includes/pageprocess.php
changeset 800 9cdfe82c56cd
parent 793 c0724bf6039b
child 801 eb8b23f11744
equal deleted inserted replaced
799:4629ad98ee88 800:9cdfe82c56cd
    17  * Class to handle fetching page text (possibly from a cache) and formatting it.
    17  * Class to handle fetching page text (possibly from a cache) and formatting it.
    18  * As of 1.0.4, this also handles the fetching and editing of certain data for pages.
    18  * As of 1.0.4, this also handles the fetching and editing of certain data for pages.
    19  * @package Enano
    19  * @package Enano
    20  * @subpackage UI
    20  * @subpackage UI
    21  * @copyright 2007 Dan Fuhry
    21  * @copyright 2007 Dan Fuhry
    22  * @license GNU General Public License <http://www.gnu.org/licenses/gpl.html>
    22  * @license GNU General Public License <http://www.gnu.org/licenses/gpl-2.0.html>
    23  */
    23  */
    24 
    24 
    25 class PageProcessor
    25 class PageProcessor
    26 {
    26 {
    27   
    27   
    32   
    32   
    33   var $page_id;
    33   var $page_id;
    34   var $namespace;
    34   var $namespace;
    35   
    35   
    36   /**
    36   /**
       
    37    * The instance of the namespace processor for the namespace we're doing.
       
    38    * @var object
       
    39    */
       
    40   
       
    41   var $ns;
       
    42   
       
    43   /**
    37    * The title of the page sent to the template parser
    44    * The title of the page sent to the template parser
    38    * @var string
    45    * @var string
    39    */
    46    */
    40   
    47   
    41   var $title = '';
    48   var $title = '';
   191         return false;
   198         return false;
   192       }
   199       }
   193     }
   200     }
   194     
   201     
   195     // Is there a custom function registered for handling this namespace?
   202     // Is there a custom function registered for handling this namespace?
       
   203     // DEPRECATED (even though it only saw its way into one alpha release.)
   196     if ( $proc = $paths->get_namespace_processor($this->namespace) )
   204     if ( $proc = $paths->get_namespace_processor($this->namespace) )
   197     {
   205     {
   198       // yes, just call that
   206       // yes, just call that
   199       // this is protected aggressively by the PathManager against overriding critical namespaces
   207       // this is protected aggressively by the PathManager against overriding critical namespaces
   200       return call_user_func($proc, $this);
   208       return call_user_func($proc, $this);
   224       }
   232       }
   225       if ( $paths->pages[$pathskey]['special'] == 1 )
   233       if ( $paths->pages[$pathskey]['special'] == 1 )
   226       {
   234       {
   227         $this->send_headers = false;
   235         $this->send_headers = false;
   228         $strict_no_headers = true;
   236         $strict_no_headers = true;
       
   237         $GLOBALS['output'] = new Output_Naked();
   229       }
   238       }
   230       if ( isset($paths->pages[$pathskey]['password']) )
   239       if ( isset($paths->pages[$pathskey]['password']) )
   231       {
   240       {
   232         if ( $paths->pages[$pathskey]['password'] != '' && $paths->pages[$pathskey]['password'] != sha1('') )
   241         if ( $paths->pages[$pathskey]['password'] != '' && $paths->pages[$pathskey]['password'] != sha1('') )
   233         {
   242         {
   269     if ( $this->page_exists && $this->namespace != 'Special' && $this->namespace != 'Admin' && $do_stats )
   278     if ( $this->page_exists && $this->namespace != 'Special' && $this->namespace != 'Admin' && $do_stats )
   270     {
   279     {
   271       require_once(ENANO_ROOT.'/includes/stats.php');
   280       require_once(ENANO_ROOT.'/includes/stats.php');
   272       doStats($this->page_id, $this->namespace);
   281       doStats($this->page_id, $this->namespace);
   273     }
   282     }
   274     if ( $this->namespace == 'Special' || $this->namespace == 'Admin' )
   283     
   275     {
   284     // We are all done. Ship off the page.
   276       if ( $this->send_headers )
   285     
   277       {
   286     if ( $this->send_headers )
   278         $template->init_vars($this);
   287     {
   279       }
   288       $template->init_vars($this);
   280       
   289     }
   281       $this->revision_time = time();
   290     
   282       
   291     $this->ns->send();
   283       if ( !$this->page_exists )
       
   284       {
       
   285         $func_name = "page_{$this->namespace}_{$this->page_id}";
       
   286         
       
   287         die_semicritical($lang->get('page_msg_admin_404_title'), $lang->get('page_msg_admin_404_body', array('func_name' => $func_name)), (!$this->send_headers));
       
   288       }
       
   289       $func_name = "page_{$this->namespace}_{$this->page_id}";
       
   290       if ( function_exists($func_name) )
       
   291       {
       
   292         $result = @call_user_func($func_name);
       
   293         return $result;
       
   294       }
       
   295       else
       
   296       {
       
   297         $title = $lang->get('page_err_custompage_function_missing_title');
       
   298         $message = $lang->get('page_err_custompage_function_missing_body', array( 'function_name' => $fname ));
       
   299                     
       
   300         if ( $this->send_headers )
       
   301         {
       
   302           $template->tpl_strings['PAGE_NAME'] = $title;
       
   303           $template->header();
       
   304           echo "<p>$message</p>";
       
   305           $template->footer();
       
   306         }
       
   307         else
       
   308         {
       
   309           echo "<h2>$title</h2>
       
   310                 <p>$message</p>";
       
   311         }
       
   312         return false;
       
   313       }
       
   314     }
       
   315     else if ( $this->namespace == 'User' && strpos($this->page_id, '/') === false )
       
   316     {
       
   317       if ( $this->send_headers )
       
   318       {
       
   319         $template->init_vars($this);
       
   320       }
       
   321       
       
   322       $this->_handle_userpage();
       
   323     }
       
   324     else if ( ( $this->namespace == 'Template' || $this->namespace == 'System' ) && $this->page_exists )
       
   325     {
       
   326       if ( $this->send_headers )
       
   327       {
       
   328         $template->init_vars($this);
       
   329       }
       
   330       
       
   331       $this->header();
       
   332       
       
   333       $text = $this->fetch_text();
       
   334       $text = preg_replace('/<noinclude>(.*?)<\/noinclude>/is', '\\1', $text);
       
   335       $text = preg_replace('/<nodisplay>(.*?)<\/nodisplay>/is', '', $text);
       
   336       
       
   337       $text = RenderMan::render( $text );
       
   338       
       
   339       eval( '?>' . $text );
       
   340       
       
   341       $this->footer();
       
   342     }
       
   343     else if ( $this->namespace == 'API' )
       
   344     {
       
   345       if ( $this->send_headers )
       
   346       {
       
   347         $template->init_vars($this);
       
   348       }
       
   349       
       
   350       $uri = scriptPath . '/' . $this->page_id;
       
   351       if ( !$this->send_headers )
       
   352       {
       
   353         $sep = ( strstr($uri, '?') ) ? '&' : '?';
       
   354         $uri .= "{$sep}noheaders";
       
   355       }
       
   356       redirect( $uri, '', '', 0 );
       
   357     }
       
   358     else if ( !$this->page_exists )
       
   359     {
       
   360       // Perhaps this is hooked?
       
   361       ob_start();
       
   362       
       
   363       $code = $plugins->setHook('page_not_found');
       
   364       foreach ( $code as $cmd )
       
   365       {
       
   366         eval($cmd);
       
   367       }
       
   368       
       
   369       $ob = ob_get_contents();
       
   370       
       
   371       if ( empty($ob) )
       
   372       {
       
   373         if ( $this->send_headers )
       
   374         {
       
   375           $template->init_vars($this);
       
   376         }
       
   377         $this->err_page_not_existent();
       
   378       }
       
   379       else
       
   380       {
       
   381         // Something sent content, so we'll assume the page exist...ed at least according to the plugin
       
   382         if ( $this->namespace != 'Special' && $this->namespace != 'Admin' && $do_stats )
       
   383         {
       
   384           require_once(ENANO_ROOT.'/includes/stats.php');
       
   385           doStats($this->page_id, $this->namespace);
       
   386         }
       
   387       }
       
   388     }
       
   389     else
       
   390     {
       
   391       $this->send_from_db($strict_no_headers);
       
   392     }
       
   393   }
   292   }
   394   
   293   
   395   /**
   294   /**
   396    * Sends the page through by fetching it from the database.
   295    * Sends the page through by fetching it from the database.
   397    */
   296    */
   448    * @return string
   347    * @return string
   449    */
   348    */
   450   
   349   
   451   function fetch_source()
   350   function fetch_source()
   452   {
   351   {
       
   352     global $db, $session, $paths, $template, $plugins; // Common objects
       
   353     
   453     if ( !$this->perms->get_permissions('view_source') )
   354     if ( !$this->perms->get_permissions('view_source') )
   454     {
   355     {
   455       return false;
   356       return false;
   456     }
   357     }
   457     if ( !$this->page_exists )
   358     if ( !$this->page_exists )
   458     {
   359     {
   459       return '';
   360       return '';
       
   361     }
       
   362     $pathskey = $paths->nslist[ $this->namespace ] . $this->page_id;
       
   363     if ( isset($paths->pages[$pathskey]) )
       
   364     {
       
   365       if ( isset($paths->pages[$pathskey]['password']) )
       
   366       {
       
   367         if ( $paths->pages[$pathskey]['password'] != sha1('') && $paths->pages[$pathskey]['password'] !== $this->password && !empty($paths->pages[$pathskey]['password']) )
       
   368         {
       
   369           return false;
       
   370         }
       
   371       }
   460     }
   372     }
   461     return $this->fetch_text();
   373     return $this->fetch_text();
   462   }
   374   }
   463   
   375   
   464   /**
   376   /**
  1011     $this->revision_id = $revision_id;
   923     $this->revision_id = $revision_id;
  1012     $this->page_id_unclean = dirtify_page_id($page_id);
   924     $this->page_id_unclean = dirtify_page_id($page_id);
  1013     
   925     
  1014     $this->perms = $session->fetch_page_acl( $page_id, $namespace );
   926     $this->perms = $session->fetch_page_acl( $page_id, $namespace );
  1015     
   927     
  1016     // Exception for Admin: pages
   928     // resolve namespace
  1017     if ( $this->namespace == 'Admin' )
   929     $this->ns = namespace_factory($this->page_id, $this->namespace, $this->revision_id);
  1018     {
   930     
  1019       $fname = "page_Admin_{$this->page_id}";
   931     $this->page_exists = $this->ns->exists();
  1020     }
       
  1021     
       
  1022     // Does the page "exist"?
       
  1023     $pathskey = $paths->nslist[$namespace] . $page_id_cleaned;
       
  1024     
       
  1025     if ( $paths->page_id == $page_id && $paths->namespace == $namespace && !$paths->page_exists && ( $this->namespace != 'Admin' || ($this->namespace == 'Admin' && !function_exists($fname) ) ) )
       
  1026     {
       
  1027       $this->page_exists = false;
       
  1028     }
       
  1029     else if ( !isset( $paths->pages[ $pathskey ] ) && ( ( $this->namespace == 'Admin' && !function_exists($fname) ) || ( $this->namespace != 'Admin' ) ) )
       
  1030     {
       
  1031       $this->page_exists = false;
       
  1032     }
       
  1033     else
       
  1034     {
       
  1035       $this->page_exists = true;
       
  1036     }
       
  1037     
       
  1038     // Compatibility with older databases
       
  1039     if ( strstr($this->page_id, '.2e') && !$this->page_exists )
       
  1040     {
       
  1041       $page_id = str_replace('.2e', '.', $page_id);
       
  1042       
       
  1043       if ( $paths->page_id == $page_id && $paths->namespace == $namespace && !$paths->page_exists && ( $this->namespace != 'Admin' || ($this->namespace == 'Admin' && !function_exists($fname) ) ) )
       
  1044       {
       
  1045         $this->page_exists = false;
       
  1046       }
       
  1047       else if ( !isset( $paths->pages[ $paths->nslist[$namespace] . $page_id ] ) && ( $this->namespace == 'Admin' && !function_exists($fname) ) )
       
  1048       {
       
  1049         $this->page_exists = false;
       
  1050       }
       
  1051       else
       
  1052       {
       
  1053         $this->page_exists = true;
       
  1054       }
       
  1055       
       
  1056     }
       
  1057     
       
  1058     $this->title = get_page_title_ns($this->page_id, $this->namespace);
   932     $this->title = get_page_title_ns($this->page_id, $this->namespace);
  1059     
   933     
  1060     profiler_log("PageProcessor [{$this->namespace}:{$this->page_id}]: Ran _setup()");
   934     profiler_log("PageProcessor [{$this->namespace}:{$this->page_id}]: Ran _setup()");
  1061   }
   935   }
  1062   
   936   
  1066    */
   940    */
  1067   
   941   
  1068   function render($incl_inner_headers = true, $_errormsg = false)
   942   function render($incl_inner_headers = true, $_errormsg = false)
  1069   {
   943   {
  1070     global $db, $session, $paths, $template, $plugins; // Common objects
   944     global $db, $session, $paths, $template, $plugins; // Common objects
  1071     global $lang;
   945     global $output, $lang;
  1072     
   946     
  1073     $text = $this->fetch_text();
   947     if ( count($this->redirect_stack) > 0 )
  1074     
   948     {
  1075     $text = preg_replace('/([\s]*)__NOBREADCRUMBS__([\s]*)/', '', $text);
   949       $stack = array_reverse($this->redirect_stack);
  1076     $text = preg_replace('/([\s]*)__NOTOC__([\s]*)/', '', $text);
   950       foreach ( $stack as $oldtarget )
  1077     
   951       {
  1078     $redir_enabled = false;
   952         $url = makeUrlNS($oldtarget[1], $oldtarget[0], 'redirect=no', true);
  1079     if ( preg_match('/^#redirect \[\[([^\]]+?)\]\]/i', $text, $match ) )
   953         $page_id_key = $paths->nslist[ $oldtarget[1] ] . $oldtarget[0];
  1080     {
   954         $page_data = $paths->pages[$page_id_key];
  1081       $redir_enabled = true;
   955         $title = ( isset($page_data['name']) ) ? $page_data['name'] : $paths->nslist[$oldtarget[1]] . htmlspecialchars( str_replace('_', ' ', dirtify_page_id( $oldtarget[0] ) ) );
  1082       
   956         $a = '<a href="' . $url . '">' . $title . '</a>';
  1083       $oldtarget = RenderMan::strToPageID($match[1]);
   957         $output->add_after_header('<small>' . $lang->get('page_msg_redirected_from', array('from' => $a)) . '<br /></small>');
  1084       $oldtarget[0] = sanitize_page_id($oldtarget[0]);
   958       }
  1085       
   959     }
  1086       $url = makeUrlNS($oldtarget[1], $oldtarget[0], false, true);
   960     $this->ns->send($incl_inner_headers, $_errormsg);
  1087       $page_id_key = $paths->nslist[ $oldtarget[1] ] . $oldtarget[0];
       
  1088       $page_data = $paths->pages[$page_id_key];
       
  1089       $title = ( isset($page_data['name']) ) ? $page_data['name'] : $paths->nslist[$oldtarget[1]] . htmlspecialchars( str_replace('_', ' ', dirtify_page_id( $oldtarget[0] ) ) );
       
  1090       if ( !isset($page_data['name']) )
       
  1091       {
       
  1092         $cls = 'class="wikilink-nonexistent"';
       
  1093       }
       
  1094       else
       
  1095       {
       
  1096         $cls = '';
       
  1097       }
       
  1098       $a = '<a ' . $cls . ' href="' . $url . '">' . $title . '</a>';
       
  1099       $redir_html = '<br /><div class="mdg-infobox">
       
  1100               <table border="0" width="100%" cellspacing="0" cellpadding="0">
       
  1101                 <tr>
       
  1102                   <td valign="top">
       
  1103                     <img alt="Cute wet-floor icon" src="'.scriptPath.'/images/redirector.png" />
       
  1104                   </td>
       
  1105                   <td valign="top" style="padding-left: 10px;">
       
  1106                     ' . $lang->get('page_msg_this_is_a_redirector', array( 'redirect_target' => $a )) . '
       
  1107                   </td>
       
  1108                 </tr>
       
  1109               </table>
       
  1110             </div>
       
  1111             <br />
       
  1112             <hr style="margin-left: 1em; width: 200px;" />';
       
  1113       $text = str_replace($match[0], '', $text);
       
  1114       $text = trim($text);
       
  1115     }
       
  1116     
       
  1117     $template->tpl_strings['PAGE_NAME'] = htmlspecialchars( $this->title );
       
  1118     
       
  1119     $this->header();
       
  1120     $this->do_breadcrumbs();
       
  1121     
       
  1122     if ( $_errormsg )
       
  1123     {
       
  1124       echo $_errormsg;
       
  1125     }
       
  1126     
       
  1127     if ( $incl_inner_headers )
       
  1128     {
       
  1129       if ( count($this->redirect_stack) > 0 )
       
  1130       {
       
  1131         $stack = array_reverse($this->redirect_stack);
       
  1132         foreach ( $stack as $oldtarget )
       
  1133         {
       
  1134           $url = makeUrlNS($oldtarget[1], $oldtarget[0], 'redirect=no', true);
       
  1135           $page_id_key = $paths->nslist[ $oldtarget[1] ] . $oldtarget[0];
       
  1136           $page_data = $paths->pages[$page_id_key];
       
  1137           $title = ( isset($page_data['name']) ) ? $page_data['name'] : $paths->nslist[$oldtarget[1]] . htmlspecialchars( str_replace('_', ' ', dirtify_page_id( $oldtarget[0] ) ) );
       
  1138           $a = '<a href="' . $url . '">' . $title . '</a>';
       
  1139           echo '<small>' . $lang->get('page_msg_redirected_from', array('from' => $a)) . '<br /></small>';
       
  1140         }
       
  1141       }
       
  1142       display_page_headers();
       
  1143     }
       
  1144     
       
  1145     if ( $this->revision_id )
       
  1146     {
       
  1147       echo '<div class="info-box" style="margin-left: 0; margin-top: 5px;">
       
  1148               <b>' . $lang->get('page_msg_archived_title') . '</b><br />
       
  1149               ' . $lang->get('page_msg_archived_body', array(
       
  1150                   'archive_date' => enano_date('F d, Y', $this->revision_time),
       
  1151                   'archive_time' => enano_date('h:i a', $this->revision_time),
       
  1152                   'current_link' => makeUrlNS($this->namespace, $this->page_id),
       
  1153                   'restore_link' => makeUrlNS($this->namespace, $this->page_id, 'do=edit&amp;revid='.$this->revision_id),
       
  1154                   'restore_onclick' => 'ajaxEditor(\''.$this->revision_id.'\'); return false;',
       
  1155                 )) . '
       
  1156             </div>';
       
  1157     }
       
  1158     
       
  1159     if ( $redir_enabled )
       
  1160     {
       
  1161       echo $redir_html;
       
  1162     }
       
  1163     
       
  1164     $code = $plugins->setHook('pageprocess_render_head');
       
  1165     foreach ( $code as $cmd )
       
  1166     {
       
  1167       eval($cmd);
       
  1168     }
       
  1169     
       
  1170     if ( $incl_inner_headers )
       
  1171     {
       
  1172       $text = '?>' . RenderMan::render($text);
       
  1173     }
       
  1174     else
       
  1175     {
       
  1176       $text = '?>' . $text;
       
  1177       $text = preg_replace('/<nowiki>(.*?)<\/nowiki>/s', '\\1', $text);
       
  1178     }
       
  1179     
       
  1180     eval ( $text );
       
  1181     
       
  1182     $code = $plugins->setHook('pageprocess_render_tail');
       
  1183     foreach ( $code as $cmd )
       
  1184     {
       
  1185       eval($cmd);
       
  1186     }
       
  1187     
       
  1188     if ( $incl_inner_headers )
       
  1189     {
       
  1190       display_page_footers();
       
  1191     }
       
  1192     
       
  1193     $this->footer();
       
  1194   }
   961   }
  1195   
   962   
  1196   /**
   963   /**
  1197    * Sends the page header, dependent on, of course, whether we're supposed to.
   964    * Sends the page header, dependent on, of course, whether we're supposed to.
  1198    */
   965    */
  1220    * @access public
   987    * @access public
  1221    */
   988    */
  1222   
   989   
  1223   function fetch_text()
   990   function fetch_text()
  1224   {
   991   {
  1225     global $db, $session, $paths, $template, $plugins; // Common objects
   992     return $this->ns->fetch_text();
  1226     
       
  1227     if ( !empty($this->text_cache) )
       
  1228     {
       
  1229       return $this->text_cache;
       
  1230     }
       
  1231     
       
  1232     if ( $this->revision_id > 0 && is_int($this->revision_id) )
       
  1233     {
       
  1234     
       
  1235       $q = $db->sql_query('SELECT page_text, char_tag, time_id FROM '.table_prefix.'logs WHERE log_type=\'page\' AND action=\'edit\' AND page_id=\'' . $this->page_id . '\' AND namespace=\'' . $this->namespace . '\' AND log_id=' . $this->revision_id . ';');
       
  1236       if ( !$q )
       
  1237       {
       
  1238         $this->send_error('Error during SQL query.', true);
       
  1239       }
       
  1240       if ( $db->numrows() < 1 )
       
  1241       {
       
  1242         // Compatibility fix for old pages with dots in the page ID
       
  1243         if ( strstr($this->page_id, '.2e') )
       
  1244         {
       
  1245           $db->free_result();
       
  1246           $page_id = str_replace('.2e', '.', $this->page_id);
       
  1247           $q = $db->sql_query('SELECT page_text, char_tag, time_id FROM '.table_prefix.'logs WHERE log_type=\'page\' AND action=\'edit\' AND page_id=\'' . $page_id . '\' AND namespace=\'' . $this->namespace . '\' AND log_id=' . $this->revision_id . ';');
       
  1248           if ( !$q )
       
  1249           {
       
  1250             $this->send_error('Error during SQL query.', true);
       
  1251           }
       
  1252           if ( $db->numrows() < 1 )
       
  1253           {
       
  1254             $this->page_exists = false;
       
  1255             return 'err_no_text_rows';
       
  1256           }
       
  1257         }
       
  1258         else
       
  1259         {
       
  1260           $this->page_exists = false;
       
  1261           return 'err_no_text_rows';
       
  1262         }
       
  1263       }
       
  1264       else
       
  1265       {
       
  1266         $row = $db->fetchrow();
       
  1267       }
       
  1268       
       
  1269       $db->free_result();
       
  1270       
       
  1271     }
       
  1272     else
       
  1273     {
       
  1274       $q = $db->sql_query('SELECT t.page_text, t.char_tag, l.time_id FROM '.table_prefix."page_text AS t\n"
       
  1275                         . "  LEFT JOIN " . table_prefix . "logs AS l\n"
       
  1276                         . "    ON ( l.page_id = t.page_id AND l.namespace = t.namespace )\n"
       
  1277                         . "  WHERE t.page_id='$this->page_id' AND t.namespace='$this->namespace'\n"
       
  1278                         . "  ORDER BY l.time_id DESC LIMIT 1;");
       
  1279       if ( !$q )
       
  1280       {
       
  1281         $this->send_error('Error during SQL query.', true);
       
  1282       }
       
  1283       if ( $db->numrows() < 1 )
       
  1284       {
       
  1285         // Compatibility fix for old pages with dots in the page ID
       
  1286         if ( strstr($this->page_id, '.2e') )
       
  1287         {
       
  1288           $db->free_result();
       
  1289           $page_id = str_replace('.2e', '.', $this->page_id);
       
  1290           $q = $db->sql_query('SELECT page_text, char_tag FROM '.table_prefix.'page_text WHERE page_id=\'' . $page_id . '\' AND namespace=\'' . $this->namespace . '\';');
       
  1291           if ( !$q )
       
  1292           {
       
  1293             $this->send_error('Error during SQL query.', true);
       
  1294           }
       
  1295           if ( $db->numrows() < 1 )
       
  1296           {
       
  1297             $this->page_exists = false;
       
  1298             return 'err_no_text_rows';
       
  1299           }
       
  1300         }
       
  1301         else
       
  1302         {
       
  1303           $this->page_exists = false;
       
  1304           return 'err_no_text_rows';
       
  1305         }
       
  1306       }
       
  1307       
       
  1308       $row = $db->fetchrow();
       
  1309       $db->free_result();
       
  1310       
       
  1311     }
       
  1312     
       
  1313     if ( !empty($row['char_tag']) )
       
  1314     {
       
  1315       // This page text entry uses the old text-escaping format
       
  1316       $from = array(
       
  1317           "{APOS:{$row['char_tag']}}",
       
  1318           "{QUOT:{$row['char_tag']}}",
       
  1319           "{SLASH:{$row['char_tag']}}"
       
  1320         );
       
  1321       $to = array("'", '"',  '\\');
       
  1322       $row['page_text'] = str_replace($from, $to, $row['page_text']);
       
  1323     }
       
  1324     
       
  1325     $this->text_cache = $row['page_text'];
       
  1326     
       
  1327     if ( isset($row['time_id']) )
       
  1328     {
       
  1329       $this->revision_time = intval($row['time_id']);
       
  1330     }
       
  1331     
       
  1332     return $row['page_text'];
       
  1333     
       
  1334   }
       
  1335   
       
  1336   /**
       
  1337    * Handles the extra overhead required for user pages.
       
  1338    * @access private
       
  1339    */
       
  1340    
       
  1341   function _handle_userpage()
       
  1342   {
       
  1343     global $db, $session, $paths, $template, $plugins; // Common objects
       
  1344     global $email;
       
  1345     global $lang;
       
  1346     
       
  1347     /**
       
  1348      * PLUGGING INTO USER PAGES
       
  1349      * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
       
  1350      * Userpages are highly programmable and extendable using a number of
       
  1351      * hooks. These hooks are:
       
  1352      *
       
  1353      *   - userpage_sidebar_left
       
  1354      *   - userpage_sidebar_right
       
  1355      *   - userpage_tabs_links
       
  1356      *   - userpage_tabs_body
       
  1357      *
       
  1358      * You can add a variety of sections to user pages, including new tabs
       
  1359      * and new sections on the tables. To add a tab, attach to
       
  1360      * userpage_tabs_links and echo out:
       
  1361      *
       
  1362      *   <li><a href="#tab:YOURTABID">YOUR TAB TEXT</a></li>
       
  1363      *
       
  1364      * Then hook into userpage_tabs_body and echo out:
       
  1365      *
       
  1366      *   <div id="tab:YOURTABID">YOUR TAB CONTENT</div>
       
  1367      *
       
  1368      * The userpage javascript runtime will take care of everything else,
       
  1369      * meaning transitions, click events, etc. Currently it's not possible
       
  1370      * to add custom click events to tabs, but any DOM-related JS that needs
       
  1371      * to run in your tab can be run onload and the effects will be seen when
       
  1372      * your tab is clicked. YOURTABID should be lowercase alphanumeric and
       
  1373      * have a short prefix so as to assure that it remains specific to your
       
  1374      * plugin.
       
  1375      *
       
  1376      * To hook into the "profile" tab, use userpage_sidebar_{left,right}. Just
       
  1377      * echo out table cells as normal. The table on the left (the wide one) has
       
  1378      * four columns, and the one on the right has one column.
       
  1379      * 
       
  1380      * See plugins.php for a guide on creating and attaching to hooks.
       
  1381      */
       
  1382     
       
  1383     $page_urlname = dirtify_page_id($this->page_id);
       
  1384     if ( $this->page_id == $paths->page_id && $this->namespace == $paths->namespace )
       
  1385     {
       
  1386       $page_name = ( isset($paths->cpage['name']) ) ? $paths->cpage['name'] : $this->page_id;
       
  1387     }
       
  1388     else
       
  1389     {
       
  1390       $page_name = ( isset($paths->pages[$this->page_id]) ) ? $paths->pages[$this->page_id]['name'] : $this->page_id;
       
  1391     }
       
  1392     
       
  1393     $target_username = strtr($page_urlname, 
       
  1394       Array(
       
  1395         '_' => ' ',
       
  1396         '<' => '&lt;',
       
  1397         '>' => '&gt;'
       
  1398         ));
       
  1399     
       
  1400     $target_username = preg_replace('/^' . str_replace('/', '\\/', preg_quote($paths->nslist['User'])) . '/', '', $target_username);
       
  1401     list($target_username) = explode('/', $target_username);
       
  1402     
       
  1403     if ( ( $page_name == str_replace('_', ' ', $this->page_id) || $page_name == $paths->nslist['User'] . str_replace('_', ' ', $this->page_id) ) || !$this->page_exists )
       
  1404     {
       
  1405       $page_name = $lang->get('userpage_page_title', array('username' => $target_username));
       
  1406     }
       
  1407     else
       
  1408     {
       
  1409       // User has a custom title for their userpage
       
  1410       $page_name = $paths->pages[ $paths->nslist[$this->namespace] . $this->page_id ]['name'];
       
  1411     }
       
  1412     
       
  1413     $template->tpl_strings['PAGE_NAME'] = htmlspecialchars($page_name);
       
  1414     
       
  1415     $q = $db->sql_query('SELECT u.username, u.user_id AS authoritative_uid, u.real_name, u.email, u.reg_time, u.user_has_avatar, u.avatar_type, x.*, COUNT(c.comment_id) AS n_comments
       
  1416                            FROM '.table_prefix.'users u
       
  1417                            LEFT JOIN '.table_prefix.'users_extra AS x
       
  1418                              ON ( u.user_id = x.user_id OR x.user_id IS NULL ) 
       
  1419                            LEFT JOIN '.table_prefix.'comments AS c
       
  1420                              ON ( ( c.user_id=u.user_id AND c.name=u.username AND c.approved=1 ) OR ( c.comment_id IS NULL AND c.approved IS NULL ) )
       
  1421                            WHERE u.username=\'' . $db->escape($target_username) . '\'
       
  1422                            GROUP BY u.username, u.user_id, u.real_name, u.email, u.reg_time, u.user_has_avatar, u.avatar_type, x.user_id, x.user_aim, x.user_yahoo, x.user_msn, x.user_xmpp, x.user_homepage, x.user_location, x.user_job, x.user_hobbies, x.email_public;');
       
  1423     if ( !$q )
       
  1424       $db->_die();
       
  1425     
       
  1426     $user_exists = true;
       
  1427     
       
  1428     if ( $db->numrows() < 1 )
       
  1429     {
       
  1430       $user_exists = false;
       
  1431     }
       
  1432     else
       
  1433     {
       
  1434       $userdata = $db->fetchrow();
       
  1435       if ( $userdata['authoritative_uid'] == 1 )
       
  1436       {
       
  1437         // Hide data for anonymous user
       
  1438         $user_exists = false;
       
  1439         unset($userdata);
       
  1440       }
       
  1441     }
       
  1442     
       
  1443     // get the user's rank
       
  1444     if ( $user_exists )
       
  1445     {
       
  1446       $rank_data = $session->get_user_rank(intval($userdata['authoritative_uid']));
       
  1447     }
       
  1448     else
       
  1449     {
       
  1450       // get the rank data for the anonymous user (placeholder basically)
       
  1451       $rank_data = $session->get_user_rank(1);
       
  1452     }
       
  1453     
       
  1454     // add the userpage script to the header
       
  1455     $template->add_header('<script type="text/javascript" src="' . cdnPath . '/includes/clientside/static/userpage.js"></script>');
       
  1456     
       
  1457     $this->header();
       
  1458     
       
  1459     // if ( $send_headers )
       
  1460     // {
       
  1461     //  display_page_headers();
       
  1462     // }
       
  1463    
       
  1464     //
       
  1465     // BASIC INFORMATION
       
  1466     // Presentation of username/rank/avatar/basic info
       
  1467     //
       
  1468     
       
  1469     if ( $user_exists )
       
  1470     {
       
  1471     
       
  1472       ?>
       
  1473       <div id="userpage_wrap">
       
  1474         <ul id="userpage_links">
       
  1475           <li><a href="#tab:profile"><?php echo $lang->get('userpage_tab_profile'); ?></a></li>
       
  1476           <li><a href="#tab:content"><?php echo $lang->get('userpage_tab_content'); ?></a></li>
       
  1477           <?php
       
  1478           $code = $plugins->setHook('userpage_tabs_links');
       
  1479           foreach ( $code as $cmd )
       
  1480           {
       
  1481             eval($cmd);
       
  1482           }
       
  1483           ?>
       
  1484         </ul>
       
  1485         
       
  1486         <div id="tab:profile">
       
  1487       
       
  1488       <?php
       
  1489       
       
  1490       echo '<table border="0" cellspacing="0" cellpadding="0">
       
  1491               <tr>';
       
  1492                 
       
  1493       echo '    <td valign="top">';
       
  1494       
       
  1495       echo '<div class="tblholder">
       
  1496               <table border="0" cellspacing="1" cellpadding="4">';
       
  1497               
       
  1498       // heading
       
  1499       echo '    <tr>
       
  1500                   <th colspan="' . ( $session->user_level >= USER_LEVEL_ADMIN ? '3' : '4' ) . '">
       
  1501                     ' . $lang->get('userpage_heading_basics', array('username' => htmlspecialchars($target_username))) . '
       
  1502                   </th>
       
  1503                   ' . (
       
  1504                     $session->user_level >= USER_LEVEL_ADMIN ?
       
  1505                     '<th class="subhead" style="width: 25%;"><a href="' . makeUrlNS('Special', 'Administration', 'module=' . $paths->nslist['Admin'] . 'UserManager&src=get&user=' . urlencode($target_username), true) . '" onclick="ajaxAdminUser(\'' . addslashes($target_username) . '\'); return false;">&raquo; ' . $lang->get('userpage_btn_administer_user') . '</a></th>'
       
  1506                       : ''
       
  1507                   ) . '
       
  1508                 </tr>';
       
  1509                 
       
  1510       // avi/rank/username
       
  1511       echo '    <tr>
       
  1512                   <td class="row3" colspan="4">
       
  1513                     ' . (
       
  1514                         $userdata['user_has_avatar'] == 1 ?
       
  1515                         '<div style="float: left; margin-right: 10px;">
       
  1516                           <img alt="' . $lang->get('usercp_avatar_image_alt', array('username' => $userdata['username'])) . '" src="' . make_avatar_url(intval($userdata['authoritative_uid']), $userdata['avatar_type'], $userdata['email']) . '" />
       
  1517                          </div>'
       
  1518                         : ''
       
  1519                       ) . '
       
  1520                       <span style="font-size: x-large; ' . $rank_data['rank_style'] . '">' . htmlspecialchars($userdata['username']) . '</span>
       
  1521                       ' . ( !empty($rank_data['user_title']) ? '<br />' . htmlspecialchars($rank_data['user_title']) : '' ) . '
       
  1522                       ' . ( !empty($rank_data['rank_title']) ? '<br />' . htmlspecialchars($lang->get($rank_data['rank_title'])) : '' ) . '
       
  1523                   </td>
       
  1524                 </tr>';
       
  1525                 
       
  1526       // join date & total comments
       
  1527       echo '<tr>';
       
  1528       echo '  <td class="row2" style="text-align: right; width: 25%;">
       
  1529                 ' . $lang->get('userpage_lbl_joined') . '
       
  1530               </td>
       
  1531               <td class="row1" style="text-align: left; width: 25%;">
       
  1532                 ' . enano_date('F d, Y h:i a', $userdata['reg_time']) . '
       
  1533               </td>';
       
  1534       echo '  <td class="row2" style="text-align: right; width: 25%;">
       
  1535                 ' . $lang->get('userpage_lbl_num_comments') . '
       
  1536               </td>
       
  1537               <td class="row1" style="text-align: left; width: 25%;">
       
  1538                 ' . $userdata['n_comments'] . '
       
  1539               </td>';
       
  1540       echo '</tr>';
       
  1541       
       
  1542       // real name
       
  1543       if ( !empty($userdata['real_name']) )
       
  1544       {
       
  1545         echo '<tr>
       
  1546                 <td class="row2" style="text-align: right;">
       
  1547                   ' . $lang->get('userpage_lbl_real_name') . '
       
  1548                 </td>
       
  1549                 <td class="row1" colspan="3" style="text-align: left;">
       
  1550                   ' . htmlspecialchars($userdata['real_name']) . '
       
  1551                 </td>
       
  1552               </tr>';
       
  1553       }
       
  1554                 
       
  1555       // latest comments
       
  1556       
       
  1557       echo '<tr><th class="subhead" colspan="4">' . $lang->get('userpage_heading_comments', array('username' => htmlspecialchars($target_username))) . '</th></tr>';
       
  1558       $q = $db->sql_query('SELECT page_id, namespace, subject, time FROM '.table_prefix.'comments WHERE name=\'' . $db->escape($target_username) . '\' AND user_id=' . $userdata['authoritative_uid'] . ' AND approved=1 ORDER BY time DESC LIMIT 7;');
       
  1559       if ( !$q )
       
  1560         $db->_die();
       
  1561       
       
  1562       $comments = Array();
       
  1563       $no_comments = false;
       
  1564       
       
  1565       if ( $row = $db->fetchrow() )
       
  1566       {
       
  1567         do 
       
  1568         {
       
  1569           $row['time'] = enano_date('F d, Y', $row['time']);
       
  1570           $comments[] = $row;
       
  1571         }
       
  1572         while ( $row = $db->fetchrow() );
       
  1573       }
       
  1574       else
       
  1575       {
       
  1576         $no_comments = true;
       
  1577       }
       
  1578       
       
  1579       echo '<tr><td class="row3" colspan="4">';
       
  1580       echo '<div style="border: 1px solid #000000; padding: 0px; width: 100%; clip: rect(0px,auto,auto,0px); overflow: auto; background-color: transparent;" class="tblholder">';
       
  1581       
       
  1582       echo '<table border="0" cellspacing="1" cellpadding="4" style="width: 200%;"><tr>';
       
  1583       $class = 'row1';
       
  1584       
       
  1585       $tpl = '  <td class="{CLASS}">
       
  1586                   <a href="{PAGE_LINK}" <!-- BEGINNOT page_exists -->class="wikilink-nonexistent"<!-- END page_exists -->>{PAGE}</a><br />
       
  1587                   <small>{lang:userpage_comments_lbl_posted} {DATE}<br /></small>
       
  1588                   <b><a href="{COMMENT_LINK}">{SUBJECT}</a></b>
       
  1589                 </td>';
       
  1590       $parser = $template->makeParserText($tpl);
       
  1591       
       
  1592       if ( count($comments) > 0 )
       
  1593       {
       
  1594         foreach ( $comments as $comment )
       
  1595         {
       
  1596           $c_page_id = $paths->nslist[ $comment['namespace'] ] . sanitize_page_id($comment['page_id']);
       
  1597           if ( isset($paths->pages[ $c_page_id ]) )
       
  1598           {
       
  1599             $parser->assign_bool(array(
       
  1600               'page_exists' => true
       
  1601               ));
       
  1602             $page_title = htmlspecialchars($paths->pages[ $c_page_id ]['name']);
       
  1603           }
       
  1604           else
       
  1605           {
       
  1606             $parser->assign_bool(array(
       
  1607               'page_exists' => false
       
  1608               ));
       
  1609             $page_title = htmlspecialchars(dirtify_page_id($c_page_id));
       
  1610           }
       
  1611           $parser->assign_vars(array(
       
  1612               'CLASS' => $class,
       
  1613               'PAGE_LINK' => makeUrlNS($comment['namespace'], sanitize_page_id($comment['page_id'])),
       
  1614               'PAGE' => $page_title,
       
  1615               'SUBJECT' => $comment['subject'],
       
  1616               'DATE' => $comment['time'],
       
  1617               'COMMENT_LINK' => makeUrlNS($comment['namespace'], sanitize_page_id($comment['page_id']), 'do=comments', true)
       
  1618             ));
       
  1619           $class = ( $class == 'row3' ) ? 'row1' : 'row3';
       
  1620           echo $parser->run();
       
  1621         }
       
  1622       }
       
  1623       else
       
  1624       {
       
  1625         echo '<td class="' . $class . '">' . $lang->get('userpage_msg_no_comments') . '</td>';
       
  1626       }
       
  1627       echo '</tr></table>';
       
  1628       
       
  1629       echo '</div>';
       
  1630       echo '</td></tr>';
       
  1631       
       
  1632       $code = $plugins->setHook('userpage_sidebar_left');
       
  1633       foreach ( $code as $cmd )
       
  1634       {
       
  1635         eval($cmd);
       
  1636       }
       
  1637               
       
  1638       echo '  </table>
       
  1639             </div>';
       
  1640             
       
  1641       echo '</td>';
       
  1642       
       
  1643       //
       
  1644       // CONTACT INFORMATION
       
  1645       //
       
  1646       
       
  1647       echo '    <td valign="top" style="width: 150px; padding-left: 10px;">';
       
  1648       
       
  1649       echo '<div class="tblholder">
       
  1650               <table border="0" cellspacing="1" cellpadding="4">';
       
  1651       
       
  1652       //
       
  1653       // Main part of sidebar
       
  1654       //
       
  1655       
       
  1656       // Contact information
       
  1657       
       
  1658       echo '<tr><th class="subhead">' . $lang->get('userpage_heading_contact') . '</th></tr>';
       
  1659       
       
  1660       $class = 'row3';
       
  1661       
       
  1662       if ( $userdata['email_public'] == 1 )
       
  1663       {
       
  1664         $class = ( $class == 'row1' ) ? 'row3' : 'row1';
       
  1665         $email_link = $email->encryptEmail($userdata['email']);
       
  1666         echo '<tr><td class="'.$class.'">' . $lang->get('userpage_lbl_email') . ' ' . $email_link . '</td></tr>';
       
  1667       }
       
  1668       
       
  1669       $class = ( $class == 'row1' ) ? 'row3' : 'row1';
       
  1670       if ( $session->user_logged_in )
       
  1671       {
       
  1672         echo '<tr><td class="'.$class.'">' . $lang->get('userpage_btn_send_pm', array('username' => htmlspecialchars($target_username), 'pm_link' => makeUrlNS('Special', 'PrivateMessages/Compose/to/' . $this->page_id, false, true))) . '</td></tr>';
       
  1673       }
       
  1674       else
       
  1675       {
       
  1676         echo '<tr><td class="'.$class.'">' . $lang->get('userpage_btn_send_pm_guest', array('username' => htmlspecialchars($target_username), 'login_flags' => 'href="' . makeUrlNS('Special', 'Login/' . $paths->nslist[$this->namespace] . $this->page_id) . '" onclick="ajaxStartLogin(); return false;"')) . '</td></tr>';
       
  1677       }
       
  1678       
       
  1679       if ( !empty($userdata['user_aim']) )
       
  1680       {
       
  1681         $class = ( $class == 'row1' ) ? 'row3' : 'row1';
       
  1682         echo '<tr><td class="'.$class.'">' . $lang->get('userpage_lbl_aim') . ' ' . $userdata['user_aim'] . '</td></tr>';
       
  1683       }
       
  1684       
       
  1685       if ( !empty($userdata['user_yahoo']) )
       
  1686       {
       
  1687         $class = ( $class == 'row1' ) ? 'row3' : 'row1';
       
  1688         echo '<tr><td class="'.$class.'">' . $lang->get('userpage_lbl_yim') . ' ' . $userdata['user_yahoo'] . '</td></tr>';
       
  1689       }
       
  1690       
       
  1691       if ( !empty($userdata['user_msn']) )
       
  1692       {
       
  1693         $class = ( $class == 'row1' ) ? 'row3' : 'row1';
       
  1694         $email_link = $email->encryptEmail($userdata['user_msn']);
       
  1695         echo '<tr><td class="'.$class.'">' . $lang->get('userpage_lbl_wlm') . ' ' . $email_link . '</td></tr>';
       
  1696       }
       
  1697       
       
  1698       if ( !empty($userdata['user_xmpp']) )
       
  1699       {
       
  1700         $class = ( $class == 'row1' ) ? 'row3' : 'row1';
       
  1701         $email_link = $email->encryptEmail($userdata['user_xmpp']);
       
  1702         echo '<tr><td class="'.$class.'">' . $lang->get('userpage_lbl_xmpp') . ' ' . $email_link . '</td></tr>';
       
  1703       }
       
  1704       
       
  1705       // Real life
       
  1706       
       
  1707       echo '<tr><th class="subhead">' . $lang->get('userpage_heading_real_life', array('username' => htmlspecialchars($target_username))) . '</th></tr>';
       
  1708       
       
  1709       if ( !empty($userdata['user_location']) )
       
  1710       {
       
  1711         $class = ( $class == 'row1' ) ? 'row3' : 'row1';
       
  1712         echo '<tr><td class="'.$class.'">' . $lang->get('userpage_lbl_location') . ' ' . $userdata['user_location'] . '</td></tr>';
       
  1713       }
       
  1714       
       
  1715       if ( !empty($userdata['user_job']) )
       
  1716       {
       
  1717         $class = ( $class == 'row1' ) ? 'row3' : 'row1';
       
  1718         echo '<tr><td class="'.$class.'">' . $lang->get('userpage_lbl_job') . ' ' . $userdata['user_job'] . '</td></tr>';
       
  1719       }
       
  1720       
       
  1721       if ( !empty($userdata['user_hobbies']) )
       
  1722       {
       
  1723         $class = ( $class == 'row1' ) ? 'row3' : 'row1';
       
  1724         echo '<tr><td class="'.$class.'">' . $lang->get('userpage_lbl_hobbies') . ' ' . $userdata['user_hobbies'] . '</td></tr>';
       
  1725       }
       
  1726       
       
  1727       if ( empty($userdata['user_location']) && empty($userdata['user_job']) && empty($userdata['user_hobbies']) )
       
  1728       {
       
  1729         $class = ( $class == 'row1' ) ? 'row3' : 'row1';
       
  1730         echo '<tr><td class="'.$class.'">' . $lang->get('userpage_msg_no_contact_info', array('username' => htmlspecialchars($target_username))) . '</td></tr>';
       
  1731       }
       
  1732       
       
  1733       $code = $plugins->setHook('userpage_sidebar_right');
       
  1734       foreach ( $code as $cmd )
       
  1735       {
       
  1736         eval($cmd);
       
  1737       }
       
  1738       
       
  1739       echo '  </table>
       
  1740             </div>';
       
  1741       echo '</td>';
       
  1742       
       
  1743       //
       
  1744       // End of profile
       
  1745       //
       
  1746       
       
  1747       echo '</tr></table>';
       
  1748       
       
  1749       echo '</div>'; // tab:profile
       
  1750     
       
  1751     }
       
  1752     
       
  1753     // User's own content
       
  1754     
       
  1755     $send_headers = $this->send_headers;
       
  1756     $this->send_headers = false;
       
  1757     
       
  1758     echo '<span class="menuclear"></span>';
       
  1759     
       
  1760     echo '<div id="tab:content">';
       
  1761     
       
  1762     if ( $this->page_exists )
       
  1763     {
       
  1764       $this->render();
       
  1765     }
       
  1766     else
       
  1767     {
       
  1768       $this->err_page_not_existent(true);
       
  1769     }
       
  1770     
       
  1771     echo '</div>'; // tab:content
       
  1772     
       
  1773     $code = $plugins->setHook('userpage_tabs_body');
       
  1774     foreach ( $code as $cmd )
       
  1775     {
       
  1776       eval($cmd);
       
  1777     }
       
  1778     
       
  1779     if ( $user_exists )
       
  1780     {
       
  1781       echo '</div>'; // userpage_wrap
       
  1782     }
       
  1783     else
       
  1784     {
       
  1785       if ( !is_valid_ip($target_username) )
       
  1786       {
       
  1787         echo '<p>' . $lang->get('userpage_msg_user_not_exist', array('username' => htmlspecialchars($target_username))) . '</p>';
       
  1788       }
       
  1789     }
       
  1790     
       
  1791     // if ( $send_headers )
       
  1792     // {
       
  1793     //  display_page_footers();
       
  1794     // }
       
  1795     
       
  1796     $this->send_headers = $send_headers;
       
  1797     unset($send_headers);
       
  1798     
       
  1799     $this->footer();
       
  1800     
       
  1801   }
   993   }
  1802   
   994   
  1803   /**
   995   /**
  1804    * Pushes to the redirect stack and resets the instance. This depends on the page ID and namespace already being validated and sanitized, and does not check the size of the redirect stack.
   996    * Pushes to the redirect stack and resets the instance. This depends on the page ID and namespace already being validated and sanitized, and does not check the size of the redirect stack.
  1805    * @param string Page ID to redirect to
   997    * @param string Page ID to redirect to
  1908   function err_wrong_password()
  1100   function err_wrong_password()
  1909   {
  1101   {
  1910     global $db, $session, $paths, $template, $plugins; // Common objects
  1102     global $db, $session, $paths, $template, $plugins; // Common objects
  1911     global $lang;
  1103     global $lang;
  1912     
  1104     
  1913     $title = 'Password required';
  1105     $title = $lang->get('page_msg_passrequired_title');
  1914     $message = ( empty($this->password) ) ?
  1106     $message = ( empty($this->password) ) ?
  1915                  '<p>' . $lang->get('page_msg_passrequired') . '</p>' :
  1107                  '<p>' . $lang->get('page_msg_passrequired') . '</p>' :
  1916                  '<p>' . $lang->get('page_msg_pass_wrong') . '</p>';
  1108                  '<p>' . $lang->get('page_msg_pass_wrong') . '</p>';
  1917     $message .= '<form action="' . makeUrlNS($this->namespace, $this->page_id) . '" method="post">
  1109     $message .= '<form action="' . makeUrlNS($this->namespace, $this->page_id) . '" method="post">
  1918                    <p>
  1110                    <p>
  1919                      <label>' . $lang->get('page_lbl_password') . ' <input name="pagepass" type="password" /></label>&nbsp;&nbsp;<input type="submit" value="Submit" />
  1111                      <label>' . $lang->get('page_lbl_password') . ' <input name="pagepass" type="password" /></label>&nbsp;&nbsp;<input type="submit" value="' . $lang->get('page_btn_password_submit') . '" />
  1920                    </p>
  1112                    </p>
  1921                  </form>';
  1113                  </form>';
  1922     if ( $this->send_headers )
  1114     if ( $this->send_headers )
  1923     {
  1115     {
  1924       $template->tpl_strings['PAGE_NAME'] = $title;
  1116       $template->tpl_strings['PAGE_NAME'] = $title;
  1957             <p>$message</p>";
  1149             <p>$message</p>";
  1958     }
  1150     }
  1959   }
  1151   }
  1960   
  1152   
  1961   /**
  1153   /**
  1962    * Tell the user the page doesn't exist, and present them with their options.
       
  1963    * @access private
       
  1964    */
       
  1965    
       
  1966   function err_page_not_existent($userpage = false)
       
  1967   {
       
  1968     global $db, $session, $paths, $template, $plugins; // Common objects
       
  1969     global $lang;
       
  1970     
       
  1971     @header('HTTP/1.1 404 Not Found');
       
  1972     
       
  1973     $this->header();
       
  1974     $this->do_breadcrumbs();
       
  1975     
       
  1976     $msg = ( $pp = $paths->sysmsg('Page_not_found') ) ? $pp : '{STANDARD404}';
       
  1977     
       
  1978     $standard_404 = '';
       
  1979     
       
  1980     if ( $userpage )
       
  1981     {
       
  1982       $standard_404 .= '<h3>' . $lang->get('page_msg_404_title_userpage') . '</h3>
       
  1983              <p>' . $lang->get('page_msg_404_body_userpage');
       
  1984     }
       
  1985     else
       
  1986     {
       
  1987       $standard_404 .= '<h3>' . $lang->get('page_msg_404_title') . '</h3>
       
  1988              <p>' . $lang->get('page_msg_404_body');
       
  1989     }
       
  1990     if ( $session->get_permissions('create_page') )
       
  1991     {
       
  1992       $standard_404 .= ' ' . $lang->get('page_msg_404_create', array(
       
  1993           'create_flags' => 'href="'.makeUrlNS($this->namespace, $this->page_id, 'do=edit', true).'" onclick="ajaxEditor(); return false;"',
       
  1994           'mainpage_link' => makeUrl(get_main_page(), false, true)
       
  1995         ));
       
  1996     }
       
  1997     else
       
  1998     {
       
  1999       $standard_404 .= ' ' . $lang->get('page_msg_404_gohome', array(
       
  2000           'mainpage_link' => makeUrl(get_main_page(), false, true)
       
  2001         ));
       
  2002     }
       
  2003     $standard_404 .= '</p>';
       
  2004     if ( $session->get_permissions('history_rollback') )
       
  2005     {
       
  2006       $e = $db->sql_query('SELECT * FROM ' . table_prefix . 'logs WHERE action=\'delete\' AND page_id=\'' . $this->page_id . '\' AND namespace=\'' . $this->namespace . '\' ORDER BY time_id DESC;');
       
  2007       if ( !$e )
       
  2008       {
       
  2009         $db->_die('The deletion log could not be selected.');
       
  2010       }
       
  2011       if ( $db->numrows() > 0 )
       
  2012       {
       
  2013         $r = $db->fetchrow();
       
  2014         $standard_404 .= '<p>' . $lang->get('page_msg_404_was_deleted', array(
       
  2015                   'delete_time' => enano_date('d M Y h:i a', $r['time_id']),
       
  2016                   'delete_reason' => htmlspecialchars($r['edit_summary']),
       
  2017                   'rollback_flags' => 'href="'.makeUrl($paths->page, 'do=rollback&amp;id='.$r['log_id']).'" onclick="ajaxRollback(\''.$r['log_id'].'\'); return false;"'
       
  2018                 ))
       
  2019               . '</p>';
       
  2020         if ( $session->user_level >= USER_LEVEL_ADMIN )
       
  2021         {
       
  2022           $standard_404 .= '<p>' . $lang->get('page_msg_404_admin_opts', array(
       
  2023                     'detag_link' => makeUrl($paths->page, 'do=detag', true)
       
  2024                   ))
       
  2025                 . '</p>';
       
  2026         }
       
  2027       }
       
  2028       $db->free_result();
       
  2029     }
       
  2030     $standard_404 .= '<p>
       
  2031             ' . $lang->get('page_msg_404_http_response') . '
       
  2032           </p>';
       
  2033           
       
  2034     $parser = $template->makeParserText($msg);
       
  2035     $parser->assign_vars(array(
       
  2036         'STANDARD404' => $standard_404
       
  2037       ));
       
  2038     
       
  2039     $msg = RenderMan::render($parser->run());
       
  2040     eval( '?>' . $msg );
       
  2041     
       
  2042     $this->footer();
       
  2043   }
       
  2044   
       
  2045   /**
       
  2046    * Echoes out breadcrumb data, if appropriate.
       
  2047    * @access private
       
  2048    */
       
  2049   
       
  2050   function do_breadcrumbs()
       
  2051   {
       
  2052     global $db, $session, $paths, $template, $plugins; // Common objects
       
  2053     global $lang;
       
  2054     
       
  2055     if ( strpos($this->text_cache, '__NOBREADCRUMBS__') !== false )
       
  2056       return false;
       
  2057     
       
  2058     $mode = getConfig('breadcrumb_mode');
       
  2059     
       
  2060     if ( $mode == 'never' )
       
  2061       // Breadcrumbs are disabled
       
  2062       return true;
       
  2063       
       
  2064     // Minimum depth for breadcrumb display
       
  2065     $threshold = ( $mode == 'always' ) ? 0 : 1;
       
  2066     
       
  2067     $breadcrumb_data = explode('/', $this->page_id);
       
  2068     if ( count($breadcrumb_data) > $threshold )
       
  2069     {
       
  2070       // If we're not on a subpage of the main page, add "Home" to the list
       
  2071       $show_home = false;
       
  2072       if ( $mode == 'always' )
       
  2073       {
       
  2074         $show_home = true;
       
  2075       }
       
  2076       echo '<!-- Start breadcrumbs -->
       
  2077             <div class="breadcrumbs">
       
  2078               ';
       
  2079       if ( $show_home )
       
  2080       {
       
  2081         // Display the "home" link first.
       
  2082         $pathskey = $paths->nslist[ $this->namespace ] . $this->page_id;
       
  2083         if ( $pathskey !== get_main_page() )
       
  2084           echo '<a href="' . makeUrl(get_main_page(), false, true) . '">';
       
  2085         echo $lang->get('onpage_btn_breadcrumbs_home');
       
  2086         if ( $pathskey !== get_main_page() )
       
  2087           echo '</a>';
       
  2088       }
       
  2089       foreach ( $breadcrumb_data as $i => $crumb )
       
  2090       {
       
  2091         $cumulative = implode('/', array_slice($breadcrumb_data, 0, ( $i + 1 )));
       
  2092         if ( $show_home && $cumulative === get_main_page() )
       
  2093           continue;
       
  2094         if ( $show_home || $i > 0 )
       
  2095           echo ' &raquo; ';
       
  2096         $title = ( isPage($cumulative) ) ? get_page_title($cumulative) : get_page_title($crumb);
       
  2097         if ( $i + 1 == count($breadcrumb_data) )
       
  2098         {
       
  2099           echo htmlspecialchars($title);
       
  2100         }
       
  2101         else
       
  2102         {
       
  2103           $exists = ( isPage($cumulative) ) ? '' : ' class="wikilink-nonexistent"';
       
  2104           echo '<a href="' . makeUrl($cumulative, false, true) . '"' . $exists . '>' . htmlspecialchars($title) . '</a>';
       
  2105         }
       
  2106       }
       
  2107       echo '</div>
       
  2108             <!-- End breadcrumbs -->
       
  2109             ';
       
  2110     }
       
  2111   }
       
  2112   
       
  2113   /**
       
  2114    * Send an error message and die. For debugging or critical technical errors only - nothing that would under normal circumstances be shown to the user.
  1154    * Send an error message and die. For debugging or critical technical errors only - nothing that would under normal circumstances be shown to the user.
  2115    * @param string Error message
  1155    * @param string Error message
  2116    * @param bool If true, send DBAL's debugging information as well
  1156    * @param bool If true, send DBAL's debugging information as well
  2117    */
  1157    */
  2118    
  1158