Ferreteria/archive/menu.php: Difference between revisions

From Woozle Writes Code
Jump to navigation Jump to search
(reconciliation with edited non-dev version)
(reconciliation part 1)
Line 6: Line 6:
   2009-11-04 clsArgs
   2009-11-04 clsArgs
   2010-02-20 clsWikiSection::SectionAdd(), ::ToggleAdd()
   2010-02-20 clsWikiSection::SectionAdd(), ::ToggleAdd()
   2010-04-06 Done earlier but not logged here:
   2010-04-06  
    clsWikiSection::ArgsToAdd() (ported from other copy of menu.php)
    * General reconciliation with edited non-dev version
    clsAdminTable, clsAdminData, clsAdminData_Logged, clsAdminEvents, clsAdminEvent
    * Done earlier but not logged here:
      clsWikiSection::ArgsToAdd() (ported from other copy of menu.php)
      clsAdminTable, clsAdminData, clsAdminData_Logged, clsAdminEvents, clsAdminEvent
  2010-10-06
    Reconciling with dev:
    * Minor improvements; split() is deprecated; small bugfixes
*/
*/
//if (!function_exists('clsMenu::WikiText')) {
//if (!function_exists('clsMenu::WikiText')) {
Line 19: Line 24:


     public function __construct($iWikiPage) {
     public function __construct($iWikiPage) {
$this->Page = $iWikiPage;
    $this->Page = $iWikiPage;
     }
     }
     public function WikiText($iAction) {
     public function WikiText($iAction) {
$this->Action = $iAction;
    $this->Action = $iAction;
if (isset($this->AllNodes[$iAction])) {
    if (isset($this->AllNodes[$iAction])) {
    $this->AllNodes[$iAction]->Activate();
        $this->AllNodes[$iAction]->Activate();
}
    }
$out = $this->WikiText_SubMenu($iAction);
    $out = $this->WikiText_SubMenu($iAction);
return $out;
    return $out;
     }
     }
     public function WikiText_SubMenu($iAction) {
     public function WikiText_SubMenu($iAction) {
$out = NULL;
    $out = NULL;
foreach ($this->SubNodes as $objNode) {
    foreach ($this->SubNodes as $objNode) {
    if (!is_null($out)) {
        if (!is_null($out)) {
$out .= ' | ';
        $out .= ' | ';
    }
        }
    $out .= $objNode->WikiText($iAction);
        $out .= $objNode->WikiText($iAction);
}
    }
return $out;
    return $out;
     }
     }
     public function Add(clsMenuNode $iNode) {
     public function Add(clsMenuNode $iNode) {
$this->SubNodes[$iNode->Name] = $iNode;
    $this->SubNodes[$iNode->Name] = $iNode;
$this->Root()->AllNodes[$iNode->Name] = $iNode;
    $this->Root()->AllNodes[$iNode->Name] = $iNode;
$iNode->Parent = $this;
    $iNode->Parent = $this;
     }
     }
     protected function Root() {
     protected function Root() {
return $this;
    return $this;
     }
     }
     protected function Activate() {    } // do nothing
     protected function Activate() {    }   // do nothing
     public function Execute() {
     public function Execute() {
if (isset($this->Selected)) {
    if (isset($this->Selected)) {
    $out = $this->Selected->DoAction();
        $out = $this->Selected->DoAction();
} else {
    } else {
    $out = NULL;
        $out = NULL;
}
    }
return $out;
    return $out;
     }
     }
}
}
Line 66: Line 71:


     public function __construct($iText, $iDo) {
     public function __construct($iText, $iDo) {
$this->Name = $iDo;
    $this->Name = $iDo;
$this->Text = $iText;
    $this->Text = $iText;
$this->DoSpec = $iDo;
    $this->DoSpec = $iDo;
     }
     }
     public function Root() {
     public function Root() {
return $this->Parent->Root();
    return $this->Parent->Root();
     }
     }
     abstract public function DoAction();
     abstract public function DoAction();
     protected function Activate() {
     protected function Activate() {
$this->IsActive = TRUE;
    $this->IsActive = TRUE;
$this->Parent->Activate();
    $this->Parent->Activate();
     }
     }
     public function WikiText($iAction) {
     public function WikiText($iAction) {
$wtSelf = $this->Root()->Page;
    $wtSelf = $this->Root()->Page;
$wtItem = "[[$wtSelf/page".KS_CHAR_URL_ASSIGN."{$this->DoSpec}|{$this->Text}]]";
    $wtItem = "[[$wtSelf/page".KS_CHAR_URL_ASSIGN."{$this->DoSpec}|{$this->Text}]]";
// if ($iAction == $this->DoSpec) {
//   if ($iAction == $this->DoSpec) {
if ($this->IsActive) {
    if ($this->IsActive) {
    $out = "'''$wtItem'''";
        $out = "'''$wtItem'''";
    $this->Root()->Selected = $this;
        $this->Root()->Selected = $this;
} else {
    } else {
    $out = $wtItem;
        $out = $wtItem;
}
    }
return $out;
    return $out;
     }
     }
}
}
Line 94: Line 99:
class clsMenuRow extends clsMenuNode {
class clsMenuRow extends clsMenuNode {
     public function DoAction() {
     public function DoAction() {
$out = "<br>'''{$this->Text}''': ";
    $out = "<br>'''{$this->Text}''': ";
$out .= $this->WikiText_SubMenu($this->Root()->Action);
    $out .= $this->WikiText_SubMenu($this->Root()->Action);
return $out;
    return $out;
     }
     }
}
}
Line 109: Line 114:
// Possibly this should be in a separate library
// 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?
// 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...
//   Currently ruling out SpecialVbzAdmin...


class clsArgs {
class clsArgs {
Line 115: Line 120:


     public function __construct(array $iPairs=NULL) {
     public function __construct(array $iPairs=NULL) {
if (!is_null($iPairs)) {
    if (!is_null($iPairs)) {
    foreach ($iPairs as $key=>$val) {
        foreach ($iPairs as $key=>$val) {
$this->Add($key,$val);
        $this->Add($key,$val);
    }
        }
}
    }
     }
     }


