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