|
eZ Publish
[4.0]
|
00001 <?php 00002 // 00003 // Definition of eZPackage class 00004 // 00005 // Created on: <23-Jul-2003 12:34:55 amos> 00006 // 00007 // ## BEGIN COPYRIGHT, LICENSE AND WARRANTY NOTICE ## 00008 // SOFTWARE NAME: eZ Publish 00009 // SOFTWARE RELEASE: 4.0.x 00010 // COPYRIGHT NOTICE: Copyright (C) 1999-2008 eZ Systems AS 00011 // SOFTWARE LICENSE: GNU General Public License v2.0 00012 // NOTICE: > 00013 // This program is free software; you can redistribute it and/or 00014 // modify it under the terms of version 2.0 of the GNU General 00015 // Public License as published by the Free Software Foundation. 00016 // 00017 // This program is distributed in the hope that it will be useful, 00018 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00019 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00020 // GNU General Public License for more details. 00021 // 00022 // You should have received a copy of version 2.0 of the GNU General 00023 // Public License along with this program; if not, write to the Free 00024 // Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 00025 // MA 02110-1301, USA. 00026 // 00027 // 00028 // ## END COPYRIGHT, LICENSE AND WARRANTY NOTICE ## 00029 // 00030 00031 /*! \file ezpackagehandler.php 00032 */ 00033 00034 /*! 00035 \group package The package manager system 00036 \ingroup package 00037 \class eZPackage ezpackagehandler.php 00038 \brief Maintains eZ Publish packages 00039 00040 */ 00041 00042 //include_once( 'lib/ezfile/classes/ezfile.php' ); 00043 //include_once( 'lib/ezfile/classes/ezdir.php' ); 00044 //include_once( 'lib/ezfile/classes/ezfilehandler.php' ); 00045 00046 class eZPackage 00047 { 00048 const VERSION = '3.5.2'; 00049 const DEVELOPMENT = false; 00050 const USE_CACHE = true; 00051 const CACHE_CODE_DATE = 1069339607; 00052 00053 const STATUS_ALREADY_EXISTS = 1; 00054 const STATUS_INVALID_NAME = 2; 00055 00056 const NON_INTERACTIVE = -1; 00057 00058 /*! 00059 Constructor 00060 */ 00061 function eZPackage( $parameters = array(), $repositoryPath = false ) 00062 { 00063 $this->setParameters( $parameters ); 00064 if ( !$repositoryPath ) 00065 $repositoryPath = eZPackage::repositoryPath(); 00066 $this->RepositoryPath = $repositoryPath; 00067 $this->RepositoryInformation = null; 00068 } 00069 00070 /*! 00071 Removes the package directory and all it's subfiles/directories. 00072 */ 00073 function remove() 00074 { 00075 $path = $this->path(); 00076 if ( file_exists( $path ) ) 00077 { 00078 eZDir::recursiveDelete( $path ); 00079 } 00080 $this->setInstalled( false ); 00081 } 00082 00083 /*! 00084 \private 00085 */ 00086 function setParameters( $parameters = array() ) 00087 { 00088 $timestamp = time(); 00089 if ( isset( $_SERVER['HOSTNAME'] ) ) 00090 $host = $_SERVER['HOSTNAME']; 00091 else if ( isset( $_SERVER['HTTP_HOST'] ) ) 00092 $host = $_SERVER['HTTP_HOST']; 00093 else 00094 $host = 'localhost'; 00095 $packaging = array( 'timestamp' => $timestamp, 00096 'host' => $host, 00097 'packager' => false ); 00098 //include_once( 'lib/version.php' ); 00099 $ezpublishVersion = eZPublishSDK::version( true ); 00100 $ezpublishNamedVersion = eZPublishSDK::version( false, false, true ); 00101 $ezpublish = array( 'version' => $ezpublishVersion, 00102 'named-version' => $ezpublishNamedVersion ); 00103 $defaults = array( 'name' => false, 00104 'development' => eZPackage::DEVELOPMENT, 00105 'summary' => false, 00106 'description' => false, 00107 'vendor' => false, 00108 'vendor-dir' => false, 00109 'priority' => false, 00110 'type' => false, 00111 'extension' => false, 00112 'install_type' => 'install', 00113 'ezpublish' => $ezpublish, 00114 'maintainers' => array(), 00115 'packaging' => $packaging, 00116 'source' => false, 00117 'documents' => array(), 00118 'groups' => array(), 00119 'changelog' => array(), 00120 'file-list' => array(), 00121 'simple-file-list' => array(), 00122 'version-number' => false, 00123 'release-number' => false, 00124 'release-timestamp' => false, 00125 'licence' => false, 00126 'state' => false, 00127 'dependencies' => array( 'provides' => array(), 00128 'requires' => array(), 00129 'obsoletes' => array(), 00130 'conflicts' => array() ), 00131 'install' => array(), 00132 'uninstall' => array() ); 00133 $this->PolicyCache = array(); 00134 $this->InstallData = array(); 00135 $this->Parameters = array_merge( $defaults, $parameters ); 00136 } 00137 00138 /*! 00139 \static 00140 \return An associative array with the possible types for a package. 00141 Each entry contains an \c id and a \c name key. 00142 */ 00143 static function typeList() 00144 { 00145 $typeList =& $GLOBALS['eZPackageTypeList']; 00146 if ( !isset( $typeList ) ) 00147 { 00148 $typeList = array(); 00149 $ini = eZINI::instance( 'package.ini' ); 00150 $types = $ini->variable( 'PackageSettings', 'TypeList' ); 00151 foreach ( $types as $typeID => $typeName ) 00152 { 00153 $typeList[] = array( 'name' => $typeName, 00154 'id' => $typeID ); 00155 } 00156 } 00157 return $typeList; 00158 } 00159 00160 /*! 00161 \static 00162 \return An associative array with the possible states for a package. 00163 Each entry contains an \c id and a \c name key. 00164 */ 00165 static function stateList() 00166 { 00167 $stateList =& $GLOBALS['eZPackageStateList']; 00168 if ( !isset( $stateList ) ) 00169 { 00170 $stateList = array(); 00171 $ini = eZINI::instance( 'package.ini' ); 00172 $states = $ini->variable( 'PackageSettings', 'StateList' ); 00173 foreach ( $states as $stateID => $stateName ) 00174 { 00175 $stateList[] = array( 'name' => $stateName, 00176 'id' => $stateID); 00177 } 00178 } 00179 return $stateList; 00180 } 00181 00182 /*! 00183 \param $repositoryID The id (string) of the repository to create the package in. 00184 If \c false it will use the \c local repository. 00185 */ 00186 static function create( $name, $parameters = array(), $repositoryPath = false, $repositoryID = false ) 00187 { 00188 $parameters['name'] = $name; 00189 $handler = new eZPackage( $parameters, $repositoryPath ); 00190 00191 // New packages always use local repository 00192 if ( $repositoryID === false ) 00193 $repositoryID = 'local'; 00194 $repositoryInformation = $handler->repositoryInformation( $repositoryID ); 00195 if ( $repositoryPath !== false ) 00196 $repositoryInformation['path'] = $repositoryPath; 00197 $handler->setCurrentRepositoryInformation( $repositoryInformation ); 00198 return $handler; 00199 } 00200 00201 /*! 00202 \return the attributes for this package. 00203 */ 00204 function attributes() 00205 { 00206 return array( 'is_local', 00207 'development', 00208 'name', 'summary', 'description', 00209 'vendor', 'vendor-dir', 'priority', 'type', 00210 'extension', 'source', 00211 'version-number', 'release-number', 'release-timestamp', 00212 'maintainers', 'documents', 'groups', 00213 'simple-file-list', 'file-list', 'file-count', 00214 'can_read', 'can_export', 'can_import', 'can_install', 00215 'changelog', 'dependencies', 00216 'is_installed', 00217 'install_type', 00218 'thumbnail-list', 00219 'install', 'uninstall', 00220 'licence', 'state', 00221 'ezpublish-version', 'ezpublish-named-version', 'packaging-timestamp', 00222 'packaging-host', 'packaging-packager' ); 00223 } 00224 00225 /*! 00226 Sets the attribute named \a $attributeName to have the value \a $attributeValue. 00227 */ 00228 function setAttribute( $attributeName, $attributeValue ) 00229 { 00230 if ( !in_array( $attributeName, 00231 array( 'development', 00232 'name', 'summary', 'description', 00233 'vendor', 'vendor-dir', 'priority', 'type', 00234 'install_type', 00235 'extension', 'source', 00236 'licence', 'state' ) ) ) 00237 return false; 00238 if ( array_key_exists( $attributeName, $this->Parameters ) and 00239 !is_array( $this->Parameters[$attributeName] )) 00240 { 00241 $this->Parameters[$attributeName] = $attributeValue; 00242 return true; 00243 } 00244 return false; 00245 } 00246 00247 /*! 00248 \return \c true if the attribute named \a $attributeName exists. 00249 */ 00250 function hasAttribute( $attributeName /*, $attributeList = false*/ ) 00251 { 00252 return in_array( $attributeName, $this->attributes() ); 00253 } 00254 00255 /*! 00256 \return the value of the attribute named \a $attributeName. 00257 */ 00258 function attribute( $attributeName /*, $attributeList = false*/ ) 00259 { 00260 if ( in_array( $attributeName, 00261 array( 'development', 00262 'name', 'summary', 'description', 00263 'vendor', 'vendor-dir', 'priority', 'type', 00264 'extension', 'source', 00265 'version-number', 'release-number', 'release-timestamp', 00266 'maintainers', 'documents', 'groups', 00267 'simple-file-list', 'file-list', 00268 'changelog', 'dependencies', 00269 'install', 'uninstall', 00270 'install_type', 00271 'licence', 'state', 'settings-files' ) ) ) 00272 return $this->Parameters[$attributeName]; 00273 else if ( $attributeName == 'is_installed' ) 00274 return $this->isInstalled; 00275 else if ( $attributeName == 'ezpublish-version' ) 00276 return $this->Parameters['ezpublish']['version']; 00277 else if ( $attributeName == 'ezpublish-named-version' ) 00278 return $this->Parameters['ezpublish']['named-version']; 00279 else if ( $attributeName == 'packaging-timestamp' ) 00280 return $this->Parameters['packaging']['timestamp']; 00281 else if ( $attributeName == 'packaging-host' ) 00282 return $this->Parameters['packaging']['host']; 00283 else if ( $attributeName == 'packaging-packager' ) 00284 return $this->Parameters['packaging']['packager']; 00285 else if ( $attributeName == 'can_read' ) 00286 { 00287 return $this->canRead(); 00288 } 00289 else if ( $attributeName == 'can_export' ) 00290 { 00291 return $this->canExport(); 00292 } 00293 else if ( $attributeName == 'can_import' ) 00294 { 00295 return $this->canImport(); 00296 } 00297 else if ( $attributeName == 'can_install' ) 00298 { 00299 return $this->canInstall(); 00300 } 00301 else if ( $attributeName == 'file-count' ) 00302 { 00303 return $this->fileCount(); 00304 } 00305 else if ( $attributeName == 'thumbnail-list' ) 00306 { 00307 return $this->thumbnailList( 'default' ); 00308 } 00309 else if ( $attributeName == 'is_local' ) 00310 { 00311 $repositoryInformation = $this->currentRepositoryInformation(); 00312 return ( $repositoryInformation['type'] == 'local' ); 00313 } 00314 00315 eZDebug::writeError( "No such attribute: $attributeName for eZPackage", 'eZPackage::attribute' ); 00316 return null; 00317 } 00318 00319 static function canUsePolicyFunction( $functionName ) 00320 { 00321 //include_once( "kernel/classes/datatypes/ezuser/ezuser.php" ); 00322 $currentUser = eZUser::currentUser(); 00323 $accessResult = $currentUser->hasAccessTo( 'package', $functionName ); 00324 if ( in_array( $accessResult['accessWord'], array( 'yes', 'limited' ) ) ) 00325 { 00326 return true; 00327 } 00328 return false; 00329 } 00330 00331 function canRead() 00332 { 00333 return $this->canUsePackagePolicyFunction( 'read' ); 00334 } 00335 00336 function canExport() 00337 { 00338 return $this->canUsePackagePolicyFunction( 'export' ); 00339 } 00340 00341 function canImport() 00342 { 00343 return $this->canUsePackagePolicyFunction( 'import' ); 00344 } 00345 00346 function canInstall() 00347 { 00348 return $this->canUsePackagePolicyFunction( 'install' ); 00349 } 00350 00351 function canUsePackagePolicyFunction( $functionName ) 00352 { 00353 if ( !isset( $this->PolicyCache[$functionName] ) ) 00354 { 00355 //include_once( "kernel/classes/datatypes/ezuser/ezuser.php" ); 00356 $currentUser = eZUser::currentUser(); 00357 $accessResult = $currentUser->hasAccessTo( 'package', $functionName ); 00358 $limitationList = array(); 00359 $canUse = false; 00360 if ( $accessResult['accessWord'] == 'yes' ) 00361 { 00362 $this->PolicyCache[$functionName] = true; 00363 } 00364 else if ( $accessResult['accessWord'] == 'limited' ) 00365 { 00366 $allRoles = array(); 00367 $limitationList = $accessResult['policies']; 00368 $typeList = false; 00369 foreach( $limitationList as $limitationArray ) 00370 { 00371 foreach ( $limitationArray as $key => $limitation ) 00372 { 00373 if ( $key == 'Type' ) 00374 { 00375 if ( !is_array( $typeList ) ) 00376 $typeList = array(); 00377 $typeList = array_merge( $typeList, $limitation ); 00378 } 00379 } 00380 } 00381 if ( $typeList === false ) 00382 { 00383 $this->PolicyCache[$functionName] = true; 00384 } 00385 else 00386 { 00387 $this->PolicyCache[$functionName] = in_array( $this->attribute( 'type' ), $typeList ); 00388 } 00389 } 00390 } 00391 return $this->PolicyCache[$functionName]; 00392 } 00393 00394 static function fetchMaintainerRoleIDList( $packageType = false, $checkRoles = false ) 00395 { 00396 $allRoles = false; 00397 if ( $checkRoles ) 00398 { 00399 //include_once( "kernel/classes/datatypes/ezuser/ezuser.php" ); 00400 $currentUser = eZUser::currentUser(); 00401 $accessResult = $currentUser->hasAccessTo( 'package', 'create' ); 00402 $limitationList = array(); 00403 if ( $accessResult['accessWord'] == 'limited' ) 00404 { 00405 $allRoles = array(); 00406 $limitationList = $accessResult['policies']; 00407 foreach( $limitationList as $limitationArray ) 00408 { 00409 $allowedType = true; 00410 $allowedRoles = false; 00411 foreach ( $limitationArray as $key => $limitation ) 00412 { 00413 if ( $key == 'Role' ) 00414 { 00415 $allowedRoles = $limitation; 00416 } 00417 else if ( $key == 'Type' ) 00418 { 00419 $typeList = $limitation; 00420 if ( $packageType === false ) 00421 { 00422 $allowedType = in_array( $packageType, $typeList ); 00423 } 00424 } 00425 } 00426 if ( $allowedType and 00427 count( $allowedRoles ) > 0 ) 00428 { 00429 $allRoles = array_merge( $allRoles, $allowedRoles ); 00430 } 00431 } 00432 } 00433 } 00434 if ( is_array( $allRoles ) and count( $allRoles ) == 0 ) 00435 return array(); 00436 $ini = eZINI::instance( 'package.ini' ); 00437 $roleList = $ini->variable( 'MaintainerSettings', 'RoleList' ); 00438 if ( $allRoles !== false ) 00439 { 00440 $roleList = array_intersect( $roleList, $allRoles ); 00441 } 00442 return $roleList; 00443 } 00444 00445 static function fetchMaintainerRoleList( $packageType = false, $checkRoles = false ) 00446 { 00447 $roleList = eZPackage::fetchMaintainerRoleIDList( $packageType, $checkRoles ); 00448 $roleNameList = array(); 00449 foreach ( $roleList as $roleID ) 00450 { 00451 $roleName = eZPackage::maintainerRoleName( $roleID ); 00452 $roleNameList[] = array( 'name' => $roleName, 00453 'id' => $roleID ); 00454 } 00455 return $roleNameList; 00456 } 00457 00458 static function maintainerRoleListForRoles() 00459 { 00460 $ini = eZINI::instance( 'package.ini' ); 00461 $roleList = $ini->variable( 'MaintainerSettings', 'RoleList' ); 00462 $roleNameList = array(); 00463 foreach ( $roleList as $roleID ) 00464 { 00465 $roleName = eZPackage::maintainerRoleName( $roleID ); 00466 $roleNameList[] = array( 'name' => $roleName, 00467 'id' => $roleID ); 00468 } 00469 return $roleNameList; 00470 } 00471 00472 static function maintainerRoleName( $roleID ) 00473 { 00474 require_once "kernel/common/i18n.php"; 00475 $nameMap = array( 'lead' => ezi18n( 'kernel/package', 'Lead' ), 00476 'developer' => ezi18n( 'kernel/package', 'Developer' ), 00477 'designer' => ezi18n( 'kernel/package', 'Designer' ), 00478 'contributor' => ezi18n( 'kernel/package', 'Contributor' ), 00479 'tester' => ezi18n( 'kernel/package', 'Tester' ) ); 00480 if ( isset( $nameMap[$roleID] ) ) 00481 return $nameMap[$roleID]; 00482 return false; 00483 } 00484 00485 function appendMaintainer( $name, $email, $role = false ) 00486 { 00487 $this->Parameters['maintainers'][] = array( 'name' => $name, 00488 'email' => $email, 00489 'role' => $role ); 00490 } 00491 00492 function appendDocument( $name, $mimeType = false, $os = false, $audience = false, 00493 $create = false, $data = false ) 00494 { 00495 if ( !$mimeType ) 00496 $mimeType = 'text/plain'; 00497 $this->Parameters['documents'][] = array( 'name' => $name, 00498 'mime-type' => $mimeType, 00499 'os' => $os, 00500 // 'create-document' => $create, 00501 'data' => $data, 00502 'audience' => $audience ); 00503 if ( $create ) 00504 { 00505 eZFile::create( $name, $this->path() . '/' . eZPackage::documentDirectory(), 00506 $data ); 00507 } 00508 } 00509 00510 function appendGroup( $name ) 00511 { 00512 $index = count( $this->Parameters['groups'] ); 00513 $this->Parameters['groups'][$index] = array( 'name' => $name ); 00514 } 00515 00516 function appendChange( $person, $email, $changes, 00517 $release = false, $timestamp = null ) 00518 { 00519 if ( $timestamp === null ) 00520 $timestamp = time(); 00521 if ( !is_array( $changes ) ) 00522 $changes = array( $changes ); 00523 if ( !$release ) 00524 $release = $this->Parameters['release-number']; 00525 if ( !$release ) 00526 $release = 1; 00527 $this->Parameters['changelog'][] = array( 'timestamp' => $timestamp, 00528 'person' => $person, 00529 'email' => $email, 00530 'changes' => $changes, 00531 'release' => $release ); 00532 } 00533 00534 static function md5sum( $file ) 00535 { 00536 if ( function_exists( 'md5_file' ) ) 00537 { 00538 if ( file_exists( $file ) ) 00539 { 00540 return md5_file( $file ); 00541 } 00542 else 00543 { 00544 eZDebug::writeError( "Could not open file $file for md5sum calculation" ); 00545 } 00546 } 00547 else 00548 { 00549 $fd = @fopen( $file, 'rb' ); 00550 if ( $fd ) 00551 { 00552 $data = ''; 00553 while ( !@feof( $fd ) ) 00554 { 00555 $data .= @fread( $fd, 4096 ); 00556 } 00557 @fclose( $fd ); 00558 return md5( $data ); 00559 } 00560 } 00561 return false; 00562 } 00563 00564 function fileStorePath( $fileItem, $collectionName, $path = false, $installVariables = array() ) 00565 { 00566 $type = $fileItem['type']; 00567 $variableName = $fileItem['variable-name']; 00568 if ( $type == 'file' ) 00569 { 00570 $pathArray = array( $path, $fileItem['subdirectory'] ); 00571 $pathArray[] = $fileItem['name']; 00572 $path = eZDir::path( $pathArray ); 00573 } 00574 else if ( $type == 'design' ) 00575 { 00576 $roleFileName = false; 00577 $design = $fileItem['design']; 00578 switch ( $fileItem['role'] ) 00579 { 00580 case 'template': 00581 { 00582 $roleFileName = 'templates'; 00583 } break; 00584 case 'image': 00585 { 00586 $roleFileName = 'images'; 00587 } break; 00588 case 'stylesheet': 00589 { 00590 $roleFileName = 'stylesheets'; 00591 } break; 00592 case 'font': 00593 { 00594 $roleFileName = 'fonts'; 00595 } break; 00596 } 00597 if ( $variableName and 00598 isset( $installVariables[$variableName] ) ) 00599 $design = $installVariables[$variableName]; 00600 $pathArray = array( $path, 'design', $design, $roleFileName, $fileItem['subdirectory'] ); 00601 if ( $fileItem['file-type'] != 'dir' ) 00602 $pathArray[] = $fileItem['name']; 00603 $path = eZDir::path( $pathArray ); 00604 } 00605 else if ( $type == 'ini' ) 00606 { 00607 $roleValue = false; 00608 $roleFileName = false; 00609 switch ( $fileItem['role'] ) 00610 { 00611 case 'override': 00612 { 00613 $roleFileName = 'override'; 00614 } break; 00615 case 'siteaccess': 00616 { 00617 $roleFileName = 'siteaccess'; 00618 $roleValue = $fileItem['role-value']; 00619 if ( $variableName and 00620 isset( $installVariables[$variableName] ) ) 00621 $roleValue = $installVariables[$variableName]; 00622 } break; 00623 case 'standard': 00624 default: 00625 { 00626 $roleFileName = ''; 00627 } break; 00628 } 00629 $pathArray = array( $path, 'settings', $roleFileName, $roleValue, $fileItem['subdirectory'] ); 00630 if ( $fileItem['file-type'] != 'dir' ) 00631 $pathArray[] = $fileItem['name']; 00632 $path = eZDir::path( $pathArray ); 00633 } 00634 return $path; 00635 } 00636 00637 function fileItemPath( $fileItem, $collectionName, $path = false ) 00638 { 00639 if ( !$path ) 00640 { 00641 $repositoryInformation = $this->currentRepositoryInformation(); 00642 $path = $repositoryInformation['path']; 00643 } 00644 $typeDir = $fileItem['type']; 00645 if ( $fileItem['type'] == 'design' ) 00646 $typeDir .= '.' . $fileItem['design']; 00647 if ( isset( $fileItem['role'] ) && $fileItem['role'] ) 00648 { 00649 $typeDir .= '.' . $fileItem['role']; 00650 if ( $fileItem['role-value'] ) 00651 $typeDir .= '-' . $fileItem['role-value']; 00652 } 00653 $path .= '/' . $this->attribute( 'name' ) . '/' . eZPackage::filesDirectory() . '/' . $collectionName . '/' . $typeDir; 00654 if ( isset( $fileItem['subdirectory'] ) && $fileItem['subdirectory'] ) 00655 $path .= '/' . $fileItem['subdirectory']; 00656 $path .= '/' . $fileItem['name']; 00657 return $path; 00658 } 00659 00660 function fileList( $collectionName ) 00661 { 00662 $fileCollections = $this->Parameters['file-list']; 00663 if ( isset( $fileCollections[$collectionName] ) ) 00664 return $fileCollections[$collectionName]; 00665 return false; 00666 } 00667 00668 function thumbnailList( $collectionName ) 00669 { 00670 $thumbnails = array(); 00671 $fileList = $this->fileList( $collectionName ); 00672 if ( !is_array( $fileList ) ) 00673 return $thumbnails; 00674 00675 foreach ( $fileList as $fileItem ) 00676 { 00677 if ( $fileItem['type'] == 'thumbnail' ) 00678 { 00679 $thumbnails[] = $fileItem; 00680 } 00681 } 00682 return $thumbnails; 00683 } 00684 00685 function fileCount() 00686 { 00687 $count = 0; 00688 foreach ( $this->Parameters['file-list'] as $collection ) 00689 { 00690 $count += count( $collection ); 00691 } 00692 return $count; 00693 } 00694 00695 function appendFile( $file, $type, $role, 00696 $design, $filePath, $collection, 00697 $subDirectory = null, $md5 = null, 00698 $copyFile = false, $modified = null, $fileType = false, 00699 $roleValue = false, $variableName = false, 00700 $packagePath = false ) 00701 { 00702 if ( !$collection ) 00703 $collection = 'default'; 00704 if ( $subDirectory === null ) 00705 { 00706 $subDirectory = false; 00707 if ( preg_match( '#^(.+)/([^/]+)$#', $file, $matches ) ) 00708 { 00709 $subDirectory = $matches[1]; 00710 $file = $matches[2]; 00711 } 00712 } 00713 if ( $packagePath ) 00714 $subDirectory = $packagePath; 00715 00716 $fileItem = array( 'name' => $file, 00717 'subdirectory' => $subDirectory, 00718 'type' => $type, 00719 'role' => $role, 00720 'role-value' => $roleValue, 00721 'variable-name' => $variableName, 00722 'path' => $filePath, 00723 'file-type' => $fileType, 00724 'design' => $design ); 00725 if ( $md5 === null ) 00726 { 00727 $md5 = $this->md5sum( $filePath ); 00728 } 00729 $fileItem['md5'] = $md5; 00730 $this->Parameters['file-list'][$collection][] = $fileItem; 00731 00732 if ( $copyFile ) 00733 { 00734 // copying file 00735 $typeDir = $type; 00736 if ( $type == 'design' ) 00737 $typeDir .= '.' . $fileItem['design']; 00738 if ( $role ) 00739 { 00740 $typeDir .= '.' . $role; 00741 if ( $roleValue ) 00742 $typeDir .= '-' . $roleValue; 00743 } 00744 $path = $this->path() . '/' . eZPackage::filesDirectory() . '/' . $collection . '/' . $typeDir; 00745 if ( $subDirectory ) 00746 $path .= '/' . $subDirectory; 00747 if ( !file_exists( $path ) ) 00748 eZDir::mkdir( $path, false, true ); 00749 00750 if ( is_dir( $fileItem['path'] ) ) 00751 { 00752 eZDir::copy( $fileItem['path'], $path, 00753 $fileItem['name'] != false, true, false, eZDir::temporaryFileRegexp() ); 00754 } 00755 else 00756 { 00757 eZFileHandler::copy( $fileItem['path'], $path . '/' . $fileItem['name'] ); 00758 } 00759 } 00760 } 00761 00762 /*! 00763 Appends a new \c provides dependency. 00764 \note This function is only a convenience function to the general appendDependency() function. 00765 */ 00766 function appendProvides( $type, $name, $value, $parameters = false ) 00767 { 00768 $dependencyParameters = array( 'type' => $type, 00769 'name' => $name, 00770 'value' => $value ); 00771 00772 if ( $parameters !== false ) 00773 $dependencyParameters = array_merge( $dependencyParameters, $parameters ); 00774 00775 $this->appendDependency( 'provides', $dependencyParameters ); 00776 } 00777 00778 /*! 00779 Appends a new dependency item to the section \a $dependencySection. 00780 \param $dependencySection Can be one of \c provides, \c requires, \c obsoletes, \c conflicts 00781 \param $parameters A list of data specific to the dependency type. 00782 */ 00783 function appendDependency( $dependencySection, $parameters ) 00784 { 00785 if ( !in_array( $dependencySection, 00786 array( 'provides', 'requires', 00787 'obsoletes', 'conflicts' ) ) ) 00788 return false; 00789 00790 $this->Parameters['dependencies'][$dependencySection][] = $parameters; 00791 } 00792 00793 function dependencyOperatorText( $dependencyItem ) 00794 { 00795 return '='; 00796 } 00797 00798 function createDependencyText( $cli, $dependencyItem, $dependencySection ) 00799 { 00800 $text = ( $cli->stylize( 'emphasize', $dependencyItem['type'] ) . 00801 '(' . 00802 $cli->stylize( 'emphasize', $dependencyItem['name'] ) . 00803 ')' ); 00804 if ( $dependencyItem['value'] ) 00805 $text .= ' ' . $this->dependencyOperatorText( $dependencyItem ) .' ' . $cli->stylize( 'symbol', $dependencyItem['value'] ); 00806 $handler = $this->packageHandler( $dependencyItem['type'] ); 00807 if ( $handler ) 00808 { 00809 $specialText = $handler->createDependencyText( $this, $dependencyItem, $dependencySection ); 00810 if ( $specialText ) 00811 $text .= ' ( ' . $specialText . ' ) '; 00812 } 00813 return $text; 00814 } 00815 00816 function groupDependencyItemsByType( $dependencyItems ) 00817 { 00818 $types = array(); 00819 foreach ( $dependencyItems as $dependencyItem ) 00820 { 00821 if ( !isset( $types[$dependencyItem['type']] ) ) 00822 $types[$dependencyItem['type']] = array(); 00823 $types[$dependencyItem['type']][] = $dependencyItem; 00824 } 00825 return $types; 00826 } 00827 00828 /*! 00829 \return an array with dependency items which match the specified criterias. 00830 */ 00831 function dependencyItems( $dependencySection, $parameters = false ) 00832 { 00833 if ( !in_array( $dependencySection, 00834 array( 'provides', 'requires', 00835 'obsoletes', 'conflicts' ) ) ) 00836 return false; 00837 00838 if ( $parameters === false ) 00839 { 00840 return $this->Parameters['dependencies'][$dependencySection]; 00841 } 00842 00843 $matches = array(); 00844 $dependencyItems = $this->Parameters['dependencies'][$dependencySection]; 00845 foreach ( $dependencyItems as $dependencyItem ) 00846 { 00847 $found = true; 00848 00849 foreach ( $parameters as $paramName => $paramValue ) 00850 { 00851 if ( !isset( $dependencyItem[$paramName] ) || 00852 $dependencyItem[$paramName] != $paramValue ) 00853 { 00854 $found = false; 00855 break; 00856 } 00857 } 00858 00859 if ( $found ) 00860 $matches[] = $dependencyItem; 00861 } 00862 00863 return $matches; 00864 } 00865 00866 /*! 00867 \return an array with install items which match the specified criterias. 00868 */ 00869 function installItemsList( $type = false, $os = false, $name = false, $isInstall = true ) 00870 { 00871 $installName = 'install'; 00872 if ( !$isInstall ) 00873 $installName = 'uninstall'; 00874 if ( !$name and !$type and !$os ) 00875 { 00876 return $this->Parameters[$installName]; 00877 } 00878 else 00879 { 00880 $matches = array(); 00881 $installItems = $this->Parameters[$installName]; 00882 foreach ( $installItems as $installItem ) 00883 { 00884 $found = false; 00885 if ( $name and $installItem['name'] == $name ) 00886 $found = true; 00887 if ( !$found and $type and $installItem['type'] == $type ) 00888 $found = true; 00889 if ( !$found ) 00890 { 00891 if ( $os ) 00892 { 00893 if ( !$installItem['os'] ) 00894 $found = true; 00895 else if ( $os and $installItem['os'] == $os ) 00896 $found = true; 00897 } 00898 else 00899 $found = true; 00900 } 00901 if ( $found ) 00902 $matches[] = $installItem; 00903 } 00904 return $matches; 00905 } 00906 } 00907 00908 function appendInstall( $type, $name, $os = false, $isInstall = true, 00909 $filename = false, $subdirectory = false, 00910 $parameters = false ) 00911 { 00912 $installEntry = $parameters; 00913 $installEntry['type'] = $type; 00914 $installEntry['name'] = $name; 00915 $installEntry['os'] = $os; 00916 $installEntry['filename'] = $filename; 00917 $installEntry['sub-directory'] = $subdirectory; 00918 if ( $installEntry['filename'] ) 00919 { 00920 $content = false; 00921 if ( isset( $installEntry['content'] ) ) 00922 $content = $installEntry['content']; 00923 if ( $content instanceof DOMElement ) 00924 { 00925 $path = $this->path(); 00926 if ( $installEntry['sub-directory'] ) 00927 { 00928 $path .= '/' . $installEntry['sub-directory']; 00929 } 00930 $filePath = $path . '/' . $installEntry['filename'] . '.xml'; 00931 if ( !file_exists( $path ) ) 00932 { 00933 eZDir::mkdir( $path, false, true ); 00934 } 00935 $partDOM = new DOMDocument( '1.0', 'utf-8' ); 00936 $partDOM->formatOutput = true; 00937 $contentImport = $partDOM->importNode( $content, true ); 00938 $partDOM->appendChild( $contentImport ); 00939 $this->storeDOM( $filePath, $partDOM ); 00940 $installEntry['content'] = false; 00941 } 00942 } 00943 $installName = 'install'; 00944 if ( !$isInstall ) 00945 $installName = 'uninstall'; 00946 $this->Parameters[$installName][] = $installEntry; 00947 } 00948 00949 /*! 00950 Sets the packager of this release. 00951 */ 00952 function setPackager( $timestamp = false, $host = false, $packager = false ) 00953 { 00954 if ( $timestamp ) 00955 $this->Parameters['packaging']['timestamp'] = $timestamp; 00956 if ( $host ) 00957 $this->Parameters['packaging']['host'] = $host; 00958 if ( $packager ) 00959 $this->Parameters['packaging']['packager'] = $packager; 00960 } 00961 00962 /*! 00963 Sets various release information. If the value is set to \c false it is not updated. 00964 \param $version The version number, eg. 1.0, 2.3.5 00965 \param $release The release number, usually starts at 1 and increments for updates on the same version 00966 \param $timestamp The timestamp of the release 00967 \param $licence The licence of the package, eg. GPL, LGPL etc. 00968 \param $state The sate of the release, e.g alpha, beta, stable etc. 00969 */ 00970 function setRelease( $version = false, $release = false, $timestamp = false, 00971 $licence = false, $state = false ) 00972 { 00973 if ( $version !== false ) 00974 { 00975 $this->Parameters['version-number'] = $version; 00976 } 00977 if ( $release !== false ) 00978 { 00979 $this->Parameters['release-number'] = $release; 00980 } 00981 if ( $timestamp !== false ) 00982 { 00983 $this->Parameters['release-timestamp'] = $timestamp; 00984 } 00985 if ( $licence !== false ) 00986 { 00987 $this->Parameters['licence'] = $licence; 00988 } 00989 if ( $state !== false ) 00990 { 00991 $this->Parameters['state'] = $state; 00992 } 00993 } 00994 00995 /*! 00996 \private 00997 \return the package as a string, the string is in xml format. 00998 */ 00999 function toString() 01000 { 01001 $dom = $this->domStructure(); 01002 $string = $dom->saveXML(); 01003 return $string; 01004 } 01005 01006 /*! 01007 \private 01008 Stores a cached version of the package in the cache directory 01009 under the repository for the package. 01010 */ 01011 function storeCache( $directory = false ) 01012 { 01013 if ( !file_exists( $directory ) ) 01014 eZDir::mkdir( $directory, false, true ); 01015 //include_once( 'lib/ezutils/classes/ezphpcreator.php' ); 01016 $php = new eZPHPCreator( $directory, 'package.php' ); 01017 $php->addComment( "Automatically created cache file for the package format\n" . 01018 "Do not modify this file" ); 01019 $php->addSpace(); 01020 $php->addVariable( 'CacheCodeDate', eZPackage::CACHE_CODE_DATE ); 01021 $php->addSpace(); 01022 $php->addVariable( 'Parameters', $this->Parameters, eZPHPCreator::VARIABLE_ASSIGNMENT, 01023 array( 'full-tree' => true ) ); 01024 $php->addVariable( 'InstallData', $this->InstallData, eZPHPCreator::VARIABLE_ASSIGNMENT, 01025 array( 'full-tree' => true ) ); 01026 $php->addVariable( 'RepositoryPath', $this->RepositoryPath ); 01027 $php->store(); 01028 } 01029 01030 /*! 01031 Stores the current package in the repository. 01032 */ 01033 function store() 01034 { 01035 $path = $this->path(); 01036 return $this->storePackageFile( $path ); 01037 } 01038 01039 /*! 01040 Stores the current package definition file to the directory \a $path. 01041 */ 01042 function storePackageFile( $path, $storeCache = true ) 01043 { 01044 if ( !file_exists( $path ) ) 01045 { 01046 eZDir::mkdir( $path, false, true ); 01047 } 01048 $filePath = $path . '/' . eZPackage::definitionFilename(); 01049 01050 $packageFileString = $this->toString(); 01051 $result = $this->storeString( $filePath, $packageFileString ); 01052 01053 if ( $storeCache ) 01054 $this->storeCache( $path . '/' . $this->cacheDirectory() ); 01055 return $result; 01056 } 01057 01058 /*! 01059 Recursively deletes \a $path 01060 */ 01061 static function removeFiles( $path ) 01062 { 01063 if ( file_exists( $path ) ) 01064 { 01065 eZDir::recursiveDelete( $path ); 01066 } 01067 } 01068 01069 /*! 01070 Exports the package as a gzip compressed tarball to the directory \a $archivePath 01071 */ 01072 function exportToArchive( $archivePath ) 01073 { 01074 $tempPath = eZPackage::temporaryExportPath() . '/' . $this->attribute( 'name' ); 01075 $this->removeFiles( $tempPath ); 01076 01077 // Create package temp dir and copy package's XML file there 01078 $this->storePackageFile( $tempPath, false ); 01079 01080 // Copy package's directories 01081 $directoryList = array( $this->documentDirectory(), 01082 $this->filesDirectory(), 01083 $this->simpleFilesDirectory(), 01084 $this->settingsDirectory() ); 01085 $installItems = $this->Parameters['install']; 01086 foreach( $installItems as $installItem ) 01087 { 01088 if ( !in_array( $installItem['sub-directory'], $directoryList ) ) 01089 $directoryList[] = $installItem['sub-directory']; 01090 } 01091 01092 $path = $this->path(); 01093 foreach( $directoryList as $dirName ) 01094 { 01095 $destDir = $tempPath; 01096 $dir = $path . '/' . $dirName; 01097 if ( file_exists( $dir ) ) 01098 eZDir::copy( $dir, $destDir ); 01099 } 01100 01101 //include_once( 'lib/ezfile/classes/ezarchivehandler.php' ); 01102 01103 $archive = eZArchiveHandler::instance( 'tar', 'gzip', $archivePath ); 01104 01105 $packageBaseDirectory = $tempPath; 01106 $fileList = array(); 01107 $fileList[] = $packageBaseDirectory; 01108 01109 $archive->createModify( $fileList, '', $packageBaseDirectory ); 01110 01111 $this->removeFiles( $tempPath ); 01112 return $archivePath; 01113 } 01114 01115 /*! 01116 Imports a package from a gzip compressed tarball file \a $archiveName 01117 */ 01118 static function import( $archiveName, &$packageName, $dbAvailable = true, $repositoryID = false ) 01119 { 01120 if ( is_dir( $archiveName ) ) 01121 { 01122 eZDebug::writeError( "Importing from directory is not supported." ); 01123 $retValue = false; 01124 return $retValue; 01125 } 01126 else 01127 { 01128 $tempDirPath = eZPackage::temporaryImportPath(); 01129 // make a temporary directory to extract the package file to 01130 do 01131 { 01132 $archivePath = eZDir::path( array( $tempDirPath, mt_rand() ) ); 01133 } while ( file_exists( $archivePath ) ); 01134 01135 eZDir::mkdir( $archivePath, false, true ); 01136 01137 eZPackage::removeFiles( $archivePath ); 01138 if ( !file_exists( $archivePath ) ) 01139 { 01140 eZDir::mkdir( $archivePath, false, true ); 01141 } 01142 //include_once( 'lib/ezfile/classes/ezarchivehandler.php' ); 01143 01144 $archive = eZArchiveHandler::instance( 'tar', 'gzip', $archiveName ); 01145 $fileList = array(); 01146 $fileList[] = eZPackage::definitionFilename(); 01147 if ( !$archive->extractList( $fileList, $archivePath, '' ) ) 01148 { 01149 eZDebug::writeError( "Failed extracting package definition file from $archivePath" ); 01150 $retValue = false; 01151 return $retValue; 01152 } 01153 01154 $definitionFileName = eZDir::path( array( $archivePath, self::definitionFilename() ) ); 01155 01156 $package = eZPackage::fetchFromFile( $definitionFileName ); 01157 01158 eZPackage::removeFiles( $archivePath ); 01159 01160 if ( $package ) 01161 { 01162 $packageName = $package->attribute( 'name' ); 01163 01164 if ( !self::isValidName( $packageName ) ) 01165 { 01166 return eZPackage::STATUS_INVALID_NAME; 01167 } 01168 01169 if ( !$repositoryID ) 01170 { 01171 $repositoryID = $package->attribute( 'vendor-dir' ); 01172 } 01173 01174 $existingPackage = eZPackage::fetch( $packageName, false, false, $dbAvailable ); 01175 if ( $existingPackage ) 01176 { 01177 return eZPackage::STATUS_ALREADY_EXISTS; 01178 } 01179 unset( $archive ); 01180 unset( $package ); 01181 01182 $fullRepositoryPath = eZPackage::repositoryPath() . '/' . $repositoryID; 01183 $packagePath = $fullRepositoryPath . '/' . $packageName; 01184 if ( !file_exists( $packagePath ) ) 01185 { 01186 eZDir::mkdir( $packagePath, false, true ); 01187 } 01188 $archive = eZArchiveHandler::instance( 'tar', 'gzip', $archiveName ); 01189 $archive->extractModify( $packagePath, '' ); 01190 01191 $package = eZPackage::fetch( $packageName, $fullRepositoryPath, false, $dbAvailable ); 01192 if ( !$package ) 01193 { 01194 eZDebug::writeError( "Failed loading imported package $packageName from $fullRepositoryPath" ); 01195 } 01196 } 01197 else 01198 { 01199 eZDebug::writeError( "Failed loading temporary package $packageName" ); 01200 } 01201 01202 return $package; 01203 } 01204 } 01205 01206 /*! 01207 \static 01208 \return the suffix for all package files. 01209 */ 01210 static function suffix() 01211 { 01212 return 'ezpkg'; 01213 } 01214 01215 /*! 01216 \return the file name for an exported archive of the current package 01217 */ 01218 function exportName() 01219 { 01220 return $this->attribute( 'name' ) . '-' . $this->attribute( 'version-number' ) . '-' . $this->attribute( 'release-number' ) . '.' . eZPackage::suffix(); 01221 } 01222 01223 /*! 01224 Stores the current package to the file \a $filename. 01225 */ 01226 function storeToFile( $filename ) 01227 { 01228 $dom = $this->domStructure(); 01229 return eZPackage::storeDOM( $filename, $dom ); 01230 } 01231 01232 /*! 01233 Applies the storage file permissions specified in site.ini to the file \a $filename 01234 */ 01235 static function applyStorageFilePermissions( $filename ) 01236 { 01237 $siteConfig = eZINI::instance( 'site.ini' ); 01238 $filePermissions = $siteConfig->variable( 'FileSettings', 'StorageFilePermissions'); 01239 chmod( $filename, octdec( $filePermissions ) ); 01240 } 01241 01242 /*! 01243 Stores the DOM tree \a $dom to the file \a $filename. 01244 */ 01245 static function storeDOM( $filename, $dom ) 01246 { 01247 $bytes = $dom->save( $filename ); 01248 01249 if ( $bytes !== false ) 01250 { 01251 eZPackage::applyStorageFilePermissions( $filename ); 01252 01253 eZDebugSetting::writeNotice( 'kernel-ezpackage-store', 01254 "Stored file $filename", 01255 'eZPackage::storeDOM' ); 01256 return true; 01257 } 01258 else 01259 { 01260 eZDebug::writeError( "Saving DOM tree to $filename failed", 'eZPackage::storeDOM' ); 01261 } 01262 01263 return false; 01264 } 01265 01266 /*! 01267 \private 01268 \static 01269 Stores the string data \a $data into the file \a $filename. 01270 \return \c true if successful. 01271 */ 01272 static function storeString( $filename, $data ) 01273 { 01274 $file = @fopen( $filename, 'w' ); 01275 if ( $file ) 01276 { 01277 fwrite( $file, $data ); 01278 fclose( $file ); 01279 01280 eZPackage::applyStorageFilePermissions( $filename ); 01281 01282 eZDebugSetting::writeNotice( 'kernel-ezpackage-store', 01283 "Stored file $filename", 01284 'eZPackage::storeString' ); 01285 return true; 01286 } 01287 else 01288 { 01289 eZDebug::writeError( "Failed to write package '$filename'" ); 01290 } 01291 return false; 01292 } 01293 01294 01295 /*! 01296 \private 01297 Loads the contents of the file \a $filename and parses it into a DOM tree. 01298 The DOM tree is returned. 01299 */ 01300 static function fetchDOMFromFile( $filename ) 01301 { 01302 if ( file_exists( $filename ) ) 01303 { 01304 $dom = new DOMDocument( '1.0', 'utf-8' ); 01305 $dom->preserveWhiteSpace = false; 01306 $success = $dom->load( $filename ); 01307 01308 if ( !$success ) 01309 { 01310 return false; 01311 } 01312 else 01313 { 01314 return $dom; 01315 } 01316 } 01317 return false; 01318 } 01319 01320 /*! 01321 \static 01322 Tries to load the package definition from file \a $filename 01323 and create a package object from it. 01324 \return \c false if it could be fetched. 01325 */ 01326 static function fetchFromFile( $filename ) 01327 { 01328 $dom = eZPackage::fetchDOMFromFile( $filename ); 01329 01330 if ( $dom === false ) 01331 { 01332 return false; 01333 } 01334 01335 $package = new eZPackage(); 01336 $parameters = $package->parseDOMTree( $dom ); 01337 if ( !$parameters ) 01338 { 01339 return false; 01340 } 01341 01342 return $package; 01343 } 01344 01345 /*! 01346 \static 01347 Tries to load the package named \a $packageName from the repository 01348 and returns the package object. 01349 \param $repositoryID Determines in which repositories the package should be searched for, 01350 if set to \c true it means only look in local packages, \c false means 01351 look in all repositories. 01352 \param $dbAvailable Do we have a database to fetch additional package info, like installed state. 01353 (false in setup wizard) 01354 \return \c false if no package could be found. 01355 */ 01356 static function fetch( $packageName, $packagePath = false, $repositoryID = false, $dbAvailable = true ) 01357 { 01358 $packageRepositories = eZPackage::packageRepositories( array( 'path' => $packagePath ) ); 01359 01360 if ( $repositoryID === true ) 01361 $repositoryID = 'local'; 01362 01363 foreach ( $packageRepositories as $packageRepository ) 01364 { 01365 if ( $repositoryID !== false and 01366 $packageRepository['id'] != $repositoryID ) 01367 continue; 01368 $path = $packageRepository['path']; 01369 01370 $path .= '/' . $packageName; 01371 $filePath = $path . '/' . eZPackage::definitionFilename(); 01372 01373 if ( file_exists( $filePath ) ) 01374 { 01375 $fileModification = filemtime( $filePath ); 01376 $package = false; 01377 $cacheExpired = false; 01378 01379 if ( eZPackage::useCache() ) 01380 { 01381 $package = eZPackage::fetchFromCache( $path, $fileModification, $cacheExpired ); 01382 } 01383 01384 if ( $package ) 01385 { 01386 $package->setCurrentRepositoryInformation( $packageRepository ); 01387 } 01388 else 01389 { 01390 $package = eZPackage::fetchFromFile( $filePath ); 01391 01392 if ( $package ) 01393 { 01394 $package->setCurrentRepositoryInformation( $packageRepository ); 01395 if ( $packagePath ) 01396 $package->RepositoryPath = $packagePath; 01397 if ( $cacheExpired and 01398 eZPackage::useCache() ) 01399 { 01400 $package->storeCache( $path . '/' . eZPackage::cacheDirectory() ); 01401 } 01402 } 01403 } 01404 if ( $dbAvailable ) 01405 $package->getInstallState(); 01406 01407 return $package; 01408 } 01409 } 01410 return false; 01411 } 01412 01413 static function useCache() 01414 { 01415 return eZPackage::USE_CACHE; 01416 } 01417 01418 /*! 01419 \private 01420 */ 01421 static function fetchFromCache( $packagePath, $packageModification, &$cacheExpired ) 01422 { 01423 $packageCachePath = $packagePath . '/' . eZPackage::cacheDirectory() . '/package.php'; 01424 01425 if ( file_exists( $packageCachePath ) ) 01426 { 01427 $cacheModification = filemtime( $packageCachePath ); 01428 if ( $cacheModification >= $packageModification ) 01429 { 01430 include( $packageCachePath ); 01431 if ( !isset( $CacheCodeDate ) or 01432 $CacheCodeDate != eZPackage::CACHE_CODE_DATE ) 01433 { 01434 $cacheExpired = true; 01435 return false; 01436 } 01437 if ( isset( $Parameters ) and 01438 isset( $InstallData ) ) 01439 { 01440 $cacheExpired = false; 01441 $package = new eZPackage( $Parameters, $RepositoryPath ); 01442 $package->InstallData = $InstallData; 01443 return $package; 01444 } 01445 } 01446 else 01447 $cacheExpired = true; 01448 } 01449 $cacheExpired = true; 01450 return false; 01451 } 01452 01453 /*! 01454 \return the full path to this package. 01455 */ 01456 function path() 01457 { 01458 $path = $this->currentRepositoryPath(); 01459 $path .= '/' . $this->attribute( 'name' ); 01460 return $path; 01461 } 01462 01463 /*! 01464 \return the path to the current repository. 01465 */ 01466 function currentRepositoryPath() 01467 { 01468 $repositoryInformation = $this->currentRepositoryInformation(); 01469 if ( $repositoryInformation ) 01470 return $repositoryInformation['path']; 01471 return $this->RepositoryPath; 01472 } 01473 01474 /*! 01475 \static 01476 \return the directory name for temporary export packages, used in conjunction with eZSys::cacheDirectory(). 01477 */ 01478 static function temporaryExportPath() 01479 { 01480 $path = eZDir::path( array( eZSys::cacheDirectory(), 01481 'packages', 01482 'export' . eZUser::currentUserID() ) ); 01483 return $path; 01484 } 01485 01486 /*! 01487 \static 01488 \return the directory name for temporary import packages, used in conjunction with eZSys::cacheDirectory(). 01489 */ 01490 static function temporaryImportPath() 01491 { 01492 $path = eZDir::path( array( eZSys::cacheDirectory(), 01493 'packages', 01494 'import' ) ); 01495 return $path; 01496 } 01497 01498 /*! 01499 \static 01500 \return the path to the package repository. 01501 */ 01502 static function repositoryPath() 01503 { 01504 $ini = eZINI::instance(); 01505 $packageIni = eZINI::instance( 'package.ini' ); 01506 01507 return eZDir::path( array( 'var', 01508 $ini->variable( 'FileSettings', 'StorageDir' ), 01509 $packageIni->variable( 'RepositorySettings', 'RepositoryDirectory' ) ) ); 01510 } 01511 01512 /*! 01513 \static 01514 \return the name of the cache directory for cached package data. 01515 */ 01516 static function cacheDirectory() 01517 { 01518 return '.cache'; 01519 } 01520 01521 /*! 01522 \static 01523 \return the name of the package definition file. 01524 */ 01525 static function definitionFilename() 01526 { 01527 return 'package.xml'; 01528 } 01529 01530 /*! 01531 \static 01532 \return the name of the documents directory for cached package data. 01533 */ 01534 static function documentDirectory() 01535 { 01536 return 'documents'; 01537 } 01538 01539 /*! 01540 \static 01541 \return the name of the documents directory for cached package data. 01542 */ 01543 static function filesDirectory() 01544 { 01545 return 'files'; 01546 } 01547 01548 /*! 01549 \private 01550 Get local simple file path 01551 */ 01552 static function simpleFilesDirectory() 01553 { 01554 return 'simplefiles'; 01555 } 01556 01557 static function settingsDirectory() 01558 { 01559 return 'settings'; 01560 } 01561 01562 /*! 01563 Locates all dependent packages in the repository and returns an array with eZPackage objects. 01564 \param $dependencyType is the name of a dependency sub-node. (ie. 'provides', 'requires' etc...) 01565 */ 01566 function fetchDependentPackages( $dependencyType, &$failedList ) 01567 { 01568 $packages = array(); 01569 $provides = $this->Parameters['dependencies'][$dependencyType]; 01570 01571 if ( $provides != null ) 01572 { 01573 foreach ( $provides as $provide ) 01574 { 01575 // fetch only dependent packages, not package items. 01576 if ( $provide['type'] == 'ezpackage' ) 01577 { 01578 // TODO: Add fetching from URL (not here ?) 01579 $package = $this->fetch( $provide['name'] ); 01580 01581 if ( !$package ) 01582 { 01583 $failedList[] = $provide['name']; 01584 continue; 01585 } 01586 $packages[] =& $package; 01587 } 01588 } 01589 } 01590 return $packages; 01591 } 01592 01593 /*! 01594 \static 01595 \return an array with repositories which can contain packages. 01596 01597 Each repository entry is an array with the following keys. 01598 - path The path to the repository relative from the eZ Publish installation 01599 - id Unique identifier for this repository 01600 - name Human readable string identifying this repository, the name is translatable 01601 - type What kind of repository, currently supports local or global. 01602 */ 01603 static function packageRepositories( $parameters = array() ) 01604 { 01605 require_once "kernel/common/i18n.php"; 01606 if ( isset( $parameters['path'] ) and $parameters['path'] ) 01607 { 01608 $path = $parameters['path']; 01609 $packageRepositories = array( array( 'path' => $path, 01610 'id' => 'local', 01611 'name' => ezi18n( 'kernel/package', 'Local' ), 01612 'type' => 'local' ) ); 01613 } 01614 else 01615 { 01616 $repositoryPath = eZPackage::repositoryPath(); 01617 $packageRepositories = array( array( 'path' => $repositoryPath . '/local', 01618 'id' => 'local', 01619 'name' => ezi18n( 'kernel/package', 'Local' ), 01620 'type' => 'local' ) ); 01621 01622 $subdirs = eZDir::findSubitems( $repositoryPath, 'd' ); 01623 foreach( $subdirs as $dir ) 01624 { 01625 if ( $dir == 'local' ) 01626 continue; 01627 01628 $packageRepositories[] = array( 'path' => $repositoryPath . '/' . $dir, 01629 'id' => $dir, 01630 'name' => $dir, 01631 'type' => 'global' ); 01632 } 01633 } 01634 return $packageRepositories; 01635 } 01636 01637 /*! 01638 \static 01639 \return information on the repository with ID $repositoryID or \c false if does not exist. 01640 */ 01641 static function repositoryInformation( $repositoryID ) 01642 { 01643 $packageRepositories = eZPackage::packageRepositories(); 01644 foreach ( $packageRepositories as $packageRepository ) 01645 { 01646 if ( $packageRepository['id'] == $repositoryID ) 01647 return $packageRepository; 01648 } 01649 return false; 01650 } 01651 01652 /*! 01653 Sets the current repository information for the package. 01654 \sa currentRepositoryInformation, packageRepositories 01655 */ 01656 function setCurrentRepositoryInformation( $information ) 01657 { 01658 $this->RepositoryInformation = $information; 01659 } 01660 01661 /*! 01662 \return the current repository information for the package, this 01663 will contain information of where the package was found. 01664 See packageRepositories too see what the information will contain. 01665 \note The return information can be \c null in some cases when the package is not properly initialized. 01666 */ 01667 function currentRepositoryInformation() 01668 { 01669 return $this->RepositoryInformation; 01670 } 01671 01672 /*! 01673 Locates all packages in the repository and returns an array with eZPackage objects. 01674 01675 \param parameters 01676 \param filterArray 01677 */ 01678 static function fetchPackages( $parameters = array(), $filterArray = array() ) 01679 { 01680 $packageRepositories = eZPackage::packageRepositories( $parameters ); 01681 01682 $packages = array(); 01683 01684 $requiredType = null; 01685 $requiredPriority = null; 01686 $requiredVendor = null; 01687 $requiredExtension = null; 01688 if ( isset( $filterArray['type'] ) ) 01689 $requiredType = $filterArray['type']; 01690 if ( isset( $filterArray['priority'] ) ) 01691 $requiredPriority = $filterArray['priority']; 01692 if ( isset( $filterArray['vendor'] ) ) 01693 $requiredVendor = $filterArray['vendor']; 01694 if ( isset( $filterArray['extension'] ) ) 01695 $requiredExtension = $filterArray['extension']; 01696 $repositoryID = false; 01697 if ( isset( $parameters['repository_id'] ) ) 01698 $repositoryID = $parameters['repository_id']; 01699 $dbAvailable = true; 01700 if ( isset( $parameters['db_available'] ) ) 01701 $dbAvailable = $parameters['db_available']; 01702 01703 foreach ( $packageRepositories as $packageRepository ) 01704 { 01705 if ( strlen( $repositoryID ) == 0 or 01706 $repositoryID == $packageRepository['id'] ) 01707 { 01708 $path = $packageRepository['path']; 01709 if ( file_exists( $path ) ) 01710 { 01711 $fileList = array(); 01712 $dir = opendir( $path ); 01713 while( ( $file = readdir( $dir ) ) !== false ) 01714 { 01715 if ( $file == '.' or 01716 $file == '..' ) 01717 continue; 01718 $fileList[] = $file; 01719 } 01720 closedir( $dir ); 01721 sort( $fileList ); 01722 foreach ( $fileList as $file ) 01723 { 01724 $dirPath = $path . '/' . $file; 01725 if ( !is_dir( $dirPath ) ) 01726 continue; 01727 $filePath = $dirPath . '/' . eZPackage::definitionFilename(); 01728 if ( file_exists( $filePath ) ) 01729 { 01730 $fileModification = filemtime( $filePath ); 01731 $name = $file; 01732 $packageCachePath = $dirPath . '/' . eZPackage::cacheDirectory() . '/package.php'; 01733 unset( $package ); 01734 $package = false; 01735 $cacheExpired = false; 01736 if ( eZPackage::useCache() ) 01737 { 01738 $package = eZPackage::fetchFromCache( $dirPath, $fileModification, $cacheExpired ); 01739 } 01740 if ( !$package ) 01741 { 01742 $package = eZPackage::fetchFromFile( $filePath ); 01743 if ( $package and 01744 $cacheExpired and 01745 eZPackage::useCache() ) 01746 { 01747 $package->storeCache( $dirPath . '/' . eZPackage::cacheDirectory() ); 01748 } 01749 } 01750 if ( !$package ) 01751 continue; 01752 01753 if ( $dbAvailable ) 01754 $package->getInstallState(); 01755 01756 if ( $requiredType !== null ) 01757 { 01758 $type = $package->attribute( 'type' ); 01759 if ( $type != $requiredType ) 01760 continue; 01761 } 01762 01763 if ( $requiredPriority !== null ) 01764 { 01765 $type = $package->attribute( 'priority' ); 01766 if ( $priority != $requiredPriority ) 01767 continue; 01768 } 01769 01770 if ( $requiredExtension !== null ) 01771 { 01772 $type = $package->attribute( 'extension' ); 01773 if ( $extension != $requiredExtension ) 01774 continue; 01775 } 01776 01777 if ( $requiredVendor !== null ) 01778 { 01779 $type = $package->attribute( 'vendor' ); 01780 if ( $vendor != $requiredVendor ) 01781 continue; 01782 } 01783 01784 $package->setCurrentRepositoryInformation( $packageRepository ); 01785 01786 $packages[] =& $package; 01787 } 01788 } 01789 } 01790 } 01791 } 01792 return $packages; 01793 } 01794 01795 /*! 01796 Install specified install item in package 01797 01798 \param Item index 01799 \param parameters 01800 */ 01801 function installItem( $item, &$installParameters ) 01802 { 01803 $type = $item['type']; 01804 $name = $item['name']; 01805 $os = $item['os']; 01806 $filename = $item['filename']; 01807 $subdirectory = $item['sub-directory']; 01808 $content = false; 01809 if ( isset( $item['content'] ) ) 01810 $content = $item['content']; 01811 $handler = $this->packageHandler( $type ); 01812 $installResult = false; 01813 if ( $handler ) 01814 { 01815 if ( $handler->extractInstallContent() ) 01816 { 01817 if ( !$content and 01818 $filename ) 01819 { 01820 if ( $subdirectory ) 01821 $filepath = $subdirectory . '/' . $filename . '.xml'; 01822 else 01823 $filepath = $filename . '.xml'; 01824 01825 $filepath = $this->path() . '/' . $filepath; 01826 01827 $dom = eZPackage::fetchDOMFromFile( $filepath ); 01828 if ( $dom ) 01829 { 01830 $content = $dom->documentElement; 01831 } 01832 else 01833 { 01834 eZDebug::writeError( "Failed fetching dom from file $filepath", 'eZPackage::installItem' ); 01835 } 01836 } 01837 } 01838 $installData =& $this->InstallData[$type]; 01839 if ( !isset( $installData ) ) 01840 $installData = array(); 01841 $installResult = $handler->install( $this, $type, $item, 01842 $name, $os, $filename, $subdirectory, 01843 $content, $installParameters, 01844 $installData ); 01845 } 01846 return $installResult; 01847 } 01848 01849 /*! 01850 Install all install items in package 01851 */ 01852 function install( &$installParameters ) 01853 { 01854 if ( $this->Parameters['install_type'] != 'install' ) 01855 return; 01856 $installItems = $this->Parameters['install']; 01857 if ( !isset( $installParameters['path'] ) ) 01858 $installParameters['path'] = false; 01859 $installResult = true; 01860 foreach ( $installItems as $item ) 01861 { 01862 if ( !$this->installItem( $item, $installParameters ) ) 01863 { 01864 eZDebug::writeDebug( $item, 'item which failed installing' ); 01865 $installResult = false; 01866 } 01867 } 01868 $this->setInstalled(); 01869 return $installResult; 01870 } 01871 01872 function uninstallItem( $item, &$uninstallParameters ) 01873 { 01874 $type = $item['type']; 01875 $name = $item['name']; 01876 $os = $item['os']; 01877 $filename = $item['filename']; 01878 $subdirectory = $item['sub-directory']; 01879 $content = false; 01880 if ( isset( $item['content'] ) ) 01881 $content = $item['content']; 01882 01883 $handler = $this->packageHandler( $type ); 01884 if ( $handler ) 01885 { 01886 if ( $handler->extractInstallContent() ) 01887 { 01888 if ( !$content and 01889 $filename ) 01890 { 01891 if ( $subdirectory ) 01892 $filepath = $subdirectory . '/' . $filename . '.xml'; 01893 else 01894 $filepath = $filename . '.xml'; 01895 01896 $filepath = $this->path() . '/' . $filepath; 01897 01898 $dom = eZPackage::fetchDOMFromFile( $filepath ); 01899 if ( $dom ) 01900 { 01901 $content = $dom->documentElement; 01902 } 01903 else 01904 { 01905 eZDebug::writeError( "Failed fetching dom from file $filepath", 'eZPackage::uninstallItem' ); 01906 } 01907 } 01908 } 01909 01910 if ( isset( $this->InstallData[$type] ) ) 01911 { 01912 $installData =& $this->InstallData[$type]; 01913 } 01914 else 01915 { 01916 unset( $installData ); 01917 $installData = array(); 01918 } 01919 $uninstallResult = $handler->uninstall( $this, $type, $item, 01920 $name, $os, $filename, $subdirectory, 01921 $content, $uninstallParameters, 01922 $installData ); 01923 } 01924 return $uninstallResult; 01925 } 01926 01927 /*! 01928 Install all install items in package 01929 */ 01930 function uninstall( $uninstallParameters = array() ) 01931 { 01932 if ( $this->Parameters['install_type'] != 'install' ) 01933 return; 01934 if ( !$this->isInstalled() ) 01935 return; 01936 $uninstallItems = $this->uninstallItemsList(); 01937 if ( !isset( $installParameters['path'] ) ) 01938 $installParameters['path'] = false; 01939 01940 $uninstallResult = true; 01941 foreach ( $uninstallItems as $item ) 01942 { 01943 if ( !$this->uninstallItem( $item, $uninstallParameters ) ) 01944 { 01945 $uninstallResult = false; 01946 } 01947 } 01948 01949 $this->InstallData = array(); 01950 $this->setInstalled( false ); 01951 return $uninstallResult; 01952 } 01953 01954 /*! 01955 \private 01956 */ 01957 function parseDOMTree( DOMDocument $dom ) 01958 { 01959 $root = $dom->documentElement; 01960 01961 // Read basic info 01962 $parameters = array(); 01963 $parameters['name'] = $root->getElementsByTagName( 'name' )->item( 0 )->textContent; 01964 $vendorNode = $root->getElementsByTagName( 'vendor' )->item( 0 ); 01965 $parameters['vendor'] = is_object( $vendorNode ) ? $vendorNode->textContent : false; 01966 $parameters['summary'] = $root->getElementsByTagName( 'summary' )->item( 0 )->textContent; 01967 $parameters['description'] = $root->getElementsByTagName( 'description' )->item( 0 )->textContent; 01968 $priorities = $root->getElementsByTagName( 'priority' ); 01969 if ( $priorities->length > 0 ) 01970 { 01971 $parameters['priority'] = $priorities->item( 0 )->getAttribute( 'value' ); 01972 } 01973 $parameters['type'] = $root->getElementsByTagName( 'type' )->item( 0 )->getAttribute( 'value' ); 01974 01975 if ( $parameters['vendor'] ) 01976 { 01977 // Creating nice vendor directory name 01978 //include_once( 'lib/ezi18n/classes/ezchartransform.php' ); 01979 $trans = eZCharTransform::instance(); 01980 $parameters['vendor-dir'] = $trans->transformByGroup( $parameters['vendor'], 'urlalias' ); 01981 } 01982 else 01983 { 01984 $parameters['vendor-dir'] = 'local'; 01985 } 01986 01987 $parameters['install_type'] = 'install'; 01988 $installType = $root->getAttribute( 'install_type' ); 01989 if ( $installType ) 01990 $parameters['install_type'] = $installType; 01991 $sourceNodes = $root->getElementsByTagName( 'source' ); 01992 if ( $sourceNodes->length > 0 ) 01993 { 01994 $parameters['source'] = $sourceNodes->item( 0 )->textContent; 01995 } 01996 $parameters['development'] = $root->getAttribute( 'development' ) == 'true'; 01997 $extensionNode = $root->getElementsByTagName( 'extension' )->item( 0 ); 01998 if ( $extensionNode ) 01999 $parameters['extension'] = $extensionNode->getAttribute( 'name' ); 02000 $ezpublishNode = $root->getElementsByTagName( 'ezpublish' )->item( 0 ); 02001 $parameters['ezpublish']['version'] = $ezpublishNode->getElementsByTagName( 'version' )->item( 0 )->textContent; 02002 $parameters['ezpublish']['named-version'] = $ezpublishNode->getElementsByTagName( 'named-version' )->item( 0 )->textContent; 02003 $this->setParameters( $parameters ); 02004 02005 // Read maintainers 02006 $maintainersNode = $root->getElementsByTagName( 'maintainers' )->item( 0 ); 02007 if ( $maintainersNode ) 02008 { 02009 $maintainerNodes = $maintainersNode->getElementsByTagName( 'maintainer' ); 02010 foreach ( $maintainerNodes as $maintainerNode ) 02011 { 02012 $maintainerName = $maintainerNode->getElementsByTagName( 'name' )->item( 0 )->textContent; 02013 $maintainerEmail = $maintainerNode->getElementsByTagName( 'email' )->item( 0 )->textContent; 02014 $maintainerRole = $maintainerNode->getElementsByTagName( 'role' )->item( 0 )->textContent; 02015 $this->appendMaintainer( $maintainerName, $maintainerEmail, $maintainerRole ); 02016 } 02017 } 02018 02019 // Read packaging info 02020 $packagingNode = $root->getElementsByTagName( 'packaging' )->item( 0 ); 02021 $packagingTimestamp = $packagingNode->getElementsByTagName( 'timestamp' )->item( 0 )->textContent; 02022 $packagingHost = $packagingNode->getElementsByTagName( 'host' )->item( 0 )->textContent; 02023 $packagerNodes = $packagingNode->getElementsByTagName( 'packager' ); 02024 if ( $packagerNodes->length > 0 ) 02025 { 02026 $packagingPackager = $packagerNodes->item( 0 )->textContent; 02027 } 02028 else 02029 { 02030 $packagingPackager = false; 02031 } 02032 $this->setPackager( $packagingTimestamp, $packagingHost, $packagingPackager ); 02033 02034 // Read documents 02035 $documentsNode = $root->getElementsByTagName( 'documents' )->item( 0 ); 02036 $documentNodes = $documentsNode->getElementsByTagName( 'document' ); 02037 02038 foreach ( $documentNodes as $documentNode ) 02039 { 02040 $documentName = $documentNode->getAttribute( 'name' ); 02041 $documentMimeType = $documentNode->getAttribute( 'mime-type' ); 02042 $documentOS = $documentNode->getAttribute( 'os' ); 02043 $documentAudience = $documentNode->getAttribute( 'audience' ); 02044 $this->appendDocument( $documentName, $documentMimeType, 02045 $documentOS, $documentAudience, 02046 false, false ); 02047 } 02048 02049 // Read changelog 02050 $changelogNode = $root->getElementsByTagName( 'changelog' )->item( 0 ); 02051 if ( $changelogNode ) 02052 { 02053 $changelogEntryNodes = $changelogNode->getElementsByTagName( 'entry' ); 02054 foreach ( $changelogEntryNodes as $changelogEntryNode ) 02055 { 02056 $changelogTimestamp = $changelogEntryNode->getAttribute( 'timestamp' ); 02057 $changelogPerson = $changelogEntryNode->getAttribute( 'person' ); 02058 $changelogEmail = $changelogEntryNode->getAttribute( 'email' ); 02059 $changelogRelease = $changelogEntryNode->getAttribute( 'release' ); 02060 $changelogChangeList = $changelogEntryNode->getElementsByTagName( 'change' )->item( 0 )->textContent; 02061 $this->appendChange( $changelogPerson, $changelogEmail, $changelogChangeList, 02062 $changelogRelease, $changelogTimestamp ); 02063 } 02064 } 02065 02066 // Read simple files 02067 $this->Parameters['simple-file-list'] = array(); 02068 $simpleFilesNode = $root->getElementsByTagName( 'simple-files' )->item( 0 ); 02069 if ( $simpleFilesNode && $simpleFilesNode->hasChildNodes() ) 02070 { 02071 $simpleFileNodes = $simpleFilesNode->getElementsByTagName( 'simple-file' ); 02072 foreach ( $simpleFileNodes as $simpleFileNode ) 02073 { 02074 $key = $simpleFileNode->getAttribute( 'key' ); 02075 $originalPath = $simpleFileNode->getAttribute( 'original-path' ); 02076 $packagePath = $simpleFileNode->getAttribute( 'package-path' ); 02077 $this->Parameters['simple-file-list'][$key] = array( 'original-path' => $originalPath, 02078 'package-path' => $packagePath ); 02079 } 02080 } 02081 02082 // Read files 02083 $filesList = $root->getElementsByTagName( 'files' ); 02084 if ( $filesList ) 02085 { 02086 foreach ( $filesList as $fileCollectionNode ) 02087 { 02088 $fileCollectionName = $fileCollectionNode->getAttribute( 'name' ); 02089 $fileLists = $fileCollectionNode->getElementsByTagName( 'file-list' ); 02090 foreach ( $fileLists as $fileListNode ) 02091 { 02092 $fileType = $fileListNode->getAttribute( 'type' ); 02093 $fileDesign = $fileListNode->getAttribute( 'design' ); 02094 $fileRole = $fileListNode->getAttribute( 'role' ); 02095 $fileVariableName = $fileListNode->getAttribute( 'variable-name' ); 02096 $fileRoleValue = $fileListNode->getAttribute( 'role-value' ); 02097 $files = $fileListNode->getElementsByTagName( 'file' ); 02098 if ( count( $files ) > 0 ) 02099 { 02100 foreach ( $files as $fileNode ) 02101 { 02102 $fileFileType = $fileNode->getAttribute( 'type' ); 02103 $fileName = $fileNode->getAttribute( 'name' ); 02104 if ( $fileNode->getAttribute( 'variable-name' ) ) 02105 $fileVariableName = $fileNode->getAttribute( 'variable-name' ); 02106 $fileSubDirectory = $fileNode->getAttribute( 'sub-directory' ); 02107 $filePath = $fileNode->getAttribute( 'path' ); 02108 $fileMD5 = $fileNode->getAttribute( 'md5sum' ); 02109 $this->appendFile( $fileName, $fileType, $fileRole, 02110 $fileDesign, $filePath, $fileCollectionName, 02111 $fileSubDirectory, $fileMD5, false, null, 02112 $fileFileType, 02113 $fileRoleValue, $fileVariableName ); 02114 } 02115 } 02116 else 02117 { 02118 $this->appendFile( false, $fileType, $fileRole, 02119 $fileDesign, false, $fileCollectionName, 02120 false, false, false, null ); 02121 } 02122 unset( $files ); 02123 } 02124 } 02125 } 02126 // Read release info 02127 $xpath = new DOMXPath( $dom ); 02128 $versionNode = $xpath->query( 'version' )->item( 0 ); 02129 $versionNumber = false; 02130 $versionRelease = false; 02131 if ( $versionNode ) 02132 { 02133 $versionNumber = $versionNode->getElementsByTagName( 'number' )->item( 0 )->textContent; 02134 $versionRelease = $versionNode->getElementsByTagName( 'release' )->item( 0 )->textContent; 02135 } 02136 $licence = $root->getElementsByTagName( 'licence' )->item( 0 )->textContent; 02137 $state = $root->getElementsByTagName( 'state' )->item( 0 )->textContent; 02138 $this->setRelease( $versionNumber, $versionRelease, false, 02139 $licence, $state ); 02140 02141 $dependenciesNode = $root->getElementsByTagName( 'dependencies' )->item( 0 ); 02142 if ( $dependenciesNode ) 02143 { 02144 $providesNode = $dependenciesNode->getElementsByTagName( 'provides' )->item( 0 ); 02145 $providesList = $providesNode->getElementsByTagName( 'provide' ); 02146 $requiresNode = $dependenciesNode->getElementsByTagName( 'requires' )->item( 0 ); 02147 $requiresList = $requiresNode->getElementsByTagName( 'require' ); 02148 $obsoletesNode = $dependenciesNode->getElementsByTagName( 'obsoletes' )->item( 0 ); 02149 $obsoletesList = $obsoletesNode->getElementsByTagName( 'obsolete' ); 02150 $conflictsNode = $dependenciesNode->getElementsByTagName( 'conflicts' )->item( 0 ); 02151 $conflictsList = $conflictsNode->getElementsByTagName( 'conflict' ); 02152 $this->parseDependencyTree( $providesList, 'provides' ); 02153 $this->parseDependencyTree( $requiresList, 'requires' ); 02154 $this->parseDependencyTree( $obsoletesList, 'obsoletes' ); 02155 $this->parseDependencyTree( $conflictsList, 'conflicts' ); 02156 } 02157 02158 $settingsNode = $root->getElementsByTagName( 'settings' )->item( 0 ); 02159 02160 if ( $settingsNode ) 02161 { 02162 $settingsFileNodes = $settingsNode->getElementsByTagName( 'settings-file' ); 02163 $this->Parameters['settings-files'] = array(); 02164 02165 foreach( $settingsFileNodes as $settingsFileNode ) 02166 { 02167 $this->Parameters['settings-files'][] = $settingsFileNode->getAttribute( 'filename' ); 02168 } 02169 } 02170 02171 $installNode = $root->getElementsByTagName( 'install' )->item( 0 ); 02172 $installList = $installNode->getElementsByTagName( 'item' ); 02173 $uninstallNode = $root->getElementsByTagName( 'uninstall' )->item( 0 ); 02174 $uninstallList = $uninstallNode->getElementsByTagName( 'item' ); 02175 $this->parseInstallTree( $installList, true ); 02176 $this->parseInstallTree( $uninstallList, false ); 02177 02178 $installDataList = $root->getElementsByTagName( 'install-data' ); 02179 if ( $installDataList ) 02180 { 02181 $this->InstallData = array(); 02182 foreach( $installDataList as $installDataNode ) 02183 { 02184 if ( is_object( $installDataNode ) && 02185 $installDataNode->getAttribute( 'name' ) == 'data' ) 02186 { 02187 $installDataType = $installDataNode->getAttribute( 'type' ); 02188 $installDataElements = $installDataNode->getElementsByTagName( 'data' ); 02189 $installData = array(); 02190 foreach ( $installDataElements as $installDataElement ) 02191 { 02192 if ( $installDataElement->attribute( 'name' ) == 'element' ) 02193 { 02194 $name = $installDataElement->getAttribute( 'name' ); 02195 $value = $installDataElement->getAttribute( 'value' ); 02196 $installData[$name] = $value; 02197 } 02198 else if ( $installDataElement->attribute( 'name' ) == 'array' ) 02199 { 02200 $arrayName = $installDataElement->getAttribute( 'name' ); 02201 $installDataElementArray = $installDataElement->childNodes; 02202 $array = array(); 02203 foreach ( $installDataElementArray as $installDataElementArrayElement ) 02204 { 02205 $name = $installDataElementArrayElement->getAttribute( 'name' ); 02206 $value = $installDataElementArrayElement->getAttribute( 'value' ); 02207 $array[$name] = $value; 02208 } 02209 $installData[$arrayName] = $array; 02210 } 02211 } 02212 if ( count( $installData ) > 0 ) 02213 $this->InstallData[$installDataType] = $installData; 02214 } 02215 } 02216 } 02217 02218 $retValue = true; 02219 return $retValue; 02220 } 02221 02222 /*! 02223 \private 02224 */ 02225 function parseDependencyTree( $dependenciesList, $dependencySection ) 02226 { 02227 foreach ( $dependenciesList as $dependencyNode ) 02228 { 02229 $dependencyType = $dependencyNode->getAttribute( 'type' ); 02230 $dependencyAttributes = $dependencyNode->attributes; 02231 $dependencyParameters = array(); 02232 for ( $i = 0; $i < $dependencyAttributes->length; $i++ ) 02233 { 02234 $dependencyAttribute = $dependencyAttributes->item( $i ); 02235 $dependencyParameters[$dependencyAttribute->name] = $dependencyAttribute->value; 02236 } 02237 02238 $additionalDependencyParameters = array(); 02239 $handler = $this->packageHandler( $dependencyType ); 02240 if ( $handler ) 02241 { 02242 $handler->parseDependencyNode( $this, $dependencyNode, $additionalDependencyParameters, $dependencySection ); 02243 } 02244 02245 if ( count( $additionalDependencyParameters ) > 0 ) 02246 $dependencyParameters = array_merge( $dependencyParameters, $additionalDependencyParameters ); 02247 02248 $this->appendDependency( $dependencySection, $dependencyParameters ); 02249 } 02250 } 02251 02252 /*! 02253 \private 02254 */ 02255 function parseInstallTree( $installList, $isInstall ) 02256 { 02257 foreach( $installList as $installNode ) 02258 { 02259 $installType = $installNode->getAttribute( 'type' ); 02260 $installName = $installNode->getAttribute( 'name' ); 02261 $installFilename = $installNode->getAttribute( 'filename' ); 02262 $installSubdirectory = $installNode->getAttribute( 'sub-directory' ); 02263 $installOS = $installNode->getAttribute( 'os' ); 02264 02265 $handler = $this->packageHandler( $installType ); 02266 $installParameters = array(); 02267 if ( $handler ) 02268 { 02269 $handler->parseInstallNode( $this, $installNode, $installParameters, $isInstall ); 02270 } 02271 if ( count( $installParameters ) == 0 ) 02272 $installParameters = false; 02273 02274 $this->appendInstall( $installType, $installName, $installOS, $isInstall, 02275 $installFilename, $installSubdirectory, 02276 $installParameters ); 02277 } 02278 } 02279 02280 /*! 02281 \return the dom document of the package. 02282 */ 02283 function &domStructure() 02284 { 02285 $dom = new DOMDocument( '1.0', 'utf-8' ); 02286 $dom->formatOutput = true; 02287 $root = $dom->createElement( 'package' ); 02288 $root->setAttribute( 'version', eZPackage::VERSION ); 02289 $root->setAttribute( 'development', ( eZPackage::DEVELOPMENT ? 'true' : 'false' ) ); 02290 $dom->appendChild( $root ); 02291 02292 if ( eZPackage::DEVELOPMENT ) 02293 { 02294 $warningText = "This format was made with a development version and will not work with any release versions.\n" . 02295 "The format of this file is also subject to change until the release version.\n" . 02296 "Upgrades to the development format will not be supported."; 02297 02298 $warningNode = $dom->createElement( 'warning' ); 02299 $warningNode->appendChild( $dom->createTextNode( $warningText ) ); 02300 $root->appendChild( $warningNode ); 02301 } 02302 02303 $name = $this->attribute( 'name' ); 02304 $summary = $this->attribute( 'summary' ); 02305 $description = $this->attribute( 'description' ); 02306 $priority = $this->attribute( 'priority' ); 02307 $type = $this->attribute( 'type' ); 02308 $extension = $this->attribute( 'extension' ); 02309 $installType = $this->attribute( 'install_type' ); 02310 $vendorName = $this->attribute( 'vendor' ); 02311 $source = $this->attribute( 'source' ); 02312 02313 $ezpublishVersion = $this->attribute( 'ezpublish-version' ); 02314 $ezpublishNamedVersion = $this->attribute( 'ezpublish-named-version' ); 02315 02316 $packagingTimestamp = $this->attribute( 'packaging-timestamp' ); 02317 $packagingHost = $this->attribute( 'packaging-host' ); 02318 $packagingPackager = $this->attribute( 'packaging-packager' ); 02319 02320 $maintainers = $this->attribute( 'maintainers' ); 02321 $documents = $this->attribute( 'documents' ); 02322 $groups = $this->attribute( 'groups' ); 02323 02324 $versionNumber = $this->attribute( 'version-number' ); 02325 $releaseNumber = $this->attribute( 'release-number' ); 02326 $releaseTimestamp = $this->attribute( 'release-timestamp' ); 02327 02328 $licence = $this->attribute( 'licence' ); 02329 $state = $this->attribute( 'state' ); 02330 02331 $simpleFileList = $this->attribute( 'simple-file-list' ); 02332 $fileList = $this->attribute( 'file-list' ); 02333 $dependencies = $this->attribute( 'dependencies' ); 02334 $install = $this->attribute( 'install' ); 02335 $uninstall = $this->attribute( 'uninstall' ); 02336 $changelog = $this->attribute( 'changelog' ); 02337 02338 $rootNameTextNode = $dom->createElement( 'name' ); 02339 $rootNameTextNode->appendChild( $dom->createTextNode( $name ) ); 02340 $root->appendChild( $rootNameTextNode ); 02341 02342 if ( $summary ) 02343 { 02344 $rootSummaryTextNode = $dom->createElement( 'summary' ); 02345 $rootSummaryTextNode->appendChild( $dom->createTextNode( $summary ) ); 02346 $root->appendChild( $rootSummaryTextNode ); 02347 } 02348 02349 if ( $description ) 02350 { 02351 $rootDescriptionTextNode = $dom->createElement( 'description' ); 02352 $rootDescriptionTextNode->appendChild( $dom->createTextNode( $description ) ); 02353 $root->appendChild( $rootDescriptionTextNode ); 02354 } 02355 02356 if ( $vendorName ) 02357 { 02358 $rootVendorTextNode = $dom->createElement( 'vendor' ); 02359 $rootVendorTextNode->appendChild( $dom->createTextNode( $vendorName ) ); 02360 $root->appendChild( $rootVendorTextNode ); 02361 } 02362 02363 if ( $priority ) 02364 { 02365 $rootPriorityTextNode = $dom->createElement( 'priority' ); 02366 $rootPriorityTextNode->setAttribute( 'value', $priority ); 02367 $root->appendChild( $rootPriorityTextNode ); 02368 } 02369 02370 if ( $type ) 02371 { 02372 $rootTypeTextNode = $dom->createElement( 'type' ); 02373 $rootTypeTextNode->setAttribute( 'value', $type ); 02374 $root->appendChild( $rootTypeTextNode ); 02375 } 02376 02377 if ( $extension ) 02378 { 02379 $rootExtensionTextNode = $dom->createElement( 'extension' ); 02380 $rootExtensionTextNode->setAttribute( 'name', $extension ); 02381 $root->appendChild( $rootExtensionTextNode ); 02382 } 02383 02384 if ( $source ) 02385 { 02386 $rootSourceTextNode = $dom->createElement( 'source' ); 02387 $rootSourceTextNode->appendChild( $dom->createTextNode( $source ) ); 02388 $root->appendChild( $rootSourceTextNode ); 02389 } 02390 02391 $root->setAttribute( 'install_type', $installType ); 02392 02393 $ezpublishNode = $dom->createElement( 'ezpublish' ); 02394 02395 $ezpublishVersionTextNode = $dom->createElement( 'version' ); 02396 $ezpublishVersionTextNode->appendChild( $dom->createTextNode( $ezpublishVersion ) ); 02397 $ezpublishNode->appendChild( $ezpublishVersionTextNode ); 02398 02399 $ezpublishNamedVersionTextNode = $dom->createElement( 'named-version' ); 02400 $ezpublishNamedVersionTextNode->appendChild( $dom->createTextNode( $ezpublishNamedVersion ) ); 02401 $ezpublishNode->appendChild( $ezpublishNamedVersionTextNode ); 02402 02403 $root->appendChild( $ezpublishNode ); 02404 02405 if ( count( $maintainers ) > 0 ) 02406 { 02407 $maintainersNode = $dom->createElement( 'maintainers' ); 02408 foreach ( $maintainers as $maintainer ) 02409 { 02410 unset( $maintainerNode ); 02411 $maintainerNode = $dom->createElement( 'maintainer' ); 02412 02413 unset( $maintainerName ); 02414 $maintainerName = $dom->createElement( 'name' ); 02415 $maintainerName->appendChild( $dom->createTextNode( $maintainer['name'] ) ); 02416 $maintainerNode->appendChild( $maintainerName ); 02417 02418 unset( $maintainerEmail ); 02419 $maintainerEmail = $dom->createElement( 'email' ); 02420 $maintainerEmail->appendChild( $dom->createTextNode( $maintainer['email'] ) ); 02421 $maintainerNode->appendChild( $maintainerEmail ); 02422 if ( $maintainer['role'] ) 02423 { 02424 unset( $maintainerRole ); 02425 $maintainerRole = $dom->createElement( 'role' ); 02426 $maintainerRole->appendChild( $dom->createTextNode( $maintainer['role'] ) ); 02427 $maintainerNode->appendChild( $maintainerRole ); 02428 } 02429 02430 $maintainersNode->appendChild( $maintainerNode ); 02431 } 02432 $root->appendChild( $maintainersNode ); 02433 } 02434 02435 $packagingNode = $dom->createElement( 'packaging' ); 02436 02437 $packagingTimestampNode = $dom->createElement( 'timestamp' ); 02438 $packagingTimestampNode->appendChild( $dom->createTextNode( $packagingTimestamp ) ); 02439 $packagingNode->appendChild( $packagingTimestampNode ); 02440 02441 $packagingHostNode = $dom->createElement( 'host' ); 02442 $packagingHostNode->appendChild( $dom->createTextNode( $packagingHost ) ); 02443 $packagingNode->appendChild( $packagingHostNode ); 02444 if ( $packagingPackager ) 02445 { 02446 $packagingPackagerNode = $dom->createElement( 'packager' ); 02447 $packagingPackagerNode->appendChild( $dom->createTextNode( $packagingPackager ) ); 02448 $packagingNode->appendChild( $packagingPackagerNode ); 02449 } 02450 02451 $root->appendChild( $packagingNode ); 02452 02453 if ( count( $documents ) > 0 ) 02454 { 02455 $documentsNode = $dom->createElement( 'documents' ); 02456 foreach ( $documents as $document ) 02457 { 02458 unset( $documentNode ); 02459 $documentNode = $dom->createElement( 'document' ); 02460 $documentNode->setAttribute( 'mime-type', $document['mime-type'] ); 02461 $documentNode->setAttribute( 'name', $document['name'] ); 02462 if ( $document['os'] ) 02463 $documentNode->setAttribute( 'os', $document['os'] ); 02464 02465 if ( $document['audience'] ) 02466 $documentNode->setAttribute( 'audience', $document['audience'] ); 02467 02468 $documentsNode->appendChild( $documentNode ); 02469 } 02470 $root->appendChild( $documentsNode ); 02471 } 02472 02473 if ( count( $groups ) > 0 ) 02474 { 02475 $groupsNode = $dom->createElement( 'groups' ); 02476 foreach ( $groups as $group ) 02477 { 02478 unset( $groupNode ); 02479 $groupNode = $dom->createElement( 'group' ); 02480 $groupNode->setAttribute( 'name', $group['name'] ); 02481 $groupsNode->appendChild( $groupNode ); 02482 } 02483 $root->appendChild( $groupsNode ); 02484 } 02485 02486 if ( count( $changelog ) > 0 ) 02487 { 02488 $changelogNode = $dom->createElement( 'changelog' ); 02489 foreach ( $changelog as $changeEntry ) 02490 { 02491 unset( $changeEntryNode ); 02492 $changeEntryNode = $dom->createElement( 'entry' ); 02493 $changeEntryNode->setAttribute( 'timestamp', $changeEntry['timestamp'] ); 02494 $changeEntryNode->setAttribute( 'person', $changeEntry['person'] ); 02495 $changeEntryNode->setAttribute( 'email', $changeEntry['email'] ); 02496 $changeEntryNode->setAttribute( 'release', $changeEntry['release'] ); 02497 02498 foreach ( $changeEntry['changes'] as $change ) 02499 { 02500 unset( $changeEntryChange ); 02501 $changeEntryChange = $dom->createElement( 'change' ); 02502 $changeEntryChange->appendChild( $dom->createTextNode( $change ) ); 02503 $changeEntryNode->appendChild( $changeEntryChange ); 02504 } 02505 $changelogNode->appendChild( $changeEntryNode ); 02506 } 02507 $root->appendChild( $changelogNode ); 02508 } 02509 02510 // Avoid a PHP warning if 'simple-file-list' is not an array 02511 if ( is_array( $this->Parameters['simple-file-list'] ) ) 02512 { 02513 $rootSimpleFiles = $dom->createElement( 'simple-files' ); 02514 foreach( $this->Parameters['simple-file-list'] as $key => $value ) 02515 { 02516 $simpleFileNode = $dom->createElement( 'simple-file' ); 02517 $simpleFileNode->setAttribute( 'key', $key ); 02518 $simpleFileNode->setAttribute( 'original-path', $value['original-path'] ); 02519 $simpleFileNode->setAttribute( 'package-path', $value['package-path'] ); 02520 $rootSimpleFiles->appendChild( $simpleFileNode ); 02521 unset( $simpleFileNode ); 02522 } 02523 $root->appendChild( $rootSimpleFiles ); 02524 } 02525 else 02526 { 02527 $rootSimpleFiles = $dom->createElement( 'simple-files' ); 02528 $root->appendChild( $rootSimpleFiles ); 02529 } 02530 02531 // Handle files 02532 $filesNode = $dom->createElement( 'files' ); 02533 02534 $hasFileItems = false; 02535 foreach ( $fileList as $fileCollectionName => $fileCollection ) 02536 { 02537 if ( count( $fileCollection ) > 0 ) 02538 { 02539 $hasFileItems = true; 02540 02541 unset( $fileCollectionNode ); 02542 $fileCollectionNode = $dom->createElement( 'collection' ); 02543 $fileCollectionNode->setAttribute( 'name', $fileCollectionName ); 02544 02545 unset( $fileLists ); 02546 unset( $fileDesignLists ); 02547 unset( $fileThumbnailLists ); 02548 $fileList = array(); 02549 $fileDesignList = array(); 02550 $fileINIList = array(); 02551 $fileThumbnailList = array(); 02552 $fileListNode = null; 02553 foreach ( $fileCollection as $fileItem ) 02554 { 02555 if ( $fileItem['type'] == 'design' ) 02556 $fileListNode =& $fileDesignLists[$fileItem['design']][$fileItem['role']][$fileItem['role-value']][$fileItem['variable-name']]; 02557 else if ( $fileItem['type'] == 'ini' ) 02558 $fileListNode =& $fileINILists[$fileItem['role']][$fileItem['role-value']][$fileItem['variable-name']]; 02559 else if ( $fileItem['type'] == 'thumbnail' ) 02560 $fileListNode =& $fileThumbnailLists[$fileItem['role']]; 02561 else 02562 $fileListNode =& $fileLists[$fileItem['type']][$fileItem['role']][$fileItem['role-value']][$fileItem['variable-name']]; 02563 02564 if ( !$fileListNode || 02565 $fileListNode->getAttribute( 'type' ) != $fileItem['type'] || 02566 $fileListNode->getAttribute( 'role' ) != $fileItem['role'] || 02567 $fileListNode->getAttribute( 'role-value' ) != $fileItem['role-value'] || 02568 $fileListNode->getAttribute( 'variable-name' ) != $fileItem['variable-name'] ) 02569 { 02570 unset( $fileListNode ); 02571 $fileListNode = $dom->createElement( 'file-list' ); 02572 $fileListNode->setAttribute( 'type', $fileItem['type'] ); 02573 02574 if ( $fileItem['type'] == 'design' ) 02575 $fileListNode->setAttribute( 'design', $fileItem['design'] ); 02576 if ( $fileItem['role'] ) 02577 $fileListNode->setAttribute( 'role', $fileItem['role'] ); 02578 if ( $fileItem['role-value'] ) 02579 $fileListNode->setAttribute( 'role-value', $fileItem['role-value'] ); 02580 if ( $fileItem['variable-name'] ) 02581 $fileListNode->setAttribute( 'variable-name', $fileItem['variable-name'] ); 02582 02583 $fileCollectionNode->appendChild( $fileListNode ); 02584 } 02585 02586 if ( $fileItem['name'] ) 02587 { 02588 unset( $fileListFile ); 02589 $fileListFile = $dom->createElement( 'file' ); 02590 $fileListFile->setAttribute( 'path', $fileItem['path'] ); 02591 $fileListFile->setAttribute( 'name', $fileItem['name'] ); 02592 02593 if ( $fileItem['md5'] ) 02594 $fileListFile->setAttribute( 'md5sum', $fileItem['md5'] ); 02595 02596 if ( $fileItem['subdirectory'] ) 02597 $fileListFile->setAttribute( 'sub-directory', $fileItem['subdirectory'] ); 02598 02599 $fileListNode->appendChild( $fileListFile ); 02600 } 02601 } 02602 $filesNode->appendChild( $fileCollectionNode ); 02603 } 02604 } 02605 if ( $hasFileItems ) 02606 $root->appendChild( $filesNode ); 02607 02608 $versionNode = $dom->createElement( 'version' ); 02609 $versionNumberTextNode = $dom->createElement( 'number' ); 02610 $versionNumberTextNode->appendChild( $dom->createTextNode( $versionNumber ) ); 02611 $versionNode->appendChild( $versionNumberTextNode ); 02612 $versionReleaseNumberTextNode = $dom->createElement( 'release' ); 02613 $versionReleaseNumberTextNode->appendChild( $dom->createTextNode( $releaseNumber ) ); 02614 $versionNode->appendChild( $versionReleaseNumberTextNode ); 02615 $root->appendChild( $versionNode ); 02616 02617 if ( $releaseTimestamp ) 02618 { 02619 $rootTimestampTextNode = $dom->createElement( 'timestamp' ); 02620 $rootTimestampTextNode->appendChild( $dom->createTextNode( $releaseTimestamp ) ); 02621 $root->appendChild( $rootTimestampTextNode ); 02622 } 02623 02624 if ( $licence ) 02625 { 02626 $rootLicenceTextNode = $dom->createElement( 'licence' ); 02627 $rootLicenceTextNode->appendChild( $dom->createTextNode( $licence ) ); 02628 $root->appendChild( $rootLicenceTextNode ); 02629 } 02630 02631 if ( $state ) 02632 { 02633 $rootStateTextNode = $dom->createElement( 'state' ); 02634 $rootStateTextNode->appendChild( $dom->createTextNode( $state ) ); 02635 $root->appendChild( $rootStateTextNode ); 02636 } 02637 02638 $dependencyNode = $dom->createElement( 'dependencies' ); 02639 02640 $providesNode = $dom->createElement( 'provides' ); 02641 $dependencyNode->appendChild( $providesNode ); 02642 $requiresNode = $dom->createElement( 'requires' ); 02643 $dependencyNode->appendChild( $requiresNode ); 02644 $obsoletesNode = $dom->createElement( 'obsoletes' ); 02645 $dependencyNode->appendChild( $obsoletesNode ); 02646 $conflictsNode = $dom->createElement( 'conflicts' ); 02647 $dependencyNode->appendChild( $conflictsNode ); 02648 02649 $this->createDependencyTree( $providesNode, 'provide', $dependencies['provides'] ); 02650 $this->createDependencyTree( $requiresNode, 'require', $dependencies['requires'] ); 02651 $this->createDependencyTree( $obsoletesNode, 'obsolete', $dependencies['obsoletes'] ); 02652 $this->createDependencyTree( $conflictsNode, 'conflict', $dependencies['conflicts'] ); 02653 02654 $root->appendChild( $dependencyNode ); 02655 02656 $installNode = $dom->createElement( 'install' ); 02657 02658 $uninstallNode = $dom->createElement( 'uninstall' ); 02659 02660 $this->createInstallTree( $installNode, $dom, $install, 'install' ); 02661 $this->createInstallTree( $uninstallNode, $dom, $uninstall, 'uninstall' ); 02662 02663 $root->appendChild( $installNode ); 02664 $root->appendChild( $uninstallNode ); 02665 02666 if ( count( $this->InstallData ) > 0 ) 02667 { 02668 $installDataNode = $dom->createElement( 'install-data' ); 02669 foreach ( $this->InstallData as $installDataType => $installData ) 02670 { 02671 if ( count( $installData ) > 0 ) 02672 { 02673 unset( $dataNode ); 02674 $dataNode = $dom->createElement( 'data' ); 02675 $dataNode->setAttribute( 'type', $installDataType ); 02676 $installDataNode->appendChild( $dataNode ); 02677 foreach ( $installData as $installDataName => $installDataValue ) 02678 { 02679 if ( is_array( $installDataValue ) ) 02680 { 02681 unset( $dataArrayNode ); 02682 $dataArrayNode = $dom->createElement( 'array' ); 02683 $dataArrayNode->setAttribute( 'name', $installDataName ); 02684 $dataNode->appendChild( $dataArrayNode ); 02685 foreach ( $installDataValue as $installDataValueName => $installDataValueValue ) 02686 { 02687 unset( $dataArrayElement ); 02688 $dataArrayElement = $dom->createElement( 'element' ); 02689 $dataArrayElement->setAttribute( 'name', $installDataValueName ); 02690 $dataArrayElement->setAttribute( 'value', $installDataValueValue ); 02691 $dataArrayNode->appendChild( $dataArrayElement ); 02692 } 02693 } 02694 else 02695 { 02696 unset( $dataArrayElement ); 02697 $dataArrayElement = $dom->createElement( 'element' ); 02698 $dataArrayElement->setAttribute( 'name', $installDataName ); 02699 $dataArrayElement->setAttribute( 'value', $installDataValue ); 02700 $dataNode->appendChild( $dataArrayElement ); 02701 } 02702 } 02703 } 02704 } 02705 $root->appendChild( $installDataNode ); 02706 } 02707 02708 return $dom; 02709 } 02710 02711 /*! 02712 \private 02713 Creates xml elements as children of the main node \a $installNode. 02714 The install elements are taken from \a $list. 02715 \param $installType Is either \c 'install' or \c 'uninstall' 02716 */ 02717 function createInstallTree( $installNode, $dom, $list, $installType ) 02718 { 02719 foreach ( $list as $installItem ) 02720 { 02721 $type = $installItem['type']; 02722 unset( $installItemNode ); 02723 $installItemNode = $dom->createElement( 'item' ); 02724 $installItemNode->setAttribute( 'type', $type ); 02725 $installNode->appendChild( $installItemNode ); 02726 02727 if ( $installItem['os'] ) 02728 $installItemNode->setAttribute( 'os', $installIItem['os'] ); 02729 02730 if ( $installItem['name'] ) 02731 $installItemNode->setAttribute( 'name', $installIItem['name'] ); 02732 02733 if ( $installItem['filename'] ) 02734 { 02735 $installItemNode->setAttribute( 'filename', $installItem['filename'] ); 02736 02737 if ( $installItem['sub-directory'] ) 02738 $installItemNode->setAttribute( 'sub-directory', $installItem['sub-directory'] ); 02739 } 02740 else if ( isset( $installItem['content'] ) && $installItem['content'] instanceof DOMElement ) 02741 { 02742 $importedContentNode = $installItemNode->ownerDocument->importNode( $installItem['content'], true ); 02743 $installItemNode->appendChild( $importedContentNode ); 02744 } 02745 02746 $handler = $this->packageHandler( $type ); 02747 if ( $handler ) 02748 { 02749 $handler->createInstallNode( $this, $installItemNode, $installItem, $installType ); 02750 } 02751 } 02752 } 02753 02754 /*! 02755 Creates dependency xml elements as child of $dependenciesNode. 02756 The dependency elements are take from \a $list. 02757 \param $dependencyType Is either \c 'provide', \c 'require', \c 'obsolete' or \c 'conflict' 02758 */ 02759 function createDependencyTree( &$dependenciesNode, $dependencyType, $list ) 02760 { 02761 $dom = $dependenciesNode->ownerDocument; 02762 02763 foreach ( $list as $dependencyItem ) 02764 { 02765 unset( $dependencyNode ); 02766 $dependencyNode = $dom->createElement( $dependencyType ); 02767 $dependencyNode->setAttribute( 'type', $dependencyItem['type'] ); 02768 $dependencyNode->setAttribute( 'name', $dependencyItem['name'] ); 02769 if ( $dependencyItem['value'] ) 02770 $dependencyNode->setAttribute( 'value', $dependencyItem['value'] ); 02771 $dependenciesNode->appendChild( $dependencyNode ); 02772 $handler = $this->packageHandler( $dependencyItem['name'] ); 02773 if ( $handler ) 02774 { 02775 $handler->createDependencyNode( $this, $dependencyNode, $dependencyItem, $dependencyType ); 02776 } 02777 } 02778 } 02779 02780 /*! 02781 \return the package handler object for the handler named \a $handlerName. 02782 */ 02783 static function packageHandler( $handlerName ) 02784 { 02785 if ( !isset( $GLOBALS['eZPackageHandlers'] ) ) 02786 { 02787 $handlers = array(); 02788 } 02789 else 02790 { 02791 $handlers = $GLOBALS['eZPackageHandlers']; 02792 } 02793 $handler = false; 02794 if ( eZExtension::findExtensionType( array( 'ini-name' => 'package.ini', 02795 'repository-group' => 'PackageSettings', 02796 'repository-variable' => 'RepositoryDirectories', 02797 'extension-group' => 'PackageSettings', 02798 'extension-variable' => 'ExtensionDirectories', 02799 'subdir' => 'packagehandlers', 02800 'extension-subdir' => 'packagehandlers', 02801 'suffix-name' => 'packagehandler.php', 02802 'type-directory' => true, 02803 'type' => $handlerName, 02804 'alias-group' => 'PackageSettings', 02805 'alias-variable' => 'HandlerAlias' ), 02806 $result ) ) 02807 { 02808 $handlerFile = $result['found-file-path']; 02809 if ( file_exists( $handlerFile ) ) 02810 { 02811 include_once( $handlerFile ); 02812 $handlerClassName = $result['type'] . 'PackageHandler'; 02813 if ( isset( $handlers[$result['type']] ) ) 02814 { 02815 $handler = $handlers[$result['type']]; 02816 $handler->reset(); 02817 } 02818 else 02819 { 02820 $handler = new $handlerClassName; 02821 $handlers[$result['type']] = $handler; 02822 } 02823 } 02824 } 02825 $GLOBALS['eZPackageHandlers'] = $handlers; 02826 return $handler; 02827 } 02828 02829 /*! 02830 Append File to package assosiated with key. The file will be available during installation using the same key. 02831 02832 \param key 02833 \param file path 02834 */ 02835 function appendSimpleFile( $key, $filepath ) 02836 { 02837 if ( !isset( $this->Parameters['simple-file-list'] ) ) 02838 { 02839 $this->Parameters['simple-file-list'] = array(); 02840 } 02841 02842 $suffix = eZFile::suffix( $filepath ); 02843 //$sourcePath = $fileInfo['original-path']; 02844 $packagePath = eZPackage::simpleFilesDirectory() . '/' . substr( md5( mt_rand() ), 0, 8 ) . '.' . $suffix; 02845 $destinationPath = $this->path() . '/' . $packagePath; 02846 eZDir::mkdir( eZDir::dirpath( $destinationPath ), false, true ); 02847 02848 //SP DBfile 02849 require_once( 'kernel/classes/ezclusterfilehandler.php' ); 02850 $fileHandler = eZClusterFileHandler::instance(); 02851 $fileHandler->fileFetch( $filepath ); 02852 02853 eZFileHandler::copy( $filepath, $destinationPath ); 02854 02855 $this->Parameters['simple-file-list'][$key] = array( 'original-path' => $filepath, 02856 'package-path' => $packagePath ); 02857 } 02858 02859 /*! 02860 Get complete path to file by file key 02861 02862 \param file key 02863 02864 \return complete file path 02865 */ 02866 function simpleFilePath( $fileKey ) 02867 { 02868 if ( !isset( $this->Parameters['simple-file-list'] ) ) 02869 { 02870 return false; 02871 } 02872 if ( !isset( $this->Parameters['simple-file-list'][$fileKey] ) ) 02873 { 02874 return false; 02875 } 02876 02877 return $this->path() . '/' . $this->Parameters['simple-file-list'][$fileKey]['package-path']; 02878 } 02879 02880 /** 02881 * Returns package version. 02882 * 02883 * Combines package version number and release number. 02884 * 02885 * \static 02886 * \return Package version (string). 02887 */ 02888 function getVersion() 02889 { 02890 return $this->Parameters['version-number'] . '-' . $this->Parameters['release-number']; 02891 } 02892 02893 /*! 02894 Sets installed/uninstalled state of the package 02895 \param installed 02896 */ 02897 function setInstalled( $installed = true ) 02898 { 02899 if ( $this->Parameters['install_type'] != 'install' ) 02900 return; 02901 02902 $name = $this->Parameters['name']; 02903 $version = $this->getVersion(); 02904 $db = eZDB::instance(); 02905 if ( $installed ) 02906 { 02907 if ( !$this->getInstallState() ) 02908 { 02909 $timestamp = time(); 02910 $db->query( "INSERT INTO ezpackage ( name, version, install_date ) VALUES ( '$name', '$version', '$timestamp' )" ); 02911 $this->isInstalled = true; 02912 } 02913 } 02914 else 02915 { 02916 $db->query( "DELETE FROM ezpackage WHERE name='$name' AND version='$version'" ); 02917 $this->isInstalled = false; 02918 } 02919 } 02920 02921 function isInstalled() 02922 { 02923 return $this->isInstalled; 02924 } 02925 02926 function getInstallState() 02927 { 02928 // TODO installation date 02929 02930 if ( $this->Parameters['install_type'] != 'install' ) 02931 return; 02932 02933 $name = $this->Parameters['name']; 02934 $version = $this->getVersion(); 02935 02936 $db = eZDB::instance(); 02937 $result = $db->arrayQuery( "SELECT count(*) AS count FROM ezpackage WHERE name='$name' AND version='$version'" ); 02938 02939 if ( !count( $result ) ) 02940 return false; 02941 $installed = $result[0]['count'] == '0' ? false : true; 02942 $this->isInstalled = $installed; 02943 return $installed; 02944 } 02945 02946 /*! 02947 \static 02948 Fetch info about languages for packages specified in $packageNameList. 02949 Return ex: array( 'eng-GB', 'rus-RU', ... ); 02950 if $withLanguageNames == true 02951 array( 'eng-GB' => "English", 02952 'rus-RU' => "Russian", 02953 ... ); 02954 */ 02955 static function languageInfoFromPackageList( $packageNameList, $withLanguageNames = false ) 02956 { 02957 $languageInfo = array(); 02958 foreach( $packageNameList as $packageName ) 02959 { 02960 $package = eZPackage::fetch( $packageName, false, false, false ); 02961 if( is_object( $package ) ) 02962 { 02963 $packageLanguageInfo = $package->languageInfo( $withLanguageNames ); 02964 // merge arrays 02965 if( $withLanguageNames ) 02966 { 02967 // we have array like 'locale' => 'name'. can use array_merge 02968 $languageInfo = array_merge( $languageInfo, $packageLanguageInfo ); 02969 } 02970 else 02971 { 02972 foreach( $packageLanguageInfo as $languageLocale ) 02973 { 02974 if( !in_array( $languageLocale, $languageInfo ) ) 02975 { 02976 $languageInfo[] = $languageLocale; 02977 } 02978 } 02979 } 02980 } 02981 else 02982 { 02983 eZDebug::writeWarning( "Unable to fetch package '$packageName'", 'eZPackage::languageInfoFromPackageList' ); 02984 } 02985 } 02986 02987 return $languageInfo; 02988 } 02989 02990 /*! 02991 Fetch info about languages for package. 02992 */ 02993 function languageInfo( $withLanguageNames = false ) 02994 { 02995 $langaugeInfo = array(); 02996 02997 $classHandler = eZPackage::packageHandler( 'ezcontentclass' ); 02998 $objectHandler = eZPackage::packageHandler( 'ezcontentobject' ); 02999 03000 $explainClassInfo = array( 'language_info' ); 03001 03002 $packageItems = $this->installItemsList(); 03003 foreach( $packageItems as $item ) 03004 { 03005 $itemLanguageInfo = array(); 03006 03007 if( $item['type'] == 'ezcontentclass' ) 03008 { 03009 $classInfo = $classHandler->explainInstallItem( $this, $item, $explainClassInfo ); 03010 $itemLanguageInfo = isset( $classInfo['language_info'] ) ? $classInfo['language_info'] : array(); 03011 } 03012 else if( $item['type'] == 'ezcontentobject' ) 03013 { 03014 $objectsInfo = $objectHandler->explainInstallItem( $this, $item ); 03015 03016 // merge objects info 03017 foreach( $objectsInfo as $objectInfo ) 03018 { 03019 $objectLanguages = isset( $objectInfo['language_info'] ) ? $objectInfo['language_info'] : array(); 03020 foreach( $objectLanguages as $objectLanguage ) 03021 { 03022 if( !in_array( $objectLanguage, $itemLanguageInfo ) ) 03023 { 03024 $itemLanguageInfo[] = $objectLanguage; 03025 } 03026 } 03027 } 03028 } 03029 03030 // merge class and objects infos 03031 foreach( $itemLanguageInfo as $languageLocale ) 03032 { 03033 if( !in_array( $languageLocale, $langaugeInfo ) ) 03034 { 03035 $langaugeInfo[] = $languageLocale; 03036 } 03037 } 03038 } 03039 03040 if( $withLanguageNames ) 03041 { 03042 $langaugeInfoWithNames = array(); 03043 foreach( $langaugeInfo as $languageLocale ) 03044 { 03045 $language = eZContentLanguage::fetchByLocale( $languageLocale ); 03046 $languageName = $language->attribute( 'name' ); 03047 $langaugeInfoWithNames[$languageLocale] = $languageName; 03048 } 03049 03050 $langaugeInfo = $langaugeInfoWithNames; 03051 } 03052 03053 return $langaugeInfo; 03054 } 03055 03056 function defaultLanguageMap() 03057 { 03058 $languageMap = array(); 03059 $packageLanguages = $this->languageInfo(); 03060 foreach( $packageLanguages as $language ) 03061 { 03062 $languageMap[$language] = $language; 03063 } 03064 03065 return $languageMap; 03066 } 03067 03068 /** 03069 * Checks if a package name is valid 03070 * 03071 * @param string $packageName the package name 03072 * @param string $transformedPackageName the package name, transformed to be valid 03073 * @return boolean true if the package name is valid, false if not 03074 */ 03075 03076 static function isValidName( $packageName, &$transformedPackageName = null ) 03077 { 03078 $trans = eZCharTransform::instance(); 03079 $transformedPackageName = $trans->transformByGroup( $packageName, 'identifier' ); 03080 03081 return $transformedPackageName === $packageName; 03082 } 03083 03084 03085 public $isInstalled = false; 03086 /// \privatesection 03087 /// All interal data 03088 public $Parameters; 03089 /// Controls which data has been modified 03090 } 03091 03092 ?>