Commit 2e8b1a44 authored by webchick's avatar webchick

Issue #2127725 by ParisLiakos: Remove category handling from aggregator.

parent 8bacdc2a
......@@ -27,97 +27,6 @@ function aggregator_requirements($phase) {
* Implements hook_schema().
*/
function aggregator_schema() {
$schema['aggregator_category'] = array(
'description' => 'Stores categories for aggregator feeds and feed items.',
'fields' => array(
'cid' => array(
'type' => 'serial',
'not null' => TRUE,
'description' => 'Primary Key: Unique aggregator category ID.',
),
'title' => array(
'type' => 'varchar',
'length' => 255,
'not null' => TRUE,
'default' => '',
'description' => 'Title of the category.',
),
'description' => array(
'type' => 'text',
'not null' => TRUE,
'size' => 'big',
'description' => 'Description of the category',
),
'block' => array(
'type' => 'int',
'not null' => TRUE,
'default' => 0,
'size' => 'tiny',
'description' => 'The number of recent items to show within the category block.',
)
),
'primary key' => array('cid'),
'unique keys' => array(
'title' => array('title'),
),
);
$schema['aggregator_category_feed'] = array(
'description' => 'Bridge table; maps feeds to categories.',
'fields' => array(
'fid' => array(
'type' => 'int',
'not null' => TRUE,
'default' => 0,
'description' => "The feed's {aggregator_feed}.fid.",
),
'cid' => array(
'type' => 'int',
'not null' => TRUE,
'default' => 0,
'description' => 'The {aggregator_category}.cid to which the feed is being assigned.',
)
),
'primary key' => array('cid', 'fid'),
'indexes' => array(
'fid' => array('fid'),
),
'foreign keys' => array(
'aggregator_category' => array(
'table' => 'aggregator_category',
'columns' => array('cid' => 'cid'),
),
),
);
$schema['aggregator_category_item'] = array(
'description' => 'Bridge table; maps feed items to categories.',
'fields' => array(
'iid' => array(
'type' => 'int',
'not null' => TRUE,
'default' => 0,
'description' => "The feed item's {aggregator_item}.iid.",
),
'cid' => array(
'type' => 'int',
'not null' => TRUE,
'default' => 0,
'description' => 'The {aggregator_category}.cid to which the feed item is being assigned.',
)
),
'primary key' => array('cid', 'iid'),
'indexes' => array(
'iid' => array('iid'),
),
'foreign keys' => array(
'aggregator_category' => array(
'table' => 'aggregator_category',
'columns' => array('cid' => 'cid'),
),
),
);
$schema['aggregator_feed'] = array(
'description' => 'Stores feeds to be parsed by the aggregator.',
'fields' => array(
......@@ -297,7 +206,6 @@ function aggregator_update_8000() {
'aggregator_teaser_length' => 'items.teaser_length',
'aggregator_clear' => 'items.expire',
'aggregator_summary_items' => 'source.list_max',
'aggregator_category_selector' => 'source.category_selector',
));
}
......
......@@ -4,12 +4,6 @@ aggregator.feed_add:
appears_on:
- 'aggregator.admin_overview'
aggregator.category_add:
route_name: aggregator.category_add
title: 'Add category'
appears_on:
- 'aggregator.admin_overview'
aggregator.opml_add:
route_name: aggregator.opml_add
title: 'Import OPML'
......
......@@ -8,28 +8,10 @@ aggregator.admin_settings:
weight: 100
tab_root_id: aggregator.admin_overview
aggregator.category_view:
route_name: aggregator.category_view
tab_root_id: aggregator.category_view
title: 'View'
aggregator.categorize_category_form:
route_name: aggregator.categorize_category_form
tab_root_id: aggregator.category_view
title: Categorize
aggregator.category_edit:
route_name: aggregator.category_edit
tab_root_id: aggregator.category_view
title: Configure
weight: 10
aggregator.feed_view:
route_name: aggregator.feed_view
tab_root_id: aggregator.feed_view
title: View
aggregator.categorize_feed_form:
route_name: aggregator.categorize_feed_form
tab_root_id: aggregator.feed_view
title: 'Categorize'
aggregator.feed_configure:
route_name: aggregator.feed_configure
tab_root_id: aggregator.feed_view
......
......@@ -25,7 +25,7 @@ function aggregator_help($path, $arg) {
$output .= '<h3>' . t('Uses') . '</h3>';
$output .= '<dl>';
$output .= '<dt>' . t('Viewing feeds') . '</dt>';
$output .= '<dd>' . t('Feeds contain published content, and may be grouped in categories, generally by topic. Users view feed content in the <a href="@aggregator">main aggregator display</a>, or by <a href="@aggregator-sources">their source</a> (usually via an RSS feed reader). The most recent content in a feed or category can be displayed as a block through the <a href="@admin-block">Blocks administration page</a>.', array('@aggregator' => url('aggregator'), '@aggregator-sources' => url('aggregator/sources'), '@admin-block' => url('admin/structure/block'))) . '</a></dd>';
$output .= '<dd>' . t('Feeds contain published content. Users view feed content in the <a href="@aggregator">main aggregator display</a>, or by <a href="@aggregator-sources">their source</a> (usually via an RSS feed reader). The most recent content in a feed can be displayed as a block through the <a href="@admin-block">Blocks administration page</a>.', array('@aggregator' => url('aggregator'), '@aggregator-sources' => url('aggregator/sources'), '@admin-block' => url('admin/structure/block'))) . '</a></dd>';
$output .= '<dt>' . t('Adding, editing, and deleting feeds') . '</dt>';
$output .= '<dd>' . t('Administrators can add, edit, and delete feeds, and choose how often to check each feed for newly updated items on the <a href="@feededit">Feed aggregator administration page</a>.', array('@feededit' => url('admin/config/services/aggregator'))) . '</dd>';
$output .= '<dt>' . t('OPML integration') . '</dt>';
......@@ -36,12 +36,10 @@ function aggregator_help($path, $arg) {
return $output;
case 'admin/config/services/aggregator':
$output = '<p>' . t('Thousands of sites (particularly news sites and blogs) publish their latest headlines and posts in feeds, using a number of standardized XML-based formats. Formats supported by the aggregator include <a href="@rss">RSS</a>, <a href="@rdf">RDF</a>, and <a href="@atom">Atom</a>.', array('@rss' => 'http://cyber.law.harvard.edu/rss/', '@rdf' => 'http://www.w3.org/RDF/', '@atom' => 'http://www.atomenabled.org')) . '</p>';
$output .= '<p>' . t('Current feeds are listed below, and <a href="@addfeed">new feeds may be added</a>. For each feed or feed category, the <em>latest items</em> block may be enabled at the <a href="@block">blocks administration page</a>.', array('@addfeed' => url('admin/config/services/aggregator/add/feed'), '@block' => url('admin/structure/block'))) . '</p>';
$output .= '<p>' . t('Current feeds are listed below, and <a href="@addfeed">new feeds may be added</a>. For each feed, the <em>latest items</em> block may be enabled at the <a href="@block">blocks administration page</a>.', array('@addfeed' => url('admin/config/services/aggregator/add/feed'), '@block' => url('admin/structure/block'))) . '</p>';
return $output;
case 'admin/config/services/aggregator/add/feed':
return '<p>' . t('Add a feed in RSS, RDF or Atom format. A feed may only have one entry.') . '</p>';
case 'admin/config/services/aggregator/add/category':
return '<p>' . t('Categories allow feed items from different feeds to be grouped together. For example, several sport-related feeds may belong to a category named <em>Sports</em>. Feed items may be grouped automatically (by selecting a category when creating or editing a feed) or manually (via the <em>Categorize</em> page available from feed item listings). Each category provides its own feed page and block.') . '</p>';
case 'admin/config/services/aggregator/add/opml':
return '<p>' . t('<acronym title="Outline Processor Markup Language">OPML</acronym> is an XML format used to exchange multiple feeds between aggregators. A single OPML document may contain a collection of many feeds. Drupal can parse such a file and import all feeds at once, saving you the effort of adding them manually. You may either upload a local file from your computer or enter a URL where Drupal can download it.') . '</p>';
}
......@@ -81,7 +79,7 @@ function aggregator_theme() {
'file' => 'aggregator.pages.inc',
),
'aggregator_page_rss' => array(
'variables' => array('feeds' => NULL, 'category' => NULL),
'variables' => array('feeds' => NULL),
'file' => 'aggregator.pages.inc',
),
);
......@@ -93,7 +91,7 @@ function aggregator_theme() {
function aggregator_menu() {
$items['admin/config/services/aggregator'] = array(
'title' => 'Feed aggregator',
'description' => "Configure which content your site aggregates from other sites, how often it polls them, and how they're categorized.",
'description' => "Configure which content your site aggregates from other sites, and how often it polls them.",
'route_name' => 'aggregator.admin_overview',
'weight' => 10,
);
......@@ -114,13 +112,6 @@ function aggregator_menu() {
'title' => 'Sources',
'route_name' => 'aggregator.sources',
);
$items['aggregator/categories'] = array(
'title' => 'Categories',
'route_name' => 'aggregator.categories',
);
$items['aggregator/categories/%aggregator_category'] = array(
'route_name' => 'aggregator.category_view',
);
$items['aggregator/sources/%aggregator_feed'] = array(
'route_name' => 'aggregator.feed_view',
);
......@@ -132,14 +123,6 @@ function aggregator_menu() {
'title' => 'Delete feed',
'route_name' => 'aggregator.feed_delete',
);
$items['admin/config/services/aggregator/edit/category/%aggregator_category'] = array(
'title' => 'Edit category',
'route_name' => 'aggregator.category_admin_edit',
);
$items['admin/config/services/aggregator/delete/category/%aggregator_category'] = array(
'title' => 'Delete category',
'route_name' => 'aggregator.category_delete',
);
return $items;
}
......@@ -199,56 +182,6 @@ function aggregator_queue_info() {
return $queues;
}
/**
* Adds/edits/deletes aggregator categories.
*
* @param $edit
* An associative array describing the category to be added/edited/deleted.
*/
function aggregator_save_category($edit) {
$link_path = 'aggregator/categories/';
if (!empty($edit['cid'])) {
$link_path .= $edit['cid'];
if (!empty($edit['title'])) {
db_merge('aggregator_category')
->key(array('cid' => $edit['cid']))
->fields(array(
'title' => $edit['title'],
'description' => $edit['description'],
))
->execute();
$op = 'update';
}
else {
db_delete('aggregator_category')
->condition('cid', $edit['cid'])
->execute();
// Make sure there is no active block for this category.
if (\Drupal::moduleHandler()->moduleExists('block')) {
foreach (entity_load_multiple_by_properties('block', array('plugin' => 'aggregator_category_block:' . $edit['cid'])) as $block) {
$block->delete();
}
}
$edit['title'] = '';
$op = 'delete';
}
}
elseif (!empty($edit['title'])) {
// A single unique id for bundles and feeds, to use in blocks.
$link_path .= db_insert('aggregator_category')
->fields(array(
'title' => $edit['title'],
'description' => $edit['description'],
'block' => 5,
))
->execute();
$op = 'insert';
}
if (isset($op) && \Drupal::moduleHandler()->moduleExists('menu_link')) {
menu_link_maintain('aggregator', $op, $link_path, $edit['title']);
}
}
/**
* Checks a news feed for new items.
*
......@@ -348,22 +281,6 @@ function aggregator_feed_load($fid) {
return entity_load('aggregator_feed', $fid);
}
/**
* Loads an aggregator category.
*
* @param $cid
* The category id.
*
* @return stdClass|null
* An object containing all category properties.
*
* @deprecated Use Drupal\aggregator\CategoryStorageControllerInterface::load()
* instead.
*/
function aggregator_category_load($cid) {
return \Drupal::service('aggregator.category.storage')->load($cid);
}
/**
* Prepares variables for individual feed item block templates.
*
......
......@@ -16,22 +16,16 @@
* - sum: No filtering.
* - source: Filter the feed items, limiting the result to items from a
* single source.
* - category: Filter the feed items by category.
* @param mixed $data
* Feed or category data used for filtering. The type and value of $data
* depends on $type:
* Feed data used for filtering. The type and value of $data depends on $type:
* - source: $data is an object with $data->fid identifying the feed used to
* as filter.
* - category: $data is an array with $data['cid'] being the category id to
* filter on.
* The $data parameter is not used when $type is 'sum'.
* @param int $limit
* (optional) The number of records to return. Defaults to 20.
*
* @deprecated Use \Drupal\aggregator\ItemStorageController::loadAll() for
* loading all feed items, \Drupal\aggregator\ItemStorageController::loadByFeed()
* for loading feed items filtered by the source feed, and \Drupal\aggregator\ItemStorageController::loadByCategory()
* for loading feed items filtered by the feed category.
*
* @return \Drupal\aggregator\ItemInterface[]
* An array of the feed items.
......@@ -44,9 +38,6 @@ function aggregator_load_feed_items($type, $data = NULL, $limit = 20) {
case 'source':
return $storage_controller->loadByFeed($data->id(), $limit);
case 'category':
return $storage_controller->loadByCategory($data->cid, $limit);
}
}
......@@ -81,11 +72,6 @@ function template_preprocess_aggregator_item(&$variables) {
$variables['source_date'] = format_date($item->getPostedTime(), 'medium');
}
$variables['categories'] = array();
foreach ($item->categories as $category) {
$variables['categories'][$category->cid] = l($category->title, 'aggregator/categories/' . $category->cid);
}
$variables['attributes']['class'][] = 'feed-item';
}
......
......@@ -95,69 +95,6 @@ aggregator.sources:
requirements:
_permission: 'access news feeds'
aggregator.categories:
path: '/aggregator/categories'
defaults:
_content: '\Drupal\aggregator\Controller\AggregatorController::categories'
_title: 'Categories'
requirements:
_access_aggregator_categories: 'TRUE'
aggregator.category_view:
path: '/aggregator/categories/{cid}'
defaults:
_content: '\Drupal\aggregator\Controller\AggregatorController::viewCategory'
_title_callback: '\Drupal\aggregator\Controller\AggregatorController::categoryTitle'
requirements:
_permission: 'access news feeds'
aggregator.category_edit:
path: '/aggregator/categories/{cid}/configure'
defaults:
_form: '\Drupal\aggregator\Form\CategoryAdminForm'
_title: 'Configure'
requirements:
_permission: 'administer news feeds'
aggregator.category_admin_edit:
path: '/admin/config/services/aggregator/edit/category/{cid}'
defaults:
_form: '\Drupal\aggregator\Form\CategoryAdminForm'
requirements:
_permission: 'administer news feeds'
aggregator.category_delete:
path: '/admin/config/services/aggregator/delete/category/{cid}'
defaults:
_form: '\Drupal\aggregator\Form\CategoryDeleteForm'
_title: 'Delete category'
requirements:
_permission: 'administer news feeds'
aggregator.category_add:
path: '/admin/config/services/aggregator/add/category'
defaults:
_form: '\Drupal\aggregator\Form\CategoryAdminForm'
_title: 'Add category'
requirements:
_permission: 'administer news feeds'
aggregator.categorize_category_form:
path: '/aggregator/categories/{cid}/categorize'
defaults:
_form: '\Drupal\aggregator\Form\CategorizeCategoryForm'
_title: 'Categorize'
requirements:
_permission: 'administer news feeds'
aggregator.categorize_feed_form:
path: '/aggregator/sources/{aggregator_feed}/categorize'
defaults:
_form: '\Drupal\aggregator\Form\CategorizeFeedForm'
_title: 'Categorize'
requirements:
_permission: 'administer news feeds'
aggregator.opml_page:
path: '/aggregator/opml/{cid}'
defaults:
......
......@@ -8,11 +8,3 @@ services:
plugin.manager.aggregator.processor:
class: Drupal\aggregator\Plugin\AggregatorPluginManager
arguments: [processor, '@container.namespaces', '@cache.cache', '@language_manager']
access_check.aggregator.categories:
class: Drupal\aggregator\Access\CategoriesAccessCheck
arguments: ['@database']
tags:
- { name: access_check }
aggregator.category.storage:
class: Drupal\aggregator\CategoryStorageController
arguments: ['@database']
......@@ -265,58 +265,5 @@ function aggregator_views_data() {
),
);
$data['aggregator_category_feed']['table']['join'] = array(
'aggregator_item' => array(
'left_field' => 'fid',
'field' => 'fid',
),
);
$data['aggregator_category']['table']['group'] = t('Aggregator category');
$data['aggregator_category']['table']['join'] = array(
'aggregator_item' => array(
'left_table' => 'aggregator_category_feed',
'left_field' => 'cid',
'field' => 'cid',
),
);
$data['aggregator_category']['cid'] = array(
'title' => t('Category ID'),
'help' => t('The unique ID of the aggregator category.'),
'field' => array(
'id' => 'numeric',
),
'argument' => array(
'id' => 'aggregator_category_cid',
'name field' => 'title',
'numeric' => TRUE,
),
'filter' => array(
'id' => 'aggregator_category_cid',
),
'sort' => array(
'id' => 'standard',
),
);
$data['aggregator_category']['title'] = array(
'title' => t('Category'),
'help' => t('The title of the aggregator category.'),
'field' => array(
'id' => 'aggregator_category',
),
'argument' => array(
'id' => 'string',
),
'sort' => array(
'id' => 'standard',
),
'filter' => array(
'id' => 'string',
),
);
return $data;
}
......@@ -8,4 +8,3 @@ items:
expire: 9676800
source:
list_max: 3
category_selector: checkboxes
......@@ -36,6 +36,3 @@ aggregator.settings:
list_max:
type: integer
label: 'Number of items shown in listing pages'
category_selector:
type: string
label: 'Select categories using'
......@@ -125,54 +125,6 @@ display:
empty: { }
relationships: { }
arguments: { }
feed_items_per_category:
display_plugin: feed
id: feed_items_per_category
display_title: 'Feed per category'
position: 2
display_options:
path: aggregator/rss/%
display_description: ''
arguments:
cid:
id: cid
table: aggregator_category
field: cid
relationship: none
group_type: group
admin_label: ''
default_action: 'not found'
exception:
value: all
title_enable: false
title: All
title_enable: false
title: ''
breadcrumb_enable: false
breadcrumb: ''
default_argument_type: fixed
default_argument_options:
argument: ''
default_argument_skip_url: false
summary_options:
base_path: ''
count: true
items_per_page: 25
override: false
summary:
sort_order: asc
number_of_records: 0
format: default_summary
specify_validation: false
validate:
type: none
fail: 'not found'
validate_options: { }
break_phrase: false
not: '0'
plugin_id: aggregator_category_cid
defaults:
arguments: false
feed_items:
display_plugin: feed
id: feed_items
......
<?php
/**
* @file
* Contains \Drupal\aggregator\Access\CategoriesAccess.
*/
namespace Drupal\aggregator\Access;
use Drupal\Core\Access\StaticAccessCheckInterface;
use Drupal\Core\Database\Connection;
use Drupal\Core\Session\AccountInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Route;
/**
* Provides an access check for aggregator categories routes.
*/
class CategoriesAccessCheck implements StaticAccessCheckInterface {
/**
* The database connection.
*
* @var \Drupal\Core\Database\Connection
*/
protected $database;
/**
* Constructs a CategoriesAccessCheck object.
*
* @param \Drupal\Core\Database\Connection
* The database connection.
*/
public function __construct(Connection $database) {
$this->database = $database;
}
/**
* {@inheritdoc}
*/
public function appliesTo() {
return array('_access_aggregator_categories');
}
/**
* {@inheritdoc}
*/
public function access(Route $route, Request $request, AccountInterface $account) {
return $account->hasPermission('access news feeds') && (bool) $this->database->queryRange('SELECT 1 FROM {aggregator_category}', 0, 1)->fetchField() ? static::ALLOW : static::DENY;
}
}
<?php
/**
* @file
* Contains \Drupal\aggregator\CategoryStorageController.
*/
namespace Drupal\aggregator;
use Drupal\Core\Database\Connection;
/**
* Storage controller for aggregator categories.
*/
class CategoryStorageController implements CategoryStorageControllerInterface {
/**
* The database connection.
*
* @var \Drupal\Core\Database\Connection
*/
protected $database;
/**
* A cache of loaded categories.
*
* @var \stdClass[]
*/
protected $categories;
/**
* Creates a new CategoryStorageController object.
*
* @param \Drupal\Core\Database\Connection $database
* The database connection.
*/
public function __construct(Connection $database) {
$this->database = $database;
}
/**
* {@inheritdoc}
*/
public function load($cid) {
if (!isset($this->categories[$cid])) {
$this->categories[$cid] = $this->database->query("SELECT * FROM {aggregator_category} WHERE cid = :cid", array(':cid' => $cid))->fetchObject();
}
return $this->categories[$cid];
}
/**
* {@inheritdoc}
*/
public function save($category) {
$cid = $this->database->insert('aggregator_category')
->fields(array(
'title' => $category->title,
'description' => $category->description,
'block' => 5,
))
->execute();
return $cid;
}
/**
* {@inheritdoc}
*/
public function update($category) {
$this->database->merge('aggregator_category')
->key(array('cid' => $category->cid))
->fields(array(
'title' => $category->title,
'description' => $category->description,
))
->execute();
}
/**
* {@inheritdoc}
*/
public function delete($cid) {
$this->database->delete('aggregator_category')
->condition('cid', $cid)
->execute();
}
/**
* {@inheritdoc}
*/