Merge pull request #139 from romainneutron/Fixes

Fixes
This commit is contained in:
Romain Neutron
2012-06-21 02:55:09 -07:00
25 changed files with 1412 additions and 997 deletions

View File

@@ -9,13 +9,18 @@
* file that was distributed with this source code. * file that was distributed with this source code.
*/ */
namespace KonsoleKommander;
/** /**
* *
* @package
* @package KonsoleKomander
* @license http://opensource.org/licenses/gpl-3.0 GPLv3 * @license http://opensource.org/licenses/gpl-3.0 GPLv3
* @link www.phraseanet.com * @link www.phraseanet.com
*/ */
use Alchemy\Phrasea\Core\Configuration;
use Alchemy\Phrasea\Core\Version;
use Alchemy\Phrasea\Command\UpgradeDBDatas;
use Alchemy\Phrasea\Command\RescanTechnicalDatas;
use Alchemy\Phrasea\Command\BuildMissingSubdefs;
use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand; use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;
use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputInterface;
@@ -25,9 +30,9 @@ use Symfony\Component\Console\Application;
require_once dirname(__FILE__) . '/../lib/classes/bootstrap.class.php'; require_once dirname(__FILE__) . '/../lib/classes/bootstrap.class.php';
bootstrap::register_autoloads(); \bootstrap::register_autoloads();
$configuration = Alchemy\Phrasea\Core\Configuration::build(); $configuration = Configuration::build();
if ($configuration->isInstalled()) { if ($configuration->isInstalled()) {
require_once dirname(__FILE__) . '/../lib/bootstrap.php'; require_once dirname(__FILE__) . '/../lib/bootstrap.php';
} }
@@ -49,8 +54,7 @@ try {
This program comes with ABSOLUTELY NO WARRANTY. This program comes with ABSOLUTELY NO WARRANTY.
This is free software, and you are welcome to redistribute it This is free software, and you are welcome to redistribute it
under certain conditions; type `about:license' for details.\n\n" under certain conditions; type `about:license' for details.\n\n"
. ' KONSOLE KOMMANDER', \Alchemy\Phrasea\Core\Version::getName() . ' KONSOLE KOMMANDER', Version::getName() . ' ' . Version::getNumber());
. ' ' . \Alchemy\Phrasea\Core\Version::getNumber());
$app->add(new module_console_aboutAuthors('about:authors')); $app->add(new module_console_aboutAuthors('about:authors'));
$app->add(new module_console_aboutLicense('about:license')); $app->add(new module_console_aboutLicense('about:license'));
@@ -58,6 +62,7 @@ try {
$app->add(new module_console_checkExtension('check:extension')); $app->add(new module_console_checkExtension('check:extension'));
$app->add(new module_console_systemUpgrade('system:upgrade')); $app->add(new module_console_systemUpgrade('system:upgrade'));
$app->add(new UpgradeDBDatas('system:upgrade-datas'));
$app->add(new module_console_sphinxGenerateSuggestion('sphinx:generate-suggestions')); $app->add(new module_console_sphinxGenerateSuggestion('sphinx:generate-suggestions'));
@@ -83,8 +88,8 @@ try {
$app->add(new module_console_fieldsRename('fields:rename')); $app->add(new module_console_fieldsRename('fields:rename'));
$app->add(new module_console_fieldsMerge('fields:merge')); $app->add(new module_console_fieldsMerge('fields:merge'));
$app->add(new Alchemy\Phrasea\Command\RescanTechnicalDatas('records:rescan-technical-datas')); $app->add(new RescanTechnicalDatas('records:rescan-technical-datas'));
$app->add(new Alchemy\Phrasea\Command\BuildMissingSubdefs('records:build-missing-subdefs')); $app->add(new BuildMissingSubdefs('records:build-missing-subdefs'));
$result_code = is_int($app->run()) ? : 1; $result_code = is_int($app->run()) ? : 1;
} catch (Exception $e) { } catch (Exception $e) {

View File

@@ -125,23 +125,4 @@ class BuildMissingSubdefs extends Command
return; return;
} }
/**
* Format a duration in seconds to human readable
*
* @param type $seconds the time to format
* @return string
*/
public function getFormattedDuration($seconds)
{
$duration = round($seconds / 60) . ' minutes';
if ($duration > 60) {
$duration = round($duration / 60, 1) . ' hours';
}
if ($duration > 24) {
$duration = round($duration / 24, 1) . ' days';
}
return $duration;
}
} }

View File

@@ -80,4 +80,27 @@ abstract class Command extends SymfoCommand
} }
} }
} }
/**
* Format a duration in seconds to human readable
*
* @param type $seconds the time to format
* @return string
*/
public function getFormattedDuration($seconds)
{
$duration = ceil($seconds) . ' seconds';
if ($duration > 60) {
$duration = round($duration / 60 , 1) . ' minutes';
}
elseif ($duration > 3600) {
$duration = round($duration / (60 * 60) , 1) . ' hours';
}
elseif ($duration > (24 * 60 * 60)) {
$duration = round($duration / (24 * 60 * 60) , 1) . ' days';
}
return $duration;
}
} }

View File

@@ -105,26 +105,6 @@ class RescanTechnicalDatas extends Command
return; return;
} }
/**
* Format a duration in seconds to human readable
*
* @param type $seconds the time to format
* @return string
*/
public function getFormattedDuration($seconds)
{
$duration = round($seconds / (60 * self::AVG_SPEED)) . ' minutes';
if ($duration > 60) {
$duration = round($duration / (60 * self::AVG_SPEED), 1) . ' hours';
}
if ($duration > 24) {
$duration = round($duration / (24 * self::AVG_SPEED), 1) . ' days';
}
return $duration;
}
/** /**
* Return the total quantity of records to process * Return the total quantity of records to process
* *

View File

@@ -0,0 +1,35 @@
<?php
/*
* This file is part of Phraseanet
*
* (c) 2005-2012 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Alchemy\Phrasea\Command\Upgrade;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
/**
* The data upgrader interface
*/
interface DatasUpgraderInterface
{
/**
* Executes the upgrade
*/
public function execute(InputInterface $input, OutputInterface $output);
/**
* Return the duration estimation in seconds
*
* @return integer
*/
public function getTimeEstimation();
}

View File

