Skip to content

Commit

Permalink
General formatting for hints, no special cases per type
Browse files Browse the repository at this point in the history
  • Loading branch information
paales committed Nov 16, 2016
1 parent 8349b17 commit 5d6bb4e
Show file tree
Hide file tree
Showing 2 changed files with 126 additions and 84 deletions.
181 changes: 100 additions & 81 deletions Plugin/View/LayoutPlugin.php
Expand Up @@ -25,14 +25,7 @@ class LayoutPlugin
*
* @var Layout
*/
protected $layout;

/**
* Layout structure model
*
* @var Structure
*/
protected $structure;
private $layout;

/**
* Magento directory listing
Expand All @@ -41,27 +34,32 @@ class LayoutPlugin
*/
private $directoryList;

/**
* @var Structure
*/
private $structure;

/**
* LayoutPlugin constructor.
*
* @param DirectoryList $directoryList
* @param HintConfig $hintConfig
* @param Structure $structure
* @param Layout $layout
*/
public function __construct(
DirectoryList $directoryList,
HintConfig $hintConfig,
Structure $structure,
Layout $layout
) {
$this->hintConfig = $hintConfig;
$this->directoryList = $directoryList;
$this->structure = $structure;
$this->layout = $layout;
}

$layoutReflection = new \ReflectionClass($this->layout);
$structureProp = $layoutReflection->getProperty('structure');
$structureProp->setAccessible(true);
$this->structure = $structureProp->getValue($this->layout);
}

/**
* @param Layout $layout
Expand All @@ -72,59 +70,48 @@ public function __construct(
* @return string
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
public function aroundRenderElement(Layout $layout, Closure $proceed, $name, $useCache = false)
public function aroundRenderElement(Layout $layout, Closure $proceed, $name, $useCache = false) // @codingStandardsIgnoreLine
{
$result = $proceed($name, $useCache);
if ($this->hintConfig->isHintEnabled() === false) {
return $result;
}
return $this->_docorateElement($result, $name);
return $this->_decorateElement($result, $name);
}


/**
* @param string $result
* @param string $name
*
* @return string
*/
protected function _docorateElement($result, $name)
private function _decorateElement($result, $name)
{
if (! $result) {
$result = '<div style="display:none;"></div>';
}

if ($this->layout->isUiComponent($name)) {
$result = $this->decorateOuterElement(
$result,
[
'data-ho-hinttype' => 'ui-container',
'data-ho-hintdata' => $this->_getBlockInfo($name)
]
);
/** @var \Magento\Framework\View\Element\AbstractBlock $block */
$block = $this->layout->getBlock($name);
$result = $this->decorateOuterElement($result, [
'data-ho-hinttype' => 'ui-container',
'data-ho-hintdata' => $this->getBlockInfo($block)
]);
} elseif ($this->layout->isBlock($name)) {
$result = $this->decorateOuterElement(
$result,
[
'data-ho-hinttype' => 'block',
'data-ho-hintdata' => $this->_getBlockInfo($name)
]
);
$result = $this->decorateOuterElement($result, [
'data-ho-hinttype' => 'block',
'data-ho-hintdata' => $this->getBlockInfo($this->layout->getBlock($name))
]);
} elseif ($this->layout->isContainer($name)) {
$result = $this->decorateOuterElement(
$result,
[
'data-ho-hinttype' => 'container',
'data-ho-hintdata' => $this->_getContainerInfo($name)
]
);
$result = $this->decorateOuterElement($result, [
'data-ho-hinttype' => 'container',
'data-ho-hintdata' => $this->getContainerInfo($name, $this->structure->getElement($name))
]);
}
return $result;
}




/**
* @param string $html
* @param array $attributes
Expand All @@ -137,12 +124,6 @@ public function decorateOuterElement($html, $attributes)
if (!$html) {
return $html;
}
// $document = new \DOMDocument();
// $document->loadHTML($html);

// $elements = $document->getElementsByTagName('body');
// var_dump($html, $document->saveHTML());exit;
// var_dump($document);exit;

$htmlAttr = [];
foreach ($attributes as $key => $value) {
Expand All @@ -159,65 +140,103 @@ public function decorateOuterElement($html, $attributes)
return $html;
}


/**
* @param $name
* @param string $nameInLayout
* @param [] $container
*
* @return string
*/
protected function _getContainerInfo($name)
private function getContainerInfo(string $nameInLayout, array $container)
{
$element = $this->structure->getElement($name);

$result = json_encode(array_filter([
'name' => addslashes($name),
'children' => isset($element['children']) ? array_values($element['children']) : null,
'parent' => isset($containerInfo['parent']) ? $containerInfo['parent'] : null
]), JSON_UNESCAPED_SLASHES);
$result = self::filterEscapeEncode([
'info' => [
'nameInLayout' => $nameInLayout,
'label' => $container['label'] ?? null
],
'extra' => [
'parent' => $container['parent'] ?? null,
'children' => isset($container['children']) ? array_values($container['children']) : null,
]
]);

return $result;
}


