/** * Get all the complex data for the loader. * This return value will be cached and stored in the database * There is no file monitoring for this cache * * @param Loader $loader * @param int $type * * @return array */ public function prepareLoader(Loader $loader, $type) { $hooks = []; $folder = ExtensionManagementUtility::extPath($loader->getExtensionKey()) . 'Classes/Hooks/'; $files = FileUtility::getBaseFilesInDir($folder, 'php'); foreach ($files as $hookFile) { $hookClass = ClassNamingUtility::getFqnByPath($loader->getVendorName(), $loader->getExtensionKey(), 'Hooks/' . $hookFile); if (!$loader->isInstantiableClass($hookClass)) { continue; } $classReflection = ReflectionUtility::createReflectionClass($hookClass); // add class hook $tagConfiguration = ReflectionUtility::getTagConfiguration($classReflection, ['hook']); if (sizeof($tagConfiguration['hook'])) { $hooks[] = ['locations' => $tagConfiguration['hook'], 'configuration' => $hookClass]; } // add method hooks foreach ($classReflection->getMethods(MethodReflection::IS_PUBLIC) as $methodReflection) { /** @var $methodReflection \TYPO3\CMS\Extbase\Reflection\MethodReflection */ $tagConfiguration = ReflectionUtility::getTagConfiguration($methodReflection, ['hook']); if (sizeof($tagConfiguration['hook'])) { $hooks[] = ['locations' => $tagConfiguration['hook'], 'configuration' => $hookClass . '->' . $methodReflection->getName()]; } } } return $hooks; }
/** * Get all the complex data for the loader. * This return value will be cached and stored in the database * There is no file monitoring for this cache * * @param Loader $loader * @param int $type * * @return array */ public function prepareLoader(Loader $loader, $type) { $pluginInformation = []; $controllerPath = ExtensionManagementUtility::extPath($loader->getExtensionKey()) . 'Classes/Controller/'; $controllers = FileUtility::getBaseFilesRecursivelyInDir($controllerPath, 'php'); foreach ($controllers as $controller) { $controllerName = ClassNamingUtility::getFqnByPath($loader->getVendorName(), $loader->getExtensionKey(), 'Controller/' . $controller); if (!$loader->isInstantiableClass($controllerName)) { continue; } $controllerKey = str_replace('/', '\\', $controller); $controllerKey = str_replace('Controller', '', $controllerKey); $methods = ReflectionUtility::getPublicMethods($controllerName); foreach ($methods as $method) { /** @var $method \TYPO3\CMS\Extbase\Reflection\MethodReflection */ if ($method->isTaggedWith('plugin')) { $pluginKeys = GeneralUtility::trimExplode(' ', implode(' ', $method->getTagValues('plugin')), true); $actionName = str_replace('Action', '', $method->getName()); foreach ($pluginKeys as $pluginKey) { $pluginInformation = $this->addPluginInformation($pluginInformation, $pluginKey, $controllerKey, $actionName, $method->isTaggedWith('noCache')); } } } } return $pluginInformation; }
/** * Get all the complex data for the loader. * This return value will be cached and stored in the database * There is no file monitoring for this cache * * @param Loader $autoLoader * @param int $type * * @return array */ public function prepareLoader(Loader $autoLoader, $type) { $slots = []; $slotPath = ExtensionManagementUtility::extPath($autoLoader->getExtensionKey()) . 'Classes/Slots/'; $slotClasses = FileUtility::getBaseFilesInDir($slotPath, 'php'); $extKey = GeneralUtility::underscoredToUpperCamelCase($autoLoader->getExtensionKey()); foreach ($slotClasses as $slot) { $slotClass = $autoLoader->getVendorName() . '\\' . $extKey . '\\Slots\\' . $slot; if (!$autoLoader->isInstantiableClass($slotClass)) { continue; } $methods = ReflectionUtility::getPublicMethods($slotClass); foreach ($methods as $methodReflection) { /** @var MethodReflection $methodReflection */ $tagConfiguration = ReflectionUtility::getTagConfiguration($methodReflection, ['signalClass', 'signalName']); foreach ($tagConfiguration['signalClass'] as $key => $signalClass) { if (!isset($tagConfiguration['signalName'][$key])) { continue; } $slots[] = ['signalClassName' => trim($signalClass, '\\'), 'signalName' => $tagConfiguration['signalName'][$key], 'slotClassNameOrObject' => $slotClass, 'slotMethodName' => $methodReflection->getName()]; } } } return $slots; }
/** * Get all the complex data for the loader. * This return value will be cached and stored in the database * There is no file monitoring for this cache * * @param Loader $autoLoader * @param int $type * * @return array */ public function prepareLoader(Loader $autoLoader, $type) { $slots = []; $slotPath = ExtensionManagementUtility::extPath($autoLoader->getExtensionKey()) . 'Classes/Slots/'; $slotClasses = FileUtility::getBaseFilesInDir($slotPath, 'php'); foreach ($slotClasses as $slot) { $slotClass = ClassNamingUtility::getFqnByPath($autoLoader->getVendorName(), $autoLoader->getExtensionKey(), 'Slots/' . $slot); if (!$autoLoader->isInstantiableClass($slotClass)) { continue; } $methods = ReflectionUtility::getPublicMethods($slotClass); foreach ($methods as $methodReflection) { /** @var MethodReflection $methodReflection */ $tagConfiguration = ReflectionUtility::getTagConfiguration($methodReflection, ['signalClass', 'signalName', 'signalPriority']); foreach ($tagConfiguration['signalClass'] as $key => $signalClass) { if (!isset($tagConfiguration['signalName'][$key])) { continue; } $priority = isset($tagConfiguration['signalPriority'][$key]) ? $tagConfiguration['signalPriority'][$key] : 0; $priority = MathUtility::forceIntegerInRange($priority, 0, 100); $slots[$priority][] = ['signalClassName' => trim($signalClass, '\\'), 'signalName' => $tagConfiguration['signalName'][$key], 'slotClassNameOrObject' => $slotClass, 'slotMethodName' => $methodReflection->getName()]; } } } $slots = $this->flattenSlotsByPriority($slots); return $slots; }
/** * Get the Arguments from the original method via Reflection. * If the $aspectClassName not available (e.g. Extension is not installed) then * throw a Exception. * * @param $aspectClassName * @param $aspectJoinPoint * * @return array * @throws \HDNET\Autoloader\Exception */ protected function getMethodArgumentsFromClassMethod($aspectClassName, $aspectJoinPoint) { $reflectionClass = ReflectionUtility::createReflectionClass($aspectClassName); $methodReflection = $reflectionClass->getMethod($aspectJoinPoint); /** @var $classReflection \TYPO3\CMS\Extbase\Reflection\ClassReflection */ $methodArguments = $methodReflection->getParameters(); $arguments = []; /** @var $argument \ReflectionParameter */ foreach ($methodArguments as $argument) { $arguments[] = ['name' => $argument->getName(), 'typeHint' => $argument->getClass()->name, 'reference' => $argument->isPassedByReference()]; } return $arguments; }
/** * Get all the complex data for the loader. * This return value will be cached and stored in the database * There is no file monitoring for this cache * * @param Loader $loader * @param int $type * * @return array */ public function prepareLoader(Loader $loader, $type) { $classNames = []; $alternativeImpPath = ExtensionManagementUtility::extPath($loader->getExtensionKey()) . 'Classes/AlternativeImplementations/'; $alternativeClasses = FileUtility::getBaseFilesInDir($alternativeImpPath, 'php'); foreach ($alternativeClasses as $aic) { $aicClass = ClassNamingUtility::getFqnByPath($loader->getVendorName(), $loader->getExtensionKey(), 'AlternativeImplementations/' . $aic); if (!$loader->isInstantiableClass($aicClass)) { continue; } $classNames[] = ['originalName' => ReflectionUtility::getParentClassName($aicClass), 'alternativeClassName' => $aicClass]; } return $classNames; }
/** * Get all the complex data for the loader. * This return value will be cached and stored in the database * There is no file monitoring for this cache * * @param Loader $loader * @param int $type * * @return array */ public function prepareLoader(Loader $loader, $type) { $classNames = []; $alternativeImpPath = ExtensionManagementUtility::extPath($loader->getExtensionKey()) . 'Classes/AlternativeImplementations/'; $alternativeClasses = FileUtility::getBaseFilesInDir($alternativeImpPath, 'php'); $extKey = GeneralUtility::underscoredToUpperCamelCase($loader->getExtensionKey()); foreach ($alternativeClasses as $aic) { $aicClass = $loader->getVendorName() . '\\' . $extKey . '\\AlternativeImplementations\\' . $aic; if (!$loader->isInstantiableClass($aicClass)) { continue; } $classNames[] = ['originalName' => ReflectionUtility::getParentClassName($aicClass), 'alternativeClassName' => $aicClass]; } return $classNames; }
/** * Check if the given class is a smart object * * Also add a work around, because the static_info_tables SPL Autoloader * get into a conflict with different classes. * * @param string $className * * @return bool */ public static function isSmartObjectClass($className) { $riskAutoLoader = ['SJBR\\StaticInfoTables\\Cache\\CachedClassLoader', 'autoload']; $registerAutoLoader = spl_autoload_unregister($riskAutoLoader); if (!class_exists($className)) { $return = false; } else { $classReflection = ReflectionUtility::createReflectionClass($className); $return = !(bool) (!$classReflection->isInstantiable() || !$classReflection->isTaggedWith('db')); } if ($registerAutoLoader) { spl_autoload_register($riskAutoLoader, true, true); } return $return; }
/** * Get all the complex data for the loader. * This return value will be cached and stored in the database * There is no file monitoring for this cache * * @param Loader $loader * @param int $type * * @return array */ public function prepareLoader(Loader $loader, $type) { $return = []; if ($type === LoaderInterface::EXT_TABLES) { return $return; } $xClassesPath = ExtensionManagementUtility::extPath($loader->getExtensionKey()) . 'Classes/Xclass/'; $xClasses = FileUtility::getBaseFilesRecursivelyInDir($xClassesPath, 'php'); foreach ($xClasses as $xClass) { $className = ClassNamingUtility::getFqnByPath($loader->getVendorName(), $loader->getExtensionKey(), 'Xclass/' . $xClass); if (!$loader->isInstantiableClass($className)) { continue; } $return[] = ['source' => ReflectionUtility::getParentClassName($className), 'target' => $className]; } return $return; }
/** * Get all the complex data for the loader. * This return value will be cached and stored in the database * There is no file monitoring for this cache * * @param Loader $loader * @param int $type * * @return array */ public function prepareLoader(Loader $loader, $type) { $return = []; if ($type === LoaderInterface::EXT_TABLES) { return $return; } $xClassesPath = ExtensionManagementUtility::extPath($loader->getExtensionKey()) . 'Classes/Xclass/'; $xClasses = FileUtility::getBaseFilesRecursivelyInDir($xClassesPath, 'php'); $extKey = GeneralUtility::underscoredToUpperCamelCase($loader->getExtensionKey()); foreach ($xClasses as $xClass) { $xclassName = $loader->getVendorName() . '\\' . $extKey . '\\Xclass\\' . str_replace('/', '\\', $xClass); if (!$loader->isInstantiableClass($xclassName)) { continue; } $return[] = ['source' => ReflectionUtility::getParentClassName($xclassName), 'target' => $xclassName]; } return $return; }
/** * Get custom database information for the given model * * @param string $modelClassName * * @return array */ protected function getCustomModelFields($modelClassName) { $properties = ReflectionUtility::getPropertiesTaggedWith($modelClassName, 'db'); $fields = []; foreach ($properties as $property) { /** @var \TYPO3\CMS\Extbase\Reflection\PropertyReflection $property */ $var = ''; if ($property->isTaggedWith('var')) { $var = $property->getTagValues('var'); $var = $var[0]; } $dbInformation = $property->getTagValues('db'); $fields[] = ['name' => GeneralUtility::camelCaseToLowerCaseUnderscored($property->getName()), 'db' => trim($dbInformation[0]), 'var' => trim($var), 'rte' => (bool) $property->isTaggedWith('enableRichText')]; } return $fields; }
/** * check if the class is loadable and is instantiable * (exists and is no interface or abstraction etc.) * * @param $class * * @return bool */ public function isInstantiableClass($class) { return ReflectionUtility::isInstantiable($class); }
/** * Same as getClassProperties, but the fields are in LowerCaseUnderscored * * @param $className * * @return array */ protected function getClassPropertiesInLowerCaseUnderscored($className) { return array_map(function ($value) { return GeneralUtility::camelCaseToLowerCaseUnderscored($value); }, ReflectionUtility::getDeclaringProperties($className)); }
/** * Generate the TypoScript setup for the smart objects defined * within the extension * * @param string $extensionKey * * @return array */ private function generateTypoScriptSetup($extensionKey) { $setup = []; foreach ($this->getSmartObjectsForExtensionKey($extensionKey) as $className) { $table = ModelUtility::getTableNameByModelReflectionAnnotation($className); $recordType = (string) ReflectionUtility::getFirstTagValue($className, 'recordType'); $parentClass = (string) ReflectionUtility::getFirstTagValue($className, 'parentClass'); if ($table !== '') { $setup[] = 'config.tx_extbase.persistence.classes.' . $className . '.mapping.tableName = ' . $table; } if ($recordType !== '') { $setup[] = 'config.tx_extbase.persistence.classes.' . $className . '.mapping.recordType = ' . $recordType; } if ($parentClass !== '') { $setup[] = 'config.tx_extbase.persistence.classes.' . $parentClass . '.subclasses.' . $className . ' = ' . $className; } } return $setup; }
/** * get the smart exclude values e.g. language, workspace, * enableFields from the given model * * @param string $name * * @return array */ public static function getSmartExcludesByModelName($name) { return GeneralUtility::trimExplode(',', (string) ReflectionUtility::getFirstTagValue($name, 'smartExclude'), true); }