CommentFileSizeAuthor
#54 drupal-aggregator_plugins-1930274-55.patch85.25 KBParisLiakos
#54 interdiff.txt741 bytesParisLiakos
#36 drupal-aggregator_plugins-1930274-36.patch85.7 KBParisLiakos
#36 interdiff.txt1.85 KBParisLiakos
#35 drupal-aggregator_plugins-1930274-35.patch85.7 KBParisLiakos
#35 interdiff.txt6.75 KBParisLiakos
#35 interdiff__.txt1.91 KBParisLiakos
#30 drupal-aggregator_plugins-1930274-30.patch85.32 KBParisLiakos
#30 interdiff.txt710 bytesParisLiakos
#28 drupal-aggregator_plugins-1930274-28.patch85.32 KBParisLiakos
#28 interdiff.txt5.61 KBParisLiakos
#25 drupal-aggregator_plugins-1930274-25.patch84.39 KBParisLiakos
#25 interdiff.txt1.25 KBParisLiakos
#23 drupal-aggregator_plugins-1930274-23.patch84.37 KBParisLiakos
#23 interdiff.txt851 bytesParisLiakos
#22 drupal-aggregator_plugins-1930274-22.patch84.42 KBParisLiakos
#22 interdiff.txt7.87 KBParisLiakos
#20 drupal-aggregator_plugins-1930274-20.patch84.41 KBParisLiakos
#17 drupal-aggregator_plugins-1930274-17.patch84.39 KBParisLiakos
#17 interdiff.txt947 bytesParisLiakos
#15 drupal-aggregator_plugins-1930274-15.patch84.39 KBParisLiakos
#15 interdiff.txt2.91 KBParisLiakos
#13 drupal-aggregator_plugins-1930274-13.patch84.42 KBParisLiakos
#13 interdiff.txt751 bytesParisLiakos
#12 drupal-aggregator_plugins-1930274-11.patch84.44 KBParisLiakos
#12 interdiff.txt772 bytesParisLiakos
#10 drupal-aggregator_plugins-1930274-10.patch84.57 KBParisLiakos
#10 interdiff.txt17.02 KBParisLiakos
#8 drupal-aggregator_plugins-1930274-8.patch74.66 KBParisLiakos
#8 interdiff.txt4.55 KBParisLiakos
#6 drupal-aggregator_plugins-1930274-6.patch74.13 KBParisLiakos
#6 interdiff.txt472 bytesParisLiakos
#3 drupal-aggregator_plugins-1930274-3.patch74.58 KBParisLiakos
#2 drupal-aggregator_plugins-1930274-2.patch59.02 KBParisLiakos
Support from Acquia helps fund testing for Drupal Acquia logo

Comments

ParisLiakos’s picture

Assigned: Unassigned » ParisLiakos

I am gonna use this as my chance to get familiar with plugin system within the weekend

ParisLiakos’s picture

Status: Active » Needs review
FileSize
59.02 KB

4 files hit @ /dev/null two of them are .inc..i love this..
this patch needs some love more, eg those globals in DefaultParser are ugly, but i am gonna turn them to properties..just want to see what tests say, functionality should be the same, i did some manual testing

Edit: do not review this patch, just want to see the tests..there wont be an interdiff with the next patch

ParisLiakos’s picture

ok, it is almost ready now, i just have some todos in tests, i am trying to figure out how to properly test them.
lets check with bot

Berdir’s picture

Only skimmed over it but looks nice.

