Source of file ClassProxyTrait.php
Size: 7,773 Bytes - Last Modified: 2021-01-12T22:04:13+00:00
C:/Users/MAKS/Code/_PROJECTS/amqp-agent/src/Helper/ClassProxyTrait.php
12345678910111213141516171819202122232425262728293031323334353637
Covered by 5 test(s):
38
Covered by 5 test(s):
394041
Covered by 5 test(s):
4243
Covered by 5 test(s):
44
Covered by 5 test(s):
45464748
Covered by 3 test(s):
49
Covered by 3 test(s):
5051
Covered by 5 test(s):
52
Covered by 5 test(s):
53
Covered by 5 test(s):
5455565758596061626364656667
Covered by 2 test(s):
68
Covered by 2 test(s):
6970
Covered by 2 test(s):
7172
Covered by 2 test(s):
73
Covered by 2 test(s):
74
Covered by 1 test(s):
75
Covered by 2 test(s):
76
Covered by 1 test(s):
77
Covered by 2 test(s):
78
Covered by 2 test(s):
7980
Covered by 1 test(s):
81
Covered by 1 test(s):
82
Covered by 2 test(s):
8384858687
Covered by 1 test(s):
88
Covered by 1 test(s):
8990
Covered by 2 test(s):
91
Covered by 2 test(s):
92
Covered by 2 test(s):
93
Covered by 2 test(s):
949596979899100101102103104105106107108
Covered by 3 test(s):
109
Covered by 3 test(s):
110111
Covered by 3 test(s):
112113
Covered by 3 test(s):
114
Covered by 1 test(s):
115
Covered by 3 test(s):
116
Covered by 2 test(s):
117118
Covered by 2 test(s):
119
Covered by 2 test(s):
120
Covered by 3 test(s):
121122123124125
Covered by 2 test(s):
126
Covered by 2 test(s):
127128
Covered by 2 test(s):
129
Covered by 3 test(s):
130
Covered by 3 test(s):
131
Covered by 3 test(s):
132133134135136137138139140141142143144
Covered by 1 test(s):
145146147148149150151152153154
Covered by 2 test(s):
155156157158159160161162163164165166
Covered by 3 test(s):
167
Covered by 1 test(s):
168
Covered by 1 test(s):
169
Covered by 1 test(s):
170
Covered by 1 test(s):
171172173174175
Covered by 2 test(s):
176
Covered by 1 test(s):
177
Covered by 1 test(s):
178
Covered by 1 test(s):
179180181182183184185
Covered by 1 test(s):
186187
Covered by 1 test(s):
188
Covered by 1 test(s):
189190
Covered by 1 test(s):
191192
Covered by 1 test(s):
193
Covered by 1 test(s):
194
Covered by 1 test(s):
195
Covered by 1 test(s):
196197
Covered by 1 test(s):
198
Covered by 1 test(s):
199
Covered by 1 test(s):
200
Covered by 1 test(s):
201202203
Covered by 1 test(s):
204
Covered by 1 test(s):
205206207208209210211
Covered by 1 test(s):
212213214215216217
| <?php /** * @author Marwan Al-Soltany <MarwanAlsoltany@gmail.com> * @copyright Marwan Al-Soltany 2020 * For the full copyright and license information, please view * the LICENSE file that was distributed with this source code. */ declare(strict_types=1); namespace MAKS\AmqpAgent\Helper; use Closure; use Exception; use ReflectionClass; use ReflectionObject; use ReflectionException; use MAKS\AmqpAgent\Exception\AmqpAgentException; /** * A trait containing methods for proxy methods calling, properties manipulation, and class utilities. * @since 2.0.0 */ trait ClassProxyTrait { /** * Calls a private, protected, or public method on an object. * @param object $object Class instance. * @param string $method Method name. * @param mixed ...$arguments * @return mixed The function result, or false on error. * @throws AmqpAgentException On failure or if the called function threw an exception. */ public static function callMethod($object, string $method, ...$arguments) { return call_user_func( Closure::bind( function () use ($object, $method, $arguments) { try { return call_user_func_array( array( $object, $method ), $arguments ); } catch (Exception $error) { AmqpAgentException::rethrow($error, sprintf('%s::%s() failed!', static::class, __FUNCTION__), false); } }, null, $object ) ); } /** * Gets a private, protected, or public property (default, static, or constant) of an object. * @param object $object Class instance. * @param string $property Property name. * @return mixed The property value. * @throws AmqpAgentException On failure. */ public static function getProperty($object, string $property) { return call_user_func( Closure::bind( function () use ($object, $property) { $return = null; try { $class = get_class($object); if (defined($class . '::' . $property)) { $return = constant($class . '::' . $property); } elseif (isset($object::$$property)) { $return = $object::$$property; } elseif (isset($object->{$property})) { $return = $object->{$property}; } else { throw new Exception( sprintf( 'No default, static, or constant property with the name "%s" exists!', $property ) ); } } catch (Exception $error) { AmqpAgentException::rethrow($error, sprintf('%s::%s() failed!', static::class, __FUNCTION__), false); } return $return; }, null, $object ) ); } /** * Sets a private, protected, or public property (default or static) of an object. * @param object $object Class instance. * @param string $property Property name. * @param string $value Property value. * @return mixed The new property value. * @throws AmqpAgentException On failure. */ public static function setProperty($object, string $property, $value) { return call_user_func( Closure::bind( function () use ($object, $property, $value) { $return = null; try { if (isset($object::$$property)) { $return = $object::$$property = $value; } elseif (isset($object->{$property})) { $return = $object->{$property} = $value; } else { throw new Exception( sprintf( 'No default or static property with the name "%s" exists!', $property ) ); } } catch (Exception $error) { AmqpAgentException::rethrow($error, sprintf('%s::%s() failed!', static::class, __FUNCTION__), false); } return $return; }, null, $object ) ); } /** * Returns a reflection class instance on a class. * @param object|string $class Class instance or class FQN. * @return ReflectionClass * @throws ReflectionException */ public static function reflectOnClass($class) { return new ReflectionClass($class); } /** * Returns a reflection object instance on an object. * @param object $object Class instance. * @return ReflectionObject */ public static function reflectOnObject($object) { return new ReflectionObject($object); } /** * Tries to cast an object into a new class. Similar classes work best. * @param object $fromObject Class instance. * @param string $toClass Class FQN. * @return object * @throws AmqpAgentException When passing a wrong argument or on failure. */ public static function castObjectToClass($fromObject, string $toClass) { if (!is_object($fromObject)) { throw new AmqpAgentException( sprintf( 'The first parameter must be an instance of class, a wrong parameter with (data-type: %s) was passed instead.', gettype($fromObject) ) ); } if (!class_exists($toClass)) { throw new AmqpAgentException( sprintf( 'Unknown class: %s.', $toClass ) ); } try { $toClass = new $toClass(); $toClassReflection = self::reflectOnObject($toClass); $fromObjectReflection = self::reflectOnObject($fromObject); $fromObjectProperties = $fromObjectReflection->getProperties(); foreach ($fromObjectProperties as $fromObjectProperty) { $fromObjectProperty->setAccessible(true); $name = $fromObjectProperty->getName(); $value = $fromObjectProperty->getValue($fromObject); if ($toClassReflection->hasProperty($name)) { $property = $toClassReflection->getProperty($name); $property->setAccessible(true); $property->setValue($toClass, $value); } else { try { self::setProperty($toClass, $name, $value); } catch (Exception $e) { // This exception means target object has a __set() // magic method that prevents setting the property. } } } return $toClass; } catch (Exception $error) { AmqpAgentException::rethrow($error, sprintf('%s::%s() failed!', static::class, __FUNCTION__), false); } } } |