Commit | Line | Data |
---|---|---|
a082d2df EM |
1 | <?php |
2 | /* | |
3 | +--------------------------------------------------------------------+ | |
4 | | Copyright CiviCRM LLC. All rights reserved. | | |
5 | | | | |
6 | | This work is published under the GNU AGPLv3 license with some | | |
7 | | permitted exceptions and without any warranty. For full license | | |
8 | | and copyright information, see https://civicrm.org/licensing | | |
9 | +--------------------------------------------------------------------+ | |
10 | */ | |
11 | ||
12 | /** | |
13 | * | |
14 | * @package CRM | |
15 | * @copyright CiviCRM LLC https://civicrm.org/licensing | |
16 | */ | |
17 | ||
3764aead EM |
18 | use Civi\Core\ClassScanner; |
19 | use Civi\UserJob\UserJobInterface; | |
20 | ||
a082d2df EM |
21 | /** |
22 | * This class contains user jobs functionality. | |
23 | */ | |
677170bd TO |
24 | class CRM_Core_BAO_UserJob extends CRM_Core_DAO_UserJob implements \Civi\Core\HookInterface { |
25 | ||
26 | /** | |
27 | * Check on the status of a queue. | |
28 | * | |
29 | * Queues that are attached to a UserJob are necessarily finite - so we can mark them 'completed' | |
30 | * when the task-list reaches empty. | |
31 | * | |
32 | * Note that this runs after processing *every item* in *every queue* (foreground, background, | |
33 | * import, upgrade, ad nauseum). The capacity to handle heavy tasks here is subjective (depending | |
34 | * on the specific queue/use-case). We try to be conservative about I/O until we know that | |
35 | * we're in a suitable context. | |
36 | */ | |
37 | public static function on_civi_queue_check(\Civi\Core\Event\GenericHookEvent $e) { | |
38 | /** @var \CRM_Queue_Queue $queue */ | |
39 | $queue = $e->queue; | |
40 | $userJobId = static::findUserJobId($queue->getName()); | |
41 | if ($userJobId && $queue->numberOfItems() < 1) { | |
42 | $queue->setStatus('completed'); | |
43 | } | |
44 | } | |
45 | ||
46 | /** | |
47 | * If the `civicrm_queue` changes status, then the `civicrm_user_job` should also change status. | |
48 | * | |
49 | * @param \CRM_Queue_Queue $queue | |
50 | * @param string $status | |
51 | * @throws \API_Exception | |
52 | * @throws \Civi\API\Exception\UnauthorizedException | |
53 | * @see \CRM_Utils_Hook::queueStatus() | |
54 | */ | |
55 | public static function hook_civicrm_queueStatus(CRM_Queue_Queue $queue, string $status) { | |
56 | $userJobId = static::findUserJobId($queue->getName()); | |
57 | if ($userJobId && $status === 'completed') { | |
58 | \Civi\Api4\UserJob::update() | |
59 | ->addWhere('id', '=', $userJobId) | |
60 | ->setValues(['status_id' => 1]) | |
61 | ->execute(); | |
62 | } | |
63 | } | |
64 | ||
65 | private static function findUserJobId(string $queueName): ?int { | |
66 | if (CRM_Core_Config::isUpgradeMode()) { | |
67 | return NULL; | |
68 | } | |
69 | ||
70 | $key = 'userJobId_' . $queueName; | |
71 | if (!isset(Civi::$statics[__CLASS__][$key])) { | |
72 | // Part of the primary structure/purpose of the queue. Shouldn't change. | |
73 | $userJobId = CRM_Core_DAO::singleValueQuery(' | |
74 | SELECT uj.id FROM civicrm_queue q | |
75 | INNER JOIN civicrm_user_job uj ON q.id = uj.queue_id | |
76 | WHERE q.name = %1 | |
77 | ', [ | |
78 | 1 => [$queueName, 'String'], | |
79 | ]); | |
80 | Civi::$statics[__CLASS__][$key] = $userJobId; | |
81 | } | |
82 | return Civi::$statics[__CLASS__][$key]; | |
83 | } | |
a082d2df | 84 | |
e36f7ee1 EM |
85 | /** |
86 | * Restrict access to the relevant user. | |
87 | * | |
88 | * Note that it is likely we might want to permit other users such as | |
89 | * sysadmins to access other people's user_jobs in future but it has been | |
90 | * kept tightly restricted for initial simplicity (ie do we want to | |
91 | * use an existing permission? a new permission ? do they require | |
92 | * 'view all contacts' etc. | |
93 | * | |
94 | * @inheritDoc | |
95 | */ | |
96 | public function addSelectWhereClause(): array { | |
9e10c913 TO |
97 | $clauses = []; |
98 | if (!\CRM_Core_Permission::check('administer queues')) { | |
99 | $clauses['created_id'] = '= ' . (int) CRM_Core_Session::getLoggedInContactID(); | |
100 | } | |
101 | CRM_Utils_Hook::selectWhereClause($this, $clauses); | |
e36f7ee1 EM |
102 | return $clauses; |
103 | } | |
104 | ||
a082d2df EM |
105 | /** |
106 | * Get the statuses for Import Jobs. | |
107 | * | |
108 | * @return array | |
109 | */ | |
110 | public static function getStatuses(): array { | |
111 | return [ | |
112 | [ | |
113 | 'id' => 1, | |
114 | 'name' => 'completed', | |
115 | 'label' => ts('Completed'), | |
116 | ], | |
117 | [ | |
118 | 'id' => 2, | |
7b057b66 EM |
119 | 'name' => 'draft', |
120 | 'label' => ts('Draft'), | |
121 | ], | |
122 | [ | |
123 | 'id' => 3, | |
a082d2df EM |
124 | 'name' => 'scheduled', |
125 | 'label' => ts('Scheduled'), | |
126 | ], | |
127 | [ | |
7b057b66 | 128 | 'id' => 4, |
a082d2df EM |
129 | 'name' => 'in_progress', |
130 | 'label' => ts('In Progress'), | |
131 | ], | |
132 | ]; | |
133 | } | |
134 | ||
135 | /** | |
136 | * Get the types Import Jobs. | |
137 | * | |
138 | * This is largely a placeholder at this stage. It will likely wind | |
139 | * up as an option value so extensions can add different types. | |
140 | * | |
141 | * However, for now it just holds the one type being worked on. | |
142 | * | |
143 | * @return array | |
144 | */ | |
145 | public static function getTypes(): array { | |
3764aead EM |
146 | $types = Civi::cache()->get('UserJobTypes'); |
147 | if ($types === NULL) { | |
148 | $types = []; | |
149 | $classes = ClassScanner::get(['interface' => UserJobInterface::class]); | |
150 | foreach ($classes as $class) { | |
151 | $declaredTypes = $class::getUserJobInfo(); | |
152 | foreach ($declaredTypes as $index => $declaredType) { | |
153 | $declaredTypes[$index]['class'] = $class; | |
154 | } | |
155 | $types = array_merge($types, $declaredTypes); | |
156 | } | |
157 | Civi::cache()->set('UserJobTypes', $types); | |
158 | } | |
94a0a549 EM |
159 | // Rekey to numeric to prevent https://lab.civicrm.org/dev/core/-/issues/3719 |
160 | return array_values($types); | |
a082d2df EM |
161 | } |
162 | ||
163 | } |