[ Index ] |
|
Code source de eZ Publish 3.9.0 |
1 <?php 2 // 3 // Created on: <23-Mar-2005 23:23:23 rl> 4 // 5 // SOFTWARE NAME: eZ publish 6 // SOFTWARE RELEASE: 3.9.0 7 // BUILD VERSION: 17785 8 // COPYRIGHT NOTICE: Copyright (C) 1999-2006 eZ systems AS 9 // SOFTWARE LICENSE: GNU General Public License v2.0 10 // NOTICE: > 11 // This program is free software; you can redistribute it and/or 12 // modify it under the terms of version 2.0 of the GNU General 13 // Public License as published by the Free Software Foundation. 14 // 15 // This program is distributed in the hope that it will be useful, 16 // but WITHOUT ANY WARRANTY; without even the implied warranty of 17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 // GNU General Public License for more details. 19 // 20 // You should have received a copy of version 2.0 of the GNU General 21 // Public License along with this program; if not, write to the Free 22 // Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 23 // MA 02110-1301, USA. 24 // 25 // 26 27 include_once ( 'kernel/classes/ezcontentobject.php' ); 28 include_once ( "lib/ezdb/classes/ezdb.php" ); 29 30 $Module =& $Params['Module']; 31 $NodeID =& $Params['NodeID']; 32 33 $http =& eZHTTPTool::instance(); 34 35 if ( $http->hasPostVariable( 'BrowseCancelButton' ) ) 36 { 37 if ( $http->hasPostVariable( 'BrowseCancelURI' ) ) 38 return $Module->redirectTo( $http->postVariable( 'BrowseCancelURI' ) ); 39 } 40 41 if ( $NodeID === null ) // NodeID is returned after browsing 42 { 43 $NodeID = $http->postVariable( 'NodeID' ); 44 } 45 46 $srcNode = eZContentObjectTreeNode::fetch( $NodeID ); 47 48 if ( $srcNode === null ) 49 return $Module->handleError( EZ_ERROR_KERNEL_NOT_AVAILABLE, 'kernel' ); 50 51 if ( !$srcNode->attribute( 'can_read' ) ) 52 return $Module->handleError( EZ_ERROR_KERNEL_ACCESS_DENIED, 'kernel' ); 53 54 if ( $Module->isCurrentAction( 'Cancel' ) ) 55 { 56 $parentNodeID = $srcNode->attribute( 'parent_node_id' ); 57 return $Module->redirectToView( 'view', array( 'full', $parentNodeID ) ); 58 } 59 60 ///// functions START ============================================================================= 61 function copyPublishContentObject( &$sourceObject, 62 &$sourceSubtreeNodeIDList, 63 &$syncNodeIDListSrc, &$syncNodeIDListNew, 64 &$syncObjectIDListSrc, &$syncObjectIDListNew, 65 &$objectIDBlackList, &$nodeIDBlackList, 66 &$notifications, 67 $allVersions = false, $keepCreator = false, $keepTime = false ) 68 { 69 $sourceObjectID = $sourceObject->attribute( 'id' ); 70 71 $key = array_search( $sourceObjectID, $syncObjectIDListSrc ); 72 if ( $key !== false ) 73 { 74 eZDebug::writeDebug( "Object (ID = $sourceObjectID) has been already copied.", 75 "Subtree copy: copyPublishContentObject()" ); 76 return 1; // object already copied 77 } 78 79 $srcNodeList = $sourceObject->attribute( 'assigned_nodes' ); 80 81 // if we already failed to copy that contentobject, then just skip it: 82 if ( in_array( $sourceObjectID, $objectIDBlackList ) ) 83 return 0; 84 // if we already failed to copy that node, then just skip it: 85 //if ( in_array( $sourceNodeID, $nodeIDBlackList ) ) 86 // return 0; 87 88 // if cannot read contentobject then remember it and all its nodes (nodes 89 // which are inside subtree being copied) in black list, and skip current node: 90 if ( !$sourceObject->attribute( 'can_read' ) ) 91 { 92 $objectIDBlackList[] = $sourceObjectID; 93 $notifications['Warnings'][] = ezi18n( 'kernel/content/copysubtree', 94 "Object (ID = %1) was not copied: you don't have permissions to read object.", 95 null, array( $sourceObjectID ) ); 96 97 $srcNodeList = $sourceObject->attribute( 'assigned_nodes' ); 98 foreach( $srcNodeList as $srcNode ) 99 { 100 $srcNodeID = $srcNode->attribute( 'node_id' ); 101 $sourceParentNodeID = $srcNode->attribute( 'parent_node_id' ); 102 103 $key = array_search( $sourceParentNodeID, $sourceSubtreeNodeIDList ); 104 if ( $key !== false ) 105 { 106 $nodeIDBlackList[] = $srcNodeID; 107 $notifications['Warnings'][] = ezi18n( 'kernel/content/copysubtree', 108 "Node (ID = %1) was not copied: you don't have permissions to read object (ID = %2).", 109 null, array( $srcNodeID, $sourceObjectID ) ); 110 } 111 } 112 return 0; 113 } 114 115 // check if all possible parent nodes for given contentobject are already published: 116 $isReadyToPublish = false; 117 foreach ( $srcNodeList as $srcNode ) 118 { 119 $srcNodeID = $srcNode->attribute( 'node_id' ); 120 121 if ( in_array( $srcNodeID, $nodeIDBlackList ) ) 122 continue; 123 124 $srcParentNodeID = $srcNode->attribute( 'parent_node_id' ); 125 126 // if parent node for this node is outside 127 // of subtree being copied, then skip this node: 128 $key = array_search( $srcParentNodeID, $sourceSubtreeNodeIDList ); 129 if ( $key === false ) 130 continue; 131 132 // if parent node for this node wasn't copied yet and is in black list 133 // then add that node in black list and just skip it: 134 $key = array_search( $srcParentNodeID, $nodeIDBlackList ); 135 if ( $key !== false ) 136 { 137 $nodeIDBlackList[] = $srcNodeID; 138 $notifications['Warnings'][] = ezi18n( 'kernel/content/copysubtree', 139 "Node (ID = %1) wasn't copied: parent node (ID = %2) wasn't copied.", 140 null, array( $srcNodeID, $srcParentNodeID ) ); 141 continue; 142 } 143 144 $key = array_search( $srcParentNodeID, $syncNodeIDListSrc ); 145 if ( $key === false ) 146 { 147 // if parent node is not copied yet and not in black list, 148 // then just skip sourceObject from copying for next time 149 eZDebug::writeDebug( "Parent node (ID = $srcParentNodeID) for contentobject (ID = $sourceObjectID) is not published yet.", 150 "Subtree copy: copyPublishContentObject()" ); 151 return 2; 152 } 153 else 154 { 155 $newParentNodeID = $syncNodeIDListNew[ $key ]; 156 $newParentNode = eZContentObjectTreeNode::fetch( $newParentNodeID ); 157 if ( $newParentNode === null ) 158 { 159 eZDebug::writeError( "Cannot fetch one of parent nodes. Error are somewhere above", 160 "Subtree copy error: copyPublishContentObject()" ); 161 return 3; 162 } 163 164 if ( $newParentNode->checkAccess( 'create', $sourceObject->attribute( 'contentclass_id' ) ) != 1 ) 165 { 166 $nodeIDBlackList[] = $srcNodeID; 167 $notifications['Warnings'][] = ezi18n( 'kernel/content/copysubtree', 168 "Node (ID = %1) was not copied: you don't have permissions to create.", 169 null, array( $srcNodeID ) ); 170 171 continue; 172 } 173 else 174 $isReadyToPublish = true; 175 } 176 } 177 178 // if all nodes of sourceObject were skiped as black list entry or 179 // as outside of subtree being copied, then sourceObject cannot be 180 // copied and published in any new location. So insert sourceObject 181 // in a black list and skip it. 182 if ( $isReadyToPublish == false ) 183 { 184 $objectIDBlackList[] = $sourceObjectID; 185 $notifications['Warnings'][] = ezi18n( 'kernel/content/copysubtree', 186 "Object (ID = %1) was not copied: no one nodes of object wasn't copied.", 187 null, array( $sourceObjectID) ); 188 return 0; 189 } 190 191 // make copy of source object 192 $newObject = $sourceObject->copy( $allVersions ); // insert source and new object's ids in $syncObjectIDList 193 // We should reset section that will be updated in updateSectionID(). 194 // If sectionID is 0 than the object has been newly created 195 $newObject->setAttribute( 'section_id', 0 ); 196 $newObject->store(); 197 198 $syncObjectIDListSrc[] = $sourceObjectID; 199 $syncObjectIDListNew[] = $newObject->attribute( 'id' ); 200 201 $curVersion = $newObject->attribute( 'current_version' ); 202 $curVersionObject = $newObject->attribute( 'current' ); 203 204 $newObjAssignments = $curVersionObject->attribute( 'node_assignments' ); 205 206 // copy nodeassigments: 207 $assignmentsForRemoving = array(); 208 $foundMainAssignment = false; 209 foreach ( $newObjAssignments as $assignment ) 210 { 211 $parentNodeID = $assignment->attribute( 'parent_node' ); 212 213 // if assigment is outside of subtree being copied then do not copy this assigment 214 $key1 = array_search( $parentNodeID, $sourceSubtreeNodeIDList ); 215 $key2 = array_search( $parentNodeID, $nodeIDBlackList ); 216 if ( $key1 === false or $key2 !== false ) 217 { 218 $assignmentsForRemoving[] = $assignment->attribute( 'id' ); 219 continue; 220 } 221 222 $key = array_search( $parentNodeID, $syncNodeIDListSrc ); 223 if ( $key === false ) 224 { 225 eZDebug::writeError( "Cannot publish contentobject (ID=$sourceObjectID). Parent is not published yet.", 226 "Subtree Copy error: copyPublishContentObject()" ); 227 return 4; 228 } 229 230 if ( $assignment->attribute( 'is_main' ) ) 231 $foundMainAssignment = true; 232 233 $newParentNodeID = $syncNodeIDListNew[ $key ]; 234 $assignment->setAttribute( 'parent_node', $newParentNodeID ); 235 $assignment->store(); 236 } 237 // remove assigments which are outside of subtree being copied: 238 eZNodeAssignment::purgeByID( $assignmentsForRemoving ); 239 240 // if main nodeassigment was not copied then set as main first nodeassigment 241 if ( $foundMainAssignment == false ) 242 { 243 $newObjAssignments = $curVersionObject->attribute( 'node_assignments' ); 244 // We need to check if it has any assignments before changing the data. 245 if ( isset( $newObjAssignments[0] ) ) 246 { 247 $newObjAssignments[0]->setAttribute( 'is_main', 1 ); 248 $newObjAssignments[0]->store(); 249 } 250 } 251 252 // publish the newly created object 253 include_once ( 'lib/ezutils/classes/ezoperationhandler.php' ); 254 $result = eZOperationHandler::execute( 'content', 'publish', array( 'object_id' => $newObject->attribute( 'id' ), 255 'version' => $curVersion ) ); 256 // Refetch the object data since it might change in the database. 257 $newObjectID = $newObject->attribute( 'id' ); 258 $newObject =& eZContentObject::fetch( $newObjectID ); 259 $newNodeList =& $newObject->attribute( 'assigned_nodes' ); 260 if ( count($newNodeList) == 0 ) 261 { 262 $newObject->purge(); 263 eZDebug::writeError( "Cannot publish contentobject.", 264 "Subtree Copy Error!" ); 265 $notifications['Warnings'][] = ezi18n( 'kernel/content/copysubtree', 266 "Cannot publish object (ID = %1).", 267 null, array( $sourceObjectID) ); 268 return -1; 269 } 270 271 $objAssignments = $curVersionObject->attribute( 'node_assignments' ); 272 foreach ( $newNodeList as $newNode ) 273 { 274 $newParentNode = $newNode->fetchParent(); 275 $newParentNodeID = $newParentNode->attribute( 'node_id' ); 276 277 $keyA = array_search( $newParentNodeID, $syncNodeIDListNew ); 278 if ( $keyA === false ) 279 { 280 eZDebug::writeError( "Algoritm ERROR! Cannot find new parent node ID in new ID's list", 281 "Subtree Copy Error!" ); 282 return -2; 283 } 284 285 $srcParentNodeID = $syncNodeIDListSrc[ $keyA ]; 286 287 // Update attributes of node 288 $bSrcParentFound = false; 289 foreach ( $srcNodeList as $srcNode ) 290 { 291 if ( $srcNode->attribute( 'parent_node_id' ) == $srcParentNodeID ) 292 { 293 $newNode->setAttribute( 'priority', $srcNode->attribute( 'priority' ) ); 294 $newNode->setAttribute( 'is_hidden', $srcNode->attribute( 'is_hidden' ) ); 295 // Update node visibility 296 if ( $newParentNode->attribute( 'is_invisible' ) or $newParentNode->attribute( 'is_hidden' ) ) 297 $newNode->setAttribute( 'is_invisible', 1 ); 298 else 299 $newNode->setAttribute( 'is_invisible', $srcNode->attribute( 'is_invisible' ) ); 300 301 $syncNodeIDListSrc[] = $srcNode->attribute( 'node_id' ); 302 $syncNodeIDListNew[] = $newNode->attribute( 'node_id' ); 303 $bSrcParentFound = true; 304 break; 305 } 306 } 307 if ( $bSrcParentFound == false ) 308 { 309 eZDebug::writeError( "Cannot find source parent node in list of nodes already copied.", 310 "Subtree Copy Error!" ); 311 } 312 // Create unique remote_id 313 $newRemoteID = md5( (string)mt_rand() . (string)mktime() ); 314 $oldRemoteID = $newNode->attribute( 'remote_id' ); 315 $newNode->setAttribute( 'remote_id', $newRemoteID ); 316 // Change parent_remote_id for object assignments 317 foreach ( $objAssignments as $assignment ) 318 { 319 if ( $assignment->attribute( 'parent_remote_id' ) == $oldRemoteID ) 320 { 321 $assignment->setAttribute( 'parent_remote_id', $newRemoteID ); 322 $assignment->store(); 323 } 324 } 325 $newNode->store(); 326 } 327 328 // if $keepCreator == true then keep owner of contentobject being 329 // copied and creator of its published version Unchaged 330 $isModified = false; 331 if ( $keepTime ) 332 { 333 $srcPublished = $sourceObject->attribute( 'published' ); 334 $newObject->setAttribute( 'published', $srcPublished ); 335 $srcModified = $sourceObject->attribute( 'modified' ); 336 $newObject->setAttribute( 'modified', $srcModified ); 337 $isModified = true; 338 } 339 if ( $keepCreator ) 340 { 341 $srcOwnerID = $sourceObject->attribute( 'owner_id' ); 342 $newObject->setAttribute( 'owner_id', $srcOwnerID ); 343 $isModified = true; 344 } 345 if ( $isModified ) 346 $newObject->store(); 347 348 if ( $allVersions ) 349 { // copy time of creation and midification and creator id for 350 // all versions of content object being copied. 351 $srcVersionsList = $sourceObject->versions(); 352 353 foreach ( $srcVersionsList as $srcVersionObject ) 354 { 355 $newVersionObject = $newObject->version( $srcVersionObject->attribute( 'version' ) ); 356 if ( !is_object( $newVersionObject ) ) 357 continue; 358 359 $isModified = false; 360 if ( $keepTime ) 361 { 362 $srcVersionCreated = $srcVersionObject->attribute( 'created' ); 363 $newVersionObject->setAttribute( 'created', $srcVersionCreated ); 364 $srcVersionModified = $srcVersionObject->attribute( 'modified' ); 365 $newVersionObject->setAttribute( 'modified', $srcVersionModified ); 366 $isModified = true; 367 } 368 if ( $keepCreator ) 369 { 370 $srcVersionCreatorID = $srcVersionObject->attribute( 'creator_id' ); 371 $newVersionObject->setAttribute( 'creator_id', $srcVersionCreatorID ); 372 373 $isModified = true; 374 } 375 if ( $isModified ) 376 $newVersionObject->store(); 377 } 378 } 379 else // if not all versions copied 380 { 381 $srcVersionObject = $sourceObject->attribute( 'current' ); 382 $newVersionObject = $newObject->attribute( 'current' ); 383 384 $isModified = false; 385 if ( $keepTime ) 386 { 387 $srcVersionCreated = $srcVersionObject->attribute( 'created' ); 388 $newVersionObject->setAttribute( 'created', $srcVersionCreated ); 389 $srcVersionModified = $srcVersionObject->attribute( 'modified' ); 390 $newVersionObject->setAttribute( 'modified', $srcVersionModified ); 391 $isModified = true; 392 } 393 if ( $keepCreator ) 394 { 395 $srcVersionCreatorID = $srcVersionObject->attribute( 'creator_id' ); 396 $newVersionObject->setAttribute( 'creator_id', $srcVersionCreatorID ); 397 $isModified = true; 398 } 399 if ( $isModified ) 400 $newVersionObject->store(); 401 } 402 403 return 0; // source object was copied successfully. 404 405 } // function copyPublishContentObject END 406 407 408 function copySubtree( $srcNodeID, $dstNodeID, &$notifications, $allVersions, $keepCreator, $keepTime ) 409 { 410 // 1. Copy subtree and form the arrays of accordance of the old and new nodes and content objects. 411 412 $sourceSubTreeMainNode = ( $srcNodeID ) ? eZContentObjectTreeNode::fetch( $srcNodeID ) : false; 413 $destinationNode = ( $dstNodeID ) ? eZContentObjectTreeNode::fetch( $dstNodeID ) : false; 414 415 if ( !$sourceSubTreeMainNode ) 416 { 417 eZDebug::writeError( "Cannot get subtree main node (nodeID = $srcNodeID).", 418 "Subtree copy Error!" ); 419 $notifications['Errors'][] = ezi18n( 'kernel/content/copysubtree', 420 "Fatal error: cannot get subtree main node (ID = %1).", 421 null, array( $srcNodeID ) ); 422 return $notifications; 423 } 424 if ( !$destinationNode ) 425 { 426 eZDebug::writeError( "Cannot get destination node (nodeID = $dstNodeID).", 427 "Subtree copy Error!" ); 428 $notifications['Errors'][] = ezi18n( 'kernel/content/copysubtree', 429 "Fatal error: cannot get destination node (ID = %1).", 430 null, array( $dstNodeID ) ); 431 return $notifications; 432 } 433 434 $sourceNodeList = array(); 435 436 $syncNodeIDListSrc = array(); // arrays for synchronizing between source and new IDs of nodes 437 $syncNodeIDListNew = array(); 438 $syncObjectIDListSrc = array(); // arrays for synchronizing between source and new IDs of contentobjects 439 $syncObjectIDListNew = array(); 440 441 $sourceSubTreeMainNodeID = $sourceSubTreeMainNode->attribute( 'node_id' ); 442 $sourceNodeList[] = $sourceSubTreeMainNode; 443 444 $syncNodeIDListSrc[] = $sourceSubTreeMainNode->attribute( 'parent_node_id' ); 445 $syncNodeIDListNew[] = (int) $dstNodeID; 446 447 $nodeIDBlackList = array(); // array of nodes which are unable to copy 448 $objectIDBlackList = array(); // array of contentobjects which are unable to copy in any location inside new subtree 449 450 $sourceNodeList = array_merge( $sourceNodeList, 451 eZContentObjectTreeNode::subTree( array( 'Limitation' => array() ), $sourceSubTreeMainNodeID ) ); 452 $countNodeList = count( $sourceNodeList ); 453 454 $notifications['Notifications'][] = ezi18n( 'kernel/content/copysubtree', 455 "Number of nodes of source subtree - %1", 456 null, array( $countNodeList ) ); 457 458 // Prepare list of source node IDs. We will need it in the future 459 // for checking node is inside or outside of the subtree being copied. 460 $sourceNodeIDList = array(); 461 foreach ( $sourceNodeList as $sourceNode ) 462 $sourceNodeIDList[] = $sourceNode->attribute( 'node_id' ); 463 464 eZDebug::writeDebug( "Source NodeID = $srcNodeID, destination NodeID = $dstNodeID", 465 "Subtree copy: START!" ); 466 467 // 1. copying and publishing source subtree 468 $k = 0; 469 while ( count( $sourceNodeList ) > 0 ) 470 { 471 if ( $k > $countNodeList ) 472 { 473 eZDebug::writeError( "Too many loops while copying nodes.", 474 "Subtree Copy Error!" ); 475 break; 476 } 477 478 for ( $i = 0; $i < count( $sourceNodeList ); $i) 479 { 480 $sourceNodeID = $sourceNodeList[ $i ]->attribute( 'node_id' ); 481 482 // if node was alreaty copied 483 if ( in_array( $sourceNodeID, $syncNodeIDListSrc ) ) 484 { 485 array_splice( $sourceNodeList, $i, 1 ); 486 continue; 487 } 488 489 //////////// check permissions START 490 // if node is already in black list, then skip current node: 491 if ( in_array( $sourceNodeID, $nodeIDBlackList ) ) 492 { 493 array_splice( $sourceNodeList, $i, 1 ); 494 continue; 495 } 496 497 $sourceObject =& $sourceNodeList[ $i ]->object(); 498 499 $srcSubtreeNodeIDlist = ($sourceNodeID == $sourceSubTreeMainNodeID) ? $syncNodeIDListSrc : $sourceNodeIDList; 500 $copyResult = copyPublishContentObject( $sourceObject, 501 $srcSubtreeNodeIDlist, 502 $syncNodeIDListSrc, $syncNodeIDListNew, 503 $syncObjectIDListSrc, $syncObjectIDListNew, 504 $objectIDBlackList, $nodeIDBlackList, 505 $notifications, 506 $allVersions, $keepCreator, $keepTime ); 507 if ( $copyResult === 0 ) 508 { // if copying successful then remove $sourceNode from $sourceNodeList 509 array_splice( $sourceNodeList, $i, 1 ); 510 } 511 else 512 $i++; 513 } 514 $k++; 515 } 516 517 array_shift( $syncNodeIDListSrc ); 518 array_shift( $syncNodeIDListNew ); 519 520 521 $countNewNodes = count( $syncNodeIDListNew ); 522 $countNewObjects = count( $syncObjectIDListNew ); 523 524 $key = array_search( $sourceSubTreeMainNodeID, $syncNodeIDListSrc ); 525 if ( $key === false ) 526 { 527 eZDebug::writeDebug( "Root node of given subtree was not copied.", 528 "Subtree copy:" ); 529 $notifications['Notifacations'][] = ezi18n( 'kernel/content/copysubtree', 530 "Subtree was not copied." ); 531 return $notifications; 532 } 533 534 $notifications['Notifications'][] = ezi18n( 'kernel/content/copysubtree', 535 "Number of copied nodes - %1", 536 null, array( $countNewNodes ) ); 537 $notifications['Notifications'][] = ezi18n( 'kernel/content/copysubtree', 538 "Number of copied contentobjects - %1", 539 null, array( $countNewObjects ) ); 540 541 eZDebug::writeDebug( count( $syncNodeIDListNew ) ,"Number of copied nodes: " ); 542 eZDebug::writeDebug( count( $syncObjectIDListNew ), "Number of copied contentobjects: " ); 543 544 eZDebug::writeDebug( $objectIDBlackList, "Copy subtree: Not copied object IDs list:" ); 545 eZDebug::writeDebug( $nodeIDBlackList, "Copy subtree: Not copied node IDs list:" ); 546 547 // 2. fetch all new subtree 548 549 $newSubTreeMainNodeID = $syncNodeIDListSrc[ $key ]; 550 $newSubTreeMainNode = eZContentObjectTreeNode::fetch( $newSubTreeMainNodeID ); 551 552 $newNodeList[] = $newSubTreeMainNode; 553 $newNodeList = $sourceNodeList = array_merge( $newNodeList, 554 eZContentObjectTreeNode::subTree( false, $newSubTreeMainNodeID ) ); 555 556 // 3. fix local links (in ezcontentobject_link) 557 eZDebug::writeDebug( "Fixing global and local links...", 558 "Subtree copy:" ); 559 560 $db =& eZDB::instance(); 561 if ( !$db ) 562 { 563 eZDebug::writeError( "Cannot create instance of eZDB for fixing local links (related objects).", 564 "Subtree Copy Error!" ); 565 $notifications['Errors'][] = ezi18n( 'kernel/content/copysubtree', 566 "Cannot create instance of eZDB to fix local links (related objects)." ); 567 return $notifications; 568 } 569 570 $idListStr = $db->implodeWithTypeCast( ',', $syncObjectIDListNew, 'int' ); 571 $relatedRecordsList = $db->arrayQuery( "SELECT * FROM ezcontentobject_link WHERE from_contentobject_id IN ($idListStr)" ); 572 573 foreach ( array_keys( $relatedRecordsList ) as $key ) 574 { 575 $relatedEntry =& $relatedRecordsList[ $key ]; 576 $kindex = array_search( $relatedEntry[ 'to_contentobject_id' ], $syncObjectIDListSrc ); 577 if ( $kindex !== false ) 578 { 579 $newToContentObjectID = (int) $syncObjectIDListNew[ $kindex ]; 580 $linkID = (int) $relatedEntry[ 'id' ]; 581 $db->query( "UPDATE ezcontentobject_link SET to_contentobject_id=$newToContentObjectID WHERE id=$linkID" ); 582 } 583 } 584 585 // 4. duplicating of global links for new contentobjects (in ezurl_object_link) are automatic during copy of contentobject. 586 // it was fixed as bug patch. 587 588 // 5. fixing node_ids and object_ids in ezxmltext attributes of copied objects 589 $conditions = array( 'contentobject_id' => '', // 5 590 'data_type_string' => 'ezxmltext' ); 591 592 foreach ( $syncObjectIDListNew as $contentObjectID ) 593 { 594 $conditions[ 'contentobject_id' ] = $contentObjectID; 595 $attributeList = eZPersistentObject::fetchObjectList( eZContentObjectAttribute::definition(), null, $conditions ); 596 if ( count( $attributeList ) == 0 ) 597 { 598 continue; 599 } 600 foreach ( array_keys( $attributeList ) as $key ) 601 { 602 $xmlAttribute =& $attributeList[ $key ]; 603 $xmlText = $xmlAttribute->attribute( 'data_text' ); 604 $xmlTextLen = strlen ( $xmlText ); 605 $isTextModified = false; 606 $curPos = 0; 607 608 while ( $curPos < $xmlTextLen ) 609 { 610 $literalTagBeginPos = strpos( $xmlText, "<literal", $curPos ); 611 if ( $literalTagBeginPos ) 612 { 613 $literalTagEndPos = strpos( $xmlText, "</literal>", $literalTagBeginPos ); 614 if ( $literalTagEndPos === false ) 615 break; 616 $curPos = $literalTagEndPos + 9; 617 } 618 619 if ( ($tagBeginPos = strpos( $xmlText, "<link", $curPos )) !== false or 620 ($tagBeginPos = strpos( $xmlText, "<a" , $curPos )) !== false or 621 ($tagBeginPos = strpos( $xmlText, "<embed",$curPos )) !== false ) 622 { 623 $tagEndPos = strpos( $xmlText, ">", $tagBeginPos + 1 ); 624 if ( $tagEndPos === false ) 625 break; 626 627 $tagText = substr( $xmlText, $tagBeginPos, $tagEndPos - $tagBeginPos ); 628 629 if ( ($nodeIDAttributePos = strpos( $tagText, " node_id=\"" )) !== false ) 630 { 631 $idNumberPos = $nodeIDAttributePos + 10; 632 $quoteEndPos = strpos( $tagText, "\"", $idNumberPos ); 633 634 if ( $quoteEndPos !== false ) 635 { 636 $idNumber = substr( $tagText, $idNumberPos, $quoteEndPos - $idNumberPos ); 637 $key = array_search( (int) $idNumber, $syncNodeIDListSrc ); 638 639 if ( $key !== false ) 640 { 641 $tagText = substr_replace( $tagText, (string) $syncNodeIDListNew[ $key ], $idNumberPos, $quoteEndPos - $idNumberPos ); 642 $xmlText = substr_replace( $xmlText, $tagText, $tagBeginPos, $tagEndPos - $tagBeginPos ); 643 $isTextModified = true; 644 } 645 } 646 } 647 else if ( ($objectIDAttributePos = strpos( $tagText, " object_id=\"" )) !== false ) 648 { 649 $idNumberPos = $objectIDAttributePos + 12; 650 $quoteEndPos = strpos( $tagText, "\"", $idNumberPos ); 651 652 if ( $quoteEndPos !== false ) 653 { 654 $idNumber = substr( $tagText, $idNumberPos, $quoteEndPos - $idNumberPos ); 655 $key = array_search( (int) $idNumber, $syncObjectIDListSrc ); 656 if ( $key !== false ) 657 { 658 $tagText = substr_replace( $tagText, (string) $syncObjectIDListNew[ $key ], $idNumberPos, $quoteEndPos - $idNumberPos ); 659 $xmlText = substr_replace( $xmlText, $tagText, $tagBeginPos, $tagEndPos - $tagBeginPos ); 660 $isTextModified = true; 661 } 662 } 663 } 664 $curPos = $tagEndPos; 665 } 666 else if ( ($tagBeginPos = strpos( $xmlText, "<object", $curPos )) !== false ) 667 { 668 $tagEndPos = strpos( $xmlText, ">", $tagBeginPos + 1 ); 669 if ( !$tagEndPos ) 670 break; 671 672 $tagText = substr( $xmlText, $tagBeginPos, $tagEndPos - $tagBeginPos ); 673 674 if ( ($idAttributePos = strpos( $tagText, " id=\"" )) !== false ) 675 { 676 $idNumberPos = $idAttributePos + 5; 677 $quoteEndPos = strpos( $tagText, "\"", $idNumberPos ); 678 679 if ( $quoteEndPos !== false ) 680 { 681 $idNumber = substr( $tagText, $idNumberPos, $quoteEndPos - $idNumberPos ); 682 $key = array_search( (int) $idNumber, $syncObjectIDListSrc ); 683 if ( $key !== false ) 684 { 685 $tagText = substr_replace( $tagText, (string) $syncObjectIDListNew[ $key ], $idNumberPos, $quoteEndPos - $idNumberPos ); 686 $xmlText = substr_replace( $xmlText, $tagText, $tagBeginPos, $tagEndPos - $tagBeginPos ); 687 $isTextModified = true; 688 } 689 } 690 } 691 $curPos = $tagEndPos; 692 } 693 else 694 break; 695 696 } // while END 697 698 if ( $isTextModified ) 699 { 700 $xmlAttribute->setAttribute( 'data_text', $xmlText ); 701 $xmlAttribute->store(); 702 } 703 } // foreach END 704 } 705 706 // 6. fixing datatype ezobjectrelationlist 707 $conditions = array( 'contentobject_id' => '', 708 'data_type_string' => 'ezobjectrelationlist' ); 709 foreach ( $syncObjectIDListNew as $contentObjectID ) 710 { 711 $conditions[ 'contentobject_id' ] = $contentObjectID; 712 $attributeList = eZPersistentObject::fetchObjectList( eZContentObjectAttribute::definition(), null, $conditions ); 713 if ( count( $attributeList ) == 0 ) 714 { 715 continue; 716 } 717 foreach ( array_keys( $attributeList ) as $key ) 718 { 719 $relationListAttribute =& $attributeList[ $key ]; 720 $relationsXmlText = $relationListAttribute->attribute( 'data_text' ); 721 $relationsDom =& eZObjectRelationListType::parseXML( $relationsXmlText ); 722 $relationItems = $relationsDom->elementsByName( 'relation-item' ) ? $relationsDom->elementsByName( 'relation-item' ) : array(); 723 $isRelationModified = false; 724 foreach ( $relationItems as $relationItem ) 725 { 726 $allAttributes = $relationItem->attributes(); 727 $relatedNodeID = $relationItem->attributeValue('node-id'); 728 $relatedNode = eZContentObjectTreeNode::fetch( $relatedNodeID ); 729 $originalObjectID = $relatedNode->attribute('contentobject_id'); 730 $srcKey = array_search( (int) $originalObjectID, $syncObjectIDListSrc ); 731 if ( $srcKey !== false ) 732 { 733 $isRelationModified = true; 734 foreach( $allAttributes as $attribute ) 735 { 736 $attrName = $attribute->Name; 737 if( $attrName == 'contentobject-id' ) 738 { 739 $attribute->setContent( $syncObjectIDListNew[$srcKey] ); 740 } 741 if( $attrName == 'node-id' ) 742 { 743 $attribute->setContent( $syncNodeIDListNew[$srcKey] ); 744 } 745 if( $attrName == 'parent-node-id' ) 746 { 747 $attrContent = $attribute->Content; 748 $newNode = eZContentObjectTreeNode::fetch( $syncNodeIDListNew[$srcKey] ); 749 $attribute->setContent( $newNode->attribute( 'parent_node_id' ) ); 750 } 751 } 752 } 753 } 754 if ( $isRelationModified ) 755 { 756 $attributeID = $relationListAttribute->attribute( 'id' ); 757 $changedDomString =$db->escapeString( eZObjectRelationListType::domString( $relationsDom ) ); 758 $db->query( "UPDATE ezcontentobject_attribute SET data_text='$changedDomString' WHERE id=$attributeID" ); 759 } 760 } 761 } 762 763 eZDebug::writeDebug( "Successfuly DONE.", 764 "Copy subtree:" ); 765 766 $notifications['Notifications'][] = ezi18n( 'kernel/content/copysubtree', 767 "Successfuly DONE." ); 768 return $notifications; 769 } // function copySubtree END 770 771 /*! 772 Browse for node to place the object copy into 773 */ 774 function browse( &$Module, &$srcNode ) 775 { 776 if ( $Module->hasActionParameter( 'LanguageCode' ) ) 777 $languageCode = $Module->actionParameter( 'LanguageCode' ); 778 else 779 { 780 $languageCode = false; 781 } 782 783 $nodeID = $srcNode->attribute( 'node_id' ); 784 $object = $srcNode->attribute( 'object' ); 785 $objectID = $object->attribute( 'id' ); 786 $class = $object->contentClass(); 787 $classID = $class->attribute( 'id' ); 788 $srcParentNodeID = $srcNode->attribute( 'parent_node_id' ); 789 790 $ignoreNodesSelect = array(); 791 $ignoreNodesClick = array(); 792 foreach ( $object->assignedNodes( false ) as $element ) 793 { 794 $ignoreNodesSelect[] = $element['node_id']; 795 $ignoreNodesClick[] = $element['node_id']; 796 } 797 $ignoreNodesSelect = array_unique( $ignoreNodesSelect ); 798 $ignoreNodesClick = array_unique( $ignoreNodesClick ); 799 800 $viewMode = 'full'; 801 if ( $Module->hasActionParameter( 'ViewMode' ) ) 802 $viewMode = $module->actionParameter( 'ViewMode' ); 803 804 include_once ( 'kernel/classes/ezcontentbrowse.php' ); 805 eZContentBrowse::browse( 806 array( 'action_name' => 'CopySubtree', 807 'description_template' => 'design:content/browse_copy_subtree.tpl', 808 'keys' => array( 'class' => $classID, 809 'class_id' => $class->attribute( 'identifier' ), 810 'classgroup' => $class->attribute( 'ingroup_id_list' ), 811 'section' => $object->attribute( 'section_id' ) ), 812 'ignore_nodes_select' => $ignoreNodesSelect, 813 'ignore_nodes_click' => $ignoreNodesClick, 814 'persistent_data' => array( 'ObjectID' => $objectID, 815 'NodeID' => $nodeID ), 816 'permission' => array( 'access' => 'create', 'contentclass_id' => $classID ), 817 'content' => array( 'node_id' => $nodeID ), 818 'start_node' => $srcParentNodeID, 819 'cancel_page' => $Module->redirectionURIForModule( $Module, 'view', 820 array( $viewMode, $srcParentNodeID, $languageCode ) ), 821 'from_page' => "/content/copysubtree" ), 822 $Module ); 823 } 824 825 /*! 826 Redirect to the page that lets a user to choose which versions to copy: 827 either all version or the current one. 828 */ 829 function chooseOptionsToCopy( &$Module, &$Result, &$srcNode, $chooseVersions, $chooseCreator, $chooseTime ) 830 { 831 include_once ( 'kernel/classes/ezcontentbrowse.php' ); 832 $selectedNodeIDArray = eZContentBrowse::result( $Module->currentAction() ); 833 834 include_once ( 'kernel/common/template.php' ); 835 $tpl =& templateInit(); 836 837 $tpl->setVariable( 'node', $srcNode ); 838 $tpl->setVariable( 'selected_node_id', $selectedNodeIDArray[0] ); 839 $tpl->setVariable( 'choose_versions', $chooseVersions ); 840 $tpl->setVariable( 'choose_creator', $chooseCreator ); 841 $tpl->setVariable( 'choose_time', $chooseTime ); 842 843 $Result['content'] = $tpl->fetch( 'design:content/copy_subtree.tpl' ); 844 $Result['path'] = array( array( 'url' => false, 845 'text' => ezi18n( 'kernel/content', 'Content' ) ), 846 array( 'url' => false, 847 'text' => ezi18n( 'kernel/content', 'Copy Subtree' ) ) ); 848 } 849 850 function showNotificationAfterCopying( &$http, &$Module, &$Result, &$Notifications, &$srcNode ) 851 { 852 include_once ( 'kernel/common/template.php' ); 853 $tpl =& templateInit(); 854 855 if ( $http->hasSessionVariable( "LastAccessesURI" ) ) 856 { 857 $tpl->setVariable( 'redirect_url', $http->sessionVariable( "LastAccessesURI" ) ); 858 } 859 else 860 { 861 $parentRootNodeID = $srcNode->attribute( 'parent_node_id' ); 862 if ( $Module->hasActionParameter( 'LanguageCode' ) ) 863 $languageCode = $Module->actionParameter( 'LanguageCode' ); 864 else 865 { 866 $languageCode = false; 867 } 868 869 if ( $Module->hasActionParameter( 'ViewMode' ) ) 870 $viewMode = $module->actionParameter( 'ViewMode' ); 871 else 872 $viewMode = 'full'; 873 874 $redirectURI = $Module->redirectionURIForModule( $Module, 'view', array( $viewMode, $parentRootNodeID, $languageCode ) ); 875 $tpl->setVariable( 'redirect_url', $redirectURI ); 876 } 877 878 $tpl->setVariable( 'source_node', $srcNode ); 879 //$tpl->setVariable( 'subtree_nodes_count', $srcSubtreeNodesCount ); 880 $tpl->setVariable( 'notifications', $Notifications ); 881 882 $Result['content'] = $tpl->fetch( 'design:content/copy_subtree_notification.tpl' ); 883 $Result['path'] = array( array( 'url' => false, 884 'text' => ezi18n( 'kernel/content', 'Content' ) ), 885 array( 'url' => false, 886 'text' => ezi18n( 'kernel/content', 'Copy Subtree' ) ) ); 887 } 888 /////////// functions END ================================================================== 889 890 $Result = array(); 891 $notifications = array( 'Notifications' => array(), 892 'Warnings' => array(), 893 'Errors' => array() ); 894 $contentINI =& eZINI::instance( 'content.ini' ); 895 896 // check if number of nodes being copied not more then MaxNodesCopySubtree setting 897 $maxNodesCopySubtree = $contentINI->variable( 'CopySettings', 'MaxNodesCopySubtree' ); 898 $srcSubtreeNodesCount = $srcNode->subTreeCount(); 899 900 if ( $srcSubtreeNodesCount > $maxNodesCopySubtree ) 901 { 902 $notifications['Warnings'][] = ezi18n( 'kernel/content/copysubtree', 903 "You are trying to copy a subtree that contains more than ". 904 "the maximum possible nodes for subtree copying. ". 905 "You can copy this subtree using Subtree Copy script.", 906 null, array( $maxNodesCopySubtree ) ); 907 $notifications['Notifications'][] = ezi18n( 'kernel/content/copysubtree', 908 "Subtree was not copied." ); 909 910 showNotificationAfterCopying( $http, $Module, $Result, $notifications, $srcNode ); 911 return; 912 } 913 914 $versionHandling = $contentINI->variable( 'CopySettings', 'VersionHandling' ); 915 $creatorHandling = $contentINI->variable( 'CopySettings', 'CreatorHandling' ); 916 $timeHandling = $contentINI->variable( 'CopySettings', 'TimeHandling' ); 917 $showCopySubtreeNotification = $contentINI->variable( 'CopySettings', 'ShowCopySubtreeNotification' ); 918 919 $chooseVersions = ( $versionHandling == 'user-defined' ); 920 $chooseCreator = ( $creatorHandling == 'user-defined' ); 921 $chooseTime = ( $timeHandling == 'user-defined' ); 922 $showNotification = ( $showCopySubtreeNotification == 'enabled' ); 923 924 if( $chooseVersions ) 925 $allVersions = ( $Module->hasActionParameter( 'VersionChoice' ) and 926 $Module->actionParameter( 'VersionChoice' ) == 1 ) ? true : false; 927 else 928 $allVersions = ( $versionHandling == 'last-published' ) ? false : true; 929 930 if ( $chooseCreator ) 931 $keepCreator = ( $Module->hasActionParameter( 'CreatorChoice' ) and 932 $Module->actionParameter( 'CreatorChoice' ) == 1 ) ? true : false; 933 else 934 $keepCreator = ( $creatorHandling == 'keep-unchanged' ); 935 936 if ( $chooseTime ) 937 $keepTime = ( $Module->hasActionParameter( 'TimeChoice' ) and 938 $Module->actionParameter( 'TimeChoice' ) == 1 ) ? true : false; 939 else 940 $keepTime = ( $timeHandling == 'keep-unchanged' ); 941 942 943 $keepCreator = false; 944 $keepTime = false; 945 946 if ( $Module->isCurrentAction( 'Copy' ) ) 947 { 948 // actually do copying after a user has selected object versions to copy 949 $newParentNodeID = $http->postVariable( 'SelectedNodeID' ); 950 copySubtree( $NodeID, $newParentNodeID, $notifications, $allVersions, $keepCreator, $keepTime ); 951 952 if ( $showNotification ) 953 { 954 showNotificationAfterCopying( $http, $Module, $Result, $notifications, $srcNode ); 955 return; 956 } 957 return $Module->redirectToView( 'view', array( 'full', $newParentNodeID ) ); 958 } 959 else if ( $Module->isCurrentAction( 'CopySubtree' ) ) 960 { 961 // we get here after a user selects target node to place the source object under 962 if( $chooseVersions or $chooseCreator or $chooseTime ) 963 { 964 // redirect to the page with choice of versions to copy 965 chooseOptionsToCopy( $Module, $Result, $srcNode, $chooseVersions, $chooseCreator, $chooseTime ); 966 } 967 else 968 { 969 // actually do copying of the pre-configured object version(s) 970 include_once ( 'kernel/classes/ezcontentbrowse.php' ); 971 $selectedNodeIDArray = eZContentBrowse::result( $Module->currentAction() ); 972 $newParentNodeID =& $selectedNodeIDArray[0]; 973 copySubtree( $NodeID, $newParentNodeID, $notifications, $allVersions, $keepCreator, $keepTime ); 974 975 if ( $showNotification ) 976 { 977 showNotificationAfterCopying( $http, $Module, $Result, $notifications, $srcNode ); 978 return; 979 } 980 return $Module->redirectToView( 'view', array( 'full', $newParentNodeID ) ); 981 } 982 } 983 else // default, initial action 984 { //Browse for target node. 985 //We get here when a user clicks "copy" button when viewing some node. 986 browse( $Module, $srcNode ); 987 } 988 989 ?>
titre
Description
Corps
titre
Description
Corps
titre
Description
Corps
titre
Corps
Généré le : Sat Feb 24 10:30:04 2007 | par Balluche grâce à PHPXref 0.7 |