Parent Directory
|
Revision Log
|
Revision Graph
added paging mechanism, seperated tree form as own form element type
| 1 | <?php |
| 2 | |
| 3 | // $Id: taxonomy_manager.module,v 1.4 2007/07/22 15:08:11 mh86 Exp $ |
| 4 | |
| 5 | /** |
| 6 | * |
| 7 | * @file |
| 8 | * Taxonomy Manager |
| 9 | * |
| 10 | * Administration interface for managing taxonomy vocabularies |
| 11 | * |
| 12 | */ |
| 13 | |
| 14 | define('TAXONOMY_MANAGER_TREE_PAGE_SIZE', 50); |
| 15 | |
| 16 | |
| 17 | /** |
| 18 | * Implementation of hook_menu |
| 19 | */ |
| 20 | function taxonomy_manager_menu($may_cache) { |
| 21 | $items = array(); |
| 22 | |
| 23 | if ($may_cache) { |
| 24 | $items[] = array('path' => 'admin/content/taxonomy_manager', |
| 25 | 'title' => t('Taxonomy Manager'), |
| 26 | 'description' => t('Administer vocabularies with the Taxonomy Manager'), |
| 27 | 'callback' => 'taxonomy_manager_voc_list', |
| 28 | 'access' => user_access('administer taxonomy'), |
| 29 | 'type' => MENU_NORMAL_ITEM |
| 30 | ); |
| 31 | } |
| 32 | else { |
| 33 | if (arg(0) == 'admin' && arg(1) == 'content' && arg(2) == 'taxonomy_manager' && is_numeric(arg(3))) { |
| 34 | $vid = arg(3); |
| 35 | $items[] = array('path' => 'admin/content/taxonomy_manager/'. $vid, |
| 36 | 'title' => t('Taxonomy Manager'), |
| 37 | 'callback' => 'drupal_get_form', |
| 38 | 'callback arguments' => array('taxonomy_manager_form', $vid), |
| 39 | 'access' => user_access('administer taxonomy'), |
| 40 | 'type' => MENU_CALLBACK |
| 41 | ); |
| 42 | } |
| 43 | |
| 44 | //if (arg(0) == 'admin' && arg(1) == 'content' && arg(2) == 'taxonomy_manager' && arg(3) == 'childform' && is_numeric(arg(4))) { |
| 45 | //$parent = arg(4); |
| 46 | $items[] = array('path' => 'admin/content/taxonomy_manager/childform', |
| 47 | 'title' => t('Taxonomy Manager'), |
| 48 | 'callback' => 'taxonomy_manager_tree_build_child_form', |
| 49 | 'access' => user_access('administer taxonomy'), |
| 50 | 'type' => MENU_CALLBACK |
| 51 | ); |
| 52 | //} |
| 53 | |
| 54 | $items[] = array('path' => 'admin/content/taxonomy_manager/weight', |
| 55 | 'title' => t('Taxonomy Manager'), |
| 56 | 'callback' => 'taxonomy_manager_update_weights', |
| 57 | 'access' => user_access('administer taxonomy'), |
| 58 | 'type' => MENU_CALLBACK |
| 59 | ); |
| 60 | //if (arg(4) && arg(5) && arg(6)) { |
| 61 | |
| 62 | $items[] = array('path' => 'admin/content/taxonomy_manager/siblingsform', |
| 63 | 'title' => t('Taxonomy Manager'), |
| 64 | 'callback' => 'taxonomy_manager_tree_build_siblings_form', |
| 65 | 'access' => user_access('administer taxonomy'), |
| 66 | 'type' => MENU_CALLBACK |
| 67 | ); |
| 68 | //} |
| 69 | } |
| 70 | |
| 71 | return $items; |
| 72 | } |
| 73 | |
| 74 | /** |
| 75 | * list of vocabularies, which link to Taxonomy Manager interface |
| 76 | */ |
| 77 | function taxonomy_manager_voc_list() { |
| 78 | $vocabularies = taxonomy_get_vocabularies(); |
| 79 | $voc_list = array(); |
| 80 | |
| 81 | foreach ($vocabularies as $vocabulary) { |
| 82 | $voc_list[] = l($vocabulary->name, 'admin/content/taxonomy_manager/'. $vocabulary->vid); |
| 83 | } |
| 84 | |
| 85 | return theme('item_list', $voc_list, "Vocabularies:"); |
| 86 | |
| 87 | } |
| 88 | |
| 89 | /** |
| 90 | * defines forms for taxonomy manager interface |
| 91 | * |
| 92 | * @param $vid vocabulary id |
| 93 | */ |
| 94 | function taxonomy_manager_form($vid) { |
| 95 | $module_path = drupal_get_path('module', 'taxonomy_manager') .'/'; |
| 96 | drupal_add_css($module_path .'css/taxonomy_manager.css'); |
| 97 | drupal_add_js($module_path .'js/hideForm.js'); |
| 98 | drupal_add_js($module_path .'js/updateWeight.js'); |
| 99 | |
| 100 | drupal_add_js(array('updateWeight' => array('up' => 'go-up', 'down' => 'go-down', 'url' => url('admin/content/taxonomy_manager/weight/'. $vid))), 'setting'); |
| 101 | |
| 102 | $form = array(); |
| 103 | |
| 104 | $voc = taxonomy_get_vocabulary($vid); |
| 105 | |
| 106 | if (!is_numeric($voc->vid)) { |
| 107 | $text = t('No vocabulary with this ID available!. '); |
| 108 | $text .= t('Check this !link_list for available vocabularies or !link_create a new one', array('!link_list' => l('list', 'admin/content/taxonomy_manager'), '!link_create' => l('create', 'admin/content/taxonomy/add/vocabulary'))); |
| 109 | $form['text'] = array( |
| 110 | '#value' => $text, |
| 111 | ); |
| 112 | return $form; |
| 113 | } |
| 114 | |
| 115 | $form['vid'] = array('#type' => 'value', "#value" => $vid); |
| 116 | |
| 117 | if (_taxonomy_manager_voc_is_empty($vid)) { |
| 118 | $text = t('No terms available'); |
| 119 | $form['text'] = array( |
| 120 | '#value' => $text, |
| 121 | ); |
| 122 | $form += taxonomy_manager_add_form(false); |
| 123 | return $form; |
| 124 | } |
| 125 | |
| 126 | |
| 127 | $form['taxonomy_manager'] = array( |
| 128 | '#type' => 'fieldset', |
| 129 | '#title' => $voc->name, |
| 130 | '#weight' => 10, |
| 131 | '#tree' => TRUE, |
| 132 | '#prefix' => '<div id="taxonomytree">', |
| 133 | '#suffix' => '</div>', |
| 134 | ); |
| 135 | |
| 136 | $form['taxonomy_manager']['tree'] = array( |
| 137 | '#type' => 'taxonomy_manager_tree', |
| 138 | '#vid' => $vid, |
| 139 | '#pager' => TRUE, |
| 140 | ); |
| 141 | |
| 142 | $form['toolbar'] = array( |
| 143 | '#type' => 'fieldset', |
| 144 | '#title' => t('Toolbar'), |
| 145 | '#weight' => -10, |
| 146 | ); |
| 147 | |
| 148 | $form['toolbar']['up_link'] = array( |
| 149 | '#type' => 'markup', |
| 150 | '#value' => theme("image", $module_path ."images/go-up.png", "go up", NULL, array('id' => 'go-up')), |
| 151 | '#prefix' => '<div id="taxonomy-toolbar"><div id="taxonomy-toolbar-images">', |
| 152 | ); |
| 153 | |
| 154 | $form['toolbar']['down_link'] = array( |
| 155 | '#type' => 'markup', |
| 156 | '#value' => theme("image", $module_path ."images/go-down.png", "go down", NULL, array('id' => 'go-down')), |
| 157 | ); |
| 158 | |
| 159 | $form['toolbar']['delete_confirm'] = array( |
| 160 | '#type' => 'markup', |
| 161 | '#value' => theme("image", $module_path ."images/list-remove.png", "remove", NULL, array('id' => 'delete-confirm')), |
| 162 | ); |
| 163 | |
| 164 | $form['toolbar']['add_show'] = array( |
| 165 | '#type' => 'markup', |
| 166 | '#value' => theme("image", $module_path ."images/list-add.png", "add", NULL, array('id' => 'add-show')), |
| 167 | '#suffix' => '</div>', |
| 168 | ); |
| 169 | |
| 170 | $form['toolbar']['merge_show'] = array( |
| 171 | '#type' => 'button', |
| 172 | '#value' => t('Merge selected into...'), |
| 173 | '#theme' => 'no_submit_button', |
| 174 | '#prefix' => '<div id="taxonomy-toolbar-buttons">' |
| 175 | ); |
| 176 | |
| 177 | $form['toolbar']['move_show'] = array( |
| 178 | '#type' => 'button', |
| 179 | '#value' => t('Move selected to...'), |
| 180 | '#theme' => 'no_submit_button', |
| 181 | '#suffix' => '</div>' |
| 182 | ); |
| 183 | |
| 184 | $form['toolbar']['wrapper'] = array( |
| 185 | '#type' => 'markup', |
| 186 | '#value' => '<div id="taxonomy-toolbar-throbber"></div></div><div class="clear"></div>', |
| 187 | '#weight' => 20, |
| 188 | ); |
| 189 | |
| 190 | $form += taxonomy_manager_add_form(); |
| 191 | |
| 192 | $form += taxonomy_manager_merge_form($voc); |
| 193 | |
| 194 | $form += taxonomy_manager_move_form($voc); |
| 195 | |
| 196 | $form += taxonomy_manager_confirm_delete($voc); |
| 197 | |
| 198 | return $form; |
| 199 | } |
| 200 | |
| 201 | /** |
| 202 | * function gets called by the taxonomy_manager_tree form type (form_id +_operations) |
| 203 | * return an form array with values to show next to every term value |
| 204 | */ |
| 205 | function taxonomy_manager_tree_operations() { |
| 206 | $module_path = drupal_get_path('module', 'taxonomy_manager') .'/'; |
| 207 | $form = array(); |
| 208 | $form['up'] = array('#value' => theme("image", $module_path ."images/go-up-small.png", "go up", NULL, array('class' => 'term-up'))); |
| 209 | $form['down'] = array('#value' => theme("image", $module_path ."images/go-down-small.png", "go down", NULL, array('class' => 'term-down'))); |
| 210 | return $form; |
| 211 | } |
| 212 | |
| 213 | /** |
| 214 | * confirmation form for deleting selected terms |
| 215 | */ |
| 216 | function taxonomy_manager_confirm_delete($voc) { |
| 217 | drupal_add_js(array('hideForm' => array( |
| 218 | 'show_button' => 'delete-confirm', |
| 219 | 'hide_button' => 'edit-delete-cancel', |
| 220 | 'div' => 'del-confirm-form')), 'setting'); |
| 221 | |
| 222 | $text = t('Confirmation required! Remember all term specific data will be lost!'); |
| 223 | |
| 224 | $form = array(); |
| 225 | |
| 226 | $form['delete'] = array( |
| 227 | '#type' => 'fieldset', |
| 228 | '#tree' => TRUE, |
| 229 | '#title' => t('Confirmation'), |
| 230 | '#prefix' => '<div id="del-confirm-form">', |
| 231 | '#suffix' => '</div>', |
| 232 | ); |
| 233 | |
| 234 | $form['delete']['text'] = array( |
| 235 | '#value' => "<b>". $text ."</b>", |
| 236 | ); |
| 237 | |
| 238 | if ($voc->hierarchy != 0) { |
| 239 | $options = array( |
| 240 | 'delete_orphans' => t('Delete orphans'), |
| 241 | ); |
| 242 | |
| 243 | $form['delete']['options'] = array( |
| 244 | '#type' => 'checkboxes', |
| 245 | '#title' => t('Options'), |
| 246 | '#options' => $options, |
| 247 | ); |
| 248 | } |
| 249 | |
| 250 | $form['delete']['delete'] = array( |
| 251 | '#type' => 'submit', |
| 252 | '#value' => t('Delete'), |
| 253 | ); |
| 254 | |
| 255 | $form['delete']['cancel'] = array( |
| 256 | '#type' => 'button', |
| 257 | '#value' => t('Cancel'), |
| 258 | '#theme' => 'no_submit_button', |
| 259 | ); |
| 260 | |
| 261 | return $form; |
| 262 | } |
| 263 | |
| 264 | /** |
| 265 | * form for adding multiple terms |
| 266 | */ |
| 267 | function taxonomy_manager_add_form($hide_form = TRUE) { |
| 268 | if ($hide_form) { |
| 269 | drupal_add_js(array('hideForm' => array( |
| 270 | 'show_button' => 'add-show', |
| 271 | 'hide_button' => 'edit-add-cancel', |
| 272 | 'div' => 'add-form')), 'setting'); |
| 273 | } |
| 274 | |
| 275 | $form = array(); |
| 276 | |
| 277 | $form['add'] = array( |
| 278 | '#type' => 'fieldset', |
| 279 | '#tree' => TRUE, |
| 280 | '#title' => t('Add new terms'), |
| 281 | '#prefix' => '<div id="add-form">', |
| 282 | '#suffix' => '</div>', |
| 283 | '#description' => t('Depending on the hierarchy settings, you can set parents (one ore more). |
| 284 | Selected terms will get the parents of the new inserted'), |
| 285 | ); |
| 286 | |
| 287 | for ($i=0; $i<5; $i++) { |
| 288 | $form['add']['term'][$i] = array( |
| 289 | '#type' => 'textfield', |
| 290 | ); |
| 291 | } |
| 292 | $form['add']['add'] = array( |
| 293 | '#type' => 'submit', |
| 294 | '#value' => t('Add'), |
| 295 | ); |
| 296 | |
| 297 | $form['add']['cancel'] = array( |
| 298 | '#type' => 'button', |
| 299 | '#value' => t('Cancel'), |
| 300 | '#theme' => 'no_submit_button', |
| 301 | ); |
| 302 | |
| 303 | return $form; |
| 304 | |
| 305 | } |
| 306 | |
| 307 | /** |
| 308 | * form for merging terms |
| 309 | */ |
| 310 | function taxonomy_manager_merge_form($voc) { |
| 311 | drupal_add_js(array('hideForm' => array( |
| 312 | 'show_button' => 'edit-merge-show', |
| 313 | 'hide_button' => 'edit-merge-cancel', |
| 314 | 'div' => 'merge-form')), 'setting'); |
| 315 | |
| 316 | $form = array(); |
| 317 | |
| 318 | $form['merge'] = array( |
| 319 | '#type' => 'fieldset', |
| 320 | '#tree' => TRUE, |
| 321 | '#title' => t('Merging of terms'), |
| 322 | '#prefix' => '<div id="merge-form">', |
| 323 | '#suffix' => '</div>', |
| 324 | ); |
| 325 | |
| 326 | $help = t("You can choose either an exisiting term or either typ in a new |
| 327 | term, which will be created automatically, as main term (selected terms |
| 328 | get merged into this term)"); |
| 329 | |
| 330 | $form['merge']['main_term'] = array( |
| 331 | '#type' => 'textfield', |
| 332 | '#title' => t('Main term'), |
| 333 | '#description' => $help, |
| 334 | '#required' => FALSE, |
| 335 | '#autocomplete_path' => 'taxonomy/autocomplete/'. $voc->vid, |
| 336 | ); |
| 337 | |
| 338 | $options = array(); |
| 339 | |
| 340 | switch ($voc->hierarchy) { |
| 341 | //multiple hierarchy |
| 342 | case 2: |
| 343 | $options['collect_parents'] = t('Collect all parents of merging terms an add it to main term'); |
| 344 | |
| 345 | //single hierarchy |
| 346 | case 1: |
| 347 | $options['collect_children'] = t('Collect all children of merging terms an add it to main term'); |
| 348 | break; |
| 349 | } |
| 350 | |
| 351 | if ($voc->relations) { |
| 352 | $options['collect_relations'] = t('Collect all relations of merging terms and add it to main term'); |
| 353 | } |
| 354 | |
| 355 | if (count($options) > 0) { |
| 356 | $form['merge']['options'] = array( |
| 357 | '#type' => 'checkboxes', |
| 358 | '#title' => t('Options'), |
| 359 | '#options' => $options, |
| 360 | ); |
| 361 | } |
| 362 | |
| 363 | $form['merge']['submit'] = array( |
| 364 | '#type' => 'submit', |
| 365 | '#value' => t('Merge'), |
| 366 | ); |
| 367 | |
| 368 | $form['merge']['cancel'] = array( |
| 369 | '#type' => 'button', |
| 370 | '#value' => t('Cancel'), |
| 371 | '#theme' => 'no_submit_button', |
| 372 | ); |
| 373 | |
| 374 | return $form; |
| 375 | } |
| 376 | |
| 377 | /** |
| 378 | * form for moving terms in hierarchies |
| 379 | */ |
| 380 | function taxonomy_manager_move_form($voc) { |
| 381 | drupal_add_js(array('hideForm' => array( |
| 382 | 'show_button' => 'edit-move-show', |
| 383 | 'hide_button' => 'edit-move-cancel', |
| 384 | 'div' => 'move-form')), 'setting'); |
| 385 | |
| 386 | $form = array(); |
| 387 | |
| 388 | $form['move'] = array( |
| 389 | '#type' => 'fieldset', |
| 390 | '#tree' => TRUE, |
| 391 | '#title' => t('Moving of terms'), |
| 392 | '#prefix' => '<div id="move-form">', |
| 393 | '#suffix' => '</div>', |
| 394 | ); |
| 395 | |
| 396 | $help = t("You can choose either an exisiting term or either typ in a new |
| 397 | term, which will be created automatically, as parent term (selected terms |
| 398 | get children of this term). If multiple parents are allowed, you can seperate |
| 399 | more terms in the autocomplete form with ','. |
| 400 | If selected terms should have no parent, leave it blank!"); |
| 401 | |
| 402 | $form['move']['parents'] = array( |
| 403 | '#type' => 'textfield', |
| 404 | '#title' => t('Parent term(s)'), |
| 405 | '#description' => $help, |
| 406 | '#required' => FALSE, |
| 407 | '#autocomplete_path' => 'taxonomy/autocomplete/'. $voc->vid, |
| 408 | ); |
| 409 | |
| 410 | $options = array(); |
| 411 | |
| 412 | if ($voc->hierarchy == 2) { |
| 413 | $options['keep_old_parents'] = t('Don\'t delete old parents, only add new parents (multiple parents)'); |
| 414 | } |
| 415 | |
| 416 | if (count($options) > 0) { |
| 417 | $form['move']['options'] = array( |
| 418 | '#type' => 'checkboxes', |
| 419 | '#title' => t('Options'), |
| 420 | '#options' => $options, |
| 421 | ); |
| 422 | } |
| 423 | |
| 424 | $form['move']['submit'] = array( |
| 425 | '#type' => 'submit', |
| 426 | '#value' => t('Move'), |
| 427 | ); |
| 428 | |
| 429 | $form['move']['cancel'] = array( |
| 430 | '#type' => 'button', |
| 431 | '#value' => t('Cancel'), |
| 432 | '#theme' => 'no_submit_button', |
| 433 | ); |
| 434 | |
| 435 | return $form; |
| 436 | } |
| 437 | |
| 438 | |
| 439 | /** |
| 440 | * validates the form |
| 441 | */ |
| 442 | function taxonomy_manager_form_validate($form_id, $form_values) { |
| 443 | $selected_tids = array(); |
| 444 | |
| 445 | $selected_tids = $form_values['taxonomy_manager']['tree']['selected_terms']; |
| 446 | |
| 447 | switch ($form_values['op']) { |
| 448 | case t('Delete'): |
| 449 | if (count($selected_tids) < 1) { |
| 450 | form_set_error('delete', t("No terms selected")); |
| 451 | } |
| 452 | |
| 453 | break; |
| 454 | |
| 455 | case t('Add'): |
| 456 | //check for parents concerning voc settings |
| 457 | $voc = taxonomy_get_vocabulary($form_values['vid']); |
| 458 | |
| 459 | if ($voc->hierarchy == 0 && count($selected_tids) > 0) { |
| 460 | form_set_error('add', t('This vocabulary doesn\'t provide hierarchies. Please unselect terms in the list before adding new terms.')); |
| 461 | } |
| 462 | else if ($voc->hierarchy == 1 && count($selected_tids) > 1) { |
| 463 | form_set_error('add', t('This vocabulary provides only single hirarchies. Please select only one term in the list (at maximum)')); |
| 464 | } |
| 465 | |
| 466 | break; |
| 467 | |
| 468 | case t('Merge'): |
| 469 | $main_terms = array(); |
| 470 | $main_terms = taxonomy_manager_autocomplete_tags_get_tids($form_values['merge']['main_term'], $form_values['vid']); |
| 471 | if (count($main_terms) > 1) { |
| 472 | form_set_error('merge][main_term', t("The field %title doesn't allows multiple values", array('%title' => "'". t('Main term') ."'"))); |
| 473 | } |
| 474 | if (!is_numeric($main_terms[0]) || $main_terms[0] == 0) { |
| 475 | form_set_error('merge][main_term', t("Error reading input from %title", array('%title' => "'". t('Main term') ."'"))); |
| 476 | } |
| 477 | if (count($selected_tids) < 1) { |
| 478 | form_set_error('merge', t("No terms for merging selected")); |
| 479 | } |
| 480 | break; |
| 481 | |
| 482 | case t('Move'): |
| 483 | if (count($selected_tids) < 1) { |
| 484 | form_set_error('move', t("No terms selected")); |
| 485 | } |
| 486 | break; |
| 487 | } |
| 488 | } |
| 489 | |
| 490 | /** |
| 491 | * submits the taxonomy manager form |
| 492 | */ |
| 493 | function taxonomy_manager_form_submit($form_id, $form_values) { |
| 494 | $selected_tids = array(); |
| 495 | |
| 496 | $selected_tids = $form_values['taxonomy_manager']['tree']['selected_terms']; |
| 497 | |
| 498 | switch ($form_values['op']) { |
| 499 | case t('Delete'): |
| 500 | taxonomy_manager_delete_terms($selected_tids, $form_values['delete']['options']); |
| 501 | drupal_set_message("Selected terms deleted"); |
| 502 | break; |
| 503 | |
| 504 | case t('Add'): |
| 505 | foreach ($form_values['add']['term'] as $value) { |
| 506 | |
| 507 | if (!empty($value)) { |
| 508 | $term = array(); |
| 509 | $term['name'] = $value; |
| 510 | $term['vid'] = $form_values['vid']; |
| 511 | $term['parent'] = $selected_tids; |
| 512 | taxonomy_save_term($term); |
| 513 | } |
| 514 | } |
| 515 | drupal_set_message("Terms added"); |
| 516 | break; |
| 517 | |
| 518 | case t('Merge'): |
| 519 | $main_terms = taxonomy_manager_autocomplete_tags_get_tids($form_values['merge']['main_term'], $form_values['vid']); |
| 520 | $main_term = $main_terms[0]; |
| 521 | taxonomy_manager_merge($main_term, $selected_tids, $form_values['merge']['options']); |
| 522 | drupal_set_message("Terms merged"); |
| 523 | break; |
| 524 | |
| 525 | case t('Move'): |
| 526 | $parents = taxonomy_manager_autocomplete_tags_get_tids($form_values['move']['parents'], $form_values['vid']); |
| 527 | if (count($parents) == 0) $parents[0] = 0; //if empty, delete all parents |
| 528 | taxonomy_manager_move($parents, $selected_tids, $form_values['move']['options']); |
| 529 | |
| 530 | drupal_set_message("Terms moved"); |
| 531 | break; |
| 532 | |
| 533 | } |
| 534 | |
| 535 | drupal_goto('admin/content/taxonomy_manager/'. $form_values['vid']); |
| 536 | } |
| 537 | |
| 538 | /** |
| 539 | * checks if voc has already terms saved |
| 540 | * |
| 541 | * @param $vid voc id |
| 542 | * @return true, if terms already exists, else false |
| 543 | */ |
| 544 | function _taxonomy_manager_voc_is_empty($vid) { |
| 545 | $count = db_result(db_query("SELECT t.* FROM {term_data} t INNER JOIN {term_hierarchy} h ON t.tid = h.tid WHERE vid = %d AND h.parent = 0 LIMIT 0,1", $vid)); |
| 546 | if ($count == 0) return true; |
| 547 | return false; |
| 548 | } |
| 549 | |
| 550 | |
| 551 | /** |
| 552 | * deletes terms from the database |
| 553 | * optional orphans (terms where parent get deleted) can be deleted as well |
| 554 | * |
| 555 | * (difference to taxonomy_del_term: deletion of orphans optional) |
| 556 | * |
| 557 | * @param $tids array of term id to delete |
| 558 | * @param $options associative array with options |
| 559 | * if $options['delete_orphans'] is true, orphans get deleted |
| 560 | */ |
| 561 | function taxonomy_manager_delete_terms($tids, $options = array()) { |
| 562 | if (!is_array($tids)) array($tids); |
| 563 | while (count($tids) > 0) { |
| 564 | $orphans = array(); |
| 565 | foreach ($tids as $tid) { |
| 566 | if ($children = taxonomy_get_children($tid)) { |
| 567 | foreach ($children as $child) { |
| 568 | $parents = taxonomy_get_parents($child->tid); |
| 569 | if ($options['delete_orphans']) { |
| 570 | if (count($parents) == 1) { |
| 571 | $orphans[] = $child->tid; |
| 572 | } |
| 573 | } |
| 574 | else { |
| 575 | db_query("DELETE FROM {term_hierarchy} WHERE tid = %d AND parent = %d", $child->tid, $tid); |
| 576 | if (count($parents) == 1) { |
| 577 | if (!db_result(db_query("SELECT COUNT(*) FROM {term_hierarchy} WHERE tid = %d AND parent = 0", $child->tid))) { |
| 578 | db_query("INSERT INTO {term_hierarchy} (parent, tid) VALUES(0, %d)", $child->tid); |
| 579 | } |
| 580 | } |
| 581 | } |
| 582 | } |
| 583 | } |
| 584 | |
| 585 | db_query('DELETE FROM {term_data} WHERE tid = %d', $tid); |
| 586 | db_query('DELETE FROM {term_hierarchy} WHERE tid = %d', $tid); |
| 587 | db_query('DELETE FROM {term_relation} WHERE tid1 = %d OR tid2 = %d', $tid, $tid); |
| 588 | db_query('DELETE FROM {term_synonym} WHERE tid = %d', $tid); |
| 589 | db_query('DELETE FROM {term_node} WHERE tid = %d', $tid); |
| 590 | |
| 591 | $term = (array) taxonomy_get_term($tid); |
| 592 | module_invoke_all('taxonomy', 'delete', 'term', $term); |
| 593 | $tids = $orphans; |
| 594 | } |
| 595 | } |
| 596 | } |
| 597 | |
| 598 | |
| 599 | /** |
| 600 | * moves terms in hierarchies to other parents |
| 601 | * |
| 602 | * @param $parents |
| 603 | * array of parent term ids to where children can be moved |
| 604 | * array should only contain more parents if multi hiearchy enabled |
| 605 | * if array contains 0, terms get placed to first (root) level |
| 606 | * @param $children |
| 607 | * array of term ids to move |
| 608 | * @param $options |
| 609 | * array of additional options for moving |
| 610 | * 'keep_old_parents': if true, exisiting parents doesn't get deleted (only possible with multi hierarchies) |
| 611 | */ |
| 612 | function taxonomy_manager_move($parents, $children, $options = array()) { |
| 613 | if (!is_array($parents)) array($parents); |
| 614 | |
| 615 | foreach ($children as $child) { |
| 616 | if (!$options['keep_old_parents']) { |
| 617 | db_query("DELETE FROM {term_hierarchy} WHERE tid = %d", $child); |
| 618 | } |
| 619 | foreach ($parents as $parent) { |
| 620 | db_query("INSERT INTO {term_hierarchy} SET parent = %d, tid = %d", $parent, $child, $child); |
| 621 | } |
| 622 | } |
| 623 | } |
| 624 | |
| 625 | /** |
| 626 | * merges terms into another term (main term), all merged term get added |
| 627 | * to the main term as synonyms. |
| 628 | * term_node relations are updated automatically (node with one of merging terms gets main term assigned) |
| 629 | * after all opterions are done (adding of hierarchies, relations is optional) merging |
| 630 | * terms get deleted |
| 631 | * |
| 632 | * @param $main_term |
| 633 | * id of term where other terms get merged into |
| 634 | * @param $merging_terms |
| 635 | * array of term ids, which get merged into main term and afterwards deleted |
| 636 | * @param $options |
| 637 | * array with additional options, possible values: |
| 638 | * 'collect_parents': if true, all parents of merging terms get added to main term (only possible with multi hierarchies) |
| 639 | * 'collect_children': if true, all children of merging terms get added to main term |
| 640 | * 'collect_relations': if true, all relations of merging terms are transfered to main term |
| 641 | */ |
| 642 | function taxonomy_manager_merge($main_term, $merging_terms, $options = array()) { |
| 643 | //TODO: add hook, so that other modules can consider changes |
| 644 | foreach ($merging_terms as $merge_term) { |
| 645 | |
| 646 | //update node-relations |
| 647 | $sql = db_query("SELECT nid FROM {term_node} WHERE tid = %d", $merge_term); |
| 648 | while ($obj = db_fetch_object($sql)) { |
| 649 | $nid = $obj->nid; |
| 650 | db_query("DELETE FROM {term_node} WHERE tid = %d AND nid = %d", $merge_term, $nid); |
| 651 | if (!db_result(db_query("SELECT COUNT(*) FROM {term_node} WHERE tid = %d AND nid = %d", $main_term, $nid))) { |
| 652 | db_query("INSERT INTO {term_node} (tid, nid) VALUES (%d, %d)", $main_term, $nid); |
| 653 | } |
| 654 | } |
| 655 | |
| 656 | if ($options['collect_parents']) { |
| 657 | $parents = taxonomy_get_parents($merge_term); |
| 658 | foreach ($parents as $parent_tid => $parent_term) { |
| 659 | if (!db_result(db_query("SELECT COUNT(*) FROM {term_hierarchy} WHERE tid = %d AND parent = %d", $main_term, $parent_tid))) { |
| 660 | db_query("INSERT INTO {term_hierarchy} (tid, parent) VALUES (%d, %d)", $main_term, $parent_tid); |
| 661 | } |
| 662 | } |
| 663 | } |
| 664 | |
| 665 | if ($options['collect_children']) { |
| 666 | $children = taxonomy_get_children($merge_term); |
| 667 | foreach ($children as $child_tid => $child_term) { |
| 668 | if (!db_result(db_query("SELECT COUNT(*) FROM {term_hierarchy} WHERE tid = %d AND parent = %d", $child_tid, $main_term))) { |
| 669 | db_query("INSERT INTO {term_hierarchy} (tid, parent) VALUES (%d, %d)", $child_tid, $main_term); |
| 670 | } |
| 671 | } |
| 672 | } |
| 673 | |
| 674 | if ($options['collect_relations']) { |
| 675 | $relations = taxonomy_get_related($merge_term); |
| 676 | foreach ($relations as $related_tid => $relation) { |
| 677 | if ($relation->tid1 == $merge_term) { |
| 678 | if (!db_result(db_query("SELECT COUNT(*) FROM {term_relation} WHERE tid1 = %d AND tid2 = %d", $main_term, $related_tid))) { |
| 679 | db_query("INSERT INTO {term_relation} (tid1, tid2) VALUES (%d, %d)", $main_term, $related_tid); |
| 680 | } |
| 681 | } |
| 682 | else if ($relation->tid2 == $merge_term) { |
| 683 | if (!db_result(db_query("SELECT COUNT(*) FROM {term_relation} WHERE tid2 = %d AND tid1 = %d", $main_term, $related_tid))) { |
| 684 | db_query("INSERT INTO {term_relation} (tid2, tid1) VALUES (%d, %d)", $main_term, $related_tid); |
| 685 | } |
| 686 | } |
| 687 | } |
| 688 | } |
| 689 | |
| 690 | //save merged term as synonym |
| 691 | $term = taxonomy_get_term($merge_term); |
| 692 | if (!db_result(db_query("SELECT COUNT(*) FROM {term_synonym} WHERE tid = %d AND name = '%s'", $main_term, $term->name))) { |
| 693 | db_query("INSERT INTO {term_synonym} (tid, name) VALUES (%d, '%s')", $main_term, $term->name); |
| 694 | } |
| 695 | |
| 696 | taxonomy_manager_delete_terms(array($merge_term)); |
| 697 | } |
| 698 | } |
| 699 | |
| 700 | /** |
| 701 | * helper function for getting out of term ids from autocomplete fields |
| 702 | * non-exsiting terms get inserted autmatically |
| 703 | * (part of taxonomy_node_save) |
| 704 | * |
| 705 | * @param $typed_input input string of form field |
| 706 | * @param $vid vocabulary id |
| 707 | * @return array of term ids |
| 708 | */ |
| 709 | function taxonomy_manager_autocomplete_tags_get_tids($typed_input, $vid) { |
| 710 | $tids = array(); |
| 711 | |
| 712 | $regexp = '%(?:^|,\ *)("(?>[^"]*)(?>""[^"]* )*"|(?: [^",]*))%x'; |
| 713 | preg_match_all($regexp, $typed_input, $matches); |
| 714 | $typed_terms = array_unique($matches[1]); |
| 715 | |
| 716 | foreach ($typed_terms as $typed_term) { |
| 717 | $typed_term = str_replace('""', '"', preg_replace('/^"(.*)"$/', '\1', $typed_term)); |
| 718 | $typed_term = trim($typed_term); |
| 719 | if ($typed_term == "") { continue; } |
| 720 | |
| 721 | $possibilities = taxonomy_get_term_by_name($typed_term); |
| 722 | $typed_term_tid = NULL; // tid match if any. |
| 723 | foreach ($possibilities as $possibility) { |
| 724 | if ($possibility->vid == $vid) { |
| 725 | $typed_term_tid = $possibility->tid; |
| 726 | $tids[] = $typed_term_tid; |
| 727 | } |
| 728 | } |
| 729 | |
| 730 | if (!$typed_term_tid) { |
| 731 | $edit = array('vid' => $vid, 'name' => $typed_term); |
| 732 | $status = taxonomy_save_term($edit); |
| 733 | $typed_term_tid = $edit['tid']; |
| 734 | $tids[] = $typed_term_tid; |
| 735 | } |
| 736 | } |
| 737 | return $tids; |
| 738 | } |
| 739 | |
| 740 | /** |
| 741 | * callback for updating weights |
| 742 | * data send through AJAX, $_POST |
| 743 | * $_POST[$tid] => $weight |
| 744 | * |
| 745 | */ |
| 746 | function taxonomy_manager_update_weights($vid) { |
| 747 | $weights = $_POST; |
| 748 | if (is_array($weights)) { |
| 749 | foreach ($weights as $tid => $weight) { |
| 750 | if (is_numeric($tid) && is_numeric($weight)) { |
| 751 | if(_taxonomy_manager_tree_term_valid($tid, $vid)) { |
| 752 | db_query("UPDATE {term_data} SET weight = %d WHERE tid = %d", $weight, $tid); |
| 753 | } |
| 754 | } |
| 755 | } |
| 756 | } |
| 757 | exit(); |
| 758 | } |
| 759 | |
| 760 | |
| 761 | //if weightening in javascript gets slow, a way of calculating it on server side... |
| 762 | |
| 763 | /*function taxonomy_manager_update_weights($term_to_swap, $up, $parent = 0) { |
| 764 | $vid = db_result(db_query("SELECT vid FROM {term_data} WHERE tid = %d", $term_to_swap)); |
| 765 | $siblings = taxonomy_get_tree($vid, $parent, -1, 1); |
| 766 | $found = false; |
| 767 | for ($i=0; !$found && $i<count($siblings); $i++) { |
| 768 | if ($term_to_swap == $siblings[$i]->tid) { |
| 769 | $position = $i; |
| 770 | $found = true; |
| 771 | } |
| 772 | } |
| 773 | if ($up) { |
| 774 | $up_term = $siblings[$position]; |
| 775 | $down_term = $siblings[$position+1]; |
| 776 | $up_term->position = $position; |
| 777 | $down_term->position = $position+1; |
| 778 | } |
| 779 | else { |
| 780 | $up_term = $siblings[$position-1]; |
| 781 | $down_term = $siblings[$position]; |
| 782 | $up_term->position = $position-1; |
| 783 | $down_term->position = $position; |
| 784 | } |
| 785 | |
| 786 | $weights = taoxnomy_manager_swap_weights($up_term, $down_term, $siblings); |
| 787 | |
| 788 | foreach ($weights as $tid => $weight) { |
| 789 | db_query("UPDATE {term_data} SET weight = %d WHERE tid = %d", $weight, $tid); |
| 790 | } |
| 791 | } |
| 792 | |
| 793 | function taoxnomy_manager_swap_weights($up_term, $down_term, $siblings) { |
| 794 | $weights = array(); |
| 795 | |
| 796 | if ($up_term->weight == $down_term->weight) { |
| 797 | $weights[$up_term->tid] = $up_term->weight-1; |
| 798 | } |
| 799 | else { |
| 800 | $weights[$up_term->tid] = $down_term->weight; |
| 801 | $weights[$down_term->tid] = $up_term->weight; |
| 802 | } |
| 803 | |
| 804 | if ($siblings[$up_term->position-1]->weight == $up_term->weight) { |
| 805 | for ($i=0; $i<$up_term->position; $i++) { |
| 806 | $weights[$siblings[$i]->tid] = $siblings[$i]->weight-1; |
| 807 | } |
| 808 | } |
| 809 | else if ($siblings[$down_term->position+1]->weight == $down_term->weight) { |
| 810 | for ($i=$down_term->position; $i<count($siblings); $i++) { |
| 811 | $weights[$siblings[$i]->tid] = $siblings[$i]->weight+1; |
| 812 | } |
| 813 | } |
| 814 | |
| 815 | return $weights; |
| 816 | }*/ |
| 817 | |
| 818 | /** |
| 819 | * theme function for taxonomy manager form |
| 820 | */ |
| 821 | function theme_taxonomy_manager_form($form) { |
| 822 | $pager = theme('pager', NULL, TAXONOMY_MANAGER_TREE_PAGE_SIZE, 0); |
| 823 | $tree = drupal_render($form['taxonomy_manager']); |
| 824 | $top = drupal_render($form); |
| 825 | $output = $top . $pager . $tree; |
| 826 | |
| 827 | return $output; |
| 828 | } |
| 829 | |
| 830 | /** |
| 831 | * themes a real button form type (no form submit) |
| 832 | */ |
| 833 | function theme_no_submit_button($element) { |
| 834 | // Make sure not to overwrite classes. |
| 835 | if (isset($element['#attributes']['class'])) { |
| 836 | $element['#attributes']['class'] = 'form-'. $element['#button_type'] .' '. $element['#attributes']['class']; |
| 837 | } |
| 838 | else { |
| 839 | $element['#attributes']['class'] = 'form-'. $element['#button_type']; |
| 840 | } |
| 841 | |
| 842 | return '<input type="button" '. (empty($element['#name']) ? '' : 'name="'. $element['#name'] .'" ') .'id="'. $element['#id'].'" value="'. check_plain($element['#value']) .'" '. drupal_attributes($element['#attributes']) ." />\n"; |
| 843 | } |
| 844 | |
| 845 | |
| 846 | /****************************************** |
| 847 | * TAXONOMY TREE FORM ELEMENT DEFINITION |
| 848 | * |
| 849 | * how to use: |
| 850 | * $form['name'] = array( |
| 851 | * '#type' => 'taxonomy_manager_tree', |
| 852 | * '#vid' => $vid, |
| 853 | * ); |
| 854 | * |
| 855 | * additional parameter: |
| 856 | * #pager: TRUE / FALSE, |
| 857 | * whether to use pagers (drupal pager, load of nested children, load of siblings) |
| 858 | * or to load the whole tree on page generation |
| 859 | * #parent: only children on this parent will be loaded |
| 860 | * #siblings_page: current page for loading pf next siblings, internal use |
| 861 | * |
| 862 | * defining term operations: |
| 863 | * to add values (operations,..) to each term, add a function, which return a form array |
| 864 | * 'tree_form_id'_operations |
| 865 | * |
| 866 | * how to retrieve selected values: |
| 867 | * selected terms ids are available in validate / submit function in |
| 868 | * $form_values['name']['selected_terms']; |
| 869 | * |
| 870 | ******************************************/ |
| 871 | |
| 872 | /** |
| 873 | * Implementation of hook_elements |
| 874 | */ |
| 875 | function taxonomy_manager_elements() { |
| 876 | $type['taxonomy_manager_tree'] = array( |
| 877 | '#input' => TRUE, |
| 878 | '#process' => array('taxonomy_manager_tree_process_elements' => array()), |
| 879 | '#tree' => TRUE, |
| 880 | ); |
| 881 | |
| 882 | return $type; |
| 883 | } |
| 884 | |
| 885 | /** |
| 886 | * Processes the tree form element |
| 887 | * |
| 888 | * @param $element |
| 889 | * @return the tree element |
| 890 | */ |
| 891 | function taxonomy_manager_tree_process_elements($element) { |
| 892 | $module_path = drupal_get_path('module', 'taxonomy_manager') .'/'; |
| 893 | $id = form_clean_id(implode('-', $element['#parents'])); |
| 894 | |
| 895 | if (!$element['#parent'] && !$element['#siblings_page']) { |
| 896 | drupal_add_css($module_path .'css/taxonomy_manager.css'); |
| 897 | drupal_add_js($module_path .'js/tree.js'); |
| 898 | drupal_add_js($module_path .'js/childForm.js'); |
| 899 | drupal_add_js($module_path .'js/siblingsForm.js'); |
| 900 | |
| 901 | drupal_add_js(array('siblingsForm' => array('url' => url('admin/content/taxonomy_manager/siblingsform'), 'modulePath' => $module_path)), 'setting'); |
| 902 | drupal_add_js(array('childForm' => array('url' => url('admin/content/taxonomy_manager/childform'), 'modulePath' => $module_path)), 'setting'); |
| 903 | drupal_add_js(array('taxonomy_manager' => array('modulePath' => $module_path)), 'setting'); |
| 904 | drupal_add_js(array('taxonomytree' => array('id' => $id)), 'setting'); |
| 905 | } |
| 906 | |
| 907 | if (!is_array($element['#operations'])) { |
| 908 | $opertions_callback = implode('_', $element['#parents']) .'_operations'; |
| 909 | if (function_exists($opertions_callback)) { |
| 910 | $element['#operations'] = $opertions_callback(); |
| 911 | } |
| 912 | } |
| 913 | |
| 914 | $vid = $element['#vid']; |
| 915 | $tree = _taxonomy_manager_tree_get_item($element['#vid'], $element['#parent'], $element['#pager'], $element['#siblings_page']); |
| 916 | |
| 917 | if ($element['#pager'] && !($element['#parent'] || $element['#siblings_page'])) { |
| 918 | $element['pager'] = array('#value' => theme('pager', NULL, TAXONOMY_MANAGER_TREE_PAGE_SIZE)); |
| 919 | } |
| 920 | $element['#tree'] = TRUE; |
| 921 | $element['#id'] = $id; |
| 922 | $element['#validate'] = array('taxonomy_manager_tree_validate' => array()); |
| 923 | $element['selected_terms'] = array('#type' => 'value', '#value' => array()); |
| 924 | |
| 925 | taxonomy_manager_tree_build_form($index = 0, $tree, $element['#elements'], $element, $element['#parents'], !$element['#pager'], $element['#siblings_page']); |
| 926 | |
| 927 | return $element; |
| 928 | } |
| 929 | |
| 930 | /** |
| 931 | * loads tree with terms (depending on various settings) |
| 932 | * |
| 933 | * @param $vid |
| 934 | * @param $parent |
| 935 | * @param $pager |
| 936 | * @param $siblings_page |
| 937 | * @return array with term elements |
| 938 | */ |
| 939 | function _taxonomy_manager_tree_get_item($vid, $parent = 0, $pager = FALSE, $siblings_page = 0) { |
| 940 | $tree = array(); |
| 941 | if ($pager) { |
| 942 | if ($parent || $siblings_page) { |
| 943 | $start = ($siblings_page-1) * TAXONOMY_MANAGER_TREE_PAGE_SIZE; |
| 944 | $result = db_query_range("SELECT t.* FROM {term_data} t INNER JOIN {term_hierarchy} h ON t.tid = h.tid WHERE vid = %d AND h.parent = %d ORDER BY weight, name", $vid, $parent, $start, TAXONOMY_MANAGER_TREE_PAGE_SIZE); |
| 945 | } |
| 946 | else { |
| 947 | $result = pager_query("SELECT t.* FROM {term_data} t INNER JOIN {term_hierarchy} h ON t.tid = h.tid WHERE vid = %d AND h.parent = 0 ORDER BY weight, name", TAXONOMY_MANAGER_TREE_PAGE_SIZE, 0, NULL, array($vid)); |
| 948 | } |
| 949 | |
| 950 | while ($term = db_fetch_object($result)) { |
| 951 | $tree[] = $term; |
| 952 | } |
| 953 | } |
| 954 | else { |
| 955 | $tree = taxonomy_get_tree($vid, $parent); |
| 956 | } |
| 957 | |
| 958 | return $tree; |
| 959 | } |
| 960 | |
| 961 | /** |
| 962 | * recursive function for building nested form array |
| 963 | * with checkboxes and weight forms for each term |
| 964 | * |
| 965 | * nested form array are allways appended to parent-form['children'] |
| 966 | * |
| 967 | * @param $index current index in tree, start with 0 |
| 968 | * @param $tree of terms (generated by taxonomy_get_tree) |
| 969 | * @return a form array |
| 970 | */ |
| 971 | function taxonomy_manager_tree_build_form(&$index, $tree, &$form, $root_form, $parents = array(), $build_subtrees = TRUE, $page = 0) { |
| 972 | |
| 973 | $current_depth = $tree[$index]->depth; |
| 974 | while ($index < count($tree) && $tree[$index]->depth >= $current_depth) { |
| 975 | $term = $tree[$index]; |
| 976 | |
| 977 | $attributes = array(); |
| 978 | |
| 979 | $this_parents = $parents; |
| 980 | $this_parents[] = $term->tid; |
| 981 | |
| 982 | $form[$term->tid]['checkbox'] = array('#type' => 'checkbox', '#title' => $term->name, '#return_value' => 1); |
| 983 | $form[$term->tid]['weight'] = array('#type' => 'hidden', '#value' => $term->weight, '#attributes' => array('class' => 'weight-form')); |
| 984 | $form[$term->tid]['tid'] = array('#type' => 'hidden', '#value' => $term->tid, '#attributes' => array('class' => 'term-id')); |
| 985 | |
| 986 | if (is_array($root_form['#operations'])) { |
| 987 | $form[$term->tid]['operations'] = $root_form['#operations']; |
| 988 | } |
| 989 | |
| 990 | if ($page) { |
| 991 | if ($index == (TAXONOMY_MANAGER_TREE_PAGE_SIZE - 1)) { |
| 992 | $module_path = drupal_get_path('module', 'taxonomy_manager') .'/'; |
| 993 | $form[$term->tid]['has-more-siblings'] = array( |
| 994 | '#type' => 'markup', |
| 995 | '#value' => theme("image", $module_path ."images/2downarrow.png", "more", NULL, array('class' => 'load-siblings')), |
| 996 | ); |
| 997 | $form[$term->tid]['page'] = array( |
| 998 | '#type' => 'hidden', |
| 999 | '#value' => $page, |
| 1000 | '#attributes' => array('class' => 'page'), |
| 1001 | ); |
| 1002 | $next_count = _taxonomy_manager_tree_get_next_siblings_count($term->vid, $page, $root_form['#parent']); |
| 1003 | $form[$term->tid]['next_count'] = array('#value' => $next_count); |
| 1004 | $form[$term->tid]['#attributes']['class'] .= 'has-more-siblings '; |
| 1005 | } |
| 1006 | } |
| 1007 | |
| 1008 | _taxonomy_manager_tree_element_set_params($this_parents, $form[$term->tid]); |
| 1009 | |
| 1010 | $index++; |
| 1011 | |
| 1012 | if ($build_subtrees) { |
| 1013 | if ($tree[$index]->depth > $current_depth) { |
| 1014 | $form[$term->tid]['#attributes']['class'] .= _taxonomy_manager_tree_term_get_class($index-1, $tree); |
| 1015 | taxonomy_manager_tree_build_form($index, $tree, $form[$term->tid]['children'], $root_form, array_merge($this_parents, array('children'))); |
| 1016 | } |
| 1017 | else { |
| 1018 | if ((count($tree)-1 == $index-1) || ($tree[$index]->depth < $current_depth)) { |
| 1019 | $form[$term->tid]['#attributes']['class'] .= 'last '; |
| 1020 | } |
| 1021 | } |
| 1022 | } |
| 1023 | else { |
| 1024 | if (_taxonomy_manager_tree_term_has_children($term->tid)) { |
| 1025 | $form[$term->tid]['#attributes']['class'] .= 'has-children '; |
| 1026 | if ($index-1 == count($tree)-1) { |
| 1027 | $form[$term->tid]['#attributes']['class'] .= 'lastExpandable '; |
| 1028 | } |
| 1029 | else { |
| 1030 | $form[$term->tid]['#attributes']['class'] .= 'expandable '; |
| 1031 | } |
| 1032 | } |
| 1033 | else { |
| 1034 | if ($index-1 == count($tree)-1) { |
| 1035 | $form[$term->tid]['#attributes']['class'] .= 'last '; |
| 1036 | } |
| 1037 | } |
| 1038 | } |
| 1039 | } |
| 1040 | } |
| 1041 | |
| 1042 | /** |
| 1043 | * adds #id and #name to all form elements |
| 1044 | * |
| 1045 | * @param $parents |
| 1046 | * @param $form |
| 1047 | */ |
| 1048 | function _taxonomy_manager_tree_element_set_params($parents, &$form) { |
| 1049 | foreach (element_children($form) as $field_name) { |
| 1050 | $field_parents = array_merge($parents, array($field_name)); |
| 1051 | $form[$field_name]['#tree'] = TRUE; |
| 1052 | $form[$field_name]['#post'] = array(); |
| 1053 | $form[$field_name]['#parents'] = $field_parents; |
| 1054 | $form[$field_name]['#id'] = form_clean_id('edit-'. implode('-', $field_parents)); |
| 1055 | $form[$field_name]['#name'] = array_shift($field_parents) .'['. implode('][', $field_parents) .']'; |
| 1056 | } |
| 1057 | } |
| 1058 | |
| 1059 | /** |
| 1060 | * calculates class type (expandable, lastExpandable) for current element |
| 1061 | * |
| 1062 | * @param $current_index in tree array |
| 1063 | * @param $tree array with terms |
| 1064 | * @return expandable or lastExpandable |
| 1065 | */ |
| 1066 | function _taxonomy_manager_tree_term_get_class($current_index, $tree) { |
| 1067 | $class = ''; |
| 1068 | $term = $tree[$current_index]; |
| 1069 | $next = $tree[++$current_index]; |
| 1070 | $children = false; |
| 1071 | while ($next->depth > $term->depth) { |
| 1072 | $children = true; |
| 1073 | $next = $tree[++$current_index]; |
| 1074 | } |
| 1075 | |
| 1076 | if ($next->depth == $term->depth) { |
| 1077 | $class = 'expandable '; |
| 1078 | } |
| 1079 | else { |
| 1080 | $class = 'lastExpandable '; |
| 1081 | } |
| 1082 | return $class; |
| 1083 | } |
| 1084 | |
| 1085 | /** |
| 1086 | * checks if a term has children |
| 1087 | * |
| 1088 | * @param $tid |
| 1089 | * @return true, if term has children, else false |
| 1090 | */ |
| 1091 | function _taxonomy_manager_tree_term_has_children($tid) { |
| 1092 | $count = db_result(db_query("SELECT COUNT(tid) FROM {term_hierarchy} WHERE parent = %d", $tid)); |
| 1093 | if ($count == 0) { |
| 1094 | return false; |
| 1095 | } |
| 1096 | return true; |
| 1097 | } |
| 1098 | |
| 1099 | /** |
| 1100 | * calculates number of next siblings if using paging |
| 1101 | * |
| 1102 | * @param $vid |
| 1103 | * @param $page |
| 1104 | * @param $parent |
| 1105 | * @return next page size |
| 1106 | */ |
| 1107 | function _taxonomy_manager_tree_get_next_siblings_count($vid, $page, $parent = 0) { |
| 1108 | $count = db_result(db_query("SELECT COUNT(t.tid) FROM {term_data} t INNER JOIN {term_hierarchy} h ON t.tid = h.tid WHERE vid = %d AND h.parent = %d", $vid, $parent)); |
| 1109 | $current_count = TAXONOMY_MANAGER_TREE_PAGE_SIZE * $page; |
| 1110 | $diff = $count - $current_count; |
| 1111 | |
| 1112 | if ($diff > TAXONOMY_MANAGER_TREE_PAGE_SIZE) { |
| 1113 | $diff = TAXONOMY_MANAGER_TREE_PAGE_SIZE; |
| 1114 | } |
| 1115 | |
| 1116 | return $diff; |
| 1117 | } |
| 1118 | |
| 1119 | /** |
| 1120 | * callback for generating and rendering nested child forms (AHAH) |
| 1121 | * |
| 1122 | * @param $tree_id |
| 1123 | * @param $parent term id of parent, that is expanded and of which children have to be loaded |
| 1124 | */ |
| 1125 | function taxonomy_manager_tree_build_child_form($tree_id, $parent) { |
| 1126 | $vid = db_result(db_query("SELECT vid FROM {term_data} WHERE tid = %d", $parent)); |
| 1127 | |
| 1128 | $child_form = array( |
| 1129 | '#type' => 'taxonomy_manager_tree', |
| 1130 | '#vid' => $vid, |
| 1131 | '#parent' => $parent, |
| 1132 | '#pager' => TRUE, |
| 1133 | '#siblings_page' => 1, |
| 1134 | ); |
| 1135 | |
| 1136 | $opertions_callback = str_replace('-', '_', $tree_id) .'_operations'; |
| 1137 | if (function_exists($opertions_callback)) { |
| 1138 | $child_form['#operations'] = $opertions_callback(); |
| 1139 | } |
| 1140 | |
| 1141 | _taxonomy_manager_tree_sub_forms_set_parents($tree_id, $parent, $child_form); |
| 1142 | |
| 1143 | $child_form = form_builder('taxonomy_manager_form', $child_form); |
| 1144 | |
| 1145 | print drupal_render($child_form); |
| 1146 | |
| 1147 | exit(); |
| 1148 | } |
| 1149 | |
| 1150 | /** |
| 1151 | * callback for generating and rendering next siblings terms form (AHAH) |
| 1152 | * |
| 1153 | * @param $tree_id |
| 1154 | * @param $page current page |
| 1155 | * @param $prev_tid last sibling, that appears |
| 1156 | * @param $parent if in hierarchies, parent id |
| 1157 | */ |
| 1158 | function taxonomy_manager_tree_build_siblings_form($tree_id, $page, $prev_tid, $parent = 0) { |
| 1159 | $vid = db_result(db_query("SELECT vid FROM {term_data} WHERE tid = %d", $prev_tid)); |
| 1160 | |
| 1161 | $siblings_form = array( |
| 1162 | '#type' => 'taxonomy_manager_tree', |
| 1163 | '#vid' => $vid, |
| 1164 | '#parent' => $parent, |
| 1165 | '#pager' => TRUE, |
| 1166 | '#siblings_page' => $page+1, |
| 1167 | ); |
| 1168 | |
| 1169 | $opertions_callback = str_replace('-', '_', $tree_id) .'_operations'; |
| 1170 | if (function_exists($opertions_callback)) { |
| 1171 | $child_form['#operations'] = $opertions_callback(); |
| 1172 | } |
| 1173 | |
| 1174 | _taxonomy_manager_tree_sub_forms_set_parents($tree_id, $parent, $siblings_form); |
| 1175 |