Difference between revisions of "Extension:AWCmod"
(add the new tag and special page) |
(update) |
||
Line 10: | Line 10: | ||
if (!defined('MEDIAWIKI')) die('Not an entry point.'); | if (!defined('MEDIAWIKI')) die('Not an entry point.'); | ||
− | define('AWCMOD_VERSION', '0. | + | define('AWCMOD_VERSION', '0.2.0, 2008-10-29'); |
+ | |||
+ | $wgAutoConfirmCount = 10^10; | ||
$wgExtensionFunctions[] = 'wfSetupAWCmod'; | $wgExtensionFunctions[] = 'wfSetupAWCmod'; | ||
− | $wgExtensionCredits['other'][] = array( | + | $wgExtensionCredits['other'][] = $wgExtensionCredits['specialpage'][] = array( |
'name' => 'AWCmod', | 'name' => 'AWCmod', | ||
'author' => '[http://www.organicdesign.co.nz/User:Nad User:Nad]', | 'author' => '[http://www.organicdesign.co.nz/User:Nad User:Nad]', | ||
'description' => 'Custom extension for Adeft', | 'description' => 'Custom extension for Adeft', | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
'url' => 'http://www.organicdesign.co.nz/Extension:AWCmod', | 'url' => 'http://www.organicdesign.co.nz/Extension:AWCmod', | ||
'version' => AWCMOD_VERSION | 'version' => AWCMOD_VERSION | ||
Line 37: | Line 31: | ||
# Process posted contact details | # Process posted contact details | ||
if (isset($_POST['wpFirstName'])) { | if (isset($_POST['wpFirstName'])) { | ||
− | $_POST['wpRealName'] | + | $_POST['wpRealName'] = $_POST['wpFirstName'].' '.$_POST['wpLastName']; |
} | } | ||
Line 56: | Line 50: | ||
class AWCmod { | class AWCmod { | ||
+ | var $JS = ''; | ||
var $searchPrefs = array(); | var $searchPrefs = array(); | ||
− | + | var $skillsOptions = ''; | |
+ | var $stateOptions = ''; | ||
+ | var $countyOptions = ''; | ||
+ | |||
function __construct() { | function __construct() { | ||
− | global $wgHooks, $wgMessageCache, $wgParser, $wgTitle, $awcSearchByPref; | + | global $wgUser, $wgHooks, $wgMessageCache, $wgParser, $wgTitle, $awcSearchByPref, $wgGroupPermissions, $wgWhitelistRead; |
+ | |||
+ | # Deny access until email address confirmed | ||
+ | #$wgGroupPermissions['*']['read'] = false; | ||
+ | #$wgWhitelistRead = array("Special:Preferences", "Special:Userlogin", "-"); | ||
+ | #if (!$wgUser->isEmailConfirmed()) $wgGroupPermissions['user']['read'] = false; | ||
$this->searchPrefs = $awcSearchByPref; | $this->searchPrefs = $awcSearchByPref; | ||
Line 76: | Line 79: | ||
$wgParser->setHook('forum_search', array($this, 'forumTag')); | $wgParser->setHook('forum_search', array($this, 'forumTag')); | ||
$wgParser->setHook('profile_search', array($this, 'profileTag')); | $wgParser->setHook('profile_search', array($this, 'profileTag')); | ||
+ | |||
} | } | ||
+ | |||
+ | /** | ||
+ | * Prepare the dropdown list content if using a special page containing one of our forms | ||
+ | */ | ||
+ | function buildOptionLists() { | ||
+ | global $wgUser; | ||
+ | include(dirname(__FILE__)."/states.php"); | ||
+ | $this->JS = $awcJS; | ||
+ | |||
+ | # Build skills option list | ||
+ | $skills = $wgUser->getOption('skills'); | ||
+ | $this->skillsOptions = '<option/>'; | ||
+ | foreach (array( | ||
+ | 'Concerned Citizen', | ||
+ | 'Accountant', | ||
+ | 'Lawyer', | ||
+ | 'Tax Advisor', | ||
+ | 'Tax Agent', | ||
+ | 'Assessor', | ||
+ | 'Realtor' | ||
+ | ) as $s) { | ||
+ | $selected = $skills == $s ? ' selected' : ''; | ||
+ | $this->skillsOptions .= "<option$selected>$s</option>\n"; | ||
+ | } | ||
+ | |||
+ | # Build state options list | ||
+ | $state = $wgUser->getOption('state'); | ||
+ | $this->stateOptions = '<option value="">Enter state...</option>'; | ||
+ | foreach (array_keys($awcStates) as $s) { | ||
+ | $selected = $state == $s ? ' selected' : ''; | ||
+ | $this->stateOptions .= "<option$selected>$s</option>\n"; | ||
+ | } | ||
+ | |||
+ | # Build county options list | ||
+ | $county = $wgUser->getOption('county'); | ||
+ | $this->countyOptions = '<option value="">Enter county...</option>'; | ||
+ | if ($state) { | ||
+ | foreach (split(',', $awcStates[$state]) as $c) { | ||
+ | $c = substr($c, 1, -1); | ||
+ | $selected = $county == $c ? ' selected' : ''; | ||
+ | $this->countyOptions .= "<option$selected>$c</option>\n"; | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | |||
/** | /** | ||
* Hack to add onSubmit to form for validation | * Hack to add onSubmit to form for validation | ||
*/ | */ | ||
function onSpecialPageExecuteAfterPage(&$special, $par, $func) { | function onSpecialPageExecuteAfterPage(&$special, $par, $func) { | ||
− | |||
if ($special->mName == 'Preferences') { | if ($special->mName == 'Preferences') { | ||
global $wgOut; | global $wgOut; | ||
Line 94: | Line 142: | ||
*/ | */ | ||
function onRenderPreferencesForm(&$form, &$out) { | function onRenderPreferencesForm(&$form, &$out) { | ||
− | $out->addHTML('<fieldset><legend> | + | $out->addHTML('<fieldset><legend>'.wfMsg('awc-preftab').'</legend>'.wfMsg('awc-prefmsg').$this->renderAWCprefs().'</fieldset>'); |
return true; | return true; | ||
} | } | ||
Line 150: | Line 198: | ||
function renderAWCprefs() { | function renderAWCprefs() { | ||
global $wgUser, $wgOut, $wgHooks; | global $wgUser, $wgOut, $wgHooks; | ||
− | + | $this->buildOptionLists(); | |
− | $wgOut->addScript("<script type='text/javascript'>$ | + | $wgOut->addScript("<script type='text/javascript'>{$this->JS}</script>"); |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
$html = "<div class=awc-loginprefs><table>" . | $html = "<div class=awc-loginprefs><table>" . | ||
Line 211: | Line 224: | ||
$this->addRow( | $this->addRow( | ||
wfLabel('Expertise', 'wpSkills'), | wfLabel('Expertise', 'wpSkills'), | ||
− | '<select name="wpSkills" id="wpSkills">'.$skillsOptions.'</select>' | + | '<select name="wpSkills" id="wpSkills">'.$this->skillsOptions.'</select>' |
) . | ) . | ||
$this->addRow( | $this->addRow( | ||
Line 235: | Line 248: | ||
$this->addRow( | $this->addRow( | ||
wfLabel('State', 'wpState'), | wfLabel('State', 'wpState'), | ||
− | '<select name="wpState" id="wpState" onchange="awcUpdateCounty(this.value)">'.$stateOptions.'</select>', | + | '<select name="wpState" id="wpState" onchange="awcUpdateCounty(this.value)">'.$this->stateOptions.'</select>', |
'Required' | 'Required' | ||
) . | ) . | ||
$this->addRow( | $this->addRow( | ||
wfLabel('County', 'wpCounty'), | wfLabel('County', 'wpCounty'), | ||
− | '<select name="wpCounty" id="wpCounty">'.$countyOptions.'</select>', | + | '<select name="wpCounty" id="wpCounty">'.$this->countyOptions.'</select>', |
'Required' | 'Required' | ||
) . | ) . | ||
Line 385: | Line 398: | ||
*/ | */ | ||
class SpecialProfileSearch extends SpecialPage { | class SpecialProfileSearch extends SpecialPage { | ||
+ | |||
+ | var $posted = array(); | ||
+ | var $results = array(); | ||
function __construct() { | function __construct() { | ||
Line 402: | Line 418: | ||
*/ | */ | ||
function execute($param) { | function execute($param) { | ||
− | global $wgOut, $wgRequest; | + | global $wgAWCmod, $wgOut, $wgRequest; |
$this->setHeaders(); | $this->setHeaders(); | ||
$title = Title::makeTitle(NS_SPECIAL, 'ProfileSearch'); | $title = Title::makeTitle(NS_SPECIAL, 'ProfileSearch'); | ||
+ | |||
+ | # Get any posted/getted values and add to object->posted array | ||
+ | |||
+ | # Render form including any posted vals | ||
+ | $wgAWCmod->buildOptionLists(); | ||
+ | $wgOut->addScript("<script type='text/javascript'>{$wgAWCmod->JS}</script>"); | ||
+ | $wgOut->addHTML( | ||
+ | wfElement('form', array('class' => 'profilesearch', 'action' => $title->getLocalURL('action=submit'), 'method' => 'post'), null) | ||
+ | # .'<b>Record ID:</b> '.wfElement('input', array('name' => 'wpTitle', 'size' => 30, 'value' => $wpTitle)) | ||
+ | # .' '.wfElement('input', array('name' => 'wpInvert', 'type' => 'checkbox')).' Invert selection' | ||
+ | ."\n<br><br><hr><br><table>\n" | ||
+ | |||
+ | .$wgAWCmod->addRow( | ||
+ | wfLabel('City', 'wpCity'), | ||
+ | wfInput('wpCity', 20, '', array('id' => 'wpCity')) | ||
+ | ) | ||
+ | .$wgAWCmod->addRow( | ||
+ | wfLabel('State', 'wpState'), | ||
+ | '<select name="wpState" id="wpState" onchange="awcUpdateCounty(this.value)">'.$wgAWCmod->stateOptions.'</select>' | ||
+ | ) | ||
+ | .$wgAWCmod->addRow( | ||
+ | wfLabel('County', 'wpCounty'), | ||
+ | '<select name="wpCounty" id="wpCounty">'.$wgAWCmod->countyOptions.'</select>' | ||
+ | ) | ||
+ | |||
+ | # .wfElement('input', array('type' => 'hidden', 'name' => 'wpType', 'value' => $type)) | ||
+ | |||
+ | .'</table><br><hr><br><table width="100%"><tr>' | ||
+ | .'<td>'.wfElement('input', array('type' => 'submit', 'name' => 'wpFind', 'value' => "Search")).'</td>' | ||
+ | .'<td width="100%" align="left">'.wfElement('input', array('type' => 'reset', 'value' => "Reset")).'</td>' | ||
+ | .'</tr></table></form>' | ||
+ | ); | ||
+ | |||
+ | # Perform query and render results if any posted vals | ||
+ | if (count($this->posted)) { | ||
+ | |||
+ | # Convert the prefs to an SQL condition statement for selecting users | ||
+ | $cond = array(); | ||
+ | foreach ($this->posted as $k => $v) $cond[] = "(user_options REGEXP('$k=$v'))"; | ||
+ | |||
+ | # Extract the fields for each user from the database | ||
+ | $dbr = wfGetDB(DB_SLAVE); | ||
+ | $tbl = $dbr->tableName('user'); | ||
+ | $res = $dbr->select($tbl, '*', join(' AND ', $cond)); | ||
+ | while ($row = $dbr->fetchRow($res)) { | ||
+ | $user = User::newFromRow($row); | ||
+ | $this->results[] = array( | ||
+ | 'First Name' => $user->getOption('firstname'), | ||
+ | 'Last Name' => $user->getOption('lastname'), | ||
+ | 'Expertise' => $user->getOption('skills'), | ||
+ | 'Business' => $user->getOption('business'), | ||
+ | 'City' => $user->getOption('city'), | ||
+ | 'State' => $user->getOption('State'), | ||
+ | 'County' => $user->getOption('County') | ||
+ | ); | ||
+ | } | ||
+ | $dbr->freeResult($res); | ||
+ | |||
+ | # Render results if any | ||
+ | if (count($this->results)) { | ||
+ | $title = Title::makeTitle(NS_SPECIAL, 'ProfileSearch'); | ||
+ | $head = join('</th><th>', array_keys($this->results[0])); | ||
+ | $wgOut->addHTML("<table class='sortable' id='searchResults'><tr><th>$head</th></tr>\n"); | ||
+ | foreach ($this->results as $row) $wgOut->addHTML("<tr><td>".join("</td><td>", $row)."</td></tr>\n"); | ||
+ | $wgOut->addHTML("</table>\n"); | ||
+ | } else $wgOut->addHTML('<i>No results to display</i>'); | ||
+ | } | ||
} | } | ||
} | } | ||
Line 414: | Line 497: | ||
if ($wgLanguageCode == 'en') { | if ($wgLanguageCode == 'en') { | ||
$wgMessageCache->addMessages(array( | $wgMessageCache->addMessages(array( | ||
− | 'profilesearch' => | + | 'profilesearch' => "Search by profile", |
− | 'awc- | + | 'awc-preftab' => "Extended Profile", |
+ | 'awc-prefmsg' => "<br><b>Client supplied explanation of this tab goes here.</b><br> | ||
+ | Change at end of the <i>AWCmod.php</i> script, remember to update the source | ||
+ | <a href='http://www.organicdesign.co.nz/Extensions:AWCmod'>here</a>.<br><br>", | ||
)); | )); | ||
} | } |
Revision as of 09:24, 29 October 2008
<?php /**
* AWC extension *Template:Php
* @package MediaWiki * @subpackage Extensions * @author Aran Dunkley User:Nad * @licence GNU General Public Licence 2.0 or later */
if (!defined('MEDIAWIKI')) die('Not an entry point.');
define('AWCMOD_VERSION', '0.2.0, 2008-10-29');
$wgAutoConfirmCount = 10^10;
$wgExtensionFunctions[] = 'wfSetupAWCmod'; $wgExtensionCredits['other'][] = $wgExtensionCredits['specialpage'][] = array( 'name' => 'AWCmod', 'author' => 'User:Nad', 'description' => 'Custom extension for Adeft', 'url' => 'http://www.organicdesign.co.nz/Extension:AWCmod', 'version' => AWCMOD_VERSION );
require_once "$IP/includes/SpecialPage.php";
- Check if any awcpref parameters passed in request
$awcSearchByPref = array(); foreach ($_REQUEST as $k => $v) if (ereg('^awcsbp_(.+)$', $k, $m)) $awcSearchByPref[$m[1]] = $v;
- Process posted contact details
if (isset($_POST['wpFirstName'])) { $_POST['wpRealName'] = $_POST['wpFirstName'].' '.$_POST['wpLastName']; }
- Don't apply the db hook unless awcsearchprefs have been posted
if ($awcDBHook = count($awcSearchByPref) > 0) $_POST['fID'] = array('all');
- First stage of db patch
if ($awcDBHook) {
# SearchEngine is based on $wgDBtype so must be set before it gets changed to DatabaseAWC # - this may be paranoid now since $wgDBtype is changed back after LoadBalancer has initialised AWCmod::fixSearchType();
$wgOldDBtype = $wgDBtype; if (class_exists('Database')) wfAWCmodDBHook(); }
class AWCmod {
var $JS = ; var $searchPrefs = array(); var $skillsOptions = ; var $stateOptions = ; var $countyOptions = ;
function __construct() { global $wgUser, $wgHooks, $wgMessageCache, $wgParser, $wgTitle, $awcSearchByPref, $wgGroupPermissions, $wgWhitelistRead;
# Deny access until email address confirmed #$wgGroupPermissions['*']['read'] = false; #$wgWhitelistRead = array("Special:Preferences", "Special:Userlogin", "-");
#if (!$wgUser->isEmailConfirmed()) $wgGroupPermissions['user']['read'] = false;
$this->searchPrefs = $awcSearchByPref;
$wgHooks['RenderPreferencesForm'][] = $this; #$wgHooks['UserCreateForm'][] = $this; $wgHooks['SavePreferences'][] = $this; #$wgHooks['AbortNewAccount'][] = $this; $wgHooks['SpecialPageExecuteAfterPage'][] = $this;
# Modify login form messages to say email and name compulsory
- $wgMessageCache->addMessages(array('prefs-help-email' => 'Required'));
- $wgMessageCache->addMessages(array('prefs-help-realname' => 'Required'));
# Add a tag for creating search links $wgParser->setHook('forum_search', array($this, 'forumTag')); $wgParser->setHook('profile_search', array($this, 'profileTag'));
}
/**
* Prepare the dropdown list content if using a special page containing one of our forms
*/
function buildOptionLists() {
global $wgUser;
include(dirname(__FILE__)."/states.php");
$this->JS = $awcJS;
# Build skills option list $skills = $wgUser->getOption('skills'); $this->skillsOptions = '<option/>'; foreach (array( 'Concerned Citizen', 'Accountant', 'Lawyer', 'Tax Advisor', 'Tax Agent', 'Assessor', 'Realtor' ) as $s) { $selected = $skills == $s ? ' selected' : ; $this->skillsOptions .= "<option$selected>$s</option>\n"; }
# Build state options list $state = $wgUser->getOption('state'); $this->stateOptions = '<option value="">Enter state...</option>'; foreach (array_keys($awcStates) as $s) { $selected = $state == $s ? ' selected' : ; $this->stateOptions .= "<option$selected>$s</option>\n"; }
# Build county options list $county = $wgUser->getOption('county'); $this->countyOptions = '<option value="">Enter county...</option>'; if ($state) { foreach (split(',', $awcStates[$state]) as $c) { $c = substr($c, 1, -1); $selected = $county == $c ? ' selected' : ; $this->countyOptions .= "<option$selected>$c</option>\n"; } } }
/** * Hack to add onSubmit to form for validation */ function onSpecialPageExecuteAfterPage(&$special, $par, $func) { if ($special->mName == 'Preferences') { global $wgOut; $wgOut->mBodytext = str_replace('<form', '<form onsubmit="return awcValidate(this)"', $wgOut->mBodytext); } return true; }
/** * Add the new prefs to a new tab in the preferences form */ function onRenderPreferencesForm(&$form, &$out) { $out->addHTML('<fieldset><legend>'.wfMsg('awc-preftab').'</legend>'.wfMsg('awc-prefmsg').$this->renderAWCprefs().'</fieldset>'); return true; }
/** * Add the new prefs to the "create new account" form */ function onUserCreateForm(&$template) { $template->data['header'] = $this->renderAWCprefs(); return true; }
/** * Update the user object when the prefs from the form are saved */ function onSavePreferences(&$form, &$user) { $this->setOptions($user); return true; }
/** * Update the user object with extra prefs in the account-creation form */ function onAbortNewAccount(&$user, &$error) { $this->setOptions($user); return true; }
/** * Set user options from posted form */ function setOptions(&$user) { global $wgRequest; $user->setOption('firstname', $wgRequest->getVal('wpFirstName')); $user->setOption('lastname', $wgRequest->getVal('wpLastName')); $user->setOption('phone', $wgRequest->getVal('wpPhone')); $user->setOption('mobile', $wgRequest->getVal('wpMobile')); $user->setOption('business', $wgRequest->getVal('wpBusiness')); $user->setOption('skills', $wgRequest->getVal('wpSkills')); $user->setOption('website', $wgRequest->getVal('wpWebsite')); $user->setOption('fax', $wgRequest->getVal('wpFax')); $user->setOption('address', $wgRequest->getVal('wpAddress')); $user->setOption('address2', $wgRequest->getVal('wpAddress2')); $user->setOption('city', $wgRequest->getVal('wpCity')); $user->setOption('state', $wgRequest->getVal('wpState')); $user->setOption('county', $wgRequest->getVal('wpCounty')); $user->setOption('zipcode', $wgRequest->getVal('wpZipCode')); $user->setOption('logo', $wgRequest->getVal('wpLogo')); $user->setOption('notes', $wgRequest->getVal('wpNotes')); }
/** * Return the HTML for the AWC preference inputs */ function renderAWCprefs() { global $wgUser, $wgOut, $wgHooks; $this->buildOptionLists(); $wgOut->addScript("<script type='text/javascript'>{$this->JS}</script>");
$html = "
$this->addRow( wfLabel('First Name', 'wpFirstName'), wfInput('wpFirstName', 20, $wgUser->getOption('firstname'), array('id' => 'wpFirstName')) ) . $this->addRow( wfLabel('Last Name', 'wpLastName'), wfInput('wpLastName', 20, $wgUser->getOption('lastname'), array('id' => 'wpLastName')) ) . $this->addRow( wfLabel('Voice Phone', 'wpPhone'), wfInput('wpPhone', 10, $wgUser->getOption('phone'), array('id' => 'wpPhone')) ) . $this->addRow( wfLabel('Mobile Phone', 'wpMobile'), wfInput('wpMobile', 10, $wgUser->getOption('mobile'), array('id' => 'wpMobile')) ) . $this->addRow( wfLabel('Fax', 'wpFax'), wfInput('wpFax', 10, $wgUser->getOption('fax'), array('id' => 'wpFax')) ) . $this->addRow( wfLabel('Expertise', 'wpSkills'), '<select name="wpSkills" id="wpSkills">'.$this->skillsOptions.'</select>' ) . $this->addRow( wfLabel('Business', 'wpBusiness'), wfInput('wpBusiness', 20, $wgUser->getOption('business'), array('id' => 'wpBusiness')) ) . $this->addRow( wfLabel('Website', 'wpWebsite'), wfInput('wpWebsite', 20, $wgUser->getOption('website'), array('id' => 'wpWebsite')) ) . $this->addRow( wfLabel('Address', 'wpAddress'), wfInput('wpAddress', 20, $wgUser->getOption('address'), array('id' => 'wpAddress')) ) . $this->addRow( wfLabel('Address 2', 'wpAddress2'), wfInput('wpAddress2', 20, $wgUser->getOption('address2'), array('id' => 'wpAddress2')) ) . $this->addRow( wfLabel('City', 'wpCity'), wfInput('wpCity', 20, $wgUser->getOption('city'), array('id' => 'wpCity')) ) . $this->addRow( wfLabel('State', 'wpState'), '<select name="wpState" id="wpState" onchange="awcUpdateCounty(this.value)">'.$this->stateOptions.'</select>', 'Required' ) . $this->addRow( wfLabel('County', 'wpCounty'), '<select name="wpCounty" id="wpCounty">'.$this->countyOptions.'</select>', 'Required' ) . $this->addRow( wfLabel('Zip Code', 'wpZipCode'), wfInput('wpZipCode', 10, $wgUser->getOption('zipcode'), array('id' => 'wpZipCode')) ) . $this->addRow( wfLabel('Logo', 'wpLogo'), wfInput('wpLogo', 10, $wgUser->getOption('logo'), array('id' => 'wpLogo', 'type' => 'file')) ) . $this->addRow(wfLabel('Additional information', 'wpNotes'), )
. '' . '<textarea cols=30 rows="7" id="wpNotes" name="wpNotes">'.$wgUser->getOption('notes').'</textarea> |
';
$html .= '<script type="text/javascript">awcAddValidation()</script>'; return $html; }
function addRow($td1, $td2, $td3 = ) {
return " $td1: $td2
"; } /** * Render a link to Special:AWCForum */ function forumTag($text, $argv, &$parser) { # Default args for a search link $defaults = array( 'action' => 'search/s_form', 'full' => 'full', 'Sis_like' => 'like', 'kw' => 'default', 's_memposts' => 'on', 'is_like' => 'is', 'memname' => , 'fID' => array('all') ); # Build query string from defaults and tag args $qs = array(); foreach ($argv as $k => $v) { if (!in_array($k, array_keys($defaults))) $qs[] = "awcsbp_$k=$v"; } if (count($qs)) $argv['memname'] = 'dummy'; foreach ($defaults as $k => $v) { if (in_array($k, array_keys($argv))) $v = $argv[$k]; if (is_array($v)) foreach ($v as $i) $qs[] = "{$k}[]=$i"; else $qs[] = "$k=$v"; } $qs = join('&', $qs); # Build link $url = Title::newFromText('AWCForum', NS_SPECIAL)->getLocalURL($qs); $link = "<a href='$url'>$text</a>"; return $link; } /** * Render a link to Special:AWCProfile */ function profileTag($text, $argv, &$parser) { $qs = array(); $qs = join('&', $qs); $url = Title::newFromText('ProfileSearch', NS_SPECIAL)->getLocalURL($qs); return $link; } /** * Patch the SQL used by the search to filter by user properties */ function patchSQL(&$sql) { # Convert the prefs to an SQL condition statement for selecting users $cond = array(); foreach ($this->searchPrefs as $k => $v) $cond[] = "(user_options REGEXP('$k=$v'))"; if (count($cond)) { # Convert the resulting users to an SQL condition statement for the AWC query $dbr = wfGetDB(DB_SLAVE); $tbl = $dbr->tableName('user'); $res = $dbr->select($tbl, 'user_name', join(' AND ', $cond)); $cond = array(); while ($row = $dbr->fetchRow($res)) $cond[] = "p.p_user='$row[0]'"; $dbr->freeResult($res); # Replace the default user condition in the SQL with the new one if (count($cond)) { $sql = preg_replace("|p.p_user\\s=\\s*'dummy'|", '('.join(' OR ', $cond).')', $sql); $sql = preg_replace("|'%default%'|", "'%%'", $sql); } } } /** * Updates passed LoadBalancer's DB servers to secure class */ static function updateLB(&$lb) { $lb->closeAll(); foreach ($lb->mServers as $i => $server) $lb->mServers[$i]['type'] = 'AWC'; } /** * Hack to ensure proper search class is used * - $wgDBtype determines search class unless already defined in $wgSearchType * - just copied method from SearchEngine::create() */ static function fixSearchType() { global $wgDBtype, $wgSearchType; if ($wgSearchType) return; elseif ($wgDBtype == 'mysql') $wgSearchType = 'SearchMySQL4'; elseif ($wgDBtype == 'postgres') $wgSearchType = 'SearchPostgres'; elseif ($wgDBtype == 'oracle') $wgSearchType = 'SearchOracle'; else $wgSearchType = 'SearchEngineDummy'; } } /** * Hook in to DB class to allow overriding the AWC query (based on SimpleSecurity method) */ function wfAWCmodDBHook() { global $wgDBtype, $awcDBHook, $wgOldDBtype; $oldClass = ucfirst($wgDBtype); $wgDBtype = 'AWC'; eval("class Database{$wgDBtype} extends Database{$oldClass}".' { public function query($sql, $fname = "", $tempIgnore = false) { #print $sql; global $wgAWCmod; if (is_object($wgAWCmod) && (preg_match("|^SELECT.+?FROM.+?WHERE.+?p.p_user\\s*=\\s*\'dummy\'|s",$sql))) $wgAWCmod->patchSQL($sql); return parent::query($sql, $fname, $tempIgnore); } }'); $awcDBHook = false; } /** * Define a new class based on the SpecialPage class */ class SpecialProfileSearch extends SpecialPage { var $posted = array(); var $results = array(); function __construct() { SpecialPage::SpecialPage( 'ProfileSearch', # name as seen in links etc false, # user rights required true, # listed in special:specialpages false, # function called by execute() - defaults to wfSpecial{$name} false, # file included by execute() - defaults to Special{$name}.php, only used if no function false # includable ); } /** * Override SpecialPage::execute() */ function execute($param) { global $wgAWCmod, $wgOut, $wgRequest; $this->setHeaders(); $title = Title::makeTitle(NS_SPECIAL, 'ProfileSearch'); # Get any posted/getted values and add to object->posted array # Render form including any posted vals $wgAWCmod->buildOptionLists(); $wgOut->addScript("<script type='text/javascript'>{$wgAWCmod->JS}</script>"); $wgOut->addHTML( wfElement('form', array('class' => 'profilesearch', 'action' => $title->getLocalURL('action=submit'), 'method' => 'post'), null)
- .'Record ID: '.wfElement('input', array('name' => 'wpTitle', 'size' => 30, 'value' => $wpTitle))
- .' '.wfElement('input', array('name' => 'wpInvert', 'type' => 'checkbox')).' Invert selection'
."\n
.$wgAWCmod->addRow( wfLabel('City', 'wpCity'), wfInput('wpCity', 20, , array('id' => 'wpCity')) ) .$wgAWCmod->addRow( wfLabel('State', 'wpState'), '<select name="wpState" id="wpState" onchange="awcUpdateCounty(this.value)">'.$wgAWCmod->stateOptions.'</select>' ) .$wgAWCmod->addRow( wfLabel('County', 'wpCounty'), '<select name="wpCounty" id="wpCounty">'.$wgAWCmod->countyOptions.'</select>' )
- .wfElement('input', array('type' => 'hidden', 'name' => 'wpType', 'value' => $type))
'.wfElement('input', array('type' => 'submit', 'name' => 'wpFind', 'value' => "Search")).' | '.wfElement('input', array('type' => 'reset', 'value' => "Reset")).' |
</form>'
);
# Perform query and render results if any posted vals if (count($this->posted)) {
# Convert the prefs to an SQL condition statement for selecting users $cond = array(); foreach ($this->posted as $k => $v) $cond[] = "(user_options REGEXP('$k=$v'))";
# Extract the fields for each user from the database $dbr = wfGetDB(DB_SLAVE); $tbl = $dbr->tableName('user'); $res = $dbr->select($tbl, '*', join(' AND ', $cond)); while ($row = $dbr->fetchRow($res)) { $user = User::newFromRow($row); $this->results[] = array( 'First Name' => $user->getOption('firstname'), 'Last Name' => $user->getOption('lastname'), 'Expertise' => $user->getOption('skills'), 'Business' => $user->getOption('business'), 'City' => $user->getOption('city'), 'State' => $user->getOption('State'), 'County' => $user->getOption('County') ); } $dbr->freeResult($res);
# Render results if any if (count($this->results)) { $title = Title::makeTitle(NS_SPECIAL, 'ProfileSearch');
$head = join('', array_keys($this->results[0])); $wgOut->addHTML("
\n"); foreach ($this->results as $row) $wgOut->addHTML("\n"); $wgOut->addHTML("$head | |
---|---|
".join(" | ", $row)." |
\n");
} else $wgOut->addHTML('No results to display'); } } }
function wfSetupAWCmod() { global $wgAWCmod, $awcDBHook, $wgLanguageCode, $wgMessageCache, $wgLoadBalancer, $wgDBtype, $wgOldDBtype;
# Add the messages used by the specialpage
if ($wgLanguageCode == 'en') {
$wgMessageCache->addMessages(array(
'profilesearch' => "Search by profile",
'awc-preftab' => "Extended Profile",
'awc-prefmsg' => "
Client supplied explanation of this tab goes here.
Change at end of the AWCmod.php script, remember to update the source
<a href='http://www.organicdesign.co.nz/Extensions:AWCmod'>here</a>.
",
));
}
# Add the specialpage to the environment SpecialPage::addPage(new SpecialProfileSearch());
# Instantiate the AWC singleton now that the environment is prepared $wgAWCmod = new AWCmod();
if ($awcDBHook) {
# If the DB hook couldn't be set up early, do it now # - but now the LoadBalancer exists and must have its DB types changed wfAWCmodDBHook(); if (function_exists('wfGetLBFactory')) wfGetLBFactory()->forEachLB(array('AWCmod', 'updateLB')); elseif (is_object($wgLoadBalancer)) AWCmod::updateLB($wgLoadBalancer); else die("Can't hook in to Database class!");
# Request a DB connection to ensure the LoadBalancer is initialised, # then change back to old DBtype since it won't be used for making connections again but can affect other operations # such as $wgContLang->stripForSearch which is called by SearchMySQL::parseQuery wfGetDB(); $wgDBtype = $wgOldDBtype; }
}