Exemplo n.º 1
0
 /**
  * @dataProvider processDataProvider
  */
 public function testProcess($xml)
 {
     $this->element = new \Magento\Framework\View\Layout\Element($xml);
     $this->context->expects($this->any())->method('getScheduledStructure')->will($this->returnValue($this->scheduledStructure));
     $this->scheduledStructure->expects($this->once())->method('setElementToRemoveList')->with('header');
     $this->model->interpret($this->context, $this->element, $this->element);
 }
 /**
  * @param array $schedule
  * @param array $expectedSchedule
  * @return void
  * @dataProvider processDataProvider
  */
 public function testProcess($schedule, $expectedSchedule)
 {
     foreach ($schedule['structure'] as $structureElement) {
         $this->scheduledStructure->setStructureElement($structureElement, []);
     }
     $reorderMap = [];
     foreach ($schedule['sort'] as $elementName => $sort) {
         list($parentName, $sibling, $isAfter) = $sort;
         $this->scheduledStructure->setElementToSortList($parentName, $elementName, $sibling, $isAfter);
         $reorderMap[] = [$parentName, $elementName, $sibling, $isAfter];
     }
     foreach ($schedule['move'] as $elementName => $move) {
         $this->scheduledStructure->setElementToMove($elementName, $move);
         list($destination, $sibling, $isAfter) = $move;
         $reorderMap[] = [$destination, $elementName, $sibling, $isAfter];
     }
     $invocation = $this->structureMock->expects($this->any())->method('reorderChildElement');
     call_user_func_array([$invocation, 'withConsecutive'], $reorderMap);
     foreach ($schedule['remove'] as $remove) {
         $this->scheduledStructure->setElementToRemoveList($remove);
     }
     $this->helperMock->expects($this->atLeastOnce())->method('scheduleElement')->with($this->scheduledStructure, $this->structureMock, $this->anything())->willReturnCallback(function ($scheduledStructure, $structure, $elementName) use($schedule) {
         /**
          * @var $scheduledStructure ScheduledStructure
          * @var $structure DataStructure
          */
         $this->assertContains($elementName, $schedule['structure']);
         $scheduledStructure->unsetStructureElement($elementName);
         $scheduledStructure->setElement($elementName, []);
         $structure->createStructuralElement($elementName, 'block', 'someClass');
     });
     $this->model->process($this->readerContextMock, $this->generatorContextMock);
     $this->assertEquals($expectedSchedule, $this->scheduledStructure->getElements());
 }
Exemplo n.º 3
0
 /**
  * Remove scheduled element
  *
  * @param ScheduledStructure $scheduledStructure
  * @param Structure $structure
  * @param string $elementName
  * @param bool $isChild
  * @return $this
  */
 protected function removeElement(ScheduledStructure $scheduledStructure, Structure $structure, $elementName, $isChild = false)
 {
     $elementsToRemove = array_keys($structure->getChildren($elementName));
     $scheduledStructure->unsetElement($elementName);
     foreach ($elementsToRemove as $element) {
         $this->removeElement($scheduledStructure, $structure, $element, true);
     }
     if (!$isChild) {
         $structure->unsetElement($elementName);
     }
     return $this;
 }
Exemplo n.º 4
0
 /**
  * Schedule structural changes for move directive
  *
  * @param \Magento\Framework\View\Layout\ScheduledStructure $scheduledStructure
  * @param \Magento\Framework\View\Layout\Element $currentElement
  * @throws \Magento\Framework\Exception\LocalizedException
  * @return $this
  */
 protected function scheduleMove(Layout\ScheduledStructure $scheduledStructure, Layout\Element $currentElement)
 {
     $elementName = (string) $currentElement->getAttribute('element');
     $destination = (string) $currentElement->getAttribute('destination');
     $alias = (string) $currentElement->getAttribute('as') ?: '';
     if ($elementName && $destination) {
         list($siblingName, $isAfter) = $this->beforeAfterToSibling($currentElement);
         $scheduledStructure->setElementToMove($elementName, [$destination, $siblingName, $isAfter, $alias]);
     } else {
         throw new \Magento\Framework\Exception\LocalizedException(new \Magento\Framework\Phrase('Element name and destination must be specified.'));
     }
     return $this;
 }
 /**
  * @return void
  */
 public function testIsListToSortEmpty()
 {
     list($parentName, $name, $sibling, $isAfter) = $this->getDataSort();
     $this->assertTrue($this->model->isListToSortEmpty());
     $this->model->setElementToSortList($parentName, $name, $sibling, $isAfter);
     $this->assertFalse($this->model->isListToSortEmpty());
 }
