. * You can contact New Signature by electronic mail at labs@newsignature.com -or- by U.S. Postal Service at 1100 H St. NW, Suite 940, Washington, DC 20005. */ /** * @file * The main file for the Most Popular module. */ // Define some constants to determine how much to style the mostpopular block. define('MOSTPOPULAR_STYLE_NONE', 0); define('MOSTPOPULAR_STYLE_BASIC', 1); define('MOSTPOPULAR_STYLE_FULL', 2); define('MOSTPOPULAR_SERVICE_STATUS_ERROR', -2); define('MOSTPOPULAR_SERVICE_STATUS_DISABLED', -1); define('MOSTPOPULAR_SERVICE_STATUS_PENDING', 0); define('MOSTPOPULAR_SERVICE_STATUS_CONFIGURED', 1); define('MOSTPOPULAR_SERVICE_STATUS_OK', 2); define('MOSTPOPULAR_DEFAULT_EXCLUDES', "admin/*\nuser/*\nnode/*/*\n*?*\n"); /** * Implements hook_permission(). */ function mostpopular_permission() { return array( 'administer mostpopular' => array( 'title' => t('Administer Most Popular'), ), ); } /** * Implement hook_help(). */ function mostpopular_help($path, $arg) { if ($path == 'admin/help#mostpopular') { return t('The Most Popular module retrieves a list of the most popular content on your site through Google Analytics or other services, and provides a block for displaying the most popular content to users.'); } if ($path == 'admin/config/mostpopular/intervals') { return '
' . t("The interval field for each row must contain a string that can be understood by strtotime(). You must specify each as a negative interval relative to today.", array( '@strtotime' => 'http://php.net/manual/en/function.strtotime.php', )) . '
' . '' . t('To remove an interval, clear both the title and interval values.') . '
' . '' . t( "If you make changes to the intervals, any custom service throttles you may have set up will be reset to their default values.") . '
'; } } /** * Implements hook_menu(). */ function mostpopular_menu() { $items = array(); $items['admin/config/mostpopular'] = array( 'title' => 'Most Popular', 'description' => 'Configure the Most Popular block functionality.', 'page callback' => 'system_admin_menu_block_page', 'access arguments' => array('administer mostpopular'), 'file' => 'system.admin.inc', 'file path' => drupal_get_path('module', 'system'), 'position' => 'right', 'type' => MENU_NORMAL_ITEM, ); $items['admin/config/mostpopular/config'] = array( 'title' => 'Settings', 'description' => 'Basic settings for all Most Popular blocks.', 'page callback' => 'drupal_get_form', 'file' => 'mostpopular.admin.inc', 'page arguments' => array('mostpopular_settings_form'), 'access arguments' => array('administer mostpopular'), 'type' => MENU_LOCAL_TASK | MENU_VISIBLE_IN_TREE, 'weight' => 0, ); $items['admin/config/mostpopular/blocks'] = array( 'title' => 'Blocks', 'description' => 'Configure the available Most Popular blocks.', 'file' => 'mostpopular.blocks.inc', 'page callback' => 'drupal_get_form', 'page arguments' => array('mostpopular_blocks_admin_form'), 'access arguments' => array('administer mostpopular'), 'type' => MENU_LOCAL_TASK | MENU_VISIBLE_IN_TREE, 'weight' => 5, ); $items['admin/config/mostpopular/services'] = array( 'title' => 'Services', 'description' => 'Configure the services available in each Most Popular block.', 'file' => 'mostpopular.services.inc', 'page callback' => 'drupal_get_form', 'page arguments' => array('mostpopular_services_admin_form'), 'access arguments' => array('administer mostpopular'), 'type' => MENU_LOCAL_TASK | MENU_VISIBLE_IN_TREE, 'weight' => 10, ); $items['admin/config/mostpopular/services/list'] = array( 'title' => 'List', 'type' => MENU_DEFAULT_LOCAL_TASK, 'weight' => -50, ); $items['admin/config/mostpopular/services/%/edit'] = array( 'title callback' => 'mostpopular_service_title', 'title arguments' => array( 4 ), 'file' => 'mostpopular.services.inc', 'page callback' => 'drupal_get_form', 'page arguments' => array( 'mostpopular_service_config_form', 4 ), 'access arguments' => array( 'administer mostpopular' ), 'type' => MENU_NORMAL_ITEM, 'context' => MENU_CONTEXT_INLINE | MENU_CONTEXT_PAGE, ); $items['admin/config/mostpopular/services/%/delete'] = array( 'title' => 'Delete', 'file' => 'mostpopular.services.inc', 'page callback' => 'drupal_get_form', 'page arguments' => array( 'mostpopular_service_delete_form', 4 ), 'access arguments' => array( 'administer mostpopular' ), 'type' => MENU_NORMAL_ITEM, 'context' => MENU_CONTEXT_INLINE | MENU_CONTEXT_PAGE, ); $items['admin/config/mostpopular/intervals'] = array( 'title' => 'Intervals', 'description' => 'Configure the intervals of time used for each Most Popular block.', 'file' => 'mostpopular.intervals.inc', 'page callback' => 'drupal_get_form', 'page arguments' => array('mostpopular_intervals_admin_form'), 'access callback' => 'user_access', 'access arguments' => array('administer mostpopular'), 'type' => MENU_LOCAL_TASK | MENU_VISIBLE_IN_TREE, 'weight' => 20, ); $items['admin/config/mostpopular/refresh'] = array( 'title' => 'Refresh Stats', 'description' => 'Refresh the Most Popular stats.', 'page callback' => 'mostpopular_refresh', 'access callback' => 'user_access', 'access arguments' => array('administer mostpopular'), 'type' => MENU_LOCAL_TASK | MENU_VISIBLE_IN_TREE, 'weight' => 30, ); $items['mostpopular/ajax/%/%/%'] = array( 'title' => 'Get the most popular stats via AJAX', 'page callback' => 'mostpopular_items_ajax', 'page arguments' => array(2, 3, 4), 'access callback' => 'user_access', 'access arguments' => array('access content'), 'type' => MENU_CALLBACK, ); return $items; } /** * Implements hook_theme(). */ function mostpopular_theme($existing, $type, $theme, $path) { $themes = array( 'mostpopular_admin_blocks_table' => array( 'render element' => 'element', 'file' => 'mostpopular.blocks.inc', ), 'mostpopular_admin_services_table' => array( 'render element' => 'element', 'file' => 'mostpopular.services.inc', ), 'mostpopular_service_status' => array( 'variables' => array( 'status' => 0 ), 'file' => 'mostpopular.services.inc', ), 'mostpopular_admin_intervals_table' => array( 'render element' => 'element', 'file' => 'mostpopular.intervals.inc', ), // Theme for the block 'mostpopular_block' => array( 'variables' => array( 'services' => array(), 'intervals' => array(), 'bid' => 0, ), 'file' => 'mostpopular.theme.inc', 'template' => 'templates/mostpopular-block', 'preprocess functions' => array( 'template_preprocess', 'template_preprocess_mostpopular_block', ), ), // Themes for the service tabs 'mostpopular_services' => array( 'variables' => array( 'services' => array(), ), 'file' => 'mostpopular.theme.inc', 'preprocess functions' => array( 'template_preprocess', 'template_preprocess_mostpopular_services', ), ), 'mostpopular_service' => array( 'variables' => array( 'service' => array(), ), 'file' => 'mostpopular.theme.inc', 'preprocess functions' => array( 'template_preprocess', 'template_preprocess_mostpopular_service', ), ), // Themes for the intervals tabs 'mostpopular_intervals' => array( 'variables' => array( 'intervals' => array(), ), 'file' => 'mostpopular.theme.inc', 'preprocess functions' => array( 'template_preprocess', 'template_preprocess_mostpopular_intervals', ), ), 'mostpopular_interval' => array( 'variables' => array( 'interval' => array(), ), 'file' => 'mostpopular.theme.inc', 'preprocess functions' => array( 'template_preprocess', 'template_preprocess_mostpopular_interval', ), ), // Themes for the most popular result items 'mostpopular_items' => array( 'variables' => array( 'items' => array(), ), 'file' => 'mostpopular.theme.inc', 'preprocess functions' => array( 'template_preprocess', 'template_preprocess_mostpopular_items', ), ), 'mostpopular_item' => array( 'variables' => array( 'item' => null, ), 'file' => 'mostpopular.theme.inc', 'template' => 'templates/mostpopular-item', 'preprocess functions' => array( 'template_preprocess', 'template_preprocess_mostpopular_item', ), ), 'mostpopular_items__none' => array( 'variables' => array(), 'file' => 'mostpopular.theme.inc', ), ); return $themes; } function _mostpopular_save($type, &$object) { if (!is_object($object)) { $object = (object)$object; } // Get information about the table $table = "mostpopular_$type"; $schema = drupal_get_schema($table); // Find the object's ID foreach ($schema['fields'] as $key => $field) { if ($field['type'] == 'serial') { $id = $key; } elseif (!empty($field['serialize'])) { $data = $key; } } // Create a data element if necessary if (isset($data) && !isset($object->$data)) { $object->$data = array(); } // Now, invoke the callbacks and save the object module_invoke_all("{$table}_presave", $object); if (!empty($object->$id)) { drupal_write_record($table, $object, array($id)); $status = 'update'; } else { drupal_write_record($table, $object); $status = 'insert'; } module_invoke_all("{$table}_{$status}", $object); } function _mostpopular_callback($callback, $info) { if (is_array($info)) { $info = (object)$info; } if (isset($info->file)) { include $info->file; } $module = $info->module; $delta = $info->delta; $function = FALSE; if (isset($info->callbacks[$callback]) && function_exists($info->callbacks[$callback])) { $function = $info->callbacks[$callback]; } elseif (function_exists("{$module}_{$callback}_{$delta}")) { $function = "{$module}_{$callback}_{$delta}"; } elseif (function_exists("{$module}_{$callback}")) { $function = "{$module}_{$callback}"; } // If the module does not define the callback but there is a default, use it. elseif (function_exists("mostpopular_default_{$callback}")) { $function = "mostpopular_default_{$callback}"; } return $function; } function _mostpopular_invoke($callback, $info, &$arg1 = NULL, &$arg2 = NULL, &$arg3 = NULL) { if (is_array($info)) { $info = (object)$info; } if (isset($info->file)) { include $info->file; } $function = _mostpopular_callback($callback, $info); if ($function) { return $function($info, $arg1, $arg2, $arg3); } return FALSE; } /** * Gets the list of available services. * * @see hook_mostpopular_service_info() */ function mostpopular_service_info($module = NULL, $delta = NULL) { $services = &drupal_static(__FUNCTION__); if (!isset($services)) { $services = array(); foreach (module_implements('mostpopular_service_info') as $m) { $info = module_invoke($m, 'mostpopular_service_info'); foreach ($info as $d => $data) { $data += array( 'module' => $m, 'delta' => $d, 'title' => '', ); $services[$m][$d] = $data; } } } if (!empty($module)) { if (!empty($delta)) { if (isset($services[$module][$delta])) { return $services[$module][$delta]; } return FALSE; } if (isset($services[$module])) { return $services[$module]; } return FALSE; } return $services; } /** * Implements hook_load(). * * Loads a configured most popular service based on its ID. * * @param integer $sid * The ID of the configured service. * @param boolean $reset * True if the cache should be reset. * @return object * A most popular service configuration from the database. */ function mostpopular_service_load($sid, $reset = FALSE) { $services = &drupal_static(__FUNCTION__, array()); if (!isset($services[$sid]) || $reset) { $services[$sid] = reset(mostpopular_service_load_multiple(array($sid))); } return $services[$sid]; } /** * Loads configured most popular services within the given block. * * @param integer $bid * The block ID. * @param boolean $enabled * If true (default), only enabled services will be retrieved. * If false, all services will be retrieved. * @return array * An array of most popular service configurations. */ function mostpopular_service_load_by_block($bid, $enabled = TRUE, $reset = FALSE) { $services = &drupal_static(__FUNCTION__, array()); if (!isset($services[$bid]) || $reset) { $params = array( 'bid' => $bid, ); if ($enabled) { $params['enabled'] = TRUE; } $services[$bid] = mostpopular_service_load_multiple(array(), $params); } return $services[$bid]; } /** * Implements hook_load_multiple(). * * Loads configured most popular services based on their IDs. * * @param array $sids * The IDs of the desired services. * @param array $conditions * Additional conditions to use. * @param boolean $reset * True if the cache should be reset. * @return array * An array of most popular service configurations. * * @see entity_load() */ function mostpopular_service_load_multiple($sids = array(), $conditions = array()) { // Unless conditions are specified explicitly, only get the enabled services. if (empty($sids) && empty($conditions)) { $conditions['enabled'] = 1; } $q = db_select('mostpopular_service', 's') ->fields('s'); if (!empty($sids)) { $q->condition('sid', $sids); } foreach ($conditions as $field => $value) { $q->condition($field, $value); } $q->orderBy('weight', 'ASC'); $services = $q->execute()->fetchAllAssoc('sid', PDO::FETCH_ASSOC); // Augment each service with data from the hooks foreach ($services as $sid => $service) { $info = mostpopular_service_info($service['module'], $service['delta']); if ($info) { $service += $info; } // Unserialize the extra data if (!empty($service['data'])) { $service['data'] = unserialize($service['data']); } $services[$sid] = (object)$service; } return $services; } function mostpopular_service_save($service) { _mostpopular_save('service', $service); } /** * Before a mostpopular service is saved, update its status. * * @param object $service The service being saved. */ function mostpopular_mostpopular_service_presave($service) { if ($service->enabled == 0) { $service->status = MOSTPOPULAR_SERVICE_STATUS_DISABLED; } elseif ($service->status == MOSTPOPULAR_SERVICE_STATUS_DISABLED) { $service->status = MOSTPOPULAR_SERVICE_STATUS_PENDING; } } /** * Returns the name of a service, for the menu hooks. * * @param integer $sid The service ID. */ function mostpopular_service_title($sid) { $service = mostpopular_service_load($sid); if ($service) { return t('@name: %title', array( '@name' => $service->name, '%title' => $service->title, )); } } /** * Deletes the service configuration with the given ID. * * @param integer $sid The service ID. */ function mostpopular_service_delete($sid) { if (!empty($sid) && is_numeric($sid)) { db_delete('mostpopular_service') ->condition('sid', $sid) ->execute(); } } /** * Gets the configured Most Popular intervals. * * @param integer $iid Optionally the ID of a single interval to retrieve. */ function mostpopular_intervals($iid = NULL) { $intervals = &drupal_static(__FUNCTION__); if (!isset($intervals)) { $intervals = db_select('mostpopular_interval', 'i') ->fields('i') ->execute() ->fetchAllAssoc('iid'); } if (!empty($iid)) { if (isset($intervals[$iid])) { return $intervals[$iid]; } return FALSE; } return $intervals; } /** * Gets the configured intervals for the given block. * * @param integer $bid The ID of the block. */ function mostpopular_interval_load_by_block($bid) { $intervals = &drupal_static(__FUNCTION__, array()); if (!isset($intervals[$bid])) { $intervals[$bid] = db_select('mostpopular_interval', 'i') ->fields('i') ->condition('bid', $bid) ->orderBy('weight', 'ASC') ->execute() ->fetchAllAssoc('iid'); } return $intervals[$bid]; } /** * Returns the timestamp, relative to the current time, that marks * the start of this interval. * * @param object $interval * The interval configuration. * @return integer * A timestamp in the past, or 0 if there is no interval string specified. */ function mostpopular_interval_timestamp($interval) { if (is_int($interval)) { $interval = mostpopular_intervals($interval); } return !empty($interval->string) ? strtotime($interval->string) : 0; } /** * Returns the full title, which is the interval's title prepended with * 'Past '. So, for instance, 'Day' becomes 'Past Day'. * * @return string * The full title of the interval. */ function mostpopular_interval_title($interval) { if (is_int($interval)) { $interval = mostpopular_intervals($interval); } if (!$interval) { return ''; } return 'Past ' . $interval->title; } function mostpopular_interval_save($interval) { _mostpopular_save('interval', $interval); } function mostpopular_interval_delete($interval) { // Delete the interval itself db_delete('mostpopular_interval') ->condition('iid', $interval->iid) ->execute(); // Delete any cached items for this interval db_delete('mostpopular_item') ->condition('iid', $interval->iid) ->execute(); } /** * Returns an array of default intervals to use for a new block. * * @param integer $bid The ID of the block. */ function mostpopular_interval_defaults($bid) { $defaults = array( (object)array( 'bid' => $bid, 'title' => '1 day', 'string' => '-1 day', 'weight' => 0, ), (object)array( 'bid' => $bid, 'title' => '1 week', 'string' => '-1 week', 'weight' => 1, ), (object)array( 'bid' => $bid, 'title' => '1 month', 'string' => '-1 month', 'weight' => 2, ), (object)array( 'bid' => $bid, 'title' => '1 year', 'string' => '-1 year', 'weight' => 3, ), ); // Allow other modules to change this list. drupal_alter('mostpopular_interval_defaults', $defaults, $bid); return $defaults; } /** * Gets the configured Most Popular blocks. * * @param integer $bid Optionally, the block ID of an individual block to get. * @return mixed If a $bid was provided, returns just the matching block. Otherwise, * returns a list of all the configured blocks. */ function mostpopular_blocks($bid = NULL) { $blocks = &drupal_static(__FUNCTION__); if (!isset($blocks)) { $blocks = db_select('mostpopular_block', 'b') ->fields('b') ->execute() ->fetchAllAssoc('bid'); foreach ($blocks as $b => $block) { $blocks[$b]->data = unserialize($block->data); if (!$blocks[$b]->data) { $blocks[$b]->data = array(); } } } if (!empty($bid)) { if (isset($blocks[$bid])) { return $blocks[$bid]; } return FALSE; } return $blocks; } function mostpopular_blocks_local() { $blocks = &drupal_static(__FUNCTION__); if (!isset($blocks)) { $blocks = db_select('mostpopular_block', 'b') ->fields('b') ->condition('remote_bid', NULL) ->execute() ->fetchAllAssoc('bid'); foreach ($blocks as $b => $block) { $blocks[$b]->data = unserialize($block->data); if (!$blocks[$b]->data) { $blocks[$b]->data = array(); } } } return $blocks; } function mostpopular_blocks_remote() { $blocks = &drupal_static(__FUNCTION__); if (!isset($blocks)) { $blocks = db_select('mostpopular_block', 'b') ->fields('b') ->condition('remote_bid', 0, '>') ->execute() ->fetchAllAssoc('bid'); foreach ($blocks as $b => $block) { $blocks[$b]->data = unserialize($block->data); if (!$blocks[$b]->data) { $blocks[$b]->data = array(); } } } return $blocks; } /** * Implements hook_block_save(). * * @param unknown_type $delta * @param unknown_type $values */ function mostpopular_block_save($block, $values = array()) { if (!is_object($block)) { $block = mostpopular_blocks($block); } if ($block) { if (isset($values['mostpopular'])) { $values = $values['mostpopular']; } foreach ($values as $key => $value) { if (is_array($value)) { $data = &$block->$key; foreach ($value as $k => $v) { $data[$k] = $v; } } else { $block->$key = $value; } } _mostpopular_save('block', $block); } } function mostpopular_block_delete($bid) { if (empty($bid)) { return; } $services = mostpopular_service_load_by_block($bid, FALSE); $intervals = mostpopular_interval_load_by_block($bid); db_delete('mostpopular_block') ->condition('bid', $bid) ->execute(); db_delete('mostpopular_service') ->condition('bid', $bid) ->execute(); db_delete('mostpopular_interval') ->condition('bid', $bid) ->execute(); if (!empty($services) && !empty($intervals)) { db_delete('mostpopular_item') ->condition('sid', array_keys($services)) ->condition('iid', array_keys($intervals)) ->execute(); db_delete('mostpopular_last_run') ->condition('sid', array_keys($services)) ->condition('iid', array_keys($intervals)) ->execute(); } drupal_set_message(t('Deleted block @bid', array( '@bid' => $bid ))); } /** * Implements hook_block_info(). * * Defines each of the most popular blocks. * * Each block will render its contents based on user cookies. This allows us to * cache the block itself. */ function mostpopular_block_info() { $out = array(); $blocks = mostpopular_blocks(); foreach ($blocks as $bid => $block) { $out[$block->bid] = array( 'info' => t('Most Popular: @name', array( '@name' => !empty($block->name) ? $block->name : $block->bid, )), 'cache' => DRUPAL_CACHE_GLOBAL, ); } return $out; } /** * Implements hook_block_view(). * * Creates the most popular block. * * The service and interval to show by default are loaded from the user's cookie. * If they don't have a cookie set, the first service and first interval will be * selected by default. * * @param integer $bid The ID of the block. */ function mostpopular_block_view($bid = '') { $block = mostpopular_blocks($bid); if ($block) { if (!empty($block->data['remote_database'])) { if (!db_set_active($block->data['remote_database'])) { watchdog('mostpopular', 'Missing remote database @database', array( '@database' => $block->data['remote_database'], ), WATCHDOG_ERROR); db_set_active('default'); return NULL; } $services = mostpopular_service_load_by_block($block->remote_bid); $intervals = mostpopular_interval_load_by_block($block->remote_bid); db_set_active('default'); } else { $services = mostpopular_service_load_by_block($bid); $intervals = mostpopular_interval_load_by_block($bid); } $out = array( 'subject' => !empty($block->title) ? $block->title : t('Most Popular'), 'content' => array( '#theme' => 'mostpopular_block', '#services' => $services, '#intervals' => $intervals, '#bid' => $bid, ), ); // Attach the stylesheets and javascript $path = drupal_get_path('module', 'mostpopular'); switch (variable_get('mostpopular_styling', MOSTPOPULAR_STYLE_FULL)) { case MOSTPOPULAR_STYLE_BASIC: $out['content']['#attached']['css'][] = "$path/css/mostpopular-basic.css"; break; case MOSTPOPULAR_STYLE_FULL: $out['content']['#attached']['css'][] = "$path/css/mostpopular-basic.css"; $out['content']['#attached']['css'][] = "$path/css/mostpopular-full.css"; break; } $out['content']['#attached']['js'][] = 'misc/jquery.cookie.js'; $out['content']['#attached']['js'][] = "$path/js/fade.js"; $out['content']['#attached']['js'][] = "$path/js/mostpopular.js"; $out['content']['#attached']['js'][] = array( 'data' => array( 'mostpopular' => array('url' => url('mostpopular/ajax')), ), 'type' => 'setting', ); return $out; } return NULL; } function mostpopular_items_ajax($bid, $sid, $iid) { $rendered = &drupal_static(__FUNCTION__); $block = mostpopular_blocks($bid); $cid = "mostpopular_items:{$bid}:{$sid}:{$iid}"; if (!isset($rendered[$bid][$sid][$iid])) { $cached = cache_get($cid, 'cache_block'); if ($cached && $cached->expire > time()) { $rendered[$bid][$sid][$iid] = $cached->data; } } if (!isset($rendered[$bid][$sid][$iid])) { if (!empty($block->data['remote_database'])) { if (!db_set_active($block->data['remote_database'])) { watchdog('mostpopular', 'Missing remote database @database', array( '@database' => $block->data['remote_database'], ), WATCHDOG_ERROR); db_set_active('default'); drupal_json_output(''); return; } } try { $items = db_select('mostpopular_item', 'i') ->fields('i') ->condition('sid', $sid) ->condition('iid', $iid) ->orderBy('count', 'DESC') ->execute() ->fetchAll(); $out = array( '#theme' => 'mostpopular_items', '#service' => mostpopular_service_load($sid), '#interval' => mostpopular_intervals($iid), '#items' => $items, ); // Cache the rendered items until the next update $next_run = db_select('mostpopular_last_run', 'm') ->fields('m', array('next_run')) ->condition('sid', $sid) ->condition('iid', $iid) ->execute() ->fetchColumn(); } catch (Exception $ex) { watchdog('mostpopular', 'Failed to load @source mostpopular items: %message', array( '@source' => !empty($block->data['remote_database']) ? t('remote') : t('local'), '%message' => $ex->getMessage() ), WATCHDOG_WARNING); } db_set_active('default'); $rendered[$bid][$sid][$iid] = drupal_render($out); cache_set($cid, $rendered[$bid][$sid][$iid], 'cache_block', $next_run > 0 ? $next_run : CACHE_TEMPORARY); } if (isset($rendered[$bid][$sid][$iid])) { drupal_json_output($rendered[$bid][$sid][$iid]); } else { drupal_json_output(''); } } /** * Implements the default 'next_run' callback, for services that don't provide their own. * * Returns the timestamp at which to next refresh the data for this interval. * * @param object $service The service definition * @param integer $span The number of seconds representing the current interval. * @param integer $last_run The timestamp at which this service was last run for this interval. */ function mostpopular_default_next_run($service, $span, $last_run) { // If the interval is 2 days or less, refresh once per hour if ($span <= 60 * 60 * 24 * 2) { return strtotime('1 hour', $last_run); } // If the interval is 1 year or more, refresh once per week elseif ($span >= 60 * 60 * 24 * 365) { return strtotime('1 week', $last_run); } // Otherwise, refresh once per day. return strtotime('1 day', $last_run); } /* ---------------------------------------------------------------------------- * Cron jobs to fetch stats * --------------------------------------------------------------------------*/ /** * Implements hook_cron(). * * Refreshes data from the services periodically. */ function mostpopular_cron() { $t = mostpopular_refresh(TRUE); watchdog('mostpopular_cron', $t); } /** * Refreshes data from each service by invoking the refresh callback for each service. */ function mostpopular_refresh($cron = FALSE) { $t = ''; // Loop through all the local blocks $blocks = mostpopular_blocks_local(); foreach ($blocks as $bid => $block) { $services = mostpopular_service_load_by_block($bid); $intervals = mostpopular_interval_load_by_block($bid); foreach ($services as $sid => $service) { $count = 0; $t .= '