eZ Publish  [4.0]
ezsubtreecopy.php
Go to the documentation of this file.
00001 #!/usr/bin/env php
00002 <?php
00003 //
00004 // Created on: <20-Feb-2005 15:00:00 rl>
00005 //
00006 // ## BEGIN COPYRIGHT, LICENSE AND WARRANTY NOTICE ##
00007 // SOFTWARE NAME: eZ Publish
00008 // SOFTWARE RELEASE: 4.0.x
00009 // COPYRIGHT NOTICE: Copyright (C) 1999-2008 eZ Systems AS
00010 // SOFTWARE LICENSE: GNU General Public License v2.0
00011 // NOTICE: >
00012 //   This program is free software; you can redistribute it and/or
00013 //   modify it under the terms of version 2.0  of the GNU General
00014 //   Public License as published by the Free Software Foundation.
00015 //
00016 //   This program is distributed in the hope that it will be useful,
00017 //   but WITHOUT ANY WARRANTY; without even the implied warranty of
00018 //   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00019 //   GNU General Public License for more details.
00020 //
00021 //   You should have received a copy of version 2.0 of the GNU General
00022 //   Public License along with this program; if not, write to the Free
00023 //   Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
00024 //   MA 02110-1301, USA.
00025 //
00026 //
00027 // ## END COPYRIGHT, LICENSE AND WARRANTY NOTICE ##
00028 //
00029 
00030 // Subtree Copy Script
00031 // file  bin/php/ezsubtreecopy.php
00032 
00033 // script initializing
00034 //include_once( 'lib/ezutils/classes/ezcli.php' );
00035 //include_once( 'kernel/classes/ezscript.php' );
00036 
00037 require 'autoload.php';
00038 
00039 $cli = eZCLI::instance();
00040 $script = eZScript::instance( array( 'description' => ( "\n" .
00041                                                          "This script will make a copy of a content object subtree and place it in a specified\n" .
00042                                                          "location.\n" ),
00043                                       'use-session' => false,
00044                                       'use-modules' => true,
00045                                       'use-extensions' => true,
00046                                       'user' => true ) );
00047 $script->startup();
00048 
00049 $scriptOptions = $script->getOptions( "[src-node-id:][dst-node-id:][all-versions][keep-creator][keep-time]",
00050                                       "",
00051                                       array( 'src-node-id' => "Source subtree parent node ID.",
00052                                              'dst-node-id' => "Destination node ID.",
00053                                              'all-versions' => "Copy all versions for each contentobject being copied.",
00054                                              'keep-creator'=> "Do not change the creator (user) for the copied content objects.",
00055                                              'keep-time'   => "Do not change the creation and modification time of the copied content objects."
00056                                              ),
00057                                       false,
00058                                       array( 'user' => true )
00059                                      );
00060 $script->initialize();
00061 
00062 $srcNodeID   = $scriptOptions[ 'src-node-id' ] ? $scriptOptions[ 'src-node-id' ] : false;
00063 $dstNodeID   = $scriptOptions[ 'dst-node-id' ] ? $scriptOptions[ 'dst-node-id' ] : false;
00064 $allVersions = $scriptOptions[ 'all-versions' ];
00065 $keepCreator = $scriptOptions[ 'keep-creator' ];
00066 $keepTime    = $scriptOptions[ 'keep-time' ];
00067 
00068 //include_once( "lib/ezdb/classes/ezdb.php" );
00069 //include_once( "kernel/classes/ezcontentobjecttreenode.php" );
00070 
00071 function copyPublishContentObject( $sourceObject,
00072                                    $sourceSubtreeNodeIDList,
00073                                    &$syncNodeIDListSrc, &$syncNodeIDListNew,
00074                                    &$syncObjectIDListSrc, &$syncObjectIDListNew,
00075                                    $allVersions = false, $keepCreator = false, $keepTime = false )
00076 {
00077     global $cli;
00078 
00079     $sourceObjectID = $sourceObject->attribute( 'id' );
00080 
00081     $key = array_search( $sourceObjectID, $syncObjectIDListSrc );
00082     if ( $key !== false )
00083     {
00084         return 1; // object already copied
00085     }
00086 
00087     $srcNodeList = $sourceObject->attribute( 'assigned_nodes' );
00088 
00089     // check if all parent nodes for given contentobject are already published:
00090     foreach ( $srcNodeList as $srcNode )
00091     {
00092         $sourceParentNodeID = $srcNode->attribute( 'parent_node_id' );
00093 
00094         // if parent node for this node is outside
00095         // of subtree being copied, then skip this node.
00096         $key = array_search( $sourceParentNodeID, $sourceSubtreeNodeIDList );
00097         if ( $key === false )
00098         {
00099             continue;
00100         }
00101 
00102         $key = array_search( $sourceParentNodeID, $syncNodeIDListSrc );
00103         if ( $key === false )
00104         {
00105             return 2; // one of parent nodes is not published yet - have to try to publish later.
00106         }
00107         else
00108         {
00109             $newParentNodeID = $syncNodeIDListNew[ $key ];
00110             if ( ( $newParentNode = eZContentObjectTreeNode::fetch( $newParentNodeID ) ) === null )
00111             {
00112                 return 3; // cannot fetch one of parent nodes - must be error somewhere above.
00113             }
00114         }
00115     }
00116 
00117     // make copy of source object
00118     $newObject             = $sourceObject->copy( $allVersions ); // insert source and new object's ids in $syncObjectIDList
00119     // We should reset section that will be updated in updateSectionID().
00120     // If sectionID is 0 than the object has been newly created
00121     $newObject->setAttribute( 'section_id', 0 );
00122     $newObject->store();
00123 
00124     $syncObjectIDListSrc[] = $sourceObjectID;
00125     $syncObjectIDListNew[] = $newObject->attribute( 'id' );
00126 
00127     $curVersion        = $newObject->attribute( 'current_version' );
00128     $curVersionObject  = $newObject->attribute( 'current' );
00129 
00130     $newObjAssignments = $curVersionObject->attribute( 'node_assignments' );
00131 
00132     // copy nodeassigments:
00133     $assignmentsForRemoving = array();
00134     $foundMainAssignment = false;
00135     foreach ( $newObjAssignments as $assignment )
00136     {
00137         $parentNodeID = $assignment->attribute( 'parent_node' );
00138 
00139         // if assigment is outside of subtree being copied then do not copy this assigment
00140         $key = array_search( $parentNodeID, $sourceSubtreeNodeIDList );
00141         if ( $key === false )
00142         {
00143             $assignmentsForRemoving[] = $assignment->attribute( 'id' );
00144             continue;
00145         }
00146 
00147         $key = array_search( $parentNodeID, $syncNodeIDListSrc );
00148         if ( $key === false )
00149         {
00150             $cli->error( "Subtree Copy Error!\nOne of parent nodes for contentobject (ID = $sourceObjectID) is not published yet." );
00151             return 4;
00152         }
00153 
00154         if ( $assignment->attribute( 'is_main' ) )
00155             $foundMainAssignment = true;
00156 
00157         $newParentNodeID = $syncNodeIDListNew[ $key ];
00158         $assignment->setAttribute( 'parent_node', $newParentNodeID );
00159         $assignment->store();
00160     }
00161     // remove assigments which are outside of subtree being copied:
00162     eZNodeAssignment::purgeByID( $assignmentsForRemoving ); // JB valid
00163 
00164     // if main nodeassigment was not copied then set as main first nodeassigment
00165     if ( $foundMainAssignment == false )
00166     {
00167         $newObjAssignments = $curVersionObject->attribute( 'node_assignments' );
00168         // JB start
00169         // We need to check if it has any assignments before changing the data.
00170         if ( isset( $newObjAssignments[0] ) )
00171         {
00172             $newObjAssignments[0]->setAttribute( 'is_main', 1 );
00173             $newObjAssignments[0]->store();
00174         }
00175         // JB end
00176     }
00177 
00178     // publish the newly created object
00179     //include_once( 'lib/ezutils/classes/ezoperationhandler.php' );
00180     $result = eZOperationHandler::execute( 'content', 'publish', array( 'object_id' => $newObject->attribute( 'id' ),
00181                                                                         'version'   => $curVersion ) );
00182     // JB start
00183     // Refetch the object data since it might change in the database.
00184     $newObjectID = $newObject->attribute( 'id' );
00185     $newObject = eZContentObject::fetch( $newObjectID );
00186     // JB end
00187     $newNodeList = $newObject->attribute( 'assigned_nodes' );
00188     if ( count($newNodeList) == 0 )
00189     {
00190         $newObject->purge();
00191         $cli->error( "Subtree Copy Error!\nCannot publish contentobject." );
00192         return 5;
00193     }
00194 
00195     $objAssignments = $curVersionObject->attribute( 'node_assignments' );
00196     foreach ( $newNodeList as $newNode )
00197     {
00198         $newParentNodeID = $newNode->attribute( 'parent_node_id' );
00199         $keyA = array_search( $newParentNodeID, $syncNodeIDListNew );
00200 
00201         if ( $keyA === false )
00202         {
00203             die( "Copy Subtree Error: Algoritm ERROR! Cannot find new parent node ID in new ID's list" );
00204         }
00205 
00206         $srcParentNodeID = $syncNodeIDListSrc[ $keyA ];
00207 
00208         // Update attributes of node
00209         $bSrcParentFound = false;
00210         foreach ( $srcNodeList as $srcNode )
00211         {
00212             if ( $srcNode->attribute( 'parent_node_id' ) == $srcParentNodeID )
00213             {
00214                 $newNode->setAttribute( 'priority',     $srcNode->attribute( 'priority' ) );
00215                 $newNode->setAttribute( 'is_hidden',    $srcNode->attribute( 'is_hidden' ) );
00216                 $newNode->setAttribute( 'is_invisible', $srcNode->attribute( 'is_invisible' ) );
00217                 $syncNodeIDListSrc[] = $srcNode->attribute( 'node_id' );
00218                 $syncNodeIDListNew[] = $newNode->attribute( 'node_id' );
00219                 $bSrcParentFound = true;
00220                 break;
00221             }
00222         }
00223         if ( $bSrcParentFound == false )
00224         {
00225             die( "Copy Subtree Error: Algoritm ERROR! Cannot find source parent node ID in source parent node ID's list of contentobject being copied." );
00226         }
00227         // Create unique remote_id
00228         $newRemoteID = md5( (string)mt_rand() . (string)time() );
00229         $oldRemoteID = $newNode->attribute( 'remote_id' );
00230         $newNode->setAttribute( 'remote_id', $newRemoteID );
00231         // Change parent_remote_id for object assignments
00232         foreach ( $objAssignments as $assignment )
00233         {
00234             if ( $assignment->attribute( 'parent_remote_id' ) == $oldRemoteID )
00235             {
00236                  $assignment->setAttribute( 'parent_remote_id', $newRemoteID );
00237                  $assignment->store();
00238             }
00239         }
00240         $newNode->store();
00241     }
00242 
00243     // Update "is_invisible" attribute for the newly created node.
00244     $newNode = $newObject->attribute( 'main_node' );
00245     eZContentObjectTreeNode::updateNodeVisibility( $newNode, $newParentNode ); // ??? do we need this here?
00246 
00247     // if $keepCreator == true then keep owner of contentobject being
00248     // copied and creator of its published version Unchaged
00249     $isModified = false;
00250     if ( $keepTime )
00251     {
00252         $srcPublished = $sourceObject->attribute( 'published' );
00253         $newObject->setAttribute( 'published', $srcPublished );
00254         $srcModified  = $sourceObject->attribute( 'modified' );
00255         $newObject->setAttribute( 'modified', $srcModified );
00256         $isModified = true;
00257     }
00258     if ( $keepCreator )
00259     {
00260         $srcOwnerID = $sourceObject->attribute( 'owner_id' );
00261         $newObject->setAttribute( 'owner_id', $srcOwnerID );
00262         $isModified = true;
00263     }
00264     if ( $isModified )
00265         $newObject->store();
00266 
00267     if ( $allVersions )
00268     {   // copy time of creation and modification and creator id for
00269         // all versions of content object being copied.
00270         $srcVersionsList = $sourceObject->versions();
00271 
00272         foreach ( $srcVersionsList as $srcVersionObject )
00273         {
00274             $newVersionObject = $newObject->version( $srcVersionObject->attribute( 'version' ) );
00275             if ( !is_object( $newVersionObject ) )
00276                 continue;
00277 
00278             $isModified = false;
00279             if ( $keepTime )
00280             {
00281                 $srcVersionCreated  = $srcVersionObject->attribute( 'created' );
00282                 $newVersionObject->setAttribute( 'created', $srcVersionCreated );
00283                 $srcVersionModified = $srcVersionObject->attribute( 'modified' );
00284                 $newVersionObject->setAttribute( 'modified', $srcVersionModified );
00285                 $isModified = true;
00286             }
00287             if ( $keepCreator )
00288             {
00289                 $srcVersionCreatorID = $srcVersionObject->attribute( 'creator_id' );
00290                 $newVersionObject->setAttribute( 'creator_id', $srcVersionCreatorID );
00291 
00292                 $isModified = true;
00293             }
00294             if ( $isModified )
00295                 $newVersionObject->store();
00296         }
00297     }
00298     else // if not all versions copied
00299     {
00300         $srcVersionObject = $sourceObject->attribute( 'current' );
00301         $newVersionObject = $newObject->attribute( 'current' );
00302 
00303         $isModified = false;
00304         if ( $keepTime )
00305         {
00306             $srcVersionCreated  = $srcVersionObject->attribute( 'created' );
00307             $newVersionObject->setAttribute( 'created', $srcVersionCreated );
00308             $srcVersionModified = $srcVersionObject->attribute( 'modified' );
00309             $newVersionObject->setAttribute( 'modified', $srcVersionModified );
00310             $isModified = true;
00311         }
00312         if ( $keepCreator )
00313         {
00314             $srcVersionCreatorID = $srcVersionObject->attribute( 'creator_id' );
00315             $newVersionObject->setAttribute( 'creator_id', $srcVersionCreatorID );
00316             $isModified = true;
00317         }
00318         if ( $isModified )
00319             $newVersionObject->store();
00320     }
00321 
00322     return 0; // source object was copied successfully.
00323 
00324 }   //function copyPublishContentObject END
00325 
00326 
00327 
00328 // 1. Copy subtree and form the arrays of accordance of the old and new nodes and content objects.
00329 
00330 $sourceSubTreeMainNode = ( $srcNodeID ) ? eZContentObjectTreeNode::fetch( $srcNodeID ) : false;
00331 $destinationNode = ( $dstNodeID ) ? eZContentObjectTreeNode::fetch( $dstNodeID ) : false;
00332 
00333 if ( !$sourceSubTreeMainNode )
00334 {
00335     $cli->error( "Subtree copy Error!\nCannot get subtree main node. Please check src-node-id argument and try again." );
00336     $script->showHelp();
00337     $script->shutdown( 1 );
00338 }
00339 if ( !$destinationNode )
00340 {
00341     $cli->error( "Subtree copy Error!\nCannot get destination node. Please check dst-node-id argument and try again." );
00342     $script->showHelp();
00343     $script->shutdown( 1 );
00344 }
00345 
00346 $sourceNodeList    = array();
00347 $syncNodeIDListSrc = array();
00348 $syncNodeIDListNew = array();
00349 
00350 $sourceSubTreeMainNodeID = $sourceSubTreeMainNode->attribute( 'node_id' );
00351 $sourceNodeList[] = $sourceSubTreeMainNode;
00352 
00353 $syncNodeIDListSrc[] = $sourceSubTreeMainNode->attribute( 'parent_node_id' );
00354 $syncNodeIDListNew[] = (int) $dstNodeID;
00355 
00356 $syncObjectIDListSrc = array();
00357 $syncObjectIDListNew = array();
00358 
00359 $sourceNodeList = array_merge( $sourceNodeList, eZContentObjectTreeNode::subTreeByNodeID( false, $sourceSubTreeMainNodeID ) );
00360 $countNodeList = count( $sourceNodeList );
00361 
00362 // Prepare list of source node IDs. We will need it in the future
00363 // for checking node is inside or outside of the subtree being copied.
00364 $sourceNodeIDList = array();
00365 foreach ( $sourceNodeList as $sourceNode )
00366     $sourceNodeIDList[] = $sourceNode->attribute( 'node_id' );
00367 
00368 $cli->output( "Copying subtree:" );
00369 
00370 $k = 0;
00371 while ( count( $sourceNodeList ) > 0 )
00372 {
00373     if ( $k > $countNodeList )
00374     {
00375         $cli->error( "Subtree Copy Error!\nToo many loops while copying nodes." );
00376         $script->shutdown( 6 );
00377     }
00378 
00379     for ( $i = 0; $i < count( $sourceNodeList ); $i)
00380     {
00381         $sourceNodeID = $sourceNodeList[ $i ]->attribute( 'node_id' );
00382 
00383         if ( in_array( $sourceNodeID, $syncNodeIDListSrc ) )
00384             array_splice( $sourceNodeList, $i, 1 );
00385         else
00386         {
00387             $sourceObject =& $sourceNodeList[ $i ]->object();
00388             $srcSubtreeNodeIDlist = ($sourceNodeID == $sourceSubTreeMainNodeID) ? $syncNodeIDListSrc : $sourceNodeIDList;
00389 
00390             $copyResult = copyPublishContentObject( $sourceObject,
00391                                                     $srcSubtreeNodeIDlist,
00392                                                     $syncNodeIDListSrc, $syncNodeIDListNew,
00393                                                     $syncObjectIDListSrc, $syncObjectIDListNew,
00394                                                     $allVersions, $keepCreator, $keepTime );
00395             if ( $copyResult === 0 )
00396             {   // if copying successful then remove $sourceNode from $sourceNodeList
00397                 array_splice( $sourceNodeList, $i, 1 );
00398                 $cli->output( ".", false );
00399             }
00400             else
00401                 $i++;
00402         }
00403     }
00404     $k++;
00405 }
00406 
00407 array_shift( $syncNodeIDListSrc );
00408 array_shift( $syncNodeIDListNew );
00409 
00410 $cli->output( "\nNumber of copied nodes: " . count( $syncNodeIDListNew ) );
00411 $cli->output( "Number of copied contentobjects: " . count( $syncObjectIDListNew ) );
00412 
00413 // 2. fetch all new subtree
00414 
00415 $key = array_search( $sourceSubTreeMainNodeID, $syncNodeIDListSrc );
00416 if ( $key === false )
00417 {
00418     $cli->error( "Subtree copy Error!\nCannot find subtree root node in array of IDs of copied nodes." );
00419     $script->shutdown( 1 );
00420 }
00421 
00422 $newSubTreeMainNodeID = $syncNodeIDListSrc[ $key ];
00423 $newSubTreeMainNode   = eZContentObjectTreeNode::fetch( $newSubTreeMainNodeID );
00424 
00425 $newNodeList[] = $newSubTreeMainNode;
00426 $newNodeList = $sourceNodeList = array_merge( $newNodeList,
00427                                               eZContentObjectTreeNode::subTreeByNodeID( false, $newSubTreeMainNodeID ) );
00428 
00429 $cli->output( "Fixing global and local links..." );
00430 
00431 // 3. fix local links (in ezcontentobject_link)
00432 
00433 $db = eZDB::instance();
00434 
00435 if ( !$db )
00436 {
00437     $cli->error( "Subtree Copy Error!\nCannot create instance of eZDB for fixing local links (related objects)." );
00438     $script->shutdown( 3 );
00439 }
00440 
00441 $idListStr = implode( ',', $syncObjectIDListNew );
00442 $relatedRecordsList = $db->arrayQuery( "SELECT * FROM ezcontentobject_link WHERE from_contentobject_id IN ($idListStr)" );
00443 
00444 foreach ( $relatedRecordsList as $relatedEntry )
00445 {
00446     $kindex = array_search( $relatedEntry[ 'to_contentobject_id' ], $syncObjectIDListSrc );
00447     if ( $kindex !== false )
00448     {
00449         $newToContentObjectID = $syncObjectIDListNew[ $kindex ];
00450         $linkID = $relatedEntry[ 'id' ];
00451         $db->query( "UPDATE ezcontentobject_link SET  to_contentobject_id=$newToContentObjectID WHERE id=$linkID" );
00452     }
00453 }
00454 
00455 // 4. duplicating of global links for new contentobjects (in ezurl_object_link) are automatic during copy of contentobject.
00456 
00457 // 5. loop on new nodes and REPLACE node_ids and object_ids
00458 
00459 $conditions = array( 'contentobject_id' => '', // 5
00460                      'data_type_string' => 'ezxmltext' );
00461 
00462 foreach ( $syncObjectIDListNew as $contentObjectID )
00463 {
00464     $conditions[ 'contentobject_id' ] = $contentObjectID;
00465     $attributeList = eZPersistentObject::fetchObjectList( eZContentObjectAttribute::definition(), null, $conditions );
00466     if ( count( $attributeList ) == 0 )
00467     {
00468         continue;
00469     }
00470     foreach ( $attributeList as $xmlAttribute )
00471     {
00472         $xmlText = $xmlAttribute->attribute( 'data_text' );
00473         $xmlTextLen = strlen ( $xmlText );
00474         $isTextModified = false;
00475         $curPos = 0;
00476 
00477         while ( $curPos < $xmlTextLen )
00478         {
00479             // JK: find out what is the first tag
00480             // This is not the optimal solution, there is better way how to do. This is just a quick fix.
00481             $tmpArray = array();
00482             if ( $literalTagBeginPos = strpos( $xmlText, "<literal", $curPos ) )
00483                 $tmpArray[] = $literalTagBeginPos;
00484             if ( $linkTagBeginPos = strpos( $xmlText, "<link", $curPos ) )
00485                 $tmpArray[] = $linkTagBeginPos;
00486             if ( $aTagBeginPos = strpos( $xmlText, "<a", $curPos ) )
00487                 $tmpArray[] = $aTagBeginPos;
00488             if ( $embedTagBeginPos = strpos( $xmlText, "<embed", $curPos ) )
00489                 $tmpArray[] = $embedTagBeginPos;
00490             if ( $objectTagBeginPos = strpos( $xmlText, "<object", $curPos ) )
00491                 $tmpArray[] = $objectTagBeginPos;
00492 
00493             if ( !$tmpArray )
00494             {
00495                 break;
00496             }
00497 
00498             $tagBeginPos = min( $tmpArray );
00499 
00500             if ( $tagBeginPos == $literalTagBeginPos )
00501             {
00502                 $literalTagEndPos = strpos( $xmlText, "</literal>", $literalTagBeginPos );
00503                 if ( $literalTagEndPos === false )
00504                     break;
00505                 $curPos = $literalTagEndPos + 9;
00506             }
00507 
00508             if ( $tagBeginPos == $linkTagBeginPos || $tagBeginPos == $aTagBeginPos || $tagBeginPos == $embedTagBeginPos )
00509             {
00510                 $tagEndPos = strpos( $xmlText, ">", $tagBeginPos + 1 );
00511                 if ( $tagEndPos === false )
00512                     break;
00513 
00514                 $tagText = substr( $xmlText, $tagBeginPos, $tagEndPos - $tagBeginPos );
00515 
00516                 if ( ($nodeIDAttributePos = strpos( $tagText, " node_id=\"" )) !== false )
00517                 {
00518                     $idNumberPos = $nodeIDAttributePos + 10;
00519                     $quoteEndPos = strpos( $tagText, "\"", $idNumberPos );
00520 
00521                     if ( $quoteEndPos !== false )
00522                     {
00523                         $idNumber = substr( $tagText, $idNumberPos, $quoteEndPos - $idNumberPos );
00524                         $key = array_search( (int) $idNumber, $syncNodeIDListSrc );
00525 
00526                         if ( $key !== false )
00527                         {
00528                             $tagText = substr_replace( $tagText, (string) $syncNodeIDListNew[ $key ], $idNumberPos, $quoteEndPos - $idNumberPos );
00529                             $xmlText = substr_replace( $xmlText, $tagText, $tagBeginPos, $tagEndPos - $tagBeginPos );
00530                             $isTextModified = true;
00531                         }
00532                     }
00533                 }
00534                 else if ( ($objectIDAttributePos = strpos( $tagText, " object_id=\"" )) !== false )
00535                 {
00536                     $idNumberPos = $objectIDAttributePos + 12;
00537                     $quoteEndPos = strpos( $tagText, "\"", $idNumberPos );
00538 
00539                     if ( $quoteEndPos !== false )
00540                     {
00541                         $idNumber = substr( $tagText, $idNumberPos, $quoteEndPos - $idNumberPos );
00542                         $key = array_search( (int) $idNumber, $syncObjectIDListSrc );
00543                         if ( $key !== false )
00544                         {
00545                             $tagText = substr_replace( $tagText, (string) $syncObjectIDListNew[ $key ], $idNumberPos, $quoteEndPos - $idNumberPos );
00546                             $xmlText = substr_replace( $xmlText, $tagText, $tagBeginPos, $tagEndPos - $tagBeginPos );
00547                             $isTextModified = true;
00548                         }
00549                     }
00550                 }
00551                 $curPos = $tagEndPos;
00552             }
00553             else if ( $tagBeginPos == $objectTagBeginPos )
00554             {
00555                 $tagEndPos = strpos( $xmlText, ">", $tagBeginPos + 1 );
00556                 if ( !$tagEndPos )
00557                     break;
00558 
00559                 $tagText = substr( $xmlText, $tagBeginPos, $tagEndPos - $tagBeginPos );
00560 
00561                 if ( ($idAttributePos = strpos( $tagText, " id=\"" )) !== false )
00562                 {
00563                     $idNumberPos = $idAttributePos + 5;
00564                     $quoteEndPos = strpos( $tagText, "\"", $idNumberPos );
00565 
00566                     if ( $quoteEndPos !== false )
00567                     {
00568                         $idNumber = substr( $tagText, $idNumberPos, $quoteEndPos - $idNumberPos );
00569                         $key = array_search( (int) $idNumber, $syncObjectIDListSrc );
00570                         if ( $key !== false )
00571                         {
00572                             $tagText = substr_replace( $tagText, (string) $syncObjectIDListNew[ $key ], $idNumberPos, $quoteEndPos - $idNumberPos );
00573                             $xmlText = substr_replace( $xmlText, $tagText, $tagBeginPos, $tagEndPos - $tagBeginPos );
00574                             $isTextModified = true;
00575                         }
00576                     }
00577                 }
00578                 $curPos = $tagEndPos;
00579             }
00580 
00581         } // while END
00582 
00583         if ( $isTextModified )
00584         {
00585             $xmlAttribute->setAttribute( 'data_text', $xmlText );
00586             $xmlAttribute->store();
00587         }
00588     } // foreach END
00589 }
00590 
00591 // 6. fixing datatype ezobjectrelationlist
00592 $conditions = array( 'contentobject_id' => '',
00593                      'data_type_string' => 'ezobjectrelationlist' );
00594 foreach ( $syncObjectIDListNew as $contentObjectID )
00595 {
00596     $conditions[ 'contentobject_id' ] = $contentObjectID;
00597     $attributeList = eZPersistentObject::fetchObjectList( eZContentObjectAttribute::definition(), null, $conditions );
00598     if ( count( $attributeList ) == 0 )
00599     {
00600         continue;
00601     }
00602     foreach ( $attributeList as $relationListAttribute )
00603     {
00604         $relationsXmlText = $relationListAttribute->attribute( 'data_text' );
00605         $relationsDom = eZObjectRelationListType::parseXML( $relationsXmlText );
00606         $relationItems = $relationsDom->getElementsByTagName( 'relation-item' );
00607         $isRelationModified = false;
00608 
00609         foreach ( $relationItems as $relationItem )
00610         {
00611             $originalObjectID = $relationItem->getAttribute( 'contentobject-id' );
00612 
00613             $key = array_search( $originalObjectID, $syncObjectIDListSrc );
00614             if ( $key !== false )
00615             {
00616                 $newObjectID = $syncObjectIDListNew[ $key ];
00617                 $relationItem->setAttribute( 'contentobject-id', $newObjectID );
00618                 $isRelationModified = true;
00619             }
00620 
00621             $originalNodeID = $relationItem->getAttribute( 'node-id' );
00622             if ( $originalNodeID )
00623             {
00624                 $key = array_search( $originalNodeID, $syncNodeIDListSrc );
00625                 if ( $key !== false )
00626                 {
00627                     $newNodeID = $syncNodeIDListNew[ $key ];
00628                     $relationItem->setAttribute( 'node-id', $newNodeID );
00629 
00630                     $newNode = eZContentObjectTreeNode::fetch( $newNodeID );
00631                     $newParentNodeID = $newNode->attribute( 'parent_node_id' );
00632                     $relationItem->setAttribute( 'parent-node-id', $newParentNodeID );
00633                     $isRelationModified = true;
00634                 }
00635             }
00636         }
00637         if ( $isRelationModified )
00638         {
00639             $attributeID = $relationListAttribute->attribute( 'id' );
00640             $attributeVersion = $relationListAttribute->attribute( 'version' );
00641             $changedDomString =$db->escapeString( eZObjectRelationListType::domString( $relationsDom ) );
00642             $db->query( "UPDATE ezcontentobject_attribute SET data_text='$changedDomString'
00643                          WHERE id=$attributeID AND version=$attributeVersion" );
00644         }
00645     }
00646 }
00647 
00648 $cli->output( "Done." );
00649 
00650 $script->shutdown();
00651 
00652 ?>