Ferreteria/archive/menu.php: Difference between revisions
(2010-10-07 revision) |
(more reconciliation; latest version in use) |
||
Line 1: | Line 1: | ||
<php><?php | <php><?php | ||
/* | /* | ||
LIBRARY: menu.php - a few classes for managing menus | |||
HISTORY: | |||
2009-08-09 Extracted from SpecialVbzAdmin.php | |||
2009-11-04 clsArgs | |||
2010-02-20 clsWikiSection::SectionAdd(), ::ToggleAdd() | |||
2010-04-06 | |||
* General reconciliation with edited non-dev version | |||
* Done earlier but not logged here: | |||
clsWikiSection::ArgsToAdd() (ported from other copy of menu.php) | |||
clsAdminTable, clsAdminData, clsAdminData_Logged, clsAdminEvents, clsAdminEvent | |||
2010-06-17 StartEvent() / FinishEvent() now keep the event ID in $this->idEvent | |||
2010-10-06 | |||
Reconciling with dev: | |||
* Minor improvements; split() is deprecated; small bugfixes | |||
2010-10-07 reconstructed clsDataSet::_AdminLink(), which apparently got lost during reconciliation | |||
BUGS: | |||
2010-09-13 When there are multiple toggles, they don't preserve each other's states | |||
http://wiki.vbz.net/Special:VbzAdmin/page:order/id:4263/receipt -- "email" cancels out "receipt" | |||
*/ | */ | ||
//if (!function_exists('clsMenu::WikiText')) { | //if (!function_exists('clsMenu::WikiText')) { | ||
class clsMenu { | class clsMenu { | ||
Line 143: | Line 148: | ||
} | } | ||
// link-data functions | // link-data functions | ||
/*---- | |||
RETURNS: the part of the path *after* the specialpage name | |||
USED BY: SelfURL(), which is used by clsWikiSection:ActionAdd() | |||
*/ | |||
function SelfLink_Path(array $iData) { | function SelfLink_Path(array $iData) { | ||
$ | $fp = ''; | ||
foreach ($iData AS $key => $val) { | foreach ($iData AS $key => $val) { | ||
if ($val !== FALSE) { | if ($val !== FALSE) { | ||
if ($val === TRUE) { | if ($val === TRUE) { | ||
$ | $fp .= '/'.$key; | ||
} else { | } else { | ||
$ | $fp .= '/'.$key.KS_CHAR_URL_ASSIGN.$val; | ||
} | } | ||
} | } | ||
} | } | ||
$out = $fp; | |||
return $out; | return $out; | ||
} | } | ||
Line 164: | Line 174: | ||
} | } | ||
} | } | ||
/* 2010-10-01 NEED TO KNOW who uses this, so I can fix it | |||
function SelfLink_HTML(array $iData,$iShow,$iPopup=NULL) { | function SelfLink_HTML(array $iData,$iShow,$iPopup=NULL) { | ||
if (is_null($iShow)) { | if (is_null($iShow)) { | ||
Line 173: | Line 184: | ||
} | } | ||
} | } | ||
*/ | |||
//} | //} | ||
class SpecialPageApp extends SpecialPage { | class SpecialPageApp extends SpecialPage { | ||
Line 178: | Line 190: | ||
public function __construct($iName) { | public function __construct($iName) { | ||
//global $wgScriptPath; | |||
global $vgMWLibPfx; | |||
global $wgTitle,$wgUser; | global $wgTitle,$wgUser; | ||
global $vgPage,$vgUserName; | global $vgPage,$vgUserName; | ||
Line 185: | Line 199: | ||
$vgUserName = $wgUser->getName(); | $vgUserName = $wgUser->getName(); | ||
$objTitleMe = $this->getTitle(); | $objTitleMe = $this->getTitle(); | ||
// $vgMWLibPfx = empty($wgScriptPath)?'':($wgScriptPath.'/'); | |||
// $strFullName = $vgMWLibPfx.$objTitleMe->getPrefixedText(); | |||
$strFullName = $objTitleMe->getPrefixedText(); | $strFullName = $objTitleMe->getPrefixedText(); | ||
$this->objRT_HTML = new clsHTML($strFullName); | $this->objRT_HTML = new clsHTML($strFullName); | ||
Line 199: | Line 215: | ||
$vgOut = $this->objRT_Wiki; | $vgOut = $this->objRT_Wiki; | ||
} | } | ||
/* | |||
public function RichTextObj() { | public function RichTextObj() { | ||
return $vgOut; | return $vgOut; | ||
} | } | ||
*/ | |||
protected function GetArgs($par) { | protected function GetArgs($par) { | ||
Line 213: | Line 231: | ||
foreach($args_raw as $arg_raw) { | foreach($args_raw as $arg_raw) { | ||
if (strpos($arg_raw,KS_CHAR_URL_ASSIGN) !== FALSE) { | if (strpos($arg_raw,KS_CHAR_URL_ASSIGN) !== FALSE) { | ||
// list($key,$val) = split(KS_CHAR_URL_ASSIGN,$arg_raw); // split() is deprecated | |||
list($key,$val) = preg_split('/'.KS_CHAR_URL_ASSIGN.'/',$arg_raw); | list($key,$val) = preg_split('/'.KS_CHAR_URL_ASSIGN.'/',$arg_raw); | ||
$this->args[$key] = $val; | $this->args[$key] = $val; | ||
Line 222: | Line 240: | ||
} | } | ||
/*---- | /*---- | ||
RETURNS: | RETURNS: array of all arguments found in URL | ||
*/ | |||
public function Args() { | |||
return $this->args; | |||
} | |||
/*---- | |||
RETURNS: value of single specified argument from URL | |||
*/ | */ | ||
public function Arg($iName) { | public function Arg($iName) { | ||
Line 230: | Line 254: | ||
return FALSE; | return FALSE; | ||
} | } | ||
} | } | ||
/*===== | /*===== | ||
RETURNS: Just the path after the page name, not the whole wiki title | RETURNS: Just the path after the page name, not the whole wiki title | ||
USED BY: $this->SelfURL() | |||
*/ | */ | ||
private function SelfLink_Path(array $iAdd) { | private function SelfLink_Path(array $iAdd) { | ||
Line 249: | Line 268: | ||
/*===== | /*===== | ||
RETURNS: Relative path, ready for use in an href | RETURNS: Relative path, ready for use in an href | ||
USED BY: clsWikiSection:ActionAdd() | |||
*/ | */ | ||
public function SelfURL(array $iAdd=NULL,$iClear=FALSE) { | public function SelfURL(array $iAdd=NULL,$iClear=FALSE) { | ||
global $wgTitle | global $wgTitle; | ||
global $wgScriptPath; | |||
if (is_array($iAdd)) { | if (is_array($iAdd)) { | ||
Line 272: | Line 293: | ||
return $out; | return $out; | ||
} | } | ||
/* 2010-10-01 NEED TO KNOW who uses this, so I can fix it | |||
public function SelfLink_HTML(array $iAdd, $iShow, $iClear=FALSE, $iPopup=NULL) { | public function SelfLink_HTML(array $iAdd, $iShow, $iClear=FALSE, $iPopup=NULL) { | ||
$urlPath = $this->SelfURL($iAdd,$iClear); | $urlPath = $this->SelfURL($iAdd,$iClear); | ||
$htPopup = is_null($iPopup)?'':(' title="'.$iPopup.'"'); | $htPopup = is_null($iPopup)?'':(' title="'.$iPopup.'"'); | ||
$out = '<a href="'.$urlPath.'"'.$htPopup.'>'.$iShow.'</a>'; | $out = '<a href="'.$urlPath.'"'.$htPopup.'>'.$iShow.'</a>'; | ||
return $out; | |||
} | |||
*/ | |||
/*---- | |||
USED BY: VbzAdminOrder.DoSetup() | |||
*/ | |||
public function SelfLink(array $iAdd, $iShow) { | |||
global $vgOut; | |||
$arData = $this->args; | |||
foreach ($iAdd AS $key => $val) { | |||
$arData[$key] = $val; // override any matching keys | |||
} | |||
$out = $vgOut->SelfLink($arData,$iShow); | |||
return $out; | return $out; | ||
} | } | ||
Line 281: | Line 317: | ||
/*========== | /*========== | ||
DATA CLASSES | DATA CLASSES | ||
2010-10-04 Moved ActionKey() back into data.php, because it's useful for logging. | |||
No more need for this class; deprecated now. | |||
*/ | */ | ||
class clsAdminTable extends clsTable { | class clsAdminTable extends clsTable { | ||
/*---- | |||
USED BY: VbzAdmin::VbzAdminItems::AdminLink() | |||
HISTORY: | |||
Extricated from VbzAdmin::VbzAdminItems | |||
*/ | |||
public static function AdminLink($iID,$iShow=NULL,$iPopup=NULL) { | |||
global $vgOut; | |||
$id = $iID; | |||
$arLink = array( | |||
'page' => 'item', | |||
'id' => $id); | |||
$strShow = is_null($iShow)?($id):$iShow; | |||
$strPopup = is_null($iPopup)?('view item ID '.$id):$iPopup; | |||
$out = $vgOut->SelfLink($arLink,$strShow,$strPopup); | |||
return $out; | |||
} | |||
/* | |||
public function ActionKey($iName=NULL) { | public function ActionKey($iName=NULL) { | ||
if (!is_null($iName)) { | if (!is_null($iName)) { | ||
Line 289: | Line 346: | ||
return $this->ActionKey; | return $this->ActionKey; | ||
} | } | ||
*/ | |||
} | } | ||
class clsAdminData extends clsDataSet { | class clsAdminData extends clsDataSet { | ||
/ | /*==== | ||
// | SECTION: static versions of dynamic functions | ||
public | PURPOSE: for classes which inherit from non-Admin classes (fake multiple inheritance) | ||
*/ | |||
/*---- | |||
USED BY: VbzAdmin::clsAdminTopic::AdminLink() | |||
HISTORY: | |||
2010-10-06 Wasn't sure who is using this, so commented it out (not WorkFerret or AudioFerret) | |||
VbzAdmin didn't *seem* to be using it... | |||
2010-10-13 Found that VbzAdmin uses it | |||
*/ | |||
static public function _AdminLink(clsDataSet $iObj, $iText=NULL,$iPopup=NULL,array $iarArgs=NULL) { | |||
global $vgOut; | global $vgOut; | ||
$txtShow = is_null($iText)?($ | $txtShow = is_null($iText)?($iObj->ID):$iText; | ||
if (isset($ | if (isset($iObj->Table->ActionKey)) { | ||
$strKey = $ | $strKey = $iObj->Table->ActionKey; | ||
} else { | } else { | ||
$strKey = $ | $strKey = $iObj->Table->Name(); | ||
} | } | ||
$arLink = array( | $arLink = array( | ||
'page' => $strKey, | 'page' => $strKey, | ||
'id' => $ | 'id' => $iObj->KeyValue()); | ||
if (is_array($iarArgs)) { // 2010-06-25 This has not been tested -- maybe it's not useful? | |||
if ( | $arLink = array_merge($arLink,$iarArgs); | ||
$ | |||
} | } | ||
$out = $vgOut->SelfLink($arLink,$txtShow,$iPopup); | $out = $vgOut->SelfLink($arLink,$txtShow,$iPopup); | ||
return $out; | return $out; | ||
*/ | } | ||
/*==== | |||
SECTION: normal dynamic functions | |||
*/ | |||
/*---- | |||
USED BY: VbzAdmin::VbzAdminStkItems::Listing_forItem() | |||
HISTORY: | |||
2010-10-06 Disabled, because it wasn't clear if anyone was using it. | |||
Thought I checked VbzAdmin, WorkFerret, and AudioFerret | |||
2010-10-13 VbzAdmin::VbzAdminStkItems::Listing_forItem() calls it | |||
*/ | |||
public function AdminLink($iText=NULL,$iPopup=NULL,array $iarArgs=NULL) { | |||
return self::_AdminLink($this,$iText,$iPopup,$iarArgs); | |||
} | } | ||
} | } | ||
abstract class clsAdminData_Logged extends clsAdminData { | abstract class clsAdminData_Logged extends clsAdminData { | ||
protected $idEvent; | |||
abstract protected function Events(); // RETURNS a clsAdminEvents object | abstract protected function Events(); // RETURNS a clsAdminEvents object | ||
/*===== | |||
INPUT: Array containing any of the following elements: | |||
'descr': description of event | |||
'where': location in code where event is taking place (usually __METHOD__ will do) | |||
'code': event code unique to type | |||
'error' (value ignored): if present, event represents an error | |||
'severe' (value ignored): if present, event represents a severe error | |||
*/ | |||
public function StartEvent(array $iarArgs) { | public function StartEvent(array $iarArgs) { | ||
$arArgs = $iarArgs; | $arArgs = $iarArgs; | ||
$arArgs['type'] = $this->Table->ActionKey; | $arArgs['type'] = $this->Table->ActionKey; // TO DO: de-couple this from URL keys | ||
$arArgs['id'] = $this->KeyValue(); | $arArgs['id'] = $this->KeyValue(); | ||
$this->idEvent = $this->Events()->StartEvent($arArgs); | |||
return $this->idEvent; | |||
} | } | ||
public function FinishEvent( | public function FinishEvent(array $iarArgs=NULL) { | ||
$this->Events()->FinishEvent($ | $this->Events()->FinishEvent($this->idEvent,$iarArgs); | ||
unset($this->idEvent); | |||
} | } | ||
} | } | ||
Line 349: | Line 423: | ||
This was written to work with FinanceFerret, but should be compatible with standard event tables. | This was written to work with FinanceFerret, but should be compatible with standard event tables. | ||
Any app-specific code should be moved out into descendant classes. | Any app-specific code should be moved out into descendant classes. | ||
*/ | |||
/*===== | |||
CLASS: clsAdminEvents | |||
PURPOSE: Event log table | |||
*/ | */ | ||
class clsAdminEvents extends clsAdminTable { | class clsAdminEvents extends clsAdminTable { | ||
Line 440: | Line 518: | ||
$arIns['WhoNetwork'] = SQLValue($_SERVER['REMOTE_ADDR']); | $arIns['WhoNetwork'] = SQLValue($_SERVER['REMOTE_ADDR']); | ||
$arIns['WhoAdmin'] = SQLValue($vgUserName); | $arIns['WhoAdmin'] = SQLValue($vgUserName); | ||
$ok = $this->Insert($arIns); | $ok = $this->Insert($arIns); | ||
if ($ok) { | if ($ok) { | ||
Line 459: | Line 536: | ||
} | } | ||
class clsAdminEvent extends clsAdminData { | class clsAdminEvent extends clsAdminData { | ||
/* | /* | ||
ASSUMES: there are rows (caller should check this) | ASSUMES: there are rows (caller should check this) | ||
*/ | */ | ||
Line 572: | Line 649: | ||
return $arOut; | return $arOut; | ||
} | } | ||
public function SelfArray() { | public function SelfArray() { | ||
$objPage = $this->objFmt->Page(); | $objPage = $this->objFmt->Page(); | ||
Line 590: | Line 664: | ||
return $wpPath; | return $wpPath; | ||
} | } | ||
/*----- | |||
PURPOSE: Add an action link to the menu | |||
*/ | |||
public function ActionAdd($iDisp,$iPopup=NULL,$iActive=NULL,$iKey=NULL,$iIsDefault=FALSE) { | public function ActionAdd($iDisp,$iPopup=NULL,$iActive=NULL,$iKey=NULL,$iIsDefault=FALSE) { | ||
$strPopup = is_null($iPopup)?($iDisp.' '.$this->strDescr):$iPopup; | $strPopup = is_null($iPopup)?($iDisp.' '.$this->strDescr):$iPopup; | ||
Line 599: | Line 676: | ||
$arLink['do'] = $strKey; | $arLink['do'] = $strKey; | ||
$arLink = $this->ArrayCheck($arLink); | $arLink = $this->ArrayCheck($arLink); | ||
// $wpPath = 'BLARG!'.$objPage->SelfURL($arLink,TRUE); | |||
$isActive = is_null($iActive)?($objPage->Arg('do')==$strKey):$iActive; | $isActive = is_null($iActive)?($objPage->Arg('do')==$strKey):$iActive; | ||
$arEntry = array( | $arEntry = array( | ||
'type' => 'action', | 'type' => 'action', | ||
'path' => $wpPath | 'path' => 'BLARG!', // was; $wpPath -- WHAT USES THIS? | ||
'popup' => $strPopup, | 'popup' => $strPopup, | ||
'displ' => $iDisp, | 'displ' => $iDisp, |
Revision as of 11:52, 14 October 2010
<php><?php /*
LIBRARY: menu.php - a few classes for managing menus HISTORY: 2009-08-09 Extracted from SpecialVbzAdmin.php 2009-11-04 clsArgs 2010-02-20 clsWikiSection::SectionAdd(), ::ToggleAdd() 2010-04-06 * General reconciliation with edited non-dev version * Done earlier but not logged here: clsWikiSection::ArgsToAdd() (ported from other copy of menu.php) clsAdminTable, clsAdminData, clsAdminData_Logged, clsAdminEvents, clsAdminEvent 2010-06-17 StartEvent() / FinishEvent() now keep the event ID in $this->idEvent 2010-10-06 Reconciling with dev: * Minor improvements; split() is deprecated; small bugfixes 2010-10-07 reconstructed clsDataSet::_AdminLink(), which apparently got lost during reconciliation BUGS: 2010-09-13 When there are multiple toggles, they don't preserve each other's states http://wiki.vbz.net/Special:VbzAdmin/page:order/id:4263/receipt -- "email" cancels out "receipt"
- /
//if (!function_exists('clsMenu::WikiText')) { class clsMenu {
public $Page; private $SubNodes; private $AllNodes; protected $Action; protected $Selected;
public function __construct($iWikiPage) { $this->Page = $iWikiPage; } public function WikiText($iAction) { $this->Action = $iAction; if (isset($this->AllNodes[$iAction])) { $this->AllNodes[$iAction]->Activate(); } $out = $this->WikiText_SubMenu($iAction); return $out; } public function WikiText_SubMenu($iAction) { $out = NULL; foreach ($this->SubNodes as $objNode) { if (!is_null($out)) { $out .= ' | '; } $out .= $objNode->WikiText($iAction); } return $out; } public function Add(clsMenuNode $iNode) { $this->SubNodes[$iNode->Name] = $iNode; $this->Root()->AllNodes[$iNode->Name] = $iNode; $iNode->Parent = $this; } protected function Root() { return $this; } protected function Activate() { } // do nothing public function Execute() { if (isset($this->Selected)) { $out = $this->Selected->DoAction(); } else { $out = NULL; } return $out; }
}
abstract class clsMenuNode extends clsMenu {
public $Name; protected $Text; protected $DoSpec; public $Parent; protected $IsActive;
public function __construct($iText, $iDo) { $this->Name = $iDo; $this->Text = $iText; $this->DoSpec = $iDo; } public function Root() { return $this->Parent->Root(); } abstract public function DoAction(); protected function Activate() { $this->IsActive = TRUE; $this->Parent->Activate(); } public function WikiText($iAction) { $wtSelf = $this->Root()->Page; $wtItem = "[[$wtSelf/page".KS_CHAR_URL_ASSIGN."{$this->DoSpec}|{$this->Text}]]";
// if ($iAction == $this->DoSpec) {
if ($this->IsActive) { $out = "$wtItem"; $this->Root()->Selected = $this; } else { $out = $wtItem; } return $out; }
}
class clsMenuRow extends clsMenuNode {
public function DoAction() { $out = "
{$this->Text}: "; $out .= $this->WikiText_SubMenu($this->Root()->Action); return $out; }
}
class clsMenuItem extends clsMenuNode {
public function DoAction() {
// later: actually implement menu item action
}
}
// A way of passing a variable number of options to a function // Possibly this should be in a separate library // 2010-02-20 ok, this is kind of stupid; just the usual array syntax is simple enough. Is any code using this? // Currently ruling out SpecialVbzAdmin...
class clsArgs {
private $arArgs;
public function __construct(array $iPairs=NULL) { if (!is_null($iPairs)) { foreach ($iPairs as $key=>$val) { $this->Add($key,$val); } } }
public function Add($iName, $iValue=NULL) { $this->arArgs[$iName] = $iValue; } public function Value($iName, $iValue=NULL) { if (!is_null($iValue)) { $this->arArgs[$iName] = $iValue; } if (isset($this->arArgs[$iName])) { return $this->arArgs[$iName]; } else { return NULL; } }
} // link-data functions /*----
RETURNS: the part of the path *after* the specialpage name USED BY: SelfURL(), which is used by clsWikiSection:ActionAdd()
- /
function SelfLink_Path(array $iData) {
$fp = ; foreach ($iData AS $key => $val) { if ($val !== FALSE) { if ($val === TRUE) { $fp .= '/'.$key; } else { $fp .= '/'.$key.KS_CHAR_URL_ASSIGN.$val; } } } $out = $fp; return $out;
} function SelfLink_WT(array $iData,$iShow) {
if (is_null($iShow)) { return NULL; } else { $strPath = SelfLink_Path($iData); return ''.$iShow.''; }
} /* 2010-10-01 NEED TO KNOW who uses this, so I can fix it function SelfLink_HTML(array $iData,$iShow,$iPopup=NULL) {
if (is_null($iShow)) { return NULL; } else { $strPath = SelfLink_Path($iData); $htPopup = is_null($iPopup)?:(' title="'.$iPopup.'"'); return '<a href="'.$strPath.'"'.$htPopup.'>'.$iShow.'</a>'; }
}
- /
//} class SpecialPageApp extends SpecialPage {
protected $objRT_HTML,$objRT_Wiki;
public function __construct($iName) { //global $wgScriptPath; global $vgMWLibPfx; global $wgTitle,$wgUser; global $vgPage,$vgUserName;
parent::__construct($iName); $vgPage = $this; $vgUserName = $wgUser->getName(); $objTitleMe = $this->getTitle();
// $vgMWLibPfx = empty($wgScriptPath)?:($wgScriptPath.'/'); // $strFullName = $vgMWLibPfx.$objTitleMe->getPrefixedText();
$strFullName = $objTitleMe->getPrefixedText(); $this->objRT_HTML = new clsHTML($strFullName); $this->objRT_Wiki = new clsWikiText($strFullName); } public function UseHTML() { global $vgOut;
$vgOut = $this->objRT_HTML; } public function UseWiki() { global $vgOut;
$vgOut = $this->objRT_Wiki; }
/*
public function RichTextObj() { return $vgOut; }
- /
protected function GetArgs($par) {
/*
PURPOSE: Parses variable arguments from the URL The URL is formatted as a series of arguments /arg=val/arg=val/..., so that we can always refer directly to any particular item as a wiki page title while also not worrying about hierarchy/order.
- /
// $args_raw = split('/',$par); // split() is deprecated
$args_raw = preg_split('/\//',$par); foreach($args_raw as $arg_raw) { if (strpos($arg_raw,KS_CHAR_URL_ASSIGN) !== FALSE) {
// list($key,$val) = split(KS_CHAR_URL_ASSIGN,$arg_raw); // split() is deprecated
list($key,$val) = preg_split('/'.KS_CHAR_URL_ASSIGN.'/',$arg_raw); $this->args[$key] = $val; } else { $this->args[$arg_raw] = TRUE; } } } /*---- RETURNS: array of all arguments found in URL */ public function Args() { return $this->args; } /*---- RETURNS: value of single specified argument from URL */ public function Arg($iName) { if (isset($this->args[$iName])) { return $this->args[$iName]; } else { return FALSE; } } /*===== RETURNS: Just the path after the page name, not the whole wiki title USED BY: $this->SelfURL() */ private function SelfLink_Path(array $iAdd) { $arData = $this->args; foreach ($iAdd AS $key => $val) { $arData[$key] = $val; // override any matching keys } return SelfLink_Path($arData); } /*===== RETURNS: Relative path, ready for use in an href USED BY: clsWikiSection:ActionAdd() */ public function SelfURL(array $iAdd=NULL,$iClear=FALSE) { global $wgTitle; global $wgScriptPath;
if (is_array($iAdd)) { if ($iClear) { $strPath = SelfLink_Path($iAdd); } else { $strPath = $this->SelfLink_Path($iAdd); } } else { $strPath = ; } return $wgScriptPath.'/'.$wgTitle->getPrefixedText().$strPath; } public function SelfLink_WT(array $iAdd, $iShow) { $arData = $this->args; foreach ($iAdd AS $key => $val) { $arData[$key] = $val; // override any matching keys } $out = SelfLink_WT($arData,$iShow); return $out; }
/* 2010-10-01 NEED TO KNOW who uses this, so I can fix it
public function SelfLink_HTML(array $iAdd, $iShow, $iClear=FALSE, $iPopup=NULL) { $urlPath = $this->SelfURL($iAdd,$iClear); $htPopup = is_null($iPopup)?:(' title="'.$iPopup.'"'); $out = '<a href="'.$urlPath.'"'.$htPopup.'>'.$iShow.'</a>'; return $out; }
- /
/*---- USED BY: VbzAdminOrder.DoSetup() */ public function SelfLink(array $iAdd, $iShow) { global $vgOut;
$arData = $this->args; foreach ($iAdd AS $key => $val) { $arData[$key] = $val; // override any matching keys } $out = $vgOut->SelfLink($arData,$iShow); return $out; }
} /*==========
DATA CLASSES 2010-10-04 Moved ActionKey() back into data.php, because it's useful for logging. No more need for this class; deprecated now.
- /
class clsAdminTable extends clsTable {
/*---- USED BY: VbzAdmin::VbzAdminItems::AdminLink() HISTORY: Extricated from VbzAdmin::VbzAdminItems */ public static function AdminLink($iID,$iShow=NULL,$iPopup=NULL) { global $vgOut;
$id = $iID;
$arLink = array( 'page' => 'item', 'id' => $id); $strShow = is_null($iShow)?($id):$iShow; $strPopup = is_null($iPopup)?('view item ID '.$id):$iPopup; $out = $vgOut->SelfLink($arLink,$strShow,$strPopup); return $out; }
/*
public function ActionKey($iName=NULL) { if (!is_null($iName)) { $this->ActionKey = $iName; } return $this->ActionKey; }
- /
} class clsAdminData extends clsDataSet {
/*==== SECTION: static versions of dynamic functions PURPOSE: for classes which inherit from non-Admin classes (fake multiple inheritance) */ /*---- USED BY: VbzAdmin::clsAdminTopic::AdminLink() HISTORY: 2010-10-06 Wasn't sure who is using this, so commented it out (not WorkFerret or AudioFerret) VbzAdmin didn't *seem* to be using it... 2010-10-13 Found that VbzAdmin uses it */ static public function _AdminLink(clsDataSet $iObj, $iText=NULL,$iPopup=NULL,array $iarArgs=NULL) { global $vgOut;
$txtShow = is_null($iText)?($iObj->ID):$iText; if (isset($iObj->Table->ActionKey)) { $strKey = $iObj->Table->ActionKey; } else { $strKey = $iObj->Table->Name(); }
$arLink = array( 'page' => $strKey, 'id' => $iObj->KeyValue());
if (is_array($iarArgs)) { // 2010-06-25 This has not been tested -- maybe it's not useful? $arLink = array_merge($arLink,$iarArgs); }
$out = $vgOut->SelfLink($arLink,$txtShow,$iPopup); return $out; } /*==== SECTION: normal dynamic functions */ /*---- USED BY: VbzAdmin::VbzAdminStkItems::Listing_forItem() HISTORY: 2010-10-06 Disabled, because it wasn't clear if anyone was using it. Thought I checked VbzAdmin, WorkFerret, and AudioFerret 2010-10-13 VbzAdmin::VbzAdminStkItems::Listing_forItem() calls it */ public function AdminLink($iText=NULL,$iPopup=NULL,array $iarArgs=NULL) { return self::_AdminLink($this,$iText,$iPopup,$iarArgs); }
} abstract class clsAdminData_Logged extends clsAdminData {
protected $idEvent;
abstract protected function Events(); // RETURNS a clsAdminEvents object /*===== INPUT: Array containing any of the following elements: 'descr': description of event 'where': location in code where event is taking place (usually __METHOD__ will do) 'code': event code unique to type 'error' (value ignored): if present, event represents an error 'severe' (value ignored): if present, event represents a severe error */ public function StartEvent(array $iarArgs) { $arArgs = $iarArgs; $arArgs['type'] = $this->Table->ActionKey; // TO DO: de-couple this from URL keys $arArgs['id'] = $this->KeyValue(); $this->idEvent = $this->Events()->StartEvent($arArgs); return $this->idEvent; } public function FinishEvent(array $iarArgs=NULL) { $this->Events()->FinishEvent($this->idEvent,$iarArgs); unset($this->idEvent); }
} /*==========
EVENT LOGGING This was written to work with FinanceFerret, but should be compatible with standard event tables. Any app-specific code should be moved out into descendant classes.
- /
/*=====
CLASS: clsAdminEvents PURPOSE: Event log table
- /
class clsAdminEvents extends clsAdminTable {
public function __construct($iDB) { assert('is_object($iDB)'); // these defaults are all overridable - must match actual event table schema parent::__construct($iDB); $this->Name('event'); $this->KeyName('ID'); $this->ClassSng('clsAdminEvent'); // override parent $this->ActionKey('event'); } public function ListPage() { global $wgOut;
$objRow = $this->GetData(NULL,NULL,'ID DESC'); if ($objRow->hasRows()) { $out = $objRow->AdminRows(); } else { $out = 'No events logged yet.'; } $wgOut->addWikiText($out,TRUE); } /*----- RETURNS: event arguments translated into field names for use in Insert() NOTE: Shouldn't this method be static? */ private function CalcSQL($iArgs) { if (is_null($iArgs)) { return NULL; } else { foreach ($iArgs as $key=>$val) { switch ($key) { case 'descr': $sqlKey = 'Descr'; $sqlVal = SQLValue($val); break; case 'notes': $sqlKey = 'Notes'; $sqlVal = SQLValue($val); break; case 'type': $sqlKey = 'ModType'; $sqlVal = SQLValue($val); break; case 'id': $sqlKey = 'ModIndex'; $sqlVal = SQLValue($val); // can be NULL break; case 'where': $sqlKey = 'EvWhere'; $sqlVal = SQLValue($val); break; case 'code': $sqlKey = 'Code'; $sqlVal = SQLValue($val); break; case 'error': $sqlKey = 'isError'; $sqlVal = SQLValue($val); break; case 'severe': $sqlKey = 'isSevere'; $sqlVal = SQLValue($val); break; } $arIns[$sqlKey] = $sqlVal; } return $arIns; } } /*----- ACTION: Logs an event from specs in an array INPUT: Array containing any of the following elements: 'descr': description of event 'type': type of event (one of the kType* class constants) 'id': ID of row in table corresponding to event type 'where': location in code where event is taking place (usually __METHOD__ will do) 'code': event code unique to type 'error' (value ignored): if present, event represents an error 'severe' (value ignored): if present, event represents a severe error */ public function StartEvent(array $iArgs) { global $vgUserName;
$arIns = $this->CalcSQL($iArgs); if (empty($arIns)) { return NULL; } else { $arIns['WhenStarted'] = 'NOW()'; $arIns['WhoNetwork'] = SQLValue($_SERVER['REMOTE_ADDR']); $arIns['WhoAdmin'] = SQLValue($vgUserName); $ok = $this->Insert($arIns); if ($ok) { return $this->objDB->NewID(__METHOD__); } else { return NULL; } } } public function FinishEvent($iEvent,array $iArgs=NULL) { if (is_array($iArgs)) { $arUpd = $this->CalcSQL($iArgs); //$arUpd = array_merge($arUpd,$iArgs); } $arUpd['WhenFinished'] = 'NOW()'; $this->Update($arUpd,'ID='.$iEvent); }
} class clsAdminEvent extends clsAdminData {
/*
ASSUMES: there are rows (caller should check this)
*/
public function AdminRows() {
$htUnknown = '?';
$out = "{|";
$out .= "\n|-\n! ID || Start || Finish || Who/How || Where";
// $out .= "\n|-\n! || colspan=5 | Description";
$isOdd = TRUE; $strDateLast = NULL; $objRow = $this; while ($objRow->NextRow()) { $wtStyle = $isOdd?'background:#ffffff;':'background:#eeeeee;'; $isOdd = !$isOdd;
$row = $objRow->Row;
$strSysUser = $row['WhoAdmin']; $strVbzUser = $row['WhoSystem']; $strMachine = $row['WhoNetwork']; $htSysUser = is_null($strSysUser)?$htUnknown:$strSysUser; $htMachine = is_null($strMachine)?$htUnknown:$strMachine; $htVbzUser = is_null($strVbzUser)?$htUnknown:$strVbzUser;
$ftDescr = $row['Descr']; $strNotes = $row['Notes'];
$id = $row['ID']; $strWhenSt = $row['WhenStarted']; $strWhenFi = $row['WhenFinished']; $strWhere = $row['EvWhere']; $htWho = $htVbzUser.'/'.$htSysUser.'@'.$htMachine; $strParams = $row['Params'];
$dtWhenSt = strtotime($strWhenSt); $dtWhenFi = strtotime($strWhenFi); $strDate = date('Y-m-d',empty($dtWhenSt)?$dtWhenFi:$dtWhenSt); $strTimeSt = empty($dtWhenSt)?:date('H:i',$dtWhenSt); $strTimeFi = empty($dtWhenFi)?:date('H:i',$dtWhenFi); if ($strDate != $strDateLast) { $strDateLast = $strDate; $out .= "\n|- style=\"background: #444466; color: #ffffff;\"\n| colspan=5 | $strDate"; } $out .= "\n|- style=\"$wtStyle\""; $out .= "\n| $id || $strTimeSt || $strTimeFi || $htWho || $strWhere"; if (!empty($ftDescr)) { $out .= "\n|- style=\"$wtStyle\""; $out .= "\n| || colspan=5 | What: $ftDescr"; } if (!empty($strParams)) { $out .= "\n|- style=\"$wtStyle\""; $out .= "\n| || colspan=5 | Params: $strParams"; } if (!empty($strNotes)) { $out .= "\n|- style=\"$wtStyle\""; $out .= "\n| || colspan=5 | Notes: $strNotes"; } } $out .= "\n|}"; return $out; }
}
/*========== | FORM CLASSES | Trying not to be too ambitious at first, but eventually could be separate library file
- /
class clsWikiFormatter {
private $mwoPage;
public function __construct(SpecialPageApp $iPage) { $this->mwoPage = $iPage; } public function Page() { return $this->mwoPage; }
} class clsWikiSection {
// STATIC public static $arKeepDefault = array('page','id');
// DYNAMIC private $strName; // short name for header text private $strDescr; // longer description for popups private $intLevel; // level of header; defaults to 2 private $objFmt; // page-formatter object private $arMenu; // menu entries private $arKeep; // arguments to preserve (in every menu item) from the current page private $arAdd; // arguments to add to every menu item
public function __construct(clsWikiFormatter $iFmt,$iName,$iDescr=NULL,$iLevel=2,array $iMenu=NULL) { $this->objFmt = $iFmt; $this->strName = $iName; $this->strDescr = is_null($iDescr)?$iName:$iDescr; $this->intLevel = $iLevel; $this->arMenu = $iMenu; $this->arKeep = self::$arKeepDefault; } public function ArgsToKeep(array $iKeep) { $this->arKeep = $iKeep; } public function ArgsToAdd(array $iAdd) { $this->arAdd = $iAdd; } protected function ArrayCheck(array $iarCheck) { if (is_array($this->arAdd)) { $arOut = array_unique(array_merge($iarCheck,$this->arAdd)); } else { $arOut = $iarCheck; } return $arOut; } public function SelfArray() { $objPage = $this->objFmt->Page(); if (is_array($this->arKeep)) { foreach ($this->arKeep as $key) { $arLink[$key] = $objPage->Arg($key); } } return $this->ArrayCheck($arLink); } public function SelfURL() { $arLink = $this->SelfArray(); $objPage = $this->objFmt->Page(); $wpPath = $objPage->SelfURL($arLink,TRUE); return $wpPath; } /*----- PURPOSE: Add an action link to the menu */ public function ActionAdd($iDisp,$iPopup=NULL,$iActive=NULL,$iKey=NULL,$iIsDefault=FALSE) { $strPopup = is_null($iPopup)?($iDisp.' '.$this->strDescr):$iPopup;
$objPage = $this->objFmt->Page(); $arLink = $this->ArrayCheck($this->SelfArray());
$strKey = is_null($iKey)?$iDisp:$iKey; $arLink['do'] = $strKey; $arLink = $this->ArrayCheck($arLink);
// $wpPath = 'BLARG!'.$objPage->SelfURL($arLink,TRUE);
$isActive = is_null($iActive)?($objPage->Arg('do')==$strKey):$iActive;
$arEntry = array( 'type' => 'action', 'path' => 'BLARG!', // was; $wpPath -- WHAT USES THIS? 'popup' => $strPopup, 'displ' => $iDisp, 'active' => $isActive, 'isdef' => $iIsDefault ); $this->arMenu[] = $arEntry; } public function SectionAdd($iDisp) { $arEntry = array( 'type' => 'section', 'displ' => $iDisp ); $this->arMenu[] = $arEntry; } public function ToggleAdd($iDisp,$iPopup=NULL,$iKey=NULL) { $strPopup = is_null($iPopup)?($iDisp.' '.$this->strDescr):$iPopup; $strKey = is_null($iKey)?$iDisp:$iKey;
$objPage = $this->objFmt->Page(); $arLink = $this->SelfArray();
$isActive = $objPage->Arg($strKey); // active state is indicated by presence of key $arLink[$strKey] = !$isActive; $arLink = $this->ArrayCheck($arLink); $wpPath = $objPage->SelfURL($arLink,TRUE);
$arEntry = array( 'type' => 'toggle', 'path' => $wpPath, 'popup' => $strPopup, 'displ' => $iDisp, 'active' => $isActive ); $this->arMenu[] = $arEntry; } public function Generate() { $out = '<h'.$this->intLevel.'>'; if (is_array($this->arMenu)) { $arMenu = array_reverse($this->arMenu); // right-alignment reverses things foreach ($arMenu as $arLink) { $strType = $arLink['type']; switch ($strType) { case 'action': $htPath = $arLink['path']; $htPopup = $arLink['popup']; $htDispl = $arLink['displ']; $isActive = !empty($arLink['active']) || $arLink['isdef']; $htFmtOpen = $isActive?'':; $htFmtShut = $isActive?'':; $out .= ''; $out .= $htFmtOpen.'['; $out .= '<a href="'.$htPath.'" title="'.$htPopup.'">'.$htDispl.'</a>'; $out .= ']'.$htFmtShut; $out .= ''; break; case 'toggle': $htPath = $arLink['path']; $htPopup = $arLink['popup']; $htDispl = $arLink['displ']; $isActive = !empty($arLink['active']); $htFmtOpen = $isActive?'':; $htFmtShut = $isActive?'':; $out .= ''; $out .= $htFmtOpen.'['; $out .= '<a href="'.$htPath.'" title="'.$htPopup.'">'.$htDispl.'</a>'; $out .= ']'.$htFmtShut; $out .= ''; break; case 'section': $htDispl = $arLink['displ']; $out .= ''; $out .= '| '.$htDispl.':'; $out .= ''; break; } } } $out .= ''.$this->strName.'</h'.$this->intLevel.'>'; return $out; } public function FormOpen() { $out = '<form method=post action="'.$this->SelfURL().'">'; return $out; }
}
// This class is DEPRECATED; replacing with clsWikiFormatter / clsWikiSection class clsWikiAdminSection {
private $strTitle; private $strDescr; private $doEdit; private $arKeep; //private $htPath; public static $arKeepDefault = array('page','id');
public function __construct($iTitle, $iDescr=NULL, array $iKeep=NULL) { global $vgPage;
$this->strTitle = $iTitle; $this->strDescr = is_null($iDescr)?$iTitle:$iDescr; $this->arKeep = is_null($iKeep)?(self::$arKeepDefault):$iKeep; $this->doEdit = $vgPage->Arg('edit'); //$this->htPath = $vgPage->SelfURL(array('edit'=>!$this->doEdit)); $this->htPath = $vgPage->SelfURL(); } public function HeaderHtml(array $iMenu=NULL) {
$out = '
'; if (is_array($iMenu)) { foreach ($iMenu as $arLink) { $htPath = $arLink['path']; $htPopup = $arLink['popup']; $htDispl = $arLink['displ']; $isActive = !empty($arLink['active']); $out .= ''; if ($isActive) { $out .= ''; } $out .= '['; if ($isActive) { $out .= ''; } $out .= '<a href="'.$htPath.'" title="'.$htPopup.'">'.$htDispl.'</a>'; if ($isActive) { $out .= ''; } $out .= ']'; if ($isActive) { $out .= ''; } $out .= ' '; } } else { $out = ; } $out .= ''.$this->strTitle.'
';
return $out; } public function HeaderHtml_OLD() {
$out = '
'; if (!$this->doEdit) { $out .= '[<a href="'.$this->htPath.'" title="Edit '.$this->strDescr.'">edit</a>] '; } $out .= ''.$this->strTitle.'
';
return $out; } public function HeaderHtml_Edit(array $iMenu=NULL) { global $vgPage;
if (is_array($this->arKeep)) { foreach ($this->arKeep as $key) { $arLink[$key] = $vgPage->Arg($key); } }
$arLink['edit'] = TRUE; $wpPathEd = $vgPage->SelfURL($arLink,TRUE);
$arLink['edit'] = FALSE; $wpPathVw = $vgPage->SelfURL($arLink,TRUE);
// generate standard part of menu: $arMenu = array( array( 'path' => $wpPathEd, 'popup' => 'edit '.$this->strDescr, 'displ' => 'edit', 'active' => $this->doEdit), array( 'path' => $wpPathVw, 'popup' => 'view '.$this->strDescr, 'displ' => 'view', 'active' => !$this->doEdit));
if (is_array($iMenu)) { $arMenu = array_merge($arMenu,$iMenu); // append passed menu }
return $this->HeaderHtml($arMenu); } public function FormOpen() { if ($this->doEdit) { $out = '<form method=post action="'.$this->htPath.'">'; } else { $out = NULL; } return $out; }
} // TABBED CONTENTS /*
NOTES: There's probably a better way of doing this (e.g. using the same code used by the User Preferences page), but for now this uses the Tabber extension.
- /
function TabsOpen() {
global $wgScriptPath,$wgOut;
$path = $wgScriptPath . '/extensions/tabber/'; $htmlHeader = '<script type="text/javascript" src="'.$path.'tabber.js"></script>' . '<link rel="stylesheet" href="'.$path.'tabber.css" TYPE="text/css" MEDIA="screen">'
. '
$wgOut->addHTML($htmlHeader);
} function TabsShut() {
global $wgOut;$wgOut->addHTML('
');
} function TabOpen($iName) {
global $wgOut;
$wgOut->addHTML('
');
} function TabShut() {
global $wgOut;$wgOut->addHTML('
');
}</php>