Overview

Namespaces

  • Autarky
    • Config
      • Loaders
    • Console
    • Container
      • Exception
      • Factory
      • Proxy
    • Database
    • Errors
    • Events
    • Files
    • Http
    • Logging
    • Providers
    • Routing
      • Events
    • Testing
    • TwigTemplating
      • Extensions
    • Utils

Classes

  • Autarky\Application
  • Autarky\Config\ConfigProvider
  • Autarky\Config\FileStore
  • Autarky\Config\LoaderFactory
  • Autarky\Config\Loaders\CachingYamlFileLoader
  • Autarky\Config\Loaders\PhpFileLoader
  • Autarky\Config\Loaders\YamlFileLoader
  • Autarky\Console\Application
  • Autarky\Console\Command
  • Autarky\Console\RouteDispatchCommand
  • Autarky\Console\RouteListCommand
  • Autarky\Container\Container
  • Autarky\Container\ContainerProvider
  • Autarky\Container\Factory\AbstractArgument
  • Autarky\Container\Factory\ClassArgument
  • Autarky\Container\Factory\Definition
  • Autarky\Container\Factory\Factory
  • Autarky\Container\Factory\ScalarArgument
  • Autarky\Container\Proxy\AbstractProxy
  • Autarky\Container\Proxy\ProxyProvider
  • Autarky\Database\ConnectionManager
  • Autarky\Database\DatabaseProvider
  • Autarky\Errors\ErrorHandlerManager
  • Autarky\Errors\ErrorHandlerProvider
  • Autarky\Errors\StubErrorHandler
  • Autarky\Events\EventDispatcher
  • Autarky\Events\EventDispatcherProvider
  • Autarky\Files\LockingFilesystem
  • Autarky\Files\PathResolver
  • Autarky\Http\CookieMiddleware
  • Autarky\Http\CookieProvider
  • Autarky\Http\CookieQueue
  • Autarky\Http\SessionMiddleware
  • Autarky\Http\SessionProvider
  • Autarky\Logging\ChannelManager
  • Autarky\Logging\DefaultLogConfigurator
  • Autarky\Logging\LoggingErrorHandler
  • Autarky\Logging\LoggingProvider
  • Autarky\Provider
  • Autarky\Providers\AbstractDependantProvider
  • Autarky\Providers\AbstractProvider
  • Autarky\Routing\Configuration
  • Autarky\Routing\Controller
  • Autarky\Routing\DefaultRouteConfigurator
  • Autarky\Routing\Events\AbstractRouteEvent
  • Autarky\Routing\Events\AfterEvent
  • Autarky\Routing\Events\BeforeEvent
  • Autarky\Routing\Events\RouteMatchedEvent
  • Autarky\Routing\Route
  • Autarky\Routing\RoutePathGenerator
  • Autarky\Routing\Router
  • Autarky\Routing\RoutingProvider
  • Autarky\Routing\UrlGenerator
  • Autarky\Testing\TestCase
  • Autarky\Testing\WebTestCase
  • Autarky\TwigTemplating\Extensions\PartialExtension
  • Autarky\TwigTemplating\Extensions\SessionExtension
  • Autarky\TwigTemplating\Extensions\UrlGenerationExtension
  • Autarky\TwigTemplating\Template
  • Autarky\TwigTemplating\TemplateContext
  • Autarky\TwigTemplating\TemplateEvent
  • Autarky\TwigTemplating\TemplatingEngine
  • Autarky\TwigTemplating\TwigEnvironment
  • Autarky\TwigTemplating\TwigTemplate
  • Autarky\TwigTemplating\TwigTemplatingProvider
  • Autarky\Utils\ArrayUtil

Interfaces

  • Autarky\Config\ConfigInterface
  • Autarky\Config\LoaderInterface
  • Autarky\ConfiguratorInterface
  • Autarky\Container\CallableInvokerInterface
  • Autarky\Container\ClassResolverInterface
  • Autarky\Container\ContainerAwareInterface
  • Autarky\Container\ContainerInterface
  • Autarky\Container\Factory\ArgumentInterface
  • Autarky\Container\Factory\FactoryInterface
  • Autarky\Database\ConnectionFactoryInterface
  • Autarky\Errors\ErrorHandlerInterface
  • Autarky\Errors\ErrorHandlerManagerInterface
  • Autarky\Events\EventDispatcherAwareInterface
  • Autarky\Providers\ConsoleProviderInterface
  • Autarky\Providers\DependantProviderInterface
  • Autarky\Providers\ProviderInterface
  • Autarky\Routing\InvokerInterface
  • Autarky\Routing\RoutePathGeneratorInterface
  • Autarky\Routing\RouterInterface

Traits

  • Autarky\Container\ContainerAwareTrait
  • Autarky\Events\EventDispatcherAwareTrait
  • Autarky\Routing\ControllerTrait

