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