[ Index ] [ Index ]     [ Classes ]     [ Functions ]     [ Variables ]     [ Constants ]

PHP Cross Reference of TXP stable 4.0.6

title

Body

[close]

/textpattern/ -> publish.php (source)

   1  <?php
   2  /*
   3              _______________________________________
   4     ________|                                       |_________
   5    \        |                                       |        /
   6     \       |              Textpattern              |       /
   7      \      |                                       |      /
   8      /      |_______________________________________|      \
   9     /___________)                               (___________\
  10  
  11      Copyright 2005 by Dean Allen
  12      All rights reserved.
  13  
  14      Use of this software denotes acceptance of the Textpattern license agreement
  15  
  16  $HeadURL: http://svn.textpattern.com/releases/4.0.6/source/textpattern/publish.php $
  17  $LastChangedRevision: 2777 $
  18  
  19  */
  20  
  21      if (!defined('txpath'))
  22          define("txpath", dirname(__FILE__));
  23      if (!defined("txpinterface"))
  24          die('If you just updated and expect to see your site here, please also update the files in your main installation directory.'.
  25              ' (Otherwise note that publish.php cannot be called directly.)');
  26  
  27  
  28      include_once txpath.'/lib/constants.php';
  29      include_once txpath.'/lib/txplib_misc.php';
  30      include_once txpath.'/lib/txplib_db.php';
  31      include_once txpath.'/lib/txplib_html.php';
  32      include_once txpath.'/lib/txplib_forms.php';
  33      include_once txpath.'/lib/admin_config.php';
  34  
  35      include_once txpath.'/publish/taghandlers.php';
  36      include_once txpath.'/publish/log.php';
  37      include_once txpath.'/publish/comment.php';
  38  
  39  //    set_error_handler('myErrorHandler');
  40  
  41      ob_start();
  42  
  43          // start the clock for runtime
  44      $microstart = getmicrotime();
  45  
  46          // get all prefs as an array
  47      $prefs = get_prefs();
  48  
  49          // add prefs to globals
  50      extract($prefs);
  51  
  52      // check the size of the url request
  53      bombShelter();
  54  
  55          // set a higher error level during initialization
  56      set_error_level(@$production_status == 'live' ? 'testing' : @$production_status);
  57  
  58          // use the current URL path if $siteurl is unknown
  59      if (empty($siteurl))
  60          $prefs['siteurl'] = $siteurl = $_SERVER['HTTP_HOST'] . rtrim(dirname($_SERVER['SCRIPT_NAME']), '/');
  61  
  62      if (empty($path_to_site))
  63          updateSitePath(dirname(dirname(__FILE__)));
  64  
  65      if (!defined('PROTOCOL')) {
  66          switch (serverSet('HTTPS')) {
  67              case '':
  68              case 'off': // ISAPI with IIS
  69                  define('PROTOCOL', 'http://');
  70              break;
  71  
  72              default:
  73                  define('PROTOCOL', 'https://');
  74              break;
  75          }
  76      }
  77  
  78          // v1.0: this should be the definitive http address of the site
  79      if (!defined('hu'))
  80          define("hu",PROTOCOL.$siteurl.'/');
  81  
  82          // v1.0 experimental relative url global
  83      if (!defined('rhu'))
  84          define("rhu",preg_replace("|^https?://[^/]+|","",hu));
  85  
  86          // 1.0: a new $here variable in the top-level index.php
  87          // should let us know the server path to the live site
  88          // let's save it to prefs
  89      if (isset($here) and $path_to_site != $here) updateSitePath($here);
  90  
  91          // 1.0 removed $doc_root variable from config, but we'll
  92          // leave it here for a bit until plugins catch up
  93      $txpcfg['doc_root'] = @$_SERVER['DOCUMENT_ROOT'];
  94      // work around the IIS lobotomy
  95      if (empty($txpcfg['doc_root']))
  96          $txpcfg['doc_root'] = @$_SERVER['PATH_TRANSLATED'];
  97  
  98      if (!defined('LANG'))
  99          define("LANG",$language);
 100      if (!empty($locale)) setlocale(LC_ALL, $locale);
 101  
 102          //Initialize the current user
 103      $txp_user = NULL;
 104  
 105          //i18n: $textarray = load_lang('en-gb');
 106      $textarray = load_lang(LANG);
 107  
 108          // here come the plugins
 109      if ($use_plugins) load_plugins();
 110  
 111          // this step deprecated as of 1.0 : really only useful with old-style
 112          // section placeholders, which passed $s='section_name'
 113      $s = (empty($s)) ? '' : $s;
 114  
 115      $pretext = !isset($pretext) ? array() : $pretext;
 116      $pretext = array_merge($pretext, pretext($s,$prefs));
 117      extract($pretext);
 118  
 119      // Now that everything is initialized, we can crank down error reporting
 120      set_error_level($production_status);
 121  
 122      if (gps('parentid') && gps('submit')) {
 123          saveComment();
 124      } elseif (gps('parentid') and $comments_mode==1) { // popup comments?
 125          header("Content-type: text/html; charset=utf-8");
 126          exit(popComments(gps('parentid')));
 127      }
 128  
 129      // we are dealing with a download
 130      if (@$s == 'file_download') {
 131          callback_event('file_download');
 132          if (!isset($file_error)) {
 133  
 134                  $fullpath = build_file_path($file_base_path,$filename);
 135  
 136                  if (is_file($fullpath)) {
 137  
 138                      // discard any error php messages
 139                      ob_clean();
 140                      $filesize = filesize($fullpath); $sent = 0;
 141                      header('Content-Description: File Download');
 142                      header('Content-Type: application/octet-stream');
 143                      header('Content-Disposition: attachment; filename="' . basename($filename) . '"; size = "'.$filesize.'"');
 144                      // Fix for lame IE 6 pdf bug on servers configured to send cache headers
 145                      header('Cache-Control: private');
 146                      @ini_set("zlib.output_compression", "Off");
 147                      @set_time_limit(0);
 148                      @ignore_user_abort(true);
 149                      if ($file = fopen($fullpath, 'rb')) {
 150                          while(!feof($file) and (connection_status()==0)) {
 151                              echo fread($file, 1024*64); $sent+=(1024*64);
 152                              ob_flush();
 153                              flush();
 154                          }
 155                          fclose($file);
 156                          // record download
 157                          if ((connection_status()==0) and !connection_aborted() ) {
 158                              safe_update("txp_file", "downloads=downloads+1", 'id='.intval($id));
 159                              log_hit('200');
 160                          } else {
 161                              $pretext['request_uri'] .= ($sent >= $filesize)
 162                                  ? '#aborted'
 163                                  : "#aborted-at-".floor($sent*100/$filesize)."%";
 164                              log_hit('200');
 165                          }
 166                      }
 167                  } else {
 168                      $file_error = 404;
 169                  }
 170          }
 171  
 172          // deal with error
 173          if (isset($file_error)) {
 174              switch($file_error) {
 175              case 403:
 176                  txp_die(gTxt('403_forbidden'), '403');
 177                  break;
 178              case 404:
 179                  txp_die(gTxt('404_not_found'), '404');
 180                  break;
 181              default:
 182                  txp_die(gTxt('500_internal_server_error'), '500');
 183                  break;
 184              }
 185          }
 186  
 187          // download done
 188          exit(0);
 189      }
 190  
 191  
 192      // send 304 Not Modified if appropriate
 193      handle_lastmod();
 194  
 195      // log the page view
 196      log_hit($status);
 197  
 198  
 199  // -------------------------------------------------------------
 200  	function preText($s,$prefs)
 201      {
 202          extract($prefs);
 203  
 204          callback_event('pretext');
 205  
 206          if(gps('rss')) {
 207              include txpath.'/publish/rss.php';
 208              exit(rss());
 209          }
 210  
 211          if(gps('atom')) {
 212              include txpath.'/publish/atom.php';
 213              exit(atom());
 214          }
 215              // set messy variables
 216          $out =  makeOut('id','s','c','q','pg','p','month','author');
 217  
 218              // some useful vars for taghandlers, plugins
 219          $out['request_uri'] = preg_replace("|^https?://[^/]+|i","",serverSet('REQUEST_URI'));
 220          $out['qs'] = serverSet('QUERY_STRING');
 221              // IIS fix
 222          if (!$out['request_uri'] and serverSet('SCRIPT_NAME'))
 223              $out['request_uri'] = serverSet('SCRIPT_NAME').( (serverSet('QUERY_STRING')) ? '?'.serverSet('QUERY_STRING') : '');
 224              // another IIS fix
 225          if (!$out['request_uri'] and serverSet('argv'))
 226          {
 227              $argv = serverSet('argv');
 228              $out['request_uri'] = @substr($argv[0], strpos($argv[0], ';') + 1);
 229          }
 230  
 231              // define the useable url, minus any subdirectories.
 232              // this is pretty fugly, if anyone wants to have a go at it - dean
 233          $out['subpath'] = $subpath = preg_quote(preg_replace("/https?:\/\/.*(\/.*)/Ui","$1",hu),"/");
 234          $out['req'] = $req = preg_replace("/^$subpath/i","/",$out['request_uri']);
 235  
 236          $is_404 = 0;
 237  
 238              // if messy vars exist, bypass url parsing
 239          if (!$out['id'] && !$out['s'] && !(txpinterface=='css') &&! ( txpinterface=='admin') ) {
 240  
 241              // return clean URL test results for diagnostics
 242              if (gps('txpcleantest')) {
 243                  exit(show_clean_test($out));
 244              }
 245  
 246              extract(chopUrl($req));
 247  
 248                  //first we sniff out some of the preset url schemes
 249              if (strlen($u1)) {
 250  
 251                  switch($u1) {
 252  
 253                      case 'atom':
 254                          include txpath.'/publish/atom.php'; exit(atom());
 255  
 256                      case 'rss':
 257                          include txpath.'/publish/rss.php'; exit(rss());
 258  
 259                      // urldecode(strtolower(urlencode())) looks ugly but is the only way to
 260                      // make it multibyte-safe without breaking backwards-compatibility
 261                      case urldecode(strtolower(urlencode(gTxt('section')))):
 262                          $out['s'] = (ckEx('section',$u2)) ? $u2 : ''; $is_404 = empty($out['s']); break;
 263  
 264                      case urldecode(strtolower(urlencode(gTxt('category')))):
 265                          $out['c'] = (ckEx('category',$u2)) ? $u2 : ''; $is_404 = empty($out['c']); break;
 266  
 267                      case urldecode(strtolower(urlencode(gTxt('author')))):
 268                          $out['author'] = (!empty($u2)) ? $u2 : ''; break;
 269                          // AuthorID gets resolved from Name further down
 270  
 271                      case urldecode(strtolower(urlencode(gTxt('file_download')))):
 272                          $out['s'] = 'file_download';
 273                          $out['id'] = (!empty($u2)) ? $u2 : ''; break;
 274  
 275                      default:
 276                          // then see if the prefs-defined permlink scheme is usable
 277                          switch ($permlink_mode) {
 278  
 279                              case 'section_id_title':
 280                                  if (empty($u2)) {
 281                                      $out['s'] = (ckEx('section',$u1)) ? $u1 : '';
 282                                      $is_404 = empty($out['s']);
 283                                  }
 284                                  else {
 285                                      $rs = lookupByIDSection($u2, $u1);
 286                                      $out['s'] = @$rs['Section'];
 287                                      $out['id'] = @$rs['ID'];
 288                                      $is_404 = (empty($out['s']) or empty($out['id']));
 289                                  }
 290                              break;
 291  
 292                              case 'year_month_day_title':
 293                                  if (empty($u2)) {
 294                                      $out['s'] = (ckEx('section',$u1)) ? $u1 : '';
 295                                      $is_404 = empty($out['s']);
 296                                  }
 297                                  elseif (empty($u4)){
 298                                      $month = "$u1-$u2";
 299                                      if (!empty($u3)) $month.= "-$u3";
 300                                      if (preg_match('/\d+-\d+(?:-\d+)?/', $month)) {
 301                                          $out['month'] = $month;
 302                                          $out['s'] = 'default';
 303                                      }
 304                                      else {
 305                                          $is_404 = 1;
 306                                      }
 307                                  }else{
 308                                      $when = "$u1-$u2-$u3";
 309                                      $rs = lookupByDateTitle($when,$u4);
 310                                      $out['id'] = (!empty($rs['ID'])) ? $rs['ID'] : '';
 311                                      $out['s'] = (!empty($rs['Section'])) ? $rs['Section'] : '';
 312                                      $is_404 = (empty($out['s']) or empty($out['id']));
 313                                  }
 314                              break;
 315  
 316                              case 'section_title':
 317                                  if (empty($u2)) {
 318                                      $out['s'] = (ckEx('section',$u1)) ? $u1 : '';
 319                                      $is_404 = empty($out['s']);
 320                                  }
 321                                  else {
 322                                      $rs = lookupByTitleSection($u2,$u1);
 323                                      $out['id'] = @$rs['ID'];
 324                                      $out['s'] = @$rs['Section'];
 325                                      $is_404 = (empty($out['s']) or empty($out['id']));
 326                                  }
 327                              break;
 328  
 329                              case 'title_only':
 330                                  $rs = lookupByTitle($u1);
 331                                  $out['id'] = @$rs['ID'];
 332                                  $out['s'] = (empty($rs['Section']) ? ckEx('section', $u1) :
 333                                          $rs['Section']);
 334                                  $is_404 = empty($out['s']);
 335                              break;
 336  
 337                              case 'id_title':
 338                                  if (is_numeric($u1) && ckExID($u1))
 339                                  {
 340                                      $rs = lookupByID($u1);
 341                                      $out['id'] = (!empty($rs['ID'])) ? $rs['ID'] : '';
 342                                      $out['s'] = (!empty($rs['Section'])) ? $rs['Section'] : '';
 343                                      $is_404 = (empty($out['s']) or empty($out['id']));
 344                                  }else{
 345                                      # We don't want to miss the /section/ pages
 346                                      $out['s']= ckEx('section',$u1)? $u1 : '';
 347                                      $is_404 = empty($out['s']);
 348                                  }
 349                              break;
 350  
 351                          }
 352                  }
 353              } else {
 354                  $out['s'] = 'default';
 355              }
 356          }
 357          else {
 358              // Messy mode, but prevent to get the id for file_downloads
 359              if ($out['id'] && !$out['s']) {
 360                  $rs = lookupByID($out['id']);
 361                  $out['id'] = (!empty($rs['ID'])) ? $rs['ID'] : '';
 362                  $out['s'] = (!empty($rs['Section'])) ? $rs['Section'] : '';
 363                  $is_404 = (empty($out['s']) or empty($out['id']));
 364              }
 365          }
 366  
 367          // Resolve AuthorID from Authorname
 368          if ($out['author'])
 369          {
 370              $name = urldecode(strtolower(urlencode($out['author'])));
 371  
 372              $name = safe_field('name', 'txp_users', "RealName like '".doSlash($out['author'])."'");
 373  
 374              if ($name)
 375              {
 376                  $out['author'] = $name;
 377              }
 378  
 379              else
 380              {
 381                  $out['author'] = '';
 382                  $is_404 = true;
 383              }
 384          }
 385  
 386          // Stats: found or not
 387          $out['status'] = ($is_404 ? '404' : '200');
 388  
 389          $out['pg'] = is_numeric($out['pg']) ? intval($out['pg']) : '';
 390          $out['id'] = is_numeric($out['id']) ? intval($out['id']) : '';
 391  
 392          if ($out['s'] == 'file_download') {
 393              // get id of potential filename
 394              if (!is_numeric($out['id'])) {
 395                  $rs = safe_row("*", "txp_file", "filename='".doSlash($out['id'])."' and status = 4");
 396              } else {
 397                  $rs = safe_row("*", "txp_file", 'id='.intval($out['id']).' and status = 4');
 398              }
 399  
 400              $out = ($rs)? array_merge($out, $rs) : array('s'=>'file_download','file_error'=> 404);
 401              return $out;
 402          }
 403  
 404          if (!$is_404)
 405              $out['s'] = (empty($out['s'])) ? 'default' : $out['s'];
 406          $s = $out['s'];
 407          $id = $out['id'];
 408  
 409          // hackish
 410          global $is_article_list;
 411          if(empty($id)) $is_article_list = true;
 412  
 413              // by this point we should know the section, so grab its page and css
 414          $rs = safe_row("*", "txp_section", "name = '".doSlash($s)."' limit 1");
 415          $out['page'] = @$rs['page'];
 416  
 417          if(is_numeric($id)) {
 418              $a = safe_row('*, unix_timestamp(Posted) as uPosted', 'textpattern', 'ID='.intval($id).' and Status in (4,5)');
 419              if ($a) {
 420                  $Posted             = $a['Posted'];
 421                  $out['id_keywords'] = $a['Keywords'];
 422                  $out['id_author']   = $a['AuthorID'];
 423                  populateArticleData($a);
 424  
 425                  if ($np = getNextPrev($id, $Posted, $s))
 426                      $out = array_merge($out, $np);
 427              }
 428          }
 429  
 430          $out['path_from_root'] = rhu; // these are deprecated as of 1.0
 431          $out['pfr']            = rhu; // leaving them here for plugin compat
 432  
 433          $out['path_to_site']   = $path_to_site;
 434          $out['permlink_mode']  = $permlink_mode;
 435          $out['sitename']       = $sitename;
 436  
 437          return $out;
 438  
 439      }
 440  
 441  //    textpattern() is the function that assembles a page, based on
 442  //    the variables passed to it by pretext();
 443  
 444  // -------------------------------------------------------------
 445  	function textpattern()
 446      {
 447          global $pretext,$microstart,$prefs,$qcount,$qtime,$production_status,$txptrace,$siteurl,$has_article_tag;
 448  
 449          $has_article_tag = false;
 450  
 451          callback_event('textpattern');
 452  
 453          if ($pretext['status'] == '404')
 454              txp_die(gTxt('404_not_found'), '404');
 455  
 456          $html = safe_field('user_html','txp_page',"name='".doSlash($pretext['page'])."'");
 457          if (!$html)
 458              txp_die(gTxt('unknown_section'), '404');
 459  
 460          // useful for clean urls with error-handlers
 461          txp_status_header('200 OK');
 462  
 463          trace_add('['.gTxt('page').': '.$pretext['page'].']');
 464          set_error_handler("tagErrorHandler");
 465          $pretext['secondpass'] = false;
 466          $html = parse($html);
 467          $pretext['secondpass'] = true;
 468          trace_add('[ ~~~ '.gTxt('secondpass').' ~~~ ]');
 469          $html = parse($html); // the function so nice, he ran it twice
 470          $html = ($prefs['allow_page_php_scripting']) ? evalString($html) : $html;
 471  
 472          // make sure the page has an article tag if necessary
 473          if (!$has_article_tag and $production_status != 'live' and (!empty($pretext['id']) or !empty($pretext['c']) or !empty($pretext['q']) or !empty($pretext['pg'])))
 474              trigger_error(gTxt('missing_article_tag', array('{page}' => $pretext['page'])));
 475          restore_error_handler();
 476  
 477          header("Content-type: text/html; charset=utf-8");
 478          echo $html;
 479  
 480          if (in_array($production_status, array('debug', 'testing'))) {
 481              $microdiff = (getmicrotime() - $microstart);
 482              echo n,comment('Runtime:    '.substr($microdiff,0,6));
 483              echo n,comment('Query time: '.$qtime);
 484              echo n,comment('Queries: '.$qcount);
 485              echo maxMemUsage('end of textpattern()',1);
 486              if (!empty($txptrace) and is_array($txptrace))
 487                  echo n, comment('txp tag trace: '.n.join(n, $txptrace).n);
 488          }
 489  
 490          callback_event('textpattern_end');
 491      }
 492  
 493  // -------------------------------------------------------------
 494  	function output_css($s='',$n='')
 495      {
 496          if ($n) {
 497              $cssname = $n;
 498          } elseif ($s) {
 499              $cssname = safe_field('css','txp_section',"name='".doSlash($s)."'");
 500          }
 501  
 502          $css = safe_field('css','txp_css',"name='".doSlash($cssname)."'");
 503          if ($css) echo base64_decode($css);
 504      }
 505  
 506  //    article() is called when parse() finds a <txp:article /> tag.
 507  //    If an $id has been established, we output a single article,
 508  //    otherwise, output a list.
 509  
 510  // -------------------------------------------------------------
 511  	function article($atts)
 512      {
 513          global $is_article_body, $has_article_tag;
 514          if ($is_article_body) {
 515              trigger_error(gTxt('article_tag_illegal_body'));
 516              return '';
 517          }
 518          $has_article_tag = true;
 519          return parseArticles($atts);
 520      }
 521  
 522  // -------------------------------------------------------------
 523  	function doArticles($atts, $iscustom)
 524      {
 525          global $pretext, $prefs, $txpcfg;
 526          extract($pretext);
 527          extract($prefs);
 528          $customFields = getCustomFields();
 529          $customlAtts = array_null(array_flip($customFields));
 530  
 531          //getting attributes
 532          $theAtts = lAtts(array(
 533              'form'      => 'default',
 534              'listform'  => '',
 535              'searchform'=> '',
 536              'limit'     => 10,
 537              'pageby'    => '',
 538              'category'  => '',
 539              'section'   => '',
 540              'excerpted' => '',
 541              'author'    => '',
 542              'sort'      => '',
 543              'sortby'    => '',
 544              'sortdir'   => '',
 545              'month'     => '',
 546              'keywords'  => '',
 547              'frontpage' => '',
 548              'id'        => '',
 549              'time'      => 'past',
 550              'status'    => '4',
 551              'pgonly'    => 0,
 552              'searchall' => 1,
 553              'searchsticky' => 0,
 554              'allowoverride' => (!$q and !$iscustom),
 555              'offset'    => 0,
 556          )+$customlAtts,$atts);
 557  
 558          // if an article ID is specified, treat it as a custom list
 559          $iscustom = (!empty($theAtts['id'])) ? true : $iscustom;
 560  
 561          //for the txp:article tag, some attributes are taken from globals;
 562          //override them before extract
 563          if (!$iscustom)
 564          {
 565              $theAtts['category'] = ($c)? $c : '';
 566              $theAtts['section'] = ($s && $s!='default')? $s : '';
 567              $theAtts['author'] = (!empty($author)? $author: '');
 568              $theAtts['month'] = (!empty($month)? $month: '');
 569              $theAtts['frontpage'] = ($s && $s=='default')? true: false;
 570              $theAtts['excerpted'] = '';
 571          }
 572          extract($theAtts);
 573  
 574          $pageby = (empty($pageby) ? $limit : $pageby);
 575  
 576          // treat sticky articles differently wrt search filtering, etc
 577          if (!is_numeric($status))
 578              $status = getStatusNum($status);
 579          $issticky = ($status == 5);
 580  
 581          //give control to search, if necesary
 582          if($q && !$iscustom && !$issticky)
 583          {
 584              include_once txpath.'/publish/search.php';
 585  
 586              $s_filter = ($searchall ? filterSearch() : '');
 587              $q        = doSlash($q);
 588              $match    = ", match (Title,Body) against ('$q') as score";
 589              $search   = " and (Title rlike '$q' or Body rlike '$q') $s_filter";
 590  
 591              // searchall=0 can be used to show search results for the current section only
 592              if ($searchall) $section = '';
 593              if (!$sort) $sort='score desc';
 594          }
 595          else {
 596              $match = $search = '';
 597              if (!$sort) $sort='Posted desc';
 598          }
 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          //Building query parts
 618          $frontpage = ($frontpage and (!$q or $issticky)) ? filterFrontPage() : '';
 619          $category  = join("','", doSlash(do_list($category)));
 620          $category  = (!$category)  ? '' : " and (Category1 IN ('".$category."') or Category2 IN ('".$category."'))";
 621          $section   = (!$section)   ? '' : " and Section IN ('".join("','", doSlash(do_list($section)))."')";
 622          $excerpted = ($excerpted=='y')  ? " and Excerpt !=''" : '';
 623          $author    = (!$author)    ? '' : " and AuthorID IN ('".join("','", doSlash(do_list($author)))."')";
 624          $month     = (!$month)     ? '' : " and Posted like '".doSlash($month)."%'";
 625          $id        = (!$id)        ? '' : " and ID = '".intval($id)."'";
 626          switch ($time) {
 627              case 'any':
 628                  $time = ""; break;
 629              case 'future':
 630                  $time = " and Posted > now()"; break;
 631              default:
 632                  $time = " and Posted <= now()";
 633          }
 634  
 635          $custom = '';
 636  
 637          if ($customFields) {
 638              foreach($customFields as $cField) {
 639                  if (isset($atts[$cField]))
 640                      $customPairs[$cField] = $atts[$cField];
 641              }
 642              if(!empty($customPairs)) {
 643                  $custom = buildCustomSql($customFields,$customPairs);
 644              }
 645          }
 646  
 647          //Allow keywords for no-custom articles. That tagging mode, you know
 648          if ($keywords) {
 649              $keys = doSlash(do_list($keywords));
 650              foreach ($keys as $key) {
 651                  $keyparts[] = "FIND_IN_SET('".$key."',Keywords)";
 652              }
 653              $keywords = " and (" . join(' or ',$keyparts) . ")";
 654          }
 655  
 656          if ($q and $searchsticky)
 657              $statusq = ' and Status >= 4';
 658          elseif ($id)
 659              $statusq = ' and Status >= 4';
 660          else
 661              $statusq = ' and Status = '.intval($status);
 662  
 663          $where = "1=1" . $statusq. $time.
 664              $search . $id . $category . $section . $excerpted . $month . $author . $keywords . $custom . $frontpage;
 665  
 666          //do not paginate if we are on a custom list
 667          if (!$iscustom and !$issticky)
 668          {
 669              $grand_total = safe_count('textpattern',$where);
 670              $total = $grand_total - $offset;
 671              $numPages = ceil($total/$pageby);
 672              $pg = (!$pg) ? 1 : $pg;
 673              $pgoffset = $offset + (($pg - 1) * $pageby);
 674              // send paging info to txp:newer and txp:older
 675              $pageout['pg']       = $pg;
 676              $pageout['numPages'] = $numPages;
 677              $pageout['s']        = $s;
 678              $pageout['c']        = $c;
 679              $pageout['grand_total'] = $grand_total;
 680              $pageout['total']    = $total;
 681  
 682              global $thispage;
 683              if (empty($thispage))
 684                  $thispage = $pageout;
 685              if ($pgonly)
 686                  return;
 687          }else{
 688              $pgoffset = $offset;
 689          }
 690  
 691          $rs = safe_rows_start("*, unix_timestamp(Posted) as uPosted".$match, 'textpattern',
 692          $where.' order by '.doSlash($sort).' limit '.intval($pgoffset).', '.intval($limit));
 693          // get the form name
 694          if ($q and !$iscustom and !$issticky)
 695              $fname = ($searchform ? $searchform : 'search_results');
 696          else
 697              $fname = ($listform ? $listform : $form);
 698  
 699          if ($rs) {
 700              $count = 0;
 701  
 702              $articles = array();
 703              while($a = nextRow($rs)) {
 704                  ++$count;
 705                  populateArticleData($a);
 706                  global $thisarticle, $uPosted, $limit;
 707                  $thisarticle['is_first'] = ($count == 1);
 708                  $thisarticle['is_last'] = ($count == numRows($rs));
 709  
 710                  if (@constant('txpinterface') === 'admin' and gps('Form')) {
 711                      $articles[] = parse(gps('Form'));
 712                  }
 713                  elseif ($allowoverride and $a['override_form']) {
 714                      $articles[] = parse_form($a['override_form']);
 715                  }
 716                  else {
 717                      $articles[] = parse_form($fname);
 718                  }
 719  
 720                  // sending these to paging_link(); Required?
 721                  $uPosted = $a['uPosted'];
 722  
 723                  unset($GLOBALS['thisarticle']);
 724              }
 725  
 726              return join('',$articles);
 727          }
 728      }
 729  
 730  // -------------------------------------------------------------
 731  
 732  	function filterFrontPage()
 733      {
 734          static $filterFrontPage;
 735  
 736          if (isset($filterFrontPage)) {
 737              return $filterFrontPage;
 738          }
 739  
 740          $filterFrontPage = false;
 741  
 742          $rs = safe_column('name', 'txp_section', "on_frontpage != '1'");
 743  
 744          if ($rs) {
 745              $filters = array();
 746  
 747              foreach ($rs as $name) {
 748                  $filters[] = " and Section != '".doSlash($name)."'";
 749              }
 750  
 751              $filterFrontPage = join('', $filters);
 752          }
 753  
 754          return $filterFrontPage;
 755      }
 756  
 757  // -------------------------------------------------------------
 758  	function doArticle($atts)
 759      {
 760          global $pretext,$prefs, $thisarticle;
 761          extract($prefs);
 762          extract($pretext);
 763  
 764          extract(gpsa(array('parentid', 'preview')));
 765  
 766          extract(lAtts(array(
 767              'allowoverride' => '1',
 768              'form'          => 'default',
 769              'status'        => '4',
 770          ),$atts, 0));
 771  
 772          if ($status and !is_numeric($status))
 773          {
 774              $status = getStatusNum($status);
 775          }
 776  
 777          if (empty($thisarticle) or $thisarticle['thisid'] != $id)
 778          {
 779              $thisarticle = NULL;
 780  
 781              $q_status = ($status ? 'and Status = '.intval($status) : 'and Status in (4,5)');
 782  
 783              $rs = safe_row("*, unix_timestamp(Posted) as uPosted",
 784                      "textpattern", 'ID = '.intval($id)." $q_status limit 1");
 785  
 786              if ($rs) {
 787                  extract($rs);
 788                  populateArticleData($rs);
 789              }
 790          }
 791  
 792          if (!empty($thisarticle) and $thisarticle['status'] == $status)
 793          {
 794              extract($thisarticle);
 795              $thisarticle['is_first'] = 1;
 796              $thisarticle['is_last'] = 1;
 797  
 798              $form = ($allowoverride and $override_form) ? $override_form : $form;
 799  
 800              $article = parse_form($form);
 801  
 802              if ($use_comments and $comments_auto_append)
 803              {
 804                  $article .= parse_form('comments_display');
 805              }
 806  
 807              unset($GLOBALS['thisarticle']);
 808  
 809              return $article;
 810          }
 811      }
 812  
 813  // -------------------------------------------------------------
 814  	function article_custom($atts)
 815      {
 816          return parseArticles($atts, '1');
 817      }
 818  
 819  // -------------------------------------------------------------
 820  	function parseArticles($atts, $iscustom = '')
 821      {
 822          global $pretext, $is_article_list;
 823          $old_ial = $is_article_list;
 824          $is_article_list = ($pretext['id'] && !$iscustom)? false : true;
 825          article_push();
 826          $r = ($is_article_list)? doArticles($atts, $iscustom) : doArticle($atts);
 827          article_pop();
 828          $is_article_list = $old_ial;
 829  
 830          return $r;
 831      }
 832  
 833  // -------------------------------------------------------------
 834  // Keep all the article tag-related values in one place,
 835  // in order to do easy bugfix and easily the addition of
 836  // new article tags.
 837  	function populateArticleData($rs)
 838      {
 839          extract($rs);
 840  
 841          trace_add("[".gTxt('Article')." $ID]");
 842          $out['thisid']          = $ID;
 843          $out['posted']          = $uPosted;
 844          $out['modified']    = $LastMod;
 845          $out['annotate']        = $Annotate;
 846          $out['comments_invite'] = $AnnotateInvite;
 847          $out['authorid']        = $AuthorID;
 848          $out['title']           = $Title;
 849          $out['url_title']       = $url_title;
 850          $out['category1']       = $Category1;
 851          $out['category2']       = $Category2;
 852          $out['section']         = $Section;
 853          $out['keywords']        = $Keywords;
 854          $out['article_image']   = $Image;
 855          $out['comments_count']  = $comments_count;
 856          $out['body']            = $Body_html;
 857          $out['excerpt']         = $Excerpt_html;
 858          $out['override_form']   = $override_form;
 859          $out['status']          = $Status;
 860  
 861          $custom = getCustomFields();
 862          if ($custom) {
 863              foreach ($custom as $i => $name)
 864                  $out[$name] = $rs['custom_' . $i];
 865          }
 866  
 867          global $thisarticle;
 868          $thisarticle = $out;
 869      }
 870  
 871  // -------------------------------------------------------------
 872  	function getNeighbour($Posted, $s, $type)
 873      {
 874          $type = ($type == '>') ? '>' : '<';
 875          $safe_name = safe_pfx('textpattern');
 876          $q = array(
 877              "select ID, Title, url_title, unix_timestamp(Posted) as uposted
 878              from ".$safe_name." where Posted $type '".doSlash($Posted)."'",
 879              ($s!='' && $s!='default') ? "and Section = '".doSlash($s)."'" : filterFrontPage(),
 880              'and Status=4 and Posted < now() order by Posted',
 881              ($type=='<') ? 'desc' : 'asc',
 882              'limit 1'
 883          );
 884  
 885          $out = getRow(join(' ',$q));
 886          return (is_array($out)) ? $out : '';
 887      }
 888  
 889  // -------------------------------------------------------------
 890  	function getNextPrev($id, $Posted, $s)
 891      {
 892          static $next, $cache;
 893  
 894          if (@isset($cache[$next[$id]]))
 895              $thenext = $cache[$next[$id]];
 896          else
 897              $thenext            = getNeighbour($Posted,$s,'>');
 898  
 899          $out['next_id']     = ($thenext) ? $thenext['ID'] : '';
 900          $out['next_title']  = ($thenext) ? $thenext['Title'] : '';
 901          $out['next_utitle'] = ($thenext) ? $thenext['url_title'] : '';
 902          $out['next_posted'] = ($thenext) ? $thenext['uposted'] : '';
 903  
 904          $theprev            = getNeighbour($Posted,$s,'<');
 905          $out['prev_id']     = ($theprev) ? $theprev['ID'] : '';
 906          $out['prev_title']  = ($theprev) ? $theprev['Title'] : '';
 907          $out['prev_utitle'] = ($theprev) ? $theprev['url_title'] : '';
 908          $out['prev_posted'] = ($theprev) ? $theprev['uposted'] : '';
 909  
 910          if ($theprev) {
 911              $cache[$theprev['ID']] = $theprev;
 912              $next[$theprev['ID']] = $id;
 913          }
 914  
 915          return $out;
 916      }
 917  
 918  // -------------------------------------------------------------
 919  	function lastMod()
 920      {
 921          $last = safe_field("unix_timestamp(val)", "txp_prefs", "`name`='lastmod' and prefs_id=1");
 922          return gmdate("D, d M Y H:i:s \G\M\T",$last);
 923      }
 924  
 925  // -------------------------------------------------------------
 926  	function parse($text)
 927      {
 928          $f = '/<txp:(\S+)\b(.*)(?:(?<!br )(\/))?'.chr(62).'(?(3)|(.+)<\/txp:\1>)/sU';
 929          return preg_replace_callback($f, 'processTags', $text);
 930      }
 931  
 932  // -------------------------------------------------------------
 933  
 934  	function processTags($matches)
 935      {
 936          global $pretext, $production_status, $txptrace, $txptracelevel, $txp_current_tag;
 937  
 938          $tag = $matches[1];
 939  
 940          $trouble_makers = array(
 941              'link'
 942          );
 943  
 944          if (in_array($tag, $trouble_makers))
 945          {
 946              $tag = 'tpt_'.$tag;
 947          }
 948  
 949          $atts = isset($matches[2]) ? splat($matches[2]) : '';
 950          $thing = isset($matches[4]) ? $matches[4] : null;
 951  
 952          $old_tag = @$txp_current_tag;
 953  
 954          $txp_current_tag = '<txp:'.$tag.
 955              ($atts ? $matches[2] : '').
 956              ($thing ? '>' : '/>');
 957  
 958          trace_add($txp_current_tag);
 959          @++$txptracelevel;
 960  
 961          if ($production_status == 'debug')
 962          {
 963              maxMemUsage(trim($matches[0]));
 964          }
 965  
 966          $out = '';
 967  
 968          if (function_exists($tag))
 969          {
 970              $out = $tag($atts, $thing, $matches[0]);
 971          }
 972  
 973          // deprecated, remove in crockery
 974          elseif (isset($pretext[$tag]))
 975          {
 976              $out = htmlspecialchars($pretext[$tag]);
 977  
 978              trigger_error(gTxt('deprecated_tag'), E_USER_NOTICE);
 979          }
 980  
 981          else
 982          {
 983              trigger_error(gTxt('unknown_tag'), E_USER_WARNING);
 984          }
 985  
 986          @--$txptracelevel;
 987  
 988          if (isset($matches[4]))
 989          {
 990              trace_add('</txp:'.$tag.'>');
 991          }
 992  
 993          $txp_current_tag = $old_tag;
 994  
 995          return $out;
 996      }
 997  
 998  // -------------------------------------------------------------
 999  	function bombShelter() // protection from those who'd bomb the site by GET
