Details
-
Bug
-
Resolution: Fixed
-
High
-
4.3.0
-
None
-
Operating System: Linux ( Ubuntu )
PHP Version: (please be specific, like '4.4.3' or '5.1.5') 5.2.4-2ubuntu5.9
Database and version: Ver 14.12 Distrib 5.0.51a, for debian-linux-gnu (x86_64) using readline 5.2
Browser (and version):
Description
*The problem*
After upgrading a couple of sites to version 4.3 we got reports from customers about missing content
on the sites. After some investigation we discovered that some paragraphs in ezxmltext attributes
were not visible even if they existed in the database.
*The cause*
We traced the problem to the renderParagraph method in the eZXHTMLXMLOutput class.
This is the method eZXHTMLXMLOutput::renderParagraph in the file kernel/classes/datatypes/ezxmltext/handlers/output/ezxhtmlxmloutput.php
429: function renderParagraph( $element, $childrenOutput, $vars ) 430: { 431: // don't render if inside 'li' or inside 'td' (by option) 432: $parent = $element->parentNode; 433: 434: 435: if ( ( $parent->nodeName == 'li' && self::childTagCount( $parent ) == 1 ) || 436: ( $parent->nodeName == 'td' && !$this->RenderParagraphInTableCells && self::childTagCount( $parent ) == 1 ) ) 437: 438: { 439: return $childrenOutput; 440: } 441: 442: // Break paragraph by block tags (like table, ol, ul, header and paragraphs) 443: $tagText = ''; 444: $lastTagInline = null; 445: $inlineContent = ''; 446: foreach( $childrenOutput as $key => $childOutput ) 447: { 448: if ( $childOutput[0] === true )// is inline 449: { 450: if( $childOutput[1] === ' ' ) 451: { 452: continue; 453: } 454: 455: $inlineContent .= $childOutput[1]; 456: } 457: 458: // Only render paragraph if current tag is block and previous was an inline tag 459: // OR if current one is inline and it's the last item in the child list 460: if ( ( $childOutput[0] === false && $lastTagInline === true ) || 461: ( $childOutput[0] === true && !isset( $childrenOutput[ $key + 1 ] ) ) ) 462: { 463: $tagText .= $this->renderTag( $element, $inlineContent, $vars ); 464: $inlineContent = ''; 465: } 466: 467: if ( $childOutput[0] === false )// is block 468: $tagText .= $childOutput[1]; 469: 470: $lastTagInline = $childOutput[0]; 471: } 472: return array( false, $tagText ); 473: }
In line 463 the content of the variable $inlineContent will be rendered if current tag is inline
and it is the last item in the $childrenOutput array. But if the last item in the $childrenOutput
array is inline and contains a space then $inlinecontent that contains content from previous inline
tags will not be rendered because the continue statement in line 452 skips the rest of the code in the
foreach loop including the code that renders the inline content of the last tag.
*The solution*
*** 449,455 **** --- 449,457 ---- { if( $childOutput[1] === ' ' ) { + if( array_key_exists($key + 1, $childrenOutput) ) { continue; + } } $inlineContent .= $childOutput[1];
We added a check that made sure the continue statement was not called on the last element. That made
the missing content appear on the websites again.
Steps to reproduce
This is not easy to reproduce, but upon request I can provide a database with this problem.