Textpattern PHP Cross Reference Content Management Systems

Source: /textpattern/include/txp_category.php - 580 lines - 16234 bytes - Summary - Text - Print

   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

title

Description

title

Description

title

title

Body