function _feedapi_invoke_refresh in FeedAPI 6
Same name and namespace in other branches
- 5 feedapi.module \_feedapi_invoke_refresh()
Helper function for feedapi_invoke(). Refresh the feed, call the proper parsers and processors' hooks. Don't call this function directly, use feedapi_refresh() instead.
@ TODO Fix: This may loop forever when a feed has no processors
1 call to _feedapi_invoke_refresh()
- feedapi_invoke in ./
feedapi.module - Invoke feedapi API callback functions.
File
- ./
feedapi.module, line 1187 - Handle the submodules (for feed and item processing) Provide a basic management of feeds
Code
function _feedapi_invoke_refresh(&$feed, $param) {
$timestamp = variable_get('cron_semaphore', FALSE) !== FALSE ? variable_get('cron_semaphore', FALSE) : time();
$counter = array();
timer_start('feedapi_' . $feed->nid);
$memory_usage_before = function_exists('memory_get_usage') ? memory_get_usage() : 0;
$cron = $param;
// Step 0: Check processors and grab settings
if (!is_array($feed->processors) || count($feed->processors) == 0) {
if (!$cron) {
drupal_set_message(t("No processors specified for URL %url. Could not refresh.", array(
'%url' => $feed->url,
)), "error");
drupal_goto('node/' . $feed->nid);
}
return 0;
}
$settings = feedapi_get_settings(NULL, $feed->vid);
// Step 1: Force processors to delete old items and determine the max. create elements.
$counter['expired'] = feedapi_expire($feed, $settings);
// Step 2: Get feed.
$nid = $feed->nid;
$hash_old = isset($feed->hash) ? $feed->hash : '';
$feed = _feedapi_call_parsers($feed, $feed->parsers, $settings['parsers']);
if (is_object($feed)) {
$feed->hash = md5(serialize($feed->items));
}
// Step 3: See, whether feed has been modified.
if (!isset($feed->items) || $hash_old == $feed->hash) {
// Updated the next_refresh_time field in any case.
db_query("UPDATE {feedapi} SET next_refresh_time = %d, half_done = %d WHERE nid = %d", time() + $settings['refresh_time'], FALSE, $nid);
if (!$cron) {
if (is_object($feed) && $hash_old == $feed->hash) {
drupal_set_message(t('There are no new items in the feed.'), 'status');
}
else {
drupal_set_message(t('Could not refresh feed.'), 'error');
}
}
return $counter;
}
// Step 4: Walk through the items and check duplicates, then save or update
$items = $feed->items;
$updated = 0;
$new = 0;
$half_done = FALSE;
// We check for time-out after each item
foreach ($items as $index => $item) {
// Call each item parser.
$item->is_updated = FALSE;
$item->is_new = FALSE;
foreach ($feed->processors as $processor) {
$unique = module_invoke($processor, 'feedapi_item', 'unique', $item, $feed->nid, $settings['processors'][$processor]);
if ($unique === FALSE || is_numeric($unique)) {
if ($settings['update_existing'] == TRUE) {
module_invoke($processor, 'feedapi_item', 'update', $item, $feed->nid, $settings['processors'][$processor], $unique);
$item->is_updated = TRUE;
}
}
else {
// We have checked before for expired items, so just save it.
// if the item is already expired then do nothing
$items_delete = $settings['items_delete'];
$diff = abs(time() - (isset($item->options->timestamp) ? $item->options->timestamp : time()));
if ($diff > $items_delete && $items_delete > FEEDAPI_NEVER_DELETE_OLD) {
break;
}
$result = module_invoke($processor, 'feedapi_item', 'save', $item, $feed->nid, $settings['processors'][$processor]);
if ($result !== FALSE) {
$item->is_new = TRUE;
}
}
}
$new = $item->is_new ? $new + 1 : $new;
$updated = $item->is_updated && !$item->is_new ? $updated + 1 : $updated;
// Decision on time. If the exec time is greather than the user-set percentage of php max execution time
if ($cron && !feedapi_cron_time()) {
$half_done = $new + $updated == count($items) ? FALSE : TRUE;
break;
}
// Save the item status for further processing
$feed->items[$index] = $item;
}
// Closing step: Call after refresh and update feed statistics
foreach (module_implements('feedapi_after_refresh') as $module) {
$func = $module . '_feedapi_after_refresh';
$func($feed);
}
// Set next_refresh_time to FEEDAPI_CRON_NEVER_REFRESH if refresh_time is FEEDAPI_CRON_NEVER_REFRESH.
$next_refresh_time = $settings['refresh_time'] == FEEDAPI_CRON_NEVER_REFRESH ? $settings['refresh_time'] : time() + $settings['refresh_time'];
db_query("UPDATE {feedapi} SET next_refresh_time = %d, half_done = %d, hash = '%s' WHERE nid = %d", $next_refresh_time, $half_done, $feed->hash, $feed->nid);
// Log statistics.
$memory_usage_after = function_exists('memory_get_usage') ? memory_get_usage() : 0;
_feedapi_store_stat($nid, 'update_times', time(), $timestamp);
_feedapi_store_stat($nid, 'new', $new, $timestamp);
_feedapi_store_stat($nid, 'download_num', count($items), $timestamp);
_feedapi_store_stat($nid, 'process_time', timer_read('feedapi_' . $feed->nid), $timestamp);
_feedapi_store_stat($nid, 'memory_increase', $memory_usage_after - $memory_usage_before, $timestamp);
_feedapi_store_stat($nid, 'next_refresh_time', $next_refresh_time, $timestamp);
if (!$cron) {
if ($new == 0 && $updated == 0) {
drupal_set_message(t('There are no new items in the feed.'), 'status');
}
else {
drupal_set_message(t("%new new item(s) were saved. %updated existing item(s) were updated.", array(
"%new" => $new,
"%updated" => $updated,
)));
}
// @ TODO what value to return here?
}
else {
// Update and return counter
$counter['new'] = $new;
$counter['updated'] = $updated;
return $counter;
}
}