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

Enabling the use of looping (for in ..) into Template.php #9401

Merged
merged 12 commits into from
Aug 21, 2017
62 changes: 62 additions & 0 deletions lib/internal/Magento/Framework/Filter/Template.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,11 @@ class Template implements \Zend_Filter_Interface
const CONSTRUCTION_IF_PATTERN = '/{{if\s*(.*?)}}(.*?)({{else}}(.*?))?{{\\/if\s*}}/si';

const CONSTRUCTION_TEMPLATE_PATTERN = '/{{(template)(.*?)}}/si';

/**
* Looping regular expression
*/
const LOOP_PATTERN = '/{{loop(.*?)delimiter=(.*?)}}(.*?){{\/loop}}/si';

/**#@-*/

Expand Down Expand Up @@ -131,6 +136,8 @@ public function filter($value)
}
}

$value = $this->_filterLoop($value);

if (preg_match_all(self::CONSTRUCTION_PATTERN, $value, $constructions, PREG_SET_ORDER)) {
foreach ($constructions as $construction) {
$callback = [$this, $construction[1] . 'Directive'];
Expand Down Expand Up @@ -371,4 +378,59 @@ protected function getStackArgs($stack)
}
return $stack;
}

/**
* Filter the string as template.
*
* @param string $value
* @return string
*/
protected function _filterLoop($value)
{
if (preg_match_all(self::LOOP_PATTERN, $value, $constructions, PREG_SET_ORDER)) {
foreach ($constructions as $construction) {

$full_text_to_replace = $construction[0];
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please use CamelCase style for variable names

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok.

$objectArrayData = $this->_getVariable($construction[1], '');
$delimiter = $construction[2];
$loop_text_to_replace = $construction[3];

if (is_array($objectArrayData) || $objectArrayData instanceof Varien_Data_Collection) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should allow more than arrays and object collections in here.
You should use is_array($data) || ($data instanceof Traversable).

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Applied :)


$loopText = [];
foreach ($objectArrayData as $k => $objectData) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why do we need $k variable?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is not needed. Will be removed.


if (!$objectData instanceof Varien_Object) { // is array?

if (!is_array($objectData)) {
continue;
}

$_item = new Varien_Object();
$_item->setData($k, $objectData);
$objectData = $_item;
}

$this->_templateVars['item'] = $objectData;

if (preg_match_all(self::CONSTRUCTION_PATTERN, $loop_text_to_replace, $attributes, PREG_SET_ORDER)) {

$subText = $loop_text_to_replace;
foreach ($attributes as $attribute) {
$text = $this->_getVariable($attribute[2], '');
$subText = str_replace($attribute[0], $text, $subText);
}
$loopText[] = $subText;
}
unset($this->_templateVars['item']);

}
$replaceText = implode($delimiter, $loopText);
$value = str_replace($full_text_to_replace, $replaceText, $value);
}
}
}

return $value;
}
}