/**
  * @brief Displays the main menu for the admin dashboard
  *
  */
 public function index()
 {
     $this->wg->Out->setPageTitle(wfMsg('admindashboard-title'));
     if (!$this->wg->User->isAllowed('admindashboard')) {
         $this->displayRestrictionError();
         return false;
         // skip rendering
     }
     $this->tab = $this->getVal('tab', 'general');
     // links
     $this->urlThemeDesigner = Title::newFromText('ThemeDesigner', NS_SPECIAL)->getFullURL();
     $this->urlRecentChanges = Title::newFromText('RecentChanges', NS_SPECIAL)->getFullURL();
     $this->urlTopNavigation = Title::newFromText('Wiki-navigation', NS_MEDIAWIKI)->getFullURL('action=edit');
     $this->urlWikiFeatures = Title::newFromText('WikiFeatures', NS_SPECIAL)->getFullURL();
     $this->urlListUsers = Title::newFromText('ListUsers', NS_SPECIAL)->getFullURL();
     $this->urlUserRights = Title::newFromText('UserRights', NS_SPECIAL)->getFullURL();
     $this->urlCommunityCorner = Title::newFromText('Community-corner', NS_MEDIAWIKI)->getFullURL('action=edit');
     $this->urlAllCategories = Title::newFromText('Categories', NS_SPECIAL)->getFullURL();
     $this->urlAddPage = Title::newFromText('CreatePage', NS_SPECIAL)->getFullURL();
     $this->urlAddPhoto = Title::newFromText('Upload', NS_SPECIAL)->getFullURL();
     if (!empty($this->wg->EnableSpecialVideosExt)) {
         $this->showVideoLink = true;
         $this->urlAddVideo = Title::newFromText('WikiaVideoAdd', NS_SPECIAL)->getFullURL();
         $this->urlAddVideoReturnUrl = SpecialPage::getTitleFor("Videos")->escapeLocalUrl("sort=recent");
     } else {
         $this->showVideoLink = false;
     }
     $this->urlCreateBlogPage = Title::newFromText('CreateBlogPage', NS_SPECIAL)->getFullURL();
     $this->urlMultipleUpload = Title::newFromText('MultipleUpload', NS_SPECIAL)->getFullURL();
     $this->urlLVS = Title::newFromText('LicensedVideoSwap', NS_SPECIAL)->getFullURL();
     $this->urlSpecialCss = SpecialPage::getTitleFor('CSS')->getFullURL();
     // special:specialpages
     $this->advancedSection = (string) $this->app->sendRequest('AdminDashboardSpecialPage', 'getAdvancedSection', array());
     // icon display logic
     $this->displayWikiFeatures = !empty($this->wg->EnableWikiFeatures);
     $this->displaySpecialCss = !empty($this->wg->EnableSpecialCssExt);
     // LicensedVideoSwap
     if (empty($this->wg->EnableLicensedVideoSwapExt)) {
         $this->displayLicensedVideoSwap = false;
         $this->badgeLicensedVideoSwap = '';
     } else {
         $this->displayLicensedVideoSwap = true;
         // alert badge
         $lvsHelper = new LicensedVideoSwapHelper();
         $this->badgeLicensedVideoSwap = $lvsHelper->getAlertBadge();
     }
     // add messages package
     JSMessages::enqueuePackage('AdminDashboard', JSMessages::INLINE);
     // Add Upload Photos Dialog
     Wikia::addAssetsToOutput('upload_photos_dialog_js');
     Wikia::addAssetsToOutput('upload_photos_dialog_scss');
 }
 /**
  * Examine every non-premium video on this wiki and add suggestions where needed.
  * @return array - An associative array of stats from processing the videos
  */
 private function processVideoList()
 {
     wfProfileIn(__METHOD__);
     $suggestDateProp = WPP_LVS_SUGGEST_DATE;
     $suggestExpire = time() - LicensedVideoSwapHelper::SUGGESTIONS_TTL;
     $pageNS = NS_FILE;
     // Only select videos with nonexistent or expired suggestions unless --refresh is on
     $whereExpired = '';
     if (!$this->refresh) {
         $whereExpired = " AND (props IS NULL OR props <= {$suggestExpire})";
     }
     // A list of all videos, returning the video title, its file page ID and
     $sql = "SELECT video_title as title,\n\t\t\t\t\t   page.page_id as page_id,\n\t\t\t\t\t   props as suggest_date\n\t\t\t\t  FROM video_info\n\t\t\t\t  JOIN page\n\t\t\t\t    ON video_title = page_title\n\t\t\t\t   AND page_namespace = {$pageNS}\n\t\t\t\t  LEFT JOIN page_wikia_props\n\t\t\t\t    ON page.page_id = page_wikia_props.page_id\n\t\t\t\t   AND propname = {$suggestDateProp}\n\t\t\t\t WHERE removed = 0\n\t\t\t\t   AND premium = 0\n\t\t\t\t   {$whereExpired}";
     $db = wfGetDB(DB_SLAVE);
     $results = $db->query($sql, __METHOD__);
     $lvsHelper = new LicensedVideoSwapHelper();
     $vidsFound = 0;
     $vidsWithSugggestions = 0;
     $totalSuggestions = 0;
     // Get the total count of relevant videos
     while ($row = $db->fetchObject($results)) {
         $vidsFound++;
         $title = $row->title;
         $this->debug("Processing '{$title}'\n");
         // This sets page_wikia_props for WPP_LVS_SUGGEST_DATE, WPP_LVS_EMPTY_SUGGEST and WPP_LVS_SUGGEST
         $suggestions = $lvsHelper->suggestionSearch($title, $this->test, $this->verbose);
         if ($suggestions) {
             $vidsWithSugggestions++;
             $totalSuggestions += count($suggestions);
             $this->debug("\tFound " . count($suggestions) . " suggestion(s)\n");
         } else {
             $this->debug("\tNo suggestions found\n");
         }
     }
     // clear cache for total videos
     $lvsHelper->invalidateCacheTotalVideos();
     // clear cache for total new videos
     $lvsHelper->invalidateCacheTotalNewVideos();
     wfProfileOut(__METHOD__);
     return array('vidsFound' => $vidsFound, 'vidsWithSuggestions' => $vidsWithSugggestions, 'totalSuggestions' => $totalSuggestions);
 }
 /**
  * Controller that is called when a user plays a video on the LVS.  Note that we mostly
  * care about the non-premium video that could be swapped rather than the premium video that
  * was played.  This is because all the metadata is stored against the non-premium video.
  *
  * @requestParam string videoTitle The title of the non-premium video that could be swapped
  * @requestParam string premiumTitle The title of the video that was played
  * @return bool Whether the controller was successful or not
  */
 public function playVideo()
 {
     // Get the non-premium title
     $videoTitle = $this->getVal('videoTitle');
     if (empty($videoTitle)) {
         return false;
     }
     // validate action
     $response = $this->sendRequest('LicensedVideoSwapSpecial', 'validateAction', array('videoTitle' => $videoTitle));
     $msg = $response->getVal('msg', '');
     if (!empty($msg)) {
         $this->html = '';
         $this->result = 'error';
         $this->msg = $msg;
     }
     // Get the list of videos already played
     /** @var User $user */
     $user = $this->getUser();
     $visitedList = $user->getGlobalAttribute(LicensedVideoSwapHelper::USER_VISITED_LIST);
     if ($visitedList) {
         $visitedList = unserialize($visitedList);
     } else {
         $visitedList = [];
     }
     // Update the list of played videos
     $visitedList[$videoTitle] = 1;
     $visitedTitles = array_keys($visitedList);
     // Remove any videos that don't exist for swapping anymore
     $helper = new LicensedVideoSwapHelper();
     $intersection = $helper->intersectUnswappedVideo($visitedTitles);
     // Go through each title in this user's list of played videos.  We're looking for the
     // video titles that don't appear in the intersection.  These titles no longer
     // need to be saved in this user property.
     foreach ($visitedTitles as $title) {
         // If this title doesn't appear in the intersection, remove it from the list
         if (!isset($intersection[$title])) {
             unset($visitedList[$title]);
         }
     }
     // set last visit date
     $user->setGlobalAttribute(LicensedVideoSwapHelper::USER_VISITED_LIST, serialize($visitedList));
     $user->saveSettings();
     return true;
 }