first import
This commit is contained in:
95
sites/all/modules/feeds/tests/common_syndication_parser.test
Normal file
95
sites/all/modules/feeds/tests/common_syndication_parser.test
Normal file
@@ -0,0 +1,95 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Tests for the common syndication parser.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Test cases for common syndication parser library.
|
||||
*
|
||||
* @todo Break out into Drupal independent test framework.
|
||||
* @todo Could I use DrupalUnitTestCase here?
|
||||
*/
|
||||
class CommonSyndicationParserTestCase extends DrupalWebTestCase {
|
||||
public static function getInfo() {
|
||||
return array(
|
||||
'name' => 'Common Syndication Parser',
|
||||
'description' => 'Unit tests for Common Syndication Parser.',
|
||||
'group' => 'Feeds',
|
||||
);
|
||||
}
|
||||
|
||||
public function setUp() {
|
||||
parent::setUp(array('feeds', 'feeds_ui', 'ctools', 'job_scheduler'));
|
||||
feeds_include_library('common_syndication_parser.inc', 'common_syndication_parser');
|
||||
}
|
||||
|
||||
/**
|
||||
* Dispatch tests, only use one entry point method testX to save time.
|
||||
*/
|
||||
public function test() {
|
||||
$this->_testRSS10();
|
||||
$this->_testRSS2();
|
||||
$this->_testAtomGeoRSS();
|
||||
}
|
||||
|
||||
/**
|
||||
* Test RSS 1.0.
|
||||
*/
|
||||
protected function _testRSS10() {
|
||||
$string = $this->readFeed('magento.rss1');
|
||||
$feed = common_syndication_parser_parse($string);
|
||||
$this->assertEqual($feed['title'], 'Magento Sites Network - A directory listing of Magento Commerce stores');
|
||||
$this->assertEqual($feed['items'][0]['title'], 'Gezondheidswebwinkel');
|
||||
$this->assertEqual($feed['items'][0]['url'], 'http://www.magentosites.net/store/2010/04/28/gezondheidswebwinkel/index.html');
|
||||
$this->assertEqual($feed['items'][1]['url'], 'http://www.magentosites.net/store/2010/04/26/mybobinocom/index.html');
|
||||
$this->assertEqual($feed['items'][1]['guid'], 'http://www.magentosites.net/node/3472');
|
||||
$this->assertEqual($feed['items'][2]['guid'], 'http://www.magentosites.net/node/3471');
|
||||
$this->assertEqual($feed['items'][2]['timestamp'], 1272285294);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test RSS 2.
|
||||
*/
|
||||
protected function _testRSS2() {
|
||||
$string = $this->readFeed('developmentseed.rss2');
|
||||
$feed = common_syndication_parser_parse($string);
|
||||
$this->assertEqual($feed['title'], 'Development Seed - Technological Solutions for Progressive Organizations');
|
||||
$this->assertEqual($feed['items'][0]['title'], 'Open Atrium Translation Workflow: Two Way Translation Updates');
|
||||
$this->assertEqual($feed['items'][1]['url'], 'http://developmentseed.org/blog/2009/oct/05/week-dc-tech-october-5th-edition');
|
||||
$this->assertEqual($feed['items'][1]['guid'], '973 at http://developmentseed.org');
|
||||
$this->assertEqual($feed['items'][2]['guid'], '972 at http://developmentseed.org');
|
||||
$this->assertEqual($feed['items'][2]['timestamp'], 1254493864);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test Geo RSS in Atom feed.
|
||||
*/
|
||||
protected function _testAtomGeoRSS() {
|
||||
$string = $this->readFeed('earthquake-georss.atom');
|
||||
$feed = common_syndication_parser_parse($string);
|
||||
$this->assertEqual($feed['title'], 'USGS M2.5+ Earthquakes');
|
||||
$this->assertEqual($feed['items'][0]['title'], 'M 2.6, Central Alaska');
|
||||
$this->assertEqual($feed['items'][1]['url'], 'http://earthquake.usgs.gov/earthquakes/recenteqsww/Quakes/us2010axbz.php');
|
||||
$this->assertEqual($feed['items'][1]['guid'], 'urn:earthquake-usgs-gov:us:2010axbz');
|
||||
$this->assertEqual($feed['items'][2]['guid'], 'urn:earthquake-usgs-gov:us:2010axbr');
|
||||
$this->assertEqual($feed['items'][2]['geolocations'][0]['name'], '-53.1979 -118.0676');
|
||||
$this->assertEqual($feed['items'][2]['geolocations'][0]['lat'], '-53.1979');
|
||||
$this->assertEqual($feed['items'][2]['geolocations'][0]['lon'], '-118.0676');
|
||||
$this->assertEqual($feed['items'][3]['geolocations'][0]['name'], '-43.4371 172.5902');
|
||||
$this->assertEqual($feed['items'][3]['geolocations'][0]['lat'], '-43.4371');
|
||||
$this->assertEqual($feed['items'][3]['geolocations'][0]['lon'], '172.5902');
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper to read a feed.
|
||||
*/
|
||||
protected function readFeed($filename) {
|
||||
$feed = dirname(__FILE__) . '/feeds/' . $filename;
|
||||
$handle = fopen($feed, 'r');
|
||||
$string = fread($handle, filesize($feed));
|
||||
fclose($handle);
|
||||
return $string;
|
||||
}
|
||||
}
|
674
sites/all/modules/feeds/tests/feeds.test
Normal file
674
sites/all/modules/feeds/tests/feeds.test
Normal file
@@ -0,0 +1,674 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Common functionality for all Feeds tests.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Test basic Data API functionality.
|
||||
*/
|
||||
class FeedsWebTestCase extends DrupalWebTestCase {
|
||||
protected $profile = 'testing';
|
||||
|
||||
public function setUp() {
|
||||
$args = func_get_args();
|
||||
|
||||
// Build the list of required modules which can be altered by passing in an
|
||||
// array of module names to setUp().
|
||||
if (isset($args[0])) {
|
||||
if (is_array($args[0])) {
|
||||
$modules = $args[0];
|
||||
}
|
||||
else {
|
||||
$modules = $args;
|
||||
}
|
||||
}
|
||||
else {
|
||||
$modules = array();
|
||||
}
|
||||
|
||||
$modules[] = 'taxonomy';
|
||||
$modules[] = 'image';
|
||||
$modules[] = 'file';
|
||||
$modules[] = 'field';
|
||||
$modules[] = 'field_ui';
|
||||
$modules[] = 'feeds';
|
||||
$modules[] = 'feeds_ui';
|
||||
$modules[] = 'feeds_tests';
|
||||
$modules[] = 'ctools';
|
||||
$modules[] = 'job_scheduler';
|
||||
$modules = array_unique($modules);
|
||||
parent::setUp($modules);
|
||||
|
||||
// Add text formats Directly.
|
||||
$filtered_html_format = array(
|
||||
'format' => 'filtered_html',
|
||||
'name' => 'Filtered HTML',
|
||||
'weight' => 0,
|
||||
'filters' => array(
|
||||
// URL filter.
|
||||
'filter_url' => array(
|
||||
'weight' => 0,
|
||||
'status' => 1,
|
||||
),
|
||||
// HTML filter.
|
||||
'filter_html' => array(
|
||||
'weight' => 1,
|
||||
'status' => 1,
|
||||
),
|
||||
// Line break filter.
|
||||
'filter_autop' => array(
|
||||
'weight' => 2,
|
||||
'status' => 1,
|
||||
),
|
||||
// HTML corrector filter.
|
||||
'filter_htmlcorrector' => array(
|
||||
'weight' => 10,
|
||||
'status' => 1,
|
||||
),
|
||||
),
|
||||
);
|
||||
$filtered_html_format = (object) $filtered_html_format;
|
||||
filter_format_save($filtered_html_format);
|
||||
|
||||
// Build the list of required administration permissions. Additional
|
||||
// permissions can be passed as an array into setUp()'s second parameter.
|
||||
if (isset($args[1]) && is_array($args[1])) {
|
||||
$permissions = $args[1];
|
||||
}
|
||||
else {
|
||||
$permissions = array();
|
||||
}
|
||||
|
||||
$permissions[] = 'access content';
|
||||
$permissions[] = 'administer site configuration';
|
||||
$permissions[] = 'administer content types';
|
||||
$permissions[] = 'administer nodes';
|
||||
$permissions[] = 'bypass node access';
|
||||
$permissions[] = 'administer taxonomy';
|
||||
$permissions[] = 'administer users';
|
||||
$permissions[] = 'administer feeds';
|
||||
|
||||
// Create an admin user and log in.
|
||||
$this->admin_user = $this->drupalCreateUser($permissions);
|
||||
$this->drupalLogin($this->admin_user);
|
||||
|
||||
$types = array(
|
||||
array(
|
||||
'type' => 'page',
|
||||
'name' => 'Basic page',
|
||||
'node_options[status]' => 1,
|
||||
'node_options[promote]' => 0,
|
||||
),
|
||||
array(
|
||||
'type' => 'article',
|
||||
'name' => 'Article',
|
||||
'node_options[status]' => 1,
|
||||
'node_options[promote]' => 1,
|
||||
),
|
||||
);
|
||||
foreach ($types as $type) {
|
||||
$this->drupalPost('admin/structure/types/add', $type, 'Save content type');
|
||||
$this->assertText("The content type " . $type['name'] . " has been added.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Absolute path to Drupal root.
|
||||
*/
|
||||
public function absolute() {
|
||||
return realpath(getcwd());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the absolute directory path of the feeds module.
|
||||
*/
|
||||
public function absolutePath() {
|
||||
return $this->absolute() . '/' . drupal_get_path('module', 'feeds');
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate an OPML test feed.
|
||||
*
|
||||
* The purpose of this function is to create a dynamic OPML feed that points
|
||||
* to feeds included in this test.
|
||||
*/
|
||||
public function generateOPML() {
|
||||
$path = $GLOBALS['base_url'] . '/' . drupal_get_path('module', 'feeds') . '/tests/feeds/';
|
||||
|
||||
$output =
|
||||
'<?xml version="1.0" encoding="utf-8"?>
|
||||
<opml version="1.1">
|
||||
<head>
|
||||
<title>Feeds test OPML</title>
|
||||
<dateCreated>Fri, 16 Oct 2009 02:53:17 GMT</dateCreated>
|
||||
<ownerName></ownerName>
|
||||
</head>
|
||||
<body>
|
||||
<outline text="Feeds test group" >
|
||||
<outline title="Development Seed - Technological Solutions for Progressive Organizations" text="" xmlUrl="' . $path . 'developmentseed.rss2" type="rss" />
|
||||
<outline title="Magyar Nemzet Online - H\'rek" text="" xmlUrl="' . $path . 'feed_without_guid.rss2" type="rss" />
|
||||
<outline title="Drupal planet" text="" type="rss" xmlUrl="' . $path . 'drupalplanet.rss2" />
|
||||
</outline>
|
||||
</body>
|
||||
</opml>';
|
||||
|
||||
// UTF 8 encode output string and write it to disk
|
||||
$output = utf8_encode($output);
|
||||
$filename = file_default_scheme() . '://test-opml-' . $this->randomName() . '.opml';
|
||||
|
||||
$filename = file_unmanaged_save_data($output, $filename);
|
||||
return $filename;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an importer configuration.
|
||||
*
|
||||
* @param $name
|
||||
* The natural name of the feed.
|
||||
* @param $id
|
||||
* The persistent id of the feed.
|
||||
* @param $edit
|
||||
* Optional array that defines the basic settings for the feed in a format
|
||||
* that can be posted to the feed's basic settings form.
|
||||
*/
|
||||
public function createImporterConfiguration($name = 'Syndication', $id = 'syndication') {
|
||||
// Create new feed configuration.
|
||||
$this->drupalGet('admin/structure/feeds');
|
||||
$this->clickLink('Add importer');
|
||||
$edit = array(
|
||||
'name' => $name,
|
||||
'id' => $id,
|
||||
);
|
||||
$this->drupalPost('admin/structure/feeds/create', $edit, 'Create');
|
||||
|
||||
// Assert message and presence of default plugins.
|
||||
$this->assertText('Your configuration has been created with default settings.');
|
||||
$this->assertPlugins($id, 'FeedsHTTPFetcher', 'FeedsSyndicationParser', 'FeedsNodeProcessor');
|
||||
// Per default attach to page content type.
|
||||
$this->setSettings($id, NULL, array('content_type' => 'page'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Choose a plugin for a importer configuration and assert it.
|
||||
*
|
||||
* @param $id
|
||||
* The importer configuration's id.
|
||||
* @param $plugin_key
|
||||
* The key string of the plugin to choose (one of the keys defined in
|
||||
* feeds_feeds_plugins()).
|
||||
*/
|
||||
public function setPlugin($id, $plugin_key) {
|
||||
if ($type = FeedsPlugin::typeOf($plugin_key)) {
|
||||
$edit = array(
|
||||
'plugin_key' => $plugin_key,
|
||||
);
|
||||
$this->drupalPost("admin/structure/feeds/$id/$type", $edit, 'Save');
|
||||
|
||||
// Assert actual configuration.
|
||||
$config = unserialize(db_query("SELECT config FROM {feeds_importer} WHERE id = :id", array(':id' => $id))->fetchField());
|
||||
$this->assertEqual($config[$type]['plugin_key'], $plugin_key, 'Verified correct ' . $type . ' (' . $plugin_key . ').');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set importer or plugin settings.
|
||||
*
|
||||
* @param $id
|
||||
* The importer configuration's id.
|
||||
* @param $plugin
|
||||
* The plugin (class) name, or NULL to set importer's settings
|
||||
* @param $settings
|
||||
* The settings to set.
|
||||
*/
|
||||
public function setSettings($id, $plugin, $settings) {
|
||||
$this->drupalPost('admin/structure/feeds/' . $id . '/settings/' . $plugin, $settings, 'Save');
|
||||
$this->assertText('Your changes have been saved.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a test feed node. Test user has to have sufficient permissions:
|
||||
*
|
||||
* * create [type] content
|
||||
* * use feeds
|
||||
*
|
||||
* Assumes that page content type has been configured with
|
||||
* createImporterConfiguration() as a feed content type.
|
||||
*
|
||||
* @return
|
||||
* The node id of the node created.
|
||||
*/
|
||||
public function createFeedNode($id = 'syndication', $feed_url = NULL, $title = '', $content_type = NULL) {
|
||||
if (empty($feed_url)) {
|
||||
$feed_url = $GLOBALS['base_url'] . '/' . drupal_get_path('module', 'feeds') . '/tests/feeds/developmentseed.rss2';
|
||||
}
|
||||
|
||||
// If content type not given, retrieve it.
|
||||
if (!$content_type) {
|
||||
$result= db_select('feeds_importer', 'f')
|
||||
->condition('f.id', $id, '=')
|
||||
->fields('f', array('config'))
|
||||
->execute();
|
||||
$config = unserialize($result->fetchField());
|
||||
$content_type = $config['content_type'];
|
||||
$this->assertFalse(empty($content_type), 'Valid content type found: ' . $content_type);
|
||||
}
|
||||
|
||||
// Create a feed node.
|
||||
$edit = array(
|
||||
'title' => $title,
|
||||
'feeds[FeedsHTTPFetcher][source]' => $feed_url,
|
||||
);
|
||||
$this->drupalPost('node/add/' . str_replace('_', '-', $content_type), $edit, 'Save');
|
||||
$this->assertText('has been created.');
|
||||
|
||||
// Get the node id from URL.
|
||||
$nid = $this->getNid($this->getUrl());
|
||||
|
||||
// Check whether feed got recorded in feeds_source table.
|
||||
$query = db_select('feeds_source', 's')
|
||||
->condition('s.id', $id, '=')
|
||||
->condition('s.feed_nid', $nid, '=');
|
||||
$query->addExpression("COUNT(*)");
|
||||
$result = $query->execute()->fetchField();
|
||||
$this->assertEqual(1, $result);
|
||||
|
||||
$source = db_select('feeds_source', 's')
|
||||
->condition('s.id', $id, '=')
|
||||
->condition('s.feed_nid', $nid, '=')
|
||||
->fields('s', array('config'))
|
||||
->execute()->fetchObject();
|
||||
$config = unserialize($source->config);
|
||||
$this->assertEqual($config['FeedsHTTPFetcher']['source'], $feed_url, t('URL in DB correct.'));
|
||||
return $nid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Edit the configuration of a feed node to test update behavior.
|
||||
*
|
||||
* @param $nid
|
||||
* The nid to edit.
|
||||
* @param $feed_url
|
||||
* The new (absolute) feed URL to use.
|
||||
* @param $title
|
||||
* Optional parameter to change title of feed node.
|
||||
*/
|
||||
public function editFeedNode($nid, $feed_url, $title = '') {
|
||||
$edit = array(
|
||||
'title' => $title,
|
||||
'feeds[FeedsHTTPFetcher][source]' => $feed_url,
|
||||
);
|
||||
// Check that the update was saved.
|
||||
$this->drupalPost('node/' . $nid . '/edit', $edit, 'Save');
|
||||
$this->assertText('has been updated.');
|
||||
|
||||
// Check that the URL was updated in the feeds_source table.
|
||||
$source = db_query("SELECT * FROM {feeds_source} WHERE feed_nid = :nid", array(':nid' => $nid))->fetchObject();
|
||||
$config = unserialize($source->config);
|
||||
$this->assertEqual($config['FeedsHTTPFetcher']['source'], $feed_url, t('URL in DB correct.'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Batch create a variable amount of feed nodes. All will have the
|
||||
* same URL configured.
|
||||
*
|
||||
* @return
|
||||
* An array of node ids of the nodes created.
|
||||
*/
|
||||
public function createFeedNodes($id = 'syndication', $num = 20, $content_type = NULL) {
|
||||
$nids = array();
|
||||
for ($i = 0; $i < $num; $i++) {
|
||||
$nids[] = $this->createFeedNode($id, NULL, $this->randomName(), $content_type);
|
||||
}
|
||||
return $nids;
|
||||
}
|
||||
|
||||
/**
|
||||
* Import a URL through the import form. Assumes FeedsHTTPFetcher in place.
|
||||
*/
|
||||
public function importURL($id, $feed_url = NULL) {
|
||||
if (empty($feed_url)) {
|
||||
$feed_url = $GLOBALS['base_url'] . '/' . drupal_get_path('module', 'feeds') . '/tests/feeds/developmentseed.rss2';
|
||||
}
|
||||
$edit = array(
|
||||
'feeds[FeedsHTTPFetcher][source]' => $feed_url,
|
||||
);
|
||||
$nid = $this->drupalPost('import/' . $id, $edit, 'Import');
|
||||
|
||||
// Check whether feed got recorded in feeds_source table.
|
||||
$this->assertEqual(1, db_query("SELECT COUNT(*) FROM {feeds_source} WHERE id = :id AND feed_nid = 0", array(':id' => $id))->fetchField());
|
||||
$source = db_query("SELECT * FROM {feeds_source} WHERE id = :id AND feed_nid = 0", array(':id' => $id))->fetchObject();
|
||||
$config = unserialize($source->config);
|
||||
$this->assertEqual($config['FeedsHTTPFetcher']['source'], $feed_url, t('URL in DB correct.'));
|
||||
|
||||
// Check whether feed got properly added to scheduler.
|
||||
$this->assertEqual(1, db_query("SELECT COUNT(*) FROM {job_schedule} WHERE type = :id AND id = 0 AND name = 'feeds_source_import' AND last <> 0 AND scheduled = 0", array(':id' => $id))->fetchField());
|
||||
// There must be only one entry for callback 'expire' - no matter what the feed_nid is.
|
||||
$this->assertEqual(0, db_query("SELECT COUNT(*) FROM {job_schedule} WHERE type = :id AND name = 'feeds_importer_expire' AND last <> 0 AND scheduled = 0", array(':id' => $id))->fetchField());
|
||||
}
|
||||
|
||||
/**
|
||||
* Import a file through the import form. Assumes FeedsFileFetcher in place.
|
||||
*/
|
||||
public function importFile($id, $file) {
|
||||
|
||||
$this->assertTrue(file_exists($file), 'Source file exists');
|
||||
$edit = array(
|
||||
'files[feeds]' => $file,
|
||||
);
|
||||
$this->drupalPost('import/' . $id, $edit, 'Import');
|
||||
}
|
||||
|
||||
/**
|
||||
* Assert a feeds configuration's plugins.
|
||||
*
|
||||
* @deprecated:
|
||||
* Use setPlugin() instead.
|
||||
*
|
||||
* @todo Refactor users of assertPlugin() and make them use setPugin() instead.
|
||||
*/
|
||||
public function assertPlugins($id, $fetcher, $parser, $processor) {
|
||||
// Assert actual configuration.
|
||||
$config = unserialize(db_query("SELECT config FROM {feeds_importer} WHERE id = :id", array(':id' => $id))->fetchField());
|
||||
|
||||
$this->assertEqual($config['fetcher']['plugin_key'], $fetcher, 'Correct fetcher');
|
||||
$this->assertEqual($config['parser']['plugin_key'], $parser, 'Correct parser');
|
||||
$this->assertEqual($config['processor']['plugin_key'], $processor, 'Correct processor');
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds mappings to a given configuration.
|
||||
*
|
||||
* @param string $id
|
||||
* ID of the importer.
|
||||
* @param array $mappings
|
||||
* An array of mapping arrays. Each mapping array must have a source and
|
||||
* an target key and can have a unique key.
|
||||
* @param bool $test_mappings
|
||||
* (optional) TRUE to automatically test mapping configs. Defaults to TRUE.
|
||||
*/
|
||||
public function addMappings($id, $mappings, $test_mappings = TRUE) {
|
||||
|
||||
$path = "admin/structure/feeds/$id/mapping";
|
||||
|
||||
// Iterate through all mappings and add the mapping via the form.
|
||||
foreach ($mappings as $i => $mapping) {
|
||||
|
||||
if ($test_mappings) {
|
||||
$current_mapping_key = $this->mappingExists($id, $i, $mapping['source'], $mapping['target']);
|
||||
$this->assertEqual($current_mapping_key, -1, 'Mapping does not exist before addition.');
|
||||
}
|
||||
|
||||
// Get unique flag and unset it. Otherwise, drupalPost will complain that
|
||||
// Split up config and mapping.
|
||||
$config = $mapping;
|
||||
unset($config['source'], $config['target']);
|
||||
$mapping = array('source' => $mapping['source'], 'target' => $mapping['target']);
|
||||
|
||||
// Add mapping.
|
||||
$this->drupalPost($path, $mapping, t('Add'));
|
||||
|
||||
// If there are other configuration options, set them.
|
||||
if ($config) {
|
||||
$this->drupalPostAJAX(NULL, array(), 'mapping_settings_edit_' . $i);
|
||||
|
||||
// Set some settings.
|
||||
$edit = array();
|
||||
foreach ($config as $key => $value) {
|
||||
$edit["config[$i][settings][$key]"] = $value;
|
||||
}
|
||||
$this->drupalPostAJAX(NULL, $edit, 'mapping_settings_update_' . $i);
|
||||
$this->drupalPost(NULL, array(), t('Save'));
|
||||
}
|
||||
|
||||
if ($test_mappings) {
|
||||
$current_mapping_key = $this->mappingExists($id, $i, $mapping['source'], $mapping['target']);
|
||||
$this->assertTrue($current_mapping_key >= 0, 'Mapping exists after addition.');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove mappings from a given configuration.
|
||||
*
|
||||
* This function mimicks the Javascript behavior in feeds_ui.js
|
||||
*
|
||||
* @param array $mappings
|
||||
* An array of mapping arrays. Each mapping array must have a source and
|
||||
* a target key and can have a unique key.
|
||||
* @param bool $test_mappings
|
||||
* (optional) TRUE to automatically test mapping configs. Defaults to TRUE.
|
||||
*/
|
||||
public function removeMappings($id, $mappings, $test_mappings = TRUE) {
|
||||
$path = "admin/structure/feeds/$id/mapping";
|
||||
|
||||
$current_mappings = $this->getCurrentMappings($id);
|
||||
|
||||
// Iterate through all mappings and remove via the form.
|
||||
foreach ($mappings as $i => $mapping) {
|
||||
|
||||
if ($test_mappings) {
|
||||
$current_mapping_key = $this->mappingExists($id, $i, $mapping['source'], $mapping['target']);
|
||||
$this->assertEqual($current_mapping_key, $i, 'Mapping exists before removal.');
|
||||
}
|
||||
|
||||
$remove_mapping = array("remove_flags[$i]" => 1);
|
||||
|
||||
$this->drupalPost($path, $remove_mapping, t('Save'));
|
||||
|
||||
$this->assertText('Your changes have been saved.');
|
||||
|
||||
if ($test_mappings) {
|
||||
$current_mapping_key = $this->mappingExists($id, $i, $mapping['source'], $mapping['target']);
|
||||
$this->assertEqual($current_mapping_key, -1, 'Mapping does not exist after removal.');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an array of current mappings from the feeds_importer config.
|
||||
*
|
||||
* @param string $id
|
||||
* ID of the importer.
|
||||
*
|
||||
* @return bool|array
|
||||
* FALSE if the importer has no mappings, or an an array of mappings.
|
||||
*/
|
||||
public function getCurrentMappings($id) {
|
||||
$config = db_query("SELECT config FROM {feeds_importer} WHERE id = :id", array(':id' => $id))->fetchField();
|
||||
|
||||
$config = unserialize($config);
|
||||
|
||||
// We are very specific here. 'mappings' can either be an array or not
|
||||
// exist.
|
||||
if (array_key_exists('mappings', $config['processor']['config'])) {
|
||||
$this->assertTrue(is_array($config['processor']['config']['mappings']), 'Mappings is an array.');
|
||||
|
||||
return $config['processor']['config']['mappings'];
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if a mapping exists for a given importer.
|
||||
*
|
||||
* @param string $id
|
||||
* ID of the importer.
|
||||
* @param integer $i
|
||||
* The key of the mapping.
|
||||
* @param string $source
|
||||
* The source field.
|
||||
* @param string $target
|
||||
* The target field.
|
||||
*
|
||||
* @return integer
|
||||
* -1 if the mapping doesn't exist, the key of the mapping otherwise.
|
||||
*/
|
||||
public function mappingExists($id, $i, $source, $target) {
|
||||
|
||||
$current_mappings = $this->getCurrentMappings($id);
|
||||
|
||||
if ($current_mappings) {
|
||||
foreach ($current_mappings as $key => $mapping) {
|
||||
if ($mapping['source'] == $source && $mapping['target'] == $target && $key == $i) {
|
||||
return $key;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function, retrieves node id from a URL.
|
||||
*/
|
||||
public function getNid($url) {
|
||||
$matches = array();
|
||||
preg_match('/node\/(\d+?)$/', $url, $matches);
|
||||
$nid = $matches[1];
|
||||
|
||||
// Test for actual integerness.
|
||||
$this->assertTrue($nid === (string) (int) $nid, 'Node id is an integer.');
|
||||
|
||||
return $nid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Copies a directory.
|
||||
*/
|
||||
public function copyDir($source, $dest) {
|
||||
$result = file_prepare_directory($dest, FILE_CREATE_DIRECTORY | FILE_MODIFY_PERMISSIONS);
|
||||
foreach (@scandir($source) as $file) {
|
||||
if (is_file("$source/$file")) {
|
||||
$file = file_unmanaged_copy("$source/$file", "$dest/$file");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Download and extract SimplePIE.
|
||||
*
|
||||
* Sets the 'feeds_simplepie_library_dir' variable to the directory where
|
||||
* SimplePie is downloaded.
|
||||
*/
|
||||
function downloadExtractSimplePie($version) {
|
||||
$url = "http://simplepie.org/downloads/simplepie_$version.mini.php";
|
||||
$filename = 'simplepie.mini.php';
|
||||
|
||||
// Avoid downloading the file dozens of times
|
||||
$library_dir = DRUPAL_ROOT . '/' . $this->originalFileDirectory . '/simpletest/feeds';
|
||||
$simplepie_library_dir = $library_dir . '/simplepie';
|
||||
|
||||
if (!file_exists($library_dir)) {
|
||||
drupal_mkdir($library_dir);
|
||||
}
|
||||
|
||||
if (!file_exists($simplepie_library_dir)) {
|
||||
drupal_mkdir($simplepie_library_dir);
|
||||
}
|
||||
|
||||
// Local file name.
|
||||
$local_file = $simplepie_library_dir . '/' . $filename;
|
||||
|
||||
// Begin single threaded code.
|
||||
if (function_exists('sem_get')) {
|
||||
$semaphore = sem_get(ftok(__FILE__, 1));
|
||||
sem_acquire($semaphore);
|
||||
}
|
||||
|
||||
// Download and extact the archive, but only in one thread.
|
||||
if (!file_exists($local_file)) {
|
||||
$local_file = system_retrieve_file($url, $local_file, FALSE, FILE_EXISTS_REPLACE);
|
||||
}
|
||||
|
||||
if (function_exists('sem_get')) {
|
||||
sem_release($semaphore);
|
||||
}
|
||||
// End single threaded code.
|
||||
|
||||
// Verify that files were successfully extracted.
|
||||
$this->assertTrue(file_exists($local_file), t('@file found.', array('@file' => $local_file)));
|
||||
|
||||
// Set the simpletest library directory.
|
||||
variable_set('feeds_library_dir', $library_dir);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides a wrapper for DrupalUnitTestCase for Feeds unit testing.
|
||||
*/
|
||||
class FeedsUnitTestHelper extends DrupalUnitTestCase {
|
||||
public function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
// Manually include the feeds module.
|
||||
// @todo Allow an array of modules from the child class.
|
||||
drupal_load('module', 'feeds');
|
||||
}
|
||||
}
|
||||
|
||||
class FeedsUnitTestCase extends FeedsUnitTestHelper {
|
||||
public static function getInfo() {
|
||||
return array(
|
||||
'name' => 'Unit tests',
|
||||
'description' => 'Test basic low-level Feeds module functionality.',
|
||||
'group' => 'Feeds',
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test valid absolute urls.
|
||||
*
|
||||
* @see ValidUrlTestCase
|
||||
*
|
||||
* @todo Remove when http://drupal.org/node/1191252 is fixed.
|
||||
*/
|
||||
function testFeedsValidURL() {
|
||||
$url_schemes = array('http', 'https', 'ftp', 'feed', 'webcal');
|
||||
$valid_absolute_urls = array(
|
||||
'example.com',
|
||||
'www.example.com',
|
||||
'ex-ample.com',
|
||||
'3xampl3.com',
|
||||
'example.com/paren(the)sis',
|
||||
'example.com/index.html#pagetop',
|
||||
'example.com:8080',
|
||||
'subdomain.example.com',
|
||||
'example.com/index.php?q=node',
|
||||
'example.com/index.php?q=node¶m=false',
|
||||
'user@www.example.com',
|
||||
'user:pass@www.example.com:8080/login.php?do=login&style=%23#pagetop',
|
||||
'127.0.0.1',
|
||||
'example.org?',
|
||||
'john%20doe:secret:foo@example.org/',
|
||||
'example.org/~,$\'*;',
|
||||
'caf%C3%A9.example.org',
|
||||
'[FEDC:BA98:7654:3210:FEDC:BA98:7654:3210]:80/index.html',
|
||||
'graph.asfdasdfasdf.com/blarg/feed?access_token=133283760145143|tGew8jbxi1ctfVlYh35CPYij1eE',
|
||||
);
|
||||
|
||||
foreach ($url_schemes as $scheme) {
|
||||
foreach ($valid_absolute_urls as $url) {
|
||||
$test_url = $scheme . '://' . $url;
|
||||
$valid_url = feeds_valid_url($test_url, TRUE);
|
||||
$this->assertTrue($valid_url, t('@url is a valid url.', array('@url' => $test_url)));
|
||||
}
|
||||
}
|
||||
|
||||
$invalid_ablosule_urls = array(
|
||||
'',
|
||||
'ex!ample.com',
|
||||
'ex%ample.com',
|
||||
);
|
||||
|
||||
foreach ($url_schemes as $scheme) {
|
||||
foreach ($invalid_ablosule_urls as $url) {
|
||||
$test_url = $scheme . '://' . $url;
|
||||
$valid_url = feeds_valid_url($test_url, TRUE);
|
||||
$this->assertFalse($valid_url, t('@url is NOT a valid url.', array('@url' => $test_url)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
BIN
sites/all/modules/feeds/tests/feeds/assets/attersee.jpeg
Normal file
BIN
sites/all/modules/feeds/tests/feeds/assets/attersee.jpeg
Normal file
Binary file not shown.
After Width: | Height: | Size: 223 KiB |
BIN
sites/all/modules/feeds/tests/feeds/assets/foosball.jpeg
Normal file
BIN
sites/all/modules/feeds/tests/feeds/assets/foosball.jpeg
Normal file
Binary file not shown.
After Width: | Height: | Size: 94 KiB |
BIN
sites/all/modules/feeds/tests/feeds/assets/hstreet.jpeg
Normal file
BIN
sites/all/modules/feeds/tests/feeds/assets/hstreet.jpeg
Normal file
Binary file not shown.
After Width: | Height: | Size: 92 KiB |
BIN
sites/all/modules/feeds/tests/feeds/assets/la fayette.jpeg
Normal file
BIN
sites/all/modules/feeds/tests/feeds/assets/la fayette.jpeg
Normal file
Binary file not shown.
After Width: | Height: | Size: 76 KiB |
BIN
sites/all/modules/feeds/tests/feeds/assets/tubing.jpeg
Normal file
BIN
sites/all/modules/feeds/tests/feeds/assets/tubing.jpeg
Normal file
Binary file not shown.
After Width: | Height: | Size: 112 KiB |
10
sites/all/modules/feeds/tests/feeds/batch/nodes1.csv
Normal file
10
sites/all/modules/feeds/tests/feeds/batch/nodes1.csv
Normal file
@@ -0,0 +1,10 @@
|
||||
Title,Body,published,GUID
|
||||
"Ut wisi enim ad minim veniam", "Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat.",205200720,2
|
||||
"Duis autem vel eum iriure dolor", "Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi.",428112720,3
|
||||
"Nam liber tempor", "Nam liber tempor cum soluta nobis eleifend option congue nihil imperdiet doming id quod mazim placerat facer possim assum.",1151766000,1
|
||||
Typi non habent"", "Typi non habent claritatem insitam; est usus legentis in iis qui facit eorum claritatem.",1256326995,4
|
||||
"Lorem ipsum","Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat.",1251936720,1
|
||||
"Investigationes demonstraverunt", "Investigationes demonstraverunt lectores legere me lius quod ii legunt saepius.",946702800,5
|
||||
"Claritas est etiam", "Claritas est etiam processus dynamicus, qui sequitur mutationem consuetudium lectorum.",438112720,6
|
||||
"Mirum est notare", "Mirum est notare quam littera gothica, quam nunc putamus parum claram, anteposuerit litterarum formas humanitatis per seacula quarta decima et quinta decima.",1151066000,7
|
||||
"Eodem modo typi", "Eodem modo typi, qui nunc nobis videntur parum clari, fiant sollemnes in futurum.",1201936720,8
|
Can't render this file because it contains an unexpected character in line 5 and column 16.
|
3
sites/all/modules/feeds/tests/feeds/batch/nodes2.csv
Normal file
3
sites/all/modules/feeds/tests/feeds/batch/nodes2.csv
Normal file
@@ -0,0 +1,3 @@
|
||||
Title,Body,published,GUID
|
||||
"Duis autem vel eum iriure dolor", "Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi.",428112720,3
|
||||
"Nam liber tempor", "Nam liber tempor cum soluta nobis eleifend option congue nihil imperdiet doming id quod mazim placerat facer possim assum.",1151766000,1
|
|
4
sites/all/modules/feeds/tests/feeds/batch/nodes3.csv
Normal file
4
sites/all/modules/feeds/tests/feeds/batch/nodes3.csv
Normal file
@@ -0,0 +1,4 @@
|
||||
Title,Body,published,GUID
|
||||
"Typi non habent", "Typi non habent claritatem insitam; est usus legentis in iis qui facit eorum claritatem.",1256326995,4
|
||||
"Lorem ipsum","Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat.",1251936720,1
|
||||
"Investigationes demonstraverunt", "Investigationes demonstraverunt lectores legere me lius quod ii legunt saepius.",946702800,5
|
|
3
sites/all/modules/feeds/tests/feeds/batch/nodes4.csv
Normal file
3
sites/all/modules/feeds/tests/feeds/batch/nodes4.csv
Normal file
@@ -0,0 +1,3 @@
|
||||
Title,Body,published,GUID
|
||||
"Investigationes demonstraverunt", "Investigationes demonstraverunt lectores legere me lius quod ii legunt saepius.",946702800,5
|
||||
"Claritas est etiam", "Claritas est etiam processus dynamicus, qui sequitur mutationem consuetudium lectorum.",438112720,6
|
|
3
sites/all/modules/feeds/tests/feeds/batch/nodes5.csv
Normal file
3
sites/all/modules/feeds/tests/feeds/batch/nodes5.csv
Normal file
@@ -0,0 +1,3 @@
|
||||
Title,Body,published,GUID
|
||||
"Mirum est notare", "Mirum est notare quam littera gothica, quam nunc putamus parum claram, anteposuerit litterarum formas humanitatis per seacula quarta decima et quinta decima.",1151066000,7
|
||||
"Eodem modo typi", "Eodem modo typi, qui nunc nobis videntur parum clari, fiant sollemnes in futurum.",1201936720,8
|
|
3
sites/all/modules/feeds/tests/feeds/content.csv
Normal file
3
sites/all/modules/feeds/tests/feeds/content.csv
Normal file
@@ -0,0 +1,3 @@
|
||||
"guid","title","created","alpha","beta","gamma","delta","body"
|
||||
1,"Lorem ipsum",1251936720,"Lorem",42,"4.2",3.14159265,"Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat."
|
||||
2,"Ut wisi enim ad minim veniam",1251932360,"Ut wisi",32,"1.2",5.62951413,"Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat."
|
|
299
sites/all/modules/feeds/tests/feeds/developmentseed.rss2
Normal file
299
sites/all/modules/feeds/tests/feeds/developmentseed.rss2
Normal file
@@ -0,0 +1,299 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?><rss version="2.0" xml:base="http://developmentseed.org/blog/all" xmlns:dc="http://purl.org/dc/elements/1.1/">
|
||||
<channel>
|
||||
<title>Development Seed - Technological Solutions for Progressive Organizations</title>
|
||||
<link>http://developmentseed.org/blog/all</link>
|
||||
<description></description>
|
||||
<language>en</language>
|
||||
<item>
|
||||
<title>Open Atrium Translation Workflow: Two Way Translation Updates</title>
|
||||
<link>http://developmentseed.org/blog/2009/oct/06/open-atrium-translation-workflow-two-way-updating</link>
|
||||
<description><div class="field field-type-text field-field-subtitle">
|
||||
<div class="field-items">
|
||||
<div class="field-item odd">
|
||||
<p>A new translation process for Open Atrium & integration with Localize Drupal</p> </div>
|
||||
</div>
|
||||
</div>
|
||||
<div class='node-body'><p>The <a href="http://openatrium.com/">Open Atrium</a> <a href="http://developmentseed.org/blog/2009/jul/16/open-atrium-solving-translation-puzzle">translation infrastructure</a> (and Drupal translations in general) are progressing quickly. For Open Atrium to be well translated we first need Drupal's modules to be translated, so I am splitting efforts at the moment between helping with <a href="http://localize.drupal.org">Localize Drupal</a> and improving <a href="https://translate.openatrium.com">Open Atrium Translate</a>. Already, it is much easier to automatically download your language, get updates from a translation server, protect locally translated strings, and scale the translation system so that translation servers can talk to each other.</p>
|
||||
|
||||
<h1>Automatically download your language</h1>
|
||||
|
||||
<p><img src="http://farm3.static.flickr.com/2496/3984689117_57559c74eb.jpg" alt="Magical translation install" /></p>
|
||||
|
||||
<p>For more than a month now you have been able to install Open Atrium, select one of its 20+ languages, and have the translation automatically downloaded and installed on your site. While this has been working for awhile now, we are still refining the process. One change we've already made is that now translations are downloaded in multiple smaller packages, rather than a single large one.</p>
|
||||
|
||||
<p>Once your translation is installed, you can use tools like the <a href="http://drupal.org/project/l10n_client">Localization client</a>, which comes bundled in the Open Atrium install, to translate page strings and then optionally contribute them back to the localization server, automatically. This flow of translations goes both ways, so your site gets the latest updates from the server just as you can send your latest updates to the server.</p>
|
||||
|
||||
<h1>Two way translation updates</h1>
|
||||
|
||||
<p><em>But what happens with my locally translated strings, which I like more than the ones that come out of the box, when I update from the server?</em></p>
|
||||
|
||||
<p><img src="http://farm3.static.flickr.com/2442/3984689343_e9b7c32718.jpg" alt="Two ways translation updates" /></p>
|
||||
|
||||
<p>In a word, nothing. There has been a major improvement on this front. Now your translations are tracked and won't be overwritten by someone else's translations when you update, unless you choose for them to be. This means that you can contribute your translations, benefit from others contributing theirs, and make the world a better (translated) place, without loosing any custom work that you want. Let the translations flow!</p></div></description>
|
||||
<comments>http://developmentseed.org/blog/2009/oct/06/open-atrium-translation-workflow-two-way-updating#comments</comments>
|
||||
<category domain="http://developmentseed.org/tags/drupal">Drupal</category>
|
||||
<category domain="http://developmentseed.org/tags/localization">localization</category>
|
||||
<category domain="http://developmentseed.org/tags/localization-client">localization client</category>
|
||||
<category domain="http://developmentseed.org/tags/localization-server">localization server</category>
|
||||
<category domain="http://developmentseed.org/tags/open-atrium">open atrium</category>
|
||||
<category domain="http://developmentseed.org/tags/translation">translation</category>
|
||||
<category domain="http://developmentseed.org/tags/translation-server">translation server</category>
|
||||
<category domain="http://developmentseed.org/channel/drupal-planet">Drupal planet</category>
|
||||
<pubDate>Tue, 06 Oct 2009 15:21:48 +0000</pubDate>
|
||||
<dc:creator>Development Seed</dc:creator>
|
||||
<guid isPermaLink="false">974 at http://developmentseed.org</guid>
|
||||
</item>
|
||||
<item>
|
||||
<title>Week in DC Tech: October 5th Edition</title>
|
||||
<link>http://developmentseed.org/blog/2009/oct/05/week-dc-tech-october-5th-edition</link>
|
||||
<description><div class="field field-type-text field-field-subtitle">
|
||||
<div class="field-items">
|
||||
<div class="field-item odd">
|
||||
<p>Drupal, PHP, and Mapping This Week in Washington, DC</p> </div>
|
||||
</div>
|
||||
</div>
|
||||
<div class='node-body'><p><img src="http://developmentseed.org/sites/developmentseed.org/files/dctech2_0_0.png" alt="Week in DC Tech" /></p>
|
||||
|
||||
<p>There are some great technology events happening this week in Washington, DC, so if you're looking to talk code, help map the city, or just hear about some neat projects and ideas, you're in luck. Below are the events that caught our eye, and you can find a full list of technology events happening this week at <a href="http://www.dctechevents.com/">DC Tech Events</a>. Have a great week!</p>
|
||||
|
||||
<h1>Wednesday, October 7</h1>
|
||||
|
||||
<p>6:30 pm</p>
|
||||
|
||||
<p><a href="http://drupal.meetup.com/21/calendar/11332695/"><strong>NOVA Drupal Meetup</strong></a>: Are you a Drupal developer, use a Drupal site, or just want to learn more about the open source content management system? Come out for this meetup to meet other Drupal fans and hear how people are using the CMS.</p>
|
||||
|
||||
<p>6:30 pm</p>
|
||||
|
||||
<p><a href="http://groups.google.com/group/washington-dcphp-group/browse_thread/thread/716d4a625287fef5?hl=en"><strong>DC PHP Beverage Subgroup</strong></a>: If you're looking to talk code with PHP developers who share your interest, come out for this casual meetup to chat over beers.</p>
|
||||
|
||||
<p>7:00 pm</p>
|
||||
|
||||
<p><a href="http://hacdc.org/"><strong>Mapping DC Meeting</strong></a>: Come out for this meetup if you want to help create high quality, free maps of Washington, DC. The <a href="http://wiki.openstreetmap.org/wiki/MappingDC">Mapping DC</a> group is doing this, starting with creating a detailed map of the National Zoo.</p></div></description>
|
||||
<comments>http://developmentseed.org/blog/2009/oct/05/week-dc-tech-october-5th-edition#comments</comments>
|
||||
<category domain="http://developmentseed.org/tags/washington-dc">Washington DC</category>
|
||||
<pubDate>Mon, 05 Oct 2009 15:27:40 +0000</pubDate>
|
||||
<dc:creator>Development Seed</dc:creator>
|
||||
<guid isPermaLink="false">973 at http://developmentseed.org</guid>
|
||||
</item>
|
||||
<item>
|
||||
<title>Mapping Innovation at the World Bank with Open Atrium</title>
|
||||
<link>http://developmentseed.org/blog/2009/oct/02/mapping-innovation-world-bank-open-atrium</link>
|
||||
<description><div class="field field-type-text field-field-subtitle">
|
||||
<div class="field-items">
|
||||
<div class="field-item odd">
|
||||
<p>Using map and faceted search features to improve collaboration</p> </div>
|
||||
</div>
|
||||
</div>
|
||||
<div class='node-body'><p><a href="http://openatrium.com/">Open Atrium</a> is being used as a base platform for collaboration at the World Bank because of its feature flexibility. Last week the World Bank launched a new Open Atrium site called "Innovate," which is being used to support an organization-wide initiative to better share information about successful projects and approaches to solving problems.</p>
|
||||
|
||||
<p>The core of the site is built around helping World Bank staff discover relevant "innovations" happening around the world and providing a space to discuss them with colleagues in topical discussion groups. To facilitate this workflow we built a custom map-based browser feature that combines custom maps with faceted search, letting users quickly find interesting content. The screenshots below from a staging site with a partial database show what this feature looks like.</p>
|
||||
|
||||
<p><img src="http://farm4.static.flickr.com/3419/3974644312_c992e1afe8.jpg" alt="The map-based browser feature makes custom maps with faceted search" /></p>
|
||||
|
||||
<p>As users apply new facets to their searches, the map results update to reveal global coverage for innovations that meet the search criteria.</p>
|
||||
|
||||
<p><img src="http://farm3.static.flickr.com/2600/3974644162_a44cc3a89a.jpg" alt="Add new facets to the search to further customize the map" /></p></div></description>
|
||||
<comments>http://developmentseed.org/blog/2009/oct/02/mapping-innovation-world-bank-open-atrium#comments</comments>
|
||||
<category domain="http://developmentseed.org/tags/custom-mapping">custom mapping</category>
|
||||
<category domain="http://developmentseed.org/tags/drupal">Drupal</category>
|
||||
<category domain="http://developmentseed.org/tags/faceted-search">faceted search</category>
|
||||
<category domain="http://developmentseed.org/tags/intranet">intranet</category>
|
||||
<category domain="http://developmentseed.org/tags/map-basec-browser">map-basec browser</category>
|
||||
<category domain="http://developmentseed.org/tags/mapbox">mapbox</category>
|
||||
<category domain="http://developmentseed.org/tags/open-atrium">open atrium</category>
|
||||
<category domain="http://developmentseed.org/tags/world-bank">World Bank</category>
|
||||
<category domain="http://developmentseed.org/channel/drupal-planet">Drupal planet</category>
|
||||
<pubDate>Fri, 02 Oct 2009 14:31:04 +0000</pubDate>
|
||||
<dc:creator>Development Seed</dc:creator>
|
||||
<guid isPermaLink="false">972 at http://developmentseed.org</guid>
|
||||
</item>
|
||||
<item>
|
||||
<title>September GeoDC Meetup Tonight</title>
|
||||
<link>http://developmentseed.org/blog/2009/sep/30/september-geodc-meetup-tonight</link>
|
||||
<description><div class="field field-type-text field-field-subtitle">
|
||||
<div class="field-items">
|
||||
<div class="field-item odd">
|
||||
<p>Presentations on Using Amazon&#8217;s Web Services and OpenStreet Map and an iPhone App that Maps Government Data</p> </div>
|
||||
</div>
|
||||
</div>
|
||||
<div class='node-body'><p>Today is the last Wednesday of the month, which means it's time for another <a href="http://geo-dc.ning.com/xn/detail/3537548:Event:1223?xg_source=activity">GeoDC meetup</a>.</p>
|
||||
|
||||
<p><img src="http://farm4.static.flickr.com/3525/3966592859_f7f4cb179c.jpg" alt="September GeoDC Meetup" /></p>
|
||||
|
||||
<p>There will be two short presentations at the meetup. <a href="http://developmentseed.org/team/tom-macwright">Tom MacWright</a> from Development Seed will talk about how using Amazon's web services and <a href="http://www.openstreetmap.org/">OpenStreetMap</a> has helped our mapping team design, render, and host custom maps. Brian Sobel of <a href="http://www.innovationgeo.com/">Innovation Geo</a> will present <a href="http://areyousafedc.com/">Are You Safe</a>, an iPhone App that uses open government data to give users up-to-date and hyper-local information about crime.</p>
|
||||
|
||||
<p>The meetup will run from 7:00 to 9:00 pm at the offices of <a href="http://www.fortiusone.com">Fortius One</a> at 2200 Wilson Blvd, Suite 307 in Arlington, just a <a href="http://maps.google.com/maps?f=q&amp;source=s_q&amp;hl=en&amp;geocode=&amp;q=2200+Wilson+Blvd+%23+307+Arlington,+VA+22201-3324&amp;sll=38.893037,-77.072783&amp;sspn=0.039481,0.087633&amp;ie=UTF8&amp;ll=38.8912,-77.086236&amp;spn=0.009871,0.021908&amp;t=h&amp;z=16&amp;iwloc=A">short walk from the Courthouse metro stop on the orange line</a>. Hope to see you there!</p></div></description>
|
||||
<comments>http://developmentseed.org/blog/2009/sep/30/september-geodc-meetup-tonight#comments</comments>
|
||||
<category domain="http://developmentseed.org/tags/geodc">GeoDC</category>
|
||||
<category domain="http://developmentseed.org/tags/washington-dc">Washington DC</category>
|
||||
<pubDate>Wed, 30 Sep 2009 12:02:53 +0000</pubDate>
|
||||
<dc:creator>Development Seed</dc:creator>
|
||||
<guid isPermaLink="false">971 at http://developmentseed.org</guid>
|
||||
</item>
|
||||
<item>
|
||||
<title>Week in DC Tech: September 28th Edition</title>
|
||||
<link>http://developmentseed.org/blog/2009/sep/28/week-dc-tech-september-28th-edition</link>
|
||||
<description><div class="field field-type-text field-field-subtitle">
|
||||
<div class="field-items">
|
||||
<div class="field-item odd">
|
||||
<p>Healthcare 2.0, iPhone Development, Online Storytelling, and More This Week in Washington, DC</p> </div>
|
||||
</div>
|
||||
</div>
|
||||
<div class='node-body'><p><img src="http://developmentseed.org/sites/developmentseed.org/files/dctech2_0_0.png" alt="Week in DC Tech" /></p>
|
||||
|
||||
<p>Looking to geek out this week? There are a bunch of interesting technology events happening in Washington, DC this week, including a look at how social media is impacting healthcare, a screening of online clips from a journalist/filmmaker, and lightning talks on all kinds of geekery by the HacDC folks. Below are the events that caught our eye, and you can find a full list of what's happening this week in technology over at <a href="http://www.dctechevents.com/">DC Tech Events</a>. Have a great week!</p>
|
||||
|
||||
<h1>Tuesday, September 29</h1>
|
||||
|
||||
<p>6:00 pm</p>
|
||||
|
||||
<p><a href="http://www.meetup.com/DC-MD-VA-Health-2-0/calendar/11291017/"><strong>Health 2.0 Meetup</strong></a>: Curious as to how - and if - online technologies are impacting healthcare? At this meetup two speakers - Sanjay Koyani from the U.S. Food and Drug Administration and Taylor Walsh from MetroHealth Media - will talk about what they're seeing and implementing.</p>
|
||||
|
||||
<p>7:00 pm</p>
|
||||
|
||||
<p><a href="http://nscodernightdc.com/"><strong>NSCoderNightDC</strong></a>: Want to build an iphone app, or talk about one that you've already built? Come out for this meetup to talk about mac and iphone development, share the latest news from Apple, and eat some delicious French desserts.</p></div></description>
|
||||
<comments>http://developmentseed.org/blog/2009/sep/28/week-dc-tech-september-28th-edition#comments</comments>
|
||||
<category domain="http://developmentseed.org/tags/washington-dc">Washington DC</category>
|
||||
<pubDate>Mon, 28 Sep 2009 15:33:15 +0000</pubDate>
|
||||
<dc:creator>Development Seed</dc:creator>
|
||||
<guid isPermaLink="false">970 at http://developmentseed.org</guid>
|
||||
</item>
|
||||
<item>
|
||||
<title>Open Data for Microfinance: The New MIXMarket.org</title>
|
||||
<link>http://developmentseed.org/blog/2009/sep/24/open-data-microfinance-new-mixmarketorg</link>
|
||||
<description><div class="field field-type-text field-field-subtitle">
|
||||
<div class="field-items">
|
||||
<div class="field-item odd">
|
||||
<p>Relaunch focuses on rich data visualization and downloadable data</p> </div>
|
||||
</div>
|
||||
</div>
|
||||
<div class='node-body'><p>The launch of the new <a href="http://www.mixmarket.org/">MIX Market</a> is a big win for open data in international development, and it vastly improves how rich financial data sets can be accessed. The MIX Market is like a Bloomberg for microfinance, publishing data on more than 1,500 microfinance institutions (MFIs) in more than 190 countries and affecting 80,021,351 people. Additionally, each MFI has as many as 150 financial indicators and in some cases going back as far as 1995. The goal of this tool is simple - to open this information up to help MFIs, researchers, raters, evaluators, and governmental and regulatory agencies better see the marketplace, and that makes for better international development.</p>
|
||||
|
||||
<p>There are profiles for every country that the MIX Market is hosting. Take a look at the country landing page for India, showing how India stacks up to other peer groups and listing out all MFIs, networks, and funders and service providers.</p>
|
||||
|
||||
<p><img src="http://farm4.static.flickr.com/3517/3941870722_390f5aa65d.jpg" alt="Country profiles give a quick overview of the performance of its microfinance institutions." /></p></div></description>
|
||||
<comments>http://developmentseed.org/blog/2009/sep/24/open-data-microfinance-new-mixmarketorg#comments</comments>
|
||||
<category domain="http://developmentseed.org/tags/data-visualization">data visualization</category>
|
||||
<category domain="http://developmentseed.org/tags/graphs">graphs</category>
|
||||
<category domain="http://developmentseed.org/tags/microfinance">microfinance</category>
|
||||
<category domain="http://developmentseed.org/tags/mix-market">MIX Market</category>
|
||||
<category domain="http://developmentseed.org/tags/open-data">open data</category>
|
||||
<category domain="http://developmentseed.org/tags/salesforce">salesforce</category>
|
||||
<category domain="http://developmentseed.org/channel/drupal-planet">Drupal planet</category>
|
||||
<pubDate>Thu, 24 Sep 2009 13:09:10 +0000</pubDate>
|
||||
<dc:creator>Development Seed</dc:creator>
|
||||
<guid isPermaLink="false">969 at http://developmentseed.org</guid>
|
||||
</item>
|
||||
<item>
|
||||
<title>Integrating the Siteminder Access System in an Open Atrium-based Intranet</title>
|
||||
<link>http://developmentseed.org/blog/2009/sep/22/integrating-siteminder-access-system-open-atrium-based-intranet</link>
|
||||
<description><div class="field field-type-text field-field-subtitle">
|
||||
<div class="field-items">
|
||||
<div class="field-item odd">
|
||||
<p>Upgraded Siteminder Module in Drupal allows for better integration with Siteminder </p> </div>
|
||||
</div>
|
||||
</div>
|
||||
<div class='node-body'><p>In <a href="http://developmentseed.org/blog/2009/sep/08/custom-open-atrium-intranet-launches-world-bank">our recent work on the World Bank's Communicate intranet</a>, we needed to integrate the <a href="http://www.ca.com/us/internet-access-control.aspx">Siteminder access system</a> into the <a href="http://openatrium.com/">Open Atrium</a>-based intranet "Communicate" to allow World Bank staff to use the same single sign-on credentials that they use to access all their internal web systems. To do this, we upgraded the Siteminder module for Drupal. You can download the <a href="http://drupal.org/project/siteminder">new module from its Drupal project page</a> and <a href="http://cvs.drupal.org/viewvc.py/drupal/contributions/modules/siteminder/README.txt?revision=1.2&amp;view=markup&amp;pathrev=DRUPAL-6--1-0-ALPHA1">learn more about its API and how to write your own Siteminder plugin in its documentation</a> and from reading the module's code. First, here is a little more background on the changes.</p>
|
||||
|
||||
<p>The Siteminder system, from <a href="http://www.ca.com/us/">Computer Associates</a>, is used by many enterprise-level organizations to authenticate signing on to their web resources. How it works is that you can designate a site - like an Open Atrium powered intranet - to be protected by the Siteminder system. Once a site is protected by Siteminder, all traffic to that site is routed through Siteminder first and then on to the actual site. Siteminder sets certain HTTP headers in the user's request, and Drupal can then examine them to determine credentials. What the Drupal Siteminder module does is map the Siteminder header values to Drupal users and allow a user to login based on the headers they send.</p>
|
||||
|
||||
<p>In addition to authentication, the Siteminder system also stores other information about users. When the Siteminder system sends HTTP headers for authentication, it can also send information about a user - like her name, email address, phone number, and so on. We wanted to be able to pull this information into the intranet too. To achieve this, we re-wrote the Siteminder module in such a way that it's easy to write a plugin module to provide the fields to which you'd like to map this extra Siteminder meta information and to determine how this information is processed and saved. To do this for the World Bank's intranet, we built the Siteminder Profile module, which lets you pick a CCK node type to serve as the target content profile for a user as well as select a few taxonomy vocabularies. Then by using the main module's administrative interface, you can choose which Siteminder headers should get mapped to which CCK fields and vocabularies based on the designated node type and vocabularies you selected in the Siteminder Profile settings page.</p>
|
||||
|
||||
<p>But what happens if a person's information changes in the Siteminder database - for example if they change phone numbers or office buildings? The Siteminder module now has built-in capability and an API to check whether values in users' profiles have changed in the Siteminder system. The Siteminder Profile module uses this API and saves a new version of a user's profile if it detects that a value has changed in the Siteminder system database.</p></div></description>
|
||||
<comments>http://developmentseed.org/blog/2009/sep/22/integrating-siteminder-access-system-open-atrium-based-intranet#comments</comments>
|
||||
<category domain="http://developmentseed.org/tags/authentication">authentication</category>
|
||||
<category domain="http://developmentseed.org/tags/drupal">Drupal</category>
|
||||
<category domain="http://developmentseed.org/tags/open-atrium">open atrium</category>
|
||||
<category domain="http://developmentseed.org/tags/siteminder">siteminder</category>
|
||||
<category domain="http://developmentseed.org/tags/siteminder-module">siteminder module</category>
|
||||
<category domain="http://developmentseed.org/channel/drupal-planet">Drupal planet</category>
|
||||
<pubDate>Tue, 22 Sep 2009 18:02:21 +0000</pubDate>
|
||||
<dc:creator>Development Seed</dc:creator>
|
||||
<guid isPermaLink="false">964 at http://developmentseed.org</guid>
|
||||
</item>
|
||||
<item>
|
||||
<title>Week in DC Tech: September 21 Edition</title>
|
||||
<link>http://developmentseed.org/blog/2009/sep/21/week-dc-tech-september-21-edition</link>
|
||||
<description><div class="field field-type-text field-field-subtitle">
|
||||
<div class="field-items">
|
||||
<div class="field-item odd">
|
||||
<p>PHP, Design, Twitter, and Wikipedia This Week in Washington, DC</p> </div>
|
||||
</div>
|
||||
</div>
|
||||
<div class='node-body'><p><img src="http://developmentseed.org/sites/default/files/dctech2_0.png" alt="Week in DC Tech" /></p>
|
||||
|
||||
<p>There's an interesting variety of technology events happening in Washington, DC this week with focuses ranging from using Twitter for advocacy to drinking beers with php developers to discussing designing way outside of the box. Additionally tomorrow is international Car Free Day and there are events happening throughout the city to celebrate it and help you how to rely on cars less. Below are the events that caught our eye, and you can find a full list of the week's technology events at <a href="http://www.dctechevents.com/">DC Tech Events</a>.</p>
|
||||
|
||||
<h2>Tuesday, September 22</h2>
|
||||
|
||||
<p>All day</p>
|
||||
|
||||
<p><a href="http://www.carfreemetrodc.com/"><strong>Car Free Day</strong></a>: Help reduce traffic and improve air quality by leaving your car at home on Tuesday in celebration of Car Free Day. There are also <a href="http://www.carfreemetrodc.com/Information/tabid/57/Default.aspx">free bike repair trainings, yoga classes, and other events</a> happening throughout the day to help you lead a car free lifestyle.</p>
|
||||
|
||||
<p>6:00 - 8:00 pm</p>
|
||||
|
||||
<p><a href="http://www.php.net/cal.php?id=3075"><strong>DC PHP Beverage Subgroup</strong></a>: Come out to talk code with other php developers over a few beers. This is a great opportunity to get to know local php developers in a casual setting while sharing stories about your code.</p></div></description>
|
||||
<comments>http://developmentseed.org/blog/2009/sep/21/week-dc-tech-september-21-edition#comments</comments>
|
||||
<category domain="http://developmentseed.org/tags/washington-dc">Washington DC</category>
|
||||
<pubDate>Mon, 21 Sep 2009 16:03:24 +0000</pubDate>
|
||||
<dc:creator>Development Seed</dc:creator>
|
||||
<guid isPermaLink="false">968 at http://developmentseed.org</guid>
|
||||
</item>
|
||||
<item>
|
||||
<title>Peru's Software Freedom Day: Impressions & Photos</title>
|
||||
<link>http://developmentseed.org/blog/2009/sep/21/perus-software-freedom-day-impressions-and-photos</link>
|
||||
<description><div class='node-body'><p>There was a great turn out a <a href="http://www.sfdperu.org/">Software Freedom Day</a> this weekend with 400 people in attendance and a solid 30 presentations. The <a href="http://developmentseed.org/blog/2009/sep/15/preparing-perus-software-freedom-day-talks-drupal-features-and-open-atrium">presentations in the Drupal track</a> were some of the best attended sessions of the day. To get a sense of Drupal's traction down here, "Drupal" was mentioned in many sessions and conversations throughout the day, and not just by the people working directly with Drupal.</p>
|
||||
|
||||
<p><img src="http://farm3.static.flickr.com/2653/3940335249_57ce995a84.jpg" alt="Presenting on Features in Drupal and Open Atrium" />
|
||||
<em>Presenting on Features in Drupal and Open Atrium</em></p>
|
||||
|
||||
<p>I had a great time meeting people and learning about the work being done in the different open source communities here in Peru. Software Freedom Day is becoming an annual event in Peru, and there were many discussions on improving the event for next year as well as keeping the energy going to improve the image of open source software in the country. It's great to see the community looking forward like this, and I'm excited to help keep the open source movement growing in Peru.</p>
|
||||
|
||||
<p><a href="http://www.flickr.com/photos/developmentseed/sets/72157622423999830/">More photos from the event here.</a></p></div></description>
|
||||
<comments>http://developmentseed.org/blog/2009/sep/21/perus-software-freedom-day-impressions-and-photos#comments</comments>
|
||||
<category domain="http://developmentseed.org/tags/drupal">Drupal</category>
|
||||
<category domain="http://developmentseed.org/tags/open-source">open source</category>
|
||||
<category domain="http://developmentseed.org/tags/peru">Peru</category>
|
||||
<category domain="http://developmentseed.org/tags/software-freedom-day">software freedom day</category>
|
||||
<pubDate>Mon, 21 Sep 2009 14:22:35 +0000</pubDate>
|
||||
<dc:creator>Development Seed</dc:creator>
|
||||
<guid isPermaLink="false">967 at http://developmentseed.org</guid>
|
||||
</item>
|
||||
<item>
|
||||
<title>Scaling the Open Atrium UI</title>
|
||||
<link>http://developmentseed.org/blog/2009/sep/18/scaling-open-atrium-ui</link>
|
||||
<description><div class="field field-type-text field-field-subtitle">
|
||||
<div class="field-items">
|
||||
<div class="field-item odd">
|
||||
<p>Refactoring a user interface for bigger, broader use cases</p> </div>
|
||||
</div>
|
||||
</div>
|
||||
<div class='node-body'><p>We released <a href="http://developmentseed.org/blog/2009/jul/14/open-atrium-public-beta-code-github">Open Atrium Beta 1</a> in July knowing that a wider audience would lead to more real world testing, feedback, and problems. In <a href="http://openatrium.com/download">the latest release this week</a>, we've incorporated some of the responses we've gotten from the <a href="http://community.openatrium.com">community</a>, as well as our <a href="http://developmentseed.org/blog/2009/sep/08/custom-open-atrium-intranet-launches-world-bank">clients' experiences</a> into key changes in Open Atrium's UI.</p>
|
||||
|
||||
<p><img src="http://farm3.static.flickr.com/2607/3928674475_285044e13c.jpg" alt=" Fluid width/ Breadcrumbs" /></p>
|
||||
|
||||
<h2>Fluid width</h2>
|
||||
|
||||
<p>The first major change is switching from the previously <code>960px</code> fixed width theme Ginkgo to fluid width. Open Atrium is now usable on screens from <code>800px</code> wide to as-big-as-your-budget-allows. Aside from meaning that the page layout stretches and shrinks when you resize your browser window, it also means slightly bigger/more readable fonts overall.</p>
|
||||
|
||||
<h2>1. Breadcrumbs</h2>
|
||||
|
||||
<p>One usability problem we often deal with is people not recognizing the site / group / user space architecture of Open Atrium. One approach to this in the past was to color-code different space types. With the color-customizations made possible by <code>spaces_design</code>, this is no longer necessarily a reliable indicator of where you are. We first introduced breadcrumbs in Open Atrium on the Communicate project for the World Bank and have since merged it into Atrium HEAD.</p>
|
||||
|
||||
<h2>2. Consolidate blocks, user info, and help</h2>
|
||||
|
||||
<p>The global tools in Open Atrium's first row of navigation have been consolidated into distinct blocks. Previously, some header links were inserted into the page template through custom <code>preprocess_page()</code> calls, while the togglable help text was inserted via a custom theme function and dropdown blocks were added into the header region. All of these components are now provided by blocks, making it straightforward for themers and developers to adjust, remove, or add to these components.</p>
|
||||
|
||||
<p><img src="http://farm3.static.flickr.com/2654/3928674449_8f443df1b3.jpg" alt="Togglable Open Atrium UI adjustments" /></p></div></description>
|
||||
<comments>http://developmentseed.org/blog/2009/sep/18/scaling-open-atrium-ui#comments</comments>
|
||||
<category domain="http://developmentseed.org/tags/drupal">Drupal</category>
|
||||
<category domain="http://developmentseed.org/tags/interface">interface</category>
|
||||
<category domain="http://developmentseed.org/tags/open-atrium">open atrium</category>
|
||||
<category domain="http://developmentseed.org/tags/usability">usability</category>
|
||||
<category domain="http://developmentseed.org/channel/drupal-planet">Drupal planet</category>
|
||||
<pubDate>Fri, 18 Sep 2009 14:31:23 +0000</pubDate>
|
||||
<dc:creator>Development Seed</dc:creator>
|
||||
<guid isPermaLink="false">966 at http://developmentseed.org</guid>
|
||||
</item>
|
||||
</channel>
|
||||
</rss>
|
299
sites/all/modules/feeds/tests/feeds/developmentseed_changes.rss2
Normal file
299
sites/all/modules/feeds/tests/feeds/developmentseed_changes.rss2
Normal file
@@ -0,0 +1,299 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?><rss version="2.0" xml:base="http://developmentseed.org/blog/all" xmlns:dc="http://purl.org/dc/elements/1.1/">
|
||||
<channel>
|
||||
<title>Development Seed - Technological Solutions for Progressive Organizations</title>
|
||||
<link>http://developmentseed.org/blog/all</link>
|
||||
<description></description>
|
||||
<language>en</language>
|
||||
<item>
|
||||
<title>Managing News Translation Workflow: Two Way Translation Updates</title>
|
||||
<link>http://developmentseed.org/blog/2009/oct/06/open-atrium-translation-workflow-two-way-updating</link>
|
||||
<description><div class="field field-type-text field-field-subtitle">
|
||||
<div class="field-items">
|
||||
<div class="field-item odd">
|
||||
<p>A new translation process for Open Atrium and integration with Localize Drupal</p> </div>
|
||||
</div>
|
||||
</div>
|
||||
<div class='node-body'><p>The <a href="http://openatrium.com/">Open Atrium</a> <a href="http://developmentseed.org/blog/2009/jul/16/open-atrium-solving-translation-puzzle">translation infrastructure</a> (and Drupal translations in general) are progressing quickly. For Open Atrium to be well translated we first need Drupal's modules to be translated, so I am splitting efforts at the moment between helping with <a href="http://localize.drupal.org">Localize Drupal</a> and improving <a href="https://translate.openatrium.com">Open Atrium Translate</a>. Already, it is much easier to automatically download your language, get updates from a translation server, protect locally translated strings, and scale the translation system so that translation servers can talk to each other.</p>
|
||||
|
||||
<h1>Automatically download your language</h1>
|
||||
|
||||
<p><img src="http://farm3.static.flickr.com/2496/3984689117_57559c74eb.jpg" alt="Magical translation install" /></p>
|
||||
|
||||
<p>For more than a month now you have been able to install Open Atrium, select one of its 20+ languages, and have the translation automatically downloaded and installed on your site. While this has been working for awhile now, we are still refining the process. One change we've already made is that now translations are downloaded in multiple smaller packages, rather than a single large one.</p>
|
||||
|
||||
<p>Once your translation is installed, you can use tools like the <a href="http://drupal.org/project/l10n_client">Localization client</a>, which comes bundled in the Open Atrium install, to translate page strings and then optionally contribute them back to the localization server, automatically. This flow of translations goes both ways, so your site gets the latest updates from the server just as you can send your latest updates to the server.</p>
|
||||
|
||||
<h1>Two way translation updates</h1>
|
||||
|
||||
<p><em>But what happens with my locally translated strings, which I like more than the ones that come out of the box, when I update from the server?</em></p>
|
||||
|
||||
<p><img src="http://farm3.static.flickr.com/2442/3984689343_e9b7c32718.jpg" alt="Two ways translation updates" /></p>
|
||||
|
||||
<p>In a word, nothing. There has been a major improvement on this front. Now your translations are tracked and won't be overwritten by someone else's translations when you update, unless you choose for them to be. This means that you can contribute your translations, benefit from others contributing theirs, and make the world a better (translated) place, without loosing any custom work that you want. Let the translations flow!</p></div></description>
|
||||
<comments>http://developmentseed.org/blog/2009/oct/06/open-atrium-translation-workflow-two-way-updating#comments</comments>
|
||||
<category domain="http://developmentseed.org/tags/drupal">Drupal</category>
|
||||
<category domain="http://developmentseed.org/tags/localization">localization</category>
|
||||
<category domain="http://developmentseed.org/tags/localization-client">localization client</category>
|
||||
<category domain="http://developmentseed.org/tags/localization-server">localization server</category>
|
||||
<category domain="http://developmentseed.org/tags/open-atrium">open atrium</category>
|
||||
<category domain="http://developmentseed.org/tags/translation">translation</category>
|
||||
<category domain="http://developmentseed.org/tags/translation-server">translation server</category>
|
||||
<category domain="http://developmentseed.org/channel/drupal-planet">Drupal planet</category>
|
||||
<pubDate>Tue, 06 Oct 2009 15:21:48 +0000</pubDate>
|
||||
<dc:creator>Development Seed</dc:creator>
|
||||
<guid isPermaLink="false">974 at http://developmentseed.org</guid>
|
||||
</item>
|
||||
<item>
|
||||
<title>Week in DC Tech: October 5th Edition</title>
|
||||
<link>http://developmentseed.org/blog/2009/oct/05/week-dc-tech-october-5th-edition</link>
|
||||
<description><div class="field field-type-text field-field-subtitle">
|
||||
<div class="field-items">
|
||||
<div class="field-item odd">
|
||||
<p>Drupal, PHP, and Mapping This Week in Washington, DC</p> </div>
|
||||
</div>
|
||||
</div>
|
||||
<div class='node-body'><p><img src="http://developmentseed.org/sites/developmentseed.org/files/dctech2_0_0.png" alt="Week in DC Tech" /></p>
|
||||
|
||||
<p>There are some great technology events happening this week in Washington, DC, so if you're looking to talk code, help map the city, or just hear about some neat projects and ideas, you're in luck. Below are the events that caught our eye, and you can find a full list of technology events happening this week at <a href="http://www.dctechevents.com/">DC Tech Events</a>. Have a great week!</p>
|
||||
|
||||
<h1>Wednesday, October 7</h1>
|
||||
|
||||
<p>6:30 pm</p>
|
||||
|
||||
<p><a href="http://drupal.meetup.com/21/calendar/11332695/"><strong>NOVA Drupal Meetup</strong></a>: Are you a Drupal developer, use a Drupal site, or just want to learn more about the open source content management system? Come out for this meetup to meet other Drupal fans and hear how people are using the CMS.</p>
|
||||
|
||||
<p>6:30 pm</p>
|
||||
|
||||
<p><a href="http://groups.google.com/group/washington-dcphp-group/browse_thread/thread/716d4a625287fef5?hl=en"><strong>DC PHP Beverage Subgroup</strong></a>: If you're looking to talk code with PHP developers who share your interest, come out for this casual meetup to chat over beers.</p>
|
||||
|
||||
<p>7:00 pm</p>
|
||||
|
||||
<p><a href="http://hacdc.org/"><strong>Mapping DC Meeting</strong></a>: Come out for this meetup if you want to help create high quality, free maps of Washington, DC. The <a href="http://wiki.openstreetmap.org/wiki/MappingDC">Mapping DC</a> group is doing this, starting with creating a detailed map of the National Zoo.</p></div></description>
|
||||
<comments>http://developmentseed.org/blog/2009/oct/05/week-dc-tech-october-5th-edition#comments</comments>
|
||||
<category domain="http://developmentseed.org/tags/washington-dc">Washington DC</category>
|
||||
<pubDate>Mon, 05 Oct 2009 15:27:40 +0000</pubDate>
|
||||
<dc:creator>Development Seed</dc:creator>
|
||||
<guid isPermaLink="false">973 at http://developmentseed.org</guid>
|
||||
</item>
|
||||
<item>
|
||||
<title>Mapping Innovation at the World Bank with Open Atrium</title>
|
||||
<link>http://developmentseed.org/blog/2009/oct/02/mapping-innovation-world-bank-open-atrium</link>
|
||||
<description><div class="field field-type-text field-field-subtitle">
|
||||
<div class="field-items">
|
||||
<div class="field-item odd">
|
||||
<p>Using map and faceted search features to improve collaboration</p> </div>
|
||||
</div>
|
||||
</div>
|
||||
<div class='node-body'><p><a href="http://openatrium.com/">Open Atrium</a> is being used as a base platform for collaboration at the World Bank because of its feature flexibility. Last week the World Bank launched a new Open Atrium site called "Innovate," which is being used to support an organization-wide initiative to better share information about successful projects and approaches to solving problems.</p>
|
||||
|
||||
<p>The core of the site is built around helping World Bank staff discover relevant "innovations" happening around the world and providing a space to discuss them with colleagues in topical discussion groups. To facilitate this workflow we built a custom map-based browser feature that combines custom maps with faceted search, letting users quickly find interesting content. The screenshots below from a staging site with a partial database show what this feature looks like.</p>
|
||||
|
||||
<p><img src="http://farm4.static.flickr.com/3419/3974644312_c992e1afe8.jpg" alt="The map-based browser feature makes custom maps with faceted search" /></p>
|
||||
|
||||
<p>As users apply new facets to their searches, the map results update to reveal global coverage for innovations that meet the search criteria.</p>
|
||||
|
||||
<p><img src="http://farm3.static.flickr.com/2600/3974644162_a44cc3a89a.jpg" alt="Add new facets to the search to further customize the map" /></p></div></description>
|
||||
<comments>http://developmentseed.org/blog/2009/oct/02/mapping-innovation-world-bank-open-atrium#comments</comments>
|
||||
<category domain="http://developmentseed.org/tags/custom-mapping">custom mapping</category>
|
||||
<category domain="http://developmentseed.org/tags/drupal">Drupal</category>
|
||||
<category domain="http://developmentseed.org/tags/faceted-search">faceted search</category>
|
||||
<category domain="http://developmentseed.org/tags/intranet">intranet</category>
|
||||
<category domain="http://developmentseed.org/tags/map-basec-browser">map-basec browser</category>
|
||||
<category domain="http://developmentseed.org/tags/mapbox">mapbox</category>
|
||||
<category domain="http://developmentseed.org/tags/open-atrium">open atrium</category>
|
||||
<category domain="http://developmentseed.org/tags/world-bank">World Bank</category>
|
||||
<category domain="http://developmentseed.org/channel/drupal-planet">Drupal planet</category>
|
||||
<pubDate>Fri, 02 Oct 2009 14:31:04 +0000</pubDate>
|
||||
<dc:creator>Development Seed</dc:creator>
|
||||
<guid isPermaLink="false">972 at http://developmentseed.org</guid>
|
||||
</item>
|
||||
<item>
|
||||
<title>September GeoDC Meetup Tonight</title>
|
||||
<link>http://developmentseed.org/blog/2009/sep/30/september-geodc-meetup-tonight</link>
|
||||
<description><div class="field field-type-text field-field-subtitle">
|
||||
<div class="field-items">
|
||||
<div class="field-item odd">
|
||||
<p>Presentations on Using Amazon&#8217;s Web Services and OpenStreet Map and an iPhone App that Maps Government Data</p> </div>
|
||||
</div>
|
||||
</div>
|
||||
<div class='node-body'><p>Today is the last Wednesday of the month, which means it's time for another <a href="http://geo-dc.ning.com/xn/detail/3537548:Event:1223?xg_source=activity">GeoDC meetup</a>.</p>
|
||||
|
||||
<p><img src="http://farm4.static.flickr.com/3525/3966592859_f7f4cb179c.jpg" alt="September GeoDC Meetup" /></p>
|
||||
|
||||
<p>There will be two short presentations at the meetup. <a href="http://developmentseed.org/team/tom-macwright">Tom MacWright</a> from Development Seed will talk about how using Amazon's web services and <a href="http://www.openstreetmap.org/">OpenStreetMap</a> has helped our mapping team design, render, and host custom maps. Brian Sobel of <a href="http://www.innovationgeo.com/">Innovation Geo</a> will present <a href="http://areyousafedc.com/">Are You Safe</a>, an iPhone App that uses open government data to give users up-to-date and hyper-local information about crime.</p>
|
||||
|
||||
<p>The meetup will run from 7:00 to 9:00 pm at the offices of <a href="http://www.fortiusone.com">Fortius One</a> at 2200 Wilson Blvd, Suite 307 in Arlington, just a <a href="http://maps.google.com/maps?f=q&amp;source=s_q&amp;hl=en&amp;geocode=&amp;q=2200+Wilson+Blvd+%23+307+Arlington,+VA+22201-3324&amp;sll=38.893037,-77.072783&amp;sspn=0.039481,0.087633&amp;ie=UTF8&amp;ll=38.8912,-77.086236&amp;spn=0.009871,0.021908&amp;t=h&amp;z=16&amp;iwloc=A">short walk from the Courthouse metro stop on the orange line</a>. Hope to see you there!</p></div></description>
|
||||
<comments>http://developmentseed.org/blog/2009/sep/30/september-geodc-meetup-tonight#comments</comments>
|
||||
<category domain="http://developmentseed.org/tags/geodc">GeoDC</category>
|
||||
<category domain="http://developmentseed.org/tags/washington-dc">Washington DC</category>
|
||||
<pubDate>Wed, 30 Sep 2009 12:02:53 +0000</pubDate>
|
||||
<dc:creator>Development Seed</dc:creator>
|
||||
<guid isPermaLink="false">971 at http://developmentseed.org</guid>
|
||||
</item>
|
||||
<item>
|
||||
<title>Week in DC Tech: September 28th Edition</title>
|
||||
<link>http://developmentseed.org/blog/2009/sep/28/week-dc-tech-september-28th-edition</link>
|
||||
<description><div class="field field-type-text field-field-subtitle">
|
||||
<div class="field-items">
|
||||
<div class="field-item odd">
|
||||
<p>Healthcare 2.0, iPhone Development, Online Storytelling, and More This Week in Washington, DC</p> </div>
|
||||
</div>
|
||||
</div>
|
||||
<div class='node-body'><p><img src="http://developmentseed.org/sites/developmentseed.org/files/dctech2_0_0.png" alt="Week in DC Tech" /></p>
|
||||
|
||||
<p>Looking to geek out this week? There are a bunch of interesting technology events happening in Washington, DC this week, including a look at how social media is impacting healthcare, a screening of online clips from a journalist/filmmaker, and lightning talks on all kinds of geekery by the HacDC folks. Below are the events that caught our eye, and you can find a full list of what's happening this week in technology over at <a href="http://www.dctechevents.com/">DC Tech Events</a>. Have a great week!</p>
|
||||
|
||||
<h1>Tuesday, September 29</h1>
|
||||
|
||||
<p>6:00 pm</p>
|
||||
|
||||
<p><a href="http://www.meetup.com/DC-MD-VA-Health-2-0/calendar/11291017/"><strong>Health 2.0 Meetup</strong></a>: Curious as to how - and if - online technologies are impacting healthcare? At this meetup two speakers - Sanjay Koyani from the U.S. Food and Drug Administration and Taylor Walsh from MetroHealth Media - will talk about what they're seeing and implementing.</p>
|
||||
|
||||
<p>7:00 pm</p>
|
||||
|
||||
<p><a href="http://nscodernightdc.com/"><strong>NSCoderNightDC</strong></a>: Want to build an iphone app, or talk about one that you've already built? Come out for this meetup to talk about mac and iphone development, share the latest news from Apple, and eat some delicious French desserts.</p></div></description>
|
||||
<comments>http://developmentseed.org/blog/2009/sep/28/week-dc-tech-september-28th-edition#comments</comments>
|
||||
<category domain="http://developmentseed.org/tags/washington-dc">Washington DC</category>
|
||||
<pubDate>Mon, 28 Sep 2009 15:33:15 +0000</pubDate>
|
||||
<dc:creator>Development Seed</dc:creator>
|
||||
<guid isPermaLink="false">970 at http://developmentseed.org</guid>
|
||||
</item>
|
||||
<item>
|
||||
<title>Open Data for Microfinance: The New MIXMarket.org</title>
|
||||
<link>http://developmentseed.org/blog/2009/sep/24/open-data-microfinance-new-mixmarketorg</link>
|
||||
<description><div class="field field-type-text field-field-subtitle">
|
||||
<div class="field-items">
|
||||
<div class="field-item odd">
|
||||
<p>Relaunch focuses on rich data visualization and downloadable data</p> </div>
|
||||
</div>
|
||||
</div>
|
||||
<div class='node-body'><p>The launch of the new <a href="http://www.mixmarket.org/">MIX Market</a> is a big win for open data in international development, and it vastly improves how rich financial data sets can be accessed. The MIX Market is like a Bloomberg for microfinance, publishing data on more than 1,500 microfinance institutions (MFIs) in more than 190 countries and affecting 80,021,351 people. Additionally, each MFI has as many as 150 financial indicators and in some cases going back as far as 1995. The goal of this tool is simple - to open this information up to help MFIs, researchers, raters, evaluators, and governmental and regulatory agencies better see the marketplace, and that makes for better international development.</p>
|
||||
|
||||
<p>There are profiles for every country that the MIX Market is hosting. Take a look at the country landing page for India, showing how India stacks up to other peer groups and listing out all MFIs, networks, and funders and service providers.</p>
|
||||
|
||||
<p><img src="http://farm4.static.flickr.com/3517/3941870722_390f5aa65d.jpg" alt="Country profiles give a quick overview of the performance of its microfinance institutions." /></p></div></description>
|
||||
<comments>http://developmentseed.org/blog/2009/sep/24/open-data-microfinance-new-mixmarketorg#comments</comments>
|
||||
<category domain="http://developmentseed.org/tags/data-visualization">data visualization</category>
|
||||
<category domain="http://developmentseed.org/tags/graphs">graphs</category>
|
||||
<category domain="http://developmentseed.org/tags/microfinance">microfinance</category>
|
||||
<category domain="http://developmentseed.org/tags/mix-market">MIX Market</category>
|
||||
<category domain="http://developmentseed.org/tags/open-data">open data</category>
|
||||
<category domain="http://developmentseed.org/tags/salesforce">salesforce</category>
|
||||
<category domain="http://developmentseed.org/channel/drupal-planet">Drupal planet</category>
|
||||
<pubDate>Thu, 24 Sep 2009 13:09:10 +0000</pubDate>
|
||||
<dc:creator>Development Seed</dc:creator>
|
||||
<guid isPermaLink="false">969 at http://developmentseed.org</guid>
|
||||
</item>
|
||||
<item>
|
||||
<title>Integrating the Siteminder Access System in an Open Atrium-based Intranet</title>
|
||||
<link>http://developmentseed.org/blog/2009/sep/22/integrating-siteminder-access-system-open-atrium-based-intranet</link>
|
||||
<description><div class="field field-type-text field-field-subtitle">
|
||||
<div class="field-items">
|
||||
<div class="field-item odd">
|
||||
<p>Upgraded Siteminder Module in Drupal allows for better integration with Siteminder </p> </div>
|
||||
</div>
|
||||
</div>
|
||||
<div class='node-body'><p>In <a href="http://developmentseed.org/blog/2009/sep/08/custom-open-atrium-intranet-launches-world-bank">our recent work on the World Bank's Communicate intranet</a>, we needed to integrate the <a href="http://www.ca.com/us/internet-access-control.aspx">Siteminder access system</a> into the <a href="http://openatrium.com/">Open Atrium</a>-based intranet "Communicate" to allow World Bank staff to use the same single sign-on credentials that they use to access all their internal web systems. To do this, we upgraded the Siteminder module for Drupal. You can download the <a href="http://drupal.org/project/siteminder">new module from its Drupal project page</a> and <a href="http://cvs.drupal.org/viewvc.py/drupal/contributions/modules/siteminder/README.txt?revision=1.2&amp;view=markup&amp;pathrev=DRUPAL-6--1-0-ALPHA1">learn more about its API and how to write your own Siteminder plugin in its documentation</a> and from reading the module's code. First, here is a little more background on the changes.</p>
|
||||
|
||||
<p>The Siteminder system, from <a href="http://www.ca.com/us/">Computer Associates</a>, is used by many enterprise-level organizations to authenticate signing on to their web resources. How it works is that you can designate a site - like an Open Atrium powered intranet - to be protected by the Siteminder system. Once a site is protected by Siteminder, all traffic to that site is routed through Siteminder first and then on to the actual site. Siteminder sets certain HTTP headers in the user's request, and Drupal can then examine them to determine credentials. What the Drupal Siteminder module does is map the Siteminder header values to Drupal users and allow a user to login based on the headers they send.</p>
|
||||
|
||||
<p>In addition to authentication, the Siteminder system also stores other information about users. When the Siteminder system sends HTTP headers for authentication, it can also send information about a user - like her name, email address, phone number, and so on. We wanted to be able to pull this information into the intranet too. To achieve this, we re-wrote the Siteminder module in such a way that it's easy to write a plugin module to provide the fields to which you'd like to map this extra Siteminder meta information and to determine how this information is processed and saved. To do this for the World Bank's intranet, we built the Siteminder Profile module, which lets you pick a CCK node type to serve as the target content profile for a user as well as select a few taxonomy vocabularies. Then by using the main module's administrative interface, you can choose which Siteminder headers should get mapped to which CCK fields and vocabularies based on the designated node type and vocabularies you selected in the Siteminder Profile settings page.</p>
|
||||
|
||||
<p>But what happens if a person's information changes in the Siteminder database - for example if they change phone numbers or office buildings? The Siteminder module now has built-in capability and an API to check whether values in users' profiles have changed in the Siteminder system. The Siteminder Profile module uses this API and saves a new version of a user's profile if it detects that a value has changed in the Siteminder system database.</p></div></description>
|
||||
<comments>http://developmentseed.org/blog/2009/sep/22/integrating-siteminder-access-system-open-atrium-based-intranet#comments</comments>
|
||||
<category domain="http://developmentseed.org/tags/authentication">authentication</category>
|
||||
<category domain="http://developmentseed.org/tags/drupal">Drupal</category>
|
||||
<category domain="http://developmentseed.org/tags/open-atrium">open atrium</category>
|
||||
<category domain="http://developmentseed.org/tags/siteminder">siteminder</category>
|
||||
<category domain="http://developmentseed.org/tags/siteminder-module">siteminder module</category>
|
||||
<category domain="http://developmentseed.org/channel/drupal-planet">Drupal planet</category>
|
||||
<pubDate>Tue, 22 Sep 2009 18:02:21 +0000</pubDate>
|
||||
<dc:creator>Development Seed</dc:creator>
|
||||
<guid isPermaLink="false">964 at http://developmentseed.org</guid>
|
||||
</item>
|
||||
<item>
|
||||
<title>Week in DC Tech: September 21 Edition</title>
|
||||
<link>http://developmentseed.org/blog/2009/sep/21/week-dc-tech-september-21-edition</link>
|
||||
<description><div class="field field-type-text field-field-subtitle">
|
||||
<div class="field-items">
|
||||
<div class="field-item odd">
|
||||
<p>PHP, Design, Twitter, and Wikipedia This Week in Washington, DC</p> </div>
|
||||
</div>
|
||||
</div>
|
||||
<div class='node-body'><p><img src="http://developmentseed.org/sites/default/files/dctech2_0.png" alt="Week in DC Tech" /></p>
|
||||
|
||||
<p>There's an interesting variety of technology events happening in Washington, DC this week with focuses ranging from using Twitter for advocacy to drinking beers with php developers to discussing designing way outside of the box. Additionally tomorrow is international Car Free Day and there are events happening throughout the city to celebrate it and help you how to rely on cars less. Below are the events that caught our eye, and you can find a full list of the week's technology events at <a href="http://www.dctechevents.com/">DC Tech Events</a>.</p>
|
||||
|
||||
<h2>Tuesday, September 22</h2>
|
||||
|
||||
<p>All day</p>
|
||||
|
||||
<p><a href="http://www.carfreemetrodc.com/"><strong>Car Free Day</strong></a>: Help reduce traffic and improve air quality by leaving your car at home on Tuesday in celebration of Car Free Day. There are also <a href="http://www.carfreemetrodc.com/Information/tabid/57/Default.aspx">free bike repair trainings, yoga classes, and other events</a> happening throughout the day to help you lead a car free lifestyle.</p>
|
||||
|
||||
<p>6:00 - 8:00 pm</p>
|
||||
|
||||
<p><a href="http://www.php.net/cal.php?id=3075"><strong>DC PHP Beverage Subgroup</strong></a>: Come out to talk code with other php developers over a few beers. This is a great opportunity to get to know local php developers in a casual setting while sharing stories about your code.</p></div></description>
|
||||
<comments>http://developmentseed.org/blog/2009/sep/21/week-dc-tech-september-21-edition#comments</comments>
|
||||
<category domain="http://developmentseed.org/tags/washington-dc">Washington DC</category>
|
||||
<pubDate>Mon, 21 Sep 2009 16:03:24 +0000</pubDate>
|
||||
<dc:creator>Development Seed</dc:creator>
|
||||
<guid isPermaLink="false">968 at http://developmentseed.org</guid>
|
||||
</item>
|
||||
<item>
|
||||
<title>Peru's Software Freedom Day: Impressions and Photos</title>
|
||||
<link>http://developmentseed.org/blog/2009/sep/21/perus-software-freedom-day-impressions-and-photos</link>
|
||||
<description><div class='node-body'><p>There was a great turn out a <a href="http://www.sfdperu.org/">Software Freedom Day</a> this weekend with 400 people in attendance and a solid 30 presentations. The <a href="http://developmentseed.org/blog/2009/sep/15/preparing-perus-software-freedom-day-talks-drupal-features-and-open-atrium">presentations in the Drupal track</a> were some of the best attended sessions of the day. To get a sense of Drupal's traction down here, "Drupal" was mentioned in many sessions and conversations throughout the day, and not just by the people working directly with Drupal.</p>
|
||||
|
||||
<p><img src="http://farm3.static.flickr.com/2653/3940335249_57ce995a84.jpg" alt="Presenting on Features in Drupal and Managing News" />
|
||||
<em>Presenting on Features in Drupal and Managing News</em></p>
|
||||
|
||||
<p>I had a great time meeting people and learning about the work being done in the different open source communities here in Peru. Software Freedom Day is becoming an annual event in Peru, and there were many discussions on improving the event for next year as well as keeping the energy going to improve the image of open source software in the country. It's great to see the community looking forward like this, and I'm excited to help keep the open source movement growing in Peru.</p>
|
||||
|
||||
<p><a href="http://www.flickr.com/photos/developmentseed/sets/72157622423999830/">More photos from the event here.</a></p></div></description>
|
||||
<comments>http://developmentseed.org/blog/2009/sep/21/perus-software-freedom-day-impressions-and-photos#comments</comments>
|
||||
<category domain="http://developmentseed.org/tags/drupal">Drupal</category>
|
||||
<category domain="http://developmentseed.org/tags/open-source">open source</category>
|
||||
<category domain="http://developmentseed.org/tags/peru">Peru</category>
|
||||
<category domain="http://developmentseed.org/tags/software-freedom-day">software freedom day</category>
|
||||
<pubDate>Mon, 21 Sep 2009 14:22:35 +0000</pubDate>
|
||||
<dc:creator>Development Seed</dc:creator>
|
||||
<guid isPermaLink="false">967 at http://developmentseed.org</guid>
|
||||
</item>
|
||||
<item>
|
||||
<title>Scaling the Open Atrium UI</title>
|
||||
<link>http://developmentseed.org/blog/2009/sep/18/scaling-open-atrium-ui</link>
|
||||
<description><div class="field field-type-text field-field-subtitle">
|
||||
<div class="field-items">
|
||||
<div class="field-item odd">
|
||||
<p>Refactoring a user interface for bigger, broader use cases</p> </div>
|
||||
</div>
|
||||
</div>
|
||||
<div class='node-body'><p>We released <a href="http://developmentseed.org/blog/2009/jul/14/open-atrium-public-beta-code-github">Open Atrium Beta 1</a> in July knowing that a wider audience would lead to more real world testing, feedback, and problems. In <a href="http://openatrium.com/download">the latest release this week</a>, we've incorporated some of the responses we've gotten from the <a href="http://community.openatrium.com">community</a>, as well as our <a href="http://developmentseed.org/blog/2009/sep/08/custom-open-atrium-intranet-launches-world-bank">clients' experiences</a> into key changes in Open Atrium's UI.</p>
|
||||
|
||||
<p><img src="http://farm3.static.flickr.com/2607/3928674475_285044e13c.jpg" alt=" Fluid width/ Breadcrumbs" /></p>
|
||||
|
||||
<h2>Fluid width</h2>
|
||||
|
||||
<p>The first major change is switching from the previously <code>960px</code> fixed width theme Ginkgo to fluid width. Open Atrium is now usable on screens from <code>800px</code> wide to as-big-as-your-budget-allows. Aside from meaning that the page layout stretches and shrinks when you resize your browser window, it also means slightly bigger/more readable fonts overall.</p>
|
||||
|
||||
<h2>1. Breadcrumbs</h2>
|
||||
|
||||
<p>One usability problem we often deal with is people not recognizing the site / group / user space architecture of Open Atrium. One approach to this in the past was to color-code different space types. With the color-customizations made possible by <code>spaces_design</code>, this is no longer necessarily a reliable indicator of where you are. We first introduced breadcrumbs in Open Atrium on the Communicate project for the World Bank and have since merged it into Atrium HEAD.</p>
|
||||
|
||||
<h2>2. Consolidate blocks, user info, and help</h2>
|
||||
|
||||
<p>The global tools in Open Atrium's first row of navigation have been consolidated into distinct blocks. Previously, some header links were inserted into the page template through custom <code>preprocess_page()</code> calls, while the togglable help text was inserted via a custom theme function and dropdown blocks were added into the header region. All of these components are now provided by blocks, making it straightforward for themers and developers to adjust, remove, or add to these components.</p>
|
||||
|
||||
<p><img src="http://farm3.static.flickr.com/2654/3928674449_8f443df1b3.jpg" alt="Togglable Open Atrium UI adjustments" /></p></div></description>
|
||||
<comments>http://developmentseed.org/blog/2009/sep/18/scaling-open-atrium-ui#comments</comments>
|
||||
<category domain="http://developmentseed.org/tags/drupal">Drupal</category>
|
||||
<category domain="http://developmentseed.org/tags/interface">interface</category>
|
||||
<category domain="http://developmentseed.org/tags/open-atrium">open atrium</category>
|
||||
<category domain="http://developmentseed.org/tags/usability">usability</category>
|
||||
<category domain="http://developmentseed.org/channel/drupal-planet">Drupal planet</category>
|
||||
<pubDate>Fri, 18 Sep 2009 14:31:23 +0000</pubDate>
|
||||
<dc:creator>Development Seed</dc:creator>
|
||||
<guid isPermaLink="false">966 at http://developmentseed.org</guid>
|
||||
</item>
|
||||
</channel>
|
||||
</rss>
|
295
sites/all/modules/feeds/tests/feeds/drupalplanet.rss2
Normal file
295
sites/all/modules/feeds/tests/feeds/drupalplanet.rss2
Normal file
@@ -0,0 +1,295 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<rss version="2.0">
|
||||
<channel>
|
||||
<title>drupal.org aggregator</title>
|
||||
<link>http://drupal.org/planet</link>
|
||||
<description>drupal.org - aggregated feeds in category Planet Drupal</description>
|
||||
<language>en</language>
|
||||
<item>
|
||||
<title>Adaptivethemes: Why I killed Node, may it RIP</title>
|
||||
<link>http://adaptivethemes.com/why-i-killed-node-may-it-rip</link>
|
||||
<description><p>Myself, like many others, have always had an acrimonious relationship with the word &#8220;node&#8221;. It didn&#8217;t exactly get off to a good start when node presented me with a rude &#8220;wtf&#8221; moment when we first met. Things only went down hill after that, node remaining aloof and abstract, without ever just coming out and telling me what it actually&nbsp;was.</p>
|
||||
<div class="og_rss_groups"></div></description>
|
||||
<pubDate>Fri, 23 Oct 2009 17:00:46 +0000</pubDate>
|
||||
</item>
|
||||
<item>
|
||||
<title>Midwestern Mac, LLC: Managing News - Revolutionary—not Evolutionary—Step for Drupal</title>
|
||||
<link>http://www.midwesternmac.com/blogs/geerlingguy/managing-news-revolutionary%E2%80%94not-evolutionary%E2%80%94step-drupal</link>
|
||||
<description><p>I noticed a post from the excellent folks over at <a href="http://developmentseed.org/">Development Seed</a> in the drupal.org Planet feed on a new Drupal installation profile they've been working on called <a href="http://managingnews.com/">Managing News</a>. Having tried (and loved) their Drupal-based installation of <a href="http://openatrium.com/">Open Atrium</a> (a great package for quick Intranets), I had pretty high expectations.</p>
|
||||
<p>Those expectations were pretty much blown out of the water; this install profile basically sets up a Drupal site (with all the Drupal bells and whistles) that is focused on one thing, and does it well: <strong>news aggregation via feeds</strong> (Atom, RSS).</p>
|
||||
<p class="rtecenter"><a href="http://catholicnewslive.com/"><img alt="Catholic News Live.com - Catholic News Aggregator" width="450" height="351" class="noborder" src="http://www.midwesternmac.com/sites/default/files/blogpost-images/catholic-news-live-screenshot.jpg" /></a></p>
|
||||
<p>I decided to quickly build out an aggregation site, <a href="http://catholicnewslive.com/">Catholic News Live</a>. The site took about 4 hours to set up, and it's already relatively customized to my needs. One thing I still don't know about is whether Drupal's cron will be able to handle the site after a few months and a few hundred more feeds... but we'll see!</p><p><a href="http://www.midwesternmac.com/blogs/geerlingguy/managing-news-revolutionary%E2%80%94not-evolutionary%E2%80%94step-drupal">read more</a></p>
|
||||
</description>
|
||||
<pubDate>Fri, 23 Oct 2009 04:58:15 +0000</pubDate>
|
||||
</item>
|
||||
<item>
|
||||
<title>Dries Buytaert: Eén using Drupal</title>
|
||||
<link>http://buytaert.net/een-using-drupal</link>
|
||||
<description>Eén (Dutch for 'one'), a public TV station reaching millions of people in Belgium, redesigned its website using <a href="http://drupal.org">Drupal</a>: see <a href="http://een.be">http://een.be</a>.
|
||||
|
||||
<div class="figure">
|
||||
<img src="http://buytaert.net/sites/buytaert.net/files/cache/drupal-een-500x500.jpg" alt="Een" style="border: 1px solid #ccc; padding: 4px;"/>
|
||||
|
||||
</div></description>
|
||||
<pubDate>Fri, 23 Oct 2009 01:30:55 +0000</pubDate>
|
||||
</item>
|
||||
<item>
|
||||
<title>Open Em Space: Em Space's top Drupal 6 modules (that aren't always in the limelight)</title>
|
||||
<link>http://open.emspace.com.au/article/em-spaces-top-drupal-6-modules-arent-always-limelight</link>
|
||||
<description><div class="field field-type-filefield field-field-article-image">
|
||||
<div class="field-items">
|
||||
<div class="field-item odd">
|
||||
<img class="imagefield imagefield-field_article_image" width="200" height="200" alt="" src="http://open.emspace.com.au/sites/open.emspace.com.au/files/article_images/Drupal-logo-C366BDF9CE-seeklogo.com_.gif?1256197849" /> </div>
|
||||
</div>
|
||||
</div>
|
||||
<style type="text/css">
|
||||
h3 { text-decoration: underline; }
|
||||
div.item-container { border-top: 1px dotted #CCC; padding-bottom: 10px; }
|
||||
</style><p>
|
||||
<strong>Every development house and their dogs seem to have a 'TOP 10 DRUPAL MODULES</strong> - Absolute definitive version!!' blog post somewhere at the minute, and they all tend to be fairly similar - 'Views, CCK, Image' etc... </p>
|
||||
<p>We have decided to go a different route, and do our own summary of drupal modules (and combinations) that we use all the time, which you may not have used before.</p></description>
|
||||
<pubDate>Fri, 23 Oct 2009 00:00:54 +0000</pubDate>
|
||||
</item>
|
||||
<item>
|
||||
<title>NodeOne: The new Feeds module</title>
|
||||
<link>http://nodeone.se/blogg/drupal/new-feeds-module</link>
|
||||
<description><p>How do you aggregate feeds into a <a href="/drupal">Drupal website</a>? Or import data from other sources like a CSV document? The answer to this is of course <a href="http://drupal.org/project/feedapi">FeedAPI</a>! Or is it?</p>
|
||||
<p>FeedAPI has for long been the mainstream solution for this kind of problems. And a really good one! But very recently the guys over at <a href="http://developmentseed.org/">Development Seed</a> (the creators and maintainers of FeedAPI) released a new alpha version of the <a href="http://drupal.org/project/feeds">Feeds</a> module. I haven't had time to play around with it too much yet. But it seems to be very promising. The dependency of <a href="http://drupal.org/project/ctools">CTools</a> and its plugin framework makes Feeds a lot more extensible than FeedAPI was. The code base and its API is more thought out and seems to be better prepared for scalability.</p>
|
||||
<p>I can't wait to use Feeds out in the wild! When I do so, I'll come back with a more in depth review.</p>
|
||||
<div class="watcher_node"><a href="/user/0/watcher/toggle/345?destination=drupalplanet%2Ffeed" class="watcher_node_toggle_watching_link" title="Watch posts to be notified when other users comment on them or the posts are changed">Du bevakar inte detta inlägg, klicka här för att börja bevaka</a></div></description>
|
||||
<pubDate>Thu, 22 Oct 2009 18:48:37 +0000</pubDate>
|
||||
</item>
|
||||
<item>
|
||||
<title>Geoff Hankerson: Bring Sanity to Your Web Site (& Your Life)</title>
|
||||
<link>http://geoffhankerson.com/node/110</link>
|
||||
<description><p> Only 9 seats left. Sign up at <a href="http://www.strategicit.org/sanity">http://www.strategicit.org/sanity</a></p>
|
||||
<p><img style="display: block; padding-bottom: 12px;" src="http://farm1.static.flickr.com/188/395226087_9002872142.jpg" border="0" alt="Sanily" /></p>
|
||||
<h6 style="font-size: 9px; padding-bottom: 12px;">Photo by <a href="http://www.flickr.com/photos/darkpatator/">http://www.flickr.com/photos/darkpatator/</a> / <a href="http://creativecommons.org/licenses/by/2.0/">CC BY 2.0</a></h6>
|
||||
<p>NO CHARGE :: Class Limited to First 15 Applicants</p>
|
||||
<p><a href="http://geoffhankerson.com/node/110" target="_blank">read more</a></p></description>
|
||||
<pubDate>Thu, 22 Oct 2009 18:19:10 +0000</pubDate>
|
||||
</item>
|
||||
<item>
|
||||
<title>Nick Vidal: HTTP and the Push Model</title>
|
||||
<link>http://nick.iss.im/2009/10/22/http-and-the-push-model/</link>
|
||||
<description><p>The Real-time Web seems to be the buzz of the moment, and there has been quite a debate comparing HTTP, XMPP and related technologies (Comet, Web sockets). Generally HTTP is associated with the Pull model, while XMPP is associated with the Push model. But it&#8217;s very well possible to design an architecture that follows the Push model using HTTP.</p>
|
||||
<p>Let&#8217;s see an example to illustrated the point: Nick and Debbie are friends and they have subscribed to each other&#8217;s feed to receive updates. Their feeds are hosted on different servers.</p>
|
||||
<p>In the Pull model, Nick has to poll Debbie&#8217;s server every time to check for updates from Debbie, and vice-versa.</p>
|
||||
<p>In the Push model, the flow goes something like this:</p>
|
||||
<ol>
|
||||
<li> Debbie publishes a new entry on her server (Push);</li>
|
||||
<li> Debbie&#8217;s server lets Nick&#8217;s server know that Debbie has published a new entry (Push);</li>
|
||||
<li> Nick polls his own server to receive updates (Pull).</li>
|
||||
</ol>
|
||||
<p>Notice that the second step is a Push implemented in HTTP. Nick&#8217;s server didn&#8217;t have to poll Debbie&#8217;s server every time to check for updates.</p><p><a href="http://nick.iss.im/2009/10/22/http-and-the-push-model/">read more</a></p>
|
||||
</description>
|
||||
<pubDate>Thu, 22 Oct 2009 16:50:31 +0000</pubDate>
|
||||
</item>
|
||||
<item>
|
||||
<title>Palantir: Pacific Northwest Drupal Summit</title>
|
||||
<link>http://www.palantir.net/blog/pacific-northwest-drupal-summit</link>
|
||||
<description><p>It's been a busy fall here in the Pacific Northwest. In the last two months the area has hosted no less than four Drupal events. </p>
|
||||
<p>Things kicked off in late September with <a href="http://drupalcamp.northstudio.com/">DrupalCamp Victoria</a>. A couple weeks later was the Seattle Drupal Clinic, an event specifically focused at introducing new users to Drupal. Two weeks after that was <a href="http://drupalpdx.org/camp09/">DrupalCamp Portland</a>, and finally last week a group of Drupal luminaries gathered in Vancouver for the <a href="http://groups.drupal.org/node/24642">Drupal Contrib Code Sprint</a>, which resulted in <a href="http://drupal4hu.com/node/223">usable versions of Views and Coder for Drupal 7</a>! </p>
|
||||
<p><img src="http://www.palantir.net/sites/default/files/pnw-summit-logo.png" alt="Pacific Northwest Drupal Summit" align="right" />Phew, that's a lot of Drupal! The best part is it's not over yet, Seattle will close off the Drupal season with the <a href="http://pnwdrupalsummit.org/">Pacific Northwest Drupal Summit</a> this coming weekend, October 24-25.</p>
|
||||
<p><a href="http://www.palantir.net/blog/pacific-northwest-drupal-summit" target="_blank">read more</a></p></description>
|
||||
<pubDate>Thu, 22 Oct 2009 16:44:15 +0000</pubDate>
|
||||
</item>
|
||||
<item>
|
||||
<title>Stéphane Corlosquet: Produce and Consume Linked Data with Drupal!</title>
|
||||
<link>http://openspring.net/blog/2009/10/22/produce-and-consume-linked-data-with-drupal</link>
|
||||
<description><p><a href="http://openspring.net/sites/openspring.net/files/corl-etal-2009iswc_logo.png"><img style="float:right" src="http://openspring.net/sites/openspring.net/files/corl-etal-2009iswc_logo_thumb.png" alt="Drupal in the Linked Data Cloud" /></a><em>Produce and Consume Linked Data with Drupal!</em> is the title of the paper I will be presenting next week at the <a href="http://iswc2009.semanticweb.org/">8th International Semantic Web Conference (ISWC 2009)</a> in Washington, DC. I wrote it at the end of M.Sc. at <a href="http://www.deri.ie/">DERI</a>, in partnership with the <a href="http://hms.harvard.edu/">Harvard Medical School</a> and the <a href="http://www.massgeneral.org/">Massachusetts General Hospital</a> which is where I am <a href="http://openspring.net/blog/2009/09/19/one-way-ticket-to-boston">now working</a>.</p>
|
||||
<p>It presents the approach for using Drupal (or any other CMS) as a Linked Data producer and consumer platform. Some part of this approach were used in the <a href="http://drupal.org/node/493030">RDF API</a> that Dries committed a few days ago to Drupal core. I have attached <a href="http://openspring.net/sites/openspring.net/files/corl-etal-2009iswc.pdf">full paper</a>, and here is the abstract:</p><p><a href="http://openspring.net/blog/2009/10/22/produce-and-consume-linked-data-with-drupal">read more</a></p>
|
||||
</description>
|
||||
<pubDate>Thu, 22 Oct 2009 13:03:26 +0000</pubDate>
|
||||
</item>
|
||||
<item>
|
||||
<title>Dries Buytaert: Lucas Arts using Drupal</title>
|
||||
<link>http://buytaert.net/lucas-arts-using-drupal</link>
|
||||
<description>Lucas Arts, the video game company of George Lucas, launched a stunning <a href="http://drupal.org">Drupal</a> site for its upcoming MMORPG: <em>Star Wars, The Old Republic</em>. Check out the website at: <a href="http://www.swtor.com">http://www.swtor.com</a>. <em>The Force is strong with Drupal!</em>
|
||||
|
||||
<div class="figure">
|
||||
<img src="http://buytaert.net/sites/buytaert.net/files/cache/drupal-star-wars-game-500x500.jpg" alt="Star wars game" style="border: 1px solid #ccc; padding: 4px;"/>
|
||||
|
||||
</div>
|
||||
|
||||
PS: in 2006, the <a href="http://lullabot.com">Lullabots</a> and myself visited Skywalker Ranch, the private workplace of George Lucas, to get <a href="http://buytaert.net/album/san-francisco-2006/light-saber-2">some lightsaber training</a>.</description>
|
||||
<pubDate>Thu, 22 Oct 2009 11:40:31 +0000</pubDate>
|
||||
</item>
|
||||
<item>
|
||||
<title>Janak Singh: Drupal Custom Pager navigation</title>
|
||||
<link>http://janaksingh.com/blog/drupal-custom-pager-navigation-73</link>
|
||||
<description><!-- google_ad_section_start --><p>For my portfolio site I wanted each image node (CCK + imagefield) to have a thumbnail strip of 10 or so images from the same category. Very simple stuff I thought. A quick search and I came across fantastic module called <a href="http://drupal.org/project/custom_pagers">Custom Pagers</a> by <a href="http://drupal.org/user/16496">Eaton</a>. This highly flexible module provides you a <b>Next</b> and <b>Previous</b> custom pager that you can display in your node pages. This was perfect for blog nodes but I wanted more control over the pager and I only wanted nodes to be pulled out from the same taxonomy term as the node being displayed.. fairly simple idea:</p>
|
||||
<!-- google_ad_section_end --></description>
|
||||
<pubDate>Thu, 22 Oct 2009 11:13:17 +0000</pubDate>
|
||||
</item>
|
||||
<item>
|
||||
<title>Ryan Szrama: Ubercart 2.0 and the Ubercore Initiative</title>
|
||||
<link>http://www.bywombats.com/blog/10-22-2009/ubercart-20-and-ubercore-initiative</link>
|
||||
<description><p>With high spirits and much excitement for the future, Lyle and I polished up and released <a href="http://drupal.org/node/610966">Ubercart 2.0</a> today. Thanks to all those who took notice, and an even bigger thanks to the dozens of contributors who made the release a reality.</p>
|
||||
<p>Features of the release should come as no surprise, as most people have been using Ubercart 2.x for some time based on the project's <a href="http://drupal.org/project/usage/ubercart">usage statistics</a> and personal experience. In the final days, we did iron out issues related to file downloads, role promotions, product kits, and Views integration. We also paved the way for smoother European use in conjunction with the <a href="http://drupal.org/project/uc_vat">UC2 VAT</a> project.</p>
|
||||
<p>For those that are interested, continue reading for my reflections on the state of the Ubercart development process and code, including a community effort to realign both of these things on Drupal 7 with the <a href="http://d7uc.org">Drupal 7 Ubercore Initiative</a>.</p>
|
||||
<p>The teaser... Ubercart, D7, Small core influence -> Ubercore (or, <a href="http://d7uc.org">d7uc</a>).</p>
|
||||
<p><a href="http://www.bywombats.com/blog/10-22-2009/ubercart-20-and-ubercore-initiative" target="_blank">read more</a></p></description>
|
||||
<pubDate>Thu, 22 Oct 2009 04:38:38 +0000</pubDate>
|
||||
</item>
|
||||
<item>
|
||||
<title>Lullabot: Drupal Voices 66: Jimmy Berry on the Drupal Test Framework</title>
|
||||
<link>http://feedproxy.google.com/~r/lullabot-all/~3/Nvm2rEBEhN4/drupal-voices-66-jimmy-berry-drupal-test-framework</link>
|
||||
<description><!--paging_filter--><p><a href="http://boombatower.com/">Jimmy Berry</a> (aka <a href="http://drupal.org/user/214218">boombatower</a>) is the Drupal 7 Testing Subsystem Maintainer and maintainer of <a href="http://testing.drupal.org">testing.drupal.org.</a> Testing has become an integral part of the core Drupal development process as Drupal 7 has adopted a test-driven development model, which <a href="http://buytaert.net/drupal-7-testing-status-update-and-next-steps">Dries explains here.</a> </p>
|
||||
<p>So Jimmy has picked up the testing torch for Drupal, and talks about his involvement with the <a href="http://drupal.org/project/simpletest">SimpleTest framework</a> and helping getting it into Drupal core, how that's changed the core development process, and what it could mean if also applied to contributed modules as well.</p>
|
||||
<p><a href="http://www.lullabot.com/audio/download/635/DrupalVoices066.mp3">Download Audio</a></p></description>
|
||||
<pubDate>Thu, 22 Oct 2009 03:46:07 +0000</pubDate>
|
||||
</item>
|
||||
<item>
|
||||
<title>Dries Buytaert: Robbie Williams using Drupal</title>
|
||||
<link>http://buytaert.net/robbie-williams-using-drupal</link>
|
||||
<description><p>A couple of weeks ago, Robbie Williams made <a href="http://www.youtube.com/watch?v=FTJfNP1VEnw">his comeback</a> on
|
||||
British television music talent show The X Factor, where he performed his new single "Bodies" for the first time live.</p>
|
||||
|
||||
<p>With his comeback also comes a website refresh using <a href="http://drupal.org">Drupal</a>: see <a href="http://robbiewilliams.com">http://robbiewilliams.com</a>. The site was developed by an Acquia partner based in the UK.</p>
|
||||
|
||||
|
||||
<div class="figure">
|
||||
<img src="http://buytaert.net/sites/buytaert.net/files/cache/drupal-robbie-williams-500x500.jpg" alt="Robbie williams" style="border: 1px solid #ccc; padding: 4px;"/>
|
||||
|
||||
</div>
|
||||
|
||||
<object width="500" height="392"><param name="movie" value="http://www.youtube.com/v/Q5uKa1bDtsk&hl=en&fs=1&"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/Q5uKa1bDtsk&hl=en&fs=1&" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="500" height="392"></embed></object></description>
|
||||
<pubDate>Thu, 22 Oct 2009 02:01:49 +0000</pubDate>
|
||||
</item>
|
||||
<item>
|
||||
<title>Growing Venture Solutions: Introducing Token Starterkit - Simple Introduction to Creating your own Drupal Tokens</title>
|
||||
<link>http://growingventuresolutions.com/blog/introducing-token-starterkit-simple-introduction-creating-your-own-drupal-tokens</link>
|
||||
<description><p>There seems to be a new pattern emerging in Drupal and I want to let you know that the <a href="http://drupal.org/project/token">Token</a> module has joined the bandwagon with a "Token Starter Kit"</p>
|
||||
<h3>History of the Starter Kit in Drupal: Zen Theming</h3>
|
||||
<p>When the Zen project started it's goal was to be a really solid base HTML theme with tons of comments in the templates so that a new themer could take it, modify it, and end up with a great theme. Unfortunately, that second step of modifying it meant that people ran into all sorts of support issues that were hard to debug and they were in trouble when a new version of Zen came out - they weren't really running Zen any more.</p>
|
||||
<h3>How to use the Token Starter Kit</h3>
|
||||
<p>The Token Starter Kit is meant to be similarly easy for folks to use. The idea is that if you just open up the token module itself and start adding tokens then you are "hacking a contrib" (modifying it) and you will have to remember to make those changes again when you upgrade. Bad news. It's also not particularly simple to understand how the module works (it's got includes, and hooks, oh my!).</p><p><a href="http://growingventuresolutions.com/blog/introducing-token-starterkit-simple-introduction-creating-your-own-drupal-tokens">read more</a></p>
|
||||
</description>
|
||||
<pubDate>Wed, 21 Oct 2009 23:16:12 +0000</pubDate>
|
||||
</item>
|
||||
<item>
|
||||
<title>Alldrupalthemes: Does spam thrive during economic decline?</title>
|
||||
<link>http://www.alldrupalthemes.com/drupal-blog/does-spam-thrive-during-economic-decline</link>
|
||||
<description><p>Are laid off IT workers discovering that sending spam is easier than getting a job these days? It sure seems that way, even with mollom running on all forms around a hundred spam comments get through every week, and they seem to get more clever every time.</p>
|
||||
<p>I just found the following comment below my review of the <em>Drupal 6 Javascript and jQuery</em> book:</p>
|
||||
<p><strong><em>Submitted by san diego real estate (not verified) on Wed, 10/21/2009 - 18:55.</em><br />
|
||||
The only reason why I like this book is that this book developers deep into the usage of jQuery in themes and modules and there is interesting stuff in there for developers of any experience.</strong></p>
|
||||
<p>I can understand mollom didn't get that message because even I thought it was a real comment. I was much surprised to</p>
|
||||
<p><a href="http://www.alldrupalthemes.com/drupal-blog/does-spam-thrive-during-economic-decline" target="_blank">read more</a></p></description>
|
||||
<pubDate>Wed, 21 Oct 2009 22:53:39 +0000</pubDate>
|
||||
</item>
|
||||
<item>
|
||||
<title>Tag1 Consulting: Tag1 Now Hiring Interns</title>
|
||||
<link>http://tag1consulting.com/blog/tag1-now-hiring-interns</link>
|
||||
<description><p>At the beginning of 2009, I was hired by Tag1 Consulting as Jeremy Andrews' full time partner. A decidedly questionable decision on his part, but a great change for me! I used to work at the Open Source Lab at Oregon State University and I am currently the sysadmin for drupal.org. Working at the OSL and drupal.org spoiled me, I'll be completely honest about that. I got used to working with interesting new technologies and consistently pushing the limits of my knowledge.</p>
|
||||
<p><a href="http://tag1consulting.com/blog/tag1-now-hiring-interns">read more</a></p></description>
|
||||
<pubDate>Wed, 21 Oct 2009 21:52:02 +0000</pubDate>
|
||||
</item>
|
||||
<item>
|
||||
<title>Greg Holsclaw: Hook on Drush for Windows</title>
|
||||
<link>http://www.tech-wanderings.com/drush-for-windows</link>
|
||||
<description><p>So I have heard of <a href="http://drupal.org/project/drush">Drush</a> for years now, saw my first demo at the Boston DrupalCon but since I do all my dev work on a Windows machine I didn't catch the Drush wave (I kept hearing it was *nix only).</p>
|
||||
<p>It has always been in the back of my mind to keep looking back into Drush, but somehow I missed the major 2.0 update in June and that it works on Windows now. When I saw <a href="http://morten.dk/blog/got-crush-drush">Morton's Mac Drush post</a> and revisited my Windows issue, and now I am a convert.</p>
|
||||
<p>Already there is an <a href="http://drupal.org/node/594744">install guide</a> written two week ago that I have verified works perfectly for my Vista Business 64 bit machine. Drush is up and running on my dev system now and I am already addicted.</p>
|
||||
<p><a href="http://www.tech-wanderings.com/drush-for-windows" target="_blank">read more</a></p></description>
|
||||
<pubDate>Wed, 21 Oct 2009 20:00:34 +0000</pubDate>
|
||||
</item>
|
||||
<item>
|
||||
<title>Geoff Hankerson: Installing Aegir Hosting System on OSX 10.6 with MAMP</title>
|
||||
<link>http://geoffhankerson.com/node/109</link>
|
||||
<description><p>Cross posted at <a href="http://groups.drupal.org/node/30270" title="http://groups.drupal.org/node/30270">http://groups.drupal.org/node/30270</a>.</p>
|
||||
<p>Aegir install on OSX Snow Leopard</p>
|
||||
<p>Aegir install instructions are fantastic if you run Debian/Ubuntu Linux. Some of the steps for OS X are a quite different</p>
|
||||
<p><a href="http://geoffhankerson.com/node/109" target="_blank">read more</a></p></description>
|
||||
<pubDate>Wed, 21 Oct 2009 19:01:59 +0000</pubDate>
|
||||
</item>
|
||||
<item>
|
||||
<title>Development Seed: Announcing Managing News: A Pluggable News + Data Aggregator</title>
|
||||
<link>http://developmentseed.org/blog/2009/oct/21/announcing-managing-news-pluggable-news-data-aggregator</link>
|
||||
<description><div class="field field-type-text field-field-subtitle">
|
||||
<div class="field-items">
|
||||
<div class="field-item odd">
|
||||
<p>From a daily news reader, to a platform for election monitoring in Afghanistan or swine flu preparedness in the United States</p> </div>
|
||||
</div>
|
||||
</div>
|
||||
<div class='node-body'><p>Managing News is a pluggable, open source news and data aggregator with visualization and workflow tools that's highly customizable and extensible. The code is now in open beta and is available for download on <a href="http://www.managingnews.com/download">www.managingnews.com/download</a>.</p>
|
||||
|
||||
<p><img src="http://farm3.static.flickr.com/2463/4031496689_0dd24a5705.jpg" alt="http://managingnews.com" /></p><p><a href="http://developmentseed.org/blog/2009/oct/21/announcing-managing-news-pluggable-news-data-aggregator">read more</a></p>
|
||||
</description>
|
||||
<pubDate>Wed, 21 Oct 2009 17:14:57 +0000</pubDate>
|
||||
</item>
|
||||
<item>
|
||||
<title>Good Old Drupal: Co-Maintainers Wanted!</title>
|
||||
<link>http://goodold.se/blog/tech/co-maintainer-wanted</link>
|
||||
<description><p>The list of modules that I maintain has become quite long, and in the beginning of next year I'll have a little daughter (if the nurse guessed right on the gender). So the time that I have for being a good maintainer will be very limited.</p>
|
||||
<p>If you feel that you'd like to help maintain any of the following modules, I would be very grateful!</p>
|
||||
<ul>
|
||||
<li><a href="http://drupal.org/project/cobalt">Cobalt</a> </li>
|
||||
<li><a href="http://drupal.org/project/nodeformcols">Node form columns</a></li>
|
||||
<li><a href="http://drupal.org/project/oauth_common">OAuth Common</a></li>
|
||||
<li><a href="http://drupal.org/project/services_oauth">Services OAuth</a></li>
|
||||
<li><a href="http://drupal.org/project/simple_geo">Simple Geo</a></li>
|
||||
<li><a href="http://drupal.org/project/jsonrpc_server">JSONRPC Server</a></li>
|
||||
<li><a href="http://drupal.org/project/query_builder">Query builder</a></li>
|
||||
</ul>
|
||||
<p><strong>Modules not on DO</strong></p>
|
||||
<ul>
|
||||
<li><a href="http://github.com/hugowetterberg/services_oop">Services OOP</a></li>
|
||||
<li><a href="http://github.com/hugowetterberg/cssdry">CSS DRY</a></li>
|
||||
</ul>
|
||||
<p>Experience of using <strong>git</strong>, or the willingness to learn, is kind of a requirement, as all my development is done with git. The alternative is a patch-based workflow.</p></description>
|
||||
<pubDate>Wed, 21 Oct 2009 06:36:30 +0000</pubDate>
|
||||
</item>
|
||||
<item>
|
||||
<title>Lullabot: Drupal Voices 65: Konstantin Kafer on Optimizing Javascript and CSS</title>
|
||||
<link>http://feedproxy.google.com/~r/lullabot-all/~3/EcYAQCa5xyE/drupal-voices-65-konstantin-kafer-optimizing-javascript-and-css</link>
|
||||
<description><!--paging_filter--><p><a href="http://kkaefer.com/">Konstantin Käfer</a> (aka <a href="http://drupal.org/user/14572">kkafer</a>) gives an overview of his Drupalcon Paris talk on optimizing the front-end Javascript and CSS -- including some <a href="http://developer.yahoo.com/yslow/">YSlow</a> tips.</p>
|
||||
<p>Konstantin also talks a bit about his <a href="http://drupal.org/project/sf_cache">Support File Cache</a> module that allows additional front-end optimizations by allowing you to control the bundling of CSS and Javascript files.</p>
|
||||
<p>He also talks a bit about the <a href="http://frontenddrupal.com/">Front-End Drupal</a> that he co-wrote with <a href="http://www.lullabot.com/drupal-voices/drupal-voices-60-emma-jane-hogbin-theming-and-bazaar-version-control">Emma Jane Hogbin.</a></p>
|
||||
<p>Finally, Konstantin talks a bit about some of his favorite changes in Drupal 7.</p>
|
||||
<p><a href="http://www.lullabot.com/audio/download/633/DrupalVoices065.mp3">Download Audio</a></p></description>
|
||||
<pubDate>Wed, 21 Oct 2009 03:09:59 +0000</pubDate>
|
||||
</item>
|
||||
<item>
|
||||
<title>Morten.dk - The King of Denmark: got a crush on drush</title>
|
||||
<link>http://morten.dk/blog/got-crush-drush</link>
|
||||
<description><div class="fieldgroup group-image">
|
||||
|
||||
|
||||
<div class="content">
|
||||
<div class="field-image-default">
|
||||
|
||||
|
||||
|
||||
|
||||
<img src="http://morten.dk/sites/morten.dk/files/imagecache/20_20_crop/drushlove.jpg" alt="" title="Drupal shell geekyness" class="imagecache imagecache-20_20_crop imagecache-default imagecache-20_20_crop_default" width="20" height="20" />
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<p>How I got drush to work on my macosx with mamp pro, and still my illustrator &amp; photoshop works fine, how to do magick stuff with the terminal with out <a href="/sites/morten.dk/files/images/argh.jpg" class="fancybox">deleting to much</a>, and learning not to use my <a href="http://www.wacom.com/bamboo/bamboo_fun.php">pen</a> to navigate my desktop...</p></description>
|
||||
<pubDate>Wed, 21 Oct 2009 01:56:57 +0000</pubDate>
|
||||
</item>
|
||||
<item>
|
||||
<title>Affinity Bridge: Drupal7 Contrib Module Upgrade Sprint</title>
|
||||
<link>http://affinitybridge.com/blog/drupal7-contrib-module-upgrade-sprint</link>
|
||||
<description><p>This past weekend was the <a href="http://groups.drupal.org/node/24642">Drupal7 Contrib Module Upgrade Sprint</a> that <a href="http://drupal.org/user/9446">K&aacute;roly N&eacute;gyesi</a> (aka chx) organized at the <a title="Now Public" href="http://www.nowpublic.com/">NowPublic</a> offices in Vancouver. I spent a good part of Saturday there, helped out with coaching the one brave beginner who turned up to learn some of the tools for helping out in the community. Otherwise, after a bit of a rough start, the devs all hunkered down and made some Drupal magic, upgrading super important things like Views, Panels, database stuff, and various other bits and pieces of modules and themes.</p>
|
||||
<p><a title="D7 contrib sprint by arianek, on Flickr" href="http://www.flickr.com/photos/arianek/4023847590/"></a></p>
|
||||
<p style="text-align: center;"><img src="http://farm3.static.flickr.com/2629/4023847590_98f25f162f.jpg" alt="D7 contrib sprint" width="500" height="375" /></p>
|
||||
<p> &lt;!--break-->
|
||||
</p><p><a href="http://affinitybridge.com/blog/drupal7-contrib-module-upgrade-sprint">read more</a></p>
|
||||
</description>
|
||||
<pubDate>Tue, 20 Oct 2009 23:43:18 +0000</pubDate>
|
||||
</item>
|
||||
<item>
|
||||
<title>Do it With Drupal: Speaker Spotlight: Earl Miles</title>
|
||||
<link>http://feedproxy.google.com/~r/DoItWithDrupal/~3/Thij4pd2cBE/speaker-spotlight-earl-miles</link>
|
||||
<description><p><img src="http://www.doitwithdrupal.com/files/imagecache/120square/biopics/earl-headshot2.jpg" alt="earl-headshot2" title="earl-headshot2" class="image-right" height="120" width="120" />We are excited to announce that <a href="http://www.angrydonuts.com/">Earl Miles</a> will be returning to <a href="http://www.doitwithdrupal.com/">Do It With Drupal</a>! It is no exaggeration to say that Earl Miles single-handedly revolutionized the <a href="http://drupal.org/">Drupal</a> community when he released the <a href="http://drupal.org/project/views">Views</a> module late in 2005.</p>
|
||||
<p><a href="http://www.doitwithdrupal.com/blog/speaker-spotlight-earl-miles" target="_blank">read more</a></p><p><a href="http://feedproxy.google.com/~r/DoItWithDrupal/~3/Thij4pd2cBE/speaker-spotlight-earl-miles">read more</a></p>
|
||||
</description>
|
||||
<pubDate>Tue, 20 Oct 2009 22:06:32 +0000</pubDate>
|
||||
</item>
|
||||
</channel>
|
||||
</rss>
|
36
sites/all/modules/feeds/tests/feeds/earthquake-georss.atom
Normal file
36
sites/all/modules/feeds/tests/feeds/earthquake-georss.atom
Normal file
@@ -0,0 +1,36 @@
|
||||
<?xml version="1.0"?>
|
||||
<feed xmlns="http://www.w3.org/2005/Atom" xmlns:georss="http://www.georss.org/georss">
|
||||
<updated>2010-09-07T21:45:39Z</updated>
|
||||
<title>USGS M2.5+ Earthquakes</title>
|
||||
<subtitle>Real-time, worldwide earthquake list for the past day</subtitle>
|
||||
<link rel="self" href="http://earthquake.usgs.gov/earthquakes/catalogs/1day-M2.5.xml"/>
|
||||
<link href="http://earthquake.usgs.gov/earthquakes/"/>
|
||||
<author><name>U.S. Geological Survey</name></author>
|
||||
<id>http://earthquake.usgs.gov/</id>
|
||||
<icon>/favicon.ico</icon>
|
||||
<entry><id>urn:earthquake-usgs-gov:ak:10076864</id><title>M 2.6, Central Alaska</title><updated>2010-09-07T21:08:45Z</updated><link rel="alternate" type="text/html" href="http://earthquake.usgs.gov/earthquakes/recenteqsww/Quakes/ak10076864.php"/><summary type="html"><![CDATA[<img src="http://earthquake.usgs.gov/images/globes/65_-150.jpg" alt="64.858°N 150.864°W" align="left" hspace="20" /><p>Tuesday, September 7, 2010 21:08:45 UTC<br>Tuesday, September 7, 2010 01:08:45 PM at epicenter</p><p><strong>Depth</strong>: 11.20 km (6.96 mi)</p>]]></summary><georss:point>64.8581 -150.8643</georss:point><georss:elev>-11200</georss:elev><category label="Age" term="Past hour"/></entry>
|
||||
<entry><id>urn:earthquake-usgs-gov:us:2010axbz</id><title>M 4.9, southern Qinghai, China</title><updated>2010-09-07T20:51:02Z</updated><link rel="alternate" type="text/html" href="http://earthquake.usgs.gov/earthquakes/recenteqsww/Quakes/us2010axbz.php"/><summary type="html"><![CDATA[<img src="http://earthquake.usgs.gov/images/globes/35_95.jpg" alt="33.329°N 96.332°E" align="left" hspace="20" /><p>Tuesday, September 7, 2010 20:51:02 UTC<br>Wednesday, September 8, 2010 04:51:02 AM at epicenter</p><p><strong>Depth</strong>: 47.50 km (29.52 mi)</p>]]></summary><georss:point>33.3289 96.3324</georss:point><georss:elev>-47500</georss:elev><category label="Age" term="Past hour"/></entry>
|
||||
<entry><id>urn:earthquake-usgs-gov:us:2010axbr</id><title>M 5.2, southern East Pacific Rise</title><updated>2010-09-07T19:54:29Z</updated><link rel="alternate" type="text/html" href="http://earthquake.usgs.gov/earthquakes/recenteqsww/Quakes/us2010axbr.php"/><link rel="related" type="application/cap+xml" href="http://earthquake.usgs.gov/earthquakes/catalogs/cap/us2010axbr" /><summary type="html"><![CDATA[<img src="http://earthquake.usgs.gov/images/globes/-55_-120.jpg" alt="53.198°S 118.068°W" align="left" hspace="20" /><p>Tuesday, September 7, 2010 19:54:29 UTC<br>Tuesday, September 7, 2010 11:54:29 AM at epicenter</p><p><strong>Depth</strong>: 15.50 km (9.63 mi)</p>]]></summary><georss:point>-53.1979 -118.0676</georss:point><georss:elev>-15500</georss:elev><category label="Age" term="Past day"/></entry>
|
||||
<entry><id>urn:earthquake-usgs-gov:us:2010axbp</id><title>M 5.0, South Island of New Zealand</title><updated>2010-09-07T19:49:57Z</updated><link rel="alternate" type="text/html" href="http://earthquake.usgs.gov/earthquakes/recenteqsww/Quakes/us2010axbp.php"/><summary type="html"><![CDATA[<img src="http://earthquake.usgs.gov/images/globes/-45_175.jpg" alt="43.437°S 172.590°E" align="left" hspace="20" /><p>Tuesday, September 7, 2010 19:49:57 UTC<br>Wednesday, September 8, 2010 07:49:57 AM at epicenter</p><p><strong>Depth</strong>: 1.00 km (0.62 mi)</p>]]></summary><georss:point>-43.4371 172.5902</georss:point><georss:elev>-1000</georss:elev><category label="Age" term="Past day"/></entry>
|
||||
<entry><id>urn:earthquake-usgs-gov:ak:10076859</id><title>M 3.1, Andreanof Islands, Aleutian Islands, Alaska</title><updated>2010-09-07T19:20:05Z</updated><link rel="alternate" type="text/html" href="http://earthquake.usgs.gov/earthquakes/recenteqsww/Quakes/ak10076859.php"/><link rel="related" type="application/cap+xml" href="http://earthquake.usgs.gov/earthquakes/catalogs/cap/ak10076859" /><summary type="html"><![CDATA[<img src="http://earthquake.usgs.gov/images/globes/50_-175.jpg" alt="51.526°N 175.798°W" align="left" hspace="20" /><p>Tuesday, September 7, 2010 19:20:05 UTC<br>Tuesday, September 7, 2010 10:20:05 AM at epicenter</p><p><strong>Depth</strong>: 22.20 km (13.79 mi)</p>]]></summary><georss:point>51.5259 -175.7979</georss:point><georss:elev>-22200</georss:elev><category label="Age" term="Past day"/></entry>
|
||||
<entry><id>urn:earthquake-usgs-gov:ci:10793957</id><title>M 2.7, Southern California</title><updated>2010-09-07T18:50:42Z</updated><link rel="alternate" type="text/html" href="http://earthquake.usgs.gov/earthquakes/recenteqsww/Quakes/ci10793957.php"/><summary type="html"><![CDATA[<img src="http://earthquake.usgs.gov/images/globes/35_-115.jpg" alt="35.717°N 116.960°W" align="left" hspace="20" /><p>Tuesday, September 7, 2010 18:50:42 UTC<br>Tuesday, September 7, 2010 11:50:42 AM at epicenter</p><p><strong>Depth</strong>: 7.80 km (4.85 mi)</p>]]></summary><georss:point>35.7170 -116.9597</georss:point><georss:elev>-7800</georss:elev><category label="Age" term="Past day"/></entry>
|
||||
<entry><id>urn:earthquake-usgs-gov:ci:10793909</id><title>M 3.5, Southern California</title><updated>2010-09-07T17:29:13Z</updated><link rel="alternate" type="text/html" href="http://earthquake.usgs.gov/earthquakes/recenteqsww/Quakes/ci10793909.php"/><link rel="related" type="application/cap+xml" href="http://earthquake.usgs.gov/earthquakes/catalogs/cap/ci10793909" /><summary type="html"><![CDATA[<img src="http://earthquake.usgs.gov/images/globes/35_-115.jpg" alt="35.727°N 116.957°W" align="left" hspace="20" /><p>Tuesday, September 7, 2010 17:29:13 UTC<br>Tuesday, September 7, 2010 10:29:13 AM at epicenter</p><p><strong>Depth</strong>: 4.50 km (2.80 mi)</p>]]></summary><georss:point>35.7273 -116.9567</georss:point><georss:elev>-4500</georss:elev><category label="Age" term="Past day"/></entry>
|
||||
<entry><id>urn:earthquake-usgs-gov:ak:10076853</id><title>M 3.1, Andreanof Islands, Aleutian Islands, Alaska</title><updated>2010-09-07T17:08:19Z</updated><link rel="alternate" type="text/html" href="http://earthquake.usgs.gov/earthquakes/recenteqsww/Quakes/ak10076853.php"/><link rel="related" type="application/cap+xml" href="http://earthquake.usgs.gov/earthquakes/catalogs/cap/ak10076853" /><summary type="html"><![CDATA[<img src="http://earthquake.usgs.gov/images/globes/50_-175.jpg" alt="51.090°N 176.131°W" align="left" hspace="20" /><p>Tuesday, September 7, 2010 17:08:19 UTC<br>Tuesday, September 7, 2010 08:08:19 AM at epicenter</p><p><strong>Depth</strong>: 16.50 km (10.25 mi)</p>]]></summary><georss:point>51.0899 -176.1314</georss:point><georss:elev>-16500</georss:elev><category label="Age" term="Past day"/></entry>
|
||||
<entry><id>urn:earthquake-usgs-gov:us:2010axa9</id><title>M 6.3, Fiji region</title><updated>2010-09-07T16:13:32Z</updated><link rel="alternate" type="text/html" href="http://earthquake.usgs.gov/earthquakes/recenteqsww/Quakes/us2010axa9.php"/><summary type="html"><![CDATA[<img src="http://earthquake.usgs.gov/images/globes/-15_-180.jpg" alt="15.869°S 179.261°W" align="left" hspace="20" /><p>Tuesday, September 7, 2010 16:13:32 UTC<br>Wednesday, September 8, 2010 04:13:32 AM at epicenter</p><p><strong>Depth</strong>: 10.00 km (6.21 mi)</p>]]></summary><georss:point>-15.8694 -179.2611</georss:point><georss:elev>-10000</georss:elev><category label="Age" term="Past day"/></entry>
|
||||
<entry><id>urn:earthquake-usgs-gov:us:2010axa7</id><title>M 5.3, Kyrgyzstan</title><updated>2010-09-07T15:41:42Z</updated><link rel="alternate" type="text/html" href="http://earthquake.usgs.gov/earthquakes/recenteqsww/Quakes/us2010axa7.php"/><link rel="related" type="application/cap+xml" href="http://earthquake.usgs.gov/earthquakes/catalogs/cap/us2010axa7" /><summary type="html"><![CDATA[<img src="http://earthquake.usgs.gov/images/globes/40_75.jpg" alt="39.476°N 73.825°E" align="left" hspace="20" /><p>Tuesday, September 7, 2010 15:41:42 UTC<br>Tuesday, September 7, 2010 09:41:42 PM at epicenter</p><p><strong>Depth</strong>: 39.70 km (24.67 mi)</p>]]></summary><georss:point>39.4759 73.8254</georss:point><georss:elev>-39700</georss:elev><category label="Age" term="Past day"/></entry>
|
||||
<entry><id>urn:earthquake-usgs-gov:ci:10793837</id><title>M 2.7, Southern California</title><updated>2010-09-07T13:07:21Z</updated><link rel="alternate" type="text/html" href="http://earthquake.usgs.gov/earthquakes/recenteqsww/Quakes/ci10793837.php"/><summary type="html"><![CDATA[<img src="http://earthquake.usgs.gov/images/globes/35_-115.jpg" alt="35.725°N 116.963°W" align="left" hspace="20" /><p>Tuesday, September 7, 2010 13:07:21 UTC<br>Tuesday, September 7, 2010 06:07:21 AM at epicenter</p><p><strong>Depth</strong>: 3.60 km (2.24 mi)</p>]]></summary><georss:point>35.7245 -116.9630</georss:point><georss:elev>-3600</georss:elev><category label="Age" term="Past day"/></entry>
|
||||
<entry><id>urn:earthquake-usgs-gov:nc:71451855</id><title>M 2.5, Northern California</title><updated>2010-09-07T13:06:56Z</updated><link rel="alternate" type="text/html" href="http://earthquake.usgs.gov/earthquakes/recenteqsww/Quakes/nc71451855.php"/><link rel="related" type="application/cap+xml" href="http://earthquake.usgs.gov/earthquakes/catalogs/cap/nc71451855" /><summary type="html"><![CDATA[<img src="http://earthquake.usgs.gov/images/globes/40_-120.jpg" alt="39.210°N 120.067°W" align="left" hspace="20" /><p>Tuesday, September 7, 2010 13:06:56 UTC<br>Tuesday, September 7, 2010 06:06:56 AM at epicenter</p><p><strong>Depth</strong>: 8.20 km (5.10 mi)</p>]]></summary><georss:point>39.2102 -120.0667</georss:point><georss:elev>-8200</georss:elev><category label="Age" term="Past day"/></entry>
|
||||
<entry><id>urn:earthquake-usgs-gov:us:2010axax</id><title>M 5.4, Fiji region</title><updated>2010-09-07T12:49:01Z</updated><link rel="alternate" type="text/html" href="http://earthquake.usgs.gov/earthquakes/recenteqsww/Quakes/us2010axax.php"/><link rel="related" type="application/cap+xml" href="http://earthquake.usgs.gov/earthquakes/catalogs/cap/us2010axax" /><summary type="html"><![CDATA[<img src="http://earthquake.usgs.gov/images/globes/-15_-175.jpg" alt="14.361°S 176.241°W" align="left" hspace="20" /><p>Tuesday, September 7, 2010 12:49:01 UTC<br>Wednesday, September 8, 2010 12:49:01 AM at epicenter</p><p><strong>Depth</strong>: 35.50 km (22.06 mi)</p>]]></summary><georss:point>-14.3605 -176.2406</georss:point><georss:elev>-35500</georss:elev><category label="Age" term="Past day"/></entry>
|
||||
<entry><id>urn:earthquake-usgs-gov:us:2010axat</id><title>M 5.0, Kuril Islands</title><updated>2010-09-07T11:30:52Z</updated><link rel="alternate" type="text/html" href="http://earthquake.usgs.gov/earthquakes/recenteqsww/Quakes/us2010axat.php"/><link rel="related" type="application/cap+xml" href="http://earthquake.usgs.gov/earthquakes/catalogs/cap/us2010axat" /><summary type="html"><![CDATA[<img src="http://earthquake.usgs.gov/images/globes/45_150.jpg" alt="45.858°N 151.311°E" align="left" hspace="20" /><p>Tuesday, September 7, 2010 11:30:52 UTC<br>Tuesday, September 7, 2010 11:30:52 PM at epicenter</p><p><strong>Depth</strong>: 30.30 km (18.83 mi)</p>]]></summary><georss:point>45.8582 151.3105</georss:point><georss:elev>-30300</georss:elev><category label="Age" term="Past day"/></entry>
|
||||
<entry><id>urn:earthquake-usgs-gov:mb:25757</id><title>M 2.7, western Montana</title><updated>2010-09-07T10:08:26Z</updated><link rel="alternate" type="text/html" href="http://earthquake.usgs.gov/earthquakes/recenteqsww/Quakes/mb25757.php"/><summary type="html"><![CDATA[<img src="http://earthquake.usgs.gov/images/globes/45_-110.jpg" alt="44.951°N 111.742°W" align="left" hspace="20" /><p>Tuesday, September 7, 2010 10:08:26 UTC<br>Tuesday, September 7, 2010 04:08:26 AM at epicenter</p><p><strong>Depth</strong>: 5.70 km (3.54 mi)</p>]]></summary><georss:point>44.9508 -111.7423</georss:point><georss:elev>-5700</georss:elev><category label="Age" term="Past day"/></entry>
|
||||
<entry><id>urn:earthquake-usgs-gov:ak:10076821</id><title>M 2.7, Andreanof Islands, Aleutian Islands, Alaska</title><updated>2010-09-07T08:40:35Z</updated><link rel="alternate" type="text/html" href="http://earthquake.usgs.gov/earthquakes/recenteqsww/Quakes/ak10076821.php"/><link rel="related" type="application/cap+xml" href="http://earthquake.usgs.gov/earthquakes/catalogs/cap/ak10076821" /><summary type="html"><![CDATA[<img src="http://earthquake.usgs.gov/images/globes/50_-175.jpg" alt="51.201°N 176.194°W" align="left" hspace="20" /><p>Tuesday, September 7, 2010 08:40:35 UTC<br>Monday, September 6, 2010 11:40:35 PM at epicenter</p><p><strong>Depth</strong>: 20.10 km (12.49 mi)</p>]]></summary><georss:point>51.2010 -176.1935</georss:point><georss:elev>-20100</georss:elev><category label="Age" term="Past day"/></entry>
|
||||
<entry><id>urn:earthquake-usgs-gov:us:2010axas</id><title>M 4.9, southwest of Sumatra, Indonesia</title><updated>2010-09-07T07:22:13Z</updated><link rel="alternate" type="text/html" href="http://earthquake.usgs.gov/earthquakes/recenteqsww/Quakes/us2010axas.php"/><summary type="html"><![CDATA[<img src="http://earthquake.usgs.gov/images/globes/-5_105.jpg" alt="7.128°S 103.263°E" align="left" hspace="20" /><p>Tuesday, September 7, 2010 07:22:13 UTC<br>Tuesday, September 7, 2010 02:22:13 PM at epicenter</p><p><strong>Depth</strong>: 35.00 km (21.75 mi)</p>]]></summary><georss:point>-7.1275 103.2631</georss:point><georss:elev>-35000</georss:elev><category label="Age" term="Past day"/></entry>
|
||||
<entry><id>urn:earthquake-usgs-gov:nc:71451750</id><title>M 3.1, Central California</title><updated>2010-09-07T06:59:25Z</updated><link rel="alternate" type="text/html" href="http://earthquake.usgs.gov/earthquakes/recenteqsww/Quakes/nc71451750.php"/><link rel="related" type="application/cap+xml" href="http://earthquake.usgs.gov/earthquakes/catalogs/cap/nc71451750" /><summary type="html"><![CDATA[<img src="http://earthquake.usgs.gov/images/globes/35_-120.jpg" alt="36.561°N 121.068°W" align="left" hspace="20" /><p>Tuesday, September 7, 2010 06:59:25 UTC<br>Monday, September 6, 2010 11:59:25 PM at epicenter</p><p><strong>Depth</strong>: 8.40 km (5.22 mi)</p>]]></summary><georss:point>36.5605 -121.0677</georss:point><georss:elev>-8400</georss:elev><category label="Age" term="Past day"/></entry>
|
||||
<entry><id>urn:earthquake-usgs-gov:ak:10076797</id><title>M 4.2, Kodiak Island region, Alaska</title><updated>2010-09-07T05:54:04Z</updated><link rel="alternate" type="text/html" href="http://earthquake.usgs.gov/earthquakes/recenteqsww/Quakes/ak10076797.php"/><link rel="related" type="application/cap+xml" href="http://earthquake.usgs.gov/earthquakes/catalogs/cap/ak10076797" /><summary type="html"><![CDATA[<img src="http://earthquake.usgs.gov/images/globes/55_-150.jpg" alt="56.980°N 151.666°W" align="left" hspace="20" /><p>Tuesday, September 7, 2010 05:54:04 UTC<br>Monday, September 6, 2010 09:54:04 PM at epicenter</p><p><strong>Depth</strong>: 25.00 km (15.53 mi)</p>]]></summary><georss:point>56.9797 -151.6661</georss:point><georss:elev>-25000</georss:elev><category label="Age" term="Past day"/></entry>
|
||||
<entry><id>urn:earthquake-usgs-gov:ak:10076786</id><title>M 3.4, Andreanof Islands, Aleutian Islands, Alaska</title><updated>2010-09-07T04:43:36Z</updated><link rel="alternate" type="text/html" href="http://earthquake.usgs.gov/earthquakes/recenteqsww/Quakes/ak10076786.php"/><link rel="related" type="application/cap+xml" href="http://earthquake.usgs.gov/earthquakes/catalogs/cap/ak10076786" /><summary type="html"><![CDATA[<img src="http://earthquake.usgs.gov/images/globes/50_-175.jpg" alt="51.098°N 176.164°W" align="left" hspace="20" /><p>Tuesday, September 7, 2010 04:43:36 UTC<br>Monday, September 6, 2010 07:43:36 PM at epicenter</p><p><strong>Depth</strong>: 16.90 km (10.50 mi)</p>]]></summary><georss:point>51.0975 -176.1635</georss:point><georss:elev>-16900</georss:elev><category label="Age" term="Past day"/></entry>
|
||||
<entry><id>urn:earthquake-usgs-gov:ak:10076776</id><title>M 3.6, Andreanof Islands, Aleutian Islands, Alaska</title><updated>2010-09-07T03:43:43Z</updated><link rel="alternate" type="text/html" href="http://earthquake.usgs.gov/earthquakes/recenteqsww/Quakes/ak10076776.php"/><summary type="html"><![CDATA[<img src="http://earthquake.usgs.gov/images/globes/50_-175.jpg" alt="51.471°N 176.667°W" align="left" hspace="20" /><p>Tuesday, September 7, 2010 03:43:43 UTC<br>Monday, September 6, 2010 06:43:43 PM at epicenter</p><p><strong>Depth</strong>: 39.00 km (24.23 mi)</p>]]></summary><georss:point>51.4706 -176.6674</georss:point><georss:elev>-39000</georss:elev><category label="Age" term="Past day"/></entry>
|
||||
<entry><id>urn:earthquake-usgs-gov:us:2010axaf</id><title>M 5.3, southern Iran</title><updated>2010-09-07T02:11:07Z</updated><link rel="alternate" type="text/html" href="http://earthquake.usgs.gov/earthquakes/recenteqsww/Quakes/us2010axaf.php"/><link rel="related" type="application/cap+xml" href="http://earthquake.usgs.gov/earthquakes/catalogs/cap/us2010axaf" /><summary type="html"><![CDATA[<img src="http://earthquake.usgs.gov/images/globes/25_55.jpg" alt="27.147°N 54.588°E" align="left" hspace="20" /><p>Tuesday, September 7, 2010 02:11:07 UTC<br>Tuesday, September 7, 2010 05:41:07 AM at epicenter</p><p><strong>Depth</strong>: 27.90 km (17.34 mi)</p>]]></summary><georss:point>27.1465 54.5877</georss:point><georss:elev>-27900</georss:elev><category label="Age" term="Past day"/></entry>
|
||||
<entry><id>urn:earthquake-usgs-gov:us:2010axad</id><title>M 4.9, Fiji region</title><updated>2010-09-07T01:42:39Z</updated><link rel="alternate" type="text/html" href="http://earthquake.usgs.gov/earthquakes/recenteqsww/Quakes/us2010axad.php"/><summary type="html"><![CDATA[<img src="http://earthquake.usgs.gov/images/globes/-20_-180.jpg" alt="19.657°S 177.699°W" align="left" hspace="20" /><p>Tuesday, September 7, 2010 01:42:39 UTC<br>Tuesday, September 7, 2010 01:42:39 PM at epicenter</p><p><strong>Depth</strong>: 390.40 km (242.58 mi)</p>]]></summary><georss:point>-19.6573 -177.6987</georss:point><georss:elev>-390400</georss:elev><category label="Age" term="Past day"/></entry>
|
||||
<entry><id>urn:earthquake-usgs-gov:us:2010axab</id><title>M 5.8, southwest of Sumatra, Indonesia</title><updated>2010-09-07T00:57:26Z</updated><link rel="alternate" type="text/html" href="http://earthquake.usgs.gov/earthquakes/recenteqsww/Quakes/us2010axab.php"/><link rel="related" type="application/cap+xml" href="http://earthquake.usgs.gov/earthquakes/catalogs/cap/us2010axab" /><summary type="html"><![CDATA[<img src="http://earthquake.usgs.gov/images/globes/-5_105.jpg" alt="6.967°S 103.657°E" align="left" hspace="20" /><p>Tuesday, September 7, 2010 00:57:26 UTC<br>Tuesday, September 7, 2010 07:57:26 AM at epicenter</p><p><strong>Depth</strong>: 34.10 km (21.19 mi)</p>]]></summary><georss:point>-6.9665 103.6573</georss:point><georss:elev>-34100</georss:elev><category label="Age" term="Past day"/></entry>
|
||||
<entry><id>urn:earthquake-usgs-gov:us:2010awby</id><title>M 5.2, North Island of New Zealand</title><updated>2010-09-06T22:48:33Z</updated><link rel="alternate" type="text/html" href="http://earthquake.usgs.gov/earthquakes/recenteqsww/Quakes/us2010awby.php"/><summary type="html"><![CDATA[<img src="http://earthquake.usgs.gov/images/globes/-40_175.jpg" alt="40.143°S 176.657°E" align="left" hspace="20" /><p>Monday, September 6, 2010 22:48:33 UTC<br>Tuesday, September 7, 2010 10:48:33 AM at epicenter</p><p><strong>Depth</strong>: 16.70 km (10.38 mi)</p>]]></summary><georss:point>-40.1430 176.6567</georss:point><georss:elev>-16700</georss:elev><category label="Age" term="Past day"/></entry>
|
||||
</feed>
|
189
sites/all/modules/feeds/tests/feeds/feed_without_guid.rss2
Normal file
189
sites/all/modules/feeds/tests/feeds/feed_without_guid.rss2
Normal file
@@ -0,0 +1,189 @@
|
||||
<rss version="2.0">
|
||||
<channel>
|
||||
<generator>Rss generator</generator>
|
||||
<pubDate>2009.10.20. 16:49:01</pubDate>
|
||||
<title>Magyar Nemzet Online - Hírek</title>
|
||||
<description>Magyar Nemzet Online - Hírek</description>
|
||||
<link>http://www.mno.hu</link>
|
||||
<language>HU</language>
|
||||
<image>
|
||||
<url>http://www.mno.hu/docfiles/rss/mno01.jpg</url>
|
||||
<link>http://www.mno.hu</link>
|
||||
<description>Magyar Nemzet Online - Hírek</description>
|
||||
<title>Magyar Nemzet Online - Hírek</title>
|
||||
<width>88</width>
|
||||
<height>31</height>
|
||||
</image>
|
||||
<item>
|
||||
<title>
|
||||
Megint csak a balhé + Videó
|
||||
</title>
|
||||
<description>
|
||||
Az egykori kiváló labdarúgó, Paul Gascoigne ezúttal sem futballtudása vagy esetleges edzői karrierjével került a címlapokra. A korábbi válogatott középpályás most egy snooker klubban okozott botrányt: lefejelte, majd bocsánatkérésként arcon csókolta az egyik kidobót. Utóbbi úriember meggondolatlanul cselekedett, mikor rászólt a sztárra, hogy tilos a dohányzás.
|
||||
</description>
|
||||
<pubDate>
|
||||
2009-10-20 16:49 +0200
|
||||
</pubDate>
|
||||
<link>
|
||||
http://www.mno.hu/portal/671000
|
||||
</link>
|
||||
<category>
|
||||
Online
|
||||
</category>
|
||||
</item>
|
||||
<item>
|
||||
<title>
|
||||
Az uniós tejalap csak filléreket hoz a magyar termelőknek
|
||||
</title>
|
||||
<description>
|
||||
A magyar tejtermelők véleménye szerint az unió által kvóta alapon kioszthatónak minősített 280 millió eurós tejalap nem igazán hathatós segítség, mivel az tejkvóta-kilogrammonként mindössze 50 fillér többletet jelenthet egy termelő számára – mondta az MTI megkeresésére kedden Bakos Erzsébet, a Tej Terméktanács szakmai koordinátora.<br /><a href="http://mno.hu/portal/670961"><strong><br /><span class="content_blog_lead" style="font-weight: bold"></span><strong><strong><strong><strong>•</strong></strong> Sürgősséggel döntenek a tejalapról</strong></strong></strong></a>
|
||||
</description>
|
||||
<pubDate>
|
||||
2009-10-20 16:48 +0200
|
||||
</pubDate>
|
||||
<link>
|
||||
http://www.mno.hu/portal/670998
|
||||
</link>
|
||||
<category>
|
||||
Online
|
||||
</category>
|
||||
</item>
|
||||
<item>
|
||||
<title>
|
||||
Pluszban zárt a BUX
|
||||
</title>
|
||||
<description>
|
||||
A Budapesti Értéktőzsde részvényindexe, a BUX 70,24 pontos, 0,33 százalékos emelkedéssel, 21.474,51 ponton zárt kedden.
|
||||
</description>
|
||||
<pubDate>
|
||||
2009-10-20 16:44 +0200
|
||||
</pubDate>
|
||||
<link>
|
||||
http://www.mno.hu/portal/671006
|
||||
</link>
|
||||
<category>
|
||||
Online
|
||||
</category>
|
||||
</item>
|
||||
<item>
|
||||
<title>
|
||||
Bajnait fogadja a pápa
|
||||
</title>
|
||||
<description>
|
||||
Bajnai Gordon miniszterelnök november 13-án a Vatikánba utazik, hogy találkozzon XVI. Benedek pápával – erősítette meg a nol.hu információját a kormányszóvivő.
|
||||
</description>
|
||||
<pubDate>
|
||||
2009-10-20 16:40 +0200
|
||||
</pubDate>
|
||||
<link>
|
||||
http://www.mno.hu/portal/670997
|
||||
</link>
|
||||
<category>
|
||||
Online
|
||||
</category>
|
||||
</item>
|
||||
<item>
|
||||
<title>
|
||||
Élelmiszereink 11 százaléka „saját”
|
||||
</title>
|
||||
<description>
|
||||
Egyre többet költünk élelmiszerre, és egyre kevesebb élelmiszert termelünk meg magunknak - derül ki a KSH 2000-2007 közötti éveket vizsgáló statisztikájából. Állati zsírt és cukrot kevesebbet fogyasztunk, gyorsétterembe viszont többet járunk.
|
||||
</description>
|
||||
<pubDate>
|
||||
2009-10-20 16:31 +0200
|
||||
</pubDate>
|
||||
<link>
|
||||
http://www.mno.hu/portal/670989
|
||||
</link>
|
||||
<category>
|
||||
Online
|
||||
</category>
|
||||
</item>
|
||||
<item>
|
||||
<title>
|
||||
Leleplezte magát a Heves megyei szocialista közgyűlési elnök
|
||||
</title>
|
||||
<description>
|
||||
Leleplezte magát Sós Tamás, a hevesi megyegyűlés elnöke, mert korábban azt állította, hogy az egri kórház fejlesztése csak magánműködtető bevonásával képzelhető el – jelentette ki kedden Egerben a megyegyűlés Fidesz-frakciójának igazgatója. Ezzel szemben Sós Tamás most bejelentette, hogy az intézmény 4,6-4,8 milliárd forintnyi uniós fejlesztési forrásra számíthat – mondta sajtótájékoztatón Herman István.
|
||||
</description>
|
||||
<pubDate>
|
||||
2009-10-20 16:28 +0200
|
||||
</pubDate>
|
||||
<link>
|
||||
http://www.mno.hu/portal/670999
|
||||
</link>
|
||||
<category>
|
||||
Online
|
||||
</category>
|
||||
</item>
|
||||
<item>
|
||||
<title>
|
||||
Oszkóék gyomra nem korog
|
||||
</title>
|
||||
<description>
|
||||
Állítólag százezer ember éhezik Magyarországon, vagyis ott, ahol „nagy a jólét”, ahová nem gyűrűznek be mindenféle válságok, és csupa remek ember rendelkezik az erőforrások és a döntési folyamatok felett. Végül is tízmillióhoz képest mi ez a százezer? Nyilván így gondolja ezt a teljes szocialista élcsapat is, mert egyetlen hangot sem hallattak az ügyben. De talán jobb is.
|
||||
</description>
|
||||
<pubDate>
|
||||
2009-10-20 16:28 +0200
|
||||
</pubDate>
|
||||
<link>
|
||||
http://www.mno.hu/portal/670522
|
||||
</link>
|
||||
<category>
|
||||
Online
|
||||
</category>
|
||||
</item>
|
||||
<item>
|
||||
<title>
|
||||
Áramot vezetett a kerítésbe, hat év fegyházbüntetést kapott
|
||||
</title>
|
||||
<description>
|
||||
Hat év fegyházbüntetésre ítélte kedden a Szabolcs-Szatmár-Bereg Megyei Bíróság azt a 41 éves kisari férfit, aki idén áprilisban áramot vezetett lakóházának kerítésébe, később pedig alkoholos állapotban késsel sebezte meg életveszélyesen az édesanyját, az ítélet nem jogerős.
|
||||
</description>
|
||||
<pubDate>
|
||||
2009-10-20 16:22 +0200
|
||||
</pubDate>
|
||||
<link>
|
||||
http://www.mno.hu/portal/670994
|
||||
</link>
|
||||
<category>
|
||||
Online
|
||||
</category>
|
||||
</item>
|
||||
<item>
|
||||
<title>
|
||||
„A kormány elvesz, majd nagy csinnadrattával morzsákat oszt”
|
||||
</title>
|
||||
<description>
|
||||
A tehetséggondozásra, az ország jövőjének a megalapozására kell, hogy legyen pénze a kormánynak – mondta Bajnai Gordon a kedden bejelentett tehetségsegítő programról. Sió László, a Fidesz szakpolitikusa szerint a kormány két kézzel elvesz, majd nagy csinnadrattával morzsákat oszt. Igen alacsony a ténylegesen kifizetett források aránya – reagált a hírre Cser-Palkovics András.
|
||||
</description>
|
||||
<pubDate>
|
||||
2009-10-20 16:18 +0200
|
||||
</pubDate>
|
||||
<link>
|
||||
http://www.mno.hu/portal/670996
|
||||
</link>
|
||||
<category>
|
||||
Online
|
||||
</category>
|
||||
</item>
|
||||
<item>
|
||||
<title>
|
||||
Hőszivattyút telepítenek az iskolába
|
||||
</title>
|
||||
<description>
|
||||
Mintegy 550 millió forintból teljesen felújítják a békési kistérségi általános iskola és pedagógiai szakszolgálat dr. Hepp Ferencről elnevezett tagintézményét – közölte Békés polgármestere kedden sajtótájékoztatón. A hőszigetelési munkák mellett hőszivattyú telepítésével is próbálják csökkenteni az energiafogyasztást.
|
||||
</description>
|
||||
<pubDate>
|
||||
2009-10-20 16:13 +0200
|
||||
</pubDate>
|
||||
<link>
|
||||
http://www.mno.hu/portal/670987
|
||||
</link>
|
||||
<category>
|
||||
Online
|
||||
</category>
|
||||
</item>
|
||||
</channel>
|
||||
</rss>
|
||||
|
@@ -0,0 +1,6 @@
|
||||
Title,published,file,GUID
|
||||
"Tubing is awesome",205200720,<?php print $files[0]; ?>,0
|
||||
"Jeff vs Tom",428112720,<?php print $files[1]; ?>,1
|
||||
"Attersee",1151766000,<?php print $files[2]; ?>,2
|
||||
"H Street NE",1256326995,<?php print $files[3]; ?>,3
|
||||
"La Fayette Park",1256326995,<?php print $files[4]; ?>,4
|
203
sites/all/modules/feeds/tests/feeds/feeds-tests-flickr.tpl.php
Normal file
203
sites/all/modules/feeds/tests/feeds/feeds-tests-flickr.tpl.php
Normal file
@@ -0,0 +1,203 @@
|
||||
<?php
|
||||
print '<?xml version="1.0" encoding="utf-8" standalone="yes"?>';
|
||||
?>
|
||||
<feed xmlns="http://www.w3.org/2005/Atom"
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:flickr="urn:flickr:" xmlns:media="http://search.yahoo.com/mrss/">
|
||||
|
||||
<title>Content from My picks</title>
|
||||
<link rel="self" href="http://api.flickr.com/services/feeds/photoset.gne?set=72157603970496952&nsid=28242329@N00&lang=en-us" />
|
||||
<link rel="alternate" type="text/html" href="http://www.flickr.com/photos/a-barth/sets/72157603970496952"/>
|
||||
<id>tag:flickr.com,2005:http://www.flickr.com/photos/28242329@N00/sets/72157603970496952</id>
|
||||
<icon>http://farm1.static.flickr.com/42/86410049_bd6dcdd5f9_s.jpg</icon>
|
||||
<subtitle>Some of my shots I like best in random order.</subtitle>
|
||||
<updated>2009-07-09T21:48:04Z</updated>
|
||||
<generator uri="http://www.flickr.com/">Flickr</generator>
|
||||
|
||||
<entry>
|
||||
<title>Tubing is awesome</title>
|
||||
<link rel="alternate" type="text/html" href="http://www.flickr.com/photos/a-barth/3596408735/in/set-72157603970496952/"/>
|
||||
<id>tag:flickr.com,2005:/photo/3596408735/in/set-72157603970496952</id>
|
||||
<published>2009-07-09T21:48:04Z</published>
|
||||
<updated>2009-07-09T21:48:04Z</updated>
|
||||
<dc:date.Taken>2009-05-01T00:00:00-08:00</dc:date.Taken>
|
||||
<content type="html"><p><a href="http://www.flickr.com/people/a-barth/">Alex Barth</a> posted a photo:</p>
|
||||
|
||||
<p><a href="http://www.flickr.com/photos/a-barth/3596408735/" title="Tubing is awesome"><img src="http://farm4.static.flickr.com/3599/3596408735_ce2f0c4824_m.jpg" width="240" height="161" alt="Tubing is awesome" /></a></p>
|
||||
|
||||
|
||||
<p>Virginia, 2009</p></content>
|
||||
<author>
|
||||
<name>Alex Barth</name>
|
||||
<uri>http://www.flickr.com/people/a-barth/</uri>
|
||||
</author>
|
||||
<link rel="license" type="text/html" href="http://creativecommons.org/licenses/by-nc/2.0/deed.en" />
|
||||
<link rel="enclosure" type="image/jpeg" href="<?php print $image_urls[0]; ?>" />
|
||||
|
||||
<category term="color" scheme="http://www.flickr.com/photos/tags/" />
|
||||
<category term="film" scheme="http://www.flickr.com/photos/tags/" />
|
||||
<category term="virginia" scheme="http://www.flickr.com/photos/tags/" />
|
||||
<category term="awesome" scheme="http://www.flickr.com/photos/tags/" />
|
||||
<category term="ishootfilm" scheme="http://www.flickr.com/photos/tags/" />
|
||||
<category term="va" scheme="http://www.flickr.com/photos/tags/" />
|
||||
<category term="badge" scheme="http://www.flickr.com/photos/tags/" />
|
||||
<category term="tubing" scheme="http://www.flickr.com/photos/tags/" />
|
||||
<category term="fuji160c" scheme="http://www.flickr.com/photos/tags/" />
|
||||
<category term="anfamiliebarth" scheme="http://www.flickr.com/photos/tags/" />
|
||||
<category term="canon24l" scheme="http://www.flickr.com/photos/tags/" />
|
||||
</entry>
|
||||
<entry>
|
||||
<title>Jeff vs Tom</title>
|
||||
<link rel="alternate" type="text/html" href="http://www.flickr.com/photos/a-barth/2640019371/in/set-72157603970496952/"/>
|
||||
<id>tag:flickr.com,2005:/photo/2640019371/in/set-72157603970496952</id>
|
||||
<published>2009-07-09T21:45:50Z</published>
|
||||
<updated>2009-07-09T21:45:50Z</updated>
|
||||
<dc:date.Taken>2008-06-01T00:00:00-08:00</dc:date.Taken>
|
||||
<content type="html"><p><a href="http://www.flickr.com/people/a-barth/">Alex Barth</a> posted a photo:</p>
|
||||
|
||||
<p><a href="http://www.flickr.com/photos/a-barth/2640019371/" title="Jeff vs Tom"><img src="http://farm4.static.flickr.com/3261/2640019371_495c3f51a2_m.jpg" width="240" height="159" alt="Jeff vs Tom" /></a></p>
|
||||
|
||||
|
||||
</content>
|
||||
<author>
|
||||
<name>Alex Barth</name>
|
||||
<uri>http://www.flickr.com/people/a-barth/</uri>
|
||||
</author>
|
||||
<link rel="license" type="text/html" href="http://creativecommons.org/licenses/by-nc/2.0/deed.en" />
|
||||
<link rel="enclosure" type="image/jpeg" href="<?php print $image_urls[1]; ?>" />
|
||||
|
||||
<category term="b" scheme="http://www.flickr.com/photos/tags/" />
|
||||
<category term="blackandwhite" scheme="http://www.flickr.com/photos/tags/" />
|
||||
<category term="bw" scheme="http://www.flickr.com/photos/tags/" />
|
||||
<category term="jeff" scheme="http://www.flickr.com/photos/tags/" />
|
||||
<category term="tom" scheme="http://www.flickr.com/photos/tags/" />
|
||||
<category term="washingtondc" scheme="http://www.flickr.com/photos/tags/" />
|
||||
<category term="blackwhite" scheme="http://www.flickr.com/photos/tags/" />
|
||||
<category term="dc" scheme="http://www.flickr.com/photos/tags/" />
|
||||
<category term="nikon" scheme="http://www.flickr.com/photos/tags/" />
|
||||
<category term="wideangle" scheme="http://www.flickr.com/photos/tags/" />
|
||||
<category term="ilfordhp5" scheme="http://www.flickr.com/photos/tags/" />
|
||||
<category term="foosball" scheme="http://www.flickr.com/photos/tags/" />
|
||||
<category term="20mm" scheme="http://www.flickr.com/photos/tags/" />
|
||||
<category term="nikonfe2" scheme="http://www.flickr.com/photos/tags/" />
|
||||
<category term="800asa" scheme="http://www.flickr.com/photos/tags/" />
|
||||
<category term="foosballtable" scheme="http://www.flickr.com/photos/tags/" />
|
||||
<category term="wuzler" scheme="http://www.flickr.com/photos/tags/" />
|
||||
<category term="wuzln" scheme="http://www.flickr.com/photos/tags/" />
|
||||
<category term="tischfusball" scheme="http://www.flickr.com/photos/tags/" />
|
||||
<category term="jeffmiccolis" scheme="http://www.flickr.com/photos/tags/" />
|
||||
<category term="ilfordhp5800asa" scheme="http://www.flickr.com/photos/tags/" />
|
||||
<category term="widean" scheme="http://www.flickr.com/photos/tags/" />
|
||||
</entry>
|
||||
<entry>
|
||||
<title>Attersee 1</title>
|
||||
<link rel="alternate" type="text/html" href="http://www.flickr.com/photos/a-barth/3686290986/in/set-72157603970496952/"/>
|
||||
<id>tag:flickr.com,2005:/photo/3686290986/in/set-72157603970496952</id>
|
||||
<published>2009-07-09T21:42:01Z</published>
|
||||
<updated>2009-07-09T21:42:01Z</updated>
|
||||
<dc:date.Taken>2009-06-01T00:00:00-08:00</dc:date.Taken>
|
||||
<content type="html"><p><a href="http://www.flickr.com/people/a-barth/">Alex Barth</a> posted a photo:</p>
|
||||
|
||||
<p><a href="http://www.flickr.com/photos/a-barth/3686290986/" title="Attersee 1"><img src="http://farm4.static.flickr.com/3606/3686290986_334c427e8c_m.jpg" width="240" height="238" alt="Attersee 1" /></a></p>
|
||||
|
||||
|
||||
<p>Upper Austria, 2009</p></content>
|
||||
<author>
|
||||
<name>Alex Barth</name>
|
||||
<uri>http://www.flickr.com/people/a-barth/</uri>
|
||||
</author>
|
||||
<link rel="license" type="text/html" href="http://creativecommons.org/licenses/by-nc/2.0/deed.en" />
|
||||
<link rel="enclosure" type="image/jpeg" href="<?php print $image_urls[2]; ?>" />
|
||||
|
||||
<category term="lake" scheme="http://www.flickr.com/photos/tags/" />
|
||||
<category term="green" scheme="http://www.flickr.com/photos/tags/" />
|
||||
<category term="water" scheme="http://www.flickr.com/photos/tags/" />
|
||||
<category term="austria" scheme="http://www.flickr.com/photos/tags/" />
|
||||
<category term="holga" scheme="http://www.flickr.com/photos/tags/" />
|
||||
<category term="toycamera" scheme="http://www.flickr.com/photos/tags/" />
|
||||
<category term="ishootfilm" scheme="http://www.flickr.com/photos/tags/" />
|
||||
<category term="fujireala" scheme="http://www.flickr.com/photos/tags/" />
|
||||
<category term="badge" scheme="http://www.flickr.com/photos/tags/" />
|
||||
<category term="100asa" scheme="http://www.flickr.com/photos/tags/" />
|
||||
<category term="attersee" scheme="http://www.flickr.com/photos/tags/" />
|
||||
<category term="plasticlens" scheme="http://www.flickr.com/photos/tags/" />
|
||||
<category term="colornegative" scheme="http://www.flickr.com/photos/tags/" />
|
||||
</entry>
|
||||
<entry>
|
||||
<title>H Street North East</title>
|
||||
<link rel="alternate" type="text/html" href="http://www.flickr.com/photos/a-barth/2640845934/in/set-72157603970496952/"/>
|
||||
<id>tag:flickr.com,2005:/photo/2640845934/in/set-72157603970496952</id>
|
||||
<published>2008-09-23T13:26:13Z</published>
|
||||
<updated>2008-09-23T13:26:13Z</updated>
|
||||
<dc:date.Taken>2008-06-01T00:00:00-08:00</dc:date.Taken>
|
||||
<content type="html"><p><a href="http://www.flickr.com/people/a-barth/">Alex Barth</a> posted a photo:</p>
|
||||
|
||||
<p><a href="http://www.flickr.com/photos/a-barth/2640845934/" title="H Street North East"><img src="http://farm4.static.flickr.com/3083/2640845934_85c11e5a18_m.jpg" width="240" height="159" alt="H Street North East" /></a></p>
|
||||
|
||||
|
||||
<p>Washington DC 2008<br />
|
||||
<a href="http://dcist.com/2008/07/07/photo_of_the_day_july_7_2008.php">Photo of the Day July 7 on DCist</a></p></content>
|
||||
<author>
|
||||
<name>Alex Barth</name>
|
||||
<uri>http://www.flickr.com/people/a-barth/</uri>
|
||||
</author>
|
||||
<link rel="license" type="text/html" href="http://creativecommons.org/licenses/by-nc/2.0/deed.en" />
|
||||
<link rel="enclosure" type="image/jpeg" href="<?php print $image_urls[3]; ?>" />
|
||||
|
||||
<category term="nightphotography" scheme="http://www.flickr.com/photos/tags/" />
|
||||
<category term="b" scheme="http://www.flickr.com/photos/tags/" />
|
||||
<category term="blackandwhite" scheme="http://www.flickr.com/photos/tags/" />
|
||||
<category term="bw" scheme="http://www.flickr.com/photos/tags/" />
|
||||
<category term="night" scheme="http://www.flickr.com/photos/tags/" />
|
||||
<category term="washingtondc" scheme="http://www.flickr.com/photos/tags/" />
|
||||
<category term="blackwhite" scheme="http://www.flickr.com/photos/tags/" />
|
||||
<category term="dc" scheme="http://www.flickr.com/photos/tags/" />
|
||||
<category term="nikon" scheme="http://www.flickr.com/photos/tags/" />
|
||||
<category term="dof" scheme="http://www.flickr.com/photos/tags/" />
|
||||
<category term="wideangle" scheme="http://www.flickr.com/photos/tags/" />
|
||||
<category term="explore" scheme="http://www.flickr.com/photos/tags/" />
|
||||
<category term="ilfordhp5" scheme="http://www.flickr.com/photos/tags/" />
|
||||
<category term="badge" scheme="http://www.flickr.com/photos/tags/" />
|
||||
<category term="dcist" scheme="http://www.flickr.com/photos/tags/" />
|
||||
<category term="20mm" scheme="http://www.flickr.com/photos/tags/" />
|
||||
<category term="hstreet" scheme="http://www.flickr.com/photos/tags/" />
|
||||
<category term="nikonfe2" scheme="http://www.flickr.com/photos/tags/" />
|
||||
<category term="800asa" scheme="http://www.flickr.com/photos/tags/" />
|
||||
<category term="hstreetne" scheme="http://www.flickr.com/photos/tags/" />
|
||||
<category term="anfamiliebarth" scheme="http://www.flickr.com/photos/tags/" />
|
||||
<category term="ilfordhp5800asa" scheme="http://www.flickr.com/photos/tags/" />
|
||||
<category term="hstreetbynight" scheme="http://www.flickr.com/photos/tags/" />
|
||||
<category term="forlaia" scheme="http://www.flickr.com/photos/tags/" />
|
||||
</entry>
|
||||
<entry>
|
||||
<title>La Fayette Park</title>
|
||||
<link rel="alternate" type="text/html" href="http://www.flickr.com/photos/a-barth/4209685951/in/set-72157603970496952/"/>
|
||||
<id>tag:flickr.com,2005:/photo/4209685951/in/set-72157603970496952</id>
|
||||
<published>2009-07-09T21:48:04Z</published>
|
||||
<updated>2009-07-09T21:48:04Z</updated>
|
||||
<dc:date.Taken>2009-05-01T00:00:00-08:00</dc:date.Taken>
|
||||
<content type="html"><p><a href="http://www.flickr.com/people/a-barth/">Alex Barth</a> posted a photo:</p>
|
||||
|
||||
<p><a href="http://www.flickr.com/photos/a-barth/3596408735/" title="Tubing is fun"><img src="http://farm3.staticflickr.com/2675/4209685951_cb073de96f_m.jpg" width="239" height="240" alt="La Fayette park" /></a></p>
|
||||
|
||||
|
||||
<p>Virginia, 2009</p></content>
|
||||
<author>
|
||||
<name>Alex Barth</name>
|
||||
<uri>http://www.flickr.com/people/a-barth/</uri>
|
||||
</author>
|
||||
<link rel="license" type="text/html" href="http://creativecommons.org/licenses/by-nc/2.0/deed.en" />
|
||||
<link rel="enclosure" type="image/jpeg" href="<?php print $image_urls[4]; ?>" />
|
||||
|
||||
<category term="color" scheme="http://www.flickr.com/photos/tags/" />
|
||||
<category term="film" scheme="http://www.flickr.com/photos/tags/" />
|
||||
<category term="virginia" scheme="http://www.flickr.com/photos/tags/" />
|
||||
<category term="awesome" scheme="http://www.flickr.com/photos/tags/" />
|
||||
<category term="ishootfilm" scheme="http://www.flickr.com/photos/tags/" />
|
||||
<category term="va" scheme="http://www.flickr.com/photos/tags/" />
|
||||
<category term="badge" scheme="http://www.flickr.com/photos/tags/" />
|
||||
<category term="tubing" scheme="http://www.flickr.com/photos/tags/" />
|
||||
<category term="fuji160c" scheme="http://www.flickr.com/photos/tags/" />
|
||||
<category term="anfamiliebarth" scheme="http://www.flickr.com/photos/tags/" />
|
||||
<category term="canon24l" scheme="http://www.flickr.com/photos/tags/" />
|
||||
</entry>
|
||||
</feed>
|
8
sites/all/modules/feeds/tests/feeds/googlenewstz.rss2
Normal file
8
sites/all/modules/feeds/tests/feeds/googlenewstz.rss2
Normal file
File diff suppressed because one or more lines are too long
248
sites/all/modules/feeds/tests/feeds/magento.rss1
Normal file
248
sites/all/modules/feeds/tests/feeds/magento.rss1
Normal file
@@ -0,0 +1,248 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<rdf:RDF xmlns="http://purl.org/rss/1.0/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:georss="http://www.georss.org/georss">
|
||||
<channel rdf:about="http://www.magentosites.net/rss.xml">
|
||||
<title xml:lang="en">Magento Sites Network - A directory listing of Magento Commerce stores</title>
|
||||
<link>http://www.magentosites.net/</link>
|
||||
<description xml:lang="en"></description>
|
||||
<items rdf:nodeID="b1"/>
|
||||
<sy:updatePeriod>daily</sy:updatePeriod>
|
||||
</channel>
|
||||
<rdf:Seq rdf:nodeID="b1">
|
||||
<rdf:li>http://www.magentosites.net/node/3473</rdf:li>
|
||||
<rdf:li>http://www.magentosites.net/node/3472</rdf:li>
|
||||
<rdf:li>http://www.magentosites.net/node/3471</rdf:li>
|
||||
<rdf:li>http://www.magentosites.net/node/3470</rdf:li>
|
||||
<rdf:li>http://www.magentosites.net/node/3468</rdf:li>
|
||||
<rdf:li>http://www.magentosites.net/node/3466</rdf:li>
|
||||
<rdf:li>http://www.magentosites.net/node/3465</rdf:li>
|
||||
<rdf:li>http://www.magentosites.net/node/3464</rdf:li>
|
||||
<rdf:li>http://www.magentosites.net/node/3463</rdf:li>
|
||||
<rdf:li>http://www.magentosites.net/node/3461</rdf:li>
|
||||
<rdf:li>http://www.magentosites.net/node/3459</rdf:li>
|
||||
<rdf:li>http://www.magentosites.net/node/3458</rdf:li>
|
||||
<rdf:li>http://www.magentosites.net/node/3457</rdf:li>
|
||||
<rdf:li>http://www.magentosites.net/node/3456</rdf:li>
|
||||
<rdf:li>http://www.magentosites.net/node/3455</rdf:li>
|
||||
<rdf:li>http://www.magentosites.net/node/3454</rdf:li>
|
||||
<rdf:li>http://www.magentosites.net/node/3453</rdf:li>
|
||||
<rdf:li>http://www.magentosites.net/node/3452</rdf:li>
|
||||
<rdf:li>http://www.magentosites.net/node/3451</rdf:li>
|
||||
<rdf:li>http://www.magentosites.net/node/3450</rdf:li>
|
||||
</rdf:Seq>
|
||||
<item rdf:about="http://www.magentosites.net/node/3473">
|
||||
<title>Gezondheidswebwinkel</title>
|
||||
<link>http://www.magentosites.net/store/2010/04/28/gezondheidswebwinkel/index.html</link>
|
||||
<description><p>Gezondheidswebwinkrl.nl is een online shop voor reformhuis gebaseerde producten.</p></description>
|
||||
<dc:date rdf:datatype="http://www.w3.org/2001/XMLSchema#dateTime">2010-04-28T03:21:33Z</dc:date>
|
||||
<dc:creator>dzinestudio</dc:creator>
|
||||
<dc:subject>Health & Personal Care</dc:subject>
|
||||
<dc:subject>Grocery, Health & Beauty</dc:subject>
|
||||
<georss:point>52.214007 6.892291</georss:point>
|
||||
</item>
|
||||
<item rdf:about="http://www.magentosites.net/node/3472">
|
||||
<title>MyBobino.com</title>
|
||||
<link>http://www.magentosites.net/store/2010/04/26/mybobinocom/index.html</link>
|
||||
<description><p>The Bobino helps you organize and shorten your iPod or cell phone earbuds. No more messy lumps of cord in your pockets or purse. Go to www.mybobino.com.</p></description>
|
||||
<dc:date rdf:datatype="http://www.w3.org/2001/XMLSchema#dateTime">2010-04-26T20:04:09Z</dc:date>
|
||||
<dc:creator>TacovanhetReve</dc:creator>
|
||||
<dc:subject>Computer Accessories</dc:subject>
|
||||
<dc:subject>Gifts</dc:subject>
|
||||
<dc:subject>MP3 & Media Players</dc:subject>
|
||||
<dc:subject>Computers & Office</dc:subject>
|
||||
<dc:subject>Electronics</dc:subject>
|
||||
<dc:subject>Gifts, Foods & Drinks</dc:subject>
|
||||
<dc:subject>Other</dc:subject>
|
||||
<georss:point>51.589322 4.774491</georss:point>
|
||||
</item>
|
||||
<item rdf:about="http://www.magentosites.net/node/3471">
|
||||
<title>Boxershorts.nl</title>
|
||||
<link>http://www.magentosites.net/store/2010/04/26/boxershortsnl/index.html</link>
|
||||
<dc:date rdf:datatype="http://www.w3.org/2001/XMLSchema#dateTime">2010-04-26T12:34:54Z</dc:date>
|
||||
<dc:creator>tomashesseling</dc:creator>
|
||||
<dc:subject>Gifts</dc:subject>
|
||||
<dc:subject>Lingerie</dc:subject>
|
||||
<dc:subject>Clothing, Shoes & Jewelry</dc:subject>
|
||||
<dc:subject>Gifts, Foods & Drinks</dc:subject>
|
||||
<dc:subject>Other</dc:subject>
|
||||
<georss:point>52.097938 5.109197</georss:point>
|
||||
</item>
|
||||
<item rdf:about="http://www.magentosites.net/node/3470">
|
||||
<title>Zapa</title>
|
||||
<link>http://www.magentosites.net/store/2010/04/26/zapa/index.html</link>
|
||||
<description><p>The Zapa's webshop is based on Magento community edition.</p></description>
|
||||
<dc:date rdf:datatype="http://www.w3.org/2001/XMLSchema#dateTime">2010-04-26T08:21:34Z</dc:date>
|
||||
<dc:creator>wecom</dc:creator>
|
||||
<dc:subject>Clothing & Accessories</dc:subject>
|
||||
<dc:subject>Clothing, Shoes & Jewelry</dc:subject>
|
||||
<georss:point>48.872290 2.363026</georss:point>
|
||||
</item>
|
||||
<item rdf:about="http://www.magentosites.net/node/3468">
|
||||
<title>Bandenshoppen</title>
|
||||
<link>http://www.magentosites.net/store/2010/04/26/bandenshoppen/index.html</link>
|
||||
<description><p>Bandenshoppen is een Magento webshop waarin voor iedere auto de juiste band te vinden is. Of het nu is voor een bestelwagen, SUV of personenwagen, de juiste band van alle grote merken kunt u hier eenvoudig vinden.</p>
|
||||
<p>Met slechts de code op uw band kiest u de juiste winter- of zomerband.</p></description>
|
||||
<dc:date rdf:datatype="http://www.w3.org/2001/XMLSchema#dateTime">2010-04-26T07:41:01Z</dc:date>
|
||||
<dc:creator>Eigen en Wijze Communicatie</dc:creator>
|
||||
<dc:subject>Automotive</dc:subject>
|
||||
<dc:subject>Tools, Auto & Industrial</dc:subject>
|
||||
<georss:point>52.792620 4.786409</georss:point>
|
||||
</item>
|
||||
<item rdf:about="http://www.magentosites.net/node/3466">
|
||||
<title>Furniture For You (Rugby) LTD</title>
|
||||
<link>http://www.magentosites.net/store/2010/04/23/furniture-for-you-rugby-ltd/index.html</link>
|
||||
<description><p>Furniture For You (Rugby) LTD is a large discount furniture store based in Rugby, Warwickshire. Huge selections of Bedroom, Living room &amp; Dining room furniture made by top manufacturers in the UK, Italy &amp; Germany.</p></description>
|
||||
<dc:date rdf:datatype="http://www.w3.org/2001/XMLSchema#dateTime">2010-04-23T13:34:28Z</dc:date>
|
||||
<dc:creator>furnitureforyoultd</dc:creator>
|
||||
<dc:subject>Furniture & Décor</dc:subject>
|
||||
<dc:subject>Home & Garden</dc:subject>
|
||||
<georss:point>52.372879 -1.286754</georss:point>
|
||||
</item>
|
||||
<item rdf:about="http://www.magentosites.net/node/3465">
|
||||
<title>GoedHip</title>
|
||||
<link>http://www.magentosites.net/store/2010/04/22/goedhip/index.html</link>
|
||||
<description><p>GoedHip is een Magento webshop met hippe fair trade, ecologische en biologische producten.</p></description>
|
||||
<dc:date rdf:datatype="http://www.w3.org/2001/XMLSchema#dateTime">2010-04-22T12:02:35Z</dc:date>
|
||||
<dc:creator>Goedhip</dc:creator>
|
||||
<dc:subject>Gifts</dc:subject>
|
||||
<dc:subject>Gifts, Foods & Drinks</dc:subject>
|
||||
<georss:point>52.091262 5.122748</georss:point>
|
||||
</item>
|
||||
<item rdf:about="http://www.magentosites.net/node/3464">
|
||||
<title>Lampenwereld</title>
|
||||
<link>http://www.magentosites.net/store/2010/04/22/lampenwereld/index.html</link>
|
||||
<description><p>Online Lightstore with a big variation of lights. All prizes include tax, lightbulb and shipment.</p></description>
|
||||
<dc:date rdf:datatype="http://www.w3.org/2001/XMLSchema#dateTime">2010-04-22T11:43:40Z</dc:date>
|
||||
<dc:creator>lampenwereld</dc:creator>
|
||||
<dc:subject>Furniture & Décor</dc:subject>
|
||||
<dc:subject>Home & Garden</dc:subject>
|
||||
<georss:point>51.581985 4.732600</georss:point>
|
||||
</item>
|
||||
<item rdf:about="http://www.magentosites.net/node/3463">
|
||||
<title>Bumblejax</title>
|
||||
<link>http://www.magentosites.net/store/2010/04/21/bumblejax/index.html-0</link>
|
||||
<dc:date rdf:datatype="http://www.w3.org/2001/XMLSchema#dateTime">2010-04-21T21:42:01Z</dc:date>
|
||||
<dc:creator>coreyd74</dc:creator>
|
||||
<dc:subject>Art, Culture & Leisure</dc:subject>
|
||||
<dc:subject>Photography</dc:subject>
|
||||
<georss:point>47.622748 -122.334355</georss:point>
|
||||
</item>
|
||||
<item rdf:about="http://www.magentosites.net/node/3461">
|
||||
<title>SendraValencia</title>
|
||||
<link>http://www.magentosites.net/store/2010/04/20/sendravalencia/index.html</link>
|
||||
<description><p>Tienda de Botas Sendra en Internet. Sendra Boots Store.<br />
|
||||
En Botas Sendra Valencia se ha cuidado al máximo el diseño y la navegación. Integración con almacenes y Courier.</p></description>
|
||||
<dc:date rdf:datatype="http://www.w3.org/2001/XMLSchema#dateTime">2010-04-20T09:32:36Z</dc:date>
|
||||
<dc:creator>Onestic</dc:creator>
|
||||
<dc:subject>Shoes</dc:subject>
|
||||
<dc:subject>Clothing, Shoes & Jewelry</dc:subject>
|
||||
<georss:point>39.469008 -0.371995</georss:point>
|
||||
</item>
|
||||
<item rdf:about="http://www.magentosites.net/node/3459">
|
||||
<title>Snowcountry</title>
|
||||
<link>http://www.magentosites.net/store/2010/04/19/snowcountry/index.html</link>
|
||||
<description><p>Freeski en Snowboard webshop</p>
|
||||
<p>Snowcountry.nl richt zich voornamelijk op de actieve boarder en skiër, je vind hier merken die niet op elke straathoek te koop zijn, sterker nog veelal zijn de ski- en snowboard collecties alleen bij Snowcountry online verkrijgbaar.</p></description>
|
||||
<dc:date rdf:datatype="http://www.w3.org/2001/XMLSchema#dateTime">2010-04-19T15:35:29Z</dc:date>
|
||||
<dc:creator>Snowcountry</dc:creator>
|
||||
<dc:subject>All Sports & Outdoors</dc:subject>
|
||||
<dc:subject>Athletic & Outdoor Clothing</dc:subject>
|
||||
<dc:subject>Outdoor Recreation</dc:subject>
|
||||
<dc:subject>Sports & Outdoors</dc:subject>
|
||||
<georss:point>52.179226 5.507952</georss:point>
|
||||
</item>
|
||||
<item rdf:about="http://www.magentosites.net/node/3458">
|
||||
<title>Floriculture Australia - Wholesale Florist</title>
|
||||
<link>http://www.magentosites.net/store/2010/04/18/floriculture-australia-wholesale-florist/index.html</link>
|
||||
<description><p>Floriculture Australia Wholesale Florist was set up as a cut flower distribution business a few years ago with a distinct difference to other wholesale florists - we quality check all product, we provide a high level of personal and professional service and a respect for the environment, ourselves and those we deal with.</p>
|
||||
<p>Originally, the family bought a country property to have some room for the dogs to roam around back in the mid 1990’s. This property just happened to have some floristry foliage trees, lavender and daffodils. Max, then in his late 20’s, took on a new industry, a new career and loads and loads of hard work.</p>
|
||||
<p>Today, the business has expanded, Max has married had some kiddies, further property purchases have been made, and a workforce employed to help with all that hard work!</p>
|
||||
<p>The driving philosophy has always been to produce and distribute quality flowers in a sustainable manner. We use natural forms of pest control, so you can be sure any flowers supplied by us at Floriculture.com.au are not only fresh and beautiful – they are safe to handle.</p></description>
|
||||
<dc:date rdf:datatype="http://www.w3.org/2001/XMLSchema#dateTime">2010-04-18T12:52:09Z</dc:date>
|
||||
<dc:creator>MaxTheFlowerGuy</dc:creator>
|
||||
<dc:subject>Flowers</dc:subject>
|
||||
<dc:subject>Gifts, Foods & Drinks</dc:subject>
|
||||
<georss:point>-37.814470 145.437914</georss:point>
|
||||
</item>
|
||||
<item rdf:about="http://www.magentosites.net/node/3457">
|
||||
<title>Flower Bunch</title>
|
||||
<link>http://www.magentosites.net/store/2010/04/18/flower-bunch/index.html</link>
|
||||
<description><p>FlowerBunch has Australia wide flower delivery direct from our own flower farm and wholesale flower distribution shed. This ensures the freshest flowers, discounted flowers and seasonal specials and next day free flower delivery.</p>
|
||||
<p>The driving philosophy for the company has always been to produce quality flowers in a sustainable manner. Our flowers are grown using hydroponic organic flower production practices, so you can be sure any flowers supplied by us at http://FlowerBunch.com.au are not only fresh and beautiful, they are also safe to handle.</p>
|
||||
<p>Our farm fresh cut flower delivery is available to Sydney, Melbourne, Brisbane, Canberra, Adelaide and all eastern states of Australia. Some remote areas may take a day or two extra for delivery. All flowers are sent direct from our farm, not through a relay/referral service.</p></description>
|
||||
<dc:date rdf:datatype="http://www.w3.org/2001/XMLSchema#dateTime">2010-04-18T12:42:54Z</dc:date>
|
||||
<dc:creator>MaxTheFlowerGuy</dc:creator>
|
||||
<dc:subject>Flowers</dc:subject>
|
||||
<dc:subject>Gifts, Foods & Drinks</dc:subject>
|
||||
<georss:point>-37.812267 145.432457</georss:point>
|
||||
</item>
|
||||
<item rdf:about="http://www.magentosites.net/node/3456">
|
||||
<title>Conec - elektronische Bauelemente</title>
|
||||
<link>http://www.magentosites.net/store/2010/04/15/conec-elektronische-bauelemente/index.html</link>
|
||||
<description><p>CONEC entwickelt und produziert in modernen Produktionsstätten mit Hightech-Technologie in zuverlässigen Produktionsprozessen. Die Vielfalt der CONEC-Produktpalette bietet zuverlässige und effektive Antworten auf alle Fragen der Verbindungstechnik, bei Geräteherstellern, Subunternehmern und Kabelverarbeitern. CONEC ist in allen Industriebereichen zu Hause.</p></description>
|
||||
<dc:date rdf:datatype="http://www.w3.org/2001/XMLSchema#dateTime">2010-04-15T09:07:48Z</dc:date>
|
||||
<dc:creator>simone.meisner</dc:creator>
|
||||
<dc:subject>Other</dc:subject>
|
||||
<georss:point>51.674817 8.377200</georss:point>
|
||||
</item>
|
||||
<item rdf:about="http://www.magentosites.net/node/3455">
|
||||
<title>Liemke - technisch chemische Artikel</title>
|
||||
<link>http://www.magentosites.net/store/2010/04/15/liemke-technisch-chemische-artikel/index.html</link>
|
||||
<description><p>Hochwertige Klebstoffe, Aerosole &amp; Reiniger aus dem Hause LIEMKE</p>
|
||||
<p>Überzeugen Sie sich von der Qualität der professionellen chemischen Produkte. Das Sortiment der Hochleistungs-Produkte der Qualitätsmarke "LK" umfasst hochwertige Klebstoffe, Schmiermittel, Aerosole, Dichtstoffe, Silikone, Reiniger, Desinfektionsmittel und Trennmittel für chemisch-technische Anwendungen, für die Bauchemie und die professionelle Desinfektion.</p></description>
|
||||
<dc:date rdf:datatype="http://www.w3.org/2001/XMLSchema#dateTime">2010-04-15T08:59:45Z</dc:date>
|
||||
<dc:creator>simone.meisner</dc:creator>
|
||||
<dc:subject>Other</dc:subject>
|
||||
<georss:point>51.956925 8.578393</georss:point>
|
||||
</item>
|
||||
<item rdf:about="http://www.magentosites.net/node/3454">
|
||||
<title>Peitz Werkzeug und Outdoorbekleidung</title>
|
||||
<link>http://www.magentosites.net/store/2010/04/15/peitz-werkzeug-und-outdoorbekleidung/index.html</link>
|
||||
<description><p>Bei Peitz Werkzeuge finden Sie ein breites Sortiment an erstklassigen Werkzeugen und hochwertigem Outdoor-Equipment. Wir führen die Marken Hitachi, Milwaukee, Matador, BP, Yeti, Nordisk, Tortuga u.v.m.</p>
|
||||
<p>Über 1.000 Artikel stehen in diesem Shop zur Verfügung. </p>
|
||||
<p>Erfahrung, Service und günstige Preise überzeugen!</p></description>
|
||||
<dc:date rdf:datatype="http://www.w3.org/2001/XMLSchema#dateTime">2010-04-15T08:46:18Z</dc:date>
|
||||
<dc:creator>simone.meisner</dc:creator>
|
||||
<dc:subject>Power & Hand Tools</dc:subject>
|
||||
<dc:subject>Tools, Auto & Industrial</dc:subject>
|
||||
<georss:point>51.791418 8.420595</georss:point>
|
||||
</item>
|
||||
<item rdf:about="http://www.magentosites.net/node/3453">
|
||||
<title>Großewinkelmann Tor- und Zaunsysteme</title>
|
||||
<link>http://www.magentosites.net/store/2010/04/15/grossewinkelmann-tor-und-zaunsysteme/index.html</link>
|
||||
<description><p>Großewinkelmann bietet Zaun- und Torsysteme sowie Stall- und Weidetechnik an. Produktideen und jahrzentelange Erfahrung bringen den entscheidenden Vorteil für den Kunden. Seit mehr als 60 Jahren steht Großewinkelmann für Qualität und persönlichen Service rund um Zäune und Tore.</p></description>
|
||||
<dc:date rdf:datatype="http://www.w3.org/2001/XMLSchema#dateTime">2010-04-15T08:39:25Z</dc:date>
|
||||
<dc:creator>simone.meisner</dc:creator>
|
||||
<dc:subject>Other</dc:subject>
|
||||
<georss:point>51.862318 8.435454</georss:point>
|
||||
</item>
|
||||
<item rdf:about="http://www.magentosites.net/node/3452">
|
||||
<title>Möbius Werbemittel</title>
|
||||
<link>http://www.magentosites.net/store/2010/04/15/mobius-werbemittel/index.html</link>
|
||||
<description><p>Möbius Werbemittel bietet einen Onlineshop für Werbemittel und Werbegeschenke. Ein breites Sortiment aus vielen Bereichen bietet optimale Auswahl. Finden Sie Feuerzeuge, Schluesselanhänger, Schirme, Tassen, Schreibgeraete, Buero- und Geschäftsausstattung und vieles mehr.<br />
|
||||
Der schnelle Druckservice und die kompetente Beratung runden das Angebot ab.</p></description>
|
||||
<dc:date rdf:datatype="http://www.w3.org/2001/XMLSchema#dateTime">2010-04-15T08:05:42Z</dc:date>
|
||||
<dc:creator>simone.meisner</dc:creator>
|
||||
<dc:subject>Other</dc:subject>
|
||||
<georss:point>49.544584 8.346575</georss:point>
|
||||
</item>
|
||||
<item rdf:about="http://www.magentosites.net/node/3451">
|
||||
<title>watch store</title>
|
||||
<link>http://www.magentosites.net/store/2010/04/14/watch-store/index.html</link>
|
||||
<description><p>watches, is a fast growing e-shop in Greece. You can find a big variety of whell priced watches.</p></description>
|
||||
<dc:date rdf:datatype="http://www.w3.org/2001/XMLSchema#dateTime">2010-04-14T21:44:32Z</dc:date>
|
||||
<dc:creator>webo2</dc:creator>
|
||||
<dc:subject>Watches</dc:subject>
|
||||
<dc:subject>Clothing, Shoes & Jewelry</dc:subject>
|
||||
<georss:point>37.443287 24.942652</georss:point>
|
||||
</item>
|
||||
<item rdf:about="http://www.magentosites.net/node/3450">
|
||||
<title>Fishingtime.com</title>
|
||||
<link>http://www.magentosites.net/store/2010/04/14/fishingtimecom/index.html</link>
|
||||
<description><p>Fishingtime.com is a very fast growing fishing tackle e-shop. You can find everything about fishing in competitive prices and services.</p></description>
|
||||
<dc:date rdf:datatype="http://www.w3.org/2001/XMLSchema#dateTime">2010-04-14T07:21:29Z</dc:date>
|
||||
<dc:creator>dimmeneidis</dc:creator>
|
||||
<dc:subject>All Sports & Outdoors</dc:subject>
|
||||
<dc:subject>Sports & Outdoors</dc:subject>
|
||||
<georss:point>37.953416 23.692998</georss:point>
|
||||
</item>
|
||||
</rdf:RDF>
|
87
sites/all/modules/feeds/tests/feeds/many_nodes.csv
Normal file
87
sites/all/modules/feeds/tests/feeds/many_nodes.csv
Normal file
@@ -0,0 +1,87 @@
|
||||
Title,Body,published,GUID
|
||||
"Ut wisi enim ad minim veniam", "Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat.",205200720,2
|
||||
"Duis autem vel eum iriure dolor", "Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi.",428112720,3
|
||||
"Nam liber tempor", "Nam liber tempor cum soluta nobis eleifend option congue nihil imperdiet doming id quod mazim placerat facer possim assum.",1151766000,1
|
||||
Typi non habent"", "Typi non habent claritatem insitam; est usus legentis in iis qui facit eorum claritatem.",1256326995,4
|
||||
"Lorem ipsum","Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat.",1251936720,1
|
||||
"Investigationes demonstraverunt", "Investigationes demonstraverunt lectores legere me lius quod ii legunt saepius.",946702800,5
|
||||
"Claritas est etiam", "Claritas est etiam processus dynamicus, qui sequitur mutationem consuetudium lectorum.",438112720,6
|
||||
"Mirum est notare", "Mirum est notare quam littera gothica, quam nunc putamus parum claram, anteposuerit litterarum formas humanitatis per seacula quarta decima et quinta decima.",1151066000,7
|
||||
"Eodem modo typi", "Eodem modo typi, qui nunc nobis videntur parum clari, fiant sollemnes in futurum.",1212891020,8
|
||||
"Ut quam dolor", "Ut quam dolor, aliquam pretium elementum ac, auctor eu tortor.",1200837000,9
|
||||
"Sed id dignissim lorem", "Donec nec urna mauris. Duis tincidunt",1201000000,10
|
||||
"Aliquam feugiat diam", "Aliquam feugiat diam ac enim egestas ut cursus lacus fermentum.",1210922021,11
|
||||
"Proin et fringilla leo", "Maecenas rhoncus velit quis nibh convallis pharetra.",1201832100,12
|
||||
"Suspendisse potenti", "Integer commodo elit et arcu dapibus at hendrerit nunc dapibus.",1122838020,12
|
||||
"Nunc eu lectus nisi", "Nunc eu lectus nisi, sed vestibulum mauris. Sed tincidunt vehicula sem, eu tincidunt massa ultrices vel.",1200827015,13
|
||||
"Mauris tellus erat", "",1201845210,13
|
||||
"Pellentesque porttitor gravida magna", "Pellentesque porttitor gravida magna, ut lacinia risus suscipit a. Nunc molestie molestie massa non auctor.",1211835320,14
|
||||
"Pellentesque facilisis ultrices", "Pellentesque facilisis ultrices risus non porttitor. Donec dapibus velit in metus consectetur et ullamcorper velit volutpat.",1190835120,15
|
||||
"Sed eros lectus", "Sed eros lectus, mollis vel commodo et, molestie vel urna.",1151825020,16
|
||||
"Morbi consectetur fringilla dolor", "Morbi consectetur fringilla dolor. Morbi eleifend pharetra purus, non facilisis tortor ullamcorper sed.",1201745220,17
|
||||
"Vivamus vitae lectus", "Vivamus vitae lectus ac urna tempus dapibus eu consectetur massa. Donec vitae arcu lectus, non ornare nunc. ",1201825020,18
|
||||
"Fusce est felis", "Fusce est felis, tincidunt eu congue id, placerat nec massa.",1201836001,19
|
||||
"Duis tristique velit", "Duis tristique velit vitae lacus malesuada sed commodo quam commodo.",1201832024,20
|
||||
"In ac felis neque", "Integer dictum sapien eget nunc commodo convallis.",1201830020,21
|
||||
"Proin a mi nulla", "Proin a mi nulla, sodales mattis nunc.",1201822020,21
|
||||
"Pellentesque vitae massa", "Pellentesque vitae massa elementum augue varius suscipit at quis turpis.",1201810020,22
|
||||
"Proin dapibus", "Nam pulvinar urna vel eros aliquam hendrerit.",1201636020,23
|
||||
"Donec", "Nulla pulvinar felis nec nulla pretium id pulvinar risus scelerisque.",1201336020,24
|
||||
"Quisque dictum sagittis purus", "Quisque dictum sagittis purus, nec tristique magna sagittis nec. Mauris tortor nisl, cursus sit amet varius vitae, posuere in ipsum.",1201236020,25
|
||||
"Praesent", "Praesent tincidunt vulputate turpis non faucibus",1201132020,26
|
||||
"Vestibulum", "Vestibulum volutpat interdum elit, quis aliquam leo lobortis non.",1201036020,27
|
||||
"Aliquam", "Aliquam fringilla lobortis mollis.",1201022020,28
|
||||
"Etiam faucibus", "Etiam faucibus, quam vitae sollicitudin sagittis, nisl metus ultricies risus, sed convallis nibh risus ut libero.",1201021020,29
|
||||
"In hac habitasse", "Proin justo sapien, dapibus vel dictum non, vestibulum in neque.",1201010020,30
|
||||
"Mauris risus dolor", "Maecenas rutrum diam suscipit mi feugiat venenatis.",1201005011,31
|
||||
"Pellentesque habitant", "Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas.",1201001010,32
|
||||
"Duis convallis", "Duis convallis quam non eros suscipit iaculis. Aliquam erat volutpat.",1201000010,33
|
||||
"Proin adipiscing mi vel", "Proin nibh est, gravida ac condimentum viverra, hendrerit sodales tellus.",1200901010,34
|
||||
"Nullam sodales", "Nullam sodales laoreet suscipit.",1200851010,35
|
||||
"Duis ornare pulvinar purus", "Duis ornare pulvinar purus, at pulvinar nulla hendrerit vel.",1200801010,35
|
||||
"Mauris sit amet nibh risus", "Mauris sit amet nibh risus, eget eleifend ante. Donec imperdiet ante quis ligula condimentum consectetur.",1200761010,36
|
||||
"Fusce sit amet mi vitae", "Fusce sit amet mi vitae ipsum tempor rhoncus. Aenean sit amet diam erat, fringilla porttitor felis.",1200751010,37
|
||||
"Cras blandit ornare", "Cras blandit ornare augue in tempor. Curabitur vitae dolor nibh, sed molestie metus.",1200601010,37
|
||||
"Proin at eros", "Proin at eros ut est laoreet tristique. Duis ullamcorper, nisi eu gravida mattis, nibh ligula laoreet lectus, vitae elementum augue sem non nisl.",1200451010,38
|
||||
"Vivamus sem purus", "Vivamus sem purus, viverra eget faucibus et, imperdiet vel massa.",1200551010,40
|
||||
"Ut id nisl", "Morbi suscipit tincidunt ultrices. Suspendisse ornare aliquet elit ac accumsan.",1200121010,41
|
||||
"Sed libero leo", "Phasellus ut sem sit amet justo sagittis placerat.",1200202010,42
|
||||
"Quisque eros nunc", "Quisque eros nunc, iaculis id bibendum ut, imperdiet ut sem. Donec mi quam, ultricies sit amet ornare et, lacinia non libero.",1201222010,43
|
||||
"Vestibulum vulputate", "Vestibulum vulputate, lacus quis fringilla imperdiet, nisi mi consequat lacus, eu sodales nisl nisi venenatis lacus.",1200022010,44
|
||||
"Suspendisse sed", "Suspendisse sed est eget quam imperdiet laoreet.",1202200010,45
|
||||
"Duis a lacus odio", "Duis a lacus odio. Nam luctus sapien id leo vestibulum tristique. Cras eu nisi velit, a aliquet turpis. Maecenas ligula est, ullamcorper vel placerat sit amet, scelerisque et lectus. Nunc velit massa; scelerisque et pretium non, sollicitudin vel tellus? Donec leo turpis, tempus dignissim placerat vel, venenatis a augue. Etiam condimentum porttitor urna, quis scelerisque justo pulvinar eget. Fusce nec nibh non enim mattis posuere. Cras pulvinar erat eget ante gravida congue. Pellentesque ultrices metus ut nunc suscipit id imperdiet nunc ornare. Nam consectetur erat quis massa congue vehicula eget vestibulum turpis. Morbi ac eleifend felis.",1202200010,45
|
||||
"Vivamus tempor", "Vivamus tempor, mi a pulvinar convallis, massa enim pulvinar metus, nec fringilla quam ante eu erat. Cras dignissim, felis non euismod iaculis, est massa posuere diam, et auctor libero ipsum ac ipsum? Nullam iaculis, eros ac sodales sollicitudin; tellus ligula volutpat urna, eget mattis felis metus ac augue.",1202200010,46
|
||||
"Sed molestie", "Sed molestie dolor sit amet neque dictum egestas? Aliquam vitae dui mi. Phasellus fermentum volutpat augue, quis ornare tortor facilisis ac. Suspendisse potenti. Duis facilisis massa at elit pharetra sit amet condimentum est pharetra.",1202200010,47
|
||||
"Donec ut", "Donec ut est ipsum. Pellentesque porttitor eleifend neque non malesuada. Morbi sollicitudin varius dapibus. Morbi sit amet risus leo, eu suscipit urna. Suspendisse velit ligula, suscipit ac rhoncus eu, convallis in eros",1202100010,48
|
||||
"Duis ut dolor sem", "Duis ut dolor sem. Donec convallis, nunc quis pulvinar tempus, leo est blandit lacus, et elementum lectus nisl et purus. Mauris eros eros, iaculis volutpat pretium euismod, porta id arcu. Integer tellus lacus, imperdiet sed vulputate varius, dignissim vel nisi. In porta molestie fermentum.",1202222101,49
|
||||
"Fusce sodales luctus porta", "Fusce sodales luctus porta. Curabitur pellentesque tincidunt tristique. In hac habitasse platea dictumst.",1202123211,50
|
||||
"In egestas lectus a sapien", "In egestas lectus a sapien sollicitudin nec blandit metus scelerisque. Proin et tortor eget risus congue sollicitudin. In auctor interdum turpis porta commodo. Donec faucibus elementum nibh, a egestas nisi tincidunt id.",1202232323,51
|
||||
"Aliquam semper", "Aliquam semper egestas aliquet. Aliquam tristique velit sit amet leo sodales aliquam. Praesent cursus ipsum quis odio aliquet eu eleifend velit aliquam? Maecenas consequat lobortis augue, at venenatis enim hendrerit quis.",1202242452,52
|
||||
"Curabitur tortor", "Curabitur tortor turpis, commodo eu pretium ac, sollicitudin a augue. ",1201341344,53
|
||||
"Duis venenatis", "Duis venenatis lorem vel sapien suscipit consectetur. In vel lectus neque, ut rutrum sapien.",1204564533,54
|
||||
"Phasellus ipsum metus", "Phasellus ipsum metus; suscipit nec malesuada et, fermentum eu nulla. Vivamus id libero in ligula gravida tristique at sed nibh. Cras congue, risus posuere hendrerit pharetra, ante justo eleifend sem, vitae faucibus lacus neque rhoncus urna.",1123452333,55
|
||||
"Nullam porta", "Nullam porta, nisl eu ornare rhoncus, dolor tortor scelerisque justo, non placerat mauris purus vel mauris.",1067356233,56
|
||||
"", "Pellentesque eget ante sit amet turpis vestibulum posuere ut non ipsum. Suspendisse potenti. ",1202122311,57
|
||||
"Pellentesque eget ante sit", "Pellentesque fringilla mi eu diam fermentum condimentum",1200010001,58
|
||||
"Praesent pellentesque quam nec", "Praesent pellentesque quam nec ligula accumsan faucibus. Duis non nisi ante. Mauris eu ullamcorper urna.",1200000000,59
|
||||
"Pellentesque habitant morbi tristique", "Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Phasellus elit risus, interdum sed iaculis a, vehicula in eros.",1000000000,60
|
||||
"Mauris lobortis luctus risus mattis luctus", "Mauris lobortis luctus risus mattis luctus. Praesent metus mi, euismod quis accumsan vel, placerat id dui. Donec sed erat vel arcu hendrerit hendrerit nec posuere metus! Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas.",1202012011,61
|
||||
"Mauris sed felis ut tortor gravida", "Mauris sed felis ut tortor gravida vestibulum vel ac enim!",1202123943,62
|
||||
"Sed vehicula, ipsum non dignissim tristique", "Sed vehicula, ipsum non dignissim tristique, urna dui gravida elit, id tempor nunc eros sit amet ligula.",1202323423,63
|
||||
"Duis consequat sagittis lectus id semper", "Duis consequat sagittis lectus id semper. Phasellus semper ante at leo faucibus venenatis.",1203124344,64
|
||||
"Nunc malesuada convallis neque", "Nunc malesuada convallis neque ac tincidunt. Etiam hendrerit mi at arcu bibendum eget viverra mi fringilla.",1202334234,65
|
||||
"Donec et ante mi?", "Donec et ante mi? Nullam auctor suscipit nibh quis dignissim. Etiam non lorem eros, vel auctor quam.",1205646554,66
|
||||
"Cras consequat", "Cras consequat, ligula quis pulvinar ultrices, dui sem venenatis leo, et dignissim ante mi vitae ipsum.",1202345600,67
|
||||
"Suspendisse convallis tempor adipiscing", "Suspendisse convallis tempor adipiscing. Vivamus ut ullamcorper nulla.",1202203200,68
|
||||
"Vestibulum ante ipsum primis in faucibus orci luctus", "Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae.",1202202300,69
|
||||
"Maecenas consectetur quam ac risus iaculis pharetra", "Maecenas consectetur quam ac risus iaculis pharetra. Nam metus velit, mattis ac interdum ac, volutpat et diam.",1202323430,70
|
||||
"Ut odio massa", "Ut odio massa, luctus aliquam pretium non, imperdiet quis risus.",1202200000,71
|
||||
"Curabitur sapien neque", "Curabitur sapien neque, elementum nec iaculis non, commodo nec arcu.",1206000000,72
|
||||
"Duis a arcu felis", "Duis a arcu felis, id tristique lectus. Nullam porta mi vitae erat suscipit vulputate?",1202906458,73
|
||||
"Cras sollicitudin lobortis rutrum", "Cras sollicitudin lobortis rutrum. Nunc vitae nisl nec orci laoreet cursus.",1204534599,74
|
||||
"Cras fringilla commodo posuere", "Cras fringilla commodo posuere. Nam sed justo dolor, vel pharetra odio.",1205345344,75
|
||||
"In fringilla erat et mi consequat convallis", "In fringilla erat et mi consequat convallis. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas.",1202455443,76
|
||||
"Aliquam in tellus nibh", "Aliquam in tellus nibh, ut pharetra metus. Fusce tempor, lectus eget ultrices sagittis, ipsum est sagittis urna, vel porttitor magna sem ac diam.",1207566663,77
|
||||
"Nunc gravida, leo sed faucibus viverra", "Nunc gravida, leo sed faucibus viverra, orci sapien mollis tellus, sit amet venenatis odio augue eu nunc.",1203453245,78
|
||||
"Vestibulum tristique sodales arcu", "Vestibulum tristique sodales arcu, nec dignissim mauris rutrum et.",1202230010,79
|
||||
"Praesent porttitor viverra rhoncus", "Praesent porttitor viverra rhoncus! Nulla malesuada elit et diam semper quis vehicula metus euismod.",1209200010,80
|
Can't render this file because it contains an unexpected character in line 5 and column 16.
|
10
sites/all/modules/feeds/tests/feeds/nodes.csv
Normal file
10
sites/all/modules/feeds/tests/feeds/nodes.csv
Normal file
@@ -0,0 +1,10 @@
|
||||
Title,Body,published,GUID
|
||||
"Ut wisi enim ad minim veniam", "Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat.",205200720,2
|
||||
"Duis autem vel eum iriure dolor", "Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi.",428112720,3
|
||||
"Nam liber tempor", "Nam liber tempor cum soluta nobis eleifend option congue nihil imperdiet doming id quod mazim placerat facer possim assum.",1151766000,1
|
||||
Typi non habent"", "Typi non habent claritatem insitam; est usus legentis in iis qui facit eorum claritatem.",1256326995,4
|
||||
"Lorem ipsum","Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat.",1251936720,1
|
||||
"Investigationes demonstraverunt", "Investigationes demonstraverunt lectores legere me lius quod ii legunt saepius.",946702800,5
|
||||
"Claritas est etiam", "Claritas est etiam processus dynamicus, qui sequitur mutationem consuetudium lectorum.",438112720,6
|
||||
"Mirum est notare", "Mirum est notare quam littera gothica, quam nunc putamus parum claram, anteposuerit litterarum formas humanitatis per seacula quarta decima et quinta decima.",1151066000,7
|
||||
"Eodem modo typi", "Eodem modo typi, qui nunc nobis videntur parum clari, fiant sollemnes in futurum.",1201936720,8
|
Can't render this file because it contains an unexpected character in line 5 and column 16.
|
78
sites/all/modules/feeds/tests/feeds/nodes.csv.php
Normal file
78
sites/all/modules/feeds/tests/feeds/nodes.csv.php
Normal file
@@ -0,0 +1,78 @@
|
||||
<?php
|
||||
/**
|
||||
* @file
|
||||
* Result of nodes.csv file parsed by ParserCSV.inc
|
||||
*/
|
||||
|
||||
$control_result = array (
|
||||
0 =>
|
||||
array (
|
||||
0 => 'Title',
|
||||
1 => 'Body',
|
||||
2 => 'published',
|
||||
3 => 'GUID',
|
||||
),
|
||||
1 =>
|
||||
array (
|
||||
0 => 'Ut wisi enim ad minim veniam',
|
||||
1 => ' Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat.',
|
||||
2 => '205200720',
|
||||
3 => '2',
|
||||
),
|
||||
2 =>
|
||||
array (
|
||||
0 => 'Duis autem vel eum iriure dolor',
|
||||
1 => ' Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi.',
|
||||
2 => '428112720',
|
||||
3 => '3',
|
||||
),
|
||||
3 =>
|
||||
array (
|
||||
0 => 'Nam liber tempor',
|
||||
1 => ' Nam liber tempor cum soluta nobis eleifend option congue nihil imperdiet doming id quod mazim placerat facer possim assum.',
|
||||
2 => '1151766000',
|
||||
3 => '1',
|
||||
),
|
||||
4 =>
|
||||
array (
|
||||
0 => 'Typi non habent',
|
||||
1 => ' Typi non habent claritatem insitam; est usus legentis in iis qui facit eorum claritatem.',
|
||||
2 => '1256326995',
|
||||
3 => '4',
|
||||
),
|
||||
5 =>
|
||||
array (
|
||||
0 => 'Lorem ipsum',
|
||||
1 => 'Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat.',
|
||||
2 => '1251936720',
|
||||
3 => '1',
|
||||
),
|
||||
6 =>
|
||||
array (
|
||||
0 => 'Investigationes demonstraverunt',
|
||||
1 => ' Investigationes demonstraverunt lectores legere me lius quod ii legunt saepius.',
|
||||
2 => '946702800',
|
||||
3 => '5',
|
||||
),
|
||||
7 =>
|
||||
array (
|
||||
0 => 'Claritas est etiam',
|
||||
1 => ' Claritas est etiam processus dynamicus, qui sequitur mutationem consuetudium lectorum.',
|
||||
2 => '438112720',
|
||||
3 => '6',
|
||||
),
|
||||
8 =>
|
||||
array (
|
||||
0 => 'Mirum est notare',
|
||||
1 => ' Mirum est notare quam littera gothica, quam nunc putamus parum claram, anteposuerit litterarum formas humanitatis per seacula quarta decima et quinta decima.',
|
||||
2 => '1151066000',
|
||||
3 => '7',
|
||||
),
|
||||
9 =>
|
||||
array (
|
||||
0 => 'Eodem modo typi',
|
||||
1 => ' Eodem modo typi, qui nunc nobis videntur parum clari, fiant sollemnes in futurum.',
|
||||
2 => '1201936720',
|
||||
3 => '8',
|
||||
),
|
||||
);
|
10
sites/all/modules/feeds/tests/feeds/nodes.tsv
Normal file
10
sites/all/modules/feeds/tests/feeds/nodes.tsv
Normal file
@@ -0,0 +1,10 @@
|
||||
Title Body published GUID
|
||||
"Ut wisi enim ad minim veniam" "Ut wisi enim ad minim veniam quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat." 205200720 2
|
||||
"Duis autem vel eum iriure dolor" "Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi." 428112720 3
|
||||
"Nam liber tempor" "Nam liber tempor cum soluta nobis eleifend option congue nihil imperdiet doming id quod mazim placerat facer possim assum." 1151766000 1
|
||||
Typi non habent"" "Typi non habent claritatem insitam; est usus legentis in iis qui facit eorum claritatem." 1256326995 4
|
||||
"Lorem ipsum" "Lorem ipsum dolor sit amet consectetuer adipiscing elit sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat." 1251936720 1
|
||||
"Investigationes demonstraverunt" "Investigationes demonstraverunt lectores legere me lius quod ii legunt saepius." 946702800 5
|
||||
"Claritas est etiam" "Claritas est etiam processus dynamicus qui sequitur mutationem consuetudium lectorum." 438112720 6
|
||||
"Mirum est notare" "Mirum est notare quam littera gothica quam nunc putamus parum claram anteposuerit litterarum formas humanitatis per seacula quarta decima et quinta decima." 1151066000 7
|
||||
"Eodem modo typi" "Eodem modo typi qui nunc nobis videntur parum clari fiant sollemnes in futurum." 1201936720 8
|
Can't render this file because it contains an unexpected character in line 5 and column 16.
|
10
sites/all/modules/feeds/tests/feeds/nodes_changes.csv
Normal file
10
sites/all/modules/feeds/tests/feeds/nodes_changes.csv
Normal file
@@ -0,0 +1,10 @@
|
||||
Title,Body,published,GUID
|
||||
"Ut wisi enim ad minim veniam", "CHANGE Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat.",205200720,2
|
||||
"Duis autem vel eum CHANGE iriure dolor", "Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi.",428112720,3
|
||||
"Nam liber tempor", "Nam liber tempor cum soluta nobis eleifend option congue nihil imperdiet doming id quod mazim placerat facer possim assum.",1151766000,1
|
||||
Typi non habent"", "Typi CHANGE non habent claritatem insitam; est usus legentis in iis qui facit eorum claritatem.",1256326995,4
|
||||
"Lorem ipsum","Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat.",1251936720,1
|
||||
"Investigationes demonstraverunt", "Investigationes demonstraverunt lectores legere me lius quod ii legunt saepius.",946702800,5
|
||||
"Claritas CHANGE est etiam", "Claritas est etiam processus dynamicus, qui sequitur mutationem consuetudium lectorum.",438112720,6
|
||||
"Mirum est notare", "Mirum est notare quam littera gothica, quam nunc putamus parum claram, anteposuerit litterarum formas humanitatis per seacula quarta decima et quinta decima.",1151066000,7
|
||||
"Eodem modo typi", "Eodem modo typi, qui nunc nobis videntur parum clari, fiant sollemnes in futurum.",1201936720,8
|
Can't render this file because it contains an unexpected character in line 5 and column 16.
|
10
sites/all/modules/feeds/tests/feeds/path_alias.csv
Normal file
10
sites/all/modules/feeds/tests/feeds/path_alias.csv
Normal file
@@ -0,0 +1,10 @@
|
||||
Title,GUID,path
|
||||
pathauto1,1,path1
|
||||
pathauto2,2,path2
|
||||
pathauto3,3,path3
|
||||
pathauto4,4,path4
|
||||
pathauto5,5,path5
|
||||
pathauto6,6,path6
|
||||
pathauto7,7,path7
|
||||
pathauto8,8,path8
|
||||
pathauto9,9,path9
|
|
3
sites/all/modules/feeds/tests/feeds/profile.csv
Normal file
3
sites/all/modules/feeds/tests/feeds/profile.csv
Normal file
@@ -0,0 +1,3 @@
|
||||
name,mail,color,letter
|
||||
magna,auctor@tortor.com,red,alpha
|
||||
rhoncus,rhoncus@habitasse.org,blue,beta
|
|
27
sites/all/modules/feeds/tests/feeds/sitemap-example.xml
Normal file
27
sites/all/modules/feeds/tests/feeds/sitemap-example.xml
Normal file
@@ -0,0 +1,27 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
|
||||
<url>
|
||||
<loc>http://www.example.com/</loc>
|
||||
<lastmod>2005-01-01</lastmod>
|
||||
<changefreq>monthly</changefreq>
|
||||
<priority>0.8</priority>
|
||||
</url>
|
||||
<url>
|
||||
<loc>http://www.example.com/catalog?item=12&desc=vacation_hawaii</loc>
|
||||
<changefreq>weekly</changefreq>
|
||||
</url>
|
||||
<url>
|
||||
<loc>http://www.example.com/catalog?item=73&desc=vacation_new_zealand</loc>
|
||||
<lastmod>2004-12-23</lastmod>
|
||||
<changefreq>weekly</changefreq>
|
||||
</url>
|
||||
<url>
|
||||
<loc>http://www.example.com/catalog?item=74&desc=vacation_newfoundland</loc>
|
||||
<lastmod>2004-12-23T18:00:15+00:00</lastmod>
|
||||
<priority>0.3</priority>
|
||||
</url>
|
||||
<url>
|
||||
<loc>http://www.example.com/catalog?item=83&desc=vacation_usa</loc>
|
||||
<lastmod>2004-11-23</lastmod>
|
||||
</url>
|
||||
</urlset>
|
6
sites/all/modules/feeds/tests/feeds/users.csv
Normal file
6
sites/all/modules/feeds/tests/feeds/users.csv
Normal file
@@ -0,0 +1,6 @@
|
||||
name,mail,since,password
|
||||
Morticia,morticia@example.com,1244347500,mort
|
||||
Fester,fester@example.com,1241865600,fest
|
||||
Gomez,gomez@example.com,1228572000,gome
|
||||
Wednesday,wednesdayexample.com,1228347137,wedn
|
||||
Pugsley,pugsley@example,1228260225,pugs
|
|
42
sites/all/modules/feeds/tests/feeds_date_time.test
Normal file
42
sites/all/modules/feeds/tests/feeds_date_time.test
Normal file
@@ -0,0 +1,42 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Tests for FeedsDateTime class.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Test FeedsDateTime class.
|
||||
*
|
||||
* Using DrupalWebTestCase as DrupalUnitTestCase is broken in SimpleTest 2.8.
|
||||
* Not inheriting from Feeds base class as ParserCSV should be moved out of
|
||||
* Feeds at some time.
|
||||
*/
|
||||
class FeedsDateTimeTest extends FeedsWebTestCase {
|
||||
protected $profile = 'testing';
|
||||
|
||||
public static function getInfo() {
|
||||
return array(
|
||||
'name' => 'FeedsDateTime unit tests',
|
||||
'description' => 'Unit tests for Feeds date handling.',
|
||||
'group' => 'Feeds',
|
||||
);
|
||||
}
|
||||
|
||||
public function setUp() {
|
||||
parent::setUp();
|
||||
module_load_include('inc', 'feeds' , 'plugins/FeedsParser');
|
||||
}
|
||||
|
||||
/**
|
||||
* Dispatch tests, only use one entry point method testX to save time.
|
||||
*/
|
||||
public function test() {
|
||||
$date = new FeedsDateTime('2010-20-12');
|
||||
$this->assertTrue(is_numeric($date->format('U')));
|
||||
$date = new FeedsDateTime('created');
|
||||
$this->assertTrue(is_numeric($date->format('U')));
|
||||
$date = new FeedsDateTime('12/3/2009 20:00:10');
|
||||
$this->assertTrue(is_numeric($date->format('U')));
|
||||
}
|
||||
}
|
70
sites/all/modules/feeds/tests/feeds_fetcher_file.test
Normal file
70
sites/all/modules/feeds/tests/feeds_fetcher_file.test
Normal file
@@ -0,0 +1,70 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* File fetcher tests.
|
||||
*/
|
||||
|
||||
/**
|
||||
* File fetcher test class.
|
||||
*/
|
||||
class FeedsFileFetcherTestCase extends FeedsWebTestCase {
|
||||
public static function getInfo() {
|
||||
return array(
|
||||
'name' => 'File fetcher',
|
||||
'description' => 'Tests for file fetcher plugin.',
|
||||
'group' => 'Feeds',
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Test scheduling on cron.
|
||||
*/
|
||||
public function test() {
|
||||
// Set up an importer.
|
||||
$this->createImporterConfiguration('Node import', 'node');
|
||||
// Set and configure plugins and mappings.
|
||||
$edit = array(
|
||||
'content_type' => '',
|
||||
);
|
||||
$this->drupalPost('admin/structure/feeds/node/settings', $edit, 'Save');
|
||||
$this->setPlugin('node', 'FeedsFileFetcher');
|
||||
$this->setPlugin('node', 'FeedsCSVParser');
|
||||
$mappings = array(
|
||||
'0' => array(
|
||||
'source' => 'title',
|
||||
'target' => 'title',
|
||||
),
|
||||
);
|
||||
$this->addMappings('node', $mappings);
|
||||
// Straight up upload is covered in other tests, focus on direct mode
|
||||
// and file batching here.
|
||||
$this->setSettings('node', 'FeedsFileFetcher', array('direct' => TRUE));
|
||||
|
||||
// Verify that invalid paths are not accepted.
|
||||
foreach (array('private://', '/tmp/') as $path) {
|
||||
$edit = array(
|
||||
'feeds[FeedsFileFetcher][source]' => $path,
|
||||
);
|
||||
$this->drupalPost('import/node', $edit, t('Import'));
|
||||
$this->assertText("File needs to reside within the site's file directory, its path needs to start with public://.");
|
||||
$count = db_query("SELECT COUNT(*) FROM {feeds_source} WHERE feed_nid = 0")->fetchField();
|
||||
$this->assertEqual($count, 0);
|
||||
}
|
||||
|
||||
// Verify batching through directories.
|
||||
// Copy directory of files.
|
||||
$dir = 'public://batchtest';
|
||||
$this->copyDir($this->absolutePath() . '/tests/feeds/batch', $dir);
|
||||
|
||||
// Ingest directory of files. Set limit to 5 to force processor to batch,
|
||||
// too.
|
||||
variable_set('feeds_process_limit', 5);
|
||||
$edit = array(
|
||||
'feeds[FeedsFileFetcher][source]' => $dir,
|
||||
);
|
||||
$this->drupalPost('import/node', $edit, t('Import'));
|
||||
$this->assertText('Created 18 nodes');
|
||||
}
|
||||
}
|
160
sites/all/modules/feeds/tests/feeds_mapper.test
Normal file
160
sites/all/modules/feeds/tests/feeds_mapper.test
Normal file
@@ -0,0 +1,160 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Helper class with auxiliary functions for feeds mapper module tests.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Base class for implementing Feeds Mapper test cases.
|
||||
*/
|
||||
class FeedsMapperTestCase extends FeedsWebTestCase {
|
||||
|
||||
// A lookup map to select the widget for each field type.
|
||||
private static $field_widgets = array(
|
||||
'date' => 'date_text',
|
||||
'datestamp' => 'date_text',
|
||||
'datetime' => 'date_text',
|
||||
'number_decimal' => 'number',
|
||||
'email' => 'email_textfield',
|
||||
'emimage' => 'emimage_textfields',
|
||||
'emaudio' => 'emaudio_textfields',
|
||||
'filefield' => 'filefield_widget',
|
||||
'image' => 'imagefield_widget',
|
||||
'link_field' => 'link_field',
|
||||
'number_float' => 'number',
|
||||
'number_integer' => 'number',
|
||||
'nodereference' => 'nodereference_select',
|
||||
'text' => 'text_textfield',
|
||||
'userreference' => 'userreference_select',
|
||||
);
|
||||
|
||||
/**
|
||||
* Assert that a form field for the given field with the given value
|
||||
* exists in the current form.
|
||||
*
|
||||
* @param $field_name
|
||||
* The name of the field.
|
||||
* @param $value
|
||||
* The (raw) value expected for the field.
|
||||
* @param $index
|
||||
* The index of the field (for q multi-valued field).
|
||||
*
|
||||
* @see FeedsMapperTestCase::getFormFieldsNames()
|
||||
* @see FeedsMapperTestCase::getFormFieldsValues()
|
||||
*/
|
||||
protected function assertNodeFieldValue($field_name, $value, $index = 0) {
|
||||
$names = $this->getFormFieldsNames($field_name, $index);
|
||||
$values = $this->getFormFieldsValues($field_name, $value);
|
||||
foreach ($names as $k => $name) {
|
||||
$value = $values[$k];
|
||||
$this->assertFieldByName($name, $value, t('Found form field %name for %field_name with the expected value.', array('%name' => $name, '%field_name' => $field_name)));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the form fields names for a given CCK field. Default implementation
|
||||
* provides support for a single form field with the following name pattern
|
||||
* <code>"field_{$field_name}[{$index}][value]"</code>
|
||||
*
|
||||
* @param $field_name
|
||||
* The name of the CCK field.
|
||||
* @param $index
|
||||
* The index of the field (for q multi-valued field).
|
||||
*
|
||||
* @return
|
||||
* An array of form field names.
|
||||
*/
|
||||
protected function getFormFieldsNames($field_name, $index) {
|
||||
return array("field_{$field_name}[und][{$index}][value]");
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the form fields values for a given CCK field. Default implementation
|
||||
* returns a single element array with $value casted to a string.
|
||||
*
|
||||
* @param $field_name
|
||||
* The name of the CCK field.
|
||||
* @param $value
|
||||
* The (raw) value expected for the CCK field.
|
||||
* @return An array of form field values.
|
||||
*/
|
||||
protected function getFormFieldsValues($field_name, $value) {
|
||||
return array((string)$value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new content-type, and add a field to it. Mostly copied from
|
||||
* cck/tests/content.crud.test ContentUICrud::testAddFieldUI
|
||||
*
|
||||
* @param $settings
|
||||
* (Optional) An array of settings to pass through to
|
||||
* drupalCreateContentType().
|
||||
* @param $fields
|
||||
* (Optional) an keyed array of $field_name => $field_type used to add additional
|
||||
* fields to the new content type.
|
||||
*
|
||||
* @return
|
||||
* The machine name of the new content type.
|
||||
*
|
||||
* @see DrupalWebTestCase::drupalCreateContentType()
|
||||
*/
|
||||
final protected function createContentType(array $settings = array(), array $fields = array()) {
|
||||
$type = $this->drupalCreateContentType($settings);
|
||||
$typename = $type->type;
|
||||
|
||||
$admin_type_url = 'admin/structure/types/manage/' . str_replace('_', '-', $typename);
|
||||
|
||||
// Create the fields
|
||||
foreach ($fields as $field_name => $options) {
|
||||
if (is_string($options)) {
|
||||
$options = array('type' => $options);
|
||||
}
|
||||
$field_type = isset($options['type']) ? $options['type'] : 'text';
|
||||
$field_widget = isset($options['widget']) ? $options['widget'] : $this->selectFieldWidget($field_name, $field_type);
|
||||
$this->assertTrue($field_widget !== NULL, "Field type $field_type supported");
|
||||
$label = $field_name . '_' . $field_type . '_label';
|
||||
$edit = array(
|
||||
'fields[_add_new_field][label]' => $label,
|
||||
'fields[_add_new_field][field_name]' => $field_name,
|
||||
'fields[_add_new_field][type]' => $field_type,
|
||||
'fields[_add_new_field][widget_type]' => $field_widget,
|
||||
);
|
||||
$this->drupalPost($admin_type_url . '/fields', $edit, 'Save');
|
||||
|
||||
// (Default) Configure the field.
|
||||
$edit = isset($options['settings']) ? $options['settings'] : array();
|
||||
$this->drupalPost(NULL, $edit, 'Save field settings');
|
||||
$this->assertText('Updated field ' . $label . ' field settings.');
|
||||
|
||||
$edit = isset($options['instance_settings']) ? $options['instance_settings'] : array();
|
||||
$this->drupalPost(NULL, $edit, 'Save settings');
|
||||
$this->assertText('Saved ' . $label . ' configuration.');
|
||||
}
|
||||
|
||||
return $typename;
|
||||
}
|
||||
|
||||
/**
|
||||
* Select the widget for the field. Default implementation provides widgets
|
||||
* for Date, Number, Text, Node reference, User reference, Email, Emfield,
|
||||
* Filefield, Image, and Link.
|
||||
*
|
||||
* Extracted as a method to allow test implementations to add widgets for
|
||||
* the tested CCK field type(s). $field_name allow to test the same
|
||||
* field type with different widget (is this useful ?)
|
||||
*
|
||||
* @param $field_name
|
||||
* The name of the field.
|
||||
* @param $field_type
|
||||
* The CCK type of the field.
|
||||
*
|
||||
* @return
|
||||
* The widget for this field, or NULL if the field_type is not
|
||||
* supported by this test class.
|
||||
*/
|
||||
protected function selectFieldWidget($field_name, $field_type) {
|
||||
$field_widgets = FeedsMapperTestCase::$field_widgets;
|
||||
return isset($field_widgets[$field_type]) ? $field_widgets[$field_type] : NULL;
|
||||
}
|
||||
}
|
115
sites/all/modules/feeds/tests/feeds_mapper_config.test
Normal file
115
sites/all/modules/feeds/tests/feeds_mapper_config.test
Normal file
@@ -0,0 +1,115 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Test cases for Feeds mapping configuration form.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Class for testing basic Feeds ajax mapping configurtaion form behavior.
|
||||
*/
|
||||
class FeedsMapperConfigTestCase extends FeedsMapperTestCase {
|
||||
public static function getInfo() {
|
||||
return array(
|
||||
'name' => 'Mapper: Config',
|
||||
'description' => 'Test the mapper configuration UI.',
|
||||
'group' => 'Feeds',
|
||||
);
|
||||
}
|
||||
|
||||
public function setUp() {
|
||||
parent::setUp(array('feeds_tests'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Basic test of mapping configuration.
|
||||
*/
|
||||
public function test() {
|
||||
// Create importer configuration.
|
||||
$this->createImporterConfiguration();
|
||||
$this->addMappings('syndication', array(
|
||||
array(
|
||||
'source' => 'url',
|
||||
'target' => 'test_target',
|
||||
),
|
||||
));
|
||||
|
||||
// Click gear to get form.
|
||||
$this->drupalPostAJAX(NULL, array(), 'mapping_settings_edit_0');
|
||||
|
||||
// Set some settings.
|
||||
$edit = array(
|
||||
'config[0][settings][checkbox]' => 1,
|
||||
'config[0][settings][textfield]' => 'Some text',
|
||||
'config[0][settings][textarea]' => 'Textarea value: Didery dofffffffffffffffffffffffffffffffffffff',
|
||||
'config[0][settings][radios]' => 'option1',
|
||||
'config[0][settings][select]' => 'option4',
|
||||
);
|
||||
$this->drupalPostAJAX(NULL, $edit, 'mapping_settings_update_0');
|
||||
|
||||
// Click Save.
|
||||
$this->drupalPost(NULL, array(), t('Save'));
|
||||
|
||||
// Reload.
|
||||
$this->drupalGet('admin/structure/feeds/syndication/mapping');
|
||||
|
||||
// See if our settings were saved.
|
||||
$this->assertText('Checkbox active.');
|
||||
$this->assertText('Textfield value: Some text');
|
||||
$this->assertText('Textarea value: Didery dofffffffffffffffffffffffffffffffffffff');
|
||||
$this->assertText('Radios value: Option 1');
|
||||
$this->assertText('Select value: Another One');
|
||||
|
||||
// Check that settings are in db.
|
||||
$config = unserialize(db_query("SELECT config FROM {feeds_importer} WHERE id='syndication'")->fetchField());
|
||||
|
||||
$settings = $config['processor']['config']['mappings'][0];
|
||||
$this->assertEqual($settings['checkbox'], 1);
|
||||
$this->assertEqual($settings['textfield'], 'Some text');
|
||||
$this->assertEqual($settings['textarea'], 'Textarea value: Didery dofffffffffffffffffffffffffffffffffffff');
|
||||
$this->assertEqual($settings['radios'], 'option1');
|
||||
$this->assertEqual($settings['select'], 'option4');
|
||||
|
||||
|
||||
// Check that form validation works.
|
||||
// Click gear to get form.
|
||||
$this->drupalPostAJAX(NULL, array(), 'mapping_settings_edit_0');
|
||||
|
||||
// Set some settings.
|
||||
$edit = array(
|
||||
// Required form item.
|
||||
'config[0][settings][textfield]' => '',
|
||||
);
|
||||
$this->drupalPostAJAX(NULL, $edit, 'mapping_settings_update_0');
|
||||
$this->assertText('A text field field is required.');
|
||||
$this->drupalPost(NULL, array(), t('Save'));
|
||||
// Reload.
|
||||
$this->drupalGet('admin/structure/feeds/syndication/mapping');
|
||||
// Value has not changed.
|
||||
$this->assertText('Textfield value: Some text');
|
||||
|
||||
// Check that multiple mappings work.
|
||||
$this->addMappings('syndication', array(
|
||||
1 => array(
|
||||
'source' => 'url',
|
||||
'target' => 'test_target',
|
||||
),
|
||||
));
|
||||
$this->assertText('Checkbox active.');
|
||||
$this->assertText('Checkbox inactive.');
|
||||
// Click gear to get form.
|
||||
$this->drupalPostAJAX(NULL, array(), 'mapping_settings_edit_1');
|
||||
// Set some settings.
|
||||
$edit = array(
|
||||
'config[1][settings][textfield]' => 'Second mapping text',
|
||||
);
|
||||
$this->drupalPostAJAX(NULL, $edit, 'mapping_settings_update_1');
|
||||
// Click Save.
|
||||
$this->drupalPost(NULL, array(), t('Save'));
|
||||
// Reload.
|
||||
$this->drupalGet('admin/structure/feeds/syndication/mapping');
|
||||
$this->assertText('Checkbox active.');
|
||||
$this->assertText('Checkbox inactive.');
|
||||
$this->assertText('Second mapping text');
|
||||
}
|
||||
}
|
100
sites/all/modules/feeds/tests/feeds_mapper_date.test
Normal file
100
sites/all/modules/feeds/tests/feeds_mapper_date.test
Normal file
@@ -0,0 +1,100 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Test case for CCK date field mapper mappers/date.inc.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Class for testing Feeds <em>content</em> mapper.
|
||||
*
|
||||
* @todo: Add test method iCal
|
||||
* @todo: Add test method for end date
|
||||
*/
|
||||
class FeedsMapperDateTestCase extends FeedsMapperTestCase {
|
||||
public static function getInfo() {
|
||||
return array(
|
||||
'name' => 'Mapper: Date',
|
||||
'description' => 'Test Feeds Mapper support for CCK Date fields.',
|
||||
'group' => 'Feeds',
|
||||
'dependencies' => array('date'),
|
||||
);
|
||||
}
|
||||
|
||||
public function setUp() {
|
||||
parent::setUp(array('date_api', 'date'));
|
||||
variable_set('date_default_timezone', 'UTC');
|
||||
}
|
||||
|
||||
/**
|
||||
* Basic test loading a single entry CSV file.
|
||||
*/
|
||||
public function test() {
|
||||
$this->drupalGet('admin/config/regional/settings');
|
||||
|
||||
// Create content type.
|
||||
$typename = $this->createContentType(array(), array(
|
||||
'date' => 'date',
|
||||
'datestamp' => 'datestamp',
|
||||
//'datetime' => 'datetime', // REMOVED because the field is broken ATM.
|
||||
));
|
||||
|
||||
// Create and configure importer.
|
||||
$this->createImporterConfiguration('Date RSS', 'daterss');
|
||||
$this->setSettings('daterss', NULL, array('content_type' => '', 'import_period' => FEEDS_SCHEDULE_NEVER));
|
||||
$this->setPlugin('daterss', 'FeedsFileFetcher');
|
||||
$this->setPlugin('daterss', 'FeedsSyndicationParser');
|
||||
$this->setSettings('daterss', 'FeedsNodeProcessor', array('content_type' => $typename));
|
||||
$this->addMappings('daterss', array(
|
||||
0 => array(
|
||||
'source' => 'title',
|
||||
'target' => 'title',
|
||||
),
|
||||
1 => array(
|
||||
'source' => 'description',
|
||||
'target' => 'body',
|
||||
),
|
||||
2 => array(
|
||||
'source' => 'timestamp',
|
||||
'target' => 'field_date:start',
|
||||
),
|
||||
3 => array(
|
||||
'source' => 'timestamp',
|
||||
'target' => 'field_datestamp:start',
|
||||
),
|
||||
));
|
||||
|
||||
$edit = array(
|
||||
'allowed_extensions' => 'rss2',
|
||||
);
|
||||
$this->drupalPost('admin/structure/feeds/daterss/settings/FeedsFileFetcher', $edit, 'Save');
|
||||
|
||||
// Import CSV file.
|
||||
$this->importFile('daterss', $this->absolutePath() . '/tests/feeds/googlenewstz.rss2');
|
||||
$this->assertText('Created 6 nodes');
|
||||
|
||||
// Check the imported nodes.
|
||||
$values = array(
|
||||
'01/06/2010 - 19:26',
|
||||
'01/06/2010 - 10:21',
|
||||
'01/06/2010 - 13:42',
|
||||
'01/06/2010 - 06:05',
|
||||
'01/06/2010 - 11:26',
|
||||
'01/07/2010 - 00:26',
|
||||
);
|
||||
for ($i = 1; $i <= 6; $i++) {
|
||||
$this->drupalGet("node/$i/edit");
|
||||
$this->assertNodeFieldValue('date', $values[$i-1]);
|
||||
$this->assertNodeFieldValue('datestamp', $values[$i-1]);
|
||||
}
|
||||
}
|
||||
|
||||
protected function getFormFieldsNames($field_name, $index) {
|
||||
if (in_array($field_name, array('date', 'datetime', 'datestamp'))) {
|
||||
return array("field_{$field_name}[und][{$index}][value][date]");
|
||||
}
|
||||
else {
|
||||
return parent::getFormFieldsNames($field_name, $index);
|
||||
}
|
||||
}
|
||||
}
|
90
sites/all/modules/feeds/tests/feeds_mapper_field.test
Normal file
90
sites/all/modules/feeds/tests/feeds_mapper_field.test
Normal file
@@ -0,0 +1,90 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Test case for simple CCK field mapper mappers/content.inc.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Class for testing Feeds field mapper.
|
||||
*/
|
||||
class FeedsMapperFieldTestCase extends FeedsMapperTestCase {
|
||||
public static function getInfo() {
|
||||
return array(
|
||||
'name' => 'Mapper: Fields',
|
||||
'description' => 'Test Feeds Mapper support for fields.',
|
||||
'group' => 'Feeds',
|
||||
);
|
||||
}
|
||||
|
||||
public function setUp() {
|
||||
parent::setUp(array('number'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Basic test loading a double entry CSV file.
|
||||
*/
|
||||
function test() {
|
||||
// Create content type.
|
||||
$typename = $this->createContentType(array(), array(
|
||||
'alpha' => 'text',
|
||||
'beta' => 'number_integer',
|
||||
'gamma' => 'number_decimal',
|
||||
'delta' => 'number_float',
|
||||
));
|
||||
|
||||
// Create and configure importer.
|
||||
$this->createImporterConfiguration('Content CSV', 'csv');
|
||||
$this->setSettings('csv', NULL, array('content_type' => '', 'import_period' => FEEDS_SCHEDULE_NEVER));
|
||||
$this->setPlugin('csv', 'FeedsFileFetcher');
|
||||
$this->setPlugin('csv', 'FeedsCSVParser');
|
||||
$this->setSettings('csv', 'FeedsNodeProcessor', array('content_type' => $typename));
|
||||
$this->addMappings('csv', array(
|
||||
0 => array(
|
||||
'source' => 'title',
|
||||
'target' => 'title',
|
||||
),
|
||||
1 => array(
|
||||
'source' => 'created',
|
||||
'target' => 'created',
|
||||
),
|
||||
2 => array(
|
||||
'source' => 'body',
|
||||
'target' => 'body',
|
||||
),
|
||||
3 => array(
|
||||
'source' => 'alpha',
|
||||
'target' => 'field_alpha',
|
||||
),
|
||||
4 => array(
|
||||
'source' => 'beta',
|
||||
'target' => 'field_beta',
|
||||
),
|
||||
5 => array(
|
||||
'source' => 'gamma',
|
||||
'target' => 'field_gamma',
|
||||
),
|
||||
6 => array(
|
||||
'source' => 'delta',
|
||||
'target' => 'field_delta',
|
||||
),
|
||||
));
|
||||
|
||||
// Import CSV file.
|
||||
$this->importFile('csv', $this->absolutePath() . '/tests/feeds/content.csv');
|
||||
$this->assertText('Created 2 nodes');
|
||||
|
||||
// Check the two imported files.
|
||||
$this->drupalGet('node/1/edit');
|
||||
$this->assertNodeFieldValue('alpha', 'Lorem');
|
||||
$this->assertNodeFieldValue('beta', '42');
|
||||
$this->assertNodeFieldValue('gamma', '4.20');
|
||||
$this->assertNodeFieldValue('delta', '3.14159');
|
||||
|
||||
$this->drupalGet('node/2/edit');
|
||||
$this->assertNodeFieldValue('alpha', 'Ut wisi');
|
||||
$this->assertNodeFieldValue('beta', '32');
|
||||
$this->assertNodeFieldValue('gamma', '1.20');
|
||||
$this->assertNodeFieldValue('delta', '5.62951');
|
||||
}
|
||||
}
|
180
sites/all/modules/feeds/tests/feeds_mapper_file.test
Normal file
180
sites/all/modules/feeds/tests/feeds_mapper_file.test
Normal file
@@ -0,0 +1,180 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Test case for Filefield mapper mappers/filefield.inc.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Class for testing Feeds file mapper.
|
||||
*
|
||||
* @todo Add a test for enclosures using a local file that is
|
||||
* a) in place and that
|
||||
* b) needs to be copied from one location to another.
|
||||
*/
|
||||
class FeedsMapperFileTestCase extends FeedsMapperTestCase {
|
||||
public static function getInfo() {
|
||||
return array(
|
||||
'name' => 'Mapper: File field',
|
||||
'description' => 'Test Feeds Mapper support for file fields. <strong>Requires SimplePie library</strong>.',
|
||||
'group' => 'Feeds',
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Basic test loading a single entry CSV file.
|
||||
*/
|
||||
public function test() {
|
||||
// If this is unset (or FALSE) http_request.inc will use curl, and will generate a 404
|
||||
// for this feel url provided by feeds_tests. However, if feeds_tests was enabled in your
|
||||
// site before running the test, it will work fine. Since it is truly screwy, lets just
|
||||
// force it to use drupal_http_request for this test case.
|
||||
variable_set('feeds_never_use_curl', TRUE);
|
||||
variable_set('clean_url', TRUE);
|
||||
|
||||
// Only download simplepie if the plugin doesn't already exist somewhere.
|
||||
// People running tests locally might have it.
|
||||
if (!feeds_simplepie_exists()) {
|
||||
$this->downloadExtractSimplePie('1.3');
|
||||
$this->assertTrue(feeds_simplepie_exists());
|
||||
// Reset all the caches!
|
||||
$this->resetAll();
|
||||
}
|
||||
$typename = $this->createContentType(array(), array('files' => 'file'));
|
||||
|
||||
// 1) Test mapping remote resources to file field.
|
||||
|
||||
// Create importer configuration.
|
||||
$this->createImporterConfiguration();
|
||||
$this->setPlugin('syndication', 'FeedsSimplePieParser');
|
||||
$this->setSettings('syndication', 'FeedsNodeProcessor', array('content_type' => $typename));
|
||||
$this->addMappings('syndication', array(
|
||||
0 => array(
|
||||
'source' => 'title',
|
||||
'target' => 'title'
|
||||
),
|
||||
1 => array(
|
||||
'source' => 'timestamp',
|
||||
'target' => 'created'
|
||||
),
|
||||
2 => array(
|
||||
'source' => 'enclosures',
|
||||
'target' => 'field_files'
|
||||
),
|
||||
));
|
||||
$nid = $this->createFeedNode('syndication', $GLOBALS['base_url'] . '/testing/feeds/flickr.xml');
|
||||
$this->assertText('Created 5 nodes');
|
||||
|
||||
$files = $this->_testFiles();
|
||||
$entities = db_select('feeds_item')
|
||||
->fields('feeds_item', array('entity_id'))
|
||||
->condition('id', 'syndication')
|
||||
->execute();
|
||||
foreach ($entities as $entity) {
|
||||
$this->drupalGet('node/' . $entity->entity_id . '/edit');
|
||||
$f = new FeedsEnclosure(array_shift($files), NULL);
|
||||
$this->assertText($f->getLocalValue());
|
||||
}
|
||||
|
||||
// 2) Test mapping local resources to file field.
|
||||
|
||||
// Copy directory of files, CSV file expects them in public://images, point
|
||||
// file field to a 'resources' directory. Feeds should copy files from
|
||||
// images/ to resources/ on import.
|
||||
$this->copyDir($this->absolutePath() . '/tests/feeds/assets', 'public://images');
|
||||
$edit = array(
|
||||
'instance[settings][file_directory]' => 'resources',
|
||||
);
|
||||
$this->drupalPost('admin/structure/types/manage/' . $typename . '/fields/field_files', $edit, t('Save settings'));
|
||||
|
||||
// Create a CSV importer configuration.
|
||||
$this->createImporterConfiguration('Node import from CSV', 'node');
|
||||
$this->setPlugin('node', 'FeedsCSVParser');
|
||||
$this->setSettings('node', 'FeedsNodeProcessor', array('content_type' => $typename));
|
||||
$this->addMappings('node', array(
|
||||
0 => array(
|
||||
'source' => 'title',
|
||||
'target' => 'title'
|
||||
),
|
||||
1 => array(
|
||||
'source' => 'file',
|
||||
'target' => 'field_files'
|
||||
),
|
||||
));
|
||||
$edit = array(
|
||||
'content_type' => '',
|
||||
);
|
||||
$this->drupalPost('admin/structure/feeds/node/settings', $edit, 'Save');
|
||||
|
||||
// Import.
|
||||
$edit = array(
|
||||
'feeds[FeedsHTTPFetcher][source]' => $GLOBALS['base_url'] . '/testing/feeds/files.csv',
|
||||
);
|
||||
$this->drupalPost('import/node', $edit, 'Import');
|
||||
$this->assertText('Created 5 nodes');
|
||||
|
||||
// Assert: files should be in resources/.
|
||||
$files = $this->_testFiles();
|
||||
$entities = db_select('feeds_item')
|
||||
->fields('feeds_item', array('entity_id'))
|
||||
->condition('id', 'node')
|
||||
->execute();
|
||||
foreach ($entities as $entity) {
|
||||
$this->drupalGet('node/' . $entity->entity_id . '/edit');
|
||||
$f = new FeedsEnclosure(array_shift($files), NULL);
|
||||
$this->assertRaw('resources/' . $f->getUrlEncodedValue());
|
||||
}
|
||||
|
||||
// 3) Test mapping of local resources, this time leave files in place.
|
||||
$this->drupalPost('import/node/delete-items', array(), 'Delete');
|
||||
// Setting the fields file directory to images will make copying files
|
||||
// obsolete.
|
||||
$edit = array(
|
||||
'instance[settings][file_directory]' => 'images',
|
||||
);
|
||||
$this->drupalPost('admin/structure/types/manage/' . $typename . '/fields/field_files', $edit, t('Save settings'));
|
||||
$edit = array(
|
||||
'feeds[FeedsHTTPFetcher][source]' => $GLOBALS['base_url'] . '/testing/feeds/files.csv',
|
||||
);
|
||||
$this->drupalPost('import/node', $edit, 'Import');
|
||||
$this->assertText('Created 5 nodes');
|
||||
|
||||
// Assert: files should be in images/ now.
|
||||
$files = $this->_testFiles();
|
||||
$entities = db_select('feeds_item')
|
||||
->fields('feeds_item', array('entity_id'))
|
||||
->condition('id', 'node')
|
||||
->execute();
|
||||
foreach ($entities as $entity) {
|
||||
$this->drupalGet('node/' . $entity->entity_id . '/edit');
|
||||
$f = new FeedsEnclosure(array_shift($files), NULL);
|
||||
$this->assertRaw('images/' . $f->getUrlEncodedValue());
|
||||
}
|
||||
|
||||
// Deleting all imported items will delete the files from the images/ dir.
|
||||
// @todo: for some reason the first file does not get deleted.
|
||||
// $this->drupalPost('import/node/delete-items', array(), 'Delete');
|
||||
// foreach ($this->_testFiles() as $file) {
|
||||
// $this->assertFalse(is_file("public://images/$file"));
|
||||
// }
|
||||
}
|
||||
|
||||
/**
|
||||
* Lists test files.
|
||||
*/
|
||||
public function _testFiles() {
|
||||
return array('tubing.jpeg', 'foosball.jpeg', 'attersee.jpeg', 'hstreet.jpeg', 'la fayette.jpeg');
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle file field widgets.
|
||||
*/
|
||||
public function selectFieldWidget($fied_name, $field_type) {
|
||||
if ($field_type == 'file') {
|
||||
return 'file_generic';
|
||||
}
|
||||
else {
|
||||
return parent::selectFieldWidget($fied_name, $field_type);
|
||||
}
|
||||
}
|
||||
}
|
157
sites/all/modules/feeds/tests/feeds_mapper_link.test
Normal file
157
sites/all/modules/feeds/tests/feeds_mapper_link.test
Normal file
@@ -0,0 +1,157 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Test case for CCK link mapper mappers/date.inc.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Class for testing Feeds <em>link</em> mapper.
|
||||
*/
|
||||
class FeedsMapperLinkTestCase extends FeedsMapperTestCase {
|
||||
public static function getInfo() {
|
||||
return array(
|
||||
'name' => 'Mapper: Link',
|
||||
'description' => 'Test Feeds Mapper support for Link fields.',
|
||||
'group' => 'Feeds',
|
||||
'dependencies' => array('link'),
|
||||
);
|
||||
}
|
||||
|
||||
public function setUp() {
|
||||
parent::setUp(array('link'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Basic test loading a single entry CSV file.
|
||||
*/
|
||||
public function test() {
|
||||
$static_title = $this->randomName();
|
||||
|
||||
// Create content type.
|
||||
$typename = $this->createContentType(array(), array(
|
||||
'alpha' => array(
|
||||
'type' => 'link_field',
|
||||
'instance_settings' => array(
|
||||
'instance[settings][title]' => 'required',
|
||||
),
|
||||
),
|
||||
'beta' => array(
|
||||
'type' => 'link_field',
|
||||
'instance_settings' => array(
|
||||
'instance[settings][title]' => 'none',
|
||||
),
|
||||
),
|
||||
'gamma' => array(
|
||||
'type' => 'link_field',
|
||||
'instance_settings' => array(
|
||||
'instance[settings][title]' => 'optional',
|
||||
),
|
||||
),
|
||||
'omega' => array(
|
||||
'type' => 'link_field',
|
||||
'instance_settings' => array(
|
||||
'instance[settings][title]' => 'value',
|
||||
'instance[settings][title_value]' => $static_title,
|
||||
),
|
||||
),
|
||||
));
|
||||
|
||||
// Create importer configuration.
|
||||
$this->createImporterConfiguration(); //Create a default importer configuration
|
||||
$this->setSettings('syndication', 'FeedsNodeProcessor', array('content_type' => $typename)); //Processor settings
|
||||
$this->addMappings('syndication', array(
|
||||
0 => array(
|
||||
'source' => 'title',
|
||||
'target' => 'title'
|
||||
),
|
||||
1 => array(
|
||||
'source' => 'timestamp',
|
||||
'target' => 'created'
|
||||
),
|
||||
2 => array(
|
||||
'source' => 'description',
|
||||
'target' => 'body'
|
||||
),
|
||||
3 => array(
|
||||
'source' => 'url',
|
||||
'target' => 'field_alpha:url'
|
||||
),
|
||||
4 => array(
|
||||
'source' => 'title',
|
||||
'target' => 'field_alpha:title'
|
||||
),
|
||||
5 => array(
|
||||
'source' => 'url',
|
||||
'target' => 'field_beta:url'
|
||||
),
|
||||
6 => array(
|
||||
'source' => 'url',
|
||||
'target' => 'field_gamma:url'
|
||||
),
|
||||
7 => array(
|
||||
'source' => 'title',
|
||||
'target' => 'field_gamma:title'
|
||||
),
|
||||
8 => array(
|
||||
'source' => 'url',
|
||||
'target' => 'field_omega:url'
|
||||
),
|
||||
));
|
||||
|
||||
// Import RSS file.
|
||||
$nid = $this->createFeedNode();
|
||||
// Assert 10 items aggregated after creation of the node.
|
||||
$this->assertText('Created 10 nodes');
|
||||
|
||||
// Edit the imported node.
|
||||
$this->drupalGet('node/2/edit');
|
||||
|
||||
$url = 'http://developmentseed.org/blog/2009/oct/06/open-atrium-translation-workflow-two-way-updating';
|
||||
$title = 'Open Atrium Translation Workflow: Two Way Translation Updates';
|
||||
$this->assertNodeFieldValue('alpha', array('url' => $url, 'static' => $title));
|
||||
$this->assertNodeFieldValue('beta', array('url' => $url));
|
||||
$this->assertNodeFieldValue('gamma', array('url' => $url, 'static' => $title));
|
||||
$this->assertNodeFieldValue('omega', array('url' => $url, 'static' => $static_title));
|
||||
|
||||
// Test the static title.
|
||||
$this->drupalGet('node/2');
|
||||
$this->assertText($static_title, 'Static title link found.');
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Override parent::getFormFieldsNames().
|
||||
*/
|
||||
protected function getFormFieldsNames($field_name, $index) {
|
||||
if (in_array($field_name, array('alpha', 'beta', 'gamma', 'omega'))) {
|
||||
$fields = array("field_{$field_name}[und][{$index}][url]");
|
||||
if (in_array($field_name, array('alpha', 'gamma'))) {
|
||||
$fields[] = "field_{$field_name}[und][{$index}][title]";
|
||||
}
|
||||
return $fields;
|
||||
}
|
||||
else {
|
||||
return parent::getFormFieldsNames($field_name, $index);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Override parent::getFormFieldsValues().
|
||||
*/
|
||||
protected function getFormFieldsValues($field_name, $value) {
|
||||
if (in_array($field_name, array('alpha', 'beta', 'gamma', 'omega'))) {
|
||||
if (!is_array($value)) {
|
||||
$value = array('url' => $value);
|
||||
}
|
||||
$values = array($value['url']);
|
||||
if (in_array($field_name, array('alpha', 'gamma'))) {
|
||||
$values[] = isset($value['title']) ? $value['title'] : '';
|
||||
}
|
||||
return $values;
|
||||
}
|
||||
else {
|
||||
return parent::getFormFieldsValues($field_name, $index);
|
||||
}
|
||||
}
|
||||
}
|
240
sites/all/modules/feeds/tests/feeds_mapper_path.test
Normal file
240
sites/all/modules/feeds/tests/feeds_mapper_path.test
Normal file
@@ -0,0 +1,240 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Test case for path alias mapper path.inc.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Class for testing Feeds <em>path</em> mapper.
|
||||
*/
|
||||
class FeedsMapperPathTestCase extends FeedsMapperTestCase {
|
||||
public static function getInfo() {
|
||||
return array(
|
||||
'name' => 'Mapper: Path',
|
||||
'description' => 'Test Feeds Mapper support for path aliases.',
|
||||
'group' => 'Feeds',
|
||||
);
|
||||
}
|
||||
|
||||
public function setUp() {
|
||||
parent::setUp(array('path'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Basic test loading a single entry CSV file.
|
||||
*/
|
||||
public function testNodeAlias() {
|
||||
|
||||
// Create importer configuration.
|
||||
$this->createImporterConfiguration($this->randomName(), 'path_test');
|
||||
$this->setPlugin('path_test', 'FeedsFileFetcher');
|
||||
$this->setPlugin('path_test', 'FeedsCSVParser');
|
||||
$this->addMappings('path_test', array(
|
||||
0 => array(
|
||||
'source' => 'Title',
|
||||
'target' => 'title',
|
||||
),
|
||||
1 => array(
|
||||
'source' => 'path',
|
||||
'target' => 'path_alias',
|
||||
),
|
||||
2 => array(
|
||||
'source' => 'GUID',
|
||||
'target' => 'guid',
|
||||
'unique' => TRUE,
|
||||
),
|
||||
));
|
||||
|
||||
// Turn on update existing.
|
||||
$this->setSettings('path_test', 'FeedsNodeProcessor', array('update_existing' => 2));
|
||||
|
||||
// Import RSS file.
|
||||
$this->importFile('path_test', $this->absolutePath() . '/tests/feeds/path_alias.csv');
|
||||
$this->assertText('Created 9 nodes');
|
||||
|
||||
$aliases = array();
|
||||
|
||||
for ($i = 1; $i <= 9; $i++) {
|
||||
$aliases[] = "path$i";
|
||||
}
|
||||
|
||||
$this->assertAliasCount($aliases);
|
||||
|
||||
// Adding a mapping will force update.
|
||||
$this->addMappings('path_test', array(
|
||||
3 => array(
|
||||
'source' => 'fake',
|
||||
'target' => 'body',
|
||||
),
|
||||
));
|
||||
// Import RSS file.
|
||||
$this->importFile('path_test', $this->absolutePath() . '/tests/feeds/path_alias.csv');
|
||||
$this->assertText('Updated 9 nodes');
|
||||
|
||||
// Check that duplicate aliases are not created.
|
||||
$this->assertAliasCount($aliases);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test support for term aliases.
|
||||
*/
|
||||
public function testTermAlias() {
|
||||
|
||||
// Create importer configuration.
|
||||
$this->createImporterConfiguration($this->randomName(), 'path_test');
|
||||
$this->setPlugin('path_test', 'FeedsFileFetcher');
|
||||
$this->setPlugin('path_test', 'FeedsCSVParser');
|
||||
$this->setPlugin('path_test', 'FeedsTermProcessor');
|
||||
|
||||
// Create vocabulary.
|
||||
$edit = array(
|
||||
'name' => 'Addams vocabulary',
|
||||
'machine_name' => 'addams',
|
||||
);
|
||||
$this->drupalPost('admin/structure/taxonomy/add', $edit, t('Save'));
|
||||
|
||||
$this->setSettings('path_test', 'FeedsTermProcessor', array('vocabulary' => 'addams'));
|
||||
|
||||
// Turn on update existing.
|
||||
$this->setSettings('path_test', 'FeedsTermProcessor', array('update_existing' => 2));
|
||||
|
||||
// Add mappings.
|
||||
$this->addMappings('path_test', array(
|
||||
0 => array(
|
||||
'source' => 'Title',
|
||||
'target' => 'name',
|
||||
),
|
||||
1 => array(
|
||||
'source' => 'path',
|
||||
'target' => 'path_alias',
|
||||
),
|
||||
2 => array(
|
||||
'source' => 'GUID',
|
||||
'target' => 'guid',
|
||||
'unique' => TRUE,
|
||||
),
|
||||
));
|
||||
|
||||
// Import RSS file.
|
||||
$this->importFile('path_test', $this->absolutePath() . '/tests/feeds/path_alias.csv');
|
||||
$this->assertText('Created 9 terms');
|
||||
|
||||
$aliases = array();
|
||||
|
||||
for ($i = 1; $i <= 9; $i++) {
|
||||
$aliases[] = "path$i";
|
||||
}
|
||||
|
||||
$this->assertAliasCount($aliases);
|
||||
|
||||
// Adding a mapping will force update.
|
||||
$this->addMappings('path_test', array(
|
||||
3 => array(
|
||||
'source' => 'fake',
|
||||
'target' => 'description',
|
||||
),
|
||||
));
|
||||
// Import RSS file.
|
||||
$this->importFile('path_test', $this->absolutePath() . '/tests/feeds/path_alias.csv');
|
||||
$this->assertText('Updated 9 terms');
|
||||
|
||||
// Check that duplicate aliases are not created.
|
||||
$this->assertAliasCount($aliases);
|
||||
}
|
||||
|
||||
public function assertAliasCount($aliases) {
|
||||
$in_db = db_select('url_alias', 'a')
|
||||
->fields('a')
|
||||
->condition('a.alias', $aliases)
|
||||
->execute()
|
||||
->fetchAll();
|
||||
|
||||
$this->assertEqual(count($in_db), count($aliases), 'Correct number of aliases in db.');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Class for testing Feeds <em>path</em> mapper with pathauto.module.
|
||||
*/
|
||||
class FeedsMapperPathPathautoTestCase extends FeedsMapperTestCase {
|
||||
public static function getInfo() {
|
||||
return array(
|
||||
'name' => 'Mapper: Path with pathauto',
|
||||
'description' => 'Test Feeds Mapper support for path aliases and pathauto.',
|
||||
'group' => 'Feeds',
|
||||
'dependencies' => array('pathauto'),
|
||||
);
|
||||
}
|
||||
|
||||
public function setUp() {
|
||||
parent::setUp(array('pathauto'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Basic for allowing pathauto to override the alias.
|
||||
*/
|
||||
public function test() {
|
||||
|
||||
// Create importer configuration.
|
||||
$this->createImporterConfiguration($this->randomName(), 'path_test');
|
||||
$this->setPlugin('path_test', 'FeedsFileFetcher');
|
||||
$this->setPlugin('path_test', 'FeedsCSVParser');
|
||||
$this->addMappings('path_test', array(
|
||||
0 => array(
|
||||
'source' => 'Title',
|
||||
'target' => 'title',
|
||||
'unique' => FALSE,
|
||||
),
|
||||
1 => array(
|
||||
'source' => 'does_not_exist',
|
||||
'target' => 'path_alias',
|
||||
'pathauto_override' => TRUE,
|
||||
),
|
||||
2 => array(
|
||||
'source' => 'GUID',
|
||||
'target' => 'guid',
|
||||
'unique' => TRUE,
|
||||
),
|
||||
));
|
||||
|
||||
// Turn on update existing.
|
||||
$this->setSettings('path_test', 'FeedsNodeProcessor', array('update_existing' => 2));
|
||||
|
||||
// Import RSS file.
|
||||
$this->importFile('path_test', $this->absolutePath() . '/tests/feeds/path_alias.csv');
|
||||
$this->assertText('Created 9 nodes');
|
||||
|
||||
$aliases = array();
|
||||
|
||||
for ($i = 1; $i <= 9; $i++) {
|
||||
$aliases[] = "path$i";
|
||||
}
|
||||
|
||||
$this->assertAliasCount($aliases);
|
||||
|
||||
// Adding a mapping will force update.
|
||||
$this->addMappings('path_test', array(
|
||||
3 => array(
|
||||
'source' => 'fake',
|
||||
'target' => 'body',
|
||||
),
|
||||
));
|
||||
// Import RSS file.
|
||||
$this->importFile('path_test', $this->absolutePath() . '/tests/feeds/path_alias.csv');
|
||||
$this->assertText('Updated 9 nodes');
|
||||
|
||||
// Check that duplicate aliases are not created.
|
||||
$this->assertAliasCount($aliases);
|
||||
}
|
||||
|
||||
public function assertAliasCount($aliases) {
|
||||
$in_db = db_select('url_alias', 'a')
|
||||
->fields('a')
|
||||
->condition('a.alias', $aliases)
|
||||
->execute()
|
||||
->fetchAll();
|
||||
|
||||
$this->assertEqual(count($in_db), count($aliases), 'Correct number of aliases in db.');
|
||||
}
|
||||
}
|
102
sites/all/modules/feeds/tests/feeds_mapper_profile.test
Normal file
102
sites/all/modules/feeds/tests/feeds_mapper_profile.test
Normal file
@@ -0,0 +1,102 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Test suite for profile mapper mappers/profile.inc.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Class for testing Feeds profile mapper.
|
||||
*/
|
||||
class FeedsMapperProfileTestCase extends FeedsMapperTestCase {
|
||||
public static function getInfo() {
|
||||
return array(
|
||||
'name' => 'Mapper: Profile',
|
||||
'description' => 'Test Feeds Mapper support for profile fields.',
|
||||
'group' => 'Feeds',
|
||||
);
|
||||
}
|
||||
|
||||
function setUp() {
|
||||
// Call parent setup with required modules.
|
||||
parent::setUp(array('profile'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Basic test loading a doulbe entry CSV file.
|
||||
*/
|
||||
function test() {
|
||||
|
||||
// Create profile fields.
|
||||
$edit = array(
|
||||
'category' => 'test',
|
||||
'title' => 'color',
|
||||
'name' => 'profile_textfield_test',
|
||||
'register' => 1,
|
||||
);
|
||||
$name = $this->drupalPost('admin/config/people/profile/add/textfield', $edit, t('Save field'));
|
||||
$edit = array(
|
||||
'category' => 'test',
|
||||
'title' => 'letter',
|
||||
'name' => 'profile_select_test',
|
||||
'options' => 'alpha' . "\n" . 'beta' . "\n" . 'gamma',
|
||||
'register' => 1,
|
||||
);
|
||||
$name = $this->drupalPost('admin/config/people/profile/add/selection', $edit, t('Save field'));
|
||||
|
||||
// Create an importer.
|
||||
$this->createImporterConfiguration('Profile import', 'profile_import');
|
||||
|
||||
// Set and configure plugins.
|
||||
$this->setPlugin('profile_import', 'FeedsFileFetcher');
|
||||
$this->setPlugin('profile_import', 'FeedsCSVParser');
|
||||
$this->setPlugin('profile_import', 'FeedsUserProcessor');
|
||||
|
||||
// Go to mapping page and create a couple of mappings.
|
||||
$mappings = array(
|
||||
'0' => array(
|
||||
'source' => 'name',
|
||||
'target' => 'name',
|
||||
'unique' => 0,
|
||||
),
|
||||
'1' => array(
|
||||
'source' => 'mail',
|
||||
'target' => 'mail',
|
||||
'unique' => 1,
|
||||
),
|
||||
'2' => array(
|
||||
'source' => 'color',
|
||||
'target' => 'profile_textfield_test',
|
||||
),
|
||||
'3' => array(
|
||||
'source' => 'letter',
|
||||
'target' => 'profile_select_test',
|
||||
),
|
||||
);
|
||||
$this->addMappings('profile_import', $mappings);
|
||||
|
||||
// Change some of the basic configuration.
|
||||
$edit = array(
|
||||
'content_type' => '',
|
||||
'import_period' => FEEDS_SCHEDULE_NEVER,
|
||||
);
|
||||
$this->drupalPost('admin/structure/feeds/profile_import/settings', $edit, 'Save');
|
||||
|
||||
// Import CSV file.
|
||||
$this->importFile('profile_import', $this->absolutePath() .'/tests/feeds/profile.csv');
|
||||
$this->assertText('Created 2 users.');
|
||||
|
||||
// Check the two imported users.
|
||||
$this->drupalGet('admin/people');
|
||||
$this->assertText('magna');
|
||||
$this->assertText('rhoncus');
|
||||
|
||||
$account = user_load_by_name('magna');
|
||||
$this->assertEqual($account->profile_textfield_test, 'red', 'User profile_textfield_test is correct');
|
||||
$this->assertEqual($account->profile_select_test, 'alpha', 'User profile_select_test is correct');
|
||||
|
||||
$account = user_load_by_name('rhoncus');
|
||||
$this->assertEqual($account->profile_textfield_test, 'blue', 'User profile_textfield_test is correct');
|
||||
$this->assertEqual($account->profile_select_test, 'beta', 'User profile_select_test is correct');
|
||||
}
|
||||
}
|
271
sites/all/modules/feeds/tests/feeds_mapper_taxonomy.test
Normal file
271
sites/all/modules/feeds/tests/feeds_mapper_taxonomy.test
Normal file
@@ -0,0 +1,271 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Test case for taxonomy mapper mappers/taxonomy.inc.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Class for testing Feeds <em>content</em> mapper.
|
||||
*/
|
||||
class FeedsMapperTaxonomyTestCase extends FeedsMapperTestCase {
|
||||
public static function getInfo() {
|
||||
return array(
|
||||
'name' => 'Mapper: Taxonomy',
|
||||
'description' => 'Test Feeds Mapper support for Taxonomy.',
|
||||
'group' => 'Feeds',
|
||||
);
|
||||
}
|
||||
|
||||
function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
// Add Tags vocabulary
|
||||
$edit = array(
|
||||
'name' => 'Tags',
|
||||
'machine_name' => 'tags',
|
||||
);
|
||||
$this->drupalPost('admin/structure/taxonomy/add', $edit, 'Save');
|
||||
|
||||
$edit = array(
|
||||
'name' => 'term1',
|
||||
);
|
||||
$this->drupalPost('admin/structure/taxonomy/tags/add', $edit, t('Save'));
|
||||
$this->assertText('Created new term term1.');
|
||||
|
||||
// Create term reference field.
|
||||
$field = array(
|
||||
'field_name' => 'field_tags',
|
||||
'type' => 'taxonomy_term_reference',
|
||||
'cardinality' => FIELD_CARDINALITY_UNLIMITED,
|
||||
'settings' => array(
|
||||
'allowed_values' => array(
|
||||
array(
|
||||
'vocabulary' => 'tags',
|
||||
'parent' => 0,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
field_create_field($field);
|
||||
|
||||
// Add term reference field to feed item bundle.
|
||||
$this->instance = array(
|
||||
'field_name' => 'field_tags',
|
||||
'bundle' => 'article',
|
||||
'entity_type' => 'node',
|
||||
'widget' => array(
|
||||
'type' => 'options_select',
|
||||
),
|
||||
'display' => array(
|
||||
'default' => array(
|
||||
'type' => 'taxonomy_term_reference_link',
|
||||
),
|
||||
),
|
||||
);
|
||||
field_create_instance($this->instance);
|
||||
|
||||
// Add term reference field to feed node bundle.
|
||||
$this->instance = array(
|
||||
'field_name' => 'field_tags',
|
||||
'bundle' => 'page',
|
||||
'entity_type' => 'node',
|
||||
'widget' => array(
|
||||
'type' => 'options_select',
|
||||
),
|
||||
'display' => array(
|
||||
'default' => array(
|
||||
'type' => 'taxonomy_term_reference_link',
|
||||
),
|
||||
),
|
||||
);
|
||||
field_create_instance($this->instance);
|
||||
|
||||
// Create an importer configuration with basic mapping.
|
||||
$this->createImporterConfiguration('Syndication', 'syndication');
|
||||
$this->addMappings('syndication',
|
||||
array(
|
||||
0 => array(
|
||||
'source' => 'title',
|
||||
'target' => 'title',
|
||||
),
|
||||
1 => array(
|
||||
'source' => 'description',
|
||||
'target' => 'body',
|
||||
),
|
||||
2 => array(
|
||||
'source' => 'timestamp',
|
||||
'target' => 'created',
|
||||
),
|
||||
3 => array(
|
||||
'source' => 'url',
|
||||
'target' => 'url',
|
||||
'unique' => TRUE,
|
||||
),
|
||||
4 => array(
|
||||
'source' => 'guid',
|
||||
'target' => 'guid',
|
||||
'unique' => TRUE,
|
||||
),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test inheriting taxonomy from the feed node.
|
||||
*/
|
||||
function testInheritTaxonomy() {
|
||||
|
||||
// Adjust importer settings
|
||||
$this->setSettings('syndication', NULL, array('import_period' => FEEDS_SCHEDULE_NEVER));
|
||||
$this->setSettings('syndication', NULL, array('import_on_create' => FALSE));
|
||||
$this->assertText('Do not import on submission');
|
||||
|
||||
// Map feed node's taxonomy to feed item node's taxonomy.
|
||||
$mappings = array(
|
||||
5 => array(
|
||||
'source' => 'parent:taxonomy:tags',
|
||||
'target' => 'field_tags',
|
||||
),
|
||||
);
|
||||
$this->addMappings('syndication', $mappings);
|
||||
|
||||
// Create feed node and add term term1.
|
||||
$langcode = LANGUAGE_NONE;
|
||||
$nid = $this->createFeedNode('syndication', NULL, 'Syndication');
|
||||
$term = taxonomy_get_term_by_name('term1');
|
||||
$term = reset($term);
|
||||
$edit = array(
|
||||
'field_tags' . '[' . $langcode . '][]' => $term->tid,
|
||||
);
|
||||
$this->drupalPost("node/$nid/edit", $edit, t('Save'));
|
||||
$this->assertTaxonomyTerm($term->name);
|
||||
|
||||
// Import nodes.
|
||||
$this->drupalPost("node/$nid/import", array(), 'Import');
|
||||
$this->assertText('Created 10 nodes.');
|
||||
|
||||
$count = db_query("SELECT COUNT(*) FROM {taxonomy_index}")->fetchField();
|
||||
|
||||
// There should be one term for each node imported plus the term on the feed node.
|
||||
$this->assertEqual(11, $count, 'Found correct number of tags for all feed nodes and feed items.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Test aggregating RSS categories to taxonomy.
|
||||
*/
|
||||
/*
|
||||
function testRSSCategoriesToTaxonomy() {
|
||||
// Add mapping to tags vocabulary.
|
||||
$this->addMappings('syndication',
|
||||
array(
|
||||
array(
|
||||
'source' => 'tags',
|
||||
'target' => 'taxonomy:1',
|
||||
),
|
||||
)
|
||||
);
|
||||
|
||||
// Aggregate feed node with "Tag" vocabulary.
|
||||
$nid = $this->createFeedNode();
|
||||
// Assert 10 items aggregated after creation of the node.
|
||||
$this->assertText('Created 10 nodes');
|
||||
// There should be 30 terms and 44 term-node relations.
|
||||
$this->assertEqual(30, db_query("SELECT count(*) FROM {term_data}")->fetchField(), "Found correct number of terms.");
|
||||
$this->assertEqual(44, db_query("SELECT count(*) FROM {term_node}")->fetchField(), "Found correct number of term-node relations.");
|
||||
|
||||
// Take a look at the actual terms on frontpage.
|
||||
$this->drupalGet('node');
|
||||
$terms = array(
|
||||
'authentication',
|
||||
'custom mapping',
|
||||
'data visualization',
|
||||
'Drupal',
|
||||
'Drupal planet',
|
||||
'faceted search',
|
||||
'GeoDC',
|
||||
'graphs',
|
||||
'interface',
|
||||
'intranet',
|
||||
'localization',
|
||||
'localization client',
|
||||
'localization server',
|
||||
'map-basec browser',
|
||||
'mapbox',
|
||||
'microfinance',
|
||||
'MIX Market',
|
||||
'open atrium',
|
||||
'open data',
|
||||
'open source',
|
||||
'Peru',
|
||||
'salesforce',
|
||||
'siteminder',
|
||||
'siteminder module',
|
||||
'software freedom day',
|
||||
'translation',
|
||||
'translation server',
|
||||
'usability',
|
||||
'Washington DC',
|
||||
'World Bank',
|
||||
);
|
||||
foreach ($terms as $term) {
|
||||
$this->assertTaxonomyTerm($term);
|
||||
}
|
||||
|
||||
// Delete all items, all associations are gone.
|
||||
$this->drupalPost("node/$nid/delete-items", array(), 'Delete');
|
||||
$this->assertText('Deleted 10 nodes');
|
||||
$this->assertEqual(30, db_query("SELECT count(*) FROM {term_data}")->fetchField(), "Found correct number of terms.");
|
||||
$this->assertEqual(0, db_query("SELECT count(*) FROM {term_node}")->fetchField(), "Found correct number of term-node relations.");
|
||||
|
||||
// Remove "Tag" setting, import again.
|
||||
$edit = array(
|
||||
'tags' => FALSE,
|
||||
);
|
||||
$this->drupalPost('admin/content/taxonomy/edit/vocabulary/1', $edit, 'Save');
|
||||
$this->drupalPost("node/$nid/import", array(), 'Import');
|
||||
$this->assertText('Created 10 nodes');
|
||||
|
||||
// We should only get one term-node association per node.
|
||||
$this->assertEqual(30, db_query("SELECT count(*) FROM {term_data}")->fetchField(), "Found correct number of terms.");
|
||||
$this->assertEqual(10, db_query("SELECT count(*) FROM {term_node}")->fetchField(), "Found correct number of term-node relations.");
|
||||
|
||||
// Delete all items.
|
||||
$this->drupalPost("node/$nid/delete-items", array(), 'Delete');
|
||||
|
||||
// Set vocabulary to multiple terms, import again.
|
||||
$edit = array(
|
||||
'multiple' => TRUE,
|
||||
);
|
||||
$this->drupalPost('admin/content/taxonomy/edit/vocabulary/1', $edit, 'Save');
|
||||
$this->drupalPost("node/$nid/import", array(), 'Import');
|
||||
$this->assertText('Created 10 nodes');
|
||||
|
||||
// We should get all term-node associations again.
|
||||
$this->assertEqual(30, db_query("SELECT count(*) FROM {term_data}")->fetchField(), "Found correct number of terms.");
|
||||
$this->assertEqual(44, db_query("SELECT count(*) FROM {term_node}")->fetchField(), "Found correct number of term-node relations.");
|
||||
|
||||
// Delete all items.
|
||||
$this->drupalPost("node/$nid/delete-items", array(), 'Delete');
|
||||
|
||||
// Remove a term, import again.
|
||||
$this->drupalPost('admin/content/taxonomy/edit/term/1', array(), 'Delete');
|
||||
$this->drupalPost(NULL, array(), 'Delete');
|
||||
$this->assertText('Deleted term');
|
||||
$this->drupalPost("node/$nid/import", array(), 'Import');
|
||||
$this->assertText('Created 10 nodes');
|
||||
|
||||
// This term should now be missing from term-node associations.
|
||||
$this->assertEqual(29, db_query("SELECT count(*) FROM {term_data}")->fetchField(), "Found correct number of terms.");
|
||||
$this->assertEqual(39, db_query("SELECT count(*) FROM {term_node}")->fetchField(), "Found correct number of term-node relations.");
|
||||
}
|
||||
*/
|
||||
|
||||
/**
|
||||
* Helper, finds node style taxonomy term markup in DOM.
|
||||
*/
|
||||
public function assertTaxonomyTerm($term) {
|
||||
$term = check_plain($term);
|
||||
$this->assertPattern('/<a href="\/.*taxonomy\/term\/[0-9]+">' . $term . '<\/a>/', 'Found ' . $term);
|
||||
}
|
||||
}
|
124
sites/all/modules/feeds/tests/feeds_parser_sitemap.test
Normal file
124
sites/all/modules/feeds/tests/feeds_parser_sitemap.test
Normal file
@@ -0,0 +1,124 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Tests for plugins/FeedsSitemapParser.inc
|
||||
*/
|
||||
|
||||
/**
|
||||
* Test Sitemap parser.
|
||||
*/
|
||||
class FeedsSitemapParserTestCase extends FeedsWebTestCase {
|
||||
public static function getInfo() {
|
||||
return array(
|
||||
'name' => 'Sitemap parser',
|
||||
'description' => 'Regression tests for Sitemap XML format parser.',
|
||||
'group' => 'Feeds',
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Run tests.
|
||||
*/
|
||||
public function test() {
|
||||
$this->createImporterConfiguration('Sitemap', 'sitemap');
|
||||
$this->setPlugin('sitemap', 'FeedsSitemapParser');
|
||||
|
||||
$this->addMappings('sitemap',
|
||||
array(
|
||||
0 => array(
|
||||
'source' => 'changefreq',
|
||||
'target' => 'title',
|
||||
'unique' => FALSE,
|
||||
),
|
||||
1 => array(
|
||||
'source' => 'priority',
|
||||
'target' => 'body',
|
||||
'unique' => FALSE,
|
||||
),
|
||||
2 => array(
|
||||
'source' => 'lastmod',
|
||||
'target' => 'created',
|
||||
'unique' => FALSE,
|
||||
),
|
||||
3 => array(
|
||||
'source' => 'url',
|
||||
'target' => 'url',
|
||||
'unique' => TRUE,
|
||||
),
|
||||
4 => array(
|
||||
'source' => 'url',
|
||||
'target' => 'guid',
|
||||
'unique' => TRUE,
|
||||
),
|
||||
)
|
||||
);
|
||||
|
||||
|
||||
$path = $GLOBALS['base_url'] . '/' . drupal_get_path('module', 'feeds') . '/tests/feeds/';
|
||||
$nid = $this->createFeedNode('sitemap', $path . 'sitemap-example.xml', 'Testing Sitemap Parser');
|
||||
$this->assertText('Created 5 nodes');
|
||||
|
||||
// Assert DB status.
|
||||
$count = db_query("SELECT COUNT(*) FROM {feeds_item} WHERE entity_type = 'node'")->fetchField();
|
||||
$this->assertEqual($count, 5, 'Accurate number of items in database.');
|
||||
|
||||
// Check items against known content of feed.
|
||||
$items = db_query("SELECT * FROM {feeds_item} WHERE entity_type = 'node' AND feed_nid = :nid ORDER BY nid", array(':nid' => $nid));
|
||||
|
||||
// Check first item.
|
||||
date_default_timezone_set('GMT');
|
||||
$item = $items->fetchObject();
|
||||
$node = node_load($item->nid);
|
||||
$this->assertEqual($node->title, 'monthly', 'Feed item 1 changefreq is correct.');
|
||||
$this->assertEqual($node->body, '0.8', 'Feed item 1 priority is correct.');
|
||||
$this->assertEqual($node->created, strtotime('2005-01-01'), 'Feed item 1 lastmod is correct.');
|
||||
$info = feeds_item_info_load('node', $node->nid);
|
||||
$this->assertEqual($info->url, 'http://www.example.com/', 'Feed item 1 url is correct.');
|
||||
$this->assertEqual($info->url, $info->guid, 'Feed item 1 guid is correct.');
|
||||
|
||||
// Check second item.
|
||||
$item = $items->fetchObject();
|
||||
$node = node_load($item->nid);
|
||||
$this->assertEqual($node->title, 'weekly', 'Feed item 2 changefreq is correct.');
|
||||
$this->assertEqual($node->body, '', 'Feed item 2 priority is correct.');
|
||||
// $node->created is... recently
|
||||
$info = feeds_item_info_load('node', $node->nid);
|
||||
$this->assertEqual($info->url, 'http://www.example.com/catalog?item=12&desc=vacation_hawaii', 'Feed item 2 url is correct.');
|
||||
$this->assertEqual($info->url, $info->guid, 'Feed item 2 guid is correct.');
|
||||
|
||||
// Check third item.
|
||||
$item = $items->fetchObject();
|
||||
$node = node_load($item->nid);
|
||||
$this->assertEqual($node->title, 'weekly', 'Feed item 3 changefreq is correct.');
|
||||
$this->assertEqual($node->body, '', 'Feed item 3 priority is correct.');
|
||||
$this->assertEqual($node->created, strtotime('2004-12-23'), 'Feed item 3 lastmod is correct.');
|
||||
$info = feeds_item_info_load('node', $node->nid);
|
||||
$this->assertEqual($info->url, 'http://www.example.com/catalog?item=73&desc=vacation_new_zealand', 'Feed item 3 url is correct.');
|
||||
$this->assertEqual($info->url, $info->guid, 'Feed item 3 guid is correct.');
|
||||
|
||||
// Check fourth item.
|
||||
$item = $items->fetchObject();
|
||||
$node = node_load($item->nid);
|
||||
$this->assertEqual($node->title, '', 'Feed item 4 changefreq is correct.');
|
||||
$this->assertEqual($node->body, '0.3', 'Feed item 4 priority is correct.');
|
||||
$this->assertEqual($node->created, strtotime('2004-12-23T18:00:15+00:00'), 'Feed item 4 lastmod is correct.');
|
||||
$info = feeds_item_info_load('node', $node->nid);
|
||||
$this->assertEqual($info->url, 'http://www.example.com/catalog?item=74&desc=vacation_newfoundland', 'Feed item 4 url is correct.');
|
||||
$this->assertEqual($info->url, $info->guid, 'Feed item 1 guid is correct.');
|
||||
|
||||
// Check fifth item.
|
||||
$item = $items->fetchObject();
|
||||
$node = node_load($item->nid);
|
||||
$this->assertEqual($node->title, '', 'Feed item 5 changefreq is correct.');
|
||||
$this->assertEqual($node->body, '', 'Feed item 5 priority is correct.');
|
||||
$this->assertEqual($node->created, strtotime('2004-11-23'), 'Feed item 5 lastmod is correct.');
|
||||
$info = feeds_item_info_load('node', $node->nid);
|
||||
$this->assertEqual($info->url, 'http://www.example.com/catalog?item=83&desc=vacation_usa', 'Feed item 5 url is correct.');
|
||||
$this->assertEqual($info->url, $info->guid, 'Feed item 5 guid is correct.');
|
||||
|
||||
// Check for more items.
|
||||
$item = $items->fetchObject();
|
||||
$this->assertFalse($item, 'Correct number of feed items recorded.');
|
||||
}
|
||||
}
|
57
sites/all/modules/feeds/tests/feeds_parser_syndication.test
Normal file
57
sites/all/modules/feeds/tests/feeds_parser_syndication.test
Normal file
@@ -0,0 +1,57 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Tests for plugins/FeedsSyndicationParser.inc.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Test single feeds.
|
||||
*/
|
||||
class FeedsSyndicationParserTestCase extends FeedsWebTestCase {
|
||||
public static function getInfo() {
|
||||
return array(
|
||||
'name' => 'Syndication parsers',
|
||||
'description' => 'Regression tests for syndication parsers Common syndication and SimplePie. Tests parsers against a set of feeds in the context of Feeds module. <strong>Requires SimplePie parser to be configured correctly.</strong>',
|
||||
'group' => 'Feeds',
|
||||
'dependencies' => array('libraries'),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set up test.
|
||||
*/
|
||||
public function setUp() {
|
||||
parent::setUp(array('libraries'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Run tests.
|
||||
*/
|
||||
public function test() {
|
||||
$this->createImporterConfiguration('Syndication', 'syndication');
|
||||
|
||||
foreach (array('FeedsSyndicationParser', 'FeedsSimplePieParser') as $parser) {
|
||||
$this->setPlugin('syndication', $parser);
|
||||
foreach ($this->feedUrls() as $url => $assertions) {
|
||||
$this->createFeedNode('syndication', $url);
|
||||
$this->assertText('Created ' . $assertions['item_count'] . ' nodes');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an array of test feeds.
|
||||
*/
|
||||
protected function feedUrls() {
|
||||
$path = $GLOBALS['base_url'] . '/' . drupal_get_path('module', 'feeds') . '/tests/feeds/';
|
||||
return array(
|
||||
"{$path}developmentseed.rss2" => array(
|
||||
'item_count' => 10,
|
||||
),
|
||||
"{$path}feed_without_guid.rss2" => array(
|
||||
'item_count' => 10,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
458
sites/all/modules/feeds/tests/feeds_processor_node.test
Normal file
458
sites/all/modules/feeds/tests/feeds_processor_node.test
Normal file
@@ -0,0 +1,458 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Tests for plugins/FeedsNodeProcessor.inc.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Test aggregating a feed as node items.
|
||||
*/
|
||||
class FeedsRSStoNodesTest extends FeedsWebTestCase {
|
||||
|
||||
public static function getInfo() {
|
||||
return array(
|
||||
'name' => 'RSS import to nodes',
|
||||
'description' => 'Tests a feed configuration that is attached to a content type, uses HTTP fetcher, common syndication parser and a node processor. Repeats the same test for an importer configuration that is not attached to a content type and for a configuration that is attached to a content type and uses the file fetcher.',
|
||||
'group' => 'Feeds',
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set up test.
|
||||
*/
|
||||
public function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
// Set the front page to show 20 nodes so we can easily see what is aggregated.
|
||||
variable_set('default_nodes_main', 20);
|
||||
|
||||
// Set the teaser length display to unlimited otherwise tests looking for
|
||||
// text on nodes will fail.
|
||||
$edit = array('fields[body][type]' => 'text_default');
|
||||
$this->drupalPost('admin/structure/types/manage/article/display/teaser', $edit, 'Save');
|
||||
|
||||
// Create an importer configuration.
|
||||
$this->createImporterConfiguration('Syndication', 'syndication');
|
||||
$this->addMappings('syndication',
|
||||
array(
|
||||
0 => array(
|
||||
'source' => 'title',
|
||||
'target' => 'title',
|
||||
'unique' => FALSE,
|
||||
),
|
||||
1 => array(
|
||||
'source' => 'description',
|
||||
'target' => 'body',
|
||||
),
|
||||
2 => array(
|
||||
'source' => 'timestamp',
|
||||
'target' => 'created',
|
||||
),
|
||||
3 => array(
|
||||
'source' => 'url',
|
||||
'target' => 'url',
|
||||
'unique' => TRUE,
|
||||
),
|
||||
4 => array(
|
||||
'source' => 'guid',
|
||||
'target' => 'guid',
|
||||
'unique' => TRUE,
|
||||
),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test node creation, refreshing/deleting feeds and feed items.
|
||||
*/
|
||||
public function test() {
|
||||
$nid = $this->createFeedNode();
|
||||
|
||||
// Assert 10 items aggregated after creation of the node.
|
||||
$this->assertText('Created 10 nodes');
|
||||
$article_nid = db_query_range("SELECT nid FROM {node} WHERE type = 'article'", 0, 1)->fetchField();
|
||||
$this->assertEqual("Created by FeedsNodeProcessor", db_query("SELECT nr.log FROM {node} n JOIN {node_revision} nr ON n.vid = nr.vid WHERE n.nid = :nid", array(':nid' => $article_nid))->fetchField());
|
||||
|
||||
// Navigate to feed node, there should be Feeds tabs visible.
|
||||
$this->drupalGet("node/$nid");
|
||||
$this->assertRaw("node/$nid/import");
|
||||
$this->assertRaw("node/$nid/delete-items");
|
||||
|
||||
// Assert accuracy of aggregated information.
|
||||
$this->drupalGet('node');
|
||||
$this->assertRaw('<span class="username">Anonymous (not verified)</span>');
|
||||
$this->assertDevseedFeedContent();
|
||||
|
||||
// Assert DB status.
|
||||
$count = db_query("SELECT COUNT(*) FROM {node} n INNER JOIN {feeds_item} fi ON fi.entity_type = 'node' AND n.nid = fi.entity_id")->fetchField();
|
||||
$this->assertEqual($count, 10, 'Accurate number of items in database.');
|
||||
|
||||
// Assert default input format on first imported feed node.
|
||||
|
||||
// NEEDS update.
|
||||
// $format = db_query_range("SELECT nr.format FROM {feeds_node_item} fi JOIN {node} n ON fi.nid = n.nid JOIN {node_revision} nr ON n.vid = nr.vid", 0, 1)->fetchField();
|
||||
// $this->assertEqual($format, filter_fallback_format(), 'Using default Input format.');
|
||||
|
||||
// Import again.
|
||||
$this->drupalPost("node/$nid/import", array(), 'Import');
|
||||
$this->assertText('There are no new nodes');
|
||||
|
||||
// Assert DB status, there still shouldn't be more than 10 items.
|
||||
$count = db_query("SELECT COUNT(*) FROM {node} n INNER JOIN {feeds_item} fi ON fi.entity_type = 'node' AND n.nid = fi.entity_id")->fetchField();
|
||||
$this->assertEqual($count, 10, 'Accurate number of items in database.');
|
||||
|
||||
// All of the above tests should have produced published nodes, set default
|
||||
// to unpublished, import again.
|
||||
$count = db_query("SELECT COUNT(*) FROM {node} n INNER JOIN {feeds_item} fi ON fi.entity_type = 'node' AND n.nid = fi.entity_id WHERE n.status = 1")->fetchField();
|
||||
$this->assertEqual($count, 10, 'All items are published.');
|
||||
$edit = array(
|
||||
'node_options[status]' => FALSE,
|
||||
);
|
||||
$this->drupalPost('admin/structure/types/manage/article', $edit, t('Save content type'));
|
||||
$this->drupalPost("node/$nid/delete-items", array(), 'Delete');
|
||||
$this->drupalPost("node/$nid/import", array(), 'Import');
|
||||
$count = db_query("SELECT COUNT(*) FROM {node} n INNER JOIN {feeds_item} fi ON fi.entity_type = 'node' AND n.nid = fi.entity_id WHERE n.status = 0")->fetchField();
|
||||
$this->assertEqual($count, 10, 'No items are published.');
|
||||
$edit = array(
|
||||
'node_options[status]' => TRUE,
|
||||
);
|
||||
$this->drupalPost('admin/structure/types/manage/article', $edit, t('Save content type'));
|
||||
$this->drupalPost("node/$nid/delete-items", array(), 'Delete');
|
||||
|
||||
// Enable replace existing and import updated feed file.
|
||||
$this->drupalPost("node/$nid/import", array(), 'Import');
|
||||
$this->setSettings('syndication', 'FeedsNodeProcessor', array('update_existing' => 1));
|
||||
$feed_url = $GLOBALS['base_url'] . '/' . drupal_get_path('module', 'feeds') . '/tests/feeds/developmentseed_changes.rss2';
|
||||
$this->editFeedNode($nid, $feed_url);
|
||||
$this->drupalPost("node/$nid/import", array(), 'Import');
|
||||
$this->assertText('Updated 2 nodes');
|
||||
|
||||
// Assert accuracy of aggregated content (check 2 updates, one original).
|
||||
$this->drupalGet('node');
|
||||
$this->assertText('Managing News Translation Workflow: Two Way Translation Updates');
|
||||
$this->assertText('Presenting on Features in Drupal and Managing News');
|
||||
$this->assertText('Scaling the Open Atrium UI');
|
||||
|
||||
// Import again.
|
||||
$this->drupalPost("node/$nid/import", array(), 'Import');
|
||||
$this->assertText('There are no new nodes');
|
||||
$this->assertFeedItemCount(10);
|
||||
|
||||
// Now delete all items.
|
||||
$this->drupalPost("node/$nid/delete-items", array(), 'Delete');
|
||||
$this->assertText('Deleted 10 nodes');
|
||||
$this->assertFeedItemCount(0);
|
||||
|
||||
// Change author and turn off authorization.
|
||||
$this->auth_user = $this->drupalCreateUser(array('access content'));
|
||||
$this->setSettings('syndication', 'FeedsNodeProcessor', array('author' => $this->auth_user->name, 'authorize' => FALSE));
|
||||
|
||||
// Change input format.
|
||||
$this->setSettings('syndication', 'FeedsNodeProcessor', array('input_format' => 'plain_text'));
|
||||
|
||||
// Import again.
|
||||
$this->drupalPost("node/$nid/import", array(), 'Import');
|
||||
$this->assertText('Created 10 nodes');
|
||||
|
||||
// Assert author.
|
||||
$this->drupalGet('node');
|
||||
$this->assertPattern('/<span class="username">' . check_plain($this->auth_user->name) . '<\/span>/');
|
||||
$count = db_query("SELECT COUNT(*) FROM {feeds_item} fi JOIN {node} n ON fi.entity_type = 'node' AND fi.entity_id = n.nid WHERE n.uid = :uid", array(':uid' => $this->auth_user->uid))->fetchField();
|
||||
$this->assertEqual($count, 10, 'Accurate number of items in database.');
|
||||
|
||||
// Assert input format.
|
||||
|
||||
// NEEDS update.
|
||||
// $format = db_query_range("SELECT nr.format FROM {feeds_node_item} fi JOIN {node} n ON fi.nid = n.nid JOIN {node_revision} nr ON n.vid = nr.vid", 0, 1)->fetchField();
|
||||
// $this->assertEqual($format, filter_fallback_format() + 1, 'Set non-default Input format.');
|
||||
|
||||
// Set to update existing, remove authorship of above nodes and import again.
|
||||
$this->setSettings('syndication', 'FeedsNodeProcessor', array('update_existing' => 2));
|
||||
$nids = db_query("SELECT nid FROM {node} n INNER JOIN {feeds_item} fi ON fi.entity_type = 'node' AND n.nid = fi.entity_id")->fetchCol();
|
||||
db_update('node')
|
||||
->fields(array('uid' => 0))
|
||||
->condition('nid', $nids, 'IN')
|
||||
->execute();
|
||||
db_update('feeds_item')
|
||||
->fields(array('hash' => ''))
|
||||
->condition('entity_type', 'node')
|
||||
->condition('entity_id', $nids, 'IN')
|
||||
->execute();
|
||||
$this->drupalPost("node/$nid/import", array(), 'Import');
|
||||
$this->drupalGet('node');
|
||||
$this->assertNoPattern('/<span class="username">' . check_plain($this->auth_user->name) . '<\/span>/');
|
||||
$count = db_query("SELECT COUNT(*) FROM {feeds_item} fi JOIN {node} n ON fi.entity_type = 'node' AND fi.entity_id = n.nid WHERE n.uid = :uid", array(':uid' => $this->auth_user->uid))->fetchField();
|
||||
$this->assertEqual($count, 0, 'Accurate number of items in database.');
|
||||
|
||||
// Map feed node's author to feed item author, update - feed node's items
|
||||
// should now be assigned to feed node author.
|
||||
$this->addMappings('syndication',
|
||||
array(
|
||||
5 => array(
|
||||
'source' => 'parent:uid',
|
||||
'target' => 'uid',
|
||||
),
|
||||
)
|
||||
);
|
||||
$this->drupalPost("node/$nid/import", array(), 'Import');
|
||||
$this->drupalGet('node');
|
||||
$this->assertNoPattern('/<span class="username">' . check_plain($this->auth_user->name) . '<\/span>/');
|
||||
$uid = db_query("SELECT uid FROM {node} WHERE nid = :nid", array(':nid' => $nid))->fetchField();
|
||||
$count = db_query("SELECT COUNT(*) FROM {node} WHERE uid = :uid", array(':uid' => $uid))->fetchField();
|
||||
$this->assertEqual($count, 11, 'All feed item nodes are assigned to feed node author.');
|
||||
|
||||
// Login with new user with only access content permissions.
|
||||
$this->drupalLogin($this->auth_user);
|
||||
|
||||
// Navigate to feed node, there should be no Feeds tabs visible.
|
||||
$this->drupalGet("node/$nid");
|
||||
$this->assertNoRaw("node/$nid/import");
|
||||
$this->assertNoRaw("node/$nid/delete-items");
|
||||
|
||||
// Now create a second feed configuration that is not attached to a content
|
||||
// type and run tests on importing/purging.
|
||||
|
||||
// Login with sufficient permissions.
|
||||
$this->drupalLogin($this->admin_user);
|
||||
// Remove all items again so that next test can check for them.
|
||||
$this->drupalPost("node/$nid/delete-items", array(), 'Delete');
|
||||
|
||||
// Create an importer, not attached to content type.
|
||||
$this->createImporterConfiguration('Syndication standalone', 'syndication_standalone');
|
||||
$edit = array(
|
||||
'content_type' => '',
|
||||
);
|
||||
$this->drupalPost('admin/structure/feeds/syndication_standalone/settings', $edit, 'Save');
|
||||
$this->addMappings('syndication_standalone',
|
||||
array(
|
||||
0 => array(
|
||||
'source' => 'title',
|
||||
'target' => 'title',
|
||||
'unique' => FALSE,
|
||||
),
|
||||
1 => array(
|
||||
'source' => 'description',
|
||||
'target' => 'body',
|
||||
),
|
||||
2 => array(
|
||||
'source' => 'timestamp',
|
||||
'target' => 'created',
|
||||
),
|
||||
3 => array(
|
||||
'source' => 'url',
|
||||
'target' => 'url',
|
||||
'unique' => TRUE,
|
||||
),
|
||||
4 => array(
|
||||
'source' => 'guid',
|
||||
'target' => 'guid',
|
||||
'unique' => TRUE,
|
||||
),
|
||||
)
|
||||
);
|
||||
|
||||
// Import, assert 10 items aggregated after creation of the node.
|
||||
$this->importURL('syndication_standalone');
|
||||
$this->assertText('Created 10 nodes');
|
||||
|
||||
// Assert accuracy of aggregated information.
|
||||
$this->drupalGet('node');
|
||||
$this->assertDevseedFeedContent();
|
||||
$this->assertFeedItemCount(10);
|
||||
|
||||
// Import again.
|
||||
$this->drupalPost('import/syndication_standalone', array(), 'Import');
|
||||
$this->assertText('There are no new nodes');
|
||||
$this->assertFeedItemCount(10);
|
||||
|
||||
// Enable replace existing and import updated feed file.
|
||||
$this->setSettings('syndication_standalone', 'FeedsNodeProcessor', array('update_existing' => 1));
|
||||
$feed_url = $GLOBALS['base_url'] . '/' . drupal_get_path('module', 'feeds') . '/tests/feeds/developmentseed_changes.rss2';
|
||||
$this->importURL('syndication_standalone', $feed_url);
|
||||
$this->assertText('Updated 2 nodes');
|
||||
|
||||
// Assert accuracy of aggregated information (check 2 updates, one orig).
|
||||
$this->drupalGet('node');
|
||||
$this->assertText('Managing News Translation Workflow: Two Way Translation Updates');
|
||||
$this->assertText('Presenting on Features in Drupal and Managing News');
|
||||
$this->assertText('Scaling the Open Atrium UI');
|
||||
|
||||
// Import again.
|
||||
$this->drupalPost('import/syndication_standalone', array(), 'Import');
|
||||
$this->assertText('There are no new nodes');
|
||||
$this->assertFeedItemCount(10);
|
||||
|
||||
// Now delete all items.
|
||||
$this->drupalPost('import/syndication_standalone/delete-items', array(), 'Delete');
|
||||
$this->assertText('Deleted 10 nodes');
|
||||
$this->assertFeedItemCount(0);
|
||||
|
||||
// Import again, we should find new content.
|
||||
$this->drupalPost('import/syndication_standalone', array(), 'Import');
|
||||
$this->assertText('Created 10 nodes');
|
||||
$this->assertFeedItemCount(10);
|
||||
|
||||
// Login with new user with only access content permissions.
|
||||
$this->drupalLogin($this->auth_user);
|
||||
|
||||
// Navigate to feed import form, access should be denied.
|
||||
$this->drupalGet('import/syndication_standalone');
|
||||
$this->assertResponse(403);
|
||||
|
||||
// Use File Fetcher.
|
||||
$this->drupalLogin($this->admin_user);
|
||||
|
||||
$edit = array('plugin_key' => 'FeedsFileFetcher');
|
||||
$this->drupalPost('admin/structure/feeds/syndication_standalone/fetcher', $edit, 'Save');
|
||||
|
||||
$edit = array(
|
||||
'allowed_extensions' => 'rss2',
|
||||
);
|
||||
$this->drupalPost('admin/structure/feeds/syndication_standalone/settings/FeedsFileFetcher', $edit, 'Save');
|
||||
|
||||
// Create a feed node.
|
||||
$edit = array(
|
||||
'files[feeds]' => $this->absolutePath() . '/tests/feeds/drupalplanet.rss2',
|
||||
);
|
||||
$this->drupalPost('import/syndication_standalone', $edit, 'Import');
|
||||
$this->assertText('Created 25 nodes');
|
||||
}
|
||||
|
||||
/**
|
||||
* Check that the total number of entries in the feeds_item table is correct.
|
||||
*/
|
||||
function assertFeedItemCount($num) {
|
||||
$count = db_query("SELECT COUNT(*) FROM {feeds_item} WHERE entity_type = 'node'")->fetchField();
|
||||
$this->assertEqual($count, $num, 'Accurate number of items in database.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Check thet contents of the current page for the DS feed.
|
||||
*/
|
||||
function assertDevseedFeedContent() {
|
||||
$this->assertText('Open Atrium Translation Workflow: Two Way Translation Updates');
|
||||
$this->assertText('Tue, 10/06/2009');
|
||||
$this->assertText('A new translation process for Open Atrium & integration with Localize Drupal');
|
||||
$this->assertText('Week in DC Tech: October 5th Edition');
|
||||
$this->assertText('Mon, 10/05/2009');
|
||||
$this->assertText('There are some great technology events happening this week');
|
||||
$this->assertText('Mapping Innovation at the World Bank with Open Atrium');
|
||||
$this->assertText('Fri, 10/02/2009');
|
||||
$this->assertText('is being used as a base platform for collaboration at the World Bank');
|
||||
$this->assertText('September GeoDC Meetup Tonight');
|
||||
$this->assertText('Wed, 09/30/2009');
|
||||
$this->assertText('Today is the last Wednesday of the month');
|
||||
$this->assertText('Week in DC Tech: September 28th Edition');
|
||||
$this->assertText('Mon, 09/28/2009');
|
||||
$this->assertText('Looking to geek out this week? There are a bunch of');
|
||||
$this->assertText('Open Data for Microfinance: The New MIXMarket.org');
|
||||
$this->assertText('Thu, 09/24/2009');
|
||||
$this->assertText('There are profiles for every country that the MIX Market is hosting.');
|
||||
$this->assertText('Integrating the Siteminder Access System in an Open Atrium-based Intranet');
|
||||
$this->assertText('Tue, 09/22/2009');
|
||||
$this->assertText('In addition to authentication, the Siteminder system');
|
||||
$this->assertText('Week in DC Tech: September 21 Edition');
|
||||
$this->assertText('Mon, 09/21/2009');
|
||||
$this->assertText('an interesting variety of technology events happening in Washington, DC ');
|
||||
$this->assertText('s Software Freedom Day: Impressions & Photos');
|
||||
$this->assertText('Mon, 09/21/2009');
|
||||
$this->assertText('Presenting on Features in Drupal and Open Atrium');
|
||||
$this->assertText('Scaling the Open Atrium UI');
|
||||
$this->assertText('Fri, 09/18/2009');
|
||||
$this->assertText('The first major change is switching');
|
||||
}
|
||||
|
||||
/**
|
||||
* Test validation of feed URLs.
|
||||
*/
|
||||
function testFeedURLValidation() {
|
||||
$edit['feeds[FeedsHTTPFetcher][source]'] = 'invalid://url';
|
||||
$this->drupalPost('node/add/page', $edit, 'Save');
|
||||
$this->assertText('The URL invalid://url is invalid.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Test using non-normal URLs like feed:// and webcal://.
|
||||
*/
|
||||
function testOddFeedSchemes() {
|
||||
$url = $GLOBALS['base_url'] . '/' . drupal_get_path('module', 'feeds') . '/tests/feeds/developmentseed.rss2';
|
||||
|
||||
$schemes = array('feed', 'webcal');
|
||||
$item_count = 0;
|
||||
foreach ($schemes as $scheme) {
|
||||
$feed_url = strtr($url, array('http://' => $scheme . '://', 'https://' => $scheme . '://'));
|
||||
|
||||
$edit['feeds[FeedsHTTPFetcher][source]'] = $feed_url;
|
||||
$this->drupalPost('node/add/page', $edit, 'Save');
|
||||
$this->assertText('Basic page Development Seed - Technological Solutions for Progressive Organizations has been created.');
|
||||
$this->assertText('Created 10 nodes.');
|
||||
$this->assertFeedItemCount($item_count + 10);
|
||||
$item_count += 10;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that feed elements and links are not found on non-feed nodes.
|
||||
*/
|
||||
function testNonFeedNodeUI() {
|
||||
// There should not be feed links on an article node.
|
||||
$non_feed_node = $this->drupalCreateNode(array('type' => 'article'));
|
||||
$this->drupalGet('node/' . $non_feed_node->nid);
|
||||
$this->assertNoLinkByHref('node/' . $non_feed_node->nid . '/import');
|
||||
$this->assertNoLink('Delete items');
|
||||
|
||||
// Navigate to a non-feed node form, there should be no Feed field visible.
|
||||
$this->drupalGet('node/add/article');
|
||||
$this->assertNoFieldByName('feeds[FeedsHTTPFetcher][source]');
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that nodes will not be created if the user is unauthorized to create
|
||||
* them.
|
||||
*/
|
||||
public function testAuthorize() {
|
||||
|
||||
// Create a user with limited permissions. We can't use
|
||||
// $this->drupalCreateUser here because we need to to set a specific user
|
||||
// name.
|
||||
$edit = array(
|
||||
'name' => 'Development Seed',
|
||||
'mail' => 'devseed@example.com',
|
||||
'pass' => user_password(),
|
||||
'status' => 1,
|
||||
);
|
||||
|
||||
$account = user_save(drupal_anonymous_user(), $edit);
|
||||
|
||||
// Adding a mapping to the user_name will invoke authorization.
|
||||
$this->addMappings('syndication',
|
||||
array(
|
||||
5 => array(
|
||||
'source' => 'author_name',
|
||||
'target' => 'user_name',
|
||||
),
|
||||
)
|
||||
);
|
||||
|
||||
$nid = $this->createFeedNode();
|
||||
|
||||
$this->assertText('Failed importing 10 nodes.');
|
||||
$this->assertText('User ' . $account->name . ' is not authorized to create content type article.');
|
||||
$node_count = db_query("SELECT COUNT(*) FROM {node}")->fetchField();
|
||||
|
||||
// We should have 1 node, the feed node.
|
||||
$this->assertEqual($node_count, 1, t('Correct number of nodes in the database.'));
|
||||
|
||||
// Give the user our admin powers.
|
||||
$edit = array(
|
||||
'roles' => $this->admin_user->roles,
|
||||
);
|
||||
$account = user_save($account, $edit);
|
||||
|
||||
$this->drupalPost("node/$nid/import", array(), 'Import');
|
||||
$this->assertText('Created 10 nodes.');
|
||||
$node_count = db_query("SELECT COUNT(*) FROM {node}")->fetchField();
|
||||
$this->assertEqual($node_count, 11, t('Correct number of nodes in the database.'));
|
||||
}
|
||||
}
|
92
sites/all/modules/feeds/tests/feeds_processor_term.test
Normal file
92
sites/all/modules/feeds/tests/feeds_processor_term.test
Normal file
@@ -0,0 +1,92 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Tests for plugins/FeedsTermProcessor.inc
|
||||
*/
|
||||
|
||||
/**
|
||||
* Test aggregating a feed as data records.
|
||||
*/
|
||||
class FeedsCSVtoTermsTest extends FeedsWebTestCase {
|
||||
public static function getInfo() {
|
||||
return array(
|
||||
'name' => 'CSV import to taxonomy',
|
||||
'description' => 'Tests a standalone import configuration that uses file fetcher and CSV parser to import taxonomy terms from a CSV file.',
|
||||
'group' => 'Feeds',
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test node creation, refreshing/deleting feeds and feed items.
|
||||
*/
|
||||
public function test() {
|
||||
|
||||
// Create an importer.
|
||||
$this->createImporterConfiguration('Term import', 'term_import');
|
||||
|
||||
// Set and configure plugins and mappings.
|
||||
$this->setPlugin('term_import', 'FeedsFileFetcher');
|
||||
$this->setPlugin('term_import', 'FeedsCSVParser');
|
||||
$this->setPlugin('term_import', 'FeedsTermProcessor');
|
||||
$mappings = array(
|
||||
0 => array(
|
||||
'source' => 'name',
|
||||
'target' => 'name',
|
||||
'unique' => 1,
|
||||
),
|
||||
);
|
||||
$this->addMappings('term_import', $mappings);
|
||||
|
||||
// Use standalone form.
|
||||
$edit = array(
|
||||
'content_type' => '',
|
||||
);
|
||||
$this->drupalPost('admin/structure/feeds/term_import/settings', $edit, 'Save');
|
||||
|
||||
$edit = array(
|
||||
'name' => 'Addams vocabulary',
|
||||
'machine_name' => 'addams',
|
||||
);
|
||||
$this->drupalPost('admin/structure/taxonomy/add', $edit, t('Save'));
|
||||
|
||||
$edit = array(
|
||||
'vocabulary' => 'addams',
|
||||
);
|
||||
$this->drupalPost('admin/structure/feeds/term_import/settings/FeedsTermProcessor', $edit, t('Save'));
|
||||
|
||||
// Import and assert.
|
||||
$this->importFile('term_import', $this->absolutePath() . '/tests/feeds/users.csv');
|
||||
$this->assertText('Created 5 terms');
|
||||
$this->drupalGet('admin/structure/taxonomy/addams');
|
||||
$this->assertText('Morticia');
|
||||
$this->assertText('Fester');
|
||||
$this->assertText('Gomez');
|
||||
$this->assertText('Pugsley');
|
||||
|
||||
// Import again.
|
||||
$this->importFile('term_import', $this->absolutePath() . '/tests/feeds/users.csv');
|
||||
$this->assertText('There are no new terms.');
|
||||
|
||||
// Force update.
|
||||
$this->setSettings('term_import', 'FeedsTermProcessor', array(
|
||||
'skip_hash_check' => TRUE,
|
||||
'update_existing' => 2,
|
||||
));
|
||||
$this->importFile('term_import', $this->absolutePath() . '/tests/feeds/users.csv');
|
||||
$this->assertText('Updated 5 terms.');
|
||||
|
||||
// Add a term manually, delete all terms, this term should still stand.
|
||||
$edit = array(
|
||||
'name' => 'Cousin Itt',
|
||||
);
|
||||
$this->drupalPost('admin/structure/taxonomy/addams/add', $edit, t('Save'));
|
||||
$this->drupalPost('import/term_import/delete-items', array(), t('Delete'));
|
||||
$this->drupalGet('admin/structure/taxonomy/addams');
|
||||
$this->assertText('Cousin Itt');
|
||||
$this->assertNoText('Morticia');
|
||||
$this->assertNoText('Fester');
|
||||
$this->assertNoText('Gomez');
|
||||
$this->assertNoText('Pugsley');
|
||||
}
|
||||
}
|
122
sites/all/modules/feeds/tests/feeds_processor_user.test
Normal file
122
sites/all/modules/feeds/tests/feeds_processor_user.test
Normal file
@@ -0,0 +1,122 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Tests for plugins/FeedsUserProcessor.inc
|
||||
*/
|
||||
|
||||
/**
|
||||
* Test aggregating a feed as data records.
|
||||
*/
|
||||
class FeedsCSVtoUsersTest extends FeedsWebTestCase {
|
||||
public static function getInfo() {
|
||||
return array(
|
||||
'name' => 'CSV import to users',
|
||||
'description' => 'Tests a standalone import configuration that uses file fetcher and CSV parser to import users from a CSV file.',
|
||||
'group' => 'Feeds',
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test node creation, refreshing/deleting feeds and feed items.
|
||||
*/
|
||||
public function test() {
|
||||
// Create an importer.
|
||||
$this->createImporterConfiguration('User import', 'user_import');
|
||||
|
||||
// Set and configure plugins.
|
||||
$this->setPlugin('user_import', 'FeedsFileFetcher');
|
||||
$this->setPlugin('user_import', 'FeedsCSVParser');
|
||||
$this->setPlugin('user_import', 'FeedsUserProcessor');
|
||||
|
||||
// Go to mapping page and create a couple of mappings.
|
||||
$mappings = array(
|
||||
0 => array(
|
||||
'source' => 'name',
|
||||
'target' => 'name',
|
||||
'unique' => FALSE,
|
||||
),
|
||||
1 => array(
|
||||
'source' => 'mail',
|
||||
'target' => 'mail',
|
||||
'unique' => TRUE,
|
||||
),
|
||||
2 => array(
|
||||
'source' => 'since',
|
||||
'target' => 'created',
|
||||
),
|
||||
3 => array(
|
||||
'source' => 'password',
|
||||
'target' => 'pass',
|
||||
),
|
||||
);
|
||||
$this->addMappings('user_import', $mappings);
|
||||
|
||||
// Use standalone form.
|
||||
$edit = array(
|
||||
'content_type' => '',
|
||||
);
|
||||
$this->drupalPost('admin/structure/feeds/user_import/settings', $edit, 'Save');
|
||||
|
||||
// Create roles and assign one of them to the users to be imported.
|
||||
$manager_rid = $this->drupalCreateRole(array('access content'), 'manager');
|
||||
$admin_rid = $this->drupalCreateRole(array('access content'), 'administrator');
|
||||
$edit = array(
|
||||
"roles[$manager_rid]" => TRUE,
|
||||
"roles[$admin_rid]" => FALSE,
|
||||
);
|
||||
$this->setSettings('user_import', 'FeedsUserProcessor', $edit);
|
||||
|
||||
// Import CSV file.
|
||||
$this->importFile('user_import', $this->absolutePath() . '/tests/feeds/users.csv');
|
||||
|
||||
// Assert result.
|
||||
$this->assertText('Created 3 users');
|
||||
// 1 user has an invalid email address, all users should be assigned
|
||||
// the manager role.
|
||||
$this->assertText('Failed importing 2 users.');
|
||||
$this->drupalGet('admin/people');
|
||||
$this->assertText('Morticia');
|
||||
$this->assertText('Fester');
|
||||
$this->assertText('Gomez');
|
||||
$count = db_query("SELECT count(*) FROM {users_roles} WHERE rid = :rid", array(':rid' => $manager_rid))->fetchField();
|
||||
$this->assertEqual($count, 3, t('All imported users were assigned the manager role.'));
|
||||
$count = db_query("SELECT count(*) FROM {users_roles} WHERE rid = :rid", array(':rid' => $admin_rid))->fetchField();
|
||||
$this->assertEqual($count, 0, t('No imported user was assigned the administrator role.'));
|
||||
|
||||
// Run import again, verify no new users.
|
||||
$this->importFile('user_import', $this->absolutePath() . '/tests/feeds/users.csv');
|
||||
$this->assertText('Failed importing 2 users.');
|
||||
|
||||
// Attempt to log in as one of the imported users.
|
||||
$account = user_load_by_name('Morticia');
|
||||
$this->assertTrue($account, 'Imported user account loaded.');
|
||||
$account->pass_raw = 'mort';
|
||||
$this->drupalLogin($account);
|
||||
|
||||
// Login as admin.
|
||||
$this->drupalLogin($this->admin_user);
|
||||
|
||||
// Removing a mapping forces updating without needing a different file.
|
||||
// We are also testing that if we don't map anything to the user's password
|
||||
// that it will keep its existing one.
|
||||
$mappings = array(
|
||||
3 => array(
|
||||
'source' => 'password',
|
||||
'target' => 'pass',
|
||||
),
|
||||
);
|
||||
$this->removeMappings('user_import', $mappings);
|
||||
$this->setSettings('user_import', 'FeedsUserProcessor', array('update_existing' => 2));
|
||||
$this->importFile('user_import', $this->absolutePath() . '/tests/feeds/users.csv');
|
||||
// Assert result.
|
||||
$this->assertText('Updated 3 users');
|
||||
$this->assertText('Failed importing 2 user');
|
||||
|
||||
// Attempt to log in as one of the imported users.
|
||||
$account = user_load_by_name('Fester');
|
||||
$this->assertTrue($account, 'Imported user account loaded.');
|
||||
$account->pass_raw = 'fest';
|
||||
$this->drupalLogin($account);
|
||||
}
|
||||
}
|
258
sites/all/modules/feeds/tests/feeds_scheduler.test
Normal file
258
sites/all/modules/feeds/tests/feeds_scheduler.test
Normal file
@@ -0,0 +1,258 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Feeds tests.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Test cron scheduling.
|
||||
*/
|
||||
class FeedsSchedulerTestCase extends FeedsWebTestCase {
|
||||
|
||||
public static function getInfo() {
|
||||
return array(
|
||||
'name' => 'Scheduler',
|
||||
'description' => 'Tests for feeds scheduler.',
|
||||
'group' => 'Feeds',
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test scheduling on cron.
|
||||
*/
|
||||
public function testScheduling() {
|
||||
// Create importer configuration.
|
||||
$this->createImporterConfiguration();
|
||||
$this->addMappings('syndication',
|
||||
array(
|
||||
0 => array(
|
||||
'source' => 'title',
|
||||
'target' => 'title',
|
||||
'unique' => FALSE,
|
||||
),
|
||||
1 => array(
|
||||
'source' => 'description',
|
||||
'target' => 'body',
|
||||
),
|
||||
2 => array(
|
||||
'source' => 'timestamp',
|
||||
'target' => 'created',
|
||||
),
|
||||
3 => array(
|
||||
'source' => 'url',
|
||||
'target' => 'url',
|
||||
'unique' => TRUE,
|
||||
),
|
||||
4 => array(
|
||||
'source' => 'guid',
|
||||
'target' => 'guid',
|
||||
'unique' => TRUE,
|
||||
),
|
||||
)
|
||||
);
|
||||
|
||||
// Create 10 feed nodes. Turn off import on create before doing that.
|
||||
$edit = array(
|
||||
'import_on_create' => FALSE,
|
||||
);
|
||||
$this->drupalPost('admin/structure/feeds/syndication/settings', $edit, 'Save');
|
||||
$this->assertText('Do not import on submission');
|
||||
|
||||
$nids = $this->createFeedNodes();
|
||||
// This implicitly tests the import_on_create node setting being 0.
|
||||
$this->assertTrue($nids[0] == 1 && $nids[1] == 2, 'Node ids sequential.');
|
||||
|
||||
// Check whether feed got properly added to scheduler.
|
||||
foreach ($nids as $nid) {
|
||||
$this->assertEqual(1, db_query("SELECT COUNT(*) FROM {job_schedule} WHERE type = 'syndication' AND id = :nid AND name = 'feeds_source_import' AND last <> 0 AND scheduled = 0 AND period = 1800 AND periodic = 1", array(':nid' => $nid))->fetchField());
|
||||
}
|
||||
|
||||
// Take time for comparisons.
|
||||
$time = time();
|
||||
sleep(1);
|
||||
|
||||
// Log out and run cron, no changes.
|
||||
$this->drupalLogout();
|
||||
$this->cronRun();
|
||||
$count = db_query("SELECT COUNT(*) FROM {job_schedule} WHERE last > :time", array(':time' => $time))->fetchField();
|
||||
$this->assertEqual($count, 0, '0 feeds refreshed on cron.');
|
||||
|
||||
// Set next time to 0 to simulate updates.
|
||||
// There should be 2 x job_schedule_num (= 10) feeds updated now.
|
||||
db_query("UPDATE {job_schedule} SET next = 0");
|
||||
$this->cronRun();
|
||||
$this->cronRun();
|
||||
|
||||
// There should be feeds_schedule_num X 2 (= 20) feeds updated now.
|
||||
$schedule = array();
|
||||
$rows = db_query("SELECT id, last, scheduled FROM {job_schedule} WHERE last > :time", array(':time' => $time));
|
||||
foreach ($rows as $row) {
|
||||
$schedule[$row->id] = $row;
|
||||
}
|
||||
$this->assertEqual(count($schedule), 20, '20 feeds refreshed on cron.' . $count);
|
||||
|
||||
// There should be 200 article nodes in the database.
|
||||
$count = db_query("SELECT COUNT(*) FROM {node} WHERE type = 'article' AND status = 1")->fetchField();
|
||||
$this->assertEqual($count, 200, 'There are 200 article nodes aggregated.' . $count);
|
||||
|
||||
// There shouldn't be any items with scheduled = 1 now, if so, this would
|
||||
// mean they are stuck.
|
||||
$count = db_query("SELECT COUNT(*) FROM {job_schedule} WHERE scheduled = 1")->fetchField();
|
||||
$this->assertEqual($count, 0, 'All items are unscheduled (schedule flag = 0).' . $count);
|
||||
|
||||
// Hit cron again twice.
|
||||
$this->cronRun();
|
||||
$this->cronRun();
|
||||
|
||||
// The import_period setting of the feed configuration is 1800, there
|
||||
// shouldn't be any change to the database now.
|
||||
$equal = TRUE;
|
||||
$rows = db_query("SELECT id, last, scheduled FROM {job_schedule} WHERE last > :time", array(':time' => $time));
|
||||
foreach ($rows as $row) {
|
||||
$equal = $equal && ($row->last == $schedule[$row->id]->last);
|
||||
}
|
||||
$this->assertTrue($equal, 'Schedule did not change.');
|
||||
|
||||
// Log back in and set refreshing to as often as possible.
|
||||
$this->drupalLogin($this->admin_user);
|
||||
$edit = array(
|
||||
'import_period' => 0,
|
||||
);
|
||||
$this->drupalPost('admin/structure/feeds/syndication/settings', $edit, 'Save');
|
||||
$this->assertText('Periodic import: as often as possible');
|
||||
$this->drupalLogout();
|
||||
|
||||
// Hit cron once, this should cause Feeds to reschedule all entries.
|
||||
$this->cronRun();
|
||||
$equal = FALSE;
|
||||
$rows = db_query("SELECT id, last, scheduled FROM {job_schedule} WHERE last > :time", array(':time' => $time));
|
||||
foreach ($rows as $row) {
|
||||
$equal = $equal && ($row->last == $schedule[$row->id]->last);
|
||||
$schedule[$row->id] = $row;
|
||||
}
|
||||
$this->assertFalse($equal, 'Every feed schedule time changed.');
|
||||
|
||||
// Hit cron again, 4 times now, every item should change again.
|
||||
for ($i = 0; $i < 4; $i++) {
|
||||
$this->cronRun();
|
||||
}
|
||||
$equal = FALSE;
|
||||
$rows = db_query("SELECT id, last, scheduled FROM {job_schedule} WHERE last > :time", array(':time' => $time));
|
||||
foreach ($rows as $row) {
|
||||
$equal = $equal && ($row->last == $schedule[$row->id]->last);
|
||||
}
|
||||
$this->assertFalse($equal, 'Every feed schedule time changed.');
|
||||
|
||||
// There should be 200 article nodes in the database.
|
||||
$count = db_query("SELECT COUNT(*) FROM {node} WHERE type = 'article' AND status = 1")->fetchField();
|
||||
$this->assertEqual($count, 200, 'The total of 200 article nodes has not changed.');
|
||||
|
||||
// Set expire settings, check rescheduling.
|
||||
$max_last = db_query("SELECT MAX(last) FROM {job_schedule} WHERE type = 'syndication' AND name = 'feeds_source_import' AND period = 0")->fetchField();
|
||||
$min_last = db_query("SELECT MIN(last) FROM {job_schedule} WHERE type = 'syndication' AND name = 'feeds_source_import' AND period = 0")->fetchField();
|
||||
$this->assertEqual(0, db_query("SELECT COUNT(*) FROM {job_schedule} WHERE type = 'syndication' AND name = 'feeds_importer_expire' AND last <> 0 AND scheduled = 0")->fetchField());
|
||||
$this->drupalLogin($this->admin_user);
|
||||
$this->setSettings('syndication', 'FeedsNodeProcessor', array('expire' => 86400));
|
||||
$this->drupalLogout();
|
||||
sleep(1);
|
||||
$this->cronRun();
|
||||
// There should be a feeds_importer_expire job now, and all last fields should be reset.
|
||||
$this->assertEqual(1, db_query("SELECT COUNT(*) FROM {job_schedule} WHERE type = 'syndication' AND name = 'feeds_importer_expire' AND last <> 0 AND scheduled = 0 AND period = 3600")->fetchField());
|
||||
$new_max_last = db_query("SELECT MAX(last) FROM {job_schedule} WHERE type = 'syndication' AND name = 'feeds_source_import' AND period = 0")->fetchField();
|
||||
$new_min_last = db_query("SELECT MIN(last) FROM {job_schedule} WHERE type = 'syndication' AND name = 'feeds_source_import' AND period = 0")->fetchField();
|
||||
$this->assertNotEqual($new_max_last, $max_last);
|
||||
$this->assertNotEqual($new_min_last, $min_last);
|
||||
$this->assertEqual($new_max_last, $new_min_last);
|
||||
$max_last = $new_max_last;
|
||||
$min_last = $new_min_last;
|
||||
|
||||
// Set import settings, check rescheduling.
|
||||
$this->drupalLogin($this->admin_user);
|
||||
$this->setSettings('syndication', '', array('import_period' => 3600));
|
||||
$this->drupalLogout();
|
||||
sleep(1);
|
||||
$this->cronRun();
|
||||
$new_max_last = db_query("SELECT MAX(last) FROM {job_schedule} WHERE type = 'syndication' AND name = 'feeds_source_import' AND period = 3600")->fetchField();
|
||||
$new_min_last = db_query("SELECT MIN(last) FROM {job_schedule} WHERE type = 'syndication' AND name = 'feeds_source_import' AND period = 3600")->fetchField();
|
||||
$this->assertNotEqual($new_max_last, $max_last);
|
||||
$this->assertNotEqual($new_min_last, $min_last);
|
||||
$this->assertEqual($new_max_last, $new_min_last);
|
||||
$this->assertEqual(0, db_query("SELECT COUNT(*) FROM {job_schedule} WHERE type = 'syndication' AND name = 'feeds_source_import' AND period <> 3600")->fetchField());
|
||||
$this->assertEqual(1, db_query("SELECT COUNT(*) FROM {job_schedule} WHERE type = 'syndication' AND name = 'feeds_importer_expire' AND period = 3600 AND last = :last", array(':last' => $new_min_last))->fetchField());
|
||||
|
||||
// Delete source, delete importer, check schedule.
|
||||
$this->drupalLogin($this->admin_user);
|
||||
$nid = array_shift($nids);
|
||||
$this->drupalPost("node/$nid/delete", array(), t('Delete'));
|
||||
$this->assertEqual(0, db_query("SELECT COUNT(*) FROM {job_schedule} WHERE type = 'syndication' AND name = 'feeds_source_import' AND id = :nid", array(':nid' => $nid))->fetchField());
|
||||
$this->assertEqual(count($nids), db_query("SELECT COUNT(*) FROM {job_schedule} WHERE type = 'syndication' AND name = 'feeds_source_import'")->fetchField());
|
||||
$this->assertEqual(1, db_query("SELECT COUNT(*) FROM {job_schedule} WHERE type = 'syndication' AND name = 'feeds_importer_expire' AND id = 0")->fetchField());
|
||||
|
||||
$this->drupalPost('admin/structure/feeds/syndication/delete', array(), t('Delete'));
|
||||
$this->assertEqual(0, db_query("SELECT COUNT(*) FROM {job_schedule} WHERE type = 'syndication' AND name = 'feeds_importer_expire' AND id = 0")->fetchField());
|
||||
$this->assertEqual(count($nids), db_query("SELECT COUNT(*) FROM {job_schedule} WHERE type = 'syndication' AND name = 'feeds_source_import'")->fetchField());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test batching on cron.
|
||||
*/
|
||||
function testBatching() {
|
||||
// Set up an importer.
|
||||
$this->createImporterConfiguration('Node import', 'node');
|
||||
// Set and configure plugins and mappings.
|
||||
$edit = array(
|
||||
'content_type' => '',
|
||||
);
|
||||
$this->drupalPost('admin/structure/feeds/node/settings', $edit, 'Save');
|
||||
$this->setPlugin('node', 'FeedsFileFetcher');
|
||||
$this->setPlugin('node', 'FeedsCSVParser');
|
||||
$mappings = array(
|
||||
0 => array(
|
||||
'source' => 'title',
|
||||
'target' => 'title',
|
||||
),
|
||||
);
|
||||
$this->addMappings('node', $mappings);
|
||||
|
||||
// Verify that there are 86 nodes total.
|
||||
$this->importFile('node', $this->absolutePath() . '/tests/feeds/many_nodes.csv');
|
||||
$this->assertText('Created 86 nodes');
|
||||
|
||||
// Run batch twice with two different process limits.
|
||||
// 50 = FEEDS_PROCESS_LIMIT.
|
||||
foreach (array(10, 50) as $limit) {
|
||||
variable_set('feeds_process_limit', $limit);
|
||||
|
||||
db_query("UPDATE {job_schedule} SET next = 0");
|
||||
$this->drupalPost('import/node/delete-items', array(), 'Delete');
|
||||
$this->assertEqual(0, db_query("SELECT COUNT(*) FROM {node} WHERE type = 'article'")->fetchField());
|
||||
|
||||
// Hit cron (item count / limit) times, assert correct number of articles.
|
||||
for ($i = 0; $i < ceil(86 / $limit); $i++) {
|
||||
$this->cronRun();
|
||||
sleep(1);
|
||||
if ($limit * ($i + 1) < 86) {
|
||||
$count = $limit * ($i + 1);
|
||||
$period = 0; // Import should be rescheduled for ASAP.
|
||||
}
|
||||
else {
|
||||
$count = 86; // We've reached our total of 86.
|
||||
$period = 1800; // Hence we should find the Source's default period.
|
||||
}
|
||||
$this->assertEqual($count, db_query("SELECT COUNT(*) FROM {node} WHERE type = 'article'")->fetchField());
|
||||
$this->assertEqual($period, db_query("SELECT period FROM {job_schedule} WHERE type = 'node' AND id = 0")->fetchField());
|
||||
}
|
||||
}
|
||||
|
||||
// Delete a couple of nodes, then hit cron again. They should not be replaced
|
||||
// as the minimum update time is 30 minutes.
|
||||
$nodes = db_query_range("SELECT nid FROM {node} WHERE type = 'article'", 0, 2);
|
||||
foreach ($nodes as $node) {
|
||||
$this->drupalPost("node/{$node->nid}/delete", array(), 'Delete');
|
||||
}
|
||||
$this->assertEqual(84, db_query("SELECT COUNT(*) FROM {node} WHERE type = 'article'")->fetchField());
|
||||
$this->cronRun();
|
||||
$this->assertEqual(84, db_query("SELECT COUNT(*) FROM {node} WHERE type = 'article'")->fetchField());
|
||||
}
|
||||
}
|
14
sites/all/modules/feeds/tests/feeds_tests.info
Normal file
14
sites/all/modules/feeds/tests/feeds_tests.info
Normal file
@@ -0,0 +1,14 @@
|
||||
name = "Feeds module tests"
|
||||
description = "Support module for Feeds related testing."
|
||||
package = Testing
|
||||
version = VERSION
|
||||
core = 7.x
|
||||
files[] = feeds_test.module
|
||||
hidden = TRUE
|
||||
|
||||
; Information added by drupal.org packaging script on 2012-10-24
|
||||
version = "7.x-2.0-alpha7"
|
||||
core = "7.x"
|
||||
project = "feeds"
|
||||
datestamp = "1351111319"
|
||||
|
184
sites/all/modules/feeds/tests/feeds_tests.module
Normal file
184
sites/all/modules/feeds/tests/feeds_tests.module
Normal file
@@ -0,0 +1,184 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Helper module for Feeds tests.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implements hook_menu().
|
||||
*/
|
||||
function feeds_tests_menu() {
|
||||
$items['testing/feeds/flickr.xml'] = array(
|
||||
'page callback' => 'feeds_tests_flickr',
|
||||
'access arguments' => array('access content'),
|
||||
'type' => MENU_CALLBACK,
|
||||
);
|
||||
$items['testing/feeds/files.csv'] = array(
|
||||
'page callback' => 'feeds_tests_files',
|
||||
'access arguments' => array('access content'),
|
||||
'type' => MENU_CALLBACK,
|
||||
);
|
||||
return $items;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_theme().
|
||||
*/
|
||||
function feeds_tests_theme() {
|
||||
return array(
|
||||
'feeds_tests_flickr' => array(
|
||||
'variables' => array('image_urls' => array()),
|
||||
'path' => drupal_get_path('module', 'feeds_tests') . '/feeds',
|
||||
'template' => 'feeds-tests-flickr',
|
||||
),
|
||||
'feeds_tests_files' => array(
|
||||
'variables' => array('files' => array()),
|
||||
'path' => drupal_get_path('module', 'feeds_tests') . '/feeds',
|
||||
'template' => 'feeds-tests-files',
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Outputs flickr test feed.
|
||||
*/
|
||||
function feeds_tests_flickr() {
|
||||
$images = array(
|
||||
0 => "tubing.jpeg",
|
||||
1 => "foosball.jpeg",
|
||||
2 => "attersee.jpeg",
|
||||
3 => "hstreet.jpeg",
|
||||
4 => "la fayette.jpeg",
|
||||
);
|
||||
$path = drupal_get_path('module', 'feeds_tests') . '/feeds/assets';
|
||||
foreach ($images as &$image) {
|
||||
$image = url("$path/$image", array('absolute' => TRUE));
|
||||
}
|
||||
drupal_add_http_header('Content-Type', 'application/rss+xml; charset=utf-8');
|
||||
print theme('feeds_tests_flickr', array('image_urls' => $images));
|
||||
}
|
||||
|
||||
/**
|
||||
* Outputs a CSV file pointing to files.
|
||||
*/
|
||||
function feeds_tests_files() {
|
||||
$images = array(
|
||||
0 => "tubing.jpeg",
|
||||
1 => "foosball.jpeg",
|
||||
2 => "attersee.jpeg",
|
||||
3 => "hstreet.jpeg",
|
||||
4 => "la fayette.jpeg",
|
||||
);
|
||||
foreach ($images as &$image) {
|
||||
$image = "public://images/$image";
|
||||
}
|
||||
drupal_add_http_header('Content-Type', 'text/plain; charset=utf-8');
|
||||
print theme('feeds_tests_files', array('files' => $images));
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_feeds_processor_targets_alter()
|
||||
*/
|
||||
function feeds_tests_feeds_processor_targets_alter(&$targets, $entity_type, $bundle_name) {
|
||||
$targets['test_target'] = array(
|
||||
'name' => t('Test Target'),
|
||||
'description' => t('This is a test target.'),
|
||||
'callback' => 'feeds_tests_mapper_set_target',
|
||||
'summary_callback' => 'feeds_tests_mapper_summary',
|
||||
'form_callback' => 'feeds_tests_mapper_form',
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set target value on entity.
|
||||
*
|
||||
* @see my_module_set_target()
|
||||
*/
|
||||
function feeds_tests_mapper_set_target($source, $entity, $target, $value, $mapping) {
|
||||
$entity->body['und'][0]['value'] = serialize($mapping);
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides setting summary for the mapper.
|
||||
*
|
||||
* @see my_module_summary_callback()
|
||||
*/
|
||||
function feeds_tests_mapper_summary($mapping, $target, $form, $form_state) {
|
||||
$options = array(
|
||||
'option1' => t('Option 1'),
|
||||
'option2' => t('Another Option'),
|
||||
'option3' => t('Option for select'),
|
||||
'option4' => t('Another One')
|
||||
);
|
||||
|
||||
$items = array();
|
||||
if (!empty($mapping['checkbox']) && $mapping['checkbox']) {
|
||||
$items[] = t('Checkbox active.');
|
||||
}
|
||||
else {
|
||||
$items[] = t('Checkbox inactive.');
|
||||
}
|
||||
if (!empty($mapping['textfield'])) {
|
||||
$items[] = t('<strong>Textfield value</strong>: %textfield', array('%textfield' => $mapping['textfield']));
|
||||
}
|
||||
if (!empty($mapping['textarea'])) {
|
||||
$items[] = t('<strong>Textarea value</strong>: %textarea', array('%textarea' => $mapping['textarea']));
|
||||
}
|
||||
if (!empty($mapping['radios'])) {
|
||||
$items[] = t('<strong>Radios value</strong>: %radios', array('%radios' => $options[$mapping['radios']]));
|
||||
}
|
||||
if (!empty($mapping['select'])) {
|
||||
$items[] = t('<strong>Select value</strong>: %select', array('%select' => $options[$mapping['select']]));
|
||||
}
|
||||
$list = array(
|
||||
'#type' => 'ul',
|
||||
'#theme' => 'item_list',
|
||||
'#items' => $items,
|
||||
);
|
||||
return drupal_render($list);
|
||||
}
|
||||
|
||||
/*
|
||||
* Provides the form with mapper settings.
|
||||
*/
|
||||
function feeds_tests_mapper_form($mapping, $target, $form, $form_state) {
|
||||
$mapping += array(
|
||||
'checkbox' => FALSE,
|
||||
'textfield' => '',
|
||||
'textarea' => '',
|
||||
'radios' => NULL,
|
||||
'select' => NULL,
|
||||
);
|
||||
return array(
|
||||
'checkbox' => array(
|
||||
'#type' => 'checkbox',
|
||||
'#title' => t('A checkbox'),
|
||||
'#default_value' => !empty($mapping['checkbox']),
|
||||
),
|
||||
'textfield' => array(
|
||||
'#type' => 'textfield',
|
||||
'#title' => t('A text field'),
|
||||
'#default_value' => $mapping['textfield'],
|
||||
'#required' => TRUE,
|
||||
),
|
||||
'textarea' => array(
|
||||
'#type' => 'textarea',
|
||||
'#title' => t('A textarea'),
|
||||
'#default_value' => $mapping['textarea'],
|
||||
),
|
||||
'radios' => array(
|
||||
'#type' => 'radios',
|
||||
'#title' => t('Some radios'),
|
||||
'#options' => array('option1' => t('Option 1'), 'option2' => t('Another Option')),
|
||||
'#default_value' => $mapping['radios'],
|
||||
),
|
||||
'select' => array(
|
||||
'#type' => 'select',
|
||||
'#title' => t('A select list'),
|
||||
'#options' => array('option3' => t('Option for select'), 'option4' => t('Another One')),
|
||||
'#default_value' => $mapping['select'],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
85
sites/all/modules/feeds/tests/parser_csv.test
Normal file
85
sites/all/modules/feeds/tests/parser_csv.test
Normal file
@@ -0,0 +1,85 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Tests for ParserCSV library.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Test aggregating a feed as node items.
|
||||
*
|
||||
* Using DrupalWebTestCase as DrupalUnitTestCase is broken in SimpleTest 2.8.
|
||||
* Not inheriting from Feeds base class as ParserCSV should be moved out of
|
||||
* Feeds at some time.
|
||||
*/
|
||||
class ParserCSVTest extends DrupalWebTestCase {
|
||||
protected $profile = 'testing';
|
||||
|
||||
public static function getInfo() {
|
||||
return array(
|
||||
'name' => 'CSV Parser unit tests',
|
||||
'description' => 'Base level test for Feeds\' built in CSV parser.',
|
||||
'group' => 'Feeds',
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method.
|
||||
*/
|
||||
public function test() {
|
||||
drupal_load('module', 'feeds');
|
||||
feeds_include_library('ParserCSV.inc', 'ParserCSV');
|
||||
|
||||
$this->_testSimple();
|
||||
$this->_testBatching();
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple test of parsing functionality.
|
||||
*/
|
||||
protected function _testSimple() {
|
||||
$file = $this->absolutePath() . '/tests/feeds/nodes.csv';
|
||||
include $this->absolutePath() . '/tests/feeds/nodes.csv.php';
|
||||
|
||||
$iterator = new ParserCSVIterator($file);
|
||||
$parser = new ParserCSV();
|
||||
$parser->setDelimiter(',');
|
||||
$rows = $parser->parse($iterator);
|
||||
$this->assertFalse($parser->lastLinePos(), t('Parser reports all lines parsed'));
|
||||
$this->assertEqual(md5(serialize($rows)), md5(serialize($control_result)), t('Parsed result matches control result.'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test batching.
|
||||
*/
|
||||
protected function _testBatching() {
|
||||
$file = $this->absolutePath() . '/tests/feeds/nodes.csv';
|
||||
include $this->absolutePath() . '/tests/feeds/nodes.csv.php';
|
||||
|
||||
// Set up parser with 2 lines to parse per call.
|
||||
$iterator = new ParserCSVIterator($file);
|
||||
$parser = new ParserCSV();
|
||||
$parser->setDelimiter(',');
|
||||
$parser->setLineLimit(2);
|
||||
$rows = array();
|
||||
$pos = 0;
|
||||
|
||||
// Call parser until all lines are parsed, then compare to control result.
|
||||
do {
|
||||
$parser->setStartByte($pos);
|
||||
$rows = array_merge($rows, $parser->parse($iterator));
|
||||
$pos = $parser->lastLinePos();
|
||||
$this->assertTrue($parser->lastLinePos() || count($rows) == 10, t('Parser reports line limit correctly'));
|
||||
}
|
||||
while ($pos = $parser->lastLinePos());
|
||||
|
||||
$this->assertEqual(md5(serialize($rows)), md5(serialize($control_result)), t('Parsed result matches control result.'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Absolute path to feeds.
|
||||
*/
|
||||
public function absolutePath() {
|
||||
return DRUPAL_ROOT . '/' . drupal_get_path('module', 'feeds');
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user