Exemplo n.º 6
0
 /**
  * @param string $literal
  * @param \PHPUnit_Framework_MockObject_Matcher_InvokedCount $getCondition
  * @param \PHPUnit_Framework_MockObject_Matcher_InvokedCount $setCondition
  * @dataProvider processReferenceDataProvider
  */
 public function testProcessReference($literal, $getCondition, $setCondition)
 {
     $this->context->expects($this->once())->method('getScheduledStructure')->will($this->returnValue($this->scheduledStructure));
     $this->scheduledStructure->expects($getCondition)->method('getStructureElementData')->with($literal, [])->willReturn(['actions' => [['someMethod', [], 'action_config_path', 'scope']]]);
     $this->scheduledStructure->expects($setCondition)->method('setStructureElementData')->with($literal, ['actions' => [['someMethod', [], 'action_config_path', 'scope']], 'arguments' => []]);
     $this->prepareReaderPool('<' . $literal . ' name="' . $literal . '">' . '<action method="someMethod" ifconfig="action_config_path" />' . '</' . $literal . '>', $literal);
     /** @var \Magento\Framework\View\Layout\Reader\Block $block */
     $block = $this->getBlock(['readerPool' => $this->readerPool, 'scopeType' => 'scope']);
     $block->interpret($this->context, $this->currentElement);
 }
Exemplo n.º 7
0
 /**
  * @covers \Magento\Framework\View\Layout\ScheduledStructure::flushScheduledStructure
  */
 public function testFlushScheduledStructure()
 {
     $this->assertNotEmpty($this->_model->getPaths());
     $this->assertNotEmpty($this->_model->getElements());
     $this->assertNotEmpty($this->_model->getStructure());
     $this->_model->flushScheduledStructure();
     $this->assertEmpty($this->_model->getPaths());
     $this->assertEmpty($this->_model->getElements());
     $this->assertEmpty($this->_model->getStructure());
 }
 /**
  * covers \Magento\Framework\View\Layout\ScheduledStructure::setElementToBrokenParentList
  * covers \Magento\Framework\View\Layout\ScheduledStructure::unsetElementFromBrokenParentList
  */
 public function testSetElementToBrokenParentList()
 {
     $element = 'element9';
     $expectedToRemove = ['element2', 'element3'];
     $expectedToRemoveWithBroken = ['element2', 'element3'];
     $this->assertEquals($expectedToRemove, $this->_model->getListToRemove());
     $this->_model->setElementToBrokenParentList($element);
     $this->assertEquals($expectedToRemoveWithBroken, $this->_model->getListToRemove());
     $this->_model->unsetElementFromBrokenParentList($element);
     $this->assertEquals($expectedToRemove, $this->_model->getListToRemove());
 }
Exemplo n.º 9
0
 /**
  * @covers Magento\Framework\View\Layout\Reader\Block::interpret()
  */
 public function testProcessReference()
 {
     $testName = 'test_value';
     $literal = 'referenceBlock';
     $this->context->expects($this->once())->method('getScheduledStructure')->will($this->returnValue($this->scheduledStructure));
     $this->scheduledStructure->expects($this->once())->method('getStructureElementData')->with($testName, [])->will($this->returnValue([]));
     $this->scheduledStructure->expects($this->once())->method('setStructureElementData')->with($testName, ['actions' => [], 'arguments' => []]);
     $this->prepareReaderPool('<' . $literal . ' name="' . $testName . '"/>');
     /** @var \Magento\Framework\View\Layout\Reader\Block $block */
     $block = $this->getBlock(['readerPool' => $this->readerPool]);
     $block->interpret($this->context, $this->currentElement);
 }
Exemplo n.º 10
0
 /**
  * Merge Container attributes
  *
  * @param \Magento\Framework\View\Layout\ScheduledStructure $scheduledStructure
  * @param \Magento\Framework\View\Layout\Element $currentElement
  * @return void
  */
 protected function mergeContainerAttributes(Layout\ScheduledStructure $scheduledStructure, Layout\Element $currentElement)
 {
     $containerName = $currentElement->getAttribute('name');
     $elementData = $scheduledStructure->getStructureElementData($containerName);
     if (isset($elementData['attributes'])) {
         $keys = array_keys($elementData['attributes']);
         foreach ($keys as $key) {
             if (isset($currentElement[$key])) {
                 $elementData['attributes'][$key] = (string) $currentElement[$key];
             }
         }
     } else {
         $elementData['attributes'] = [self::CONTAINER_OPT_HTML_TAG => (string) $currentElement[self::CONTAINER_OPT_HTML_TAG], self::CONTAINER_OPT_HTML_ID => (string) $currentElement[self::CONTAINER_OPT_HTML_ID], self::CONTAINER_OPT_HTML_CLASS => (string) $currentElement[self::CONTAINER_OPT_HTML_CLASS], self::CONTAINER_OPT_LABEL => (string) $currentElement[self::CONTAINER_OPT_LABEL]];
     }
     $scheduledStructure->setStructureElementData($containerName, $elementData);
 }
