plugin = $plugin;
$this->acfViewFactory = $acfViewFactory;
$this->acfCardFactory = $acfCardFactory;
$this->bufferLevel = 0;
}
protected function printPluginsCSS(): string
{
return '';
}
public function startBuffering(): void
{
ob_start();
$this->bufferLevel = ob_get_level();
}
public function printStylesStub(): void
{
echo '';
}
public function enqueueGoogleMapsJS(): void
{
if (!function_exists('acf_get_setting') ||
!$this->acfViewFactory->getMaps()) {
return;
}
$apiData = apply_filters('acf/fields/google_map/api', []);
$key = $apiData['key'] ?? '';
$key = !$key ?
acf_get_setting('google_api_key') :
$key;
if (!$key) {
return;
}
wp_enqueue_script(
ViewsCpt::NAME . '_maps',
$this->plugin->getAssetsUrl('front/js/maps.min.js'),
[],
$this->plugin->getVersion(),
[
'in_footer' => true,
]
);
wp_localize_script(
ViewsCpt::NAME . '_maps',
'acfViewsMaps',
$this->acfViewFactory->getMaps()
);
wp_enqueue_script(
ViewsCpt::NAME . '_google-maps',
sprintf('https://maps.googleapis.com/maps/api/js?key=%s&callback=acfViewsGoogleMaps', $key),
[
// setup deps, to make sure loaded only after plugin's maps.min.js
ViewsCpt::NAME . '_maps',
],
null,
[
'in_footer' => true,
]
);
}
public function printCustomAssets(): void
{
$allJsCode = '';
$allCssCode = $this->printPluginsCSS();
$views = $this->acfViewFactory->getRenderedViews();
foreach ($views as $view) {
$cssCode = $view->getCssCode();
// 'minify' JS
$jsCode = str_replace(["\t", "\n", "\r"], '', $view->jsCode);
$jsCode = trim($jsCode);
// no escaping, it's a CSS code, so e.g '.a > .b' shouldn't be escaped
$allCssCode .= $cssCode ?
sprintf("\n/*view-%s*/\n%s", $view->getSource(), $cssCode) :
'';
$allJsCode .= $jsCode ?
sprintf("\n/*view-%s*/\n%s", $view->getSource(), $jsCode) :
'';
}
$cards = $this->acfCardFactory->getRenderedCards();
foreach ($cards as $card) {
$cssCode = $card->getCssCode();
// 'minify' JS
$jsCode = str_replace(["\t", "\n", "\r"], '', $card->jsCode);
$jsCode = trim($jsCode);
// no escaping, it's a CSS code, so e.g '.a > .b' shouldn't be escaped
$allCssCode .= $cssCode ?
sprintf("\n/*card-%s*/\n%s", $card->getSource(), $cssCode) :
'';
$allJsCode .= $jsCode ?
sprintf("\n/*card-%s*/\n%s", $card->getSource(), $jsCode) :
'';
}
if (!$allCssCode &&
!$allJsCode) {
// do not close the buffer, if it's not ours
// (then ours will be closed automatically with the end of script execution)
if (ob_get_level() === $this->bufferLevel) {
echo ob_get_clean();
}
return;
}
// close previous buffers. Some plugins may not close, if detect that ob_get_level() is another than was
// e.g. 'lightbox-photoswipe'
while (ob_get_level() > $this->bufferLevel) {
echo ob_get_clean();
}
$pageContent = ob_get_clean();
$cssTag = $allCssCode ?
sprintf("", $allCssCode) :
'';
$pageContent = str_replace('', $cssTag, $pageContent);
echo $pageContent;
if ($allJsCode) {
printf("", $allJsCode);
}
}
public function makeEnqueueJSAsync(string $tag, string $handle): string
{
if (!in_array($handle, [
ViewsCpt::NAME . '_maps',
ViewsCpt::NAME . '_google-maps'
], true)) {
return $tag;
}
// defer, not async as order should be kept (google-maps will call a callback from maps' js)
return str_replace(' src', ' defer src', $tag);
}
public function setHooks(): void
{
add_action('wp_footer', [$this, 'enqueueGoogleMapsJS']);
// printCustomAssets() contains ob_get_clean, so must be executed after all other scripts
add_action('wp_footer', [$this, 'printCustomAssets'], 9999);
add_action('wp_head', [$this, 'printStylesStub']);
// don't use 'get_header', as it doesn't work in blocks theme
add_action('template_redirect', [$this, 'startBuffering']);
add_filter('script_loader_tag', [$this, 'makeEnqueueJSAsync'], 10, 2);
}
}