22 $this->skinContext = $skinContext;
30 private function getTemplateDataFooter(): array {
32 'info' => $this->formatFooterInfoData(
33 $this->getFooterInfoData()
35 'places' => $this->getSiteFooterLinks(),
37 foreach ( $data as $key => $existingItems ) {
39 $this->skinContext->runHook(
'onSkinAddFooterLinks', [ $key, &$newItems ] );
41 foreach ( $newItems as $index => $linkHTML ) {
42 $data[ $key ][ $index ] = [
43 'id' =>
'footer-' . $key .
'-' . $index,
55 $footerData = $this->getTemplateDataFooter();
61 $this->skinContext->getMessageLocalizer()
65 $footerData[
'places'],
66 $this->skinContext->getMessageLocalizer()
74 $footerMenuData[
'data-info'] = $footerInfoMenuData->getTemplateData();
75 $footerMenuData[
'data-places'] = $footerSiteMenuData->getTemplateData();
76 $footerMenuData[
'data-icons'] = $this->getFooterIcons();
77 $footerMenuData = $this->formatFooterDataForCurrentSpec( $footerMenuData );
80 'data-info' => $footerMenuData[
'data-info'],
81 'data-places' => $footerMenuData[
'data-places'],
82 'data-icons' => $footerMenuData[
'data-icons']
96 private function getFooterInfoData(): array {
98 $skinContext = $this->skinContext;
101 $title = $out->getTitle();
104 $maxCredits = $config->get( MainConfigNames::MaxCredits );
105 $showCreditsIfMax = $config->get( MainConfigNames::ShowCreditsIfMax );
106 $useCredits = $titleExists
108 && $out->isRevisionCurrent()
109 && $maxCredits !== 0;
113 $article = Article::newFromWikiPage( $skinContext->
getWikiPage(), $ctx );
114 $action = Action::factory(
'credits', $article, $ctx );
117 '@phan-var CreditsAction $action';
119 'lastmod' => !$useCredits ? $this->lastModified() : null,
120 'numberofwatchingusers' => null,
121 'credits' => $useCredits && $action ?
122 $action->getCredits( $maxCredits, $showCreditsIfMax ) : null,
123 'copyright' => $titleExists &&
124 $out->showsCopyright() ? $this->getCopyright() : null,
131 private function getCopyright() {
132 $copyright =
new SkinComponentCopyright( $this->skinContext );
133 return $copyright->getTemplateData()[
'html' ];
145 private function formatFooterInfoData( array $data ): array {
147 foreach ( $data as $key => $item ) {
148 if ( !empty( $item ) ) {
149 $formattedData[ $key ] = [
150 'id' =>
'footer-info-' . $key,
155 return $formattedData;
164 private function getSiteFooterLinks(): array {
167 'privacy' => [
'privacy',
'privacypage' ],
168 'about' => [
'aboutsite',
'aboutpage' ],
169 'disclaimers' => [
'disclaimers',
'disclaimerpage' ]
171 $localizer = $this->skinContext->getMessageLocalizer();
173 foreach ( $siteLinks as $key => $siteLink ) {
176 if ( !$localizer->msg( $siteLink[0] )->inContentLanguage()->isDisabled() ) {
179 $title = Title::newFromText( $localizer->msg( $siteLink[1] )->inContentLanguage()->text() );
181 $siteLinksData[$key] = [
182 'id' =>
"footer-places-$key",
183 'text' => $localizer->msg( $siteLink[0] )->text(),
184 'href' =>
$title->fixSpecialName()->getLinkURL()
189 return $siteLinksData;
204 if ( is_string( $icon ) ) {
207 $url = $icon[
'url'] ??
null;
208 unset( $icon[
'url'] );
209 if ( isset( $icon[
'src'] ) && $withImage ===
'withImage' ) {
211 $icon[
'loading'] =
'lazy';
213 $html = Html::element(
'img', $icon );
215 $html = htmlspecialchars( $icon[
'alt'] ??
'' );
218 $html = Html::rawElement(
'a', [
220 'target' => $config->get( MainConfigNames::ExternalLinkTarget ),
238 $config->
get( MainConfigNames::FooterIcons ) as $footerIconsKey => &$footerIconsBlock
240 if ( count( $footerIconsBlock ) > 0 ) {
241 $footericons[$footerIconsKey] = [];
242 foreach ( $footerIconsBlock as &$footerIcon ) {
243 if ( isset( $footerIcon[
'src'] ) ) {
244 if ( !isset( $footerIcon[
'width'] ) ) {
245 $footerIcon[
'width'] = 88;
247 if ( !isset( $footerIcon[
'height'] ) ) {
248 $footerIcon[
'height'] = 31;
257 if ( is_string( $footerIcon ) || isset( $footerIcon[
'src'] ) ) {
258 $footericons[$footerIconsKey][] = $footerIcon;
264 if ( !count( $footericons[$footerIconsKey] ) ) {
265 unset( $footericons[$footerIconsKey] );
279 private function getFooterIcons(): array {
281 $skinContext = $this->skinContext;
285 if ( count( $footerIcons ) > 0 ) {
287 foreach ( $footerIcons as $blockName => $blockIcons ) {
289 foreach ( $blockIcons as $icon ) {
295 $block = htmlspecialchars( $blockName );
298 'id' =>
'footer-' . $block .
'ico',
300 'class' => [
'noprint' ],
307 if ( count( $icons ) > 0 ) {
308 $dataIcons =
new SkinComponentMenu(
311 $this->skinContext->getMessageLocalizer(),
318 return $dataIcons ? $dataIcons->getTemplateData() : [];
332 private function formatFooterDataForCurrentSpec( array $data ): array {
334 foreach ( $data as $key => $item ) {
335 unset( $item[
'html-tooltip'] );
336 unset( $item[
'html-items'] );
337 unset( $item[
'html-after-portal'] );
338 unset( $item[
'html-before-portal'] );
339 unset( $item[
'label'] );
340 unset( $item[
'class'] );
341 foreach ( $item[
'array-items'] ?? [] as $index => $arrayItem ) {
342 unset( $item[
'array-items'][$index][
'html-item'] );
344 $formattedData[$key] = $item;
345 $formattedData[$key][
'className'] = $key ===
'data-icons' ?
'noprint' :
null;
347 return $formattedData;
356 private function lastModified() {
357 $skinContext = $this->skinContext;
359 $timestamp = $out->getRevisionTimestamp();
364 if ( $timestamp ===
null ) {
365 $revId = $out->getRevisionId();
366 if ( $revId !==
null ) {
367 $timestamp = MediaWikiServices::getInstance()->getRevisionLookup()->getTimestampFromId( $revId );
371 $lastModified =
new SkinComponentLastModified(
376 return $lastModified->getTemplateData()[
'text'];
Legacy class representing an editable page and handling UI for some page actions.