diff --git a/lib/Alchemy/Phrasea/Command/ExpiringRights/AlertExpiringRightsCommand.php b/lib/Alchemy/Phrasea/Command/ExpiringRights/AlertExpiringRightsCommand.php
index f354aee59d..d3b2fc9804 100644
--- a/lib/Alchemy/Phrasea/Command/ExpiringRights/AlertExpiringRightsCommand.php
+++ b/lib/Alchemy/Phrasea/Command/ExpiringRights/AlertExpiringRightsCommand.php
@@ -154,6 +154,9 @@ private function playJobOwners($jobname, $job)
return true;
}
+ // actions by api
+ $actions = [];
+
// build sql where clause
$wheres = [];
@@ -173,7 +176,7 @@ private function playJobOwners($jobname, $job)
$dbox = $this->databoxes[$d]['dbox'];
$sbas_id = $dbox->get_sbas_id();
- // filter on collections ?
+ // filter on collections
$collList = [];
foreach (get_in($job, ['collection'], []) as $c) {
/** @var collection $coll */
@@ -190,38 +193,69 @@ private function playJobOwners($jobname, $job)
}
}
- // clause on sb (negated)
- $mask = get_in($job, ['set_status']);
- if ($mask === null) {
- $this->output->writeln(sprintf("missing 'set_status' clause"));
- return false;
- }
- $m = preg_replace('/[^0-1]/', 'x', trim($mask));
- if (strlen($m) > 32) {
- $this->output->writeln(sprintf("status mask (%s) too long", $mask));
- return false;
- }
- $mask_xor = str_replace(' ', '0', ltrim(str_replace(array('0', 'x'), array(' ', ' '), $m)));
- $mask_and = str_replace(' ', '0', ltrim(str_replace(array('x', '0'), array(' ', '1'), $m)));
- if ($mask_xor && $mask_and) {
- $wheres[] = '((r.`status` ^ 0b' . $mask_xor . ') & 0b' . $mask_and . ') != 0';
- } elseif ($mask_xor) {
- $wheres[] = '(r.`status` ^ 0b' . $mask_xor . ') != 0';
- } elseif ($mask_and) {
- $wheres[] = '(r.`status` & 0b' . $mask_and . ') != 0';
- } else {
- $this->output->writeln(sprintf("empty status mask"));
- return false;
+ // filter on status
+ if (($status = get_in($job, ['status'])) !== null) {
+ $m = preg_replace('/[^0-1]/', 'x', trim($status));
+ if (strlen($m) == 0 || strlen($m) > 32) {
+ $this->output->writeln(sprintf("invalid status (%s)", $status));
+ return false;
+ }
+ $mask_xor = str_replace(' ', '0', ltrim(str_replace(['0', 'x'], [' ', ' '], $m)));
+ $mask_and = str_replace(' ', '0', ltrim(str_replace(['x', '0'], [' ', '1'], $m)));
+ if ($mask_xor && $mask_and) {
+ $wheres[] = '((r.`status` ^ 0b' . $mask_xor . ') & 0b' . $mask_and . ') = 0';
+ }
+ elseif ($mask_xor) {
+ $wheres[] = '(r.`status` ^ 0b' . $mask_xor . ') = 0';
+ }
+ elseif ($mask_and) {
+ $wheres[] = '(r.`status` & 0b' . $mask_and . ') = 0';
+ }
}
- // set status
- $set_status = "`status`";
- $set_or = str_replace(' ', '0', ltrim(str_replace(array('0', 'x'), array(' ', ' '), $m)));
- $set_nand = str_replace(' ', '0', ltrim(str_replace(array('x', '1', '0'), array(' ', ' ', '1'), $m)));
- if($set_or) {
- $set_status = "(" . $set_status . " | 0b" . $set_or . ")";
+
+ // filter on negated set_status
+ if(($set_status = get_in($job, ['set_status'])) !== null) {
+ $m = preg_replace('/[^0-1]/', 'x', trim($set_status));
+ if (strlen($m) == 0 || strlen($m) > 32) {
+ $this->output->writeln(sprintf("invalid set_status (%s)", $set_status));
+ return false;
+ }
+ $mask_xor = str_replace(' ', '0', ltrim(str_replace(['0', 'x'], [' ', ' '], $m)));
+ $mask_and = str_replace(' ', '0', ltrim(str_replace(['x', '0'], [' ', '1'], $m)));
+ if ($mask_xor && $mask_and) {
+ $wheres[] = '((r.`status` ^ 0b' . $mask_xor . ') & 0b' . $mask_and . ') != 0';
+ }
+ elseif ($mask_xor) {
+ $wheres[] = '(r.`status` ^ 0b' . $mask_xor . ') != 0';
+ }
+ elseif ($mask_and) {
+ $wheres[] = '(r.`status` & 0b' . $mask_and . ') != 0';
+ }
+
+ // set status by actions api
+ foreach (str_split(strrev($m)) as $bit => $val) {
+ if ($val == '0' || $val == '1') {
+ if(!array_key_exists('status', $actions)) {
+ $actions['status'] = [];
+ }
+ $actions['status'][] = ['bit' => $bit, 'state' => $val=='1'];
+ }
+ }
}
- if($set_nand) {
- $set_status = "(" . $set_status . " & ~0b" . $set_nand . ")";
+
+ // filter on negated set_collection
+ if($set_collection = get_in($job, ['set_collection'])) {
+ /** @var collection $coll */
+ if (($coll = get_in($this->databoxes[$sbas_id], ['collections', $set_collection])) !== null) {
+ $wheres[] = "r.`coll_id`!=" . $dbox->get_connection()->quote($coll->get_coll_id());
+
+ // change collection by actions api
+ $actions['base_id'] = $coll->get_coll_id();
+ }
+ else {
+ $this->output->writeln(sprintf("unknown collection (%s)", $c));
+ return false;
+ }
}
// clause on expiration date
@@ -270,18 +304,30 @@ private function playJobOwners($jobname, $job)
$this->output->writeln(sprintf("dry mode: updates on %d records NOT executed", $stmt->rowCount()));
}
+ if(empty($actions)) {
+ $this->output->writeln(sprintf("no actions defined"));
+ return false;
+ }
+
while ($row = $stmt->fetch(\PDO::FETCH_ASSOC)) {
$record = $dbox->get_record($row['record_id']);
$row['collection'] = $record->getCollection()->get_name();
$row['title'] = $record->get_title();
$records[] = $row;
- $sql = "UPDATE `record` SET `status`=" . $set_status . " WHERE record_id=" . $dbox->get_connection()->quote($row['record_id']);
- if ($this->input->getOption('show-sql')) {
- $this->output->writeln(sprintf("sql: %s", $sql));
- }
- if (!$this->input->getOption('dry')) {
- $dbox->get_connection()->exec($sql);
+ // update by api
+ if(!empty($actions)) {
+ $js = json_encode($actions);
+ $this->output->writeln(sprintf("on databox(%s), record(%s) :%s js=%s \n",
+ $sbas_id,
+ $row['record_id'],
+ $this->input->getOption('dry') ? " [DRY]" : '',
+ $js
+ ));
+
+ if(!$this->input->getOption('dry')) {
+ $record->setMetadatasByActions(json_decode($js, false)); // false: setMetadatasByActions expects object, not array !
+ }
}
}
$stmt->closeCursor();
@@ -575,12 +621,11 @@ private function sanitizeJob($job)
private function sanitizeJobOwners($job)
{
- return $this->sanitize(
- $job,
- [
- 'set_status' => "is_string",
- ]
- );
+ if(get_in($job, ['set_status']) === null && get_in($job, ['set_collection']) === null) {
+ $this->output->writeln(sprintf("missing 'set_status' or 'set_collection' setting"));
+ return false;
+ }
+ return true;
}
private function sanitizeJobDownloaders($job)