1: <?php
2:
3: 4: 5: 6: 7: 8: 9:
10:
11: 12: 13: 14: 15: 16: 17:
18: class Swift_Mime_Grammar
19: {
20: 21: 22: 23: 24:
25: private static $_specials = array();
26:
27: 28: 29: 30: 31:
32: private static $_grammar = array();
33:
34: 35: 36: 37:
38: public function __construct()
39: {
40: $this->init();
41: }
42:
43: public function __wakeup()
44: {
45: $this->init();
46: }
47:
48: protected function init()
49: {
50: if (count(self::$_specials) > 0) {
51: return;
52: }
53:
54: self::$_specials = array(
55: '(', ')', '<', '>', '[', ']',
56: ':', ';', '@', ',', '.', '"'
57: );
58:
59:
60:
61:
62: self::$_grammar['NO-WS-CTL'] = '[\x01-\x08\x0B\x0C\x0E-\x19\x7F]';
63: self::$_grammar['WSP'] = '[ \t]';
64: self::$_grammar['CRLF'] = '(?:\r\n)';
65: self::$_grammar['FWS'] = '(?:(?:' . self::$_grammar['WSP'] . '*' .
66: self::$_grammar['CRLF'] . ')?' . self::$_grammar['WSP'] . ')';
67: self::$_grammar['text'] = '[\x00-\x08\x0B\x0C\x0E-\x7F]';
68: self::$_grammar['quoted-pair'] = '(?:\\\\' . self::$_grammar['text'] . ')';
69: self::$_grammar['ctext'] = '(?:' . self::$_grammar['NO-WS-CTL'] .
70: '|[\x21-\x27\x2A-\x5B\x5D-\x7E])';
71:
72: self::$_grammar['ccontent'] = '(?:' . self::$_grammar['ctext'] . '|' .
73: self::$_grammar['quoted-pair'] . '|(?1))';
74: self::$_grammar['comment'] = '(\((?:' . self::$_grammar['FWS'] . '|' .
75: self::$_grammar['ccontent']. ')*' . self::$_grammar['FWS'] . '?\))';
76: self::$_grammar['CFWS'] = '(?:(?:' . self::$_grammar['FWS'] . '?' .
77: self::$_grammar['comment'] . ')*(?:(?:' . self::$_grammar['FWS'] . '?' .
78: self::$_grammar['comment'] . ')|' . self::$_grammar['FWS'] . '))';
79: self::$_grammar['qtext'] = '(?:' . self::$_grammar['NO-WS-CTL'] .
80: '|[\x21\x23-\x5B\x5D-\x7E])';
81: self::$_grammar['qcontent'] = '(?:' . self::$_grammar['qtext'] . '|' .
82: self::$_grammar['quoted-pair'] . ')';
83: self::$_grammar['quoted-string'] = '(?:' . self::$_grammar['CFWS'] . '?"' .
84: '(' . self::$_grammar['FWS'] . '?' . self::$_grammar['qcontent'] . ')*' .
85: self::$_grammar['FWS'] . '?"' . self::$_grammar['CFWS'] . '?)';
86: self::$_grammar['atext'] = '[a-zA-Z0-9!#\$%&\'\*\+\-\/=\?\^_`\{\}\|~]';
87: self::$_grammar['atom'] = '(?:' . self::$_grammar['CFWS'] . '?' .
88: self::$_grammar['atext'] . '+' . self::$_grammar['CFWS'] . '?)';
89: self::$_grammar['dot-atom-text'] = '(?:' . self::$_grammar['atext'] . '+' .
90: '(\.' . self::$_grammar['atext'] . '+)*)';
91: self::$_grammar['dot-atom'] = '(?:' . self::$_grammar['CFWS'] . '?' .
92: self::$_grammar['dot-atom-text'] . '+' . self::$_grammar['CFWS'] . '?)';
93: self::$_grammar['word'] = '(?:' . self::$_grammar['atom'] . '|' .
94: self::$_grammar['quoted-string'] . ')';
95: self::$_grammar['phrase'] = '(?:' . self::$_grammar['word'] . '+?)';
96: self::$_grammar['no-fold-quote'] = '(?:"(?:' . self::$_grammar['qtext'] .
97: '|' . self::$_grammar['quoted-pair'] . ')*")';
98: self::$_grammar['dtext'] = '(?:' . self::$_grammar['NO-WS-CTL'] .
99: '|[\x21-\x5A\x5E-\x7E])';
100: self::$_grammar['no-fold-literal'] = '(?:\[(?:' . self::$_grammar['dtext'] .
101: '|' . self::$_grammar['quoted-pair'] . ')*\])';
102:
103:
104: self::$_grammar['id-left'] = '(?:' . self::$_grammar['dot-atom-text'] . '|' .
105: self::$_grammar['no-fold-quote'] . ')';
106: self::$_grammar['id-right'] = '(?:' . self::$_grammar['dot-atom-text'] . '|' .
107: self::$_grammar['no-fold-literal'] . ')';
108:
109:
110: self::$_grammar['local-part'] = '(?:' . self::$_grammar['dot-atom'] . '|' .
111: self::$_grammar['quoted-string'] . ')';
112: self::$_grammar['dcontent'] = '(?:' . self::$_grammar['dtext'] . '|' .
113: self::$_grammar['quoted-pair'] . ')';
114: self::$_grammar['domain-literal'] = '(?:' . self::$_grammar['CFWS'] . '?\[(' .
115: self::$_grammar['FWS'] . '?' . self::$_grammar['dcontent'] . ')*?' .
116: self::$_grammar['FWS'] . '?\]' . self::$_grammar['CFWS'] . '?)';
117: self::$_grammar['domain'] = '(?:' . self::$_grammar['dot-atom'] . '|' .
118: self::$_grammar['domain-literal'] . ')';
119: self::$_grammar['addr-spec'] = '(?:' . self::$_grammar['local-part'] . '@' .
120: self::$_grammar['domain'] . ')';
121: }
122:
123: 124: 125: 126: 127:
128: public function getDefinition($name)
129: {
130: if (array_key_exists($name, self::$_grammar)) {
131: return self::$_grammar[$name];
132: } else {
133: throw new Swift_RfcComplianceException(
134: "No such grammar '" . $name . "' defined."
135: );
136: }
137: }
138:
139: 140: 141: 142:
143: public function getGrammarDefinitions()
144: {
145: return self::$_grammar;
146: }
147:
148: 149: 150: 151:
152: public function getSpecials()
153: {
154: return self::$_specials;
155: }
156:
157: 158: 159: 160: 161: 162: 163:
164: public function escapeSpecials($token, $include = array(), $exclude = array())
165: {
166: foreach (
167: array_merge(array('\\'), array_diff(self::$_specials, $exclude), $include) as $char)
168: {
169: $token = str_replace($char, '\\' . $char, $token);
170: }
171:
172: return $token;
173: }
174: }
175: