diff --git a/.env b/.env index ee9abb8769..a747122777 100644 --- a/.env +++ b/.env @@ -179,6 +179,7 @@ PHRASEANET_WORKER_ftp=1 PHRASEANET_WORKER_mainQueue=3 PHRASEANET_WORKER_populateIndex=1 PHRASEANET_WORKER_pullAssets=1 +PHRASEANET_WORKER_recordMover=1 PHRASEANET_WORKER_subdefCreation=1 PHRASEANET_WORKER_subtitle=1 PHRASEANET_WORKER_validationReminder=1 diff --git a/docker-compose.yml b/docker-compose.yml index 629785e460..da83b3d4d0 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -166,6 +166,7 @@ services: - PHRASEANET_WORKER_pullAssets - PHRASEANET_WORKER_subdefCreation - PHRASEANET_WORKER_subtitle + - PHRASEANET_WORKER_recordMover - PHRASEANET_WORKER_validationReminder - PHRASEANET_WORKER_webhook - PHRASEANET_WORKER_writeMetadatas diff --git a/lib/Alchemy/Phrasea/WorkerManager/Controller/AdminConfigurationController.php b/lib/Alchemy/Phrasea/WorkerManager/Controller/AdminConfigurationController.php index 8c8ba70c26..332fa78761 100644 --- a/lib/Alchemy/Phrasea/WorkerManager/Controller/AdminConfigurationController.php +++ b/lib/Alchemy/Phrasea/WorkerManager/Controller/AdminConfigurationController.php @@ -12,6 +12,7 @@ use Alchemy\Phrasea\WorkerManager\Event\WorkerEvents; use Alchemy\Phrasea\WorkerManager\Form\WorkerConfigurationType; use Alchemy\Phrasea\WorkerManager\Form\WorkerFtpType; use Alchemy\Phrasea\WorkerManager\Form\WorkerPullAssetsType; +use Alchemy\Phrasea\WorkerManager\Form\WorkerRecordMoverType; use Alchemy\Phrasea\WorkerManager\Form\WorkerSearchengineType; use Alchemy\Phrasea\WorkerManager\Form\WorkerValidationReminderType; use Alchemy\Phrasea\WorkerManager\Queue\AMQPConnection; @@ -334,12 +335,71 @@ class AdminConfigurationController extends Controller $running = true; } } + return $this->render('admin/worker-manager/worker_validation_reminder.html.twig', [ 'form' => $form->createView(), 'running' => $running ]); } + public function recordMoverAction(PhraseaApplication $app, Request $request) + { + $config = $this->getConf()->get(['workers', 'record_mover'], []); + $ttl_retry = $this->getConf()->get(['workers','queues', MessagePublisher::RECORD_MOVER_TYPE, 'ttl_retry'], null); + if(!is_null($ttl_retry)) { + $ttl_retry /= 1000; // form is in sec + } + $config['ttl_retry'] = $ttl_retry; + + $form = $app->form(new WorkerRecordMoverType(), $config); + + $form->handleRequest($request); + if ($form->isSubmitted() && $form->isValid()) { + $data = $form->getData(); + switch($data['act']) { + case 'save' : // save the form content (settings) in 2 places + $ttl_retry = $data['ttl_retry']; + unset($data['act'], $data['ttl_retry'], $config['ttl_retry']); + // save most data under workers/record_mover + $app['conf']->set(['workers', 'record_mover'], array_merge($config, $data)); + // save ttl in the q settings + if(!is_null($ttl_retry)) { + $this->getConf()->set(['workers','queues', MessagePublisher::RECORD_MOVER_TYPE, 'ttl_retry'], 1000 * (int)$ttl_retry); + } + $this->getAMQPConnection()->reinitializeQueue([MessagePublisher::RECORD_MOVER_TYPE]); + break; + case 'start': + // reinitialize the validation reminder queues + $this->getAMQPConnection()->setQueue(MessagePublisher::RECORD_MOVER_TYPE); + $this->getAMQPConnection()->reinitializeQueue([MessagePublisher::RECORD_MOVER_TYPE]); + $this->getMessagePublisher()->initializeLoopQueue(MessagePublisher::RECORD_MOVER_TYPE); + break; + case 'stop': + $this->getAMQPConnection()->reinitializeQueue([MessagePublisher::RECORD_MOVER_TYPE]); + break; + } + + return $app->redirectPath('worker_admin', ['_fragment'=>'worker-record-mover']); + } + + // guess if the q is "running" = check if there are pending message on Q or loop-Q + $running = false; + $qStatuses = $this->getAMQPConnection()->getQueuesStatus(); + foreach([ + MessagePublisher::RECORD_MOVER_TYPE, + $this->getAMQPConnection()->getLoopQueueName(MessagePublisher::RECORD_MOVER_TYPE) + ] as $qName) { + if(isset($qStatuses[$qName]) && $qStatuses[$qName]['messageCount'] > 0) { + $running = true; + } + } + + return $this->render('admin/worker-manager/worker_record_mover.html.twig', [ + 'form' => $form->createView(), + 'running' => $running + ]); + } + public function populateStatusAction(PhraseaApplication $app, Request $request) { $databoxIds = $request->get('sbasIds'); diff --git a/lib/Alchemy/Phrasea/WorkerManager/Form/WorkerRecordMoverType.php b/lib/Alchemy/Phrasea/WorkerManager/Form/WorkerRecordMoverType.php new file mode 100644 index 0000000000..872d4a7b57 --- /dev/null +++ b/lib/Alchemy/Phrasea/WorkerManager/Form/WorkerRecordMoverType.php @@ -0,0 +1,39 @@ +add('act', HiddenType::class, [ + 'attr' => [ + 'class' => 'act' + ] + ]) + ->add('ttl_retry', TextType::class, [ + 'label' => 'admin::workermanager:tab:record mover: period in second' + ]) + ->add('xmlSetting', TextareaType::class, [ + 'label' => 'admin::workermanager:tab:record mover: xml view' + ]) + ->add("apply", SubmitType::class, [ + 'label' => "boutton::appliquer", + 'attr' => ['value' => 'save'] + ]) + ; + } + + public function getName() + { + return 'worker_recordMover'; + } +} diff --git a/lib/Alchemy/Phrasea/WorkerManager/Provider/AlchemyWorkerServiceProvider.php b/lib/Alchemy/Phrasea/WorkerManager/Provider/AlchemyWorkerServiceProvider.php index b5dce5775e..11772373c3 100644 --- a/lib/Alchemy/Phrasea/WorkerManager/Provider/AlchemyWorkerServiceProvider.php +++ b/lib/Alchemy/Phrasea/WorkerManager/Provider/AlchemyWorkerServiceProvider.php @@ -18,6 +18,7 @@ use Alchemy\Phrasea\WorkerManager\Worker\PopulateIndexWorker; use Alchemy\Phrasea\WorkerManager\Worker\ProcessPool; use Alchemy\Phrasea\WorkerManager\Worker\PullAssetsWorker; use Alchemy\Phrasea\WorkerManager\Worker\EditRecordWorker; +use Alchemy\Phrasea\WorkerManager\Worker\RecordMoverWorker; use Alchemy\Phrasea\WorkerManager\Worker\Resolver\TypeBasedWorkerResolver; use Alchemy\Phrasea\WorkerManager\Worker\SubdefCreationWorker; use Alchemy\Phrasea\WorkerManager\Worker\SubtitleWorker; @@ -158,6 +159,10 @@ class AlchemyWorkerServiceProvider implements PluginProviderInterface return new ValidationReminderWorker($app); })); + $app['alchemy_worker.type_based_worker_resolver']->addFactory(MessagePublisher::RECORD_MOVER_TYPE, new CallableWorkerFactory(function () use ($app) { + return new RecordMoverWorker($app); + })); + $app['alchemy_worker.type_based_worker_resolver']->addFactory(MessagePublisher::EDIT_RECORD_TYPE, new CallableWorkerFactory(function () use ($app) { return (new EditRecordWorker($app['repo.worker-running-job'], $app['dispatcher'], $app['alchemy_worker.message.publisher'])) ->setApplicationBox($app['phraseanet.appbox']) diff --git a/lib/Alchemy/Phrasea/WorkerManager/Provider/ControllerServiceProvider.php b/lib/Alchemy/Phrasea/WorkerManager/Provider/ControllerServiceProvider.php index 8d51a0368d..290cff39b3 100644 --- a/lib/Alchemy/Phrasea/WorkerManager/Provider/ControllerServiceProvider.php +++ b/lib/Alchemy/Phrasea/WorkerManager/Provider/ControllerServiceProvider.php @@ -104,6 +104,11 @@ class ControllerServiceProvider implements ControllerProviderInterface, ServiceP ->method('GET|POST') ->bind('worker_admin_validationReminder'); + /** @uses AdminConfigurationController::recordMoverAction */ + $controllers->match('/record-mover', 'controller.worker.admin.configuration:recordMoverAction') + ->method('GET|POST') + ->bind('worker_admin_recordMover'); + /** @uses AdminConfigurationController::queueMonitorAction */ $controllers->match('/queue-monitor', 'controller.worker.admin.configuration:queueMonitorAction') ->method('GET') diff --git a/lib/Alchemy/Phrasea/WorkerManager/Queue/AMQPConnection.php b/lib/Alchemy/Phrasea/WorkerManager/Queue/AMQPConnection.php index 8477664493..82cfc44e62 100644 --- a/lib/Alchemy/Phrasea/WorkerManager/Queue/AMQPConnection.php +++ b/lib/Alchemy/Phrasea/WorkerManager/Queue/AMQPConnection.php @@ -98,6 +98,11 @@ class AMQPConnection self::MAX_RETRY => self::DEFAULT_MAX_RETRY_VALUE, self::TTL_RETRY => self::DEFAULT_RETRY_DELAY_VALUE, ], + MessagePublisher::RECORD_MOVER_TYPE => [ + 'with' => self::WITH_LOOP, + self::MAX_RETRY => self::DEFAULT_MAX_RETRY_VALUE, + self::TTL_RETRY => self::DEFAULT_RETRY_DELAY_VALUE + ], MessagePublisher::SUBDEF_CREATION_TYPE => [ 'with' => self::WITH_RETRY | self::WITH_DELAYED, self::MAX_RETRY => self::DEFAULT_MAX_RETRY_VALUE, diff --git a/lib/Alchemy/Phrasea/WorkerManager/Queue/MessagePublisher.php b/lib/Alchemy/Phrasea/WorkerManager/Queue/MessagePublisher.php index 63c6ea8c65..7f4704e331 100644 --- a/lib/Alchemy/Phrasea/WorkerManager/Queue/MessagePublisher.php +++ b/lib/Alchemy/Phrasea/WorkerManager/Queue/MessagePublisher.php @@ -20,6 +20,7 @@ class MessagePublisher const POPULATE_INDEX_TYPE = 'populateIndex'; const PULL_ASSETS_TYPE = 'pullAssets'; const EDIT_RECORD_TYPE = 'editRecord'; + const RECORD_MOVER_TYPE = 'recordMover'; const SUBDEF_CREATION_TYPE = 'subdefCreation'; const VALIDATION_REMINDER_TYPE = 'validationReminder'; const WRITE_METADATAS_TYPE = 'writeMetadatas'; diff --git a/lib/Alchemy/Phrasea/WorkerManager/Worker/RecordMoverWorker.php b/lib/Alchemy/Phrasea/WorkerManager/Worker/RecordMoverWorker.php new file mode 100644 index 0000000000..8f612a7577 --- /dev/null +++ b/lib/Alchemy/Phrasea/WorkerManager/Worker/RecordMoverWorker.php @@ -0,0 +1,523 @@ +app = $app; + $this->conf = $this->app['conf']; + $this->logger = $this->app['alchemy_worker.logger']; + $this->repoWorker = $app['repo.worker-running-job']; + } + + public function process(array $payload) + { + $xmlSettings = $this->conf->get(['workers', 'record_mover', 'xmlSetting'], null); + + if (empty($xmlSettings)) { + $this->logger->error("Can't find the xml setting!"); + + return 0; + } else { + $em = $this->repoWorker->getEntityManager(); + $em->beginTransaction(); + + try { + $workerRunningJob = new WorkerRunningJob(); + $workerRunningJob + ->setWork(MessagePublisher::RECORD_MOVER_TYPE) + ->setPublished(new \DateTime('now')) + ->setStatus(WorkerRunningJob::RUNNING) + ; + + $em->persist($workerRunningJob); + + $em->flush(); + + $em->commit(); + } catch (\Exception $e) { + $em->rollback(); + } + + $settings = simplexml_load_string($xmlSettings); + $logsql = (Boolean) $settings->logsql; + $tasks = array(); + foreach($settings->tasks->task as $task) { + $tasks[] = $task; + } + + try { + $data = $this->getData($this->app, $tasks, $logsql); + + foreach ($data as $record) { + $this->processData($this->app, $record, $logsql); + } + } catch(\Exception $e) { + $this->logger->error('Exception when processing data: ' . $e->getMessage()); + + $workerRunningJob + ->setStatus(WorkerRunningJob::ERROR) + ->setInfo($e->getMessage()) + ->setFinished(new \DateTime('now')) + ; + + $this->repoWorker->reconnect(); + + $em->persist($workerRunningJob); + + $em->flush(); + + return 0; + } + + if ($workerRunningJob != null) { + $workerRunningJob + ->setStatus(WorkerRunningJob::FINISHED) + ->setFinished(new \DateTime('now')) + ; + + $this->repoWorker->reconnect(); + + $em->persist($workerRunningJob); + + $em->flush(); + } + } + + } + + private function getData(Application $app, array $tasks, $logsql) + { + $ret = []; + foreach ($tasks as $sxtask) { + $task = $this->calcSQL($app, $sxtask); + + if (!$task['active'] || !$task['sql']) { + continue; + } + + if ($logsql) { + $this->logger->debug(sprintf("playing task '%s' on base '%s'", $task['name'], $task['basename'] ? $task['basename'] : '')); + } + + try { + /** @var databox $databox */ + $databox = $app->findDataboxById($task['sbas_id']); + } catch (\Exception $e) { + $this->logger->error(sprintf("can't connect sbas %s", $task['sbas_id'])); + continue; + } + + $stmt = $databox->get_connection()->prepare($task['sql']['real']['sql']); + $stmt->execute(); + while (false !== $row = $stmt->fetch(\PDO::FETCH_ASSOC)) { + $tmp = [ + 'sbas_id' => $task['sbas_id'], + 'record_id' => $row['record_id'], + 'action' => $task['action'] + ]; + + $rec = $databox->get_record($row['record_id']); + switch ($task['action']) { + case 'UPDATE': + // change collection ? + if (($x = (int) ($sxtask->to->coll['id'])) > 0) { + $tmp['coll'] = $x; + } + // change sb ? + if (($x = $sxtask->to->status['mask'])) { + $tmp['sb'] = $x; + } + $ret[] = $tmp; + break; + case 'DELETE': + $tmp['deletechildren'] = false; + if ($sxtask['deletechildren'] && $rec->isStory()) { + $tmp['deletechildren'] = true; + } + $ret[] = $tmp; + break; + } + } + $stmt->closeCursor(); + } + + return $ret; + } + + private function processData(Application $app, $row, $logsql) + { + $databox = $app->findDataboxById($row['sbas_id']); + $rec = $databox->get_record($row['record_id']); + + switch ($row['action']) { + case 'UPDATE': + // change collection ? + if (array_key_exists('coll', $row)) { + $coll = \collection::getByCollectionId($app, $databox, $row['coll']); + $rec->move_to_collection($coll); + if ($logsql) { + $this->logger->debug(sprintf("on sbas %s move rid %s to coll %s \n", $row['sbas_id'], $row['record_id'], $coll->get_coll_id())); + } + } + + // change sb ? + if (array_key_exists('sb', $row)) { + $status = str_split($rec->getStatus()); + foreach (str_split(strrev($row['sb'])) as $bit => $val) { + if ($val == '0' || $val == '1') { + $status[31 - $bit] = $val; + } + } + $status = implode('', $status); + $rec->setStatus($status); + if ($logsql) { + $this->logger->debug(sprintf("on sbas %s set rid %s status to %s \n", $row['sbas_id'], $row['record_id'], $status)); + } + } + break; + + case 'DELETE': + if ($row['deletechildren'] && $rec->isStory()) { + /** @var record_adapter $child */ + foreach ($rec->getChildren() as $child) { + $child->delete(); + if ($logsql) { + $this->logger->debug(sprintf("on sbas %s delete (grp child) rid %s \n", $row['sbas_id'], $child->getRecordId())); + } + } + } + $rec->delete(); + if ($logsql) { + $this->logger->debug(sprintf("on sbas %s delete rid %s \n", $row['sbas_id'], $rec->getRecordId())); + } + break; + } + + return $this; + } + + private function calcSQL(Application $app, $sxtask, $playTest = false) + { + $sbas_id = (int) $sxtask['sbas_id']; + + $ret = [ + 'name' => $sxtask['name'] ? (string) $sxtask['name'] : 'sans nom', + 'name_htmlencoded' => \p4string::MakeString(($sxtask['name'] ? $sxtask['name'] : 'sans nom'), 'html'), + 'active' => trim($sxtask['active']) === '1', + 'sbas_id' => $sbas_id, + 'basename' => '', + 'basename_htmlencoded' => '', + 'action' => strtoupper($sxtask['action']), + 'sql' => null, + 'err' => '', + 'err_htmlencoded' => '', + ]; + + try { + /** @var databox $dbox */ + $dbox = $app->findDataboxById($sbas_id); + + $ret['basename'] = $dbox->get_label($app['locale']); + $ret['basename_htmlencoded'] = htmlentities($ret['basename']); + try { + switch ($ret['action']) { + case 'UPDATE': + $ret['sql'] = $this->calcUPDATE($app, $sbas_id, $sxtask, $playTest); + break; + case 'DELETE': + $ret['sql'] = $this->calcDELETE($app, $sbas_id, $sxtask, $playTest); + $ret['deletechildren'] = (int)($sxtask['deletechildren']); + break; + default: + $ret['err'] = "bad action '" . $ret['action'] . "'"; + $ret['err_htmlencoded'] = htmlentities($ret['err']); + break; + } + } catch (\Exception $e) { + $ret['err'] = $e->getMessage(); + $ret['err_htmlencoded'] = htmlentities($e->getMessage()); + } + } catch (\Exception $e) { + $ret['err'] = "bad sbas '" . $sbas_id . "'"; + $ret['err_htmlencoded'] = htmlentities($ret['err']); + } + + return $ret; + } + + private function calcUPDATE(Application $app, $sbas_id, &$sxtask, $playTest) + { + $tws = array(); // NEGATION of updates, used to build the 'test' sql + + // set coll_id ? + if (($x = (int) ($sxtask->to->coll['id'])) > 0) { + $tws[] = 'coll_id!=' . $x; + } + + // set status ? + $x = trim($sxtask->to->status['mask']); + $x = preg_replace('/[^0-1]/', 'x', $x); + + $mx = str_replace(' ', '0', ltrim(str_replace(array('0', 'x'), array(' ', ' '), $x))); + $ma = str_replace(' ', '0', ltrim(str_replace(array('x', '0'), array(' ', '1'), $x))); + if ($mx && $ma) { + $tws[] = '((status ^ 0b' . $mx . ') & 0b' . $ma . ')!=0'; + } + elseif ($mx) { + $tws[] = '(status ^ 0b' . $mx . ')!=0'; + } + elseif ($ma) { + $tws[] = '(status & 0b' . $ma . ')!=0'; + } + + // compute the 'where' clause + list($tw, $join, $err) = $this->calcWhere($app, $sbas_id, $sxtask); + + if(!empty($err)) { + throw(new \Exception($err)); + } + + // ... complete the where to build the TEST + if (count($tws) == 1) { + $tw[] = $tws[0]; + } elseif (count($tws) > 1) { + $tw[] = '(' . implode(') OR (', $tws) . ')'; + } + + // build the TEST sql (select) + $sql_test = 'SELECT record_id FROM record' . $join; + if (count($tw) > 0) { + $sql_test .= ' WHERE ' . ((count($tw) == 1) ? $tw[0] : '(' . implode(') AND (', $tw) . ')'); + } + + // build the real sql (select) + $sql_real = 'SELECT record_id FROM record' . $join; + if (count($tw) > 0) { + $sql_real .= ' WHERE ' . ((count($tw) == 1) ? $tw[0] : '(' . implode(') AND (', $tw) . ')'); + } + + $ret = array( + 'real' => array( + 'sql' => $sql_real, + 'sql_htmlencoded' => htmlentities($sql_real), + ), + 'test' => array( + 'sql' => $sql_test, + 'sql_htmlencoded' => htmlentities($sql_test), + 'result' => null, + 'err' => null + ) + ); + + if ($playTest) { + $ret['test']['result'] = $this->playTest($app, $sbas_id, $sql_test); + } + + return $ret; + } + + private function calcDELETE(Application $app, $sbas_id, &$sxtask, $playTest) + { + // compute the 'where' clause + list($tw, $join, $err) = $this->calcWhere($app, $sbas_id, $sxtask); + + if(!empty($err)) { + throw(new \Exception($err)); + } + + // build the TEST sql (select) + $sql_test = 'SELECT SQL_CALC_FOUND_ROWS record_id FROM record' . $join; + if (count($tw) > 0) + $sql_test .= ' WHERE ' . ((count($tw) == 1) ? $tw[0] : '(' . implode(') AND (', $tw) . ')'); + $sql_test .= ' LIMIT 10'; + + // build the real sql (select) + $sql_real = 'SELECT record_id FROM record' . $join; + if (count($tw) > 0) + $sql_real .= ' WHERE ' . ((count($tw) == 1) ? $tw[0] : '(' . implode(') AND (', $tw) . ')'); + + $ret = [ + 'real' => [ + 'sql' => $sql_real, + 'sql_htmlencoded' => htmlentities($sql_real), + ], + 'test' => [ + 'sql' => $sql_test, + 'sql_htmlencoded' => htmlentities($sql_test), + 'result' => null, + 'err' => null + ] + ]; + + if ($playTest) { + $ret['test']['result'] = $this->playTest($app, $sbas_id, $sql_test); + } + + return $ret; + } + + private function playTest(Application $app, $sbas_id, $sql) + { + /** @var databox $databox */ + $databox = $app->findDataboxById($sbas_id); + $connbas = $databox->get_connection(); + $result = ['rids' => [], 'err' => '', 'n' => null]; + + $result['n'] = $connbas->query('SELECT COUNT(*) AS n FROM (' . $sql . ') AS x')->fetchColumn(); + + $stmt = $connbas->prepare('SELECT record_id FROM (' . $sql . ') AS x LIMIT 10'); + if ($stmt->execute([])) { + while (($row = $stmt->fetch(\PDO::FETCH_ASSOC))) { + $result['rids'][] = $row['record_id']; + } + $stmt->closeCursor(); + } else { + $result['err'] = $connbas->errorInfo(); + } + + return $result; + } + + private function calcWhere(Application $app, $sbas_id, &$sxtask) + { + $err = ""; + /** @var databox $databox */ + $databox = $app->findDataboxById($sbas_id); + /** @var Connection $connbas */ + $connbas = $databox->get_connection(); + + $struct = $databox->get_meta_structure(); + + $tw = array(); + $join = ''; + + $ijoin = 0; + + // criteria + if (($x = $sxtask->from->type['type']) !== null) { + switch (strtoupper($x)) { + case 'RECORD': + $tw[] = 'parent_record_id!=record_id'; + break; + case 'STORY': + $tw[] = 'parent_record_id=record_id'; + break; + } + } + + // criteria + foreach ($sxtask->from->text as $x) { + $field = $struct->get_element_by_name($x['field']); + if($field != null) { + $ijoin++; + $comp = trim($x['compare']); + if (in_array($comp, array('<', '>', '<=', '>=', '=', '!='))) { + $s = 'p' . $ijoin . '.meta_struct_id=' . $connbas->quote($field->get_id()) . ' AND p' . $ijoin . '.value' . $comp + . '' . $connbas->quote($x['value']) . ''; + + $tw[] = $s; + $join .= ' INNER JOIN metadatas AS p' . $ijoin . ' USING(record_id)'; + } else { + // bad comparison operator + $err .= sprintf("bad comparison operator (%s)\n", $comp); + } + } else { + // unknown field ? + $err .= sprintf("unknown field (%s)\n", $x['field']); + } + } + + // criteria + foreach ($sxtask->from->date as $x) { + $field = $struct->get_element_by_name($x['field']); + if($field != null) { + $ijoin++; + $s = 'p' . $ijoin . '.meta_struct_id=' . $connbas->quote($field->get_id()) . ' AND NOW()'; + $dir = strtoupper($x['direction']); + if (in_array($dir, array('BEFORE', 'AFTER'))) { + // prevent malformed dates to act + $tw[] = '!ISNULL(CAST(p' . $ijoin . '.value AS DATETIME))'; + $s .= $dir == 'BEFORE' ? '<' : '>='; + $delta = (int)($x['delta']); + if ($delta > 0) { + $s .= '(p' . $ijoin . '.value+INTERVAL ' . $delta . ' DAY)'; + } elseif ($delta < 0) { + $s .= '(p' . $ijoin . '.value-INTERVAL ' . -$delta . ' DAY)'; + } else { + $s .= 'CAST(p' . $ijoin . '.value AS DATETIME)'; + } + + $tw[] = $s; + $join .= ' INNER JOIN metadatas AS p' . $ijoin . ' USING(record_id)'; + } else { + // bad direction + $err .= sprintf("bad direction (%s)\n", $x['direction']); + } + } + else { + // unknown field ? + $err .= sprintf("unknown field (%s)\n", $x['field']); + } + } + + // criteria + if (($x = $sxtask->from->coll) ) { + $tcoll = explode(',', $x['id']); + foreach ($tcoll as $i => $c) { + $tcoll[$i] = (int)$c; + } + if ($x['compare'] == '=') { + if (count($tcoll) == 1) { + $tw[] = 'coll_id = ' . $tcoll[0]; + } else { + $tw[] = 'coll_id IN(' . implode(',', $tcoll) . ')'; + } + } elseif ($x['compare'] == '!=') { + if (count($tcoll) == 1) { + $tw[] = 'coll_id != ' . $tcoll[0]; + } else { + $tw[] = 'coll_id NOT IN(' . implode(',', $tcoll) . ')'; + } + } else { + // bad operator + $err .= sprintf("bad comparison operator (%s)\n", $x['compare']); + } + } + + // criteria + $x = trim($sxtask->from->status['mask']); + $x = preg_replace('/[^0-1]/', 'x', $x); + + $mx = str_replace(' ', '0', ltrim(str_replace(array('0', 'x'), array(' ', ' '), $x))); + $ma = str_replace(' ', '0', ltrim(str_replace(array('x', '0'), array(' ', '1'), $x))); + if ($mx && $ma) { + $tw[] = '((status ^ 0b'. $mx . ') & 0b'. $ma . ')=0'; + } elseif ($mx) { + $tw[] = '(status ^ 0b' . $mx . ')=0'; + } elseif ($ma) { + $tw[] = '(status & 0b' . $ma . ")=0"; + } + + return array($tw, $join, $err); + } +} diff --git a/resources/locales/messages.de.xlf b/resources/locales/messages.de.xlf index e42cd18ecc..f7f8fbe1d7 100644 --- a/resources/locales/messages.de.xlf +++ b/resources/locales/messages.de.xlf @@ -1,6 +1,6 @@ - +
The source node in most cases contains the sample message as written by the developer. If it looks like a dot-delimitted string such as "form.label.firstname", then the developer has not provided a default message. @@ -587,18 +587,18 @@ Account has been unlocked, you can now login. Konto wurde freigeschaltet, Sie dürfen nun einloggen - Controller/Root/LoginController.php - Controller/Root/LoginController.php + Controller/Root/LoginController.php + Controller/Root/LoginController.php Account has been unlocked, you still have to wait for admin approval. Konto wurde freigeschaltet, Sie müssen auf eine Administrator Genehmigung warten. - Controller/Root/LoginController.php + Controller/Root/LoginController.php Account is already unlocked, you can login. Konto ist schon freigeschaltet, Sie dürfen einloggen - Controller/Root/LoginController.php + Controller/Root/LoginController.php Account is not found. @@ -1045,7 +1045,7 @@ An unexpected error occurred during authentication process, please contact an admin Ein Fehler ist bei Ihre Authentifizierung aufgetreten. Bitte wenden Sie sich an Ihren Systemadministrator - Controller/Root/LoginController.php + Controller/Root/LoginController.php An upload on %bridge_adapter% failed, the resaon is : %reason% @@ -3852,8 +3852,8 @@ Invalid unlock link. ungültiges freigeschaltet Link - Controller/Root/LoginController.php - Controller/Root/LoginController.php + Controller/Root/LoginController.php + Controller/Root/LoginController.php Inverser @@ -5035,7 +5035,7 @@ Phraseanet guest-access is disabled Phraseanet Gast Zugriff ist deaktiviert - Controller/Root/LoginController.php + Controller/Root/LoginController.php Phraseanet may require many binaries. @@ -5097,7 +5097,7 @@ Please fill the captcha Füllen Sie bitte die CAPTCHA aus - Controller/Root/LoginController.php + Controller/Root/LoginController.php Please fix the database before starting @@ -6325,6 +6325,7 @@ Start Start admin/worker-manager/worker_pull_assets.html.twig + admin/worker-manager/worker_record_mover.html.twig admin/worker-manager/worker_validation_reminder.html.twig admin/task-manager/templates.html.twig admin/task-manager/templates.html.twig @@ -6377,6 +6378,7 @@ prod/upload/lazaret.html.twig prod/upload/lazaret.html.twig admin/worker-manager/worker_pull_assets.html.twig + admin/worker-manager/worker_record_mover.html.twig admin/worker-manager/worker_validation_reminder.html.twig admin/task-manager/templates.html.twig admin/task-manager/templates.html.twig @@ -7047,7 +7049,7 @@ Unable to authenticate with %provider_name% Unmöglich, mit %provider_name% zu authentifizieren - Controller/Root/LoginController.php + Controller/Root/LoginController.php Controller/Api/OAuth2Controller.php @@ -7090,7 +7092,7 @@ Unable to retrieve provider identity unmöglich, Provider Identität abzurufen - Controller/Root/LoginController.php + Controller/Root/LoginController.php Controller/Api/OAuth2Controller.php @@ -7561,7 +7563,7 @@ Vous etes maintenant deconnecte. A bientot. Sie sind nun erfolgreich abgemeldet. Bis bald! - Controller/Root/LoginController.php + Controller/Root/LoginController.php Vous n'avez pas assez de droits sur certains elements selectionnes @@ -7998,7 +8000,7 @@ Your identity is not recognized. Ihre Identität wird nicht erkannt - Controller/Root/LoginController.php + Controller/Root/LoginController.php Your install might need to build some sub-definitions @@ -9157,7 +9159,7 @@ admin::workermanager: Rabbit config error Konfigurationsfehler des Nachrichten Managers - admin/worker-manager/index.html.twig + admin/worker-manager/index.html.twig admin::workermanager:tab:Reminder: Interval in second @@ -9277,8 +9279,28 @@ admin::workermanager:tab:queueMonitor: title Warteschlange + admin/worker-manager/index.html.twig + + + admin::workermanager:tab:record mover: description + admin::workermanager:tab:record mover: description + admin/worker-manager/worker_record_mover.html.twig + + + admin::workermanager:tab:record mover: period in second + admin::workermanager:tab:record mover: period in second + WorkerManager/Form/WorkerRecordMoverType.php + + + admin::workermanager:tab:record mover: title + admin::workermanager:tab:record mover: title admin/worker-manager/index.html.twig + + admin::workermanager:tab:record mover: xml view + admin::workermanager:tab:record mover: xml view + WorkerManager/Form/WorkerRecordMoverType.php + admin::workermanager:tab:reminder: title Feedback Erinnerung @@ -9619,7 +9641,7 @@ admin:worker Retrieve configuration error Worker Abruf Konfigurationsfehler - admin/worker-manager/index.html.twig + admin/worker-manager/index.html.twig alert @@ -9780,6 +9802,7 @@ WorkerManager/Form/WorkerValidationReminderType.php WorkerManager/Form/WorkerConfigurationType.php WorkerManager/Form/WorkerPullAssetsType.php + WorkerManager/Form/WorkerRecordMoverType.php web/admin/users.html.twig @@ -10929,18 +10952,18 @@ login::erreur: Erreur d'authentification Anmeldefehler - Controller/Root/LoginController.php + Controller/Root/LoginController.php Controller/Api/OAuth2Controller.php login::erreur: No available connection - Please contact sys-admin Fehler: Keine verfügbare Verbindung - Bitte kontaktieren Sie den Administrator - Controller/Root/LoginController.php + Controller/Root/LoginController.php login::erreur: Vous n'avez pas confirme votre email Zugriff nicht möglich. Sie haben Ihre E-Mail Adresse noch nicht bestätigt - Controller/Root/LoginController.php + Controller/Root/LoginController.php login::notification: Changements enregistres @@ -10950,7 +10973,7 @@ login::notification: Mise a jour du mot de passe avec succes erfolgreiche Passwort Aktualisierung - Controller/Root/LoginController.php + Controller/Root/LoginController.php Controller/Root/AccountController.php @@ -11482,7 +11505,7 @@ phraseanet:: Un email vient de vous etre envoye Wir haben Ihnen ein E-Mail gesendet - Controller/Root/LoginController.php + Controller/Root/LoginController.php phraseanet:: a propos diff --git a/resources/locales/messages.en.xlf b/resources/locales/messages.en.xlf index bc5dccd8b1..5e4b52ad1d 100644 --- a/resources/locales/messages.en.xlf +++ b/resources/locales/messages.en.xlf @@ -1,6 +1,6 @@ - +
The source node in most cases contains the sample message as written by the developer. If it looks like a dot-delimitted string such as "form.label.firstname", then the developer has not provided a default message. @@ -587,18 +587,18 @@ Account has been unlocked, you can now login. Account has been unlocked. You can now login. - Controller/Root/LoginController.php - Controller/Root/LoginController.php + Controller/Root/LoginController.php + Controller/Root/LoginController.php Account has been unlocked, you still have to wait for admin approval. Account has been unlocked. But you still have to wait for an administration approval. - Controller/Root/LoginController.php + Controller/Root/LoginController.php Account is already unlocked, you can login. Account is already unlocked. You can login. - Controller/Root/LoginController.php + Controller/Root/LoginController.php Account is not found. @@ -1046,7 +1046,7 @@ An unexpected error occurred during authentication process, please contact an admin An unexpected error has occured during authentication process. Please contact an admin - Controller/Root/LoginController.php + Controller/Root/LoginController.php An upload on %bridge_adapter% failed, the resaon is : %reason% @@ -3855,8 +3855,8 @@ Invalid unlock link. Invalid unlock link. - Controller/Root/LoginController.php - Controller/Root/LoginController.php + Controller/Root/LoginController.php + Controller/Root/LoginController.php Inverser @@ -5038,7 +5038,7 @@ Phraseanet guest-access is disabled Phraseanet guest-access is disabled. - Controller/Root/LoginController.php + Controller/Root/LoginController.php Phraseanet may require many binaries. @@ -5100,7 +5100,7 @@ Please fill the captcha Please fill the captcha field. - Controller/Root/LoginController.php + Controller/Root/LoginController.php Please fix the database before starting @@ -6328,6 +6328,7 @@ Start Start admin/worker-manager/worker_pull_assets.html.twig + admin/worker-manager/worker_record_mover.html.twig admin/worker-manager/worker_validation_reminder.html.twig admin/task-manager/templates.html.twig admin/task-manager/templates.html.twig @@ -6380,6 +6381,7 @@ prod/upload/lazaret.html.twig prod/upload/lazaret.html.twig admin/worker-manager/worker_pull_assets.html.twig + admin/worker-manager/worker_record_mover.html.twig admin/worker-manager/worker_validation_reminder.html.twig admin/task-manager/templates.html.twig admin/task-manager/templates.html.twig @@ -7050,7 +7052,7 @@ Unable to authenticate with %provider_name% Unable to authenticate with %provider_name% - Controller/Root/LoginController.php + Controller/Root/LoginController.php Controller/Api/OAuth2Controller.php @@ -7093,7 +7095,7 @@ Unable to retrieve provider identity Unable to retrieve provider identity. - Controller/Root/LoginController.php + Controller/Root/LoginController.php Controller/Api/OAuth2Controller.php @@ -7564,7 +7566,7 @@ Vous etes maintenant deconnecte. A bientot. You are now disconnected. See you soon. - Controller/Root/LoginController.php + Controller/Root/LoginController.php Vous n'avez pas assez de droits sur certains elements selectionnes @@ -8001,7 +8003,7 @@ Your identity is not recognized. Your identity is not recognized. - Controller/Root/LoginController.php + Controller/Root/LoginController.php Your install might need to build some sub-definitions @@ -9160,7 +9162,7 @@ admin::workermanager: Rabbit config error Message Queue configuration error - admin/worker-manager/index.html.twig + admin/worker-manager/index.html.twig admin::workermanager:tab:Reminder: Interval in second @@ -9280,8 +9282,28 @@ admin::workermanager:tab:queueMonitor: title Queues + admin/worker-manager/index.html.twig + + + admin::workermanager:tab:record mover: description + admin::workermanager:tab:record mover: description + admin/worker-manager/worker_record_mover.html.twig + + + admin::workermanager:tab:record mover: period in second + admin::workermanager:tab:record mover: period in second + WorkerManager/Form/WorkerRecordMoverType.php + + + admin::workermanager:tab:record mover: title + admin::workermanager:tab:record mover: title admin/worker-manager/index.html.twig + + admin::workermanager:tab:record mover: xml view + admin::workermanager:tab:record mover: xml view + WorkerManager/Form/WorkerRecordMoverType.php + admin::workermanager:tab:reminder: title Feedback Reminder @@ -9622,7 +9644,7 @@ admin:worker Retrieve configuration error Worker Retrieve configuration error - admin/worker-manager/index.html.twig + admin/worker-manager/index.html.twig alert @@ -9783,6 +9805,7 @@ WorkerManager/Form/WorkerValidationReminderType.php WorkerManager/Form/WorkerConfigurationType.php WorkerManager/Form/WorkerPullAssetsType.php + WorkerManager/Form/WorkerRecordMoverType.php web/admin/users.html.twig @@ -10932,18 +10955,18 @@ login::erreur: Erreur d'authentification Authentication error - Controller/Root/LoginController.php + Controller/Root/LoginController.php Controller/Api/OAuth2Controller.php login::erreur: No available connection - Please contact sys-admin No available connection. Please contact system administrator - Controller/Root/LoginController.php + Controller/Root/LoginController.php login::erreur: Vous n'avez pas confirme votre email Access denied, you have not confirmed your e-mail address. - Controller/Root/LoginController.php + Controller/Root/LoginController.php login::notification: Changements enregistres @@ -10953,7 +10976,7 @@ login::notification: Mise a jour du mot de passe avec succes Password update done - Controller/Root/LoginController.php + Controller/Root/LoginController.php Controller/Root/AccountController.php @@ -11485,7 +11508,7 @@ phraseanet:: Un email vient de vous etre envoye An e-mail has been sent. - Controller/Root/LoginController.php + Controller/Root/LoginController.php phraseanet:: a propos diff --git a/resources/locales/messages.fr.xlf b/resources/locales/messages.fr.xlf index dac7a9d71a..674e0ec753 100644 --- a/resources/locales/messages.fr.xlf +++ b/resources/locales/messages.fr.xlf @@ -1,6 +1,6 @@ - +
The source node in most cases contains the sample message as written by the developer. If it looks like a dot-delimitted string such as "form.label.firstname", then the developer has not provided a default message. @@ -587,18 +587,18 @@ Account has been unlocked, you can now login. Le compte a été débloqué. Vous pouvez maintenant vous connecter. - Controller/Root/LoginController.php - Controller/Root/LoginController.php + Controller/Root/LoginController.php + Controller/Root/LoginController.php Account has been unlocked, you still have to wait for admin approval. Le compte a été débloqué. Vous devez toutefois attendre l'approbation d'un administrateur. - Controller/Root/LoginController.php + Controller/Root/LoginController.php Account is already unlocked, you can login. Le compte est déjà déverrouillé. Vous pouvez vous connecter. - Controller/Root/LoginController.php + Controller/Root/LoginController.php Account is not found. @@ -1045,7 +1045,7 @@ An unexpected error occurred during authentication process, please contact an admin Une erreur est survenue lors de l'authentification. Veuillez contacter un Administrateur - Controller/Root/LoginController.php + Controller/Root/LoginController.php An upload on %bridge_adapter% failed, the resaon is : %reason% @@ -3852,8 +3852,8 @@ Invalid unlock link. Lien de déverrouillage non valide. - Controller/Root/LoginController.php - Controller/Root/LoginController.php + Controller/Root/LoginController.php + Controller/Root/LoginController.php Inverser @@ -5035,7 +5035,7 @@ Phraseanet guest-access is disabled L'accès invité de Phraseanet est désactivé. - Controller/Root/LoginController.php + Controller/Root/LoginController.php Phraseanet may require many binaries. @@ -5097,7 +5097,7 @@ Please fill the captcha Veuillez remplir le champ CAPTCHA - Controller/Root/LoginController.php + Controller/Root/LoginController.php Please fix the database before starting @@ -6327,6 +6327,7 @@ Pour les utilisateurs authentifiés, la demande de validation est également dis Start Démarrer admin/worker-manager/worker_pull_assets.html.twig + admin/worker-manager/worker_record_mover.html.twig admin/worker-manager/worker_validation_reminder.html.twig admin/task-manager/templates.html.twig admin/task-manager/templates.html.twig @@ -6379,6 +6380,7 @@ Pour les utilisateurs authentifiés, la demande de validation est également dis prod/upload/lazaret.html.twig prod/upload/lazaret.html.twig admin/worker-manager/worker_pull_assets.html.twig + admin/worker-manager/worker_record_mover.html.twig admin/worker-manager/worker_validation_reminder.html.twig admin/task-manager/templates.html.twig admin/task-manager/templates.html.twig @@ -7049,7 +7051,7 @@ Pour les utilisateurs authentifiés, la demande de validation est également dis Unable to authenticate with %provider_name% Impossible de s'authentifier avec %provider_name% - Controller/Root/LoginController.php + Controller/Root/LoginController.php Controller/Api/OAuth2Controller.php @@ -7092,7 +7094,7 @@ Pour les utilisateurs authentifiés, la demande de validation est également dis Unable to retrieve provider identity Impossible de récupérer l'identité auprès du fournisseur. - Controller/Root/LoginController.php + Controller/Root/LoginController.php Controller/Api/OAuth2Controller.php @@ -7563,7 +7565,7 @@ Pour les utilisateurs authentifiés, la demande de validation est également dis Vous etes maintenant deconnecte. A bientot. Vous êtes maintenant déconnecté. A bientôt. - Controller/Root/LoginController.php + Controller/Root/LoginController.php Vous n'avez pas assez de droits sur certains elements selectionnes @@ -8000,7 +8002,7 @@ Pour les utilisateurs authentifiés, la demande de validation est également dis Your identity is not recognized. Votre identité n'est pas reconnue. - Controller/Root/LoginController.php + Controller/Root/LoginController.php Your install might need to build some sub-definitions @@ -9160,7 +9162,7 @@ Si vous recevez cet e-mail sans l'avoir sollicité, merci de l'ignorer ou de le admin::workermanager: Rabbit config error Erreur dans la configuration du gestionnaire de messages - admin/worker-manager/index.html.twig + admin/worker-manager/index.html.twig admin::workermanager:tab:Reminder: Interval in second @@ -9280,8 +9282,28 @@ Si vous recevez cet e-mail sans l'avoir sollicité, merci de l'ignorer ou de le admin::workermanager:tab:queueMonitor: title Files de message + admin/worker-manager/index.html.twig + + + admin::workermanager:tab:record mover: description + admin::workermanager:tab:record mover: description + admin/worker-manager/worker_record_mover.html.twig + + + admin::workermanager:tab:record mover: period in second + admin::workermanager:tab:record mover: period in second + WorkerManager/Form/WorkerRecordMoverType.php + + + admin::workermanager:tab:record mover: title + admin::workermanager:tab:record mover: title admin/worker-manager/index.html.twig + + admin::workermanager:tab:record mover: xml view + admin::workermanager:tab:record mover: xml view + WorkerManager/Form/WorkerRecordMoverType.php + admin::workermanager:tab:reminder: title Rappel de la validation @@ -9622,7 +9644,7 @@ Si vous recevez cet e-mail sans l'avoir sollicité, merci de l'ignorer ou de le admin:worker Retrieve configuration error Erreur lors de la récupération de la configuration des workers - admin/worker-manager/index.html.twig + admin/worker-manager/index.html.twig alert @@ -9783,6 +9805,7 @@ Si vous recevez cet e-mail sans l'avoir sollicité, merci de l'ignorer ou de le WorkerManager/Form/WorkerValidationReminderType.php WorkerManager/Form/WorkerConfigurationType.php WorkerManager/Form/WorkerPullAssetsType.php + WorkerManager/Form/WorkerRecordMoverType.php web/admin/users.html.twig @@ -10932,18 +10955,18 @@ Si vous recevez cet e-mail sans l'avoir sollicité, merci de l'ignorer ou de le login::erreur: Erreur d'authentification Erreur d'authentification - Controller/Root/LoginController.php + Controller/Root/LoginController.php Controller/Api/OAuth2Controller.php login::erreur: No available connection - Please contact sys-admin Connexion impossible, contactez un administrateur système - Controller/Root/LoginController.php + Controller/Root/LoginController.php login::erreur: Vous n'avez pas confirme votre email Accès impossible, vous n'avez pas confirmé votre adresse e-mail. - Controller/Root/LoginController.php + Controller/Root/LoginController.php login::notification: Changements enregistres @@ -10953,7 +10976,7 @@ Si vous recevez cet e-mail sans l'avoir sollicité, merci de l'ignorer ou de le login::notification: Mise a jour du mot de passe avec succes Mise à jour du mot de passe effectuée - Controller/Root/LoginController.php + Controller/Root/LoginController.php Controller/Root/AccountController.php @@ -11485,7 +11508,7 @@ Si vous recevez cet e-mail sans l'avoir sollicité, merci de l'ignorer ou de le phraseanet:: Un email vient de vous etre envoye Un e-mail vient de vous être envoyé - Controller/Root/LoginController.php + Controller/Root/LoginController.php phraseanet:: a propos diff --git a/resources/locales/messages.nl.xlf b/resources/locales/messages.nl.xlf index a7edc57208..7458d4c134 100644 --- a/resources/locales/messages.nl.xlf +++ b/resources/locales/messages.nl.xlf @@ -1,6 +1,6 @@ - +
The source node in most cases contains the sample message as written by the developer. If it looks like a dot-delimitted string such as "form.label.firstname", then the developer has not provided a default message. @@ -587,18 +587,18 @@ Account has been unlocked, you can now login. Gebruiker is ontgrendeld, u kunt zich aanmelden. - Controller/Root/LoginController.php - Controller/Root/LoginController.php + Controller/Root/LoginController.php + Controller/Root/LoginController.php Account has been unlocked, you still have to wait for admin approval. Gebruiker is ontgrendeld, u dient nog te wachten op goedkeuring van een beheerder. - Controller/Root/LoginController.php + Controller/Root/LoginController.php Account is already unlocked, you can login. Deze gebruiker is reeds ontgrendeld, u kunt zich aanmelden. - Controller/Root/LoginController.php + Controller/Root/LoginController.php Account is not found. @@ -1047,7 +1047,7 @@ An unexpected error occurred during authentication process, please contact an admin An unexpected error occurred during authentication process, please contact an admin - Controller/Root/LoginController.php + Controller/Root/LoginController.php An upload on %bridge_adapter% failed, the resaon is : %reason% @@ -3864,8 +3864,8 @@ Invalid unlock link. Ongeldige ontgrendelings-link - Controller/Root/LoginController.php - Controller/Root/LoginController.php + Controller/Root/LoginController.php + Controller/Root/LoginController.php Inverser @@ -5047,7 +5047,7 @@ Phraseanet guest-access is disabled Gast toegang voor Phraseanet is niet actief - Controller/Root/LoginController.php + Controller/Root/LoginController.php Phraseanet may require many binaries. @@ -5109,7 +5109,7 @@ Please fill the captcha Gelieve de captcha in te vullen - Controller/Root/LoginController.php + Controller/Root/LoginController.php Please fix the database before starting @@ -6337,6 +6337,7 @@ Start Start admin/worker-manager/worker_pull_assets.html.twig + admin/worker-manager/worker_record_mover.html.twig admin/worker-manager/worker_validation_reminder.html.twig admin/task-manager/templates.html.twig admin/task-manager/templates.html.twig @@ -6389,6 +6390,7 @@ prod/upload/lazaret.html.twig prod/upload/lazaret.html.twig admin/worker-manager/worker_pull_assets.html.twig + admin/worker-manager/worker_record_mover.html.twig admin/worker-manager/worker_validation_reminder.html.twig admin/task-manager/templates.html.twig admin/task-manager/templates.html.twig @@ -7059,7 +7061,7 @@ Unable to authenticate with %provider_name% Unable to authenticate with %provider_name% - Controller/Root/LoginController.php + Controller/Root/LoginController.php Controller/Api/OAuth2Controller.php @@ -7102,7 +7104,7 @@ Unable to retrieve provider identity Het is niet mogelijk om de identiteit van de provider te ontvangen - Controller/Root/LoginController.php + Controller/Root/LoginController.php Controller/Api/OAuth2Controller.php @@ -7573,7 +7575,7 @@ Vous etes maintenant deconnecte. A bientot. U bent nu uitgelogd. Tot later. - Controller/Root/LoginController.php + Controller/Root/LoginController.php Vous n'avez pas assez de droits sur certains elements selectionnes @@ -8010,7 +8012,7 @@ Your identity is not recognized. Uw identiteit werd niet herkend - Controller/Root/LoginController.php + Controller/Root/LoginController.php Your install might need to build some sub-definitions @@ -9169,7 +9171,7 @@ admin::workermanager: Rabbit config error admin::workermanager: Rabbit config error - admin/worker-manager/index.html.twig + admin/worker-manager/index.html.twig admin::workermanager:tab:Reminder: Interval in second @@ -9289,8 +9291,28 @@ admin::workermanager:tab:queueMonitor: title admin::workermanager:tab:queueMonitor: title + admin/worker-manager/index.html.twig + + + admin::workermanager:tab:record mover: description + admin::workermanager:tab:record mover: description + admin/worker-manager/worker_record_mover.html.twig + + + admin::workermanager:tab:record mover: period in second + admin::workermanager:tab:record mover: period in second + WorkerManager/Form/WorkerRecordMoverType.php + + + admin::workermanager:tab:record mover: title + admin::workermanager:tab:record mover: title admin/worker-manager/index.html.twig + + admin::workermanager:tab:record mover: xml view + admin::workermanager:tab:record mover: xml view + WorkerManager/Form/WorkerRecordMoverType.php + admin::workermanager:tab:reminder: title admin::workermanager:tab:reminder: title @@ -9631,7 +9653,7 @@ admin:worker Retrieve configuration error admin:worker Retrieve configuration error - admin/worker-manager/index.html.twig + admin/worker-manager/index.html.twig alert @@ -9792,6 +9814,7 @@ WorkerManager/Form/WorkerValidationReminderType.php WorkerManager/Form/WorkerConfigurationType.php WorkerManager/Form/WorkerPullAssetsType.php + WorkerManager/Form/WorkerRecordMoverType.php web/admin/users.html.twig @@ -10941,18 +10964,18 @@ login::erreur: Erreur d'authentification Verificatiefout - Controller/Root/LoginController.php + Controller/Root/LoginController.php Controller/Api/OAuth2Controller.php login::erreur: No available connection - Please contact sys-admin Geen beschikbare verbinding - Neem contact op met sys-admin - Controller/Root/LoginController.php + Controller/Root/LoginController.php login::erreur: Vous n'avez pas confirme votre email U hebt uw email adres niet bevestigd - Controller/Root/LoginController.php + Controller/Root/LoginController.php login::notification: Changements enregistres @@ -10962,7 +10985,7 @@ login::notification: Mise a jour du mot de passe avec succes Update van het paswoord met succes uitgevoerd - Controller/Root/LoginController.php + Controller/Root/LoginController.php Controller/Root/AccountController.php @@ -11494,7 +11517,7 @@ phraseanet:: Un email vient de vous etre envoye Een email werd u toegestuurd - Controller/Root/LoginController.php + Controller/Root/LoginController.php phraseanet:: a propos diff --git a/resources/locales/validators.de.xlf b/resources/locales/validators.de.xlf index d7171559ff..723ad790de 100644 --- a/resources/locales/validators.de.xlf +++ b/resources/locales/validators.de.xlf @@ -1,6 +1,6 @@ - +
The source node in most cases contains the sample message as written by the developer. If it looks like a dot-delimitted string such as "form.label.firstname", then the developer has not provided a default message. diff --git a/resources/locales/validators.en.xlf b/resources/locales/validators.en.xlf index 2acbe99de7..a44bfd4dff 100644 --- a/resources/locales/validators.en.xlf +++ b/resources/locales/validators.en.xlf @@ -1,6 +1,6 @@ - +
The source node in most cases contains the sample message as written by the developer. If it looks like a dot-delimitted string such as "form.label.firstname", then the developer has not provided a default message. diff --git a/resources/locales/validators.fr.xlf b/resources/locales/validators.fr.xlf index ecc4742691..d0089e1af0 100644 --- a/resources/locales/validators.fr.xlf +++ b/resources/locales/validators.fr.xlf @@ -1,6 +1,6 @@ - +
The source node in most cases contains the sample message as written by the developer. If it looks like a dot-delimitted string such as "form.label.firstname", then the developer has not provided a default message. diff --git a/resources/locales/validators.nl.xlf b/resources/locales/validators.nl.xlf index 14000e9f5e..5d496e5ab2 100644 --- a/resources/locales/validators.nl.xlf +++ b/resources/locales/validators.nl.xlf @@ -1,6 +1,6 @@ - +
The source node in most cases contains the sample message as written by the developer. If it looks like a dot-delimitted string such as "form.label.firstname", then the developer has not provided a default message. diff --git a/templates/web/admin/worker-manager/index.html.twig b/templates/web/admin/worker-manager/index.html.twig index 55e0fb0d4a..aec9ac720f 100644 --- a/templates/web/admin/worker-manager/index.html.twig +++ b/templates/web/admin/worker-manager/index.html.twig @@ -45,6 +45,11 @@ {{ 'admin::workermanager:tab:reminder: title' |trans }} +