includes/namespaces/default.php
changeset 1227 bdac73ed481e
parent 1173 b5b8e7ab0914
child 1252 e34c23a35dc9
equal deleted inserted replaced
1226:de56132c008d 1227:bdac73ed481e
    19  * @license GNU General Public License <http://www.gnu.org/licenses/gpl-2.0.html>
    19  * @license GNU General Public License <http://www.gnu.org/licenses/gpl-2.0.html>
    20  */
    20  */
    21 
    21 
    22 class Namespace_Default
    22 class Namespace_Default
    23 {
    23 {
    24   /**
    24 	/**
    25    * Page ID
    25  	* Page ID
    26    * @var string
    26  	* @var string
    27    */
    27  	*/
    28   
    28 	
    29   public $page_id;
    29 	public $page_id;
    30   
    30 	
    31   /**
    31 	/**
    32    * Namespace
    32  	* Namespace
    33    * @var string
    33  	* @var string
    34    */
    34  	*/
    35   
    35 	
    36   public $namespace;
    36 	public $namespace;
    37   
    37 	
    38   /**
    38 	/**
    39    * Local copy of the page text
    39  	* Local copy of the page text
    40    */
    40  	*/
    41   
    41 	
    42   public $text_cache;
    42 	public $text_cache;
    43   
    43 	
    44   /**
    44 	/**
    45    * Revision ID to send. If 0, the latest revision.
    45  	* Revision ID to send. If 0, the latest revision.
    46    * @var int
    46  	* @var int
    47    */
    47  	*/
    48   
    48 	
    49   public $revision_id = 0;
    49 	public $revision_id = 0;
    50   
    50 	
    51   /**
    51 	/**
    52    * Tracks whether the page exists
    52  	* Tracks whether the page exists
    53    * @var bool
    53  	* @var bool
    54    */
    54  	*/
    55   
    55 	
    56   public $exists = false;
    56 	public $exists = false;
    57   
    57 	
    58   /**
    58 	/**
    59    * Page title
    59  	* Page title
    60    * @var string
    60  	* @var string
    61    */
    61  	*/
    62   
    62 	
    63   public $title = '';
    63 	public $title = '';
    64   
    64 	
    65   /**
    65 	/**
    66    * PathManager info array ("cdata") for this page. (The one with urlname, name, namespace, delvotes, delvote_ips, protected, visible, etc.)
    66  	* PathManager info array ("cdata") for this page. (The one with urlname, name, namespace, delvotes, delvote_ips, protected, visible, etc.)
    67    * @var array
    67  	* @var array
    68    */
    68  	*/
    69   
    69 	
    70   public $cdata = array();
    70 	public $cdata = array();
    71   
    71 	
    72   /**
    72 	/**
    73    * ACL calculation instance for this page.
    73  	* ACL calculation instance for this page.
    74    * @var object(Session_ACLPageInfo)
    74  	* @var object(Session_ACLPageInfo)
    75    */
    75  	*/
    76   
    76 	
    77   public $perms = false;
    77 	public $perms = false;
    78   
    78 	
    79   /**
    79 	/**
    80    * Protection calculation
    80  	* Protection calculation
    81    * @var bool
    81  	* @var bool
    82    */
    82  	*/
    83   
    83 	
    84   public $page_protected = false;
    84 	public $page_protected = false;
    85   
    85 	
    86   /**
    86 	/**
    87    * Wiki mode calculation
    87  	* Wiki mode calculation
    88    * @var bool
    88  	* @var bool
    89    */
    89  	*/
    90   
    90 	
    91   public $wiki_mode = false;
    91 	public $wiki_mode = false;
    92   
    92 	
    93   /**
    93 	/**
    94    * Page conditions. These represent the final decision as to whether an action is allowed or not. They are set to true if ACLs permit AND if
    94  	* Page conditions. These represent the final decision as to whether an action is allowed or not. They are set to true if ACLs permit AND if
    95    * the action "makes sense." (e.g., you can't vote to delete a non-wikimode page.)
    95  	* the action "makes sense." (e.g., you can't vote to delete a non-wikimode page.)
    96    * @var array
    96  	* @var array
    97    */
    97  	*/
    98   
    98 	
    99   public $conds = array();
    99 	public $conds = array();
   100   
   100 	
   101   /**
   101 	/**
   102    * Constructor.
   102  	* Constructor.
   103    */
   103  	*/
   104   
   104 	
   105   public function __construct($page_id, $namespace, $revision_id = 0)
   105 	public function __construct($page_id, $namespace, $revision_id = 0)
   106   {
   106 	{
   107     global $db, $session, $paths, $template, $plugins; // Common objects
   107 		global $db, $session, $paths, $template, $plugins; // Common objects
   108     
   108 		
   109     $this->page_id = sanitize_page_id($page_id);
   109 		$this->page_id = sanitize_page_id($page_id);
   110     $this->namespace = $namespace;
   110 		$this->namespace = $namespace;
   111     $this->revision_id = intval($revision_id);
   111 		$this->revision_id = intval($revision_id);
   112     
   112 		
   113     // grab the cdata
   113 		// grab the cdata
   114     $this->build_cdata();
   114 		$this->build_cdata();
   115     
   115 		
   116     $this->page_protected = $this->cdata['really_protected'] ? true : false;
   116 		$this->page_protected = $this->cdata['really_protected'] ? true : false;
   117     switch($this->cdata['wiki_mode'])
   117 		switch($this->cdata['wiki_mode'])
   118     {
   118 		{
   119       case 0: $this->wiki_mode = false; break;
   119 			case 0: $this->wiki_mode = false; break;
   120       case 1: $this->wiki_mode = true; break;
   120 			case 1: $this->wiki_mode = true; break;
   121       default: case 2: $this->wiki_mode = getConfig('wiki_mode') == 1; break;
   121 			default: case 2: $this->wiki_mode = getConfig('wiki_mode') == 1; break;
   122     }
   122 		}
   123   }
   123 	}
   124   
   124 	
   125   /**
   125 	/**
   126    * Build the page's cdata.
   126  	* Build the page's cdata.
   127    */
   127  	*/
   128   
   128 	
   129   public function build_cdata()
   129 	public function build_cdata()
   130   {
   130 	{
   131     global $db, $session, $paths, $template, $plugins; // Common objects
   131 		global $db, $session, $paths, $template, $plugins; // Common objects
   132     static $cdata_cache = array();
   132 		static $cdata_cache = array();
   133     $pathskey = $paths->get_pathskey($this->page_id, $this->namespace);
   133 		$pathskey = $paths->get_pathskey($this->page_id, $this->namespace);
   134     if ( isset($cdata_cache[$pathskey]) )
   134 		if ( isset($cdata_cache[$pathskey]) )
   135     {
   135 		{
   136       $this->cdata = $cdata_cache[$pathskey];
   136 			$this->cdata = $cdata_cache[$pathskey];
   137       $this->exists = $cdata_cache[$pathskey]['page_exists'];
   137 			$this->exists = $cdata_cache[$pathskey]['page_exists'];
   138       $this->title = $cdata_cache[$pathskey]['name'];
   138 			$this->title = $cdata_cache[$pathskey]['name'];
   139       return null;
   139 			return null;
   140     }
   140 		}
   141     
   141 		
   142     $this->exists = false;
   142 		$this->exists = false;
   143     $ns_char = substr($paths->nslist['Special'], -1);
   143 		$ns_char = substr($paths->nslist['Special'], -1);
   144     $page_name = $this->namespace == 'Article' ? dirtify_page_id($this->page_id) : "{$this->namespace}{$ns_char}" . dirtify_page_id($this->page_id);
   144 		$page_name = $this->namespace == 'Article' ? dirtify_page_id($this->page_id) : "{$this->namespace}{$ns_char}" . dirtify_page_id($this->page_id);
   145     $page_name = str_replace('_', ' ', $page_name);
   145 		$page_name = str_replace('_', ' ', $page_name);
   146     $this->title = $page_name;
   146 		$this->title = $page_name;
   147     
   147 		
   148     $this->cdata = array(
   148 		$this->cdata = array(
   149       'name' => $page_name,
   149 			'name' => $page_name,
   150       'urlname' => $this->page_id,
   150 			'urlname' => $this->page_id,
   151       'namespace' => $this->namespace,
   151 			'namespace' => $this->namespace,
   152       'special' => 0,
   152 			'special' => 0,
   153       'visible' => 0,
   153 			'visible' => 0,
   154       'comments_on' => 1,
   154 			'comments_on' => 1,
   155       'protected' => 0,
   155 			'protected' => 0,
   156       'delvotes' => 0,
   156 			'delvotes' => 0,
   157       'delvote_ips' => '',
   157 			'delvote_ips' => '',
   158       'wiki_mode' => 2,
   158 			'wiki_mode' => 2,
   159       'page_exists' => false,
   159 			'page_exists' => false,
   160       'page_format' => getConfig('default_page_format', 'wikitext')
   160 			'page_format' => getConfig('default_page_format', 'wikitext')
   161     );
   161 		);
   162     
   162 		
   163     if ( $data_from_db = Namespace_Default::get_cdata_from_db($this->page_id, $this->namespace) )
   163 		if ( $data_from_db = Namespace_Default::get_cdata_from_db($this->page_id, $this->namespace) )
   164     {
   164 		{
   165       $this->exists = true;
   165 			$this->exists = true;
   166       $this->cdata = $data_from_db;
   166 			$this->cdata = $data_from_db;
   167       $this->cdata['page_exists'] = true;
   167 			$this->cdata['page_exists'] = true;
   168       $this->title = $this->cdata['name'];
   168 			$this->title = $this->cdata['name'];
   169     }
   169 		}
   170         
   170 				
   171     $this->cdata = Namespace_Default::bake_cdata($this->cdata);
   171 		$this->cdata = Namespace_Default::bake_cdata($this->cdata);
   172     
   172 		
   173     $cdata_cache[$pathskey] = $this->cdata;
   173 		$cdata_cache[$pathskey] = $this->cdata;
   174   }
   174 	}
   175   
   175 	
   176   /**
   176 	/**
   177    * Pulls the page's actual text from the database.
   177  	* Pulls the page's actual text from the database.
   178    */
   178  	*/
   179   
   179 	
   180   function fetch_text()
   180 	function fetch_text()
   181   {
   181 	{
   182     global $db, $session, $paths, $template, $plugins; // Common objects
   182 		global $db, $session, $paths, $template, $plugins; // Common objects
   183     
   183 		
   184     if ( !empty($this->text_cache) )
   184 		if ( !empty($this->text_cache) )
   185     {
   185 		{
   186       return $this->text_cache;
   186 			return $this->text_cache;
   187     }
   187 		}
   188     
   188 		
   189     if ( $this->revision_id > 0 && is_int($this->revision_id) )
   189 		if ( $this->revision_id > 0 && is_int($this->revision_id) )
   190     {
   190 		{
   191     
   191 		
   192       $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 . ';');
   192 			$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 . ';');
   193       if ( !$q )
   193 			if ( !$q )
   194       {
   194 			{
   195         $this->send_error('Error during SQL query.', true);
   195 				$this->send_error('Error during SQL query.', true);
   196       }
   196 			}
   197       if ( $db->numrows() < 1 )
   197 			if ( $db->numrows() < 1 )
   198       {
   198 			{
   199         // Compatibility fix for old pages with dots in the page ID
   199 				// Compatibility fix for old pages with dots in the page ID
   200         if ( strstr($this->page_id, '.2e') )
   200 				if ( strstr($this->page_id, '.2e') )
   201         {
   201 				{
   202           $db->free_result();
   202 					$db->free_result();
   203           $page_id = str_replace('.2e', '.', $this->page_id);
   203 					$page_id = str_replace('.2e', '.', $this->page_id);
   204           $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 . ';');
   204 					$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 . ';');
   205           if ( !$q )
   205 					if ( !$q )
   206           {
   206 					{
   207             $this->send_error('Error during SQL query.', true);
   207 						$this->send_error('Error during SQL query.', true);
   208           }
   208 					}
   209           if ( $db->numrows() < 1 )
   209 					if ( $db->numrows() < 1 )
   210           {
   210 					{
   211             $this->page_exists = false;
   211 						$this->page_exists = false;
   212             return 'err_no_text_rows';
   212 						return 'err_no_text_rows';
   213           }
   213 					}
   214         }
   214 				}
   215         else
   215 				else
   216         {
   216 				{
   217           $this->page_exists = false;
   217 					$this->page_exists = false;
   218           return 'err_no_text_rows';
   218 					return 'err_no_text_rows';
   219         }
   219 				}
   220       }
   220 			}
   221       else
   221 			else
   222       {
   222 			{
   223         $row = $db->fetchrow();
   223 				$row = $db->fetchrow();
   224       }
   224 			}
   225       
   225 			
   226       $db->free_result();
   226 			$db->free_result();
   227       
   227 			
   228     }
   228 		}
   229     else
   229 		else
   230     {
   230 		{
   231       $q = $db->sql_query('SELECT t.page_text, t.char_tag, l.time_id FROM '.table_prefix."page_text AS t\n"
   231 			$q = $db->sql_query('SELECT t.page_text, t.char_tag, l.time_id FROM '.table_prefix."page_text AS t\n"
   232                         . "  LEFT JOIN " . table_prefix . "logs AS l\n"
   232 												. "  LEFT JOIN " . table_prefix . "logs AS l\n"
   233                         . "    ON ( l.page_id = t.page_id AND l.namespace = t.namespace )\n"
   233 												. "    ON ( l.page_id = t.page_id AND l.namespace = t.namespace )\n"
   234                         . "  WHERE t.page_id='$this->page_id' AND t.namespace='$this->namespace'\n"
   234 												. "  WHERE t.page_id='$this->page_id' AND t.namespace='$this->namespace'\n"
   235                         . "  ORDER BY l.time_id DESC LIMIT 1;");
   235 												. "  ORDER BY l.time_id DESC LIMIT 1;");
   236       if ( !$q )
   236 			if ( !$q )
   237       {
   237 			{
   238         $this->send_error('Error during SQL query.', true);
   238 				$this->send_error('Error during SQL query.', true);
   239       }
   239 			}
   240       if ( $db->numrows() < 1 )
   240 			if ( $db->numrows() < 1 )
   241       {
   241 			{
   242         // Compatibility fix for old pages with dots in the page ID
   242 				// Compatibility fix for old pages with dots in the page ID
   243         if ( strstr($this->page_id, '.2e') )
   243 				if ( strstr($this->page_id, '.2e') )
   244         {
   244 				{
   245           $db->free_result();
   245 					$db->free_result();
   246           $page_id = str_replace('.2e', '.', $this->page_id);
   246 					$page_id = str_replace('.2e', '.', $this->page_id);
   247           $q = $db->sql_query('SELECT page_text, char_tag FROM '.table_prefix.'page_text WHERE page_id=\'' . $page_id . '\' AND namespace=\'' . $this->namespace . '\';');
   247 					$q = $db->sql_query('SELECT page_text, char_tag FROM '.table_prefix.'page_text WHERE page_id=\'' . $page_id . '\' AND namespace=\'' . $this->namespace . '\';');
   248           if ( !$q )
   248 					if ( !$q )
   249           {
   249 					{
   250             $this->send_error('Error during SQL query.', true);
   250 						$this->send_error('Error during SQL query.', true);
   251           }
   251 					}
   252           if ( $db->numrows() < 1 )
   252 					if ( $db->numrows() < 1 )
   253           {
   253 					{
   254             $this->page_exists = false;
   254 						$this->page_exists = false;
   255             return 'err_no_text_rows';
   255 						return 'err_no_text_rows';
   256           }
   256 					}
   257         }
   257 				}
   258         else
   258 				else
   259         {
   259 				{
   260           $this->page_exists = false;
   260 					$this->page_exists = false;
   261           return 'err_no_text_rows';
   261 					return 'err_no_text_rows';
   262         }
   262 				}
   263       }
   263 			}
   264       
   264 			
   265       $row = $db->fetchrow();
   265 			$row = $db->fetchrow();
   266       $db->free_result();
   266 			$db->free_result();
   267       
   267 			
   268     }
   268 		}
   269     
   269 		
   270     if ( !empty($row['char_tag']) )
   270 		if ( !empty($row['char_tag']) )
   271     {
   271 		{
   272       // This page text entry uses the old text-escaping format
   272 			// This page text entry uses the old text-escaping format
   273       $from = array(
   273 			$from = array(
   274           "{APOS:{$row['char_tag']}}",
   274 					"{APOS:{$row['char_tag']}}",
   275           "{QUOT:{$row['char_tag']}}",
   275 					"{QUOT:{$row['char_tag']}}",
   276           "{SLASH:{$row['char_tag']}}"
   276 					"{SLASH:{$row['char_tag']}}"
   277         );
   277 				);
   278       $to = array("'", '"',  '\\');
   278 			$to = array("'", '"',  '\\');
   279       $row['page_text'] = str_replace($from, $to, $row['page_text']);
   279 			$row['page_text'] = str_replace($from, $to, $row['page_text']);
   280     }
   280 		}
   281     
   281 		
   282     $this->text_cache = $row['page_text'];
   282 		$this->text_cache = $row['page_text'];
   283     
   283 		
   284     if ( isset($row['time_id']) )
   284 		if ( isset($row['time_id']) )
   285     {
   285 		{
   286       $this->revision_time = intval($row['time_id']);
   286 			$this->revision_time = intval($row['time_id']);
   287     }
   287 		}
   288     
   288 		
   289     return $row['page_text'];
   289 		return $row['page_text'];
   290   }
   290 	}
   291   
   291 	
   292   /**
   292 	/**
   293    * Send the page.
   293  	* Send the page.
   294    */
   294  	*/
   295   
   295 	
   296   public function send()
   296 	public function send()
   297   {
   297 	{
   298     global $db, $session, $paths, $template, $plugins; // Common objects
   298 		global $db, $session, $paths, $template, $plugins; // Common objects
   299     global $output;
   299 		global $output;
   300     
   300 		
   301     $output->add_before_footer($this->display_categories());
   301 		$output->add_before_footer($this->display_categories());
   302     
   302 		
   303     if ( $this->exists )
   303 		if ( $this->exists )
   304       $this->send_from_db();
   304 			$this->send_from_db();
   305     else
   305 		else
   306     {
   306 		{
   307       // This is the DEPRECATED way to extend namespaces. It's left in only for compatibility with older plugins.
   307 			// This is the DEPRECATED way to extend namespaces. It's left in only for compatibility with older plugins.
   308       ob_start();
   308 			ob_start();
   309       $code = $plugins->setHook('page_not_found');
   309 			$code = $plugins->setHook('page_not_found');
   310       foreach ( $code as $cmd )
   310 			foreach ( $code as $cmd )
   311       {
   311 			{
   312         eval($cmd);
   312 				eval($cmd);
   313       }
   313 			}
   314       $c = ob_get_contents();
   314 			$c = ob_get_contents();
   315       if ( !empty($c) )
   315 			if ( !empty($c) )
   316       {
   316 			{
   317         ob_end_clean();
   317 				ob_end_clean();
   318         echo $c;
   318 				echo $c;
   319       }
   319 			}
   320       else
   320 			else
   321       {
   321 			{
   322         $output->header();
   322 				$output->header();
   323         $this->error_404();
   323 				$this->error_404();
   324         $output->footer();
   324 				$output->footer();
   325       }
   325 			}
   326     }
   326 		}
   327   }
   327 	}
   328   
   328 	
   329   /**
   329 	/**
   330    * Get a redirect, if there is one.
   330  	* Get a redirect, if there is one.
   331    * @return mixed Array: Page ID and namespace, associative; bool: false (no redirect)
   331  	* @return mixed Array: Page ID and namespace, associative; bool: false (no redirect)
   332    */
   332  	*/
   333   
   333 	
   334   public function get_redirect()
   334 	public function get_redirect()
   335   {
   335 	{
   336     $text = $this->fetch_text();
   336 		$text = $this->fetch_text();
   337     if ( preg_match('/^#redirect \[\[([^\]]+?)\]\]/i', $text, $match ) )
   337 		if ( preg_match('/^#redirect \[\[([^\]]+?)\]\]/i', $text, $match ) )
   338     {
   338 		{
   339       list($page_id, $namespace) = RenderMan::strToPageID($match[1]);
   339 			list($page_id, $namespace) = RenderMan::strToPageID($match[1]);
   340       return array(
   340 			return array(
   341           'page_id' => $page_id,
   341 					'page_id' => $page_id,
   342           'namespace' => $namespace
   342 					'namespace' => $namespace
   343         );
   343 				);
   344     }
   344 		}
   345     return false;
   345 		return false;
   346   }
   346 	}
   347    
   347  	
   348   /**
   348 	/**
   349    * The "real" send-the-page function. The reason for this is so other namespaces can re-use the code
   349  	* The "real" send-the-page function. The reason for this is so other namespaces can re-use the code
   350    * to fetch the page from the DB while being able to install their own wrappers.
   350  	* to fetch the page from the DB while being able to install their own wrappers.
   351    */
   351  	*/
   352   
   352 	
   353   public function send_from_db($incl_inner_headers = true, $send_headers = true)
   353 	public function send_from_db($incl_inner_headers = true, $send_headers = true)
   354   {
   354 	{
   355     global $db, $session, $paths, $template, $plugins; // Common objects
   355 		global $db, $session, $paths, $template, $plugins; // Common objects
   356     global $lang;
   356 		global $lang;
   357     global $output;
   357 		global $output;
   358     
   358 		
   359     $text = $this->fetch_text();
   359 		$text = $this->fetch_text();
   360     
   360 		
   361     profiler_log("Namespace [$this->namespace, $this->page_id]: pulled text from DB");
   361 		profiler_log("Namespace [$this->namespace, $this->page_id]: pulled text from DB");
   362     
   362 		
   363     $text = preg_replace('/([\s]*)__NOBREADCRUMBS__([\s]*)/', '', $text);
   363 		$text = preg_replace('/([\s]*)__NOBREADCRUMBS__([\s]*)/', '', $text);
   364     $text = preg_replace('/([\s]*)__NOTOC__([\s]*)/', '', $text);
   364 		$text = preg_replace('/([\s]*)__NOTOC__([\s]*)/', '', $text);
   365     $text = preg_replace('/^#redirect \[\[.+?\]\]\s*/i', '', $text);
   365 		$text = preg_replace('/^#redirect \[\[.+?\]\]\s*/i', '', $text);
   366     
   366 		
   367     if ( $send_headers )
   367 		if ( $send_headers )
   368     {
   368 		{
   369       $output->set_title($this->title);
   369 			$output->set_title($this->title);
   370       $output->header();
   370 			$output->header();
   371     }
   371 		}
   372     $this->do_breadcrumbs();
   372 		$this->do_breadcrumbs();
   373     
   373 		
   374     if ( $incl_inner_headers )
   374 		if ( $incl_inner_headers )
   375     {
   375 		{
   376       if ( !$this->perms )
   376 			if ( !$this->perms )
   377         $this->perms = $session->fetch_page_acl($this->page_id, $this->namespace);
   377 				$this->perms = $session->fetch_page_acl($this->page_id, $this->namespace);
   378       
   378 			
   379       if ( $this->perms->get_permissions('vote_reset') && $this->cdata['delvotes'] > 0)
   379 			if ( $this->perms->get_permissions('vote_reset') && $this->cdata['delvotes'] > 0)
   380       {
   380 			{
   381         $delvote_ips = unserialize($this->cdata['delvote_ips']);
   381 				$delvote_ips = unserialize($this->cdata['delvote_ips']);
   382         $hr = htmlspecialchars(implode(', ', $delvote_ips['u']));
   382 				$hr = htmlspecialchars(implode(', ', $delvote_ips['u']));
   383         
   383 				
   384         $string_id = ( $this->cdata['delvotes'] == 1 ) ? 'delvote_lbl_votes_one' : 'delvote_lbl_votes_plural';
   384 				$string_id = ( $this->cdata['delvotes'] == 1 ) ? 'delvote_lbl_votes_one' : 'delvote_lbl_votes_plural';
   385         $string = $lang->get($string_id, array('num_users' => $this->cdata['delvotes']));
   385 				$string = $lang->get($string_id, array('num_users' => $this->cdata['delvotes']));
   386         
   386 				
   387         echo '<div class="info-box" style="margin-left: 0; margin-top: 5px;" id="mdgDeleteVoteNoticeBox">
   387 				echo '<div class="info-box" style="margin-left: 0; margin-top: 5px;" id="mdgDeleteVoteNoticeBox">
   388                 <b>' . $lang->get('etc_lbl_notice') . '</b> ' . $string . '<br />
   388 								<b>' . $lang->get('etc_lbl_notice') . '</b> ' . $string . '<br />
   389                 <b>' . $lang->get('delvote_lbl_users_that_voted') . '</b> ' . $hr . '<br />
   389 								<b>' . $lang->get('delvote_lbl_users_that_voted') . '</b> ' . $hr . '<br />
   390                 <a href="'.makeUrl($paths->page, 'do=deletepage').'" onclick="ajaxDeletePage(); return false;">' . $lang->get('delvote_btn_deletepage') . '</a>  |  <a href="'.makeUrl($paths->page, 'do=resetvotes').'" onclick="ajaxResetDelVotes(); return false;">' . $lang->get('delvote_btn_resetvotes') . '</a>
   390 								<a href="'.makeUrl($paths->page, 'do=deletepage').'" onclick="ajaxDeletePage(); return false;">' . $lang->get('delvote_btn_deletepage') . '</a>  |  <a href="'.makeUrl($paths->page, 'do=resetvotes').'" onclick="ajaxResetDelVotes(); return false;">' . $lang->get('delvote_btn_resetvotes') . '</a>
   391               </div>';
   391 							</div>';
   392       }
   392 			}
   393     }
   393 		}
   394     
   394 		
   395     if ( $this->revision_id )
   395 		if ( $this->revision_id )
   396     {
   396 		{
   397       echo '<div class="info-box" style="margin-left: 0; margin-top: 5px;">
   397 			echo '<div class="info-box" style="margin-left: 0; margin-top: 5px;">
   398               <b>' . $lang->get('page_msg_archived_title') . '</b><br />
   398 							<b>' . $lang->get('page_msg_archived_title') . '</b><br />
   399               ' . $lang->get('page_msg_archived_body', array(
   399 							' . $lang->get('page_msg_archived_body', array(
   400                   'archive_date' => enano_date(ED_DATE, $this->revision_time),
   400 									'archive_date' => enano_date(ED_DATE, $this->revision_time),
   401                   'archive_time' => enano_date(ED_TIME, $this->revision_time),
   401 									'archive_time' => enano_date(ED_TIME, $this->revision_time),
   402                   'current_link' => makeUrlNS($this->namespace, $this->page_id),
   402 									'current_link' => makeUrlNS($this->namespace, $this->page_id),
   403                   'restore_link' => makeUrlNS($this->namespace, $this->page_id, 'do=edit&amp;revid='.$this->revision_id),
   403 									'restore_link' => makeUrlNS($this->namespace, $this->page_id, 'do=edit&amp;revid='.$this->revision_id),
   404                   'restore_onclick' => 'ajaxEditor(\''.$this->revision_id.'\'); return false;',
   404 									'restore_onclick' => 'ajaxEditor(\''.$this->revision_id.'\'); return false;',
   405                 )) . '
   405 								)) . '
   406             </div>';
   406 						</div>';
   407       $q = $db->sql_query('SELECT page_format FROM ' . table_prefix . "logs WHERE log_id = {$this->revision_id};");
   407 			$q = $db->sql_query('SELECT page_format FROM ' . table_prefix . "logs WHERE log_id = {$this->revision_id};");
   408       if ( !$q )
   408 			if ( !$q )
   409         $db->_die();
   409 				$db->_die();
   410       
   410 			
   411       list($page_format) = $db->fetchrow_num();
   411 			list($page_format) = $db->fetchrow_num();
   412       $db->free_result();
   412 			$db->free_result();
   413     }
   413 		}
   414     else
   414 		else
   415     {
   415 		{
   416       $page_format = $this->cdata['page_format'];
   416 			$page_format = $this->cdata['page_format'];
   417     }
   417 		}
   418     
   418 		
   419     $code = $plugins->setHook('pageprocess_render_head');
   419 		$code = $plugins->setHook('pageprocess_render_head');
   420     foreach ( $code as $cmd )
   420 		foreach ( $code as $cmd )
   421     {
   421 		{
   422       eval($cmd);
   422 			eval($cmd);
   423     }
   423 		}
   424     
   424 		
   425     $prof_contentevent = profiler_log("Namespace [$this->namespace, $this->page_id]: headers and preprocessing done - about to send content");
   425 		$prof_contentevent = profiler_log("Namespace [$this->namespace, $this->page_id]: headers and preprocessing done - about to send content");
   426     
   426 		
   427     if ( $incl_inner_headers )
   427 		if ( $incl_inner_headers )
   428     {
   428 		{
   429       if ( $page_format === 'wikitext' )
   429 			if ( $page_format === 'wikitext' )
   430       {
   430 			{
   431         $text = '?>' . RenderMan::render($text);
   431 				$text = '?>' . RenderMan::render($text);
   432       }
   432 			}
   433       else
   433 			else
   434       {
   434 			{
   435         // Page format is XHTML. This means we want to disable functionality that MCE takes care of, while still retaining
   435 				// Page format is XHTML. This means we want to disable functionality that MCE takes care of, while still retaining
   436         // the ability to wikilink, the ability to use images, etc. Basically, RENDER_INLINEONLY disables all behavior in
   436 				// the ability to wikilink, the ability to use images, etc. Basically, RENDER_INLINEONLY disables all behavior in
   437         // the rendering engine/Text_Wiki that conflicts with MCE.
   437 				// the rendering engine/Text_Wiki that conflicts with MCE.
   438         $text = '?>' . RenderMan::render($text, RENDER_INLINE);
   438 				$text = '?>' . RenderMan::render($text, RENDER_INLINE);
   439       }
   439 			}
   440     }
   440 		}
   441     else
   441 		else
   442     {
   442 		{
   443       $text = '?>' . $text;
   443 			$text = '?>' . $text;
   444       $text = preg_replace('/<nowiki>(.*?)<\/nowiki>/s', '\\1', $text);
   444 			$text = preg_replace('/<nowiki>(.*?)<\/nowiki>/s', '\\1', $text);
   445     }
   445 		}
   446     
   446 		
   447     eval ( $text );
   447 		eval ( $text );
   448     
   448 		
   449     profiler_log("Namespace [$this->namespace, $this->page_id]: content sent", true, $prof_contentevent);
   449 		profiler_log("Namespace [$this->namespace, $this->page_id]: content sent", true, $prof_contentevent);
   450     
   450 		
   451     $code = $plugins->setHook('pageprocess_render_tail');
   451 		$code = $plugins->setHook('pageprocess_render_tail');
   452     foreach ( $code as $cmd )
   452 		foreach ( $code as $cmd )
   453     {
   453 		{
   454       eval($cmd);
   454 			eval($cmd);
   455     }
   455 		}
   456     
   456 		
   457     if ( $incl_inner_headers )
   457 		if ( $incl_inner_headers )
   458     {
   458 		{
   459       display_page_footers();
   459 			display_page_footers();
   460     }
   460 		}
   461     
   461 		
   462     profiler_log("Namespace [$this->namespace, $this->page_id]: sent footers");
   462 		profiler_log("Namespace [$this->namespace, $this->page_id]: sent footers");
   463     
   463 		
   464     if ( $send_headers )
   464 		if ( $send_headers )
   465       $output->footer();
   465 			$output->footer();
   466   }
   466 	}
   467   
   467 	
   468   /**
   468 	/**
   469    * Echoes out breadcrumb data, if appropriate.
   469  	* Echoes out breadcrumb data, if appropriate.
   470    * @access private
   470  	* @access private
   471    */
   471  	*/
   472   
   472 	
   473   function do_breadcrumbs()
   473 	function do_breadcrumbs()
   474   {
   474 	{
   475     global $db, $session, $paths, $template, $plugins; // Common objects
   475 		global $db, $session, $paths, $template, $plugins; // Common objects
   476     global $lang;
   476 		global $lang;
   477     
   477 		
   478     if ( strpos($this->text_cache, '__NOBREADCRUMBS__') !== false )
   478 		if ( strpos($this->text_cache, '__NOBREADCRUMBS__') !== false )
   479       return false;
   479 			return false;
   480     
   480 		
   481     $mode = getConfig('breadcrumb_mode');
   481 		$mode = getConfig('breadcrumb_mode');
   482     
   482 		
   483     if ( $mode == 'never' )
   483 		if ( $mode == 'never' )
   484       // Breadcrumbs are disabled
   484 			// Breadcrumbs are disabled
   485       return true;
   485 			return true;
   486       
   486 			
   487     // Minimum depth for breadcrumb display
   487 		// Minimum depth for breadcrumb display
   488     $threshold = ( $mode == 'always' ) ? 0 : 1;
   488 		$threshold = ( $mode == 'always' ) ? 0 : 1;
   489     
   489 		
   490     $breadcrumb_data = explode('/', $this->page_id);
   490 		$breadcrumb_data = explode('/', $this->page_id);
   491     if ( count($breadcrumb_data) > $threshold )
   491 		if ( count($breadcrumb_data) > $threshold )
   492     {
   492 		{
   493       // If we're not on a subpage of the main page, add "Home" to the list
   493 			// If we're not on a subpage of the main page, add "Home" to the list
   494       $show_home = false;
   494 			$show_home = false;
   495       if ( $mode == 'always' )
   495 			if ( $mode == 'always' )
   496       {
   496 			{
   497         $show_home = true;
   497 				$show_home = true;
   498       }
   498 			}
   499       echo '<!-- Start breadcrumbs -->
   499 			echo '<!-- Start breadcrumbs -->
   500             <div class="breadcrumbs">
   500 						<div class="breadcrumbs">
   501               ';
   501 							';
   502       if ( $show_home )
   502 			if ( $show_home )
   503       {
   503 			{
   504         // Display the "home" link first.
   504 				// Display the "home" link first.
   505         $pathskey = $paths->nslist[ $this->namespace ] . $this->page_id;
   505 				$pathskey = $paths->nslist[ $this->namespace ] . $this->page_id;
   506         if ( $pathskey !== get_main_page() )
   506 				if ( $pathskey !== get_main_page() )
   507           echo '<a href="' . makeUrl(get_main_page(), false, true) . '">';
   507 					echo '<a href="' . makeUrl(get_main_page(), false, true) . '">';
   508         echo $lang->get('onpage_btn_breadcrumbs_home');
   508 				echo $lang->get('onpage_btn_breadcrumbs_home');
   509         if ( $pathskey !== get_main_page() )
   509 				if ( $pathskey !== get_main_page() )
   510           echo '</a>';
   510 					echo '</a>';
   511       }
   511 			}
   512       foreach ( $breadcrumb_data as $i => $crumb )
   512 			foreach ( $breadcrumb_data as $i => $crumb )
   513       {
   513 			{
   514         $cumulative = implode('/', array_slice($breadcrumb_data, 0, ( $i + 1 )));
   514 				$cumulative = implode('/', array_slice($breadcrumb_data, 0, ( $i + 1 )));
   515         if ( $show_home && $cumulative === get_main_page() )
   515 				if ( $show_home && $cumulative === get_main_page() )
   516           continue;
   516 					continue;
   517         if ( $show_home || $i > 0 )
   517 				if ( $show_home || $i > 0 )
   518           echo ' &raquo; ';
   518 					echo ' &raquo; ';
   519         $title = ( isPage($cumulative) ) ? get_page_title($cumulative) : get_page_title($crumb);
   519 				$title = ( isPage($cumulative) ) ? get_page_title($cumulative) : get_page_title($crumb);
   520         if ( $i + 1 == count($breadcrumb_data) )
   520 				if ( $i + 1 == count($breadcrumb_data) )
   521         {
   521 				{
   522           echo htmlspecialchars($title);
   522 					echo htmlspecialchars($title);
   523         }
   523 				}
   524         else
   524 				else
   525         {
   525 				{
   526           $exists = ( isPage($cumulative) ) ? '' : ' class="wikilink-nonexistent"';
   526 					$exists = ( isPage($cumulative) ) ? '' : ' class="wikilink-nonexistent"';
   527           echo '<a href="' . makeUrl($cumulative, false, true) . '"' . $exists . '>' . htmlspecialchars($title) . '</a>';
   527 					echo '<a href="' . makeUrl($cumulative, false, true) . '"' . $exists . '>' . htmlspecialchars($title) . '</a>';
   528         }
   528 				}
   529       }
   529 			}
   530       echo '</div>
   530 			echo '</div>
   531             <!-- End breadcrumbs -->
   531 						<!-- End breadcrumbs -->
   532             ';
   532 						';
   533     }
   533 		}
   534   }
   534 	}
   535   
   535 	
   536   public function error_404()
   536 	public function error_404()
   537   {
   537 	{
   538     global $db, $session, $paths, $template, $plugins; // Common objects
   538 		global $db, $session, $paths, $template, $plugins; // Common objects
   539     global $lang, $output;
   539 		global $lang, $output;
   540     
   540 		
   541     $userpage = $this->namespace == 'User';
   541 		$userpage = $this->namespace == 'User';
   542     
   542 		
   543     @header('HTTP/1.1 404 Not Found');
   543 		@header('HTTP/1.1 404 Not Found');
   544     
   544 		
   545     $msg = ( $pp = $paths->sysmsg('Page_not_found') ) ? $pp : '{STANDARD404}';
   545 		$msg = ( $pp = $paths->sysmsg('Page_not_found') ) ? $pp : '{STANDARD404}';
   546     
   546 		
   547     $standard_404 = '';
   547 		$standard_404 = '';
   548     
   548 		
   549     if ( $userpage )
   549 		if ( $userpage )
   550     {
   550 		{
   551       $standard_404 .= '<h3>' . $lang->get('page_msg_404_title_userpage') . '</h3>
   551 			$standard_404 .= '<h3>' . $lang->get('page_msg_404_title_userpage') . '</h3>
   552              <p>' . $lang->get('page_msg_404_body_userpage');
   552  						<p>' . $lang->get('page_msg_404_body_userpage');
   553     }
   553 		}
   554     else
   554 		else
   555     {
   555 		{
   556       $standard_404 .= '<h3>' . $lang->get('page_msg_404_title') . '</h3>
   556 			$standard_404 .= '<h3>' . $lang->get('page_msg_404_title') . '</h3>
   557              <p>' . $lang->get('page_msg_404_body');
   557  						<p>' . $lang->get('page_msg_404_body');
   558     }
   558 		}
   559     if ( $session->get_permissions('create_page') )
   559 		if ( $session->get_permissions('create_page') )
   560     {
   560 		{
   561       $standard_404 .= ' ' . $lang->get('page_msg_404_create', array(
   561 			$standard_404 .= ' ' . $lang->get('page_msg_404_create', array(
   562           'create_flags' => 'href="'.makeUrlNS($this->namespace, $this->page_id, 'do=edit', true).'" onclick="ajaxEditor(); return false;"',
   562 					'create_flags' => 'href="'.makeUrlNS($this->namespace, $this->page_id, 'do=edit', true).'" onclick="ajaxEditor(); return false;"',
   563           'mainpage_link' => makeUrl(get_main_page(), false, true)
   563 					'mainpage_link' => makeUrl(get_main_page(), false, true)
   564         ));
   564 				));
   565     }
   565 		}
   566     else
   566 		else
   567     {
   567 		{
   568       $standard_404 .= ' ' . $lang->get('page_msg_404_gohome', array(
   568 			$standard_404 .= ' ' . $lang->get('page_msg_404_gohome', array(
   569           'mainpage_link' => makeUrl(get_main_page(), false, true)
   569 					'mainpage_link' => makeUrl(get_main_page(), false, true)
   570         ));
   570 				));
   571     }
   571 		}
   572     $standard_404 .= '</p>';
   572 		$standard_404 .= '</p>';
   573     if ( $session->get_permissions('history_rollback') )
   573 		if ( $session->get_permissions('history_rollback') )
   574     {
   574 		{
   575       $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;');
   575 			$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;');
   576       if ( !$e )
   576 			if ( !$e )
   577       {
   577 			{
   578         $db->_die('The deletion log could not be selected.');
   578 				$db->_die('The deletion log could not be selected.');
   579       }
   579 			}
   580       if ( $db->numrows() > 0 )
   580 			if ( $db->numrows() > 0 )
   581       {
   581 			{
   582         $r = $db->fetchrow();
   582 				$r = $db->fetchrow();
   583         $standard_404 .= '<p>' . $lang->get('page_msg_404_was_deleted', array(
   583 				$standard_404 .= '<p>' . $lang->get('page_msg_404_was_deleted', array(
   584                   'delete_time' => enano_date(ED_DATE | ED_TIME, $r['time_id']),
   584 									'delete_time' => enano_date(ED_DATE | ED_TIME, $r['time_id']),
   585                   'delete_reason' => htmlspecialchars($r['edit_summary']),
   585 									'delete_reason' => htmlspecialchars($r['edit_summary']),
   586                   'rollback_flags' => 'href="'.makeUrl($paths->page, 'do=rollback&amp;id='.$r['log_id']).'" onclick="ajaxRollback(\''.$r['log_id'].'\'); return false;"'
   586 									'rollback_flags' => 'href="'.makeUrl($paths->page, 'do=rollback&amp;id='.$r['log_id']).'" onclick="ajaxRollback(\''.$r['log_id'].'\'); return false;"'
   587                 ))
   587 								))
   588               . '</p>';
   588 							. '</p>';
   589         if ( $session->user_level >= USER_LEVEL_ADMIN )
   589 				if ( $session->user_level >= USER_LEVEL_ADMIN )
   590         {
   590 				{
   591           $standard_404 .= '<p>' . $lang->get('page_msg_404_admin_opts', array(
   591 					$standard_404 .= '<p>' . $lang->get('page_msg_404_admin_opts', array(
   592                     'detag_link' => makeUrl($paths->page, 'do=detag', true)
   592 										'detag_link' => makeUrl($paths->page, 'do=detag', true)
   593                   ))
   593 									))
   594                 . '</p>';
   594 								. '</p>';
   595         }
   595 				}
   596       }
   596 			}
   597       $db->free_result();
   597 			$db->free_result();
   598     }
   598 		}
   599     $standard_404 .= '<p>
   599 		$standard_404 .= '<p>
   600             ' . $lang->get('page_msg_404_http_response') . '
   600 						' . $lang->get('page_msg_404_http_response') . '
   601           </p>';
   601 					</p>';
   602           
   602 					
   603     $parser = $template->makeParserText($msg);
   603 		$parser = $template->makeParserText($msg);
   604     $parser->assign_vars(array(
   604 		$parser->assign_vars(array(
   605         'STANDARD404' => $standard_404
   605 				'STANDARD404' => $standard_404
   606       ));
   606 			));
   607     
   607 		
   608     $msg = RenderMan::render($parser->run());
   608 		$msg = RenderMan::render($parser->run());
   609     eval( '?>' . $msg );
   609 		eval( '?>' . $msg );
   610   }
   610 	}
   611   
   611 	
   612   /**
   612 	/**
   613    * Display the categories a page is in. If the current page is a category, its contents will also be printed.
   613  	* Display the categories a page is in. If the current page is a category, its contents will also be printed.
   614    */
   614  	*/
   615   
   615 	
   616   function display_categories()
   616 	function display_categories()
   617   {
   617 	{
   618     global $db, $session, $paths, $template, $plugins; // Common objects
   618 		global $db, $session, $paths, $template, $plugins; // Common objects
   619     global $lang;
   619 		global $lang;
   620     
   620 		
   621     $html = '';
   621 		$html = '';
   622     
   622 		
   623     if ( $this->namespace == 'Category' )
   623 		if ( $this->namespace == 'Category' )
   624     {
   624 		{
   625       // Show member pages and subcategories
   625 			// Show member pages and subcategories
   626       $q = $db->sql_query('SELECT p.urlname, p.namespace, p.name, p.namespace=\'Category\' AS is_category FROM '.table_prefix.'categories AS c
   626 			$q = $db->sql_query('SELECT p.urlname, p.namespace, p.name, p.namespace=\'Category\' AS is_category FROM '.table_prefix.'categories AS c
   627                              LEFT JOIN '.table_prefix.'pages AS p
   627  														LEFT JOIN '.table_prefix.'pages AS p
   628                                ON ( p.urlname = c.page_id AND p.namespace = c.namespace )
   628  															ON ( p.urlname = c.page_id AND p.namespace = c.namespace )
   629                              WHERE c.category_id=\'' . $db->escape($this->page_id) . '\'
   629  														WHERE c.category_id=\'' . $db->escape($this->page_id) . '\'
   630                              ORDER BY is_category DESC, p.name ASC;');
   630  														ORDER BY is_category DESC, p.name ASC;');
   631       if ( !$q )
   631 			if ( !$q )
   632       {
   632 			{
   633         $db->_die();
   633 				$db->_die();
   634       }
   634 			}
   635       $html .= '<h3>' . $lang->get('onpage_cat_heading_subcategories') . '</h3>';
   635 			$html .= '<h3>' . $lang->get('onpage_cat_heading_subcategories') . '</h3>';
   636       $html .= '<div class="tblholder">';
   636 			$html .= '<div class="tblholder">';
   637       $html .= '<table border="0" cellspacing="1" cellpadding="4">';
   637 			$html .= '<table border="0" cellspacing="1" cellpadding="4">';
   638       $html .= '<tr>';
   638 			$html .= '<tr>';
   639       $ticker = 0;
   639 			$ticker = 0;
   640       $counter = 0;
   640 			$counter = 0;
   641       $switched = false;
   641 			$switched = false;
   642       $class  = 'row1';
   642 			$class  = 'row1';
   643       while ( $row = $db->fetchrow($q) )
   643 			while ( $row = $db->fetchrow($q) )
   644       {
   644 			{
   645         if ( $row['is_category'] == 0 && !$switched )
   645 				if ( $row['is_category'] == 0 && !$switched )
   646         {
   646 				{
   647           if ( $counter > 0 )
   647 					if ( $counter > 0 )
   648           {
   648 					{
   649             // Fill-in
   649 						// Fill-in
   650             while ( $ticker < 3 )
   650 						while ( $ticker < 3 )
   651             {
   651 						{
   652               $ticker++;
   652 							$ticker++;
   653               $html .= '<td class="' . $class . '" style="width: 33.3%;"></td>';
   653 							$html .= '<td class="' . $class . '" style="width: 33.3%;"></td>';
   654             }
   654 						}
   655           }
   655 					}
   656           else
   656 					else
   657           {
   657 					{
   658             $html .= '<td class="' . $class . '">' . $lang->get('onpage_cat_msg_no_subcategories') . '</td>';
   658 						$html .= '<td class="' . $class . '">' . $lang->get('onpage_cat_msg_no_subcategories') . '</td>';
   659           }
   659 					}
   660           $html .= '</tr></table></div>' . "\n\n";
   660 					$html .= '</tr></table></div>' . "\n\n";
   661           $html .= '<h3>' . $lang->get('onpage_cat_heading_pages') . '</h3>';
   661 					$html .= '<h3>' . $lang->get('onpage_cat_heading_pages') . '</h3>';
   662           $html .= '<div class="tblholder">';
   662 					$html .= '<div class="tblholder">';
   663           $html .= '<table border="0" cellspacing="1" cellpadding="4">';
   663 					$html .= '<table border="0" cellspacing="1" cellpadding="4">';
   664           $html .= '<tr>';
   664 					$html .= '<tr>';
   665           $counter = 0;
   665 					$counter = 0;
   666           $ticker = -1;
   666 					$ticker = -1;
   667           $switched = true;
   667 					$switched = true;
   668         }
   668 				}
   669         $counter++;
   669 				$counter++;
   670         $ticker++;
   670 				$ticker++;
   671         if ( $ticker == 3 )
   671 				if ( $ticker == 3 )
   672         {
   672 				{
   673           $html .= '</tr><tr>';
   673 					$html .= '</tr><tr>';
   674           $ticker = 0;
   674 					$ticker = 0;
   675           $class = ( $class == 'row3' ) ? 'row1' : 'row3';
   675 					$class = ( $class == 'row3' ) ? 'row1' : 'row3';
   676         }
   676 				}
   677         $html .= "<td class=\"{$class}\" style=\"width: 33.3%;\">"; // " to workaround stupid jEdit bug
   677 				$html .= "<td class=\"{$class}\" style=\"width: 33.3%;\">"; // " to workaround stupid jEdit bug
   678         
   678 				
   679         $link = makeUrlNS($row['namespace'], sanitize_page_id($row['urlname']));
   679 				$link = makeUrlNS($row['namespace'], sanitize_page_id($row['urlname']));
   680         $html .= '<a href="' . $link . '"';
   680 				$html .= '<a href="' . $link . '"';
   681         $key = $paths->nslist[$row['namespace']] . sanitize_page_id($row['urlname']);
   681 				$key = $paths->nslist[$row['namespace']] . sanitize_page_id($row['urlname']);
   682         if ( !isPage( $key ) )
   682 				if ( !isPage( $key ) )
   683         {
   683 				{
   684           $html .= ' class="wikilink-nonexistent"';
   684 					$html .= ' class="wikilink-nonexistent"';
   685         }
   685 				}
   686         $html .= '>';
   686 				$html .= '>';
   687         $title = get_page_title_ns($row['urlname'], $row['namespace']);
   687 				$title = get_page_title_ns($row['urlname'], $row['namespace']);
   688         $html .= htmlspecialchars($title);
   688 				$html .= htmlspecialchars($title);
   689         $html .= '</a>';
   689 				$html .= '</a>';
   690         
   690 				
   691         $html .= "</td>";
   691 				$html .= "</td>";
   692       }
   692 			}
   693       if ( !$switched )
   693 			if ( !$switched )
   694       {
   694 			{
   695         if ( $counter > 0 )
   695 				if ( $counter > 0 )
   696         {
   696 				{
   697           // Fill-in
   697 					// Fill-in
   698           while ( $ticker < 2 )
   698 					while ( $ticker < 2 )
   699           {
   699 					{
   700             $ticker++;
   700 						$ticker++;
   701             $html .= '<td class="' . $class . '" style="width: 33.3%;"></td>';
   701 						$html .= '<td class="' . $class . '" style="width: 33.3%;"></td>';
   702           }
   702 					}
   703         }
   703 				}
   704         else
   704 				else
   705         {
   705 				{
   706           $html .= '<td class="' . $class . '">' . $lang->get('onpage_cat_msg_no_subcategories') . '</td>';
   706 					$html .= '<td class="' . $class . '">' . $lang->get('onpage_cat_msg_no_subcategories') . '</td>';
   707         }
   707 				}
   708         $html .= '</tr></table></div>' . "\n\n";
   708 				$html .= '</tr></table></div>' . "\n\n";
   709         $html .= '<h3>' . $lang->get('onpage_cat_heading_pages') . '</h3>';
   709 				$html .= '<h3>' . $lang->get('onpage_cat_heading_pages') . '</h3>';
   710         $html .= '<div class="tblholder">';
   710 				$html .= '<div class="tblholder">';
   711         $html .= '<table border="0" cellspacing="1" cellpadding="4">';
   711 				$html .= '<table border="0" cellspacing="1" cellpadding="4">';
   712         $html .= '<tr>';
   712 				$html .= '<tr>';
   713         $counter = 0;
   713 				$counter = 0;
   714         $ticker = 0;
   714 				$ticker = 0;
   715         $switched = true;
   715 				$switched = true;
   716       }
   716 			}
   717       if ( $counter > 0 )
   717 			if ( $counter > 0 )
   718       {
   718 			{
   719         // Fill-in
   719 				// Fill-in
   720         while ( $ticker < 2 )
   720 				while ( $ticker < 2 )
   721         {
   721 				{
   722           $ticker++;
   722 					$ticker++;
   723           $html .= '<td class="' . $class . '" style="width: 33.3%;"></td>';
   723 					$html .= '<td class="' . $class . '" style="width: 33.3%;"></td>';
   724         }
   724 				}
   725       }
   725 			}
   726       else
   726 			else
   727       {
   727 			{
   728         $html .= '<td class="' . $class . '">' . $lang->get('onpage_cat_msg_no_pages') . '</td>';
   728 				$html .= '<td class="' . $class . '">' . $lang->get('onpage_cat_msg_no_pages') . '</td>';
   729       }
   729 			}
   730       $html .= '</tr></table></div>' . "\n\n";
   730 			$html .= '</tr></table></div>' . "\n\n";
   731     }
   731 		}
   732     
   732 		
   733     if ( $this->namespace != 'Special' && $this->namespace != 'Admin' )
   733 		if ( $this->namespace != 'Special' && $this->namespace != 'Admin' )
   734     {
   734 		{
   735       $html .= '<div class="mdg-comment" style="margin: 10px 0 0 0;" id="category_box_wrapper">';
   735 			$html .= '<div class="mdg-comment" style="margin: 10px 0 0 0;" id="category_box_wrapper">';
   736       $html .= '<div style="float: right;">';
   736 			$html .= '<div style="float: right;">';
   737       $html .= '(<a href="#" onclick="ajaxCatToTag(); return false;">' . $lang->get('tags_catbox_link') . '</a>)';
   737 			$html .= '(<a href="#" onclick="ajaxCatToTag(); return false;">' . $lang->get('tags_catbox_link') . '</a>)';
   738       $html .= '</div>';
   738 			$html .= '</div>';
   739       $html .= '<div id="mdgCatBox">' . $lang->get('catedit_catbox_lbl_categories') . ' ';
   739 			$html .= '<div id="mdgCatBox">' . $lang->get('catedit_catbox_lbl_categories') . ' ';
   740       
   740 			
   741       $q = $db->sql_query('SELECT category_id FROM ' . table_prefix . "categories WHERE page_id = '$this->page_id' AND namespace = '$this->namespace';");
   741 			$q = $db->sql_query('SELECT category_id FROM ' . table_prefix . "categories WHERE page_id = '$this->page_id' AND namespace = '$this->namespace';");
   742       if ( !$q )
   742 			if ( !$q )
   743         $db->_die();
   743 				$db->_die();
   744       
   744 			
   745       if ( $row = $db->fetchrow() )
   745 			if ( $row = $db->fetchrow() )
   746       {
   746 			{
   747         $list = array();
   747 				$list = array();
   748         do
   748 				do
   749         {
   749 				{
   750           $cid = sanitize_page_id($row['category_id']);
   750 					$cid = sanitize_page_id($row['category_id']);
   751           $title = get_page_title_ns($cid, 'Category');
   751 					$title = get_page_title_ns($cid, 'Category');
   752           $link = makeUrlNS('Category', $cid);
   752 					$link = makeUrlNS('Category', $cid);
   753           $list[] = '<a href="' . $link . '">' . htmlspecialchars($title) . '</a>';
   753 					$list[] = '<a href="' . $link . '">' . htmlspecialchars($title) . '</a>';
   754         }
   754 				}
   755         while ( $row = $db->fetchrow($q) );
   755 				while ( $row = $db->fetchrow($q) );
   756         $html .= implode(', ', $list);
   756 				$html .= implode(', ', $list);
   757       }
   757 			}
   758       else
   758 			else
   759       {
   759 			{
   760         $html .= $lang->get('catedit_catbox_lbl_uncategorized');
   760 				$html .= $lang->get('catedit_catbox_lbl_uncategorized');
   761       }
   761 			}
   762       
   762 			
   763       $can_edit = ( $session->get_permissions('edit_cat') && ( !$paths->page_protected || $session->get_permissions('even_when_protected') ) );
   763 			$can_edit = ( $session->get_permissions('edit_cat') && ( !$paths->page_protected || $session->get_permissions('even_when_protected') ) );
   764       if ( $can_edit )
   764 			if ( $can_edit )
   765       {
   765 			{
   766         $edit_link = '<a href="' . makeUrl($paths->page, 'do=catedit', true) . '" onclick="ajaxCatEdit(); return false;">' . $lang->get('catedit_catbox_link_edit') . '</a>';
   766 				$edit_link = '<a href="' . makeUrl($paths->page, 'do=catedit', true) . '" onclick="ajaxCatEdit(); return false;">' . $lang->get('catedit_catbox_link_edit') . '</a>';
   767         $html .= ' [ ' . $edit_link . ' ]';
   767 				$html .= ' [ ' . $edit_link . ' ]';
   768       }
   768 			}
   769       
   769 			
   770       $html .= '</div></div>';
   770 			$html .= '</div></div>';
   771     }
   771 		}
   772     return $html;
   772 		return $html;
   773   }
   773 	}
   774   
   774 	
   775   /**
   775 	/**
   776    * Pull in switches as to whether a specific toolbar button should be used or not. This sets things up according to the current page being displayed.
   776  	* Pull in switches as to whether a specific toolbar button should be used or not. This sets things up according to the current page being displayed.
   777    * @return array Associative
   777  	* @return array Associative
   778    */
   778  	*/
   779   
   779 	
   780   function set_conds()
   780 	function set_conds()
   781   {
   781 	{
   782     global $db, $session, $paths, $template, $plugins; // Common objects
   782 		global $db, $session, $paths, $template, $plugins; // Common objects
   783     
   783 		
   784     if ( !$this->perms )
   784 		if ( !$this->perms )
   785       $this->perms = $session->fetch_page_acl($this->page_id, $this->namespace);
   785 			$this->perms = $session->fetch_page_acl($this->page_id, $this->namespace);
   786     
   786 		
   787     if ( !$this->perms )
   787 		if ( !$this->perms )
   788     {
   788 		{
   789       // We're trying to send a page WAY too early (session hasn't been started yet), such as for a redirect. Send a default set of conds because
   789 			// We're trying to send a page WAY too early (session hasn't been started yet), such as for a redirect. Send a default set of conds because
   790       // there's NO way to get permissions to determine anything otherwise. Yes, starting $session here might be dangerous.
   790 			// there's NO way to get permissions to determine anything otherwise. Yes, starting $session here might be dangerous.
   791       $this->conds = array(
   791 			$this->conds = array(
   792           'article' => true,
   792 					'article' => true,
   793           'comments' => false,
   793 					'comments' => false,
   794           'edit' => false,
   794 					'edit' => false,
   795           'viewsource' => false,
   795 					'viewsource' => false,
   796           'history' => false,
   796 					'history' => false,
   797           'rename' => false,
   797 					'rename' => false,
   798           'delvote' => false,
   798 					'delvote' => false,
   799           'resetvotes' => false,
   799 					'resetvotes' => false,
   800           'delete' => false,
   800 					'delete' => false,
   801           'printable' => false,
   801 					'printable' => false,
   802           'protect' => false,
   802 					'protect' => false,
   803           'setwikimode' => false,
   803 					'setwikimode' => false,
   804           'clearlogs' => false,
   804 					'clearlogs' => false,
   805           'password' => false,
   805 					'password' => false,
   806           'acledit' => false,
   806 					'acledit' => false,
   807           'adminpage' => false
   807 					'adminpage' => false
   808         );
   808 				);
   809       return $this->conds;
   809 			return $this->conds;
   810     }
   810 		}
   811     
   811 		
   812     // die('have perms: <pre>' . print_r($this->perms, true) . "\n---------------------------------\nBacktrace:\n" . enano_debug_print_backtrace(true));
   812 		// die('have perms: <pre>' . print_r($this->perms, true) . "\n---------------------------------\nBacktrace:\n" . enano_debug_print_backtrace(true));
   813     
   813 		
   814     $enforce_protection = ( $this->page_protected && ( ( $session->check_acl_scope('even_when_protected', $this->namespace) && !$this->perms->get_permissions('even_when_protected') ) || !$session->check_acl_scope('even_when_protected', $this->namespace) ) );
   814 		$enforce_protection = ( $this->page_protected && ( ( $session->check_acl_scope('even_when_protected', $this->namespace) && !$this->perms->get_permissions('even_when_protected') ) || !$session->check_acl_scope('even_when_protected', $this->namespace) ) );
   815     
   815 		
   816     $conds = array();
   816 		$conds = array();
   817     
   817 		
   818     // Article: always show
   818 		// Article: always show
   819     $conds['article'] = true;
   819 		$conds['article'] = true;
   820     
   820 		
   821     // Discussion: Show if comments are enabled on the site, and if comments are on for this page.
   821 		// Discussion: Show if comments are enabled on the site, and if comments are on for this page.
   822     $conds['comments'] = $this->perms->get_permissions('read') && getConfig('enable_comments', '1')=='1' && $this->cdata['comments_on'] == 1;
   822 		$conds['comments'] = $this->perms->get_permissions('read') && getConfig('enable_comments', '1')=='1' && $this->cdata['comments_on'] == 1;
   823     
   823 		
   824     // Edit: Show if we have permission to edit the page, and if we don't have protection in effect
   824 		// Edit: Show if we have permission to edit the page, and if we don't have protection in effect
   825     $conds['edit'] = $this->perms->get_permissions('read') && $session->check_acl_scope('edit_page', $this->namespace) && $this->perms->get_permissions('edit_page') && !$enforce_protection;
   825 		$conds['edit'] = $this->perms->get_permissions('read') && $session->check_acl_scope('edit_page', $this->namespace) && $this->perms->get_permissions('edit_page') && !$enforce_protection;
   826     
   826 		
   827     // View source: Show if we have permission to view source and either ACLs prohibit editing or protection is in effect
   827 		// View source: Show if we have permission to view source and either ACLs prohibit editing or protection is in effect
   828     $conds['viewsource'] = $session->check_acl_scope('view_source', $this->namespace) && $this->perms->get_permissions('view_source') && ( !$this->perms->get_permissions('edit_page') || $enforce_protection ) && $this->namespace != 'API';
   828 		$conds['viewsource'] = $session->check_acl_scope('view_source', $this->namespace) && $this->perms->get_permissions('view_source') && ( !$this->perms->get_permissions('edit_page') || $enforce_protection ) && $this->namespace != 'API';
   829     
   829 		
   830     // History: Show if we have permission to see history and if the page exists
   830 		// History: Show if we have permission to see history and if the page exists
   831     $conds['history'] = $session->check_acl_scope('history_view', $this->namespace) && $this->exists && $this->perms->get_permissions('history_view');
   831 		$conds['history'] = $session->check_acl_scope('history_view', $this->namespace) && $this->exists && $this->perms->get_permissions('history_view');
   832     
   832 		
   833     // Rename: Show if the page exists, if we have permission to rename, and if protection isn't in effect
   833 		// Rename: Show if the page exists, if we have permission to rename, and if protection isn't in effect
   834     $conds['rename'] = $session->check_acl_scope('rename', $this->namespace) && $this->exists && $this->perms->get_permissions('rename') && !$enforce_protection;
   834 		$conds['rename'] = $session->check_acl_scope('rename', $this->namespace) && $this->exists && $this->perms->get_permissions('rename') && !$enforce_protection;
   835     
   835 		
   836     // Vote-to-delete: Show if we have Wiki Mode on, if we have permission to vote for deletion, and if the page exists (can't vote to delete a nonexistent page)
   836 		// Vote-to-delete: Show if we have Wiki Mode on, if we have permission to vote for deletion, and if the page exists (can't vote to delete a nonexistent page)
   837     $conds['delvote'] = $this->wiki_mode && $session->check_acl_scope('vote_delete', $this->namespace) && $this->perms->get_permissions('vote_delete') && $this->exists;
   837 		$conds['delvote'] = $this->wiki_mode && $session->check_acl_scope('vote_delete', $this->namespace) && $this->perms->get_permissions('vote_delete') && $this->exists;
   838     
   838 		
   839     // Reset votes: Show if we have Wiki Mode on, if we have permission to reset votes, if the page exists, and if there's at least one vote
   839 		// Reset votes: Show if we have Wiki Mode on, if we have permission to reset votes, if the page exists, and if there's at least one vote
   840     $conds['resetvotes'] = $session->check_acl_scope('vote_reset', $this->namespace) && $this->wiki_mode && $this->exists && $this->perms->get_permissions('vote_reset') && $this->cdata['delvotes'] > 0;
   840 		$conds['resetvotes'] = $session->check_acl_scope('vote_reset', $this->namespace) && $this->wiki_mode && $this->exists && $this->perms->get_permissions('vote_reset') && $this->cdata['delvotes'] > 0;
   841     
   841 		
   842     // Delete page: Show if the page exists and if we have permission to delete it
   842 		// Delete page: Show if the page exists and if we have permission to delete it
   843     $conds['delete'] = $session->check_acl_scope('delete_page', $this->namespace) && $this->exists && $this->perms->get_permissions('delete_page');
   843 		$conds['delete'] = $session->check_acl_scope('delete_page', $this->namespace) && $this->exists && $this->perms->get_permissions('delete_page');
   844     
   844 		
   845     // Printable view: Show if the page exists
   845 		// Printable view: Show if the page exists
   846     $conds['printable'] = $this->exists;
   846 		$conds['printable'] = $this->exists;
   847     
   847 		
   848     // Protect: Show if we have Wiki Mode on, if the page exists, and if we have permission to protect the page.
   848 		// Protect: Show if we have Wiki Mode on, if the page exists, and if we have permission to protect the page.
   849     $conds['protect'] = $session->check_acl_scope('protect', $this->namespace) && $this->wiki_mode && $this->exists && $this->perms->get_permissions('protect');
   849 		$conds['protect'] = $session->check_acl_scope('protect', $this->namespace) && $this->wiki_mode && $this->exists && $this->perms->get_permissions('protect');
   850     
   850 		
   851     // Set Wiki Mode: Show if the page exists and if we have permission to set wiki mode
   851 		// Set Wiki Mode: Show if the page exists and if we have permission to set wiki mode
   852     $conds['setwikimode'] = $session->check_acl_scope('set_wiki_mode', $this->namespace) && $this->exists && $this->perms->get_permissions('set_wiki_mode');
   852 		$conds['setwikimode'] = $session->check_acl_scope('set_wiki_mode', $this->namespace) && $this->exists && $this->perms->get_permissions('set_wiki_mode');
   853     
   853 		
   854     // Clear logs: Show if we have permission to clear logs
   854 		// Clear logs: Show if we have permission to clear logs
   855     $conds['clearlogs'] = $session->check_acl_scope('clear_logs', $this->namespace) && $this->perms->get_permissions('clear_logs');
   855 		$conds['clearlogs'] = $session->check_acl_scope('clear_logs', $this->namespace) && $this->perms->get_permissions('clear_logs');
   856     
   856 		
   857     // Set password: a little bit complicated. If there's a password, check for password_reset; else, check for password_set.
   857 		// Set password: a little bit complicated. If there's a password, check for password_reset; else, check for password_set.
   858     $conds['password'] = empty($this->cdata['password']) ?
   858 		$conds['password'] = empty($this->cdata['password']) ?
   859                            $session->check_acl_scope('password_set', $this->namespace) && $this->perms->get_permissions('password_set') :
   859  													$session->check_acl_scope('password_set', $this->namespace) && $this->perms->get_permissions('password_set') :
   860                            $session->check_acl_scope('password_reset', $this->namespace) && $this->perms->get_permissions('password_reset');
   860  													$session->check_acl_scope('password_reset', $this->namespace) && $this->perms->get_permissions('password_reset');
   861     
   861 		
   862     // Edit ACLs: Show if this is a non-Enano page that's calling the Enano API and (a) if we have permissions to edit ACLs or (b) we're an admin AND ACL_ALWAYS_ALLOW_ADMIN_EDIT_ACL is on
   862 		// Edit ACLs: Show if this is a non-Enano page that's calling the Enano API and (a) if we have permissions to edit ACLs or (b) we're an admin AND ACL_ALWAYS_ALLOW_ADMIN_EDIT_ACL is on
   863     $conds['acledit'] = $this->namespace != 'API' && $session->check_acl_scope('edit_acl', $this->namespace) && ( $this->perms->get_permissions('edit_acl') || ( defined('ACL_ALWAYS_ALLOW_ADMIN_EDIT_ACL') &&  $session->user_level >= USER_LEVEL_ADMIN ) );
   863 		$conds['acledit'] = $this->namespace != 'API' && $session->check_acl_scope('edit_acl', $this->namespace) && ( $this->perms->get_permissions('edit_acl') || ( defined('ACL_ALWAYS_ALLOW_ADMIN_EDIT_ACL') &&  $session->user_level >= USER_LEVEL_ADMIN ) );
   864     
   864 		
   865     // Admin page: Show if the page exists and if we're an admin
   865 		// Admin page: Show if the page exists and if we're an admin
   866     $conds['adminpage'] = $session->user_level >= USER_LEVEL_ADMIN && $this->exists;
   866 		$conds['adminpage'] = $session->user_level >= USER_LEVEL_ADMIN && $this->exists;
   867     
   867 		
   868     // Allow plugins to change stuff
   868 		// Allow plugins to change stuff
   869     $code = $plugins->setHook('page_conds_set');
   869 		$code = $plugins->setHook('page_conds_set');
   870     foreach ( $code as $cmd )
   870 		foreach ( $code as $cmd )
   871     {
   871 		{
   872       eval($cmd);
   872 			eval($cmd);
   873     }
   873 		}
   874     
   874 		
   875     $this->conds = $conds;
   875 		$this->conds = $conds;
   876   }
   876 	}
   877   
   877 	
   878   /**
   878 	/**
   879    * Return page conditions
   879  	* Return page conditions
   880    * @return array
   880  	* @return array
   881    */
   881  	*/
   882   
   882 	
   883   public function get_conds()
   883 	public function get_conds()
   884   {
   884 	{
   885     if ( empty($this->conds) )
   885 		if ( empty($this->conds) )
   886       $this->set_conds();
   886 			$this->set_conds();
   887     
   887 		
   888     return $this->conds;
   888 		return $this->conds;
   889   }
   889 	}
   890   
   890 	
   891   /**
   891 	/**
   892    * Just tell us if the current page exists or not.
   892  	* Just tell us if the current page exists or not.
   893    * @return bool
   893  	* @return bool
   894    */
   894  	*/
   895    
   895  	
   896   public function exists()
   896 	public function exists()
   897   {
   897 	{
   898     return $this->exists;
   898 		return $this->exists;
   899   }
   899 	}
   900   
   900 	
   901   /**
   901 	/**
   902    * Return cdata
   902  	* Return cdata
   903    * @return array
   903  	* @return array
   904    */
   904  	*/
   905   
   905 	
   906   public function get_cdata()
   906 	public function get_cdata()
   907   {
   907 	{
   908     return $this->cdata;
   908 		return $this->cdata;
   909   }
   909 	}
   910   
   910 	
   911   /**
   911 	/**
   912    * Bake, or finalize the processing of, a cdata array.
   912  	* Bake, or finalize the processing of, a cdata array.
   913    * @static
   913  	* @static
   914    * @access public
   914  	* @access public
   915    */
   915  	*/
   916   
   916 	
   917   public static function bake_cdata($cdata)
   917 	public static function bake_cdata($cdata)
   918   {
   918 	{
   919     global $db, $session, $paths, $template, $plugins; // Common objects
   919 		global $db, $session, $paths, $template, $plugins; // Common objects
   920     
   920 		
   921     // urlname_nons is the actual page_id.
   921 		// urlname_nons is the actual page_id.
   922     $cdata['urlname_nons'] = $cdata['urlname'];
   922 		$cdata['urlname_nons'] = $cdata['urlname'];
   923     if ( isset($paths->nslist[ $cdata['namespace'] ]) )
   923 		if ( isset($paths->nslist[ $cdata['namespace'] ]) )
   924     {
   924 		{
   925       $cdata['urlname'] = $paths->nslist[ $cdata['namespace'] ] . $cdata['urlname'];
   925 			$cdata['urlname'] = $paths->nslist[ $cdata['namespace'] ] . $cdata['urlname'];
   926     }
   926 		}
   927     else
   927 		else
   928     {
   928 		{
   929       $ns_char = substr($paths->nslist['Special'], -1);
   929 			$ns_char = substr($paths->nslist['Special'], -1);
   930       $cdata['urlname'] = $cdata['namespace'] . $ns_char . $cdata['urlname'];
   930 			$cdata['urlname'] = $cdata['namespace'] . $ns_char . $cdata['urlname'];
   931     }
   931 		}
   932     
   932 		
   933     // add missing keys
   933 		// add missing keys
   934     $defaults = array(
   934 		$defaults = array(
   935       'special' => 0,
   935 			'special' => 0,
   936       'visible' => 0,
   936 			'visible' => 0,
   937       'comments_on' => 1,
   937 			'comments_on' => 1,
   938       'protected' => 0,
   938 			'protected' => 0,
   939       'delvotes' => 0,
   939 			'delvotes' => 0,
   940       'delvote_ips' => serialize(array()),
   940 			'delvote_ips' => serialize(array()),
   941       'wiki_mode' => 2,
   941 			'wiki_mode' => 2,
   942       'page_format' => getConfig('default_page_format', 'wikitext')
   942 			'page_format' => getConfig('default_page_format', 'wikitext')
   943     );
   943 		);
   944     foreach ( $defaults as $key => $value )
   944 		foreach ( $defaults as $key => $value )
   945     {
   945 		{
   946       if ( !isset($cdata[$key]) )
   946 			if ( !isset($cdata[$key]) )
   947         $cdata[$key] = $value;
   947 				$cdata[$key] = $value;
   948     }
   948 		}
   949     
   949 		
   950     // fix up deletion votes
   950 		// fix up deletion votes
   951     if ( empty($cdata['delvotes']) )
   951 		if ( empty($cdata['delvotes']) )
   952       $cdata['delvotes'] = 0;
   952 			$cdata['delvotes'] = 0;
   953     
   953 		
   954     // fix up deletion vote IP list
   954 		// fix up deletion vote IP list
   955     if ( empty($cdata['delvote_ips']) )
   955 		if ( empty($cdata['delvote_ips']) )
   956       $cdata['delvote_ips'] = serialize(array());
   956 			$cdata['delvote_ips'] = serialize(array());
   957     
   957 		
   958     // calculate wiki mode
   958 		// calculate wiki mode
   959     $cdata['really_wiki_mode'] = ( $cdata['wiki_mode'] == 1 || ( $cdata['wiki_mode'] == 2 && getConfig('wiki_mode', 0) == 1 ) );
   959 		$cdata['really_wiki_mode'] = ( $cdata['wiki_mode'] == 1 || ( $cdata['wiki_mode'] == 2 && getConfig('wiki_mode', 0) == 1 ) );
   960     
   960 		
   961     // calculate protection
   961 		// calculate protection
   962     $cdata['really_protected'] = ( $cdata['protected'] > 0 );
   962 		$cdata['really_protected'] = ( $cdata['protected'] > 0 );
   963     if ( $cdata['protected'] == 2 )
   963 		if ( $cdata['protected'] == 2 )
   964     {
   964 		{
   965       $cdata['really_protected'] = !$session->user_logged_in || ( $session->user_logged_in && $session->reg_time + 86400*4 > time() );
   965 			$cdata['really_protected'] = !$session->user_logged_in || ( $session->user_logged_in && $session->reg_time + 86400*4 > time() );
   966     }
   966 		}
   967     
   967 		
   968     return $cdata;
   968 		return $cdata;
   969   }
   969 	}
   970   
   970 	
   971   /**
   971 	/**
   972    * Grabs raw (unbaked) cdata from the database, caching if possible.
   972  	* Grabs raw (unbaked) cdata from the database, caching if possible.
   973    * @param string Page ID
   973  	* @param string Page ID
   974    * @param string Namespace.
   974  	* @param string Namespace.
   975    * @static
   975  	* @static
   976    */
   976  	*/
   977   
   977 	
   978   public static function get_cdata_from_db($page_id, $namespace)
   978 	public static function get_cdata_from_db($page_id, $namespace)
   979   {
   979 	{
   980     global $db, $session, $paths, $template, $plugins; // Common objects
   980 		global $db, $session, $paths, $template, $plugins; // Common objects
   981     static $cache = array();
   981 		static $cache = array();
   982     
   982 		
   983     $pathskey = $paths->get_pathskey($page_id, $namespace);
   983 		$pathskey = $paths->get_pathskey($page_id, $namespace);
   984     if ( isset($cache[$pathskey]) )
   984 		if ( isset($cache[$pathskey]) )
   985       return $cache[$pathskey];
   985 			return $cache[$pathskey];
   986     
   986 		
   987     $page_id_db = $db->escape($page_id);
   987 		$page_id_db = $db->escape($page_id);
   988     $namespace_db = $db->escape($namespace);
   988 		$namespace_db = $db->escape($namespace);
   989     
   989 		
   990     $q = $db->sql_query('SELECT p.*'
   990 		$q = $db->sql_query('SELECT p.*'
   991                       . '    FROM ' . table_prefix . "pages AS p\n"
   991 											. '    FROM ' . table_prefix . "pages AS p\n"
   992                       . "  WHERE p.urlname = '$page_id_db' AND p.namespace = '$namespace_db'\n"
   992 											. "  WHERE p.urlname = '$page_id_db' AND p.namespace = '$namespace_db'\n"
   993                       . "    GROUP BY p.urlname, p.name, p.namespace, p.page_order, p.special, p.visible, p.protected, p.wiki_mode, p.comments_on, p.delvotes, p.delvote_ips, p.page_format, p.password;");
   993 											. "    GROUP BY p.urlname, p.name, p.namespace, p.page_order, p.special, p.visible, p.protected, p.wiki_mode, p.comments_on, p.delvotes, p.delvote_ips, p.page_format, p.password;");
   994     
   994 		
   995     if ( !$q )
   995 		if ( !$q )
   996       $db->_die();
   996 			$db->_die();
   997     
   997 		
   998     if ( $db->numrows() < 1 )
   998 		if ( $db->numrows() < 1 )
   999     {
   999 		{
  1000       $db->free_result();
  1000 			$db->free_result();
  1001       $cache[$pathskey] = false;
  1001 			$cache[$pathskey] = false;
  1002       return false;
  1002 			return false;
  1003     }
  1003 		}
  1004     
  1004 		
  1005     $row = $db->fetchrow();
  1005 		$row = $db->fetchrow();
  1006     
  1006 		
  1007     // Get comment counts
  1007 		// Get comment counts
  1008     // FIXME: Apparently there's a bit of recursion in here. Fetching permissions depends on this cdata function.
  1008 		// FIXME: Apparently there's a bit of recursion in here. Fetching permissions depends on this cdata function.
  1009     // Perhaps we should eliminate session's dependency on cdata? (What is it used for?)
  1009 		// Perhaps we should eliminate session's dependency on cdata? (What is it used for?)
  1010     $q = $db->sql_query('SELECT approved FROM ' . table_prefix . "comments WHERE page_id = '$page_id_db' AND namespace = '$namespace_db';");
  1010 		$q = $db->sql_query('SELECT approved FROM ' . table_prefix . "comments WHERE page_id = '$page_id_db' AND namespace = '$namespace_db';");
  1011     // yay parallel assignment
  1011 		// yay parallel assignment
  1012     $row['comments_approved'] = $row['comments_unapproved'] = $row['comments_spam'] = 0;
  1012 		$row['comments_approved'] = $row['comments_unapproved'] = $row['comments_spam'] = 0;
  1013     while ( $commentrow = $db->fetchrow() )
  1013 		while ( $commentrow = $db->fetchrow() )
  1014       switch($commentrow['approved'])
  1014 			switch($commentrow['approved'])
  1015       {
  1015 			{
  1016         case COMMENT_APPROVED:
  1016 				case COMMENT_APPROVED:
  1017         default:
  1017 				default:
  1018           $row['comments_approved']++;
  1018 					$row['comments_approved']++;
  1019           break;
  1019 					break;
  1020         case COMMENT_UNAPPROVED:
  1020 				case COMMENT_UNAPPROVED:
  1021           $row['comments_unapproved']++;
  1021 					$row['comments_unapproved']++;
  1022           break;
  1022 					break;
  1023         case COMMENT_SPAM:
  1023 				case COMMENT_SPAM:
  1024           $row['comments_spam']++;
  1024 					$row['comments_spam']++;
  1025           break;
  1025 					break;
  1026       }
  1026 			}
  1027     
  1027 		
  1028     $cache[$pathskey] = $row;
  1028 		$cache[$pathskey] = $row;
  1029     return $row;
  1029 		return $row;
  1030   }
  1030 	}
  1031 }
  1031 }
  1032 
  1032 
  1033 /**
  1033 /**
  1034  * The namespaces that use the default handler.
  1034  * The namespaces that use the default handler.
  1035  */
  1035  */