Search:

# CWIS Developers Documentation

- Main Page
- Classes
- Files

- File List
- File Members

# ApplicationFramework.php

Go to the documentation of this file.

    00001 <?PHP
    00002
    00003 #
    00004 #   FILE:  ApplicationFramework.php
    00005 #
    00006 #   Part of the ScoutLib application support library
    00007 #   Copyright 2009-2011 Edward Almasy and Internet Scout
    00008 #   http://scout.wisc.edu
    00009 #
    00010
    00015 class ApplicationFramework {
    00016
    00017     # ---- PUBLIC INTERFACE --------------------------------------------------
    00018  /*@(*/
    00020
    00028     function __construct($ObjectDirectories = NULL)
    00029     {
    00030         # save execution start time
    00031         $this->ExecutionStartTime = microtime(TRUE);
    00032
    00033         # save object directory search list
    00034         if ($ObjectDirectories) {  $this->AddObjectDirectories($ObjectDirectories);  }
    00035
    00036         # set up object file autoloader
    00037         $this->SetUpObjectAutoloading();
    00038
    00039         # set up function to output any buffered text in case of crash
    00040         register_shutdown_function(array($this, "OnCrash"));
    00041
    00042         # set up our internal environment
    00043         $this->DB = new Database();
    00044
    00045         # load our settings from database
    00046         $this->DB->Query("SELECT * FROM ApplicationFrameworkSettings");
    00047         $this->Settings = $this->DB->FetchRow();
    00048         if (!$this->Settings)
    00049         {
    00050             $this->DB->Query("INSERT INTO ApplicationFrameworkSettings"
    00051                     ." (LastTaskRunAt) VALUES ('2000-01-02 03:04:05')");
    00052             $this->DB->Query("SELECT * FROM ApplicationFrameworkSettings");
    00053             $this->Settings = $this->DB->FetchRow();
    00054         }
    00055
    00056         # set PHP maximum execution time
    00057         $this->MaxExecutionTime($this->Settings["MaxExecTime"]);
    00058
    00059         # register events we handle internally
    00060         $this->RegisterEvent($this->PeriodicEvents);
    00061         $this->RegisterEvent($this->UIEvents);
    00062     }
    00070     function AddObjectDirectories($Dirs)
    00071     {
    00072         foreach ($Dirs as $Location => $Prefix)
    00073         {
    00074             $Location = $Location
    00075                     .((substr($Location, -1) != "/") ? "/" : "");
    00076             self::$ObjectDirectories = array_merge(
    00077                     array($Location => $Prefix),
    00078                     self::$ObjectDirectories);
    00079         }
    00080     }
    00081
    00087     function SetBrowserDetectionFunc($DetectionFunc)
    00088     {
    00089         $this->BrowserDetectFunc = $DetectionFunc;
    00090     }
    00091
    00096     function LoadPage($PageName)
    00097     {
    00098         # buffer any output from includes or PHP file
    00099         ob_start();
    00100
    00101         # include any files needed to set up execution environment
    00102         foreach ($this->EnvIncludes as $IncludeFile)
    00103         {
    00104             include($IncludeFile);
    00105         }
    00106
    00107         # sanitize incoming page name
    00108         $PageName = preg_replace("/[^a-zA-Z0-9_.-]/", "", $PageName);
    00109
    00110         # signal page load
    00111         $this->SignalEvent("EVENT_PAGE_LOAD", array("PageName" => $PageName));
    00112
    00113         # signal PHP file load
    00114         $SignalResult = $this->SignalEvent("EVENT_PHP_FILE_LOAD", array(
    00115                 "PageName" => $PageName));
    00116
    00117         # if signal handler returned new page name value
    00118         $NewPageName = $PageName;
    00119         if (($SignalResult["PageName"] != $PageName)
    00120                 && strlen($SignalResult["PageName"]))
    00121         {
    00122             # if new page name value is page file
    00123             if (file_exists($SignalResult["PageName"]))
    00124             {
    00125                 # use new value for PHP file name
    00126                 $PageFile = $SignalResult["PageName"];
    00127             }
    00128             else
    00129             {
    00130                 # use new value for page name
    00131                 $NewPageName = $SignalResult["PageName"];
    00132             }
    00133         }
    00134
    00135         # if we do not already have a PHP file
    00136         if (!isset($PageFile))
    00137         {
    00138             # look for PHP file for page
    00139             $OurPageFile = "pages/".$NewPageName.".php";
    00140             $LocalPageFile = "local/pages/".$NewPageName.".php";
    00141             $PageFile = file_exists($LocalPageFile) ? $LocalPageFile
    00142                     : (file_exists($OurPageFile) ? $OurPageFile
    00143                     : "pages/".$this->DefaultPage.".php");
    00144         }
    00145
    00146         # load PHP file
    00147         include($PageFile);
    00148
    00149         # save buffered output to be displayed later after HTML file loads
    00150         $PageOutput = ob_get_contents();
    00151         ob_end_clean();
    00152
    00153         # set up for possible TSR (Terminate and Stay Resident :))
    00154         $ShouldTSR = $this->PrepForTSR();
    00155
    00156         # if PHP file indicated we should autorefresh to somewhere else
    00157         if ($this->JumpToPage)
    00158         {
    00159             if (!strlen(trim($PageOutput)))
    00160             {
    00161                 ?><html>
    00162                 <head>
    00163                     <meta http-equiv="refresh" content="0; URL=<?PHP
    00164                             print($this->JumpToPage);  ?>">
    00165                 </head>
    00166                 <body bgcolor="white">
    00167                 </body>
    00168                 </html><?PHP
    00169             }
    00170         }
    00171         # else if HTML loading is not suppressed
    00172         elseif (!$this->SuppressHTML)
    00173         {
    00174             # set content-type to get rid of diacritic errors
    00175             header("Content-Type: text/html; charset="
    00176                 .$this->HtmlCharset, TRUE);
    00177
    00178             # load common HTML file (defines common functions) if available
    00179             $CommonHtmlFile = $this->FindCommonTemplate("Common");
    00180             if ($CommonHtmlFile) {  include($CommonHtmlFile);  }
    00181
    00182             # load UI functions
    00183             $this->LoadUIFunctions();
    00184
    00185             # begin buffering content
    00186             ob_start();
    00187
    00188             # signal HTML file load
    00189             $SignalResult = $this->SignalEvent("EVENT_HTML_FILE_LOAD", array(
    00190                     "PageName" => $PageName));
    00191
    00192             # if signal handler returned new page name value
    00193             $NewPageName = $PageName;
    00194             $PageContentFile = NULL;
    00195             if (($SignalResult["PageName"] != $PageName)
    00196                     && strlen($SignalResult["PageName"]))
    00197             {
    00198                 # if new page name value is HTML file
    00199                 if (file_exists($SignalResult["PageName"]))
    00200                 {
    00201                     # use new value for HTML file name
    00202                     $PageContentFile = $SignalResult["PageName"];
    00203                 }
    00204                 else
    00205                 {
    00206                     # use new value for page name
    00207                     $NewPageName = $SignalResult["PageName"];
    00208                 }
    00209             }
    00210
    00211             # load page content HTML file if available
    00212             if ($PageContentFile === NULL)
    00213             {
    00214                 $PageContentFile = $this->FindTemplate(
    00215                         $this->ContentTemplateList, $NewPageName);
    00216             }
    00217             if ($PageContentFile)
    00218             {
    00219                 include($PageContentFile);
    00220             }
    00221             else
    00222             {
    00223                 print "<h2>ERROR:  No HTML/TPL template found"
    00224                         ." for this page.</h2>";
    00225             }
    00226
    00227             # signal HTML file load complete
    00228             $SignalResult = $this->SignalEvent("EVENT_HTML_FILE_LOAD_COMPLETE");
    00229
    00230             # stop buffering and save output
    00231             $PageContentOutput = ob_get_contents();
    00232             ob_end_clean();
    00233
    00234             # load page start HTML file if available
    00235             ob_start();
    00236             $PageStartFile = $this->FindCommonTemplate("Start");
    00237             if ($PageStartFile) {  include($PageStartFile);  }
    00238             $PageStartOutput = ob_get_contents();
    00239             ob_end_clean();
    00240
    00241             # load page end HTML file if available
    00242             ob_start();
    00243             $PageEndFile = $this->FindCommonTemplate("End");
    00244             if ($PageEndFile) {  include($PageEndFile);  }
    00245             $PageEndOutput = ob_get_contents();
    00246             ob_end_clean();
    00247
    00248             # get list of any required files not loaded
    00249             $RequiredFiles = $this->GetRequiredFilesNotYetLoaded($PageContentFile);
    00250
    00251             # if a browser detection function has been made available
    00252             if (is_callable($this->BrowserDetectFunc))
    00253             {
    00254                 # call function to get browser list
    00255                 $Browsers = call_user_func($this->BrowserDetectFunc);
    00256
    00257                 # for each required file
    00258                 $NewRequiredFiles = array();
    00259                 foreach ($RequiredFiles as $File)
    00260                 {
    00261                     # if file name includes browser keyword
    00262                     if (preg_match("/%BROWSER%/", $File))
    00263                     {
    00264                         # for each browser
    00265                         foreach ($Browsers as $Browser)
    00266                         {
    00267                             # substitute in browser name and add to new file list
    00268                             $NewRequiredFiles[] = preg_replace(
    00269                                     "/%BROWSER%/", $Browser, $File);
    00270                         }
    00271                     }
    00272                     else
    00273                     {
    00274                         # add to new file list
    00275                         $NewRequiredFiles[] = $File;
    00276                     }
    00277                 }
    00278                 $RequiredFiles = $NewRequiredFiles;
    00279             }
    00280
    00281             # for each required file
    00282             foreach ($RequiredFiles as $File)
    00283             {
    00284                 # locate specific file to use
    00285                 $FilePath = $this->GUIFile($File);
    00286
    00287                 # if file was found
    00288                 if ($FilePath)
    00289                 {
    00290                     # determine file type
    00291                     $NamePieces = explode(".", $File);
    00292                     $FileSuffix = strtolower(array_pop($NamePieces));
    00293
    00294                     # add file to HTML output based on file type
    00295                     $FilePath = htmlspecialchars($FilePath);
    00296                     switch ($FileSuffix)
    00297                     {
    00298                         case "js":
    00299                             $Tag = '<script type="text/javascript" src="'
    00300                                     .$FilePath.'"></script>';
    00301                             $PageEndOutput = preg_replace(
    00302                                     "#</body>#i", $Tag."\n</body>", $PageEndOutput, 1);
    00303                             break;
    00304
    00305                         case "css":
    00306                             $Tag = '<link rel="stylesheet" type="text/css"'
    00307                                     .' media="all" href="'.$FilePath.'">';
    00308                             $PageStartOutput = preg_replace(
    00309                                     "#</head>#i", $Tag."\n</head>", $PageStartOutput, 1);
    00310                             break;
    00311                     }
    00312                 }
    00313             }
    00314
    00315             # write out page
    00316             print $PageStartOutput.$PageContentOutput.$PageEndOutput;
    00317         }
    00318
    00319         # run any post-processing routines
    00320         foreach ($this->PostProcessingFuncs as $Func)
    00321         {
    00322             call_user_func_array($Func["FunctionName"], $Func["Arguments"]);
    00323         }
    00324
    00325         # write out any output buffered from page code execution
    00326         if (strlen($PageOutput))
    00327         {
    00328             if (!$this->SuppressHTML)
    00329             {
    00330                 ?><table width="100%" cellpadding="5"
    00331                         style="border: 2px solid #666666;  background: #CCCCCC;
    00332                         font-family: Courier New, Courier, monospace;
    00333                         margin-top: 10px;"><tr><td><?PHP
    00334             }
    00335             if ($this->JumpToPage)
    00336             {
    00337                 ?><div style="color: #666666;"><span style="font-size: 150%;">
    00338                 <b>Page Jump Aborted</b></span>
    00339                 (because of error or other unexpected output)<br />
    00340                 <b>Jump Target:</b>
    00341                 <i><?PHP  print($this->JumpToPage);  ?></i></div><?PHP
    00342             }
    00343             print($PageOutput);
    00344             if (!$this->SuppressHTML)
    00345             {
    00346                 ?></td></tr></table><?PHP
    00347             }
    00348         }
    00349
    00350         # terminate and stay resident (TSR!) if indicated and HTML has been output
    00351         # (only TSR if HTML has been output because otherwise browsers will misbehave)
    00352         if ($ShouldTSR) {  $this->LaunchTSR();  }
    00353     }
    00354
    00361     function SetJumpToPage($Page)
    00362     {
    00363         if ((strpos($Page, "?") === FALSE)
    00364                 && ((strpos($Page, "=") !== FALSE)
    00365                     || ((stripos($Page, ".php") === FALSE)
    00366                         && (stripos($Page, ".htm") === FALSE)
    00367                         && (strpos($Page, "/") === FALSE)))
    00368                 && (stripos($Page, "http://") !== 0)
    00369                 && (stripos($Page, "https://") !== 0))
    00370         {
    00371             $this->JumpToPage = "index.php?P=".$Page;
    00372         }
    00373         else
    00374         {
    00375             $this->JumpToPage = $Page;
    00376         }
    00377     }
    00378
    00383     function JumpToPageIsSet()
    00384     {
    00385         return ($this->JumpToPage === NULL) ? FALSE : TRUE;
    00386     }
    00387
    00397     function HtmlCharset($NewSetting = NULL)
    00398     {
    00399         if ($NewSetting !== NULL) {  $this->HtmlCharset = $NewSetting;  }
    00400         return $this->HtmlCharset;
    00401     }
    00402
    00409     function SuppressHTMLOutput($NewSetting = TRUE)
    00410     {
    00411         $this->SuppressHTML = $NewSetting;
    00412     }
    00413
    00420     function ActiveUserInterface($UIName = NULL)
    00421     {
    00422         if ($UIName !== NULL)
    00423         {
    00424             $this->ActiveUI = preg_replace("/^SPTUI--/", "", $UIName);
    00425         }
    00426         return $this->ActiveUI;
    00427     }
    00428
    00444     function AddPostProcessingCall($FunctionName,
    00445             &$Arg1 = self::NOVALUE, &$Arg2 = self::NOVALUE, &$Arg3 = self::NOVALUE,
    00446             &$Arg4 = self::NOVALUE, &$Arg5 = self::NOVALUE, &$Arg6 = self::NOVALUE,
    00447             &$Arg7 = self::NOVALUE, &$Arg8 = self::NOVALUE, &$Arg9 = self::NOVALUE)
    00448     {
    00449         $FuncIndex = count($this->PostProcessingFuncs);
    00450         $this->PostProcessingFuncs[$FuncIndex]["FunctionName"] = $FunctionName;
    00451         $this->PostProcessingFuncs[$FuncIndex]["Arguments"] = array();
    00452         $Index = 1;
    00453         while (isset(${"Arg".$Index}) && (${"Arg".$Index} !== self::NOVALUE))
    00454         {
    00455             $this->PostProcessingFuncs[$FuncIndex]["Arguments"][$Index]
    00456                     =& ${"Arg".$Index};
    00457             $Index++;
    00458         }
    00459     }
    00460
    00466     function AddEnvInclude($FileName)
    00467     {
    00468         $this->EnvIncludes[] = $FileName;
    00469     }
    00470
    00477     function GUIFile($FileName)
    00478     {
    00479         # pull off file name suffix
    00480         $NamePieces = explode(".", $FileName);
    00481         $Suffix = strtolower(array_pop($NamePieces));
    00482
    00483         # determine which location to search based on file suffix
    00484         $ImageSuffixes = array("gif", "jpg", "png");
    00485         $FileList = in_array($Suffix, $ImageSuffixes)
    00486                 ? $this->ImageFileList : $this->CommonTemplateList;
    00487
    00488         # search for file
    00489         $FoundFileName = $this->FindTemplate($FileList, $FileName);
    00490
    00491         # add non-image files to list of found files
    00492         if (!in_array($Suffix, $ImageSuffixes))
    00493                 {  $this->FoundUIFiles[] = basename($FoundFileName);  }
    00494
    00495         # return file name to caller
    00496         return $FoundFileName;
    00497     }
    00498
    00508     function PUIFile($FileName)
    00509     {
    00510         $FullFileName = $this->GUIFile($FileName);
    00511         if ($FullFileName) {  print($FullFileName);  }
    00512     }
    00513
    00518     function FindCommonTemplate($PageName)
    00519     {
    00520         return $this->FindTemplate(
    00521                 array_merge($this->CommonTemplateList, $this->ContentTemplateList),
    00522                 $PageName);
    00523     }
    00524
    00533     function LoadFunction($Callback)
    00534     {
    00535         if (!is_callable($Callback) && is_string($Callback))
    00536         {
    00537             $Locations = $this->FunctionFileList;
    00538             foreach (self::$ObjectDirectories as $Location => $Prefix)
    00539             {
    00540                 $Locations[] = $Location."%PAGENAME%.php";
    00541                 $Locations[] = $Location."%PAGENAME%.html";
    00542             }
    00543             $FunctionFileName = $this->FindTemplate($Locations, "F-".$Callback);
    00544             if ($FunctionFileName)
    00545             {
    00546                 include_once($FunctionFileName);
    00547             }
    00548         }
    00549         return is_callable($Callback);
    00550     }
    00551
    00556     function GetElapsedExecutionTime()
    00557     {
    00558         return microtime(TRUE) - $this->ExecutionStartTime;
    00559     }
    00560
    00565     function GetSecondsBeforeTimeout()
    00566     {
    00567         return ini_get("max_execution_time") - $this->GetElapsedExecutionTime();
    00568     }
    00569
    00570     /*@)*/ /* Application Framework */
    00571
    00572     # ---- Event Handling ----------------------------------------------------
    00573  /*@(*/
    00575
    00579     const EVENTTYPE_DEFAULT = 1;
    00585     const EVENTTYPE_CHAIN = 2;
    00591     const EVENTTYPE_FIRST = 3;
    00599     const EVENTTYPE_NAMED = 4;
    00600
    00602     const ORDER_FIRST = 1;
    00604     const ORDER_MIDDLE = 2;
    00606     const ORDER_LAST = 3;
    00607
    00616     function RegisterEvent($EventsOrEventName, $EventType = NULL)
    00617     {
    00618         # convert parameters to array if not already in that form
    00619         $Events = is_array($EventsOrEventName) ? $EventsOrEventName
    00620                 : array($EventsOrEventName => $Type);
    00621
    00622         # for each event
    00623         foreach ($Events as $Name => $Type)
    00624         {
    00625             # store event information
    00626             $this->RegisteredEvents[$Name]["Type"] = $Type;
    00627             $this->RegisteredEvents[$Name]["Hooks"] = array();
    00628         }
    00629     }
    00630
    00644     function HookEvent($EventsOrEventName, $Callback = NULL, $Order = self::ORDER_MIDDLE)
    00645     {
    00646         # convert parameters to array if not already in that form
    00647         $Events = is_array($EventsOrEventName) ? $EventsOrEventName
    00648                 : array($EventsOrEventName => $Callback);
    00649
    00650         # for each event
    00651         $Success = TRUE;
    00652         foreach ($Events as $EventName => $EventCallback)
    00653         {
    00654             # if callback is valid
    00655             if (is_callable($EventCallback))
    00656             {
    00657                 # if this is a periodic event we process internally
    00658                 if (isset($this->PeriodicEvents[$EventName]))
    00659                 {
    00660                     # process event now
    00661                     $this->ProcessPeriodicEvent($EventName, $EventCallback);
    00662                 }
    00663                 # if specified event has been registered
    00664                 elseif (isset($this->RegisteredEvents[$EventName]))
    00665                 {
    00666                     # add callback for event
    00667                     $this->RegisteredEvents[$EventName]["Hooks"][]
    00668                             = array("Callback" => $EventCallback, "Order" => $Order);
    00669
    00670                     # sort callbacks by order
    00671                     if (count($this->RegisteredEvents[$EventName]["Hooks"]) > 1)
    00672                     {
    00673                         usort($this->RegisteredEvents[$EventName]["Hooks"],
    00674                                 array("ApplicationFramework", "HookEvent_OrderCompare"));
    00675                     }
    00676                 }
    00677                 else
    00678                 {
    00679                     $Success = FALSE;
    00680                 }
    00681             }
    00682             else
    00683             {
    00684                 $Success = FALSE;
    00685             }
    00686         }
    00687
    00688         # report to caller whether all callbacks were hooked
    00689         return $Success;
    00690     }
    00691     private static function HookEvent_OrderCompare($A, $B)
    00692     {
    00693         if ($A["Order"] == $B["Order"]) {  return 0;  }
    00694         return ($A["Order"] < $B["Order"]) ? -1 : 1;
    00695     }
    00696
    00705     function SignalEvent($EventName, $Parameters = NULL)
    00706     {
    00707         $ReturnValue = NULL;
    00708
    00709         # if event has been registered
    00710         if (isset($this->RegisteredEvents[$EventName]))
    00711         {
    00712             # set up default return value (if not NULL)
    00713             switch ($this->RegisteredEvents[$EventName]["Type"])
    00714             {
    00715                 case self::EVENTTYPE_CHAIN:
    00716                     $ReturnValue = $Parameters;
    00717                     break;
    00718
    00719                 case self::EVENTTYPE_NAMED:
    00720                     $ReturnValue = array();
    00721                     break;
    00722             }
    00723
    00724             # for each callback for this event
    00725             foreach ($this->RegisteredEvents[$EventName]["Hooks"] as $Hook)
    00726             {
    00727                 # invoke callback
    00728                 $Callback = $Hook["Callback"];
    00729                 $Result = ($Parameters !== NULL)
    00730                         ? call_user_func_array($Callback, $Parameters)
    00731                         : call_user_func($Callback);
    00732
    00733                 # process return value based on event type
    00734                 switch ($this->RegisteredEvents[$EventName]["Type"])
    00735                 {
    00736                     case self::EVENTTYPE_CHAIN:
    00737                         $ReturnValue = $Result;
    00738                         $Parameters = $Result;
    00739                         break;
    00740
    00741                     case self::EVENTTYPE_FIRST:
    00742                         if ($Result !== NULL)
    00743                         {
    00744                             $ReturnValue = $Result;
    00745                             break 2;
    00746                         }
    00747                         break;
    00748
    00749                     case self::EVENTTYPE_NAMED:
    00750                         $CallbackName = is_array($Callback)
    00751                                 ? (is_object($Callback[0])
    00752                                         ? get_class($Callback[0])
    00753                                         : $Callback[0])."::".$Callback[1]
    00754                                 : $Callback;
    00755                         $ReturnValue[$CallbackName] = $Result;
    00756                         break;
    00757
    00758                     default:
    00759                         break;
    00760                 }
    00761             }
    00762         }
    00763
    00764         # return value if any to caller
    00765         return $ReturnValue;
    00766     }
    00767
    00773     function IsStaticOnlyEvent($EventName)
    00774     {
    00775         return isset($this->PeriodicEvents[$EventName]) ? TRUE : FALSE;
    00776     }
    00777
    00778     /*@)*/ /* Event Handling */
    00779
    00780     # ---- Task Management ---------------------------------------------------
    00781  /*@(*/
    00783
    00785     const PRIORITY_HIGH = 1;
    00787     const PRIORITY_MEDIUM = 2;
    00789     const PRIORITY_LOW = 3;
    00791     const PRIORITY_BACKGROUND = 4;
    00792
    00805     function QueueTask($Callback, $Parameters = NULL,
    00806             $Priority = self::PRIORITY_MEDIUM, $Description = "")
    00807     {
    00808         # pack task info and write to database
    00809         if ($Parameters === NULL) {  $Parameters = array();  }
    00810         $this->DB->Query("INSERT INTO TaskQueue"
    00811                 ." (Callback, Parameters, Priority, Description)"
    00812                 ." VALUES ('".addslashes(serialize($Callback))."', '"
    00813                 .addslashes(serialize($Parameters))."', ".intval($Priority).", '"
    00814                 .addslashes($Description)."')");
    00815     }
    00816
    00834     function QueueUniqueTask($Callback, $Parameters = NULL,
    00835             $Priority = self::PRIORITY_MEDIUM, $Description = "")
    00836     {
    00837         if ($this->TaskIsInQueue($Callback, $Parameters))
    00838         {
    00839             $QueryResult = $this->DB->Query("SELECT TaskId,Priority FROM TaskQueue"
    00840                     ." WHERE Callback = '".addslashes(serialize($Callback))."'"
    00841                     .($Parameters ? " AND Parameters = '"
    00842                             .addslashes(serialize($Parameters))."'" : ""));
    00843             if ($QueryResult !== FALSE)
    00844             {
    00845                 $Record = $this->DB->FetchRow();
    00846                 if ($Record["Priority"] > $Priority)
    00847                 {
    00848                     $this->DB->Query("UPDATE TaskQueue"
    00849                             ." SET Priority = ".intval($Priority)
    00850                             ." WHERE TaskId = ".intval($Record["TaskId"]));
    00851                 }
    00852             }
    00853             return FALSE;
    00854         }
    00855         else
    00856         {
    00857             $this->QueueTask($Callback, $Parameters, $Priority, $Description);
    00858             return TRUE;
    00859         }
    00860     }
    00861
    00871     function TaskIsInQueue($Callback, $Parameters = NULL)
    00872     {
    00873         $FoundCount = $this->DB->Query("SELECT COUNT(*) AS FoundCount FROM TaskQueue"
    00874                 ." WHERE Callback = '".addslashes(serialize($Callback))."'"
    00875                 .($Parameters ? " AND Parameters = '"
    00876                         .addslashes(serialize($Parameters))."'" : ""),
    00877                 "FoundCount")
    00878                 + $this->DB->Query("SELECT COUNT(*) AS FoundCount FROM RunningTasks"
    00879                 ." WHERE Callback = '".addslashes(serialize($Callback))."'"
    00880                 .($Parameters ? " AND Parameters = '"
    00881                         .addslashes(serialize($Parameters))."'" : ""),
    00882                 "FoundCount");
    00883         return ($FoundCount ? TRUE : FALSE);
    00884     }
    00885
    00891     function GetTaskQueueSize($Priority = NULL)
    00892     {
    00893         return $this->DB->Query("SELECT COUNT(*) AS QueueSize FROM TaskQueue"
    00894                 .($Priority ? " WHERE Priority = ".intval($Priority) : ""),
    00895                 "QueueSize");
    00896     }
    00897
    00905     function GetQueuedTaskList($Count = 100, $Offset = 0)
    00906     {
    00907         return $this->GetTaskList("SELECT * FROM TaskQueue"
    00908                 ." ORDER BY Priority, TaskId ", $Count, $Offset);
    00909     }
    00910
    00918     function GetRunningTaskList($Count = 100, $Offset = 0)
    00919     {
    00920         return $this->GetTaskList("SELECT * FROM RunningTasks"
    00921                 ." WHERE StartedAt >= '".date("Y-m-d H:i:s",
    00922                         (time() - ini_get("max_execution_time")))."'"
    00923                 ." ORDER BY StartedAt", $Count, $Offset);
    00924     }
    00925
    00933     function GetOrphanedTaskList($Count = 100, $Offset = 0)
    00934     {
    00935         return $this->GetTaskList("SELECT * FROM RunningTasks"
    00936                 ." WHERE StartedAt < '".date("Y-m-d H:i:s",
    00937                         (time() - ini_get("max_execution_time")))."'"
    00938                 ." ORDER BY StartedAt", $Count, $Offset);
    00939     }
    00940
    00945     function ReQueueOrphanedTask($TaskId)
    00946     {
    00947         $this->DB->Query("LOCK TABLES TaskQueue WRITE, RunningTasks WRITE");
    00948         $this->DB->Query("INSERT INTO TaskQueue"
    00949                          ." (Callback,Parameters,Priority,Description) "
    00950                          ."SELECT Callback, Parameters, Priority, Description"
    00951                          ." FROM RunningTasks WHERE TaskId = ".intval($TaskId));
    00952         $this->DB->Query("DELETE FROM RunningTasks WHERE TaskId = ".intval($TaskId));
    00953         $this->DB->Query("UNLOCK TABLES");
    00954     }
    00955
    00960     function DeleteTask($TaskId)
    00961     {
    00962         $this->DB->Query("DELETE FROM TaskQueue WHERE TaskId = ".intval($TaskId));
    00963         $this->DB->Query("DELETE FROM RunningTasks WHERE TaskId = ".intval($TaskId));
    00964     }
    00965
    00973     function GetTask($TaskId)
    00974     {
    00975         # assume task will not be found
    00976         $Task = NULL;
    00977
    00978         # look for task in task queue
    00979         $this->DB->Query("SELECT * FROM TaskQueue WHERE TaskId = ".intval($TaskId));
    00980
    00981         # if task was not found in queue
    00982         if (!$this->DB->NumRowsSelected())
    00983         {
    00984             # look for task in running task list
    00985             $this->DB->Query("SELECT * FROM RunningTasks WHERE TaskId = "
    00986                     .intval($TaskId));
    00987         }
    00988
    00989         # if task was found
    00990         if ($this->DB->NumRowsSelected())
    00991         {
    00992             # if task was periodic
    00993             $Row = $this->DB->FetchRow();
    00994             if ($Row["Callback"] ==
    00995                     serialize(array("ApplicationFramework", "PeriodicEventWrapper")))
    00996             {
    00997                 # unpack periodic task callback
    00998                 $WrappedCallback = unserialize($Row["Parameters"]);
    00999                 $Task["Callback"] = $WrappedCallback[1];
    01000                 $Task["Parameters"] = NULL;
    01001             }
    01002             else
    01003             {
    01004                 # unpack task callback and parameters
    01005                 $Task["Callback"] = unserialize($Row["Callback"]);
    01006                 $Task["Parameters"] = unserialize($Row["Parameters"]);
    01007             }
    01008         }
    01009
    01010         # return task to caller
    01011         return $Task;
    01012     }
    01013
    01019     function MaxTasks($NewValue = NULL)
    01020     {
    01021         if (func_num_args() && ($NewValue >= 1))
    01022         {
    01023             $this->DB->Query("UPDATE ApplicationFrameworkSettings"
    01024                     ." SET MaxTasksRunning = '".intval($NewValue)."'");
    01025             $this->Settings["MaxTasksRunning"] = intval($NewValue);
    01026         }
    01027         return $this->Settings["MaxTasksRunning"];
    01028     }
    01029
    01037     function MaxExecutionTime($NewValue = NULL)
    01038     {
    01039         if (func_num_args() && !ini_get("safe_mode"))
    01040         {
    01041             if ($NewValue != $this->Settings["MaxExecTime"])
    01042             {
    01043                 $this->Settings["MaxExecTime"] = max($NewValue, 5);
    01044                 $this->DB->Query("UPDATE ApplicationFrameworkSettings"
    01045                         ." SET MaxExecTime = '"
    01046                                 .intval($this->Settings["MaxExecTime"])."'");
    01047             }
    01048             ini_set("max_execution_time", $this->Settings["MaxExecTime"]);
    01049             set_time_limit($this->Settings["MaxExecTime"]);
    01050         }
    01051         return ini_get("max_execution_time");
    01052     }
    01053
    01054     /*@)*/ /* Task Management */
    01055
    01056     # ---- PRIVATE INTERFACE -------------------------------------------------
    01057
    01058     private $ActiveUI = "default";
    01059     private $BrowserDetectFunc;
    01060     private $DB;
    01061     private $DefaultPage = "Home";
    01062     private $EnvIncludes = array();
    01063     private $ExecutionStartTime;
    01064     private $FoundUIFiles = array();
    01065     private $HtmlCharset = "UTF-8";
    01066     private $JumpToPage = NULL;
    01067     private $MaxRunningTasksToTrack = 250;
    01068     private static $ObjectDirectories = array();
    01069     private $PostProcessingFuncs = array();
    01070     private $RunningTask;
    01071     private $Settings;
    01072     private $SuppressHTML = FALSE;
    01073
    01074     # set to TRUE to not close browser connection before running background tasks
    01075     private $NoTSR = FALSE;
    01076
    01077     private $PeriodicEvents = array(
    01078                 "EVENT_HOURLY" => self::EVENTTYPE_DEFAULT,
    01079                 "EVENT_DAILY" => self::EVENTTYPE_DEFAULT,
    01080                 "EVENT_WEEKLY" => self::EVENTTYPE_DEFAULT,
    01081                 "EVENT_MONTHLY" => self::EVENTTYPE_DEFAULT,
    01082                 "EVENT_PERIODIC" => self::EVENTTYPE_NAMED,
    01083                 );
    01084     private $UIEvents = array(
    01085                 "EVENT_PAGE_LOAD" => self::EVENTTYPE_DEFAULT,
    01086                 "EVENT_PHP_FILE_LOAD" => self::EVENTTYPE_CHAIN,
    01087                 "EVENT_HTML_FILE_LOAD" => self::EVENTTYPE_CHAIN,
    01088                 "EVENT_HTML_FILE_LOAD_COMPLETE" => self::EVENTTYPE_DEFAULT,
    01089                 );
    01090
    01091     private function FindTemplate($FileList, $PageName)
    01092     {
    01093         $FileNameFound = NULL;
    01094         foreach ($FileList as $FileName)
    01095         {
    01096             $FileName = str_replace("%ACTIVEUI%", $this->ActiveUI, $FileName);
    01097             $FileName = str_replace("%PAGENAME%", $PageName, $FileName);
    01098             if (file_exists($FileName))
    01099             {
    01100                 $FileNameFound = $FileName;
    01101                 break;
    01102             }
    01103         }
    01104         return $FileNameFound;
    01105     }
    01106
    01113     private function GetRequiredFilesNotYetLoaded($PageContentFile)
    01114     {
    01115         # start out assuming no files required
    01116         $RequiredFiles = array();
    01117
    01118         # if page content file supplied
    01119         if ($PageContentFile)
    01120         {
    01121             # if file containing list of required files is available
    01122             $Path = dirname($PageContentFile);
    01123             $RequireListFile = $Path."/REQUIRES";
    01124             if (file_exists($RequireListFile))
    01125             {
    01126                 # read in list of required files
    01127                 $RequestedFiles = file($RequireListFile);
    01128
    01129                 # for each line in required file list
    01130                 foreach ($RequestedFiles as $Line)
    01131                 {
    01132                     # if line is not a comment
    01133                     $Line = trim($Line);
    01134                     if (!preg_match("/^#/", $Line))
    01135                     {
    01136                         # if file has not already been loaded
    01137                         if (!in_array($Line, $this->FoundUIFiles))
    01138                         {
    01139                             # add to list of required files
    01140                             $RequiredFiles[] = $Line;
    01141                         }
    01142                     }
    01143                 }
    01144             }
    01145         }
    01146
    01147         # return list of required files to caller
    01148         return $RequiredFiles;
    01149     }
    01150
    01151     private function SetUpObjectAutoloading()
    01152     {
    01153         function __autoload($ClassName)
    01154         {
    01155             ApplicationFramework::AutoloadObjects($ClassName);
    01156         }
    01157     }
    01158
    01160     static function AutoloadObjects($ClassName)
    01161     {
    01162         foreach (self::$ObjectDirectories as $Location => $Prefix)
    01163         {
    01164             $FileName = $Location.$Prefix.$ClassName.".php";
    01165             if (file_exists($FileName))
    01166             {
    01167                 require_once($FileName);
    01168                 break;
    01169             }
    01170         }
    01171     }
    01174     private function LoadUIFunctions()
    01175     {
    01176         $Dirs = array(
    01177                 "local/interface/%ACTIVEUI%/include",
    01178                 "interface/%ACTIVEUI%/include",
    01179                 "local/interface/default/include",
    01180                 "interface/default/include",
    01181                 );
    01182         foreach ($Dirs as $Dir)
    01183         {
    01184             $Dir = str_replace("%ACTIVEUI%", $this->ActiveUI, $Dir);
    01185             if (is_dir($Dir))
    01186             {
    01187                 $FileNames = scandir($Dir);
    01188                 foreach ($FileNames as $FileName)
    01189                 {
    01190                     if (preg_match("/^F-([A-Za-z_]+)\.php/", $FileName, $Matches)
    01191                             || preg_match("/^F-([A-Za-z_]+)\.html/", $FileName, $Matches))
    01192                     {
    01193                         if (!function_exists($Matches[1]))
    01194                         {
    01195                             include_once($Dir."/".$FileName);
    01196                         }
    01197                     }
    01198                 }
    01199             }
    01200         }
    01201     }
    01202
    01203     private function ProcessPeriodicEvent($EventName, $Callback)
    01204     {
    01205         # retrieve last execution time for event if available
    01206         $Signature = self::GetCallbackSignature($Callback);
    01207         $LastRun = $this->DB->Query("SELECT LastRunAt FROM PeriodicEvents"
    01208                 ." WHERE Signature = '".addslashes($Signature)."'", "LastRunAt");
    01209
    01210         # determine whether enough time has passed for event to execute
    01211         $EventPeriods = array(
    01212                 "EVENT_HOURLY" => 60*60,
    01213                 "EVENT_DAILY" => 60*60*24,
    01214                 "EVENT_WEEKLY" => 60*60*24*7,
    01215                 "EVENT_MONTHLY" => 60*60*24*30,
    01216                 "EVENT_PERIODIC" => 0,
    01217                 );
    01218         $ShouldExecute = (($LastRun === NULL)
    01219                 || (time() > (strtotime($LastRun) + $EventPeriods[$EventName])))
    01220                 ? TRUE : FALSE;
    01221
    01222         # if event should run
    01223         if ($ShouldExecute)
    01224         {
    01225             # add event to task queue
    01226             $WrapperCallback = array("ApplicationFramework", "PeriodicEventWrapper");
    01227             $WrapperParameters = array(
    01228                     $EventName, $Callback, array("LastRunAt" => $LastRun));
    01229             $this->QueueUniqueTask($WrapperCallback, $WrapperParameters);
    01230         }
    01231     }
    01232
    01233     private static function PeriodicEventWrapper($EventName, $Callback, $Parameters)
    01234     {
    01235         static $DB;
    01236         if (!isset($DB)) {  $DB = new Database();  }
    01237
    01238         # run event
    01239         $ReturnVal = call_user_func_array($Callback, $Parameters);
    01240
    01241         # if event is already in database
    01242         $Signature = self::GetCallbackSignature($Callback);
    01243         if ($DB->Query("SELECT COUNT(*) AS EventCount FROM PeriodicEvents"
    01244                 ." WHERE Signature = '".addslashes($Signature)."'", "EventCount"))
    01245         {
    01246             # update last run time for event
    01247             $DB->Query("UPDATE PeriodicEvents SET LastRunAt = "
    01248                     .(($EventName == "EVENT_PERIODIC")
    01249                             ? "'".date("Y-m-d H:i:s", time() + ($ReturnVal * 60))."'"
    01250                             : "NOW()")
    01251                     ." WHERE Signature = '".addslashes($Signature)."'");
    01252         }
    01253         else
    01254         {
    01255             # add last run time for event to database
    01256             $DB->Query("INSERT INTO PeriodicEvents (Signature, LastRunAt) VALUES "
    01257                     ."('".addslashes($Signature)."', "
    01258                     .(($EventName == "EVENT_PERIODIC")
    01259                             ? "'".date("Y-m-d H:i:s", time() + ($ReturnVal * 60))."'"
    01260                             : "NOW()").")");
    01261         }
    01262     }
    01263
    01264     private static function GetCallbackSignature($Callback)
    01265     {
    01266         return !is_array($Callback) ? $Callback
    01267                 : (is_object($Callback[0]) ? md5(serialize($Callback[0])) : $Callback[0])
    01268                         ."::".$Callback[1];
    01269     }
    01270
    01271     private function PrepForTSR()
    01272     {
    01273         # if HTML has been output and it's time to launch another task
    01274         # (only TSR if HTML has been output because otherwise browsers
    01275         #       may misbehave after connection is closed)
    01276         if (($this->JumpToPage || !$this->SuppressHTML)
    01277                 && (time() > (strtotime($this->Settings["LastTaskRunAt"])
    01278                         + (ini_get("max_execution_time")
    01279                                 / $this->Settings["MaxTasksRunning"]) + 5))
    01280                 && $this->GetTaskQueueSize())
    01281         {
    01282             # begin buffering output for TSR
    01283             ob_start();
    01284
    01285             # let caller know it is time to launch another task
    01286             return TRUE;
    01287         }
    01288         else
    01289         {
    01290             # let caller know it is not time to launch another task
    01291             return FALSE;
    01292         }
    01293     }
    01294
    01295     private function LaunchTSR()
    01296     {
    01297         # set needed headers and
    01298         if (!$this->NoTSR)
    01299         {
    01300             ignore_user_abort(TRUE);
    01301             header("Connection: close");
    01302             header("Content-Length: ".ob_get_length());
    01303         }
    01304
    01305         # output buffered content
    01306         ob_end_flush();
    01307         flush();
    01308
    01309         # write out any outstanding data and end HTTP session
    01310         session_write_close();
    01311
    01312         # if there is still a task in the queue
    01313         if ($this->GetTaskQueueSize())
    01314         {
    01315             # turn on output buffering to (hopefully) record any crash output
    01316             ob_start();
    01317
    01318             # lock tables and grab last task run time to double check
    01319             $this->DB->Query("LOCK TABLES ApplicationFrameworkSettings WRITE");
    01320             $this->DB->Query("SELECT * FROM ApplicationFrameworkSettings");
    01321             $this->Settings = $this->DB->FetchRow();
    01322
    01323             # if still time to launch another task
    01324             if (time() > (strtotime($this->Settings["LastTaskRunAt"])
    01325                         + (ini_get("max_execution_time")
    01326                                 / $this->Settings["MaxTasksRunning"]) + 5))
    01327             {
    01328                 # update the "last run" time and release tables
    01329                 $this->DB->Query("UPDATE ApplicationFrameworkSettings"
    01330                         ." SET LastTaskRunAt = '".date("Y-m-d H:i:s")."'");
    01331                 $this->DB->Query("UNLOCK TABLES");
    01332
    01333                 # run tasks while there is a task in the queue and enough time left
    01334                 do
    01335                 {
    01336                     # run the next task
    01337                     $this->RunNextTask();
    01338                 }
    01339                 while ($this->GetTaskQueueSize()
    01340                         && ($this->GetSecondsBeforeTimeout() > 65));
    01341             }
    01342             else
    01343             {
    01344                 # release tables
    01345                 $this->DB->Query("UNLOCK TABLES");
    01346             }
    01347         }
    01348     }
    01349
    01357     private function GetTaskList($DBQuery, $Count, $Offset)
    01358     {
    01359         $this->DB->Query($DBQuery." LIMIT ".intval($Offset).",".intval($Count));
    01360         $Tasks = array();
    01361         while ($Row = $this->DB->FetchRow())
    01362         {
    01363             $Tasks[$Row["TaskId"]] = $Row;
    01364             if ($Row["Callback"] ==
    01365                     serialize(array("ApplicationFramework", "PeriodicEventWrapper")))
    01366             {
    01367                 $WrappedCallback = unserialize($Row["Parameters"]);
    01368                 $Tasks[$Row["TaskId"]]["Callback"] = $WrappedCallback[1];
    01369                 $Tasks[$Row["TaskId"]]["Parameters"] = NULL;
    01370             }
    01371             else
    01372             {
    01373                 $Tasks[$Row["TaskId"]]["Callback"] = unserialize($Row["Callback"]);
    01374                 $Tasks[$Row["TaskId"]]["Parameters"] = unserialize($Row["Parameters"]);
    01375             }
    01376         }
    01377         return $Tasks;
    01378     }
    01379
    01383     private function RunNextTask()
    01384     {
    01385         # look for task at head of queue
    01386         $this->DB->Query("SELECT * FROM TaskQueue ORDER BY Priority, TaskId LIMIT 1");
    01387         $Task = $this->DB->FetchRow();
    01388
    01389         # if there was a task available
    01390         if ($Task)
    01391         {
    01392             # move task from queue to running tasks list
    01393             $this->DB->Query("INSERT INTO RunningTasks "
    01394                              ."(TaskId,Callback,Parameters,Priority,Description) "
    01395                              ."SELECT * FROM TaskQueue WHERE TaskId = "
    01396                                     .intval($Task["TaskId"]));
    01397             $this->DB->Query("DELETE FROM TaskQueue WHERE TaskId = "
    01398                     .intval($Task["TaskId"]));
    01399
    01400             # unpack stored task info
    01401             $Callback = unserialize($Task["Callback"]);
    01402             $Parameters = unserialize($Task["Parameters"]);
    01403
    01404             # attempt to load task callback if not already available
    01405             $this->LoadFunction($Callback);
    01406
    01407             # run task
    01408             $this->RunningTask = $Task;
    01409             if ($Parameters)
    01410             {
    01411                 call_user_func_array($Callback, $Parameters);
    01412             }
    01413             else
    01414             {
    01415                 call_user_func($Callback);
    01416             }
    01417             unset($this->RunningTask);
    01418
    01419             # remove task from running tasks list
    01420             $this->DB->Query("DELETE FROM RunningTasks"
    01421                     ." WHERE TaskId = ".intval($Task["TaskId"]));
    01422
    01423             # prune running tasks list if necessary
    01424             $RunningTasksCount = $this->DB->Query(
    01425                     "SELECT COUNT(*) AS TaskCount FROM RunningTasks", "TaskCount");
    01426             if ($RunningTasksCount > $this->MaxRunningTasksToTrack)
    01427             {
    01428                 $this->DB->Query("DELETE FROM RunningTasks ORDER BY StartedAt"
    01429                         ." LIMIT ".($RunningTasksCount - $this->MaxRunningTasksToTrack));
    01430             }
    01431         }
    01432     }
    01433
    01439     function OnCrash()
    01440     {
    01441         if (isset($this->RunningTask))
    01442         {
    01443             if (function_exists("error_get_last"))
    01444             {
    01445                 $CrashInfo["LastError"] = error_get_last();
    01446             }
    01447             if (ob_get_length() !== FALSE)
    01448             {
    01449                 $CrashInfo["OutputBuffer"] = ob_get_contents();
    01450             }
    01451             if (isset($CrashInfo))
    01452             {
    01453                 $DB = new Database();
    01454                 $DB->Query("UPDATE RunningTasks SET CrashInfo = '"
    01455                         .addslashes(serialize($CrashInfo))
    01456                         ."' WHERE TaskId = ".intval($this->RunningTask["TaskId"]));
    01457             }
    01458         }
    01459
    01460         print("\n");
    01461         return;
    01462
    01463         if (ob_get_length() !== FALSE)
    01464         {
    01465             ?>
    01466             <table width="100%" cellpadding="5" style="border: 2px solid #666666;  background: #FFCCCC;  font-family: Courier New, Courier, monospace;  margin-top: 10px;  font-weight: bold;"><tr><td>
    01467             <div style="font-size: 200%;">CRASH OUTPUT</div><?PHP
    01468             ob_end_flush();
    01469             ?></td></tr></table><?PHP
    01470         }
    01471     }
    01472
    01473     private $CommonTemplateList = array(
    01474             "local/interface/%ACTIVEUI%/include/StdPage%PAGENAME%.tpl",
    01475             "local/interface/%ACTIVEUI%/include/StdPage%PAGENAME%.html",
    01476             "local/interface/%ACTIVEUI%/include/%PAGENAME%.tpl",
    01477             "local/interface/%ACTIVEUI%/include/%PAGENAME%.html",
    01478             "local/interface/%ACTIVEUI%/include/SPT--StandardPage%PAGENAME%.tpl",
    01479             "local/interface/%ACTIVEUI%/include/SPT--StandardPage%PAGENAME%.html",
    01480             "local/interface/%ACTIVEUI%/include/SPT--%PAGENAME%.tpl",
    01481             "local/interface/%ACTIVEUI%/include/SPT--%PAGENAME%.html",
    01482             "local/interface/%ACTIVEUI%/include/%PAGENAME%",
    01483             "interface/%ACTIVEUI%/include/StdPage%PAGENAME%.tpl",
    01484             "interface/%ACTIVEUI%/include/StdPage%PAGENAME%.html",
    01485             "interface/%ACTIVEUI%/include/%PAGENAME%.tpl",
    01486             "interface/%ACTIVEUI%/include/%PAGENAME%.html",
    01487             "interface/%ACTIVEUI%/include/SPT--StandardPage%PAGENAME%.tpl",
    01488             "interface/%ACTIVEUI%/include/SPT--StandardPage%PAGENAME%.html",
    01489             "interface/%ACTIVEUI%/include/SPT--%PAGENAME%.tpl",
    01490             "interface/%ACTIVEUI%/include/SPT--%PAGENAME%.html",
    01491             "interface/%ACTIVEUI%/include/%PAGENAME%",
    01492             "SPTUI--%ACTIVEUI%/include/StdPage%PAGENAME%.tpl",
    01493             "SPTUI--%ACTIVEUI%/include/StdPage%PAGENAME%.html",
    01494             "SPTUI--%ACTIVEUI%/include/%PAGENAME%.tpl",
    01495             "SPTUI--%ACTIVEUI%/include/%PAGENAME%.html",
    01496             "SPTUI--%ACTIVEUI%/include/SPT--StandardPage%PAGENAME%.tpl",
    01497             "SPTUI--%ACTIVEUI%/include/SPT--StandardPage%PAGENAME%.html",
    01498             "SPTUI--%ACTIVEUI%/include/SPT--%PAGENAME%.tpl",
    01499             "SPTUI--%ACTIVEUI%/include/SPT--%PAGENAME%.html",
    01500             "SPTUI--%ACTIVEUI%/include/%PAGENAME%",
    01501             "%ACTIVEUI%/include/StdPage%PAGENAME%.tpl",
    01502             "%ACTIVEUI%/include/StdPage%PAGENAME%.html",
    01503             "%ACTIVEUI%/include/%PAGENAME%.tpl",
    01504             "%ACTIVEUI%/include/%PAGENAME%.html",
    01505             "%ACTIVEUI%/include/SPT--StandardPage%PAGENAME%.tpl",
    01506             "%ACTIVEUI%/include/SPT--StandardPage%PAGENAME%.html",
    01507             "%ACTIVEUI%/include/SPT--%PAGENAME%.tpl",
    01508             "%ACTIVEUI%/include/SPT--%PAGENAME%.html",
    01509             "%ACTIVEUI%/include/%PAGENAME%",
    01510             "local/interface/default/include/StdPage%PAGENAME%.tpl",
    01511             "local/interface/default/include/StdPage%PAGENAME%.html",
    01512             "local/interface/default/include/%PAGENAME%.tpl",
    01513             "local/interface/default/include/%PAGENAME%.html",
    01514             "local/interface/default/include/SPT--StandardPage%PAGENAME%.tpl",
    01515             "local/interface/default/include/SPT--StandardPage%PAGENAME%.html",
    01516             "local/interface/default/include/SPT--%PAGENAME%.tpl",
    01517             "local/interface/default/include/SPT--%PAGENAME%.html",
    01518             "local/interface/default/include/%PAGENAME%",
    01519             "interface/default/include/StdPage%PAGENAME%.tpl",
    01520             "interface/default/include/StdPage%PAGENAME%.html",
    01521             "interface/default/include/%PAGENAME%.tpl",
    01522             "interface/default/include/%PAGENAME%.html",
    01523             "interface/default/include/SPT--StandardPage%PAGENAME%.tpl",
    01524             "interface/default/include/SPT--StandardPage%PAGENAME%.html",
    01525             "interface/default/include/SPT--%PAGENAME%.tpl",
    01526             "interface/default/include/SPT--%PAGENAME%.html",
    01527             "interface/default/include/%PAGENAME%",
    01528             );
    01529     private $ContentTemplateList = array(
    01530             "local/interface/%ACTIVEUI%/%PAGENAME%.tpl",
    01531             "local/interface/%ACTIVEUI%/%PAGENAME%.html",
    01532             "local/interface/%ACTIVEUI%/SPT--%PAGENAME%.tpl",
    01533             "local/interface/%ACTIVEUI%/SPT--%PAGENAME%.html",
    01534             "interface/%ACTIVEUI%/%PAGENAME%.tpl",
    01535             "interface/%ACTIVEUI%/%PAGENAME%.html",
    01536             "interface/%ACTIVEUI%/SPT--%PAGENAME%.tpl",
    01537             "interface/%ACTIVEUI%/SPT--%PAGENAME%.html",
    01538             "SPTUI--%ACTIVEUI%/%PAGENAME%.tpl",
    01539             "SPTUI--%ACTIVEUI%/%PAGENAME%.html",
    01540             "SPTUI--%ACTIVEUI%/SPT--%PAGENAME%.tpl",
    01541             "SPTUI--%ACTIVEUI%/SPT--%PAGENAME%.html",
    01542             "%ACTIVEUI%/%PAGENAME%.tpl",
    01543             "%ACTIVEUI%/%PAGENAME%.html",
    01544             "%ACTIVEUI%/SPT--%PAGENAME%.tpl",
    01545             "%ACTIVEUI%/SPT--%PAGENAME%.html",
    01546             "local/interface/default/%PAGENAME%.tpl",
    01547             "local/interface/default/%PAGENAME%.html",
    01548             "local/interface/default/SPT--%PAGENAME%.tpl",
    01549             "local/interface/default/SPT--%PAGENAME%.html",
    01550             "interface/default/%PAGENAME%.tpl",
    01551             "interface/default/%PAGENAME%.html",
    01552             "interface/default/SPT--%PAGENAME%.tpl",
    01553             "interface/default/SPT--%PAGENAME%.html",
    01554             );
    01555     private $ImageFileList = array(
    01556             "local/interface/%ACTIVEUI%/images/%PAGENAME%",
    01557             "interface/%ACTIVEUI%/images/%PAGENAME%",
    01558             "SPTUI--%ACTIVEUI%/images/%PAGENAME%",
    01559             "%ACTIVEUI%/images/%PAGENAME%",
    01560             "local/interface/default/images/%PAGENAME%",
    01561             "interface/default/images/%PAGENAME%",
    01562             );
    01563     private $FunctionFileList = array(
    01564             "local/interface/%ACTIVEUI%/include/%PAGENAME%.php",
    01565             "local/interface/%ACTIVEUI%/include/%PAGENAME%.html",
    01566             "interface/%ACTIVEUI%/include/%PAGENAME%.php",
    01567             "interface/%ACTIVEUI%/include/%PAGENAME%.html",
    01568             "SPTUI--%ACTIVEUI%/include/%PAGENAME%.php",
    01569             "SPTUI--%ACTIVEUI%/include/%PAGENAME%.html",
    01570             "%ACTIVEUI%/include/%PAGENAME%.php",
    01571             "%ACTIVEUI%/include/%PAGENAME%.html",
    01572             "local/interface/default/include/%PAGENAME%.php",
    01573             "local/interface/default/include/%PAGENAME%.html",
    01574             "local/include/%PAGENAME%.php",
    01575             "local/include/%PAGENAME%.html",
    01576             "interface/default/include/%PAGENAME%.php",
    01577             "interface/default/include/%PAGENAME%.html",
    01578             "include/%PAGENAME%.php",
    01579             "include/%PAGENAME%.html",
    01580             );
    01581
    01582     const NOVALUE = ".-+-.NO VALUE PASSED IN FOR ARGUMENT.-+-.";
    01583 };
    01584
    01585
    01586 ?>

Copyright 2010 Internet Scout