This commit is contained in:
Benoît Burnichon
2016-02-03 18:56:21 +01:00
parent 58b80bf08a
commit afde09645a
8 changed files with 236 additions and 132 deletions

View File

@@ -22,13 +22,13 @@ class SubdefServiceProvider implements ServiceProviderInterface
public function register(SilexApplication $app) public function register(SilexApplication $app)
{ {
$app['subdef.generator'] = $app->share(function (Application $app) { $app['subdef.generator'] = $app->share(function (Application $app) {
$generator = new SubdefGenerator($app, $app['media-alchemyst'], $app['filesystem'], $app['mediavorus'], isset($app['task-manager.logger']) ? $app['task-manager.logger'] : $app['monolog']); $generator = new SubdefGenerator($app, $app['media-alchemyst'], $app['phraseanet.filesystem'], $app['mediavorus'], isset($app['task-manager.logger']) ? $app['task-manager.logger'] : $app['monolog']);
$generator->setDispatcher($app['dispatcher']); $generator->setDispatcher($app['dispatcher']);
return $generator; return $generator;
}); });
$app['subdef.substituer'] = $app->share(function (Application $app) { $app['subdef.substituer'] = $app->share(function (Application $app) {
return new SubdefSubstituer($app, $app['filesystem'], $app['media-alchemyst'], $app['mediavorus'], $app['dispatcher']); return new SubdefSubstituer($app, $app['phraseanet.filesystem'], $app['media-alchemyst'], $app['mediavorus'], $app['dispatcher']);
}); });
} }

View File

@@ -0,0 +1,208 @@
<?php
/**
* This file is part of Phraseanet
*
* (c) 2005-2016 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Alchemy\Phrasea\Filesystem;
use MediaAlchemyst\Specification\SpecificationInterface;
class FilesystemService
{
/**
* @var \Symfony\Component\Filesystem\Filesystem
*/
private $filesystem;
public function __construct(\Symfony\Component\Filesystem\Filesystem $filesystem)
{
$this->filesystem = $filesystem;
}
/**
* @param string $repository_path
* @return string
*/
public function directorySpread($repository_path)
{
$repository_path = \p4string::addEndSlash($repository_path);
$timestamp = strtotime(date('Y-m-d'));
$year = date('Y', $timestamp);
$month = date('m', $timestamp);
$day = date('d', $timestamp);
$comp = $year . DIRECTORY_SEPARATOR . $month . DIRECTORY_SEPARATOR . $day . DIRECTORY_SEPARATOR;
$n = 0;
do {
$pathout = sprintf('%s%s%05d', $repository_path, $comp, $n++);
} while (is_dir($pathout) && iterator_count(new \DirectoryIterator($pathout)) > 100);
$this->filesystem->mkdir($pathout, 0750);
return $pathout . DIRECTORY_SEPARATOR;
}
public function exists($path)
{
return $this->filesystem->exists($path);
}
public function generateSubdefPathname(\record_adapter $record, \databox_subdef $subdef, $oldVersion)
{
if ($oldVersion) {
$pathdest = \p4string::addEndSlash(pathinfo($oldVersion, PATHINFO_DIRNAME));
} else {
$pathdest = $this->directorySpread($subdef->get_path());
}
return $pathdest . $this->generateSubdefFilename($record, $subdef);
}
/**
* @param \record_adapter $record
* @param string|\SplFileInfo $source
* @return string
*/
public function generateDocumentFilename(\record_adapter $record, $source)
{
if (!$source instanceof \SplFileInfo) {
$source = new \SplFileInfo($source);
}
return $record->getRecordId() . '_document' . strtolower($source->getExtension());
}
/**
* @param \record_adapter $record
* @param \databox_subdef $subdef
* @param string $marker
* @return string
*/
public function generateSubdefFilename(\record_adapter $record, \databox_subdef $subdef, $marker = '')
{
return $record->getRecordId() . '_' . $marker . $subdef->get_name() . '.' . $this->getExtensionFromSpec($subdef->getSpecs());
}
public function generateSubdefSubstitutionPathname(\record_adapter $record, \databox_subdef $subdef)
{
$pathdest = $this->directorySpread($subdef->get_path());
return $pathdest . $this->generateSubdefFilename($record, $subdef, '0_');
}
/**
* @param \databox $databox
* @return string
*/
public function generateDataboxDocumentBasePath(\databox $databox)
{
$baseprefs = $databox->get_sxml_structure();
return $this->directorySpread(\p4string::addEndSlash((string)($baseprefs->path)));
}
/**
* Write Media source file with given filename
*
* @param \databox $databox
* @param string $source
* @param string $filename
*/
public function writeMediaSourceFile(\databox $databox, $source, $filename)
{
$realPath = $this->generateDataboxDocumentBasePath($databox) . $filename;
$this->filesystem->copy($source, $realPath, true);
$this->filesystem->chmod($realPath, 0760);
}
/**
* Copy file from source to target
*
* @param string $source
* @param string $target
*/
public function copy($source, $target)
{
$this->filesystem->copy($source, $target, true);
}
public function chmod($files, $mode, $umask = 0000, $recursive = false)
{
$this->filesystem->chmod($files, $mode, $umask, $recursive);
}
/**
* Get the extension from MediaAlchemyst specs
*
* @param SpecificationInterface $spec
*
* @return string
*/
private function getExtensionFromSpec(SpecificationInterface $spec)
{
switch ($spec->getType()) {
case SpecificationInterface::TYPE_IMAGE:
return 'jpg';
case SpecificationInterface::TYPE_ANIMATION:
return 'gif';
case SpecificationInterface::TYPE_AUDIO:
return $this->getExtensionFromAudioCodec($spec->getAudioCodec());
case SpecificationInterface::TYPE_VIDEO:
return $this->getExtensionFromVideoCodec($spec->getVideoCodec());
case SpecificationInterface::TYPE_SWF:
return 'swf';
}
return null;
}
/**
* Get the extension from audiocodec
*
* @param string $audioCodec
*
* @return string
*/
private function getExtensionFromAudioCodec($audioCodec)
{
switch ($audioCodec) {
case 'flac':
return 'flac';
case 'libvorbis':
return 'ogg';
case 'libmp3lame':
return 'mp3';
}
return null;
}
/**
* Get the extension from videocodec
*
* @param string $videoCodec
*
* @return string
*/
private function getExtensionFromVideoCodec($videoCodec)
{
switch ($videoCodec) {
case 'libtheora':
return 'ogv';
case 'libvpx':
return 'webm';
case 'libx264':
return 'mp4';
}
return null;
}
}

