00001 <?PHP
00002
00007 class ApplicationFramework {
00008
00009 # ---- PUBLIC INTERFACE --------------------------------------------------
00010
00012
00020 function __construct($ObjectDirectories = NULL)
00021 {
00022 # save object directory search list
00023 self::$ObjectDirectories = $ObjectDirectories;
00024
00025 # set up object file autoloader
00026 $this->SetUpObjectAutoloading();
00027
00028 # set up function to output any buffered text in case of crash
00029 register_shutdown_function(array($this, "OnCrash"));
00030
00031 # set up our internal environment
00032 $this->DB = new Database();
00033
00034 # load our settings from database
00035 $this->DB->Query("SELECT * FROM ApplicationFrameworkSettings");
00036 $this->Settings = $this->DB->FetchRow();
00037 if (!$this->Settings)
00038 {
00039 $this->DB->Query("INSERT INTO ApplicationFrameworkSettings"
00040 ." (LastTaskRunAt) VALUES (NOW())");
00041 $this->DB->Query("SELECT * FROM ApplicationFrameworkSettings");
00042 $this->Settings = $this->DB->FetchRow();
00043 }
00044
00045 # register events we handle internally
00046 $this->RegisterEvent($this->PeriodicEvents);
00047 $this->RegisterEvent($this->UIEvents);
00048 }
00056 function AddObjectDirectories($Dirs)
00057 {
00058 self::$ObjectDirectories += $Dirs;
00059 }
00060
00065 function LoadPage($PageName)
00066 {
00067 # buffer any output from includes or PHP file
00068 ob_start();
00069
00070 # include any files needed to set up execution environment
00071 foreach ($this->EnvIncludes as $IncludeFile)
00072 {
00073 include($IncludeFile);
00074 }
00075
00076 # signal page load
00077 $this->SignalEvent("EVENT_PAGE_LOAD", array("PageName" => $PageName));
00078
00079 # signal PHP file load
00080 $SignalResult = $this->SignalEvent("EVENT_PHP_FILE_LOAD", array(
00081 "PageName" => $PageName));
00082
00083 # if signal handler returned new page name value
00084 $NewPageName = $PageName;
00085 if (($SignalResult["PageName"] != $PageName)
00086 && strlen($SignalResult["PageName"]))
00087 {
00088 # if new page name value is page file
00089 if (file_exists($SignalResult["PageName"]))
00090 {
00091 # use new value for PHP file name
00092 $PageFile = $SignalResult["PageName"];
00093 }
00094 else
00095 {
00096 # use new value for page name
00097 $NewPageName = $SignalResult["PageName"];
00098 }
00099 }
00100
00101 # if we do not already have a PHP file
00102 if (!isset($PageFile))
00103 {
00104 # look for PHP file for page
00105 $OurPageFile = "pages/".$NewPageName.".php";
00106 $LocalPageFile = "local/pages/".$NewPageName.".php";
00107 $PageFile = file_exists($LocalPageFile) ? $LocalPageFile
00108 : (file_exists($OurPageFile) ? $OurPageFile
00109 : "pages/".$this->DefaultPage.".php");
00110 }
00111
00112 # load PHP file
00113 include($PageFile);
00114
00115 # save buffered output to be displayed later after HTML file loads
00116 $PageOutput = ob_get_contents();
00117 ob_end_clean();
00118
00119 # set up for possible TSR (Terminate and Stay Resident :))
00120 $ShouldTSR = $this->PrepForTSR();
00121
00122 # if PHP file indicated we should autorefresh to somewhere else
00123 if ($this->JumpToPage)
00124 {
00125 if (!strlen(trim($PageOutput)))
00126 {
00127 ?><html>
00128 <head>
00129 <meta http-equiv="refresh" content="0; URL=<?PHP
00130 print($this->JumpToPage); ?>">
00131 </head>
00132 <body bgcolor="white">
00133 </body>
00134 </html><?PHP
00135 }
00136 }
00137 # else if HTML loading is not suppressed
00138 elseif (!$this->SuppressHTML)
00139 {
00140 # set content-type to get rid of diacritic errors
00141 header("Content-Type: text/html; charset="
00142 .$this->HtmlCharset, TRUE);
00143
00144 # load common HTML file if available
00145 $HtmlFile = $this->FindCommonTemplate("Common");
00146 if ($HtmlFile) { include($HtmlFile); }
00147
00148 # begin buffering content
00149 ob_start();
00150
00151 # signal HTML file load
00152 $SignalResult = $this->SignalEvent("EVENT_HTML_FILE_LOAD", array(
00153 "PageName" => $PageName));
00154
00155 # if signal handler returned new page name value
00156 $NewPageName = $PageName;
00157 $HtmlFile = NULL;
00158 if (($SignalResult["PageName"] != $PageName)
00159 && strlen($SignalResult["PageName"]))
00160 {
00161 # if new page name value is HTML file
00162 if (file_exists($SignalResult["PageName"]))
00163 {
00164 # use new value for HTML file name
00165 $HtmlFile = $SignalResult["PageName"];
00166 }
00167 else
00168 {
00169 # use new value for page name
00170 $NewPageName = $SignalResult["PageName"];
00171 }
00172 }
00173
00174 # load page content HTML file if available
00175 if ($HtmlFile === NULL)
00176 {
00177 $HtmlFile = $this->FindTemplate($this->ContentTemplateList, $NewPageName);
00178 }
00179 if ($HtmlFile)
00180 {
00181 include($HtmlFile);
00182 }
00183 else
00184 {
00185 print("<h2>ERROR: No HTML/TPL template found"
00186 ." for this page.</h2>");
00187 }
00188
00189 # signal HTML file load complete
00190 $SignalResult = $this->SignalEvent("EVENT_HTML_FILE_LOAD_COMPLETE");
00191
00192 # stop buffering and save content
00193 $BufferedContent = ob_get_contents();
00194 ob_end_clean();
00195
00196 # load page start HTML file if available
00197 $HtmlFile = $this->FindCommonTemplate("Start");
00198 if ($HtmlFile) { include($HtmlFile); }
00199
00200 # write out page content
00201 print($BufferedContent);
00202
00203 # load page end HTML file if available
00204 $HtmlFile = $this->FindCommonTemplate("End");
00205 if ($HtmlFile) { include($HtmlFile); }
00206 }
00207
00208 # run any post-processing routines
00209 foreach ($this->PostProcessingFuncs as $Func)
00210 {
00211 call_user_func_array($Func["FunctionName"], $Func["Arguments"]);
00212 }
00213
00214 # write out any output buffered from page code execution
00215 if (strlen($PageOutput))
00216 {
00217 if (!$this->SuppressHTML)
00218 {
00219 ?><table width="100%" cellpadding="5"
00220 style="border: 2px solid #666666; background: #CCCCCC;
00221 font-family: Courier New, Courier, monospace;
00222 margin-top: 10px;"><tr><td><?PHP
00223 }
00224 if ($this->JumpToPage)
00225 {
00226 ?><div style="color: #666666;"><span style="font-size: 150%;">
00227 <b>Page Jump Aborted</b></span>
00228 (because of error or other unexpected output)<br />
00229 <b>Jump Target:</b>
00230 <i><?PHP print($this->JumpToPage); ?></i></div><?PHP
00231 }
00232 print($PageOutput);
00233 if (!$this->SuppressHTML)
00234 {
00235 ?></td></tr></table><?PHP
00236 }
00237 }
00238
00239 # terminate and stay resident (TSR!) if indicated
00240 if ($ShouldTSR) { $this->LaunchTSR(); }
00241 }
00242
00249 function SetJumpToPage($Page)
00250 {
00251 if ((strpos($Page, "?") === FALSE)
00252 && ((strpos($Page, "=") !== FALSE)
00253 || ((strpos($Page, ".php") === FALSE)
00254 && (strpos($Page, ".htm") === FALSE)
00255 && (strpos($Page, "/") === FALSE))))
00256 {
00257 $this->JumpToPage = "index.php?P=".$Page;
00258 }
00259 else
00260 {
00261 $this->JumpToPage = $Page;
00262 }
00263 }
00264
00269 function JumpToPageIsSet()
00270 {
00271 return ($this->JumpToPage === NULL) ? FALSE : TRUE;
00272 }
00273
00283 function HtmlCharset($NewSetting = NULL)
00284 {
00285 if ($NewSetting !== NULL) { $this->HtmlCharset = $NewSetting; }
00286 return $this->HtmlCharset;
00287 }
00288
00295 function SuppressHTMLOutput($NewSetting = TRUE)
00296 {
00297 $this->SuppressHTML = $NewSetting;
00298 }
00299
00306 function ActiveUserInterface($UIName = NULL)
00307 {
00308 if ($UIName !== NULL)
00309 {
00310 $this->ActiveUI = preg_replace("/^SPTUI--/", "", $UIName);
00311 }
00312 return $this->ActiveUI;
00313 }
00314
00330 function AddPostProcessingCall($FunctionName,
00331 &$Arg1 = self::NOVALUE, &$Arg2 = self::NOVALUE, &$Arg3 = self::NOVALUE,
00332 &$Arg4 = self::NOVALUE, &$Arg5 = self::NOVALUE, &$Arg6 = self::NOVALUE,
00333 &$Arg7 = self::NOVALUE, &$Arg8 = self::NOVALUE, &$Arg9 = self::NOVALUE)
00334 {
00335 $FuncIndex = count($this->PostProcessingFuncs);
00336 $this->PostProcessingFuncs[$FuncIndex]["FunctionName"] = $FunctionName;
00337 $this->PostProcessingFuncs[$FuncIndex]["Arguments"] = array();
00338 $Index = 1;
00339 while (isset(${"Arg".$Index}) && (${"Arg".$Index} !== self::NOVALUE))
00340 {
00341 $this->PostProcessingFuncs[$FuncIndex]["Arguments"][$Index]
00342 =& ${"Arg".$Index};
00343 $Index++;
00344 }
00345 }
00346
00352 function AddEnvInclude($FileName)
00353 {
00354 $this->EnvIncludes[] = $FileName;
00355 }
00356
00362 function GUIFile($FileName)
00363 {
00364 # pull off file name suffix
00365 $NamePieces = explode(".", $FileName);
00366 $Suffix = strtolower(array_pop($NamePieces));
00367
00368 # determine which location to search based on file suffix
00369 $ImageSuffixes = array("gif", "jpg", "png");
00370 $FileList = in_array($Suffix, $ImageSuffixes)
00371 ? $this->ImageFileList : $this->CommonTemplateList;
00372
00373 # search for file and return result to caller
00374 return $this->FindTemplate($FileList, $FileName);
00375 }
00376
00386 function PUIFile($FileName)
00387 {
00388 $FullFileName = $this->GUIFile($FileName);
00389 if ($FullFileName) { print($FullFileName); }
00390 }
00391
00396 function FindCommonTemplate($PageName)
00397 {
00398 return $this->FindTemplate(
00399 array_merge($this->CommonTemplateList, $this->ContentTemplateList),
00400 $PageName);;
00401 }
00402
00403
00404
00405 # ---- Event Handling ----------------------------------------------------
00406
00408
00412 const EVENTTYPE_DEFAULT = 1;
00418 const EVENTTYPE_CHAIN = 2;
00424 const EVENTTYPE_FIRST = 3;
00432 const EVENTTYPE_NAMED = 4;
00433
00442 function RegisterEvent($EventsOrEventName, $EventType = NULL)
00443 {
00444 # convert parameters to array if not already in that form
00445 $Events = is_array($EventsOrEventName) ? $EventsOrEventName
00446 : array($EventsOrEventName => $Type);
00447
00448 # for each event
00449 foreach ($Events as $Name => $Type)
00450 {
00451 # store event information
00452 $this->RegisteredEvents[$Name]["Type"] = $Type;
00453 $this->RegisteredEvents[$Name]["Callbacks"] = array();
00454 }
00455 }
00456
00468 function HookEvent($EventsOrEventName, $Callback = NULL)
00469 {
00470 # convert parameters to array if not already in that form
00471 $Events = is_array($EventsOrEventName) ? $EventsOrEventName
00472 : array($EventsOrEventName => $Callback);
00473
00474 # for each event
00475 $Success = TRUE;
00476 foreach ($Events as $EventName => $EventCallback)
00477 {
00478 # if callback is valid
00479 if (is_callable($EventCallback))
00480 {
00481 # if this is a periodic event we process internally
00482 if (isset($this->PeriodicEvents[$EventName]))
00483 {
00484 # process event now
00485 $this->ProcessPeriodicEvent($EventName, $EventCallback);
00486 }
00487 # if specified event has been registered
00488 elseif (isset($this->RegisteredEvents[$EventName]))
00489 {
00490 # add callback for event
00491 $this->RegisteredEvents[$EventName]["Callbacks"][]
00492 = $EventCallback;
00493 }
00494 else
00495 {
00496 $Success = FALSE;
00497 }
00498 }
00499 else
00500 {
00501 $Success = FALSE;
00502 }
00503 }
00504
00505 # report to caller whether all callbacks were hooked
00506 return $Success;
00507 }
00508
00516 function SignalEvent($EventName, $Parameters = NULL)
00517 {
00518 $ReturnValue = NULL;
00519
00520 # if event has been registered
00521 if (isset($this->RegisteredEvents[$EventName]))
00522 {
00523 # set up default return value (if not NULL)
00524 switch ($this->RegisteredEvents[$EventName]["Type"])
00525 {
00526 case self::EVENTTYPE_CHAIN:
00527 $ReturnValue = $Parameters;
00528 break;
00529
00530 case self::EVENTTYPE_NAMED:
00531 $ReturnValue = array();
00532 break;
00533 }
00534
00535 # for each callback for this event
00536 foreach ($this->RegisteredEvents[$EventName]["Callbacks"]
00537 as $Callback)
00538 {
00539 # invoke callback
00540 $Result = ($Parameters !== NULL)
00541 ? call_user_func_array($Callback, $Parameters)
00542 : call_user_func($Callback);;
00543
00544 # process return value based on event type
00545 switch ($this->RegisteredEvents[$EventName]["Type"])
00546 {
00547 case self::EVENTTYPE_CHAIN:
00548 $ReturnValue = $Result;
00549 $Parameters = $Result;
00550 break;
00551
00552 case self::EVENTTYPE_FIRST:
00553 if ($Result !== NULL)
00554 {
00555 $ReturnValue = $Result;
00556 break 2;
00557 }
00558 break;
00559
00560 case self::EVENTTYPE_NAMED:
00561 $CallbackName = is_array($Callback)
00562 ? (is_object($Callback[0])
00563 ? get_class($Callback[0])
00564 : $Callback[0])."::".$Callback[1]
00565 : $Callback;
00566 $ReturnValue[$CallbackName] = $Result;
00567 break;
00568
00569 default:
00570 break;
00571 }
00572 }
00573 }
00574
00575 # return value if any to caller
00576 return $ReturnValue;
00577 }
00578
00579
00580
00581 # ---- Task Management ---------------------------------------------------
00582
00584
00586 const PRIORITY_HIGH = 1;
00588 const PRIORITY_MEDIUM = 2;
00590 const PRIORITY_LOW = 3;
00591
00600 function QueueTask($Callback, $Parameters,
00601 $Priority = self::PRIORITY_MEDIUM, $Description = "")
00602 {
00603 # pack task info and write to database
00604 $this->DB->Query("INSERT INTO TaskQueue"
00605 ." (Callback, Parameters, Priority, Description)"
00606 ." VALUES ('".addslashes(serialize($Callback))."', '"
00607 .addslashes(serialize($Parameters))."', ".intval($Priority).", '"
00608 .addslashes($Description)."')");
00609 }
00610
00621 function QueueUniqueTask($Callback, $Parameters,
00622 $Priority = self::PRIORITY_MEDIUM, $Description = "")
00623 {
00624 if ($this->TaskIsInQueue($Callback, $Parameters))
00625 {
00626 return FALSE;
00627 }
00628 else
00629 {
00630 $this->QueueTask($Callback, $Parameters, $Priority, $Description);
00631 return TRUE;
00632 }
00633 }
00634
00643 function TaskIsInQueue($Callback, $Parameters = NULL)
00644 {
00645 $FoundCount = $this->DB->Query("SELECT COUNT(*) AS FoundCount FROM TaskQueue"
00646 ." WHERE Callback = '".addslashes(serialize($Callback))."'"
00647 .($Parameters ? " AND Parameters = '"
00648 .addslashes(serialize($Parameters))."'" : ""),
00649 "FoundCount");
00650 return ($FoundCount ? TRUE : FALSE);
00651 }
00652
00658 function GetTaskQueueSize($Priority = NULL)
00659 {
00660 return $this->DB->Query("SELECT COUNT(*) AS QueueSize FROM TaskQueue"
00661 .($Priority ? " WHERE Priority = ".intval($Priority) : ""),
00662 "QueueSize");
00663 }
00664
00670 function GetTaskList($Count = 100, $Offset = 0)
00671 {
00672 $this->DB->Query("SELECT * FROM TaskQueue LIMIT "
00673 .intval($Offset).",".intval($Count));
00674 $Tasks = array();
00675 while ($Row = $this->DB->FetchRow())
00676 {
00677 $Tasks[$Row["TaskId"]] = $Row;
00678 if (unserialize($Row["Callback"]) ==
00679 array("ApplicationFramework", "PeriodicEventWrapper"))
00680 {
00681 $WrappedCallback = unserialize($Row["Parameters"]);
00682 $Tasks[$Row["TaskId"]]["Callback"] = $WrappedCallback[1];
00683 $Tasks[$Row["TaskId"]]["Parameters"] = NULL;
00684 }
00685 else
00686 {
00687 $Tasks[$Row["TaskId"]]["Callback"] = unserialize($Row["Callback"]);
00688 $Tasks[$Row["TaskId"]]["Parameters"] = unserialize($Row["Parameters"]);
00689 }
00690 }
00691 return $Tasks;
00692 }
00693
00697 function RunNextTask()
00698 {
00699 # look for task at head of queue
00700 $this->DB->Query("SELECT * FROM TaskQueue ORDER BY Priority, TaskId LIMIT 1");
00701 $Task = $this->DB->FetchRow();
00702
00703 # if there was a task available
00704 if ($Task)
00705 {
00706 # remove task from queue
00707 $this->DB->Query("DELETE FROM TaskQueue WHERE TaskId = ".$Task["TaskId"]);
00708
00709 # unpack stored task info
00710 $Callback = unserialize($Task["Callback"]);
00711 $Parameters = unserialize($Task["Parameters"]);
00712
00713 # run task
00714 call_user_func_array($Callback, $Parameters);
00715 }
00716 }
00717
00718
00719
00720 # ---- PRIVATE INTERFACE -------------------------------------------------
00721
00722 private $JumpToPage = NULL;
00723 private $SuppressHTML = FALSE;
00724 private $DefaultPage = "Home";
00725 private $ActiveUI = "default";
00726 private $HtmlCharset = "UTF-8";
00727 private $PostProcessingFuncs = array();
00728 private $EnvIncludes = array();
00729 private $DB;
00730 private $Settings;
00731 private static $ObjectDirectories = array();
00732
00733 private $PeriodicEvents = array(
00734 "EVENT_HOURLY" => self::EVENTTYPE_DEFAULT,
00735 "EVENT_DAILY" => self::EVENTTYPE_DEFAULT,
00736 "EVENT_WEEKLY" => self::EVENTTYPE_DEFAULT,
00737 "EVENT_MONTHLY" => self::EVENTTYPE_DEFAULT,
00738 "EVENT_PERIODIC" => self::EVENTTYPE_NAMED,
00739 );
00740 private $UIEvents = array(
00741 "EVENT_PAGE_LOAD" => self::EVENTTYPE_DEFAULT,
00742 "EVENT_PHP_FILE_LOAD" => self::EVENTTYPE_CHAIN,
00743 "EVENT_HTML_FILE_LOAD" => self::EVENTTYPE_CHAIN,
00744 "EVENT_HTML_FILE_LOAD_COMPLETE" => self::EVENTTYPE_DEFAULT,
00745 );
00746
00747 private function FindTemplate($FileList, $PageName)
00748 {
00749 $FileNameFound = NULL;
00750 foreach ($FileList as $FileName)
00751 {
00752 $FileName = str_replace("%ACTIVEUI%", $this->ActiveUI, $FileName);
00753 $FileName = str_replace("%PAGENAME%", $PageName, $FileName);
00754 if (file_exists($FileName))
00755 {
00756 $FileNameFound = $FileName;
00757 break;
00758 }
00759 }
00760 return $FileNameFound;
00761 }
00762
00763 private function SetUpObjectAutoloading()
00764 {
00765 function __autoload($ClassName)
00766 {
00767 ApplicationFramework::AutoloadObjects($ClassName);
00768 }
00769 }
00770
00772 static function AutoloadObjects($ClassName)
00773 {
00774 foreach (self::$ObjectDirectories as $Location => $Prefix)
00775 {
00776 $FileName = $Location
00777 .((substr($Location, -1) != "/") ? "/" : "")
00778 .$Prefix.$ClassName.".php";
00779 if (file_exists($FileName))
00780 {
00781 require_once($FileName);
00782 }
00783 }
00784 }
00787 private function ProcessPeriodicEvent($EventName, $Callback)
00788 {
00789 # retrieve last execution time for event if available
00790 $Signature = self::GetCallbackSignature($Callback);
00791 $LastRun = $this->DB->Query("SELECT LastRunAt FROM PeriodicEvents"
00792 ." WHERE Signature = '".addslashes($Signature)."'", "LastRunAt");
00793
00794 # determine whether enough time has passed for event to execute
00795 $EventPeriods = array(
00796 "EVENT_HOURLY" => 60*60,
00797 "EVENT_DAILY" => 60*60*24,
00798 "EVENT_WEEKLY" => 60*60*24*7,
00799 "EVENT_MONTHLY" => 60*60*24*30,
00800 "EVENT_PERIODIC" => 0,
00801 );
00802 $ShouldExecute = (($LastRun === NULL)
00803 || (time() > (strtotime($LastRun) + $EventPeriods[$EventName])))
00804 ? TRUE : FALSE;
00805
00806 # if event should run
00807 if ($ShouldExecute)
00808 {
00809 # if event is not already in task queue
00810 $WrapperCallback = array("ApplicationFramework", "PeriodicEventWrapper");
00811 $WrapperParameters = array(
00812 $EventName, $Callback, array("LastRunAt" => $LastRun));
00813 if (!$this->TaskIsInQueue($WrapperCallback, $WrapperParameters))
00814 {
00815 # add event to task queue
00816 $this->QueueTask($WrapperCallback, $WrapperParameters);
00817 }
00818 }
00819 }
00820
00821 private static function PeriodicEventWrapper($EventName, $Callback, $Parameters)
00822 {
00823 static $DB;
00824 if (!isset($DB)) { $DB = new Database(); }
00825
00826 # run event
00827 $ReturnVal = call_user_func_array($Callback, $Parameters);
00828
00829 # if event is already in database
00830 $Signature = ApplicationFramework::GetCallbackSignature($Callback);
00831 if ($DB->Query("SELECT COUNT(*) AS EventCount FROM PeriodicEvents"
00832 ." WHERE Signature = '".addslashes($Signature)."'", "EventCount"))
00833 {
00834 # update last run time for event
00835 $DB->Query("UPDATE PeriodicEvents SET LastRunAt = "
00836 .(($EventName == "EVENT_PERIODIC")
00837 ? "'".date("Y-m-d H:i:s", time() + ($ReturnVal * 60))."'"
00838 : "NOW()")
00839 ." WHERE Signature = '".addslashes($Signature)."'");
00840 }
00841 else
00842 {
00843 # add last run time for event to database
00844 $DB->Query("INSERT INTO PeriodicEvents (Signature, LastRunAt) VALUES "
00845 ."('".addslashes($Signature)."', "
00846 .(($EventName == "EVENT_PERIODIC")
00847 ? "'".date("Y-m-d H:i:s", time() + ($ReturnVal * 60))."'"
00848 : "NOW()").")");
00849 }
00850 }
00851
00852 private static function GetCallbackSignature($Callback)
00853 {
00854 return !is_array($Callback) ? $Callback
00855 : (is_object($Callback[0]) ? md5(serialize($Callback[0])) : $Callback[0])
00856 ."::".$Callback[1];
00857 }
00858
00859 private function PrepForTSR()
00860 {
00861 # if it is time to launch another task
00862 if ((time() > (strtotime($this->Settings["LastTaskRunAt"])
00863 + ($this->Settings["MaxTaskTime"]
00864 / $this->Settings["MaxTasksRunning"])))
00865 && $this->GetTaskQueueSize())
00866 {
00867 # begin buffering output for TSR
00868 ob_start();
00869
00870 # let caller know it is time to launch another task
00871 return TRUE;
00872 }
00873 else
00874 {
00875 # let caller know it is not time to launch another task
00876 return FALSE;
00877 }
00878 }
00879
00880 private function LaunchTSR()
00881 {
00882 # set needed headers and
00883 ignore_user_abort(TRUE);
00884 header("Connection: close");
00885 header("Content-Length: ".ob_get_length());
00886
00887 # output buffered content
00888 ob_end_flush();
00889 flush();
00890
00891 # write out any outstanding data and end HTTP session
00892 session_write_close();
00893
00894 # if there is still a task in the queue
00895 if ($this->GetTaskQueueSize())
00896 {
00897 # update the "last run" time
00898 $this->DB->Query("UPDATE ApplicationFrameworkSettings"
00899 ." SET LastTaskRunAt = NOW()");
00900
00901 # run the task
00902 $this->RunNextTask();
00903 }
00904 }
00905
00912 function OnCrash()
00913 {
00914 print("\n");
00915 return;
00916
00917 if (ob_get_length() !== FALSE)
00918 {
00919 ?>
00920 <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>
00921 <div style="font-size: 200%;">CRASH OUTPUT</div><?PHP
00922 ob_end_flush();
00923 ?></td></tr></table><?PHP
00924 }
00925 }
00928 private $CommonTemplateList = array(
00929 "local/interface/%ACTIVEUI%/include/StdPage%PAGENAME%.tpl",
00930 "local/interface/%ACTIVEUI%/include/StdPage%PAGENAME%.html",
00931 "local/interface/%ACTIVEUI%/include/%PAGENAME%.tpl",
00932 "local/interface/%ACTIVEUI%/include/%PAGENAME%.html",
00933 "local/interface/%ACTIVEUI%/include/SPT--StandardPage%PAGENAME%.tpl",
00934 "local/interface/%ACTIVEUI%/include/SPT--StandardPage%PAGENAME%.html",
00935 "local/interface/%ACTIVEUI%/include/SPT--%PAGENAME%.tpl",
00936 "local/interface/%ACTIVEUI%/include/SPT--%PAGENAME%.html",
00937 "local/interface/%ACTIVEUI%/include/%PAGENAME%",
00938 "local/interface/%ACTIVEUI%/include/%PAGENAME%",
00939 "interface/%ACTIVEUI%/include/StdPage%PAGENAME%.tpl",
00940 "interface/%ACTIVEUI%/include/StdPage%PAGENAME%.html",
00941 "interface/%ACTIVEUI%/include/%PAGENAME%.tpl",
00942 "interface/%ACTIVEUI%/include/%PAGENAME%.html",
00943 "interface/%ACTIVEUI%/include/SPT--StandardPage%PAGENAME%.tpl",
00944 "interface/%ACTIVEUI%/include/SPT--StandardPage%PAGENAME%.html",
00945 "interface/%ACTIVEUI%/include/SPT--%PAGENAME%.tpl",
00946 "interface/%ACTIVEUI%/include/SPT--%PAGENAME%.html",
00947 "interface/%ACTIVEUI%/include/%PAGENAME%",
00948 "interface/%ACTIVEUI%/include/%PAGENAME%",
00949 "SPTUI--%ACTIVEUI%/include/StdPage%PAGENAME%.tpl",
00950 "SPTUI--%ACTIVEUI%/include/StdPage%PAGENAME%.html",
00951 "SPTUI--%ACTIVEUI%/include/%PAGENAME%.tpl",
00952 "SPTUI--%ACTIVEUI%/include/%PAGENAME%.html",
00953 "SPTUI--%ACTIVEUI%/include/SPT--StandardPage%PAGENAME%.tpl",
00954 "SPTUI--%ACTIVEUI%/include/SPT--StandardPage%PAGENAME%.html",
00955 "SPTUI--%ACTIVEUI%/include/SPT--%PAGENAME%.tpl",
00956 "SPTUI--%ACTIVEUI%/include/SPT--%PAGENAME%.html",
00957 "SPTUI--%ACTIVEUI%/include/%PAGENAME%",
00958 "SPTUI--%ACTIVEUI%/include/%PAGENAME%",
00959 "%ACTIVEUI%/include/StdPage%PAGENAME%.tpl",
00960 "%ACTIVEUI%/include/StdPage%PAGENAME%.html",
00961 "%ACTIVEUI%/include/%PAGENAME%.tpl",
00962 "%ACTIVEUI%/include/%PAGENAME%.html",
00963 "%ACTIVEUI%/include/SPT--StandardPage%PAGENAME%.tpl",
00964 "%ACTIVEUI%/include/SPT--StandardPage%PAGENAME%.html",
00965 "%ACTIVEUI%/include/SPT--%PAGENAME%.tpl",
00966 "%ACTIVEUI%/include/SPT--%PAGENAME%.html",
00967 "%ACTIVEUI%/include/%PAGENAME%",
00968 "%ACTIVEUI%/include/%PAGENAME%",
00969 "local/interface/default/include/StdPage%PAGENAME%.tpl",
00970 "local/interface/default/include/StdPage%PAGENAME%.html",
00971 "local/interface/default/include/%PAGENAME%.tpl",
00972 "local/interface/default/include/%PAGENAME%.html",
00973 "local/interface/default/include/SPT--StandardPage%PAGENAME%.tpl",
00974 "local/interface/default/include/SPT--StandardPage%PAGENAME%.html",
00975 "local/interface/default/include/SPT--%PAGENAME%.tpl",
00976 "local/interface/default/include/SPT--%PAGENAME%.html",
00977 "local/interface/default/include/%PAGENAME%",
00978 "local/interface/default/include/%PAGENAME%",
00979 "interface/default/include/StdPage%PAGENAME%.tpl",
00980 "interface/default/include/StdPage%PAGENAME%.html",
00981 "interface/default/include/%PAGENAME%.tpl",
00982 "interface/default/include/%PAGENAME%.html",
00983 "interface/default/include/SPT--StandardPage%PAGENAME%.tpl",
00984 "interface/default/include/SPT--StandardPage%PAGENAME%.html",
00985 "interface/default/include/SPT--%PAGENAME%.tpl",
00986 "interface/default/include/SPT--%PAGENAME%.html",
00987 "interface/default/include/%PAGENAME%",
00988 "interface/default/include/%PAGENAME%",
00989 );
00990 private $ContentTemplateList = array(
00991 "local/interface/%ACTIVEUI%/%PAGENAME%.tpl",
00992 "local/interface/%ACTIVEUI%/%PAGENAME%.html",
00993 "local/interface/%ACTIVEUI%/SPT--%PAGENAME%.tpl",
00994 "local/interface/%ACTIVEUI%/SPT--%PAGENAME%.html",
00995 "interface/%ACTIVEUI%/%PAGENAME%.tpl",
00996 "interface/%ACTIVEUI%/%PAGENAME%.html",
00997 "interface/%ACTIVEUI%/SPT--%PAGENAME%.tpl",
00998 "interface/%ACTIVEUI%/SPT--%PAGENAME%.html",
00999 "SPTUI--%ACTIVEUI%/%PAGENAME%.tpl",
01000 "SPTUI--%ACTIVEUI%/%PAGENAME%.html",
01001 "SPTUI--%ACTIVEUI%/SPT--%PAGENAME%.tpl",
01002 "SPTUI--%ACTIVEUI%/SPT--%PAGENAME%.html",
01003 "%ACTIVEUI%/%PAGENAME%.tpl",
01004 "%ACTIVEUI%/%PAGENAME%.html",
01005 "%ACTIVEUI%/SPT--%PAGENAME%.tpl",
01006 "%ACTIVEUI%/SPT--%PAGENAME%.html",
01007 "local/interface/default/%PAGENAME%.tpl",
01008 "local/interface/default/%PAGENAME%.html",
01009 "local/interface/default/SPT--%PAGENAME%.tpl",
01010 "local/interface/default/SPT--%PAGENAME%.html",
01011 "interface/default/%PAGENAME%.tpl",
01012 "interface/default/%PAGENAME%.html",
01013 "interface/default/SPT--%PAGENAME%.tpl",
01014 "interface/default/SPT--%PAGENAME%.html",
01015 );
01016 private $ImageFileList = array(
01017 "local/interface/%ACTIVEUI%/images/%PAGENAME%",
01018 "interface/%ACTIVEUI%/images/%PAGENAME%",
01019 "SPTUI--%ACTIVEUI%/images/%PAGENAME%",
01020 "%ACTIVEUI%/images/%PAGENAME%",
01021 "local/interface/default/images/%PAGENAME%",
01022 "interface/default/images/%PAGENAME%",
01023 );
01024
01026 const NOVALUE = ".-+-.NO VALUE PASSED IN FOR ARGUMENT.-+-.";
01028 };
01029
01030
01031 ?>