diff --git a/core/modules/aggregator/aggregator.admin.inc b/core/modules/aggregator/aggregator.admin.inc index bdf142e..37aefb4 100644 --- a/core/modules/aggregator/aggregator.admin.inc +++ b/core/modules/aggregator/aggregator.admin.inc @@ -108,133 +108,6 @@ function aggregator_feed_add() { } /** - * Form constructor for importing feeds from OPML. - * - * @ingroup forms - * @see aggregator_menu() - * @see aggregator_form_opml_validate() - * @see aggregator_form_opml_submit() - */ -function aggregator_form_opml($form, &$form_state) { - $period = drupal_map_assoc(array(900, 1800, 3600, 7200, 10800, 21600, 32400, 43200, 64800, 86400, 172800, 259200, 604800, 1209600, 2419200), 'format_interval'); - - $form['upload'] = array( - '#type' => 'file', - '#title' => t('OPML File'), - '#description' => t('Upload an OPML file containing a list of feeds to be imported.'), - ); - $form['remote'] = array( - '#type' => 'url', - '#title' => t('OPML Remote URL'), - '#maxlength' => 1024, - '#description' => t('Enter the URL of an OPML file. This file will be downloaded and processed only once on submission of the form.'), - ); - $form['refresh'] = array( - '#type' => 'select', - '#title' => t('Update interval'), - '#default_value' => 3600, - '#options' => $period, - '#description' => t('The length of time between feed updates. Requires a correctly configured cron maintenance task.', array('@cron' => url('admin/reports/status'))), - ); - $form['block'] = array('#type' => 'select', - '#title' => t('News items in block'), - '#default_value' => 5, - '#options' => drupal_map_assoc(array(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20)), - '#description' => t("Drupal can make a block with the most recent news items of a feed. You can configure blocks to be displayed in the sidebar of your page. This setting lets you configure the number of news items to show in a feed's block. If you choose '0' these feeds' blocks will be disabled.", array('@block-admin' => url('admin/structure/block'))), - ); - - // Handling of categories. - $options = array_map('check_plain', db_query("SELECT cid, title FROM {aggregator_category} ORDER BY title")->fetchAllKeyed()); - if ($options) { - $form['category'] = array( - '#type' => 'checkboxes', - '#title' => t('Categorize news items'), - '#options' => $options, - '#description' => t('New feed items are automatically filed in the checked categories.'), - ); - } - $form['actions'] = array('#type' => 'actions'); - $form['actions']['submit'] = array( - '#type' => 'submit', - '#value' => t('Import') - ); - - return $form; -} - -/** - * Form validation handler for aggregator_form_opml(). - * - * @see aggregator_form_opml_submit() - */ -function aggregator_form_opml_validate($form, &$form_state) { - // If both fields are empty or filled, cancel. - if (empty($form_state['values']['remote']) == empty($_FILES['files']['name']['upload'])) { - form_set_error('remote', t('You must either upload a file or enter a URL.')); - } -} - -/** - * Form submission handler for aggregator_form_opml(). - * - * @see aggregator_form_opml_validate() - */ -function aggregator_form_opml_submit($form, &$form_state) { - $data = ''; - $validators = array('file_validate_extensions' => array('opml xml')); - if ($file = file_save_upload('upload', $validators)) { - $data = file_get_contents($file->uri); - } - else { - $response = drupal_http_request($form_state['values']['remote']); - if (!isset($response->error)) { - $data = $response->data; - } - else { - watchdog('aggregator', 'HTTP request to @url failed with error: @error', array('@url' => $form_state['values']['remote'], '@error' => $response->error)); - } - } - - $feeds = _aggregator_parse_opml($data); - if (empty($feeds)) { - drupal_set_message(t('No new feed has been added.')); - return; - } - - foreach ($feeds as $feed) { - // Ensure URL is valid. - if (!valid_url($feed['url'], TRUE)) { - drupal_set_message(t('The URL %url is invalid.', array('%url' => $feed['url'])), 'warning'); - continue; - } - - // Check for duplicate titles or URLs. - $result = db_query("SELECT title, url FROM {aggregator_feed} WHERE title = :title OR url = :url", array(':title' => $feed['title'], ':url' => $feed['url'])); - foreach ($result as $old) { - if (strcasecmp($old->title, $feed['title']) == 0) { - drupal_set_message(t('A feed named %title already exists.', array('%title' => $old->title)), 'warning'); - continue 2; - } - if (strcasecmp($old->url, $feed['url']) == 0) { - drupal_set_message(t('A feed with the URL %url already exists.', array('%url' => $old->url)), 'warning'); - continue 2; - } - } - - $new_feed = entity_create('aggregator_feed', array( - 'title' => $feed['title'], - 'url' => $feed['url'], - 'refresh' => $form_state['values']['refresh'], - 'block' => $form_state['values']['block'], - )); - $new_feed->categories = $form_state['values']['category']; - $new_feed->save(); - } - - $form_state['redirect'] = 'admin/config/services/aggregator'; -} - -/** * Parses an OPML file. * * Feeds are recognized as elements with the attributes "text" and diff --git a/core/modules/aggregator/aggregator.module b/core/modules/aggregator/aggregator.module index 525cdc1..30f7197 100644 --- a/core/modules/aggregator/aggregator.module +++ b/core/modules/aggregator/aggregator.module @@ -114,11 +114,8 @@ function aggregator_menu() { ); $items['admin/config/services/aggregator/add/opml'] = array( 'title' => 'Import OPML', - 'page callback' => 'drupal_get_form', - 'page arguments' => array('aggregator_form_opml'), - 'access arguments' => array('administer news feeds'), 'type' => MENU_LOCAL_ACTION, - 'file' => 'aggregator.admin.inc', + 'route_name' => 'aggregator_opml_add', ); $items['admin/config/services/aggregator/remove/%aggregator_feed'] = array( 'title' => 'Remove items', diff --git a/core/modules/aggregator/aggregator.routing.yml b/core/modules/aggregator/aggregator.routing.yml index fbb0caf..b3a903e 100644 --- a/core/modules/aggregator/aggregator.routing.yml +++ b/core/modules/aggregator/aggregator.routing.yml @@ -10,3 +10,10 @@ aggregator_feed_items_delete: _form: '\Drupal\aggregator\Form\FeedItemsDelete' requirements: _permission: 'administer news feeds' + +aggregator_opml_add: + pattern: '/admin/config/services/aggregator/add/opml' + defaults: + _form: '\Drupal\aggregator\Form\OpmlFeedAdd' + requirements: + _permission: 'administer news feeds' diff --git a/core/modules/aggregator/lib/Drupal/aggregator/Form/OpmlFeedAdd.php b/core/modules/aggregator/lib/Drupal/aggregator/Form/OpmlFeedAdd.php new file mode 100644 index 0000000..67d7a49 --- /dev/null +++ b/core/modules/aggregator/lib/Drupal/aggregator/Form/OpmlFeedAdd.php @@ -0,0 +1,174 @@ +get('database')); + } + + /** + * Constructs a database object. + * + * @param \Drupal\Core\Database\Connection; $database + * The database object. + */ + public function __construct(Connection $database) { + $this->database = $database; + } + + /** + * {@inheritdoc} + */ + public function getFormID() { + return 'aggregator_opml_add'; + } + + /** + * {@inheritdoc} + */ + public function buildForm(array $form, array &$form_state) { + $period = drupal_map_assoc(array(900, 1800, 3600, 7200, 10800, 21600, 32400, 43200, + 64800, 86400, 172800, 259200, 604800, 1209600, 2419200), 'format_interval'); + + $form['upload'] = array( + '#type' => 'file', + '#title' => t('OPML File'), + '#description' => t('Upload an OPML file containing a list of feeds to be imported.'), + ); + $form['remote'] = array( + '#type' => 'url', + '#title' => t('OPML Remote URL'), + '#maxlength' => 1024, + '#description' => t('Enter the URL of an OPML file. This file will be downloaded and processed only once on submission of the form.'), + ); + $form['refresh'] = array( + '#type' => 'select', + '#title' => t('Update interval'), + '#default_value' => 3600, + '#options' => $period, + '#description' => t('The length of time between feed updates. Requires a correctly configured cron maintenance task.', array('@cron' => url('admin/reports/status'))), + ); + $form['block'] = array( + '#type' => 'select', + '#title' => t('News items in block'), + '#default_value' => 5, + '#options' => drupal_map_assoc(array(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20)), + '#description' => t("Drupal can make a block with the most recent news items of a feed. You can configure blocks to be displayed in the sidebar of your page. This setting lets you configure the number of news items to show in a feed's block. If you choose '0' these feeds' blocks will be disabled.", array('@block-admin' => url('admin/structure/block'))), + ); + + // Handling of categories. + $options = array_map('check_plain', $this->database->query("SELECT cid, title FROM {aggregator_category} ORDER BY title")->fetchAllKeyed()); + if ($options) { + $form['category'] = array( + '#type' => 'checkboxes', + '#title' => t('Categorize news items'), + '#options' => $options, + '#description' => t('New feed items are automatically filed in the checked categories.'), + ); + } + $form['actions'] = array('#type' => 'actions'); + $form['actions']['submit'] = array( + '#type' => 'submit', + '#value' => t('Import'), + ); + + return $form; + } + + /** + * {@inheritdoc} + */ + public function validateForm(array &$form, array &$form_state) { + // If both fields are empty or filled, cancel. + if (empty($form_state['values']['remote']) == empty($_FILES['files']['name']['upload'])) { + form_set_error('remote', t('You must either upload a file or enter a URL.')); + } + } + + /** + * {@inheritdoc} + */ + public function submitForm(array &$form, array &$form_state) { + $data = ''; + $validators = array('file_validate_extensions' => array('opml xml')); + if ($file = file_save_upload('upload', $validators)) { + $data = file_get_contents($file->uri); + } + else { + $response = drupal_http_request($form_state['values']['remote']); + if (!isset($response->error)) { + $data = $response->data; + } + else { + watchdog('aggregator', 'HTTP request to @url failed with error: @error', array('@url' => $form_state['values']['remote'], '@error' => $response->error)); + } + } + + $feeds = _aggregator_parse_opml($data); + if (empty($feeds)) { + drupal_set_message(t('No new feed has been added.')); + return; + } + + foreach ($feeds as $feed) { + // Ensure URL is valid. + if (!valid_url($feed['url'], TRUE)) { + drupal_set_message(t('The URL %url is invalid.', array('%url' => $feed['url'])), 'warning'); + continue; + } + + // Check for duplicate titles or URLs. + $result = $this->database->query("SELECT title, url FROM {aggregator_feed} WHERE title = :title OR url = :url", array(':title' => $feed['title'], ':url' => $feed['url'])); + foreach ($result as $old) { + if (strcasecmp($old->title, $feed['title']) == 0) { + drupal_set_message(t('A feed named %title already exists.', array('%title' => $old->title)), 'warning'); + continue 2; + } + if (strcasecmp($old->url, $feed['url']) == 0) { + drupal_set_message(t('A feed with the URL %url already exists.', array('%url' => $old->url)), 'warning'); + continue 2; + } + } + + $new_feed = drupal_container()->get('plugin.manager.entity') + ->getStorageController('aggregator_feed') + ->create(array( + 'title' => $feed['title'], + 'url' => $feed['url'], + 'refresh' => $form_state['values']['refresh'], + 'block' => $form_state['values']['block'], + )); + $new_feed->categories = $form_state['values']['category']; + $new_feed->save(); + } + + $form_state['redirect'] = 'admin/config/services/aggregator'; + } +}