Search:

# CWIS Developers Documentation

- Main Page
- Classes
- Files

- File List
- File Members

# ApplicationFramework.php

Go to the documentation of this file.

    00001 <?PHP
    00002
    00007 class ApplicationFramework {
    00008
    00009     # ---- PUBLIC INTERFACE --------------------------------------------------
    00010  /*@(*/
    00012
    00020     function __construct($ObjectDirectories = NULL)
    00021     {
    00022         # save execution start time
    00023         $this->ExecutionStartTime = microtime(TRUE);
    00024
    00025         # save object directory search list
    00026         if ($ObjectDirectories) {  $this->AddObjectDirectories($ObjectDirectories);  }
    00027
    00028         # set up object file autoloader
    00029         $this->SetUpObjectAutoloading();
    00030
    00031         # set up function to output any buffered text in case of crash
    00032         register_shutdown_function(array($this, "OnCrash"));
    00033
    00034         # set up our internal environment
    00035         $this->DB = new Database();
    00036
    00037         # load our settings from database
    00038         $this->DB->Query("SELECT * FROM ApplicationFrameworkSettings");
    00039         $this->Settings = $this->DB->FetchRow();
    00040         if (!$this->Settings)
    00041         {
    00042             $this->DB->Query("INSERT INTO ApplicationFrameworkSettings"
    00043                     ." (LastTaskRunAt) VALUES ('2000-01-02 03:04:05')");
    00044             $this->DB->Query("SELECT * FROM ApplicationFrameworkSettings");
    00045             $this->Settings = $this->DB->FetchRow();
    00046         }
    00047
    00048         # set PHP maximum execution time
    00049         $this->MaxExecutionTime($this->Settings["MaxExecTime"]);
    00050
    00051         # register events we handle internally
    00052         $this->RegisterEvent($this->PeriodicEvents);
    00053         $this->RegisterEvent($this->UIEvents);
    00054     }
    00062     function AddObjectDirectories($Dirs)
    00063     {
    00064         foreach ($Dirs as $Location => $Prefix)
    00065         {
    00066             $Location = $Location
    00067                     .((substr($Location, -1) != "/") ? "/" : "");
    00068             self::$ObjectDirectories = array_merge(
    00069                     array($Location => $Prefix),
    00070                     self::$ObjectDirectories);
    00071         }
    00072     }
    00073
    00078     function LoadPage($PageName)
    00079     {
    00080         # buffer any output from includes or PHP file
    00081         ob_start();
    00082
    00083         # include any files needed to set up execution environment
    00084         foreach ($this->EnvIncludes as $IncludeFile)
    00085         {
    00086             include($IncludeFile);
    00087         }
    00088
    00089         # sanitize incoming page name
    00090         $PageName = preg_replace("/[^a-zA-Z0-9_.-]/", "", $PageName);
    00091
    00092         # signal page load
    00093         $this->SignalEvent("EVENT_PAGE_LOAD", array("PageName" => $PageName));
    00094
    00095         # signal PHP file load
    00096         $SignalResult = $this->SignalEvent("EVENT_PHP_FILE_LOAD", array(
    00097                 "PageName" => $PageName));
    00098
    00099         # if signal handler returned new page name value
    00100         $NewPageName = $PageName;
    00101         if (($SignalResult["PageName"] != $PageName)
    00102                 && strlen($SignalResult["PageName"]))
    00103         {
    00104             # if new page name value is page file
    00105             if (file_exists($SignalResult["PageName"]))
    00106             {
    00107                 # use new value for PHP file name
    00108                 $PageFile = $SignalResult["PageName"];
    00109             }
    00110             else
    00111             {
    00112                 # use new value for page name
    00113                 $NewPageName = $SignalResult["PageName"];
    00114             }
    00115         }
    00116
    00117         # if we do not already have a PHP file
    00118         if (!isset($PageFile))
    00119         {
    00120             # look for PHP file for page
    00121             $OurPageFile = "pages/".$NewPageName.".php";
    00122             $LocalPageFile = "local/pages/".$NewPageName.".php";
    00123             $PageFile = file_exists($LocalPageFile) ? $LocalPageFile
    00124                     : (file_exists($OurPageFile) ? $OurPageFile
    00125                     : "pages/".$this->DefaultPage.".php");
    00126         }
    00127
    00128         # load PHP file
    00129         include($PageFile);
    00130
    00131         # save buffered output to be displayed later after HTML file loads
    00132         $PageOutput = ob_get_contents();
    00133         ob_end_clean();
    00134
    00135         # set up for possible TSR (Terminate and Stay Resident :))
    00136         $ShouldTSR = $this->PrepForTSR();
    00137
    00138         # if PHP file indicated we should autorefresh to somewhere else
    00139         if ($this->JumpToPage)
    00140         {
    00141             if (!strlen(trim($PageOutput)))
    00142             {
    00143                 ?><html>
    00144                 <head>
    00145                     <meta http-equiv="refresh" content="0; URL=<?PHP
    00146                             print($this->JumpToPage);  ?>">
    00147                 </head>
    00148                 <body bgcolor="white">
    00149                 </body>
    00150                 </html><?PHP
    00151             }
    00152         }
    00153         # else if HTML loading is not suppressed
    00154         elseif (!$this->SuppressHTML)
    00155         {
    00156             # set content-type to get rid of diacritic errors
    00157             header("Content-Type: text/html; charset="
    00158                 .$this->HtmlCharset, TRUE);
    00159
    00160             # load common HTML file if available
    00161             $HtmlFile = $this->FindCommonTemplate("Common");
    00162             if ($HtmlFile) {  include($HtmlFile);  }
    00163
    00164             # load UI functions
    00165             $this->LoadUIFunctions();
    00166
    00167             # begin buffering content
    00168             ob_start();
    00169
    00170             # signal HTML file load
    00171             $SignalResult = $this->SignalEvent("EVENT_HTML_FILE_LOAD", array(
    00172                     "PageName" => $PageName));
    00173
    00174             # if signal handler returned new page name value
    00175             $NewPageName = $PageName;
    00176             $HtmlFile = NULL;
    00177             if (($SignalResult["PageName"] != $PageName)
    00178                     && strlen($SignalResult["PageName"]))
    00179             {
    00180                 # if new page name value is HTML file
    00181                 if (file_exists($SignalResult["PageName"]))
    00182                 {
    00183                     # use new value for HTML file name
    00184                     $HtmlFile = $SignalResult["PageName"];
    00185                 }
    00186                 else
    00187                 {
    00188                     # use new value for page name
    00189                     $NewPageName = $SignalResult["PageName"];
    00190                 }
    00191             }
    00192
    00193             # load page content HTML file if available
    00194             if ($HtmlFile === NULL)
    00195             {
    00196                 $HtmlFile = $this->FindTemplate($this->ContentTemplateList, $NewPageName);
    00197             }
    00198             if ($HtmlFile)
    00199             {
    00200                 include($HtmlFile);
    00201             }
    00202             else
    00203             {
    00204                 print("<h2>ERROR:  No HTML/TPL template found"
    00205                         ." for this page.</h2>");
    00206             }
    00207
    00208             # signal HTML file load complete
    00209             $SignalResult = $this->SignalEvent("EVENT_HTML_FILE_LOAD_COMPLETE");
    00210
    00211             # stop buffering and save content
    00212             $BufferedContent = ob_get_contents();
    00213             ob_end_clean();
    00214
    00215             # load page start HTML file if available
    00216             $HtmlFile = $this->FindCommonTemplate("Start");
    00217             if ($HtmlFile) {  include($HtmlFile);  }
    00218
    00219             # write out page content
    00220             print($BufferedContent);
    00221
    00222             # load page end HTML file if available
    00223             $HtmlFile = $this->FindCommonTemplate("End");
    00224             if ($HtmlFile) {  include($HtmlFile);  }
    00225         }
    00226
    00227         # run any post-processing routines
    00228         foreach ($this->PostProcessingFuncs as $Func)
    00229         {
    00230             call_user_func_array($Func["FunctionName"], $Func["Arguments"]);
    00231         }
    00232
    00233         # write out any output buffered from page code execution
    00234         if (strlen($PageOutput))
    00235         {
    00236             if (!$this->SuppressHTML)
    00237             {
    00238                 ?><table width="100%" cellpadding="5"
    00239                         style="border: 2px solid #666666;  background: #CCCCCC;
    00240                         font-family: Courier New, Courier, monospace;
    00241                         margin-top: 10px;"><tr><td><?PHP
    00242             }
    00243             if ($this->JumpToPage)
    00244             {
    00245                 ?><div style="color: #666666;"><span style="font-size: 150%;">
    00246                 <b>Page Jump Aborted</b></span>
    00247                 (because of error or other unexpected output)<br />
    00248                 <b>Jump Target:</b>
    00249                 <i><?PHP  print($this->JumpToPage);  ?></i></div><?PHP
    00250             }
    00251             print($PageOutput);
    00252             if (!$this->SuppressHTML)
    00253             {
    00254                 ?></td></tr></table><?PHP
    00255             }
    00256         }
    00257
    00258         # terminate and stay resident (TSR!) if indicated and HTML has been output
    00259         # (only TSR if HTML has been output because otherwise browsers will misbehave)
    00260         if ($ShouldTSR) {  $this->LaunchTSR();  }
    00261     }
    00262
    00269     function SetJumpToPage($Page)
    00270     {
    00271         if ((strpos($Page, "?") === FALSE)
    00272                 && ((strpos($Page, "=") !== FALSE)
    00273                     || ((strpos($Page, ".php") === FALSE)
    00274                         && (strpos($Page, ".htm") === FALSE)
    00275                         && (strpos($Page, "/") === FALSE))))
    00276         {
    00277             $this->JumpToPage = "index.php?P=".$Page;
    00278         }
    00279         else
    00280         {
    00281             $this->JumpToPage = $Page;
    00282         }
    00283     }
    00284
    00289     function JumpToPageIsSet()
    00290     {
    00291         return ($this->JumpToPage === NULL) ? FALSE : TRUE;
    00292     }
    00293
    00303     function HtmlCharset($NewSetting = NULL)
    00304     {
    00305         if ($NewSetting !== NULL) {  $this->HtmlCharset = $NewSetting;  }
    00306         return $this->HtmlCharset;
    00307     }
    00308
    00315     function SuppressHTMLOutput($NewSetting = TRUE)
    00316     {
    00317         $this->SuppressHTML = $NewSetting;
    00318     }
    00319
    00326     function ActiveUserInterface($UIName = NULL)
    00327     {
    00328         if ($UIName !== NULL)
    00329         {
    00330             $this->ActiveUI = preg_replace("/^SPTUI--/", "", $UIName);
    00331         }
    00332         return $this->ActiveUI;
    00333     }
    00334
    00350     function AddPostProcessingCall($FunctionName,
    00351             &$Arg1 = self::NOVALUE, &$Arg2 = self::NOVALUE, &$Arg3 = self::NOVALUE,
    00352             &$Arg4 = self::NOVALUE, &$Arg5 = self::NOVALUE, &$Arg6 = self::NOVALUE,
    00353             &$Arg7 = self::NOVALUE, &$Arg8 = self::NOVALUE, &$Arg9 = self::NOVALUE)
    00354     {
    00355         $FuncIndex = count($this->PostProcessingFuncs);
    00356         $this->PostProcessingFuncs[$FuncIndex]["FunctionName"] = $FunctionName;
    00357         $this->PostProcessingFuncs[$FuncIndex]["Arguments"] = array();
    00358         $Index = 1;
    00359         while (isset(${"Arg".$Index}) && (${"Arg".$Index} !== self::NOVALUE))
    00360         {
    00361             $this->PostProcessingFuncs[$FuncIndex]["Arguments"][$Index]
    00362                     =& ${"Arg".$Index};
    00363             $Index++;
    00364         }
    00365     }
    00366
    00372     function AddEnvInclude($FileName)
    00373     {
    00374         $this->EnvIncludes[] = $FileName;
    00375     }
    00376
    00382     function GUIFile($FileName)
    00383     {
    00384         # pull off file name suffix
    00385         $NamePieces = explode(".", $FileName);
    00386         $Suffix = strtolower(array_pop($NamePieces));
    00387
    00388         # determine which location to search based on file suffix
    00389         $ImageSuffixes = array("gif", "jpg", "png");
    00390         $FileList = in_array($Suffix, $ImageSuffixes)
    00391                 ? $this->ImageFileList : $this->CommonTemplateList;
    00392
    00393         # search for file and return result to caller
    00394         return $this->FindTemplate($FileList, $FileName);
    00395     }
    00396
    00406     function PUIFile($FileName)
    00407     {
    00408         $FullFileName = $this->GUIFile($FileName);
    00409         if ($FullFileName) {  print($FullFileName);  }
    00410     }
    00411
    00416     function FindCommonTemplate($PageName)
    00417     {
    00418         return $this->FindTemplate(
    00419                 array_merge($this->CommonTemplateList, $this->ContentTemplateList),
    00420                 $PageName);
    00421     }
    00422
    00431     function LoadFunction($Callback)
    00432     {
    00433         if (!is_callable($Callback) && is_string($Callback))
    00434         {
    00435             $Locations = $this->FunctionFileList;
    00436             foreach (self::$ObjectDirectories as $Location => $Prefix)
    00437             {
    00438                 $Locations[] = $Location."%PAGENAME%.php";
    00439                 $Locations[] = $Location."%PAGENAME%.html";
    00440             }
    00441             $FunctionFileName = $this->FindTemplate($Locations, "F-".$Callback);
    00442             if ($FunctionFileName)
    00443             {
    00444                 include_once($FunctionFileName);
    00445             }
    00446         }
    00447         return is_callable($Callback);
    00448     }
    00449
    00454     function GetElapsedExecutionTime()
    00455     {
    00456         return microtime(TRUE) - $this->ExecutionStartTime;
    00457     }
    00458
    00463     function GetSecondsBeforeTimeout()
    00464     {
    00465         return ini_get("max_execution_time") - $this->GetElapsedExecutionTime();
    00466     }
    00467
    00468     /*@)*/ /* Application Framework */
    00469
    00470     # ---- Event Handling ----------------------------------------------------
    00471  /*@(*/
    00473
    00477     const EVENTTYPE_DEFAULT = 1;
    00483     const EVENTTYPE_CHAIN = 2;
    00489     const EVENTTYPE_FIRST = 3;
    00497     const EVENTTYPE_NAMED = 4;
    00498
    00500     const ORDER_FIRST = 1;
    00502     const ORDER_MIDDLE = 2;
    00504     const ORDER_LAST = 3;
    00505
    00514     function RegisterEvent($EventsOrEventName, $EventType = NULL)
    00515     {
    00516         # convert parameters to array if not already in that form
    00517         $Events = is_array($EventsOrEventName) ? $EventsOrEventName
    00518                 : array($EventsOrEventName => $Type);
    00519
    00520         # for each event
    00521         foreach ($Events as $Name => $Type)
    00522         {
    00523             # store event information
    00524             $this->RegisteredEvents[$Name]["Type"] = $Type;
    00525             $this->RegisteredEvents[$Name]["Hooks"] = array();
    00526         }
    00527     }
    00528
    00542     function HookEvent($EventsOrEventName, $Callback = NULL, $Order = self::ORDER_MIDDLE)
    00543     {
    00544         # convert parameters to array if not already in that form
    00545         $Events = is_array($EventsOrEventName) ? $EventsOrEventName
    00546                 : array($EventsOrEventName => $Callback);
    00547
    00548         # for each event
    00549         $Success = TRUE;
    00550         foreach ($Events as $EventName => $EventCallback)
    00551         {
    00552             # if callback is valid
    00553             if (is_callable($EventCallback))
    00554             {
    00555                 # if this is a periodic event we process internally
    00556                 if (isset($this->PeriodicEvents[$EventName]))
    00557                 {
    00558                     # process event now
    00559                     $this->ProcessPeriodicEvent($EventName, $EventCallback);
    00560                 }
    00561                 # if specified event has been registered
    00562                 elseif (isset($this->RegisteredEvents[$EventName]))
    00563                 {
    00564                     # add callback for event
    00565                     $this->RegisteredEvents[$EventName]["Hooks"][]
    00566                             = array("Callback" => $EventCallback, "Order" => $Order);
    00567
    00568                     # sort callbacks by order
    00569                     if (count($this->RegisteredEvents[$EventName]["Hooks"]) > 1)
    00570                     {
    00571                         usort($this->RegisteredEvents[$EventName]["Hooks"],
    00572                                 array("ApplicationFramework", "HookEvent_OrderCompare"));
    00573                     }
    00574                 }
    00575                 else
    00576                 {
    00577                     $Success = FALSE;
    00578                 }
    00579             }
    00580             else
    00581             {
    00582                 $Success = FALSE;
    00583             }
    00584         }
    00585
    00586         # report to caller whether all callbacks were hooked
    00587         return $Success;
    00588     }
    00589     private static function HookEvent_OrderCompare($A, $B)
    00590     {
    00591         if ($A["Order"] == $B["Order"]) {  return 0;  }
    00592         return ($A["Order"] < $B["Order"]) ? -1 : 1;
    00593     }
    00594
    00603     function SignalEvent($EventName, $Parameters = NULL)
    00604     {
    00605         $ReturnValue = NULL;
    00606
    00607         # if event has been registered
    00608         if (isset($this->RegisteredEvents[$EventName]))
    00609         {
    00610             # set up default return value (if not NULL)
    00611             switch ($this->RegisteredEvents[$EventName]["Type"])
    00612             {
    00613                 case self::EVENTTYPE_CHAIN:
    00614                     $ReturnValue = $Parameters;
    00615                     break;
    00616
    00617                 case self::EVENTTYPE_NAMED:
    00618                     $ReturnValue = array();
    00619                     break;
    00620             }
    00621
    00622             # for each callback for this event
    00623             foreach ($this->RegisteredEvents[$EventName]["Hooks"] as $Hook)
    00624             {
    00625                 # invoke callback
    00626                 $Callback = $Hook["Callback"];
    00627                 $Result = ($Parameters !== NULL)
    00628                         ? call_user_func_array($Callback, $Parameters)
    00629                         : call_user_func($Callback);
    00630
    00631                 # process return value based on event type
    00632                 switch ($this->RegisteredEvents[$EventName]["Type"])
    00633                 {
    00634                     case self::EVENTTYPE_CHAIN:
    00635                         $ReturnValue = $Result;
    00636                         $Parameters = $Result;
    00637                         break;
    00638
    00639                     case self::EVENTTYPE_FIRST:
    00640                         if ($Result !== NULL)
    00641                         {
    00642                             $ReturnValue = $Result;
    00643                             break 2;
    00644                         }
    00645                         break;
    00646
    00647                     case self::EVENTTYPE_NAMED:
    00648                         $CallbackName = is_array($Callback)
    00649                                 ? (is_object($Callback[0])
    00650                                         ? get_class($Callback[0])
    00651                                         : $Callback[0])."::".$Callback[1]
    00652                                 : $Callback;
    00653                         $ReturnValue[$CallbackName] = $Result;
    00654                         break;
    00655
    00656                     default:
    00657                         break;
    00658                 }
    00659             }
    00660         }
    00661
    00662         # return value if any to caller
    00663         return $ReturnValue;
    00664     }
    00665
    00671     function IsStaticOnlyEvent($EventName)
    00672     {
    00673         return isset($this->PeriodicEvents[$EventName]) ? TRUE : FALSE;
    00674     }
    00675
    00676     /*@)*/ /* Event Handling */
    00677
    00678     # ---- Task Management ---------------------------------------------------
    00679  /*@(*/
    00681
    00683     const PRIORITY_HIGH = 1;
    00685     const PRIORITY_MEDIUM = 2;
    00687     const PRIORITY_LOW = 3;
    00689     const PRIORITY_BACKGROUND = 4;
    00690
    00703     function QueueTask($Callback, $Parameters = NULL,
    00704             $Priority = self::PRIORITY_MEDIUM, $Description = "")
    00705     {
    00706         # pack task info and write to database
    00707         if ($Parameters === NULL) {  $Parameters = array();  }
    00708         $this->DB->Query("INSERT INTO TaskQueue"
    00709                 ." (Callback, Parameters, Priority, Description)"
    00710                 ." VALUES ('".addslashes(serialize($Callback))."', '"
    00711                 .addslashes(serialize($Parameters))."', ".intval($Priority).", '"
    00712                 .addslashes($Description)."')");
    00713     }
    00714
    00732     function QueueUniqueTask($Callback, $Parameters = NULL,
    00733             $Priority = self::PRIORITY_MEDIUM, $Description = "")
    00734     {
    00735         if ($this->TaskIsInQueue($Callback, $Parameters))
    00736         {
    00737             $QueryResult = $this->DB->Query("SELECT TaskId,Priority FROM TaskQueue"
    00738                     ." WHERE Callback = '".addslashes(serialize($Callback))."'"
    00739                     .($Parameters ? " AND Parameters = '"
    00740                             .addslashes(serialize($Parameters))."'" : ""));
    00741             if ($QueryResult !== FALSE)
    00742             {
    00743                 $Record = $this->DB->FetchRow();
    00744                 if ($Record["Priority"] > $Priority)
    00745                 {
    00746                     $this->DB->Query("UPDATE TaskQueue"
    00747                             ." SET Priority = ".intval($Priority)
    00748                             ." WHERE TaskId = ".intval($Record["TaskId"]));
    00749                 }
    00750             }
    00751             return FALSE;
    00752         }
    00753         else
    00754         {
    00755             $this->QueueTask($Callback, $Parameters, $Priority, $Description);
    00756             return TRUE;
    00757         }
    00758     }
    00759
    00769     function TaskIsInQueue($Callback, $Parameters = NULL)
    00770     {
    00771         $FoundCount = $this->DB->Query("SELECT COUNT(*) AS FoundCount FROM TaskQueue"
    00772                 ." WHERE Callback = '".addslashes(serialize($Callback))."'"
    00773                 .($Parameters ? " AND Parameters = '"
    00774                         .addslashes(serialize($Parameters))."'" : ""),
    00775                 "FoundCount")
    00776                 + $this->DB->Query("SELECT COUNT(*) AS FoundCount FROM RunningTasks"
    00777                 ." WHERE Callback = '".addslashes(serialize($Callback))."'"
    00778                 .($Parameters ? " AND Parameters = '"
    00779                         .addslashes(serialize($Parameters))."'" : ""),
    00780                 "FoundCount");
    00781         return ($FoundCount ? TRUE : FALSE);
    00782     }
    00783
    00789     function GetTaskQueueSize($Priority = NULL)
    00790     {
    00791         return $this->DB->Query("SELECT COUNT(*) AS QueueSize FROM TaskQueue"
    00792                 .($Priority ? " WHERE Priority = ".intval($Priority) : ""),
    00793                 "QueueSize");
    00794     }
    00795
    00803     function GetQueuedTaskList($Count = 100, $Offset = 0)
    00804     {
    00805         return $this->GetTaskList("SELECT * FROM TaskQueue"
    00806                 ." ORDER BY Priority, TaskId ", $Count, $Offset);
    00807     }
    00808
    00816     function GetRunningTaskList($Count = 100, $Offset = 0)
    00817     {
    00818         return $this->GetTaskList("SELECT * FROM RunningTasks"
    00819                 ." WHERE StartedAt >= '".date("Y-m-d H:i:s",
    00820                         (time() - ini_get("max_execution_time")))."'"
    00821                 ." ORDER BY StartedAt", $Count, $Offset);
    00822     }
    00823
    00831     function GetOrphanedTaskList($Count = 100, $Offset = 0)
    00832     {
    00833         return $this->GetTaskList("SELECT * FROM RunningTasks"
    00834                 ." WHERE StartedAt < '".date("Y-m-d H:i:s",
    00835                         (time() - ini_get("max_execution_time")))."'"
    00836                 ." ORDER BY StartedAt", $Count, $Offset);
    00837     }
    00838
    00843     function ReQueueOrphanedTask($TaskId)
    00844     {
    00845         $this->DB->Query("LOCK TABLES TaskQueue WRITE, RunningTasks WRITE");
    00846         $this->DB->Query("INSERT INTO TaskQueue"
    00847                          ." (Callback,Parameters,Priority,Description) "
    00848                          ."SELECT Callback, Parameters, Priority, Description"
    00849                          ." FROM RunningTasks WHERE TaskId = ".intval($TaskId));
    00850         $this->DB->Query("DELETE FROM RunningTasks WHERE TaskId = ".intval($TaskId));
    00851         $this->DB->Query("UNLOCK TABLES");
    00852     }
    00853
    00858     function DeleteTask($TaskId)
    00859     {
    00860         $this->DB->Query("DELETE FROM TaskQueue WHERE TaskId = ".intval($TaskId));
    00861         $this->DB->Query("DELETE FROM RunningTasks WHERE TaskId = ".intval($TaskId));
    00862     }
    00863
    00871     function GetTask($TaskId)
    00872     {
    00873         # assume task will not be found
    00874         $Task = NULL;
    00875
    00876         # look for task in task queue
    00877         $this->DB->Query("SELECT * FROM TaskQueue WHERE TaskId = ".intval($TaskId));
    00878
    00879         # if task was not found in queue
    00880         if (!$this->DB->NumRowsSelected())
    00881         {
    00882             # look for task in running task list
    00883             $this->DB->Query("SELECT * FROM RunningTasks WHERE TaskId = "
    00884                     .intval($TaskId));
    00885         }
    00886
    00887         # if task was found
    00888         if ($this->DB->NumRowsSelected())
    00889         {
    00890             # if task was periodic
    00891             $Row = $this->DB->FetchRow();
    00892             if ($Row["Callback"] ==
    00893                     serialize(array("ApplicationFramework", "PeriodicEventWrapper")))
    00894             {
    00895                 # unpack periodic task callback
    00896                 $WrappedCallback = unserialize($Row["Parameters"]);
    00897                 $Task["Callback"] = $WrappedCallback[1];
    00898                 $Task["Parameters"] = NULL;
    00899             }
    00900             else
    00901             {
    00902                 # unpack task callback and parameters
    00903                 $Task["Callback"] = unserialize($Row["Callback"]);
    00904                 $Task["Parameters"] = unserialize($Row["Parameters"]);
    00905             }
    00906         }
    00907
    00908         # return task to caller
    00909         return $Task;
    00910     }
    00911
    00917     function MaxTasks($NewValue = NULL)
    00918     {
    00919         if (func_num_args() && ($NewValue >= 1))
    00920         {
    00921             $this->DB->Query("UPDATE ApplicationFrameworkSettings"
    00922                     ." SET MaxTasksRunning = '".intval($NewValue)."'");
    00923             $this->Settings["MaxTasksRunning"] = intval($NewValue);
    00924         }
    00925         return $this->Settings["MaxTasksRunning"];
    00926     }
    00927
    00935     function MaxExecutionTime($NewValue = NULL)
    00936     {
    00937         if (func_num_args() && !ini_get("safe_mode"))
    00938         {
    00939             if ($NewValue != $this->Settings["MaxExecTime"])
    00940             {
    00941                 $this->Settings["MaxExecTime"] = max($NewValue, 5);
    00942                 $this->DB->Query("UPDATE ApplicationFrameworkSettings"
    00943                         ." SET MaxExecTime = '"
    00944                                 .intval($this->Settings["MaxExecTime"])."'");
    00945             }
    00946             ini_set("max_execution_time", $this->Settings["MaxExecTime"]);
    00947             set_time_limit($this->Settings["MaxExecTime"]);
    00948         }
    00949         return ini_get("max_execution_time");
    00950     }
    00951
    00952     /*@)*/ /* Task Management */
    00953
    00954     # ---- PRIVATE INTERFACE -------------------------------------------------
    00955
    00956     private $JumpToPage = NULL;
    00957     private $SuppressHTML = FALSE;
    00958     private $DefaultPage = "Home";
    00959     private $ActiveUI = "default";
    00960     private $HtmlCharset = "UTF-8";
    00961     private $PostProcessingFuncs = array();
    00962     private $EnvIncludes = array();
    00963     private $DB;
    00964     private $Settings;
    00965     private $ExecutionStartTime;
    00966     private static $ObjectDirectories = array();
    00967     private $MaxRunningTasksToTrack = 250;
    00968     private $RunningTask;
    00969
    00970     private $PeriodicEvents = array(
    00971                 "EVENT_HOURLY" => self::EVENTTYPE_DEFAULT,
    00972                 "EVENT_DAILY" => self::EVENTTYPE_DEFAULT,
    00973                 "EVENT_WEEKLY" => self::EVENTTYPE_DEFAULT,
    00974                 "EVENT_MONTHLY" => self::EVENTTYPE_DEFAULT,
    00975                 "EVENT_PERIODIC" => self::EVENTTYPE_NAMED,
    00976                 );
    00977     private $UIEvents = array(
    00978                 "EVENT_PAGE_LOAD" => self::EVENTTYPE_DEFAULT,
    00979                 "EVENT_PHP_FILE_LOAD" => self::EVENTTYPE_CHAIN,
    00980                 "EVENT_HTML_FILE_LOAD" => self::EVENTTYPE_CHAIN,
    00981                 "EVENT_HTML_FILE_LOAD_COMPLETE" => self::EVENTTYPE_DEFAULT,
    00982                 );
    00983
    00984     private function FindTemplate($FileList, $PageName)
    00985     {
    00986         $FileNameFound = NULL;
    00987         foreach ($FileList as $FileName)
    00988         {
    00989             $FileName = str_replace("%ACTIVEUI%", $this->ActiveUI, $FileName);
    00990             $FileName = str_replace("%PAGENAME%", $PageName, $FileName);
    00991             if (file_exists($FileName))
    00992             {
    00993                 $FileNameFound = $FileName;
    00994                 break;
    00995             }
    00996         }
    00997         return $FileNameFound;
    00998     }
    00999
    01000     private function SetUpObjectAutoloading()
    01001     {
    01002         function __autoload($ClassName)
    01003         {
    01004             ApplicationFramework::AutoloadObjects($ClassName);
    01005         }
    01006     }
    01007
    01009     static function AutoloadObjects($ClassName)
    01010     {
    01011         foreach (self::$ObjectDirectories as $Location => $Prefix)
    01012         {
    01013             $FileName = $Location.$Prefix.$ClassName.".php";
    01014             if (file_exists($FileName))
    01015             {
    01016                 require_once($FileName);
    01017                 break;
    01018             }
    01019         }
    01020     }
    01023     private function LoadUIFunctions()
    01024     {
    01025         $Dirs = array(
    01026                 "local/interface/%ACTIVEUI%/include",
    01027                 "interface/%ACTIVEUI%/include",
    01028                 "local/interface/default/include",
    01029                 "interface/default/include",
    01030                 );
    01031         foreach ($Dirs as $Dir)
    01032         {
    01033             $Dir = str_replace("%ACTIVEUI%", $this->ActiveUI, $Dir);
    01034             if (is_dir($Dir))
    01035             {
    01036                 $FileNames = scandir($Dir);
    01037                 foreach ($FileNames as $FileName)
    01038                 {
    01039                     if (preg_match("/^F-([A-Za-z_]+)\.php/", $FileName, $Matches)
    01040                             || preg_match("/^F-([A-Za-z_]+)\.html/", $FileName, $Matches))
    01041                     {
    01042                         if (!function_exists($Matches[1]))
    01043                         {
    01044                             include_once($Dir."/".$FileName);
    01045                         }
    01046                     }
    01047                 }
    01048             }
    01049         }
    01050     }
    01051
    01052     private function ProcessPeriodicEvent($EventName, $Callback)
    01053     {
    01054         # retrieve last execution time for event if available
    01055         $Signature = self::GetCallbackSignature($Callback);
    01056         $LastRun = $this->DB->Query("SELECT LastRunAt FROM PeriodicEvents"
    01057                 ." WHERE Signature = '".addslashes($Signature)."'", "LastRunAt");
    01058
    01059         # determine whether enough time has passed for event to execute
    01060         $EventPeriods = array(
    01061                 "EVENT_HOURLY" => 60*60,
    01062                 "EVENT_DAILY" => 60*60*24,
    01063                 "EVENT_WEEKLY" => 60*60*24*7,
    01064                 "EVENT_MONTHLY" => 60*60*24*30,
    01065                 "EVENT_PERIODIC" => 0,
    01066                 );
    01067         $ShouldExecute = (($LastRun === NULL)
    01068                 || (time() > (strtotime($LastRun) + $EventPeriods[$EventName])))
    01069                 ? TRUE : FALSE;
    01070
    01071         # if event should run
    01072         if ($ShouldExecute)
    01073         {
    01074             # add event to task queue
    01075             $WrapperCallback = array("ApplicationFramework", "PeriodicEventWrapper");
    01076             $WrapperParameters = array(
    01077                     $EventName, $Callback, array("LastRunAt" => $LastRun));
    01078             $this->QueueUniqueTask($WrapperCallback, $WrapperParameters);
    01079         }
    01080     }
    01081
    01082     private static function PeriodicEventWrapper($EventName, $Callback, $Parameters)
    01083     {
    01084         static $DB;
    01085         if (!isset($DB)) {  $DB = new Database();  }
    01086
    01087         # run event
    01088         $ReturnVal = call_user_func_array($Callback, $Parameters);
    01089
    01090         # if event is already in database
    01091         $Signature = self::GetCallbackSignature($Callback);
    01092         if ($DB->Query("SELECT COUNT(*) AS EventCount FROM PeriodicEvents"
    01093                 ." WHERE Signature = '".addslashes($Signature)."'", "EventCount"))
    01094         {
    01095             # update last run time for event
    01096             $DB->Query("UPDATE PeriodicEvents SET LastRunAt = "
    01097                     .(($EventName == "EVENT_PERIODIC")
    01098                             ? "'".date("Y-m-d H:i:s", time() + ($ReturnVal * 60))."'"
    01099                             : "NOW()")
    01100                     ." WHERE Signature = '".addslashes($Signature)."'");
    01101         }
    01102         else
    01103         {
    01104             # add last run time for event to database
    01105             $DB->Query("INSERT INTO PeriodicEvents (Signature, LastRunAt) VALUES "
    01106                     ."('".addslashes($Signature)."', "
    01107                     .(($EventName == "EVENT_PERIODIC")
    01108                             ? "'".date("Y-m-d H:i:s", time() + ($ReturnVal * 60))."'"
    01109                             : "NOW()").")");
    01110         }
    01111     }
    01112
    01113     private static function GetCallbackSignature($Callback)
    01114     {
    01115         return !is_array($Callback) ? $Callback
    01116                 : (is_object($Callback[0]) ? md5(serialize($Callback[0])) : $Callback[0])
    01117                         ."::".$Callback[1];
    01118     }
    01119
    01120     private function PrepForTSR()
    01121     {
    01122         # if HTML has been output and it's time to launch another task
    01123         # (only TSR if HTML has been output because otherwise browsers
    01124         #       may misbehave after connection is closed)
    01125         if (($this->JumpToPage || !$this->SuppressHTML)
    01126                 && (time() > (strtotime($this->Settings["LastTaskRunAt"])
    01127                         + (ini_get("max_execution_time")
    01128                                 / $this->Settings["MaxTasksRunning"]) + 5))
    01129                 && $this->GetTaskQueueSize())
    01130         {
    01131             # begin buffering output for TSR
    01132             ob_start();
    01133
    01134             # let caller know it is time to launch another task
    01135             return TRUE;
    01136         }
    01137         else
    01138         {
    01139             # let caller know it is not time to launch another task
    01140             return FALSE;
    01141         }
    01142     }
    01143
    01144     private function LaunchTSR()
    01145     {
    01146         # set needed headers and
    01147         ignore_user_abort(TRUE);
    01148         header("Connection: close");
    01149         header("Content-Length: ".ob_get_length());
    01150
    01151         # output buffered content
    01152         ob_end_flush();
    01153         flush();
    01154
    01155         # write out any outstanding data and end HTTP session
    01156         session_write_close();
    01157
    01158         # if there is still a task in the queue
    01159         if ($this->GetTaskQueueSize())
    01160         {
    01161             # turn on output buffering to (hopefully) record any crash output
    01162             ob_start();
    01163
    01164             # lock tables and grab last task run time to double check
    01165             $this->DB->Query("LOCK TABLES ApplicationFrameworkSettings WRITE");
    01166             $this->DB->Query("SELECT * FROM ApplicationFrameworkSettings");
    01167             $this->Settings = $this->DB->FetchRow();
    01168
    01169             # if still time to launch another task
    01170             if (time() > (strtotime($this->Settings["LastTaskRunAt"])
    01171                         + (ini_get("max_execution_time")
    01172                                 / $this->Settings["MaxTasksRunning"]) + 5))
    01173             {
    01174                 # update the "last run" time and release tables
    01175                 $this->DB->Query("UPDATE ApplicationFrameworkSettings"
    01176                         ." SET LastTaskRunAt = '".date("Y-m-d H:i:s")."'");
    01177                 $this->DB->Query("UNLOCK TABLES");
    01178
    01179                 # run tasks while there is a task in the queue and enough time left
    01180                 do
    01181                 {
    01182                     # run the next task
    01183                     $this->RunNextTask();
    01184                 }
    01185                 while ($this->GetTaskQueueSize()
    01186                         && ($this->GetSecondsBeforeTimeout() > 65));
    01187             }
    01188             else
    01189             {
    01190                 # release tables
    01191                 $this->DB->Query("UNLOCK TABLES");
    01192             }
    01193         }
    01194     }
    01195
    01203     private function GetTaskList($DBQuery, $Count, $Offset)
    01204     {
    01205         $this->DB->Query($DBQuery." LIMIT ".intval($Offset).",".intval($Count));
    01206         $Tasks = array();
    01207         while ($Row = $this->DB->FetchRow())
    01208         {
    01209             $Tasks[$Row["TaskId"]] = $Row;
    01210             if ($Row["Callback"] ==
    01211                     serialize(array("ApplicationFramework", "PeriodicEventWrapper")))
    01212             {
    01213                 $WrappedCallback = unserialize($Row["Parameters"]);
    01214                 $Tasks[$Row["TaskId"]]["Callback"] = $WrappedCallback[1];
    01215                 $Tasks[$Row["TaskId"]]["Parameters"] = NULL;
    01216             }
    01217             else
    01218             {
    01219                 $Tasks[$Row["TaskId"]]["Callback"] = unserialize($Row["Callback"]);
    01220                 $Tasks[$Row["TaskId"]]["Parameters"] = unserialize($Row["Parameters"]);
    01221             }
    01222         }
    01223         return $Tasks;
    01224     }
    01225
    01229     private function RunNextTask()
    01230     {
    01231         # look for task at head of queue
    01232         $this->DB->Query("SELECT * FROM TaskQueue ORDER BY Priority, TaskId LIMIT 1");
    01233         $Task = $this->DB->FetchRow();
    01234
    01235         # if there was a task available
    01236         if ($Task)
    01237         {
    01238             # move task from queue to running tasks list
    01239             $this->DB->Query("INSERT INTO RunningTasks "
    01240                              ."(TaskId,Callback,Parameters,Priority,Description) "
    01241                              ."SELECT * FROM TaskQueue WHERE TaskId = "
    01242                                     .intval($Task["TaskId"]));
    01243             $this->DB->Query("DELETE FROM TaskQueue WHERE TaskId = "
    01244                     .intval($Task["TaskId"]));
    01245
    01246             # unpack stored task info
    01247             $Callback = unserialize($Task["Callback"]);
    01248             $Parameters = unserialize($Task["Parameters"]);
    01249
    01250             # attempt to load task callback if not already available
    01251             $this->LoadFunction($Callback);
    01252
    01253             # run task
    01254             $this->RunningTask = $Task;
    01255             if ($Parameters)
    01256             {
    01257                 call_user_func_array($Callback, $Parameters);
    01258             }
    01259             else
    01260             {
    01261                 call_user_func($Callback);
    01262             }
    01263             unset($this->RunningTask);
    01264
    01265             # remove task from running tasks list
    01266             $this->DB->Query("DELETE FROM RunningTasks"
    01267                     ." WHERE TaskId = ".intval($Task["TaskId"]));
    01268
    01269             # prune running tasks list if necessary
    01270             $RunningTasksCount = $this->DB->Query(
    01271                     "SELECT COUNT(*) AS TaskCount FROM RunningTasks", "TaskCount");
    01272             if ($RunningTasksCount > $this->MaxRunningTasksToTrack)
    01273             {
    01274                 $this->DB->Query("DELETE FROM RunningTasks ORDER BY StartedAt"
    01275                         ." LIMIT ".($RunningTasksCount - $this->MaxRunningTasksToTrack));
    01276             }
    01277         }
    01278     }
    01279
    01285     function OnCrash()
    01286     {
    01287         if (isset($this->RunningTask))
    01288         {
    01289             if (function_exists("error_get_last"))
    01290             {
    01291                 $CrashInfo["LastError"] = error_get_last();
    01292             }
    01293             if (ob_get_length() !== FALSE)
    01294             {
    01295                 $CrashInfo["OutputBuffer"] = ob_get_contents();
    01296             }
    01297             if (isset($CrashInfo))
    01298             {
    01299                 $DB = new Database();
    01300                 $DB->Query("UPDATE RunningTasks SET CrashInfo = '"
    01301                         .addslashes(serialize($CrashInfo))
    01302                         ."' WHERE TaskId = ".intval($this->RunningTask["TaskId"]));
    01303             }
    01304         }
    01305
    01306         print("\n");
    01307         return;
    01308
    01309         if (ob_get_length() !== FALSE)
    01310         {
    01311             ?>
    01312             <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>
    01313             <div style="font-size: 200%;">CRASH OUTPUT</div><?PHP
    01314             ob_end_flush();
    01315             ?></td></tr></table><?PHP
    01316         }
    01317     }
    01318
    01319     private $CommonTemplateList = array(
    01320             "local/interface/%ACTIVEUI%/include/StdPage%PAGENAME%.tpl",
    01321             "local/interface/%ACTIVEUI%/include/StdPage%PAGENAME%.html",
    01322             "local/interface/%ACTIVEUI%/include/%PAGENAME%.tpl",
    01323             "local/interface/%ACTIVEUI%/include/%PAGENAME%.html",
    01324             "local/interface/%ACTIVEUI%/include/SPT--StandardPage%PAGENAME%.tpl",
    01325             "local/interface/%ACTIVEUI%/include/SPT--StandardPage%PAGENAME%.html",
    01326             "local/interface/%ACTIVEUI%/include/SPT--%PAGENAME%.tpl",
    01327             "local/interface/%ACTIVEUI%/include/SPT--%PAGENAME%.html",
    01328             "local/interface/%ACTIVEUI%/include/%PAGENAME%",
    01329             "interface/%ACTIVEUI%/include/StdPage%PAGENAME%.tpl",
    01330             "interface/%ACTIVEUI%/include/StdPage%PAGENAME%.html",
    01331             "interface/%ACTIVEUI%/include/%PAGENAME%.tpl",
    01332             "interface/%ACTIVEUI%/include/%PAGENAME%.html",
    01333             "interface/%ACTIVEUI%/include/SPT--StandardPage%PAGENAME%.tpl",
    01334             "interface/%ACTIVEUI%/include/SPT--StandardPage%PAGENAME%.html",
    01335             "interface/%ACTIVEUI%/include/SPT--%PAGENAME%.tpl",
    01336             "interface/%ACTIVEUI%/include/SPT--%PAGENAME%.html",
    01337             "interface/%ACTIVEUI%/include/%PAGENAME%",
    01338             "SPTUI--%ACTIVEUI%/include/StdPage%PAGENAME%.tpl",
    01339             "SPTUI--%ACTIVEUI%/include/StdPage%PAGENAME%.html",
    01340             "SPTUI--%ACTIVEUI%/include/%PAGENAME%.tpl",
    01341             "SPTUI--%ACTIVEUI%/include/%PAGENAME%.html",
    01342             "SPTUI--%ACTIVEUI%/include/SPT--StandardPage%PAGENAME%.tpl",
    01343             "SPTUI--%ACTIVEUI%/include/SPT--StandardPage%PAGENAME%.html",
    01344             "SPTUI--%ACTIVEUI%/include/SPT--%PAGENAME%.tpl",
    01345             "SPTUI--%ACTIVEUI%/include/SPT--%PAGENAME%.html",
    01346             "SPTUI--%ACTIVEUI%/include/%PAGENAME%",
    01347             "%ACTIVEUI%/include/StdPage%PAGENAME%.tpl",
    01348             "%ACTIVEUI%/include/StdPage%PAGENAME%.html",
    01349             "%ACTIVEUI%/include/%PAGENAME%.tpl",
    01350             "%ACTIVEUI%/include/%PAGENAME%.html",
    01351             "%ACTIVEUI%/include/SPT--StandardPage%PAGENAME%.tpl",
    01352             "%ACTIVEUI%/include/SPT--StandardPage%PAGENAME%.html",
    01353             "%ACTIVEUI%/include/SPT--%PAGENAME%.tpl",
    01354             "%ACTIVEUI%/include/SPT--%PAGENAME%.html",
    01355             "%ACTIVEUI%/include/%PAGENAME%",
    01356             "local/interface/default/include/StdPage%PAGENAME%.tpl",
    01357             "local/interface/default/include/StdPage%PAGENAME%.html",
    01358             "local/interface/default/include/%PAGENAME%.tpl",
    01359             "local/interface/default/include/%PAGENAME%.html",
    01360             "local/interface/default/include/SPT--StandardPage%PAGENAME%.tpl",
    01361             "local/interface/default/include/SPT--StandardPage%PAGENAME%.html",
    01362             "local/interface/default/include/SPT--%PAGENAME%.tpl",
    01363             "local/interface/default/include/SPT--%PAGENAME%.html",
    01364             "local/interface/default/include/%PAGENAME%",
    01365             "interface/default/include/StdPage%PAGENAME%.tpl",
    01366             "interface/default/include/StdPage%PAGENAME%.html",
    01367             "interface/default/include/%PAGENAME%.tpl",
    01368             "interface/default/include/%PAGENAME%.html",
    01369             "interface/default/include/SPT--StandardPage%PAGENAME%.tpl",
    01370             "interface/default/include/SPT--StandardPage%PAGENAME%.html",
    01371             "interface/default/include/SPT--%PAGENAME%.tpl",
    01372             "interface/default/include/SPT--%PAGENAME%.html",
    01373             "interface/default/include/%PAGENAME%",
    01374             );
    01375     private $ContentTemplateList = array(
    01376             "local/interface/%ACTIVEUI%/%PAGENAME%.tpl",
    01377             "local/interface/%ACTIVEUI%/%PAGENAME%.html",
    01378             "local/interface/%ACTIVEUI%/SPT--%PAGENAME%.tpl",
    01379             "local/interface/%ACTIVEUI%/SPT--%PAGENAME%.html",
    01380             "interface/%ACTIVEUI%/%PAGENAME%.tpl",
    01381             "interface/%ACTIVEUI%/%PAGENAME%.html",
    01382             "interface/%ACTIVEUI%/SPT--%PAGENAME%.tpl",
    01383             "interface/%ACTIVEUI%/SPT--%PAGENAME%.html",
    01384             "SPTUI--%ACTIVEUI%/%PAGENAME%.tpl",
    01385             "SPTUI--%ACTIVEUI%/%PAGENAME%.html",
    01386             "SPTUI--%ACTIVEUI%/SPT--%PAGENAME%.tpl",
    01387             "SPTUI--%ACTIVEUI%/SPT--%PAGENAME%.html",
    01388             "%ACTIVEUI%/%PAGENAME%.tpl",
    01389             "%ACTIVEUI%/%PAGENAME%.html",
    01390             "%ACTIVEUI%/SPT--%PAGENAME%.tpl",
    01391             "%ACTIVEUI%/SPT--%PAGENAME%.html",
    01392             "local/interface/default/%PAGENAME%.tpl",
    01393             "local/interface/default/%PAGENAME%.html",
    01394             "local/interface/default/SPT--%PAGENAME%.tpl",
    01395             "local/interface/default/SPT--%PAGENAME%.html",
    01396             "interface/default/%PAGENAME%.tpl",
    01397             "interface/default/%PAGENAME%.html",
    01398             "interface/default/SPT--%PAGENAME%.tpl",
    01399             "interface/default/SPT--%PAGENAME%.html",
    01400             );
    01401     private $ImageFileList = array(
    01402             "local/interface/%ACTIVEUI%/images/%PAGENAME%",
    01403             "interface/%ACTIVEUI%/images/%PAGENAME%",
    01404             "SPTUI--%ACTIVEUI%/images/%PAGENAME%",
    01405             "%ACTIVEUI%/images/%PAGENAME%",
    01406             "local/interface/default/images/%PAGENAME%",
    01407             "interface/default/images/%PAGENAME%",
    01408             );
    01409     private $FunctionFileList = array(
    01410             "local/interface/%ACTIVEUI%/include/%PAGENAME%.php",
    01411             "local/interface/%ACTIVEUI%/include/%PAGENAME%.html",
    01412             "interface/%ACTIVEUI%/include/%PAGENAME%.php",
    01413             "interface/%ACTIVEUI%/include/%PAGENAME%.html",
    01414             "SPTUI--%ACTIVEUI%/include/%PAGENAME%.php",
    01415             "SPTUI--%ACTIVEUI%/include/%PAGENAME%.html",
    01416             "%ACTIVEUI%/include/%PAGENAME%.php",
    01417             "%ACTIVEUI%/include/%PAGENAME%.html",
    01418             "local/interface/default/include/%PAGENAME%.php",
    01419             "local/interface/default/include/%PAGENAME%.html",
    01420             "local/include/%PAGENAME%.php",
    01421             "local/include/%PAGENAME%.html",
    01422             "interface/default/include/%PAGENAME%.php",
    01423             "interface/default/include/%PAGENAME%.html",
    01424             "include/%PAGENAME%.php",
    01425             "include/%PAGENAME%.html",
    01426             );
    01427
    01428     const NOVALUE = ".-+-.NO VALUE PASSED IN FOR ARGUMENT.-+-.";
    01429 };
    01430
    01431
    01432 ?>

Copyright 2010 Internet Scout