0
votes

I try to list all File-Records depending on the given categories. So I had problems to list all Files with the right categories and asked about it here (solved).

Now I got to the problem described here.

In short: Typo3 saves already rendered records and dosen't render it again to prevent endless loops. But I need to get the records rendered.

My Typo3 version is 7.6.18.

I started with this working code, which just displays all Files wich have a relation with the categorie uid=1 and his childs (described further in my previous question-thread):

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>

}

But now, I want to display this more grouped on categories, like:

Name Of Cat 1
 - File 1
 - File 2
Name Of Cat 2
- File 3

For this I have advanced the code like this:

lib.documentindex = CONTENT
lib.documentindex {
  wrap = <ul>|</ul>

  table = sys_category
  select {
    pidInList = 1
    recursive = 1000
    selectFields = sys_category.title, sys_category.uid as theuid
    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
    groupBy = sys_category.title
  }

  renderObj = COA
  renderObj.wrap = <li>|</li>
  renderObj.10 = TEXT
  renderObj.10 {
    field = title
    wrap = <h3>|</h3>
  }

  renderObj.20 = CONTENT
  renderObj.20 {

    table = sys_category
    select {
      begin = 0
      pidInList = 1
      recursive = 1000
      selectFields = sys_file.name, sys_file.identifier
      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")
      orderBy = sys_file.name
      andWhere.cObject = TEXT
      andWhere.cObject.dataWrap = sys_category.uid='{field:theuid}'
      //andWhere.cObject.dataWrap = sys_category.uid='4'
      andWhere.cObject.insertData= 1

    }

    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>

  }

}

The first query is for displaying the titles of categories which have at least 1 file connected with, and the 2nd select is for displaying the files which are connected.

The problem is now, that the files are saved because of the first select and are so locked from being rendered in the 2nd query.

I could not find a typoscript-only workaround, but I have seen that this problem is known for a long time. Now my question: Does somebody know a workaround for the problem, with only typoscript? I don't want a solution which is split over multiple files, because I'm new on typo3 and I don't have an overview over our typo3-projects already.

Edit 1:

So I changed the order of the 2nd query as Bernd Wilke πφ has told me to:

