Search:

# CWIS Developers Documentation

- Main Page
- Classes
- Files

- Search for |

- 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 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     /*@)*/ /* Application Framework */
    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     /*@)*/ /* Event Handling */
    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     /*@)*/ /* Task Management */
    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 ?>