eZ Publish  [trunk]
eznodeassignment.php
Go to the documentation of this file.
00001 <?php
00002 /**
00003  * File containing the eZNodeAssignment class.
00004  *
00005  * @copyright Copyright (C) 1999-2012 eZ Systems AS. All rights reserved.
00006  * @license http://www.gnu.org/licenses/gpl-2.0.txt GNU General Public License v2
00007  * @version //autogentag//
00008  * @package kernel
00009  */
00010 
00011 /*!
00012   \class eZNodeAssignment eznodeassignment.php
00013   \brief The class eZNodeAssignment does
00014 
00015 */
00016 class eZNodeAssignment extends eZPersistentObject
00017 {
00018     // Bit 0 is used to mark if the action is to be performed or not
00019     // A value of 0 means ignore and 1 means execute
00020     const OP_CODE_NOP =          0;
00021     const OP_CODE_EXECUTE =      1;
00022     // Create the node at specified location
00023     const OP_CODE_CREATE_NOP =   2;
00024     const OP_CODE_CREATE =       3;
00025     // Move the node to new location
00026     const OP_CODE_MOVE_NOP =     4;
00027     const OP_CODE_MOVE =         5;
00028     // Remove existing node
00029     const OP_CODE_REMOVE_NOP =   6;
00030     const OP_CODE_REMOVE =       7;
00031     // Set (update/create) values for node
00032     const OP_CODE_SET_NOP =      8;
00033     const OP_CODE_SET =          9;
00034 
00035     /*!
00036      Constructor
00037     */
00038     function eZNodeAssignment( $row )
00039     {
00040         $this->TempNode = null;
00041         $this->Name = false;
00042         $this->eZPersistentObject( $row );
00043     }
00044 
00045     static function definition()
00046     {
00047         return array( 'fields' => array( 'id' => array( 'name' => 'ID',
00048                                                         'datatype' => 'integer',
00049                                                         'default' => 0,
00050                                                         'required' => true ),
00051                                          'remote_id' => array( 'name' => 'RemoteID',
00052                                                                'datatype' => 'integer',
00053                                                                'default' => 0,
00054                                                                'required' => true ),
00055                                          'contentobject_id' => array( 'name' => 'ContentobjectID',
00056                                                                       'datatype' => 'integer',
00057                                                                       'default' => 0,
00058                                                                       'required' => true,
00059                                                                       'foreign_class' => 'eZContentObject',
00060                                                                       'foreign_attribute' => 'id',
00061                                                                       'multiplicity' => '1..*' ),
00062                                          'contentobject_version' => array( 'name' => 'ContentObjectVersion',
00063                                                                            'datatype' => 'integer',
00064                                                                            'default' => 0,
00065                                                                            'required' => true ),
00066                                          'parent_node' => array( 'name' => 'ParentNode',
00067                                                                  'datatype' => 'integer',
00068                                                                  'default' => 0,
00069                                                                  'required' => true,
00070                                                                  'foreign_class' => 'eZContentObjectTreeNode',
00071                                                                  'foreign_attribute' => 'node_id',
00072                                                                  'multiplicity' => '1..*' ),
00073                                          'sort_field' => array( 'name' => 'SortField',
00074                                                                 'datatype' => 'integer',
00075                                                                 'default' => eZContentObjectTreeNode::SORT_FIELD_PATH,
00076                                                                 'required' => true ),
00077                                          'sort_order' => array( 'name' => 'SortOrder',
00078                                                                 'datatype' => 'integer',
00079                                                                 'default' => eZContentObjectTreeNode::SORT_ORDER_ASC,
00080                                                                 'required' => true ),
00081                                          'is_main' => array( 'name' => 'Main',
00082                                                              'datatype' => 'integer',
00083                                                              'default' => 0,
00084                                                              'required' => true ),
00085                                          'from_node_id' => array( 'name' => 'FromNodeID',
00086                                                                   'datatype' => 'integer',
00087                                                                   'default' => 0,
00088                                                                   'required' => true,
00089                                                                   'foreign_class' => 'eZContentObjectTreeNode',
00090                                                                   'foreign_attribute' => 'node_id',
00091                                                                   'multiplicity' => '1..*' ),
00092                                          'parent_remote_id' => array( 'name' => 'ParentRemoteID',
00093                                                                       'datatype' => 'string',
00094                                                                       'default' => '',
00095                                                                       'required' => false ),
00096                                          'op_code' => array( 'name' => 'OpCode',
00097                                                              'datatype' => 'int',
00098                                                              'default' => 0, // eZNodeAssignment::OP_CODE_NOP
00099                                                              'required' => true ) ),
00100                       'keys' => array( 'id' ),
00101                       "function_attributes" => array( "parent_node_obj"      => "getParentNode",
00102                                                       "parent_contentobject" => "getParentObject",
00103                                                       "node"                 => "fetchNode",
00104                                                       'is_nop_operation'     => 'isNopOperation',
00105                                                       'is_create_operation'  => 'isCreateOperation',
00106                                                       'is_move_operation'    => 'isMoveOperation',
00107                                                       'is_remove_operation'  => 'isRemoveOperation',
00108                                                       'is_set_operation'     => 'isSetOperation',
00109                                                       'temp_node'            => 'tempNode' ),
00110                       "increment_key" => "id",
00111                       'class_name' => 'eZNodeAssignment',
00112                       'name' => 'eznode_assignment' );
00113     }
00114 
00115     function tempNode()
00116     {
00117         if ( $this->TempNode == null )
00118         {
00119             $this->TempNode = eZContentObjectTreeNode::create( $this->attribute( 'parent_node' ),
00120                                                                $this->attribute( 'contentobject_id' ),
00121                                                                $this->attribute( 'contentobject_version' ),
00122                                                                $this->attribute( 'sort_field' ),
00123                                                                $this->attribute( 'sort_order' ) );
00124             $this->TempNode->setName( $this->Name );
00125         }
00126         return $this->TempNode;
00127     }
00128 
00129     function setName( $name )
00130     {
00131         return $this->Name = $name;
00132     }
00133 
00134     function name()
00135     {
00136         return $this->Name;
00137     }
00138 
00139     /*!
00140      * Returns true if the assignment is a nop (no operation) operation.
00141      * \return bool
00142      */
00143     function isNopOperation()
00144     {
00145         return ( $this->OpCode & 1 ) == eZNodeAssignment::OP_CODE_NOP;
00146     }
00147 
00148     /*!
00149      * Returns true if the assignment is a create operation.
00150      * \return bool
00151      */
00152     function isCreateOperation()
00153     {
00154         return $this->OpCode == eZNodeAssignment::OP_CODE_CREATE;
00155     }
00156 
00157     /*!
00158      * Returns true if the assignment is a move operation.
00159      * \return bool
00160      */
00161     function isMoveOperation()
00162     {
00163         return $this->OpCode == eZNodeAssignment::OP_CODE_MOVE;
00164     }
00165 
00166     /*!
00167      * Returns true if the assignment is a remove operation.
00168      * \return bool
00169      */
00170     function isRemoveOperation()
00171     {
00172         return $this->OpCode == eZNodeAssignment::OP_CODE_REMOVE;
00173     }
00174 
00175     /*!
00176      * Returns true if the assignment is a set (update/create) operation.
00177      * \return bool
00178      */
00179     function isSetOperation()
00180     {
00181         return $this->OpCode == eZNodeAssignment::OP_CODE_SET;
00182     }
00183 
00184     static function create( $parameters = array() )
00185     {
00186         if ( !isset( $parameters['contentobject_id'] ) )
00187         {
00188             eZDebug::writeError( $parameters, "Cannot create node assignment without contentobject_id" );
00189             $retValue = null;
00190             return $retValue;
00191         }
00192         if ( !isset( $parameters['contentobject_version'] ) )
00193         {
00194             $parameters['contentobject_version'] = 1;
00195         }
00196         if ( !isset( $parameters['remote_id'] ) )
00197         {
00198             $parameters['remote_id'] = 0;
00199         }
00200         if ( !isset( $parameters['parent_node'] ) )
00201         {
00202             $parameters['parent_node'] = 2;
00203         }
00204         if ( !isset( $parameters['is_main'] ) )
00205         {
00206             $parameters['is_main'] = 0;
00207         }
00208         if ( !isset( $parameters['sort_field'] ) )
00209         {
00210             $parameters['sort_field'] = eZContentObjectTreeNode::SORT_FIELD_PUBLISHED;
00211         }
00212         if ( !isset( $parameters['sort_order'] ) )
00213         {
00214             $parameters['sort_order'] = eZContentObjectTreeNode::SORT_ORDER_DESC;
00215         }
00216         if ( !isset( $parameters['from_node_id'] ) )
00217         {
00218             $parameters['from_node_id'] = 0;
00219         }
00220         if ( !isset( $parameters['parent_remote_id'] ) )
00221         {
00222             $parameters['parent_remote_id'] = '';
00223         }
00224         if ( !isset( $parameters['op_code'] ) )
00225         {
00226             // The default value for new node-assigments is to create nodes from them.
00227             $parameters['op_code'] = eZNodeAssignment::OP_CODE_CREATE;
00228         }
00229 
00230         return new eZNodeAssignment( $parameters );
00231     }
00232 
00233     /*!
00234      Marks the specified nodeassignment to remove its node. It uses
00235      \a parentNodeID and \a contentObjectID if they are given,
00236      if they are \c false it will mark the current node assignment.
00237 
00238      \param $parentNodeID The ID of the parent node
00239      \param $contentObjectID The ID of the object
00240      \note Transaction unsafe. If you call several transaction unsafe methods you must enclose
00241      the calls within a db transaction; thus within db->begin and db->commit.
00242      */
00243     function remove( $parentNodeID = false, $contentObjectID = false )
00244     {
00245         $db = eZDB::instance();
00246         if ( $parentNodeID == false and $contentObjectID == false )
00247         {
00248             $nodeAssignment = $this;
00249         }
00250         else
00251         {
00252             $parentNodeID =(int) $parentNodeID;
00253             $contentObjectID =(int) $contentObjectID;
00254             $cond = array( 'parent_node' => $parentNodeID,
00255                            'contentobject_id' => $contentObjectID );
00256             $nodeAssignment = eZPersistentObject::fetchObject( eZNodeAssignment::definition(),
00257                                                                null,
00258                                                                $cond,
00259                                                                true );
00260         }
00261         $nodeAssignment->setAttribute( "op_code", eZNodeAssignment::OP_CODE_REMOVE );
00262         $nodeAssignment->store();
00263     }
00264 
00265     /*!
00266      \static
00267      Marks the node assignment with the ID \a $assignmentID to remove its node.
00268 
00269      \param $assignmentID Either an ID or an array with IDs.
00270      \return \c true if it were able to remove the assignments, \c false if something failed.
00271      \note If \a $assignmentID is an empty array it immediately returns \c false.
00272      \note Transaction unsafe. If you call several transaction unsafe methods you must enclose
00273      the calls within a db transaction; thus within db->begin and db->commit.
00274     */
00275     static function removeByID( $assignmentID )
00276     {
00277         $db = eZDB::instance();
00278         if ( is_array( $assignmentID ) )
00279         {
00280             if ( count( $assignmentID ) == 0 )
00281             {
00282                 return false;
00283             }
00284             $sql = "UPDATE eznode_assignment SET op_code = " . eZNodeAssignment::OP_CODE_REMOVE . ", is_main = 0 WHERE id IN ( ";
00285             $i = 0;
00286             foreach ( $assignmentID as $id )
00287             {
00288                 if ( $i > 0 )
00289                     $sql .= ", ";
00290                 $sql .= (int)$id;
00291                 ++$i;
00292             }
00293             $sql .= ' )';
00294         }
00295         else
00296         {
00297             $sql = "UPDATE eznode_assignment SET op_code = " . eZNodeAssignment::OP_CODE_REMOVE . ", is_main = 0 WHERE id=" . (int)$assignmentID;
00298         }
00299         $db->query( $sql );
00300         return true;
00301     }
00302 
00303     /*!
00304      Delete specified nodeassignment if \a parentNodeID and \a contentObjectID are given,
00305      if they are \c false it will remove the current node assignment.
00306 
00307      \param $parentNodeID The ID of the parent node
00308      \param $contentObjectID The ID of the object
00309      \note Transaction unsafe. If you call several transaction unsafe methods you must enclose
00310      the calls within a db transaction; thus within db->begin and db->commit.
00311      */
00312     function purge( $parentNodeID = false, $contentObjectID = false )
00313     {
00314         $db = eZDB::instance();
00315         if ( $parentNodeID == false and $contentObjectID == false )
00316         {
00317             $nodeAssignmentID = $this->attribute( 'id' );
00318             $sqlQuery = "DELETE FROM eznode_assignment WHERE id='$nodeAssignmentID'";
00319             $db->query( $sqlQuery );
00320         }
00321         else
00322         {
00323             $parentNodeID =(int) $parentNodeID;
00324             $contentObjectID =(int) $contentObjectID;
00325             $sqlQuery = "DELETE FROM eznode_assignment WHERE parent_node='$parentNodeID' AND contentobject_id='$contentObjectID'";
00326             $db->query( $sqlQuery );
00327         }
00328     }
00329 
00330     /*!
00331      \static
00332      Delelet the node assignment with the ID \a $assignmentID.
00333 
00334      \param $assignmentID Either an ID or an array with IDs.
00335      \return \c true if it were able to remove the assignments, \c false if something failed.
00336      \note If \a $assignmentID is an empty array it immediately returns \c false.
00337      \note Transaction unsafe. If you call several transaction unsafe methods you must enclose
00338      the calls within a db transaction; thus within db->begin and db->commit.
00339     */
00340     static function purgeByID( $assignmentID )
00341     {
00342         $db = eZDB::instance();
00343         if ( is_array( $assignmentID ) )
00344         {
00345             if ( count( $assignmentID ) == 0 )
00346             {
00347                 return false;
00348             }
00349             $sql = "DELETE FROM eznode_assignment WHERE id IN ( ";
00350             $i = 0;
00351             foreach ( $assignmentID as $id )
00352             {
00353                 if ( $i > 0 )
00354                     $sql .= ", ";
00355                 $sql .= (int)$id;
00356                 ++$i;
00357             }
00358             $sql .= ' )';
00359         }
00360         else
00361         {
00362             $sql = "DELETE FROM eznode_assignment WHERE id=" . (int)$assignmentID;
00363         }
00364         $db->query( $sql );
00365         return true;
00366     }
00367 
00368     static function fetchForObject( $contentObjectID, $version = 1, $main = 0, $asObject = true )
00369     {
00370         $cond = array( 'contentobject_id' => $contentObjectID,
00371                        'contentobject_version' => $version );
00372         if( $main > 0 )
00373         {
00374             $cond['is_main'] = 1;
00375         }
00376         $objectList = eZPersistentObject::fetchObjectList( eZNodeAssignment::definition(),
00377                                                             null,
00378                                                             $cond,
00379                                                             null,
00380                                                             null,
00381                                                             $asObject );
00382         return $objectList;
00383     }
00384 
00385     static function fetch( $contentObjectID, $version = 1, $parentNode = 0 ,$asObject = true )
00386     {
00387         $cond = array( 'contentobject_id' => $contentObjectID,
00388                        'contentobject_version' => $version,
00389                        'parent_node' => $parentNode );
00390         return eZPersistentObject::fetchObject( eZNodeAssignment::definition(),
00391                                                 null,
00392                                                 $cond,
00393                                                 $asObject );
00394     }
00395 
00396     /*!
00397      Finds the node for the current assignemnt if it exists and returns it.
00398      \return An eZContentObjectTreeNode object or \c null if no node was found.
00399       \sa eZContentObjectTreeNode::fetchNode
00400     */
00401     function fetchNode()
00402     {
00403         return eZContentObjectTreeNode::fetchNode( $this->ContentobjectID, $this->ParentNode );
00404     }
00405 
00406     /*!
00407      Fetches the node assignment which has id \a $id and returns it.
00408      \sa fetchListByID
00409     */
00410     static function fetchByID( $id ,$asObject = true )
00411     {
00412         $cond = array( 'id' => $id );
00413         return eZPersistentObject::fetchObject( eZNodeAssignment::definition(),
00414                                                 null, $cond,
00415                                                 $asObject );
00416     }
00417 
00418     /*!
00419      Fetches all node assignments which is mentioned in array \a $ID and returns it.
00420      \sa fetchByID
00421     */
00422     static function fetchListByID( $idList ,$asObject = true )
00423     {
00424         $cond = array( 'id' => array( $idList ) );
00425         return eZPersistentObject::fetchObjectList( eZNodeAssignment::definition(),
00426                                                     null, $cond, null, null,
00427                                                     $asObject );
00428     }
00429 
00430     /**
00431      * Fetch node assignment count by version status, giving parent node id list.
00432      *
00433      * @param array $parentNodeIDList
00434      * @param int $status
00435      * @return int
00436      */
00437     static function fetchChildCountByVersionStatus( $parentNodeIDList, $status = eZContentObjectVersion::STATUS_PENDING )
00438     {
00439         $db = eZDB::instance();
00440         $parentIDStatement = $db->generateSQLINStatement( $parentNodeIDList );
00441         $sql = "SELECT COUNT( DISTINCT eznode_assignment.id ) AS cnt
00442                     FROM ezcontentobject_version, eznode_assignment
00443                     WHERE ezcontentobject_version.contentobject_id = eznode_assignment.contentobject_id
00444                     AND ezcontentobject_version.version = eznode_assignment.contentobject_version
00445                     AND ezcontentobject_version.status = $status
00446                     AND eznode_assignment.parent_node $parentIDStatement ";
00447          $countResult = $db->arrayQuery( $sql );
00448          return (int)$countResult[0]['cnt'];
00449     }
00450 
00451     /**
00452      * Fetch node assignment list by version status, giving parent node id list.
00453      *
00454      * @param array $idList node id array
00455      * @param int $status status of the object version
00456      * @param boolean $count
00457      * @param boolean $asObject valid only when $count is false
00458      * @return array|int
00459      */
00460     static function fetchChildListByVersionStatus( $parentNodeIDList, $status = eZContentObjectVersion::STATUS_PENDING, $asObject = true )
00461     {
00462         $db = eZDB::instance();
00463         $parentIDStatement = $db->generateSQLINStatement( $parentNodeIDList );
00464 
00465         $sql = "SELECT DISTINCT eznode_assignment.*
00466                 FROM ezcontentobject_version, eznode_assignment
00467                 WHERE ezcontentobject_version.contentobject_id = eznode_assignment.contentobject_id
00468                 AND ezcontentobject_version.version = eznode_assignment.contentobject_version
00469                 AND ezcontentobject_version.status = $status
00470                 AND eznode_assignment.parent_node $parentIDStatement
00471                 ORDER BY eznode_assignment.contentobject_id";
00472         $nodeAssignmentArray = $db->arrayQuery( $sql );
00473         if( $asObject )
00474         {
00475             $result = array();
00476             foreach( $nodeAssignmentArray as $nodeAssignment )
00477             {
00478                 $result[] = new eZNodeAssignment( $nodeAssignment );
00479             }
00480             return $result;
00481         }
00482         else
00483         {
00484             return $nodeAssignmentArray;
00485         }
00486     }
00487 
00488 
00489     function cloneNodeAssignment( $nextVersionNumber = 1, $contentObjectID = false )
00490     {
00491         $assignmentRow = array( 'contentobject_id' => $this->attribute( 'contentobject_id' ),
00492                                 'contentobject_version' => $nextVersionNumber,
00493                                 'remote_id' => $this->attribute( 'remote_id' ),
00494                                 'parent_node' => $this->attribute( 'parent_node' ),
00495                                 'sort_field' => $this->attribute( 'sort_field' ),
00496                                 'sort_order' => $this->attribute( 'sort_order' ),
00497                                 'is_main' => $this->attribute( 'is_main' ),
00498                                 'parent_remote_id' => $this->attribute( 'parent_remote_id' ) );
00499         if ( $contentObjectID !== false )
00500             $assignmentRow['contentobject_id'] = $contentObjectID;
00501         return eZNodeAssignment::create( $assignmentRow );
00502     }
00503 
00504     function getParentNode()
00505     {
00506         return eZContentObjectTreeNode::fetch( $this->attribute( 'parent_node' ) );
00507     }
00508 
00509     /*!
00510      \return The contentobject which the parent node points to.
00511     */
00512     function getParentObject( )
00513     {
00514         return eZContentObject::fetchByNodeID( $this->attribute( 'parent_node' ) );
00515     }
00516 
00517     /*!
00518     \static
00519     Chooses and sets new main assignment for the specified object, in case if there's main assignment already.
00520     \return false if there is already main assignment, true on success.
00521      \note Transaction unsafe. If you call several transaction unsafe methods you must enclose
00522      the calls within a db transaction; thus within db->begin and db->commit.
00523     */
00524     static function setNewMainAssignment( $objectID, $version )
00525     {
00526         $assignments = eZNodeAssignment::fetchForObject( $objectID, $version );
00527 
00528         if ( count( $assignments ) == 0 )
00529             return true;
00530 
00531         // check: if there is already main assignment for the object then we should do nothing
00532         // BTW choose first nonremoving assignment as new main assignment
00533         $newMainAssignment = null;
00534         foreach ( $assignments as $key => $assignment )
00535         {
00536             if ( $assignment->attribute( 'op_code' ) != eZNodeAssignment::OP_CODE_REMOVE )
00537             {
00538                 if ( $newMainAssignment === null )
00539                 {
00540                     $newMainAssignment = $assignment;
00541                 }
00542                 if ( $assignment->attribute( 'is_main' ) )
00543                 {
00544                     return false;
00545                 }
00546             }
00547         }
00548 
00549         $db = eZDB::instance();
00550 
00551         if ( $newMainAssignment === null )
00552         {
00553             $db->query( "UPDATE eznode_assignment SET is_main=0 WHERE contentobject_id=$objectID AND contentobject_version=$version" );
00554             return false;
00555         }
00556 
00557         $parentMainNodeID = $newMainAssignment->attribute( 'parent_node' );
00558 
00559         $db->begin();
00560         $db->query( "UPDATE eznode_assignment SET is_main=1 WHERE contentobject_id=$objectID AND contentobject_version=$version AND parent_node=$parentMainNodeID" );
00561         $db->query( "UPDATE eznode_assignment SET is_main=0 WHERE contentobject_id=$objectID AND contentobject_version=$version AND parent_node<>$parentMainNodeID" );
00562         $db->commit();
00563 
00564         return true;
00565     }
00566 
00567     /// \privatesection
00568     public $ID;
00569     /// Used for giving unique values to an assignment which can later be checked.
00570     /// This is often used in templates to provide limited choices for assignments.
00571     public $RemoteID;
00572     public $ParentRemoteID;
00573     public $ContentobjectID;
00574     public $ContentObjectVersion;
00575     public $ParentNode;
00576     public $SortField;
00577     public $SortOrder;
00578     public $Main;
00579     public $FromNodeID;
00580 }
00581 
00582 ?>