diff --git a/config/schema/feeds.schema.yml b/config/schema/feeds.schema.yml index 138a7cd2..70aa6448 100644 --- a/config/schema/feeds.schema.yml +++ b/config/schema/feeds.schema.yml @@ -121,6 +121,8 @@ feeds.fetcher.http: type: boolean use_pubsubhubbub: type: boolean + always_download: + type: boolean fallback_hub: type: string request_timeout: diff --git a/src/Feeds/Fetcher/Form/HttpFetcherForm.php b/src/Feeds/Fetcher/Form/HttpFetcherForm.php index 299ca36a..8cdf6a96 100644 --- a/src/Feeds/Fetcher/Form/HttpFetcherForm.php +++ b/src/Feeds/Fetcher/Form/HttpFetcherForm.php @@ -26,6 +26,12 @@ class HttpFetcherForm extends ExternalPluginFormBase { '#description' => $this->t('Attempt to use a PubSubHubbub subscription if available.'), '#default_value' => $this->plugin->getConfiguration('use_pubsubhubbub'), ]; + $form['always_download'] = [ + '#type' => 'checkbox', + '#title' => $this->t('Always download'), + '#description' => $this->t('Always download the feed, even if the feed has not been updated.'), + '#default_value' => $this->plugin->getConfiguration('always_download'), + ]; $form['fallback_hub'] = [ '#type' => 'url', '#title' => $this->t('Fallback hub'), diff --git a/src/Feeds/Fetcher/HttpFetcher.php b/src/Feeds/Fetcher/HttpFetcher.php index d06f35ca..6c57a1a4 100644 --- a/src/Feeds/Fetcher/HttpFetcher.php +++ b/src/Feeds/Fetcher/HttpFetcher.php @@ -99,7 +99,10 @@ class HttpFetcher extends PluginBase implements ClearableInterface, FetcherInter $sink = $this->fileSystem->tempnam('temporary://', 'feeds_http_fetcher'); $sink = $this->fileSystem->realpath($sink); - $response = $this->get($feed->getSource(), $sink, $this->getCacheKey($feed)); + // Get cache key if caching is enabled. + $cache_key = $this->useCache() ? $this->getCacheKey($feed) : FALSE; + + $response = $this->get($feed->getSource(), $sink, $cache_key); // @todo Handle redirects. // @codingStandardsIgnoreStart // $feed->setSource($response->getEffectiveUrl()); @@ -163,6 +166,16 @@ class HttpFetcher extends PluginBase implements ClearableInterface, FetcherInter return $response; } + /** + * Returns if the cache should be used. + * + * @return bool + * True if results should be cached. False otherwise. + */ + protected function useCache() { + return !$this->configuration['always_download']; + } + /** * Returns the download cache key for a given feed. * @@ -193,6 +206,7 @@ class HttpFetcher extends PluginBase implements ClearableInterface, FetcherInter // resolved. 'auto_detect_feeds' => FALSE, 'use_pubsubhubbub' => FALSE, + 'always_download' => FALSE, 'fallback_hub' => '', 'request_timeout' => 30, ]; diff --git a/tests/src/Functional/Feeds/Fetcher/HttpFetcherTest.php b/tests/src/Functional/Feeds/Fetcher/HttpFetcherTest.php index 4cd601ce..c124bd71 100644 --- a/tests/src/Functional/Feeds/Fetcher/HttpFetcherTest.php +++ b/tests/src/Functional/Feeds/Fetcher/HttpFetcherTest.php @@ -171,4 +171,77 @@ class HttpFetcherTest extends FeedsBrowserTestBase { $this->assertText('Deleted 6'); } + /** + * Tests if nothing gets cached when disabling HTTP Caching. + */ + public function testHttpCacheDisabled() { + // Disable caching. + $fetcher = $this->feedType->getFetcher(); + $config = $fetcher->getConfiguration(); + $config['always_download'] = TRUE; + $fetcher->setConfiguration($config); + $this->feedType->save(); + + // Import feed. + $feed = $this->createFeed($this->feedType->id(), [ + 'source' => $this->resourcesUrl() . '/rss/googlenewstz.rss2', + ]); + $this->batchImport($feed); + $this->assertText('Created 6'); + $this->assertNodeCount(6); + + // Assert that no cache entries were created. + $count = $this->container->get('database') + ->select('cache_feeds_download') + ->fields('cache_feeds_download', []) + ->countQuery() + ->execute() + ->fetchField(); + $this->assertEquals(0, $count); + } + + /** + * Tests if a changed source is refetched. + */ + public function testChangedSource() { + // Install module that dynamically generates a CSV file. + $this->container->get('module_installer')->install(['feeds_test_files']); + $this->rebuildContainer(); + + // Create a feed type. + $feed_type = $this->createFeedTypeForCsv([ + 'guid' => 'GUID', + 'title' => 'Title', + ], [ + 'fetcher' => 'http', + 'fetcher_configuration' => [], + 'processor_configuration' => [ + 'update_existing' => ProcessorInterface::UPDATE_EXISTING, + 'values' => [ + 'type' => 'article', + ], + ], + ]); + + // Import feed. + $feed = $this->createFeed($feed_type->id(), [ + 'source' => \Drupal::request()->getSchemeAndHttpHost() . '/testing/feeds/nodes.csv', + ]); + $this->batchImport($feed); + $this->assertText('Created 8'); + $this->assertNodeCount(8); + + // Import again. + $this->batchImport($feed); + $this->assertText('There are no new'); + + // Now change the source to test if the source is refetched. + // - Items 1 and 4 changed. + // - Items 2 and 7 were removed. + \Drupal::state()->set('feeds_test_nodes_last_modified', strtotime('Sun, 30 Mar 2016 10:19:55 GMT')); + + $this->batchImport($feed); + $this->assertText('Updated 2'); + } + } diff --git a/tests/src/Unit/Feeds/Fetcher/Form/HttpFetcherFormTest.php b/tests/src/Unit/Feeds/Fetcher/Form/HttpFetcherFormTest.php index 75d61404..435e08f4 100644 --- a/tests/src/Unit/Feeds/Fetcher/Form/HttpFetcherFormTest.php +++ b/tests/src/Unit/Feeds/Fetcher/Form/HttpFetcherFormTest.php @@ -26,7 +26,8 @@ class HttpFetcherFormTest extends FeedsUnitTestCase { $form_object->setStringTranslation($this->getStringTranslationStub()); $form = $form_object->buildConfigurationForm([], new FormState()); - $this->assertSame(count($form), 4); + $this->assertTrue(is_array($form)); + $this->assertNotEmpty($form); } }