mirror of
https://github.com/alchemy-fr/Phraseanet.git
synced 2025-10-18 07:23:13 +00:00
Makes static thumbnails delivery as default delivery && set symlink dir in www directory
This commit is contained in:
3
.gitignore
vendored
3
.gitignore
vendored
@@ -6,6 +6,9 @@
|
|||||||
/www/assets
|
/www/assets
|
||||||
/tmp-assets
|
/tmp-assets
|
||||||
|
|
||||||
|
# Exclude thumbnails folder
|
||||||
|
/www/thumbnails
|
||||||
|
|
||||||
# Exclude node.js dependencies folder
|
# Exclude node.js dependencies folder
|
||||||
/node_modules
|
/node_modules
|
||||||
|
|
||||||
|
@@ -15,7 +15,6 @@ use Alchemy\Phrasea\Command\BuildSubdefs;
|
|||||||
use Alchemy\Phrasea\Command\Plugin\ListPlugin;
|
use Alchemy\Phrasea\Command\Plugin\ListPlugin;
|
||||||
use Alchemy\Phrasea\Command\Setup\H264ConfigurationDumper;
|
use Alchemy\Phrasea\Command\Setup\H264ConfigurationDumper;
|
||||||
use Alchemy\Phrasea\Command\Setup\H264MappingGenerator;
|
use Alchemy\Phrasea\Command\Setup\H264MappingGenerator;
|
||||||
use Alchemy\Phrasea\Command\Setup\StaticConfigurationDumper;
|
|
||||||
use Alchemy\Phrasea\Core\Version;
|
use Alchemy\Phrasea\Core\Version;
|
||||||
use Alchemy\Phrasea\Command\BuildMissingSubdefs;
|
use Alchemy\Phrasea\Command\BuildMissingSubdefs;
|
||||||
use Alchemy\Phrasea\Command\CreateCollection;
|
use Alchemy\Phrasea\Command\CreateCollection;
|
||||||
@@ -30,7 +29,6 @@ use Alchemy\Phrasea\Command\Plugin\RemovePlugin;
|
|||||||
use Alchemy\Phrasea\Command\CheckConfig;
|
use Alchemy\Phrasea\Command\CheckConfig;
|
||||||
use Alchemy\Phrasea\Command\Setup\XSendFileMappingGenerator;
|
use Alchemy\Phrasea\Command\Setup\XSendFileMappingGenerator;
|
||||||
use Alchemy\Phrasea\Command\Setup\XSendFileConfigurationDumper;
|
use Alchemy\Phrasea\Command\Setup\XSendFileConfigurationDumper;
|
||||||
use Alchemy\Phrasea\Command\Setup\StaticMappingGenerator;
|
|
||||||
use Alchemy\Phrasea\Command\Task\SchedulerResumeTasks;
|
use Alchemy\Phrasea\Command\Task\SchedulerResumeTasks;
|
||||||
use Alchemy\Phrasea\Command\Task\SchedulerState;
|
use Alchemy\Phrasea\Command\Task\SchedulerState;
|
||||||
use Alchemy\Phrasea\Command\Task\SchedulerPauseTasks;
|
use Alchemy\Phrasea\Command\Task\SchedulerPauseTasks;
|
||||||
@@ -117,9 +115,6 @@ $cli->command(new H264MappingGenerator());
|
|||||||
$cli->command(new XSendFileConfigurationDumper());
|
$cli->command(new XSendFileConfigurationDumper());
|
||||||
$cli->command(new XSendFileMappingGenerator());
|
$cli->command(new XSendFileMappingGenerator());
|
||||||
|
|
||||||
$cli->command(new StaticConfigurationDumper());
|
|
||||||
$cli->command(new StaticMappingGenerator());
|
|
||||||
|
|
||||||
$cli->loadPlugins();
|
$cli->loadPlugins();
|
||||||
|
|
||||||
exit(is_int($cli->run()) ? : 1);
|
exit(is_int($cli->run()) ? : 1);
|
||||||
|
@@ -206,10 +206,6 @@ api_cors:
|
|||||||
session:
|
session:
|
||||||
idle: 0
|
idle: 0
|
||||||
lifetime: 604800 # 1 week
|
lifetime: 604800 # 1 week
|
||||||
static-file:
|
|
||||||
enabled: false
|
|
||||||
type: nginx
|
|
||||||
symlink-directory: ''
|
|
||||||
crossdomain:
|
crossdomain:
|
||||||
site-control: 'master-only'
|
site-control: 'master-only'
|
||||||
allow-access-from:
|
allow-access-from:
|
||||||
|
@@ -702,6 +702,8 @@ class Application extends SilexApplication
|
|||||||
$this['tmp.path'] = $this['root.path'].'/tmp';
|
$this['tmp.path'] = $this['root.path'].'/tmp';
|
||||||
// plugin path
|
// plugin path
|
||||||
$this['plugin.path'] = $dir = $this['root.path'].'/plugins';
|
$this['plugin.path'] = $dir = $this['root.path'].'/plugins';
|
||||||
|
// thumbnails path
|
||||||
|
$this['thumbnail.path'] = $dir = $this['root.path'].'/www/thumbnails';
|
||||||
|
|
||||||
// cache path for dev env
|
// cache path for dev env
|
||||||
$this['cache.dev.path'] = $this->share(function() {
|
$this['cache.dev.path'] = $this->share(function() {
|
||||||
|
@@ -1,56 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
/*
|
|
||||||
* This file is part of Phraseanet
|
|
||||||
*
|
|
||||||
* (c) 2005-2015 Alchemy
|
|
||||||
*
|
|
||||||
* For the full copyright and license information, please view the LICENSE
|
|
||||||
* file that was distributed with this source code.
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace Alchemy\Phrasea\Command\Setup;
|
|
||||||
|
|
||||||
use Alchemy\Phrasea\Command\Command;
|
|
||||||
use Alchemy\Phrasea\Exception\RuntimeException;
|
|
||||||
use Symfony\Component\Console\Input\InputInterface;
|
|
||||||
use Symfony\Component\Console\Output\OutputInterface;
|
|
||||||
|
|
||||||
class StaticConfigurationDumper extends Command
|
|
||||||
{
|
|
||||||
public function __construct($name = null)
|
|
||||||
{
|
|
||||||
parent::__construct('static-file:dump-configuration');
|
|
||||||
|
|
||||||
$this->setDescription('Dump the virtual host configuration depending on Phraseanet configuration');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritdoc}
|
|
||||||
*/
|
|
||||||
protected function doExecute(InputInterface $input, OutputInterface $output)
|
|
||||||
{
|
|
||||||
$output->writeln('');
|
|
||||||
|
|
||||||
if (!$this->container['phraseanet.static-file-factory']->isStaticFileModeEnabled()) {
|
|
||||||
$output->writeln('Static file support is <error>disabled</error>');
|
|
||||||
$ret = 1;
|
|
||||||
} else {
|
|
||||||
$output->writeln('Static file support is <info>enabled</info>');
|
|
||||||
$ret = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
$configuration = $this->container['phraseanet.static-file-factory']->getMode(true, true)->getVirtualHostConfiguration();
|
|
||||||
$output->writeln('Static file configuration seems <info>OK</info>');
|
|
||||||
$output->writeln($configuration);
|
|
||||||
} catch (RuntimeException $e) {
|
|
||||||
$output->writeln('Static file configuration seems <error>invalid</error>');
|
|
||||||
$ret = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
$output->writeln('');
|
|
||||||
|
|
||||||
return $ret;
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,64 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
/*
|
|
||||||
* This file is part of Phraseanet
|
|
||||||
*
|
|
||||||
* (c) 2005-2015 Alchemy
|
|
||||||
*
|
|
||||||
* For the full copyright and license information, please view the LICENSE
|
|
||||||
* file that was distributed with this source code.
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace Alchemy\Phrasea\Command\Setup;
|
|
||||||
|
|
||||||
use Alchemy\Phrasea\Command\Command;
|
|
||||||
use Alchemy\Phrasea\Http\StaticFile\StaticFileFactory;
|
|
||||||
use Symfony\Component\Console\Input\InputArgument;
|
|
||||||
use Symfony\Component\Console\Input\InputInterface;
|
|
||||||
use Symfony\Component\Console\Output\OutputInterface;
|
|
||||||
use Symfony\Component\Yaml\Yaml;
|
|
||||||
|
|
||||||
class StaticMappingGenerator extends Command
|
|
||||||
{
|
|
||||||
public function __construct($name = null)
|
|
||||||
{
|
|
||||||
parent::__construct('static-file:generate-mapping');
|
|
||||||
|
|
||||||
$this->addOption('write', 'w', null, 'Writes the configuration')
|
|
||||||
->addOption('enabled', 'e', null, 'Set the enable toggle to `true`')
|
|
||||||
->addArgument('type', InputArgument::REQUIRED, 'The configuration type, either `nginx` or `apache`')
|
|
||||||
->setDescription('Generates Phraseanet Static file configuration');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritdoc}
|
|
||||||
*/
|
|
||||||
protected function doExecute(InputInterface $input, OutputInterface $output)
|
|
||||||
{
|
|
||||||
$enabled = $input->getOption('enabled');
|
|
||||||
$type = strtolower($input->getArgument('type'));
|
|
||||||
|
|
||||||
$factory = new StaticFileFactory($this->container['monolog'], true, $type, $this->container['phraseanet.thumb-symlinker']);
|
|
||||||
$mode = $factory->getMode(true);
|
|
||||||
|
|
||||||
$conf = array(
|
|
||||||
'enabled' => $enabled,
|
|
||||||
'type' => $type,
|
|
||||||
'mapping' => $mode->getMapping(),
|
|
||||||
);
|
|
||||||
|
|
||||||
if ($input->getOption('write')) {
|
|
||||||
$output->write("Writing configuration ...");
|
|
||||||
$this->container['phraseanet.configuration']['static-file'] = $conf;
|
|
||||||
$output->writeln(" <info>OK</info>");
|
|
||||||
$output->writeln("");
|
|
||||||
$output->write("It is now strongly recommended to use <info>static-file:dump-configuration</info> command to upgrade your virtual-host");
|
|
||||||
} else {
|
|
||||||
$output->writeln("Configuration will <info>not</info> be written, use <info>--write</info> option to write it");
|
|
||||||
$output->writeln("");
|
|
||||||
$output->writeln(Yaml::dump(array('static-file' => $conf), 4));
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
@@ -15,6 +15,8 @@ use Alchemy\Phrasea\Core\Event\Subscriber\XSendFileSubscriber;
|
|||||||
use Alchemy\Phrasea\Http\H264PseudoStreaming\H264Factory;
|
use Alchemy\Phrasea\Http\H264PseudoStreaming\H264Factory;
|
||||||
use Alchemy\Phrasea\Http\ServeFileResponseFactory;
|
use Alchemy\Phrasea\Http\ServeFileResponseFactory;
|
||||||
use Alchemy\Phrasea\Http\StaticFile\StaticFileFactory;
|
use Alchemy\Phrasea\Http\StaticFile\StaticFileFactory;
|
||||||
|
use Alchemy\Phrasea\Http\StaticFile\StaticMode;
|
||||||
|
use Alchemy\Phrasea\Http\StaticFile\Symlink\SymLinker;
|
||||||
use Alchemy\Phrasea\Http\XSendFile\XSendFileFactory;
|
use Alchemy\Phrasea\Http\XSendFile\XSendFileFactory;
|
||||||
use Silex\Application;
|
use Silex\Application;
|
||||||
use Silex\ServiceProviderInterface;
|
use Silex\ServiceProviderInterface;
|
||||||
@@ -34,16 +36,12 @@ class FileServeServiceProvider implements ServiceProviderInterface
|
|||||||
return H264Factory::create($app);
|
return H264Factory::create($app);
|
||||||
});
|
});
|
||||||
|
|
||||||
$app['phraseanet.static-file-factory'] = $app->share(function ($app) {
|
|
||||||
return StaticFileFactory::create($app);
|
|
||||||
});
|
|
||||||
|
|
||||||
$app['phraseanet.h264'] = $app->share(function ($app) {
|
$app['phraseanet.h264'] = $app->share(function ($app) {
|
||||||
return $app['phraseanet.h264-factory']->createMode(false);
|
return $app['phraseanet.h264-factory']->createMode(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
$app['phraseanet.static-file'] = $app->share(function ($app) {
|
$app['phraseanet.static-file'] = $app->share(function (Application $app) {
|
||||||
return $app['phraseanet.static-file-factory']->getMode(false);
|
return new StaticMode(SymLinker::create($app));
|
||||||
});
|
});
|
||||||
|
|
||||||
$app['phraseanet.file-serve'] = $app->share(function (Application $app) {
|
$app['phraseanet.file-serve'] = $app->share(function (Application $app) {
|
||||||
|
@@ -1,52 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
/*
|
|
||||||
* This file is part of Phraseanet
|
|
||||||
*
|
|
||||||
* (c) 2005-2015 Alchemy
|
|
||||||
*
|
|
||||||
* For the full copyright and license information, please view the LICENSE
|
|
||||||
* file that was distributed with this source code.
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace Alchemy\Phrasea\Http\StaticFile;
|
|
||||||
|
|
||||||
use Alchemy\Phrasea\Exception\InvalidArgumentException;
|
|
||||||
|
|
||||||
class Apache extends AbstractStaticMode implements StaticFileModeInterface
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* @params array $mapping
|
|
||||||
*
|
|
||||||
* @throws InvalidArgumentException if mapping is invalid;
|
|
||||||
*/
|
|
||||||
public function setMapping(array $mapping)
|
|
||||||
{
|
|
||||||
if (!isset($mapping['directory'])) {
|
|
||||||
throw new InvalidArgumentException('Static file mapping entry must contain at least a "directory" key');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!isset($mapping['mount-point'])) {
|
|
||||||
throw new InvalidArgumentException('Static file mapping entry must contain at least a "mount-point" key');
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->mapping = $mapping;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritdoc}
|
|
||||||
*/
|
|
||||||
public function getVirtualHostConfiguration()
|
|
||||||
{
|
|
||||||
$output = "\n";
|
|
||||||
$output .= " Alias ".$this->mapping['mount-point']." ".$this->mapping['directory']."\n";
|
|
||||||
$output .= "\n";
|
|
||||||
$output .= " <Location ".$this->mapping['directory'].">\n";
|
|
||||||
$output .= " Order allow,deny\n";
|
|
||||||
$output .= " Allow from all\n";
|
|
||||||
$output .= " </Location>\n";
|
|
||||||
$output .= "\n";
|
|
||||||
|
|
||||||
return $output;
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,50 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
/*
|
|
||||||
* This file is part of Phraseanet
|
|
||||||
*
|
|
||||||
* (c) 2005-2015 Alchemy
|
|
||||||
*
|
|
||||||
* For the full copyright and license information, please view the LICENSE
|
|
||||||
* file that was distributed with this source code.
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace Alchemy\Phrasea\Http\StaticFile;
|
|
||||||
|
|
||||||
use Alchemy\Phrasea\Exception\InvalidArgumentException;
|
|
||||||
|
|
||||||
class Nginx extends AbstractStaticMode implements StaticFileModeInterface
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* @params array $mapping
|
|
||||||
*
|
|
||||||
* @throws InvalidArgumentException if mapping is invalid;
|
|
||||||
*/
|
|
||||||
public function setMapping(array $mapping)
|
|
||||||
{
|
|
||||||
if (!isset($mapping['directory'])) {
|
|
||||||
throw new InvalidArgumentException('Static file mapping entry must contain at least a "directory" key');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!isset($mapping['mount-point'])) {
|
|
||||||
throw new InvalidArgumentException('Static file mapping entry must contain at least a "mount-point" key');
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->mapping = $mapping;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritdoc}
|
|
||||||
*/
|
|
||||||
public function getVirtualHostConfiguration()
|
|
||||||
{
|
|
||||||
$output = "\n";
|
|
||||||
$output .= " location " . $this->mapping['mount-point']. " {\n";
|
|
||||||
$output .= " alias ".$this->mapping['directory'].";\n";
|
|
||||||
$output .= " types { }";
|
|
||||||
$output .= " default_type image/jpeg;";
|
|
||||||
$output .= " }\n";
|
|
||||||
|
|
||||||
return $output;
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,30 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
/*
|
|
||||||
* This file is part of Phraseanet
|
|
||||||
*
|
|
||||||
* (c) 2005-2015 Alchemy
|
|
||||||
*
|
|
||||||
* For the full copyright and license information, please view the LICENSE
|
|
||||||
* file that was distributed with this source code.
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace Alchemy\Phrasea\Http\StaticFile;
|
|
||||||
|
|
||||||
class NullMode implements StaticFileModeInterface
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* {@inheritdoc}
|
|
||||||
*/
|
|
||||||
public function getVirtualHostConfiguration()
|
|
||||||
{
|
|
||||||
return "\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritdoc}
|
|
||||||
*/
|
|
||||||
public function getUrl($pathFile)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,104 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
/*
|
|
||||||
* This file is part of Phraseanet
|
|
||||||
*
|
|
||||||
* (c) 2005-2015 Alchemy
|
|
||||||
*
|
|
||||||
* For the full copyright and license information, please view the LICENSE
|
|
||||||
* file that was distributed with this source code.
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace Alchemy\Phrasea\Http\StaticFile;
|
|
||||||
|
|
||||||
use Alchemy\Phrasea\Application;
|
|
||||||
use Alchemy\Phrasea\Exception\InvalidArgumentException;
|
|
||||||
use Alchemy\Phrasea\Http\StaticFile\Symlink\SymLinker;
|
|
||||||
use Psr\Log\LoggerInterface;
|
|
||||||
|
|
||||||
class StaticFileFactory
|
|
||||||
{
|
|
||||||
private $enabled;
|
|
||||||
private $logger;
|
|
||||||
private $type;
|
|
||||||
/** @var Symlink\SymLinker */
|
|
||||||
private $symlinker;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructor
|
|
||||||
*
|
|
||||||
* @param LoggerInterface $logger
|
|
||||||
* @param bool $enabled
|
|
||||||
* @param string $type
|
|
||||||
* @param SymLinker $symlinker
|
|
||||||
*/
|
|
||||||
public function __construct(LoggerInterface $logger, $enabled, $type, SymLinker $symlinker)
|
|
||||||
{
|
|
||||||
$this->logger = $logger;
|
|
||||||
$this->enabled = (Boolean) $enabled;
|
|
||||||
$this->type = strtolower($type);
|
|
||||||
$this->symlinker = $symlinker;
|
|
||||||
|
|
||||||
$this->mapping = array(
|
|
||||||
'mount-point' => $symlinker->getDefaultAlias(),
|
|
||||||
'directory' => $symlinker->getSymlinkDir()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a new instance of StaticFileFactory Factory according to the application
|
|
||||||
* configuration.
|
|
||||||
*
|
|
||||||
* @param Application $app
|
|
||||||
* @return StaticFileFactory
|
|
||||||
*/
|
|
||||||
public static function create(Application $app)
|
|
||||||
{
|
|
||||||
$conf = $app['phraseanet.configuration']['static-file'];
|
|
||||||
|
|
||||||
return new self($app['monolog'], $conf['enabled'], $conf['type'], $app['phraseanet.thumb-symlinker']);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a new instance of ModeInterface
|
|
||||||
*
|
|
||||||
* @param bool $throwException
|
|
||||||
* @param bool $forceMode
|
|
||||||
*
|
|
||||||
* @return Apache|Nginx|NullMode
|
|
||||||
* @throws InvalidArgumentException
|
|
||||||
*/
|
|
||||||
public function getMode($throwException = false, $forceMode = false)
|
|
||||||
{
|
|
||||||
if (false === $this->enabled && true !== $forceMode) {
|
|
||||||
return new NullMode();
|
|
||||||
}
|
|
||||||
|
|
||||||
switch ($this->type) {
|
|
||||||
case 'nginx':
|
|
||||||
return new Nginx($this->mapping, $this->symlinker);
|
|
||||||
break;
|
|
||||||
case 'apache':
|
|
||||||
case 'apache2':
|
|
||||||
return new Apache($this->mapping, $this->symlinker);
|
|
||||||
default:
|
|
||||||
$this->logger->error('Invalid static file configuration.');
|
|
||||||
if ($throwException) {
|
|
||||||
throw new InvalidArgumentException(sprintf(
|
|
||||||
'Invalid static file type value "%s"',
|
|
||||||
$this->type
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
return new NullMode();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return bool
|
|
||||||
*/
|
|
||||||
public function isStaticFileModeEnabled()
|
|
||||||
{
|
|
||||||
return $this->enabled;
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,25 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
/*
|
|
||||||
* This file is part of Phraseanet
|
|
||||||
*
|
|
||||||
* (c) 2005-2015 Alchemy
|
|
||||||
*
|
|
||||||
* For the full copyright and license information, please view the LICENSE
|
|
||||||
* file that was distributed with this source code.
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace Alchemy\Phrasea\Http\StaticFile;
|
|
||||||
|
|
||||||
use Alchemy\Phrasea\Http\ServerModeInterface;
|
|
||||||
use Guzzle\Http\Url;
|
|
||||||
|
|
||||||
interface StaticFileModeInterface extends ServerModeInterface
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* @param $pathFile
|
|
||||||
*
|
|
||||||
* @return Url|null
|
|
||||||
*/
|
|
||||||
public function getUrl($pathFile);
|
|
||||||
}
|
|
@@ -15,15 +15,13 @@ use Alchemy\Phrasea\Http\AbstractServerMode;
|
|||||||
use Alchemy\Phrasea\Http\StaticFile\Symlink\SymLinker;
|
use Alchemy\Phrasea\Http\StaticFile\Symlink\SymLinker;
|
||||||
use Guzzle\Http\Url;
|
use Guzzle\Http\Url;
|
||||||
|
|
||||||
abstract class AbstractStaticMode extends AbstractServerMode
|
class StaticMode
|
||||||
{
|
{
|
||||||
protected $symlinker;
|
protected $symlinker;
|
||||||
|
|
||||||
public function __construct(array $mapping, SymLinker $symlinker)
|
public function __construct(SymLinker $symlinker)
|
||||||
{
|
{
|
||||||
$this->symlinker = $symlinker;
|
$this->symlinker = $symlinker;
|
||||||
|
|
||||||
parent::__construct($mapping);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -33,7 +31,7 @@ abstract class AbstractStaticMode extends AbstractServerMode
|
|||||||
{
|
{
|
||||||
$this->ensureSymlink($pathFile);
|
$this->ensureSymlink($pathFile);
|
||||||
|
|
||||||
return Url::factory(sprintf('%s/%s', $this->mapping['mount-point'], $this->symlinker->getSymlinkBasePath($pathFile)));
|
return Url::factory(sprintf('/thumbnails/%s', $this->symlinker->getSymlinkBasePath($pathFile)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
@@ -21,9 +21,6 @@ use Guzzle\Http\Url;
|
|||||||
*/
|
*/
|
||||||
class SymLinker
|
class SymLinker
|
||||||
{
|
{
|
||||||
/** Mount Point Alias Name */
|
|
||||||
const ALIAS = 'thumb';
|
|
||||||
|
|
||||||
protected $encoder;
|
protected $encoder;
|
||||||
protected $fs;
|
protected $fs;
|
||||||
protected $symlinkDir;
|
protected $symlinkDir;
|
||||||
@@ -33,7 +30,7 @@ class SymLinker
|
|||||||
return new SymLinker(
|
return new SymLinker(
|
||||||
$app['phraseanet.thumb-symlinker-encoder'],
|
$app['phraseanet.thumb-symlinker-encoder'],
|
||||||
$app['filesystem'],
|
$app['filesystem'],
|
||||||
isset($app['phraseanet.configuration']['static-file']['symlink-directory']) ? $app['phraseanet.configuration']['static-file']['symlink-directory'] : $app['root.path'] . '/tmp/symlinks'
|
$app['thumbnail.path']
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -49,11 +46,6 @@ class SymLinker
|
|||||||
return $this->symlinkDir;
|
return $this->symlinkDir;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getDefaultAlias()
|
|
||||||
{
|
|
||||||
return sprintf('/%s', self::ALIAS);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function symlink($pathFile)
|
public function symlink($pathFile)
|
||||||
{
|
{
|
||||||
$this->fs->symlink($pathFile, $this->getSymlinkPath($pathFile)) ;
|
$this->fs->symlink($pathFile, $this->getSymlinkPath($pathFile)) ;
|
||||||
@@ -68,7 +60,7 @@ class SymLinker
|
|||||||
{
|
{
|
||||||
$symlinkName = $this->getSymlink($pathFile);
|
$symlinkName = $this->getSymlink($pathFile);
|
||||||
|
|
||||||
return sprintf('%s/%s/%s',
|
return sprintf('%s/%s/%s.jpg',
|
||||||
substr($symlinkName, 0, 2),
|
substr($symlinkName, 0, 2),
|
||||||
substr($symlinkName, 2, 2),
|
substr($symlinkName, 2, 2),
|
||||||
substr($symlinkName, 4)
|
substr($symlinkName, 4)
|
||||||
|
@@ -451,21 +451,6 @@ class databox extends base
|
|||||||
|
|
||||||
public function unmount_databox()
|
public function unmount_databox()
|
||||||
{
|
{
|
||||||
if ($this->app['phraseanet.static-file-factory']->isStaticFileModeEnabled()) {
|
|
||||||
$sql = "SELECT path, file FROM subdef WHERE `name`='thumbnail'";
|
|
||||||
$stmt = $this->get_connection()->prepare($sql);
|
|
||||||
$stmt->execute();
|
|
||||||
$rows = $stmt->fetchAll(\PDO::FETCH_ASSOC);
|
|
||||||
$stmt->closeCursor();
|
|
||||||
foreach ($rows as $row) {
|
|
||||||
$pathfile = $this->app['phraseanet.thumb-symlinker']->getSymlinkPath(sprintf(
|
|
||||||
'%s/%s',
|
|
||||||
rtrim($row['path'], '/'),
|
|
||||||
$row['file']
|
|
||||||
));
|
|
||||||
$this->app['filesystem']->remove($pathfile);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
foreach ($this->get_collections() as $collection) {
|
foreach ($this->get_collections() as $collection) {
|
||||||
$collection->unmount_collection($this->app);
|
$collection->unmount_collection($this->app);
|
||||||
}
|
}
|
||||||
|
@@ -735,7 +735,7 @@ class media_subdef extends media_abstract implements cache_cacheableInterface
|
|||||||
$subdef->get_permalink()->delete_data_from_cache();
|
$subdef->get_permalink()->delete_data_from_cache();
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($name === 'thumbnail' && $app['phraseanet.static-file-factory']->isStaticFileModeEnabled()) {
|
if ($name === 'thumbnail') {
|
||||||
$app['phraseanet.thumb-symlinker']->symlink($subdef->get_pathfile());
|
$app['phraseanet.thumb-symlinker']->symlink($subdef->get_pathfile());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -755,8 +755,9 @@ class media_subdef extends media_abstract implements cache_cacheableInterface
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// serve thumbnails using static file service
|
||||||
if ($this->get_name() === 'thumbnail') {
|
if ($this->get_name() === 'thumbnail') {
|
||||||
if ($this->app['phraseanet.static-file-factory']->isStaticFileModeEnabled() && null !== $url = $this->app['phraseanet.static-file']->getUrl($this->get_pathfile())) {
|
if (null !== $url = $this->app['phraseanet.static-file']->getUrl($this->get_pathfile())) {
|
||||||
$this->url = $url. "?etag=".$this->getEtag();
|
$this->url = $url. "?etag=".$this->getEtag();
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
67
lib/classes/patch/390alpha21a.php
Normal file
67
lib/classes/patch/390alpha21a.php
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of Phraseanet
|
||||||
|
*
|
||||||
|
* (c) 2005-2014 Alchemy
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
use Alchemy\Phrasea\Application;
|
||||||
|
|
||||||
|
class patch_390alpha21a extends patchAbstract
|
||||||
|
{
|
||||||
|
/** @var string */
|
||||||
|
private $release = '3.9.0-alpha.21';
|
||||||
|
|
||||||
|
/** @var array */
|
||||||
|
private $concern = [base::APPLICATION_BOX];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function get_release()
|
||||||
|
{
|
||||||
|
return $this->release;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function require_all_upgrades()
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function concern()
|
||||||
|
{
|
||||||
|
return $this->concern;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function getDoctrineMigrations()
|
||||||
|
{
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function apply(base $appbox, Application $app)
|
||||||
|
{
|
||||||
|
$main = $app['conf']->get(['main']);
|
||||||
|
if (isset($main['static-file'])) {
|
||||||
|
unset($main['static-file']);
|
||||||
|
}
|
||||||
|
$app['conf']->set(['main'], $main);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
@@ -1564,7 +1564,7 @@ class record_adapter implements record_Interface, cache_cacheableInterface
|
|||||||
if (!$subdef->is_physically_present())
|
if (!$subdef->is_physically_present())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if ($subdef->get_name() === 'thumbnail' && $this->app['phraseanet.static-file-factory']->isStaticFileModeEnabled()) {
|
if ($subdef->get_name() === 'thumbnail') {
|
||||||
$this->app['filesystem']->remove($this->app['phraseanet.thumb-symlinker']->getSymlinkPath($subdef->get_pathfile()));
|
$this->app['filesystem']->remove($this->app['phraseanet.thumb-symlinker']->getSymlinkPath($subdef->get_pathfile()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -203,10 +203,6 @@ session:
|
|||||||
idle: 0
|
idle: 0
|
||||||
# 1 week
|
# 1 week
|
||||||
lifetime: 604800
|
lifetime: 604800
|
||||||
static-file:
|
|
||||||
enabled: false
|
|
||||||
type: nginx
|
|
||||||
symlink-directory: ''
|
|
||||||
crossdomain:
|
crossdomain:
|
||||||
allow-access-from:
|
allow-access-from:
|
||||||
-
|
-
|
||||||
|
@@ -1,37 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace Alchemy\Tests\Phrasea\Http\StaticFile;
|
|
||||||
|
|
||||||
use Alchemy\Phrasea\Http\StaticFile\Apache;
|
|
||||||
use Symfony\Component\HttpFoundation\Request;
|
|
||||||
|
|
||||||
class ApacheModeTest extends \PhraseanetWebTestCase
|
|
||||||
{
|
|
||||||
public function testGetVirtualHost()
|
|
||||||
{
|
|
||||||
$mode = new Apache(array(
|
|
||||||
'directory' => __DIR__,
|
|
||||||
'mount-point' => '/thumbs'
|
|
||||||
), self::$DI['app']['phraseanet.thumb-symlinker']);
|
|
||||||
$conf = $mode->getVirtualHostConfiguration();
|
|
||||||
$this->assertRegExp('#'.__DIR__ . '#', $conf);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @dataProvider provideMappings
|
|
||||||
* @expectedException Alchemy\Phrasea\Exception\InvalidArgumentException
|
|
||||||
*/
|
|
||||||
public function testInvalidMapping($mapping)
|
|
||||||
{
|
|
||||||
new Apache($mapping, self::$DI['app']['phraseanet.thumb-symlinker']);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function provideMappings()
|
|
||||||
{
|
|
||||||
return array(
|
|
||||||
array(array('Directory' => __DIR__)),
|
|
||||||
array(array('wrong-key' => __DIR__, 'mount-point' => '/')),
|
|
||||||
array(array('directory' => __DIR__, 'wrong-key' => '/')),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,37 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace Alchemy\Tests\Phrasea\Http\StaticFile;
|
|
||||||
|
|
||||||
use Alchemy\Phrasea\Http\StaticFile\Nginx;
|
|
||||||
use Symfony\Component\HttpFoundation\Request;
|
|
||||||
|
|
||||||
class NginxModeTest extends \PhraseanetWebTestCase
|
|
||||||
{
|
|
||||||
public function testGetVirtualHost()
|
|
||||||
{
|
|
||||||
$mode = new Nginx(array(
|
|
||||||
'directory' => __DIR__,
|
|
||||||
'mount-point' => '/thumbs'
|
|
||||||
), self::$DI['app']['phraseanet.thumb-symlinker']);
|
|
||||||
$conf = $mode->getVirtualHostConfiguration();
|
|
||||||
$this->assertRegExp('#'.__DIR__ . '#', $conf);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @dataProvider provideMappings
|
|
||||||
* @expectedException Alchemy\Phrasea\Exception\InvalidArgumentException
|
|
||||||
*/
|
|
||||||
public function testInvalidMapping($mapping)
|
|
||||||
{
|
|
||||||
new Nginx($mapping, self::$DI['app']['phraseanet.thumb-symlinker']);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function provideMappings()
|
|
||||||
{
|
|
||||||
return array(
|
|
||||||
array(array('Directory' => __DIR__)),
|
|
||||||
array(array('wrong-key' => __DIR__, 'mount-point' => '/')),
|
|
||||||
array(array('directory' => __DIR__, 'wrong-key' => '/')),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,54 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace Alchemy\Tests\Phrasea\Http\XSendFile;
|
|
||||||
|
|
||||||
use Alchemy\Phrasea\Http\StaticFile\StaticFileFactory;
|
|
||||||
|
|
||||||
class StaticFileFactoryTest extends \PhraseanetWebTestCase
|
|
||||||
{
|
|
||||||
public function testFactoryCreation()
|
|
||||||
{
|
|
||||||
$factory = StaticFileFactory::create(self::$DI['app']);
|
|
||||||
$this->assertInstanceOf('Alchemy\Phrasea\Http\StaticFile\StaticFileFactory', $factory);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function testFactoryWithStaticFileEnable()
|
|
||||||
{
|
|
||||||
$logger = $this->getMock('Psr\Log\LoggerInterface');
|
|
||||||
|
|
||||||
$factory = new StaticFileFactory($logger, true, 'nginx', self::$DI['app']['phraseanet.thumb-symlinker']);
|
|
||||||
$this->assertInstanceOf('Alchemy\Phrasea\Http\StaticFile\AbstractStaticMode', $factory->getMode());
|
|
||||||
}
|
|
||||||
|
|
||||||
public function testFactoryWithStaticFileDisabled()
|
|
||||||
{
|
|
||||||
$logger = $this->getMock('Psr\Log\LoggerInterface');
|
|
||||||
|
|
||||||
$factory = new StaticFileFactory($logger, false, 'nginx', self::$DI['app']['phraseanet.thumb-symlinker']);
|
|
||||||
$this->assertInstanceOf('Alchemy\Phrasea\Http\StaticFile\NullMode', $factory->getMode());
|
|
||||||
$this->assertFalse($factory->isStaticFileModeEnabled());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @expectedException Alchemy\Phrasea\Exception\InvalidArgumentException
|
|
||||||
*/
|
|
||||||
public function testFactoryWithWrongTypeThrowsAnExceptionIfRequired()
|
|
||||||
{
|
|
||||||
$logger = $this->getMock('Psr\Log\LoggerInterface');
|
|
||||||
|
|
||||||
$factory = new StaticFileFactory($logger, true, 'wrong-type', self::$DI['app']['phraseanet.thumb-symlinker']);
|
|
||||||
$factory->getMode(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function testFactoryWithWrongTypeDoesNotThrowsAnException()
|
|
||||||
{
|
|
||||||
$logger = $this->getMock('Psr\Log\LoggerInterface');
|
|
||||||
|
|
||||||
$logger->expects($this->once())
|
|
||||||
->method('error')
|
|
||||||
->with($this->isType('string'));
|
|
||||||
|
|
||||||
$factory = new StaticFileFactory($logger, true, 'wrong-type', self::$DI['app']['phraseanet.thumb-symlinker']);
|
|
||||||
$this->assertInstanceOf('Alchemy\Phrasea\Http\StaticFile\NullMode', $factory->getMode(false));
|
|
||||||
}
|
|
||||||
}
|
|
0
www/thumbnails/.gitkeep
Normal file
0
www/thumbnails/.gitkeep
Normal file
Reference in New Issue
Block a user