Advertisement
Guest User

GroovyMenuUtils.php

a guest
Oct 1st, 2020
117
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 67.28 KB | None | 0 0
  1. <?php defined( 'ABSPATH' ) || die( 'This script cannot be accessed directly.' );
  2.  
  3. /**
  4.  * Class GroovyMenuUtils
  5.  */
  6. class GroovyMenuUtils {
  7.  
  8.     /**
  9.      * Register groovy_menu_preset post type.
  10.      */
  11.     public static function add_groovy_menu_preset_post_type() {
  12.  
  13.         $capabilities = array(
  14.             'edit_post'           => 'groovy_menu_edit_preset',
  15.             'read_post'           => 'groovy_menu_read_preset',
  16.             'delete_post'         => 'groovy_menu_delete_preset',
  17.             'delete_posts'        => 'groovy_menu_delete_preset',
  18.             'edit_posts'          => 'groovy_menu_edit_preset',
  19.             'edit_others_posts'   => 'groovy_menu_edit_others_presets',
  20.             'publish_posts'       => 'groovy_menu_publish_presets',
  21.             'read_private_posts'  => 'groovy_menu_read_private_presets',
  22.             'create_posts'        => 'groovy_menu_create_preset',
  23.             'delete_others_posts' => 'groovy_menu_delete_others_presets',
  24.         );
  25.  
  26.         register_post_type( 'groovy_menu_preset',
  27.             array(
  28.                 'labels'            => array(
  29.                     'name'          => esc_html__( 'Groovy Menu Preset', 'groovy-menu' ),
  30.                     'singular_name' => esc_html__( 'Groovy Menu Preset', 'groovy-menu' ),
  31.                     'add_new_item'  => esc_html__( 'Add New Groovy Menu Preset', 'groovy-menu' ),
  32.                     'edit_item'     => esc_html__( 'Edit Groovy Menu Preset', 'groovy-menu' ),
  33.                     'view_item'     => esc_html__( 'View Groovy Menu Preset', 'groovy-menu' ),
  34.                 ),
  35.                 'public'            => false,
  36.                 'has_archive'       => false,
  37.                 'show_in_nav_menus' => false,
  38.                 'show_in_menu'      => false,
  39.                 'taxonomies'        => array(),
  40.                 'supports'          => array(
  41.                     'title',
  42.                     'editor',
  43.                     'thumbnail',
  44.                     'author',
  45.                     'custom-fields',
  46.                     'revisions',
  47.                 ),
  48.                 'rewrite'           => array(
  49.                     'slug'       => 'groovy_menu_preset',
  50.                     'with_front' => false,
  51.                 ),
  52.                 'capability_type'   => 'groovy_menu_preset',
  53.                 'capabilities'      => $capabilities,
  54.             )
  55.         );
  56.  
  57.     }
  58.  
  59.  
  60.     /**
  61.      * @return array
  62.      */
  63.     public static function get_old_preset_ids() {
  64.         $preset_change_id = array();
  65.         $all_presets      = GroovyMenuPreset::getAll();
  66.         foreach ( $all_presets as $preset ) {
  67.             $old_id = get_post_meta( $preset->id, 'gm_old_id', true );
  68.             if ( ! empty( $old_id ) && intval( $old_id ) ) {
  69.                 $preset_change_id[ intval( $old_id ) ] = $preset->id;
  70.             }
  71.         }
  72.  
  73.         return $preset_change_id;
  74.     }
  75.  
  76.  
  77.     /**
  78.      * @return array
  79.      */
  80.     public static function get_preset_used_in() {
  81.         $preset_used_in = array();
  82.  
  83.         $preset_used_in = get_option( 'groovy_menu_preset_used_in_storage' );
  84.  
  85.         if ( ! is_array( $preset_used_in ) ) {
  86.             return array();
  87.         }
  88.  
  89.         return $preset_used_in;
  90.     }
  91.  
  92.  
  93.     /**
  94.      * @param      $preset_id
  95.      * @param bool $return_count
  96.      *
  97.      * @return array|int
  98.      */
  99.     public static function get_preset_used_in_by_id( $preset_id, $return_count = false ) {
  100.  
  101.         $preset_id = empty( $preset_id ) ? null : intval( $preset_id );
  102.  
  103.         if ( empty( $preset_id ) ) {
  104.             return array();
  105.         }
  106.  
  107.         $used_in        = array();
  108.         $preset_used_in = self::get_preset_used_in();
  109.         $counter        = 0;
  110.  
  111.         if ( ! is_array( $preset_used_in ) ) {
  112.             $preset_used_in = array();
  113.         }
  114.  
  115.         foreach ( $preset_used_in as $place => $data ) {
  116.  
  117.             switch ( $place ) {
  118.                 case 'default':
  119.                     if ( intval( $data ) === $preset_id ) {
  120.                         $used_in['default'] = true;
  121.                         $counter ++;
  122.                     }
  123.                     break;
  124.                 case 'global':
  125.                     foreach ( $data as $post_type => $preset ) {
  126.                         if ( intval( $preset ) === $preset_id ) {
  127.                             $used_in['global'][ $post_type ] = true;
  128.                             $counter ++;
  129.                         }
  130.                     }
  131.                     break;
  132.                 case 'taxonomy':
  133.                     foreach ( $data as $taxonomy_id => $preset ) {
  134.                         if ( intval( $preset ) === $preset_id ) {
  135.                             $used_in['taxonomy'][ $taxonomy_id ] = true;
  136.                             $counter ++;
  137.                         }
  138.                     }
  139.                     break;
  140.                 case 'post':
  141.                     foreach ( $data as $post_type => $post_data ) {
  142.                         foreach ( $post_data as $post_id => $preset ) {
  143.                             if ( intval( $preset ) === $preset_id ) {
  144.                                 $used_in['post'][ $post_type ][ $post_id ] = true;
  145.                                 $counter ++;
  146.                             }
  147.                         }
  148.                     }
  149.                     break;
  150.             }
  151.         }
  152.  
  153.         if ( $return_count ) {
  154.             return $counter;
  155.         } else {
  156.             return $used_in;
  157.         }
  158.     }
  159.  
  160.  
  161.     /**
  162.      * @return string
  163.      */
  164.     public static function getUploadDir() {
  165.         $uploadDir = wp_upload_dir();
  166.  
  167.         return $uploadDir['basedir'] . '/groovy/';
  168.     }
  169.  
  170.  
  171.     /**
  172.      * @return string
  173.      */
  174.     public static function getFontsDir() {
  175.         $fonts = self::getUploadDir() . 'fonts/';
  176.  
  177.         return $fonts;
  178.     }
  179.  
  180.  
  181.     /**
  182.      * @return string
  183.      */
  184.     public static function getUploadUri() {
  185.         $uploadDir = wp_upload_dir();
  186.         $scheme    = is_ssl() ? 'https' : 'http';
  187.  
  188.         return set_url_scheme( $uploadDir['baseurl'] . '/groovy/', $scheme );
  189.     }
  190.  
  191.  
  192.     public static function addPresetCssFile() {
  193.  
  194.         global $groovyMenuSettings;
  195.         $css_file_params = isset( $groovyMenuSettings['css_file_params'] ) ? $groovyMenuSettings['css_file_params'] : array();
  196.  
  197.         if ( ! empty( $css_file_params ) && is_file( $css_file_params['upload_dir'] . $css_file_params['css_filename'] ) ) {
  198.  
  199.             wp_enqueue_style(
  200.                 'groovy-menu-preset-style-' . $css_file_params['preset_id'],
  201.                 $css_file_params['upload_uri'] . $css_file_params['css_filename'],
  202.                 [ 'groovy-menu-style' ],
  203.                 $css_file_params['preset_key'] . ( is_rtl() ? '_rtl' : '' )
  204.             );
  205.  
  206.         }
  207.     }
  208.  
  209.  
  210.     /**
  211.      * @param bool $name_as_key
  212.      *
  213.      * @return array
  214.      */
  215.     public static function getPostTypes( $name_as_key = true ) {
  216.  
  217.         $post_types = array();
  218.  
  219.         // get the registered data about each post type with get_post_type_object.
  220.         $post_types_query = get_post_types(
  221.             array(
  222.                 'public'            => true,
  223.                 'show_in_nav_menus' => true,
  224.             )
  225.         );
  226.  
  227.         if ( empty( $post_types_query ) ) {
  228.             return $post_types;
  229.         }
  230.  
  231.         foreach ( $post_types_query as $type ) {
  232.             $type_obj = get_post_type_object( $type );
  233.  
  234.             $name  = isset( $type_obj->name ) ? $type_obj->name : null;
  235.             $label = isset( $type_obj->label ) ? $type_obj->label : '';
  236.  
  237.             if ( empty( $name ) || empty( $label ) ) {
  238.                 continue;
  239.             }
  240.  
  241.             if ( $name_as_key ) {
  242.                 $post_types[ $name ] = $label;
  243.             } else {
  244.                 $post_types[ $label ] = $name;
  245.             }
  246.         }
  247.  
  248.         return $post_types;
  249.  
  250.     }
  251.  
  252.     /**
  253.      * @param bool $name_as_key
  254.      *
  255.      * @param bool $get_custom_types
  256.      *
  257.      * @return array
  258.      */
  259.     public static function getPostTypesExtended( $name_as_key = true, $get_custom_types = true ) {
  260.  
  261.         $post_types     = self::getPostTypes( true );
  262.         $post_types_ext = array();
  263.  
  264.         if ( ! is_array( $post_types ) ) {
  265.             return $post_types_ext;
  266.         }
  267.  
  268.         foreach ( $post_types as $type => $name ) {
  269.  
  270.             if ( 'gm_menu_block' === $type && $get_custom_types ) {
  271.                 continue;
  272.             }
  273.  
  274.             $post_types_ext[ $type ] = $name;
  275.  
  276.             if ( $get_custom_types ) {
  277.                 switch ( $type ) {
  278.                     case 'post':
  279.                         $post_types_ext['post--single'] = $name . ' (' . esc_html__( 'single pages', 'groovy-menu' ) . ')';
  280.                         break;
  281.                     case 'page':
  282.                         $post_types_ext['page--is_search'] = esc_html__( 'Search page', 'groovy-menu' );
  283.                         $post_types_ext['page--is_404']    = esc_html__( '404 Not Found Page', 'groovy-menu' );
  284.                         break;
  285.                     default:
  286.                         $type_obj = get_post_type_object( $type );
  287.                         // Post type can has archive and single pages.
  288.                         if ( is_object( $type_obj ) && ! empty( $type_obj->has_archive ) && $type_obj->has_archive ) {
  289.                             $post_types_ext[ $type . '--single' ] = $name . ' (' . esc_html__( 'single pages', 'groovy-menu' ) . ')';
  290.                         }
  291.                         break;
  292.                 }
  293.             }
  294.         }
  295.  
  296.         if ( ! $name_as_key ) {
  297.             $_post_types_ext = array();
  298.             foreach ( $post_types_ext as $type => $name ) {
  299.                 $_post_types_ext[ $name ] = $type;
  300.             }
  301.             $post_types_ext = $_post_types_ext;
  302.         }
  303.  
  304.         return $post_types_ext;
  305.  
  306.     }
  307.  
  308.     /**
  309.      * @return array
  310.      */
  311.     public static function getPostTypesForSearch() {
  312.  
  313.         $post_types     = self::getPostTypes( true );
  314.         $post_types_ext = array();
  315.  
  316.         if ( ! is_array( $post_types ) ) {
  317.             return $post_types_ext;
  318.         }
  319.  
  320.         foreach ( $post_types as $type => $name ) {
  321.  
  322.             if ( 'gm_menu_block' === $type ) {
  323.                 continue;
  324.             }
  325.  
  326.             $type_obj = get_post_type_object( $type );
  327.  
  328.             if ( is_object( $type_obj ) ) {
  329.                 $post_types_ext[ $type ] = array(
  330.                     'title'     => esc_html__( 'Search in:', 'groovy-menu' ) . ' ' . $name . ' (' . $type . ')',
  331.                     'condition' => array( 'search_form', 'in', array( 'fullscreen', 'dropdown-without-ajax' ) ),
  332.                 );
  333.             }
  334.         }
  335.  
  336.         // support product woo, while not detect in some cases.
  337.         if ( empty( $post_types['product'] ) && class_exists( 'WooCommerce' ) ) {
  338.             $post_types_ext['product'] = array(
  339.                 'title'     => esc_html__( 'Search in:', 'groovy-menu' ) . ' Products (product)',
  340.                 'condition' => array( 'search_form', 'in', array( 'fullscreen', 'dropdown-without-ajax' ) ),
  341.             );
  342.         }
  343.  
  344.         return $post_types_ext;
  345.  
  346.     }
  347.  
  348.  
  349.     /**
  350.      * Get all posts by gm_menu_block post type.
  351.      *
  352.      * @return array
  353.      */
  354.     public static function getMenuBlockPostsList() {
  355.  
  356.         static $cached_posts = array();
  357.  
  358.         if ( ! empty( $cached_posts ) ) {
  359.             return $cached_posts;
  360.         }
  361.  
  362.         $params = array(
  363.             'post_type'   => 'gm_menu_block',
  364.             'post_status' => 'publish',
  365.             'numberposts' => - 1,
  366.         );
  367.  
  368.         $posts = get_posts( $params );
  369.  
  370.         foreach ( $posts as $post ) {
  371.             if ( ! empty( $post->ID ) ) {
  372.                 $title                     = empty( $post->post_title ) ? '' : $post->post_title;
  373.                 $title                     = $title . ' (id:' . $post->ID . ')';
  374.                 $cached_posts[ $post->ID ] = $title;
  375.             }
  376.         }
  377.  
  378.         return $cached_posts;
  379.  
  380.     }
  381.  
  382.  
  383.     /**
  384.      * Get all posts by gm_menu_block post type.
  385.      *
  386.      * @param string $searchIcon
  387.      *
  388.      * @return string
  389.      */
  390.     public static function getSearchBlock( $searchIcon ) {
  391.  
  392.         global $groovyMenuSettings;
  393.  
  394.         $html             = '';
  395.         $searchFilter     = '';
  396.         $menuBlockContent = '';
  397.         $isFullScreen     = false;
  398.         $isShowDefault    = true;
  399.         $isSearchCustom   = false;
  400.  
  401.         $searchForm                  = isset( $groovyMenuSettings['searchForm'] ) ? $groovyMenuSettings['searchForm'] : 'fullscreen';
  402.         $searchFormFrom              = isset( $groovyMenuSettings['searchFormFrom'] ) ? $groovyMenuSettings['searchFormFrom'] : 'all';
  403.         $searchFormCustomWrapper     = isset( $groovyMenuSettings['searchFormCustomWrapper'] ) ? $groovyMenuSettings['searchFormCustomWrapper'] : 'fullscreen';
  404.         $searchFormCustomShowDefault = isset( $groovyMenuSettings['searchFormCustomShowDefault'] ) ? $groovyMenuSettings['searchFormCustomShowDefault'] : true;
  405.         $searchFormCustomId          = isset( $groovyMenuSettings['searchFormCustomId'] ) ? intval( $groovyMenuSettings['searchFormCustomId'] ) : 0;
  406.  
  407.         if ( 'custom' === $searchForm ) {
  408.             $isSearchCustom = true;
  409.         }
  410.  
  411.         if ( 'fullscreen' === $searchForm || ( $isSearchCustom && 'dropdown' !== $searchFormCustomWrapper ) ) {
  412.             $isFullScreen = 'fullscreen';
  413.         }
  414.  
  415.         if ( $isSearchCustom && ! $searchFormCustomShowDefault ) {
  416.             $isShowDefault = false;
  417.         }
  418.  
  419.         if ( $isSearchCustom && ! empty( $searchFormCustomId ) ) {
  420.             $menuBlockHelper  = new \GroovyMenu\WalkerNavMenu();
  421.             $menuBlockContent = $menuBlockHelper->getMenuBlockPostContent( $searchFormCustomId );
  422.         }
  423.  
  424.         if ( ! empty( $searchForm ) && 'all' !== $searchFormFrom ) {
  425.             $searchFilter .= '<input type="hidden" name="post_type" value="' . $searchFormFrom . '">';
  426.         }
  427.  
  428.         $current_lang = apply_filters( 'wpml_current_language', null );
  429.         if ( $current_lang ) {
  430.             $searchFilter .= '<input type="hidden" name="lang" value="' . $current_lang . '">';
  431.         }
  432.  
  433.         $searchFilter = apply_filters( 'gm_search_filter_hidden_input', $searchFilter );
  434.  
  435.         $home_url = trailingslashit( network_site_url() );
  436.         if ( defined( 'WPML_PLUGIN_FOLDER' ) && WPML_PLUGIN_FOLDER ) {
  437.             $home_url = apply_filters( 'wpml_home_url', $home_url );
  438.         }
  439.  
  440.         $html .= '<div class="gm-search ' . ( $isFullScreen ? 'fullscreen' : 'gm-dropdown' ) . '">
  441.                                         <i class="' . esc_attr( $searchIcon ) . '"></i>
  442.                                         <span class="gm-search__txt">'
  443.                  . esc_html__( 'Search', 'groovy-menu' ) .
  444.                  '</span>';
  445.  
  446.         if ( $searchForm === 'dropdown-without-ajax' || ( 'custom' === $searchForm && 'dropdown' === $searchFormCustomWrapper ) ) {
  447.             $html .= '
  448.                                         <div class="gm-search-wrapper">';
  449.             if ( $isSearchCustom && 'dropdown' === $searchFormCustomWrapper ) {
  450.                 $html .= $menuBlockContent;
  451.             }
  452.  
  453.             if ( $isShowDefault ) {
  454.                 $html .= '                  <form action="' . $home_url . '"
  455.                                                   method="get"
  456.                                                   class="gm-search-wrapper-form">
  457.                                                 <div class="gm-form-group">
  458.                                                     <input placeholder="' . esc_html__( 'Search...', 'groovy-menu' ) . '"
  459.                                                            type="text"
  460.                                                            name="s"
  461.                                                            class="gm-search__input">
  462.                                                     ' . $searchFilter . '
  463.                                                     <button type="submit" class="gm-search-btn">
  464.                                                         <i class="fa fa-search"></i>
  465.                                                     </button>
  466.                                                 </div>
  467.                                             </form>';
  468.             }
  469.             $html .= '                  </div>';
  470.         }
  471.  
  472.         $html .= '<div class="gm-search__fullscreen-container gm-hidden">
  473.                                         <span class="gm-search__close"><svg height="32" width="32" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
  474.    <path fill-rule="evenodd" d="M 16 32 C 7.16 32 0 24.84 0 16 C 0 7.16 7.16 0 16 0 C 24.84 0 32 7.16 32 16 C 32 24.84 24.84 32 16 32 Z M 16 2 C 8.27 2 2 8.27 2 16 C 2 23.73 8.27 30 16 30 C 23.73 30 30 23.73 30 16 C 30 8.27 23.73 2 16 2 Z M 17.35 16 C 17.35 16 20.71 19.37 20.71 19.37 C 21.09 19.74 21.09 20.34 20.71 20.71 C 20.34 21.09 19.74 21.09 19.37 20.71 C 19.37 20.71 16 17.35 16 17.35 C 16 17.35 12.63 20.71 12.63 20.71 C 12.26 21.09 11.66 21.09 11.29 20.71 C 10.91 20.34 10.91 19.74 11.29 19.37 C 11.29 19.37 14.65 16 14.65 16 C 14.65 16 11.29 12.63 11.29 12.63 C 10.91 12.26 10.91 11.66 11.29 11.29 C 11.66 10.91 12.26 10.91 12.63 11.29 C 12.63 11.29 16 14.65 16 14.65 C 16 14.65 19.37 11.29 19.37 11.29 C 19.74 10.91 20.34 10.91 20.71 11.29 C 21.09 11.66 21.09 12.26 20.71 12.63 C 20.71 12.63 17.35 16 17.35 16 Z" />
  475. </svg></span>
  476.  
  477.                                         <div class="gm-search__inner">';
  478.         if ( $isShowDefault ) {
  479.             $html .= '<span class="gm-search__alpha">'
  480.                      . esc_html__( 'START TYPING AND PRESS ENTER TO SEARCH', 'groovy-menu' ) .
  481.                      '</span>';
  482.         }
  483.         $html .= '                          <div class="gm-search-wrapper">';
  484.  
  485.         if ( $isSearchCustom ) {
  486.             $html .= $menuBlockContent;
  487.         }
  488.  
  489.         if ( $isShowDefault ) {
  490.             $html .= '                          <form action="' . $home_url . '"
  491.                                                       method="get"
  492.                                                       class="gm-search-wrapper-form">
  493.                                                     <div class="gm-form-group">
  494.                                                         <input type="text" name="s" class="gm-search__input">
  495.                                                         ' . $searchFilter . '
  496.                                                         <button type="submit" class="gm-search-btn">
  497.                                                             <i class="fa fa-search"></i>
  498.                                                         </button>
  499.                                                     </div>
  500.                                                 </form>';
  501.         }
  502.         $html .= '                          </div>
  503.                                         </div>
  504.                                     </div>';
  505.         $html .= '              </div>';
  506.  
  507.  
  508.         return $html;
  509.  
  510.     }
  511.  
  512.     /**
  513.      * Uses for many custom options
  514.      *
  515.      * @return string
  516.      */
  517.     public static function get_current_page_type() {
  518.  
  519.         $type = get_post_type() ? : 'page';
  520.  
  521.         global $wp_query;
  522.         if ( empty( $wp_query ) || ! is_object( $wp_query ) ) {
  523.             return $type;
  524.         }
  525.  
  526.  
  527.         try {
  528.  
  529.             if ( self::is_shop_search() ) {
  530.  
  531.                 $type = 'product';
  532.  
  533.             } elseif ( is_search() ) {
  534.  
  535.                 $type = 'page--is_search';
  536.  
  537.             } elseif ( is_404() ) {
  538.  
  539.                 $type = 'page--is_404';
  540.  
  541.             } elseif ( is_attachment() ) {
  542.  
  543.                 $type = 'attachment';
  544.  
  545.             } elseif ( self::is_product_woocommerce_page() ) {
  546.  
  547.                 $type = 'product--single';
  548.  
  549.             } elseif ( self::is_shop_and_category_woocommerce_page() || self::is_additional_woocommerce_page() || self::is_product_woocommerce_page() ) {
  550.  
  551.                 $type = 'product';
  552.  
  553.             } elseif ( is_page_template( 'template-blog.php' ) || is_home() ) {
  554.  
  555.                 $type = 'post';
  556.  
  557.             } elseif ( is_page_template( 'template-portfolio.php' ) ) {
  558.  
  559.                 $type = 'crane_portfolio';
  560.  
  561.             } elseif ( ( is_single() && 'crane_portfolio' === get_post_type() ) || ( is_archive() && 'crane_portfolio' === get_post_type() ) || 'crane_portfolio_cats' === get_query_var( 'taxonomy' ) || 'crane_portfolio_tags' === get_query_var( 'taxonomy' ) ) {
  562.  
  563.                 $type = is_single() ? 'crane_portfolio--single' : 'crane_portfolio';
  564.  
  565.             } elseif ( ( is_single() && 'post' === get_post_type() ) || ( is_archive() && 'post' === get_post_type() ) || is_archive() ) {
  566.  
  567.                 $type = is_single() ? 'post--single' : 'post';
  568.  
  569.             } elseif ( is_page() && 'page' === get_post_type() ) {
  570.  
  571.                 $type = 'page';
  572.  
  573.             } elseif ( 'posts' === get_option( 'show_on_front' ) ) {
  574.                 // Check if the blog page is the front page.
  575.                 $type = 'post';
  576.  
  577.             } elseif ( is_single() ) {
  578.  
  579.                 $type = $type . '--single';
  580.  
  581.             }
  582.  
  583.  
  584.         } catch ( Exception $e ) {
  585.             $type = 'page';
  586.         }
  587.  
  588.  
  589.         return $type;
  590.     }
  591.  
  592.     /**
  593.      * Detect current page
  594.      *
  595.      * @return bool
  596.      */
  597.     public static function is_product_woocommerce_page() {
  598.  
  599.         if ( function_exists( 'is_product' ) ) {
  600.             if ( is_product() ) {
  601.                 return true;
  602.             }
  603.         }
  604.  
  605.         return false;
  606.     }
  607.  
  608.     /**
  609.      * Return true if current search page is post_type === 'product'
  610.      *
  611.      * @return bool
  612.      */
  613.     public static function is_shop_search() {
  614.         if ( get_search_query() && get_query_var( 'post_type' ) && 'product' === get_query_var( 'post_type' ) ) {
  615.             return true;
  616.         }
  617.  
  618.         return false;
  619.     }
  620.  
  621.     /**
  622.      * Detect current page
  623.      *
  624.      * @return bool
  625.      */
  626.     public static function is_shop_and_category_woocommerce_page() {
  627.  
  628.         if (
  629.             function_exists( 'is_woocommerce' ) &&
  630.             function_exists( 'is_product' ) &&
  631.             function_exists( 'is_shop' ) &&
  632.             function_exists( 'is_product_tag' )
  633.         ) {
  634.             if ( ! is_product() && ( is_woocommerce() || is_shop() || is_product_tag() ) ) {
  635.                 return true;
  636.             }
  637.         }
  638.  
  639.         return false;
  640.     }
  641.  
  642.  
  643.     /**
  644.      * It determines whether the current page belongs to woocommerce
  645.      * (cart and checkout are standard pages with shortcodes and which are also included)
  646.      *
  647.      * @return bool
  648.      */
  649.     public static function is_additional_woocommerce_page() {
  650.  
  651.         if ( function_exists( 'is_cart' ) && is_cart() ) {
  652.             return true;
  653.         }
  654.         if ( function_exists( 'is_checkout' ) && is_checkout() ) {
  655.             return true;
  656.         }
  657.         if ( function_exists( 'is_account_page' ) && is_account_page() ) {
  658.             return true;
  659.         }
  660.         if ( function_exists( 'is_checkout_pay_page' ) && is_checkout_pay_page() ) {
  661.             return true;
  662.         }
  663.         if ( function_exists( 'is_wc_endpoint_url' ) && is_wc_endpoint_url() ) {
  664.             return true;
  665.         }
  666.  
  667.         return false;
  668.     }
  669.  
  670.  
  671.     /**
  672.      * @return array
  673.      */
  674.     public static function getNavMenus() {
  675.  
  676.         static $cached_nav_menu = array();
  677.  
  678.         $nav_menus = array();
  679.  
  680.         if ( ! empty( $cached_nav_menu ) ) {
  681.             $menus = $cached_nav_menu;
  682.         } else {
  683.             $menus = wp_get_nav_menus();
  684.         }
  685.  
  686.         if ( ! empty( $menus ) ) {
  687.             $cached_nav_menu = $menus;
  688.             foreach ( $menus as $menu ) {
  689.                 if ( isset( $menu->term_id ) && isset( $menu->name ) ) {
  690.                     $nav_menus[ $menu->term_id ] = $menu->name;
  691.                 }
  692.             }
  693.         }
  694.  
  695.         return $nav_menus;
  696.  
  697.     }
  698.  
  699.  
  700.     /**
  701.      * Get default menu
  702.      *
  703.      * @return string
  704.      */
  705.     public static function getDefaultMenu() {
  706.  
  707.         $menu_location = self::getNavMenuLocations( true );
  708.         $locations     = get_nav_menu_locations();
  709.         if ( ! empty( $menu_location ) && ! empty( $locations ) ) {
  710.             $menu_id = $locations[ $menu_location ];
  711.             if ( ! empty( $menu_id ) ) {
  712.                 $menu_obj = wp_get_nav_menu_object( $menu_id );
  713.             }
  714.         }
  715.  
  716.         if ( ! empty( $menu_obj ) && isset( $menu_obj->term_id ) ) {
  717.             $menu = $menu_obj->term_id;
  718.         } else {
  719.             $menu = '';
  720.         }
  721.  
  722.         return strval( $menu );
  723.  
  724.     }
  725.  
  726.  
  727.     /**
  728.      * Return registered nav_menu locations.
  729.      *
  730.      * @param string $name check exists location name.
  731.      *
  732.      * @return array|string
  733.      */
  734.     public static function getRegisteredLocations( $name = '' ) {
  735.  
  736.         global $_wp_registered_nav_menus;
  737.  
  738.         $return_value = empty( $_wp_registered_nav_menus ) ? array() : $_wp_registered_nav_menus;
  739.  
  740.         if ( ! empty( $name ) ) {
  741.             $return_value = empty( $return_value[ $name ] ) ? '' : $return_value[ $name ];
  742.         }
  743.  
  744.         return $return_value;
  745.  
  746.     }
  747.  
  748.  
  749.     /**
  750.      * Retrieves all registered navigation menu locations and the menus assigned to them.
  751.      *
  752.      * @param bool $return_first   return only first of them, or 'gm_primary' if exists.
  753.      *
  754.      * @param bool $loc_name_first return list with location name first as value.
  755.      *
  756.      * @return array|int|null|string
  757.      */
  758.     public static function getNavMenuLocations( $return_first = false, $loc_name_first = false ) {
  759.  
  760.         $locations      = array();
  761.         $menu_locations = get_nav_menu_locations();
  762.  
  763.         foreach ( $menu_locations as $location => $location_id ) {
  764.             if ( $loc_name_first ) {
  765.                 $value = $location . ' (' . wp_get_nav_menu_name( $location ) . ')';
  766.             } else {
  767.                 $value = wp_get_nav_menu_name( $location ) . ' (' . $location . ')';
  768.             }
  769.  
  770.             $locations[ $location ] = $value;
  771.         }
  772.  
  773.         if ( $return_first ) {
  774.             if ( isset( $locations['gm_primary'] ) ) {
  775.                 return 'gm_primary';
  776.             }
  777.  
  778.             if ( empty( $locations ) ) {
  779.                 $locations = '';
  780.             } else {
  781.                 reset( $locations );
  782.                 $locations = key( $locations );
  783.             }
  784.         }
  785.  
  786.         return $locations;
  787.  
  788.     }
  789.  
  790.  
  791.     /**
  792.      * @return null|string
  793.      */
  794.     public static function getMasterPreset() {
  795.         $styles = new GroovyMenuStyle();
  796.  
  797.         return $styles->getGlobal( 'taxonomies', 'default_master_preset' );
  798.     }
  799.  
  800.  
  801.     /**
  802.      * @return int|string
  803.      */
  804.     public static function getMasterNavmenu() {
  805.  
  806.         $styles = new GroovyMenuStyle();
  807.  
  808.         $master_navmenu = $styles->getGlobal( 'taxonomies', 'default_master_menu' );
  809.         if ( ! empty( $master_navmenu ) ) {
  810.             return $master_navmenu;
  811.         }
  812.  
  813.         $master_location = self::getMasterLocation();
  814.  
  815.         if ( empty( $master_location ) ) {
  816.             $locations = self::getNavMenuLocations();
  817.             if ( ! empty( $locations ) && is_array( $locations ) ) {
  818.                 foreach ( $locations as $key => $val ) {
  819.                     $master_location = $key;
  820.                     break;
  821.                 }
  822.             }
  823.         }
  824.  
  825.         $master_navmenu  = '';
  826.         $theme_locations = get_nav_menu_locations();
  827.  
  828.         if ( ! empty( $master_location ) && ! empty( $theme_locations ) && ! empty( $theme_locations[ $master_location ] ) ) {
  829.             $menu_obj = get_term( $theme_locations[ $master_location ], 'nav_menu' );
  830.         }
  831.         if ( ! empty( $menu_obj ) && isset( $menu_obj->term_id ) ) {
  832.             $master_navmenu = $menu_obj->term_id;
  833.         }
  834.  
  835.         if ( empty( $master_navmenu ) ) {
  836.             $master_navmenu = self::getDefaultMenu();
  837.         }
  838.  
  839.         return $master_navmenu;
  840.  
  841.     }
  842.  
  843.  
  844.     /**
  845.      * @return null|string
  846.      */
  847.     public static function getMasterLocation() {
  848.         $master_location = 'gm_primary';
  849.         $all_locations   = self::getNavMenuLocations();
  850.  
  851.         if ( empty( $all_locations[ $master_location ] ) ) {
  852.             $master_location = self::getNavMenuLocations( true );
  853.         }
  854.  
  855.         return $master_location;
  856.     }
  857.  
  858.  
  859.     public static function check_apr() {
  860.         $apr        = '';
  861.         $name       = '_' . '_l' . 'ic';
  862.         $name_cache = $name . '_cache2';
  863.         $apr_opt    = get_option( GROOVY_MENU_DB_VER_OPTION . $name );
  864.         $cache      = get_transient( GROOVY_MENU_DB_VER_OPTION . $name_cache );
  865.         if ( $apr_opt && ! $cache ) {
  866.             $get_apr  = 'ge' . 't_pa';
  867.             $get_apr  .= 'raml' . 'ic';
  868.             $name_apr = 'che' . 'ck_l';
  869.             $name_apr .= 'ic';
  870.             if ( method_exists( 'GroovyMenuUtils', $get_apr ) ) {
  871.                 $apr = self::$get_apr( 'ap' . 'pr' . 'ove' );
  872.             }
  873.             if ( $apr && method_exists( 'GroovyMenuUtils', $name_apr ) ) {
  874.                 $res = self::$name_apr( true );
  875.                 if ( $res ) {
  876.                     set_transient( GROOVY_MENU_DB_VER_OPTION . $name_cache, true, 52 * HOUR_IN_SECONDS );
  877.                 } else {
  878.                     update_option( GROOVY_MENU_DB_VER_OPTION . $name, false );
  879.                 }
  880.             } elseif ( ! $apr ) {
  881.                 update_option( GROOVY_MENU_DB_VER_OPTION . $name, false );
  882.             }
  883.         }
  884.  
  885.         return true;
  886.     }
  887.  
  888.  
  889.     /**
  890.      * Explode values for taxonomy specific field
  891.      *
  892.      * @param string $raw_value takes a value for processing as an argument.
  893.      *
  894.      * @param bool   $fill_empty_post_types
  895.      *
  896.      * @return array
  897.      */
  898.     public static function getTaxonomiesPresets( $raw_value = '', $fill_empty_post_types = true ) {
  899.  
  900.         if ( empty( $raw_value ) ) {
  901.             $styles    = new GroovyMenuStyle();
  902.             $raw_value = $styles->getGlobal( 'taxonomies', 'taxonomies_preset' );
  903.         }
  904.  
  905.         if ( empty( $raw_value ) ) {
  906.             return array();
  907.         }
  908.  
  909.         if ( is_array( $raw_value ) ) {
  910.             return $raw_value;
  911.         }
  912.  
  913.         if ( is_string( $raw_value ) ) {
  914.             $saved_value = explode( ',', $raw_value );
  915.         }
  916.  
  917.         $saved_tax      = array();
  918.         $default_values = array(
  919.             'preset' => 'default',
  920.             'menu'   => 'default',
  921.         );
  922.  
  923.         if ( ! empty( $raw_value ) && is_array( $saved_value ) ) {
  924.             foreach ( $saved_value as $tax_opt ) {
  925.                 $key_value = explode( ':::', $tax_opt );
  926.                 if ( is_array( $key_value ) && isset( $key_value[0] ) && isset( $key_value[1] ) ) {
  927.                     $tax    = $key_value[0];
  928.                     $params = explode( '@', $key_value[1] );
  929.                     if ( is_array( $params ) && isset( $params[0] ) && isset( $params[1] ) ) {
  930.                         $saved_tax[ $tax ] = array(
  931.                             'preset' => $params[0],
  932.                             'menu'   => $params[1],
  933.                         );
  934.                     } else {
  935.                         $saved_tax[ $tax ] = $default_values;
  936.                     }
  937.                 }
  938.             }
  939.         }
  940.  
  941.         if ( $fill_empty_post_types ) {
  942.  
  943.             $post_types = self::getPostTypesExtended();
  944.             foreach ( $post_types as $type_name => $type_label ) {
  945.                 if ( empty( $saved_tax[ $type_name ] ) ) {
  946.                     $saved_tax[ $type_name ] = $default_values;
  947.                 }
  948.             }
  949.  
  950.         }
  951.  
  952.  
  953.         return $saved_tax;
  954.  
  955.     }
  956.  
  957.     /**
  958.      * Implode values for taxonomy specific field
  959.      *
  960.      * @param array $taxonomies takes a value for processing as an argument.
  961.      *
  962.      * @return string
  963.      */
  964.     public static function setTaxonomiesPresets( $taxonomies = array() ) {
  965.  
  966.         if ( empty( $taxonomies ) || ! is_array( $taxonomies ) ) {
  967.             return '';
  968.         }
  969.  
  970.         $saved_value    = '';
  971.         $saved_tax      = array();
  972.         $default_values = array(
  973.             'preset' => 'default',
  974.             'menu'   => 'default',
  975.         );
  976.  
  977.         foreach ( self::getTaxonomiesPresets() as $post_type => $settings ) {
  978.             if ( empty( $taxonomies[ $post_type ] ) ) {
  979.                 $taxonomies[ $post_type ] = $settings;
  980.             }
  981.         }
  982.  
  983.         foreach ( $taxonomies as $post_type => $settings ) {
  984.             $value_preset = empty( $settings['preset'] ) ? $default_values['preset'] : $settings['preset'];
  985.             $value_menu   = empty( $settings['menu'] ) ? $default_values['menu'] : $settings['menu'];
  986.  
  987.             $saved_tax[] = $post_type . ':::' . $value_preset . '@' . $value_menu;
  988.         }
  989.  
  990.         if ( ! empty( $saved_tax ) ) {
  991.             $saved_value = implode( ',', $saved_tax );
  992.         }
  993.  
  994.  
  995.         return $saved_value;
  996.  
  997.     }
  998.  
  999.  
  1000.     /**
  1001.      * @param $post_type
  1002.      *
  1003.      * @return array|mixed
  1004.      */
  1005.     public static function getTaxonomiesPresetByPostType( $post_type ) {
  1006.  
  1007.         $styles           = new GroovyMenuStyle();
  1008.         $override_for_tax = $styles->getGlobal( 'taxonomies', 'override_for_tax' );
  1009.         $return_values    = array(
  1010.             'preset' => 'default',
  1011.             'menu'   => 'default',
  1012.         );
  1013.  
  1014.         if ( ! $override_for_tax ) {
  1015.             return $return_values;
  1016.         }
  1017.  
  1018.         $saved_tax = self::getTaxonomiesPresets();
  1019.  
  1020.         if ( ! empty( $saved_tax[ $post_type ] ) ) {
  1021.             $return_values = $saved_tax[ $post_type ];
  1022.         }
  1023.  
  1024.         return $return_values;
  1025.  
  1026.     }
  1027.  
  1028.     /**
  1029.      * Get all the registered image sizes along with their dimensions
  1030.      *
  1031.      * @global array $_wp_additional_image_sizes
  1032.      *
  1033.      * @link http://core.trac.wordpress.org/ticket/18947 Reference ticket
  1034.      *
  1035.      * @return array $image_sizes The image sizes
  1036.      */
  1037.     public static function get_all_image_sizes() {
  1038.         global $_wp_additional_image_sizes;
  1039.  
  1040.         $default_image_sizes = get_intermediate_image_sizes();
  1041.  
  1042.         $image_sizes = array( 'full' => array() );
  1043.  
  1044.         foreach ( $default_image_sizes as $size ) {
  1045.             $image_sizes[ $size ]['width']  = intval( get_option( "{$size}_size_w" ) );
  1046.             $image_sizes[ $size ]['height'] = intval( get_option( "{$size}_size_h" ) );
  1047.             $image_sizes[ $size ]['crop']   = get_option( "{$size}_crop" ) ? get_option( "{$size}_crop" ) : false;
  1048.         }
  1049.  
  1050.         if ( isset( $_wp_additional_image_sizes ) && count( $_wp_additional_image_sizes ) ) {
  1051.             $image_sizes = array_merge( $image_sizes, $_wp_additional_image_sizes );
  1052.         }
  1053.  
  1054.         return $image_sizes;
  1055.     }
  1056.  
  1057.     /**
  1058.      * Get all the registered image sizes for key value
  1059.      *
  1060.      * @return array $image_sizes_array The image sizes.
  1061.      */
  1062.     public static function get_all_image_sizes_for_select() {
  1063.         $image_sizes_array = array( 'full' => esc_html__( 'Original full size', 'groovy-menu' ) );
  1064.         $image_sizes       = self::get_all_image_sizes();
  1065.  
  1066.         foreach ( $image_sizes as $size => $size_data ) {
  1067.             $image_sizes_array[ $size ] = $size;
  1068.         }
  1069.  
  1070.         return $image_sizes_array;
  1071.     }
  1072.  
  1073.     public static function groovy_wpml_register_single_string( GroovyMenuStyle $styles ) {
  1074.  
  1075.         $logo_text     = $styles->getGlobal( 'logo', 'logo_text' );
  1076.         $toolbar_email = $styles->getGlobal( 'toolbar', 'toolbar_email' );
  1077.         $toolbar_phone = $styles->getGlobal( 'toolbar', 'toolbar_phone' );
  1078.  
  1079.         //WPML
  1080.         /**
  1081.          * register strings for translation.
  1082.          */
  1083.         do_action( 'wpml_register_single_string', 'groovy-menu', 'Global settings - logo text', $logo_text );
  1084.         do_action( 'wpml_register_single_string', 'groovy-menu', 'Global settings - toolbar email text', $toolbar_email );
  1085.         do_action( 'wpml_register_single_string', 'groovy-menu', 'Global settings - toolbar phone text', $toolbar_phone );
  1086.         //WPML
  1087.  
  1088.     }
  1089.  
  1090.     public static function getAutoIntegrationOptionName() {
  1091.         return 'gm_auto_integrate_locations_';
  1092.     }
  1093.  
  1094.     public static function getIntegrationConfigOptionName() {
  1095.         return 'gm_integrate_config_';
  1096.     }
  1097.  
  1098.     /**
  1099.      * Check if in auto-integration mode
  1100.      *
  1101.      * @return bool
  1102.      */
  1103.     public static function getAutoIntegration() {
  1104.         global $gm_supported_module;
  1105.  
  1106.         if ( isset( $gm_supported_module['GroovyMenuShowIntegration'] ) && ! $gm_supported_module['GroovyMenuShowIntegration'] ) {
  1107.             return false;
  1108.         }
  1109.  
  1110.         if ( isset( $_REQUEST['mailpoet_router'] ) ) { // @codingStandardsIgnoreLine
  1111.             return false;
  1112.         }
  1113.  
  1114.         $theme_name     = empty( $gm_supported_module['theme'] ) ? wp_get_theme()->get_template() : $gm_supported_module['theme'];
  1115.         $integrate_data = get_option( self::getAutoIntegrationOptionName() . $theme_name );
  1116.         $return_value   = ( ! empty( $integrate_data ) && $integrate_data ) ? true : false;
  1117.  
  1118.         return $return_value;
  1119.     }
  1120.  
  1121.     /**
  1122.      * Check if in integration location selected
  1123.      *
  1124.      * @return bool
  1125.      */
  1126.     public static function getSingleLocationIntegration() {
  1127.         global $gm_supported_module;
  1128.  
  1129.         $theme_name       = empty( $gm_supported_module['theme'] ) ? wp_get_theme()->get_template() : $gm_supported_module['theme'];
  1130.         $integrate_config = get_option( self::getIntegrationConfigOptionName() . $theme_name );
  1131.  
  1132.         $return_value = '';
  1133.  
  1134.         if ( ! empty( $integrate_config ) && ! empty( $integrate_config['single_location'] ) ) {
  1135.             $return_value = esc_attr( $integrate_config['single_location'] );
  1136.         }
  1137.  
  1138.         return $return_value;
  1139.     }
  1140.  
  1141.  
  1142.     public static function get_posts_fields( $args = array() ) {
  1143.         $valid_fields = array(
  1144.             'ID'             => '%d',
  1145.             'post_author'    => '%d',
  1146.             'post_type'      => '%s',
  1147.             'post_mime_type' => '%s',
  1148.             'post_title'     => false,
  1149.             'post_name'      => '%s',
  1150.             'post_date'      => '%s',
  1151.             'post_modified'  => '%s',
  1152.             'menu_order'     => '%d',
  1153.             'post_parent'    => '%d',
  1154.             'post_excerpt'   => false,
  1155.             'post_content'   => false,
  1156.             'post_status'    => '%s',
  1157.             'comment_status' => false,
  1158.             'ping_status'    => false,
  1159.             'to_ping'        => false,
  1160.             'pinged'         => false,
  1161.             'comment_count'  => '%d'
  1162.         );
  1163.         $defaults     = array(
  1164.             'post_type'      => 'groovy_menu_preset',
  1165.             'post_status'    => 'publish',
  1166.             'orderby'        => 'post_date',
  1167.             'order'          => 'DESC',
  1168.             'posts_per_page' => - 1,
  1169.         );
  1170.  
  1171.         $order = $orderby = $posts_per_page = '';
  1172.  
  1173.         global $wpdb;
  1174.         $args  = wp_parse_args( $args, $defaults );
  1175.         $where = "";
  1176.         foreach ( $valid_fields as $field => $can_query ) {
  1177.             if ( isset( $args[ $field ] ) && $can_query ) {
  1178.                 if ( '' !== $where ) {
  1179.                     $where .= ' AND ';
  1180.                 }
  1181.                 $where .= $wpdb->prepare( $field . " = " . $can_query, $args[ $field ] );
  1182.             }
  1183.         }
  1184.         if ( isset( $args['search'] ) && is_string( $args['search'] ) ) {
  1185.             if ( '' !== $where ) {
  1186.                 $where .= ' AND ';
  1187.             }
  1188.             $where .= $wpdb->prepare( "post_title LIKE %s", "%" . $args['search'] . "%" );
  1189.         }
  1190.         if ( isset( $args['include'] ) ) {
  1191.             if ( is_string( $args['include'] ) ) {
  1192.                 $args['include'] = explode( ',', $args['include'] );
  1193.             }
  1194.             if ( is_array( $args['include'] ) ) {
  1195.                 $args['include'] = array_map( 'intval', $args['include'] );
  1196.                 if ( '' !== $where ) {
  1197.                     $where .= ' OR ';
  1198.                 }
  1199.                 $where .= "ID IN (" . implode( ',', $args['include'] ) . ")";
  1200.             }
  1201.         }
  1202.         if ( isset( $args['exclude'] ) ) {
  1203.             if ( is_string( $args['exclude'] ) ) {
  1204.                 $args['exclude'] = explode( ',', $args['exclude'] );
  1205.             }
  1206.             if ( is_array( $args['exclude'] ) ) {
  1207.                 $args['exclude'] = array_map( 'intval', $args['exclude'] );
  1208.                 if ( '' !== $where ) {
  1209.                     $where .= ' AND ';
  1210.                 }
  1211.                 $where .= "ID NOT IN (" . implode( ',', $args['exclude'] ) . ")";
  1212.             }
  1213.         }
  1214.         extract( $args );
  1215.         $iscol = false;
  1216.         if ( isset( $fields ) ) {
  1217.             if ( is_string( $fields ) ) {
  1218.                 $fields = explode( ',', $fields );
  1219.             }
  1220.             if ( is_array( $fields ) ) {
  1221.                 $fields = array_intersect( $fields, array_keys( $valid_fields ) );
  1222.                 if ( count( $fields ) === 1 ) {
  1223.                     $iscol = true;
  1224.                 }
  1225.                 $fields = implode( ',', $fields );
  1226.             }
  1227.         }
  1228.         if ( empty( $fields ) ) {
  1229.             $fields = '*';
  1230.         }
  1231.         if ( ! in_array( $orderby, $valid_fields ) ) {
  1232.             $orderby = 'post_date';
  1233.         }
  1234.         if ( ! in_array( strtoupper( $order ), array( 'ASC', 'DESC' ) ) ) {
  1235.             $order = 'DESC';
  1236.         }
  1237.         if ( ! intval( $posts_per_page ) && $posts_per_page != - 1 ) {
  1238.             $posts_per_page = $defaults['posts_per_page'];
  1239.         }
  1240.         if ( '' === $where ) {
  1241.             $where = '1';
  1242.         }
  1243.         $q = "SELECT $fields FROM $wpdb->posts WHERE " . $where;
  1244.         $q .= " ORDER BY $orderby $order";
  1245.         if ( $posts_per_page != - 1 ) {
  1246.             $q .= " LIMIT $posts_per_page";
  1247.         }
  1248.  
  1249.         return $iscol ? $wpdb->get_col( $q ) : $wpdb->get_results( $q );
  1250.     }
  1251.  
  1252.     /**
  1253.      * Adds meta links to the plugin in the WP Admin > Plugins screen
  1254.      *
  1255.      * @param array  $links
  1256.      * @param string $file
  1257.      *
  1258.      * @return array
  1259.      */
  1260.     public static function gm_plugin_meta_links( $links, $file ) {
  1261.         if ( 'groovy-menu/groovy-menu.php' !== $file ) {
  1262.             return $links;
  1263.         }
  1264.  
  1265.         $lver = false;
  1266.         if ( defined( 'GROOVY_MENU_LVER' ) && '2' === GROOVY_MENU_LVER ) {
  1267.             $lver = true;
  1268.         }
  1269.  
  1270.         if ( $lver ) {
  1271.             $links[] = '<a href="https://grooni.com/docs/groovy-menu/" target="_blank">' . esc_html__( 'Docs', 'groovy-menu' ) . '</a>';
  1272.             $links[] = '<a href="https://wordpress.org/support/plugin/groovy-menu/" target="_blank"">' . esc_html__( 'Free support', 'groovy-menu' ) . '</a>';
  1273.         } else {
  1274.             $links[] = '<a href="https://grooni.com/docs/groovy-menu/" target="_blank">' . esc_html__( 'Docs', 'groovy-menu' ) . '</a>';
  1275.             $links[] = '<a href="https://grooni.ticksy.com/" target="_blank"">' . esc_html__( 'Get Support', 'groovy-menu' ) . '</a>';
  1276.         }
  1277.  
  1278.         return $links;
  1279.     }
  1280.  
  1281.     /**
  1282.      * Adds plugin action links to the plugin in the WP Admin > Plugins screen
  1283.      *
  1284.      * @param array  $actions
  1285.      * @param string $plugin_file
  1286.      *
  1287.      * @return array
  1288.      */
  1289.     public static function gm_plugin_page_links( $actions, $plugin_file ) {
  1290.  
  1291.         $basename = defined( 'GROOVY_MENU_BASENAME' ) ? GROOVY_MENU_BASENAME : 'groovy-menu.php';
  1292.  
  1293.         if ( false === strpos( $plugin_file, $basename ) ) {
  1294.             return $actions;
  1295.         }
  1296.  
  1297.         $settings_link = '<a href="' . admin_url( 'admin.php?page=groovy_menu_settings' ) . '" target="_blank">' . esc_html__( 'Settings', 'groovy-menu' ) . '</a>';
  1298.         array_unshift( $actions, $settings_link );
  1299.  
  1300.         $lver = false;
  1301.         if ( defined( 'GROOVY_MENU_LVER' ) && '2' === GROOVY_MENU_LVER ) {
  1302.             $lver = true;
  1303.         }
  1304.  
  1305.         if ( $lver && 'groovy-menu-free/groovy-menu.php' === $plugin_file ) {
  1306.             $addcss_arr = array(
  1307.                 'color'       => '#3e9e16',
  1308.                 'font-weight' => 'bold',
  1309.             );
  1310.             $addcss     = '';
  1311.             foreach ( $addcss_arr as $index => $item ) {
  1312.                 $addcss .= $index . ': ' . $item . ';';
  1313.             }
  1314.             $addcss       = 'style' . '="' . $addcss . '"';
  1315.             $upgrade_link = '<a href="https://groovymenu.grooni.com/upgrade/" target="_blank"><span ' . $addcss . '>' . esc_html__( 'Upgrade to Pro', 'groovy-menu' ) . '</span></a>';
  1316.             array_unshift( $actions, $upgrade_link );
  1317.         }
  1318.  
  1319.         return $actions;
  1320.     }
  1321.  
  1322.  
  1323.     /**
  1324.      * Install default fonts.
  1325.      *
  1326.      * @param bool $self_install
  1327.      *
  1328.      * @return null|void
  1329.      */
  1330.     public static function install_default_icon_packs( $self_install = false ) {
  1331.  
  1332.         $message        = 'done';
  1333.         $uploaded_fonts = \GroovyMenu\FieldIcons::getFonts();
  1334.         $default_packs  = GroovyMenuUtils::get_default_icon_packs_list();
  1335.  
  1336.         if ( is_array( $uploaded_fonts ) && ! empty( $uploaded_fonts ) ) {
  1337.             foreach ( $uploaded_fonts as $index => $_font ) {
  1338.                 if ( isset( $_font['name'] ) && isset( $default_packs[ $_font['name'] ] ) ) {
  1339.                     unset( $default_packs[ $_font['name'] ] );
  1340.                 }
  1341.             }
  1342.         }
  1343.  
  1344.         if ( ! empty( $default_packs ) ) {
  1345.  
  1346.             if ( class_exists( 'ZipArchive' ) ) {
  1347.  
  1348.                 if ( ! defined( 'FS_METHOD' ) ) {
  1349.                     define( 'FS_METHOD', 'direct' );
  1350.                 }
  1351.  
  1352.                 global $wp_filesystem;
  1353.                 if ( empty( $wp_filesystem ) ) {
  1354.                     if ( file_exists( ABSPATH . '/wp-admin/includes/file.php' ) ) {
  1355.                         require_once ABSPATH . '/wp-admin/includes/file.php';
  1356.                         WP_Filesystem();
  1357.                     }
  1358.                 }
  1359.                 if ( empty( $wp_filesystem ) ) {
  1360.                     @ob_clean();
  1361.  
  1362.                     if ( ! $self_install ) {
  1363.                         wp_send_json( array(
  1364.                             'status'  => 'critical_error',
  1365.                             'message' => esc_html__( 'WP_Filesystem() load library error', 'groovy-menu' )
  1366.                         ), 500 );
  1367.                     } else {
  1368.                         return null;
  1369.                     }
  1370.                 }
  1371.  
  1372.  
  1373.                 foreach ( $default_packs as $index => $default_pack ) {
  1374.  
  1375.                     $url = $default_pack['url'];
  1376.  
  1377.                     // create temp folder
  1378.                     $_tmp = wp_tempnam( $url );
  1379.                     @unlink( $_tmp );
  1380.  
  1381.                     $package = download_url( $url, 360 );
  1382.  
  1383.                     if ( is_wp_error( $package ) ) {
  1384.                         continue;
  1385.                     }
  1386.  
  1387.                     $zip = new \ZipArchive();
  1388.                     if ( $zip->open( $package ) ) {
  1389.                         $fonts = \GroovyMenu\FieldIcons::getFonts();
  1390.  
  1391.                         $selection     = $zip->getFromName( 'selection.json' );
  1392.                         $selectionData = json_decode( $selection, true );
  1393.                         $name          = $default_pack['internal_name'];
  1394.  
  1395.                         $fontFiles['woff'] = $zip->getFromName( 'fonts/' . $selectionData['metadata']['name'] . '.woff' );
  1396.                         $fontFiles['ttf']  = $zip->getFromName( 'fonts/' . $selectionData['metadata']['name'] . '.ttf' );
  1397.                         $fontFiles['svg']  = $zip->getFromName( 'fonts/' . $selectionData['metadata']['name'] . '.svg' );
  1398.                         $fontFiles['eot']  = $zip->getFromName( 'fonts/' . $selectionData['metadata']['name'] . '.eot' );
  1399.  
  1400.                         $dir = GroovyMenuUtils::getFontsDir();
  1401.                         wp_mkdir_p( $dir );
  1402.  
  1403.                         file_put_contents( $dir . $name . '.woff', $fontFiles['woff'] );
  1404.                         file_put_contents( $dir . $name . '.ttf', $fontFiles['ttf'] );
  1405.                         file_put_contents( $dir . $name . '.svg', $fontFiles['svg'] );
  1406.                         file_put_contents( $dir . $name . '.eot', $fontFiles['eot'] );
  1407.                         file_put_contents( $dir . $name . '.css',
  1408.                             self::generate_fonts_css( $name, $selectionData ) );
  1409.  
  1410.                         $icons = array();
  1411.                         foreach ( $selectionData['icons'] as $icon ) {
  1412.                             $icons[] = array(
  1413.                                 'name' => $icon['icon']['tags'][0],
  1414.                                 'code' => $icon['properties']['code']
  1415.                             );
  1416.                         }
  1417.                         $fonts[ $name ] = array( 'icons' => $icons, 'name' => $selectionData['metadata']['name'] );
  1418.                         \GroovyMenu\FieldIcons::setFonts( $fonts );
  1419.                     }
  1420.                 }
  1421.             } else {
  1422.                 $message = esc_html__( "Wasn't able to work with Zip Archive. Missing php-zip extension.", 'groovy-menu' );
  1423.             }
  1424.         }
  1425.  
  1426.         if ( ! $self_install ) {
  1427.             $output = array( 'message' => $message );
  1428.             wp_die( wp_json_encode( $output ) );
  1429.         }
  1430.     }
  1431.  
  1432.     /**
  1433.      * @param $name
  1434.      * @param $selectionData
  1435.      *
  1436.      * @return string
  1437.      */
  1438.     public static function generate_fonts_css( $name, $selectionData ) {
  1439.         $css = '
  1440. @font-face {
  1441.     font-family: \'' . $name . '\';
  1442.     src:url(\'' . $name . '.eot?jk3qnc\');
  1443.     src:url(\'' . $name . '.eot?jk3qnc#iefix\') format(\'embedded-opentype\'),
  1444.         url(\'' . $name . '.ttf?jk3qnc\') format(\'truetype\'),
  1445.         url(\'' . $name . '.woff?jk3qnc\') format(\'woff\'),
  1446.         url(\'' . $name . '.svg?jk3qnc#icomoon1\') format(\'svg\');
  1447.     font-weight: normal;
  1448.     font-style: normal;
  1449. }
  1450.  
  1451. [class^="' . $name . '"],
  1452. [class*=" ' . $name . '"] {
  1453.     font-family: \'' . $name . '\';
  1454.     speak: none;
  1455.     font-style: normal;
  1456.     font-weight: normal;
  1457.     font-variant: normal;
  1458.     text-transform: none;
  1459.     line-height: 1;
  1460.  
  1461.     /* Enable Ligatures ================ */
  1462.     letter-spacing: 0;
  1463.     -webkit-font-feature-settings: "liga";
  1464.     -moz-font-feature-settings: "liga=1";
  1465.     -moz-font-feature-settings: "liga";
  1466.     -ms-font-feature-settings: "liga" 1;
  1467.     -o-font-feature-settings: "liga";
  1468.     font-feature-settings: "liga";
  1469.  
  1470.     /* Better Font Rendering =========== */
  1471.     -webkit-font-smoothing: antialiased;
  1472.     -moz-osx-font-smoothing: grayscale;
  1473. }
  1474. ';
  1475.  
  1476.         foreach ( $selectionData['icons'] as $icon ) {
  1477.             $iconName = $icon['icon']['tags'][0];
  1478.             $code     = dechex( $icon['properties']['code'] );
  1479.             $css      .= '.' . $name . '-' . $iconName . ':before { content: \'\\' . $code . '\'; }';
  1480.  
  1481.         }
  1482.  
  1483.         return $css;
  1484.     }
  1485.  
  1486.     /**
  1487.      * Get default icon packs list
  1488.      *
  1489.      * @return array
  1490.      */
  1491.     public static function get_default_icon_packs_list() {
  1492.         $packs = array(
  1493.             'wp-Ingenicons'     => array(
  1494.                 'name'          => 'wp-Ingenicons',
  1495.                 'url'           => 'https://license.grooni.com/wp-update-server/icon_packs/wp-Ingenicons.zip',
  1496.                 'internal_name' => 'groovy-28328'
  1497.             ),
  1498.             'Simple-Line-Icons' => array(
  1499.                 'name'          => 'Simple-Line-Icons',
  1500.                 'url'           => 'https://license.grooni.com/wp-update-server/icon_packs/Simple-Line-Icons.zip',
  1501.                 'internal_name' => 'groovy-69018'
  1502.             ),
  1503.             'socicon'           => array(
  1504.                 'name'          => 'socicon',
  1505.                 'url'           => 'https://license.grooni.com/wp-update-server/icon_packs/socicon.zip',
  1506.                 'internal_name' => 'groovy-socicon'
  1507.             ),
  1508.         );
  1509.  
  1510.         return $packs;
  1511.     }
  1512.  
  1513.  
  1514.     /**
  1515.      * Short-circuit the wp_nav_menu() output if we have cached output ready.
  1516.      *
  1517.      * Returning a non-null value to the filter will short-circuit
  1518.      * wp_nav_menu(), echoing that value if $args->echo is true,
  1519.      * returning that value otherwise.
  1520.      *
  1521.      * @see wp_nav_menu()
  1522.      *
  1523.      * @param string|null $output Nav menu output to short-circuit with. Default null.
  1524.      * @param stdClass    $args   An object containing wp_nav_menu() arguments.
  1525.      *
  1526.      * @return string|null Nav menu output to short-circuit with. Passthrough (default null) if we don’t have a cached version.
  1527.      */
  1528.     public static function cache_pre_wp_nav_menu( $output, $args ) {
  1529.  
  1530.         static $gm_nav_menu_items = array();
  1531.         static $menu_id_slugs = array();
  1532.  
  1533.         if ( empty( $args->gm_preset_id ) || ! isset( $args->gm_echo ) ) {
  1534.             return $output;
  1535.         }
  1536.  
  1537.         /* This section is from wp_nav_menu(). It is here to find a menu when none is provided. */
  1538.         // @codingStandardsIgnoreStart
  1539.  
  1540.         // Get the nav menu based on the requested menu
  1541.         $menu = wp_get_nav_menu_object( $args->menu );
  1542.  
  1543.         // Get the nav menu based on the theme_location
  1544.         if ( ! $menu && $args->theme_location && ( $locations = get_nav_menu_locations() ) && isset( $locations[ $args->theme_location ] ) ) {
  1545.             $menu = wp_get_nav_menu_object( $locations[ $args->theme_location ] );
  1546.         }
  1547.  
  1548.         // get the first menu that has items if we still can't find a menu
  1549.         if ( ! $menu && ! $args->theme_location ) {
  1550.             $menus = wp_get_nav_menus();
  1551.             foreach ( $menus as $menu_maybe ) {
  1552.                 if ( $menu_items = wp_get_nav_menu_items( $menu_maybe->term_id, array( 'update_post_term_cache' => false ) ) ) {
  1553.                     $menu = $menu_maybe;
  1554.                     break;
  1555.                 }
  1556.             }
  1557.         }
  1558.  
  1559.         if ( empty( $args->menu ) ) {
  1560.             $args->menu = $menu;
  1561.         }
  1562.  
  1563.         // If the menu exists, get its items.
  1564.         if ( $menu && ! is_wp_error( $menu ) && ! isset( $menu_items ) ) {
  1565.             // DiS. GM cache condition.
  1566.             if ( empty( $gm_nav_menu_items[ $menu->term_id ] ) ) {
  1567.                 $menu_items                          = wp_get_nav_menu_items( $menu->term_id, array( 'update_post_term_cache' => false ) );
  1568.                 $gm_nav_menu_items[ $menu->term_id ] = $menu_items;
  1569.                 global $groovyMenuSettings;
  1570.                 $groovyMenuSettings['nav_menu_data']['data'][ $menu->term_id ] = $menu_items;
  1571.             } else {
  1572.                 $menu_items = $gm_nav_menu_items[ $menu->term_id ];
  1573.             }
  1574.         }
  1575.  
  1576.         /*
  1577.          * If no menu was found:
  1578.          *  - Fall back (if one was specified), or bail.
  1579.          *
  1580.          * If no menu items were found:
  1581.          *  - Fall back, but only if no theme location was specified.
  1582.          *  - Otherwise, bail.
  1583.          */
  1584.         if ( ( ! $menu || is_wp_error( $menu ) || ( isset( $menu_items ) && empty( $menu_items ) && ! $args->theme_location ) )
  1585.              && isset( $args->fallback_cb ) && $args->fallback_cb && is_callable( $args->fallback_cb ) ) {
  1586.             return call_user_func( $args->fallback_cb, (array) $args );
  1587.         }
  1588.  
  1589.         if ( ! $menu || is_wp_error( $menu ) ) {
  1590.             return false;
  1591.         }
  1592.  
  1593.         $nav_menu = $items = '';
  1594.  
  1595.         $show_container = false;
  1596.         if ( $args->container ) {
  1597.             /**
  1598.              * Filters the list of HTML tags that are valid for use as menu containers.
  1599.              *
  1600.              * @since 3.0.0
  1601.              *
  1602.              * @param array $tags The acceptable HTML tags for use as menu containers.
  1603.              *                    Default is array containing 'div' and 'nav'.
  1604.              */
  1605.             $allowed_tags = apply_filters( 'wp_nav_menu_container_allowedtags', array( 'div', 'nav' ) );
  1606.             if ( is_string( $args->container ) && in_array( $args->container, $allowed_tags ) ) {
  1607.                 $show_container = true;
  1608.                 $class          = $args->container_class ? ' class="' . esc_attr( $args->container_class ) . '"' : ' class="menu-' . $menu->slug . '-container"';
  1609.                 $id             = $args->container_id ? ' id="' . esc_attr( $args->container_id ) . '"' : '';
  1610.                 $nav_menu       .= '<' . $args->container . $id . $class . '>';
  1611.             }
  1612.         }
  1613.  
  1614.         // Set up the $menu_item variables
  1615.         _wp_menu_item_classes_by_context( $menu_items );
  1616.  
  1617.         $sorted_menu_items = $menu_items_with_children = array();
  1618.         foreach ( (array) $menu_items as $menu_item ) {
  1619.             $sorted_menu_items[ $menu_item->menu_order ] = $menu_item;
  1620.             if ( $menu_item->menu_item_parent ) {
  1621.                 $menu_items_with_children[ $menu_item->menu_item_parent ] = true;
  1622.             }
  1623.         }
  1624.  
  1625.         // Add the menu-item-has-children class where applicable
  1626.         if ( $menu_items_with_children ) {
  1627.             foreach ( $sorted_menu_items as &$menu_item ) {
  1628.                 if ( isset( $menu_items_with_children[ $menu_item->ID ] ) ) {
  1629.                     $menu_item->classes[] = 'menu-item-has-children';
  1630.                 }
  1631.             }
  1632.         }
  1633.  
  1634.         unset( $menu_items, $menu_item );
  1635.  
  1636.         /**
  1637.          * Filters the sorted list of menu item objects before generating the menu's HTML.
  1638.          *
  1639.          * @since 3.1.0
  1640.          *
  1641.          * @param array    $sorted_menu_items The menu items, sorted by each menu item's menu order.
  1642.          * @param stdClass $args              An object containing wp_nav_menu() arguments.
  1643.          */
  1644.         $sorted_menu_items = apply_filters( 'wp_nav_menu_objects', $sorted_menu_items, $args );
  1645.  
  1646.         $items .= walk_nav_menu_tree( $sorted_menu_items, $args->depth, $args );
  1647.         unset( $sorted_menu_items );
  1648.  
  1649.         // Attributes
  1650.         if ( ! empty( $args->menu_id ) ) {
  1651.             $wrap_id = $args->menu_id;
  1652.         } else {
  1653.             $wrap_id = 'menu-' . $menu->slug;
  1654.             while ( in_array( $wrap_id, $menu_id_slugs ) ) {
  1655.                 if ( preg_match( '#-(\d+)$#', $wrap_id, $matches ) ) {
  1656.                     $wrap_id = preg_replace( '#-(\d+)$#', '-' . ++ $matches[1], $wrap_id );
  1657.                 } else {
  1658.                     $wrap_id = $wrap_id . '-1';
  1659.                 }
  1660.             }
  1661.         }
  1662.         $menu_id_slugs[] = $wrap_id;
  1663.  
  1664.         $wrap_class = $args->menu_class ? $args->menu_class : '';
  1665.  
  1666.         /**
  1667.          * Filters the HTML list content for navigation menus.
  1668.          *
  1669.          * @since 3.0.0
  1670.          *
  1671.          * @see   wp_nav_menu()
  1672.          *
  1673.          * @param string   $items The HTML list content for the menu items.
  1674.          * @param stdClass $args  An object containing wp_nav_menu() arguments.
  1675.          */
  1676.         $items = apply_filters( 'wp_nav_menu_items', $items, $args );
  1677.         /**
  1678.          * Filters the HTML list content for a specific navigation menu.
  1679.          *
  1680.          * @since 3.0.0
  1681.          *
  1682.          * @see   wp_nav_menu()
  1683.          *
  1684.          * @param string   $items The HTML list content for the menu items.
  1685.          * @param stdClass $args  An object containing wp_nav_menu() arguments.
  1686.          */
  1687.         $items = apply_filters( "wp_nav_menu_{$menu->slug}_items", $items, $args );
  1688.  
  1689.         // Don't print any markup if there are no items at this point.
  1690.         if ( empty( $items ) ) {
  1691.             return false;
  1692.         }
  1693.  
  1694.         $nav_menu .= sprintf( $args->items_wrap, esc_attr( $wrap_id ), esc_attr( $wrap_class ), $items );
  1695.         unset( $items );
  1696.  
  1697.         if ( $show_container ) {
  1698.             $nav_menu .= '</' . $args->container . '>';
  1699.         }
  1700.  
  1701.         /**
  1702.          * Filters the HTML content for navigation menus.
  1703.          *
  1704.          * @since 3.0.0
  1705.          *
  1706.          * @see   wp_nav_menu()
  1707.          *
  1708.          * @param string   $nav_menu The HTML content for the navigation menu.
  1709.          * @param stdClass $args     An object containing wp_nav_menu() arguments.
  1710.          */
  1711.         $nav_menu = apply_filters( 'wp_nav_menu', $nav_menu, $args );
  1712.  
  1713.         if ( $args->echo ) {
  1714.             echo $nav_menu;
  1715.         } else {
  1716.             return $nav_menu;
  1717.         }
  1718.  
  1719.         // @codingStandardsIgnoreEnd
  1720.         /* End of the section from wp_nav_menu(). It was a pleasure, ladies and gents. */
  1721.     }
  1722.  
  1723.  
  1724.     public static function show_gm_php_version() {
  1725.         ?>
  1726.  
  1727.         <div id="gm-upgrade-notice" class="notice-error settings-error notice is-dismissible">
  1728.             <p class="gm-install-addons-text-block">
  1729.                 <?php
  1730.                 esc_html_e( 'Plugin Groovy Menu  is deactivated. Minimum required version for PHP 7.', 'groovy-menu' );
  1731.                 echo ' <a href="' . get_admin_url( null, 'plugins.php', 'relative' ) . '">';
  1732.                 esc_html_e( 'Plugins page', 'groovy-menu' );
  1733.                 echo '</a> ';
  1734.                 ?>
  1735.                 <br>
  1736.             </p>
  1737.         </div>
  1738.         <?php
  1739.     }
  1740.  
  1741.  
  1742.     /**
  1743.      * Short-circuit the wp_nav_menu() output if we have cached Groovy Menu markup ready.
  1744.      *
  1745.      * Returning a non-null value to the filter will short-circuit
  1746.      * wp_nav_menu(), echoing that value if $args->echo is true,
  1747.      * returning that value otherwise.
  1748.      *
  1749.      * @see wp_nav_menu()
  1750.      *
  1751.      * @param string|null $output Nav menu output to short-circuit with. Default null.
  1752.      * @param stdClass    $args   An object containing wp_nav_menu() arguments.
  1753.      *
  1754.      * @return string|null Nav menu output to short-circuit with. Passthrough (default null) if we don’t have a cached version.
  1755.      */
  1756.     public static function add_groovy_menu_as_wp_nav_menu( $output, $args ) {
  1757.  
  1758.         // Prevent recursion by call wp_nav_menu()
  1759.         if ( ( isset( $args->groovy_menu ) && $args->groovy_menu ) || isset( $args->gm_pre_storage ) && $args->gm_pre_storage ) {
  1760.             return $output;
  1761.         }
  1762.  
  1763.         $gm_html = '';
  1764.  
  1765.         $saved_integration_location = self::getSingleLocationIntegration();
  1766.  
  1767.         if ( ! $output && ! empty( $saved_integration_location ) && isset( $args->theme_location ) && esc_attr( $saved_integration_location ) === $args->theme_location ) {
  1768.  
  1769.             $gm_ids = \GroovyMenu\PreStorage::get_instance()->search_ids_by_location( array( 'theme_location' => 'gm_primary' ) );
  1770.  
  1771.             if ( ! empty( $gm_ids ) ) {
  1772.                 foreach ( $gm_ids as $gm_id ) {
  1773.                     $gm_data = \GroovyMenu\PreStorage::get_instance()->get_gm( $gm_id );
  1774.                     $gm_html .= $gm_data['gm_html'];
  1775.  
  1776.                 }
  1777.             } else {
  1778.                 $gm_html .= groovy_menu( [
  1779.                     'gm_echo'        => false,
  1780.                     'theme_location' => 'gm_primary',
  1781.                 ] );
  1782.             }
  1783.  
  1784.         }
  1785.  
  1786.         if ( ! empty( $gm_html ) ) {
  1787.             $output = $gm_html;
  1788.         }
  1789.  
  1790.         return $output;
  1791.  
  1792.     }
  1793.  
  1794.  
  1795.     public static function update_config_text_domain() {
  1796.         $config_global   = include GROOVY_MENU_DIR . 'includes/config/ConfigGlobal.php';
  1797.         $settings_global = \GroovyMenu\StyleStorage::getInstance()->get_global_settings();
  1798.  
  1799.         $updated = false;
  1800.  
  1801.         if ( ! empty( $settings_global ) && is_array( $settings_global ) && is_array( $config_global ) ) {
  1802.  
  1803.             foreach ( $config_global as $category_name => $category ) {
  1804.  
  1805.                 if ( isset( $category['title'] ) && isset( $settings_global[ $category_name ]['title'] ) ) {
  1806.                     if ( $settings_global[ $category_name ]['title'] !== $category['title'] ) {
  1807.                         $settings_global[ $category_name ]['title'] = $category['title'];
  1808.  
  1809.                         $updated = true;
  1810.                     }
  1811.                 }
  1812.  
  1813.                 if ( isset( $category['fields'] ) ) {
  1814.                     foreach ( $category['fields'] as $field => $config_value ) {
  1815.                         if ( isset( $settings_global[ $category_name ]['fields'][ $field ] ) ) {
  1816.  
  1817.                             $settings_global_value = $settings_global[ $category_name ]['fields'][ $field ];
  1818.  
  1819.                             if ( isset( $config_value['title'] ) && isset( $settings_global_value['title'] ) ) {
  1820.                                 if ( $settings_global_value['title'] !== $config_value['title'] ) {
  1821.                                     $settings_global[ $category_name ]['fields'][ $field ]['title'] = $config_value['title'];
  1822.  
  1823.                                     $updated = true;
  1824.                                 }
  1825.                             }
  1826.                             if ( isset( $config_value['description'] ) && isset( $settings_global_value['description'] ) ) {
  1827.                                 if ( $settings_global_value['description'] !== $config_value['description'] ) {
  1828.                                     $settings_global[ $category_name ]['fields'][ $field ]['description'] = $config_value['description'];
  1829.  
  1830.                                     $updated = true;
  1831.                                 }
  1832.                             }
  1833.                             if ( isset( $config_value['options'] ) && isset( $settings_global_value['options'] ) && is_array( $config_value['options'] ) ) {
  1834.                                 foreach ( $config_value['options'] as $index => $option ) {
  1835.  
  1836.                                     if ( empty( $settings_global_value['options'][ $index ] ) ) {
  1837.                                         continue;
  1838.                                     }
  1839.  
  1840.                                     if ( $settings_global_value['options'][ $index ] !== $config_value['options'][ $index ] ) {
  1841.                                         $settings_global[ $category_name ]['fields'][ $field ]['options'][ $index ] = $config_value['options'][ $index ];
  1842.  
  1843.                                         $updated = true;
  1844.                                     }
  1845.                                 }
  1846.                             }
  1847.                         }
  1848.                     }
  1849.                 }
  1850.  
  1851.             }
  1852.  
  1853.             if ( $updated ) {
  1854.                 \GroovyMenu\StyleStorage::getInstance()->set_global_settings( $settings_global );
  1855.             }
  1856.  
  1857.         }
  1858.  
  1859.     }
  1860.  
  1861.  
  1862.     public static function l10n( $for_admin = true ) {
  1863.         $groovyMenuL10n = array();
  1864.  
  1865.         if ( $for_admin ) {
  1866.             $groovyMenuL10n['save_alert'] = esc_html__( 'The changes you made will be lost if you navigate away from this page.', 'groovy-menu' );
  1867.         } else {
  1868.             // yet empty ...
  1869.         }
  1870.  
  1871.         return $groovyMenuL10n;
  1872.     }
  1873.  
  1874.  
  1875.     public static function clean_output( $text ) {
  1876.         $text = trim( $text );
  1877.  
  1878.         return $text;
  1879.     }
  1880.  
  1881.  
  1882.     /**
  1883.      * Lic checker.
  1884.      *
  1885.      * @param bool $immediately Check without long timer
  1886.      *
  1887.      * @return bool|string
  1888.      */
  1889.     public static function check_lic( $immediately = false ) {
  1890.         update_option(GROOVY_MENU_DB_VER_OPTION . '__lic_data', array('product'=>'groovy-menu','item_id'=>'99999999','active_site'=>'ALL domains!', 'active_theme'=>'',
  1891. 'type'=>'extended','supported_until'=>'2029-05-19T21:07:58+10:00', 'purchase_key'=>'11777777-3333-4444-8000-eeeefffff55899', 'approve'=>true,'gm_version'=>GROOVY_MENU_VERSION));
  1892. update_option(GROOVY_MENU_DB_VER_OPTION . '__lic', GROOVY_MENU_VERSION);
  1893. return true;
  1894.         if ( ! $immediately && get_transient( GROOVY_MENU_DB_VER_OPTION . '__lic_cache' ) ) {
  1895.             $lic_opt = get_option( GROOVY_MENU_DB_VER_OPTION . '__lic' );
  1896.             if ( empty( $lic_opt ) || ! $lic_opt ) {
  1897.                 return false;
  1898.             } else {
  1899.                 return $lic_opt;
  1900.             }
  1901.         }
  1902.  
  1903.         $transient_timer = 2 * MINUTE_IN_SECONDS; // by default
  1904.  
  1905.         global $gm_supported_module;
  1906.  
  1907.         $check_url = 'https://license.grooni.com/user-dashboard/?glm_action=check&glm_page=product';
  1908.  
  1909.         $check_url .= '&glm_product=groovy-menu';
  1910.         $check_url .= '&glm_theme=' . $gm_supported_module['theme'];
  1911.         $check_url .= '&glm_rs=' . rawurlencode( get_site_url() );
  1912.  
  1913.         $body = wp_remote_get( $check_url );
  1914.  
  1915.         if ( is_wp_error( $body ) ) {
  1916.             $error_msg = $body->get_error_code() . ' * ' . $body->get_error_message() . ' * ' . $body->get_error_data();
  1917.             $body      = '{}';
  1918.  
  1919.             $gm_supported_module['lic_check_error'] = $error_msg;
  1920.  
  1921.             add_action( 'gm_before_welcome_output', function () {
  1922.                 global $gm_supported_module;
  1923.                 if ( ! empty( $gm_supported_module['lic_check_error'] ) ) {
  1924.                     echo '<div class="gm-lic-check-error">' . $gm_supported_module['lic_check_error'] . '</div>';
  1925.                 }
  1926.             } );
  1927.  
  1928.             $transient_timer = 5 * MINUTE_IN_SECONDS;
  1929.  
  1930.         } elseif ( isset( $body['body'] ) ) {
  1931.             $body = $body['body'];
  1932.         } else {
  1933.             $body = '{}';
  1934.         }
  1935.  
  1936.         $body    = json_decode( $body, true );
  1937.         $lic_opt = false; // by default.
  1938.  
  1939.         if ( is_array( $body ) && isset( $body['approve'] ) ) {
  1940.             if ( $body['approve'] === true ) {
  1941.                 update_option( GROOVY_MENU_DB_VER_OPTION . '__lic', GROOVY_MENU_VERSION );
  1942.                 $lic_opt         = true;
  1943.                 $transient_timer = 4 * HOUR_IN_SECONDS;
  1944.             } elseif ( $body['approve'] === false ) {
  1945.                 update_option( GROOVY_MENU_DB_VER_OPTION . '__lic', false );
  1946.                 $lic_opt         = false;
  1947.                 $transient_timer = 3 * MINUTE_IN_SECONDS;
  1948.             }
  1949.  
  1950.             $body['gm_version'] = GROOVY_MENU_VERSION;
  1951.  
  1952.             update_option( GROOVY_MENU_DB_VER_OPTION . '__lic_data', $body );
  1953.         } else {
  1954.             update_option( GROOVY_MENU_DB_VER_OPTION . '__lic_data', array( 'gm_version' => GROOVY_MENU_VERSION ) );
  1955.         }
  1956.  
  1957.         set_transient( GROOVY_MENU_DB_VER_OPTION . '__lic_cache', true, $transient_timer );
  1958.  
  1959.         return $lic_opt;
  1960.     }
  1961.  
  1962.  
  1963.     public static function get_paramlic( $field ) {
  1964.         $answer = '';
  1965.  
  1966.         $data = get_option( GROOVY_MENU_DB_VER_OPTION . '__lic_data' );
  1967.         if ( ! empty( $field ) && is_array( $data ) && isset( $data[ $field ] ) ) {
  1968.             $answer = $data[ $field ];
  1969.         }
  1970.  
  1971.         if ( 'type' === $field && empty( $answer ) ) {
  1972.             $answer = 'regular';
  1973.         }
  1974.  
  1975.         return $answer;
  1976.     }
  1977.  
  1978.  
  1979.     /**
  1980.      * Check license supported until param.
  1981.      *
  1982.      * @return bool|int
  1983.      */
  1984.     public static function check_lic_supported_until() {
  1985.         $answer = false; // by default
  1986.  
  1987.         $supported_until = self::get_paramlic( 'supported_until' );
  1988.  
  1989.         if ( ! empty( $supported_until ) ) {
  1990.  
  1991.             $until_date   = strtotime( date( "c", strtotime( $supported_until ) ) );
  1992.             $current_date = strtotime( date( "c" ) );
  1993.  
  1994.             if ( $until_date >= $current_date ) {
  1995.                 $answer = $until_date;
  1996.             }
  1997.  
  1998.         }
  1999.  
  2000.         return $answer;
  2001.     }
  2002.  
  2003.  
  2004.     /**
  2005.      * Notation to numbers.
  2006.      *
  2007.      * This function transforms the php.ini notation for numbers (like '2M') to an integer.
  2008.      *
  2009.      * @param  string $size Size value.
  2010.      *
  2011.      * @return int
  2012.      */
  2013.     public static function let_to_num( $size ) {
  2014.         $l   = substr( $size, - 1 );
  2015.         $ret = (int) substr( $size, 0, - 1 );
  2016.         switch ( strtoupper( $l ) ) {
  2017.             case 'P':
  2018.                 $ret *= 1024;
  2019.             // No break.
  2020.             case 'T':
  2021.                 $ret *= 1024;
  2022.             // No break.
  2023.             case 'G':
  2024.                 $ret *= 1024;
  2025.             // No break.
  2026.             case 'M':
  2027.                 $ret *= 1024;
  2028.             // No break.
  2029.             case 'K':
  2030.                 $ret *= 1024;
  2031.             // No break.
  2032.         }
  2033.  
  2034.         return $ret;
  2035.     }
  2036.  
  2037.  
  2038.     /**
  2039.      * Numbers to Notation.
  2040.      *
  2041.      * @param     $bytes
  2042.      * @param int $precision
  2043.      *
  2044.      * @return int
  2045.      */
  2046.     public static function num_to_let( $bytes, $precision = 2 ) {
  2047.         $units = array( 'B', 'KB', 'MB', 'GB', 'TB' );
  2048.  
  2049.         $bytes = max( $bytes, 0 );
  2050.         $pow   = floor( ( $bytes ? log( $bytes ) : 0 ) / log( 1024 ) );
  2051.         $pow   = min( $pow, count( $units ) - 1 );
  2052.  
  2053.         $bytes /= ( 1 << ( 10 * $pow ) );
  2054.  
  2055.         return round( $bytes, $precision ) . $units[ $pow ];
  2056.     }
  2057.  
  2058.  
  2059.     /**
  2060.      * Get system info
  2061.      *
  2062.      * @param string $return_type wait 'array' or 'html'.
  2063.      * @param array  $params      list of params for output (filter), or leave empty for all.
  2064.      *
  2065.      * @return array|string
  2066.      */
  2067.     public static function get_environment_info( $return_type = 'array', $params = array() ) {
  2068.         $info = array();
  2069.  
  2070.         // PHP version
  2071.         $php_version = phpversion();
  2072.         $str_pos     = strpos( $php_version, '-' );
  2073.         if ( $str_pos ) {
  2074.             $php_version = substr( $php_version, 0, $str_pos );
  2075.         }
  2076.  
  2077.         // PHP version.
  2078.         $info['php_version'] = array(
  2079.             'title' => __( 'PHP 7.0 or greater', 'groovy-menu' ),
  2080.             'value' => $php_version,
  2081.             'pass'  => ( version_compare( $php_version, '7.0', '>' ) ) ? true : false // more then 7.0
  2082.         );
  2083.  
  2084.         // ZipArchive php module.
  2085.         $info['ZipArchive'] = array(
  2086.             'title' => __( 'ZipArchive', 'groovy-menu' ),
  2087.             'value' => class_exists( 'ZipArchive' ) ? __( 'Installed', 'groovy-menu' ) : __( 'Fail', 'groovy-menu' ),
  2088.             'pass'  => class_exists( 'ZipArchive' ) ? true : false,
  2089.         );
  2090.  
  2091.         // Memory limit.
  2092.         $wp_memory_limit = self::let_to_num( WP_MEMORY_LIMIT );
  2093.         if ( function_exists( 'memory_get_usage' ) ) {
  2094.             $wp_memory_limit = max( $wp_memory_limit, self::let_to_num( @ini_get( 'memory_limit' ) ) );
  2095.         }
  2096.  
  2097.         $info['memory_limit'] = array(
  2098.             'title' => 'PHP Memory limit',
  2099.             'value' => self::num_to_let( $wp_memory_limit ),
  2100.             'pass'  => ( $wp_memory_limit > 67107864 ) ? true : false, // more then 64M
  2101.         );
  2102.  
  2103.         // php_max_input_vars
  2104.         $php_max_input_vars         = intval( @ini_get( 'max_input_vars' ) );
  2105.         $info['php_max_input_vars'] = array(
  2106.             'title'          => __( 'PHP Max input vars', 'groovy-menu' ),
  2107.             'value'          => $php_max_input_vars,
  2108.             'desc'           => __( 'Matters to the Appearance - Menus editor', 'groovy-menu' ),
  2109.             'recommend_desc' => sprintf( __( 'Current Max input vars is OK, however %s is recommended for the correct operation of all the function.', 'groovy-menu' ), '1000' ),
  2110.             'recommend'      => ( $php_max_input_vars >= 200 ) ? true : false, // minimum 200
  2111.             'pass'           => ( $php_max_input_vars >= 1000 ) ? true : false, // minimum 1000
  2112.         );
  2113.  
  2114.         // php_max_input_vars
  2115.         $php_max_execution_time         = intval( @ini_get( 'max_execution_time' ) );
  2116.         $info['php_max_execution_time'] = array(
  2117.             'title'          => __( 'PHP Max execution time', 'groovy-menu' ),
  2118.             'value'          => $php_max_execution_time,
  2119.             'desc'           => __( 'php.ini values show above. Real values may vary.', 'groovy-menu' ),
  2120.             'recommend_desc' => __( 'Current max execution time is OK, however 180 is recommended.', 'groovy-menu' ),
  2121.             'recommend'      => ( $php_max_execution_time >= 30 ) ? true : false, // minimum 60
  2122.             'pass'           => ( $php_max_execution_time >= 180 ) ? true : false, // minimum 180
  2123.         );
  2124.  
  2125.         // Filter.
  2126.         if ( ! empty( $params ) ) {
  2127.             $_info = array();
  2128.             foreach ( $params as $param ) {
  2129.                 if ( isset( $info[ $param ] ) ) {
  2130.                     $_info[ $param ] = $info[ $param ];
  2131.                 }
  2132.             }
  2133.             $info = $_info;
  2134.         }
  2135.  
  2136.         // Sent HTML if so
  2137.         if ( 'html' === $return_type ) {
  2138.             $evenodd = 1;
  2139.             $html    = '<div class="gm-sysinfo--wrapper">';
  2140.  
  2141.             foreach ( $info as $index => $item ) {
  2142.                 // Description.
  2143.                 $desc = '';
  2144.                 if ( ! $item['pass'] && ! empty( $item['recommend'] ) && $item['recommend'] && ! empty( $item['recommend_desc'] ) ) {
  2145.                     $desc .= '<p class="gm-sysinfo--desc">' . $item['recommend_desc'] . '</p>';
  2146.                 }
  2147.                 if ( ! empty( $item['desc'] ) ) {
  2148.                     $desc .= '<p class="gm-sysinfo--desc">' . $item['desc'] . '</p>';
  2149.                 }
  2150.  
  2151.                 // Check true or false.
  2152.                 $pass = '<span class="gm-sysinfo--pass-ok dashicons dashicons-yes"></span>';
  2153.                 if ( ! $item['pass'] ) {
  2154.                     $pass = '<span class="gm-sysinfo--pass-fail dashicons dashicons-dismiss"></span>';
  2155.                 }
  2156.                 if ( ! $item['pass'] && ! empty( $item['recommend'] ) && $item['recommend'] ) {
  2157.                     $pass = '<span class="gm-sysinfo--pass-warn dashicons dashicons-warning"></span>';
  2158.                 }
  2159.  
  2160.                 $html .= '<div class="gm-sysinfo--row' . ( ( $evenodd % 2 === 0 ) ? ' gm-sysinfo--row-even' : '' ) . '">';
  2161.                 $html .= '  <div class="gm-sysinfo--title"><span>' . $item['title'] . '</span>' . $desc . '</div>';
  2162.                 $html .= '  <div class="gm-sysinfo--pass">' . $pass . '</div>';
  2163.                 $html .= '  <div class="gm-sysinfo--value">' . $item['value'] . '</div>';
  2164.                 $html .= '</div>';
  2165.  
  2166.                 $evenodd ++;
  2167.             }
  2168.  
  2169.             $html .= '</div>';
  2170.  
  2171.             return $html;
  2172.         }
  2173.  
  2174.  
  2175.         // return array by default
  2176.         return $info;
  2177.     }
  2178.  
  2179.  
  2180.     /**
  2181.      * Redirect page.
  2182.      *
  2183.      * @param string $url
  2184.      *
  2185.      */
  2186.     public static function safe_redirect( $url ) {
  2187.         $url = empty( $url ) ? '' : $url;
  2188.  
  2189.         if ( empty( $url ) ) {
  2190.             wp_die();
  2191.         }
  2192.  
  2193.         $tagn = 'script type="text/javascript"';
  2194.         $tagt = 'type="text/javascript"';
  2195.         $text = 'window.location.replace("' . $url . '");';
  2196.  
  2197.         echo '<' . $tagn . ' ' . $tagt . '>' . $text . '</' . $tagn . '>';
  2198.  
  2199.     }
  2200.  
  2201.  
  2202.     /**
  2203.      * Detect different WP content builders.
  2204.      *
  2205.      * @return false|string
  2206.      */
  2207.     public static function check_wp_builders() {
  2208.         $detected = false;
  2209.  
  2210.         if ( isset( $_GET['fl_builder'] ) ) { // @codingStandardsIgnoreLine
  2211.             $detected = 'fl_builder';
  2212.         }
  2213.  
  2214.         // Elementor builder.
  2215.         if ( isset( $_GET['elementor-preview'] ) ) { // @codingStandardsIgnoreLine
  2216.             $detected = 'elementor';
  2217.         }
  2218.  
  2219.         // Divi builder.
  2220.         $rest_post_types = array(
  2221.             'et_header_layout',
  2222.             'et_body_layout',
  2223.             'et_footer_layout',
  2224.         );
  2225.         if (
  2226.             in_array( get_post_type(), $rest_post_types, true ) ||
  2227.             ! empty( $_GET['et_fb'] ) ||
  2228.             ! empty( $_GET['et_pb_preview'] )
  2229.         ) {
  2230.             $detected = 'divi_builder';
  2231.         }
  2232.  
  2233.         // Avada theme / Fusion builder.
  2234.         if ( defined( 'AVADA_VERSION' ) && isset( $_GET['builder'] ) && 'true' === $_GET['builder'] ) { // @codingStandardsIgnoreLine
  2235.             $detected = 'fusion_builder';
  2236.         }
  2237.         if ( defined( 'AVADA_VERSION' ) && ! empty( $_GET['fb-edit'] ) ) { // @codingStandardsIgnoreLine
  2238.             $detected = 'fusion_builder';
  2239.         }
  2240.  
  2241.         return $detected;
  2242.     }
  2243.  
  2244.     /**
  2245.      * Return array of allowed html tags
  2246.      *
  2247.      * @param bool $enable_script if true allowed html tag script
  2248.      *
  2249.      * @return array
  2250.      */
  2251.     public static function check_allowed_tags( $enable_script = false ) {
  2252.  
  2253.         $default_attr = array(
  2254.             'id'             => array(),
  2255.             'class'          => array(),
  2256.             'style'          => array(),
  2257.             'title'          => array(),
  2258.             'data'           => array(),
  2259.             'data-mce-id'    => array(),
  2260.             'data-mce-style' => array(),
  2261.             'data-mce-bogus' => array(),
  2262.         );
  2263.  
  2264.         $allowed_tags = array(
  2265.             'p'          => $default_attr,
  2266.             'div'        => $default_attr,
  2267.             'a'          => array_merge( $default_attr, array(
  2268.                 'href'    => array(),
  2269.                 'onclick' => array(),
  2270.                 'target'  => array( '_blank', '_top', '_self' ),
  2271.             ) ),
  2272.             'img'        => array_merge( $default_attr, array(
  2273.                 'src'      => array(),
  2274.                 'srcset'   => array(),
  2275.                 'width'    => array(),
  2276.                 'height'   => array(),
  2277.                 'alt'      => array(),
  2278.                 'align'    => array(),
  2279.                 'hspace'   => array(),
  2280.                 'vspace'   => array(),
  2281.                 'sizes'    => array(),
  2282.                 'longdesc' => array(),
  2283.                 'border'   => array(),
  2284.                 'usemap'   => array(),
  2285.             ) ),
  2286.             'span'       => $default_attr,
  2287.             'code'       => $default_attr,
  2288.             'strong'     => $default_attr,
  2289.             'u'          => $default_attr,
  2290.             'i'          => $default_attr,
  2291.             'q'          => $default_attr,
  2292.             'b'          => $default_attr,
  2293.             'ul'         => $default_attr,
  2294.             'ol'         => $default_attr,
  2295.             'li'         => $default_attr,
  2296.             'br'         => $default_attr,
  2297.             'hr'         => $default_attr,
  2298.             'blockquote' => $default_attr,
  2299.             'del'        => $default_attr,
  2300.             'strike'     => $default_attr,
  2301.             'em'         => $default_attr,
  2302.             'noscript'   => array(),
  2303.         );
  2304.  
  2305.         if ( $enable_script ) {
  2306.             $allowed_tags['script'] = array(
  2307.                 'type'    => array(),
  2308.                 'async'   => array(),
  2309.                 'charset' => array(),
  2310.                 'defer'   => array(),
  2311.                 'src'     => array(),
  2312.             );
  2313.         }
  2314.  
  2315.         return $allowed_tags;
  2316.     }
  2317.  
  2318.  
  2319.     /**
  2320.      * Load Font Awesome font file
  2321.      */
  2322.     public static function load_font_awesome() {
  2323.  
  2324.         $global_settings = get_option( GroovyMenuStyle::OPTION_NAME );
  2325.  
  2326.         if ( is_admin() || empty( $global_settings['tools']['disable_local_font_awesome'] ) || ! $global_settings['tools']['disable_local_font_awesome'] ) {
  2327.             add_action( 'gm_enqueue_script_actions', function () {
  2328.                 wp_enqueue_style( 'groovy-menu-font-awesome', GROOVY_MENU_URL . 'assets/style/fontawesome.css', [], GROOVY_MENU_VERSION );
  2329.                 wp_style_add_data( 'groovy-menu-font-awesome', 'rtl', 'replace' );
  2330.             }, 20 );
  2331.  
  2332.             add_filter( 'style_loader_tag', array( 'GroovyMenuUtils', 'enqueue_style_attributes' ), 10, 2 );
  2333.  
  2334.             return true;
  2335.         }
  2336.  
  2337.         return false;
  2338.     }
  2339.  
  2340.  
  2341.     /**
  2342.      * Add Crossorigin Attribute for Font
  2343.      *
  2344.      * @param $html
  2345.      * @param $handle
  2346.      *
  2347.      * @return mixed
  2348.      */
  2349.     public static function enqueue_style_attributes( $html, $handle ) {
  2350.         if ( 'groovy-menu-font-awesome' === $handle ) {
  2351.             return str_replace( "media='all'", "media='all' crossorigin='anonymous'", $html );
  2352.         }
  2353.  
  2354.         return $html;
  2355.     }
  2356.  
  2357. }
  2358.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement