private function group_body_components($components)
{
$new_components = array();
$body_collector = null;
$i = 0;
$len = count($components);
while ($i < $len) {
$component = $components[$i];
// If the component is not body, no need to group, just add.
if ('body' != $component['role']) {
if (!is_null($body_collector)) {
$body_collector['text'] = $body_collector['text'];
$new_components[] = $body_collector;
$body_collector = null;
}
$new_components[] = $component;
$i++;
continue;
}
// If the component is a body, test if it is an anchor target. For
// grouping an anchor target body several things need to happen:
if (isset($component['identifier']) && isset($components[$i + 1]['anchor']) && isset($components[$i + 2]['role']) && 'body' == $components[$i + 2]['role'] && !isset($components[$i + 2]['identifier'])) {
// Collect
if (!is_null($body_collector)) {
$body_collector['text'] = $body_collector['text'];
$new_components[] = $body_collector;
$body_collector = null;
}
$new_components[] = $components[$i + 1];
$body_collector = $component;
$body_collector['text'] .= $components[$i + 2]['text'];
$i += 3;
continue;
}
// Another case for anchor target grouping is when the component was anchored
// to the next element rather than the previous one, in that case:
if (isset($component['identifier']) && isset($components[$i + 1]['role']) && 'body' == $components[$i + 1]['role'] && !isset($components[$i + 1]['identifier'])) {
// Collect
if (!is_null($body_collector)) {
$body_collector['text'] = $body_collector['text'];
$new_components[] = $body_collector;
$body_collector = null;
}
$body_collector = $component;
$body_collector['text'] .= $components[$i + 1]['text'];
$i += 2;
continue;
}
// If the component was an anchor target but failed to match the
// requirements for grouping, just add it, don't group it.
if (isset($component['identifier'])) {
if (!is_null($body_collector)) {
$body_collector['text'] = $body_collector['text'];
$new_components[] = $body_collector;
$body_collector = null;
}
$new_components[] = $component;
} else {
// The component is not an anchor target, just collect.
if (is_null($body_collector)) {
$body_collector = $component;
} else {
$body_collector['text'] .= $component['text'];
}
}
$i++;
}
// Make a final check for the body collector, as it might not be empty
if (!is_null($body_collector)) {
$body_collector['text'] = $body_collector['text'];
$new_components[] = $body_collector;
}
// Trim all body components before returning.
// Also set the layout for the final body component.
$cover_index = null;
foreach ($new_components as $i => $component) {
if ('body' == $component['role']) {
$new_components[$i]['text'] = trim($new_components[$i]['text']);
if ($i + 1 === count($new_components)) {
$new_components[$i]['layout'] = 'body-layout-last';
}
}
// Find the location of the cover for later
if ('header' == $component['role']) {
$cover_index = $i;
}
}
// Finally, all components after the cover must be grouped
// to avoid issues with parallax text scroll.
//
// If no cover was found, this is unnecessary.
if (null !== $cover_index) {
$regrouped_components = array_slice($new_components, 0, $cover_index + 1);
if (count($new_components) > $cover_index + 1) {
$regrouped_components[] = array('role' => 'container', 'layout' => array('columnStart' => 0, 'columnSpan' => 7, 'ignoreDocumentMargin' => true), 'style' => array('backgroundColor' => $this->get_setting('body_background_color')), 'components' => array_slice($new_components, $cover_index + 1));
}
} else {
$regrouped_components = $new_components;
}
return $regrouped_components;
}