/** * Run job * * @return boolean success */ function run() { wfProfileIn('SMWRefreshJob::run (SMW)'); if (!array_key_exists('spos', $this->params)) { wfProfileOut('SMWRefreshJob::run (SMW)'); return true; } $run = array_key_exists('run', $this->params) ? $this->params['run'] : 1; $spos = $this->params['spos']; $namespaces = $this->params['rc'] > 1 && $run == 1 ? array(SMW_NS_PROPERTY, SMW_NS_TYPE) : false; $progress = smwfGetStore()->refreshData($spos, 20, $namespaces); $jobParams = null; if ($spos > 0) { $jobParams = array('spos' => $spos, 'prog' => $progress, 'rc' => $this->params['rc'], 'run' => $run); } elseif ($this->params['rc'] > $run) { // do another run from the beginning $jobParams = array('spos' => 1, 'prog' => 0, 'rc' => $this->params['rc'], 'run' => $run + 1); } if (!empty($jobParams)) { // wikia change start - jobqueue migration $task = new \Wikia\Tasks\Tasks\JobWrapperTask(); $task->call('SMWRefreshJob', $this->title, $jobParams); $task->queue(); // wikia change end } wfProfileOut('SMWRefreshJob::run (SMW)'); return true; }
public function notifyUsers() { global $wgSitename, $wgSMTP, $wgEmergencyContact, $wgEnotifyMeJob; $sStore = NMStorage::getDatabase(); $nm_send_jobs = array(); $id = 0; if (count($this->m_notifyHtmlMsgs) > 0) { $notifications = $sStore->getNotifyMe(array_keys($this->m_notifyHtmlMsgs)); } $html_style = ''; // <style> // table.smwtable{background-color: #EEEEFF;} // table.smwtable th{background-color: #EEEEFF;text-align: left;} // table.smwtable td{background-color: #FFFFFF;padding: 1px;padding-left: 5px;padding-right: 5px;text-align: left;vertical-align: top;} // table.smwtable tr.smwfooter td{font-size: 90%;line-height: 1;background-color: #EEEEFF;padding: 0px;padding-left: 5px;padding-right: 5px;text-align: right;vertical-align: top;} // </style>'; $html_showall = array(); foreach ($this->m_notifyHtmlMsgs as $notify_id => $msg) { $html_msg = $html_style; $showing_all = false; if (isset($notifications[$notify_id]) && $notifications[$notify_id]['show_all']) { SMWQueryProcessor::processFunctionParams(SMWNotifyProcessor::getQueryRawParams($notifications[$notify_id]['query']), $querystring, $params, $printouts); $format = 'auto'; if (array_key_exists('format', $params)) { $format = strtolower(trim($params['format'])); global $smwgResultFormats; if (!array_key_exists($format, $smwgResultFormats)) { $format = 'auto'; } } $query = SMWQueryProcessor::createQuery($querystring, $params, SMWQueryProcessor::INLINE_QUERY, $format, $printouts); $res = smwfGetStore()->getQueryResult($query); $printer = SMWQueryProcessor::getResultPrinter($format, SMWQueryProcessor::INLINE_QUERY, $res); $result = $printer->getResult($res, $params, SMW_OUTPUT_HTML); // FIXME: hardcode switch to full url global $wgScriptPath, $wgServer; $result = str_replace($wgScriptPath, $wgServer . $wgScriptPath, $result); $html_msg .= $result . '<br/>'; $html_showall[$notify_id] = array('name' => $notifications[$notify_id]['name'], 'html' => $result); $showing_all = true; $link = $res->getQueryLink()->getURL(); } global $smwgNMHideDiffWhenShowAll; if (!($smwgNMHideDiffWhenShowAll && $showing_all)) { $html_msg .= wfMsg('smw_nm_hint_notification_html', $this->m_notifyHtmlMsgs[$notify_id]); if (isset($this->m_notifyHtmlPropMsgs[$notify_id])) { $html_msg .= wfMsg('smw_nm_hint_nmtable_html', $this->m_notifyHtmlPropMsgs[$notify_id]); } } if ($showing_all) { $id = $sStore->addNotifyRSS('nid', $notify_id, "All current items, " . date('Y-m-d H:i:s', time()), $this->applyStyle($html_msg), $link); } else { $id = $sStore->addNotifyRSS('nid', $notify_id, $this->m_title->getText(), $this->applyStyle($html_msg)); } } foreach ($this->m_userMsgs as $user_id => $msg) { // generate RSS items $html_msg = $html_style; foreach (array_unique($this->m_userNMs[$user_id]) as $showall_nid) { if (isset($html_showall[$showall_nid])) { $html_msg .= wfMsg('smw_nm_hint_item_html', $html_showall[$showall_nid]['name'], $html_showall[$showall_nid]['html']); } } $html_msg .= wfMsg('smw_nm_hint_notification_html', $this->m_userHtmlNMMsgs[$user_id]); if (isset($this->m_userHtmlPropMsgs[$user_id])) { $html_msg .= wfMsg('smw_nm_hint_nmtable_html', $this->m_userHtmlPropMsgs[$user_id]); } global $wgNMReportModifier, $wgUser; if ($wgNMReportModifier) { $userText = $wgUser->getName(); if ($wgUser->getId() == 0) { $page = SpecialPage::getTitleFor('Contributions', $userText); } else { $page = Title::makeTitle(NS_USER, $userText); } $l = '<a href="' . $page->getFullUrl() . '">' . htmlspecialchars($userText) . '</a>'; $html_msg .= wfMsg('smw_nm_hint_modifier_html', $l); $msg .= wfMsg('smw_nm_hint_modifier', $wgUser->getName()); } $id = $sStore->addNotifyRSS('uid', $user_id, $this->m_title->getText(), $this->applyStyle($html_msg)); if ($wgEnotifyMeJob) { // send notifications by mail $user_info = $sStore->getUserInfo($user_id); $user = User::newFromRow($user_info); if ($user_info->user_email != '' && $user->getGlobalPreference('enotifyme')) { $name = $user_info->user_real_name == '' ? $user_info->user_name : $user_info->user_real_name; $params = array('to' => new MailAddress($user_info->user_email, $name), 'from' => new MailAddress($wgEmergencyContact, 'Admin'), 'subj' => wfMsg('smw_nm_hint_mail_title', $this->m_title->getText(), $wgSitename), 'body' => wfMsg('smw_nm_hint_mail_body', $name, $msg), 'replyto' => new MailAddress($wgEmergencyContact, 'Admin')); // wikia change start - jobqueue migration $task = new \Wikia\Tasks\Tasks\JobWrapperTask(); $task->call('SMW_NMSendMailJob', $this->m_title, $params); $nm_send_jobs[] = $task; // wikia change end } } } if ($wgEnotifyMeJob) { if (count($nm_send_jobs)) { // wikia change start - jobqueue migration \Wikia\Tasks\Tasks\BaseTask::batch($nm_send_jobs); // wikia change end } } else { global $phpInterpreter; if (!isset($phpInterpreter)) { // if $phpInterpreter is not set, assume it is in search path // if not, starting of bot will FAIL! $phpInterpreter = "php"; } // copy from SMW_GardeningBot.php ob_start(); phpinfo(); $info = ob_get_contents(); ob_end_clean(); // Get Systemstring preg_match('!\\nSystem(.*?)\\n!is', strip_tags($info), $ma); // Check if it consists 'windows' as string preg_match('/[Ww]indows/', $ma[1], $os); global $smwgNMIP; if ($os[0] == '' && $os[0] == null) { // FIXME: $runCommand must allow whitespaces in paths too $runCommand = "{$phpInterpreter} -q {$smwgNMIP}/specials/SMWNotifyMe/SMW_NMSendMailAsync.php"; // TODO: test async code for linux. // low prio $nullResult = `{$runCommand} > /dev/null &`; } else { $runCommand = "\"\"{$phpInterpreter}\" -q \"{$smwgNMIP}/specials/SMWNotifyMe/SMW_NMSendMailAsync.php\"\""; $wshShell = new COM("WScript.Shell"); $runCommand = "cmd /C " . $runCommand; $oExec = $wshShell->Run($runCommand, 7, false); } } }
/** * Takes a set of SMW "update jobs", and keeps only the unique, actual * titles among them - this is useful if there are any internal objects * among the group; a set of names like "Page name#1", "Page name#2" * etc. should be turned into just "Page name". */ static function handleUpdatingOfInternalObjects(&$jobs) { $uniqueTitles = array(); foreach ($jobs as $i => $job) { // wikia change start - jobqueue migration /** @var \Wikia\Tasks\Tasks\BaseTask $job */ $jobTitle = $job->getTitle(); $title = Title::makeTitleSafe($jobTitle->getNamespace(), $jobTitle->getText()); $id = $title->getArticleID(); $uniqueTitles[$id] = $title; } $jobs = array(); foreach ($uniqueTitles as $id => $title) { // wikia change start - jobqueue migration $task = new \Wikia\Tasks\Tasks\JobWrapperTask(); $task->call('SMWUpdateJob', $title); $jobs[] = $task; // wikia change end } return true; }
/** * This function takes care of storing the collected semantic data and takes * care of clearing out any outdated entries for the processed page. It assume that * parsing has happened and that all relevant data is contained in the provided parser * output. * * Optionally, this function also takes care of triggering indirect updates that might be * needed for overall database consistency. If the saved page describes a property or data type, * the method checks whether the property type, the data type, the allowed values, or the * conversion factors have changed. If so, it triggers SMWUpdateJobs for the relevant articles, * which then asynchronously update the semantic data in the database. * * @param $parseroutput ParserOutput object that contains the results of parsing which will * be stored. * @param $title Title object specifying the page that should be saved. * @param $makejobs Bool stating whether jobs should be created to trigger further updates if * this appears to be necessary after this update. * * @todo FIXME: Some job generations here might create too many jobs at once on a large wiki. Use incremental jobs instead. */ public static function storeData($parseroutput, Title $title, $makejobs = true) { global $smwgEnableUpdateJobs, $smwgDeclarationProperties, $smwgPageSpecialProperties; $semdata = $parseroutput->mSMWData; $namespace = $title->getNamespace(); $processSemantics = smwfIsSemanticsProcessed($namespace); if (!isset($semdata)) { // no data at all? $semdata = new SMWSemanticData(SMWDIWikiPage::newFromTitle($title)); } if ($processSemantics) { $props = array(); foreach ($smwgPageSpecialProperties as $propId) { // Do not calculate the same property again. if (array_key_exists($propId, $props)) { continue; } // Remember the property is processed. $props[$propId] = true; $prop = new SMWDIProperty($propId); if (count($semdata->getPropertyValues($prop)) > 0) { continue; } // Calculate property value. $value = null; switch ($propId) { case '_MDAT': $timestamp = Revision::getTimeStampFromID($title, $title->getLatestRevID()); $value = self::getDataItemFromMWTimestamp($timestamp); break; case '_CDAT': $timestamp = $title->getFirstRevision()->getTimestamp(); $value = self::getDataItemFromMWTimestamp($timestamp); break; case '_NEWP': $value = new SMWDIBoolean($title->isNewPage()); break; case '_LEDT': $revision = Revision::newFromId($title->getLatestRevID()); $user = User::newFromId($revision->getUser()); $value = SMWDIWikiPage::newFromTitle($user->getUserPage()); break; } if (!is_null($value)) { $semdata->addPropertyObjectValue($prop, $value); } // Issue error or warning? } // foreach } else { // data found, but do all operations as if it was empty $semdata = new SMWSemanticData($semdata->getSubject()); } // Check if the semantic data has been changed. // Sets the updateflag to true if so. // Careful: storage access must happen *before* the storage update; // even finding uses of a property fails after its type was changed. $updatejobflag = false; $jobs = array(); if ($makejobs && $smwgEnableUpdateJobs && $namespace == SMW_NS_PROPERTY) { // If it is a property, then we need to check if the type or the allowed values have been changed. $ptype = new SMWDIProperty('_TYPE'); $oldtype = smwfGetStore()->getPropertyValues($semdata->getSubject(), $ptype); $newtype = $semdata->getPropertyValues($ptype); if (!self::equalDatavalues($oldtype, $newtype)) { $updatejobflag = true; } else { foreach ($smwgDeclarationProperties as $prop) { $pv = new SMWDIProperty($prop); $oldvalues = smwfGetStore()->getPropertyValues($semdata->getSubject(), $pv); $newvalues = $semdata->getPropertyValues($pv); $updatejobflag = !self::equalDatavalues($oldvalues, $newvalues); } } if ($updatejobflag) { $prop = new SMWDIProperty($title->getDBkey()); $subjects = smwfGetStore()->getAllPropertySubjects($prop); foreach ($subjects as $subject) { $subjectTitle = $subject->getTitle(); if (!is_null($subjectTitle)) { // wikia change start - jobqueue migration $task = new \Wikia\Tasks\Tasks\JobWrapperTask(); $task->call('SMWUpdateJob', $subjectTitle); $jobs[] = $task; // wikia change end } } wfRunHooks('smwUpdatePropertySubjects', array(&$jobs)); $subjects = smwfGetStore()->getPropertySubjects(new SMWDIProperty('_ERRP'), $semdata->getSubject()); foreach ($subjects as $subject) { $subjectTitle = $subject->getTitle(); if (!is_null($subjectTitle)) { // wikia change start - jobqueue migration $task = new \Wikia\Tasks\Tasks\JobWrapperTask(); $task->call('SMWUpdateJob', $subjectTitle); $jobs[] = $task; // wikia change end } } } } elseif ($makejobs && $smwgEnableUpdateJobs && $namespace == SMW_NS_TYPE) { // if it is a type we need to check if the conversion factors have been changed $pconv = new SMWDIProperty('_CONV'); $ptype = new SMWDIProperty('_TYPE'); $oldfactors = smwfGetStore()->getPropertyValues($semdata->getSubject(), $pconv); $newfactors = $semdata->getPropertyValues($pconv); $updatejobflag = !self::equalDatavalues($oldfactors, $newfactors); if ($updatejobflag) { $store = smwfGetStore(); /// FIXME: this will kill large wikis! Use incremental updates! $dv = SMWDataValueFactory::newTypeIdValue('__typ', $title->getDBkey()); $proppages = $store->getPropertySubjects($ptype, $dv); foreach ($proppages as $proppage) { $propertyTitle = $proppage->getTitle(); if (!is_null($propertyTitle)) { // wikia change start - jobqueue migration $task = new \Wikia\Tasks\Tasks\JobWrapperTask(); $task->call('SMWUpdateJob', $propertyTitle); $jobs[] = $task; // wikia change end } $prop = new SMWDIProperty($proppage->getDBkey()); $subjects = $store->getAllPropertySubjects($prop); foreach ($subjects as $subject) { $subjectTitle = $subject->getTitle(); if (!is_null($subjectTitle)) { // wikia change start - jobqueue migration $task = new \Wikia\Tasks\Tasks\JobWrapperTask(); $task->call('SMWUpdateJob', $subjectTitle); $jobs[] = $task; // wikia change end } } $subjects = smwfGetStore()->getPropertySubjects(new SMWDIProperty('_ERRP'), $prop->getWikiPageValue()); foreach ($subjects as $subject) { $subjectTitle = $subject->getTitle(); if (!is_null($subjectTitle)) { // wikia change start - jobqueue migration $task = new \Wikia\Tasks\Tasks\JobWrapperTask(); $task->call('SMWUpdateJob', $subjectTitle); $jobs[] = $task; // wikia change end } } } } } // Actually store semantic data, or at least clear it if needed if ($processSemantics) { smwfGetStore()->updateData($semdata); } else { smwfGetStore()->clearData($semdata->getSubject()); } // Finally trigger relevant Updatejobs if necessary if ($updatejobflag) { // wikia change start - jobqueue migration \Wikia\Tasks\Tasks\BaseTask::batch($jobs); // wikia change end } return true; }
public function refreshData(&$index, $count, $namespaces = false, $usejobs = true) { $updatejobs = array(); $emptyrange = true; // was nothing found in this run? // update by MediaWiki page id --> make sure we get all pages $tids = array(); for ($i = $index; $i < $index + $count; $i++) { // array of ids $tids[] = $i; } $titles = Title::newFromIDs($tids); foreach ($titles as $title) { if ($namespaces == false || in_array($title->getNamespace(), $namespaces)) { // wikia change start - jobqueue migration $task = new \Wikia\Tasks\Tasks\JobWrapperTask(); $task->call('SMWUpdateJob', $title); $updatejobs[] = $task; // wikia change end $emptyrange = false; } } wfRunHooks('smwRefreshDataJobs', array(&$updatejobs)); if ($usejobs) { // wikia change start - jobqueue migration \Wikia\Tasks\Tasks\BaseTask::batch($updatejobs); // wikia change end } else { foreach ($updatejobs as $job) { // wikia change start - jobqueue migration /** @var \Wikia\Tasks\Tasks\JobWrapperTask $job */ try { $job->init(); } catch (Exception $e) { continue; } $job->wrap('SMWUpdateJob'); // wikia change end } } $db = wfGetDB(DB_SLAVE); $nextpos = $index + $count; if ($emptyrange) { // nothing found, check if there will be more pages later on $nextpos = $db->selectField('page', 'page_id', "page_id >= {$nextpos}", __METHOD__, array('ORDER BY' => "page_id ASC")); } $maxpos = $db->selectField('page', 'MAX(page_id)', '', __METHOD__); $index = $nextpos ? $nextpos : -1; return $index > 0 ? $index / $maxpos : 1; }
public function execute($par) { global $wgOut, $wgRequest, $wgServer, $wgArticlePath, $wgUser, $smwgAdminRefreshStore; if (!$this->userCanExecute($wgUser)) { // If the user is not authorized, show an error. $this->displayRestrictionError(); return; } $this->setHeaders(); /**** Get status of refresh job, if any ****/ $dbr = wfGetDB(DB_SLAVE); $row = $dbr->selectRow('job', '*', array('job_cmd' => 'SMWRefreshJob'), __METHOD__); if ($row !== false) { // similar to Job::pop_type, but without deleting the job $title = Title::makeTitleSafe($row->job_namespace, $row->job_title); $refreshjob = Job::factory($row->job_cmd, $title, Job::extractBlob($row->job_params), $row->job_id); } else { $refreshjob = null; } /**** Execute actions if any ****/ $action = $wgRequest->getText('action'); if ($action == 'updatetables') { $sure = $wgRequest->getText('udsure'); if ($sure == 'yes') { $wgOut->disable(); // raw output ob_start(); print "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\" lang=\"en\" dir=\"ltr\">\n<head><meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\" /><title>Setting up Storage for Semantic MediaWiki</title></head><body><p><pre>"; header("Content-type: text/html; charset=UTF-8"); $result = smwfGetStore()->setup(); wfRunHooks('smwInitializeTables'); print '</pre></p>'; if ($result === true) { print '<p><b>' . wfMsg('smw_smwadmin_setupsuccess') . "</b></p>\n"; } $returntitle = SpecialPage::getTitleFor('SMWAdmin'); print '<p> ' . wfMsg('smw_smwadmin_return', '<a href="' . htmlspecialchars($returntitle->getFullURL()) . '">Special:SMWAdmin</a>') . "</p>\n"; print '</body></html>'; ob_flush(); flush(); return; } } elseif ($smwgAdminRefreshStore && $action == 'refreshstore') { // managing refresh jobs for the store $sure = $wgRequest->getText('rfsure'); if ($sure == 'yes') { if (is_null($refreshjob)) { // careful, there might be race conditions here $title = SpecialPage::getTitleFor('SMWAdmin'); $jobParams = array('spos' => 1, 'prog' => 0, 'rc' => 2); // wikia change start - jobqueue migration $task = new \Wikia\Tasks\Tasks\JobWrapperTask(); $task->call('SMWRefreshJob', $title, $jobParams); $task->queue(); // wikia change end $wgOut->addHTML('<p>' . wfMsg('smw_smwadmin_updatestarted') . '</p>'); } else { $wgOut->addHTML('<p>' . wfMsg('smw_smwadmin_updatenotstarted') . '</p>'); } } elseif ($sure == 'stop') { $dbw = wfGetDB(DB_MASTER); // delete (all) existing iteration jobs $dbw->delete('job', array('job_cmd' => 'SMWRefreshJob'), __METHOD__); $wgOut->addHTML('<p>' . wfMsg('smw_smwadmin_updatestopped') . '</p>'); } else { $wgOut->addHTML('<p>' . wfMsg('smw_smwadmin_updatenotstopped') . '</p>'); } return; } /**** Normal output ****/ $html = '<p>' . wfMsg('smw_smwadmin_docu') . "</p>\n"; // creating tables and converting contents from older versions $html .= '<form name="buildtables" action="" method="POST">' . "\n" . '<input type="hidden" name="action" value="updatetables" />' . "\n"; $html .= '<br /><h2>' . wfMsg('smw_smwadmin_db') . "</h2>\n" . '<p>' . wfMsg('smw_smwadmin_dbdocu') . "</p>\n"; $html .= '<p>' . wfMsg('smw_smwadmin_permissionswarn') . "</p>\n" . '<input type="hidden" name="udsure" value="yes"/>' . '<input type="submit" value="' . wfMsg('smw_smwadmin_dbbutton') . '"/></form>' . "\n"; $html .= '<br /><h2>' . wfMsg('smw_smwadmin_datarefresh') . "</h2>\n" . '<p>' . wfMsg('smw_smwadmin_datarefreshdocu') . "</p>\n"; if (!is_null($refreshjob)) { $prog = $refreshjob->getProgress(); $html .= '<p>' . wfMsg('smw_smwadmin_datarefreshprogress') . "</p>\n" . '<p><div style="float: left; background: #DDDDDD; border: 1px solid grey; width: 300px; "><div style="background: #AAF; width: ' . round($prog * 300) . 'px; height: 20px; "> </div></div>  ' . round($prog * 100, 4) . '%</p><br /><br />'; if ($smwgAdminRefreshStore) { $html .= '<form name="refreshwiki" action="" method="POST">' . '<input type="hidden" name="action" value="refreshstore" />' . '<input type="submit" value="' . htmlspecialchars(wfMsg('smw_smwadmin_datarefreshstop')) . '" /> ' . ' <input type="checkbox" name="rfsure" value="stop"/> ' . htmlspecialchars(wfMsg('smw_smwadmin_datarefreshstopconfirm')) . '</form>' . "\n"; } } elseif ($smwgAdminRefreshStore) { $html .= '<form name="refreshwiki" action="" method="POST">' . '<input type="hidden" name="action" value="refreshstore" />' . '<input type="hidden" name="rfsure" value="yes"/>' . '<input type="submit" value="' . wfMsg('smw_smwadmin_datarefreshbutton') . '"/>' . '</form>' . "\n"; } $html .= '<br /><h2>' . wfMsg('smw_smwadmin_announce') . "</h2>\n" . '<p>' . wfMsg('smw_smwadmin_announcedocu') . "</p>\n" . '<p>' . wfMsg('smw_smwadmin_announcebutton') . "</p>\n" . '<form name="announcewiki" action="http://semantic-mediawiki.org/wiki/Special:SMWRegistry" method="GET">' . '<input type="hidden" name="url" value="' . $wgServer . str_replace('$1', '', $wgArticlePath) . '" />' . '<input type="hidden" name="return" value="Special:SMWAdmin" />' . '<input type="submit" value="' . wfMsg('smw_smwadmin_announce') . '"/></form>' . "\n"; $html .= '<br /><h2>' . wfMsg('smw_smwadmin_support') . "</h2>\n" . '<p>' . wfMsg('smw_smwadmin_supportdocu') . "</p>\n" . "<ul>\n" . '<li>' . wfMsg('smw_smwadmin_installfile') . "</li>\n" . '<li>' . wfMsg('smw_smwadmin_smwhomepage') . "</li>\n" . '<li>' . wfMsg('smw_smwadmin_mediazilla') . "</li>\n" . '<li>' . wfMsg('smw_smwadmin_questions') . "</li>\n" . "</ul>\n"; $wgOut->addHTML($html); }
/** * Helper method to write information about some redirect. Various updates * can be necessary if redirects are resolved as identities in SMW. The * title and namespace of the affected page and of its updated redirect * target are given. The target can be empty ('') to delete any redirect. * Returns the canonical ID that is now to be used for the subject. * * This method does not change the ids of the affected pages, and thus it * is not concerned with updates of the data that is currently stored for * the subject. Normally, a subject that is a redirect will not have other * data, but this method does not depend on this. * * @note Please make sure you fully understand this code before making any * changes here. Keeping the redirect structure consistent is important, * and errors in this code can go unnoticed for quite some time. * * @note This method merely handles the addition or deletion of a redirect * statement in the wiki. It does not assume that any page contents has * been changed (e.g. moved). See changeTitle() for additional handling in * this case. */ protected function updateRedirects($subject_t, $subject_ns, $curtarget_t = '', $curtarget_ns = -1) { global $smwgQEqualitySupport, $smwgEnableUpdateJobs; // *** First get id of subject, old redirect target, and current (new) redirect target ***// $sid = $this->getSMWPageID($subject_t, $subject_ns, '', '', false); // find real id of subject, if any /// NOTE: $sid can be 0 here; this is useful to know since it means that fewer table updates are needed $new_tid = $curtarget_t ? $this->makeSMWPageID($curtarget_t, $curtarget_ns, '', '', false) : 0; // real id of new target, if given $db = wfGetDB(DB_SLAVE, 'smw'); $row = $db->selectRow(array('smw_redi2'), 'o_id', array('s_title' => $subject_t, 's_namespace' => $subject_ns), __METHOD__); $old_tid = $row !== false ? $row->o_id : 0; // real id of old target, if any /// NOTE: $old_tid and $new_tid both (intentionally) ignore further redirects: no redirect chains if ($old_tid == $new_tid) { // no change, all happy return $new_tid == 0 ? $sid : $new_tid; } // note that this means $old_tid != $new_tid in all cases below // *** Make relevant changes in property tables (don't write the new redirect yet) ***// $db = wfGetDB(DB_MASTER, 'smw'); // now we need to write something if ($old_tid == 0 && $sid != 0 && $smwgQEqualitySupport != SMW_EQ_NONE) { // new redirect // $smwgQEqualitySupport requires us to change all tables' page references from $sid to $new_tid. // Since references must not be 0, we don't have to do this is $sid == 0. $this->changeSMWPageID($sid, $new_tid, $subject_ns, $curtarget_ns, false, true); } elseif ($old_tid != 0) { // existing redirect is changed or deleted $db->delete('smw_redi2', array('s_title' => $subject_t, 's_namespace' => $subject_ns), __METHOD__); if ($smwgEnableUpdateJobs && $smwgQEqualitySupport != SMW_EQ_NONE) { // entries that refer to old target may in fact refer to subject, // but we don't know which: schedule affected pages for update $jobs = array(); foreach (self::getPropertyTables() as $proptable) { if ($proptable->name == 'smw_redi2') { continue; } // can safely be skipped if ($proptable->idsubject) { $from = $db->tableName($proptable->name) . ' INNER JOIN ' . $db->tableName('smw_ids') . ' ON s_id=smw_id'; $select = 'DISTINCT smw_title AS t,smw_namespace AS ns'; } else { $from = $db->tableName($proptable->name); $select = 'DISTINCT s_title AS t,s_namespace AS ns'; } if ($subject_ns == SMW_NS_PROPERTY && !$proptable->fixedproperty) { $res = $db->select($from, $select, array('p_id' => $old_tid), __METHOD__); foreach ($res as $row) { $title = Title::makeTitleSafe($row->ns, $row->t); if (!is_null($title)) { // wikia change start - jobqueue migration $task = new \Wikia\Tasks\Tasks\JobWrapperTask(); $task->call('SMWUpdateJob', $title); $jobs[] = $task; // wikia change end } } $db->freeResult($res); } foreach ($proptable->objectfields as $fieldname => $type) { if ($type == 'p') { $res = $db->select($from, $select, array($fieldname => $old_tid), __METHOD__); foreach ($res as $row) { $title = Title::makeTitleSafe($row->ns, $row->t); if (!is_null($title)) { // wikia change start - jobqueue migration $task = new \Wikia\Tasks\Tasks\JobWrapperTask(); $task->call('SMWUpdateJob', $title); $jobs[] = $task; // wikia change end } } $db->freeResult($res); } } } /// NOTE: we do not update the concept cache here; this remains an offline task /// NOTE: this only happens if $smwgEnableUpdateJobs was true above: \Wikia\Tasks\Tasks\BaseTask::batch($jobs); } } // *** Finally, write the new redirect data ***// if ($new_tid != 0) { // record a new redirect // Redirecting done right: // (1) make a new ID with iw SMW_SQL2_SMWREDIIW or // change iw field of current ID in this way, // (2) write smw_redi2 table, // (3) update canonical cache. // This order must be obeyed unless you really understand what you are doing! if ($old_tid == 0 && $smwgQEqualitySupport != SMW_EQ_NONE) { // mark subject as redirect (if it was no redirect before) if ($sid == 0) { // every redirect page must have an ID $sid = $this->makeSMWPageID($subject_t, $subject_ns, SMW_SQL2_SMWREDIIW, '', false); } else { $db->update('smw_ids', array('smw_iw' => SMW_SQL2_SMWREDIIW), array('smw_id' => $sid), __METHOD__); $this->m_idCache->setId($subject_t, $subject_ns, '', '', 0); $this->m_idCache->setId($subject_t, $subject_ns, SMW_SQL2_SMWREDIIW, '', $sid); } } $db->insert('smw_redi2', array('s_title' => $subject_t, 's_namespace' => $subject_ns, 'o_id' => $new_tid), __METHOD__); } else { // delete old redirect // This case implies $old_tid != 0 (or we would have new_tid == old_tid above). // Therefore $subject had a redirect, and it must also have an ID. // This shows that $sid != 0 here. if ($smwgQEqualitySupport != SMW_EQ_NONE) { // mark subject as non-redirect $db->update('smw_ids', array('smw_iw' => ''), array('smw_id' => $sid), __METHOD__); $this->m_idCache->setId($subject_t, $subject_ns, '', '', $sid); } } // *** Flush some caches to be safe, though they are not essential in runs with redirect updates ***// unset($this->m_semdata[$sid]); unset($this->m_semdata[$new_tid]); unset($this->m_semdata[$old_tid]); unset($this->m_sdstate[$sid]); unset($this->m_sdstate[$new_tid]); unset($this->m_sdstate[$old_tid]); return $new_tid == 0 ? $sid : $new_tid; }
/** * @see SMWStore::refreshData * * @todo This method will be overhauled in SMW 1.9 to become cleaner * and more robust. * * @param integer $index * @param integer $count * @param mixed $namespaces Array or false * @param boolean $usejobs * * @return decimal between 0 and 1 to indicate the overall progress of the refreshing */ public function refreshData(&$index, $count, $namespaces = false, $usejobs = true) { $updatejobs = array(); $emptyrange = true; // was nothing done in this run? // Update by MediaWiki page id --> make sure we get all pages. $tids = array(); // Array of ids for ($i = $index; $i < $index + $count; $i++) { $tids[] = $i; } $titles = Title::newFromIDs($tids); foreach ($titles as $title) { if ($namespaces == false || in_array($title->getNamespace(), $namespaces)) { // wikia change start - jobqueue migration $task = new \Wikia\Tasks\Tasks\JobWrapperTask(); $task->call('SMWUpdateJob', $title); $updatejobs[] = $task; // wikia change end $emptyrange = false; } } // update by internal SMW id --> make sure we get all objects in SMW $dbr = wfGetDB(DB_SLAVE, 'smw'); $res = $dbr->select(SMWSql3SmwIds::tableName, array('smw_id', 'smw_title', 'smw_namespace', 'smw_iw', 'smw_subobject'), array("smw_id >= {$index} ", " smw_id < " . $dbr->addQuotes($index + $count)), __METHOD__); foreach ($res as $row) { $emptyrange = false; // note this even if no jobs were created if ($namespaces && !in_array($row->smw_namespace, $namespaces)) { continue; } // Find page to refresh, even for special properties: if ($row->smw_title != '' && $row->smw_title[0] != '_') { $titleKey = $row->smw_title; } elseif ($row->smw_namespace == SMW_NS_PROPERTY && $row->smw_iw == '' && $row->smw_subobject == '') { $titleKey = str_replace(' ', '_', SMWDIProperty::findPropertyLabel($row->smw_title)); } else { $titleKey = ''; } if ($row->smw_subobject !== '') { // leave subobjects alone; they ought to be changed with their pages } elseif (($row->smw_iw === '' || $row->smw_iw == SMW_SQL3_SMWREDIIW) && $titleKey != '') { // objects representing pages // TODO: special treament of redirects needed, since the store will // not act on redirects that did not change according to its records $title = Title::makeTitleSafe($row->smw_namespace, $titleKey); if ($title !== null && !$title->exists()) { // wikia change start - jobqueue migration $task = new \Wikia\Tasks\Tasks\JobWrapperTask(); $task->call('SMWUpdateJob', $title); $updatejobs[] = $task; // wikia change end } } elseif ($row->smw_iw == SMW_SQL3_SMWIW_OUTDATED) { // remove outdated internal object references $dbw = wfGetDB(DB_MASTER, 'smw'); foreach (SMWSQLStore3::getPropertyTables() as $proptable) { if ($proptable->usesIdSubject()) { $dbw->delete($proptable->getName(), array('s_id' => $row->smw_id), __METHOD__); } } $dbw->delete(SMWSql3SmwIds::tableName, array('smw_id' => $row->smw_id), __METHOD__); } elseif ($titleKey != '') { // "normal" interwiki pages or outdated internal objects -- delete $diWikiPage = new SMWDIWikiPage($titleKey, $row->smw_namespace, $row->smw_iw); $emptySemanticData = new SMWSemanticData($diWikiPage); $this->store->doDataUpdate($emptySemanticData); } } $dbr->freeResult($res); wfRunHooks('smwRefreshDataJobs', array(&$updatejobs)); if ($usejobs) { // wikia change start - jobqueue migration \Wikia\Tasks\Tasks\BaseTask::batch($updatejobs); // wikia change end } else { foreach ($updatejobs as $job) { // wikia change start - jobqueue migration /** @var \Wikia\Tasks\Tasks\JobWrapperTask $job */ try { $job->init(); } catch (Exception $e) { continue; } $job->wrap('SMWUpdateJob'); // wikia change end } } $nextpos = $index + $count; // smw+ wikia change, handler to local database $dbl = wfGetDB(DB_SLAVE); if ($emptyrange) { // nothing found, check if there will be more pages later on $next1 = $dbl->selectField('page', 'page_id', "page_id >= {$nextpos}", __METHOD__, array('ORDER BY' => "page_id ASC")); $next2 = $dbr->selectField(SMWSql3SmwIds::tableName, 'smw_id', "smw_id >= {$nextpos}", __METHOD__, array('ORDER BY' => "smw_id ASC")); $nextpos = $next2 != 0 && $next2 < $next1 ? $next2 : $next1; } $max1 = $dbl->selectField('page', 'MAX(page_id)', '', __METHOD__); $max2 = $dbr->selectField(SMWSql3SmwIds::tableName, 'MAX(smw_id)', '', __METHOD__); $index = $nextpos ? $nextpos : -1; return $index > 0 ? $index / max($max1, $max2) : 1; }
/** * Automatically creates a page that's red-linked from the page being * viewed, if there's a property pointing from anywhere to that page * that's defined with the 'Creates pages with form' special property */ static function createLinkedPage($title, $incoming_properties) { // if we're in a 'special' page, just exit - this is to prevent // constant additions being made from the 'Special:RecentChanges' // page, which shows pages that were previously deleted as red // links, even if they've since been recreated. The same might // hold true for other special pages. global $wgTitle; if (empty($wgTitle)) { return false; } if ($wgTitle->getNamespace() == NS_SPECIAL) { return false; } foreach ($incoming_properties as $property_name) { $auto_create_forms = self::getFormsThatPagePointsTo($property_name, SMW_NS_PROPERTY, self::AUTO_CREATE_FORM); if (count($auto_create_forms) > 0) { global $sfgFormPrinter; $form_name = $auto_create_forms[0]; $form_title = Title::makeTitleSafe(SF_NS_FORM, $form_name); $form_article = new Article($form_title); $form_definition = $form_article->getContent(); list($form_text, $javascript_text, $data_text, $form_page_title, $generated_page_name) = $sfgFormPrinter->formHTML($form_definition, false, false, null, null, 'Some very long page name that will hopefully never get created ABCDEF123', null); $params = array(); global $wgUser; $params['user_id'] = $wgUser->getId(); $params['page_text'] = $data_text; // wikia change start - jobqueue migration $task = new \Wikia\Tasks\Tasks\JobWrapperTask(); $task->call('createPage', $title, $params); $task->queue(); // wikia change end return true; } } return false; }
function execute($query) { global $wgOut, $wgRequest, $wgUser, $sfgScriptPath; global $wgLang, $smwgContLang; # Check permissions if (!$wgUser->isAllowed('createclass')) { $this->displayRestrictionError(); return; } $this->setHeaders(); $wgOut->addExtensionStyle($sfgScriptPath . "/skins/SemanticForms.css"); $numStartingRows = 10; self::addJavascript($numStartingRows); $property_name_error_str = ''; $save_page = $wgRequest->getCheck('save'); if ($save_page) { // Guard against cross-site request forgeries (CSRF) $validToken = $this->getUser()->matchEditToken($wgRequest->getVal('csrf'), 'CreateClass'); if (!$validToken) { $text = "This appears to be a cross-site request forgery; canceling save."; $wgOut->addHTML($text); return; } $template_name = trim($wgRequest->getVal("template_name")); $form_name = trim($wgRequest->getVal("form_name")); $category_name = trim($wgRequest->getVal("category_name")); if ($template_name === '' | $form_name === '' || $category_name === '') { $wgOut->addWikiMsg('sf_createclass_missingvalues'); return; } $fields = array(); $jobs = array(); // cycle through all the rows passed in for ($i = 1; $wgRequest->getCheck("property_name_{$i}"); $i++) { // go through the query values, setting the appropriate local variables $property_name = trim($wgRequest->getVal("property_name_{$i}")); if (empty($property_name)) { continue; } $field_name = trim($wgRequest->getVal("field_name_{$i}")); if ($field_name === '') { $field_name = $property_name; } $property_type = $wgRequest->getVal("property_type_{$i}"); $allowed_values = $wgRequest->getVal("allowed_values_{$i}"); $is_list = $wgRequest->getCheck("is_list_{$i}"); // create an SFTemplateField based on these // values, and add it to the $fields array $field = SFTemplateField::create($field_name, $field_name, $property_name, $is_list); $fields[] = $field; // create the property, and make a job for it $full_text = SFCreateProperty::createPropertyText($property_type, '', $allowed_values); $property_title = Title::makeTitleSafe(SMW_NS_PROPERTY, $property_name); $params = array(); $params['user_id'] = $wgUser->getId(); $params['page_text'] = $full_text; // wikia change start - jobqueue migration $job = new \Wikia\Tasks\Tasks\JobWrapperTask(); $job->call('createPage', $property_title, $params); $jobs[] = $job; // wikia change end } // create the template, and save it $full_text = SFTemplateField::createTemplateText($template_name, $fields, null, $category_name, null, null, null); $template_title = Title::makeTitleSafe(NS_TEMPLATE, $template_name); $template_article = new Article($template_title, 0); $edit_summary = ''; $template_article->doEdit($full_text, $edit_summary); // create the form, and make a job for it $form_template = SFTemplateInForm::create($template_name, '', false); $form_templates = array($form_template); $form = SFForm::create($form_name, $form_templates); $full_text = $form->createMarkup(); $form_title = Title::makeTitleSafe(SF_NS_FORM, $form_name); $params = array(); $params['user_id'] = $wgUser->getId(); $params['page_text'] = $full_text; // wikia change start - jobqueue migration $job = new \Wikia\Tasks\Tasks\JobWrapperTask(); $job->call('createPage', $form_title, $params); $jobs[] = $job; // wikia change end // create the category, and make a job for it $full_text = SFCreateCategory::createCategoryText($form_name, $category_name, ''); $category_title = Title::makeTitleSafe(NS_CATEGORY, $category_name); $params = array(); $params['user_id'] = $wgUser->getId(); $params['page_text'] = $full_text; // wikia change start - jobqueue migration $job = new \Wikia\Tasks\Tasks\JobWrapperTask(); $job->call('createPage', $category_title, $params); $jobs[] = $job; \Wikia\Tasks\Tasks\BaseTask::batch($jobs); // wikia change end $wgOut->addWikiMsg('sf_createclass_success'); return; } $datatype_labels = $smwgContLang->getDatatypeLabels(); // make links to all the other 'Create...' pages, in order to // link to them at the top of the page $sk = $wgUser->getSkin(); $creation_links = array(); $creation_links[] = SFUtils::linkForSpecialPage($sk, 'CreateProperty'); $creation_links[] = SFUtils::linkForSpecialPage($sk, 'CreateTemplate'); $creation_links[] = SFUtils::linkForSpecialPage($sk, 'CreateForm'); $creation_links[] = SFUtils::linkForSpecialPage($sk, 'CreateCategory'); $create_class_docu = wfMsg('sf_createclass_docu', $wgLang->listToText($creation_links)); $leave_field_blank = wfMsg('sf_createclass_leavefieldblank'); $form_name_label = wfMsg('sf_createclass_nameinput'); $template_name_label = wfMsg('sf_createtemplate_namelabel'); $category_name_label = wfMsg('sf_createcategory_name'); $property_name_label = wfMsg('sf_createproperty_propname'); $field_name_label = wfMsg('sf_createtemplate_fieldname'); $type_label = wfMsg('sf_createproperty_proptype'); $allowed_values_label = wfMsg('sf_createclass_allowedvalues'); $list_of_values_label = wfMsg('sf_createclass_listofvalues'); $text = <<<END <form action="" method="post"> \t<p>{$create_class_docu}</p> \t<p>{$leave_field_blank}</p> \t<p>{$template_name_label} <input type="text" size="30" name="template_name"></p> \t<p>{$form_name_label} <input type="text" size="30" name="form_name"></p> \t<p>{$category_name_label} <input type="text" size="30" name="category_name"></p> \t<div> \t\t<table id="mainTable"> \t\t<tr> \t\t\t<th colspan="2">{$property_name_label}</th> \t\t\t<th>{$field_name_label}</th> \t\t\t<th>{$type_label}</th> \t\t\t<th>{$allowed_values_label}</th> \t\t\t<th>{$list_of_values_label}</th> \t\t</tr> END; // Make one more row than what we're displaying - use the // last row as a "starter row", to be cloned when the // "Add another" button is pressed. for ($i = 1; $i <= $numStartingRows + 1; $i++) { if ($i == $numStartingRows + 1) { $rowString = 'id="starterRow" style="display: none"'; $n = 'starter'; } else { $rowString = ''; $n = $i; } $text .= <<<END \t\t<tr {$rowString}> \t\t\t<td>{$n}.</td> \t\t\t<td><input type="text" size="25" name="property_name_{$n}" /></td> \t\t\t<td><input type="text" size="25" name="field_name_{$n}" /></td> \t\t\t<td> \t\t\t<select name="property_type_{$n}"> END; $optionsStr = ""; foreach ($datatype_labels as $label) { $text .= "\t\t\t\t<option>{$label}</option>\n"; $optionsStr .= $label . ","; } $text .= <<<END \t\t\t</select> \t\t\t</td> \t\t\t<td><input type="text" size="25" name="allowed_values_{$n}" /></td> \t\t\t<td><input type="checkbox" name="is_list_{$n}" /></td> END; } $text .= <<<END \t\t</tr> \t\t</table> \t</div> END; $add_another_button = Html::element('input', array('type' => 'button', 'value' => wfMsg('sf_formedit_addanother'), 'onclick' => "createClassAddRow()")); $text .= Html::rawElement('p', null, $add_another_button) . "\n"; // Set 'title' as hidden field, in case there's no URL niceness $cc = $this->getTitle(); $text .= Html::hidden('title', SFUtils::titleURLString($cc)); $text .= Html::element('input', array('type' => 'submit', 'name' => 'save', 'value' => wfMsg('sf_createclass_create'))); $text .= Html::hidden('csrf', $this->getUser()->getEditToken('CreateClass')) . "\n"; $text .= "</form>\n"; $wgOut->addHTML($text); }