PluginProbe
AcyMailing – An Ultimate Newsletter Plugin and Marketing Automation Solution for WordPress / 10.0.1
AcyMailing – An Ultimate Newsletter Plugin and Marketing Automation Solution for WordPress v10.0.1
11.1.1 11.1.0 11.0.5 11.0.4 11.0.3 11.0.2 11.0.1 11.0.0 10.11.1 10.11.0 10.10.2 10.10.1 10.10.0 10.9.1 trunk 10.0.0 10.0.1 10.1.0 10.1.1 10.1.2 10.1.3 10.1.4 10.2.0 10.2.1 10.2.2 All 62 releases
acymailing / back / Libraries / Pear / Pear.php

Pear.php in AcyMailing – An Ultimate Newsletter Plugin and Marketing Automation Solution for WordPress 10.0.1, at back/Libraries/Pear/Pear.php

870 lines 27.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace AcyMailing\Libraries\Pear;
4
5 acym_cmsLoaded();
6
7 /**
8 * PEAR, the PHP Extension and Application Repository
9 *
10 * PEAR class and PEAR_Error class
11 *
12 * PHP versions 4 and 5
13 *
14 * @category pear
15 * @package PEAR
16 * @author Sterling Hughes <[email protected]>
17 * @author Stig Bakken <[email protected]>
18 * @author Tomas V.V.Cox <[email protected]>
19 * @author Greg Beaver <[email protected]>
20 * @copyright 1997-2010 The Authors
21 * @license http://opensource.org/licenses/bsd-license.php New BSD License
22 * @link http://pear.php.net/package/PEAR
23 * @since File available since Release 0.1
24 */
25
26 /**#@+
27 * ERROR constants
28 */
29 define('PEAR_ERROR_RETURN', 1);
30 define('PEAR_ERROR_PRINT', 2);
31 define('PEAR_ERROR_TRIGGER', 4);
32 define('PEAR_ERROR_DIE', 8);
33 define('PEAR_ERROR_CALLBACK', 16);
34 /**
35 * WARNING: obsolete
36 * @deprecated
37 */
38 define('PEAR_ERROR_EXCEPTION', 32);
39 /**#@-*/
40
41 if (substr(PHP_OS, 0, 3) == 'WIN') {
42 define('OS_WINDOWS', true);
43 define('OS_UNIX', false);
44 define('PEAR_OS', 'Windows');
45 } else {
46 define('OS_WINDOWS', false);
47 define('OS_UNIX', true);
48 define('PEAR_OS', 'Unix'); // blatant assumption
49 }
50
51 $GLOBALS['_PEAR_default_error_mode'] = PEAR_ERROR_RETURN;
52 $GLOBALS['_PEAR_default_error_options'] = E_USER_NOTICE;
53 $GLOBALS['_PEAR_destructor_object_list'] = [];
54 $GLOBALS['_PEAR_shutdown_funcs'] = [];
55 $GLOBALS['_PEAR_error_handler_stack'] = [];
56
57 if (function_exists('ini_set')) {
58 @ini_set('track_errors', true);
59 }
60
61 /**
62 * Base class for other PEAR classes. Provides rudimentary
63 * emulation of destructors.
64 *
65 * If you want a destructor in your class, inherit PEAR and make a
66 * destructor method called _yourclassname (same name as the
67 * constructor, but with a "_" prefix). Also, in your constructor you
68 * have to call the PEAR constructor: $this->PEAR();.
69 * The destructor method will be called without parameters. Note that
70 * at in some SAPI implementations (such as Apache), any output during
71 * the request shutdown (in which destructors are called) seems to be
72 * discarded. If you need to get any debug information from your
73 * destructor, use error_log(), syslog() or something similar.
74 *
75 * IMPORTANT! To use the emulated destructors you need to create the
76 * objects by reference: $obj =& new PEAR_child;
77 *
78 * @category pear
79 * @package PEAR
80 * @author Stig Bakken <[email protected]>
81 * @author Tomas V.V. Cox <[email protected]>
82 * @author Greg Beaver <[email protected]>
83 * @copyright 1997-2006 The PHP Group
84 * @license http://opensource.org/licenses/bsd-license.php New BSD License
85 * @version Release: 1.10.16
86 * @link http://pear.php.net/package/PEAR
87 * @see PEAR_Error
88 * @since Class available since PHP 4.0.2
89 * @link http://pear.php.net/manual/en/core.pear.php#core.pear.pear
90 */
91 class Pear
92 {
93 /**
94 * Whether to enable internal debug messages.
95 *
96 * @var bool
97 * @access private
98 */
99 var $_debug = false;
100
101 /**
102 * Default error mode for this object.
103 *
104 * @var int
105 * @access private
106 */
107 var $_default_error_mode = null;
108
109 /**
110 * Default error options used for this object when error mode
111 * is PEAR_ERROR_TRIGGER.
112 *
113 * @var int
114 * @access private
115 */
116 var $_default_error_options = null;
117
118 /**
119 * Default error handler (callback) for this object, if error mode is
120 * PEAR_ERROR_CALLBACK.
121 *
122 * @var string
123 * @access private
124 */
125 var $_default_error_handler = '';
126
127 /**
128 * Which class to use for error objects.
129 *
130 * @var string
131 * @access private
132 */
133 var $_error_class = 'AcyMailing\Libraries\Pear\Error';
134
135 /**
136 * An array of expected errors.
137 *
138 * @var array
139 * @access private
140 */
141 var $_expected_errors = [];
142
143 /**
144 * List of methods that can be called both statically and non-statically.
145 * @var array
146 */
147 protected static $bivalentMethods = [
148 'setErrorHandling' => true,
149 'raiseError' => true,
150 'throwError' => true,
151 'pushErrorHandling' => true,
152 'popErrorHandling' => true,
153 ];
154
155 /**
156 * Constructor. Registers this object in
157 * $_PEAR_destructor_object_list for destructor emulation if a
158 * destructor object exists.
159 *
160 * @param string $error_class (optional) which class to use for
161 * error objects, defaults to PEAR_Error.
162 *
163 * @access public
164 * @return void
165 */
166 function __construct($error_class = null)
167 {
168 $classname = strtolower(get_class($this));
169 if ($this->_debug) {
170 print "PEAR constructor called, class=$classname\n";
171 }
172
173 if ($error_class !== null) {
174 $this->_error_class = $error_class;
175 }
176
177 while ($classname && strcasecmp($classname, "pear")) {
178 $destructor = "_$classname";
179 if (method_exists($this, $destructor)) {
180 global $_PEAR_destructor_object_list;
181 $_PEAR_destructor_object_list[] = $this;
182 if (!isset($GLOBALS['_PEAR_SHUTDOWN_REGISTERED'])) {
183 register_shutdown_function("_PEAR_call_destructors");
184 $GLOBALS['_PEAR_SHUTDOWN_REGISTERED'] = true;
185 }
186 break;
187 } else {
188 $classname = get_parent_class($classname);
189 }
190 }
191 }
192
193 /**
194 * Only here for backwards compatibility.
195 * E.g. Archive_Tar calls $this->PEAR() in its constructor.
196 *
197 * @param string $error_class Which class to use for error objects,
198 * defaults to PEAR_Error.
199 */
200 public function PEAR($error_class = null)
201 {
202 self::__construct($error_class);
203 }
204
205 /**
206 * Destructor (the emulated type of...). Does nothing right now,
207 * but is included for forward compatibility, so subclass
208 * destructors should always call it.
209 *
210 * See the note in the class desciption about output from
211 * destructors.
212 *
213 * @access public
214 * @return void
215 */
216 function _PEAR()
217 {
218 if ($this->_debug) {
219 printf("PEAR destructor called, class=%s\n", strtolower(get_class($this)));
220 }
221 }
222
223 public function __call($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
232 return call_user_func_array(
233 [__CLASS__, '_'.$method],
234 array_merge([$this], $arguments)
235 );
236 }
237
238 public static function __callStatic($method, $arguments)
239 {
240 if (!isset(self::$bivalentMethods[$method])) {
241 trigger_error(
242 'Call to undefined method PEAR::'.$method.'()',
243 E_USER_ERROR
244 );
245 }
246
247 return call_user_func_array(
248 [__CLASS__, '_'.$method],
249 array_merge([null], $arguments)
250 );
251 }
252
253 /**
254 * If you have a class that's mostly/entirely static, and you need static
255 * properties, you can use this method to simulate them. Eg. in your method(s)
256 * do this: $myVar = &PEAR::getStaticProperty('myclass', 'myVar');
257 * You MUST use a reference, or they will not persist!
258 *
259 * @param string $class The calling classname, to prevent clashes
260 * @param string $var The variable to retrieve.
261 *
262 * @return mixed A reference to the variable. If not set it will be
263 * auto initialised to NULL.
264 */
265 public static function &getStaticProperty($class, $var)
266 {
267 static $properties;
268 if (!isset($properties[$class])) {
269 $properties[$class] = [];
270 }
271
272 if (!array_key_exists($var, $properties[$class])) {
273 $properties[$class][$var] = null;
274 }
275
276 return $properties[$class][$var];
277 }
278
279 /**
280 * Use this function to register a shutdown method for static
281 * classes.
282 *
283 * @param mixed $func The function name (or array of class/method) to call
284 * @param mixed $args The arguments to pass to the function
285 *
286 * @return void
287 */
288 public static function registerShutdownFunc($func, $args = [])
289 {
290 // if we are called statically, there is a potential
291 // that no shutdown func is registered. Bug #6445
292 if (!isset($GLOBALS['_PEAR_SHUTDOWN_REGISTERED'])) {
293 register_shutdown_function("_PEAR_call_destructors");
294 $GLOBALS['_PEAR_SHUTDOWN_REGISTERED'] = true;
295 }
296 $GLOBALS['_PEAR_shutdown_funcs'][] = [$func, $args];
297 }
298
299 /**
300 * Tell whether a value is a PEAR error.
301 *
302 * @param mixed $data the value to test
303 * @param int $code if $data is an error object, return true
304 * only if $code is a string and
305 * $obj->getMessage() == $code or
306 * $code is an integer and $obj->getCode() == $code
307 *
308 * @return bool true if parameter is an error
309 */
310 public static function isError($data, $code = null)
311 {
312 if (!is_a($data, 'AcyMailing\Libraries\Pear\Error')) {
313 return false;
314 }
315
316 if (is_null($code)) {
317 return true;
318 } elseif (is_string($code)) {
319 return $data->getMessage() == $code;
320 }
321
322 return $data->getCode() == $code;
323 }
324
325 /**
326 * Sets how errors generated by this object should be handled.
327 * Can be invoked both in objects and statically. If called
328 * statically, setErrorHandling sets the default behaviour for all
329 * PEAR objects. If called in an object, setErrorHandling sets
330 * the default behaviour for that object.
331 *
332 * @param object $object
333 * Object the method was called on (non-static mode)
334 *
335 * @param int $mode
336 * One of PEAR_ERROR_RETURN, PEAR_ERROR_PRINT,
337 * PEAR_ERROR_TRIGGER, PEAR_ERROR_DIE,
338 * PEAR_ERROR_CALLBACK or PEAR_ERROR_EXCEPTION.
339 *
340 * @param mixed $options
341 * When $mode is PEAR_ERROR_TRIGGER, this is the error level (one
342 * of E_USER_NOTICE, E_USER_WARNING or E_USER_ERROR).
343 *
344 * When $mode is PEAR_ERROR_CALLBACK, this parameter is expected
345 * to be the callback function or method. A callback
346 * function is a string with the name of the function, a
347 * callback method is an array of two elements: the element
348 * at index 0 is the object, and the element at index 1 is
349 * the name of the method to call in the object.
350 *
351 * When $mode is PEAR_ERROR_PRINT or PEAR_ERROR_DIE, this is
352 * a printf format string used when printing the error
353 * message.
354 *
355 * @access public
356 * @return void
357 * @see PEAR_ERROR_RETURN
358 * @see PEAR_ERROR_PRINT
359 * @see PEAR_ERROR_TRIGGER
360 * @see PEAR_ERROR_DIE
361 * @see PEAR_ERROR_CALLBACK
362 * @see PEAR_ERROR_EXCEPTION
363 *
364 * @since PHP 4.0.5
365 */
366 protected static function _setErrorHandling(
367 $object,
368 $mode = null,
369 $options = null
370 ) {
371 if ($object !== null) {
372 $setmode = &$object->_default_error_mode;
373 $setoptions = &$object->_default_error_options;
374 } else {
375 $setmode = &$GLOBALS['_PEAR_default_error_mode'];
376 $setoptions = &$GLOBALS['_PEAR_default_error_options'];
377 }
378
379 switch ($mode) {
380 case PEAR_ERROR_EXCEPTION:
381 case PEAR_ERROR_RETURN:
382 case PEAR_ERROR_PRINT:
383 case PEAR_ERROR_TRIGGER:
384 case PEAR_ERROR_DIE:
385 case null:
386 $setmode = $mode;
387 $setoptions = $options;
388 break;
389
390 case PEAR_ERROR_CALLBACK:
391 $setmode = $mode;
392 // class/object method callback
393 if (is_callable($options)) {
394 $setoptions = $options;
395 } else {
396 trigger_error("invalid error callback", E_USER_WARNING);
397 }
398 break;
399
400 default:
401 trigger_error("invalid error mode", E_USER_WARNING);
402 break;
403 }
404 }
405
406 /**
407 * This method is used to tell which errors you expect to get.
408 * Expected errors are always returned with error mode
409 * PEAR_ERROR_RETURN. Expected error codes are stored in a stack,
410 * and this method pushes a new element onto it. The list of
411 * expected errors are in effect until they are popped off the
412 * stack with the popExpect() method.
413 *
414 * Note that this method can not be called statically
415 *
416 * @param mixed $code a single error code or an array of error codes to expect
417 *
418 * @return int the new depth of the "expected errors" stack
419 * @access public
420 */
421 function expectError($code = '*')
422 {
423 if (is_array($code)) {
424 array_push($this->_expected_errors, $code);
425 } else {
426 array_push($this->_expected_errors, [$code]);
427 }
428
429 return count($this->_expected_errors);
430 }
431
432 /**
433 * This method pops one element off the expected error codes
434 * stack.
435 *
436 * @return array the list of error codes that were popped
437 */
438 function popExpect()
439 {
440 return array_pop($this->_expected_errors);
441 }
442
443 /**
444 * This method checks unsets an error code if available
445 *
446 * @param mixed error code
447 *
448 * @return bool true if the error code was unset, false otherwise
449 * @access private
450 * @since PHP 4.3.0
451 */
452 function _checkDelExpect($error_code)
453 {
454 $deleted = false;
455 foreach ($this->_expected_errors as $key => $error_array) {
456 if (in_array($error_code, $error_array)) {
457 unset($this->_expected_errors[$key][array_search($error_code, $error_array)]);
458 $deleted = true;
459 }
460
461 // clean up empty arrays
462 if (0 == count($this->_expected_errors[$key])) {
463 unset($this->_expected_errors[$key]);
464 }
465 }
466
467 return $deleted;
468 }
469
470 /**
471 * This method deletes all occurrences of the specified element from
472 * the expected error codes stack.
473 *
474 * @param mixed $error_code error code that should be deleted
475 *
476 * @return mixed list of error codes that were deleted or error
477 * @access public
478 * @since PHP 4.3.0
479 */
480 function delExpect($error_code)
481 {
482 $deleted = false;
483 if ((is_array($error_code) && (0 != count($error_code)))) {
484 // $error_code is a non-empty array here; we walk through it trying
485 // to unset all values
486 foreach ($error_code as $key => $error) {
487 $deleted = $this->_checkDelExpect($error) ? true : false;
488 }
489
490 return $deleted ? true : PEAR::raiseError("The expected error you submitted does not exist"); // IMPROVE ME
491 } elseif (!empty($error_code)) {
492 // $error_code comes alone, trying to unset it
493 if ($this->_checkDelExpect($error_code)) {
494 return true;
495 }
496
497 return PEAR::raiseError("The expected error you submitted does not exist"); // IMPROVE ME
498 }
499
500 // $error_code is empty
501 return PEAR::raiseError("The expected error you submitted is empty"); // IMPROVE ME
502 }
503
504 /**
505 * This method is a wrapper that returns an instance of the
506 * configured error class with this object's default error
507 * handling applied. If the $mode and $options parameters are not
508 * specified, the object's defaults are used.
509 *
510 * @param mixed $message a text error message or a PEAR error object
511 *
512 * @param int $code a numeric error code (it is up to your class
513 * to define these if you want to use codes)
514 *
515 * @param int $mode One of PEAR_ERROR_RETURN, PEAR_ERROR_PRINT,
516 * PEAR_ERROR_TRIGGER, PEAR_ERROR_DIE,
517 * PEAR_ERROR_CALLBACK, PEAR_ERROR_EXCEPTION.
518 *
519 * @param mixed $options If $mode is PEAR_ERROR_TRIGGER, this parameter
520 * specifies the PHP-internal error level (one of
521 * E_USER_NOTICE, E_USER_WARNING or E_USER_ERROR).
522 * If $mode is PEAR_ERROR_CALLBACK, this
523 * parameter specifies the callback function or
524 * method. In other error modes this parameter
525 * is ignored.
526 *
527 * @param string $userinfo If you need to pass along for example debug
528 * information, this parameter is meant for that.
529 *
530 * @param string $error_class The returned error object will be
531 * instantiated from this class, if specified.
532 *
533 * @param bool $skipmsg If true, raiseError will only pass error codes,
534 * the error message parameter will be dropped.
535 *
536 * @return object a PEAR error object
537 * @see PEAR::setErrorHandling
538 * @since PHP 4.0.5
539 */
540 protected static function _raiseError(
541 $object,
542 $message = null,
543 $code = null,
544 $mode = null,
545 $options = null,
546 $userinfo = null,
547 $error_class = null,
548 $skipmsg = false
549 ) {
550 // The error is yet a PEAR error object
551 if (is_object($message)) {
552 $code = $message->getCode();
553 $userinfo = $message->getUserInfo();
554 $error_class = $message->getType();
555 $message->error_message_prefix = '';
556 $message = $message->getMessage();
557 }
558
559 if (
560 $object !== null &&
561 isset($object->_expected_errors) &&
562 count($object->_expected_errors) > 0 &&
563 count($exp = end($object->_expected_errors))
564 ) {
565 if ($exp[0] === "*" ||
566 (is_int(reset($exp)) && in_array($code, $exp)) ||
567 (is_string(reset($exp)) && in_array($message, $exp))
568 ) {
569 $mode = PEAR_ERROR_RETURN;
570 }
571 }
572
573 // No mode given, try global ones
574 if ($mode === null) {
575 // Class error handler
576 if ($object !== null && isset($object->_default_error_mode)) {
577 $mode = $object->_default_error_mode;
578 $options = $object->_default_error_options;
579 // Global error handler
580 } elseif (isset($GLOBALS['_PEAR_default_error_mode'])) {
581 $mode = $GLOBALS['_PEAR_default_error_mode'];
582 $options = $GLOBALS['_PEAR_default_error_options'];
583 }
584 }
585
586 if ($error_class !== null) {
587 $ec = $error_class;
588 } elseif ($object !== null && isset($object->_error_class)) {
589 $ec = $object->_error_class;
590 } else {
591 $ec = 'AcyMailing\Libraries\Pear\Error';
592 }
593
594 if ($skipmsg) {
595 $a = new $ec($code, $mode, $options, $userinfo);
596 } else {
597 $a = new $ec($message, $code, $mode, $options, $userinfo);
598 }
599
600 return $a;
601 }
602
603 /**
604 * Simpler form of raiseError with fewer options. In most cases
605 * message, code and userinfo are enough.
606 *
607 * @param mixed $message a text error message or a PEAR error object
608 *
609 * @param int $code a numeric error code (it is up to your class
610 * to define these if you want to use codes)
611 *
612 * @param string $userinfo If you need to pass along for example debug
613 * information, this parameter is meant for that.
614 *
615 * @return object a PEAR error object
616 * @see PEAR::raiseError
617 */
618 protected static function _throwError($object, $message = null, $code = null, $userinfo = null)
619 {
620 if ($object !== null) {
621 $a = $object->raiseError($message, $code, null, null, $userinfo);
622
623 return $a;
624 }
625
626 $a = PEAR::raiseError($message, $code, null, null, $userinfo);
627
628 return $a;
629 }
630
631 public static function staticPushErrorHandling($mode, $options = null)
632 {
633 $stack = &$GLOBALS['_PEAR_error_handler_stack'];
634 $def_mode = &$GLOBALS['_PEAR_default_error_mode'];
635 $def_options = &$GLOBALS['_PEAR_default_error_options'];
636 $stack[] = [$def_mode, $def_options];
637 switch ($mode) {
638 case PEAR_ERROR_EXCEPTION:
639 case PEAR_ERROR_RETURN:
640 case PEAR_ERROR_PRINT:
641 case PEAR_ERROR_TRIGGER:
642 case PEAR_ERROR_DIE:
643 case null:
644 $def_mode = $mode;
645 $def_options = $options;
646 break;
647
648 case PEAR_ERROR_CALLBACK:
649 $def_mode = $mode;
650 // class/object method callback
651 if (is_callable($options)) {
652 $def_options = $options;
653 } else {
654 trigger_error("invalid error callback", E_USER_WARNING);
655 }
656 break;
657
658 default:
659 trigger_error("invalid error mode", E_USER_WARNING);
660 break;
661 }
662 $stack[] = [$mode, $options];
663
664 return true;
665 }
666
667 public static function staticPopErrorHandling()
668 {
669 $stack = &$GLOBALS['_PEAR_error_handler_stack'];
670 $setmode = &$GLOBALS['_PEAR_default_error_mode'];
671 $setoptions = &$GLOBALS['_PEAR_default_error_options'];
672 array_pop($stack);
673 [$mode, $options] = $stack[sizeof($stack) - 1];
674 array_pop($stack);
675 switch ($mode) {
676 case PEAR_ERROR_EXCEPTION:
677 case PEAR_ERROR_RETURN:
678 case PEAR_ERROR_PRINT:
679 case PEAR_ERROR_TRIGGER:
680 case PEAR_ERROR_DIE:
681 case null:
682 $setmode = $mode;
683 $setoptions = $options;
684 break;
685
686 case PEAR_ERROR_CALLBACK:
687 $setmode = $mode;
688 // class/object method callback
689 if (is_callable($options)) {
690 $setoptions = $options;
691 } else {
692 trigger_error("invalid error callback", E_USER_WARNING);
693 }
694 break;
695
696 default:
697 trigger_error("invalid error mode", E_USER_WARNING);
698 break;
699 }
700
701 return true;
702 }
703
704 /**
705 * Push a new error handler on top of the error handler options stack. With this
706 * you can easily override the actual error handler for some code and restore
707 * it later with popErrorHandling.
708 *
709 * @param mixed $mode (same as setErrorHandling)
710 * @param mixed $options (same as setErrorHandling)
711 *
712 * @return bool Always true
713 *
714 * @see PEAR::setErrorHandling
715 */
716 protected static function _pushErrorHandling($object, $mode, $options = null)
717 {
718 $stack = &$GLOBALS['_PEAR_error_handler_stack'];
719 if ($object !== null) {
720 $def_mode = &$object->_default_error_mode;
721 $def_options = &$object->_default_error_options;
722 } else {
723 $def_mode = &$GLOBALS['_PEAR_default_error_mode'];
724 $def_options = &$GLOBALS['_PEAR_default_error_options'];
725 }
726 $stack[] = [$def_mode, $def_options];
727
728 if ($object !== null) {
729 $object->setErrorHandling($mode, $options);
730 } else {
731 PEAR::setErrorHandling($mode, $options);
732 }
733 $stack[] = [$mode, $options];
734
735 return true;
736 }
737
738 /**
739 * Pop the last error handler used
740 *
741 * @return bool Always true
742 *
743 * @see PEAR::pushErrorHandling
744 */
745 protected static function _popErrorHandling($object)
746 {
747 $stack = &$GLOBALS['_PEAR_error_handler_stack'];
748 array_pop($stack);
749 [$mode, $options] = $stack[sizeof($stack) - 1];
750 array_pop($stack);
751 if ($object !== null) {
752 $object->setErrorHandling($mode, $options);
753 } else {
754 PEAR::setErrorHandling($mode, $options);
755 }
756
757 return true;
758 }
759
760 /**
761 * OS independent PHP extension load. Remember to take care
762 * on the correct extension name for case sensitive OSes.
763 *
764 * @param string $ext The extension name
765 *
766 * @return bool Success or not on the dl() call
767 */
768 public static function loadExtension($ext)
769 {
770 if (extension_loaded($ext)) {
771 return true;
772 }
773
774 // if either returns true dl() will produce a FATAL error, stop that
775 if (
776 function_exists('dl') === false ||
777 ini_get('enable_dl') != 1
778 ) {
779 return false;
780 }
781
782 if (OS_WINDOWS) {
783 $suffix = '.dll';
784 } elseif (PHP_OS == 'HP-UX') {
785 $suffix = '.sl';
786 } elseif (PHP_OS == 'AIX') {
787 $suffix = '.a';
788 } elseif (PHP_OS == 'OSX') {
789 $suffix = '.bundle';
790 } else {
791 $suffix = '.so';
792 }
793
794 return @dl('php_'.$ext.$suffix) || @dl($ext.$suffix);
795 }
796
797 /**
798 * Get SOURCE_DATE_EPOCH environment variable
799 * See https://reproducible-builds.org/specs/source-date-epoch/
800 *
801 * @return int
802 * @access public
803 */
804 static function getSourceDateEpoch()
805 {
806 if ($source_date_epoch = getenv('SOURCE_DATE_EPOCH')) {
807 if (preg_match('/^\d+$/', $source_date_epoch)) {
808 return (int)$source_date_epoch;
809 } else {
810 // "If the value is malformed, the build process SHOULD exit with a non-zero error code."
811 self::raiseError("Invalid SOURCE_DATE_EPOCH: $source_date_epoch");
812 exit(1);
813 }
814 } else {
815 return time();
816 }
817 }
818 }
819
820 function _PEAR_call_destructors()
821 {
822 global $_PEAR_destructor_object_list;
823 if (is_array($_PEAR_destructor_object_list) &&
824 sizeof($_PEAR_destructor_object_list)) {
825 reset($_PEAR_destructor_object_list);
826
827 $destructLifoExists = PEAR::getStaticProperty('PEAR', 'destructlifo');
828
829 if ($destructLifoExists) {
830 $_PEAR_destructor_object_list = array_reverse($_PEAR_destructor_object_list);
831 }
832
833 foreach ($_PEAR_destructor_object_list as $k => $objref) {
834 $classname = get_class($objref);
835 while ($classname) {
836 $destructor = "_$classname";
837 if (method_exists($objref, $destructor)) {
838 $objref->$destructor();
839 break;
840 } else {
841 $classname = get_parent_class($classname);
842 }
843 }
844 }
845 // Empty the object list to ensure that destructors are
846 // not called more than once.
847 $_PEAR_destructor_object_list = [];
848 }
849
850 // Now call the shutdown functions
851 if (
852 isset($GLOBALS['_PEAR_shutdown_funcs']) &&
853 is_array($GLOBALS['_PEAR_shutdown_funcs']) &&
854 !empty($GLOBALS['_PEAR_shutdown_funcs'])
855 ) {
856 foreach ($GLOBALS['_PEAR_shutdown_funcs'] as $value) {
857 call_user_func_array($value[0], $value[1]);
858 }
859 }
860 }
861
862
863 /*
864 * Local Variables:
865 * mode: php
866 * tab-width: 4
867 * c-basic-offset: 4
868 * End:
869 */
870