@@ -0,0 +1,161 @@
<?php
/*
* This file is part of Phraseanet
*
* (c) 2005-2012 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Alchemy\Phrasea\Command\Upgrade;
use Alchemy\Phrasea\Border\File;
use Alchemy\Phrasea\Core;
use Monolog\Logger;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
/**
* Upgrade datas for version 3.1 : read UUIDs
*/
class Step31 implements DatasUpgraderInterface
{
const AVERAGE_PER_SECOND = 1.4;
protected $core;
/**
* @var Monolog\Logger
*/
protected $logger;
/**
* Constructor
*
* @param Core $core
* @param Logger $logger
*/
public function __construct(Core $core, Logger $logger)
{
$this->core = $core;
$this->logger = $logger;
}
/**
* {@inheritdoc}
*/
public function execute(InputInterface $input, OutputInterface $output)
{
$appbox = \appbox::get_instance($this->core);
foreach ($appbox->get_databoxes() as $databox) {
do {
$records = $this->getNullUUIDs($databox);
foreach ($records as $record) {
$this->updateRecordUUID($databox, $record);
}
} while (count($records) > 0);
}
}
/**
* {@inheritdoc}
*/
public function getTimeEstimation()
{
$appbox = \appbox::get_instance($this->core);
$time = 0;
foreach ($appbox->get_databoxes() as $databox) {
$time += $this->getDataboxTimeEstimation($databox);
}
$time = $time / self::AVERAGE_PER_SECOND;
return $time;
}
/**
* Return the number of record which does not have a UUID
*
* @param \databox $databox
*/
protected function getDataboxTimeEstimation(\databox $databox)
{
$sql = 'SELECT r.coll_id, r.type, r.record_id, s.path, s.file, r.xml
FROM record r, subdef s
WHERE ISNULL(uuid)
AND s.record_id = r.record_id AND s.name="document"
AND parent_record_id = 0';
$stmt = $databox->get_connection()->prepare($sql);
$stmt->execute();
$quantity = $stmt->rowCount();
$stmt->closeCursor();
return $quantity;
}
/**
* Return a maximum of 100 recods without UUIDs
*
* @param \databox $databox
* @return array
*/
protected function getNullUUIDs(\databox $databox)
{
$sql = 'SELECT r.coll_id, r.type, r.record_id, s.path, s.file, r.xml
FROM record r, subdef s
WHERE ISNULL(uuid)
AND s.record_id = r.record_id AND s.name="document"
AND parent_record_id = 0 LIMIT 100';
$stmt = $databox->get_connection()->prepare($sql);
$stmt->execute();
$rs = $stmt->fetchAll(\PDO::FETCH_ASSOC);
$stmt->closeCursor();
return $rs;
}
/**
* Update a record with a UUID
*
* @param \databox $databox
* @param array $record
*/
protected function updateRecordUUID(\databox $databox, array $record)
{
$pathfile = \p4string::addEndSlash($record['path']) . $record['file'];
$uuid = \uuid::generate_v4();
try {
$media = $this->core['mediavorus']->guess(new \SplFileInfo($pathfile));
$collection = \collection::get_from_coll_id($databox, (int) $record['coll_id']);
$file = new File($media, $collection);
$uuid = $file->getUUID(true, true);
$sha256 = $file->getSha256();
$this->logger->addInfo(sprintf("Upgrading record %d with uuid %s", $record['record_id'], $uuid));
} catch (\Exception $e) {
$this->logger->addError(sprintf("Uuid upgrade for record %s failed", $record['record_id']));
}
$sql = 'UPDATE record SET uuid = :uuid, sha256 = :sha256 WHERE record_id = :record_id';
$params = array(
':uuid' => $uuid,
'sha256' => $sha256,
':record_id' => $record['record_id'],
);
$stmt = $databox->get_connection()->prepare($sql);
$stmt->execute($params);
$stmt->closeCursor();
}
}

View File

