eZ Publish  [4.0]
ezworkflow.php
Go to the documentation of this file.
00001 <?php
00002 //
00003 // Definition of eZWorkflow class
00004 //
00005 // Created on: <16-Apr-2002 11:08:14 amos>
00006 //
00007 // ## BEGIN COPYRIGHT, LICENSE AND WARRANTY NOTICE ##
00008 // SOFTWARE NAME: eZ Publish
00009 // SOFTWARE RELEASE: 4.0.x
00010 // COPYRIGHT NOTICE: Copyright (C) 1999-2008 eZ Systems AS
00011 // SOFTWARE LICENSE: GNU General Public License v2.0
00012 // NOTICE: >
00013 //   This program is free software; you can redistribute it and/or
00014 //   modify it under the terms of version 2.0  of the GNU General
00015 //   Public License as published by the Free Software Foundation.
00016 //
00017 //   This program is distributed in the hope that it will be useful,
00018 //   but WITHOUT ANY WARRANTY; without even the implied warranty of
00019 //   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00020 //   GNU General Public License for more details.
00021 //
00022 //   You should have received a copy of version 2.0 of the GNU General
00023 //   Public License along with this program; if not, write to the Free
00024 //   Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
00025 //   MA 02110-1301, USA.
00026 //
00027 //
00028 // ## END COPYRIGHT, LICENSE AND WARRANTY NOTICE ##
00029 //
00030 
00031 //!! eZKernel
00032 //! The class eZWorkflow does
00033 /*!
00034 
00035 */
00036 
00037 //include_once( "lib/ezdb/classes/ezdb.php" );
00038 //include_once( "kernel/classes/ezpersistentobject.php" );
00039 //include_once( "kernel/classes/ezworkflowevent.php" );
00040 //include_once( 'kernel/classes/ezworkflowgrouplink.php' );
00041 
00042 class eZWorkflow extends eZPersistentObject
00043 {
00044     const STATUS_NONE = 0;
00045     const STATUS_BUSY = 1;
00046     const STATUS_DONE = 2;
00047     const STATUS_FAILED = 3;
00048     const STATUS_DEFERRED_TO_CRON = 4;
00049     const STATUS_CANCELLED = 5;
00050     const STATUS_FETCH_TEMPLATE = 6;
00051     const STATUS_REDIRECT = 7;
00052     const STATUS_RESET = 8;
00053     const STATUS_WAITING_PARENT = 9;
00054     const STATUS_FETCH_TEMPLATE_REPEAT = 10;
00055 
00056     function eZWorkflow( $row )
00057     {
00058         $this->eZPersistentObject( $row );
00059     }
00060 
00061     static function definition()
00062     {
00063         return array( "fields" => array( "id" => array( 'name' => 'ID',
00064                                                         'datatype' => 'integer',
00065                                                         'default' => 0,
00066                                                         'required' => true ),
00067                                          "version" => array( 'name' => "Version",
00068                                                              'datatype' => 'integer',
00069                                                              'default' => 0,
00070                                                              'required' => true ),
00071                                          "is_enabled" => array( 'name' => "IsEnabled",
00072                                                                 'datatype' => 'integer',
00073                                                                 'default' => 0,
00074                                                                 'required' => true ),
00075                                          "workflow_type_string" => array( 'name' => "WorkflowTypeString",
00076                                                                           'datatype' => 'string',
00077                                                                           'default' => '',
00078                                                                           'required' => true,
00079                                                                           'max_length' => 50 ),
00080                                          "name" => array( 'name' => "Name",
00081                                                           'datatype' => 'string',
00082                                                           'default' => '',
00083                                                           'required' => true,
00084                                                           'max_length' => 255 ),
00085                                          "creator_id" => array( 'name' => "CreatorID",
00086                                                                 'datatype' => 'integer',
00087                                                                 'default' => 0,
00088                                                                 'required' => true,
00089                                                                 'foreign_class' => 'eZUser',
00090                                                                 'foreign_attribute' => 'contentobject_id',
00091                                                                 'multiplicity' => '1..*' ),
00092                                          "modifier_id" => array( 'name' => "ModifierID",
00093                                                                  'datatype' => 'integer',
00094                                                                  'default' => 0,
00095                                                                  'required' => true,
00096                                                                  'foreign_class' => 'eZUser',
00097                                                                  'foreign_attribute' => 'contentobject_id',
00098                                                                  'multiplicity' => '1..*' ),
00099                                          "created" => array( 'name' => "Created",
00100                                                              'datatype' => 'integer',
00101                                                              'default' => 0,
00102                                                              'required' => true ),
00103                                          "modified" => array( 'name' => "Modified",
00104                                                               'datatype' => 'integer',
00105                                                               'default' => 0,
00106                                                               'required' => true ) ),
00107                       "keys" => array( "id", "version" ),
00108                       'function_attributes' => array( 'creator' => 'creator',
00109                                                       'modifier' => 'modifier',
00110                                                       'workflow_type' => 'workflowType',
00111                                                       'event_count' => 'fetchEventCount',
00112                                                       'ordered_event_list' => 'fetchEvents',
00113                                                       'ingroup_list' => 'ingroupList',
00114                                                       'ingroup_id_list' => 'ingroupIDList',
00115                                                       'group_list' => 'groupList' ),
00116                       "increment_key" => "id",
00117                       "class_name" => "eZWorkflow",
00118                       "sort" => array( "name" => "asc" ),
00119                       "name" => "ezworkflow" );
00120     }
00121 
00122     static function statusName( $status )
00123     {
00124         $statusNameMap = self::statusNameMap();
00125         if ( isset( $statusNameMap[$status] ) )
00126             return $statusNameMap[$status];
00127         return false;
00128     }
00129 
00130     static function create( $user_id )
00131     {
00132         $date_time = time();
00133         $row = array(
00134             "id" => null,
00135             "workflow_type_string" => "group_ezserial",
00136             "version" => 1,
00137             "is_enabled" => 1,
00138             "name" => "",
00139             "creator_id" => $user_id,
00140             "modifier_id" => $user_id,
00141             "created" => $date_time,
00142             "modified" => $date_time );
00143         return new eZWorkflow( $row );
00144     }
00145 
00146     static function setIsEnabled( $enabled, $id, $version = 0 )
00147     {
00148         eZPersistentObject::updateObjectList( array(
00149                                                   "definition" => eZWorkflow::definition(),
00150                                                   "update_fields" => array( "is_enabled" => ( $enabled ? 1 : 0 ) ),
00151                                                   "conditions" => array( "id" => $id,
00152                                                                          "version" => $version )
00153                                                   )
00154                                               );
00155     }
00156 
00157     /*!
00158      \note Transaction unsafe. If you call several transaction unsafe methods you must enclose
00159      the calls within a db transaction; thus within db->begin and db->commit.
00160      */
00161     static function removeWorkflow( $id, $version )
00162     {
00163         eZPersistentObject::removeObject( eZWorkflow::definition(),
00164                                           array( "id" => $id,
00165                                                  "version" => $version ) );
00166     }
00167 
00168     /*!
00169      \note Transaction unsafe. If you call several transaction unsafe methods you must enclose
00170      the calls within a db transaction; thus within db->begin and db->commit.
00171      */
00172     function removeThis( $remove_childs = false )
00173     {
00174         $db = eZDB::instance();
00175         $db->begin();
00176         if ( is_array( $remove_childs ) )
00177         {
00178             foreach( $remove_childs as $event )
00179             {
00180                 $event->remove();
00181             }
00182         }
00183         else if ( $remove_childs )
00184         {
00185             eZPersistentObject::removeObject( eZWorkflowEvent::definition(),
00186                                               array( "workflow_id" => $this->ID,
00187                                                      "version" => $this->Version ) );
00188         }
00189 
00190         eZPersistentObject::remove();
00191         $db->commit();
00192     }
00193 
00194     /*!
00195      \static
00196      Removes all temporary versions.
00197      \note Transaction unsafe. If you call several transaction unsafe methods you must enclose
00198      the calls within a db transaction; thus within db->begin and db->commit.
00199     */
00200     static function removeTemporary()
00201     {
00202         $version = 1;
00203         $temporaryWorkflows = eZWorkflow::fetchList( $version, null, true );
00204 
00205         $db = eZDB::instance();
00206         $db->begin();
00207         foreach ( $temporaryWorkflows as $workflow )
00208         {
00209             $workflow->removeThis( true );
00210         }
00211         eZPersistentObject::removeObject( eZWorkflowEvent::definition(),
00212                                           array( 'version' => $version ) );
00213         $db->commit();
00214     }
00215 
00216     /*!
00217      \note Transaction unsafe. If you call several transaction unsafe methods you must enclose
00218      the calls within a db transaction; thus within db->begin and db->commit.
00219      */
00220     static function removeEvents( $events = false, $id = false, $version = false )
00221     {
00222         if ( is_array( $events ) )
00223         {
00224             $db = eZDB::instance();
00225             $db->begin();
00226             foreach( $events as $event )
00227             {
00228                 $event->remove();
00229             }
00230             $db->commit();
00231         }
00232         else
00233         {
00234             $condArray = array();
00235             if ( $version !== false )
00236             {
00237                 $condArray['version'] = $version;
00238             }
00239             if ( $id !== false )
00240             {
00241                 $condArray['workflow_id'] = $id;
00242             }
00243             eZPersistentObject::removeObject( eZWorkflowEvent::definition(),
00244                                               $condArray );
00245         }
00246     }
00247 
00248     static function adjustEventPlacements( $events )
00249     {
00250         if ( !is_array( $events ) )
00251             return;
00252         $i = 0;
00253         foreach( $events as $event )
00254         {
00255             $event->setAttribute( "placement", ++$i );
00256         }
00257     }
00258 
00259     /*!
00260      \note Transaction unsafe. If you call several transaction unsafe methods you must enclose
00261      the calls within a db transaction; thus within db->begin and db->commit.
00262      */
00263     function store( $store_childs = false )
00264     {
00265         $db = eZDB::instance();
00266         $db->begin();
00267         if ( is_array( $store_childs ) or $store_childs )
00268         {
00269             if ( is_array( $store_childs ) )
00270             {
00271                 $events = $store_childs;
00272             }
00273             else
00274             {
00275                 $events = $this->fetchEvents();
00276             }
00277             foreach ( $events as $event )
00278             {
00279                 $event->store();
00280             }
00281         }
00282         eZPersistentObject::store();
00283         $db->commit();
00284     }
00285     /*!
00286      \note Transaction unsafe. If you call several transaction unsafe methods you must enclose
00287      the calls within a db transaction; thus within db->begin and db->commit.
00288      */
00289     function storeDefined( $store_childs = false )
00290     {
00291         $db = eZDB::instance();
00292         $db->begin();
00293         if ( is_array( $store_childs ) or $store_childs )
00294         {
00295             if ( is_array( $store_childs ) )
00296             {
00297                 $events = $store_childs;
00298             }
00299             else
00300             {
00301                 $events = $this->fetchEvents();
00302             }
00303             foreach ( $events as $event )
00304             {
00305                 $event->storeDefined();
00306             }
00307         }
00308         eZPersistentObject::store();
00309         $db->commit();
00310     }
00311 
00312     function setVersion( $version, $set_childs = false )
00313     {
00314         if ( is_array( $set_childs ) or $set_childs )
00315         {
00316             if ( is_array( $set_childs ) )
00317             {
00318                 $events = $set_childs;
00319             }
00320             else
00321             {
00322                 $events = $this->fetchEvents();
00323             }
00324             foreach( $events as $event )
00325             {
00326                 $event->setAttribute( "version", $version );
00327             }
00328         }
00329         eZPersistentObject::setAttribute( "version", $version );
00330     }
00331 
00332     static function fetch( $id, $asObject = true, $version = 0 )
00333     {
00334         return eZPersistentObject::fetchObject( eZWorkflow::definition(),
00335                                                 null,
00336                                                 array( "id" => $id,
00337                                                        "version" => $version ),
00338                                                 $asObject );
00339     }
00340 
00341     /*!
00342       \static
00343       Fetch workflows based on module, function and connection type
00344 
00345       \param module name
00346       \param function name
00347       \param connect type
00348 
00349       \returns array of allowed workflows limited by trigger
00350     */
00351     static function fetchLimited( $moduleName, $functionName, $connectType )
00352     {
00353         $workflowArray = eZWorkflow::fetchList();
00354         $returnArray = array();
00355 
00356         foreach ( array_keys( $workflowArray ) as $key )
00357         {
00358             if ( $workflowArray[$key]->isAllowed( $moduleName,
00359                                                   $functionName,
00360                                                   $connectType ) )
00361             {
00362                 $returnArray[] = $workflowArray[$key];
00363             }
00364         }
00365 
00366         return $returnArray;
00367     }
00368 
00369     /*!
00370       Check if a trigger specified trigger is allowed to use with this workflow
00371 
00372       \param module name
00373       \param function name
00374       \param connect type
00375 
00376       \return true if allowed, false if not.
00377     */
00378     function isAllowed( $moduleName, $functionName, $connectType )
00379     {
00380         $eventArray = $this->fetchEvents();
00381 
00382         foreach ( array_keys( $eventArray ) as $key )
00383         {
00384             $eventType = $eventArray[$key]->attribute( 'workflow_type' );
00385             if ( !is_object( $eventType ) or !$eventType->isAllowed( $moduleName, $functionName, $connectType ) )
00386             {
00387                 return false;
00388             }
00389         }
00390 
00391         return true;
00392     }
00393 
00394     static function fetchList( $version = 0, $enabled = 1, $asObject = true )
00395     {
00396         $conds = array( 'version' => $version );
00397         if ( $enabled !== null )
00398             $conds['is_enabled'] = $enabled;
00399         return eZPersistentObject::fetchObjectList( eZWorkflow::definition(),
00400                                                     null, $conds, null, null,
00401                                                     $asObject );
00402     }
00403 
00404     static function fetchListCount( $version = 0, $enabled = 1 )
00405     {
00406         $list = eZPersistentObject::fetchObjectList( eZWorkflow::definition(),
00407                                                      array(),
00408                                                      array( 'version' => $version,
00409                                                             'is_enabled' => $enabled ),
00410                                                      false,
00411                                                      null,
00412                                                      false,
00413                                                      null,
00414                                                      array( array( 'operation' => 'count( id )',
00415                                                                     'name' => 'count' ) ) );
00416         return $list[0]["count"];
00417     }
00418 
00419     function fetchEventIndexed( $index )
00420     {
00421         $id = $this->ID;
00422         eZDebugSetting::writeDebug( 'workflow-event', $index, 'index in fetchEventIndexed' );
00423         $list = eZPersistentObject::fetchObjectList( eZWorkflowEvent::definition(),
00424                                                       array( "id", "placement" ),
00425                                                       array( "workflow_id" => $id,
00426                                                              "version" => 0 ),
00427                                                       array( "placement" => "asc" ),
00428                                                       array( "offset" => $index - 1,
00429                                                              "length" => 1 ),
00430                                                       false );
00431 
00432         eZDebugSetting::writeDebug( 'workflow-event', $list, "event indexed" );
00433         if ( count( $list ) > 0 )
00434             return $list[$index - 1]["id"];
00435         return null;
00436     }
00437 
00438     function fetchEvents( $asObject = true, $version = false )
00439     {
00440         if ( $version === false )
00441         {
00442             $version = $this->Version;
00443         }
00444         return eZWorkflowEvent::fetchFilteredList( array( "workflow_id" => $this->ID,
00445                                                           "version" => $version ),
00446                                                    $asObject );
00447     }
00448 
00449     static function fetchEventsByWorkflowID( $id, $asObject = true, $version = 0 )
00450     {
00451         return eZWorkflowEvent::fetchFilteredList( array( "workflow_id" => $id,
00452                                                           "version" => $version ),
00453                                                    $asObject );
00454     }
00455 
00456     function fetchEventCount( $version = false )
00457     {
00458         if ( $version === false )
00459         {
00460             $version = $this->Version;
00461         }
00462         $list = eZPersistentObject::fetchObjectList( eZWorkflowEvent::definition(),
00463                                                      array(),
00464                                                      array( 'version' => $version,
00465                                                             'workflow_id' => $id ),
00466                                                      false,
00467                                                      null,
00468                                                      false,
00469                                                      false,
00470                                                      array( array( 'operation' => 'count( id )',
00471                                                                    'name' => 'count' ) ) );
00472         return $list[0]["count"];
00473     }
00474 
00475     static function fetchEventCountByWorkflowID( $id, $version = 0 )
00476     {
00477         $list = eZPersistentObject::fetchObjectList( eZWorkflowEvent::definition(),
00478                                                      array(),
00479                                                      array( 'version' => $version,
00480                                                             'workflow_id' => $id ),
00481                                                      false,
00482                                                      null,
00483                                                      false,
00484                                                      false,
00485                                                      array( array( 'operation' => 'count( id )',
00486                                                                    'name' => 'count' ) ) );
00487         return $list[0]["count"];
00488     }
00489 
00490     function creator()
00491     {
00492         if ( isset( $this->CreatorID ) and $this->CreatorID )
00493         {
00494             //include_once( "kernel/classes/datatypes/ezuser/ezuser.php" );
00495             return eZUser::fetch( $this->CreatorID );
00496         }
00497 
00498         return null;
00499     }
00500 
00501     function modifier()
00502     {
00503         if ( isset( $this->ModifierID ) and $this->ModifierID )
00504         {
00505             //include_once( "kernel/classes/datatypes/ezuser/ezuser.php" );
00506             return eZUser::fetch( $this->ModifierID );
00507         }
00508 
00509         return null;
00510     }
00511 
00512     function ingroupList()
00513     {
00514         $this->InGroups = eZWorkflowGroupLink::fetchGroupList( $this->attribute("id"),
00515                                                                $this->attribute("version"),
00516                                                                true );
00517         return $this->InGroups;
00518     }
00519 
00520     function ingroupIDList()
00521     {
00522         $list = eZWorkflowGroupLink::fetchGroupList( $this->attribute("id"),
00523                                                      $this->attribute("version"),
00524                                                      false );
00525 
00526         $this->InGroupIDs = array();
00527         foreach ( $list as $item )
00528         {
00529             $this->InGroupIDs[] = $item['group_id'];
00530         }
00531         return $this->InGroupIDs;
00532     }
00533 
00534     function groupList()
00535     {
00536         $this->AllGroups = eZWorkflowGroup::fetchList();
00537         return $this->AllGroups;
00538     }
00539 
00540     function workflowType()
00541     {
00542         //include_once( "kernel/classes/ezworkflowtype.php" );
00543         return eZWorkflowType::createType( $this->WorkflowTypeString );
00544     }
00545 
00546     /*!
00547      \note Transaction unsafe. If you call several transaction unsafe methods you must enclose
00548      the calls within a db transaction; thus within db->begin and db->commit.
00549      */
00550     function cleanupWorkFlowProcess()
00551     {
00552         $db = eZDB::instance();
00553         $workflowID = $this->attribute( 'id' );
00554         $event_list = $this->fetchEvents();
00555         if ( $event_list != null )
00556         {
00557             $existEventIDArray = array();
00558             foreach ( $event_list as $event )
00559             {
00560                 $eventID = $event->attribute( 'id' );
00561                 $existEventIDArray[] = $eventID;
00562             }
00563             $existEventIDString = implode( ',', $existEventIDArray );
00564             $db->query( "DELETE FROM ezworkflow_process
00565                                WHERE workflow_id=$workflowID
00566                                  AND event_id not in ( $existEventIDString )" );
00567         }
00568         else
00569         {
00570             $db->query( "DELETE FROM ezworkflow_process WHERE workflow_id=$workflowID" );
00571         }
00572     }
00573 
00574     /**
00575      * Get status name map.
00576      *
00577      * @return array Status name map.
00578      */
00579     static function statusNameMap()
00580     {
00581         return array( eZWorkflow::STATUS_NONE => ezi18n( 'kernel/classes', 'No state yet' ),
00582                       eZWorkflow::STATUS_BUSY => ezi18n( 'kernel/classes', 'Workflow running' ),
00583                       eZWorkflow::STATUS_DONE => ezi18n( 'kernel/classes', 'Workflow done' ),
00584                       eZWorkflow::STATUS_FAILED => ezi18n( 'kernel/classes', 'Workflow failed an event' ),
00585                       eZWorkflow::STATUS_DEFERRED_TO_CRON => ezi18n( 'kernel/classes', 'Workflow event deferred to cron job' ),
00586                       eZWorkflow::STATUS_CANCELLED => ezi18n( 'kernel/classes', 'Workflow was canceled' ),
00587                       eZWorkflow::STATUS_FETCH_TEMPLATE => ezi18n( 'kernel/classes', 'Workflow fetches template' ),
00588                       eZWorkflow::STATUS_REDIRECT => ezi18n( 'kernel/classes', 'Workflow redirects user view' ),
00589                       eZWorkflow::STATUS_RESET => ezi18n( 'kernel/classes', 'Workflow was reset for reuse' ) );
00590     }
00591 
00592     /// \privatesection
00593     public $ID;
00594     public $Name;
00595     public $WorkflowTypeString;
00596     public $Version;
00597     public $IsEnabled;
00598     public $CreatorID;
00599     public $ModifierID;
00600     public $Created;
00601     public $Modified;
00602     public $InGroups;
00603     public $InGroupIDs;
00604     public $AllGroups;
00605 }
00606 
00607 ?>