Skip to content

Commit efba9a7

Browse files
committed
Merge pull request #82 from soloweb/enumFeature
Static Enumeration aka Enum
2 parents 1ba981e + 2b25872 commit efba9a7

19 files changed

+1580
-13
lines changed

core/Base/Enum.class.php

Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
<?php
2+
/***************************************************************************
3+
* Copyright (C) 2012 by Georgiy T. Kutsurua *
4+
* *
5+
* This program is free software; you can redistribute it and/or modify *
6+
* it under the terms of the GNU Lesser General Public License as *
7+
* published by the Free Software Foundation; either version 3 of the *
8+
* License, or (at your option) any later version. *
9+
* *
10+
***************************************************************************/
11+
12+
/**
13+
* Parent of all enumeration classes.
14+
*
15+
* @see MimeType for example
16+
*
17+
* @ingroup Base
18+
* @ingroup Module
19+
**/
20+
abstract class Enum extends NamedObject
21+
implements
22+
Serializable
23+
{
24+
protected static $names = array(/* override me */);
25+
26+
/**
27+
* @param integer $id
28+
* @return Enum
29+
*/
30+
public static function create($id)
31+
{
32+
return new static($id);
33+
}
34+
35+
public function __construct($id)
36+
{
37+
$this->setInternalId($id);
38+
}
39+
40+
/**
41+
* @param $id
42+
* @return Enum
43+
* @throws MissingElementException
44+
*/
45+
protected function setInternalId($id)
46+
{
47+
if (isset(static::$names[$id])) {
48+
$this->id = $id;
49+
$this->name = static::$names[$id];
50+
} else
51+
throw new MissingElementException(
52+
'knows nothing about such id == '.$id
53+
);
54+
55+
return $this;
56+
}
57+
58+
/**
59+
* @return string
60+
*/
61+
public function serialize()
62+
{
63+
return (string) $this->id;
64+
}
65+
66+
/**
67+
* @param $serialized
68+
*/
69+
public function unserialize($serialized)
70+
{
71+
$this->setInternalId($serialized);
72+
}
73+
74+
/**
75+
* Array of object
76+
* @static
77+
* @return array
78+
*/
79+
public static function getList()
80+
{
81+
$list = array();
82+
foreach (array_keys(static::$names) as $id)
83+
$list[] = static::create($id);
84+
85+
return $list;
86+
}
87+
88+
/**
89+
* must return any existent ID
90+
* 1 should be ok for most enumerations
91+
* @return integer
92+
**/
93+
public static function getAnyId()
94+
{
95+
return 1;
96+
}
97+
98+
/**
99+
* @return null|integer
100+
*/
101+
public function getId()
102+
{
103+
return $this->id;
104+
}
105+
106+
107+
/**
108+
* Alias for getList()
109+
* @static
110+
* @deprecated
111+
* @return array
112+
*/
113+
public static function getObjectList()
114+
{
115+
return static::getList();
116+
}
117+
118+
/**
119+
* @return string
120+
*/
121+
public function toString()
122+
{
123+
return $this->name;
124+
}
125+
126+
/**
127+
* Plain list
128+
* @static
129+
* @return array
130+
*/
131+
public static function getNameList()
132+
{
133+
return static::$names;
134+
}
135+
136+
/**
137+
* @return Enum
138+
**/
139+
public function setId($id)
140+
{
141+
throw new UnsupportedMethodException('You can not change id here, because it is politics for Enum!');
142+
}
143+
}
144+
?>

