# HG changeset patch # User Dan # Date 1241496626 14400 # Node ID 323c4cd1aa3753ef16984548e6cb2374ba025898 # Parent d52dfa1f08da39aa7ffe5e7a39885e952f874af5 Made some more changes to the way namespaces are handled, for optimization purposes. This is a bit of a structural reorganization: $paths->pages is obsoleted in its entirety; calculating page existence and metadata is now the job of the Namespace_* backend class. There are many things in PageProcessor that should be reorganized, and page actions in general should really be rethought. This is probably the beginning of a long process that will be taking place over the course of the betas. diff -r d52dfa1f08da -r 323c4cd1aa37 includes/dbal.php --- a/includes/dbal.php Mon May 04 23:07:00 2009 -0400 +++ b/includes/dbal.php Tue May 05 00:10:26 2009 -0400 @@ -427,10 +427,24 @@ } function fetchrow($r = false) { - if(!$this->_conn) return false; - if(!$r) $r = $this->latest_result; - if(!$r) $this->_die('$db->fetchrow(): an invalid MySQL resource was passed.'); + if ( !$this->_conn ) + return false; + + if ( !$r ) + $r = $this->latest_result; + + if ( !$r ) + $this->_die('$db->fetchrow(): an invalid MySQL resource was passed.'); + $row = mysql_fetch_assoc($r); + /* + if ( empty($row) ) + { + $GLOBALS['do_gzip'] = false; + echo '
' . enano_debug_print_backtrace(true) . ''; + } + */ + return integerize_array($row); } diff -r d52dfa1f08da -r 323c4cd1aa37 includes/functions.php --- a/includes/functions.php Mon May 04 23:07:00 2009 -0400 +++ b/includes/functions.php Tue May 05 00:10:26 2009 -0400 @@ -380,16 +380,7 @@ global $db, $session, $paths, $template, $plugins; // Common objects $idata = RenderMan::strToPageID($page_id); - $page_id_key = $paths->nslist[ $idata[1] ] . $idata[0]; - $page_id_key = sanitize_page_id($page_id_key); - $page_data = @$paths->pages[$page_id_key]; - $title = ( isset($page_data['name']) ) ? - ( ( $page_data['namespace'] == 'Article' || !$show_ns ) ? - '' : - $paths->nslist[ $idata[1] ] ) - . $page_data['name'] : - ( $show_ns ? $paths->nslist[$idata[1]] : '' ) . str_replace('_', ' ', dirtify_page_id( $idata[0] ) ); - return $title; + return get_page_title_ns($idata[0], $idata[1]); } /** @@ -402,19 +393,9 @@ function get_page_title_ns($page_id, $namespace) { global $db, $session, $paths, $template, $plugins; // Common objects - - $ns_prefix = ( isset($paths->nslist[ $namespace ]) ) ? $paths->nslist[ $namespace ] : $namespace . substr($paths->nslist['Special'], -1); - $page_id_key = $ns_prefix . $page_id; - if ( isPage($page_id_key) ) - { - $page_data = $paths->pages[$page_id_key]; - } - else - { - $page_data = array(); - } - $title = ( isset($page_data['name']) ) ? $page_data['name'] : $ns_prefix . str_replace('_', ' ', dirtify_page_id( $page_id ) ); - return $title; + + $ns = namespace_factory($page_id, $namespace); + return $ns->title; } /** @@ -578,32 +559,24 @@ * @return bool True if the page exists, false otherwise */ -function isPage($p) { +function isPage($p) +{ global $db, $session, $paths, $template, $plugins; // Common objects - - // Try the easy way first ;-) - if ( isset( $paths->pages[ $p ] ) ) - { - return true; - } - - // Special case for Special, Template, and Admin pages that can't have slashes in their URIs - $ns_test = RenderMan::strToPageID( $p ); - - if($ns_test[1] != 'Special' && $ns_test[1] != 'Template' && $ns_test[1] != 'Admin') - { - return false; - } - - $particles = explode('/', $p); - if ( isset ( $paths->pages[ $particles[ 0 ] ] ) ) - { - return true; - } - else - { - return false; - } + static $ispage_cache = array(); + if ( isset($ispage_cache[$p]) ) + return $ispage_cache[$p]; + + list($page_id, $namespace) = RenderMan::strToPageID($p); + $cdata = $paths->get_cdata($page_id, $namespace); + if ( !isset($cdata['page_exists']) ) + { + $class = ( class_exists($_ = "Namespace_$namespace") ) ? $_ : "Namespace_Default"; + $page = new $class($page_id, $namespace); + return $page->exists(); + } + + $ispage_cache[$p] = $cdata['page_exists']; + return $cdata['page_exists']; } /** @@ -615,6 +588,13 @@ function namespace_factory($page_id, $namespace, $revision_id = 0) { + global $db, $session, $paths, $template, $plugins; // Common objects + + static $objcache = array(); + $pathskey = $paths->get_pathskey($page_id, $namespace) . ":$revision_id"; + if ( isset($objcache[$pathskey]) ) + return $objcache[$pathskey]; + if ( !class_exists("Namespace_$namespace") ) { if ( file_exists(ENANO_ROOT . "/includes/namespaces/" . strtolower($namespace) . ".php") ) @@ -626,11 +606,13 @@ { $class = "Namespace_$namespace"; $ns = new $class($page_id, $namespace, $revision_id); + $objcache[$pathskey] = $ns; return $ns; } else { $ns = new Namespace_Default($page_id, $namespace, $revision_id); + $objcache[$pathskey] = $ns; return $ns; } } @@ -915,22 +897,7 @@ function display_page_headers() { - global $db, $session, $paths, $template, $plugins; // Common objects - global $lang; - if($session->get_permissions('vote_reset') && $paths->cpage['delvotes'] > 0) - { - $delvote_ips = unserialize($paths->cpage['delvote_ips']); - $hr = htmlspecialchars(implode(', ', $delvote_ips['u'])); - - $string_id = ( $paths->cpage['delvotes'] == 1 ) ? 'delvote_lbl_votes_one' : 'delvote_lbl_votes_plural'; - $string = $lang->get($string_id, array('num_users' => $paths->cpage['delvotes'])); - - echo '
$message
"; $output->footer(); } + + function set_conds() + { + parent::set_conds(); + + $this->conds['printable'] = false; + $this->conds['adminpage'] = false; + } } diff -r d52dfa1f08da -r 323c4cd1aa37 includes/namespaces/user.php --- a/includes/namespaces/user.php Mon May 04 23:07:00 2009 -0400 +++ b/includes/namespaces/user.php Tue May 05 00:10:26 2009 -0400 @@ -58,13 +58,7 @@ $page_urlname = dirtify_page_id($this->page_id); if ( $this->page_id == $paths->page_id && $this->namespace == $paths->namespace ) - { - $page_name = ( isset($paths->cpage['name']) ) ? $paths->cpage['name'] : $this->page_id; - } - else - { - $page_name = ( isset($paths->pages[$this->page_id]) ) ? $paths->pages[$this->page_id]['name'] : $this->page_id; - } + $page_name = $this->cdata['name']; $target_username = strtr($page_urlname, Array( @@ -80,13 +74,8 @@ { $page_name = $lang->get('userpage_page_title', array('username' => $target_username)); } - else - { - // User has a custom title for their userpage - $page_name = $paths->pages[ $paths->nslist[$this->namespace] . $this->page_id ]['name']; - } - $template->tpl_strings['PAGE_NAME'] = htmlspecialchars($page_name); + $output->set_title($page_name); $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 FROM '.table_prefix.'users u @@ -275,7 +264,7 @@ $parser->assign_bool(array( 'page_exists' => true )); - $page_title = htmlspecialchars($paths->pages[ $c_page_id ]['name']); + $page_title = get_page_title($c_page_id); } else { diff -r d52dfa1f08da -r 323c4cd1aa37 includes/pageprocess.php --- a/includes/pageprocess.php Mon May 04 23:07:00 2009 -0400 +++ b/includes/pageprocess.php Tue May 05 00:10:26 2009 -0400 @@ -181,10 +181,6 @@ if ( !$this->perms->get_permissions('read') ) { - if ( $this->send_headers ) - { - $template->init_vars($this); - } // Permission denied to read page. Is this one of our core pages that must always be allowed? // NOTE: Not even the administration panel will work if ACLs deny access to it. if ( $this->namespace == 'Special' && in_array($this->page_id, array('Login', 'Logout', 'LangExportJSON', 'CSS')) ) @@ -218,10 +214,6 @@ $admin_fail = false; if ( $this->namespace == 'Admin' && strstr($this->page_id, '/') ) { - if ( $this->send_headers ) - { - $template->init_vars($this); - } $this->page_id = substr($this->page_id, 0, strpos($this->page_id, '/')); $funcname = "page_{$this->namespace}_{$this->page_id}"; if ( function_exists($funcname) ) @@ -231,21 +223,19 @@ } if ( isPage($pathskey) ) { - if ( $this->send_headers ) - { - $template->init_vars($this); - } - if ( $paths->pages[$pathskey]['special'] == 1 ) + $cdata = $this->ns->get_cdata(); + + if ( $cdata['special'] == 1 ) { $this->send_headers = false; $strict_no_headers = true; $GLOBALS['output'] = new Output_Naked(); } - if ( isset($paths->pages[$pathskey]['password']) ) + if ( isset($cdata['password']) ) { - if ( $paths->pages[$pathskey]['password'] != '' && $paths->pages[$pathskey]['password'] != sha1('') ) + if ( $cdata['password'] != '' && $cdata['password'] != sha1('') ) { - $password =& $paths->pages[$pathskey]['password']; + $password =& $cdata['password']; if ( $this->password != $password ) { $this->err_wrong_password(); @@ -253,7 +243,7 @@ } } } - if ( isset($paths->pages[$pathskey]['require_admin']) && $paths->pages[$pathskey]['require_admin'] ) + if ( isset($cdata['require_admin']) && $cdata['require_admin'] ) { if ( $session->auth_level < USER_LEVEL_ADMIN ) { @@ -288,11 +278,6 @@ // We are all done. Ship off the page. - if ( $this->send_headers ) - { - $template->init_vars($this); - } - $this->ns->send(); } @@ -325,15 +310,12 @@ { return ''; } - $pathskey = $paths->nslist[ $this->namespace ] . $this->page_id; - if ( isPage($pathskey) ) + $cdata = $this->ns->get_cdata(); + if ( isset($cdata['password']) ) { - if ( isset($paths->pages[$pathskey]['password']) ) + if ( $cdata['password'] != sha1('') && $cdata['password'] !== $this->password && !empty($cdata['password']) ) { - if ( $paths->pages[$pathskey]['password'] != sha1('') && $paths->pages[$pathskey]['password'] !== $this->password && !empty($paths->pages[$pathskey]['password']) ) - { - return false; - } + return false; } } return $this->fetch_text(); @@ -462,9 +444,9 @@ } // Set page_format - $pathskey = $paths->nslist[ $this->namespace ] . $this->page_id; // Using @ due to warning thrown when saving new page - if ( @$paths->pages[ $pathskey ]['page_format'] !== $page_format ) + $cdata = $this->ns->get_cdata(); + if ( @$cdata['page_format'] !== $page_format ) { // Note: no SQL injection to worry about here. Everything that goes into this is sanitized already, barring some rogue plugin. // (and if there's a rogue plugin running, we have bigger things to worry about anyway.) @@ -906,15 +888,7 @@ } // Retrieve page metadata - $pathskey = $paths->nslist[ $this->namespace ] . $this->page_id; - if ( !isPage($pathskey) ) - { - return array( - 'success' => false, - 'error' => 'page_metadata_not_found' - ); - } - $metadata =& $paths->pages[$pathskey]; + $metadata = $this->ns->get_cdata(); // Log the action $username = $db->escape($session->username); @@ -1000,8 +974,7 @@ foreach ( $stack as $oldtarget ) { $url = makeUrlNS($oldtarget[1], $oldtarget[0], 'redirect=no', true); - $page_id_key = $paths->nslist[ $oldtarget[1] ] . $oldtarget[0]; - $page_data = $paths->pages[$page_id_key]; + $page_data = $this->ns->get_cdata(); $title = ( isset($page_data['name']) ) ? $page_data['name'] : $paths->nslist[$oldtarget[1]] . htmlspecialchars( str_replace('_', ' ', dirtify_page_id( $oldtarget[0] ) ) ); $a = '' . $title . ''; $output->add_after_header('' . $lang->get('page_msg_redirected_from', array('from' => $a)) . '' . $lang->get('history_err_wrong_password') . '
'; } } - $wiki = ( ( $paths->pages[$pname]['wiki_mode'] == 2 && getConfig('wiki_mode') == '1') || $paths->pages[$pname]['wiki_mode'] == 1) ? true : false; - $prot = ( ( $paths->pages[$pname]['protected'] == 2 && $session->user_logged_in && $session->reg_time + 60*60*24*4 < time() ) || $paths->pages[$pname]['protected'] == 1) ? true : false; + $wiki = ( ( $cdata['wiki_mode'] == 2 && getConfig('wiki_mode') == '1') || $cdata['wiki_mode'] == 1) ? true : false; + $prot = ( ( $cdata['protected'] == 2 && $session->user_logged_in && $session->reg_time + 60*60*24*4 < time() ) || $cdata['protected'] == 1) ? true : false; $q = 'SELECT log_id,time_id,date_string,page_id,namespace,author,edit_summary,minor_edit FROM ' . table_prefix.'logs WHERE log_type=\'page\' AND action=\'edit\' AND page_id=\'' . $page_id . '\' AND namespace=\'' . $namespace . '\' AND is_draft != 1 ORDER BY time_id DESC;'; if(!$db->sql_query($q)) $db->_die('The history data for the page "' . $paths->cpage['name'] . '" could not be selected.'); @@ -1055,40 +967,8 @@ global $db, $session, $paths, $template, $plugins; // Common objects global $lang; - $pname = $paths->nslist[$namespace] . $page_id; - - $prot = ( ( $paths->pages[$pname]['protected'] == 2 && $session->user_logged_in && $session->reg_time + 60*60*24*4 < time() ) || $paths->pages[$pname]['protected'] == 1) ? true : false; - $wiki = ( ( $paths->pages[$pname]['wiki_mode'] == 2 && getConfig('wiki_mode') == '1') || $paths->pages[$pname]['wiki_mode'] == 1) ? true : false; - - if( empty($name)) - { - return($lang->get('ajax_rename_too_short')); - } - if( ( $session->get_permissions('rename') && ( ( $prot && $session->get_permissions('even_when_protected') ) || !$prot ) ) && ( $paths->namespace != 'Special' && $paths->namespace != 'Admin' )) - { - $e = $db->sql_query('INSERT INTO ' . table_prefix.'logs(time_id,date_string,log_type,action,page_id,namespace,author,edit_summary) VALUES('.time().', \''.enano_date('d M Y h:i a').'\', \'page\', \'rename\', \'' . $db->escape($paths->page_id) . '\', \'' . $paths->namespace . '\', \'' . $db->escape($session->username) . '\', \'' . $db->escape($paths->cpage['name']) . '\')'); - if ( !$e ) - { - $db->_die('The page title could not be updated.'); - } - $e = $db->sql_query('UPDATE ' . table_prefix.'pages SET name=\'' . $db->escape($name) . '\' WHERE urlname=\'' . $db->escape($page_id) . '\' AND namespace=\'' . $db->escape($namespace) . '\';'); - if ( !$e ) - { - $db->_die('The page title could not be updated.'); - } - else - { - $subst = array( - 'page_name_old' => $paths->pages[$pname]['name'], - 'page_name_new' => $name - ); - return $lang->get('ajax_rename_success', $subst); - } - } - else - { - return($lang->get('etc_access_denied')); - } + $page = new PageProcessor($page_id, $namespace); + return $page->rename_page($name); } /** @@ -1120,7 +1000,7 @@ // If the page exists, make a backup of it in case it gets spammed/vandalized // If not, the admin's probably deleting a trash page - if ( isset($paths->pages[ $paths->nslist[$namespace] . $page_id ]) ) + if ( isPage($paths->get_pathskey($page_id, $namespace)) ) { $e = $db->sql_query('SELECT page_text,char_tag FROM ' . table_prefix.'page_text WHERE page_id=\'' . $page_id . '\' AND namespace=\'' . $namespace . '\';'); if(!$e) $db->_die('The current page text could not be selected; as a result, creating the backup of the page failed. Please make a backup copy of the page by clicking Edit this page and then clicking Save Changes.'); @@ -1256,8 +1136,11 @@ return 'The page does not exist.'; } - $cv =& $paths->pages[$pname]['delvotes']; - $ips = $paths->pages[$pname]['delvote_ips']; + $ns = namespace_factory($page_id, $namespace); + $cdata = $ns->get_cdata(); + + $cv =& $cdata['delvotes']; + $ips =& $cdata['delvote_ips']; if ( empty($ips) ) { @@ -1424,10 +1307,15 @@ $cat_current[] = $r; } $db->free_result(); - $cat_all = Array(); - foreach ( $paths->pages as $i => $_ ) + + $cat_all = array(); + $q = $db->sql_query('SELECT * FROM ' . table_prefix . 'pages WHERE namespace = \'Category\';'); + if ( !$q ) + $db->_die(); + + while ( $row = $db->fetchrow() ) { - if($paths->pages[$i]['namespace']=='Category') $cat_all[] = $paths->pages[$i]; + $cat_all[] = Namespace_Default::bake_cdata($row); } // Make $cat_all an associative array, like $paths->pages @@ -1498,12 +1386,17 @@ if(!$session->get_permissions('edit_cat')) return('Insufficient privileges to change category information'); $page_perms = $session->fetch_page_acl($page_id, $namespace); - $page_data =& $paths->pages[$paths->nslist[$namespace].$page_id]; + $ns = namespace_factory($page_id, $namespace); + $page_data = $ns->get_cdata(); - $cat_all = Array(); - foreach ( $paths->pages as $i => $_ ) + $cat_all = array(); + $q = $db->sql_query('SELECT * FROM ' . table_prefix . 'pages WHERE namespace = \'Category\';'); + if ( !$q ) + $db->_die(); + + while ( $row = $db->fetchrow() ) { - if($paths->pages[$i]['namespace']=='Category') $cat_all[] = $paths->pages[$i]; + $cat_all[] = Namespace_Default::bake_cdata($row); } // Make $cat_all an associative array, like $paths->pages @@ -1597,13 +1490,16 @@ global $db, $session, $paths, $template, $plugins; // Common objects global $lang, $cache; // Determine permissions - if($paths->pages[$paths->nslist[$namespace].$page_id]['password'] != '') + $ns = namespace_factory($page_id, $namespace); + $cdata = $ns->get_cdata(); + if ( $cdata['password'] != '' ) $a = $session->get_permissions('password_reset'); else $a = $session->get_permissions('password_set'); - if(!$a) + if ( !$a ) return $lang->get('etc_access_denied'); - if(!isset($pass)) return('Password was not set on URL'); + if ( !isset($pass) ) + return('Password was not set on URL'); $p = $pass; if ( !preg_match('#([0-9a-f]){40,40}#', $p) ) { @@ -1617,7 +1513,6 @@ { die('PageUtils::setpass(): Error during update query: '.$db->get_error()."\n\nSQL Backtrace:\n".$db->sql_backtrace()); } - $cache->purge('page_meta'); // Is the new password blank? if ( $p == '' ) { diff -r d52dfa1f08da -r 323c4cd1aa37 includes/paths.php --- a/includes/paths.php Mon May 04 23:07:00 2009 -0400 +++ b/includes/paths.php Tue May 05 00:10:26 2009 -0400 @@ -163,30 +163,6 @@ eval($cmd); } - if ( $page_cache = $cache->fetch('page_meta') ) - { - $this->pages = array_merge($this->pages, $page_cache); - } - else - { - $e = $db->sql_query('SELECT name,urlname,namespace,special,visible,comments_on,protected,delvotes,' . "\n" - . ' delvote_ips,wiki_mode,password,page_format FROM '.table_prefix.'pages ORDER BY name;'); - - if( !$e ) - { - $db->_die('The error seems to have occured while selecting the page information. File: includes/paths.php; line: '.__LINE__); - } - while($r = $db->fetchrow()) - { - $r = $this->calculate_metadata_from_row($r); - - $this->pages[$r['urlname']] = $r; - $this->pages[] =& $this->pages[$r['urlname']]; - } - - $this->update_metadata_cache(); - } - $db->free_result(); if ( defined('ENANO_INTERFACE_INDEX') || defined('ENANO_INTERFACE_AJAX') || defined('IN_ENANO_UPGRADE') ) { $title = $this->parse_url(false); @@ -391,6 +367,39 @@ $session->init_permissions(); } + /** + * Fetch cdata (metadata) for a page. + * @param string Page ID + * @param string Namespace + * @return array + */ + + function get_cdata($page_id, $namespace) + { + global $db, $session, $paths, $template, $plugins; // Common objects + + $pathskey = $this->get_pathskey($page_id, $namespace); + if ( isset($this->pages[$pathskey]) ) + return $this->pages[$pathskey]; + + $page = namespace_factory($page_id, $namespace); + $cdata = $page->get_cdata(); + + $this->pages[$pathskey] = $cdata; + return $cdata; + } + + /** + * For a given page ID and namespace, generate a flat string that can be used to access $paths->pages. + * @param string Page ID + * @param string Namespace + */ + + function get_pathskey($page_id, $namespace) + { + return ( isset($this->nslist[$namespace]) ) ? "{$this->nslist[$namespace]}{$page_id}" : "{$namespace}:{$page_id}"; + } + function add_page($flags) { global $lang; @@ -404,10 +413,9 @@ } $flags['require_admin'] = ( $flags['namespace'] === 'Admin' ); + $flags['page_exists'] = true; - $pages_len = sizeof($this->pages) / 2; - $this->pages[$pages_len] = $flags; - $this->pages[$flags['urlname']] =& $this->pages[$pages_len]; + $this->pages[$flags['urlname']] = $flags; } function main_page() @@ -564,7 +572,7 @@ $title = $this->parse_url(false); list(, $ns) = RenderMan::strToPageID($title); $title = substr($title, strlen($this->nslist[$ns])); - $regex = '/^' . str_replace('/', '\\/', preg_quote($this->nslist[$this->namespace])) . '\\/?/'; + $regex = '/^' . str_replace('/', '\\/', preg_quote($this->nslist[$ns])) . '\\/?/'; $title = preg_replace($regex, '', $title); $title = explode('/', $title); $id = $id + 1; @@ -604,42 +612,14 @@ } /** - * Updates the cache containing all page metadata. + * Deprecated. */ function update_metadata_cache() { global $db, $session, $paths, $template, $plugins; // Common objects - if ( getConfig('cache_thumbs') != '1' ) - return false; - - $e = $db->sql_unbuffered_query('SELECT name,urlname,namespace,special,visible,comments_on,protected,delvotes,' . "\n" - . ' delvote_ips,wiki_mode,password,page_format FROM '.table_prefix.'pages ORDER BY name;'); - if ( !$e ) - $db->_die(); - - $md_array = array(); - - while ( $row = $db->fetchrow() ) - { - $row = $this->calculate_metadata_from_row($row); - $md_array[$row['urlname']] = $row; - } - - // import cache functions - global $cache; - - // store data (TTL 20 minutes) - try - { - $cache->store('page_meta', $md_array, 20); - } - catch ( Exception $e ) - { - } - - return true; + return false; } /** @@ -650,34 +630,7 @@ function calculate_metadata_from_row($r) { - $r['urlname_nons'] = $r['urlname']; - if ( isset($this->nslist[$r['namespace']]) ) - { - $r['urlname'] = $this->nslist[$r['namespace']] . $r['urlname']; // Applies the User:/File:/etc prefixes to the URL names - } - else - { - $ns_char = substr($this->nslist['Special'], -1); - $r['urlname'] = $r['namespace'] . $ns_char . $r['urlname']; - } - - if ( $r['delvotes'] == null) - { - $r['delvotes'] = 0; - } - if ( $r['protected'] == 0 || $r['protected'] == 1 ) - { - $r['really_protected'] = (int)$r['protected']; - } - else if ( $r['protected'] == 2 && getConfig('wiki_mode') == '1') - { - $r['really_protected'] = 1; - } - else if ( $r['protected'] == 2 && getConfig('wiki_mode') == '0' ) - { - $r['really_protected'] = 0; - } - return $r; + return Namespace_Default::bake_cdata($r); } /** @@ -838,7 +791,6 @@ $db->_die(); $sha1_blank = sha1(''); - $query_func = ( ENANO_DBLAYER == 'MYSQL' ) ? 'mysql_query' : 'pg_query'; // // Index $pages_in_batch pages at a time @@ -1082,65 +1034,6 @@ } /** - * Creates an instance of the Searcher class, including index info - * @return object - */ - - function makeSearcher($match_case = false) - { - global $db, $session, $paths, $template, $plugins; // Common objects - $search = new Searcher(); - $q = $db->sql_query('SELECT word,page_names FROM '.table_prefix.'search_index;'); - if(!$q) - { - echo $db->get_error(); - return false; - } - $idx = Array(); - while($row = $db->fetchrow($q)) - { - $row['word'] = rtrim($row['word'], "\0"); - $idx[$row['word']] = $row['page_names']; - } - $db->free_result(); - $search->index = $idx; - if($match_case) - $search->match_case = true; - return $search; - } - - /** - * Creates an associative array filled with the values of all the page titles - * @return array - */ - - function get_page_titles() - { - $texts = Array(); - for ( $i = 0; $i < sizeof($this->pages) / 2; $i++ ) - { - $texts[$this->pages[$i]['urlname']] = $this->pages[$i]['name']; - } - return $texts; - } - - /** - * Creates an instance of the Searcher class, including index info for page titles - * @return object - */ - - function makeTitleSearcher($match_case = false) - { - global $db, $session, $paths, $template, $plugins; // Common objects - $search = new Searcher(); - $texts = $this->get_page_titles(); - $search->buildIndex($texts); - if($match_case) - $search->match_case = true; - return $search; - } - - /** * Returns a list of groups that a given page is a member of. * @param string Page ID * @param string Namespace diff -r d52dfa1f08da -r 323c4cd1aa37 includes/plugins.php --- a/includes/plugins.php Mon May 04 23:07:00 2009 -0400 +++ b/includes/plugins.php Tue May 05 00:10:26 2009 -0400 @@ -96,6 +96,7 @@ { if ( in_array($plugin, $this->system_plugins) ) continue; + if ( $this->loaded_plugins[$plugin]['status'] & PLUGIN_OUTOFDATE ) { // it's out of date, don't load diff -r d52dfa1f08da -r 323c4cd1aa37 includes/render.php --- a/includes/render.php Mon May 04 23:07:00 2009 -0400 +++ b/includes/render.php Tue May 05 00:10:26 2009 -0400 @@ -55,7 +55,7 @@ public static function getTemplate($id, $parms) { global $db, $session, $paths, $template, $plugins; // Common objects - if(!isset($paths->pages[$paths->nslist['Template'].$id])) + if ( !isPage($paths->get_pathskey($id, 'Template')) ) { return '[['.$paths->nslist['Template'].$id.']]'; } @@ -65,7 +65,8 @@ } else { - $text = RenderMan::getPage($id, 'Template', 0, true, true, 0); + $page = new PageProcessor($id, 'Template'); + $text = $page->fetch_text(); $paths->template_cache[$id] = $text; } @@ -95,7 +96,7 @@ { global $db, $session, $paths, $template, $plugins; // Common objects $fetch_ns = 'Template'; - if(!isset($paths->pages[$paths->nslist['Template'].$id])) + if ( !isPage($paths->get_pathskey($id, 'Template')) ) { // Transclusion of another page // 1.1.5: Now You, Too, Can Be A Template, Even If You're Just A Plain Old Article! (TM) diff -r d52dfa1f08da -r 323c4cd1aa37 includes/search.php --- a/includes/search.php Mon May 04 23:07:00 2009 -0400 +++ b/includes/search.php Tue May 05 00:10:26 2009 -0400 @@ -251,16 +251,15 @@ $inc = 1; // Is this search term present in the page's title? If so, give extra points - preg_match("/^ns=$ns_list;pid=(.+)$/", $match, $piecesparts); - $pathskey = $paths->nslist[ $piecesparts[1] ] . sanitize_page_id($piecesparts[2]); - if ( isPage($pathskey) ) + preg_match("/^ns=$ns_list;pid=(.+)$/", $pages, $piecesparts); + $title = get_page_title_ns($piecesparts[2], $piecesparts[1]); + + $test_func = ( $case_sensitive ) ? 'strstr' : 'stristr'; + if ( $test_func($title, $row['word']) || $test_func($piecesparts[2], $row['word']) ) { - $test_func = ( $case_sensitive ) ? 'strstr' : 'stristr'; - if ( $test_func($paths->pages[$pathskey]['name'], $row['word']) || $test_func($paths->pages[$pathskey]['urlname_nons'], $row['word']) ) - { - $inc = 1.5; - } + $inc = 1.5; } + if ( isset($scores[$match]) ) { $scores[$match] = $scores[$match] + $inc; @@ -392,20 +391,15 @@ $inc = 1; // Is this search term present in the page's title? If so, give extra points - preg_match("/^ns=$ns_list;pid=(.+)$/", $id, $piecesparts); - $pathskey = $paths->nslist[ $piecesparts[1] ] . sanitize_page_id($piecesparts[2]); - if ( isPage($pathskey) ) + preg_match("/^ns=$ns_list;pid=(.+)$/", $pages, $piecesparts); + $title = get_page_title_ns($piecesparts[2], $piecesparts[1]); + + $test_func = ( $case_sensitive ) ? 'strstr' : 'stristr'; + if ( $test_func($title, $row['word']) || $test_func($piecesparts[2], $row['word']) ) { - $test_func = ( $case_sensitive ) ? 'strstr' : 'stristr'; - foreach ( array_merge($query_phrase['any'], $query_phrase['req']) as $term ) - { - if ( $test_func($paths->pages[$pathskey]['name'], $term) || $test_func($paths->pages[$pathskey]['urlname_nons'], $term) ) - { - $inc = 1.5; - break; - } - } + $inc = 1.5; } + if ( isset($scores[$id]) ) { $scores[$id] = $scores[$id] + $inc; diff -r d52dfa1f08da -r 323c4cd1aa37 includes/sessions.php --- a/includes/sessions.php Mon May 04 23:07:00 2009 -0400 +++ b/includes/sessions.php Tue May 05 00:10:26 2009 -0400 @@ -670,7 +670,7 @@ $captcha_good = true; } } - if ( $policy != 'disable' && !$captcha_good ) + if ( $lockout_data['lockout_policy'] != 'disable' && !$captcha_good ) { if ( $lockout_data['lockout_fails'] >= $lockout_data['lockout_threshold'] ) { @@ -2929,12 +2929,6 @@ return $objcache[$namespace][$page_id]; } - //if ( !isset( $paths->pages[$paths->nslist[$namespace] . $page_id] ) ) - //{ - // // Page does not exist - // return false; - //} - $objcache[$namespace][$page_id] = new Session_ACLPageInfo( $page_id, $namespace, $this->acl_types, $this->acl_descs, $this->acl_deps, $this->acl_base_cache ); $object =& $objcache[$namespace][$page_id]; @@ -4384,12 +4378,11 @@ $this->namespace = $namespace; $pathskey = $paths->nslist[$this->namespace].sanitize_page_id($this->page_id); - $ppwm = 2; - if ( isset($paths->pages[$pathskey]) ) - { - if ( isset($paths->pages[$pathskey]['wiki_mode']) ) - $ppwm = $paths->pages[$pathskey]['wiki_mode']; - } + $ns = namespace_factory($this->page_id, $this->namespace); + $cdata = $ns->get_cdata(); + $ppwm = $cdata['wiki_mode']; + unset($ns, $cdata); + if ( $ppwm == 1 && ( $session->user_logged_in || getConfig('wiki_mode_require_login') != '1' ) ) $this->wiki_mode = true; else if ( $ppwm == 1 && !$session->user_logged_in && getConfig('wiki_mode_require_login') == '1' ) diff -r d52dfa1f08da -r 323c4cd1aa37 includes/stats.php --- a/includes/stats.php Mon May 04 23:07:00 2009 -0400 +++ b/includes/stats.php Tue May 05 00:10:26 2009 -0400 @@ -65,25 +65,9 @@ while ( $row = $db->fetchrow() ) { - if ( isset($paths->pages[ $paths->nslist[ $row['namespace'] ] . $row['page_id'] ]) ) - { - $page_data =& $paths->pages[ $paths->nslist[ $row['namespace'] ] . $row['page_id'] ]; - $title = $page_data['name']; - $page_id = $page_data['urlname']; - } - else if ( !isset($paths->nslist[$row['namespace']]) ) - { - $title = $row['namespace'] . ':' . $row['page_id']; - $page_id = sanitize_page_id($title); - } - else - { - $title = dirtify_page_id( $paths->nslist[$row['namespace']] . $row['page_id'] ); - $title = str_replace('_', ' ', $title); - $page_id = sanitize_page_id($title); - } + $title = get_page_title_ns($row['page_id'], $row['namespace']); $data[] = array( - 'page_urlname' => $page_id, + 'page_urlname' => $paths->get_pathskey($row['page_id'], $row['namespace']), 'page_title' => $title, 'num_hits' => $row['num_hits'] ); diff -r d52dfa1f08da -r 323c4cd1aa37 includes/template.php --- a/includes/template.php Mon May 04 23:07:00 2009 -0400 +++ b/includes/template.php Tue May 05 00:10:26 2009 -0400 @@ -14,12 +14,27 @@ class template { - var $tpl_strings, $tpl_bool, $vars_assign_history, $theme, $style, $no_headers, $additional_headers, $sidebar_extra, $sidebar_widgets, $toolbar_menu, $theme_list, $named_theme_list, $default_theme, $default_style, $plugin_blocks, $plugin_blocks_content, $namespace_string, $style_list, $theme_loaded, $initted_to_page_id, $initted_to_namespace; + var $tpl_strings, $tpl_bool, $vars_assign_history, $theme, $style, $no_headers, $additional_headers, $sidebar_extra, $sidebar_widgets, $toolbar_menu, $theme_list, $named_theme_list, $default_theme, $default_style, $plugin_blocks, $plugin_blocks_content, $namespace_string, $style_list, $theme_loaded; + + var $theme_initted = false; + var $page_initted = false; + var $elements = false; + var $page_id = false; + var $namespace = false; - var $initted_to_theme = array( - 'theme' => false, - 'style' => false - ); + /** + * Page action conditions + * @var array + */ + + var $conds = array(); + + /** + * The PageProcessor for the current page + * @var object + */ + + var $page = false; /** * The list of themes that are critical for Enano operation. This doesn't include oxygen which @@ -287,7 +302,7 @@ function sidebar_widget($t, $h, $use_normal_section = false) { global $db, $session, $paths, $template, $plugins; // Common objects - if(!defined('ENANO_TEMPLATE_LOADED')) + if ( !$this->theme_loaded ) { $this->load_theme($session->theme, $session->style); } @@ -365,141 +380,65 @@ } /** - * Initializes all variables related to on-page content. This includes sidebars and what have you. - * @param object Optional PageProcessor object to use for passing metadata and permissions on. If omitted, uses information from $paths and $session. - * @param bool If true, re-inits even if already initted with this page_id and namespace + * Change the theme we're supposed to display. + * @param string Theme name + * @param string Style name; optional + */ + + function set_theme($theme = false, $style = false) + { + $this->theme_initted = false; + $this->load_theme($theme, $style); + } + + /** + * Change the page we're supposed to generate for + * @param mixed Page ID *or* PageProcessor. If a PageProcessor, pulls permission info and such from that; if not, starts a PageProcessor. YOU SHOULD USE A PageProcessor WHENEVER POSSIBLE! It improves efficiency. + * @param string Namespace; not required if including a PageProcessor. */ - function init_vars($page = false, $force_init = false) + function set_page($page_id_or_pp, $namespace = false) { - global $db, $session, $paths, $template, $plugins; // Common objects - global $email; - global $lang; - - if(!$this->theme || !$this->style) + if ( is_object($page_id_or_pp) && get_class($page_id_or_pp) === 'PageProcessor' ) { - $this->load_theme(); - } - - if ( defined('ENANO_TEMPLATE_LOADED') ) - { - // trigger_error("\$template->init_vars() called more than once", E_USER_WARNING); - // die_semicritical('Illegal call', '$template->init_vars() was called multiple times, this is not supposed to happen. Exiting with fatal error.
'); - } - else - { - @define('ENANO_TEMPLATE_LOADED', ''); + $this->page_initted = false; + $page =& $page_id_or_pp; + $this->page = $page; + $this->page_id = $page->page_id; + $this->namespace = $page->namespace; } - - if ( is_object($page) && ( @get_class($page) == 'PageProcessor' || preg_match('/^Namespace_/', @get_class($page)) ) ) + else if ( is_string($page_id_or_pp) ) { - $page_append = substr($paths->fullpage, strlen($paths->page)); - if ( isset($paths->nslist[$page->namespace]) ) - { - $local_page = $paths->nslist[$page->namespace] . $page->page_id; - } - else - { - $local_page = $page->namespace . substr($paths->nslist['Special'], -1) . $page->page_id . $page_append; - } - $local_fullpage = $local_page . $page_append; - $local_page_id =& $page->page_id; - $local_namespace =& $page->namespace; - $local_page_exists = $page->exists(); - $perms =& $page->perms; - if ( !is_object($perms) ) - { - unset($perms); - $perms = $session->fetch_page_acl($local_page_id, $local_namespace); - } + if ( !is_string($namespace) ) + return false; + + if ( $page_id_or_pp === $this->page_id && $namespace === $this->namespace ) + return true; + + $this->page_initted = false; + $this->page = false; + $this->page_id = sanitize_page_id($page_id_or_pp); + $this->namespace = $namespace; } else { - $local_page =& $paths->page; - $local_page_id =& $paths->page_id; - $local_fullpage =& $paths->fullpage; - $local_namespace =& $paths->namespace; - $local_page_exists =& $paths->page_exists; - $local_page_protected =& $paths->page_protected; - $perms =& $session; - } - - if ( $local_page_id === $this->initted_to_page_id && $local_namespace === $this->initted_to_namespace && $this->theme === $this->initted_to_theme['theme'] && $this->style === $this->initted_to_theme['style'] && !$force_init ) - { - // we're already initted with this page. - return true; - } - - profiler_log("template: starting var init"); - - $this->initted_to_page_id = $local_page_id; - $this->initted_to_namespace = $local_namespace; - $this->initted_to_theme = array( - 'theme' => $this->theme, - 'style' => $this->style - ); - - require(ENANO_ROOT . "/themes/{$this->theme}/theme.cfg"); - - if ( $local_page_exists && isPage($local_page) ) - { - $local_cdata =& $paths->pages[$local_page]; + return false; } - else - { - // if the page doesn't exist but we're trying to load it, it was requested manually and $paths->cpage should match it. - if ( $paths->page_id == $local_page_id ) - { - // load metadata from cpage - $local_cdata =& $paths->cpage; - } - else - { - // generate our own failsafe metadata - $local_cdata = array( - 'urlname' => $local_page, - 'urlname_nons' => $local_page_id, - 'namespace' => $local_namespace, - 'name' => get_page_title_ns($local_page_id, $local_namespace), - 'comments_on' => 0, - 'protected' => 0, - 'wiki_mode' => 2, - 'delvotes' => 0, - 'delvote_ips' => serialize(array()) - ); - } - } + return true; + } + + /** + * Global, only-called-once init. Goes to all themes. + */ + + function init_global_vars() + { + global $db, $session, $paths, $template, $plugins; // Common objects + global $lang; + global $email; - // calculate protection - if ( !isset($local_page_protected) ) - { - if ( $local_cdata['protected'] == 0 ) - { - $local_page_protected = false; - } - else if ( $local_cdata['protected'] == 1 ) - { - $local_page_protected = true; - } - else if ( $local_cdata['protected'] == 2 ) - { - if ( - ( !$session->user_logged_in || // Is the user logged in? - ( $session->user_logged_in && $session->reg_time + ( 4 * 86400 ) >= time() ) ) // If so, have they been registered for 4 days? - && !$perms->get_permissions('even_when_protected') ) // And of course, is there an ACL that overrides semi-protection? - { - $local_page_protected = true; - } - else - { - $local_page_protected = false; - } - } - } - - $tplvars = $this->extract_vars('elements.tpl'); - - if(isset($_SERVER['HTTP_USER_AGENT']) && strstr($_SERVER['HTTP_USER_AGENT'], 'MSIE')) + // IE PNG fixing code + if ( isset($_SERVER['HTTP_USER_AGENT']) && strstr($_SERVER['HTTP_USER_AGENT'], 'MSIE') ) { $this->add_header('