Select other PID if select result is empty - typo3

I got this TS:
markers.input_readonly_b_price = CONTENT
markers.input_readonly_b_price {
table = tx_pricelist_prices_full
select {
pidInList = 27
orderBy = uid
selectFields = uid, group_b_1_3
# possible conditions
where = ( hidden='0' AND deleted='0')
}
renderObj = COA
renderObj {
#value
1 = TEXT
1.insertData = 1
1.data = field:group_b_1_3
2 = TEXT
2.value = *
3 = TEXT
3.insertData = 1
3.data = TSFE:fe_user|sesData|finish_day
stdWrap.prioriCalc = 1
}
}
I need to change that TypoScript with that condition:
If on page with id 27 - pid=27 record inside will have status deleted/hidden then read data from pid=20 else (there is one record visible) read data from pid=27
On pid=20 there will be a record (always). On 'pid=27` will be one record but sometime hidden, sometime visible.
Does anyone have an idea how to set this condition?

Related

How can I use the selected category in a databaseQueryProcessor?

I have a simple content element that I have added the categories field to.
The user selects the parent category of their choice.
I want to use the DatabaseQueryProcessor to output a list of child categories to the one that was selected.
How do I format the where so that it gets categories with the parent of the chosen category?
10 = TYPO3\CMS\Frontend\DataProcessing\DatabaseQueryProcessor
10 {
if.isTrue.field = categories
table = sys_category
selectFields = sys_category.*
pidInList = {$categories}
recursive = 999
where = parent = ???
as = categories
}
According to TSRef the database query processor makes use of the select function and its parameters.
So something like this should be working - (not tested)
10 = TYPO3\CMS\Frontend\DataProcessing\DatabaseQueryProcessor
10 {
if.isTrue.field = categories
table = sys_category
selectFields = sys_category.*
pidInList = {$categories}
recursive = 999
join = sys_category_record_mm ON sys_category_record_mm.uid_local = sys_category.uid
where.dataWrap = sys_category_record_mm.uid_foreign={field:_ORIG_uid // field:uid} AND sys_category_record_mm.tablenames = 'mytable' AND sys_category_record_mm.fieldname = 'myfield'
orderBy = sys_category_record_mm.sorting_foreign
languageField = 0
as = categories
}
https://docs.typo3.org/m/typo3/reference-typoscript/master/en-us/Functions/Select.html#select

How to control the order of records for output

I have a MASK content element where the editor can choose some records to put out as teasers (see screenshot below). The content should be output in the order selected by the editor. The UID List for example will look like this: 19,18,20,17
In the MySQL syntax the function SELECT FIND_IN_SET() does this job, I think - how can I use it (or a similar functionality) in the select part of a typoscript CONTENT object?
Thank you in advance for any help.
EDIT: My code example - neither the orderBy clause work nor the where clause:
table = tt_content
select {
pidInList = 11,12
uidInList.data = field:recid // the list with the wanted record IDs (19,18,20,17) transferred from the content object
recursive = 2
join = sys_category_record_mm ON sys_category_record_mm.uid_foreign = tt_content.uid
orderBy.data = field:recid
orderBy.wrap = FIND_IN_SET(`tt_content`.`uid`,'|')
where = tt_content.CType='mask_cnt_textpic_uni'
#where.data = field:recid
#where.wrap = FIND_IN_SET(`tt_content`.`uid`,'|')
where.data = field:syscats
where.intval = 1
where.wrap = sys_category_record_mm.uid_local IN (|)
max = 999
}
is that what you want?
example for content by colPos:
lib.content.left = CONTENT
lib.content.left {
table = tt_content
select {
orderBy = sorting
where = {#colPos}=1
}
}
the key here is the select.orderBy
Thanks to the note from HerrZ I found the solution - here my customized script:
10 = CONTENT
10 {
table = tt_content
select {
pidInList = 11,12
uidInList.data = field:recid
recursive = 2
selectFields.dataWrap = *,FIND_IN_SET(`uid`,'{field:recid}') AS reclist_sortby
join = sys_category_record_mm ON sys_category_record_mm.uid_foreign = tt_content.uid
where = tt_content.CType='mask_cnt_textpic_uni'
where.data = field:syscats
where.intval = 1
where.wrap = sys_category_record_mm.uid_local IN (|)
orderBy = reclist_sortby
}
renderObj = COA
renderObj { ... }
}
Important note: In the FIND_IN_SET syntax, the parameters must be quoted as shown in the example - otherwise Typo3 will throw an error ("Incorrect parameter count in the call to native function 'FIND_IN_SET'").

How to create a select clause with AND query that matches tx_news items with two or more assotiated categories

I try to create a query to get all news items, that are flagged with at least two different categories and they have to match the AND clause.
I need this query to make a decision, if the following code should be rendered, or not. E.g. If there is no news item with category A and category B, do nothing. Else show tx_news LIST view.
lib.field_dmnewsplugin.5 = CONTENT
lib.field_dmnewsplugin.5 {
table = tx_news_domain_model_news
select {
pidInList = 124
max = 9
orderBy = uid DESC
leftjoin = sys_category_record_mm ON (sys_category_record_mm.uid_foreign = tx_news_domain_model_news.uid)
#andWhere = sys_category_record_mm.uid_local IN (14,16)
#where = sys_category_record_mm.uid_local = 14
andWhere = sys_category_record_mm.uid_local = 14 AND sys_category_record_mm.uid_local = 16
}
renderObj = COA
renderObj {
1 = TEXT
1.value = Aktuelles
1.wrap = <h2>|</h2>
2 = TEXT
2.field = title
2.crop = 50|...|1
2.wrap = <h3>|</h3>
3 = TEXT
3.field = teaser
3.crop = 500|...|1
3.wrap = <p>|</p>
}
}
My code is the result of some testings. With the "andWhere" clause, the result is empty. without any where clause, I get double entries for all news items, because all of them have at least two different categories.
My goal is to get unique results for each news item, that is flagged with category A and category B (and maybe as an universal solution additional categories).
What do I have to do?
Thank you in advance,
Ralf
Try to put the WHERE clause into the ON part of the JOIN and use a groupBy to get a counter.
select {
selectFields = count(*) AS counter
leftjoin = sys_category_record_mm ON (sys_category_record_mm.uid_foreign = tx_news_domain_model_news.uid) AND sys_category_record_mm.uid_local IN (14,16)
pidInList = 124
max = 9
groupBy = uid
orderBy = uid DESC
where = counter > 1
}
After I had to realize, that Jo's solution does not work for me, I had another idea:
lib.field_dmnewsplugin = COA
lib.field_dmnewsplugin {
10 = CONTENT
10 {
table = tx_news_domain_model_news
select {
selectFields = title, teaser, count(uid) AS counter
leftjoin = sys_category_record_mm ON (sys_category_record_mm.uid_foreign = tx_news_domain_model_news.uid) AND sys_category_record_mm.uid_local IN ({14,###maincat###)
pidInList = 124
max = 1
groupBy = uid
orderBy = counter DESC, crdate DESC
#where = counter > 1
markers {
maincat.value = 16
}
}
renderObj = COA
renderObj {
10 = COA
10 {
stdWrap {
if {
value = 1
isGreaterThan.data = field:counter
#equals.data = field:counter
}
required = 1
wrap = <h2>Some Headline</h2>
}
10 = USER
10 {
userFunc = TYPO3\CMS\Extbase\Core\Bootstrap->run
extensionName = News
pluginName = Pi1
vendorName = GeorgRinger
switchableControllerActions {
News {
1 = list
}
}
settings < plugin.tx_news.settings
settings {
cropMaxCharacters = 164 | [...] | 1
categoryConjunction = and
categories = 14,16
excludeAlreadyDisplayedNews = 1
archiveRestriction = active
[...]
The problem is, that we cannot use the alias "counter" in the where clause and I have no idea, how I can solve the problem with typoscript. With native SQL there might be a better way.
But I'm able to get the value of "counter" to create an "if" rule. And additionally, I can sort the query by "counter". So, if the query returns at least one hit with "counter" greater than 1, I can decide to render a COA-Object like a news list view with headline.
I'm satisfied with this solution. But maybe, somebody has a special trick for me?
Thank's for your help,
Ralf

Show category names of current page in TYPO3 8

I am trying to display the category name(s) of the current page on a TYPO3 8 installation. In TYPO3 7 it used to work like this (see below), however now I only receive a random error code and no Text output. Any Ideas?
lib.catclass = CONTENT
lib.catclass {
wrap = <div class="categories">|</div>
table = sys_category
select {
pidInList = 35 // UiD of your category_page
join = sys_category_record_mm ON(sys_category_record_mm.uid_local=sys_category.uid)
where = sys_category_record_mm.tablenames='pages'
andWhere.dataWrap = sys_category_record_mm.uid_foreign = {TSFE:id}
}
renderObj = TEXT
renderObj.field = title
renderObj.wrap = <li class="category {field:title}">|</li>
renderObj.insertData = 1
}
The corresponding error output is as follows:
An exception occurred while executing 'SELECT * FROM `sys_category` INNER JOIN `sys_category_record_mm`
`ON(sys_category_record_mm`.`uid_local=sys_category`.`uid)` ON WHERE
(`sys_category`.`pid` IN (35)) AND
(sys_category_record_mm.tablenames='pages') AND (`sys_category`.`sys_language_uid` IN (0, -1)) AND
((`sys_category`.`deleted` = 0) AND (`sys_category`.`t3ver_state` <= 0) AND (`sys_category`.`pid` <> -1) AND (`sys_category`.`hidden` = 0) AND (`sys_category`.`starttime` <= 1546204860) AND
((`sys_category`.`endtime` = 0) OR (`sys_category`.`endtime` > 1546204860)))': You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version
for the right syntax to use near '.`uid_local=sys_category`.`uid)` ON WHERE (`sys_category`.`pid` IN (35)) AND (s' at line 1
Try adding a space after ON, so:
join = sys_category_record_mm ON (sys_category_record_mm.uid_local=sys_category.uid)
Also, andWhere has been deprecated since TYPO3 7.1 and has been removed in 8. You need to add that to where and use markers to add the page uid. From the top of my head, that would make it:
lib.catclass = CONTENT
lib.catclass {
wrap = <div class="categories">|</div>
table = sys_category
select {
pidInList = 35 // UiD of your category_page
join = sys_category_record_mm ON (sys_category_record_mm.uid_local=sys_category.uid)
where = sys_category_record_mm.tablenames='pages' AND sys_category_record_mm.uid_foreign = ###pageuid###
markers {
pageuid.data = TSFE:id
}
}
renderObj = TEXT
renderObj.field = title
renderObj.wrap = <li class="category {field:title}">|</li>
renderObj.insertData = 1
}
See https://docs.typo3.org/typo3cms/TyposcriptReference/8.7/Functions/Select/#markers for more on markers

Typo3 Typoscript-Select use OR-operator in where condition

I try select all Files from table sys_files which are linked with a category or the subcategories.
On my Example the main category for files has the ID 1 and there are some sub-categories on it.
I first created the SQL-Code, to try it out directly on the database:
SELECT sys_file.name, sys_file.identifier, sys_category.title
FROM sys_category
RIGHT JOIN sys_file_metadata ON (sys_file_metadata.categories =
sys_category.uid)
JOIN sys_file ON (sys_file.uid = sys_file_metadata.file)
WHERE (sys_category.parent = 1) OR (sys_category.uid = 1)
order By sys_category.title
This works fine as expected.
Now, I tried to do it similar in typoscript, this looks like:
lib.documentindex = CONTENT
lib.documentindex {
wrap = <ul>|</ul>
table = sys_category
select {
selectFields = sys_file.name, sys_file.identifier, sys_category.title
rightjoin = sys_file_metadata ON (sys_file_metadata.categories = sys_category.uid) join sys_file ON (sys_file.uid = sys_file_metadata.file)
where = sys_category.uid = 1 OR sys_category.parent = 1
orderBy = sys_category.title
}
renderObj = COA
renderObj.wrap = <li>|</li>
renderObj.10 = TEXT
renderObj.10 {
field = identifier
wrap = <a href="|">
}
renderObj.20 = TEXT
renderObj.20.field = name
renderObj.30 = TEXT
renderObj.30.value = </a>
}
And this dosen't work. But really strange is, it works halfway.
So if i write the where like this:
where = sys_category.uid = 1 OR sys_category.parent = 1
It displays as all files with a category on which the parent is 1.
But it dosen't display files with the category where the id is 1.
Do I now write it like
where = sys_category.parent = 1 OR sys_category.uid = 1
It works the other way around, it displays files with the category where the id is 1. But none where the parent id is 1.
In the official documentation of the select (found here), it just tells on the where-option:
WHERE clause without the word "WHERE".
But this is not all. I tried so much things and pretty everything i tried don't behave like real SQL code. I don't know if this typo3-thing is buggy as hell or if I just use it totally wrong.
I think your query is wrong (even the pure SQL).
categories are never(?) referenced immediately, but always with the mm-records in sys_category_record_mm.
So your join needs to be another one where you join sys_category with sys_file via these mm-records (and the sys_file_metadata records):
SELECT sys_file.name, sys_file.identifier, sys_category.title
FROM sys_category
JOIN sys_category_record_mm
ON sys_category_record_mm.uid_local = sys_category.uid
JOIN sys_file_metadata
ON sys_file_metadata.uid = sys_category_record_mm.uid_foreign
JOIN sys_file
ON sys_file_metadata.file = sys_file.uid
WHERE sys_category_record_mm.tablenames = "sys_file_metadata"
AND sys_category_record_mm.fieldname = "categories"
AND ((sys_category.parent = 1) OR (sys_category.uid = 1))
ORDER By sys_category.title
be aware: there are category fields in categorized records, but those only hold a counter of the references (given by the mm-records). It is not the uid of a category.
Might be misleading if you use the category with uid = 1 much often.
Here is the typoscript realizing this Query:
Edit: Included TypoScript (by FuFu)
This typoscript-select worked for me, but I had to move categories out of the root to the first page.
lib.documentindex = CONTENT
lib.documentindex {
wrap = <ul>|</ul>
table = sys_category
select {
pidInList = 1
recursive = 1000
selectFields = sys_file.name, sys_file.identifier, sys_category.title
join = sys_category_record_mm ON (sys_category_record_mm.uid_local = sys_category.uid) JOIN sys_file_metadata ON (sys_file_metadata.uid = sys_category_record_mm.uid_foreign) JOIN sys_file ON (sys_file_metadata.file = sys_file.uid)
where = (sys_category_record_mm.tablenames = "sys_file_metadata") AND (sys_category_record_mm.fieldname = "categories") AND ((sys_category.parent = 1) OR (sys_category.uid = 1))
orderBy = sys_category.title
}
renderObj = COA
renderObj.wrap = <li>|</li>
renderObj.10 = TEXT
renderObj.10 {
field = identifier
wrap = <a href="|">
}
renderObj.20 = TEXT
renderObj.20.field = name
renderObj.30 = TEXT
renderObj.30.value = </a>
}
As
Did you try it with DataProcessing? You can combine two DatabaseQueryProcessors to get what you need. See: https://docs.typo3.org/typo3cms/TyposcriptReference/7.6/ContentObjects/Fluidtemplate/Index.html#dataprocessing