Difference between revisions of "Extension:AWCmod"

From Organic Design wiki
m (ver)
(0.0.5 - make new form tab read its current values)
Line 10: Line 10:
 
if (!defined('MEDIAWIKI')) die('Not an entry point.');
 
if (!defined('MEDIAWIKI')) die('Not an entry point.');
  
define('AWCMOD_VERSION', '0.0.4, 2008-10-12');
+
define('AWCMOD_VERSION', '0.0.5, 2008-10-15');
  
 
$wgExtensionFunctions[] = 'wfSetupAWCmod';
 
$wgExtensionFunctions[] = 'wfSetupAWCmod';
Line 86: Line 86:
 
* Update the user object when the prefs from the form are saved
 
* Update the user object when the prefs from the form are saved
 
*/
 
*/
function onSavePreferences(&$form, &$user, &$error, &$options) {
+
function onSavePreferences(&$form, &$user) {
 
$this->setOptions($user);
 
$this->setOptions($user);
 
return true;
 
return true;
Line 124: Line 124:
 
*/
 
*/
 
function renderAWCprefs() {
 
function renderAWCprefs() {
global $wgOut, $wgHooks;
+
global $wgUser, $wgOut, $wgHooks;
 
include(dirname(__FILE__)."/states.php");
 
include(dirname(__FILE__)."/states.php");
 
$wgOut->addScript("<script type='text/javascript'>$awcJS</script>");
 
$wgOut->addScript("<script type='text/javascript'>$awcJS</script>");
 +
 +
# Build state options list
 +
$state  = $wgUser->getOption('state');
 
$stateOptions = '<option value="">Enter state...</option>';
 
$stateOptions = '<option value="">Enter state...</option>';
foreach (array_keys($awcStates) as $state) $stateOptions .= "<option>$state</option>\n";
+
foreach (array_keys($awcStates) as $s) {
 +
$selected = $state == $s ? ' selected' : '';
 +
$stateOptions .= "<option$selected>$s</option>\n";
 +
}
 +
 
 +
# Build county options list
 +
$county = $wgUser->getOption('county');
 +
$countyOptions = '<option value="">Enter county...</option>';
 +
if ($state) {
 +
foreach (split(',',$awcStates[$state]) as $c) {
 +
$c = substr($c, 1, -1);
 +
$selected = $county == $c ? ' selected' : '';
 +
$countyOptions .= "<option$selected>$c</option>\n";
 +
}
 +
}
 +
 
 
$html = "<div class=awc-loginprefs><table>" .
 
$html = "<div class=awc-loginprefs><table>" .
 
$this->addRow(
 
$this->addRow(
 
wfLabel('First Name', 'wpFirstName'),
 
wfLabel('First Name', 'wpFirstName'),
wfInput('wpFirstName', 20, '', array('id' => 'wpFirstName', 'onBlur' => 'awcValidate()')),
+
wfInput('wpFirstName', 20, $wgUser->getOption('firstname'), array('id' => 'wpFirstName', 'onBlur' => 'awcValidate()')),
 
'Required'
 
'Required'
 
) .
 
) .
 
$this->addRow(
 
$this->addRow(
 
wfLabel('Last Name', 'wpLastName'),
 
wfLabel('Last Name', 'wpLastName'),
wfInput('wpLastName', 20, '', array('id' => 'wpLastName', 'onBlur' => 'awcValidate()')),
+
wfInput('wpLastName', 20, $wgUser->getOption('lastname'), array('id' => 'wpLastName', 'onBlur' => 'awcValidate()')),
 
'Required'
 
'Required'
 
) .
 
) .
 
$this->addRow(
 
$this->addRow(
 
wfLabel('Voice Phone', 'wpPhone'),
 
wfLabel('Voice Phone', 'wpPhone'),
wfInput('wpPhone', 10, '', array('id' => 'wpPhone', 'onBlur' => 'awcValidate()')),
+
wfInput('wpPhone', 10, $wgUser->getOption('phone'), array('id' => 'wpPhone', 'onBlur' => 'awcValidate()')),
 
'Required'
 
'Required'
 
) .
 
) .
 
$this->addRow(
 
$this->addRow(
 
wfLabel('Mobile Phone', 'wpMobile'),
 
wfLabel('Mobile Phone', 'wpMobile'),
wfInput('wpMobile', 10, '', array('id' => 'wpMobile'))
+
wfInput('wpMobile', 10, $wgUser->getOption('mobile'), array('id' => 'wpMobile'))
 
) .
 
) .
 
$this->addRow(
 
$this->addRow(
 
wfLabel('Fax', 'wpFax'),
 
wfLabel('Fax', 'wpFax'),
wfInput('wpFax', 10, '', array('id' => 'wpFax'))
+
wfInput('wpFax', 10, $wgUser->getOption('fax'), array('id' => 'wpFax'))
 
) .
 
) .
 
$this->addRow(
 
$this->addRow(
 
wfLabel('Business', 'wpBusiness'),
 
wfLabel('Business', 'wpBusiness'),
wfInput('wpBusiness', 20, '', array('id' => 'wpBusiness', 'onBlur' => 'awcValidate()')),
+
wfInput('wpBusiness', 20, $wgUser->getOption('business'), array('id' => 'wpBusiness', 'onBlur' => 'awcValidate()')),
 
'Can be "none"'
 
'Can be "none"'
 
) .
 
) .
 
$this->addRow(
 
$this->addRow(
 
wfLabel('Website', 'wpWebsite'),
 
wfLabel('Website', 'wpWebsite'),
wfInput('wpWebsite', 20, '', array('id' => 'wpWebsite'))
+
wfInput('wpWebsite', 20, $wgUser->getOption('website'), array('id' => 'wpWebsite'))
 
) .
 
) .
 
$this->addRow(
 
$this->addRow(
 
wfLabel('Email', 'wpEmailAddress'),
 
wfLabel('Email', 'wpEmailAddress'),
wfInput('wpEmailAddress', 20, '', array('id' => 'wpEmailAddress', 'onBlur' => 'awcValidate()')),
+
wfInput('wpEmailAddress', 20, $wgUser->getEmail(), array('id' => 'wpEmailAddress', 'onBlur' => 'awcValidate()')),
 
'Required'
 
'Required'
 
) .
 
) .
 
$this->addRow(
 
$this->addRow(
 
wfLabel('Address', 'wpAddress'),
 
wfLabel('Address', 'wpAddress'),
wfInput('wpAddress', 20, '', array('id' => 'wpAddress', 'onBlur' => 'awcValidate()')),
+
wfInput('wpAddress', 20, $wgUser->getOption('address'), array('id' => 'wpAddress', 'onBlur' => 'awcValidate()')),
 
'Required'
 
'Required'
 
) .
 
) .
 
$this->addRow(
 
$this->addRow(
 
wfLabel('Address 2', 'wpAddress2'),
 
wfLabel('Address 2', 'wpAddress2'),
wfInput('wpAddress2', 20, '', array('id' => 'wpAddress2'))
+
wfInput('wpAddress2', 20, $wgUser->getOption('address2'), array('id' => 'wpAddress2'))
 
) .
 
) .
 
$this->addRow(
 
$this->addRow(
 
wfLabel('City', 'wpCity'),
 
wfLabel('City', 'wpCity'),
wfInput('wpCity', 20, '', array('id' => 'wpCity', 'onBlur' => 'awcValidate()')),
+
wfInput('wpCity', 20, $wgUser->getOption('city'), array('id' => 'wpCity', 'onBlur' => 'awcValidate()')),
 
'Required'
 
'Required'
 
) .
 
) .
Line 188: Line 206:
 
$this->addRow(
 
$this->addRow(
 
wfLabel('County', 'wpCounty'),
 
wfLabel('County', 'wpCounty'),
'<select name="wpCounty" id="wpCounty"><option>Enter county...</option></select>'
+
'<select name="wpCounty" id="wpCounty">'.$countyOptions.'</select>'
 
) .
 
) .
 
$this->addRow(
 
$this->addRow(
 
wfLabel('Zip Code', 'wpZipCode'),
 
wfLabel('Zip Code', 'wpZipCode'),
wfInput('wpZipCode', 10, '', array('id' => 'wpZipCode', 'onBlur' => 'awcValidate()')),
+
wfInput('wpZipCode', 10, $wgUser->getOption('zipcode'), array('id' => 'wpZipCode', 'onBlur' => 'awcValidate()')),
 
'Required'
 
'Required'
 
) .
 
) .
 
$this->addRow(
 
$this->addRow(
 
wfLabel('Logo', 'wpLogo'),
 
wfLabel('Logo', 'wpLogo'),
wfInput('wpLogo', 10, '', array('id' => 'wpLogo', 'type' => 'file'))
+
wfInput('wpLogo', 10, $wgUser->getOption('logo'), array('id' => 'wpLogo', 'type' => 'file'))
 
) . '</table></div>';
 
) . '</table></div>';
 
$html .= '<script type="text/javascript">awcAddValidation()</script>';
 
$html .= '<script type="text/javascript">awcAddValidation()</script>';

Revision as of 08:25, 15 October 2008

<?php /**

* AWC extension
*Template:Php
Info.svg These are the MediaWiki extensions we're using and/or developing. Please refer to the information on the mediawiki.org wiki for installation and usage details. Extensions here which have no corresponding mediawiki article are either not ready for use or have been superseded. You can also browse our extension code in our local Subversion repository or our GitHub mirror.
* @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.0.5, 2008-10-15');

$wgExtensionFunctions[] = 'wfSetupAWCmod'; $wgExtensionCredits['other'][] = array( 'name' => 'AWCmod', 'author' => 'User:Nad', 'description' => 'Custom extension for Adeft', 'url' => 'http://www.organicdesign.co.nz/Extension:AWCmod', 'version' => AWCMOD_VERSION );

  1. print_r($_REQUEST);
  2. Check if any awcpref parameters passed in request

$awcSearchByPref = array(); foreach ($_REQUEST as $k => $v) if (ereg('^awcsbp_(.+)$', $k, $m)) $awcSearchByPref[$m[1]] = $v;

  1. Process posted contact details

if (isset($_POST['wpFirstName'])) { $_POST['wpRealName'] = $_POST['wpFirstName'].' '.$_POST['wpLastName']; $_POST['wpUserEmail'] = $_POST['wpEmailAddress']; }

  1. Don't apply the db hook unless awcsearchprefs have been posted

if ($awcDBHook = count($awcSearchByPref) > 0) $_POST['fID'] = array('all');

  1. 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 $searchPrefs = array();

function __construct() { global $wgHooks, $wgMessageCache, $wgParser, $wgTitle, $awcSearchByPref;

$this->searchPrefs = $awcSearchByPref;

$wgHooks['RenderPreferencesForm'][] = $this; $wgHooks['UserCreateForm'][] = $this; $wgHooks['SavePreferences'][] = $this; $wgHooks['AbortNewAccount'][] = $this;

# Modify login form messages to say email and name compulsory

  1. $wgMessageCache->addMessages(array('prefs-help-email' => '
    Required
    '));
  2. $wgMessageCache->addMessages(array('prefs-help-realname' => '
    Required
    '));

# Add a tag for creating search links $wgParser->setHook('forum_search', array($this, 'searchTag')); }

/** * Add the new prefs to a new tab in the preferences form */ function onRenderPreferencesForm(&$form, &$out) { $out->addHTML('<fieldset><legend>Contact details</legend>'.$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('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')); }

/** * Return the HTML for the AWC preference inputs */ function renderAWCprefs() { global $wgUser, $wgOut, $wgHooks; include(dirname(__FILE__)."/states.php"); $wgOut->addScript("<script type='text/javascript'>$awcJS</script>");

# Build state options list $state = $wgUser->getOption('state'); $stateOptions = '<option value="">Enter state...</option>'; foreach (array_keys($awcStates) as $s) { $selected = $state == $s ? ' selected' : ; $stateOptions .= "<option$selected>$s</option>\n"; }

# Build county options list $county = $wgUser->getOption('county'); $countyOptions = '<option value="">Enter county...</option>'; if ($state) { foreach (split(',',$awcStates[$state]) as $c) { $c = substr($c, 1, -1); $selected = $county == $c ? ' selected' : ; $countyOptions .= "<option$selected>$c</option>\n"; } }

$html = "

" .

$this->addRow( wfLabel('First Name', 'wpFirstName'), wfInput('wpFirstName', 20, $wgUser->getOption('firstname'), array('id' => 'wpFirstName', 'onBlur' => 'awcValidate()')), 'Required' ) . $this->addRow( wfLabel('Last Name', 'wpLastName'), wfInput('wpLastName', 20, $wgUser->getOption('lastname'), array('id' => 'wpLastName', 'onBlur' => 'awcValidate()')), 'Required' ) . $this->addRow( wfLabel('Voice Phone', 'wpPhone'), wfInput('wpPhone', 10, $wgUser->getOption('phone'), array('id' => 'wpPhone', 'onBlur' => 'awcValidate()')), 'Required' ) . $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('Business', 'wpBusiness'), wfInput('wpBusiness', 20, $wgUser->getOption('business'), array('id' => 'wpBusiness', 'onBlur' => 'awcValidate()')), 'Can be "none"' ) . $this->addRow( wfLabel('Website', 'wpWebsite'), wfInput('wpWebsite', 20, $wgUser->getOption('website'), array('id' => 'wpWebsite')) ) . $this->addRow( wfLabel('Email', 'wpEmailAddress'), wfInput('wpEmailAddress', 20, $wgUser->getEmail(), array('id' => 'wpEmailAddress', 'onBlur' => 'awcValidate()')), 'Required' ) . $this->addRow( wfLabel('Address', 'wpAddress'), wfInput('wpAddress', 20, $wgUser->getOption('address'), array('id' => 'wpAddress', 'onBlur' => 'awcValidate()')), 'Required' ) . $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', 'onBlur' => 'awcValidate()')), 'Required' ) . $this->addRow( wfLabel('State', 'wpState'), '<select name="wpState" id="wpState" onchange="awcUpdateCounty(this.value)" onBlur = "awcValidate()">'.$stateOptions.'</select>', 'Required' ) . $this->addRow( wfLabel('County', 'wpCounty'), '<select name="wpCounty" id="wpCounty">'.$countyOptions.'</select>' ) . $this->addRow( wfLabel('Zip Code', 'wpZipCode'), wfInput('wpZipCode', 10, $wgUser->getOption('zipcode'), array('id' => 'wpZipCode', 'onBlur' => 'awcValidate()')), 'Required' ) . $this->addRow( wfLabel('Logo', 'wpLogo'), wfInput('wpLogo', 10, $wgUser->getOption('logo'), array('id' => 'wpLogo', 'type' => 'file'))

) . '

';

$html .= '<script type="text/javascript">awcAddValidation()</script>'; return $html; }

function addRow($td1, $td2, $td3 = ) {

return " $td1: $td2

$td3

"; } /** * Render a link to Special:AWCForum */ function searchTag($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; } /** * 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; } function wfSetupAWCmod() { global $wgAWCmod, $awcDBHook, $wgLanguageCode, $wgMessageCache, $wgLoadBalancer, $wgDBtype, $wgOldDBtype; # 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; } # Add messages if ($wgLanguageCode == 'en') { $wgMessageCache->addMessages(array( 'awc-prefhead' => "AWC" )); } }