/** * If it's a Uploadable object, verify if the file was uploaded. * If that's the case, process it. * * @param \Gedmo\Mapping\Event\AdapterInterface $ea * @param $object * @param $action * @throws \Gedmo\Exception\UploadableNoPathDefinedException * @throws \Gedmo\Exception\UploadableCouldntGuessMimeTypeException * @throws \Gedmo\Exception\UploadableMaxSizeException * @throws \Gedmo\Exception\UploadableInvalidMimeTypeException */ public function processFile(AdapterInterface $ea, $object, $action) { $oid = spl_object_hash($object); $om = $ea->getObjectManager(); $uow = $om->getUnitOfWork(); $meta = $om->getClassMetadata(get_class($object)); $config = $this->getConfiguration($om, $meta->name); if (!$config || !isset($config['uploadable']) || !$config['uploadable']) { // Nothing to do return; } $refl = $meta->getReflectionClass(); $fileInfo = $this->fileInfoObjects[$oid]['fileInfo']; $evm = $om->getEventManager(); if ($evm->hasListeners(Events::uploadablePreFileProcess)) { $evm->dispatchEvent(Events::uploadablePreFileProcess, new UploadablePreFileProcessEventArgs($this, $om, $config, $fileInfo, $object, $action)); } // Validations if ($config['maxSize'] > 0 && $fileInfo->getSize() > $config['maxSize']) { $msg = 'File "%s" exceeds the maximum allowed size of %d bytes. File size: %d bytes'; throw new UploadableMaxSizeException(sprintf($msg, $fileInfo->getName(), $config['maxSize'], $fileInfo->getSize())); } $mime = $this->mimeTypeGuesser->guess($fileInfo->getTmpName()); if (!$mime) { throw new UploadableCouldntGuessMimeTypeException(sprintf('Couldn\'t guess mime type for file "%s".', $fileInfo->getName())); } if ($config['allowedTypes'] || $config['disallowedTypes']) { $ok = $config['allowedTypes'] ? false : true; $mimes = $config['allowedTypes'] ? $config['allowedTypes'] : $config['disallowedTypes']; foreach ($mimes as $m) { if ($mime === $m) { $ok = $config['allowedTypes'] ? true : false; break; } } if (!$ok) { throw new UploadableInvalidMimeTypeException(sprintf('Invalid mime type "%s" for file "%s".', $mime, $fileInfo->getName())); } } $filePathField = $refl->getProperty($config['filePathField']); $filePathField->setAccessible(true); $path = $config['path']; if ($path === '') { if ($config['pathMethod'] !== '') { $pathMethod = $refl->getMethod($config['pathMethod']); $pathMethod->setAccessible(true); $path = $pathMethod->invoke($object); } else { if ($this->getDefaultPath() !== null) { $path = $this->getDefaultPath(); } else { $msg = 'You have to define the path to save files either in the listener, or in the class "%s"'; throw new UploadableNoPathDefinedException(sprintf($msg, $meta->name)); } } } Validator::validatePath($path); $path = substr($path, strlen($path) - 1) === '/' ? substr($path, 0, strlen($path) - 2) : $path; if ($config['fileMimeTypeField']) { $fileMimeTypeField = $refl->getProperty($config['fileMimeTypeField']); $fileMimeTypeField->setAccessible(true); } if ($config['fileSizeField']) { $fileSizeField = $refl->getProperty($config['fileSizeField']); $fileSizeField->setAccessible(true); } if ($action === self::ACTION_UPDATE) { // First we add the original file to the pendingFileRemovals array $this->pendingFileRemovals[] = $this->getFilePath($meta, $config, $object); } // We generate the filename based on configuration $generatorNamespace = 'Gedmo\\Uploadable\\FilenameGenerator'; switch ($config['filenameGenerator']) { case Validator::FILENAME_GENERATOR_ALPHANUMERIC: $generatorClass = $generatorNamespace . '\\FilenameGeneratorAlphanumeric'; break; case Validator::FILENAME_GENERATOR_SHA1: $generatorClass = $generatorNamespace . '\\FilenameGeneratorSha1'; break; case Validator::FILENAME_GENERATOR_NONE: $generatorClass = false; break; default: $generatorClass = $config['filenameGenerator']; } $info = $this->moveFile($fileInfo, $path, $generatorClass, $config['allowOverwrite'], $config['appendNumber']); // We override the mime type with the guessed one $info['fileMimeType'] = $mime; $filePathField->setValue($object, $info['filePath']); if ($config['callback'] !== '') { $callbackMethod = $refl->getMethod($config['callback']); $callbackMethod->setAccessible(true); $callbackMethod->invokeArgs($object, array($info)); } $changes = array($config['filePathField'] => array($filePathField->getValue($object), $info['filePath'])); if ($config['fileMimeTypeField']) { $changes[$config['fileMimeTypeField']] = array($fileMimeTypeField->getValue($object), $info['fileMimeType']); $this->updateField($object, $uow, $ea, $meta, $config['fileMimeTypeField'], $info['fileMimeType']); } if ($config['fileSizeField']) { $changes[$config['fileSizeField']] = array($fileSizeField->getValue($object), $info['fileSize']); $this->updateField($object, $uow, $ea, $meta, $config['fileSizeField'], $info['fileSize']); } $this->updateField($object, $uow, $ea, $meta, $config['filePathField'], $info['filePath']); $ea->recomputeSingleObjectChangeSet($uow, $meta, $object); if ($evm->hasListeners(Events::uploadablePostFileProcess)) { $evm->dispatchEvent(Events::uploadablePostFileProcess, new UploadablePostFileProcessEventArgs($this, $om, $config, $fileInfo, $object, $action)); } unset($this->fileInfoObjects[$oid]); }
/** * @expectedException Gedmo\Exception\UploadableCantWriteException */ public function test_validatePath_ifPassedDirIsNotAValidDirectoryOrIsNotWriteableThrowException() { Validator::validatePath('/invalid/directory/12312432423'); }
/** * @param ClassMetadata $meta * @param array $config * @param object $object Entity * * @return string * * @throws UploadableNoPathDefinedException */ protected function getPath(ClassMetadata $meta, array $config, $object) { $path = $config['path']; if ($path === '') { $defaultPath = $this->getDefaultPath(); if ($config['pathMethod'] !== '') { $pathMethod = $meta->getReflectionClass()->getMethod($config['pathMethod']); $pathMethod->setAccessible(true); $path = $pathMethod->invoke($object, $defaultPath); } elseif ($defaultPath !== null) { $path = $defaultPath; } else { $msg = 'You have to define the path to save files either in the listener, or in the class "%s"'; throw new UploadableNoPathDefinedException(sprintf($msg, $meta->name)); } } Validator::validatePath($path); $path = rtrim($path, '\\/'); return $path; }
public function test_validatePath_ifPassedDirIsNotAValidDirectoryOrIsNotWriteableDoesNotThrowExceptionIfDisabled() { Validator::$validateWritableDirectory = false; Validator::validatePath('/invalid/directory/12312432423'); Validator::$validateWritableDirectory = true; }