Server : Apache System : Linux indy02.toastserver.com 3.10.0-962.3.2.lve1.5.85.el7.x86_64 #1 SMP Thu Apr 18 15:18:36 UTC 2024 x86_64 User : palandch ( 1163) PHP Version : 7.1.33 Disable Function : NONE Directory : /home/palandch/www/core/xpdo/transport/ |
<?php /* * Copyright 2010-2013 by MODX, LLC. * * This file is part of xPDO. * * xPDO is free software; you can redistribute it and/or modify it under the * terms of the GNU General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) any later * version. * * xPDO is distributed in the hope that it will be useful, but WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR * A PARTICULAR PURPOSE. See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along with * xPDO; if not, write to the Free Software Foundation, Inc., 59 Temple Place, * Suite 330, Boston, MA 02111-1307 USA */ /** * Represents a transportable package of related data and other resources. * * @package xpdo * @subpackage transport */ /** * Represents xPDOObject and related data in a serialized format for exchange. * * @package xpdo * @subpackage transport */ class xPDOTransport { /**#@+ * Attributes of the package that can be used to control behavior. * @var string */ const PRESERVE_KEYS = 'preserve_keys'; const NATIVE_KEY = 'native_key'; const UNIQUE_KEY = 'unique_key'; const UPDATE_OBJECT = 'update_object'; const RESOLVE_FILES = 'resolve_files'; const RESOLVE_FILES_REMOVE = 'resolve_files_remove'; const RESOLVE_PHP = 'resolve_php'; const PACKAGE_ACTION = 'package_action'; const PACKAGE_STATE = 'package_state'; const RELATED_OBJECTS = 'related_objects'; const RELATED_OBJECT_ATTRIBUTES = 'related_object_attributes'; const MANIFEST_ATTRIBUTES = 'manifest-attributes'; const MANIFEST_VEHICLES = 'manifest-vehicles'; const MANIFEST_VERSION = 'manifest-version'; const PREEXISTING_MODE = 'preexisting_mode'; const INSTALL_FILES = 'install_files'; const UNINSTALL_FILES = 'uninstall_files'; const UNINSTALL_OBJECT = 'uninstall_object'; const ARCHIVE_WITH = 'archive_with'; const ABORT_INSTALL_ON_VEHICLE_FAIL = 'abort_install_on_vehicle_fail'; const PACKAGE_NAME = 'package_name'; const PACKAGE_VERSION = 'package_version'; /** * Indicates how pre-existing objects are treated on install/uninstall. * @var integer */ const PRESERVE_PREEXISTING = 0; const REMOVE_PREEXISTING = 1; const RESTORE_PREEXISTING = 2; /** * Indicates the physical state of the package. * @var integer */ const STATE_UNPACKED = 0; const STATE_PACKED = 1; const STATE_INSTALLED = 2; /** * Indicates an action that can be performed on the package. * @var integer */ const ACTION_INSTALL = 0; const ACTION_UPGRADE = 1; const ACTION_UNINSTALL = 2; /**#@-*/ /** * Indicates which archiving tool to use for pack()'ing and unpack()'ing the transport. * @var integer */ const ARCHIVE_WITH_DEFAULT = 0; const ARCHIVE_WITH_PCLZIP = 1; const ARCHIVE_WITH_ZIPARCHIVE = 2; /** * An {@link xPDO} reference controlling this transport instance. * @var xPDO * @access public */ public $xpdo= null; /** * A unique signature to identify the package. * @var string * @access public */ public $signature= null; /** * A unique name used to identify the package without the version. * @var string */ public $name= null; /** * The package version, as a PHP-standardized version number string. * @var string */ public $version= null; /** * Indicates the state of the xPDOTransport instance. * @var integer */ public $state= null; /** * Stores various attributes about the transport package. * @var array */ public $attributes= array (); /** * A map of object vehicles containing payloads of data for transport. * @var array */ public $vehicles= array (); /** * The physical location of the transport package. * @var string */ public $path= null; /** * The current manifest version for this transport. * @var string */ public $manifestVersion = '1.1'; /** * An map of preserved objects from an install used by uninstall. * @var array */ public $_preserved = array(); /** * Parse the name and version from a package signature. * * @static * @param string $signature The package signature to parse. * @return array An array with two elements containing the name and version respectively. */ public static function parseSignature($signature) { $exploded = explode('-', $signature); $name = current($exploded); $version = ''; $part = next($exploded); while ($part !== false) { $dotPos = strpos($part, '.'); if ($dotPos > 0 && is_numeric(substr($part, 0, $dotPos))) { $version = $part; while (($part = next($exploded)) !== false) { $version .= '-' . $part; } break; } else { $name .= '-' . $part; $part = next($exploded); } } return array( $name, $version ); } /** * Compares two package versions by signature. * * @static * @param string $signature1 A package signature. * @param string $signature2 Another package signature to compare. * @return bool|int Returns -1 if the first version is lower than the second, 0 if they * are equal, and 1 if the second is lower if the package names in the provided * signatures are equal; otherwise returns false. */ public static function compareSignature($signature1, $signature2) { $value = false; $parsed1 = self::parseSignature($signature1); $parsed2 = self::parseSignature($signature2); if ($parsed1[0] === $parsed2[0]) { $value = version_compare($parsed1[1], $parsed2[1]); } return $value; } /** * Prepares and returns a new xPDOTransport instance. * * @param xPDO &$xpdo The xPDO instance accessing this package. * @param string $signature The unique signature of the package. * @param string $path Valid path to the physical transport package. * @param array $options An optional array of attributes for constructing the instance. */ public function __construct(& $xpdo, $signature, $path, array $options = array()) { $this->xpdo= & $xpdo; $this->signature= $signature; $this->path= $path; if (!empty($options) && array_key_exists(self::PACKAGE_NAME, $options) && array_key_exists(self::PACKAGE_VERSION, $options)) { $this->name= $options[self::PACKAGE_NAME]; $this->version= $options[self::PACKAGE_VERSION]; } else { $nameAndVersion= self::parseSignature($this->signature); if (count($nameAndVersion) == 2) { $this->name= $nameAndVersion[0]; $this->version= $nameAndVersion[1]; } } $xpdo->loadClass('transport.xPDOVehicle', XPDO_CORE_PATH, true, true); } /** * Get an {@link xPDOVehicle} instance from an unpacked transport package. * * @param string $objFile Full path to a payload file to import. The * payload file, when included must return a valid {@link xPDOVehicle::$payload}. * @param array $options An array of options to be applied when getting the * object. * @return xPDOVehicle The vehicle represented in the file. */ public function get($objFile, $options= array ()) { $vehicle = null; $objFile = $this->path . $this->signature . '/' . $objFile; $vehiclePackage = isset($options['vehicle_package']) ? $options['vehicle_package'] : ''; $vehiclePackagePath = isset($options['vehicle_package_path']) ? $options['vehicle_package_path'] : ''; $vehicleClass = isset($options['vehicle_class']) ? $options['vehicle_class'] : ''; if (empty($vehiclePackage)) $vehiclePackage = $options['vehicle_package'] = 'transport'; if (empty($vehicleClass)) $vehicleClass = $options['vehicle_class'] = 'xPDOObjectVehicle'; if ($className = $this->xpdo->loadClass("{$vehiclePackage}.{$vehicleClass}", $vehiclePackagePath, true, true)) { $vehicle = new $className(); if (file_exists($objFile)) { $payload = include ($objFile); if ($payload) { $vehicle->payload = $payload; } } } else { $this->xpdo->log(xPDO::LOG_LEVEL_ERROR, "The specified xPDOVehicle class ({$vehiclePackage}.{$vehicleClass}) could not be loaded."); } return $vehicle; } /** * Install vehicles in the package into the sponsor {@link xPDO} instance. * * @param array $options Install options to be applied to the process. * @return boolean true if the vehicles were successfully installed. */ public function install($options= array ()) { $installed= false; $saved = array(); $this->_preserved = array(); if (!is_array($options)) { $options= array(xPDOTransport::PACKAGE_ACTION => xPDOTransport::ACTION_INSTALL); } elseif (!isset($options[xPDOTransport::PACKAGE_ACTION])) { $options[xPDOTransport::PACKAGE_ACTION]= xPDOTransport::ACTION_INSTALL; } if (!empty ($this->vehicles)) { foreach ($this->vehicles as $vIndex => $vehicleMeta) { $vOptions = array_merge($options, $vehicleMeta); if ($vehicle = $this->get($vehicleMeta['filename'], $vOptions)) { $vehicleInstalled = $vehicle->install($this, $vOptions); if (!$vehicleInstalled && isset($vehicle->payload[xPDOTransport::ABORT_INSTALL_ON_VEHICLE_FAIL]) && !empty($vehicle->payload[xPDOTransport::ABORT_INSTALL_ON_VEHICLE_FAIL])) { $this->xpdo->log(xPDO::LOG_LEVEL_ERROR, "Vehicle {$vehicle->payload['guid']} in transport {$this->signature} failed to install and indicated the process should be aborted."); return false; } else { $saved[$vehicle->payload['guid']] = $vehicleInstalled; } } } $this->writePreserved(); if (!empty($saved)) { $installed = true; } } else { $this->xpdo->log(xPDO::LOG_LEVEL_WARN, 'No vehicles are defined in the transport package (' . $this->signature . ') manifest for installation'); } return $installed; } /** * Uninstall vehicles in the package from the sponsor {@link xPDO} instance. * * @param array $options Uninstall options to be applied to the process. * @return boolean true if the vehicles were successfully uninstalled. */ public function uninstall($options = array ()) { $processed = array(); if (!is_array($options)) { $options= array(xPDOTransport::PACKAGE_ACTION => xPDOTransport::ACTION_UNINSTALL); } elseif (!isset($options[xPDOTransport::PACKAGE_ACTION])) { $options[xPDOTransport::PACKAGE_ACTION]= xPDOTransport::ACTION_UNINSTALL; } if (!empty ($this->vehicles)) { $this->_preserved = $this->loadPreserved(); $vehicleArray = array_reverse($this->vehicles, true); foreach ($vehicleArray as $vIndex => $vehicleMeta) { $vOptions = array_merge($options, $vehicleMeta); if ($this->xpdo->getDebug() === true) { $this->xpdo->log(xPDO::LOG_LEVEL_DEBUG, "Removing Vehicle: " . print_r($vOptions, true)); } if ($vehicle = $this->get($vehicleMeta['filename'], $vOptions)) { $processed[$vehicleMeta['guid']] = $vehicle->uninstall($this, $vOptions); } else { $this->xpdo->log(xPDO::LOG_LEVEL_ERROR, 'Could not load vehicle: ' . print_r($vOptions, true)); } } } else { $this->xpdo->log(xPDO::LOG_LEVEL_WARN, 'No vehicles are defined in the transport package (' . $this->signature . ') for removal'); } $uninstalled = (array_search(false, $processed, true) === false); return $uninstalled; } /** * Wrap artifact with an {@link xPDOVehicle} and register in the transport. * * @param mixed $artifact An artifact to load into the transport. * @param array $attributes A set of attributes related to the artifact; these * can be anything from rules describing how to pack or unpack the artifact, * or any other data that might be useful when dealing with a transportable * artifact. * @return bool TRUE if the artifact is successfully registered in the transport. */ public function put($artifact, $attributes = array ()) { $added= false; if (!empty($artifact)) { $vehiclePackage = isset($attributes['vehicle_package']) ? $attributes['vehicle_package'] : ''; $vehiclePackagePath = isset($attributes['vehicle_package_path']) ? $attributes['vehicle_package_path'] : ''; $vehicleClass = isset($attributes['vehicle_class']) ? $attributes['vehicle_class'] : ''; if (empty($vehiclePackage)) $vehiclePackage = $attributes['vehicle_package'] = 'transport'; if (empty($vehicleClass)) $vehicleClass = $attributes['vehicle_class'] = 'xPDOObjectVehicle'; if ($className = $this->xpdo->loadClass("{$vehiclePackage}.{$vehicleClass}", $vehiclePackagePath, true, true)) { /** @var xPDOVehicle $vehicle */ $vehicle = new $className(); $vehicle->put($this, $artifact, $attributes); if ($added= $vehicle->store($this)) { $this->registerVehicle($vehicle); } } else { $this->xpdo->log(xPDO::LOG_LEVEL_ERROR, "The specified xPDOVehicle class ({$vehiclePackage}.{$vehicleClass}) could not be loaded."); } } return $added; } /** * Pack the {@link xPDOTransport} instance in preparation for distribution. * * @return boolean Indicates if the transport was packed successfully. */ public function pack() { if (empty($this->vehicles)) { $this->xpdo->log(xPDO::LOG_LEVEL_ERROR, 'Attempt to pack a transport package with no vehicles.'); return false; } $this->writeManifest(); $fileName = $this->path . $this->signature . '.transport.zip'; return xPDOTransport::_pack($this->xpdo, $fileName, $this->path, $this->signature); } /** * Pack the resources from path relative to source into an archive with filename. * * @uses compression.xPDOZip OR compression.PclZip * @todo Refactor this to be implemented in a service class external to xPDOTransport. * * @param xPDO &$xpdo A reference to an xPDO instance. * @param string $filename A valid zip archive filename. * @param string $path An absolute file system path location of the resources to pack. * @param string $source A relative portion of path to include in the archive. * @return boolean True if packed successfully. */ public static function _pack(& $xpdo, $filename, $path, $source) { $packed = false; $packResults = false; $errors = array(); if ($xpdo->getOption(xPDOTransport::ARCHIVE_WITH, null, 0) != xPDOTransport::ARCHIVE_WITH_PCLZIP && class_exists('ZipArchive', true) && $xpdo->loadClass('compression.xPDOZip', XPDO_CORE_PATH, true, true)) { if ($xpdo->getDebug() === true) { $xpdo->log(xPDO::LOG_LEVEL_DEBUG, "Using xPDOZip / native ZipArchive", null, __METHOD__, __FILE__, __LINE__); } $archive = new xPDOZip($xpdo, $filename, array(xPDOZip::CREATE => true, xPDOZip::OVERWRITE => true)); if ($archive) { $packResults = $archive->pack("{$path}{$source}", array(xPDOZip::ZIP_TARGET => "{$source}/")); $archive->close(); if (!$archive->hasError() && !empty($packResults)) { $packed = true; } else { $errors = $archive->getErrors(); } } } elseif (class_exists('PclZip') || include(XPDO_CORE_PATH . 'compression/pclzip.lib.php')) { $archive = new PclZip($filename); if ($archive) { $packResults = $archive->create("{$path}{$source}", PCLZIP_OPT_REMOVE_PATH, "{$path}"); if ($packResults) { $packed = true; } else { $errors = $archive->errorInfo($xpdo->getDebug() === true); } } } if (!$packed) { $xpdo->log(xPDO::LOG_LEVEL_ERROR, "Error packing {$path}{$source} to {$filename}: " . print_r($errors, true)); } if ($xpdo->getDebug() === true) { $xpdo->log(xPDO::LOG_LEVEL_DEBUG, "Results of packing {$path}{$source} to {$filename}: " . print_r($packResults, true), null, __METHOD__, __FILE__, __LINE__); } return $packed; } /** * Write the package manifest file. * * @return boolean Indicates if the manifest was successfully written. */ public function writeManifest() { $written = false; if (!empty ($this->vehicles)) { if (!empty($this->attributes['setup-options']) && is_array($this->attributes['setup-options'])) { $cacheManager = $this->xpdo->getCacheManager(); $cacheManager->copyFile($this->attributes['setup-options']['source'],$this->path . $this->signature . '/setup-options.php'); $this->attributes['setup-options'] = $this->signature . '/setup-options.php'; } $manifest = array( xPDOTransport::MANIFEST_VERSION => $this->manifestVersion, xPDOTransport::MANIFEST_ATTRIBUTES => $this->attributes, xPDOTransport::MANIFEST_VEHICLES => $this->vehicles ); $content = var_export($manifest, true); $cacheManager = $this->xpdo->getCacheManager(); if ($content && $cacheManager) { $fileName = $this->path . $this->signature . '/manifest.php'; $content = "<?php return {$content};"; if (!($written = $cacheManager->writeFile($fileName, $content))) { $this->xpdo->log(xPDO::LOG_LEVEL_ERROR, 'Error writing manifest to ' . $fileName); } } } return $written; } /** * Write objects preserved during install() to file for use by uninstall(). * * @return boolean Indicates if the preserved file was successfully written. */ public function writePreserved() { $written = false; if (!empty($this->_preserved)) { $content = var_export($this->_preserved, true); $cacheManager = $this->xpdo->getCacheManager(); if ($content && $cacheManager) { $fileName = $this->path . $this->signature . '/preserved.php'; $content = "<?php return {$content};"; if (!($written = $cacheManager->writeFile($fileName, $content))) { $this->xpdo->log(xPDO::LOG_LEVEL_ERROR, 'Error writing preserved objects to ' . $fileName); } } } return $written; } /** * Load preserved objects from the previous install(). * * @return array An array of preserved objects, or an empty array. */ public function loadPreserved() { $preserved = array(); $fileName = $this->path . $this->signature . '/preserved.php'; if (file_exists($fileName)) { $content = include($fileName); if (is_array($content)) { $preserved = $content; } else { $this->xpdo->log(xPDO::LOG_LEVEL_ERROR, 'Error loading preserved objects from ' . $fileName); } } return $preserved; } /** * Register an xPDOVehicle with this transport instance. * * @param xPDOVehicle &$vehicle A reference to the vehicle being registered. */ public function registerVehicle(& $vehicle) { $this->vehicles[] = $vehicle->register($this); } /** * Get an attribute of the package manifest. * * @param string $key The key of the attribute to retrieve. * @return mixed The value of the attribute or null if it is not set. */ public function getAttribute($key) { $value = null; if (array_key_exists($key, $this->attributes)) $value = $this->attributes[$key]; return $value; } /** * Set an attribute of the package manifest. * * @param string $key The key identifying the attribute to set. * @param mixed $value The value to set the attribute to. */ public function setAttribute($key, $value) { $this->attributes[$key]= $value; } /** * Get dependency requirements for this xPDOTransport. * * @param array $requires An optional array of dependent package constraints * to override/supplement those specified in the package metadata. * * @return array An array of dependency requirements for the package. */ public function getDependencies(array $requires = array()) { $requiresAttribute = $this->getAttribute('requires'); if (is_array($requiresAttribute)) { $requires = array_merge($requiresAttribute, $requires); } return $requires; } /** * Check if dependencies are satisfied for the package. * * Override this method to check implementation specific package * dependencies. This implementation only checks platform dependencies. * * @param array $options An array of options for the checks. * * @return array An array containing any unsatisfied dependencies. */ public function checkDependencies(array $options = array()) { $unsatisfied = $this->getDependencies(); return self::checkPlatformDependencies($unsatisfied); } /** * Check if any specified platform dependencies are satisfied. * * @param array $dependencies An array of dependencies to test. * * @return array An array containing any unsatisfied dependencies. */ public static function checkPlatformDependencies($dependencies) { if (is_array($dependencies)) { foreach ($dependencies as $depName => $depRequire) { switch ($depName) { case 'php': if (self::satisfies(XPDO_PHP_VERSION, $depRequire)) { unset($dependencies[$depName]); } break; default: break; } } } return $dependencies; } /** * Test if a version satisfies a version constraint. * * @param string $version The version to test. * @param string $constraint The constraint to satisfy. * * @return bool TRUE if the version satisfies the constraint; FALSE otherwise. */ public static function satisfies($version, $constraint) { $satisfied = false; $constraint = trim($constraint); if (substr($constraint, 0, 1) === '~') { $requirement = substr($constraint, 1); $constraint = ">={$requirement},<" . self::nextSignificantRelease($requirement); } if (strpos($constraint, ',') !== false) { $exploded = explode(',', $constraint); array_walk($exploded, 'trim'); $satisfies = array(); foreach ($exploded as $requirement) { $satisfies[] = self::satisfies($version, $requirement); } $satisfied = (false === array_search(false, $satisfies, true)); } elseif (($wildcardPos = strpos($constraint, '.*')) > 0) { $requirement = substr($constraint, 0, $wildcardPos + 1); $requirements = array( ">=" . $requirement, "<" . self::nextSignificantRelease($requirement) ); $satisfies = array(); foreach ($requirements as $requires) { $satisfies[] = self::satisfies($version, $requires); } $satisfied = (false === array_search(false, $satisfies, true)); } elseif (in_array(substr($constraint, 0, 1), array('<', '>', '!'))) { $operator = substr($constraint, 0, 1); $versionPos = 1; if (substr($constraint, 1, 1) === '=') { $operator .= substr($constraint, 1, 1); $versionPos++; } $requirement = substr($constraint, $versionPos); $satisfied = version_compare($version, $requirement, $operator); } elseif ($constraint === '*') { $satisfied = true; } elseif (version_compare($version, $constraint) === 0) { $satisfied = true; } return $satisfied; } /** * Get the next significant release version for a given version string. * * @param string $version A valid SemVer version string. * * @return string The next significant version for the specified version. */ public static function nextSignificantRelease($version) { $parsed = explode('.', $version, 3); if (count($parsed) > 1) array_pop($parsed); $parsed[count($parsed) - 1]++; if (count($parsed) === 1) $parsed[] = '0'; return implode('.', $parsed); } /** * Get an xPDOTransport instance from an existing package. * * @param xPDO &$xpdo A reference to an xPDO instance. * @param string $source Path to the packed transport. * @param string $target Path to unpack the transport to. * @param int $state The packed state of the transport. * * @return null|xPDOTransport An xPDOTransport instance or null. */ public static function retrieve(& $xpdo, $source, $target, $state= xPDOTransport::STATE_PACKED) { $instance= null; $signature = basename($source, '.transport.zip'); if (file_exists($source)) { if (is_writable($target)) { $manifest = xPDOTransport :: unpack($xpdo, $source, $target, $state); if ($manifest) { $instance = new xPDOTransport($xpdo, $signature, $target); if (!$instance) { $xpdo->log(xPDO::LOG_LEVEL_ERROR, "Could not instantiate a valid xPDOTransport object from the package {$source} to {$target}. SIG: {$signature} MANIFEST: " . print_r($manifest, 1)); } $manifestVersion = xPDOTransport :: manifestVersion($manifest); switch ($manifestVersion) { case '0.1': $instance->vehicles = xPDOTransport :: _convertManifestVer1_1(xPDOTransport :: _convertManifestVer1_0($manifest)); case '0.2': $instance->vehicles = xPDOTransport :: _convertManifestVer1_1(xPDOTransport :: _convertManifestVer1_0($manifest[xPDOTransport::MANIFEST_VEHICLES])); $instance->attributes = $manifest[xPDOTransport::MANIFEST_ATTRIBUTES]; break; case '1.0': $instance->vehicles = xPDOTransport :: _convertManifestVer1_1($manifest[xPDOTransport::MANIFEST_VEHICLES]); $instance->attributes = $manifest[xPDOTransport::MANIFEST_ATTRIBUTES]; break; default: $instance->vehicles = $manifest[xPDOTransport::MANIFEST_VEHICLES]; $instance->attributes = $manifest[xPDOTransport::MANIFEST_ATTRIBUTES]; break; } } else { $xpdo->log(xPDO::LOG_LEVEL_ERROR, "Could not unpack package {$source} to {$target}. SIG: {$signature}"); } } else { $xpdo->log(xPDO::LOG_LEVEL_ERROR, "Could not unpack package: {$target} is not writable. SIG: {$signature}"); } } else { $xpdo->log(xPDO::LOG_LEVEL_ERROR, "Package {$source} not found. SIG: {$signature}"); } return $instance; } /** * Store the package to a specified resource location. * * @todo Implement ability to store a package to a specified location, supporting various * transport methods. * @param mixed $location The location to store the package. * @return bool TRUE if the package is stored successfully. */ public function store($location) { $stored= false; if ($this->state === xPDOTransport::STATE_PACKED) {} return $stored; } /** * Unpack the package to prepare for installation and return a manifest. * * @param xPDO &$xpdo A reference to an xPDO instance. * @param string $from Filename of the archive containing the transport package. * @param string $to The root path where the contents of the archive should be extracted. This * path must be writable by the user executing the PHP process on the server. * @param integer $state The current state of the package, i.e. packed or unpacked. * @return array The manifest which is included after successful extraction. */ public static function unpack(& $xpdo, $from, $to, $state = xPDOTransport::STATE_PACKED) { $manifest= null; if ($state !== xPDOTransport::STATE_UNPACKED) { $resources = xPDOTransport::_unpack($xpdo, $from, $to); } else { $resources = true; } if ($resources) { $manifestFilename = $to . basename($from, '.transport.zip') . '/manifest.php'; if (file_exists($manifestFilename)) { $manifest= @include ($manifestFilename); } else { $xpdo->log(xPDO::LOG_LEVEL_ERROR, "Could not find package manifest at {$manifestFilename}"); } } return $manifest; } /** * Unpack a zip archive to a specified location. * * @uses compression.xPDOZip OR compression.PclZip * @todo Refactor this to be implemented in a service class external to xPDOTransport. * * @param xPDO &$xpdo A reference to an xPDO instance. * @param string $from An absolute file system location to a valid zip archive. * @param string $to A file system location to extract the contents of the archive to. * @return array|boolean An array of unpacked resources or false on failure. */ public static function _unpack(& $xpdo, $from, $to) { $resources = false; if ($xpdo->getOption(xPDOTransport::ARCHIVE_WITH, null, 0) != xPDOTransport::ARCHIVE_WITH_PCLZIP && class_exists('ZipArchive', true) && $xpdo->loadClass('compression.xPDOZip', XPDO_CORE_PATH, true, true)) { $archive = new xPDOZip($xpdo, $from); if ($archive) { $resources = $archive->unpack($to); $archive->close(); } } elseif (class_exists('PclZip') || include(XPDO_CORE_PATH . 'compression/pclzip.lib.php')) { $archive = new PclZip($from); if ($archive) { $resources = $archive->extract(PCLZIP_OPT_PATH, $to); } } return $resources; } /** * Returns the structure version of the given manifest array. * * @static * @param array $manifest A valid xPDOTransport manifest array. * @return string Version string of the manifest structure. */ public static function manifestVersion($manifest) { $version = false; if (is_array($manifest)) { if (isset($manifest[xPDOTransport::MANIFEST_VERSION])) { $version = $manifest[xPDOTransport::MANIFEST_VERSION]; } elseif (isset($manifest[xPDOTransport::MANIFEST_VEHICLES])) { $version = '0.2'; } else { $version = '0.1'; } } return $version; } /** * Converts older manifest vehicles to 1.0 format. * * @static * @access private * @param array $manifestVehicles A structure representing vehicles from a pre-1.0 manifest * format. * @return array Vehicle definition structures converted to 1.0 format. */ protected static function _convertManifestVer1_0($manifestVehicles) { $manifest = array(); foreach ($manifestVehicles as $vClass => $vehicles) { foreach ($vehicles as $vKey => $vehicle) { $entry = array( 'class' => $vClass, 'native_key' => $vehicle['native_key'], 'filename' => $vehicle['filename'], ); if (isset($vehicle['namespace'])) { $entry['namespace'] = $vehicle['namespace']; } $manifest[] = $entry; } } return $manifest; } /** * Converts 1.0 manifest vehicles to 1.1 format. * * @static * @access private * @param array $vehicles A structure representing vehicles from a pre-1.1 manifest format. * @return array Vehicle definition structures converted to 1.1 format. */ protected static function _convertManifestVer1_1($vehicles) { $manifest = array(); foreach ($vehicles as $vKey => $vehicle) { $entry = $vehicle; if (!isset($vehicle['vehicle_class'])) { $entry['vehicle_class'] = 'xPDOObjectVehicle'; } if (!isset($vehicle['vehicle_package'])) { $entry['vehicle_package'] = 'transport'; } $manifest[] = $entry; } return $manifest; } }