# HG changeset patch # User Dan # Date 1275530306 14400 # Node ID e34c23a35dc978f01953eda94f6246e7e7fa57f1 # Parent d543689ed2ebe460ef61ce045f80c78fda6a2b05 Rewrote category editor. This breaks the JSON API. Also fixed a few bugs with how Wiki Mode is set in $paths. (Hopefully that doesn't cause infinite loops, heh). Fixes issue 20. diff -r d543689ed2eb -r e34c23a35dc9 ajax.php --- a/ajax.php Sun May 16 21:35:43 2010 -0400 +++ b/ajax.php Wed Jun 02 21:58:26 2010 -0400 @@ -453,7 +453,8 @@ break; case "catsave": require_once(ENANO_ROOT.'/includes/pageutils.php'); - echo PageUtils::catsave($paths->page_id, $paths->namespace, $_POST); + $categories = !empty($_POST['categories']) ? $_POST['categories'] : array(); + echo PageUtils::catsave($paths->page_id, $paths->namespace, $categories); break; case "setwikimode": require_once(ENANO_ROOT.'/includes/pageutils.php'); diff -r d543689ed2eb -r e34c23a35dc9 includes/clientside/jsres.php --- a/includes/clientside/jsres.php Sun May 16 21:35:43 2010 -0400 +++ b/includes/clientside/jsres.php Wed Jun 02 21:58:26 2010 -0400 @@ -12,7 +12,7 @@ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. */ -// define('ENANO_JS_DEBUG', 1); +define('ENANO_JS_DEBUG', 1); // if Enano's already loaded, we've been included from a helper script if ( defined('ENANO_CONFIG_FETCHED') ) diff -r d543689ed2eb -r e34c23a35dc9 includes/clientside/static/ajax.js --- a/includes/clientside/static/ajax.js Sun May 16 21:35:43 2010 -0400 +++ b/includes/clientside/static/ajax.js Wed Jun 02 21:58:26 2010 -0400 @@ -626,19 +626,12 @@ // IE <6 pseudo-compatibility if ( KILL_SWITCH ) return true; - if(!catlist) - { - alert('Var catlist has no properties'); - return; - } - query=''; - for(i=0;i' . htmlspecialchars($title) . ''; + $exists = isPage("{$paths->nslist['Category']}$cid") ? '' : ' class="wikilink-nonexistent"'; + $list[] = '' . htmlspecialchars($title) . ''; } while ( $row = $db->fetchrow($q) ); $html .= implode(', ', $list); @@ -932,6 +933,7 @@ // add missing keys $defaults = array( + 'name' => dirtify_page_id(str_replace('_', ' ', $cdata['urlname'])), 'special' => 0, 'visible' => 0, 'comments_on' => 1, diff -r d543689ed2eb -r e34c23a35dc9 includes/pageprocess.php --- a/includes/pageprocess.php Sun May 16 21:35:43 2010 -0400 +++ b/includes/pageprocess.php Wed Jun 02 21:58:26 2010 -0400 @@ -953,7 +953,7 @@ } $sql = 'INSERT INTO ' . table_prefix . "logs ( log_type, action, page_id, namespace, author, author_uid, edit_summary, time_id, page_text, date_string ) VALUES\n" - . " ( 'page', '$action', '{$this->page_id}', '{$this->namespace}', '$username', $author_uid, '$reason', '$time', '$existing_protection', 'DATE_STRING COLUMN OBSOLETE, USE time_id' );"; + . " ( 'page', '$action', '{$this->page_id}', '{$this->namespace}', '$username', {$session->user_id}, '$reason', '$time', '$existing_protection', 'DATE_STRING COLUMN OBSOLETE, USE time_id' );"; if ( !$db->sql_query($sql) ) { $db->die_json(); diff -r d543689ed2eb -r e34c23a35dc9 includes/pageutils.php --- a/includes/pageutils.php Sun May 16 21:35:43 2010 -0400 +++ b/includes/pageutils.php Wed Jun 02 21:58:26 2010 -0400 @@ -1339,8 +1339,8 @@ public static function catedit($page_id, $namespace) { - $d = PageUtils::catedit_raw($page_id, $namespace); - return $d[0] . ' /* BEGIN CONTENT */ document.getElementById("ajaxEditContainer").innerHTML = unescape(\''.rawurlencode($d[1]).'\');'; + list($js, $html) = PageUtils::catedit_raw($page_id, $namespace); + return $js . ' /* BEGIN CONTENT */ document.getElementById("ajaxEditContainer").innerHTML = unescape(\''.rawurlencode($html).'\');'; } /** @@ -1353,78 +1353,113 @@ global $db, $session, $paths, $template, $plugins; // Common objects global $lang; - ob_start(); - $_ob = ''; - $e = $db->sql_query('SELECT category_id FROM ' . table_prefix.'categories WHERE page_id=\'' . $paths->page_id . '\' AND namespace=\'' . $paths->namespace . '\''); - if(!$e) jsdie('Error selecting category information for current page: '.$db->get_error()); - $cat_current = Array(); - while($r = $db->fetchrow()) + // notes + // span class is catCheck + // return array(jsblob, innerHTML) + /* + $perms = $session->fetch_page_acl($cat_info[$i]['urlname_nons'], 'Category'); + $cat_is_protected = ( !$session->get_permissions('edit_cat') || !$perms->get_permissions('edit_cat') || + ( $cat_info[$i]['really_protected'] && !$perms->get_permissions('even_when_protected') ) ) + */ + + // two buffers: one is HTML and one is Javascript. + $js = $html = ''; + + // page permissions + $page_perms = $session->fetch_page_acl($page_id, $namespace); + + // Pull the list of categories this page is in + $cats_member_of = array(); + $q = $db->sql_query('SELECT category_id FROM ' . table_prefix . 'categories WHERE page_id = \'' . $db->escape($page_id) . '\' AND namespace = \'' . $db->escape($namespace) . '\';'); + if ( !$q ) + $db->_die(); + while ( $row = $db->fetchrow() ) { - $cat_current[] = $r; + $cats_member_of[] = $row['category_id']; } - $db->free_result(); - $cat_all = array(); - $q = $db->sql_query('SELECT * FROM ' . table_prefix . 'pages WHERE namespace = \'Category\';'); + // Get a list of all categories on the site + $q = $db->sql_query('SELECT * FROM ' . table_prefix . 'pages WHERE namespace = \'Category\' ORDER BY name ASC;'); if ( !$q ) $db->_die(); - while ( $row = $db->fetchrow() ) - { - $cat_all[] = Namespace_Default::bake_cdata($row); - } - - // Make $cat_all an associative array, like $paths->pages - $sz = sizeof($cat_all); - for($i=0;$i<$sz;$i++) + $categories = array(); + while ( $row = $db->fetchrow($q) ) { - $cat_all[$cat_all[$i]['urlname_nons']] = $cat_all[$i]; - } - // Now, the "zipper" function - join the list of categories with the list of cats that this page is a part of - $cat_info = $cat_all; - for($i=0;$ifetch_page_acl($row['urlname_nons'], 'Category'); + $row['disabled'] = ( + // no permissions to edit categorization in this category, or + !$row['perms']->get_permissions('edit_cat') || + // category is protected, and no protect override permissions + ( $row['really_protected'] && !$row['perms']->get_permissions('even_when_protected') ) + ); + // append to array + $categories[ $row['urlname_nons'] ] = $row; } - echo 'catlist = new Array();'; // Initialize the client-side category list - $_ob .= '

