[b354002] | 1 | <?php |
---|
| 2 | |
---|
| 3 | /** |
---|
| 4 | * @file |
---|
| 5 | * Admin page callbacks for the aggregator module. |
---|
| 6 | */ |
---|
| 7 | |
---|
| 8 | /** |
---|
| 9 | * Menu callback; displays the aggregator administration page. |
---|
| 10 | */ |
---|
| 11 | function aggregator_admin_overview() { |
---|
| 12 | return aggregator_view(); |
---|
| 13 | } |
---|
| 14 | |
---|
| 15 | /** |
---|
| 16 | * Displays the aggregator administration page. |
---|
| 17 | * |
---|
| 18 | * @return |
---|
| 19 | * The page HTML. |
---|
| 20 | */ |
---|
| 21 | function aggregator_view() { |
---|
| 22 | $result = db_query('SELECT f.*, COUNT(i.iid) AS items FROM {aggregator_feed} f LEFT JOIN {aggregator_item} i ON f.fid = i.fid GROUP BY f.fid, f.title, f.url, f.refresh, f.checked, f.link, f.description, f.etag, f.modified, f.image, f.block ORDER BY f.title'); |
---|
| 23 | |
---|
| 24 | $output = '<h3>'. t('Feed overview') .'</h3>'; |
---|
| 25 | |
---|
| 26 | $header = array(t('Title'), t('Items'), t('Last update'), t('Next update'), array('data' => t('Operations'), 'colspan' => '3')); |
---|
| 27 | $rows = array(); |
---|
| 28 | while ($feed = db_fetch_object($result)) { |
---|
[d7a822e] | 29 | $rows[] = array( |
---|
| 30 | l($feed->title, "aggregator/sources/$feed->fid"), |
---|
| 31 | format_plural($feed->items, '1 item', '@count items'), |
---|
| 32 | ($feed->checked ? t('@time ago', array('@time' => format_interval(time() - $feed->checked))) : t('never')), |
---|
| 33 | ($feed->checked ? t('%time left', array('%time' => format_interval($feed->checked + $feed->refresh - time()))) : t('never')), |
---|
| 34 | l(t('edit'), "admin/content/aggregator/edit/feed/$feed->fid"), |
---|
| 35 | l(t('remove items'), "admin/content/aggregator/remove/$feed->fid"), |
---|
| 36 | l(t('update items'), "admin/content/aggregator/update/$feed->fid", array('query' => array('token' => drupal_get_token("aggregator/update/$feed->fid")))), |
---|
| 37 | ); |
---|
[b354002] | 38 | } |
---|
| 39 | $output .= theme('table', $header, $rows); |
---|
| 40 | |
---|
| 41 | $result = db_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'); |
---|
| 42 | |
---|
| 43 | $output .= '<h3>'. t('Category overview') .'</h3>'; |
---|
| 44 | |
---|
| 45 | $header = array(t('Title'), t('Items'), t('Operations')); |
---|
| 46 | $rows = array(); |
---|
| 47 | while ($category = db_fetch_object($result)) { |
---|
| 48 | $rows[] = array(l($category->title, "aggregator/categories/$category->cid"), format_plural($category->items, '1 item', '@count items'), l(t('edit'), "admin/content/aggregator/edit/category/$category->cid")); |
---|
| 49 | } |
---|
| 50 | $output .= theme('table', $header, $rows); |
---|
| 51 | |
---|
| 52 | return $output; |
---|
| 53 | } |
---|
| 54 | |
---|
| 55 | /** |
---|
| 56 | * Form builder; Generate a form to add/edit feed sources. |
---|
| 57 | * |
---|
| 58 | * @ingroup forms |
---|
| 59 | * @see aggregator_form_feed_validate() |
---|
| 60 | * @see aggregator_form_feed_submit() |
---|
| 61 | */ |
---|
| 62 | function aggregator_form_feed(&$form_state, $edit = array('refresh' => 900, 'title' => '', 'url' => '', 'fid' => NULL)) { |
---|
| 63 | $period = drupal_map_assoc(array(900, 1800, 3600, 7200, 10800, 21600, 32400, 43200, 64800, 86400, 172800, 259200, 604800, 1209600, 2419200), 'format_interval'); |
---|
| 64 | |
---|
| 65 | if ($edit['refresh'] == '') { |
---|
| 66 | $edit['refresh'] = 3600; |
---|
| 67 | } |
---|
| 68 | |
---|
| 69 | $form['title'] = array('#type' => 'textfield', |
---|
| 70 | '#title' => t('Title'), |
---|
| 71 | '#default_value' => $edit['title'], |
---|
| 72 | '#maxlength' => 255, |
---|
| 73 | '#description' => t('The name of the feed (or the name of the website providing the feed).'), |
---|
| 74 | '#required' => TRUE, |
---|
| 75 | ); |
---|
| 76 | $form['url'] = array('#type' => 'textfield', |
---|
| 77 | '#title' => t('URL'), |
---|
| 78 | '#default_value' => $edit['url'], |
---|
| 79 | '#maxlength' => 255, |
---|
| 80 | '#description' => t('The fully-qualified URL of the feed.'), |
---|
| 81 | '#required' => TRUE, |
---|
| 82 | ); |
---|
| 83 | $form['refresh'] = array('#type' => 'select', |
---|
| 84 | '#title' => t('Update interval'), |
---|
| 85 | '#default_value' => $edit['refresh'], |
---|
| 86 | '#options' => $period, |
---|
| 87 | '#description' => 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'))), |
---|
| 88 | ); |
---|
| 89 | |
---|
| 90 | // Handling of categories: |
---|
| 91 | $options = array(); |
---|
| 92 | $values = array(); |
---|
| 93 | $categories = db_query('SELECT c.cid, c.title, f.fid FROM {aggregator_category} c LEFT JOIN {aggregator_category_feed} f ON c.cid = f.cid AND f.fid = %d ORDER BY title', $edit['fid']); |
---|
| 94 | while ($category = db_fetch_object($categories)) { |
---|
| 95 | $options[$category->cid] = check_plain($category->title); |
---|
| 96 | if ($category->fid) $values[] = $category->cid; |
---|
| 97 | } |
---|
| 98 | if ($options) { |
---|
| 99 | $form['category'] = array('#type' => 'checkboxes', |
---|
| 100 | '#title' => t('Categorize news items'), |
---|
| 101 | '#default_value' => $values, |
---|
| 102 | '#options' => $options, |
---|
| 103 | '#description' => t('New feed items are automatically filed in the checked categories.'), |
---|
| 104 | ); |
---|
| 105 | } |
---|
| 106 | $form['submit'] = array('#type' => 'submit', '#value' => t('Save')); |
---|
| 107 | |
---|
| 108 | if ($edit['fid']) { |
---|
| 109 | $form['delete'] = array('#type' => 'submit', '#value' => t('Delete')); |
---|
| 110 | $form['fid'] = array('#type' => 'hidden', '#value' => $edit['fid']); |
---|
| 111 | } |
---|
| 112 | |
---|
| 113 | return $form; |
---|
| 114 | } |
---|
| 115 | |
---|
| 116 | /** |
---|
| 117 | * Validate aggregator_form_feed form submissions. |
---|
| 118 | */ |
---|
| 119 | function aggregator_form_feed_validate($form, &$form_state) { |
---|
| 120 | if ($form_state['values']['op'] == t('Save')) { |
---|
| 121 | // Ensure URL is valid. |
---|
| 122 | if (!valid_url($form_state['values']['url'], TRUE)) { |
---|
| 123 | form_set_error('url', t('The URL %url is invalid. Please enter a fully-qualified URL, such as http://www.example.com/feed.xml.', array('%url' => $form_state['values']['url']))); |
---|
| 124 | } |
---|
| 125 | // Check for duplicate titles. |
---|
| 126 | if (isset($form_state['values']['fid'])) { |
---|
| 127 | $result = db_query("SELECT title, url FROM {aggregator_feed} WHERE (title = '%s' OR url = '%s') AND fid <> %d", $form_state['values']['title'], $form_state['values']['url'], $form_state['values']['fid']); |
---|
| 128 | } |
---|
| 129 | else { |
---|
| 130 | $result = db_query("SELECT title, url FROM {aggregator_feed} WHERE title = '%s' OR url = '%s'", $form_state['values']['title'], $form_state['values']['url']); |
---|
| 131 | } |
---|
| 132 | while ($feed = db_fetch_object($result)) { |
---|
| 133 | if (strcasecmp($feed->title, $form_state['values']['title']) == 0) { |
---|
| 134 | form_set_error('title', t('A feed named %feed already exists. Please enter a unique title.', array('%feed' => $form_state['values']['title']))); |
---|
| 135 | } |
---|
| 136 | if (strcasecmp($feed->url, $form_state['values']['url']) == 0) { |
---|
| 137 | form_set_error('url', t('A feed with this URL %url already exists. Please enter a unique URL.', array('%url' => $form_state['values']['url']))); |
---|
| 138 | } |
---|
| 139 | } |
---|
| 140 | } |
---|
| 141 | } |
---|
| 142 | |
---|
| 143 | /** |
---|
| 144 | * Process aggregator_form_feed form submissions. |
---|
| 145 | * |
---|
| 146 | * @todo Add delete confirmation dialog. |
---|
| 147 | */ |
---|
| 148 | function aggregator_form_feed_submit($form, &$form_state) { |
---|
| 149 | if ($form_state['values']['op'] == t('Delete')) { |
---|
| 150 | $title = $form_state['values']['title']; |
---|
| 151 | // Unset the title: |
---|
| 152 | unset($form_state['values']['title']); |
---|
| 153 | } |
---|
| 154 | aggregator_save_feed($form_state['values']); |
---|
| 155 | if (isset($form_state['values']['fid'])) { |
---|
| 156 | if (isset($form_state['values']['title'])) { |
---|
| 157 | drupal_set_message(t('The feed %feed has been updated.', array('%feed' => $form_state['values']['title']))); |
---|
| 158 | if (arg(0) == 'admin') { |
---|
| 159 | $form_state['redirect'] = 'admin/content/aggregator/'; |
---|
| 160 | return; |
---|
| 161 | } |
---|
| 162 | else { |
---|
| 163 | $form_state['redirect'] = 'aggregator/sources/'. $form_state['values']['fid']; |
---|
| 164 | return; |
---|
| 165 | } |
---|
| 166 | } |
---|
| 167 | else { |
---|
| 168 | watchdog('aggregator', 'Feed %feed deleted.', array('%feed' => $title)); |
---|
| 169 | drupal_set_message(t('The feed %feed has been deleted.', array('%feed' => $title))); |
---|
| 170 | if (arg(0) == 'admin') { |
---|
| 171 | $form_state['redirect'] = 'admin/content/aggregator/'; |
---|
| 172 | return; |
---|
| 173 | } |
---|
| 174 | else { |
---|
| 175 | $form_state['redirect'] = 'aggregator/sources/'; |
---|
| 176 | return; |
---|
| 177 | } |
---|
| 178 | } |
---|
| 179 | } |
---|
| 180 | else { |
---|
| 181 | watchdog('aggregator', 'Feed %feed added.', array('%feed' => $form_state['values']['title']), WATCHDOG_NOTICE, l(t('view'), 'admin/content/aggregator')); |
---|
| 182 | drupal_set_message(t('The feed %feed has been added.', array('%feed' => $form_state['values']['title']))); |
---|
| 183 | } |
---|
| 184 | } |
---|
| 185 | |
---|
| 186 | function aggregator_admin_remove_feed($form_state, $feed) { |
---|
| 187 | return confirm_form( |
---|
| 188 | array( |
---|
| 189 | 'feed' => array( |
---|
| 190 | '#type' => 'value', |
---|
| 191 | '#value' => $feed, |
---|
| 192 | ), |
---|
| 193 | ), |
---|
| 194 | t('Are you sure you want to remove all items from the feed %feed?', array('%feed' => $feed['title'])), |
---|
| 195 | 'admin/content/aggregator', |
---|
| 196 | t('This action cannot be undone.'), |
---|
| 197 | t('Remove items'), |
---|
| 198 | t('Cancel') |
---|
| 199 | ); |
---|
| 200 | } |
---|
| 201 | |
---|
| 202 | /** |
---|
| 203 | * Remove all items from a feed and redirect to the overview page. |
---|
| 204 | * |
---|
| 205 | * @param $feed |
---|
| 206 | * An associative array describing the feed to be cleared. |
---|
| 207 | */ |
---|
| 208 | function aggregator_admin_remove_feed_submit($form, &$form_state) { |
---|
| 209 | aggregator_remove($form_state['values']['feed']); |
---|
| 210 | $form_state['redirect'] = 'admin/content/aggregator'; |
---|
| 211 | } |
---|
| 212 | |
---|
| 213 | /** |
---|
| 214 | * Menu callback; refreshes a feed, then redirects to the overview page. |
---|
| 215 | * |
---|
| 216 | * @param $feed |
---|
| 217 | * An associative array describing the feed to be refreshed. |
---|
| 218 | */ |
---|
| 219 | function aggregator_admin_refresh_feed($feed) { |
---|
[d7a822e] | 220 | if (!isset($_GET['token']) || !drupal_valid_token($_GET['token'], 'aggregator/update/' . $feed['fid'])) { |
---|
| 221 | return drupal_access_denied(); |
---|
| 222 | } |
---|
[b354002] | 223 | aggregator_refresh($feed); |
---|
| 224 | drupal_goto('admin/content/aggregator'); |
---|
| 225 | } |
---|
| 226 | |
---|
| 227 | /** |
---|
| 228 | * Form builder; Configure the aggregator system. |
---|
| 229 | * |
---|
| 230 | * @ingroup forms |
---|
| 231 | * @see system_settings_form() |
---|
| 232 | */ |
---|
| 233 | function aggregator_admin_settings() { |
---|
| 234 | $items = array(0 => t('none')) + drupal_map_assoc(array(3, 5, 10, 15, 20, 25), '_aggregator_items'); |
---|
| 235 | $period = drupal_map_assoc(array(3600, 10800, 21600, 32400, 43200, 86400, 172800, 259200, 604800, 1209600, 2419200, 4838400, 9676800), 'format_interval'); |
---|
| 236 | |
---|
| 237 | $form['aggregator_allowed_html_tags'] = array( |
---|
| 238 | '#type' => 'textfield', '#title' => t('Allowed HTML tags'), '#size' => 80, '#maxlength' => 255, |
---|
| 239 | '#default_value' => variable_get('aggregator_allowed_html_tags', '<a> <b> <br> <dd> <dl> <dt> <em> <i> <li> <ol> <p> <strong> <u> <ul>'), |
---|
| 240 | '#description' => t('A space-separated list of HTML tags allowed in the content of feed items. (Tags in this list are not removed by Drupal.)') |
---|
| 241 | ); |
---|
| 242 | |
---|
| 243 | $form['aggregator_summary_items'] = array( |
---|
| 244 | '#type' => 'select', '#title' => t('Items shown in sources and categories pages') , |
---|
| 245 | '#default_value' => variable_get('aggregator_summary_items', 3), '#options' => $items, |
---|
| 246 | '#description' => t('Number of feed items displayed in feed and category summary pages.') |
---|
| 247 | ); |
---|
| 248 | |
---|
| 249 | $form['aggregator_clear'] = array( |
---|
| 250 | '#type' => 'select', '#title' => t('Discard items older than'), |
---|
| 251 | '#default_value' => variable_get('aggregator_clear', 9676800), '#options' => $period, |
---|
| 252 | '#description' => t('The length of time to retain feed items before discarding. (Requires a correctly configured <a href="@cron">cron maintenance task</a>.)', array('@cron' => url('admin/reports/status'))) |
---|
| 253 | ); |
---|
| 254 | |
---|
| 255 | $form['aggregator_category_selector'] = array( |
---|
| 256 | '#type' => 'radios', '#title' => t('Category selection type'), '#default_value' => variable_get('aggregator_category_selector', 'checkboxes'), |
---|
| 257 | '#options' => array('checkboxes' => t('checkboxes'), 'select' => t('multiple selector')), |
---|
| 258 | '#description' => t('The type of category selection widget displayed on categorization pages. (For a small number of categories, checkboxes are easier to use, while a multiple selector work well with large numbers of categories.)') |
---|
| 259 | ); |
---|
| 260 | |
---|
| 261 | return system_settings_form($form); |
---|
| 262 | } |
---|
| 263 | |
---|
| 264 | /** |
---|
| 265 | * Form builder; Generate a form to add/edit/delete aggregator categories. |
---|
| 266 | * |
---|
| 267 | * @ingroup forms |
---|
| 268 | * @see aggregator_form_category_validate() |
---|
| 269 | * @see aggregator_form_category_submit() |
---|
| 270 | */ |
---|
| 271 | function aggregator_form_category(&$form_state, $edit = array('title' => '', 'description' => '', 'cid' => NULL)) { |
---|
| 272 | $form['title'] = array('#type' => 'textfield', |
---|
| 273 | '#title' => t('Title'), |
---|
| 274 | '#default_value' => $edit['title'], |
---|
| 275 | '#maxlength' => 64, |
---|
| 276 | '#required' => TRUE, |
---|
| 277 | ); |
---|
| 278 | $form['description'] = array('#type' => 'textarea', |
---|
| 279 | '#title' => t('Description'), |
---|
| 280 | '#default_value' => $edit['description'], |
---|
| 281 | ); |
---|
| 282 | $form['submit'] = array('#type' => 'submit', '#value' => t('Save')); |
---|
| 283 | |
---|
| 284 | if ($edit['cid']) { |
---|
| 285 | $form['delete'] = array('#type' => 'submit', '#value' => t('Delete')); |
---|
| 286 | $form['cid'] = array('#type' => 'hidden', '#value' => $edit['cid']); |
---|
| 287 | } |
---|
| 288 | |
---|
| 289 | return $form; |
---|
| 290 | } |
---|
| 291 | |
---|
| 292 | /** |
---|
| 293 | * Validate aggregator_form_feed form submissions. |
---|
| 294 | */ |
---|
| 295 | function aggregator_form_category_validate($form, &$form_state) { |
---|
| 296 | if ($form_state['values']['op'] == t('Save')) { |
---|
| 297 | // Check for duplicate titles |
---|
| 298 | if (isset($form_state['values']['cid'])) { |
---|
| 299 | $category = db_fetch_object(db_query("SELECT cid FROM {aggregator_category} WHERE title = '%s' AND cid <> %d", $form_state['values']['title'], $form_state['values']['cid'])); |
---|
| 300 | } |
---|
| 301 | else { |
---|
| 302 | $category = db_fetch_object(db_query("SELECT cid FROM {aggregator_category} WHERE title = '%s'", $form_state['values']['title'])); |
---|
| 303 | } |
---|
| 304 | if ($category) { |
---|
| 305 | form_set_error('title', t('A category named %category already exists. Please enter a unique title.', array('%category' => $form_state['values']['title']))); |
---|
| 306 | } |
---|
| 307 | } |
---|
| 308 | } |
---|
| 309 | |
---|
| 310 | /** |
---|
| 311 | * Process aggregator_form_category form submissions. |
---|
| 312 | * |
---|
| 313 | * @todo Add delete confirmation dialog. |
---|
| 314 | */ |
---|
| 315 | function aggregator_form_category_submit($form, &$form_state) { |
---|
| 316 | if ($form_state['values']['op'] == t('Delete')) { |
---|
| 317 | $title = $form_state['values']['title']; |
---|
| 318 | // Unset the title: |
---|
| 319 | unset($form_state['values']['title']); |
---|
| 320 | } |
---|
| 321 | aggregator_save_category($form_state['values']); |
---|
| 322 | if (isset($form_state['values']['cid'])) { |
---|
| 323 | if (isset($form_state['values']['title'])) { |
---|
| 324 | drupal_set_message(t('The category %category has been updated.', array('%category' => $form_state['values']['title']))); |
---|
| 325 | if (arg(0) == 'admin') { |
---|
| 326 | $form_state['redirect'] = 'admin/content/aggregator/'; |
---|
| 327 | return; |
---|
| 328 | } |
---|
| 329 | else { |
---|
| 330 | $form_state['redirect'] = 'aggregator/categories/'. $form_state['values']['cid']; |
---|
| 331 | return; |
---|
| 332 | } |
---|
| 333 | } |
---|
| 334 | else { |
---|
| 335 | watchdog('aggregator', 'Category %category deleted.', array('%category' => $title)); |
---|
| 336 | drupal_set_message(t('The category %category has been deleted.', array('%category' => $title))); |
---|
| 337 | if (arg(0) == 'admin') { |
---|
| 338 | $form_state['redirect'] = 'admin/content/aggregator/'; |
---|
| 339 | return; |
---|
| 340 | } |
---|
| 341 | else { |
---|
| 342 | $form_state['redirect'] = 'aggregator/categories/'; |
---|
| 343 | return; |
---|
| 344 | } |
---|
| 345 | } |
---|
| 346 | } |
---|
| 347 | else { |
---|
| 348 | watchdog('aggregator', 'Category %category added.', array('%category' => $form_state['values']['title']), WATCHDOG_NOTICE, l(t('view'), 'admin/content/aggregator')); |
---|
| 349 | drupal_set_message(t('The category %category has been added.', array('%category' => $form_state['values']['title']))); |
---|
| 350 | } |
---|
| 351 | } |
---|