Topic on Extension talk:DynamicPageList (Wikimedia)

New feature parameter: categorymatch

2
Odysseus277 (talkcontribs)

The third-party-version of this addon (found here) supports the very useful parameter categorymatch. On my wiki, this is used to collect articles from categories with similar names. After switching to the Intersection-Addon, I missed this feature. so I added it myself. Maybe other users are also interested in this, so here is the udiff for DynamicPageList.php

Usage:

<DynamicPageList>
category=MustBeExtended
categorymatch=%fruit%|%vegetables%
notcategory=electronics
</DynamicPageList>

This will find any aticles in categories with names like fruit and vegetables which also are contained in the category MustBeExtended.

- Odysseus277 16:01, 4 January 2012 (UTC)

--- X:\Scripte\intersection\DynamicPageList.php	2011-11-14 17:31:42.000000000 +0100
+++ X:\xampp\htdocs\wiki\mediawiki\extensions\intersection\DynamicPageList.php	2012-01-04 17:25:23.000000000 +0100
@@ -114,12 +114,13 @@
 	$addFirstCategoryDate = false;
 	$dateFormat = '';
 	$stripYear = false;
 
 	$linkOptions = array();
 	$categories = array();
+	$categoryMatches = array();
 	$excludeCategories = array();
 
 	$parameters = explode( "\n", $input );
 
 	$parser = new Parser;
 	$poptions = new ParserOptions;
@@ -146,12 +147,33 @@
 					$parser->transformMsg( $arg, $poptions )
 				);
 				if( is_null( $title ) ) {
 					continue;
 				}
 				$excludeCategories[] = $title;
+				break;
+			case 'categorymatch':
+				$matchedCategories = explode('|', $arg);
+				foreach($matchedCategories as $currentCategory) {
+					$value = null;
+					if(preg_match("/^\%[^%]*\%$/i", $currentCategory)) {
+						$value = mysql_real_escape_string(str_replace('%', '', $currentCategory));
+						$value = '%' . $value . '%';
+					} elseif(preg_match("/^\%[^%]*$/i", $currentCategory)) {
+						$value = mysql_real_escape_string(str_replace('%', '', $currentCategory));
+						$value = '%' . $value;
+					} elseif(preg_match("/^[^%]*\%$$/i", $currentCategory)) {
+						$value = mysql_real_escape_string(str_replace('%', '', $currentCategory));
+						$value = $value . '%';
+					}
+                    
+					if( is_null($value) ) continue;
+                    
+					$title = Title::newFromText( $parser->transformMsg( $value, $poptions ) );
+					$categoryMatches[] = $title;
+				}
 				break;
 			case 'namespace':
 				$ns = $wgContLang->getNsIndex( $arg );
 				if ( $ns != null ) {
 					$namespaceIndex = $ns;
 					$namespaceFiltering = true;
@@ -386,13 +408,14 @@
 				break;
 		} // end main switch()
 	} // end foreach()
 
 	$catCount = count( $categories );
 	$excludeCatCount = count( $excludeCategories );
-	$totalCatCount = $catCount + $excludeCatCount;
+	$catMatchCount = empty($categoryMatches) ? 0 : 1;
+	$totalCatCount = $catCount + $excludeCatCount + $catMatchCount;
 
 	if ( $catCount < 1 && false == $namespaceFiltering ) {
 		if ( $suppressErrors == false ) {
 			return htmlspecialchars( wfMsgForContent( 'intersection_noincludecats' ) ); // "!!no included categories!!";
 		} else {
 			return '';
@@ -428,13 +451,13 @@
 		}
 	}
 
 	// build the SQL query
 	$dbr = wfGetDB( DB_SLAVE );
 	$tables = array( 'page' );
-	$fields = array( 'page_namespace', 'page_title' );
+	$fields = array( 'DISTINCT page_id', 'page_namespace', 'page_title' );
 	$where = array();
 	$join = array();
 	$options = array();
 
 	if ( $googleHack ) {
 		$fields[] = 'page_id';
@@ -487,19 +510,38 @@
 
 	for ( $i = 0; $i < $catCount; $i++ ) {
 		$join["$categorylinks AS c$currentTableNumber"] = array(
 			'INNER JOIN',
 			array(
 				"page_id = c{$currentTableNumber}.cl_from",
-			 	"c{$currentTableNumber}.cl_to={$dbr->addQuotes( $categories[$i]->getDBKey() )}"
+				"c{$currentTableNumber}.cl_to={$dbr->addQuotes( $categories[$i]->getDBKey() )}"
 			)
 		);
 		$tables[] = "$categorylinks AS c$currentTableNumber";
 
 		$currentTableNumber++;
 	}
+	
+	if( !empty($categoryMatches) ) {
+		$onStatements = array();
+		
+		foreach( $categoryMatches as $categoryMatch ) {
+			$onStatements[] = "LOWER(c{$currentTableNumber}.cl_to) LIKE LOWER({$dbr->addQuotes( $categoryMatch->getDBKey() )})";
+		}
+		
+		$join["$categorylinks AS c$currentTableNumber"] = array(
+			'INNER JOIN',
+			array(
+				"page_id = c{$currentTableNumber}.cl_from",
+				implode(' OR ', $onStatements)
+			)
+		);
+		$tables[] = "$categorylinks AS c$currentTableNumber";
+
+		$currentTableNumber++;		
+	}
 
 	for ( $i = 0; $i < $excludeCatCount; $i++ ) {
 		$join["$categorylinks AS c$currentTableNumber"] = array(
 			'LEFT OUTER JOIN',
 			array(
 				"page_id = c{$currentTableNumber}.cl_from",

This post was posted by Odysseus277, but signed as 188.192.164.182.

76.102.130.155 (talkcontribs)

Too bad this was never integrated, and, along the way, mysql_real_escape_string was seemingly removed.

Reply to "New feature parameter: categorymatch"