/library/Javis/Annotation/Manager.php
PHP | 358 lines | 190 code | 33 blank | 135 comment | 43 complexity | d60fef422a11a4968b6832a1cbc5c4c0 MD5 | raw file
- <?php
- /**
- * Javis Framework
- *
- * LICENSE
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * @package Javis\Annotation
- * @author XWEB Dev Team
- * @copyright Copyright (c) 2010-2011 XWEB. (http://xweb.vn)
- * @license http://javis.xweb.vn/license.html GNU GPL License
- * @version $Id: Manager.php 1 2015-27-07 11:25:09 Mr.UBKey $
- */
- namespace Javis\Annotation;
- use Javis\Runtime;
- /**
- * Annotation Manager
- *
- * @author Mr.UBKey
- * @link http://javis.xweb.vn/document/javis_annotation_manager.html
- */
- class Manager
- {
- const MEMBER_CLASS = 'class';
- const MEMBER_PROPERTY = 'property';
- const MEMBER_METHOD = 'method';
- /**
- * @var array Default annotation mapping
- */
- public static $mapping
- = array(
- #Action
- 'Compresses' => '\\XPHP\\Action\\Attribute\\Compresses',
- 'OutputCache' => '\\XPHP\\Action\\Attribute\\OutputCache',
- #Model
- 'Type' => '\\XPHP\\Model\\Attribute\\Type',
- 'Join' => '\\XPHP\\Model\\Attribute\\Join',
- #Model Html
- 'Label' => '\\XPHP\\Model\\Attribute\\Html\\Label',
- 'Tooltip' => '\\XPHP\\Model\\Attribute\\Html\\Tooltip',
- #Model Binding
- 'Table' => '\\XPHP\\Model\\Attribute\\Binding\\Table',
- 'PrimaryKey' => '\\XPHP\\Model\\Attribute\\Binding\\PrimaryKey',
- 'Adapter' => '\\XPHP\\Model\\Attribute\\Binding\\Adapter',
- 'ReadOnly' => '\\XPHP\\Model\\Attribute\\Binding\\ReadOnly',
- 'Command' => '\\XPHP\\Model\\Attribute\\Binding\\Command',
- #Model Validation
- 'Required' => '\\XPHP\\Model\\Attribute\\Validation\\Required',
- 'MinLength' => '\\XPHP\\Model\\Attribute\\Validation\\Minlength',
- 'MaxLength' => '\\XPHP\\Model\\Attribute\\Validation\\Maxlength',
- 'RangeLength' => '\\XPHP\\Model\\Attribute\\Validation\\RangeLength',
- 'Min' => '\\XPHP\\Model\\Attribute\\Validation\\Min',
- 'Max' => '\\XPHP\\Model\\Attribute\\Validation\\Max',
- 'Range' => '\\XPHP\\Model\\Attribute\\Validation\\Range',
- 'Email' => '\\XPHP\\Model\\Attribute\\Validation\\Email',
- 'Url' => '\\XPHP\\Model\\Attribute\\Validation\\Url',
- 'Number' => '\\XPHP\\Model\\Attribute\\Validation\\Number',
- #Widget DataTable
- 'DataTable' => '\\XPHP\\Widget\\Attribute\\DataTable');
- /**
- * @var Parser
- */
- protected static $parser;
- /**
- * All annotation of a class
- *
- * @var array
- */
- protected static $annotations = array();
- /**
- * All class has annotations
- *
- * @var array
- */
- protected static $initialized;
- /**
- * Check annotation class exists
- *
- * @param $class
- *
- * @return bool
- */
- public static function hasAnnotationClassName($class)
- {
- return class_exists($class);
- }
- /**
- * Check mapping name of annotation
- *
- * @param $name
- *
- * @return bool
- */
- public static function hasAnnotation($name)
- {
- return isset(static::$mapping[$name]);
- }
- /**
- * Create instance of Annotation Parser class
- *
- * @return Parser
- */
- public static function getParser()
- {
- if (!static::$parser) {
- static::$parser = new Parser();
- }
- return static::$parser;
- }
- /**
- * Get annotation class name
- *
- * @param $name
- *
- * @return bool
- */
- public static function getAnnotationClassName($name)
- {
- $type = $name;
- if (@ static::$mapping[$type] === false) {
- return false; // disabled
- }
- if (isset(static::$mapping[$type])) {
- return static::$mapping[$type];
- } // class annotation
- else {
- if (preg_match('/^[a-zA-Z_]+/i', $name) && class_exists($name)) {
- return $name; //get name class is annotation name
- } else {
- return false;
- }
- }
- }
- /**
- * Get annotations
- *
- * @param $class
- * @param string $member const MEMBER_
- * @param null $name
- *
- * @return array
- */
- protected static function getAnnotations($class, $member = 'class', $name = null)
- {
- //Runtime key
- $runtimeKey = "Annotation/" . md5($class);
- //Load Runtime no trigger to get file path
- Runtime::load($runtimeKey);
- //Get path to file contains class
- $path = Runtime::get("{$runtimeKey}.path");
- if ($path === null) {
- $reflection = new \ReflectionClass($class);
- $path = str_replace(realpath(APPLICATION_PATH), APPLICATION_PATH, $reflection->getFileName());
- $path = str_replace(realpath(LIBRARY_PATH), LIBRARY_PATH, $path);
- }
- //No path no annotations
- if ($path === false) {
- return array();
- }
- //Load Runtime with trigger
- Runtime::load($runtimeKey, function ($time) use ($path) {
- return $time >= filemtime($path);
- });
- //Get key in annotations array
- if ($member == "class") {
- $key = $class;
- } else {
- if ($member == "method") {
- $key = "{$class}::{$name}()";
- } else {
- $key = "{$class}::{$name}";
- }
- }
- //Check loaded annotations from class
- if (!isset(static::$initialized[$key])) {
- //Check data from runtime
- $specs = Runtime::get("{$runtimeKey}.annotations");
- //If runtime no contains parse file to get annotations and save to runtime
- if ($specs === null) {
- $specs = static::getParser()->parse($path);
- Runtime::set($runtimeKey, array('path' => $path, 'annotations' => $specs));
- Runtime::save($runtimeKey);
- }
- if ($specs) {
- foreach ($specs as $k => $v) {
- //Flag class loaded
- static::$initialized[$k] = true;
- //Save all annotations from class to $annotations
- static::$annotations[$k] = $specs[$k];
- }
- }
- }
- return isset(static::$annotations[$key]) ? static::$annotations[$key] : array();
- }
- /**
- * Filter annotations
- *
- * @param $annotations
- * @param $type
- *
- * @return array
- */
- protected static function filterAnnotations($annotations, $type)
- {
- //Check type is class or annotation name
- if (static::hasAnnotation($type)) {
- $type = static::getAnnotationClassName($type);
- }
- $result = array();
- foreach ($annotations as $a) {
- if ($a instanceof $type) {
- $result[] = $a;
- }
- }
- return $result;
- }
- /**
- * Get annotations of class with filter
- *
- * @param $class
- * @param null $type
- *
- * @return mixed
- *
- * @throws \Exception
- */
- public static function getClassAnnotations($class, $type = null)
- {
- if ($class instanceof \ReflectionClass) {
- $class = $class->getName();
- } else {
- if (is_object($class)) {
- $class = get_class($class);
- }
- }
- if (!class_exists($class)) {
- throw new \Exception(get_class($class) . "::getClassAnnotations() : chưa định nghĩa lớp {$class}");
- }
- if ($type === null) {
- return static::getAnnotations($class);
- } else {
- return static::filterAnnotations(static::getAnnotations($class), $type);
- }
- }
- /**
- * Get annotations of method with filter
- *
- * @param $class
- * @param null $method
- * @param null $type
- *
- * @return mixed
- *
- * @throws \Exception
- */
- public static function getMethodAnnotations($class, $method = null, $type = null)
- {
- if ($class instanceof \ReflectionClass) {
- $class = $class->getName();
- } else {
- if ($class instanceof \ReflectionMethod) {
- $method = $class->name;
- $class = $class->class;
- } else {
- if (is_object($class)) {
- $class = get_class($class);
- }
- }
- }
- if (!class_exists($class)) {
- throw new \Exception(get_class($class) . "::getMethodAnnotations() : Declare class {$class}");
- }
- if (!method_exists($class, $method)) {
- throw new \Exception(get_class($class)
- . "::getMethodAnnotations() : Declare method {$class}::{$method}()");
- }
- if ($type === null) {
- return static::getAnnotations($class, 'method', $method);
- } else {
- return static::filterAnnotations(static::getAnnotations($class, 'method', $method), $type);
- }
- }
- /**
- * Get annotations of property with filter
- *
- * @param $class
- * @param null $property
- * @param null $type
- *
- * @return mixed
- *
- * @throws \Exception
- */
- public static function getPropertyAnnotations($class, $property = null, $type = null)
- {
- if ($class instanceof \ReflectionClass) {
- $class = $class->getName();
- } else {
- if ($class instanceof \ReflectionProperty) {
- $property = $class->name;
- $class = $class->class;
- } else {
- if (is_object($class)) {
- $class = get_class($class);
- }
- }
- }
- if (!class_exists($class)) {
- throw new \Exception(get_class($class) . "::getPropertyAnnotations() : Declare property {$class}");
- }
- if ($type === null) {
- return static::getAnnotations($class, 'property', '$' . $property);
- } else {
- return static::filterAnnotations(static::getAnnotations($class, 'property', '$' . $property), $type);
- }
- }
- }