/** * Reflect the handle class * * @param string $class * @return Collection\Method * @throws Exception\InvalidArgument */ public function reflect($class) { if (class_exists($class) === false) { throw new Exception\InvalidArgument(sprintf($this->exceptions[1], $class), 1); } // Check if we've already reflected this class if (static::$reflections->offsetExists($class)) { return static::$reflections->offsetGet($class); } // Create reflection $reflectionClass = new \ReflectionClass($class); $reflectionMethods = $reflectionClass->getMethods(\ReflectionMethod::IS_PUBLIC); // Method container $methods = new Collection\Method(); // Loop through the class methods (Only public); foreach ($reflectionMethods as $reflectionMethod) { // Create method information entity $method = new Entity\Method(); $method->setName($reflectionMethod->getName()); // Get method parameters $reflectionParams = $reflectionMethod->getParameters(); // Evaluate the method params foreach ($reflectionParams as $reflectionParam) { // Create parameter information entity $parameter = new Entity\Parameter(); $parameter->setIndex($reflectionParam->getPosition()); $parameter->setName($reflectionParam->getName()); $parameter->setRequired($reflectionParam->isDefaultValueAvailable() === false); // Only set default value when param is optional if ($parameter->getRequired() === false) { $parameter->setDefault($reflectionParam->getDefaultValue()); } // Add the parameter to the container $method->addParameter($parameter); } // Add the method to the method container $methods->offsetSet(strtolower($method->getName()), $method); } // Cache reflection in the runtime self::$reflections->offsetSet($class, $methods); // Return the methods return $methods; }
/** * Get the setters of an object * * @param mixed $object * @return Collection\Method */ protected function getSetters($object) { // Get the current class $class = get_class($object); // Check if we have already parsed this class if (array_key_exists($class, $this->classMethodsCache) === true) { return $this->classMethodsCache[$class]; } // Regex for parsing ReflectionParameter::__toString() $regex = '/\\[\\s\\<(?P<required>[^\\>]+)\\>\\s' . '(?:(?P<typehint_a>[^\\s]+|(?P<typehint_b>[^\\s]+)\\sor\\s(?P<typehint_c>[^\\s]+))\\s)?' . '(?P<variable>\\$[^\\s]+)\\s(?:=\\s(?P<default>[^\\]]+)\\s)?\\]/'; // Make reflection and fetch the methods $reflectionClass = new ReflectionClass($object); $methods = $reflectionClass->getMethods(ReflectionMethod::IS_PUBLIC); // Make result container $setters = new Collection\Method(); // Loop through the methods foreach ($methods as $method) { // We only care about the setters if (substr($method->getName(), 0, 3) !== 'set') { continue; } // Get parameter collection $parameters = $method->getParameters(); // We only take care of the first parameter of the setter $parameter = $parameters[0]; $raw = (string) $parameter; // If we cannot match it we continue if (($result = preg_match($regex, $raw, $matches)) === false || $result === 0) { continue; } // Parse the result of the regex $required = $matches['required'] === 'required'; $variable = $matches['variable']; $default = $required ? null : $matches['default']; $typehint = null; // Advanced typehint detection if (empty($matches['typehint_b']) === false) { $typehint = $matches['typehint_b']; } else { if (empty($matches['typehint_a']) === false) { $typehint = $matches['typehint_a']; } } // Set the correct default value switch ($default) { case null: case 'NULL': $default = null; break; case 'Array': $default = array(); break; default: $default = trim($default, "'"); break; } // Has it child objects $childObject = $typehint !== null && $typehint !== 'array'; // Set the results the the response object $setters->offsetSet($method->getName(), new Entity\Method($required, $default, $typehint, $childObject)); } // Return the just generated response return $this->classMethodsCache[$class] = $setters; }