blob: b901dbc3a96987a17bed6393fbc84dfcce4e7908 [file] [log] [blame]
Matthias Andreas Benkardb382b102021-01-02 15:32:21 +01001<?php namespace Sieve;
2
3class SieveKeywordRegistry
4{
5 protected $registry_ = array();
6 protected $matchTypes_ = array();
7 protected $comparators_ = array();
8 protected $addressParts_ = array();
9 protected $commands_ = array();
10 protected $tests_ = array();
11 protected $arguments_ = array();
12
13 protected static $refcount = 0;
14 protected static $instance = null;
15
16 protected function __construct()
17 {
18 $keywords = simplexml_load_file(dirname(__FILE__) .'/keywords.xml');
19 foreach ($keywords->children() as $keyword)
20 {
21 switch ($keyword->getName())
22 {
23 case 'matchtype':
24 $type =& $this->matchTypes_;
25 break;
26 case 'comparator':
27 $type =& $this->comparators_;
28 break;
29 case 'addresspart':
30 $type =& $this->addressParts_;
31 break;
32 case 'test':
33 $type =& $this->tests_;
34 break;
35 case 'command':
36 $type =& $this->commands_;
37 break;
38 default:
39 trigger_error('Unsupported keyword type "'. $keyword->getName()
40 . '" in file "keywords/'. basename($file) .'"');
41 return;
42 }
43
44 $name = (string) $keyword['name'];
45 if (array_key_exists($name, $type))
46 trigger_error("redefinition of $type $name - skipping");
47 else
48 $type[$name] = $keyword->children();
49 }
50
51 foreach (glob(dirname(__FILE__) .'/extensions/*.xml') as $file)
52 {
53 $extension = simplexml_load_file($file);
54 $name = (string) $extension['name'];
55
56 if (array_key_exists($name, $this->registry_))
57 {
58 trigger_error('overwriting extension "'. $name .'"');
59 }
60 $this->registry_[$name] = $extension;
61 }
62 }
63
64 public static function get()
65 {
66 if (self::$instance == null)
67 {
68 self::$instance = new SieveKeywordRegistry();
69 }
70
71 self::$refcount++;
72
73 return self::$instance;
74 }
75
76 public function put()
77 {
78 if (--self::$refcount == 0)
79 {
80 self::$instance = null;
81 }
82 }
83
84 public function activate($extension)
85 {
86 if (!isset($this->registry_[$extension]))
87 {
88 return;
89 }
90
91 $xml = $this->registry_[$extension];
92
93 foreach ($xml->children() as $e)
94 {
95 switch ($e->getName())
96 {
97 case 'matchtype':
98 $type =& $this->matchTypes_;
99 break;
100 case 'comparator':
101 $type =& $this->comparators_;
102 break;
103 case 'addresspart':
104 $type =& $this->addressParts_;
105 break;
106 case 'test':
107 $type =& $this->tests_;
108 break;
109 case 'command':
110 $type =& $this->commands_;
111 break;
112 case 'tagged-argument':
113 $xml = $e->parameter[0];
114 $this->arguments_[(string) $xml['name']] = array(
115 'extends' => (string) $e['extends'],
116 'rules' => $xml
117 );
118 continue;
119 default:
120 trigger_error('Unsupported extension type \''.
121 $e->getName() ."' in extension '$extension'");
122 return;
123 }
124
125 $name = (string) $e['name'];
126 if (!isset($type[$name]) ||
127 (string) $e['overrides'] == 'true')
128 {
129 $type[$name] = $e->children();
130 }
131 }
132 }
133
134 public function isTest($name)
135 {
136 return (isset($this->tests_[$name]) ? true : false);
137 }
138
139 public function isCommand($name)
140 {
141 return (isset($this->commands_[$name]) ? true : false);
142 }
143
144 public function matchtype($name)
145 {
146 if (isset($this->matchTypes_[$name]))
147 {
148 return $this->matchTypes_[$name];
149 }
150 return null;
151 }
152
153 public function addresspart($name)
154 {
155 if (isset($this->addressParts_[$name]))
156 {
157 return $this->addressParts_[$name];
158 }
159 return null;
160 }
161
162 public function comparator($name)
163 {
164 if (isset($this->comparators_[$name]))
165 {
166 return $this->comparators_[$name];
167 }
168 return null;
169 }
170
171 public function test($name)
172 {
173 if (isset($this->tests_[$name]))
174 {
175 return $this->tests_[$name];
176 }
177 return null;
178 }
179
180 public function command($name)
181 {
182 if (isset($this->commands_[$name]))
183 {
184 return $this->commands_[$name];
185 }
186 return null;
187 }
188
189 public function arguments($command)
190 {
191 $res = array();
192 foreach ($this->arguments_ as $arg)
193 {
194 if (preg_match('/'.$arg['extends'].'/', $command))
195 array_push($res, $arg['rules']);
196 }
197 return $res;
198 }
199
200 public function argument($name)
201 {
202 if (isset($this->arguments_[$name]))
203 {
204 return $this->arguments_[$name]['rules'];
205 }
206 return null;
207 }
208
209 public function requireStrings()
210 {
211 return array_keys($this->registry_);
212 }
213 public function matchTypes()
214 {
215 return array_keys($this->matchTypes_);
216 }
217 public function comparators()
218 {
219 return array_keys($this->comparators_);
220 }
221 public function addressParts()
222 {
223 return array_keys($this->addressParts_);
224 }
225 public function tests()
226 {
227 return array_keys($this->tests_);
228 }
229 public function commands()
230 {
231 return array_keys($this->commands_);
232 }
233}