Total Complexity | 104 |
Total Lines | 700 |
Duplicated Lines | 0 % |
Changes | 2 | ||
Bugs | 1 | Features | 0 |
Complex classes like PEAR often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
While breaking up the class, it is a good idea to analyze how other classes use PEAR, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
84 | class PEAR |
||
85 | { |
||
86 | /** |
||
87 | * Whether to enable internal debug messages. |
||
88 | * |
||
89 | * @var bool |
||
90 | * @access private |
||
91 | */ |
||
92 | public $_debug = false; |
||
93 | /** |
||
94 | * Default error mode for this object. |
||
95 | * |
||
96 | * @var int |
||
97 | * @access private |
||
98 | */ |
||
99 | public $_default_error_mode = null; |
||
100 | /** |
||
101 | * Default error options used for this object when error mode |
||
102 | * is PEAR_ERROR_TRIGGER. |
||
103 | * |
||
104 | * @var int |
||
105 | * @access private |
||
106 | */ |
||
107 | public $_default_error_options = null; |
||
108 | /** |
||
109 | * Default error handler (callback) for this object, if error mode is |
||
110 | * PEAR_ERROR_CALLBACK. |
||
111 | * |
||
112 | * @var string |
||
113 | * @access private |
||
114 | */ |
||
115 | public $_default_error_handler = ''; |
||
116 | /** |
||
117 | * Which class to use for error objects. |
||
118 | * |
||
119 | * @var string |
||
120 | * @access private |
||
121 | */ |
||
122 | public $_error_class = 'PEAR_Error'; |
||
123 | /** |
||
124 | * An array of expected errors. |
||
125 | * |
||
126 | * @var array |
||
127 | * @access private |
||
128 | */ |
||
129 | public $_expected_errors = []; |
||
130 | /** |
||
131 | * List of methods that can be called both statically and non-statically. |
||
132 | * @var array |
||
133 | */ |
||
134 | protected static $bivalentMethods = [ |
||
135 | 'setErrorHandling' => true, |
||
136 | 'raiseError' => true, |
||
137 | 'throwError' => true, |
||
138 | 'pushErrorHandling' => true, |
||
139 | 'popErrorHandling' => true, |
||
140 | ]; |
||
141 | |||
142 | /** |
||
143 | * Constructor. Registers this object in |
||
144 | * $_PEAR_destructor_object_list for destructor emulation if a |
||
145 | * destructor object exists. |
||
146 | * |
||
147 | * @param string $error_class (optional) which class to use for |
||
148 | * error objects, defaults to PEAR_Error. |
||
149 | * @access public |
||
150 | * @return void |
||
151 | */ |
||
152 | public function __construct($error_class = null) |
||
153 | { |
||
154 | $classname = strtolower(get_class($this)); |
||
155 | if ($this->_debug) { |
||
156 | print "PEAR constructor called, class=$classname\n"; |
||
157 | } |
||
158 | |||
159 | if (null !== $error_class) { |
||
160 | $this->_error_class = $error_class; |
||
161 | } |
||
162 | |||
163 | while ($classname && strcasecmp($classname, 'pear')) { |
||
164 | $destructor = "_$classname"; |
||
165 | if (method_exists($this, $destructor)) { |
||
166 | global $_PEAR_destructor_object_list; |
||
167 | $_PEAR_destructor_object_list[] = $this; |
||
168 | if (!isset($GLOBALS['_PEAR_SHUTDOWN_REGISTERED'])) { |
||
169 | register_shutdown_function('_PEAR_call_destructors'); |
||
170 | $GLOBALS['_PEAR_SHUTDOWN_REGISTERED'] = true; |
||
171 | } |
||
172 | break; |
||
173 | } else { |
||
174 | $classname = get_parent_class($classname); |
||
175 | } |
||
176 | } |
||
177 | } |
||
178 | |||
179 | /** |
||
180 | * Only here for backwards compatibility. |
||
181 | * E.g. Archive_Tar calls $this->PEAR() in its constructor. |
||
182 | * |
||
183 | * @param string $error_class Which class to use for error objects, |
||
184 | * defaults to PEAR_Error. |
||
185 | */ |
||
186 | public function PEAR($error_class = null) |
||
187 | { |
||
188 | self::__construct($error_class); |
||
189 | } |
||
190 | |||
191 | /** |
||
192 | * Destructor (the emulated type of...). Does nothing right now, |
||
193 | * but is included for forward compatibility, so subclass |
||
194 | * destructors should always call it. |
||
195 | * |
||
196 | * See the note in the class desciption about output from |
||
197 | * destructors. |
||
198 | * |
||
199 | * @access public |
||
200 | * @return void |
||
201 | */ |
||
202 | public function _PEAR() |
||
203 | { |
||
204 | if ($this->_debug) { |
||
205 | printf("PEAR destructor called, class=%s\n", strtolower(get_class($this))); |
||
206 | } |
||
207 | } |
||
208 | |||
209 | public function __call($method, $arguments) |
||
210 | { |
||
211 | if (!isset(self::$bivalentMethods[$method])) { |
||
212 | trigger_error( |
||
213 | 'Call to undefined method PEAR::' . $method . '()', |
||
214 | E_USER_ERROR |
||
215 | ); |
||
216 | } |
||
217 | return call_user_func_array( |
||
218 | [get_class(), '_' . $method], |
||
219 | array_merge([$this], $arguments) |
||
220 | ); |
||
221 | } |
||
222 | |||
223 | public static function __callStatic($method, $arguments) |
||
224 | { |
||
225 | if (!isset(self::$bivalentMethods[$method])) { |
||
226 | trigger_error( |
||
227 | 'Call to undefined method PEAR::' . $method . '()', |
||
228 | E_USER_ERROR |
||
229 | ); |
||
230 | } |
||
231 | return call_user_func_array( |
||
232 | [get_class(), '_' . $method], |
||
233 | array_merge([null], $arguments) |
||
234 | ); |
||
235 | } |
||
236 | |||
237 | /** |
||
238 | * If you have a class that's mostly/entirely static, and you need static |
||
239 | * properties, you can use this method to simulate them. Eg. in your method(s) |
||
240 | * do this: $myVar = &PEAR::getStaticProperty('myclass', 'myVar'); |
||
241 | * You MUST use a reference, or they will not persist! |
||
242 | * |
||
243 | * @param string $class The calling classname, to prevent clashes |
||
244 | * @param string $var The variable to retrieve. |
||
245 | * @return mixed A reference to the variable. If not set it will be |
||
246 | * auto initialised to NULL. |
||
247 | */ |
||
248 | public static function &getStaticProperty($class, $var) |
||
249 | { |
||
250 | static $properties; |
||
251 | if (!isset($properties[$class])) { |
||
252 | $properties[$class] = []; |
||
253 | } |
||
254 | |||
255 | if (!array_key_exists($var, $properties[$class])) { |
||
256 | $properties[$class][$var] = null; |
||
257 | } |
||
258 | |||
259 | return $properties[$class][$var]; |
||
260 | } |
||
261 | |||
262 | /** |
||
263 | * Use this function to register a shutdown method for static |
||
264 | * classes. |
||
265 | * |
||
266 | * @param mixed $func The function name (or array of class/method) to call |
||
267 | * @param mixed $args The arguments to pass to the function |
||
268 | * |
||
269 | * @return void |
||
270 | */ |
||
271 | public static function registerShutdownFunc($func, $args = []) |
||
272 | { |
||
273 | // if we are called statically, there is a potential |
||
274 | // that no shutdown func is registered. Bug #6445 |
||
275 | if (!isset($GLOBALS['_PEAR_SHUTDOWN_REGISTERED'])) { |
||
276 | register_shutdown_function('_PEAR_call_destructors'); |
||
277 | $GLOBALS['_PEAR_SHUTDOWN_REGISTERED'] = true; |
||
278 | } |
||
279 | $GLOBALS['_PEAR_shutdown_funcs'][] = [$func, $args]; |
||
280 | } |
||
281 | |||
282 | /** |
||
283 | * Tell whether a value is a PEAR error. |
||
284 | * |
||
285 | * @param mixed $data the value to test |
||
286 | * @param int $code if $data is an error object, return true |
||
287 | * only if $code is a string and |
||
288 | * $obj->getMessage() == $code or |
||
289 | * $code is an integer and $obj->getCode() == $code |
||
290 | * |
||
291 | * @return bool true if parameter is an error |
||
292 | */ |
||
293 | public static function isError($data, $code = null) |
||
294 | { |
||
295 | if (!is_a($data, 'PEAR_Error')) { |
||
296 | return false; |
||
297 | } |
||
298 | |||
299 | if (null === $code) { |
||
300 | return true; |
||
301 | } elseif (is_string($code)) { |
||
302 | return $data->getMessage() == $code; |
||
303 | } |
||
304 | |||
305 | return $data->getCode() == $code; |
||
306 | } |
||
307 | |||
308 | /** |
||
309 | * Sets how errors generated by this object should be handled. |
||
310 | * Can be invoked both in objects and statically. If called |
||
311 | * statically, setErrorHandling sets the default behaviour for all |
||
312 | * PEAR objects. If called in an object, setErrorHandling sets |
||
313 | * the default behaviour for that object. |
||
314 | * |
||
315 | * @param object $object |
||
316 | * Object the method was called on (non-static mode) |
||
317 | * |
||
318 | * @param int $mode |
||
319 | * One of PEAR_ERROR_RETURN, PEAR_ERROR_PRINT, |
||
320 | * PEAR_ERROR_TRIGGER, PEAR_ERROR_DIE, |
||
321 | * PEAR_ERROR_CALLBACK or PEAR_ERROR_EXCEPTION. |
||
322 | * |
||
323 | * @param mixed $options |
||
324 | * When $mode is PEAR_ERROR_TRIGGER, this is the error level (one |
||
325 | * of E_USER_NOTICE, E_USER_WARNING or E_USER_ERROR). |
||
326 | * |
||
327 | * When $mode is PEAR_ERROR_CALLBACK, this parameter is expected |
||
328 | * to be the callback function or method. A callback |
||
329 | * function is a string with the name of the function, a |
||
330 | * callback method is an array of two elements: the element |
||
331 | * at index 0 is the object, and the element at index 1 is |
||
332 | * the name of the method to call in the object. |
||
333 | * |
||
334 | * When $mode is PEAR_ERROR_PRINT or PEAR_ERROR_DIE, this is |
||
335 | * a printf format string used when printing the error |
||
336 | * message. |
||
337 | * |
||
338 | * @access public |
||
339 | * @return void |
||
340 | * @see PEAR_ERROR_RETURN |
||
341 | * @see PEAR_ERROR_PRINT |
||
342 | * @see PEAR_ERROR_TRIGGER |
||
343 | * @see PEAR_ERROR_DIE |
||
344 | * @see PEAR_ERROR_CALLBACK |
||
345 | * @see PEAR_ERROR_EXCEPTION |
||
346 | * |
||
347 | * @since PHP 4.0.5 |
||
348 | */ |
||
349 | protected static function _setErrorHandling( |
||
350 | $object, |
||
351 | $mode = null, |
||
352 | $options = null |
||
353 | ) { |
||
354 | if (null !== $object) { |
||
355 | $setmode = &$object->_default_error_mode; |
||
356 | $setoptions = &$object->_default_error_options; |
||
357 | } else { |
||
358 | $setmode = &$GLOBALS['_PEAR_default_error_mode']; |
||
359 | $setoptions = &$GLOBALS['_PEAR_default_error_options']; |
||
360 | } |
||
361 | |||
362 | switch ($mode) { |
||
363 | case PEAR_ERROR_EXCEPTION: |
||
364 | case PEAR_ERROR_RETURN: |
||
365 | case PEAR_ERROR_PRINT: |
||
366 | case PEAR_ERROR_TRIGGER: |
||
367 | case PEAR_ERROR_DIE: |
||
368 | case null: |
||
369 | $setmode = $mode; |
||
370 | $setoptions = $options; |
||
371 | break; |
||
372 | |||
373 | case PEAR_ERROR_CALLBACK: |
||
374 | $setmode = $mode; |
||
375 | // class/object method callback |
||
376 | if (is_callable($options)) { |
||
377 | $setoptions = $options; |
||
378 | } else { |
||
379 | trigger_error('invalid error callback', E_USER_WARNING); |
||
380 | } |
||
381 | break; |
||
382 | |||
383 | default: |
||
384 | trigger_error('invalid error mode', E_USER_WARNING); |
||
385 | break; |
||
386 | } |
||
387 | } |
||
388 | |||
389 | /** |
||
390 | * This method is used to tell which errors you expect to get. |
||
391 | * Expected errors are always returned with error mode |
||
392 | * PEAR_ERROR_RETURN. Expected error codes are stored in a stack, |
||
393 | * and this method pushes a new element onto it. The list of |
||
394 | * expected errors are in effect until they are popped off the |
||
395 | * stack with the popExpect() method. |
||
396 | * |
||
397 | * Note that this method can not be called statically |
||
398 | * |
||
399 | * @param mixed $code a single error code or an array of error codes to expect |
||
400 | * |
||
401 | * @return int the new depth of the "expected errors" stack |
||
402 | * @access public |
||
403 | */ |
||
404 | public function expectError($code = '*') |
||
405 | { |
||
406 | if (is_array($code)) { |
||
407 | array_push($this->_expected_errors, $code); |
||
408 | } else { |
||
409 | array_push($this->_expected_errors, [$code]); |
||
410 | } |
||
411 | return count($this->_expected_errors); |
||
412 | } |
||
413 | |||
414 | /** |
||
415 | * This method pops one element off the expected error codes |
||
416 | * stack. |
||
417 | * |
||
418 | * @return array the list of error codes that were popped |
||
419 | */ |
||
420 | public function popExpect() |
||
421 | { |
||
422 | return array_pop($this->_expected_errors); |
||
423 | } |
||
424 | |||
425 | /** |
||
426 | * This method checks unsets an error code if available |
||
427 | * |
||
428 | * @param mixed error code |
||
429 | * @return bool true if the error code was unset, false otherwise |
||
430 | * @access private |
||
431 | * @since PHP 4.3.0 |
||
432 | */ |
||
433 | public function _checkDelExpect($error_code) |
||
434 | { |
||
435 | $deleted = false; |
||
436 | foreach ($this->_expected_errors as $key => $error_array) { |
||
437 | if (in_array($error_code, $error_array)) { |
||
438 | unset($this->_expected_errors[$key][array_search($error_code, $error_array)]); |
||
439 | $deleted = true; |
||
440 | } |
||
441 | |||
442 | // clean up empty arrays |
||
443 | if (0 == count($this->_expected_errors[$key])) { |
||
444 | unset($this->_expected_errors[$key]); |
||
445 | } |
||
446 | } |
||
447 | |||
448 | return $deleted; |
||
449 | } |
||
450 | |||
451 | /** |
||
452 | * This method deletes all occurrences of the specified element from |
||
453 | * the expected error codes stack. |
||
454 | * |
||
455 | * @param mixed $error_code error code that should be deleted |
||
456 | * @return mixed list of error codes that were deleted or error |
||
457 | * @access public |
||
458 | * @since PHP 4.3.0 |
||
459 | */ |
||
460 | public function delExpect($error_code) |
||
482 | } |
||
483 | |||
484 | /** |
||
485 | * This method is a wrapper that returns an instance of the |
||
486 | * configured error class with this object's default error |
||
487 | * handling applied. If the $mode and $options parameters are not |
||
488 | * specified, the object's defaults are used. |
||
489 | * |
||
490 | * @param mixed $message a text error message or a PEAR error object |
||
491 | * |
||
492 | * @param int $code a numeric error code (it is up to your class |
||
493 | * to define these if you want to use codes) |
||
494 | * |
||
495 | * @param int $mode One of PEAR_ERROR_RETURN, PEAR_ERROR_PRINT, |
||
496 | * PEAR_ERROR_TRIGGER, PEAR_ERROR_DIE, |
||
497 | * PEAR_ERROR_CALLBACK, PEAR_ERROR_EXCEPTION. |
||
498 | * |
||
499 | * @param mixed $options If $mode is PEAR_ERROR_TRIGGER, this parameter |
||
500 | * specifies the PHP-internal error level (one of |
||
501 | * E_USER_NOTICE, E_USER_WARNING or E_USER_ERROR). |
||
502 | * If $mode is PEAR_ERROR_CALLBACK, this |
||
503 | * parameter specifies the callback function or |
||
504 | * method. In other error modes this parameter |
||
505 | * is ignored. |
||
506 | * |
||
507 | * @param string $userinfo If you need to pass along for example debug |
||
508 | * information, this parameter is meant for that. |
||
509 | * |
||
510 | * @param string $error_class The returned error object will be |
||
511 | * instantiated from this class, if specified. |
||
512 | * |
||
513 | * @param bool $skipmsg If true, raiseError will only pass error codes, |
||
514 | * the error message parameter will be dropped. |
||
515 | * |
||
516 | * @return object a PEAR error object |
||
517 | * @see PEAR::setErrorHandling |
||
518 | * @since PHP 4.0.5 |
||
519 | */ |
||
520 | protected static function _raiseError( |
||
521 | $object, |
||
522 | $message = null, |
||
523 | $code = null, |
||
524 | $mode = null, |
||
525 | $options = null, |
||
526 | $userinfo = null, |
||
527 | $error_class = null, |
||
528 | $skipmsg = false |
||
529 | ) { |
||
530 | // The error is yet a PEAR error object |
||
531 | if (is_object($message)) { |
||
532 | $code = $message->getCode(); |
||
533 | $userinfo = $message->getUserInfo(); |
||
534 | $error_class = $message->getType(); |
||
535 | $message->error_message_prefix = ''; |
||
536 | $message = $message->getMessage(); |
||
537 | } |
||
538 | |||
539 | if (null !== $object |
||
540 | && isset($object->_expected_errors) |
||
541 | && count($object->_expected_errors) > 0 |
||
542 | && count($exp = end($object->_expected_errors))) { |
||
543 | if ('*' === $exp[0] |
||
544 | || (is_int(reset($exp)) && in_array($code, $exp)) |
||
545 | || (is_string(reset($exp)) && in_array($message, $exp))) { |
||
546 | $mode = PEAR_ERROR_RETURN; |
||
547 | } |
||
548 | } |
||
549 | |||
550 | // No mode given, try global ones |
||
551 | if (null === $mode) { |
||
552 | // Class error handler |
||
553 | if (null !== $object && isset($object->_default_error_mode)) { |
||
554 | $mode = $object->_default_error_mode; |
||
555 | $options = $object->_default_error_options; |
||
556 | // Global error handler |
||
557 | } elseif (isset($GLOBALS['_PEAR_default_error_mode'])) { |
||
558 | $mode = $GLOBALS['_PEAR_default_error_mode']; |
||
559 | $options = $GLOBALS['_PEAR_default_error_options']; |
||
560 | } |
||
561 | } |
||
562 | |||
563 | if (null !== $error_class) { |
||
564 | $ec = $error_class; |
||
565 | } elseif (null !== $object && isset($object->_error_class)) { |
||
566 | $ec = $object->_error_class; |
||
567 | } else { |
||
568 | $ec = 'PEAR_Error'; |
||
569 | } |
||
570 | |||
571 | if ($skipmsg) { |
||
572 | $a = new $ec($code, $mode, $options, $userinfo); |
||
573 | } else { |
||
574 | $a = new $ec($message, $code, $mode, $options, $userinfo); |
||
575 | } |
||
576 | |||
577 | return $a; |
||
578 | } |
||
579 | |||
580 | /** |
||
581 | * Simpler form of raiseError with fewer options. In most cases |
||
582 | * message, code and userinfo are enough. |
||
583 | * |
||
584 | * @param mixed $message a text error message or a PEAR error object |
||
585 | * |
||
586 | * @param int $code a numeric error code (it is up to your class |
||
587 | * to define these if you want to use codes) |
||
588 | * |
||
589 | * @param string $userinfo If you need to pass along for example debug |
||
590 | * information, this parameter is meant for that. |
||
591 | * |
||
592 | * @return object a PEAR error object |
||
593 | * @see PEAR::raiseError |
||
594 | */ |
||
595 | protected static function _throwError($object, $message = null, $code = null, $userinfo = null) |
||
604 | } |
||
605 | |||
606 | public static function staticPushErrorHandling($mode, $options = null) |
||
607 | { |
||
608 | $stack = &$GLOBALS['_PEAR_error_handler_stack']; |
||
609 | $def_mode = &$GLOBALS['_PEAR_default_error_mode']; |
||
610 | $def_options = &$GLOBALS['_PEAR_default_error_options']; |
||
611 | $stack[] = [$def_mode, $def_options]; |
||
612 | switch ($mode) { |
||
613 | case PEAR_ERROR_EXCEPTION: |
||
614 | case PEAR_ERROR_RETURN: |
||
615 | case PEAR_ERROR_PRINT: |
||
616 | case PEAR_ERROR_TRIGGER: |
||
617 | case PEAR_ERROR_DIE: |
||
618 | case null: |
||
619 | $def_mode = $mode; |
||
620 | $def_options = $options; |
||
621 | break; |
||
622 | |||
623 | case PEAR_ERROR_CALLBACK: |
||
624 | $def_mode = $mode; |
||
625 | // class/object method callback |
||
626 | if (is_callable($options)) { |
||
627 | $def_options = $options; |
||
628 | } else { |
||
629 | trigger_error('invalid error callback', E_USER_WARNING); |
||
630 | } |
||
631 | break; |
||
632 | |||
633 | default: |
||
634 | trigger_error('invalid error mode', E_USER_WARNING); |
||
635 | break; |
||
636 | } |
||
637 | $stack[] = [$mode, $options]; |
||
638 | return true; |
||
639 | } |
||
640 | |||
641 | public static function staticPopErrorHandling() |
||
642 | { |
||
643 | $stack = &$GLOBALS['_PEAR_error_handler_stack']; |
||
644 | $setmode = &$GLOBALS['_PEAR_default_error_mode']; |
||
645 | $setoptions = &$GLOBALS['_PEAR_default_error_options']; |
||
646 | array_pop($stack); |
||
647 | [$mode, $options] = $stack[count($stack) - 1]; |
||
648 | array_pop($stack); |
||
649 | switch ($mode) { |
||
650 | case PEAR_ERROR_EXCEPTION: |
||
651 | case PEAR_ERROR_RETURN: |
||
652 | case PEAR_ERROR_PRINT: |
||
653 | case PEAR_ERROR_TRIGGER: |
||
654 | case PEAR_ERROR_DIE: |
||
655 | case null: |
||
656 | $setmode = $mode; |
||
657 | $setoptions = $options; |
||
658 | break; |
||
659 | |||
660 | case PEAR_ERROR_CALLBACK: |
||
661 | $setmode = $mode; |
||
662 | // class/object method callback |
||
663 | if (is_callable($options)) { |
||
664 | $setoptions = $options; |
||
665 | } else { |
||
666 | trigger_error('invalid error callback', E_USER_WARNING); |
||
667 | } |
||
668 | break; |
||
669 | |||
670 | default: |
||
671 | trigger_error('invalid error mode', E_USER_WARNING); |
||
672 | break; |
||
673 | } |
||
674 | return true; |
||
675 | } |
||
676 | |||
677 | /** |
||
678 | * Push a new error handler on top of the error handler options stack. With this |
||
679 | * you can easily override the actual error handler for some code and restore |
||
680 | * it later with popErrorHandling. |
||
681 | * |
||
682 | * @param mixed $mode (same as setErrorHandling) |
||
683 | * @param mixed $options (same as setErrorHandling) |
||
684 | * |
||
685 | * @return bool Always true |
||
686 | * |
||
687 | * @see PEAR::setErrorHandling |
||
688 | */ |
||
689 | protected static function _pushErrorHandling($object, $mode, $options = null) |
||
690 | { |
||
691 | $stack = &$GLOBALS['_PEAR_error_handler_stack']; |
||
692 | if (null !== $object) { |
||
693 | $def_mode = &$object->_default_error_mode; |
||
694 | $def_options = &$object->_default_error_options; |
||
695 | } else { |
||
696 | $def_mode = &$GLOBALS['_PEAR_default_error_mode']; |
||
697 | $def_options = &$GLOBALS['_PEAR_default_error_options']; |
||
698 | } |
||
699 | $stack[] = [$def_mode, $def_options]; |
||
700 | |||
701 | if (null !== $object) { |
||
702 | $object->setErrorHandling($mode, $options); |
||
703 | } else { |
||
704 | self::setErrorHandling($mode, $options); |
||
705 | } |
||
706 | $stack[] = [$mode, $options]; |
||
707 | return true; |
||
708 | } |
||
709 | |||
710 | /** |
||
711 | * Pop the last error handler used |
||
712 | * |
||
713 | * @return bool Always true |
||
714 | * |
||
715 | * @see PEAR::pushErrorHandling |
||
716 | */ |
||
717 | protected static function _popErrorHandling($object) |
||
718 | { |
||
719 | $stack = &$GLOBALS['_PEAR_error_handler_stack']; |
||
720 | array_pop($stack); |
||
721 | [$mode, $options] = $stack[count($stack) - 1]; |
||
722 | array_pop($stack); |
||
723 | if (null !== $object) { |
||
724 | $object->setErrorHandling($mode, $options); |
||
725 | } else { |
||
726 | self::setErrorHandling($mode, $options); |
||
727 | } |
||
728 | return true; |
||
729 | } |
||
730 | |||
731 | /** |
||
732 | * OS independent PHP extension load. Remember to take care |
||
733 | * on the correct extension name for case sensitive OSes. |
||
734 | * |
||
735 | * @param string $ext The extension name |
||
736 | * @return bool Success or not on the dl() call |
||
737 | */ |
||
738 | public static function loadExtension($ext) |
||
739 | { |
||
740 | if (extension_loaded($ext)) { |
||
741 | return true; |
||
742 | } |
||
743 | |||
744 | // if either returns true dl() will produce a FATAL error, stop that |
||
745 | if (false === function_exists('dl') |
||
746 | || 1 != ini_get('enable_dl')) { |
||
747 | return false; |
||
748 | } |
||
749 | |||
750 | if (OS_WINDOWS) { |
||
751 | $suffix = '.dll'; |
||
752 | } elseif (PHP_OS == 'HP-UX') { |
||
753 | $suffix = '.sl'; |
||
754 | } elseif (PHP_OS == 'AIX') { |
||
755 | $suffix = '.a'; |
||
756 | } elseif (PHP_OS == 'OSX') { |
||
757 | $suffix = '.bundle'; |
||
758 | } else { |
||
759 | $suffix = '.so'; |
||
760 | } |
||
761 | |||
762 | return @dl('php_' . $ext . $suffix) || @dl($ext . $suffix); |
||
763 | } |
||
764 | |||
765 | /** |
||
766 | * Get SOURCE_DATE_EPOCH environment variable |
||
767 | * See https://reproducible-builds.org/specs/source-date-epoch/ |
||
768 | * |
||
769 | * @return int |
||
770 | * @access public |
||
771 | */ |
||
772 | public static function getSourceDateEpoch() |
||
784 | } |
||
785 | } |
||
786 | } |
||
787 | |||
788 | function _PEAR_call_destructors() |
||
789 | { |
||
790 | global $_PEAR_destructor_object_list; |
||
791 | if (is_array($_PEAR_destructor_object_list) |
||
792 | && count($_PEAR_destructor_object_list)) { |
||
793 | reset($_PEAR_destructor_object_list); |
||
794 | |||
795 | $destructLifoExists = PEAR::getStaticProperty('PEAR', 'destructlifo'); |
||
796 | |||
797 | if ($destructLifoExists) { |
||
798 | $_PEAR_destructor_object_list = array_reverse($_PEAR_destructor_object_list); |
||
799 | } |
||
800 | |||
1142 |