/** * @param Schema $schema * @return void */ public function up(Schema $schema) { $this->abortIf($this->connection->getDatabasePlatform()->getName() != "postgresql"); $resourcesResult = $this->connection->executeQuery('SELECT persistence_object_identifier, sha1, filename FROM typo3_flow_resource_resource'); while ($resourceInfo = $resourcesResult->fetch(\PDO::FETCH_ASSOC)) { $resourcePathAndFilename = FLOW_PATH_DATA . 'Persistent/Resources/' . wordwrap($resourceInfo['sha1'], 5, '/', true) . '/' . $resourceInfo['sha1']; $newResourcePathAndFilename = FLOW_PATH_DATA . 'Persistent/Resources/' . $resourceInfo['sha1'][0] . '/' . $resourceInfo['sha1'][1] . '/' . $resourceInfo['sha1'][2] . '/' . $resourceInfo['sha1'][3] . '/' . $resourceInfo['sha1']; if (!file_exists($newResourcePathAndFilename)) { if (!file_exists($resourcePathAndFilename)) { $this->write(sprintf('<warning>Could not move the data file of resource "%s" from its legacy location at "%s" to the correct location "%s" because the source file does not exist.', $resourceInfo['sha1'], $resourcePathAndFilename, $newResourcePathAndFilename)); continue; } if (!file_exists(dirname($newResourcePathAndFilename))) { Files::createDirectoryRecursively(dirname($newResourcePathAndFilename)); } if (@rename($resourcePathAndFilename, $newResourcePathAndFilename) === false) { $this->write(sprintf('<warning>Could not move the data file of resource "%s" from its legacy location at "%s" to the correct location "%s".', $resourceInfo['sha1'], $resourcePathAndFilename, $newResourcePathAndFilename)); } Files::removeEmptyDirectoriesOnPath(dirname($resourcePathAndFilename)); } } }
/** * Removes the specified target file from the public directory * * This method fails silently if the given file could not be unpublished or already didn't exist anymore. * * @param string $relativeTargetPathAndFilename relative path and filename in the target directory * @return void */ protected function unpublishFile($relativeTargetPathAndFilename) { $targetPathAndFilename = $this->path . $relativeTargetPathAndFilename; if (!file_exists($targetPathAndFilename)) { return; } if (!Files::unlink($targetPathAndFilename)) { return; } Files::removeEmptyDirectoriesOnPath(dirname($targetPathAndFilename)); }
/** * Deletes the storage data related to the given Resource object * * @param PersistentResource $resource The Resource to delete the storage data of * @return boolean TRUE if removal was successful */ public function deleteResource(PersistentResource $resource) { $pathAndFilename = $this->getStoragePathAndFilenameByHash($resource->getSha1()); if (!file_exists($pathAndFilename)) { return true; } if (unlink($pathAndFilename) === false) { return false; } Files::removeEmptyDirectoriesOnPath(dirname($pathAndFilename)); return true; }
/** * @test * @expectedException \TYPO3\Flow\Utility\Exception */ public function removeEmptyDirectoriesOnPathThrowsExceptionIfBasePathIsNotParentOfPath() { Files::createDirectoryRecursively('vfs://Foo/Bar/Baz/Quux'); Files::removeEmptyDirectoriesOnPath('vfs://Foo/Bar/Baz/Quux', 'vfs://Other/Bar'); }
/** * Move resource files back to the old locations and adjust records. * * @param Schema $schema * @return void */ public function postDown(Schema $schema) { $resourcesResult = $this->connection->executeQuery('SELECT DISTINCT resourcepointer FROM typo3_flow_resource_resource'); while ($resourceInfo = $resourcesResult->fetch(\PDO::FETCH_ASSOC)) { $this->connection->executeQuery('INSERT INTO typo3_flow_resource_resourcepointer (hash) VALUES (?)', array($resourceInfo['resourcepointer'])); $resourcePathAndFilename = FLOW_PATH_DATA . 'Persistent/Resources/' . $resourceInfo['resourcepointer'][0] . '/' . $resourceInfo['resourcepointer'][1] . '/' . $resourceInfo['resourcepointer'][2] . '/' . $resourceInfo['resourcepointer'][3] . '/' . $resourceInfo['resourcepointer']; if (!file_exists($resourcePathAndFilename)) { $this->write(sprintf('Error while migrating database for the old resource management: the resource file "%s" was not found.', $resourcePathAndFilename)); continue; } $newResourcePathAndFilename = FLOW_PATH_DATA . 'Persistent/Resources/' . $resourceInfo['resourcepointer']; $result = @rename($resourcePathAndFilename, $newResourcePathAndFilename); if ($result === FALSE) { $this->write(sprintf('Could not move the data file of resource "%s" from its location at %s to the legacy location %s.', $resourceInfo['resourcepointer'], $resourcePathAndFilename, $newResourcePathAndFilename)); } Files::removeEmptyDirectoriesOnPath(dirname($resourcePathAndFilename)); } $this->connection->exec('UPDATE typo3_flow_resource_resource SET fileextension = substring(filename from \'\\.(.+)$\')'); $this->connection->exec('ALTER TABLE typo3_flow_resource_resource ALTER fileextension SET NOT NULL'); $this->connection->exec('ALTER TABLE typo3_flow_resource_resource ADD CONSTRAINT fk_b4d45b323cb65d1 FOREIGN KEY (resourcepointer) REFERENCES typo3_flow_resource_resourcepointer (hash) NOT DEFERRABLE INITIALLY IMMEDIATE'); }
/** * Deletes the storage data related to the given Resource object * * @param \TYPO3\Flow\Resource\Resource $resource The Resource to delete the storage data of * @return boolean TRUE if removal was successful */ public function deleteResource(Resource $resource) { $pathAndFilename = $this->getStoragePathAndFilenameByHash($resource->getSha1()); if (!file_exists($pathAndFilename)) { return TRUE; } if (unlink($pathAndFilename) === FALSE) { return FALSE; } Files::removeEmptyDirectoriesOnPath(dirname($pathAndFilename)); return TRUE; }