/**
  * Translate meta data
  * @see \WPGlobus_Filters::set_multilingual_meta_keys
  *
  * @param string|array $value     Null is passed. We set the value.
  * @param int          $object_id Post ID
  * @param string       $meta_key  Passed by the filter. We need only one key.
  * @param string|array $single    Meta value, or an array of values.
  *
  * @return string|array
  */
 public static function filter__postmeta($value, $object_id, $meta_key, $single)
 {
     /**
      * @todo Currently, only single values are supported
      */
     if (!$single) {
         return $value;
     }
     /**
      * Will process only if the `meta_key` is one of the explicitly set.
      */
     if (!isset(self::$multilingual_meta_keys[$meta_key])) {
         return $value;
     }
     /**
      * May be called many times on one page. Let's cache.
      */
     static $_cache;
     if (isset($_cache[$meta_key][$object_id])) {
         return $_cache[$meta_key][$object_id];
     }
     /** @global wpdb $wpdb */
     global $wpdb;
     $meta_value = $wpdb->get_var($wpdb->prepare("SELECT meta_value FROM {$wpdb->postmeta} WHERE meta_key = %s AND post_id = %d LIMIT 1;", $meta_key, $object_id));
     if ($meta_value) {
         if (is_serialized($meta_value)) {
             /**
              * @todo Refactor this. Write a `filter__array` method.
              */
             $_meta_array = unserialize($meta_value);
             foreach ($_meta_array as &$_value) {
                 if (is_array($_value)) {
                     foreach ($_value as &$_deep_value) {
                         /**
                          * @todo Assuming that the array had max. two levels, which is wrong.
                          */
                         $_deep_value = WPGlobus_Filters::filter__text($_deep_value);
                     }
                     unset($_deep_value);
                 } else {
                     $_value = WPGlobus_Filters::filter__text($_value);
                 }
             }
             unset($_value);
             $value = $_meta_array;
             /**
              * If single is requested, the following code is executed by
              * @see get_metadata
              * <code>
              * if ( $single && is_array( $check ) )
              *      return $check[0];
              * </code>
              * Therefore, we need to return the entire `$value` as the first element of
              * an array.
              */
             if ($single) {
                 $value = array($value);
             }
         } else {
             $value = WPGlobus_Filters::filter__text($meta_value);
         }
     }
     /**
      * Save to cache, even if we did not do anything
      */
     $_cache[$meta_key][$object_id] = $value;
     return $value;
 }
 /**
  * Filter api results
  *
  * @param stdClass|WP_Error $res    Response object or WP_Error.
  * @param string            $action The type of information being requested from the Plugin Install API.
  * @param stdClass          $args   Plugin API arguments.
  *
  * @return stdClass|WP_Error
  */
 public static function filter__plugins_api_result($res, $action, $args)
 {
     if (is_wp_error($res)) {
         return $res;
     }
     if (empty($res->plugins)) {
         return $res;
     }
     foreach ((array) $res->plugins as $key => $plugin) {
         if (false === strpos($plugin->slug, 'wpglobus')) {
             unset($res->plugins[$key]);
         } else {
             if ('wpglobus-for-black-studio-tinymce-widget' === $plugin->slug) {
                 /**
                  * Set correct slug for the
                  * `WPGlobus for Black Studio TinyMCE Widget` plugin.
                  *
                  * @since 1.6.3
                  */
                 $plugin->slug = 'wpglobus-for-black-studio-widget';
                 self::$plugin_card['free'][] = $plugin->slug;
                 self::$free_plugins[$plugin->slug]['extra_data']['correctLink'] = 'wpglobus-for-black-studio-tinymce-widget';
             } else {
                 self::$plugin_card['free'][] = $plugin->slug;
             }
         }
     }
     $url_wpglobus_site = WPGlobus_Utils::url_wpglobus_site();
     $all_products = self::_get_all_product_info();
     foreach (self::$paid_plugins as $plugin => $plugin_data) {
         $plugin_file = implode('/', array(WP_PLUGIN_DIR, $plugin_data['slug'], $plugin_data['loader']));
         if (is_readable($plugin_file)) {
             // Plugin is installed.
             self::$paid_plugins[$plugin]['plugin_data'] = get_plugin_data($plugin_file, false);
         } else {
             self::$paid_plugins[$plugin]['plugin_data'] = null;
             $product_slug = isset($plugin_data['product_slug']) ? $plugin_data['product_slug'] : $plugin;
             if (isset($all_products[$product_slug])) {
                 $plugin_info = $all_products[$product_slug];
                 // Titles come as multilingual strings.
                 $_plugin_title = WPGlobus_Filters::filter__text($plugin_info['title']);
                 self::$paid_plugins[$plugin]['plugin_data'] = array('Description' => '', 'Name' => $_plugin_title, 'Title' => $_plugin_title, 'Version' => $plugin_info['_api_new_version'], 'PluginURI' => $url_wpglobus_site . 'product/' . $product_slug . '/');
             }
         }
     }
     /**
      * Prepend the premium add-ons to the list of plugins.
      */
     foreach (self::$paid_plugins as $slug => $paid_plugin) {
         $_info = self::_plugin_info_template();
         $_info->slug = $slug;
         $_info->icons['default'] = $_info->icons['1x'] = $_info->icons['2x'] = WPGlobus::internal_images_url() . '/' . $paid_plugin['image_file'];
         if (!empty($paid_plugin['plugin_data'])) {
             $_info->name = $paid_plugin['plugin_data']['Name'];
             $_info->short_description = $paid_plugin['plugin_data']['Description'];
             $_info->homepage = $paid_plugin['plugin_data']['PluginURI'];
         } else {
             $_info->name = $slug;
         }
         self::$plugin_card['paid'][] = $slug;
         self::$paid_plugins[$slug]['card'] = $_info;
         self::$paid_plugins[$slug]['extra_data']['product_url'] = self::$paid_plugins[$slug]['extra_data']['details_url'] = $_info->homepage;
         array_unshift($res->plugins, $_info);
     }
     $res->info['results'] = count($res->plugins);
     return $res;
 }
 /**
  * Collect data for the beacon.
  * @return array
  */
 protected static function get_data()
 {
     $user = wp_get_current_user();
     $theme = wp_get_theme();
     $data = array('name' => WPGlobus_Filters::filter__text($user->display_name), 'email' => $user->user_email, 'home_url' => home_url(), 'site_url' => site_url(), 'REMOTE_ADDR' => $_SERVER['REMOTE_ADDR'], 'SERVER_PORT' => $_SERVER['SERVER_PORT'], 'OS' => implode(' ', array(php_uname('s'), php_uname('r'), php_uname('v'))), 'PHP_SAPI' => PHP_SAPI, 'PHP_VERSION' => PHP_VERSION, 'loaded_extensions' => implode(', ', get_loaded_extensions()), 'wp_version' => $GLOBALS['wp_version'], 'is_multisite' => is_multisite() ? 'Y' : 'N', 'theme' => $theme->display('Name') . ' ' . $theme->display('ThemeURI') . ' by ' . $theme->get('Author') . ' ' . $theme->get('AuthorURI') . (is_child_theme() ? '; child of ' . $theme->display('Template') : ''), 'enabled_languages' => implode(', ', WPGlobus::Config()->enabled_languages));
     // The list of plugins is formatted here for display on the admin page,
     // to fit into one table cell.
     $active_plugins = array();
     foreach (wp_get_active_and_valid_plugins() as $plugin) {
         $plugin_data = get_plugin_data($plugin);
         $plugin_file = str_replace(trailingslashit(WP_PLUGIN_DIR), '', dirname($plugin));
         $active_plugins[] = $plugin_file . ':' . $plugin_data['Version'];
     }
     $data['active_plugins'] = implode(', ', $active_plugins);
     return $data;
 }