Commit | Line | Data |
---|---|---|
3137a6a6 MW |
1 | <?php |
2 | /* | |
3 | +--------------------------------------------------------------------+ | |
bc77d7c0 | 4 | | Copyright CiviCRM LLC. All rights reserved. | |
3137a6a6 | 5 | | | |
bc77d7c0 TO |
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 | | |
3137a6a6 MW |
9 | +--------------------------------------------------------------------+ |
10 | */ | |
11 | ||
12 | /** | |
13 | * @package CRM | |
ca5cec67 | 14 | * @copyright CiviCRM LLC https://civicrm.org/licensing |
3137a6a6 MW |
15 | */ |
16 | ||
17 | /** | |
18 | * Class to represent the actions that can be performed on a group of contacts used by the search forms. | |
19 | */ | |
20 | abstract class CRM_Core_Task { | |
21 | ||
22 | /** | |
23 | * These constants are only used as enumerators for each of the batch tasks. | |
24 | */ | |
25 | const | |
26 | // General (Implemented by more than one entity) | |
27 | GROUP_REMOVE = 1, | |
28 | GROUP_ADD = 2, | |
29 | PDF_LETTER = 3, | |
30 | TASK_DELETE = 4, | |
31 | TASK_PRINT = 5, | |
32 | BATCH_UPDATE = 6, | |
33 | TASK_SMS = 7, | |
34 | TASK_EXPORT = 8, | |
35 | TASK_EMAIL = 9, | |
36 | TAG_ADD = 10, | |
37 | TAG_REMOVE = 11, | |
38 | // Contact tasks | |
39 | SAVE_SEARCH = 12, | |
40 | SAVE_SEARCH_UPDATE = 13, | |
41 | CREATE_MAILING = 14, | |
42 | DELETE_PERMANENTLY = 15, | |
43 | LABEL_CONTACTS = 16; | |
44 | ||
45 | /** | |
46 | * The task array | |
47 | * | |
48 | * @var array | |
49 | */ | |
95913c71 | 50 | public static $_tasks = []; |
3137a6a6 MW |
51 | |
52 | /** | |
53 | * @var string | |
54 | * This must be defined in each child class. It is passed to the searchTasks hook. | |
55 | * Example: $objectType = 'event'; | |
56 | */ | |
518fa0ee | 57 | public static $objectType = NULL; |
3137a6a6 MW |
58 | |
59 | /** | |
60 | * Generates a list of batch tasks available for the current entities. | |
61 | * Each child class should populate $_tasks array and then call this parent function for shared functionality. | |
62 | * * @return array The set of tasks for a group of contacts | |
63 | * [ 'title' => The Task title, | |
64 | * 'class' => The Task Form class name, | |
65 | * 'result => Boolean. FIXME: Not sure what this is for | |
66 | * ] | |
67 | */ | |
68 | public static function tasks() { | |
fde25552 | 69 | CRM_Utils_Hook::searchTasks(static::$objectType, self::$_tasks); |
3137a6a6 MW |
70 | asort(self::$_tasks); |
71 | ||
72 | return self::$_tasks; | |
73 | } | |
74 | ||
75 | /** | |
76 | * These tasks are the core set of tasks that the user can perform | |
77 | * on a contact / group of contacts | |
78 | * | |
79 | * @return array | |
80 | * the set of tasks for a group of contacts | |
81 | */ | |
82 | public static function taskTitles() { | |
83 | static::tasks(); | |
84 | ||
be2fb01f | 85 | $titles = []; |
3137a6a6 MW |
86 | foreach (self::$_tasks as $id => $value) { |
87 | $titles[$id] = $value['title']; | |
88 | } | |
89 | ||
90 | if (!CRM_Utils_Mail::validOutBoundMail()) { | |
91 | unset($titles[self::TASK_EMAIL]); | |
92 | unset($titles[self::CREATE_MAILING]); | |
93 | } | |
94 | ||
95 | // Users who do not have 'access deleted contacts' should NOT have the 'Delete Permanently' option in search result tasks | |
96 | if (!CRM_Core_Permission::check('access deleted contacts') || | |
97 | !CRM_Core_Permission::check('delete contacts') | |
98 | ) { | |
99 | unset($titles[self::DELETE_PERMANENTLY]); | |
100 | } | |
101 | return $titles; | |
102 | } | |
103 | ||
104 | /** | |
105 | * Show tasks selectively based on the permission level | |
106 | * of the user | |
affe58b8 | 107 | * This function should be overridden by the child class which would normally call parent::corePermissionedTaskTitles |
3137a6a6 MW |
108 | * |
109 | * @param int $permission | |
110 | * @param array $params | |
111 | * "ssID: Saved Search ID": If !empty we are in saved search context | |
112 | * | |
113 | * @return array | |
114 | * set of tasks that are valid for the user | |
115 | */ | |
affe58b8 MW |
116 | public static function permissionedTaskTitles($permission, $params) { |
117 | return self::corePermissionedTaskTitles(self::tasks(), $permission, $params); | |
118 | } | |
3137a6a6 MW |
119 | |
120 | /** | |
121 | * Show tasks selectively based on the permission level | |
122 | * of the user | |
123 | * This function should be called by permissionedTaskTitles in children | |
124 | * | |
125 | * @param array $tasks The array of tasks generated by permissionedTaskTitles | |
126 | * @param int $permission | |
127 | * @param array $params | |
128 | * "ssID: Saved Search ID": If !empty we are in saved search context | |
129 | * | |
130 | * @return array | |
131 | * set of tasks that are valid for the user | |
132 | */ | |
133 | public static function corePermissionedTaskTitles($tasks, $permission, $params) { | |
134 | // Only offer the "Update Smart Group" task if a smart group/saved search is already in play and we have edit permissions | |
96db3ecb | 135 | if (!empty($params['ssID']) && ($permission == CRM_Core_Permission::EDIT) && CRM_Core_Permission::check('edit groups')) { |
3137a6a6 MW |
136 | $tasks[self::SAVE_SEARCH_UPDATE] = self::$_tasks[self::SAVE_SEARCH_UPDATE]['title']; |
137 | } | |
138 | else { | |
139 | unset($tasks[self::SAVE_SEARCH_UPDATE]); | |
140 | } | |
141 | ||
142 | asort($tasks); | |
143 | return $tasks; | |
144 | } | |
145 | ||
146 | /** | |
147 | * These tasks are the core set of tasks that the user can perform | |
148 | * on participants | |
149 | * | |
150 | * @param int $value | |
151 | * | |
152 | * @return array | |
153 | * the set of tasks for a group of participants | |
154 | */ | |
155 | public static function getTask($value) { | |
156 | static::tasks(); | |
157 | ||
f3acfdd9 | 158 | if (empty(self::$_tasks[$value])) { |
ccd9c371 | 159 | // Children can specify a default task (eg. print), pick another if it is not valid. |
160 | $value = key(self::$_tasks); | |
3137a6a6 | 161 | } |
be2fb01f | 162 | return [ |
3137a6a6 MW |
163 | CRM_Utils_Array::value('class', self::$_tasks[$value]), |
164 | CRM_Utils_Array::value('result', self::$_tasks[$value]), | |
be2fb01f | 165 | ]; |
3137a6a6 MW |
166 | } |
167 | ||
61fad6d6 EM |
168 | /** |
169 | * Filter tasks based on the permission key, if available. | |
170 | * | |
171 | * @param array $tasks | |
172 | * @param bool $hasEditContactPermission | |
173 | * Does the user have permission to edit the given contact. Required where | |
174 | * permission to edit the user is required in conjunction with permission | |
175 | * to do the task. | |
176 | * | |
177 | * @return array | |
178 | */ | |
179 | protected static function getTasksFilteredByPermission(array $tasks, bool $hasEditContactPermission): array { | |
180 | foreach ($tasks as $index => $task) { | |
181 | // requires_edit_contact_permission is a (hopefully transient way) of denoting which | |
182 | // tasks need 'edit this contact' on top of the membership permission. | |
183 | if (!empty($task['requires_edit_contact_permission']) && !$hasEditContactPermission) { | |
184 | unset($tasks[$index]); | |
185 | } | |
186 | elseif (!empty($task['permissions']) && !CRM_Core_Permission::check($task['permissions'])) { | |
187 | unset($tasks[$index]); | |
188 | } | |
189 | } | |
190 | return $tasks; | |
191 | } | |
192 | ||
193 | /** | |
194 | * Get task tiles filtered by any declared permissions. | |
195 | * | |
196 | * @param array $tasks | |
197 | * @param bool $hasEditContactPermission | |
198 | * Does the user have permission to edit the given contact. Required where | |
199 | * permission to edit the user is required in conjunction with permission | |
200 | * to do the task. | |
201 | * | |
202 | * @return array | |
203 | */ | |
204 | protected static function getTitlesFilteredByPermission(array $tasks, bool $hasEditContactPermission): array { | |
205 | $availableTasks = self::getTasksFilteredByPermission($tasks, $hasEditContactPermission); | |
206 | $return = []; | |
207 | foreach ($availableTasks as $key => $details) { | |
208 | $return[$key] = $details['title']; | |
209 | } | |
210 | return $return; | |
211 | } | |
212 | ||
3137a6a6 MW |
213 | /** |
214 | * Function to return the task information on basis of provided task's form name | |
215 | * | |
216 | * @param string $className | |
217 | * | |
218 | * @return array [ 0 => Task ID, 1 => Task Title ] | |
219 | */ | |
220 | public static function getTaskAndTitleByClass($className) { | |
221 | static::tasks(); | |
222 | ||
223 | foreach (self::$_tasks as $task => $value) { | |
224 | if ((!empty($value['url']) || $task == self::TASK_EXPORT) | |
225 | && ((is_array($value['class']) && in_array($className, $value['class'])) | |
226 | || ($value['class'] == $className))) { | |
be2fb01f | 227 | return [$task, CRM_Utils_Array::value('title', $value)]; |
3137a6a6 MW |
228 | } |
229 | } | |
be2fb01f | 230 | return []; |
3137a6a6 MW |
231 | } |
232 | ||
233 | } |