http://www.mediawiki.org/wiki/Special:Code/MediaWiki/91952

Revision: 91952
Author:   jeroendedauw
Date:     2011-07-12 12:44:07 +0000 (Tue, 12 Jul 2011)
Log Message:
-----------
applied patch by Van de Bugger

Modified Paths:
--------------
    trunk/extensions/SubPageList/SubPageList.class.php
    trunk/extensions/SubPageList/SubPageList.i18n.php
    trunk/extensions/SubPageList/SubPageList.php

Modified: trunk/extensions/SubPageList/SubPageList.class.php
===================================================================
--- trunk/extensions/SubPageList/SubPageList.class.php  2011-07-12 12:42:57 UTC 
(rev 91951)
+++ trunk/extensions/SubPageList/SubPageList.class.php  2011-07-12 12:44:07 UTC 
(rev 91952)
@@ -11,6 +11,7 @@
  * @licence GNU GPL v3 or later
  *
  * @author Jeroen De Dauw
+ * @author Van de Bugger
  * @author James McCormack (email: user "qedoc" at hotmail); preceding version 
Martin Schallnahs <[email protected]>, original Rob Church <[email protected]>
  * @copyright © 2008 James McCormack, preceding version Martin Schallnahs, 
original Rob Church
  */
@@ -68,20 +69,20 @@
                
                $params['sortby'] = new Parameter( 'sortby' );
                $params['sortby']->addCriteria( new CriterionInArray( 'title', 
'lastedit' ) );
-               $params['sortby']->addManipulations( new 
ParamManipulationFunctions( 'strtolower' ) );          
+               $params['sortby']->addManipulations( new 
ParamManipulationFunctions( 'strtolower' ) );
                $params['sortby']->setDefault( 'title' );
                $params['sortby']->setDescription( wfMsg( 
'spl-subpages-par-sortby' ) );
                
                $params['format'] = new Parameter( 'format' );
-               $params['format']->addAliases( 'liststyle' );           
+               $params['format']->addAliases( 'liststyle' );
                $params['format']->addCriteria( new CriterionInArray(
                        'ul', 'unordered',
                        'ol', 'ordered',
-                       'list', 'bar'                   
+                       'list', 'bar'
                ) );
-               $params['format']->addManipulations( new 
ParamManipulationFunctions( 'strtolower' ) );          
-               $params['format']->setDefault( 'ul' );  
-               $params['format']->setDescription( wfMsg( 
'spl-subpages-par-format' ) );        
+               $params['format']->addManipulations( new 
ParamManipulationFunctions( 'strtolower' ) );
+               $params['format']->setDefault( 'ul' );
+               $params['format']->setDescription( wfMsg( 
'spl-subpages-par-format' ) );
                
                $params['page'] = new Parameter( 'page' );
                $params['page']->addAliases( 'parent' );
@@ -90,18 +91,20 @@
                
                $params['showpage'] = new Parameter( 'showpage', 
Parameter::TYPE_BOOLEAN );
                $params['showpage']->addAliases( 'showparent' );
-               $params['showpage']->setDefault( 'no' );                        
+               $params['showpage']->setDefault( 'no' );
                $params['showpage']->setDescription( wfMsg( 
'spl-subpages-par-showpage' ) );
                
                $params['pathstyle'] = new Parameter( 'pathstyle' );
                $params['pathstyle']->addAliases( 'showpath' );
                $params['pathstyle']->addCriteria( new CriterionInArray(
                        'none', 'no',
-                       'children', 'notparent',
-                       'full'
+                       'subpagename', 'children', 'notparent',
+                       'pagename',
+                       'full',                 // Deprecate? --vdb
+                       'fullpagename'
                ) );
                $params['pathstyle']->setDefault( 'none' );
-               $params['pathstyle']->addManipulations( new 
ParamManipulationFunctions( 'strtolower' ) );       
+               $params['pathstyle']->addManipulations( new 
ParamManipulationFunctions( 'strtolower' ) );
                $params['pathstyle']->setDescription( wfMsg( 
'spl-subpages-par-pathstyle' ) );
                
                $params['kidsonly'] = new Parameter( 'kidsonly', 
Parameter::TYPE_BOOLEAN );
@@ -110,8 +113,21 @@
                
                $params['limit'] = new Parameter( 'limit', 
Parameter::TYPE_INTEGER );
                $params['limit']->setDefault( 200 );