@@ -0,0 +1,315 @@
<?php
/*
* This file is part of Phraseanet
*
* (c) 2005-2012 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Alchemy\Phrasea\Command\Upgrade;
use Alchemy\Phrasea\Core;
use Monolog\Logger;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
/**
* Upgrade datas for version 3.1 : move metadatas from XML to relationnal tables
*/
class Step35 implements DatasUpgraderInterface
{
const AVERAGE_PER_SECOND = 100;
protected $core;
/**
* @var Monolog\Logger
*/
protected $logger;
/**
* Constructor
*
* @param Core $core
* @param Logger $logger
*/
public function __construct(Core $core, Logger $logger)
{
$this->core = $core;
$this->logger = $logger;
}
/**
* {@inheritdoc}
*/
public function execute(InputInterface $input, OutputInterface $output)
{
$appbox = \appbox::get_instance($this->core);
foreach ($appbox->get_databoxes() as $databox) {
foreach ($databox->get_meta_structure()->get_elements() as $databox_field) {
if ($databox_field->is_on_error()) {
throw new \Exception(sprintf("Databox description field %s is on error, please fix it before continue</error>", $databox_field->get_name()));
}
}
$this->ensureMigrateColumn($databox);
$sql = 'TRUNCATE metadatas';
$stmt = $databox->get_connection()->prepare($sql);
$stmt->execute();
$stmt->closeCursor();
do {
$rs = $this->getEmptyOriginalNameRecords($databox);
$databox->get_connection()->beginTransaction();
foreach ($rs as $record) {
$this->setOriginalName($databox, $record);
}
$databox->get_connection()->commit();
} while (count($rs) > 0);
do {
$rs = $this->getRecordsToMigrate($databox);
$databox->get_connection()->beginTransaction();
$sql = 'UPDATE record SET migrate35=1 WHERE record_id = :record_id';
$stmt = $databox->get_connection()->prepare($sql);
foreach ($rs as $row) {
$stmt->execute(array(':record_id' => $row['record_id']));
try {
$record = new \record_adapter($databox->get_sbas_id(), $row['record_id']);
} catch (\Exception $e) {
$this->logger->addError(sprintf("Unable to load record %d on databox %d : %s", $record->get_record_id(), $record->get_sbas_id(), $record->get_sbas_id(), $e->getMessage()));
continue;
}
try {
$this->updateMetadatas($record, $row['xml']);
} catch (Exception $e) {
$this->logger->addError(sprintf("Error while upgrading metadatas for record %d on databox %d : %s", $record->get_record_id(), $record->get_sbas_id(), $e->getMessage()));
}
try {
$record->set_binary_status($row['status']);
} catch (Exception $e) {
$this->logger->addError(sprintf("Error while upgrading status for record %d on databox %d : %s", $record->get_record_id(), $record->get_sbas_id(), $e->getMessage()));
}
unset($record);
}
$stmt->closeCursor();
$databox->get_connection()->commit();
} while (count($rs) > 0);
}
foreach ($appbox->get_databoxes() as $databox) {
$this->ensureDropMigrateColumn($databox);
}
}
/**
* {@inheritdoc}
*/
public function getTimeEstimation()
{
$appbox = \appbox::get_instance($this->core);
$time = 0;
foreach ($appbox->get_databoxes() as $databox) {
$sql = 'select record_id
FROM record';
$stmt = $databox->get_connection()->prepare($sql);
$stmt->execute();
$time += $stmt->rowCount();
$stmt->closeCursor();
}
$time = $time / self::AVERAGE_PER_SECOND;
return $time;
}
/**
* Update the metadatas of a record
*
* @param \record_adapter $record
* @param string $xml
*/
protected function updateMetadatas(\record_adapter $record, $xml)
{
$metas = $record->get_databox()->get_meta_structure();
$datas = $metadatas = array();
if (false !== $sxe = simplexml_load_string($xml)) {
$fields = $sxe->xpath('/record/description');
if ($fields && is_array($fields)) {
foreach ($fields[0] as $fieldname => $value) {
$fieldname = trim($fieldname);
$value = trim($value);
if (null === $databox_field = $metas->get_element_by_name($fieldname)) {
continue;
}
if ($databox_field->is_multi()) {
$new_value = \caption_field::get_multi_values($value, $databox_field->get_separator());
if (isset($datas[$databox_field->get_id()])) {
$value = array_unique(array_merge($datas[$databox_field->get_id()], $new_value));
} else {
$value = $new_value;
}
} else {
$new_value = $value;
if (isset($datas[$databox_field->get_id()])) {
$value = $datas[$databox_field->get_id()] . ' ' . $new_value;
} else {
$value = $new_value;
}
}
$datas[$databox_field->get_id()] = $value;
}
}
}
foreach ($datas as $meta_struct_id => $values) {
if (is_array($values)) {
foreach ($values as $value) {
$metadatas[$meta_struct_id] = array(
'meta_struct_id' => $meta_struct_id
, 'meta_id' => null
, 'value' => $value
);
}
} else {
$metadatas[$meta_struct_id] = array(
'meta_struct_id' => $meta_struct_id
, 'meta_id' => null
, 'value' => $values
);
}
}
$record->set_metadatas($metadatas, true);
}
/**
* Update the original name of a record
*
* @staticvar \PDO_statement $stmt
* @param \databox $databox
* @param array $record
*/
protected function setOriginalName(\databox $databox, array $record)
{
static $stmt;
if ( ! $stmt) {
$sql = 'UPDATE record SET originalname = :originalname WHERE record_id = :record_id';
$stmt = $databox->get_connection()->prepare($sql);
}
$original = '';
if (false !== $sxe = simplexml_load_string($record['xml'])) {
foreach ($sxe->doc->attributes() as $key => $value) {
if (trim($key) != 'originalname') {
continue;
}
$original = basename(trim($value));
break;
}
}
$stmt->execute(array(':originalname' => $original, ':record_id' => $record['record_id']));
}
/**
* Returns an array of 500 records to update
*
* @return array
*/
protected function getRecordsToMigrate(\databox $databox)
{
$sql = 'select record_id, coll_id, xml, BIN(status) as status
FROM record
WHERE migrate35=0
LIMIT 0, 500';
$stmt = $databox->get_connection()->prepare($sql);
$stmt->execute();
$rs = $stmt->fetchAll(\PDO::FETCH_ASSOC);
$stmt->closeCursor();
return $rs;
}
/**
* Returns an array of 500 records without original name
*
* @return array
*/
protected function getEmptyOriginalNameRecords(\databox $databox)
{
$sql = 'SELECT record_id, coll_id, xml, BIN(status) as status
FROM record
WHERE originalname IS NULL
LIMIT 0, 500';
$stmt = $databox->get_connection()->prepare($sql);
$stmt->execute();
$rs = $stmt->fetchAll(\PDO::FETCH_ASSOC);
$stmt->closeCursor();
return $rs;
}
/**
* Removes the migration column
*
* @param \databox $databox
*/
protected function ensureDropMigrateColumn(\databox $databox)
{
$sql = 'ALTER TABLE `record` DROP `migrate35` ';
$stmt = $databox->get_connection()->prepare($sql);
$stmt->execute();
$stmt->closeCursor();
}
/**
* Add a migration column to the table
*
* @param \databox $databox
*/
protected function ensureMigrateColumn(\databox $databox)
{
try {
$sql = 'ALTER TABLE `record`
ADD `migrate35` TINYINT( 1 ) UNSIGNED NOT NULL ,
ADD INDEX ( `migrate35` ) ';
$stmt = $databox->get_connection()->prepare($sql);
$stmt->execute();
$stmt->closeCursor();
} catch (\Exception $e) {
}
}
}

View File

@@ -0,0 +1,146 @@
<?php
/*
* This file is part of Phraseanet
*
* (c) 2005-2012 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Alchemy\Phrasea\Command;
use Alchemy\Phrasea\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
/**
*
* @license http://opensource.org/licenses/gpl-3.0 GPLv3
* @link www.phraseanet.com
*/
class UpgradeDBDatas extends Command
{
protected $upgrades =array();
/**
* Constructor
*/
public function __construct($name = null)
{
parent::__construct($name);
$this
->setDescription("Upgrade Phraseanet datas")
->setHelp(<<<EOF
Upgrade Phraseanet datas from older version
Steps are
- version 3.1 : records UUID
- version 3.5 : metadatas upgrade
EOF
);
$this->addOption('from', 'f', null, 'The version where to start upgrade');
$this->addOption('at-version', null, null, 'The version step to upgrade');
return $this;
}
protected function generateUpgradesFromOption(InputInterface $input)
{
if (false === $input->getOption('from') && false === $input->getOption('at-version')) {
throw new \Exception('You MUST provide a `from` or `at-version` option');
}
if (false !== $input->getOption('from') && false !== $input->getOption('at-version')) {
throw new \Exception('You CAN NOT provide a `from` AND `at-version` option at the same time');
}
$core = \bootstrap::getCore();
$versions = array(
'Upgrade\\Step31' => '3.1',
'Upgrade\\Step35' => '3.5',
);
if (null !== $input->getOption('from')) {
foreach ($versions as $classname => $version) {
if (version_compare($input->getOption('from'), $version) > 0) {
continue;
}
$classname = __NAMESPACE__ . '\\' . $classname;
$this->upgrades[] = new $classname($core, $this->logger);
}
}
}
/**
* {@inheritdoc}
*/
public function requireSetup()
{
return true;
}
public function setUpgrades(array $upgrades)
{
$this->upgrades = array();
foreach ($upgrades as $upgrade) {
$this->addUpgrade($upgrade);
}
}
public function addUpgrade(Upgrade\DatasUpgraderInterface $upgrade)
{
$this->upgrades[] = $upgrade;
}
public function getUpgrades()
{
return $this->upgrades;
}
/**
* {@inheritdoc}
*/
public function execute(InputInterface $input, OutputInterface $output)
{
$this->generateUpgradesFromOption($input);
if ( ! $this->upgrades) {
throw new \Exception('No upgrade available');
}
$time = 0;
foreach ($this->upgrades as $version) {
$time += $version->getTimeEstimation();
}
$question = sprintf("This process is estimated to %s", $this->getFormattedDuration($time));
$dialog = $this->getHelperSet()->get('dialog');
do {
$continue = strtolower($dialog->ask($output, $question. '<question>Continue ? (Y/n)</question>', 'Y'));
} while ( ! in_array($continue, array('y', 'n')));
if (strtolower($continue) !== 'y') {
$output->writeln('Aborting !');
return;
}
foreach ($this->upgrades as $version) {
$version->execute($input, $output);
}
return;
}
}

