eZ Publish  [trunk]
copy.php
Go to the documentation of this file.
00001 <?php
00002 /**
00003  * @copyright Copyright (C) 1999-2012 eZ Systems AS. All rights reserved.
00004  * @license http://www.gnu.org/licenses/gpl-2.0.txt GNU General Public License v2
00005  * @version //autogentag//
00006  * @package kernel
00007  */
00008 
00009 $Module = $Params['Module'];
00010 $ObjectID = $Params['ObjectID'];
00011 
00012 $http = eZHTTPTool::instance();
00013 
00014 if ( $http->hasPostVariable( 'BrowseCancelButton' ) )
00015 {
00016     if ( $http->hasPostVariable( 'BrowseCancelURI' ) )
00017     {
00018         return $Module->redirectTo( $http->postVariable( 'BrowseCancelURI' ) );
00019     }
00020 }
00021 
00022 if ( $ObjectID === null )
00023 {
00024     // ObjectID is returned after browsing
00025     $ObjectID = $http->postVariable( 'ObjectID' );
00026 }
00027 
00028 $object = eZContentObject::fetch( $ObjectID );
00029 
00030 if ( $object === null )
00031     return $Module->handleError( eZError::KERNEL_NOT_AVAILABLE, 'kernel' );
00032 
00033 if ( !$object->attribute( 'can_read' ) )
00034     return $Module->handleError( eZError::KERNEL_ACCESS_DENIED, 'kernel' );
00035 
00036 if ( $Module->isCurrentAction( 'Cancel' ) )
00037 {
00038     $mainParentNodeID = $object->attribute( 'main_parent_node_id' );
00039     return $Module->redirectToView( 'view', array( 'full', $mainParentNodeID ) );
00040 }
00041 
00042 $contentINI = eZINI::instance( 'content.ini' );
00043 
00044 /*!
00045  Copy the specified object to a given node
00046 */
00047 function copyObject( $Module, $object, $allVersions, $newParentNodeID )
00048 {
00049     if ( !$newParentNodeID )
00050         return $Module->redirectToView( 'view', array( 'full', 2 ) );
00051 
00052     // check if we can create node under the specified parent node
00053     if( ( $newParentNode = eZContentObjectTreeNode::fetch( $newParentNodeID ) ) === null )
00054         return $Module->redirectToView( 'view', array( 'full', 2 ) );
00055 
00056     $classID = $object->attribute('contentclass_id');
00057 
00058     if ( !$newParentNode->checkAccess( 'create', $classID ) )
00059     {
00060         $objectID = $object->attribute( 'id' );
00061         eZDebug::writeError( "Cannot copy object $objectID to node $newParentNodeID, " .
00062                                "the current user does not have create permission for class ID $classID",
00063                              'content/copy' );
00064         return $Module->handleError( eZError::KERNEL_ACCESS_DENIED, 'kernel' );
00065     }
00066 
00067     $db = eZDB::instance();
00068     $db->begin();
00069     $newObject = $object->copy( $allVersions );
00070     // We should reset section that will be updated in updateSectionID().
00071     // If sectionID is 0 then the object has been newly created
00072     $newObject->setAttribute( 'section_id', 0 );
00073     $newObject->store();
00074 
00075     $curVersion        = $newObject->attribute( 'current_version' );
00076     $curVersionObject  = $newObject->attribute( 'current' );
00077     $newObjAssignments = $curVersionObject->attribute( 'node_assignments' );
00078     unset( $curVersionObject );
00079 
00080     // remove old node assignments
00081     foreach( $newObjAssignments as $assignment )
00082     {
00083         $assignment->purge();
00084     }
00085 
00086     // and create a new one
00087     $nodeAssignment = eZNodeAssignment::create( array(
00088                                                      'contentobject_id' => $newObject->attribute( 'id' ),
00089                                                      'contentobject_version' => $curVersion,
00090                                                      'parent_node' => $newParentNodeID,
00091                                                      'is_main' => 1
00092                                                      ) );
00093     $nodeAssignment->store();
00094 
00095     // publish the newly created object
00096     eZOperationHandler::execute( 'content', 'publish', array( 'object_id' => $newObject->attribute( 'id' ),
00097                                                               'version'   => $curVersion ) );
00098     // Update "is_invisible" attribute for the newly created node.
00099     $newNode = $newObject->attribute( 'main_node' );
00100     eZContentObjectTreeNode::updateNodeVisibility( $newNode, $newParentNode );
00101 
00102     $db->commit();
00103     return $Module->redirectToView( 'view', array( 'full', $newParentNodeID ) );
00104 }
00105 
00106 /*!
00107 Browse for node to place the object copy into
00108 */
00109 function browse( $Module, $object )
00110 {
00111     if ( $Module->hasActionParameter( 'LanguageCode' ) )
00112         $languageCode = $Module->actionParameter( 'LanguageCode' );
00113     else
00114     {
00115         $languageCode = false;
00116     }
00117 
00118     $objectID = $object->attribute( 'id' );
00119     $node     = $object->attribute( 'main_node' );
00120     $class    = $object->contentClass();
00121 
00122     $ignoreNodesSelect = array();
00123     $ignoreNodesClick = array();
00124     foreach ( $object->assignedNodes( false ) as $element )
00125     {
00126         $ignoreNodesSelect[] = $element['node_id'];
00127         $ignoreNodesClick[]  = $element['node_id'];
00128     }
00129     $ignoreNodesSelect = array_unique( $ignoreNodesSelect );
00130     $ignoreNodesClick = array_unique( $ignoreNodesClick );
00131 
00132     $viewMode = 'full';
00133     if ( $Module->hasActionParameter( 'ViewMode' ) )
00134         $viewMode = $Module->actionParameter( 'ViewMode' );
00135 
00136 
00137     $sourceParentNodeID = $node->attribute( 'parent_node_id' );
00138     eZContentBrowse::browse( array( 'action_name' => 'CopyNode',
00139                                     'description_template' => 'design:content/browse_copy_node.tpl',
00140                                     'keys' => array( 'class' => $class->attribute( 'id' ),
00141                                                      'class_id' => $class->attribute( 'identifier' ),
00142                                                      'classgroup' => $class->attribute( 'ingroup_id_list' ),
00143                                                      'section' => $object->attribute( 'section_id' ) ),
00144                                     'ignore_nodes_select' => $ignoreNodesSelect,
00145                                     'ignore_nodes_click'  => $ignoreNodesClick,
00146                                     'persistent_data' => array( 'ObjectID' => $objectID ),
00147                                     'permission' => array( 'access' => 'create', 'contentclass_id' => $class->attribute( 'id' ) ),
00148                                     'content' => array( 'object_id' => $objectID,
00149                                                         'object_version' => $object->attribute( 'current_version' ),
00150                                                         'object_language' => $languageCode ),
00151                                     'start_node' => $sourceParentNodeID,
00152                                     'cancel_page' => $Module->redirectionURIForModule( $Module, 'view',
00153                                                                                        array( $viewMode, $sourceParentNodeID, $languageCode ) ),
00154                                     'from_page' => "/content/copy" ),
00155                              $Module );
00156 }
00157 
00158 /*!
00159 Redirect to the page that lets a user to choose which versions to copy:
00160 either all version or the current one.
00161 */
00162 function chooseObjectVersionsToCopy( $Module, &$Result, $object )
00163 {
00164         $selectedNodeIDArray = eZContentBrowse::result( $Module->currentAction() );
00165 
00166         $tpl = eZTemplate::factory();
00167         $tpl->setVariable( 'object', $object );
00168         $tpl->setVariable( 'selected_node_id', $selectedNodeIDArray[0] );
00169         $Result['content'] = $tpl->fetch( 'design:content/copy.tpl' );
00170         $Result['path'] = array( array( 'url' => false,
00171                                         'text' => ezpI18n::tr( 'kernel/content', 'Content' ) ),
00172                                  array( 'url' => false,
00173                                         'text' => ezpI18n::tr( 'kernel/content', 'Copy' ) ) );
00174 }
00175 
00176 /*
00177  Object copying logic in pseudo-code:
00178 
00179  $targetNodeID = browse();
00180  $versionsToCopy = fetchObjectVersionsToCopyFromContentINI();
00181  if ( $versionsToCopy != 'user-defined' )
00182     $versionsToCopy = askUserAboutVersionsToCopy();
00183  copyObject( $object, $versionsToCopy, $targeNodeID );
00184 
00185  Action parameters:
00186 
00187  1. initially:                                   null
00188  2. when user has selected the target node:     'CopyNode'
00189  3. when/if user has selected versions to copy: 'Copy' or 'Cancel'
00190 */
00191 
00192 $versionHandling = $contentINI->variable( 'CopySettings', 'VersionHandling' );
00193 $chooseVersions = ( $versionHandling == 'user-defined' );
00194 if( $chooseVersions )
00195     $allVersions = ( $Module->actionParameter( 'VersionChoice' ) == 1 ) ? true : false;
00196 else
00197     $allVersions = ( $versionHandling == 'last-published' ) ? false : true;
00198 
00199 if ( $Module->isCurrentAction( 'Copy' ) )
00200 {
00201     // actually do copying after a user has selected object versions to copy
00202     $newParentNodeID = $http->postVariable( 'SelectedNodeID' );
00203     return copyObject( $Module, $object, $allVersions, $newParentNodeID );
00204 }
00205 else if ( $Module->isCurrentAction( 'CopyNode' ) )
00206 {
00207     // we get here after a user selects target node to place the source object under
00208     if( $chooseVersions )
00209     {
00210         // redirect to the page with choice of versions to copy
00211         $Result = array();
00212         chooseObjectVersionsToCopy( $Module, $Result, $object );
00213     }
00214     else
00215     {
00216         // actually do copying of the pre-configured object version(s)
00217         $selectedNodeIDArray = eZContentBrowse::result( $Module->currentAction() );
00218         $newParentNodeID = $selectedNodeIDArray[0];
00219         return copyObject( $Module, $object, $allVersions, $newParentNodeID );
00220     }
00221 }
00222 else // default, initial action
00223 {
00224     /*
00225     Browse for target node.
00226     We get here when a user clicks "copy" button when viewing some node.
00227     */
00228     browse( $Module, $object );
00229 }
00230 
00231 ?>