Application.php
1 <?php
2 /**
3  * wCMF - wemove Content Management Framework
4  * Copyright (C) 2005-2017 wemove digital solutions GmbH
5  *
6  * Licensed under the terms of the MIT License.
7  *
8  * See the LICENSE file distributed with this work for
9  * additional information.
10  */
11 namespace wcmf\lib\presentation;
12 
19 
20 /**
21  * Application is the main application class, that does all the initialization.
22  *
23  * @author ingo herwig <ingo@wemove.com>
24  */
25 class Application {
26 
27  private $startTime = null;
28  private $request = null;
29  private $response = null;
30 
31  private $debug = false;
32 
33  private static $logger = null;
34 
35  /**
36  * Constructor
37  */
38  public function __construct() {
39  $this->startTime = microtime(true);
40  if (self::$logger == null) {
41  self::$logger = LogManager::getLogger(__CLASS__);
42  }
43  ob_start([$this, "outputHandler"]);
44  new ErrorHandler();
45  }
46 
47  /**
48  * Destructor
49  */
50  public function __destruct() {
51  // log resource usage
52  if (self::$logger->isDebugEnabled()) {
53  $timeDiff = microtime(true)-$this->startTime;
54  $memory = number_format(memory_get_peak_usage()/(1024*1024), 2);
55  $msg = "Time[".round($timeDiff, 2)."s] Memory[".$memory."mb]";
56  if ($this->request != null) {
57  $msg .= " Request[".$this->request->getSender()."?".
58  $this->request->getContext()."?".$this->request->getAction()."]";
59  }
60  $msg .= " URI[".$_SERVER['REQUEST_URI']."]";
61  self::$logger->debug($msg);
62  }
63  ob_end_flush();
64  }
65 
66  /**
67  * Initialize the request.
68  *
69  * @param $defaultController The controller to call if none is given in request parameters (optional, default: '')
70  * @param $defaultContext The context to set if none is given in request parameters (optional, default: '')
71  * @param $defaultAction The action to perform if none is given in request parameters (optional, default: 'login')
72  * @return Request instance representing the current HTTP request
73  */
74  public function initialize($defaultController='', $defaultContext='', $defaultAction='login') {
75  $config = ObjectFactory::getInstance('configuration');
76  $this->debug = $config->getBooleanValue('debug', 'Application');
77 
78  // configure php
79  if ($config->hasSection('phpconfig')) {
80  $phpSettings = $config->getSection('phpconfig');
81  foreach ($phpSettings as $option => $value) {
82  ini_set($option, $value);
83  }
84  }
85 
86  // create the Request and Response instances
87  $this->request = ObjectFactory::getInstance('request');
88  $this->response = ObjectFactory::getInstance('response');
89  $this->request->setResponse($this->response);
90 
91  $this->request->initialize($defaultController, $defaultContext, $defaultAction);
92 
93  // initialize session
94  $session = ObjectFactory::getInstance('session');
95 
96  // load user configuration
97  $principalFactory = ObjectFactory::getInstance('principalFactory');
98  $authUser = $principalFactory->getUser($session->getAuthUser(), true);
99  if ($authUser && strlen($authUser->getConfig()) > 0) {
100  $config->addConfiguration($authUser->getConfig(), true);
101  }
102 
103  // load event listeners
104  $listeners = $config->getValue('listeners', 'application');
105  foreach ($listeners as $key) {
107  }
108 
109  // set timezone
110  date_default_timezone_set($config->getValue('timezone', 'application'));
111 
112  // return the request
113  return $this->request;
114  }
115 
116  /**
117  * Run the application with the given request
118  * @param $request
119  * @return Response instance
120  */
121  public function run(Request $request) {
122  // process the requested action
123  ObjectFactory::getInstance('actionMapper')->processAction($request, $this->response);
124  return $this->response;
125  }
126 
127  /**
128  * Default exception handling method. Rolls back the transaction and
129  * executes 'failure' action.
130  * @param $exception The Exception instance
131  */
132  public function handleException(\Exception $exception) {
133  // get error level
134  $logFunction = 'error';
135  if ($exception instanceof ApplicationException) {
136  $logFunction = $exception->getError()->getLevel() == ApplicationError::LEVEL_WARNING ?
137  'warn' : 'error';
138  }
139  self::$logger->$logFunction($exception);
140 
141  try {
142  if (ObjectFactory::getInstance('configuration') != null) {
143  // rollback current transaction
144  $persistenceFacade = ObjectFactory::getInstance('persistenceFacade');
145  $persistenceFacade->getTransaction()->rollback();
146 
147  // redirect to failure action
148  if ($this->request) {
149  $error = ApplicationError::fromException($exception);
150  $this->request->addError($error);
151  $this->response->addError($error);
152  $this->request->setAction('failure');
153  $this->response->setAction('failure');
154  $this->response->setStatus($error->getStatusCode());
155  ObjectFactory::getInstance('actionMapper')->processAction($this->request, $this->response);
156  return;
157  }
158  }
159  throw $exception;
160  }
161  catch (Exception $ex) {
162  self::$logger->error($ex->getMessage()."\n".$ex->getTraceAsString());
163  }
164  }
165 
166  /**
167  * This method is run as ob_start callback
168  * @note must be public
169  * @param $buffer The content to be returned to the client
170  * @return String
171  */
172  public function outputHandler($buffer) {
173  // log last error, if it's level is enabled
174  $error = error_get_last();
175  if ($error !== null && $error['type'] == E_ERROR) {
176  $errorStr = $error['file']."::".$error['line'].": ".$error['type'].": ".$error['message'];
177  self::$logger->error($errorStr);
178  // suppress error message in browser
179  if (!$this->debug) {
180  header('HTTP/1.1 500 Internal Server Error');
181  $buffer = '';
182  }
183  }
184  return trim($buffer);
185  }
186 }
187 ?>
initialize($defaultController='', $defaultContext='', $defaultAction='login')
Initialize the request.
Definition: Application.php:74
handleException(\Exception $exception)
Default exception handling method.
Application is the main application class, that does all the initialization.
Definition: Application.php:25
Presentation related interfaces and classes.
Definition: namespaces.php:59
static getLogger($name)
Get the logger with the given name.
Definition: LogManager.php:37
Request holds the request values that are used as input to Controller instances.
Definition: Request.php:18
static fromException(\Exception $ex)
Factory method for transforming an exception into an ApplicationError instance.
ErrorHandler catches all php errors and transforms fatal errors into ErrorExceptions and non-fatal in...
static getInstance($name, $dynamicConfiguration=[])
outputHandler($buffer)
This method is run as ob_start callback.
ApplicationException signals a general application exception.
run(Request $request)
Run the application with the given request.