Index: aggregation_api.inc =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/feedfield/aggregation_api.inc,v retrieving revision 1.2 diff -u -p -r1.2 aggregation_api.inc --- aggregation_api.inc 19 Dec 2006 19:20:09 -0000 1.2 +++ aggregation_api.inc 5 Jan 2010 22:14:42 -0000 @@ -1,16 +1,11 @@ $feed['title']))); - } - else { - drupal_set_message(t('A database error occured, no aggregator feed could be created.'), "error"); - } - return $fid; - } +function _aggregation_insert_feed($feed){ + // In the two lines below, the statements will short circuit if the variable + // is not null. Never seen this before, but it works. + $feed['refresh'] or $feed['refresh']=3600; + $feed['block_id'] or $feed['block_id']=5; + db_query("INSERT INTO {aggregator_feed} (title, url, refresh, block) VALUES ('%s', '%s', %d, %d)", + $feed['title'], + $feed['url'], + $feed['refresh'], + $feed['block_id']); + + if (!db_error()) { + drupal_set_message(t('A new aggregator feed "%title" was created', array('%title' => $feed['title']))); + } + else { + drupal_set_message(t('A database error occured, no aggregator feed could be created.'), "error"); + } + return db_last_insert_id('aggregator_feed', 'fid'); +} /** * Update an existing feed. Do not call directly, use sync_feed @@ -247,13 +265,13 @@ function aggregation_remove_feed_items($ * @return * A feed id for the updated feed */ - function _aggregation_update_feed($feed){ - $feed['refesh'] or $feed['refresh']=3600; - db_query("UPDATE {aggregator_feed} SET title = '%s', url = '%s', refresh = %d WHERE fid = %d", - $feed['title'], - $feed['url'], - $feed['refresh'], - $feed['fid']); - return $feed['fid']; - } -?> \ No newline at end of file +function _aggregation_update_feed($feed){ + $feed['refesh'] or $feed['refresh']=3600; + db_query("UPDATE {aggregator_feed} SET title = '%s', url = '%s', refresh = %d WHERE fid = %d", + $feed['title'], + $feed['url'], + $feed['refresh'], + $feed['fid']); + return $feed['fid']; +} +?> Index: feedfield.info =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/feedfield/feedfield.info,v retrieving revision 1.1 diff -u -p -r1.1 feedfield.info --- feedfield.info 17 May 2007 13:30:30 -0000 1.1 +++ feedfield.info 5 Jan 2010 22:14:42 -0000 @@ -1,4 +1,7 @@ -name = Feed field -description = CCK field to add an aggregation feed -dependencies = content -package = CCK +; $Id$ +name = FeedField +description = CCK field to add an aggregation feed +dependencies[] = content +dependencies[] = aggregator +package = CCK +core = 6.x Index: feedfield.install =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/feedfield/feedfield.install,v retrieving revision 1.1 diff -u -p -r1.1 feedfield.install --- feedfield.install 30 Nov 2006 14:48:13 -0000 1.1 +++ feedfield.install 5 Jan 2010 22:14:42 -0000 @@ -1,48 +1,37 @@ = 0), - vid integer NOT NULL default '0' CHECK (nid >= 0), - field_name varchar(32) NOT NULL default '', - delta integer NOT NULL default '0' CHECK (nid >= 0), - field_title varchar(255) NOT NULL default '', - field_url varchar(255) NOT NULL default '', - field_fid integer NOT NULL default '0' CHECK (nid >= 0), - field_type varchar(32) NOT NULL default '', - PRIMARY KEY (vid,field_name,delta) - )"); - break; - } + drupal_load('module', 'content'); + content_notify('install', 'feedfield'); +} + +/** +* Implementation of hook_uninstall(). +*/ +function feedfield_uninstall() { + drupal_load('module', 'content'); + content_notify('uninstall', 'feedfield'); +} + +/** +* Implementation of hook_enable(). +*/ +function feedfield_enable() { + drupal_load('module', 'content'); + content_notify('enable', 'feedfield'); +} + +/** +* Implementation of hook_disable(). +*/ +function feedfield_disable() { + drupal_load('module', 'content'); + content_notify('disable', 'feedfield'); } -function feedfield_update_1(){ - $items[]=update_sql("ALTER TABLE {node_field_feedfield_data} ADD `field_type` VARCHAR( 32 ) NOT NULL default ''"); - return $items; -} - -function feedfield_update_2(){ - $items[]=update_sql("ALTER TABLE {node_field_feedfield_data} ADD field_title varchar(255) NOT NULL default ''"); - return $items; -} \ No newline at end of file Index: feedfield.module =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/feedfield/feedfield.module,v retrieving revision 1.4 diff -u -p -r1.4 feedfield.module --- feedfield.module 17 May 2007 14:27:32 -0000 1.4 +++ feedfield.module 5 Jan 2010 22:14:42 -0000 @@ -1,121 +1,217 @@ array( + 'arguments' => array('element' => NULL), + ), + 'feedfield_formatter_default' => array( + 'arguments' => array('element' => NULL), + ), + ); +} /** * Implementation of hook_field_info(). + * + * Here we indicate that the content module will use its default + * handling for the view of this field. + * + * Callbacks can be omitted if default handing is used. + * They're included here just so this module can be used + * as an example for custom modules that might do things + * differently. */ function feedfield_field_info() { return array( - 'feedfield' => array('label' => 'Feed'), - ); + 'feedfield' => array( + 'label' => t('Feed'), + 'description' => t('Create aggregator feed'), + 'callbacks' => array( + 'tables' => CONTENT_CALLBACK_DEFAULT, + 'arguments' => CONTENT_CALLBACK_DEFAULT, + ), + ), + ); +} + +/** + * Implementation of hook_field_settings(). + */ +function feedfield_field_settings($op, $field) { + switch ($op) { + case 'form': + $form = array(); + $form['categories_fieldset'] = array( + '#type' => 'fieldset', + '#title' => t('Force Categories'), + '#collapsible' => TRUE, + '#collapsed' => empty($field['force_categories']) + ); + + $form['categories_fieldset']['force_categories'] = array( + '#type' => 'checkbox', + '#title' => t('Force Feed Categories'), + '#default_value' => $field['force_categories'], + '#description' => t('If checked, users will not have the option to + select the feed\'s categories, and it will automatically be put in the + category chosen below.'), + ); + + $form['categories_fieldset']['categories'] = array( + '#type' => 'checkboxes', + '#options' => aggregation_get_all_feed_categories(), + '#default_value' => !empty($field['categories']) ? + $field['categories'] : array(NULL) + ); + $form['refresh_fieldset'] = array( + '#type' => 'fieldset', + '#title' => t('Force Refesh Interval'), + '#collapsible' => TRUE, + '#collapsed' => empty($field['force_refresh']) + ); + + $form['refresh_fieldset']['force_refresh'] = array( + '#type' => 'checkbox', + '#title' => t('Force Feed Refresh Interval'), + '#default_value' => $field['force_refresh'], + '#description' => t('If checked, users will not have the option to + select the feed\'s refresh interval, and it will + automatically be set to the value chosen below.'), + ); + + $form['refresh_fieldset']['refresh'] = array( + '#type' => 'select', + '#options' => aggregation_get_allowed_refresh_intervals(), + '#default_value' => isset($field['refresh']) ? + $field['refresh'] : 3600 + ); + + $form['force_title'] = array( + '#type' => 'checkbox', + '#title' => t('Force Feed Title To Node Title'), + '#default_value' => $field['force_title'], + '#description' => t('If checked, users will not have the option to + select the feed\'s title, and it will + automatically be set to the node\'s title.') + ); + return $form; + + case 'save': + return array('force_categories', 'categories', 'force_refresh', + 'refresh', 'force_title'); + + case 'database columns': + return array( + /* Only need to store fid, everything else will be stored by Aggregator. + * content_type_* will only serve as a junction table to link feeds + * to node versions. + */ + 'fid' => array('type' => 'int'), + ); + + } } + /** * Implementation of hook_field(). */ function feedfield_field($op, &$node, $field, &$node_field, $teaser, $page) { switch ($op) { - case 'load': - switch($field['type']) { - case 'feedfield': - $result = db_query("SELECT field_url, field_fid, field_type,field_title FROM {node_field_feedfield_data} WHERE vid = %d AND field_name = '%s' ORDER BY delta", $node->vid, $field['field_name']); - while ($value = db_fetch_array($result)) { - // load the feed details from the aggregator in case they have been modified there - $feed=aggregation_get_feed_by_id($value['field_fid']); - $values[] = array('value' => array( - 'feed' => $feed['url'], - 'fid' => $value['field_fid'], - 'type'=>$value['field_type'], - 'title'=>$feed['title'])); - } - $additions = array($field['field_name'] => $values); - break; + + case 'presave': + foreach ($node_field as $delta => &$item) { + if(!empty($field['force_title'])) { + $item['title'] = $node->title; + } } - return $additions; + break; - case 'view': - foreach ($node_field as $delta => $item) { - $node_field[$delta]['view'] = _feedfield_field_view($field, $item['value'], $item, $node); + case 'load': + if ($field['type'] == 'feedfield') { + return _add_values_on_load($node_field); } - return theme('field', $node, $field, $node_field, $teaser, $page); + break; + case 'insert': - switch($field['type']) { - case 'feedfield': - foreach ($node_field as $delta => $item) { - if ($item['value']['feed']) { - // we have a feed url - // You might want to force specific titles, so we pass the title through a theme function - $title=theme('feedfield_title',$node,$field,$item); - - if ($fid=aggregation_sync_feed($title, $item['value']['feed'])) { - // set categories - if (is_array($item['value']['category'])) { - foreach ($item['value']['category'] as $cid => $set) { - // convert categories from option list to value list - if ($set) $feed_categories[]=$cid; - } - } - aggregation_set_feed_categories($fid,$feed_categories); - - // If we have a new feed ID, then we are going to need to remove the old feed - if (($item['value']['fid']) and ($item['value']['fid'] != $fid)) { - aggregation_remove_feed_items($item['value']['fid']); - aggregation_delete_feed($item['value']['fid']); - } - } - // and now insert into our own table - db_query("INSERT INTO {node_field_feedfield_data} (nid, vid, field_name, delta, field_url,field_fid,field_type,field_title) VALUES (%d, %d, '%s', %d, '%s',%d,'%s','%s')", $node->nid, $node->vid, $field['field_name'], $delta, $item['value']['feed'],$fid,$item['value']['type'],$title); - } elseif ($item['value']['fid']) { - // no feed, but a feed id, that means we have to remove this feed - aggregation_remove_feed_items($item['value']['fid']); - aggregation_delete_feed($item['value']['fid']); + if ($field['type'] == 'feedfield') { + foreach ($node_field as $delta => &$item) { + if (!empty($item['feed'])) { + $new_fid = aggregation_sync_feed($item['title'], $item['feed']); + // we have a feed url + if ($new_fid != -1) { + aggregation_set_refresh_interval($new_fid, $item['refresh']); + if (is_array($item['categories'])) { + _set_categories($item['categories'], $new_fid); + } + /* If we have a new feed ID, then we are going to need to remove + * the old feed + */ + if (!is_null($item['fid']) && $item['fid'] != $new_fid) { + _remove_feed($item['fid']); + } } + // and now set the variable to have cck save it to the database. + $item['fid'] = $new_fid; + } elseif ($item['fid']) { + // no feed, but a feed id, that means we have to remove this feed + _remove_feed($item['fid']); } - break; + } } - return; + break; case 'update': // Delete and insert, rather than update, in case a field was added. - switch($field['type']) { - case 'feedfield': - db_query("DELETE FROM {node_field_feedfield_data} WHERE vid = %d AND field_name = '%s'", $node->vid, $field['field_name']); - feedfield_field('insert', $node, $field, $node_field, $teaser, $page); - break; + if ($field['type'] == 'feedfield') { + + feedfield_field('insert', $node, $field, $node_field, $teaser, $page); } - return; + break; case 'delete': // Delete using nid rather than vid to purge all revisions. - switch($field['type']) { - case 'feedfield': - // remove all linked feeds - foreach ($node_field as $delta => $item) { - if ($item['value']['fid']) { - aggregation_remove_feed_items($item['value']['fid']); - aggregation_delete_feed($item['value']['fid']); - } - } - db_query("DELETE FROM {node_field_feedfield_data} WHERE nid = %d AND field_name = '%s'", $node->nid, $field['field_name']); - break; + if ($field['type'] == 'feedfield') { + + // remove all linked feeds + foreach ($node_field as $delta => $item) { + if ($item['value']['fid']) { + _remove_feed($item['value']['fid']); + } + } } - return; + break; + } } +/** + * Implementation of hook_content_is_empty(). + */ +function feedfield_content_is_empty($item, $field) { + if (empty($item['feed'])) { + return TRUE; + } + return FALSE; +} /** @@ -123,328 +219,197 @@ function feedfield_field($op, &$node, $f */ function feedfield_widget_info() { return array( - 'feedfield' => array( - 'label' => 'Aggregator Feed', - 'field types' => array('feedfield'), - ), - ); + 'feedfield' => array( + 'label' => 'Aggregator Feed', + 'field types' => array('feedfield'), + 'multiple values' => CONTENT_HANDLE_CORE, + 'callbacks' => array( + 'default value' => CONTENT_CALLBACK_DEFAULT, + ), + ), + ); } /** * Implementation of hook_widget(). */ -function feedfield_widget($op, &$node, $field, &$node_field) { - switch ($op) { - case 'form': - $form = array(); - $form[$field['field_name']] = array('#tree' => TRUE,'#type'=>'fieldset','#title'=>$field['widget']['label']); +function feedfield_widget(&$form, &$form_state, $field, $items, $delta = 0) { - if ($field['multiple']) { - // Generate more fields if necessary on preview - if ($_POST['edit'][$field['field_name']]) { - $node_field = $_POST['edit'][$field['field_name']]; - } - $delta = 0; - // Render feedfield fields for all the entered values - foreach ($node_field as $data) { - if ($data['value']['feed']) { - $form[$field['field_name']][$delta]=array('#tree' => TRUE,'#type'=>'fieldset'); - _feedfield_widget_form($form[$field['field_name']][$delta], $field, $data, $delta); - - $delta++; - } - } - // Render two additional new feedfield fields - foreach (range($delta, $delta + 1) as $delta) { - $form[$field['field_name']][$delta]=array('#tree' => TRUE,'#type'=>'fieldset'); - _feedfield_widget_form($form[$field['field_name']][$delta], $field, $node_field, $delta); - } - } // end if multiple - else { - // Convert an old 'single' value field into the new array based format - if ($node_field['value']) { - $node_field[0]['value'] = $node_field['value']; - unset($node_field['value']); - } - _feedfield_widget_form($form[$field['field_name']][0], $field, $node_field[0]); - } - - return $form; + $element = array( + '#type' => $field['widget']['type'], + '#default_value' => isset($items[$delta]) ? $items[$delta] : '', + ); + return $element; +} - case 'validate': - foreach($node_field as $delta => $value) { - if ($value['value']['feed']) { - // Validate the feedfield - if (!feedfield_validate_link($value['value']['feed'])) { - form_set_error($field['field_name'] .']['. $delta. '][value][feed', t('Not a valid URL.')); - } elseif ($existing_feed=aggregation_get_feed_by_url($value['value']['feed'])) { - //url's must be unique - if ($value['value']['fid']!=$existing_feed['fid']) { - form_set_error($field['field_name'] .']['. $delta. '][value][feed', t('This feed already exists in the aggregator.')); - } - } elseif ($existing_feed=aggregation_get_feed_by_title($value['value']['title'])){ - // Titles must be unique - if ($value['value']['fid']!=$existing_feed['fid']) { - form_set_error($field['field_name'] .']['. $delta. '][value][title', t('A feed already exists with this title.')); - } - } - } - } - return; - - case 'process form values': - foreach($node_field as $delta => $value) { - //_feedfield_widget_process($node_field[$delta],$delta); - } - return; - - case 'submit': - return; - } +/** + * Implementation of FAPI hook_elements(). + */ +function feedfield_elements() { + return array( + 'feedfield' => array( + '#input' => TRUE, + '#columns' => array('title', 'feed', 'categories', 'refresh', 'fid'), + '#process' => array('feedfield_process'), + ), + ); } +/** + * Process the link type element before displaying the field. + */ +function feedfield_process($element, $edit, $form_state, $form) { + $field = $form['#field_info'][$element['#field_name']]; + $delta = $element['#delta']; + + if(empty($field['force_title'])) { + $element['title'] = array( + '#type' => 'textfield', + '#maxlength' => '255', + '#title' => t('Feed title'), + '#default_value' => isset($element['#value']['value']['title']) ? + $element['#value']['value']['title'] : $element['#value']['title'] + ); + } else { + $element['title'] = array( + '#type' => 'value', + '#value' => isset($element['#value']['value']['fid']) ? + $element['#value']['value']['fid'] : NULL + ); + } + $element['feed'] = array( + '#type' => 'textfield', + '#maxlength' => '255', + '#title' => t(' Feed URL'), + '#default_value' => isset($element['#value']['value']['feed']) ? + $element['#value']['value']['feed'] : $element['#value']['feed'], + '#required' => ($delta == 0) ? $field['required'] : FALSE, + ); + + if(empty($field['force_refresh'])) { + $element['refresh'] = array( + '#type' => 'select', + '#title' => t('Update interval'), + '#default_value' => isset($element['#value']['value']['refresh']) ? + $element['#value']['value']['refresh'] : + (isset($element['#value']['refresh']) ? $element['#value']['refresh'] : + 3600), + '#options' => aggregation_get_allowed_refresh_intervals() + ); + } else { + $element['refresh'] = array( + '#type' => 'value', + '#value' => $field['refresh'] + ); + } + if(empty($field['force_categories'])) { + $element['categories'] = array( + '#type' => 'checkboxes', + '#title' => t('Aggregator Categories'), + '#options' => aggregation_get_all_feed_categories(), + '#default_value' => !empty($element['#value']['value']['categories']) ? + $element['#value']['value']['categories'] : + (is_array($element['#value']['categories']) ? $element['#value']['categories'] : + array(NULL)) + ); + } else { + $element['categories'] = array( + '#type' => 'value', + '#value' => $field['categories'] + ); + } + $element['fid'] = array( + '#type' => 'value', + '#value' => isset($element['#value']['value']['fid']) ? + $element['#value']['value']['fid'] : NULL + ); + return $element; +} /** - * Helper function renders the feedfield widget in both single and multiple value cases. + * Implementation of hook_field_formatter_info(). */ - -function _feedfield_widget_form (&$form_item, $field, $node_field, $delta = 0) { - $form_item['value'] = array( - '#tree' => true, - '#weigth' => $field['widget']['weight'], - ); - - $form_item['value']['title'] = array( - '#type' => 'textfield', - '#maxlength' => '255', - '#title' => t('Feed title'), - '#default_value' => $node_field['value']['title'], - ); - - $options = array ( - 'news' => t('News/blog feed'), - 'wiki' => t('Wiki recent changes'), - ); - - $form_item['value']['type'] = array( - '#type' => 'select', - '#title' => t('Feed type'), - '#default_value' => isset($node_field['value']['type']) ? $node_field['value']['type'] : 'news', - '#options' => $options, - ); - - $form_item['value']['feed'] = array( - '#type' => 'textfield', - '#maxlength' => '255', - '#title' => t(' Feed URL'), - '#default_value' => $node_field['value']['feed'], - '#required' => ($delta == 0) ? $field['required'] : FALSE, - '#description' => $field['widget']['description'], - ); - - - $form_item['value']['category'] = array( - '#type' => 'checkboxes', - '#title' => t('Aggregator Categories'), - '#options' => aggregation_get_all_feed_categories(), - ); - ($node_field['value']['fid']) and $form_item['value']['category']['#default_value']=aggregation_get_assigned_feed_categories($node_field['value']['fid']); - - - $form_item['value']['fid'] = array( - '#type' => 'hidden', - '#value' => $node_field['value']['fid'], - ); -} - -/** - * Implementation of hook_field_view() which performs any translation necessary. - */ -function _feedfield_field_view($field, $value, $addlfields = array(), $node = NULL) { - $attributes = array(); - $output = l(strlen($value['feed']) > 80 ? substr($value['feed'],0,80)."..." : $value['feed'],feedfield_cleanup_url($value['feed']),$attributes); - return $output; -} - -/** - * Implementation of hook_views_tables(). - */ -function feedfield_views_tables() { - $tables = array(); - - $fields = content_fields(); - foreach ($fields as $field) { - if ($field['type'] == 'feedfield') { - $tables['node_field_feedfield_data_'. $field['field_name']] = array( - 'name' => 'node_field_feedfield_data', - 'join' => array( - 'left' => array( - 'table' => 'node', - 'field' => 'vid', - ), - 'right' => array( - 'field' => 'vid', - ), - 'extra' => array('field_name' => $field['field_name']), - ), - 'fields' => array( - 'field_url' => array( - 'name' => 'Feed URL: '. $field['widget']['label'], - 'sortable' => TRUE, - ), - 'field_title' => array( - 'name' => 'Feed title: '.$field['widget']['label'], - 'sortable' => TRUE, - ), - 'field_type' => array( - 'name' => 'Feed type: '. $field['widget']['label'], - 'sortable' => TRUE, - ), - ), - 'sorts' => array( - 'field_url' => array('name' => 'Feed URL: '. $field['widget']['label']), - 'field_title' => array('name' => 'Feed title: '. $field['widget']['label']), - 'field_type' => array('name' => 'Feed type: '. $field['widget']['label']), - ), - 'filters' => array( - 'field_url' => array( - 'name' => 'Feed URL: '. $field['widget']['label'], - 'operator' => array( - '=' => 'is', - 'contains' => 'contains', - 'begins' => 'begins with', - 'ends' => 'ends wth', - 'LIKE' => 'matches pattern', - ), - 'operator-handler' => '_text_filter_operator', - ), - 'field_title' => array( - 'name' => 'Feed title: '. $field['widget']['label'], - 'operator' => array( - '=' => 'is', - 'contains' => 'contains', - 'begins' => 'begins with', - 'ends' => 'ends wth', - 'LIKE' => 'matches pattern', - ), - 'operator-handler' => '_text_filter_operator', - ), - 'field_type' => array( - 'name' => 'Feed type: '. $field['widget']['label'], - 'operator' => "views_handler_operator_eqneq", - 'list' => array('news'=>'news','wiki'=>'wiki'), - ), +function feedfield_field_formatter_info() { + return array( + 'default' => array( + 'label' => t('Display Aggregator Block (default)'), + 'field types' => array('feedfield'), + 'multiple values' => CONTENT_HANDLE_CORE, ), ); - } - } - - return $tables; } /** - * Forms a valid URL if possible from an entered address. - * Trims whitespace and automatically adds an http:// to addresses without a protocol specified - * - * @param string $url - * @param string $protocol The protocol to be prepended to the url if one is not specified + * FAPI theme for an individual text elements. */ -function feedfield_cleanup_url ($url, $protocol = "http") { - $url = trim($url); - - // Check if there is no protocol specified - $protocol_match = preg_match("/^([a-z0-9][a-z0-9\.\-_]*:\/\/)/i",$url); - if (empty($protocol_match)) { - // But should it be? Add an automatic http:// if it starts with a domain name - $domain_match = preg_match('/^(([a-z0-9]([a-z0-9\-_]*\.)+)(aero|arpa|biz|com|coop|edu|gov|info|int|jobs|mil|museum|name|nato|net|org|pro|travel|[a-z]{2}))/i',$url); - if (!empty($domain_match)) { - $url = $protocol."://".$url; - } - } - - return $url; +function theme_feedfield($element) { + return $element['#children']; } /** - * A lenient verification for URLs. Accepts all URLs following RFC 1738 standard for URL formation. - * - * @param string $text - * @return mixed Returns boolean FALSE if the URL is not valid. On success, returns an object with - * the following attributes: protocol, hostname, ip, and port. - */ -function feedfield_validate_link($text) { - if (!preg_match( - // protocol - '/^([a-z0-9][a-z0-9\.\-_]*:\/\/)?'. - '('. - // domains - '(([a-z0-9]([a-z0-9\-_]*\.)+)(aero|arpa|biz|com|coop|edu|gov|info|int|jobs|mil|museum|name|nato|net|org|pro|travel|[a-z]{2}))'. - // OR ip addresses - '|(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})'. - ')'. - // port number - '(:([0-9]{1,4}))?'. - // the rest of the path - "(\/[a-z0-9_\-\.~+%=&,$'():;*@]+)*". - // anchors - "\/?#?[a-z0-9_\-\.~+%=&,$'():;*@]*". - // the query string - "(\/?\?[a-z0-9+_\-\.\/%=&,$'():;*@]*)?". - // forward slash 0 or 1 times - '(\/)?'. - // end of the expression, case insensitive - '$/i', $text, $m)) { - return false; - } - else { - $url = new stdClass(); - $url->protocol = $m[2]; - $url->hostname = strtolower($m[5]).strtolower($m[7]); - $url->ip = $m[8]; - $url->port = $m[10]; - return $url; - } + * Theme function for default formatter. This is just a quick and dirty way of + * showing feeds with the existing aggregator_block method. + */ +function theme_feedfield_formatter_default($element) { + $fid = 'feed-'.$element['#item']['value']['fid']; + $show = aggregator_block('view', $fid); + return $show['content']; } +/////// "private" helper functions //////// + /** - * Implementation of hook_block. - * + * Helper function to add values to the node when the node is loaded. Gets the values from the + * aggregator tables. + * + * @param $node_field Array of field items. */ -function feedfield_block($op = 'list', $delta = 0, $edit = array()) { - switch ($op){ - case 'list': - $fields=content_fields(); - if (is_array($fields)) { - foreach($fields as $field) { - if ($field['type']=='feedfield') { - $blocks[$field['field_name']]['info']=t("Feed for current node's @name feedfield",array('@name'=>$field['field_name'])); - } - } - } - return $blocks; - break; - case 'view': - if (arg(0)=='node' && is_numeric(arg(1))) { - $node=node_load(arg(1)); - $feeds=$node->$delta; - return aggregator_block('view', 'feed-'.$feeds[0]['value']['fid']); - } - break; +function _add_values_on_load($node_field) { + foreach ($node_field as $key => $item) { + $feed=aggregation_get_feed_by_id($node_field[$key]['fid']); + $categories = + aggregation_get_assigned_feed_categories($node_field[$key]['fid']); + $values[] = array( + 'value' => array( + 'title'=> $feed['title'], + 'feed' => $feed['url'], + 'refresh' => $feed['refresh'], + 'categories' => $categories, + 'fid' => $feed['fid'] + ) + ); } + + $additions = array($field['field_name'] => $values); + + return $additions; } +/** + * Helper function to set a feed's categories. + * + * @param $categories Array of category cid's the feed should be + * associated with. + * @param $fid The feed's fid that should be associated with the categories. + */ +function _set_categories($categories, $fid) { + foreach ($categories as $cid => $set) { + // convert categories from option list to value list + if ($set) $feed_categories[]=$cid; + } + aggregation_set_feed_categories($new_fid, $feed_categories); +} /** - * Theme the way a feed title is displayed + * Just removes all feed items of a feed, then deletes the feed. * - * @return string with formatted title + * @param The feed that will be deleted. */ -function theme_feedfield_title($node,$field,$item) { - if (!$result=$item['value']['title']) { - $result= $node->title.' ('.$item['value']['type'].')'; - } - return $result; -} \ No newline at end of file +function _remove_feed($fid) { + aggregation_remove_feed_items($fid); + aggregation_delete_feed($fid); +} + Index: feedfield.test =================================================================== RCS file: feedfield.test diff -N feedfield.test --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ feedfield.test 5 Jan 2010 22:14:42 -0000 @@ -0,0 +1,136 @@ + 'aggregation_api', + 'description' => 'Tests the aggregation_api file. Ensures that all + functions function correctly', + 'group' => 'FeedField', + ); + } + + public function setUp() { + parent::setUp('aggregator'); // Enable any modules required for the test + // include the aggregation_api file + include_once('aggregation_api.inc'); + // Create and log in our user + $privileged_user = $this->drupalCreateUser(array('access news feeds', 'administer news feeds')); + $this->drupalLogin($privileged_user); + } + + /** + * Tests aggregation_api's aggregation_sync_feed function and helper + * functions. + */ + public function testAggregationSyncFeed() { + //Add a feed using aggregation's form + $url = 'http://feeds.wired.com/wired/index'; + $title = 'newFeed'; + + // Feed doesn't exist, so it should be inserted + $feedId = aggregation_sync_feed($title, $url); + // Function should return the fid of the feed that was just inserted + $this->assertNotNull($feedId); + // Function should not return -1. -1 means there was a conflict + $this->assertNotEqual($feedId, -1); + $feedId2 = aggregation_sync_feed($title, $url); + // Feed exists. Function should have returned the same fid + $this->assertEqual($feedId, $feedId2); + $title2 = $this->randomName(8); + $feedId = aggregation_sync_feed($title2, $url); + // Should have just updated the feed, so the feedId's should be the same + $this->assertEqual($feedId, $feedId2); + // Ensures that the name was changed + $this->assertEqual($feedId2, aggregation_sync_feed($title2, $url)); + $url2 = 'http://rss.slashdot.org/slashdot/eqWf'; + $feedId2 = aggregation_sync_feed($title2, $url2); + // Should have just updated the feed, so the feedId's should be the same + $this->assertEqual($feedId, $feedId2); + // Ensures that the name was changed + $this->assertEqual($feedId2, aggregation_sync_feed($title, $url2)); + } + + /** + * Tests aggregation_api's catogory functions. + */ + public function testAggregationCatagory() { + $edit = array(); + $edit['title'] = 'category1'; + $edit['description'] = $this->randomName(50); + + $this->drupalPost('admin/content/aggregator/add/category', $edit, t('Save')); + $this->assertText(t('The category @title has been added.', array('@title' => $edit['title']))); + + $edit['title'] = 'category2'; + $edit['description'] = $this->randomName(50); + + $this->drupalPost('admin/content/aggregator/add/category', $edit, t('Save')); + $this->assertText(t('The category @title has been added.', array('@title' => $edit['title']))); + + $edit['title'] = 'category3'; + $edit['description'] = $this->randomName(50); + + $this->drupalPost('admin/content/aggregator/add/category', $edit, t('Save')); + $this->assertText(t('The category @title has been added.', array('@title' => $edit['title']))); + + $categories = aggregation_get_all_feed_categories(); + $ctr = 1; + foreach ($categories as $cid => $title) + { + $this->assertEqual($title, 'category'.$ctr); + ++$ctr; + } + + $url = 'http://feeds.wired.com/wired/index'; + $title = 'newFeed'; + + $fid = aggregation_sync_feed($title, $url); + + $tmpCategories = $categories; + array_pop($tmpCategories); + aggregation_set_feed_categories($fid, array_keys($tmpCategories)); + $this->assertEqual(aggregation_get_assigned_feed_categories($fid), array_keys($tmpCategories)); + + $url2 = 'http://rss.slashdot.org/slashdot/eqWf'; + $title2 = 'newerFeed'; + + $fid2 = aggregation_sync_feed($title2, $url2); + + aggregation_set_feed_categories($fid2, array_keys($categories)); + $this->assertEqual(aggregation_get_assigned_feed_categories($fid2), array_keys($categories)); + $this->assertEqual(aggregation_get_assigned_feed_categories($fid), array_keys($tmpCategories)); + + $this->assertEqual(aggregation_get_all_feed_categories(), $categories); + + } + + /** + * Tests aggregation_api's refresh functions. + * aggregation_get_allowed_refresh_intervals is left untested due to the + * simplicity of that function. + */ + public function testAggregationRefresh() { + $url = 'http://rss.cnn.com/rss/cnn_mostpopular.rss'; + $title = 'newFeed'; + $fid = aggregation_sync_feed($title, $url); + + $url2 = 'http://online.wsj.com/xml/rss/3_7011.xml'; + $title2 = 'newFeed2'; + $fid2 = aggregation_sync_feed($title2, $url2); + + aggregation_set_refresh_interval($fid, 10800); + aggregation_set_refresh_interval($fid2, 64800); + + $feed = aggregation_get_feed_by_id($fid); + $feed2 = aggregation_get_feed_by_id($fid2); + + $this->assertEqual($feed['refresh'], 10800); + $this->assertEqual($feed2['refresh'], 64800); + } + +} + +