     public function Add($iName, $iValue=NULL) {
     public function Add($iName, $iValue=NULL) {
$this->arArgs[$iName] = $iValue;
    $this->arArgs[$iName] = $iValue;
     }
     }
     public function Value($iName, $iValue=NULL) {
     public function Value($iName, $iValue=NULL) {
if (!is_null($iValue)) {
    if (!is_null($iValue)) {
    $this->arArgs[$iName] = $iValue;
        $this->arArgs[$iName] = $iValue;
}
    }
if (isset($this->arArgs[$iName])) {
    if (isset($this->arArgs[$iName])) {
    return $this->arArgs[$iName];
        return $this->arArgs[$iName];
} else {
    } else {
    return NULL;
        return NULL;
}
    }
     }
     }
}
}
Line 140: Line 145:
     $out = '';
     $out = '';
     foreach ($iData AS $key => $val) {
     foreach ($iData AS $key => $val) {
if ($val !== FALSE) {
    if ($val !== FALSE) {
    if ($val === TRUE) {
        if ($val === TRUE) {
$out .= '/'.$key;
        $out .= '/'.$key;
    } else {
        } else {
$out .= '/'.$key.KS_CHAR_URL_ASSIGN.$val;
        $out .= '/'.$key.KS_CHAR_URL_ASSIGN.$val;
    }
        }
}
    }
     }
     }
     return $out;
     return $out;
