PageRenderTime 47ms CodeModel.GetById 19ms RepoModel.GetById 1ms app.codeStats 0ms

/src/xPDO/Transport/xPDOFileVehicle.php

https://github.com/modxcms/xpdo
PHP | 223 lines | 181 code | 8 blank | 34 comment | 28 complexity | f13816f91a1e267c17697f834d5ae00e MD5 | raw file
Possible License(s): GPL-2.0
  1. <?php
  2. /**
  3. * This file is part of the xPDO package.
  4. *
  5. * Copyright (c) Jason Coward <jason@opengeek.com>
  6. *
  7. * For the full copyright and license information, please view the LICENSE
  8. * file that was distributed with this source code.
  9. */
  10. namespace xPDO\Transport;
  11. use xPDO\xPDO;
  12. /**
  13. * Represents an individual file set within an {@link xPDOTransport} package.
  14. *
  15. * @package xpdo
  16. * @subpackage transport
  17. */
  18. class xPDOFileVehicle extends xPDOVehicle {
  19. public $class = 'xPDO\\Transport\\xPDOFileVehicle';
  20. /**
  21. * Install a file set represented by and stored in this vehicle.
  22. */
  23. public function install(& $transport, $options) {
  24. $installed = $this->_installFiles($transport, $options);
  25. return $installed;
  26. }
  27. /**
  28. * Uninstall a file set represented by and stored in this vehicle.
  29. */
  30. public function uninstall(& $transport, $options) {
  31. $uninstalled = $this->_uninstallFiles($transport, $options);
  32. return $uninstalled;
  33. }
  34. /**
  35. * Install files or folders represented by and stored in this vehicle.
  36. *
  37. * @access protected
  38. * @param xPDOTransport &$transport A reference the transport this vehicle is stored in.
  39. * @param array $options Optional attributes that can be applied to vehicle install process.
  40. * @return boolean True if the files are installed successfully.
  41. */
  42. protected function _installFiles(& $transport, $options) {
  43. $installed = false;
  44. $copied = false;
  45. $vOptions = $this->get($transport, $options);
  46. if (isset ($vOptions['object']) && isset ($vOptions['object']['source']) && isset ($vOptions['object']['target'])) {
  47. $object = $vOptions['object'];
  48. $fileName = $object['name'];
  49. $fileSource = $transport->path . $object['source'];
  50. $fileTarget = eval ($object['target']);
  51. $fileTargetPath = $fileTarget . $fileName;
  52. $preExistingMode = xPDOTransport::PRESERVE_PREEXISTING;
  53. if (isset ($vOptions[xPDOTransport::PREEXISTING_MODE])) {
  54. $preExistingMode = (integer) $vOptions[xPDOTransport::PREEXISTING_MODE];
  55. }
  56. $cacheManager = $transport->xpdo->getCacheManager();
  57. if ($this->validate($transport, $object, $vOptions)) {
  58. if (isset ($vOptions[xPDOTransport::INSTALL_FILES]) && !$vOptions[xPDOTransport::INSTALL_FILES]) {
  59. $transport->xpdo->log(xPDO::LOG_LEVEL_INFO, "Skipping installion of files from {$fileSource} to {$fileTargetPath}");
  60. $installed = true;
  61. } elseif ($cacheManager && file_exists($fileSource) && !empty ($fileTarget)) {
  62. $transport->xpdo->log(xPDO::LOG_LEVEL_INFO, "Installing files from {$fileSource} to {$fileTargetPath}");
  63. $copied = array();
  64. if ($preExistingMode === xPDOTransport::PRESERVE_PREEXISTING && file_exists($fileTargetPath)) {
  65. $preservedArchive = $transport->path . $transport->signature . '/' . str_replace('\\', '/', $this->payload['class']) . '/' . $this->payload['signature'] . '.preserved.zip';
  66. $transport->xpdo->log(xPDO::LOG_LEVEL_INFO, "Attempting to preserve files at {$fileTargetPath} into archive {$preservedArchive}");
  67. $preserved = xPDOTransport::_pack($transport->xpdo, $preservedArchive, $fileTarget, $fileName);
  68. }
  69. if (is_dir($fileSource)) {
  70. $copied = $cacheManager->copyTree($fileSource, $fileTarget, array_merge($vOptions, array('copy_return_file_stat' => true)));
  71. } elseif (is_file($fileSource)) {
  72. $copied = $cacheManager->copyFile($fileSource, $fileTarget, array_merge($vOptions, array('copy_return_file_stat' => true)));
  73. }
  74. if (empty($copied)) {
  75. $transport->xpdo->log(xPDO::LOG_LEVEL_ERROR, "Error copying files from {$fileSource} to {$fileTargetPath}");
  76. } else {
  77. if ($preExistingMode === xPDOTransport::PRESERVE_PREEXISTING && is_array($copied)) {
  78. foreach ($copied as $copiedFile => $stat) {
  79. if (isset($stat['overwritten'])) $transport->_preserved[$vOptions['guid']]['files'][$copiedFile]= $stat;
  80. }
  81. }
  82. $installed = true;
  83. }
  84. } else {
  85. $transport->xpdo->log(xPDO::LOG_LEVEL_ERROR, "Could not install files from {$fileSource} to {$fileTarget}");
  86. }
  87. if (!$this->resolve($transport, $object, $vOptions)) {
  88. $transport->xpdo->log(xPDO::LOG_LEVEL_ERROR, 'Could not resolve vehicle for object: ' . print_r($object, true));
  89. if ($transport->xpdo->getDebug() === true) $transport->xpdo->log(xPDO::LOG_LEVEL_DEBUG, 'Could not resolve vehicle: ' . print_r($vOptions, true));
  90. }
  91. } else {
  92. $transport->xpdo->log(xPDO::LOG_LEVEL_ERROR, 'Could not validate vehicle for object: ' . print_r($object, true));
  93. if ($transport->xpdo->getDebug() === true) $transport->xpdo->log(xPDO::LOG_LEVEL_DEBUG, 'Could not validate vehicle: ' . print_r($vOptions, true));
  94. }
  95. }
  96. return $installed;
  97. }
  98. /**
  99. * Uninstall files or folders represented by and stored in this vehicle.
  100. *
  101. * @access protected
  102. * @param xPDOTransport &$transport A reference the transport this vehicle is stored in.
  103. * @param array $options Optional attributes that can be applied to vehicle uninstall process.
  104. * @return boolean True if the files are uninstalled successfully.
  105. */
  106. protected function _uninstallFiles(& $transport, $options) {
  107. $uninstalled = false;
  108. $vOptions = $this->get($transport, $options);
  109. if (isset ($vOptions['object']) && isset ($vOptions['object']['source']) && isset ($vOptions['object']['target'])) {
  110. $object = $vOptions['object'];
  111. $fileName = $object['name'];
  112. $fileSource = $transport->path . $object['source'];
  113. $fileTarget = eval ($object['target']);
  114. $preExistingMode = xPDOTransport::PRESERVE_PREEXISTING;
  115. if (isset ($vOptions[xPDOTransport::PREEXISTING_MODE])) {
  116. $preExistingMode = (integer) $vOptions[xPDOTransport::PREEXISTING_MODE];
  117. }
  118. $cacheManager = $transport->xpdo->getCacheManager();
  119. $path = $fileTarget . $fileName;
  120. $transport->xpdo->log(xPDO::LOG_LEVEL_INFO, 'Uninstalling files from xPDOFileVehicle: ' . $path);
  121. if ($this->validate($transport, $object, $vOptions)) {
  122. if (!isset ($vOptions[xPDOTransport::UNINSTALL_FILES]) || $vOptions[xPDOTransport::UNINSTALL_FILES] == true) {
  123. $transport->xpdo->log(xPDO::LOG_LEVEL_INFO,'Removing files from xPDOFileVehicle: '.$path);
  124. if ($cacheManager && file_exists($path)) {
  125. if (is_dir($path) && $cacheManager->deleteTree($path, array_merge(array('deleteTop' => true, 'skipDirs' => false, 'extensions' => array()), $vOptions))) {
  126. $uninstalled = true;
  127. } elseif (is_file($path) && unlink($path)) {
  128. $uninstalled = true;
  129. } else {
  130. $transport->xpdo->log(xPDO::LOG_LEVEL_ERROR,'Could not remove files from path: '.$path);
  131. }
  132. } else {
  133. $transport->xpdo->log(xPDO::LOG_LEVEL_ERROR,'Could not find files to remove at path: '.$path);
  134. }
  135. } else {
  136. $transport->xpdo->log(xPDO::LOG_LEVEL_INFO,'Skipping removal of files according to vehicle attributes.');
  137. $uninstalled = true;
  138. }
  139. $preservedArchive = $transport->path . $transport->signature . '/' . str_replace('\\', '/', $this->payload['class']) . '/' . $this->payload['signature'] . '.preserved.zip';
  140. if ($preExistingMode === xPDOTransport::RESTORE_PREEXISTING && file_exists($preservedArchive)) {
  141. $transport->xpdo->log(xPDO::LOG_LEVEL_ERROR, "Attempting to restore files to {$fileTarget} from archive {$preservedArchive}");
  142. $unpackedResult = xPDOTransport::_unpack($transport->xpdo, $preservedArchive, $fileTarget);
  143. if ($unpackedResult > 0) {
  144. $uninstalled = true;
  145. } else {
  146. $transport->xpdo->log(xPDO::LOG_LEVEL_ERROR, "Error unpacking preserved files from archive {$preservedArchive}");
  147. }
  148. }
  149. if (!$this->resolve($transport, $object, $vOptions)) {
  150. $transport->xpdo->log(xPDO::LOG_LEVEL_ERROR, 'Could not resolve vehicle for object: ' . print_r($object, true));
  151. if ($transport->xpdo->getDebug() === true) $transport->xpdo->log(xPDO::LOG_LEVEL_DEBUG, 'Could not resolve vehicle: ' . print_r($vOptions, true));
  152. }
  153. } else {
  154. $transport->xpdo->log(xPDO::LOG_LEVEL_ERROR, 'Could not validate vehicle for object: ' . print_r($object, true));
  155. if ($transport->xpdo->getDebug() === true) $transport->xpdo->log(xPDO::LOG_LEVEL_DEBUG, 'Could not validate vehicle: ' . print_r($vOptions, true));
  156. }
  157. }
  158. return $uninstalled;
  159. }
  160. /**
  161. * Adds the file definition object to the payload.
  162. */
  163. public function put(& $transport, & $object, $attributes = array ()) {
  164. if (!isset ($this->payload['class'])) {
  165. $this->payload['class'] = $this->class;
  166. }
  167. if (is_array($object) && isset ($object['source']) && isset ($object['target'])) {
  168. if (!isset($object['name'])) $object['name'] = basename($object['source']);
  169. $this->payload['object'] = $object;
  170. }
  171. parent :: put($transport, $object, $attributes);
  172. }
  173. /**
  174. * Copies the files into the vehicle and transforms the payload for storage.
  175. */
  176. protected function _compilePayload(& $transport) {
  177. parent :: _compilePayload($transport);
  178. $body = array ();
  179. $cacheManager = $transport->xpdo->getCacheManager();
  180. if ($cacheManager) {
  181. if (isset($this->payload['object'])) {
  182. $object = $this->payload['object'];
  183. $fileSource = $object['source'];
  184. $body['source'] = $transport->signature . '/' . str_replace('\\', '/', $this->payload['class']) . '/' . $this->payload['signature'] . '/';
  185. $fileTarget = $transport->path . $body['source'];
  186. $body['target'] = $object['target'];
  187. $fileName = isset ($object['name']) ? $object['name'] : basename($fileSource);
  188. $body['name'] = $fileName;
  189. if (!is_writable($fileTarget)) {
  190. $cacheManager->writeTree($fileTarget);
  191. }
  192. if (file_exists($fileSource) && is_writable($fileTarget)) {
  193. $copied = false;
  194. if (is_dir($fileSource)) {
  195. $copied = $cacheManager->copyTree($fileSource, $fileTarget . $fileName);
  196. }
  197. elseif (is_file($fileSource)) {
  198. $copied = $cacheManager->copyFile($fileSource, $fileTarget . $fileName);
  199. }
  200. if (!$copied) {
  201. $transport->xpdo->log(xPDO::LOG_LEVEL_ERROR, "Could not copy file from {$fileSource} to {$fileTarget}{$fileName}");
  202. $body = null;
  203. }
  204. } else {
  205. $transport->xpdo->log(xPDO::LOG_LEVEL_ERROR, "Source file {$fileSource} is missing or {$fileTarget} is not writable");
  206. $body = null;
  207. }
  208. }
  209. }
  210. if (!empty($body)) {
  211. $this->payload['object'] = $body;
  212. }
  213. }
  214. }