PluginProbe ʕ •ᴥ•ʔ
WooCommerce / 10.9.1
WooCommerce v10.9.1
10.9.3 10.9.2 10.9.1 10.9.0 10.9.0-rc.1 10.9.0-beta.2 10.9.0-beta.1 10.8.1 10.8.0 10.8.0-rc.1 10.8.0-beta.2 10.8.0-beta.1 7.8.0-beta.1 7.8.0-beta.2 7.8.0-rc.1 7.8.0-rc.2 7.8.1 7.8.2 7.8.3 7.8.4 7.9.0 7.9.0-beta.1 7.9.0-beta.2 7.9.0-rc.2 7.9.0-rc.3 7.9.1 7.9.2 8.0.0 8.0.0-beta.1 8.0.0-beta.2 8.0.0-rc.1 8.0.0-rc.2 8.0.1 8.0.2 8.0.3 8.0.4 8.0.5 8.1.0 8.1.0-beta.1 8.1.0-rc.1 8.1.0-rc.2 8.1.1 8.1.2 8.1.3 8.1.4 8.2.0 8.2.0-beta.1 8.2.0-rc.1 8.2.0-rc.2 8.2.1 8.2.2 8.2.3 8.2.4 8.2.5 8.3.0 8.3.0-beta.1 8.3.0-rc.1 8.3.0-rc.2 8.3.1 8.3.2 8.3.3 8.3.4 8.4.0 8.4.0-beta.1 8.4.0-rc.1 8.4.1 8.4.2 8.4.3 8.5.0 8.5.0-beta.1 8.5.0-rc.1 8.5.1 8.5.2 8.5.3 8.5.4 8.5.5 8.6.0 8.6.0-beta.1 8.6.0-rc.1 8.6.1 8.6.2 8.6.3 8.6.4 8.7.0 8.7.0-beta.1 8.7.0-beta.2 8.7.0-rc.1 8.7.1 8.7.2 8.7.3 8.8.0 8.8.0-beta.1 8.8.0-rc.1 8.8.1 8.8.2 8.8.3 8.8.4 8.8.5 8.8.6 8.8.7 8.9.0 8.9.0-beta.1 8.9.0-rc.1 8.9.1 8.9.2 8.9.3 8.9.4 8.9.5 9.0.0 9.0.0-beta.1 9.0.0-beta.2 9.0.0-rc.1 9.0.1 9.0.2 9.0.3 9.0.4 9.1.0 9.1.0-beta.1 9.1.0-rc.1 9.1.1 9.1.2 9.1.3 9.1.4 9.1.5 9.1.6 9.2.0 9.2.0-beta.1 9.2.0-rc.1 9.2.1 9.2.2 9.2.3 9.2.4 9.2.5 9.3.0 9.3.0-beta.1 9.3.0-rc.1 9.3.1 9.3.2 9.3.3 9.3.4 9.3.5 9.3.6 9.4.0 9.4.0-beta.1 9.4.0-beta.2 9.4.0-rc.1 9.4.0-rc.2 9.4.0-rc.3 9.4.0-rc.4 9.4.1 9.4.2 9.4.3 9.4.4 9.4.5 9.5.0 9.5.0-beta.1 9.5.0-beta.2 9.5.0-rc.1 9.5.1 9.5.2 9.5.3 9.5.4 9.6.0 9.6.0-beta.1 9.6.0-beta.2 9.6.0-rc.1 9.6.1 9.6.2 9.6.3 9.6.4 9.7.0 9.7.0-beta.1 9.7.0-rc.1 9.7.1 9.7.2 9.7.3 9.8.0 9.8.0-beta.1 9.8.0-rc.1 9.8.1 9.8.2 9.8.3 9.8.4 9.8.5 9.8.6 9.8.7 9.9.0 9.9.0-beta.1 9.9.0-rc.1 9.9.1 9.9.2 9.9.3 9.9.4 9.9.5 9.9.6 9.9.7 3.7.3 7.1.2 3.8.0 7.2.0 3.8.0-beta.1 7.2.0-beta.1 3.8.0-rc.1 7.2.0-beta.2 3.8.0-rc.2 7.2.0-rc.1 3.8.1 7.2.0-rc.2 3.8.2 7.2.1 3.8.3 7.2.2 3.9.0 7.2.3 3.9.0-beta.1 7.2.4 3.9.0-beta.2 7.3.0 3.9.0-rc.1 7.3.0-beta.1 3.9.0-rc.2 7.3.0-beta.2 3.9.0-rc.3 7.3.0-rc.1 3.9.0-rc.4 7.3.0-rc.2 3.9.1 7.3.1 3.9.2 7.4.0 3.9.3 7.4.0-beta.1 3.9.4 7.4.0-beta.2 3.9.5 7.4.0-rc.1 4.0.0 7.4.0-rc.2 4.0.0-beta.1 7.4.1 4.0.0-rc.1 7.4.2 4.0.0-rc.2 7.5.0 4.0.1 7.5.0-beta.1 4.0.2 7.5.0-beta.2 4.0.3 7.5.0-rc.1 4.0.4 7.5.1 4.1.0 7.5.2 4.1.0-beta.1 7.6.0 4.1.0-beta.2 7.6.0-beta.1 4.1.0-rc.1 7.6.0-beta.2 4.1.0-rc.2 7.6.0-rc.1 4.1.1 7.6.0-rc.2 4.1.2 7.6.0-rc.3 4.1.3 7.6.1 4.1.4 7.6.2 4.2.0 7.7.0 4.2.0-RC.1 7.7.0-beta.1 4.2.0-RC.2 7.7.0-beta.2 4.2.0-beta.1 7.7.0-rc.1 4.2.1 7.7.1 4.2.2 7.7.2 4.2.3 7.7.3 4.2.4 7.8.0 4.2.5 4.3.0 4.3.0-beta.1 4.3.0-rc.1 4.3.0-rc.2 4.3.0-rc.3 4.3.1 4.3.2 4.3.3 4.3.4 4.3.5 4.3.6 4.4.0 4.4.0-beta.1 4.4.0-rc.1 4.4.1 4.4.2 4.4.3 4.4.4 4.5.0 4.5.0-beta.1 4.5.0-rc.1 4.5.0-rc.3 4.5.1 4.5.2 4.5.3 4.5.4 4.5.5 4.6.0 4.6.0-beta.1 4.6.0-rc.1 4.6.1 4.6.2 4.6.3 4.6.4 4.6.5 4.7.0 4.7.0-beta.1 4.7.0-beta.2 4.7.0-rc.1 4.7.1 4.7.1-beta.1 4.7.2 4.7.3 4.7.4 4.8.0 4.8.0-beta.1 4.8.0-rc.1 4.8.0-rc.2 4.8.1 4.8.2 4.8.3 4.9.0 4.9.0-beta.1 4.9.0-rc.1 4.9.0-rc.2 4.9.1 4.9.2 4.9.3 4.9.4 4.9.5 5.0.0 5.0.0-beta.1 5.0.0-beta.2 5.0.0-rc.1 5.0.0-rc.2 5.0.0-rc.3 5.0.1 5.0.2 5.0.3 5.1.0 5.1.0-beta.1 5.1.0-rc.1 trunk 5.1.1 10.0.0 5.1.2 10.0.0-rc.1 5.1.3 10.0.0-rc.2 5.2.0 10.0.1 5.2.0-beta.1 10.0.2 5.2.0-rc.1 10.0.3 5.2.0-rc.2 10.0.4 5.2.1 10.0.5 5.2.2 10.0.6 5.2.3 10.1.0 5.2.4 10.1.0-rc.1 5.2.5 10.1.0-rc.2 5.3.0 10.1.0-rc.3 5.3.0-beta.1 10.1.0-rc.4 5.3.0-rc.1 10.1.1 5.3.0-rc.2 10.1.2 5.3.1 10.1.3 5.3.2 10.1.4 5.3.3 10.2.0 5.4.0 10.2.0-beta.1 5.4.0-beta.1 10.2.0-beta.2 5.4.0-rc.1 10.2.0-rc.1 5.4.1 10.2.1 5.4.2 10.2.2 5.4.3 10.2.3 5.4.4 10.2.4 5.4.5 10.3.0 5.5.0 10.3.0-beta.1 5.5.0-beta.1 10.3.0-beta.2 5.5.0-rc.1 10.3.0-rc.1 5.5.0-rc.2 10.3.0-rc.2 5.5.1 10.3.1 5.5.2 10.3.2 5.5.3 10.3.3 5.5.4 10.3.4 5.5.5 10.3.5 5.6.0 10.3.6 5.6.0-beta.1 10.3.7 5.6.0-rc.1 10.3.8 5.6.0-rc.2 10.4.0 5.6.1 10.4.0-beta.1 5.6.2 10.4.0-beta.2 5.6.3 10.4.0-rc.1 5.7.0 10.4.1 5.7.0-beta.1 10.4.2 5.7.0-rc.1 10.4.3 5.7.1 10.4.4 5.7.2 10.5.0 5.7.3 10.5.0-beta.1 5.8.0 10.5.0-beta.2 5.8.0-beta.1 10.5.0-rc.1 5.8.0-beta.2 10.5.0-rc.2 5.8.0-rc.1 10.5.0-rc.3 5.8.1 10.5.1 5.8.2 10.5.2 5.9.0 10.5.3 5.9.0-beta.1 10.6.0 5.9.0-rc.1 10.6.0-beta.1 5.9.0-rc.2 10.6.0-beta.2 5.9.1 10.6.0-rc.1 5.9.2 10.6.1 6.0.0 10.6.2 6.0.0-beta.1 10.7.0 6.0.0-rc.1 10.7.0-beta.1 6.0.1 10.7.0-beta.2 6.0.2 10.7.0-rc.1 6.1.0 3.0.0 6.1.0-beta.1 3.0.1 6.1.0-rc.1 3.0.2 6.1.0-rc.2 3.0.3 6.1.1 3.0.4 6.1.2 3.0.5 6.1.3 3.0.6 6.2.0 3.0.7 6.2.0-beta.1 3.0.8 6.2.0-rc.1 3.0.9 6.2.0-rc.2 3.1.0 6.2.1 3.1.1 6.2.2 3.1.2 6.2.3 3.2.0 6.3.0 3.2.1 6.3.0-beta.1 3.2.2 6.3.0-rc.1 3.2.3 6.3.0-rc.2 3.2.4 6.3.1 3.2.5 6.3.2 3.2.6 6.4.0 3.3.0 6.4.0-beta.1 3.3.1 6.4.0-rc.1 3.3.2 6.4.1 3.3.2-rc.1 6.4.2 3.3.3 6.5.0 3.3.4 6.5.0-beta.1 3.3.5 6.5.0-rc.1 3.3.6 6.5.0-rc.2 3.4.0 6.5.1 3.4.0-beta.1 6.5.2 3.4.0-rc.2 6.6.0 3.4.1 6.6.0-beta.1 3.4.2 6.6.0-rc.1 3.4.3 6.6.0-rc.2 3.4.4 6.6.1 3.4.5 6.6.2 3.4.6 6.7.0 3.4.7 6.7.0-beta.1 3.4.8 6.7.0-beta.2 3.5.0 6.7.0-rc.1 3.5.0-beta.1 6.7.1 3.5.0-rc.1 6.8.0 3.5.0-rc.2 6.8.0-beta.1 3.5.1 6.8.0-beta.2 3.5.10 6.8.0-rc.1 3.5.2 6.8.1 3.5.3 6.8.2 3.5.4 6.8.3 3.5.5 6.9.0 3.5.6 6.9.0-beta.1 3.5.7 6.9.0-beta.2 3.5.8 6.9.0-rc.1 3.5.9 6.9.1 3.6.0 6.9.2 3.6.0-beta.1 6.9.3 3.6.0-rc.1 6.9.4 3.6.0-rc.2 6.9.5 3.6.0-rc.3 7.0.0 3.6.1 7.0.0-beta.1 3.6.2 7.0.0-beta.2 3.6.3 7.0.0-beta.3 3.6.4 7.0.0-rc.1 3.6.5 7.0.0-rc.2 3.6.6 7.0.1 3.6.7 7.0.2 3.7.0 7.1.0 3.7.0-beta.1 7.1.0-beta.1 3.7.0-rc.1 7.1.0-beta.2 3.7.0-rc.2 7.1.0-rc.1 3.7.1 7.1.0-rc.2 3.7.2 7.1.1
woocommerce / src / Admin / Features / OnboardingTasks / TaskList.php
woocommerce / src / Admin / Features / OnboardingTasks Last commit date
Tasks 1 month ago DeprecatedExtendedTask.php 2 years ago DeprecatedOptions.php 3 months ago Init.php 3 years ago Task.php 11 months ago TaskList.php 4 weeks ago TaskListSection.php 3 years ago TaskLists.php 4 months ago TaskTraits.php 4 years ago
TaskList.php
456 lines
1 <?php
2 /**
3 * Handles storage and retrieval of a task list
4 */
5
6 namespace Automattic\WooCommerce\Admin\Features\OnboardingTasks;
7
8 use Automattic\WooCommerce\Admin\Features\OnboardingTasks\Task;
9
10
11 /**
12 * Task List class.
13 */
14 class TaskList {
15 /**
16 * Task traits.
17 */
18 use TaskTraits;
19
20 /**
21 * Option name hidden task lists.
22 */
23 const HIDDEN_OPTION = 'woocommerce_task_list_hidden_lists';
24
25 /**
26 * Option name of completed task lists.
27 */
28 const COMPLETED_OPTION = 'woocommerce_task_list_completed_lists';
29
30 /**
31 * Option name of the dismissed reminder bar option.
32 *
33 * @deprecated 10.9.0 The reminder bar feature was removed; this option is no longer used.
34 * Retained as a stub to avoid fatal errors in third-party code that
35 * references the constant.
36 */
37 const REMINDER_BAR_HIDDEN_OPTION = 'woocommerce_task_list_reminder_bar_hidden';
38
39 /**
40 * ID.
41 *
42 * @var string
43 */
44 public $id = '';
45
46 /**
47 * ID.
48 *
49 * @var string
50 */
51 public $hidden_id = '';
52
53 /**
54 * ID.
55 *
56 * @var boolean
57 */
58 public $display_progress_header = false;
59
60 /**
61 * Title.
62 *
63 * @var string
64 */
65 public $title = '';
66
67 /**
68 * Tasks.
69 *
70 * @var array
71 */
72 public $tasks = array();
73
74 /**
75 * Sort keys.
76 *
77 * @var array
78 */
79 public $sort_by = array();
80
81 /**
82 * Event prefix.
83 *
84 * @var string|null
85 */
86 public $event_prefix = null;
87
88 /**
89 * Task list visibility.
90 *
91 * @var boolean
92 */
93 public $visible = true;
94
95 /**
96 * Array of custom options.
97 *
98 * @var array
99 */
100 public $options = array();
101
102 /**
103 * Array of TaskListSection.
104 *
105 * @deprecated 7.2.0
106 *
107 * @var array
108 */
109 private $sections = array();
110
111 /**
112 * Key value map of task class and id used for sections.
113 *
114 * @deprecated 7.2.0
115 *
116 * @var array
117 */
118 public $task_class_id_map = array();
119
120 /**
121 * Constructor
122 *
123 * @param array $data Task list data.
124 */
125 public function __construct( $data = array() ) {
126 $defaults = array(
127 'id' => null,
128 'hidden_id' => null,
129 'title' => '',
130 'tasks' => array(),
131 'sort_by' => array(),
132 'event_prefix' => null,
133 'options' => array(),
134 'visible' => true,
135 'display_progress_header' => false,
136 );
137
138 $data = wp_parse_args( $data, $defaults );
139
140 $this->id = $data['id'];
141 $this->hidden_id = $data['hidden_id'];
142 $this->title = $data['title'];
143 $this->sort_by = $data['sort_by'];
144 $this->event_prefix = $data['event_prefix'];
145 $this->options = $data['options'];
146 $this->visible = $data['visible'];
147 $this->display_progress_header = $data['display_progress_header'];
148
149 foreach ( $data['tasks'] as $task_name ) {
150 $class = 'Automattic\WooCommerce\Admin\Features\OnboardingTasks\Tasks\\' . $task_name;
151 $task = new $class( $this );
152 $this->add_task( $task );
153 }
154 }
155
156 /**
157 * Check if the task list is hidden.
158 *
159 * @return bool
160 */
161 public function is_hidden() {
162 $hidden = get_option( self::HIDDEN_OPTION, array() );
163 return in_array( $this->hidden_id ? $this->hidden_id : $this->id, $hidden, true );
164 }
165
166 /**
167 * Check if the task list is visible.
168 *
169 * @return bool
170 */
171 public function is_visible() {
172 // If the task list is explicitly set to not be visible, return false.
173 if ( ! $this->visible ) {
174 return false;
175 }
176
177 // If the task list is hidden, return false.
178 if ( $this->is_hidden() ) {
179 return false;
180 }
181
182 // If the task list has no viewable tasks, return false.
183 $no_viewable_tasks = count( $this->get_viewable_tasks() ) === 0;
184 if ( $no_viewable_tasks ) {
185 return false;
186 }
187
188 return true;
189 }
190
191 /**
192 * Hide the task list.
193 *
194 * @return bool
195 */
196 public function hide() {
197 if ( $this->is_hidden() ) {
198 return;
199 }
200
201 $viewable_tasks = $this->get_viewable_tasks();
202 $completed_count = array_reduce(
203 $viewable_tasks,
204 function ( $total, $task ) {
205 return $task->is_complete() ? $total + 1 : $total;
206 },
207 0
208 );
209
210 $this->record_tracks_event(
211 'completed',
212 array(
213 'action' => 'remove_card',
214 'completed_task_count' => $completed_count,
215 'incomplete_task_count' => count( $viewable_tasks ) - $completed_count,
216 'tasklist_id' => $this->id,
217 )
218 );
219
220 $hidden = get_option( self::HIDDEN_OPTION, array() );
221 $hidden[] = $this->hidden_id ? $this->hidden_id : $this->id;
222 $this->maybe_set_default_layout( $hidden );
223 return update_option( self::HIDDEN_OPTION, array_unique( $hidden ) );
224 }
225
226 /**
227 * Sets the default homepage layout to two_columns if "setup" tasklist is completed or hidden.
228 *
229 * @param array $completed_or_hidden_tasklist_ids Array of tasklist ids.
230 */
231 public function maybe_set_default_layout( $completed_or_hidden_tasklist_ids ) {
232 if ( in_array( 'setup', $completed_or_hidden_tasklist_ids, true ) ) {
233 update_option( 'woocommerce_default_homepage_layout', 'two_columns' );
234 }
235 }
236
237 /**
238 * Undo hiding of the task list.
239 *
240 * @return bool
241 */
242 public function unhide() {
243 $hidden = get_option( self::HIDDEN_OPTION, array() );
244 $hidden = array_diff( $hidden, array( $this->hidden_id ? $this->hidden_id : $this->id ) );
245 return update_option( self::HIDDEN_OPTION, $hidden );
246 }
247
248 /**
249 * Check if all viewable tasks are complete.
250 *
251 * @return bool
252 */
253 public function is_complete() {
254 foreach ( $this->get_viewable_tasks() as $viewable_task ) {
255 if ( $viewable_task->is_complete() === false ) {
256 return false;
257 }
258 }
259
260 return true;
261 }
262
263 /**
264 * Check if a task list has previously been marked as complete.
265 *
266 * @return bool
267 */
268 public function has_previously_completed() {
269 $complete = get_option( self::COMPLETED_OPTION, array() );
270 return in_array( $this->get_list_id(), $complete, true );
271 }
272
273 /**
274 * Add task to the task list.
275 *
276 * @param Task $task Task class.
277 */
278 public function add_task( $task ) {
279 if ( ! is_subclass_of( $task, 'Automattic\WooCommerce\Admin\Features\OnboardingTasks\Task' ) ) {
280 return new \WP_Error(
281 'woocommerce_task_list_invalid_task',
282 __( 'Task is not a subclass of `Task`', 'woocommerce' )
283 );
284 }
285 if ( array_search( $task, $this->tasks, true ) ) {
286 return;
287 }
288
289 $this->tasks[] = $task;
290 }
291
292 /**
293 * Get only visible tasks in list.
294 *
295 * @param string $task_id id of task.
296 * @return Task
297 */
298 public function get_task( $task_id ) {
299 return current(
300 array_filter(
301 $this->tasks,
302 function ( $task ) use ( $task_id ) {
303 return $task->get_id() === $task_id;
304 }
305 )
306 );
307 }
308
309 /**
310 * Get only visible tasks in list.
311 *
312 * @return array
313 */
314 public function get_viewable_tasks() {
315 return array_values(
316 array_filter(
317 $this->tasks,
318 function ( $task ) {
319 return $task->can_view();
320 }
321 )
322 );
323 }
324
325 /**
326 * Get task list sections.
327 *
328 * @deprecated 7.2.0
329 *
330 * @return array
331 */
332 public function get_sections() {
333 wc_deprecated_function( __CLASS__ . '::' . __FUNCTION__, '7.2.0' );
334
335 return $this->sections;
336 }
337
338 /**
339 * Track list completion of viewable tasks.
340 */
341 public function possibly_track_completion() {
342 if ( $this->has_previously_completed() ) {
343 return;
344 }
345
346 // If it's hidden, completion is tracked via hide method.
347 if ( $this->is_hidden() ) {
348 return;
349 }
350
351 // Expensive check, do it last.
352 if ( ! $this->is_complete() ) {
353 return;
354 }
355
356 $completed_lists = get_option( self::COMPLETED_OPTION, array() );
357 $completed_lists[] = $this->get_list_id();
358 update_option( self::COMPLETED_OPTION, $completed_lists, true );
359 $this->maybe_set_default_layout( $completed_lists );
360 $this->record_tracks_event(
361 'tasks_completed',
362 array(
363 'tasklist_id' => $this->id,
364 )
365 );
366 }
367
368 /**
369 * Sorts the attached tasks array.
370 *
371 * @param array $sort_by list of columns with sort order.
372 * @return TaskList returns $this, for chaining.
373 */
374 public function sort_tasks( $sort_by = array() ) {
375 $sort_by = count( $sort_by ) > 0 ? $sort_by : $this->sort_by;
376 if ( 0 !== count( $sort_by ) ) {
377 usort(
378 $this->tasks,
379 function ( $a, $b ) use ( $sort_by ) {
380 return Task::sort( $a, $b, $sort_by );
381 }
382 );
383 }
384 return $this;
385 }
386
387 /**
388 * Prefix event for track event naming.
389 *
390 * @param string $event_name Event name.
391 * @return string
392 */
393 public function prefix_event( $event_name ) {
394 if ( null !== $this->event_prefix ) {
395 return $this->event_prefix . $event_name;
396 }
397 return $this->get_list_id() . '_tasklist_' . $event_name;
398 }
399
400 /**
401 * Returns option to keep completed task list.
402 *
403 * @return string
404 */
405 public function get_keep_completed_task_list() {
406 return get_option( 'woocommerce_task_list_keep_completed', 'no' );
407 }
408
409 /**
410 * Get the list for use in JSON.
411 *
412 * @return array
413 */
414 public function get_json() {
415 $this->possibly_track_completion();
416 $tasks_json = array();
417
418 foreach ( $this->tasks as $task ) {
419 // We have no use for hidden lists, it's expensive to compute individual tasks completion.
420 // Exception: Secret tasklist is always hidden, or a task is always accessible.
421 $list_is_visible = $this->is_visible() || 'secret_tasklist' === $this->id;
422 if ( $list_is_visible || ( method_exists( $task, 'is_always_accessible' ) && $task->is_always_accessible() ) ) {
423 $json = $task->get_json();
424 if ( $json['canView'] ) {
425 $tasks_json[] = $json;
426 }
427 }
428 }
429
430 return array(
431 'id' => $this->get_list_id(),
432 'title' => $this->title,
433 'isHidden' => $this->is_hidden(),
434 'isVisible' => $this->is_visible(),
435 'isComplete' => $this->is_complete(),
436 'tasks' => $tasks_json,
437 'eventPrefix' => $this->prefix_event( '' ),
438 'displayProgressHeader' => $this->display_progress_header,
439 'keepCompletedTaskList' => $this->get_keep_completed_task_list(),
440 );
441 }
442
443 /**
444 * Possibly remove the task list reminder bar.
445 *
446 * @deprecated 10.9.0 The reminder bar feature was removed; this method is now a no-op.
447 * Retained as a stub to avoid fatal errors in third-party code that
448 * references the method.
449 *
450 * @return void
451 */
452 public static function possibly_remove_reminder_bar(): void {
453 wc_deprecated_function( __METHOD__, '10.9.0' );
454 }
455 }
456