Xaraya PHP Cross Reference Web Portal Systems

Source: /modules/comments/xarrenderer.php - 762 lines - 29117 bytes - Summary - Text - Print

   1  <?php
   2  /**
   3   * @package modules
   4   * @copyright (C) 2002-2007 The Digital Development Foundation
   5   * @license GPL {@link http://www.gnu.org/licenses/gpl.html}
   6   * @link http://www.xaraya.com
   7   *
   8   * @subpackage comments
   9   * @link http://xaraya.com/index.php/release/14.html
  10   * @author Carl P. Corliss <rabbitt@xaraya.com>
  11   */
  12  
  13  /**
  14   * Set/Load important constants for use throughout the renderer
  15   *
  16   * defines set here are thread view specific and should be here
  17   */
  18  include_once ('modules/comments/xarincludes/defines.php');
  19  
  20  define('_COM_NO_CONNECTOR',0);
  21  define('_COM_O_CONNECTOR', 1);
  22  define('_COM_P_CONNECTOR', 2);
  23  define('_COM_DASH_CONNECTOR',3);
  24  define('_COM_T_CONNECTOR', 4);
  25  define('_COM_L_CONNECTOR', 5);
  26  define('_COM_I_CONNECTOR', 6);
  27  define('_COM_BLANK_CONNECTOR', 7);
  28  define('_COM_CUTOFF_CONNECTOR', 8);
  29  
  30  
  31  /**
  32   * Takes a an array of related (parent -> child) values and assigns a depth to
  33   * each one -- requires that each node in the array has the 'children' field
  34   * telling how many children it [the current node] has
  35   * List passed as argument MUST be an ordered list - in the order of
  36   * Parent1 -> child2-> child3 -> child4 -> subchild5 -> sub-subchild6-> subchild7-> child8-> child9-> subchild10 -> Parent11 ->....
  37   * for example, the below list is an -ordered list- in thread order (ie., parent to child relation ships):
  38   * <pre>
  39   *
  40   *   ID | VISUAL       |   DEPTH
  41   *   ===+==============+=========
  42   *    1 | o            |   0
  43   *      | |            |
  44   *    2 | +--          |   1
  45   *      | |            |
  46   *    3 | +--          |   1
  47   *      | |            |
  48   *    4 | +--o         |   1
  49   *      | |  |         |
  50   *    5 | +  +--o      |   2
  51   *      | |  |  |      |
  52   *    6 | +  +  +--    |   3
  53   *      | |  |         |
  54   *    7 | +  +--       |   2
  55   *      | |            |
  56   *    8 | +--          |   1
  57   *      | |            |
  58   *    9 | +--o         |   1
  59   *      |    |         |
  60   *   10 |    +--       |   2
  61   *      |              |
  62   *   11 | o            |   0
  63   *      | |            |
  64   *   12 | +--o         |   1
  65   *      |    |         |
  66   *   13 |    +--       |   2
  67   *
  68   * </pre>
  69   *
  70   * @author Carl P. Corliss (aka rabbitt)
  71   * @access public
  72   * @param array &$comments_list  A reference (pointer) to an array or related items in parent -> child order (see above)
  73   * @return bool
  74   */
  75  function comments_renderer_array_markdepths_bychildren(&$comments_list)
  76  {
  77      // check to make sure we got passed an array,
  78      // return false if we got no array or it has no items in it
  79      if (!is_array($comments_list) || !count($comments_list)) return false;
  80  
  81      // figure out how man total nodes are in this array,
  82      $total_nodes = count($comments_list);
  83  
  84      // check to see if this array has the depth field in it already,
  85      // if not, it's the first time this array has been parsed through
  86      // this function so initialize each node to have a depth of zero:
  87      if (!isset($comments_list[0]['depth'])) {
  88          for ($node = 0; $node < $total_nodes; $node++) {
  89              $comments_list[$node]['depth'] = 0;
  90          }
  91      }
  92  
  93      for ($node = 0; $node < $total_nodes; $node++) {
  94          // if the current node has zero (or less) children,
  95          // skip to the next one
  96          if ($comments_list[$node]['children'] <= 0) {
  97              continue;
  98          } else {
  99              // otherwise, the node has children so figure out it's last child's index number
 100              $last_child = $node + $comments_list[$node]['children'];
 101          }
 102  
 103          // now we increment starting at the node's first child up
 104          // to it's last one adding one to each of it's kids
 105          for ($index = $node + 1; $index <= $last_child && $index < $total_nodes; $index++) {
 106              $comments_list[$index]['depth'] += 1;
 107          }
 108      }
 109  
 110      return true;
 111  }
 112  
 113  /**
 114   * Takes a an array of related (parent -> child) values and assigns a depth to each one
 115   *
 116   * Requires that each node in the array has the 'pid' (parent id) field
 117   * List passed as argument MUST be an ordered list - in the order of
 118   * Parent1 -> child2-> child3 -> child4 -> subchild5 -> sub-subchild6-> subchild7-> child8-> child9-> subchild10 -> Parent11 ->....
 119   * This function is exactly like comments_display_array_markdepths but tailored for
 120   * use with parent id's instead.
 121   *
 122   * @author Carl P. Corliss (aka rabbitt)
 123   * @access public
 124   * @param array   &$comments_list    an array of related (array) items - each item -must- contain a parent id field
 125   * @return bool
 126   */
 127  function comments_renderer_array_markdepths_bypid(&$comments_list)
 128  {
 129      if (empty($comments_list) || !count($comments_list)) {
 130          $msg = xarML('Empty comments list');
 131          xarErrorSet(XAR_USER_EXCEPTION, 'MISSING_DATA', new DefaultUserException($msg));
 132          return;
 133      }
 134  
 135      // start the initial depth off at zero
 136      $depth = 0;
 137  
 138      $parents = array();
 139      $new_list = array();
 140      $prep_list = array();
 141  
 142      // Initialize parents array and make the first key in it equal
 143      // to the first node in the array's parentid
 144      $parents['PID_' . $comments_list[0]['xar_pid']] = $depth;
 145  
 146      // setup the keys for each comment so that we can
 147      // easily reference them further down
 148      foreach($comments_list as $node) {
 149          $new_list[$node['xar_cid']] = $node;
 150      }
 151      $comments_list = $new_list;
 152  
 153      // re-initialize the new_list array
 154      $new_list = array();
 155  
 156      // foreach node in the array, check to see if we
 157      // have it's parent id marked in memory and, if so
 158      // set the current nodes depth equal to that of
 159      // the marked parent id. If not, then we need to
 160      // add the depth for the current parent id to the
 161      // parents list for future use :)
 162      foreach ($comments_list as $key => $node) {
 163          // if the current node's parent isn't yet
 164          // defined, then add it to the list of parents
 165          // and give it a depth equal to it's parent's depth + 1
 166          if (!array_key_exists("PID_".$node['xar_pid'],$parents)) {
 167              if (!array_key_exists($node['xar_pid'], $comments_list)) {
 168                  $comments_list[$node['xar_pid']]['xar_pid'] = 0;
 169                  $comments_list[$node['xar_pid']]['xar_cid'] = 0;
 170                  $comments_list[$node['xar_pid']]['remove'] = 'remove';
 171                  $parents["PID_".$node['xar_pid']] = -1;
 172              }
 173              $ppidkey = "PID_".$comments_list[$node['xar_pid']]['xar_pid'];
 174  
 175              // CHECKME: when we start with a category 2+ levels deep, $parents['PID_0'] is undefined here
 176              if (!isset($parents[$ppidkey])) {
 177                  $parents[$ppidkey] = -1;
 178              }
 179              $parents["PID_".$node['xar_pid']] = $parents[$ppidkey] + 1;
 180          }
 181  
 182          // if the current nodes parent already has
 183          // has a defined depth and that depth is
 184          // zero, then reset the $depth counter to zero
 185          if (0 == $parents['PID_'.$node['xar_pid']]) {
 186              $depth = 0;
 187          }
 188  
 189          $prep_list[$key] = $node;
 190          $prep_list[$key]['depth'] = $parents["PID_".$node['xar_pid']];
 191      }
 192  
 193      // now we go through and find all the nodes that were marked
 194      // as parent nodes and add the 'haschildren' field to them
 195      // setting it to true -- otherwise, if the node wasn't a
 196      // parent ID we set it's 'haschildren' equal to false
 197      foreach ($prep_list as $node) {
 198          if (isset($parents['PID_' . $node['xar_cid']])) {
 199              $node['children'] = 1;
 200              unset($parents['PID_' . $node['xar_cid']]);
 201          } else {
 202              $node['children'] = 0;
 203          }
 204          $new_list[] = $node;
 205      }
 206  
 207      $comments_list = '';
 208  
 209      // remove any items that aren't really a part of the array
 210      // and are just excess baggage from previous code
 211      foreach ($new_list as $node) {
 212          if (!array_key_exists('remove', $node)) {
 213              $comments_list[] = $node;
 214          }
 215      }
 216  
 217      return true;
 218  }
 219  
 220  
 221  /**
 222   * Remove any comments from the list with a depth greater than
 223   * the cutoff point. If the depth of any particular node is equal
 224   * to (cutoff + 1), then just the cid and the depth for that particular
 225   * node are included in the array. Reason: it allows us to show that
 226   * there are more comments in that direction. This is used by
 227   * comments_userapi_get() to limit the comments pulled by depth.
 228   *
 229   * @access private
 230   * @author Carl P. Corliss (aka rabbitt)
 231   * @param array      $args['array_list']    list of comments to check
 232   * @param integer    $args['cutoff']        depth cutoff point
 233   * @return mixed void if no array is passed or the array has no nodes return void
 234   */
 235  function comments_renderer_array_prune_excessdepth($args)
 236  {
 237      extract($args);
 238      if (!is_array($array_list) || !count($array_list)) return;
 239  
 240      // TODO: find better way to get min. left & max. right for this list
 241      foreach ($array_list as $node) {
 242          if (!isset($left)) $left = $node['xar_left'];
 243          if (!isset($right)) $right = $node['xar_right'];
 244          if ($node['xar_left'] < $left) $left = $node['xar_left'];
 245          if ($node['xar_right'] > $right) $right = $node['xar_right'];
 246      }
 247  
 248      $countlist = xarModAPIFunc('comments', 'user', 'get_childcountlist',
 249          array(
 250              'left' => $left,
 251              'right' => $right,
 252              'modid' => $modid,
 253              'itemtype' => $itemtype,
 254              'objectid' => $objectid
 255          )
 256      );
 257  
 258      $new_list = array();
 259      foreach ($array_list as $node) {
 260          if (isset($countlist[$node['xar_cid']])) {
 261              $childcount = $countlist[$node['xar_cid']];
 262          } else {
 263              $childcount = 0;
 264          }
 265  
 266          if ($cutoff == $node['depth']) {
 267              if ($childcount) {
 268                  // TODO: change childcount -> xar_childcount
 269                  // TODO: change children --> xar_children
 270                  $node['xar_branchout']      = true;
 271                  $node['childcount']         = $childcount;
 272                  $node['children']           = (int) '-1';
 273  
 274                  // TODO: change thread_text / nested_text --> xar_children_short_text / xar_children_long_text
 275                  if ($childcount > 1) {
 276                      $node['thread_text'] = xarML('(#(1) children.)', $childcount);
 277                      $node['nested_text'] = xarML('#(1) children beneath this comment.', $childcount);
 278                  } else {
 279                      $node['thread_text'] = xarML('(#(1) child.)', $childcount);
 280                      $node['nested_text'] = xarML('#(1) child beneath this comment.', $childcount);
 281                  }
 282  
 283                  $new_list[] = $node;
 284              } else {
 285                  // if the comment doesn't have any children, then
 286                  // display it normally...
 287                  $node['xar_branchout'] = 0;
 288                  $new_list[] = $node;
 289              }
 290          } elseif ($node['depth'] > $cutoff) {
 291              continue;
 292          } else {
 293              $node['xar_branchout'] = 0;
 294              $node['childcount']    = $childcount;
 295              $new_list[] = $node;
 296          }
 297      }
 298      $array_list = $new_list;
 299      unset($new_list);
 300  
 301      return $array_list;
 302  }
 303  
 304  /**
 305   * Used internally by comments_renderer_array_maptree() to keep track
 306   * of depths while mapping out the visual tree structure
 307   *
 308   * @access private
 309   * @author Carl P. Corliss (aka rabbitt)
 310   * @param string  $action    get or set
 311   * @param integer $depth     the depth to set or get
 312   * @param bool    $value     true if the depth is set or false if unset
 313   * @return bool
 314   */
 315  function comments_renderer_array_depthbuoy($action, $depth, $value=true)
 316  {
 317      static $matrix = array();
 318  
 319      if (empty($matrix)) {
 320          $matrix = array_pad(array(0=>0), _COM_MAX_DEPTH, _COM_NO_CONNECTOR);
 321      }
 322  
 323      if (strtolower($action) == 'set') {
 324          $matrix[($depth)] = (bool) $value;
 325      }
 326  
 327      if ($depth < 0) {
 328          return 0;
 329      } else {
 330          return $matrix[($depth)];
 331      }
 332  }
 333  
 334  /**
 335   * Maps out the visual structure of a tree based on each
 336   * node's 'depth' and 'children' fields
 337   *
 338   * @author Carl P. Corliss (aka rabbitt)
 339   * @access  public
 340   * @param   array   $CommentList    List of related comments
 341   * @param   string  $modName        the name of the module to use when pulling thread images (defaults to comments module)
 342   * @return array   an array of comments with an extra field ('map') for each comment
 343   *                  that's contains the visual representation for that particular node
 344   */
 345  function comments_renderer_array_maptree(&$CommentList, $modName = NULL)
 346  {
 347  
 348      // if $CommentList isn't an array or it is empty,
 349      // return an empty array
 350      if (!is_array($CommentList) || count($CommentList) == 0) {
 351          return array();
 352      }
 353  
 354      // if comments in the list don't have depth then we can't generate
 355      // the visual image -- so, in that case, see if the comments
 356      // have a children field. If they do, setup the depths for each
 357      // comment based on that -- if not, check for a pid field and
 358      // then set up the depth fields for each if that is present,
 359      // otherwise -- raise an exception.  Also, sort them after
 360      // assigning depths.
 361  
 362      $current_depth  = 0;         // depth of the current comment in the array
 363      $next_depth     = 0;         // depth of the next comment in the array (closer to beginning of array)
 364      $prev_depth     = 0;         // depth of the previous comment in the array (closer to end of array)
 365      $matrix         = array();   // initialize the matrix to a null array
 366  
 367      $listsize = (count($CommentList) - 1);
 368      $total = count($CommentList);
 369  
 370      // create the matrix starting from the end and working our way towards
 371      // the beginning.
 372      for ($counter = $listsize; $counter >= 0; $counter = $counter - 1) {
 373          // unmapped matrix for current comment
 374          $matrix = array_pad(array(0=>0), _COM_MAX_DEPTH, _COM_NO_CONNECTOR);
 375  
 376          // make sure to $depth = $depth modulus _COM_MAX_DEPTH  - because we are only ever showing
 377          // ten levels of depth -- anything more than that and the display doesn't look good
 378          $current_depth  = @$CommentList[$counter]['depth'] % _COM_MAX_DEPTH;
 379          $next_depth     = (($counter -1) < 0 ? -1 : @$CommentList[$counter-1]['depth'] % _COM_MAX_DEPTH);
 380          $prev_depth     = (($counter +1) > $listsize ? -1 : @$CommentList[$counter+1]['depth'] % _COM_MAX_DEPTH);
 381  
 382          // first start by placing the depth point in the matrix
 383          // if the current comment has children place a P connetor
 384          if ($CommentList[$counter]['children'] === true || $CommentList[$counter]['children'] > 0) {
 385              $matrix[$current_depth] = _COM_P_CONNECTOR;
 386          } elseif ($CommentList[$counter]['children'] < 0) {
 387              $matrix[$current_depth] = _COM_CUTOFF_CONNECTOR;
 388          } else {
 389              // if the current comment doesn't have children
 390              // and it is at depth ZERO it is an O connector
 391              // otherwise use a dash connector
 392              if (!$current_depth) {
 393                  $matrix[$current_depth] = _COM_O_CONNECTOR;
 394              } else {
 395                  $matrix[$current_depth] = _COM_DASH_CONNECTOR;
 396              }
 397          }
 398  
 399          // if the current depth is zero then all that it requires is an O or P connector
 400          // soooo if the current depth is -not- zero then we have other connectors so
 401          // below we figure out what the other connectors are...
 402          if (0 != $current_depth) {
 403              if ( ($current_depth != $prev_depth) ) {
 404                  $matrix[$current_depth - 1] = _COM_L_CONNECTOR;
 405              }
 406  
 407              // in order to have a T connector the current depth -must-
 408              // be less then or equal to the previous depth
 409              if ( $current_depth <= $prev_depth) {
 410                  // if there is a DepthBuoy set for (current depth -1)
 411                  // then
 412                  if (comments_renderer_array_depthbuoy('get',($current_depth - 1)) === true ) {
 413                      // the DepthBuoy for this depth can now be turned off.
 414                      comments_renderer_array_depthbuoy('set',($current_depth - 1),false);
 415                      $matrix[($current_depth - 1)] = _COM_T_CONNECTOR;
 416                  }
 417  
 418                  if ($current_depth == $prev_depth) {
 419                      $matrix[($current_depth - 1)] = _COM_T_CONNECTOR;
 420                  }
 421  
 422              }
 423  
 424              // Once we've got the T and L connectors done, we need to go through
 425              // the matrix working our way from the indice equal to the current comment
 426              // depth towards the begginning of the array - checking for I connectors
 427              // and Blank connectors.
 428              for ($node = $current_depth; $node >= 0; $node -= 1) {
 429                  // be sure not to overwrite another node in the matrix
 430                  if (!$matrix[$node]) {
 431                      // if a depth buoy was set for this depth, add I connector
 432                      if (comments_renderer_array_depthbuoy('get', $node) == true) {
 433                          $matrix[($node)] = _COM_I_CONNECTOR;
 434                      } else {
 435                          // otherwise add a blank.gif
 436                          $matrix[($node)] = _COM_BLANK_CONNECTOR;
 437                      }
 438                  }
 439              }
 440          }
 441  
 442          // Set depth buoy if the next depth is greater then the current,
 443          // this way we can remember where to set an I connector :)
 444          if ($next_depth > $current_depth && $current_depth != 0) {
 445              comments_renderer_array_depthbuoy('set', $current_depth - 1, true);
 446          }
 447  
 448          // ok -- once that's all done, take this segment of the whole matrix map (ie.,
 449          // this comment's matrix) create the array of images that will represent this
 450          // comments place on the "threaded map."
 451  
 452          // if modName == NULL or empty then we default to using the comments api's
 453          //  thread images otherwise, we use images from the calling module
 454          if (empty($modName) || $nodName == NULL) {
 455              $CommentList[$counter]['xar_map'] = comments_renderer_array_image_substitution($matrix, 'comments');
 456          } else {
 457              $CommentList[$counter]['xar_map'] = comments_renderer_array_image_substitution($matrix);
 458          }
 459      }
 460  
 461      return $CommentList;
 462  }
 463  
 464  /**
 465   * Used internally by comments_renderer_array_maptree(). Takes the nodes in a matrix created for
 466   * a particular comment and translates them into the visual (html'ified) segments of the full map.
 467   *
 468   * @author  Carl P. Corliss (aka rabbitt)
 469   * @access  private
 470   * @param   array   $matrix  The current node's tree matrix
 471   * @param   string  $modName (optional) the module name to use when grabbing the image location
 472   * @return array   an list of the images needed for displaying this particular node in the tree
 473   */
 474  function comments_renderer_array_image_substitution($matrix, $modName = NULL)
 475  {
 476      $map = array();
 477  
 478      foreach ($matrix as $value) {
 479          switch ($value) {
 480              case _COM_O_CONNECTOR:
 481                  $map[] = xarTplGetImage('n_nosub.gif', $modName);
 482                  break;
 483              case _COM_P_CONNECTOR:
 484                  $map[] = xarTplGetImage('n_sub.gif', $modName);
 485                  break;
 486              case _COM_T_CONNECTOR:
 487                  $map[] = xarTplGetImage('n_sub_branch_t.gif', $modName);
 488                  break;
 489              case _COM_L_CONNECTOR:
 490                  $map[] = xarTplGetImage('n_sub_branch_l.gif', $modName);
 491                  break;
 492              case _COM_I_CONNECTOR:
 493                  $map[] = xarTplGetImage('n_sub_line.gif', $modName);
 494                  break;
 495              case _COM_BLANK_CONNECTOR:
 496                  $map[] = xarTplGetImage('n_spacer.gif', $modName);
 497                  break;
 498              case _COM_DASH_CONNECTOR:
 499                  $map[] = xarTplGetImage('n_sub_end.gif', $modName);
 500                  break;
 501              case _COM_CUTOFF_CONNECTOR:
 502                  $map[] = xarTplGetImage('n_sub_cutoff.gif', $modName);
 503                  break;
 504              default:
 505              case _COM_NO_CONNECTOR:
 506                  break;
 507          }
 508      }
 509      return $map;
 510  }
 511  
 512  /**
 513   * Used internally by comments_renderer_array_sort(). facilitates
 514   * sorting of comments whereby the only ones that are sorted in reverse
 515   * are the top level comments -- all other comments are sorted in ascending order
 516   * maintaining parent->child relationships
 517   *
 518   * @access private
 519   * @author Carl P. Corliss (aka rabbitt)
 520   * @param string    $a     Lineage to compare
 521   * @param string    $b     Lineage to compare
 522   * @return integer  -1 if a < b, 0 if a == b, 1 if a > b
 523   *
 524   */
 525  function comments_renderer_array_fieldrelation_compare ($a, $b)
 526  {
 527      // get the sort value
 528      $sort = comments_renderer_array_sortvalue();
 529  
 530      // first we start off by putting the array key into
 531      // array format with each id that makes up
 532      // the lineage having it's own array index.
 533      // As well, we find out how many id's there
 534      // are for each Lineage.
 535      $Family_A = explode(':', $a);
 536      $Family_A_count = count($Family_A);
 537  
 538      $Family_B = explode(':', $b);
 539      $Family_B_count = count($Family_B);
 540  
 541      // We need the lineage with the least amount of id's in
 542      // it for use in our for loop.
 543      if ($Family_A_count == $Family_B_count) {
 544          // if they are both equal we could just as easily
 545          // set this to Family_B instead.. doesn't really
 546          // matter
 547          $members_count = $Family_A_count;
 548      } else {
 549          $members_count = ($Family_A_count < $Family_B_count ? $Family_A_count : $Family_B_count);
 550      }
 551      // here we do the sorting of the toplevel comments in
 552      // the list by comparing the first ID's in the lineage
 553      // which are always the top level id's.
 554      if (is_numeric($Family_A[0]) && is_numeric($Family_B[0])) {
 555          if ((int) $Family_A[0] != (int) $Family_B[0]) {
 556              if ($sort == _COM_SORT_ASC) {
 557                  return ((int) $Family_A[0] < (int) $Family_B[0]) ? -1 : 1;
 558              } elseif ($sort == _COM_SORT_DESC) {
 559                  return ((int) $Family_A[0] < (int) $Family_B[0]) ? 1 : -1;
 560              } else {
 561                  // in the event that sort is set to some unexpected value
 562                  // assume sort = ASC
 563                  return ((int) $Family_A[0] < (int) $Family_B[0]) ? -1 : 1;
 564              }
 565          }
 566      } else {
 567          if (strcasecmp($Family_A[0], $Family_B[0]) != 0) {
 568              if ($sort == _COM_SORT_ASC) {
 569                  return strcasecmp($Family_A[0], $Family_B[0]);
 570              } elseif ($sort == _COM_SORT_DESC) {
 571                  return (int) -(strcasecmp($Family_A[0], $Family_B[0]));
 572              } else {
 573                  // in the event that sort is set to some unexpected value
 574                  // assume sort = ASC
 575                  return strcasecmp($Family_A[0], $Family_B[0]);
 576              }
 577          }
 578      }
 579      // now we do an id to id comparison but only up to the number of
 580      // elements (comment ids) of the smallest lineage.
 581      for ($i = 1; $i < $members_count; $i++) {
 582          if ((int) $Family_A[$i] != (int) $Family_B[$i]) {
 583              return ((int) $Family_A[$i] < (int) $Family_B[$i]) ? -1 : 1;
 584          }
 585      }
 586  
 587      // Since we are here it means that both lineages matched up to the
 588      // length of the smallest lineage soo-, the one that has the most
 589      // elements (comment ids) is obviously of higher value. If however they
 590      // have the same amount of elements, then the lineages are the same --
 591      // [Note]: this should NEVER happen.
 592      if ($Family_A_count != $Family_B_count) {
 593          return ($Family_A_count < $Family_B_count) ? -1 : 1;
 594      } else {
 595          return 0;
 596      }
 597  }
 598  
 599  /**
 600   * Used to set/retrieve the current value of sort. -- used internally
 601   * and should not be utilized outside of this function group.
 602   *
 603   * @access  private
 604   * @author  Carl P. Corliss (aka rabbitt)
 605   * @param   string  $value  'ASC' for Ascending, 'DESC' for descending sort order
 606   * @return  string  The current sort value
 607   *
 608   */
 609  function comments_renderer_array_sortvalue($value=NULL)
 610  {
 611      static $sort;
 612  
 613      if ($value != NULL) {
 614          switch (strtolower($value)) {
 615          case _COM_SORT_DESC:
 616              $sort = _COM_SORT_DESC;
 617              break;
 618          case _COM_SORT_ASC:
 619          default:
 620              $sort = _COM_SORT_ASC;
 621          }
 622      }
 623      return $sort;
 624  }
 625  
 626  /**
 627   * Sorts the specified array by the specified 'sortby' value in the direction specified by 'direction'
 628   *
 629   * @author Carl P. Corliss (aka rabbitt)
 630   * @access public
 631   * @param    string  $args['sortby']         represents the field to sort by
 632   * @param    string  $args['direction']      represents the direction to sort (ascending / descending )
 633   * @param    array   $args['comment_list']   List of comments to sort
 634   * @returns   void    nothing
 635   */
 636  
 637  function  comments_renderer_array_sort( &$comment_list, $sortby, $direction)
 638  {
 639      if (!isset($comment_list) || !is_array($comment_list)) {
 640          $msg = xarML('Missing or invalid argument [#(1)] for #(2) function #(3) in module #(4)',
 641                                   'comment_list','renderer','array_sort',$modName);
 642          xarErrorSet(XAR_USER_EXCEPTION, 'BAD_PARAM', new SystemException(__FILE__.' ('.__LINE__.'):  '.$msg));
 643          return false;
 644      }
 645  
 646      $index      = array();
 647      $new_list   = array();
 648  
 649      comments_renderer_array_sortvalue($direction);
 650  
 651      if ($sortby == _COM_SORTBY_THREAD) {
 652          foreach ($comment_list as $node) {
 653  
 654              if ($node['depth'] == 0) {
 655                  $key = $node['xar_cid'];
 656                  $index[$node['xar_cid']] = $key;
 657              } else {
 658                  $key = $index[$node['xar_pid']] .":".$node['xar_cid'];
 659                  $index[$node['xar_cid']] = $key;
 660              }
 661              $new_list[$key] = $node;
 662          }
 663      } else {
 664          // Initial presort for non threaded sort - We do a presort to
 665          // get all the comments in order by the key that we're sorting
 666          // by -- otherwise, when we assign parents and children
 667          // (further below) there will  be a chance that some will be
 668          // out of order and mess up the rendering
 669          foreach ($comment_list as $node) {
 670              switch($sortby) {
 671                  case _COM_SORTBY_TOPIC:
 672                      $key = str_replace(":", " ", $node['xar_title']);
 673                      break;
 674                  case _COM_SORTBY_DATE:
 675                      $key = 'a' . $node['xar_datetime'];
 676                      break;
 677                  default:
 678                  case _COM_SORTBY_AUTHOR:
 679                      $key = $node['xar_author'];
 680                      break;
 681                      // default to sorting by author
 682              }
 683  
 684              $new_list[$key .":". $node['xar_cid']] = $node;
 685          }
 686          $comment_list = $new_list;
 687          $new_list = array();
 688  
 689          uksort($comment_list, 'comments_renderer_array_fieldrelation_compare');
 690          // End of PreSORT
 691  
 692          foreach ($comment_list as $node) {
 693              switch($sortby) {
 694                  case _COM_SORTBY_TOPIC:
 695                      $key = str_replace(":"," ",$node['xar_title']);
 696                      break;
 697                  case _COM_SORTBY_DATE:
 698                      $key = 'a' . $node['xar_datetime'];
 699                      break;
 700                  default:
 701                  case _COM_SORTBY_AUTHOR:
 702                      $key = $node['xar_author'];
 703                      break;
 704                      // default to sorting by author
 705              }
 706  
 707              if (!isset($index[$key])) {
 708                  $index[$key]['depth'] = 0;
 709                  $index[$key]['children'] = 0;
 710                  $new_list[$key.":0"] = $node;
 711                  $new_list[$key.":0"]['depth'] = $index[$key]['depth'];
 712                  $new_list[$key.":0"]['children'] = $index[$key]['children'];
 713              } else {
 714                  $key2 = $key.":".$node['xar_cid'];
 715                  $new_list[$key2] = $node;
 716                  $new_list[$key2]['depth'] = 1;
 717                  $new_list[$key2]['children'] = 0;
 718                  $new_list[$key.":0"]['children'] += 1;
 719              }
 720          }
 721      }
 722      $comment_list = $new_list;
 723  
 724      uksort($comment_list, 'comments_renderer_array_fieldrelation_compare');
 725  
 726      // reset the indexes on the comments_list
 727      $comments = array();
 728      foreach ($comment_list as $comment) {
 729          $comments[] = $comment;
 730      }
 731  
 732      $comment_list = $comments;
 733      unset($comments);
 734  
 735      return $comment_list;
 736  }
 737  
 738  /**
 739   * Wraps words at the specified length
 740   *
 741   * @author Carl P. Corliss (aka rabbitt)
 742   * @access public
 743   * @param    string  &$str  the string to perform word wrapping on
 744   * @param    integer $chars the amount of characters to word wrap at
 745   * @return   string the word-wrapped string
 746   * @todo do we need this function? \
 747   * @todo is this the correct place for wrap modvar checking?
 748   */
 749  function comments_renderer_wrap_words(&$str, $chars)
 750  {
 751      if (xarModGetVar('comments','wrap')){
 752          // Added for bug 4210 wrapping on multibyte words
 753          $before_lt="[\\x21-\\x3B]"; //"space" is x20 and "<" is x3C
 754          $equal="[\\x3D]";           //"=" is x3D
 755          $after_gt="[\\x3F-\\x7F]";  //">" is x3E
 756          $single = $before_lt."|".$equal."|".$after_gt;
 757          $pattern = "/(".$single."){".$chars.",".$chars."}/";
 758          $str = preg_replace($pattern, '\0 ',$str);
 759      }
 760      //$str = preg_replace('/([^\s\<\>]{'.$chars.','.$chars.'})/', '\1 ', $str);
 761  }
 762  ?>

title

Description

title

Description

title

Description

title

title

Body