Exceptions

  • Autarky\Config\LoadException
  • Autarky\Container\Exception\ContainerException
  • Autarky\Container\Exception\NotInstantiableException
  • Autarky\Container\Exception\ResolvingException
  • Autarky\Container\Exception\ResolvingInternalException
  • Autarky\Container\Exception\UnresolvableArgumentException
  • Autarky\Database\CannotConnectException
  • Autarky\Files\IOException
  • Autarky\Providers\ProviderException
  • Overview
  • Namespace
  • Class
  1: <?php
  2: /**
  3:  * This file is part of the Autarky package.
  4:  *
  5:  * (c) Andreas Lutro <anlutro@gmail.com>
  6:  *
  7:  * For the full copyright and license information, please view the LICENSE
  8:  * file that was distributed with this source code.
  9:  */
 10: 
 11: namespace Autarky\Container\Factory;
 12: 
 13: use Autarky\Container\ContainerInterface;
 14: use Autarky\Container\Exception\NotInstantiableException;
 15: use Autarky\Container\Exception\UnresolvableArgumentException;
 16: use Closure;
 17: use ReflectionClass;
 18: use ReflectionException;
 19: use ReflectionFunction;
 20: use ReflectionFunctionAbstract;
 21: use ReflectionMethod;
 22: 
 23: /**
 24:  * Factory definition.
 25:  */
 26: class Definition implements FactoryInterface
 27: {
 28:     /**
 29:      * The callable function/method.
 30:      *
 31:      * @var callable
 32:      */
 33:     protected $callable;
 34: 
 35:     /**
 36:      * The name of the definition.
 37:      *
 38:      * @var string|null
 39:      */
 40:     protected $name;
 41: 
 42:     /**
 43:      * Map of argument position => argument
 44:      *
 45:      * @var array
 46:      */
 47:     protected $argumentPositions = [];
 48: 
 49:     /**
 50:      * Map of argument name => argument
 51:      *
 52:      * @var array
 53:      */
 54:     protected $argumentNames = [];
 55: 
 56:     /**
 57:      * Map of argument class => argument
 58:      *
 59:      * @var array
 60:      */
 61:     protected $argumentClasses = [];
 62: 
 63:     /**
 64:      * The current argument postition.
 65:      *
 66:      * @var integer
 67:      */
 68:     protected $argumentPosition = 0;
 69: 
 70:     /**
 71:      * Constructor.
 72:      *
 73:      * @param callable $callable
 74:      */
 75:     public function __construct($callable, $name = null)
 76:     {
 77:         $this->callable = $callable;
 78:         $this->name = $name;
 79:     }
 80: 
 81:     /**
 82:      * Get a default factory for a class.
 83:      *
 84:      * @param  string $class
 85:      * @param  array  $params Optional
 86:      *
 87:      * @return FactoryInterface
 88:      */
 89:     public static function getDefaultForClass($class, array $params = array())
 90:     {
 91:         $reflectionClass = new ReflectionClass($class);
 92: 
 93:         if (!$reflectionClass->isInstantiable()) {
 94:             throw new NotInstantiableException("Class $class is not instantiable");
 95:         }
 96: 
 97:         $factory = new static([$reflectionClass, 'newInstance'], "$class::__construct");
 98: 
 99:         if ($reflectionClass->hasMethod('__construct')) {
100:             static::addReflectionArguments($factory, $reflectionClass->getMethod('__construct'));
101:         }
102: 
103:         return $factory->getFactory($params);
104:     }
105: 
106:     /**
107:      * Get a default factory for a callable.
108:      *
109:      * @param  callable $callable
110:      * @param  array    $params   Optional
111:      *
112:      * @return FactoryInterface
113:      */
114:     public static function getDefaultForCallable($callable, array $params = array())
115:     {
116:         if ($callable instanceof Closure) {
117:             $factory = new static($callable, 'closure');
118:             $factory->addOptionalClassArgument('$container', 'Autarky\Container\ContainerInterface');
119:             return $factory->getFactory($params);
120:         }
121: 
122:         return static::getFromReflection($callable, null)
123:             ->getFactory($params);
124:     }
125: 
126:     /**
127:      * Get a new factory definition instance via reflection.
128:      *
129:      * @param  callable                   $callable
130:      * @param  ReflectionFunctionAbstract $reflectionFunction
131:      *
132:      * @return static
133:      */
134:     public static function getFromReflection($callable, ReflectionFunctionAbstract $reflectionFunction = null)
135:     {
136:         $factory = new static($callable);
137: 
138:         static::addReflectionArguments($factory, $reflectionFunction);
139: 
140:         return $factory;
141:     }
142: 
143:     /**
144:      * Add arguments to an existing factory via reflection.
145:      *
146:      * @param Definition                      $factory
147:      * @param ReflectionFunctionAbstract|null $reflectionFunction Optional
148:      */
149:     protected static function addReflectionArguments(Definition $factory, ReflectionFunctionAbstract $reflectionFunction = null)
150:     {
151:         if (!$reflectionFunction) {
152:             $callable = $factory->getCallable();
153: 
154:             if (is_array($callable)) {
155:                 $reflectionFunction = new ReflectionMethod($callable[0], $callable[1]);
156:             } else {
157:                 $reflectionFunction = new ReflectionFunction($callable);
158:             }
159:         }
160: 
161:         foreach ($reflectionFunction->getParameters() as $arg) {
162:             try {
163:                 $name = $arg->getName();
164:                 $required = ! $arg->isOptional();
165:                 if ($argClass = $arg->getClass()) {
166:                     $factory->addClassArgument($name, $argClass->getName(), $required);
167:                 } else {
168:                     $default = ($required ? null : $arg->getDefaultValue());
169:                     $factory->addScalarArgument($name, null, $required, $default);
170:                 }
171:             } catch (ReflectionException $re) {
172:                 throw UnresolvableArgumentException::fromReflectionParam(
173:                     $arg, $reflectionFunction, $re);
174:             }
175:         }
176:     }
177: 
178:     /**
179:      * Get the factory's name.
180:      *
181:      * @return string|null
182:      */
183:     public function getName()
184:     {
185:         return $this->name;
186:     }
187: 
188:     /**
189:      * Get the factory callable.
190:      *
191:      * @return callable
192:      */
193:     public function getCallable()
194:     {
195:         return $this->callable;
196:     }
197: 
198:     /**
199:      * Get the factory definition's arguments, mapped by position.
200:      *
201:      * @return array
202:      */
203:     public function getArguments()
204:     {
205:         return $this->argumentPositions;
206:     }
207: 
208:     /**
209:      * Add a scalar argument to the factory definition.
210:      *
211:      * @param string  $name
212:      * @param string  $type     int, string, object, etc.
213:      * @param boolean $required
214:      * @param mixed   $default  Default value, if not required
215:      */
216:     public function addScalarArgument($name, $type, $required = true, $default = null)
217:     {
218:         return $this->addArgument(new ScalarArgument($this->argumentPosition++, $name, $type, $required, $default));
219:     }
220: 
221:     /**
222:      * Add an optional scalar argument to the factory definition.
223:      *
224:      * @param string  $name
225:      * @param string  $type    int, string, object, etc.
226:      * @param mixed   $default
227:      */
228:     public function addOptionalScalarArgument($name, $type, $default)
229:     {
230:         return $this->addArgument(new ScalarArgument($this->argumentPosition++, $name, $type, false, $default));
231:     }
232: 
233:     /**
234:      * Add a class argument to the factory definition.
235:      *
236:      * @param string  $name
237:      * @param string  $class
238:      * @param boolean $required Optional - defaults to true
239:      */
240:     public function addClassArgument($name, $class, $required = true)
241:     {
242:         return $this->addArgument(new ClassArgument($this->argumentPosition++, $name, $class, $required));
243:     }
244: 
245:     /**
246:      * Add an optional class argument to the factory definition.
247:      *
248:      * @param string  $name
249:      * @param string  $class
250:      */
251:     public function addOptionalClassArgument($name, $class)
252:     {
253:         return $this->addArgument(new ClassArgument($this->argumentPosition++, $name, $class, false));
254:     }
255: 
256:     /**
257:      * Add an argument to the factory definition.
258:      *
259:      * @param ArgumentInterface $argument
260:      */
261:     public function addArgument(ArgumentInterface $argument)
262:     {
263:         $this->argumentPositions[$argument->getPosition()] = $argument;
264:         $this->argumentNames[$argument->getName()] = $argument;
265:         if ($argument->isClass()) {
266:             $this->argumentClasses[$argument->getClass()] = $argument;
267:         }
268:         return $argument;
269:     }
270: 
271:     /**
272:      * Get the definition's factory.
273:      *
274:      * @param  array  $params
275:      *
276:      * @return Factory
277:      */
278:     public function getFactory(array $params = array())
279:     {
280:         return new Factory($this, $params);
281:     }
282: 
283:     /**
284:      * {@inheritdoc}
285:      */
286:     public function invoke(ContainerInterface $container, array $params = array())
287:     {
288:         return $this->getFactory($params)
289:             ->invoke($container);
290:     }
291: 
292:     /**
293:      * Proxy for the invoke method. Makes the factory definition class callable.
294:      *
295:      * @param  ContainerInterface $container
296:      * @param  array              $params
297:      *
298:      * @return mixed
299:      */
300:     public function __invoke(ContainerInterface $container, array $params = array())
301:     {
302:         return $this->invoke($container, $params);
303:     }
304: }
305: 
Autarky Framework API documentation generated by ApiGen