Example #1
0
 public function execute()
 {
     $params = $this->extractRequestParams();
     $prop = array_flip($params['prop']);
     $fld_displayname = isset($prop['displayname']);
     $fld_description = isset($prop['description']);
     $fld_hitcount = isset($prop['hitcount']);
     $fld_defined = isset($prop['defined']);
     $fld_source = isset($prop['source']);
     $fld_active = isset($prop['active']);
     $limit = $params['limit'];
     $result = $this->getResult();
     $extensionDefinedTags = array_fill_keys(ChangeTags::listExtensionDefinedTags(), 0);
     $explicitlyDefinedTags = array_fill_keys(ChangeTags::listExplicitlyDefinedTags(), 0);
     $extensionActivatedTags = array_fill_keys(ChangeTags::listExtensionActivatedTags(), 0);
     $definedTags = array_merge($extensionDefinedTags, $explicitlyDefinedTags);
     # Fetch defined tags that aren't past the continuation
     if ($params['continue'] !== null) {
         $cont = $params['continue'];
         $tags = array_filter(array_keys($definedTags), function ($v) use($cont) {
             return $v >= $cont;
         });
         $tags = array_fill_keys($tags, 0);
     } else {
         $tags = $definedTags;
     }
     # Merge in all used tags
     $this->addTables('change_tag');
     $this->addFields('ct_tag');
     $this->addFields(array('hitcount' => $fld_hitcount ? 'COUNT(*)' : '0'));
     $this->addOption('LIMIT', $limit + 1);
     $this->addOption('GROUP BY', 'ct_tag');
     $this->addWhereRange('ct_tag', 'newer', $params['continue'], null);
     $res = $this->select(__METHOD__);
     foreach ($res as $row) {
         $tags[$row->ct_tag] = (int) $row->hitcount;
     }
     # Now make sure the array is sorted for proper continuation
     ksort($tags);
     $count = 0;
     foreach ($tags as $tagName => $hitcount) {
         if (++$count > $limit) {
             $this->setContinueEnumParameter('continue', $tagName);
             break;
         }
         $tag = array();
         $tag['name'] = $tagName;
         if ($fld_displayname) {
             $tag['displayname'] = ChangeTags::tagDescription($tagName);
         }
         if ($fld_description) {
             $msg = $this->msg("tag-{$tagName}-description");
             $tag['description'] = $msg->exists() ? $msg->text() : '';
         }
         if ($fld_hitcount) {
             $tag['hitcount'] = $hitcount;
         }
         $isExtension = isset($extensionDefinedTags[$tagName]);
         $isExplicit = isset($explicitlyDefinedTags[$tagName]);
         if ($fld_defined) {
             $tag['defined'] = $isExtension || $isExplicit;
         }
         if ($fld_source) {
             $tag['source'] = array();
             if ($isExtension) {
                 $tag['source'][] = 'extension';
             }
             if ($isExplicit) {
                 $tag['source'][] = 'manual';
             }
         }
         if ($fld_active) {
             $tag['active'] = $isExplicit || isset($extensionActivatedTags[$tagName]);
         }
         $fit = $result->addValue(array('query', $this->getModuleName()), null, $tag);
         if (!$fit) {
             $this->setContinueEnumParameter('continue', $tagName);
             break;
         }
     }
     $result->addIndexedTagName(array('query', $this->getModuleName()), 'tag');
 }
