/** * Imports the latest items from media sources * * @mvc Controller * * The semaphore is used to prevent importing the same post twice in a parallel request. The key is * based on the `site_url()` in order to avoid blocking requests to other sites in the same multisite network, * or other single-site installations on the same server. We could include the hashtag in the key as * well in order to allow parallel requests for different hashtags, but that would require handling the case * where multiple hashtags are used in one or both requests, which would complicate things without adding * much benefit. * * @param string $hashtags Comma-separated list of hashtags * @param string $rate_limit 'respect' to enforce the rate limit, or 'ignore' to ignore it */ protected function import_new_items($hashtags, $rate_limit = 'respect') { $hashtags = explode(',', $hashtags); $semaphore_key = (int) base_convert(substr(md5(__METHOD__ . site_url()), 0, 8), 16, 10); $semaphore_id = function_exists('sem_get') ? sem_get($semaphore_key) : false; if ($semaphore_id) { sem_acquire($semaphore_id); } $last_fetch = get_transient(Tagregator::PREFIX . 'last_media_fetch', 0); if ('ignore' == $rate_limit || self::refresh_interval_elapsed($last_fetch, $this->refresh_interval)) { set_transient(Tagregator::PREFIX . 'last_media_fetch', microtime(true)); // do this right away to minimize the chance of race conditions on systems that don't support the Semaphore module foreach (Tagregator::get_instance()->media_sources as $source) { foreach ($hashtags as $hashtag) { $source->import_new_items(trim($hashtag)); } } } if ($semaphore_id) { sem_release($semaphore_id); } }
require_once dirname(__FILE__) . '/views/requirements-error.php'; } /** * Loads all the files that make up Tagregator */ function tggr_include_files() { require_once dirname(__FILE__) . '/classes/tggr-module.php'; require_once dirname(__FILE__) . '/classes/tagregator.php'; require_once dirname(__FILE__) . '/classes/tggr-settings.php'; require_once dirname(__FILE__) . '/classes/tggr-shortcode-tagregator.php'; require_once dirname(__FILE__) . '/classes/tggr-media-source.php'; require_once dirname(__FILE__) . '/classes/tggr-source-twitter.php'; require_once dirname(__FILE__) . '/classes/tggr-source-instagram.php'; require_once dirname(__FILE__) . '/classes/tggr-source-flickr.php'; require_once dirname(__FILE__) . '/classes/tggr-source-google.php'; } /* * Check requirements and load main class * The main program needs to be in a separate file that only gets loaded if the plugin requirements are met. Otherwise older PHP installations could crash when trying to parse it. */ if (tggr_requirements_met()) { tggr_include_files(); if (class_exists('Tagregator')) { $GLOBALS['tggr'] = Tagregator::get_instance(); register_activation_hook(__FILE__, array($GLOBALS['tggr'], 'activate')); register_deactivation_hook(__FILE__, array($GLOBALS['tggr'], 'deactivate')); } } else { add_action('admin_notices', 'tggr_requirements_error'); }
/** * Validates submitted setting values before they get saved to the database. Invalid data will be overwritten with defaults. * @mvc Model * * @param array $new_settings * @return array */ public function validate_settings($new_settings) { $new_settings = shortcode_atts($this->settings, $new_settings, self::SETTING_SLUG); if (is_string($new_settings['db_version'])) { $new_settings['db_version'] = sanitize_text_field($new_settings['db_version']); } else { $new_settings['db_version'] = Tagregator::VERSION; } foreach (Tagregator::get_instance()->media_sources as $class_name => $media_source) { $new_settings[$class_name] = $media_source::get_instance()->validate_settings($new_settings[$class_name]); } return $new_settings; }