/core/src/Revolution/Processors/Workspace/Packages/Purge.php

https://github.com/opengeek/revolution · PHP · 228 lines · 137 code · 25 blank · 66 comment · 17 complexity · bdbe6a480af07ed4abf20bed244e2fa8 MD5 · raw file

  1. <?php
  2. /*
  3. * This file is part of MODX Revolution.
  4. *
  5. * Copyright (c) MODX, LLC. All Rights Reserved.
  6. *
  7. * For complete copyright and license information, see the COPYRIGHT and LICENSE
  8. * files found in the top-level directory of this distribution.
  9. */
  10. namespace MODX\Revolution\Processors\Workspace\Packages;
  11. use MODX\Revolution\Processors\Processor;
  12. use MODX\Revolution\modX;
  13. use MODX\Revolution\Transport\modTransportPackage;
  14. use xPDO\xPDO;
  15. /**
  16. * Purge old package versions
  17. * @param string $package_name The name of the package, could be set to * to purge all old packages
  18. * @package MODX\Revolution\Processors\Workspace\Packages
  19. */
  20. class Purge extends Processor
  21. {
  22. /** @var modTransportPackage[] $package */
  23. public $packages;
  24. public $packageName;
  25. /**
  26. * @return bool
  27. */
  28. public function checkPermissions()
  29. {
  30. return $this->modx->hasPermission('packages');
  31. }
  32. /**
  33. * @return array
  34. */
  35. public function getLanguageTopics()
  36. {
  37. return ['workspace'];
  38. }
  39. /**
  40. * @return array|bool|string
  41. */
  42. public function initialize()
  43. {
  44. $this->setDefaultProperties(['package' => '']);
  45. $this->packageName = $this->getProperty('packagename');
  46. if (empty($this->packageName)) {
  47. $this->modx->log(xPDO::LOG_LEVEL_ERROR, $this->modx->lexicon('packagename_err_ns'));
  48. return $this->failure(xPDO::LOG_LEVEL_ERROR, $this->modx->lexicon('packagename_err_ns'));
  49. }
  50. $c = $this->modx->newQuery(modTransportPackage::class);
  51. $c->select('package_name');
  52. $c->groupby('package_name');
  53. if ($this->packageName !== '*') {
  54. $c->where([
  55. 'package_name' => $this->packageName,
  56. ]);
  57. }
  58. $this->packages = $this->modx->getIterator(modTransportPackage::class, $c);
  59. if (empty($this->packages)) {
  60. $this->modx->log(xPDO::LOG_LEVEL_ERROR, $this->modx->lexicon('packagename_err_nf'));
  61. return $this->failure(xPDO::LOG_LEVEL_ERROR, $this->modx->lexicon('packagename_err_nf'));
  62. }
  63. return true;
  64. }
  65. /**
  66. * Return a failure message from the processor.
  67. * @param string $msg
  68. * @param mixed $object
  69. * @return array|string
  70. */
  71. public function failure($msg = '', $object = null)
  72. {
  73. $this->modx->log(modX::LOG_LEVEL_INFO, 'COMPLETED');
  74. sleep(2);
  75. return $this->modx->error->failure($msg, $object);
  76. }
  77. /**
  78. * @return array
  79. */
  80. public function process()
  81. {
  82. foreach ($this->packages as $package) {
  83. $c = $this->modx->newQuery(modTransportPackage::class, [
  84. 'package_name' => $package->get('package_name'),
  85. ]);
  86. $c->where(['installed:!=' => '0000-00-00 00:00:00']);
  87. $c->sortby('installed', 'desc');
  88. $c->limit(1000, 1);
  89. $purgedPackages = $this->modx->getIterator(modTransportPackage::class, $c);
  90. foreach ($purgedPackages as $purgedPackage) {
  91. $this->removePackage($purgedPackage);
  92. }
  93. }
  94. $this->clearCache();
  95. return $this->cleanup();
  96. }
  97. /**
  98. * Remove the package
  99. * @param modTransportPackage $package
  100. * @return void
  101. */
  102. public function removePackage($package)
  103. {
  104. $this->modx->log(xPDO::LOG_LEVEL_INFO,
  105. $this->modx->lexicon('packages_purge_info_gpurge', ['signature' => $package->signature]));
  106. $transportZip = $this->modx->getOption('core_path') . 'packages/' . $package->signature . '.transport.zip';
  107. $transportDir = $this->modx->getOption('core_path') . 'packages/' . $package->signature . '/';
  108. if (file_exists($transportZip) && file_exists($transportDir)) {
  109. /* remove transport package */
  110. if ($package->remove() === false) {
  111. $this->modx->log(xPDO::LOG_LEVEL_ERROR,
  112. $this->modx->lexicon('package_err_remove', ['signature' => $package->getPrimaryKey()]));
  113. $this->failure($this->modx->lexicon('package_err_remove', ['signature' => $package->getPrimaryKey()]));
  114. return;
  115. }
  116. } else {
  117. /* for some reason the files were removed, so just remove the DB object instead */
  118. $package->remove();
  119. }
  120. $this->removeTransportZip($transportZip);
  121. $this->removeTransportDirectory($transportDir);
  122. $this->modx->invokeEvent('OnPackageRemove', [
  123. 'package' => $package,
  124. ]);
  125. }
  126. /**
  127. * Remove the transport package archive
  128. * @param string $transportZip
  129. * @return void
  130. */
  131. public function removeTransportZip($transportZip)
  132. {
  133. $this->modx->log(xPDO::LOG_LEVEL_INFO, $this->modx->lexicon('package_remove_info_tzip_start'));
  134. if (!file_exists($transportZip)) {
  135. $this->modx->log(xPDO::LOG_LEVEL_ERROR, $this->modx->lexicon('package_remove_err_tzip_nf'));
  136. } else if (!@unlink($transportZip)) {
  137. $this->modx->log(xPDO::LOG_LEVEL_ERROR, $this->modx->lexicon('package_remove_err_tzip'));
  138. } else {
  139. $this->modx->log(xPDO::LOG_LEVEL_INFO, $this->modx->lexicon('package_remove_info_tzip'));
  140. }
  141. }
  142. /**
  143. * Remove the transport package directory
  144. * @param string $transportDir
  145. * @return void
  146. */
  147. public function removeTransportDirectory($transportDir)
  148. {
  149. $this->modx->log(xPDO::LOG_LEVEL_INFO, $this->modx->lexicon('package_remove_info_tdir_start'));
  150. if (!file_exists($transportDir)) {
  151. $this->modx->log(xPDO::LOG_LEVEL_ERROR, $this->modx->lexicon('package_remove_err_tdir_nf'));
  152. } else if (!$this->modx->cacheManager->deleteTree($transportDir, true, false, [])) {
  153. $this->modx->log(xPDO::LOG_LEVEL_ERROR, $this->modx->lexicon('package_remove_err_tdir'));
  154. } else {
  155. $this->modx->log(xPDO::LOG_LEVEL_INFO, $this->modx->lexicon('package_remove_info_tdir'));
  156. }
  157. }
  158. /**
  159. * Empty the site cache
  160. * @return void
  161. */
  162. public function clearCache()
  163. {
  164. $this->modx->getCacheManager();
  165. $this->modx->cacheManager->refresh([
  166. $this->modx->getOption('cache_packages_key', null, 'packages') => [],
  167. ]);
  168. $this->modx->cacheManager->refresh();
  169. }
  170. /**
  171. * Cleanup and return the result
  172. * @return array
  173. */
  174. public function cleanup()
  175. {
  176. if ($this->packageName === '*') {
  177. $this->modx->log(modX::LOG_LEVEL_WARN, $this->modx->lexicon('packages_purge_info_success'));
  178. } else {
  179. $this->modx->log(modX::LOG_LEVEL_WARN, $this->modx->lexicon('package_versions_purge_info_success'));
  180. }
  181. sleep(2);
  182. return $this->success();
  183. }
  184. /**
  185. * Return a success message from the processor.
  186. * @param string $msg
  187. * @param mixed $object
  188. * @return array|string
  189. */
  190. public function success($msg = '', $object = null)
  191. {
  192. $this->modx->log(modX::LOG_LEVEL_INFO, 'COMPLETED');
  193. sleep(2);
  194. return $this->modx->error->success($msg, $object);
  195. }
  196. /**
  197. * Log manager action
  198. */
  199. public function logManagerAction()
  200. {
  201. $this->modx->logManagerAction('packages_purge', modTransportPackage::class, $this->packageName);
  202. }
  203. }