# HG changeset patch # User Dan # Date 1187118820 14400 # Node ID 8079b0288e8e1a937b9ccc68920c4d0d0657ad55 # Parent 9d29f7e101d69b74ce805ceadb1c025f62af9ebb Added ability to detag deleted pages diff -r 9d29f7e101d6 -r 8079b0288e8e ajax.php diff -r 9d29f7e101d6 -r 8079b0288e8e includes/clientside/css/enano-shared.css --- a/includes/clientside/css/enano-shared.css Sun Aug 12 14:56:52 2007 -0400 +++ b/includes/clientside/css/enano-shared.css Tue Aug 14 15:13:40 2007 -0400 @@ -150,6 +150,8 @@ padding-right: 5px; } +div.breadcrumbs { margin: 10px 0; padding: 5px; border: 1px solid #AAAAAA; background-color: #E8E8E8; font-size: smaller; font-weight: bold; } + /* Tables */ .tblholder { margin: 10px 0 0 0; padding: 0; border: 1px solid #AAAAAA; background-color: #E8E8E8; } diff -r 9d29f7e101d6 -r 8079b0288e8e includes/dbal.php --- a/includes/dbal.php Sun Aug 12 14:56:52 2007 -0400 +++ b/includes/dbal.php Tue Aug 14 15:13:40 2007 -0400 @@ -83,8 +83,17 @@ $bt = $this->latest_query; // $this->sql_backtrace(); $e = htmlspecialchars(mysql_error()); if($e=='') $e='<none>'; - if(defined('ENANO_CONFIG_FETCHED')) die_semicritical('Database error', '

An error occurred during a database query.

'.$t.'
Error returned by MySQL: '.$e.'
SQL Backtrace:

'.$bt.'
'); - else grinding_halt('Database error', '

An error occurred during a database query.

'.$t.'
Error returned by MySQL: '.$e.'
SQL Backtrace:

'.$bt.'
'); + $t = ( !empty($t) ) ? $t : '<No error description provided>'; + global $email; + $email_info = ( defined('ENANO_CONFIG_FETCHED') && is_object($email) ) ? ', at <' . $email->jscode() . $email->encryptEmail(getConfig('contact_email')) . '>' : ''; + $internal_text = '

The site was unable to finish serving your request.

+

We apologize for the inconveience, but an error occurred in the Enano database layer. Please report the full text of this page to the administrator of this site' . $email_info . '.

+

Description or location of error: '.$t.'
+ Error returned by MySQL extension: ' . $e . '
+ Most recent SQL query:

+
'.$bt.'
'; + if(defined('ENANO_CONFIG_FETCHED')) die_semicritical('Database error', $internal_text); + else grinding_halt('Database error', $internal_text); exit; } @@ -101,8 +110,15 @@ $bt = $this->sql_backtrace(); $e = htmlspecialchars(mysql_error()); if($e=='') $e='<none>'; - $text = '

An error occurred during a database query.

'.$t.'
Error returned by MySQL: '.$e.'
SQL Backtrace:

'.$bt.'
'; - return $text; + global $email; + $email_info = ( defined('ENANO_CONFIG_FETCHED') && is_object($email) ) ? ', at <' . $email->jscode() . $email->encryptEmail(getConfig('contact_email')) . '>' : ''; + $internal_text = '

The site was unable to finish serving your request.

+

We apologize for the inconveience, but an error occurred in the Enano database layer. Please report the full text of this page to the administrator of this site' . $email_info . '.

+

Description or location of error: '.$t.'
+ Error returned by MySQL extension: ' . $e . '
+ Most recent SQL query:

