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
* @link www.phraseanet.com
*/
use Alchemy\Phrasea\Command\BuildSubdefs;
use Alchemy\Phrasea\Command\Plugin\ListPlugin;
use Alchemy\Phrasea\Command\Setup\H264ConfigurationDumper;
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 RescanTechnicalDatas('records:rescan-technical-datas'));
$cli->command(new BuildMissingSubdefs('records:build-missing-subdefs'));
$cli->command(new BuildSubdefs('records:build-subdefs'));
$cli->command(new AddPlugin());
$cli->command(new ListPlugin());

View File

@@ -44,9 +44,6 @@ class BuildMissingSubdefs extends Command
$n = 0;
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';
$stmt = $databox->get_connection()->prepare($sql);
$stmt->execute();
@@ -56,38 +53,14 @@ class BuildMissingSubdefs extends Command
foreach ($rs as $row) {
$record = $databox->get_record($row['record_id']);
try {
$record->get_hd_file();
} catch (FileNotFoundException $e) {
continue;
}
$wanted_subdefs = $record->get_missing_subdefs();
$group = $subdefStructure->getSubdefGroup($record->get_type());
if (count($wanted_subdefs) > 0) {
$record->generate_subdefs($databox, $this->container, $wanted_subdefs);
if ($group) {
foreach ($group as $subdef) {
$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 ++;
}
foreach ($wanted_subdefs as $subdef) {
$this->container['monolog']->addInfo("generate " .$subdef . " 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) {
$return = array('success' => true);
$force = $request->request->get('force_substitution') == '1';
$selection = RecordsRequest::fromRequest($app, $request, false, array('canmodifrecord'));
foreach ($selection as $record) {
$substituted = false;
foreach ($record->get_subdefs() as $subdef) {
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();
}
}
return $app->json($return);
})->bind('prod_tools_image');

View File

@@ -1202,7 +1202,7 @@ class record_adapter implements record_Interface, cache_cacheableInterface
*
* @return record_adapter
*/
public function rebuild_subdefs()
public function rebuild_subdefs()
{
$connbas = connection::getPDOConnection($this->app, $this->get_sbas_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;
}
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

View File

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