Issue #2127725 by ParisLiakos: Remove category handling from aggregator.
parent
8bacdc2aa6
commit
2e8b1a44ca
|
@ -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 @@ use Drupal\Core\Entity\EntityInterface;
|
|||
* - 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
|
||||
|
|
|
@ -1,52 +0,0 @@
|
|||
<?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;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,135 +0,0 @@
|
|||
<?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}
|
||||
*/
|
||||
public function isUnique($title, $cid = NULL) {
|
||||
$query = $this->database->select('aggregator_category', 'ac')
|
||||
->fields('ac', array('title'))
|
||||
->condition('title', $title);
|
||||
if (!empty($cid)) {
|
||||
$query->condition('cid', $cid, '<>');
|
||||
}
|
||||
$rows = $query->execute()->fetchCol();
|
||||
return (empty($rows));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function loadByItem($item_id) {
|
||||
return $this->database->query('SELECT c.cid, c.title, ci.iid FROM {aggregator_category} c LEFT JOIN {aggregator_category_item} ci ON c.cid = ci.cid AND ci.iid = :iid', array(':iid' => $item_id));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function updateItem($iid, array $cids) {
|
||||
// Remove all existing category items.
|
||||
$this->database->delete('aggregator_category_item')
|
||||
->condition('iid', $iid)
|
||||
->execute();
|
||||
|
||||
// Insert new category items.
|
||||
if (!empty($cids)) {
|
||||
$insert = $this->database->insert('aggregator_category_item')
|
||||
->fields(array('iid', 'cid'));
|
||||
foreach ($cids as $cid) {
|
||||
$insert->values(array('iid' => $iid, 'cid' => $cid));
|
||||
}
|
||||
$insert->execute();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function loadAllKeyed() {
|
||||
return $this->database->query('SELECT c.cid, c.title FROM {aggregator_category} c ORDER BY title')->fetchAllKeyed();
|
||||
}
|
||||
|
||||
}
|
|
@ -1,99 +0,0 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\aggregator\CategoryStorageControllerInterface.
|
||||
*/
|
||||
|
||||
namespace Drupal\aggregator;
|
||||
|
||||
/**
|
||||
* Storage Controller for aggregator categories.
|
||||
*/
|
||||
interface CategoryStorageControllerInterface {
|
||||
|
||||
/**
|
||||
* Loads an aggregator category by its unique ID.
|
||||
*
|
||||
* @param int $cid
|
||||
* The unique category ID.
|
||||
*
|
||||
* @return stdClass|null
|
||||
* An object containing all category properties.
|
||||
*/
|
||||
public function load($cid);
|
||||
|
||||
/**
|
||||
* Saves an aggregator category.
|
||||
*
|
||||
* @param \stdClass $category
|
||||
* The category to save.
|
||||
*
|
||||
* @return int
|
||||
* The new category ID.
|
||||
*/
|
||||
public function save($category);
|
||||
|
||||
/**
|
||||
* Updates and aggregator category.
|
||||
*
|
||||
* @param \stdClass $category
|
||||
* The category.
|
||||
*/
|
||||
public function update($category);
|
||||
|
||||
/**
|
||||
* Deletes an aggregator category.
|
||||
*
|
||||
* @param int $cid
|
||||
* The category ID.
|
||||
*/
|
||||
public function delete($cid);
|
||||
|
||||
/**
|
||||
* Checks if the category title is unique.
|
||||
*
|
||||
* Optionally passes a category ID to exclude, if this check is for an
|
||||
* existing category.
|
||||
*
|
||||
* @param string $title
|
||||
* The category title.
|
||||
* @param int $cid
|
||||
* (optional) The category ID to exclude from the check.
|
||||
*
|
||||
* @return bool
|
||||
* TRUE if the category title is unique, FALSE otherwise.
|
||||
*/
|
||||
public function isUnique($title, $cid = NULL);
|
||||
|
||||
/**
|
||||
* Loads aggregator categories for an aggregator item.
|
||||
*
|
||||
* @param int $item_id
|
||||
* The aggregator item ID.
|
||||
*
|
||||
* @return array
|
||||
* An array of objects containing item ID, category ID and title.
|
||||
*/
|
||||
public function loadByItem($item_id);
|
||||
|
||||
/**
|
||||
* Updates the categories for an aggregator item.
|
||||
*
|
||||
* @param int $iid
|
||||
* The aggregator item ID.
|
||||
* @param array $cids
|
||||
* The category IDs.
|
||||
*/
|
||||
public function updateItem($iid, array $cids);
|
||||
|
||||
/**
|
||||
* Loads all categories.
|
||||
*
|
||||
* @return array
|
||||
* An array keyed on cid listing all available categories.
|
||||
*/
|
||||
public function loadAllKeyed();
|
||||
|
||||
}
|
||||
|
|
@ -10,7 +10,6 @@ namespace Drupal\aggregator\Controller;
|
|||
use Drupal\Component\Utility\Xss;
|
||||
use Drupal\Core\Controller\ControllerBase;
|
||||
use Drupal\Core\DependencyInjection\ContainerInjectionInterface;
|
||||
use Drupal\aggregator\CategoryStorageControllerInterface;
|
||||
use Drupal\aggregator\FeedInterface;
|
||||
use Drupal\aggregator\ItemInterface;
|
||||
use Drupal\Core\Database\Connection;
|
||||
|
@ -31,24 +30,14 @@ class AggregatorController extends ControllerBase implements ContainerInjectionI
|
|||
*/
|
||||
protected $database;
|
||||
|
||||
/**
|
||||
* The category storage controller.
|
||||
*
|
||||
* @var \Drupal\aggregator\CategoryStorageControllerInterface
|
||||
*/
|
||||
protected $categoryStorage;
|
||||
|
||||
/**
|
||||
* Constructs a \Drupal\aggregator\Controller\AggregatorController object.
|
||||
*
|
||||
* @param \Drupal\Core\Database\Connection $database
|
||||
* The database connection.
|
||||
* @param \Drupal\aggregator\CategoryStorageControllerInterface $category_storage
|
||||
* The category storage service.
|
||||
*/
|
||||
public function __construct(Connection $database, CategoryStorageControllerInterface $category_storage) {
|
||||
public function __construct(Connection $database) {
|
||||
$this->database = $database;
|
||||
$this->categoryStorage = $category_storage;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -56,8 +45,7 @@ class AggregatorController extends ControllerBase implements ContainerInjectionI
|
|||
*/
|
||||
public static function create(ContainerInterface $container) {
|
||||
return new static(
|
||||
$container->get('database'),
|
||||
$container->get('aggregator.category.storage')
|
||||
$container->get('database')
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -96,21 +84,6 @@ class AggregatorController extends ControllerBase implements ContainerInjectionI
|
|||
return $build;
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays feed items aggregated in a category.
|
||||
*
|
||||
* @param int $cid
|
||||
* The category id for which to list all of the aggregated items.
|
||||
*
|
||||
* @return array
|
||||
* The render array with list of items for the feed.
|
||||
*/
|
||||
public function viewCategory($cid) {
|
||||
$items = $this->entityManager()->getStorageController('aggregator_item')->loadByCategory($cid);
|
||||
$build = $this->buildPageList($items);
|
||||
return $build;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds a listing of aggregator feed items.
|
||||
*
|
||||
|
@ -209,75 +182,6 @@ class AggregatorController extends ControllerBase implements ContainerInjectionI
|
|||
'#empty' => $this->t('No feeds available. <a href="@link">Add feed</a>.', array('@link' => $this->urlGenerator()->generateFromPath('admin/config/services/aggregator/add/feed'))),
|
||||
);
|
||||
|
||||
$result = $this->database->query('SELECT c.cid, c.title, COUNT(ci.iid) as items FROM {aggregator_category} c LEFT JOIN {aggregator_category_item} ci ON c.cid = ci.cid GROUP BY c.cid, c.title ORDER BY title');
|
||||
|
||||
$header = array($this->t('Title'), $this->t('Items'), $this->t('Operations'));
|
||||
$rows = array();
|
||||
foreach ($result as $category) {
|
||||
$row = array();
|
||||
$row[] = l($category->title, "aggregator/categories/$category->cid");
|
||||
$row[] = format_plural($category->items, '1 item', '@count items');
|
||||
$links = array();
|
||||
$links['edit'] = array(
|
||||
'title' => $this->t('Edit'),
|
||||
'route_name' => 'aggregator.category_admin_edit',
|
||||
'route_parameters' => array('cid' => $category->cid),
|
||||
);
|
||||
$links['delete'] = array(
|
||||
'title' => $this->t('Delete'),
|
||||
'route_name' => 'aggregator.category_delete',
|
||||
'route_parameters' => array('cid' => $category->cid),
|
||||
);
|
||||
$row[] = array(
|
||||
'data' => array(
|
||||
'#type' => 'operations',
|
||||
'#links' => $links,
|
||||
),
|
||||
);
|
||||
$rows[] = $row;
|
||||
}
|
||||
$build['categories'] = array(
|
||||
'#prefix' => '<h3>' . $this->t('Category overview') . '</h3>',
|
||||
'#theme' => 'table',
|
||||
'#header' => $header,
|
||||
'#rows' => $rows,
|
||||
'#empty' => $this->t('No categories available. <a href="@link">Add category</a>.', array('@link' => $this->urlGenerator()->generateFromPath('admin/config/services/aggregator/add/category'))),
|
||||
);
|
||||
|
||||
return $build;
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays all the categories used by the Aggregator module.
|
||||
*
|
||||
* @return array
|
||||
* A render array.
|
||||
*/
|
||||
public function categories() {
|
||||
$entity_manager = $this->entityManager();
|
||||
$result = $this->database->query('SELECT c.cid, c.title, c.description FROM {aggregator_category} c LEFT JOIN {aggregator_category_item} ci ON c.cid = ci.cid LEFT JOIN {aggregator_item} i ON ci.iid = i.iid GROUP BY c.cid, c.title, c.description');
|
||||
|
||||
$build = array(
|
||||
'#type' => 'container',
|
||||
'#attributes' => array('class' => array('aggregator-wrapper')),
|
||||
'#sorted' => TRUE,
|
||||
);
|
||||
$aggregator_summary_items = $this->config('aggregator.settings')->get('source.list_max');
|
||||
foreach ($result as $category) {
|
||||
$summary_items = array();
|
||||
if ($aggregator_summary_items) {
|
||||
$items = $entity_manager->getStorageController('aggregator_item')->loadByCategory($category->cid);
|
||||
if ($items) {
|
||||
$summary_items = $entity_manager->getViewBuilder('aggregator_item')->viewMultiple($items, 'summary');
|
||||
}
|
||||
}
|
||||
$category->url = $this->urlGenerator()->generateFromPath('aggregator/categories/' . $category->cid);
|
||||
$build[$category->cid] = array(
|
||||
'#theme' => 'aggregator_summary_items',
|
||||
'#summary_items' => $summary_items,
|
||||
'#source' => $category,
|
||||
);
|
||||
}
|
||||
return $build;
|
||||
}
|
||||
|
||||
|
@ -340,22 +244,13 @@ class AggregatorController extends ControllerBase implements ContainerInjectionI
|
|||
}
|
||||
|
||||
/**
|
||||
* Generates an OPML representation of all feeds or feeds by category.
|
||||
*
|
||||
* @param int $cid
|
||||
* (optional) If set, feeds are exported only from a category with this ID.
|
||||
* Otherwise, all feeds are exported. Defaults to NULL.
|
||||
* Generates an OPML representation of all feeds.
|
||||
*
|
||||
* @return \Symfony\Component\HttpFoundation\Response
|
||||
* The response containing the OPML.
|
||||
*/
|
||||
public function opmlPage($cid = NULL) {
|
||||
if ($cid) {
|
||||
$result = $this->database->query('SELECT f.title, f.url FROM {aggregator_feed} f LEFT JOIN {aggregator_category_feed} c on f.fid = c.fid WHERE c.cid = :cid ORDER BY title', array(':cid' => $cid));
|
||||
}
|
||||
else {
|
||||
$result = $this->database->query('SELECT * FROM {aggregator_feed} ORDER BY title');
|
||||
}
|
||||
$result = $this->database->query('SELECT * FROM {aggregator_feed} ORDER BY title');
|
||||
|
||||
$feeds = $result->fetchAll();
|
||||
$aggregator_page_opml = array(
|
||||
|
@ -384,18 +279,4 @@ class AggregatorController extends ControllerBase implements ContainerInjectionI
|
|||
return Xss::filter($aggregator_feed->label());
|
||||
}
|
||||
|
||||
/**
|
||||
* Route title callback.
|
||||
*
|
||||
* @param int $cid
|
||||
* The category ID.
|
||||
*
|
||||
* @return string
|
||||
* The category label.
|
||||
*/
|
||||
public function categoryTitle($cid) {
|
||||
$category = $this->categoryStorage->load($cid);
|
||||
return Xss::filter($category->title);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -200,7 +200,6 @@ class Feed extends ContentEntityBase implements FeedInterface {
|
|||
* {@inheritdoc}
|
||||
*/
|
||||
public static function preDelete(EntityStorageControllerInterface $storage_controller, array $entities) {
|
||||
$storage_controller->deleteCategories($entities);
|
||||
foreach ($entities as $entity) {
|
||||
// Notify processors to remove stored items.
|
||||
$manager = \Drupal::service('plugin.manager.aggregator.processor');
|
||||
|
@ -227,26 +226,6 @@ class Feed extends ContentEntityBase implements FeedInterface {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function preSave(EntityStorageControllerInterface $storage_controller) {
|
||||
parent::preSave($storage_controller);
|
||||
|
||||
$storage_controller->deleteCategories(array($this->id() => $this));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function postSave(EntityStorageControllerInterface $storage_controller, $update = FALSE) {
|
||||
parent::postSave($storage_controller, $update);
|
||||
|
||||
if (!empty($this->categories)) {
|
||||
$storage_controller->saveCategories($this, $this->categories);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
|
|
@ -59,24 +59,6 @@ class Item extends ContentEntityBase implements ItemInterface {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function postSave(EntityStorageControllerInterface $storage_controller, $update = TRUE) {
|
||||
parent::postSave($storage_controller, $update);
|
||||
|
||||
$storage_controller->saveCategories($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function preDelete(EntityStorageControllerInterface $storage_controller, array $entities) {
|
||||
parent::preDelete($storage_controller, $entities);
|
||||
|
||||
$storage_controller->deleteCategories($entities);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
|
|
@ -11,7 +11,6 @@ use Drupal\Component\Utility\String;
|
|||
use Drupal\Core\Entity\ContentEntityFormController;
|
||||
use Drupal\Core\Entity\EntityManagerInterface;
|
||||
use Drupal\Core\Language\Language;
|
||||
use Drupal\aggregator\CategoryStorageControllerInterface;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
|
||||
/**
|
||||
|
@ -19,36 +18,6 @@ use Symfony\Component\DependencyInjection\ContainerInterface;
|
|||
*/
|
||||
class FeedFormController extends ContentEntityFormController {
|
||||
|
||||
/**
|
||||
* The category storage controller.
|
||||
*
|
||||
* @var \Drupal\aggregator\CategoryStorageControllerInterface
|
||||
*/
|
||||
protected $categoryStorageController;
|
||||
|
||||
/**
|
||||
* Constructs a FeedForm object.
|
||||
*
|
||||
* @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager
|
||||
* The entity manager.
|
||||
* @param \Drupal\aggregator\CategoryStorageControllerInterface $category_storage_controller
|
||||
* The category storage controller.
|
||||
*/
|
||||
public function __construct(EntityManagerInterface $entity_manager, CategoryStorageControllerInterface $category_storage_controller) {
|
||||
parent::__construct($entity_manager);
|
||||
$this->categoryStorageController = $category_storage_controller;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function create(ContainerInterface $container) {
|
||||
return new static(
|
||||
$container->get('entity.manager'),
|
||||
$container->get('aggregator.category.storage')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
@ -88,27 +57,6 @@ class FeedFormController extends ContentEntityFormController {
|
|||
'#description' => $this->t('The length of time between feed updates. Requires a correctly configured <a href="@cron">cron maintenance task</a>.', array('@cron' => url('admin/reports/status'))),
|
||||
);
|
||||
|
||||
// Handling of categories.
|
||||
$options = array();
|
||||
$values = array();
|
||||
$categories = $this->categoryStorageController->loadAllKeyed();
|
||||
foreach ($categories as $cid => $title) {
|
||||
$options[$cid] = String::checkPlain($title);
|
||||
if (!empty($feed->categories) && in_array($cid, array_keys($feed->categories))) {
|
||||
$values[] = $cid;
|
||||
}
|
||||
}
|
||||
|
||||
if ($options) {
|
||||
$form['category'] = array(
|
||||
'#type' => 'checkboxes',
|
||||
'#title' => $this->t('Categorize news items'),
|
||||
'#default_value' => $values,
|
||||
'#options' => $options,
|
||||
'#description' => $this->t('New feed items are automatically filed in the checked categories.'),
|
||||
);
|
||||
}
|
||||
|
||||
return parent::form($form, $form_state, $feed);
|
||||
}
|
||||
|
||||
|
@ -137,11 +85,6 @@ class FeedFormController extends ContentEntityFormController {
|
|||
public function save(array $form, array &$form_state) {
|
||||
$feed = $this->entity;
|
||||
$insert = (bool) $feed->id();
|
||||
if (!empty($form_state['values']['category'])) {
|
||||
// Store category values for post save operations.
|
||||
// @see \Drupal\Core\Entity\FeedStorageController::postSave()
|
||||
$feed->categories = $form_state['values']['category'];
|
||||
}
|
||||
$feed->save();
|
||||
if ($insert) {
|
||||
drupal_set_message($this->t('The feed %feed has been updated.', array('%feed' => $feed->label())));
|
||||
|
|
|
@ -18,49 +18,6 @@ use Drupal\Core\Entity\FieldableDatabaseStorageController;
|
|||
*/
|
||||
class FeedStorageController extends FieldableDatabaseStorageController implements FeedStorageControllerInterface {
|
||||
|
||||
/**
|
||||
* Overrides Drupal\Core\Entity\DataBaseStorageController::attachLoad().
|
||||
*/
|
||||
protected function attachLoad(&$queried_entities, $load_revision = FALSE) {
|
||||
parent::attachLoad($queried_entities, $load_revision);
|
||||
$this->loadCategories($queried_entities);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function loadCategories(array $feeds) {
|
||||
foreach ($feeds as $feed) {
|
||||
$feed->categories = $this->database->query('SELECT c.cid, c.title FROM {aggregator_category} c JOIN {aggregator_category_feed} f ON c.cid = f.cid AND f.fid = :fid ORDER BY title', array(':fid' => $feed->id()))->fetchAllKeyed();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function saveCategories(FeedInterface $feed, array $categories) {
|
||||
foreach ($categories as $cid => $value) {
|
||||
if ($value) {
|
||||
$this->database->insert('aggregator_category_feed')
|
||||
->fields(array(
|
||||
'fid' => $feed->id(),
|
||||
'cid' => $cid,
|
||||
))
|
||||
->execute();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function deleteCategories(array $feeds) {
|
||||
// An existing feed is being modified, delete the category listings.
|
||||
$this->database->delete('aggregator_category_feed')
|
||||
->condition('fid', array_keys($feeds))
|
||||
->execute();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
|
|
@ -15,33 +15,6 @@ use Drupal\Core\Entity\EntityStorageControllerInterface;
|
|||
*/
|
||||
interface FeedStorageControllerInterface extends EntityStorageControllerInterface {
|
||||
|
||||
/**
|
||||
* Loads the categories of a feed.
|
||||
*
|
||||
* @param array $feeds
|
||||
* A list of feed entities keyed by feed id. Each entity will get a
|
||||
* categories property added.
|
||||
*/
|
||||
public function loadCategories(array $feeds);
|
||||
|
||||
/**
|
||||
* Saves the categories of a feed.
|
||||
*
|
||||
* @param \Drupal\aggregator\Entity\FeedInterface $feed
|
||||
* The feed entity.
|
||||
* @param array $categories
|
||||
* The array of categories.
|
||||
*/
|
||||
public function saveCategories(FeedInterface $feed, array $categories);
|
||||
|
||||
/**
|
||||
* Deletes the categories of a feed.
|
||||
*
|
||||
* @param array $feeds
|
||||
* A list of feed entities keyed by feed id.
|
||||
*/
|
||||
public function deleteCategories(array $feeds);
|
||||
|
||||
/**
|
||||
* Provides a list of duplicate feeds.
|
||||
*
|
||||
|
|
|
@ -1,147 +0,0 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\aggregator\Form\AggregatorCategorizeFormBase.
|
||||
*/
|
||||
|
||||
namespace Drupal\aggregator\Form;
|
||||
|
||||
use Drupal\aggregator\CategoryStorageControllerInterface;
|
||||
use Drupal\aggregator\FeedInterface;
|
||||
use Drupal\aggregator\ItemStorageControllerInterface;
|
||||
use Drupal\Component\Utility\String;
|
||||
use Drupal\Core\Entity\EntityViewBuilderInterface;
|
||||
use Drupal\Core\Form\FormBase;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
|
||||
/**
|
||||
* Provides a base form to allow items to be categorized.
|
||||
*/
|
||||
abstract class AggregatorCategorizeFormBase extends FormBase {
|
||||
|
||||
/**
|
||||
* The aggregator item view builder.
|
||||
*
|
||||
* @var \Drupal\Core\Entity\EntityViewBuilderInterface
|
||||
*/
|
||||
protected $aggregatorItemRenderer;
|
||||
|
||||
/**
|
||||
* The aggregator config.
|
||||
*
|
||||
* @var \Drupal\Core\Config\Config
|
||||
*/
|
||||
protected $config;
|
||||
|
||||
/**
|
||||
* The aggregator item storage controller.
|
||||
*
|
||||
* @var \Drupal\aggregator\ItemStorageControllerInterface
|
||||
*/
|
||||
protected $aggregatorItemStorage;
|
||||
|
||||
/**
|
||||
* The aggregator category storage controller.
|
||||
*
|
||||
* @var \Drupal\aggregator\CategoryStorageControllerInterface
|
||||
*/
|
||||
protected $categoryStorage;
|
||||
|
||||
/**
|
||||
* The feed to use.
|
||||
*
|
||||
* @var \Drupal\aggregator\FeedInterface
|
||||
*/
|
||||
protected $feed;
|
||||
|
||||
/**
|
||||
* Constructs a \Drupal\aggregator\Controller\AggregatorController object.
|
||||
*
|
||||
* @param \Drupal\Core\Entity\EntityViewBuilderInterface $aggregator_item_renderer
|
||||
* The item view builder.
|
||||
* @param \Drupal\aggregator\ItemStorageControllerInterface $aggregator_item_storage
|
||||
* The aggregator item storage controller.
|
||||
* @param \Drupal\aggregator\CategoryStorageControllerInterface $category_storage
|
||||
* The category storage controller.
|
||||
*/
|
||||
public function __construct(EntityViewBuilderInterface $aggregator_item_renderer, ItemStorageControllerInterface $aggregator_item_storage, CategoryStorageControllerInterface $category_storage) {
|
||||
$this->aggregatorItemRenderer = $aggregator_item_renderer;
|
||||
$this->config = $this->config('aggregator.settings');
|
||||
$this->aggregatorItemStorage = $aggregator_item_storage;
|
||||
$this->categoryStorage = $category_storage;
|
||||
}
|
||||
|
||||
public static function create(ContainerInterface $container) {
|
||||
return new static(
|
||||
$container->get('entity.manager')->getViewBuilder('aggregator_item'),
|
||||
$container->get('entity.manager')->getStorageController('aggregator_item'),
|
||||
$container->get('aggregator.category.storage')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function buildForm(array $form, array &$form_state, array $items = NULL) {
|
||||
|
||||
$form['feed_source'] = array(
|
||||
'#value' => $this->feed,
|
||||
);
|
||||
$categories = array();
|
||||
$done = FALSE;
|
||||
|
||||
$form['items'] = array(
|
||||
'#type' => 'table',
|
||||
'#header' => array('', $this->t('Categorize')),
|
||||
);
|
||||
if ($items && ($form_items = $this->aggregatorItemRenderer->viewMultiple($items, 'default'))) {
|
||||
foreach (element_children($form_items) as $iid) {
|
||||
$categories_result = $this->categoryStorage->loadByItem($iid);
|
||||
|
||||
$selected = array();
|
||||
foreach ($categories_result as $category) {
|
||||
if (!$done) {
|
||||
$categories[$category->cid] = String::checkPlain($category->title);
|
||||
}
|
||||
if ($category->iid) {
|
||||
$selected[] = $category->cid;
|
||||
}
|
||||
}
|
||||
$done = TRUE;
|
||||
$form['items'][$iid]['item'] = $form_items[$iid];
|
||||
$form['items'][$iid]['categories'] = array(
|
||||
'#type' => $this->config->get('source.category_selector'),
|
||||
'#default_value' => $selected,
|
||||
'#options' => $categories,
|
||||
'#size' => 10,
|
||||
'#multiple' => TRUE,
|
||||
'#parents' => array('categories', $iid),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
$form['actions'] = array('#type' => 'actions');
|
||||
$form['actions']['submit'] = array(
|
||||
'#type' => 'submit',
|
||||
'#value' => t('Save categories'),
|
||||
);
|
||||
$form['pager'] = array('#theme' => 'pager');
|
||||
|
||||
return $form;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function submitForm(array &$form, array &$form_state) {
|
||||
if (!empty($form_state['values']['categories'])) {
|
||||
foreach ($form_state['values']['categories'] as $iid => $cids) {
|
||||
$this->categoryStorage->updateItem($iid, $cids);
|
||||
}
|
||||
}
|
||||
drupal_set_message($this->t('The categories have been saved.'));
|
||||
}
|
||||
|
||||
}
|
|
@ -1,30 +0,0 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains Drupal\aggregator\Form\CategorizeCategoryForm
|
||||
*/
|
||||
|
||||
namespace Drupal\aggregator\Form;
|
||||
|
||||
/**
|
||||
* A form for categorizing feed items in a feed category.
|
||||
*/
|
||||
class CategorizeCategoryForm extends AggregatorCategorizeFormBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getFormId() {
|
||||
return 'aggregator_page_category_form';
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function buildForm(array $form, array &$form_state, $cid = NULL) {
|
||||
$items = $this->aggregatorItemStorage->loadByCategory($cid);
|
||||
return parent::buildForm($form, $form_state, $items);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,33 +0,0 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains Drupal\aggregator\Form\CategorizeFeedForm
|
||||
*/
|
||||
|
||||
namespace Drupal\aggregator\Form;
|
||||
|
||||
use Drupal\aggregator\FeedInterface;
|
||||
|
||||
/**
|
||||
* A form for categorizing feed items from a feed.
|
||||
*/
|
||||
class CategorizeFeedForm extends AggregatorCategorizeFormBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getFormId() {
|
||||
return 'aggregator_page_source_form';
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function buildForm(array $form, array &$form_state, FeedInterface $aggregator_feed = NULL) {
|
||||
$this->feed = $aggregator_feed;
|
||||
$items = $this->aggregatorItemStorage->loadByFeed($aggregator_feed->id());
|
||||
return parent::buildForm($form, $form_state, $items);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,208 +0,0 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains Drupal\aggregator\Form\CategoryAdminForm.
|
||||
*/
|
||||
|
||||
namespace Drupal\aggregator\Form;
|
||||
|
||||
use Drupal\aggregator\CategoryStorageControllerInterface;
|
||||
use Drupal\block\Plugin\Type\BlockManager;
|
||||
use Drupal\Core\Extension\ModuleHandlerInterface;
|
||||
use Drupal\Core\Form\FormBase;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
|
||||
/**
|
||||
* Provides a form for configuring aggregator categories.
|
||||
*/
|
||||
class CategoryAdminForm extends FormBase {
|
||||
|
||||
/**
|
||||
* The module handler.
|
||||
*
|
||||
* @var \Drupal\Core\Extension\ModuleHandlerInterface
|
||||
*/
|
||||
protected $moduleHandler;
|
||||
|
||||
/**
|
||||
* The category storage controller.
|
||||
*
|
||||
* @var \Drupal\aggregator\CategoryStorageControllerInterface.
|
||||
*/
|
||||
protected $categoryStorageController;
|
||||
|
||||
/**
|
||||
* The block manager.
|
||||
*
|
||||
* @var \Drupal\block\Plugin\Type\BlockManager
|
||||
*/
|
||||
protected $blockManager;
|
||||
|
||||
/**
|
||||
* Creates a new CategoryForm object.
|
||||
*
|
||||
* @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
|
||||
* The module handler.
|
||||
* @param \Drupal\aggregator\CategoryStorageControllerInterface $category_storage_controller
|
||||
* The category storage controller.
|
||||
* @param \Drupal\block\Plugin\Type\BlockManager $block_manager
|
||||
* (optional) The block manager. Used if block module is enabled.
|
||||
*/
|
||||
public function __construct(ModuleHandlerInterface $module_handler, CategoryStorageControllerInterface $category_storage_controller, BlockManager $block_manager = NULL) {
|
||||
$this->moduleHandler = $module_handler;
|
||||
$this->categoryStorageController = $category_storage_controller;
|
||||
$this->blockManager = $block_manager;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function create(ContainerInterface $container) {
|
||||
$block_manager = NULL;
|
||||
if ($container->get('module_handler')->moduleExists('block')) {
|
||||
$block_manager = $container->get('plugin.manager.block');
|
||||
}
|
||||
return new static(
|
||||
$container->get('module_handler'),
|
||||
$container->get('aggregator.category.storage'),
|
||||
$block_manager
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getFormId() {
|
||||
return 'aggregator_form_category';
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function buildForm(array $form, array &$form_state, $cid = NULL) {
|
||||
$category = $this->categoryStorageController->load($cid);
|
||||
$form['title'] = array(
|
||||
'#type' => 'textfield',
|
||||
'#title' => $this->t('Title'),
|
||||
'#default_value' => isset($category->title) ? $category->title : '',
|
||||
'#maxlength' => 64,
|
||||
'#required' => TRUE,
|
||||
);
|
||||
$form['description'] = array(
|
||||
'#type' => 'textarea',
|
||||
'#title' => $this->t('Description'),
|
||||
'#default_value' => isset($category->description) ? $category->description : '',
|
||||
);
|
||||
$form['actions'] = array('#type' => 'actions');
|
||||
$form['actions']['submit'] = array(
|
||||
'#type' => 'submit',
|
||||
'#value' => $this->t('Save'),
|
||||
);
|
||||
if (!empty($category->cid)) {
|
||||
$form['actions']['delete'] = array(
|
||||
'#type' => 'submit',
|
||||
'#value' => $this->t('Delete'),
|
||||
);
|
||||
$form['cid'] = array('#type' => 'hidden', '#value' => $category->cid);
|
||||
}
|
||||
|
||||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function validateForm(array &$form, array &$form_state) {
|
||||
if ($form_state['values']['op'] == $this->t('Save')) {
|
||||
// Check for duplicate titles.
|
||||
$title = $form_state['values']['title'];
|
||||
if (isset($form_state['values']['cid'])) {
|
||||
// Exclude the current category ID when checking if it's unique.
|
||||
$unique = $this->categoryStorageController->isUnique($title, $form_state['values']['cid']);
|
||||
}
|
||||
else {
|
||||
$unique = $this->categoryStorageController->isUnique($title);
|
||||
}
|
||||
if (!$unique) {
|
||||
form_set_error('title', $form_state, $this->t('A category named %category already exists. Enter a unique title.', array('%category' => $title)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function submitForm(array &$form, array &$form_state) {
|
||||
// @todo Replicate this cache invalidation when these ops are separated.
|
||||
// Invalidate the block cache to update aggregator category-based derivatives.
|
||||
$this->clearBlockCache();
|
||||
|
||||
$link_path = 'aggregator/categories/';
|
||||
$title = $form_state['values']['title'];
|
||||
|
||||
// Redirect to a confirm delete form.
|
||||
if ($form_state['values']['op'] == $this->t('Delete')) {
|
||||
$cid = $form_state['values']['cid'];
|
||||
$form_state['redirect_route'] = array(
|
||||
'route_name' => 'aggregator.category_delete',
|
||||
'route_parameters' => array('cid' => $cid),
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
// Update the category.
|
||||
if (!empty($form_state['values']['cid'])) {
|
||||
$cid = $form_state['values']['cid'];
|
||||
$this->categoryStorageController->update((object) $form_state['values']);
|
||||
drupal_set_message($this->t('The category %category has been updated.', array('%category' => $title)));
|
||||
if (preg_match('/^\/admin/', $this->getRequest()->getPathInfo())) {
|
||||
$form_state['redirect_route']['route_name'] = 'aggregator.admin_overview';
|
||||
}
|
||||
else {
|
||||
$form_state['redirect_route'] = array(
|
||||
'route_name' => 'aggregator.category_view',
|
||||
'route_parameters' => array('cid' => $cid),
|
||||
);
|
||||
}
|
||||
$this->updateMenuLink('update', $link_path . $cid, $title);
|
||||
return;
|
||||
}
|
||||
|
||||
// Insert the category.
|
||||
$cid = $this->categoryStorageController->save((object) $form_state['values']);
|
||||
watchdog('aggregator', 'Category %category added.', array('%category' => $form_state['values']['title']), WATCHDOG_NOTICE, l($this->t('view'), 'admin/config/services/aggregator'));
|
||||
drupal_set_message($this->t('The category %category has been added.', array('%category' => $title)));
|
||||
|
||||
$this->updateMenuLink('insert', $link_path . $cid, $title);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear the block cached definitions.
|
||||
*/
|
||||
protected function clearBlockCache() {
|
||||
if (!empty($this->blockManager)) {
|
||||
$this->blockManager->clearCachedDefinitions();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates a category menu link.
|
||||
*
|
||||
* @param string $op
|
||||
* The operation to perform.
|
||||
* @param string $link_path
|
||||
* The path of the menu link.
|
||||
* @param string $title
|
||||
* The title of the menu link.
|
||||
*
|
||||
* @see menu_link_maintain()
|
||||
*/
|
||||
protected function updateMenuLink($op, $link_path, $title) {
|
||||
if (isset($op) && $this->moduleHandler->moduleExists('menu_link')) {
|
||||
menu_link_maintain('aggregator', $op, $link_path, $title);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -1,192 +0,0 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\aggregator\Form\CategoryDeleteForm.
|
||||
*/
|
||||
|
||||
namespace Drupal\aggregator\Form;
|
||||
|
||||
use Drupal\aggregator\CategoryStorageControllerInterface;
|
||||
use Drupal\Core\DependencyInjection\ContainerInjectionInterface;
|
||||
use Drupal\Core\Entity\EntityManagerInterface;
|
||||
use Drupal\Core\Extension\ModuleHandlerInterface;
|
||||
use Drupal\Core\Form\ConfirmFormBase;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
||||
|
||||
/**
|
||||
* Provides a confirm delete form.
|
||||
*/
|
||||
class CategoryDeleteForm extends ConfirmFormBase implements ContainerInjectionInterface {
|
||||
|
||||
/**
|
||||
* The category to be deleted.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $category;
|
||||
|
||||
/**
|
||||
* The module handler.
|
||||
*
|
||||
* @var \Drupal\Core\Extension\ModuleHandlerInterface
|
||||
*/
|
||||
protected $moduleHandler;
|
||||
|
||||
/**
|
||||
* The entity manager.
|
||||
*
|
||||
* @var \Drupal\Core\Entity\EntityManagerInterface
|
||||
*/
|
||||
protected $entityManager;
|
||||
|
||||
/**
|
||||
* The category storage controller.
|
||||
*
|
||||
* @var \Drupal\aggregator\CategoryStorageControllerInterface
|
||||
*/
|
||||
protected $categoryStorageController;
|
||||
|
||||
/**
|
||||
* Creates a new CategoryDeleteForm.
|
||||
*
|
||||
* @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
|
||||
* The module handler.
|
||||
* @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager
|
||||
* The entity manager.
|
||||
* @param CategoryStorageControllerInterface $category_storage_controller
|
||||
* The category storage controller.
|
||||
*/
|
||||
public function __construct(ModuleHandlerInterface $module_handler, EntityManagerInterface $entity_manager, CategoryStorageControllerInterface $category_storage_controller) {
|
||||
$this->moduleHandler = $module_handler;
|
||||
$this->entityManager = $entity_manager;
|
||||
$this->categoryStorageController = $category_storage_controller;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function create(ContainerInterface $container) {
|
||||
return new static (
|
||||
$container->get('module_handler'),
|
||||
$container->get('entity.manager'),
|
||||
$container->get('aggregator.category.storage')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getQuestion() {
|
||||
return $this->t('Are you sure you want to delete the category %title?', array('%title' => $this->category->title));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getCancelRoute() {
|
||||
return array(
|
||||
'route_name' => 'aggregator.admin_overview',
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getFormId() {
|
||||
return 'aggregator_category_delete';
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getConfirmText() {
|
||||
return $this->t('Delete');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getDescription() {
|
||||
return $this->t('This will delete the aggregator category, the menu item for this category, and any related category blocks.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Form constructor.
|
||||
*
|
||||
* @param array $form
|
||||
* An associative array containing the structure of the form.
|
||||
* @param array $form_state
|
||||
* An associative array containing the current state of the form.
|
||||
* @param int|null $cid
|
||||
* The category ID.
|
||||
*
|
||||
* @return array
|
||||
* The form structure.
|
||||
*
|
||||
* @throws \Symfony\Component\HttpKernel\Exception\NotFoundHttpException
|
||||
* If the cid param or category is not found.
|
||||
*/
|
||||
public function buildForm(array $form, array &$form_state, $cid = NULL) {
|
||||
$category = $this->categoryStorageController->load($cid);
|
||||
if (empty($cid) || empty($category)) {
|
||||
throw new NotFoundHttpException();
|
||||
}
|
||||
$this->category = $category;
|
||||
return parent::buildForm($form, $form_state);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function submitForm(array &$form, array &$form_state) {
|
||||
$cid = $this->category->cid;
|
||||
$title = $this->category->title;
|
||||
$this->categoryStorageController->delete($cid);
|
||||
// Make sure there is no active block for this category.
|
||||
$this->deleteBlocks($cid);
|
||||
watchdog('aggregator', 'Category %category deleted.', array('%category' => $title));
|
||||
drupal_set_message($this->t('The category %category has been deleted.', array('%category' => $title)));
|
||||
if (preg_match('/^\/admin/', $this->getRequest()->getPathInfo())) {
|
||||
$form_state['redirect_route']['route_name'] = 'aggregator.admin_overview';
|
||||
}
|
||||
else {
|
||||
$form_state['redirect_route']['route_name'] = 'aggregator.page_last';
|
||||
}
|
||||
$this->updateMenuLink('delete', 'aggregator/categories/' . $cid, $title);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete aggregator category blocks.
|
||||
*
|
||||
* @param int $cid
|
||||
* The category ID.
|
||||
*/
|
||||
protected function deleteBlocks($cid) {
|
||||
if ($this->moduleHandler->moduleExists('block')) {
|
||||
foreach ($this->entityManager->getStorageController('block')->loadByProperties(array('plugin' => 'aggregator_category_block:' . $cid)) as $block) {
|
||||
$block->delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates a category menu link.
|
||||
*
|
||||
* @param string $op
|
||||
* The operation to perform.
|
||||
* @param string $link_path
|
||||
* The path of the menu link.
|
||||
* @param string $title
|
||||
* The title of the menu link.
|
||||
*
|
||||
* @see menu_link_maintain()
|
||||
*/
|
||||
protected function updateMenuLink($op, $link_path, $title) {
|
||||
if (isset($op) && $this->moduleHandler->moduleExists('menu_link')) {
|
||||
menu_link_maintain('aggregator', $op, $link_path, $title);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -7,7 +7,6 @@
|
|||
|
||||
namespace Drupal\aggregator\Form;
|
||||
|
||||
use Drupal\aggregator\CategoryStorageControllerInterface;
|
||||
use Drupal\aggregator\FeedStorageControllerInterface;
|
||||
use Drupal\Component\Utility\Url;
|
||||
use Drupal\Core\Entity\Query\QueryFactory;
|
||||
|
@ -43,13 +42,6 @@ class OpmlFeedAdd extends FormBase {
|
|||
*/
|
||||
protected $httpClient;
|
||||
|
||||
/**
|
||||
* The category storage controller.
|
||||
*
|
||||
* @var \Drupal\aggregator\CategoryStorageControllerInterface
|
||||
*/
|
||||
protected $categoryStorageController;
|
||||
|
||||
/**
|
||||
* Constructs a database object.
|
||||
*
|
||||
|
@ -59,14 +51,11 @@ class OpmlFeedAdd extends FormBase {
|
|||
* The feed storage.
|
||||
* @param \Guzzle\Http\ClientInterface $http_client
|
||||
* The Guzzle HTTP client.
|
||||
* @param \Drupal\aggregator\CategoryStorageControllerInterface $category_storage_controller
|
||||
* The category storage controller.
|
||||
*/
|
||||
public function __construct(QueryFactory $query_factory, FeedStorageControllerInterface $feed_storage, ClientInterface $http_client, CategoryStorageControllerInterface $category_storage_controller) {
|
||||
public function __construct(QueryFactory $query_factory, FeedStorageControllerInterface $feed_storage, ClientInterface $http_client) {
|
||||
$this->queryFactory = $query_factory;
|
||||
$this->feedStorageController = $feed_storage;
|
||||
$this->httpClient = $http_client;
|
||||
$this->categoryStorageController = $category_storage_controller;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -76,8 +65,7 @@ class OpmlFeedAdd extends FormBase {
|
|||
return new static(
|
||||
$container->get('entity.query'),
|
||||
$container->get('entity.manager')->getStorageController('aggregator_feed'),
|
||||
$container->get('http_default_client'),
|
||||
$container->get('aggregator.category.storage')
|
||||
$container->get('http_default_client')
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -114,16 +102,6 @@ class OpmlFeedAdd extends FormBase {
|
|||
'#description' => $this->t('The length of time between feed updates. Requires a correctly configured <a href="@cron">cron maintenance task</a>.', array('@cron' => url('admin/reports/status'))),
|
||||
);
|
||||
|
||||
// Handling of categories.
|
||||
$options = array_map('check_plain', $this->categoryStorageController->loadAllKeyed());
|
||||
if ($options) {
|
||||
$form['category'] = array(
|
||||
'#type' => 'checkboxes',
|
||||
'#title' => $this->t('Categorize news items'),
|
||||
'#options' => $options,
|
||||
'#description' => $this->t('New feed items are automatically filed in the checked categories.'),
|
||||
);
|
||||
}
|
||||
$form['actions'] = array('#type' => 'actions');
|
||||
$form['actions']['submit'] = array(
|
||||
'#type' => 'submit',
|
||||
|
@ -210,7 +188,6 @@ class OpmlFeedAdd extends FormBase {
|
|||
'url' => $feed['url'],
|
||||
'refresh' => $form_state['values']['refresh'],
|
||||
));
|
||||
$new_feed->categories = $form_state['values']['category'];
|
||||
$new_feed->save();
|
||||
}
|
||||
|
||||
|
|
|
@ -20,47 +20,6 @@ use Drupal\Core\Entity\FieldableDatabaseStorageController;
|
|||
*/
|
||||
class ItemStorageController extends FieldableDatabaseStorageController implements ItemStorageControllerInterface {
|
||||
|
||||
/**
|
||||
* Overrides Drupal\Core\Entity\DataBaseStorageController::attachLoad().
|
||||
*/
|
||||
protected function attachLoad(&$queried_entities, $load_revision = FALSE) {
|
||||
parent::attachLoad($queried_entities, $load_revision);
|
||||
$this->loadCategories($queried_entities);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function loadCategories(array $entities) {
|
||||
foreach ($entities as $item) {
|
||||
$item->categories = db_query('SELECT c.title, c.cid FROM {aggregator_category_item} ci LEFT JOIN {aggregator_category} c ON ci.cid = c.cid WHERE ci.iid = :iid ORDER BY c.title', array(':iid' => $item->id()))->fetchAll();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function deleteCategories(array $entities) {
|
||||
$this->database->delete('aggregator_category_item')
|
||||
->condition('iid', array_keys($entities))
|
||||
->execute();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function saveCategories(Item $item) {
|
||||
$result = $this->database->query('SELECT cid FROM {aggregator_category_feed} WHERE fid = :fid', array(':fid' => $item->getFeedId()));
|
||||
foreach ($result as $category) {
|
||||
$this->database->merge('aggregator_category_item')
|
||||
->key(array(
|
||||
'iid' => $item->id(),
|
||||
'cid' => $category->cid,
|
||||
))
|
||||
->execute();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
@ -82,19 +41,6 @@ class ItemStorageController extends FieldableDatabaseStorageController implement
|
|||
return $this->executeFeedItemQuery($query, $limit);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function loadByCategory($cid, $limit = 20) {
|
||||
$query = $this->database->select('aggregator_category_item', 'c');
|
||||
$query->leftJoin('aggregator_item', 'i', 'c.iid = i.iid');
|
||||
$query->leftJoin('aggregator_feed', 'f', 'i.fid = f.fid');
|
||||
$query
|
||||
->fields('i', array('iid'))
|
||||
->condition('cid', $cid);
|
||||
return $this->executeFeedItemQuery($query, $limit);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to execute an item query.
|
||||
*
|
||||
|
|
|
@ -15,33 +15,6 @@ use Drupal\core\Entity\EntityStorageControllerInterface;
|
|||
*/
|
||||
interface ItemStorageControllerInterface extends EntityStorageControllerInterface {
|
||||
|
||||
/**
|
||||
* Load the categories for aggregator items.
|
||||
*
|
||||
* @param array $entities
|
||||
* An array of aggregator item objects, keyed by the item id. Each object
|
||||
* will get a categories property added.
|
||||
*/
|
||||
public function loadCategories(array $entities);
|
||||
|
||||
/**
|
||||
* Delete the categories for aggregator items.
|
||||
*
|
||||
* @param array $entities
|
||||
* An array of aggregator item objects, keyed by the item id being
|
||||
* deleted. The storage backend should delete the category data of the
|
||||
* items.
|
||||
*/
|
||||
public function deleteCategories(array $entities);
|
||||
|
||||
/**
|
||||
* Store the categories for aggregator items.
|
||||
*
|
||||
* @param Item $item
|
||||
* The storage backend should save the categories of this item.
|
||||
*/
|
||||
public function saveCategories(Item $item);
|
||||
|
||||
/**
|
||||
* Loads feed items from all feeds.
|
||||
*
|
||||
|
@ -66,17 +39,4 @@ interface ItemStorageControllerInterface extends EntityStorageControllerInterfac
|
|||
*/
|
||||
public function loadByFeed($fid, $limit = 20);
|
||||
|
||||
/**
|
||||
* Loads feed items from all feeds.
|
||||
*
|
||||
* @param int $cid
|
||||
* The category ID to filter by.
|
||||
* @param int $limit
|
||||
* (optional) The number of items to return. Defaults to 20.
|
||||
*
|
||||
* @return \Drupal\aggregator\ItemInterface[]
|
||||
* An array of the feed items.
|
||||
*/
|
||||
public function loadByCategory($cid, $limit = 20);
|
||||
|
||||
}
|
||||
|
|
|
@ -1,165 +0,0 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\aggregator\Plugin\Block\AggregatorCategoryBlock.
|
||||
*/
|
||||
|
||||
namespace Drupal\aggregator\Plugin\Block;
|
||||
|
||||
use Drupal\aggregator\CategoryStorageControllerInterface;
|
||||
use Drupal\block\BlockBase;
|
||||
use Drupal\block\Annotation\Block;
|
||||
use Drupal\Core\Annotation\Translation;
|
||||
use Drupal\Core\Database\Connection;
|
||||
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
|
||||
use Drupal\Core\Session\AccountInterface;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
|
||||
/**
|
||||
* Provides an 'Aggregator category' block for the latest items in a category.
|
||||
*
|
||||
* @Block(
|
||||
* id = "aggregator_category_block",
|
||||
* admin_label = @Translation("Aggregator category"),
|
||||
* category = @Translation("Lists (Views)")
|
||||
* )
|
||||
*/
|
||||
class AggregatorCategoryBlock extends BlockBase implements ContainerFactoryPluginInterface {
|
||||
|
||||
/**
|
||||
* The database connection.
|
||||
*
|
||||
* @var \Drupal\Core\Database\Connection
|
||||
*/
|
||||
protected $connection;
|
||||
|
||||
/**
|
||||
* The category storage controller.
|
||||
*
|
||||
* @var \Drupal\aggregator\CategoryStorageControllerInterface
|
||||
*/
|
||||
protected $categoryStorageController;
|
||||
|
||||
/**
|
||||
* Constructs an AggregatorFeedBlock object.
|
||||
*
|
||||
* @param array $configuration
|
||||
* A configuration array containing information about the plugin instance.
|
||||
* @param string $plugin_id
|
||||
* The plugin_id for the plugin instance.
|
||||
* @param array $plugin_definition
|
||||
* The plugin implementation definition.
|
||||
* @param \Drupal\Core\Database\Connection $connection
|
||||
* The database connection.
|
||||
*/
|
||||
public function __construct(array $configuration, $plugin_id, array $plugin_definition, Connection $connection, CategoryStorageControllerInterface $category_storage_controller) {
|
||||
parent::__construct($configuration, $plugin_id, $plugin_definition);
|
||||
$this->connection = $connection;
|
||||
$this->categoryStorageController = $category_storage_controller;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function create(ContainerInterface $container, array $configuration, $plugin_id, array $plugin_definition) {
|
||||
return new static(
|
||||
$configuration,
|
||||
$plugin_id,
|
||||
$plugin_definition,
|
||||
$container->get('database'),
|
||||
$container->get('aggregator.category.storage')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function defaultConfiguration() {
|
||||
// By default, the block will contain 10 feed items.
|
||||
return array(
|
||||
'cid' => 0,
|
||||
'block_count' => 10,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function access(AccountInterface $account) {
|
||||
// Only grant access to users with the 'access news feeds' permission.
|
||||
return $account->hasPermission('access news feeds');
|
||||
}
|
||||
|
||||
/**
|
||||
* Overrides \Drupal\block\BlockBase::blockForm().
|
||||
*/
|
||||
public function blockForm($form, &$form_state) {
|
||||
$result = $this->connection->query('SELECT cid, title FROM {aggregator_category} ORDER BY title');
|
||||
$options = array();
|
||||
foreach ($result as $category) {
|
||||
$options[$category->cid] = check_plain($category->title);
|
||||
}
|
||||
|
||||
$form['cid'] = array(
|
||||
'#type' => 'select',
|
||||
'#title' => t('Select the category that should be displayed'),
|
||||
'#default_value' => $this->configuration['cid'],
|
||||
'#options' => $options,
|
||||
);
|
||||
$form['block_count'] = array(
|
||||
'#type' => 'select',
|
||||
'#title' => t('Number of news items in block'),
|
||||
'#default_value' => $this->configuration['block_count'],
|
||||
'#options' => drupal_map_assoc(range(2, 20)),
|
||||
);
|
||||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* Overrides \Drupal\block\BlockBase::blockSubmit().
|
||||
*/
|
||||
public function blockSubmit($form, &$form_state) {
|
||||
$this->configuration['cid'] = $form_state['values']['cid'];
|
||||
$this->configuration['block_count'] = $form_state['values']['block_count'];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function build() {
|
||||
$cid = $this->configuration['cid'];
|
||||
if ($category = $this->categoryStorageController->load($cid)) {
|
||||
$result = $this->connection->queryRange('SELECT i.* FROM {aggregator_category_item} ci LEFT JOIN {aggregator_item} i ON ci.iid = i.iid WHERE ci.cid = :cid ORDER BY i.timestamp DESC, i.iid DESC', 0, $this->configuration['block_count'], array(':cid' => $category->cid));
|
||||
$more_link = array(
|
||||
'#theme' => 'more_link',
|
||||
'#url' => 'aggregator/categories/' . $category->cid,
|
||||
'#title' => t("View this category's recent news."),
|
||||
);
|
||||
$read_more = drupal_render($more_link);
|
||||
|
||||
$items = array();
|
||||
foreach ($result as $item) {
|
||||
$aggregator_block_item = array(
|
||||
'#theme' => 'aggregator_block_item',
|
||||
'#item' => $item,
|
||||
);
|
||||
$items[] = drupal_render($aggregator_block_item);
|
||||
}
|
||||
|
||||
// Only display the block if there are items to show.
|
||||
if (count($items) > 0) {
|
||||
$item_list = array(
|
||||
'#theme' => 'item_list',
|
||||
'#items' => $items,
|
||||
);
|
||||
return array(
|
||||
'#children' => drupal_render($item_list) . $read_more,
|
||||
);
|
||||
}
|
||||
return array();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -105,14 +105,6 @@ class DefaultProcessor extends AggregatorPluginSettingsBase implements Processor
|
|||
'#description' => t('Requires a correctly configured <a href="@cron">cron maintenance task</a>.', array('@cron' => url('admin/reports/status'))),
|
||||
);
|
||||
|
||||
$form['processors'][$info['id']]['aggregator_category_selector'] = array(
|
||||
'#type' => 'radios',
|
||||
'#title' => t('Select categories using'),
|
||||
'#default_value' => $this->configuration['source']['category_selector'],
|
||||
'#options' => array('checkboxes' => t('checkboxes'),
|
||||
'select' => t('multiple selector')),
|
||||
'#description' => t('For a small number of categories, checkboxes are easier to use, while a multiple selector works well with large numbers of categories.'),
|
||||
);
|
||||
$form['processors'][$info['id']]['aggregator_teaser_length'] = array(
|
||||
'#type' => 'select',
|
||||
'#title' => t('Length of trimmed description'),
|
||||
|
@ -130,7 +122,6 @@ class DefaultProcessor extends AggregatorPluginSettingsBase implements Processor
|
|||
$this->configuration['items']['expire'] = $form_state['values']['aggregator_clear'];
|
||||
$this->configuration['items']['teaser_length'] = $form_state['values']['aggregator_teaser_length'];
|
||||
$this->configuration['source']['list_max'] = $form_state['values']['aggregator_summary_items'];
|
||||
$this->configuration['source']['category_selector'] = $form_state['values']['aggregator_category_selector'];
|
||||
// @todo Refactor aggregator plugins to ConfigEntity so this is not needed.
|
||||
$this->setConfiguration($this->configuration);
|
||||
}
|
||||
|
|
|
@ -1,67 +0,0 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\aggregator\Plugin\views\argument\CategoryCid.
|
||||
*/
|
||||
|
||||
namespace Drupal\aggregator\Plugin\views\argument;
|
||||
|
||||
use Drupal\views\Plugin\views\argument\Numeric;
|
||||
use Drupal\Component\Annotation\PluginID;
|
||||
use Drupal\Component\Utility\String;
|
||||
use Drupal\Core\Database\Connection;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
|
||||
/**
|
||||
* Argument handler to accept an aggregator category id.
|
||||
*
|
||||
* @ingroup views_argument_handlers
|
||||
*
|
||||
* @PluginID("aggregator_category_cid")
|
||||
*/
|
||||
class CategoryCid extends Numeric {
|
||||
|
||||
/**
|
||||
* Database Service Object.
|
||||
*
|
||||
* @var \Drupal\Core\Database\Connection
|
||||
*/
|
||||
protected $database;
|
||||
|
||||
/**
|
||||
* Constructs a Drupal\Component\Plugin\PluginBase object.
|
||||
*
|
||||
* @param array $configuration
|
||||
* A configuration array containing information about the plugin instance.
|
||||
* @param string $plugin_id
|
||||
* The plugin_id for the plugin instance.
|
||||
* @param array $plugin_definition
|
||||
* The plugin implementation definition.
|
||||
* @param \Drupal\Core\Database\Connection $database
|
||||
* Database Service Object.
|
||||
*/
|
||||
public function __construct(array $configuration, $plugin_id, array $plugin_definition, Connection $database) {
|
||||
parent::__construct($configuration, $plugin_id, $plugin_definition);
|
||||
$this->database = $database;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function create(ContainerInterface $container, array $configuration, $plugin_id, array $plugin_definition) {
|
||||
return new static($configuration, $plugin_id, $plugin_definition, $container->get('database'));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
function titleQuery() {
|
||||
$titles = $this->database->query("SELECT title FROM {aggregator_category} where cid IN (:cid)", array(':cid' => $this->value))->fetchCol();
|
||||
|
||||
return array_map(function ($title) {
|
||||
return String::checkPlain($title);
|
||||
}, $titles);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,85 +0,0 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\aggregator\Plugin\views\field\Category.
|
||||
*/
|
||||
|
||||
namespace Drupal\aggregator\Plugin\views\field;
|
||||
|
||||
use Drupal\views\Plugin\views\display\DisplayPluginBase;
|
||||
use Drupal\views\Plugin\views\field\FieldPluginBase;
|
||||
use Drupal\views\ResultRow;
|
||||
use Drupal\views\ViewExecutable;
|
||||
use Drupal\Component\Annotation\PluginID;
|
||||
|
||||
/**
|
||||
* Defines a simple renderer that allows linking to an aggregator category.
|
||||
*
|
||||
* @ingroup views_field_handlers
|
||||
*
|
||||
* @PluginID("aggregator_category")
|
||||
*/
|
||||
class Category extends FieldPluginBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function init(ViewExecutable $view, DisplayPluginBase $display, array &$options = NULL) {
|
||||
parent::init($view, $display, $options);
|
||||
|
||||
$this->additional_fields['cid'] = 'cid';
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function defineOptions() {
|
||||
$options = parent::defineOptions();
|
||||
|
||||
$options['link_to_category'] = array('default' => FALSE);
|
||||
return $options;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function buildOptionsForm(&$form, &$form_state) {
|
||||
$form['link_to_category'] = array(
|
||||
'#title' => t('Link this field to its aggregator category page'),
|
||||
'#description' => t('This will override any other link you have set.'),
|
||||
'#type' => 'checkbox',
|
||||
'#default_value' => !empty($this->options['link_to_category']),
|
||||
);
|
||||
parent::buildOptionsForm($form, $form_state);
|
||||
}
|
||||
|
||||
/**
|
||||
* Render whatever the data is as a link to the category.
|
||||
*
|
||||
* @param string $data
|
||||
* The XSS safe string for the link text.
|
||||
* @param \Drupal\views\ResultRow $values
|
||||
* The values retrieved from a single row of a view's query result.
|
||||
*
|
||||
* @return string
|
||||
* Returns a string for the link text.
|
||||
*/
|
||||
protected function renderLink($data, ResultRow $values) {
|
||||
$cid = $this->getValue($values, 'cid');
|
||||
if (!empty($this->options['link_to_category']) && !empty($cid) && $data !== NULL && $data !== '') {
|
||||
$this->options['alter']['make_link'] = TRUE;
|
||||
$this->options['alter']['path'] = "aggregator/categories/$cid";
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function render(ResultRow $values) {
|
||||
$value = $this->getValue($values);
|
||||
return $this->renderLink($this->sanitizeValue($value), $values);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,65 +0,0 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\aggregator\Plugin\views\filter\CategoryCid.
|
||||
*/
|
||||
|
||||
namespace Drupal\aggregator\Plugin\views\filter;
|
||||
|
||||
use Drupal\views\Plugin\views\filter\InOperator;
|
||||
use Drupal\Component\Annotation\PluginID;
|
||||
|
||||
/**
|
||||
* Defines a filter handler that filters by aggregator category cid.
|
||||
*
|
||||
* @ingroup views_filter_handlers
|
||||
*
|
||||
* @PluginID("aggregator_category_cid")
|
||||
*/
|
||||
class CategoryCid extends InOperator {
|
||||
|
||||
/**
|
||||
* Database Service Object.
|
||||
*
|
||||
* @var \Drupal\Core\Database\Connection
|
||||
*/
|
||||
protected $database;
|
||||
|
||||
/**
|
||||
* Constructs a Drupal\Component\Plugin\PluginBase object.
|
||||
*
|
||||
* @param array $configuration
|
||||
* A configuration array containing information about the plugin instance.
|
||||
* @param string $plugin_id
|
||||
* The plugin_id for the plugin instance.
|
||||
* @param array $plugin_definition
|
||||
* The plugin implementation definition.
|
||||
* @param \Drupal\Core\Database\Connection $database
|
||||
* Database Service Object.
|
||||
*/
|
||||
public function __construct(array $configuration, $plugin_id, array $plugin_definition, Connection $database) {
|
||||
parent::__construct($configuration, $plugin_id, $plugin_definition);
|
||||
$this->database = $database;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function create(ContainerInterface $container, array $configuration, $plugin_id, array $plugin_definition) {
|
||||
return new static($configuration, $plugin_id, $plugin_definition, $container->get('database'));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
function getValueOptions() {
|
||||
if (isset($this->value_options)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->value_options = array();
|
||||
$this->value_options = $this->database->query('SELECT cid, title FROM {aggregator_category} ORDER BY title')->fetchAllKeyed();
|
||||
}
|
||||
|
||||
}
|
|
@ -33,8 +33,6 @@ class AddFeedTest extends AggregatorTestBase {
|
|||
$this->drupalGet('aggregator/sources/' . $feed->id());
|
||||
$this->assertResponse(200, 'Feed source exists.');
|
||||
$this->assertText($feed->label(), 'Page title');
|
||||
$this->drupalGet('aggregator/sources/' . $feed->id() . '/categorize');
|
||||
$this->assertResponse(200, 'Feed categorization page exists.');
|
||||
$this->assertText($feed->label());
|
||||
|
||||
// Delete feed.
|
||||
|
@ -62,8 +60,6 @@ class AddFeedTest extends AggregatorTestBase {
|
|||
$this->drupalGet('aggregator/sources/' . $feed->id());
|
||||
$this->assertResponse(200, 'Long URL feed source exists.');
|
||||
$this->assertText($feed->label(), 'Page title');
|
||||
$this->drupalGet('aggregator/sources/' . $feed->id() . '/categorize');
|
||||
$this->assertResponse(200, 'Long URL feed categorization page exists.');
|
||||
$this->assertText($feed->label());
|
||||
|
||||
// Delete feeds.
|
||||
|
|
|
@ -34,7 +34,6 @@ class AggregatorConfigurationTest extends AggregatorTestBase {
|
|||
'aggregator_allowed_html_tags' => '<a>',
|
||||
'aggregator_summary_items' => 10,
|
||||
'aggregator_clear' => 3600,
|
||||
'aggregator_category_selector' => 'select',
|
||||
'aggregator_teaser_length' => 200,
|
||||
'aggregator_fetcher' => 'aggregator_test_fetcher',
|
||||
'aggregator_parser' => 'aggregator_test_parser',
|
||||
|
|
|
@ -31,8 +31,6 @@ class AggregatorRenderingTest extends AggregatorTestBase {
|
|||
|
||||
/**
|
||||
* Adds a feed block to the page and checks its links.
|
||||
*
|
||||
* @todo Test the category block as well.
|
||||
*/
|
||||
public function testBlockLinks() {
|
||||
// Create feed.
|
||||
|
|
|
@ -206,37 +206,6 @@ abstract class AggregatorTestBase extends WebTestBase {
|
|||
$this->assertTrue($count == 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Pulls feed categories from {aggregator_category_feed} table.
|
||||
*
|
||||
* @param \Drupal\aggregator\Entity\Feed $feed
|
||||
* Feed object representing the feed.
|
||||
*/
|
||||
function getFeedCategories(Feed $feed) {
|
||||
// add the categories to the feed so we can use them
|
||||
$result = db_query('SELECT cid FROM {aggregator_category_feed} WHERE fid = :fid', array(':fid' => $feed->id()));
|
||||
|
||||
foreach ($result as $category) {
|
||||
$feed->categories[] = $category->cid;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Pulls categories from {aggregator_category} table.
|
||||
*
|
||||
* @return array
|
||||
* An associative array keyed by category ID and values are set to the
|
||||
* category names.
|
||||
*/
|
||||
function getCategories() {
|
||||
$categories = array();
|
||||
$result = db_query('SELECT * FROM {aggregator_category}');
|
||||
foreach ($result as $category) {
|
||||
$categories[$category->cid] = $category;
|
||||
}
|
||||
return $categories;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the feed name and URL are unique.
|
||||
*
|
||||
|
|
|
@ -1,93 +0,0 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Definition of Drupal\aggregator\Tests\CategorizeFeedItemTest.
|
||||
*/
|
||||
|
||||
namespace Drupal\aggregator\Tests;
|
||||
|
||||
/**
|
||||
* Tests categorization functionality in the Aggregator module.
|
||||
*/
|
||||
class CategorizeFeedItemTest extends AggregatorTestBase {
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = array('block');
|
||||
|
||||
public static function getInfo() {
|
||||
return array(
|
||||
'name' => 'Categorize feed item functionality',
|
||||
'description' => 'Test feed item categorization.',
|
||||
'group' => 'Aggregator'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks that children of a feed inherit a defined category.
|
||||
*
|
||||
* If a feed has a category, make sure that the children inherit that
|
||||
* categorization.
|
||||
*/
|
||||
function testCategorizeFeedItem() {
|
||||
$this->createSampleNodes();
|
||||
|
||||
// Simulate form submission on "admin/config/services/aggregator/add/category".
|
||||
$edit = array('title' => $this->randomName(10), 'description' => '');
|
||||
$this->drupalPostForm('admin/config/services/aggregator/add/category', $edit, t('Save'));
|
||||
$this->assertRaw(t('The category %title has been added.', array('%title' => $edit['title'])), format_string('The category %title has been added.', array('%title' => $edit['title'])));
|
||||
|
||||
$category = db_query("SELECT * FROM {aggregator_category} WHERE title = :title", array(':title' => $edit['title']))->fetch();
|
||||
$this->assertTrue(!empty($category), 'The category found in database.');
|
||||
|
||||
$link_path = 'aggregator/categories/' . $category->cid;
|
||||
$menu_links = entity_load_multiple_by_properties('menu_link', array('link_path' => $link_path));
|
||||
$this->assertTrue(!empty($menu_links), 'The menu link associated with the category found in database.');
|
||||
|
||||
$feed = $this->createFeed();
|
||||
db_insert('aggregator_category_feed')
|
||||
->fields(array(
|
||||
'cid' => $category->cid,
|
||||
'fid' => $feed->id(),
|
||||
))
|
||||
->execute();
|
||||
|
||||
$this->updateFeedItems($feed, $this->getDefaultFeedItemCount());
|
||||
$this->getFeedCategories($feed);
|
||||
$this->assertTrue(!empty($feed->categories), 'The category found in the feed.');
|
||||
|
||||
// For each category of a feed, ensure feed items have that category, too.
|
||||
if (!empty($feed->categories) && !empty($feed->items)) {
|
||||
foreach ($feed->categories as $cid) {
|
||||
$categorized_count = db_select('aggregator_category_item')
|
||||
->condition('iid', $feed->items, 'IN')
|
||||
->countQuery()
|
||||
->execute()
|
||||
->fetchField();
|
||||
|
||||
$this->assertEqual($feed->item_count, $categorized_count, 'Total items in feed equal to the total categorized feed items in database');
|
||||
}
|
||||
}
|
||||
|
||||
// Place a category block.
|
||||
$block = $this->drupalPlaceBlock("aggregator_category_block", array('label' => 'category-' . $category->title));
|
||||
|
||||
// Configure the feed that should be displayed.
|
||||
$block->getPlugin()->setConfigurationValue('cid', $category->cid);
|
||||
$block->save();
|
||||
|
||||
// Visit the frontpage, assert that the block and the feeds are displayed.
|
||||
$this->drupalGet('');
|
||||
$this->assertText('category-' . $category->title);
|
||||
foreach (\Drupal::entityManager()->getStorageController('aggregator_item')->loadMultiple() as $item) {
|
||||
$this->assertText($item->label());
|
||||
}
|
||||
|
||||
// Delete feed.
|
||||
$this->deleteFeed($feed);
|
||||
}
|
||||
}
|
|
@ -1,57 +0,0 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Definition of Drupal\aggregator\Tests\CategorizeFeedTest.
|
||||
*/
|
||||
|
||||
namespace Drupal\aggregator\Tests;
|
||||
|
||||
/**
|
||||
* Tests the categorize feed functionality in the Aggregator module.
|
||||
*/
|
||||
class CategorizeFeedTest extends AggregatorTestBase {
|
||||
public static function getInfo() {
|
||||
return array(
|
||||
'name' => 'Categorize feed functionality',
|
||||
'description' => 'Categorize feed test.',
|
||||
'group' => 'Aggregator'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a feed and makes sure you can add more than one category to it.
|
||||
*/
|
||||
function testCategorizeFeed() {
|
||||
|
||||
// Create 2 categories.
|
||||
$category_1 = array('title' => $this->randomName(10), 'description' => '');
|
||||
$this->drupalPostForm('admin/config/services/aggregator/add/category', $category_1, t('Save'));
|
||||
$this->assertRaw(t('The category %title has been added.', array('%title' => $category_1['title'])), format_string('The category %title has been added.', array('%title' => $category_1['title'])));
|
||||
|
||||
$category_2 = array('title' => $this->randomName(10), 'description' => '');
|
||||
$this->drupalPostForm('admin/config/services/aggregator/add/category', $category_2, t('Save'));
|
||||
$this->assertRaw(t('The category %title has been added.', array('%title' => $category_2['title'])), format_string('The category %title has been added.', array('%title' => $category_2['title'])));
|
||||
|
||||
// Get categories from database.
|
||||
$categories = $this->getCategories();
|
||||
|
||||
// Create a feed and assign 2 categories to it.
|
||||
$feed = $this->getFeedEditObject();
|
||||
foreach ($categories as $cid => $category) {
|
||||
$feed->categories[$cid] = $cid;
|
||||
}
|
||||
|
||||
$feed->save();
|
||||
$db_fid = db_query("SELECT fid FROM {aggregator_feed} WHERE title = :title AND url = :url", array(':title' => $feed->label(), ':url' => $feed->url->value))->fetchField();
|
||||
|
||||
$db_feed = aggregator_feed_load($db_fid);
|
||||
// Assert the feed has two categories.
|
||||
$this->assertEqual(count($db_feed->categories), 2, 'Feed has 2 categories');
|
||||
|
||||
// Verify the categories overview page is correctly displayed.
|
||||
$this->drupalGet('aggregator/categories');
|
||||
$this->assertText($category_1['title']);
|
||||
$this->assertText($category_2['title']);
|
||||
}
|
||||
}
|
|
@ -38,16 +38,6 @@ class ImportOpmlTest extends AggregatorTestBase {
|
|||
* Opens OPML import form.
|
||||
*/
|
||||
function openImportForm() {
|
||||
db_delete('aggregator_category')->execute();
|
||||
|
||||
$category = $this->randomName(10);
|
||||
$cid = db_insert('aggregator_category')
|
||||
->fields(array(
|
||||
'title' => $category,
|
||||
'description' => '',
|
||||
))
|
||||
->execute();
|
||||
|
||||
// Enable the help block.
|
||||
$this->drupalPlaceBlock('system_help_block', array('region' => 'help'));
|
||||
|
||||
|
@ -56,7 +46,6 @@ class ImportOpmlTest extends AggregatorTestBase {
|
|||
$this->assertField('files[upload]', 'Found file upload field.');
|
||||
$this->assertField('remote', 'Found Remote URL field.');
|
||||
$this->assertField('refresh', '', 'Found Refresh field.');
|
||||
$this->assertFieldByName("category[$cid]", $cid, 'Found category field.');
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -103,17 +92,6 @@ class ImportOpmlTest extends AggregatorTestBase {
|
|||
$this->assertEqual($before, $after, 'No feeds were added during the two last form submissions.');
|
||||
|
||||
db_delete('aggregator_feed')->execute();
|
||||
db_delete('aggregator_category')->execute();
|
||||
db_delete('aggregator_category_feed')->execute();
|
||||
|
||||
$category = $this->randomName(10);
|
||||
db_insert('aggregator_category')
|
||||
->fields(array(
|
||||
'cid' => 1,
|
||||
'title' => $category,
|
||||
'description' => '',
|
||||
))
|
||||
->execute();
|
||||
|
||||
$feeds[0] = $this->getFeedEditArray();
|
||||
$feeds[1] = $this->getFeedEditArray();
|
||||
|
@ -121,7 +99,6 @@ class ImportOpmlTest extends AggregatorTestBase {
|
|||
$edit = array(
|
||||
'files[upload]' => $this->getValidOpml($feeds),
|
||||
'refresh' => '900',
|
||||
'category[1]' => $category,
|
||||
);
|
||||
$this->drupalPostForm('admin/config/services/aggregator/add/opml', $edit, t('Import'));
|
||||
$this->assertRaw(t('A feed with the URL %url already exists.', array('%url' => $feeds[0]['url'])), 'Verifying that a duplicate URL was identified');
|
||||
|
@ -130,19 +107,17 @@ class ImportOpmlTest extends AggregatorTestBase {
|
|||
$after = db_query('SELECT COUNT(*) FROM {aggregator_feed}')->fetchField();
|
||||
$this->assertEqual($after, 2, 'Verifying that two distinct feeds were added.');
|
||||
|
||||
$feeds_from_db = db_query("SELECT f.title, f.url, f.refresh, cf.cid FROM {aggregator_feed} f LEFT JOIN {aggregator_category_feed} cf ON f.fid = cf.fid");
|
||||
$refresh = $category = TRUE;
|
||||
$feeds_from_db = db_query("SELECT title, url, refresh FROM {aggregator_feed}");
|
||||
$refresh = TRUE;
|
||||
foreach ($feeds_from_db as $feed) {
|
||||
$title[$feed->url] = $feed->title;
|
||||
$url[$feed->title] = $feed->url;
|
||||
$category = $category && $feed->cid == 1;
|
||||
$refresh = $refresh && $feed->refresh == 900;
|
||||
}
|
||||
|
||||
$this->assertEqual($title[$feeds[0]['url']], $feeds[0]['title'], 'First feed was added correctly.');
|
||||
$this->assertEqual($url[$feeds[1]['title']], $feeds[1]['url'], 'Second feed was added correctly.');
|
||||
$this->assertTrue($refresh, 'Refresh times are correct.');
|
||||
$this->assertTrue($category, 'Categories are correct.');
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -54,7 +54,7 @@ class IntegrationTest extends ViewUnitTestBase {
|
|||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
$this->installSchema('aggregator', array('aggregator_item', 'aggregator_feed', 'aggregator_category_feed', 'aggregator_category', 'aggregator_category_item'));
|
||||
$this->installSchema('aggregator', array('aggregator_item', 'aggregator_feed'));
|
||||
|
||||
ViewTestData::createTestViews(get_class($this), array('aggregator_test_views'));
|
||||
|
||||
|
|
|
@ -10,7 +10,6 @@
|
|||
* - source_title: Title of the remote source.
|
||||
* - source_date: Date the feed was posted on the remote source.
|
||||
* - content: Feed item content.
|
||||
* - categories: Linked categories assigned to the feed.
|
||||
*
|
||||
* @see template_preprocess_aggregator_item()
|
||||
*
|
||||
|
@ -34,10 +33,4 @@
|
|||
{{ content }}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if categories %}
|
||||
<div class="feed-item-categories">
|
||||
{{ 'Categories'|t }}: {{ categories|join(', ') }}
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
|
|
@ -3,13 +3,13 @@
|
|||
* @file
|
||||
* Default theme implementation to present feeds as list items.
|
||||
*
|
||||
* Each iteration generates a single feed source or category.
|
||||
* Each iteration generates a single feed source.
|
||||
*
|
||||
* Available variables:
|
||||
* - title: Title of the feed or category.
|
||||
* - title: Title of the feed.
|
||||
* - summary_list: Unordered list of linked feed items generated through
|
||||
* theme_item_list().
|
||||
* - source_url: URL to the local source or category.
|
||||
* - source_url: URL to the local source.
|
||||
*
|
||||
* @see template_preprocess_aggregator_summary_items()
|
||||
*
|
||||
|
|
|
@ -51,29 +51,6 @@ class AggregatorLocalTasksTest extends LocalTaskIntegrationTest {
|
|||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks aggregator category tasks.
|
||||
*
|
||||
* @dataProvider getAggregatorCategoryRoutes
|
||||
*/
|
||||
public function testAggregatorCategoryLocalTasks($route) {
|
||||
$this->assertLocalTasks($route, array(
|
||||
0 => array('aggregator.category_view', 'aggregator.categorize_category_form', 'aggregator.category_edit'),
|
||||
));
|
||||
;
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides a list of category routes to test.
|
||||
*/
|
||||
public function getAggregatorCategoryRoutes() {
|
||||
return array(
|
||||
array('aggregator.category_view'),
|
||||
array('aggregator.categorize_category_form'),
|
||||
array('aggregator.category_edit'),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks aggregator source tasks.
|
||||
*
|
||||
|
@ -81,7 +58,7 @@ class AggregatorLocalTasksTest extends LocalTaskIntegrationTest {
|
|||
*/
|
||||
public function testAggregatorSourceLocalTasks($route) {
|
||||
$this->assertLocalTasks($route, array(
|
||||
0 => array('aggregator.feed_view', 'aggregator.categorize_feed_form', 'aggregator.feed_configure'),
|
||||
0 => array('aggregator.feed_view', 'aggregator.feed_configure'),
|
||||
));
|
||||
;
|
||||
}
|
||||
|
@ -92,7 +69,6 @@ class AggregatorLocalTasksTest extends LocalTaskIntegrationTest {
|
|||
public function getAggregatorSourceRoutes() {
|
||||
return array(
|
||||
array('aggregator.feed_view'),
|
||||
array('aggregator.categorize_feed_form'),
|
||||
array('aggregator.feed_configure'),
|
||||
);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue