diff --git a/vendor/magento/module-backend/view/adminhtml/layout/default.xml b/vendor/magento/module-backend/view/adminhtml/layout/default.xml
index 1c28d5fc59350..105372537f41b 100644
--- a/vendor/magento/module-backend/view/adminhtml/layout/default.xml
+++ b/vendor/magento/module-backend/view/adminhtml/layout/default.xml
@@ -17,6 +17,7 @@
+
diff --git a/vendor/magento/module-catalog/view/frontend/layout/default.xml b/vendor/magento/module-catalog/view/frontend/layout/default.xml
index 8f414724f51db..618c8e91e5429 100644
--- a/vendor/magento/module-catalog/view/frontend/layout/default.xml
+++ b/vendor/magento/module-catalog/view/frontend/layout/default.xml
@@ -65,6 +65,7 @@
+
diff --git a/vendor/magento/module-new-relic-reporting/Model/NewRelicWrapper.php b/vendor/magento/module-new-relic-reporting/Model/NewRelicWrapper.php
index 61a4c099c5f7c..0e11aab478c53 100644
--- a/vendor/magento/module-new-relic-reporting/Model/NewRelicWrapper.php
+++ b/vendor/magento/module-new-relic-reporting/Model/NewRelicWrapper.php
@@ -14,6 +14,9 @@
*/
class NewRelicWrapper
{
+ private const NEWRELIC_APPNAME = 'newrelic.appname';
+ private const NEWRELIC_AUTO_INSTRUMENT = 'newrelic.browser_monitoring.auto_instrument';
+
/**
* Wrapper for 'newrelic_add_custom_parameter' function
*
@@ -69,6 +72,19 @@ public function setTransactionName(string $transactionName): void
}
}
+ /**
+ * Wrapper to start background transaction
+ *
+ * @return void
+ */
+ public function startBackgroundTransaction()
+ {
+ if ($this->isExtensionInstalled()) {
+ newrelic_start_transaction(ini_get(self::NEWRELIC_APPNAME));
+ newrelic_background_job();
+ }
+ }
+
/**
* Wrapper for 'newrelic_end_transaction'
*
@@ -91,4 +107,58 @@ public function isExtensionInstalled()
{
return extension_loaded('newrelic');
}
+
+ /**
+ * Checks whether automatic injection of the browser monitoring is enabled
+ *
+ * @return bool
+ */
+ public function isAutoInstrumentEnabled(): bool
+ {
+ return $this->isExtensionInstalled() && ini_get(self::NEWRELIC_AUTO_INSTRUMENT);
+ }
+
+ /**
+ * Wrapper for 'newrelic_disable_autorum'
+ *
+ * @return bool|null
+ */
+ public function disableAutorum(): ?bool
+ {
+ if (!$this->isExtensionInstalled()) {
+ return null;
+ }
+
+ return newrelic_disable_autorum();
+ }
+
+ /**
+ * Wrapper for 'newrelic_get_browser_timing_header'
+ *
+ * @param bool $includeTags
+ * @return string|null
+ */
+ public function getBrowserTimingHeader(bool $includeTags = true): ?string
+ {
+ if (!$this->isExtensionInstalled()) {
+ return null;
+ }
+
+ return newrelic_get_browser_timing_header($includeTags);
+ }
+
+ /**
+ * Wrapper for 'newrelic_get_browser_timing_footer'
+ *
+ * @param bool $includeTags
+ * @return string|null
+ */
+ public function getBrowserTimingFooter(bool $includeTags = true): ?string
+ {
+ if (!$this->isExtensionInstalled()) {
+ return null;
+ }
+
+ return newrelic_get_browser_timing_footer($includeTags);
+ }
}
diff --git a/vendor/magento/module-new-relic-reporting/Observer/DisableBrowserMonitoringAutomaticInjection.php b/vendor/magento/module-new-relic-reporting/Observer/DisableBrowserMonitoringAutomaticInjection.php
new file mode 100644
index 0000000000000..496f39debae46
--- /dev/null
+++ b/vendor/magento/module-new-relic-reporting/Observer/DisableBrowserMonitoringAutomaticInjection.php
@@ -0,0 +1,40 @@
+newRelicWrapper->isAutoInstrumentEnabled()) {
+ $this->newRelicWrapper->disableAutorum();
+ }
+ }
+}
diff --git a/vendor/magento/module-new-relic-reporting/Plugin/StatPlugin.php b/vendor/magento/module-new-relic-reporting/Plugin/StatPlugin.php
index 30dddfe11910a..f35a4e11957c6 100644
--- a/vendor/magento/module-new-relic-reporting/Plugin/StatPlugin.php
+++ b/vendor/magento/module-new-relic-reporting/Plugin/StatPlugin.php
@@ -64,6 +64,7 @@ public function beforeStart(Stat $schedule, ...$args): array
$timerName = current($args);
if ($this->isCronJob($timerName)) {
+ $this->newRelicWrapper->startBackgroundTransaction();
$this->newRelicWrapper->setTransactionName(
sprintf('Cron %s', $timerName)
);
diff --git a/vendor/magento/module-new-relic-reporting/ViewModel/BrowserMonitoringFooterJs.php b/vendor/magento/module-new-relic-reporting/ViewModel/BrowserMonitoringFooterJs.php
new file mode 100644
index 0000000000000..de4b72c87f68c
--- /dev/null
+++ b/vendor/magento/module-new-relic-reporting/ViewModel/BrowserMonitoringFooterJs.php
@@ -0,0 +1,32 @@
+newRelicWrapper->isAutoInstrumentEnabled()
+ ? $this->newRelicWrapper->getBrowserTimingFooter(false)
+ : null;
+ }
+}
diff --git a/vendor/magento/module-new-relic-reporting/ViewModel/BrowserMonitoringHeaderJs.php b/vendor/magento/module-new-relic-reporting/ViewModel/BrowserMonitoringHeaderJs.php
new file mode 100644
index 0000000000000..f45926d82d4cf
--- /dev/null
+++ b/vendor/magento/module-new-relic-reporting/ViewModel/BrowserMonitoringHeaderJs.php
@@ -0,0 +1,32 @@
+newRelicWrapper->isAutoInstrumentEnabled()
+ ? $this->newRelicWrapper->getBrowserTimingHeader(false)
+ : null;
+ }
+}
diff --git a/vendor/magento/module-new-relic-reporting/ViewModel/ContentProviderInterface.php b/vendor/magento/module-new-relic-reporting/ViewModel/ContentProviderInterface.php
new file mode 100644
index 0000000000000..e27e54e4712e2
--- /dev/null
+++ b/vendor/magento/module-new-relic-reporting/ViewModel/ContentProviderInterface.php
@@ -0,0 +1,18 @@
+
+
+
+
diff --git a/vendor/magento/module-new-relic-reporting/etc/di.xml b/vendor/magento/module-new-relic-reporting/etc/di.xml
index 4b03aecac6ffa..ad5b9e454e702 100644
--- a/vendor/magento/module-new-relic-reporting/etc/di.xml
+++ b/vendor/magento/module-new-relic-reporting/etc/di.xml
@@ -46,14 +46,6 @@
-
-
-
- - true
- - true
-
-
-
Magento\Framework\Serialize\Serializer\Json
diff --git a/vendor/magento/module-new-relic-reporting/etc/frontend/events.xml b/vendor/magento/module-new-relic-reporting/etc/frontend/events.xml
index 5829b4dd16dd1..7d46576f86344 100644
--- a/vendor/magento/module-new-relic-reporting/etc/frontend/events.xml
+++ b/vendor/magento/module-new-relic-reporting/etc/frontend/events.xml
@@ -10,4 +10,7 @@
+
+
+
diff --git a/vendor/magento/module-new-relic-reporting/view/base/layout/default.xml b/vendor/magento/module-new-relic-reporting/view/base/layout/default.xml
new file mode 100644
index 0000000000000..f3e7c115d2cb3
--- /dev/null
+++ b/vendor/magento/module-new-relic-reporting/view/base/layout/default.xml
@@ -0,0 +1,29 @@
+
+
+
+
+
+
+
+
+ Magento\NewRelicReporting\ViewModel\BrowserMonitoringHeaderJs
+
+
+
+
+
+
+
+
+ Magento\NewRelicReporting\ViewModel\BrowserMonitoringFooterJs
+
+
+
+
+
+
diff --git a/vendor/magento/module-new-relic-reporting/view/base/templates/html/inline_js.phtml b/vendor/magento/module-new-relic-reporting/view/base/templates/html/inline_js.phtml
new file mode 100644
index 0000000000000..5d652df4e61bc
--- /dev/null
+++ b/vendor/magento/module-new-relic-reporting/view/base/templates/html/inline_js.phtml
@@ -0,0 +1,18 @@
+getContentProvider();
+$content = $contentProvider->getContent();
+?>
+
+ = /* @noEscape */ $secureRenderer->renderTag('script', [], $content, false) ?>
+
diff --git a/vendor/magento/module-theme/view/base/templates/root.phtml b/vendor/magento/module-theme/view/base/templates/root.phtml
index 16948d097ab97..e7d0061c39495 100644
--- a/vendor/magento/module-theme/view/base/templates/root.phtml
+++ b/vendor/magento/module-theme/view/base/templates/root.phtml
@@ -9,6 +9,8 @@
>
= /* @noEscape */ $requireJs ?>
= /* @noEscape */ $headContent ?>
+ = /* @noEscape */ $headCritical ?>
+ = /* @noEscape */ $headAssets ?>
= /* @noEscape */ $headAdditional ?>
-
+
Magento\Theme\Block\Html\Header\CriticalCss
diff --git a/vendor/magento/framework/View/Page/Config/Renderer.php b/vendor/magento/framework/View/Page/Config/Renderer.php
index 80f6fcbfc1b54..c04a84b859e91 100644
--- a/vendor/magento/framework/View/Page/Config/Renderer.php
+++ b/vendor/magento/framework/View/Page/Config/Renderer.php
@@ -10,6 +10,11 @@
use Magento\Framework\View\Asset\GroupedCollection;
use Magento\Framework\View\Page\Config;
use Magento\Framework\View\Page\Config\Metadata\MsApplicationTileImage;
+use Psr\Log\LoggerInterface;
+use Magento\Framework\UrlInterface;
+use Magento\Framework\Escaper;
+use Magento\Framework\Stdlib\StringUtils;
+use Magento\Framework\View\Asset\MergeService;
/**
* Page config Renderer model
@@ -51,29 +56,29 @@ class Renderer implements RendererInterface
protected $pageConfig;
/**
- * @var \Magento\Framework\View\Asset\MergeService
+ * @var MergeService
*/
protected $assetMergeService;
/**
- * @var \Magento\Framework\Escaper
+ * @var UrlInterface
*/
- protected $escaper;
+ protected $urlBuilder;
/**
- * @var \Magento\Framework\Stdlib\StringUtils
+ * @var Escaper
*/
- protected $string;
+ protected $escaper;
/**
- * @var \Psr\Log\LoggerInterface
+ * @var StringUtils
*/
- protected $logger;
+ protected $string;
/**
- * @var \Magento\Framework\UrlInterface
+ * @var LoggerInterface
*/
- protected $urlBuilder;
+ protected $logger;
/**
* @var MsApplicationTileImage
@@ -82,20 +87,20 @@ class Renderer implements RendererInterface
/**
* @param Config $pageConfig
- * @param \Magento\Framework\View\Asset\MergeService $assetMergeService
- * @param \Magento\Framework\UrlInterface $urlBuilder
- * @param \Magento\Framework\Escaper $escaper
- * @param \Magento\Framework\Stdlib\StringUtils $string
- * @param \Psr\Log\LoggerInterface $logger
+ * @param MergeService $assetMergeService
+ * @param UrlInterface $urlBuilder
+ * @param Escaper $escaper
+ * @param StringUtils $string
+ * @param LoggerInterface $logger
* @param MsApplicationTileImage|null $msApplicationTileImage
*/
public function __construct(
Config $pageConfig,
- \Magento\Framework\View\Asset\MergeService $assetMergeService,
- \Magento\Framework\UrlInterface $urlBuilder,
- \Magento\Framework\Escaper $escaper,
- \Magento\Framework\Stdlib\StringUtils $string,
- \Psr\Log\LoggerInterface $logger,
+ MergeService $assetMergeService,
+ UrlInterface $urlBuilder,
+ Escaper $escaper,
+ StringUtils $string,
+ LoggerInterface $logger,
MsApplicationTileImage $msApplicationTileImage = null
) {
$this->pageConfig = $pageConfig;
@@ -134,6 +139,17 @@ public function renderHeadContent()
$result .= $this->renderMetadata();
$result .= $this->renderTitle();
$this->prepareFavicon();
+ return $result;
+ }
+
+ /**
+ * Render head assets
+ *
+ * @return string
+ */
+ public function renderHeadAssets()
+ {
+ $result = '';
$result .= $this->renderAssets($this->getAvailableResultGroups());
$result .= $this->pageConfig->getIncludes();
return $result;
@@ -210,26 +226,20 @@ protected function getMetadataTemplate($name)
switch ($name) {
case Config::META_CHARSET:
- $metadataTemplate = '' . "\n";
- break;
+ return '' . "\n";
case Config::META_CONTENT_TYPE:
- $metadataTemplate = '' . "\n";
- break;
+ return '' . "\n";
case Config::META_X_UI_COMPATIBLE:
- $metadataTemplate = '' . "\n";
- break;
+ return '' . "\n";
case Config::META_MEDIA_TYPE:
- $metadataTemplate = false;
- break;
+ return false;
default:
- $metadataTemplate = '' . "\n";
- break;
+ return '' . "\n";
}
- return $metadataTemplate;
}
/**
diff --git a/vendor/magento/framework/View/Result/Page.php b/vendor/magento/framework/View/Result/Page.php
index 2221908346f8a..d2db18def8fd2 100644
--- a/vendor/magento/framework/View/Result/Page.php
+++ b/vendor/magento/framework/View/Result/Page.php
@@ -9,9 +9,26 @@
use Magento\Framework;
use Magento\Framework\App\Response\HttpInterface as HttpResponseInterface;
use Magento\Framework\View;
+use Magento\Framework\View\Element\Template\Context;
+use Magento\Framework\View\LayoutFactory;
+use Magento\Framework\View\Layout\ReaderPool;
+use Magento\Framework\Translate\InlineInterface;
+use Magento\Framework\View\Layout\BuilderFactory;
+use Magento\Framework\View\Layout\GeneratorPool;
+use Magento\Framework\View\Page\Config\RendererInterface as PageConfigRendererInterface;
+use Magento\Framework\View\Page\Config\RendererFactory as PageConfigRendererFactory;
+use Magento\Framework\View\Page\Layout\Reader as PageLayoutReader;
+use Magento\Framework\App\RequestInterface as AppRequestInterface;
+use Magento\Framework\View\Asset\Repository as AssetRepository;
+use Psr\Log\LoggerInterface;
+use Magento\Framework\UrlInterface;
+use Magento\Framework\View\Page\Config as PageConfig;
+use Magento\Framework\View\FileSystem as ViewFileSystem;
+use Magento\Framework\App\ObjectManager;
+use Magento\Framework\View\EntitySpecificHandlesList;
/**
- * A "page" result that encapsulates page type, page configuration
+ * Class Page represents a "page" result that encapsulates page type, page configuration
* and imposes certain layout handles.
*
* The framework convention is that there will be loaded a guaranteed handle for "all pages",
@@ -35,27 +52,27 @@ class Page extends Layout
protected $pageLayout;
/**
- * @var \Magento\Framework\View\Page\Config
+ * @var PageConfig
*/
protected $pageConfig;
/**
- * @var \Magento\Framework\View\Page\Config\RendererInterface
+ * @var PageConfigRendererInterface
*/
protected $pageConfigRenderer;
/**
- * @var \Magento\Framework\View\Page\Config\RendererFactory
+ * @var PageConfigRendererFactory
*/
protected $pageConfigRendererFactory;
/**
- * @var \Magento\Framework\View\Page\Layout\Reader
+ * @var PageLayoutReader
*/
protected $pageLayoutReader;
/**
- * @var \Magento\Framework\View\FileSystem
+ * @var ViewFileSystem
*/
protected $viewFileSystem;
@@ -70,61 +87,59 @@ class Page extends Layout
protected $template;
/**
- * @var Framework\App\RequestInterface
+ * @var AppRequestInterface
*/
protected $request;
/**
- * Asset service
- *
- * @var \Magento\Framework\View\Asset\Repository
+ * @var AssetRepository
*/
protected $assetRepo;
/**
- * @var \Psr\Log\LoggerInterface
+ * @var LoggerInterface
*/
protected $logger;
/**
- * @var Framework\UrlInterface
+ * @var UrlInterface
*/
protected $urlBuilder;
/**
- * @var View\EntitySpecificHandlesList
+ * @var EntitySpecificHandlesList
*/
private $entitySpecificHandlesList;
/**
* Constructor
*
- * @param View\Element\Template\Context $context
- * @param View\LayoutFactory $layoutFactory
- * @param View\Layout\ReaderPool $layoutReaderPool
- * @param Framework\Translate\InlineInterface $translateInline
- * @param View\Layout\BuilderFactory $layoutBuilderFactory
- * @param View\Layout\GeneratorPool $generatorPool
- * @param View\Page\Config\RendererFactory $pageConfigRendererFactory
- * @param View\Page\Layout\Reader $pageLayoutReader
+ * @param Context $context
+ * @param LayoutFactory $layoutFactory
+ * @param ReaderPool $layoutReaderPool
+ * @param InlineInterface $translateInline
+ * @param BuilderFactory $layoutBuilderFactory
+ * @param GeneratorPool $generatorPool
+ * @param PageConfigRendererFactory $pageConfigRendererFactory
+ * @param PageLayoutReader $pageLayoutReader
* @param string $template
* @param bool $isIsolated
- * @param View\EntitySpecificHandlesList $entitySpecificHandlesList
+ * @param EntitySpecificHandlesList $entitySpecificHandlesList
*
* @SuppressWarnings(PHPMD.ExcessiveParameterList)
*/
public function __construct(
- View\Element\Template\Context $context,
- View\LayoutFactory $layoutFactory,
- View\Layout\ReaderPool $layoutReaderPool,
- Framework\Translate\InlineInterface $translateInline,
- View\Layout\BuilderFactory $layoutBuilderFactory,
- View\Layout\GeneratorPool $generatorPool,
- View\Page\Config\RendererFactory $pageConfigRendererFactory,
- View\Page\Layout\Reader $pageLayoutReader,
+ Context $context,
+ LayoutFactory $layoutFactory,
+ ReaderPool $layoutReaderPool,
+ InlineInterface $translateInline,
+ BuilderFactory $layoutBuilderFactory,
+ GeneratorPool $generatorPool,
+ PageConfigRendererFactory $pageConfigRendererFactory,
+ PageLayoutReader $pageLayoutReader,
$template,
$isIsolated = false,
- View\EntitySpecificHandlesList $entitySpecificHandlesList = null
+ EntitySpecificHandlesList $entitySpecificHandlesList = null
) {
$this->request = $context->getRequest();
$this->assetRepo = $context->getAssetRepository();
@@ -136,7 +151,7 @@ public function __construct(
$this->pageConfigRendererFactory = $pageConfigRendererFactory;
$this->template = $template;
$this->entitySpecificHandlesList = $entitySpecificHandlesList
- ?: \Magento\Framework\App\ObjectManager::getInstance()->get(View\EntitySpecificHandlesList::class);
+ ?: ObjectManager::getInstance()->get(EntitySpecificHandlesList::class);
parent::__construct(
$context,
$layoutFactory,
@@ -203,7 +218,7 @@ public function addDefaultHandle()
/**
* Return page configuration
*
- * @return \Magento\Framework\View\Page\Config
+ * @return PageConfig
*/
public function getConfig()
{
@@ -220,7 +235,7 @@ public function getConfig()
*/
public function addPageLayoutHandles(array $parameters = [], $defaultHandle = null, $entitySpecific = true)
{
- $handle = $defaultHandle ? $defaultHandle : $this->getDefaultLayoutHandle();
+ $handle = $defaultHandle ?: $this->getDefaultLayoutHandle();
$pageHandles = [$handle];
foreach ($parameters as $key => $value) {
$handle = $value['handle'] ?? $handle;
@@ -237,7 +252,13 @@ public function addPageLayoutHandles(array $parameters = [], $defaultHandle = nu
}
/**
+ * Render the page.
+ *
* {@inheritdoc}
+ *
+ * @param HttpResponseInterface $response The HTTP response object.
+ * @return $this
+ * @throws \Exception If the template file is not found.
*/
protected function render(HttpResponseInterface $response)
{
@@ -245,11 +266,14 @@ protected function render(HttpResponseInterface $response)
if ($this->getPageLayout()) {
$config = $this->getConfig();
$this->addDefaultBodyClasses();
+ $addCritical = $this->getLayout()->getBlock('head.critical');
$addBlock = $this->getLayout()->getBlock('head.additional'); // todo
$requireJs = $this->getLayout()->getBlock('require.js');
$this->assign([
'requireJs' => $requireJs ? $requireJs->toHtml() : null,
'headContent' => $this->pageConfigRenderer->renderHeadContent(),
+ 'headCritical' => $addCritical ? $addCritical->toHtml() : null,
+ 'headAssets' => $this->pageConfigRenderer->renderHeadAssets(),
'headAdditional' => $addBlock ? $addBlock->toHtml() : null,
'htmlAttributes' => $this->pageConfigRenderer->renderElementAttributes($config::ELEMENT_TYPE_HTML),
'headAttributes' => $this->pageConfigRenderer->renderElementAttributes($config::ELEMENT_TYPE_HEAD),
@@ -284,7 +308,9 @@ protected function addDefaultBodyClasses()
}
/**
- * @return string
+ * Get the page layout.
+ *
+ * @return string The page layout.
*/
protected function getPageLayout()
{
@@ -294,9 +320,9 @@ protected function getPageLayout()
/**
* Assign variable
*
- * @param string|array $key
- * @param mixed $value
- * @return $this
+ * @param string|array $key
+ * @param mixed $value
+ * @return $this
*/
protected function assign($key, $value = null)
{