| Drupal | PHP Cross Reference | Content Management Systems |
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.fid, f.title, f.url, f.refresh, f.checked, f.link, f.description, f.hash, f.etag, f.modified, f.image, f.block, 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.hash, 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 foreach ($result as $feed) { 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(REQUEST_TIME - $feed->checked))) : t('never')), 33 ($feed->checked && $feed->refresh ? t('%time left', array('%time' => format_interval($feed->checked + $feed->refresh - REQUEST_TIME))) : t('never')), 34 l(t('edit'), "admin/config/services/aggregator/edit/feed/$feed->fid"), 35 l(t('remove items'), "admin/config/services/aggregator/remove/$feed->fid"), 36 l(t('update items'), "admin/config/services/aggregator/update/$feed->fid", array('query' => array('token' => drupal_get_token("aggregator/update/$feed->fid")))), 37 ); 38 } 39 $output .= theme('table', array('header' => $header, 'rows' => $rows, 'empty' => t('No feeds available. <a href="@link">Add feed</a>.', array('@link' => url('admin/config/services/aggregator/add/feed'))))); 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 foreach ($result as $category) { 48 $rows[] = array(l($category->title, "aggregator/categories/$category->cid"), format_plural($category->items, '1 item', '@count items'), l(t('edit'), "admin/config/services/aggregator/edit/category/$category->cid")); 49 } 50 $output .= theme('table', array('header' => $header, 'rows' => $rows, 'empty' => t('No categories available. <a href="@link">Add category</a>.', array('@link' => url('admin/config/services/aggregator/add/category'))))); 51 52 return $output; 53 } 54 55 /** 56 * Form constructor for adding and editing feed sources. 57 * 58 * @param $feed 59 * If editing a feed, the feed to edit as a PHP stdClass value; if adding a 60 * new feed, NULL. 61 * 62 * @ingroup forms 63 * @see aggregator_form_feed_validate() 64 * @see aggregator_form_feed_submit() 65 */ 66 function aggregator_form_feed($form, &$form_state, stdClass $feed = NULL) { 67 $period = drupal_map_assoc(array(900, 1800, 3600, 7200, 10800, 21600, 32400, 43200, 64800, 86400, 172800, 259200, 604800, 1209600, 2419200), 'format_interval'); 68 $period[AGGREGATOR_CLEAR_NEVER] = t('Never'); 69 70 $form['title'] = array('#type' => 'textfield', 71 '#title' => t('Title'), 72 '#default_value' => isset($feed->title) ? $feed->title : '', 73 '#maxlength' => 255, 74 '#description' => t('The name of the feed (or the name of the website providing the feed).'), 75 '#required' => TRUE, 76 ); 77 $form['url'] = array('#type' => 'textfield', 78 '#title' => t('URL'), 79 '#default_value' => isset($feed->url) ? $feed->url : '', 80 '#maxlength' => NULL, 81 '#description' => t('The fully-qualified URL of the feed.'), 82 '#required' => TRUE, 83 ); 84 $form['refresh'] = array('#type' => 'select', 85 '#title' => t('Update interval'), 86 '#default_value' => isset($feed->refresh) ? $feed->refresh : 3600, 87 '#options' => $period, 88 '#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'))), 89 ); 90 $form['block'] = array('#type' => 'select', 91 '#title' => t('News items in block'), 92 '#default_value' => isset($feed->block) ? $feed->block : 5, 93 '#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)), 94 '#description' => t("Drupal can make a block with the most recent news items of this feed. You can <a href=\"@block-admin\">configure blocks</a> to be displayed in the sidebar of your page. This setting lets you configure the number of news items to show in this feed's block. If you choose '0' this feed's block will be disabled.", array('@block-admin' => url('admin/structure/block'))), 95 ); 96 97 // Handling of categories. 98 $options = array(); 99 $values = array(); 100 $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 = :fid ORDER BY title', array(':fid' => isset($feed->fid) ? $feed->fid : NULL)); 101 foreach ($categories as $category) { 102 $options[$category->cid] = check_plain($category->title); 103 if ($category->fid) $values[] = $category->cid; 104 } 105 106 if ($options) { 107 $form['category'] = array( 108 '#type' => 'checkboxes', 109 '#title' => t('Categorize news items'), 110 '#default_value' => $values, 111 '#options' => $options, 112 '#description' => t('New feed items are automatically filed in the checked categories.'), 113 ); 114 } 115 116 $form['actions'] = array('#type' => 'actions'); 117 $form['actions']['submit'] = array( 118 '#type' => 'submit', 119 '#value' => t('Save'), 120 ); 121 if (!empty($feed->fid)) { 122 $form['actions']['delete'] = array( 123 '#type' => 'submit', 124 '#value' => t('Delete'), 125 ); 126 $form['fid'] = array( 127 '#type' => 'hidden', 128 '#value' => $feed->fid, 129 ); 130 } 131 132 return $form; 133 } 134 135 /** 136 * Form validation handler for aggregator_form_feed(). 137 * 138 * @see aggregator_form_feed_submit() 139 */ 140 function aggregator_form_feed_validate($form, &$form_state) { 141 if ($form_state['values']['op'] == t('Save')) { 142 // Ensure URL is valid. 143 if (!valid_url($form_state['values']['url'], TRUE)) { 144 form_set_error('url', t('The URL %url is invalid. Enter a fully-qualified URL, such as http://www.example.com/feed.xml.', array('%url' => $form_state['values']['url']))); 145 } 146 // Check for duplicate titles. 147 if (isset($form_state['values']['fid'])) { 148 $result = db_query("SELECT title, url FROM {aggregator_feed} WHERE (title = :title OR url = :url) AND fid <> :fid", array(':title' => $form_state['values']['title'], ':url' => $form_state['values']['url'], ':fid' => $form_state['values']['fid'])); 149 } 150 else { 151 $result = db_query("SELECT title, url FROM {aggregator_feed} WHERE title = :title OR url = :url", array(':title' => $form_state['values']['title'], ':url' => $form_state['values']['url'])); 152 } 153 foreach ($result as $feed) { 154 if (strcasecmp($feed->title, $form_state['values']['title']) == 0) { 155 form_set_error('title', t('A feed named %feed already exists. Enter a unique title.', array('%feed' => $form_state['values']['title']))); 156 } 157 if (strcasecmp($feed->url, $form_state['values']['url']) == 0) { 158 form_set_error('url', t('A feed with this URL %url already exists. Enter a unique URL.', array('%url' => $form_state['values']['url']))); 159 } 160 } 161 } 162 } 163 164 /** 165 * Form submission handler for aggregator_form_feed(). 166 * 167 * @see aggregator_form_feed_validate() 168 * @todo Add delete confirmation dialog. 169 */ 170 function aggregator_form_feed_submit($form, &$form_state) { 171 if ($form_state['values']['op'] == t('Delete')) { 172 $title = $form_state['values']['title']; 173 // Unset the title. 174 unset($form_state['values']['title']); 175 } 176 aggregator_save_feed($form_state['values']); 177 if (isset($form_state['values']['fid'])) { 178 if (isset($form_state['values']['title'])) { 179 drupal_set_message(t('The feed %feed has been updated.', array('%feed' => $form_state['values']['title']))); 180 if (arg(0) == 'admin') { 181 $form_state['redirect'] = 'admin/config/services/aggregator/'; 182 return; 183 } 184 else { 185 $form_state['redirect'] = 'aggregator/sources/' . $form_state['values']['fid']; 186 return; 187 } 188 } 189 else { 190 watchdog('aggregator', 'Feed %feed deleted.', array('%feed' => $title)); 191 drupal_set_message(t('The feed %feed has been deleted.', array('%feed' => $title))); 192 if (arg(0) == 'admin') { 193 $form_state['redirect'] = 'admin/config/services/aggregator/'; 194 return; 195 } 196 else { 197 $form_state['redirect'] = 'aggregator/sources/'; 198 return; 199 } 200 } 201 } 202 else { 203 watchdog('aggregator', 'Feed %feed added.', array('%feed' => $form_state['values']['title']), WATCHDOG_NOTICE, l(t('view'), 'admin/config/services/aggregator')); 204 drupal_set_message(t('The feed %feed has been added.', array('%feed' => $form_state['values']['title']))); 205 } 206 } 207 208 /** 209 * Deletes a feed. 210 * 211 * @param $feed 212 * An associative array describing the feed to be cleared. 213 * 214 * @see aggregator_admin_remove_feed_submit() 215 */ 216 function aggregator_admin_remove_feed($form, $form_state, $feed) { 217 return confirm_form( 218 array( 219 'feed' => array( 220 '#type' => 'value', 221 '#value' => $feed, 222 ), 223 ), 224 t('Are you sure you want to remove all items from the feed %feed?', array('%feed' => $feed->title)), 225 'admin/config/services/aggregator', 226 t('This action cannot be undone.'), 227 t('Remove items'), 228 t('Cancel') 229 ); 230 } 231 232 /** 233 * Form submission handler for aggregator_admin_remove_feed(). 234 * 235 * Removes all items from a feed and redirects to the overview page. 236 */ 237 function aggregator_admin_remove_feed_submit($form, &$form_state) { 238 aggregator_remove($form_state['values']['feed']); 239 $form_state['redirect'] = 'admin/config/services/aggregator'; 240 } 241 242 /** 243 * Form constructor for importing feeds from OPML. 244 * 245 * @ingroup forms 246 * @see aggregator_form_opml_validate() 247 * @see aggregator_form_opml_submit() 248 */ 249 function aggregator_form_opml($form, &$form_state) { 250 $period = drupal_map_assoc(array(900, 1800, 3600, 7200, 10800, 21600, 32400, 43200, 64800, 86400, 172800, 259200, 604800, 1209600, 2419200), 'format_interval'); 251 252 $form['upload'] = array( 253 '#type' => 'file', 254 '#title' => t('OPML File'), 255 '#description' => t('Upload an OPML file containing a list of feeds to be imported.'), 256 ); 257 $form['remote'] = array( 258 '#type' => 'textfield', 259 '#title' => t('OPML Remote URL'), 260 '#maxlength' => 1024, 261 '#description' => t('Enter the URL of an OPML file. This file will be downloaded and processed only once on submission of the form.'), 262 ); 263 $form['refresh'] = array( 264 '#type' => 'select', 265 '#title' => t('Update interval'), 266 '#default_value' => 3600, 267 '#options' => $period, 268 '#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'))), 269 ); 270 $form['block'] = array('#type' => 'select', 271 '#title' => t('News items in block'), 272 '#default_value' => 5, 273 '#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)), 274 '#description' => t("Drupal can make a block with the most recent news items of a feed. You can <a href=\"@block-admin\">configure blocks</a> 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'))), 275 ); 276 277 // Handling of categories. 278 $options = array_map('check_plain', db_query("SELECT cid, title FROM {aggregator_category} ORDER BY title")->fetchAllKeyed()); 279 if ($options) { 280 $form['category'] = array( 281 '#type' => 'checkboxes', 282 '#title' => t('Categorize news items'), 283 '#options' => $options, 284 '#description' => t('New feed items are automatically filed in the checked categories.'), 285 ); 286 } 287 $form['actions'] = array('#type' => 'actions'); 288 $form['actions']['submit'] = array( 289 '#type' => 'submit', 290 '#value' => t('Import') 291 ); 292 293 return $form; 294 } 295 296 /** 297 * Form validation handler for aggregator_form_opml(). 298 * 299 * @see aggregator_form_opml_submit() 300 */ 301 function aggregator_form_opml_validate($form, &$form_state) { 302 // If both fields are empty or filled, cancel. 303 if (empty($form_state['values']['remote']) == empty($_FILES['files']['name']['upload'])) { 304 form_set_error('remote', t('You must <em>either</em> upload a file or enter a URL.')); 305 } 306 307 // Validate the URL, if one was entered. 308 if (!empty($form_state['values']['remote']) && !valid_url($form_state['values']['remote'], TRUE)) { 309 form_set_error('remote', t('This URL is not valid.')); 310 } 311 } 312 313 /** 314 * Form submission handler for aggregator_form_opml(). 315 * 316 * @see aggregator_form_opml_validate() 317 */ 318 function aggregator_form_opml_submit($form, &$form_state) { 319 $data = ''; 320 $validators = array('file_validate_extensions' => array('opml xml')); 321 if ($file = file_save_upload('upload', $validators)) { 322 $data = file_get_contents($file->uri); 323 } 324 else { 325 $response = drupal_http_request($form_state['values']['remote']); 326 if (!isset($response->error)) { 327 $data = $response->data; 328 } 329 } 330 331 $feeds = _aggregator_parse_opml($data); 332 if (empty($feeds)) { 333 drupal_set_message(t('No new feed has been added.')); 334 return; 335 } 336 337 $form_state['values']['op'] = t('Save'); 338 339 foreach ($feeds as $feed) { 340 // Ensure URL is valid. 341 if (!valid_url($feed['url'], TRUE)) { 342 drupal_set_message(t('The URL %url is invalid.', array('%url' => $feed['url'])), 'warning'); 343 continue; 344 } 345 346 // Check for duplicate titles or URLs. 347 $result = db_query("SELECT title, url FROM {aggregator_feed} WHERE title = :title OR url = :url", array(':title' => $feed['title'], ':url' => $feed['url'])); 348 foreach ($result as $old) { 349 if (strcasecmp($old->title, $feed['title']) == 0) { 350 drupal_set_message(t('A feed named %title already exists.', array('%title' => $old->title)), 'warning'); 351 continue 2; 352 } 353 if (strcasecmp($old->url, $feed['url']) == 0) { 354 drupal_set_message(t('A feed with the URL %url already exists.', array('%url' => $old->url)), 'warning'); 355 continue 2; 356 } 357 } 358 359 $form_state['values']['title'] = $feed['title']; 360 $form_state['values']['url'] = $feed['url']; 361 drupal_form_submit('aggregator_form_feed', $form_state); 362 } 363 364 $form_state['redirect'] = 'admin/config/services/aggregator'; 365 } 366 367 /** 368 * Parses an OPML file. 369 * 370 * Feeds are recognized as <outline> elements with the attributes "text" and 371 * "xmlurl" set. 372 * 373 * @param $opml 374 * The complete contents of an OPML document. 375 * 376 * @return 377 * An array of feeds, each an associative array with a "title" and a "url" 378 * element, or NULL if the OPML document failed to be parsed. An empty array 379 * will be returned if the document is valid but contains no feeds, as some 380 * OPML documents do. 381 */ 382 function _aggregator_parse_opml($opml) { 383 $feeds = array(); 384 $xml_parser = drupal_xml_parser_create($opml); 385 if (xml_parse_into_struct($xml_parser, $opml, $values)) { 386 foreach ($values as $entry) { 387 if ($entry['tag'] == 'OUTLINE' && isset($entry['attributes'])) { 388 $item = $entry['attributes']; 389 if (!empty($item['XMLURL']) && !empty($item['TEXT'])) { 390 $feeds[] = array('title' => $item['TEXT'], 'url' => $item['XMLURL']); 391 } 392 } 393 } 394 } 395 xml_parser_free($xml_parser); 396 397 return $feeds; 398 } 399 400 /** 401 * Menu callback; refreshes a feed, then redirects to the overview page. 402 * 403 * @param $feed 404 * An object describing the feed to be refreshed. 405 */ 406 function aggregator_admin_refresh_feed($feed) { 407 if (!isset($_GET['token']) || !drupal_valid_token($_GET['token'], 'aggregator/update/' . $feed->fid)) { 408 return MENU_ACCESS_DENIED; 409 } 410 aggregator_refresh($feed); 411 drupal_goto('admin/config/services/aggregator'); 412 } 413 414 /** 415 * Form constructor for the aggregator system settings. 416 * 417 * @see aggregator_admin_form_submit() 418 * @ingroup forms 419 */ 420 function aggregator_admin_form($form, $form_state) { 421 // Global aggregator settings. 422 $form['aggregator_allowed_html_tags'] = array( 423 '#type' => 'textfield', 424 '#title' => t('Allowed HTML tags'), 425 '#size' => 80, 426 '#maxlength' => 255, 427 '#default_value' => variable_get('aggregator_allowed_html_tags', '<a> <b> <br> <dd> <dl> <dt> <em> <i> <li> <ol> <p> <strong> <u> <ul>'), 428 '#description' => t('A space-separated list of HTML tags allowed in the content of feed items. Disallowed tags are stripped from the content.'), 429 ); 430 431 // Make sure configuration is sane. 432 aggregator_sanitize_configuration(); 433 434 // Get all available fetchers. 435 $fetchers = module_implements('aggregator_fetch'); 436 foreach ($fetchers as $k => $module) { 437 if ($info = module_invoke($module, 'aggregator_fetch_info')) { 438 $label = $info['title'] . ' <span class="description">' . $info['description'] . '</span>'; 439 } 440 else { 441 $label = $module; 442 } 443 unset($fetchers[$k]); 444 $fetchers[$module] = $label; 445 } 446 447 // Get all available parsers. 448 $parsers = module_implements('aggregator_parse'); 449 foreach ($parsers as $k => $module) { 450 if ($info = module_invoke($module, 'aggregator_parse_info')) { 451 $label = $info['title'] . ' <span class="description">' . $info['description'] . '</span>'; 452 } 453 else { 454 $label = $module; 455 } 456 unset($parsers[$k]); 457 $parsers[$module] = $label; 458 } 459 460 // Get all available processors. 461 $processors = module_implements('aggregator_process'); 462 foreach ($processors as $k => $module) { 463 if ($info = module_invoke($module, 'aggregator_process_info')) { 464 $label = $info['title'] . ' <span class="description">' . $info['description'] . '</span>'; 465 } 466 else { 467 $label = $module; 468 } 469 unset($processors[$k]); 470 $processors[$module] = $label; 471 } 472 473 // Only show basic configuration if there are actually options. 474 $basic_conf = array(); 475 if (count($fetchers) > 1) { 476 $basic_conf['aggregator_fetcher'] = array( 477 '#type' => 'radios', 478 '#title' => t('Fetcher'), 479 '#description' => t('Fetchers download data from an external source. Choose a fetcher suitable for the external source you would like to download from.'), 480 '#options' => $fetchers, 481 '#default_value' => variable_get('aggregator_fetcher', 'aggregator'), 482 ); 483 } 484 if (count($parsers) > 1) { 485 $basic_conf['aggregator_parser'] = array( 486 '#type' => 'radios', 487 '#title' => t('Parser'), 488 '#description' => t('Parsers transform downloaded data into standard structures. Choose a parser suitable for the type of feeds you would like to aggregate.'), 489 '#options' => $parsers, 490 '#default_value' => variable_get('aggregator_parser', 'aggregator'), 491 ); 492 } 493 if (count($processors) > 1) { 494 $basic_conf['aggregator_processors'] = array( 495 '#type' => 'checkboxes', 496 '#title' => t('Processors'), 497 '#description' => t('Processors act on parsed feed data, for example they store feed items. Choose the processors suitable for your task.'), 498 '#options' => $processors, 499 '#default_value' => variable_get('aggregator_processors', array('aggregator')), 500 ); 501 } 502 if (count($basic_conf)) { 503 $form['basic_conf'] = array( 504 '#type' => 'fieldset', 505 '#title' => t('Basic configuration'), 506 '#description' => t('For most aggregation tasks, the default settings are fine.'), 507 '#collapsible' => TRUE, 508 '#collapsed' => FALSE, 509 ); 510 $form['basic_conf'] += $basic_conf; 511 } 512 513 // Implementing modules will expect an array at $form['modules']. 514 $form['modules'] = array(); 515 516 $form['actions'] = array('#type' => 'actions'); 517 $form['actions']['submit'] = array( 518 '#type' => 'submit', 519 '#value' => t('Save configuration'), 520 ); 521 522 return $form; 523 } 524 525 /** 526 * Form submission handler for aggregator_admin_form(). 527 */ 528 function aggregator_admin_form_submit($form, &$form_state) { 529 if (isset($form_state['values']['aggregator_processors'])) { 530 $form_state['values']['aggregator_processors'] = array_filter($form_state['values']['aggregator_processors']); 531 } 532 system_settings_form_submit($form, $form_state); 533 } 534 535 /** 536 * Form constructor to add/edit/delete aggregator categories. 537 * 538 * @param $edit 539 * An associative array containing: 540 * - title: A string to use for the category title. 541 * - description: A string to use for the category description. 542 * - cid: The category ID. 543 * 544 * @ingroup forms 545 * @see aggregator_form_category_validate() 546 * @see aggregator_form_category_submit() 547 */ 548 function aggregator_form_category($form, &$form_state, $edit = array('title' => '', 'description' => '', 'cid' => NULL)) { 549 $form['title'] = array('#type' => 'textfield', 550 '#title' => t('Title'), 551 '#default_value' => $edit['title'], 552 '#maxlength' => 64, 553 '#required' => TRUE, 554 ); 555 $form['description'] = array('#type' => 'textarea', 556 '#title' => t('Description'), 557 '#default_value' => $edit['description'], 558 ); 559 $form['actions'] = array('#type' => 'actions'); 560 $form['actions']['submit'] = array('#type' => 'submit', '#value' => t('Save')); 561 if ($edit['cid']) { 562 $form['actions']['delete'] = array('#type' => 'submit', '#value' => t('Delete')); 563 $form['cid'] = array('#type' => 'hidden', '#value' => $edit['cid']); 564 } 565 566 return $form; 567 } 568 569 /** 570 * Form validation handler for aggregator_form_category(). 571 * 572 * @see aggregator_form_category_submit() 573 */ 574 function aggregator_form_category_validate($form, &$form_state) { 575 if ($form_state['values']['op'] == t('Save')) { 576 // Check for duplicate titles 577 if (isset($form_state['values']['cid'])) { 578 $category = db_query("SELECT cid FROM {aggregator_category} WHERE title = :title AND cid <> :cid", array(':title' => $form_state['values']['title'], ':cid' => $form_state['values']['cid']))->fetchObject(); 579 } 580 else { 581 $category = db_query("SELECT cid FROM {aggregator_category} WHERE title = :title", array(':title' => $form_state['values']['title']))->fetchObject(); 582 } 583 if ($category) { 584 form_set_error('title', t('A category named %category already exists. Enter a unique title.', array('%category' => $form_state['values']['title']))); 585 } 586 } 587 } 588 589 /** 590 * Form submission handler for aggregator_form_category(). 591 * 592 * @see aggregator_form_category_validate() 593 * @todo Add delete confirmation dialog. 594 */ 595 function aggregator_form_category_submit($form, &$form_state) { 596 if ($form_state['values']['op'] == t('Delete')) { 597 $title = $form_state['values']['title']; 598 // Unset the title. 599 unset($form_state['values']['title']); 600 } 601 aggregator_save_category($form_state['values']); 602 if (isset($form_state['values']['cid'])) { 603 if (isset($form_state['values']['title'])) { 604 drupal_set_message(t('The category %category has been updated.', array('%category' => $form_state['values']['title']))); 605 if (arg(0) == 'admin') { 606 $form_state['redirect'] = 'admin/config/services/aggregator/'; 607 return; 608 } 609 else { 610 $form_state['redirect'] = 'aggregator/categories/' . $form_state['values']['cid']; 611 return; 612 } 613 } 614 else { 615 watchdog('aggregator', 'Category %category deleted.', array('%category' => $title)); 616 drupal_set_message(t('The category %category has been deleted.', array('%category' => $title))); 617 if (arg(0) == 'admin') { 618 $form_state['redirect'] = 'admin/config/services/aggregator/'; 619 return; 620 } 621 else { 622 $form_state['redirect'] = 'aggregator/categories/'; 623 return; 624 } 625 } 626 } 627 else { 628 watchdog('aggregator', 'Category %category added.', array('%category' => $form_state['values']['title']), WATCHDOG_NOTICE, l(t('view'), 'admin/config/services/aggregator')); 629 drupal_set_message(t('The category %category has been added.', array('%category' => $form_state['values']['title']))); 630 } 631 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
title