Chris@0
|
1 <?php
|
Chris@0
|
2 /*
|
Chris@0
|
3 * This file is part of the PHPUnit_MockObject package.
|
Chris@0
|
4 *
|
Chris@0
|
5 * (c) Sebastian Bergmann <sebastian@phpunit.de>
|
Chris@0
|
6 *
|
Chris@0
|
7 * For the full copyright and license information, please view the LICENSE
|
Chris@0
|
8 * file that was distributed with this source code.
|
Chris@0
|
9 */
|
Chris@0
|
10
|
Chris@0
|
11 use SebastianBergmann\Exporter\Exporter;
|
Chris@0
|
12
|
Chris@0
|
13 /**
|
Chris@0
|
14 * Represents a static invocation.
|
Chris@0
|
15 *
|
Chris@0
|
16 * @since Class available since Release 1.0.0
|
Chris@0
|
17 */
|
Chris@0
|
18 class PHPUnit_Framework_MockObject_Invocation_Static implements PHPUnit_Framework_MockObject_Invocation, PHPUnit_Framework_SelfDescribing
|
Chris@0
|
19 {
|
Chris@0
|
20 /**
|
Chris@0
|
21 * @var array
|
Chris@0
|
22 */
|
Chris@0
|
23 protected static $uncloneableExtensions = array(
|
Chris@0
|
24 'mysqli' => true,
|
Chris@0
|
25 'SQLite' => true,
|
Chris@0
|
26 'sqlite3' => true,
|
Chris@0
|
27 'tidy' => true,
|
Chris@0
|
28 'xmlwriter' => true,
|
Chris@0
|
29 'xsl' => true
|
Chris@0
|
30 );
|
Chris@0
|
31
|
Chris@0
|
32 /**
|
Chris@0
|
33 * @var array
|
Chris@0
|
34 */
|
Chris@0
|
35 protected static $uncloneableClasses = array(
|
Chris@0
|
36 'Closure',
|
Chris@0
|
37 'COMPersistHelper',
|
Chris@0
|
38 'IteratorIterator',
|
Chris@0
|
39 'RecursiveIteratorIterator',
|
Chris@0
|
40 'SplFileObject',
|
Chris@0
|
41 'PDORow',
|
Chris@0
|
42 'ZipArchive'
|
Chris@0
|
43 );
|
Chris@0
|
44
|
Chris@0
|
45 /**
|
Chris@0
|
46 * @var string
|
Chris@0
|
47 */
|
Chris@0
|
48 public $className;
|
Chris@0
|
49
|
Chris@0
|
50 /**
|
Chris@0
|
51 * @var string
|
Chris@0
|
52 */
|
Chris@0
|
53 public $methodName;
|
Chris@0
|
54
|
Chris@0
|
55 /**
|
Chris@0
|
56 * @var array
|
Chris@0
|
57 */
|
Chris@0
|
58 public $parameters;
|
Chris@0
|
59
|
Chris@0
|
60 /**
|
Chris@0
|
61 * @param string $className
|
Chris@0
|
62 * @param string $methodname
|
Chris@0
|
63 * @param array $parameters
|
Chris@0
|
64 * @param bool $cloneObjects
|
Chris@0
|
65 */
|
Chris@0
|
66 public function __construct($className, $methodName, array $parameters, $cloneObjects = false)
|
Chris@0
|
67 {
|
Chris@0
|
68 $this->className = $className;
|
Chris@0
|
69 $this->methodName = $methodName;
|
Chris@0
|
70 $this->parameters = $parameters;
|
Chris@0
|
71
|
Chris@0
|
72 if (!$cloneObjects) {
|
Chris@0
|
73 return;
|
Chris@0
|
74 }
|
Chris@0
|
75
|
Chris@0
|
76 foreach ($this->parameters as $key => $value) {
|
Chris@0
|
77 if (is_object($value)) {
|
Chris@0
|
78 $this->parameters[$key] = $this->cloneObject($value);
|
Chris@0
|
79 }
|
Chris@0
|
80 }
|
Chris@0
|
81 }
|
Chris@0
|
82
|
Chris@0
|
83 /**
|
Chris@0
|
84 * @return string
|
Chris@0
|
85 */
|
Chris@0
|
86 public function toString()
|
Chris@0
|
87 {
|
Chris@0
|
88 $exporter = new Exporter;
|
Chris@0
|
89
|
Chris@0
|
90 return sprintf(
|
Chris@0
|
91 '%s::%s(%s)',
|
Chris@0
|
92 $this->className,
|
Chris@0
|
93 $this->methodName,
|
Chris@0
|
94 implode(
|
Chris@0
|
95 ', ',
|
Chris@0
|
96 array_map(
|
Chris@0
|
97 array($exporter, 'shortenedExport'),
|
Chris@0
|
98 $this->parameters
|
Chris@0
|
99 )
|
Chris@0
|
100 )
|
Chris@0
|
101 );
|
Chris@0
|
102 }
|
Chris@0
|
103
|
Chris@0
|
104 /**
|
Chris@0
|
105 * @param object $original
|
Chris@0
|
106 * @return object
|
Chris@0
|
107 */
|
Chris@0
|
108 protected function cloneObject($original)
|
Chris@0
|
109 {
|
Chris@0
|
110 $cloneable = null;
|
Chris@0
|
111 $object = new ReflectionObject($original);
|
Chris@0
|
112
|
Chris@0
|
113 // Check the blacklist before asking PHP reflection to work around
|
Chris@0
|
114 // https://bugs.php.net/bug.php?id=53967
|
Chris@0
|
115 if ($object->isInternal() &&
|
Chris@0
|
116 isset(self::$uncloneableExtensions[$object->getExtensionName()])) {
|
Chris@0
|
117 $cloneable = false;
|
Chris@0
|
118 }
|
Chris@0
|
119
|
Chris@0
|
120 if ($cloneable === null) {
|
Chris@0
|
121 foreach (self::$uncloneableClasses as $class) {
|
Chris@0
|
122 if ($original instanceof $class) {
|
Chris@0
|
123 $cloneable = false;
|
Chris@0
|
124 break;
|
Chris@0
|
125 }
|
Chris@0
|
126 }
|
Chris@0
|
127 }
|
Chris@0
|
128
|
Chris@0
|
129 if ($cloneable === null && method_exists($object, 'isCloneable')) {
|
Chris@0
|
130 $cloneable = $object->isCloneable();
|
Chris@0
|
131 }
|
Chris@0
|
132
|
Chris@0
|
133 if ($cloneable === null && $object->hasMethod('__clone')) {
|
Chris@0
|
134 $method = $object->getMethod('__clone');
|
Chris@0
|
135 $cloneable = $method->isPublic();
|
Chris@0
|
136 }
|
Chris@0
|
137
|
Chris@0
|
138 if ($cloneable === null) {
|
Chris@0
|
139 $cloneable = true;
|
Chris@0
|
140 }
|
Chris@0
|
141
|
Chris@0
|
142 if ($cloneable) {
|
Chris@0
|
143 try {
|
Chris@0
|
144 return clone $original;
|
Chris@0
|
145 } catch (Exception $e) {
|
Chris@0
|
146 return $original;
|
Chris@0
|
147 }
|
Chris@0
|
148 } else {
|
Chris@0
|
149 return $original;
|
Chris@0
|
150 }
|
Chris@0
|
151 }
|
Chris@0
|
152 }
|