|
eZ Publish
[trunk]
|
00001 <?php 00002 /** 00003 * File containing the eZSiteInstaller class. 00004 * 00005 * @copyright Copyright (C) 1999-2012 eZ Systems AS. All rights reserved. 00006 * @license http://www.gnu.org/licenses/gpl-2.0.txt GNU General Public License v2 00007 * @version //autogentag// 00008 * @package kernel 00009 */ 00010 00011 /*! 00012 \class eZSiteInstaller ezsiteinstaller.php 00013 \ingroup eZUtils 00014 \brief A set of functions to do web-site installation from command-line. 00015 00016 Helps simplify installation process by providing a set of steps 00017 which will be executed sequentially. This class contains a common functions 00018 which can be reused in particular installations. 00019 00020 */ 00021 00022 class eZSiteInstaller 00023 { 00024 const ERR_OK = 0; 00025 const ERR_ABORT = 1; 00026 const ERR_CONTINUE = 2; 00027 00028 function eZSiteInstaller( $parameters = false ) 00029 { 00030 $this->initSettings( $parameters ); 00031 $this->initSteps(); 00032 00033 $this->LastErrorCode = eZSiteInstaller::ERR_OK; 00034 } 00035 00036 function &instance( $params ) 00037 { 00038 eZDebug::writeWarning( "Your installer doesn't implement 'instance' function", __METHOD__ ); 00039 return false; 00040 } 00041 00042 /*! 00043 Initialize $Settings member with custom values which can be used 00044 in install steps. 00045 */ 00046 function initSettings( $parameters ) 00047 { 00048 eZDebug::writeWarning( "Your installer doesn't implement 'initSettings' function", __METHOD__ ); 00049 } 00050 00051 /*! 00052 Define install steps 00053 Step definition: 00054 array( '_function' => <function_name>, 00055 '_params' => array( <param_list> ) ) 00056 where '_function' defines function name(which should be implemented within installer class) which will be called, 00057 '_params' is an array of parameters which will be passed to function <function_name>. Note that items of <param_list> 00058 can be defined in the form as <step definition> and this rule can be applied recursively. 00059 00060 Each function used in step definition should be defined as: 00061 function someFunction( $params ) 00062 { 00063 ... 00064 // you code goes here 00065 ... 00066 00067 // optionally you can set $LastErrorCode to 'eZSiteInstaller::ERR_ABORT' if you want to break installation if some step is failed. 00068 // $this->setLastErrorCode( eZSiteInstaller::ERR_ABORT ); 00069 } 00070 00071 Example: 00072 array( '_function' => 'step_1', 00073 '_params' => array( 'param_a' => 'foo', 00074 'param_b' => array( '_function' => 'helper_function_for_b', 00075 '_params' => array( 'param_b_a' => 'goo', 00076 'param_b_b' => array( '_function' => 'helper_functin_for_b_b', 00077 '_params' => array( 'param_b_b_a' => 'b_b_a' ) ) ) ) ) ); 00078 Execution flow: 00079 - $b_b = helper_function_b_b( array( 'param_b_b_a' => 'b_b_a' ) ); 00080 - $b = helper_function_for_b( array( 'param_b_a' => 'goo', 00081 'param_b_b' => $b_b ) ); 00082 - $result = step_1( array( 'param_a' => 'foo', 00083 'param_b' => $b ) ); 00084 */ 00085 function initSteps() 00086 { 00087 eZDebug::writeWarning( "Your installer doesn't implement 'initSteps' function", __METHOD__ ); 00088 } 00089 00090 /*! 00091 Add setting with $name and $value. 00092 */ 00093 function addSetting( $name, $value ) 00094 { 00095 $this->Settings[$name] = $value; 00096 } 00097 00098 /*! 00099 Return value for setting $name. 00100 */ 00101 function setting( $name ) 00102 { 00103 $value = false; 00104 if( $this->hasSetting( $name ) ) 00105 { 00106 $value = $this->Settings[$name]; 00107 } 00108 else 00109 { 00110 eZDebug::writeWarning( "Setting '$name' doesn't exist", __METHOD__ ); 00111 } 00112 00113 return $value; 00114 } 00115 00116 /*! 00117 Return TRUE if setting exist, otherwise FALSE. 00118 */ 00119 function hasSetting( $name ) 00120 { 00121 $hasSetting = false; 00122 if( isset( $this->Settings[$name] ) ) 00123 $hasSetting = true; 00124 00125 return $hasSetting; 00126 } 00127 00128 /*! 00129 Return 'post_install' steps 00130 */ 00131 function postInstallSteps() 00132 { 00133 return $this->Steps['post_install']; 00134 } 00135 00136 /*! 00137 Execute 'post_install' steps 00138 */ 00139 function postInstall() 00140 { 00141 $steps = $this->postInstallSteps(); 00142 $this->executeSteps( $steps ); 00143 } 00144 00145 /*! 00146 Execute $steps 00147 */ 00148 function executeSteps( $steps ) 00149 { 00150 $stepNum = 1; 00151 foreach( $steps as $step ) 00152 { 00153 $this->execFunction( $step ); 00154 00155 if( $this->lastErrorCode() !== eZSiteInstaller::ERR_OK ) 00156 { 00157 $res = $this->handleError(); 00158 if( $res === false ) 00159 $res = $this->defaultErrorHandler(); 00160 00161 if( $res === eZSiteInstaller::ERR_ABORT ) 00162 { 00163 $this->reportError( "Aborting execution on step number $stepNum: '". $step['_function'] ."'", 'eZSiteInstaller::postInstall' ); 00164 break; 00165 } 00166 } 00167 00168 ++$stepNum; 00169 } 00170 } 00171 00172 /*! 00173 Execute $function defined in step 00174 */ 00175 function execFunction( $function ) 00176 { 00177 $functionName = $function['_function']; 00178 00179 $this->buildFunctionParams( $function['_params'] ); 00180 00181 $result = $this->$functionName( $function['_params'] ); 00182 00183 return $result; 00184 } 00185 00186 /*! 00187 Prepare parameters for function executed in step definition. 00188 */ 00189 function buildFunctionParams( &$params ) 00190 { 00191 foreach( array_keys( $params ) as $paramKey ) 00192 { 00193 if( $this->isFunctionParam( $params[$paramKey] ) ) 00194 { 00195 $params[$paramKey] = $this->execFunction( $params[$paramKey] ); 00196 } 00197 else if( is_array( $params[$paramKey] ) ) 00198 { 00199 $this->buildFunctionParams( $params[$paramKey] ); 00200 } 00201 } 00202 } 00203 00204 /*! 00205 Return TRUE is custom function should be called to prepare params, otherwise FALSE( $param is constant). 00206 */ 00207 function isFunctionParam( $param ) 00208 { 00209 $isFunction = false; 00210 if( is_array( $param) && isset( $param['_function'] ) ) 00211 $isFunction = true; 00212 00213 return $isFunction; 00214 } 00215 00216 /*! 00217 Set last error code. 00218 */ 00219 function setLastErrorCode( $errCode ) 00220 { 00221 $this->LastErrorCode = $errCode; 00222 } 00223 00224 /*! 00225 Get last error code. 00226 */ 00227 function lastErrorCode() 00228 { 00229 return $this->LastErrorCode; 00230 } 00231 00232 /*! 00233 Set last error code and write error message to debug output 00234 Params: 00235 $text - error message text; 00236 $caption - error message caption; 00237 $errCode - error code to set; 00238 */ 00239 function reportError( $text, $caption, $errCode = eZSiteInstaller::ERR_ABORT ) 00240 { 00241 eZDebug::writeError( $text, $caption ); 00242 00243 $this->setLastErrorCode( $errCode ); 00244 } 00245 00246 00247 // 00248 // Function groups for common use in install steps. 00249 // 00250 00251 /////////////////////////////////////////////////////////////////////////// 00252 // DB: 00253 // dbBegin 00254 // dbCommit 00255 /////////////////////////////////////////////////////////////////////////// 00256 00257 /*! 00258 Start transaction. 00259 Params: 00260 no params 00261 */ 00262 function dbBegin( $params ) 00263 { 00264 $db = eZDB::instance(); 00265 $db->begin(); 00266 } 00267 00268 /*! 00269 Commit transaction. 00270 Params: 00271 no params 00272 */ 00273 function dbCommit( $params ) 00274 { 00275 $db = eZDB::instance(); 00276 $db->commit(); 00277 } 00278 00279 00280 /////////////////////////////////////////////////////////////////////////// 00281 // Content class: 00282 // classIDbyIdentifier 00283 // classByIdentifier 00284 /////////////////////////////////////////////////////////////////////////// 00285 00286 /*! 00287 Return ID of the content class. 00288 Params: 00289 'identifier' - identifier of the class. 00290 */ 00291 function classIDbyIdentifier( $params ) 00292 { 00293 $classID = false; 00294 00295 $contentClass = $this->classByIdentifier( $params ); 00296 00297 if( is_object( $contentClass ) ) 00298 { 00299 $classID = $contentClass->attribute( 'id' ); 00300 } 00301 00302 return $classID; 00303 } 00304 00305 /*! 00306 Return content class. 00307 Params: 00308 'identifier' - identifier of the class. 00309 */ 00310 function classByIdentifier( $params ) 00311 { 00312 $classIdentifier = $params['identifier']; 00313 00314 $contentClass = eZContentClass::fetchByIdentifier( $classIdentifier ); 00315 if( !is_object( $contentClass ) ) 00316 { 00317 eZDebug::writeWarning( "Content class with identifier '$classIdentifier' doesn't exist.", __METHOD__ ); 00318 } 00319 00320 return $contentClass; 00321 } 00322 00323 00324 /////////////////////////////////////////////////////////////////////////// 00325 // Content class attributes: 00326 // removeClassAttribute 00327 // addClassAttributes 00328 // updateClassAttributes 00329 /////////////////////////////////////////////////////////////////////////// 00330 00331 /*! 00332 Remove attribute from the content class 00333 Params: 00334 'class_id' - ID of content class to remove attribute from; 00335 'attribute_identifier' - attibute identifier to remove; 00336 */ 00337 function removeClassAttribute( $params ) 00338 { 00339 $contentClassID = $params['class_id']; 00340 $classAttributeIdentifier = $params['attribute_identifier']; 00341 00342 // get attributes of 'temporary' version as well 00343 $classAttributeList = eZContentClassAttribute::fetchFilteredList( array( 'contentclass_id' => $contentClassID, 00344 'identifier' => $classAttributeIdentifier ), 00345 true ); 00346 00347 $validation = array(); 00348 foreach( $classAttributeList as $classAttribute ) 00349 { 00350 $dataType = $classAttribute->dataType(); 00351 if( $dataType->isClassAttributeRemovable( $classAttribute ) ) 00352 { 00353 $objectAttributes = eZContentObjectAttribute::fetchSameClassAttributeIDList( $classAttribute->attribute( 'id' ) ); 00354 foreach( $objectAttributes as $objectAttribute ) 00355 { 00356 $objectAttributeID = $objectAttribute->attribute( 'id' ); 00357 $objectAttribute->removeThis( $objectAttributeID ); 00358 } 00359 00360 $classAttribute->removeThis(); 00361 } 00362 else 00363 { 00364 $removeInfo = $dataType->classAttributeRemovableInformation( $classAttribute ); 00365 if( $removeInfo === false ) 00366 $removeInfo = "Unknow reason"; 00367 00368 $validation[] = array( 'id' => $classAttribute->attribute( 'id' ), 00369 'identifier' => $classAttribute->attribute( 'identifier' ), 00370 'reason' => $removeInfo ); 00371 } 00372 } 00373 00374 if( count( $validation ) > 0 ) 00375 { 00376 $this->reportError( $validation, 'eZSiteInstaller::removeClassAttribute: Unable to remove eZClassAttribute(s)' ); 00377 } 00378 00379 } 00380 00381 /*! 00382 Add attribute to the content class 00383 Params: 00384 array( 'class' => array( 'identifier' => optional, string: identifire of content class; see 'id'; 00385 'id' => optional, ID of content class. if set it's used instead of 'class_identifier' to speed up things. 00386 you must supply either 'class_identifier' or 'class_id'; ), 00387 'attributes' => array( array( 'identifier' => attibute identifier, 00388 'name' => attribute name, 00389 'data_type_string' => attribute datatype, 00390 'default_value' => optional, attribute default value, default is 'false' 00391 'can_translate' => optional, default '1' 00392 'is_required' => optional, default '0' 00393 'is_searchable' => optional, default '0' 00394 'content' => optional, attribute content ), 00395 ... 00396 ); 00397 */ 00398 function addClassAttributes( $params ) 00399 { 00400 $classInfo = $params['class']; 00401 $attributesInfo = $params['attributes']; 00402 00403 $classID = isset( $classInfo['id'] ) ? $classInfo['id'] : false; 00404 if( $classID ) 00405 { 00406 $class = eZContentClass::fetch( $classID ); 00407 } 00408 else 00409 { 00410 if( isset( $classInfo['identifier'] ) ) 00411 { 00412 $class = eZSiteInstaller::classByIdentifier( $classInfo ); 00413 } 00414 else 00415 { 00416 $this->reportError( "neither 'id' nor 'identifier' is set for content class" , 00417 'eZSiteInstaller::addClassAttribute' ); 00418 } 00419 } 00420 00421 if( !is_object( $class ) ) 00422 { 00423 $this->reportError( "Can't fetch content class" , 00424 'eZSiteInstaller::addClassAttribute' ); 00425 return; 00426 } 00427 00428 $classID = $class->attribute( 'id' ); 00429 00430 foreach( $attributesInfo as $attributeInfo ) 00431 { 00432 $classAttributeIdentifier = $attributeInfo['identifier']; 00433 $classAttributeName = $attributeInfo['name']; 00434 $datatype = $attributeInfo['data_type_string']; 00435 $defaultValue = isset( $attributeInfo['default_value'] ) ? $attributeInfo['default_value'] : false; 00436 $canTranslate = isset( $attributeInfo['can_translate'] ) ? $attributeInfo['can_translate'] : 1; 00437 $isRequired = isset( $attributeInfo['is_required'] ) ? $attributeInfo['is_required'] : 0; 00438 $isSearchable = isset( $attributeInfo['is_searchable'] ) ? $attributeInfo['is_searchable'] : 0; 00439 $attrContent = isset( $attributeInfo['content'] ) ? $attributeInfo['content'] : false; 00440 00441 $attrCreateInfo = array( 'identifier' => $classAttributeIdentifier, 00442 'name' => $classAttributeName, 00443 'can_translate' => $canTranslate, 00444 'is_required' => $isRequired, 00445 'is_searchable' => $isSearchable ); 00446 $newAttribute = eZContentClassAttribute::create( $classID, $datatype, $attrCreateInfo ); 00447 00448 $dataType = $newAttribute->dataType(); 00449 $dataType->initializeClassAttribute( $newAttribute ); 00450 00451 // not all datatype can have 'default_value'. do check here. 00452 if( $defaultValue !== false ) 00453 { 00454 switch( $datatype ) 00455 { 00456 case 'ezboolean': 00457 { 00458 $newAttribute->setAttribute( 'data_int3', $defaultValue ); 00459 } 00460 break; 00461 00462 default: 00463 break; 00464 } 00465 } 00466 00467 if( $attrContent ) 00468 $newAttribute->setContent( $attrContent ); 00469 00470 // store attribute, update placement, etc... 00471 $attributes = $class->fetchAttributes(); 00472 $attributes[] = $newAttribute; 00473 00474 // remove temporary version 00475 if ( $newAttribute->attribute( 'id' ) !== null ) 00476 { 00477 $newAttribute->remove(); 00478 } 00479 00480 $newAttribute->setAttribute( 'version', eZContentClass::VERSION_STATUS_DEFINED ); 00481 $newAttribute->setAttribute( 'placement', count( $attributes ) ); 00482 00483 $class->adjustAttributePlacements( $attributes ); 00484 foreach( $attributes as $attribute ) 00485 { 00486 $attribute->storeDefined(); 00487 } 00488 00489 // update objects 00490 $classAttributeID = $newAttribute->attribute( 'id' ); 00491 $objects = eZContentObject::fetchSameClassList( $classID ); 00492 foreach( $objects as $object ) 00493 { 00494 $contentobjectID = $object->attribute( 'id' ); 00495 $objectVersions = $object->versions(); 00496 foreach( $objectVersions as $objectVersion ) 00497 { 00498 $translations = $objectVersion->translations( false ); 00499 $version = $objectVersion->attribute( 'version' ); 00500 foreach( $translations as $translation ) 00501 { 00502 $objectAttribute = eZContentObjectAttribute::create( $classAttributeID, $contentobjectID, $version ); 00503 $objectAttribute->setAttribute( 'language_code', $translation ); 00504 $objectAttribute->initialize(); 00505 $objectAttribute->store(); 00506 $objectAttribute->postInitialize(); 00507 } 00508 } 00509 } 00510 } 00511 } 00512 00513 /*! 00514 Update class attribute data. Currently only attribute 'name' is supported. 00515 Params: 00516 'class' - array( 'identifier' - identifire of content class ); 00517 'attributes - array( array( 'identifier' - attibute identifier to update; 00518 'new_name' - new attribute name ), 00519 ... 00520 ); 00521 */ 00522 function updateClassAttributes( $params ) 00523 { 00524 $classInfo = $params['class']; 00525 $attributesInfo = $params['attributes']; 00526 00527 $contentClassID = eZSiteInstaller::classIDbyIdentifier( $classInfo ); 00528 if( $contentClassID ) 00529 { 00530 foreach( $attributesInfo as $attributeInfo ) 00531 { 00532 $attributeIdentifier = $attributeInfo['identifier']; 00533 $name = isset( $attributeInfo['new_name'] ) ? $attributeInfo['new_name'] : false; 00534 00535 $classAttributeList = eZContentClassAttribute::fetchFilteredList( array( 'contentclass_id' => $contentClassID, 00536 'identifier' => $attributeIdentifier ), 00537 true ); 00538 foreach( $classAttributeList as $attribute ) 00539 { 00540 if( $name !== false ) 00541 { 00542 $attribute->setName( $name ); 00543 } 00544 00545 $attribute->store(); 00546 } 00547 } 00548 } 00549 } 00550 00551 00552 /////////////////////////////////////////////////////////////////////////// 00553 // Content object: 00554 // contentObjectByUrl 00555 // contentObjectByName 00556 // createContentObject 00557 // removeContentObject 00558 // renameContentObject 00559 /////////////////////////////////////////////////////////////////////////// 00560 00561 /*! 00562 Return content object by path identification string of its node. 00563 Params: 00564 'location' - path_identification_string of the node. 00565 */ 00566 function contentObjectByUrl( $params ) 00567 { 00568 $object = false; 00569 00570 $node = $this->nodeByUrl( $params ); 00571 if( is_object( $node ) ) 00572 { 00573 $object = $node->object(); 00574 } 00575 00576 return $object; 00577 } 00578 00579 /*! 00580 Create content object. 00581 Params: 00582 class_identifier - identifier of class; 00583 location - path identification string of parent node; 00584 attributes - array with object attributes; 00585 */ 00586 function createContentObject( $params ) 00587 { 00588 $objectID = false; 00589 00590 $classIdentifier = $params['class_identifier']; 00591 $location = $params['location']; 00592 $attributesData = $params['attributes']; 00593 00594 $parentNode = $this->nodeByUrl( $params ); 00595 if( is_object( $parentNode ) ) 00596 { 00597 $parentNodeID = $parentNode->attribute( 'node_id' ); 00598 $object = eZContentFunctions::createAndPublishObject( array( 'parent_node_id' => $parentNodeID, 00599 'class_identifier' => $classIdentifier, 00600 'attributes' => $attributesData ) ); 00601 00602 if( is_object( $object ) ) 00603 { 00604 $objectID = $object->attribute( 'id' ); 00605 } 00606 } 00607 00608 return $objectID; 00609 } 00610 00611 /*! 00612 Change name of content object. 00613 Params: 00614 contentobject_id - ID of object; 00615 name - new object name; 00616 */ 00617 function renameContentObject( $params ) 00618 { 00619 $contentObjectID = $params['contentobject_id']; 00620 $newName = $params['name']; 00621 $object = eZContentObject::fetch( $contentObjectID ); 00622 if( !is_object( $object ) ) 00623 return false; 00624 $object->rename( $newName ); 00625 } 00626 00627 /*! 00628 Return content object. The first object is returned in case if several objects have the same name. 00629 Params: 00630 'name' - object's name to look up; 00631 'class_id' - optional, ID of content class; 00632 */ 00633 function contentObjectByName( $params ) 00634 { 00635 $objectName = $params['name']; 00636 $classID = isset( $params['class_id'] ) ? $params['class_id'] : false; 00637 00638 //build up the conditions 00639 $conditions = array( 'name' => $objectName ); 00640 00641 if( $classID ) 00642 array_merge( $conditions, array( 'contentclass_id' => $classID ) ); 00643 00644 $objectList = eZContentObject::fetchList( true, $conditions, 0, 1 ); 00645 00646 $object = false; 00647 if( count( $objectList ) > 0 ) 00648 $object = $objectList[0]; 00649 00650 return $object; 00651 } 00652 00653 /*! 00654 Remove content object. 00655 Params: see 'contentObjectByName' 00656 */ 00657 function removeContentObject( $params ) 00658 { 00659 $object = $this->contentObjectByName( $params ); 00660 if( is_object( $object ) ) 00661 { 00662 $object->purge(); 00663 } 00664 else 00665 { 00666 eZDebug::writeWarning( "Object with name '" . $params['name'] . "' doesn't exist", __METHOD__ ); 00667 } 00668 } 00669 00670 00671 00672 /////////////////////////////////////////////////////////////////////////// 00673 // Content object attributes: 00674 // updateObjectAttributeFromString 00675 // updateContentObjectAttributes 00676 /////////////////////////////////////////////////////////////////////////// 00677 00678 /*! 00679 Update contentObjectAttribute with value specified in string. 00680 The object can be specified either by ID or by path identification string 00681 of its node. 00682 Params: 00683 object_id - optional, ID of object to update; 00684 location - optional, path to node with object; 00685 class_attribute_identifier - an identifier of attribute to update; 00686 string - new attribute value; 00687 */ 00688 function updateObjectAttributeFromString( $params ) 00689 { 00690 $objectID = isset( $params['object_id'] ) ? $params['object_id'] : false; 00691 $location = isset( $params['location'] ) ? $params['location'] : false; 00692 $classAttrIdentifier = $params['class_attribute_identifier']; 00693 $stringParam = $params['string']; 00694 00695 $contentObject = false; 00696 if( $objectID ) 00697 { 00698 $contentObject = eZContentObject::fetch( $objectID ); 00699 if( !is_object( $contentObject ) ) 00700 { 00701 $this->reportError( "Content object with id '$objectID' doesn't exist." , 'eZSiteInstaller::updateObjectAttributeFromString' ); 00702 } 00703 } 00704 else if( $location ) 00705 { 00706 $contentObject = $this->contentObjectByUrl( array( 'location' => $location ) ); 00707 } 00708 00709 if( is_object( $contentObject ) ) 00710 { 00711 $attributes = $contentObject->contentObjectAttributes(); 00712 if( count( $attributes ) > 0 ) 00713 { 00714 $objectAttribute = false; 00715 foreach( $attributes as $attribute ) 00716 { 00717 if( $attribute->attribute( 'contentclass_attribute_identifier' ) == $classAttrIdentifier ) 00718 { 00719 $objectAttribute = $attribute; 00720 break; 00721 } 00722 } 00723 00724 if( is_object( $objectAttribute ) ) 00725 { 00726 $objectAttribute->fromString( $stringParam ); 00727 $objectAttribute->store(); 00728 } 00729 else 00730 { 00731 $this->reportError( "Content object with id '$objectID' doesn't have attribute with contentClassAttribute identifier '$classAttrIdentifier'." , 'eZSiteInstaller::updateObjectAttributeFromString' ); 00732 } 00733 } 00734 else 00735 { 00736 $this->reportError( "Content object with id '$objectID' doesn't have attributes." , 'eZSiteInstaller::updateObjectAttributeFromString' ); 00737 } 00738 } 00739 } 00740 00741 00742 function updateContentObjectAttributes( $params ) 00743 { 00744 $objectID = $params['object_id']; 00745 $attributesData = $params['attributes_data']; 00746 00747 $contentObject = eZContentObject::fetch( $objectID ); 00748 if( !is_object( $contentObject ) ) 00749 { 00750 $this->reportError( "Content object with id '$objectID' doesn't exist." , 'eZSiteInstaller::updateContentObjectAttributes' ); 00751 return; 00752 } 00753 00754 $dataMap = $contentObject->dataMap(); 00755 foreach( $attributesData as $attrIdentifier => $attrData ) 00756 { 00757 $attribute = $dataMap[$attrIdentifier]; 00758 if( !is_object( $attribute ) ) 00759 { 00760 $this->reportError( "Warning: could not acquire attribute with identifier '$attrIdentifier'.", 00761 'eZSiteInstaller::updateContentObjectAttributes', 00762 eZSiteInstaller::ERR_CONTINUE ); 00763 continue; 00764 } 00765 00766 //get datatype name 00767 $datatypeString = $attribute->attribute( 'data_type_string' ); 00768 00769 switch( $datatypeString ) 00770 { 00771 case 'ezstring': 00772 { 00773 $attribute->setAttribute( "data_text", $attrData['DataText']); 00774 } break; 00775 00776 case 'ezxmltext': 00777 { 00778 $xml = '<?xml version="1.0" encoding="utf-8"?>'."\n". 00779 '<section xmlns:image="http://ez.no/namespaces/ezpublish3/image/"'."\n". 00780 ' xmlns:xhtml="http://ez.no/namespaces/ezpublish3/xhtml/"'."\n". 00781 ' xmlns:custom="http://ez.no/namespaces/ezpublish3/custom/">'."\n". 00782 ' <section>'."\n"; 00783 { 00784 $xml .= ' <paragraph>'; 00785 $numSentences = mt_rand( ( int ) $attributeParameters['min_sentences'], ( int ) $attributeParameters['max_sentences'] ); 00786 for( $sentence = 0; $sentence < $numSentences; $sentence++ ) 00787 { 00788 if( $sentence != 0 ) 00789 { 00790 $xml .= ' '; 00791 } 00792 } 00793 $xml .= "</paragraph>\n"; 00794 } 00795 $xml .= " </section>\n</section>\n"; 00796 00797 $attribute->setAttribute( 'data_text', $xml ); 00798 } break; 00799 00800 case 'eztext': 00801 { 00802 $attribute->setAttribute( 'data_text', $attrData['DataText'] ); 00803 } break; 00804 00805 case 'ezmatrix': 00806 { 00807 $columnsCount = count( $attrData["MatrixDefinition"]->attribute( 'columns' ) ); 00808 if( $columnsCount > 0 ) 00809 { 00810 $rowsCount = count( $attrData["MatrixCells"] ) / $columnsCount; 00811 00812 $tempMatrix = new eZMatrix( $attrData["MatrixTitle"], $rowsCount, $attrData["MatrixDefinition"] ); 00813 $tempMatrix->Cells = $attrData["MatrixCells"]; 00814 00815 $attribute->setAttribute( 'data_text', $tempMatrix->xmlString() ); 00816 $tempMatrix->decodeXML( $attribute->attribute( 'data_text' ) ); 00817 00818 $attribute->setContent( $tempMatrix ); 00819 } 00820 else 00821 { 00822 $this->reportError( "Number of columns in 'ezmatrix' should be greater then zero", 00823 'eZSiteInstaller::updateContentObjectAttributes', 00824 eZSiteInstaller::ERR_CONTINUE ); 00825 } 00826 00827 } break; 00828 00829 case 'ezboolean': 00830 { 00831 $attribute->setAttribute( 'data_int', $attrData['DataInt'] ); 00832 } break; 00833 00834 case 'ezinteger': 00835 { 00836 $attribute->setAttribute( 'data_int', $attrData['DataInt'] ); 00837 } break; 00838 00839 case 'ezfloat': 00840 { 00841 $power = 100; 00842 $float = mt_rand( $power * ( int ) $attrData['Min'], $power * ( int ) $attrData['Max'] ); 00843 $float = $float / $power; 00844 $attribute->setAttribute( 'data_float', $float ); 00845 } break; 00846 00847 case 'ezprice': 00848 { 00849 $power = 10; 00850 $price = mt_rand( $power * ( int ) $attrData['Min'], $power * ( int ) $attrData['Max'] ); 00851 $price = $price / $power; 00852 $attribute->setAttribute( 'data_float', $price ); 00853 } break; 00854 00855 case 'ezurl': 00856 { 00857 $attribute->setContent( $attrData['Content'] ); 00858 $attribute->setAttribute( "data_text", $attrData['DataText']); 00859 } break; 00860 00861 case 'ezuser': 00862 { 00863 $user = $attribute->content(); 00864 if( $user === null ) 00865 { 00866 $user = eZUser::create( $objectID ); 00867 } 00868 00869 $user->setInformation( $objectID, 00870 md5( time() . '-' . mt_rand() ), 00871 md5( time() . '-' . mt_rand() ) . '@ez.no', 00872 'publish', 00873 'publish' ); 00874 $user->store(); 00875 } break; 00876 } 00877 $attribute->store(); 00878 } 00879 00880 $contentObject->store(); 00881 } 00882 00883 00884 /////////////////////////////////////////////////////////////////////////// 00885 // Content object tree node: 00886 // nodeByUrl 00887 // nodeByName 00888 // nodeIdByName 00889 // nodePathStringByURL 00890 // moveTreeNode 00891 // swapNodes 00892 /////////////////////////////////////////////////////////////////////////// 00893 00894 /*! 00895 Return 'path_string' attribute of the node. 00896 Params: 00897 'location' - path_identification_string of the node. 00898 */ 00899 function nodePathStringByURL( $params ) 00900 { 00901 $pathString = ''; 00902 00903 $node = $this->nodeByUrl( $params ); 00904 00905 if( is_object( $node ) ) 00906 { 00907 $pathString = $node->attribute( 'path_string' ); 00908 } 00909 00910 return $pathString; 00911 } 00912 00913 /*! 00914 Return node. 00915 Params: 00916 'location' - path_identification_string of the node. 00917 */ 00918 function nodeByUrl( $params ) 00919 { 00920 $path_identification_string = $params['location']; 00921 00922 $node = eZContentObjectTreeNode::fetchByURLPath( $path_identification_string ); 00923 00924 if( !is_object( $node ) ) 00925 { 00926 $this->reportError( "The node '$path_identification_string' doesn't exist", 'eZSiteInstaller::nodeByUrl' ); 00927 } 00928 00929 return $node; 00930 } 00931 00932 /* 00933 Return 'main' node ID of object which has specifued name. For more info see 'contentObjectByName' 00934 Params: 00935 See 'contentObjectByName' 00936 */ 00937 function nodeIdByName( $params ) 00938 { 00939 $node = $this->nodeByName( $params ); 00940 00941 $id = false; 00942 if( is_object( $node ) ) 00943 $id = $node->attribute( 'node_id' ); 00944 00945 return $id; 00946 } 00947 00948 /* 00949 Return 'main' node of object which has specifued name. For more info see 'contentObjectByName' 00950 Params: 00951 See 'contentObjectByName' 00952 */ 00953 function nodeByName( $params ) 00954 { 00955 $node = false; 00956 00957 $contentObject = $this->contentObjectByName( $params ); 00958 if( is_object( $contentObject ) ) 00959 $node = $contentObject->attribute( 'main_node' ); 00960 00961 return $node; 00962 } 00963 00964 /*! 00965 Move node. 00966 Params: 00967 'node' - array( 'name' => object's name to move, 00968 'class_id' => optional, object's content class ID ); 00969 00970 'parent_node' - array( 'name' => parent object's name to move; 00971 'class_id' => optional, parent object's content class ID ); 00972 */ 00973 function moveTreeNode( $params ) 00974 { 00975 $nodeID = $this->nodeIdByName( $params['node'] ); 00976 $parentNodeID = $this->nodeIdByName( $params['parent_node'] ); 00977 00978 $result = eZContentObjectTreeNodeOperations::move( $nodeID, $parentNodeID ); 00979 00980 return $result; 00981 } 00982 00983 /*! 00984 Swap two nodes. 00985 It's a copy/paste from kernel/content/action.php 00986 */ 00987 function swapNodes( $params ) 00988 { 00989 $nodeInfo1 = $params['src_node']; 00990 $nodeInfo2 = $params['dst_node']; 00991 00992 //init vars 00993 $node1 = $this->nodeIdByName( $nodeInfo1 ); 00994 $node2 = $this->nodeIdByName( $nodeInfo2 ); 00995 00996 $nodeID = $node1; 00997 $node = eZContentObjectTreeNode::fetch( $nodeID ); 00998 00999 if( !is_object( $node ) ) 01000 { 01001 $this->reportError( "Can't fetch node '$nodeID'", 'eZSiteInstaller::swapNodes' ); 01002 return false; 01003 } 01004 01005 if( !$node->canSwap() ) 01006 { 01007 $this->reportError( "Cannot swap node '$nodeID' (no edit permission)", 'eZSiteInstaller::swapNodes' ); 01008 return false; 01009 } 01010 01011 $nodeParentNodeID = $node->attribute( 'parent_node_id' ); 01012 01013 $object = $node->object(); 01014 if( !is_object( $object ) ) 01015 { 01016 $this->reportError( "Cannot fetch object for node '$nodeID'", 'eZSiteInstaller::swapNodes' ); 01017 return false; 01018 } 01019 01020 $objectID = $object->attribute( 'id' ); 01021 $objectVersion = $object->attribute( 'current_version' ); 01022 $class = $object->contentClass(); 01023 $classID = $class->attribute( 'id' ); 01024 01025 $selectedNodeID = $node2; 01026 01027 $selectedNode = eZContentObjectTreeNode::fetch( $selectedNodeID ); 01028 01029 if( !is_object( $selectedNode ) ) 01030 { 01031 $this->reportError( "Cannot fetch node '$selectedNodeID'", 'eZSiteInstaller::swapNodes' ); 01032 return false; 01033 } 01034 01035 if( !$selectedNode->canSwap() ) 01036 { 01037 $this->reportError( "Cannot use node $selectedNodeID as the exchanging node for $nodeID, the current user does not have edit permission for it", 01038 'eZSiteInstaller::swapNodes' ); 01039 return false; 01040 } 01041 01042 // clear cache. 01043 eZContentCacheManager::clearContentCacheIfNeeded( $objectID ); 01044 01045 $selectedObject = $selectedNode->object(); 01046 $selectedObjectID = $selectedObject->attribute( 'id' ); 01047 $selectedObjectVersion = $selectedObject->attribute( 'current_version' ); 01048 $selectedNodeParentNodeID = $selectedNode->attribute( 'parent_node_id' ); 01049 01050 01051 /* In order to swap node1 and node2 a user should have the following permissions: 01052 * 1. move_from: move node1 01053 * 2. move_from: move node2 01054 * 3. move_to: move an object of the same class as node2 under parent of node1 01055 * 4. move_to: move an object of the same class as node1 under parent of node2 01056 * 01057 * The First two has already been checked. Let's check the rest. 01058 */ 01059 $nodeParent = $node->attribute( 'parent' ); 01060 $selectedNodeParent = $selectedNode->attribute( 'parent' ); 01061 $objectClassID = $object->attribute( 'contentclass_id' ); 01062 $selectedObjectClassID = $selectedObject->attribute( 'contentclass_id' ); 01063 01064 if( !$nodeParent || !$selectedNodeParent ) 01065 { 01066 $this->reportError( "No $nodeParent or no !$selectedNodeParent received.", 01067 'eZSiteInstaller::swapNodes' ); 01068 return false; 01069 } 01070 01071 if( !$nodeParent->canMoveTo( $selectedObjectClassID ) ) 01072 { 01073 $this->reportError( "Cannot move an object of class $selectedObjectClassID to node $nodeParentNodeID (no create permission)", 01074 'eZSiteInstaller::swapNodes' ); 01075 return false; 01076 } 01077 01078 if( !$selectedNodeParent->canMoveTo( $objectClassID ) ) 01079 { 01080 $this->reportError( "Cannot move an object of class $objectClassID to node $selectedNodeParentNodeID (no create permission)", 01081 'eZSiteInstaller::swapNodes' ); 01082 return false; 01083 } 01084 01085 // exchange contentobject ids and versions. 01086 $node->setAttribute( 'contentobject_id', $selectedObjectID ); 01087 $node->setAttribute( 'contentobject_version', $selectedObjectVersion ); 01088 01089 $db = eZDB::instance(); 01090 $db->begin(); 01091 $node->store(); 01092 $selectedNode->setAttribute( 'contentobject_id', $objectID ); 01093 $selectedNode->setAttribute( 'contentobject_version', $objectVersion ); 01094 $selectedNode->store(); 01095 01096 // modify path string 01097 $changedOriginalNode = eZContentObjectTreeNode::fetch( $nodeID ); 01098 $changedOriginalNode->updateSubTreePath(); 01099 $changedTargetNode = eZContentObjectTreeNode::fetch( $selectedNodeID ); 01100 $changedTargetNode->updateSubTreePath(); 01101 01102 // modify section 01103 if( $changedOriginalNode->attribute( 'main_node_id' ) == $changedOriginalNode->attribute( 'node_id' ) ) 01104 { 01105 $changedOriginalObject = $changedOriginalNode->object(); 01106 $parentObject = $nodeParent->object(); 01107 if( $changedOriginalObject->attribute( 'section_id' ) != $parentObject->attribute( 'section_id' ) ) 01108 { 01109 01110 eZContentObjectTreeNode::assignSectionToSubTree( $changedOriginalNode->attribute( 'main_node_id' ), 01111 $parentObject->attribute( 'section_id' ), 01112 $changedOriginalObject->attribute( 'section_id' ) ); 01113 } 01114 } 01115 if( $changedTargetNode->attribute( 'main_node_id' ) == $changedTargetNode->attribute( 'node_id' ) ) 01116 { 01117 $changedTargetObject = $changedTargetNode->object(); 01118 $selectedParentObject = $selectedNodeParent->object(); 01119 if( $changedTargetObject->attribute( 'section_id' ) != $selectedParentObject->attribute( 'section_id' ) ) 01120 { 01121 01122 eZContentObjectTreeNode::assignSectionToSubTree( $changedTargetNode->attribute( 'main_node_id' ), 01123 $selectedParentObject->attribute( 'section_id' ), 01124 $changedTargetObject->attribute( 'section_id' ) ); 01125 } 01126 } 01127 01128 $db->commit(); 01129 01130 // clear cache for new placement. 01131 eZContentCacheManager::clearContentCacheIfNeeded( $objectID ); 01132 01133 return true; 01134 } 01135 01136 /////////////////////////////////////////////////////////////////////////// 01137 // Roles and policies: 01138 // assignUserToRole 01139 // addPoliciesForRole 01140 // removePoliciesForRole 01141 /////////////////////////////////////////////////////////////////////////// 01142 01143 /*! 01144 Assign user to role. 01145 Params: 01146 location - path to user node where user object is located; 01147 role_name - name of role to assign; 01148 */ 01149 function assignUserToRole( $params ) 01150 { 01151 $location = $params['location']; 01152 $roleName = $params['role_name']; 01153 01154 $node = $this->nodeByUrl( $params ); 01155 if( is_object( $node ) ) 01156 { 01157 $role = eZRole::fetchByName( $roleName ); 01158 if( is_object( $role ) ) 01159 $role->assignToUser( $node->attribute( 'contentobject_id' ) ); 01160 } 01161 } 01162 01163 /*! 01164 Add policies from role 01165 Params: 01166 role_name - name of role; 01167 policies - array of policies to remove. Each item is an 01168 array of policy definition: array( 'module' => 01169 'function' => 01170 ['limitation'] => ); 01171 create_role - boolean, optional. If TRUE - will create new role if it doesn't exist. 01172 Default is TRUE. 01173 */ 01174 function addPoliciesForRole( $params ) 01175 { 01176 $roleName = $params['role_name']; 01177 $policiesDefinition = $params['policies']; 01178 $createRoleIfNotExists = isset( $params['create_role'] ) ? $params['create_role'] : true; 01179 01180 $role = eZRole::fetchByName( $roleName ); 01181 if( is_object( $role ) || $createRoleIfNotExists ) 01182 { 01183 if( !is_object( $role ) ) 01184 { 01185 $role = eZRole::create( $roleName ); 01186 $role->store(); 01187 } 01188 01189 $roleID = $role->attribute( 'id' ); 01190 if( count( $policiesDefinition ) > 0 ) 01191 { 01192 foreach( $policiesDefinition as $policyDefinition ) 01193 { 01194 if( isset( $policyDefinition['limitation'] ) ) 01195 { 01196 $role->appendPolicy( $policyDefinition['module'], $policyDefinition['function'], $policyDefinition['limitation'] ); 01197 } 01198 else 01199 { 01200 $role->appendPolicy( $policyDefinition['module'], $policyDefinition['function'] ); 01201 } 01202 } 01203 } 01204 } 01205 else 01206 { 01207 $this->reportError( "Role '$roleName' doesn't exist." , 'eZSiteInstaller::addPoliciesToRole' ); 01208 } 01209 } 01210 01211 /*! 01212 Remove policies from role 01213 Params: 01214 role_name - name of role; 01215 policies - array of policies to remove. Each item is an 01216 array of policy definition: array( 'module' => , 01217 'function' => ); 01218 remove_role - boolean, optional. If TRUE - empty(without policies) role will be removed. 01219 Default is TRUE. 01220 */ 01221 function removePoliciesForRole( $params ) 01222 { 01223 $roleName = $params['role_name']; 01224 $policiesDefinition = $params['policies']; 01225 $removeRoleIfEmpty = isset( $params['remove_role'] ) ? $params['remove_role'] : true; 01226 01227 $role = eZRole::fetchByName( $roleName ); 01228 if( is_object( $role ) ) 01229 { 01230 foreach( $policiesDefinition as $policyDefinition ) 01231 { 01232 $role->removePolicy( $policyDefinition['module'], $policyDefinition['function'] ); 01233 } 01234 01235 if( $removeRoleIfEmpty && count( $role->policyList() ) == 0 ) 01236 { 01237 $role->removeThis(); 01238 } 01239 } 01240 else 01241 { 01242 $this->reportError( "Role '$roleName' doesn't exist." , 'eZSiteInstaller::removePoliciesForRole' ); 01243 } 01244 } 01245 01246 01247 /////////////////////////////////////////////////////////////////////////// 01248 // Section: 01249 // sectionIDbyName 01250 // createContentSection 01251 // setSection 01252 /////////////////////////////////////////////////////////////////////////// 01253 01254 /*! 01255 Return ID of the section. 01256 Params: 01257 'section_name' - name of the section 01258 */ 01259 function sectionIDbyName( $params ) 01260 { 01261 $sectionID = false; 01262 $sectionName = $params['section_name']; 01263 01264 $sectionList = eZSection::fetchFilteredList( array( 'name' => $sectionName ), false, false, true ); 01265 01266 if( is_array( $sectionList ) && count( $sectionList ) > 0 ) 01267 { 01268 $section = $sectionList[0]; 01269 if( is_object( $section ) ) 01270 { 01271 $sectionID = $section->attribute( 'id' ); 01272 } 01273 } 01274 01275 return $sectionID; 01276 } 01277 01278 /*! 01279 Create new content section. 01280 Params: 01281 'name' - string: section name; 01282 'navigation_part_identifier' - string: identifier of navigation part; 01283 */ 01284 function createContentSection( $params ) 01285 { 01286 $section = false; 01287 01288 $sectionName = $params['name']; 01289 $navigationPart = $params['navigation_part_identifier']; 01290 01291 $section = new eZSection( array() ); 01292 $section->setAttribute( 'name', $sectionName ); 01293 $section->setAttribute( 'navigation_part_identifier', $navigationPart ); 01294 $section->store(); 01295 01296 return $section; 01297 } 01298 01299 /*! 01300 Assign section to subtree. 01301 Params: 01302 'section_name' - string: section name; 01303 'location' - string: path_identification_string of the node(root node of subtree); 01304 */ 01305 function setSection( $params ) 01306 { 01307 $location = $params['location']; 01308 $sectionName = $params['section_name']; 01309 01310 $sectionID = $this->sectionIDbyName( $params ); 01311 if( $sectionID ) 01312 { 01313 $rootNode = $this->nodeByUrl( $params ); 01314 if( is_object( $rootNode ) ) 01315 { 01316 eZContentObjectTreeNode::assignSectionToSubTree( $rootNode->attribute( 'node_id' ), $sectionID ); 01317 } 01318 } 01319 01320 } 01321 01322 01323 /////////////////////////////////////////////////////////////////////////// 01324 // RSS: 01325 // setRSSExport 01326 /////////////////////////////////////////////////////////////////////////// 01327 01328 /*! 01329 Create rss export. 01330 */ 01331 function setRSSExport( $params ) 01332 { 01333 01334 01335 // Create default rssExport object to use 01336 $rssExport = eZRSSExport::create( $params['creator'] ); 01337 $rssExport->setAttribute( 'access_url', $params['access_url'] ); 01338 $rssExport->setAttribute( 'main_node_only', $params['main_node_only'] ); 01339 $rssExport->setAttribute( 'number_of_objects', $params['number_of_objects'] ); 01340 $rssExport->setAttribute( 'rss_version', $params['rss_version'] ); 01341 $rssExport->setAttribute( 'status', $params['status'] ); 01342 $rssExport->setAttribute( 'title', $params['title'] ); 01343 $rssExport->store(); 01344 01345 $rssExportID = $rssExport->attribute( 'id' ); 01346 01347 foreach( $params['rss_export_itmes'] as $item ) 01348 { 01349 // Create One empty export item 01350 $rssExportItem = eZRSSExportItem::create( $rssExportID ); 01351 $rssExportItem->setAttribute( 'class_id', $item['class_id'] ); 01352 $rssExportItem->setAttribute( 'description', $item['description'] ); 01353 $rssExportItem->setAttribute( 'source_node_id', $item['source_node_id'] ); 01354 $rssExportItem->setAttribute( 'status', $item['status'] ); 01355 $rssExportItem->setAttribute( 'title', $item['title'] ); 01356 if ( isset( $item['enclosure'] ) ) 01357 { 01358 $rssExportItem->setAttribute( 'enclosure', $item['enclosure'] ); 01359 } 01360 $rssExportItem->store(); 01361 } 01362 } 01363 01364 01365 /////////////////////////////////////////////////////////////////////////// 01366 // Package: 01367 // packageFileItemPath 01368 /////////////////////////////////////////////////////////////////////////// 01369 01370 /*! 01371 Return path for package item. 01372 */ 01373 function packageFileItemPath( $params ) 01374 { 01375 $collection = $params['collection']; 01376 $fileItem = $params['file_item']; 01377 01378 $filePath = $fileItem['name']; 01379 01380 $package = $this->setting( 'package_object' ); 01381 if( is_object( $package ) ) 01382 { 01383 $filePath = $package->fileItemPath( $fileItem, $collection ); 01384 } 01385 else 01386 { 01387 eZDebug::writeWarning( "'Package' object is not set", __METHOD__ ); 01388 } 01389 01390 return $filePath; 01391 } 01392 01393 /////////////////////////////////////////////////////////////////////////// 01394 // Languages and Locales: 01395 // languageNameListFromLocaleList 01396 // languageNameFromLocale 01397 /////////////////////////////////////////////////////////////////////////// 01398 01399 /*! 01400 Build array of language names from locale list. 01401 Example: array( 'eng-GB', 'rus-RU' ) => array( 'eng', 'rus' ) 01402 */ 01403 function languageNameListFromLocaleList( $localeList ) 01404 { 01405 $languageList = array(); 01406 foreach( $localeList as $locale ) 01407 $languageList[] = $this->languageNameFromLocale( $locale ); 01408 01409 return $languageList; 01410 } 01411 01412 /*! 01413 Return language name from locale string. 01414 Example: 'rus' from 'rus-RU' 01415 */ 01416 function languageNameFromLocale( $locale ) 01417 { 01418 $pos = strpos( $locale , "-"); 01419 $languageName = substr( $locale , 0, $pos ); 01420 return $languageName; 01421 } 01422 01423 /*! 01424 Helper function used for extracting hostname from the given \param $uri 01425 */ 01426 public function extractHostname( $uri ) 01427 { 01428 $hostname = false; 01429 01430 $parts = parse_url( $uri ); 01431 01432 if ( isset( $parts['host'] ) ) 01433 $hostname = $parts['host']; 01434 01435 return $hostname; 01436 } 01437 01438 /*! 01439 Create siteaccess urls for additional user siteacceses using info about access type(host, post, uri) 01440 Params: 01441 'siteaccess_list' - list of siteaccess names to build urls; 01442 'access_type' - access type: port, hostname, url; 01443 'access_type_value' - access type value provided by setup wizard 01444 'exclude_port_list' - optional, ports to skip. used if 'access_type' is 'port'; 01445 'host' - host name 01446 'host_prepend_siteaccess' - optional, boolean which instructs to prepend the site access name or not to the value of 'host', by default true 01447 */ 01448 function createSiteaccessUrls( $params ) 01449 { 01450 $urlList = array(); 01451 01452 $siteaccessList = $params['siteaccess_list']; 01453 $accessType = $params['access_type']; 01454 $accessTypeValue = $params['access_type_value']; 01455 01456 $excludePortList = isset( $params['exclude_port_list'] ) ? $params['exclude_port_list'] : array(); 01457 01458 $hostname = false; 01459 01460 if ( isset( $params['host'] ) && $params['host'] !== '' ) 01461 $hostname = $this->extractHostname( $params['host'] ); 01462 01463 if ( !$hostname ) 01464 $hostname = eZSys::hostname(); 01465 01466 $indexFile = eZSys::wwwDir() . eZSys::indexFileName(); 01467 01468 switch( $accessType ) 01469 { 01470 case 'port': 01471 { 01472 $port = $accessTypeValue; 01473 01474 // build urls 01475 foreach( $siteaccessList as $siteaccess ) 01476 { 01477 // skip ports which are already in use 01478 while( in_array( $port, $excludePortList ) ) 01479 ++$port; 01480 01481 $urlList[$siteaccess]['url'] = "$hostname:$port" . $indexFile; 01482 $urlList[$siteaccess]['port'] = $port; 01483 ++$port; 01484 } 01485 } 01486 break; 01487 case 'host': 01488 case 'hostname': 01489 { 01490 $prependSiteAccess = isset( $params['host_prepend_siteaccess'] ) && is_bool( $params['host_prepend_siteaccess'] ) ? $params['host_prepend_siteaccess'] : true; 01491 01492 $hostname = $this->extractHostname( $accessTypeValue ); 01493 01494 if ( !$hostname ) 01495 $hostname = $accessTypeValue; 01496 01497 foreach( $siteaccessList as $siteaccess ) 01498 { 01499 if ( $prependSiteAccess ) 01500 { 01501 // replace undescores with dashes( '_' -> '-' ); 01502 $hostPrefix = preg_replace( '/(_)/', '-', $siteaccess); 01503 01504 // create url and host 01505 $urlList[$siteaccess]['url'] = $hostPrefix . '.' . $hostname . $indexFile; 01506 $urlList[$siteaccess]['host'] = $hostPrefix . '.' . $hostname; 01507 } 01508 else 01509 { 01510 // create url and host 01511 $urlList[$siteaccess]['url'] = $hostname . $indexFile; 01512 $urlList[$siteaccess]['host'] = $hostname; 01513 } 01514 } 01515 } 01516 break; 01517 case 'url': 01518 case 'uri': 01519 { 01520 foreach( $siteaccessList as $siteaccess ) 01521 { 01522 $urlList[$siteaccess]['url'] = $hostname . $indexFile . '/' . $siteaccess; 01523 } 01524 } 01525 break; 01526 01527 default: 01528 break; 01529 } 01530 01531 return $urlList; 01532 } 01533 01534 /*! 01535 Create localized siteaccess: copy general setting form 'source' siteaccess, apply new custom settings(locale, others...). 01536 */ 01537 function createSiteAccess( $params ) 01538 { 01539 $srcSiteaccess = $params['src']['siteaccess']; 01540 $dstSiteaccess = $params['dst']['siteaccess']; 01541 $dstSettings = isset( $params['dst']['settings'] ) ? $params['dst']['settings'] : array(); 01542 01543 // Create the siteaccess directory 01544 $srcSiteaccessDir = "settings/siteaccess/" . $srcSiteaccess; 01545 $dstSiteaccessDir = "settings/siteaccess/" . $dstSiteaccess; 01546 eZDir::mkdir( $dstSiteaccessDir, false, true ); 01547 eZDir::copy( $srcSiteaccessDir, $dstSiteaccessDir, false, true ); 01548 01549 // Update settings 01550 foreach ( $dstSettings as $iniFile => $settingGroups ) 01551 { 01552 $ini = eZINI::instance( $iniFile . ".append.php", $dstSiteaccessDir, null, false, null, true ); 01553 01554 foreach ( $settingGroups as $settingGroup => $settings ) 01555 { 01556 foreach ( $settings as $name => $value ) 01557 { 01558 $ini->setVariable( $settingGroup, $name, $value ); 01559 } 01560 } 01561 01562 $ini->save( false, false, false, false, true, true ); 01563 unset( $ini ); 01564 } 01565 01566 // Create roles 01567 $role = eZRole::fetchByName( "Anonymous" ); 01568 $role->appendPolicy( "user", "login", array( "SiteAccess" => array( eZSys::ezcrc32( $dstSiteaccess ) ) ) ); 01569 $role->store(); 01570 } 01571 01572 function solutionVersion() 01573 { 01574 eZDebug::writeWarning( "Your installer doesn't implement 'solutionVersion' function", __METHOD__ ); 01575 return false; 01576 } 01577 01578 function solutionName() 01579 { 01580 eZDebug::writeWarning( "Your installer doesn't implement 'solutionName' function", __METHOD__ ); 01581 return false; 01582 } 01583 01584 /*! 01585 Set solution name and version into db. 01586 Params: 01587 not used 01588 */ 01589 function setVersion( $params = false ) 01590 { 01591 $db = eZDB::instance(); 01592 01593 $name = strtolower( $this->solutionName() ); 01594 $version = $this->solutionVersion(); 01595 01596 $result = $db->query( "INSERT INTO ezsite_data VALUES( '$name', '$version' )" ); 01597 01598 return $result; 01599 } 01600 01601 function updateINIFiles( $params ) 01602 { 01603 foreach( $params['groups'] as $settingsData ) 01604 { 01605 $iniFilename = $settingsData['name'] . '.append.php'; 01606 $ini = eZINI::instance( $iniFilename, $params['settings_dir'] ); 01607 if( isset( $settingsData['discard_old_values'] ) && $settingsData['discard_old_values'] ) 01608 $ini->reset(); 01609 01610 // Ignore site.ini[eZINISettings].ReadonlySettingList[] settings when saving ini variables. 01611 $ini->setReadOnlySettingsCheck( false ); 01612 $ini->setVariables( $settingsData['settings'] ); 01613 $ini->save(); 01614 } 01615 } 01616 01617 function updateRoles( $params ) 01618 { 01619 foreach( $params['roles'] as $roleData ) 01620 { 01621 $roleName = $roleData['name']; 01622 $role = eZRole::fetchByName( $roleName ); 01623 if( !is_object( $role ) ) 01624 { 01625 $role = eZRole::create( $roleName ); 01626 $role->store(); 01627 } 01628 01629 $roleID = $role->attribute( 'id' ); 01630 if( isset( $roleData['policies'] ) ) 01631 { 01632 $policies = $roleData['policies']; 01633 foreach( $policies as $policy ) 01634 { 01635 $role->appendPolicy( $policy['module'], $policy['function'], isset( $policy['limitation'] ) ? $policy['limitation'] : array() ); 01636 } 01637 } 01638 01639 if( isset( $roleData['assignments'] ) ) 01640 { 01641 $roleAssignments = $roleData['assignments']; 01642 foreach( $roleAssignments as $roleAssignment ) 01643 { 01644 $assignmentIdentifier = false; 01645 $assignmentValue = false; 01646 if( isset( $roleAssignment['limitation'] ) ) 01647 { 01648 $assignmentIdentifier = $roleAssignment['limitation']['identifier']; 01649 $assignmentValue = $roleAssignment['limitation']['value']; 01650 } 01651 $role->assignToUser( $roleAssignment['user_id'], $assignmentIdentifier, $assignmentValue ); 01652 } 01653 } 01654 } 01655 } 01656 01657 function updatePreferences( $params ) 01658 { 01659 foreach( $params['prefs'] as $prefEntry ) 01660 { 01661 $prefUserID = $prefEntry['user_id']; 01662 foreach( $prefEntry['preferences'] as $pref ) 01663 { 01664 $prefName = $pref['name']; 01665 $prefValue = $pref['value']; 01666 eZPreferences::setValue( $prefName, $prefValue, $prefUserID ); 01667 } 01668 } 01669 } 01670 01671 /*! 01672 \static 01673 Return a value from $params hash. 01674 Return $defaultValue is value is not set. 01675 $name - a key in $params hash. $name can point to 2-dimensional array. 01676 example: $name = 'foo' will return $params['foo']; 01677 $name = 'foo/boo' will return $params['foo']['boo'] 01678 01679 */ 01680 function getParam( $params, $name, $defaultValue = false ) 01681 { 01682 $value = $defaultValue; 01683 01684 $pos = strpos( $name, '/' ); 01685 if( $pos !== false ) 01686 { 01687 $dim1 = substr( $name, 0, $pos ); 01688 $dim2 = substr( $name, $pos + 1 ); 01689 if( isset( $params[$dim1][$dim2] ) ) 01690 { 01691 $value = $params[$dim1][$dim2]; 01692 } 01693 } 01694 else if( isset( $params[$name] ) ) 01695 { 01696 $value = $params[$name]; 01697 } 01698 01699 return $value; 01700 } 01701 01702 /*! 01703 Default error handler 01704 */ 01705 function defaultErrorHandler() 01706 { 01707 return $this->lastErrorCode(); 01708 } 01709 01710 /*! 01711 Virtual function to re-implement in derived classes to handle error. 01712 Default error handler will be called if returns FALSE. 01713 */ 01714 function handleError() 01715 { 01716 // call default error handler 01717 return false; 01718 } 01719 01720 // store data to use in your steps. 01721 public $Settings; 01722 // define an order of functions to execute. 01723 public $Steps; 01724 // hold an error code of last executed step. 01725 public $LastErrorCode; 01726 } 01727 01728 ?>