renderObj.20 {

    table = sys_file
    select {
      begin = 0
      pidInList = 1
      recursive = 1000
      selectFields = sys_file.name, sys_file.identifier
      join = sys_file_metadata ON (sys_file_metadata.file = sys_file.uid) JOIN sys_category_record_mm ON (sys_file_metadata.uid = sys_category_record_mm.uid_foreign)
      where = (sys_category_record_mm.tablenames = "sys_file_metadata") AND (sys_category_record_mm.fieldname = "categories")
      orderBy = sys_file.name
      andWhere.cObject = TEXT
      andWhere.cObject.dataWrap = sys_category_record_mm.uid_local='{field:theuid}'
      andWhere.cObject.dataWrap = //sys_category_record_mm.uid_local='2' OR sys_category_record_mm.uid_local='4'
      andWhere.cObject.insertData= 1
    }

    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 far as I can tell now, this replaces the problem of not rendering the records I need with the problem it don't render a thing I need at all.

Do I replace

sys_category_record_mm.uid_local='{field:theuid}'
//andWhere.cObject.dataWrap = sys_category_record_mm.uid_local='2' OR sys_category_record_mm.uid_local='4'

with

//sys_category_record_mm.uid_local='{field:theuid}'
  andWhere.cObject.dataWrap = sys_category_record_mm.uid_local='2' OR sys_category_record_mm.uid_local='4'

Some records are shown, but I've again the strange problem that only the condition after 'OR' counts. So only records with the category.uid=4 are displayed. If I change it to 2 in the code, it displays the records with category.uid=2. Anyway, if it's a bug or something else, I don't care for now. Because I want it to work with andWhere.cObject.dataWrap = sys_category_record_mm.uid_local='{field:theuid}' and it does not.

Edit2:

Ok I got it to work as expected, but the way I did it, is so strange, that I don't want to use it.

Solution:

renderObj.20 {

    table = sys_file
    select {
      begin = 0
      pidInList = 1
      recursive = 1000
      selectFields = sys_file.name, sys_file.identifier
      join = sys_file_metadata ON (sys_file_metadata.file = sys_file.uid) JOIN sys_category_record_mm ON (sys_file_metadata.uid = sys_category_record_mm.uid_foreign)
      where = (sys_category_record_mm.tablenames = "sys_file_metadata") AND (sys_category_record_mm.fieldname = "categories")
      orderBy = sys_file.name
      andWhere.cObject = TEXT
      andWhere.cObject.dataWrap = 0 OR sys_category_record_mm.uid_local='{field:theuid}'
      //andWhere.cObject.dataWrap = sys_category_record_mm.uid_local='2' OR sys_category_record_mm.uid_local='4'
      andWhere.cObject.insertData= 1
    }

So, I learned: In Typo3 conditions only matter if an OR-operator is standing before the condition. Well, just a Typo3-thing?

2
why do you base the second CONTENT object (renderObj.20) an the same table as the outer CONTENT object? I think that is a logical fault. And maybe TYPO3 gets confused by this. your current context for renderObj.20 is the current record of sys_category you have selected with lib.documentindex and are rendering in the current lib.documentindex.renderObj. you need a select on table sys_file with a join to sys_category_record_mm where sys_category_record_mm.uid_local.field = uid (bad formatting in comments :-( )Bernd Wilke πφ
using cObject within a select is bad style. It might need some time to get used to it, but typoscript offers the option of markers within select options so you can avoid datawrap, COA or similar. (docs.typo3.org/typo3cms/TyposcriptReference/7.6/Functions/… last option documented)Bernd Wilke πφ
Be aware that a pure typoscript solution might be complicated with stacking objects inside each other, each with another context. Here: you start with a CONTENT select and in the renderObj you use another CONTENT to select other records based on the values from the outer record.Bernd Wilke πφ
I tried to use the markers before I used andWhere.cObject but that didn't worked at all. ( I could not fetch a single record even with hardcoded ID's). I use my answer now, cause my next project has nothing to do with t3, so I want to finish this fast.FuFu
have a look at my cleanup and simplification to your answer.Bernd Wilke πφ

2 Answers

0
votes

andWhere should not be starting with the field name but with AND, OR or another official SQL statement. So you should replace the line

andWhere.cObject.dataWrap = 0 OR sys_category_record_mm.uid_local='{field:theuid}'

with

andWhere.cObject.dataWrap = AND sys_category_record_mm.uid_local='{field:theuid}'

Maybe this feels less weird then. ;-)

So here we go with the fully edited solution:

lib.documentindex = CONTENT
lib.documentindex {
  wrap = <ul>|</ul>    
  table = sys_category
  select {
    pidInList = 1
    recursive = 1000
    selectFields = sys_category.title, sys_category.uid as theuid
    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)
    )
    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
    groupBy = sys_category.title
  }

  // context = sys_category
  renderObj = COA
  renderObj {
    wrap = <li>|</li>
    10 = TEXT
    10 {
      dataWrap = <h3>{field:title}</h3>
    }

    20 = CONTENT
    20 {
      table = sys_file
      select {
        pidInList = 1
        recursive = 1000
        selectFields = sys_file.name, sys_file.identifier
        join (
               sys_file_metadata 
                 ON (sys_file_metadata.file = sys_file.uid) 
          JOIN sys_category_record_mm 
                 ON (sys_file_metadata.uid = sys_category_record_mm.uid_foreign)
        )
        where (
          (sys_category_record_mm.tablenames = "sys_file_metadata") AND
          (sys_category_record_mm.fieldname = "categories")
        )
        orderBy = sys_file.name
        andWhere.dataWrap = AND sys_category_record_mm.uid_local='{field:theuid}'
        }
      }

      // context: sys_file
      renderObj = TEXT
      renderObj {
        wrap = <li>|</li>
        field = name
        typolink.parameter.field = identifier
      }
    }
  }
}
-1
votes

OK, it don't make sense, but it's solved. I would like to know why it works like this. But I may should stop asking myself about typo3.

Solution:

In Typo3 conditions only matter if an OR-operator is standing before it?!

lib.documentindex = CONTENT
lib.documentindex {
  wrap = <ul>|</ul>

  table = sys_category
  select {
    pidInList = 1
    recursive = 1000
    selectFields = sys_category.title, sys_category.uid as theuid
    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)
    )
    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
    groupBy = sys_category.title
  }

  // context = sys_category
  renderObj = COA
  renderObj {
    wrap = <li>|</li>
    10 = TEXT
    10 {
      field = title
      wrap = <h3>|</h3>
    }

    20 = CONTENT
    20 {
      table = sys_file
      select {
        begin = 0
        pidInList = 1
        recursive = 1000
        selectFields = sys_file.name, sys_file.identifier
        join (
               sys_file_metadata 
                 ON (sys_file_metadata.file = sys_file.uid) 
          JOIN sys_category_record_mm 
                 ON (sys_file_metadata.uid = sys_category_record_mm.uid_foreign)
        )
        where (
          (sys_category_record_mm.tablenames = "sys_file_metadata") AND
          (sys_category_record_mm.fieldname = "categories")
        )
        orderBy = sys_file.name
        andWhere.cObject = TEXT
        andWhere.cObject {
          dataWrap = 0 OR sys_category_record_mm.uid_local='{field:theuid}'
          insertData= 1
        }
      }

      // context: sys_file
      renderObj = TEXT
      renderObj {
        wrap = <li>|</li>
        field = name
        typolink.parameter.field = identifier
      }
    }
  }
}