ApplicationError.php
1 <?php
2 /**
3  * wCMF - wemove Content Management Framework
4  * Copyright (C) 2005-2020 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 
16 use wcmf\lib\util\StringUtil;
18 
19 /**
20  * ApplicationError is used to signal errors that occur
21  * while processing a request.
22  *
23  * This class allows to use predefined errors by using the ApplicationError::get()
24  * method. Errors are defined in the following way:
25 
26  * @code
27  * $message = ObjectFactory::getInstance('message');
28  * define('GENERAL_ERROR', serialize(['GENERAL_ERROR', ApplicationError::LEVEL_ERROR, 400,
29  * $message->getText('An unspecified error occurred.')
30  * ]));
31  * @endcode
32  *
33  * To use the error in the code:
34  *
35  * @code
36  * $error = ApplicationError::get('GENERAL_ERROR', $mySpecificErrorData);
37  * @endcode
38  *
39  * @author ingo herwig <ingo@wemove.com>
40  */
42 
43  // Error levels
44  const LEVEL_WARNING = 'warning';
45  const LEVEL_ERROR = 'error';
46  const LEVEL_FATAL = 'fatal';
47 
48  const DEFAULT_ERROR_STATUS = 500;
49 
50  private $code = null;
51  private $level = null;
52  private $statusCode = self::DEFAULT_ERROR_STATUS;
53  private $message = null;
54  private $data = null;
55 
56  private static $predefined = false;
57 
58  /**
59  * Constructor
60  * @param $code An error code, describing the type of error
61  * @param $level One of the LEVEL_ constants
62  * "param $statusCode The HTTP status code that should be sent with this error
63  * @param $message An error message which is displayed to the user
64  * @param $data Some error codes required to transmit further information
65  * to the client (optional, default: _null_)
66  */
67  private function __construct($code, $level, $statusCode, $message, $data=null) {
68  $this->code = $code;
69  $this->level = $level;
70  $this->statusCode = $statusCode;
71  $this->message = $message;
72  $this->data = $data;
73  }
74 
75  /**
76  * Get the error code
77  * @return String
78  */
79  public function getCode() {
80  return $this->code;
81  }
82 
83  /**
84  * Get the error level
85  * @return String
86  */
87  public function getLevel() {
88  return $this->level;
89  }
90 
91  /**
92  * Get the associated HTTP status code
93  * @return Integer
94  */
95  public function getStatusCode() {
96  return $this->statusCode;
97  }
98 
99  /**
100  * Get the error message
101  * @return String
102  */
103  public function getMessage() {
104  return $this->message;
105  }
106 
107  /**
108  * Set the error data
109  * @param $data Some error codes require to transmit
110  * further information to the client
111  */
112  public function setData($data) {
113  $this->data = $data;
114  }
115 
116  /**
117  * Get the error data
118  * @return Mixed
119  */
120  public function getData() {
121  return $this->data;
122  }
123 
124  /**
125  * Get a string representation of the error
126  * @return String
127  */
128  public function __toString() {
129  $str = strtoupper($this->level).": ".$this->code." (".$this->statusCode.
130  "): ".$this->message;
131  if ($this->data) {
132  $str .= " Data: ".StringUtil::getDump($this->data);
133  }
134  return $str;
135  }
136 
137  /**
138  * Factory method for retrieving a predefined error instance.
139  * @param $code An error code
140  * @param $data Some error codes required to transmit further information
141  * to the client (optional, default: _null_)
142  * @return ApplicationError
143  */
144  public static function get($code, $data=null) {
145  self::predefine();
146  if (defined($code)) {
147  $def = unserialize(constant($code));
148  $error = new ApplicationError($def[0], $def[1], $def[2], $def[3], $data);
149  return $error;
150  }
151  else {
152  throw new IllegalArgumentException("The error code '".$code."' is not defined");
153  }
154  }
155 
156  /**
157  * Factory method for creating a general error instance.
158  * @param $message Error message
159  * @param $statusCode HTTP status code (optional, default: _DEFAULT_ERROR_STATUS_)
160  * @return ApplicationError
161  */
162  public static function getGeneral($message, $statusCode=self::DEFAULT_ERROR_STATUS) {
163  $error = new ApplicationError('GENERAL_ERROR', ApplicationError::LEVEL_ERROR, $statusCode, $message);
164  return $error;
165  }
166 
167  /**
168  * Factory method for transforming an exception into an ApplicationError instance.
169  * @param $ex Exception
170  * @return ApplicationError
171  */
172  public static function fromException(\Exception $ex) {
173  if ($ex instanceof ApplicationException) {
174  return $ex->getError();
175  }
176  if ($ex instanceof AuthorizationException) {
177  return self::get(PERMISSION_DENIED);
178  }
179  return self::getGeneral($ex->getMessage());
180  }
181 
182  /**
183  * Predefined errors
184  */
185  private static function predefine() {
186  if (!self::$predefined) {
187  $message = ObjectFactory::getInstance('message');
188  define('GENERAL_WARNING', serialize(['GENERAL_WARNING', ApplicationError::LEVEL_WARNING, 400,
189  $message->getText('An unspecified warning occurred.')
190  ]));
191  define('GENERAL_ERROR', serialize(['GENERAL_ERROR', ApplicationError::LEVEL_ERROR, 500,
192  $message->getText('An unspecified error occurred.')
193  ]));
194  define('GENERAL_FATAL', serialize(['GENERAL_FATAL', ApplicationError::LEVEL_FATAL, 500,
195  $message->getText('An unspecified fatal error occurred.')
196  ]));
197 
198  define('ACTION_INVALID', serialize(['ACTION_INVALID', ApplicationError::LEVEL_ERROR, 404,
199  $message->getText('The requested action is unknown.')
200  ]));
201  define('SESSION_INVALID', serialize(['SESSION_INVALID', ApplicationError::LEVEL_ERROR, 401,
202  $message->getText('The session is invalid.')
203  ]));
204  define('PARAMETER_MISSING', serialize(['PARAMETER_MISSING', ApplicationError::LEVEL_ERROR, 400,
205  $message->getText('One or more parameters are missing.')
206  ]));
207  define('PARAMETER_INVALID', serialize(['PARAMETER_INVALID', ApplicationError::LEVEL_ERROR, 400,
208  $message->getText('One or more parameters are invalid.')
209  ]));
210  define('OID_INVALID', serialize(['OID_INVALID', ApplicationError::LEVEL_ERROR, 400,
211  $message->getText('One or more object ids are invalid.')
212  ]));
213  define('CLASS_NAME_INVALID', serialize(['CLASS_NAME_INVALID', ApplicationError::LEVEL_ERROR, 400,
214  $message->getText('One or more classes are invalid.')
215  ]));
216 
217  define('AUTHENTICATION_FAILED', serialize(['AUTHENTICATION_FAILED', ApplicationError::LEVEL_ERROR, 401,
218  $message->getText('Authentication failed.')
219  ]));
220  define('PERMISSION_DENIED', serialize(['PERMISSION_DENIED', ApplicationError::LEVEL_ERROR, 403,
221  $message->getText('The user does not have the permission to perform this action.')
222  ]));
223 
224  define('LIMIT_NEGATIVE', serialize(['LIMIT_NEGATIVE', ApplicationError::LEVEL_WARNING, 400,
225  $message->getText('The passed limit is a negative number.')
226  ]));
227  define('OFFSET_OUT_OF_BOUNDS', serialize(['OFFSET_OUT_OF_BOUNDS', ApplicationError::LEVEL_WARNING, 400,
228  $message->getText('The passed offset is negative or greater than the number of entries matching the parameters.')
229  ]));
230  define('SORT_FIELD_UNKNOWN', serialize(['SORT_FIELD_UNKNOWN', ApplicationError::LEVEL_ERROR, 400,
231  $message->getText('The passed sortFieldName is no valid attribute of the passed class.')
232  ]));
233  define('SORT_DIRECTION_UNKNOWN', serialize(['SORT_DIRECTION_UNKNOWN', ApplicationError::LEVEL_ERROR, 400,
234  $message->getText('The passed sortDirection has an invalid value.')
235  ]));
236 
237  define('DEPTH_INVALID', serialize(['DEPTH_INVALID', ApplicationError::LEVEL_ERROR, 400,
238  $message->getText('The passed depth is a negative number other than -1.')
239  ]));
240 
241  define('ATTRIBUTE_NAME_INVALID', serialize(['ATTRIBUTE_NAME_INVALID', ApplicationError::LEVEL_ERROR, 400,
242  $message->getText('The attribute name passed cannot be found in the selected class.')
243  ]));
244  define('ATTRIBUTE_VALUE_INVALID', serialize(['ATTRIBUTE_VALUE_INVALID', ApplicationError::LEVEL_ERROR, 400,
245  $message->getText('The attribute value passed is invalid for the attribute.')
246  ]));
247  define('CONCURRENT_UPDATE', serialize(['CONCURRENT_UPDATE', ApplicationError::LEVEL_ERROR, 400,
248  $message->getText('The server detected a concurrent update.')
249  ]));
250 
251  define('ROLE_INVALID', serialize(['ROLE_INVALID', ApplicationError::LEVEL_ERROR, 400,
252  $message->getText('The role passed cannot be found in the selected source class.')
253  ]));
254  define('ASSOCIATION_INVALID', serialize(['ASSOCIATION_INVALID', ApplicationError::LEVEL_ERROR, 400,
255  $message->getText('There is no association between the source and the target class.')
256  ]));
257  define('ASSOCIATION_NOT_FOUND', serialize(['ASSOCIATION_NOT_FOUND', ApplicationError::LEVEL_WARNING, 400,
258  $message->getText('No current association matching the input parameters can be found.')
259  ]));
260 
261  define('SEARCH_NOT_SUPPORTED', serialize(['SEARCH_NOT_SUPPORTED', ApplicationError::LEVEL_ERROR, 400,
262  $message->getText('There selected class does not support searching.')
263  ]));
264 
265  define('ORDER_UNDEFINED', serialize(['ORDER_UNDEFINED', ApplicationError::LEVEL_WARNING, 400,
266  $message->getText('There is no order defined for the root object.')
267  ]));
268 
269  define('REFERENCE_INVALID', serialize(['REFERENCE_INVALID', ApplicationError::LEVEL_ERROR, 400,
270  $message->getText('There reference object cannot be found in the container object.')
271  ]));
272  define('ORDER_NOT_SUPPORTED', serialize(['ORDER_NOT_SUPPORTED', ApplicationError::LEVEL_ERROR, 400,
273  $message->getText('The container class does not support ordered references.')
274  ]));
275 
276  define('CLASSES_DO_NOT_MATCH', serialize(['CLASSES_DO_NOT_MATCH', ApplicationError::LEVEL_ERROR, 400,
277  $message->getText('The classes of insertOid and referenceOid do not match.')
278  ]));
279 
280  define('HISTORY_NOT_SUPPORTED', serialize(['HISTORY_NOT_SUPPORTED', ApplicationError::LEVEL_ERROR, 400,
281  $message->getText('There selected class does not support history.')
282  ]));
283 
284  define('OBJECT_IS_LOCKED', serialize(['OBJECT_IS_LOCKED', ApplicationError::LEVEL_ERROR, 400,
285  $message->getText('The object is currently locked by another user.')
286  ]));
287 
288  self::$predefined = true;
289  }
290  }
291 }
292 ?>
getStatusCode()
Get the associated HTTP status code.
static fromException(\Exception $ex)
Factory method for transforming an exception into an ApplicationError instance.
IllegalArgumentException signals an exception in method arguments.
static getGeneral($message, $statusCode=self::DEFAULT_ERROR_STATUS)
Factory method for creating a general error instance.
ApplicationError is used to signal errors that occur while processing a request.
static get($code, $data=null)
Factory method for retrieving a predefined error instance.
ApplicationException signals a general application exception.
static getInstance($name, $dynamicConfiguration=[])
__toString()
Get a string representation of the error.
ObjectFactory implements the service locator pattern by wrapping a Factory instance and providing sta...
Presentation related interfaces and classes.
Definition: namespaces.php:59
AuthorizationException signals an exception in authorization.