Skip to content

Commit

Permalink
(refactor) Turn EventCalendar class into a service
Browse files Browse the repository at this point in the history
  • Loading branch information
edwardspec committed Dec 16, 2024
1 parent 419a7fa commit a38b4d2
Show file tree
Hide file tree
Showing 3 changed files with 107 additions and 18 deletions.
66 changes: 49 additions & 17 deletions includes/EventCalendar.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,27 +26,61 @@
use DateTime;
use FormatJson;
use Html;
use MediaWiki\MediaWikiServices;
use MWException;
use ObjectCache;
use Parser;
use Title;
use Wikimedia\Rdbms\ILoadBalancer;

class EventCalendar {
/** @var ServiceOptions */
protected $options;

/** @var ILoadBalancer */
protected $loadBalancer;

/** @var Language */
protected $contentLanguage;

/** @var ReadOnlyMode */
protected $readOnlyMode;

public const CONSTRUCTOR_OPTIONS = [
'ECMaxCacheTime',
'JsCalendarFullCalendarVersion'
];

/**
* @param ServiceOptions $options
* @param ILoadBalancer $loadBalancer
* @param Language $contentLanguage
* @param ReadOnlyMode $readOnlyMode
*/
public function __construct(
ServiceOptions $options,
ILoadBalancer $loadBalancer,
Language $contentLanguage,
ReadOnlyMode $readOnlyMode
) {
$this->options = $options;
$this->loadBalancer = $loadBalancer;
$this->contentLanguage = $contentLanguage;
$this->readOnlyMode = $readOnlyMode;
}

/**
* @var int
* For multiple calendars on the same page: they will be named Calendar1, Calendar2, etc.
*/
protected static $calendarsCounter = 0;
protected $calendarsCounter = 0;

/**
* Calculate an array of events in the format expected by JavaScript side of the calendar.
* @param array $opt Parameters obtained from contents of <eventcalendar> tag.
* @param Parser $recursiveParser Parser object that is being used to render <EventCalendar>.
* @return array
*/
public static function findEvents( array $opt, Parser $recursiveParser ) {
public function findEvents( array $opt, Parser $recursiveParser ) {
$namespaceIdx = $opt['namespace'] ?? NS_MAIN;
$prefix = $opt['prefix'] ?? '';
$suffix = $opt['suffix'] ?? '';
Expand Down Expand Up @@ -103,7 +137,7 @@ public static function findEvents( array $opt, Parser $recursiveParser ) {
$res = $query->getResult();

// Obtain connections to DB/cache that may or may not be used for storing snippets in cache.
$dbw = MediaWikiServices::getInstance()->getDBLoadBalancer()->getConnection( DB_PRIMARY );
$dbw = $this->loadBalancer->getConnection( DB_PRIMARY );
$dbCache = ObjectCache::getInstance( CACHE_DB );

$eventmap = [];
Expand Down Expand Up @@ -207,7 +241,7 @@ public static function findEvents( array $opt, Parser $recursiveParser ) {
// NOTE: the reason why we don't use $dbCache->set() here is that SqlBagOStuff::set() will do
// both compression and serialization, and decoding this is in protected methods.
// We don't want all that code duplication here, so we store HTML snippet in raw form.
if ( !MediaWikiServices::getInstance()->getReadOnlyMode()->isReadOnly() ) {
if ( !$this->readOnlyMode->isReadOnly() ) {
$dbw->insert( 'objectcache', [
'keyname' => $dbCache->makeKey( 'jscalendar-snippet-' . $row->latest ),
'value' => $snippet,
Expand Down Expand Up @@ -307,12 +341,9 @@ public static function findEvents( array $opt, Parser $recursiveParser ) {
* @param Parser $parser
* @return array|string
*/
public static function renderEventCalendar( $input, Parser $parser ) {
// config variables
global $wgECMaxCacheTime, $wgJsCalendarFullCalendarVersion;

public function renderCalendar( $input, Parser $parser ) {
$modules = [];
switch ( $wgJsCalendarFullCalendarVersion ) {
switch ( intval( $this->options->get( 'JsCalendarFullCalendarVersion' ) ) ) {
case 2:
$modules[] = 'ext.yasec';
break;
Expand All @@ -322,14 +353,15 @@ public static function renderEventCalendar( $input, Parser $parser ) {
break;

default:
throw new MWException( 'Unsupported value of $wgJsCalendarFullCalendarVersion (' .
$wgJsCalendarFullCalendarVersion . '): can only be 2 or 5.' );
throw new MWException(
'Unsupported value of $wgJsCalendarFullCalendarVersion: can only be 2 or 5.' );
}

$parser->getOutput()->addModules( $modules );

if ( $wgECMaxCacheTime !== false ) {
$parser->getOutput()->updateCacheExpiry( $wgECMaxCacheTime );
$cacheTime = $this->options->get( 'ECMaxCacheTime' );
if ( $cacheTime !== false ) {
$parser->getOutput()->updateCacheExpiry( $cacheTime );
}

// Parse the contents of the tag ($input string) for parameters.
Expand All @@ -345,13 +377,13 @@ public static function renderEventCalendar( $input, Parser $parser ) {
$val = trim( $keyval[1] );

if ( $key == 'namespace' ) {
$val = MediaWikiServices::getInstance()->getContentLanguage()->getNsIndex( $val );
$val = $this->contentLanguage->getNsIndex( $val );
}

$options[$key] = $val;
}

$events = self::findEvents( array_filter( $options ), $parser );
$events = $this->findEvents( array_filter( $options ), $parser );

// calendar container and data array
$scriptHtml = '';
Expand All @@ -360,7 +392,7 @@ public static function renderEventCalendar( $input, Parser $parser ) {

$attr = [
'class' => 'eventcalendar',
'id' => 'eventcalendar-' . ( ++ self::$calendarsCounter )
'id' => 'eventcalendar-' . ( ++$this->calendarsCounter )
];

$height = $options['height'] ?? 0;
Expand Down
13 changes: 12 additions & 1 deletion includes/Hooks.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,17 @@
use Parser;

class Hooks {

/** @var EventCalendar */
protected $eventCalendar;

/**
* @param EventCalendar $eventCalendar
*/
public function __construct( EventCalendar $eventCalendar ) {
$this->eventCalendar = $eventCalendar;
}

/**
* Set up the <EventCalendar> tag.
*
Expand All @@ -45,6 +56,6 @@ public static function onParserFirstCallInit( Parser $parser ) {
* @return array|string
*/
public static function parserFunction( $input, $args, Parser $parser ) {
return EventCalendar::renderEventCalendar( $input, $parser );
return $this->eventCalendar->renderCalendar( $input, $parser );
}
}
46 changes: 46 additions & 0 deletions includes/ServiceWiring.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
<?php

/**
* Implements the JsCalendar extension for MediaWiki.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* http://www.gnu.org/copyleft/gpl.html
*
* @file
*/

namespace MediaWiki\JsCalendar;

use MediaWiki\Config\ServiceOptions;
use MediaWiki\MediaWikiServices;

// @codeCoverageIgnoreStart

return [
'JsCalendar.EventCalendar' =>
static function ( MediaWikiServices $services ): EventCalendar {
return new AnotherWikiPages(
new ServiceOptions(
EventCalendar::CONSTRUCTOR_OPTIONS,
$services->getMainConfig()
),
$services->getDBLoadBalancer(),
$services->getContentLanguage(),
$services->getReadOnlyMode()
);
}
];

// @codeCoverageIgnoreEnd

0 comments on commit a38b4d2

Please sign in to comment.