+
'.$bt.'
'; + return $internal_text; } function connect() { diff -r 9d29f7e101d6 -r 8079b0288e8e includes/functions.php --- a/includes/functions.php Sun Aug 12 14:56:52 2007 -0400 +++ b/includes/functions.php Tue Aug 14 15:13:40 2007 -0400 @@ -71,6 +71,7 @@ global $db, $session, $paths, $template, $plugins; // Common objects $flags = ''; $sep = urlSeparator; + $t = sanitize_page_id($t); if ( isset($_GET['printable'] ) ) { $flags .= $sep . 'printable=yes'; @@ -226,17 +227,24 @@ /** * Tells you the title for the given page ID string * @param string Page ID string (ex: Special:Administration) + * @param bool Optional. If true, and if the namespace turns out to be something other than Article, the namespace prefix will be prepended to the return value. * @return string */ -function get_page_title($page_id) +function get_page_title($page_id, $show_ns = true) { 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' ? '' : $paths->nslist[ $idata[1] ] ) . $page_data['name'] : $paths->nslist[$idata[1]] . str_replace('_', ' ', dirtify_page_id( $idata[0] ) ); + $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; } diff -r 9d29f7e101d6 -r 8079b0288e8e includes/pageprocess.php --- a/includes/pageprocess.php Sun Aug 12 14:56:52 2007 -0400 +++ b/includes/pageprocess.php Tue Aug 14 15:13:40 2007 -0400 @@ -212,7 +212,7 @@ return false; } } - else if ( $this->namespace == 'User' ) + else if ( $this->namespace == 'User' && strpos($this->page_id, '/') === false ) { $this->_handle_userpage(); } @@ -371,6 +371,8 @@ global $db, $session, $paths, $template, $plugins; // Common objects $text = $this->fetch_text(); + $text = preg_replace('/([\s]*)__NOBREADCRUMBS__([\s]*)/', '', $text); + $text = preg_replace('/([\s]*)__NOTOC__([\s]*)/', '', $text); $redir_enabled = false; if ( preg_match('/^#redirect \[\[([^\]]+?)\]\]/i', $text, $match ) ) @@ -418,6 +420,7 @@ $template->tpl_strings['PAGE_NAME'] = htmlspecialchars( $this->title ); $this->header(); + $this->do_breadcrumbs(); if ( $_errormsg ) { @@ -631,6 +634,8 @@ )); $target_username = preg_replace('/^' . preg_quote($paths->nslist['User']) . '/', '', $target_username); + $target_username = explode('/', $target_username); + $target_username = $target_username[0]; if ( ( $page_name == str_replace('_', ' ', $this->page_id) || $page_name == $paths->nslist['User'] . str_replace('_', ' ', $this->page_id) ) || !$this->page_exists ) { @@ -1044,8 +1049,11 @@ { global $db, $session, $paths, $template, $plugins; // Common objects + header('HTTP/1.1 404 Not Found'); + $this->header(); - header('HTTP/1.1 404 Not Found'); + $this->do_breadcrumbs(); + if ( $userpage ) { echo '

There is no page with this title yet.

