/** * {@inheritedDoc} */ protected function releaseTreeLocks(ObjectManager $om, AdapterInterface $ea) { $uow = $om->getUnitOfWork(); foreach ($this->rootsOfTreesWhichNeedsLocking as $oid => $root) { $meta = $om->getClassMetadata(get_class($root)); $config = $this->listener->getConfiguration($om, $meta->name); $lockTimeProp = $meta->getReflectionProperty($config['lock_time']); $lockTimeProp->setAccessible(true); $lockTimeValue = null; $lockTimeProp->setValue($root, $lockTimeValue); $changes = array($config['lock_time'] => array(null, null)); $uow->scheduleExtraUpdate($root, $changes); $ea->setOriginalObjectProperty($uow, $oid, $config['lock_time'], $lockTimeValue); unset($this->rootsOfTreesWhichNeedsLocking[$oid]); } }
/** * {@inheritdoc} */ public function processPostPersist($em, $entity, AdapterInterface $ea) { $uow = $em->getUnitOfWork(); while ($node = array_shift($this->pendingChildNodeInserts)) { $meta = $em->getClassMetadata(get_class($node)); $config = $this->listener->getConfiguration($em, $meta->name); $identifier = $meta->getSingleIdentifierFieldName(); $nodeId = $meta->getReflectionProperty($identifier)->getValue($node); $parent = $meta->getReflectionProperty($config['parent'])->getValue($node); $closureClass = $config['closure']; $closureMeta = $em->getClassMetadata($closureClass); $closureTable = $closureMeta->getTableName(); $ancestorColumnName = $this->getJoinColumnFieldName($em->getClassMetadata($config['closure'])->getAssociationMapping('ancestor')); $descendantColumnName = $this->getJoinColumnFieldName($em->getClassMetadata($config['closure'])->getAssociationMapping('descendant')); $depthColumnName = $em->getClassMetadata($config['closure'])->getColumnName('depth'); $entries = array(array($ancestorColumnName => $nodeId, $descendantColumnName => $nodeId, $depthColumnName => 0)); if ($parent) { $dql = "SELECT c, a FROM {$closureMeta->name} c"; $dql .= " JOIN c.ancestor a"; $dql .= " WHERE c.descendant = :parent"; $q = $em->createQuery($dql); $q->setParameters(compact('parent')); $ancestors = $q->getArrayResult(); foreach ($ancestors as $ancestor) { $entries[] = array($ancestorColumnName => $ancestor['ancestor']['id'], $descendantColumnName => $nodeId, $depthColumnName => $ancestor['depth'] + 1); } if (isset($config['level'])) { $this->pendingNodesLevelProcess[$nodeId] = $node; } } else { if (isset($config['level'])) { $uow->scheduleExtraUpdate($node, array($config['level'] => array(null, 1))); $ea->setOriginalObjectProperty($uow, spl_object_hash($node), $config['level'], 1); } } foreach ($entries as $closure) { if (!$em->getConnection()->insert($closureTable, $closure)) { throw new RuntimeException('Failed to insert new Closure record'); } } } // Process pending node updates if (!empty($this->pendingNodeUpdates)) { foreach ($this->pendingNodeUpdates as $info) { $this->updateNode($em, $info['node'], $info['oldParent']); } $this->pendingNodeUpdates = array(); } // Process TreeLevel field value $this->setLevelFieldOnPendingNodes($em); }
/** * If it's a Uploadable object, verify if the file was uploaded. * If that's the case, process it. * * @param UnitOfWork * @param AdapterInterface * @param ClassMetadata * @param array - Configuration * @param object - The entity * @param string - String representing the action (insert or update) * * @return void */ public function processFile(UnitOfWork $uow, AdapterInterface $ea, ClassMetadata $meta, array $config, $object, $action) { $refl = $meta->getReflectionClass(); $oid = spl_object_hash($object); if (!isset($this->fileInfoObjects[$oid])) { // Nothing to do return; } $fileInfo = $this->fileInfoObjects[$oid]; // 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']); $ea->setOriginalObjectProperty($uow, $oid, $config['fileMimeTypeField'], $info['fileMimeType']); } if ($config['fileSizeField']) { $changes[$config['fileSizeField']] = array($fileSizeField->getValue($object), $info['fileSize']); $ea->setOriginalObjectProperty($uow, $oid, $config['fileSizeField'], $info['fileSize']); } $uow->scheduleExtraUpdate($object, $changes); $ea->setOriginalObjectProperty($uow, $oid, $config['filePathField'], $info['filePath']); unset($this->fileInfoObjects[$oid]); }