ion/src/Friend.php

153 lines
2.9 KiB
PHP
Raw Normal View History

2016-10-13 13:11:22 -04:00
<?php declare(strict_types=1);
/**
* Ion
*
* Building blocks for web development
*
2018-01-17 12:45:58 -05:00
* PHP version 7.1
*
* @package Ion
* @author Timothy J. Warren <tim@timshomepage.net>
2018-01-17 12:45:58 -05:00
* @copyright 2015 - 2018 Timothy J. Warren
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version 2.3.0
* @link https://git.timshomepage.net/timw4mail/ion
*/
namespace Aviat\Ion;
use BadMethodCallException;
use InvalidArgumentException;
use ReflectionClass;
use ReflectionMethod;
use ReflectionProperty;
/**
* Friend class for testing
*/
class Friend {
/**
* Object to create a friend of
2018-01-17 12:43:44 -05:00
* @var mixed
*/
private $_friend_;
/**
* Reflection class of the object
2018-01-17 12:43:44 -05:00
* @var \ReflectionClass
*/
private $_reflect_;
/**
* Create a friend object
*
2018-01-17 12:43:44 -05:00
* @param mixed $obj
* @throws InvalidArgumentException
*/
public function __construct($obj)
{
2018-01-17 12:43:44 -05:00
if ( ! \is_object($obj))
{
2018-01-17 12:43:44 -05:00
throw new InvalidArgumentException('Friend must be an object');
}
$this->_friend_ = $obj;
$this->_reflect_ = new ReflectionClass($obj);
}
/**
* Retrieve a friend's property
*
* @param string $key
* @return mixed
*/
public function __get(string $key)
{
2018-01-17 12:43:44 -05:00
if ($this->__isset($key))
{
$property = $this->_get_property($key);
2018-01-17 12:43:44 -05:00
if ($property !== NULL)
{
return $property->getValue($this->_friend_);
}
}
return NULL;
}
2018-01-17 12:43:44 -05:00
/**
* See if a property exists on the friend
*
* @param string $name
* @return bool
*/
public function __isset(string $name): bool
{
return $this->_reflect_->hasProperty($name);
}
/**
* Set a friend's property
*
* @param string $key
2016-08-26 17:21:50 -04:00
* @param mixed $value
* @return void
*/
public function __set(string $key, $value)
{
2018-01-17 12:43:44 -05:00
if ($this->__isset($key))
{
$property = $this->_get_property($key);
2018-01-17 12:43:44 -05:00
if ($property !== NULL)
{
$property->setValue($this->_friend_, $value);
}
}
}
/**
* Calls a protected or private method on the friend
*
* @param string $method
2016-08-26 17:21:50 -04:00
* @param array $args
* @return mixed
* @throws BadMethodCallException
*/
public function __call(string $method, array $args)
{
if ( ! $this->_reflect_->hasMethod($method))
{
throw new BadMethodCallException("Method '{$method}' does not exist");
}
$friendMethod = new ReflectionMethod($this->_friend_, $method);
$friendMethod->setAccessible(TRUE);
return $friendMethod->invokeArgs($this->_friend_, $args);
}
/**
* Iterates over parent classes to get a ReflectionProperty
*
* @param string $name
* @return ReflectionProperty|null
*/
2018-01-17 12:43:44 -05:00
private function _get_property(string $name): ?ReflectionProperty
{
try
{
$property = $this->_reflect_->getProperty($name);
$property->setAccessible(TRUE);
return $property;
}
// Return NULL on any exception, so no further logic needed
// in the catch block
catch (\Exception $e)
{
return NULL;
}
}
}
// End of Friend.php