| Textpattern | PHP Cross Reference | Content Management Systems |
1 <?php 2 3 /* 4 This is Textpattern 5 6 Copyright 2005 by Dean Allen 7 www.textpattern.com 8 All rights reserved 9 10 Use of this software indicates acceptance of the Textpattern license agreement 11 12 $HeadURL: https://textpattern.googlecode.com/svn/releases/4.5.4/source/textpattern/include/txp_category.php $ 13 $LastChangedRevision: 4089 $ 14 */ 15 16 if (!defined('txpinterface')) die('txpinterface is undefined.'); 17 18 if ($event == 'category') { 19 require_privs('category'); 20 21 $available_steps = array( 22 'cat_category_list' => false, 23 'cat_category_multiedit' => true, 24 'cat_article_create' => true, 25 'cat_image_create' => true, 26 'cat_file_create' => true, 27 'cat_link_create' => true, 28 'cat_article_save' => true, 29 'cat_image_save' => true, 30 'cat_file_save' => true, 31 'cat_link_save' => true, 32 'cat_article_edit' => false, 33 'cat_image_edit' => false, 34 'cat_file_edit' => false, 35 'cat_link_edit' => false, 36 ); 37 38 if ($step && bouncer($step, $available_steps)){ 39 $step(); 40 } else { 41 cat_category_list(); 42 } 43 } 44 45 //------------------------------------------------------------- 46 function cat_category_list($message="") 47 { 48 pagetop(gTxt('categories'),$message); 49 $out = array('<h1 class="txp-heading">'.gTxt('tab_organise').'</h1>', 50 '<div id="category_container" class="txp-container">', 51 '<table class="category-list">', 52 '<tr>', 53 tdtl('<div id="categories_article">'.cat_article_list().'</div>',' class="categories article"'), 54 tdtl('<div id="categories_link">'.cat_link_list().'</div>',' class="categories link"'), 55 tdtl('<div id="categories_image">'.cat_image_list().'</div>',' class="categories image"'), 56 tdtl('<div id="categories_file">'.cat_file_list().'</div>',' class="categories file"'), 57 '</tr>', 58 endTable(), 59 '</div>', 60 script_js( <<<EOS 61 $(document).ready(function() { 62 $('.category-tree').txpMultiEditForm({ 63 'row' : 'p', 64 'highlighted' : 'p' 65 }); 66 }); 67 EOS 68 )); 69 echo join(n,$out); 70 } 71 72 73 //------------------------------------------------------------- 74 function cat_article_list() 75 { 76 return cat_event_category_list('article'); 77 } 78 79 //------------------------------------------------------------- 80 function cat_article_create() 81 { 82 return cat_event_category_create('article'); 83 } 84 85 //------------------------------------------------------------- 86 function cat_article_edit() 87 { 88 return cat_event_category_edit('article'); 89 } 90 91 //------------------------------------------------------------- 92 function cat_article_save() 93 { 94 return cat_event_category_save('article', 'textpattern'); 95 } 96 97 //-------------------------------------------------------------- 98 99 function cat_parent_pop($name, $type, $id) 100 { 101 if ($id) 102 { 103 $id = assert_int($id); 104 list($lft, $rgt) = array_values(safe_row('lft, rgt', 'txp_category', 'id = '.$id)); 105 106 $rs = getTree('root', $type, "lft not between $lft and $rgt"); 107 } 108 109 else 110 { 111 $rs = getTree('root', $type); 112 } 113 114 if ($rs) 115 { 116 return array(treeSelectInput('parent', $rs, $name, 'category_parent'), true); 117 } 118 119 return array(gTxt('no_other_categories_exist'), false); 120 } 121 122 // ------------------------------------------------------------- 123 function cat_link_list() 124 { 125 return cat_event_category_list('link'); 126 } 127 128 //------------------------------------------------------------- 129 function cat_link_create() 130 { 131 return cat_event_category_create('link'); 132 } 133 134 //------------------------------------------------------------- 135 function cat_link_edit() 136 { 137 return cat_event_category_edit('link'); 138 } 139 140 //------------------------------------------------------------- 141 function cat_link_save() 142 { 143 return cat_event_category_save('link', 'txp_link'); 144 } 145 146 // ------------------------------------------------------------- 147 function cat_image_list() 148 { 149 return cat_event_category_list('image'); 150 } 151 152 //------------------------------------------------------------- 153 function cat_image_create() 154 { 155 return cat_event_category_create('image'); 156 } 157 158 //------------------------------------------------------------- 159 function cat_image_edit() 160 { 161 return cat_event_category_edit('image'); 162 } 163 164 //------------------------------------------------------------- 165 function cat_image_save() 166 { 167 return cat_event_category_save('image', 'txp_image'); 168 } 169 170 171 // ------------------------------------------------------------- 172 function cat_article_multiedit_form($area, $array) 173 { 174 $rs = getTree('root', $area); 175 $categories = $rs ? treeSelectInput('new_parent', $rs, '') : ''; 176 177 $methods = array( 178 'changeparent' => array('label' => gTxt('changeparent'), 'html' => $categories), 179 'deleteforce' => gTxt('deleteforce'), 180 'delete' => gTxt('delete'), 181 ); 182 183 if ($array) { 184 return 185 form( 186 join('',$array). 187 hInput('type',$area). 188 n.multi_edit($methods, 'category', 'cat_category_multiedit', '', '', '', '', '', $area) 189 ,'', '', 'post', 'category-tree', '', 'category_'.$area.'_form' 190 ); 191 } 192 return; 193 } 194 195 // ------------------------------------------------------------- 196 function cat_category_multiedit() 197 { 198 $type = ps('type'); 199 $method = ps('edit_method'); 200 $things = ps('selected'); 201 202 if (is_array($things) and $things and in_array($type, array('article','image','link','file'))) 203 { 204 $things = array_map('assert_int', $things); 205 206 if ($method == 'delete' || $method == 'deleteforce') 207 { 208 if ($type === 'article') 209 { 210 $used = 'name NOT IN(SELECT category1 FROM '.safe_pfx('textpattern').')'. 211 ' AND name NOT IN(SELECT category2 FROM '.safe_pfx('textpattern').')'; 212 } 213 else 214 { 215 $used = 'name NOT IN(SELECT category FROM '.safe_pfx('txp_'.$type).')'; 216 } 217 218 $rs = safe_rows('id, name', 'txp_category', "id IN (".join(',', $things).") AND type='".$type."'" . (($method == 'deleteforce') ? '' : " AND rgt - lft = 1 AND ".$used)); 219 220 if ($rs) 221 { 222 foreach($rs as $cat) 223 { 224 $catid[] = $cat['id']; 225 $names[] = doSlash($cat['name']); 226 } 227 228 if (safe_delete('txp_category','id IN ('.join(',', $catid).')')) 229 { 230 if ($method == 'deleteforce') 231 { 232 // Clear the deleted category names from assets 233 $affected = join("','", $names); 234 if($type === 'article') 235 { 236 safe_update('textpattern', "category1 = ''", "category1 IN ('$affected')"); 237 safe_update('textpattern', "category2 = ''", "category2 IN ('$affected')"); 238 } 239 else 240 { 241 safe_update('txp_'.$type, "category = ''", "category IN ('$affected')"); 242 } 243 244 // Promote subcats of deleted cats to root 245 safe_update('txp_category', "parent='root'", "parent IN ('$affected')"); 246 } 247 248 rebuild_tree_full($type); 249 callback_event('categories_deleted', $type, 0, $catid); 250 251 $message = gTxt($type.'_categories_deleted', array('{list}' => join(', ',$catid))); 252 253 return cat_category_list($message); 254 } 255 } 256 } 257 258 else if ($method == 'changeparent') 259 { 260 $new_parent = ps('new_parent'); 261 262 $rs = safe_rows('id, name', 'txp_category', "id IN (".join(',', $things).") AND type='".$type."'"); 263 264 if ($rs) 265 { 266 $exists = safe_field('name', 'txp_category', "name = '".doSlash($new_parent)."' AND type='$type'"); 267 $parent = ($exists == '') ? 'root' : $exists; 268 $to_change = $affected = array(); 269 270 foreach($rs as $cat) 271 { 272 // Cannot assign parent to itself 273 if ($cat['name'] != $new_parent) 274 { 275 $to_change[] = doSlash($cat['name']); 276 $affected[] = $cat['name']; 277 } 278 } 279 280 $ret = safe_update('txp_category', "parent='".doSlash($parent)."'", "name IN ('".join("','", $to_change)."') AND type='".$type."'"); 281 282 if ($ret) 283 { 284 rebuild_tree_full($type); 285 286 $message = gTxt('categories_set_parent', array('{type}' => gTxt($type), '{parent}' => $parent, '{list}' => join(', ',$affected))); 287 288 return cat_category_list($message); 289 } 290 } 291 } 292 } 293 294 return cat_category_list(); 295 } 296 297 //Refactoring: Functions are more or less the same for all event types 298 // so, merge them. Addition of new event categories is easiest now. 299 300 //------------------------------------------------------------- 301 302 function cat_event_category_list($event) 303 { 304 $rs = getTree('root', $event); 305 306 $parent = ps('parent_cat'); 307 308 $heading = 'tab_' . ($event == 'article' ? 'list' : $event); 309 $for = $rs ? ' for="'.$event.'_category_parent"' : ''; 310 311 $out = n.n.hed(gTxt($heading).sp.popHelp($event.'_category'), 2). 312 form( 313 fInput('text', 'title', '', '', '', '', INPUT_REGULAR). 314 (($rs) ? '<div class="parent"><label'.$for.'>' . gTxt('parent') . '</label>' . treeSelectInput('parent_cat', $rs, $parent, $event.'_category_parent') . '</div>' : ''). 315 n.fInput('submit', '', gTxt('Create')). 316 n.eInput('category'). 317 n.sInput('cat_'.$event.'_create') 318 ,'', '', 'post', 'action-create '.$event); 319 320 if ($rs) 321 { 322 $total_count = array(); 323 324 if ($event == 'article') 325 { 326 // Count distinct articles for both categories, avoid duplicates 327 $rs2 = getRows( 328 'select category, count(*) as num from ('. 329 'select ID, Category1 as category from '.safe_pfx('textpattern'). 330 ' union '. 331 'select ID, Category2 as category from '.safe_pfx('textpattern'). 332 ') as t where category != "" group by category'); 333 334 if ($rs2 !== false) 335 { 336 foreach ($rs2 as $a) 337 { 338 $total_count[$a['category']] = $a['num']; 339 } 340 } 341 } 342 343 else 344 { 345 switch ($event) 346 { 347 case 'link': 348 $rs2 = safe_rows_start('category, count(*) as num', 'txp_link', "1 group by category"); 349 break; 350 351 case 'image': 352 $rs2 = safe_rows_start('category, count(*) as num', 'txp_image', "1 group by category"); 353 break; 354 355 case 'file': 356 $rs2 = safe_rows_start('category, count(*) as num', 'txp_file', "1 group by category"); 357 break; 358 } 359 360 while ($a = nextRow($rs2)) 361 { 362 $name = $a['category']; 363 $num = $a['num']; 364 365 $total_count[$name] = $num; 366 } 367 } 368 369 $items = array(); 370 371 foreach ($rs as $a) 372 { 373 extract($a); 374 375 // format count 376 switch ($event) 377 { 378 case 'article': 379 $url = 'index.php?event=list'.a.'search_method=categories'.a.'crit='.$name; 380 break; 381 382 case 'link': 383 $url = 'index.php?event=link'.a.'search_method=category'.a.'crit='.$name; 384 break; 385 386 case 'image': 387 $url = 'index.php?event=image'.a.'search_method=category'.a.'crit='.$name; 388 break; 389 390 case 'file': 391 $url = 'index.php?event=file'.a.'search_method=category'.a.'crit='.$name; 392 break; 393 } 394 395 $count = isset($total_count[$name]) ? href('('.$total_count[$name].')', $url) : '(0)'; 396 397 if (empty($title)) { 398 $edit_link = '<em>'.eLink('category', 'cat_'.$event.'_edit', 'id', $id, gTxt('untitled')).'</em>'; 399 } else { 400 $edit_link = eLink('category', 'cat_'.$event.'_edit', 'id', $id, $title); 401 } 402 403 $items[] = graf( 404 checkbox('selected[]', $id, 0).sp.str_repeat(sp.sp, $level * 2).$edit_link.sp.$count 405 , ' class="level-'.$level.'"'); 406 } 407 408 if ($items) 409 { 410 $out .= cat_article_multiedit_form($event, $items); 411 } 412 } 413 414 else 415 { 416 $out .= graf(gTxt('no_categories_exist')); 417 } 418 419 return $out; 420 } 421 422 //------------------------------------------------------------- 423 424 function cat_event_category_create($event) 425 { 426 $title = ps('title'); 427 428 $name = strtolower(sanitizeForUrl($title)); 429 430 if (!$name) 431 { 432 $message = array(gTxt($event.'_category_invalid', array('{name}' => $name)), E_ERROR); 433 434 return cat_category_list($message); 435 } 436 437 $exists = safe_field('name', 'txp_category', "name = '".doSlash($name)."' and type = '".doSlash($event)."'"); 438 439 if ($exists) 440 { 441 $message = array(gTxt($event.'_category_already_exists', array('{name}' => $name)), E_ERROR); 442 443 return cat_category_list($message); 444 } 445 446 $parent = strtolower(sanitizeForUrl(ps('parent_cat'))); 447 $parent_exists = safe_field('name', 'txp_category', "name = '".doSlash($parent)."' and type = '".doSlash($event)."'"); 448 $parent = ($parent_exists) ? $parent_exists : 'root'; 449 450 $q = safe_insert('txp_category', "name = '".doSlash($name)."', title = '".doSlash($title)."', type = '".doSlash($event)."', parent = '".$parent."'"); 451 452 if ($q) 453 { 454 rebuild_tree_full($event); 455 456 $message = gTxt($event.'_category_created', array('{name}' => $name)); 457 458 cat_category_list($message); 459 } 460 else 461 { 462 cat_category_list(array(gTxt('category_save_failed'), E_ERROR)); 463 } 464 } 465 466 //------------------------------------------------------------- 467 468 function cat_event_category_edit($evname) 469 { 470 $id = assert_int(gps('id')); 471 $parent = doSlash(gps('parent')); 472 473 $row = safe_row('*', 'txp_category', "id=$id"); 474 if ($row) { 475 pagetop(gTxt('edit_category')); 476 extract($row); 477 list($parent_widget, $has_parent) = cat_parent_pop($parent,$evname,$id); 478 $out = '<div class="txp-edit">'.n. 479 hed(gTxt('edit_category'), 2).n. 480 inputLabel('category_name', fInput('text', 'name', $name, '', '', '', INPUT_REGULAR, '', 'category_name'), $evname.'_category_name').n. 481 ($has_parent ? inputLabel('category_parent', $parent_widget, 'parent') : graf('<span class="edit-label">'.gTxt('parent').'</span><span class="edit-value">'.$parent_widget.'</span>')).n. 482 inputLabel('category_title', fInput('text', 'title', $title, '', '', '', INPUT_REGULAR, '', 'category_title'), $evname.'_category_title').n. 483 pluggable_ui('category_ui', 'extend_detail_form', '', $row).n. 484 hInput('id',$id). 485 graf(fInput('submit', '', gTxt('save'), 'publish')). 486 eInput('category'). 487 sInput('cat_'.$evname.'_save'). 488 hInput('old_name',$name). 489 '</div>'; 490 echo '<div id="category_container" class="txp-container">'. 491 form( $out, '', '', 'post', 'edit-form' ). 492 '</div>'; 493 } else { 494 cat_category_list(array(gTxt('category_not_found'), E_ERROR)); 495 } 496 } 497 498 //------------------------------------------------------------- 499 500 function cat_event_category_save($event, $table_name) 501 { 502 extract(doSlash(array_map('assert_string', psa(array('id', 'name', 'old_name', 'parent', 'title'))))); 503 $id = assert_int($id); 504 505 $name = sanitizeForUrl($name); 506 507 // make sure the name is valid 508 if (!$name) 509 { 510 $message = array(gTxt($event.'_category_invalid', array('{name}' => $name)), E_ERROR); 511 512 return cat_category_list($message); 513 } 514 515 // don't allow rename to clobber an existing category 516 $existing_id = safe_field('id', 'txp_category', "name = '$name' and type = '$event'"); 517 518 if ($existing_id and $existing_id != $id) 519 { 520 $message = array(gTxt($event.'_category_already_exists', array('{name}' => $name)), E_ERROR); 521 522 return cat_category_list($message); 523 } 524 525 //TODO: validate parent? 526 $parent = ($parent) ? $parent : 'root'; 527 528 $message = array(gTxt('category_save_failed'), E_ERROR); 529 if (safe_update('txp_category', "name = '$name', parent = '$parent', title = '$title'", "id = $id") && 530 safe_update('txp_category', "parent = '$name'", "parent = '$old_name'")) 531 { 532 rebuild_tree_full($event); 533 534 if ($event == 'article') 535 { 536 if (safe_update('textpattern', "Category1 = '$name'", "Category1 = '$old_name'") && 537 safe_update('textpattern', "Category2 = '$name'", "Category2 = '$old_name'")) 538 { 539 $message = gTxt($event.'_category_updated', array('{name}' => doStrip($name))); 540 } 541 } 542 else 543 { 544 if (safe_update($table_name, "category = '$name'", "category = '$old_name'")) 545 { 546 $message = gTxt($event.'_category_updated', array('{name}' => doStrip($name))); 547 } 548 } 549 } 550 cat_category_list($message); 551 } 552 553 // -------------------------------------------------------------- 554 // Non image file upload. Have I mentioned how much I love this file refactoring? 555 // ------------------------------------------------------------- 556 function cat_file_list() 557 { 558 return cat_event_category_list('file'); 559 } 560 561 //------------------------------------------------------------- 562 function cat_file_create() 563 { 564 return cat_event_category_create('file'); 565 } 566 567 //------------------------------------------------------------- 568 function cat_file_edit() 569 { 570 return cat_event_category_edit('file'); 571 } 572 573 //------------------------------------------------------------- 574 function cat_file_save() 575 { 576 return cat_event_category_save('file','txp_file'); 577 } 578 579 580 ?>
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
title