diff --git a/CRM/Core/DAO/UserJob.php b/CRM/Core/DAO/UserJob.php index ebe7e1ee75f1..cfa405500408 100644 --- a/CRM/Core/DAO/UserJob.php +++ b/CRM/Core/DAO/UserJob.php @@ -6,7 +6,7 @@ * * Generated from xml/schema/CRM/Core/UserJob.xml * DO NOT EDIT. Generated by CRM_Core_CodeGen - * (GenCodeChecksum:58e6fcaa028d157bfa074a073111239d) + * (GenCodeChecksum:fc2efbbf7b26018fe3dff0cda44ffa28) */ /** @@ -125,6 +125,15 @@ class CRM_Core_DAO_UserJob extends CRM_Core_DAO { */ public $metadata; + /** + * Is this a template configuration (for use by other/future jobs)? + * + * @var bool|string + * (SQL type: tinyint) + * Note that values will be retrieved from the database as a string. + */ + public $is_template; + /** * Class constructor. */ @@ -350,6 +359,24 @@ public static function &fields() { 'serialize' => self::SERIALIZE_JSON, 'add' => '5.50', ], + 'is_template' => [ + 'name' => 'is_template', + 'type' => CRM_Utils_Type::T_BOOLEAN, + 'title' => ts('Is Template'), + 'description' => ts('Is this a template configuration (for use by other/future jobs)?'), + 'required' => TRUE, + 'where' => 'civicrm_user_job.is_template', + 'default' => '0', + 'table_name' => 'civicrm_user_job', + 'entity' => 'UserJob', + 'bao' => 'CRM_Core_BAO_UserJob', + 'localizable' => 0, + 'html' => [ + 'type' => 'CheckBox', + 'label' => ts("Is Template"), + ], + 'add' => '5.51', + ], ]; CRM_Core_DAO_AllCoreTables::invoke(__CLASS__, 'fields_callback', Civi::$statics[__CLASS__]['fields']); } diff --git a/CRM/Queue/DAO/Queue.php b/CRM/Queue/DAO/Queue.php index 48debc8284f4..65b349c53e60 100644 --- a/CRM/Queue/DAO/Queue.php +++ b/CRM/Queue/DAO/Queue.php @@ -6,7 +6,7 @@ * * Generated from xml/schema/CRM/Queue/Queue.xml * DO NOT EDIT. Generated by CRM_Core_CodeGen - * (GenCodeChecksum:0b068d0a6ba5d6348f11706b3854feb1) + * (GenCodeChecksum:85012d3cc88cad6b1c868665e0b490c3) */ /** @@ -118,6 +118,15 @@ class CRM_Queue_DAO_Queue extends CRM_Core_DAO { */ public $error; + /** + * Is this a template configuration (for use by other/future queues)? + * + * @var bool|string + * (SQL type: tinyint) + * Note that values will be retrieved from the database as a string. + */ + public $is_template; + /** * Class constructor. */ @@ -327,6 +336,24 @@ public static function &fields() { ], 'add' => '5.51', ], + 'is_template' => [ + 'name' => 'is_template', + 'type' => CRM_Utils_Type::T_BOOLEAN, + 'title' => ts('Is Template'), + 'description' => ts('Is this a template configuration (for use by other/future queues)?'), + 'required' => TRUE, + 'where' => 'civicrm_queue.is_template', + 'default' => '0', + 'table_name' => 'civicrm_queue', + 'entity' => 'Queue', + 'bao' => 'CRM_Queue_BAO_Queue', + 'localizable' => 0, + 'html' => [ + 'type' => 'CheckBox', + 'label' => ts("Is Template"), + ], + 'add' => '5.51', + ], ]; CRM_Core_DAO_AllCoreTables::invoke(__CLASS__, 'fields_callback', Civi::$statics[__CLASS__]['fields']); } diff --git a/CRM/Queue/Service.php b/CRM/Queue/Service.php index 0fd874a96b63..338c46eac253 100644 --- a/CRM/Queue/Service.php +++ b/CRM/Queue/Service.php @@ -142,6 +142,12 @@ protected function findCreateQueueSpec(array $queueSpec): array { return $loaded; } + if (isset($queueSpec['template'])) { + $base = $this->findQueueSpec(['name' => $queueSpec['template']]); + $reset = ['is_template' => 0]; + $queueSpec = array_merge($base, $reset, $queueSpec); + } + $this->validateQueueSpec($queueSpec); $dao = new CRM_Queue_DAO_Queue(); diff --git a/CRM/Upgrade/Incremental/php/FiveFiftyOne.php b/CRM/Upgrade/Incremental/php/FiveFiftyOne.php index 4f440dfb01d1..f8ae125bde98 100644 --- a/CRM/Upgrade/Incremental/php/FiveFiftyOne.php +++ b/CRM/Upgrade/Incremental/php/FiveFiftyOne.php @@ -36,6 +36,10 @@ public function upgrade_5_51_alpha1($rev): void { 'status', "varchar(16) NULL DEFAULT 'active' COMMENT 'Execution status'"); $this->addTask('Add column "civicrm_queue.error"', 'addColumn', 'civicrm_queue', 'error', "varchar(16) NULL COMMENT 'Fallback behavior for unhandled errors'"); + $this->addTask('Add column "civicrm_queue.is_template"', 'addColumn', 'civicrm_queue', + 'is_template', "tinyint NOT NULL DEFAULT 0 COMMENT 'Is this a template configuration (for use by other/future queues)?'"); + $this->addTask('Add column "civicrm_user_job.is_template"', 'addColumn', 'civicrm_user_job', + 'is_template', "tinyint NOT NULL DEFAULT 0 COMMENT 'Is this a template configuration (for use by other/future jobs)?'"); $this->addTask('Backfill "civicrm_queue.status" and "civicrm_queue.error")', 'fillQueueColumns'); } diff --git a/tests/phpunit/CRM/Queue/QueueTest.php b/tests/phpunit/CRM/Queue/QueueTest.php index 781da94e5f64..e3fe0010aa7f 100644 --- a/tests/phpunit/CRM/Queue/QueueTest.php +++ b/tests/phpunit/CRM/Queue/QueueTest.php @@ -107,6 +107,38 @@ public function testStatuses() { } } + public function testTemplating() { + \Civi\Api4\Queue::create()->setValues([ + 'is_template' => TRUE, + 'name' => 'test/template', + 'type' => 'SqlParallel', + 'runner' => 'task', + 'error' => 'delete', + ])->execute(); + $this->assertDBQuery(1, "SELECT is_template FROM civicrm_queue WHERE name = 'test/template'"); + + $qActive = Civi::queue('test/my-active', [ + 'template' => 'test/template', + ]); + $this->assertEquals('test/my-active', $qActive->getName()); + $this->assertEquals('SqlParallel', $qActive->getSpec('type')); + $this->assertEquals('task', $qActive->getSpec('runner')); + $this->assertEquals('delete', $qActive->getSpec('error')); + $this->assertDBQuery('active', "SELECT status FROM civicrm_queue WHERE name = 'test/my-active'"); + $this->assertDBQuery(0, "SELECT is_template FROM civicrm_queue WHERE name = 'test/my-active'"); + + $qDraft = Civi::queue('test/my-draft', [ + 'template' => 'test/template', + 'status' => 'draft', + ]); + $this->assertEquals('test/my-draft', $qDraft->getName()); + $this->assertEquals('SqlParallel', $qDraft->getSpec('type')); + $this->assertEquals('task', $qDraft->getSpec('runner')); + $this->assertEquals('delete', $qDraft->getSpec('error')); + $this->assertDBQuery('draft', "SELECT status FROM civicrm_queue WHERE name = 'test/my-draft'"); + $this->assertDBQuery(0, "SELECT is_template FROM civicrm_queue WHERE name = 'test/my-active'"); + } + /** * Create a few queue items; alternately enqueue and dequeue various * diff --git a/xml/schema/Core/UserJob.xml b/xml/schema/Core/UserJob.xml index 0c8113e0c992..dd01a2e79184 100644 --- a/xml/schema/Core/UserJob.xml +++ b/xml/schema/Core/UserJob.xml @@ -153,4 +153,17 @@ JSON 5.50 + + is_template + Is Template + boolean + true + 0 + Is this a template configuration (for use by other/future jobs)? + + CheckBox + + + 5.51 + diff --git a/xml/schema/Queue/Queue.xml b/xml/schema/Queue/Queue.xml index 9f91aa5800ec..de777a9c8104 100644 --- a/xml/schema/Queue/Queue.xml +++ b/xml/schema/Queue/Queue.xml @@ -154,4 +154,17 @@ CRM_Queue_BAO_Queue::getErrorModes + + is_template + Is Template + boolean + true + 0 + Is this a template configuration (for use by other/future queues)? + + CheckBox + + + 5.51 +