array(), 'subtabs' => array(), 'anchors' => array(), 'profiles' => array()); $file = AIEO_DIR . 'includes/dmm/data/menu-descriptions.php'; if (is_readable($file)) { $loaded = include $file; if (is_array($loaded)) { foreach (array('groups', 'subtabs', 'anchors', 'profiles') as $bucket) { if (!empty($loaded[$bucket]) && is_array($loaded[$bucket])) { $out[$bucket] = $loaded[$bucket]; } } } } self::$registry[$locale] = $out; return $out; } public static function for_subtab($id) { $r = self::registry(); $id = (string) $id; return isset($r['subtabs'][$id]) ? (string) $r['subtabs'][$id] : ''; } public static function for_group($id) { $r = self::registry(); $id = (string) $id; return isset($r['groups'][$id]) ? (string) $r['groups'][$id] : ''; } public static function resolve($key) { $key = (string) $key; if ($key === '' || strlen($key) > self::MAX_KEY) { return self::none(); } $r = self::registry(); if (strpos($key, 'profile-') === 0) { $p = substr($key, strlen('profile-')); if (!isset($r['profiles'][$p])) { return self::none(); } $text = (string) $r['profiles'][$p]; if (class_exists('AIEO_SEO_Score') && method_exists('AIEO_SEO_Score', 'profile_status')) { $text = rtrim($text); if ('' !== $text && !preg_match('/[.!?;·]$/u', $text)) { $text .= '.'; } $status = AIEO_SEO_Score::profile_status(); $text .= ' ' . (!empty($status['pinned']) ? __('You set this yourself.', 'ai-eshop-optimizer') : __('Detected automatically.', 'ai-eshop-optimizer')); if (!empty($status['mismatch'])) { $text .= ' ' . __('It no longer matches what detection sees, which may be exactly why you set it.', 'ai-eshop-optimizer'); } } return array('text' => $text, 'scope' => 'self', 'owner' => ''); } $anchor = ''; $path = $key; $hash = strpos($key, '#'); if ($hash !== false) { $anchor = substr($key, $hash + 1); $path = substr($key, 0, $hash); if (strpos($anchor, 'aieo-card-') === 0) { $anchor = substr($anchor, strlen('aieo-card-')); } if ($anchor !== '' && isset($r['anchors'][$anchor])) { return array('text' => (string) $r['anchors'][$anchor], 'scope' => 'self', 'owner' => ''); } } $parts = array_values(array_filter(explode('/', $path), static function ($p) { return $p !== ''; })); if (count($parts) === 1) { $id = $parts[0]; if ($anchor === '' && isset($r['subtabs'][$id])) { return array('text' => (string) $r['subtabs'][$id], 'scope' => 'self', 'owner' => ''); } if ($anchor === '' && isset($r['groups'][$id])) { return array('text' => (string) $r['groups'][$id], 'scope' => 'self', 'owner' => ''); } if (isset($r['subtabs'][$id])) { return array('text' => (string) $r['subtabs'][$id], 'scope' => 'page', 'owner' => $id); } return self::none(); } $tab = isset($parts[1]) ? $parts[1] : ''; if ($tab === '') { return self::none(); } if (isset($parts[2])) { $composite = $tab . '_' . $parts[2]; if (isset($r['subtabs'][$composite])) { return array( 'text' => (string) $r['subtabs'][$composite], 'scope' => ('' === $anchor) ? 'self' : 'page', 'owner' => ('' === $anchor) ? '' : $tab, ); } } if (isset($r['subtabs'][$tab])) { $exact = ($anchor === '' && !isset($parts[2])); return array( 'text' => (string) $r['subtabs'][$tab], 'scope' => $exact ? 'self' : 'page', 'owner' => $exact ? '' : $tab, ); } return self::none(); } private static function none() { return array('text' => '', 'scope' => '', 'owner' => ''); } private static function owner_label($id) { if ($id === '' || !class_exists('AIEO_DMM')) { return ''; } $module = AIEO_DMM::instance()->get_module($id); if (!$module || !method_exists($module, 'get_label')) { return ''; } return html_entity_decode(wp_strip_all_tags((string) $module->get_label()), ENT_QUOTES, 'UTF-8'); } public static function register() { add_action('wp_ajax_' . self::AJAX_ACTION, array(__CLASS__, 'ajax_describe')); } public static function enqueue() { $path = AIEO_DIR . 'assets/js/aieo-describe.js'; if (!file_exists($path)) { return; } wp_enqueue_script( 'aieo-describe', AIEO_URI . 'assets/js/aieo-describe.js', array(), (string) filemtime($path), true ); wp_localize_script('aieo-describe', 'aieoDescribe', array( 'ajaxUrl' => admin_url('admin-ajax.php'), 'action' => self::AJAX_ACTION, 'nonce' => wp_create_nonce(self::AJAX_ACTION), 'i18n' => array( 'partOf' => __('Part of %s', 'ai-eshop-optimizer'), 'none' => __('No description written for this one yet', 'ai-eshop-optimizer'), 'loading' => __('…', 'ai-eshop-optimizer'), ), )); } public static function ajax_describe() { check_ajax_referer(self::AJAX_ACTION, 'nonce'); if (!current_user_can('manage_woocommerce') && !current_user_can('manage_options')) { wp_send_json_error(array('message' => __('Not allowed.', 'ai-eshop-optimizer')), 403); } $key = isset($_GET['key']) ? (string) wp_unslash($_GET['key']) : ''; $key = preg_replace('/[^A-Za-z0-9_\-\/#]/', '', $key); $key = (string) substr((string) $key, 0, self::MAX_KEY); $hit = self::resolve($key); wp_send_json_success(array( 'key' => $key, 'text' => $hit['text'], 'scope' => $hit['scope'], 'owner' => 'page' === $hit['scope'] ? self::owner_label($hit['owner']) : '', )); } }