static function changeMIMEType(&$mimeInfo, $mimetype)
 {
     $mimeInfo['name'] = $mimetype;
     $newMimeInfo = eZMimeType::findByName($mimetype);
     $mimeInfo['suffixes'] = $newMimeInfo['suffixes'];
     $mimeInfo['prefixes'] = $newMimeInfo['prefixes'];
     $mimeInfo['suffix'] = $newMimeInfo['suffix'];
     $mimeInfo['prefix'] = $newMimeInfo['prefix'];
     $filename = $mimeInfo['filename'];
     $dotPosition = strrpos($filename, '.');
     $basename = $filename;
     if ($dotPosition !== false) {
         $basename = substr($filename, 0, $dotPosition);
     }
     $mimeInfo['filename'] = $basename . '.' . $mimeInfo['suffix'];
     if ($mimeInfo['dirpath']) {
         $mimeInfo['url'] = $mimeInfo['dirpath'] . '/' . $mimeInfo['filename'];
     } else {
         $mimeInfo['url'] = $mimeInfo['filename'];
     }
 }
 function outputMIMEType(&$manager, $currentMimeData, $wantedMimeData, $supportedFormatsOriginal, $aliasName = false)
 {
     if (is_array($this->conversionRules())) {
         $conversionRules = array_merge($manager->conversionRules(), $this->conversionRules());
     } else {
         $conversionRules = $manager->conversionRules();
     }
     $mimeData = false;
     $mimeType = false;
     if (!$this->isInputMIMETypeSupported($currentMimeData)) {
         return false;
     }
     if ($wantedMimeData) {
         $conversionRules = array_merge(array(array('from' => $currentMimeData['name'], 'to' => $wantedMimeData['name'])), $conversionRules);
     }
     $supportedFormats = array();
     foreach ($supportedFormatsOriginal as $supportedFormat) {
         if ($this->isOutputMIMETypeSupported($supportedFormat)) {
             $supportedFormats[] = $supportedFormat;
             $conversionRules[] = array('from' => $supportedFormat, 'to' => $supportedFormat);
         }
     }
     if ($wantedMimeData and in_array($wantedMimeData['name'], $supportedFormats)) {
         $mimeType = $wantedMimeData['name'];
     } else {
         if (is_array($conversionRules)) {
             foreach ($conversionRules as $rule) {
                 if (!$this->isOutputMIMETypeSupported($rule['to']) or !in_array($rule['to'], $supportedFormats)) {
                     continue;
                 }
                 $matchRule = false;
                 if (strpos($rule['from'], '*') !== false) {
                     $matchString = eZImageHandler::wildcardToRegexp($rule['from']);
                     if (preg_match("#^" . $matchString . "\$#", $currentMimeData['name'])) {
                         $matchRule = $rule;
                     }
                 } else {
                     if ($rule['from'] == $currentMimeData['name']) {
                         $matchRule = $rule;
                     }
                 }
                 if ($matchRule) {
                     if ($mimeType) {
                         if ($wantedMimeData and $matchRule['to'] == $wantedMimeData['name']) {
                             $mimeType = $matchRule['to'];
                         }
                     } else {
                         $mimeType = $matchRule['to'];
                     }
                 }
             }
         }
     }
     if ($mimeType) {
         $mimeData = eZMimeType::findByName($mimeType);
         $this->rewriteURL($currentMimeData, $mimeData, $this->outputRewriteType(), $aliasName);
     }
     return $mimeData;
 }
 /**
  * Gathers information about a given node specified as parameter.
  *
  * The format of the returned array is:
  * <code>
  * array( 'name' => node name (eg. 'Group picture'),
  *        'size' => storage size of the_node in bytes (eg. 57123),
  *        'mimetype' => mime type of the node (eg. 'image/jpeg'),
  *        'ctime' => creation time as timestamp,
  *        'mtime' => latest modification time as timestamp,
  *        'href' => the path to the node (eg. '/plain_site_user/Content/Folder1/file1.jpg')
  * </code>
  *
  * @param string $target Eg. '/plain_site_user/Content/Folder1/file1.jpg
  * @param eZContentObject &$node The node corresponding to $target
  * @return array(string=>mixed)
  * @todo remove/replace .ini calls, eZContentUpload, eZMimeType, eZSys RequestURI
  * @todo handle articles as files
  */
 protected function fetchNodeInfo($target, &$node)
 {
     // When finished, we'll return an array of attributes/properties.
     $entry = array();
     $classIdentifier = $node->attribute('class_identifier');
     $object = $node->attribute('object');
     $urlAlias = $node->urlAlias();
     // By default, everything is displayed as a folder:
     // Trim the name of the node, it is in some cases whitespace in eZ Publish
     $name = trim($node->attribute('name'));
     // @as 2009-03-09: return node_id as displayname in case name is missing
     // displayname is not actually used by WebDAV clients
     $entry["name"] = $name !== '' && $name !== NULL ? $name : $node->attribute('node_id');
     $entry["size"] = 0;
     $entry["mimetype"] = self::DIRECTORY_MIMETYPE;
     eZWebDAVContentBackend::appendLogEntry('FetchNodeInfo:' . $node->attribute('name') . '/' . $urlAlias);
     // @todo handle articles as files
     // if ( $classIdentifier === 'article' )
     // {
     //     $entry["mimetype"] = 'application/ms-word';
     // }
     $entry["ctime"] = $object->attribute('published');
     $entry["mtime"] = $object->attribute('modified');
     $upload = new eZContentUpload();
     $info = $upload->objectFileInfo($object);
     $suffix = '';
     $class = $object->contentClass();
     $isObjectFolder = $this->isObjectFolder($object, $class);
     if ($isObjectFolder) {
         // We do nothing, the default is to see it as a folder
     } else {
         if ($info) {
             $filePath = $info['filepath'];
             $entry['filepath'] = $filePath;
             $entry["mimetype"] = false;
             $entry["size"] = false;
             if (isset($info['filesize'])) {
                 $entry['size'] = $info['filesize'];
             }
             if (isset($info['mime_type'])) {
                 $entry['mimetype'] = $info['mime_type'];
             }
             // Fill in information from the actual file if they are missing.
             $file = eZClusterFileHandler::instance($filePath);
             if (!$entry['size'] and $file->exists()) {
                 $entry["size"] = $file->size();
             }
             if (!$entry['mimetype']) {
                 $mimeInfo = eZMimeType::findByURL($filePath);
                 $entry["mimetype"] = $mimeInfo['name'];
                 $suffix = $mimeInfo['suffix'];
                 if (strlen($suffix) > 0) {
                     $entry["name"] .= '.' . $suffix;
                 }
             } else {
                 // eZMimeType returns first suffix in its list
                 // this could be another one than the original file extension
                 // so let's try to get the suffix from the file path first
                 $suffix = eZFile::suffix($filePath);
                 if (!$suffix) {
                     $mimeInfo = eZMimeType::findByName($entry['mimetype']);
                     $suffix = $mimeInfo['suffix'];
                 }
                 if (strlen($suffix) > 0) {
                     $entry["name"] .= '.' . $suffix;
                 }
             }
             if ($file->exists()) {
                 $entry["ctime"] = $file->mtime();
                 $entry["mtime"] = $file->mtime();
             }
         } else {
             // Here we only show items as folders if they have
             // is_container set to true, otherwise it's an unknown binary file
             if (!$class->attribute('is_container')) {
                 $entry['mimetype'] = 'application/octet-stream';
             }
         }
     }
     $scriptURL = $target;
     if (strlen($scriptURL) > 0 and $scriptURL[strlen($scriptURL) - 1] !== "/") {
         $scriptURL .= "/";
     }
     $trimmedScriptURL = trim($scriptURL, '/');
     $scriptURLParts = explode('/', $trimmedScriptURL);
     $urlPartCount = count($scriptURLParts);
     if ($urlPartCount >= 2) {
         // one of the virtual folders
         // or inside one of the virtual folders
         $siteAccess = $scriptURLParts[0];
         $virtualFolder = $scriptURLParts[1];
         // only when the virtual folder is Content we need to add its path to the start URL
         // the paths of other top level folders (like Media) are included in URL aliases of their descending nodes
         if ($virtualFolder === self::virtualContentFolderName()) {
             $startURL = '/' . $siteAccess . '/' . $virtualFolder . '/';
         } else {
             if ($virtualFolder === self::virtualMediaFolderName()) {
                 $startURL = '/' . $siteAccess . '/' . $virtualFolder . '/';
                 $urlAlias = substr($urlAlias, strpos($urlAlias, '/') + 1);
             } else {
                 $startURL = '/' . $siteAccess . '/';
             }
         }
     } else {
         // site access level
         $startURL = $scriptURL;
     }
     // Set the href attribute (note that it doesn't just equal the name).
     if (!isset($entry['href'])) {
         if (strlen($suffix) > 0) {
             $suffix = '.' . $suffix;
         }
         $entry["href"] = $startURL . $urlAlias . $suffix;
     }
     // Return array of attributes/properties (name, size, mime, times, etc.).
     return $entry;
 }
    function fetchNodeInfo( &$node )
    {
        // When finished, we'll return an array of attributes/properties.
        $entry = array();

        // Grab settings from the ini file:
        $webdavINI = eZINI::instance( eZWebDAVContentServer::WEBDAV_INI_FILE );
        $iniSettings = $webdavINI->variable( 'DisplaySettings', 'FileAttribute' );

        $classIdentifier = $node->attribute( 'class_identifier' );

        $object = $node->attribute( 'object' );

        // By default, everything is displayed as a folder:
        // Trim the name of the node, it is in some cases whitespace in eZ Publish
        $entry["name"] = trim( $node->attribute( 'name' ) );
        $entry["size"] = 0;
        $entry["mimetype"] = 'httpd/unix-directory';
        $entry["ctime"] = $object->attribute( 'published' );
        $entry["mtime"] = $object->attribute( 'modified' );

        $upload = new eZContentUpload();
        $info = $upload->objectFileInfo( $object );
        $suffix = '';
        $class = $object->contentClass();
        $isObjectFolder = $this->isObjectFolder( $object, $class );

        if ( $isObjectFolder )
        {
            // We do nothing, the default is to see it as a folder
        }
        else if ( $info )
        {
            $filePath = $info['filepath'];
            $entry["mimetype"] = false;
            $entry["size"] = false;
            if ( isset( $info['filesize'] ) )
                $entry['size'] = $info['filesize'];
            if ( isset( $info['mime_type'] ) )
                $entry['mimetype'] = $info['mime_type'];

            // Fill in information from the actual file if they are missing.
            $file = eZClusterFileHandler::instance( $filePath );
            if ( !$entry['size'] and $file->exists() )
            {
                $entry["size"] = $file->size();
            }
            if ( !$entry['mimetype']  )
            {
                $mimeInfo = eZMimeType::findByURL( $filePath );
                $entry["mimetype"] = $mimeInfo['name'];
                $suffix = $mimeInfo['suffix'];
                if ( strlen( $suffix ) > 0 )
                    $entry["name"] .= '.' . $suffix;
            }
            else
            {
                // eZMimeType returns first suffix in its list
                // this could be another one than the original file extension
                // so let's try to get the suffix from the file path first
                $suffix = eZFile::suffix( $filePath );
                if ( !$suffix )
                {
                    $mimeInfo = eZMimeType::findByName( $entry['mimetype'] );
                    $suffix = $mimeInfo['suffix'];
                }
                if ( strlen( $suffix ) > 0 )
                    $entry["name"] .= '.' . $suffix;
            }

            if ( $file->exists() )
            {
                $entry["ctime"] = $file->mtime();
                $entry["mtime"] = $file->mtime();
            }
        }
        else
        {
            // Here we only show items as folders if they have
            // is_container set to true, otherwise it's an unknown binary file
            if ( !$class->attribute( 'is_container' ) )
            {
                $entry['mimetype'] = 'application/octet-stream';
            }
        }

        $scriptURL = eZSys::instance()->RequestURI;
        if ( strlen( $scriptURL ) > 0 and $scriptURL[ strlen( $scriptURL ) - 1 ] != "/" )
            $scriptURL .= "/";

        $trimmedScriptURL = trim( $scriptURL, '/' );
        $scriptURLParts = explode( '/', $trimmedScriptURL );

        $siteAccess = $scriptURLParts[0];
        $virtualFolder = $scriptURLParts[1];

        $startURL = '/' . $siteAccess . '/' . $virtualFolder . '/';

        // Set the href attribute (note that it doesn't just equal the name).
        if ( !isset( $entry['href'] ) )
        {
            if ( strlen( $suffix ) > 0 )
                $suffix = '.' . $suffix;

            $alias = $node->urlAlias();
            if ( $virtualFolder == eZWebDAVContentServer::virtualMediaFolderName() )
            {
                // remove the real media node url alias, the virtual media folder is already in $startURL
                $aliasParts = explode( '/', $alias );
                array_shift( $aliasParts );
                $alias = implode( '/', $aliasParts );
            }
            $entry["href"] = $startURL . $alias . $suffix;
        }
        // Return array of attributes/properties (name, size, mime, times, etc.).
        return $entry;
    }
