/** * @param string $sourceFilePath * @return string */ public function process($sourceFilePath) { $options = ['relativeUrls' => false, 'compress' => $this->appState->getMode() !== State::MODE_DEVELOPER]; try { $parser = new \Less_Parser($options); $parser->parseFile($sourceFilePath, ''); return $parser->getCss(); } catch (\Exception $e) { $messagePrefix = 'CSS compilation from LESS '; $this->logger->critical($messagePrefix . $e->getMessage()); return $messagePrefix . $e->getMessage(); } }
/** * @param \Magento\Framework\Controller\ResultInterface $subject * @param callable $proceed * @param ResponseHttp $response * @return \Magento\Framework\Controller\ResultInterface * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ public function aroundRenderResult(\Magento\Framework\Controller\ResultInterface $subject, \Closure $proceed, ResponseHttp $response) { $result = $proceed($response); $usePlugin = $this->registry->registry('use_page_cache_plugin'); if (!$usePlugin || !$this->config->isEnabled() || $this->config->getType() != \Magento\PageCache\Model\Config::BUILT_IN) { return $result; } if ($this->state->getMode() == \Magento\Framework\App\State::MODE_DEVELOPER) { $cacheControlHeader = $response->getHeader('Cache-Control'); if ($cacheControlHeader instanceof \Zend\Http\Header\HeaderInterface) { $response->setHeader('X-Magento-Cache-Control', $cacheControlHeader->getFieldValue()); } $response->setHeader('X-Magento-Cache-Debug', 'MISS', true); } $tagsHeader = $response->getHeader('X-Magento-Tags'); $tags = []; if ($tagsHeader) { $tags = explode(',', $tagsHeader->getFieldValue()); $response->clearHeader('X-Magento-Tags'); } $tags = array_unique(array_merge($tags, [\Magento\PageCache\Model\Cache\Type::CACHE_TAG])); $response->setHeader('X-Magento-Tags', implode(',', $tags)); $this->kernel->process($response); return $result; }
/** * Check whether asset minification is on for specified content type * * @param string $contentType * @return bool */ public function isEnabled($contentType) { if (!isset($this->configCache[self::XML_PATH_MINIFICATION_ENABLED][$contentType])) { $this->configCache[self::XML_PATH_MINIFICATION_ENABLED][$contentType] = $this->appState->getMode() != State::MODE_DEVELOPER && (bool) $this->scopeConfig->isSetFlag(sprintf(self::XML_PATH_MINIFICATION_ENABLED, $contentType), $this->scope); } return $this->configCache[self::XML_PATH_MINIFICATION_ENABLED][$contentType]; }
/** * Make sure the aggregated configuration is materialized * * By default write the file if it doesn't exist, but in developer mode always do it. * * @param string $relPath * @return void */ private function ensureSourceFile($relPath) { $dir = $this->filesystem->getDirectoryWrite(\Magento\Framework\App\Filesystem::STATIC_VIEW_DIR); if ($this->appState->getMode() == \Magento\Framework\App\State::MODE_DEVELOPER || !$dir->isExist($relPath)) { $dir->writeFile($relPath, $this->config->getConfig()); } }
/** * @param string $sourceFilePath * @return string */ public function process($sourceFilePath) { $options = ['relativeUrls' => false, 'compress' => $this->appState->getMode() !== State::MODE_DEVELOPER]; $parser = new \Less_Parser($options); $parser->parseFile($sourceFilePath, ''); return $parser->getCss(); }
public function testProcess() { $sourceFilePath = realpath(__DIR__ . '/_files/oyejorge.less'); $expectedCss = $this->state->getMode() === State::MODE_DEVELOPER ? file_get_contents(__DIR__ . '/_files/oyejorge_dev.css') : file_get_contents(__DIR__ . '/_files/oyejorge.css'); $actualCss = $this->model->process($sourceFilePath); $this->assertEquals($this->cutCopyrights($expectedCss), $actualCss); }
/** * Retrieve deployment version of static files * * @return string */ public function getValue() { if (!$this->cachedValue) { $this->cachedValue = $this->readValue($this->appState->getMode()); } return $this->cachedValue; }
/** * @inheritdoc * @throws ContentProcessorException */ public function processContent(File $asset) { $path = $asset->getPath(); try { $parser = new \Less_Parser(['relativeUrls' => false, 'compress' => $this->appState->getMode() !== State::MODE_DEVELOPER]); $content = $this->assetSource->getContent($asset); if (trim($content) === '') { return ''; } $tmpFilePath = $this->temporaryFile->createFile($path, $content); gc_disable(); $parser->parseFile($tmpFilePath, ''); $content = $parser->getCss(); gc_enable(); if (trim($content) === '') { $errorMessage = PHP_EOL . self::ERROR_MESSAGE_PREFIX . PHP_EOL . $path; $this->logger->critical($errorMessage); throw new ContentProcessorException(new Phrase($errorMessage)); } return $content; } catch (\Exception $e) { $errorMessage = PHP_EOL . self::ERROR_MESSAGE_PREFIX . PHP_EOL . $path . PHP_EOL . $e->getMessage(); $this->logger->critical($errorMessage); throw new ContentProcessorException(new Phrase($errorMessage)); } }
/** * @param \Magento\Framework\Event\ObserverInterface $object * @param Observer $observer * @return $this * @throws \LogicException */ protected function _callObserverMethod($object, $observer) { if ($object instanceof \Magento\Framework\Event\ObserverInterface) { $object->execute($observer); } elseif ($this->_appState->getMode() == \Magento\Framework\App\State::MODE_DEVELOPER) { throw new \LogicException(sprintf('Observer "%s" must implement interface "%s"', get_class($object), 'Magento\\Framework\\Event\\ObserverInterface')); } return $this; }
/** * Performs non-existent observer method calls protection * * @param object $object * @param string $method * @param Observer $observer * @return $this * @throws \LogicException */ protected function _callObserverMethod($object, $method, $observer) { if (method_exists($object, $method) && is_callable([$object, $method])) { $object->{$method}($observer); } elseif ($this->_appState->getMode() == \Magento\Framework\App\State::MODE_DEVELOPER) { throw new \LogicException('Method "' . $method . '" is not defined in "' . get_class($object) . '"'); } return $this; }
/** * Wrap template with the debugging hints in comments * * @param Template $subject * @param string $result * * @return string */ public function afterToHtml(Template $subject, $result) { if ($this->scopeConfig->getValue(self::XML_PATH_DEBUG_TEMPLATE_HINTS, ScopeInterface::SCOPE_STORE) && $this->appState->getMode() === State::MODE_DEVELOPER) { $name = $subject->getNameInLayout(); $template = $subject->getTemplateFile(); $class = get_class($subject); $result = "<!-- BEGIN {$name} using {$template} \n" . $class . '-->' . $result . "<!-- END {$name} using {$template} -->"; } return $result; }
/** * Add new theme from filesystem * * @param AbstractAction $subject * @param RequestInterface $request * * @return void * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ public function beforeDispatch(AbstractAction $subject, RequestInterface $request) { try { if ($this->appState->getMode() != AppState::MODE_PRODUCTION) { $this->themeRegistration->register(); } } catch (LocalizedException $e) { $this->logger->critical($e); } }
/** * @param \Magento\Framework\App\FrontControllerInterface $subject * @param callable $proceed * @param \Magento\Framework\App\RequestInterface $request * @return false|\Magento\Framework\App\Response\Http|\Magento\Framework\Controller\ResultInterface * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ public function aroundDispatch(\Magento\Framework\App\FrontControllerInterface $subject, \Closure $proceed, \Magento\Framework\App\RequestInterface $request) { $response = $proceed($request); if ($this->config->getType() == \Magento\PageCache\Model\Config::VARNISH && $this->config->isEnabled() && $response instanceof \Magento\Framework\App\Response\Http) { $this->version->process(); if ($this->state->getMode() == \Magento\Framework\App\State::MODE_DEVELOPER) { $response->setHeader('X-Magento-Debug', 1); } } return $response; }
/** * {@inheritdoc} */ public function publish(Asset\LocalInterface $asset) { if ($this->appState->getMode() === \Magento\Framework\App\State::MODE_DEVELOPER) { return false; } $dir = $this->filesystem->getDirectoryRead(\Magento\Framework\App\Filesystem::STATIC_VIEW_DIR); if ($dir->isExist($asset->getPath())) { return true; } return $this->publishAsset($asset); }
/** * @param \Magento\Framework\Controller\ResultInterface $subject * @param callable $proceed * @param ResponseHttp $response * @return \Magento\Framework\Controller\ResultInterface */ public function aroundRenderResult(\Magento\Framework\Controller\ResultInterface $subject, \Closure $proceed, ResponseHttp $response) { $proceed($response); $usePlugin = $this->registry->registry('use_page_cache_plugin'); if ($this->config->getType() == \Magento\PageCache\Model\Config::VARNISH && $this->config->isEnabled() && $usePlugin) { $this->version->process(); if ($this->state->getMode() == \Magento\Framework\App\State::MODE_DEVELOPER) { $response->setHeader('X-Magento-Debug', 1); } } return $subject; }
/** * @param string $sourceFilePath * @return string */ public function process($sourceFilePath) { $options = ['relativeUrls' => false, 'compress' => $this->appState->getMode() !== State::MODE_DEVELOPER]; try { $parser = new \Less_Parser($options); $parser->parseFile($sourceFilePath, ''); return $parser->getCss(); } catch (\Exception $e) { $errorMessage = self::ERROR_MESSAGE_PREFIX . $e->getMessage(); $this->logger->critical($errorMessage); return $errorMessage; } }
/** * @param \Magento\Framework\View\Layout $subject * @param callable $proceed * @param string $name * @return string * @throws \Exception * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ public function aroundRenderNonCachedElement(\Magento\Framework\View\Layout $subject, \Closure $proceed, $name) { $result = ''; try { $result = $proceed($name); } catch (\Exception $e) { if ($this->appState->getMode() === State::MODE_DEVELOPER) { throw $e; } $message = $e instanceof LocalizedException ? $e->getLogMessage() : $e->getMessage(); $this->logger->critical($message); } return $result; }
/** * Parse Request body into array of params. * * @param string $encodedBody Posted content from request. * @return array|null Return NULL if content is invalid. * @throws \InvalidArgumentException * @throws \Magento\Webapi\Exception If decoding error was encountered. */ public function deserialize($encodedBody) { if (!is_string($encodedBody)) { throw new \InvalidArgumentException(sprintf('"%s" data type is invalid. String is expected.', gettype($encodedBody))); } try { $decodedBody = $this->_helper->jsonDecode($encodedBody); } catch (\Zend_Json_Exception $e) { if ($this->_appState->getMode() !== State::MODE_DEVELOPER) { throw new \Magento\Webapi\Exception(__('Decoding error.')); } else { throw new \Magento\Webapi\Exception(__('Decoding error: %1%2%3%4', PHP_EOL, $e->getMessage(), PHP_EOL, $e->getTraceAsString())); } } return $decodedBody; }
/** * Get storage instance * * @param array $arguments * @return \Magento\Store\Model\StoreManagerInterface * @throws \InvalidArgumentException */ public function get(array $arguments = array()) { $className = $this->_appState->isInstalled() ? $this->_installedStorageClassName : $this->_defaultStorageClassName; if (false == isset($this->_cache[$className])) { /** @var $storage \Magento\Store\Model\StoreManagerInterface */ $storage = $this->_objectManager->create($className, $arguments); if (false === $storage instanceof \Magento\Store\Model\StoreManagerInterface) { throw new \InvalidArgumentException($className . ' doesn\'t implement \\Magento\\Store\\Model\\StoreManagerInterface'); } $this->_cache[$className] = $storage; if ($className === $this->_installedStorageClassName) { $this->_reinitStores($storage, $arguments); $useSid = $this->_scopeConfig->isSetFlag(\Magento\Framework\Session\SidResolver::XML_PATH_USE_FRONTEND_SID, \Magento\Store\Model\ScopeInterface::SCOPE_STORE, $storage->getStore()); $this->_sidResolver->setUseSessionInUrl($useSid); $this->_eventManager->dispatch('core_app_init_current_store_after'); $store = $storage->getStore(true); $logActive = $this->_scopeConfig->isSetFlag('dev/log/active', \Magento\Store\Model\ScopeInterface::SCOPE_STORE, $store); if ($logActive || $this->_appState->getMode() === \Magento\Framework\App\State::MODE_DEVELOPER) { $logFile = $this->_scopeConfig->getValue('dev/log/file', \Magento\Store\Model\ScopeInterface::SCOPE_STORE, $store); $logExceptionFile = $this->_scopeConfig->getValue('dev/log/exception_file', \Magento\Store\Model\ScopeInterface::SCOPE_STORE, $store); $this->_log->unsetLoggers(); $this->_log->addStreamLog(\Magento\Framework\Logger::LOGGER_SYSTEM, $logFile, $this->_writerModel); $this->_log->addStreamLog(\Magento\Framework\Logger::LOGGER_EXCEPTION, $logExceptionFile, $this->_writerModel); } } } return $this->_cache[$className]; }
/** * Finds requested resource and provides it to the client * * @return \Magento\Framework\App\ResponseInterface * @throws \Exception */ public function launch() { $appMode = $this->state->getMode(); if ($appMode == \Magento\Framework\App\State::MODE_PRODUCTION) { $this->response->setHttpResponseCode(404); } else { try { $path = $this->request->get('resource'); $params = $this->parsePath($path); $this->state->setAreaCode($params['area']); $this->objectManager->configure($this->configLoader->load($params['area'])); $file = $params['file']; unset($params['file']); $asset = $this->assetRepo->createAsset($file, $params); $this->response->setFilePath($asset->getSourceFile()); $this->publisher->publish($asset); } catch (\Exception $e) { if ($appMode == \Magento\Framework\App\State::MODE_DEVELOPER) { throw $e; } $this->response->setHttpResponseCode(404); } } return $this->response; }
public function testRemoveBroken() { if ($this->state->getMode() === State::MODE_DEVELOPER) { $this->setExpectedException('OutOfBoundsException'); } $this->_getLayoutModel('remove_broken.xml'); }
/** * Reorder a child of a specified element * * If $offsetOrSibling is null, it will put the element to the end * If $offsetOrSibling is numeric (integer) value, it will put the element after/before specified position * Otherwise -- after/before specified sibling * * @param string $parentName * @param string $childName * @param string|int|null $offsetOrSibling * @param bool $after * @return void */ public function reorderChildElement($parentName, $childName, $offsetOrSibling, $after = true) { if (is_numeric($offsetOrSibling)) { $offset = (int) abs($offsetOrSibling) * ($after ? 1 : -1); $this->reorderChild($parentName, $childName, $offset); } elseif (null === $offsetOrSibling) { $this->reorderChild($parentName, $childName, null); } else { $children = array_keys($this->getChildren($parentName)); if ($this->getChildId($parentName, $offsetOrSibling) !== false) { $offsetOrSibling = $this->getChildId($parentName, $offsetOrSibling); } $sibling = $this->_filterSearchMinus($offsetOrSibling, $children, $after); if ($childName !== $sibling) { $siblingParentName = $this->getParentId($sibling); if ($parentName !== $siblingParentName) { if ($this->state->getMode() === State::MODE_DEVELOPER) { $this->logger->critical("Broken reference: the '{$childName}' tries to reorder itself towards '{$sibling}', but " . "their parents are different: '{$parentName}' and '{$siblingParentName}' respectively."); } return; } $this->reorderToSibling($parentName, $childName, $sibling, $after ? 1 : -1); } } }
/** * Generate and set HTTP response code, error messages to Response object. * * @return $this */ protected function _renderMessages() { $responseHttpCode = null; /** @var \Exception $exception */ foreach ($this->getException() as $exception) { $maskedException = $this->_errorProcessor->maskException($exception); $messageData = array('message' => $maskedException->getMessage()); if ($maskedException->getErrors()) { $messageData['errors'] = []; foreach ($maskedException->getErrors() as $errorMessage) { $errorData['message'] = $errorMessage->getRawMessage(); $errorData['parameters'] = $errorMessage->getParameters(); $messageData['errors'][] = $errorData; } } if ($maskedException->getCode()) { $messageData['code'] = $maskedException->getCode(); } if ($maskedException->getDetails()) { $messageData['parameters'] = $maskedException->getDetails(); } if ($this->_appState->getMode() == \Magento\Framework\App\State::MODE_DEVELOPER) { $messageData['trace'] = $exception->getTraceAsString(); } $responseHttpCode = $maskedException->getHttpCode(); } // set HTTP code of the last error, Content-Type, and all rendered error messages to body $this->setHttpResponseCode($responseHttpCode); $this->setMimeType($this->_renderer->getMimeType()); $this->setBody($this->_renderer->render($messageData)); return $this; }
/** * Get existing file name, using fallback mechanism * * @param string $area * @param ThemeInterface $themeModel * @param string $file * @param string|null $module * @return string|bool */ public function getFile($area, ThemeInterface $themeModel, $file, $module = null) { $template = parent::getFile($area, $themeModel, $file, $module); if ($template && $this->assetConfig->isMinifyHtml()) { switch ($this->appState->getMode()) { case State::MODE_PRODUCTION: return $this->templateMinifier->getPathToMinified($template); case State::MODE_DEFAULT: return $this->templateMinifier->getMinified($template); case State::MODE_DEVELOPER: default: return $template; } } return $template; }
/** * Handle exceptions during rendering process * * @param \Exception $cause * @throws \Exception * @return void */ protected function handleRenderException(\Exception $cause) { if ($this->appState->getMode() === State::MODE_DEVELOPER) { throw $cause; } $message = $cause instanceof LocalizedException ? $cause->getLogMessage() : $cause->getMessage(); $this->logger->critical($message); }
/** * Return merged assets, if merging is enabled for a given content type * * @param MergeableInterface[] $assets * @param string $contentType * @return array|\Iterator * @throws \InvalidArgumentException */ public function getMergedAssets(array $assets, $contentType) { $isCss = $contentType == 'css'; $isJs = $contentType == 'js'; if (!$isCss && !$isJs) { throw new \InvalidArgumentException("Merge for content type '{$contentType}' is not supported."); } $isCssMergeEnabled = $this->config->isMergeCssFiles(); $isJsMergeEnabled = $this->config->isMergeJsFiles(); if ($isCss && $isCssMergeEnabled || $isJs && $isJsMergeEnabled) { $mergeStrategyClass = \Magento\Framework\View\Asset\MergeStrategy\FileExists::class; if ($this->state->getMode() === \Magento\Framework\App\State::MODE_DEVELOPER) { $mergeStrategyClass = \Magento\Framework\View\Asset\MergeStrategy\Checksum::class; } $mergeStrategy = $this->objectManager->get($mergeStrategyClass); $assets = $this->objectManager->create('Magento\\Framework\\View\\Asset\\Merged', ['assets' => $assets, 'mergeStrategy' => $mergeStrategy]); } return $assets; }
/** * Show error as exception or log it * * @param string $errorMessage * @throws \Exception * @return void */ protected function _processError($errorMessage) { if ($this->_appState->getMode() == \Magento\Framework\App\State::MODE_DEVELOPER) { parent::_processError($errorMessage); } else { $exception = new \Exception($errorMessage); $errorMessage .= $exception->getTraceAsString(); $this->_logger->log($errorMessage, \Zend_Log::ERR); } }
/** * Finds requested resource and provides it to the client * * @return \Magento\Framework\App\ResponseInterface * @throws \Exception */ public function launch() { // disabling profiling when retrieving static resource \Magento\Framework\Profiler::reset(); $appMode = $this->state->getMode(); if ($appMode == \Magento\Framework\App\State::MODE_PRODUCTION) { $this->response->setHttpResponseCode(404); } else { $path = $this->request->get('resource'); $params = $this->parsePath($path); $this->state->setAreaCode($params['area']); $this->objectManager->configure($this->configLoader->load($params['area'])); $file = $params['file']; unset($params['file']); $asset = $this->assetRepo->createAsset($file, $params); $this->response->setFilePath($asset->getSourceFile()); $this->publisher->publish($asset); } return $this->response; }
/** * Render exception as XML. * * @return string */ public function toXml() { if ($this->appState->getMode() == State::MODE_DEVELOPER) { $this->addDetails([self::NODE_DETAIL_TRACE => "<![CDATA[{$this->stackTrace}]]>"]); } if ($this->getParameters()) { $this->addDetails([self::NODE_DETAIL_PARAMETERS => $this->getParameters()]); } if ($this->getWrappedErrors()) { $this->addDetails([self::NODE_DETAIL_WRAPPED_ERRORS => $this->getWrappedErrors()]); } return $this->getSoapFaultMessage($this->getMessage(), $this->getSoapCode(), $this->getDetails()); }
/** * Function to catch errors, that has not been caught by the user error dispatcher function. * * @return void */ public function apiShutdownFunction() { $fatalErrorFlag = E_ERROR | E_USER_ERROR | E_PARSE | E_CORE_ERROR | E_COMPILE_ERROR | E_RECOVERABLE_ERROR; $error = error_get_last(); if ($error && $error['type'] & $fatalErrorFlag) { $errorMessage = "Fatal Error: '{$error['message']}' in '{$error['file']}' on line {$error['line']}"; $reportId = $this->_saveFatalErrorReport($errorMessage); if ($this->_appState->getMode() == State::MODE_DEVELOPER) { $this->renderErrorMessage($errorMessage); } else { $this->renderErrorMessage(new Phrase('Server internal error. See details in report api/%1', [$reportId])); } } }