]> git.mxchange.org Git - core.git/blob - framework/bootstrap/class_FrameworkBootstrap.php
Continued:
[core.git] / framework / bootstrap / class_FrameworkBootstrap.php
1 <?php
2 // Own namespace
3 namespace Org\Mxchange\CoreFramework\Bootstrap;
4
5 // Import framework stuff
6 use Org\Mxchange\CoreFramework\Configuration\FrameworkConfiguration;
7 use Org\Mxchange\CoreFramework\Connection\Database\DatabaseConnection;
8 use Org\Mxchange\CoreFramework\Connector\Database\DatabaseConnector;
9 use Org\Mxchange\CoreFramework\Console\Tools\ConsoleTools;
10 use Org\Mxchange\CoreFramework\EntryPoint\ApplicationEntryPoint;
11 use Org\Mxchange\CoreFramework\Factory\Object\ObjectFactory;
12 use Org\Mxchange\CoreFramework\Generic\FrameworkInterface;
13 use Org\Mxchange\CoreFramework\Generic\NullPointerException;
14 use Org\Mxchange\CoreFramework\Helper\Application\ApplicationHelper;
15 use Org\Mxchange\CoreFramework\Localization\ManageableLanguage;
16 use Org\Mxchange\CoreFramework\Loader\ClassLoader;
17 use Org\Mxchange\CoreFramework\Manager\ManageableApplication;
18 use Org\Mxchange\CoreFramework\Middleware\Debug\DebugMiddleware;
19 use Org\Mxchange\CoreFramework\Object\BaseFrameworkSystem;
20 use Org\Mxchange\CoreFramework\Registry\GenericRegistry;
21 use Org\Mxchange\CoreFramework\Request\Requestable;
22 use Org\Mxchange\CoreFramework\Response\Responseable;
23 use Org\Mxchange\CoreFramework\Utils\Strings\StringUtils;
24
25 // Import SPL stuff
26 use \BadMethodCallException;
27 use \InvalidArgumentException;
28 use \SplFileInfo;
29
30 /**
31  * A framework-bootstrap class which helps the frameworks to bootstrap ... ;-)
32  *
33  * @author              Roland Haeder <webmaster@ship-simu.org>
34  * @version             0.0.0
35  * @copyright   Copyright (c) 2007, 2008 Roland Haeder, 2009 - 2023 Core Developer Team
36  * @license             GNU GPL 3.0 or any newer version
37  * @link                http://www.ship-simu.org
38  *
39  * This program is free software: you can redistribute it and/or modify
40  * it under the terms of the GNU General Public License as published by
41  * the Free Software Foundation, either version 3 of the License, or
42  * (at your option) any later version.
43  *
44  * This program is distributed in the hope that it will be useful,
45  * but WITHOUT ANY WARRANTY; without even the implied warranty of
46  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
47  * GNU General Public License for more details.
48  *
49  * You should have received a copy of the GNU General Public License
50  * along with this program. If not, see <http://www.gnu.org/licenses/>.
51  */
52 final class FrameworkBootstrap {
53
54         /**
55          * Detected server address
56          */
57         private static $serverAddress = NULL;
58
59         /**
60          * Instance of a Requestable class
61          */
62         private static $requestInstance = NULL;
63
64         /**
65          * Instance of a Responseable class
66          */
67         private static $responseInstance = NULL;
68
69         /**
70          * Instance of a FrameworkConfiguration class
71          */
72         private static $configurationInstance = NULL;
73
74         /**
75          * Database instance
76          */
77         private static $databaseInstance = NULL;
78
79         /**
80          * Language system instance
81          */
82         private static $languageInstance = NULL;
83
84         /*
85          * Includes applications may have. They will be tried in the given order,
86          * some will become soon deprecated.
87          */
88         private static $configAppIncludes = [
89                 // The ApplicationHelper class (required)
90                 'class_ApplicationHelper' => 'required',
91                 // Some debugging stuff (optional but can be committed)
92                 'debug'                   => 'optional',
93                 // Application's exception handler (optional but can be committed)
94                 'exceptions'              => 'optional',
95                 // Application's configuration file (committed, non-local specific)
96                 'config'                  => 'required',
97                 // Local configuration file (optional, not committed, listed in .gitignore)
98                 'config-local'            => 'optional',
99                 // Application data (deprecated)
100                 'data'                    => 'deprecated',
101                 // Application loader (deprecated)
102                 'loader'                  => 'deprecated',
103                 // Application initializer (deprecated)
104                 'init'                    => 'deprecated',
105                 // Application starter (deprecated)
106                 'starter'                 => 'deprecated',
107         ];
108
109         /**
110          * Detected application's name
111          */
112         private static $detectedApplicationName;
113
114         /**
115          * Detected application's full path
116          */
117         private static $detectedApplicationPath;
118
119         /**
120          * Private constructor, no instance is needed from this class as only
121          * static methods exist.
122          */
123         private function __construct () {
124                 // Prevent making instances from this "utilities" class
125         }
126
127         /**
128          * Some "getter" for a configuration instance, making sure, it is unique
129          *
130          * @return      $configurationInstance  An instance of a FrameworkConfiguration class
131          */
132         public static function getConfigurationInstance () {
133                 // Is the instance there?
134                 if (is_null(self::$configurationInstance)) {
135                         // Init new instance
136                         self::$configurationInstance = new FrameworkConfiguration();
137                 }
138
139                 // Return it
140                 return self::$configurationInstance;
141         }
142
143         /**
144          * Getter for detected application name
145          *
146          * @return      $detectedApplicationName        Detected name of application
147          */
148         public static function getDetectedApplicationName () {
149                 return self::$detectedApplicationName;
150         }
151
152         /**
153          * Getter for detected application's full path
154          *
155          * @return      $detectedApplicationPath        Detected full path of application
156          */
157         public static function getDetectedApplicationPath () {
158                 return self::$detectedApplicationPath;
159         }
160
161         /**
162          * "Getter" to get response/request type from analysis of the system.
163          *
164          * @return      $requestType    Analyzed request type
165          */
166         public static function getRequestTypeFromSystem () {
167                 // Default is console
168                 $requestType = 'console';
169
170                 // Is 'HTTP_HOST' set?
171                 if (isset($_SERVER['HTTP_HOST'])) {
172                         // Then it is a HTML response/request.
173                         $requestType = 'html';
174                 }
175
176                 // Return it
177                 return $requestType;
178         }
179
180         /**
181          * Checks whether the given file/path is in open_basedir(). This does not
182          * gurantee that the file is actually readable and/or writeable. If you need
183          * such gurantee then please use isReadableFile() instead.
184          *
185          * @param       $fileInstance   An instance of a SplFileInfo class
186          * @return      $isReachable    Whether it is within open_basedir()
187          */
188         public static function isReachableFilePath (SplFileInfo $fileInstance) {
189                 // Is not reachable by default
190                 //* NOISY-DEBUG: */ printf('[%s:%d]: fileInstance=%s - CALLED!' . PHP_EOL, __METHOD__, __LINE__, get_class($fileInstance));
191                 $isReachable = false;
192
193                 // Get open_basedir parameter
194                 $openBaseDir = trim(ini_get('open_basedir'));
195
196                 // Is it set?
197                 //* NOISY-DEBUG: */ printf('[%s:%d]: openBaseDir=%s' . PHP_EOL, __METHOD__, __LINE__, $openBaseDir);
198                 if (!empty($openBaseDir)) {
199                         // Check all entries
200                         foreach (explode(PATH_SEPARATOR, $openBaseDir) as $dir) {
201                                 // Check on existence
202                                 //* NOISY-DEBUG: */ printf('[%s:%d]: dir=%s' . PHP_EOL, __METHOD__, __LINE__, $dir);
203                                 if (substr($fileInstance->getPathname(), 0, strlen($dir)) == $dir) {
204                                         // Is reachable
205                                         $isReachable = true;
206
207                                         // Abort lookup as it has been found in open_basedir
208                                         //* NOISY-DEBUG: */ printf('[%s:%d]: BREAK!' . PHP_EOL, __METHOD__, __LINE__);
209                                         break;
210                                 }
211                         }
212                 } else {
213                         // If open_basedir is not set, all is allowed
214                         //* NOISY-DEBUG: */ printf('[%s:%d]: All is allowed - BREAK!' . PHP_EOL, __METHOD__, __LINE__);
215                         $isReachable = true;
216                 }
217
218                 // Return status
219                 //* NOISY-DEBUG: */ printf('[%s:%d]: isReachable=%d - EXIT' . PHP_EOL, __METHOD__, __LINE__, intval($isReachable));
220                 return $isReachable;
221         }
222
223         /**
224          * Checks whether the give file is within open_basedir() (done by
225          * isReachableFilePath()), is actually a file and is readable.
226          *
227          * @param       $fileInstance   An instance of a SplFileInfo class
228          * @return      $isReadable             Whether the file is readable (and therefor exists)
229          */
230         public static function isReadableFile (SplFileInfo $fileInstance) {
231                 // Default is not readable
232                 $isReadable = false;
233
234                 // Check if it is a file and readable
235                 $isReadable = (
236                         (
237                                 self::isReachableFilePath($fileInstance)
238                         ) && (
239                                 $fileInstance->isFile()
240                         ) && (
241                                 $fileInstance->isReadable()
242                         )
243                 );
244
245                 // Return status
246                 return $isReadable;
247         }
248
249         /**
250          * Loads given include file
251          *
252          * @param       $fileInstance   An instance of a SplFileInfo class
253          * @return      void
254          * @throws      InvalidArgumentException        If file was not found or not readable or deprecated
255          */
256         public static function loadInclude (SplFileInfo $fileInstance) {
257                 // Should be there ...
258                 //* NOISY-DEBUG: */ printf('[%s:%d]: fileInstance=%s - CALLED!' . PHP_EOL, __METHOD__, __LINE__, $fileInstance);
259                 if (!self::isReadableFile($fileInstance)) {
260                         // Abort here
261                         throw new InvalidArgumentException(sprintf('Cannot find fileInstance.pathname=%s.', $fileInstance->getPathname()));
262                 }
263
264                 // Load it
265                 require_once $fileInstance->getPathname();
266
267                 // Trace message
268                 //* NOISY-DEBUG: */ printf('[%s:%d]: EXIT!' . PHP_EOL, __METHOD__, __LINE__);
269         }
270
271         /**
272          * Does the actual bootstrap. I think the amount of statically loaded
273          * include files cannot be reduced here as those files are need to early
274          * in the bootstrap phase. If you can find an other solution than this, with
275          * lesser "static includes" (means not loaded by the class loader), please
276          * let me know.
277          *
278          * @return      void
279          */
280         public static function doBootstrap () {
281                 // Load basic include files to continue bootstrapping
282                 //* NOISY-DEBUG: */ printf('[%s:%d]: CALLED!' . PHP_EOL, __METHOD__, __LINE__);
283                 self::loadInclude(new SplFileInfo(sprintf('%smain%sinterfaces%sclass_FrameworkInterface.php', ApplicationEntryPoint::detectFrameworkPath(), DIRECTORY_SEPARATOR, DIRECTORY_SEPARATOR)));
284                 self::loadInclude(new SplFileInfo(sprintf('%smain%sclasses%sclass_BaseFrameworkSystem.php', ApplicationEntryPoint::detectFrameworkPath(), DIRECTORY_SEPARATOR, DIRECTORY_SEPARATOR)));
285                 self::loadInclude(new SplFileInfo(sprintf('%smain%sclasses%sutils%sstrings%sclass_StringUtils.php', ApplicationEntryPoint::detectFrameworkPath(), DIRECTORY_SEPARATOR, DIRECTORY_SEPARATOR, DIRECTORY_SEPARATOR, DIRECTORY_SEPARATOR)));
286                 self::loadInclude(new SplFileInfo(sprintf('%smain%sinterfaces%sregistry%sclass_Registerable.php', ApplicationEntryPoint::detectFrameworkPath(), DIRECTORY_SEPARATOR, DIRECTORY_SEPARATOR, DIRECTORY_SEPARATOR)));
287                 self::loadInclude(new SplFileInfo(sprintf('%sconfig%sclass_FrameworkConfiguration.php', ApplicationEntryPoint::detectFrameworkPath(), DIRECTORY_SEPARATOR)));
288
289                 // Load global configuration
290                 self::loadInclude(new SplFileInfo(sprintf('%s%s', ApplicationEntryPoint::detectFrameworkPath(), 'config-global.php')));
291
292                 // Trace message
293                 //* NOISY-DEBUG: */ printf('[%s:%d]: EXIT!' . PHP_EOL, __METHOD__, __LINE__);
294         }
295
296         /**
297          * Initializes the framework by scanning for all framework-relevant
298          * classes, interfaces and exception. Then determine the request type and
299          * initialize a Requestable instance which will then contain all request
300          * parameter, also from CLI. Next step is to validate the application
301          * (very basic).
302          *
303          * @return      void
304          */
305         public static function initFramework () {
306                 /**
307                  * 1) Load class loader and scan framework classes, interfaces and
308                  *    exceptions.
309                  */
310                 self::scanFrameworkClasses();
311
312                 /*
313                  * 2) Determine the request type, console or web and store request and
314                  *    response here. This also initializes the request instance with
315                  *    all given parameters (see doc-tag for possible sources of
316                  *    parameters).
317                  */
318                 self::determineRequestType();
319
320                 /*
321                  * 3) Now, that there are all request parameters being available, check
322                  *    if 'application' is supplied. If it is not found, abort execution, if
323                  *    found, continue below with next step.
324                  */
325                 self::validateApplicationParameter();
326         }
327
328         /**
329          * Initializes the detected application. This may fail if required files
330          * are not found in the application's base path (not to be confused with
331          * 'application_base_path' which only points to /some/foo/application/.
332          *
333          * @return      void
334          */
335         public static function prepareApplication () {
336                 /*
337                  * Now check and load all files, found deprecated files will throw a
338                  * warning at the user.
339                  */
340                 foreach (self::$configAppIncludes as $fileName => $status) {
341                         // Construct file instance
342                         $fileInstance = new SplFileInfo(sprintf('%s%s.php', self::getDetectedApplicationPath(), $fileName));
343
344                         // Determine if this file is wanted/readable/deprecated
345                         if (($status == 'required') && (!self::isReadableFile($fileInstance))) {
346                                 // Nope, required file cannot be found/read from
347                                 ApplicationEntryPoint::exitApplication(sprintf('Application "%s" does not have required file "%s.php". Please add it.', self::getDetectedApplicationName(), $fileInstance->getBasename()));
348                         } elseif (($fileInstance->isFile()) && (!$fileInstance->isReadable())) {
349                                 // Found, not readable file
350                                 ApplicationEntryPoint::exitApplication(sprintf('File "%s.php" from application "%s" cannot be read. Please fix CHMOD.', $fileInstance->getBasename(), self::getDetectedApplicationName()));
351                         } elseif (($status != 'required') && (!self::isReadableFile($fileInstance))) {
352                                 // Not found but optional/deprecated file, skip it
353                                 continue;
354                         }
355
356                         // Is the file deprecated?
357                         if ($status == 'deprecated') {
358                                 // Issue warning
359                                 trigger_error(sprintf('Deprecated file "%s.php" found, will not load it to avoid problems. Please remove it from your application "%s" to avoid this warning.', $fileName, self::getDetectedApplicationName()), E_USER_WARNING);
360
361                                 // Skip loading deprecated file
362                                 continue;
363                         }
364
365                         // Load it
366                         self::loadInclude($fileInstance);
367                 }
368
369                 // After this, sort the configuration array
370                 self::getConfigurationInstance()->sortConfigurationArray();
371
372                 // Scan for application's classes, exceptions and interfaces
373                 ClassLoader::scanApplicationClasses();
374         }
375
376         /**
377          * Starts a fully initialized application, the class ApplicationHelper must
378          * be loaded at this point.
379          *
380          * @return      void
381          */
382         public static function startApplication () {
383                 // Is there an application helper instance?
384                 $applicationInstance = call_user_func_array(
385                         [
386                                 'Org\Mxchange\CoreFramework\Helper\Application\ApplicationHelper', 'getSelfInstance'
387                         ], []
388                 );
389
390                 // Some sanity checks
391                 if ((empty($applicationInstance)) || (is_null($applicationInstance))) {
392                         // Something went wrong!
393                         ApplicationEntryPoint::exitApplication(sprintf('[Main:] The application <span class="app_name">%s</span> could not be launched because the helper class <span class="class_name">%s</span> is not loaded.',
394                                 self::getDetectedApplicationName(),
395                                 'Org\Mxchange\CoreFramework\Helper\Application\ApplicationHelper'
396                         ));
397                 } elseif (!is_object($applicationInstance)) {
398                         // No object!
399                         ApplicationEntryPoint::exitApplication(sprintf('[Main:] The application <span class="app_name">%s</span> could not be launched because &#39;app&#39; is not an object (%s).',
400                                 self::getDetectedApplicationName(),
401                                 gettype($applicationInstance)
402                         ));
403                 } elseif (!($applicationInstance instanceof ManageableApplication)) {
404                         // Missing interface
405                         ApplicationEntryPoint::exitApplication(sprintf('[Main:] The application <span class="app_name">%s</span> could not be launched because &#39;app&#39; is lacking required interface ManageableApplication.',
406                                 self::getDetectedApplicationName()
407                         ));
408                 }
409
410                 // Now call all methods in one go
411                 foreach (['setupApplicationData', 'initApplication', 'launchApplication'] as $methodName) {
412                         // Call method
413                         //*NOISY-DEBUG: */ printf('[%s:%d]: Calling methodName=%s ...' . PHP_EOL, __METHOD__, __LINE__, $methodName);
414                         call_user_func([$applicationInstance, $methodName]);
415                 }
416         }
417
418         /**
419          * Initializes database instance, no need to double-call this method
420          *
421          * @return      void
422          */
423         public static function initDatabaseInstance () {
424                 // Get application instance
425                 $applicationInstance = ApplicationHelper::getSelfInstance();
426
427                 // Is the database instance already set?
428                 if (self::getDatabaseInstance() instanceof DatabaseConnector) {
429                         // Yes, then abort here
430                         throw new BadMethodCallException('Method called twice.');
431                 }
432
433                 // Initialize database layer
434                 $databaseInstance = ObjectFactory::createObjectByConfiguredName(self::getConfigurationInstance()->getConfigEntry('database_type') . '_class');
435
436                 // Prepare database instance
437                 $connectionInstance = DatabaseConnection::createDatabaseConnection(DebugMiddleware::getSelfInstance(), $databaseInstance);
438
439                 // Set it in application helper
440                 self::setDatabaseInstance($connectionInstance);
441         }
442
443         /**
444          * Detects the server address (SERVER_ADDR) and set it in configuration
445          *
446          * @return      $serverAddress  The detected server address
447          * @throws      UnknownHostnameException        If SERVER_NAME cannot be resolved to an IP address
448          * @todo        Have to check some more entries from $_SERVER here
449          */
450         public static function detectServerAddress () {
451                 // Is the entry set?
452                 if (!isset(self::$serverAddress)) {
453                         // Is it set in $_SERVER?
454                         if (!empty($_SERVER['SERVER_ADDR'])) {
455                                 // Set it from $_SERVER
456                                 self::$serverAddress = $_SERVER['SERVER_ADDR'];
457                         } elseif (isset($_SERVER['SERVER_NAME'])) {
458                                 // Resolve IP address
459                                 $serverIp = ConsoleTools::resolveIpAddress($_SERVER['SERVER_NAME']);
460
461                                 // Is it valid?
462                                 if ($serverIp === false) {
463                                         /*
464                                          * Why is gethostbyname() returning the host name and not
465                                          * false as many other PHP functions are doing? ;-(
466                                          */
467                                         throw new UnknownHostnameException(sprintf('Cannot resolve "%s" to an IP address. Please fix your setup.', $_SERVER['SERVER_NAME']));
468                                 }
469
470                                 // Al fine, set it
471                                 self::$serverAddress = $serverIp;
472                         } else {
473                                 // Run auto-detecting through console tools lib
474                                 self::$serverAddress = ConsoleTools::acquireSelfIpAddress();
475                         }
476                 }
477
478                 // Return it
479                 return self::$serverAddress;
480         }
481
482         /**
483          * Setter for default time zone (must be correct!)
484          *
485          * @param       $timezone       The timezone string (e.g. Europe/Berlin)
486          * @return      $success        If timezone was accepted
487          * @throws      InvalidArgumentException        If $timezone is empty
488          */
489         public static function setDefaultTimezone (string $timezone) {
490                 // Is it set?
491                 if (empty($timezone)) {
492                         // Entry is empty
493                         throw new InvalidArgumentException('Parameter "timezone" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
494                 }
495
496                 // Default success
497                 $success = FALSE;
498
499                 /*
500                  * Set desired time zone to prevent date() and related functions to
501                  * issue an E_WARNING.
502                  */
503                 $success = date_default_timezone_set($timezone);
504
505                 // Return status
506                 return $success;
507         }
508
509         /**
510          * Checks whether HTTPS is set in $_SERVER
511          *
512          * @return      $isset  Whether HTTPS is set
513          * @todo        Test more fields
514          */
515         public static function isHttpSecured () {
516                 return (
517                         (
518                                 (
519                                         isset($_SERVER['HTTPS'])
520                                 ) && (
521                                         strtolower($_SERVER['HTTPS']) == 'on'
522                                 )
523                         ) || (
524                                 (
525                                         isset($_SERVER['HTTP_X_FORWARDED_PROTO'])
526                                 ) && (
527                                         strtolower($_SERVER['HTTP_X_FORWARDED_PROTO']) == 'https'
528                                 )
529                         )
530                 );
531         }
532
533         /**
534          * Dectect and return the base URL for all URLs and forms
535          *
536          * @return      $baseUrl        Detected base URL
537          */
538         public static function detectBaseUrl () {
539                 // Initialize the URL
540                 $protocol = 'http';
541
542                 // Do we have HTTPS?
543                 if (self::isHttpSecured()) {
544                         // Add the >s< for HTTPS
545                         $protocol = 'https';
546                 }
547
548                 // Construct the full URL and secure it against CSRF attacks
549                 $baseUrl = sprintf('%s://%s%s', $protocol, self::detectDomain(), self::detectScriptPath());
550
551                 // Return the URL
552                 return $baseUrl;
553         }
554
555         /**
556          * Detect safely and return the full domain where this script is installed
557          *
558          * @return      $fullDomain             The detected full domain
559          */
560         public static function detectDomain () {
561                 // Full domain is localnet.invalid by default
562                 $fullDomain = 'localnet.invalid';
563
564                 // Is the server name there?
565                 if (isset($_SERVER['SERVER_NAME'])) {
566                         // Detect the full domain
567                         $fullDomain = htmlentities(strip_tags($_SERVER['SERVER_NAME']), ENT_QUOTES);
568                 }
569
570                 // Return it
571                 return $fullDomain;
572         }
573
574         /**
575          * Detect safely the script path without trailing slash which is the glue
576          * between "http://your-domain.invalid/" and "script-name.php"
577          *
578          * @return      $scriptPath             The script path extracted from $_SERVER['SCRIPT_NAME']
579          */
580         public static function detectScriptPath () {
581                 // Default is empty
582                 $scriptPath = '';
583
584                 // Is the scriptname set?
585                 if (isset($_SERVER['SCRIPT_NAME'])) {
586                         // Get dirname from it and replace back-slashes with slashes for lame OSes...
587                         $scriptPath = str_replace("\\", '/', dirname($_SERVER['SCRIPT_NAME']));
588                 }
589
590                 // Return it
591                 return $scriptPath;
592         }
593
594         /**
595          * 1) Loads class scanner and scans all framework's classes and interfaces.
596          * This method also registers the class loader's method autoLoad() for the
597          * SPL auto-load feature. Remember that you can register additional methods
598          * (not functions, please) for other libraries.
599          *
600          * Yes, I know about Composer, but I like to keep my class loader around.
601          * You can always use mine as long as your classes have a namespace
602          * according naming-convention: Vendor\Project\Group[\SubGroup]
603          *
604          * @return      void
605          */
606         private static function scanFrameworkClasses () {
607                 // Include class loader
608                 require self::getConfigurationInstance()->getConfigEntry('framework_base_path') . 'loader/class_ClassLoader.php';
609
610                 // Register auto-load function with the SPL
611                 spl_autoload_register('Org\Mxchange\CoreFramework\Loader\ClassLoader::autoLoad');
612
613                 // Scan for all framework classes, exceptions and interfaces
614                 ClassLoader::scanFrameworkClasses();
615         }
616
617         /**
618          * 2) Determines request/response type and stores the created
619          * request/response instances in this object for later usage.
620          *
621          * @return      void
622          */
623         private static function determineRequestType () {
624                 // Determine request type
625                 $request = self::getRequestTypeFromSystem();
626                 $requestType = self::getRequestTypeFromSystem();
627
628                 // Create a new request object
629                 $requestInstance = ObjectFactory::createObjectByName(sprintf('Org\Mxchange\CoreFramework\Request\%sRequest', StringUtils::convertToClassName($request)));
630
631                 // Remember request instance here
632                 self::setRequestInstance($requestInstance);
633
634                 // Do we have another response?
635                 if ($requestInstance->isRequestElementSet('request')) {
636                         // Then use it
637                         $request = strtolower($requestInstance->getRequestElement('request'));
638                         $requestType = $request;
639                 }
640
641                 // ... and a new response object
642                 $responseInstance = ObjectFactory::createObjectByName(sprintf('Org\Mxchange\CoreFramework\Response\%sResponse', StringUtils::convertToClassName($request)));
643
644                 // Remember response instance here
645                 self::setResponseInstance($responseInstance);
646         }
647
648         /**
649          * 3) Validate parameter 'application' if it is set and the application is there.
650          *
651          * @return      void
652          */
653         private static function validateApplicationParameter () {
654                 // Is the parameter set?
655                 if (!self::getRequestInstance()->isRequestElementSet('app')) {
656                         /*
657                          * Don't continue here, the application 'selector' is no longer
658                          * supported and only existed as an idea to select the proper
659                          * application (by user).
660                          */
661                         ApplicationEntryPoint::exitApplication('No application specified. Please provide a parameter "app" and retry.');
662                 }
663
664                 // Get it for local usage
665                 $applicationName = self::getRequestInstance()->getRequestElement('app');
666
667                 // Secure it, by keeping out tags
668                 $applicationName = htmlentities(strip_tags($applicationName), ENT_QUOTES);
669
670                 // Secure it a little more with a reg.exp.
671                 $applicationName = preg_replace('/([^a-z0-9_-])+/i', '', $applicationName);
672
673                 // Construct FQPN (Full-Qualified Path Name) for ApplicationHelper class
674                 $applicationPath = sprintf(
675                         '%s%s%s',
676                         self::getConfigurationInstance()->getConfigEntry('application_base_path'),
677                         $applicationName,
678                         DIRECTORY_SEPARATOR
679                 );
680
681                 // Full path for application
682                 // Is the path there? This secures a bit the parameter (from untrusted source).
683                 if ((!is_dir($applicationPath)) || (!is_readable($applicationPath))) {
684                         // Not found or not readable
685                         ApplicationEntryPoint::exitApplication(sprintf('Application "%s" not found.', $applicationName));
686                 }
687
688                 // Set the detected application's name and full path for later usage
689                 self::$detectedApplicationPath = $applicationPath;
690                 self::$detectedApplicationName = $applicationName;
691         }
692
693         /**
694          * Getter for request instance
695          *
696          * @return      $requestInstance        An instance of a Requestable class
697          */
698         public static function getRequestInstance () {
699                 return self::$requestInstance;
700         }
701
702         /**
703          * Getter for response instance
704          *
705          * @return      $responseInstance       An instance of a Responseable class
706          */
707         public static function getResponseInstance () {
708                 return self::$responseInstance;
709         }
710
711         /**
712          * Setter for request instance
713          *
714          * @param       $requestInstance        An instance of a Requestable class
715          * @return      void
716          */
717         private static function setRequestInstance (Requestable $requestInstance) {
718                 self::$requestInstance = $requestInstance;
719         }
720
721         /**
722          * Setter for response instance
723          *
724          * @param       $responseInstance       An instance of a Responseable class
725          * @return      void
726          */
727         private static function setResponseInstance (Responseable $responseInstance) {
728                 self::$responseInstance = $responseInstance;
729         }
730
731         /**
732          * Setter for database instance
733          *
734          * @param       $databaseInstance       An instance of a DatabaseConnection class
735          * @return      void
736          */
737         public static function setDatabaseInstance (DatabaseConnection $databaseInstance) {
738                 self::$databaseInstance = $databaseInstance;
739         }
740
741         /**
742          * Getter for database instance
743          *
744          * @return      $databaseInstance       An instance of a DatabaseConnection class
745          */
746         public static function getDatabaseInstance () {
747                 // Return instance
748                 return self::$databaseInstance;
749         }
750
751         /**
752          * Private getter for language instance
753          *
754          * @return      $languageInstance       An instance of a ManageableLanguage class
755          */
756         public static function getLanguageInstance () {
757                 return self::$languageInstance;
758         }
759
760         /**
761          * Setter for language instance
762          *
763          * @param       $languageInstance       An instance of a ManageableLanguage class
764          * @return      void
765          */
766         public static function setLanguageInstance (ManageableLanguage $languageInstance) {
767                 self::$languageInstance = $languageInstance;
768         }
769
770 }