' . $lang->get('catedit_title') . '

-
'; - if ( sizeof($cat_info) < 1 ) - { - $_ob .= '

' . $lang->get('catedit_no_categories') . '

'; - } - for ( $i = 0; $i < sizeof($cat_info) / 2; $i++ ) + // fabricate information on categories that don't exist. + foreach ( $cats_member_of as $category ) { - // Protection code added 1/3/07 - // Updated 3/4/07 - $is_prot = false; - $perms = $session->fetch_page_acl($cat_info[$i]['urlname_nons'], 'Category'); - if ( !$session->get_permissions('edit_cat') || !$perms->get_permissions('edit_cat') || - ( $cat_info[$i]['really_protected'] && !$perms->get_permissions('even_when_protected') ) ) - $is_prot = true; - $prot = ( $is_prot ) ? ' disabled="disabled" ' : ''; - $prottext = ( $is_prot ) ? ' (protected)' : ''; - echo 'catlist[' . $i . '] = \'' . $cat_info[$i]['urlname_nons'] . '\';'; - $_ob .= '' . $cat_info[$i]['name'].$prottext.'
'; + if ( isset($categories[$category]) ) + // already have it in the array, skip + continue; + // create page metadata + $row = Namespace_Default::bake_cdata(array( + 'urlname' => $category, + 'namespace' => 'Category' + )); + // we know it's in this category + $row['checked'] = true; + // we know it doesn't exist + $row['exists'] = false; + $row['perms'] = $session->fetch_page_acl($category, 'Category'); + $row['disabled'] = ( + // no permissions to edit categorization in this category (honor inheritance and everything) + !$row['perms']->get_permissions('edit_cat') + // not checking protection because it's defaulted to off + ); + // append + $categories[ $category ] = $row; } - $disabled = ( sizeof($cat_info) < 1 ) ? 'disabled="disabled"' : ''; - - $_ob .= '
'; + // spit out the form + $html .= '

' . $lang->get('catedit_title') . '

'; + $html .= '
'; + foreach ( $categories as $category ) + { + $html .= '
'; + } + if ( count($categories) < 1 ) + $html .= '

' . $lang->get('catedit_no_categories') . '

'; + // submit buttons + $save_disabled = ( count($categories) < 1 ) ? 'disabled="disabled"' : ''; + $html .= '
+ + +
'; - $cont = ob_get_contents(); - ob_end_clean(); - return Array($cont, $_ob); + $html .= '
'; + + return array($js, $html); } /** @@ -1444,65 +1479,122 @@ $page_perms = $session->fetch_page_acl($page_id, $namespace); $ns = namespace_factory($page_id, $namespace); $page_data = $ns->get_cdata(); + if ( !$page_perms->get_permissions('edit_cat') || + ( $page_data['really_protected'] && !$page_perms->get_permissions('even_when_protected') ) ) + return 'Insufficient privileges'; - $cat_all = array(); - $q = $db->sql_query('SELECT * FROM ' . table_prefix . 'pages WHERE namespace = \'Category\';'); + // Pull the list of categories this page is in + $cats_member_of = array(); + $q = $db->sql_query('SELECT category_id FROM ' . table_prefix . 'categories WHERE page_id = \'' . $db->escape($page_id) . '\' AND namespace = \'' . $db->escape($namespace) . '\';'); + if ( !$q ) + $db->_die(); + while ( $row = $db->fetchrow() ) + { + $cats_member_of[] = $row['category_id']; + } + + // Get a list of all categories on the site + $q = $db->sql_query('SELECT * FROM ' . table_prefix . 'pages WHERE namespace = \'Category\' ORDER BY name ASC;'); if ( !$q ) $db->_die(); - while ( $row = $db->fetchrow() ) + $categories = array(); + while ( $row = $db->fetchrow($q) ) { - $cat_all[] = Namespace_Default::bake_cdata($row); + // bake page information + $row = Namespace_Default::bake_cdata($row); + // add our own info + $row['checked'] = in_array($row['urlname_nons'], $cats_member_of); + $row['exists'] = true; + $row['perms'] = $session->fetch_page_acl($row['urlname_nons'], 'Category'); + $row['disabled'] = ( + // no permissions to edit categorization in this category, or + !$row['perms']->get_permissions('edit_cat') || + // category is protected, and no protect override permissions + ( $row['really_protected'] && !$row['perms']->get_permissions('even_when_protected') ) + ); + // append to array + $categories[ $row['urlname_nons'] ] = $row; } - // Make $cat_all an associative array, like $paths->pages - $sz = sizeof($cat_all); - for($i=0;$i<$sz;$i++) + // fabricate information on categories that don't exist. + foreach ( $cats_member_of as $category ) { - $cat_all[$cat_all[$i]['urlname_nons']] = $cat_all[$i]; + if ( isset($categories[$category]) ) + // already have it in the array, skip + continue; + // create page metadata + $row = Namespace_Default::bake_cdata(array( + 'urlname' => $category, + 'namespace' => 'Category' + )); + // we know it's in this category + $row['checked'] = true; + // we know it doesn't exist + $row['exists'] = false; + $row['perms'] = $session->fetch_page_acl($category, 'Category'); + $row['disabled'] = ( + // no permissions to edit categorization in this category (honor inheritance and everything) + !$row['perms']->get_permissions('edit_cat') + // not checking protection because it's defaulted to off, and we know we are using the defaults + // because we made it past the check above ;) + ); + // append + $categories[ $category ] = $row; } - $rowlist = Array(); - - for($i=0;$i $category ) { - $auth = true; - $perms = $session->fetch_page_acl($cat_all[$i]['urlname_nons'], 'Category'); - if ( !$session->get_permissions('edit_cat') || !$perms->get_permissions('edit_cat') || - ( $cat_all[$i]['really_protected'] && !$perms->get_permissions('even_when_protected') ) || - ( !$page_perms->get_permissions('even_when_protected') && $page_data['protected'] == '1' ) ) - $auth = false; - if(!$auth) + // allowed to change it? + if ( $category['disabled'] ) + continue; + + if ( $category['checked'] && !in_array($cat_id, $which_cats) ) + { + // delete + $to_delete[] = $cat_id; + } + else if ( !$category['checked'] && in_array($cat_id, $which_cats) ) + { + // insert + $to_insert[] = $cat_id; + } + else { - // Find out if the page is currently in the category - $q = $db->sql_query('SELECT * FROM ' . table_prefix.'categories WHERE page_id=\'' . $page_id . '\' AND namespace=\'' . $namespace . '\';'); - if(!$q) - return 'MySQL error: ' . $db->get_error(); - if($db->numrows() > 0) - { - $auth = true; - $which_cats[$cat_all[$i]['urlname_nons']] = true; // Force the category to stay in its current state - } - $db->free_result(); + // no change } - if(isset($which_cats[$cat_all[$i]['urlname_nons']]) && $which_cats[$cat_all[$i]['urlname_nons']] == true /* for clarity ;-) */ && $auth ) $rowlist[] = '(\'' . $page_id . '\', \'' . $namespace . '\', \'' . $cat_all[$i]['urlname_nons'] . '\')'; } - if(sizeof($rowlist) > 0) + + // commit changes + if ( !empty($to_insert) ) { - $val = implode(',', $rowlist); - $q = 'INSERT INTO ' . table_prefix.'categories(page_id,namespace,category_id) VALUES' . $val . ';'; - $e = $db->sql_query('DELETE FROM ' . table_prefix.'categories WHERE page_id=\'' . $page_id . '\' AND namespace=\'' . $namespace . '\';'); - if(!$e) $db->_die('The old category data could not be deleted.'); - $e = $db->sql_query($q); - if(!$e) $db->_die('The new category data could not be inserted.'); - return('GOOD'); + $rows = array(); + foreach ( $to_insert as $cat_id ) + { + $rows[] = "('{$db->escape($page_id)}', '{$db->escape($namespace)}', '{$db->escape($cat_id)}')"; + } + $q = $db->sql_query("INSERT INTO " . table_prefix . "categories(page_id, namespace, category_id) VALUES\n " + . implode(",\n ", $rows) . ";"); + if ( !$q ) + $db->_die(); } - else + if ( !empty($to_delete) ) { - $e = $db->sql_query('DELETE FROM ' . table_prefix.'categories WHERE page_id=\'' . $page_id . '\' AND namespace=\'' . $namespace . '\';'); - if(!$e) $db->_die('The old category data could not be deleted.'); - return('GOOD'); + $entries = array(); + foreach ( $to_delete as $cat_id ) + { + $entries[] = "category_id = '{$db->escape($cat_id)}'"; + } + $q = $db->sql_query("DELETE FROM " . table_prefix . "categories WHERE page_id = '{$db->escape($page_id)}' AND namespace = '{$db->escape($namespace)}'\n" + . " AND ( " . implode(' OR ', $entries) . " );"); + if ( !$q ) + $db->_die(); } + + + return 'GOOD'; } /** diff -r d543689ed2eb -r e34c23a35dc9 includes/paths.php --- a/includes/paths.php Sun May 16 21:35:43 2010 -0400 +++ b/includes/paths.php Wed Jun 02 21:58:26 2010 -0400 @@ -165,6 +165,15 @@ } $this->page = $this->nslist[$namespace] . $page_id; $this->page_id = $page_id; + + $ns = namespace_factory($page_id, $namespace); + $this->cpage = $ns->get_cdata(); + $this->page_exists = $ns->exists(); + $this->wiki_mode = false; + $wiki_mode_eligible = ($session->user_logged_in && getConfig('wiki_mode_require_login', 0) == 1) || getConfig('wiki_mode_require_login', 0) == 0; + $global_wiki_mode = getConfig('wiki_mode', 0) == 1; + if ( $wiki_mode_eligible && (($this->cpage['wiki_mode'] == 2 && $global_wiki_mode) || $this->cpage['wiki_mode'] == 1)) + $this->wiki_mode = true; // die("All done setting parameters. What we've got:
namespace: $namespace
fullpage: $this->fullpage
page: $this->page
page_id: $this->page_id"); } else @@ -218,7 +227,7 @@ // Determine the wiki mode for this page, now that we have this->cpage established if($this->cpage['wiki_mode'] == 2) { - $this->wiki_mode = (int)getConfig('wiki_mode'); + $this->wiki_mode = (int)getConfig('wiki_mode', 0); } else { diff -r d543689ed2eb -r e34c23a35dc9 includes/sessions.php --- a/includes/sessions.php Sun May 16 21:35:43 2010 -0400 +++ b/includes/sessions.php Wed Jun 02 21:58:26 2010 -0400 @@ -4477,31 +4477,12 @@ $pathskey = $paths->nslist[$this->namespace].sanitize_page_id($this->page_id); $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' ) + + $this->wiki_mode = false; + $wiki_mode_eligible = ($session->user_logged_in && getConfig('wiki_mode_require_login', 0) == 1) || getConfig('wiki_mode_require_login', 0) == 0; + $global_wiki_mode = getConfig('wiki_mode', 0) == 1; + if ( $wiki_mode_eligible && (($cdata['wiki_mode'] == 2 && $global_wiki_mode) || $cdata['wiki_mode'] == 1)) $this->wiki_mode = true; - else if ( $ppwm == 0 ) - $this->wiki_mode = false; - else if ( $ppwm == 2 ) - { - if ( $this->user_id > 1 ) - { - $this->wiki_mode = ( getConfig('wiki_mode') == '1' ); - } - else - { - $this->wiki_mode = ( getConfig('wiki_mode') == '1' && getConfig('wiki_mode_require_login') != '1' ); - } - } - else - { - // Ech. Internal logic failure, this should never happen. - return false; - } } /** diff -r d543689ed2eb -r e34c23a35dc9 index.php --- a/index.php Sun May 16 21:35:43 2010 -0400 +++ b/index.php Wed Jun 02 21:58:26 2010 -0400 @@ -322,10 +322,10 @@ break; case 'catedit': require_once(ENANO_ROOT.'/includes/pageutils.php'); - if(isset($_POST['__enanoSaveButton'])) + if(isset($_POST['save'])) { - unset($_POST['__enanoSaveButton']); - $val = PageUtils::catsave($paths->page_id, $paths->namespace, $_POST); + unset($_POST['save']); + $val = PageUtils::catsave($paths->page_id, $paths->namespace, $_POST['categories']); if($val == 'GOOD') { header('Location: '.makeUrl($paths->page)); echo 'Redirecting...If you haven\'t been redirected yet, click here.'; break; diff -r d543689ed2eb -r e34c23a35dc9 language/english/core.json --- a/language/english/core.json Sun May 16 21:35:43 2010 -0400 +++ b/language/english/core.json Wed Jun 02 21:58:26 2010 -0400 @@ -458,6 +458,7 @@ catedit: { title: 'Select which categories this page should be included in.', no_categories: 'There are no categories on this site yet.', + msg_protected_tip: '(protected)', catbox_lbl_categories: 'Categories:', catbox_lbl_uncategorized: '(Uncategorized)', catbox_link_edit: 'edit categorization',