# HG changeset patch # User Dan # Date 1191198007 14400 # Node ID edbff85d43e8ec3b16d0700fef2f13fd57877cf6 # Parent 87bffacdfb92f84e756fa6df07dccd3c0ff403a6 Feature add: new page group type: regular expression match (PCRE) diff -r 87bffacdfb92 -r edbff85d43e8 includes/constants.php --- a/includes/constants.php Sun Sep 30 19:40:07 2007 -0400 +++ b/includes/constants.php Sun Sep 30 20:20:07 2007 -0400 @@ -37,6 +37,7 @@ define('PAGE_GRP_CATLINK', 1); define('PAGE_GRP_TAGGED', 2); define('PAGE_GRP_NORMAL', 3); +define('PAGE_GRP_REGEX', 4); // // User types - don't touch these diff -r 87bffacdfb92 -r edbff85d43e8 includes/paths.php --- a/includes/paths.php Sun Sep 30 19:40:07 2007 -0400 +++ b/includes/paths.php Sun Sep 30 20:20:07 2007 -0400 @@ -855,14 +855,35 @@ { global $db, $session, $paths, $template, $plugins; // Common objects - $page_id = $db->escape(sanitize_page_id($page_id)); + static $cache = array(); + + if ( count($cache) == 0 ) + { + foreach ( $this->nslist as $key => $_ ) + { + $cache[$key] = array(); + } + } + if ( !isset($this->nslist[$namespace]) ) die('$paths->get_page_groups(): HACKING ATTEMPT: namespace "'. htmlspecialchars($namespace) .'" doesn\'t exist'); + $page_id_unescaped = $paths->nslist[$namespace] . + dirtify_page_id($page_id); + $page_id_str = $paths->nslist[$namespace] . + sanitize_page_id($page_id); + + $page_id = $db->escape(sanitize_page_id($page_id)); + + if ( isset($cache[$namespace][$page_id]) ) + { + return $cache[$namespace][$page_id]; + } + $group_list = array(); // What linked categories have this page? - $q = $db->sql_query('SELECT g.pg_id FROM '.table_prefix.'page_groups AS g + $q = $db->sql_unbuffered_query('SELECT g.pg_id, g.pg_type, g.pg_target FROM '.table_prefix.'page_groups AS g LEFT JOIN '.table_prefix.'categories AS c ON ( ( c.category_id = g.pg_target AND g.pg_type = ' . PAGE_GRP_CATLINK . ' ) OR c.category_id IS NULL ) LEFT JOIN '.table_prefix.'page_group_members AS m @@ -872,47 +893,32 @@ WHERE ( c.page_id=\'' . $page_id . '\' AND c.namespace=\'' . $namespace . '\' ) OR ( t.page_id=\'' . $page_id . '\' AND t.namespace=\'' . $namespace . '\' ) OR - ( m.page_id=\'' . $page_id . '\' AND m.namespace=\'' . $namespace . '\' );'); + ( m.page_id=\'' . $page_id . '\' AND m.namespace=\'' . $namespace . '\' ) OR + ( g.pg_type = ' . PAGE_GRP_REGEX . ' );'); if ( !$q ) $db->_die(); while ( $row = $db->fetchrow() ) { - $group_list[] = $row['pg_id']; + if ( $row['pg_type'] == PAGE_GRP_REGEX ) + { + //echo "<debug> matching page " . htmlspecialchars($page_id_unescaped) . " against regex " . htmlspecialchars($row['pg_target']) . "."; + if ( @preg_match($row['pg_target'], $page_id_unescaped) || @preg_match($row['pg_target'], $page_id_str) ) + { + //echo "..matched"; + $group_list[] = $row['pg_id']; + } + //echo "
"; + } + else + { + $group_list[] = $row['pg_id']; + } } $db->free_result(); - /* - // Static-page groups - $q = $db->sql_query('SELECT g.pg_id FROM '.table_prefix.'page_groups AS g - LEFT JOIN '.table_prefix.'page_group_members AS m - ON ( g.pg_id = m.pg_id ) - WHERE m.page_id=\'' . $page_id . '\' AND m.namespace=\'' . $namespace . '\' - GROUP BY g.pg_id;'); - - if ( !$q ) - $db->_die(); - - while ( $row = $db->fetchrow() ) - { - $group_list[] = $row['pg_id']; - } - - // Tag groups - - $q = $db->sql_query('SELECT g.pg_id FROM '.table_prefix.'page_groups AS g - LEFT JOIN '.table_prefix.'tags AS t - ON ( t.tag_name = g.pg_target AND pg_type = ' . PAGE_GRP_TAGGED . ' ) - WHERE t.page_id = \'' . $page_id . '\' AND t.namespace = \'' . $namespace . '\';'); - if ( !$q ) - $db->_die(); - - while ( $row = $db->fetchrow() ) - { - $group_list[] = $row['pg_id']; - } - */ + $cache[$namespace][$page_id] = $group_list; return $group_list; diff -r 87bffacdfb92 -r edbff85d43e8 includes/sessions.php --- a/includes/sessions.php Sun Sep 30 19:40:07 2007 -0400 +++ b/includes/sessions.php Sun Sep 30 20:20:07 2007 -0400 @@ -2117,13 +2117,30 @@ return false; } + // cache of permission objects (to save RAM and SQL queries) + static $objcache = array(); + + if ( count($objcache) == 0 ) + { + foreach ( $paths->nslist as $key => $_ ) + { + $objcache[$key] = array(); + } + } + + if ( isset($objcache[$namespace][$page_id]) ) + { + return $objcache[$namespace][$page_id]; + } + //if ( !isset( $paths->pages[$paths->nslist[$namespace] . $page_id] ) ) //{ // // Page does not exist // return false; //} - $object = new Session_ACLPageInfo( $page_id, $namespace, $this->acl_types, $this->acl_descs, $this->acl_deps, $this->acl_base_cache ); + $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]; return $object; diff -r 87bffacdfb92 -r edbff85d43e8 plugins/admin/PageGroups.php --- a/plugins/admin/PageGroups.php Sun Sep 30 19:40:07 2007 -0400 +++ b/plugins/admin/PageGroups.php Sun Sep 30 20:20:07 2007 -0400 @@ -48,7 +48,12 @@ echo '
Please specify at least one page to place in this group.
'; return; } - if ( $_POST['group_type'] != PAGE_GRP_TAGGED && $_POST['group_type'] != PAGE_GRP_CATLINK && $_POST['group_type'] != PAGE_GRP_NORMAL ) + if ( $_POST['group_type'] == PAGE_GRP_REGEX && empty($_POST['regex']) ) + { + echo '
Please specify a regular expression to match page IDs against.
'; + return; + } + if ( $_POST['group_type'] != PAGE_GRP_TAGGED && $_POST['group_type'] != PAGE_GRP_CATLINK && $_POST['group_type'] != PAGE_GRP_NORMAL && $_POST['group_type'] != PAGE_GRP_REGEX ) { echo '
Umm, you sent an invalid group type. I\'d put a real error message here but this will only be shown if you try to hack the system.
'; return; @@ -103,6 +108,14 @@ if ( !$q ) $db->_die(); break; + case PAGE_GRP_REGEX: + $name = $db->escape($_POST['pg_name']); + $regex = $db->escape($_POST['regex']); + $sql = 'INSERT INTO '.table_prefix.'page_groups(pg_type,pg_name,pg_target) VALUES(' . PAGE_GRP_REGEX . ', \'' . $name . '\', \'' . $regex . '\');'; + $q = $db->sql_query($sql); + if ( !$q ) + $db->_die(); + break; } echo '
The page group "' . htmlspecialchars($_POST['pg_name']) . '" has been created.
'; break; @@ -115,6 +128,7 @@ var pg_normal = ; var pg_tagged = ; var pg_catlink = ; + var pg_regex = ; var selection = false; // Get selection for ( var i = 0; i < selector.childNodes.length; i++ ) @@ -135,7 +149,7 @@ return true; } selection = parseInt(selection); - if ( selection != pg_normal && selection != pg_tagged && selection != pg_catlink ) + if ( selection != pg_normal && selection != pg_tagged && selection != pg_catlink && selection != pg_regex ) { alert('Invalid field value'); return true; @@ -156,6 +170,10 @@ document.getElementById('pg_create_title_normal').style.display = 'inline'; document.getElementById('pg_create_normal_1').style.display = 'block'; document.getElementById('pg_create_normal_2').style.display = 'block'; + + document.getElementById('pg_create_title_regex').style.display = 'none'; + document.getElementById('pg_create_regex_1').style.display = 'none'; + document.getElementById('pg_create_regex_2').style.display = 'none'; } else if ( selection == pg_catlink ) { @@ -170,6 +188,10 @@ document.getElementById('pg_create_title_normal').style.display = 'none'; document.getElementById('pg_create_normal_1').style.display = 'none'; document.getElementById('pg_create_normal_2').style.display = 'none'; + + document.getElementById('pg_create_title_regex').style.display = 'none'; + document.getElementById('pg_create_regex_1').style.display = 'none'; + document.getElementById('pg_create_regex_2').style.display = 'none'; } else if ( selection == pg_tagged ) { @@ -184,6 +206,28 @@ document.getElementById('pg_create_title_normal').style.display = 'none'; document.getElementById('pg_create_normal_1').style.display = 'none'; document.getElementById('pg_create_normal_2').style.display = 'none'; + + document.getElementById('pg_create_title_regex').style.display = 'none'; + document.getElementById('pg_create_regex_1').style.display = 'none'; + document.getElementById('pg_create_regex_2').style.display = 'none'; + } + else if ( selection == pg_regex ) + { + document.getElementById('pg_create_title_catlink').style.display = 'none'; + document.getElementById('pg_create_catlink_1').style.display = 'none'; + document.getElementById('pg_create_catlink_2').style.display = 'none'; + + document.getElementById('pg_create_title_tagged').style.display = 'none'; + document.getElementById('pg_create_tagged_1').style.display = 'none'; + document.getElementById('pg_create_tagged_2').style.display = 'none'; + + document.getElementById('pg_create_title_normal').style.display = 'none'; + document.getElementById('pg_create_normal_1').style.display = 'none'; + document.getElementById('pg_create_normal_2').style.display = 'none'; + + document.getElementById('pg_create_title_regex').style.display = 'inline'; + document.getElementById('pg_create_regex_1').style.display = 'block'; + document.getElementById('pg_create_regex_2').style.display = 'block'; } } @@ -199,6 +243,10 @@ document.getElementById('pg_create_tagged_1').style.display = 'none'; document.getElementById('pg_create_tagged_2').style.display = 'none'; + document.getElementById('pg_create_title_regex').style.display = 'none'; + document.getElementById('pg_create_regex_1').style.display = 'none'; + document.getElementById('pg_create_regex_2').style.display = 'none'; + document.getElementById('pg_create_title_normal').style.display = 'inline'; document.getElementById('pg_create_normal_1').style.display = 'block'; document.getElementById('pg_create_normal_2').style.display = 'block'; @@ -292,6 +340,7 @@ + '; @@ -308,6 +357,9 @@ Mirror a category + + Filter through a regular expression + '; @@ -324,6 +376,14 @@
Include pages with this tag:
+
+ Regular expression:
+ Be sure to include the starting and ending delimiters and any flags you might need.
+ These pages might help: Pattern modifiers • + Pattern syntax
+ Examples: /^(Special|Admin):/i/^Image:([0-9]+)$/
+ Developers, remember that this will be matched against the full page identifier string. This means that /^About_Enano$/ + will NOT match the page Special:About_Enano.
'; echo ' @@ -341,6 +401,9 @@ +
+ +
'; @@ -911,6 +974,9 @@ case PAGE_GRP_NORMAL: $type = 'Static set of pages'; break; + case PAGE_GRP_REGEX: + $type = 'Regular expression match'; + break; } $target = ''; if ( $row['pg_type'] == PAGE_GRP_TAGGED ) @@ -921,6 +987,10 @@ { $target = 'Category: ' . htmlspecialchars(get_page_title($paths->nslist['Category'] . sanitize_page_id($row['pg_target']))); } + else if ( $row['pg_type'] == PAGE_GRP_REGEX ) + { + $target = 'Expression: ' . htmlspecialchars($row['pg_target']) . ''; + } $btn_edit = ''; $btn_del = ''; // stupid jEdit bug/hack diff -r 87bffacdfb92 -r edbff85d43e8 upgrade.sql --- a/upgrade.sql Sun Sep 30 19:40:07 2007 -0400 +++ b/upgrade.sql Sun Sep 30 20:20:07 2007 -0400 @@ -5,6 +5,8 @@ DELETE FROM {{TABLE_PREFIX}}config WHERE config_name='enano_version' OR config_name='enano_beta_version' OR config_name='enano_alpha_version' OR config_name='enano_rc_version'; INSERT INTO {{TABLE_PREFIX}}config (config_name, config_value) VALUES( 'enano_version', '1.0.2' ); ---BEGIN 1.0.2b1--- +-- This is really optional, but could reduce confusion if regex page groups get truncated for no apparent reason. +ALTER TABLE {{TABLE_PREFIX}}page_groups MODIFY COLUMN pg_target text DEFAULT NULL; ---END 1.0.2b1--- ---BEGIN 1.0.1.1--- ---END 1.0.1.1---