SieveKeywordRegistry.php 5.8 KB

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