1 <?php
2
3 4 5 6 7 8 9 10
11
12 namespace Icybee\Modules\Views;
13
14 use ICanBoogie\Exception;
15 use ICanBoogie\OffsetNotWritable;
16
17 18 19
20 class Collection implements \ArrayAccess, \IteratorAggregate
21 {
22 private static $instance;
23
24 25 26 27 28
29 static public function get()
30 {
31 if (self::$instance)
32 {
33 return self::$instance;
34 }
35
36 return self::$instance = new static;
37 }
38
39 protected $collection;
40
41 protected function __construct()
42 {
43 global $core;
44
45 if ($core->config['cache views'])
46 {
47 $collection = $core->vars['cached_views'];
48
49 if (!$collection)
50 {
51 $collection = $this->collect();
52
53 $core->vars['cached_views'] = $collection;
54 }
55 }
56 else
57 {
58 $collection = $this->collect();
59 }
60
61 $this->collection = $collection;
62 }
63
64 65 66 67 68 69 70 71 72 73 74
75 protected function collect()
76 {
77 global $core;
78
79 $collection = array();
80 $modules = $core->modules;
81
82 foreach ($modules->enabled_modules_descriptors as $id => $descriptor)
83 {
84 $module = $modules[$id];
85
86 if (!$module->has_property('views'))
87 {
88 continue;
89 }
90
91 $module_views = $module->views;
92
93 foreach ($module_views as $type => $definition)
94 {
95 $definition += array
96 (
97 'module' => $id,
98 'type' => $type
99 );
100
101 $collection[$id . '/' . $type] = $definition;
102 }
103 }
104
105 new Collection\CollectEvent($this, array('collection' => &$collection));
106
107 $required = array('title', 'type', 'module', 'renders');
108
109 foreach ($collection as $id => &$definition)
110 {
111 $definition += array
112 (
113 'access_callback' => null,
114 'class' => null,
115 'provider' => null,
116 'title args' => array()
117 );
118
119 foreach ($required as $property)
120 {
121 if (empty($definition[$property]))
122 {
123 throw new \UnexpectedValueException(\ICanBoogie\format
124 (
125 '%property is empty for the view %id.', array
126 (
127 'property' => $property,
128 'id' => $id
129 )
130 ));
131 }
132 }
133 }
134
135 return $collection;
136 }
137
138 139 140 141 142
143 public function offsetExists($offset)
144 {
145 return isset($this->collection[$offset]);
146 }
147
148 149 150 151 152
153 public function offsetGet($id)
154 {
155 if (!$this->offsetExists($id))
156 {
157 throw new Collection\ViewNotDefined($id);
158 }
159
160 return $this->collection[$id];
161 }
162
163 164 165
166 public function offsetSet($offset, $value)
167 {
168 throw new OffsetNotWritable(array($offset, $this));
169 }
170
171 172 173
174 public function offsetUnset($offset)
175 {
176 throw new OffsetNotWritable(array($offset, $this));
177 }
178
179 public function getIterator()
180 {
181 return new \ArrayIterator($this->collection);
182 }
183 }
184
185 namespace Icybee\Modules\Views\Collection;
186
187 188 189
190 class CollectEvent extends \ICanBoogie\Event
191 {
192 193 194 195 196
197 public $collection;
198
199 200 201 202 203 204
205 public function __construct(\Icybee\Modules\Views\Collection $target, array $payload)
206 {
207 parent::__construct($target, 'collect', $payload);
208 }
209 }
210
211 212 213
214 class ViewNotDefined extends \RuntimeException
215 {
216 public function __construct($id, $code=500, \Exception $previous=null)
217 {
218 parent::__construct("View not defined: $id.", $code, $previous);
219 }
220 }