User:Cm/SelectCategoryFunctions

From MediaWiki.org
Jump to: navigation, search
<?php
 
# Implementation of the SelectCategory extension, an extension of the
# edit box of MediaWiki to provide an easy way to add category links
# to a specific page.

# @addtogroup Extensions
# @author Leon Weber <leon@leonweber.de> & Manuel Schneider <manuel.schneider@wikimedia.ch>
# @copyright © 2006 by Leon Weber & Manuel Schneider
# @licence GNU General Public Licence 2.0 or later

# Extended by Cynthia Mattingly @ Marketing Factory Consulting
# * If editing a category page, the category and its subcategories are not options
# * User can also enter a new category in a text box

if( !defined( 'MEDIAWIKI' ) ) {
        echo( "This file is an extension to the MediaWiki software and cannot be used standalone.\n" );
        die();
}
 
## Entry point for the hook and main worker function for editing the page:
function fnSelectCategoryShowHook( $m_isUpload = false, &$m_pageObj ) {
        global $wgContLang;
        $what = get_class($m_pageObj);
 
        if ($what == 'EditPage') {
                $a = $m_pageObj->getArticle();
        } 
 
        # check if we should do anything or sleep
        if ( fnSelectCategoryCheckConditions( $m_isUpload, &$m_pageObj ) ) {
                # Register CSS file for our select box:
                global $wgOut, $wgScriptPath;
                $wgOut->addLink(
                array(
        'rel'  => 'stylesheet',
        'type' => 'text/css',
        'href' => "$wgScriptPath/extensions/SelectCategory/SelectCategory.css"
                )
                );
 
                # Get all categories from wiki:
                $m_allCats = fnSelectCategoryGetAllCategories();
                # Load system messages:
                wfLoadExtensionMessages( 'SelectCategory' );
                # Get the right member variables, depending on if we're on an upload form or not:
                if( !$m_isUpload ) {
                        # Extract all categorylinks from page:
                        $m_pageCats = fnSelectCategoryGetPageCategories( $m_pageObj );
 
                        # Never ever use editFormTextTop here as it resides outside the <form> so we will never get contents
                        $m_place = 'editFormTextAfterWarn';
                        # Print the localised title for the select box:
                        $m_textBefore = '<b>'. wfMsg( 'selectcategory-title' ) . '</b>:';
                } else {
                        # No need to get categories:
                        $m_pageCats = array();
 
                        # Place output at the right place:
                        $m_place = 'uploadFormTextAfterSummary';
                        # Print the part of the table including the localised title for the select box:
                        $m_textBefore = "\n</td></tr><tr><td align='right'><label for='wpSelectCategory'>" . wfMsg( 'selectcategory-title' ) .":</label></td><td align='left'>";
                }
                # Introduce the output:
                $m_pageObj->$m_place .= "<!-- SelectCategory begin -->\n";
                # Print the select box:
                $m_pageObj->$m_place .= "\n$m_textBefore";
                #    # First come up with the JavaScript version of the select boxes:
                #    $m_pageObj->$m_place .= "<script type=\"text/javascript\" src=\"'/extensions/SelectCategory/SelectCategory.js\"></script>\n";
                #    # Then the "old-style" select box for those without JavaScript:
                #    $m_pageObj->$m_place .= "<noscript>\n";
                #    $m_pageObj->$m_place .= "</noscript>\n";

                if ($what == 'EditPage' && (get_class($a) == 'CategoryPage' || get_class($a) == 'CategoryTreeCategoryPage')) {
                        //we are editing a category page, so we want to exclude the current category
                        //and its subcategories from the list!
                        $m_catString = strtolower( $wgContLang->getNsText( NS_CATEGORY ) );
                        # The regular expression to find the current category name:
                        $m_pattern = "({$m_catString}|category):([^\|\]]*)(\|{{PAGENAME}}|)";
                        preg_match( "/{$m_pattern}/i", $a->getTitle(), $cat);
                        if (is_array($cat) && count($cat) > 0) {
                                $currentcategory = $cat[2];
                        }
                } else {
                        $currentcategory = '';
                }
                $excludeuntillevel = '';
 
                $m_pageObj->$m_place .= "<ul id='SelectCategoryList'>";
                $text = '';
                foreach( $m_allCats as $m_cat => $m_depth ) {
                        $checkbox = true;
                        if ($currentcategory == $m_cat) {
                                $excludeuntillevel = $m_depth;
                                $checkbox = false;
                        } elseif ($excludeuntillevel !== '' && $m_depth > $excludeuntillevel) {
                                $checkbox = false;
                        } elseif ($excludeuntillevel !== '' && $m_depth == $excludeuntillevel) {
                                $excludeuntillevel = '';
                        }
 
                                $checked = '';
 
                                if (isset($m_pageCats[$m_cat])) {
                                        $checked = "checked='checked'";
                                }
 
                                $category =  htmlspecialchars( $m_cat );
 
                                # Indent subcategories
                                $indention = '';
                                for ($i = 0; $i < $m_depth; $i++) {
                                        $indention .= '&nbsp;&nbsp;';
                                }
                                //                              $text .=
                                if ($checkbox) {
                                        $m_pageObj->$m_place .= "
                                        <li>
                                        $indention<input type='checkbox' name='SelectCategoryList[]'
                                            value='$category' class='checkbox' $checked />
                                            $category
                                        </li>";
                                } else {
                                        $m_pageObj->$m_place .= "
                                        <li>
                                                $indention<input type='checkbox' name='SelectCategoryList[]'
                                            value='$category' class='checkbox' $checked disabled />
                                                        $category
                                        </li>";
                                }
                }
 
 
                #die();
                $m_pageObj->$m_place .= '</ul>';
                $m_pageObj->$m_place .= "<label for='wpEnterCategory'><b>".wfMsg( 'entercategory-title' ).'</b></label> '.
                        '<input name="wpEnterCategory" id="wpEnterCategory">'.'<br><br>';
 
                # Print localised help string:
                $m_pageObj->$m_place .= "<!-- SelectCategory end -->\n";
        }
 
        # Return true to let the rest work:
        return true;
}
 
