eZ Publish  [trunk]
ezcontentupload.php
Go to the documentation of this file.
00001 <?php
00002 /**
00003  * File containing the eZContentUpload 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 eZContentUpload ezcontentupload.php
00013   \brief Handles simple creation of content objects by uploading files
00014 
00015   This class makes it easy to use the start a new file upload
00016   and let it be created as a content object.
00017 
00018   Using it is simply to call the \link eZContentUpload::upload() upload \endlink function with some parameters.
00019 
00020 \code
00021 eZContentUpload::upload( array( 'action_name' => 'MyActionName' ), $module );
00022 \endcode
00023 
00024   It requires the module objects as the second parameter to redirect and the first
00025   define how the upload page should behave. Normally you just want to set \c action_name
00026   and define the behaviour of that action in settings/upload.ini.
00027 
00028   Fetching the result afterwards is done by calling the result() method, it will return
00029   the resulting node ID or object ID depending on the configuration of the upload action.
00030 
00031 \code
00032 eZContentUpload::result( 'MyActionName' );
00033 \endcode
00034 
00035   It is also possible to use this class to upload a given file (HTTP or regular) as an object.
00036   The correct class and location can be determined automatically.
00037 
00038   Simply create an instance and then call handleUpload() or handleLocalFile().
00039 
00040 \code
00041 $upload = new eZContentUpload();
00042 $upload->handleUpload( $result, 'UploadFile', 'auto', false );
00043 
00044 $upload->handleLocalFile( $result, 'a_yellow_flower.jpg', 'auto' );
00045 \endcode
00046 */
00047 
00048 class eZContentUpload
00049 {
00050 
00051     const STATUS_PERMISSION_DENIED = 1;
00052 
00053     /*!
00054      Initializes the object with the session data if they are found.
00055      If \a $params is supplied it used instead.
00056     */
00057     function eZContentUpload( $params = false )
00058     {
00059         $http = eZHTTPTool::instance();
00060         if ( !$params && $http->hasSessionVariable( 'ContentUploadParameters' ) )
00061         {
00062             $this->Parameters =& $http->sessionVariable( 'ContentUploadParameters' );
00063         }
00064         else
00065         {
00066             if ( $params === false )
00067                 $params = array();
00068             $this->Parameters = $params;
00069         }
00070     }
00071 
00072     /*!
00073      \return an array with attribute names.
00074     */
00075     function attributes()
00076     {
00077         return array_keys( $this->Parameters );
00078     }
00079 
00080     /*!
00081      \return true if the attribute name \a $attributeName is among the upload parameters.
00082     */
00083     function hasAttribute( $attributeName )
00084     {
00085         return array_key_exists( $attributeName, $this->Parameters );
00086     }
00087 
00088     /*!
00089      \return the attribute value of the attribute named \a $attributeName or \c null if no such attribute.
00090     */
00091     function attribute( $attributeName )
00092     {
00093         if ( isset( $this->Parameters[$attributeName] ) )
00094         {
00095             return $this->Parameters[$attributeName];
00096         }
00097 
00098         eZDebug::writeError( "Attribute '$attributeName' does not exist", __METHOD__ );
00099         return null;
00100     }
00101 
00102     /*!
00103      \static
00104      Sets some session data taken from \a $parameters and start the upload module by redirecting to it using \a $module.
00105      Most data will be automatically derived from the \c action_name value taken from settings/upload.ini, other
00106      values will override default values.
00107     */
00108     static function upload( $parameters = array(), $module )
00109     {
00110         $ini = eZINI::instance( 'upload.ini' );
00111 
00112         if ( !isset( $parameters['action_name'] ) )
00113             $parameters['action_name'] = $ini->variable( 'UploadSettings', 'DefaultActionName' );
00114 
00115         if ( !isset( $parameters['result_action_name'] ) )
00116             $parameters['result_action_name'] = $parameters['action_name'];
00117 
00118         if ( !isset( $parameters['navigation_part_identifier'] ) )
00119             $parameters['navigation_part_identifier'] = false;
00120         if ( !$parameters['navigation_part_identifier'] and
00121              $ini->hasVariable( 'UploadSettings', 'NavigationPartIdentifier' ) )
00122             $parameters['navigation_part_identifier'] = $ini->variable( 'UploadSettings', 'NavigationPartIdentifier' );
00123 
00124         if ( !isset( $parameters['type'] ) )
00125             $parameters['type'] = $parameters['action_name'];
00126 
00127         if ( !isset( $parameters['return_type'] ) )
00128         {
00129             if ( $ini->hasVariable( $parameters['type'], 'ReturnType' ) )
00130                 $parameters['return_type'] = $ini->variable( $parameters['type'], 'ReturnType' );
00131             else
00132                 $parameters['return_type'] = $ini->variable( 'UploadSettings', 'DefaultReturnType' );
00133         }
00134 
00135         if ( !isset( $parameters['upload_custom_action'] ) )
00136             $parameters['upload_custom_action'] = false;
00137 
00138         if ( !isset( $parameters['custom_action_data'] ) )
00139             $parameters['custom_action_data'] = false;
00140 
00141         if ( !isset( $parameters['description_template'] ) )
00142             $parameters['description_template'] = false;
00143 
00144         if ( !isset( $parameters['parent_nodes'] ) )
00145         {
00146             $parameters['parent_nodes'] = false;
00147             if ( $ini->hasVariable( $parameters['type'], 'ParentNodes' ) )
00148             {
00149                 $parameters['parent_nodes'] = $ini->variable( $parameters['type'], 'ParentNodes' );
00150             }
00151         }
00152 
00153         if ( !isset( $parameters['persistent_data'] ) )
00154             $parameters['persistent_data'] = false;
00155 
00156         if ( isset( $parameters['parent_nodes'] ) and
00157              is_array( $parameters['parent_nodes'] ) )
00158         {
00159             foreach ( $parameters['parent_nodes'] as $key => $parentNode )
00160             {
00161                 if ( !is_numeric( $parentNode ) )
00162                 {
00163                     $parameters['parent_nodes'][$key] = eZContentUpload::nodeAliasID( $parentNode );
00164                 }
00165             }
00166         }
00167 
00168         if ( !isset( $parameters['result_uri'] ) )
00169             $parameters['result_uri'] = false;
00170 
00171         if ( !isset( $parameters['cancel_uri'] ) )
00172             $parameters['cancel_uri'] = false;
00173 
00174         if ( !isset( $parameters['result_module'] ) )
00175             $parameters['result_module'] = false;
00176 
00177         $parameters['result'] = false;
00178 
00179         $http = eZHTTPTool::instance();
00180         $http->setSessionVariable( 'ContentUploadParameters', $parameters );
00181 
00182         if ( $module === null )
00183         {
00184             return "/content/upload/";
00185         }
00186         else
00187         {
00188             $module->redirectTo( "/content/upload/" );
00189             return "/content/upload/";
00190         }
00191     }
00192 
00193     /**
00194      * Fetches the local file, figures out its MIME-type and creates the
00195      * proper content object out of it.
00196      *
00197      * @param array $result
00198      *        Result data, will be filled with information which the client can
00199      *        examine, contains: errors An array with errors, each element is
00200      *        an array with a 'description' entry containing the text
00201      * @param string $filePath
00202      *        Path to file which should be stored
00203      * @param mixed $location
00204      *        The node ID which the new object will be placed or the string
00205      *        'auto' for automatic placement of type.
00206      * @param eZContentObjectTreeNode|false $existingNode
00207      *        Pass a contentobjecttreenode object to let the uploading be done
00208      *        to an existing object, if not it will create one from scratch.
00209      * @param string $nameString
00210      *        The name of the new object/new version
00211      * @param string|false $localeCode
00212      *        Locale code (eg eng-GB, fre-FR, ...) to use when creating the
00213      *        object or the version.
00214      *
00215      * @return boolean
00216      */
00217     function handleLocalFile( &$result, $filePath, $location, $existingNode, $nameString = '', $localeCode = false )
00218     {
00219         $result = array( 'errors' => array(),
00220                          'notices' => array(),
00221                          'result' => false,
00222                          'redirect_url' => false,
00223                          'status' => false );
00224 
00225         if ( !file_exists( $filePath ) )
00226         {
00227             $result['errors'][] =
00228                 array( 'description' => ezpI18n::tr( 'kernel/content/upload',
00229                                                 'The file %filename does not exist, cannot insert file.', null,
00230                                                 array( '%filename' => $filePath ) ) );
00231             return false;
00232         }
00233         $mimeData = eZMimeType::findByFileContents( $filePath );
00234         $mime = $mimeData['name'];
00235 
00236         $handler = $this->findHandler( $result, $mimeData );
00237         if ( $handler === false )
00238         {
00239             $result['errors'][] =
00240                 array( 'description' => ezpI18n::tr( 'kernel/content/upload',
00241                                                 'There was an error trying to instantiate content upload handler.' ) );
00242             return false;
00243         }
00244 
00245         // If this is an object we have a special handler for the file.
00246         // The handler will be responsible for the rest of the execution.
00247         if ( is_object( $handler ) )
00248         {
00249             $originalFilename = $filePath;
00250             return $handler->handleFile( $this, $result,
00251                                          $filePath, $originalFilename, $mimeData,
00252                                          $location, $existingNode );
00253         }
00254 
00255         $object = false;
00256         $class = false;
00257         // Figure out class identifier from an existing node
00258         // if not we will have to detect it from the mimetype
00259         if ( is_object( $existingNode ) )
00260         {
00261             $object = $existingNode->object();
00262             $class = $object->contentClass();
00263             $classIdentifier = $class->attribute( 'identifier' );
00264         }
00265         else
00266         {
00267             $classIdentifier = $this->detectClassIdentifier( $mime );
00268         }
00269 
00270         if ( !$classIdentifier )
00271         {
00272             $result['errors'][] =
00273                 array( 'description' => ezpI18n::tr( 'kernel/content/upload',
00274                                                 'No matching class identifier found.' ) );
00275             return false;
00276         }
00277 
00278         if ( !is_object( $class ) )
00279             $class = eZContentClass::fetchByIdentifier( $classIdentifier );
00280 
00281         if ( !$class )
00282         {
00283             $result['errors'][] =
00284                 array( 'description' => ezpI18n::tr( 'kernel/content/upload',
00285                                                 'The class %class_identifier does not exist.', null,
00286                                                 array( '%class_identifier' => $classIdentifier ) ) );
00287             return false;
00288         }
00289 
00290         $parentNodes = false;
00291         $parentMainNode = false;
00292         // If do not have an existing node we need to figure
00293         // out the locations from $location and $classIdentifier
00294         if ( !is_object( $existingNode ) )
00295         {
00296             $locationOK = $this->detectLocations( $classIdentifier, $class, $location, $parentNodes, $parentMainNode );
00297             if ( $locationOK === false )
00298             {
00299                 $result['errors'][] =
00300                     array( 'description' => ezpI18n::tr( 'kernel/content/upload',
00301                                                     'Was not able to figure out placement of object.' ) );
00302                 return false;
00303             }
00304             elseif ( $locationOK === null )
00305             {
00306                 $result['status'] = eZContentUpload::STATUS_PERMISSION_DENIED;
00307                 $result['errors'][] =
00308                     array( 'description' => ezpI18n::tr( 'kernel/content/upload',
00309                                                     'Permission denied' ) );
00310                 return false;
00311             }
00312         }
00313 
00314         $uploadINI = eZINI::instance( 'upload.ini' );
00315         $iniGroup = $classIdentifier . '_ClassSettings';
00316         if ( !$uploadINI->hasGroup( $iniGroup ) )
00317         {
00318             $result['errors'][] =
00319                 array( 'description' => ezpI18n::tr( 'kernel/content/upload',
00320                                                 'No configuration group in upload.ini for class identifier %class_identifier.', null,
00321                                                 array( '%class_identifier' => $classIdentifier ) ) );
00322             return false;
00323         }
00324 
00325         $fileAttribute = $uploadINI->variable( $iniGroup, 'FileAttribute' );
00326         $dataMap = $class->dataMap();
00327 
00328         $fileAttribute = $this->findRegularFileAttribute( $dataMap, $fileAttribute );
00329         if ( !$fileAttribute )
00330         {
00331             $result['errors'][] =
00332                 array( 'description' => ezpI18n::tr( 'kernel/content/upload',
00333                                                 'No matching file attribute found, cannot create content object without this.' ) );
00334             return false;
00335         }
00336 
00337         $nameAttribute = $uploadINI->variable( $iniGroup, 'NameAttribute' );
00338         if ( !$nameAttribute )
00339         {
00340             $nameAttribute = $this->findStringAttribute( $dataMap, $nameAttribute );
00341         }
00342         if ( !$nameAttribute )
00343         {
00344             $result['errors'][] =
00345                 array( 'description' => ezpI18n::tr( 'kernel/content/upload',
00346                                                 'No matching name attribute found, cannot create content object without this.' ) );
00347             return false;
00348         }
00349 
00350         $variables = array( 'original_filename' => $mimeData['filename'],
00351                             'mime_type' => $mime );
00352         $variables['original_filename_base'] = $mimeData['basename'];
00353         $variables['original_filename_suffix'] = $mimeData['suffix'];
00354 
00355         if ( !$nameString )
00356         {
00357             $namePattern = $uploadINI->variable( $iniGroup, 'NamePattern' );
00358             $nameString = $this->processNamePattern( $variables, $namePattern );
00359         }
00360         // If we have an existing node we need to create
00361         // a new version in it.
00362         // If we don't we have to make a new object
00363         if ( is_object( $existingNode ) )
00364         {
00365             if ( $existingNode->canEdit( ) != '1' )
00366             {
00367                 $result['status'] = eZContentUpload::STATUS_PERMISSION_DENIED;
00368                 $result['errors'][] =
00369                     array( 'description' => ezpI18n::tr( 'kernel/content/upload',
00370                                                     'Permission denied' ) );
00371                 return false;
00372             }
00373             $version = $object->createNewVersion( false, true, $localeCode );
00374             unset( $dataMap );
00375             $dataMap = $version->dataMap();
00376             $publishVersion = $version->attribute( 'version' );
00377         }
00378         else
00379         {
00380             $object = $class->instantiateIn( $localeCode );
00381             unset( $dataMap );
00382             $dataMap = $object->dataMap();
00383             $publishVersion = $object->attribute( 'current_version' );
00384         }
00385 
00386         if ( $localeCode === false )
00387         {
00388             $localeCode = eZContentObject::defaultLanguage();
00389         }
00390         $status = $dataMap[$fileAttribute]->insertRegularFile( $object, $publishVersion, $localeCode,
00391                                                                $filePath,
00392                                                                $storeResult );
00393         if ( $status === null )
00394         {
00395             $result['errors'][] =
00396                 array( 'description' => ezpI18n::tr( 'kernel/content/upload',
00397                                                 'The attribute %class_identifier does not support regular file storage.', null,
00398                                                 array( '%class_identifier' => $classIdentifier ) ) );
00399             return false;
00400         }
00401         else if ( !$status )
00402         {
00403             $result['errors'] = array_merge( $result['errors'], $storeResult['errors'] );
00404             return false;
00405         }
00406         if ( $storeResult['require_storage'] )
00407             $dataMap[$fileAttribute]->store();
00408 
00409         $status = $dataMap[$nameAttribute]->insertSimpleString( $object, $publishVersion, $localeCode,
00410                                                                 $nameString,
00411                                                                 $storeResult );
00412         if ( $status === null )
00413         {
00414             $result['errors'][] =
00415                 array( 'description' => ezpI18n::tr( 'kernel/content/upload',
00416                                                 'The attribute %class_identifier does not support simple string storage.', null,
00417                                                 array( '%class_identifier' => $classIdentifier ) ) );
00418             return false;
00419         }
00420         else if ( !$status )
00421         {
00422             $result['errors'] = array_merge( $result['errors'], $storeResult['errors'] );
00423             return false;
00424         }
00425         if ( $storeResult['require_storage'] )
00426             $dataMap[$nameAttribute]->store();
00427 
00428         return $this->publishObject( $result, $result['errors'], $result['notices'],
00429                                      $object, $publishVersion, $class, $parentNodes, $parentMainNode );
00430     }
00431 
00432     /**
00433      * Fetches the uploaded file, figures out its MIME-type and creates the
00434      * proper content object out of it.
00435      *
00436      * @param array $result
00437      *        Result data, will be filled with information which the client can
00438      *        examine, contains: errors An array with errors, each element is
00439      *        an array with a 'description' entry containing the text
00440      * @param string $httpFileIdentifier
00441      *        The HTTP identifier of the uploaded file, this must match the
00442      *        name of the input tag.
00443      * @param mixed $location
00444      *        The node ID which the new object will be placed or the string
00445      *        'auto' for automatic placement of type.
00446      * @param eZContentObjectTreeNode|false $existingNode
00447      *        Pass a contentobjecttreenode object to let the uploading be done
00448      *        to an existing object, if not it will create one from scratch.
00449      * @param string $nameString
00450      *        The name of the new object/new version
00451      * @param string|false $localeCode
00452      *        Locale code (eg eng-GB, fre-FR, ...) to use when creating the
00453      *        object or the version.
00454      *
00455      * @return boolean
00456      */
00457     function handleUpload( &$result, $httpFileIdentifier, $location, $existingNode, $nameString = '', $localeCode = false )
00458     {
00459         $result = array( 'errors' => array(),
00460                          'notices' => array(),
00461                          'result' => false,
00462                          'redirect_url' => false );
00463 
00464         $this->fetchHTTPFile( $httpFileIdentifier, $result['errors'], $file, $mimeData );
00465         if ( !$file )
00466         {
00467             $result['errors'][] =
00468                 array( 'description' => ezpI18n::tr( 'kernel/content/upload',
00469                                                 'No HTTP file found, cannot fetch uploaded file.' ) );
00470             return false;
00471         }
00472         $mime = $mimeData['name'];
00473         if ( $mime == '' )
00474             $mime = $file->attribute( "mime_type" );
00475 
00476         $handler = $this->findHandler( $result, $mimeData );
00477         if ( $handler === false )
00478         {
00479             $result['errors'][] =
00480                 array( 'description' => ezpI18n::tr( 'kernel/content/upload',
00481                                                 'There was an error trying to instantiate content upload handler.' ) );
00482             return false;
00483         }
00484 
00485         // If this is an object we have a special handler for the file
00486         // The handler will be responsible for the rest of the execution.
00487         if ( is_object( $handler ) )
00488         {
00489             $filePath = $file->attribute( "filename" );
00490             $originalFilename = $file->attribute( "original_filename" );
00491             $handlerResult = $handler->handleFile( $this, $result,
00492                                                    $filePath, $originalFilename, $mimeData,
00493                                                    $location, $existingNode );
00494             if ( is_object( $result['contentobject'] ) )
00495                 return $handlerResult;
00496         }
00497 
00498         $object = false;
00499         $class = false;
00500         // Figure out class identifier from an existing node
00501         // if not we will have to detect it from the mimetype
00502         if ( is_object( $existingNode ) )
00503         {
00504             $object = $existingNode->object();
00505             $class = $object->contentClass();
00506             $classIdentifier = $class->attribute( 'identifier' );
00507         }
00508         else
00509         {
00510             $classIdentifier = $this->detectClassIdentifier( $mime );
00511         }
00512 
00513         if ( !$classIdentifier )
00514         {
00515             $result['errors'][] =
00516                 array( 'description' => ezpI18n::tr( 'kernel/content/upload',
00517                                                 'No matching class identifier found.' ) );
00518             return false;
00519         }
00520 
00521         if ( !is_object( $class ) )
00522             $class = eZContentClass::fetchByIdentifier( $classIdentifier );
00523 
00524         if ( !$class )
00525         {
00526             $result['errors'][] =
00527                 array( 'description' => ezpI18n::tr( 'kernel/content/upload',
00528                                                 'The class %class_identifier does not exist.', null,
00529                                                 array( '%class_identifier' => $classIdentifier ) ) );
00530             return false;
00531         }
00532 
00533 
00534         $parentNodes = false;
00535         $parentMainNode = false;
00536         // If do not have an existing node we need to figure
00537         // out the locations from $location and $classIdentifier
00538         if ( !is_object( $existingNode ) )
00539         {
00540             $locationOK = $this->detectLocations( $classIdentifier, $class, $location, $parentNodes, $parentMainNode );
00541             if ( $locationOK === false )
00542             {
00543                 $result['errors'][] =
00544                     array( 'description' => ezpI18n::tr( 'kernel/content/upload',
00545                                                     'Was not able to figure out placement of object.' ) );
00546                 return false;
00547             }
00548             elseif ( $locationOK === null )
00549             {
00550                 $result['status'] = eZContentUpload::STATUS_PERMISSION_DENIED;
00551                 $result['errors'][] =
00552                     array( 'description' => ezpI18n::tr( 'kernel/content/upload',
00553                                                     'Permission denied' ) );
00554                 return false;
00555             }
00556         }
00557 
00558         $uploadINI = eZINI::instance( 'upload.ini' );
00559         $iniGroup = $classIdentifier . '_ClassSettings';
00560         if ( !$uploadINI->hasGroup( $iniGroup ) )
00561         {
00562             $result['errors'][] =
00563                 array( 'description' => ezpI18n::tr( 'kernel/content/upload',
00564                                                 'No configuration group in upload.ini for class identifier %class_identifier.', null,
00565                                                 array( '%class_identifier' => $classIdentifier ) ) );
00566             return false;
00567         }
00568 
00569         $fileAttribute = $uploadINI->variable( $iniGroup, 'FileAttribute' );
00570         $dataMap = $class->dataMap();
00571 
00572         if ( $classIdentifier == 'image' )
00573         {
00574             $classAttribute = $dataMap['image'];
00575             $maxSize = 1024 * 1024 * $classAttribute->attribute( 'data_int1' );
00576             if ( $maxSize != 0 && $file->attribute( 'filesize' ) > $maxSize )
00577             {
00578                 $result['errors'][] =
00579                     array( 'description' => ezpI18n::tr( 'kernel/content/upload',
00580                                                     'The size of the uploaded file exceeds the limit set for this site: %1 bytes.', null, array( $maxSize ) ) );
00581                 return false;
00582             }
00583         }
00584 
00585 
00586         $fileAttribute = $this->findHTTPFileAttribute( $dataMap, $fileAttribute );
00587         if ( !$fileAttribute )
00588         {
00589             $result['errors'][] =
00590                 array( 'description' => ezpI18n::tr( 'kernel/content/upload',
00591                                                 'No matching file attribute found, cannot create content object without this.' ) );
00592             return false;
00593         }
00594 
00595         $nameAttribute = $uploadINI->variable( $iniGroup, 'NameAttribute' );
00596         if ( !$nameAttribute )
00597         {
00598             $nameAttribute = $this->findStringAttribute( $dataMap, $nameAttribute );
00599         }
00600         if ( !$nameAttribute )
00601         {
00602             $result['errors'][] =
00603                 array( 'description' => ezpI18n::tr( 'kernel/content/upload',
00604                                                 'No matching name attribute found, cannot create content object without this.' ) );
00605             return false;
00606         }
00607 
00608         $variables = array( 'original_filename' => $file->attribute( 'original_filename' ),
00609                             'mime_type' => $mime );
00610         $variables['original_filename_base'] = $mimeData['basename'];
00611         $variables['original_filename_suffix'] = $mimeData['suffix'];
00612 
00613         if ( !$nameString )
00614         {
00615             $namePattern = $uploadINI->variable( $iniGroup, 'NamePattern' );
00616             $nameString = $this->processNamePattern( $variables, $namePattern );
00617         }
00618 
00619         $db = eZDB::instance();
00620         $db->begin();
00621 
00622         // If we have an existing node we need to create
00623         // a new version in it.
00624         // If we don't we have to make a new object
00625         if ( is_object( $existingNode ) )
00626         {
00627             if ( $existingNode->canEdit( ) != '1' )
00628             {
00629                 $result['status'] = eZContentUpload::STATUS_PERMISSION_DENIED;
00630                 $result['errors'][] =
00631                     array( 'description' => ezpI18n::tr( 'kernel/content/upload',
00632                                                     'Permission denied' ) );
00633 
00634                 $db->commit();
00635                 return false;
00636             }
00637             $version = $object->createNewVersion( false, true, $localeCode );
00638             unset( $dataMap );
00639             $dataMap = $version->dataMap();
00640             $publishVersion = $version->attribute( 'version' );
00641         }
00642         else
00643         {
00644             $object = $class->instantiateIn( $localeCode );
00645             unset( $dataMap );
00646             $dataMap = $object->dataMap();
00647             $publishVersion = $object->attribute( 'current_version' );
00648         }
00649 
00650         unset( $dataMap );
00651         $dataMap = $object->dataMap();
00652 
00653         if ( $localeCode === false )
00654         {
00655             $localeCode = eZContentObject::defaultLanguage();
00656         }
00657         $status = $dataMap[$fileAttribute]->insertHTTPFile( $object, $publishVersion, $localeCode,
00658                                                             $file, $mimeData,
00659                                                             $storeResult );
00660         if ( $status === null )
00661         {
00662             $result['errors'][] =
00663                 array( 'description' => ezpI18n::tr( 'kernel/content/upload',
00664                                                 'The attribute %class_identifier does not support HTTP file storage.', null,
00665                                                         array( '%class_identifier' => $classIdentifier ) ) );
00666             $db->commit();
00667             return false;
00668         }
00669         else if ( !$status )
00670         {
00671             $result['errors'] = array_merge( $result['errors'], $storeResult['errors'] );
00672             $db->commit();
00673             return false;
00674         }
00675         if ( $storeResult['require_storage'] )
00676             $dataMap[$fileAttribute]->store();
00677 
00678         $status = $dataMap[$nameAttribute]->insertSimpleString( $object, $publishVersion, $localeCode,
00679                                                                 $nameString,
00680                                                                 $storeResult );
00681         if ( $status === null )
00682         {
00683             $result['errors'][] =
00684                 array( 'description' => ezpI18n::tr( 'kernel/content/upload',
00685                                                 'The attribute %class_identifier does not support simple string storage.', null,
00686                                                 array( '%class_identifier' => $classIdentifier ) ) );
00687             $db->commit();
00688             return false;
00689         }
00690         else if ( !$status )
00691         {
00692             $result['errors'] = array_merge( $result['errors'], $storeResult['errors'] );
00693             $db->commit();
00694             return false;
00695         }
00696         if ( $storeResult['require_storage'] )
00697             $dataMap[$nameAttribute]->store();
00698 
00699         $tmpresult = $this->publishObject( $result, $result['errors'], $result['notices'],
00700                                            $object, $publishVersion, $class, $parentNodes, $parentMainNode );
00701 
00702         $db->commit();
00703         return $tmpresult;
00704     }
00705 
00706     /*!
00707      \private
00708      Publishes the object to the selected locations.
00709 
00710      \return \c true if everything was OK, \c false if something failed.
00711     */
00712     function publishObject( &$result, &$errors, &$notices,
00713                             $object, $publishVersion, $class, $parentNodes, $parentMainNode )
00714     {
00715         if ( is_array( $parentNodes ) )
00716         {
00717             foreach ( $parentNodes as $key => $parentNode )
00718             {
00719                 $object->createNodeAssignment( $parentNode, $parentNode == $parentMainNode );
00720             }
00721         }
00722 
00723         $object->setName( $class->contentObjectName( $object ) );
00724         $object->store();
00725 
00726         $operationResult = eZOperationHandler::execute( 'content', 'publish', array( 'object_id' => $object->attribute( 'id' ),
00727                                                                                      'version' => $publishVersion ) );
00728 
00729         $objectID = $object->attribute( 'id' );
00730         unset( $object );
00731         $object = eZContentObject::fetch( $objectID );
00732         $result['contentobject'] = $object;
00733         $result['contentobject_id'] = $object->attribute( 'id' );
00734         $result['contentobject_version'] = $publishVersion;
00735         $result['contentobject_main_node'] = false;
00736         $result['contentobject_main_node_id'] = false;
00737 
00738         $this->setResult( array( 'node_id' => false,
00739                                  'object_id' => $object->attribute( 'id' ),
00740                                  'object_version' => $publishVersion ) );
00741 
00742         switch ( $operationResult['status'] )
00743         {
00744             case eZModuleOperationInfo::STATUS_HALTED:
00745             {
00746                 if ( isset( $operationResult['redirect_url'] ) )
00747                 {
00748                     $result['redirect_url'] = $operationResult['redirect_url'];
00749                     $notices[] = array( 'description' => ezpI18n::tr( 'kernel/content/upload',
00750                                                                  'Publishing of content object was halted.' ) );
00751                     return true;
00752                 }
00753                 else if ( isset( $operationResult['result'] ) )
00754                 {
00755                     $result['result'] = $operationResult['result'];
00756                     return true;
00757                 }
00758             } break;
00759 
00760             case eZModuleOperationInfo::STATUS_CANCELLED:
00761             {
00762                 $result['result'] = ezpI18n::tr( 'kernel/content/upload',
00763                                             'Publish process was cancelled.' );
00764                 return true;
00765             } break;
00766 
00767             case eZModuleOperationInfo::STATUS_CONTINUE:
00768             {
00769             }
00770         }
00771 
00772         $mainNode = $object->mainNode();
00773         $result['contentobject_main_node'] = $mainNode;
00774         $result['contentobject_main_node_id'] = $mainNode->attribute( 'node_id' );
00775         $this->setResult( array( 'node_id' => $mainNode->attribute( 'node_id' ),
00776                                  'object_id' => $object->attribute( 'id' ),
00777                                  'object_version' => $publishVersion ) );
00778 
00779         return true;
00780     }
00781 
00782     /*!
00783       Finds the file attribute for object \a $contentObject and tries to extract
00784       file information using eZDataType::storedFileInformation().
00785       \return The information structure or \c false if it fails somehow.
00786     */
00787     function objectFileInfo( $contentObject )
00788     {
00789         $uploadINI = eZINI::instance( 'upload.ini' );
00790 
00791         $class = $contentObject->contentClass();
00792         $classIdentifier = $class->attribute( 'identifier' );
00793         $classDataMap = $class->dataMap();
00794         $attributeIdentifier = false;
00795         if ( $uploadINI->hasGroup( $classIdentifier . '_ClassSettings' ) )
00796         {
00797             $attributeIdentifier = $uploadINI->variable( $classIdentifier . '_ClassSettings', 'FileAttribute' );
00798         }
00799 
00800         $attributeIdentifier = $this->findRegularFileAttribute( $classDataMap, $attributeIdentifier );
00801         if ( !$attributeIdentifier )
00802         {
00803             // No file information for this object
00804             return false;
00805         }
00806 
00807         $dataMap = $contentObject->dataMap();
00808         $fileAttribute = $dataMap[$attributeIdentifier];
00809 
00810         if ( $fileAttribute->hasStoredFileInformation( $contentObject, false, false ) )
00811         {
00812             return $fileAttribute->storedFileInformation( $contentObject, false, false );
00813         }
00814         return false;
00815     }
00816 
00817     /**
00818      * Fetches the HTTP-File into $file and fills in MIME-Type information into $mimeData.
00819      *
00820      * @return bool false if something went wrong.
00821      */
00822     function fetchHTTPFile( $httpFileIdentifier, &$errors, &$file, &$mimeData )
00823     {
00824         $returnCode = eZHTTPFile::canFetch( $httpFileIdentifier, 0 );
00825         if ( $returnCode !== eZHTTPFile::UPLOADEDFILE_OK && $returnCode !== true )
00826         {
00827             switch ( $returnCode )
00828             {
00829                 case eZHTTPFile::UPLOADEDFILE_DOES_NOT_EXIST:
00830                     $errors[] = array( 'description' => ezpI18n::tr( 'kernel/content/upload', 'A file is required for upload, no file were found.' ) );
00831                     break;
00832                 case eZHTTPFile::UPLOADEDFILE_EXCEEDS_PHP_LIMIT:
00833                 case eZHTTPFile::UPLOADEDFILE_EXCEEDS_MAX_SIZE:
00834                     $errors[] = array( 'description' => ezpI18n::tr( 'kernel/content/upload', 'The uploaded file size is above the maximum limit.' ) );
00835                     break;
00836                 case eZHTTPFile::UPLOADEDFILE_MISSING_TMP_DIR:
00837                 case eZHTTPFile::UPLOADEDFILE_CANT_WRITE:
00838                 case eZHTTPFile::UPLOADEDFILE_UNKNOWN_ERROR:
00839                     $errors[] = array( 'description' => ezpI18n::tr( 'kernel/content/upload', 'A system error occured while writing the uploaded file.' ) );
00840                     break;
00841             }
00842             return false;
00843         }
00844 
00845         $file = eZHTTPFile::fetch( $httpFileIdentifier );
00846         if ( !( $file instanceof eZHTTPFile ) )
00847         {
00848             $errors[] = array( 'description' => ezpI18n::tr( 'kernel/content/upload',
00849                                                         'Expected a eZHTTPFile object but got nothing.' ) );
00850             return false;
00851         }
00852 
00853         $mimeData = eZMimeType::findByFileContents( $file->attribute( "original_filename" ) );
00854 
00855         return true;
00856     }
00857 
00858     /*!
00859      \private
00860      \static
00861      Checks if the attribute with the identifier \a $fileAttribute in \a $dataMap
00862      supports HTTP file uploading. If not it will go trough all attributes and
00863      find the first that has this support.
00864 
00865      \return The identifier of the matched attribute or \c false if none were found.
00866      \param $dataMap Associative array with class attributes, the key is attribute identifier
00867      \param $fileAttribute The identifier of the attribute that is expected to have the file datatype.
00868     */
00869     function findHTTPFileAttribute( $dataMap, $fileAttribute )
00870     {
00871         $fileDatatype = false;
00872         if ( isset( $dataMap[$fileAttribute] ) )
00873             $fileDatatype = $dataMap[$fileAttribute]->dataType();
00874         if ( !$fileDatatype or
00875              !$fileDatatype->isHTTPFileInsertionSupported() )
00876         {
00877             $fileAttribute = false;
00878             foreach ( $dataMap as $identifier => $attribute )
00879             {
00880                 $datatype = $attribute->dataType();
00881                 if ( $datatype->isHTTPFileInsertionSupported() )
00882                 {
00883                     $fileAttribute = $identifier;
00884                     break;
00885                 }
00886             }
00887         }
00888         return $fileAttribute;
00889     }
00890 
00891     /*!
00892      \private
00893      \static
00894      Checks if the attribute with the identifier \a $fileAttribute in \a $dataMap
00895      supports file uploading. If not it will go trough all attributes and
00896      find the first that has this support.
00897 
00898      \return The identifier of the matched attribute or \c false if none were found.
00899      \param $dataMap Associative array with class attributes, the key is attribute identifier
00900      \param $fileAttribute The identifier of the attribute that is expected to have the file datatype.
00901     */
00902     function findRegularFileAttribute( $dataMap, $fileAttribute )
00903     {
00904         $fileDatatype = false;
00905         if ( isset( $dataMap[$fileAttribute] ) )
00906             $fileDatatype = $dataMap[$fileAttribute]->dataType();
00907         if ( !$fileDatatype or
00908              !$fileDatatype->isRegularFileInsertionSupported() )
00909         {
00910             $fileAttribute = false;
00911             foreach ( $dataMap as $identifier => $attribute )
00912             {
00913                 $datatype = $attribute->dataType();
00914                 if ( $datatype->isRegularFileInsertionSupported() )
00915                 {
00916                     $fileAttribute = $identifier;
00917                     break;
00918                 }
00919             }
00920         }
00921         return $fileAttribute;
00922     }
00923 
00924     /*!
00925      \private
00926      \static
00927      Checks if the attribute with the identifier \a $nameAttribute in \a $dataMap
00928      supports string insertion. If not it will go trough all attributes and
00929      find the first that has this support.
00930 
00931      \return The identifier of the matched attribute or \c false if none were found.
00932      \param $dataMap Associative array with class attributes, the key is attribute identifier
00933      \param $nameAttribute The identifier of the attribute that is expected to have the string datatype.
00934     */
00935     function findStringAttribute( $dataMap, $nameAttribute )
00936     {
00937         $nameDatatype = false;
00938         if ( isset( $dataMap[$nameAttribute] ) )
00939             $nameDatatype = $dataMap[$nameAttribute]->dataType();
00940         if ( !$nameDatatype or
00941              !$nameDatatype->isSimpleStringInsertionSupported() )
00942         {
00943             $nameAttribute = false;
00944             foreach ( $dataMap as $identifier => $attribute )
00945             {
00946                 $datatype = $attribute->dataType();
00947                 if ( $datatype->isSimpleStringInsertionSupported() )
00948                 {
00949                     $nameAttribute = $identifier;
00950                     break;
00951                 }
00952             }
00953         }
00954         return $nameAttribute;
00955     }
00956 
00957     /*!
00958      \private
00959      \static
00960      Figures out the class which should be used for file with
00961      MIME-Type \a $mime and returns the class identifier.
00962      \param $mime A string defining the MIME-Type, will be used to determine class identifier.
00963     */
00964     function detectClassIdentifier( $mime )
00965     {
00966         $uploadINI = eZINI::instance( 'upload.ini' );
00967 
00968         $mimeClassMap = $uploadINI->variable( 'CreateSettings', 'MimeClassMap' );
00969         $defaultClass = $uploadINI->variable( 'CreateSettings', 'DefaultClass' );
00970 
00971         list( $group, $type ) = explode( '/', $mime );
00972         if ( isset( $mimeClassMap[$mime] ) )
00973         {
00974             $classIdentifier = $mimeClassMap[$mime];
00975         }
00976         else if ( isset( $mimeClassMap[$group] ) )
00977         {
00978             $classIdentifier = $mimeClassMap[$group];
00979         }
00980         else
00981         {
00982             $classIdentifier = $defaultClass;
00983         }
00984         return $classIdentifier;
00985     }
00986 
00987     /*!
00988      \private
00989      Figures out the location(s) in which the class with
00990      the identifier \a $classIdentifier should be placed.
00991      The returned locations will either be a node ID or an identifier
00992      for a node (e.g. content).
00993 
00994      \return \c true if a location was found or \c false if no location could be determined
00995      \param $classIdentifier Identifier of class, is used to determine location
00996      \param $location The wanted location, either use \c 'auto' for automatic placement
00997                       or number to determine to parent node ID.
00998      \param[out] $parentNodes Will contain an array with node IDs or identifiers if a location could be detected.
00999      \param[out] $parentMainNode Will contain the ID of the main node if a location could be detected.
01000      */
01001     function detectLocations( $classIdentifier, $class, $location,
01002                               &$parentNodes, &$parentMainNode )
01003     {
01004         $isAccessChecked = false;
01005         $parentMainNode = false;
01006         if ( $this->hasAttribute( 'parent_nodes' ) &&
01007              $this->attribute( 'parent_nodes' ) )
01008         {
01009             $parentNodes = $this->attribute( 'parent_nodes' );
01010             foreach( $parentNodes as $key => $parentNode )
01011             {
01012                 $parentNodes[$key] = eZContentUpload::nodeAliasID( $parentNode );
01013                 if ( !eZContentUpload::checkAccess( $parentNodes[$key], $class ) )
01014                 {
01015                     $parentNodes = false;
01016                     return null;
01017                 }
01018             }
01019         }
01020         else
01021         {
01022             if ( $location == 'auto' or !is_numeric( $location ) )
01023             {
01024                 $contentINI = eZINI::instance( 'content.ini' );
01025 
01026                 $classPlacementMap = $contentINI->variable( 'RelationAssignmentSettings', 'ClassSpecificAssignment' );
01027                 $defaultPlacement = $contentINI->variable( 'RelationAssignmentSettings', 'DefaultAssignment' );
01028 
01029                 // Find location that matches the class and where user is allowed to create objects
01030                 foreach ( $classPlacementMap as $classData )
01031                 {
01032                     $classElements = explode( ';', $classData );
01033                     $classList = explode( ',', $classElements[0] );
01034 
01035                     if ( in_array( $classIdentifier, $classList ) )
01036                     {
01037                         $parentNodes = explode( ',', $classElements[1] );
01038                         if ( count( $parentNodes ) == 0 )
01039                             continue;
01040 
01041                         if ( isset( $classElements[2] ) )
01042                             $parentMainNode = eZContentUpload::nodeAliasID( $classElements[2] );
01043 
01044                         // check access rights and convert to IDs
01045                         foreach ( $parentNodes as $key => $parentNode )
01046                         {
01047                             $parentNodeID = eZContentUpload::nodeAliasID( $parentNode );
01048                             if ( !$parentNodeID )
01049                             {
01050                                 $parentNodes = false;
01051                                 break;
01052                             }
01053 
01054                             $parentNodes[$key] = $parentNodeID;
01055 
01056                             if ( !eZContentUpload::checkAccess( $parentNodeID, $class ) )
01057                             {
01058                                 eZDebug::writeNotice( "Upload assignment setting '$classData' skipped - no permissions", __METHOD__ );
01059                                 $parentNodes = false;
01060                                 break;
01061                             }
01062                         }
01063 
01064                         if ( $parentNodes )
01065                         {
01066                             eZDebug::writeNotice( "Matched assignment for upload :'$classData'", __METHOD__ );
01067                             break;
01068                         }
01069                     }
01070                 }
01071 
01072                 if ( !$parentNodes && isset( $defaultPlacement ) && $defaultPlacement )
01073                 {
01074                     $defaultNodeID = eZContentUpload::nodeAliasID( $defaultPlacement );
01075                     if ( $defaultNodeID )
01076                     {
01077                         if ( eZContentUpload::checkAccess( $defaultNodeID, $class ) )
01078                         {
01079                             $parentNodes = array( $defaultNodeID );
01080                         }
01081                         else
01082                         {
01083                             eZDebug::writeNotice( "No create permission for default upload location: node #$defaultNodeID", __METHOD__ );
01084                             return null;
01085                         }
01086 
01087                     }
01088                 }
01089             }
01090             else
01091             {
01092                 $locationID = eZContentUpload::nodeAliasID( $location );
01093                 if ( $locationID )
01094                 {
01095                     if ( eZContentUpload::checkAccess( $locationID, $class ) )
01096                     {
01097                         $parentNodes = array( $locationID );
01098                     }
01099                     else
01100                     {
01101                         eZDebug::writeNotice( "No create permission for upload location: node #$locationID", __METHOD__ );
01102                         return null;
01103                     }
01104                 }
01105             }
01106         }
01107 
01108         if ( !$parentNodes || count( $parentNodes ) == 0 )
01109         {
01110             return false;
01111         }
01112 
01113         if ( !$parentMainNode )
01114         {
01115             $parentMainNode = $parentNodes[0];
01116         }
01117 
01118         return true;
01119     }
01120 
01121     /*!
01122      \private
01123      \static
01124     */
01125 
01126     function checkAccess( $nodeID, $class )
01127     {
01128         $parentNodeObj = eZContentObjectTreeNode::fetch( $nodeID );
01129         $parentObject =  $parentNodeObj->attribute( 'object' );
01130 
01131         if ( $parentNodeObj->checkAccess( 'create',
01132                                           $class->attribute( 'id' ),
01133                                           $parentObject->attribute( 'contentclass_id' ) ) != '1' )
01134         {
01135             return false;
01136         }
01137         return true;
01138     }
01139 
01140     /*!
01141      \private
01142      \static
01143      Parses the name pattern \a $namePattern and replaces any
01144      variables found in \a $variables with the variable value.
01145 
01146      \return The resulting string with all \e tags replaced.
01147      \param $variables An associative array where the key is variable name and element the variable value.
01148      \param $namePattern A string containing of plain text or \e tags, each tag is enclosed in < and > and
01149                          defines name of the variable to lookup.
01150 
01151      \code
01152      $vars = array( 'name' => 'A name',
01153                     'filename' => 'myfile.txt' );
01154      $name = $this->parseNamePattern( $vars, '<name> - <filename>' );
01155      print( $name ); // Will output 'A name - myfile.txt'
01156      \endcode
01157     */
01158     function processNamePattern( $variables, $namePattern )
01159     {
01160         $tags = array();
01161         $pos = 0;
01162         $lastPos = false;
01163         $len = strlen( $namePattern );
01164         while ( $pos < $len )
01165         {
01166             $markerPos = strpos( $namePattern, '<', $pos );
01167             if ( $markerPos !== false )
01168             {
01169                 $markerEndPos = strpos( $namePattern, '>', $markerPos + 1 );
01170                 if ( $markerEndPos === false )
01171                 {
01172                     $markerEndPos = $len;
01173                     $pos = $len;
01174                 }
01175                 else
01176                 {
01177                     $pos = $markerEndPos + 1;
01178                 }
01179                 $tag = substr( $namePattern, $markerPos + 1, $markerEndPos - $markerPos - 1 );
01180                 $tags[] = array( 'name' => $tag );
01181             }
01182             if ( $lastPos !== false and
01183                  $lastPos < $pos )
01184             {
01185                 $tags[] = substr( $namePattern, $lastPos, $pos - $lastPos );
01186             }
01187             $lastPos = $pos;
01188         }
01189         $nameString = '';
01190         foreach ( $tags as $tag )
01191         {
01192             if ( is_string( $tag ) )
01193             {
01194                 $nameString .= $tag;
01195             }
01196             else
01197             {
01198                 if ( isset( $variables[$tag['name']] ) )
01199                     $nameString .= $variables[$tag['name']];
01200             }
01201         }
01202         return $nameString;
01203     }
01204 
01205     /*!
01206      \static
01207      \return the node ID for the node alias \a $nodeName or \c false if no ID could be found.
01208     */
01209     function nodeAliasID( $nodeName )
01210     {
01211         if ( is_numeric( $nodeName ) )
01212         {
01213             $node = eZContentObjectTreeNode::fetch( $nodeName, false, false );
01214             if ( is_array( $node ) )
01215             {
01216                 $result['status'] = eZContentUpload::STATUS_PERMISSION_DENIED;
01217                 $errors[] = array( 'description' => ezpI18n::tr( 'kernel/content/upload',
01218                                                             'Permission denied' ) );
01219 
01220                 return $nodeName;
01221             }
01222         }
01223 
01224         $uploadINI = eZINI::instance( 'upload.ini' );
01225         $aliasList = $uploadINI->variable( 'UploadSettings', 'AliasList' );
01226         if ( isset( $aliasList[$nodeName] ) )
01227             return $aliasList[$nodeName];
01228         $contentINI = eZINI::instance( 'content.ini' );
01229         if ( $nodeName == 'content' or $nodeName == 'root' )
01230             return $contentINI->variable( 'NodeSettings', 'RootNode' );
01231         else if ( $nodeName == 'users' )
01232             return $contentINI->variable( 'NodeSettings', 'UserRootNode' );
01233         else if ( $nodeName == 'media' )
01234             return $contentINI->variable( 'NodeSettings', 'MediaRootNode' );
01235         else if ( $nodeName == 'setup' )
01236             return $contentINI->variable( 'NodeSettings', 'SetupRootNode' );
01237 
01238         // Check for node path element
01239         $pathPos = strpos( $nodeName, '/' );
01240         if ( $pathPos !== false )
01241         {
01242             $node = eZContentObjectTreeNode::fetchByURLPath( $nodeName, false );
01243             if ( is_array( $node ) )
01244             {
01245                 return $node['node_id'];
01246             }
01247         }
01248         return false;
01249     }
01250 
01251     /*!
01252      Sets the result array to \a $result and stores the session variable.
01253     */
01254     function setResult( $result )
01255     {
01256         $this->Parameters['result'] = $result;
01257         $http = eZHTTPTool::instance();
01258         $http->setSessionVariable( 'ContentUploadParameters', $this->Parameters );
01259     }
01260 
01261     /*!
01262      \static
01263      \return the result of the previous upload operation or \c false if no result was found.
01264              It uses the action name \a $actionName to determine which result to look for.
01265      \param $cleanup If \c true it the persisten data is cleaned up by calling cleanup().
01266     */
01267     static function result( $actionName, $cleanup = true )
01268     {
01269         $upload = new eZContentUpload();
01270 
01271         $isNodeSelection = $upload->attribute( 'return_type' ) == 'NodeID';
01272         $resultData = $upload->attribute( 'result' );
01273         $result = false;
01274         if ( $isNodeSelection )
01275         {
01276             $result = $resultData['node_id'];
01277         }
01278         else
01279         {
01280             $result = $resultData['object_id'];
01281         }
01282         if ( $cleanup )
01283             eZContentUpload::cleanup( $actionName );
01284         return $result;
01285     }
01286 
01287     /*!
01288      \static
01289      Cleans up the persistent data and result for action named \a $actionName
01290     */
01291     static function cleanup( $actionName )
01292     {
01293         $http = eZHTTPTool::instance();
01294         $http->removeSessionVariable( 'ContentUploadParameters' );
01295     }
01296 
01297     /*!
01298      \static
01299      Similar to cleanup() but removes persistent data from all actions.
01300     */
01301     function cleanupAll()
01302     {
01303         $http = eZHTTPTool::instance();
01304         $http->removeSessionVariable( 'ContentUploadParameters' );
01305     }
01306 
01307     /*!
01308      Finds the correct upload handler for the file specified in \a $mimeInfo.
01309      If no handler is found it will return the default attribute based handler eZContentUpload,
01310      this means that the file is passed to one suitable attribute and handled from there.
01311      \return An object with the interface eZContentUploadHandler or \c false if an error occured.
01312              Will return \c true if there is no handler configured for this type.
01313     */
01314     function findHandler( &$result, $mimeInfo )
01315     {
01316         // Check for specific mime handler plugin
01317         $uploadINI = eZINI::instance( 'upload.ini' );
01318         $uploadSettings = $uploadINI->variable( 'CreateSettings', 'MimeUploadHandlerMap' );
01319 
01320         $mime = $mimeInfo['name'];
01321         $elements = explode( '/', $mime );
01322         $mimeGroup = $elements[0];
01323 
01324         $handlerName = false;
01325         // Check first for MIME-Type group, this allows a handler to work
01326         // with an entire group, e.g. image
01327         if ( isset( $uploadSettings[$mimeGroup] ) )
01328         {
01329             $handlerName = $uploadSettings[$mimeGroup];
01330         }
01331         else if ( isset( $uploadSettings[$mime] ) )
01332         {
01333             $handlerName = $uploadSettings[$mime];
01334         }
01335 
01336         if ( $handlerName !== false )
01337         {
01338             $baseDirectory = eZExtension::baseDirectory();
01339             $extensionDirectories = eZExtension::activeExtensions();
01340 
01341             // Check all extension directories for an upload handler for this mimetype
01342             foreach ( $extensionDirectories as $extensionDirectory )
01343             {
01344                 $handlerPath = $baseDirectory . '/' . $extensionDirectory . '/uploadhandlers/' . $handlerName . ".php";
01345                 if ( !file_exists( $handlerPath ) )
01346                     continue;
01347 
01348                 include_once( $handlerPath );
01349                 $handlerClass = $handlerName;
01350                 $handler = new $handlerClass();
01351                 if ( !$handler instanceof eZContentUploadHandler )
01352                 {
01353                     eZDebug::writeError( "Content upload handler '$handlerName' is not inherited from eZContentUploadHandler. All upload handlers must do this.", __METHOD__ );
01354                     return false;
01355                 }
01356                 return $handler;
01357             }
01358 
01359             $result['errors'][] =
01360                 array( 'description' => ezpI18n::tr( 'kernel/content/upload',
01361                                                 "Could not find content upload handler '%handler_name'",
01362                                                 null, array( '%handler_name' => $handlerName ) ) );
01363 
01364             return false;
01365         }
01366         return true;
01367     }
01368 
01369     /// \privatesection
01370     /// The upload parameters.
01371     public $Parameters = false;
01372 }
01373 
01374 ?>