Exemple #5
0
 /**
  * Initializes the content object attribute with the uploaded HTTP file
  *
  * @param eZHTTPFile $httpFile
  * @param string $imageAltText Optional image ALT text
  *
  * @return TODO: FIXME
  */
 function initializeFromHTTPFile($httpFile, $imageAltText = false)
 {
     $this->increaseImageSerialNumber();
     $mimeData = eZMimeType::findByFileContents($httpFile->attribute('filename'));
     if (!$mimeData['is_valid']) {
         $mimeData = eZMimeType::findByName($httpFile->attribute('mime_type'));
         if (!$mimeData['is_valid']) {
             $mimeData = eZMimeType::findByURL($httpFile->attribute('original_filename'));
         }
     }
     $attr = false;
     $this->removeAliases($attr);
     $this->setOriginalAttributeDataValues($this->ContentObjectAttributeData['id'], $this->ContentObjectAttributeData['version'], $this->ContentObjectAttributeData['language_code']);
     $contentVersion = eZContentObjectVersion::fetchVersion($this->ContentObjectAttributeData['version'], $this->ContentObjectAttributeData['contentobject_id']);
     $objectName = $this->imageName($this->ContentObjectAttributeData, $contentVersion);
     $objectPathString = $this->imagePath($this->ContentObjectAttributeData, $contentVersion, true);
     eZMimeType::changeBaseName($mimeData, $objectName);
     eZMimeType::changeDirectoryPath($mimeData, $objectPathString);
     $httpFile->store(false, false, $mimeData);
     $originalFilename = $httpFile->attribute('original_filename');
     return $this->initialize($mimeData, $originalFilename, $imageAltText);
 }
    /**
     * Creates the image alias $aliasName if it's not already part of the
     * existing aliases
     *
     * @param string $aliasName Name of the alias to create
     * @param array $existingAliasList
     *        Reference to the current alias list. The created alias will be
     *        added to the list.
     * @param array $parameters
     *        Optional array that can be used to specify the image's basename
     * @return bool true if the alias was created, false if it wasn't
     */
    function createImageAlias( $aliasName, &$existingAliasList, $parameters = array() )
    {
        $fname = "createImageAlias( $aliasName )";

        // check for $aliasName validity
        $aliasList = $this->aliasList();
        if ( !isset( $aliasList[$aliasName] ) )
        {
            eZDebug::writeWarning( "Alias name $aliasName does not exist, cannot create it" );
            return false;
        }

        // check if the reference alias is defined, and if no, use original as ref
        $currentAliasInfo = $aliasList[$aliasName];
        $referenceAlias = $currentAliasInfo['reference'];
        if ( $referenceAlias and !$this->hasAlias( $referenceAlias ) )
        {
            eZDebug::writeError( "The referenced alias '$referenceAlias' for image alias '$aliasName' does not exist, cannot use it for reference.\n" .
                                 "Will use 'original' alias instead.",
                                 __METHOD__ );
            $referenceAlias = false;
        }
        if ( !$referenceAlias )
            $referenceAlias = 'original';

        // generate the reference alias if it hasn't been generated yet
        $hasReference = false;
        if ( array_key_exists( $referenceAlias, $existingAliasList ) )
        {
            $fileHandler = eZClusterFileHandler::instance();
            if ( $fileHandler->fileExists( $existingAliasList[$referenceAlias]['url'] ) )
            {
                $hasReference = true;
            }
            else
            {
                eZDebug::writeError( "The reference alias $referenceAlias file {$existingAliasList[$referenceAlias]['url']} does not exist", __METHOD__ );
            }
        }
        if ( !$hasReference )
        {
            $ini = eZINI::instance( 'image.ini' );
            
            if ( $ini->hasVariable( 'AliasSettings', 'AlwaysGenerate') && $ini->variable( 'AliasSettings', 'AlwaysGenerate' ) == 'enabled' ) 
            {
                $mimeData = eZMimeType::findByURL( $existingAliasList[$referenceAlias]['url'] );
                $destinationMimeData = eZMimeType::findByName( $mimeData['name'] );

                if ( $aliasName != 'original' )
                {
                    foreach ( array( 'url', 'filename', 'basename') as $k )
                    {
                        $mimeData[$k] = preg_replace('#(\.[^.]+)$#', '_'.strtolower($aliasName).'.'.$destinationMimeData['suffix'], $mimeData[$k]);
                    }
                }
                $existingAliasList[$aliasName] = $mimeData;
                return true;
            } 
            else 
            {
                if ( $referenceAlias == 'original' )
                {
                    eZDebug::writeError( "Original alias does not exist, cannot create other aliases without it" );
                    return false;
                }
                if ( !$this->createImageAlias( $referenceAlias, $existingAliasList, $parameters ) )
                {
                    eZDebug::writeError( "Failed creating the referenced alias $referenceAlias, cannot create alias $aliasName", __METHOD__ );
                    return false;
                }
            }
        }

        // from now on, our reference image (either reference or original)
        // exists
        $aliasInfo = $existingAliasList[$referenceAlias];
        $aliasFilePath = $aliasInfo['url'];
        $aliasKey = $currentAliasInfo['alias_key'];

        $sourceMimeData = eZMimeType::findByFileContents( $aliasFilePath );

        /**
         * at first, destinationMimeData (mimedata for the alias we're
         * generating) is the same as sourceMimeData. It will evolve as
         * alias generation goes on
         */
        $destinationMimeData = $sourceMimeData;
        if ( isset( $parameters['basename'] ) )
        {
            $sourceMimeData['basename'] = $parameters['basename'];
            eZMimeType::changeBasename( $destinationMimeData, $parameters['basename'] );
        }

        /**
         * Concurrency protection
         * startCacheGeneration will return true if the file is not
         * already being generated by another process. If it is, it will
         * return the maximum time before the generating process enters
         * generation timeout
         */
        while ( true )
        {
            $convertHandler = eZClusterFileHandler::instance( $sourceMimeData['url'] );
            $startGeneration = $convertHandler->startCacheGeneration();
            if ( $startGeneration === true )
            {
                $destinationMimeData['is_valid'] = false;
                if ( $this->convert( $sourceMimeData, $destinationMimeData, $aliasName, $parameters ) )
                {
                    /**
                     * At this point, we consider that the image exists and destinationMimeData
                     * has been filled with the proper information
                     *
                     * If we were locked during alias generation, we need to recreate
                     * this structure so that the image can actually be used, but ONLY
                     * if it was the same alias... sounds like a HUGE mess.
                     *
                     * Can we reload the alias list somehow ?
                     */
                    $currentAliasData = array( 'url' => $destinationMimeData['url'],
                                               'dirpath' => $destinationMimeData['dirpath'],
                                               'filename' => $destinationMimeData['filename'],
                                               'suffix' => $destinationMimeData['suffix'],
                                               'basename' => $destinationMimeData['basename'],
                                               'alternative_text' => $aliasInfo['alternative_text'],
                                               'name' => $aliasName,
                                               'sub_type' => false,
                                               'timestamp' => time(),
                                               'alias_key' => $aliasKey,
                                               'mime_type' => $destinationMimeData['name'],
                                               'override_mime_type' => false,
                                               'info' => false,
                                               'width' => false,
                                               'height' => false,
                                               'is_valid' => true,
                                               'is_new' => true );

                    if ( isset( $destinationMimeData['override_mime_type'] ) )
                        $currentAliasData['override_mime_type'] = $destinationMimeData['override_mime_type'];
                    if ( isset( $destinationMimeData['info'] ) )
                        $currentAliasData['info'] = $destinationMimeData['info'];
                    $currentAliasData['full_path'] = $currentAliasData['url'];

                    if ( function_exists( 'getimagesize' ) )
                    {
                        /**
                         * we may want to fetch a unique name here, since we won't use
                         * the data for anything else
                         */
                        $fileHandler = eZClusterFileHandler::instance( $destinationMimeData['url'] );
                        if ( $tempPath = $fileHandler->fetchUnique() )
                        {
                            $info = getimagesize( $tempPath );
                            if ( $info )
                            {
                                list( $currentAliasData['width'], $currentAliasData['height'] ) = $info;
                            }
                            else
                            {
                                eZDebug::writeError("The size of the generated image {$destinationMimeData['url']} could not be read by getimagesize()", __METHOD__ );
                            }
                            $fileHandler->fileDeleteLocal( $tempPath );
                        }
                        else
                        {
                            eZDebug::writeError( "The destination image {$destinationMimeData['url']} does not exist, cannot figure out image size", __METHOD__ );
                        }
                    }
                    else
                    {
                        eZDebug::writeError( "Unknown function 'getimagesize', cannot get image size", __METHOD__ );
                    }
                    $existingAliasList[$aliasName] = $currentAliasData;

                    $convertHandler->endCacheGeneration( false );

                    // Notify about image alias generation. Parameters are alias
                    // url and alias name.
                    ezpEvent::getInstance()->notify( 'image/alias', array( $currentAliasData['url'],
                                                                           $currentAliasData['name'] ) );
                    
                    return true;
                }
                // conversion failed, we abort generation
                else
                {
                    $sourceFile = $sourceMimeData['url'];
                    $destinationDir = $destinationMimeData['dirpath'];
                    eZDebug::writeError( "Failed converting $sourceFile to alias '$aliasName' in directory '$destinationDir'", __METHOD__ );
                    $convertHandler->abortCacheGeneration();
                    return false;
                }
            }
            // we were not granted file generation (someone else is doing it)
            // we wait for max. $remainingGenerationTime and check if the
            // file has been generated in between
            // Actually, we have no clue if the generated file was the one we were
            // looking for, and it doesn't seem possible to RELOAD the alias list.
            // We don't even know what attribute we're using... CRAP
            else
            {
                eZDebug::writeDebug( "An alias is already being generated for this image, let's wait", __METHOD__ );
                while ( true )
                {
                    $startGeneration = $convertHandler->startCacheGeneration();
                    // generation lock granted: we can start again by breaking to
                    // the beggining of the while loop
                    if ( $startGeneration === true )
                    {
                        eZDebug::writeDebug( "Got granted generation permission, restarting !", __METHOD__ );
                        $convertHandler->abortCacheGeneration();
                        continue 2;
                    }
                    else
                    {
                        sleep( 1 );
                    }
                }
            }
        }
        return false;
    }