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;
103 $titleExists = $title && $title->exists();
105 $maxCredits = $config->get( MainConfigNames::MaxCredits );
106 $showCreditsIfMax = $config->get( MainConfigNames::ShowCreditsIfMax );
107 $useCredits = $titleExists
109 && $out->isRevisionCurrent()
110 && $maxCredits !== 0;
114 $article = Article::newFromWikiPage( $skinContext->
getWikiPage(), $ctx );
115 $action = Action::factory(
'credits', $article, $ctx );
118 '@phan-var CreditsAction $action';
120 'lastmod' => !$useCredits ? $this->lastModified() : null,
121 'numberofwatchingusers' => null,
122 'credits' => $useCredits && $action ?
123 $action->getCredits( $maxCredits, $showCreditsIfMax ) : null,
124 'copyright' => $titleExists &&
125 $out->showsCopyright() ? $this->getCopyright() : null,
132 private function getCopyright() {
133 $copyright =
new SkinComponentCopyright( $this->skinContext );
134 return $copyright->getTemplateData()[
'html' ];
146 private function formatFooterInfoData( array $data ): array {
148 foreach ( $data as $key => $item ) {
150 $formattedData[ $key ] = [
151 'id' =>
'footer-info-' . $key,
156 return $formattedData;
165 private function getSiteFooterLinks(): array {
168 'privacy' => [
'privacy',
'privacypage' ],
169 'about' => [
'aboutsite',
'aboutpage' ],
170 'disclaimers' => [
'disclaimers',
'disclaimerpage' ]
172 $localizer = $this->skinContext->getMessageLocalizer();
174 foreach ( $siteLinks as $key => $siteLink ) {
177 if ( !$localizer->msg( $siteLink[0] )->inContentLanguage()->isDisabled() ) {
180 $title = Title::newFromText( $localizer->msg( $siteLink[1] )->inContentLanguage()->text() );
181 if ( $title !==
null ) {
182 $siteLinksData[$key] = [
183 'id' =>
"footer-places-$key",
184 'text' => $localizer->msg( $siteLink[0] )->text(),
185 'href' => $title->fixSpecialName()->getLinkURL()
190 return $siteLinksData;
205 if ( is_string( $icon ) ) {
208 $url = $icon[
'url'] ??
null;
209 unset( $icon[
'url'] );
210 if ( isset( $icon[
'src'] ) && $withImage ===
'withImage' ) {
212 $icon[
'loading'] =
'lazy';
214 $html = Html::element(
'img', $icon );
216 $html = htmlspecialchars( $icon[
'alt'] ??
'' );
219 $html = Html::rawElement(
'a', [
221 'target' => $config->get( MainConfigNames::ExternalLinkTarget ),
239 $config->
get( MainConfigNames::FooterIcons ) as $footerIconsKey => &$footerIconsBlock
241 if ( count( $footerIconsBlock ) > 0 ) {
242 $footericons[$footerIconsKey] = [];
243 foreach ( $footerIconsBlock as &$footerIcon ) {
244 if ( isset( $footerIcon[
'src'] ) ) {
245 if ( !isset( $footerIcon[
'width'] ) ) {
246 $footerIcon[
'width'] = 88;
248 if ( !isset( $footerIcon[
'height'] ) ) {
249 $footerIcon[
'height'] = 31;
258 if ( is_string( $footerIcon ) || isset( $footerIcon[
'src'] ) ) {
259 $footericons[$footerIconsKey][] = $footerIcon;
265 if ( !count( $footericons[$footerIconsKey] ) ) {
266 unset( $footericons[$footerIconsKey] );
280 private function getFooterIcons(): array {
282 $skinContext = $this->skinContext;
286 if ( count( $footerIcons ) > 0 ) {
288 foreach ( $footerIcons as $blockName => $blockIcons ) {
290 foreach ( $blockIcons as $icon ) {
296 $block = htmlspecialchars( $blockName );
299 'id' =>
'footer-' . $block .
'ico',
301 'class' => [
'noprint' ],
308 if ( count( $icons ) > 0 ) {
309 $dataIcons =
new SkinComponentMenu(
312 $this->skinContext->getMessageLocalizer(),
319 return $dataIcons ? $dataIcons->getTemplateData() : [];
333 private function formatFooterDataForCurrentSpec( array $data ): array {
335 foreach ( $data as $key => $item ) {
336 unset( $item[
'html-tooltip'] );
337 unset( $item[
'html-items'] );
338 unset( $item[
'html-after-portal'] );
339 unset( $item[
'html-before-portal'] );
340 unset( $item[
'label'] );
341 unset( $item[
'class'] );
342 foreach ( $item[
'array-items'] ?? [] as $index => $arrayItem ) {
343 unset( $item[
'array-items'][$index][
'html-item'] );
345 $formattedData[$key] = $item;
346 $formattedData[$key][
'className'] = $key ===
'data-icons' ?
'noprint' :
null;
348 return $formattedData;
357 private function lastModified() {
358 $skinContext = $this->skinContext;
360 $timestamp = $out->getRevisionTimestamp();
365 if ( $timestamp ===
null ) {
366 $revId = $out->getRevisionId();
367 if ( $revId !==
null ) {
368 $timestamp = MediaWikiServices::getInstance()->getRevisionLookup()->getTimestampFromId( $revId );
372 $lastModified =
new SkinComponentLastModified(
377 return $lastModified->getTemplateData()[
'text'];
Legacy class representing an editable page and handling UI for some page actions.