[ Index ]

PHP Cross Reference of Textpattern 4.0.8

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


Generated: Thu May 21 23:03:01 2009 Cross-referenced by PHPXref 0.7