+++ /dev/nullundefined
@@ -1,192 +0,0 @@
-/**
- * @file
- * Documentation for aggregator API.

Why are we removing the api documentation?

ParisLiakos’s picture

No hook_*_info() anymore..i transferred the documentation to the plugin interfaces

ParisLiakos’s picture

uh, noticed some stuff that accidentally slipped in the patch

Berdir’s picture

Nice patch, didn't read everything but awesome clean-up, just a few notes...

+++ b/core/modules/aggregator/aggregator.moduleundefined
@@ -313,18 +313,22 @@ function aggregator_cron() {
-  db_update('aggregator_feed')
-    ->fields(array('queued' => 0))
+  $result = entity_query('aggregator_feed')
     ->condition('queued', REQUEST_TIME - (3600 * 6), '<')

Off topic, but it's amazing that you can just switch a db_select() (well, in this case it's db_update but the result is the same) with entity_query() and. it. just. works. Even if it's a simple one as in this case.

+++ b/core/modules/aggregator/aggregator.moduleundefined
@@ -421,19 +423,7 @@ function aggregator_remove(Feed $feed) {
 function _aggregator_get_variables() {
   $config = config('aggregator.settings');
-  $fetcher = $config->get('fetcher');
-
-  $parser = $config->get('parser');
-  if ($parser == 'aggregator') {
-    include_once DRUPAL_ROOT . '/' . drupal_get_path('module', 'aggregator') . '/aggregator.parser.inc';
-  }
-
-  $processors = $config->get('processors');
-  if (in_array('aggregator', $processors)) {
-    include_once DRUPAL_ROOT . '/' . drupal_get_path('module', 'aggregator') . '/aggregator.processor.inc';
-  }
-
-  return array($fetcher, $parser, $processors);
+  return array($config->get('fetcher'), $config->get('parser'), $config->get('processors'));

Wondering if we want to kill this function and access the config directly where it's used? No need for this hack anymore...

+++ b/core/modules/aggregator/aggregator.moduleundefined
@@ -564,55 +562,6 @@ function aggregator_filter_xss($value) {
-function aggregator_sanitize_configuration() {

Is this still checked somewhere or do we no longer care? It could still happen that a module that provides a processor is disabled... but we don't do this for other plugins either I guess. And if the plugin no longer exits then I guess we can fall back to the default in the manager? (haven't actually checked if we do that)

+++ b/core/modules/aggregator/tests/lib/Drupal/aggregator_test/Plugin/aggregator/parser/TestParser.phpundefined
@@ -0,0 +1,33 @@
+   * Implements \Drupal\aggregator\Plugin\ParserInterface::parse().
+   * @todo Actually test this.

Nitpick, can we have a space between the Implements and @todo lines? ;)

ParisLiakos’s picture

You are right, _aggregator_get_variables() was only used in one place after the previous cleanup:) one more down!

About aggregator_sanitize_configuration

  1. This function was only called in the admin form..so if someone was disabling a module, nothing was happening till he actually visits the settings form...(which happens only once in my experience..when setting things up)...if we want to keep this, we should move it as a cron call too
  2. i dont see why we should mess with user settings..configuration should not be reset..Thats what views do right? It just says, broken/missing handler, it does not reset all the handlers or whatsoever
  3. If a plugin does not exist, it just wont be called (i might write a test for that later)

I know it might not be the issue to have this conversation, so i can just put it back in, i am fine with, i made so much more progress with the cleanup here, so i dont care

Berdir’s picture

Removing it sounds fine to me, as long as we don't crash if something is missing. Views is also simply displaying a "plugin missing" message, no need to do something different here I think.

ParisLiakos’s picture

as long as we don't crash if something is missing

Oops..added try/catch and tests for that..also tests for plugins:)
here we go

Status: Needs review » Needs work

The last submitted patch, drupal-aggregator_plugins-1930274-10.patch, failed testing.

ParisLiakos’s picture

Status: Needs work » Needs review
FileSize
772 bytes
84.44 KB

actually no need for try catch in aggregator_remove..hmmm and somehow i messed all the tests up with the patch above..lets see

ParisLiakos’s picture

oh, got it..forgot to remove an innocent line from the test plugin:)

Status: Needs review » Needs work

The last submitted patch, drupal-aggregator_plugins-1930274-13.patch, failed testing.

ParisLiakos’s picture

Status: Needs work » Needs review
FileSize
2.91 KB
84.39 KB

seems my ideas were bad:) lets see now..go. bot. green.

Status: Needs review » Needs work

The last submitted patch, drupal-aggregator_plugins-1930274-15.patch, failed testing.

ParisLiakos’s picture

Status: Needs work » Needs review
FileSize
947 bytes
84.39 KB

right..sorry for the noise
there we go, this should be green

Berdir’s picture

Issue tags: -Plugin system

Status: Needs review » Needs work
Issue tags: +Plugin system

The last submitted patch, drupal-aggregator_plugins-1930274-17.patch, failed testing.

ParisLiakos’s picture

Status: Needs work » Needs review
FileSize
84.41 KB

Annotation\Plugin moved to Component..
manually edited patches++

Berdir’s picture

Nit-pick mode...

+++ b/core/modules/aggregator/aggregator.moduleundefined
@@ -398,42 +403,17 @@ function aggregator_save_category($edit) {
+  // Call ProcessorInterface::remove() on all processors.

This should probably use the fully qualified namespace so that api.drupal.org (and a manual reader) can resolve it. Starting with a \

+++ b/core/modules/aggregator/aggregator.moduleundefined
@@ -446,15 +426,29 @@ function aggregator_refresh(Feed $feed) {
+    // @todo Maybe add a watchdog entry?

Yep, I'd suggest to add a watchdog_exception('aggregator', $e) here. Is almost easier than adding a @todo, so we can IMHO just do it here.

+++ b/core/modules/aggregator/aggregator.moduleundefined
@@ -464,43 +458,49 @@ function aggregator_refresh(Feed $feed) {
+        if (@count($feed->items)) {

The @count was already ther but that looks a bit ugly. Why do we need it? Can't we just add a !empty($feed->items) or something instead? Doesn't need to be in this issue.

+++ b/core/modules/aggregator/lib/Drupal/aggregator/Plugin/AggregatorPluginManager.phpundefined
@@ -2,7 +2,7 @@
- * Definition of Drupal\aggregator\Plugin\FetcherManager.
+ * Definition of Drupal\aggregator\Plugin\AggregatorPluginManager.

When changing this anyway, let's change it to "Contains \Drupal\..."

+++ b/core/modules/aggregator/lib/Drupal/aggregator/Plugin/ParserInterface.phpundefined
@@ -0,0 +1,53 @@
+   * @return
+   *   TRUE if parsing was successful, FALSE otherwise.

Should be @return bool then.

+++ b/core/modules/aggregator/lib/Drupal/aggregator/Plugin/ProcessorInterface.phpundefined
@@ -0,0 +1,86 @@
+   *   contains an array of feed items downloaded and parsed at the parsing stage.
+   *   See Drupal\aggregator\Plugin\FetcherInterface::parse()
+   *   for the basic format of a single item in the $feed->items array.

"stage." is a tiny bit over 80 characters. On the other side, there is some more space behind ".. parse()". Generally, docblocks should get as close to 80 characters as possible without getting above. Also, the parse() reference should have a leading \

+++ b/core/modules/aggregator/lib/Drupal/aggregator/Plugin/aggregator/fetcher/DefaultFetcher.phpundefined
@@ -16,7 +16,7 @@
- * Uses drupal_http_request() to download the feed.
+ * Uses http_default_client class to download the feed.

Should probably say service and not class.

+++ b/core/modules/aggregator/lib/Drupal/aggregator/Plugin/aggregator/parser/DefaultParser.phpundefined
@@ -0,0 +1,351 @@
+   * The extracted channel info.
+   * @var array
+   */
+  protected $channel = array();