1000      {
1001          global $prefs;
1002          $in = serverset('REQUEST_URI');
1003          if (!empty($prefs['max_url_len']) and strlen($in) > $prefs['max_url_len']) exit('Nice try.');
1004      }
1005  
1006  // -------------------------------------------------------------
1007  	function evalString($html)
1008      {
1009          global $prefs;
1010          if (strpos($html, chr(60).'?php') !== false) {
1011              trigger_error(gTxt('raw_php_deprecated'), E_USER_WARNING);
1012              if (!empty($prefs['allow_raw_php_scripting']))
1013                  $html = eval(' ?'.chr(62).$html.chr(60).'?php ');
1014              else
1015                  trigger_error(gTxt('raw_php_disabled'), E_USER_WARNING);
1016          }
1017          return $html;
1018      }
1019  
1020  // -------------------------------------------------------------
1021  	function getCustomFields()
1022      {
1023          global $prefs;
1024          $out = array();
1025          $i = 0;
1026          for ($i=1; $i<=10; $i++) {
1027              if (!empty($prefs['custom_'.$i.'_set'])) {
1028                  $out[$i] = strtolower($prefs['custom_'.$i.'_set']);
1029              }
1030          }
1031          return $out;
1032      }
1033  
1034  // -------------------------------------------------------------
1035  	function buildCustomSql($custom,$pairs)
1036      {
1037          if ($pairs) {
1038              $pairs = doSlash($pairs);
1039              foreach($pairs as $k => $v) {
1040                  if(in_array($k,$custom)) {
1041                      $no = array_keys($custom,$k);
1042                      # nb - use 'like' here to allow substring matches
1043                      $out[] = "and custom_".$no[0]." like '$v'";
1044                  }
1045              }
1046          }
1047          return (!empty($out)) ? ' '.join(' ',$out).' ' : false;
1048      }
1049  
1050  // -------------------------------------------------------------
1051  	function getStatusNum($name)
1052      {
1053          $labels = array('draft' => 1, 'hidden' => 2, 'pending' => 3, 'live' => 4, 'sticky' => 5);
1054          $status = strtolower($name);
1055          $num = empty($labels[$status]) ? 4 : $labels[$status];
1056          return $num;
1057      }
1058  
1059  // -------------------------------------------------------------
1060  	function ckEx($table,$val,$debug='')
1061      {
1062          return safe_field("name",'txp_'.$table,"`name` like '".doSlash($val)."' limit 1",$debug);
1063      }
1064  
1065  // -------------------------------------------------------------
1066  	function ckExID($val,$debug='')
1067      {
1068          return safe_row("ID,Section",'textpattern','ID = '.intval($val).' and Status >= 4 limit 1',$debug);
1069      }
1070  
1071  // -------------------------------------------------------------
1072  	function lookupByTitle($val,$debug='')
1073      {
1074          return safe_row("ID,Section",'textpattern',"url_title like '".doSlash($val)."' and Status >= 4 limit 1",$debug);
1075      }
1076  // -------------------------------------------------------------
1077  	function lookupByTitleSection($val,$section,$debug='')
1078      {
1079          return safe_row("ID,Section",'textpattern',"url_title like '".doSlash($val)."' AND Section='".doSlash($section)."' and Status >= 4 limit 1",$debug);
1080      }
1081  
1082  // -------------------------------------------------------------
1083  
1084  	function lookupByIDSection($id, $section, $debug = '')
1085      {
1086          return safe_row('ID, Section', 'textpattern',
1087              'ID = '.intval($id)." and Section = '".doSlash($section)."' and Status >= 4 limit 1", $debug);
1088      }
1089  
1090  // -------------------------------------------------------------
1091  	function lookupByID($id,$debug='')
1092      {
1093          return safe_row("ID,Section",'textpattern','ID = '.intval($id).' and Status >= 4 limit 1',$debug);
1094      }
1095  
1096  // -------------------------------------------------------------
1097  	function lookupByDateTitle($when,$title,$debug='')
1098      {
1099          return safe_row("ID,Section","textpattern",
1100          "posted like '".doSlash($when)."%' and url_title like '".doSlash($title)."' and Status >= 4 limit 1");
1101      }
1102  
1103  // -------------------------------------------------------------
1104  	function makeOut()
1105      {
1106          foreach(func_get_args() as $a) {
1107              $array[$a] = strval(gps($a));
1108          }
1109          return $array;
1110      }
1111  
1112  // -------------------------------------------------------------
1113  	function chopUrl($req)
1114      {
1115          $req = strtolower($req);
1116          //strip off query_string, if present
1117          $qs = strpos($req,'?');
1118          if ($qs) $req = substr($req, 0, $qs);
1119          $req = preg_replace('/index\.php$/', '', $req);
1120          $r = array_map('urldecode', explode('/',$req));
1121          $o['u0'] = (isset($r[0])) ? $r[0] : '';
1122          $o['u1'] = (isset($r[1])) ? $r[1] : '';
1123          $o['u2'] = (isset($r[2])) ? $r[2] : '';
1124          $o['u3'] = (isset($r[3])) ? $r[3] : '';
1125          $o['u4'] = (isset($r[4])) ? $r[4] : '';
1126  
1127          return $o;
1128      }
1129  
1130  ?>


Generated: Mon Feb 18 03:42:45 2008 Cross-referenced by PHPXref 0.7