-               $params['limit']->addCriteria( new CriterionInRange( 1, 500 ) 
);                        
+               $params['limit']->addCriteria( new CriterionInRange( 1, 500 ) );
                $params['limit']->setDescription( wfMsg( 
'spl-subpages-par-limit' ) );
+
+               // TODO: Add description strings. --vdb
+               $params['element'] = new Parameter( 'element', 
Parameter::TYPE_STRING, 'div' );
+               $params['element']->addCriteria( new CriterionInArray( 'div', 
'p', 'span' ) );
+               $params['class'] = new Parameter( 'class', 
Parameter::TYPE_STRING, 'subpagelist' );
+               $params['intro'] = new Parameter( 'intro', 
Parameter::TYPE_STRING, '' );
+               $params['outro'] = new Parameter( 'outro', 
Parameter::TYPE_STRING, '' );
+               $params['default'] = new Parameter( 'default', 
Parameter::TYPE_STRING, '' );
+               $params['separator'] = new Parameter( 'separator', 
Parameter::TYPE_STRING, '&#160;· ' );
+               $params['separator']->addAliases( 'sep' );
+               $params['template'] = new Parameter( 'template', 
Parameter::TYPE_STRING, '' );
+               $params['links'] = new Parameter( 'links', 
Parameter::TYPE_BOOLEAN, true );
+               $params['links']->addAliases( 'link' );
                
                return $params;
        }