Exemplo n.º 11
0
 /**
  * @param bool $hasParent
  * @param int $setAsChild
  * @param int $toRemoveList
  * @param string $siblingName
  * @param bool $isAfter
  * @param int $toSortList
  * @return void
  *
  * @dataProvider scheduleElementDataProvider
  */
 public function testScheduleElement($hasParent, $setAsChild, $toRemoveList, $siblingName, $isAfter, $toSortList)
 {
     $key = 'key';
     $parentName = 'parent';
     $alias = 'alias';
     $block = 'block';
     $data = ['data'];
     $this->scheduledStructureMock->expects($this->any())->method('getStructureElement')->willReturnMap([[$key, null, [Layout\ScheduledStructure\Helper::SCHEDULED_STRUCTURE_INDEX_TYPE => $block, Layout\ScheduledStructure\Helper::SCHEDULED_STRUCTURE_INDEX_ALIAS => $alias, Layout\ScheduledStructure\Helper::SCHEDULED_STRUCTURE_INDEX_PARENT_NAME => $parentName, Layout\ScheduledStructure\Helper::SCHEDULED_STRUCTURE_INDEX_SIBLING_NAME => $siblingName, Layout\ScheduledStructure\Helper::SCHEDULED_STRUCTURE_INDEX_IS_AFTER => $isAfter]], [$parentName, null, []]]);
     $this->scheduledStructureMock->expects($this->any())->method('getStructureElementData')->willReturnMap([[$key, null, $data], [$parentName, null, $data]]);
     $this->scheduledStructureMock->expects($this->any())->method('hasStructureElement')->willReturn(true);
     $this->scheduledStructureMock->expects($this->once())->method('setElement')->with($key, [$block, $data]);
     $this->dataStructureMock->expects($this->once())->method('createElement')->with($key, ['type' => $block]);
     $this->dataStructureMock->expects($this->once())->method('hasElement')->with($parentName)->willReturn($hasParent);
     $this->dataStructureMock->expects($this->exactly($setAsChild))->method('setAsChild')->with($key, $parentName, $alias)->willReturn(true);
     $this->scheduledStructureMock->expects($this->exactly($toRemoveList))->method('setElementToBrokenParentList')->with($key);
     $this->scheduledStructureMock->expects($this->exactly($toSortList))->method('setElementToSortList')->with($parentName, $key, $siblingName, $isAfter);
     $this->helper->scheduleElement($this->scheduledStructureMock, $this->dataStructureMock, $key);
 }
Exemplo n.º 12
0
 /**
  * @param string $name
  */
 protected function prepareGenerateBlock($name)
 {
     $blockClass = 'Magento\\Framework\\View\\Element\\Template';
     $template = 'file.phtml';
     $ttl = 100;
     $xmlString = '<?xml version="1.0"?><block class="' . $blockClass . '" template="' . $template . '" ttl="' . $ttl . '"></block>';
     $xml = simplexml_load_string($xmlString, 'Magento\\Framework\\View\\Layout\\Element');
     $elementData = [\Magento\Framework\View\Layout\Element::TYPE_BLOCK, $xml, [], []];
     $this->schStructureMock->expects($this->once())->method('getElement')->with($this->equalTo($name))->will($this->returnValue($elementData));
     $this->schStructureMock->expects($this->once())->method('unsetElement')->with($this->equalTo($name))->will($this->returnSelf());
     $blockMock = $this->getMockBuilder('Magento\\Framework\\View\\Element\\Template')->setMethods(['setType', 'setNameInLayout', 'addData', 'setLayout', 'setTemplate', 'setTtl'])->disableOriginalConstructor()->getMock();
     $blockMock->expects($this->once())->method('setTemplate')->with($this->equalTo($template))->will($this->returnSelf());
     $blockMock->expects($this->once())->method('setTtl')->with($this->equalTo($ttl))->will($this->returnSelf());
     $blockMock->expects($this->once())->method('setType')->with($this->equalTo(get_class($blockMock)))->will($this->returnSelf());
     $blockMock->expects($this->once())->method('setNameInLayout')->with($this->equalTo($name))->will($this->returnSelf());
     $blockMock->expects($this->once())->method('addData')->with($this->equalTo([]))->will($this->returnSelf());
     $blockMock->expects($this->once())->method('setLayout')->with($this->equalTo($this->model))->will($this->returnSelf());
     $this->blockFactoryMock->expects($this->once())->method('createBlock')->with($this->equalTo('Magento\\Framework\\View\\Element\\Template'), $this->equalTo(['data' => []]))->will($this->returnValue($blockMock));
     $this->eventManagerMock->expects($this->once())->method('dispatch')->with($this->equalTo('core_layout_block_create_after'), $this->equalTo(['block' => $blockMock]))->will($this->returnSelf());
 }