Needs a space above @var I think. Same for those below.

+++ b/core/modules/aggregator/lib/Drupal/aggregator/Plugin/aggregator/processor/DefaultProcessor.phpundefined
@@ -0,0 +1,209 @@
+    // @todo This should probably be removed.
+    drupal_set_message(t('The news items from %site have been removed.', array('%site' => $feed->label())));

Removed or moved to wherever it's called, but not something to fix for this issue I guess.

+++ b/core/modules/aggregator/lib/Drupal/aggregator/Plugin/aggregator/processor/DefaultProcessor.phpundefined
@@ -0,0 +1,209 @@
+   * Implements \Drupal\aggregator\Plugin\ProcessorInterface::postProcess().
+   * Expires items from a feed depending on expiration settings.

Another space here.

+++ b/core/modules/aggregator/lib/Drupal/aggregator/Plugin/aggregator/processor/DefaultProcessor.phpundefined
@@ -0,0 +1,209 @@
+   * @param $count
+   *   Items count.
+   *
+   * @return
+   *   A string that is plural-formatted as "@count items".
+   */
+  protected function formatItems($count) {

Most of it is moved code, but while we're moving it, probably doesn't hurt to add some types to @param and @return where it's missing.

+++ b/core/modules/aggregator/lib/Drupal/aggregator/Tests/AggregatorConfigurationTest.phpundefined
@@ -36,5 +46,22 @@ function testSettingsPage() {
+    // @todo Re-enable when http://drupal.org/node/1780396 is fixed
+    //$this->assertResponse(200);

What does this have to do with that issue? The namespace/plugin issues should be fixed...

+++ b/core/modules/aggregator/lib/Drupal/aggregator/Tests/FeedFetcherPluginTest.phpundefined
@@ -0,0 +1,54 @@
+
+  /**
+   * Overrides \Drupal\simpletest\WebTestBase::setUp().
+   */
+  public function setUp() {

setUp() currently doesn't need a docblock.

ParisLiakos’s picture

Fixed all above

What does this have to do with that issue? The namespace/plugin issues should be fixed...

This tests fails because the plugin manager discovers plugin classes provided by aggregator_test, even though it is in the line above disabled..when i try it manually it works as should but not in the simpletest enviroment..This also made me spend quite some time to write some tests that are unaffected by this anomaly:(
so i tend to think that the issue is not fixed

ParisLiakos’s picture

Actually, nvm, i missed clearing the cache..fixed that as well:)

twistor’s picture

+++ b/core/modules/aggregator/aggregator.admin.incundefined
@@ -341,70 +341,50 @@ function aggregator_admin_form($form, $form_state) {
+  // Store definitions and managers so we can access them later.
+  $form['#definitions'] = $definitions;

Aren't we supposed to be putting things in $form_state instead?

+++ b/core/modules/aggregator/aggregator.moduleundefined
@@ -304,7 +305,7 @@ function aggregator_permission() {
 function aggregator_cron() {
- $result = db_query('SELECT fid FROM {aggregator_feed} WHERE queued = 0 AND checked + refresh < :time AND refresh <> :never', array(
+  $result = db_query('SELECT fid FROM {aggregator_feed} WHERE queued = 0 AND checked + refresh < :time AND refresh <> :never', array(
     ':time' => REQUEST_TIME,
     ':never' => AGGREGATOR_CLEAR_NEVER

entity_query()?

Review was interrupted, more to come.

ParisLiakos’s picture

I cant see how to convert this query to entity_query..this part AND checked + refresh < :time AND i dont think entity query supports it

ParisLiakos’s picture

Berdir’s picture

Looks great to me. Some final nitpicks and then I'll RTBC, looks like nobody else in interested in reviewing this :(

Maybe we can try to get some of the Feeds guys (looks like there's not much activity, but maybe @twistor?) interested in our aggregator.module improvements, so that they can actually rely on parts of it instead of doing their own thing in 8.x?

+++ b/core/modules/aggregator/aggregator.moduleundefined
@@ -464,43 +458,48 @@ function aggregator_refresh(Feed $feed) {
+  // Processing is done call postProcess on enabled processors.
+  foreach ($processor_instances as $instance) {

Processing is done*,* call ...

+++ b/core/modules/aggregator/lib/Drupal/aggregator/Plugin/aggregator/fetcher/DefaultFetcher.phpundefined
@@ -16,7 +16,7 @@
- * Uses drupal_http_request() to download the feed.
+ * Uses http_default_client service to download the feed.

Uses *the* http_default_client service, I think

+++ b/core/modules/aggregator/lib/Drupal/aggregator/Plugin/aggregator/parser/DefaultParser.phpundefined
@@ -0,0 +1,357 @@
+   * @return
+   *   FALSE on error, TRUE otherwise.

@return bool.

+++ b/core/modules/aggregator/lib/Drupal/aggregator/Plugin/aggregator/parser/DefaultParser.phpundefined
@@ -0,0 +1,357 @@
+   * Performs an action when an opening tag is encountered.
...
+   * Performs an action when a closing tag is encountered.
...
+   * Performs an action when data is encountered.

Can we add some @param's to those. And maybe state that those are callbacks for the XML parser.

Just want to make sure that the patch isn't going to come back from RTBC because of something like this :)

+++ b/core/modules/aggregator/lib/Drupal/aggregator/Plugin/aggregator/parser/DefaultParser.phpundefined
@@ -0,0 +1,357 @@
+   * @param $date_str
+   *   A string with a potentially W3C DTF date.
+   *
+   * @return

string for @param and int|false for @return I think.

+++ b/core/modules/aggregator/tests/lib/Drupal/aggregator_test/Plugin/aggregator/fetcher/TestFetcher.phpundefined
@@ -0,0 +1,39 @@
+    if ($feed->label() == 'Test feed') {

Can we use a different string for this? Maybe "Do not fetch" or "Return FALSE" or something other that's more self-speaking :)

ParisLiakos’s picture

thanks for the review:)
I fixed all the above..one thing i am not sure..
+ * @param resource $parser
i guess we dont use resource? i wasnt sure what it is and my d8 installation is really messed up, so i checked php.net and it documents it as resource:/

Berdir’s picture

Status: Needs review » Reviewed & tested by the community
+++ b/core/modules/aggregator/lib/Drupal/aggregator/Plugin/aggregator/parser/DefaultParser.phpundefined
@@ -321,10 +342,10 @@ function elementData($parser, $data) {
-   * @return
+   * @return int|FALSE

super-minor thing, false should be lowercase, see http://drupal.org/node/1354#types.

This can be fixed while commiting or when this will need a re-roll.

This looks great to me and is a very nice example of plugin conversions. Cleaner, interface-based and documented API's, unification with other systems, has better tests and improved inline documentation. Nothing left to complain about :)

ParisLiakos’s picture

fixed too:)

Status: Reviewed & tested by the community » Needs work
Issue tags: -Plugin system

The last submitted patch, drupal-aggregator_plugins-1930274-30.patch, failed testing.

Berdir’s picture

Status: Needs work » Needs review
Issue tags: +Plugin system

#30: drupal-aggregator_plugins-1930274-30.patch queued for re-testing.

Yeah sure testbot, as if *that* change could have broken anything.

Berdir’s picture

Status: Needs review » Reviewed & tested by the community
Lars Toomre’s picture

I am not changing status, but think drupal_container() notes should be addressed before this goes in. The rest are nitpicks from reading through the patch for first time.

+++ b/core/modules/aggregator/aggregator.admin.incundefined
@@ -341,70 +341,50 @@ function aggregator_admin_form($form, $form_state) {
+    $definitions[$type] = isset($definitions[$type]) ? $definitions[$type] : array();
+    $managers[$type] = drupal_container()->get("plugin.manager.aggregator.$type");
+    foreach ($managers[$type]->getDefinitions() as $id => $definition) {

I am pretty sure drupal_container() has been deprecated in favor of Drupal::service(). Can this be implemented here?

+++ b/core/modules/aggregator/aggregator.moduleundefined
@@ -398,42 +403,18 @@ function aggregator_save_category($edit) {
+  // Call \Drupal\aggregator\Plugin\ProcessorInterface::remove()
+  // on all processors.
+  $manager = drupal_container()->get('plugin.manager.aggregator.processor');
+  foreach ($manager->getDefinitions() as $id => $definition) {

This comment can be wrapped better. Ibid re: drupal_container().

+++ b/core/modules/aggregator/aggregator.moduleundefined
@@ -446,15 +427,28 @@ function aggregator_refresh(Feed $feed) {
+  // Retrieve processor manager now.
+  $processor_manager = drupal_container()->get('plugin.manager.aggregator.processor');
+  // Store instances in an array so we dont have to instantiate new objects.

Ibid re: drupal_container()

+++ b/core/modules/aggregator/aggregator.moduleundefined
@@ -464,43 +458,48 @@ function aggregator_refresh(Feed $feed) {
+        // If there are items on the feed, let all enabled processors do their work on it.
+        if (!empty($feed->items)) {
+          foreach ($processor_instances as $instance) {

I am pretty sure code comments are supposed to wrap at 80 characters as well.

+++ b/core/modules/aggregator/lib/Drupal/aggregator/FeedStorageController.phpundefined
@@ -51,9 +51,10 @@ protected function preDelete($entities) {
+      // Notify processors to remove stored items.
+      $manager = drupal_container()->get('plugin.manager.aggregator.processor');
+      foreach ($manager->getDefinitions() as $id => $definition) {

drupal_container() again.

+++ b/core/modules/aggregator/lib/Drupal/aggregator/Plugin/AggregatorPluginManager.phpundefined
@@ -13,19 +13,21 @@
+  }
+}

My understanding is that coding standards call for blank line before closing brace of a class. Same with other classes below (some are already correct).

+++ b/core/modules/aggregator/lib/Drupal/aggregator/Plugin/ProcessorInterface.phpundefined
@@ -0,0 +1,86 @@
+  /**
+   * Process feed data.

Processes? (third person verb tense)

+++ b/core/modules/aggregator/lib/Drupal/aggregator/Plugin/ProcessorInterface.phpundefined
@@ -0,0 +1,86 @@
+  /**
+   * Refresh feed information.

Refreshes?

+++ b/core/modules/aggregator/lib/Drupal/aggregator/Plugin/ProcessorInterface.phpundefined
@@ -0,0 +1,86 @@
+   * Called after the processing of the feed is completed
+   * by all selected processors.

Can be better wrapped for 80 characters.

+++ b/core/modules/aggregator/lib/Drupal/aggregator/Plugin/ProcessorInterface.phpundefined
@@ -0,0 +1,86 @@
+  /**
+   * Remove stored feed data.

Removes?

+++ b/core/modules/aggregator/lib/Drupal/aggregator/Tests/AggregatorConfigurationTest.phpundefined
@@ -23,12 +23,22 @@ public static function getInfo() {
+    $this->drupalGet('admin/config/services/aggregator/settings');
+    // Make sure that test plugins are present.
+    $this->assertText(t('Test fetcher'));
+    $this->assertText(t('Test parser'));
+    $this->assertText(t('Test processor'));

Are we ever testing this settings page in a language other than English? If not, t() calls can be removed to speed up tests.

+++ b/core/modules/aggregator/lib/Drupal/aggregator/Tests/AggregatorTestBase.phpundefined
@@ -149,9 +149,9 @@ function getDefaultFeedItemCount() {
    * @param $expected_count
-   *   Expected number of feed items.
+   *   Expected number of feed items. If omitted no check will happen.

This needs a type hint. 'int|null' correct? Also description should start with '(optional)'. Finally, I might suggest 'If omitted or set to NULL,'. (note comma)

ParisLiakos’s picture

ah, yeah drupal_container is a very good point..and sorry for double interdiff but i found a couple more drupal_container calls right before posting the patch

ParisLiakos’s picture

...that should be prefixed with \ while in class context

podarok’s picture

#36 +1RTBC

jibran’s picture

xjm’s picture

Issue tags: -Plugin system

Status: Reviewed & tested by the community » Needs work

The last submitted patch, drupal-aggregator_plugins-1930274-36.patch, failed testing.

ParisLiakos’s picture

Status: Needs work » Needs review
Issue tags: +Plugin system
ParisLiakos’s picture

Status: Needs review » Reviewed & tested by the community

Drupal\Core\Config\StorageException: Failed to write configuration file: sites/default/files/simpletest/571115/config_active/update_test.settings.yml in Drupal\Core\Config\FileStorage->write() (line 102 of /var/lib/drupaltestbot/sites/default/files/checkout/core/lib/Drupal/Core/Config/FileStorage.php).

obviously a bot thingie, back to rtbc...

podarok’s picture

Title: Convert aggregator processors and parsers to plugins » Convert aggregator fetcher, processors and parsers to plugins

wow
looking at #36 and it looks like Feeds contrib into core )))
Code looks good for me +1 RTBC

podarok’s picture

Priority: Normal » Major

marked #1827164: Integrate Feeds into core #1136482: [policy] Deprecate aggregator.module in D9 core and remove it in D10 as duplicates
and bumping this one as major due to covering a lot of possible issues with Feeds and possible help from Feeds contrib team

andypost’s picture

Nice patch, +1 to commit. Also there's some small suggestions
diffstat 23 files changed, 1201 insertions(+), 893 deletions(-)

+++ b/core/modules/aggregator/aggregator.admin.incundefined
@@ -341,70 +341,50 @@ function aggregator_admin_form($form, $form_state) {
+    foreach ($managers[$type]->getDefinitions() as $id => $definition) {
+      $label = $definition['title'] . ' <span class="description">' . $definition['description'] . '</span>';
+      $definitions[$type][$id] = $label;

This looks ugly, please change to format_string()
actually admin_form() needs follow-up for usability

+++ b/core/modules/aggregator/aggregator.moduleundefined
@@ -304,7 +305,7 @@ function aggregator_permission() {
 function aggregator_cron() {
- $result = db_query('SELECT fid FROM {aggregator_feed} WHERE queued = 0 AND checked + refresh < :time AND refresh <> :never', array(
+  $result = db_query('SELECT fid FROM {aggregator_feed} WHERE queued = 0 AND checked + refresh < :time AND refresh <> :never', array(
     ':time' => REQUEST_TIME,
     ':never' => AGGREGATOR_CLEAR_NEVER

+++ b/core/modules/aggregator/lib/Drupal/aggregator/Plugin/aggregator/processor/DefaultProcessor.phpundefined
@@ -0,0 +1,210 @@
+      if ($entry = entity_load_multiple_by_properties('aggregator_item', $values)) {
...
+    $iids = Database::getConnection()->query('SELECT iid FROM {aggregator_item} WHERE fid = :fid', array(':fid' => $feed->id()))->fetchCol();
...
+      $iids = Database::getConnection()->query('SELECT iid FROM {aggregator_item} WHERE fid = :fid AND timestamp < :timestamp', array(
+        ':fid' => $feed->id(),

+++ b/core/modules/aggregator/lib/Drupal/aggregator/Tests/FeedProcessorPluginTest.phpundefined
@@ -0,0 +1,70 @@
+    $entities = entity_load_multiple_by_properties('aggregator_feed', array('description' => $feed->description->value));

needs follow-up to convert to entity_query() to use entity storage controller

Suppose better off with "mysqkism" and have clean entity api for all aggregator

twistor’s picture

This will throw parse errors on a 304, 403, 404, etc, . I guess it's not actually related to this patch, and more-so to do with the Guzzle conversion. But, we need to handle status codes. Maybe turn off dead feeds. While we're at it, we should handle cache-control and expires headers.

twistor’s picture

Excuse me for a second, while I take a brain dump.

To elaborate more on my very brief statement in #1827164: Integrate Feeds into core, this doesn't get us too much farther with regard to Feeds depending on Aggregator, or some such thing. I'm not sure how much room is left for architectural improvements, but off the top of my head:

  • All processors run for every feed. Could make for an interesting pipeline approach, but breaks the terminology of Feeds. Would it be up to each processor's configuration if they were supposed to run?
  • A global parser?
  • The interfaces are too limited. For example: Feeds needs fetchers and parsers to be able to provide config forms. We could extend the interfaces, or wrap them, but all we would gain us is re-using the core fetcher and parser. Which brings me to:
  • It would be great to have a real RSS/Atom parser in core. Especially the Atom part. I know there's #1268232: XPath-based parser for aggregator, but I've been looking for an excuse to port Universal Feed Parser from Python to PHP. It's pretty much the greatest thing ever. Apologies to Zend_Feed. I still hate you, SimplePie.
  • No mapping stage. Might could shoehorn something in there, not sure. But, with mapping comes Importers and an entire new level of complexity. Sidenote: I would love a better name for those. Feed templates? Feed types?
  • No batching. This goes along with the interfaces being too simplistic.
  • Passing the same Feed object along. Ick. Way too much responsibility on individual plugins. Speaking of which:
  • I really want to change processors so that they operate on one item at a time. Then we could have an intelligent batch manager that watches memory usage. À la Drush.
  • PubSubHubbub support could be very interesting to add to core.

I'm sure there's more, but that's what stuck in my brain after reviewing the current state of Aggregator. I keep forgetting it exists.

This reminds me of Actions/Triggers vs. Rules.

ParisLiakos’s picture

All processors run for every feed

No, actually only the enabled processors process a feed..All of them run only on remove()..i only exposed remove() for all processors cause i replaced hook_aggregator_remove() with that..but maybe it makes sense to run remove() only for enabled processors as well
When #15266: Replace aggregator category system with taxonomy is in, i will make them configurable per feed type, so you can set different processors per feed type..right now configuration is global, which kinda defeats the point of enabling/disabling processors

It would be great to have a real RSS/Atom parser in core

We are gonna introduce one (zend feed probably) for both aggregator and views #1839468: [Followup] Replace aggregator rss parsing with Zend Feed
Maybe you can post your feedback there, eg why you think zend feed is bad idea

No batching.

Maybe we should convert the update items callback to batch

ParisLiakos’s picture

Title: Convert aggregator fetcher, processors and parsers to plugins » Convert aggregator processors and parsers to plugins

And fetchers are already plugins

ParisLiakos’s picture

Also, feel free open to open follow up issues for your bullet points above, i would be happy to work on them
Thanks for the feedback!

Berdir’s picture

@twistor: Thanks for joining in :)

The comment caused a bit of confusing, the goal of this issue is not to replace feeds. All it does is convert custom aggregator plugin stuff to the standard plugin architecture. How these plugins work together is AFAIK more or less unchanged. It will be the job of other issues to improve it.

Small improvements can still make it into 8.x (given that we will get below thresholds and we're currently a fair bit away from that) but moving feeds in core obviously not. The best thing might be to create separate issues for your feedback, point out how feeds does and why that's better.

Also, I suggest we stop commenting on this issue because every comment moves it back to the end of the RTBC queue, this has been waiting for quite a while already.

effulgentsia’s picture

neclimdul’s picture

Status: Reviewed & tested by the community » Needs review

I like everything about this _except_ some of the entity changes in hook_cron(). They seem unrelated to this patch(as far as I can tell) and I wonder if splitting a db_update into "load a bunch of entities and the call save on them" has some serious performance concerns for large collections of feeds.

Rather than mire this issue in "can we get a benchmarking and discuss", can we remove it from this issue and follow up or is it actually connected? If its is actually necessary, lets just move forward and discuss elsewhere if anyone cares.

ParisLiakos’s picture

Agreed, i reverted changes on the second db_update on aggregator_cron()
The first one has no performance impact since feed object is already loaded, i merely replace db_update with ->save()

neclimdul’s picture

Status: Needs review » Reviewed & tested by the community

Agreed. Back to RTBC!

webchick’s picture

Title: Convert aggregator processors and parsers to plugins » Change notice: Convert aggregator processors and parsers to plugins
Priority: Major » Critical
Status: Reviewed & tested by the community » Active
Issue tags: +Needs change record

Wow, this is a fantastic patch! It essentially represents almost a complete re-write of aggregator.module, but definitely for the better. Things that used to be pseudo-hooks are now part of an actual interface, and it's a lot clearer now of what's required in order to implement a processer, fetcher, or parser.

I'm sure I could probably find some nits if I looked hard enough, but I think whatever there is we can deal with in follow-ups. Great work!

Committed and pushed to 8.x. Thanks!

rootatwc: Want to be added to MAINTAINERS.txt for aggregator module? :)

Marking for change notice.

ParisLiakos’s picture

Status: Active » Needs review
Issue tags: -Needs change record

Change notice here:
http://drupal.org/node/1957310

Re #45

This looks ugly, please change to format_string()

I sneaked it in #1925048: Convert aggregator's system_config_form() to SystemConfigFormBase

actually admin_form() needs follow-up for usability

I actually think we should leave this after #15266: Replace aggregator category system with taxonomy is in, since certain stuff will change there

needs follow-up to convert to entity_query() to use entity storage controller

Suppose better off with "mysqkism" and have clean entity api for all aggregator

Opened #1957312: Use the entity storage controller in aggregator module

Re #56

rootatwc: Want to be added to MAINTAINERS.txt for aggregator module? :)

Sure, opened #1957314: Add rootatwc as aggregator maintainer in MAINTAINERS.txt, thanks!

Berdir’s picture

Title: Change notice: Convert aggregator processors and parsers to plugins » Convert aggregator processors and parsers to plugins
Priority: Critical » Major
Status: Needs review » Fixed

Hm, maybe shorten the change notice a bit by removing the code within the functions/methods and instead simply link to the new class on a.d.o as soon as it's there? That and link to the plugin API documentation on d.o. Looks good to me otherwise.

ParisLiakos’s picture

Assigned: ParisLiakos » Unassigned

Sure, i updated the change notice, looks better/shorter now:)

andypost’s picture

Status: Fixed » Needs work

Please add some lines about fetchers

Berdir’s picture

Fetchers were converted and documented in the initial change record: http://drupal.org/node/1704454

Maybe just reference that?

andypost’s picture

@Berdir yep, please reference both to have the overall picture,

Also this one requires updates in summary based on #47 feedback and follow-ups

ParisLiakos’s picture

Status: Needs work » Fixed

fetchers have nothing to do with this issue, they were already plugins..
i added a link in the change notice any way though

ParisLiakos’s picture

Issue summary: View changes

Updated issue summary

ParisLiakos’s picture

Issue summary: View changes

Add followups

ParisLiakos’s picture

i added the follow ups in summary, please if new ones are opened add them too

Automatically closed -- issue fixed for 2 weeks with no activity.

Anonymous’s picture

Issue summary: View changes

admin form usability