title = $title; $this->user = $user; $this->context = $context; $this->permissions = $permissions; $this->skinOptions = $skinOptions; $this->relevantUserPageHelper = $relevantUserPageHelper; $this->languagesHelper = $languagesHelper; $this->watchlistExpiryEnabled = $options->get( 'WatchlistExpiry' ); $this->watchlistManager = $watchlistManager; } /** * @param array $actions * @param array $views * @return Group */ public function getGroup( array $actions, array $views ): Group { $group = new Group( 'p-views' ); $permissions = $this->permissions; $userPageOrUserTalkPageWithOverflowMode = $this->skinOptions->get( SkinOptions::TOOLBAR_SUBMENU ) && $this->relevantUserPageHelper->isUserPage(); if ( !$userPageOrUserTalkPageWithOverflowMode && $permissions->isAllowed( IMinervaPagePermissions::SWITCH_LANGUAGE ) ) { $group->insertEntry( new LanguageSelectorEntry( $this->title, $this->languagesHelper->doesTitleHasLanguagesOrVariants( $this->context->getOutput(), $this->title ), $this->context, true ) ); } $watchKey = $key = isset( $actions['unwatch'] ) ? 'unwatch' : 'watch'; // The watchstar is typically not shown to anonymous users but it is in Minerva. $watchData = $actions[ $watchKey ] ?? [ 'icon' => 'star', 'class' => '', 'href' => $this->getLoginUrl( [ 'returnto' => $this->title ] ), 'text' => $this->context->msg( 'watch' ), ]; if ( $permissions->isAllowed( IMinervaPagePermissions::WATCHABLE ) && $watchData ) { $group->insertEntry( $this->createWatchPageAction( $watchKey, $watchData ) ); } $historyView = $views[ 'history'] ?? []; if ( $historyView && $permissions->isAllowed( IMinervaPagePermissions::HISTORY ) ) { $group->insertEntry( $this->getHistoryPageAction( $historyView ) ); } $user = $this->relevantUserPageHelper->getPageUser(); $isUserPageAccessible = $this->relevantUserPageHelper->isUserPageAccessibleToCurrentUser(); if ( $user && $isUserPageAccessible ) { // T235681: Contributions icon should be added to toolbar on user pages // and user talk pages for all users $group->insertEntry( $this->createContributionsPageAction( $user ) ); } // We want the edit icon/action(s) always to be the last element on the toolbar list if ( $permissions->isAllowed( IMinervaPagePermissions::CONTENT_EDIT ) ) { foreach ( $views as $key => $viewData ) { if ( in_array( $key, [ 've-edit', 'viewsource', 'edit' ] ) ) { $group->insertEntry( $this->createEditPageAction( $key, $viewData ) ); } } } return $group; } /** * Create Contributions page action visible on user pages or user talk pages * for given $user * * @param UserIdentity $user Determines what the contribution page action will link to * @return IMenuEntry */ protected function createContributionsPageAction( UserIdentity $user ): IMenuEntry { $label = $this->context->msg( 'mobile-frontend-user-page-contributions' ); $entry = new SingleMenuEntry( 'page-actions-contributions', $label->escaped(), SpecialPage::getTitleFor( 'Contributions', $user->getName() )->getLocalURL() ); $entry->setTitle( $label ) ->trackClicks( 'contributions' ) ->setIcon( 'userContributions' ); return $entry; } /** * Creates the "edit" page action: the well-known pencil icon that, when tapped, will open an * editor with the lead section loaded. * * @param string $key * @param array $editAction * @return IMenuEntry An edit page actions menu entry */ protected function createEditPageAction( string $key, array $editAction ): IMenuEntry { $title = $this->title; $id = $editAction['single-id'] ?? 'ca-edit'; $entry = new SingleMenuEntry( 'page-actions-' . $key, $editAction['text'], $editAction['href'], 'edit-page' ); $iconFallback = $key === 'viewsource' ? 'editLock' : 'edit'; $icon = $editAction['icon'] ?? $iconFallback; $entry->setIcon( $icon . '-base20' ) ->trackClicks( $key ) ->setTitle( $this->context->msg( 'tooltip-' . $id ) ) ->setNodeID( $id ); return $entry; } /** * Creates the "watch" or "unwatch" action: the well-known star icon that, when tapped, will * add the page to or remove the page from the user's watchlist; or, if the user is logged out, * will direct the user's UA to Special:Login. * * @param string $watchKey either watch or unwatch * @param array $watchData * @return IMenuEntry An watch/unwatch page actions menu entry */ protected function createWatchPageAction( string $watchKey, array $watchData ): IMenuEntry { $entry = new SingleMenuEntry( 'page-actions-watch', $watchData['text'], $watchData['href'], $watchData[ 'class' ], $this->permissions->isAllowed( IMinervaPagePermissions::WATCH ) ); $icon = $watchData['icon'] ?? ''; return $entry->trackClicks( $watchKey ) ->setIcon( $icon ) ->setTitle( $this->context->msg( $watchKey ) ) ->setNodeID( 'ca-watch' ); } /** * Creates a history action: An icon that links to the mobile history page. * * @param array $historyAction * @return IMenuEntry A menu entry object that represents a map of HTML attributes * and a 'text' property to be used with the pageActionMenu.mustache template. */ protected function getHistoryPageAction( array $historyAction ): IMenuEntry { $entry = new SingleMenuEntry( 'page-actions-history', $historyAction['text'], $historyAction['href'], ); $icon = $historyAction['icon'] ?? 'history'; $entry->setIcon( $icon . '-base20' ) ->trackClicks( 'history' ); return $entry; } /** * Get the URL for the history page for the given title using Special:History * when available. * FIXME: temporary duplicated code, same as SkinMinerva::getHistoryUrl() * @param Title $title The Title object of the page being viewed * @return string */ protected function getHistoryUrl( Title $title ): string { return ExtensionRegistry::getInstance()->isLoaded( 'MobileFrontend' ) && SpecialMobileHistory::shouldUseSpecialHistory( $title, $this->user ) ? SpecialPage::getTitleFor( 'History', $title )->getLocalURL() : $title->getLocalURL( [ 'action' => 'history' ] ); } /** * Prepares a url to the Special:UserLogin with query parameters * @param array $query * @return string */ private function getLoginUrl( $query ): string { return SpecialPage::getTitleFor( 'Userlogin' )->getLocalURL( $query ); } }