├── .gitignore
├── .travis.yml
├── README.md
├── composer.json
├── phalcon.ini
├── phpunit.xml
├── src
└── Enum
│ ├── Adapter
│ ├── AdapterInterface.php
│ ├── PhalconAdapter.php
│ └── ReflectionAdapter.php
│ ├── Enum.php
│ └── Exception
│ └── EnumException.php
└── tests
├── App
├── ErrorCode.php
├── ErrorCode2.php
└── ErrorCodeNoPhalcon.php
├── Enum
└── BaseTest.php
├── TestCase.php
└── bootstrap.php
/.gitignore:
--------------------------------------------------------------------------------
1 | /vendor/
2 | composer.lock
3 |
4 | *.cache
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: php
2 |
3 | dist: trusty
4 | sudo: false
5 |
6 | php:
7 | - 7.0
8 | - 7.1
9 | - 7.2
10 | - 7.3
11 | - 7.4
12 | - nightly
13 |
14 | matrix:
15 | fast_finish: true
16 | allow_failures:
17 | - php: nightly
18 |
19 | git:
20 | depth: 1
21 |
22 | before_install:
23 | - export PHP_MAJOR="$(`phpenv which php` -r 'echo phpversion();' | cut -d '.' -f 1)"
24 | - export PHP_MINOR="$(`phpenv which php` -r 'echo phpversion();' | cut -d '.' -f 2)"
25 | - echo $PHP_MAJOR
26 | - echo $PHP_MINOR
27 |
28 | install:
29 | - cd $TRAVIS_BUILD_DIR
30 | # 更新扩展
31 | - sudo apt-get update
32 | - sudo apt-get install libpcre3-dev gcc make re2c
33 | # 安装Phalcon扩展
34 | - git clone https://github.com/phalcon/cphalcon.git --depth=1
35 | - cd $TRAVIS_BUILD_DIR/cphalcon/build
36 | - sudo ./install --phpize $(phpenv which phpize) --php-config $(phpenv which php-config)
37 | - phpenv config-add $TRAVIS_BUILD_DIR/phalcon.ini
38 | # 安装项目
39 | - composer self-update
40 | - cd $TRAVIS_BUILD_DIR
41 | - composer install --prefer-dist --optimize-autoloader
42 |
43 | script:
44 | - cd $TRAVIS_BUILD_DIR
45 | - ./vendor/bin/phpunit
46 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # x-phalcon-enum
2 |
3 | [](https://travis-ci.org/limingxinleo/x-phalcon-enum)
4 |
5 | ## 安装
6 | ~~~
7 | composer require limingxinleo/x-phalcon-enum
8 | ~~~
9 |
10 | ## 使用
11 | 定义枚举类
12 | ~~~
13 | use Xin\Phalcon\Enum\Enum;
14 |
15 | class ErrorCode extends Enum
16 | {
17 | /**
18 | * @Message('非法的TOKEN')
19 | */
20 | public static $ENUM_INVALID_TOKEN = 700;
21 | }
22 | ~~~
23 |
24 |
25 |
26 |
27 | 获取单个枚举
28 | ~~~
29 | $code = ErrorCode::$ENUM_INVALID_TOKEN;
30 | $message = ErrorCode::getMessage($code);
31 | ~~~
32 |
33 | 获取枚举数组
34 | ~~~
35 |
36 | $message = ErrorCode::toArray();
37 | ~~~
38 |
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "limingxinleo/x-phalcon-enum",
3 | "description": "a phalcon enum component",
4 | "type": "library",
5 | "license": "MIT",
6 | "keywords": [
7 | "phalcon-enum",
8 | "phalcon-component",
9 | "phalcon"
10 | ],
11 | "authors": [
12 | {
13 | "name": "李铭昕",
14 | "email": "715557344@qq.com"
15 | }
16 | ],
17 | "autoload": {
18 | "psr-4": {
19 | "Xin\\Phalcon\\": "src/"
20 | }
21 | },
22 | "autoload-dev": {
23 | "psr-4": {
24 | "Tests\\": "tests/"
25 | }
26 | },
27 | "require": {
28 | "php": ">=7.0",
29 | "limingxinleo/x-trait-common": "^1.1",
30 | "limingxinleo/support-str": "^1.0"
31 | },
32 | "require-dev": {
33 | "phpunit/phpunit": ">=5.6"
34 | },
35 | "suggest": {
36 | "php": ">=7.0",
37 | "ext-phalcon": "^3.0"
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/phalcon.ini:
--------------------------------------------------------------------------------
1 | ;
2 | ; Phalcon Framework
3 | ;
4 | ; Copyright (c) 2011-present Phalcon Team (https://www.phalconphp.com)
5 | ;
6 | ; This source file is subject to the New BSD License that is bundled
7 | ; with this package in the file LICENSE.txt.
8 | ;
9 | ; If you did not receive a copy of the license and are unable to
10 | ; obtain it through the world-wide-web, please send an email
11 | ; to license@phalconphp.com so we can send you a copy immediately.
12 |
13 | [phalcon]
14 | extension=phalcon.so
15 |
16 | ; ----- Options to use the Phalcon Framework
17 |
18 | ; phalcon.db.escape_identifiers = On
19 | ; phalcon.db.force_casting = Off
20 |
21 | ; phalcon.orm.events = On
22 | ; phalcon.orm.virtual_foreign_keys = On
23 | ; phalcon.orm.column_renaming = On
24 | ; phalcon.orm.not_null_validations = On
25 | ; phalcon.orm.exception_on_failed_save = Off
26 | ; phalcon.orm.enable_literals = On
27 | ; phalcon.orm.late_state_binding = Off
28 | ; phalcon.orm.enable_implicit_joins = On
29 | ; phalcon.orm.cast_on_hydrate = Off
30 | ; phalcon.orm.ignore_unknown_columns = Off
31 | ; phalcon.orm.update_snapshot_on_save = On
32 | ; phalcon.orm.disable_assign_setters = Off
33 |
--------------------------------------------------------------------------------
/phpunit.xml:
--------------------------------------------------------------------------------
1 |
2 |
12 |
13 | ./tests/
14 |
15 |
--------------------------------------------------------------------------------
/src/Enum/Adapter/AdapterInterface.php:
--------------------------------------------------------------------------------
1 |
8 | // +----------------------------------------------------------------------
9 | namespace Xin\Phalcon\Enum\Adapter;
10 |
11 | interface AdapterInterface
12 | {
13 | public function __construct($class);
14 |
15 | public function getAnnotationsByName($name, $properties);
16 | }
17 |
--------------------------------------------------------------------------------
/src/Enum/Adapter/PhalconAdapter.php:
--------------------------------------------------------------------------------
1 |
8 | // +----------------------------------------------------------------------
9 | namespace Xin\Phalcon\Enum\Adapter;
10 |
11 | use Phalcon\Text;
12 | use Phalcon\Annotations\Adapter\Memory as MemoryAdapter;
13 |
14 | class PhalconAdapter implements AdapterInterface
15 | {
16 | protected $class;
17 |
18 | public function __construct($class)
19 | {
20 | $this->class = $class;
21 | }
22 |
23 | public function getAnnotationsByName($name, $properties)
24 | {
25 | $adapter = new MemoryAdapter();
26 | $reflection = $adapter->get($this->class);
27 | $annotations = $reflection->getPropertiesAnnotations();
28 |
29 | $result = [];
30 | foreach ($properties as $key => $val) {
31 | $isValid = Text::startsWith($key, 'ENUM_') // 必须以ENUM_开头
32 | && isset($annotations[$key]) // 当前字段存在注释
33 | && $annotations[$key]->has(Text::camelize($name)); // 当前字段存在此注解的注释
34 |
35 | if ($isValid) {
36 | // 获取对应注释
37 | $ret = $annotations[$key]->get(Text::camelize($name));
38 | $result[$val] = $ret->getArgument(0);
39 |
40 | }
41 | }
42 |
43 | return $result;
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/src/Enum/Adapter/ReflectionAdapter.php:
--------------------------------------------------------------------------------
1 |
8 | // +----------------------------------------------------------------------
9 | namespace Xin\Phalcon\Enum\Adapter;
10 |
11 | use limx\Support\Str;
12 | use ReflectionClass;
13 | use ReflectionProperty;
14 |
15 | class ReflectionAdapter implements AdapterInterface
16 | {
17 | protected $class;
18 |
19 | public function __construct($class)
20 | {
21 | $this->class = $class;
22 | }
23 |
24 | public function getAnnotationsByName($name, $properties)
25 | {
26 | $result = [];
27 | foreach ($properties as $key => $val) {
28 | if (Str::startsWith($key, 'ENUM_')) {
29 | // 获取对应注释
30 | $ret = new ReflectionProperty($this->class, $key);
31 | $result[$val] = $this->getCommentByName($ret->getDocComment(), $name);
32 | }
33 | }
34 |
35 | return $result;
36 | }
37 |
38 | /**
39 | * @desc 根据name解析doc获取对应注释
40 | * @author limx
41 | * @param $doc 注释
42 | * @param $name 字段名
43 | */
44 | protected function getCommentByName($doc, $name)
45 | {
46 | $name = Str::studly($name);
47 | $pattern = "/\@{$name}\(\'(.*)\'\)/U";
48 | if (preg_match($pattern, $doc, $result)) {
49 | if (isset($result[1])) {
50 | return $result[1];
51 | }
52 | }
53 | return null;
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/src/Enum/Enum.php:
--------------------------------------------------------------------------------
1 |
8 | // +----------------------------------------------------------------------
9 | namespace Xin\Phalcon\Enum;
10 |
11 | use limx\Support\Str;
12 | use Xin\Phalcon\Enum\Adapter\AdapterInterface;
13 | use Xin\Phalcon\Enum\Adapter\PhalconAdapter;
14 | use Xin\Phalcon\Enum\Adapter\ReflectionAdapter;
15 | use Xin\Phalcon\Enum\Exception\EnumException;
16 | use ReflectionClass;
17 | use Xin\Traits\Common\InstanceTrait;
18 |
19 | /**
20 | * Class Enum
21 | * @package Xin\Phalcon\Enum
22 | * @method getMessage($code)
23 | * @method getDesc($code)
24 | */
25 | abstract class Enum
26 | {
27 | use InstanceTrait;
28 |
29 | public static $_instance;
30 |
31 | /** @var AdapterInterface */
32 | public $_adapter;
33 |
34 | protected $phalconExtEnable = true;
35 |
36 | private function __construct()
37 | {
38 | if ($this->phalconExtEnable && extension_loaded('phalcon')) {
39 | $this->_adapter = new PhalconAdapter(static::class);
40 | } else {
41 | $this->_adapter = new ReflectionAdapter(static::class);
42 | }
43 | }
44 |
45 | public function __call($name, $arguments)
46 | {
47 | if (!Str::startsWith($name, 'get')) {
48 | throw new EnumException('The function is not defined!');
49 | }
50 | if (!isset($arguments) || count($arguments) === 0) {
51 | throw new EnumException('The Code is required');
52 | }
53 |
54 | $code = $arguments[0];
55 | $name = strtolower(substr($name, 3));
56 |
57 | if (isset($this->$name)) {
58 | return isset($this->$name[$code]) ? $this->$name[$code] : '';
59 | }
60 |
61 | // 获取变量
62 | $ref = new ReflectionClass(static::class);
63 | $properties = $ref->getDefaultProperties();
64 |
65 | $arr = $this->_adapter->getAnnotationsByName($name, $properties);
66 |
67 | if (version_compare(PHP_VERSION, 7, '<')) {
68 | // 版本小于7
69 | return isset($arr[$code]) ? $arr[$code] : '';
70 | }
71 |
72 | $this->$name = $arr;
73 | return isset($this->$name[$code]) ? $this->$name[$code] : '';
74 | }
75 |
76 | public static function __callStatic($method, $arguments)
77 | {
78 | return static::getInstance()->$method(...$arguments);
79 | }
80 |
81 | /**
82 | * 获取枚举数组
83 | * @return array
84 | */
85 | public static function toArray(){
86 |
87 | $ref = new ReflectionClass(static::class);
88 | $properties = $ref->getDefaultProperties();
89 | $_adapter = new ReflectionAdapter(static::class);
90 | $arr = $_adapter->getAnnotationsByName('Message', $properties);
91 |
92 | return $arr;
93 | }
94 | }
95 |
--------------------------------------------------------------------------------
/src/Enum/Exception/EnumException.php:
--------------------------------------------------------------------------------
1 |
8 | // +----------------------------------------------------------------------
9 | namespace Xin\Phalcon\Enum\Exception;
10 |
11 | use Exception;
12 |
13 | class EnumException extends Exception
14 | {
15 | }
16 |
--------------------------------------------------------------------------------
/tests/App/ErrorCode.php:
--------------------------------------------------------------------------------
1 |
8 | // +----------------------------------------------------------------------
9 | namespace Tests\App;
10 |
11 | use Xin\Phalcon\Enum\Enum;
12 |
13 | class ErrorCode extends Enum
14 | {
15 | /**
16 | * @Message('非法的TOKEN')
17 | * @Desc('需要重新登录')
18 | */
19 | public static $ENUM_INVALID_TOKEN = 700;
20 |
21 | /**
22 | * @Message('Code不为数字')
23 | */
24 | public static $ENUM_NOT_NUMBER = 'OP1000';
25 | }
26 |
--------------------------------------------------------------------------------
/tests/App/ErrorCode2.php:
--------------------------------------------------------------------------------
1 |
8 | // +----------------------------------------------------------------------
9 | namespace Tests\App;
10 |
11 | use Xin\Phalcon\Enum\Enum;
12 |
13 | class ErrorCode2 extends Enum
14 | {
15 | /**
16 | * @Message('非法的TOKEN 2')
17 | * @Desc('需要重新登录')
18 | */
19 | public static $ENUM_INVALID_TOKEN = 700;
20 | }
21 |
--------------------------------------------------------------------------------
/tests/App/ErrorCodeNoPhalcon.php:
--------------------------------------------------------------------------------
1 |
8 | // +----------------------------------------------------------------------
9 | namespace Tests\App;
10 |
11 | use Xin\Phalcon\Enum\Enum;
12 |
13 | class ErrorCodeNoPhalcon extends Enum
14 | {
15 | protected $phalconExtEnable = false;
16 |
17 | /**
18 | * @Message('非法的TOKEN')
19 | * @Desc('需要重新登录')
20 | */
21 | public static $ENUM_INVALID_TOKEN = 700;
22 | }
23 |
--------------------------------------------------------------------------------
/tests/Enum/BaseTest.php:
--------------------------------------------------------------------------------
1 |
8 | // +----------------------------------------------------------------------
9 | namespace Tests\Middleware;
10 |
11 | use Tests\App\ErrorCode;
12 | use Tests\App\ErrorCode2;
13 | use Tests\App\ErrorCodeNoPhalcon;
14 | use Tests\TestCase;
15 |
16 | class BaseTest extends TestCase
17 | {
18 | public function testCode()
19 | {
20 | $this->assertEquals(700, ErrorCode::$ENUM_INVALID_TOKEN);
21 | }
22 |
23 | public function testMessage()
24 | {
25 | $this->assertEquals('非法的TOKEN', ErrorCode::getMessage(ErrorCode::$ENUM_INVALID_TOKEN));
26 | }
27 |
28 | public function testDesc()
29 | {
30 | $this->assertEquals('需要重新登录', ErrorCode::getDesc(ErrorCode::$ENUM_INVALID_TOKEN));
31 | }
32 |
33 | public function testTwoEnum()
34 | {
35 | $code = ErrorCode::$ENUM_INVALID_TOKEN;
36 | $msg1 = ErrorCode2::getMessage($code);
37 | $msg2 = ErrorCode::getMessage($code);
38 |
39 | $this->assertEquals('非法的TOKEN', $msg2);
40 | $this->assertEquals('非法的TOKEN 2', $msg1);
41 | }
42 |
43 | public function testNoPhalconExt()
44 | {
45 | $code = ErrorCode::$ENUM_INVALID_TOKEN;
46 | $res = ErrorCodeNoPhalcon::getMessage($code);
47 | $res2 = ErrorCode::getMessage($code);
48 | $this->assertEquals($res, $res2);
49 |
50 | $res = ErrorCodeNoPhalcon::getDesc($code);
51 | $res2 = ErrorCode::getDesc($code);
52 | $this->assertEquals($res, $res2);
53 |
54 | $res3 = ErrorCodeNoPhalcon::getMsg($code);
55 | $this->assertEquals('', $res3);
56 | }
57 |
58 | public function testNotNumber()
59 | {
60 | $code = ErrorCode::$ENUM_NOT_NUMBER;
61 | $res = ErrorCode::getMessage($code);
62 |
63 | $this->assertEquals('Code不为数字', $res);
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/tests/TestCase.php:
--------------------------------------------------------------------------------
1 |
8 | // +----------------------------------------------------------------------
9 | namespace Tests;
10 |
11 | use Phalcon\Di\FactoryDefault;
12 | use PHPUnit\Framework\TestCase as UnitTestCase;
13 | use Phalcon\Config;
14 | use Xin\Phalcon\Middleware\Manager;
15 | use Xin\Phalcon\Middleware\Mvc\Dispatcher;
16 |
17 | class TestCase extends UnitTestCase
18 | {
19 | public $di;
20 |
21 | /** @var Dispatcher $dispatcher */
22 | public $dispatcher;
23 |
24 |
25 | }
26 |
--------------------------------------------------------------------------------
/tests/bootstrap.php:
--------------------------------------------------------------------------------
1 |
8 | // +----------------------------------------------------------------------
9 | require __DIR__ . '/../vendor/autoload.php';
10 | define('TESTS_PATH', __DIR__);
11 |
--------------------------------------------------------------------------------