/** * Provides a template method for enum values representing the index of the method. * This can be aliased in an enum class. * * @return Enum|null */ public static final function _() { $MethodName = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 1)[0]['function']; if ($MethodName === __FUNCTION__) { return null; } $CalledEnumClass = get_called_class(); if (!isset(self::$AliasedMethodOrdinalMap[$CalledEnumClass])) { self::$AliasedMethodOrdinalMap[$CalledEnumClass] = array(); $BaseConstant = $CalledEnumClass . '::' . 'Base'; $OrdinalBase = constant($BaseConstant) ?: 0; $Reflection = new \ReflectionClass($CalledEnumClass); $Aliases = $Reflection->getTraitAliases(); $Count = $OrdinalBase; foreach ($Aliases as $Alias => $OriginalName) { if ($OriginalName === __METHOD__) { self::$AliasedMethodOrdinalMap[$CalledEnumClass][$Count] = $Alias; $Count++; } } self::$AliasedMethodOrdinalMap[$CalledEnumClass] = array_flip(self::$AliasedMethodOrdinalMap[$CalledEnumClass]); } return self::Representing(self::$AliasedMethodOrdinalMap[$CalledEnumClass][$MethodName]); }
/** * Returns method aliases from traits. * * @return array */ public function getTraitAliases() { return NATIVE_TRAITS ? parent::getTraitAliases() : array(); }
<?php trait myTrait { public function run() { } } class myClass { use myTrait { MyTrait::run as private; } } $class = new \ReflectionClass('myClass'); var_dump($class->getTraitAliases());
} function m2() { } } class C1 { } class C2 { use T1; } class C3 { use T1 { m1 as a1; } } class C4 { use T1 { m1 as a1; m2 as a2; } } for ($c = "C1"; $c <= "C4"; $c++) { echo "class {$c}:\n"; $r = new ReflectionClass($c); var_dump($r->getTraitAliases()); echo "\n"; }
trait Trait1 { public function run() { } public function say() { } } trait Trait2 { public function run() { } public function say() { } } class MyClass { use Trait1, Trait2 { Trait1::run as execute; Trait1::say insteadof Trait2; Trait2::run insteadof Trait1; Trait2::say as talk; } } $ref = new ReflectionClass('MyClass'); print_r($ref->getTraitAliases()); print_r($ref->getTraits());
/** * Tests traits support comparing with the internal reflection. * * For PHP 5.4+ only. */ public function testTraits() { if (PHP_VERSION_ID < 50400) { $this->markTestSkipped('Requires PHP 5.4 or higher.'); } static $classes = array('TokenReflection_Test_ClassTraitsTrait1', 'TokenReflection_Test_ClassTraitsTrait2', 'TokenReflection_Test_ClassTraitsTrait3', 'TokenReflection_Test_ClassTraitsTrait4', 'TokenReflection_Test_ClassTraits', 'TokenReflection_Test_ClassTraits2', 'TokenReflection_Test_ClassTraits3', 'TokenReflection_Test_ClassTraits4'); require_once $this->getFilePath('traits'); $this->getBroker()->process($this->getFilePath('traits')); foreach ($classes as $className) { $token = $this->getBroker()->getClass($className); $internal = new \ReflectionClass($className); $this->assertSame($internal->isTrait(), $token->isTrait(), $className); $this->assertSame($internal->getTraitAliases(), $token->getTraitAliases(), $className); $this->assertSame($internal->getTraitNames(), $token->getTraitNames(), $className); $this->assertSame(count($internal->getTraits()), count($token->getTraits()), $className); foreach ($internal->getTraits() as $trait) { $this->assertTrue($token->usesTrait($trait->getName()), $className); } } }
/** * {@inheritdoc} */ public function getTraitAliases() { return $this->reflectionClass->getTraitAliases(); }
/** * @param array $properties * @param bool $checkAll * @throws \Exception * @throws \InvalidArgumentException * * @return void */ protected function magicSetProperties(array $properties, $checkAll = true) { static $meta = []; static $converters = []; static $validators = []; static $mutualConditions = []; $class = get_class($this); if (!isset($meta[$class])) { $meta[$class] = []; $converters[$class] = []; $validators[$class] = []; $validator = [$this, 'validateMutualCondition']; $fallback = [$this, 'fallbackMutualCondition']; $mutualConditions[$class]['validator'] = is_callable($validator) ? $validator : null; $mutualConditions[$class]['fallback'] = is_callable($fallback) ? $fallback : null; $self = new \ReflectionClass($this); $aliases = [$self->getTraitAliases()]; $parent = $self->getParentClass(); while ($parent) { array_unshift($aliases, $parent->getTraitAliases()); $parent = $parent->getParentClass(); } $aliases = call_user_func_array('array_merge', $aliases); foreach ($aliases as $alias => $traitMethod) { list($trait, $method) = explode('::', $traitMethod); if (!$this->magicIsClassHelperTraitName($trait)) { continue; } $type = lcfirst(preg_replace('/OrNull$/', '', substr($method, 3), -1, $nullable)); $camelProperty = ucfirst(preg_replace('/^(get|is)/', '', $alias)); $snakeProperty = strtolower(preg_replace('/[A-Z]/', '_$0', lcfirst($camelProperty))); $validator = [$this, 'validate' . $camelProperty]; $fallback = [$this, 'fallback' . $camelProperty]; $meta[$class][$snakeProperty] = ['type' => $type, 'nullable' => (bool) $nullable, 'validator' => is_callable($validator) ? $validator : null, 'fallback' => is_callable($fallback) ? $fallback : null]; } } foreach ($meta[$class] as $property => $propertyMeta) { $type = $propertyMeta['type']; $nullable = $propertyMeta['nullable']; if (!array_key_exists($property, $properties)) { if (!$checkAll) { continue; } if ($nullable) { $properties[$property] = null; } else { $message = sprintf('%s::%s must be defined.', __CLASS__, $property); throw new \InvalidArgumentException($message); } $value = null; } else { $value = $properties[$property]; } if (isset($validators[$class][$type])) { $validator = $validators[$class][$type]['function']; $expected = $validators[$class][$type]['expected']; } else { $validator = "is_{$type}"; $expected = true; if (!function_exists($validator)) { $validator = [$this, 'validateType' . ucfirst($type)]; $expected = false; } $validators[$class][$type]['function'] = $validator; $validators[$class][$type]['expected'] = $expected; } // validate type if (!($nullable && is_null($value)) && $expected !== $validator($value)) { $actualType = gettype($value); $actualType = str_replace(['integer', 'double', 'boolean'], ['int', 'float', 'bool'], $actualType); $key = "{$actualType} {$type}"; if (isset($converters[$class][$key])) { $converter = $converters[$class][$key]; } else { $converter = [$this, sprintf('convert%sTo%s', ucfirst($actualType), ucfirst($type))]; if (!is_callable($converter)) { //marks converter doesn't exist $converter = 0; } $converters[$class][$key] = $converter; } if ($converter) { // coerce and rescue $value = $converter($value); } else { if (is_object($value)) { $value = 'a instance of ' . get_class($value); } elseif (is_array($value)) { $value = 'array'; } else { $value = var_export($value, true); } $message = sprintf('%s::%s must be %s. %s is %s', __CLASS__, $property, $type, $value, $actualType); throw new \InvalidArgumentException($message); } } // validate property constraint if ($propertyMeta['validator']) { $exception = null; try { $result = $propertyMeta['validator']($value); } catch (\Exception $exception) { $result = $exception; } if ($result) { if ($propertyMeta['fallback']) { $value = $propertyMeta['fallback']($value, $result); } else { if ($exception) { throw $exception; } $message = sprintf('%s::%s value %s is invalid.', __CLASS__, $property, $value); throw new \InvalidArgumentException($message); } } } $properties[$property] = $value; } if ($mutualConditions[$class]['validator']) { $exception = null; try { $result = $mutualConditions[$class]['validator']($properties); } catch (\Exception $exception) { $result = $exception; } if ($result) { if ($mutualConditions[$class]['fallback']) { $properties = $mutualConditions[$class]['fallback']($properties, $result); } else { if ($exception) { throw $exception; } $message = sprintf("invalid condition at %s.\nproperties %s", __CLASS__, json_encode($properties)); throw new \InvalidArgumentException($message); } } } $this->helperProperties = array_merge($this->helperProperties, $properties); }
/** * @author Damien Lasserre <*****@*****.**> * @param \ReflectionClass $class * @return bool|int|string */ protected function getMapping(\ReflectionClass $class) { /** @var array $aliases */ $aliases = $class->getTraitAliases(); foreach ($aliases as $alias => $method) { if ($method == 'library\\uranium\\RESTfull::_' . $this->httpMethod(true)) { /** Return */ return $alias; } } /** Return */ return false; }