PluginProbe
UpStream: a Project Management Plugin for WordPress / 1.39.1
UpStream: a Project Management Plugin for WordPress v1.39.1
trunk 1.39.0 1.39.1 1.39.2 1.39.3 2.0.7 2.1.0
upstream / includes / admin / class-up-admin.php

class-up-admin.php in UpStream: a Project Management Plugin for WordPress 1.39.1, at includes/admin/class-up-admin.php

830 lines 27.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * UpStream Admin
4 *
5 * @class UpStream_Admin
6 * @author UpStream
7 * @category Admin
8 * @package UpStream/Admin
9 * @version 1.0.0
10 */
11
12 // Exit if accessed directly
13 if ( ! defined('ABSPATH')) {
14 exit;
15 }
16
17 /**
18 * UpStream_Admin class.
19 */
20 class UpStream_Admin
21 {
22
23 /**
24 * @var \Allex\Core
25 */
26 protected $framework;
27
28 /**
29 * Constructor.
30 */
31 public function __construct()
32 {
33 add_action('init', [$this, 'includes']);
34 add_action('init', [$this, 'init'], 13);
35 add_filter('admin_body_class', [$this, 'admin_body_class']);
36 add_filter('ajax_query_attachments_args', [$this, 'filter_user_attachments'], 10, 1);
37 add_action('admin_menu', [$this, 'limitUpStreamUserAccess']);
38
39 add_action('show_user_profile', [$this, 'renderAdditionalUserFields'], 10, 1);
40 add_action('edit_user_profile', [$this, 'renderAdditionalUserFields'], 10, 1);
41 add_action('personal_options_update', [$this, 'saveAdditionalUserFields'], 10, 1);
42 add_action('edit_user_profile_update', [$this, 'saveAdditionalUserFields'], 10, 1);
43
44 global $pagenow;
45 if ($pagenow === 'edit-comments.php') {
46 add_filter('comment_status_links', [$this, 'commentStatusLinks'], 10, 1);
47 add_action('pre_get_comments', [$this, 'preGetComments'], 10, 1);
48 }
49
50 add_action(
51 'wp_ajax_upstream:project.get_all_items_comments',
52 ['UpStream_Metaboxes_Projects', 'fetchAllItemsComments']
53 );
54
55 add_action('cmb2_render_up_timestamp', [$this, 'renderCmb2TimestampField'], 10, 5);
56 add_action('cmb2_sanitize_up_timestamp', [$this, 'sanitizeCmb2TimestampField'], 10, 5);
57
58 add_action('cmb2_render_up_button', [$this, 'renderCmb2ButtonField'], 10, 5);
59 add_action('cmb2_sanitize_up_button', [$this, 'sanitizeCmb2ButtonField'], 10, 5);
60
61 add_action('cmb2_render_up_buttonsgroup', [$this, 'renderCmb2ButtonsGroupField'], 10, 5);
62 add_action('cmb2_sanitize_up_buttonsgroup', [$this, 'sanitizeCmb2ButtonsGroupField'], 10, 5);
63
64 add_filter('cmb2_override_option_get_upstream_general', [$this, 'filter_override_option_get_upstream_general'],
65 10, 3);
66
67 $this->framework = UpStream::instance()->get_container()['framework'];
68
69 add_action('wp_ajax_upstream.milestone-edit.editmenuorder', [$this, 'editMenuOrder']);
70
71 add_action('wp_ajax_upstream.task-edit.gettaskpercent', [$this, 'getTaskPercent']);
72 add_action('wp_ajax_upstream.task-edit.gettaskstatus', [$this, 'getTaskStatus']);
73 }
74
75 /**
76 * @since 1.24.5
77 * @static
78 */
79 public function editMenuOrder()
80 {
81 //YYYYYYYYYYYYYYY
82 /*update_metadata('post', $_REQUEST['post_id'], 'upst_order', $_REQUEST['item_val']);*/
83 $cur_post = array(
84 'ID'=> (int) $_REQUEST['post_id'],
85 'menu_order'=> (int) $_REQUEST['item_val']
86 );
87 wp_update_post( $cur_post );
88
89 return 'success';
90 }
91
92 /**
93 * @since 1.24.5
94 * @static
95 */
96 public function getTaskPercent()
97 {
98 // task IDs are alnum
99 $task_id = sanitize_text_field($_REQUEST['task_id']);
100 $cur_per = (int)$_REQUEST['cur_per'];
101
102 $option = get_option('upstream_tasks');
103 $statuses = isset($option['statuses']) ? $option['statuses'] : '';
104 if ($statuses) {
105 foreach ($statuses as $status) {
106 if ($status['id'] == $task_id) {
107 if (!empty($status['percent']) && (int)$status['percent'] > $cur_per) {
108 echo (int)$status['percent'];
109 exit;
110 } else {
111 echo (int)$cur_per;
112 exit;
113 }
114 }
115 }
116 }
117 return 0;
118 }
119
120 /**
121 * @since 1.24.5
122 * @static
123 */
124 public function getTaskStatus()
125 {
126 $task_percent = (int)sanitize_text_field( $_REQUEST['task_percent']);
127
128 $option = get_option('upstream_tasks');
129 $statuses = isset($option['statuses']) ? $option['statuses'] : '';
130 $sortArr = array();
131 $selStatus = '';
132 if ($statuses) {
133 foreach ($statuses as $status) {
134 $sortArr[$status['id']] = $status['percent'];
135 if ($task_percent == '100' && $status['percent'] == '100') {
136 echo esc_attr($status['id']);
137 exit;
138 }
139 }
140 }
141 asort($sortArr);
142 if ($sortArr) {
143 foreach ($sortArr as $id => $percent) {
144 if ($percent > $task_percent) {
145 echo esc_attr($selStatus);
146 exit;
147 }
148 $selStatus = $id;
149 }
150 }
151 return 0;
152 }
153
154 /**
155 * Filter comments for Comments.php page.
156 *
157 * @param array $query Query args array.
158 *
159 * @since 1.13.0
160 * @static
161 *
162 */
163 public static function preGetComments($query)
164 {
165 if ( ! isUserEitherManagerOrAdmin()) {
166 $user = wp_get_current_user();
167
168 if (in_array('upstream_user', $user->roles) || in_array('upstream_client_user', $user->roles)) {
169 // Limit comments visibility to projects user is participating in.
170 $allowedProjects = upstream_get_users_projects($user);
171 $query->query_vars['post__in'] = array_keys($allowedProjects);
172
173 $userCanModerateComments = user_can($user, 'moderate_comments');
174 $userCanDeleteComments = user_can($user, 'delete_project_discussion');
175
176 $query->query_vars['status'] = ['approve'];
177
178 if ($userCanModerateComments) {
179 $query->query_vars['status'][] = 'hold';
180 } elseif (empty($allowedProjects)) {
181 $query->query_vars['post__in'] = -1;
182 }
183 } else {
184 // Hide Projects comments from other user types.
185 $projects = get_posts([
186 'post_type' => 'project',
187 'post_status' => 'any',
188 'posts_per_page' => -1,
189 ]);
190
191 $ids = [];
192 foreach ($projects as $project) {
193 $ids[] = $project->ID;
194 }
195
196 $query->query_vars['post__not_in'] = $ids;
197 }
198 }
199 }
200
201 /**
202 * Set up WP-Table filters links.
203 *
204 * @param array $links Associative array of table filters.
205 *
206 * @return array $links
207 * @since 1.13.0
208 * @static
209 *
210 */
211 public static function commentStatusLinks($links)
212 {
213 if ( ! isUserEitherManagerOrAdmin()) {
214 $user = wp_get_current_user();
215
216 if (in_array('upstream_user', $user->roles) || in_array('upstream_client_user', $user->roles)) {
217 $userCanModerateComments = user_can($user, 'moderate_comments');
218 $userCanDeleteComments = user_can($user, 'delete_project_discussion');
219
220 if ( ! $userCanModerateComments) {
221 unset($links['moderated'], $links['approved'], $links['spam']);
222
223 if ( ! $userCanDeleteComments) {
224 unset($links['trash']);
225 }
226 }
227
228 $projects = upstream_get_users_projects($user);
229
230 $commentsQueryArgs = [
231 'post_type' => "project",
232 'post__in' => array_keys($projects),
233 'count' => true,
234 ];
235
236 $commentsCount = new stdClass();
237 $commentsCount->all = get_comments($commentsQueryArgs);
238
239 $links['all'] = preg_replace(
240 '/<span class="all-count">\d+<\/span>/',
241 '<span class="all-count">' . $commentsCount->all . '</span>',
242 $links['all']
243 );
244
245 if (isset($links['moderated'])) {
246 $commentsCount->approved = get_comments(array_merge(
247 $commentsQueryArgs,
248 ['status' => "approve"]
249 ));
250
251 $links['approved'] = preg_replace(
252 '/<span class="approved-count">\d+<\/span>/',
253 '<span class="approved-count">' . $commentsCount->approved . '</span>',
254 $links['approved']
255 );
256
257 $commentsCount->pending = get_comments(array_merge($commentsQueryArgs, ['status' => "hold"]));
258
259 $links['moderated'] = preg_replace(
260 '/<span class="pending-count">\d+<\/span>/',
261 '<span class="pending-count">' . $commentsCount->pending . '</span>',
262 $links['moderated']
263 );
264 }
265
266 if (isset($links['trash'])) {
267 $commentsCount->trash = get_comments(array_merge($commentsQueryArgs, ['status' => "trash"]));
268
269 $links['trash'] = preg_replace(
270 '/<span class="trash-count">\d+<\/span>/',
271 '<span class="trash-count">' . $commentsCount->trash . '</span>',
272 $links['trash']
273 );
274 }
275 } else {
276 $projects = get_posts([
277 'post_type' => "project",
278 'posts_per_page' => -1,
279 ]);
280
281 $projectsIds = [];
282 foreach ($projects as $project) {
283 $projectsIds[] = $project->ID;
284 }
285
286 $commentsQueryArgs = [
287 'post__not_in' => $projectsIds,
288 'count' => true,
289 ];
290
291 if (isset($links['all'])) {
292 $count = get_comments($commentsQueryArgs);
293 $links['all'] = preg_replace(
294 '/<span class="all-count">\d+<\/span>/',
295 '<span class="all-count">' . $count . '</span>',
296 $links['all']
297 );
298 }
299
300 if (isset($links['moderated'])) {
301 $count = get_comments(array_merge($commentsQueryArgs, ['status' => "hold"]));
302 $links['moderated'] = preg_replace(
303 '/<span class="pending-count">\d+<\/span>/',
304 '<span class="pending-count">' . $count . '</span>',
305 $links['moderated']
306 );
307 }
308
309 if (isset($links['approved'])) {
310 $count = get_comments(array_merge($commentsQueryArgs, ['status' => "approve"]));
311 $links['approved'] = preg_replace(
312 '/<span class="approved-count">\d+<\/span>/',
313 '<span class="approved-count">' . $count . '</span>',
314 $links['approved']
315 );
316 }
317
318 if (isset($links['spam'])) {
319 $count = get_comments(array_merge($commentsQueryArgs, ['status' => "spam"]));
320 $links['spam'] = preg_replace(
321 '/<span class="spam-count">\d+<\/span>/',
322 '<span class="spam-count">' . $count . '</span>',
323 $links['spam']
324 );
325 }
326
327 if (isset($links['trash'])) {
328 $count = get_comments(array_merge($commentsQueryArgs, ['status' => "trash"]));
329 $links['trash'] = preg_replace(
330 '/<span class="trash-count">\d+<\/span>/',
331 '<span class="trash-count">' . $count . '</span>',
332 $links['trash']
333 );
334 }
335 }
336 }
337
338 return $links;
339 }
340
341 /**
342 * Render a button
343 *
344 * @param \CMB2_Field $field The current CMB2_Field object.
345 * @param string $value The field value passed through the escaping filter.
346 * @param mixed $objectId The object id.
347 * @param string $objectType The type of object being handled.
348 * @param \CMB2_Types $fieldType Instance of the correspondent CMB2_Types object.
349 *
350 * @since 1.15.1
351 * @static
352 *
353 */
354 public static function renderCmb2ButtonsGroupField($field, $value, $objectId, $objectType, $fieldType)
355 {
356 $count = (int)$field->args['count'];
357
358 $html = '';
359 $selectors = [];
360
361 for ($i = 0; $i < $count; $i++) {
362 $id = $field->args['id'] . '_' . $i;
363 $selectors[] = '#' . $id;
364
365 $html .= sprintf('<button class="%s" id="%s" data-nonce="%s" data-slug="%s">%s</button>',
366 isset($field->args['class']) ? esc_attr($field->args['class']) : 'button-secondary',
367 esc_attr($id),
368 esc_attr($field->args['nonce']),
369 esc_attr($field->args['slugs'][$i]),
370 esc_html($field->args['labels'][$i]));
371
372 }
373
374 $selector = implode(', ', $selectors);
375
376 $html .= '<script>';
377 $html .= 'jQuery("' . $selector . '").on("click", function(event){event.preventDefault(); ' . $field->args['onclick'] . '});';
378 $html .= '</script>';
379
380 $html .= isset($field->args['desc']) ? '<p class="cmb2-metabox-description">' . esc_html($field->args['desc']) . '</p>' : '';
381
382 echo $html;
383 }
384
385 /**
386 * Ensure 'up_button' fills in missing button on newer CMB2.
387 *
388 * @param null $overrideValue Sanitization override value to return.
389 * @param mixed $value The actual field value.
390 * @param mixed $objectId The object id.
391 * @param string $objectType The type of object being handled.
392 * @param \CMB2_Sanitizer $sanitizer Sanitizer's instance.
393 *
394 * @return mixed
395 * @since 1.15.1
396 * @static
397 *
398 */
399 public static function sanitizeCmb2ButtonsGroupField($overrideValue, $value, $objectId, $fieldArgs, $sanitizer)
400 {
401 }
402
403 /**
404 * Render a button
405 *
406 * @param \CMB2_Field $field The current CMB2_Field object.
407 * @param string $value The field value passed through the escaping filter.
408 * @param mixed $objectId The object id.
409 * @param string $objectType The type of object being handled.
410 * @param \CMB2_Types $fieldType Instance of the correspondent CMB2_Types object.
411 *
412 * @since 1.15.1
413 * @static
414 *
415 */
416 public static function renderCmb2ButtonField($field, $value, $objectId, $objectType, $fieldType)
417 {
418
419 $html = sprintf('<button class="%s" id="%s" data-nonce="%s">%s</button>',
420 isset($field->args['class']) ? esc_attr($field->args['class']) : 'button-secondary',
421 esc_attr($field->args['id']),
422 esc_attr($field->args['nonce']),
423 esc_html($field->args['label']));
424
425 $html .= isset($field->args['desc']) ? '<p class="cmb2-metabox-description">' . esc_html($field->args['desc']) . '</p>' : '';
426
427 $selector = '#' . $field->_id();
428
429 $html .= '<script>';
430 $html .= 'jQuery("' . $selector . '").on("click", function(event){event.preventDefault(); ' . $field->args['onclick'] . '});';
431 $html .= '</script>';
432
433 echo $html;
434 }
435
436 /**
437 * Ensure 'up_button' fills in missing button on newer CMB2.
438 *
439 * @param null $overrideValue Sanitization override value to return.
440 * @param mixed $value The actual field value.
441 * @param mixed $objectId The object id.
442 * @param string $objectType The type of object being handled.
443 * @param \CMB2_Sanitizer $sanitizer Sanitizer's instance.
444 *
445 * @return mixed
446 * @since 1.15.1
447 * @static
448 *
449 */
450 public static function sanitizeCmb2ButtonField($overrideValue, $value, $objectId, $fieldArgs, $sanitizer)
451 {
452 }
453
454 /**
455 * Render a modified 'text_date_timestamp' that will always use
456 * its date's time being as 12:00:00 AM.
457 *
458 * @param \CMB2_Field $field The current CMB2_Field object.
459 * @param string $value The field value passed through the escaping filter.
460 * @param mixed $objectId The object id.
461 * @param string $objectType The type of object being handled.
462 * @param \CMB2_Types $fieldType Instance of the correspondent CMB2_Types object.
463 *
464 * @since 1.15.1
465 * @static
466 *
467 */
468 public static function renderCmb2TimestampField($field, $value, $objectId, $objectType, $fieldType)
469 {
470 echo $fieldType->text_date_timestamp();
471 }
472
473 /**
474 * Ensure 'up_timestamp' fields date's time are set to 12:00:00 AM before it is stored AS GMT/UTC.
475 *
476 * @param null $overrideValue Sanitization override value to return.
477 * @param mixed $value The actual field value.
478 * @param mixed $objectId The object id.
479 * @param string $objectType The type of object being handled.
480 * @param \CMB2_Sanitizer $sanitizer Sanitizer's instance.
481 *
482 * @return mixed
483 * @since 1.15.1
484 * @static
485 *
486 */
487 public static function sanitizeCmb2TimestampField($overrideValue, $value, $objectId, $fieldArgs, $sanitizer)
488 {
489 $value = trim((string)$value);
490
491 if (strlen($value) > 0) {
492 try {
493 $date = DateTime::createFromFormat($fieldArgs['date_format'], $value);
494
495 if ($date !== false) {
496 $date->setTime(0, 0, 0);
497 $value = (string)$date->format('U');
498 $overrideValue = $value;
499 } else {
500 $value = '';
501 }
502 } catch (\Exception $e) {
503 $value = '';
504 }
505 }
506
507 return $value;
508 }
509
510 public static function escapeCmb2TimestampField($value, $args, $field)
511 {
512 $value = (int)$value;
513 if ($value > 0) {
514 $date = new \DateTime('now');
515 $date->setTimestamp($value);
516
517 $value = $date->format($args['date_format']);
518 }
519
520 return $value;
521 }
522
523 public static function saveAdditionalUserFields($user_id)
524 {
525 if ( ! current_user_can('edit_user', $user_id)
526 || ! isset($_POST['upstream'])
527 ) {
528 return false;
529 }
530
531 $crn = isset($_POST['upstream']['comment_replies_notification']) ? sanitize_text_field($_POST['upstream']['comment_replies_notification']) : '';
532
533 if ($crn) {
534 $receiveNotifications = $crn !== 'no';
535 update_user_meta($user_id, 'upstream_comment_replies_notification', $receiveNotifications ? 'yes' : 'no');
536
537 unset($receiveNotifications);
538 }
539 }
540
541 public static function renderAdditionalUserFields($user)
542 {
543 $receiveNotifications = userCanReceiveCommentRepliesNotification($user->ID); ?>
544 <h2><?php _e('UpStream', 'upstream'); ?></h2>
545 <table class="form-table">
546 <tbody>
547 <tr>
548 <th>
549 <label for="upstream_comment_reply_notifications"><?php _e(
550 'Comment reply notifications',
551 'upstream'
552 ); ?></label>
553 </th>
554 <td>
555 <div>
556 <label>
557 <?php _e('Yes'); ?>
558 <input type="radio" name="upstream[comment_replies_notification]"
559 value="1"<?php echo $receiveNotifications ? ' checked' : ''; ?>>
560 </label>
561 <label>
562 <?php _e('No'); ?>
563 <input type="radio" name="upstream[comment_replies_notification]"
564 value="no"<?php echo $receiveNotifications ? '' : ' checked'; ?>>
565 </label>
566 </div>
567 <p class="description"><?php printf(
568 __('Whether to be notified when someone reply to your comments within %s.', 'upstream'),
569 esc_html(upstream_project_label_plural(true))
570 ); ?></p>
571 </td>
572 </tr>
573 </tbody>
574 </table>
575 <?php
576 }
577
578 /**
579 * Create id for newly added project/bugs/tasks statuses.
580 * This method is called right before field data is saved to db.
581 *
582 * @param array $value Array of the new data set.
583 * @param array $args Field arguments.
584 * @param \CMB2_Field $field The field object.
585 *
586 * @return array $value
587 * @since 1.17.0
588 * @static
589 *
590 */
591 public static function onBeforeSave($value, $args, $field)
592 {
593 if (is_array($value)) {
594 $value = self::createMissingIdsInSet($value);
595
596 $i = 0;
597 while ($i < count($value)) {
598 if (!isset($value[$i]['name'])) {
599 array_splice($value, $i, 1);
600 } else {
601 $i++;
602 }
603 }
604 }
605
606 return $value;
607 }
608
609 /**
610 * Create missing id in a rowset.
611 *
612 * @param array $rowset Data array;
613 *
614 * @return array
615 * @since 1.17.0
616 * @static
617 *
618 */
619 public static function createMissingIdsInSet($rowset)
620 {
621 if ( ! is_array($rowset)) {
622 return false;
623 }
624
625 if (count($rowset) > 0) {
626 $indexesMissingId = [];
627 $idsMap = [];
628
629 foreach ($rowset as $rowIndex => $row) {
630 if ( ! isset($row['id'])
631 || empty($row['id'])
632 ) {
633 $indexesMissingId[] = $rowIndex;
634 } else {
635 $idsMap[$row['id']] = $rowIndex;
636 }
637 }
638
639 if (count($indexesMissingId) > 0) {
640 $newIdsLength = 5;
641 $newIdsCharsPool = 'abcdefghijklmnopqrstuvwxyz0123456789';
642
643 foreach ($indexesMissingId as $rowIndex) {
644 do {
645 $id = upstreamGenerateRandomString($newIdsLength, $newIdsCharsPool);
646 } while (isset($idsMap[$id]));
647
648 $rowset[$rowIndex]['id'] = $id;
649 $idsMap[$id] = $rowIndex;
650 }
651 }
652 }
653
654 return $rowset;
655 }
656
657 /**
658 * Init the dependencies.
659 */
660 public function init()
661 {
662 do_action('alex_enable_module_upgrade', 'https://upstreamplugin.com/pricing/');
663 }
664
665 public function limitUpStreamUserAccess()
666 {
667 if (empty($_GET) || ! is_admin()) {
668 return;
669 }
670
671 $user = wp_get_current_user();
672 $userIsUpStreamUser = count(array_intersect(
673 (array)$user->roles,
674 ['administrator', 'upstream_manager']
675 )) === 0;
676
677 if ($userIsUpStreamUser) {
678 global $pagenow;
679
680 $shouldRedirect = false;
681
682 // this is checked against a known list of post types later
683 $postType = isset($_GET['post_type']) ? sanitize_text_field($_GET['post_type']) : '';
684 $isPostTypeProject = $postType === 'project';
685
686 if ($pagenow === 'edit-tags.php') {
687 if (isset($_GET['taxonomy'])
688 && sanitize_text_field($_GET['taxonomy']) === 'project_category'
689 && $isPostTypeProject
690 ) {
691 $shouldRedirect = true;
692 }
693 } elseif ($pagenow === 'post.php'
694 && $isPostTypeProject
695 ) {
696 $projectMembersList = (array)get_post_meta((int)$_GET['post'], '_upstream_project_members', true);
697 // Since he's not and Administrator nor an UpStream Manager, we need to check if he's participating in the project.
698 if ( ! in_array($user->ID, $projectMembersList)) {
699 $shouldRedirect = true;
700 }
701 } elseif ($pagenow === 'post-new.php'
702 && $isPostTypeProject
703 ) {
704 $shouldRedirect = true;
705 } elseif ($pagenow === 'edit.php'
706 && $postType === 'client'
707 ) {
708 $shouldRedirect = true;
709 }
710
711 if ($shouldRedirect) {
712 // Redirect the user to the projects list page.
713 $pagenow = 'edit.php';
714 wp_redirect(admin_url('/edit.php?post_type=project'));
715 exit;
716 }
717 }
718 }
719
720 /**
721 * Include any classes we need within admin.
722 */
723 public function includes()
724 {
725
726 // option pages
727 include_once('class-up-admin-options.php');
728 include_once('options/option-functions.php');
729
730 // metaboxes
731 include_once('class-up-admin-metaboxes.php');
732 include_once('metaboxes/metabox-functions.php');
733
734 include_once('up-enqueues.php');
735 include_once('class-up-admin-projects-menu.php');
736 include_once('class-up-admin-project-columns.php');
737 include_once('class-up-admin-client-columns.php');
738 include_once('class-up-admin-pointers.php');
739 }
740
741 /**
742 * Adds one or more classes to the body tag in the dashboard.
743 *
744 * @param String $classes Current body classes.
745 *
746 * @return String Altered body classes.
747 */
748 public function admin_body_class($classes)
749 {
750 $screen = get_current_screen();
751
752 if (in_array($screen->id, [
753 'client',
754 'edit-client',
755 'project',
756 'edit-project',
757 'edit-project_category',
758 'project_page_tasks',
759 'project_page_bugs',
760 'toplevel_page_upstream_general',
761 'upstream_page_upstream_bugs',
762 'upstream_page_upstream_tasks',
763 'upstream_page_upstream_milestones',
764 'upstream_page_upstream_clients',
765 'upstream_page_upstream_projects',
766 ])) {
767 return "$classes upstream";
768 }
769
770 return $classes;
771 }
772
773 /**
774 * Only show current users media items
775 *
776 */
777 public function filter_user_attachments($query = [])
778 {
779 $user = wp_get_current_user();
780 $roles = upstream_media_unrestricted_roles();
781
782 // Get the user's role
783 $match = array_intersect($user->roles, $roles);
784
785 // If the user's has a role selected as unrestricted, we do not filter the attachments.
786 if ( ! empty($match)) {
787 return $query;
788 }
789
790 // The user should only see its own attachments.
791 if (is_object($user) && isset($user->ID) && ! empty($user->ID)) {
792 $query['author'] = $user->ID;
793 }
794
795 return $query;
796 }
797
798 /**
799 * Override the media_comment_images option based on the current capabilities.
800 *
801 * @param string $test
802 * @param $default
803 * @param $instance
804 *
805 * @return array
806 */
807 public function filter_override_option_get_upstream_general($test, $default, $instance)
808 {
809
810 // Identify roles that has the upstream_comment_images capability.
811 $roles = array_keys(get_editable_roles());
812 $capable_roles = [];
813 foreach ($roles as $role_id) {
814 $role = get_role($role_id);
815 if ($role->has_cap('upstream_comment_images')) {
816 $capable_roles[] = $role_id;
817 }
818 }
819
820 $options = get_option('upstream_general');
821
822 $options['media_comment_images'] = $capable_roles;
823
824
825 return $options;
826 }
827 }
828
829 return new UpStream_Admin();
830