View File

@@ -75,6 +75,10 @@ class Upgrader implements ControllerProviderInterface
$upgrader = new \Setup_Upgrade($appbox); $upgrader = new \Setup_Upgrade($appbox);
$appbox->forceUpgrade($upgrader); $appbox->forceUpgrade($upgrader);
/**
* @todo Show recomandation instead of redirect
*/
return new \Symfony\Component\HttpFoundation\RedirectResponse('/'); return new \Symfony\Component\HttpFoundation\RedirectResponse('/');
}); });

View File

@@ -31,6 +31,11 @@ class Setup_Upgrade
* @var string * @var string
*/ */
protected $message; protected $message;
/**
*
* @var array
*/
protected $recommendations = array();
/** /**
* *
@@ -119,6 +124,26 @@ class Setup_Upgrade
return $this; return $this;
} }
/**
*
* @param type $recommendation
* @param type $command
*/
public function addRecommendation($recommendation, $command = null)
{
$this->recommendations[] = array($recommendation, $command);
}
/**
* Return an array of recommendations
*
* @return array
*/
public function getRecommendations()
{
return $this->recommendations;
}
/** /**
* *
* @return float * @return float

View File

@@ -274,6 +274,8 @@ class appbox extends base
public function forceUpgrade(Setup_Upgrade &$upgrader) public function forceUpgrade(Setup_Upgrade &$upgrader)
{ {
$from_version = $this->get_version();
$upgrader->add_steps(7 + count($this->get_databoxes())); $upgrader->add_steps(7 + count($this->get_databoxes()));
$registry = $this->get_registry(); $registry = $this->get_registry();
@@ -358,6 +360,17 @@ class appbox extends base
$upgrader->add_steps_complete(1); $upgrader->add_steps_complete(1);
if(version_compare($from_version, '3.1') < 0) {
$upgrader->addRecommendation(_('Your install requires data migration, please execute the following command'), 'bin/upgrader --from=3.1');
} elseif (version_compare($from_version, '3.5') < 0) {
$upgrader->addRecommendation(_('Your install requires data migration, please execute the following command'), 'bin/upgrader --from=3.5');
}
if (version_compare($from_version, '3.7') < 0) {
$upgrader->addRecommendation(_('Your install might need to re-read technical datas'), 'bin/console records:rescan-technical-datas');
$upgrader->addRecommendation(_('Your install might need to re-read technical datas'), 'bin/console records:build-missing-subdefs');
}
return $advices; return $advices;
} }

View File

@@ -114,8 +114,9 @@ class databox extends base
$connection_params = phrasea::sbas_params(); $connection_params = phrasea::sbas_params();
if ( ! isset($connection_params[$sbas_id])) if ( ! isset($connection_params[$sbas_id])) {
throw new Exception_DataboxNotFound (); throw new Exception_DataboxNotFound(sprintf('databox %d not found', $sbas_id));
}
$this->host = $connection_params[$sbas_id]['host']; $this->host = $connection_params[$sbas_id]['host'];
$this->port = $connection_params[$sbas_id]['port']; $this->port = $connection_params[$sbas_id]['port'];

View File

@@ -27,7 +27,7 @@ class module_console_systemUpgrade extends Command
{ {
parent::__construct($name); parent::__construct($name);
$this->setDescription('Upgrade Phraseanet to the lastest version'); $this->setDescription('Upgrade Phraseanet to the latest version');
return $this; return $this;
} }
@@ -39,11 +39,12 @@ class module_console_systemUpgrade extends Command
public function execute(InputInterface $input, OutputInterface $output) public function execute(InputInterface $input, OutputInterface $output)
{ {
$this->checkSetup(); $old_connexion_file = __DIR__ . '/../../../../config/connexion.inc';
$old_config_file = __DIR__ . '/../../../../config/config.inc';
$Core = \bootstrap::getCore(); $Core = \bootstrap::getCore();
if ( ! setup::is_installed()) { if ( ! $Core->getConfiguration()->isInstalled() && file_exists($old_config_file) && file_exists($old_connexion_file)) {
$output->writeln('This version of Phraseanet requires a config/config.yml, config/connexion.yml, config/service.yml'); $output->writeln('This version of Phraseanet requires a config/config.yml, config/connexion.yml, config/service.yml');
$output->writeln('Would you like it to be created based on your settings ?'); $output->writeln('Would you like it to be created based on your settings ?');
@@ -55,8 +56,8 @@ class module_console_systemUpgrade extends Command
if ($continue == 'y') { if ($continue == 'y') {
try { try {
$connexionInc = new \SplFileInfo(__DIR__ . '/../../../../config/connexion.inc', true); $connexionInc = new \SplFileInfo($old_connexion_file, true);
$configInc = new \SplFileInfo(__DIR__ . '/../../../../config/config.inc', true); $configInc = new \SplFileInfo($old_config_file, true);
$Core->getConfiguration()->upgradeFromOldConf($configInc, $connexionInc); $Core->getConfiguration()->upgradeFromOldConf($configInc, $connexionInc);
} catch (\Exception $e) { } catch (\Exception $e) {
@@ -67,6 +68,8 @@ class module_console_systemUpgrade extends Command
} }
} }
$this->checkSetup();
$output->write('Phraseanet is going to be upgraded', true); $output->write('Phraseanet is going to be upgraded', true);
$dialog = $this->getHelperSet()->get('dialog'); $dialog = $this->getHelperSet()->get('dialog');
@@ -86,6 +89,16 @@ class module_console_systemUpgrade extends Command
$upgrader = new Setup_Upgrade($appbox); $upgrader = new Setup_Upgrade($appbox);
$appbox->forceUpgrade($upgrader); $appbox->forceUpgrade($upgrader);
foreach ($upgrader->getRecommendations() as $recommendation) {
list($message, $command) = $recommendation;
$output->writeln(sprintf('<info>%s</info>', $message));
$output->writeln("");
$output->writeln(sprintf("\t\t%s", $command));
$output->writeln("");
$output->writeln("");
}
} catch (\Exception $e) { } catch (\Exception $e) {
$output->writeln(sprintf('<error>An error occured while upgrading : %s </error>', $e->getMessage())); $output->writeln(sprintf('<error>An error occured while upgrading : %s </error>', $e->getMessage()));

View File

@@ -1,91 +0,0 @@
<?php
/*
* This file is part of Phraseanet
*
* (c) 2005-2012 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
/**
*
*
* @license http://opensource.org/licenses/gpl-3.0 GPLv3
* @link www.phraseanet.com
*/
class patch_3102 implements patchInterface
{
/**
*
* @var string
*/
private $release = '3.1.20';
/**
*
* @var Array
*/
private $concern = array(base::APPLICATION_BOX, base::DATA_BOX);
/**
*
* @return string
*/
public function get_release()
{
return $this->release;
}
public function require_all_upgrades()
{
return false;
}
/**
*
* @return Array
*/
public function concern()
{
return $this->concern;
}
public function apply(base &$base)
{
$conn = connection::getPDOConnection();
$sql = 'SELECT task_id FROM task2 WHERE `class` = "task_period_upgradetov31"';
$stmt = $conn->prepare($sql);
$stmt->execute();
$rowcount = $stmt->rowCount();
$stmt->closeCursor();
if ($rowcount == 0) {
$sql = 'INSERT INTO `task2`
(`task_id`, `usr_id_owner`, `pid`, `status`, `crashed`,
`active`, `name`, `last_exec_time`, `class`, `settings`, `completed`)
VALUES
(null, 0, 0, "stopped", 0, 1, "upgrade to v3.1",
"0000-00-00 00:00:00", "task_period_upgradetov31",
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>' .
'<tasksettings></tasksettings>", -1)';
$stmt = $conn->prepare($sql);
$stmt->execute();
$stmt->closeCursor();
}
if ($base->get_base_type() == base::DATA_BOX) {
$sql = 'UPDATE record SET sha256 = ""
WHERE sha256 IS NULL AND parent_record_id = 0';
$stmt = $base->get_connection()->prepare($sql);
$stmt->execute();
$stmt->closeCursor();
}
return true;
}
}

View File

@@ -117,17 +117,6 @@ class patch_320c implements patchInterface
$databox->delete_data_from_cache(databox::CACHE_META_STRUCT); $databox->delete_data_from_cache(databox::CACHE_META_STRUCT);
$conn = connection::getPDOConnection(); $conn = connection::getPDOConnection();
$sql = 'INSERT INTO `task2`
(`task_id`, `usr_id_owner`, `pid`, `status`, `crashed`,
`active`, `name`, `last_exec_time`, `class`, `settings`, `completed`)
VALUES
(null, 0, 0, "stopped", 0, 1, "upgrade to v3.2 for sbas ' . $databox->get_sbas_id() . '",
"0000-00-00 00:00:00", "task_period_upgradetov32",
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>' .
'<tasksettings><sbas_id>' . $databox->get_sbas_id() . '</sbas_id></tasksettings>", -1)';
$stmt = $conn->prepare($sql);
$stmt->execute();
$stmt->closeCursor();
$sql = 'DELETE FROM `task2` WHERE class="readmeta"'; $sql = 'DELETE FROM `task2` WHERE class="readmeta"';
$stmt = $conn->prepare($sql); $stmt = $conn->prepare($sql);

View File

@@ -157,19 +157,8 @@ class patch_370a7 implements patchInterface
private function truncateTable(\Doctrine\ORM\EntityManager $em, $className) private function truncateTable(\Doctrine\ORM\EntityManager $em, $className)
{ {
$cmd = $em->getClassMetadata($className); $query = $em->createQuery(sprintf('DELETE FROM %s', $className));
$connection = $em->getConnection(); $query->execute();
$dbPlatform = $connection->getDatabasePlatform();
$connection->beginTransaction();
try {
$query = $dbPlatform->getTruncateTableSql($cmd->getTableName());
$connection->executeUpdate($query);
$connection->commit();
} catch (\Exception $e) {
$connection->rollback();
// throw e to stop patch execution if one truncate failed
throw $e;
}
} }
} }

