mirror of
https://github.com/alchemy-fr/Phraseanet.git
synced 2025-10-07 01:54:27 +00:00
Introduce configuration-tester
This commit is contained in:
@@ -20,6 +20,7 @@ use Alchemy\Phrasea\Core\Version;
|
||||
use Alchemy\Phrasea\Command\UpgradeDBDatas;
|
||||
use Alchemy\Phrasea\Command\Setup\Install;
|
||||
use Alchemy\Phrasea\CLI;
|
||||
use Alchemy\Phrasea\Command\Setup\CheckEnvironment;
|
||||
|
||||
require_once __DIR__ . '/../vendor/autoload.php';
|
||||
|
||||
@@ -59,7 +60,7 @@ try {
|
||||
$app->command(new UpgradeDBDatas('system:upgrade-datas'));
|
||||
}
|
||||
|
||||
$app->command(new \module_console_systemConfigCheck('check:system'));
|
||||
$app->command(new CheckEnvironment('check:system'));
|
||||
$app->command(new Install('system:install'));
|
||||
|
||||
$result_code = is_int($app->run()) ? : 1;
|
||||
|
@@ -11,16 +11,29 @@
|
||||
|
||||
namespace Alchemy\Phrasea\Application;
|
||||
|
||||
use Alchemy\Phrasea\Application as PhraseaApplication;
|
||||
use Alchemy\Phrasea\Controller\Setup\Installer;
|
||||
use Alchemy\Phrasea\Controller\Utils\ConnectionTest;
|
||||
use Alchemy\Phrasea\Controller\Utils\PathFileTest;
|
||||
use Silex\Application as SilexApplication;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
|
||||
return call_user_func(function() {
|
||||
|
||||
$app = new Application();
|
||||
$app = new SilexApplication();
|
||||
|
||||
$app->get('/', function(PhraseaApplication $app) {
|
||||
$app['debug'] = true;
|
||||
|
||||
$app['twig'] = $app->share(function (SilexApplication $app) {
|
||||
$ld_path = array(__DIR__ . '/../../../../templates/web');
|
||||
$loader = new \Twig_Loader_Filesystem($ld_path);
|
||||
|
||||
$twig = new \Twig_Environment($loader);
|
||||
$twig->addExtension(new \Twig_Extensions_Extension_I18n());
|
||||
|
||||
return $twig;
|
||||
});
|
||||
|
||||
$app->get('/', function(SilexApplication $app) {
|
||||
if (!$app['phraseanet.configuration-tester']->isBlank()) {
|
||||
return $app->redirect('/login/');
|
||||
}
|
||||
@@ -33,12 +46,12 @@ return call_user_func(function() {
|
||||
$app->mount('/connection_test', new ConnectionTest());
|
||||
|
||||
$app->error(function($e) use ($app) {
|
||||
if ($e instanceof \Exception_Setup_PhraseaAlreadyInstalled) {
|
||||
return $app->redirect('/login/');
|
||||
}
|
||||
if ($e instanceof \Exception_Setup_PhraseaAlreadyInstalled) {
|
||||
return $app->redirect('/login/');
|
||||
}
|
||||
|
||||
return new Response('Internal Server Error', 500, array('X-Status-Code' => 500));
|
||||
});
|
||||
return new Response('Internal Server Error', 500, array('X-Status-Code' => 500));
|
||||
});
|
||||
|
||||
return $app;
|
||||
});
|
||||
|
91
lib/Alchemy/Phrasea/Command/Setup/CheckEnvironment.php
Normal file
91
lib/Alchemy/Phrasea/Command/Setup/CheckEnvironment.php
Normal file
@@ -0,0 +1,91 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Phraseanet
|
||||
*
|
||||
* (c) 2005-2013 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\Setup\Installer;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Input\InputOption;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
use Symfony\Component\Process\ExecutableFinder;
|
||||
use Symfony\Component\Console\Helper\DialogHelper;
|
||||
use Alchemy\Phrasea\Setup\Requirements\BinariesRequirements;
|
||||
use Alchemy\Phrasea\Setup\Requirements\FilesystemRequirements;
|
||||
use Alchemy\Phrasea\Setup\Requirements\LocalesRequirements;
|
||||
use Alchemy\Phrasea\Setup\Requirements\PhraseaRequirements;
|
||||
use Alchemy\Phrasea\Setup\Requirements\PhpRequirements;
|
||||
use Alchemy\Phrasea\Setup\Requirements\SystemRequirements;
|
||||
|
||||
class CheckEnvironment extends Command
|
||||
{
|
||||
public function __construct($name = null)
|
||||
{
|
||||
parent::__construct($name);
|
||||
|
||||
$this
|
||||
->setDescription("Check environment");
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function doExecute(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
foreach(array(
|
||||
new BinariesRequirements(),
|
||||
new FilesystemRequirements(),
|
||||
new LocalesRequirements(),
|
||||
new PhraseaRequirements(),
|
||||
new PhpRequirements(),
|
||||
new SystemRequirements(),
|
||||
) as $collection) {
|
||||
|
||||
$output->writeln('');
|
||||
$output->writeln($collection->getName() . ' requirements : ');
|
||||
$output->writeln('');
|
||||
|
||||
foreach ($collection->getRequirements() as $requirement) {
|
||||
|
||||
$result = $requirement->isFulfilled() ? '<info>OK </info>' : ($requirement->isOptional() ? '<comment>WARNING</comment> ' : '<error>ERROR</error> ');
|
||||
$output->write(' ' . $result);
|
||||
|
||||
$output->writeln($requirement->getTestMessage());
|
||||
|
||||
if (!$requirement->isFulfilled()) {
|
||||
$output->writeln(" " . $requirement->getHelpText());
|
||||
$output->writeln('');
|
||||
}
|
||||
}
|
||||
|
||||
$output->writeln('');
|
||||
$output->writeln($collection->getName() . ' recommendations : ');
|
||||
$output->writeln('');
|
||||
|
||||
foreach ($collection->getRecommendations() as $requirement) {
|
||||
|
||||
$result = $requirement->isFulfilled() ? '<info>OK </info>' : ($requirement->isOptional() ? '<comment>WARNING</comment> ' : '<error>ERROR</error> ');
|
||||
$output->write(' ' . $result);
|
||||
|
||||
$output->writeln($requirement->getTestMessage());
|
||||
|
||||
if (!$requirement->isFulfilled()) {
|
||||
$output->writeln(" " . $requirement->getHelpText());
|
||||
$output->writeln('');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
@@ -140,15 +140,6 @@ class Dashboard implements ControllerProviderInterface
|
||||
'cache_flushed' => $request->query->get('flush_cache') === 'ok',
|
||||
'admins' => \User_Adapter::get_sys_admins($app),
|
||||
'email_status' => $emailStatus,
|
||||
'search_engine_status' => $app['phraseanet.SE']->getStatus(),
|
||||
'php_version_constraints' => \setup::check_php_version(),
|
||||
'writability_constraints' => \setup::check_writability($app['phraseanet.registry']),
|
||||
'binaries_constraints' => \setup::check_binaries($app['phraseanet.registry']),
|
||||
'php_extension_constraints' => \setup::check_php_extension(),
|
||||
'cache_constraints' => \setup::check_cache_server(),
|
||||
'phrasea_constraints' => \setup::check_phrasea(),
|
||||
'cache_opcode_constraints' => \setup::check_cache_opcode(),
|
||||
'php_configuration_constraints' => \setup::check_php_configuration(),
|
||||
);
|
||||
|
||||
return $app['twig']->render('admin/dashboard.html.twig', $parameters);
|
||||
|
@@ -38,64 +38,62 @@ class Installer implements ControllerProviderInterface
|
||||
|
||||
public function rootInstaller(Application $app, Request $request)
|
||||
{
|
||||
$php_constraint = \setup::check_php_version();
|
||||
$writability_constraints = \setup::check_writability(new \Setup_Registry());
|
||||
$extension_constraints = \setup::check_php_extension();
|
||||
$opcode_constraints = \setup::check_cache_opcode();
|
||||
$php_conf_constraints = \setup::check_php_configuration();
|
||||
$locales_constraints = \setup::check_system_locales($app);
|
||||
|
||||
// $php_constraint = \setup::check_php_version();
|
||||
// $writability_constraints = \setup::check_writability(new \Setup_Registry());
|
||||
// $extension_constraints = \setup::check_php_extension();
|
||||
// $opcode_constraints = \setup::check_cache_opcode();
|
||||
// $php_conf_constraints = \setup::check_php_configuration();
|
||||
// $locales_constraints = \setup::check_system_locales($app);
|
||||
//
|
||||
// $constraints_coll = array(
|
||||
// 'php_constraint' => $php_constraint
|
||||
// , 'writability_constraints' => $writability_constraints
|
||||
// , 'extension_constraints' => $extension_constraints
|
||||
// , 'opcode_constraints' => $opcode_constraints
|
||||
// , 'php_conf_constraints' => $php_conf_constraints
|
||||
// , 'locales_constraints' => $locales_constraints
|
||||
// );
|
||||
$constraints_coll = array(
|
||||
'php_constraint' => $php_constraint
|
||||
, 'writability_constraints' => $writability_constraints
|
||||
, 'extension_constraints' => $extension_constraints
|
||||
, 'opcode_constraints' => $opcode_constraints
|
||||
, 'php_conf_constraints' => $php_conf_constraints
|
||||
, 'locales_constraints' => $locales_constraints
|
||||
new \Alchemy\Phrasea\Setup\Requirements\BinariesRequirements(),
|
||||
new \Alchemy\Phrasea\Setup\Requirements\FilesystemRequirements(),
|
||||
new \Alchemy\Phrasea\Setup\Requirements\LocalesRequirements(),
|
||||
new \Alchemy\Phrasea\Setup\Requirements\PhpRequirements(),
|
||||
new \Alchemy\Phrasea\Setup\Requirements\PhraseaRequirements(),
|
||||
new \Alchemy\Phrasea\Setup\Requirements\SystemRequirements(),
|
||||
);
|
||||
$redirect = true;
|
||||
// $redirect = true;
|
||||
|
||||
foreach ($constraints_coll as $key => $constraints) {
|
||||
$unset = true;
|
||||
foreach ($constraints as $constraint) {
|
||||
if (!$constraint->is_ok() && $constraint->is_blocker())
|
||||
$redirect = $unset = false;
|
||||
}
|
||||
if ($unset === true) {
|
||||
unset($constraints_coll[$key]);
|
||||
}
|
||||
}
|
||||
// foreach ($constraints_coll as $key => $constraints) {
|
||||
// $unset = true;
|
||||
// foreach ($constraints as $constraint) {
|
||||
// if (!$constraint->is_ok() && $constraint->is_blocker())
|
||||
// $redirect = $unset = false;
|
||||
// }
|
||||
// if ($unset === true) {
|
||||
// unset($constraints_coll[$key]);
|
||||
// }
|
||||
// }
|
||||
|
||||
if ($redirect) {
|
||||
return $app->redirect('/setup/installer/step2/');
|
||||
}
|
||||
// if ($redirect) {
|
||||
// return $app->redirect('/setup/installer/step2/');
|
||||
// }
|
||||
|
||||
$app['twig.loader.filesystem']->setPaths(array(
|
||||
__DIR__ . '/../../../../../templates/web'
|
||||
// $app['twig.loader.filesystem']->setPaths(array(
|
||||
// __DIR__ . '/../../../../../templates/web'
|
||||
// ));
|
||||
|
||||
return $app['twig']->render('/setup/index.html.twig', array(
|
||||
'locale' => $app['locale'],
|
||||
'available_locales' => $app->getAvailableLanguages(),
|
||||
'current_servername' => $request->getScheme() . '://' . $request->getHttpHost() . '/',
|
||||
'constraints' => $constraints_coll,
|
||||
));
|
||||
|
||||
return $app['twig']->render(
|
||||
'/setup/index.html.twig'
|
||||
, array_merge($constraints_coll, array(
|
||||
'locale' => $app['locale']
|
||||
, 'available_locales' => $app->getAvailableLanguages()
|
||||
, 'version_number' => $app['phraseanet.version']->getNumber()
|
||||
, 'version_name' => $app['phraseanet.version']->getName()
|
||||
, 'current_servername' => $request->getScheme() . '://' . $request->getHttpHost() . '/'
|
||||
))
|
||||
);
|
||||
}
|
||||
|
||||
public function getInstallForm(Application $app, Request $request)
|
||||
{
|
||||
\phrasea::use_i18n($app['locale']);
|
||||
|
||||
$ld_path = array(__DIR__ . '/../../../../../templates/web');
|
||||
$loader = new \Twig_Loader_Filesystem($ld_path);
|
||||
|
||||
$twig = new \Twig_Environment($loader);
|
||||
$twig->addExtension(new \Twig_Extensions_Extension_I18n());
|
||||
|
||||
$warnings = array();
|
||||
|
||||
$php_constraint = \setup::check_php_version();
|
||||
@@ -127,20 +125,20 @@ class Installer implements ControllerProviderInterface
|
||||
$warnings[] = _('It is not recommended to install Phraseanet without HTTPS support');
|
||||
}
|
||||
|
||||
return $twig->render(
|
||||
'/setup/step2.html.twig'
|
||||
, array(
|
||||
'locale' => $app['locale']
|
||||
, 'available_locales' => $app->getAvailableLanguages()
|
||||
, 'available_templates' => array('en', 'fr')
|
||||
, 'version_number' => $app['phraseanet.version']->getNumber()
|
||||
, 'version_name' => $app['phraseanet.version']->getName()
|
||||
, 'warnings' => $warnings
|
||||
, 'error' => $request->query->get('error')
|
||||
, 'current_servername' => $request->getScheme() . '://' . $request->getHttpHost() . '/'
|
||||
, 'discovered_binaries' => \setup::discover_binaries()
|
||||
, 'rootpath' => dirname(dirname(dirname(dirname(__DIR__)))) . '/'
|
||||
));
|
||||
return $app['twig']->render(
|
||||
'/setup/step2.html.twig'
|
||||
, array(
|
||||
'locale' => $app['locale']
|
||||
, 'available_locales' => $app->getAvailableLanguages()
|
||||
, 'available_templates' => array('en', 'fr')
|
||||
, 'version_number' => $app['phraseanet.version']->getNumber()
|
||||
, 'version_name' => $app['phraseanet.version']->getName()
|
||||
, 'warnings' => $warnings
|
||||
, 'error' => $request->query->get('error')
|
||||
, 'current_servername' => $request->getScheme() . '://' . $request->getHttpHost() . '/'
|
||||
, 'discovered_binaries' => \setup::discover_binaries()
|
||||
, 'rootpath' => dirname(dirname(dirname(dirname(__DIR__)))) . '/'
|
||||
));
|
||||
}
|
||||
|
||||
public function doInstall(Application $app, Request $request)
|
||||
|
@@ -12,17 +12,28 @@
|
||||
namespace Alchemy\Phrasea\Setup;
|
||||
|
||||
use Alchemy\Phrasea\Application;
|
||||
use Alchemy\Phrasea\Setup\System\ProbeInterface as SystemProbeInterface;
|
||||
use Alchemy\Phrasea\Setup\Version\Probe\Probe31;
|
||||
use Alchemy\Phrasea\Setup\Version\Probe\Probe35;
|
||||
use Alchemy\Phrasea\Setup\Version\Probe\ProbeInterface as VersionProbeInterface;
|
||||
use Alchemy\Phrasea\Setup\Probe\BinariesProbe;
|
||||
use Alchemy\Phrasea\Setup\Probe\CacheServerProbe;
|
||||
use Alchemy\Phrasea\Setup\Probe\OpcodeCacheProbe;
|
||||
use Alchemy\Phrasea\Setup\Probe\FilesystemProbe;
|
||||
use Alchemy\Phrasea\Setup\Probe\LocalesProbe;
|
||||
use Alchemy\Phrasea\Setup\Probe\PhpProbe;
|
||||
use Alchemy\Phrasea\Setup\Probe\PhraseaProbe;
|
||||
use Alchemy\Phrasea\Setup\Probe\SearchEngineProbe;
|
||||
use Alchemy\Phrasea\Setup\Probe\SystemProbe;
|
||||
|
||||
class ConfigurationTester
|
||||
{
|
||||
private $app;
|
||||
private $probes;
|
||||
private $requirements;
|
||||
private $versionProbes;
|
||||
|
||||
const PROD_ENV = 'prod';
|
||||
const DEV_ENV = 'dev';
|
||||
|
||||
public function __construct(Application $app)
|
||||
{
|
||||
$this->app = $app;
|
||||
@@ -33,9 +44,25 @@ class ConfigurationTester
|
||||
);
|
||||
}
|
||||
|
||||
public function registerProbe(SystemProbeInterface $probe)
|
||||
public function getRequirements()
|
||||
{
|
||||
$this->probes[] = $probe;
|
||||
if ($this->requirements) {
|
||||
return $this->requirements;
|
||||
}
|
||||
|
||||
$this->requirements = array(
|
||||
BinariesProbe::create($this->app),
|
||||
CacheServerProbe::create($this->app),
|
||||
OpcodeCacheProbe::create($this->app),
|
||||
FilesystemProbe::create($this->app),
|
||||
LocalesProbe::create($this->app),
|
||||
PhpProbe::create($this->app),
|
||||
PhraseaProbe::create($this->app),
|
||||
SearchEngineProbe::create($this->app),
|
||||
SystemProbe::create($this->app),
|
||||
);
|
||||
|
||||
return $this->requirements;
|
||||
}
|
||||
|
||||
public function registerVersionProbe(VersionProbeInterface $probe)
|
||||
@@ -96,6 +123,7 @@ class ConfigurationTester
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if a major migration script can be executed
|
||||
*
|
||||
* @return type
|
||||
*/
|
||||
|
38
lib/Alchemy/Phrasea/Setup/Probe/BinariesProbe.php
Normal file
38
lib/Alchemy/Phrasea/Setup/Probe/BinariesProbe.php
Normal file
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
namespace Alchemy\Phrasea\Setup\Probe;
|
||||
|
||||
use Alchemy\Phrasea\Application;
|
||||
use Alchemy\Phrasea\Setup\Requirements\BinariesRequirements;
|
||||
|
||||
class BinariesProbe extends BinariesRequirements implements ProbeInterface
|
||||
{
|
||||
const REQUIRED_PHP_VERSION = '5.3.3';
|
||||
|
||||
public function __construct(\registryInterface $registry)
|
||||
{
|
||||
parent::__construct(array_filter(array(
|
||||
'php_binary' => $registry->get('php_binary'),
|
||||
'convert_binary' => $registry->get('convert_binary'),
|
||||
'pdf2swf_binary' => $registry->get('pdf2swf_binary'),
|
||||
'unoconv_binary' => $registry->get('unoconv_binary'),
|
||||
'swf_extract_binary' => $registry->get('swf_extract_binary'),
|
||||
'swf_render_binary' => $registry->get('swf_render_binary'),
|
||||
'mp4box_binary' => $registry->get('mp4box_binary'),
|
||||
'pdftotext_binary' => $registry->get('pdftotext_binary'),
|
||||
'composite_binary' => $registry->get('composite_binary'),
|
||||
'ffmpeg_binary' => $registry->get('ffmpeg_binary'),
|
||||
'ffprobe_binary' => $registry->get('ffprobe_binary'),
|
||||
)));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @return BinariesProbe
|
||||
*/
|
||||
public static function create(Application $app)
|
||||
{
|
||||
return new static($app['phraseanet.registry']);
|
||||
}
|
||||
}
|
55
lib/Alchemy/Phrasea/Setup/Probe/FilesystemProbe.php
Normal file
55
lib/Alchemy/Phrasea/Setup/Probe/FilesystemProbe.php
Normal file
@@ -0,0 +1,55 @@
|
||||
<?php
|
||||
|
||||
namespace Alchemy\Phrasea\Setup\Probe;
|
||||
|
||||
use Alchemy\Phrasea\Application;
|
||||
use Alchemy\Phrasea\Setup\Requirements\FilesystemRequirements;
|
||||
|
||||
class FilesystemProbe extends FilesystemRequirements implements ProbeInterface
|
||||
{
|
||||
public function __construct(\registryInterface $registry)
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
$baseDir = realpath(__DIR__ . '/../../../../../');
|
||||
|
||||
$paths = array(
|
||||
$baseDir . '/config/config.yml',
|
||||
$baseDir . '/config/connexions.yml',
|
||||
$baseDir . '/config/services.yml',
|
||||
$baseDir . '/config/binaries.yml',
|
||||
);
|
||||
|
||||
foreach ($paths as $path) {
|
||||
$this->addRecommendation(
|
||||
"00" === substr(sprintf('%o', fileperms($path)), -2),
|
||||
"$path should not be readable or writeable for other users, current mode is (".substr(sprintf('%o', fileperms($path)), -4).")",
|
||||
"Change the permissions of the \"<strong>$path</strong>\" file to 0600"
|
||||
);
|
||||
}
|
||||
|
||||
$path = array();
|
||||
|
||||
if ($registry->is_set('GV_base_datapath_noweb')) {
|
||||
$paths[] = $registry->get('GV_base_datapath_noweb');
|
||||
}
|
||||
|
||||
foreach ($paths as $path) {
|
||||
$this->addRequirement(
|
||||
is_writable($path),
|
||||
"$path directory must be writable",
|
||||
"Change the permissions of the \"<strong>$path</strong>\" directory so that the web server can write into it."
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @return FilesystemProbe
|
||||
*/
|
||||
public static function create(Application $app)
|
||||
{
|
||||
return new static($app['phraseanet.registry']);
|
||||
}
|
||||
}
|
24
lib/Alchemy/Phrasea/Setup/Probe/LocalesProbe.php
Normal file
24
lib/Alchemy/Phrasea/Setup/Probe/LocalesProbe.php
Normal file
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
namespace Alchemy\Phrasea\Setup\Probe;
|
||||
|
||||
use Alchemy\Phrasea\Application;
|
||||
use Alchemy\Phrasea\Setup\Requirements\LocalesRequirements;
|
||||
|
||||
class LocalesProbe extends LocalesRequirements implements ProbeInterface
|
||||
{
|
||||
public function __construct($locale)
|
||||
{
|
||||
parent::__construct($locale);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @return LocalesProbe
|
||||
*/
|
||||
public static function create(Application $app)
|
||||
{
|
||||
return new static($app['locale']);
|
||||
}
|
||||
}
|
19
lib/Alchemy/Phrasea/Setup/Probe/PhpProbe.php
Normal file
19
lib/Alchemy/Phrasea/Setup/Probe/PhpProbe.php
Normal file
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
namespace Alchemy\Phrasea\Setup\Probe;
|
||||
|
||||
use Alchemy\Phrasea\Application;
|
||||
use Alchemy\Phrasea\Setup\Requirements\PhpRequirements;
|
||||
|
||||
class PhpProbe extends PhpRequirements implements ProbeInterface
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @return SystemProbe
|
||||
*/
|
||||
public static function create(Application $app)
|
||||
{
|
||||
return new static();
|
||||
}
|
||||
}
|
19
lib/Alchemy/Phrasea/Setup/Probe/PhraseaProbe.php
Normal file
19
lib/Alchemy/Phrasea/Setup/Probe/PhraseaProbe.php
Normal file
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
namespace Alchemy\Phrasea\Setup\Probe;
|
||||
|
||||
use Alchemy\Phrasea\Application;
|
||||
use Alchemy\Phrasea\Setup\Requirements\PhraseaRequirements;
|
||||
|
||||
class PhraseaProbe extends PhraseaRequirements implements ProbeInterface
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @return PhraseaProbe
|
||||
*/
|
||||
public static function create(Application $app)
|
||||
{
|
||||
return new static();
|
||||
}
|
||||
}
|
14
lib/Alchemy/Phrasea/Setup/Probe/ProbeInterface.php
Normal file
14
lib/Alchemy/Phrasea/Setup/Probe/ProbeInterface.php
Normal file
@@ -0,0 +1,14 @@
|
||||
<?php
|
||||
|
||||
namespace Alchemy\Phrasea\Setup\Probe;
|
||||
|
||||
use Alchemy\Phrasea\Application;
|
||||
use Alchemy\Phrasea\Setup\System\RequirementCollectionInterface;
|
||||
|
||||
interface ProbeInterface extends RequirementCollectionInterface
|
||||
{
|
||||
/**
|
||||
* @param Application $app
|
||||
*/
|
||||
public static function create(Application $app);
|
||||
}
|
25
lib/Alchemy/Phrasea/Setup/Probe/SearchEngineProbe.php
Normal file
25
lib/Alchemy/Phrasea/Setup/Probe/SearchEngineProbe.php
Normal file
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
namespace Alchemy\Phrasea\Setup\Probe;
|
||||
|
||||
use Alchemy\Phrasea\Application;
|
||||
use Alchemy\Phrasea\Setup\System\RequirementCollection;
|
||||
use Alchemy\Phrasea\SearchEngine\SearchEngineInterface;
|
||||
|
||||
class SearchEngineProbe extends RequirementCollection implements ProbeInterface
|
||||
{
|
||||
public function __construct(SearchEngineInterface $searchEngine)
|
||||
{
|
||||
$this->setName('Search Engine');
|
||||
|
||||
foreach ($searchEngine->getStatus() as $infos)
|
||||
{
|
||||
$this->addInformation($infos[0], $infos[1]);
|
||||
}
|
||||
}
|
||||
|
||||
public static function create(Application $app)
|
||||
{
|
||||
return new static($app['phraseanet.SE']);
|
||||
}
|
||||
}
|
19
lib/Alchemy/Phrasea/Setup/Probe/SystemProbe.php
Normal file
19
lib/Alchemy/Phrasea/Setup/Probe/SystemProbe.php
Normal file
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
namespace Alchemy\Phrasea\Setup\Probe;
|
||||
|
||||
use Alchemy\Phrasea\Application;
|
||||
use Alchemy\Phrasea\Setup\Requirements\SystemRequirements;
|
||||
|
||||
class SystemProbe extends SystemRequirements implements ProbeInterface
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @return SystemProbe
|
||||
*/
|
||||
public static function create(Application $app)
|
||||
{
|
||||
return new static();
|
||||
}
|
||||
}
|
213
lib/Alchemy/Phrasea/Setup/Requirements/BinariesRequirements.php
Normal file
213
lib/Alchemy/Phrasea/Setup/Requirements/BinariesRequirements.php
Normal file
@@ -0,0 +1,213 @@
|
||||
<?php
|
||||
|
||||
namespace Alchemy\Phrasea\Setup\Requirements;
|
||||
|
||||
use Alchemy\Phrasea\Setup\System\RequirementCollection;
|
||||
use Symfony\Component\Process\ExecutableFinder;
|
||||
|
||||
class BinariesRequirements extends RequirementCollection
|
||||
{
|
||||
const REQUIRED_PHP_VERSION = '5.3.3';
|
||||
|
||||
public function __construct($binaries = array())
|
||||
{
|
||||
$this->setName('Binaries');
|
||||
|
||||
$finder = new ExecutableFinder();
|
||||
|
||||
$phpCLI = isset($binaries['php_binary']) ? $binaries['php_binary'] : $finder->find('php');
|
||||
|
||||
$this->addRequirement(
|
||||
null !== $phpCLI && is_executable($phpCLI),
|
||||
'PHP CLI is required to run Phraseanet task manager',
|
||||
'Please reinstall PHP with CLI support'
|
||||
);
|
||||
|
||||
$indexer = $finder->find('phraseanet_indexer');
|
||||
|
||||
$this->addRecommendation(
|
||||
null !== $indexer && is_executable($indexer),
|
||||
'Phraseanet Indexer is required to use Phrasea search-engine',
|
||||
'Please install latest Phraseanet Indexer (https://github.com/alchemy-fr/Phraseanet-Indexer)'
|
||||
);
|
||||
|
||||
$convert = isset($binaries['convert_binary']) ? $binaries['convert_binary'] : $finder->find('convert');
|
||||
|
||||
$this->addRequirement(
|
||||
null !== $convert && is_executable($convert),
|
||||
'ImageMagick Convert is required',
|
||||
'Please install ImageMagick'
|
||||
);
|
||||
|
||||
if (null !== $convert) {
|
||||
$output = null;
|
||||
exec($convert . ' --version', $output);
|
||||
$data = sscanf($output[0], 'Version: ImageMagick %d.%d.%d');
|
||||
$version = sprintf('%d.%d.%d', $data[0], $data[1], $data[2]);
|
||||
|
||||
$this->addRequirement(
|
||||
version_compare('6.2.9', $version, '<'),
|
||||
'Convert version 6.2.9 or higher is required ('.$version.' provided)',
|
||||
'Please update to a more recent version'
|
||||
);
|
||||
}
|
||||
|
||||
$composite = isset($binaries['composite_binary']) ? $binaries['composite_binary'] : $finder->find('composite');
|
||||
|
||||
$this->addRequirement(
|
||||
null !== $composite && is_executable($composite),
|
||||
'ImageMagick Composite is required',
|
||||
'Please install ImageMagick'
|
||||
);
|
||||
|
||||
if (null !== $composite) {
|
||||
$output = null;
|
||||
exec($composite . ' --version', $output);
|
||||
$data = sscanf($output[0], 'Version: ImageMagick %d.%d.%d');
|
||||
$version = sprintf('%d.%d.%d', $data[0], $data[1], $data[2]);
|
||||
|
||||
$this->addRequirement(
|
||||
version_compare('6.2.9', $version, '<'),
|
||||
'Composite version 6.2.9 or higher is required ('.$version.' provided)',
|
||||
'Please update to a more recent version.'
|
||||
);
|
||||
}
|
||||
|
||||
$pdf2swf = isset($binaries['pdf2swf_binary']) ? $binaries['pdf2swf_binary'] : $finder->find('pdf2swf');
|
||||
|
||||
$this->addRecommendation(
|
||||
null !== $pdf2swf && is_executable($pdf2swf),
|
||||
'SWFTools are required for documents (Word, Excel, PDF, etc...) support',
|
||||
'Please install SWFTools (http://www.swftools.org/)'
|
||||
);
|
||||
|
||||
if (null !== $pdf2swf) {
|
||||
$output = null;
|
||||
exec($pdf2swf . ' --version', $output);
|
||||
$data = sscanf($output[0], 'pdf2swf - part of swftools %d.%d.%d');
|
||||
$version = sprintf('%d.%d.%d', $data[0], $data[1], $data[2]);
|
||||
|
||||
$this->addRecommendation(
|
||||
version_compare('0.9.0', $version, '<='),
|
||||
'SWFTools (pdf2swf) version 0.9.0 or higher is required ('.$version.' provided)',
|
||||
'Please update to a more recent version.'
|
||||
);
|
||||
}
|
||||
|
||||
$unoconv = isset($binaries['unoconv_binary']) ? $binaries['unoconv_binary'] : $finder->find('unoconv');
|
||||
|
||||
$this->addRecommendation(
|
||||
null !== $unoconv && is_executable($unoconv),
|
||||
'Unoconv is required for documents (Word, Excel, etc...) support',
|
||||
'Please install Unoconv'
|
||||
);
|
||||
|
||||
if (null !== $unoconv) {
|
||||
$output = null;
|
||||
exec($unoconv . ' --version', $output);
|
||||
$data = sscanf($output[0], 'unoconv %d.%d');
|
||||
$version = sprintf('%d.%d', $data[0], $data[1]);
|
||||
|
||||
$this->addRecommendation(
|
||||
version_compare('0.5', $version, '<='),
|
||||
'Unoconv version 0.5 or higher is required ('.$version.' provided)',
|
||||
'Please update to a more recent version.'
|
||||
);
|
||||
}
|
||||
|
||||
$swfextract = isset($binaries['swf_extract_binary']) ? $binaries['swf_extract_binary'] : $finder->find('swfextract');
|
||||
|
||||
$this->addRecommendation(
|
||||
null !== $swfextract && is_executable($swfextract),
|
||||
'SWFTools (swfextract) are required for flash files support',
|
||||
'Please install SWFTools (http://www.swftools.org/)'
|
||||
);
|
||||
|
||||
if (null !== $swfextract) {
|
||||
$output = null;
|
||||
exec($swfextract . ' --version', $output);
|
||||
$data = sscanf($output[0], 'swfextract - part of swftools %d.%d.%d');
|
||||
$version = sprintf('%d.%d.%d', $data[0], $data[1], $data[2]);
|
||||
|
||||
$this->addRecommendation(
|
||||
version_compare('0.9.0', $version, '<='),
|
||||
'SWFTools (swfextract) version 0.9.0 or higher is required ('.$version.' provided)',
|
||||
'Please update to a more recent version.'
|
||||
);
|
||||
}
|
||||
|
||||
$swfrender = isset($binaries['swf_render_binary']) ? $binaries['swf_render_binary'] : $finder->find('swfrender');
|
||||
|
||||
$this->addRecommendation(
|
||||
null !== $swfrender && is_executable($swfrender),
|
||||
'SWFTools (swfrender) are required for flash files support',
|
||||
'Please install SWFTools (http://www.swftools.org/)'
|
||||
);
|
||||
|
||||
if (null !== $swfrender) {
|
||||
$output = null;
|
||||
exec($swfrender . ' --version', $output);
|
||||
$data = sscanf($output[0], 'swfrender - part of swftools %d.%d.%d');
|
||||
$version = sprintf('%d.%d.%d', $data[0], $data[1], $data[2]);
|
||||
|
||||
$this->addRecommendation(
|
||||
version_compare('0.9.0', $version, '<='),
|
||||
'SWFTools (swfrender) version 0.9.0 or higher is required ('.$version.' provided)',
|
||||
'Please update to a more recent version.'
|
||||
);
|
||||
}
|
||||
|
||||
$mp4box = isset($binaries['mp4box_binary']) ? $binaries['mp4box_binary'] : $finder->find('MP4Box');
|
||||
|
||||
$this->addRecommendation(
|
||||
null !== $mp4box && is_executable($mp4box),
|
||||
'MP4Box is required for video support',
|
||||
'Please install MP4Box'
|
||||
);
|
||||
|
||||
if (null !== $mp4box) {
|
||||
$output = null;
|
||||
exec($mp4box . ' -version', $output);
|
||||
$data = sscanf($output[0], 'MP4Box - GPAC version %d.%d.%d');
|
||||
$version = sprintf('%d.%d.%d', $data[0], $data[1], $data[2]);
|
||||
|
||||
$this->addRecommendation(
|
||||
version_compare('0.4.0', $version, '<='),
|
||||
'MP4Box version 0.4.0 or higher is required ('.$version.' provided)',
|
||||
'Please update to a more recent version.'
|
||||
);
|
||||
}
|
||||
|
||||
$pdftotext = isset($binaries['pdftotext_binary']) ? $binaries['pdftotext_binary'] : $finder->find('pdftotext');
|
||||
|
||||
$this->addRecommendation(
|
||||
null !== $pdftotext && is_executable($pdftotext),
|
||||
'XPDF is required for PDF indexation',
|
||||
'Please install XPDF'
|
||||
);
|
||||
|
||||
$ffmpeg = isset($binaries['ffmpeg_binary']) ? $binaries['ffmpeg_binary'] : $finder->find('ffmpeg');
|
||||
|
||||
if (null === $ffmpeg) {
|
||||
$ffmpeg = $finder->find('avconv');
|
||||
}
|
||||
|
||||
$this->addRecommendation(
|
||||
null !== $ffmpeg && is_executable($ffmpeg),
|
||||
'FFMpeg (or libav-tools) is required for Video processing',
|
||||
'Please install FFMpeg (or libav-tools)'
|
||||
);
|
||||
|
||||
$ffprobe = isset($binaries['ffprobe_binary']) ? $binaries['ffprobe_binary'] : $finder->find('ffprobe');
|
||||
|
||||
if (null === $ffprobe) {
|
||||
$ffprobe = $finder->find('avprobe');
|
||||
}
|
||||
|
||||
$this->addRecommendation(
|
||||
null !== $ffprobe && is_executable($ffprobe),
|
||||
'FFProbe (or avprobe) is required for Video processing',
|
||||
'Please install FFProbe (or avprobe)'
|
||||
);
|
||||
}
|
||||
}
|
@@ -0,0 +1,43 @@
|
||||
<?php
|
||||
|
||||
namespace Alchemy\Phrasea\Setup\Requirements;
|
||||
|
||||
use Alchemy\Phrasea\Setup\System\RequirementCollection;
|
||||
|
||||
class FilesystemRequirements extends RequirementCollection
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
$baseDir = realpath(__DIR__ . '/../../../../../');
|
||||
|
||||
$this->setName('Filesystem');
|
||||
|
||||
$paths = array(
|
||||
$baseDir . '/config',
|
||||
$baseDir . '/config/stamp',
|
||||
$baseDir . '/config/status',
|
||||
$baseDir . '/config/minilogos',
|
||||
$baseDir . '/config/templates',
|
||||
$baseDir . '/config/topics',
|
||||
$baseDir . '/config/wm',
|
||||
$baseDir . '/logs',
|
||||
$baseDir . '/tmp',
|
||||
$baseDir . '/www/custom',
|
||||
$baseDir . '/tmp/locks',
|
||||
$baseDir . '/tmp/cache_twig',
|
||||
$baseDir . '/tmp/cache_minify',
|
||||
$baseDir . '/tmp/lazaret',
|
||||
$baseDir . '/tmp/desc_tmp',
|
||||
$baseDir . '/tmp/download',
|
||||
$baseDir . '/tmp/batches'
|
||||
);
|
||||
|
||||
foreach ($paths as $path) {
|
||||
$this->addRequirement(
|
||||
is_writable($path),
|
||||
"$path directory must be writable",
|
||||
"Change the permissions of the \"<strong>$path</strong>\" directory so that the web server can write into it."
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,63 @@
|
||||
<?php
|
||||
|
||||
namespace Alchemy\Phrasea\Setup\Requirements;
|
||||
|
||||
use Alchemy\Phrasea\Setup\System\RequirementCollection;
|
||||
use Alchemy\Phrasea\Application as PhraseaApplication;
|
||||
|
||||
class LocalesRequirements extends RequirementCollection
|
||||
{
|
||||
public function __construct($locale = 'en_GB')
|
||||
{
|
||||
$this->setName('Locales');
|
||||
|
||||
$this->addRequirement(
|
||||
class_exists('Locale'),
|
||||
'intl extension should be available',
|
||||
'Install and enable the <strong>intl</strong> extension (used for validators).'
|
||||
);
|
||||
|
||||
if (function_exists('_')) {
|
||||
foreach (PhraseaApplication::getAvailableLanguages() as $code => $language_name){
|
||||
\phrasea::use_i18n($code, 'test');
|
||||
|
||||
$this->addRecommendation(
|
||||
'test' === _('test::test'),
|
||||
sprintf('Locale %s (%s) should be supported', $language_name, $code),
|
||||
'Install support for locale <strong>' . $code . '</strong> (' . $language_name . ').'
|
||||
);
|
||||
|
||||
\phrasea::use_i18n($locale);
|
||||
}
|
||||
}
|
||||
|
||||
if (class_exists('Collator')) {
|
||||
$this->addRecommendation(
|
||||
null !== new \Collator('fr_FR'),
|
||||
'intl extension should be correctly configured',
|
||||
'The intl extension does not behave properly. This problem is typical on PHP 5.3.X x64 WIN builds.'
|
||||
);
|
||||
}
|
||||
|
||||
if (class_exists('Locale')) {
|
||||
if (defined('INTL_ICU_VERSION')) {
|
||||
$version = INTL_ICU_VERSION;
|
||||
} else {
|
||||
$reflector = new ReflectionExtension('intl');
|
||||
|
||||
ob_start();
|
||||
$reflector->info();
|
||||
$output = strip_tags(ob_get_clean());
|
||||
|
||||
preg_match('/^ICU version +(?:=> )?(.*)$/m', $output, $matches);
|
||||
$version = $matches[1];
|
||||
}
|
||||
|
||||
$this->addRecommendation(
|
||||
version_compare($version, '4.0', '>='),
|
||||
'intl ICU version should be at least 4+',
|
||||
'Upgrade your <strong>intl</strong> extension with a newer ICU version (4+).'
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
67
lib/Alchemy/Phrasea/Setup/Requirements/PhpRequirements.php
Normal file
67
lib/Alchemy/Phrasea/Setup/Requirements/PhpRequirements.php
Normal file
@@ -0,0 +1,67 @@
|
||||
<?php
|
||||
|
||||
namespace Alchemy\Phrasea\Setup\Requirements;
|
||||
|
||||
use Alchemy\Phrasea\Setup\System\RequirementCollection;
|
||||
|
||||
class PhpRequirements extends RequirementCollection
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
$this->setName('PHP');
|
||||
|
||||
$this->addPhpIniRequirement(
|
||||
'date.timezone', true, false,
|
||||
'date.timezone setting must be set',
|
||||
'Set the "<strong>date.timezone</strong>" setting in php.ini<a href="#phpini">*</a> (like Europe/Paris).'
|
||||
);
|
||||
|
||||
$this->addPhpIniRequirement('detect_unicode', false);
|
||||
|
||||
if (extension_loaded('suhosin')) {
|
||||
$this->addPhpIniRequirement(
|
||||
'suhosin.executor.include.whitelist',
|
||||
create_function('$cfgValue', 'return false !== stripos($cfgValue, "phar");'),
|
||||
false,
|
||||
'suhosin.executor.include.whitelist must be configured correctly in php.ini',
|
||||
'Add "<strong>phar</strong>" to <strong>suhosin.executor.include.whitelist</strong> in php.ini<a href="#phpini">*</a>.'
|
||||
);
|
||||
}
|
||||
|
||||
if (extension_loaded('xdebug')) {
|
||||
$this->addPhpIniRequirement(
|
||||
'xdebug.show_exception_trace', false, true
|
||||
);
|
||||
|
||||
$this->addPhpIniRequirement(
|
||||
'xdebug.scream', false, true
|
||||
);
|
||||
|
||||
$this->addPhpIniRecommendation(
|
||||
'xdebug.max_nesting_level',
|
||||
create_function('$cfgValue', 'return $cfgValue > 100;'),
|
||||
true,
|
||||
'xdebug.max_nesting_level should be above 100 in php.ini',
|
||||
'Set "<strong>xdebug.max_nesting_level</strong>" to e.g. "<strong>250</strong>" in php.ini<a href="#phpini">*</a> to stop Xdebug\'s infinite recursion protection erroneously throwing a fatal error in your project.'
|
||||
);
|
||||
}
|
||||
|
||||
$this->addPhpIniRequirement('safe_mode', false, true);
|
||||
$this->addPhpIniRequirement('file_uploads', true, true);
|
||||
$this->addPhpIniRequirement('session.cache_limiter', '');
|
||||
$this->addPhpIniRequirement('default_charset', 'UTF-8', true, 'Default charset should be UTF-8', 'Set default_charset to UTF-8 in php.ini');
|
||||
$this->addPhpIniRequirement('magic_quotes_gpc', false, true);
|
||||
$this->addPhpIniRequirement('magic_quotes_runtime', false, true);
|
||||
|
||||
$this->addPhpIniRecommendation('short_open_tag', false);
|
||||
$this->addPhpIniRecommendation('register_globals', false, true);
|
||||
$this->addPhpIniRecommendation('session.auto_start', false);
|
||||
$this->addPhpIniRecommendation('display_errors', false, true);
|
||||
$this->addPhpIniRecommendation('display_startup_errors', false, true);
|
||||
$this->addPhpIniRecommendation('allow_url_fopen', true, true);
|
||||
$this->addPhpIniRecommendation('session.hash_bits_per_character', '6', true, 'session.hash_bits_per_character should be at least 6', 'Set session.hash_bits_per_character to 6 in php.ini');
|
||||
$this->addPhpIniRecommendation('session.hash_function', true, true);
|
||||
$this->addPhpIniRecommendation('session.use_only_cookies', true, true);
|
||||
$this->addPhpIniRecommendation('session.use_cookies', true, true);
|
||||
}
|
||||
}
|
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
namespace Alchemy\Phrasea\Setup\Requirements;
|
||||
|
||||
use Alchemy\Phrasea\Setup\System\RequirementCollection;
|
||||
|
||||
class PhraseaRequirements extends RequirementCollection
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
$this->setName('Phrasea');
|
||||
|
||||
$this->addRecommendation(
|
||||
function_exists('phrasea_fetch_results'),
|
||||
'phrasea extension is required to use Phrasea search-engine',
|
||||
'Install and enable the <strong>phrasea</strong> extension to enable Phrasea search-engine (https://github.com/alchemy-fr/Phraseanet-Extension).'
|
||||
);
|
||||
|
||||
if (function_exists('phrasea_fetch_results')) {
|
||||
$infos = phrasea_info();
|
||||
|
||||
$this->addRequirement(
|
||||
version_compare($infos['version'], '1.21.0.1', '>='),
|
||||
'phrasea extension version 1.21.0.1 is required (version ' . $infos['version'] . ' installed)',
|
||||
'Update <strong>phrasea</strong> extension to the latest stable (https://github.com/alchemy-fr/Phraseanet-Extension).'
|
||||
);
|
||||
$this->addRequirement(
|
||||
true === $infos['temp_writable'],
|
||||
'phrasea extension should be able to write in its temporary directory (current is ' . $infos['temp_dir'] . ')',
|
||||
'Change directory <strong>' . $infos['temp_dir'] . '</strong> mode so phrasea extension could write to it'
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
331
lib/Alchemy/Phrasea/Setup/Requirements/SystemRequirements.php
Normal file
331
lib/Alchemy/Phrasea/Setup/Requirements/SystemRequirements.php
Normal file
@@ -0,0 +1,331 @@
|
||||
<?php
|
||||
|
||||
namespace Alchemy\Phrasea\Setup\Requirements;
|
||||
|
||||
use Alchemy\Phrasea\Setup\System\RequirementCollection;
|
||||
use Alchemy\Phrasea\Application as PhraseaApplication;
|
||||
|
||||
class SystemRequirements extends RequirementCollection
|
||||
{
|
||||
const REQUIRED_PHP_VERSION = '5.3.3';
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$installedPhpVersion = phpversion();
|
||||
|
||||
$baseDir = realpath(__DIR__ . '/../../../../../');
|
||||
|
||||
$this->setName('System');
|
||||
|
||||
$this->addRequirement(
|
||||
version_compare($installedPhpVersion, self::REQUIRED_PHP_VERSION, '>='),
|
||||
sprintf('PHP version must be at least %s (%s installed)', self::REQUIRED_PHP_VERSION, $installedPhpVersion),
|
||||
sprintf('You are running PHP version "<strong>%s</strong>", but Phraseanet needs at least PHP "<strong>%s</strong>" to run.
|
||||
Before using Phraseanet, upgrade your PHP installation, preferably to the latest version.',
|
||||
$installedPhpVersion, self::REQUIRED_PHP_VERSION),
|
||||
sprintf('Install PHP %s or newer (installed version is %s)', self::REQUIRED_PHP_VERSION, $installedPhpVersion)
|
||||
);
|
||||
|
||||
$this->addRequirement(
|
||||
version_compare($installedPhpVersion, '5.3.16', '!='),
|
||||
'PHP version must not be 5.3.16 as Phraseanet won\'t work properly with it',
|
||||
'Install PHP 5.3.17 or newer (or downgrade to an earlier PHP version)'
|
||||
);
|
||||
|
||||
$this->addRequirement(
|
||||
is_dir($baseDir.'/vendor/composer'),
|
||||
'Vendor libraries must be installed',
|
||||
'Vendor libraries are missing. Install composer following instructions from <a href="http://getcomposer.org/">http://getcomposer.org/</a>. ' .
|
||||
'Then run "<strong>php composer.phar install</strong>" to install them.'
|
||||
);
|
||||
|
||||
$this->addPhpIniRequirement(
|
||||
'date.timezone', true, false,
|
||||
'date.timezone setting must be set',
|
||||
'Set the "<strong>date.timezone</strong>" setting in php.ini<a href="#phpini">*</a> (like Europe/Paris).'
|
||||
);
|
||||
|
||||
if (version_compare($installedPhpVersion, self::REQUIRED_PHP_VERSION, '>=')) {
|
||||
$timezones = array();
|
||||
foreach (\DateTimeZone::listAbbreviations() as $abbreviations) {
|
||||
foreach ($abbreviations as $abbreviation) {
|
||||
$timezones[$abbreviation['timezone_id']] = true;
|
||||
}
|
||||
}
|
||||
|
||||
$this->addRequirement(
|
||||
isset($timezones[date_default_timezone_get()]),
|
||||
sprintf('Configured default timezone "%s" must be supported by your installation of PHP', date_default_timezone_get()),
|
||||
'Your default timezone is not supported by PHP. Check for typos in your <strong>php.ini</strong> file and have a look at the list of deprecated timezones at <a href="http://php.net/manual/en/timezones.others.php">http://php.net/manual/en/timezones.others.php</a>.'
|
||||
);
|
||||
}
|
||||
|
||||
$this->addRequirement(
|
||||
function_exists('json_encode'),
|
||||
'json_encode() must be available',
|
||||
'Install and enable the <strong>JSON</strong> extension.'
|
||||
);
|
||||
|
||||
$this->addRequirement(
|
||||
function_exists('session_start'),
|
||||
'session_start() must be available',
|
||||
'Install and enable the <strong>session</strong> extension.'
|
||||
);
|
||||
|
||||
$this->addRequirement(
|
||||
function_exists('ctype_alpha'),
|
||||
'ctype_alpha() must be available',
|
||||
'Install and enable the <strong>ctype</strong> extension.'
|
||||
);
|
||||
|
||||
$this->addRequirement(
|
||||
function_exists('token_get_all'),
|
||||
'token_get_all() must be available',
|
||||
'Install and enable the <strong>Tokenizer</strong> extension.'
|
||||
);
|
||||
|
||||
$this->addRequirement(
|
||||
function_exists('simplexml_import_dom'),
|
||||
'simplexml_import_dom() must be available',
|
||||
'Install and enable the <strong>SimpleXML</strong> extension.'
|
||||
);
|
||||
|
||||
if (function_exists('apc_store') && ini_get('apc.enabled')) {
|
||||
if (version_compare($installedPhpVersion, '5.4.0', '>=')) {
|
||||
$this->addRequirement(
|
||||
version_compare(phpversion('apc'), '3.1.13', '>='),
|
||||
'APC version must be at least 3.1.13 when using PHP 5.4',
|
||||
'Upgrade your <strong>APC</strong> extension (3.1.13+).'
|
||||
);
|
||||
} else {
|
||||
$this->addRequirement(
|
||||
version_compare(phpversion('apc'), '3.0.17', '>='),
|
||||
'APC version must be at least 3.0.17',
|
||||
'Upgrade your <strong>APC</strong> extension (3.0.17+).'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
$this->addPhpIniRequirement('detect_unicode', false);
|
||||
|
||||
if (extension_loaded('suhosin')) {
|
||||
$this->addPhpIniRequirement(
|
||||
'suhosin.executor.include.whitelist',
|
||||
create_function('$cfgValue', 'return false !== stripos($cfgValue, "phar");'),
|
||||
false,
|
||||
'suhosin.executor.include.whitelist must be configured correctly in php.ini',
|
||||
'Add "<strong>phar</strong>" to <strong>suhosin.executor.include.whitelist</strong> in php.ini<a href="#phpini">*</a>.'
|
||||
);
|
||||
}
|
||||
|
||||
if (extension_loaded('xdebug')) {
|
||||
$this->addPhpIniRequirement(
|
||||
'xdebug.show_exception_trace', false, true
|
||||
);
|
||||
|
||||
$this->addPhpIniRequirement(
|
||||
'xdebug.scream', false, true
|
||||
);
|
||||
|
||||
$this->addPhpIniRecommendation(
|
||||
'xdebug.max_nesting_level',
|
||||
create_function('$cfgValue', 'return $cfgValue > 100;'),
|
||||
true,
|
||||
'xdebug.max_nesting_level should be above 100 in php.ini',
|
||||
'Set "<strong>xdebug.max_nesting_level</strong>" to e.g. "<strong>250</strong>" in php.ini<a href="#phpini">*</a> to stop Xdebug\'s infinite recursion protection erroneously throwing a fatal error in your project.'
|
||||
);
|
||||
}
|
||||
|
||||
$pcreVersion = defined('PCRE_VERSION') ? (float) PCRE_VERSION : null;
|
||||
|
||||
$this->addRequirement(
|
||||
null !== $pcreVersion,
|
||||
'PCRE extension must be available',
|
||||
'Install the <strong>PCRE</strong> extension (version 8.0+).'
|
||||
);
|
||||
|
||||
$this->addRecommendation(
|
||||
version_compare($installedPhpVersion, '5.3.4', '>='),
|
||||
'You should use at least PHP 5.3.4 due to PHP bug #52083 in earlier versions',
|
||||
'Your project might malfunction randomly due to PHP bug #52083 ("Notice: Trying to get property of non-object"). Install PHP 5.3.4 or newer.'
|
||||
);
|
||||
|
||||
$this->addRecommendation(
|
||||
version_compare($installedPhpVersion, '5.3.8', '>='),
|
||||
'When using annotations you should have at least PHP 5.3.8 due to PHP bug #55156',
|
||||
'Install PHP 5.3.8 or newer if your project uses annotations.'
|
||||
);
|
||||
|
||||
$this->addRecommendation(
|
||||
version_compare($installedPhpVersion, '5.4.0', '!='),
|
||||
'You should not use PHP 5.4.0 due to the PHP bug #61453',
|
||||
'Your project might not work properly due to the PHP bug #61453 ("Cannot dump definitions which have method calls"). Install PHP 5.4.1 or newer.'
|
||||
);
|
||||
|
||||
if (null !== $pcreVersion) {
|
||||
$this->addRecommendation(
|
||||
$pcreVersion >= 8.0,
|
||||
sprintf('PCRE extension should be at least version 8.0 (%s installed)', $pcreVersion),
|
||||
'<strong>PCRE 8.0+</strong> is preconfigured in PHP since 5.3.2 but you are using an outdated version of it. Phraseanet probably works anyway but it is recommended to upgrade your PCRE extension.'
|
||||
);
|
||||
}
|
||||
|
||||
$this->addRequirement(
|
||||
class_exists('DomDocument'),
|
||||
'PHP-XML module should be installed',
|
||||
'Install and enable the <strong>PHP-XML</strong> module.'
|
||||
);
|
||||
|
||||
$this->addRequirement(
|
||||
function_exists('mb_strlen'),
|
||||
'mb_strlen() should be available',
|
||||
'Install and enable the <strong>mbstring</strong> extension.'
|
||||
);
|
||||
|
||||
$this->addRequirement(
|
||||
function_exists('iconv'),
|
||||
'iconv() should be available',
|
||||
'Install and enable the <strong>iconv</strong> extension.'
|
||||
);
|
||||
|
||||
$this->addRequirement(
|
||||
function_exists('exif_read_data'),
|
||||
'exif extension is required',
|
||||
'Install and enable the <strong>exif</strong> extension to enable FTP exports.'
|
||||
);
|
||||
|
||||
$this->addRequirement(
|
||||
function_exists('curl_init'),
|
||||
'curl extension is required',
|
||||
'Install and enable the <strong>curl</strong> extension.'
|
||||
);
|
||||
|
||||
$this->addRequirement(
|
||||
function_exists('gd_info'),
|
||||
'gd extension is required',
|
||||
'Install and enable the <strong>gd</strong> extension.'
|
||||
);
|
||||
|
||||
$this->addRequirement(
|
||||
function_exists('hash_hmac'),
|
||||
'hash extension is required',
|
||||
'Install and enable the <strong>hash</strong> extension.'
|
||||
);
|
||||
|
||||
if ('cli' === php_sapi_name() && !defined('PHP_WINDOWS_VERSION_BUILD')) {
|
||||
$this->addRecommendation(
|
||||
function_exists('pcntl_fork'),
|
||||
'pcntl extension is recommended in unix environments',
|
||||
'Install and enable the <strong>pcntl</strong> extension to enable process fork.'
|
||||
);
|
||||
}
|
||||
|
||||
$this->addRequirement(
|
||||
function_exists('proc_open'),
|
||||
'proc_* functions are required',
|
||||
'Enable the <strong>proc_c*</strong> functions.'
|
||||
);
|
||||
|
||||
if (!defined('PHP_WINDOWS_VERSION_BUILD')) {
|
||||
$this->addRecommendation(
|
||||
function_exists('posix_uname'),
|
||||
'Posix extension is recommended for task manager',
|
||||
'Install and enable the <strong>posix</strong> extension to enable process fork.'
|
||||
);
|
||||
}
|
||||
|
||||
$this->addRequirement(
|
||||
function_exists('socket_connect'),
|
||||
'Socket extension is required for task manager',
|
||||
'Install and enable the <strong>socket</strong> extension.'
|
||||
);
|
||||
|
||||
$this->addRequirement(
|
||||
class_exists('ZipArchive'),
|
||||
'Zip extension is required for download',
|
||||
'Install and enable the <strong>zip</strong> extension.'
|
||||
);
|
||||
|
||||
$this->addRecommendation(
|
||||
extension_loaded('twig'),
|
||||
'Twig extension is strongly recommended in production',
|
||||
'Install and enable the <strong>twig</strong> extension.'
|
||||
);
|
||||
|
||||
$this->addRecommendation(
|
||||
class_exists('Imagick') || class_exists('Gmagick'),
|
||||
'Imagick or Gmagick extension is strongly recommended for image processing',
|
||||
'Install and enable the <strong>gmagick</strong> or <strong>imagick</strong> extension.'
|
||||
);
|
||||
|
||||
$this->addRecommendation(
|
||||
class_exists('Gmagick'),
|
||||
'Gmagick extension is required for video processing (animated thumbnail generation)',
|
||||
'Install and enable the <strong>gmagick</strong> extension.'
|
||||
);
|
||||
|
||||
$this->addRecommendation(
|
||||
function_exists('finfo_open'),
|
||||
'Fileinfo extension is recommended',
|
||||
'Install and enable the <strong>fileinfo</strong> extension to enable file detection.'
|
||||
);
|
||||
|
||||
$this->addRequirement(
|
||||
function_exists('utf8_decode'),
|
||||
'utf8_decode() should be available',
|
||||
'Install and enable the <strong>XML</strong> extension.'
|
||||
);
|
||||
|
||||
|
||||
if (!defined('PHP_WINDOWS_VERSION_BUILD')) {
|
||||
$this->addRecommendation(
|
||||
function_exists('posix_isatty'),
|
||||
'posix_isatty() should be available',
|
||||
'Install and enable the <strong>php_posix</strong> extension (used to colorize the CLI output).'
|
||||
);
|
||||
}
|
||||
|
||||
$this->addRecommendation(
|
||||
function_exists('ftp_fget'),
|
||||
'ftp extension is required for FTP export',
|
||||
'Install and enable the <strong>ftp</strong> extension to enable FTP exports.'
|
||||
);
|
||||
|
||||
$accelerator =
|
||||
(function_exists('apc_store') && ini_get('apc.enabled'))
|
||||
||
|
||||
function_exists('eaccelerator_put') && ini_get('eaccelerator.enable')
|
||||
||
|
||||
function_exists('xcache_set')
|
||||
;
|
||||
|
||||
$this->addRecommendation(
|
||||
$accelerator,
|
||||
'a PHP accelerator should be installed',
|
||||
'Install and enable a <strong>PHP accelerator</strong> like APC (highly recommended).'
|
||||
);
|
||||
|
||||
$this->addPhpIniRecommendation('short_open_tag', false);
|
||||
|
||||
$this->addPhpIniRecommendation('magic_quotes_gpc', false, true);
|
||||
|
||||
$this->addPhpIniRecommendation('register_globals', false, true);
|
||||
|
||||
$this->addPhpIniRecommendation('session.auto_start', false);
|
||||
|
||||
$this->addRequirement(
|
||||
class_exists('PDO'),
|
||||
'PDO should be installed',
|
||||
'Install <strong>PDO</strong> (mandatory for Doctrine).'
|
||||
);
|
||||
|
||||
if (class_exists('PDO')) {
|
||||
$drivers = \PDO::getAvailableDrivers();
|
||||
$this->addRequirement(
|
||||
in_array('mysql', $drivers),
|
||||
sprintf('PDO should have MySQL driver installed (currently available: %s)', count($drivers) ? implode(', ', $drivers) : 'none'),
|
||||
'Install <strong>PDO MySQL driver</strong>.'
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
25
lib/Alchemy/Phrasea/Setup/System/Information.php
Normal file
25
lib/Alchemy/Phrasea/Setup/System/Information.php
Normal file
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
namespace Alchemy\Phrasea\Setup\System;
|
||||
|
||||
class Information implements InformationInterface
|
||||
{
|
||||
private $name;
|
||||
private $value;
|
||||
|
||||
public function __construct($name, $value)
|
||||
{
|
||||
$this->name = $name;
|
||||
$this->value = $value;
|
||||
}
|
||||
|
||||
public function getName()
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
public function getValue()
|
||||
{
|
||||
return $this->value;
|
||||
}
|
||||
}
|
@@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
namespace Alchemy\Phrasea\Setup\System;
|
||||
|
||||
interface InformationInterface
|
||||
{
|
||||
public function getName();
|
||||
public function getValue();
|
||||
}
|
59
lib/Alchemy/Phrasea/Setup/System/PhpIniRequirement.php
Normal file
59
lib/Alchemy/Phrasea/Setup/System/PhpIniRequirement.php
Normal file
@@ -0,0 +1,59 @@
|
||||
<?php
|
||||
|
||||
namespace Alchemy\Phrasea\Setup\System;
|
||||
|
||||
/**
|
||||
* @see https://github.com/sensio/SensioDistributionBundle/blob/master/Resources/skeleton/app/SymfonyRequirements.php
|
||||
*
|
||||
* Represents a PHP requirement in form of a php.ini configuration.
|
||||
*
|
||||
* @author Tobias Schultze <http://tobion.de>
|
||||
*/
|
||||
class PhpIniRequirement extends Requirement
|
||||
{
|
||||
/**
|
||||
* Constructor that initializes the requirement.
|
||||
*
|
||||
* @param string $cfgName The configuration name used for ini_get()
|
||||
* @param Boolean|callback $evaluation Either a Boolean indicating whether the configuration should evaluate to true or false,
|
||||
or a callback function receiving the configuration value as parameter to determine the fulfillment of the requirement
|
||||
* @param Boolean $approveCfgAbsence If true the Requirement will be fulfilled even if the configuration option does not exist, i.e. ini_get() returns false.
|
||||
This is helpful for abandoned configs in later PHP versions or configs of an optional extension, like Suhosin.
|
||||
Example: You require a config to be true but PHP later removes this config and defaults it to true internally.
|
||||
* @param string|null $testMessage The message for testing the requirement (when null and $evaluation is a Boolean a default message is derived)
|
||||
* @param string|null $helpHtml The help text formatted in HTML for resolving the problem (when null and $evaluation is a Boolean a default help is derived)
|
||||
* @param string|null $helpText The help text (when null, it will be inferred from $helpHtml, i.e. stripped from HTML tags)
|
||||
* @param Boolean $optional Whether this is only an optional recommendation not a mandatory requirement
|
||||
*/
|
||||
public function __construct($cfgName, $evaluation, $approveCfgAbsence = false, $testMessage = null, $helpHtml = null, $helpText = null, $optional = false)
|
||||
{
|
||||
$cfgValue = ini_get($cfgName);
|
||||
|
||||
if (is_callable($evaluation)) {
|
||||
if (null === $testMessage || null === $helpHtml) {
|
||||
throw new InvalidArgumentException('You must provide the parameters testMessage and helpHtml for a callback evaluation.');
|
||||
}
|
||||
|
||||
$fulfilled = call_user_func($evaluation, $cfgValue);
|
||||
} else {
|
||||
if (null === $testMessage) {
|
||||
$testMessage = sprintf('%s %s be %s in php.ini',
|
||||
$cfgName,
|
||||
$optional ? 'should' : 'must',
|
||||
$evaluation ? 'enabled' : 'disabled'
|
||||
);
|
||||
}
|
||||
|
||||
if (null === $helpHtml) {
|
||||
$helpHtml = sprintf('Set <strong>%s</strong> to <strong>%s</strong> in php.ini<a href="#phpini">*</a>.',
|
||||
$cfgName,
|
||||
$evaluation ? 'on' : 'off'
|
||||
);
|
||||
}
|
||||
|
||||
$fulfilled = $evaluation == $cfgValue;
|
||||
}
|
||||
|
||||
parent::__construct($fulfilled || ($approveCfgAbsence && false === $cfgValue), $testMessage, $helpHtml, $helpText, $optional);
|
||||
}
|
||||
}
|
@@ -1,16 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Phraseanet
|
||||
*
|
||||
* (c) 2005-2013 Alchemy
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Alchemy\Phrasea\Setup\System;
|
||||
|
||||
interface ProbeInterface
|
||||
{
|
||||
}
|
79
lib/Alchemy/Phrasea/Setup/System/Requirement.php
Normal file
79
lib/Alchemy/Phrasea/Setup/System/Requirement.php
Normal file
@@ -0,0 +1,79 @@
|
||||
<?php
|
||||
|
||||
namespace Alchemy\Phrasea\Setup\System;
|
||||
|
||||
/**
|
||||
* @see https://github.com/sensio/SensioDistributionBundle/blob/master/Resources/skeleton/app/SymfonyRequirements.php
|
||||
*
|
||||
* Represents a single PHP requirement, e.g. an installed extension.
|
||||
* It can be a mandatory requirement or an optional recommendation.
|
||||
* There is a special subclass, named PhpIniRequirement, to check a php.ini configuration.
|
||||
*
|
||||
* @author Tobias Schultze <http://tobion.de>
|
||||
*/
|
||||
class Requirement implements RequirementInterface
|
||||
{
|
||||
private $fulfilled;
|
||||
private $testMessage;
|
||||
private $helpText;
|
||||
private $helpHtml;
|
||||
private $optional;
|
||||
|
||||
/**
|
||||
* Constructor that initializes the requirement.
|
||||
*
|
||||
* @param Boolean $fulfilled Whether the requirement is fulfilled
|
||||
* @param string $testMessage The message for testing the requirement
|
||||
* @param string $helpHtml The help text formatted in HTML for resolving the problem
|
||||
* @param string|null $helpText The help text (when null, it will be inferred from $helpHtml, i.e. stripped from HTML tags)
|
||||
* @param Boolean $optional Whether this is only an optional recommendation not a mandatory requirement
|
||||
*/
|
||||
public function __construct($fulfilled, $testMessage, $helpHtml, $helpText = null, $optional = false)
|
||||
{
|
||||
$this->fulfilled = (Boolean) $fulfilled;
|
||||
$this->testMessage = (string) $testMessage;
|
||||
$this->helpHtml = (string) $helpHtml;
|
||||
$this->helpText = null === $helpText ? strip_tags($this->helpHtml) : (string) $helpText;
|
||||
$this->optional = (Boolean) $optional;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function isFulfilled()
|
||||
{
|
||||
return $this->fulfilled;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getTestMessage()
|
||||
{
|
||||
return $this->testMessage;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getHelpText()
|
||||
{
|
||||
return $this->helpText;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getHelpHtml()
|
||||
{
|
||||
return $this->helpHtml;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function isOptional()
|
||||
{
|
||||
return $this->optional;
|
||||
}
|
||||
}
|
193
lib/Alchemy/Phrasea/Setup/System/RequirementCollection.php
Normal file
193
lib/Alchemy/Phrasea/Setup/System/RequirementCollection.php
Normal file
@@ -0,0 +1,193 @@
|
||||
<?php
|
||||
|
||||
namespace Alchemy\Phrasea\Setup\System;
|
||||
|
||||
/**
|
||||
* @see https://github.com/sensio/SensioDistributionBundle/blob/master/Resources/skeleton/app/SymfonyRequirements.php
|
||||
*
|
||||
* A RequirementCollection represents a set of Requirement instances.
|
||||
*
|
||||
* @author Tobias Schultze <http://tobion.de>
|
||||
*/
|
||||
class RequirementCollection implements RequirementCollectionInterface
|
||||
{
|
||||
private $requirements = array();
|
||||
private $informations = array();
|
||||
private $name;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setName($name)
|
||||
{
|
||||
$this->name = $name;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function addInformation($name, $value)
|
||||
{
|
||||
$this->informations[] = new Information($name, $value);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getInformations()
|
||||
{
|
||||
return $this->informations;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getIterator()
|
||||
{
|
||||
return new \ArrayIterator($this->requirements);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function add(Requirement $requirement)
|
||||
{
|
||||
$this->requirements[] = $requirement;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function addRequirement($fulfilled, $testMessage, $helpHtml, $helpText = null)
|
||||
{
|
||||
$this->add(new Requirement($fulfilled, $testMessage, $helpHtml, $helpText, false));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function addRecommendation($fulfilled, $testMessage, $helpHtml, $helpText = null)
|
||||
{
|
||||
$this->add(new Requirement($fulfilled, $testMessage, $helpHtml, $helpText, true));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function addPhpIniRequirement($cfgName, $evaluation, $approveCfgAbsence = false, $testMessage = null, $helpHtml = null, $helpText = null)
|
||||
{
|
||||
$this->add(new PhpIniRequirement($cfgName, $evaluation, $approveCfgAbsence, $testMessage, $helpHtml, $helpText, false));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function addPhpIniRecommendation($cfgName, $evaluation, $approveCfgAbsence = false, $testMessage = null, $helpHtml = null, $helpText = null)
|
||||
{
|
||||
$this->add(new PhpIniRequirement($cfgName, $evaluation, $approveCfgAbsence, $testMessage, $helpHtml, $helpText, true));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function addCollection(RequirementCollection $collection)
|
||||
{
|
||||
$this->requirements = array_merge($this->requirements, $collection->all());
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function all()
|
||||
{
|
||||
return $this->requirements;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getRequirements()
|
||||
{
|
||||
$array = array();
|
||||
foreach ($this->requirements as $req) {
|
||||
if (!$req->isOptional()) {
|
||||
$array[] = $req;
|
||||
}
|
||||
}
|
||||
|
||||
return $array;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getFailedRequirements()
|
||||
{
|
||||
$array = array();
|
||||
foreach ($this->requirements as $req) {
|
||||
if (!$req->isFulfilled() && !$req->isOptional()) {
|
||||
$array[] = $req;
|
||||
}
|
||||
}
|
||||
|
||||
return $array;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getRecommendations()
|
||||
{
|
||||
$array = array();
|
||||
foreach ($this->requirements as $req) {
|
||||
if ($req->isOptional()) {
|
||||
$array[] = $req;
|
||||
}
|
||||
}
|
||||
|
||||
return $array;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getFailedRecommendations()
|
||||
{
|
||||
$array = array();
|
||||
foreach ($this->requirements as $req) {
|
||||
if (!$req->isFulfilled() && $req->isOptional()) {
|
||||
$array[] = $req;
|
||||
}
|
||||
}
|
||||
|
||||
return $array;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function hasPhpIniConfigIssue()
|
||||
{
|
||||
foreach ($this->requirements as $req) {
|
||||
if (!$req->isFulfilled() && $req instanceof PhpIniRequirement) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getPhpIniConfigPath()
|
||||
{
|
||||
return get_cfg_var('cfg_file_path');
|
||||
}
|
||||
}
|
@@ -0,0 +1,146 @@
|
||||
<?php
|
||||
|
||||
namespace Alchemy\Phrasea\Setup\System;
|
||||
|
||||
/**
|
||||
* @see https://github.com/sensio/SensioDistributionBundle/blob/master/Resources/skeleton/app/SymfonyRequirements.php
|
||||
*
|
||||
* A RequirementCollection represents a set of Requirement instances.
|
||||
*
|
||||
* @author Tobias Schultze <http://tobion.de>
|
||||
*/
|
||||
interface RequirementCollectionInterface extends \IteratorAggregate
|
||||
{
|
||||
/**
|
||||
* Get the name of the requirement collection
|
||||
*
|
||||
* @return String
|
||||
*/
|
||||
public function getName();
|
||||
|
||||
/**
|
||||
* Set a name to the requirement collection
|
||||
*
|
||||
* @param String $name
|
||||
*
|
||||
* @return RequirementCollectionInterface
|
||||
*/
|
||||
public function setName($name);
|
||||
|
||||
public function addInformation($name, $value);
|
||||
|
||||
public function getInformations();
|
||||
|
||||
/**
|
||||
* Adds a Requirement.
|
||||
*
|
||||
* @param Requirement $requirement A Requirement instance
|
||||
*/
|
||||
public function add(Requirement $requirement);
|
||||
|
||||
/**
|
||||
* Adds a mandatory requirement.
|
||||
*
|
||||
* @param Boolean $fulfilled Whether the requirement is fulfilled
|
||||
* @param string $testMessage The message for testing the requirement
|
||||
* @param string $helpHtml The help text formatted in HTML for resolving the problem
|
||||
* @param string|null $helpText The help text (when null, it will be inferred from $helpHtml, i.e. stripped from HTML tags)
|
||||
*/
|
||||
public function addRequirement($fulfilled, $testMessage, $helpHtml, $helpText = null);
|
||||
|
||||
/**
|
||||
* Adds an optional recommendation.
|
||||
*
|
||||
* @param Boolean $fulfilled Whether the recommendation is fulfilled
|
||||
* @param string $testMessage The message for testing the recommendation
|
||||
* @param string $helpHtml The help text formatted in HTML for resolving the problem
|
||||
* @param string|null $helpText The help text (when null, it will be inferred from $helpHtml, i.e. stripped from HTML tags)
|
||||
*/
|
||||
public function addRecommendation($fulfilled, $testMessage, $helpHtml, $helpText = null);
|
||||
|
||||
/**
|
||||
* Adds a mandatory requirement in form of a php.ini configuration.
|
||||
*
|
||||
* @param string $cfgName The configuration name used for ini_get()
|
||||
* @param Boolean|callback $evaluation Either a Boolean indicating whether the configuration should evaluate to true or false,
|
||||
or a callback function receiving the configuration value as parameter to determine the fulfillment of the requirement
|
||||
* @param Boolean $approveCfgAbsence If true the Requirement will be fulfilled even if the configuration option does not exist, i.e. ini_get() returns false.
|
||||
This is helpful for abandoned configs in later PHP versions or configs of an optional extension, like Suhosin.
|
||||
Example: You require a config to be true but PHP later removes this config and defaults it to true internally.
|
||||
* @param string $testMessage The message for testing the requirement (when null and $evaluation is a Boolean a default message is derived)
|
||||
* @param string $helpHtml The help text formatted in HTML for resolving the problem (when null and $evaluation is a Boolean a default help is derived)
|
||||
* @param string|null $helpText The help text (when null, it will be inferred from $helpHtml, i.e. stripped from HTML tags)
|
||||
*/
|
||||
public function addPhpIniRequirement($cfgName, $evaluation, $approveCfgAbsence = false, $testMessage = null, $helpHtml = null, $helpText = null);
|
||||
|
||||
/**
|
||||
* Adds an optional recommendation in form of a php.ini configuration.
|
||||
*
|
||||
* @param string $cfgName The configuration name used for ini_get()
|
||||
* @param Boolean|callback $evaluation Either a Boolean indicating whether the configuration should evaluate to true or false,
|
||||
or a callback function receiving the configuration value as parameter to determine the fulfillment of the requirement
|
||||
* @param Boolean $approveCfgAbsence If true the Requirement will be fulfilled even if the configuration option does not exist, i.e. ini_get() returns false.
|
||||
This is helpful for abandoned configs in later PHP versions or configs of an optional extension, like Suhosin.
|
||||
Example: You require a config to be true but PHP later removes this config and defaults it to true internally.
|
||||
* @param string $testMessage The message for testing the requirement (when null and $evaluation is a Boolean a default message is derived)
|
||||
* @param string $helpHtml The help text formatted in HTML for resolving the problem (when null and $evaluation is a Boolean a default help is derived)
|
||||
* @param string|null $helpText The help text (when null, it will be inferred from $helpHtml, i.e. stripped from HTML tags)
|
||||
*/
|
||||
public function addPhpIniRecommendation($cfgName, $evaluation, $approveCfgAbsence = false, $testMessage = null, $helpHtml = null, $helpText = null);
|
||||
|
||||
/**
|
||||
* Adds a requirement collection to the current set of requirements.
|
||||
*
|
||||
* @param RequirementCollection $collection A RequirementCollection instance
|
||||
*/
|
||||
public function addCollection(RequirementCollection $collection);
|
||||
|
||||
/**
|
||||
* Returns both requirements and recommendations.
|
||||
*
|
||||
* @return array Array of Requirement instances
|
||||
*/
|
||||
public function all();
|
||||
|
||||
/**
|
||||
* Returns all mandatory requirements.
|
||||
*
|
||||
* @return array Array of Requirement instances
|
||||
*/
|
||||
public function getRequirements();
|
||||
|
||||
/**
|
||||
* Returns the mandatory requirements that were not met.
|
||||
*
|
||||
* @return array Array of Requirement instances
|
||||
*/
|
||||
public function getFailedRequirements();
|
||||
|
||||
/**
|
||||
* Returns all optional recommmendations.
|
||||
*
|
||||
* @return array Array of Requirement instances
|
||||
*/
|
||||
public function getRecommendations();
|
||||
|
||||
/**
|
||||
* Returns the recommendations that were not met.
|
||||
*
|
||||
* @return array Array of Requirement instances
|
||||
*/
|
||||
public function getFailedRecommendations();
|
||||
|
||||
/**
|
||||
* Returns whether a php.ini configuration is not correct.
|
||||
*
|
||||
* @return Boolean php.ini configuration problem?
|
||||
*/
|
||||
public function hasPhpIniConfigIssue();
|
||||
|
||||
/**
|
||||
* Returns the PHP configuration file (php.ini) path.
|
||||
*
|
||||
* @return string|false php.ini file path
|
||||
*/
|
||||
public function getPhpIniConfigPath();
|
||||
}
|
50
lib/Alchemy/Phrasea/Setup/System/RequirementInterface.php
Normal file
50
lib/Alchemy/Phrasea/Setup/System/RequirementInterface.php
Normal file
@@ -0,0 +1,50 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Phraseanet
|
||||
*
|
||||
* (c) 2005-2013 Alchemy
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Alchemy\Phrasea\Setup\System;
|
||||
|
||||
interface RequirementInterface
|
||||
{
|
||||
/**
|
||||
* Returns whether the requirement is fulfilled.
|
||||
*
|
||||
* @return Boolean true if fulfilled, otherwise false
|
||||
*/
|
||||
public function isFulfilled();
|
||||
|
||||
/**
|
||||
* Returns the message for testing the requirement.
|
||||
*
|
||||
* @return string The test message
|
||||
*/
|
||||
public function getTestMessage();
|
||||
|
||||
/**
|
||||
* Returns the help text for resolving the problem
|
||||
*
|
||||
* @return string The help text
|
||||
*/
|
||||
public function getHelpText();
|
||||
|
||||
/**
|
||||
* Returns the help text formatted in HTML.
|
||||
*
|
||||
* @return string The HTML help
|
||||
*/
|
||||
public function getHelpHtml();
|
||||
|
||||
/**
|
||||
* Returns whether this is only an optional recommendation and not a mandatory requirement.
|
||||
*
|
||||
* @return Boolean true if optional, false if mandatory
|
||||
*/
|
||||
public function isOptional();
|
||||
}
|
@@ -23,6 +23,9 @@ class Probe31 implements ProbeInterface
|
||||
$this->app = $app;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function isMigrable()
|
||||
{
|
||||
/**
|
||||
@@ -33,6 +36,9 @@ class Probe31 implements ProbeInterface
|
||||
&& is_file(__DIR__ . "/../../../../../../config/_GV.php");
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getMigration()
|
||||
{
|
||||
return new Migration31($this->app);
|
||||
|
@@ -23,6 +23,9 @@ class Probe35 implements ProbeInterface
|
||||
$this->app = $app;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function isMigrable()
|
||||
{
|
||||
/**
|
||||
@@ -33,6 +36,9 @@ class Probe35 implements ProbeInterface
|
||||
&& is_file(__DIR__ . "/../../../../../../config/config.inc");
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getMigration()
|
||||
{
|
||||
return new Migration35($this->app);
|
||||
|
@@ -11,9 +11,17 @@
|
||||
|
||||
namespace Alchemy\Phrasea\Setup\Version\Probe;
|
||||
|
||||
use Alchemy\Phrasea\Setup\Version\Migration\MigrationInterface;
|
||||
|
||||
interface ProbeInterface
|
||||
{
|
||||
/**
|
||||
* @return Boolean
|
||||
*/
|
||||
public function isMigrable();
|
||||
|
||||
/**
|
||||
* @return MigrationInterface
|
||||
*/
|
||||
public function getMigration();
|
||||
}
|
||||
|
@@ -362,7 +362,7 @@ class User_Adapter implements User_Interface, cache_cacheableInterface
|
||||
if (!isset(self::$_instance[$id])) {
|
||||
try {
|
||||
self::$_instance[$id] = $app['phraseanet.appbox']->get_data_from_cache('_user_' . $id);
|
||||
self::$_instance[$id]->set_app($app['phraseanet.appbox']);
|
||||
self::$_instance[$id]->set_app($app);
|
||||
} catch (Exception $e) {
|
||||
self::$_instance[$id] = new self($id, $app);
|
||||
$app['phraseanet.appbox']->set_data_to_cache(self::$_instance[$id], '_user_' . $id);
|
||||
@@ -1727,7 +1727,7 @@ class User_Adapter implements User_Interface, cache_cacheableInterface
|
||||
{
|
||||
$vars = array();
|
||||
foreach ($this as $key => $value) {
|
||||
if (in_array($key, array('ACL', 'appbox')))
|
||||
if (in_array($key, array('ACL', 'app')))
|
||||
continue;
|
||||
$vars[] = $key;
|
||||
}
|
||||
|
@@ -1,109 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Phraseanet
|
||||
*
|
||||
* (c) 2005-2013 Alchemy
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @todo write tests
|
||||
*
|
||||
* @package KonsoleKomander
|
||||
* @license http://opensource.org/licenses/gpl-3.0 GPLv3
|
||||
* @link www.phraseanet.com
|
||||
*/
|
||||
use Alchemy\Phrasea\Command\Command;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
||||
class module_console_systemConfigCheck extends Command
|
||||
{
|
||||
|
||||
public function __construct($name = null)
|
||||
{
|
||||
parent::__construct($name);
|
||||
|
||||
$this->setDescription('Check the configuration');
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
protected function doExecute(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
if ( ! function_exists('_')) {
|
||||
$output->writeln('<error>YOU MUST ENABLE GETTEXT SUPPORT TO USE PHRASEANET</error>');
|
||||
$output->writeln('Canceled');
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
$ok = true;
|
||||
|
||||
if ($this->container['phraseanet.configuration-tester']->isInstalled()) {
|
||||
$registry = $this->container['phraseanet.registry'];
|
||||
|
||||
$output->writeln(_('*** CHECK BINARY CONFIGURATION ***'));
|
||||
$ok = $this->processConstraints(setup::check_binaries($this->container['phraseanet.registry']), $output) && $ok;
|
||||
$output->writeln("");
|
||||
} else {
|
||||
$registry = new Setup_Registry();
|
||||
}
|
||||
|
||||
$output->writeln(_('*** FILESYSTEM CONFIGURATION ***'));
|
||||
$ok = $this->processConstraints(setup::check_writability($registry), $output) && $ok;
|
||||
$output->writeln("");
|
||||
$output->writeln(_('*** CHECK CACHE OPCODE ***'));
|
||||
$ok = $this->processConstraints(setup::check_cache_opcode(), $output) && $ok;
|
||||
$output->writeln("");
|
||||
$output->writeln(_('*** CHECK CACHE SERVER ***'));
|
||||
$ok = $this->processConstraints(setup::check_cache_server(), $output) && $ok;
|
||||
$output->writeln("");
|
||||
$output->writeln(_('*** CHECK PHP CONFIGURATION ***'));
|
||||
$ok = $this->processConstraints(setup::check_php_configuration(), $output) && $ok;
|
||||
$output->writeln("");
|
||||
$output->writeln(_('*** CHECK PHP EXTENSIONS ***'));
|
||||
$ok = $this->processConstraints(setup::check_php_extension(), $output) && $ok;
|
||||
$output->writeln("");
|
||||
$output->writeln(_('*** CHECK PHRASEA ***'));
|
||||
$ok = $this->processConstraints(setup::check_phrasea(), $output) && $ok;
|
||||
$output->writeln("");
|
||||
$output->writeln(_('*** CHECK SYSTEM LOCALES ***'));
|
||||
$ok = $this->processConstraints(setup::check_system_locales($this->container), $output) && $ok;
|
||||
$output->writeln("");
|
||||
|
||||
$output->write('Finished !', true);
|
||||
|
||||
return (int) ! $ok;
|
||||
}
|
||||
|
||||
protected function processConstraints(Setup_ConstraintsIterator $constraints, OutputInterface $output)
|
||||
{
|
||||
$hasError = false;
|
||||
foreach ($constraints as $constraint) {
|
||||
if ( ! $this->processConstraint($constraint, $output)) {
|
||||
$hasError = true;
|
||||
}
|
||||
}
|
||||
|
||||
return ! $hasError;
|
||||
}
|
||||
|
||||
protected function processConstraint(Setup_Constraint $constraint, OutputInterface $output)
|
||||
{
|
||||
$ok = true;
|
||||
if ($constraint->is_ok()) {
|
||||
$output->writeln("\t\t<info>" . $constraint->get_message() . '</info>');
|
||||
} elseif ($constraint->is_blocker()) {
|
||||
$output->writeln("\t!!!\t<error>" . $constraint->get_message() . '</error>');
|
||||
$ok = false;
|
||||
} else {
|
||||
$output->writeln("\t/!\\\t<comment>" . $constraint->get_message() . '</comment>');
|
||||
}
|
||||
|
||||
return $ok;
|
||||
}
|
||||
}
|
@@ -1,11 +1,44 @@
|
||||
{% macro board_sub_section(sub_section_title, constraints_type) %}
|
||||
<h2>{{ sub_section_title }}</h2>
|
||||
{% macro board_sub_section(requirements) %}
|
||||
<h2>{{ requirements.getName() }}</h2>
|
||||
<ul class="setup">
|
||||
{% for constraint in constraints_type %}
|
||||
<li class="{% if not constraint.is_ok() %}{% if constraint.is_blocker() %}blocker{% else %}non-blocker{% endif %}{% else %}good-enough{% endif %}">
|
||||
{{ constraint.get_message() }}
|
||||
</li>
|
||||
{% endfor %}
|
||||
{% if requirements.getRequirements() is not empty %}
|
||||
<li><strong>{% trans 'Requirements' %}</strong></li>
|
||||
{% for requirement in requirements.getRequirements() %}
|
||||
|
||||
<li class="{% if not requirement.isFulfilled() %}{% if not requirement.isOptional() %}blocker{% else %}non-blocker{% endif %}{% else %}good-enough{% endif %}">
|
||||
{{ requirement.getTestMessage }}
|
||||
|
||||
<p>
|
||||
{% if not requirement.isFulfilled() %}
|
||||
{{ requirement.getHelpHtml() | raw }}
|
||||
{% endif %}
|
||||
</p>
|
||||
</li>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% if requirements.getRecommendations() is not empty %}
|
||||
<li><strong>{% trans 'Recommendations' %}</strong></li>
|
||||
{% for requirement in requirements.getRecommendations() %}
|
||||
|
||||
<li class="{% if not requirement.isFulfilled() %}{% if not requirement.isOptional() %}blocker{% else %}non-blocker{% endif %}{% else %}good-enough{% endif %}">
|
||||
{{ requirement.getTestMessage }}
|
||||
|
||||
<p>
|
||||
{% if not requirement.isFulfilled() %}
|
||||
{{ requirement.getHelpHtml() | raw }}
|
||||
{% endif %}
|
||||
</p>
|
||||
</li>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% if requirements.getInformations() is not empty %}
|
||||
<li><strong>{% trans 'Informations' %}</strong></li>
|
||||
{% for information in requirements.getInformations() %}
|
||||
<li>
|
||||
{{ information.getName() }} : {{ information.getValue() }}
|
||||
</li>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
</ul>
|
||||
{% endmacro %}
|
||||
|
||||
@@ -90,7 +123,7 @@
|
||||
<div class="board_section">
|
||||
<h1 style="margin-bottom: 0;">{% trans 'setup:: Reglages generaux' %}</h1>
|
||||
<h2 style="margin-top: 0; font-style: italic;">{% trans 'setup::Votre configuration' %}</h2>
|
||||
<div class="section_left">
|
||||
<div class="section">
|
||||
|
||||
<h2>{% trans 'setup::Tests d\'envois d\'emails' %}</h2>
|
||||
<form id="mail_checker" method="post" action="/admin/dashboard/send-mail-test/" target="_self">
|
||||
@@ -101,96 +134,14 @@
|
||||
{% endif %}
|
||||
</form>
|
||||
|
||||
{% for constraint in php_version_constraints %}
|
||||
<h2>{{ constraint.get_name() }}</h2>
|
||||
<ul class="setup">
|
||||
<li class="{% if constraint.is_ok() %}good-enough{% else %}blocker{% endif %}">
|
||||
{{ constraint.get_message() }}
|
||||
</li>
|
||||
</ul>
|
||||
{% endfor %}
|
||||
|
||||
{% set sub_section_title %}
|
||||
{% trans 'setup::Filesystem configuration' %}
|
||||
{% endset %}
|
||||
{{ _self.board_sub_section(sub_section_title, writability_constraints) }}
|
||||
|
||||
{% set sub_section_title %}
|
||||
{% trans 'setup::Executables' %}
|
||||
{% endset %}
|
||||
{{ _self.board_sub_section(sub_section_title, binaries_constraints) }}
|
||||
|
||||
{% set sub_section_title %}
|
||||
{% trans 'setup::PHP extensions' %}
|
||||
{% endset %}
|
||||
{{ _self.board_sub_section(sub_section_title, php_extension_constraints) }}
|
||||
|
||||
{% set sub_section_title %}
|
||||
{% trans 'setup::Serveur de cache' %}
|
||||
{% endset %}
|
||||
{{ _self.board_sub_section(sub_section_title, cache_constraints) }}
|
||||
|
||||
</div>
|
||||
|
||||
<div class="section_right">
|
||||
|
||||
{% set sub_section_title %}
|
||||
{% trans 'Phrasea Module' %}
|
||||
{% endset %}
|
||||
{{ _self.board_sub_section(sub_section_title, phrasea_constraints) }}
|
||||
|
||||
{% set sub_section_title %}
|
||||
{% trans 'setup::Serveur de cache' %}
|
||||
{% endset %}
|
||||
{{ _self.board_sub_section(sub_section_title, cache_opcode_constraints) }}
|
||||
|
||||
<h2>{% trans 'setup:: Serveur Memcached' %}</h2>
|
||||
<ul class="setup">
|
||||
{% if app['cache'].isServer() %}
|
||||
{% set stats = app['cache'].getStats() %}
|
||||
<li>{% trans 'setup::Serveur actif sur %s' %} {{app['phraseanet.registry'].get('GV_cache_server_host')}} : {{app['phraseanet.registry'].get('GV_cache_server_port')}}</li>
|
||||
<table>
|
||||
{% for name, stat in stats%}
|
||||
<tr class="even"><td>{{ name }}</td><td> {{ stat }}</td></tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
{% else %}
|
||||
<li class="non-blocker">{% trans 'setup::Aucun serveur memcached rattache.' %}</li>
|
||||
{% endif %}
|
||||
</ul>
|
||||
{% if app['cache'].isServer() %}
|
||||
<form id="cache_flusher" method="post" action="/admin/dashboard/flush-cache/">
|
||||
<input type="submit" id="flush_button" class="btn btn-warning" value="Flush All Caches" />
|
||||
</form>
|
||||
{% endif %}
|
||||
|
||||
<h2>{% trans 'OPCode cache' %}</h2>
|
||||
<ul class="setup">
|
||||
{% if app['opcode-cache'].getName() == 'array' %}
|
||||
<li class="non-blocker">{% trans 'Array opcode cache is activated, but phrasea strongly recommand the use of APC or Xcache in production' %}</li>
|
||||
{% else %}
|
||||
<li>{{ app['opcode-cache'].getName() }}</li>
|
||||
{% endif %}
|
||||
</ul>
|
||||
|
||||
{% if search_engine_status %}
|
||||
<h2>{% trans 'setup::Etat du moteur de recherche' %}</h2>
|
||||
<ul class="setup">
|
||||
{% for value in search_engine_status %}
|
||||
<li>{{ value[0] }} : {{ value[1] }}</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% else %}
|
||||
<h2>{% trans 'setup::Sphinx confguration' %}</h2>
|
||||
<ul class="setup">
|
||||
<li class="blocker">{% trans 'Search Engine not available' %}</li>
|
||||
</ul>
|
||||
{% endif %}
|
||||
|
||||
{% set sub_section_title %}
|
||||
{% trans 'PHP Configuration' %}
|
||||
{% endset %}
|
||||
{{ _self.board_sub_section(sub_section_title, php_configuration_constraints) }}
|
||||
|
||||
{% for requirements in app['phraseanet.configuration-tester'].getRequirements() %}
|
||||
{{ _self.board_sub_section(requirements) }}
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
|
@@ -212,43 +212,36 @@ div.switch_right.unchecked {
|
||||
.board_section #mail_checker {
|
||||
margin: 0 0 20px 15px;
|
||||
}
|
||||
.board_section div[class^="section_"] {
|
||||
width: 400px;
|
||||
.board_section div[class="section"] {
|
||||
height: auto;
|
||||
}
|
||||
.board_section div[class^="section_"] h2 {
|
||||
.board_section div[class="section"] h2 {
|
||||
line-height: 24px;
|
||||
}
|
||||
.board_section div[class^="section_"] ul.setup {
|
||||
width: 360px;
|
||||
.board_section div[class="section"] ul.setup {
|
||||
border: 1px solid #cccccc;
|
||||
list-style-type: none;
|
||||
}
|
||||
.board_section div[class^="section_"] ul.setup li {
|
||||
.board_section div[class="section"] ul.setup li {
|
||||
padding: 2px 5px 2px 30px;
|
||||
background-image: url(/skins/icons/ok.png);
|
||||
background-repeat: no-repeat;
|
||||
background-position: 5px center;
|
||||
}
|
||||
.board_section div[class^="section_"] ul.setup li.non-blocker {
|
||||
.board_section div[class="section"] ul.setup li.good-enough {
|
||||
background-image: url(/skins/icons/ok.png);
|
||||
}
|
||||
.board_section div[class="section"] ul.setup li.non-blocker {
|
||||
background-image: url(/skins/icons/alert.png);
|
||||
}
|
||||
.board_section div[class^="section_"] ul.setup li.blocker {
|
||||
.board_section div[class="section"] ul.setup li.blocker {
|
||||
background-image: url(/skins/icons/delete.png);
|
||||
}
|
||||
.board_section div[class^="section_"] ul.setup li:hover {
|
||||
.board_section div[class="section"] ul.setup li:hover {
|
||||
background-color: #fffbcd;
|
||||
}
|
||||
.board_section div[class^="section_"] #cache_flusher {
|
||||
.board_section div[class="section"] #cache_flusher {
|
||||
margin: -10px 0 20px 0;
|
||||
}
|
||||
.board_section .section_left {
|
||||
float: left;
|
||||
}
|
||||
.board_section .section_right {
|
||||
margin-left: 430px;
|
||||
padding-top: 1px;
|
||||
}
|
||||
.board_section #flush_button {
|
||||
width: 362px;
|
||||
margin-left: 15px;
|
||||
|
@@ -254,21 +254,21 @@ div.switch_right {
|
||||
ul, #mail_checker {
|
||||
margin: 0 0 20px 15px;
|
||||
}
|
||||
div[class^="section_"] {
|
||||
width: 400px;
|
||||
div[class="section"] {
|
||||
height: auto;
|
||||
h2 {
|
||||
line-height: 24px;
|
||||
}
|
||||
ul.setup {
|
||||
width: 360px;
|
||||
border: 1px solid @grey;
|
||||
list-style-type: none;
|
||||
li {
|
||||
padding: 2px 5px 2px 30px;
|
||||
background-image: url(/skins/icons/ok.png);
|
||||
background-repeat: no-repeat;
|
||||
background-position: 5px center;
|
||||
&.good-enough {
|
||||
background-image: url(/skins/icons/ok.png);
|
||||
}
|
||||
&.non-blocker {
|
||||
background-image: url(/skins/icons/alert.png);
|
||||
}
|
||||
@@ -284,13 +284,6 @@ div.switch_right {
|
||||
margin: -10px 0 20px 0;
|
||||
}
|
||||
}
|
||||
.section_left {
|
||||
float: left;
|
||||
}
|
||||
.section_right {
|
||||
margin-left: 430px;
|
||||
padding-top: 1px;
|
||||
}
|
||||
#flush_button {
|
||||
width: 362px;
|
||||
margin-left: 15px;
|
||||
|
Reference in New Issue
Block a user