@@ -1078,6 +1086,10 @@ } $db->free_result(); } + if ( $session->user_level >= USER_LEVEL_ADMIN ) + { + echo '

Additional admin options: detag page

'; + } echo '

HTTP Error: 404 Not Found

'; @@ -1085,6 +1097,58 @@ } /** + * Echoes out breadcrumb data, if appropriate. + * @access private + */ + + function do_breadcrumbs() + { + global $db, $session, $paths, $template, $plugins; // Common objects + if ( strpos($this->text_cache, '__NOBREADCRUMBS__') !== false ) + return false; + $breadcrumb_data = explode('/', $this->page_id); + if ( count($breadcrumb_data) > 1 ) + { + echo ' + + + '; + } + } + + /** * PHP 4 constructor. * @see PageProcessor::__construct() */ diff -r 9d29f7e101d6 -r 8079b0288e8e includes/render.php --- a/includes/render.php Sun Aug 12 14:56:52 2007 -0400 +++ b/includes/render.php Tue Aug 14 15:13:40 2007 -0400 @@ -408,7 +408,7 @@ function sanitize_html($text) { $text = htmlspecialchars($text); - $allowed_tags = Array('b', 'i', 'u', 'pre', 'code', 'tt', 'br', 'p', 'nowiki', '!--([^.]+)--'); + $allowed_tags = Array('b', 'i', 'u', 'pre', 'code', 'tt', 'br', 'p', 'nowiki', '!--([\w\W]+)--'); foreach($allowed_tags as $t) { $text = preg_replace('#<'.$t.'>(.*?)</'.$t.'>#is', '<'.$t.'>\\1', $text); @@ -418,6 +418,52 @@ return $text; } + /** + * Parses internal links (wikilinks) in a block of text. + * @param string Text to process + * @return string + */ + + function parse_internal_links($text) + { + + // stage 1 - links with alternate text + preg_match_all('/\[\[([^\[\]<>\{\}\|]+)\|(.+?)\]\]/', $text, $matches); + foreach ( $matches[0] as $i => $match ) + { + list($page_id, $namespace) = RenderMan::strToPageID($matches[1][$i]); + $pid_clean = $paths->nslist[$namespace] . sanitize_page_id($page_id); + + $url = makeUrl($pid_clean, false, true); + $inner_text = $matches[2][$i]; + $quot = '"'; + $exists = ( isPage($pid_clean) ) ? '' : ' class="wikilink-nonexistent"'; + + $link = "{$inner_text}"; + + $text = str_replace($match, $link, $text); + } + + // stage 2 - links with no alternate text + preg_match_all('/\[\[([^\[\]<>\{\}\|]+)\]\]/', $text, $matches); + foreach ( $matches[0] as $i => $match ) + { + list($page_id, $namespace) = RenderMan::strToPageID($matches[1][$i]); + $pid_clean = $paths->nslist[$namespace] . sanitize_page_id($page_id); + + $url = makeUrl($matches[1][$i], false, true); + $inner_text = htmlspecialchars(get_page_title($pid_clean)); + $quot = '"'; + $exists = ( isPage($pid_clean) ) ? '' : ' class="wikilink-nonexistent"'; + + $link = "{$inner_text}"; + + $text = str_replace($match, $link, $text); + } + + return $text; + } + /* * * Replaces template inclusions with the templates * @param string $message The text to format diff -r 9d29f7e101d6 -r 8079b0288e8e includes/template.php --- a/includes/template.php Sun Aug 12 14:56:52 2007 -0400 +++ b/includes/template.php Tue Aug 14 15:13:40 2007 -0400 @@ -732,7 +732,7 @@ 'ADMIN_SID_AMP_HTML'=>$ash, 'ADMIN_SID_AUTO'=>$as2, 'ADDITIONAL_HEADERS'=>$this->additional_headers, - 'COPYRIGHT'=>getConfig('copyright_notice'), + 'COPYRIGHT'=>RenderMan::parse_internal_links(getConfig('copyright_notice')), 'TOOLBAR_EXTRAS'=>$this->toolbar_menu, 'REQUEST_URI'=>$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'], 'STYLE_LINK'=>makeUrlNS('Special', 'CSS'.$p, null, true), //contentPath.$paths->nslist['Special'].'CSS' . $p, @@ -1672,6 +1672,7 @@ global $db, $session, $paths, $template, $plugins; // Common objects if(!$this->no_headers) { global $_starttime; + $f = microtime(true); $f = $f - $_starttime; $f = round($f, 4); @@ -1681,6 +1682,9 @@ $dbg = 'Time: '.$f.'s | Queries: '.$nq; $t = $this->process_template('footer.tpl'); $t = str_replace('[[Stats]]', $dbg, $t); + $t = str_replace('[[NumQueries]]', (string)$db->num_queries, $t); + $t = str_replace('[[GenTime]]', (string)$f, $t); + echo $t; } else return ''; diff -r 9d29f7e101d6 -r 8079b0288e8e index.php --- a/index.php Sun Aug 12 14:56:52 2007 -0400 +++ b/index.php Tue Aug 14 15:13:40 2007 -0400 @@ -359,6 +359,20 @@ echo PageUtils::pagediff($paths->cpage['urlname_nons'], $paths->namespace, $id1, $id2); $template->footer(); break; + case 'detag': + if ( $session->user_level < USER_LEVEL_ADMIN ) + { + die_friendly('Access denied', '

You need to be an administrator to detag pages.

'); + } + if ( $paths->page_exists ) + { + die_friendly('Invalid request', '

The detag action is only valid for pages that have been deleted in the past.

'); + } + $q = $db->sql_query('DELETE FROM '.table_prefix.'tags WHERE page_id=\'' . $db->escape($paths->cpage['urlname_nons']) . '\' AND namespace=\'' . $paths->namespace . '\';'); + if ( !$q ) + $db->_die('Detag query, index.php:'.__LINE__); + die_friendly('Page detagged', '

All stale tags have been removed from this page.

'); + break; case 'aclmanager': $data = ( isset($_POST['data']) ) ? $_POST['data'] : Array('mode' => 'listgroups'); PageUtils::aclmanager($data); diff -r 9d29f7e101d6 -r 8079b0288e8e install.php diff -r 9d29f7e101d6 -r 8079b0288e8e plugins/SpecialPageFuncs.php diff -r 9d29f7e101d6 -r 8079b0288e8e schema.sql diff -r 9d29f7e101d6 -r 8079b0288e8e themes/oxygen/css/bleu.css --- a/themes/oxygen/css/bleu.css Sun Aug 12 14:56:52 2007 -0400 +++ b/themes/oxygen/css/bleu.css Tue Aug 14 15:13:40 2007 -0400 @@ -28,7 +28,7 @@ .dbx-handle { cursor: move !important; } /* The credits thingy at the bottom */ -div#credits { margin: 0; padding: 10px; padding-bottom: 0px; padding-top: 12px; background-color: #E8E8E8; color: #AAA; font-size: 7pt; } +div#credits { margin: 0; padding: 10px; padding-bottom: 0px; padding-top: 12px; background-color: #E8E8E8; color: #AAA; font-size: 7pt; font-family: lucida grande, verdana, arial, sans-serif; } div#credits a { color: #90B0D0; text-decoration: none; } div#credits a:hover { color: #80A0C0; text-decoration: underline; } diff -r 9d29f7e101d6 -r 8079b0288e8e themes/oxygen/css/mint.css --- a/themes/oxygen/css/mint.css Sun Aug 12 14:56:52 2007 -0400 +++ b/themes/oxygen/css/mint.css Tue Aug 14 15:13:40 2007 -0400 @@ -28,7 +28,7 @@ .dbx-handle { cursor: move !important; } /* The credits thingy at the bottom */ -div#credits { margin: 0; padding: 10px; padding-bottom: 0px; padding-top: 12px; background-color: #E8E8E8; color: #AAA; font-size: 7pt; } +div#credits { margin: 0; padding: 10px; padding-bottom: 0px; padding-top: 12px; background-color: #E8E8E8; color: #AAA; font-size: 7pt; font-family: lucida grande, verdana, arial, sans-serif; } div#credits a { color: #90D0B0; text-decoration: none; } div#credits a:hover { color: #80C0A0; text-decoration: underline; } diff -r 9d29f7e101d6 -r 8079b0288e8e themes/oxygen/footer.tpl --- a/themes/oxygen/footer.tpl Sun Aug 12 14:56:52 2007 -0400 +++ b/themes/oxygen/footer.tpl Tue Aug 14 15:13:40 2007 -0400 @@ -11,8 +11,8 @@ -Dan -->
- {COPYRIGHT}
- Powered by Enano | Valid XHTML 1.1 | Valid CSS | [[Stats]] + {COPYRIGHT}
+ Website engine powered by Enano  |  Valid XHTML 1.1  |  Valid CSS  |  Generated in [[GenTime]]sec
diff -r 9d29f7e101d6 -r 8079b0288e8e upgrade.php --- a/upgrade.php Sun Aug 12 14:56:52 2007 -0400 +++ b/upgrade.php Tue Aug 14 15:13:40 2007 -0400 @@ -493,6 +493,7 @@
  • You have completely backed up your database ()
  • You have backed up the entire Enano directory ()
  • You have reviewed the release notes for this version, and you
    are comfortable with any known bugs or issues
  • +
  • If you've configured Enano to work using a MySQL user with restricted
    privileges, you need to enable ALTER, CREATE TABLE, and CREATE INDEX privileges
    for this upgrade to work.
  • diff -r 9d29f7e101d6 -r 8079b0288e8e upgrade.sql