Skip to content

Commit

Permalink
Merge pull request #2437 from nanasess/enum-like-properties
Browse files Browse the repository at this point in the history
Trait でクラス定数(っぽいもの)を追加する仕組み
  • Loading branch information
Yangsin authored Aug 2, 2017
2 parents 74f244c + 3fc5543 commit 4dd1493
Show file tree
Hide file tree
Showing 3 changed files with 106 additions and 1 deletion.
34 changes: 34 additions & 0 deletions src/Eccube/Entity/Master/AbstractMasterEntity.php
Original file line number Diff line number Diff line change
Expand Up @@ -113,4 +113,38 @@ public function getRank()
{
return $this->rank;
}

public function __get($name)
{
return self::getConstantValue($name);
}

public function __set($name, $value)
{
throw new \InvalidArgumentException();
}

public static function __callStatic($name, $arguments)
{
return self::getConstantValue($name);
}

protected static function getConstantValue($name)
{
if (in_array($name, ['id', 'name', 'rank'])) {
throw new \InvalidArgumentException();
}
// see also. http://qiita.com/Hiraku/items/71e385b56dcaa37629fe
$class = get_class(new static());
$ref = new \ReflectionClass($class);
// クラス定数が存在していれば, クラス定数から値を取得する
$constants = $ref->getConstants();
if (array_key_exists($name, $constants)) {
return $constants[$name];
}
// XXX $obj = new static(); とすると segmentation fault が発生するため, リフレクションで値を取得する
$refProperty = $ref->getProperty($name);
$refProperty->setAccessible(true);
return $refProperty->getValue(new $class);
}
}
2 changes: 1 addition & 1 deletion tests/Eccube/Tests/Entity/AbstractEntityTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
*/
class AbstractEntityTest extends \PHPUnit_Framework_TestCase
{
private $objEntity;
private $objEntity;

public function testNewInstance()
{
Expand Down
71 changes: 71 additions & 0 deletions tests/Eccube/Tests/Entity/Master/AbstractMasterEntityTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
<?php

namespace Eccube\Tests\Entity\Master;

use Eccube\Tests\EccubeTestCase;
use Eccube\Entity\Master\Sex;

/**
* AbstractMasterEntity test cases.
*
* @author Kentaro Ohkouchi
*/
class AbstractMasterEntityTest extends EccubeTestCase
{
public function testGetConstant()
{
self::assertEquals(1, TestSexDecorator::TEST_MALE, 'constant access');
self::assertEquals(1, TestSexDecorator::TEST_MALE(), 'enum like access');
}

public function testGetConstantWithTrait()
{
self::assertEquals(2, TestSexDecorator::TEST_FEMALE(), 'enum like access via trait');
}

public function testExplicitOverwriteConstant()
{
try {
$c = new TestSexDecorator();
// クラス変数を上書きしようとすると InvalidArgumentException になる
$c->TEST_FEMALE = 3;
self::fail();
} catch (\InvalidArgumentException $e) {
self::assertInstanceOf(\InvalidArgumentException::class, $e);
}
}

public function testInvalidFields()
{
// id, name, rank は取得できない
try {
$c = TestSexDecorator::id();
self::fail();
} catch (\InvalidArgumentException $e) {
self::assertInstanceOf(\InvalidArgumentException::class, $e);
}
try {
$c = TestSexDecorator::name();
self::fail();
} catch (\InvalidArgumentException $e) {
self::assertInstanceOf(\InvalidArgumentException::class, $e);
}
try {
$c = TestSexDecorator::rank();
self::fail();
} catch (\InvalidArgumentException $e) {
self::assertInstanceOf(\InvalidArgumentException::class, $e);
}
}
}

class TestSexDecorator extends Sex
{
use TestSexTrait;
const TEST_MALE = 1;
}

trait TestSexTrait
{
private $TEST_FEMALE = 2;
}

0 comments on commit 4dd1493

Please sign in to comment.