Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 769
0.00% covered (danger)
0.00%
0 / 16
CRAP
0.00% covered (danger)
0.00%
0 / 1
Learn_Menu
0.00% covered (danger)
0.00%
0 / 768
0.00% covered (danger)
0.00%
0 / 16
15500
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 render_learn_menu
0.00% covered (danger)
0.00%
0 / 23
0.00% covered (danger)
0.00%
0 / 1
42
 set_slugs
0.00% covered (danger)
0.00%
0 / 12
0.00% covered (danger)
0.00%
0 / 1
20
 get_slug
0.00% covered (danger)
0.00%
0 / 87
0.00% covered (danger)
0.00%
0 / 1
2162
 get_override_slug
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
6
 slug_has_learn_content
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
12
 render_generic_learn_menu
0.00% covered (danger)
0.00%
0 / 60
0.00% covered (danger)
0.00%
0 / 1
156
 draw_learn_popup
0.00% covered (danger)
0.00%
0 / 44
0.00% covered (danger)
0.00%
0 / 1
110
 apply_filters_to_content
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
20
 get_content
0.00% covered (danger)
0.00%
0 / 33
0.00% covered (danger)
0.00%
0 / 1
306
 get_content_body
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
6
 get_content_urls
0.00% covered (danger)
0.00%
0 / 11
0.00% covered (danger)
0.00%
0 / 1
6
 get_image_url
0.00% covered (danger)
0.00%
0 / 5
0.00% covered (danger)
0.00%
0 / 1
12
 get_all_content
0.00% covered (danger)
0.00%
0 / 466
0.00% covered (danger)
0.00%
0 / 1
42
 get_learn_menu_container_css_classes
0.00% covered (danger)
0.00%
0 / 5
0.00% covered (danger)
0.00%
0 / 1
12
 get_learn_menu_css_classes
