presentation.doxy
1 /*!
2 \page presentation Presentation
3 <div class="has-toc"></div>
4 
5 # Presentation # {#pres_main}
6 
7 Presentation refers to the part of the application that is visible to the user -
8 the _user interface_ - and the handling of user interaction.
9 
10 ## Services ## {#pres_services}
11 
12 The presentation layer usually depends on underlying services like persistency,
13 event handling, caching - just to name a few. These services typically exist as
14 one instance that is created on application startup and is used throughout the
15 whole application lifetime.
16 
17 The preferred way to get access to a service instance in client code is to set
18 the dependency explicitly or let it be injected, if the instance is not created
19 explicitly (see \ref conf_di). But there are also situations where this is not
20 possible (e.g. a global function that is used by third party code). Since most
21 of these services are registered with
22 \link wcmf::lib::core::ObjectFactory `ObjectFactory`\endlink, it's
23 \link wcmf::lib::core::ObjectFactory::getInstance `getInstance`\endlink method
24 is used as a [service locator](https://en.wikipedia.org/wiki/Service_locator_pattern).
25 
26 The following example shows how to get the persistence service at any code location:
27 
28 <div class="php">
29 ```
30 $persistenceFacade = ObjectFactory::getInstance('persistenceFacade');
31 ```
32 </div>
33 
34 ## Application ## {#pres_application}
35 
36 Web applications typically implement a _request-response pattern_, where a
37 client sends a
38 ([HTTP](http://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol)-)request to the
39 application, which returns a response after processing it. wCMF encapsulates the
40 described procedure inside the
41 \link wcmf::lib::presentation::Application `Application`\endlink class. The
42 following code demonstrates the usage of this class in the main entry script of
43 the \ref app "default application".
44 
45 <div class="php">
46 ```
47 $application = new Application();
48 try {
49  // initialize the application
50  $request = $application->initialize('', '', 'cms');
51 
52  // run the application
53  $response = $application->run($request);
54 }
55 catch (Exception $ex) {
56  try {
57  $application->handleException($ex);
58  }
59  catch (Exception $unhandledEx) {
60  echo("An unhandled exception occured. Please see log file for details.");
61  }
62 }
63 ```
64 </div>
65 
66 The example shows the three important methods of the
67 \link wcmf::lib::presentation::Application `Application`\endlink class:
68 
69 - The \link wcmf::lib::presentation::Application::initialize `initialize`\endlink
70  method is used to __setup__ the
71  \link wcmf::lib::presentation::Application `Application`\endlink. It returns a
72  \link wcmf::lib::presentation::Request `Request`\endlink instance, that could be
73  modified before execution.
74 - The \link wcmf::lib::presentation::Application::run `run`\endlink method is
75  called to __execute__ the given request. The method returns a
76  \link wcmf::lib::presentation::Response `Response`\endlink instance, that is not
77  used in this example.
78 - The \link wcmf::lib::presentation::Application::handleException `handleException`\endlink
79  method is called, if an __exception__ occurs. The method rolls back the database
80  transaction and calls the _failure_ action.
81 
82 The details of request execution are the topic of the next section.
83 
84 ## Request processing ## {#pres_request}
85 
86 The \link wcmf::lib::presentation::Request `Request`\endlink instance created
87 on initialization of the application provides all information about the incoming
88 HTTP request, that is necessary for execution. Upon execution, the following
89 actions are performed:
90 
91 1. The \link wcmf::lib::presentation::Request `Request`\endlink instance is passed
92  to \link wcmf::lib::presentation::ActionMapper `ActionMapper`\endlink for further
93  processing.
94 2. The \ref arch_actionkey is determined from the request parameters.
95 3. \link wcmf::lib::security::PermissionManager `PermissionManager`\endlink is
96  asked to authorize the action key for the current user (see \ref sec_perm_check).
97 4. If authorization is successful, the request data is transformed into the internal
98  application format (see \ref pres_format).
99 5. The \link wcmf::lib::presentation::Controller `Controller`\endlink instance
100  matching the request is determined (see \ref pres_routing) and executed.
101 6. The \link wcmf::lib::presentation::Response `Response`\endlink instance is
102  obtained after execution.
103 7. The response data is transformed into the requested response format (see
104  \ref pres_format).
105 8. Execution returns to step 3, if a valid action key is contained in the response
106  data. It terminates, if either no action key is found or the next action key
107  would be the same as the previous (to prevent recursion).
108 
109 ### Formats ### {#pres_format}
110 
111 wCMF is designed to be able to consume various request formats and produce
112 several response formats. While some clients communicate using
113 [JSON](http://en.wikipedia.org/wiki/JSON) format, others might prefer to encode
114 data in [XML](http://en.wikipedia.org/wiki/XML).
115 \link wcmf::lib::presentation::format::Formatter `Formatter`\endlink
116 is used to determine the required format and delegate the actual formatting to
117 the correct \link wcmf::lib::presentation::format::Format `Format`\endlink
118 implementation. wCMF currently provides the following __implementations__:
119 
120 - \link wcmf::lib::presentation::format::impl::HtmlFormat `HtmlFormat`\endlink
121  expects all data to be sent as key-value-pairs. Object data are transferred in
122  parameters named `value-`<em>name-oid</em> (e.g. `value-title-Book:3`).
123  Responses in this format are rendered as HTML views (see \ref pres_views).
124 - \link wcmf::lib::presentation::format::impl::JsonFormat `JsonFormat`\endlink
125  handles JSON encoded request data and encodes response data into the same format.
126 - \link wcmf::lib::presentation::format::impl::SoapFormat `SoapFormat`\endlink
127  is used together with the [NuSOAP](http://sourceforge.net/projects/nusoap/)
128  library to implement a SOAP interface.
129 - \link wcmf::lib::presentation::format::impl::GenericFormat `GenericFormat`\endlink
130  is used to output arbitrary responses.
131 - \link wcmf::lib::presentation::format::impl::DownloadFormat `DownloadFormat`\endlink
132  is used to create a downloadable reponse document. It is automatically chosen, if
133  the \link wcmf::lib::presentation::Response::setDocument `Response::setDocument`\endlink
134  method is called with a \link wcmf::lib::presentation::ResponseDocument `ResponseDocument`\endlink.
135 - \link wcmf::lib::presentation::format::impl::NullFormat `NullFormat`\endlink
136  is used internally, if no formatting is required, e.g. if one controller calls
137  another controller.
138 
139 If not explicitely set, the request and response format is automatically
140 determined from the __HTTP headers__ sent with the request:
141 
142 - The `Content-Type` header defines the __request__ format
143 - The `Accept` header defines the __response__ format
144 
145 To find the correct format, the
146 [Media Type](https://www.iana.org/assignments/media-types/media-types.xhtml)
147 value set in those headers is matched against the mime type of all registered
148 formats (see
149 \link wcmf::lib::presentation::format::Format::getMimeType `Format::getMimeType`\endlink).
150 
151 Formats are defined in the `Formats` configuration section as shown in the following
152 example:
153 
154 <div class="ini">
155 ```
156 [Formats]
157 html = $htmlFormat
158 null = $nullFormat
159 
160 [HtmlFormat]
161 __class = wcmf\lib\presentation\format\impl\HtmlFormat
162 
163 [NullFormat]
164 __class = wcmf\lib\presentation\format\impl\NullFormat
165 ```
166 </div>
167 
168 ### Routing ### {#pres_routing}
169 
170 Routing is the process of selecting the correct
171 \link wcmf::lib::presentation::Controller `Controller`\endlink for a given request.
172 wCMF distinguishes between _internal_ and _external_ routing.
173 
174 #### Internal routing #### {#pres_routingint}
175 
176 Internal routing takes place after the \link wcmf::lib::presentation::Request `Request`\endlink
177 instance is created and initialized. wCMF inspects the __action key__ formed from
178 it's _sender_, _context_ and _action_ parameters (see \ref arch_actionkey) to
179 determine the controller to be executed for the request. The mapping of action
180 keys to controllers is defined in the `ActionMapping` configuration section.
181 
182 If the executed controller together with the _context_ and _action_ parameters of
183 the response match another action key, the corresponding controller
184 will be executed afterwards. This allows to __chain actions__ together. If no
185 matching action key is found, the response is returned to the client.
186 
187 The following code is taken from the \ref app "default application" configuration
188 and shows the configuration of the indexing process (see \ref pres_longrequest):
189 
190 <div class="ini">
191 ```
192 [ActionMapping]
193 ??indexAll = wcmf\application\controller\SearchIndexController
194 wcmf\application\controller\SearchIndexController??continue =
195  wcmf\application\controller\SearchIndexController
196 ```
197 </div>
198 
199 - The first line states that the action _indexAll_ called from _any_ controller and
200  in _any_ context will invoke
201  \link wcmf::application::controller::SearchIndexController `SearchIndexController`\endlink,
202  which will set a state dependent action name on the response (see
203  \link wcmf::application::controller::BatchController `BatchController`\endlink).
204 - The second line tells \link wcmf::lib::presentation::ActionMapper `ActionMapper`\endlink
205  to re-invoke
206  \link wcmf::application::controller::SearchIndexController `SearchIndexController`\endlink,
207  if it was the last controller and the action is _continue_. So this action key
208  only matches, if the last controller was
209  \link wcmf::application::controller::SearchIndexController `SearchIndexController`\endlink.
210 
211 ##### Controller methods ##### {#pres_controller_methods}
212 
213 The previous example maps the action keys to a controller class without specifying
214 a method to be called. In these cases, the framework calls the default method
215 `doExecute`, which must then be defined in the controller class (see \ref pres_controllers).
216 
217 Alternatively a specific __controller method__ to be called could be defined in the
218 action mapping, like illustrated in the following example:
219 
220 <div class="ini">
221 ```
222 [ActionMapping]
223 ??indexAll = wcmf\application\controller\SearchIndexController::doBegin
224 wcmf\application\controller\SearchIndexController??continue =
225  wcmf\application\controller\SearchIndexController::doContinue
226 ```
227 </div>
228 
229 In this case \link wcmf::application::controller::SearchIndexController `SearchIndexController`\endlink
230 would have to define the methods `doBegin` and `doContinue` which are called
231 for the appropriate action keys.
232 
233 #### External routing #### {#pres_routingext}
234 
235 The mapping of the current __request uri__ to an __action key__ is called external
236 routing. The default mapping logic is implemented in the
237 \link wcmf::lib::presentation::impl::DefaultRequest::initialize `DefaultRequest::initialize`\endlink
238 method. The method matches the _path part_ of the request uri against the entries
239 of the `Routes` configuration section to find an appropriate action key.
240 
241 __Variables__ declared in path segments will be automatically passed as request parameters,
242 but would be overwritten by explicit request parameters if provided. The character <em>*</em> is used
243 as _wildcard_. Regular expression __patterns__ can be added to variables to narrow
244 the set of possibilities.
245 
246 The following example configuration taken from the \ref app "default application"
247 illustrates the concept:
248 
249 <div class="ini">
250 ```
251 [Routes]
252 POST/session = action=login
253 DELETE/session = action=logout
254 /rest/{language}/{className} = action=restAction&collection=1
255 /rest/{language}/{className}/{id|[0-9]+} = action=restAction&collection=0
256 GET/* = action=cms
257 ```
258 </div>
259 
260 - The first two entries define the login and logout routes using the appropriate
261  HTTP methods.
262 - The third entry defines the _language_ and _className_ variables (surrounded
263  by curly braces) and would be matched by the request uris <em>/rest/de/Author</em>
264  or <em>/rest/en/Book</em>. The executed action would be _restAction_.
265 - The _id_ variable in the next entry must be an integer because of the regular
266  expression constraint `[0-9]+`.
267 - The last entry is matched by any GET request to a path that was not matched before.
268  It is mapped to the _cms_ action - corresponding to the action key <em>??cms</em>.
269 
270 @note Any requests on routes that are __not__ defined in the `Routes` configuration
271 section will cause a `404` error. This is why this section is also considered the
272 _public_ interface of the application.
273 
274 ##### Precedence rules #####
275 
276 Due to the use of variables in route definitions several routes might match a given
277 request. This leads to the question which route to take, since the application only
278 processes one per request. To find the best matching route
279 \link wcmf::lib::presentation::impl::DefaultRequest `DefaultRequest`\endlink orders
280 all matching routes and takes the first one. The sorting is done under the assumption
281 that a more specific route is a better match.
282 
283 The following __rules__ are implemented to find the more specific route:
284 - the route with _less variables_ is more specific and if two routes have the same number of variables
285 - the route with _more patterns_ in the variable definitions is more specific.
286 
287 In cases where these simple rules are not sufficient, you could configure a __custom__
288 \link wcmf::lib::presentation::Request `Request`\endlink implementation (see \ref conf_di)
289 which overrides the \link wcmf::lib::presentation::impl::DefaultRequest::isMatch `DefaultRequest::isMatch`\endlink
290 method.
291 
292 ##### HTTP methods #####
293 
294 To restrict a path to one or more __HTTP methods__, they are added in front of
295 the route definition. In the following example the _cms_ action is only available
296 for the _GET_ method, while the other actions accept _GET_, _POST_, _PUT_ and
297 _DELETE_ requests:
298 
299 <div class="ini">
300 ```
301 [Routes]
302 GET/ = action=cms
303 GET,POST,PUT,DELETE/rest/{language}/{className} = action=restAction&collection=1
304 GET,POST,PUT,DELETE/rest/{language}/{className}/{id|[0-9]+} = action=restAction&collection=0
305 ```
306 </div>
307 
308 If no method is added to a route, all methods are accepted.
309 
310 ## Controllers ## {#pres_controllers}
311 
312 Controllers take the user input from the request and modify the model according
313 to it. As a result a response is created which is presented to the user in a view
314 or any other format. Which controller is executed on a specific request is
315 determined in the routing process (see \ref pres_routing).
316 
317 wCMF provides \link wcmf::lib::presentation::Controller `Controller`\endlink as
318 abstract base class for controller implementations. There are three important
319 methods defined in this class, which are called by
320 \link wcmf::lib::presentation::ActionMapper `ActionMapper`\endlink in the following order:
321 
322 1. \link wcmf::lib::presentation::Controller::initialize `Controller::initialize`\endlink
323  is called directly after instantiation of the controller. The current
324  \link wcmf::lib::presentation::Request `Request`\endlink and
325  \link wcmf::lib::presentation::Response `Response`\endlink instances are passed
326  as parameters and subclasses can override this method to implement task specific
327  initializations.
328 2. \link wcmf::lib::presentation::Controller::validate `Controller::validate`\endlink
329  is called afterwards to check the validity of the request parameters. The default
330  implementation returns _true_ and subclasses are assumed to override this method
331  if necessary to do task specific validations.
332 3. \link wcmf::lib::presentation::Controller::execute `Controller::execute`\endlink
333  is called finally. This method accepts a parameter, that defines the actual
334  method to be called on the subclass. If the parameter is omitted it defaults
335  to `doExecute` which must then be defined in the subclass (see \pres_controller_methods).
336 
337 Controllers can _redirect_ to other controllers by using the
338 \link wcmf::lib::presentation::Controller::redirect `Controller::redirect`\endlink
339 method.
340 
341 If variables need to be shared between several requests to the same controller they can
342 be stored in _local session variables_ to avoid side effects (see
343 \link wcmf::lib::presentation::Controller::setLocalSessionValue `Controller::setLocalSessionValue`\endlink).
344 
345 ### Error handling ### {#pres_errors}
346 
347 Errors are typically divided into __fatal errors__ and __non-fatal errors__.
348 
349 By definition the application is not able to recover from a _fatal error_, meaning
350 that it's not functioning correctly. An example would be a programming error or
351 a missing vital resource. These errors normally need to be fixed by the application
352 maintainer. In case of _non-fatal errors_ a notice to the user is sufficient in most
353 cases. A typical example would be invalid user input, that can be fixed by the user
354 itself.
355 
356 In wCMF the following two strategies are recommended for handling these kind of
357 situations:
358 
359 - In case of a __fatal error__, an exception should be thrown. If it is not caught
360  inside the application code, it will bubble up to the main script (usually
361  _index.php_). In case the application is set up like in the \ref pres_application
362  section, the method
363  \link wcmf::lib::presentation::Application::handleException `Application::handleException`\endlink
364  will be called. This method rolls back the current transaction and calls the
365  _failure_ action, which is executed by
366  \link wcmf::application::controller::FailureController `FailureController`\endlink
367  by default.
368 
369 - If a __non-fatal error__ occurs, an instance of
370  \link wcmf::lib::presentation::ApplicationError `ApplicationError`\endlink
371  should be created and added to the response using the
372  \link wcmf::lib::presentation::Response::addError `Response::addError`\endlink
373  method. The error class provides the
374  \link wcmf::lib::presentation::ApplicationError::get `ApplicationError::get`\endlink
375  method to retrieve predefined errors. The following example shows how to signal
376  an invalid _type_ parameter while request validation:
377 
378 <div class="php">
379 ```
380 $response->addError(ApplicationError::get('PARAMETER_INVALID',
381  ['invalidParameters' => ['type']]));
382 ```
383 </div>
384 
385 ### Action composition ### {#pres_controllers_composite}
386 
387 The \ref pres_routingint section describes how chaining controller actions works.
388 This is usefull, if there is a sequence of actions to be executed. If a complex action
389 can be composed from simpler (already existing) actions, it is also possible to
390 execute another controller _inside_ a controller action and return to that action afterwards.
391 This is done using the
392 \link wcmf::lib::presentation::Controller::executeSubAction `Controller::executeSubAction`\endlink
393 method. An example is \link wcmf::application::controller::RESTController `RESTController`\endlink
394 which serves as a facade to the CRUD controllers.
395 
396 ### Automatic transactions ### {#pres_controllers_transaction}
397 
398 To run a controller method inside a persistence transaction the convenience method
399 \link wcmf::lib::presentation::Controller::requireTransaction `Controller::requireTransaction`\endlink
400 can be called at the beginning of the method. This call will start a transaction or join the already
401 opened one. The transaction will be automatically committed after method execution or rolled back in
402 case of an exception. Calls to \link wcmf::lib::presentation::Controller::executeSubAction `Controller::executeSubAction`\endlink
403 will use the same transaction.
404 
405 ### Long running requests ### {#pres_longrequest}
406 
407 There are situations where you want to split a long running process into parts,
408 because it's exceeding memory or time limits or simply to give the user feedback
409 about the progress. By subclassing
410 \link wcmf::application::controller::BatchController `BatchController`\endlink
411 the implementation of this behavior is as simple as defining the steps of
412 the process in the
413 \link wcmf::application::controller::BatchController::getWorkPackage `BatchController::getWorkPackage`\endlink
414 method.
415 
416 \link wcmf::application::controller::SearchIndexController `SearchIndexController`\endlink
417 is an example for a controller implementing a long running process. It is used
418 to create a Lucene search index over all searchable entity objects. The process
419 is split into collecting all object ids and then indexing them. In the final
420 step the index is optimized.
421 
422 ## Views ## {#pres_views}
423 
424 Views are used to present application information to the user. In a web application
425 they are typically HTML pages displayed in the browser.
426 
427 In wCMF the response will be turned into an HTML page, if the `Accept` HTTP header
428 is set to _text/html_ (see \ref pres_format). The appropriate
429 \link wcmf::lib::presentation::format::Format `Format`\endlink implementation is
430 \link wcmf::lib::presentation::format::impl::HtmlFormat `HtmlFormat`\endlink.
431 It renders the response into a template file using the configured
432 \link wcmf::lib::presentation::view::View `View`\endlink implementation. The format
433 of the template files depends on that implementation. Since different
434 actions could require different views to be displayed, a mapping of action keys to
435 view templates is defined in the `Views` configuration section.
436 
437 The following example shows the configuration of the
438 \link wcmf::lib::presentation::view::impl::SmartyView `SmartyView`\endlink class
439 and the mapping of action keys to views in the \ref app "default application":
440 
441 <div class="ini">
442 ```
443 [View]
444 __class = wcmf\lib\presentation\view\impl\SmartyView
445 __shared = false
446 compileCheck = true
447 caching = false
448 cacheLifetime = 3600
449 cacheDir = app/cache/smarty/
450 
451 [Views]
452 app\src\controller\RootController?? = app/src/views/cms.tpl
453 ```
454 </div>
455 
456 Since the \ref app "default application" only uses an HTML page to bootstrap the
457 actual [Dojo](https://dojotoolkit.org/) application, there is only one view mapping
458 for `RootController`.
459 
460 ### Device dependent views ###
461 
462 \link wcmf::lib::presentation::format::impl::HtmlFormat `HtmlFormat`\endlink
463 allows to provide different versions of a view template. This is especially
464 useful, if you want to deliver device dependent content for the same action key.
465 
466 To select a specific template version, the property `html_tpl_format` has to be set
467 on the response instance (see \link wcmf::lib::presentation::ControllerMessage::setProperty `ControllerMessage::setProperty`\endlink).
468 E.g. if the template file would be _home.tpl_, setting the value to _mobile_ would
469 select the template file _home-mobile.tpl_. If the requested version does not exist,
470 it is ignored and the default template is used (_home.tpl_ in this example).
471 
472 ## Webservice APIs ## {#pres_apis}
473 
474 Besides the user interface driven \ref app "default application" wCMF provides
475 APIs for using the application as a [web service](https://en.wikipedia.org/wiki/Web_service).
476 These APIs provide create/read/update/delete
477 ([CRUD](https://en.wikipedia.org/wiki/Create,_read,_update_and_delete))
478 operations on all entity types.
479 
480 ### RESTful API ###
481 
482 The [REST](https://en.wikipedia.org/wiki/Representational_state_transfer)ful
483 interface is implemented in
484 \link wcmf::application::controller::RESTController `RESTController`\endlink,
485 which basically acts as a facade in front of the application. That means the
486 controller checks the request data only and delegates the actual processing to
487 the action specific controller.
488 
489 The following example shows the configuration of the RESTful interface in the
490 \ref app "default application":
491 
492 <div class="ini">
493 ```
494 [Routes]
495 /rest/{language}/{className} = action=restAction&collection=1
496 /rest/{language}/{className}/{id|[0-9]+} = action=restAction&collection=0
497 /rest/{language}/{className}/{sourceId|[0-9]+}/{relation} = action=restAction&collection=1
498 /rest/{language}/{className}/{sourceId|[0-9]+}/{relation}/{targetId|[0-9]+} = action=restAction&collection=0
499 
500 [ActionMapping]
501 ??restAction = wcmf\application\controller\RESTController
502 ```
503 </div>
504 
505 The `Routes` configuration section defines the urls for the interface. They all
506 call the action _restAction_ internally, which is handled by
507 \link wcmf::application::controller::RESTController `RESTController`\endlink as
508 defined in the `ActionMapping` section. For example the english version of
509 the `Author` instance with id _1_ is retrieved by making a GET request to
510 the url <em>/rest/en/Author/1</em>.
511 
512 ### SOAP API ###
513 
514 wCMF uses the [NuSOAP](http://sourceforge.net/projects/nusoap/) library for
515 implementing the SOAP interface. It consists of the
516 \link wcmf::lib::service::SoapServer `SoapServer`\endlink and
517 \link wcmf::application::controller::SOAPController `SOAPController`\endlink classes.
518 The controller class handles all requests and delegates the processing to the
519 server class. The service description in the
520 [WSDL](https://en.wikipedia.org/wiki/Web_Services_Description_Language) format
521 is generated by the code generator into a file called _soap-interface.php_
522 (see \ref generator_artefacts_php).
523 
524 The following example shows the configuration of the SOAP interface in the
525 \ref app "default application":
526 
527 <div class="ini">
528 ```
529 [Routes]
530 /soap = action=soapAction
531 
532 [ActionMapping]
533 ??soapAction = wcmf\application\controller\SOAPController
534 ```
535 </div>
536 
537 The `Routes` configuration section defines that the url <em>/soap</em> redirects
538 to the action _soapAction_ internally. The `ActionMapping` section defines that
539 this action is handled by
540 \link wcmf::application::controller::SOAPController `SOAPController`\endlink.
541 The interface description is available at the url <em>/soap?wsdl</em>.
542 
543 ## Caching ## {#pres_caching}
544 
545 Caching is an effective method to improve application performance. Caches in wCMF
546 are supposed to be divided into sections, which hold key-value pairs (see
547 \link wcmf::lib::io::Cache `Cache`\endlink interface). Cache instances are
548 defined in the application configuration and retrieved by using
549 \link wcmf::lib::core::ObjectFactory `ObjectFactory`\endlink, which makes it easy
550 to exchange the underlying caching implementation.
551 
552 The following example shows the configuration of a
553 \link wcmf::lib::io::impl::FileCache `FileCache`\endlink instance in the
554 \ref app "default application":
555 
556 <div class="ini">
557 ```
558 [Cache]
559 __class = wcmf\lib\io\impl\FileCache
560 cacheDir = app/cache/
561 ```
562 </div>
563 
564 The usage of this cache is illustrated in the code example:
565 
566 <div class="php">
567 ```
568 $cache = ObjectFactory::getInstance('cache');
569 $cacheSection = 'calculations';
570 
571 $cacheKey = 'resultA';
572 if (!$cache->exists($cacheSection, $cacheKey)) {
573  // calculate the result and store it in the cache
574  $result = complexCalculationA();
575  $cache->put($cacheSection, $cacheKey, $value);
576 }
577 else {
578  // retrieve the result from the cache
579  $resultA = $cache->get($cacheSection, $cacheKey);
580 }
581 ```
582 </div>
583 
584 Supposed that `complexCalculationA` in this example takes long to finish, it
585 should only run once at the first time the result is needed. So we check if
586 _resultA_ is already cached and calculate it, if not. Since it is put it into the
587 cache after calculation, it can be retrieved _resultA_ directly from there the
588 next time it is needed.
589 
590 ### Response caching ### {#pres_response_caching}
591 
592 Besides setting caching headers by using the
593 \link wcmf::lib::presentation::Response::setHeader `Response::setHeader`\endlink
594 method, wCMF provides a convenient way to set the `Etag` and `Last Modified`
595 headers on the response.
596 
597 All one needs to do is derive a _cache identifier_ from the request data, that
598 allows to distinguish different requests and set it on the response
599 using the \link wcmf::lib::presentation::Response::setCacheId `Response::setCacheId`\endlink
600 method. If the used \link wcmf::lib::presentation::format::Format `Format`\endlink
601 is capable of caching
602 (e.g. \link wcmf::lib::presentation::format::impl::HtmlFormat `HtmlFormat`\endlink)
603 it will provide the _last modified date_ from the cached data.
604 \link wcmf::lib::presentation::format::impl::DefaultFormatter `DefaultFormatter`\endlink
605 will then use this information to create the `Etag` and `Last Modified` headers:
606 
607 <div class="shell">
608 ```
609 ...
610 Cache-Control:public
611 ETag:"93256174cf75e43ba8172a6ce01ceded"
612 Last-Modified:Fri, 07 Oct 2016 19:19:13 GMT
613 ...
614 ```
615 </div>
616 
617 Another advantage of using a _cache identifier_ is the possibility to avoid
618 expensive calculations in \link wcmf::lib::presentation::Controller `Controller`\endlink
619 implementations by using the
620 \link wcmf::lib::presentation::Response::isCached `Response::isCached`\endlink
621 method. The following example shows it's usage:
622 
623 <div class="php">
624 ```
625 // define a unique id for the request data and set it on the response
626 $cacheId = $pageId.$language;
627 $response->setCacheId($cacheId);
628 
629 if (!$response->isCached()) {
630  // this will be executed only, if the response is not cached yet
631  ...
632 }
633 ```
634 </div>
635 
636 ## Events ## {#pres_events}
637 
638 Events are a way to decouple parts of a software by introducing an indirect
639 communication. They allow clients to react to certain application events without
640 the event source knowing them. wCMF uses the
641 [publish-subscribe](https://en.wikipedia.org/wiki/Publish%E2%80%93subscribe_pattern)
642 messaging pattern, in which \link wcmf::lib::core::EventManager `EventManager`\endlink
643 acts as the message broker. Subscribers use this class to register for certain
644 \link wcmf::lib::core::Event `Event`\endlink types and publishers to send the
645 events.
646 
647 The following events are defined in wCMF:
648 
649 - \link wcmf::lib::persistence::PersistenceEvent `PersistenceEvent`\endlink
650  is sent whenever a \link wcmf::lib::persistence::PersistentObject `PersistentObject`\endlink
651  instance is created, updated or deleted.
652 - \link wcmf::lib::persistence::PropertyChangeEvent `PropertyChangeEvent`\endlink,
653  \link wcmf::lib::persistence::ValueChangeEvent `ValueChangeEvent`\endlink and
654  \link wcmf::lib::persistence::StateChangeEvent `StateChangeEvent`\endlink
655  signal changes in \link wcmf::lib::persistence::PersistentObject `PersistentObject`\endlink
656  instances.
657 - \link wcmf::lib::persistence::TransactionEvent `TransactionEvent`\endlink
658  is fired at different phases of a transaction.
659 - \link wcmf::lib::presentation::ApplicationEvent `ApplicationEvent`\endlink
660  allows to listen to the different steps of the request handling process.
661 
662 The event system can be extended by custom events by inheriting from the
663 \link wcmf::lib::core::Event `Event`\endlink class.
664 
665 The class below is a basic example for a listener that subscribes to persistence
666 events:
667 
668 <div class="php">
669 ```
670 class PersistenceEventListener {
671  private $_eventListener = null;
672 
673  public function __construct(EventListener $eventListener) {
674  $this->_eventListener = $eventListener;
675  $this->_eventListener->addListener(PersistenceEvent::NAME,
676  [$this, 'persisted']);
677  }
678 
679  public function __destruct() {
680  $this->_eventListener->removeListener(PersistenceEvent::NAME,
681  [this, 'persisted']);
682  }
683 
684  /**
685  * Listen to PersistenceEvent
686  * @param $event PersistenceEvent instance
687  */
688  public function persisted(PersistenceEvent $event) {
689  // do something on any create/update/delete
690  }
691 }
692 ```
693 </div>
694 
695 @note To prevent memory leaks the
696 \link wcmf::lib::core::EventManager::removeListener `EventManager::removeListener`\endlink
697 method __must__ be called, if the event listener is destroyed.
698 
699 To send a persistence event, the following code is used:
700 
701 <div class="php">
702 ```
703 $eventListener = ObjectFactory::getInstance('eventManager');
704 $eventListener->dispatch(PersistenceEvent::NAME,
705  new PersistenceEvent($object, PersistenceAction::UPDATE));
706 ```
707 </div>
708 
709 ### Implicit listener installation ### {#pres_listeners}
710 
711 In some cases you might want to install event listeners without explicitely
712 instantiating them, because there is no appropriate place for that. For these
713 cases the \link wcmf::lib::presentation::Application `Application`\endlink class
714 reads the `listeners` value of the `Application` configuration section and
715 initializes all instances listed there.
716 
717 The \ref app "default application" defines two listeners as shown in the following
718 example:
719 
720 <div class="ini">
721 ```
722 [Application]
723 listeners = {Search, EventListener}
724 ```
725 </div>
726 
727 Each entry in the `listeners` array is supposed to refer to an instance
728 configuration (see \ref conf_di).
729 
730 ## Logging ## {#pres_log}
731 
732 wCMF integrates the logging frameworks [log4php](http://logging.apache.org/log4php/)
733 and [Monolog](https://github.com/Seldaek/monolog). To abstract from these libraries
734 wCMF defines the \link wcmf::lib::core::Logger `Logger`\endlink interface and
735 implementations for each framework. The decision, which framework to use is made
736 by instantiating the appropriate \link wcmf::lib::core::Logger `Logger`\endlink
737 instance and passing it to the
738 \link wcmf::lib::core::LogManager::configure `LogManager::configure`\endlink
739 method as shown for _Monolog_ in the following example:
740 
741 <div class="php">
742 ```
743 $logger = new MonologFileLogger('main', WCMF_BASE.'app/config/log.ini');
744 LogManager::configure($logger);
745 ```
746 </div>
747 
748 Afterwards \link wcmf::lib::core::Logger `Logger`\endlink instances can be retrieved
749 using the following code:
750 
751 <div class="php">
752 ```
753 $logger = LogManager::getLogger(__CLASS__);
754 ```
755 </div>
756 
757 The parameter used in the
758 \link wcmf::lib::core::LogManager::getLogger `LogManager::getLogger`\endlink method
759 is the _logger name_. It's a good practice to use the `__CLASS__` constant as logger
760  name, since this allows to enable/disable loggers by class names in the configuration
761 (see \ref conf_logging).
762 
763 The following example shows how to log an error message with a stack trace
764 appended (see
765 \link wcmf::lib::core::ErrorHandler::getStackTrace `ErrorHandler::getStackTrace`\endlink):
766 
767 <div class="php">
768 ```
769 $logger->error("An error occured.\n".ErrorHandler::getStackTrace());
770 ```
771 </div>
772 */
removeListener($eventName, $callback)
Remove a listener for a given event.
static configure(Logger $logger)
Configure the manager.
Definition: LogManager.php:28
Interface for logger implementations.
Definition: Logger.php:18
static getLogger($name)
Get the logger with the given name.
Definition: LogManager.php:37
Application is the main application class, that does all the initialization.
Definition: Application.php:22