1<?php 2 3/* 4 * This file is part of the Prophecy. 5 * (c) Konstantin Kudryashov <ever.zet@gmail.com> 6 * Marcello Duarte <marcello.duarte@gmail.com> 7 * 8 * For the full copyright and license information, please view the LICENSE 9 * file that was distributed with this source code. 10 */ 11 12namespace Prophecy\Promise; 13 14use Doctrine\Instantiator\Instantiator; 15use Prophecy\Prophecy\ObjectProphecy; 16use Prophecy\Prophecy\MethodProphecy; 17use Prophecy\Exception\InvalidArgumentException; 18use ReflectionClass; 19 20/** 21 * Throw promise. 22 * 23 * @author Konstantin Kudryashov <ever.zet@gmail.com> 24 */ 25class ThrowPromise implements PromiseInterface 26{ 27 private $exception; 28 29 /** 30 * @var \Doctrine\Instantiator\Instantiator 31 */ 32 private $instantiator; 33 34 /** 35 * Initializes promise. 36 * 37 * @param string|\Exception|\Throwable $exception Exception class name or instance 38 * 39 * @throws \Prophecy\Exception\InvalidArgumentException 40 */ 41 public function __construct($exception) 42 { 43 if (is_string($exception)) { 44 if (!class_exists($exception) || !$this->isAValidThrowable($exception)) { 45 throw new InvalidArgumentException(sprintf( 46 'Exception / Throwable class or instance expected as argument to ThrowPromise, but got %s.', 47 $exception 48 )); 49 } 50 } elseif (!$exception instanceof \Exception && !$exception instanceof \Throwable) { 51 throw new InvalidArgumentException(sprintf( 52 'Exception / Throwable class or instance expected as argument to ThrowPromise, but got %s.', 53 is_object($exception) ? get_class($exception) : gettype($exception) 54 )); 55 } 56 57 $this->exception = $exception; 58 } 59 60 /** 61 * Throws predefined exception. 62 * 63 * @param array $args 64 * @param ObjectProphecy $object 65 * @param MethodProphecy $method 66 * 67 * @throws object 68 */ 69 public function execute(array $args, ObjectProphecy $object, MethodProphecy $method) 70 { 71 if (is_string($this->exception)) { 72 $classname = $this->exception; 73 $reflection = new ReflectionClass($classname); 74 $constructor = $reflection->getConstructor(); 75 76 if ($constructor->isPublic() && 0 == $constructor->getNumberOfRequiredParameters()) { 77 throw $reflection->newInstance(); 78 } 79 80 if (!$this->instantiator) { 81 $this->instantiator = new Instantiator(); 82 } 83 84 throw $this->instantiator->instantiate($classname); 85 } 86 87 throw $this->exception; 88 } 89 90 /** 91 * @param string $exception 92 * 93 * @return bool 94 */ 95 private function isAValidThrowable($exception) 96 { 97 return is_a($exception, 'Exception', true) || is_subclass_of($exception, 'Throwable', true); 98 } 99} 100