_name = $name; $this->types = ['markup', 'template', 'callback', 'scriptFile', 'scriptUrl', 'script', 'jquery', 'settings', 'style', 'styleFile', 'styleUrl']; $this->defaults['region'] = $name; // Placeholder which represents any of the default content generated by the main Smarty template $this->add([ 'name' => 'default', 'type' => 'markup', 'markup' => '', 'weight' => 0, ]); } /** * Render all the snippets in a region. * * @param string $default * HTML, the initial content of the region. * @param bool $allowCmsOverride * Allow CMS to override rendering of region. * @return string, HTML */ public function render($default, $allowCmsOverride = TRUE) { // $default is just another part of the region if (is_array($this->snippets['default'])) { $this->snippets['default']['markup'] = $default; } Civi::dispatcher()->dispatch('civi.region.render', \Civi\Core\Event\GenericHookEvent::create(['region' => $this])); $this->sort(); $cms = CRM_Core_Config::singleton()->userSystem; $smarty = CRM_Core_Smarty::singleton(); $html = ''; $renderSnippet = function($snippet) use (&$html, $smarty, $cms, $allowCmsOverride, &$renderSnippet) { switch ($snippet['type']) { case 'markup': $html .= $snippet['markup']; break; case 'template': $tmp = $smarty->get_template_vars('snippet'); $smarty->assign('snippet', $snippet); $html .= $smarty->fetch($snippet['template']); $smarty->assign('snippet', $tmp); break; case 'callback': $args = $snippet['arguments'] ?? array(&$snippet, &$html); $html .= call_user_func_array($snippet['callback'], $args); break; case 'scriptUrl': if (!$allowCmsOverride || !$cms->addScriptUrl($snippet['scriptUrl'], $this->_name)) { $html .= sprintf("\n", $snippet['scriptUrl']); } break; case 'jquery': $renderSnippet([ 'type' => 'script', 'script' => sprintf("CRM.\$(function(\$) {\n%s\n});", $snippet['jquery']), ]); break; case 'scriptFile': foreach ($snippet['scriptFileUrls'] as $url) { $html .= $renderSnippet(['type' => 'scriptUrl', 'scriptUrl' => $url] + $snippet); } break; case 'script': if (!$allowCmsOverride || !$cms->addScript($snippet['script'], $this->_name)) { $html .= sprintf("\n", $snippet['script']); } break; case 'styleFile': foreach ($snippet['styleFileUrls'] as $url) { $html .= $renderSnippet(['type' => 'styleUrl', 'styleUrl' => $url] + $snippet); } break; case 'styleUrl': if (!$allowCmsOverride || !$cms->addStyleUrl($snippet['styleUrl'], $this->_name)) { $html .= sprintf("\n", $snippet['styleUrl']); } break; case 'style': if (!$allowCmsOverride || !$cms->addStyle($snippet['style'], $this->_name)) { $html .= sprintf("\n", $snippet['style']); } break; case 'settings': $settingsData = json_encode($this->getSettings(), JSON_UNESCAPED_SLASHES); $js = "(function(vars) { if (window.CRM) CRM.$.extend(true, CRM, vars); else window.CRM = vars; })($settingsData)"; $html .= sprintf("\n", $js); break; default: throw new CRM_Core_Exception(ts('Snippet type %1 is unrecognized', [1 => $snippet['type']])); } }; foreach ($this->snippets as $snippet) { if (empty($snippet['disabled'])) { $renderSnippet($snippet); } } return $html; } }