Exemplo n.º 13
0
 /**
  * Process queue of structural elements and actually add them to structure, and schedule elements for generation
  *
  * The catch is to populate parents first, if they are not in the structure yet.
  * Since layout updates could come in arbitrary order, a case is possible where an element is declared in reference,
  * while referenced element itself is not declared yet.
  *
  * @param \Magento\Framework\View\Layout\ScheduledStructure $scheduledStructure
  * @param Layout\Data\Structure $structure
  * @param string $key in _scheduledStructure represent element name
  * @return void
  * @SuppressWarnings(PHPMD.NPathComplexity)
  * @SuppressWarnings(PHPMD.CyclomaticComplexity)
  */
 public function scheduleElement(Layout\ScheduledStructure $scheduledStructure, Layout\Data\Structure $structure, $key)
 {
     $row = $scheduledStructure->getStructureElement($key);
     $data = $scheduledStructure->getStructureElementData($key);
     // if we have reference container to not existed element
     if (!isset($row[self::SCHEDULED_STRUCTURE_INDEX_TYPE])) {
         $this->logger->critical("Broken reference: missing declaration of the element '{$key}'.");
         $scheduledStructure->unsetPathElement($key);
         $scheduledStructure->unsetStructureElement($key);
         return;
     }
     list($type, $alias, $parentName, $siblingName, $isAfter) = $row;
     $name = $this->_createStructuralElement($structure, $key, $type, $parentName . $alias);
     if ($parentName) {
         // recursively populate parent first
         if ($scheduledStructure->hasStructureElement($parentName)) {
             $this->scheduleElement($scheduledStructure, $structure, $parentName);
         }
         if ($structure->hasElement($parentName)) {
             try {
                 $structure->setAsChild($name, $parentName, $alias);
             } catch (\Exception $e) {
                 $this->logger->critical($e);
             }
         } else {
             $scheduledStructure->setElementToBrokenParentList($key);
             $this->logger->critical("Broken reference: the '{$name}' element cannot be added as child to '{$parentName}', " . 'because the latter doesn\'t exist');
         }
     }
     // Move from scheduledStructure to scheduledElement
     $scheduledStructure->unsetStructureElement($key);
     $scheduledStructure->setElement($name, [$type, $data]);
     /**
      * Some elements provide info "after" or "before" which sibling they are supposed to go
      * Make sure to populate these siblings as well and order them correctly
      */
     if ($siblingName) {
         if ($scheduledStructure->hasStructureElement($siblingName)) {
             $this->scheduleElement($scheduledStructure, $structure, $siblingName);
         }
         $structure->reorderChildElement($parentName, $name, $siblingName, $isAfter);
     }
 }
Exemplo n.º 14
0
 /**
  * Schedule reference data
  *
  * @param Layout\ScheduledStructure $scheduledStructure
  * @param Layout\Element $currentElement
  * @return void
  */
 protected function scheduleReference(Layout\ScheduledStructure $scheduledStructure, Layout\Element $currentElement)
 {
     $elementName = $currentElement->getAttribute('name');
     $data = $scheduledStructure->getStructureElementData($elementName, []);
     $this->updateScheduledData($currentElement, $data);
     $this->evaluateArguments($currentElement, $data);
     $scheduledStructure->setStructureElementData($elementName, $data);
 }
Exemplo n.º 15
0
 /**
  * @param \Magento\Framework\View\Layout\Element $currentElement
  * @param string $destination
  * @param string $siblingName
  * @param bool $isAfter
  * @param string $alias
  * @param \Magento\Framework\View\Layout\Element $parentElement
  *
  * @dataProvider processDataProvider
  */
 public function testProcess($currentElement, $destination, $siblingName, $isAfter, $alias, $parentElement)
 {
     $this->scheduledStructureMock->expects($this->any())->method('setElementToMove')->with((string) $currentElement->getAttribute('element'), [$destination, $siblingName, $isAfter, $alias]);
     $this->move->interpret($this->contextMock, $currentElement, $parentElement);
 }
