2 // Own namespace (watch out: core)
3 namespace CoreFramework\EntryPoint;
5 // Import framework stuff
6 use CoreFramework\Configuration\FrameworkConfiguration;
7 use CoreFramework\Factory\ObjectFactory;
8 use CoreFramework\Helper\Application\ApplicationHelper;
9 use CoreFramework\Loader\ClassLoader;
10 use CoreFramework\Generic\FrameworkException;
13 * The main class with the entry point to the whole application. This class
14 * "emulates" Java's entry point call. Additionally it covers local
15 * variables from outside access to prevent possible attacks on uninitialized
18 * But good little boys and girls would always initialize their variables... ;-)
20 * @author Roland Haeder <webmaster@shipsimu.org>
22 * @copyright Copyright (c) 2007, 2008 Roland Haeder, 2009 - 2015 Core Developer Team
23 * @license GNU GPL 3.0 or any newer version
24 * @link http://www.shipsimu.org
26 * This program is free software: you can redistribute it and/or modify
27 * it under the terms of the GNU General Public License as published by
28 * the Free Software Foundation, either version 3 of the License, or
29 * (at your option) any later version.
31 * This program is distributed in the hope that it will be useful,
32 * but WITHOUT ANY WARRANTY; without even the implied warranty of
33 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
34 * GNU General Public License for more details.
36 * You should have received a copy of the GNU General Public License
37 * along with this program. If not, see <http://www.gnu.org/licenses/>.
39 final class ApplicationEntryPoint {
43 private static $corePath = '';
46 * The application's emergency exit
48 * @param $message The optional message we shall output on exit
49 * @param $code Error code from exception
50 * @param $extraData Extra information from exceptions
51 * @param $silentMode Whether silent mode is turned on
53 * @todo This method is old code and needs heavy rewrite and should be moved to ApplicationHelper
55 public static final function app_exit ($message = '', $code = FALSE, $extraData = '', $silentMode = FALSE) {
56 // Is this method already called?
57 if (isset($GLOBALS['app_die_called'])) {
58 // Then output the text directly
62 // This method shall not be called twice
63 $GLOBALS['app_die_called'] = TRUE;
66 if (empty($message)) {
67 // No message provided
68 $message = 'No message provided.';
71 // Get config instance
72 $configInstance = FrameworkConfiguration::getSelfInstance();
74 // Do we have debug installation?
75 if (($configInstance->getConfigEntry('product_install_mode') == 'productive') || ($silentMode === TRUE)) {
81 $tpl = FrameworkConfiguration::getSelfInstance()->getConfigEntry('html_template_class');
82 $languageInstance = LanguageSystem::getSelfInstance();
84 // Initialize template instance here to avoid warnings in IDE
85 $templateInstance = NULL;
87 // Get response instance
88 $responseInstance = ApplicationHelper::getSelfInstance()->getResponseInstance();
90 // Is the template engine loaded?
91 if ((class_exists($tpl)) && (is_object($languageInstance))) {
92 // Use the template engine for putting out (nicer look) the message
94 // Get the template instance from our object factory
95 $templateInstance = ObjectFactory::createObjectByName($tpl);
96 } catch (FrameworkException $e) {
97 exit(sprintf("[Main:] Could not initialize template engine for reason: <span class=\"exception_reason\">%s</span>",
102 // Get and prepare backtrace for output
103 $backtraceArray = debug_backtrace();
105 foreach ($backtraceArray as $key => $trace) {
106 // Set missing array elements
107 if (!isset($trace['file'])) {
108 $trace['file'] = __FILE__;
110 if (!isset($trace['line'])) {
111 $trace['line'] = __LINE__;
113 if (!isset($trace['args'])) {
114 $trace['args'] = array();
117 // Add the traceback path to the final output
118 $backtrace .= sprintf("<span class=\"backtrace_file\">%s</span>:%d, <span class=\"backtrace_function\">%s(%d)</span><br />\n",
119 basename($trace['file']),
122 count($trace['args'])
126 // Init application instance
127 $applicationInstance = NULL;
129 // Is the class there?
130 if (class_exists('CoreFramework\Helper\Application\ApplicationHelper')) {
131 // Get application instance
132 $applicationInstance = ApplicationHelper::getSelfInstance();
134 // Assign application data
135 $templateInstance->assignApplicationData($applicationInstance);
141 $templateInstance->assignVariable('message', $message);
142 $templateInstance->assignVariable('code', $code);
143 $templateInstance->assignVariable('extra', $extraData);
144 $templateInstance->assignVariable('backtrace', $backtrace);
145 $templateInstance->assignVariable('total_includes', ClassLoader::getSelfInstance()->getTotal());
146 $templateInstance->assignVariable('total_objects', ObjectFactory::getTotal());
147 $templateInstance->assignVariable('title', $languageInstance->getMessage('emergency_exit_title'));
150 $templateInstance->loadCodeTemplate('emergency_exit');
152 // Compile the template
153 $templateInstance->compileTemplate();
155 // Compile all variables
156 $templateInstance->compileVariables();
158 // Transfer data to response
159 $templateInstance->transferToResponse($responseInstance);
161 // Flush the response
162 $responseInstance->flushBuffer();
163 } catch (FileNotFoundException $e) {
164 // Even the template 'emergency_exit' wasn't found so output both message
165 exit($message . ', exception: ' . $e->getMessage());
171 // Output message and die
172 exit(sprintf('[Main:] Emergency exit reached: <span class="emergency_span">%s</span>',
179 * Determines the correct absolute path for all includes only once per run.
180 * Other calls of this method are being "cached". This is done by checking
181 * a small list of common paths where the framework can reside and check if
182 * framework/config.php can be found.
184 * @return $corePath Base path (core) for all includes
186 protected static final function detectCorePath () {
188 if (empty(self::$corePath)) {
189 // Auto-detect core path (first application-common)
190 foreach (array('core', '.') as $possiblePath) {
191 // Create full path for testing
192 $realPath = realpath($possiblePath);
195 //* NOISY-DEBUG: */ printf('[%s:%d]: realPath[%s]=%s' . PHP_EOL, __METHOD__, __LINE__, gettype($realPath), $realPath);
198 if ($realPath === FALSE) {
203 // First create full-qualified file name (FQFN) to framework/config.php
205 '%s%sframework%sconfig.php',
213 //* NOISY-DEBUG: */ printf('[%s:%d]: fqfn=%s' . PHP_EOL, __METHOD__, __LINE__, $fqfn);
216 if (is_readable($fqfn)) {
218 self::$corePath = $realPath;
227 return self::$corePath;
231 * The framework's main entry point. This class isolates some local
232 * variables which shall not become visible to outside because of security
233 * concerns. This is done here to "emulate" the well-known entry point in
238 public static final function main () {
239 // Load config file, this no longer provides $cfg
240 require(self::detectCorePath() . '/framework/config.php');
242 // Get a new configuration instance
243 $cfg = FrameworkConfiguration::getSelfInstance();
245 // Load bootstrap class
246 require($cfg->getConfigEntry('base_path') . 'framework/bootstrap/class_BootstrapFramework.php');
248 // ----- Below is deprecated -----
250 // Load all include files
251 require($cfg->getConfigEntry('base_path') . 'framework/includes.php');
253 // Include the application selector
254 require($cfg->getConfigEntry('base_path') . 'framework/selector.php');
258 // Developer mode active? Comment out if no dev!
259 define('DEVELOPER', TRUE);
261 // Log all exceptions (only debug! This option can create large error logs)
262 //define('LOG_EXCEPTIONS', TRUE);
264 //xdebug_start_trace();
266 // Call above main() method
267 ApplicationEntryPoint::main();