Example #2
0
 function showTagList()
 {
     $out = $this->getOutput();
     $out->setPageTitle($this->msg('tags-title'));
     $out->wrapWikiMsg("<div class='mw-tags-intro'>\n\$1\n</div>", 'tags-intro');
     $user = $this->getUser();
     $userCanManage = $user->isAllowed('managechangetags');
     $userCanDelete = $user->isAllowed('deletechangetags');
     $userCanEditInterface = $user->isAllowed('editinterface');
     // Show form to create a tag
     if ($userCanManage) {
         $fields = ['Tag' => ['type' => 'text', 'label' => $this->msg('tags-create-tag-name')->plain(), 'required' => true], 'Reason' => ['type' => 'text', 'label' => $this->msg('tags-create-reason')->plain(), 'size' => 50], 'IgnoreWarnings' => ['type' => 'hidden']];
         $form = new HTMLForm($fields, $this->getContext());
         $form->setAction($this->getPageTitle('create')->getLocalURL());
         $form->setWrapperLegendMsg('tags-create-heading');
         $form->setHeaderText($this->msg('tags-create-explanation')->parseAsBlock());
         $form->setSubmitCallback([$this, 'processCreateTagForm']);
         $form->setSubmitTextMsg('tags-create-submit');
         $form->show();
         // If processCreateTagForm generated a redirect, there's no point
         // continuing with this, as the user is just going to end up getting sent
         // somewhere else. Additionally, if we keep going here, we end up
         // populating the memcache of tag data (see ChangeTags::listDefinedTags)
         // with out-of-date data from the slave, because the slave hasn't caught
         // up to the fact that a new tag has been created as part of an implicit,
         // as yet uncommitted transaction on master.
         if ($out->getRedirect() !== '') {
             return;
         }
     }
     // Used to get hitcounts for #doTagRow()
     $tagStats = ChangeTags::tagUsageStatistics();
     // Used in #doTagRow()
     $this->explicitlyDefinedTags = array_fill_keys(ChangeTags::listExplicitlyDefinedTags(), true);
     $this->extensionDefinedTags = array_fill_keys(ChangeTags::listExtensionDefinedTags(), true);
     // List all defined tags, even if they were never applied
     $definedTags = array_keys(array_merge($this->explicitlyDefinedTags, $this->extensionDefinedTags));
     // Show header only if there exists atleast one tag
     if (!$tagStats && !$definedTags) {
         return;
     }
     // Write the headers
     $html = Xml::tags('tr', null, Xml::tags('th', null, $this->msg('tags-tag')->parse()) . Xml::tags('th', null, $this->msg('tags-display-header')->parse()) . Xml::tags('th', null, $this->msg('tags-description-header')->parse()) . Xml::tags('th', null, $this->msg('tags-source-header')->parse()) . Xml::tags('th', null, $this->msg('tags-active-header')->parse()) . Xml::tags('th', null, $this->msg('tags-hitcount-header')->parse()) . ($userCanManage ? Xml::tags('th', ['class' => 'unsortable'], $this->msg('tags-actions-header')->parse()) : ''));
     // Used in #doTagRow()
     $this->extensionActivatedTags = array_fill_keys(ChangeTags::listExtensionActivatedTags(), true);
     // Insert tags that have been applied at least once
     foreach ($tagStats as $tag => $hitcount) {
         $html .= $this->doTagRow($tag, $hitcount, $userCanManage, $userCanDelete, $userCanEditInterface);
     }
     // Insert tags defined somewhere but never applied
     foreach ($definedTags as $tag) {
         if (!isset($tagStats[$tag])) {
             $html .= $this->doTagRow($tag, 0, $userCanManage, $userCanDelete, $userCanEditInterface);
         }
     }
     $out->addHTML(Xml::tags('table', ['class' => 'mw-datatable sortable mw-tags-table'], $html));
 }
 function showTagList()
 {
     $out = $this->getOutput();
     $out->setPageTitle($this->msg('tags-title'));
     $out->wrapWikiMsg("<div class='mw-tags-intro'>\n\$1\n</div>", 'tags-intro');
     $user = $this->getUser();
     // Show form to create a tag
     if ($user->isAllowed('managechangetags')) {
         $fields = array('Tag' => array('type' => 'text', 'label' => $this->msg('tags-create-tag-name')->plain(), 'required' => true), 'Reason' => array('type' => 'text', 'label' => $this->msg('tags-create-reason')->plain(), 'size' => 50), 'IgnoreWarnings' => array('type' => 'hidden'));
         $form = new HTMLForm($fields, $this->getContext());
         $form->setAction($this->getPageTitle('create')->getLocalURL());
         $form->setWrapperLegendMsg('tags-create-heading');
         $form->setHeaderText($this->msg('tags-create-explanation')->plain());
         $form->setSubmitCallback(array($this, 'processCreateTagForm'));
         $form->setSubmitTextMsg('tags-create-submit');
         $form->show();
         // If processCreateTagForm generated a redirect, there's no point
         // continuing with this, as the user is just going to end up getting sent
         // somewhere else. Additionally, if we keep going here, we end up
         // populating the memcache of tag data (see ChangeTags::listDefinedTags)
         // with out-of-date data from the slave, because the slave hasn't caught
         // up to the fact that a new tag has been created as part of an implicit,
         // as yet uncommitted transaction on master.
         if ($out->getRedirect() !== '') {
             return;
         }
     }
     // Whether to show the "Actions" column in the tag list
     // If any actions added in the future require other user rights, add those
     // rights here
     $showActions = $user->isAllowed('managechangetags');
     // Write the headers
     $tagUsageStatistics = ChangeTags::tagUsageStatistics();
     // Show header only if there exists atleast one tag
     if (!$tagUsageStatistics) {
         return;
     }
     $html = Xml::tags('tr', null, Xml::tags('th', null, $this->msg('tags-tag')->parse()) . Xml::tags('th', null, $this->msg('tags-display-header')->parse()) . Xml::tags('th', null, $this->msg('tags-description-header')->parse()) . Xml::tags('th', null, $this->msg('tags-source-header')->parse()) . Xml::tags('th', null, $this->msg('tags-active-header')->parse()) . Xml::tags('th', null, $this->msg('tags-hitcount-header')->parse()) . ($showActions ? Xml::tags('th', array('class' => 'unsortable'), $this->msg('tags-actions-header')->parse()) : ''));
     // Used in #doTagRow()
     $this->explicitlyDefinedTags = array_fill_keys(ChangeTags::listExplicitlyDefinedTags(), true);
     $this->extensionDefinedTags = array_fill_keys(ChangeTags::listExtensionDefinedTags(), true);
     $this->extensionActivatedTags = array_fill_keys(ChangeTags::listExtensionActivatedTags(), true);
     foreach ($tagUsageStatistics as $tag => $hitcount) {
         $html .= $this->doTagRow($tag, $hitcount, $showActions);
     }
     $out->addHTML(Xml::tags('table', array('class' => 'mw-datatable sortable mw-tags-table'), $html));
 }