Exemplo n.º 16
0
 /**
  * Get block object by name
  *
  * @param string $name
  * @return \Magento\Framework\View\Element\AbstractBlock|bool
  */
 public function getBlock($name)
 {
     if ($this->_scheduledStructure->hasElement($name)) {
         $this->_generateBlock($name);
     }
     if (isset($this->_blocks[$name])) {
         return $this->_blocks[$name];
     } else {
         return false;
     }
 }
Exemplo n.º 17
0
 /**
  * Handling reference of container
  *
  * If attribute remove="true" then add the element to list remove,
  * else merge container attributes
  *
  * @param Layout\ScheduledStructure $scheduledStructure
  * @param Layout\Element $currentElement
  * @return void
  */
 protected function containerReference(Layout\ScheduledStructure $scheduledStructure, Layout\Element $currentElement)
 {
     $containerName = $currentElement->getAttribute('name');
     $containerRemove = filter_var($currentElement->getAttribute('remove'), FILTER_VALIDATE_BOOLEAN);
     if ($containerRemove) {
         $scheduledStructure->setElementToRemoveList($containerName);
     } else {
         $this->mergeContainerAttributes($scheduledStructure, $currentElement);
     }
 }
Exemplo n.º 18
0
 /**
  * Create block and set related data
  *
  * @param \Magento\Framework\View\Layout\ScheduledStructure $scheduledStructure
  * @param \Magento\Framework\View\Layout\Data\Structure $structure
  * @param string $elementName
  * @return \Magento\Framework\View\Element\AbstractBlock
  */
 protected function generateBlock(Layout\ScheduledStructure $scheduledStructure, Layout\Data\Structure $structure, $elementName)
 {
     list(, $data) = $scheduledStructure->getElement($elementName);
     $attributes = $data['attributes'];
     if (!empty($attributes['group'])) {
         $structure->addToParentGroup($elementName, $attributes['group']);
     }
     if (!empty($attributes['display'])) {
         $structure->setAttribute($elementName, 'display', $attributes['display']);
     }
     // create block
     $className = $attributes['class'];
     $block = $this->createBlock($className, $elementName, ['data' => $this->evaluateArguments($data['arguments'])]);
     if (!empty($attributes['template'])) {
         $block->setTemplate($attributes['template']);
     }
     if (!empty($attributes['ttl'])) {
         $ttl = (int) $attributes['ttl'];
         $block->setTtl($ttl);
     }
     return $block;
 }
Exemplo n.º 19
0
 /**
  * @param array $structureElements
  *
  * @dataProvider processWithExceptionDataProvider
  * @expectedException \Magento\Framework\Exception\LocalizedException
  */
 public function testProcessWithException($structureElements)
 {
     $this->scheduledStructureMock->expects($this->once())->method('getElements')->willReturn($structureElements);
     $this->structureMock->expects($this->once())->method('setAttribute')->willReturnSelf();
     $this->container->process($this->readerContextMock, $this->generatorContextMock);
 }
Exemplo n.º 20
0
 protected function prepareScheduledStructure()
 {
     $this->scheduledStructureMock->expects($this->any())->method('getElements')->willReturn([UiComponent::TYPE => [UiComponent::TYPE, ['attributes' => ['group' => 'new_group', 'component' => 'component_name'], 'arguments' => ['attribute_1' => ['key_1' => 'value_1'], 'attribute_2' => ['key_2' => 'value_2']]]]]);
 }
Exemplo n.º 21
0
 /**
  * Schedule reference data
  *
  * @param Layout\ScheduledStructure $scheduledStructure
  * @param Layout\Element $currentElement
  * @return void
  */
 protected function scheduleReference(Layout\ScheduledStructure $scheduledStructure, Layout\Element $currentElement)
 {
     $elementName = $currentElement->getAttribute('name');
     $elementRemove = filter_var($currentElement->getAttribute('remove'), FILTER_VALIDATE_BOOLEAN);
     if ($elementRemove) {
         $scheduledStructure->setElementToRemoveList($elementName);
     } else {
         $data = $scheduledStructure->getStructureElementData($elementName, []);
         $data['attributes'] = $this->mergeBlockAttributes($data, $currentElement);
         $this->updateScheduledData($currentElement, $data);
         $this->evaluateArguments($currentElement, $data);
         $scheduledStructure->setStructureElementData($elementName, $data);
     }
 }