--- a/includes/clientside/static/misc.js Mon Feb 18 16:13:56 2008 -0500
+++ b/includes/clientside/static/misc.js Mon Feb 18 16:14:22 2008 -0500
@@ -872,3 +872,80 @@
}
return myWidth;
}
+
+/**
+ * Sanitizes a page URL string so that it can safely be stored in the database.
+ * @param string Page ID to sanitize
+ * @return string Cleaned text
+ */
+
+function sanitize_page_id(page_id)
+{
+ // Remove character escapes
+ page_id = dirtify_page_id(page_id);
+
+ var regex = new RegExp('[A-Za-z0-9\\[\\]\./:;\(\)@_-]', 'g');
+ pid_clean = page_id.replace(regex, 'X');
+ var pid_dirty = [];
+ for ( var i = 0; i < pid_clean.length; i++ )
+ pid_dirty[i] = pid_clean.substr(i, 1);
+
+ for ( var i = 0; i < pid_dirty.length; i++ )
+ {
+ var char = pid_dirty[i];
+ if ( char == 'X' )
+ continue;
+ var cid = char.charCodeAt(0);
+ cid = cid.toString(16).toUpperCase();
+ if ( cid.length < 2 )
+ {
+ cid = '0' + cid;
+ }
+ pid_dirty[i] = "." + cid;
+ }
+
+ var pid_chars = [];
+ for ( var i = 0; i < page_id.length; i++ )
+ pid_chars[i] = page_id.substr(i, 1);
+
+ var page_id_cleaned = '';
+
+ for ( var id in pid_chars )
+ {
+ var char = pid_chars[id];
+ if ( pid_dirty[id] == 'X' )
+ page_id_cleaned += char;
+ else
+ page_id_cleaned += pid_dirty[id];
+ }
+
+ return page_id_cleaned;
+}
+
+/**
+ * Removes character escapes in a page ID string
+ * @param string Page ID string to dirty up
+ * @return string
+ */
+
+function dirtify_page_id(page_id)
+{
+ // First, replace spaces with underscores
+ page_id = page_id.replace(/ /g, '_');
+
+ var matches = page_id.match(/\.[A-Fa-f0-9][A-Fa-f0-9]/g);
+
+ if ( matches != null )
+ {
+ for ( var i = 0; i < matches.length; i++ )
+ {
+ var match = matches[i];
+ var byt = (match.substr(1)).toUpperCase();
+ var code = eval("0x" + byt);
+ var regex = new RegExp('\\.' + byt, 'g');
+ page_id = page_id.replace(regex, String.fromCharCode(code));
+ }
+ }
+
+ return page_id;
+}
--- a/includes/pageprocess.php Mon Feb 18 16:13:56 2008 -0500
+++ b/includes/pageprocess.php Mon Feb 18 16:14:22 2008 -0500
@@ -471,24 +471,26 @@
/**
* Creates the page if it doesn't already exist.
+ * @param string Optional page title.
* @return bool True on success, false on failure.
*/
- function create_page()
+ function create_page($title = false)
{
global $db, $session, $paths, $template, $plugins; // Common objects
+ global $lang;
// Do we have permission to create the page?
if ( !$this->perms->get_permissions('create_page') )
{
- $this->raise_error('You do not have permission to create this page.');
+ $this->raise_error($lang->get('pagetools_create_err_no_permission'));
return false;
}
// Does it already exist?
if ( $this->page_exists )
{
- $this->raise_error('The page already exists.');
+ $this->raise_error($lang->get('pagetools_create_err_already_exists'));
return false;
}
@@ -497,17 +499,17 @@
// We can't create special, admin, or external pages.
if ( $this->namespace == 'Special' || $this->namespace == 'Admin' || $this->namespace == 'Anonymous' )
{
- $this->raise_error('You cannot create Special or Admin pages - they can\'t be stored in the database.');
+ $this->raise_error($lang->get('pagetools_create_err_nodb_namespace'));
return false;
}
// Guess the proper title
- $name = dirtify_page_id($this->page_id);
+ $name = ( !empty($title) ) ? $title : dirtify_page_id($this->page_id);
// Check for the restricted Project: prefix
if ( substr($this->page_id, 0, 8) == 'Project:' )
{
- $this->raise_error('The prefix "Project:" is reserved for internal links and can\'t be used on a page name.');
+ $this->raise_error($lang->get('pagetools_create_err_reserved_prefix'));
return false;
}
@@ -546,6 +548,13 @@
if ( !$q )
$db->_die('PageProcessor page creation - text stage');
+ // Query 3: Log entry
+ $db->sql_query('INSERT INTO ' . table_prefix."logs(time_id, date_string, log_type, action, author, page_id, namespace)\n"
+ . " VALUES ( " . time() . ", '" . enano_date('d M Y h:i a') . "', 'page', 'create', \n"
+ . " '" . $db->escape($session->username) . "', '" . $db->escape($this->page_id) . "', '" . $this->namespace . "');");
+ if ( !$q )
+ $db->_die('PageProcessor page creation - logging stage');
+
// Page created. We're good!
return true;
}
@@ -575,11 +584,13 @@
}
// Does the page "exist"?
+ $pathskey = $paths->nslist[$namespace] . $page_id_cleaned;
+
if ( $paths->page_id == $page_id && $paths->namespace == $namespace && !$paths->page_exists && ( $this->namespace != 'Admin' || ($this->namespace == 'Admin' && !function_exists($fname) ) ) )
{
$this->page_exists = false;
}
- else if ( !isset( $paths->pages[ $paths->nslist[$namespace] . $page_id ] ) && ( $this->namespace == 'Admin' && !function_exists($fname) ) )
+ else if ( !isset( $paths->pages[ $pathskey ] ) && ( ( $this->namespace == 'Admin' && !function_exists($fname) ) || ( $this->namespace != 'Admin' ) ) )
{
$this->page_exists = false;
}
--- a/language/english/tools.json Mon Feb 18 16:13:56 2008 -0500
+++ b/language/english/tools.json Mon Feb 18 16:14:22 2008 -0500
@@ -88,14 +88,23 @@
pagetools: {
// Create a page
- create_err_title: 'The page could not be created.',
- create_err_name_invalid: 'The name "%page_name%" is invalid.',
- create_err_project_shortcut: 'The page title can\'t start with "Project:" because this prefix is reserved for a parser shortcut.',
- create_err_already_exist: 'The page already exists.',
+ create_err_invalid_namespace: 'You have selected an invalid page type.',
+ create_err_invalid_urlname: 'Please enter a title for your page and a custom URL if desired.',
+ create_err_already_exists: 'A page with that URL already exists. Please enter another title or enter a custom URL. (You can have two pages with the same name, but not two pages with the same URL.)',
+ create_err_no_permission: 'You don\'t have permission to create this page. Try another URL or title; if that does not work, please contact the site administration for permission to create pages.',
+ create_err_nodb_namespace: 'You cannot create Special or Admin pages - they can\'t be stored in the database.',
+ create_err_reserved_prefix: 'The prefix "Project:" is reserved for internal links and can\'t be used on a page name.',
- create_blurb: 'Using the form below you can create a page.',
- create_namespace_none: '[No prefix]',
- create_btn_create: 'Create Page',
+ create_blurb: 'Add a new page to the site.',
+ create_field_title: 'Page title:',
+ create_field_namespace: 'Page type:',
+ create_group_advanced: 'Advanced options',
+ create_field_url_auto: 'Generate a URL based on the title',
+ create_field_url_manual: 'Enter a custom page URL',
+ create_field_url: 'Page ID:',
+ create_field_preview: 'Preview of URL:',
+ create_field_preview_hint: '(Requires Javascript support)',
+ create_btn_create: 'Create page',
// All pages
allpages_blurb: 'Below is a list of all of the pages on this website.',
--- a/plugins/SpecialPageFuncs.php Mon Feb 18 16:13:56 2008 -0500
+++ b/plugins/SpecialPageFuncs.php Mon Feb 18 16:14:22 2008 -0500
@@ -10,7 +10,7 @@
/*
* Enano - an open-source CMS capable of wiki functions, Drupal-like sidebar blocks, and everything in between
- * Version 1.1.1
+ * Version 1.1.2 (Caoineag alpha 2)
* Copyright (C) 2006-2007 Dan Fuhry
*
* This program is Free Software; you can redistribute and/or modify it under the terms of the GNU General Public License
@@ -74,6 +74,183 @@
global $db, $session, $paths, $template, $plugins; // Common objects
global $lang;
+ $whitelist_ns = array('Article', 'User', 'Help', 'Template', 'Category', 'Project');
+ $code = $plugins->setHook('page_create_ns_whitelist');
+ foreach ( $code as $cmd )
+ {
+ eval($cmd);
+ }
+
+ $errors = array();
+
+ switch ( isset($_POST['page_title']) )
+ {
+ case true:
+ // "Create page" was clicked
+
+ //
+ // VALIDATION CODE
+ //
+
+ // Check namespace
+ $namespace = ( isset($_POST['namespace']) ) ? $_POST['namespace'] : 'Article';
+ if ( !in_array($namespace, $whitelist_ns) )
+ {
+ $errors[] = $lang->get('pagetools_create_err_invalid_namespace');
+ }
+
+ // Check title and figure out urlname
+ $title = $_POST['page_title'];
+ $urlname = $_POST['page_title'];
+ if ( @$_POST['custom_url'] === 'yes' && isset($_POST['urlname']) )
+ {
+ $urlname = $_POST['urlname'];
+ }
+ $urlname = sanitize_page_id($urlname);
+ if ( $urlname == '.00' || empty($urlname) )
+ {
+ $errors[] = $lang->get('pagetools_create_err_invalid_urlname');
+ }
+
+ // Validate page existence
+ $pathskey = $paths->nslist[$namespace] . $urlname;
+ if ( isPage($pathskey) )
+ {
+ $errors[] = $lang->get('pagetools_create_err_already_exists');
+ }
+
+ // Validate permissions
+ $perms = $session->fetch_page_acl($urlname, $namespace);
+ if ( !$perms->get_permissions('create_page') )
+ {
+ $errors[] = $lang->get('pagetools_create_err_no_permission');
+ }
+
+ // Run hooks
+ $code = $plugins->setHook('page_create_request');
+ foreach ( $code as $cmd )
+ {
+ eval($cmd);
+ }
+
+ // Create the page
+ if ( count($errors) < 1 )
+ {
+ $page = new PageProcessor($urlname, $namespace);
+ $page->create_page($title);
+ if ( $error = $page->pop_error() )
+ {
+ do
+ {
+ $errors[] = $error;
+ }
+ while ( $error = $page->pop_error() );
+ }
+ else
+ {
+ redirect(makeUrlNS($namespace, $urlname) . '#do:edit', '', '', 0);
+ return true;
+ }
+ }
+
+ break;
+ }
+
+ $template->header();
+
+ echo $lang->get('pagetools_create_blurb');
+
+ if ( count($errors) > 0 )
+ {
+ echo '<div class="error-box">' . implode("<br />\n ", $errors) . '</div>';
+ }
+
+ ?>
+ <enano:no-opt>
+ <script type="text/javascript">
+ function cpGenPreviewUrl()
+ {
+ var frm = document.forms['create_form'];
+ var radio_custom = frm.getElementsByTagName('input')[2];
+ var use_custom_url = radio_custom.checked;
+ if ( use_custom_url )
+ {
+ var title_src = frm.urlname.value;
+ }
+ else
+ {
+ var title_src = frm.page_title.value;
+ }
+ var url = window.location.protocol + '//' + window.location.hostname + contentPath + namespace_list[frm.namespace.value] + sanitize_page_id(title_src);
+ document.getElementById('createpage_url_preview').firstChild.nodeValue = url;
+ }
+ </script>
+ </enano:no-opt>
+ <?php
+
+ echo '<form action="' . makeUrlNS('Special', 'CreatePage') . '" method="post" name="create_form">';
+
+ echo '<p>';
+ echo $lang->get('pagetools_create_field_title');
+ echo ' <input onkeyup="cpGenPreviewUrl();" type="text" name="page_title" size="40" tabindex="1" />';
+ echo '</p>';
+
+ echo '<p>';
+ echo $lang->get('pagetools_create_field_namespace');
+ echo ' <select onchange="cpGenPreviewUrl();" name="namespace" tabindex="2">';
+ foreach ( $paths->nslist as $ns => $ns_prefix )
+ {
+ if ( !in_array($ns, $whitelist_ns) )
+ continue;
+ $lang_string = 'onpage_lbl_page_' . strtolower($ns);
+ $str = $lang->get($lang_string);
+ if ( $str == $lang_string )
+ $str = $ns;
+
+ echo '<option value="' . $ns . '">' . ucwords($str) . '</option>';
+ }
+ echo '</select>';
+ echo '</p>';
+
+ echo '<fieldset>';
+ echo '<legend>' . $lang->get('pagetools_create_group_advanced') . '</legend>';
+
+ echo '<p>';
+ echo '<label><input tabindex="3" type="radio" name="custom_url" value="no" checked="checked" onclick="cpGenPreviewUrl(); document.getElementById(\'createpage_custom_url\').style.display = \'none\';" /> ' . $lang->get('pagetools_create_field_url_auto') . '</label>';
+ echo '</p>';
+
+ echo '<p>';
+ echo '<label><input tabindex="3" type="radio" name="custom_url" value="yes" onclick="cpGenPreviewUrl(); document.getElementById(\'createpage_custom_url\').style.display = \'block\';" /> ' . $lang->get('pagetools_create_field_url_manual') . '</label>';
+ echo '</p>';
+
+ echo '<p id="createpage_custom_url" style="display: none; margin-left: 2em;">';
+ echo $lang->get('pagetools_create_field_url');
+ echo ' <input onkeyup="cpGenPreviewUrl();" tabindex="4" type="text" name="urlname" value="" size="40" />';
+ echo '</p>';
+
+ echo '<p>';
+ echo $lang->get('pagetools_create_field_preview') . ' <tt id="createpage_url_preview"> </tt><br />';
+ echo '<small>' . $lang->get('pagetools_create_field_preview_hint') . '</small>';
+ echo '</p>';
+
+ echo '</fieldset>';
+
+ echo '<p>';
+ echo '<input tabindex="5" type="submit" value="' . $lang->get('pagetools_create_btn_create') . '" />';
+ echo '</p>';
+
+ echo '</form>';
+
+ echo '<script type="text/javascript">cpGenPreviewUrl();</script>';
+
+ $template->footer();
+}
+
+function page_Special_CreatePage_Old()
+{
+ global $db, $session, $paths, $template, $plugins; // Common objects
+ global $lang;
+
if ( isset($_POST['do']) )
{
$p = $_POST['pagename'];