View File

@@ -484,6 +484,71 @@ class record_adapter implements record_Interface, cache_cacheableInterface
$this->base_id = $collection->get_base_id(); $this->base_id = $collection->get_base_id();
try {
$sphinx_rt = sphinxrt::get_instance($appbox->get_registry());
$sbas_id = $this->get_sbas_id();
$sbas_params = phrasea::sbas_params();
if (isset($sbas_params[$sbas_id])) {
$params = $sbas_params[$sbas_id];
$sbas_crc = crc32(
str_replace(
array('.', '%')
, '_'
, sprintf('%s_%s_%s_%s', $params['host'], $params['port'], $params['user'], $params['dbname'])
)
);
foreach ($this->get_caption()->get_fields(null, true) as $field) {
if ( ! $field->is_indexable()) {
continue;
}
$databox_field = $field->get_databox_field();
foreach ($field->get_values() as $value) {
$sphinx_rt->delete(array("metadatas" . $sbas_crc, "metadatas" . $sbas_crc . "_stemmed_en", "metadatas" . $sbas_crc . "_stemmed_fr"), "metas_realtime" . $sbas_crc, $value->getId());
$sphinx_rt->replace_in_metas(
"metas_realtime" . $sbas_crc
, $value->getId()
, $databox_field->get_id()
, $this->get_record_id()
, $sbas_id
, phrasea::collFromBas($this->get_base_id())
, ($this->is_grouping() ? '1' : '0')
, $this->get_type()
, $value->getValue()
, ($databox_field->isBusiness() ? '1' : '0')
, $this->get_creation_date()
);
}
}
$all_datas = array();
foreach ($this->get_caption()->get_fields(null, true) as $field) {
if ( ! $field->is_indexable()) {
continue;
}
$all_datas[] = $field->get_serialized_values();
}
$all_datas = implode(' ', $all_datas);
$sphinx_rt->delete(array("documents" . $sbas_crc, "documents" . $sbas_crc . "_stemmed_fr", "documents" . $sbas_crc . "_stemmed_en"), "docs_realtime" . $sbas_crc, $this->get_record_id());
$sphinx_rt->replace_in_documents(
"docs_realtime" . $sbas_crc, $this->get_record_id(), $all_datas, $sbas_id, phrasea::collFromBas($this->get_base_id()), ($this->is_grouping() ? '1' : '0'), $this->get_type(), $this->get_creation_date()
);
}
} catch (Exception $e) {
}
$appbox->get_session()->get_logger($this->get_databox()) $appbox->get_session()->get_logger($this->get_databox())
->log($this, Session_Logger::EVENT_MOVE, $collection->get_coll_id(), ''); ->log($this, Session_Logger::EVENT_MOVE, $collection->get_coll_id(), '');