Line 152: Line 157:
function SelfLink_WT(array $iData,$iShow) {
function SelfLink_WT(array $iData,$iShow) {
     if (is_null($iShow)) {
     if (is_null($iShow)) {
return NULL;
    return NULL;
     } else {
     } else {
$strPath = SelfLink_Path($iData);
    $strPath = SelfLink_Path($iData);
return '[[{{FULLPAGENAME}}'.$strPath.'|'.$iShow.']]';
    return '[[{{FULLPAGENAME}}'.$strPath.'|'.$iShow.']]';
     }
     }
}
}
function SelfLink_HTML(array $iData,$iShow,$iPopup=NULL) {
function SelfLink_HTML(array $iData,$iShow,$iPopup=NULL) {
     if (is_null($iShow)) {
     if (is_null($iShow)) {
return NULL;
    return NULL;
     } else {
     } else {
$strPath = SelfLink_Path($iData);
    $strPath = SelfLink_Path($iData);
$htPopup = is_null($iPopup)?'':(' title="'.$iPopup.'"');
    $htPopup = is_null($iPopup)?'':(' title="'.$iPopup.'"');
return '<a href="'.$strPath.'"'.$htPopup.'>'.$iShow.'</a>';
    return '<a href="'.$strPath.'"'.$htPopup.'>'.$iShow.'</a>';
     }
     }
}
}
Line 172: Line 177:


     public function __construct($iName) {
     public function __construct($iName) {
global $wgTitle;
    global $wgTitle,$wgUser;
global $vgPage;
    global $vgPage,$vgUserName;


parent::__construct($iName);
    parent::__construct($iName);
$vgPage = $this;
    $vgPage = $this;
$objTitleMe = $this->getTitle();
    $vgUserName = $wgUser->getName();
$strFullName = $objTitleMe->getPrefixedText();
    $objTitleMe = $this->getTitle();
$this->objRT_HTML = new clsHTML($strFullName);
    $strFullName = $objTitleMe->getPrefixedText();
$this->objRT_Wiki = new clsWikiText($strFullName);
    $this->objRT_HTML = new clsHTML($strFullName);
    $this->objRT_Wiki = new clsWikiText($strFullName);
     }
     }
     public function UseHTML() {
     public function UseHTML() {
global $vgOut;
    global $vgOut;


$vgOut = $this->objRT_HTML;
    $vgOut = $this->objRT_HTML;
     }
     }
     public function UseWiki() {
     public function UseWiki() {
global $vgOut;
    global $vgOut;


$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 202: Line 208:
     to any particular item as a wiki page title while also not worrying about hierarchy/order.
     to any particular item as a wiki page title while also not worrying about hierarchy/order.
*/
*/
$args_raw = split('/',$par);
//    $args_raw = split('/',$par);    // split() is deprecated
foreach($args_raw as $arg_raw) {
    $args_raw = preg_split('/\//',$par);
    if (strpos($arg_raw,KS_CHAR_URL_ASSIGN) !== FALSE) {
    foreach($args_raw as $arg_raw) {
list($key,$val) = split(KS_CHAR_URL_ASSIGN,$arg_raw);
        if (strpos($arg_raw,KS_CHAR_URL_ASSIGN) !== FALSE) {
$this->args[$key] = $val;
//        list($key,$val) = split(KS_CHAR_URL_ASSIGN,$arg_raw);    // split() is deprecated
    } else {
        list($key,$val) = preg_split('/'.KS_CHAR_URL_ASSIGN.'/',$arg_raw);
$this->args[$arg_raw] = TRUE;
        $this->args[$key] = $val;
    }
        } else {
}
        $this->args[$arg_raw] = TRUE;
        }
    }
     }
     }
     public function Arg($iName) {
     public function Arg($iName) {
if (isset($this->args[$iName])) {
    if (isset($this->args[$iName])) {
    return $this->args[$iName];
        return $this->args[$iName];
} else {
    } else {
    return FALSE;
        return FALSE;
}
    }
     }
     }
     /*=====
     /*=====
Line 223: Line 231:
     */
     */
     private function SelfLink_Path(array $iAdd) {
     private function SelfLink_Path(array $iAdd) {
$arData = $this->args;
    $arData = $this->args;
foreach ($iAdd AS $key => $val) {
    foreach ($iAdd AS $key => $val) {
    $arData[$key] = $val; // override any matching keys
        $arData[$key] = $val;   // override any matching keys
}
    }
return SelfLink_Path($arData);
    return SelfLink_Path($arData);
     }
     }
     /*=====
     /*=====
Line 233: Line 241:
     */
     */
     public function SelfURL(array $iAdd=NULL,$iClear=FALSE) {
     public function SelfURL(array $iAdd=NULL,$iClear=FALSE) {
global $wgTitle;
    global $wgTitle;


if (is_array($iAdd)) {
    if (is_array($iAdd)) {
    if ($iClear) {
        if ($iClear) {
$strPath = SelfLink_Path($iAdd);
        $strPath = SelfLink_Path($iAdd);
    } else {
        } else {
$strPath = $this->SelfLink_Path($iAdd);
        $strPath = $this->SelfLink_Path($iAdd);
    }
        }
} else {
    } else {
    $strPath = '';
        $strPath = '';
}
    }
return '/'.$wgTitle->getPrefixedText().$strPath;
    return '/'.$wgTitle->getPrefixedText().$strPath;
     }
     }
     public function SelfLink_WT(array $iAdd, $iShow) {
     public function SelfLink_WT(array $iAdd, $iShow) {
$arData = $this->args;
    $arData = $this->args;
foreach ($iAdd AS $key => $val) {
    foreach ($iAdd AS $key => $val) {
    $arData[$key] = $val; // override any matching keys
        $arData[$key] = $val;   // override any matching keys
}
    }
$out = SelfLink_WT($arData,$iShow);
    $out = SelfLink_WT($arData,$iShow);
return $out;
    return $out;
     }
     }
     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;
    return $out;
     }
     }
}
}
Line 266: Line 274:
class clsAdminTable extends clsTable {
class clsAdminTable extends clsTable {
     public function ActionKey($iName=NULL) {
     public function ActionKey($iName=NULL) {
if (!is_null($iName)) {
    if (!is_null($iName)) {
    $this->ActionKey = $iName;
        $this->ActionKey = $iName;
}
    }
return $this->ActionKey;
    return $this->ActionKey;
     }
     }
}
}
class clsAdminData extends clsDataSet {
class clsAdminData extends clsDataSet {
     public function AdminLink($iText=NULL,$iPopup=NULL) {
     public function AdminLink($iText=NULL,$iPopup=NULL) {
global $vgOut;
    global $vgOut;


$txtShow = is_null($iText)?($this->ID):$iText;
    $txtShow = is_null($iText)?($this->ID):$iText;
if (isset($this->Table->ActionKey)) {
    if (isset($this->Table->ActionKey)) {
    $strKey = $this->Table->ActionKey;
        $strKey = $this->Table->ActionKey;
} else {
    } else {
    $strKey = $this->Table->Name();
        $strKey = $this->Table->Name();
}
    }


$arLink = array(
    $arLink = array(
  'page' => $strKey,
      'page'   => $strKey,
  'id' => $this->ID);
      'id'       => $this->KeyValue());
$out = $vgOut->SelfLink($arLink,$txtShow,$iPopup);
    $out = $vgOut->SelfLink($arLink,$txtShow,$iPopup);
return $out;
    return $out;
     }
     }
}
}
abstract class clsAdminData_Logged extends clsAdminData {
abstract class clsAdminData_Logged extends clsAdminData {
     abstract protected function Events(); // RETURNS a clsAdminEvents object
     abstract protected function Events();       // RETURNS a clsAdminEvents object
     public function StartEvent(array $iarArgs) {
     public function StartEvent(array $iarArgs) {
$arArgs = $iarArgs;
    $arArgs = $iarArgs;
$arArgs['type'] = $this->Table->ActionKey; // TO DO: de-couple this from URL keys
    $arArgs['type'] = $this->Table->ActionKey;   // TO DO: de-couple this from URL keys
$arArgs['id'] = $this->ID;
    //$arArgs['id'] = $this->ID;
return $this->Events()->StartEvent($arArgs);
    $arArgs['id'] = $this->KeyValue();
//echo '<pre>'.print_r($arArgs,TRUE).'</pre>'; die();
    return $this->Events()->StartEvent($arArgs);
     }
     }
     public function FinishEvent($iEvent,array $iarArgs=NULL) {
     public function FinishEvent($iEvent,array $iarArgs=NULL) {
$this->Events()->FinishEvent($iEvent,$iarArgs);
    $this->Events()->FinishEvent($iEvent,$iarArgs);
     }
     }
}
}
Line 309: Line 319:
class clsAdminEvents extends clsAdminTable {
class clsAdminEvents extends clsAdminTable {
     public function __construct($iDB) {
     public function __construct($iDB) {
assert('is_object($iDB)');
    assert('is_object($iDB)');
// these defaults are all overridable - must match actual event table schema
    // these defaults are all overridable - must match actual event table schema
parent::__construct($iDB);
    parent::__construct($iDB);
  $this->Name('event');
      $this->Name('event');
  $this->KeyName('ID');
      $this->KeyName('ID');
  $this->ClassSng('clsAdminEvent'); // override parent
      $this->ClassSng('clsAdminEvent');   // override parent
  $this->ActionKey('event');
      $this->ActionKey('event');
     }
     }
     public function ListPage() {
     public function ListPage() {
global $wgOut;
    global $wgOut;


$objRow = $this->GetData(NULL,NULL,'ID DESC');
    $objRow = $this->GetData(NULL,NULL,'ID DESC');
if ($objRow->hasRows()) {
    if ($objRow->hasRows()) {
    $out = $objRow->AdminRows();
        $out = $objRow->AdminRows();
} else {
    } else {
    $out = 'No events logged yet.';
        $out = 'No events logged yet.';
}
    }
$wgOut->addWikiText($out,TRUE);
    $wgOut->addWikiText($out,TRUE);
     }
     }
     /*-----
     /*-----
       RETURNS: event arguments translated into field names for use in Insert()
       RETURNS: event arguments translated into field names for use in Insert()
      NOTE: Shouldn't this method be static?
     */
     */
     private function CalcSQL($iArgs) {
     private function CalcSQL($iArgs) {
if (is_null($iArgs)) {
    if (is_null($iArgs)) {
    return NULL;
        return NULL;
} else {
    } else {
    foreach ($iArgs as $key=>$val) {
        foreach ($iArgs as $key=>$val) {
switch ($key) {
        switch ($key) {
  case 'descr':
          case 'descr':
    $sqlKey = 'Descr';
            $sqlKey = 'Descr';
    $sqlVal = SQLValue($val);
            $sqlVal = SQLValue($val);
    break;
            break;
  case 'notes':
          case 'notes':
    $sqlKey = 'Notes';
            $sqlKey = 'Notes';
    $sqlVal = SQLValue($val);
            $sqlVal = SQLValue($val);
    break;
            break;
  case 'type':
          case 'type':
    $sqlKey = 'ModType';
            $sqlKey = 'ModType';
    $sqlVal = SQLValue($val);
            $sqlVal = SQLValue($val);
    break;
            break;
  case 'id':
          case 'id':
    $sqlKey = 'ModIndex';
            $sqlKey = 'ModIndex';
    $sqlVal = SQLValue($val); // can be NULL
            $sqlVal = SQLValue($val);   // can be NULL
    break;
            break;
  case 'where':
          case 'where':
    $sqlKey = 'EvWhere';
            $sqlKey = 'EvWhere';
    $sqlVal = SQLValue($val);
            $sqlVal = SQLValue($val);
    break;
            break;
  case 'code':
          case 'code':
    $sqlKey = 'Code';
            $sqlKey = 'Code';
    $sqlVal = SQLValue($val);
            $sqlVal = SQLValue($val);
    break;
            break;
  case 'error':
          case 'error':
    $sqlKey = 'isError';
            $sqlKey = 'isError';
    $sqlVal = TRUE;
            $sqlVal = SQLValue($val);
    break;
            break;
  case 'severe':
          case 'severe':
    $sqlKey = 'isSevere';
            $sqlKey = 'isSevere';
    $sqlVal = TRUE;
            $sqlVal = SQLValue($val);
    break;
            break;
}
        }
$arIns[$sqlKey] = $sqlVal;
        $arIns[$sqlKey] = $sqlVal;
    }
        }
    return $arIns;
        return $arIns;
}
    }
     }
     }
     /*-----
     /*-----
       ACTION: Logs an event from specs in an array
       ACTION: Logs an event from specs in an array
       INPUT: Array containing any of the following elements:
       INPUT: Array containing any of the following elements:
'descr': description of event
    'descr': description of event
'type': type of event (one of the kType* class constants)
    'type': type of event (one of the kType* class constants)
'id': ID of row in table corresponding to event type
    'id': ID of row in table corresponding to event type
'where': location in code where event is taking place (usually __METHOD__ will do)
    'where': location in code where event is taking place (usually __METHOD__ will do)
'code': event code unique to type
    'code': event code unique to type
'error' (value ignored): if present, event represents an error
    'error' (value ignored): if present, event represents an error
'severe' (value ignored): if present, event represents a severe error
    'severe' (value ignored): if present, event represents a severe error
     */
     */
     public function StartEvent(array $iArgs) {
     public function StartEvent(array $iArgs) {
global $vgUserName;
    global $vgUserName;


$arIns = $this->CalcSQL($iArgs);
    $arIns = $this->CalcSQL($iArgs);
if (empty($arIns)) {
    if (empty($arIns)) {
    return NULL;
        return NULL;
} else {
    } else {
    $arIns['WhenStarted'] = 'NOW()';
        $arIns['WhenStarted'] = 'NOW()';
    $arIns['WhoNetwork'] = SQLValue($_SERVER['REMOTE_ADDR']);
        $arIns['WhoNetwork'] = SQLValue($_SERVER['REMOTE_ADDR']);
    $arIns['WhoAdmin'] = SQLValue($vgUserName);
        $arIns['WhoAdmin'] = SQLValue($vgUserName);
    $ok = $this->Insert($arIns);
echo '<pre>'.print_r($arIns,TRUE).'</pre>'; die();
    if ($ok) {
        $ok = $this->Insert($arIns);
return $this->objDB->NewID(__METHOD__);
        if ($ok) {
    } else {
        return $this->objDB->NewID(__METHOD__);
return NULL;
        } else {
    }
        return NULL;
}
        }
    }
     }
     }
     public function FinishEvent($iEvent,array $iArgs=NULL) {
     public function FinishEvent($iEvent,array $iArgs=NULL) {
if (is_array($iArgs)) {
    if (is_array($iArgs)) {
    $arUpd = $this->CalcSQL($iArgs);
        $arUpd = $this->CalcSQL($iArgs);
    //$arUpd = array_merge($arUpd,$iArgs);
        //$arUpd = array_merge($arUpd,$iArgs);
}
    }
$arUpd['WhenFinished'] = 'NOW()';
    $arUpd['WhenFinished'] = 'NOW()';
$this->Update($arUpd,'ID='.$iEvent);
    $this->Update($arUpd,'ID='.$iEvent);
     }
     }
}
}
Line 418: Line 430:
     */
     */
     public function AdminRows() {
     public function AdminRows() {
$htUnknown = '<span style="color: #888888;">?</span>';
    $htUnknown = '<span style="color: #888888;">?</span>';
$out = "{|";
    $out = "{|";
$out .= "\n|-\n! ID || Start || Finish || Who/How || Where";
    $out .= "\n|-\n! ID || Start || Finish || Who/How || Where";
//     $out .= "\n|-\n!    || colspan=5 | Description";
//       $out .= "\n|-\n!    || colspan=5 | Description";
$isOdd = TRUE;
    $isOdd = TRUE;
$strDateLast = NULL;
    $strDateLast = NULL;
$objRow = $this;
    $objRow = $this;
while ($objRow->NextRow()) {
    while ($objRow->NextRow()) {
    $wtStyle = $isOdd?'background:#ffffff;':'background:#eeeeee;';
        $wtStyle = $isOdd?'background:#ffffff;':'background:#eeeeee;';
    $isOdd = !$isOdd;
        $isOdd = !$isOdd;


    $row = $objRow->Row;
        $row = $objRow->Row;


    $strSysUser = $row['WhoAdmin'];
        $strSysUser   = $row['WhoAdmin'];
    $strVbzUser = $row['WhoSystem'];
        $strVbzUser   = $row['WhoSystem'];
    $strMachine = $row['WhoNetwork'];
        $strMachine   = $row['WhoNetwork'];
    $htSysUser = is_null($strSysUser)?$htUnknown:$strSysUser;
        $htSysUser   = is_null($strSysUser)?$htUnknown:$strSysUser;
    $htMachine = is_null($strMachine)?$htUnknown:$strMachine;
        $htMachine   = is_null($strMachine)?$htUnknown:$strMachine;
    $htVbzUser = is_null($strVbzUser)?$htUnknown:$strVbzUser;
        $htVbzUser   = is_null($strVbzUser)?$htUnknown:$strVbzUser;


    $ftDescr = $row['Descr'];
        $ftDescr   = $row['Descr'];
    $strNotes = $row['Notes'];
        $strNotes   = $row['Notes'];


    $id = $row['ID'];
        $id       = $row['ID'];
    $strWhenSt = $row['WhenStarted'];
        $strWhenSt   = $row['WhenStarted'];
    $strWhenFi = $row['WhenFinished'];
        $strWhenFi   = $row['WhenFinished'];
    $strWhere = $row['EvWhere'];
        $strWhere   = $row['EvWhere'];
    $htWho = $htVbzUser.'/'.$htSysUser.'@'.$htMachine;
        $htWho       = $htVbzUser.'/'.$htSysUser.'@'.$htMachine;
    $strParams = $row['Params'];
        $strParams   = $row['Params'];


    $dtWhenSt = strtotime($strWhenSt);
        $dtWhenSt   = strtotime($strWhenSt);
    $dtWhenFi = strtotime($strWhenFi);
        $dtWhenFi   = strtotime($strWhenFi);
    $strDate = date('Y-m-d',empty($dtWhenSt)?$dtWhenFi:$dtWhenSt);
        $strDate   = date('Y-m-d',empty($dtWhenSt)?$dtWhenFi:$dtWhenSt);
    $strTimeSt = empty($dtWhenSt)?'':date('H:i',$dtWhenSt);
        $strTimeSt = empty($dtWhenSt)?'':date('H:i',$dtWhenSt);
    $strTimeFi = empty($dtWhenFi)?'':date('H:i',$dtWhenFi);
        $strTimeFi = empty($dtWhenFi)?'':date('H:i',$dtWhenFi);
    if ($strDate != $strDateLast) {
        if ($strDate != $strDateLast) {
$strDateLast = $strDate;
        $strDateLast = $strDate;
$out .= "\n|- style=\"background: #444466; color: #ffffff;\"\n| colspan=5 | '''$strDate'''";
        $out .= "\n|- style=\"background: #444466; color: #ffffff;\"\n| colspan=5 | '''$strDate'''";
    }
        }
   
       
    $out .= "\n|- style=\"$wtStyle\"";
        $out .= "\n|- style=\"$wtStyle\"";
    $out .= "\n| $id || $strTimeSt || $strTimeFi || $htWho || <small>$strWhere</small>";
        $out .= "\n| $id || $strTimeSt || $strTimeFi || $htWho || <small>$strWhere</small>";
    if (!empty($ftDescr)) {
        if (!empty($ftDescr)) {
$out .= "\n|- style=\"$wtStyle\"";
        $out .= "\n|- style=\"$wtStyle\"";
$out .= "\n|    || colspan=5 | '''What''': $ftDescr";
        $out .= "\n|    || colspan=5 | '''What''': $ftDescr";
    }
        }
    if (!empty($strParams)) {
        if (!empty($strParams)) {
$out .= "\n|- style=\"$wtStyle\"";
        $out .= "\n|- style=\"$wtStyle\"";
$out .= "\n|    || colspan=5 | '''Params''': $strParams";
        $out .= "\n|    || colspan=5 | '''Params''': $strParams";
    }
        }
    if (!empty($strNotes)) {
        if (!empty($strNotes)) {
$out .= "\n|- style=\"$wtStyle\"";
        $out .= "\n|- style=\"$wtStyle\"";
$out .= "\n|    || colspan=5 | '''Notes''': ''$strNotes''";
        $out .= "\n|    || colspan=5 | '''Notes''': ''$strNotes''";
    }
        }
}
    }
$out .= "\n|}";
    $out .= "\n|}";
return $out;
    return $out;
     }
     }
}
}
Line 486: Line 498:


     public function __construct(SpecialPageApp $iPage) {
     public function __construct(SpecialPageApp $iPage) {
$this->mwoPage = $iPage;
    $this->mwoPage = $iPage;
     }
     }
     public function Page() {
     public function Page() {
return $this->mwoPage;
    return $this->mwoPage;
     }
     }
}
}
Line 497: Line 509:


     // DYNAMIC
     // DYNAMIC
     private $strName; // short name for header text
     private $strName;   // short name for header text
     private $strDescr; // longer description for popups
     private $strDescr;   // longer description for popups
     private $intLevel; // level of header; defaults to 2
     private $intLevel;   // level of header; defaults to 2
     private $objFmt; // page-formatter object
     private $objFmt;   // page-formatter object
     private $arMenu; // menu entries
     private $arMenu;   // menu entries
     private $arKeep; // arguments to preserve (in every menu item) from the current page  
     private $arKeep;   // arguments to preserve (in every menu item) from the current page  
     private $arAdd; // arguments to add to every menu item
     private $arAdd;   // arguments to add to every menu item


     public function __construct(clsWikiFormatter $iFmt,$iName,$iDescr=NULL,$iLevel=2,array $iMenu=NULL) {
     public function __construct(clsWikiFormatter $iFmt,$iName,$iDescr=NULL,$iLevel=2,array $iMenu=NULL) {
$this->objFmt = $iFmt;
    $this->objFmt = $iFmt;
$this->strName = $iName;
    $this->strName = $iName;
$this->strDescr = is_null($iDescr)?$iName:$iDescr;
    $this->strDescr = is_null($iDescr)?$iName:$iDescr;
$this->intLevel = $iLevel;
    $this->intLevel = $iLevel;
$this->arMenu = $iMenu;
    $this->arMenu = $iMenu;
$this->arKeep = self::$arKeepDefault;
    $this->arKeep = self::$arKeepDefault;
     }
     }
     public function ArgsToKeep(array $iKeep) {
     public function ArgsToKeep(array $iKeep) {
$this->arKeep = $iKeep;
    $this->arKeep = $iKeep;  
     }
     }
     public function ArgsToAdd(array $iAdd) {
     public function ArgsToAdd(array $iAdd) {
$this->arAdd = $iAdd;
    $this->arAdd = $iAdd;
     }
     }
     protected function ArrayCheck(array $iarCheck) {
     protected function ArrayCheck(array $iarCheck) {
if (is_array($this->arAdd)) {
    if (is_array($this->arAdd)) {
    $arOut = array_unique(array_merge($iarCheck,$this->arAdd));
        $arOut = array_unique(array_merge($iarCheck,$this->arAdd));
} else {
    } else {
    $arOut = $iarCheck;
        $arOut = $iarCheck;
}
    }
return $arOut;
    return $arOut;
     }
     }
     /*-----
     /*-----
Line 531: Line 543:
     */
     */
     public function SelfArray() {
     public function SelfArray() {
$objPage = $this->objFmt->Page();
    $objPage = $this->objFmt->Page();
if (is_array($this->arKeep)) {
    if (is_array($this->arKeep)) {
    foreach ($this->arKeep as $key) {
        foreach ($this->arKeep as $key) {
$arLink[$key] = $objPage->Arg($key);
        $arLink[$key] = $objPage->Arg($key);
    }
        }
}
    }
return $this->ArrayCheck($arLink);
    return $this->ArrayCheck($arLink);
     }
     }
     public function SelfURL() {
     public function SelfURL() {
$arLink = $this->SelfArray();
    $arLink = $this->SelfArray();
$objPage = $this->objFmt->Page();
    $objPage = $this->objFmt->Page();
$wpPath = $objPage->SelfURL($arLink,TRUE);
    $wpPath = $objPage->SelfURL($arLink,TRUE);
return $wpPath;
    return $wpPath;
     }
     }
     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;


