I have following PHP function which converts shortcode such as
[column]
[row]
[column][/column]
[/row]
[/column]
To nested array
Array
(
[0] => Array
(
[tag] => column
[attributes] => Array
(
)
[content] => Array
(
[0] => Array
(
[tag] => row
[attributes] => Array
(
)
[content] => Array
(
[0] => Array
(
[tag] => column
[attributes] => Array
(
)
[content] =>
)
)
)
)
)
)
This works fine, if I have a single [column] as child, but if I have multiple column as child which is
[column]
[row]
[column][/column]
[column][/column]
[/row]
[/column]
Then it gives me incorrect nested array, which is
Array
(
[0] => Array
(
[tag] => column
[attributes] => Array
(
)
[content] => Array
(
[0] => Array
(
[tag] => row
[attributes] => Array
(
)
[content] => Array
(
[0] => Array
(
[tag] => column
[attributes] => Array
(
)
[content] =>
)
)
)
)
)
[1] => Array
(
[tag] => column
[attributes] => Array
(
)
[content] =>
)
)
Here is my PHP function
protected function shortCodeToArray($inputString)
{
$itemArray = [];
$openingTag = '/[(w+)(?:s+([^]]*))?](.*?)([/1]|$)/s';
preg_match_all($openingTag, $inputString, $matches, PREG_SET_ORDER);
foreach ($matches as $match) {
$tagName = $match[1];
$paramString = isset($match[2]) ? $match[2] : '';
$content = $match[3];
$nestedShortcodes = $this->shortCodeToArray($content);
$itemArray[] = [
'tag' => $tagName,
'attributes' => $this->parseShortcodeParameters($paramString),
'content' => is_array($nestedShortcodes) && !empty($nestedShortcodes) ? $nestedShortcodes : $content,
];
}
return $itemArray;
}
protected function parseShortcodeParameters($paramString)
{
$params = [];
preg_match_all('/(w+)s*=s*["']([^"']+)["']/', $paramString, $matches);
for ($i = 0; $i < count($matches[0]); $i++) {
$paramName = $matches[1][$i];
$paramValue = $matches[2][$i];
$params[$paramName] = $paramValue;
}
return $params;
}
Where am I going wrong here?
2
Answers
Here is how I ended up doing it, thanks to @Markus Zeller and from another SO post which I am unable to find now.
Although this worked, the
xml -> json -> array
created its own syntax and I wanted it in specific format withhas_children
andchildren
keys, hence I am ended up using this functionWhat about the idea to convert it to HTML tags and use DOM Parser?
Outputting
Now you can traverse the DOMDocument like you want and even manipulate in a simple way.
Update
When having it as DOM Document you can traverse the whole tree and convert to an array.
See Demo: https://3v4l.org/h1eMR