Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

maxitems Error by copy #471

Closed
ghedeon-work opened this issue Feb 1, 2024 · 7 comments · Fixed by #550
Closed

maxitems Error by copy #471

ghedeon-work opened this issue Feb 1, 2024 · 7 comments · Fixed by #550
Assignees

Comments

@ghedeon-work
Copy link

I get a "reached maxitems configuration of 1" error by copying one content element into a container without any maxitems configuration, which is found inside a backend layout section which has a maxitems limitation.

BackendLayout:

...
columns {
  1 {
      name = LLL:EXT:vendor/Resources/Private/Language/Backend/BackendLayouts.xlf:Default.Teaser
      colPos = 1
  
      allowed {
          CType = teaser-slider
      }
      maxitems = 1
  }
...

Container:

...
GeneralUtility::makeInstance(Registry::class)->configureContainer(
    (
        new ContainerConfiguration(
            'teaser-slider',
            'Teaser Slider', // label
            '',
            [
                [
                    ['name' => 'content', 'colPos' => 20, 'allowed' => ['CType' => 'dce_general-slide-header']]
                ],
            ]
        )
    )
    ->setIcon('EXT:vendor/Resources/Public/Icons/teaserSlide.svg')
);

Content Elements Structure:

Page
|- BackendLayout Cell 1
|-- Teaser Slider (Container)
|--- CE#1
|--- CE#2
|--- CE#2
|- BackendLayout Cell 2
...

Creating a new element after CE#2 works fine, but copy a new element after CE#2 or any of the CE`s throws an error of "reached maxitems configuration of 1", even though there is no maxitems defined for the container.

P.S.
If i remove the maxitems config from the backend_layout, everything works normal.

Somehow Container takes the maxitems config from the parent instead.

@pitscribble
Copy link

pitscribble commented Sep 5, 2024

I ran into the same problem today on TYPO3 v11.5 with ext:container v2.3.6. So I played around with it a bit:

When I try to copy a CE from a container column which has maxitems = 1 set, I get the error “The command couldn't be executed due to reached maxitems configuration“, if I try to copy

  • into another container into a column with maxitems set
  • directly behind a container containing at least 1 CE in whichever column (behind an empty container works fine)
  • to the very top of the page
  • same page or other page doesn't matter

Copying the CE to any other place like right before a container always works fine (if this is not also directly behind another non-empty container). Copying a CE from a column with maxitems not set also works.
To make it more confusing: I do not get the error every time in the above scenarios. But at least getting the error or not is consistent.

On top of this, for each try to copy a CE and getting the error, the assets or image field content of the original CE gets duplicated.

This also prevents me from copying a whole container with all columns set to maxitems = 1. It then only copies the container itself and the content element in the first column and I get said error. The copy is only visible in the BE after reloading the page. The CE in the second column of the origin container has its assets duplicated.

I tested this with CE in the default language and without translation.

And last but not least, if I drag & drop a CE out of a maxitems = 1 column, I need to reload the page (like click on it in the page tree again) to see the +Content button again so I can add new content there. On the other hand, if I drag & drop a CE into a maxitems = 1 column the +Content stays visible and clickable in the target column. Again I need to reload the page to fix this. I have no idea if this is connected to the problem.

I thought it might be connected to #383. So I dug into it a bit. (well ok, it was a whole night 😀)

At some point in container/Classes/ContentDefender/Xclasses/DatamapHook.php the function processDatamap_beforeStart is called. It works with the array datamap['tt_content']['NEW12345'] where NEW12345 is the temporary uid of the new CE.

Let's look at some values in this array:
If we try to copy to the very top of the page

  • pid is the uid of the page
  • colPos is the colPos of the original CE
  • tx_container_parent is the uid of the container containing the original CE

If we copy directly after a container

  • pid is the negated uid of the content element we want to copy after (like –657 for instance). This is not as you might think the id of this container, but the uid of the last CE in the rightmost filled column of this container
  • colPos equals the colPos of the CE just mentioned
  • tx_container_parent is the uid of the container containing the original CE

If we copy into a container

  • pid is the negated uid of the CE we want to copy after, in this case the uid of the last CE in the container before the place we want to copy into, counted from left and top, or the uid of the container itself if we copy into the top of the left column
  • colPos equals the colPos of the CE just mentioned or of the container itself if we copy into the top of the left column
  • tx_container_parent is the uid of the container containing the original CE

From this array we work with the values colPos and tx_container_parent. pid seems not to be used

  • colPos goes into $colPos
  • tx_container_parent goes into $containerId

Since NEW12345 is not an integer we jump into the else branch in line 92. getTargetColPosForNew and getContainerIdForNew are called with $containerId and $colPos. In other words, for the second scenario, we take the colPos value of the rightmost filled column in the container we want to copy our CE after and then look for a column with this same colPos value in the container where our CE to copy originates from. This does not seem to make any sense.
In the end both these functions come back with NULL. Therefore we keep $colPos and $containerId from before and also call isMaxitemsReachedByContainenrId with the same weird values. This means, if the said column in our origin container has its maxitems setting reached we get the error. This also explains why it sometimes works and sometimes not and the pattern is not obvious at all.

So either the data given to the function in the DatamapHook is not correct or it handles the given data in a wrong way. If I skip the extended function processDatamap_beforeStart and thus only the one from ext:content_defender is used I get no errors. But I did not check this for side effects or with any translations, so this is possibly not the solution.

Also I did not find out how this connects to the assets / image field duplication, but if we do not get the error this is not an issue anyways.

Unfortunately I do not know the extension well enough to provide a patch, but maybe someone more experienced can take over from here with the information I found.

@achimfritz
Copy link
Contributor

achimfritz commented Sep 30, 2024

Hi @ghedeon-work , @pitscribble , sorry for late answer.
i have tryd the 2 first examples described in the issue, and cannot reproduce the Bug, for first example i have this tt_content Items:

MariaDB [db]> select uid,Ctype,colPos,tx_container_parent,header from tt_content order by sorting;
+-----+---------------------------------+--------+---------------------+--------+
| uid | Ctype                           | colPos | tx_container_parent | header |
+-----+---------------------------------+--------+---------------------+--------+
|   5 | header                          |      1 |                   0 | out    |
|   1 | b13-2cols-with-header-container |      0 |                   0 | 1      |
|   2 | header                          |    200 |                   1 | ce1    |
|   3 | header                          |    200 |                   1 | ce2    |
|   4 | header                          |    200 |                   1 | ce3    |
+-----+---------------------------------+--------+---------------------+--------+

and the container uid 1 is an an backend-layout column with maxitems=1
i can copy uid 5 after uid 3 (so i got

MariaDB [db]> select uid,Ctype,colPos,tx_container_parent,header from tt_content order by sorting;
+-----+---------------------------------+--------+---------------------+--------------+
| uid | Ctype                           | colPos | tx_container_parent | header       |
+-----+---------------------------------+--------+---------------------+--------------+
|   5 | header                          |      1 |                   0 | out          |
|   1 | b13-2cols-with-header-container |      0 |                   0 | 1            |
|   2 | header                          |    200 |                   1 | ce1          |
|   3 | header                          |    200 |                   1 | ce2          |
|   6 | header                          |    200 |                   1 | out (copy 1) |
|   4 | header                          |    200 |                   1 | ce3          |
+-----+---------------------------------+--------+---------------------+--------------+

i have tested with TYPO3 12 and container 2.3.6 PHP 8.2, on a vanilla TYPO3 with EXT:container, EXT:container_example and EXT:content_defender

second example in this issue, i have

MariaDB [db]> select uid,Ctype,colPos,tx_container_parent,header from tt_content order by sorting;
+-----+---------------------------------+--------+---------------------+-----------------+
| uid | Ctype                           | colPos | tx_container_parent | header          |
+-----+---------------------------------+--------+---------------------+-----------------+
|   1 | b13-2cols-with-header-container |      0 |                   0 |                 |
|   2 | header                          |    202 |                   1 | child 1         |
|   3 | b13-2cols-with-header-container |      0 |                   0 | other container |
+-----+---------------------------------+--------+---------------------+-----------------+

with b13-2cols-with-header-container colPos 202 has maxitems=1
and i can copy uid2 into uid 3 colPos 202, i got

MariaDB [db]> select uid,Ctype,colPos,tx_container_parent,header from tt_content order by sorting;
+-----+---------------------------------+--------+---------------------+------------------+
| uid | Ctype                           | colPos | tx_container_parent | header           |
+-----+---------------------------------+--------+---------------------+------------------+
|   1 | b13-2cols-with-header-container |      0 |                   0 |                  |
|   2 | header                          |    202 |                   1 | child 1          |
|   3 | b13-2cols-with-header-container |      0 |                   0 | other container  |
|   5 | header                          |    202 |                   3 | child 1 (copy 1) |
+-----+---------------------------------+--------+---------------------+------------------+

a db dump with minimal content elements on a vanilla installation (with the 3 extensions mentioned above) and a description copy to would help me to reproduce your described bugs

@pitscribble
Copy link

pitscribble commented Sep 30, 2024

As for my problem (other than for @ghedeon-work) the be-layout-section maxitems setting it not relevant, only the container columns ones. Unfortunately I currently cannot provide a DB dump, but it's really easy to recreate:

Preparation

  • set all columns of CType b13-2cols in vendor/b13/container-example/Configuration/TCA/Overrides/tt_content.php to maxitems=1 (line 28)
// second container
\TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(\B13\Container\Tca\Registry::class)->configureContainer(
    (
        new \B13\Container\Tca\ContainerConfiguration(
            'b13-2cols', // CType
            '2 Column', // label
            'Some Description of the Container', // description
            [
                [
                    ['name' => '2-cols-left', 'colPos' => 200, 'maxitems' => 1],
                    ['name' => '2-cols-right', 'colPos' => 201, 'maxitems' => 1]
                ]
            ] // grid configuration
        )
    )
);

  • add a new page
  • add a text element
  • add a CType 'b13-2cols' container below the text element
  • fill all its columns with new text CE

Now, to get some errors, try:

  1. Copy whole Container:
    • copy container
    • paste wherever
    • -> error shown
    • refresh page
    • -> now you can see only container and left column is copied
    • -> delete the broken copy for the next tests
  2. Copy CE from Container to Page:
    • copy CE from whichever container column
    • paste
      • below container -> error shown, nothing copied
      • between text CE and Container -> works fine
      • to the top of the page -> error shown, nothing copied
  3. Copy from Container to Container:
    • add a new empty container of CType b13-2cols between the text element and the other container
    • add a new text CE in the left column of the new container
    • copy the CE from right column of the old container
    • paste to the right column of the new container
    • -> error shown, nothing copied
    • now delete the left CE from the old container and try copying the right one again -> works fine
    • also copy-pasting the left CE from the old container to the right column of the new container works fine
  4. drag & drop:
    • drag a random CE from of one of the containers
    • drop somewhere
    • -> you can't drag & drop the CE back to where it came from, the +content and paste buttons are missing
    • you need to refresh the page somehow
    • then you can drag the CE back into the container

I hope that helps.

@achimfritz
Copy link
Contributor

ok, thanks, i can at least confirm first example, i will look at it, but maxitems is a "little complecated" (as you can see here https://github.com/b13/container/blob/master/Tests/Functional/Datahandler/ContentDefender/MaxItemsTest.php).

i think this will me cost "some time"

@pitscribble
Copy link

Thanks. As I wrote in my first comment is seems to check for reached maxitems in the wrong space. If I can help with anything, feel free to reach out.

@achimfritz achimfritz self-assigned this Oct 14, 2024
achimfritz added a commit that referenced this issue Oct 30, 2024
when operating on container elements no datamaphook
for content_defender should be executed

Fixes: #471
achimfritz added a commit that referenced this issue Nov 5, 2024
disable content_defender checks
in our xclassed datamaphook
for datahandler cmdMap operations

Fixes: #471
Fixes: #444
Fixes: #383
achimfritz added a commit that referenced this issue Nov 6, 2024
disable content_defender checks
in our xclassed datamaphook
for datahandler cmdMap operations

Fixes: #471
Fixes: #444
Fixes: #383
@achimfritz
Copy link
Contributor

Hi @pitscribble , test bugfix/471 branch
a926004
(1. and 2. should work, 3: cannot reproduce (maybe "site-effect-fix", 4: UX, ("only display error"), you can create a new issue for this (or better solve it)

@pitscribble
Copy link

I tested the bugfix-branch in different setups in TYPO3 v11 and v12 and everything (besides 4, as you wrote) seems to work fine. Thank you so much for this bugfix!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants