PHRAS-374 Add command to rebuild subdefs

This commit is contained in:
Nicolas Le Goff
2015-01-15 13:22:37 +01:00
parent e43036aaf1
commit 10c3869ca3
6 changed files with 222 additions and 47 deletions

View File

@@ -16,6 +16,7 @@ namespace KonsoleKommander;
* @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\Command\BuildSubdefs;
use Alchemy\Phrasea\Command\Plugin\ListPlugin; use Alchemy\Phrasea\Command\Plugin\ListPlugin;
use Alchemy\Phrasea\Command\Setup\H264ConfigurationDumper; use Alchemy\Phrasea\Command\Setup\H264ConfigurationDumper;
use Alchemy\Phrasea\Command\Setup\H264MappingGenerator; use Alchemy\Phrasea\Command\Setup\H264MappingGenerator;
@@ -97,6 +98,7 @@ $cli->command(new CreateCollection('collection:create'));
$cli->command(new RecordAdd('records:add')); $cli->command(new RecordAdd('records:add'));
$cli->command(new RescanTechnicalDatas('records:rescan-technical-datas')); $cli->command(new RescanTechnicalDatas('records:rescan-technical-datas'));
$cli->command(new BuildMissingSubdefs('records:build-missing-subdefs')); $cli->command(new BuildMissingSubdefs('records:build-missing-subdefs'));
$cli->command(new BuildSubdefs('records:build-subdefs'));
$cli->command(new AddPlugin()); $cli->command(new AddPlugin());
$cli->command(new ListPlugin()); $cli->command(new ListPlugin());

View File