0.00% covered (danger)
0.00%
0 / 5
0.00% covered (danger)
0.00%
0 / 1
12
1<?php
2/**
3 * Jetpack CRM
4 * https://jetpackcrm.com
5 *
6 * Learn menus
7 *
8 * @package automattic/jetpack-crm
9 */
10
11namespace Automattic\JetpackCRM;
12
13// block direct access
14defined( 'ZEROBSCRM_PATH' ) || exit( 0 );
15
16/**
17 * Learn menu class
18 * This is a bit of a misnomer, as it really refers to the page titlebar (under the top menu).
19 */
20class Learn_Menu {
21
22    /**
23     * Current slug (which learn menu to render)
24     *
25     * @var string
26     */
27    protected $slug;
28
29    /**
30     * Current override slug (previously zbsSlug)
31     * This is used for override WP pages with JPCRM variants
32     *
33     * @var string
34     */
35    protected $override_slug;
36
37    /**
38     * Title of page
39     *
40     * @var string
41     */
42    private $page_title;
43
44    /**
45     * HTML to the left of the page header, often containing buttons
46     *
47     * @var string
48     */
49    private $left_buttons;
50
51    /**
52     * HTML to the right of the page header, often containing buttons
53     *
54     * @var string
55     */
56    private $right_buttons;
57
58    /**
59     * Whether or not to show the learn button
60     *
61     * @var bool
62     */
63    private $show_learn;
64
65    /**
66     * The learn box title
67     *
68     * @var string
69     */
70    private $learn_title;
71
72    /**
73     * The learn box content (HTML)
74     *
75     * @var string
76     */
77    private $learn_content;
78
79    /**
80     * The "learn more" link url
81     *
82     * @var string
83     */
84    private $learn_more_url;
85
86    /**
87     * The learn image url
88     *
89     * @var string
90     */
91    private $learn_image_url;
92
93    /**
94     * The learn video url
95     *
96     * @var string
97     */
98    private $learn_video_url;
99
100    /**
101     * Any extra JS to output
102     *
103     * @var string
104     */
105    private $extra_js;
106
107    /**
108     * Any extra css styles to add to the popup element
109     *
110     * @var string
111     */
112    private $popup_extra_css;
113
114    /**
115     * If $learn_video_url is provided, specify a video title here
116     *
117     * @var string
118     */
119    private $learn_video_title;
120
121    /**
122     * An icon to show before the page title
123     *
124     * @var string
125     */
126    private $icon_class;
127
128    /**
129     * The slug to use for a "back to list" link, or false if not used
130     *
131     * @var string|bool
132     */
133    private $back_slug;
134
135    /**
136     * Setup learn menu.
137     */
138    public function __construct() {
139        // set slugs
140        $this->set_slugs();
141
142        // require legacy functions
143        require_once ZEROBSCRM_INCLUDE_PATH . 'jpcrm-learn-menu-legacy-functions.php';
144    }
145
146    /**
147     * Renders a learn menu
148     */
149    public function render_learn_menu() {
150
151        // retrieve
152        $learn_menu_settings = $this->get_content( $this->slug );
153
154        if ( is_array( $learn_menu_settings ) ) {
155
156            // allow filter function for more complex operations on $learn_menu_settings
157            if ( isset( $learn_menu_settings['filter_function'] ) ) {
158                $learn_menu_settings = call_user_func( $learn_menu_settings['filter_function'], $learn_menu_settings );
159            }
160
161            // render
162
163            // adapted from `zeroBSCRM_admin_subtop_menu()`
164            // ... so there are functions to call for some learn menus, (if specified in 'output_function' attr)
165            // ... else the intention is to use `render_generic_learn_menu()` (previously `zeroBS_genericLearnMenu()`)
166
167            // if we have an `output_function` use it, else render generically
168            if ( isset( $learn_menu_settings['output_function'] ) && function_exists( $learn_menu_settings['output_function'] ) ) {
169
170                // call learn menu function
171                call_user_func( $learn_menu_settings['output_function'] );
172
173            } else {
174
175                // render generic learn menu with content
176                $this->render_generic_learn_menu(
177                    $learn_menu_settings['title'],
178                    $learn_menu_settings['left_buttons'],
179                    $learn_menu_settings['right_buttons'],
180                    $learn_menu_settings['show_learn'],
181                    $learn_menu_settings['learn_title'],
182                    $learn_menu_settings['content'],
183                    $learn_menu_settings['url'],
184                    $this->get_image_url( $learn_menu_settings['img'] ),
185                    $learn_menu_settings['video'],
186                    $learn_menu_settings['extra_js'],
187                    '',
188                    ( ! empty( $learn_menu_settings['video_title'] ) ? $learn_menu_settings['video_title'] : '' ),
189                    $learn_menu_settings['icon_class'],
190                    $learn_menu_settings['back_slug']
191                );
192            }
193        }
194
195        // for any exts to hook into (currently PayPal Sync) :)
196        do_action( 'zerobscrm-subtop-menu' ); // phpcs:ignore WordPress.NamingConventions.ValidHookName.UseUnderscores
197    }
198
199    /**
200     * Sets slug values
201     */
202    private function set_slugs() {
203
204        global $zbs;
205
206        // retrieve slug
207        $slug = $this->get_slug();
208
209        // set if legitimate
210        if ( $this->slug_has_learn_content( $slug ) ) {
211
212            // store the slug
213            $this->slug = $slug;
214
215        } else { // phpcs:ignore Generic.CodeAnalysis.EmptyStatement.DetectedElse
216
217            // error here? :thinking-face:
218
219        }
220
221        // retrieve override slug
222        $this->override_slug = $this->get_override_slug();
223
224        // Catch override slug situations
225        switch ( $this->override_slug ) {
226
227            case $zbs->slugs['zbs-new-user']:
228                $this->slug = 'teamadd';
229                break;
230
231            case $zbs->slugs['zbs-edit-user']:
232                $this->slug = 'teamedit';
233                break;
234
235        }
236    }
237
238    /**
239     * Retrieve slug
240     */
241    private function get_slug() {
242
243        global $zbs;
244
245        #} GET the page slug..
246        $slug = '';
247        if ( isset( $_GET['page'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
248            $slug = sanitize_text_field( $_GET['page'] ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended,WordPress.Security.ValidatedSanitizedInput.MissingUnslash
249        }
250
251        // HERE we set pageKey to be slug (lazy global)
252        // this is used for screenoptions, so will require you to set it wherever you want to use them (see userScreenOptions in core.php)
253        // must be exposed via zeroBS_outputScreenOptions :)
254        // note: for some 'sub pages' e.g. add-edit TYPE - this'll be appended to by functions below/above this level.
255        // ... so if this is just 'root' we can override it, otherwise, don't (default)
256        if ( $zbs->pageKey === 'root' ) { // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
257            $zbs->pageKey = $slug; // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
258        }
259
260        // Specific page checks
261        // There are instances where page checks override passed slug
262        // because they're a bit more complex logic than a slug-check
263        // (as adapted from previous setup)
264
265        // if slug is a $zbs->slug value, use the key
266        // e.g. translates `zerobscrm-dash` into `dash`
267        $core_slug_key = array_search( $slug, $zbs->slugs, true );
268        if ( ! empty( $core_slug_key ) ) {
269            $slug = $core_slug_key;
270        }
271
272        // Add edit generic
273        if ( $slug === $zbs->slugs['addedit'] || $slug === 'addedit' ) {
274
275            // if we have action, switch :)
276            if ( isset( $_GET['action'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
277
278                if ( $_GET['action'] !== 'edit' && $_GET['action'] !== 'delete' ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
279
280                    if ( isset( $_GET['zbstype'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
281
282                        $action = sanitize_text_field( $_GET['zbstype'] ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended,WordPress.Security.ValidatedSanitizedInput.MissingUnslash
283
284                        switch ( $action ) {
285
286                            case 'contact':
287                                $slug = 'viewcontact';
288                                break;
289
290                            case 'company':
291                                $slug = 'viewcompany';
292                                break;
293
294                            case 'segment':
295                                $slug = 'viewsegment';
296                                break;
297
298                            default:
299                                // no type
300                                // can default to contact. if no 'type' it'll be contact :)
301                                $slug = 'viewcontact';
302                                break;
303                        }
304                    } else {
305                        // can default to contact. if no 'type' it'll be contact :)
306                        $slug = 'viewcontact';
307                    }
308                }
309            } else {
310                $slug = 'viewcontact';
311            }
312        }
313
314        // Contacts
315        if ( zeroBSCRM_is_customer_new_page() ) {
316            $slug = 'contactnew';
317        } elseif ( zeroBSCRM_is_customer_edit_page() ) {
318            $slug = 'contactedit';
319        }
320        if ( zeroBSCRM_is_customertags_page() ) {
321            $slug = 'contacttags';
322        }
323
324        // Segments
325        if ( zeroBSCRM_is_segment_new_page() || zeroBSCRM_is_segment_new_page() ) {
326            $slug = 'segmentedit';
327        }
328
329        // Companies
330        if ( zeroBSCRM_is_company_new_page() ) {
331            $slug = 'companynew';
332        } elseif ( zeroBSCRM_is_company_edit_page() ) {
333            $slug = 'companyedit';
334        }
335        if ( zeroBSCRM_is_companytags_page() ) {
336            $slug = 'companytags';
337        }
338
339        // Quotes
340        if ( zeroBSCRM_is_quo_new_page() ) {
341            $slug = 'quotenew';
342        } elseif ( zeroBSCRM_is_quo_edit_page() ) {
343            $slug = 'quoteedit';
344        }
345        if ( zeroBSCRM_is_quotetags_page() ) {
346            $slug = 'quotetags';
347        }
348
349        // Quote Templates
350        if ( zeroBSCRM_is_quotetemplate_new_page() ) {
351            $slug = 'quotetemplatenew';
352        } elseif ( zeroBSCRM_is_quotetemplate_edit_page() ) {
353            $slug = 'quotetemplateedit';
354        }
355
356        // Invoices
357        if ( zeroBSCRM_is_invoice_new_page() ) {
358            $slug = 'invoicenew';
359        } elseif ( zeroBSCRM_is_invoice_edit_page() ) {
360            $slug = 'invoiceedit';
361        }
362        if ( zeroBSCRM_is_invoicetags_page() ) {
363            $slug = 'invoicetags';
364        }
365
366        // Transactions
367        if ( zeroBSCRM_is_transaction_new_page() ) {
368            $slug = 'transactionnew';
369        } elseif ( zeroBSCRM_is_transaction_edit_page() ) {
370            $slug = 'transactionedit';
371        }
372        if ( zeroBSCRM_is_transactiontags_page() ) {
373            $slug = 'transactiontags';
374        }
375
376        // Tasks
377        if ( zeroBSCRM_is_task_new_page() ) {
378            $slug = 'tasknew';
379        } elseif ( zeroBSCRM_is_task_edit_page() ) {
380            $slug = 'taskedit';
381        }
382
383        // Forms
384        if ( zeroBSCRM_is_form_new_page() ) {
385            $slug = 'formnew';
386        } elseif ( zeroBSCRM_is_form_edit_page() ) {
387            $slug = 'editform';
388        }
389
390        // profile page
391        if ( zeroBSCRM_is_profile_page() ) {
392            $slug = 'profile';
393        }
394
395        // generic delete page
396        if ( zeroBSCRM_is_delete_page() ) {
397            $slug = 'delete';
398        }
399
400        if ( $slug === 'email-templates' ) {
401            if ( ! empty( $_GET['zbs_template_editor'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
402                $slug = 'template-settings';
403            } elseif ( empty( $_GET['zbs_template_id'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
404                $slug = 'recent-emails';
405            }
406        }
407
408        if ( $slug === 'settings' ) {
409            $tab = ( empty( $_GET['tab'] ) ? '' : sanitize_text_field( $_GET['tab'] ) ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended,WordPress.Security.ValidatedSanitizedInput.MissingUnslash
410            if ( $tab === 'maildelivery' ) {
411                $slug = 'maildelivery';
412            } elseif ( $tab === 'mail' ) {
413                $slug = 'mail';
414            }
415        }
416
417        return $slug;
418    }
419
420    /**
421     * Retrieve override slug
422     */
423    private function get_override_slug() {
424
425        // CUSTOM slugs to affect behavior of standard WP pages
426        $override_slug = '';
427        if ( isset( $_GET['zbsslug'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
428            $override_slug = sanitize_text_field( $_GET['zbsslug'] ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended,WordPress.Security.ValidatedSanitizedInput.MissingUnslash
429        }
430
431        return $override_slug;
432    }
433
434    /**
435     * Verification of a slug
436     *
437     * @param string $slug Learn menu slug.
438     */
439    public function slug_has_learn_content( $slug ) {
440
441        if ( ! empty( $slug ) && $this->get_content( $slug ) ) {
442
443            return true;
444
445        }
446
447        return false;
448    }
449
450    /**
451     * Render generic learn menu by parameters
452     *
453     * Noting here that this is a drop-in replacement for `zeroBS_genericLearnMenu()`,
454     * so some of the params are somewhat unnecessary, but have been kept in for parity
455     *
456     * @param string $page_title The current page title.
457     * @param string $left_buttons A string to append in the 'add new x' area of learn menu (e.g. "Add new contact" button).
458     * @param string $right_buttons A string to append in the 'filter' area of learn menu (e.g. "Filtered by tag x" on a list view).
459     * @param bool   $show_learn Whether to show the learn button or not.
460     * @param string $learn_title The learn box title.
461     * @param string $learn_content The learn content html.
462     * @param string $learn_more_url The learn more link url.
463     * @param string $learn_image_url The learn image url.
464     * @param string $learn_video_url The learn video url.
465     * @param string $extra_js Any extra JS to output.
466     * @param string $popup_extra_css Any extra css styles to add to the popup element.
467     * @param string $learn_video_title If {$learn_video_url} specify a video title here.
468     * @param string $icon_class An icon to show before the page title.
469     * @param string $back_slug The slug to use for a "back to list" link.
470     */
471    public function render_generic_learn_menu(
472        $page_title = '',
473        $left_buttons = '',
474        $right_buttons = '',
475        $show_learn = true,
476        $learn_title = '',
477        $learn_content = '',
478        $learn_more_url = '',
479        $learn_image_url = '',
480        $learn_video_url = '',
481        $extra_js = '',
482        $popup_extra_css = '',
483        $learn_video_title = '',
484        $icon_class = '',
485        $back_slug = false
486    ) {
487
488        // assign params as object properties so we don't have to pass them all over the place
489        $this->page_title        = $page_title;
490        $this->left_buttons      = $left_buttons;
491        $this->right_buttons     = $right_buttons;
492        $this->show_learn        = $show_learn;
493        $this->learn_title       = $learn_title;
494        $this->learn_content     = $learn_content;
495        $this->learn_more_url    = $learn_more_url;
496        $this->learn_image_url   = $learn_image_url;
497        $this->learn_video_url   = $learn_video_url;
498        $this->extra_js          = $extra_js;
499        $this->popup_extra_css   = $popup_extra_css;
500        $this->learn_video_title = $learn_video_title;
501        $this->icon_class        = $icon_class;
502        $this->back_slug         = $back_slug;
503
504        // WL users don't see learn:
505        if ( zeroBSCRM_isWL() ) {
506            $show_learn = false;
507        }
508
509        // determine whether to show learn popup sidebar
510        if ( ! $show_learn ) {
511            $do_popup_sidebar = false;
512        } elseif ( ! empty( $learn_video_url ) ) {
513            $do_popup_sidebar = true;
514        } elseif ( ! empty( $learn_image_url ) && ! empty( $learn_more_url ) ) {
515            $do_popup_sidebar = true;
516        } else {
517            $do_popup_sidebar = false;
518        }
519
520        // js to enact learn / any custom js
521        ?>
522        <script type="text/javascript">
523            jQuery(function($){
524                <?php if ( $show_learn ) { ?>
525                    jQuery('.learn').popup({
526                        inline: false,
527                        on:'click',
528                        lastResort: 'bottom right',
529                    });
530                <?php } ?>
531                jQuery('.jpcrm-learn-popup-close').on('click',function(){
532                    jQuery('.learn').popup('hide');
533                });
534                <?php echo $extra_js . "\n"; /* phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped */ ?>
535            });
536        </script>
537        <div class="<?php echo esc_attr( $this->get_learn_menu_container_css_classes() ); ?>">
538            <?php
539            if ( $back_slug ) {
540                ?>
541                <a href="<?php echo jpcrm_esc_link( $back_slug ); /* phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped */ ?>" class="jpcrm-button transparent-bg font-14px zero-padding"><i class="fa fa-arrow-left"></i>&nbsp;<?php echo esc_html__( 'Back to list', 'zero-bs-crm' ); ?></a>
542                <?php
543            }
544            ?>
545            <div class="<?php echo esc_attr( $this->get_learn_menu_css_classes() ); ?>">
546                <div class="jpcrm-learn-menu-subdiv-75">
547                    <div class="jpcrm-learn-menu-subdiv-75">
548                        <div class="jpcrm-learn-page-title">
549                            <?php
550
551                            if ( ! empty( $icon_class ) ) {
552                                echo '<i class="' . esc_attr( $icon_class ) . ' icon"></i>';
553                            }
554                            echo esc_html( $page_title );
555                            ?>
556                        </div>
557                        <?php
558                        if ( $show_learn ) {
559                            $this->draw_learn_popup( $do_popup_sidebar );
560                        }
561                        ?>
562                    </div>
563                    <div class="jpcrm-learn-menu-subdiv-25">
564                        <?php echo ( empty( $left_buttons ) ? '' : $left_buttons ); /* phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped */ ?>
565                    </div>
566                </div>
567                <div class="jpcrm-learn-menu-subdiv-25">
568                    <?php echo ( empty( $right_buttons ) ? '' : $right_buttons ); /* phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped */ ?>
569                </div>
570            </div>
571        </div>
572        <?php
573    }
574
575    /**
576     * Draws learn menu popup.
577     *
578     * @param bool $do_popup_sidebar Determine whether there's a popup sidebar (e.g. for a video).
579     */
580    public function draw_learn_popup( $do_popup_sidebar ) {
581        global $zbs;
582
583        ?>
584        <div class="ui tiny learn button" id="learn">
585            <img class="jpcrm-info-gridicon" src="<?php echo esc_url( ZEROBSCRM_URL ); ?>i/gridicon-info.svg" />
586        </div>
587        <div class="ui special popup top left transition hidden" id="learn-pop" style="<?php echo esc_attr( $this->popup_extra_css ); ?>">
588            <div class="jpcrm-learn-popup-close"></div>
589            <div class="jpcrm-learn-container ui grid">
590                <div class="jpcrm-learn-content <?php echo ( $do_popup_sidebar ? 'ten' : 'sixteen' ); ?> wide column">
591                    <h3 class="learn-h3"><?php echo esc_html( $this->learn_title ); ?></h3>
592                    <div class="content">
593                        <?php
594
595                        // content
596                        echo $this->learn_content; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
597
598                        // learn more link
599                        if ( ! empty( $this->learn_more_url ) ) {
600                            echo '<br/><a href="' . esc_url( $this->learn_more_url ) . '" target="_blank" class="learn-more-link">' . esc_html__( 'Learn More', 'zero-bs-crm' ) .
601                            '<img class="jpcrm-external-link-icon" src="' . esc_url( ZEROBSCRM_URL ) . 'i/external-link.svg" />' .
602                            '</a>';
603                        }
604                        ?>
605                    </div>
606                </div>
607                <?php
608                // sidebar if image/video
609                if ( $do_popup_sidebar ) {
610                    ?>
611                    <div class="jpcrm-learn-sidebar six wide column">
612                        <div class="sidebar-content">
613                            <?php
614                            if ( ! empty( $this->learn_video_url ) ) {
615                                $video_thumbnail_url = jpcrm_youtube_url_to_thumbnail_url( $this->learn_video_url );
616                                ?>
617                                <div class="jpcrm-learn-popup-video">
618                                    <?php
619                                    if ( ! empty( $video_thumbnail_url ) ) {
620                                        ?>
621                                        <a href="<?php echo esc_url( $this->learn_video_url ); ?>" target="_blank"><img src="<?php echo esc_url( $video_thumbnail_url ); ?>" alt="<?php echo esc_attr( $this->learn_video_title ); ?>" class="jpcrm-video-thumbnail" /></a>
622                                        <?php
623                                    }
624                                    ?>
625                                    <br>
626                                    <?php
627                                    // show title if present
628                                    if ( ! empty( $learn_video_title ) ) {
629                                        ?>
630                                        <a href="<?php echo esc_url( $this->learn_video_url ); ?>" target="_blank"><?php echo esc_html( $this->learn_video_title ); ?></a>
631                                        <?php
632                                    }
633                                    ?>
634                                    <div class="jpcrm-learn-popup-video-cta">
635                                        <a href="<?php echo esc_url( $zbs->urls['youtube_intro_playlist'] ); ?>" target="_blank"><img src="<?php echo esc_url( ZEROBSCRM_URL ); ?>i/first-use-dash-learn-video-ico.png" alt="<?php esc_attr_e( 'View More on YouTube', 'zero-bs-crm' ); ?>" /> <?php esc_html_e( 'View More on YouTube', 'zero-bs-crm' ); ?></a>
636                                    </div>
637                                </div>
638                                <?php
639                            } elseif ( ! empty( $this->learn_image_url ) && ! empty( $this->learn_more_url ) ) {
640                                ?>
641                                <div class="jpcrm-learn-popup-image">
642                                    <a href="<?php echo esc_url( $this->learn_more_url ); ?>" target="_blank"><img src="<?php echo esc_url( $this->learn_image_url ); ?>" alt="<?php echo esc_attr( $this->learn_title ); ?>" class="jpcrm-learn-image" /></a>
643                                    <?php
644
645                                    // show title if present
646                                    if ( ! empty( $this->learn_title ) ) {
647                                        ?>
648                                        <br>
649                                        <a href="<?php echo esc_url( $this->learn_more_url ); ?>" target="_blank"><?php echo esc_html( $this->learn_title ); ?></a>
650                                        <?php
651                                    }
652
653                                    ?>
654                                    <div class="jpcrm-learn-popup-image-cta">
655                                        <a href="<?php echo esc_url( $this->learn_more_url ); ?>" target="_blank"><div class="jpcrm-learn-popup-external-link"></div> <?php esc_html_e( 'Read more', 'zero-bs-crm' ); ?></a>
656                                    </div>
657                                </div>
658                                <?php
659
660                            }
661
662                            ?>
663                        </div>
664                    </div>
665                    <?php
666                }
667                ?>
668                </div>
669        </div>
670        <?php
671    }
672
673    /**
674     * Apply filters to a learn menus content
675     *
676     * Unclear if this is used anywhere.
677     *
678     * @param string $slug A slug used in a filter name.
679     * @param array  $learn_menu_array A learn menu content array.
680     */
681    public function apply_filters_to_content( $slug, $learn_menu_array ) {
682
683        if ( ! empty( $slug ) && is_array( $learn_menu_array ) ) {
684
685            // legacy content filtering, not certain where this is used.
686            if ( isset( $learn_menu_array['content'] ) ) {
687
688                // filter
689                $learn_menu_array['content'] = apply_filters( 'zbs_learn_' . $slug . '_content', $learn_menu_array['content'] );
690            }
691        }
692
693        return $learn_menu_array;
694    }
695
696    /**
697     * Retrieve learn menu content
698     *
699     * @param string $slug Learn menu slug.
700     */
701    private function get_content( $slug ) {
702
703        global $zbs;
704
705        // retrieve full list
706        $learn_menu_content = $this->get_all_content();
707
708        // check if available
709        if ( isset( $learn_menu_content[ $slug ] ) ) {
710
711            if ( empty( $learn_menu_content[ $slug ]['title'] ) ) {
712                $learn_menu_content[ $slug ]['title'] = '';
713            }
714            if ( empty( $learn_menu_content[ $slug ]['left_buttons'] ) ) {
715                $learn_menu_content[ $slug ]['left_buttons'] = '';
716            }
717            if ( empty( $learn_menu_content[ $slug ]['right_buttons'] ) ) {
718                $learn_menu_content[ $slug ]['right_buttons'] = '';
719            }
720            if ( ! isset( $learn_menu_content[ $slug ]['show_learn'] ) || $learn_menu_content[ $slug ]['show_learn'] !== false ) {
721                $learn_menu_content[ $slug ]['show_learn'] = true;
722            }
723            if ( empty( $learn_menu_content[ $slug ]['learn_title'] ) ) {
724                $learn_menu_content[ $slug ]['learn_title'] = $learn_menu_content[ $slug ]['title'];
725            }
726            if ( empty( $learn_menu_content[ $slug ]['content'] ) ) {
727                $learn_menu_content[ $slug ]['content'] = '<p></p>';
728            }
729            if ( empty( $learn_menu_content[ $slug ]['url'] ) ) {
730                $learn_menu_content[ $slug ]['url'] = $zbs->urls['docs'];
731            }
732            if ( empty( $learn_menu_content[ $slug ]['img'] ) ) {
733                $learn_menu_content[ $slug ]['img'] = 'learn-extensions-list.png';
734            }
735            if ( empty( $learn_menu_content[ $slug ]['video'] ) ) {
736                $learn_menu_content[ $slug ]['video'] = false;
737            }
738            if ( empty( $learn_menu_content[ $slug ]['extra_js'] ) ) {
739                $learn_menu_content[ $slug ]['extra_js'] = '';
740            }
741            if ( empty( $learn_menu_content[ $slug ]['extra_css'] ) ) {
742                $learn_menu_content[ $slug ]['extra_css'] = '';
743            }
744            if ( empty( $learn_menu_content[ $slug ]['video_title'] ) ) {
745                $learn_menu_content[ $slug ]['video_title'] = '';
746            }
747            if ( empty( $learn_menu_content[ $slug ]['icon_class'] ) ) {
748                $learn_menu_content[ $slug ]['icon_class'] = '';
749            }
750            if ( empty( $learn_menu_content[ $slug ]['back_slug'] ) ) {
751                $learn_menu_content[ $slug ]['back_slug'] = false;
752            }
753
754            // return filtered content
755            return $this->apply_filters_to_content( $slug, $learn_menu_content[ $slug ] );
756        }
757        return false;
758    }
759
760    /**
761     * Retrieve learn menu ['content']
762     * (Wrapper for assisting legacty function calls in `jpcrm-learn-menu-legacy-functions.php`)
763     * Replaces `zeroBS_generateLearnContent()`
764     *
765     * @param string $slug Learn menu slug.
766     */
767    public function get_content_body( $slug ) {
768
769        $content = $this->get_content( $slug );
770
771        if ( empty( $content ) ) {
772            return false;
773        }
774
775        return $content['content'];
776    }
777
778    /**
779     * Retrieve learn menu urls
780     * (Wrapper for assisting legacty function calls in `jpcrm-learn-menu-legacy-functions.php`)
781     * Replaces `zeroBS_generateLearnLinks()`
782     *
783     * @param string $slug Learn menu slug.
784     */
785    public function get_content_urls( $slug ) {
786
787        $content_urls = array(
788            'learn' => '',
789            'img'   => '',
790            'vid'   => '',
791        );
792
793        $content = $this->get_content( $slug );
794
795        if ( ! empty( $content ) ) {
796            $content_urls['learn'] = $content['url'];
797            $content_urls['img']   = $this->get_image_url( $content['img'] );
798            $content_urls['vid']   = $content['video'];
799        }
800
801        return $content_urls;
802    }
803
804    /**
805     * Retrieve learn menu image url
806     * (Seeks to return an absolute url from either a local image filename or a full url)
807     *
808     * @param string $img_url Image url.
809     */
810    public function get_image_url( $img_url ) {
811
812        if ( empty( $img_url ) ) {
813            return '';
814        }
815
816        if ( strpos( $img_url, '/' ) ) {
817            // is probably an absolute url
818            return $img_url;
819        }
820
821        // for now return blank string
822        return '';
823    }
824
825    /**
826     * Retrieve learn menu content (using $this->slug)
827     *  This replaces a previous collection of 4~ global arrays
828     *  The array key used should either match a $zbs->slugs[] key, or be otherwise caught
829     *  by the special conditions in `get_slugs()` and `set_slugs()`
830     *
831     * The aim here is for this array to be the one source of truth for learn menus.
832     */
833    private function get_all_content() {
834
835        global $zbs;
836
837        // learn content
838        $learn_menu_array = array(
839
840            'dash'               => array(
841                'title'         => __( 'Dashboard', 'zero-bs-crm' ),
842                'url'           => 'https://jetpackcrm.com/feature/dashboard/',
843                'img'           => 'learn-dashboard.png',
844                'content'       => '<p>' . __( 'This your CRM dashboard. It shows you at a glance some key data from your CRM activity.', 'zero-bs-crm' ) . '</p><p>' . __( '<b>Sales Funnel</b> shows how effective you are at converting leads to customers.', 'zero-bs-crm' ) . '</p><p>' . __( '<b>Revenue Chart</b> shows you the overview of your transactions for the past few months.', 'zero-bs-crm' ) . '</p>',
845                'right_buttons' => '<button class="jpcrm-button transparent-bg font-14px" type="button" id="jpcrm_dash_page_options">' . esc_html__( 'Page options', 'zero-bs-crm' ) . '&nbsp;<i class="fa fa-cog"></i></button>',
846            ),
847            'managecontacts'     => array(
848                'title'           => __( 'Contacts', 'zero-bs-crm' ),
849                'url'             => 'https://jetpackcrm.com/feature/contacts/',
850                'img'             => 'learn-contact-list.png',
851                'content'         => '<p>' . __( 'Here is your contact list. It is central to your CRM. You can manage your contacts here and apply quick filters.', 'zero-bs-crm' ) . '</p><p>' . __( 'Transactions Total is how much your contact has spent with you (for approved statuses). You can choose which transaction types should be included in your settings.', 'zero-bs-crm' ) . '</p><p>' . __( 'Total Value is the total value including other transaction statuses (pending, on-hold, etc) as well as the value of any unpaid invoices.', 'zero-bs-crm' ) . '</p>',
852                'filter_function' => 'jpcrm_contactlist_learn_menu',
853            ),
854            'viewcontact'        => array(
855                'title'           => __( 'Viewing Contact', 'zero-bs-crm' ),
856                'url'             => 'https://jetpackcrm.com/feature/contacts/',
857                'img'             => 'learn-edit-contact.png',
858                'content'         => '<p>' . __( 'View Contact gives you an easy way to see your contact information in one place.', 'zero-bs-crm' ) . '</p>',
859                'back_slug'       => $zbs->slugs['managecontacts'],
860                'filter_function' => 'jpcrm_viewcontact_learn_menu',
861            ),
862            'contactnew'         => array(
863                'title'        => __( 'New Contact', 'zero-bs-crm' ),
864                'url'          => 'https://jetpackcrm.com/feature/contacts/',
865                'img'          => 'learn-import-contacts.png',
866                'content'      => '<p>' . __( 'There are plenty of ways which you can add contacts to your CRM', 'zero-bs-crm' ) . '</p><div class="ui divider"></div><p><strong>' . __( 'Adding them manually', 'zero-bs-crm' ) . '</strong> ' . __( 'You can add contacts manually. This takes time.', 'zero-bs-crm' ) . '</p><p><strong>' . __( 'Import from CSV', 'zero-bs-crm' ) . '</strong> ' . __( 'You can import via a CSV file.', 'zero-bs-crm' ) . '</p><p><strong>' . __( 'Import using our extensions', 'zero-bs-crm' ) . '</strong> ' . __( 'such as PayPal Sync, Stripe Sync or WooSync which will help get your contacts into your CRM automatically.', 'zero-bs-crm' ) . '</p>',
867                'left_buttons' => '<button class="jpcrm-button transparent-bg font-14px" type="button" id="jpcrm_page_options">' . esc_html__( 'Page options', 'zero-bs-crm' ) . '&nbsp;<i class="fa fa-cog"></i></button>',
868                'back_slug'    => $zbs->slugs['managecontacts'],
869            ),
870            'contactedit'        => array(
871                'title'           => __( 'Edit Contact', 'zero-bs-crm' ),
872                'url'             => 'https://jetpackcrm.com/feature/contacts/',
873                'img'             => 'learn-edit-contact.png',
874                'content'         => '<p>' . __( 'Keep the details of your contacts up to date.', 'zero-bs-crm' ) . '</p><p>' . __( '<strong>Key details</strong> should be kept up to date here. Your contacts email, their address, plus any additional information you want to hold on them.', 'zero-bs-crm' ) . '</p><p>' . sprintf( __( 'If the available fields below are not enough, you can add custom fields to your contacts record through the <a href="%s">custom field settings</a>', 'zero-bs-crm' ), admin_url( 'admin.php?page=' . $zbs->slugs['settings'] . '&tab=customfields' ) ) . '</p>',   // phpcs:ignore WordPress.WP.I18n.MissingTranslatorsComment
875                'back_slug'       => $zbs->slugs['managecontacts'],
876                'filter_function' => 'jpcrm_contactedit_learn_menu',
877            ),
878            'contacttags'        => array(
879                'title'       => __( 'Contact Tags', 'zero-bs-crm' ),
880                'url'         => 'https://jetpackcrm.com/feature/tags/',
881                'img'         => 'learn-contact-tags.png',
882                'video'       => 'https://www.youtube.com/watch?v=KwGh-Br_exc',
883                'video_title' => __( 'Introduction to Tags and Segments', 'zero-bs-crm' ),
884                'content'     => '<p>' . __( 'Tags are a powerful part of Jetpack CRM. You can tag your contacts and then filter or send emails based on those tags.', 'zero-bs-crm' ) . '</p><p>' . __( 'You can add as many tags as you like. Use them to keep track of important things with your contact. For example, contact has agreed to receive marketing material (or contact has opted out of marketing).', 'zero-bs-crm' ) . '</p>',
885            ),
886            'companytags'        => array(
887                'title'       => __( jpcrm_label_company() . ' Tags', 'zero-bs-crm' ), // phpcs:ignore WordPress.WP.I18n.NonSingularStringLiteralText
888                'url'         => 'https://jetpackcrm.com/feature/b2b-mode/',
889                'img'         => 'learn-company-tags.png',
890                'video'       => 'https://www.youtube.com/watch?v=KwGh-Br_exc',
891                'video_title' => __( 'Introduction to Tags and Segments', 'zero-bs-crm' ),
892                'content'     => '<p>' . __( jpcrm_label_company() . ' tags let you label your ' . jpcrm_label_company( true ) . ' for easier filtering in the ' . jpcrm_label_company() . ' list.', 'zero-bs-crm' ) . '</p><p>' . __( 'Tags help you organise your ' . jpcrm_label_company() . ' easier, expanding on just searching or filtering by status.', 'zero-bs-crm' ) . '</p>', // phpcs:ignore WordPress.WP.I18n.NonSingularStringLiteralText
893            ),
894            'sendmail'           => array(
895                'title'   => __( 'Send Email', 'zero-bs-crm' ),
896                'url'     => 'https://jetpackcrm.com/feature/system-emails/',
897                'img'     => 'learn-send-email.png',
898                'content' => '<p>' . __( 'Send your contact a single email from this page.', 'zero-bs-crm' ) . '</p><p>' . __( '<strong>Emails</strong> sent from here are logged against your contact in their Activity log', 'zero-bs-crm' ) . '</p><p><img style="max-width:90%" src="' . ZEROBSCRM_URL . 'i/learn/learn-email-activity-log.png" alt="" /></p><p>' . __( 'Emails are sent using your chosen method of delivery (wp_mail, SMTP).', 'zero-bs-crm' ) . '</p>',
899            ),
900            'viewcompany'        => array(
901                'title'           => __( 'Viewing ' . jpcrm_label_company(), 'zero-bs-crm' ), // phpcs:ignore WordPress.WP.I18n.NonSingularStringLiteralText
902                'url'             => 'https://jetpackcrm.com/feature/b2b-mode/',
903                'img'             => 'learn-new-company.png',
904                'content'         => '<p>' . __( 'View ' . jpcrm_label_company() . ' gives you an overview of the key ' . jpcrm_label_company() . ' information. Including the ability to see which contacts work at the ' . jpcrm_label_company() . ' and click into viewing the contact information easily.', 'zero-bs-crm' ) . '</p>', // phpcs:ignore WordPress.WP.I18n.NonSingularStringLiteralText
905                'back_slug'       => $zbs->slugs['managecompanies'],
906                'filter_function' => 'jpcrm_viewcompany_learn_menu',
907            ),
908            'manageformscrm'     => array(
909                'title'           => __( 'Forms', 'zero-bs-crm' ),
910                'url'             => 'https://jetpackcrm.com/feature/forms/',
911                'img'             => 'learn-forms.png',
912                'video'           => 'https://www.youtube.com/watch?v=mBPjV1KUb-w',
913                'video_title'     => __( 'All about Forms', 'zero-bs-crm' ),
914                'content'         => '<p>' . __( 'We offer built-in lead generation forms. Using these forms you can see which form is driving the most growth in your list.', 'zero-bs-crm' ) . '</p><p>' . __( 'If you want more features than the built-in forms provide, you can use our form integrations with Jetpack Contact Forms, Gravity Forms, or Contact Form 7.', 'zero-bs-crm' ) . '</p>',
915                'filter_function' => 'jpcrm_formlist_learn_menu',
916            ),
917            'editform'           => array(
918                'title'       => __( 'Edit Form', 'zero-bs-crm' ),
919                'url'         => 'https://jetpackcrm.com/feature/forms/',
920                'img'         => 'learn-forms.png',
921                'content'     => '<p>' . __( 'Each form has its views and submissions tracked.', 'zero-bs-crm' ) . '</p><p>' . __( 'The more information asked for on a form, the lower the submission rate. Only ask for what you need and keep your contact list growing fast.', 'zero-bs-crm' ) . '</p>',
922                'video'       => 'https://www.youtube.com/watch?v=mBPjV1KUb-w',
923                'video_title' => __( 'All about Forms', 'zero-bs-crm' ),
924                'back_slug'   => $zbs->slugs['manageformscrm'],
925            ),
926            'formnew'            => array(
927                'title'       => __( 'New Form', 'zero-bs-crm' ),
928                'url'         => 'https://jetpackcrm.com/feature/forms/',
929                'img'         => 'learn-forms.png',
930                'video'       => 'https://www.youtube.com/watch?v=mBPjV1KUb-w',
931                'video_title' => __( 'All about Forms', 'zero-bs-crm' ),
932                'content'     => '<p>' . __( 'Add a new form and choose your form layout.', 'zero-bs-crm' ) . '</p><p>' . __( 'Each form has its views and submissions tracked.', 'zero-bs-crm' ) . '</p><p>' . __( 'The more information asked for on a form, the lower the submission rate. Only ask for what you need and keep your contact list growing fast.', 'zero-bs-crm' ) . '</p>',
933                'back_slug'   => $zbs->slugs['manageformscrm'],
934            ),
935            'manage-tasks'       => array(
936                'title'           => __( 'Task Calendar', 'zero-bs-crm' ),
937                'url'             => 'https://jetpackcrm.com/feature/tasks/',
938                'img'             => 'learn-task-calendar.png',
939                'content'         => '<p>' . __( 'Tasks are our internal word for managing things to do related to contacts.', 'zero-bs-crm' ) . '</p><p>' . __( 'They are not intended to be a full appointment system operatable from the front end. They are useful to schedule short appointments and if using Client Portal Pro your clients can add them to their Calendar.', 'zero-bs-crm' ) . '</p>',
940                'filter_function' => 'jpcrm_taskcalendar_learn_menu',
941            ),
942            'manage-tasks-list'  => array(
943                'title'           => __( 'Task List', 'zero-bs-crm' ),
944                'url'             => 'https://jetpackcrm.com/feature/tasks/',
945                'img'             => 'learn-task-calendar.png',
946                'content'         => '<p>' . __( 'Tasks are our internal word for managing things to do related to contacts.', 'zero-bs-crm' ) . '</p><p>' . __( 'They are not intended to be a full appointment system operatable from the front end. They are useful to schedule short appointments and if using Client Portal Pro your clients can add them to their Calendar.', 'zero-bs-crm' ) . '</p>',
947                'filter_function' => 'jpcrm_tasklistview_learn_menu',
948            ),
949            'taskedit'           => array(
950                'title'           => __( 'Edit Task', 'zero-bs-crm' ),
951                'url'             => 'https://jetpackcrm.com/feature/tasks/',
952                'img'             => 'learn-task-calendar.png',
953                'content'         => '<p>' . __( 'Tasks are our internal word for managing things to do related to contacts.', 'zero-bs-crm' ) . '</p><p>' . __( 'They are not intended to be a full appointment system operatable from the front end. They are useful to schedule short appointments and if using Client Portal Pro your clients can add them to their Calendar.', 'zero-bs-crm' ) . '</p>',
954                'filter_function' => 'jpcrm_taskedit_learn_menu',
955            ),
956            'tasknew'            => array(
957                'title'           => __( 'New Task', 'zero-bs-crm' ),
958                'url'             => 'https://jetpackcrm.com/feature/tasks/',
959                'img'             => 'learn-task-calendar.png',
960                'content'         => '<p>' . __( 'Tasks are our internal word for managing things to do related to contacts.', 'zero-bs-crm' ) . '</p><p>' . __( 'They are not intended to be a full appointment system operatable from the front end. They are useful to schedule short appointments and if using Client Portal Pro your clients can add them to their Calendar.', 'zero-bs-crm' ) . '</p>',
961                'filter_function' => 'jpcrm_tasknew_learn_menu',
962            ),
963            'managequotes'       => array(
964                'title'           => __( 'Quotes', 'zero-bs-crm' ),
965                'url'             => 'https://jetpackcrm.com/feature/quotes/',
966                'img'             => 'learn-quote-list.png',
967                'content'         => '<p>' . __( 'Here is your list of quotes. You can see which quotes you have issued in the past.', 'zero-bs-crm' ) . '</p><p>' . __( 'You can also change the status of quotes in Bulk Actions by ticking a quote row.', 'zero-bs-crm' ) . '</p>',
968                'filter_function' => 'jpcrm_quotelist_learn_menu',
969            ),
970            'quotenew'           => array(
971                'title'        => __( 'New Quote', 'zero-bs-crm' ),
972                'url'          => 'https://jetpackcrm.com/feature/quotes/',
973                'img'          => 'learn-new-quote.png',
974                'content'      => '<p>' . __( 'Add a new quote here. When creating a quote you fill in the key details such as contact name and quote value. You can then choose which template should populate the quote content.', 'zero-bs-crm' ) . '</p><p>' . __( 'Templates automatically fill in the contact fields and save you time if you regularly issue similar quotes.', 'zero-bs-crm' ) . '</p>',
975                'left_buttons' => '<div id="zbs-quote-learn-nav"></div>',
976                'back_slug'    => $zbs->slugs['managequotes'],
977            ),
978            'quoteedit'          => array(
979                'title'        => __( 'Edit Quote', 'zero-bs-crm' ),
980                'url'          => 'https://jetpackcrm.com/feature/quotes/',
981                'img'          => 'learn-new-quote.png',
982                'left_buttons' => '<div id="zbs-quote-learn-nav"></div>',
983                'back_slug'    => $zbs->slugs['managequotes'],
984            ),
985            'quotetags'          => array(
986                'title'       => __( 'Quote Tags', 'zero-bs-crm' ),
987                'url'         => 'https://jetpackcrm.com/feature/quotes/',
988                'img'         => 'learn-quotes-tags.png',
989                'video'       => 'https://www.youtube.com/watch?v=KwGh-Br_exc',
990                'video_title' => __( 'Introduction to Tags and Segments', 'zero-bs-crm' ),
991                'content'     => '<p>' . __( 'Quote tags can be used to filter your quote list.', 'zero-bs-crm' ) . '</p>',
992            ),
993            'transactiontags'    => array(
994                'title'       => __( 'Transaction Tags', 'zero-bs-crm' ),
995                'url'         => 'https://jetpackcrm.com/feature/transactions/',
996                'img'         => 'learn-trans-tags.png',
997                'video'       => 'https://www.youtube.com/watch?v=KwGh-Br_exc',
998                'video_title' => __( 'Introduction to Tags and Segments', 'zero-bs-crm' ),
999                'content'     => '<p>' . __( 'Transaction tags can be used to filter your transaction list.', 'zero-bs-crm' ) . '</p><p>' . __( 'Some of our sync tools like PayPal Sync or WooSync can automatically tag the transaction with the item name. This lets you filter based on product and even feed tag-based filters in the Sales Dashboard extension.', 'zero-bs-crm' ) . '</p>',
1000            ),
1001            'transactionnew'     => array(
1002                'title'        => __( 'New Transaction', 'zero-bs-crm' ),
1003                'url'          => 'https://jetpackcrm.com/feature/transactions/',
1004                'img'          => 'learn-trans.png',
1005                'content'      => '<p>' . __( 'Adding a new transaction is easy. You should assign it to a contact and then optionally to an invoice.', 'zero-bs-crm' ) . '</p><p>' . __( 'Assigned transactions are deducted from the balance of an invoice and feed into the total value for the contact.', 'zero-bs-crm' ) . '</p><p>' . __( 'Be sure to define which transaction statuses to include in totals via the Transactions tab in CRM Settings.', 'zero-bs-crm' ) . '</p>',
1006                'left_buttons' => '<div id="zbs-transaction-learn-nav"></div>',
1007                'back_slug'    => $zbs->slugs['managetransactions'],
1008            ),
1009            'transactionedit'    => array(
1010                'title'        => __( 'Edit Transaction', 'zero-bs-crm' ),
1011                'url'          => 'https://jetpackcrm.com/feature/transactions/',
1012                'img'          => 'learn-trans.png',
1013                'content'      => '<p>' . __( 'Editing a Transaction is easy. You should assign it to a contact and then optionally to an invoice.', 'zero-bs-crm' ) . '</p><p>' . __( 'Assigned transactions are deducted from the balance of an invoice and feed into the total value for the contact.', 'zero-bs-crm' ) . '</p><p>' . __( 'Be sure to define which transaction statuses to include in totals via the Transactions tab in CRM Settings.', 'zero-bs-crm' ) . '</p>',
1014                'left_buttons' => '<div id="zbs-transaction-learn-nav"></div>',
1015                'back_slug'    => $zbs->slugs['managetransactions'],
1016            ),
1017            'managetransactions' => array(
1018                'title'           => __( 'Transactions', 'zero-bs-crm' ),
1019                'url'             => 'https://jetpackcrm.com/feature/transactions/',
1020                'img'             => 'learn-transactions-list.png',
1021                'content'         => '<p>' . __( 'Here is your transactions list. This transactions of all statuses, such as completed, refunded, cancelled, and failed. You can manage your transactions and see who has made them.', 'zero-bs-crm' ) . '</p><p>' . __( 'You can choose which transaction types should be included in totals in the Transactions tab of the CRM settings.', 'zero-bs-crm' ) . '</p>',
1022                'filter_function' => 'jpcrm_transactionlist_learn_menu',
1023            ),
1024            'quote-templates'    => array(
1025                'title'         => __( 'Quote Templates', 'zero-bs-crm' ),
1026                'url'           => 'https://jetpackcrm.com/feature/quotes/',
1027                'img'           => 'learn-quote-template.png',
1028                'content'       => '<p>' . __( 'Quote templates save you time. You can enter placeholders so that when you generate a new quote using the template, the contact fields are automatically populated.', 'zero-bs-crm' ) . '</p>',
1029                'right_buttons' => ' <a href="' . jpcrm_esc_link( 'create', -1, 'zerobs_quo_template', false ) . '" class="jpcrm-button font-14px" id="add-template">' . __( 'Add new template', 'zero-bs-crm' ) . '</a>',
1030            ),
1031            'quotetemplatenew'   => array(
1032                'title'     => __( 'New Quote Template', 'zero-bs-crm' ),
1033                'url'       => 'https://jetpackcrm.com/feature/quotes/',
1034                'img'       => 'learn-quote-templates.png',
1035                'content'   => '<p>' . __( 'A quote template is where you should populate all the business information when putting together a proposal or quote for your services.', 'zero-bs-crm' ) . '</p><p>' . __( 'Templates save time, since in new quotes you can just edit any price information and be up and running in seconds vs. typing out all the details again.', 'zero-bs-crm' ) . '</p>',
1036                'back_slug' => $zbs->slugs['quote-templates'],
1037            ),
1038            'quotetemplateedit'  => array(
1039                'title'     => __( 'Edit Quote Template', 'zero-bs-crm' ),
1040                'url'       => 'https://jetpackcrm.com/feature/quotes/',
1041                'img'       => 'learn-quote-templates.png',
1042                'content'   => '<p>' . __( 'A quote template is where you should populate all the business information when putting together a proposal or quote for your services.', 'zero-bs-crm' ) . '</p><p>' . __( 'Templates save time, since in new quotes you can just edit any price information and be up and running in seconds vs. typing out all the details again.', 'zero-bs-crm' ) . '</p>',
1043                'back_slug' => $zbs->slugs['quote-templates'],
1044            ),
1045            'manageinvoices'     => array(
1046                'title'           => __( 'Invoices', 'zero-bs-crm' ),
1047                'url'             => 'https://jetpackcrm.com/feature/invoices/',
1048                'img'             => 'learn-invoice-list.png',
1049                'content'         => '<p>' . __( 'Here is your Invoice List. It shows you all your invoices. You can search and filter the list to find the invoices you want.', 'zero-bs-crm' ) . '</p>',
1050                'filter_function' => 'jpcrm_invoicelist_learn_menu',
1051            ),
1052            'invoicenew'         => array(
1053                'title'           => __( 'New Invoice', 'zero-bs-crm' ),
1054                'url'             => 'https://jetpackcrm.com/feature/invoices/',
1055                'img'             => 'learn-new-invoice.png',
1056                'content'         => '<p>' . __( 'Having invoices in your CRM is a great way to keep contacts and payments together.', 'zero-bs-crm' ) . '</p><p>' . __( 'Do you want to provide PDF invoices to your clients? Simple. Choose the PDF option and download your invoices as PDF.', 'zero-bs-crm' ) . '</p><p>' . __( 'The real power of invoicing comes when you allow your invoices to be accessed and paid straight from your client portal using Invoicing Pro.', 'zero-bs-crm' ) . '</p>',
1057                'left_buttons'    => '<div id="zbs-invoice-learn-nav"></div>',
1058                'back_slug'       => $zbs->slugs['manageinvoices'],
1059                'filter_function' => 'jpcrm_invoicenew_learn_menu',
1060            ),
1061            'invoiceedit'        => array(
1062                'title'           => __( 'Edit Invoice', 'zero-bs-crm' ),
1063                'url'             => 'https://jetpackcrm.com/feature/invoices/',
1064                'img'             => 'learn-invoice-list.png',
1065                'content'         => '<p>' . __( 'Having invoices in your CRM is a great way to keep contacts and payments together.', 'zero-bs-crm' ) . '</p><p>' . __( 'Do you want to provide PDF invoices to your clients? Simple. Choose the PDF option and download your invoices as PDF.', 'zero-bs-crm' ) . '</p><p>' . __( 'The real power of invoicing comes when you allow your invoices to be accessed and paid straight from your client portal using Invoicing Pro.', 'zero-bs-crm' ) . '</p>',
1066                'left_buttons'    => '<div id="zbs-invoice-learn-nav"></div>',
1067                'back_slug'       => $zbs->slugs['manageinvoices'],
1068                'filter_function' => 'jpcrm_invoiceedit_learn_menu',
1069            ),
1070            'invoicetags'        => array(
1071                'title'       => __( 'Invoice Tags', 'zero-bs-crm' ),
1072                'url'         => 'https://jetpackcrm.com/feature/invoices/',
1073                'img'         => 'learn-invoices-tags.png',
1074                'video'       => 'https://www.youtube.com/watch?v=KwGh-Br_exc',
1075                'video_title' => __( 'Introduction to Tags and Segments', 'zero-bs-crm' ),
1076                'content'     => '<p>' . __( 'Invoice tags can be used to filter your invoice list.', 'zero-bs-crm' ) . '</p>',
1077            ),
1078            'team'               => array(
1079                'title'   => __( 'Your Team', 'zero-bs-crm' ),
1080                'url'     => 'https://jetpackcrm.com/feature/team/',
1081                'img'     => 'learn-zbs-team.png',
1082                'content' => '<p>' . __( 'Here is your CRM team. You can see what role your team members have and when they were last active.', 'zero-bs-crm' ) . '</p>',
1083            ),
1084            'teamadd'            => array(
1085                'title'   => __( 'Add New Team Member', 'zero-bs-crm' ),
1086                'url'     => 'https://jetpackcrm.com/feature/team/',
1087                'img'     => 'learn-zbs-team.png',
1088                'content' => '<p>' . __( 'As your business grows you will want to expand your team.', 'zero-bs-crm' ) . '</p><p>' . __( 'Add new team members or search existing WordPress users to add them to your team.', 'zero-bs-crm' ) . '</p><p>' . __( 'WordPress Administrator level by default has access to everything. You can manage your other user permissions here.', 'zero-bs-crm' ) . '</p>',
1089            ),
1090            'teamedit'           => array(
1091                'title'   => __( 'Edit Team Member', 'zero-bs-crm' ),
1092                'url'     => 'https://jetpackcrm.com/feature/team/',
1093                'img'     => 'learn-zbs-team.png',
1094                'content' => '<p>' . __( 'As your business grows you will want to expand your team.', 'zero-bs-crm' ) . '</p><p>' . __( 'Add new team members or search existing WordPress users to add them to your team.', 'zero-bs-crm' ) . '</p><p>' . __( 'WordPress Administrator level by default has access to everything. You can manage your other user permissions here.', 'zero-bs-crm' ) . '</p>',
1095            ),
1096            'extensions'         => array(
1097                'title'           => __( 'Extensions', 'zero-bs-crm' ),
1098                'url'             => 'https://jetpackcrm.com/pricing/',
1099                'img'             => 'learn-extensions-list.png',
1100                'video'           => false,
1101                'content'         => '<p>' . sprintf( __( 'The core of the CRM is free to use, and you can  <a href="%s">manage your core modules here</a>; this page lets you manage premium extensions.', 'zero-bs-crm' ), admin_url( 'admin.php?page=' . $zbs->slugs['modules'] ) ) . '</p>' . ( jpcrm_is_license_valid() ? '' : '<p>' . __( '<b>Premium Extensions</b> Want all the extensions? Purchase our Entrepeneur Bundle to get access to them all.', 'zero-bs-crm' ) . '</p>' ), // phpcs:ignore WordPress.WP.I18n.MissingTranslatorsComment
1102                'filter_function' => 'jpcrm_extensions_learn_menu',
1103            ),
1104            'managecompanies'    => array(
1105                'title'           => __( jpcrm_label_company( true ), 'zero-bs-crm' ), // phpcs:ignore WordPress.WP.I18n.NonSingularStringLiteralText
1106                'url'             => 'https://jetpackcrm.com/feature/companies/',
1107                'img'             => 'learn-company-list.png',
1108                'content'         => '<p>' . __( 'Keep track of important ', 'zero-bs-crm' ) . jpcrm_label_company() . __( ' level relationships in your CRM', 'zero-bs-crm' ) . '</p><p>' . __( 'Managing ', 'zero-bs-crm' ) . jpcrm_label_company( true ) . __( ' is a way of seeing which contacts work at which ', 'zero-bs-crm' ) . jpcrm_label_company() . __( ' If you have three or four contacts who keep in touch with you, it is useful to know which ', 'zero-bs-crm' ) . jpcrm_label_company() . __( ' they all share in common.', 'zero-bs-crm' ) . '</p>',
1109                'filter_function' => 'jpcrm_companylist_learn_menu',
1110            ),
1111            'companynew'         => array(
1112                'title'     => sprintf( __( 'New %s', 'zero-bs-crm' ), jpcrm_label_company() ), // phpcs:ignore WordPress.WP.I18n.MissingTranslatorsComment
1113                'url'       => 'https://jetpackcrm.com/feature/companies/',
1114                'img'       => 'learn-company-list.png',
1115                'content'   => '<p>' . __( 'Add a New Company to your CRM. When adding a ', 'zero-bs-crm' ) . jpcrm_label_company() . __( ' you can also choose which contacts to assign to the ', 'zero-bs-crm' ) . jpcrm_label_company() . __( '.', 'zero-bs-crm' ) . '</p><p>' . __( 'Managing large clients, this gives you an easy way to zero in on contacts at a particular company.', 'zero-bs-crm' ) . '</p>',
1116                'back_slug' => $zbs->slugs['managecompanies'],
1117            ),
1118            'companyedit'        => array(
1119                'title'           => sprintf( __( 'Edit %s', 'zero-bs-crm' ), jpcrm_label_company() ), // phpcs:ignore WordPress.WP.I18n.MissingTranslatorsComment
1120                'url'             => 'https://jetpackcrm.com/feature/companies/',
1121                'img'             => 'learn-company-list.png',
1122                'content'         => '<p>' . __( 'Editing a Company in your CRM. When editing a ', 'zero-bs-crm' ) . jpcrm_label_company() . __( ' you can also choose which contacts to assign to the ', 'zero-bs-crm' ) . jpcrm_label_company() . __( '.', 'zero-bs-crm' ) . '</p><p>' . __( 'Managing large clients, this gives you an easy way to zero in on contacts at a particular company.', 'zero-bs-crm' ) . '</p>',
1123                'back_slug'       => $zbs->slugs['managecompanies'],
1124                'filter_function' => 'jpcrm_companyedit_learn_menu',
1125            ),
1126            'mail'               => array(
1127                'title'   => __( 'Settings: Mail', 'zero-bs-crm' ),
1128                'url'     => 'https://jetpackcrm.com/feature/system-emails/',
1129                'img'     => 'learn-mail.png',
1130                'content' => '<p>' . __( 'Your mail settings control the emails that are sent out of your CRM.', 'zero-bs-crm' ) . '</p><p>' . __( 'You can choose how you want your email "From" name to look when single emails are sent and setup various mail delivery options (such as adding your STMP settings).', 'zero-bs-crm' ) . '</p>',
1131            ),
1132            'maildelivery'       => array(
1133                'title'   => __( 'Settings: Mail Delivery', 'zero-bs-crm' ),
1134                'url'     => 'https://jetpackcrm.com/feature/mail-delivery/',
1135                'img'     => 'learn-mail-delivery.png',
1136                'content' => '<p>' . __( 'Mail delivery options help you improve your CRM email deliverability. If you are running Mail Campaigns or our mail templates you may also wish to choose which email account sends the emails (or system emails).', 'zero-bs-crm' ) . '</p><p>' . __( 'You could have your new client account emails come from one email and your invoices come from another email.', 'zero-bs-crm' ) . '</p>',
1137            ),
1138            'email-templates'    => array(
1139                'title'   => __( 'System Email Templates', 'zero-bs-crm' ),
1140                'url'     => 'https://jetpackcrm.com/feature/system-emails/',
1141                'img'     => 'learn-mail.png',
1142                'content' => '<p>' . __( 'Edit your different system email templates.', 'zero-bs-crm' ) . '</p>',
1143            ),
1144            'recent-emails'      => array(
1145                'title'   => __( 'Recent Email Activity', 'zero-bs-crm' ),
1146                'url'     => 'https://jetpackcrm.com/feature/system-emails/',
1147                'img'     => 'learn-mail.png',
1148                'content' => '<p>' . __( 'Recent email activity across your CRM email templates.', 'zero-bs-crm' ) . '</p>',
1149            ),
1150            'template-settings'  => array(
1151                'title'   => __( 'Template Settings', 'zero-bs-crm' ),
1152                'url'     => 'https://jetpackcrm.com/feature/system-emails/',
1153                'img'     => 'learn-mail.png',
1154                'content' => '<p>' . __( 'Manage your main email template settings.', 'zero-bs-crm' ) . '</p>',
1155            ),
1156            'viewsegment'        => array(
1157                'title'           => __( 'View Segment', 'zero-bs-crm' ),
1158                'url'             => 'https://jetpackcrm.com/feature/segments/',
1159                'img'             => 'learn-segment-edit.png',
1160                'video'           => 'https://www.youtube.com/watch?v=KwGh-Br_exc',
1161                'video_title'     => __( 'Introduction to Tags and Segments', 'zero-bs-crm' ),
1162                'content'         => '<p>' . __( 'Create a segment to partition a group of contacts into a manageable list.', 'zero-bs-crm' ) . '</p><p>' . __( 'Perfect for quick filters and links in seamlessly with Mail Campaigns and Automations. Segments are a great way to give you extra list power and save you having to manually group contacts based on multiple tags.', 'zero-bs-crm' ) . '</p>',
1163                'icon_class'      => 'pie chart',
1164                'back_slug'       => $zbs->slugs['segments'],
1165                'filter_function' => 'jpcrm_segmentedit_learn_menu',
1166            ),
1167            'segmentedit'        => array(
1168                'title'           => __( 'Edit Segment', 'zero-bs-crm' ),
1169                'url'             => 'https://jetpackcrm.com/feature/segments/',
1170                'img'             => 'learn-segment-edit.png',
1171                'video'           => 'https://www.youtube.com/watch?v=KwGh-Br_exc',
1172                'video_title'     => __( 'Introduction to Tags and Segments', 'zero-bs-crm' ),
1173                'content'         => '<p>' . __( 'Create a segment to partition a group of contacts into a manageable list.', 'zero-bs-crm' ) . '</p><p>' . __( 'Perfect for quick filters and links in seamlessly with Mail Campaigns and Automations. Segments are a great way to give you extra list power and save you having to manually group contacts based on multiple tags.', 'zero-bs-crm' ) . '</p>',
1174                'icon_class'      => 'pie chart',
1175                'back_slug'       => $zbs->slugs['segments'],
1176                'filter_function' => 'jpcrm_segmentedit_learn_menu',
1177            ),
1178            'segments'           => array(
1179                'title'           => __( 'Segments', 'zero-bs-crm' ),
1180                'url'             => 'https://jetpackcrm.com/feature/segments/',
1181                'img'             => 'learn-segment-list.png',
1182                'video'           => 'https://www.youtube.com/watch?v=KwGh-Br_exc',
1183                'video_title'     => __( 'Introduction to Tags and Segments', 'zero-bs-crm' ),
1184                'content'         => '<p>' . __( 'Here is your segment list. This is where you will see any segments you create.', 'zero-bs-crm' ) . '</p><p>' . __( 'Segments are a powerful way to split out groups of contacts from your contact list and act on them (e.g. via Mail Campaigns or Automations).', 'zero-bs-crm' ) . '</p>',
1185                'icon_class'      => 'pie chart',
1186                'filter_function' => 'jpcrm_segmentlist_learn_menu',
1187            ),
1188            'notifications'      => array(
1189                'title'           => __( 'Notifications', 'zero-bs-crm' ),
1190                'url'             => 'https://kb.jetpackcrm.com/knowledge-base/jetpack-crm-notifications/',
1191                'img'             => 'learn-notifications.png',
1192                'content'         => '<p>' . __( 'When you are running your CRM you want to be kept up to date with everything.', 'zero-bs-crm' ) . '</p><p>' . __( 'Notifications are here to help keep you notified. Here is where you will see useful messages and updates from us.', 'zero-bs-crm' ) . '</p>',
1193                'filter_function' => 'jpcrm_notifications_learn_menu',
1194            ),
1195            'export-tools'       => array(
1196                'title'   => __( 'Export Tools', 'zero-bs-crm' ),
1197                'url'     => 'https://kb.jetpackcrm.com/knowledge-base/how-to-export-company-data/',
1198                'img'     => 'learn-export-tools.png',
1199                'content' => '<p>' . __( 'Here is the central area for exporting information from your CRM.', 'zero-bs-crm' ) . '</p><p>' . __( 'Export to keep backups offline, to do additional analysis in a spreadsheet, or to import into other tools you use.', 'zero-bs-crm' ) . '</p>',
1200            ),
1201            'datatools'          => array(
1202                'title'       => __( 'Data Tools', 'zero-bs-crm' ),
1203                'url'         => 'https://kb.jetpackcrm.com/knowledge-base/how-to-export-company-data/',
1204                'img'         => 'learn-data-tools.png',
1205                'video'       => 'https://www.youtube.com/watch?v=2KDy-a2wC8w',
1206                'video_title' => __( 'How to import contacts using CSV files', 'zero-bs-crm' ),
1207                'content'     => '<p>' . __( 'Data Tools is the area where you can reset your CRM data or import data from a CSV file.', 'zero-bs-crm' ) . '</p><p>' . __( 'You can also export various types of CRM data, including as contacts, transactions, quotes, and invoices.', 'zero-bs-crm' ) . '</p>',
1208            ),
1209            'systemstatus'       => array(
1210                'title'   => __( 'System Assistant', 'zero-bs-crm' ),
1211                'img'     => 'learn-system-settings.png',
1212                'content' => '<p>' . __( 'This page is your CRM backend hub. You can use the System Assistant to guide your setup, or the System Status tab lets you see the various server and software settings which exist behind the scenes in your Jetpack CRM install.', 'zero-bs-crm' ) . '</p><p>' . __( 'You will not need to change anything here, but our support team might ask you to load this page to retrieve a status flag.', 'zero-bs-crm' ) . '</p>',
1213            ),
1214            'modules'            => array(
1215                'title'       => __( 'Core Modules', 'zero-bs-crm' ),
1216                'img'         => 'learn-core-modules.png',
1217                'video'       => 'https://www.youtube.com/watch?v=j9RsXPcgeIo',
1218                'video_title' => __( 'Introduction to core CRM modules', 'zero-bs-crm' ),
1219                'content'     => '<p>' . __( 'From this page you can manage which core modules are enabled, it gives you ultimate control of the areas of your CRM that you plan to use or hide. Modules are kind of like bundled CRM extensions and vary from object-areas like Invoices to functionality like adding PDF generation.', 'zero-bs-crm' ) . '</p><p>' . sprintf( __( 'If you want to manage your premium extensions, you can do that <a href="%s">here</a>.', 'zero-bs-crm' ), admin_url( 'admin.php?page=' . $zbs->slugs['extensions'] ) ) . '</p>', // phpcs:ignore WordPress.WP.I18n.MissingTranslatorsComment
1220            ),
1221            'export'             => array(
1222                'title' => __( 'Export', 'zero-bs-crm' ),
1223                'url'   => 'https://kb.jetpackcrm.com/knowledge-base/how-to-export-company-data/',
1224                'img'   => 'learn-extensions-list.png',
1225            ),
1226            'bulktagger'         => array(
1227                'title' => __( 'Bulk Tagger', 'zero-bs-crm' ),
1228                'url'   => 'https://kb.jetpackcrm.com/article-categories/bulk-tagger/',
1229                'img'   => 'learn-extensions-list.png',
1230            ),
1231            'salesdash'          => array(
1232                'title' => __( 'Sales Dashboard', 'zero-bs-crm' ),
1233                'url'   => 'https://kb.jetpackcrm.com/article-categories/sales-dashboard/',
1234                'img'   => 'learn-extensions-list.png',
1235            ),
1236            'home'               => array(
1237                'show_learn' => false,
1238            ),
1239            'welcome'            => array(
1240                'title' => __( 'Welcome', 'zero-bs-crm' ),
1241                'url'   => 'https://jetpackcrm.com/',
1242                'img'   => 'learn-contact-list.png',
1243            ),
1244            'sync'               => array(
1245                'title' => __( 'Sync Tools', 'zero-bs-crm' ),
1246                'url'   => 'https://jetpackcrm.com/pricing/',
1247                'img'   => 'learn-contact-list.png',
1248            ),
1249            'settings'           => array(
1250                'title'           => __( 'Settings', 'zero-bs-crm' ),
1251                'url'             => 'https://kb.jetpackcrm.com/knowledge-base/settings-page/',
1252                'img'             => 'learn-settings-page.png',
1253                'content'         => '<p>' . __( 'This settings page lets you control all of the different areas of Jetpack CRM. As you install extensions you will also see their settings pages showing up on the left hand menu below.', 'zero-bs-crm' ),
1254                'filter_function' => 'jpcrm_settings_learn_menu',
1255            ),
1256            'emails'             => array(
1257                'title'           => __( 'Emails', 'zero-bs-crm' ),
1258                'url'             => 'https://jetpackcrm.com/feature/emails',
1259                'img'             => 'learn-emails.png',
1260                'content'         => '<p>' . __( 'Emails are centric to your CRM communications. Send emails to your contacts and schedule them to send at certain times in the future (if conditions are met).', 'zero-bs-crm' ) . '</p><p>' . __( 'Check out our System Emails Pro extension to extend the email functionality.', 'zero-bs-crm' ) . '</p>',
1261                'filter_function' => 'jpcrm_emails_learn_menu',
1262            ),
1263            'profile'            => array(
1264                'title'   => __( 'Your Profile', 'zero-bs-crm' ),
1265                'img'     => 'learn-your-profile.png',
1266                'content' => '<p>' . __( 'This is your profile page.', 'zero-bs-crm' ) . '</p>',
1267            ),
1268            'crmresources'       => array(
1269                'title'   => __( 'CRM Resources', 'zero-bs-crm' ),
1270                'content' => '<p>' . __( 'The CRM Resources page collects together the general resources for CRM Admins.', 'zero-bs-crm' ) . '</p>',
1271            ),
1272            'delete'             => array(
1273                'title'           => __( 'Delete', 'zero-bs-crm' ),
1274                'output_function' => 'jpcrm_delete_learn_menu',
1275            ),
1276            'csvlite'            => array(
1277                'title'           => __( 'CSV Importer Lite', 'zero-bs-crm' ),
1278                'learn_title'     => esc_html__( 'Import contacts from CSV', 'zero-bs-crm' ),
1279                'filter_function' => 'jpcrm_csvlite_learn_menu',
1280            ),
1281        );
1282
1283        /**
1284         * Extension tie-ins
1285         */
1286        if ( isset( $zbs->slugs['stripesync'] ) ) {
1287            $learn_menu_array[ $zbs->slugs['stripesync'] ] = array(
1288                'title'           => __( 'Stripe Sync', 'zero-bs-crm' ),
1289                'output_function' => 'zeroBSCRM_stripesync_learn_menu',
1290            );
1291        }
1292
1293        if ( isset( $zbs->slugs['woosync'] ) ) {
1294            $learn_menu_array[ $zbs->slugs['woosync'] ] = array(
1295                'title'           => 'WooSync',
1296                'output_function' => 'zeroBSCRM_woosync_learn_menu',
1297            );
1298        }
1299
1300        if ( isset( $zbs->slugs['mailpoet'] ) ) {
1301            $learn_menu_array[ $zbs->slugs['mailpoet'] ] = array(
1302                'title'           => 'MailPoet',
1303                'output_function' => 'zeroBSCRM_mailpoet_learn_menu',
1304            );
1305        }
1306
1307        if ( isset( $zbs->slugs['paypalsync'] ) ) {
1308            $learn_menu_array[ $zbs->slugs['paypalsync'] ] = array(
1309                'title'           => 'PayPal Sync',
1310                'output_function' => 'zeroBSCRM_paypalsync_learn_menu',
1311            );
1312        }
1313
1314        $learn_menu_array = apply_filters( 'jpcrm_learn_menus', $learn_menu_array );
1315
1316        return $learn_menu_array;
1317    }
1318
1319    /**
1320     * Retrieves the CSS classes for the Learn menu container.
1321     *
1322     * @return string The CSS classes for the Learn menu container.
1323     */
1324    private function get_learn_menu_container_css_classes() {
1325        $classes = 'jpcrm-learn-menu-container';
1326
1327        if ( isset( $_GET['page'] ) && jpcrm_is_full_width_page( wp_unslash( $_GET['page'] ) ) ) { // phpcs:ignore
1328            $classes .= ' jpcrm-full-width';
1329        }
1330
1331        $classes = apply_filters( 'jetpack_crm_learn_menu_container_css_classes', $classes );
1332        return $classes;
1333    }
1334
1335    /**
1336     * Retrieves the CSS classes for the Learn menu.
1337     *
1338     * @return string The CSS classes for the Learn menu.
1339     */
1340    private function get_learn_menu_css_classes() {
1341        $classes = 'jpcrm-learn-menu';
1342
1343        if ( isset( $_GET['page'] ) && jpcrm_is_full_width_page( wp_unslash( $_GET['page'] ) ) ) { // phpcs:ignore
1344            $classes .= ' jpcrm-full-width';
1345        }
1346
1347        $classes = apply_filters( 'jetpack_crm_learn_menu_css_classes', $classes );
1348        return $classes;
1349    }
1350}