[ PHPXref.com ] [ Generated: Thu Nov 4 14:43:12 2010 ] [ Textpattern 4.3.0 ]
[ Index ]     [ Variables ]     [ Functions ]     [ Classes ]     [ Constants ]     [ Statistics ]

title

Body

[close]

/textpattern/publish/ -> taghandlers.php (source)

   1  <?php
   2  
   3  /*
   4      This is Textpattern
   5      Copyright 2005 by Dean Allen - all rights reserved.
   6  
   7      Use of this software denotes acceptance of the Textpattern license agreement
   8  
   9  $HeadURL: https://textpattern.googlecode.com/svn/releases/4.3.0/source/textpattern/publish/taghandlers.php $
  10  $LastChangedRevision: 3443 $
  11  
  12  */
  13  
  14  // -------------------------------------------------------------
  15  
  16  	function page_title($atts)
  17      {
  18          global $parentid, $thisarticle, $id, $q, $c, $context, $s, $pg, $sitename;
  19  
  20          extract(lAtts(array(
  21              'separator' => ': ',
  22          ), $atts));
  23  
  24          $out = htmlspecialchars($sitename.$separator);
  25  
  26          if ($parentid) {
  27              $parent_id = (int) $parent_id;
  28              $out .= gTxt('comments_on').' '.escape_title(safe_field('Title', 'textpattern', "ID = $parentid"));
  29          } elseif ($thisarticle['title']) {
  30              $out .= escape_title($thisarticle['title']);
  31          } elseif ($q) {
  32              $out .= gTxt('search_results').htmlspecialchars($separator.$q);
  33          } elseif ($c) {
  34              $out .= htmlspecialchars(fetch_category_title($c, $context));
  35          } elseif ($s and $s != 'default') {
  36              $out .= htmlspecialchars(fetch_section_title($s));
  37          } elseif ($pg) {
  38              $out .= gTxt('page').' '.$pg;
  39          } else {
  40              $out = htmlspecialchars($sitename);
  41          }
  42  
  43          return $out;
  44      }
  45  
  46  // -------------------------------------------------------------
  47  
  48  	function css($atts)
  49      {
  50          global $css;
  51  
  52          extract(lAtts(array(
  53              'format' => 'url',
  54              'media'  => 'screen',
  55              'n'      => $css, // deprecated in 4.3.0
  56              'name'   => $css,
  57              'rel'    => 'stylesheet',
  58              'title'  => '',
  59          ), $atts));
  60  
  61          if (isset($atts['n'])) {
  62              $name = $n;
  63              trigger_error(gTxt('deprecated_attribute', array('{name}' => 'n')), E_USER_NOTICE);
  64          }
  65  
  66          if (empty($name)) $name = 'default';
  67          $url = hu.'css.php?n='.$name;
  68  
  69          if ($format == 'link') {
  70              return '<link rel="'.$rel.'" type="text/css"'.
  71                  ($media ? ' media="'.$media.'"' : '').
  72                  ($title ? ' title="'.$title.'"' : '').
  73                  ' href="'.$url.'" />';
  74          }
  75  
  76          return $url;
  77      }
  78  
  79  // -------------------------------------------------------------
  80  
  81  	function image($atts)
  82      {
  83          global $thisimage;
  84  
  85          static $cache = array();
  86  
  87          extract(lAtts(array(
  88              'align'   => '', // deprecated in 4.2.0
  89              'class'   => '',
  90              'escape'  => 'html',
  91              'html_id' => '',
  92              'id'      => '',
  93              'name'    => '',
  94              'width'   => '',
  95              'height'  => '',
  96              'style'   => '',
  97              'wraptag' => '',
  98          ), $atts));
  99  
 100          if ($align)
 101              trigger_error(gTxt('deprecated_attribute', array('{name}' => 'align')), E_USER_NOTICE);
 102  
 103          if ($name)
 104          {
 105              if (isset($cache['n'][$name]))
 106              {
 107                  $rs = $cache['n'][$name];
 108              }
 109  
 110              else
 111              {
 112                  $name = doSlash($name);
 113  
 114                  $rs = safe_row('*', 'txp_image', "name = '$name' limit 1");
 115  
 116                  $cache['n'][$name] = $rs;
 117              }
 118          }
 119  
 120          elseif ($id)
 121          {
 122              if (isset($cache['i'][$id]))
 123              {
 124                  $rs = $cache['i'][$id];
 125              }
 126  
 127              else
 128              {
 129                  $id = (int) $id;
 130  
 131                  $rs = safe_row('*', 'txp_image', "id = $id limit 1");
 132  
 133                  $cache['i'][$id] = $rs;
 134              }
 135          }
 136  
 137          elseif ($thisimage)
 138          {
 139              $id = (int) $thisimage['id'];
 140              $rs = $thisimage;
 141              $cache['i'][$id] = $rs;
 142          }
 143  
 144          else
 145          {
 146              trigger_error(gTxt('unknown_image'));
 147              return;
 148          }
 149  
 150          if ($rs)
 151          {
 152              extract($rs);
 153  
 154              if ($escape == 'html')
 155              {
 156                  $alt = htmlspecialchars($alt);
 157                  $caption = htmlspecialchars($caption);
 158              }
 159  
 160              if ($width=='' && $w) $width = $w;
 161              if ($height=='' && $h) $height = $h;
 162  
 163              $out = '<img src="'.imagesrcurl($id, $ext).'" alt="'.$alt.'"'.
 164                  ($caption ? ' title="'.$caption.'"' : '').
 165                  ( ($html_id and !$wraptag) ? ' id="'.$html_id.'"' : '' ).
 166                  ( ($class and !$wraptag) ? ' class="'.$class.'"' : '' ).
 167                  ($style ? ' style="'.$style.'"' : '').
 168                  ($align ? ' align="'.$align.'"' : '').
 169                  ($width ? ' width="'.$width.'"' : '').
 170                  ($height ? ' height="'.$height.'"' : '').
 171                  ' />';
 172  
 173              return ($wraptag) ? doTag($out, $wraptag, $class, '', $html_id) : $out;
 174          }
 175  
 176          trigger_error(gTxt('unknown_image'));
 177      }
 178  
 179  // -------------------------------------------------------------
 180  
 181  	function thumbnail($atts)
 182      {
 183          global $thisimage;
 184  
 185          extract(lAtts(array(
 186              'align'     => '', // deprecated in 4.2.0
 187              'class'     => '',
 188              'escape'    => 'html',
 189              'html_id'   => '',
 190              'height'       => '',
 191              'id'        => '',
 192              'link'      => 0,
 193              'link_rel'  => '',
 194              'name'      => '',
 195              'poplink'   => 0, // is this used?
 196              'style'     => '',
 197              'wraptag'   => '',
 198              'width'       => ''
 199          ), $atts));
 200  
 201          if ($align)
 202              trigger_error(gTxt('deprecated_attribute', array('{name}' => 'align')), E_USER_NOTICE);
 203  
 204          if ($name)
 205          {
 206              $name = doSlash($name);
 207  
 208              $rs = safe_row('*', 'txp_image', "name = '$name' limit 1");
 209          }
 210  
 211          elseif ($id)
 212          {
 213              $id = (int) $id;
 214  
 215              $rs = safe_row('*', 'txp_image', "id = $id limit 1");
 216          }
 217  
 218          elseif ($thisimage)
 219          {
 220              $id = (int) $thisimage['id'];
 221              $rs = $thisimage;
 222          }
 223  
 224          else
 225          {
 226              trigger_error(gTxt('unknown_image'));
 227              return;
 228          }
 229  
 230          if ($rs)
 231          {
 232              extract($rs);
 233  
 234              if ($thumbnail)
 235              {
 236                  if ($escape == 'html')
 237                  {
 238                      $alt = htmlspecialchars($alt);
 239                      $caption = htmlspecialchars($caption);
 240                  }
 241  
 242                  if ($width=='' && $thumb_w) $width = $thumb_w;
 243                  if ($height=='' && $thumb_h) $height = $thumb_h;
 244  
 245                  $out = '<img src="'.imagesrcurl($id, $ext, true).'" alt="'.$alt.'"'.
 246                      ($caption ? ' title="'.$caption.'"' : '').
 247                      ( ($html_id and !$wraptag) ? ' id="'.$html_id.'"' : '' ).
 248                      ( ($class and !$wraptag) ? ' class="'.$class.'"' : '' ).
 249                      ($style ? ' style="'.$style.'"' : '').
 250                      ($align ? ' align="'.$align.'"' : '').
 251                      ($width ? ' width="'.$width.'"' : '').
 252                      ($height ? ' height="'.$height.'"' : '').
 253                      ' />';
 254  
 255                  if ($link)
 256                  {
 257                      $out = href($out, imagesrcurl($id, $ext), (!empty($link_rel) ? " rel='$link_rel'" : '')." title='$caption'");
 258                  }
 259  
 260                  elseif ($poplink)
 261                  {
 262                      $out = '<a href="'.imagesrcurl($id, $ext).'"'.
 263                          ' onclick="window.open(this.href, \'popupwindow\', '.
 264                          '\'width='.$w.', height='.$h.', scrollbars, resizable\'); return false;">'.$out.'</a>';
 265                  }
 266  
 267                  return ($wraptag) ? doTag($out, $wraptag, $class, '', $html_id) : $out;
 268              }
 269  
 270          }
 271  
 272          trigger_error(gTxt('unknown_image'));
 273      }
 274  
 275  // -------------------------------------------------------------
 276  	function imageFetchInfo($where)
 277      {
 278          $rs = safe_row('*', 'txp_image', $where);
 279  
 280          if ($rs)
 281          {
 282              return image_format_info($rs);
 283          }
 284  
 285          return false;
 286      }
 287  
 288  //--------------------------------------------------------------------------
 289  	function image_format_info($image)
 290      {
 291          if (($unix_ts = @strtotime($image['date'])) > 0)
 292              $image['date'] = $unix_ts;
 293  
 294          return $image;
 295      }
 296  
 297  // -------------------------------------------------------------
 298  
 299  	function output_form($atts, $thing = NULL)
 300      {
 301          global $yield;
 302  
 303          extract(lAtts(array(
 304              'form' => '',
 305          ), $atts));
 306  
 307          if (!$form)
 308          {
 309              trigger_error(gTxt('form_not_specified'));
 310          }
 311          else
 312          {
 313              $yield[] = $thing !== NULL ? parse($thing) : NULL;
 314              $out = parse_form($form);
 315              array_pop($yield);
 316              return $out;
 317          }
 318      }
 319  
 320  // -------------------------------------------------------------
 321  
 322  	function yield()
 323      {
 324          global $yield;
 325  
 326          $inner = end($yield);
 327  
 328          return isset($inner) ? $inner : '';
 329      }
 330  
 331  // -------------------------------------------------------------
 332  
 333  	function feed_link($atts, $thing = NULL)
 334      {
 335          global $s, $c;
 336  
 337          extract(lAtts(array(
 338              'category' => $c,
 339              'flavor'   => 'rss',
 340              'format'   => 'a',
 341              'label'    => '',
 342              'limit'    => '',
 343              'section'  => ( $s == 'default' ? '' : $s),
 344              'title'    => gTxt('rss_feed_title'),
 345              'wraptag'  => '',
 346              'class'    => '',
 347          ), $atts));
 348  
 349          $url = pagelinkurl(array(
 350              $flavor    => '1',
 351              'section'  => $section,
 352              'category' => $category,
 353              'limit'    => $limit
 354          ));
 355  
 356          if ($flavor == 'atom')
 357          {
 358              $title = ($title == gTxt('rss_feed_title')) ? gTxt('atom_feed_title') : $title;
 359          }
 360  
 361          $title = htmlspecialchars($title);
 362  
 363          if ($format == 'link')
 364          {
 365              $type = ($flavor == 'atom') ? 'application/atom+xml' : 'application/rss+xml';
 366  
 367              return '<link rel="alternate" type="'.$type.'" title="'.$title.'" href="'.$url.'" />';
 368          }
 369  
 370          $txt = ($thing === NULL ? $label : parse($thing));
 371          $out = '<a href="'.$url.'" title="'.$title.'">'.$txt.'</a>';
 372  
 373          return ($wraptag) ? doTag($out, $wraptag, $class) : $out;
 374      }
 375  
 376  // -------------------------------------------------------------
 377  
 378  	function link_feed_link($atts)
 379      {
 380          global $c;
 381  
 382          extract(lAtts(array(
 383              'category' => $c,
 384              'flavor'   => 'rss',
 385              'format'   => 'a',
 386              'label'    => '',
 387              'title'    => gTxt('rss_feed_title'),
 388              'wraptag'  => '',
 389              'class'    => __FUNCTION__,
 390          ), $atts));
 391  
 392          $url = pagelinkurl(array(
 393              $flavor => '1',
 394              'area'  =>'link',
 395              'c'     => $category
 396          ));
 397  
 398          if ($flavor == 'atom')
 399          {
 400              $title = ($title == gTxt('rss_feed_title')) ? gTxt('atom_feed_title') : $title;
 401          }
 402  
 403          $title = htmlspecialchars($title);
 404  
 405          if ($format == 'link')
 406          {
 407              $type = ($flavor == 'atom') ? 'application/atom+xml' : 'application/rss+xml';
 408  
 409              return '<link rel="alternate" type="'.$type.'" title="'.$title.'" href="'.$url.'" />';
 410          }
 411  
 412          $out = '<a href="'.$url.'" title="'.$title.'">'.$label.'</a>';
 413  
 414          return ($wraptag) ? doTag($out, $wraptag, $class) : $out;
 415      }
 416  
 417  // -------------------------------------------------------------
 418  
 419  	function linklist($atts, $thing = NULL)
 420      {
 421          global $s, $c, $context, $thislink, $thispage, $pretext;
 422  
 423          extract(lAtts(array(
 424              'break'       => '',
 425              'category'    => '',
 426              'author'      => '',
 427              'realname'    => '',
 428              'auto_detect' => 'category, author',
 429              'class'       => __FUNCTION__,
 430              'form'        => 'plainlinks',
 431              'label'       => '',
 432              'labeltag'    => '',
 433              'pageby'      => '',
 434              'limit'       => 0,
 435              'offset'      => 0,
 436              'sort'        => 'linksort asc',
 437              'wraptag'     => '',
 438          ), $atts));
 439  
 440          $where = array();
 441          $filters = isset($atts['category']) || isset($atts['author']) || isset($atts['realname']);
 442          $context_list = (empty($auto_detect) || $filters) ? array() : do_list($auto_detect);
 443          $pageby = ($pageby=='limit') ? $limit : $pageby;
 444  
 445          if ($category) $where[] = "category IN ('".join("','", doSlash(do_list($category)))."')";
 446          if ($author) $where[] = "author IN ('".join("','", doSlash(do_list($author)))."')";
 447          if ($realname) {
 448              $authorlist = safe_column('name', 'txp_users', "RealName IN ('". join("','", doArray(doSlash(do_list($realname)), 'urldecode')) ."')" );
 449              $where[] = "author IN ('".join("','", doSlash($authorlist))."')";
 450          }
 451  
 452          // If no links are selected, try...
 453          if (!$where && !$filters)
 454          {
 455              foreach ($context_list as $ctxt)
 456              {
 457                  switch ($ctxt)
 458                  {
 459                      case 'category':
 460                          // ... the global category in the URL
 461                          if ($context == 'link' && !empty($c))
 462                          {
 463                              $where[] = "category = '".doSlash($c)."'";
 464                          }
 465                          break;
 466                      case 'author':
 467                          // ... the global author in the URL
 468                          if ($context == 'link' && !empty($pretext['author']))
 469                          {
 470                              $where[] = "author = '".doSlash($pretext['author'])."'";
 471                          }
 472                          break;
 473                  }
 474                  // Only one context can be processed
 475                  if ($where) break;
 476              }
 477          }
 478  
 479          if (!$where && $filters)
 480          {
 481              return ''; // If nothing matches, output nothing
 482          }
 483  
 484          if (!$where)
 485          {
 486              $where[] = "1=1"; // If nothing matches, start with all links
 487          }
 488  
 489          $where = join(' AND ', $where);
 490  
 491          // Set up paging if required
 492          if ($limit && $pageby) {
 493              $grand_total = safe_count('txp_link', $where);
 494              $total = $grand_total - $offset;
 495              $numPages = ($pageby > 0) ? ceil($total/$pageby) : 1;
 496              $pg = (!$pretext['pg']) ? 1 : $pretext['pg'];
 497              $pgoffset = $offset + (($pg - 1) * $pageby);
 498              // send paging info to txp:newer and txp:older
 499              $pageout['pg']          = $pg;
 500              $pageout['numPages']    = $numPages;
 501              $pageout['s']           = $s;
 502              $pageout['c']           = $c;
 503              $pageout['context']     = 'link';
 504              $pageout['grand_total'] = $grand_total;
 505              $pageout['total']       = $total;
 506  
 507              if (empty($thispage))
 508                  $thispage = $pageout;
 509          } else {
 510              $pgoffset = $offset;
 511          }
 512  
 513          $qparts = array(
 514              $where,
 515              'order by '.doSlash($sort),
 516              ($limit) ? 'limit '.intval($pgoffset).', '.intval($limit) : ''
 517          );
 518  
 519          $rs = safe_rows_start('*, unix_timestamp(date) as uDate', 'txp_link', join(' ', $qparts));
 520  
 521          if ($rs)
 522          {
 523              $out = array();
 524  
 525              while ($a = nextRow($rs))
 526              {
 527                  extract($a);
 528  
 529                  $thislink = array(
 530                      'id'          => $id,
 531                      'linkname'    => $linkname,
 532                      'url'         => $url,
 533                      'description' => $description,
 534                      'date'        => $uDate,
 535                      'category'    => $category,
 536                      'author'      => $author,
 537                  );
 538  
 539                  $out[] = ($thing) ? parse($thing) : parse_form($form);
 540  
 541                  $thislink = '';
 542              }
 543  
 544              if ($out)
 545              {
 546                  return doLabel($label, $labeltag).doWrap($out, $wraptag, $break, $class);
 547              }
 548          }
 549  
 550          return false;
 551      }
 552  
 553  // -------------------------------------------------------------
 554  // NOTE: tpt_ prefix used because link() is a PHP function. See publish.php
 555  	function tpt_link($atts)
 556      {
 557          global $thislink;
 558          assert_link();
 559  
 560          extract(lAtts(array(
 561              'rel' => '',
 562          ), $atts));
 563  
 564          return tag(
 565              htmlspecialchars($thislink['linkname']), 'a',
 566              ($rel ? ' rel="'.$rel.'"' : '').
 567              ' href="'.doSpecial($thislink['url']).'"'
 568          );
 569      }
 570  
 571  // -------------------------------------------------------------
 572  
 573  	function linkdesctitle($atts)
 574      {
 575          global $thislink;
 576          assert_link();
 577  
 578          extract(lAtts(array(
 579              'rel' => '',
 580          ), $atts));
 581  
 582          $description = ($thislink['description']) ?
 583              ' title="'.htmlspecialchars($thislink['description']).'"' :
 584              '';
 585  
 586          return tag(
 587              htmlspecialchars($thislink['linkname']), 'a',
 588              ($rel ? ' rel="'.$rel.'"' : '').
 589              ' href="'.doSpecial($thislink['url']).'"'.$description
 590          );
 591      }
 592  
 593  // -------------------------------------------------------------
 594  
 595  	function link_name($atts)
 596      {
 597          global $thislink;
 598          assert_link();
 599  
 600          extract(lAtts(array(
 601              'escape' => 'html',
 602          ), $atts));
 603  
 604          return ($escape == 'html') ?
 605              htmlspecialchars($thislink['linkname']) :
 606              $thislink['linkname'];
 607      }
 608  
 609  // -------------------------------------------------------------
 610  
 611  	function link_url()
 612      {
 613          global $thislink;
 614          assert_link();
 615  
 616          return doSpecial($thislink['url']);
 617      }
 618  
 619  //--------------------------------------------------------------------------
 620  
 621  	function link_author($atts)
 622      {
 623          global $thislink, $s;
 624          assert_link();
 625  
 626          extract(lAtts(array(
 627              'class'        => '',
 628              'link'         => 0,
 629              'title'        => 1,
 630              'section'      => '',
 631              'this_section' => '',
 632              'wraptag'      => '',
 633          ), $atts));
 634  
 635          if ($thislink['author'])
 636          {
 637              $author_name = get_author_name($thislink['author']);
 638              $display_name = htmlspecialchars( ($title) ? $author_name : $thislink['author'] );
 639  
 640              $section = ($this_section) ? ( $s == 'default' ? '' : $s ) : $section;
 641  
 642              $author = ($link) ?
 643                  href($display_name, pagelinkurl(array('s' => $section, 'author' => $author_name, 'context' => 'link'))) :
 644                  $display_name;
 645  
 646              return ($wraptag) ? doTag($author, $wraptag, $class) : $author;
 647          }
 648      }
 649  
 650  // -------------------------------------------------------------
 651  
 652  	function link_description($atts)
 653      {
 654          global $thislink;
 655          assert_link();
 656  
 657          extract(lAtts(array(
 658              'class'    => '',
 659              'escape'   => 'html',
 660              'label'    => '',
 661              'labeltag' => '',
 662              'wraptag'  => '',
 663          ), $atts));
 664  
 665          if ($thislink['description'])
 666          {
 667              $description = ($escape == 'html') ?
 668                  htmlspecialchars($thislink['description']) :
 669                  $thislink['description'];
 670  
 671              return doLabel($label, $labeltag).doTag($description, $wraptag, $class);
 672          }
 673      }
 674  
 675  // -------------------------------------------------------------
 676  
 677  	function link_date($atts)
 678      {
 679          global $thislink, $dateformat;
 680          assert_link();
 681  
 682          extract(lAtts(array(
 683              'format' => $dateformat,
 684              'gmt'    => '',
 685              'lang'   => '',
 686          ), $atts));
 687  
 688          return safe_strftime($format, $thislink['date'], $gmt, $lang);
 689      }
 690  
 691  // -------------------------------------------------------------
 692  
 693  	function link_category($atts)
 694      {
 695          global $thislink;
 696          assert_link();
 697  
 698          extract(lAtts(array(
 699              'class'    => '',
 700              'label'    => '',
 701              'labeltag' => '',
 702              'title'    => 0,
 703              'wraptag'  => '',
 704          ), $atts));
 705  
 706          if ($thislink['category'])
 707          {
 708              $category = ($title) ?
 709                  fetch_category_title($thislink['category'], 'link') :
 710                  $thislink['category'];
 711  
 712              return doLabel($label, $labeltag).doTag($category, $wraptag, $class);
 713          }
 714      }
 715  
 716  // -------------------------------------------------------------
 717  
 718  	function link_id()
 719      {
 720          global $thislink;
 721          assert_link();
 722          return $thislink['id'];
 723      }
 724  
 725  // -------------------------------------------------------------
 726  	function link_format_info($link)
 727      {
 728          if (($unix_ts = @strtotime($link['date'])) > 0)
 729              $link['date'] = $unix_ts;
 730  
 731          return $link;
 732      }
 733  
 734  // -------------------------------------------------------------
 735      function eE($txt) // convert email address into unicode entities
 736      {
 737          for ($i=0;$i<strlen($txt);$i++) {
 738              $ent[] = "&#".ord(substr($txt,$i,1)).";";
 739          }
 740          if (!empty($ent)) return join('',$ent);
 741      }
 742  
 743  // -------------------------------------------------------------
 744  	function email($atts, $thing = NULL)
 745      {
 746          extract(lAtts(array(
 747              'email'    => '',
 748              'linktext' => gTxt('contact'),
 749              'title'    => '',
 750          ),$atts));
 751  
 752          if ($email) {
 753              if ($thing !== NULL) $linktext = parse($thing);
 754              // obfuscate link text?
 755              if (is_valid_email($linktext)) $linktext = eE($linktext);
 756  
 757              return '<a href="'.eE('mailto:'.$email).'"'.
 758                  ($title ? ' title="'.$title.'"' : '').">$linktext</a>";
 759          }
 760          return '';
 761      }
 762  
 763  // -------------------------------------------------------------
 764  	function password_protect($atts)
 765      {
 766          ob_start();
 767  
 768          extract(lAtts(array(
 769              'login' => '',
 770              'pass'  => '',
 771          ),$atts));
 772  
 773          $au = serverSet('PHP_AUTH_USER');
 774          $ap = serverSet('PHP_AUTH_PW');
 775          //For php as (f)cgi, two rules in htaccess often allow this workaround
 776          $ru = serverSet('REDIRECT_REMOTE_USER');
 777          if ($ru && !$au && !$ap && substr( $ru,0,5) == 'Basic' ) {
 778              list ( $au, $ap ) = explode( ':', base64_decode( substr( $ru,6)));
 779          }
 780          if ($login && $pass) {
 781              if (!$au || !$ap || $au!= $login || $ap!= $pass) {
 782                  header('WWW-Authenticate: Basic realm="Private"');
 783                  txp_die(gTxt('auth_required'), '401');
 784              }
 785          }
 786      }
 787  
 788  // -------------------------------------------------------------
 789  
 790  	function recent_articles($atts)
 791      {
 792          global $prefs;
 793          extract(lAtts(array(
 794              'break'    => br,
 795              'category' => '',
 796              'class'    => __FUNCTION__,
 797              'label'    => gTxt('recent_articles'),
 798              'labeltag' => '',
 799              'limit'    => 10,
 800              'section'  => '',
 801              'sort'     => 'Posted desc',
 802              'sortby'   => '', // deprecated
 803              'sortdir'  => '', // deprecated
 804              'wraptag'  => '',
 805              'no_widow' => @$prefs['title_no_widow'],
 806          ), $atts));
 807  
 808          // for backwards compatibility
 809          // sortby and sortdir are deprecated
 810          if ($sortby)
 811          {
 812              trigger_error(gTxt('deprecated_attribute', array('{name}' => 'sortby')), E_USER_NOTICE);
 813  
 814              if (!$sortdir)
 815              {
 816                  $sortdir = 'desc';
 817              }
 818              else
 819              {
 820                  trigger_error(gTxt('deprecated_attribute', array('{name}' => 'sortdir')), E_USER_NOTICE);
 821              }
 822  
 823              $sort = "$sortby $sortdir";
 824          }
 825  
 826          elseif ($sortdir)
 827          {
 828              trigger_error(gTxt('deprecated_attribute', array('{name}' => 'sortdir')), E_USER_NOTICE);
 829              $sort = "Posted $sortdir";
 830          }
 831  
 832          $category   = join("','", doSlash(do_list($category)));
 833          $categories = ($category) ? "and (Category1 IN ('".$category."') or Category2 IN ('".$category."'))" : '';
 834          $section = ($section) ? " and Section IN ('".join("','", doSlash(do_list($section)))."')" : '';
 835          $expired = ($prefs['publish_expired_articles']) ? '' : ' and (now() <= Expires or Expires = '.NULLDATETIME.') ';
 836  
 837          $rs = safe_rows_start('*, id as thisid, unix_timestamp(Posted) as posted', 'textpattern',
 838              "Status = 4 $section $categories and Posted <= now()$expired order by ".doSlash($sort).' limit 0,'.intval($limit));
 839  
 840          if ($rs)
 841          {
 842              $out = array();
 843  
 844              while ($a = nextRow($rs))
 845              {
 846                  $a['Title'] = ($no_widow) ? noWidow(escape_title($a['Title'])) : escape_title($a['Title']);
 847                  $out[] = href($a['Title'], permlinkurl($a));
 848              }
 849  
 850              if ($out)
 851              {
 852                  return doLabel($label, $labeltag).doWrap($out, $wraptag, $break, $class);
 853              }
 854          }
 855  
 856          return '';
 857      }
 858  
 859  // -------------------------------------------------------------
 860  
 861  	function recent_comments($atts, $thing = NULL)
 862      {
 863  
 864          global $prefs;
 865          global $thisarticle, $thiscomment;
 866          extract(lAtts(array(
 867              'break'    => br,
 868              'class'    => __FUNCTION__,
 869              'form'     => '',
 870              'label'    => '',
 871              'labeltag' => '',
 872              'limit'    => 10,
 873              'offset'   => 0,
 874              'sort'     => 'posted desc',
 875              'wraptag'  => '',
 876          ), $atts));
 877  
 878          $sort = preg_replace('/\bposted\b/', 'd.posted', $sort);
 879          $expired = ($prefs['publish_expired_articles']) ? '' : ' and (now() <= t.Expires or t.Expires = '.NULLDATETIME.') ';
 880  
 881          $rs = startRows('select d.name, d.email, d.web, d.message, d.discussid, unix_timestamp(d.Posted) as time, '.
 882                  't.ID as thisid, unix_timestamp(t.Posted) as posted, t.Title as title, t.Section as section, t.url_title '.
 883                  'from '. safe_pfx('txp_discuss') .' as d inner join '. safe_pfx('textpattern') .' as t on d.parentid = t.ID '.
 884                  'where t.Status >= 4'.$expired.' and d.visible = '.VISIBLE.' order by '.doSlash($sort).' limit '.intval($offset).','.intval($limit));
 885          if ($rs)
 886          {
 887              $out = array();
 888              $old_article = $thisarticle;
 889              while ($c = nextRow($rs))
 890              {
 891                  if (empty($form) && empty($thing))
 892                  {
 893                      $out[] = href(
 894                          htmlspecialchars($c['name']).' ('.escape_title($c['title']).')',
 895                          permlinkurl($c).'#c'.$c['discussid']
 896                      );
 897                  }
 898                  else
 899                  {
 900                      $thiscomment['name'] = $c['name'];
 901                      $thiscomment['email'] = $c['email'];
 902                      $thiscomment['web'] = $c['web'];
 903                      $thiscomment['message'] = $c['message'];
 904                      $thiscomment['discussid'] = $c['discussid'];
 905                      $thiscomment['time'] = $c['time'];
 906  
 907                      // allow permlink guesstimation in permlinkurl(), elsewhere
 908                      $thisarticle['thisid'] = $c['thisid'];
 909                      $thisarticle['posted'] = $c['posted'];
 910                      $thisarticle['title'] = $c['title'];
 911                      $thisarticle['section'] = $c['section'];
 912                      $thisarticle['url_title'] = $c['url_title'];
 913  
 914                      $out[] = ($thing) ? parse($thing) : parse_form($form);
 915                  }
 916              }
 917  
 918              if ($out)
 919              {
 920                  unset($GLOBALS['thiscomment']);
 921                  $thisarticle = $old_article;
 922                  return doLabel($label, $labeltag).doWrap($out, $wraptag, $break, $class);
 923              }
 924          }
 925  
 926          return '';
 927      }
 928  
 929  // -------------------------------------------------------------
 930  
 931  	function related_articles($atts, $thing = NULL)
 932      {
 933          global $thisarticle, $prefs;
 934  
 935          assert_article();
 936  
 937          extract(lAtts(array(
 938              'break'    => br,
 939              'class'    => __FUNCTION__,
 940              'form'       => '',
 941              'label'    => '',
 942              'labeltag' => '',
 943              'limit'    => 10,
 944              'match'    => 'Category1,Category2',
 945              'no_widow' => @$prefs['title_no_widow'],
 946              'section'  => '',
 947              'sort'     => 'Posted desc',
 948              'wraptag'  => '',
 949          ), $atts));
 950  
 951          if (empty($thisarticle['category1']) and empty($thisarticle['category2']))
 952          {
 953              return;
 954          }
 955  
 956          $match = do_list($match);
 957  
 958          if (!in_array('Category1', $match) and !in_array('Category2', $match))
 959          {
 960              return;
 961          }
 962  
 963          $id = $thisarticle['thisid'];
 964  
 965          $cats = array();
 966  
 967          if ($thisarticle['category1'])
 968          {
 969              $cats[] = doSlash($thisarticle['category1']);
 970          }
 971  
 972          if ($thisarticle['category2'])
 973          {
 974              $cats[] = doSlash($thisarticle['category2']);
 975          }
 976  
 977          $cats = join("','", $cats);
 978  
 979          $categories = array();
 980  
 981          if (in_array('Category1', $match))
 982          {
 983              $categories[] = "Category1 in('$cats')";
 984          }
 985  
 986          if (in_array('Category2', $match))
 987          {
 988              $categories[] = "Category2 in('$cats')";
 989          }
 990  
 991          $categories = 'and ('.join(' or ', $categories).')';
 992  
 993          $section = ($section) ? " and Section IN ('".join("','", doSlash(do_list($section)))."')" : '';
 994  
 995          $expired = ($prefs['publish_expired_articles']) ? '' : ' and (now() <= Expires or Expires = '.NULLDATETIME.') ';
 996          $rs = safe_rows_start('*, unix_timestamp(Posted) as posted, unix_timestamp(LastMod) as uLastMod, unix_timestamp(Expires) as uExpires', 'textpattern',
 997              'ID != '.intval($id)." and Status = 4 $expired  and Posted <= now() $categories $section order by ".doSlash($sort).' limit 0,'.intval($limit));
 998  
 999          if ($rs)
1000          {
1001              $out = array();
1002              $old_article = $thisarticle;
1003  
1004              while ($a = nextRow($rs))
1005              {
1006                  $a['Title'] = ($no_widow) ? noWidow(escape_title($a['Title'])) : escape_title($a['Title']);
1007                  $a['uPosted'] = $a['posted']; // populateArticleData() and permlinkurl() assume quite a bunch of posting dates...
1008  
1009                  if (empty($form) && empty($thing))
1010                  {
1011                      $out[] = href($a['Title'], permlinkurl($a));
1012                  }
1013                  else
1014                  {
1015                      populateArticleData($a);
1016                      $out[] = ($thing) ?  parse($thing) : parse_form($form);
1017                  }
1018              }
1019              $thisarticle = $old_article;
1020  
1021              if ($out)
1022              {
1023                  return doLabel($label, $labeltag).doWrap($out, $wraptag, $break, $class);
1024              }
1025          }
1026  
1027          return '';
1028      }
1029  
1030  // -------------------------------------------------------------
1031  
1032  	function popup($atts)
1033      {
1034          global $s, $c;
1035  
1036          extract(lAtts(array(
1037              'label'        => gTxt('browse'),
1038              'wraptag'      => '',
1039              'class'        => '',
1040              'section'      => '',
1041              'this_section' => 0,
1042              'type'         => 'c',
1043          ), $atts));
1044  
1045          if ($type == 's')
1046          {
1047              $rs = safe_rows_start('name, title', 'txp_section', "name != 'default' order by name");
1048          }
1049  
1050          else
1051          {
1052              $rs = safe_rows_start('name, title', 'txp_category', "type = 'article' and name != 'root' order by name");
1053          }
1054  
1055          if ($rs)
1056          {
1057              $out = array();
1058  
1059              $current = ($type == 's') ? $s : $c;
1060  
1061              $sel = '';
1062              $selected = false;
1063  
1064              while ($a = nextRow($rs))
1065              {
1066                  extract($a);
1067  
1068                  if ($name == $current)
1069                  {
1070                      $sel = ' selected="selected"';
1071                      $selected = true;
1072                  }
1073  
1074                  $out[] = '<option value="'.$name.'"'.$sel.'>'.htmlspecialchars($title).'</option>';
1075  
1076                  $sel = '';
1077              }
1078  
1079              if ($out)
1080              {
1081                  $section = ($this_section) ? ( $s == 'default' ? '' : $s) : $section;
1082  
1083                  $out = n.'<select name="'.$type.'" onchange="submit(this.form);">'.
1084                      n.t.'<option value=""'.($selected ? '' : ' selected="selected"').'>&nbsp;</option>'.
1085                      n.t.join(n.t, $out).
1086                      n.'</select>';
1087  
1088                  if ($label)
1089                  {
1090                      $out = $label.br.$out;
1091                  }
1092  
1093                  if ($wraptag)
1094                  {
1095                      $out = doTag($out, $wraptag, $class);
1096                  }
1097  
1098                  return '<form method="get" action="'.hu.'">'.
1099                      '<div>'.
1100                      ( ($type != 's' and $section and $s) ? n.hInput('s', $section) : '').
1101                      n.$out.
1102                      n.'<noscript><div><input type="submit" value="'.gTxt('go').'" /></div></noscript>'.
1103                      n.'</div>'.
1104                      n.'</form>';
1105              }
1106          }
1107      }
1108  
1109  // -------------------------------------------------------------
1110  // output href list of site categories
1111  
1112  	function category_list($atts, $thing = NULL)
1113      {
1114          global $s, $c, $thiscategory;
1115  
1116          extract(lAtts(array(
1117              'active_class' => '',
1118              'break'        => br,
1119              'categories'   => '',
1120              'class'        => __FUNCTION__,
1121              'exclude'      => '',
1122              'form'         => '',
1123              'label'        => '',
1124              'labeltag'     => '',
1125              'parent'       => '',
1126              'section'      => '',
1127              'children'     => '1',
1128              'sort'         => '',
1129              'this_section' => 0,
1130              'type'         => 'article',
1131              'wraptag'      => '',
1132          ), $atts));
1133  
1134          $sort = doSlash($sort);
1135  
1136          if ($categories)
1137          {
1138              $categories = do_list($categories);
1139              $categories = join("','", doSlash($categories));
1140  
1141              $rs = safe_rows_start('name, title', 'txp_category',
1142                  "type = '".doSlash($type)."' and name in ('$categories') order by ".($sort ? $sort : "field(name, '$categories')"));
1143          }
1144  
1145          else
1146          {
1147              if ($children)
1148              {
1149                  $shallow = '';
1150              } else {
1151                  // descend only one level from either 'parent' or 'root', plus parent category
1152                  $shallow = ($parent) ? "and (parent = '".doSlash($parent)."' or name = '".doSlash($parent)."')" : "and parent = 'root'" ;
1153              }
1154  
1155              if ($exclude)
1156              {
1157                  $exclude = do_list($exclude);
1158  
1159                  $exclude = join("','", doSlash($exclude));
1160  
1161                  $exclude = "and name not in('$exclude')";
1162              }
1163  
1164              if ($parent)
1165              {
1166                  $qs = safe_row('lft, rgt', 'txp_category', "type = '".doSlash($type)."' and name = '".doSlash($parent)."'");
1167  
1168                  if ($qs)
1169                  {
1170                      extract($qs);
1171  
1172                      $rs = safe_rows_start('name, title', 'txp_category',
1173                          "(lft between $lft and $rgt) and type = '".doSlash($type)."' and name != 'default' $exclude $shallow order by ".($sort ? $sort : 'lft ASC'));
1174                  }
1175              }
1176  
1177              else
1178              {
1179                  $rs = safe_rows_start('name, title', 'txp_category',
1180                      "type = '".doSlash($type)."' and name not in('default','root') $exclude $shallow order by ".($sort ? $sort : 'name ASC'));
1181              }
1182          }
1183  
1184          if ($rs)
1185          {
1186              $out = array();
1187              $count = 0;
1188              $last = numRows($rs);
1189  
1190              if (isset($thiscategory)) $old_category = $thiscategory;
1191              while ($a = nextRow($rs))
1192              {
1193                  ++$count;
1194                  extract($a);
1195  
1196                  if ($name)
1197                  {
1198                      $section = ($this_section) ? ( $s == 'default' ? '' : $s ) : $section;
1199  
1200                      if (empty($form) && empty($thing))
1201                      {
1202                          $out[] = tag(htmlspecialchars($title), 'a',
1203                              ( ($active_class and (0 == strcasecmp($c, $name))) ? ' class="'.$active_class.'"' : '' ).
1204                              ' href="'.pagelinkurl(array('s' => $section, 'c' => $name, 'context' => $type)).'"'
1205                          );
1206                      }
1207                      else
1208                      {
1209                          $thiscategory = array('name' => $name, 'title' => $title, 'type' => $type);
1210                          $thiscategory['is_first'] = ($count == 1);
1211                          $thiscategory['is_last'] = ($count == $last);
1212                          $out[] = ($thing) ? parse($thing) : parse_form($form);
1213                      }
1214                  }
1215              }
1216              $thiscategory = (isset($old_category) ? $old_category : NULL);
1217  
1218              if ($out)
1219              {
1220                  return doLabel($label, $labeltag).doWrap($out, $wraptag, $break, $class);
1221              }
1222          }
1223  
1224          return '';
1225      }
1226  
1227  // -------------------------------------------------------------
1228  // output href list of site sections
1229  
1230  	function section_list($atts, $thing = NULL)
1231      {
1232          global $sitename, $s, $thissection;
1233  
1234          extract(lAtts(array(
1235              'active_class'    => '',
1236              'break'           => br,
1237              'class'           => __FUNCTION__,
1238              'default_title'   => $sitename,
1239              'exclude'         => '',
1240              'form'            => '',
1241              'include_default' => '',
1242              'label'           => '',
1243              'labeltag'        => '',
1244              'sections'        => '',
1245              'sort'            => '',
1246              'wraptag'         => '',
1247          ), $atts));
1248  
1249          $sort = doSlash($sort);
1250  
1251          $rs = array();
1252          if ($sections)
1253          {
1254              $sections = do_list($sections);
1255  
1256              $sections = join("','", doSlash($sections));
1257  
1258              $rs = safe_rows('name, title', 'txp_section', "name in ('$sections') order by ".($sort ? $sort : "field(name, '$sections')"));
1259          }
1260  
1261          else
1262          {
1263              if ($exclude)
1264              {
1265                  $exclude = do_list($exclude);
1266  
1267                  $exclude = join("','", doSlash($exclude));
1268  
1269                  $exclude = "and name not in('$exclude')";
1270              }
1271  
1272              $rs = safe_rows('name, title', 'txp_section', "name != 'default' $exclude order by ".($sort ? $sort : 'name ASC'));
1273          }
1274  
1275          if ($include_default)
1276          {
1277              array_unshift($rs, array('name' => 'default', 'title' => $default_title));
1278          }
1279  
1280          if ($rs)
1281          {
1282              $out = array();
1283              $count = 0;
1284              $last = count($rs);
1285  
1286              if (isset($thissection)) $old_section = $thissection;
1287              foreach ($rs as $a)
1288              {
1289                  ++$count;
1290                  extract($a);
1291  
1292                  if (empty($form) && empty($thing))
1293                  {
1294                      $url = pagelinkurl(array('s' => $name));
1295  
1296                      $out[] = tag(htmlspecialchars($title), 'a',
1297                          ( ($active_class and (0 == strcasecmp($s, $name))) ? ' class="'.$active_class.'"' : '' ).
1298                          ' href="'.$url.'"'
1299                      );
1300                  }
1301                  else
1302                  {
1303                      $thissection = array('name' => $name, 'title' => ($name == 'default') ? $default_title : $title);
1304                      $thissection['is_first'] = ($count == 1);
1305                      $thissection['is_last'] = ($count == $last);
1306                      $out[] = ($thing) ? parse($thing) : parse_form($form);
1307                  }
1308              }
1309              $thissection = (isset($old_section) ? $old_section : NULL);
1310  
1311              if ($out)
1312              {
1313                  return doLabel($label, $labeltag).doWrap($out, $wraptag, $break, $class);
1314              }
1315          }
1316  
1317          return '';
1318      }
1319  
1320  // -------------------------------------------------------------
1321  	function search_input($atts) // input form for search queries
1322      {
1323          global $q, $permlink_mode;
1324          extract(lAtts(array(
1325              'form'    => 'search_input',
1326              'wraptag' => 'p',
1327              'class'   => __FUNCTION__,
1328              'size'    => '15',
1329              'html_id' => '',
1330              'label'   => gTxt('search'),
1331              'button'  => '',
1332              'section' => '',
1333              'match' => 'exact',
1334          ),$atts));
1335  
1336          if ($form) {
1337              $rs = fetch('form','txp_form','name',$form);
1338              if ($rs) {
1339                  return parse($rs);
1340              }
1341          }
1342  
1343          $sub = (!empty($button)) ? '<input type="submit" value="'.$button.'" />' : '';
1344          $id =  (!empty($html_id)) ? ' id="'.$html_id.'"' : '';
1345          $out = fInput('text','q',$q,'','','',$size);
1346          $out = (!empty($label)) ? $label.br.$out.$sub : $out.$sub;
1347          $out = ($match === 'exact') ? $out : fInput('hidden','m',$match) . $out;
1348          $out = ($wraptag) ? doTag($out,$wraptag, $class) : $out;
1349  
1350          if (!$section) {
1351              return '<form method="get" action="'.hu.'"'.$id.'>'.
1352                  n.$out.
1353                  n.'</form>';
1354          }
1355  
1356          if ($permlink_mode != 'messy') {
1357              return '<form method="get" action="'.pagelinkurl(array('s' => $section)).'"'.$id.'>'.
1358                  n.$out.
1359                  n.'</form>';
1360          }
1361  
1362          return '<form method="get" action="'.hu.'"'.$id.'>'.
1363              n.hInput('s', $section).
1364              n.$out.
1365              n.'</form>';
1366      }
1367  
1368  // -------------------------------------------------------------
1369  	function search_term($atts)
1370      {
1371          global $q;
1372          if(empty($q)) return '';
1373  
1374          extract(lAtts(array(
1375              'escape' => 'html'
1376          ),$atts));
1377  
1378          return ($escape == 'html' ? htmlspecialchars($q) : $q);
1379      }
1380  
1381  // -------------------------------------------------------------
1382  // link to next article, if it exists
1383  
1384  	function link_to_next($atts, $thing = NULL)
1385      {
1386          global $id, $next_id, $next_title;
1387  
1388          extract(lAtts(array(
1389              'showalways' => 0,
1390          ), $atts));
1391  
1392          if (intval($id) == 0)
1393          {
1394              global $thisarticle, $s;
1395  
1396              assert_article();
1397  
1398              extract(getNextPrev(
1399                  @$thisarticle['thisid'],
1400                  @strftime('%Y-%m-%d %H:%M:%S', $thisarticle['posted']),
1401                  @$s
1402              ));
1403          }
1404  
1405          if ($next_id)
1406          {
1407              $url = permlinkurl_id($next_id);
1408  
1409              if ($thing)
1410              {
1411                  $thing = parse($thing);
1412                  $next_title = escape_title($next_title);
1413  
1414                  return '<a rel="next" href="'.$url.'"'.
1415                      ($next_title != $thing ? ' title="'.$next_title.'"' : '').
1416                      '>'.$thing.'</a>';
1417              }
1418  
1419              return $url;
1420          }
1421  
1422          return ($showalways) ? parse($thing) : '';
1423      }
1424  
1425  // -------------------------------------------------------------
1426  // link to next article, if it exists
1427  
1428  	function link_to_prev($atts, $thing = NULL)
1429      {
1430          global $id, $prev_id, $prev_title;
1431  
1432          extract(lAtts(array(
1433              'showalways' => 0,
1434          ), $atts));
1435  
1436          if (intval($id) == 0)
1437          {
1438              global $thisarticle, $s;
1439  
1440              assert_article();
1441  
1442              extract(getNextPrev(
1443                  $thisarticle['thisid'],
1444                  @strftime('%Y-%m-%d %H:%M:%S', $thisarticle['posted']),
1445                  @$s
1446              ));
1447          }
1448  
1449          if ($prev_id)
1450          {
1451              $url = permlinkurl_id($prev_id);
1452  
1453              if ($thing)
1454              {
1455                  $thing = parse($thing);
1456                  $prev_title = escape_title($prev_title);
1457  
1458                  return '<a rel="prev" href="'.$url.'"'.
1459                      ($prev_title != $thing ? ' title="'.$prev_title.'"' : '').
1460                      '>'.$thing.'</a>';
1461              }
1462  
1463              return $url;
1464          }
1465  
1466          return ($showalways) ? parse($thing) : '';
1467      }
1468  
1469  // -------------------------------------------------------------
1470  
1471  	function next_title()
1472      {
1473          return escape_title($GLOBALS['next_title']);
1474      }
1475  
1476  // -------------------------------------------------------------
1477  
1478  	function prev_title()
1479      {
1480          return escape_title($GLOBALS['prev_title']);
1481      }
1482  
1483  // -------------------------------------------------------------
1484  
1485  	function site_name()
1486      {
1487          return htmlspecialchars($GLOBALS['sitename']);
1488      }
1489  
1490  // -------------------------------------------------------------
1491  
1492  	function site_slogan()
1493      {
1494          return htmlspecialchars($GLOBALS['site_slogan']);
1495      }
1496  
1497  // -------------------------------------------------------------
1498  
1499  	function link_to_home($atts, $thing = NULL)
1500      {
1501          extract(lAtts(array(
1502              'class' => false,
1503          ), $atts));
1504  
1505          if ($thing)
1506          {
1507              $class = ($class) ? ' class="'.$class.'"' : '';
1508              return '<a rel="home" href="'.hu.'"'.$class.'>'.parse($thing).'</a>';
1509          }
1510  
1511          return hu;
1512      }
1513  
1514  // -------------------------------------------------------------
1515  
1516  	function newer($atts, $thing = NULL)
1517      {
1518          global $thispage, $pretext, $m;
1519  
1520          extract(lAtts(array(
1521              'showalways'    => 0,
1522              'title'            => '',
1523              'escape'        => 'html'
1524          ), $atts));
1525  
1526          $numPages = $thispage['numPages'];
1527          $pg = $thispage['pg'];
1528  
1529          if ($numPages > 1 and $pg > 1 and $pg <= $numPages)
1530          {
1531              $nextpg = ($pg - 1 == 1) ? 0 : ($pg - 1);
1532  
1533              // author urls should use RealName, rather than username
1534              if (!empty($pretext['author'])) {
1535                  $author = safe_field('RealName', 'txp_users', "name = '".doSlash($pretext['author'])."'");
1536              } else {
1537                  $author = '';
1538              }
1539  
1540              $url = pagelinkurl(array(
1541                  'month'   => @$pretext['month'],
1542                  'pg'      => $nextpg,
1543                  's'       => @$pretext['s'],
1544                  'c'       => @$pretext['c'],
1545                  'context' => @$pretext['context'],
1546                  'q'       => @$pretext['q'],
1547                  'm'       => @$m,
1548                  'author'  => $author
1549              ));
1550  
1551              if ($thing)
1552              {
1553                  if ($escape == 'html')
1554                  {
1555                      $title = escape_title($title);
1556                  }
1557  
1558                  return '<a href="'.$url.'"'.
1559                      (empty($title) ? '' : ' title="'.$title.'"').
1560                      '>'.parse($thing).'</a>';
1561              }
1562  
1563              return $url;
1564          }
1565  
1566          return ($showalways) ? parse($thing) : '';
1567      }
1568  
1569  // -------------------------------------------------------------
1570  
1571  	function older($atts, $thing = NULL)
1572      {
1573          global $thispage, $pretext, $m;
1574  
1575          extract(lAtts(array(
1576              'showalways'    => 0,
1577              'title'            => '',
1578              'escape'        => 'html'
1579          ), $atts));
1580  
1581          $numPages = $thispage['numPages'];
1582          $pg = $thispage['pg'];
1583  
1584          if ($numPages > 1 and $pg > 0 and $pg < $numPages)
1585          {
1586              $nextpg = $pg + 1;
1587  
1588              // author urls should use RealName, rather than username
1589              if (!empty($pretext['author'])) {
1590                  $author = safe_field('RealName', 'txp_users', "name = '".doSlash($pretext['author'])."'");
1591              } else {
1592                  $author = '';
1593              }
1594  
1595              $url = pagelinkurl(array(
1596                  'month'   => @$pretext['month'],
1597                  'pg'      => $nextpg,
1598                  's'       => @$pretext['s'],
1599                  'c'       => @$pretext['c'],
1600                  'context' => @$pretext['context'],
1601                  'q'       => @$pretext['q'],
1602                  'm'       => @$m,
1603                  'author'  => $author
1604              ));
1605  
1606              if ($thing)
1607              {
1608                  if ($escape == 'html')
1609                  {
1610                      $title = escape_title($title);
1611                  }
1612  
1613                  return '<a href="'.$url.'"'.
1614                      (empty($title) ? '' : ' title="'.$title.'"').
1615                      '>'.parse($thing).'</a>';
1616              }
1617  
1618              return $url;
1619          }
1620  
1621          return ($showalways) ? parse($thing) : '';
1622      }
1623  
1624  // -------------------------------------------------------------
1625  	function text($atts)
1626      {
1627          extract(lAtts(array(
1628              'item' => '',
1629          ),$atts));
1630          return ($item) ? gTxt($item) : '';
1631      }
1632  
1633  // -------------------------------------------------------------
1634  
1635  	function article_id()
1636      {
1637          global $thisarticle;
1638  
1639          assert_article();
1640  
1641          return $thisarticle['thisid'];
1642      }
1643  
1644  // -------------------------------------------------------------
1645  
1646  	function article_url_title()
1647      {
1648          global $thisarticle;
1649  
1650          assert_article();
1651  
1652          return $thisarticle['url_title'];
1653      }
1654  
1655  // -------------------------------------------------------------
1656  
1657  	function if_article_id($atts, $thing)
1658      {
1659          global $thisarticle, $pretext;
1660  
1661          assert_article();
1662  
1663          extract(lAtts(array(
1664              'id' => $pretext['id'],
1665          ), $atts));
1666  
1667          if ($id)
1668          {
1669              return parse(EvalElse($thing, in_list($thisarticle['thisid'], $id)));
1670          }
1671      }
1672  
1673  // -------------------------------------------------------------
1674  
1675  	function posted($atts)
1676      {
1677          global $thisarticle, $id, $c, $pg, $dateformat, $archive_dateformat;
1678  
1679          assert_article();
1680  
1681          extract(lAtts(array(
1682              'class'   => '',
1683              'format'  => '',
1684              'gmt'     => '',
1685              'lang'    => '',
1686              'wraptag' => ''
1687          ), $atts));
1688  
1689          if ($format)
1690          {
1691              $out = safe_strftime($format, $thisarticle['posted'], $gmt, $lang);
1692          }
1693  
1694          else
1695          {
1696              if ($id or $c or $pg)
1697              {
1698                  $out = safe_strftime($archive_dateformat, $thisarticle['posted']);
1699              }
1700  
1701              else
1702              {
1703                  $out = safe_strftime($dateformat, $thisarticle['posted']);
1704              }
1705          }
1706  
1707          return ($wraptag) ? doTag($out, $wraptag, $class) : $out;
1708      }
1709  
1710  // -------------------------------------------------------------
1711  
1712  	function expires($atts)
1713      {
1714          global $thisarticle, $id, $c, $pg, $dateformat, $archive_dateformat;
1715  
1716          assert_article();
1717  
1718          if($thisarticle['expires'] == 0)
1719          {
1720              return;
1721          }
1722  
1723          extract(lAtts(array(
1724              'class'   => '',
1725              'format'  => '',
1726              'gmt'     => '',
1727              'lang'    => '',
1728              'wraptag' => '',
1729          ), $atts));
1730  
1731          if ($format)
1732          {
1733              $out = safe_strftime($format, $thisarticle['expires'], $gmt, $lang);
1734          }
1735  
1736          else
1737          {
1738              if ($id or $c or $pg)
1739              {
1740                  $out = safe_strftime($archive_dateformat, $thisarticle['expires']);
1741              }
1742  
1743              else
1744              {
1745                  $out = safe_strftime($dateformat, $thisarticle['expires']);
1746              }
1747          }
1748  
1749          return ($wraptag) ? doTag($out, $wraptag, $class) : $out;
1750      }
1751  
1752  // -------------------------------------------------------------
1753  
1754  	function if_expires($atts, $thing)
1755      {
1756          global $thisarticle;
1757          assert_article();
1758          return parse(EvalElse($thing, $thisarticle['expires']));
1759      }
1760  
1761  // -------------------------------------------------------------
1762  
1763  	function if_expired($atts, $thing)
1764      {
1765          global $thisarticle;
1766          assert_article();
1767          return parse(EvalElse($thing,
1768              $thisarticle['expires'] && ($thisarticle['expires'] <= time() )));
1769      }
1770  
1771  // -------------------------------------------------------------
1772  
1773  	function modified($atts)
1774      {
1775          global $thisarticle, $id, $c, $pg, $dateformat, $archive_dateformat;
1776  
1777          assert_article();
1778  
1779          extract(lAtts(array(
1780              'format'  => '',
1781              'gmt'     => '',
1782              'lang'    => ''
1783          ), $atts));
1784  
1785          if ($format)
1786          {
1787              return safe_strftime($format, $thisarticle['modified'], $gmt, $lang);
1788          }
1789  
1790          else
1791          {
1792              if ($id or $c or $pg)
1793              {
1794                  return safe_strftime($archive_dateformat, $thisarticle['modified']);
1795              }
1796  
1797              else
1798              {
1799                  return safe_strftime($dateformat, $thisarticle['modified']);
1800              }
1801          }
1802      }
1803  
1804  // -------------------------------------------------------------
1805  
1806  	function comments_count()
1807      {
1808          global $thisarticle;
1809  
1810          assert_article();
1811  
1812          return $thisarticle['comments_count'];
1813      }
1814  
1815  // -------------------------------------------------------------
1816  	function comments_invite($atts)
1817      {
1818          global $thisarticle,$is_article_list;
1819  
1820          assert_article();
1821  
1822          extract($thisarticle);
1823          global $comments_mode;
1824  
1825          if (!$comments_invite)
1826              $comments_invite = @$GLOBALS['prefs']['comments_default_invite'];
1827  
1828          extract(lAtts(array(
1829              'class'        => __FUNCTION__,
1830              'showcount'    => true,
1831              'textonly'    => false,
1832              'showalways'=> false,  //FIXME in crockery. This is only for BC.
1833              'wraptag'   => '',
1834          ), $atts));
1835  
1836          $invite_return = '';
1837          if (($annotate or $comments_count) && ($showalways or $is_article_list) ) {
1838  
1839              $ccount = ($comments_count && $showcount) ?  ' ['.$comments_count.']' : '';
1840              if ($textonly)
1841                  $invite_return = $comments_invite.$ccount;
1842              else
1843              {
1844                  if (!$comments_mode) {
1845                      $invite_return = doTag($comments_invite, 'a', $class, ' href="'.permlinkurl($thisarticle).'#'.gTxt('comment').'" '). $ccount;
1846                  } else {
1847                      $invite_return = "<a href=\"".hu."?parentid=$thisid\" onclick=\"window.open(this.href, 'popupwindow', 'width=500,height=500,scrollbars,resizable,status'); return false;\"".(($class) ? ' class="'.$class.'"' : '').'>'.$comments_invite.'</a> '.$ccount;
1848                  }
1849              }
1850              if ($wraptag) $invite_return = doTag($invite_return, $wraptag, $class);
1851          }
1852  
1853          return $invite_return;
1854      }
1855  // -------------------------------------------------------------
1856  
1857  	function comments_form($atts)
1858      {
1859          global $thisarticle, $has_comments_preview;
1860  
1861          extract(lAtts(array(
1862              'class'        => __FUNCTION__,
1863              'form'         => 'comment_form',
1864              'isize'        => '25',
1865              'msgcols'      => '25',
1866              'msgrows'      => '5',
1867              'msgstyle'     => '',
1868              'show_preview' => empty($has_comments_preview),
1869              'wraptag'      => '',
1870          ), $atts));
1871  
1872          assert_article();
1873  
1874          extract($thisarticle);
1875  
1876          $out = '';
1877          $ip = serverset('REMOTE_ADDR');
1878          $blacklisted = is_blacklisted($ip);
1879  
1880          if (!checkCommentsAllowed($thisid)) {
1881              $out = graf(gTxt("comments_closed"), ' id="comments_closed"');
1882          } elseif (!checkBan($ip)) {
1883              $out = graf(gTxt('you_have_been_banned'), ' id="comments_banned"');
1884          } elseif ($blacklisted) {
1885              $out = graf(gTxt('your_ip_is_blacklisted_by'.' '.$blacklisted), ' id="comments_blacklisted"');
1886          } elseif (gps('commented')!=='') {
1887              $out = gTxt("comment_posted");
1888              if (gps('commented')==='0')
1889                  $out .= " ". gTxt("comment_moderated");
1890              $out = graf($out, ' id="txpCommentInputForm"');
1891          } else {
1892              # display a comment preview if required
1893              if (ps('preview') and $show_preview)
1894                  $out = comments_preview(array());
1895              $out .= commentForm($thisid,$atts);
1896          }
1897  
1898          return (!$wraptag ? $out : doTag($out,$wraptag,$class) );
1899      }
1900  
1901  // -------------------------------------------------------------
1902  
1903  	function comments_error($atts)
1904      {
1905          extract(lAtts(array(
1906              'break'        => 'br',
1907              'class'        => __FUNCTION__,
1908              'wraptag'    => 'div',
1909          ), $atts));
1910  
1911          $evaluator =& get_comment_evaluator();
1912  
1913          $errors = $evaluator->get_result_message();
1914  
1915          if ($errors)
1916          {
1917              return doWrap($errors, $wraptag, $break, $class);
1918          }
1919      }
1920  
1921  // -------------------------------------------------------------
1922  	function if_comments_error($atts, $thing)
1923      {
1924          $evaluator =& get_comment_evaluator();
1925          return parse(EvalElse($thing,(count($evaluator -> get_result_message()) > 0)));
1926      }
1927  
1928  // -------------------------------------------------------------
1929      # DEPRECATED - provided only for backwards compatibility
1930      # this functionality will be merged into comments_invite
1931      # no point in having two tags for one functionality
1932  	function comments_annotateinvite($atts, $thing)
1933      {
1934          trigger_error(gTxt('deprecated_tag'), E_USER_NOTICE);
1935  
1936          global $thisarticle, $pretext;
1937  
1938          extract(lAtts(array(
1939              'class'        => __FUNCTION__,
1940              'wraptag'    => 'h3',
1941          ),$atts));
1942  
1943          assert_article();
1944  
1945          extract($thisarticle);
1946  
1947          extract(
1948              safe_row(
1949                  "Annotate,AnnotateInvite,unix_timestamp(Posted) as uPosted",
1950                      "textpattern", 'ID = '.intval($thisid)
1951              )
1952          );
1953  
1954          if (!$thing)
1955              $thing = $AnnotateInvite;
1956  
1957          return (!$Annotate) ? '' : doTag($thing,$wraptag,$class,' id="'.gTxt('comment').'"');
1958      }
1959  
1960  // -------------------------------------------------------------
1961  	function comments($atts)
1962      {
1963          global $thisarticle, $prefs;
1964          extract($prefs);
1965  
1966          extract(lAtts(array(
1967              'form'       => 'comments',
1968              'wraptag'    => ($comments_are_ol ? 'ol' : ''),
1969              'break'      => ($comments_are_ol ? 'li' : 'div'),
1970              'class'      => __FUNCTION__,
1971              'breakclass' => '',
1972              'limit'      => 0,
1973              'offset'     => 0,
1974              'sort'       => 'posted ASC',
1975          ),$atts));
1976  
1977          assert_article();
1978  
1979          extract($thisarticle);
1980  
1981          if (!$comments_count) return '';
1982  
1983          $qparts = array(
1984              'parentid='.intval($thisid).' and visible='.VISIBLE,
1985              'order by '.doSlash($sort),
1986              ($limit) ? 'limit '.intval($offset).', '.intval($limit) : ''
1987          );
1988  
1989          $rs = safe_rows_start('*, unix_timestamp(posted) as time', 'txp_discuss', join(' ', $qparts));
1990  
1991          $out = '';
1992  
1993          if ($rs) {
1994              $comments = array();
1995  
1996              while($vars = nextRow($rs)) {
1997                  $GLOBALS['thiscomment'] = $vars;
1998                  $comments[] = parse_form($form).n;
1999                  unset($GLOBALS['thiscomment']);
2000              }
2001  
2002              $out .= doWrap($comments,$wraptag,$break,$class,$breakclass);
2003          }
2004  
2005          return $out;
2006      }
2007  
2008  // -------------------------------------------------------------
2009  	function comments_preview($atts)
2010      {
2011          global $has_comments_preview;
2012  
2013          if (!ps('preview'))
2014              return;
2015  
2016          extract(lAtts(array(
2017              'form'        => 'comments',
2018              'wraptag'    => '',
2019              'class'        => __FUNCTION__,
2020          ),$atts));
2021  
2022          assert_article();
2023  
2024          $preview = psa(array('name','email','web','message','parentid','remember'));
2025          $preview['time'] = time();
2026          $preview['discussid'] = 0;
2027          $preview['name'] = strip_tags($preview['name']);
2028          $preview['email'] = clean_url($preview['email']);
2029          if ($preview['message'] == '')
2030          {
2031              $in = getComment();
2032              $preview['message'] = $in['message'];
2033  
2034          }
2035          $preview['message'] = markup_comment(substr(trim($preview['message']), 0, 65535)); // it is called 'message', not 'novel'
2036          $preview['web'] = clean_url($preview['web']);
2037  
2038          $GLOBALS['thiscomment'] = $preview;
2039          $comments = parse_form($form).n;
2040          unset($GLOBALS['thiscomment']);
2041          $out = doTag($comments,$wraptag,$class);
2042  
2043          # set a flag, to tell the comments_form tag that it doesn't have to show a preview
2044          $has_comments_preview = true;
2045  
2046          return $out;
2047      }
2048  
2049  // -------------------------------------------------------------
2050  	function if_comments_preview($atts, $thing)
2051      {
2052          return parse(EvalElse($thing, ps('preview') && checkCommentsAllowed(gps('parentid')) ));
2053      }
2054  
2055  // -------------------------------------------------------------
2056  	function comment_permlink($atts, $thing)
2057      {
2058          global $thisarticle, $thiscomment;
2059  
2060          assert_article();
2061          assert_comment();
2062  
2063          extract($thiscomment);
2064          extract(lAtts(array(
2065              'anchor' => empty($thiscomment['has_anchor_tag']),
2066          ),$atts));
2067  
2068          $dlink = permlinkurl($thisarticle).'#c'.$discussid;
2069  
2070          $thing = parse($thing);
2071  
2072          $name = ($anchor ? ' id="c'.$discussid.'"' : '');
2073  
2074          return tag($thing,'a',' href="'.$dlink.'"'.$name);
2075      }
2076  
2077  // -------------------------------------------------------------
2078  	function comment_id()
2079      {
2080          global $thiscomment;
2081  
2082          assert_comment();
2083  
2084          return $thiscomment['discussid'];
2085      }
2086  
2087  // -------------------------------------------------------------
2088  
2089  	function comment_name($atts)
2090      {
2091          global $thiscomment, $prefs;
2092  
2093          assert_comment();
2094  
2095          extract($prefs);
2096          extract($thiscomment);
2097  
2098          extract(lAtts(array(
2099              'link' => 1,
2100          ), $atts));
2101  
2102          $name = htmlspecialchars($name);
2103  
2104          if ($link)
2105          {
2106              if (!preg_match('|^https?://|', $web))
2107              {
2108                  $web = 'http://'.$web;
2109              }
2110  
2111              $nofollow = (@$comment_nofollow ? ' rel="nofollow"' : '');
2112  
2113              if (preg_match('|^https?://\S|', $web))
2114              {
2115                  return '<a href="'.htmlspecialchars($web).'"'.$nofollow.'>'.$name.'</a>';
2116              }
2117  
2118              if ($email && !$never_display_email)
2119              {
2120                  return '<a href="'.eE('mailto:'.$email).'"'.$nofollow.'>'.$name.'</a>';
2121              }
2122          }
2123  
2124          return $name;
2125      }
2126  
2127  // -------------------------------------------------------------
2128  	function comment_email()
2129      {
2130          global $thiscomment;
2131  
2132          assert_comment();
2133  
2134          return htmlspecialchars($thiscomment['email']);
2135      }
2136  
2137  // -------------------------------------------------------------
2138  	function comment_web()
2139      {
2140          global $thiscomment;
2141  
2142          assert_comment();
2143  
2144          return htmlspecialchars($thiscomment['web']);
2145      }
2146  
2147  // -------------------------------------------------------------
2148  
2149  	function comment_time($atts)
2150      {
2151          global $thiscomment, $comments_dateformat;
2152  
2153          assert_comment();
2154  
2155          extract(lAtts(array(
2156              'format' => $comments_dateformat,
2157              'gmt'    => '',
2158              'lang'   => '',
2159          ), $atts));
2160  
2161          return safe_strftime($format, $thiscomment['time'], $gmt, $lang);
2162      }
2163  
2164  // -------------------------------------------------------------
2165  	function comment_message()
2166      {
2167          global $thiscomment;
2168  
2169          assert_comment();
2170  
2171          return $thiscomment['message'];
2172      }
2173  
2174  // -------------------------------------------------------------
2175  	function comment_anchor()
2176      {
2177          global $thiscomment;
2178  
2179          assert_comment();
2180  
2181          $thiscomment['has_anchor_tag'] = 1;
2182          return '<a id="c'.$thiscomment['discussid'].'"></a>';
2183      }
2184  
2185  // -------------------------------------------------------------
2186  
2187  	function author($atts)
2188      {
2189          global $thisarticle, $s;
2190  
2191          assert_article();
2192  
2193          extract(lAtts(array(
2194              'link'         => '',
2195              'title'        => 1,
2196              'section'      => '',
2197              'this_section' => 0,
2198          ), $atts));
2199  
2200          $author_name = get_author_name($thisarticle['authorid']);
2201          $display_name = htmlspecialchars( ($title) ? $author_name : $thisarticle['authorid'] );
2202  
2203          $section = ($this_section) ? ( $s == 'default' ? '' : $s ) : $section;
2204  
2205          return ($link) ?
2206              href($display_name, pagelinkurl(array('s' => $section, 'author' => $author_name))) :
2207              $display_name;
2208      }
2209  
2210  // -------------------------------------------------------------
2211  
2212  	function if_author($atts, $thing)
2213      {
2214          global $author, $context;
2215  
2216          extract(lAtts(array(
2217              'type' => 'article',
2218              'name' => '',
2219          ),$atts));
2220  
2221          $theType = ($type) ? $type == $context : true;
2222  
2223          if ($name)
2224          {
2225              return parse(EvalElse($thing, ($theType && in_list($author, $name))));
2226          }
2227  
2228          return parse(EvalElse($thing, ($theType && !empty($author))));
2229      }
2230  
2231  // -------------------------------------------------------------
2232  
2233  	function if_article_author($atts, $thing)
2234      {
2235          global $thisarticle;
2236  
2237          assert_article();
2238  
2239          extract(lAtts(array(
2240              'name' => '',
2241          ), $atts));
2242  
2243          $author = $thisarticle['authorid'];
2244  
2245          if ($name)
2246          {
2247              return parse(EvalElse($thing, in_list($author, $name)));
2248          }
2249  
2250          return parse(EvalElse($thing, !empty($author)));
2251      }
2252  
2253  // -------------------------------------------------------------
2254  
2255  	function body()
2256      {
2257          global $thisarticle, $is_article_body;
2258          assert_article();
2259  
2260          $is_article_body = 1;
2261          $out = parse($thisarticle['body']);
2262          $is_article_body = 0;
2263          return $out;
2264      }
2265  
2266  // -------------------------------------------------------------
2267  	function title($atts)
2268      {
2269          global $thisarticle, $prefs;
2270          assert_article();
2271          extract(lAtts(array(
2272              'no_widow' => @$prefs['title_no_widow'],
2273          ), $atts));
2274  
2275          $t = escape_title($thisarticle['title']);
2276          if ($no_widow)
2277              $t = noWidow($t);
2278          return $t;
2279      }
2280  
2281  // -------------------------------------------------------------
2282  	function excerpt()
2283      {
2284          global $thisarticle, $is_article_body;
2285          assert_article();
2286  
2287          $is_article_body = 1;
2288          $out = parse($thisarticle['excerpt']);
2289          $is_article_body = 0;
2290          return $out;
2291      }
2292  
2293  // -------------------------------------------------------------
2294  
2295  	function category1($atts, $thing = NULL)
2296      {
2297          global $thisarticle, $s, $permlink_mode;
2298  
2299          assert_article();
2300  
2301          extract(lAtts(array(
2302              'class'        => '',
2303              'link'         => 0,
2304              'title'        => 0,
2305              'section'      => '',
2306              'this_section' => 0,
2307              'wraptag'      => '',
2308          ), $atts));
2309  
2310          if ($thisarticle['category1'])
2311          {
2312              $section = ($this_section) ? ( $s == 'default' ? '' : $s ) : $section;
2313              $category = $thisarticle['category1'];
2314  
2315              $label = htmlspecialchars(($title) ? fetch_category_title($category) : $category);
2316  
2317              if ($thing)
2318              {
2319                  $out = '<a'.
2320                      ($permlink_mode != 'messy' ? ' rel="tag"' : '').
2321                      ( ($class and !$wraptag) ? ' class="'.$class.'"' : '' ).
2322                      ' href="'.pagelinkurl(array('s' => $section, 'c' => $category)).'"'.
2323                      ($title ? ' title="'.$label.'"' : '').
2324                      '>'.parse($thing).'</a>';
2325              }
2326  
2327              elseif ($link)
2328              {
2329                  $out = '<a'.
2330                      ($permlink_mode != 'messy' ? ' rel="tag"' : '').
2331                      ' href="'.pagelinkurl(array('s' => $section, 'c' => $category)).'">'.$label.'</a>';
2332              }
2333  
2334              else
2335              {
2336                  $out = $label;
2337              }
2338  
2339              return doTag($out, $wraptag, $class);
2340          }
2341      }
2342  
2343  // -------------------------------------------------------------
2344  
2345  	function category2($atts, $thing = NULL)
2346      {
2347          global $thisarticle, $s, $permlink_mode;
2348  
2349          assert_article();
2350  
2351          extract(lAtts(array(
2352              'class'        => '',
2353              'link'         => 0,
2354              'title'        => 0,
2355              'section'      => '',
2356              'this_section' => 0,
2357              'wraptag'      => '',
2358          ), $atts));
2359  
2360          if ($thisarticle['category2'])
2361          {
2362              $section = ($this_section) ? ( $s == 'default' ? '' : $s ) : $section;
2363              $category = $thisarticle['category2'];
2364  
2365              $label = htmlspecialchars(($title) ? fetch_category_title($category) : $category);
2366  
2367              if ($thing)
2368              {
2369                  $out = '<a'.
2370                      ($permlink_mode != 'messy' ? ' rel="tag"' : '').
2371                      ( ($class and !$wraptag) ? ' class="'.$class.'"' : '' ).
2372                      ' href="'.pagelinkurl(array('s' => $section, 'c' => $category)).'"'.
2373                      ($title ? ' title="'.$label.'"' : '').
2374                      '>'.parse($thing).'</a>';
2375              }
2376  
2377              elseif ($link)
2378              {
2379                  $out = '<a'.
2380                      ($permlink_mode != 'messy' ? ' rel="tag"' : '').
2381                      ' href="'.pagelinkurl(array('s' => $section, 'c' => $category)).'">'.$label.'</a>';
2382              }
2383  
2384              else
2385              {
2386                  $out = $label;
2387              }
2388  
2389              return doTag($out, $wraptag, $class);
2390          }
2391      }
2392  
2393  // -------------------------------------------------------------
2394  
2395  	function category($atts, $thing = NULL)
2396      {
2397          global $s, $c, $thiscategory;
2398  
2399          extract(lAtts(array(
2400              'class'        => '',
2401              'link'         => 0,
2402              'name'         => '',
2403              'section'      => $s, // fixme in crockery
2404              'this_section' => 0,
2405              'title'        => 0,
2406              'type'         => 'article',
2407              'url'          => 0,
2408              'wraptag'      => '',
2409          ), $atts));
2410  
2411          if ($name)
2412          {
2413              $category = $name;
2414          }
2415  
2416          elseif (!empty($thiscategory['name']))
2417          {
2418              $category = $thiscategory['name'];
2419              $type = $thiscategory['type'];
2420          }
2421  
2422          else
2423          {
2424              $category = $c;
2425          }
2426  
2427          if ($category)
2428          {
2429              $section = ($this_section) ? ( $s == 'default' ? '' : $s ) : $section;
2430              $label = htmlspecialchars( ($title) ? fetch_category_title($category, $type) : $category );
2431  
2432              $href = pagelinkurl(array('s' => $section, 'c' => $category, 'context' => $type));
2433  
2434              if ($thing)
2435              {
2436                  $out = '<a href="'.$href.'"'.
2437                      ( ($class and !$wraptag) ? ' class="'.$class.'"' : '' ).
2438                      ($title ? ' title="'.$label.'"' : '').
2439                      '>'.parse($thing).'</a>';
2440              }
2441  
2442              elseif ($link)
2443              {
2444                  $out = href($label, $href, ($class and !$wraptag) ? ' class="'.$class.'"' : '');
2445              }
2446  
2447              elseif ($url)
2448              {
2449                  $out = $href;
2450              }
2451  
2452              else
2453              {
2454                  $out = $label;
2455              }
2456  
2457              return doTag($out, $wraptag, $class);
2458          }
2459      }
2460  
2461  // -------------------------------------------------------------
2462  
2463  	function section($atts, $thing = NULL)
2464      {
2465          global $thisarticle, $s, $thissection;
2466  
2467          extract(lAtts(array(
2468              'class'   => '',
2469              'link'        => 0,
2470              'name'        => '',
2471              'title'        => 0,
2472              'url'        => 0,
2473              'wraptag' => '',
2474          ), $atts));
2475  
2476          if ($name)
2477          {
2478              $sec = $name;
2479          }
2480  
2481          elseif (!empty($thissection['name']))
2482          {
2483              $sec = $thissection['name'];
2484          }
2485  
2486          elseif (!empty($thisarticle['section']))
2487          {
2488              $sec = $thisarticle['section'];
2489          }
2490  
2491          else
2492          {
2493              $sec = $s;
2494          }
2495  
2496          if ($sec)
2497          {
2498              $label = htmlspecialchars( ($title) ? fetch_section_title($sec) : $sec );
2499  
2500              $href = pagelinkurl(array('s' => $sec));
2501  
2502              if ($thing)
2503              {
2504                  $out = '<a href="'.$href.'"'.
2505                      ( ($class and !$wraptag) ? ' class="'.$class.'"' : '' ).
2506                      ($title ? ' title="'.$label.'"' : '').
2507                      '>'.parse($thing).'</a>';
2508              }
2509  
2510              elseif ($link)
2511              {
2512                  $out = href($label, $href, ($class and !$wraptag) ? ' class="'.$class.'"' : '');
2513              }
2514  
2515              elseif ($url)
2516              {
2517                  $out = $href;
2518              }
2519  
2520              else
2521              {
2522                  $out = $label;
2523              }
2524  
2525              return doTag($out, $wraptag, $class);
2526          }
2527      }
2528  
2529  // -------------------------------------------------------------
2530  	function keywords()
2531      {
2532          global $thisarticle;
2533          assert_article();
2534  
2535          return htmlspecialchars($thisarticle['keywords']);
2536      }
2537  
2538  // -------------------------------------------------------------
2539  	function if_keywords($atts, $thing = NULL)
2540      {
2541          global $thisarticle;
2542          assert_article();
2543          extract(lAtts(array(
2544              'keywords' => ''
2545          ), $atts));
2546  
2547          $condition = empty($keywords) ?
2548              $thisarticle['keywords'] :
2549              array_intersect(do_list($keywords), do_list($thisarticle['keywords']));
2550  
2551          return parse(EvalElse($thing, !empty($condition)));
2552      }
2553  
2554  // -------------------------------------------------------------
2555  
2556  	function if_article_image($atts, $thing='')
2557      {
2558          global $thisarticle;
2559          assert_article();
2560  
2561          return parse(EvalElse($thing, $thisarticle['article_image']));
2562      }
2563  
2564  // -------------------------------------------------------------
2565  
2566  	function article_image($atts)
2567      {
2568          global $thisarticle;
2569  
2570          assert_article();
2571  
2572          extract(lAtts(array(
2573              'align'     => '', // deprecated in 4.2.0
2574              'class'     => '',
2575              'escape'    => 'html',
2576              'html_id'   => '',
2577              'style'     => '',
2578              'width'     => '',
2579              'height'    => '',
2580              'thumbnail' => 0,
2581              'wraptag'   => '',
2582          ), $atts));
2583  
2584          if ($align)
2585              trigger_error(gTxt('deprecated_attribute', array('{name}' => 'align')), E_USER_NOTICE);
2586  
2587          if ($thisarticle['article_image'])
2588          {
2589              $image = $thisarticle['article_image'];
2590          }
2591  
2592          else
2593          {
2594              return;
2595          }
2596  
2597          if (intval($image))
2598          {
2599              $rs = safe_row('*', 'txp_image', 'id = '.intval($image));
2600  
2601              if ($rs)
2602              {
2603                  $width = ($width=='') ? (($thumbnail) ? $rs['thumb_w'] : $rs['w']) : $width;
2604                  $height = ($height=='') ? (($thumbnail) ? $rs['thumb_h'] : $rs['h']) : $height;
2605  
2606                  if ($thumbnail)
2607                  {
2608                      if ($rs['thumbnail'])
2609                      {
2610                          extract($rs);
2611  
2612                          if ($escape == 'html')
2613                          {
2614                              $alt = htmlspecialchars($alt);
2615                              $caption = htmlspecialchars($caption);
2616                          }
2617  
2618                          $out = '<img src="'.imagesrcurl($id, $ext, true).'" alt="'.$alt.'"'.
2619                              ($caption ? ' title="'.$caption.'"' : '').
2620                              ( ($html_id and !$wraptag) ? ' id="'.$html_id.'"' : '' ).
2621                              ( ($class and !$wraptag) ? ' class="'.$class.'"' : '' ).
2622                              ($style ? ' style="'.$style.'"' : '').
2623                              ($align ? ' align="'.$align.'"' : '').
2624                              ($width ? ' width="'.$width.'"' : '').
2625                              ($height ? ' height="'.$height.'"' : '').
2626                              ' />';
2627                      }
2628  
2629                      else
2630                      {
2631                          return '';
2632                      }
2633                  }
2634  
2635                  else
2636                  {
2637                      extract($rs);
2638  
2639                      if ($escape == 'html')
2640                      {
2641                          $alt = htmlspecialchars($alt);
2642                          $caption = htmlspecialchars($caption);
2643                      }
2644  
2645                      $out = '<img src="'.imagesrcurl($id, $ext).'" alt="'.$alt.'"'.
2646                          ($caption ? ' title="'.$caption.'"' : '').
2647                          ( ($html_id and !$wraptag) ? ' id="'.$html_id.'"' : '' ).
2648                          ( ($class and !$wraptag) ? ' class="'.$class.'"' : '' ).
2649                          ($style ? ' style="'.$style.'"' : '').
2650                          ($align ? ' align="'.$align.'"' : '').
2651                          ($width ? ' width="'.$width.'"' : '').
2652                          ($height ? ' height="'.$height.'"' : '').
2653                          ' />';
2654                  }
2655              }
2656  
2657              else
2658              {
2659                  trigger_error(gTxt('unknown_image'));
2660                  return;
2661              }
2662          }
2663  
2664          else
2665          {
2666              $out = '<img src="'.$image.'" alt=""'.
2667                  ( ($html_id and !$wraptag) ? ' id="'.$html_id.'"' : '' ).
2668                  ( ($class and !$wraptag) ? ' class="'.$class.'"' : '' ).
2669                  ($style ? ' style="'.$style.'"' : '').
2670                  ($align ? ' align="'.$align.'"' : '').
2671                  ($width ? ' width="'.$width.'"' : '').
2672                  ($height ? ' height="'.$height.'"' : '').
2673                  ' />';
2674          }
2675  
2676          return ($wraptag) ? doTag($out, $wraptag, $class, '', $html_id) : $out;
2677      }
2678  
2679  // -------------------------------------------------------------
2680  	function search_result_title($atts)
2681      {
2682          return permlink($atts, '<txp:title />');
2683      }
2684  
2685  // -------------------------------------------------------------
2686  	function search_result_excerpt($atts)
2687      {
2688          global $thisarticle, $pretext;
2689  
2690          assert_article();
2691  
2692          extract(lAtts(array(
2693              'break'   => ' &#8230;',
2694              'hilight' => 'strong',
2695              'limit'   => 5,
2696          ), $atts));
2697  
2698          $m = $pretext['m'];
2699          $q = $pretext['q'];
2700  
2701          $quoted = ($q[0] === '"') && ($q[strlen($q)-1] === '"');
2702          $q = $quoted ? trim(trim($q, '"')) : $q;
2703  
2704          $result = preg_replace('/\s+/', ' ', strip_tags(str_replace('><', '> <', $thisarticle['body'])));
2705  
2706          if ($quoted || empty($m) || $m === 'exact')
2707          {
2708              $regex_search = '/(?:\G|\s).{0,50}'.preg_quote($q).'.{0,50}(?:\s|$)/iu';
2709              $regex_hilite = '/('.preg_quote($q).')/i';
2710          }
2711          else
2712          {
2713              $regex_search = '/(?:\G|\s).{0,50}('.preg_replace('/\s+/', '|', preg_quote($q)).').{0,50}(?:\s|$)/iu';
2714              $regex_hilite = '/('.preg_replace('/\s+/', '|', preg_quote($q)).')/i';
2715          }
2716  
2717          preg_match_all($regex_search, $result, $concat);
2718          $concat = $concat[0];
2719  
2720          for ($i = 0, $r = array(); $i < min($limit, count($concat)); $i++)
2721          {
2722              $r[] = trim($concat[$i]);
2723          }
2724  
2725          $concat = join($break.n, $r);
2726          $concat = preg_replace('/^[^>]+>/U', '', $concat);
2727  #TODO
2728  
2729          $concat = preg_replace($regex_hilite, "<$hilight>$1</$hilight>", $concat);
2730  
2731          return ($concat) ? trim($break.$concat.$break) : '';
2732      }
2733  
2734  // -------------------------------------------------------------
2735  	function search_result_url($atts)
2736      {
2737          global $thisarticle;
2738          assert_article();
2739  
2740          $l = permlinkurl($thisarticle);
2741          return permlink($atts, $l);
2742      }
2743  
2744  // -------------------------------------------------------------
2745  	function search_result_date($atts)
2746      {
2747          assert_article();
2748          return posted($atts);
2749      }
2750  
2751  // -------------------------------------------------------------
2752  	function search_result_count($atts)
2753      {
2754          global $thispage;
2755          $t = @$thispage['grand_total'];
2756          extract(lAtts(array(
2757              'text'     => ($t == 1 ? gTxt('article_found') : gTxt('articles_found')),
2758          ),$atts));
2759  
2760          return $t . ($text ? ' ' . $text : '');
2761      }
2762  
2763  // -------------------------------------------------------------
2764  	function image_index($atts)
2765      {
2766          global $s,$c,$p,$path_to_site;
2767          extract(lAtts(array(
2768              'label'    => '',
2769              'break'    => br,
2770              'wraptag'  => '',
2771              'class'    => __FUNCTION__,
2772              'labeltag' => '',
2773              'c'        => $c, // Keep the option to override categories due to backward compatibility
2774              'category' => $c,
2775              'limit'    => 0,
2776              'offset'   => 0,
2777              'sort'     => 'name ASC',
2778          ),$atts));
2779  
2780          if (isset($atts['c'])) {
2781              trigger_error(gTxt('deprecated_attribute', array('{name}' => 'c')), E_USER_NOTICE);
2782          }
2783  
2784          if (isset($atts['category'])) {
2785              $c = $category; // Override the global
2786          }
2787  
2788          $qparts = array(
2789              "category = '".doSlash($c)."' and thumbnail = 1",
2790              'order by '.doSlash($sort),
2791              ($limit) ? 'limit '.intval($offset).', '.intval($limit) : ''
2792          );
2793  
2794          $rs = safe_rows_start('*', 'txp_image',  join(' ', $qparts));
2795  
2796          if ($rs) {
2797              $out = array();
2798              while ($a = nextRow($rs)) {
2799                  extract($a);
2800                  $dims = ($thumb_h ? " height=\"$thumb_h\"" : '') . ($thumb_w ? " width=\"$thumb_w\"" : '');
2801                  $url = pagelinkurl(array('c'=>$c, 'context'=>'image', 's'=>$s, 'p'=>$id));
2802                  $out[] = '<a href="'.$url.'">'.
2803                      '<img src="'.imagesrcurl($id, $ext, true).'"'.$dims.' alt="'.$alt.'" />'.'</a>';
2804              }
2805              if (count($out)) {
2806                  return doLabel($label, $labeltag).doWrap($out, $wraptag, $break, $class);
2807              }
2808          }
2809          return '';
2810      }
2811  
2812  // -------------------------------------------------------------
2813  	function image_display($atts)
2814      {
2815          if (is_array($atts)) extract($atts);
2816          global $s,$c,$p;
2817          if($p) {
2818              $rs = safe_row("*", "txp_image", 'id='.intval($p).' limit 1');
2819              if ($rs) {
2820                  extract($rs);
2821                  return '<img src="'.imagesrcurl($id, $ext).
2822                      '" style="height:'.$h.'px;width:'.$w.'px" alt="'.$alt.'" />';
2823              }
2824          }
2825      }
2826  
2827  // -------------------------------------------------------------
2828  	function images($atts, $thing = NULL)
2829      {
2830          global $s, $c, $context, $p, $path_to_site, $thisimage, $thisarticle, $thispage, $pretext;
2831  
2832          extract(lAtts(array(
2833              'name'        => '',
2834              'id'          => '',
2835              'category'    => '',
2836              'author'      => '',
2837              'realname'    => '',
2838              'extension'   => '',
2839              'thumbnail'   => '',
2840              'auto_detect' => 'article, category, author',
2841              'label'       => '',
2842              'break'       => br,
2843              'wraptag'     => '',
2844              'class'       => __FUNCTION__,
2845              'html_id'     => '',
2846              'labeltag'    => '',
2847              'form'        => '',
2848              'pageby'      => '',
2849              'limit'       => 0,
2850              'offset'      => 0,
2851              'sort'        => 'name ASC',
2852          ),$atts));
2853  
2854          $where = array();
2855          $has_content = $thing || $form;
2856          $filters = isset($atts['id']) || isset($atts['name']) || isset($atts['category']) || isset($atts['author']) || isset($atts['realname']) || isset($atts['extension']) || $thumbnail === '1' || $thumbnail === '0';
2857          $context_list = (empty($auto_detect) || $filters) ? array() : do_list($auto_detect);
2858          $pageby = ($pageby=='limit') ? $limit : $pageby;
2859  
2860          if ($name) $where[] = "name IN ('".join("','", doSlash(do_list($name)))."')";
2861  
2862          if ($category) $where[] = "category IN ('".join("','", doSlash(do_list($category)))."')";
2863  
2864          if ($id) $where[] = "id IN ('".join("','", doSlash(do_list($id)))."')";
2865  
2866          if ($author) $where[] = "author IN ('".join("','", doSlash(do_list($author)))."')";
2867  
2868          if ($realname) {
2869              $authorlist = safe_column('name', 'txp_users', "RealName IN ('". join("','", doArray(doSlash(do_list($realname)), 'urldecode')) ."')" );
2870              $where[] = "author IN ('".join("','", doSlash($authorlist))."')";
2871          }
2872  
2873          if ($extension) $where[] = "ext IN ('".join("','", doSlash(do_list($extension)))."')";
2874          if ($thumbnail === '0' || $thumbnail === '1') $where[] = "thumbnail = $thumbnail";
2875  
2876          // If no images are selected, try...
2877          if (!$where && !$filters)
2878          {
2879              foreach ($context_list as $ctxt)
2880              {
2881                  switch($ctxt)
2882                  {
2883                      case 'article':
2884                          // ...the article image field
2885                          if ($thisarticle && !empty($thisarticle['article_image']))
2886                          {
2887                              $items = do_list($thisarticle['article_image']);
2888                              $i = 0; // TODO: Indexed array access required for PHP 4 compat. Replace with &$item in TXP5. @see [r3435].
2889                              foreach ($items as $item)
2890                              {
2891                                  if (is_numeric($item))
2892                                  {
2893                                      $items[$i] = intval($item);
2894                                  }
2895                                  else
2896                                  {
2897                                      return article_image(compact('class', 'html_id', 'wraptag'));
2898                                  }
2899                                  $i++;
2900                              }
2901                              $where[] = "id IN ('".join("','", doSlash($items))."')";
2902                          }
2903                          break;
2904                      case 'category':
2905                          // ... the global category in the URL
2906                          if ($context == 'image' && !empty($c))
2907                          {
2908                              $where[] = "category = '".doSlash($c)."'";
2909                          }
2910                          break;
2911                      case 'author':
2912                          // ... the global author in the URL
2913                          if ($context == 'image' && !empty($pretext['author']))
2914                          {
2915                              $where[] = "author = '".doSlash($pretext['author'])."'";
2916                          }
2917                          break;
2918                  }
2919                  // Only one context can be processed
2920                  if ($where) break;
2921              }
2922          }
2923  
2924          if (!$where && $filters)
2925          {
2926              return ''; // If nothing matches, output nothing
2927          }
2928  
2929          if (!$where)
2930          {
2931              $where[] = "1=1"; // If nothing matches, start with all images
2932          }
2933  
2934          $where = join(' AND ', $where);
2935  
2936          // Set up paging if required
2937          if ($limit && $pageby) {
2938              $grand_total = safe_count('txp_image', $where);
2939              $total = $grand_total - $offset;
2940              $numPages = ($pageby > 0) ? ceil($total/$pageby) : 1;
2941              $pg = (!$pretext['pg']) ? 1 : $pretext['pg'];
2942              $pgoffset = $offset + (($pg - 1) * $pageby);
2943              // send paging info to txp:newer and txp:older
2944              $pageout['pg']          = $pg;
2945              $pageout['numPages']    = $numPages;
2946              $pageout['s']           = $s;
2947              $pageout['c']           = $c;
2948              $pageout['context']     = 'image';
2949              $pageout['grand_total'] = $grand_total;
2950              $pageout['total']       = $total;
2951  
2952              if (empty($thispage))
2953                  $thispage = $pageout;
2954          } else {
2955              $pgoffset = $offset;
2956          }
2957  
2958          $qparts = array(
2959              $where,
2960              'order by '.doSlash($sort),
2961              ($limit) ? 'limit '.intval($pgoffset).', '.intval($limit) : ''
2962          );
2963  
2964          $rs = safe_rows_start('*', 'txp_image',  join(' ', $qparts));
2965  
2966          if ($rs)
2967          {
2968              $out = array();
2969  
2970              if (isset($thisimage)) $old_image = $thisimage;
2971  
2972              while ($a = nextRow($rs))
2973              {
2974                  $thisimage = image_format_info($a);
2975                  if (!$has_content)
2976                  {
2977                      $url = pagelinkurl(array('c'=>$thisimage['category'], 'context'=>'image', 's'=>$s, 'p'=>$thisimage['id']));
2978                      $src = image_url(array('thumbnail' => '1'));
2979                      $thing = '<a href="'.$url.'">'.
2980                          '<img src="'. $src .'" alt="'.$thisimage['alt'].'" />'.'</a>'.n;
2981                  }
2982                  $out[] = ($thing) ? parse($thing) : parse_form($form);
2983              }
2984  
2985              $thisimage = (isset($old_image) ? $old_image : NULL);
2986  
2987              if ($out)
2988              {
2989                  return doLabel($label, $labeltag).doWrap($out, $wraptag, $break, $class, '', '', '', $html_id);
2990              }
2991          }
2992          return '';
2993      }
2994  
2995  // -------------------------------------------------------------
2996  	function image_info($atts) {
2997          global $thisimage;
2998  
2999          extract(lAtts(array(
3000              'name'  => '',
3001              'id'    => '',
3002              'type'       => 'caption',
3003              'escape'     => 'html',
3004              'wraptag'    => '',
3005              'class'      => '',
3006              'break'      => '',
3007              'breakclass' => '',
3008          ), $atts));
3009  
3010          $validItems = array('id','name','category','category_title','alt','caption','ext','author','w','h','thumb_w','thumb_h','date');
3011          $type = do_list($type);
3012  
3013          $from_form = false;
3014  
3015          if ($id)
3016          {
3017              $thisimage = imageFetchInfo('id = '.intval($id));
3018          }
3019  
3020          elseif ($name)
3021          {
3022              $thisimage = imageFetchInfo("name = '".doSlash($name)."'");
3023          }
3024  
3025          else
3026          {
3027              assert_image();
3028              $from_form = true;
3029          }
3030  
3031          $out = array();
3032          if ($thisimage)
3033          {
3034              $thisimage['category_title'] = fetch_category_title($thisimage['category'], 'image');
3035  
3036              foreach ($type as $item)
3037              {
3038                  if (in_array($item, $validItems))
3039                  {
3040                      if (isset($thisimage[$item]))
3041                      {
3042                          $out[] = ($escape == 'html') ?
3043                              htmlspecialchars($thisimage[$item]) : $thisimage[$item];
3044                      }
3045                  }
3046              }
3047  
3048              if (!$from_form)
3049              {
3050                  $thisimage = '';
3051              }
3052          }
3053          return doWrap($out, $wraptag, $break, $class, $breakclass);
3054      }
3055  
3056  // -------------------------------------------------------------
3057  	function image_url($atts, $thing = NULL)
3058      {
3059          global $thisimage;
3060  
3061          extract(lAtts(array(
3062              'name'      => '',
3063              'id'        => '',
3064              'thumbnail' => 0,
3065              'link'      => 'auto',
3066          ), $atts));
3067  
3068          $from_form = false;
3069  
3070          if ($id)
3071          {
3072              $thisimage = imageFetchInfo('id = '.intval($id));
3073          }
3074  
3075          elseif ($name)
3076          {
3077              $thisimage = imageFetchInfo("name = '".doSlash($name)."'");
3078          }
3079  
3080          else
3081          {
3082              assert_image();
3083              $from_form = true;
3084          }
3085  
3086          if ($thisimage)
3087          {
3088              $url = imagesrcurl($thisimage['id'], $thisimage['ext'], $thumbnail);
3089              $link = ($link == 'auto') ? (($thing) ? 1 : 0) : $link;
3090              $out = ($thing) ? parse($thing) : $url;
3091              $out = ($link) ? href($out, $url) : $out;
3092  
3093              if (!$from_form)
3094              {
3095                  $thisimage = '';
3096              }
3097  
3098              return $out;
3099          }
3100          return '';
3101      }
3102  
3103  //--------------------------------------------------------------------------
3104  
3105  	function image_author($atts)
3106      {
3107          global $thisimage, $s;
3108          assert_image();
3109  
3110          extract(lAtts(array(
3111              'class'        => '',
3112              'link'         => 0,
3113              'title'        => 1,
3114              'section'      => '',
3115              'this_section' => '',
3116              'wraptag'      => '',
3117          ), $atts));
3118  
3119          if ($thisimage['author'])
3120          {
3121              $author_name = get_author_name($thisimage['author']);
3122              $display_name = htmlspecialchars( ($title) ? $author_name : $thisimage['author'] );
3123  
3124              $section = ($this_section) ? ( $s == 'default' ? '' : $s ) : $section;
3125  
3126              $author = ($link) ?
3127                  href($display_name, pagelinkurl(array('s' => $section, 'author' => $author_name, 'context' => 'image'))) :
3128                  $display_name;
3129  
3130              return ($wraptag) ? doTag($author, $wraptag, $class) : $author;
3131          }
3132      }
3133  
3134  //--------------------------------------------------------------------------
3135  	function image_date($atts)
3136      {
3137          global $thisimage;
3138  
3139          extract(lAtts(array(
3140              'name'  => '',
3141              'id'    => '',
3142              'format' => '',
3143          ), $atts));
3144  
3145          $from_form = false;
3146  
3147          if ($id)
3148          {
3149              $thisimage = imageFetchInfo('id = '.intval($id));
3150          }
3151  
3152          elseif ($name)
3153          {
3154              $thisimage = imageFetchInfo("name = '".doSlash($name)."'");
3155          }
3156  
3157          else
3158          {
3159              assert_image();
3160              $from_form = true;
3161          }
3162  
3163          if (isset($thisimage['date'])) {
3164              // Not a typo: use fileDownloadFormatTime() since it is fit for purpose
3165              $out = fileDownloadFormatTime(array(
3166                  'ftime'  => $thisimage['date'],
3167                  'format' => $format
3168              ));
3169  
3170              if (!$from_form)
3171              {
3172                  $thisimage = '';
3173              }
3174  
3175              return $out;
3176          }
3177      }
3178  
3179  //--------------------------------------------------------------------------
3180  	function if_thumbnail($atts, $thing)
3181      {
3182          global $thisimage;
3183          assert_image();
3184  
3185          return parse(EvalElse($thing, ($thisimage['thumbnail'] == 1)));
3186      }
3187  
3188  // -------------------------------------------------------------
3189  	function if_comments($atts, $thing)
3190      {
3191          global $thisarticle;
3192          assert_article();
3193  
3194          return parse(EvalElse($thing, ($thisarticle['comments_count'] > 0)));
3195      }
3196  
3197  // -------------------------------------------------------------
3198  	function if_comments_allowed($atts, $thing)
3199      {
3200          global $thisarticle;
3201          assert_article();
3202  
3203          return parse(EvalElse($thing, checkCommentsAllowed($thisarticle['thisid'])));
3204      }
3205  
3206  // -------------------------------------------------------------
3207  	function if_comments_disallowed($atts, $thing)
3208      {
3209          global $thisarticle;
3210          assert_article();
3211  
3212          return parse(EvalElse($thing, !checkCommentsAllowed($thisarticle['thisid'])));
3213      }
3214  
3215  // -------------------------------------------------------------
3216  	function if_individual_article($atts, $thing)
3217      {
3218          global $is_article_list;
3219          return parse(EvalElse($thing, ($is_article_list == false)));
3220      }
3221  
3222  // -------------------------------------------------------------
3223  	function if_article_list($atts, $thing)
3224      {
3225          global $is_article_list;
3226          return parse(EvalElse($thing, ($is_article_list == true)));
3227      }
3228  
3229  // -------------------------------------------------------------
3230  	function meta_keywords()
3231      {
3232          global $id_keywords;
3233          return ($id_keywords)
3234          ?    '<meta name="keywords" content="'.htmlspecialchars($id_keywords).'" />'
3235          :    '';
3236      }
3237  
3238  // -------------------------------------------------------------
3239  	function meta_author($atts)
3240      {
3241          global $id_author;
3242  
3243          extract(lAtts(array(
3244              'title'  => 0,
3245          ), $atts));
3246  
3247          if ($id_author)
3248          {
3249              $display_name = ($title) ? get_author_name($id_author) : $id_author;
3250              return '<meta name="author" content="'.htmlspecialchars($display_name).'" />';
3251          }
3252          return '';
3253      }
3254  
3255  // -------------------------------------------------------------
3256  
3257  	function doWrap($list, $wraptag, $break, $class = '', $breakclass = '', $atts = '', $breakatts = '', $id = '')
3258      {
3259          if (!$list)
3260          {
3261              return '';
3262          }
3263  
3264          if ($id)
3265          {
3266              $atts .= ' id="'.$id.'"';
3267          }
3268  
3269          if ($class)
3270          {
3271              $atts .= ' class="'.$class.'"';
3272          }
3273  
3274          if ($breakclass)
3275          {
3276              $breakatts.= ' class="'.$breakclass.'"';
3277          }
3278  
3279          // non-enclosing breaks
3280          if (!preg_match('/^\w+$/', $break) or $break == 'br' or $break == 'hr')
3281          {
3282              if ($break == 'br' or $break == 'hr')
3283              {
3284                  $break = "<$break $breakatts/>".n;
3285              }
3286  
3287              return ($wraptag) ?    tag(join($break, $list), $wraptag, $atts) :    join($break, $list);
3288          }
3289  
3290          return ($wraptag) ?
3291              tag(n.t.tag(join("</$break>".n.t."<{$break}{$breakatts}>", $list), $break, $breakatts).n, $wraptag, $atts) :
3292              tag(n.join("</$break>".n."<{$break}{$breakatts}>".n, $list).n, $break, $breakatts);
3293      }
3294  
3295  // -------------------------------------------------------------
3296  
3297  	function doTag($content, $tag, $class = '', $atts = '', $id = '')
3298      {
3299          if ($id)
3300          {
3301              $atts .= ' id="'.$id.'"';
3302          }
3303  
3304          if ($class)
3305          {
3306              $atts .= ' class="'.$class.'"';
3307          }
3308  
3309          if (!$tag)
3310          {
3311              return $content;
3312          }
3313  
3314          return ($content) ? tag($content, $tag, $atts) : "<$tag $atts />";
3315      }
3316  
3317  // -------------------------------------------------------------
3318  	function doLabel($label='', $labeltag='')
3319      {
3320          if ($label) {
3321              return (empty($labeltag)? $label.'<br />' : tag($label, $labeltag));
3322          }
3323          return '';
3324      }
3325  
3326  // -------------------------------------------------------------
3327  
3328  	function permlink($atts, $thing = NULL)
3329      {
3330          global $thisarticle;
3331  
3332          extract(lAtts(array(
3333              'class' => '',
3334              'id'        => '',
3335              'style' => '',
3336              'title' => '',
3337          ), $atts));
3338  
3339          if (!$id)
3340          {
3341              assert_article();
3342          }
3343  
3344          $url = ($id) ? permlinkurl_id($id) : permlinkurl($thisarticle);
3345  
3346          if ($url)
3347          {
3348              if ($thing === NULL)
3349              {
3350                  return $url;
3351              }
3352  
3353              return tag(parse($thing), 'a', ' rel="bookmark" href="'.$url.'"'.
3354                  ($title ? ' title="'.$title.'"' : '').
3355                  ($style ? ' style="'.$style.'"' : '').
3356                  ($class ? ' class="'.$class.'"' : '')
3357              );
3358          }
3359      }
3360  
3361  // -------------------------------------------------------------
3362  
3363  	function permlinkurl_id($id)
3364      {
3365          global $permlinks;
3366          if (isset($permlinks[$id])) return $permlinks[$id];
3367  
3368          $id = (int) $id;
3369  
3370          $rs = safe_row(
3371              "ID as thisid, Section as section, Title as title, url_title, unix_timestamp(Posted) as posted",
3372              'textpattern',
3373              "ID = $id"
3374          );
3375  
3376          return permlinkurl($rs);
3377      }
3378  
3379  // -------------------------------------------------------------
3380  	function permlinkurl($article_array)
3381      {
3382          global $permlink_mode, $prefs, $permlinks;
3383  
3384          if (isset($prefs['custom_url_func'])
3385              and is_callable($prefs['custom_url_func'])
3386              and ($url = call_user_func($prefs['custom_url_func'], $article_array, PERMLINKURL)) !== FALSE)
3387          {
3388              return $url;
3389          }
3390  
3391          if (empty($article_array)) return;
3392  
3393          extract($article_array);
3394  
3395          if (empty($thisid)) $thisid = $ID;
3396  
3397          if (isset($permlinks[$thisid])) return $permlinks[$thisid];
3398  
3399          if (!isset($title)) $title = $Title;
3400          if (empty($url_title)) $url_title = stripSpace($title);
3401          if (empty($section)) $section = $Section; // lame, huh?
3402          if (!isset($posted)) $posted = $Posted;
3403  
3404          $section = urlencode($section);
3405          $url_title = urlencode($url_title);
3406  
3407          switch($permlink_mode) {
3408              case 'section_id_title':
3409                  if ($prefs['attach_titles_to_permalinks'])
3410                  {
3411                      $out = hu."$section/$thisid/$url_title";
3412                  }else{
3413                      $out = hu."$section/$thisid/";
3414                  }
3415                  break;
3416              case 'year_month_day_title':
3417                  list($y,$m,$d) = explode("-",date("Y-m-d",$posted));
3418                  $out =  hu."$y/$m/$d/$url_title";
3419                  break;
3420              case 'id_title':
3421                  if ($prefs['attach_titles_to_permalinks'])
3422                  {
3423                      $out = hu."$thisid/$url_title";
3424                  }else{
3425                      $out = hu."$thisid/";
3426                  }
3427                  break;
3428              case 'section_title':
3429                  $out = hu."$section/$url_title";
3430                  break;
3431              case 'title_only':
3432                  $out = hu."$url_title";
3433                  break;
3434              case 'messy':
3435                  $out = hu."index.php?id=$thisid";
3436                  break;
3437          }
3438          return $permlinks[$thisid] = $out;
3439      }
3440  
3441  // -------------------------------------------------------------
3442  	function lang()
3443      {
3444          return LANG;
3445      }
3446  
3447  // -------------------------------------------------------------
3448      # DEPRECATED - provided only for backwards compatibility
3449  	function formatPermLink($ID,$Section)
3450      {
3451          trigger_error(gTxt('deprecated_tag'), E_USER_NOTICE);
3452  
3453          return permlinkurl_id($ID);
3454      }
3455  
3456  // -------------------------------------------------------------
3457      # DEPRECATED - provided only for backwards compatibility
3458  	function formatCommentsInvite($AnnotateInvite,$Section,$ID)
3459      {
3460          trigger_error(gTxt('deprecated_tag'), E_USER_NOTICE);
3461  
3462          global $comments_mode;
3463  
3464          $dc = safe_count('txp_discuss','parentid='.intval($ID).' and visible='.VISIBLE);
3465  
3466          $ccount = ($dc) ?  '['.$dc.']' : '';
3467          if (!$comments_mode) {
3468              return '<a href="'.permlinkurl_id($ID).'/#'.gTxt('comment').
3469                  '">'.$AnnotateInvite.'</a>'. $ccount;
3470          } else {
3471              return "<a href=\"".hu."?parentid=$ID\" onclick=\"window.open(this.href, 'popupwindow', 'width=500,height=500,scrollbars,resizable,status'); return false;\">".$AnnotateInvite.'</a> '.$ccount;
3472          }
3473  
3474      }
3475  // -------------------------------------------------------------
3476      # DEPRECATED - provided only for backwards compatibility
3477  	function doPermlink($text, $plink, $Title, $url_title)
3478      {
3479          trigger_error(gTxt('deprecated_tag'), E_USER_NOTICE);
3480  
3481          global $url_mode;
3482          $Title = ($url_title) ? $url_title : stripSpace($Title);
3483          $Title = ($url_mode) ? $Title : '';
3484          return preg_replace("/<(txp:permlink)>(.*)<\/\\1>/sU",
3485              "<a href=\"".$plink.$Title."\" title=\"".gTxt('permanent_link')."\">$2</a>",$text);
3486      }
3487  
3488  // -------------------------------------------------------------
3489      # DEPRECATED - provided only for backwards compatibility
3490  	function doArticleHref($ID,$Title,$url_title,$Section)
3491      {
3492          trigger_error(gTxt('deprecated_tag'), E_USER_NOTICE);
3493  
3494          $conTitle = ($url_title) ? $url_title : stripSpace($Title);
3495          return ($GLOBALS['url_mode'])
3496          ?    tag($Title,'a',' href="'.hu.$Section.'/'.$ID.'/'.$conTitle.'"')
3497          :    tag($Title,'a',' href="'.hu.'index.php?id='.$ID.'"');
3498      }
3499  
3500  // -------------------------------------------------------------
3501  
3502  	function breadcrumb($atts)
3503      {
3504          global $pretext,$sitename;
3505  
3506          extract(lAtts(array(
3507              'wraptag' => 'p',
3508              'sep' => '&#160;&#187;&#160;', // deprecated in 4.3.0
3509              'separator' => '&#160;&#187;&#160;',
3510              'link' => 1,
3511              'label' => $sitename,
3512              'title' => '',
3513              'class' => '',
3514              'linkclass' => 'noline',
3515          ),$atts));
3516  
3517          if (isset($atts['sep'])) {
3518              $separator = $sep;
3519              trigger_error(gTxt('deprecated_attribute', array('{name}' => 'sep')), E_USER_NOTICE);
3520          }
3521  
3522          // bc, get rid of in crockery
3523          if ($link == 'y') {
3524              $linked = true;
3525          } elseif ($link == 'n') {
3526              $linked = false;
3527          } else {
3528              $linked = $link;
3529          }
3530  
3531          if ($linked) $label = doTag($label,'a',$linkclass,' href="'.hu.'"');
3532  
3533          $content = array();
3534          extract($pretext);
3535          if(!empty($s) && $s!= 'default')
3536          {
3537              $section_title = ($title) ? fetch_section_title($s) : $s;
3538              $section_title_html = escape_title($section_title);
3539              $content[] = ($linked)? (
3540                      doTag($section_title_html,'a',$linkclass,' href="'.pagelinkurl(array('s'=>$s)).'"')
3541                  ):$section_title_html;
3542          }
3543  
3544          $category = empty($c)? '': $c;
3545  
3546          foreach (getTreePath($category, 'article') as $cat) {
3547              if ($cat['name'] != 'root') {
3548                  $category_title_html = $title ? escape_title($cat['title']) : $cat['name'];
3549                  $content[] = ($linked)?
3550                      doTag($category_title_html,'a',$linkclass,' href="'.pagelinkurl(array('c'=>$cat['name'])).'"')
3551                          :$category_title_html;
3552              }
3553          }
3554  
3555          // add the label at the end, to prevent breadcrumb for home page
3556          if ($content)
3557          {
3558              $content = array_merge(array($label), $content);
3559  
3560              return doTag(join($separator, $content), $wraptag, $class);
3561          }
3562      }
3563  
3564  
3565  //------------------------------------------------------------------------
3566  
3567  	function if_excerpt($atts, $thing)
3568      {
3569          global $thisarticle;
3570          assert_article();
3571          # eval condition here. example for article excerpt
3572          $excerpt = trim($thisarticle['excerpt']);
3573          $condition = (!empty($excerpt))? true : false;
3574          return parse(EvalElse($thing, $condition));
3575      }
3576  
3577  //--------------------------------------------------------------------------
3578  // Searches use default page. This tag allows you to use different templates if searching
3579  //--------------------------------------------------------------------------
3580  
3581  	function if_search($atts, $thing)
3582      {
3583          global $pretext;
3584          return parse(EvalElse($thing, !empty($pretext['q'])));
3585      }
3586  
3587  //--------------------------------------------------------------------------
3588  
3589  	function if_search_results($atts, $thing)
3590      {
3591          global $thispage, $pretext;
3592  
3593          if(empty($pretext['q'])) return '';
3594  
3595          extract(lAtts(array(
3596              'min' => 1,
3597              'max' => 0,
3598          ),$atts));
3599  
3600          $results = (int)$thispage['grand_total'];
3601          return parse(EvalElse($thing, $results >= $min && (!$max || $results <= $max)));
3602      }
3603  
3604  //--------------------------------------------------------------------------
3605  	function if_category($atts, $thing)
3606      {
3607          global $c, $context;
3608  
3609          extract(lAtts(array(
3610              'type' => 'article',
3611              'name' => FALSE,
3612          ),$atts));
3613  
3614          $theType = ($type) ? $type == $context : true;
3615          if ($name === FALSE)
3616          {
3617              return parse(EvalElse($thing, ($theType && !empty($c))));
3618          }
3619          else
3620          {
3621              return parse(EvalElse($thing, ($theType && in_list($c, $name))));
3622          }
3623      }
3624  
3625  //--------------------------------------------------------------------------
3626  
3627  	function if_article_category($atts, $thing)
3628      {
3629          global $thisarticle;
3630  
3631          assert_article();
3632  
3633          extract(lAtts(array(
3634              'name'   => '',
3635              'number' => '',
3636          ), $atts));
3637  
3638          $cats = array();
3639  
3640          if ($number) {
3641              if (!empty($thisarticle['category'.$number])) {
3642                  $cats = array($thisarticle['category'.$number]);
3643              }
3644          } else {
3645              if (!empty($thisarticle['category1'])) {
3646                  $cats[] = $thisarticle['category1'];
3647              }
3648  
3649              if (!empty($thisarticle['category2'])) {
3650                  $cats[] = $thisarticle['category2'];
3651              }
3652  
3653              $cats = array_unique($cats);
3654          }
3655  
3656          if ($name) {
3657              return parse(EvalElse($thing, array_intersect(do_list($name), $cats)));
3658          } else {
3659              return parse(EvalElse($thing, ($cats)));
3660          }
3661      }
3662  
3663  // -------------------------------------------------------------
3664  	function if_first_category($atts, $thing)
3665      {
3666          global $thiscategory;
3667          assert_category();
3668          return parse(EvalElse($thing, !empty($thiscategory['is_first'])));
3669      }
3670  
3671  // -------------------------------------------------------------
3672  	function if_last_category($atts, $thing)
3673      {
3674          global $thiscategory;
3675          assert_category();
3676          return parse(EvalElse($thing, !empty($thiscategory['is_last'])));
3677      }
3678  
3679  //--------------------------------------------------------------------------
3680  	function if_section($atts, $thing)
3681      {
3682          global $pretext;
3683          extract($pretext);
3684  
3685          extract(lAtts(array(
3686              'name' => FALSE,
3687          ),$atts));
3688  
3689          $section = ($s == 'default' ? '' : $s);
3690  
3691          if ($section)
3692              return parse(EvalElse($thing, $name === FALSE or in_list($section, $name)));
3693          else
3694              return parse(EvalElse($thing, $name !== FALSE and (in_list('', $name) or in_list('default', $name))));
3695  
3696      }
3697  
3698  //--------------------------------------------------------------------------
3699  	function if_article_section($atts, $thing)
3700      {
3701          global $thisarticle;
3702          assert_article();
3703  
3704          extract(lAtts(array(
3705              'name' => '',
3706          ),$atts));
3707  
3708          $section = $thisarticle['section'];
3709  
3710          return parse(EvalElse($thing, in_list($section, $name)));
3711      }
3712  
3713  // -------------------------------------------------------------
3714  	function if_first_section($atts, $thing)
3715      {
3716          global $thissection;
3717          assert_section();
3718          return parse(EvalElse($thing, !empty($thissection['is_first'])));
3719      }
3720  
3721  // -------------------------------------------------------------
3722  	function if_last_section($atts, $thing)
3723      {
3724          global $thissection;
3725          assert_section();
3726          return parse(EvalElse($thing, !empty($thissection['is_last'])));
3727      }
3728  
3729  //--------------------------------------------------------------------------
3730  	function php($atts, $thing)
3731      {
3732          global $is_article_body, $thisarticle, $prefs;
3733  
3734          ob_start();
3735          if (empty($is_article_body)) {
3736              if (!empty($prefs['allow_page_php_scripting']))
3737                  eval($thing);
3738              else
3739                  trigger_error(gTxt('php_code_disabled_page'));
3740          }
3741          else {
3742              if (!empty($prefs['allow_article_php_scripting'])) {
3743                  if (has_privs('article.php', $thisarticle['authorid']))
3744                      eval($thing);
3745                  else
3746                      trigger_error(gTxt('php_code_forbidden_user'));
3747              }
3748              else
3749                  trigger_error(gTxt('php_code_disabled_article'));
3750          }
3751          return ob_get_clean();
3752      }
3753  
3754  //--------------------------------------------------------------------------
3755  	function custom_field($atts)
3756      {
3757          global $thisarticle, $prefs;
3758          assert_article();
3759  
3760          extract(lAtts(array(
3761              'name' => @$prefs['custom_1_set'],
3762              'escape' => 'html',
3763              'default' => '',
3764          ),$atts));
3765  
3766          $name = strtolower($name);
3767          if (!empty($thisarticle[$name]))
3768              $out = $thisarticle[$name];
3769          else
3770              $out = $default;
3771  
3772          return ($escape == 'html' ? htmlspecialchars($out) : $out);
3773      }
3774  
3775  //--------------------------------------------------------------------------
3776  	function if_custom_field($atts, $thing)
3777      {
3778          global $thisarticle, $prefs;
3779          assert_article();
3780  
3781          extract(lAtts(array(
3782              'name' => @$prefs['custom_1_set'],
3783              'value' => NULL,
3784              'val' => NULL, // deprecated in 4.3.0
3785              'match' => 'exact',
3786              'separator' => '',
3787          ),$atts));
3788  
3789          if (isset($atts['val'])) {
3790              $value = $val;
3791              trigger_error(gTxt('deprecated_attribute', array('{name}' => 'val')), E_USER_NOTICE);
3792          }
3793  
3794          $name = strtolower($name);
3795          if ($value !== NULL)
3796              switch ($match) {
3797                  case '':
3798                  case 'exact':
3799                      $cond = (@$thisarticle[$name] == $value);
3800                      break;
3801                  case 'any':
3802                      $values = do_list($value);
3803                      $cond = false;
3804                      $cf_contents = ($separator) ? do_list(@$thisarticle[$name], $separator) : @$thisarticle[$name];
3805                      foreach($values as $term) {
3806                          if ($term == '') continue;
3807                          $cond = is_array($cf_contents) ? in_array($term, $cf_contents) : ((strpos($cf_contents, $term) !== false) ? true : false);
3808  
3809                          // Short circuit if a match is found
3810                          if ($cond) break;
3811                      }
3812                      break;
3813                  case 'all':
3814                      $values = do_list($value);
3815                      $num_values = count($values);
3816                      $term_count = 0;
3817                      $cf_contents = ($separator) ? do_list(@$thisarticle[$name], $separator) : @$thisarticle[$name];
3818                      foreach ($values as $term) {
3819                          if ($term == '') continue;
3820                          $term_count += is_array($cf_contents) ? in_array($term, $cf_contents) : ((strpos($cf_contents, $term) !== false) ? true : false);
3821                      }
3822                      $cond = ($term_count == $num_values) ? true : false;
3823                      break;
3824                  case 'pattern':
3825                      // Cannot guarantee that a fixed delimiter won't break preg_match (and preg_quote doesn't help) so
3826                      // dynamically assign the delimiter based on the first entry in $dlmPool that is NOT in the value attribute.
3827                      // This minimises (does not eliminate) the possibility of a TXP-initiated preg_match error, while still
3828                      // preserving errors outside TXP's control (e.g. mangled user-submitted PCRE pattern)
3829                      $dlmPool = array('/', '@', '#', '~', '`', '|', '!', '%');
3830                      $dlm = array_merge(array_diff($dlmPool, preg_split('//', $value, -1)));
3831                      $dlm = (count($dlm) > 0) ? $dlm[0].$value.$dlm[0] : $value;
3832                      $cond = preg_match($dlm, @$thisarticle[$name]);
3833                      break;
3834                  default:
3835                      trigger_error(gTxt('invalid_attribute_value', array('{name}' => 'value')), E_USER_NOTICE);
3836                      $cond = false;
3837              }
3838          else
3839              $cond = !empty($thisarticle[$name]);
3840  
3841          return parse(EvalElse($thing, $cond));
3842      }
3843  
3844  // -------------------------------------------------------------
3845  	function site_url()
3846      {
3847          return hu;
3848      }
3849  
3850  // -------------------------------------------------------------
3851      # DEPRECATED - provided only for backwards compatibility
3852  	function img($atts)
3853      {
3854          trigger_error(gTxt('deprecated_tag'), E_USER_NOTICE);
3855  
3856          extract(lAtts(array(
3857              'src' => '',
3858          ), $atts));
3859  
3860          $img = rtrim(hu, '/').'/'.ltrim($src, '/');
3861  
3862          $out = '<img src="'.$img.'" />';
3863  
3864          return $out;
3865      }
3866  
3867  // -------------------------------------------------------------
3868  	function error_message()
3869      {
3870          return @$GLOBALS['txp_error_message'];
3871      }
3872  
3873  // -------------------------------------------------------------
3874  	function error_status()
3875      {
3876          return @$GLOBALS['txp_error_status'];
3877      }
3878  
3879  // -------------------------------------------------------------
3880  	function if_status($atts, $thing)
3881      {
3882          global $pretext;
3883  
3884          extract(lAtts(array(
3885              'status' => '200',
3886          ), $atts));
3887  
3888          $page_status = !empty($GLOBALS['txp_error_code'])
3889              ? $GLOBALS['txp_error_code']
3890              : $pretext['status'];
3891  
3892          return parse(EvalElse($thing, $status == $page_status));
3893      }
3894  
3895  // -------------------------------------------------------------
3896  	function page_url($atts)
3897      {
3898          global $pretext;
3899  
3900          extract(lAtts(array(
3901              'type' => 'request_uri',
3902          ), $atts));
3903  
3904          return @htmlspecialchars($pretext[$type]);
3905      }
3906  
3907  // -------------------------------------------------------------
3908  	function if_different($atts, $thing)
3909      {
3910          static $last;
3911  
3912          $key = md5($thing);
3913  
3914          $cond = EvalElse($thing, 1);
3915  
3916          $out = parse($cond);
3917          if (empty($last[$key]) or $out != $last[$key]) {
3918              return $last[$key] = $out;
3919          }
3920          else
3921              return parse(EvalElse($thing, 0));
3922      }
3923  
3924  // -------------------------------------------------------------
3925  	function if_first_article($atts, $thing)
3926      {
3927          global $thisarticle;
3928          assert_article();
3929          return parse(EvalElse($thing, !empty($thisarticle['is_first'])));
3930      }
3931  
3932  // -------------------------------------------------------------
3933  	function if_last_article($atts, $thing)
3934      {
3935          global $thisarticle;
3936          assert_article();
3937          return parse(EvalElse($thing, !empty($thisarticle['is_last'])));
3938      }
3939  
3940  // -------------------------------------------------------------
3941  	function if_plugin($atts, $thing)
3942      {
3943          global $plugins, $plugins_ver;
3944          extract(lAtts(array(
3945              'name'    => '',
3946              'ver'     => '', // deprecated in 4.3.0
3947              'version' => '',
3948          ),$atts));
3949  
3950          if (isset($atts['ver'])) {
3951              $version = $ver;
3952              trigger_error(gTxt('deprecated_attribute', array('{name}' => 'ver')), E_USER_NOTICE);
3953          }
3954  
3955          return parse(EvalElse($thing, @in_array($name, $plugins) and (!$version or version_compare($plugins_ver[$name], $version) >= 0)));
3956      }
3957  
3958  //--------------------------------------------------------------------------
3959  
3960  	function file_download_list($atts, $thing = NULL)
3961      {
3962          global $s, $c, $context, $thisfile, $thispage, $pretext;
3963  
3964          extract(lAtts(array(
3965              'break'       => br,
3966              'category'    => '',
3967              'author'      => '',
3968              'realname'    => '',
3969              'auto_detect' => 'category, author',
3970              'class'       => __FUNCTION__,
3971              'form'        => 'files',
3972              'id'          => '',
3973              'label'       => '',
3974              'labeltag'    => '',
3975              'pageby'      => '',
3976              'limit'       => 10,
3977              'offset'      => 0,
3978              'sort'        => 'filename asc',
3979              'wraptag'     => '',
3980              'status'      => '4',
3981          ), $atts));
3982  
3983          if (!is_numeric($status))
3984              $status = getStatusNum($status);
3985  
3986          // N.B. status treated slightly differently
3987          $where = $statwhere = array();
3988          $filters = isset($atts['id']) || isset($atts['category']) || isset($atts['author']) || isset($atts['realname']) || isset($atts['status']);
3989          $context_list = (empty($auto_detect) || $filters) ? array() : do_list($auto_detect);
3990          $pageby = ($pageby=='limit') ? $limit : $pageby;
3991  
3992          if ($category) $where[] = "category IN ('".join("','", doSlash(do_list($category)))."')";
3993          if ($id) $where[] = "id IN ('".join("','", doSlash(do_list($id)))."')";
3994          if ($status) $statwhere[] = "status = '".doSlash($status)."'";
3995          if ($author) $where[] = "author IN ('".join("','", doSlash(do_list($author)))."')";
3996          if ($realname) {
3997              $authorlist = safe_column('name', 'txp_users', "RealName IN ('". join("','", doArray(doSlash(do_list($realname)), 'urldecode')) ."')" );
3998              $where[] = "author IN ('".join("','", doSlash($authorlist))."')";
3999          }
4000  
4001          // If no files are selected, try...
4002          if (!$where && !$filters)
4003          {
4004              foreach ($context_list as $ctxt)
4005              {
4006                  switch ($ctxt)
4007                  {
4008                      case 'category':
4009                          // ... the global category in the URL
4010                          if ($context == 'file' && !empty($c))
4011                          {
4012                              $where[] = "category = '".doSlash($c)."'";
4013                          }
4014                          break;
4015                      case 'author':
4016                          // ... the global author in the URL
4017                          if ($context == 'file' && !empty($pretext['author']))
4018                          {
4019                              $where[] = "author = '".doSlash($pretext['author'])."'";
4020                          }
4021                          break;
4022                  }
4023                  // Only one context can be processed
4024                  if ($where) break;
4025              }
4026          }
4027  
4028          if (!$where && !$statwhere && $filters)
4029          {
4030              return ''; // If nothing matches, output nothing
4031          }
4032  
4033          if (!$where)
4034          {
4035              $where[] = "1=1"; // If nothing matches, start with all files
4036          }
4037  
4038          $where = join(' AND ', array_merge($where, $statwhere));
4039  
4040          // Set up paging if required
4041          if ($limit && $pageby) {
4042              $grand_total = safe_count('txp_file', $where);
4043              $total = $grand_total - $offset;
4044              $numPages = ($pageby > 0) ? ceil($total/$pageby) : 1;
4045              $pg = (!$pretext['pg']) ? 1 : $pretext['pg'];
4046              $pgoffset = $offset + (($pg - 1) * $pageby);
4047              // send paging info to txp:newer and txp:older
4048              $pageout['pg']          = $pg;
4049              $pageout['numPages']    = $numPages;
4050              $pageout['s']           = $s;
4051              $pageout['c']           = $c;
4052              $pageout['context']     = 'file';
4053              $pageout['grand_total'] = $grand_total;
4054              $pageout['total']       = $total;
4055  
4056              if (empty($thispage))
4057                  $thispage = $pageout;
4058          } else {
4059              $pgoffset = $offset;
4060          }
4061  
4062          $qparts = array(
4063              'order by '.doSlash($sort),
4064              ($limit) ? 'limit '.intval($pgoffset).', '.intval($limit) : '',
4065          );
4066  
4067          $rs = safe_rows_start('*', 'txp_file', $where.' '.join(' ', $qparts));
4068  
4069          if ($rs)
4070          {
4071              $out = array();
4072  
4073              while ($a = nextRow($rs))
4074              {
4075                  $thisfile = file_download_format_info($a);
4076  
4077                  $out[] = ($thing) ? parse($thing) : parse_form($form);
4078  
4079                  $thisfile = '';
4080              }
4081  
4082              if ($out)
4083              {
4084                  return doLabel($label, $labeltag).doWrap($out, $wraptag, $break, $class);
4085              }
4086          }
4087          return '';
4088      }
4089  
4090  //--------------------------------------------------------------------------
4091  
4092  	function file_download($atts)
4093      {
4094          global $thisfile;
4095  
4096          extract(lAtts(array(
4097              'filename' => '',
4098              'form'     => 'files',
4099              'id'       => '',
4100          ), $atts));
4101  
4102          $from_form = false;
4103  
4104          if ($id)
4105          {
4106              $thisfile = fileDownloadFetchInfo('id = '.intval($id));
4107          }
4108  
4109          elseif ($filename)
4110          {
4111              $thisfile = fileDownloadFetchInfo("filename = '".doSlash($filename)."'");
4112          }
4113  
4114          else
4115          {
4116              assert_file();
4117  
4118              $from_form = true;
4119          }
4120  
4121          if ($thisfile)
4122          {
4123              $out = parse_form($form);
4124  
4125              // cleanup: this wasn't called from a form,
4126              // so we don't want this value remaining
4127              if (!$from_form)
4128              {
4129                  $thisfile = '';
4130              }
4131  
4132              return $out;
4133          }
4134      }
4135  
4136  //--------------------------------------------------------------------------
4137  
4138  	function file_download_link($atts, $thing = NULL)
4139      {
4140          global $thisfile;
4141  
4142          extract(lAtts(array(
4143              'filename' => '',
4144              'id'       => '',
4145          ), $atts));
4146  
4147          $from_form = false;
4148  
4149          if ($id)
4150          {
4151              $thisfile = fileDownloadFetchInfo('id = '.intval($id));
4152          }
4153  
4154          elseif ($filename)
4155          {
4156              $thisfile = fileDownloadFetchInfo("filename = '".doSlash($filename)."'");
4157          }
4158  
4159          else
4160          {
4161              assert_file();
4162  
4163              $from_form = true;
4164          }
4165  
4166          if ($thisfile)
4167          {
4168              $url = filedownloadurl($thisfile['id'], $thisfile['filename']);
4169  
4170              $out = ($thing) ? href(parse($thing), $url) : $url;
4171  
4172              // cleanup: this wasn't called from a form,
4173              // so we don't want this value remaining
4174              if (!$from_form)
4175              {
4176                  $thisfile = '';
4177              }
4178  
4179              return $out;
4180          }
4181      }
4182  
4183  //--------------------------------------------------------------------------
4184  
4185  	function fileDownloadFetchInfo($where)
4186      {
4187          $rs = safe_row('*', 'txp_file', $where);
4188  
4189          if ($rs)
4190          {
4191              return file_download_format_info($rs);
4192          }
4193  
4194          return false;
4195      }
4196  
4197  //--------------------------------------------------------------------------
4198  
4199  	function file_download_format_info($file)
4200      {
4201          if (($unix_ts = @strtotime($file['created'])) > 0)
4202              $file['created'] = $unix_ts;
4203          if (($unix_ts = @strtotime($file['modified'])) > 0)
4204              $file['modified'] = $unix_ts;
4205  
4206          return $file;
4207      }
4208  
4209  //--------------------------------------------------------------------------
4210  
4211  	function file_download_size($atts)
4212      {
4213          global $thisfile;
4214          assert_file();
4215  
4216          extract(lAtts(array(
4217              'decimals' => 2,
4218              'format'   => '',
4219          ), $atts));
4220  
4221          if (is_numeric($decimals) and $decimals >= 0)
4222          {
4223              $decimals = intval($decimals);
4224          }
4225  
4226          else
4227          {
4228              $decimals = 2;
4229          }
4230  
4231          if (@$thisfile['size'])
4232          {
4233              $size = $thisfile['size'];
4234  
4235              if (!in_array($format, array('B','KB','MB','GB','PB')))
4236              {
4237                  $divs = 0;
4238  
4239                  while ($size >= 1024)
4240                  {
4241                      $size /= 1024;
4242                      $divs++;
4243                  }
4244  
4245                  switch ($divs)
4246                  {
4247                      case 1:
4248                          $format = 'KB';
4249                      break;
4250  
4251                      case 2:
4252                          $format = 'MB';
4253                      break;
4254  
4255                      case 3:
4256                          $format = 'GB';
4257                      break;
4258  
4259                      case 4:
4260                          $format = 'PB';
4261                      break;
4262  
4263                      case 0:
4264                      default:
4265                          $format = 'B';
4266                      break;
4267                  }
4268              }
4269  
4270              $size = $thisfile['size'];
4271  
4272              switch ($format)
4273              {
4274                  case 'KB':
4275                      $size /= 1024;
4276                  break;
4277  
4278                  case 'MB':
4279                      $size /= (1024*1024);
4280                  break;
4281  
4282                  case 'GB':
4283                      $size /= (1024*1024*1024);
4284                  break;
4285  
4286                  case 'PB':
4287                      $size /= (1024*1024*1024*1024);
4288                  break;
4289  
4290                  case 'B':
4291                  default:
4292                      // do nothing
4293                  break;
4294              }
4295  
4296              return number_format($size, $decimals).$format;
4297          }
4298  
4299          else
4300          {
4301              return '';
4302          }
4303      }
4304  
4305  //--------------------------------------------------------------------------
4306  
4307  	function file_download_created($atts)
4308      {
4309          global $thisfile;
4310          assert_file();
4311  
4312          extract(lAtts(array(
4313              'format' => '',
4314          ), $atts));
4315  
4316          if ($thisfile['created']) {
4317              return fileDownloadFormatTime(array(
4318                  'ftime'  => $thisfile['created'],
4319                  'format' => $format
4320              ));
4321          }
4322      }
4323  
4324  //--------------------------------------------------------------------------
4325  
4326  	function file_download_modified($atts)
4327      {
4328          global $thisfile;
4329          assert_file();
4330  
4331          extract(lAtts(array(
4332              'format' => '',
4333          ), $atts));
4334  
4335          if ($thisfile['modified']) {
4336              return fileDownloadFormatTime(array(
4337                  'ftime'  => $thisfile['modified'],
4338                  'format' => $format
4339              ));
4340          }
4341      }
4342  
4343  //-------------------------------------------------------------------------
4344  // All the time related file_download tags in one
4345  // One Rule to rule them all... now using safe formats
4346  
4347  	function fileDownloadFormatTime($params)
4348      {
4349          global $prefs;
4350  
4351          extract($params);
4352  
4353          if (!empty($ftime))
4354          {
4355              return !empty($format) ?
4356                  safe_strftime($format, $ftime) : safe_strftime($prefs['archive_dateformat'], $ftime);
4357          }
4358          return '';
4359      }
4360  
4361  //--------------------------------------------------------------------------
4362  
4363  	function file_download_id()
4364      {
4365          global $thisfile;
4366          assert_file();
4367          return $thisfile['id'];
4368      }
4369  
4370  //--------------------------------------------------------------------------
4371  
4372  	function file_download_name($atts)
4373      {
4374          global $thisfile;
4375          assert_file();
4376  
4377          extract(lAtts(array(
4378              'title' => 0,
4379          ), $atts));
4380  
4381          return ($title) ? $thisfile['title'] : $thisfile['filename'];
4382      }
4383  
4384  //--------------------------------------------------------------------------
4385  
4386  	function file_download_category($atts)
4387      {
4388          global $thisfile;
4389          assert_file();
4390  
4391          extract(lAtts(array(
4392              'class'   => '',
4393              'title'   => 0,
4394              'wraptag' => '',
4395          ), $atts));
4396  
4397          if ($thisfile['category'])
4398          {
4399              $category = ($title) ?
4400                  fetch_category_title($thisfile['category'], 'file') :
4401                  $thisfile['category'];
4402  
4403              return ($wraptag) ? doTag($category, $wraptag, $class) : $category;
4404          }
4405      }
4406  
4407  //--------------------------------------------------------------------------
4408  
4409  	function file_download_author($atts)
4410      {
4411          global $thisfile, $s;
4412          assert_file();
4413  
4414          extract(lAtts(array(
4415              'class'        => '',
4416              'link'         => 0,
4417              'title'        => 1,
4418              'section'      => '',
4419              'this_section' => '',
4420              'wraptag'      => '',
4421          ), $atts));
4422  
4423          if ($thisfile['author'])
4424          {
4425              $author_name = get_author_name($thisfile['author']);
4426              $display_name = htmlspecialchars( ($title) ? $author_name : $thisfile['author'] );
4427  
4428              $section = ($this_section) ? ( $s == 'default' ? '' : $s ) : $section;
4429  
4430              $author = ($link) ?
4431                  href($display_name, pagelinkurl(array('s' => $section, 'author' => $author_name, 'context' => 'file'))) :
4432                  $display_name;
4433  
4434              return ($wraptag) ? doTag($author, $wraptag, $class) : $author;
4435          }
4436      }
4437  
4438  //--------------------------------------------------------------------------
4439  
4440  	function file_download_downloads()
4441      {
4442          global $thisfile;
4443          assert_file();
4444          return $thisfile['downloads'];
4445      }
4446  
4447  //--------------------------------------------------------------------------
4448  
4449  	function file_download_description($atts)
4450      {
4451          global $thisfile;
4452          assert_file();
4453  
4454          extract(lAtts(array(
4455              'class'   => '',
4456              'escape'  => 'html',
4457              'wraptag' => '',
4458          ), $atts));
4459  
4460          if ($thisfile['description'])
4461          {
4462              $description = ($escape == 'html') ?
4463                  htmlspecialchars($thisfile['description']) : $thisfile['description'];
4464  
4465              return ($wraptag) ? doTag($description, $wraptag, $class) : $description;
4466          }
4467      }
4468  
4469  // -------------------------------------------------------------
4470  
4471  	function hide()
4472      {
4473          return '';
4474      }
4475  
4476  // -------------------------------------------------------------
4477  
4478  	function rsd()
4479      {
4480          global $prefs;
4481          return ($prefs['enable_xmlrpc_server']) ? '<link rel="EditURI" type="application/rsd+xml" title="RSD" href="'.hu.'rpc/" />' : '';
4482      }
4483  
4484  // -------------------------------------------------------------
4485  
4486  	function variable($atts, $thing = NULL)
4487      {
4488          global $variable;
4489  
4490          extract(lAtts(array(
4491              'name'    => '',
4492              'value'    => parse($thing)
4493          ), $atts));
4494  
4495          if (empty($name))
4496          {
4497              trigger_error(gTxt('variable_name_empty'));
4498              return;
4499          }
4500  
4501          if (!isset($atts['value']) and empty($thing))
4502          {
4503              return $variable[$name];
4504          }
4505          else
4506          {
4507              $variable[$name] = $value;
4508          }
4509      }
4510  
4511  // -------------------------------------------------------------
4512  
4513  	function if_variable($atts, $thing = NULL)
4514      {
4515          global $variable;
4516  
4517          extract(lAtts(array(
4518              'name'    => '',
4519              'value'    => ''
4520          ), $atts));
4521  
4522          if (empty($name))
4523          {
4524              trigger_error(gTxt('variable_name_empty'));
4525              return;
4526          }
4527  
4528          if (isset($variable[$name]))
4529          {
4530              if (!isset($atts['value']))
4531              {
4532                  $x = true;
4533              }
4534              else
4535              {
4536                  $x = $variable[$name] == $value;
4537              }
4538          }
4539          else
4540          {
4541              $x = false;
4542          }
4543  
4544          return parse(EvalElse($thing, $x));
4545      }
4546  ?>


[ Powered by PHPXref - Served by Debian GNU/Linux ]