## Entry point for the hook and main worker function for saving the page:
function fnSelectCategorySaveHook( $m_isUpload, &$m_pageObj ) {
        global $wgContLang;
        global $wgTitle;
 
        # check if we should do anything or sleep
        if ( fnSelectCategoryCheckConditions( $m_isUpload, &$m_pageObj ) ) {
 
                # Get localised namespace string:
                $m_catString = $wgContLang->getNsText( NS_CATEGORY );
 
                # default sort key is page name with stripped namespace name,
                # otherwise sorting is ugly.
                if ($wgTitle->getNamespace() == NS_MAIN) {
                        $default_sortkey = "";
                } else {
                        $default_sortkey = "|{{PAGENAME}}";
                }
 
                # Get some distance from the rest of the content:
                $m_text = "\n";
 
                # Iterate through all selected category entries:
                if (array_key_exists('SelectCategoryList', $_POST)) {
                        foreach( $_POST['SelectCategoryList'] as $m_cat ) {
                                $m_text .= "\n[[$m_catString:$m_cat$default_sortkey]]";
                        }
                }
 
                if (array_key_exists('wpEnterCategory', $_POST) && trim($_POST['wpEnterCategory']) != '') {
                        $m_text .= "\n[[$m_catString:".$_POST['wpEnterCategory']."]]";
                }
 
                # If it is an upload we have to call a different method:
                if ( $m_isUpload ) {
                        $m_pageObj->mUploadDescription .= $m_text;
                } else{
                        $m_pageObj->textbox1 .= $m_text;
                }
        }
 
        # Return to the let MediaWiki do the rest of the work:
        return true;
}
 
## Get all categories from the wiki - starting with a given root or otherwise detect root automagically (expensive)
## Returns an array like this:
## array (
##   'Name' => (int) Depth,
##   ...
## )
function fnSelectCategoryGetAllCategories() {
        global $wgTitle;
        global $wgSelectCategoryRoot;
 
        # Get current namespace (save duplicate call of method):
        $m_namespace = $wgTitle->getNamespace();
        if( $m_namespace >= 0 && $wgSelectCategoryRoot[$m_namespace] ) {
                # Include root and step into the recursion:
                $m_allCats = array_merge( array( $wgSelectCategoryRoot[$m_namespace] => 0 ), fnSelectCategoryGetChildren( $wgSelectCategoryRoot[$m_namespace] ) );
        } else {
                # Initialize return value:
                $m_allCats = array();
 
                # Get a database object:
                $m_dbObj =& wfGetDB( DB_SLAVE );
                # Get table names to access them in SQL query:
                $m_tblCatLink = $m_dbObj->tableName( 'categorylinks' );
                $m_tblPage = $m_dbObj->tableName( 'page' );
 
                # Automagically detect root categories:
                $m_sql = "  SELECT tmpSelectCat1.cl_to AS title
        FROM $m_tblCatLink AS tmpSelectCat1
        LEFT JOIN $m_tblPage AS tmpSelectCatPage ON (tmpSelectCat1.cl_to = tmpSelectCatPage.page_title AND tmpSelectCatPage.page_namespace = 14)
        LEFT JOIN $m_tblCatLink AS tmpSelectCat2 ON tmpSelectCatPage.page_id = tmpSelectCat2.cl_from
        WHERE tmpSelectCat2.cl_from IS NULL GROUP BY tmpSelectCat1.cl_to";
                # Run the query:
                $m_res = $m_dbObj->query( $m_sql, __METHOD__ );
                # Process the resulting rows:
                while ( $m_row = $m_dbObj->fetchRow( $m_res ) ) {
                        $m_allCats += array( $m_row['title'] => 0 );
                        $m_allCats += fnSelectCategoryGetChildren( $m_row['title'] );
                }
                # Free result:
                $m_dbObj->freeResult( $m_res );
        }
 
        # Afterwards return the array to the caller:
        return $m_allCats;
}
 
