modpackagebuilder.class.php 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329
  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. /**
  11. * Abstracts the package building process
  12. *
  13. * @package modx
  14. * @subpackage transport
  15. */
  16. class modPackageBuilder {
  17. /**
  18. * @var string The directory in which the package file is located.
  19. * @access public
  20. */
  21. public $directory;
  22. /**
  23. * @var string The unique signature for the package.
  24. * @access public
  25. */
  26. public $signature;
  27. /**
  28. * @var string The filename of the actual package.
  29. * @access public
  30. */
  31. public $filename;
  32. /**
  33. * @var xPDOTransport The xPDOTransport package object.
  34. * @access public
  35. */
  36. public $package;
  37. /**
  38. * @var modNamespace The modNamespace that the package is associated with.
  39. * @access public
  40. */
  41. public $namespace;
  42. /**
  43. * @var array An array of classnames to automatically select by namespace
  44. * @access public
  45. */
  46. public $autoselects;
  47. /**
  48. * Creates an instance of the modPackageBuilder class.
  49. *
  50. * @param modX &$modx A reference to a modX instance.
  51. * @return modPackageBuilder
  52. */
  53. function __construct(modX &$modx) {
  54. $this->modx = & $modx;
  55. $this->modx->loadClass('transport.modTransportVehicle', '', false, true);
  56. $this->modx->loadClass('transport.xPDOTransport', XPDO_CORE_PATH, true, true);
  57. if (!$workspace = $this->modx->getObject('modWorkspace', array (
  58. 'active' => 1
  59. ))) {
  60. $this->modx->log(modX::LOG_LEVEL_FATAL,$this->modx->lexicon('core_err_invalid'));
  61. exit ();
  62. }
  63. $this->directory = $workspace->get('path') . 'packages/';
  64. $this->modx->lexicon->load('workspace');
  65. $this->autoselects = array ();
  66. }
  67. /**
  68. * Allows for customization of the package workspace.
  69. *
  70. * @access public
  71. * @param integer $workspace_id The ID of the workspace to select.
  72. * @return modWorkspace The workspace set, false if invalid.
  73. */
  74. public function setWorkspace($workspace_id) {
  75. if (!is_numeric($workspace_id)) {
  76. return false;
  77. }
  78. $workspace = $this->modx->getObject('modWorkspace', $workspace_id);
  79. if ($workspace == null) {
  80. return false;
  81. }
  82. $this->directory = $workspace->get('path') . 'packages/';
  83. return $workspace;
  84. }
  85. /**
  86. * @deprecated To be removed in 2.2
  87. * @param string $name
  88. * @param string $version
  89. * @param string $release
  90. * @see modPackageBuilder::createPackage
  91. */
  92. public function create($name, $version, $release = '') {
  93. $this->modx->deprecated('2.1.2', 'Use modPackageBuilder::createPackage instead.');
  94. $this->createPackage($name, $version, $release);
  95. }
  96. /**
  97. * Creates a new xPDOTransport package.
  98. *
  99. * @access public
  100. * @param string $name The name of the component the package represents.
  101. * @param string $version A string representing the version of the package.
  102. * @param string $release A string describing the specific release of this version of the
  103. * package.
  104. * @return xPDOTransport The xPDOTransport package object.
  105. */
  106. public function createPackage($name, $version, $release = '') {
  107. /* setup the signature and filename */
  108. $s['name'] = strtolower($name);
  109. $s['version'] = $version;
  110. $s['release'] = $release;
  111. $this->signature = $s['name'];
  112. if (!empty ($s['version'])) {
  113. $this->signature .= '-' . $s['version'];
  114. }
  115. if (!empty ($s['release'])) {
  116. $this->signature .= '-' . $s['release'];
  117. }
  118. $this->filename = $this->signature . '.transport.zip';
  119. /* remove the package if it's already been made */
  120. if (file_exists($this->directory . $this->filename)) {
  121. unlink($this->directory . $this->filename);
  122. }
  123. if (file_exists($this->directory . $this->signature) && is_dir($this->directory . $this->signature)) {
  124. $cacheManager = $this->modx->getCacheManager();
  125. if ($cacheManager) {
  126. $cacheManager->deleteTree($this->directory . $this->signature, true, false, array ());
  127. }
  128. }
  129. /* create the transport package */
  130. $this->package = new xPDOTransport($this->modx, $this->signature, $this->directory);
  131. $this->modx->log(modX::LOG_LEVEL_INFO, $this->modx->lexicon('package_created',array(
  132. 'signature' => $this->signature,
  133. )));
  134. return $this->package;
  135. }
  136. /**
  137. * Sets the classes that are to automatically be included and built into the
  138. * package.
  139. *
  140. * @access public
  141. * @param array $classes An array of class names to build in
  142. * @return void
  143. */
  144. public function setAutoSelects(array $classes = array ()) {
  145. $this->autoselects = $classes;
  146. }
  147. /**
  148. * Creates the modTransportVehicle for the specified object.
  149. *
  150. * @access public
  151. * @param mixed $obj The payload being abstracted as a vehicle.
  152. * @param array $attr Attributes for the vehicle.
  153. * @return modTransportVehicle The created modTransportVehicle instance.
  154. */
  155. public function createVehicle($obj, $attr) {
  156. if ($this->{'namespace'}) {
  157. $attr['namespace'] = $this->{'namespace'}; /* package the namespace into the metadata */
  158. }
  159. $vehicle = new modTransportVehicle($obj, $attr);
  160. return $vehicle;
  161. }
  162. /**
  163. * Registers a namespace to the transport package. If no namespace is found,
  164. * will create a namespace.
  165. *
  166. * @access public
  167. * @param string|modNamespace $ns The modNamespace object or the
  168. * string name of the namespace
  169. * @param boolean|array $autoincludes If true, will automatically select
  170. * relative resources to the namespace.
  171. * @param boolean $packageNamespace If false, will not package the namespace
  172. * as a vehicle.
  173. * @param string $path The path for the namespace to be created.
  174. * @param string $assetsPath An optional custom assets_path for the namespace.
  175. * @return boolean True if successful.
  176. */
  177. public function registerNamespace($ns = 'core', $autoincludes = true, $packageNamespace = true, $path = '', $assetsPath = '') {
  178. if (!($ns instanceof modNamespace)) {
  179. $namespace = $this->modx->getObject('modNamespace', $ns);
  180. if (!$namespace) {
  181. $namespace = $this->modx->newObject('modNamespace');
  182. $namespace->set('name', $ns);
  183. $namespace->set('path',$path);
  184. $namespace->set('assets_path',$assetsPath);
  185. }
  186. if (!empty($path)) {
  187. $namespace->set('path',$path);
  188. }
  189. if (!empty($assetsPath)) {
  190. $namespace->set('assets_path',$assetsPath);
  191. }
  192. } else {
  193. $namespace = $ns;
  194. }
  195. $this->{'namespace'} = $namespace;
  196. $this->modx->log(modX::LOG_LEVEL_INFO, $this->modx->lexicon('namespace_registered',array(
  197. 'namespace' => $this->{'namespace'}->get('name'),
  198. )));
  199. /* define some basic attributes */
  200. $attributes = array (
  201. xPDOTransport::UNIQUE_KEY => 'name',
  202. xPDOTransport::PRESERVE_KEYS => true,
  203. xPDOTransport::UPDATE_OBJECT => true,
  204. xPDOTransport::RESOLVE_FILES => true,
  205. xPDOTransport::RESOLVE_PHP => true,
  206. );
  207. if ($packageNamespace) {
  208. /* create the namespace vehicle */
  209. $v = $this->createVehicle($namespace, $attributes);
  210. /* put it into the package */
  211. if (!$this->putVehicle($v)) {
  212. return false;
  213. }
  214. $this->modx->log(modX::LOG_LEVEL_INFO, $this->modx->lexicon('namespace_packaged',array(
  215. 'namespace' => $this->{'namespace'}->get('name'),
  216. )));
  217. }
  218. /* Can automatically package in certain classes based upon their namespace values */
  219. if ($autoincludes == true || (is_array($autoincludes) && !empty ($autoincludes))) {
  220. $this->modx->log(modx::LOG_LEVEL_INFO, $this->modx->lexicon('autoincludes_packaging',array(
  221. 'autoincludes' => print_r($autoincludes, true),
  222. )));
  223. if (is_array($autoincludes)) {
  224. /* set automatically included packages */
  225. $this->setAutoSelects($autoincludes);
  226. }
  227. /* grab all related classes that can be auto-packaged and package them in */
  228. foreach ($this->autoselects as $classname) {
  229. $objs = $this->modx->getCollection($classname, array (
  230. 'namespace' => $namespace->get('name'),
  231. ));
  232. foreach ($objs as $obj) {
  233. $v = $this->createVehicle($obj, $attributes);
  234. if (!$this->putVehicle($v)) {
  235. return false;
  236. }
  237. }
  238. }
  239. }
  240. return true;
  241. }
  242. /**
  243. * Puts the vehicle into the package.
  244. *
  245. * @access public
  246. * @param modTransportVehicle $vehicle The vehicle to insert into the package.
  247. * @return boolean True if successful.
  248. */
  249. public function putVehicle($vehicle) {
  250. $attr = $vehicle->compile();
  251. $obj = $vehicle->fetch();
  252. return $this->package->put($obj, $attr);
  253. }
  254. /**
  255. * Packs the package.
  256. *
  257. * @see xPDOTransport::pack
  258. *
  259. * @access public
  260. * @return boolean True if successful.
  261. */
  262. public function pack() {
  263. return $this->package->pack();
  264. }
  265. /**
  266. * Retrieves the package signature.
  267. *
  268. * @access public
  269. * @return string The signature of the included package.
  270. */
  271. public function getSignature() {
  272. return $this->package->signature;
  273. }
  274. /**
  275. * Generates the model from a schema.
  276. *
  277. * @access public
  278. * @param string $model The directory path of the model to generate to.
  279. * @param string $schema The schema file to generate from.
  280. * @return boolean true if successful
  281. */
  282. public function buildSchema($model, $schema) {
  283. $manager = $this->modx->getManager();
  284. $generator = $manager->getGenerator();
  285. $generator->parseSchema($schema, $model);
  286. return true;
  287. }
  288. /**
  289. * Set an array of attributes into the xPDOTransport manifest.
  290. *
  291. * @access public
  292. * @param array $attributes An array of attributes to set in the
  293. * manifest of the package being built.
  294. * @return null
  295. */
  296. public function setPackageAttributes(array $attributes = array ()) {
  297. if ($this->package !== null) {
  298. foreach ($attributes as $k => $v)
  299. $this->package->setAttribute($k, $v);
  300. } else {
  301. $this->modx->log(modX::LOG_LEVEL_ERROR, $this->modx->lexicon('package_err_spa'));
  302. }
  303. }
  304. }