core/Form/Primitive.class.php

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -362,5 +362,29 @@ public static function ipRange($name)
362362
{
363363
return new PrimitiveIpRange($name);
364364
}
365+
366+
/**
367+
* @return PrimitiveEnum
368+
**/
369+
public static function enum($name)
370+
{
371+
return new PrimitiveEnum($name);
372+
}
373+
374+
/**
375+
* @return PrimitiveEnumByValue
376+
**/
377+
public static function enumByValue($name)
378+
{
379+
return new PrimitiveEnumByValue($name);
380+
}
381+
382+
/**
383+
* @return PrimitiveEnumList
384+
**/
385+
public static function enumList($name)
386+
{
387+
return new PrimitiveEnumList($name);
388+
}
365389
}
366390
?>
Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
<?php
2+
/***************************************************************************
3+
* Copyright (C) 2012 by Georgiy T. Kutsurua *
4+
* *
5+
* This program is free software; you can redistribute it and/or modify *
6+
* it under the terms of the GNU Lesser General Public License as *
7+
* published by the Free Software Foundation; either version 3 of the *
8+
* License, or (at your option) any later version. *
9+
* *
10+
***************************************************************************/
11+
12+
/**
13+
* @ingroup Primitives
14+
**/
15+
class PrimitiveEnum extends IdentifiablePrimitive implements ListedPrimitive
16+
{
17+
public function getList()
18+
{
19+
if ($this->value)
20+
return ClassUtils::callStaticMethod(get_class($this->value).'::getList');
21+
elseif ($this->default)
22+
return ClassUtils::callStaticMethod(get_class($this->default).'::getList');
23+
else {
24+
$object = new $this->className(
25+
ClassUtils::callStaticMethod($this->className.'::getAnyId')
26+
);
27+
28+
return $object->getObjectList();
29+
}
30+
31+
Assert::isUnreachable();
32+
}
33+
34+
/**
35+
* @throws WrongArgumentException
36+
* @return PrimitiveEnum
37+
**/
38+
public function of($class)
39+
{
40+
$className = $this->guessClassName($class);
41+
42+
Assert::classExists($className);
43+
44+
Assert::isInstance($className, 'Enum');
45+
46+
$this->className = $className;
47+
48+
return $this;
49+
}
50+
51+
public function importValue(/* Identifiable */ $value)
52+
{
53+
if ($value)
54+
Assert::isEqual(get_class($value), $this->className);
55+
else
56+
return parent::importValue(null);
57+
58+
return $this->import(array($this->getName() => $value->getId()));
59+
}
60+
61+
public function import($scope)
62+
{
63+
$result = parent::import($scope);
64+
65+
if ($result === true) {
66+
try {
67+
$this->value = $this->makeEnumById($this->value);
68+
} catch (MissingElementException $e) {
69+
$this->value = null;
70+
71+
return false;
72+
}
73+
74+
return true;
75+
}
76+
77+
return $result;
78+
}
79+
80+
/**
81+
* @param $list
82+
* @throws UnsupportedMethodException
83+
*/
84+
public function setList($list)
85+
{
86+
throw new UnsupportedMethodException('you cannot set list here, it is impossible, because list getted from enum classes');
87+
}
88+
89+
/**
90+
* @return null|string
91+
*/
92+
public function getChoiceValue()
93+
{
94+
if(
95+
($value = $this->getValue() ) &&
96+
$value instanceof Enum
97+
)
98+
return $value->getName();
99+
100+
return null;
101+
}
102+
103+
104+
/**
105+
* @return Enum|mixed|null
106+
*/
107+
public function getActualChoiceValue()
108+
{
109+
if(
110+
!$this->getChoiceValue() &&
111+
$this->getDefault()
112+
)
113+
return $this->getDefault()->getName();
114+
115+
return null;
116+
}
117+
118+
/**
119+
* @param $id
120+
* @return Enum|mixed
121+
*/
122+
protected function makeEnumById($id)
123+
{
124+
if (!$this->className)
125+
throw new WrongStateException(
126+
"no class defined for PrimitiveEnum '{$this->name}'"
127+
);
128+
129+
return new $this->className($id);
130+
}
131+
}
132+
?>
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
<?php
2+
/***************************************************************************
3+
* Copyright (C) 2012 by Georgiy T. Kutsurua *
4+
* *
5+
* This program is free software; you can redistribute it and/or modify *
6+
* it under the terms of the GNU Lesser General Public License as *
7+
* published by the Free Software Foundation; either version 3 of the *
8+
* License, or (at your option) any later version. *
9+
* *
10+
***************************************************************************/
11+
12+
/**
13+
* @ingroup Primitives
14+
**/
15+
final class PrimitiveEnumByValue extends PrimitiveEnum
16+
{
17+
public function import($scope)
18+
{
19+
if (!$this->className)
20+
throw new WrongStateException(
21+
"no class defined for PrimitiveEnum '{$this->name}'"
22+
);
23+
24+
if (isset($scope[$this->name])) {
25+
$scopedValue = urldecode($scope[$this->name]);
26+
27+
$names = ClassUtils::callStaticMethod($this->className.'::getNameList');
28+
29+
foreach ($names as $key => $value) {
30+
if ($value == $scopedValue) {
31+
try {
32+
$this->value = new $this->className($key);
33+
} catch (MissingElementException $e) {
34+
$this->value = null;
35+
return false;
36+
}
37+
38+
return true;
39+
}
40+
}
41+
42+
return false;
43+
}
44+
45+
return null;
46+
}
47+
}
48+
?>

0 commit comments

Comments
 (0)