PluginProbe ʕ •ᴥ•ʔ
Pods – Custom Content Types and Fields / 2.8.23.4
Pods – Custom Content Types and Fields v2.8.23.4
2.7.31.4 2.8.23.5 2.9.19.5 3.0.10.5 3.1.4.3 3.2.8.4 3.3.9.2 2.8.23.4 2.9.19.4 3.0.10.4 3.1.4.2 3.2.8.3 3.3.9.1 trunk 1.14.8 2.7.31.3 2.8.23.3 2.9.19.3 3.0.10.3 3.1.4.1 3.2.0 3.2.1 3.2.1.1 3.2.2 3.2.4 3.2.5 3.2.6 3.2.7 3.2.7.1 3.2.8 3.2.8.1 3.2.8.2 3.3.0 3.3.1 3.3.2 3.3.3 3.3.4 3.3.5 3.3.6 3.3.7 3.3.8 3.3.9
pods / tribe-common / src / Tribe / Admin / Help_Page.php
pods / tribe-common / src / Tribe / Admin Last commit date
Notice 2 weeks ago Activation_Page.php 2 weeks ago Help_Page.php 2 weeks ago Helpers.php 2 weeks ago Live_Date_Preview.php 2 weeks ago Notices.php 2 weeks ago
Help_Page.php
917 lines
1 <?php
2
3 // Don't load directly
4 if ( ! defined( 'ABSPATH' ) ) {
5 die( '-1' );
6 }
7
8 /**
9 * Class with a few helpers for the Administration Pages
10 *
11 * @since 4.0
12 *
13 */
14 class Tribe__Admin__Help_Page {
15 /**
16 * Static Singleton Factory Method
17 *
18 * @return Tribe__Admin__Help_Page
19 */
20 public static function instance() {
21 return tribe( static::class );
22 }
23
24 /**
25 * Checks if the current page is the Help one
26 *
27 * @since 4.5.7
28 *
29 * @return bool
30 */
31 public function is_current_page() {
32 return Tribe__Admin__Helpers::instance()->is_screen( 'tribe_events_page_tribe-help' ) || Tribe__Admin__Helpers::instance()->is_screen( 'settings_page_tribe-common-help-network' );
33 }
34
35 /**
36 * Register the Admin assets for the help page
37 *
38 * @since 4.9.12
39 *
40 * @return void
41 */
42 public function register_assets() {
43 $plugin = Tribe__Main::instance();
44 tribe_asset(
45 $plugin,
46 'tribe-admin-help-page',
47 'admin/help-page.js',
48 [ 'tribe-clipboard', 'tribe-common' ],
49 'admin_enqueue_scripts',
50 [
51 'conditionals' => [ $this, 'is_current_page' ],
52 'localize' => [
53 'name' => 'tribe_system_info',
54 'data' => [
55 'sysinfo_optin_nonce' => wp_create_nonce( 'sysinfo_optin_nonce' ),
56 'clipboard_btn_text' => __( 'Copy to clipboard', 'tribe-common' ),
57 'clipboard_copied_text' => __( 'System info copied', 'tribe-common' ),
58 'clipboard_fail_text' => __( 'Press "Cmd + C" to copy', 'tribe-common' ),
59 ],
60 ],
61 ]
62 );
63 }
64
65 /**
66 * Get the list of plugins
67 *
68 * @since 4.0
69 *
70 * @param string $plugin_name Should get only one plugin?
71 * @param boolean $is_active Only get active plugins?
72 * @return array
73 */
74 public function get_plugins( $plugin_name = null, $is_active = true ) {
75 $plugins = [];
76
77 $plugins['the-events-calendar'] = [
78 'name' => 'the-events-calendar',
79 'title' => esc_html__( 'The Events Calendar', 'tribe-common' ),
80 'repo' => 'https://wordpress.org/plugins/the-events-calendar/',
81 'forum' => 'https://wordpress.org/support/plugin/the-events-calendar/',
82 'stars_url' => 'https://wordpress.org/support/plugin/the-events-calendar/reviews/?filter=5',
83 'description' => esc_html__(
84 'The Events Calendar is a carefully crafted, extensible plugin that lets you easily share your events.',
85 'tribe-common'
86 ),
87 'is_active' => false,
88 'version' => null,
89 ];
90
91 if ( class_exists( 'Tribe__Events__Main' ) ) {
92 $plugins['the-events-calendar']['version'] = Tribe__Events__Main::VERSION;
93 $plugins['the-events-calendar']['is_active'] = true;
94 }
95
96 $plugins['event-tickets'] = [
97 'name' => 'event-tickets',
98 'title' => esc_html__( 'Event Tickets', 'tribe-common' ),
99 'repo' => 'https://wordpress.org/plugins/event-tickets/',
100 'forum' => 'https://wordpress.org/support/plugin/event-tickets',
101 'stars_url' => 'https://wordpress.org/support/plugin/event-tickets/reviews/?filter=5',
102 'description' => esc_html__(
103 'Events Tickets is a carefully crafted, extensible plugin that lets you easily sell tickets for your events.',
104 'tribe-common'
105 ),
106 'is_active' => false,
107 'version' => null,
108 ];
109
110 if ( class_exists( 'Tribe__Tickets__Main' ) ) {
111 $plugins['event-tickets']['version'] = Tribe__Tickets__Main::VERSION;
112 $plugins['event-tickets']['is_active'] = true;
113 }
114
115 $plugins['advanced-post-manager'] = [
116 'name' => 'advanced-post-manager',
117 'title' => esc_html__( 'Advanced Post Manager', 'tribe-common' ),
118 'repo' => 'https://wordpress.org/plugins/advanced-post-manager/',
119 'forum' => 'https://wordpress.org/support/plugin/advanced-post-manager/',
120 'stars_url' => 'https://wordpress.org/support/plugin/advanced-post-manager/reviews/?filter=5',
121 'description' => esc_html__(
122 'Turbo charge your posts admin for any custom post type with sortable filters and columns, and auto-registration of metaboxes.',
123 'tribe-common'
124 ),
125 'is_active' => false,
126 'version' => null,
127 ];
128
129 if ( class_exists( 'Tribe_APM' ) ) {
130 $plugins['advanced-post-manager']['version'] = 1;
131 $plugins['advanced-post-manager']['is_active'] = true;
132 }
133
134 $plugins = (array) apply_filters( 'tribe_help_plugins', $plugins );
135
136 // Only active ones?
137 if ( true === $is_active ) {
138 foreach ( $plugins as $key => $plugin ) {
139 if ( true !== $plugin['is_active'] ) {
140 unset( $plugins[ $key ] );
141 }
142 }
143 }
144
145 // Do the search
146 if ( is_string( $plugin_name ) ) {
147 if ( isset( $plugins[ $plugin_name ] ) ) {
148 return $plugins[ $plugin_name ];
149 } else {
150 return false;
151 }
152 } else {
153 return $plugins;
154 }
155 }
156
157 /**
158 * Get the formatted links of the possible plugins
159 *
160 * @since 4.0
161 *
162 * @param boolean $is_active Filter only active plugins
163 * @return array
164 */
165 public function get_plugin_forum_links( $is_active = true ) {
166 $plugins = $this->get_plugins( null, $is_active );
167
168 $list = [];
169 foreach ( $plugins as $plugin ) {
170 $list[] = '<a href="' . esc_url( $plugin['forum'] ) . '" target="_blank">' . $plugin['title'] . '</a>';
171 }
172
173 return $list;
174 }
175
176 /**
177 * Get the formatted text of the possible plugins
178 *
179 * @since 4.0
180 *
181 * @param boolean $is_active Filter only active plugins
182 * @return string
183 */
184 public function get_plugins_text( $is_active = true ) {
185 $plugins = array_merge( $this->get_plugins( null, $is_active ), $this->get_addons( null, $is_active, true ) );
186
187 $plugins_text = '';
188 $i = 0;
189 $count = count( $plugins );
190 foreach ( $plugins as $plugin ) {
191 $i++;
192 if ( ! isset( $plugin['is_active'] ) || $plugin['is_active'] !== $is_active ) {
193 continue;
194 }
195
196 $plugins_text .= $plugin['title'];
197
198 if ( $i === $count - 1 ) {
199 $plugins_text .= esc_html__( ' and ', 'tribe-common' );
200 } elseif ( $i !== $count ) {
201 $plugins_text .= ', ';
202 }
203 }
204
205 return $plugins_text;
206 }
207
208 /**
209 * Get the Addons
210 *
211 * @since 4.0
212 *
213 * @param string $plugin Plugin Name to filter
214 * @param string $is_active Filter if it's active
215 * @param string $is_important filter if the plugin is important
216 * @return array
217 */
218 public function get_addons( $plugin = null, $is_active = null, $is_important = null ) {
219 $addons = [];
220
221 $addons['events-calendar-pro'] = [
222 'id' => 'events-calendar-pro',
223 'title' => esc_html__( 'Events Calendar PRO', 'tribe-common' ),
224 'link' => 'http://evnt.is/dr',
225 'plugin' => [ 'the-events-calendar' ],
226 'is_active' => class_exists( 'Tribe__Events__Pro__Main' ),
227 'is_important' => true,
228 ];
229
230 $addons['eventbrite-tickets'] = [
231 'id' => 'eventbrite-tickets',
232 'title' => esc_html__( 'Eventbrite Tickets', 'tribe-common' ),
233 'link' => 'http://evnt.is/ds',
234 'plugin' => [ 'the-events-calendar' ],
235 'is_active' => class_exists( 'Tribe__Events__Tickets__Eventbrite__Main' ),
236 ];
237
238 $addons['community-events'] = [
239 'id' => 'community-events',
240 'title' => esc_html__( 'Community Events', 'tribe-common' ),
241 'link' => 'http://evnt.is/dt',
242 'plugin' => [ 'the-events-calendar' ],
243 'is_active' => class_exists( 'Tribe__Events__Community__Main' ),
244 ];
245
246 $addons['event-aggregator'] = [
247 'id' => 'event-aggregator',
248 'title' => esc_html__( 'Event Aggregator', 'tribe-common' ),
249 'link' => 'http://evnt.is/19mk',
250 'plugin' => [ 'the-events-calendar' ],
251 'is_active' => class_exists( 'Tribe__Events__Aggregator' ) && tribe(
252 'events-aggregator.main'
253 )->is_service_active(),
254 ];
255
256 $addons['events-filter-bar'] = [
257 'id' => 'events-filter-bar',
258 'title' => esc_html__( 'Filter Bar', 'tribe-common' ),
259 'link' => 'http://evnt.is/hu',
260 'plugin' => [ 'the-events-calendar' ],
261 'is_active' => class_exists( 'Tribe__Events__Filterbar__View' ),
262 ];
263
264 $addons['events-virtual'] = [
265 'id' => 'events-virtual',
266 'title' => esc_html__( 'Virtual Events', 'tribe-common' ),
267 'link' => 'http://evnt.is/1alb',
268 'plugin' => [ 'the-events-calendar' ],
269 'is_active' => class_exists( '\Tribe\Events\Virtual\Plugin' ),
270 ];
271
272 $addons['event-tickets-plus'] = [
273 'id' => 'event-tickets-plus',
274 'title' => esc_html__( 'Event Tickets Plus', 'tribe-common' ),
275 'link' => 'http://evnt.is/18wa',
276 'plugin' => [ 'event-tickets' ],
277 'is_active' => class_exists( 'Tribe__Tickets_Plus__Main' ),
278 'is_important' => true,
279 ];
280
281 $addons['event-community-tickets'] = [
282 'id' => 'event-community-tickets',
283 'title' => esc_html__( 'Community Tickets', 'tribe-common' ),
284 'link' => 'http://evnt.is/18m2',
285 'plugin' => [ 'event-tickets' ],
286 'is_active' => class_exists( 'Tribe__Events__Community__Tickets__Main' ),
287 ];
288
289 /**
290 * Filter the array of premium addons upsold on the sidebar of the Settings > Help tab
291 *
292 * @param array $addons
293 */
294 $addons = (array) apply_filters( 'tribe_help_addons', $addons );
295
296 // Should I filter something
297 if ( is_null( $plugin ) && is_null( $is_active ) && is_null( $is_important ) ) {
298 return $addons;
299 }
300
301 // Allow for easily grab the addons for a plugin
302 $filtered = [];
303 foreach ( $addons as $id => $addon ) {
304 if ( ! is_null( $plugin ) && ! in_array( $plugin, (array) $addon['plugin'] ) ) {
305 continue;
306 }
307
308 // Filter by is_active
309 if (
310 ! is_null( $is_active ) &&
311 ( ! isset( $addon['is_active'] ) || $is_active !== $addon['is_active'] )
312 ) {
313 continue;
314 }
315
316 // Filter by is_important
317 if (
318 ! is_null( $is_important ) &&
319 ( ! isset( $addon['is_important'] ) || $is_important !== $addon['is_important'] )
320 ) {
321 continue;
322 }
323
324 $filtered[ $id ] = $addon;
325 }
326
327 return $filtered;
328 }
329
330 public function is_active( $should_be_active ) {
331 $plugins = $this->get_plugins( null, true );
332 $addons = $this->get_addons( null, true );
333
334 $actives = array_merge( $plugins, $addons );
335 $is_active = [];
336
337 foreach ( $actives as $id => $active ) {
338 if ( in_array( $id, (array) $should_be_active ) ) {
339 $is_active[] = $id;
340 }
341 }
342
343 return count( array_filter( $is_active ) ) === 0 ? false : true;
344 }
345
346 /**
347 * From a Given link returns it with a GA arguments
348 *
349 * @since 4.0
350 *
351 * @param string $link An absolute or a Relative link
352 * @param boolean $relative Is the Link absolute or relative?
353 * @return string Link with the GA arguments
354 */
355 public function get_ga_link( $link = null, $relative = true ) {
356 $query_args = [
357 'utm_source' => 'helptab',
358 'utm_medium' => 'plugin-tec',
359 'utm_campaign' => 'in-app',
360 ];
361
362 if ( true === $relative ) {
363 $link = trailingslashit( Tribe__Main::$tec_url . $link );
364 }
365
366 return esc_url( add_query_arg( $query_args, $link ) );
367 }
368
369 /**
370 * Gets the Feed items from The Events Calendar's Blog
371 *
372 * @since 4.0
373 *
374 * @return array Feed Title and Link
375 */
376 public function get_feed_items() {
377 $news_rss = fetch_feed( Tribe__Main::FEED_URL );
378 $news_feed = [];
379
380 if ( ! is_wp_error( $news_rss ) ) {
381 /**
382 * Filter the maximum number of items returned from the tribe news feed
383 *
384 * @param int $max_items default 5
385 */
386 $maxitems = $news_rss->get_item_quantity( apply_filters( 'tribe_help_rss_max_items', 5 ) );
387 $rss_items = $news_rss->get_items( 0, $maxitems );
388 if ( $maxitems > 0 ) {
389 foreach ( $rss_items as $item ) {
390 $item = [
391 'title' => esc_html( $item->get_title() ),
392 'link' => esc_url( $item->get_permalink() ),
393 ];
394 $news_feed[] = $item;
395 }
396 }
397 }
398
399 return $news_feed;
400 }
401
402 /**
403 * Get the information from the Plugin API data
404 *
405 * @since 4.0
406 *
407 * @param object $plugin Plugin Object to be used
408 * @return object An object with the API data
409 */
410 private function get_plugin_api_data( $plugin = null ) {
411 if ( is_scalar( $plugin ) ) {
412 return false;
413 }
414
415 $plugin = (object) $plugin;
416
417 /**
418 * Filter the amount of time (seconds) we will keep api data to avoid too many external calls
419 * @var int
420 */
421 $timeout = apply_filters( 'tribe_help_api_data_timeout', 3 * HOUR_IN_SECONDS );
422 $transient = 'tribe_help_api_data-' . $plugin->name;
423 $data = get_transient( $transient );
424
425 if ( false === $data ) {
426 if ( ! function_exists( 'plugins_api' ) ) {
427 include_once ABSPATH . '/wp-admin/includes/plugin-install.php';
428 }
429
430 // Fetch the data
431 $data = plugins_api( 'plugin_information', [
432 'slug' => $plugin->name,
433 'is_ssl' => is_ssl(),
434 'fields' => [
435 'banners' => true,
436 'reviews' => true,
437 'downloaded' => true,
438 'active_installs' => true,
439 ],
440 ] );
441
442 if ( ! is_wp_error( $data ) ) {
443 // Format Downloaded Infomation
444 $data->downloaded = $data->downloaded ? number_format( $data->downloaded ) : _x( 'n/a', 'not available', 'tribe-common' );
445 } else {
446 // If there was a bug on the Current Request just leave
447 return false;
448 }
449
450 set_transient( $transient, $data, $timeout );
451 }
452 $data->up_to_date = ( version_compare( $plugin->version, $data->version, '<' ) ) ? esc_html__( 'You need to upgrade!', 'tribe-common' ) : esc_html__( 'You are up to date!', 'tribe-common' );
453
454 /**
455 * Filters the API data that was stored in the Transient option
456 *
457 * @var array
458 * @var object The plugin object, check `$this->get_plugins()` for more info
459 */
460 return (object) apply_filters( 'tribe_help_api_data', $data, $plugin );
461 }
462
463 /**
464 * Parses the help text from an Array to the final HTML.
465 *
466 * It is the responsibility of code calling this function to ensure proper escaping
467 * within any HTML.
468 *
469 * @since 4.0
470 *
471 * @param string|array $mixed The mixed value to create the HTML from
472 * @return string
473 */
474 public function get_content_html( $mixed = '' ) {
475 // If it's an StdObj or String it will be converted
476 $mixed = (array) $mixed;
477
478 // Loop to start the HTML
479 foreach ( $mixed as &$line ) {
480 // If we have content we use that
481 if ( isset( $line->content ) ) {
482 $line = $line->content;
483 }
484
485 if ( is_string( $line ) ) {
486 continue;
487 } elseif ( is_array( $line ) ) {
488 // Allow the developer to pass some configuration
489 if ( empty( $line['type'] ) ) {
490 $line['type'] = 'ul';
491 }
492
493 $text = '<' . $line['type'] . '>' . "\n";
494 foreach ( $line as $key => $item ) {
495 // Don't add non-numeric items (a.k.a.: configuration)
496 if ( ! is_numeric( $key ) ) {
497 continue;
498 }
499
500 // Only add List Item if is a UL or OL
501 if ( in_array( $line['type'], [ 'ul', 'ol' ] ) ) {
502 $text .= '<li>' . "\n";
503 }
504
505 $text .= $this->get_content_html( $item );
506
507 if ( in_array( $line['type'], [ 'ul', 'ol' ] ) ) {
508 $text .= '</li>' . "\n";
509 }
510 }
511 $text .= '</' . $line['type'] . '>' . "\n";
512
513 // Create the list as html instead of array
514 $line = $text;
515 }
516 }
517
518 return wpautop( implode( "\n\n", $mixed ) );
519 }
520
521 /**
522 * A Private storage for sections.
523 *
524 * @since 4.0
525 *
526 * @access private
527 * @var array
528 */
529 private $sections = [];
530
531 /**
532 * Incremented with each method call, then stored in $section->uid.
533 *
534 * Used when sorting two instances whose priorities are equal.
535 *
536 * @since 4.0
537 *
538 * @static
539 * @access protected
540 * @var int
541 */
542 protected static $section_count = 0;
543
544 /**
545 * Helper function to compare two objects by priority, ensuring sort stability via uid.
546 *
547 * @since 4.0
548 *
549 * @access protected
550 * @param object $a Object A.
551 * @param object $b Object B.
552 *
553 * @return int
554 */
555 protected function by_priority( $a, $b ) {
556 if ( ! isset( $a->priority ) || ! isset( $b->priority ) || $a->priority === $b->priority ) {
557 if ( ! isset( $a->unique_call_order ) || ! isset( $b->unique_call_order ) ) {
558 return 0;
559 } else {
560 return $a->unique_call_order > $b->unique_call_order ? 1 : -1;
561 }
562 } else {
563 return $a->priority > $b->priority ? 1 : -1;
564 }
565 }
566
567 /**
568 * Adds a new section to the Help Page
569 *
570 * @since 4.0
571 *
572 * @param string $id HTML like ID
573 * @param string $title The Title of the section, doesn't allow HTML
574 * @param integer $priority A Numeric ordering for the Section
575 * @param string $type by default only 'default' or 'box'
576 *
577 * @return object The section added
578 */
579 public function add_section( $id, $title = null, $priority = 10, $type = 'default' ) {
580 if ( empty( $id ) ) {
581 return false;
582 }
583
584 // Everytime you call this we will add this up
585 self::$section_count++;
586
587 $possible_types = (array) apply_filters( 'tribe_help_available_section_types', [ 'default', 'box' ] );
588
589 // Set a Default type
590 if ( empty( $type ) || ! in_array( $type, $possible_types ) ) {
591 $type = 'default';
592 }
593
594 // Create the section and Sanitize the values to avoid having to do it later
595 $section = (object) [
596 'id' => sanitize_html_class( $id ),
597 'title' => esc_html( $title ),
598 'priority' => absint( $priority ),
599 'type' => sanitize_html_class( $type ),
600
601 // This Method Unique count integer used for ordering with priority
602 'unique_call_order' => self::$section_count,
603
604 // Counter for ordering Content
605 'content_count' => 0,
606
607 // Setup the Base for the content to come
608 'content' => [],
609 ];
610
611 $this->sections[ $section->id ] = $section;
612
613 return $section;
614 }
615
616 /**
617 * Add a New content Item to a Help page Section
618 *
619 * @since 4.0
620 *
621 * @param string $section_id Which section this content should be assigned to
622 * @param string|array $content Item text or array of items, will be passed to `$this->get_content_html`
623 * @param integer $priority A Numeric priority
624 * @param array $arguments If you need arguments for item, they can be passed here
625 *
626 * @return object The content item added
627 */
628 public function add_section_content( $section_id, $content, $priority = 10, $arguments = [] ) {
629 $section_id = sanitize_html_class( $section_id );
630
631 // Check if the section exists
632 if ( empty( $this->sections[ $section_id ] ) ) {
633 return false;
634 }
635
636 // Make sure we have arguments as Array
637 if ( ! is_array( $arguments ) ) {
638 return false;
639 }
640
641 $section = &$this->sections[ $section_id ];
642
643 // Increment the content counter
644 $section->content_count++;
645
646 $item = (object) $arguments;
647
648 // Set the priority
649 $item->priority = absint( $priority );
650
651 // Set the uid to help ordering
652 $item->unique_call_order = $section->content_count;
653
654 // Content is not Safe, will be Sanitized on Output
655 $item->content = $content;
656
657 $section->content[] = $item;
658
659 return $item;
660 }
661
662 /**
663 * Remove a section based on the ID
664 * This method will remove any sections that are indexed at that ID on the sections array
665 * And the sections that have a propriety of `id` equals to the given $section_id argument
666 *
667 * @param string|int $section_id You can use Numeric or String indexes to search
668 * @return bool|int Returns `false` when no sections were removed and an `int` with the number of sections removed
669 */
670 public function remove_section( $section_id ) {
671 if (
672 ! isset( $this->sections[ $section_id ] ) &&
673 ! in_array( (object) [ 'id' => $section_id ], $this->sections, true )
674 ) {
675 // There are no sections to remove, so false
676 return false;
677 }
678
679 $removed = [];
680 foreach ( $this->sections as $id => $section ) {
681 if ( ! is_numeric( $id ) && ! is_numeric( $section_id ) && ! empty( $section->id ) ) {
682 if ( $section->id === $section_id ) {
683 unset( $this->sections[ $id ] );
684 // Mark that this section was removed
685 $removed[ $id ] = true;
686 }
687 } elseif ( $id === $section_id ) {
688 unset( $this->sections[ $section_id ] );
689 // Mark that this section was removed
690 $removed[ $id ] = true;
691 } else {
692 // Mark that this section was NOT removed
693 $removed[ $id ] = false;
694 }
695 }
696
697 // Count how many were removed
698 $total = count( array_filter( $removed ) );
699
700 // if Zero just return false
701 return $total === 0 ? false : $total;
702 }
703
704 /**
705 * Based on an Array of sections it render the Help Page contents
706 *
707 * @since 4.0
708 *
709 * @param boolean $print Return or Print the HTML after
710 * @return void|string
711 */
712 public function get_sections( $print = true ) {
713 /**
714 * Allow third-party sections here
715 *
716 * @var Tribe__Admin__Help_Page
717 */
718 do_action( 'tribe_help_pre_get_sections', $this );
719
720 /**
721 * Allow developers to filter all the sections at once
722 * NOTE: You should be using `tribe_help_add_sections` to add new sections or content
723 *
724 * @var array
725 */
726 $sections = apply_filters( 'tribe_help_sections', $this->sections );
727
728 if ( ! is_array( $sections ) || empty( $sections ) ) {
729 return false;
730 }
731
732 // Sort by Priority
733 uasort( $sections, [ $this, 'by_priority' ] );
734
735 $html = [];
736
737 foreach ( $sections as $index => $section ) {
738 $section = (object) $section;
739
740 // If it has no ID or Content, skip
741 if ( empty( $section->id ) || empty( $section->content ) ) {
742 continue;
743 }
744
745 // Set a Default type
746 if ( empty( $section->type ) ) {
747 $section->type = 'default';
748 }
749
750 /**
751 * Creates a way to filter a specific section based on the ID
752 *
753 * @var object
754 */
755 $section = apply_filters( 'tribe_help_section_' . $section->id, $section, $this );
756
757 // Sort by Priority
758 uasort( $section->content, [ $this, 'by_priority' ] );
759
760 $html[ $section->id . '-start' ] = '<div id="tribe-' . sanitize_html_class( $section->id ) . '" class="tribe-help-section clearfix tribe-section-type-' . sanitize_html_class( $section->type ) . '">';
761
762 if ( ! empty( $section->title ) ) {
763 $html[ $section->id . '-title' ] = '<h3 class="tribe-help-title">' . esc_html__( $section->title ) . '</h3>';
764 }
765
766 $html[ $section->id . '-content' ] = $this->get_content_html( $section->content );
767
768 $html[ $section->id . '-end' ] = '</div>';
769 }
770
771 /**
772 * Creates a way for developers to hook to the final HTML
773 * @var array $html
774 * @var array $sections
775 */
776 $html = apply_filters( 'tribe_help_sections_html', $html, $sections );
777
778 if ( true === $print ) {
779 echo implode( "\n", $html );
780 } else {
781 return $html;
782 }
783
784 }
785
786 /**
787 * Prints the Plugin box for the given plugin
788 *
789 * @since 4.0
790 *
791 * @param string $plugin Plugin Name key
792 * @return void
793 */
794 public function print_plugin_box( $plugin ) {
795 $plugin = (object) $this->get_plugins( $plugin, false );
796 $api_data = $this->get_plugin_api_data( $plugin );
797 $addons = $this->get_addons( $plugin->name );
798 $plugins = get_plugins();
799
800 if ( $api_data ) {
801 if ( ! function_exists( 'install_plugin_install_status' ) ) {
802 include_once ABSPATH . '/wp-admin/includes/plugin-install.php';
803 }
804 $status = install_plugin_install_status( $api_data );
805 $plugin_active = is_plugin_active( $status['file'] );
806 $plugin_exists = isset( $plugins[ $status['file'] ] );
807
808 if ( 'install' !== $status['status'] && ! $plugin_active ) {
809 $args = [
810 'action' => 'activate',
811 'plugin' => $status['file'],
812 'plugin_status' => 'all',
813 'paged' => 1,
814 's' => '',
815 ];
816 $activate_url = wp_nonce_url( add_query_arg( $args, 'plugins.php' ), 'activate-plugin_' . $status['file'] );
817 $link = '<a class="button" href="' . $activate_url . '" aria-label="' . esc_attr( sprintf( esc_attr__( 'Activate %s', 'tribe-common' ), $plugin->name ) ) . '">' . esc_html__( 'Activate Plugin', 'tribe-common' ) . '</a>';
818 } elseif ( 'update_available' === $status['status'] ) {
819 $args = [
820 'action' => 'upgrade-plugin',
821 'plugin' => $status['file'],
822 ];
823 $update_url = wp_nonce_url( add_query_arg( $args, 'update.php' ), 'upgrade-plugin_' . $status['file'] );
824
825 $link = '<a class="button" href="' . $update_url . '">' . esc_html__( 'Upgrade Plugin', 'tribe-common' ) . '</a>';
826 } elseif ( $plugin_exists ) {
827 $link = '<a class="button disabled">' . esc_html__( 'You are up to date!', 'tribe-common' ) . '</a>';
828 }
829 }
830
831 if ( ! isset( $link ) ) {
832 if ( $api_data ) {
833 $args = [
834 'tab' => 'plugin-information',
835 'plugin' => $plugin->name,
836 'TB_iframe' => true,
837 'width' => 772,
838 'height' => 600,
839 ];
840 $iframe_url = add_query_arg( $args, admin_url( '/plugin-install.php' ) );
841 $link = '<a class="button thickbox" href="' . $iframe_url . '" aria-label="' . esc_attr( sprintf( esc_attr__( 'Install %s', 'tribe-common' ), $plugin->name ) ) . '">' . esc_html__( 'Install Plugin', 'tribe-common' ) . '</a>';
842 } else {
843 $link = null;
844 }
845 }
846 ?>
847 <div class="tribe-help-plugin-info">
848 <h3><a href="<?php echo esc_url( $plugin->repo ); ?>" target="_blank"><?php echo esc_html( $plugin->title ); ?></a></h3>
849
850 <?php
851 if ( ! empty( $plugin->description ) && ! $plugin->is_active ) {
852 echo wpautop( $plugin->description );
853 }
854 ?>
855
856 <?php if ( $api_data ) { ?>
857 <dl>
858 <dt><?php esc_html_e( 'Latest Version:', 'tribe-common' ); ?></dt>
859 <dd><?php echo esc_html( $api_data->version ); ?></dd>
860
861 <dt><?php esc_html_e( 'Requires:', 'tribe-common' ); ?></dt>
862 <dd><?php echo esc_html__( 'WordPress ', 'tribe-common' ) . esc_html( $api_data->requires ); ?>+</dd>
863
864 <dt><?php esc_html_e( 'Active Users:', 'tribe-common' ); ?></dt>
865 <dd><?php echo esc_html( number_format( $api_data->active_installs ) ); ?>+</dd>
866
867 <dt><?php esc_html_e( 'Rating:', 'tribe-common' ); ?></dt>
868 <dd>
869 <a href="<?php echo esc_url( $plugin->stars_url ); ?>" target="_blank">
870 <?php
871 wp_star_rating( [
872 'rating' => $api_data->rating,
873 'type' => 'percent',
874 'number' => $api_data->num_ratings,
875 ] );
876 ?>
877 </a>
878 </dd>
879 </dl>
880 <?php } ?>
881
882 <?php
883 // Only show the link to the users can use it
884 if ( current_user_can( 'update_plugins' ) && current_user_can( 'install_plugins' ) ) {
885 echo $link ? '<p style="text-align: center;">' . $link . '</p>' : '';
886 }
887 ?>
888
889 <?php if ( ! empty( $addons ) ) { ?>
890 <h3><?php esc_html_e( 'Premium Add-Ons', 'tribe-common' ); ?></h3>
891 <ul class='tribe-list-addons'>
892 <?php foreach ( $addons as $addon ) {
893 $addon = (object) $addon;
894
895 if ( isset( $addon->is_active ) && $addon->is_active ) {
896 $active_title = __( 'Plugin Active', 'tribe-common' );
897 } else {
898 $active_title = __( 'Plugin Inactive', 'tribe-common' );
899 }
900
901 echo '<li title="' . esc_attr( $active_title ) . '" class="' . ( isset( $addon->is_active ) && $addon->is_active ? 'tribe-active-addon' : '' ) . '">';
902 if ( isset( $addon->link ) ) {
903 echo '<a href="' . esc_url( $addon->link ) . '" title="' . esc_attr__( 'Visit the Add-on Page', 'tribe-common' ) . '" target="_blank">';
904 }
905 echo esc_html( $addon->title );
906 if ( isset( $addon->link ) ) {
907 echo '</a>';
908 }
909 echo '</li>';
910 } ?>
911 </ul>
912 <?php } ?>
913 </div>
914 <?php
915 }
916 }
917