Magento 2 Documentation  2.3
Documentation for Magento 2 CMS v2.3 (December 2018)
processor.php
Go to the documentation of this file.
1 <?php
7 
9 
15 class Processor
16 {
17  const MAGE_ERRORS_LOCAL_XML = 'local.xml';
18  const MAGE_ERRORS_DESIGN_XML = 'design.xml';
19  const DEFAULT_SKIN = 'default';
20  const ERROR_DIR = 'pub/errors';
21 
27  public $pageTitle;
28 
34  public $skinUrl;
35 
41  public $baseUrl;
42 
48  public $postData;
49 
55  public $reportData;
56 
62  public $reportAction;
63 
69  public $reportId;
70 
76  protected $_reportFile;
77 
83  public $showErrorMsg;
84 
90  public $showSentMsg;
91 
97  public $showSendForm;
98 
102  public $reportUrl;
103 
109  protected $_scriptName;
110 
116  protected $_root;
117 
123  protected $_config;
124 
130  protected $_response;
131 
137  private $serializer;
138 
143  public function __construct(\Magento\Framework\App\Response\Http $response, Json $serializer = null)
144  {
145  $this->_response = $response;
146  $this->_errorDir = __DIR__ . '/';
147  $this->_reportDir = dirname(dirname($this->_errorDir)) . '/var/report/';
148  $this->serializer = $serializer ?: \Magento\Framework\App\ObjectManager::getInstance()->get(Json::class);
149 
150  if (!empty($_SERVER['SCRIPT_NAME'])) {
151  if (in_array(basename($_SERVER['SCRIPT_NAME'], '.php'), ['404', '503', 'report'])) {
152  $this->_scriptName = dirname($_SERVER['SCRIPT_NAME']);
153  } else {
154  $this->_scriptName = $_SERVER['SCRIPT_NAME'];
155  }
156  }
157 
158  $reportId = (isset($_GET['id'])) ? (int)$_GET['id'] : null;
159  if ($reportId) {
160  $this->loadReport($reportId);
161  }
162 
163  $this->_indexDir = $this->_getIndexDir();
164  $this->_root = is_dir($this->_indexDir . 'app');
165 
166  $this->_prepareConfig();
167  if (isset($_GET['skin'])) {
168  $this->_setSkin($_GET['skin']);
169  }
170  }
171 
177  public function processNoCache()
178  {
179  $this->pageTitle = 'Error : cached config data is unavailable';
180  $this->_response->setBody($this->_renderPage('nocache.phtml'));
181  return $this->_response;
182  }
183 
189  public function process404()
190  {
191  $this->pageTitle = 'Error 404: Not Found';
192  $this->_response->setHttpResponseCode(404);
193  $this->_response->setBody($this->_renderPage('404.phtml'));
194  return $this->_response;
195  }
196 
202  public function process503()
203  {
204  $this->pageTitle = 'Error 503: Service Unavailable';
205  $this->_response->setHttpResponseCode(503);
206  $this->_response->setBody($this->_renderPage('503.phtml'));
207  return $this->_response;
208  }
209 
215  public function processReport()
216  {
217  $this->pageTitle = 'There has been an error processing your request';
218  $this->_response->setHttpResponseCode(500);
219 
220  $this->showErrorMsg = false;
221  $this->showSentMsg = false;
222  $this->showSendForm = false;
223  $this->reportAction = $this->_config->action;
224  $this->_setReportUrl();
225 
226  if ($this->reportAction == 'email') {
227  $this->showSendForm = true;
228  $this->sendReport();
229  }
230  $this->_response->setBody($this->_renderPage('report.phtml'));
231  return $this->_response;
232  }
233 
239  public function getViewFileUrl()
240  {
241  //The url needs to be updated base on Document root path.
242  return $this->getBaseUrl() .
243  str_replace(
244  str_replace('\\', '/', $this->_indexDir),
245  '',
246  str_replace('\\', '/', $this->_errorDir)
247  ) . $this->_config->skin . '/';
248  }
249 
255  public function getHostUrl()
256  {
260  if (!empty($_SERVER['HTTP_HOST'])) {
261  $host = $_SERVER['HTTP_HOST'];
262  } elseif (!empty($_SERVER['SERVER_NAME'])) {
263  $host = $_SERVER['SERVER_NAME'];
264  } else {
265  $host = 'localhost';
266  }
267 
268  $isSecure = (!empty($_SERVER['HTTPS'])) && ($_SERVER['HTTPS'] != 'off');
269  $url = ($isSecure ? 'https://' : 'http://') . $host;
270 
271  if (!empty($_SERVER['SERVER_PORT']) && !in_array($_SERVER['SERVER_PORT'], [80, 443])
272  && !preg_match('/.*?\:[0-9]+$/', $url)
273  ) {
274  $url .= ':' . $_SERVER['SERVER_PORT'];
275  }
276  return $url;
277  }
278 
285  public function getBaseUrl($param = false)
286  {
288 
289  if ($param && !$this->_root) {
290  $path = dirname($path);
291  }
292 
293  $basePath = str_replace('\\', '/', dirname($path));
294  return $this->getHostUrl() . ('/' == $basePath ? '' : $basePath) . '/';
295  }
296 
302  protected function _getClientIp()
303  {
304  return (isset($_SERVER['REMOTE_ADDR'])) ? $_SERVER['REMOTE_ADDR'] : 'undefined';
305  }
306 
312  protected function _getIndexDir()
313  {
314  $documentRoot = '';
315  if (!empty($_SERVER['DOCUMENT_ROOT'])) {
316  $documentRoot = rtrim(realpath($_SERVER['DOCUMENT_ROOT']), '/');
317  }
318  return dirname($documentRoot . $this->_scriptName) . '/';
319  }
320 
328  protected function _prepareConfig()
329  {
330  $local = $this->_loadXml(self::MAGE_ERRORS_LOCAL_XML);
331  $design = $this->_loadXml(self::MAGE_ERRORS_DESIGN_XML);
332 
333  //initial settings
334  $config = new \stdClass();
335  $config->action = '';
336  $config->subject = 'Store Debug Information';
337  $config->email_address = '';
338  $config->trash = 'leave';
339  $config->skin = self::DEFAULT_SKIN;
340 
341  //combine xml data to one object
342  if ($design !== null && (string)$design->skin) {
343  $this->_setSkin((string)$design->skin, $config);
344  }
345  if ($local !== null) {
346  if ((string)$local->report->action) {
347  $config->action = $local->report->action;
348  }
349  if ((string)$local->report->subject) {
350  $config->subject = $local->report->subject;
351  }
352  if ((string)$local->report->email_address) {
353  $config->email_address = $local->report->email_address;
354  }
355  if ((string)$local->report->trash) {
356  $config->trash = $local->report->trash;
357  }
358  if ((string)$local->skin) {
359  $this->_setSkin((string)$local->skin, $config);
360  }
361  }
362  if ((string)$config->email_address == '' && (string)$config->action == 'email') {
363  $config->action = '';
364  }
365 
366  $this->_config = $config;
367  }
368 
375  protected function _loadXml($xmlFile)
376  {
377  $configPath = $this->_getFilePath($xmlFile);
378  return ($configPath) ? simplexml_load_file($configPath) : null;
379  }
380 
385  protected function _renderPage($template)
386  {
387  $baseTemplate = $this->_getTemplatePath('page.phtml');
388  $contentTemplate = $this->_getTemplatePath($template);
389 
390  $html = '';
391  if ($baseTemplate && $contentTemplate) {
392  ob_start();
393  require_once $baseTemplate;
394  $html = ob_get_clean();
395  }
396  return $html;
397  }
398 
406  protected function _getFilePath($file, $directories = null)
407  {
408  if ($directories === null) {
409  $directories[] = $this->_errorDir;
410  }
411 
412  foreach ($directories as $directory) {
413  if (file_exists($directory . $file)) {
414  return $directory . $file;
415  }
416  }
417  }
418 
425  protected function _getTemplatePath($template)
426  {
427  $directories[] = $this->_errorDir . $this->_config->skin . '/';
428 
429  if ($this->_config->skin != self::DEFAULT_SKIN) {
430  $directories[] = $this->_errorDir . self::DEFAULT_SKIN . '/';
431  }
432 
433  return $this->_getFilePath($template, $directories);
434  }
435 
442  protected function _setReportData($reportData)
443  {
444  $this->reportData = $reportData;
445 
446  if (!isset($reportData['url'])) {
447  $this->reportData['url'] = '';
448  } else {
449  $this->reportData['url'] = $this->getHostUrl() . $reportData['url'];
450  }
451 
452  if ($this->reportData['script_name']) {
453  $this->_scriptName = $this->reportData['script_name'];
454  }
455  }
456 
463  public function saveReport($reportData)
464  {
465  $this->reportData = $reportData;
466  $this->reportId = abs(intval(microtime(true) * random_int(100, 1000)));
467  $this->_reportFile = $this->_reportDir . '/' . $this->reportId;
468  $this->_setReportData($reportData);
469 
470  if (!file_exists($this->_reportDir)) {
471  @mkdir($this->_reportDir, 0777, true);
472  }
473 
474  @file_put_contents($this->_reportFile, $this->serializer->serialize($reportData));
475 
476  if (isset($reportData['skin']) && self::DEFAULT_SKIN != $reportData['skin']) {
477  $this->_setSkin($reportData['skin']);
478  }
479  $this->_setReportUrl();
480 
481  return $this->reportUrl;
482  }
483 
491  public function loadReport($reportId)
492  {
493  $this->reportId = $reportId;
494  $this->_reportFile = $this->_reportDir . '/' . $reportId;
495 
496  if (!file_exists($this->_reportFile) || !is_readable($this->_reportFile)) {
497  header("Location: " . $this->getBaseUrl());
498  die();
499  }
500  $this->_setReportData($this->serializer->unserialize(file_get_contents($this->_reportFile)));
501  }
502 
510  public function sendReport()
511  {
512  $this->pageTitle = 'Error Submission Form';
513 
514  $this->postData['firstName'] = (isset($_POST['firstname'])) ? trim(htmlspecialchars($_POST['firstname'])) : '';
515  $this->postData['lastName'] = (isset($_POST['lastname'])) ? trim(htmlspecialchars($_POST['lastname'])) : '';
516  $this->postData['email'] = (isset($_POST['email'])) ? trim(htmlspecialchars($_POST['email'])) : '';
517  $this->postData['telephone'] = (isset($_POST['telephone'])) ? trim(htmlspecialchars($_POST['telephone'])) : '';
518  $this->postData['comment'] = (isset($_POST['comment'])) ? trim(htmlspecialchars($_POST['comment'])) : '';
519 
520  if (isset($_POST['submit'])) {
521  if ($this->_validate()) {
522  $msg = "URL: {$this->reportData['url']}\n"
523  . "IP Address: {$this->_getClientIp()}\n"
524  . "First Name: {$this->postData['firstName']}\n"
525  . "Last Name: {$this->postData['lastName']}\n"
526  . "Email Address: {$this->postData['email']}\n";
527  if ($this->postData['telephone']) {
528  $msg .= "Telephone: {$this->postData['telephone']}\n";
529  }
530  if ($this->postData['comment']) {
531  $msg .= "Comment: {$this->postData['comment']}\n";
532  }
533 
534  $subject = sprintf('%s [%s]', (string)$this->_config->subject, $this->reportId);
535  @mail((string)$this->_config->email_address, $subject, $msg);
536 
537  $this->showSendForm = false;
538  $this->showSentMsg = true;
539  } else {
540  $this->showErrorMsg = true;
541  }
542  } else {
543  $time = gmdate('Y-m-d H:i:s \G\M\T');
544 
545  $msg = "URL: {$this->reportData['url']}\n"
546  . "IP Address: {$this->_getClientIp()}\n"
547  . "Time: {$time}\n"
548  . "Error:\n{$this->reportData[0]}\n\n"
549  . "Trace:\n{$this->reportData[1]}";
550 
551  $subject = sprintf('%s [%s]', (string)$this->_config->subject, $this->reportId);
552  @mail((string)$this->_config->email_address, $subject, $msg);
553 
554  if ($this->_config->trash == 'delete') {
555  @unlink($this->_reportFile);
556  }
557  }
558  }
559 
565  protected function _validate()
566  {
567  $email = preg_match(
568  '/^[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,3})$/',
569  $this->postData['email']
570  );
571  return ($this->postData['firstName'] && $this->postData['lastName'] && $email);
572  }
573 
581  protected function _setSkin($value, \stdClass $config = null)
582  {
583  if (preg_match('/^[a-z0-9_]+$/i', $value) && is_dir($this->_errorDir . $value)) {
584  if (!$config) {
585  if ($this->_config) {
587  }
588  }
589  if ($config) {
590  $config->skin = $value;
591  }
592  }
593  }
594 
600  protected function _setReportUrl()
601  {
602  if ($this->reportId && $this->_config && isset($this->_config->skin)) {
603  $this->reportUrl = "{$this->getBaseUrl(true)}pub/errors/report.php?"
604  . http_build_query(['id' => $this->reportId, 'skin' => $this->_config->skin]);
605  }
606  }
607 }
$response
Definition: 404.php:11
_setSkin($value, \stdClass $config=null)
Definition: processor.php:581
elseif(isset( $params[ 'redirect_parent']))
Definition: iframe.phtml:17
$email
Definition: details.phtml:13
$config
Definition: fraud_order.php:17
defined('TESTS_BP')||define('TESTS_BP' __DIR__
Definition: _bootstrap.php:60
__construct(\Magento\Framework\App\Response\Http $response, Json $serializer=null)
Definition: processor.php:143
$value
Definition: gender.phtml:16
mkdir($pathname, $mode=0777, $recursive=false, $context=null)
Definition: ioMock.php:25
_getFilePath($file, $directories=null)
Definition: processor.php:406
$template
Definition: export.php:12