View File

@@ -21,7 +21,7 @@ class FilesystemServiceProvider implements ServiceProviderInterface
public function register(Application $app) public function register(Application $app)
{ {
$app['filesystem'] = $app->share(function () { $app['filesystem'] = $app->share(function () {
new Filesystem(); return new Filesystem();
}); });
$app['temporary-filesystem.temporary-fs'] = $app->share(function (Application $app) { $app['temporary-filesystem.temporary-fs'] = $app->share(function (Application $app) {
@@ -30,6 +30,10 @@ class FilesystemServiceProvider implements ServiceProviderInterface
$app['temporary-filesystem'] = $app->share(function (Application $app) { $app['temporary-filesystem'] = $app->share(function (Application $app) {
return new Manager($app['temporary-filesystem.temporary-fs'], $app['filesystem']); return new Manager($app['temporary-filesystem.temporary-fs'], $app['filesystem']);
}); });
$app['phraseanet.filesystem'] = $app->share(function (Application $app) {
return new FilesystemService($app['filesystem']);
});
} }
public function boot(Application $app) public function boot(Application $app)

View File

@@ -18,12 +18,11 @@ use Alchemy\Phrasea\Core\Event\Record\SubDefinitionCreationEvent;
use Alchemy\Phrasea\Core\Event\Record\SubDefinitionsCreationEvent; use Alchemy\Phrasea\Core\Event\Record\SubDefinitionsCreationEvent;
use Alchemy\Phrasea\Core\Event\Record\SubDefinitionCreationFailedEvent; use Alchemy\Phrasea\Core\Event\Record\SubDefinitionCreationFailedEvent;
use Alchemy\Phrasea\Core\Event\Record\RecordEvents; use Alchemy\Phrasea\Core\Event\Record\RecordEvents;
use Alchemy\Phrasea\Filesystem\FilesystemService;
use MediaAlchemyst\Alchemyst; use MediaAlchemyst\Alchemyst;
use MediaAlchemyst\Specification\SpecificationInterface;
use MediaVorus\MediaVorus; use MediaVorus\MediaVorus;
use MediaAlchemyst\Exception\ExceptionInterface as MediaAlchemystException; use MediaAlchemyst\Exception\ExceptionInterface as MediaAlchemystException;
use Psr\Log\LoggerInterface; use Psr\Log\LoggerInterface;
use Symfony\Component\Filesystem\Filesystem;
class SubdefGenerator class SubdefGenerator
{ {
@@ -38,7 +37,7 @@ class SubdefGenerator
private $logger; private $logger;
private $mediavorus; private $mediavorus;
public function __construct(Application $app, Alchemyst $alchemyst, Filesystem $filesystem, MediaVorus $mediavorus, LoggerInterface $logger) public function __construct(Application $app, Alchemyst $alchemyst, FilesystemService $filesystem, MediaVorus $mediavorus, LoggerInterface $logger)
{ {
$this->app = $app; $this->app = $app;
$this->alchemyst = $alchemyst; $this->alchemyst = $alchemyst;
@@ -78,7 +77,7 @@ class SubdefGenerator
$record->clearSubdefCache($subdefname); $record->clearSubdefCache($subdefname);
} }
$pathdest = $this->generateSubdefPathname($record, $subdef, $pathdest); $pathdest = $this->filesystem->generateSubdefPathname($record, $subdef, $pathdest);
$this->dispatch( $this->dispatch(
RecordEvents::SUB_DEFINITION_CREATION, RecordEvents::SUB_DEFINITION_CREATION,
@@ -141,82 +140,4 @@ class SubdefGenerator
$this->logger->error(sprintf('Subdef generation failed for record %d with message %s', $record->getRecordId(), $e->getMessage())); $this->logger->error(sprintf('Subdef generation failed for record %d with message %s', $record->getRecordId(), $e->getMessage()));
} }
} }
private function generateSubdefPathname(\record_adapter $record, \databox_subdef $subdef, $oldVersion = null)
{
if ($oldVersion) {
$pathdest = \p4string::addEndSlash(pathinfo($oldVersion, PATHINFO_DIRNAME));
} else {
$pathdest = \databox::dispatch($this->filesystem, $subdef->get_path());
}
return $pathdest . $record->getRecordId() . '_' . $subdef->get_name() . '.' . $this->getExtensionFromSpec($subdef->getSpecs());
}
/**
* Get the extension from MediaAlchemyst specs
*
* @param SpecificationInterface $spec
*
* @return string
*/
private function getExtensionFromSpec(SpecificationInterface $spec)
{
switch ($spec->getType()) {
case SpecificationInterface::TYPE_IMAGE:
return 'jpg';
case SpecificationInterface::TYPE_ANIMATION:
return 'gif';
case SpecificationInterface::TYPE_AUDIO:
return $this->getExtensionFromAudioCodec($spec->getAudioCodec());
case SpecificationInterface::TYPE_VIDEO:
return $this->getExtensionFromVideoCodec($spec->getVideoCodec());
case SpecificationInterface::TYPE_SWF:
return 'swf';
}
return null;
}
/**
* Get the extension from audiocodec
*
* @param string $audioCodec
*
* @return string
*/
private function getExtensionFromAudioCodec($audioCodec)
{
switch ($audioCodec) {
case 'flac':
return 'flac';
case 'libvorbis':
return 'ogg';
case 'libmp3lame':
return 'mp3';
}
return null;
}
/**
* Get the extension from videocodec
*
* @param string $videoCodec
*
* @return string
*/
private function getExtensionFromVideoCodec($videoCodec)
{
switch ($videoCodec) {
case 'libtheora':
return 'ogv';
case 'libvpx':
return 'webm';
case 'libx264':
return 'mp4';
}
return null;
}
} }

View File

@@ -13,12 +13,12 @@ namespace Alchemy\Phrasea\Media;
use Alchemy\Phrasea\Application; use Alchemy\Phrasea\Application;
use Alchemy\Phrasea\Core\Event\Record\MediaSubstitutedEvent; use Alchemy\Phrasea\Core\Event\Record\MediaSubstitutedEvent;
use Alchemy\Phrasea\Core\Event\Record\RecordEvents; use Alchemy\Phrasea\Core\Event\Record\RecordEvents;
use Alchemy\Phrasea\Filesystem\FilesystemService;
use MediaAlchemyst\Alchemyst; use MediaAlchemyst\Alchemyst;
use MediaAlchemyst\Exception\ExceptionInterface as MediaAlchemystException; use MediaAlchemyst\Exception\ExceptionInterface as MediaAlchemystException;
use MediaVorus\Media\MediaInterface; use MediaVorus\Media\MediaInterface;
use MediaVorus\MediaVorus; use MediaVorus\MediaVorus;
use Symfony\Component\EventDispatcher\EventDispatcherInterface; use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\Filesystem\Filesystem;
class SubdefSubstituer class SubdefSubstituer
{ {
@@ -26,7 +26,7 @@ class SubdefSubstituer
private $fs; private $fs;
private $mediavorus; private $mediavorus;
public function __construct(Application $app, Filesystem $fs, Alchemyst $alchemyst, MediaVorus $mediavorus, EventDispatcherInterface $dispatcher) public function __construct(Application $app, FilesystemService $fs, Alchemyst $alchemyst, MediaVorus $mediavorus, EventDispatcherInterface $dispatcher)
{ {
$this->alchemyst = $alchemyst; $this->alchemyst = $alchemyst;
$this->app = $app; $this->app = $app;
@@ -56,18 +56,15 @@ class SubdefSubstituer
public function substituteDocument(\record_adapter $record, MediaInterface $media) public function substituteDocument(\record_adapter $record, MediaInterface $media)
{ {
$baseprefs = $record->getDatabox()->get_sxml_structure(); /** @var \SplFileInfo $file */
$pathhd = \databox::dispatch($this->fs, \p4string::addEndSlash((string) ($baseprefs->path))); $file = $media->getFile();
$extension = strtolower($media->getFile()->getExtension()); $source = $file->getRealPath();
$filehd = $record->getRecordId() . "_document." . $extension; $target = $this->fs->generateDocumentFilename($record, $file);
$subdefFile = $pathhd . $filehd; $this->fs->writeMediaSourceFile($record->getDatabox(), $source, $target);
$this->fs->copy($media->getFile()->getRealPath(), $subdefFile, true); $media = $this->mediavorus->guess($source);
$this->fs->chmod($subdefFile, 0760);
$media = $this->mediavorus->guess($subdefFile);
$this->createMediaSubdef($record, 'document', $media); $this->createMediaSubdef($record, 'document', $media);
@@ -98,9 +95,7 @@ class SubdefSubstituer
$record->get_subdef($name)->remove_file(); $record->get_subdef($name)->remove_file();
$record->clearSubdefCache($name); $record->clearSubdefCache($name);
} else { } else {
$path = \databox::dispatch($this->fs, $databox_subdef->get_path()); $path_file_dest = $this->fs->generateSubdefSubstitutionPathname($record, $databox_subdef);
$this->fs->mkdir($path, 0750);
$path_file_dest = $path . $record->getRecordId() . '_0_' . $name . '.' . $media->getFile()->getExtension();
} }
if($adapt) { if($adapt) {

View File

@@ -158,23 +158,9 @@ class databox extends base implements ThumbnailedElement
public static function dispatch(Filesystem $filesystem, $repository_path) public static function dispatch(Filesystem $filesystem, $repository_path)
{ {
$repository_path = p4string::addEndSlash($repository_path); $filesystem = new \Alchemy\Phrasea\Filesystem\FilesystemService($filesystem);
$timestamp = strtotime(date('Y-m-d')); return $filesystem->directorySpread($repository_path);
$year = date('Y', $timestamp);
$month = date('m', $timestamp);
$day = date('d', $timestamp);
$comp = $year . DIRECTORY_SEPARATOR . $month . DIRECTORY_SEPARATOR . $day . DIRECTORY_SEPARATOR;
$n = 0;
do {
$pathout = sprintf('%s%s%05d', $repository_path, $comp, $n++);
} while (is_dir($pathout) && iterator_count(new DirectoryIterator($pathout)) > 100);
$filesystem->mkdir($pathout, 0750);
return $pathout . DIRECTORY_SEPARATOR;
} }
public static function get_available_dcfields() public static function get_available_dcfields()

View File

@@ -1,5 +1,4 @@
<?php <?php
/* /*
* This file is part of Phraseanet * This file is part of Phraseanet
* *
@@ -75,10 +74,6 @@ class databox_subdefsStructure implements IteratorAggregate, Countable
return null; return null;
} }
/**
*
* @return databox_subdefsStructure
*/
protected function load_subdefs() protected function load_subdefs()
{ {
$sx_struct = $this->databox->get_sxml_structure(); $sx_struct = $this->databox->get_sxml_structure();
@@ -92,7 +87,7 @@ class databox_subdefsStructure implements IteratorAggregate, Countable
]; ];
if (! $sx_struct) { if (! $sx_struct) {
return $this; return;
} }
$subdefgroup = $sx_struct->subdefs[0]; $subdefgroup = $sx_struct->subdefs[0];
@@ -132,8 +127,6 @@ class databox_subdefsStructure implements IteratorAggregate, Countable
} }
} }
$this->AvSubdefs = $avSubdefs; $this->AvSubdefs = $avSubdefs;
return $this;
} }
/** /**

View File

@@ -20,6 +20,7 @@ use Alchemy\Phrasea\Core\Event\Record\RecordEvent;
use Alchemy\Phrasea\Core\Event\Record\RecordEvents; use Alchemy\Phrasea\Core\Event\Record\RecordEvents;
use Alchemy\Phrasea\Core\Event\Record\StatusChangedEvent; use Alchemy\Phrasea\Core\Event\Record\StatusChangedEvent;
use Alchemy\Phrasea\Core\PhraseaTokens; use Alchemy\Phrasea\Core\PhraseaTokens;
use Alchemy\Phrasea\Filesystem\FilesystemService;
use Alchemy\Phrasea\Media\ArrayTechnicalDataSet; use Alchemy\Phrasea\Media\ArrayTechnicalDataSet;
use Alchemy\Phrasea\Media\FloatTechnicalData; use Alchemy\Phrasea\Media\FloatTechnicalData;
use Alchemy\Phrasea\Media\IntegerTechnicalData; use Alchemy\Phrasea\Media\IntegerTechnicalData;
@@ -36,7 +37,6 @@ use Alchemy\Phrasea\SearchEngine\SearchEngineOptions;
use Doctrine\ORM\EntityManager; use Doctrine\ORM\EntityManager;
use MediaVorus\MediaVorus; use MediaVorus\MediaVorus;
use Ramsey\Uuid\Uuid; use Ramsey\Uuid\Uuid;
use Symfony\Component\Filesystem\Filesystem;
use Symfony\Component\HttpFoundation\File\File as SymfoFile; use Symfony\Component\HttpFoundation\File\File as SymfoFile;
@@ -53,13 +53,11 @@ class record_adapter implements RecordInterface, cache_cacheableInterface
/** /**
* @param Application $app * @param Application $app
* @return Filesystem * @return FilesystemService
*/ */
private static function getFilesystem(Application $app) private static function getFilesystem(Application $app)
{ {
$filesystem = $app['filesystem']; return $app['phraseanet.filesystem'];
return $filesystem;
} }
private $base_id; private $base_id;
@@ -1161,7 +1159,6 @@ class record_adapter implements RecordInterface, cache_cacheableInterface
} }
/** /**
*
* @param File $file * @param File $file
* @param Application $app * @param Application $app
* *
@@ -1211,10 +1208,10 @@ class record_adapter implements RecordInterface, cache_cacheableInterface
$filesystem = self::getFilesystem($app); $filesystem = self::getFilesystem($app);
$pathhd = databox::dispatch($filesystem, trim($databox->get_sxml_structure()->path)); $pathhd = $filesystem->generateDataboxDocumentBasePath($databox);
$newname = $record->getRecordId() . "_document." . pathinfo($file->getOriginalName(), PATHINFO_EXTENSION); $newname = $filesystem->generateDocumentFilename($record, $file->getFile());
$filesystem->copy($file->getFile()->getRealPath(), $pathhd . $newname, true); $filesystem->copy($file->getFile()->getRealPath(), $pathhd . $newname);
$media = $app->getMediaFromUri($pathhd . $newname); $media = $app->getMediaFromUri($pathhd . $newname);
media_subdef::create($app, $record, 'document', $media); media_subdef::create($app, $record, 'document', $media);