/** * Internal function to set the default skins based on this theme * * Returns false if nothing changed, else will return the configuration options changed. * * @param boolean $install Set to false to force uninstall/disable mode. * @param int $verbosity (default 0) 0: standard output, 1: real-time, 2: real-time verbose output. * * @return false | array * * @throws \InstallerException */ public function _parseSkins($install = true, $verbosity = 0) { // Keep track of if this changed anything. $changes = array(); $action = $install ? 'Installing' : 'Uninstalling'; $set = $install ? 'Set' : 'Unset'; \Core\Utilities\Logger\write_debug($action . ' skins for ' . $this->getName()); // I need to get the schema definitions first. $node = $this->_xmlloader->getElement('skins'); // If requested, set those skins as the site default. $defaultFrontend = $node->getAttribute('default'); $adminFrontend = $node->getAttribute('admindefault'); $emailNode = $this->_xmlloader->getElement('emailskins'); $defaultEmail = $emailNode->getAttribute('default'); if ($defaultFrontend) { \ConfigHandler::Set('/theme/default_template', $defaultFrontend); $changes[] = 'Set default template'; } if ($adminFrontend) { \ConfigHandler::Set('/theme/default_admin_template', $adminFrontend); $changes[] = 'Set default admin template'; } if ($defaultEmail) { \ConfigHandler::Set('/theme/default_email_template', $defaultEmail); $changes[] = 'Set default email template'; } return sizeof($changes) ? $changes : false; }
/** * Load all the components in the system, replacement for the Core. * @throws CoreException */ private function _loadComponents() { // cannot reload components. if ($this->_components) return null; $this->_components = array(); $this->_libraries = array(); $tempcomponents = false; Core\Utilities\Logger\write_debug('Starting loading of component metadata'); // If the site is in DEVELOPMENT mode, component caching would probably be a bad idea; ie: the developer probably wants // those component files loaded everytime. if(DEVELOPMENT_MODE){ $enablecache = false; } else{ $enablecache = true; } // Is there a cache of elements available? This is a primary system cache that greatly increases performance, // since it will no longer have to run through each component.xml file to register each one. if($enablecache){ Core\Utilities\Logger\write_debug('Checking core-components cache'); // Try to load up the cached components and check them first. $tempcomponents = \Core\Cache::Get('core-components', (3600 * 24)); if($tempcomponents !== false){ // Cached components only need to be loaded. foreach ($tempcomponents as $c) { try { $c->load(); } catch (Exception $e) { // Don't completely bail out here, just invalidate the cache and continue on. \Core\Cache::Delete('core-components'); $tempcomponents = false; } } } } if(!$enablecache || $tempcomponents == false){ \Core\Utilities\Profiler\Profiler::GetDefaultProfiler()->record('Scanning for component.xml files manually'); Core\Utilities\Logger\write_debug('Scanning for component.xml files manually'); // Core is first, (obviously) $tempcomponents['core'] = ComponentFactory::Load(ROOT_PDIR . 'core/component.xml'); Core\Utilities\Logger\write_debug('Core component loaded'); // First, build my cache of components, regardless if the component is installed or not. $dh = opendir(ROOT_PDIR . 'components'); if (!$dh) throw new CoreException('Unable to open directory [' . ROOT_PDIR . 'components/] for reading.'); // This will read through every directory in 'components', which is // where all components in the system are installed to. while (($file = readdir($dh)) !== false) { // skip hidden directories. if ($file{0} == '.') continue; // skip non-directories if (!is_dir(ROOT_PDIR . 'components/' . $file)) continue; // Skip directories that do not have a readable component.xml file. if (!is_readable(ROOT_PDIR . 'components/' . $file . '/component.xml')) continue; //Core\Utilities\Logger\write_debug(' * Loading component ' . $file); $c = ComponentFactory::Load(ROOT_PDIR . 'components/' . $file . '/component.xml'); Core\Utilities\Logger\write_debug('Opened component ' . $file); // All further operations are case insensitive. // The original call to Component needs to be case sensitive because it sets the filename to pull. $file = strtolower($file); // If the component was flagged as invalid.. just skip to the next one. if (!$c->isValid()) { if (DEVELOPMENT_MODE) { \Core\set_message('Component ' . $c->getName() . ' appears to be invalid.'); } continue; } $tempcomponents[$file] = $c; unset($c); } closedir($dh); \Core\Utilities\Profiler\Profiler::GetDefaultProfiler()->record('Component XML files scanned'); // Now I probably could actually load the components! foreach ($tempcomponents as $c) { /** @var Component_2_1 $c */ try { // Load some of the data in the class so that it's available in the cached version. // This is because the component 2.1 has built-in caching for many of the XML requests. // by calling them once, that lookup data is cached in that component, which in turn gets // copied to the cache version here! $c->load(); $c->getClassList(); $c->getViewSearchDir(); $c->getSmartyPluginDirectory(); $c->getWidgetList(); } catch (Exception $e) { var_dump($e); die(); } } // Cache this list! if($enablecache){ Core\Utilities\Logger\write_debug(' * Caching core-components for next pass'); \Core\Cache::Set('core-components', $tempcomponents, (3600 * 24)); } } $list = $tempcomponents; \Core\Utilities\Profiler\Profiler::GetDefaultProfiler()->record('Component metadata loaded, starting registration'); Core\Utilities\Logger\write_debug(' * Component metadata loaded, starting registration'); // The core component at a minimum needs to be loaded and registered. // $this->_registerComponent($list['core']); // $this->_components['core']->loadFiles(); // unset($list['core']); // Now that I have a list of components available, copy them into a list of // components that are installed. do { $size = sizeof($list); foreach ($list as $n => $c) { /** @var $c Component_2_1 */ // Disabled components don't get recognized. if($c->isInstalled() && !$c->isEnabled()){ // But they do get sent to the disabled list! $this->_componentsDisabled[$n] = $c; unset($list[$n]); continue; } // Clear out the temporary class list $this->_tmpclasses = []; // If it's loaded, register it and remove it from the list! if ($c->isInstalled() && $c->isLoadable() && $c->loadFiles()) { try{ // Allow for on-the-fly package upgrading regardless of DEV mode or not. if ($c->needsUpdated()) { // Load this component's classes in case an upgrade operation requires one. // This allows a component to be loaded partially without completely being loaded. $this->_tmpclasses = $c->getClassList(); // Lock the site first! // This is because some upgrade procedures take a long time to upgrade. file_put_contents(TMP_DIR . 'lock.message', 'Core Plus is being upgraded, please try again in a minute. '); $c->upgrade(); unlink(TMP_DIR . 'lock.message'); } } catch(Exception $e){ SystemLogModel::LogErrorEvent('/core/component/failedupgrade', 'Ignoring component [' . $n . '] due to an error during upgrading!', $e->getMessage()); unlink(TMP_DIR . 'lock.message'); //$c->disable(); $this->_componentsDisabled[$n] = $c; unset($list[$n]); continue; } try{ $this->_components[$n] = $c; $this->_registerComponent($c); $c->loadSupplementalModels(); } catch(Exception $e){ SystemLogModel::LogErrorEvent('/core/component/failedregister', 'Ignoring component [' . $n . '] due to an error during registration!', $e->getMessage()); //$c->disable(); $this->_componentsDisabled[$n] = $c; unset($list[$n]); continue; } unset($list[$n]); continue; } // Allow for on-the-fly package upgrading regardless of DEV mode or not. // Guess this is needed for the loadFiles part... if ($c->isInstalled() && $c->needsUpdated() && $c->isLoadable()) { // Lock the site first! // This is because some upgrade procedures take a long time to upgrade. file_put_contents(TMP_DIR . 'lock.message', 'Core Plus is being upgraded, please try again in a minute. '); $c->upgrade(); $c->loadFiles(); $this->_components[$n] = $c; $this->_registerComponent($c); unlink(TMP_DIR . 'lock.message'); unset($list[$n]); continue; } // Allow packages to be auto-installed if in DEV mode. // If DEV mode is not enabled, just install the new component, do not enable it. if (!$c->isInstalled() && $c->isLoadable()) { // Load this component's classes in case an install operation requires one. // This allows a component to be loaded partially without completely being loaded. $this->_tmpclasses = $c->getClassList(); // w00t $c->install(); // BLAH, until I fix the disabled-packages-not-viewable bug... $c->enable(); $c->loadFiles(); $this->_components[$n] = $c; $this->_registerComponent($c); /* if(!DEVELOPMENT_MODE){ $c->disable(); } else{ $c->enable(); $c->loadFiles(); $this->_components[$n] = $c; $this->_registerComponent($c); } */ unset($list[$n]); continue; } } } while ($size > 0 && ($size != sizeof($list))); // If dev mode is enabled, display a list of components installed but not loadable. foreach ($list as $n => $c) { //$this->_components[$n] = $c; $this->_componentsDisabled[$n] = $c; // Ignore anything with the execmode different, those should be minor notices for debugging if anything. if ($c->error & Component_2_1::ERROR_WRONGEXECMODE) continue; if (DEVELOPMENT_MODE) { SystemLogModel::LogErrorEvent('/core/component/missingrequirement', 'Could not load installed component ' . $n . ' due to requirement failed.', $c->getErrors()); } } // Don't forget to load the themes too! if(class_exists('ThemeHandler')){ foreach(ThemeHandler::GetAllThemes() as $theme){ /** @var $theme Theme */ $theme->load(); } } // Lastly, make sure that the template path cache is updated! if(class_exists('\\Core\\Templates\\Template')){ \Core\Templates\Template::RequeryPaths(); } }
/** * Simple method to return if two schemas are different * * @param Schema $oldSchema * @param Schema $newSchema * * @return bool */ private function _schemasDiffer(Schema $oldSchema, Schema $newSchema){ // Compare the order of the columns. // This requires more than just A == B ? // because old columns that exist in the database should be ignored if they do not appear in the new schema // AND are at the end of the table. // This is because they get shuffled to the end WITHOUT deleting them. // So if the DB version has `key1`, `key2`, `oldkey1` // and the new has `key1`, `key2`, the order should NOT trigger a different flag since the old keys are at the end. foreach($newSchema->order as $i => $name){ if(!isset($oldSchema->order[$i])){ // The old schema has fewer keys than the new schema! return true; } if($oldSchema->order[$i] != $name){ // The old schema has a different order than the new schema, // eg: column '0' on old is `oldkey1` but the new schema has `key1`. return true; } } if(!\Core\compare_values($oldSchema->indexes, $newSchema->indexes)){ \Core\Utilities\Logger\write_debug('MySQLi Backend::_schemasDiffer: Indexes Different'); return true; } // The schemas require a little more work, // iterate over each and compare the resolved SQL for altering. // This is because some columns have oddities such as TEXT fields and defaults. foreach($newSchema->definitions as $c2){ /** @var SchemaColumn $c2 */ $c1 = $oldSchema->getColumn($c2->field); if($c1 === null){ // This column doesn't exist in the old schema, DIFFERENT! return true; } $c1String = $this->_getColumnString($c1); $c2String = $this->_getColumnString($c2); if($c1String != $c2String){ \Core\Utilities\Logger\write_debug('MySQLi Backend::_schemasDiffer: Column ' . $c1->field . ' Different'); \Core\Utilities\Logger\write_debug('MySQLi Backend::_schemasDiffer: C1 == ' . $c1String); \Core\Utilities\Logger\write_debug('MySQLi Backend::_schemasDiffer: C2 == ' . $c2String); return true; } } // Order, Index, and Defintiion checks all passed. // The columns seem to be the same. return false; }
/** * Dispatch an event, optionally passing 1 or more parameters. * * @param string $hookName The name of the hook to dispatch * @param mixed $args * * @return mixed */ public static function DispatchHook($hookName, $args = null) { // Prevent any hooks from being dispatched until Core is ready! if(!Core::GetComponent()) return null; $hookName = strtolower($hookName); // Case insensitive will prevent errors later on. Core\Utilities\Logger\write_debug('Dispatching hook ' . $hookName); //echo "Calling hook $hookName<br>"; //var_dump(HookHandler::$RegisteredHooks[$hookName]); if (!isset(HookHandler::$RegisteredHooks[$hookName])) { trigger_error('Tried to dispatch an undefined hook ' . $hookName, E_USER_NOTICE); return null; } \Core\Utilities\Profiler\Profiler::GetDefaultProfiler()->record('Dispatching hook ' . $hookName); $args = func_get_args(); // Drop off the hook name from the arguments. array_shift($args); $hook = HookHandler::$RegisteredHooks[$hookName]; $result = call_user_func_array(array(&$hook, 'dispatch'), $args); Core\Utilities\Logger\write_debug('Dispatched hook ' . $hookName); \Core\Utilities\Profiler\Profiler::GetDefaultProfiler()->record('Dispatched hook ' . $hookName); return $result; }
/** * Resize this image and save the output as another File object. * * This is used on conjunction with getPreview* and getQuickPreview. * QuickPreview creates the destination file in the correct directory * and getPreview* methods request the actual resizing. * * @param Filestore\File $file The destination file * @param int $width Width of the final image (in px) * @param int $height Height of the final image (in px) * @param string $mode Mode (part of the geometry) */ private function _resizeTo(Filestore\File $file, $width, $height, $mode){ if(!$this->isImage()){ // :/ return; } \Core\Utilities\Logger\write_debug('Resizing image ' . $this->getFilename('') . ' to ' . $width . 'x' . $height . $mode); $m = $this->getMimetype(); // Make sure the directory of the destination file exists! // By touching the file, Core will create all parent directories as necessary. $file->putContents(''); if($m == 'image/gif' && exec('which convert 2>/dev/null')){ // The GIF resizer handles EVERYTHING :) // Granted of course, that imagemagick's convert is available on the server. $resize = escapeshellarg($mode . $width . 'x' . $height); exec('convert ' . escapeshellarg($this->getFilename()) . ' -resize ' . $resize . ' ' . escapeshellarg($file->getFilename())); \Core\Utilities\Logger\write_debug('Resizing complete (via convert)'); return; } // Traditional resizing logic. switch ($m) { case 'image/jpeg': $thumbType = 'JPEG'; $thumbWidth = $width; $thumbHeight = $height; if($width <= 200 && $height <= 200 && function_exists('exif_thumbnail')){ // Try to write out from the thumbnail img instead of the full size. // This is done to increase server performance. // eg: resizing a 5MB JPEG can take upwards of 50-100ms, // whereas the embedded thumbnail will take only 2-10ms. // Not to mention professional JPEG management tools such as PS and Gimp // produce marginally higher-quality thumbnails than GD will. // (The resulting filesize is negligible.) // Of course if the requested image is larger than a thumbnail size, (200x200 in this case), // using the thumbnail is counter-productive! $img = exif_thumbnail($this->getFilename(), $thumbWidth, $thumbHeight, $thumbType); if($img){ \Core\Utilities\Logger\write_debug('JPEG has thumbnail data of ' . $thumbWidth . 'x' . $thumbHeight . '!'); $file->putContents($img); $img = imagecreatefromjpeg($file->getFilename()); } else{ $img = imagecreatefromjpeg($this->getFilename()); } } else{ $img = imagecreatefromjpeg($this->getFilename()); } break; case 'image/png': $img = imagecreatefrompng($this->getFilename()); break; case 'image/gif': $img = imagecreatefromgif($this->getFilename()); break; default: // Hmmm... \Core\Utilities\Logger\write_debug('Resizing complete (failed, not sure what it was)'); return; } if ($img) { $sW = imagesx($img); $sH = imagesy($img); $nW = $sW; $nH = $sH; switch($mode){ // Standard mode, images are scaled down (only) while preserving aspect ratio case '': case '<': if ($nW > $width) { $nH = $width * $sH / $sW; $nW = $width; } if ($nH > $height) { $nW = $height * $sW / $sH; $nH = $height; } break; // Only resize up case '>': if ($nW < $width) { $nH = $width * $sH / $sW; $nW = $width; } if ($nH < $height) { $nW = $height * $sW / $sH; $nH = $height; } break; // Resize to new size, regardless about aspect ratio case '!': $nW = $width; $nH = $height; break; // Resize image based on smallest dimension case '^': $ratioheight = $sW / $height; $ratiowidth = $sH / $width; if($ratioheight > 1 && $ratiowidth > 1){ // The image is larger than any of the dimensions, I can use the reduction logic. if(($width * $sH / $sW) > ($height * $sW / $sH)){ $nH = $width * $sH / $sW; $nW = $width; } else{ $nH = $height; $nW = $height * $sW / $sH; } } elseif($ratiowidth > $ratioheight){ // The image needs to be increased in size, this logic is slightly different. $nW = $width; $nH = round($width * $sH / $sW); } else{ $nH = $height; $nW = round($height * $sW / $sH); } } // If it's a JPEG, try to find the original thumbnail. /*if(false && $m == 'image/jpeg'){ $type = 'JPEG'; $img = exif_thumbnail($this->getFilename(), $nW, $nH, $type); $file->putContents($img); return; }*/ $img2 = imagecreatetruecolor($nW, $nH); imagealphablending($img2, false); imagesavealpha($img2, true); imagealphablending($img, true); // Assign a transparency color. //$trans = imagecolorallocatealpha($img2, 0, 0, 0, 0); //imagefill($img2, 0, 0, $trans); imagecopyresampled($img2, $img, 0, 0, 0, 0, $nW, $nH, $sW, $sH); imagedestroy($img); switch ($m) { case 'image/jpeg': imagejpeg($img2, $file->getFilename(), 60); \Core\Utilities\Logger\write_debug('Resizing complete (via imagejpeg)'); break; case 'image/png': imagepng($img2, $file->getFilename(), 9); \Core\Utilities\Logger\write_debug('Resizing complete (via imagepng)'); break; case 'image/gif': imagegif($img2, $file->getFilename()); \Core\Utilities\Logger\write_debug('Resizing complete (via imagegif)'); break; default: // Hmmm... \Core\Utilities\Logger\write_debug('Resizing complete (failed, not sure what it was)'); return; } } }
private function _loadDB(){ Core\Utilities\Logger\write_debug('Config data loading from database'); // Clear out the cache, (if it has any) $this->_clearCache(); // Get a list of config models in the system. // These will be the root configuration options needed for any other system. $fac = ConfigModel::Find(); foreach ($fac as $config) { /** @var $config ConfigModel */ $key = $config->get('key'); $this->_cacheFromDB[$key] = $config; $val = $config->getValue(); // Set the defines on any that need to be defined, (via the "mapto" attribute) if($config->get('mapto') && !defined($config->get('mapto'))){ define($config->get('mapto'), $val); } } Core\Utilities\Logger\write_debug('Config data loaded from database'); }
/** * Start recording a given query. * * @param string $type "read" or "write", (usually). * @param string $query Human-readable version of the query string. */ public function start($type, $query){ // Record this query! // This needs to include the query itself, what type it was, how long it took to execute, // any errors it produced, and where in the code it was called. if(FULL_DEBUG || (DEVELOPMENT_MODE && sizeof($this->_events) < 40)){ // By skipping this in production, memory usage is cut by nearly 50% on über DB heavy pages! // (This occurs on pages that have more than 10k queries. $debug = debug_backtrace(); $callinglocation = array(); $count = 0; $totalcount = 0; foreach($debug as $d){ $class = (isset($d['class'])) ? $d['class'] : null; ++$totalcount; if(strpos($class, 'Core\\Datamodel') === 0) continue; if(strpos($class, 'Core\\Utilities\\Profiler') === 0) continue; if($class == 'Model') continue; $file = (isset($d['file'])) ? (substr($d['file'], strlen(ROOT_PDIR))) : 'anonymous'; $line = (isset($d['line'])) ? (':' . $d['line']) : ''; $func = ($class !== null) ? ($d['class'] . $d['type'] . $d['function']) : $d['function']; $callinglocation[] = $file . $line . ', [' . $func . '()]'; ++$count; if($count >= 3 && sizeof($debug) >= $totalcount + 2){ $callinglocation[] = '...'; break; } } } else{ $callinglocation = ['**SKIPPED** Please enable FULL_DEBUG to see the calling stack.']; } \Core\Utilities\Logger\write_debug('DatamodelProfiler: [' . $type . '] ' . $query); $this->_last[] = [ 'start' => microtime(true), 'type' => $type, 'query' => $query, 'caller' => $callinglocation, 'memory' => memory_get_usage(true), ]; }
/** * Internal function to parse and handle the configs in the component.xml file. * This is used for installations and upgrades. * * @param boolean $install Set to false to force uninstall/disable mode. * @param int $verbosity (default 0) 0: standard output, 1: real-time, 2: real-time verbose output. * * @return boolean | int * @throws InstallerException */ public function _parsePages($install = true, $verbosity = 0) { $changes = array(); $overallAction = $install ? 'Installing' : 'Uninstalling'; Core\Utilities\Logger\write_debug($overallAction . ' pages for ' . $this->getName()); // I need to get the schema definitions first. $node = $this->_xmlloader->getElement('pages'); //$prefix = $node->getAttribute('prefix'); // Now, get every table under this node. foreach ($node->getElementsByTagName('page') as $subnode) { /** @var DomElement $subnode */ $baseurl = $subnode->getAttribute('baseurl'); // Insert/Update the defaults for an entry in the database. // These are always global pages. $m = new PageModel(-1, $baseurl); if($verbosity == 2){ CLI::PrintActionStart($overallAction . ' page ' . $baseurl); } // Hard-set pages get removed upon disabling. They'll be recreated if re-enabled. if($install){ // Just something to help the log. $action = ($m->exists()) ? 'Updated' : 'Added'; $admin = $subnode->getAttribute('admin'); $selectable = ($admin ? '0' : '1'); // Defaults $group = ($admin ? $subnode->getAttribute('group') : ''); if($subnode->getAttribute('selectable') !== ''){ $selectable = $subnode->getAttribute('selectable'); } $indexable = ($subnode->getAttribute('indexable') !== '') ? $subnode->getAttribute('indexable') : $selectable; $editurl = $subnode->getAttribute('editurl') ? $subnode->getAttribute('editurl') : ''; $access = ($subnode->getAttribute('access')) ? $subnode->getAttribute('access') : null; // Do not "update" value, keep whatever the user set previously. if (!$m->get('rewriteurl')) { if ($subnode->getAttribute('rewriteurl')) $m->set('rewriteurl', $subnode->getAttribute('rewriteurl')); else $m->set('rewriteurl', $subnode->getAttribute('baseurl')); } // Do not "update" value, keep whatever the user set previously. if (!$m->get('title')) $m->set('title', $subnode->getAttribute('title')); if($access !== null){ $m->set('access', $access); } // Do not update parent urls if the page already exists. if(!$m->exists()) $m->set('parenturl', $subnode->getAttribute('parenturl')); //$m->set('widget', $subnode->getAttribute('widget')); $m->set('admin', $admin); $m->set('admin_group', $group); $m->set('selectable', $selectable); $m->set('indexable', $indexable); $m->set('component', $this->getKeyName()); $m->set('editurl', $editurl); if ($m->save()){ $changes[] = $action . ' page [' . $baseurl . ']'; if($verbosity == 2){ CLI::PrintActionStatus(true); } } else{ if($verbosity == 2){ CLI::PrintActionStatus('skip'); } } } else{ $m->delete(); $changes[] = 'Removed page [' . $subnode->getAttribute('baseurl') . ']'; if($verbosity == 2){ CLI::PrintActionStatus(true); } } } return ($changes > 0) ? $changes : false; }
Core\Utilities\Logger\write_debug('Loading hook handler'); require_once(ROOT_PDIR . "core/libs/core/HookHandler.class.php"); // Pre includes are ready. $preincludes_time = microtime(true); // And start the core! Core\Utilities\Logger\write_debug('Loading core system'); //require_once(ROOT_PDIR . 'core/libs/core/InstallTask.class.php'); require_once(ROOT_PDIR . 'core/libs/core/Core.class.php'); //Core::Singleton(); // Configuration handler, for loading any config variable/constant from XML data or the database. Core\Utilities\Logger\write_debug('Loading configs'); require_once(ROOT_PDIR . "core/libs/core/ConfigHandler.class.php"); ConfigHandler::Singleton(); \Core\Utilities\Profiler\Profiler::GetDefaultProfiler()->record('Configuration loaded and available'); // Give me core settings! // This will do the defines for the site, and provide any core variables to get started. $core_settings = ConfigHandler::LoadConfigFile("configuration"); if (!$core_settings) { if(EXEC_MODE == 'WEB'){ $newURL = 'install/'; //header('HTTP/1.1 302 Moved Temporarily'); //header("Location:" . $newURL); // This is not just redirected automatically because many browsers remember the redirect and just insist on redirecting from / to /install!
} // Start a traditional session. if(!file_exists(TMP_DIR . 'sessions')){ mkdir(TMP_DIR . 'sessions', 0700, true); } session_save_path(TMP_DIR . 'sessions'); session_start(); /********************* Initial system defines *********************************/ require_once(__DIR__ . '/../core/bootstrap_predefines.php'); Core\Utilities\Logger\write_debug('Starting Application'); /********************** Critical file inclusions ******************************/ Core\Utilities\Logger\write_debug('Loading pre-include files'); require_once(__DIR__ . '/../core/bootstrap_preincludes.php'); require_once(ROOT_PDIR . 'core/libs/core/templates/TemplateInterface.php'); require_once(ROOT_PDIR . 'core/libs/core/templates/Exception.php'); require_once(ROOT_PDIR . 'core/libs/core/templates/Template.php'); require_once(ROOT_PDIR . 'core/libs/core/templates/backends/PHTML.php'); //require_once(ROOT_PDIR . 'core/libs/core/Exception.php'); require_once(ROOT_PDIR . 'install/classes/InstallerStep.php'); require_once(ROOT_PDIR . 'core/functions/Core.functions.php'); require_once(ROOT_PDIR . 'install/utilities.php'); require_once(ROOT_PDIR . "core/libs/core/ConfigHandler.class.php");