Extension:SubPageList3/SPL2Code
From MediaWiki.org
This is the code for Extension:SubPageList2.
<?php /** * Add a <subpages /> tag which produces a linked list of all subpages of the current page * * @package MediaWiki * @subpackage Extensions * @author Martin Schallnahs <myself@schaelle.de>, original Rob Church <robchur@gmail.com> * @copyright © 2006 Martin Schallnahs, original Rob Church * @licence GNU General Public Licence 2.0 or later * @link http://www.mediawiki.org/wiki/SubPageList2 * @todo better description * @todo usage of the attributes category, namespace and parent like ignore * @todo Add Mediawiki Entry * */ if( !defined( 'MEDIAWIKI' ) ) { echo( "This file is an extension to the MediaWiki software and cannot be used standalone.\n" ); die( 1 ); } if( file_exists( 'extensions/SubPageList.php' ) ) { echo ( "<strong>Fatal Error [Subpage List 2]:</strong> The orginal version of the SubpageList extension <em>(SubPageList.php)</em> is found in the extension dir, that may can produce a fatal error while using the <subpages> element.\n" ); die(1); } $wgExtensionFunctions[] = 'efSubpageList'; $wgExtensionCredits['parserhook'][] = array( 'name' => 'Subpage List 2', 'author' => 'Martin Schallnahs, Rob Church' ); /** * Hook in function */ function efSubpageList() { global $wgParser; $wgParser->setHook( 'subpages', 'efRenderSubpageList' ); } /** * Function called by the Hook, returns the wiki text */ function efRenderSubpageList( $input, $args, &$parser ) { $list = new SubpageList( $parser ); $list->options( $args ); return $list->render(); } /** * SubPageList2 class */ class SubpageList { /** * parser object * @var object parser object * @private */ var $parser; /** * title object * @var object title object * @private */ var $title; /** * language object * @var object language object * @private */ var $language; /** * Contain the cached content of the pages * @var array contain the cached content of the pages * @private */ var $articlecontent = array(); /** * category title of the pages * Can be: * - -1: all categorys * - string: title of a category * @var mixed category of listed pages * @private * @default -1 all */ var $category = -1; /** * count of articles be displayed * @var integer how much articles shall be displayed * @private * @default -1 all */ var $count = -1; /** * error display on or off * @var mixed error display on or off * @private * @default 0 hide errors */ var $debug = 0; /** * deepness of the subpages * @var integer deepness of the subpages * @private * @default -1 endless */ var $deepness = -1; /** * contain the error messages * @var array contain the errors messages * @private */ var $errors = array(); /** * headline size in a preview list * @var integer headline size in a preview list * @private * @default 2 normal */ var $headline = 2; /** * what pages shall be hide * @var mixed what pages shall hide * @private * @default -1 dont hide */ var $ignore = -1; /** * order type * Can be: * - ASC * - DESC * @var string order type * @private * @default ASC */ var $order = 'ASC'; /** * column thats used as order method * Can be: * - title: alphabetic order of a page title * - lastedit: Timestamp numeric order of the last edit of a page * @var string order method * @private * @default title */ var $ordermethod = 'title'; /** * mode of the output * Can be: * - unordered: UL list as output * - ordered: OL list as output * - preview: listing of the pages with headline and a preview in a specific output format * @var string mode of output * @private * @default unordered * @see $headline * @see $previewcount * @see $previemode */ var $mode = 'unordered'; /** * namespaces of the pages * Can be: * - -1: for all namespaces * - integer: ID of a namespace * @var mixed namespace of listed pages * @private * @default -1 all */ var $namespace = -1; /** * parent of the listed pages * Can be: * - -1: the current page title * - string: title of the specific title * e.g. if you are in Mainpage/ it will list all subpages of Mainpage/ * @var mixed parent of listed pages * @private * @default -1 current */ var $parent = -1; /** * how much letters are shown if the mode is preview * Can be: * - -1: the whole content of the page * - integer: $previewcount letters of thepage * - firstsection: the first section/part of the page (the most times the introduction) * @var integer how much letters are shown if the mode is preview * @private * @default -1 all * @see $mode */ var $previewcount = -1; /** * layout style of the preview * Can be: * - normal: normal layout * - pre: a tab before every line (using colons) * - tt: in the teletyper layout * - code: wrapped by a code unit * @var string layout style of the preview * @private * @default normal * @see $mode * @see $previewcount */ var $previewmode = 'normal'; /** * style of the path (title) * Can be: * - normal: normal, e.g. Mainpage/Entry/Sub * - notparent: the path without the $parent item, e.g. Entry/Sub * - no: no path, only the page title, e.g. Sub * @var string style of the path (title) * @private * @default normal * @see $parent */ var $showpath = 'normal'; /** * Constructor function of the class * @param object $parser the parser object * @global object $wgContLang * @see SubpageList * @private */ function SubpageList( &$parser ) { global $wgContLang; /** * assignment of the object to the classs vars * @see $parser * @see $title * @see $language */ $this->parser =& $parser; $this->title =& $parser->mTitle; $this->language =& $wgContLang; } /** * adds error to the $errors container * but only if $debug is true or 1 * @param string $message the errors message * @see $errors * @see $debug * @private */ function error( $message ) { if ( $this->debug || $this->debug == 1 ) { $this->errors[] = "<strong>Error [Subpage List 2]:</strong> $message"; } } /** * returns all errors as a string * @return string all errors seperated by a newline * @private */ function geterrors() { return implode( "\n", $this->errors ); } /** * check if there is any link to this cat * this is a sign if there is a cat * @param string $category the category title * @return boolean if there is a cat with this title * @todo Anyone in #mediawiki means this way isn't the best * @see $category */ function checkCat( $category ) { $dbr =& wfGetDB( DB_SLAVE ); $exists = $dbr->selectField( 'categorylinks', '1', array( 'cl_to' => $category ), __METHOD__ ); if( intval( $exists ) > 0 ) { return true; } else { return false; } } /** * parse the options that the user has entered * a bit long way, but because that it's easy to add alias * @param array $options the options inserts by the user as array * @see $category * @see $count * @see $debug * @see $deepness * @see $headline * @see $ignore * @see $order * @see $ordermethod * @see $mode * @see $namespace * @see $parent * @see $previewcount * @see $previewmode * @see $showpath * @private */ function options( $options ) { if( isset( $options['category'] ) ) { if( intval( $options['category'] ) == -1 ) { $this->category = -1; } else if( is_string( $options['category'] ) ) { if( $this->checkCat( $options['category'] ) ) { $this->category = $options['category']; } else { $this->error( "Using not defined category." ); } } else { $this->error( "Unknown value for option category." ); } } if( isset( $options['count'] ) ) { if( intval( $options['count'] ) == -1 || intval( $options['count'] ) > 0 ) { $this->count = round ( intval ( $options['count'] ) ); } else { $this->error( "Unknown value for option count." ); } } if( isset( $options['debug'] ) ) { if( $options['debug'] == 'true' || intval( $options['debug'] ) == 1 ) { $this->debug = 1; } else if( $options['debug'] == 'false' || intval( $options['debug'] ) == 0 ) { $this->debug = 1; } else { $this->error( "Unknown value for option debug." ); } } if( isset( $options['deepness'] ) ) { if( intval( $options['deepness'] ) == -1 || intval( $options['deepness'] ) > 0 ) { $this->deepness = round ( intval ( $options['deepness'] ) ); } else { $this->error( "Unknown value for option deepness." ); } } if( isset( $options['headline'] ) ) { if( intval( $options['headline'] ) == -1 || intval( $options['headline'] ) > 0 ) { $this->headline = round ( intval ( $options['headline'] ) ); } else { $this->error( "Unknown value for option headline." ); } } if( isset( $options['ignore'] ) && intval( $options['ignore'] ) != -1 ) { $cache = explode( '|', $options['ignore'] ); $ignore = array(); foreach( $cache as $aignore ) { $aignore_cache = trim( $aignore ); if( !empty( $aignore ) ) { $ignore[] = $aignore; } } if( count( $ignore ) > 0 ) { $this->ignore = $ignore; } else { $this->ignore = array( $options['ignore'] ); } } if( isset( $options['order'] ) ) { if( strtolower( $options['order'] ) == 'asc' ) { $this->order = 'asc'; } else if( strtolower( $options['order'] ) == 'desc' ) { $this->order = 'desc'; } else { $this->error( "Unknown value for option order." ); } } if( isset( $options['ordermethod'] ) ) { switch( strtolower( $options['ordermethod'] ) ) { case 'title': $this->ordermethod = 'title'; break; case 'lastedit': $this->ordermethod = 'lastedit'; break; default: $this->error( "Unknown value for option ordermethod." ); } } if( isset( $options['mode'] ) ) { switch( strtolower( $options['mode'] ) ) { case 'ordered': $this->mode = 'ordered'; break; case 'unordered': $this->mode = 'unordered'; break; case 'preview': $this->mode = 'preview'; break; default: $this->error( "Unknown value for option mode." ); } } if( isset( $options['namespace'] ) ) { if( intval( $options['namespace'] ) == -1 ) { $this->namespace = -1; } else if( intval( $options['namespace'] ) == 0 ) { $this->namespace = 0; } else if( is_string( $options['namespace'] ) ) { if( $this->language->getNsIndex( $options['namespace'] ) != false ) { $this->namespace = $this->language->getNsIndex( $options['namespace'] ); } else { $this->error( "Using not defined namespace." ); } } else { $this->error( "Unknown value for option namespace." ); } } if( isset( $options['parent'] ) ) { if( intval( $options['parent'] ) == -1 ) { $this->parent = -1; } else if( is_string( $options['parent'] ) ) { $this->parent = $options['parent']; } else { $this->error( "Unknown value for option parent." ); } } if( isset( $options['previewcount'] ) ) { if( intval( $options['previewcount'] ) == -1 || intval( $options['previewcount'] ) > 0 ) { $this->previewcount = round ( intval ( $options['previewcount'] ) ); } else if( strtolower( $options['previewcount'] == 'firstsection' ) ) { $this->previewcount = 'firstsection'; } else { $this->error( "Unknown value for option previewcount." ); } } if( isset( $options['previewmode'] ) ) { switch( strtolower( $options['previewmode'] ) ) { case 'normal': $this->previewmode = 'normal'; break; case 'pre': $this->previewmode = 'pre'; break; case 'tt': $this->previewmode = 'tt'; break; case 'code': $this->previewmode = 'code'; break; default: $this->error( "Unknown value for option previewmode." ); } } if( isset( $options['showpath'] ) ) { switch( strtolower( $options['showpath'] ) ) { case 'no': $this->showpath = 'no'; break; case 'notparent': $this->showpath = 'notparent'; break; case 'normal': $this->showpath = 'normal'; break; default: $this->error( "Unknown value for option showpath." ); } } } /** * produce output using this claSS * @return string html output * @private */ function render() { wfProfileIn( __METHOD__ ); $pages = $this->getTitles(); if( count( $pages ) > 0 ) { if( $this->mode == 'ordered' || $this->mode == 'unordered' ) { if( $this->mode == 'ordered' ) { $token = '#'; } else { $token = '*'; } $list = $this->makeList( $pages, $token ); } else if( $this->mode == 'preview' ) { $list = $this->makePreviewList( $pages, $this->articlecontent, $this->headline ); } $html = $this->parse( $list ); } else { $html = ''; } $html = $this->geterrors() . $html; wfProfileOut( __METHOD__ ); return "<div class=\"subpagelist\">{$html}</div>"; } /** * return the titles in a array * @return array all titles * @see $category * @see $count * @see $deepness * @see $headline * @see $ignore * @see $order * @see $ordermethod * @see $mode * @see $namespace * @see $parent * @see $previewcount * @private */ function getTitles() { wfProfileIn( __METHOD__ ); $dbr =& wfGetDB( DB_SLAVE ); $category = ''; $condtitions = array(); $deepness = ''; $options = array(); $order = strtoupper( $this->order ); $parent = ''; $page = $dbr->tableName( 'page' ); if( $this->category != -1 ) { $category = $this->category . ':'; } if( $this->count > 0 ) { $options['LIMIT'] = $this->count; } if( $this->deepness > 0 ) { $deepness = '(/.+){' . $this->deepness . '}'; } if( $this->namespace == -1 ) { $namespace = $this->title->getNamespace(); } else { $namespace = $this->namespace; } if( $this->ordermethod == 'title' ) { $options['ORDER BY'] = 'UPPER(`page_title`) ' . $order; } else if( $this->ordermethod == 'lastedit' ) { $options['ORDER BY'] = '`page_touched` ' . $order; } if( $this->parent != -1) { $parent = $this->parent; } else { $parent = $this->title->getDBkey(); } if( $this->ignore != -1 ) { $ignore = ''; foreach( $this->ignore as $aignore ) { $ignore .= 'AND `page_title` NOT LIKE ' . $dbr->addQuotes( $category . $parent . '/' . $aignore ); $conditions[] = '`page_title` NOT LIKE ' . $dbr->addQuotes( $category . $parent . '/' . $aignore ); } } if( $this->deepness == -1 && $this->parent != -1 ) { $parent .= '/.*'; } $conditions['page_namespace'] = $namespace; $conditions['page_is_redirect'] = 0; $conditions[] = '`page_title` REGEXP ' . $dbr->addQuotes( $category . $parent . $deepness ); $res = $dbr->select( 'page', 'page_title', $conditions, __METHOD__, $options ); $titles = array(); $content = array(); while( $row = $dbr->fetchObject( $res ) ) { $title = Title::makeTitleSafe( $namespace, $row->page_title ); if( is_object( $title ) ) { $titles[] = $title; $article = new Article( $title ); if( $this->previewcount == -1 ) { $content[$title->getText()] = $article->getContent(); } else if( $this->previewcount == 'firstsection' ) { $content[$title->getText()] = $article->getSection( $article->getContent(), 0 ) . ' ...'; } else { $content[$title->getText()] = substr( $article->getContent(), 0, $this->previewcount ) . ' ...'; } } } $this->articlecontent = $content; $dbr->freeResult( $res ); wfProfileOut( __METHOD__ ); return $titles; } /** * adds a double point before every line * @param string $text the text where colons shall be add * @return string the new text */ function makePreText( $text ) { return ':' . str_replace( "\n", "\n:", $text ); } /** * create one list item * cases: * - normal: normal, e.g. Mainpage/Entry/Sub * - notparent: the path without the $parent item, e.g. Entry/Sub * - no: no path, only the page title, e.g. Sub * @param string $title the title of a page * @return string the prepared string * @see $showpath */ function makeListItem( $title ) { switch( $this->showpath ) { case 'no': $linktitle = substr( strrchr( $title->getText(), "/" ), 1 ); break; case 'notparent': $linktitle = substr( strstr( $title->getText(), "/" ), 1 ); break; case 'normal': $linktitle = $title->getText(); } return ' [[' . $title->getPrefixedText() . '|' . $linktitle . ']]'; } /** * creating headline for preview "list" using makeListItem * that means add the equal chars * @param string $title the title of a page * @return string the prepared title * @see $headline * @see SubPageList::makeListItem */ function makeHeadline( $title ) { $headcode = ''; for( $i = 1; $i <= intval( $this->headline ); $i++ ) $headcode .= '='; return $headcode . ' ' . $this->makeListItem( $title ) . ' ' . $headcode; } /** * create whole list using makeListItem * @param string $titles all page titles * @param string $token the token symbol: * - * for ul, * - # for ol * @return string the whole list * @see SubPageList::makeListItem */ function makeList( $titles, $token ) { foreach( $titles as $title ) $list[] = $token . $this->makeListItem( $title ); return implode( "\n", $list ); } /** * create preview list * listing of the pages with headline and a preview in a specific output format * styles: * - normal: normal layout * - pre: a tab before every line (using colons) * - tt: in the teletyper layout * - code: wrapped by a code unit * @param array $titles the page titles - used to get the content out of $articlecontent * @param array $article the article content * @return string the preview list * @see $articlecontent * @see $title */ function makePreviewList( $titles, $article ) { $list = array(); foreach( $titles as $title ) { switch( $this->previewmode ) { case 'normal': $content = $article[$title->getText()]; break; case 'pre': $content = $this->makePreText( $article[$title->getText()] ); break; case 'tt': $content = '<tt>' . $article[$title->getText()] . '</tt>'; break; case 'code': $content = '<code>' . $article[$title->getText()] . '</code>'; break; default: $this->error( "Unknown value for option previewmode." ); } $list[] = $this->makeHeadline( $title ) . "\n" . $content . ''; } return implode( "\n", $list ); } /** * Wrapper function parse, call the other functions * @param string $text the content * @return string the parsed output */ function parse( $text ) { wfProfileIn( __METHOD__ ); $options =& $this->parser->mOptions; $output = $this->parser->parse( $text, $this->title, $options, true, false ); wfProfileOut( __METHOD__ ); return $output->getText(); } } ?>

