/** * Renders additional code for the __construct() method of the Proxy Class which realizes constructor injection. * * @param Configuration $objectConfiguration * @return string The built code * @throws ObjectException\UnknownObjectException */ protected function buildConstructorInjectionCode(Configuration $objectConfiguration) { $assignments = []; $argumentConfigurations = $objectConfiguration->getArguments(); $constructorParameterInfo = $this->reflectionService->getMethodParameters($objectConfiguration->getClassName(), '__construct'); $argumentNumberToOptionalInfo = []; foreach ($constructorParameterInfo as $parameterInfo) { $argumentNumberToOptionalInfo[$parameterInfo['position'] + 1] = $parameterInfo['optional']; } $highestArgumentPositionWithAutowiringEnabled = -1; foreach ($argumentConfigurations as $argumentNumber => $argumentConfiguration) { if ($argumentConfiguration === null) { continue; } $argumentPosition = $argumentNumber - 1; if ($argumentConfiguration->getAutowiring() === Configuration::AUTOWIRING_MODE_ON) { $highestArgumentPositionWithAutowiringEnabled = $argumentPosition; } $argumentValue = $argumentConfiguration->getValue(); $assignmentPrologue = 'if (!array_key_exists(' . ($argumentNumber - 1) . ', $arguments)) $arguments[' . ($argumentNumber - 1) . '] = '; if ($argumentValue === null && isset($argumentNumberToOptionalInfo[$argumentNumber]) && $argumentNumberToOptionalInfo[$argumentNumber] === true) { $assignments[$argumentPosition] = $assignmentPrologue . 'NULL'; } else { switch ($argumentConfiguration->getType()) { case ConfigurationArgument::ARGUMENT_TYPES_OBJECT: if ($argumentValue instanceof Configuration) { $argumentValueObjectName = $argumentValue->getObjectName(); $argumentValueClassName = $argumentValue->getClassName(); if ($argumentValueClassName === null) { $preparedArgument = $this->buildCustomFactoryCall($argumentValue->getFactoryObjectName(), $argumentValue->getFactoryMethodName(), $argumentValue->getArguments()); $assignments[$argumentPosition] = $assignmentPrologue . $preparedArgument; } else { if ($this->objectConfigurations[$argumentValueObjectName]->getScope() === Configuration::SCOPE_PROTOTYPE) { $assignments[$argumentPosition] = $assignmentPrologue . 'new \\' . $argumentValueObjectName . '(' . $this->buildMethodParametersCode($argumentValue->getArguments()) . ')'; } else { $assignments[$argumentPosition] = $assignmentPrologue . '\\Neos\\Flow\\Core\\Bootstrap::$staticObjectManager->get(\'' . $argumentValueObjectName . '\')'; } } } else { if (strpos($argumentValue, '.') !== false) { $settingPath = explode('.', $argumentValue); $settings = Arrays::getValueByPath($this->configurationManager->getConfiguration(ConfigurationManager::CONFIGURATION_TYPE_SETTINGS), array_shift($settingPath)); $argumentValue = Arrays::getValueByPath($settings, $settingPath); } if (!isset($this->objectConfigurations[$argumentValue])) { throw new ObjectException\UnknownObjectException('The object "' . $argumentValue . '" which was specified as an argument in the object configuration of object "' . $objectConfiguration->getObjectName() . '" does not exist.', 1264669967); } $assignments[$argumentPosition] = $assignmentPrologue . '\\Neos\\Flow\\Core\\Bootstrap::$staticObjectManager->get(\'' . $argumentValue . '\')'; } break; case ConfigurationArgument::ARGUMENT_TYPES_STRAIGHTVALUE: $assignments[$argumentPosition] = $assignmentPrologue . var_export($argumentValue, true); break; case ConfigurationArgument::ARGUMENT_TYPES_SETTING: $assignments[$argumentPosition] = $assignmentPrologue . '\\Neos\\Flow\\Core\\Bootstrap::$staticObjectManager->getSettingsByPath(explode(\'.\', \'' . $argumentValue . '\'))'; break; } } } for ($argumentCounter = count($assignments) - 1; $argumentCounter > $highestArgumentPositionWithAutowiringEnabled; $argumentCounter--) { unset($assignments[$argumentCounter]); } $code = $argumentCounter >= 0 ? "\n " . implode(";\n ", $assignments) . ";\n" : ''; $index = 0; foreach ($constructorParameterInfo as $parameterName => $parameterInfo) { if ($parameterInfo['optional'] === true) { break; } if ($objectConfiguration->getScope() === Configuration::SCOPE_SINGLETON) { $code .= ' if (!array_key_exists(' . $index . ', $arguments)) throw new \\Neos\\Flow\\ObjectManagement\\Exception\\UnresolvedDependenciesException(\'Missing required constructor argument $' . $parameterName . ' in class \' . __CLASS__ . \'. Please check your calling code and Dependency Injection configuration.\', 1296143787);' . "\n"; } else { $code .= ' if (!array_key_exists(' . $index . ', $arguments)) throw new \\Neos\\Flow\\ObjectManagement\\Exception\\UnresolvedDependenciesException(\'Missing required constructor argument $' . $parameterName . ' in class \' . __CLASS__ . \'. Note that constructor injection is only support for objects of scope singleton (and this is not a singleton) – for other scopes you must pass each required argument to the constructor yourself.\', 1296143788);' . "\n"; } $index++; } return $code; }