|
eZ Publish
[trunk]
|
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 ?>