Advertisement
verygoodplugins

Untitled

Jan 25th, 2022
831
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 15.93 KB | None | 0 0
  1. <?php
  2. /*
  3. Plugin Name: If Menu - Visibility control for menu items
  4. Plugin URI: https://layered.market/plugins/if-menu
  5. Description: Display tailored menu items to each visitor with visibility rules
  6. Version: 0.16.2
  7. Text Domain: if-menu
  8. Author: Layered
  9. Author URI: https://layered.market
  10. License: GPL-3.0-or-later
  11. License URI: https://www.gnu.org/licenses/gpl-3.0.html
  12. */
  13.  
  14. use Layered\SafeEval\SafeEval;
  15.  
  16. require plugin_dir_path(__FILE__) . 'vendor/autoload.php';
  17.  
  18. class If_Menu {
  19.  
  20.     public static function init() {
  21.         global $pagenow, $wp_version;
  22.  
  23.         add_action('rest_api_init', 'If_Menu::restApi');
  24.  
  25.         if (is_admin()) {
  26.             add_action('admin_enqueue_scripts', 'If_Menu::admin_init');
  27.             add_action('wp_update_nav_menu_item', 'If_Menu::wp_update_nav_menu_item', 10, 2);
  28.  
  29.             // Add missing `wp_nav_menu_item_custom_fields` filter in Walker_Nav_Menu_Edit
  30.             if (version_compare($wp_version, '5.4', '<')) {
  31.                 add_filter('wp_edit_nav_menu_walker', 'If_Menu::customWalker', 500, 2);
  32.             }
  33.  
  34.             add_action('wp_nav_menu_item_custom_fields', 'If_Menu::menu_item_fields');
  35.             add_action('wp_nav_menu_item_custom_title', 'If_Menu::menu_item_title');
  36.             add_action('admin_footer', 'If_Menu::adminFooter');
  37.  
  38.             if (get_option('if-menu-admin', 1) && $pagenow !== 'nav-menus.php') {
  39.                 add_filter('wp_get_nav_menu_items', 'If_Menu::wp_get_nav_menu_items');
  40.             }
  41.         } else {
  42.             add_filter('wp_get_nav_menu_items', 'If_Menu::wp_get_nav_menu_items');
  43.             add_action('wp_enqueue_scripts', 'If_Menu::addAssets');
  44.         }
  45.     }
  46.  
  47.     public static function get_conditions( $for_testing = false ) {
  48.         $conditions = apply_filters( 'if_menu_conditions', array() );
  49.  
  50.         if ($for_testing) {
  51.             $c2 = array();
  52.             foreach ($conditions as $condition) {
  53.                 if (isset($condition['id'])) {
  54.                     $c2[$condition['id']] = $condition;
  55.                 }
  56.                 if (isset($condition['name'])) {
  57.                     $c2[$condition['name']] = $condition;
  58.                 }
  59.                 if (isset($condition['alias'])) {
  60.                     $c2[$condition['alias']] = $condition;
  61.                 }
  62.             }
  63.             $conditions = $c2;
  64.         }
  65.  
  66.         return $conditions;
  67.     }
  68.  
  69.     public static function wp_get_nav_menu_items($items) {
  70.         $conditions = If_Menu::get_conditions($for_testing = true);
  71.         $hidden_items = array();
  72.  
  73.         $canPeek = is_user_logged_in() && get_option('if-menu-peak') && current_user_can('edit_theme_options');
  74.  
  75.         foreach ($items as $key => $item) {
  76.  
  77.             if (in_array($item->menu_item_parent, $hidden_items)) {
  78.                 if ($canPeek) {
  79.                     $item->classes[] = 'if-menu-peek';
  80.                 } else {
  81.                     unset($items[$key]);
  82.                 }
  83.                 $hidden_items[] = $item->ID;
  84.             } else {
  85.                 $enabled = get_post_meta($item->ID, 'if_menu_enable');
  86.  
  87.                 if ($enabled && $enabled[0] !== '0') {
  88.                     $if_condition_types = get_post_meta($item->ID, 'if_menu_condition_type');
  89.                     $if_conditions = get_post_meta($item->ID, 'if_menu_condition');
  90.                     $ifMenuOptions = get_post_meta($item->ID, 'if_menu_options');
  91.  
  92.                     $eval = array();
  93.  
  94.                     foreach ($enabled as $index => $operator) {
  95.                         $singleCondition = '';
  96.  
  97.                         if ($index) {
  98.                             $singleCondition .= $operator . ' ';
  99.                         }
  100.  
  101.                         $bit1 = $if_condition_types[$index] === 'show' ? 1 : 0;
  102.                         $bit2 = $if_condition_types[$index] === 'show' ? 0 : 1;
  103.  
  104.                         $params = array($item);
  105.  
  106.                         if ($ifMenuOptions && isset($ifMenuOptions[$index])) {
  107.                             $params[] = $ifMenuOptions[$index];
  108.                         }
  109.  
  110.                         $singleCondition .= call_user_func_array($conditions[$if_conditions[$index]]['condition'], $params) ? $bit1 : $bit2;
  111.  
  112.                         $eval[] = $singleCondition;
  113.                     }
  114.  
  115.                     $safeEval = new SafeEval;
  116.  
  117.                     if ((count($eval) === 1 && $eval[0] == 0) || (count($eval) > 1 && !$safeEval->evaluate(implode(' ', $eval)))) {
  118.                         if ($canPeek) {
  119.                             $item->classes[] = 'if-menu-peek';
  120.                         } else {
  121.                             unset($items[$key]);
  122.                         }
  123.  
  124.                         $hidden_items[] = $item->ID;
  125.                     }
  126.                 }
  127.             }
  128.         }
  129.  
  130.         return $items;
  131.     }
  132.  
  133.     public static function admin_init() {
  134.         global $pagenow;
  135.  
  136.         if ($pagenow == 'nav-menus.php') {
  137.             wp_enqueue_script('select2', plugins_url('assets/select2.min.js', __FILE__), array('jquery'), '4.0.5');
  138.             wp_enqueue_script('if-menu', plugins_url('assets/if-menu.js', __FILE__), array('select2', 'jquery-ui-dialog'), '0.16');
  139.  
  140.             wp_enqueue_style('select2', plugins_url('assets/select2.min.css', __FILE__), array(), '4.0.5');
  141.             wp_enqueue_style('if-menu', plugins_url('assets/if-menu.css', __FILE__), array('wp-jquery-ui-dialog'), '0.15');
  142.  
  143.             wp_localize_script('if-menu', 'IfMenu', array(
  144.                 'plan'                  =>  self::getPlan(),
  145.                 'conflictErrorMessage'  =>  sprintf(
  146.                     wp_kses(
  147.                         __('<strong>If Menu</strong> detected a conflict with another plugin or theme (%s) and may not work as expected. <a href="%s" target="_blank">Read more about the issue here</a>', 'if-menu'),
  148.                         array('a' => array('href' => [], 'target' => []), 'strong' => [])
  149.                     ),
  150.                     apply_filters('wp_edit_nav_menu_walker', 'Walker_Nav_Menu_Edit', 0),
  151.                     esc_url('https://wordpress.org/plugins/if-menu/#if%20menu%20is%20broken%2C%20no%20visibility%20rules%20are%20available')
  152.                 ),
  153.                 'duplicateErrorMessage'  =>  sprintf(
  154.                     wp_kses(
  155.                         __('<strong>If Menu</strong> detected that another plugin or theme (%s) extends menu items incorrectly. This may cause duplicate visibility rules to show up, but functionality should be fine.', 'if-menu'),
  156.                         ['strong' => []]
  157.                     ),
  158.                     apply_filters('wp_edit_nav_menu_walker', 'Walker_Nav_Menu_Edit', 0)
  159.                 )
  160.             ));
  161.         }
  162.     }
  163.  
  164.     public static function adminFooter() {
  165.         ?>
  166.         <div class="if-menu-dialog-premium hidden" title="<?php _e('That\'s a Premium feature', 'if-menu') ?>">
  167.             <p><?php _e('Get <strong>If Menu Premium</strong> plan to enable integrations with third-party plugins, user location detection and priority support', 'if-menu') ?></p><br>
  168.             <p>
  169.                 <a href="<?php echo admin_url('themes.php?page=if-menu') ?>" class="button button-primary pull-right if-menu-dialog-btn" data-action="get-premium"><?php _e('Get If Menu Premium', 'if-menu') ?></a>
  170.                 <button class="button close if-menu-dialog-btn" data-action="close"><?php _e('Use Basic plan', 'if-menu') ?></button>
  171.             </p>
  172.         </div>
  173.         <?php
  174.     }
  175.  
  176.     public static function addAssets() {
  177.         wp_enqueue_style('if-menu-site-css', plugins_url('assets/if-menu-site.css', __FILE__));
  178.     }
  179.  
  180.     public static function menu_item_fields($item_id) {
  181.         $conditions = If_Menu::get_conditions();
  182.         $if_menu_enable = get_post_meta( $item_id, 'if_menu_enable' );
  183.         $if_menu_condition_type = get_post_meta( $item_id, 'if_menu_condition_type' );
  184.         $if_menu_condition = get_post_meta( $item_id, 'if_menu_condition' );
  185.         $ifMenuOptions = get_post_meta($item_id, 'if_menu_options');
  186.  
  187.         if (!count($if_menu_enable)) {
  188.             $if_menu_enable[] = 0;
  189.             $if_menu_condition_type[] = '';
  190.             $if_menu_condition[] = '';
  191.         }
  192.  
  193.         $groupedConditions = array();
  194.         foreach ($conditions as $condition) {
  195.             $groupedConditions[isset($condition['group']) ? $condition['group'] : 'Custom'][] = $condition;
  196.         }
  197.         ?>
  198.  
  199.         <p class="if-menu-enable description description-wide">
  200.             <a href="<?php echo admin_url('themes.php?page=if-menu') ?>" class="if-menu-help" data-tooltip="<?php esc_attr_e('Visibility rule examples', 'if-menu') ?>" title="<?php esc_attr_e('Visibility rule examples', 'if-menu') ?>"><span class="dashicons dashicons-editor-help"></span></a>
  201.             <label>
  202.                 <input <?php if (isset($if_menu_enable[0])) checked( $if_menu_enable[0], 1 ) ?> type="checkbox" value="1" class="menu-item-if-menu-enable" name="menu-item-if-menu-enable[<?php echo esc_attr( $item_id ); ?>][]" />
  203.                 <?php esc_html_e('Enable visibility rules', 'if-menu') ?>
  204.             </label>
  205.         </p>
  206.  
  207.         <div class="if-menu-conditions" style="display: <?php echo $if_menu_enable[0] ? 'block' : 'none' ?>">
  208.             <?php for ($index = 0; $index < count($if_menu_enable); $index++) : ?>
  209.  
  210.                 <p class="if-menu-condition description description-wide" data-menu-item-id="<?php echo $item_id ?>">
  211.                     <?php
  212.                     $selectedCondition = null;
  213.                     ?>
  214.                     <span class="if-menu-condition-rule">
  215.                         <select class="menu-item-if-menu-condition-type" id="edit-menu-item-if-menu-condition-type-<?php echo esc_attr( $item_id ); ?>" name="menu-item-if-menu-condition-type[<?php echo esc_html( $item_id ); ?>][]" data-val="<?php echo esc_html($if_menu_condition_type[$index]) ?>">
  216.                             <option <?php selected( 'show', $if_menu_condition_type[$index] ) ?> value="show"><?php esc_html_e( 'Show', 'if-menu' ) ?></option>
  217.                             <option <?php selected( 'hide', $if_menu_condition_type[$index] ) ?> value="hide"><?php esc_html_e( 'Hide', 'if-menu' ) ?></option>
  218.                         </select>
  219.                         <?php esc_html_e( 'if', 'if-menu' ); ?>
  220.                         <select class="menu-item-if-menu-condition" id="edit-menu-item-if-menu-condition-<?php echo esc_attr( $item_id ); ?>" name="menu-item-if-menu-condition[<?php echo esc_attr( $item_id ); ?>][]">
  221.                             <?php foreach ($groupedConditions as $group => $conditions) : ?>
  222.                                 <optgroup label="<?php echo esc_attr($group) ?>">
  223.                                     <?php foreach($conditions as $condition) : ?>
  224.                                         <?php
  225.                                         if ($condition['id'] === $if_menu_condition[$index]) {
  226.                                             $selectedCondition = $condition;
  227.                                         }
  228.                                         ?>
  229.                                         <option value="<?php echo $condition['id'] ?>" <?php selected($condition['id'], $if_menu_condition[$index]) ?> <?php selected($condition['name'], $if_menu_condition[$index]) ?> data-options='<?php if (isset($condition['options'])) echo htmlspecialchars( json_encode($condition['options']), ENT_QUOTES, 'UTF-8 ); ?>'><?php echo esc_html($condition['name']) . (isset($condition['options']) ? ' &raquo;' : '') ?></option>
  230.                                     <?php endforeach ?>
  231.                                 </optgroup>
  232.                             <?php endforeach ?>
  233.                         </select>
  234.                     </span>
  235.                     <select class="menu-item-if-menu-enable-next" name="menu-item-if-menu-enable[<?php echo esc_attr( $item_id ); ?>][]">
  236.                         <option value="false">+</option>
  237.                         <option value="and" <?php if (isset($if_menu_enable[$index + 1])) selected( 'and', $if_menu_enable[$index + 1] ) ?>><?php esc_html_e( 'AND', 'if-menu' ) ?></option>
  238.                         <option value="or" <?php if (isset($if_menu_enable[$index + 1])) selected( 'or', $if_menu_enable[$index + 1] ) ?>><?php esc_html_e( 'OR', 'if-menu' ) ?></option>-->
  239.                     </select>
  240.                     <?php if (isset($selectedCondition['options'])) : ?>
  241.                         <select class="menu-item-if-menu-options" name="menu-item-if-menu-options[<?php echo esc_attr($item_id) ?>][<?php echo esc_attr($index) ?>][]" style="width: 305px" multiple>
  242.                             <?php foreach ($selectedCondition['options'] as $value => $label) : ?>
  243.                                 <option value="<?php echo esc_attr($value) ?>" <?php if (is_array($ifMenuOptions[$index]) && in_array($value, $ifMenuOptions[$index])) echo 'selected' ?>><?php echo $label ?></option>
  244.                             <?php endforeach ?>
  245.                         </select>
  246.                     <?php endif ?>
  247.                 </p>
  248.  
  249.             <?php endfor ?>
  250.         </div>
  251.  
  252.         <?php
  253.     }
  254.  
  255.   public static function menu_item_title( $item_id ) {
  256.     $if_menu_enabled = get_post_meta( $item_id, 'if_menu_enable' );
  257.  
  258.     if ( count( $if_menu_enabled ) && $if_menu_enabled[0] !== '0' ) {
  259.       $conditionTypes = get_post_meta( $item_id, 'if_menu_condition_type' );
  260.       $conditions = get_post_meta( $item_id, 'if_menu_condition' );
  261.       $rules = If_Menu::get_conditions($for_testing = true);
  262.  
  263.       if ( $conditionTypes[0] === 'show' ) {
  264.         $conditionTypes[0] = '';
  265.       }
  266.  
  267.       echo '<span class="is-submenu">';
  268.       printf( __( '%s if %s', 'if-menu' ), $conditionTypes[0], $rules[$conditions[0]]['name'] );
  269.       if ( count( $if_menu_enabled ) > 1 ) {
  270.         printf( ' ' . _n( 'and %d more rule', 'and %d more rules', count( $if_menu_enabled ) - 1, 'if-menu' ), count( $if_menu_enabled ) - 1 );
  271.       }
  272.       echo '</span>';
  273.     }
  274.   }
  275.  
  276.   public static function customWalker($walker, $menuId = null) {
  277.     global $wp_version;
  278.  
  279.     if (version_compare( $wp_version, '4.7.0', '>=')) {
  280.       require_once(plugin_dir_path(__FILE__) . 'src/if-menu-nav-menu-4.7.php');
  281.     } elseif ( version_compare( $wp_version, '4.5.0', '>=' ) ){
  282.       require_once(plugin_dir_path(__FILE__) . 'src/if-menu-nav-menu-4.5.php');
  283.     } else {
  284.       require_once(plugin_dir_path(__FILE__) . 'src/if-menu-nav-menu.php');
  285.     }
  286.  
  287.     return 'If_Menu_Walker_Nav_Menu_Edit';
  288.   }
  289.  
  290.     public static function wp_update_nav_menu_item( $menu_id, $menu_item_db_id ) {
  291.         if (isset($_POST['menu-item-if-menu-enable'])) {
  292.  
  293.             delete_post_meta($menu_item_db_id, 'if_menu_enable');
  294.             delete_post_meta($menu_item_db_id, 'if_menu_condition_type');
  295.             delete_post_meta($menu_item_db_id, 'if_menu_condition');
  296.             delete_post_meta($menu_item_db_id, 'if_menu_options');
  297.  
  298.             foreach ($_POST['menu-item-if-menu-enable'][$menu_item_db_id] as $index => $value) {
  299.                 if (in_array( $value, array('1', 'and', 'or'))) {
  300.                     add_post_meta($menu_item_db_id, 'if_menu_enable', $value);
  301.                     add_post_meta($menu_item_db_id, 'if_menu_condition_type', $_POST['menu-item-if-menu-condition-type'][$menu_item_db_id][$index]);
  302.                     add_post_meta($menu_item_db_id, 'if_menu_condition', $_POST['menu-item-if-menu-condition'][$menu_item_db_id][$index]);
  303.                     if (isset($_POST['menu-item-if-menu-options']) && isset($_POST['menu-item-if-menu-options'][$menu_item_db_id]) && isset($_POST['menu-item-if-menu-options'][$menu_item_db_id][$index])) {
  304.                         add_post_meta($menu_item_db_id, 'if_menu_options', array_unique($_POST['menu-item-if-menu-options'][$menu_item_db_id][$index]));
  305.                     } else {
  306.                         add_post_meta($menu_item_db_id, 'if_menu_options', 0);
  307.                     }
  308.                 } else {
  309.                     break;
  310.                 }
  311.             }
  312.         }
  313.     }
  314.  
  315.     public static function apiNonce($action) {
  316.         $nonce = uniqid();
  317.         set_transient('if-menu-nonce-' . $action, $nonce, 600);
  318.         return $nonce;
  319.     }
  320.  
  321.     public static function getPlan() {
  322.         global $layeredMarketMoreVisibilityRules;
  323.  
  324.         if (class_exists('Layered\LayeredMarketForWp\Api') && isset($layeredMarketMoreVisibilityRules) && $layeredMarketMoreVisibilityRules instanceof Layered\LayeredMarketForWp\Api && $layeredMarketMoreVisibilityRules->isLicenseActive()) {
  325.             $license = $layeredMarketMoreVisibilityRules->getLicense();
  326.             $license['until'] = $license['end'];
  327.             $license['plan'] = 'premium';
  328.  
  329.             return $license;
  330.         }
  331.  
  332.         if (isset($_REQUEST['if-menu-recheck-plan']) || false === ($plan = get_transient('if-menu-plan'))) {
  333.             $plan = false;
  334.             $request = wp_remote_get('https://layered.market/get-plan?site=' . urlencode(site_url()) . '&for=if-menu&_nonce=' . self::apiNonce('plan-check') . '&licenseKey=' . get_option('if-menu-license-key'), array('timeout' => 60));
  335.  
  336.             if (!is_wp_error($request)) {
  337.                 $data = json_decode(wp_remote_retrieve_body($request), true);
  338.                 if (isset($data['plans'])) {
  339.                     $plan = $data['plans']['if-menu'];
  340.                     set_transient('if-menu-plan', $plan, 500);
  341.                 }
  342.             }
  343.         }
  344.  
  345.         return $plan;
  346.     }
  347.  
  348.     public static function restApi() {
  349.         register_rest_route('if-menu/v1', '/did-you-made-this-request', array(
  350.             'methods'   =>  'GET',
  351.             'callback'  =>  function() {
  352.                 $action = isset($_REQUEST['action']) ? sanitize_key($_REQUEST['action']) : false;
  353.                 $nonce = isset($_REQUEST['nonce']) ? sanitize_key($_REQUEST['nonce']) : false;
  354.                 return array('valid' => $action && $nonce && $nonce === get_transient('if-menu-nonce-' . $action));
  355.             },
  356.             'permission_callback' => '__return_true',
  357.         ));
  358.     }
  359.  
  360. }
  361.  
  362.  
  363.  
  364. /* ------------------------------------------------
  365.     Include default visibility rules for menu items
  366. ------------------------------------------------ */
  367.  
  368. include 'src/user-info.php';
  369. include 'src/conditions-basic.php';
  370. include 'src/conditions-multiple-options.php';
  371.  
  372.  
  373.  
  374. /* ------------------------------------------------
  375.     Run the plugin
  376. ------------------------------------------------ */
  377.  
  378. if (version_compare(PHP_VERSION, '5.4', '<')) {
  379.     add_action('admin_notices', function() {
  380.         ?>
  381.         <div class="notice notice-warning is-dismissible">
  382.             <p><?php printf(__('<strong>If Menu</strong> plugin requires PHP version to be at least 5.4, current one is %s', 'if-menu'), PHP_VERSION) ?></p>
  383.         </div>
  384.         <?php
  385.     });
  386. }
  387.  
  388. add_action('plugins_loaded', 'If_Menu::init');
  389. add_action('plugins_loaded', 'Layered\IfMenu\Admin::start');
  390.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement