/**
  * Generate the content of each table row (1 row = 1 banner)
  */
 function formatRow($row)
 {
     // Begin banner row
     $htmlOut = Xml::openElement('tr');
     if ($this->editable) {
         // Add box
         $htmlOut .= Xml::tags('td', array('valign' => 'top'), Xml::check('addTemplates[]', '', array('value' => $row->tmp_name)));
         // Weight select
         $htmlOut .= Xml::tags('td', array('valign' => 'top'), Xml::listDropDown("weight[{$row->tmp_id}]", CentralNotice::dropDownList(wfMsg('centralnotice-weight'), range(0, 100, 5)), '', '25', '', ''));
     }
     // Link and Preview
     $render = new SpecialBannerLoader();
     $render->siteName = 'Wikipedia';
     $render->language = $this->mRequest->getVal('wpUserLanguage');
     try {
         $preview = $render->getHtmlNotice($row->tmp_name);
     } catch (SpecialBannerLoaderException $e) {
         $preview = wfMsg('centralnotice-nopreview');
     }
     $htmlOut .= Xml::tags('td', array('valign' => 'top'), $this->getSkin()->makeLinkObj($this->viewPage, htmlspecialchars($row->tmp_name), 'template=' . urlencode($row->tmp_name)) . Xml::fieldset(wfMsg('centralnotice-preview'), $preview, array('class' => 'cn-bannerpreview')));
     // End banner row
     $htmlOut .= Xml::closeElement('tr');
     return $htmlOut;
 }
 /**
  * Return settings for a campaign
  * @param $campaignName string: The name of the campaign
  * @param $detailed boolean: Whether or not to include targeting and banner assignment info
  * @return an array of settings
  */
 static function getCampaignSettings($campaignName, $detailed = true)
 {
     global $wgCentralDBname;
     // Read from the master database to avoid concurrency problems
     $dbr = wfGetDB(DB_MASTER, array(), $wgCentralDBname);
     $campaign = array();
     // Get campaign info from database
     $row = $dbr->selectRow('cn_notices', array('not_id', 'not_start', 'not_end', 'not_enabled', 'not_preferred', 'not_locked', 'not_geo'), array('not_name' => $campaignName), __METHOD__);
     if ($row) {
         $campaign = array('start' => $row->not_start, 'end' => $row->not_end, 'enabled' => $row->not_enabled, 'preferred' => $row->not_preferred, 'locked' => $row->not_locked, 'geo' => $row->not_geo);
     }
     if ($detailed) {
         $projects = CentralNotice::getNoticeProjects($campaignName);
         $languages = CentralNotice::getNoticeLanguages($campaignName);
         $geo_countries = CentralNotice::getNoticeCountries($campaignName);
         $campaign['projects'] = implode(", ", $projects);
         $campaign['languages'] = implode(", ", $languages);
         $campaign['countries'] = implode(", ", $geo_countries);
         $bannersIn = CentralNoticeDB::getCampaignBanners($row->not_id, true);
         $bannersOut = array();
         // All we want are the banner names and weights
         foreach ($bannersIn as $key => $row) {
             $outKey = $bannersIn[$key]['name'];
             $bannersOut[$outKey] = $bannersIn[$key]['weight'];
         }
         // Encode into a JSON string for storage
         $campaign['banners'] = FormatJson::encode($bannersOut);
     }
     return $campaign;
 }
 /**
  * Handle different types of page requests
  */
 function execute($sub)
 {
     global $wgOut, $wgLang, $wgRequest, $wgNoticeProjects, $wgLanguageCode, $wgNoticeProject;
     $this->project = $wgRequest->getText('project', $wgNoticeProject);
     $this->language = $wgRequest->getText('language', $wgLanguageCode);
     // If the form has been submitted, the country code should be passed along.
     $locationSubmitted = $wgRequest->getVal('country');
     $this->location = $locationSubmitted ? $locationSubmitted : $this->location;
     // Convert submitted location to boolean value. If it true, showList() will be called.
     $locationSubmitted = (bool) $locationSubmitted;
     // Begin output
     $this->setHeaders();
     // Output ResourceLoader module for styling and javascript functions
     $wgOut->addModules(array('ext.centralNotice.interface', 'ext.centralNotice.bannerStats'));
     // Initialize error variable
     $this->centralNoticeError = false;
     // Show summary
     $wgOut->addWikiMsg('centralnotice-summary');
     // Show header
     CentralNotice::printHeader();
     // Begin Banners tab content
     $wgOut->addHTML(Html::openElement('div', array('id' => 'preferences')));
     $htmlOut = '';
     // Begin Allocation selection fieldset
     $htmlOut .= Html::openElement('fieldset', array('class' => 'prefsection'));
     $htmlOut .= Html::openElement('form', array('method' => 'get'));
     $htmlOut .= Html::element('h2', null, wfMsg('centralnotice-view-allocation'));
     $htmlOut .= Xml::tags('p', null, wfMsg('centralnotice-allocation-instructions'));
     $htmlOut .= Html::openElement('table', array('id' => 'envpicker', 'cellpadding' => 7));
     $htmlOut .= Html::openElement('tr');
     $htmlOut .= Xml::tags('td', array('style' => 'width: 20%;'), wfMsg('centralnotice-project-name'));
     $htmlOut .= Html::openElement('td');
     $htmlOut .= Html::openElement('select', array('name' => 'project'));
     foreach ($wgNoticeProjects as $value) {
         $htmlOut .= Xml::option($value, $value, $value === $this->project);
     }
     $htmlOut .= Html::closeElement('select');
     $htmlOut .= Html::closeElement('td');
     $htmlOut .= Html::closeElement('tr');
     $htmlOut .= Html::openElement('tr');
     $htmlOut .= Xml::tags('td', array('valign' => 'top'), wfMsg('centralnotice-project-lang'));
     $htmlOut .= Html::openElement('td');
     // Make sure the site language is in the list; a custom language code
     // might not have a defined name...
     $languages = Language::getLanguageNames(true);
     if (!array_key_exists($wgLanguageCode, $languages)) {
         $languages[$wgLanguageCode] = $wgLanguageCode;
     }
     ksort($languages);
     $htmlOut .= Html::openElement('select', array('name' => 'language'));
     foreach ($languages as $code => $name) {
         $htmlOut .= Xml::option(wfMsg('centralnotice-language-listing', $code, $name), $code, $code === $this->language);
     }
     $htmlOut .= Html::closeElement('select');
     $htmlOut .= Html::closeElement('td');
     $htmlOut .= Html::closeElement('tr');
     $htmlOut .= Html::openElement('tr');
     $htmlOut .= Xml::tags('td', array(), wfMsg('centralnotice-country'));
     $htmlOut .= Html::openElement('td');
     $userLanguageCode = $wgLang->getCode();
     $countries = CentralNoticeDB::getCountriesList($userLanguageCode);
     $htmlOut .= Html::openElement('select', array('name' => 'country'));
     foreach ($countries as $code => $name) {
         $htmlOut .= Xml::option($name, $code, $code === $this->location);
     }
     $htmlOut .= Html::closeElement('select');
     $htmlOut .= Html::closeElement('td');
     $htmlOut .= Html::closeElement('tr');
     $htmlOut .= Html::closeElement('table');
     $htmlOut .= Xml::tags('div', array('class' => 'cn-buttons'), Xml::submitButton(wfMsg('centralnotice-view')));
     $htmlOut .= Html::closeElement('form');
     // End Allocation selection fieldset
     $htmlOut .= Html::closeElement('fieldset');
     $wgOut->addHTML($htmlOut);
     // Handle form submissions
     if ($locationSubmitted) {
         $this->showList();
     }
     // End Banners tab content
     $wgOut->addHTML(Html::closeElement('div'));
 }
 /**
  * Log any changes related to a campaign
  * @param $action string: 'created', 'modified', or 'removed'
  * @param $campaignId integer: ID of campaign
  * @param $beginSettings array of campaign settings before changes (optional)
  * @param $endSettings array of campaign settings after changes (optional)
  * @param $beginAssignments array of banner assignments before changes (optional)
  * @param $endAssignments array of banner assignments after changes (optional)
  * @return integer: ID of log entry (or null)
  */
 function logCampaignChange($action, $campaignId, $beginSettings = array(), $endSettings = array(), $beginAssignments = array(), $endAssignments = array())
 {
     global $wgUser;
     // Only log the change if it is done by an actual user (rather than a testing script)
     if ($wgUser->getId() > 0) {
         // User::getID returns 0 for anonymous or non-existant users
         $dbw = wfGetDB(DB_MASTER);
         $log = array('notlog_timestamp' => $dbw->timestamp(), 'notlog_user_id' => $wgUser->getId(), 'notlog_action' => $action, 'notlog_not_id' => $campaignId, 'notlog_not_name' => CentralNotice::getNoticeName($campaignId));
         foreach ($beginSettings as $key => $value) {
             $log['notlog_begin_' . $key] = $value;
         }
         foreach ($endSettings as $key => $value) {
             $log['notlog_end_' . $key] = $value;
         }
         $res = $dbw->insert('cn_notice_log', $log);
         $log_id = $dbw->insertId();
         return $log_id;
     } else {
         return null;
     }
 }
 /**
  * Handle different types of page requests
  */
 function execute($sub)
 {
     global $wgOut, $wgUser, $wgRequest;
     // Begin output
     $this->setHeaders();
     // Output ResourceLoader module for styling and javascript functions
     $wgOut->addModules('ext.centralNotice.interface');
     // Check permissions
     $this->editable = $wgUser->isAllowed('centralnotice-admin');
     // Initialize error variable
     $this->centralNoticeError = false;
     // Show summary
     $wgOut->addWikiMsg('centralnotice-summary');
     // Show header
     CentralNotice::printHeader();
     // Begin Banners tab content
     $wgOut->addHTML(Html::openElement('div', array('id' => 'preferences')));
     $method = $wgRequest->getVal('wpMethod');
     // Handle form submissions
     if ($this->editable && $wgRequest->wasPosted()) {
         // Check authentication token
         if ($wgUser->matchEditToken($wgRequest->getVal('authtoken'))) {
             // Handle removing banners
             $toRemove = $wgRequest->getArray('removeTemplates');
             if (isset($toRemove)) {
                 // Remove banners in list
                 foreach ($toRemove as $template) {
                     $this->removeTemplate($template);
                 }
             }
             // Handle translation message update
             $update = $wgRequest->getArray('updateText');
             if (isset($update)) {
                 foreach ($update as $lang => $messages) {
                     foreach ($messages as $text => $translation) {
                         // If we actually have text
                         if ($translation) {
                             $this->updateMessage($text, $translation, $lang);
                         }
                     }
                 }
             }
             // Handle adding banner
             if ($method == 'addTemplate') {
                 $newTemplateName = $wgRequest->getText('templateName');
                 $newTemplateBody = $wgRequest->getText('templateBody');
                 if ($newTemplateName != '' && $newTemplateBody != '') {
                     $this->addTemplate($newTemplateName, $newTemplateBody, $wgRequest->getBool('displayAnon'), $wgRequest->getBool('displayAccount'), $wgRequest->getBool('fundraising'), $wgRequest->getBool('autolink'), $wgRequest->getVal('landingPages'));
                     $sub = 'view';
                 } else {
                     $this->showError('centralnotice-null-string');
                 }
             }
             // Handle editing banner
             if ($method == 'editTemplate') {
                 $this->editTemplate($wgRequest->getText('template'), $wgRequest->getText('templateBody'), $wgRequest->getBool('displayAnon'), $wgRequest->getBool('displayAccount'), $wgRequest->getBool('fundraising'), $wgRequest->getBool('autolink'), $wgRequest->getVal('landingPages'));
                 $sub = 'view';
             }
         } else {
             $this->showError('sessionfailure');
         }
     }
     // Handle viewing of a banner in all languages
     if ($sub == 'view' && $wgRequest->getVal('wpUserLanguage') == 'all') {
         $template = $wgRequest->getVal('template');
         $this->showViewAvailable($template);
         $wgOut->addHTML(Html::closeElement('div'));
         return;
     }
     // Handle viewing a specific banner
     if ($sub == 'view' && $wgRequest->getText('template') != '') {
         $this->showView();
         $wgOut->addHTML(Html::closeElement('div'));
         return;
     }
     if ($this->editable) {
         // Handle showing "Add a banner" interface
         if ($sub == 'add') {
             $this->showAdd();
             $wgOut->addHTML(Html::closeElement('div'));
             return;
         }
         // Handle cloning a specific banner
         if ($sub == 'clone') {
             // Check authentication token
             if ($wgUser->matchEditToken($wgRequest->getVal('authtoken'))) {
                 $oldTemplate = $wgRequest->getVal('oldTemplate');
                 $newTemplate = $wgRequest->getVal('newTemplate');
                 // We use the returned name in case any special characters had to be removed
                 $template = $this->cloneTemplate($oldTemplate, $newTemplate);
                 $wgOut->redirect($this->getTitle('view')->getLocalUrl("template={$template}"));
                 return;
             } else {
                 $this->showError('sessionfailure');
             }
         }
     }
     // Show list of banners by default
     $this->showList();
     // End Banners tab content
     $wgOut->addHTML(Html::closeElement('div'));
 }
 public function testGetCampaignBanners()
 {
     $campaignId = CentralNotice::getNoticeId('PHPUnitTestCampaign');
     $this->assertEquals('[{"name":"PHPUnitTestBanner","weight":25,"display_anon":1,"display_account":1,"fundraising":1,"landing_pages":"JA1, JA2","campaign":"PHPUnitTestCampaign"}]', json_encode(CentralNoticeDB::getCampaignBanners($campaignId)));
 }
 private function dateSelector($prefix, $year = 0, $month = 0, $day = 0)
 {
     $dateRanges = CentralNotice::getDateRanges();
     $fields = array(array($prefix . "_month", "centralnotice-month", $dateRanges['months'], $month), array($prefix . "_day", "centralnotice-day", $dateRanges['days'], $day), array($prefix . "_year", "centralnotice-year", $dateRanges['years'], $year));
     $out = '';
     foreach ($fields as $data) {
         list($field, $label, $set, $current) = $data;
         $out .= Xml::listDropDown($field, CentralNotice::dropDownList(wfMsg($label), $set), '', $current);
     }
     return $out;
 }