$objPage = $this->objFmt->Page();
    $objPage = $this->objFmt->Page();
$arLink = $this->ArrayCheck($this->SelfArray());
    $arLink = $this->ArrayCheck($this->SelfArray());


$strKey = is_null($iKey)?$iDisp:$iKey;
    $strKey = is_null($iKey)?$iDisp:$iKey;
$arLink['do'] = $strKey;
    $arLink['do'] = $strKey;
$arLink = $this->ArrayCheck($arLink);
    $arLink = $this->ArrayCheck($arLink);
$wpPath = $objPage->SelfURL($arLink,TRUE);
    $wpPath = $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'   => $wpPath,
  'popup' => $strPopup,
      'popup'   => $strPopup,
  'displ' => $iDisp,
      'displ'   => $iDisp,
  'active' => $isActive,
      'active'   => $isActive,
  'isdef' => $iIsDefault
      'isdef'   => $iIsDefault
  );
      );
$this->arMenu[] = $arEntry;
    $this->arMenu[] = $arEntry;
     }
     }
     public function SectionAdd($iDisp) {
     public function SectionAdd($iDisp) {
$arEntry = array(
    $arEntry = array(
  'type' => 'section',
      'type'   => 'section',
  'displ' => $iDisp
      'displ'   => $iDisp
  );
      );
$this->arMenu[] = $arEntry;
    $this->arMenu[] = $arEntry;
     }
     }
     public function ToggleAdd($iDisp,$iPopup=NULL,$iKey=NULL) {
     public function ToggleAdd($iDisp,$iPopup=NULL,$iKey=NULL) {
$strPopup = is_null($iPopup)?($iDisp.' '.$this->strDescr):$iPopup;
    $strPopup = is_null($iPopup)?($iDisp.' '.$this->strDescr):$iPopup;
$strKey = is_null($iKey)?$iDisp:$iKey;
    $strKey = is_null($iKey)?$iDisp:$iKey;


$objPage = $this->objFmt->Page();
    $objPage = $this->objFmt->Page();
$arLink = $this->SelfArray();
    $arLink = $this->SelfArray();


$isActive = $objPage->Arg($strKey); // active state is indicated by presence of key
    $isActive = $objPage->Arg($strKey);   // active state is indicated by presence of key
$arLink[$strKey] = !$isActive;
    $arLink[$strKey] = !$isActive;
$arLink = $this->ArrayCheck($arLink);
    $arLink = $this->ArrayCheck($arLink);
$wpPath = $objPage->SelfURL($arLink,TRUE);
    $wpPath = $objPage->SelfURL($arLink,TRUE);


$arEntry = array(
    $arEntry = array(
  'type' => 'toggle',
      'type'   => 'toggle',
  'path' => $wpPath,
      'path'   => $wpPath,
  'popup' => $strPopup,
      'popup'   => $strPopup,
  'displ' => $iDisp,
      'displ'   => $iDisp,
  'active' => $isActive
      'active'   => $isActive
  );
      );
$this->arMenu[] = $arEntry;
    $this->arMenu[] = $arEntry;
     }
     }
     public function Generate() {
     public function Generate() {
$out = '<h'.$this->intLevel.'>';
    $out = '<h'.$this->intLevel.'>';
if (is_array($this->arMenu)) {
    if (is_array($this->arMenu)) {
    $arMenu = array_reverse($this->arMenu); // right-alignment reverses things
        $arMenu = array_reverse($this->arMenu);   // right-alignment reverses things
    foreach ($arMenu as $arLink) {
        foreach ($arMenu as $arLink) {
$strType = $arLink['type'];
        $strType = $arLink['type'];
switch ($strType) {
        switch ($strType) {
  case 'action':
          case 'action':
    $htPath = $arLink['path'];
            $htPath = $arLink['path'];
    $htPopup = $arLink['popup'];
            $htPopup = $arLink['popup'];
    $htDispl = $arLink['displ'];
            $htDispl = $arLink['displ'];
    $isActive = !empty($arLink['active']) || $arLink['isdef'];
            $isActive = !empty($arLink['active']) || $arLink['isdef'];
    $htFmtOpen = $isActive?'<b>':'';
            $htFmtOpen = $isActive?'<b>':'';
    $htFmtShut = $isActive?'</b>':'';
            $htFmtShut = $isActive?'</b>':'';
    $out .= '<span class="editsection">';
            $out .= '<span class="editsection">';
    $out .= $htFmtOpen.'[';
            $out .= $htFmtOpen.'[';
    $out .= '<a href="'.$htPath.'" title="'.$htPopup.'">'.$htDispl.'</a>';
            $out .= '<a href="'.$htPath.'" title="'.$htPopup.'">'.$htDispl.'</a>';
    $out .= ']'.$htFmtShut;
            $out .= ']'.$htFmtShut;
    $out .= '</span>';
            $out .= '</span>';
    break;
            break;
  case 'toggle':
          case 'toggle':
    $htPath = $arLink['path'];
            $htPath = $arLink['path'];
    $htPopup = $arLink['popup'];
            $htPopup = $arLink['popup'];
    $htDispl = $arLink['displ'];
            $htDispl = $arLink['displ'];
    $isActive = !empty($arLink['active']);
            $isActive = !empty($arLink['active']);
    $htFmtOpen = $isActive?'<b>':'';
            $htFmtOpen = $isActive?'<b>':'';
    $htFmtShut = $isActive?'</b>':'';
            $htFmtShut = $isActive?'</b>':'';
    $out .= '<span class="editsection">';
            $out .= '<span class="editsection">';
    $out .= $htFmtOpen.'[';
            $out .= $htFmtOpen.'[';
    $out .= '<a href="'.$htPath.'" title="'.$htPopup.'">'.$htDispl.'</a>';
            $out .= '<a href="'.$htPath.'" title="'.$htPopup.'">'.$htDispl.'</a>';
    $out .= ']'.$htFmtShut;
            $out .= ']'.$htFmtShut;
    $out .= '</span>';
            $out .= '</span>';
    break;
            break;
  case 'section':
          case 'section':
    $htDispl = $arLink['displ'];
            $htDispl = $arLink['displ'];
    $out .= '<span class="editsection">';
            $out .= '<span class="editsection">';
    $out .= '| <b>'.$htDispl.'</b>:';
            $out .= '| <b>'.$htDispl.'</b>:';
    $out .= '</span>';
            $out .= '</span>';
    break;
            break;
}
        }
    }
        }
}
    }
$out .= '<span class="mw-headline">'.$this->strName.'</span></h'.$this->intLevel.'>';
    $out .= '<span class="mw-headline">'.$this->strName.'</span></h'.$this->intLevel.'>';
return $out;
    return $out;
     }
     }
     public function FormOpen() {
     public function FormOpen() {
$out = '<form method=post action="'.$this->SelfURL().'">';
    $out = '<form method=post action="'.$this->SelfURL().'">';
return $out;
    return $out;
     }
     }
}
}
Line 656: Line 668:


     public function __construct($iTitle, $iDescr=NULL, array $iKeep=NULL) {
     public function __construct($iTitle, $iDescr=NULL, array $iKeep=NULL) {
global $vgPage;
    global $vgPage;


$this->strTitle = $iTitle;
    $this->strTitle = $iTitle;
$this->strDescr = is_null($iDescr)?$iTitle:$iDescr;
    $this->strDescr = is_null($iDescr)?$iTitle:$iDescr;
$this->arKeep = is_null($iKeep)?(self::$arKeepDefault):$iKeep;
    $this->arKeep = is_null($iKeep)?(self::$arKeepDefault):$iKeep;
$this->doEdit = $vgPage->Arg('edit');
    $this->doEdit = $vgPage->Arg('edit');
//$this->htPath = $vgPage->SelfURL(array('edit'=>!$this->doEdit));
    //$this->htPath = $vgPage->SelfURL(array('edit'=>!$this->doEdit));
$this->htPath = $vgPage->SelfURL();
    $this->htPath = $vgPage->SelfURL();
     }
     }
     public function HeaderHtml(array $iMenu=NULL) {
     public function HeaderHtml(array $iMenu=NULL) {
$out = '<h2>';
    $out = '<h2>';
if (is_array($iMenu)) {
    if (is_array($iMenu)) {
    foreach ($iMenu as $arLink) {
        foreach ($iMenu as $arLink) {
$htPath = $arLink['path'];
        $htPath = $arLink['path'];
$htPopup = $arLink['popup'];
        $htPopup = $arLink['popup'];
$htDispl = $arLink['displ'];
        $htDispl = $arLink['displ'];
$isActive = !empty($arLink['active']);
        $isActive = !empty($arLink['active']);
$out .= '<span class="editsection">';
        $out .= '<span class="editsection">';
if ($isActive) {  $out .= '<b>'; }
        if ($isActive) {  $out .= '<b>'; }
$out .= '[';
        $out .= '[';
if ($isActive) {  $out .= '</b>'; }
        if ($isActive) {  $out .= '</b>'; }
$out .= '<a href="'.$htPath.'" title="'.$htPopup.'">'.$htDispl.'</a>';
        $out .= '<a href="'.$htPath.'" title="'.$htPopup.'">'.$htDispl.'</a>';
if ($isActive) {  $out .= '<b>'; }
        if ($isActive) {  $out .= '<b>'; }
$out .= ']';
        $out .= ']';
if ($isActive) {  $out .= '</b>'; }
        if ($isActive) {  $out .= '</b>'; }
$out .= '</span> ';
        $out .= '</span> ';
    }
        }
} else {
    } else {
    $out = '';
        $out = '';
}
    }
$out .= '<span class="mw-headline">'.$this->strTitle.'</span></h2>';
    $out .= '<span class="mw-headline">'.$this->strTitle.'</span></h2>';
return $out;
    return $out;
     }
     }
     public function HeaderHtml_OLD() {
     public function HeaderHtml_OLD() {
$out = '<h2>';
    $out = '<h2>';
if (!$this->doEdit) {
    if (!$this->doEdit) {
  $out .= '<span class="editsection">[<a href="'.$this->htPath.'" title="Edit '.$this->strDescr.'">edit</a>]</span> ';
      $out .= '<span class="editsection">[<a href="'.$this->htPath.'" title="Edit '.$this->strDescr.'">edit</a>]</span> ';
}
    }
$out .= '<span class="mw-headline">'.$this->strTitle.'</span></h2>';
    $out .= '<span class="mw-headline">'.$this->strTitle.'</span></h2>';
return $out;
    return $out;
     }
     }
     public function HeaderHtml_Edit(array $iMenu=NULL) {
     public function HeaderHtml_Edit(array $iMenu=NULL) {
global $vgPage;
    global $vgPage;


if (is_array($this->arKeep)) {
    if (is_array($this->arKeep)) {
    foreach ($this->arKeep as $key) {
        foreach ($this->arKeep as $key) {
$arLink[$key] = $vgPage->Arg($key);
        $arLink[$key] = $vgPage->Arg($key);
    }
        }
}
    }


$arLink['edit'] = TRUE;
    $arLink['edit'] = TRUE;
$wpPathEd = $vgPage->SelfURL($arLink,TRUE);
    $wpPathEd = $vgPage->SelfURL($arLink,TRUE);


$arLink['edit'] = FALSE;
    $arLink['edit'] = FALSE;
$wpPathVw = $vgPage->SelfURL($arLink,TRUE);
    $wpPathVw = $vgPage->SelfURL($arLink,TRUE);


// generate standard part of menu:
    // generate standard part of menu:
$arMenu = array(
    $arMenu = array(
  array(
      array(
    'path' => $wpPathEd,
        'path'   => $wpPathEd,
    'popup' => 'edit '.$this->strDescr,
        'popup'   => 'edit '.$this->strDescr,
    'displ' => 'edit',
        'displ'   => 'edit',
    'active' => $this->doEdit),
        'active'   => $this->doEdit),
  array(
      array(
    'path' => $wpPathVw,
        'path'   => $wpPathVw,
    'popup' => 'view '.$this->strDescr,
        'popup'   => 'view '.$this->strDescr,
    'displ' => 'view',
        'displ'   => 'view',
    'active' => !$this->doEdit));
        'active'   => !$this->doEdit));


if (is_array($iMenu)) {
    if (is_array($iMenu)) {
    $arMenu = array_merge($arMenu,$iMenu); // append passed menu
        $arMenu = array_merge($arMenu,$iMenu);   // append passed menu
}
    }


return $this->HeaderHtml($arMenu);
    return $this->HeaderHtml($arMenu);
     }
     }
     public function FormOpen() {
     public function FormOpen() {
if ($this->doEdit) {
    if ($this->doEdit) {
    $out = '<form method=post action="'.$this->htPath.'">';
        $out = '<form method=post action="'.$this->htPath.'">';
} else {
    } else {
    $out = NULL;
        $out = NULL;
}
    }
return $out;
    return $out;
     }
     }
}
}
Line 750: Line 762:
     $path = $wgScriptPath . '/extensions/tabber/';
     $path = $wgScriptPath . '/extensions/tabber/';
     $htmlHeader = '<script type="text/javascript" src="'.$path.'tabber.js"></script>'
     $htmlHeader = '<script type="text/javascript" src="'.$path.'tabber.js"></script>'
    . '<link rel="stylesheet" href="'.$path.'tabber.css" TYPE="text/css" MEDIA="screen">'
        . '<link rel="stylesheet" href="'.$path.'tabber.css" TYPE="text/css" MEDIA="screen">'
    . '<div class="tabber">';
        . '<div class="tabber">';
     $wgOut->addHTML($htmlHeader);
     $wgOut->addHTML($htmlHeader);
}
}

