/** * Create a module. * * @param string $moduleName * @param bool $active * @return \Codeception\Module * @throws \Codeception\Exception\ConfigurationException * @throws \Codeception\Exception\ModuleException * @throws \Codeception\Exception\ModuleRequireException * @throws \Codeception\Exception\InjectionException */ public function create($moduleName, $active = true) { $this->active[$moduleName] = $active; $moduleClass = $this->getModuleClass($moduleName); if (!class_exists($moduleClass)) { throw new ConfigurationException("Module {$moduleName} could not be found and loaded"); } $config = $this->getModuleConfig($moduleName); if (empty($config) && !$active) { // For modules that are a dependency of other modules we want to skip the validation of the config. // This config validation is performed in \Codeception\Module::__construct(). // Explicitly setting $config to null skips this validation. $config = null; } $this->modules[$moduleName] = $module = $this->di->instantiate($moduleClass, [$this, $config], false); if ($this->moduleHasDependencies($module)) { $this->injectModuleDependencies($moduleName, $module); } // If module is not active its actions should not be included in the actor class $actions = $active ? $this->getActionsForModule($module, $config) : []; foreach ($actions as $action) { $this->actions[$action] = $moduleName; } return $module; }
private function instantiate($name, $class, $config) { $module = $this->di->instantiate($class, [$this, $config], false); $this->modules[$name] = $module; if (!$this->active[$name]) { // if module is not active, its actions should not be included into actor class return $module; } if ($module instanceof DependsOnModule) { $this->injectDependentModule($name, $module); } $class = new \ReflectionClass($module); $methods = $class->getMethods(\ReflectionMethod::IS_PUBLIC); foreach ($methods as $method) { $inherit = $class->getStaticPropertyValue('includeInheritedActions'); $only = $class->getStaticPropertyValue('onlyActions'); $exclude = $class->getStaticPropertyValue('excludeActions'); // exclude methods when they are listed as excluded if (in_array($method->name, $exclude)) { continue; } if (!empty($only)) { // skip if method is not listed if (!in_array($method->name, $only)) { continue; } } else { // skip if method is inherited and inheritActions == false if (!$inherit && $method->getDeclaringClass() != $class) { continue; } } // those with underscore at the beginning are considered as hidden if (strpos($method->name, '_') === 0) { continue; } if ($module instanceof PartedModule && isset($config['part'])) { if (!$this->moduleActionBelongsToPart($module, $method->name, $config['part'])) { continue; } } $this->actions[$method->name] = $name; } return $module; }
/** * @param string $className * @param array $constructorArgs * @param string $injectMethodName Method which will be invoked after object creation; * Resolved dependencies will be passed to it as arguments * @throws InjectionException * @return null|object */ public function instantiate($className, $constructorArgs = null, $injectMethodName = self::DEFAULT_INJECT_METHOD_NAME) { // normalize namespace $className = ltrim($className, '\\'); // get class from container if (isset($this->container[$className])) { if ($this->container[$className] instanceof $className) { return $this->container[$className]; } else { throw new InjectionException("Failed to resolve cyclic dependencies for class '{$className}'"); } } // get class from parent container if ($this->fallback) { if ($class = $this->fallback->get($className)) { return $class; } } $this->container[$className] = false; // flag that object is being instantiated $reflectedClass = new \ReflectionClass($className); if (!$reflectedClass->isInstantiable()) { return null; } $reflectedConstructor = $reflectedClass->getConstructor(); if (is_null($reflectedConstructor)) { $object = new $className(); } else { try { if (!$constructorArgs) { $constructorArgs = $this->prepareArgs($reflectedConstructor); } } catch (\Exception $e) { throw new InjectionException("Failed to create instance of '{$className}'. " . $e->getMessage()); } $object = $reflectedClass->newInstanceArgs($constructorArgs); } if ($injectMethodName) { $this->injectDependencies($object, $injectMethodName); } $this->container[$className] = $object; return $object; }
/** * @param $t * @throws Exception\InjectionException */ protected function configureTest($t) { if (!$t instanceof TestCase\Interfaces\Configurable) { return; } $t->configDispatcher($this->dispatcher); $t->configActor($this->getActor()); $t->configEnv($this->env); $t->configModules($this->moduleContainer); $t->configDi($this->di); $t->initConfig(); $this->di->injectDependencies($t); }