PluginProbe
Event Post / 6.1.2
Event Post v6.1.2
6.1.2 6.1.1 6.1.0 6.0.1 6.0.0 5.12.0 trunk 3.9 4.0 4.2 4.3 4.4 4.5 5.0 5.1 5.10.0 5.10.1 5.10.2 5.10.3 5.10.4 5.11.0 5.11.1 5.2 5.5 5.6 All 47 releases
event-post / inc / class-children.php

class-children.php in Event Post 6.1.2, at inc/class-children.php

641 lines 21.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Manage sub events
4 *
5 * @package event-post
6 * @version 6.1.2
7 * @since 4.3
8 */
9
10 namespace EventPost;
11
12 if ( ! defined( 'ABSPATH' ) ) exit;
13
14 $Children = new Children();
15
16 /**
17 * Manage child events
18 */
19 class Children{
20
21 var $POST_TYPE;
22
23 function __construct() {
24
25 $this->POST_TYPE = 'eventpost';
26
27 // Hook into the plugin
28
29 add_action('eventpost_getsettings_action', array(&$this, 'get_settings'), 1, 2);
30 add_action('eventpost_settings_form', array(&$this, 'settings_form'));
31 add_action('evenpost_init', array(&$this, 'init'));
32 add_action('wp_loaded', array(&$this, 'add_post_type'));
33 }
34
35 /**
36 * PHP4 constructor
37 */
38 function Children() {
39 $this->__construct();
40 }
41
42
43 /**
44 * Initialize
45 *
46 * @param object $EP
47 *
48 * @return void
49 */
50 function init($EP) {
51 // Ensure EventPost\Children is required.
52 if (!$EP->settings['children_enabled']) {
53 return;
54 }
55
56 add_filter('eventpost_retreive', array(&$this, 'retreive'));
57 add_filter('eventpost_get_items', array(&$this, 'hide_children_of_unpublished'));
58 add_filter('eventpost_get_post_types', array(&$this, 'get_post_types'));
59 add_filter('eventpost_contentbar', array(&$this, 'display_single'), 3, 2);
60
61 add_action('eventpost_add_custom_box', array(&$this, 'add_custom_box'));
62 add_filter('eventpost_add_custom_box_position', array(&$this, 'add_custom_box_position'), 1, 2);
63 add_action('admin_notices', array(&$this, 'notice'));
64 add_action('save_post', array(&$this, 'save_postdata'), 100);
65 add_action('edit_form_top', array(&$this, 'edit_form_top'), 1);
66
67 add_action('admin_post_EventPostAddChild', array(&$this, 'add_child_admin_post'));
68 add_action('admin_post_EventPostDeleteChild', array(&$this, 'delete_child_admin_post'));
69
70 add_action('wp_ajax_EventPostAddChild', array(&$this, 'add_child_ajax'));
71 add_action('wp_ajax_EventPostDeleteChild', array(&$this, 'delete_child_ajax'));
72
73 add_filter('eventpost_columns_head', array(&$this, 'columns_head'));
74 add_action('eventpost_columns_content', array(&$this, 'columns_content'), 10, 2);
75 }
76
77 /**
78 * Registers custom post-type
79 *
80 * @return void
81 */
82 function add_post_type(){
83 register_post_type(
84 $this->POST_TYPE,
85 array(
86 'label' => __("Event post",'event-post'),
87 'description' => 'Child of event posts',
88 'public' => false,
89 'publicly_queryable'=>true,
90 'show_ui' => true,
91 'show_in_menu' => false,
92 'capability_type' => 'post',
93 'hierarchical' => false,
94 'rewrite' => array('slug' => ''),
95 'taxonomies'=>get_taxonomies(),
96 'query_var' => true,
97 'has_archive' => false,
98 'supports' => array('page_attributes', 'author'),
99 'labels' => array (
100 'name' => __("Event post",'event-post'),
101 'singular_name' => __("Event post",'event-post'),
102 'menu_name' => __("Event post",'event-post'),
103 'add_new' => __('add','event-post'),
104 'add_new_item' => __('Add event child','event-post'),
105 'edit' => __('Edit','event-post'),
106 'edit_item' => __('Edit event child','event-post'),
107 'new_item' => __('New','event-post'),
108 'view' => __('View','event-post'),
109 'view_item' => __('View event child','event-post'),
110 'search_items' => __('Search event children','event-post'),
111 'not_found' => __('No event child Found','event-post'),
112 'parent' => __(' Event post Parent','event-post'),
113 )
114 )
115 );
116
117 }
118
119 /**
120 * Alter settings from eventpost_getsettings_action filter
121 *
122 * @param array reference &$ep_settings
123 * @param boolean reference &$reg_settings
124 */
125 function get_settings(&$ep_settings, &$reg_settings) {
126 if (!isset($ep_settings['children_enabled'])) {
127 $ep_settings['children_enabled'] = false;
128 $reg_settings = true;
129 }
130 elseif($ep_settings['children_enabled']==true && !in_array($this->POST_TYPE, $ep_settings['posttypes'])){
131 array_push($ep_settings['posttypes'], $this->POST_TYPE);
132 }
133 if (!isset($ep_settings['children_sync_tax'])) {
134 $ep_settings['children_sync_tax'] = false;
135 $reg_settings = true;
136 }
137 }
138
139
140 /**
141 * Add custom box
142 *
143 * @param string $post_type
144 *
145 * @global \EventPost $EventPost
146 */
147 function add_custom_box($post_type){
148 global $EventPost;
149 if($post_type==$this->POST_TYPE){
150 return;
151 }
152 add_meta_box('event_post_children', __('Children events', 'event-post'), array(&$this, 'inner_custom_box_children'), $post_type, $EventPost->settings['adminpos'], 'core');
153 }
154
155 function add_custom_box_position($position, $post_type){
156 if($post_type==$this->POST_TYPE){
157 $position = 'advanced';
158 }
159 return $position;
160 }
161
162 /**
163 * Remove self post type form global list
164 *
165 * @param array $post_types
166 *
167 * @return array
168 */
169 function get_post_types($post_types=array()){
170 unset($post_types[$this->POST_TYPE]);
171 return $post_types;
172 }
173
174 /**
175 * Delete a child
176 *
177 * @param int $child_id
178 *
179 * @return bool
180 */
181 function _delete_child($child_id){
182 $child = get_post($child_id);
183 if(!$child || $child->post_type !== $this->POST_TYPE){
184 return false;
185 }
186 return wp_delete_post( $child->ID, true );
187 }
188
189 /**
190 * Syncs a child
191 *
192 * @param int $child_id
193 *
194 * @global $EventPost
195 */
196 function _sync_child($child_id){
197 global $EventPost;
198 if (!$EventPost->settings['children_sync_tax']) {
199 return;
200 }
201 $child = get_post($child_id);
202 $taxonomies = get_object_taxonomies(get_post($child->post_parent));
203 foreach($taxonomies as $taxonomy){
204 wp_set_object_terms($child_id, wp_get_object_terms( $child->post_parent, $taxonomy, array('fields'=>'ids') ), $taxonomy);
205 }
206 }
207
208 /**
209 * Add a child
210 *
211 * @param int $post_id
212 *
213 * @global type $EventPost
214 *
215 * @return int|WP_Error The post ID on success. The value 0 or WP_Error on failure.
216 */
217 function _add_child($post_id){
218 global $EventPost;
219 if(!is_numeric($post_id)){
220 return false;
221 }
222 $parent = get_post($post_id);
223 if(!$parent || $parent->post_type === $this->POST_TYPE){
224 return false;
225 }
226
227 $id = wp_insert_post(array(
228 'post_type'=>$this->POST_TYPE,
229 'post_parent'=>$parent->ID,
230 'post_status'=>'publish',
231 'post_mime_type'=>'text/calendar',
232 ));
233
234 if(!is_numeric($id) || !$id){
235 return false;
236 }
237 if ($EventPost->settings['children_sync_tax']) {
238 $this->_sync_child($id);
239 }
240 return $id;
241 }
242
243 /**
244 * Get a child
245 *
246 * @param int $post_id
247 *
248 * @global \EventPost $EventPost
249 *
250 * @return array
251 */
252 function get($post_id){
253 global $EventPost;
254 $param = array(
255 'post_type'=>$this->POST_TYPE,
256 'post_parent'=>$post_id,
257 'post_status'=>array('publish', 'draft'),
258 'posts_per_page'=>-1
259 );
260
261 $children=array();
262 $query = new \WP_Query($param);
263 foreach($query->posts as $post){
264 array_push($children, $EventPost->retreive($post) );
265 }
266 return $children;
267 }
268
269 /**
270 * Saves a child
271 *
272 * @param int $post_id
273 *
274 * @global type $EventPost
275 *
276 * @return void
277 */
278 public function save_postdata($post_id) {
279 global $EventPost;
280 if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE){
281 return;
282 }
283 if (!$EventPost->settings['children_sync_tax']) {
284 return;
285 }
286 $children = $this->get($post_id);
287 if(count($children)){
288 foreach($children as $child){
289 $this->_sync_child($child->ID);
290 }
291 }
292 }
293
294 /**
295 * Retreive a child's details
296 *
297 * @param \WP_Post $event
298 *
299 * @return object
300 */
301 function retreive($event){
302 global $EventPost;
303 if($event->post_type == $this->POST_TYPE && $event->post_parent){
304 $event->root_ID = $event->post_parent;
305 $parent_status = get_post_status($event->post_parent);
306 if(!$parent_status || !is_post_status_viewable($parent_status)){
307 $event->post_status = $parent_status ? $parent_status : 'private';
308 return $event;
309 }
310 $parent = $EventPost->retreive($event->post_parent);
311 $event->post_title = $parent->post_title;
312 $event->permalink = $parent->permalink;
313 if(empty($parent->post_password)){
314 $event->post_content = $parent->post_content;
315 $event->description = $parent->description;
316 }
317 }
318 return $event;
319 }
320
321 /**
322 * Removes from public lists the children whose parent is not publicly readable
323 *
324 * @param array $events
325 *
326 * @return array
327 */
328 function hide_children_of_unpublished($events){
329 if(!is_array($events)){
330 return $events;
331 }
332 $post_type = $this->POST_TYPE;
333 return array_values(array_filter($events, function($event) use ($post_type){
334 return !(is_object($event) && $event->post_type === $post_type && $event->post_status !== 'publish');
335 }));
336 }
337
338
339 /* -------------------- VIEWS ----------------------- */
340
341 /**
342 * Shows notices
343 */
344 function notice(){
345 if(false == $notice = filter_input(INPUT_GET, 'eventpost_child_notice')){
346 return;
347 }
348 $notices = array(
349 'add_failed'=>array('warning', __( 'An error occured while creating a child event...', 'event-post' )),
350 'delete_success'=>array('success', __( 'Child event has been deleted', 'event-post' )),
351 'delete_failed'=>array('warning', __( 'An error occured while deleting a child event...', 'event-post' ))
352 );
353
354 if(!isset($notices[$notice])){
355 return;
356 }
357
358 ?>
359 <div class="notice-<?php echo esc_attr($notices[$notice][0]); ?>"><p><?php echo wp_kses_post($notices[$notice][1]); ?></p></div>
360 <?php
361 }
362
363 function check_admin_legitimity(){
364 if (!wp_verify_nonce((string) filter_input(INPUT_GET, 'eventpost_children_nonce'), 'eventpost_children_nonce') ){
365 wp_die(esc_html__('Invalid link', 'event-post'), '', array('response' => 403));
366 }
367 }
368
369 /**
370 * Checks that the current user is allowed to add children to a post
371 *
372 * @param int $post_id
373 *
374 * @return bool
375 */
376 function can_add_child($post_id){
377 $post_id = absint($post_id);
378 return $post_id > 0 && get_post($post_id) && current_user_can('edit_post', $post_id);
379 }
380
381 /**
382 * Checks that the current user is allowed to delete a child of a post
383 *
384 * @param int $post_id
385 * @param int $child_id
386 *
387 * @return bool
388 */
389 function can_delete_child($post_id, $child_id){
390 $child = get_post(absint($child_id));
391 return $child
392 && $child->post_type === $this->POST_TYPE
393 && (int) $child->post_parent === absint($post_id)
394 && current_user_can('edit_post', $child->post_parent)
395 && current_user_can('delete_post', $child->ID);
396 }
397
398 /**
399 * Checks nonce for AJAX requests and answers in JSON on failure
400 *
401 * @return void
402 */
403 function check_ajax_legitimity(){
404 if (!check_ajax_referer('eventpost_children_nonce', 'eventpost_children_nonce', false)) {
405 wp_send_json(array('success'=>false, 'message'=>__('Invalid link', 'event-post')), 403);
406 }
407 }
408
409 /**
410 * Triggers child add on form submission
411 *
412 * @return void
413 */
414 function add_child_admin_post(){
415 $this->check_admin_legitimity();
416
417 $post_id = absint(filter_input(INPUT_GET, 'post_id', FILTER_SANITIZE_NUMBER_INT));
418 if(!$post_id){
419 wp_die(esc_html__('No post ID given...', 'event-post'));
420 }
421 if(!$this->can_add_child($post_id)){
422 wp_die(esc_html__('Sorry, you are not allowed to edit this item.', 'event-post'), '', array('response' => 403));
423 }
424
425 if(false !== $child_id = $this->_add_child($post_id)){
426 wp_redirect(admin_url('post.php?post='.$child_id.'&action=edit&post_type=eventpost'));
427 }
428 else{
429 wp_redirect(admin_url('post.php?post='.$post_id.'&action=edit&eventpost_child_notice=add_failed'));
430 }
431 exit;
432 }
433 function add_child_ajax(){
434 $this->check_ajax_legitimity();
435
436 $post_id = absint(filter_input(INPUT_GET, 'post_id', FILTER_SANITIZE_NUMBER_INT));
437 if(!$post_id){
438 wp_send_json(array('success'=>false, 'message'=>__('No post ID given...', 'event-post')), 400);
439 }
440 if(!$this->can_add_child($post_id)){
441 wp_send_json(array('success'=>false, 'message'=>__('Sorry, you are not allowed to edit this item.', 'event-post')), 403);
442 }
443
444 if(false !== $child_id = $this->_add_child($post_id)){
445 wp_send_json(array(
446 'success'=>true,
447 'child_id'=>$child_id,
448 'edit_url'=>admin_url('post.php?post='.$child_id.'&action=edit')
449 ));
450 }
451 else{
452 wp_send_json(array(
453 'success'=>false
454 ));
455 }
456 exit;
457 }
458
459 function delete_child_admin_post(){
460 $this->check_admin_legitimity();
461 $post_id = absint(filter_input(INPUT_GET, 'post_id', FILTER_SANITIZE_NUMBER_INT));
462 if(!$post_id){
463 wp_die(esc_html__('No post ID given...', 'event-post'));
464 }
465 $child_id = absint(filter_input(INPUT_GET, 'child_id', FILTER_SANITIZE_NUMBER_INT));
466 if(!$child_id){
467 wp_die(esc_html__('No child ID given...', 'event-post'));
468 }
469 if(!$this->can_delete_child($post_id, $child_id)){
470 wp_die(esc_html__('Sorry, you are not allowed to delete this item.', 'event-post'), '', array('response' => 403));
471 }
472
473 if($this->_delete_child($child_id)){
474 wp_redirect(admin_url('post.php?post='.$post_id.'&action=edit&eventpost_child_notice=delete_success'));
475 }
476 else{
477 wp_redirect(admin_url('post.php?post='.$post_id.'&action=edit&eventpost_child_notice=delete_failed'));
478 }
479 exit;
480 }
481
482 /**
483 * Deletes a child event from an AJAX request
484 *
485 * @return void
486 */
487 function delete_child_ajax(){
488 $this->check_ajax_legitimity();
489
490 $post_id = absint(filter_input(INPUT_GET, 'post_id', FILTER_SANITIZE_NUMBER_INT));
491 $child_id = absint(filter_input(INPUT_GET, 'child_id', FILTER_SANITIZE_NUMBER_INT));
492 if(!$post_id || !$child_id){
493 wp_send_json(array('success'=>false, 'message'=>__('No child ID given...', 'event-post')), 400);
494 }
495 if(!$this->can_delete_child($post_id, $child_id)){
496 wp_send_json(array('success'=>false, 'message'=>__('Sorry, you are not allowed to delete this item.', 'event-post')), 403);
497 }
498
499 wp_send_json(array(
500 'success'=>(bool) $this->_delete_child($child_id),
501 ));
502 }
503
504 /**
505 * Settings form
506 *
507 * @param type $ep_settings
508 */
509 function settings_form($ep_settings) {
510 ?>
511 <h2><?php esc_html_e('Multi dates', 'event-post'); ?></h2>
512 <table class="form-table" id="eventpost-settings-table-children">
513 <tbody>
514 <tr>
515 <th>
516 <?php esc_html_e('Enable children events', 'event-post') ?>
517 </th>
518 <td>
519 <label for="children_enabled">
520 <input type="checkbox" name="ep_settings[children_enabled]" id="children_enabled" <?php if ($ep_settings['children_enabled'] == '1') {
521 echo esc_attr('checked');
522 } ?> value="1">
523 <?php esc_html_e('Allow event post to create children to events', 'event-post') ?>
524 </label>
525 </td>
526 </tr>
527 <tr>
528 <th>
529 <?php esc_html_e('Synchronize taxonomies', 'event-post') ?>
530 </th>
531 <td>
532 <label for="children_sync_tax">
533 <input type="checkbox" name="ep_settings[children_sync_tax]" id="children_sync_tax" <?php if ($ep_settings['children_sync_tax'] == '1') {
534 echo esc_attr('checked');
535 } ?> value="1">
536 <?php esc_html_e('Make children herit all taxonomies (categories, tags, custom taxonomies...) from the original event.', 'event-post') ?>
537 </label>
538 </td>
539 </tr>
540
541 </tbody>
542 </table><!-- #eventpost-settings-table-children -->
543 <?php
544 }
545
546 /**
547 * Edit form
548 *
549 * @param type $post
550 */
551 function edit_form_top($post){
552 if($post->post_type==$this->POST_TYPE){
553 $parent = get_post($post->post_parent);
554 ?>
555 <a href="<?php echo admin_url('post.php?post='.$parent->ID.'&action=edit'); ?>" class="button button-default">
556 <i class="dashicons dashicons-arrow-left-alt"></i>
557 <?php // translators: %s represents the parent post title ?>
558 <strong><?php printf(esc_html__('Back to %s', 'event-post'), esc_html($parent->post_title)); ?></strong>
559 </a>
560 <?php
561 }
562 }
563
564 /**
565 * Displays the children custom box
566 *
567 * @global \EventPost $EventPost
568 */
569 function inner_custom_box_children() {
570 global $EventPost;
571 wp_nonce_field('eventpost_children_nonce', 'eventpost_children_nonce');
572 $post_id = get_the_ID();
573 $children = $this->get($post_id);
574 ?>
575 <ul id="eventpost-children-list">
576 <?php foreach ($children as $child): ?>
577 <li>
578 <?php echo wp_kses($EventPost->get_singledate($child), EventPost()->kses_tags); ?>
579 <?php echo wp_kses($EventPost->get_singleloc($child), EventPost()->kses_tags); ?>
580 <a class="button button-default eventpost-children-edit" href="<?php echo admin_url('post.php?post='.$child->ID.'&action=edit'); ?>" title="<?php _e('Edit child event', 'event-post'); ?>">
581 <i class="dashicons dashicons-edit"></i>
582 </a>
583 <a class="button button-default eventpost-children-delete" href="<?php echo wp_nonce_url(admin_url('admin-post.php?action=EventPostDeleteChild&post_id='.$post_id.'&child_id='.$child->ID), 'eventpost_children_nonce', 'eventpost_children_nonce'); ?>" title="<?php _e('Delete child event', 'event-post'); ?>">
584 <i class="dashicons dashicons-trash"></i>
585 </a>
586 </li>
587 <?php endforeach; ?>
588 </ul>
589 <a class="button button-default eventpost-children-add" href="<?php echo wp_nonce_url(admin_url('admin-post.php?action=EventPostAddChild&post_id='.$post_id), 'eventpost_children_nonce', 'eventpost_children_nonce'); ?>">
590 <i class="dashicons dashicons-plus"></i>
591 <?php esc_html_e('Add child event', 'event-post'); ?>
592 </a>
593 <?php
594 }
595
596 /**
597 * Alters columns
598 *
599 * @param array $defaults
600 *
601 * @return array
602 */
603 public function columns_head($defaults) {
604 $defaults['children_events'] = __('Children events', 'event-post');
605 return $defaults;
606 }
607
608 /**
609 * Echoes content of a row in a given column
610 *
611 * @param string $column_name
612 * @param int $post_id
613 */
614 public function columns_content($column_name, $post_id) {
615 if ($column_name == 'children_events') {
616 $nb = count($this->get($post_id));
617 echo $nb ? '<p align="center">'.esc_html($nb).'</p>' : '';
618 }
619 }
620
621
622 /* -------------------------------------- FRONT -------------------------------*/
623
624 function display_single($eventbar, $event){
625 remove_filter('eventpost_contentbar', array(&$this, 'display_single'), 3, 2);
626 global $EventPost;
627 $children = $this->get($event->ID);
628 if(0 !== $count = count($children)){
629 // translators: %s other dates
630 $eventbar.='<p class="eventpost-children-text-more">'.sprintf(_n('%d other date:', '%d other dates:', $count, 'event-post'), $count).'</p>';
631 foreach($children as $child){
632 $eventbar.=$EventPost->get_single($child, 'event_single', 'single');
633 }
634 }
635 add_filter('eventpost_contentbar', array(&$this, 'display_single'), 3, 2);
636 return $eventbar;
637 }
638
639
640 }
641