PluginProbe ʕ •ᴥ•ʔ
Advanced Access Manager – Access Governance for WordPress / 5.8.2
Advanced Access Manager – Access Governance for WordPress v5.8.2
6.8.4 6.8.5 6.9.0 6.9.1 6.9.10 6.9.11 6.9.12 6.9.13 6.9.14 6.9.15 6.9.16 6.9.17 6.9.18 6.9.19 6.9.2 6.9.20 6.9.21 6.9.22 6.9.23 6.9.24 6.9.25 6.9.26 6.9.27 6.9.28 6.9.29 6.9.3 6.9.30 6.9.31 6.9.32 6.9.33 6.9.34 6.9.35 6.9.36 6.9.37 6.9.38 6.9.39 6.9.4 6.9.41 6.9.42 6.9.43 6.9.44 6.9.45 6.9.46 6.9.47 6.9.48 6.9.49 6.9.5 6.9.51 6.9.6 6.9.7 6.9.8 6.9.9 7.0.0 7.0.0-alpha.6 7.0.0-alpha.7 7.0.0-beta.1 7.0.0-rc1 7.0.0-rc2 7.0.0-rc3 7.0.1 7.0.10 7.0.11 7.0.2 7.0.3 7.0.4 7.0.5 7.0.6 7.0.7 7.0.8 7.0.9 7.1.0 7.1.1 trunk 3.0 4.0 4.0.1 4.1 4.2 4.3 4.4 4.4.1 4.5 4.6 4.6.1 4.6.2 4.7 4.7.1 4.7.2 4.7.5 4.7.6 4.8 4.8.1 4.9 4.9.1 4.9.2 4.9.3 4.9.4 4.9.5 4.9.5.1 4.9.5.2 5.0 5.0.1 5.0.2 5.0.3 5.0.4 5.0.5 5.0.6 5.0.7 5.0.8 5.1 5.1.1 5.10 5.11 5.2 5.2.1 5.2.5 5.2.6 5.2.7 5.3 5.3.1 5.3.2 5.3.3 5.3.4 5.3.5 5.4 5.4.1 5.4.2 5.4.3 5.4.3.1 5.4.3.2 5.5 5.5.1 5.5.2 5.6 5.6.1 5.6.1.1 5.7 5.7.1 5.7.2 5.7.3 5.8 5.8.1 5.8.2 5.8.3 5.9 5.9.1 5.9.1.1 5.9.2 5.9.2.1 5.9.3 5.9.4 5.9.5 5.9.6 5.9.6.1 5.9.6.2 5.9.6.3 5.9.7 5.9.7.1 5.9.7.2 5.9.7.3 5.9.8 5.9.8.1 5.9.9 5.9.9.1 6.0.0 6.0.1 6.0.2 6.0.3 6.0.4 6.0.5 6.1.0 6.1.1 6.2.0 6.2.1 6.2.2 6.3.0 6.3.1 6.3.2 6.3.3 6.4.0 6.4.1 6.4.2 6.4.3 6.5.0 6.5.1 6.5.2 6.5.3 6.5.4 6.6.0 6.6.1 6.6.2 6.6.3 6.6.4 6.7.0 6.7.1 6.7.2 6.7.3 6.7.4 6.7.5 6.7.6 6.7.7 6.7.8 6.7.9 6.8.0 6.8.1 6.8.2 6.8.3
advanced-access-manager / Application / Backend / Feature / Main / Post.php
advanced-access-manager / Application / Backend / Feature / Main Last commit date
404Redirect.php 7 years ago Capability.php 7 years ago GetStarted.php 7 years ago LoginRedirect.php 7 years ago LogoutRedirect.php 7 years ago Menu.php 7 years ago Metabox.php 7 years ago Policy.php 7 years ago Post.php 7 years ago Redirect.php 7 years ago Route.php 7 years ago Toolbar.php 7 years ago Uri.php 7 years ago
Post.php
659 lines
1 <?php
2
3 /**
4 * ======================================================================
5 * LICENSE: This file is subject to the terms and conditions defined in *
6 * file 'license.txt', which is part of this source code package. *
7 * ======================================================================
8 */
9
10 /**
11 * Backend posts & pages manager
12 *
13 * @package AAM
14 * @author Vasyl Martyniuk <vasyl@vasyltech.com>
15 */
16 class AAM_Backend_Feature_Main_Post extends AAM_Backend_Feature_Abstract {
17
18 /**
19 * Get list for the table
20 *
21 * @return string
22 *
23 * @access public
24 */
25 public function getTable() {
26 $type = trim(AAM_Core_Request::request('type'));
27
28 if (empty($type)) {
29 $response = $this->retrieveTypeList();
30 } else {
31 $response = $this->retrieveTypeContent($type);
32 }
33
34 return $this->wrapTable($response);
35 }
36
37 /**
38 * Retrieve list of registered post types
39 *
40 * @return array
41 *
42 * @access protected
43 */
44 protected function retrieveTypeList() {
45 $list = $this->prepareTypeList();
46 $response = array(
47 'data' => array(),
48 'recordsTotal' => $list->total,
49 'recordsFiltered' => $list->filtered
50 );
51
52 foreach ($list->records as $type) {
53 $response['data'][] = array(
54 $type->name,
55 null,
56 'type',
57 $type->labels->name,
58 'drilldown,manage',
59 null,
60 apply_filters('aam-type-override-status', false, $type->name, AAM_Backend_Subject::getInstance())
61 );
62 }
63
64 return $response;
65 }
66
67 /**
68 *
69 * @return type
70 */
71 protected function prepareTypeList() {
72 $list = get_post_types(array(), 'objects');
73 $filtered = array();
74
75 //filters
76 $s = AAM_Core_Request::post('search.value');
77 $length = AAM_Core_Request::post('length');
78 $start = AAM_Core_Request::post('start');
79 $all = AAM_Core_Config::get('core.settings.manageHiddenPostTypes', false);
80
81 foreach (get_post_types(array(), 'objects') as $type) {
82 if (($all || $type->show_ui)
83 && (empty($s) || stripos($type->labels->name, $s) !== false)) {
84 $filtered[$type->label] = $type;
85 }
86 }
87
88 $this->getOrderDirection() === 'ASC' ? ksort($filtered) : krsort($filtered);
89
90 return (object) array(
91 'total' => count($list),
92 'filtered' => count($filtered),
93 'records' => array_slice($filtered, $start, $length)
94 );
95 }
96
97 /**
98 *
99 * @return type
100 */
101 protected function getOrderDirection() {
102 $dir = 'asc';
103 $order = AAM_Core_Request::post('order.0');
104
105 if (!empty($order['column']) && ($order['column'] === '3')) {
106 $dir = !empty($order['dir']) ? $order['dir'] : 'asc';
107 }
108
109 return strtoupper($dir);
110 }
111
112 /**
113 * Get post type children
114 *
115 * Retrieve list of all posts and terms that belong to specified post type
116 *
117 * @param string $type
118 *
119 * @return array
120 *
121 * @access protected
122 */
123 protected function retrieveTypeContent($type) {
124 $list = $this->prepareContentList($type);
125 $response = array(
126 'data' => array(),
127 'recordsTotal' => $list->total,
128 'recordsFiltered' => $list->filtered
129 );
130
131 foreach($list->records as $record) {
132 if (isset($record->ID)) { //this is post
133 $link = get_edit_post_link($record->ID, 'link');
134
135 $parent = '';
136
137 if (!empty($record->post_parent)) {
138 $p = get_post($record->post_parent);
139 $parent = (is_a($p, 'WP_Post') ? $p->post_title : '');
140 }
141
142 if (empty($parent)) {
143 $taxonomies = array_filter(
144 get_object_taxonomies($record), 'is_taxonomy_hierarchical'
145 );
146 if (!empty($taxonomies)) {
147 $terms = wp_get_object_terms(
148 $record->ID, $taxonomies, array('fields' => 'names')
149 );
150 $parent = implode(', ', $terms);
151 }
152 }
153
154 $response['data'][] = array(
155 $record->ID,
156 $link,
157 'post',
158 get_the_title($record),
159 'manage' . ($link ? ',edit' : ',no-edit'),
160 $parent,
161 AAM_Backend_Subject::getInstance()->getObject('post', $record->ID)->isOverwritten()
162 );
163 } else { //term
164 $response['data'][] = array(
165 $record->term_id . '|' . $record->taxonomy,
166 get_edit_term_link($record->term_id, $record->taxonomy),
167 'term',
168 $record->name,
169 'manage,edit',
170 rtrim($this->getParentTermList($record), '/'),
171 apply_filters(
172 'aam-term-override-status',
173 false,
174 $record->term_id . '|' . $record->taxonomy,
175 AAM_Backend_Subject::getInstance()
176 )
177 );
178 }
179 }
180
181 return $response;
182 }
183
184 /**
185 *
186 * @global type $wp_version
187 * @param type $term
188 * @return type
189 * @todo Remove when min WP version will be 4.8
190 */
191 protected function getParentTermList($term) {
192 global $wp_version;
193
194 $list = '';
195 $args = array(
196 'link' => false,
197 'format' => 'name',
198 'separator' => '/',
199 'inclusive' => false
200 );
201
202 if (version_compare($wp_version, '4.8.0') === -1) {
203 $term = get_term($term->term_id, $term->taxonomy);
204
205 foreach (array('link', 'inclusive') as $bool) {
206 $args[$bool] = wp_validate_boolean($args[$bool]);
207 }
208
209 $parents = get_ancestors($term->term_id, $term->taxonomy, 'taxonomy');
210
211 foreach (array_reverse($parents) as $term_id) {
212 $parent = get_term($term_id, $term->taxonomy);
213
214 if ($args['link']) {
215 $url = esc_url(get_term_link($parent->term_id, $term->taxonomy));
216 $list .= sprintf('<a href="%s">%s</a>', $url, $parent->name);
217 } else {
218 $list .= $parent->name;
219 }
220 $list .= $args['separator'];
221 }
222 } else {
223 $list = get_term_parents_list($term->term_id, $term->taxonomy, $args);
224 }
225
226 return $list;
227 }
228
229 /**
230 *
231 * @return type
232 */
233 protected function prepareContentList($type) {
234 $list = array();
235 //filters
236 $s = AAM_Core_Request::post('search.value');
237 $length = AAM_Core_Request::post('length');
238 $start = AAM_Core_Request::post('start');
239
240 //calculate how many term and/or posts we need to fetch
241 $paging = $this->getFetchPagination($type, $s, $start, $length);
242
243 //first retrieve all hierarchical terms that belong to Post Type
244 if ($paging['terms']) {
245 $list = $this->retrieveTermList(
246 $this->getTypeTaxonomies($type),
247 $s,
248 $paging['term_offset'],
249 $paging['terms']
250 );
251 }
252
253 //retrieve all posts
254 if ($paging['posts']) {
255 $list = array_merge(
256 $list,
257 $this->retrievePostList(
258 $type, $s, $paging['post_offset'], $paging['posts']
259 )
260 );
261 }
262
263 return (object) array(
264 'total' => $paging['total'],
265 'filtered' => $paging['total'],
266 'records' => $list
267 );
268 }
269
270 /**
271 *
272 * @param type $type
273 * @return type
274 */
275 protected function getTypeTaxonomies($type) {
276 $list = array();
277
278 foreach (get_object_taxonomies($type) as $name) {
279 if (is_taxonomy_hierarchical($name)) {
280 //get all terms that have no parent category
281 $list[] = $name;
282 }
283 }
284
285 return $list;
286 }
287
288 /**
289 *
290 * @param type $type
291 * @param type $search
292 * @param type $offset
293 * @param type $limit
294 * @return type
295 */
296 protected function getFetchPagination($type, $search, $offset, $limit) {
297 $result = array('terms' => 0, 'posts' => 0, 'term_offset' => $offset);
298
299 //get terms count
300 $taxonomy = $this->getTypeTaxonomies($type);
301
302 if (!empty($taxonomy)) {
303 $terms = get_terms(array(
304 'fields' => 'count',
305 'search' => $search,
306 'hide_empty' => false,
307 'taxonomy' => $taxonomy
308 ));
309 } else {
310 $terms = 0;
311 }
312
313 //get posts count
314 $posts = $this->getPostCount($type, $search);
315
316 if ($offset < $terms) {
317 if ($terms - $limit >= $offset) {
318 $result['terms'] = $limit;
319 } else {
320 $result['terms'] = $terms - $offset;
321 $result['posts'] = $limit - $result['terms'];
322 }
323 } else {
324 $result['posts'] = $limit;
325 }
326
327 $result['total'] = $terms + $posts;
328 $result['post_offset'] = ($offset ? $offset - $terms : 0);
329
330 return $result;
331 }
332
333 /**
334 *
335 * @global type $wpdb
336 * @param type $type
337 * @param type $search
338 * @return type
339 */
340 protected function getPostCount($type, $search) {
341 global $wpdb;
342
343 $query = "SELECT COUNT(*) AS total FROM {$wpdb->posts} ";
344 $query .= "WHERE (post_type = %s) AND (post_title LIKE %s)";
345
346 $args = array($type, "{$search}%");
347
348 foreach (get_post_stati(array( 'exclude_from_search' => true)) as $status ) {
349 $query .= " AND ({$wpdb->posts}.post_status <> %s)";
350 $args[] = $status;
351 }
352
353 return $wpdb->get_var($wpdb->prepare($query, $args));
354 }
355
356 /**
357 * Retrieve term list
358 *
359 * @param array $taxonomies
360 *
361 * @return array
362 *
363 * @access protected
364 */
365 protected function retrieveTermList($taxonomies, $search, $offset, $limit) {
366 $args = array(
367 'fields' => 'all',
368 'hide_empty' => false,
369 'search' => $search,
370 'taxonomy' => $taxonomies,
371 'offset' => $offset,
372 'number' => $limit,
373 'order' => $this->getOrderDirection()
374 );
375
376 return get_terms($args);
377 }
378
379 /**
380 *
381 * @param type $type
382 * @param type $search
383 * @param type $offset
384 * @param type $limit
385 * @return type
386 */
387 protected function retrievePostList($type, $search, $offset, $limit) {
388 return get_posts(array(
389 'post_type' => $type,
390 'category' => 0,
391 's' => $search,
392 'suppress_filters' => true,
393 'offset' => $offset,
394 'numberposts' => $limit,
395 'orderby' => 'title',
396 'order' => $this->getOrderDirection(),
397 'post_status' => 'any',
398 'fields' => 'all'
399 ));
400 }
401
402 /**
403 * Prepare response
404 *
405 * @param array $response
406 *
407 * @return string
408 *
409 * @access protected
410 */
411 protected function wrapTable($response) {
412 $response['draw'] = AAM_Core_Request::request('draw');
413
414 return wp_json_encode($response);
415 }
416
417 /**
418 * Get Post or Term access
419 *
420 * @return string
421 *
422 * @access public
423 */
424 public function getAccess() {
425 $type = trim(AAM_Core_Request::post('type'));
426 $id = AAM_Core_Request::post('id');
427 $access = $metadata = array();
428 $object = AAM_Backend_Subject::getInstance()->getObject($type, $id);
429
430 //prepare the response object
431 $bValues = array(1, '1', 0, '0', false, "false", true, "true");
432 if (is_a($object, 'AAM_Core_Object')) {
433 foreach($object->getOption() as $key => $value) {
434 if (in_array($value, $bValues, true)) {
435 $access[$key] = !empty($value);
436 } else {
437 $access[$key] = $value;
438 }
439 }
440 $metadata = array('overwritten' => $object->isOverwritten());
441 $access = apply_filters('aam-get-post-access-filter', $access, $object);
442 }
443
444 return wp_json_encode(array(
445 'access' => $access,
446 'meta' => $metadata,
447 'preview' => $this->preparePreviewValues($access)
448 ));
449 }
450
451 /**
452 *
453 * @param type $options
454 * @return type
455 */
456 protected function preparePreviewValues($options) {
457 $previews = array();
458
459 foreach($options as $option => $value) {
460 $previews[$option] = $this->getPreviewValue($option, $value);
461 }
462
463 return $previews;
464 }
465
466 /**
467 *
468 * @param type $option
469 * @param type $val
470 * @return type
471 */
472 protected function getPreviewValue($option, $val) {
473 switch($option) {
474 case 'frontend.teaser':
475 $str = wp_strip_all_tags($val);
476 if (function_exists('mb_strlen')) {
477 $preview = (mb_strlen($str) > 25 ? mb_substr($str, 0, 22) . '...' : $str);
478 } else {
479 $preview = (strlen($str) > 25 ? substr($str, 0, 22) . '...' : $str);
480 }
481 break;
482
483 case 'frontend.location':
484 if (!empty($val)) {
485 $chunks = explode('|', $val);
486 if ($chunks[0] === 'page') {
487 $preview = __('Existing Page', AAM_KEY);
488 } elseif ($chunks[0] === 'url') {
489 $preview = __('Valid URL', AAM_KEY);
490 } elseif ($chunks[0] === 'callback') {
491 $preview = __('Custom Callback', AAM_KEY);
492 }
493 }
494 break;
495
496 default:
497 $preview = apply_filters(
498 'aam-post-option-preview-filter', $val, $option
499 );
500 break;
501 }
502
503 return $preview;
504 }
505
506 /**
507 * Save post properties
508 *
509 * @return string
510 *
511 * @access public
512 */
513 public function save() {
514 $subject = AAM_Backend_Subject::getInstance();
515
516 $object = trim(AAM_Core_Request::post('object'));
517 $id = AAM_Core_Request::post('objectId', null);
518
519 $param = AAM_Core_Request::post('param');
520 $value = AAM_Core_Request::post('value');
521
522 //clear cache
523 AAM_Core_API::clearCache();
524
525 $result = $subject->save($param, $value, $object, $id);
526
527 return wp_json_encode(array(
528 'status' => ($result ? 'success' : 'failure'),
529 'value' => $value,
530 'preview' => $this->getPreviewValue($param, $value)
531 ));
532 }
533
534 /**
535 * Reset the object settings
536 *
537 * @return string
538 *
539 * @access public
540 */
541 public function reset() {
542 $type = trim(AAM_Core_Request::post('type'));
543 $id = AAM_Core_Request::post('id', 0);
544
545 $object = AAM_Backend_Subject::getInstance()->getObject($type, $id);
546 if ($object instanceof AAM_Core_Object) {
547 $result = $object->reset();
548 //clear cache
549 AAM_Core_API::clearCache();
550 } else {
551 $result = false;
552 }
553
554 return wp_json_encode(array('status' => ($result ? 'success' : 'failure')));
555 }
556
557 /**
558 * @inheritdoc
559 */
560 public static function getTemplate() {
561 return 'main/post.phtml';
562 }
563
564 /**
565 *
566 * @staticvar type $list
567 * @param type $area
568 * @return type
569 */
570 public static function getAccessOptionList($area) {
571 static $cache = null;
572
573 if (is_null($cache)) {
574 $cache = AAM_Backend_View_PostOptionList::get();
575 }
576
577 $subject = AAM_Backend_Subject::getInstance()->getUID();
578 $list = apply_filters(
579 'aam-post-access-options-filter', $cache[$area], $area
580 );
581
582 $filtered = array();
583 foreach($list as $option => $data) {
584 $add = empty($data['exclude']) || !in_array($subject, $data['exclude'], true);
585
586 if ($add) {
587 $add = empty($data['config']) || AAM_Core_Config::get($data['config'], true);
588 }
589
590 if ($add) {
591 $filtered[$option] = $data;
592 }
593 }
594
595 return $filtered;
596 }
597
598 /**
599 *
600 * @param type $renderBackButton
601 * @param type $extraClass
602 */
603 public static function renderAccessForm() {
604 ob_start();
605 require_once AAM_BASEDIR . '/Application/Backend/phtml/partial/post-access-form.phtml';
606 $content = ob_get_contents();
607 ob_end_clean();
608
609 return $content;
610 }
611
612 /**
613 *
614 * @return type
615 */
616 public static function getCurrentObject() {
617 $object = (object) array(
618 'id' => urldecode(AAM_Core_Request::request('oid')),
619 'type' => AAM_Core_Request::request('otype')
620 );
621
622 if ($object->id) {
623 if (strpos($object->id, '|') !== false) { //term
624 $part = explode('|', $object->id);
625 $object->term = get_term($part[0], $part[1]);
626 } else {
627 $object->post = get_post($object->id);
628 }
629 }
630
631 return $object;
632 }
633
634 /**
635 * Register Posts & Pages feature
636 *
637 * @return void
638 *
639 * @access public
640 */
641 public static function register() {
642 AAM_Backend_Feature::registerFeature((object) array(
643 'uid' => 'post',
644 'position' => 20,
645 'title' => __('Posts & Terms', AAM_KEY),
646 'capability' => 'aam_manage_posts',
647 'type' => 'main',
648 'subjects' => array(
649 AAM_Core_Subject_Role::UID,
650 AAM_Core_Subject_User::UID,
651 AAM_Core_Subject_Visitor::UID,
652 AAM_Core_Subject_Default::UID
653 ),
654 'option' => 'core.settings.backendAccessControl,core.settings.frontendAccessControl,core.settings.apiAccessControl',
655 'view' => __CLASS__
656 ));
657 }
658
659 }