@@ -44,9 +44,6 @@ class BuildMissingSubdefs extends Command
$n = 0; $n = 0;
foreach ($this->container['phraseanet.appbox']->get_databoxes() as $databox) { foreach ($this->container['phraseanet.appbox']->get_databoxes() as $databox) {
$subdefStructure = $databox->get_subdef_structure();
$sql = 'SELECT record_id FROM record WHERE parent_record_id = 0'; $sql = 'SELECT record_id FROM record WHERE parent_record_id = 0';
$stmt = $databox->get_connection()->prepare($sql); $stmt = $databox->get_connection()->prepare($sql);
$stmt->execute(); $stmt->execute();
@@ -56,38 +53,14 @@ class BuildMissingSubdefs extends Command
foreach ($rs as $row) { foreach ($rs as $row) {
$record = $databox->get_record($row['record_id']); $record = $databox->get_record($row['record_id']);
try { $wanted_subdefs = $record->get_missing_subdefs();
$record->get_hd_file();
} catch (FileNotFoundException $e) {
continue;
}
$group = $subdefStructure->getSubdefGroup($record->get_type()); if (count($wanted_subdefs) > 0) {
$record->generate_subdefs($databox, $this->container, $wanted_subdefs);
if ($group) { foreach ($wanted_subdefs as $subdef) {
foreach ($group as $subdef) { $this->container['monolog']->addInfo("generate " .$subdef . " for record " . $record->get_record_id());
$n ++;
$todo = false;
if ( ! $record->has_subdef($subdef->get_name())) {
$todo = true;
}
if (in_array($subdef->get_name(), array('preview', 'thumbnail', 'thumbnailgif'))) {
try {
$sub = $record->get_subdef($subdef->get_name());
if ( ! $sub->is_physically_present()) {
$todo = true;
}
} catch (\Exception_Media_SubdefNotFound $e) {
$todo = true;
}
}
if ($todo) {
$record->generate_subdefs($databox, $this->container, array($subdef->get_name()));
$this->container['monolog']->addInfo("generate " . $subdef->get_name() . " for record " . $record->get_record_id());
$n ++;
}
} }
} }

View File

@@ -0,0 +1,171 @@
<?php
/*
* This file is part of Phraseanet
*
* (c) 2005-2014 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Alchemy\Phrasea\Command;
use Doctrine\DBAL\Connection;
use Doctrine\DBAL\SQLParserUtils;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
class BuildSubdefs extends Command
{
/**
* Constructor
*/
public function __construct($name = null)
{
parent::__construct($name);
$this->setDescription('Build subviews for given subview names and record types');
$this->addArgument('databox', InputArgument::REQUIRED, 'The databox id');
$this->addArgument('type', InputArgument::REQUIRED, 'Types of the document to rebuild');
$this->addArgument('subdefs', InputArgument::REQUIRED, 'Names of sub-definition to re-build');
$this->addOption('max_record', 'max', InputOption::VALUE_OPTIONAL, 'Max record id');
$this->addOption('min_record', 'min', InputOption::VALUE_OPTIONAL, 'Min record id');
return $this;
}
/**
* {@inheritdoc}
*/
protected function doExecute(InputInterface $input, OutputInterface $output)
{
$availableTypes = array('document', 'audio', 'video', 'image', 'flash', 'map');
$typesOption = $input->getArgument('type');
$recordsType = explode(',', $typesOption);
$recordsType = array_filter($recordsType, function($type) use($availableTypes) {
return in_array($type, $availableTypes);
});
if (count($recordsType) === 0) {
$output->write(sprintf('Invalid records type provided %s', implode(', ', $availableTypes)));
return;
}
$subdefsOption = $input->getArgument('subdefs');
$subdefsName = explode(',', $subdefsOption);
if (count($subdefsOption) === 0) {
$output->write('No subdef options provided');
return;
}
$sqlCount = "
SELECT COUNT(DISTINCT(r.record_id)) AS nb_records
FROM record r
INNER JOIN subdef s
ON (r.record_id = s.record_id)
WHERE s.name IN (?)
AND r.type IN (?)
";
$types = array(Connection::PARAM_STR_ARRAY, Connection::PARAM_STR_ARRAY);
$params = array($subdefsName, $recordsType);
if (null !== $min = $input->getOption('min_record')) {
$sqlCount .= " AND (r.record_id >= ?)";
$params[] = (int) $min;
$types[] = \PDO::PARAM_INT;
}
if (null !== $max = $input->getOption('max_record')) {
$sqlCount .= " AND (r.record_id <= ?)";
$params[] = (int) $max;
$types[] = \PDO::PARAM_INT;
}
list($sqlCount, $stmtParams) = SQLParserUtils::expandListParameters($sqlCount, $params, $types);
$totalRecords = 0;
foreach ($this->container['phraseanet.appbox']->get_databoxes() as $databox) {
$connection = $databox->get_connection();
$stmt = $connection->prepare($sqlCount);
$stmt->execute($stmtParams);
$row = $stmt->fetch();
$totalRecords += $row['nb_records'];
}
if ($totalRecords === 0) {
return;
}
$progress = $this->getHelperSet()->get('progress');
$progress->start($output, $totalRecords);
$progress->display();
$databox = $this->container['phraseanet.appbox']->get_databox($input->getArgument('databox'));
$sql = "
SELECT DISTINCT(r.record_id)
FROM record r
INNER JOIN subdef s
ON (r.record_id = s.record_id)
WHERE s.name IN (?)
AND r.type IN (?)
";
$types = array(Connection::PARAM_STR_ARRAY, Connection::PARAM_STR_ARRAY);
$params = array($subdefsName, $recordsType);
if ($min) {
$sql .= " AND (r.record_id >= ?)";
$params[] = (int) $min;
$types[] = \PDO::PARAM_INT;
}
if ($max) {
$sql .= " AND (r.record_id <= ?)";
$params[] = (int) $max;
$types[] = \PDO::PARAM_INT;
}
list($sql, $stmtParams) = SQLParserUtils::expandListParameters($sql, $params, $types);
$connection = $databox->get_connection();
$stmt = $connection->prepare($sql);
$stmt->execute($stmtParams);
$rows = $stmt->fetchAll(\PDO::FETCH_ASSOC);
foreach ($rows as $row) {
$output->write(sprintf(' (#%s)', $row['record_id']));
$record = new \record_adapter($this->container, $databox->get_sbas_id(), $row['record_id']);
$subdefs = array_filter($record->get_subdefs(), function($subdef) use ($subdefsName) {
return in_array($subdef->get_name(), $subdefsName);
});
foreach ($subdefs as $subdef) {
$subdef->remove_file();
}
$record->generate_subdefs($databox, $this->container, $subdefsName);
$stmt->closeCursor();
$progress->advance();
}
unset($rows, $record, $stmt, $connection);
$progress->finish();
}
}

View File

@@ -90,10 +90,11 @@ class Tools implements ControllerProviderInterface
$controllers->post('/image/', function (Application $app, Request $request) { $controllers->post('/image/', function (Application $app, Request $request) {
$return = array('success' => true); $return = array('success' => true);
$force = $request->request->get('force_substitution') == '1';
$selection = RecordsRequest::fromRequest($app, $request, false, array('canmodifrecord')); $selection = RecordsRequest::fromRequest($app, $request, false, array('canmodifrecord'));
foreach ($selection as $record) { foreach ($selection as $record) {
$substituted = false; $substituted = false;
foreach ($record->get_subdefs() as $subdef) { foreach ($record->get_subdefs() as $subdef) {
if ($subdef->is_substituted()) { if ($subdef->is_substituted()) {
@@ -102,11 +103,12 @@ class Tools implements ControllerProviderInterface
} }
} }
if (!$substituted || $request->request->get('ForceThumbSubstit') == '1') { if (!$substituted || $force) {
$record->rebuild_subdefs(); $record->rebuild_subdefs();
} }
} }
return $app->json($return); return $app->json($return);
})->bind('prod_tools_image'); })->bind('prod_tools_image');

View File

@@ -1202,7 +1202,7 @@ class record_adapter implements record_Interface, cache_cacheableInterface
* *
* @return record_adapter * @return record_adapter
*/ */
public function rebuild_subdefs() public function rebuild_subdefs()
{ {
$connbas = connection::getPDOConnection($this->app, $this->get_sbas_id()); $connbas = connection::getPDOConnection($this->app, $this->get_sbas_id());
$sql = 'UPDATE record SET jeton=(jeton | ' . JETON_MAKE_SUBDEF . ') WHERE record_id = :record_id'; $sql = 'UPDATE record SET jeton=(jeton | ' . JETON_MAKE_SUBDEF . ') WHERE record_id = :record_id';
@@ -1213,6 +1213,38 @@ class record_adapter implements record_Interface, cache_cacheableInterface
return $this; return $this;
} }
public function get_missing_subdefs()
{
$databox = $this->get_databox();
try {
$this->get_hd_file();
} catch (\Exception $e) {
return array();
}
$subDefDefinitions = $databox->get_subdef_structure()->getSubdefGroup($this->get_type());
if (!$subDefDefinitions) {
return array();
}
$record = $this;
$wanted_subdefs = array_map(function($subDef) {
return $subDef->get_name();
}, array_filter($subDefDefinitions, function($subDef) use ($record) {
return !$record->has_subdef($subDef->get_name());
}));
$missing_subdefs = array_map(function($subDef) {
return $subDef->get_name();
}, array_filter($this->get_subdefs(), function($subdef) {
return !$subdef->is_physically_present();
}));
return array_values(array_merge($wanted_subdefs, $missing_subdefs));
}
/** /**
* *
* @return record_adapter * @return record_adapter

View File

@@ -70,25 +70,20 @@
<legend style='color:#EEE'>&nbsp;<b>{% trans "Reconstruire les sous definitions" %}</b>&nbsp;</legend> <legend style='color:#EEE'>&nbsp;<b>{% trans "Reconstruire les sous definitions" %}</b>&nbsp;</legend>
{% if nbThumbSubstitute > 0 %} {% if nbThumbSubstitute > 0 %}
<div style="color:#A00;"> <div style="color:#A00;">
{% trans "Attention, certain documents ont des sous-definitions substituees"%} {% trans "Attention, certain documents ont des sous-definitions substituees" %}
</div> </div>
<label for="FTS" class="checkbox"> <label for="FTS" class="checkbox">
<input type="checkbox" name="ForceThumbSubstit" value="1" id="FTS" /> <input type="checkbox" name="force_substitution" value="1" id="FTS" />
{% trans "Forcer la reconstruction sur les enregistrements ayant des thumbnails substituees" %} {% trans "Forcer la reconstruction sur les enregistrements ayant des thumbnails substituees" %}
</label> </label>
<br/> <br/>
{% else %} {% else %}
<input type="hidden" name="ForceThumbSubstit" value="1"> <input type="hidden" name="force_substitution" value="1">
{% endif %} {% endif %}
<div> <div>
<select name="rebuild"> <p>
<option selected="selected" value="none"> {{ 'Are you sure you want to rebuild the sub-definitions of selected records?' }}
{% trans "recreer aucune sous-definitions" %} </p>
</option>
<option value="all">
{% trans "recreer toutes les sous-definitions" %}
</option>
</select>
</div> </div>
<input type="hidden" name="ACT" value="SEND" /> <input type="hidden" name="ACT" value="SEND" />
<input type="hidden" name="lst" value="{{records.serializedList()}}" /> <input type="hidden" name="lst" value="{{records.serializedList()}}" />