Revision as of 22:35, 6 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-10-06
   Reconciling with dev:
   * Minor improvements; split() is deprecated; small bugfixes
  • /

//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 function SelfLink_Path(array $iData) {

   $out = ;
   foreach ($iData AS $key => $val) {
   if ($val !== FALSE) {
       if ($val === TRUE) {
       $out .= '/'.$key;
       } else {
       $out .= '/'.$key.KS_CHAR_URL_ASSIGN.$val;
       }
   }
   }
   return $out;

} function SelfLink_WT(array $iData,$iShow) {

   if (is_null($iShow)) {
   return NULL;
   } else {
   $strPath = SelfLink_Path($iData);
   return ''.$iShow.'';
   }

} 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 $wgTitle,$wgUser;
   global $vgPage,$vgUserName;
   parent::__construct($iName);
   $vgPage = $this;
   $vgUserName = $wgUser->getName();
   $objTitleMe = $this->getTitle();
   $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;
       }
   }
   }
   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
   */
   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
   */
   public function SelfURL(array $iAdd=NULL,$iClear=FALSE) {
   global $wgTitle;
   if (is_array($iAdd)) {
       if ($iClear) {
       $strPath = SelfLink_Path($iAdd);
       } else {
       $strPath = $this->SelfLink_Path($iAdd);
       }
   } else {
       $strPath = ;
   }
   return '/'.$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;
   }
   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;
   }

} /*==========

 DATA CLASSES
  • /

class clsAdminTable extends clsTable {

   public function ActionKey($iName=NULL) {
   if (!is_null($iName)) {
       $this->ActionKey = $iName;
   }
   return $this->ActionKey;
   }

} class clsAdminData extends clsDataSet {

   public function AdminLink($iText=NULL,$iPopup=NULL) {
   global $vgOut;
   $txtShow = is_null($iText)?($this->ID):$iText;
   if (isset($this->Table->ActionKey)) {
       $strKey = $this->Table->ActionKey;
   } else {
       $strKey = $this->Table->Name();
   }
   $arLink = array(
     'page'    => $strKey,
     'id'        => $this->KeyValue());
   $out = $vgOut->SelfLink($arLink,$txtShow,$iPopup);
   return $out;
   }

} abstract class clsAdminData_Logged extends clsAdminData {

   abstract protected function Events();        // RETURNS a clsAdminEvents object
   public function StartEvent(array $iarArgs) {
   $arArgs = $iarArgs;
   $arArgs['type'] = $this->Table->ActionKey;    // TO DO: de-couple this from URL keys
   //$arArgs['id'] = $this->ID;
   $arArgs['id'] = $this->KeyValue();

//echo '

'.print_r($arArgs,TRUE).'

'; die();

   return $this->Events()->StartEvent($arArgs);
   }
   public function FinishEvent($iEvent,array $iarArgs=NULL) {
   $this->Events()->FinishEvent($iEvent,$iarArgs);
   }

} /*==========

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 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);

echo '

'.print_r($arIns,TRUE).'

'; die();

       $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;
   }
   /*-----
    PURPOSE: Add an action link to the menu
   */
   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;
   }
   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 = $objPage->SelfURL($arLink,TRUE);
   $isActive = is_null($iActive)?($objPage->Arg('do')==$strKey):$iActive;
   $arEntry = array(
     'type'    => 'action',
     'path'    => $wpPath,
     '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>