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; }
/** * 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; }