public function convert($mimeType) { if (Mime_Type::guessName($mimeType) != 'audio') { return true; // others care about inter media type conversions } $sourceType = Mime_Type::guessExtension($this->_object); $targetType = Mime_Type::guessExtension($mimeType); if ($this->_compress) { // do stuff... } $command = "{$this->_command} -t {$sourceType} - -t {$targetType} -"; rewind($this->_object); $temporary = fopen('php://temp', 'w'); $descr = array(0 => $this->_object, 1 => $temporary, 2 => array('pipe', 'a')); $process = proc_open($command, $descr, $pipes); fclose($pipes[2]); $return = proc_close($process); if ($return != 0) { //var_dump(stream_get_contents($temporary, -1, 0)); // throw new RuntimeException("Command `{$command}` returned `{$return}`."); return false; } $this->_object = $temporary; return true; }
public function convert($mimeType) { $sourceType = Mime_Type::guessExtension($this->_object); $targetType = Mime_Type::guessExtension($mimeType); $map = array('ogv' => 'ogg'); if (isset($map[$sourceType])) { $sourceType = $map[$sourceType]; } if (isset($map[$targetType])) { $targetType = $map[$targetType]; } $command = "{$this->_command} -f {$sourceType} -i - "; switch (Mime_Type::guessName($mimeType)) { case 'image': $command .= "-vcodec {$targetType} -vframes 1 -an -f rawvideo -"; break; case 'video': $command .= "-f {$targetType} -"; break; default: return true; } rewind($this->_object); $temporary = fopen('php://temp', 'w+b'); $descr = array(0 => $this->_object, 1 => $temporary, 2 => array('pipe', 'a')); $process = proc_open($command, $descr, $pipes); fclose($pipes[2]); $return = proc_close($process); if ($return != 0) { // throw new RuntimeException("Command `{$command}` returned `{$return}`."); return false; } $this->_object = $temporary; return true; }
protected function setUp() { $this->_files = dirname(dirname(dirname(dirname(__FILE__)))) . '/data'; $this->_data = dirname(dirname(dirname(dirname(dirname(__FILE__))))) . '/data'; Mime_Type::config('Magic', array('adapter' => 'Freedesktop', 'file' => $this->_data . '/magic.db')); Mime_Type::config('Glob', array('adapter' => 'Freedesktop', 'file' => $this->_data . '/glob.db')); }
protected function setUp() { $this->_files = dirname(dirname(dirname(__FILE__))) . '/data'; $this->_data = dirname(dirname(dirname(dirname(__FILE__)))) . '/data'; Media_Process::config(array('image' => new Media_Process_Adapter_GenericMock(null), 'audio' => new Media_Process_Adapter_GenericMock(null), 'document' => new Media_Process_Adapter_GenericMock(null), 'video' => new Media_Process_Adapter_GenericMock(null))); Mime_Type::config('Magic', array('adapter' => 'Freedesktop', 'file' => "{$this->_data}/magic.db")); Mime_Type::config('Glob', array('adapter' => 'Freedesktop', 'file' => "{$this->_data}/glob.db")); }
public function convert($mimeType) { if (Mime_Type::guessName($mimeType) != 'image') { return true; } if (isset($this->_formatMap[$mimeType])) { return $this->_format = $this->_formatMap[$mimeType]; } return false; }
public function convert($mimeType) { if (Mime_Type::guessName($mimeType) != 'image') { return true; } if (!isset($this->_formatMap[$mimeType])) { throw new OutOfBoundsException("MIME type `{$mimeType}` cannot be mapped to a format."); } return $this->_object->setFormat($this->_formatMap[$mimeType]); }
public function testConvertImageToImage() { $source = fopen("{$this->_files}/image_png.png", 'rb'); $target = fopen('php://temp', 'wb'); $subject = new Media_Process_Adapter_Gd($source); $subject->convert('image/jpeg'); $result = $subject->store($target); $this->assertType(PHPUnit_Framework_Constraint_IsType::TYPE_INT, $result); $this->assertEquals('image/jpeg', Mime_Type::guessType($target)); fclose($source); fclose($target); }
public function testConvert() { $source = fopen("{$this->_files}/audio_vorbis_comments.ogg", 'rb'); $target = fopen('php://temp', 'wb'); $subject = new Media_Process_Adapter_SoxShell($source); $subject->convert('audio/x-wav'); $result = $subject->store($target); $this->assertType(PHPUnit_Framework_Constraint_IsType::TYPE_INT, $result); $this->assertEquals('audio/x-wav', Mime_Type::guessType($target)); fclose($source); fclose($target); }
public function testConvertToVideo() { $source = fopen("{$this->_files}/video_theora_comments.ogv", 'rb'); $target = fopen('php://temp', 'wb'); $subject = new Media_Process_Adapter_FfmpegShell($source); $subject->convert('video/mpeg'); $result = $subject->store($target); $this->assertType(PHPUnit_Framework_Constraint_IsType::TYPE_INT, $result); $this->assertEquals('video/mpeg', Mime_Type::guessType($target)); fclose($source); fclose($target); }
public function convert($mimeType) { if (Mime_Type::guessName($mimeType) != 'audio') { return true; // others care about inter media type conversions } $sourceType = Mime_Type::guessExtension($this->_object); $targetType = Mime_Type::guessExtension($mimeType); $map = array('ogv' => 'ogg', 'oga' => 'ogg'); if (isset($map[$sourceType])) { $sourceType = $map[$sourceType]; } if (isset($map[$targetType])) { $targetType = $map[$targetType]; } $modify = null; if ($this->_sampleRate) { $modify .= " --rate {$this->_sampleRate}"; } if ($this->_channels) { $modify .= " --channels {$this->_channels}"; } rewind($this->_object); $error = fopen('php://temp', 'wrb+'); $targetFile = tempnam(sys_get_temp_dir(), 'mm_'); // Since SoX 14.3.0 multi threading is enabled which // paradoxically can cause huge slowdowns. $command = "{$this->_command} -q --single-threaded"; $command .= " -t {$sourceType} -{$modify} -t {$targetType} {$targetFile}"; $descr = array(0 => $this->_object, 1 => array('pipe', 'a'), 2 => array('pipe', 'a')); $process = proc_open($command, $descr, $pipes); fclose($pipes[1]); fclose($pipes[2]); $return = proc_close($process); // Workaround for header based formats which require the output stream to be seekable. $target = fopen($targetFile, 'rb'); $temporary = fopen('php://temp', 'wb+'); stream_copy_to_stream($target, $temporary); fclose($target); unlink($targetFile); if ($return != 0) { rewind($error); //var_dump(stream_get_contents($temporary, -1, 0)); // throw new RuntimeException("Command `{$command}` returned `{$return}`."); return false; } fclose($error); $this->_object = $temporary; return true; }
function transferTo($via, $from) { extract($from); $irregular = array('image' => 'img', 'text' => 'txt'); $name = Mime_Type::guessName($mimeType ? $mimeType : $file); if (isset($irregular[$name])) { $short = $irregular[$name]; } else { $short = substr($name, 0, 3); } $path = $short . DS; $path .= uniqid(); // <--- This is the important part. $path .= !empty($extension) ? '.' . strtolower($extension) : null; return $path; }
/** * Returns the relative path to the destination file * * @param array $via Information about the temporary file * @param array $from Information about the source file * @return string The path to the destination file or false */ public function transferTo($via, $from) { extract($from); $irregular = array('image' => 'img', 'text' => 'txt'); $name = Mime_Type::guessName($mimeType ? $mimeType : $file); if (empty($extension)) { $extension = Mime_Type::guessExtension($mimeType ? $mimeType : $file); } if (isset($irregular[$name])) { $short = $irregular[$name]; } else { $short = substr($name, 0, 3); } $path = $short . DS; $path .= strtolower(Inflector::underscore($this->model)) . DS; $path .= String::uuid(); $path .= !empty($extension) ? '.' . strtolower($extension) : null; return $path; }
/** * This factory method takes a source or an instance of an adapter, * guesses the type of media maps it to a media information class * and instantiates it. * * @param array $config Valid values are: * - `'source'`: An absolute path to a file. * - `'adapters'`: Names or instances of media adapters (i.e. `array('Gd')`). * @return Media_Process_Generic An instance of a subclass of `Media_Process_Generic` or * if type could not be mapped an instance of the that class * itself. */ public static function &factory(array $config = array()) { $default = array('source' => null, 'adapters' => array()); extract($config + $default); if (!$source) { throw new BadMethodCallException("No source given."); } $name = Mime_Type::guessName($source); if (!$adapters) { if (!isset(self::$_config[$name])) { throw new Exception("No adapters configured for media name `{$name}`."); } $adapters = self::$_config[$name]; } $name = ucfirst($name); $class = "Media_Info_{$name}"; require_once "Media/Info/{$name}.php"; $media = new $class(compact('source', 'adapters')); return $media; }
/** * This factory method takes a source or an instance of an adapter, * guesses the type of media maps it to a media processing class * and instantiates it. * * @param array $config Valid values are: * - `'source'`: An absolute path, a file or an open handle or * a MIME type if `'adapter'` is an instance. * - `'adapter'`: A name or instance of a media adapter (i.e. `'Gd'`). * @return Media_Process_Generic An instance of a subclass of `Media_Process_Generic` or * if type could not be mapped an instance of the that class * itself. */ public static function &factory(array $config = array()) { $default = array('source' => null, 'adapter' => null); extract($config + $default); if (!$source) { throw new BadMethodCallException("No source given."); } $name = Mime_Type::guessName($source); if (!$adapter) { if (!isset(self::$_config[$name])) { throw new Exception("No adapter configured for media name `{$name}`."); } $adapter = self::$_config[$name]; } $name = ucfirst($name); $class = "Media_Process_{$name}"; if (!class_exists($class)) { // Allows for injecting arbitrary classes. require_once "Media/Process/{$name}.php"; } $media = new $class(compact('source', 'adapter')); return $media; }
/** * Takes an array of paths and generates and array of source items. * * @param array $paths An array of relative or absolute paths to files. * @param boolean $full When `true` will generate absolute URLs. * @return array An array of sources each one with the keys `name`, `mimeType`, `url` and `file`. */ function _sources($paths, $full = false) { $sources = array(); foreach ($paths as $path) { if (!($url = $this->url($path, $full))) { return; } if (strpos('://', $path) !== false) { $file = parse_url($url, PHP_URL_PATH); } else { $file = $this->file($path); } $mimeType = Mime_Type::guessType($file); $name = Mime_Type::guessName($mimeType); $sources[] = compact('name', 'mimeType', 'url', 'file'); } return $sources; }
public function testGuessNameFile() { $map = array('video_flash_snippet.flv' => 'video', 'audio_ogg_snippet.ogg' => 'audio', 'xml_snippet.xml' => 'generic', 'image_png.png' => 'image'); foreach ($map as $file => $name) { $this->assertEquals($name, Mime_Type::guessName($this->_files . '/' . $file), "File `{$file}`."); } }
/** * Generate a version of a file. If this method is reimplemented in the * model, than that one is used by `make()` instead of the implementation * below. * * $process an array with the following contents: * - `directory`: The destination directory (If this method was called * by `make()` the directory is already created) * - `version`: The version requested to be processed (e.g. `'l'`) * - `instructions`: An array specifying processing steps to execute on $file * in order to get to the desired transformed file. * * Each instruction is either a key/value pair where the key * can be thought of the method and the value the arguments * passed to that method. Whenever a value appears without a * corresponding string key it is used as the method instead. * * `array('name of method', 'name of other method')` * `array('name of method' => array('arg1', 'arg2'))` * * Most methods are made available through the `Media_Process_*` * classes. The class is chosen depending on the type of media * being processed. Since each one of those classes exposes * different methods the availaibility of those depends on the * type of media being processed. * * Please see the documentation for the mm library for further * information on the `Media_Process_*` classes mentioned above. * * However some methods are builtin and made available directly * through this method here. One of them being the `clone` method. * Cloning allows instructions which don't actually modify a file * but represent just a copy of it. Available clone types are `copy`, * `link` and `symlink`. * * `array('clone' => <type>)` * * In case an instruction method is neither builtin nor available * through one of the `Media_Proces_*` classes, the `passthru()` * method is invoked on that media object. The concrete implementation * of `passthru()` and therefore how it deals with the data passed * to it *highly* depends on the adapter in use. * * @link https://github.com/davidpersson/mm The PHP media library. * @param Model $Model * @param string $file Absolute path to the source file * @param array $process directory, version, instructions * @return boolean `true` if version for the file was successfully stored */ function makeVersion(&$Model, $file, $process) { extract($this->settings[$Model->alias]); /* Process builtin instructions */ if (isset($process['instructions']['clone'])) { $action = $process['instructions']['clone']; if (!in_array($action, array('copy', 'link', 'symlink'))) { return false; } $destination = $this->_destinationFile($file, $process['directory'], null, $overwrite); if (!$destination) { return false; } if (!call_user_func($action, $file, $destination)) { return false; } return $action == 'copy' ? chmod($destination, $mode) : true; } /* Process `Media_Process_*` instructions */ $Media = Media_Process::factory(array('source' => $file)); foreach ($process['instructions'] as $method => $args) { if (is_int($method)) { $method = $args; $args = null; } if (method_exists($Media, $method)) { $result = call_user_func_array(array($Media, $method), (array) $args); } else { $result = $Media->passthru($method, $args); } if ($result === false) { return false; } elseif (is_a($result, 'Media_Process_Generic')) { $Media = $result; } } /* Determine destination file */ $extension = null; if ($guessExtension) { if (isset($process['instructions']['convert'])) { $extension = Mime_Type::guessExtension($process['instructions']['convert']); } else { $extension = Mime_Type::guessExtension($file); } } $destination = $this->_destinationFile($file, $process['directory'], $extension, $overwrite); if (!$destination) { return false; } return $Media->store($destination) && chmod($destination, $mode); }
/** * Generates markup to link to file * * @param string $path Absolute or partial path to a file * @param array $options * @return mixed * @deprecated */ function link($path, $options = array()) { $message = "MediaHelper::link - "; $message .= "All functionality related to assets has been deprecated."; trigger_error($message, E_USER_NOTICE); $default = array('inline' => true, 'restrict' => array()); $defaultRss = array('title' => 'RSS Feed'); if (is_bool($options)) { $options = array('inline' => $options); } $options = array_merge($default, $options); if (is_array($path) && !array_key_exists('controller', $path)) { $out = null; foreach ($path as $i) { $out .= $this->link($i, $options); } if (empty($out)) { return; } return $out; } $inline = $options['inline']; unset($options['inline']); if (!($url = $this->url($path))) { return; } if (strpos('://', $path) !== false) { $file = parse_url($url, PHP_URL_PATH); } else { $file = $this->file($path); } $mimeType = Mime_Type::guessType($file); $name = Mime_Type::guessName($mimeType); if ($options['restrict'] && !in_array($name, (array) $options['restrict'])) { return; } unset($options['restrict']); switch ($mimeType) { case 'text/css': $out = sprintf($this->tags['csslink'], $url, $this->_parseAttributes($options, null, '', ' ')); return $this->output($out, $inline); case 'application/javascript': case 'application/x-javascript': $out = sprintf($this->tags['javascriptlink'], $url); return $this->output($out, $inline); case 'application/rss+xml': $options = array_merge($defaultRss, $options); $out = sprintf($this->tags['rsslink'], $url, $options['title']); return $this->output($out, $inline); default: return $this->Html->link(basename($file), $url); } }
/** * Retrieve (cached) metadata of a file * * @param Model $Model * @param string $file An absolute path to a file * @param integer $level level of amount of info to add, `0` disable, `1` for basic, `2` for detailed info * @return mixed Array with results or false if file is not readable */ function metadata(&$Model, $file, $level = 1) { if ($level < 1) { return array(); } extract($this->settings[$Model->alias]); $File = new File($file); if (!$File->readable()) { return false; } $checksum = $File->md5(true); if (isset($this->__cached[$Model->alias][$checksum])) { $data = $this->__cached[$Model->alias][$checksum]; } if ($level > 0 && !isset($data[1])) { $data[1] = array('size' => $File->size(), 'mime_type' => Mime_Type::guessType($File->pwd()), 'checksum' => $checksum); } if ($level > 1 && !isset($data[2])) { $data[2] = array(); try { $Info = Media_Info::factory(array('source' => $File->pwd())); foreach ($Info->all() as $key => $value) { $data[2][Inflector::underscore($key)] = $value; } } catch (Exception $E) { } } for ($i = $level, $result = array(); $i > 0; $i--) { $result = array_merge($result, $data[$i]); } $this->__cached[$Model->alias][$checksum] = $data; return $result; }
/** * Converts the media to given MIME type. * * @param string $mimeType * @return boolean|object false on error or a Media object on success */ public function convert($mimeType) { if (!$this->_adapter->convert($mimeType)) { return false; } if ($this->name() != Mime_Type::guessName($mimeType)) { // i.e. document -> image $config = Media_Process::config(); if ($config[$this->name()] == $config[Mime_Type::guessName($mimeType)]) { $media = Media_Process::factory(array('source' => $mimeType, 'adapter' => $this->_adapter)); } else { $handle = fopen('php://temp', 'w+'); if (!$this->_adapter->store($handle)) { // err } $media = Media_Process::factory(array('source' => $handle)); fclose($handle); } return $media; } return $this; }
/** * Returns the configured filter array * * @param Model $Model * @param string $file * @return array */ public function filter(Model $Model, $file) { $name = Mime_Type::guessName($file); $filter = $this->settings[$Model->alias]['filter']; $filters = (array) Configure::read('Media.filter'); $default = false; if (!is_array($filter)) { if (array_key_exists($filter, $filters)) { $filter = $filters[$filter]; } else { $filter = $filters; $default = true; } } if ($default !== true && $this->settings[$Model->alias]['mergeFilter'] === true) { $filter = array_merge($filters, $filter); } // TODO Maybe trigger a notice in case no filter is defined for the given MIME-Type. if (!isset($filter[$name])) { return array(); } return $filter[$name]; }
public function testPassthru() { $source = fopen("{$this->_files}/image_png.png", 'rb'); $target = fopen('php://temp', 'wb'); $subject = new Media_Process_Adapter_Imagick($source); $subject->passthru('setFormat', 'jpeg'); $result = $subject->store($target); $this->assertInternalType('integer', $result); $this->assertEquals('image/jpeg', Mime_Type::guessType($target)); fclose($source); fclose($target); }
* @see MetaBehavior * @see MediaHelper */ require_once 'Mime/Type.php'; if ($hasFileinfo) { Mime_Type::config('Magic', array('adapter' => 'Fileinfo')); } else { Mime_Type::config('Magic', array('adapter' => 'Freedesktop', 'file' => $mm . DS . 'data' . DS . 'magic.db')); } if ($cached = Cache::read('mime_type_glob')) { Mime_Type::config('Glob', array('adapter' => 'Memory')); foreach ($cached as $item) { Mime_Type::$glob->register($item); } } else { Mime_Type::config('Glob', array('adapter' => 'Freedesktop', 'file' => $mm . DS . 'data' . DS . 'glob.db')); Cache::write('mime_type_glob', Mime_Type::$glob->to('array')); } /** * Configure the adpters to be used by media process class. Adjust this * mapping of media names to adapters according to your environment. For example: * most PHP installations have GD enabled thus should choose the `Gd` adapter for * image transformations. However the `Imagick` adapter may be more desirable * in other cases and also supports transformations for documents. * * @see GeneratorBehavior */ require_once 'Media/Process.php'; Media_Process::config(array('document' => $hasImagick ? 'Imagick' : null, 'image' => $hasImagick ? 'Imagick' : 'Gd')); /** * Configure the adpters to be used by media info class. Adjust this
public function testGuessNameResource() { $handleA = fopen("{$this->_files}/application_pdf.pdf", 'rb'); $handleB = fopen('php://temp', 'rb+'); stream_copy_to_stream($handleA, $handleB); $this->assertEquals('document', Mime_Type::guessName($handleA)); $this->assertEquals('document', Mime_Type::guessName($handleB)); fclose($handleA); fclose($handleB); }
/** * Generate a version of a file. If this method is reimplemented in the * model, than that one is used by `make()` instead of the implementation * below. * * $process an array with the following contents: * - `directory`: The destination directory (If this method was called * by `make()` the directory is already created) * - `version`: The version requested to be processed (e.g. `'l'`) * - `instructions`: An array containing which names of methods to be called. * Possible instructions are: * - `array('name of method', 'name of other method')` * - `array('name of method' => array('arg1', 'arg2'))` * @param Model $Model * @param string $file Absolute path to the source file * @param array $process directory, version, instructions * @return boolean `true` if version for the file was successfully stored */ function makeVersion(&$Model, $file, $process) { extract($this->settings[$Model->alias]); /* Process clone instruction */ if (isset($process['instructions']['clone'])) { $action = $process['instructions']['clone']; if (!in_array($action, array('copy', 'link', 'symlink'))) { return false; } $destination = $this->_destinationFile($file, $process['directory'], null, $overwrite); if (!$destination) { return false; } return call_user_func($action, $file, $destination) && chmod($destination, $mode); } /* Process media transforms */ try { $Media = Media_Process::factory(array('source' => $file)); } catch (Exception $E) { return false; } foreach ($process['instructions'] as $key => $value) { if (is_int($key)) { $method = $value; $args = null; } else { $method = $key; $args = (array) $value; } if (!method_exists($Media, $method)) { return false; } $result = call_user_func_array(array($Media, $method), $args); if ($result === false) { return false; } elseif (is_a($result, 'Media_Process_Generic')) { $Media = $result; } } /* Determine destination file */ $extension = null; if ($guessExtension) { if (isset($process['instructions']['convert'])) { $extension = Mime_Type::guessExtension($process['instructions']['convert']); } else { $extension = Mime_Type::guessExtension($file); } } $destination = $this->_destinationFile($file, $process['directory'], $extension, $overwrite); if (!$destination) { return false; } return $Media->store($destination) && chmod($destination, $mode); }
public static function reset() { self::$glob = self::$magic = null; }
/** * Checks if resource has (not) one of given MIME types * * This check is less strict in that it isn't sensitive to MIME types with or * without properties or experimental indicators. This holds true for the type * which is subject of the check as well as types provided for $deny and * $allow. I.e. `audio/x-ogg` will be allowed if $allow contains `audio/ogg` * and `video/ogg` works also if $allow contains the stricter `video/x-ogg`. * * @param Model $Model * @param array $field * @param mixed $deny True or * blocks any MIME type, * an array containing MIME types selectively blocks, * false blocks no MIME type * @param mixed $allow True or * allows any extension, * an array containing extensions selectively allows, * false allows no MIME type * @return boolean */ function checkMimeType(&$Model, $field, $deny = false, $allow = true) { extract($this->runtime[$Model->alias]); extract($this->settings[$Model->alias], EXTR_SKIP); foreach (array('source', 'temporary') as $type) { /* * MIME types and trustClient setting * * trust | source | (temporary) | (destination) * ------|----------|---------------------------- * true | x/x | x/x | x/x,null * ------|----------|---------------------------- * false | x/x,null | x/x,null | null */ /* Temporary is optional */ if ($type === 'temporary' && empty(${$type})) { continue; } /* With `trustClient` set to `false` we don't necessarily have a MIME type */ if (!isset(${$type}['mimeType']) && !$trustClient) { continue; } $result = MediaValidation::mimeType(${$type}['mimeType'], $deny, $allow); $result |= MediaValidation::mimeType(Mime_Type::simplify(${$type}['mimeType']), $deny, $allow); return $result; } return true; }
protected function _type($object) { $type = Mime_Type::guessExtension($object); $map = array('ogv' => 'ogg', 'oga' => 'ogg'); return isset($map[$type]) ? $map[$type] : $type; }
public function testMakeVersionUnknownMethodsArePassedThrough() { $config = Media_Process::config(); $message = 'Need imagick media processing adapters configured for both image.'; $skipped = $this->skipIf(!isset($config['image']) || $config['image'] != 'Imagick', $message); if ($skipped) { return; } $Model = ClassRegistry::init('Unicorn', 'Model'); $Model->Behaviors->load('Media.Generator', $this->behaviorSettings); $directory = $this->Data->settings['filter'] . 's' . DS; mkdir($directory); $file = $this->Data->getFile(array('image-jpg.jpg' => 'image.jpg')); $result = $Model->Behaviors->Generator->makeVersion($Model, $file, array('version' => 's', 'directory' => $directory, 'instructions' => array('setFormat' => 'png'))); $this->assertTrue($result); $mimeType = Mime_Type::guessType($directory . 'image.jpg', array('paranoid' => true)); $this->assertEqual($mimeType, 'image/png'); }
/** * Reimplements the TransferBehavior::transferTo() method from Media plugin * * @access public * @return array */ function transferTo($via, $from) { extract($from); $irregular = array('image' => 'img', 'text' => 'txt'); $name = Mime_Type::guessName($mimeType ? $mimeType : $file); if (isset($irregular[$name])) { $short = $irregular[$name]; } else { $short = substr($name, 0, 3); } $extension = !empty($extension) ? '.' . strtolower($extension) : null; $newFilename = uniqid('', true) . $extension; $this->data[$this->alias]['original_filename'] = $filename . $extension; return $short . DS . $newFilename; }