mirror of
https://github.com/alchemy-fr/Phraseanet.git
synced 2025-10-17 23:13:15 +00:00
Merge branch '3.8'
Conflicts: config/configuration.sample.yml lib/Alchemy/Phrasea/Core/Version.php lib/classes/module/console/schedulerStart.php lib/classes/module/console/taskrun.php lib/conf.d/configuration.yml templates/mobile/common/index.html.twig
This commit is contained in:
@@ -15,6 +15,9 @@ use Alchemy\Phrasea\Core\Version;
|
||||
use Alchemy\Phrasea\Command\UpgradeDBDatas;
|
||||
use Alchemy\Phrasea\Command\Setup\Install;
|
||||
use Alchemy\Phrasea\Command\Setup\PluginsReset;
|
||||
use Alchemy\Phrasea\Command\Plugin\ListPlugin;
|
||||
use Alchemy\Phrasea\Command\Plugin\AddPlugin;
|
||||
use Alchemy\Phrasea\Command\Plugin\RemovePlugin;
|
||||
use Alchemy\Phrasea\CLI;
|
||||
use Alchemy\Phrasea\Command\Setup\CheckEnvironment;
|
||||
use Alchemy\Phrasea\Core\CLIProvider\DoctrineMigrationServiceProvider;
|
||||
@@ -58,6 +61,9 @@ if ($app['phraseanet.configuration-tester']->isInstalled()) {
|
||||
$app->command(new UpgradeDBDatas('system:upgrade-datas'));
|
||||
}
|
||||
|
||||
$app->command(new AddPlugin());
|
||||
$app->command(new ListPlugin());
|
||||
$app->command(new RemovePlugin());
|
||||
$app->command(new PluginsReset());
|
||||
$app->command(new CheckEnvironment('check:system'));
|
||||
$app->command(new Install('system:install'));
|
||||
|
@@ -28,6 +28,11 @@ main:
|
||||
search-engine:
|
||||
type: Alchemy\Phrasea\SearchEngine\Phrasea\PhraseaEngine
|
||||
options: []
|
||||
task-manager:
|
||||
logger:
|
||||
max-files: 10
|
||||
enabled: true
|
||||
level: INFO
|
||||
session:
|
||||
type: 'file'
|
||||
options: []
|
||||
|
@@ -82,6 +82,13 @@ class CLI extends Application
|
||||
$app->run();
|
||||
}
|
||||
|
||||
public function boot()
|
||||
{
|
||||
parent::boot();
|
||||
|
||||
$this['console']->setDispatcher($this['dispatcher']);
|
||||
}
|
||||
|
||||
public function run(\Symfony\Component\HttpFoundation\Request $request = null)
|
||||
{
|
||||
if (null !== $request) {
|
||||
|
@@ -30,6 +30,19 @@ abstract class AbstractPluginCommand extends Command
|
||||
return $manifests;
|
||||
}
|
||||
|
||||
protected function doExecute(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
if (basename($_SERVER['PHP_SELF']) === 'console') {
|
||||
$output->writeln("");
|
||||
$output->writeln(sprintf('<error> /!\ </error> <comment>Warning</comment>, this command is deprecated and will be removed as of Phraseanet 3.9, please use <info>bin/setup %s</info> instead <error> /!\ </error>', $this->getName()));
|
||||
$output->writeln("");
|
||||
}
|
||||
|
||||
return $this->doExecutePluginAction($input, $output);
|
||||
}
|
||||
|
||||
abstract protected function doExecutePluginAction(InputInterface $input, OutputInterface $output);
|
||||
|
||||
protected function updateConfigFiles(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
$manifests = $this->validatePlugins($input, $output);
|
||||
|
@@ -26,7 +26,7 @@ class AddPlugin extends AbstractPluginCommand
|
||||
->addArgument('source', InputArgument::REQUIRED, 'The source is a folder');
|
||||
}
|
||||
|
||||
protected function doExecute(InputInterface $input, OutputInterface $output)
|
||||
protected function doExecutePluginAction(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
$source = $input->getArgument('source');
|
||||
|
||||
|
@@ -27,7 +27,7 @@ class ListPlugin extends AbstractPluginCommand
|
||||
->addOption('json', 'j', InputOption::VALUE_NONE, 'Output result in JSON');
|
||||
}
|
||||
|
||||
protected function doExecute(InputInterface $input, OutputInterface $output)
|
||||
protected function doExecutePluginAction(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
$plugins = array_map(function (Plugin $plugin) use ($input) {
|
||||
if ($plugin->isErroneous()) {
|
||||
|
@@ -12,6 +12,7 @@
|
||||
namespace Alchemy\Phrasea\Command\Plugin;
|
||||
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Input\InputOption;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
|
||||
@@ -23,13 +24,20 @@ class RemovePlugin extends AbstractPluginCommand
|
||||
|
||||
$this
|
||||
->setDescription('Removes a plugin given its name')
|
||||
->addArgument('name', InputArgument::REQUIRED, 'The name of the plugin');
|
||||
->addArgument('name', InputArgument::REQUIRED, 'The name of the plugin')
|
||||
->addOption('keep-config', 'k', InputOption::VALUE_NONE, 'Use this flag to keep configuration');
|
||||
}
|
||||
|
||||
protected function doExecute(InputInterface $input, OutputInterface $output)
|
||||
protected function doExecutePluginAction(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
$name = $input->getArgument('name');
|
||||
|
||||
if (!$this->container['plugins.manager']->hasPlugin($name)) {
|
||||
$output->writeln(sprintf('There is no plugin named <comment>%s</comment>, aborting', $name));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
$output->write("Removing public assets...");
|
||||
$this->container['plugins.assets-manager']->remove($name);
|
||||
$output->writeln(" <comment>OK</comment>");
|
||||
@@ -42,6 +50,12 @@ class RemovePlugin extends AbstractPluginCommand
|
||||
|
||||
$this->updateConfigFiles($input, $output);
|
||||
|
||||
if (!$input->getOption('keep-config')) {
|
||||
$conf = $this->container['phraseanet.configuration']->getConfig();
|
||||
unset($conf['plugins'][$name]);
|
||||
$this->container['phraseanet.configuration']->setConfig($conf);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
@@ -14,6 +14,8 @@ namespace Alchemy\Phrasea\Command\Task;
|
||||
use Alchemy\TaskManager\TaskManager;
|
||||
use Alchemy\Phrasea\Command\Command;
|
||||
use Alchemy\TaskManager\Event\TaskManagerSubscriber\LockFileSubscriber;
|
||||
use Monolog\Handler\RotatingFileHandler;
|
||||
use Monolog\Logger;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
||||
@@ -38,6 +40,12 @@ class SchedulerRun extends Command
|
||||
protected function doExecute(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
declare(ticks=1);
|
||||
|
||||
if ($this->container['task-manager.logger.configuration']['enabled']) {
|
||||
$file = $this->container['task-manager.log-file.factory']->forManager();
|
||||
$this->container['task-manager.logger']->pushHandler(new RotatingFileHandler($file, $this->container['task-manager.logger.configuration']['max-files'], $this->container['task-manager.logger.configuration']['level']));
|
||||
}
|
||||
|
||||
$this->container['signal-handler']->register([SIGINT, SIGTERM], [$this, 'signalHandler']);
|
||||
$this->container['task-manager']->addSubscriber(new LockFileSubscriber($this->container['task-manager.logger'], $this->container['root.path'].'/tmp/locks'));
|
||||
$this->container['task-manager']->start();
|
||||
|
@@ -20,6 +20,7 @@ use Alchemy\TaskManager\Event\JobSubscriber\LockFileSubscriber;
|
||||
use Alchemy\TaskManager\Event\JobSubscriber\MemoryLimitSubscriber;
|
||||
use Alchemy\TaskManager\Event\JobSubscriber\SignalControlledSubscriber;
|
||||
use Alchemy\TaskManager\Event\JobSubscriber\StopSignalSubscriber;
|
||||
use Monolog\Handler\RotatingFileHandler;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
@@ -51,6 +52,11 @@ class TaskRun extends Command
|
||||
$job = $this->container['task-manager.job-factory']->create($task->getJobId());
|
||||
$logger = $this->container['task-manager.logger'];
|
||||
|
||||
if ($this->container['task-manager.logger.configuration']['enabled']) {
|
||||
$file = $this->container['task-manager.log-file.factory']->forTask($task);
|
||||
$logger->pushHandler(new RotatingFileHandler($file, $this->container['task-manager.logger.configuration']['max-files'], $this->container['task-manager.logger.configuration']['level']));
|
||||
}
|
||||
|
||||
$job->addSubscriber(new LockFileSubscriber('task-'.$task->getId(), $logger, $this->container['root.path'].'/tmp/locks'));
|
||||
$job->addSubscriber(new StopSignalSubscriber($this->container['signal-handler'], $logger));
|
||||
|
||||
|
@@ -14,6 +14,7 @@ namespace Alchemy\Phrasea\Core\CLIProvider;
|
||||
use Alchemy\TaskManager\TaskManager;
|
||||
use Alchemy\Phrasea\TaskManager\TaskList;
|
||||
use Monolog\Handler\NullHandler;
|
||||
use Monolog\Logger;
|
||||
use Silex\Application;
|
||||
use Silex\ServiceProviderInterface;
|
||||
use Symfony\Component\Process\PhpExecutableFinder;
|
||||
@@ -44,6 +45,18 @@ class TaskManagerServiceProvider implements ServiceProviderInterface
|
||||
);
|
||||
});
|
||||
|
||||
$app['task-manager.logger.configuration'] = $app->share(function (Application $app) {
|
||||
$conf = array_replace([
|
||||
'enabled' => true,
|
||||
'level' => 'INFO',
|
||||
'max-files' => 10,
|
||||
], $app['conf']->get(['main', 'task-manager', 'logger'], []));
|
||||
|
||||
$conf['level'] = defined('Monolog\\Logger::'.$conf['level']) ? constant('Monolog\\Logger::'.$conf['level']) : Logger::INFO;
|
||||
|
||||
return $conf;
|
||||
});
|
||||
|
||||
$app['task-manager.task-list'] = $app->share(function (Application $app) {
|
||||
$conf = $app['conf']->get(['registry', 'executables', 'php-conf-path']);
|
||||
$finder = new PhpExecutableFinder();
|
||||
|
63
lib/classes/patch/383alpha5a.php
Normal file
63
lib/classes/patch/383alpha5a.php
Normal file
@@ -0,0 +1,63 @@
|
||||
<?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_383alpha5a implements patchInterface
|
||||
{
|
||||
/** @var string */
|
||||
private $release = '3.8.3-alpha.5';
|
||||
|
||||
/** @var array */
|
||||
private $concern = array(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 apply(base $appbox, Application $app)
|
||||
{
|
||||
$config = $app['phraseanet.configuration']->getConfig();
|
||||
|
||||
$config['main']['task-manager']['logger'] = array(
|
||||
'enabled' => true,
|
||||
'max-files' => 10,
|
||||
'level' => 'INFO',
|
||||
);
|
||||
|
||||
$app['phraseanet.configuration']->setConfig($config);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
@@ -28,6 +28,11 @@ main:
|
||||
search-engine:
|
||||
type: Alchemy\Phrasea\SearchEngine\Phrasea\PhraseaEngine
|
||||
options: []
|
||||
task-manager:
|
||||
logger:
|
||||
max-files: 10
|
||||
enabled: true
|
||||
level: INFO
|
||||
session:
|
||||
type: 'file'
|
||||
options: []
|
||||
|
@@ -4,6 +4,7 @@
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="apple-mobile-web-app-capable" content="yes" />
|
||||
<meta name="apple-mobile-web-app-status-bar-style" content="black" />
|
||||
<meta name="viewport" content="initial-scale=1">
|
||||
<title>{{ app['conf'].get(['registry', 'general', 'title']) }} - {{ module_name }} </title>
|
||||
<link rel="stylesheet" href="{{ path('minifier', { 'f' : 'assets/jquery-mobile/jquery.mobile.css' }) }}" />
|
||||
<script src="{{ path('minifier', { 'f' : 'assets/jquery/jquery.js' }) }}"></script>
|
||||
|
@@ -34,7 +34,7 @@
|
||||
{% set random = thumbnail.get_random() %}
|
||||
<div class="record record_video imgTips" style="width:{{d_width|round}}px;height:{{d_height|round}}px;top:{{top|round}}px;">
|
||||
<video type="video/mp4" controls="controls" style="width:{{d_width|round}}px;height:{{d_height|round}}px;" autoplay="autoplay">
|
||||
<source src="{{thumbnail.get_url()}}" type="video/mp4"></source>
|
||||
<source src="{{thumbnail.get_url()}}" type="video/mp4" />
|
||||
</video>
|
||||
</div>
|
||||
{% elseif record_type == 'FLEXPAPER' %}
|
||||
@@ -79,8 +79,8 @@
|
||||
{% if record_type == 'VIDEO_MP4' or record_type == 'VIDEO_FLV' %}
|
||||
{% set random = thumbnail.get_random() %}
|
||||
<div class="record record_video imgTips">
|
||||
<video type="video/mp4" controls="controls" style="height:100%;" autoplay="autoplay">
|
||||
<source src="{{thumbnail.get_url()}}" type="video/mp4"></source>
|
||||
<video type="video/mp4" controls="controls" style="height:80%;width:80%;max-height: 80%;max-width:80%; margin: 0 auto" autoplay="autoplay">
|
||||
<source src="{{thumbnail.get_url()}}" type="video/mp4" />
|
||||
</video>
|
||||
</div>
|
||||
{% elseif record_type == 'FLEXPAPER' %}
|
||||
|
@@ -15,12 +15,28 @@ class RemovePluginTest extends PluginCommandTestCase
|
||||
->method('getArgument')
|
||||
->with($this->equalTo('name'))
|
||||
->will($this->returnValue($name));
|
||||
$input->expects($this->any())
|
||||
->method('getOption')
|
||||
->will($this->returnCallback(function ($option) {
|
||||
if ($option === 'keep-config') {
|
||||
return false;
|
||||
}
|
||||
}));
|
||||
|
||||
$output = $this->getMock('Symfony\Component\Console\Output\OutputInterface');
|
||||
|
||||
$command = new RemovePlugin();
|
||||
$command->setContainer(self::$DI['cli']);
|
||||
|
||||
self::$DI['cli']['plugins.manager'] = $this->getMockBuilder('Alchemy\Phrasea\Plugin\PluginManager')
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
|
||||
self::$DI['cli']['plugins.manager']->expects($this->once())
|
||||
->method('hasPlugin')
|
||||
->with('test-plugin')
|
||||
->will($this->returnValue(true));
|
||||
|
||||
self::$DI['cli']['filesystem'] = $this->createFilesystemMock();
|
||||
self::$DI['cli']['filesystem']->expects($this->at(0))
|
||||
->method('remove')
|
||||
@@ -33,5 +49,60 @@ class RemovePluginTest extends PluginCommandTestCase
|
||||
$result = $command->execute($input, $output);
|
||||
|
||||
$this->assertSame(0, $result);
|
||||
|
||||
$conf = self::$DI['cli']['phraseanet.configuration']->getConfig();
|
||||
$this->assertArrayNotHasKey('test-plugin', $conf['plugins']);
|
||||
}
|
||||
|
||||
public function testExecuteWithoutRemoveConfig()
|
||||
{
|
||||
$name = 'test-plugin';
|
||||
|
||||
$input = $this->getMock('Symfony\Component\Console\Input\InputInterface');
|
||||
$input->expects($this->once())
|
||||
->method('getArgument')
|
||||
->with($this->equalTo('name'))
|
||||
->will($this->returnValue($name));
|
||||
$input->expects($this->any())
|
||||
->method('getOption')
|
||||
->will($this->returnCallback(function ($option) {
|
||||
if ($option === 'keep-config') {
|
||||
return true;
|
||||
}
|
||||
}));
|
||||
|
||||
$output = $this->getMock('Symfony\Component\Console\Output\OutputInterface');
|
||||
|
||||
$command = new RemovePlugin();
|
||||
$command->setContainer(self::$DI['cli']);
|
||||
|
||||
$data = $this->addPluginData();
|
||||
|
||||
self::$DI['cli']['filesystem'] = $this->createFilesystemMock();
|
||||
self::$DI['cli']['filesystem']->expects($this->at(0))
|
||||
->method('remove')
|
||||
->with(self::$DI['cli']['root.path'].'/www/plugins/'.$name);
|
||||
|
||||
self::$DI['cli']['filesystem']->expects($this->at(1))
|
||||
->method('remove')
|
||||
->with(self::$DI['cli']['plugins.directory'].'/'.$name);
|
||||
|
||||
$result = $command->execute($input, $output);
|
||||
|
||||
$this->assertSame(0, $result);
|
||||
|
||||
$conf = self::$DI['cli']['phraseanet.configuration']->getConfig();
|
||||
$this->assertSame($data, $conf['plugins']['test-plugin']);
|
||||
}
|
||||
|
||||
private function addPluginData()
|
||||
{
|
||||
$data = array('key' => 'value');
|
||||
|
||||
$conf = self::$DI['cli']['phraseanet.configuration']->getConfig();
|
||||
$conf['plugins']['test-plugin'] = $data;
|
||||
self::$DI['cli']['phraseanet.configuration']->setConfig($conf);
|
||||
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user