Skip to content

Commit 2bc4bec

Browse files
authored
Fix duplicate block rendering with getSortedChildren() (OpenMage#4337)
1 parent a893eaf commit 2bc4bec

File tree

2 files changed

+105
-2
lines changed

2 files changed

+105
-2
lines changed

app/code/core/Mage/Core/Block/Abstract.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -464,6 +464,7 @@ public function setChild($alias, $block)
464464

465465
$block->setParentBlock($this);
466466
$block->setBlockAlias($alias);
467+
$this->unsetChild($alias);
467468
$this->_children[$alias] = $block;
468469
return $this;
469470
}
@@ -482,7 +483,7 @@ public function unsetChild($alias)
482483
unset($this->_children[$alias]);
483484
$key = array_search($name, $this->_sortedChildren);
484485
if ($key !== false) {
485-
unset($this->_sortedChildren[$key]);
486+
array_splice($this->_sortedChildren, $key, 1);
486487
}
487488
}
488489

@@ -741,7 +742,6 @@ public function insert($block, $siblingName = '', $after = false, $alias = '')
741742
*/
742743
public function sortChildren($force = false)
743744
{
744-
$this->_sortedChildren = array_values($this->_sortedChildren); // reset indexes which might have gaps after unsetting blocks
745745
foreach ($this->_sortInstructions as $name => $list) {
746746
list($siblingName, $after, $exists) = $list;
747747
if ($exists && !$force) {
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
<?php
2+
3+
/**
4+
* OpenMage
5+
*
6+
* This source file is subject to the Open Software License (OSL 3.0)
7+
* that is bundled with this package in the file LICENSE.txt.
8+
* It is also available at https://opensource.org/license/osl-3-0-php
9+
*
10+
* @category OpenMage
11+
* @package OpenMage_Tests
12+
* @copyright Copyright (c) 2024 The OpenMage Contributors (https://www.openmage.org)
13+
* @license https://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
14+
*/
15+
16+
declare(strict_types=1);
17+
18+
namespace OpenMage\Tests\Unit\Mage\Core\Block\Text;
19+
20+
use Mage;
21+
use PHPUnit\Framework\TestCase;
22+
23+
class ListTest extends TestCase
24+
{
25+
public function setUp(): void
26+
{
27+
Mage::app();
28+
}
29+
30+
/**
31+
* @group Mage_Core
32+
* @group Mage_Core_Block
33+
*/
34+
public function testDuplicateBlockName(): void
35+
{
36+
$layout = Mage::getModel('core/layout');
37+
38+
$parentBlock = $layout->createBlock('core/text_list', 'parent');
39+
40+
$childBlockA = $layout->createBlock('core/text', 'child_a')->setText('A1');
41+
$parentBlock->append($childBlockA);
42+
43+
$childBlockA = $layout->createBlock('core/text', 'child_a')->setText('A2');
44+
$parentBlock->append($childBlockA);
45+
46+
$this->assertSame('A2', $parentBlock->toHtml());
47+
}
48+
49+
/**
50+
* @group Mage_Core
51+
* @group Mage_Core_Block
52+
*/
53+
public function testDuplicateBlockNameOrdering(): void
54+
{
55+
$layout = Mage::getModel('core/layout');
56+
57+
$parentBlock = $layout->createBlock('core/text_list', 'parent');
58+
59+
$childBlockA = $layout->createBlock('core/text', 'child_a')->setText('A');
60+
$parentBlock->append($childBlockA);
61+
62+
$childBlockB = $layout->createBlock('core/text', 'child_b')->setText('B');
63+
$parentBlock->append($childBlockB);
64+
65+
$childBlockC = $layout->createBlock('core/text', 'child_c')->setText('C');
66+
$parentBlock->append($childBlockC);
67+
68+
$parentBlock->unsetChild('child_b');
69+
70+
$childBlockB = $layout->createBlock('core/text', 'child_b')->setText('B');
71+
$parentBlock->insert($childBlockB, 'child_c', false);
72+
73+
$this->assertSame('ABC', $parentBlock->toHtml());
74+
}
75+
76+
/**
77+
* @group Mage_Core
78+
* @group Mage_Core_Block
79+
*/
80+
public function testUniqueBlockNameOrdering(): void
81+
{
82+
$layout = Mage::getModel('core/layout');
83+
84+
$parentBlock = $layout->createBlock('core/text_list', 'parent');
85+
86+
$childBlockD = $layout->createBlock('core/text', 'child_d')->setText('D');
87+
$parentBlock->insert($childBlockD, 'child_c', true);
88+
89+
$childBlockC = $layout->createBlock('core/text', 'child_c')->setText('C');
90+
$parentBlock->insert($childBlockC, 'child_b', true);
91+
92+
$childBlockA = $layout->createBlock('core/text', 'child_a')->setText('A');
93+
$parentBlock->insert($childBlockC, 'child_b', false);
94+
95+
$childBlockB = $layout->createBlock('core/text', 'child_b')->setText('B');
96+
$parentBlock->insert($childBlockC, 'child_a', true);
97+
98+
$parentBlock->unsetChild('child_a');
99+
$parentBlock->unsetChild('child_b');
100+
101+
$this->assertSame('CD', $parentBlock->toHtml());
102+
}
103+
}

0 commit comments

Comments
 (0)