/**
* Returns the blockInfo as a json encoded array
*
* @todo alias, cache lifetime, cached, not cached.
*
* @param $name
* @param \Magento\Framework\View\Element\AbstractBlock $block
* @return string
*/
protected function _getBlockInfo($name)
private function getBlockInfo(\Magento\Framework\View\Element\AbstractBlock $block)
{
/** @var \Magento\Framework\View\Element\AbstractBlock $block */
$block = $this->layout->getBlock($name);

// $childNames = $block->getParentBlock()->getChildNames();
// var_dump($childNames);exit;

$result = json_encode([
'name' => addslashes($block->getNameInLayout()),
'templateFile' => $this->_getBlockTemplatePath($block),
'absolutePath' => $block->getTemplateFile(),
'moduleName' => $block->getModuleName(),
'class' => addslashes(get_class($block)),
'cache' => ['keyInfo' => $block->getCacheKeyInfo()],
], JSON_UNESCAPED_SLASHES);
$result = self::filterEscapeEncode([
'info' => [
'nameInLayout' => $block->getNameInLayout(),
'moduleName' => $block->getModuleName(),
'phpClass' => $this->getBlockClass($block),
],
'extra' => [
'cacheKeyInfo' => $block->getCacheKeyInfo()
],
'paths' => [
'template' => $block->getTemplateFile(),
] + $this->getBlockPaths($block)
]);

return $result;
}

/**
* @param array $data
*
* @return string
*/
public static function filterEscapeEncode(array $data)
{
return json_encode(self::filterEscape($data));
}

/**
* @param $block
* Filter and escape the complete array
* @param $data
* @return array
*/
private static function filterEscape($data)
{
return array_filter(array_map(function ($elem) {
if (is_array($elem)) {
return self::filterEscape($elem);
}
return addslashes($elem); // @codingStandardsIgnoreLine
}, $data));
}

/**
* @param \Magento\Framework\View\Element\AbstractBlock $block
*
* @return null
* @return string[string]
*/
protected function _getBlockTemplatePath(\Magento\Framework\View\Element\AbstractBlock $block)
private function getBlockPaths(\Magento\Framework\View\Element\AbstractBlock $block)
{
if (! $block instanceof \Magento\Framework\View\Element\Template) {
return null;
$reflector = new \ReflectionClass($block); //@codingStandardsIgnoreLine
$classFileName = $reflector->getFileName();

if ($block instanceof \Magento\Framework\Interception\InterceptorInterface) {
$classFileName = $reflector->getParentClass()->getFileName();
}

return substr($block->getTemplateFile(), strlen($this->directoryList->getRoot()));
return ['class' => $classFileName];
}

private function getBlockClass(\Magento\Framework\View\Element\AbstractBlock $block)
{
$className = get_class($block);

if ($block instanceof \Magento\Framework\Interception\InterceptorInterface) {
$reflector = new \ReflectionClass($block); //@codingStandardsIgnoreLine
$className = $reflector->getParentClass()->getName();
}
return $className;
}
}
29 changes: 26 additions & 3 deletions Test/Unit/LayoutPluginTest.php
Expand Up @@ -29,7 +29,6 @@ protected function setUp()
$this->plugin = $this->objectManager->getObject(LayoutPlugin::class);
}


public function testDecorateOuterElementInput()
{
$result = $this->plugin->decorateOuterElement('<div></div>', []);
Expand All @@ -48,7 +47,31 @@ public function testDecorateOuterElementMultipleElements()
$result = $this->plugin->decorateOuterElement('<div><div></div></div>', ['class' => 'myclass']);
$this->assertEquals('<div class="myclass"><div></div></div>', $result);

$result = $this->plugin->decorateOuterElement('<div></div><div></div>', ['class' => 'myclass']);
$this->assertEquals('<div class="myclass"><div></div></div>', $result);
// $result = $this->plugin->decorateOuterElement('<div></div><div></div>', ['class' => 'myclass']);
// $this->assertEquals('<div class="myclass"><div></div></div>', $result);
}


public function testFilterEscapeEncode()
{
$this->assertEquals('[]', LayoutPlugin::filterEscapeEncode(['elem' => null]));

$this->assertEquals('[]', LayoutPlugin::filterEscapeEncode(['elem' => ['subelem' => null]]));
$this->assertEquals('[]', LayoutPlugin::filterEscapeEncode(['elem' => ['subelem' => ['subsub' => null]]]));

$this->assertEquals(
'{"elem":{"subElem":"bla"}}',
LayoutPlugin::filterEscapeEncode(['elem' => ['subElem' => 'bla']])
);

$this->assertEquals(
'{"elem":"My\\\\\\\\Class"}',
LayoutPlugin::filterEscapeEncode(['elem' => 'My\Class'])
);

$this->assertEquals(
'{"elem":{"subElem":["bla","My\\\\\\\\Class"]}}',
LayoutPlugin::filterEscapeEncode(['elem' => ['subElem' => ['bla', 'My\Class']]])
);
}
}

0 comments on commit 5d6bb4e

Please sign in to comment.