View File

@@ -530,8 +530,10 @@ abstract class task_abstract
protected function sleep($nsec) protected function sleep($nsec)
{ {
$nsec = (integer) $nsec; $nsec = (integer) $nsec;
if ($nsec < 0) if ($nsec < 0) {
throw new \InvalidArgumentException(sprintf("(%s) is not > 0")); throw new \InvalidArgumentException(sprintf("(%s) is not > 0"));
}
while ($this->running && $nsec -- > 0) { while ($this->running && $nsec -- > 0) {
sleep(1); sleep(1);
} }

File diff suppressed because it is too large Load Diff

View File

@@ -1,172 +0,0 @@
<?php
/*
* This file is part of Phraseanet
*
* (c) 2005-2012 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
/**
*
* @license http://opensource.org/licenses/gpl-3.0 GPLv3
* @link www.phraseanet.com
*/
class task_period_upgradetov31 extends task_abstract
{
// ==========================================================================
// ===== les interfaces de settings (task2.php) pour ce type de tache
// ==========================================================================
// ====================================================================
// getName() : must return the name of this kind of task (utf8), MANDATORY
// ====================================================================
public function getName()
{
return(_("upgrade to v3.1"));
}
public static function interfaceAvailable()
{
return false;
}
public function help()
{
return(utf8_encode("Upgrade some database values"));
}
protected function run2()
{
printf("taskid %s starting." . PHP_EOL, $this->getID());
// task can't be stopped here
$core = \bootstrap::getCore();
$appbox = appbox::get_instance($core);
$conn = $appbox->get_connection();
$running = true;
$todo = $this->how_many_left();
$done = 0;
$appbox = appbox::get_instance(\bootstrap::getCore());
$ret = 'stopped';
$this->setProgress($done, $todo);
while ($running) {
foreach ($appbox->get_databoxes() as $databox) {
$connbas = $databox->get_connection();
$sql = 'SELECT r.coll_id, r.type, r.record_id, s.path, s.file, r.xml
FROM record r, subdef s
WHERE ISNULL(uuid)
AND s.record_id = r.record_id AND s.name="document" LIMIT 100';
$stmt = $connbas->prepare($sql);
$stmt->execute();
$rs = $stmt->fetchAll(PDO::FETCH_ASSOC);
$stmt->closeCursor();
foreach ($rs as $row) {
$pathfile = p4string::addEndSlash($row['path']) . $row['file'];
$uuid = uuid::generate_v4();
try {
$media = $core->guess(new \SplFileInfo($pathfile));
$collection = \collection::get_from_coll_id($databox, $row['coll_id']);
$file = new \Alchemy\Phrasea\Border\File($media, $collection);
$uuid = $file->getUUID(true, true);
} catch (\Exception $e) {
}
$sql = 'UPDATE record SET uuid = :uuid WHERE record_id = :record_id';
$params = array(
':uuid' => $uuid
, ':record_id' => $row['record_id']
);
$stmt = $connbas->prepare($sql);
$stmt->execute($params);
$stmt->closeCursor();
$this->log("mise a jour du record " . $row['record_id'] . " avec uuid " . $uuid);
$done ++;
$this->setProgress($done, $todo);
}
}
$todo = $this->how_many_left() + $done;
if ($done == $todo) {
$sql = 'UPDATE task2 SET status="tostop" WHERE task_id = :task_id';
$stmt = $conn->prepare($sql);
$stmt->execute(array(':task_id' => $this->getID()));
$stmt->closeCursor();
$this->setProgress(0, 0);
$ret = 'todelete';
}
$sql = "SELECT status FROM task2 WHERE status='tostop' AND task_id=" . $this->getID();
$stmt = $conn->prepare($sql);
$stmt->execute(array(':task_id' => $this->getID()));
$row = $stmt->fetch(PDO::FETCH_ASSOC);
$stmt->closeCursor();
if ($row) {
$running = false;
}
$conn->close();
unset($conn);
sleep(1);
$conn = connection::getPDOConnection();
}
printf("taskid %s ending." . PHP_EOL, $this->getID());
sleep(1);
printf("good bye world I was task upgrade to version 3.1" . PHP_EOL);
flush();
return $ret;
}
private function how_many_left()
{
$todo = 0;
$appbox = appbox::get_instance(\bootstrap::getCore());
foreach ($appbox->get_databoxes() as $databox) {
try {
$connbas = $databox->get_connection();
$sql = 'SELECT count(r.record_id) as total FROM record r, subdef s'
. ' WHERE ISNULL(uuid)'
. ' AND s.record_id = r.record_id AND s.name="document"';
$stmt = $connbas->prepare($sql);
$stmt->execute();
$row = $stmt->fetch(PDO::FETCH_ASSOC);
$stmt->closeCursor();
if ($row) {
$todo += (int) $row['total'];
}
} catch (Exception $e) {
}
}
return $todo;
}
}

View File

@@ -1,347 +0,0 @@
<?php
/*
* This file is part of Phraseanet
*
* (c) 2005-2012 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
/**
*
* @license http://opensource.org/licenses/gpl-3.0 GPLv3
* @link www.phraseanet.com
*/
class task_period_upgradetov32 extends task_abstract
{
protected $sbas_id;
// ==========================================================================
// ===== les interfaces de settings (task2.php) pour ce type de tache
// ==========================================================================
// ====================================================================
// getName() : must return the name of this kind of task (utf8), MANDATORY
// ====================================================================
public function getName()
{
return(_("upgrade to v3.2"));
}
public static function interfaceAvailable()
{
return false;
}
// ==========================================================================
// help() : text displayed if --help
// ==========================================================================
public function help()
{
return(utf8_encode("Upgrade some database values"));
}
// ==========================================================================
// run() : the real code executed by each task, MANDATORY
// ==========================================================================
protected function loadSettings(SimpleXMLElement $sx_task_settings)
{
$this->sbas_id = (int) $sx_task_settings->sbas_id;
parent::loadSettings($sx_task_settings);
}
protected function run2()
{
printf("taskid %s starting." . PHP_EOL, $this->getID());
$registry = registry::get_instance();
$registry->set('GV_sphinx', false, \registry::TYPE_BOOLEAN);
if ( ! $this->sbas_id) {
printf("sbas_id '" . $this->sbas_id . "' invalide\n");
$this->return_value = self::RETURNSTATUS_STOPPED;
return;
}
try {
$databox = databox::get_instance($this->sbas_id);
$connbas = connection::getPDOConnection($this->sbas_id);
} catch (Exception $e) {
$this->return_value = self::RETURNSTATUS_STOPPED;
return;
}
foreach ($databox->get_meta_structure()->get_elements() as $struct_el) {
if ($struct_el->is_on_error()) {
printf("Please verify all your databox meta fields before migrating, It seems somes are wrong\n");
$this->return_value = self::STATE_STOPPED;
return self::STATE_STOPPED;
}
}
$this->running = true;
try {
$sql = 'ALTER TABLE `record` ADD `migrated` TINYINT( 1 ) UNSIGNED NOT NULL , ADD INDEX ( `migrated` ) ';
$stmt = $connbas->prepare($sql);
$stmt->execute();
$stmt->closeCursor();
} catch (Exception $e) {
}
$n_done = 0;
while ($this->running) {
try {
$sql = 'SELECT COUNT(record_id) as total FROM record';
$stmt = $connbas->prepare($sql);
$stmt->execute();
$row = $stmt->fetch(PDO::FETCH_ASSOC);
$stmt->closeCursor();
$total = 0;
if ($row) {
$total = $row['total'];
}
$sql = 'SELECT COUNT(record_id) as total FROM record WHERE migrated = 1';
$stmt = $connbas->prepare($sql);
$stmt->execute();
$row = $stmt->fetch(PDO::FETCH_ASSOC);
$stmt->closeCursor();
$done = 0;
if ($row) {
$done = $row['total'];
}
$this->setProgress($done, $total);
$this->running = false;
$sql = 'select record_id, coll_id, xml, BIN(status) as status
FROM record
WHERE originalname IS NULL
LIMIT 0, 500';
$stmt = $connbas->prepare($sql);
$stmt->execute();
$rs = $stmt->fetchAll(PDO::FETCH_ASSOC);
$stmt->closeCursor();
if (count($rs) > 0) {
$this->running = true;
}
$sql = 'UPDATE record SET originalname = :originalname WHERE record_id = :record_id';
$stmt_original = $connbas->prepare($sql);
$connbas->beginTransaction();
foreach ($rs as $row) {
$original = '';
$sxe = simplexml_load_string($row['xml']);
if ($sxe) {
foreach ($sxe->doc->attributes() as $key => $value) {
$key = trim($key);
$value = trim($value);
if ($key != 'originalname') {
continue;
}
$original = basename($value);
break;
}
}
try {
$stmt_original->execute(array(':originalname' => $value, ':record_id' => $row['record_id']));
} catch (Exception $e) {
}
}
$connbas->commit();
$sql = 'select record_id, coll_id, xml, BIN(status) as status
FROM record
WHERE migrated="0" AND record_id NOT IN (select distinct record_id from technical_datas)
LIMIT 0, 500';
$stmt = $connbas->prepare($sql);
$stmt->execute();
$rs = $stmt->fetchAll(PDO::FETCH_ASSOC);
$stmt->closeCursor();
if (count($rs) > 0) {
$this->running = true;
}
$sql = 'REPLACE INTO technical_datas (id, record_id, name, value)
VALUES (null, :record_id, :name, :value)';
$stmt = $connbas->prepare($sql);
$connbas->beginTransaction();
foreach ($rs as $row) {
try {
$record = new record_adapter($this->sbas_id, $row['record_id']);
$document = $record->get_subdef('document');
foreach ($document->readTechnicalDatas() as $name => $value) {
if (is_null($value)) {
continue;
}
$stmt->execute(array(
':record_id' => $record->get_record_id()
, ':name' => $name
, ':value' => $value
));
}
} catch (Exception $e) {
}
}
$connbas->commit();
$stmt->closeCursor();
$sql = 'select record_id, coll_id, xml, BIN(status) as status
FROM record
WHERE migrated=0
LIMIT 0, 500';
$stmt = $connbas->prepare($sql);
$stmt->execute();
$rs = $stmt->fetchAll(PDO::FETCH_ASSOC);
$stmt->closeCursor();
if (count($rs) > 0) {
$this->running = true;
}
$connbas->beginTransaction();
$sql = 'UPDATE record SET migrated=1 WHERE record_id = :record_id';
$stmt = $connbas->prepare($sql);
foreach ($rs as $row) {
try {
$record = new record_adapter($this->sbas_id, $row['record_id']);
$metas = $databox->get_meta_structure();
$metadatas = array();
if (($sxe = simplexml_load_string($row['xml'])) != FALSE) {
$z = $sxe->xpath('/record/description');
if ($z && is_array($z)) {
foreach ($z[0] as $ki => $vi) {
$databox_field = $metas->get_element_by_name((string) $ki);
if ( ! $databox_field) {
continue;
}
$value = (string) $vi;
if (trim($value) === '') {
continue;
}
if ($databox_field->is_multi()) {
$new_value = caption_field::get_multi_values($value, $databox_field->get_separator());
if (isset($metadatas[$databox_field->get_id()])) {
$value = array_unique(array_merge($metadatas[$databox_field->get_id()]['value'], $new_value));
} else {
$value = $new_value;
}
} else {
$new_value = array($value);
if (isset($metadatas[$databox_field->get_id()])) {
$value = array(array_shift($metadatas[$databox_field->get_id()]['value']) . ' ' . array_shift($new_value));
} else {
$value = $new_value;
}
}
$metadatas[$databox_field->get_id()] = array(
'meta_struct_id' => $databox_field->get_id()
, 'meta_id' => null
, 'value' => $value
);
}
}
}
$record->set_metadatas($metadatas, true);
unset($record);
} catch (Exception $e) {
}
try {
$record = new record_adapter($this->sbas_id, $row['record_id']);
$record->set_binary_status($row['status']);
unset($record);
} catch (Exception $e) {
}
$stmt->execute(array(':record_id' => $row['record_id']));
}
$stmt->closeCursor();
unset($stmt);
$connbas->commit();
$n_done += 500;
$memory = memory_get_usage() >> 20;
if ($n_done >= 5000) {
$this->return_value = task_abstract::RETURNSTATUS_TORESTART;
return;
}
if ($memory > 100) {
$this->return_value = task_abstract::RETURNSTATUS_TORESTART;
return;
}
} catch (Exception $e) {
}
usleep(500000);
}
$sql = 'ALTER TABLE `record` DROP `migrated`';
$stmt = $connbas->prepare($sql);
$stmt->execute();
$stmt->closeCursor();
$sql = "DELETE from technical_datas WHERE name='DONE'";
$stmt = $connbas->prepare($sql);
$stmt->execute();
$stmt->closeCursor();
$conn = connection::getPDOConnection();
printf("taskid %s ending." . PHP_EOL, $this->getID());
sleep(1);
printf("good bye world I was task upgrade to version 3.2" . PHP_EOL);
$sql = 'UPDATE task2 SET status="tostop" WHERE task_id = :task_id';
$stmt = $conn->prepare($sql);
$stmt->execute(array(':task_id' => $this->getID()));
$stmt->closeCursor();
$this->setProgress(0, 0);
$this->return_value = self::RETURNSTATUS_TODELETE;
flush();
return;
}
}

View File

@@ -1,5 +1,5 @@
{% macro prod(record, user, entry_id)%} {% macro prod(record, user, entry_id)%}
{% if entry_id is none %} {% if not entry_id %}
<a style="float:right;padding:0;margin:0;cursor:pointer;" class="contextMenuTrigger" <a style="float:right;padding:0;margin:0;cursor:pointer;" class="contextMenuTrigger"
id="contextTrigger_{{record.get_base_id}}_{{record.get_record_id}}">&#9660;</a> id="contextTrigger_{{record.get_base_id}}_{{record.get_record_id}}">&#9660;</a>
<table cellspacing="0" cellpadding="0" style="display:none;" <table cellspacing="0" cellpadding="0" style="display:none;"

View File

@@ -0,0 +1,52 @@
<?php
namespace Alchemy\Phrasea\Command;
class CommandTest extends \PHPUnit_Framework_TestCase
{
/**
* @var Command
*/
protected $object;
protected function setUp()
{
$this->object = new AbstractCommandTester('name');
$this->logger = new \Monolog\Logger('test');
}
/**
* @covers Alchemy\Phrasea\Command\Command::setLogger
* @covers Alchemy\Phrasea\Command\Command::getLogger
*/
public function testSetLogger()
{
$this->object->setLogger($this->logger);
$this->assertEquals($this->logger, $this->object->getLogger());
}
/**
* @covers Alchemy\Phrasea\Command\Command::checkSetup
*/
public function testCheckSetup()
{
$this->object->checkSetup();
}
/**
* @covers Alchemy\Phrasea\Command\Command::getFormattedDuration
*/
public function testGetFormattedDuration()
{
$this->assertRegExp('/50 \w+/', $this->object->getFormattedDuration(50));
$this->assertRegExp('/1(\.|,)2 \w+/', $this->object->getFormattedDuration(70));
}
}
class AbstractCommandTester extends Command
{
public function requireSetup()
{
return true;
}
}

View File

@@ -0,0 +1,78 @@
<?php
namespace Alchemy\Phrasea\Command;
class UpgradeDBDatasTest extends \PHPUnit_Framework_TestCase
{
/**
* @var UpgradeDBDatas
*/
protected $object;
/**
* @covers Alchemy\Phrasea\Command\UpgradeDBDatas::__construct
*/
protected function setUp()
{
$this->object = new UpgradeDBDatas('commandname');
}
/**
* @covers Alchemy\Phrasea\Command\UpgradeDBDatas::requireSetup
*/
public function testRequireSetup()
{
$this->assertInternalType('boolean', $this->object->requireSetup());
}
/**
* @covers Alchemy\Phrasea\Command\UpgradeDBDatas::setUpgrades
* @covers Alchemy\Phrasea\Command\UpgradeDBDatas::addUpgrade
* @covers Alchemy\Phrasea\Command\UpgradeDBDatas::getUpgrades
*/
public function testSetUpgrades()
{
$this->object->setUpgrades(array());
$this->assertEquals(array(), $this->object->getUpgrades());
$core = \bootstrap::getCore();
$upgrades = array(
new Upgrade\Step31($core, $core['monolog'])
);
$this->object->setUpgrades($upgrades);
$this->assertEquals($upgrades, $this->object->getUpgrades());
}
/**
* @covers Alchemy\Phrasea\Command\UpgradeDBDatas::addUpgrade
*/
public function testAddUpgrade()
{
$this->assertEquals(array(), $this->object->getUpgrades());
$core = \bootstrap::getCore();
$step31 = new Upgrade\Step31($core, $core['monolog']);
$this->object->addUpgrade($step31);
$this->assertEquals(array($step31), $this->object->getUpgrades());
$step35 = new Upgrade\Step35($core, $core['monolog']);
$this->object->addUpgrade($step35);
$this->assertEquals(array($step31, $step35), $this->object->getUpgrades());
}
/**
* @covers Alchemy\Phrasea\Command\UpgradeDBDatas::execute
* @todo Implement testExecute().
*/
public function testExecute()
{
// Remove the following lines when you implement this test.
$this->markTestIncomplete(
'This test has not been implemented yet.'
);
}
}

View File

@@ -60,13 +60,30 @@ phrasea::headers();
$code .= $advice['sql'] . '<br/>'; $code .= $advice['sql'] . '<br/>';
} }
$recommendations = $upgrader->getRecommendations();
if($code) {
$code = _('Propositions de modifications des tables') $code = _('Propositions de modifications des tables')
. '<blockquote>' . $code . '</blockquote>'; . '<blockquote>' . $code . '</blockquote>';
?> ?>
<pre> <pre>
<?php echo $code; ?> <?php echo $code; ?>
</pre> </pre>
<?php ?> <?php
}
if ($recommendations) {
foreach($recommendations as $recommendation) {
list($message, $command) = $recommendation;
?>
<p><?php echo $message; ?></p>
<pre>
<blockquote><?php echo $command; ?></blockquote>
</pre>
<?php
}
}
?>
<div style="color:black;font-weight:bold;background-color:green;"> <div style="color:black;font-weight:bold;background-color:green;">
<?php echo _('N\'oubliez pas de redemarrer le planificateur de taches'); ?> <?php echo _('N\'oubliez pas de redemarrer le planificateur de taches'); ?>
</div> </div>