1: <?php
2:
3: /**
4: * PhpOptions
5: * @link https://github.com/masicek/PhpOptions
6: * @author Viktor Mašíček <viktor@masicek.net>
7: * @license "New" BSD License
8: */
9:
10: namespace PhpOptions\Types;
11:
12: /**
13: * Class for better work with defined types extends ITypes
14: *
15: * @author Viktor Mašíček <viktor@masicek.net>
16: */
17: class Types
18: {
19:
20:
21: /**
22: * List of registered types
23: *
24: * @var array [name] => array(
25: * 'className' => [name of class with namespace]
26: * 'classPath' => [full path of file contains class of type]
27: * )
28: */
29: private $registeredTypes = array();
30:
31: /**
32: * Serialized list of default types.
33: * This value is used in minified version.
34: *
35: * @var string
36: */
37: private static $serializedDeafultTypes = '';
38:
39:
40: /**
41: * Register default types.
42: * There are all files with suffix "Type.php" in this directory.
43: * Name type is prefix: "[name of type]Type.php"
44: */
45: public function __construct()
46: {
47: foreach ($this->getDefaultTypes() as $name => $class)
48: {
49: $this->register($name, $class['className'], $class['classPath']);
50: }
51: }
52:
53:
54: /**
55: * Register new type. It has to by child of abstract class AType.
56: * It is possible rewrite already registered types (so defaults too).
57: *
58: * @param string $name Name of type
59: * @param string $className Name of class of type with namespace
60: * @param string $classPath Full path of file contains class of type
61: *
62: * @return void
63: */
64: public function register($name, $className, $classPath)
65: {
66: $name = strtolower($name);
67: $this->registeredTypes[$name]['className'] = $className;
68: $this->registeredTypes[$name]['classPath'] = $classPath;
69: }
70:
71:
72: /**
73: * Get class for specifis type of option value.
74: *
75: * @param string $type Type of option value
76: * @param array $settings List of setting specific for selected type
77: *
78: * @throws \PhpOptions\InvalidArgumentException Undefined type of option.
79: * @return AType
80: */
81: public function getType($type, $settings)
82: {
83: if (!isset($this->registeredTypes[$type]))
84: {
85: throw new \PhpOptions\InvalidArgumentException($type . ': Undefined type of option.');
86: }
87:
88: require_once $this->registeredTypes[$type]['classPath'];
89: $className = $this->registeredTypes[$type]['className'];
90: $typeClass = new $className($settings);
91:
92: if (!($typeClass instanceof \PhpOptions\Types\AType))
93: {
94: throw new \PhpOptions\InvalidArgumentException($type . ': Type have to be instance of \PhpOptions\Types\AType.');
95: }
96:
97: return $typeClass;
98: }
99:
100:
101: /**
102: * Return list of all defaults types with their class name and files for including.
103: *
104: * @return array
105: */
106: public function getDefaultTypes()
107: {
108: // minified version
109: if (self::$serializedDeafultTypes)
110: {
111: return unserialize(self::$serializedDeafultTypes);
112: }
113:
114: $types = array();
115: $files = scandir(__DIR__);
116: foreach ($files as $file)
117: {
118: if (substr($file, -8) == 'Type.php')
119: {
120: // remove Type.php at the end
121: $nameOfType = substr($file, 0, -8);
122:
123: // remove .php at the end
124: $className = '\\PhpOptions\\Types\\' . substr($file, 0, -4);
125: $types[$nameOfType]['className'] = $className;
126: $types[$nameOfType]['classPath'] = __DIR__ . DIRECTORY_SEPARATOR . $file;
127: }
128: }
129: unset($types['A']);
130: return $types;
131: }
132:
133:
134: }
135: