eZ Publish  [4.0]
fixobjectremoteid.php
Go to the documentation of this file.
00001 #!/usr/bin/env php
00002 <?php
00003 //
00004 // ## BEGIN COPYRIGHT, LICENSE AND WARRANTY NOTICE ##
00005 // SOFTWARE NAME: eZ Publish
00006 // SOFTWARE RELEASE: 4.0.x
00007 // COPYRIGHT NOTICE: Copyright (C) 1999-2008 eZ Systems AS
00008 // SOFTWARE LICENSE: GNU General Public License v2.0
00009 // NOTICE: >
00010 //   This program is free software; you can redistribute it and/or
00011 //   modify it under the terms of version 2.0  of the GNU General
00012 //   Public License as published by the Free Software Foundation.
00013 //
00014 //   This program is distributed in the hope that it will be useful,
00015 //   but WITHOUT ANY WARRANTY; without even the implied warranty of
00016 //   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017 //   GNU General Public License for more details.
00018 //
00019 //   You should have received a copy of version 2.0 of the GNU General
00020 //   Public License along with this program; if not, write to the Free
00021 //   Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
00022 //   MA 02110-1301, USA.
00023 //
00024 //
00025 // ## END COPYRIGHT, LICENSE AND WARRANTY NOTICE ##
00026 //
00027 
00028 if ( !function_exists( 'readline' ) )
00029 {
00030     function readline( $prompt = '' )
00031     {
00032         echo $prompt . ' ';
00033         return trim( fgets( STDIN ) );
00034     }
00035 }
00036 
00037 require 'autoload.php';
00038 
00039 $cli = eZCLI::instance();
00040 
00041 $scriptSettings = array();
00042 $scriptSettings['description'] = 'Fix non-unique usage of content object remote ID\'s';
00043 $scriptSettings['use-session'] = false;
00044 $scriptSettings['use-modules'] = false;
00045 $scriptSettings['use-extensions'] = false;
00046 
00047 $script = eZScript::instance( $scriptSettings );
00048 $script->startup();
00049 
00050 $config = '[mode:]';
00051 $argumentConfig = '';
00052 $optionHelp = array( 'mode' => "the fixing mode to use, either d (detailed) or a (automatic)" );
00053 $arguments = false;
00054 $useStandardOptions = true;
00055 
00056 $options = $script->getOptions( $config, $argumentConfig, $optionHelp, $arguments, $useStandardOptions );
00057 $script->initialize();
00058 
00059 if ( isset( $options['mode'] ) )
00060 {
00061     if ( !in_array( $options['mode'], array( 'a', 'd' ) ) )
00062     {
00063         $script->shutdown( 1, 'Invalid mode. Use either d for detailed or a for automatic.' );
00064     }
00065 
00066     $mode = $options['mode'];
00067 }
00068 else
00069 {
00070     $mode = false;
00071 }
00072 
00073 $db = eZDB::instance();
00074 
00075 $nonUniqueRemoteIDDataList = $db->arrayQuery( 'SELECT remote_id, COUNT(*) AS cnt FROM ezcontentobject GROUP BY remote_id HAVING COUNT(*) > 1' );
00076 
00077 $nonUniqueRemoteIDDataListCount = count( $nonUniqueRemoteIDDataList );
00078 
00079 $cli->output( '' );
00080 $cli->output( "Found $nonUniqueRemoteIDDataListCount non-unique content object remote IDs." );
00081 $cli->output( '' );
00082 
00083 $totalCount = 0;
00084 
00085 foreach ( $nonUniqueRemoteIDDataList as $nonUniqueRemoteIDData )
00086 {
00087     if ( $mode )
00088     {
00089         $cli->output( "Remote ID '$nonUniqueRemoteIDData[remote_id]' is used for $nonUniqueRemoteIDData[cnt] different content objects." );
00090         $action = $mode;
00091     }
00092     else
00093     {
00094         $action = readline( "Remote ID '$nonUniqueRemoteIDData[remote_id]' is used for $nonUniqueRemoteIDData[cnt] different content objects. Do you want to see the details (d) or do you want this inconsistency to be fixed automatically (a) ?" );
00095 
00096         while ( !in_array( $action, array( 'a', 'd' ) ) )
00097         {
00098             $action = readline( 'Invalid option. Type either d for details or a to fix automatically.' );
00099         }
00100     }
00101 
00102     $contentObjects = eZPersistentObject::fetchObjectList( eZContentObject::definition(),
00103                                                            null,
00104                                                            array( 'remote_id' => $nonUniqueRemoteIDData['remote_id'] ),
00105                                                            array( 'status' => 'desc', 'published' => 'asc' ) );
00106 
00107     switch ( $action )
00108     {
00109         case 'd':
00110         {
00111             $cli->output( '' );
00112             $cli->output( 'Select the number of the content object that you want to keep the current remote ID. The other listed content objects will get a new one.' );
00113             $cli->output( '' );
00114 
00115             foreach ( $contentObjects as $i => $contentObject )
00116             {
00117                 $status = $contentObject->attribute( 'status' );
00118                 $objectID = $contentObject->attribute( 'id' );
00119 
00120                 switch ( $status )
00121                 {
00122                     case eZContentObject::STATUS_PUBLISHED:
00123                     {
00124                         $dateTime = new eZDateTime( $contentObject->attribute( 'published' ) );
00125                         $formattedDateTime = $dateTime->toString( true );
00126                         $mainNode = $contentObject->attribute( 'main_node' );
00127                         $pathIdentificationString = $mainNode->attribute( 'path_identification_string' );
00128 
00129                         $message = "$pathIdentificationString (object ID: $objectID, published: $formattedDateTime )";
00130                     } break;
00131 
00132                     case eZContentObject::STATUS_DRAFT:
00133                     {
00134                         $message = "draft content object (object ID: $objectID )";
00135                     } break;
00136 
00137                     case eZContentObject::STATUS_ARCHIVED:
00138                     {
00139                         $message = "trashed content object (object ID: $objectID)";
00140                     } break;
00141 
00142                     default:
00143                     {
00144                         $script->shutdown( 2, "Impossible object status $status for object $objectID" );
00145                     }
00146                 }
00147 
00148                 $cli->output( "$i) $message" );
00149                 $cli->output( '' );
00150             }
00151 
00152             do {
00153                 $skip = readline( 'Number of object that should keep the current remote ID: ' );
00154             } while ( !array_key_exists( $skip, $contentObjects ) );
00155         } break;
00156 
00157         case 'a':
00158         default:
00159         {
00160             $skip = 0;
00161         }
00162     }
00163 
00164     $cli->output( 'Fixing...' );
00165 
00166     foreach ( $contentObjects as $i => $contentObject )
00167     {
00168         if ( $i == $skip )
00169         {
00170             continue;
00171         }
00172 
00173         $newRemoteID = md5( (string)mt_rand() . (string)time() );
00174         $contentObject->setAttribute( 'remote_id', $newRemoteID );
00175         $contentObject->store();
00176     }
00177 
00178     $totalCount += $nonUniqueRemoteIDData['cnt'] - 1;
00179 
00180     $cli->output( '' );
00181     $cli->output( '' );
00182 }
00183 
00184 $cli->output( "Number of content objects that received a new remote ID : $totalCount" );
00185 
00186 $script->shutdown( 0 );
00187 
00188 ?>