2020-11-22 20:02:14 +00:00
|
|
|
<?php
|
|
|
|
/**
|
|
|
|
* DynamicPageList3
|
|
|
|
* DPL List Class
|
|
|
|
*
|
|
|
|
* @license GPL-2.0-or-later
|
|
|
|
* @package DynamicPageList3
|
|
|
|
*
|
2021-02-22 23:48:01 +00:00
|
|
|
*/
|
2020-11-22 20:02:14 +00:00
|
|
|
namespace DPL\Heading;
|
|
|
|
|
|
|
|
use DPL\Article;
|
|
|
|
use DPL\Lister\Lister;
|
|
|
|
use DPL\Parameters;
|
|
|
|
|
|
|
|
class Heading {
|
|
|
|
/**
|
|
|
|
* Listing style for this class.
|
|
|
|
*
|
2021-02-22 23:48:01 +00:00
|
|
|
* @var constant
|
2020-11-22 20:02:14 +00:00
|
|
|
*/
|
|
|
|
public $style = null;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* List(Section) Start
|
|
|
|
* Use %s for attribute placement. Example: <div%s>
|
|
|
|
*
|
2021-02-22 23:48:01 +00:00
|
|
|
* @var string
|
2020-11-22 20:02:14 +00:00
|
|
|
*/
|
|
|
|
public $listStart = '';
|
|
|
|
|
|
|
|
/**
|
|
|
|
* List(Section) End
|
|
|
|
*
|
2021-02-22 23:48:01 +00:00
|
|
|
* @var string
|
2020-11-22 20:02:14 +00:00
|
|
|
*/
|
|
|
|
public $listEnd = '';
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Item Start
|
|
|
|
* Use %s for attribute placement. Example: <div%s>
|
|
|
|
*
|
2021-02-22 23:48:01 +00:00
|
|
|
* @var string
|
2020-11-22 20:02:14 +00:00
|
|
|
*/
|
|
|
|
public $itemStart = '';
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Item End
|
|
|
|
*
|
2021-02-22 23:48:01 +00:00
|
|
|
* @var string
|
2020-11-22 20:02:14 +00:00
|
|
|
*/
|
|
|
|
public $itemEnd = '';
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Extra list HTML attributes.
|
|
|
|
*
|
2021-02-22 23:48:01 +00:00
|
|
|
* @var array
|
2020-11-22 20:02:14 +00:00
|
|
|
*/
|
|
|
|
public $listAttributes = '';
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Extra item HTML attributes.
|
|
|
|
*
|
2021-02-22 23:48:01 +00:00
|
|
|
* @var array
|
2020-11-22 20:02:14 +00:00
|
|
|
*/
|
|
|
|
public $itemAttributes = '';
|
|
|
|
|
|
|
|
/**
|
|
|
|
* If the article count per heading should be shown.
|
|
|
|
*
|
2021-02-22 23:48:01 +00:00
|
|
|
* @var bool
|
2020-11-22 20:02:14 +00:00
|
|
|
*/
|
|
|
|
protected $showHeadingCount = false;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* \DPL\Parameters
|
|
|
|
*
|
2021-02-22 23:48:01 +00:00
|
|
|
* @var object
|
2020-11-22 20:02:14 +00:00
|
|
|
*/
|
|
|
|
protected $parameters = null;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Main Constructor
|
|
|
|
*
|
|
|
|
* @access public
|
|
|
|
* @param object \DPL\Parameters
|
|
|
|
* @return void
|
|
|
|
*/
|
2021-02-22 23:48:01 +00:00
|
|
|
public function __construct( Parameters $parameters ) {
|
|
|
|
$this->setListAttributes( $parameters->getParameter( 'hlistattr' ) );
|
|
|
|
$this->setItemAttributes( $parameters->getParameter( 'hitemattr' ) );
|
|
|
|
$this->setShowHeadingCount( $parameters->getParameter( 'headingcount' ) );
|
2020-11-22 20:02:14 +00:00
|
|
|
$this->parameters = $parameters;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get a new List subclass based on user selection.
|
|
|
|
*
|
|
|
|
* @access public
|
|
|
|
* @param string Heading style.
|
|
|
|
* @param object \DPL\Parameters
|
|
|
|
* @param object MediaWiki \Parser
|
|
|
|
* @return mixed Heading subclass or null for a bad style.
|
|
|
|
*/
|
2021-02-22 23:48:01 +00:00
|
|
|
public static function newFromStyle( $style, \DPL\Parameters $parameters ) {
|
|
|
|
$style = strtolower( $style );
|
|
|
|
switch ( $style ) {
|
2020-11-22 20:02:14 +00:00
|
|
|
case 'definition':
|
|
|
|
$class = 'DefinitionHeading';
|
|
|
|
break;
|
|
|
|
case 'h1':
|
|
|
|
case 'h2':
|
|
|
|
case 'h3':
|
|
|
|
case 'h4':
|
|
|
|
case 'h5':
|
|
|
|
case 'h6':
|
|
|
|
case 'header':
|
|
|
|
$class = 'TieredHeading';
|
|
|
|
break;
|
|
|
|
case 'ordered':
|
|
|
|
$class = 'OrderedHeading';
|
|
|
|
break;
|
|
|
|
case 'unordered':
|
|
|
|
$class = 'UnorderedHeading';
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
return null;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
$class = '\DPL\Heading\\' . $class;
|
|
|
|
|
2021-02-22 23:48:01 +00:00
|
|
|
return new $class( $parameters );
|
2020-11-22 20:02:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get the \DPL\Parameters object this object was constructed with.
|
|
|
|
*
|
|
|
|
* @access public
|
|
|
|
* @return object \DPL\Parameters
|
|
|
|
*/
|
|
|
|
public function getParameters() {
|
|
|
|
return $this->parameters;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Set extra list attributes.
|
|
|
|
*
|
|
|
|
* @access public
|
|
|
|
* @param string Tag soup attributes, example: this="that" thing="no"
|
|
|
|
* @return void
|
|
|
|
*/
|
2021-02-22 23:48:01 +00:00
|
|
|
public function setListAttributes( $attributes ) {
|
|
|
|
$this->listAttributes = \Sanitizer::fixTagAttributes( $attributes, 'ul' );
|
2020-11-22 20:02:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Set extra item attributes.
|
|
|
|
*
|
|
|
|
* @access public
|
|
|
|
* @param string Tag soup attributes, example: this="that" thing="no"
|
|
|
|
* @return void
|
|
|
|
*/
|
2021-02-22 23:48:01 +00:00
|
|
|
public function setItemAttributes( $attributes ) {
|
|
|
|
$this->itemAttributes = \Sanitizer::fixTagAttributes( $attributes, 'li' );
|
2020-11-22 20:02:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Set if the article count per heading should be shown.
|
|
|
|
*
|
|
|
|
* @access public
|
|
|
|
* @param boolean [Optional] Show Heading Count
|
|
|
|
* @return void
|
|
|
|
*/
|
2021-02-22 23:48:01 +00:00
|
|
|
public function setShowHeadingCount( $show = false ) {
|
|
|
|
$this->showHeadingCount = boolval( $show );
|
2020-11-22 20:02:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Return the list style.
|
|
|
|
*
|
|
|
|
* @access public
|
|
|
|
* @return integer List style constant.
|
|
|
|
*/
|
|
|
|
public function getStyle() {
|
|
|
|
return $this->style;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Format a list of articles into all lists with headings as needed.
|
|
|
|
*
|
|
|
|
* @access public
|
|
|
|
* @param array List of \DPL\Article
|
|
|
|
* @param object List of \DPL\Lister\Lister
|
|
|
|
* @return string Formatted list.
|
|
|
|
*/
|
2021-02-22 23:48:01 +00:00
|
|
|
public function format( $articles, Lister $lister ) {
|
|
|
|
$columns = $this->getParameters()->getParameter( 'columns' );
|
|
|
|
$rows = $this->getParameters()->getParameter( 'rows' );
|
|
|
|
$rowSize = $this->getParameters()->getParameter( 'rowsize' );
|
|
|
|
$rowColFormat = $this->getParameters()->getParameter( 'rowcolformat' );
|
2020-11-22 20:02:14 +00:00
|
|
|
|
|
|
|
$start = 0;
|
|
|
|
$count = 0;
|
|
|
|
|
|
|
|
$headings = Article::getHeadings();
|
|
|
|
$output = '';
|
2021-02-22 23:48:01 +00:00
|
|
|
if ( !empty( $headings ) ) {
|
|
|
|
if ( $columns != 1 || $rows != 1 ) {
|
2020-11-22 20:02:14 +00:00
|
|
|
$hspace = 2; // the extra space for headings
|
|
|
|
// repeat outer tags for each of the specified columns / rows in the output
|
|
|
|
// we assume that a heading roughly takes the space of two articles
|
2021-02-22 23:48:01 +00:00
|
|
|
$count = count( $articles ) + $hspace * count( $headings );
|
|
|
|
if ( $columns != 1 ) {
|
2020-11-22 20:02:14 +00:00
|
|
|
$iGroup = $columns;
|
|
|
|
} else {
|
|
|
|
$iGroup = $rows;
|
|
|
|
}
|
2021-02-22 23:48:01 +00:00
|
|
|
$nsize = floor( $count / $iGroup );
|
|
|
|
$rest = $count - ( floor( $nsize ) * floor( $iGroup ) );
|
|
|
|
if ( $rest > 0 ) {
|
2020-11-22 20:02:14 +00:00
|
|
|
$nsize += 1;
|
|
|
|
}
|
|
|
|
$output .= "{|" . $rowColFormat . "\n|\n";
|
2021-02-22 23:48:01 +00:00
|
|
|
if ( $nsize < $hspace + 1 ) {
|
2020-11-22 20:02:14 +00:00
|
|
|
$nsize = $hspace + 1; // correction for result sets with one entry
|
|
|
|
}
|
|
|
|
$output .= $this->getListStart();
|
|
|
|
$nstart = 0;
|
|
|
|
$greml = $nsize; // remaining lines in current group
|
|
|
|
$g = 0;
|
|
|
|
$offset = 0;
|
2021-02-22 23:48:01 +00:00
|
|
|
foreach ( $headings as $headingCount ) {
|
2020-11-22 20:02:14 +00:00
|
|
|
$headingStart = $nstart - $offset;
|
|
|
|
$headingLink = $articles[$headingStart]->mParentHLink;
|
|
|
|
$output .= $this->getItemStart() . $headingLink . $this->getItemEnd();
|
2021-02-22 23:48:01 +00:00
|
|
|
if ( $this->showHeadingCount ) {
|
|
|
|
$output .= $this->articleCountMessage( $headingCount );
|
2020-11-22 20:02:14 +00:00
|
|
|
}
|
|
|
|
$offset += $hspace;
|
|
|
|
$nstart += $hspace;
|
|
|
|
$portion = $headingCount;
|
|
|
|
$greml -= $hspace;
|
|
|
|
$listOutput = '';
|
|
|
|
do {
|
|
|
|
$greml -= $portion;
|
|
|
|
// $output .= "nsize=$nsize, portion=$portion, greml=$greml";
|
2021-02-22 23:48:01 +00:00
|
|
|
if ( $greml > 0 ) {
|
|
|
|
$output .= $lister->formatList( $articles, $nstart - $offset, $portion );
|
2020-11-22 20:02:14 +00:00
|
|
|
$nstart += $portion;
|
|
|
|
$portion = 0;
|
|
|
|
break;
|
|
|
|
} else {
|
2021-02-22 23:48:01 +00:00
|
|
|
$output .= $lister->formatList( $articles, $nstart - $offset, $portion + $greml );
|
|
|
|
$nstart += ( $portion + $greml );
|
|
|
|
$portion = ( -$greml );
|
|
|
|
if ( $columns != 1 ) {
|
2020-11-22 20:02:14 +00:00
|
|
|
$output .= "\n|valign=top|\n";
|
|
|
|
} else {
|
|
|
|
$output .= "\n|-\n|\n";
|
|
|
|
}
|
|
|
|
++$g;
|
|
|
|
// if ($rest != 0 && $g==$rest) $nsize -= 1;
|
2021-02-22 23:48:01 +00:00
|
|
|
if ( $nstart + $nsize > $count ) {
|
2020-11-22 20:02:14 +00:00
|
|
|
$nsize = $count - $nstart;
|
|
|
|
}
|
|
|
|
$greml = $nsize;
|
2021-02-22 23:48:01 +00:00
|
|
|
if ( $greml <= 0 ) {
|
2020-11-22 20:02:14 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2021-02-22 23:48:01 +00:00
|
|
|
} while ( $portion > 0 );
|
2020-11-22 20:02:14 +00:00
|
|
|
$output .= $this->getItemEnd();
|
|
|
|
}
|
|
|
|
$output .= $this->listEnd;
|
|
|
|
$output .= "\n|}\n";
|
|
|
|
} else {
|
|
|
|
$output .= $this->getListStart();
|
|
|
|
$headingStart = 0;
|
2021-02-22 23:48:01 +00:00
|
|
|
foreach ( $headings as $headingCount ) {
|
2020-11-22 20:02:14 +00:00
|
|
|
$headingLink = $articles[$headingStart]->mParentHLink;
|
2021-02-22 23:48:01 +00:00
|
|
|
$output .= $this->formatItem( $headingStart, $headingCount, $headingLink, $articles, $lister );
|
2020-11-22 20:02:14 +00:00
|
|
|
$headingStart += $headingCount;
|
|
|
|
}
|
|
|
|
$output .= $this->listEnd;
|
|
|
|
}
|
2021-02-22 23:48:01 +00:00
|
|
|
} elseif ( $columns != 1 || $rows != 1 ) {
|
2020-11-22 20:02:14 +00:00
|
|
|
// repeat outer tags for each of the specified columns / rows in the output
|
|
|
|
$nstart = 0;
|
2021-02-22 23:48:01 +00:00
|
|
|
$count = count( $articles );
|
|
|
|
if ( $columns != 1 ) {
|
2020-11-22 20:02:14 +00:00
|
|
|
$iGroup = $columns;
|
|
|
|
} else {
|
|
|
|
$iGroup = $rows;
|
|
|
|
}
|
2021-02-22 23:48:01 +00:00
|
|
|
$nsize = floor( $count / $iGroup );
|
|
|
|
$rest = $count - ( floor( $nsize ) * floor( $iGroup ) );
|
|
|
|
if ( $rest > 0 ) {
|
2020-11-22 20:02:14 +00:00
|
|
|
$nsize += 1;
|
|
|
|
}
|
|
|
|
$output .= "{|" . $rowColFormat . "\n|\n";
|
2021-02-22 23:48:01 +00:00
|
|
|
for ( $g = 0; $g < $iGroup; $g++ ) {
|
|
|
|
$output .= $lister->formatList( $articles, $nstart, $nsize );
|
|
|
|
if ( $columns != 1 ) {
|
2020-11-22 20:02:14 +00:00
|
|
|
$output .= "\n|valign=top|\n";
|
|
|
|
} else {
|
|
|
|
$output .= "\n|-\n|\n";
|
|
|
|
}
|
|
|
|
$nstart = $nstart + $nsize;
|
|
|
|
// if ($rest != 0 && $g+1==$rest) $nsize -= 1;
|
2021-02-22 23:48:01 +00:00
|
|
|
if ( $nstart + $nsize > $count ) {
|
2020-11-22 20:02:14 +00:00
|
|
|
$nsize = $count - $nstart;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
$output .= "\n|}\n";
|
2021-02-22 23:48:01 +00:00
|
|
|
} elseif ( $rowSize > 0 ) {
|
2020-11-22 20:02:14 +00:00
|
|
|
// repeat row header after n lines of output
|
|
|
|
$nstart = 0;
|
|
|
|
$nsize = $rowSize;
|
2021-02-22 23:48:01 +00:00
|
|
|
$count = count( $articles );
|
2020-11-22 20:02:14 +00:00
|
|
|
$output .= '{|' . $rowColFormat . "\n|\n";
|
|
|
|
do {
|
2021-02-22 23:48:01 +00:00
|
|
|
if ( $nstart + $nsize > $count ) {
|
2020-11-22 20:02:14 +00:00
|
|
|
$nsize = $count - $nstart;
|
|
|
|
}
|
2021-02-22 23:48:01 +00:00
|
|
|
$output .= $lister->formatList( $articles, $nstart, $nsize );
|
2020-11-22 20:02:14 +00:00
|
|
|
$output .= "\n|-\n|\n";
|
|
|
|
$nstart = $nstart + $nsize;
|
2021-02-22 23:48:01 +00:00
|
|
|
if ( $nstart >= $count ) {
|
2020-11-22 20:02:14 +00:00
|
|
|
break;
|
|
|
|
}
|
2021-02-22 23:48:01 +00:00
|
|
|
} while ( true );
|
2020-11-22 20:02:14 +00:00
|
|
|
$output .= "\n|}\n";
|
|
|
|
} else {
|
|
|
|
//Even though the headingmode is not none there were no headings, but still results. Output them anyway.
|
2021-02-22 23:48:01 +00:00
|
|
|
$output .= $lister->formatList( $articles, 0, count( $articles ) );
|
2020-11-22 20:02:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return $output;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Format a heading group.
|
|
|
|
*
|
|
|
|
* @access public
|
|
|
|
* @param integer Article start index for this heading.
|
|
|
|
* @param integer Article count for this heading.
|
|
|
|
* @param string Heading link/text display.
|
|
|
|
* @param array List of \DPL\Article.
|
|
|
|
* @param object List of \DPL\Lister\Lister
|
|
|
|
* @return string Heading HTML
|
|
|
|
*/
|
2021-02-22 23:48:01 +00:00
|
|
|
public function formatItem( $headingStart, $headingCount, $headingLink, $articles, Lister $lister ) {
|
2020-11-22 20:02:14 +00:00
|
|
|
$item = '';
|
|
|
|
|
|
|
|
$item .= $this->getItemStart() . $headingLink;
|
2021-02-22 23:48:01 +00:00
|
|
|
if ( $this->showHeadingCount ) {
|
|
|
|
$item .= $this->articleCountMessage( $headingCount );
|
2020-11-22 20:02:14 +00:00
|
|
|
}
|
2021-02-22 23:48:01 +00:00
|
|
|
$item .= $lister->formatList( $articles, $headingStart, $headingCount );
|
2020-11-22 20:02:14 +00:00
|
|
|
$item .= $this->getItemEnd();
|
|
|
|
|
|
|
|
return $item;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Return $this->listStart with attributes replaced.
|
|
|
|
*
|
|
|
|
* @access public
|
|
|
|
* @return string List Start
|
|
|
|
*/
|
|
|
|
public function getListStart() {
|
2021-02-22 23:48:01 +00:00
|
|
|
return sprintf( $this->listStart, $this->listAttributes );
|
2020-11-22 20:02:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Return $this->itemStart with attributes replaced.
|
|
|
|
*
|
|
|
|
* @access public
|
|
|
|
* @return string Item Start
|
|
|
|
*/
|
|
|
|
public function getItemStart() {
|
2021-02-22 23:48:01 +00:00
|
|
|
return sprintf( $this->itemStart, $this->itemAttributes );
|
2020-11-22 20:02:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Return $this->itemEnd with attributes replaced.
|
|
|
|
*
|
|
|
|
* @access public
|
|
|
|
* @return string Item End
|
|
|
|
*/
|
|
|
|
public function getItemEnd() {
|
|
|
|
return $this->itemEnd;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get the article count message appropriate for this list.
|
|
|
|
*
|
|
|
|
* @access public
|
|
|
|
* @param integer Count
|
|
|
|
* @return string Message
|
|
|
|
*/
|
2021-02-22 23:48:01 +00:00
|
|
|
protected function articleCountMessage( $count ) {
|
|
|
|
$orderMethods = $this->getParameters()->getParameter( 'ordermethods' );
|
|
|
|
if ( isset( $orderMethods[0] ) && $orderMethods[0] === 'category' ) {
|
2020-11-22 20:02:14 +00:00
|
|
|
$message = 'categoryarticlecount';
|
|
|
|
} else {
|
|
|
|
$message = 'dpl_articlecount';
|
|
|
|
}
|
2021-02-22 23:48:01 +00:00
|
|
|
return '<p>' . wfMessage( $message, $count )->escaped() . '</p>';
|
2020-11-22 20:02:14 +00:00
|
|
|
}
|
|
|
|
}
|