/update/app/code/Magento/Update/CronReadinessCheck.php

https://gitlab.com/yousafsyed/easternglamor · PHP · 150 lines · 101 code · 15 blank · 34 comment · 13 complexity · b4fb90504de970cfe241a8507c072bb1 MD5 · raw file

  1. <?php
  2. /**
  3. * Copyright © 2016 Magento. All rights reserved.
  4. * See COPYING.txt for license details.
  5. */
  6. namespace Magento\Update;
  7. /**
  8. * This class is used by Updater cron script to check if it can be run properly
  9. */
  10. class CronReadinessCheck
  11. {
  12. /**
  13. * Basename to Updater status file
  14. */
  15. const CRON_JOB_STATUS_FILE = '.update_cronjob_status';
  16. const UPDATE_CRON_LOG_FILE = 'var/log/update.log';
  17. /**#@+
  18. * Keys used in status file
  19. */
  20. const KEY_READINESS_CHECKS = 'readiness_checks';
  21. const KEY_FILE_PERMISSIONS_VERIFIED = 'file_permissions_verified';
  22. const KEY_ERROR = 'error';
  23. const KEY_CURRENT_TIMESTAMP = 'current_timestamp';
  24. const KEY_LAST_TIMESTAMP = 'last_timestamp';
  25. /**#@-*/
  26. /**
  27. * Setup cron job status file name
  28. */
  29. const SETUP_CRON_JOB_STATUS_FILE = '.setup_cronjob_status';
  30. /**#@+
  31. * Keys from .setup_cronjob_status file
  32. */
  33. const KEY_FILE_PATHS = 'file_paths';
  34. const KEY_LIST = 'list';
  35. /**#@-*/
  36. /**
  37. * Run Cron job readiness check
  38. *
  39. * @return bool
  40. */
  41. public function runReadinessCheck()
  42. {
  43. $resultJsonRawData = ['readiness_checks' => []];
  44. $success = true;
  45. $permissionInfo = $this->checkPermissionsRecursively();
  46. if ($permissionInfo->containsPaths())
  47. {
  48. $error = '';
  49. if (!empty($permissionInfo->getNonWritablePaths())) {
  50. $error .= '<br/>Found non-writable path(s):<br/>' .
  51. implode('<br/>', $permissionInfo->getNonWritablePaths());
  52. }
  53. if (!empty($permissionInfo->getNonReadablePaths())) {
  54. $error .= '<br/>Found non-readable path(s):<br/>' .
  55. implode('<br/>', $permissionInfo->getNonReadablePaths());
  56. }
  57. $resultJsonRawData[self::KEY_READINESS_CHECKS][self::KEY_ERROR] = $error;
  58. $resultJsonRawData[self::KEY_READINESS_CHECKS][self::KEY_FILE_PERMISSIONS_VERIFIED] = false;
  59. $success = false;
  60. } else {
  61. $resultJsonRawData[self::KEY_READINESS_CHECKS][self::KEY_FILE_PERMISSIONS_VERIFIED] = true;
  62. }
  63. if (file_exists(MAGENTO_BP . '/var/' . self::CRON_JOB_STATUS_FILE)) {
  64. $jsonData = json_decode(file_get_contents(MAGENTO_BP . '/var/' . self::CRON_JOB_STATUS_FILE), true);
  65. if (isset($jsonData[self::KEY_CURRENT_TIMESTAMP])) {
  66. $resultJsonRawData[self::KEY_LAST_TIMESTAMP] = $jsonData[self::KEY_CURRENT_TIMESTAMP];
  67. }
  68. }
  69. $resultJsonRawData[self::KEY_CURRENT_TIMESTAMP] = time();
  70. $resultJson = json_encode($resultJsonRawData, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES);
  71. file_put_contents(MAGENTO_BP . '/var/' . self::CRON_JOB_STATUS_FILE, $resultJson);
  72. // If non-accessible paths are found, log an 'error' entry for the same in update.log
  73. if ( !$success ) {
  74. $outputString = 'Cron readiness check failure! Found following non-writable paths' . PHP_EOL;
  75. $outputString .= "\t" . implode(PHP_EOL . "\t", $nonWritablePaths);
  76. $updateLoggerFactory = new UpdateLoggerFactory();
  77. $logger = $updateLoggerFactory->create();
  78. $logger->log(\Psr\Log\LogLevel::ERROR, $outputString);
  79. }
  80. return $success;
  81. }
  82. /**
  83. * Check file permissions recursively
  84. *
  85. * @return PermissionInfo
  86. */
  87. private function checkPermissionsRecursively()
  88. {
  89. // For backward compatibility, initialize the list wth magento root directory.
  90. $dirAndFileList[] = '';
  91. // Get the list of magento specific directories and files
  92. $setupCronJobStatusFilePath = MAGENTO_BP . '/var/' . self::SETUP_CRON_JOB_STATUS_FILE;
  93. if (is_readable($setupCronJobStatusFilePath)) {
  94. $fileContents = json_decode(file_get_contents($setupCronJobStatusFilePath), true);
  95. if (isset($fileContents[self::KEY_FILE_PATHS][self::KEY_LIST])) {
  96. $dirAndFileList = $fileContents[self::KEY_FILE_PATHS][self::KEY_LIST];
  97. }
  98. }
  99. $nonWritablePaths = [];
  100. $nonReadablePaths = [];
  101. foreach ($dirAndFileList as $path) {
  102. $path = MAGENTO_BP . '/' . $path;
  103. if (is_dir($path)) {
  104. try {
  105. $filesystemIterator = new \RecursiveIteratorIterator(
  106. new \RecursiveDirectoryIterator($path),
  107. \RecursiveIteratorIterator::SELF_FIRST
  108. );
  109. $filesystemIterator = new ExcludeFilter(
  110. $filesystemIterator,
  111. [
  112. MAGENTO_BP . '/update',
  113. MAGENTO_BP . '/var/session',
  114. '.git',
  115. '.idea'
  116. ]
  117. );
  118. foreach ($filesystemIterator as $item) {
  119. $path = $item->__toString();
  120. if (!is_writable($path)) {
  121. $nonWritablePaths[] = $path;
  122. }
  123. }
  124. } catch (\UnexpectedValueException $e) {
  125. $nonReadablePaths[] = $path;
  126. }
  127. } else {
  128. if (!is_writable($path)) {
  129. $nonWritablePaths[] = $path;
  130. }
  131. }
  132. }
  133. return new PermissionInfo($nonWritablePaths, $nonReadablePaths);
  134. }
  135. }