function fnSelectCategoryGetChildren( $m_root, $m_depth = 1 ) {
        # Initialize return value:
        $m_allCats = array();
 
        # Get a database object:
        $m_dbObj =& wfGetDB( DB_SLAVE );
        # Get table names to access them in SQL query:
        $m_tblCatLink = $m_dbObj->tableName( 'categorylinks' );
        $m_tblPage = $m_dbObj->tableName( 'page' );
 
        # The normal query to get all children of a given root category:
        $m_sql = "  SELECT tmpSelectCatPage.page_title AS title
      FROM $m_tblCatLink AS tmpSelectCat
      LEFT JOIN $m_tblPage AS tmpSelectCatPage ON tmpSelectCat.cl_from = tmpSelectCatPage.page_id
      WHERE tmpSelectCat.cl_to LIKE " . $m_dbObj->addQuotes( $m_root ) . " AND tmpSelectCatPage.page_namespace = 14";
        # Run the query:
        $m_res = $m_dbObj->query( $m_sql, __METHOD__ );
        # Process the resulting rows:
        while ( $m_row = $m_dbObj->fetchRow( $m_res ) ) {
                # Survive category link loops:
                if( $m_root == $m_row['title'] ) {
                        continue;
                }
 
                $m_row['title'] = str_replace(array('_'), ' ', $m_row['title']);
 
                # Add current entry to array:
                $m_allCats += array( $m_row['title'] => $m_depth );
                $m_allCats += fnSelectCategoryGetChildren( $m_row['title'], $m_depth + 1 );
        }
        # Free result:
        $m_dbObj->freeResult( $m_res );
 
        # Afterwards return the array to the upper recursion level:
        return $m_allCats;
}
 
## Returns an array with the categories the articles is in.
## Also removes them from the text the user views in the editbox.
function fnSelectCategoryGetPageCategories( $m_pageObj ) {
 
        if (array_key_exists('SelectCategoryList', $_POST)) {
                # We have already extracted the categories, return them instead
                # of extracting zero categories from the page text.
                $m_catLinks = array();
                foreach( $_POST['SelectCategoryList'] as $m_cat ) {
                        $m_catLinks[ $m_cat ] = true;
                }
                return $m_catLinks;
        }
 
        global $wgContLang;
 
        # Get page contents:
        $m_pageText = $m_pageObj->textbox1;
        # Get localised namespace string:
        $m_catString = strtolower( $wgContLang->getNsText( NS_CATEGORY ) );
        # The regular expression to find the category links:
        $m_pattern = "\[\[({$m_catString}|category):([^\|\]]*)(\|{{PAGENAME}}|)\]\]";
        $m_replace = "$2";
        # The container to store all found category links:
        $m_catLinks = array ();
        # The container to store the processed text:
        $m_cleanText = '';
 
        # Check linewise for category links:
        foreach( explode( "\n", $m_pageText ) as $m_textLine ) {
                # Filter line through pattern and store the result:
                $m_cleanText .= preg_replace( "/{$m_pattern}/i", "", $m_textLine ) . "\n";
                # Check if we have found a category, else proceed with next line:
                if( !preg_match( "/{$m_pattern}/i", $m_textLine) ) continue;
                # Get the category link from the original text and store it in our list:
                $m_catLinks[ str_replace( ' ', '_', preg_replace( "/.*{$m_pattern}/i", $m_replace, $m_textLine ) ) ] = true;
        }
        # Place the cleaned text into the text box:
        $m_pageObj->textbox1 = trim( $m_cleanText );
 
        # Return the list of categories as an array:
        return $m_catLinks;
}
 
# Function that checks if we meet the run conditions of the extension
function fnSelectCategoryCheckConditions ($m_isUpload, &$m_pageObj ) {
        global $wgSelectCategoryNamespaces;
        global $wgSelectCategoryEnableSubpages;
        global $wgTitle;
 
 
        # Run only if we are in an upload, an activated namespace or if page is
        # a subpage and subpages are enabled (unfortunately we can't use
        # implication in PHP) but not if we do a sectionedit:

        if ($m_isUpload == true) {
                return true;
        }
 
        $ns = $wgTitle->getNamespace();
        if (array_key_exists ($ns, $wgSelectCategoryNamespaces)) {
                $enabledForNamespace = $wgSelectCategoryNamespaces[$ns];
        } else {
                $enabledForNamespace = false;
        }
 
        # Check if page is subpage once to save method calls below:
        $m_isSubpage = $wgTitle->isSubpage();
 
        if ($enabledForNamespace
        && (!$m_isSubpage
        || $m_isSubpage && $wgSelectCategoryEnableSubpage)
        && $m_pageObj->section == false) {
                return true;
        }
}
Personal tools
Namespaces

Variants
Actions
Navigation
Support
Download
Development
Communication
Print/export
Toolbox