@@ -140,17 +156,65 @@
         */
        public function render( array $parameters ) {
                $title = $this->getTitle( $parameters );
-               
                $pages = $this->getSubPages( $title, $parameters );
-               
+               // There is no need in encoding `$parameters['element']', 
because it is validated and can
+               // be only one of `span', `p', or `div'.
+               $element = $parameters['element'];
+               // Using `$parameters['class']' is dangerous and may be a 
security hole, because it may lead
+               // to incorrect (or malicious) HTML code. `encodeAttribute' 
solves the issue.
+               $class = Sanitizer::encodeAttribute( $parameters['class'] );
+               $open = "<$element class=\"$class\">";
+               $close = "</$element>";
+               $inlineList = ( $parameters['format'] == 'list' || 
$parameters['format'] == 'bar' );
+               $inlineText = ( $element == 'span' );
+               $list = '';
+
                if ( count( $pages ) > 0 ) {
-                       $list = $this->makeList( $title, $parameters, $pages );
+                       $intro = $parameters['intro'];
+                       $outro = $parameters['outro'];
+                       if ( $inlineText && ! $inlineList ) {
+                               if ( $intro !== '' ) {
+                                       $list .= $open . $intro . $close;
+                               }
+                               $list .=
+                                       "<div class=\"$class\">" .
+                                       $this->makeList( $title, $parameters, 
$pages ) .
+                                       "</div>";
+                               if ( $outro !== "" ) {
+                                       $list .= $open . $outro . $close;
+                               }
+                       }
+                       else {
+                               $list =
+                                       $open . $intro . 
+                                       $this->makeList( $title, $parameters, 
$pages ) .
+                                       $outro . $close;
+                       }
+                       $list = $this->parseWikitext( $list );
                }
                else {
-                       $list = "''" . wfMsg( 'spl-nosubpages', '[[' . 
$title->getFullText() . ']]' ) . "''\n";
+                       $default = $parameters['default'];
+                       if ( $default === "" ) {
+                               if ( is_null( $title ) ) {
+                                       $list = "''" . wfMsg( 
'spl-noparentpage', $parameters['page'] ) . "''";
+                               }
+                               elseif ( $title instanceof Title ) {
+                                       $list = "''" . wfMsg( 'spl-nosubpages', 
'[[' . $title->getFullText() . ']]' ) . "''";
+                               }
+                               else {
+                                       $list = "''" . wfMsg( 'spl-nopages', 
$parameters['page'] ) . "''";
+                               }
+                       }
+                       elseif ( $default !== "-" ) {
+                               $list = $default;
+                       }
+                       // Format element only if content is not empty. 
+                       if ( $list !== "" ) {
+                               $list = $open . $this->parseWikitext( $list ) . 
$close;
+                       }
                }
-               
-               return "<div class='subpagelist'>\n" . $this->parseWikitext( 
$list ) . "\n</div>";
+
+               return $list;
        }       
        
        /**
@@ -160,23 +224,32 @@
         * 
         * @param array $parameters
         * 
-        * @return Title
+        * @return Instance of Title class — title of an existing page, or 
integer — index of an
+        * existing namespace, or null otherwise.
         */
        protected function getTitle( array $parameters ) {
-               $title = false;
+               global $wgContLang;
                
-               if ( $parameters['page'] != '' ) {
-                       $specifiedTitle = Title::newFromText( 
$parameters['page'] );
-                       
-                       if ( !is_null( $specifiedTitle ) && 
$specifiedTitle->exists() ) {
-                               $title = $specifiedTitle;
+               $page = $parameters['page'];
+               $title = null;
+
+               if ( $page == '' ) {
+                       $title = $this->parser->mTitle;
+               }
+               else {
+                       $title = Title::newFromText( $page );
+                       if ( is_null( $title ) ) {
+                               // It is a wrog page name. Probably it is a 
namespace name?
+                               $m = array();
+                               if ( preg_match( '/^\s*(.*):\s*$/', $page, $m ) 
) {
+                                       $title = $wgContLang->getNsIndex( $m[ 1 
] );
+                               }
                        }
+                       else if ( ! $title->exists() ) {
+                               $title = null;
+                       }
                }
                
-               if ( $title === false ) {
-                       $title = $this->parser->mTitle;
-               }
-
                return $title;
        }
 
@@ -185,69 +258,110 @@
         * 
         * @since 0.1
         * 
-        * @param Title $title
+        * @param $title can be either an instance of Title class (title of an 
existing page), or number
+        *        (index of an existing namespace) or null.
         * @param array $parameters
         * 
         * @return array of Title
         */
        protected function getSubPages( Title $title, array $parameters ) {
                $titles = array();
-               
-               $dbr = wfGetDB( DB_SLAVE );
-               
-               $options = array();
-               $options['ORDER BY'] = 
-                       ( $parameters['sortby'] == 'title' ? 'page_title' : 
'page_touched' ) . ' ' .
-                       ( strtoupper( $parameters['sort'] ) );
-               $options['LIMIT'] = $parameters['limit'];
 
-               $conditions = array();
-               $conditions['page_namespace'] = $title->getNamespace(); // 
Don't let list cross namespaces.
-               $conditions['page_is_redirect'] = 0;
-               
-               // TODO: this is rather resource heavy
-               $conditions[] = 'page_title ' . $dbr->buildLike( 
$title->getDBkey() . '/', $dbr->anyString() );
+               if ( ! is_null( $title ) ) {
+                       // TODO: Check whether subpages enabled?
+                       $dbr = wfGetDB( DB_SLAVE );
+                       
+                       $options = array();
+                       $options['ORDER BY'] = 
+                               ( $parameters['sortby'] == 'title' ? 
'page_title' : 'page_touched' ) . ' ' .
+                               ( strtoupper( $parameters['sort'] ) );
+                       $options['LIMIT'] = $parameters['limit'];
 
-               $fields = array();
-               $fields[] = 'page_title';
-               $fields[] = 'page_namespace';
-               
-               $res = $dbr->select( 'page', $fields, $conditions, __METHOD__, 
$options );
-
-               foreach( $res as $row ) {
-                       $title = Title::makeTitleSafe( $row->page_namespace, 
$row->page_title );
-                       if( is_object( $title ) ) {
-                               $titles[] = $title;
+                       $conditions = array();
+                       $conditions['page_is_redirect'] = 0;
+                       if ( $title instanceof Title ) {
+                               $conditions['page_namespace'] = 
$title->getNamespace(); // Don't let list cross namespaces.
+                               // TODO: this is rather resource heavy
+                               $conditions[] = 'page_title ' . 
$dbr->buildLike( $title->getDBkey() . '/', $dbr->anyString() );
+                               if ( $parameters['kidsonly'] ) {
+                                       $conditions[] = 'page_title NOT ' . 
$dbr->buildLike( $title->getDBkey() . '/', $dbr->anyString(), '/', 
$dbr->anyString() );
+                               }
                        }
-               }               
-               
-               $dbr->freeResult( $res );
+                       else {
+                               $conditions['page_namespace'] = $title;
+                               if ( $parameters['kidsonly'] ) {
+                                       // Request only root pages, not 
subpages.
+                                       $conditions[] = 'page_title NOT ' . 
$dbr->buildLike( $dbr->anyString(), '/', $dbr->anyString() );
+                               }
+                           else {
+                                       $conditions[] = 'page_title ' . 
$dbr->buildLike( $dbr->anyString() );
+                               }
+                       }
 
+                       $fields = array();
+                       $fields[] = 'page_title';
+                       $fields[] = 'page_namespace';
+
+                       $res = $dbr->select( 'page', $fields, $conditions, 
__METHOD__, $options );
+
+                       foreach( $res as $row ) {
+                               $title = Title::makeTitleSafe( 
$row->page_namespace, $row->page_title );
+                               if( is_object( $title ) ) {
+                                       $titles[] = $title;
+                               }
+                       }               
+                       
+                       $dbr->freeResult( $res );
+
+               }
+
                return $titles;
        }
        
        /**
         * Creates one list item.
         *  
-        * @param Title $title the title of a page
-        * @param array $parameters
+        * @param $fullName — Full name of page, including namespace (but 
excluding fragment).
+        * @param $nsLen — Length of namespace name (including colon, if any).
+        * @param $parentLen — Length of parent title (not including namespace 
but including slash).
         * 
         * @return string: wikitext for the list item
         */
-       protected function makeListItem( Title $title, array $parameters ) {
+       protected function makeListItem( $fullName, $nsLen, $parentLen, array 
$parameters ) {
                switch( $parameters['pathstyle'] ) {
-                       case 'none' : case 'no' : 
-                               $linktitle = substr( strrchr( 
$title->getText(), "/" ), 1 );
+                       case 'none' : case 'no' :
+                               // Just a last item.
+                               $slash = strrpos( $fullName, '/' );
+                               if ( $slash ) {
+                                       $item = substr( $fullName, $slash + 1 
);  // +1 to skip slash.
+                               }
+                               else {
+                                       $item = substr( $fullName, $nsLen ); 
+                               }
                                break;
-                       case 'children' : case 'notparent' : 
-                               $linktitle = substr( strstr( $title->getText(), 
"/" ), 1 );
+                       case 'subpagename' : case 'children' : case 'notparent' 
:
+                               // Pagename starting from parent.
+                               $item = substr( $fullName, $nsLen + $parentLen 
);
                                break;
-                       case 'full' :
-                               $linktitle = $title->getText();
+                       case 'pagename' : case 'full' :
+                               // Almost full (without namespace).
+                               $item = substr( $fullName, $nsLen );
                                break;
+                       case 'fullpagename' :
+                               // Full name (including namespace).
+                               $item = $fullName;
+                               break;
                }
                
-               return ' [[' . $title->getFullText() . '|' . $linktitle . ']]';
+               if ( $parameters['links'] ) {
+                       $item = "[[$fullName|$item]]";
+               }
+               
+               if ( $parameters['template'] !== '' ) {
+                       $item = '{{' . $parameters['template'] . '|' . $item . 
'}}';
+               }
+               
+               return $item;
        }
 
        /**
@@ -262,69 +376,95 @@
         * @return string the whole list
         */
        protected function makeList( Title $title, array $parameters, array 
$titles ) {
-               $token = '';
-               $isSingleLine = false;
-               
+               global $wgContLang;
+               $start = '';    // String to render once in the very beginning 
of each item.
+               $bullet = '';   // String to render between `$start' and item
+                                               // (may be rendered few times, 
depends on nesting level).
+               $sep = '';              // String to render between two items.
                $items = array();
                
                switch ( $parameters['format'] ) {
                        case 'ol' : case 'ordered' :
-                               $token = '#';
+                               $start = "\n";
+                               $bullet = '#';
                                break;
                        case 'ul' : case 'unordered' : 
-                               $token = '*';
+                               $start = "\n";
+                               $bullet = '*';
                                break;
                        case 'list' : case 'bar' :
-                               $isSingleLine = true;
-                               $token = '&#160;· ';
+                               $sep = $parameters['separator'];
                                break;
                }
-               
-               if ( $parameters['showpage'] ) {
-                       $item = '[[' . $title->getFullText() .'|'. 
$title->getText() .']]';
-                       
-                       if ( !$isSingleLine ) {
-                               $item = $token . $item;
+               // A kind of optimization: I do not want to run loop every time 
I need series of bullets.
+               // Let us intialize $bullets array so $bullets[$i] is a bullet 
repeated $i times.
+               $bullets = array();
+               $bullets[0] = $bullet;
+
+               // WARNING: It seems strlen and other sring functions operated 
with bytes, not characters.
+               // But it seems it is ok for UTF-8 encoding...
+
+               if ( $title instanceof Title ) {
+                       $nsName = $title->getNsText();            // Namespace 
name.
+                       $parentFull = $title->getPrefixedText();  // Including 
namespace.
+                       $parentText = $title->getText();          // Not 
including namespace.
+                       $parentSlashCount = substr_count( $parentFull, '/' );
+               }
+               else {
+                       $nsName = $wgContLang->getNsText( $title );
+                       $parentFull = $nsName;
+                       $parentText = '';
+                       $parentSlashCount = -1;
+               }
+               // If prefix (namespace name) is not empty, count subsequent 
colon also.
+               $nsLen = strlen( $nsName );
+               if ( $nsLen > 0 ) {
+                       ++ $nsLen;
+               }
+               // If parent page name is not empty, count subsequent slash 
also.
+               $parentLen = strlen( $parentText );
+               if ( $parentLen > 0 ) {
+                       ++ $parentLen;
+               }
+               // Max nesting level. 
+               $maxLevel = ( $parameters['kidsonly'] ? 1 : 1000 );
+
+               if ( $parameters['showpage'] && $title instanceof Title ) {
+                       // If parent should be shown, correct starting point:
+                       $slash = strrpos( $parentText, "/" );
+                       if ( $slash ) {
+                               $parentLen = $slash + 1;
                        }
-                       
-                       $items[] = trim( $item );
+                       else {
+                               $parentLen = 0;
+                       }
+                       -- $parentSlashCount;
+                       ++ $maxLevel;
+                       // Render page itself as the very first item of the 
list.
+                       $item =
+                               $start . $bullet .
+                               $this->makeListItem( $parentFull, $nsLen, 
$parentLen, $parameters );
+                       $items[] = $item;
                }
-               
-               $parentLevel = substr_count( $title->getFullText(), '/' );
-               
-               $isFirst = true;
-               
-               foreach( $titles as $subPageTitle ) {
-                       $level = substr_count( $subPageTitle->getFullText(), 
'/' ) - $parentLevel;      
-                       
-                       if ( !$parameters['kidsonly'] || $level < 2 ) {
-                               
-                               if ( $parameters['showpage'] ) {
-                                       $level++;
-                               }
-                               
+
+               foreach( $titles as $pageTitle ) {
+                       $pageFull = $pageTitle->getPrefixedText();
+                       $level = substr_count( $pageFull, '/' ) - 
$parentSlashCount;
+                       if ( $level <= $maxLevel ) {
                                $item = '';
-                               
-                               if( $isSingleLine ) {
-                                       if( $isFirst ) {
-                                               $item .= ': ';
-                                       }
-                                       else {
-                                               $item .= $token;
-                                       }
-                               } else {
-                                       for ( $i = 0; $i < $level; $i++ ) {
-                                               $item .= $token;
-                                       }
+                               if ( $bullet != '' ) {
+                                       // Make sure $bullets[ $level ] is 
properly initialized.
+                                       for ( $l = sizeof( $bullets ); $l <= 
$level; ++ $l ) {
+                                               $bullets[$l] = $bullets[$l - 1] 
. $bullet;
+                                       } 
+                                       $item .= $start . $bullets[ $level ];
                                }
-                               
-                               $items[] = trim( $item . $this->makeListItem( 
$subPageTitle, $parameters ) );
+                               $item .= $this->makeListItem( $pageFull, 
$nsLen, $parentLen, $parameters );
+                               $items[] = $item; 
                        }
-                       
-                       $isFirst = false;
                }
 
-               return implode( $isSingleLine ? '' : "\n", $items );
+               return implode( $sep, $items );
        }
 
        /**
@@ -340,6 +480,6 @@
                        'noparse' => true,
                        'isHTML' => true
                );
-       }       
+       }
        
 }

Modified: trunk/extensions/SubPageList/SubPageList.i18n.php
===================================================================
--- trunk/extensions/SubPageList/SubPageList.i18n.php   2011-07-12 12:42:57 UTC 
(rev 91951)
+++ trunk/extensions/SubPageList/SubPageList.i18n.php   2011-07-12 12:44:07 UTC 
(rev 91952)
@@ -19,7 +19,9 @@
 $messages['en'] = array(
        'spl-desc' => 'Adds a <code><nowiki><splist /></nowiki></code> tag that 
enables you to list subpages',
 
-       'spl-nosubpages' => '$1 has no subpages to list.',
+       'spl-nosubpages' => 'Page "$1" has no subpages to list.',
+       'spl-noparentpage' => 'Page "$1" does not exist.',
+       'spl-nopages' => 'Namespace "$1" does not have pages.',
 
        'spl-subpages-par-sort' => 'The direction to sort in.',
        'spl-subpages-par-sortby' => 'What to sort the subpages by.',
@@ -313,9 +315,11 @@
  */
 $messages['ru'] = array(
        'spl-desc' => 'Добавляет тег 
<code><nowiki><splist></splist></nowiki></code>, выводящий список подстраниц',
-       'spl-nosubpages' => '$1 не имеет подстраниц.',
+       'spl-nosubpages' => 'Страница «$1» не имеет подстраниц.',
+       'spl-noparentpage' => 'Страница «$1» не существует.',
+       'spl-nopages' => 'Пространство имён  «$1» не содержит страниц.',
        'spl-subpages-par-sort' => 'Направление сортировки.',
-       'spl-subpages-par-sortby' => 'По чему сортировать подстраницы.',
+       'spl-subpages-par-sortby' => 'Ключ сортировки: название (title) или 
дата последней правки (lastedit).',
        'spl-subpages-par-format' => 'Список подстраниц может быть показан в 
нескольких форматах. Нумерованный список (ol), маркированный список (ul), 
список через запятые (list).',
        'spl-subpages-par-page' => 'Страница для которой показывать список 
подстраниц. По умолчанию текущая страница.',
        'spl-subpages-par-showpage' => 'Указывает, должна ли отображаться сама 
страница.',
@@ -357,4 +361,3 @@
        'spl-subpages-par-page' => 'Сторінка, для якої показати підсторінки. За 
умовчанням — поточна сторінка.',
        'spl-subpages-par-limit' => 'Максимальна кількість сторінок у списку.',
 );
-

Modified: trunk/extensions/SubPageList/SubPageList.php
===================================================================
--- trunk/extensions/SubPageList/SubPageList.php        2011-07-12 12:42:57 UTC 
(rev 91951)
+++ trunk/extensions/SubPageList/SubPageList.php        2011-07-12 12:44:07 UTC 
(rev 91952)
@@ -35,7 +35,7 @@
        die( '<b>Error:</b> You need to have <a 
href="http://www.mediawiki.org/wiki/Extension:Validator";>Validator</a> 
installed in order to use <a 
href="http://www.mediawiki.org/wiki/Extension:SubPageList";>SubPageList</a>.<br 
/>' );
 }
 
-define( 'SPL_VERSION', '0.3' );
+define( 'SPL_VERSION', '0.4 alpha' );
 
 $wgExtensionCredits['parserhook'][] = array(
        'path' => __FILE__,


_______________________________________________
MediaWiki-CVS mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-cvs

Reply via email to