Rev 29 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 29 | Rev 31 | ||
---|---|---|---|
1 | <?php |
1 | <?php |
2 | 2 | ||
3 | /* |
3 | /* |
4 | * OID-Info.com API for PHP |
4 | * OID-Info.com API for PHP |
5 | * Copyright 2019-2022 Daniel Marschall, ViaThinkSoft |
5 | * Copyright 2019-2022 Daniel Marschall, ViaThinkSoft |
6 | * Version 2022-03-24 |
6 | * Version 2022-12-09 |
7 | * |
7 | * |
8 | * Licensed under the Apache License, Version 2.0 (the "License"); |
8 | * Licensed under the Apache License, Version 2.0 (the "License"); |
9 | * you may not use this file except in compliance with the License. |
9 | * you may not use this file except in compliance with the License. |
10 | * You may obtain a copy of the License at |
10 | * You may obtain a copy of the License at |
11 | * |
11 | * |
12 | * http://www.apache.org/licenses/LICENSE-2.0 |
12 | * http://www.apache.org/licenses/LICENSE-2.0 |
13 | * |
13 | * |
14 | * Unless required by applicable law or agreed to in writing, software |
14 | * Unless required by applicable law or agreed to in writing, software |
15 | * distributed under the License is distributed on an "AS IS" BASIS, |
15 | * distributed under the License is distributed on an "AS IS" BASIS, |
16 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
16 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
17 | * See the License for the specific language governing permissions and |
17 | * See the License for the specific language governing permissions and |
18 | * limitations under the License. |
18 | * limitations under the License. |
19 | */ |
19 | */ |
20 | 20 | ||
21 | // error_reporting(E_ALL | E_NOTICE | E_STRICT | E_DEPRECATED); |
21 | // error_reporting(E_ALL | E_NOTICE | E_STRICT | E_DEPRECATED); |
22 | 22 | ||
23 | if(!defined('STDIN')) define('STDIN', fopen('php://stdin', 'rb')); |
23 | if(!defined('STDIN')) define('STDIN', fopen('php://stdin', 'rb')); |
24 | if(!defined('STDOUT')) define('STDOUT', fopen('php://stdout', 'wb')); |
24 | if(!defined('STDOUT')) define('STDOUT', fopen('php://stdout', 'wb')); |
25 | if(!defined('STDERR')) define('STDERR', fopen('php://stderr', 'wb')); |
25 | if(!defined('STDERR')) define('STDERR', fopen('php://stderr', 'wb')); |
26 | 26 | ||
27 | if (file_exists(__DIR__ . '/oid_utils.inc.phps')) require_once __DIR__ . '/oid_utils.inc.phps'; |
27 | if (file_exists(__DIR__ . '/oid_utils.inc.phps')) require_once __DIR__ . '/oid_utils.inc.phps'; |
28 | if (file_exists(__DIR__ . '/oid_utils.inc.php')) require_once __DIR__ . '/oid_utils.inc.php'; |
28 | if (file_exists(__DIR__ . '/oid_utils.inc.php')) require_once __DIR__ . '/oid_utils.inc.php'; |
29 | if (file_exists(__DIR__ . '/xml_utils.inc.phps')) require_once __DIR__ . '/xml_utils.inc.phps'; |
29 | if (file_exists(__DIR__ . '/xml_utils.inc.phps')) require_once __DIR__ . '/xml_utils.inc.phps'; |
30 | if (file_exists(__DIR__ . '/xml_utils.inc.php')) require_once __DIR__ . '/xml_utils.inc.php'; |
30 | if (file_exists(__DIR__ . '/xml_utils.inc.php')) require_once __DIR__ . '/xml_utils.inc.php'; |
31 | if (file_exists(__DIR__ . '/../includes/oid_utils.inc.php')) require_once __DIR__ . '/../includes/oid_utils.inc.php'; |
31 | if (file_exists(__DIR__ . '/../includes/oid_utils.inc.php')) require_once __DIR__ . '/../includes/oid_utils.inc.php'; |
32 | if (file_exists(__DIR__ . '/../includes/xml_utils.inc.php')) require_once __DIR__ . '/../includes/xml_utils.inc.php'; |
32 | if (file_exists(__DIR__ . '/../includes/xml_utils.inc.php')) require_once __DIR__ . '/../includes/xml_utils.inc.php'; |
33 | if (file_exists(__DIR__ . '/../../includes/oid_utils.inc.php')) require_once __DIR__ . '/../../includes/oid_utils.inc.php'; |
33 | if (file_exists(__DIR__ . '/../../includes/oid_utils.inc.php')) require_once __DIR__ . '/../../includes/oid_utils.inc.php'; |
34 | if (file_exists(__DIR__ . '/../../includes/xml_utils.inc.php')) require_once __DIR__ . '/../../includes/xml_utils.inc.php'; |
34 | if (file_exists(__DIR__ . '/../../includes/xml_utils.inc.php')) require_once __DIR__ . '/../../includes/xml_utils.inc.php'; |
35 | if (file_exists(__DIR__ . '/../../../includes/oid_utils.inc.php')) require_once __DIR__ . '/../../../includes/oid_utils.inc.php'; |
35 | if (file_exists(__DIR__ . '/../../../includes/oid_utils.inc.php')) require_once __DIR__ . '/../../../includes/oid_utils.inc.php'; |
36 | if (file_exists(__DIR__ . '/../../../includes/xml_utils.inc.php')) require_once __DIR__ . '/../../../includes/xml_utils.inc.php'; |
36 | if (file_exists(__DIR__ . '/../../../includes/xml_utils.inc.php')) require_once __DIR__ . '/../../../includes/xml_utils.inc.php'; |
37 | 37 | ||
38 | class OIDInfoException extends Exception { |
38 | class OIDInfoException extends Exception { |
39 | } |
39 | } |
40 | 40 | ||
41 | class OIDInfoAPI { |
41 | class OIDInfoAPI { |
42 | 42 | ||
43 | # --- PART 0: Constants |
43 | # --- PART 0: Constants |
44 | 44 | ||
45 | // First digit of the ping result |
45 | // First digit of the ping result |
46 | // "-" = error |
46 | // "-" = error |
47 | // "0" = OID does not exist |
47 | // "0" = OID does not exist |
48 | // "1" = OID does exist, but is not approved yet |
48 | // "1" = OID does exist, but is not approved yet |
49 | // "2" = OID does exist and is accessible |
49 | // "2" = OID does exist and is accessible |
50 | /*private*/ const PING_IDX_EXISTS = 0; |
50 | /*private*/ const PING_IDX_EXISTS = 0; |
51 | 51 | ||
52 | // Second digit of the ping result |
52 | // Second digit of the ping result |
53 | // "-" = error |
53 | // "-" = error |
54 | // "0" = The OID may not be created |
54 | // "0" = The OID may not be created |
55 | // "1" = OID is not an illegal OID, and none of its ascendant is a leaf and its parent OID is not frozen |
55 | // "1" = OID is not an illegal OID, and none of its ascendant is a leaf and its parent OID is not frozen |
56 | /*private*/ const PING_IDX_MAY_CREATE = 1; |
56 | /*private*/ const PING_IDX_MAY_CREATE = 1; |
57 | 57 | ||
58 | /*private*/ const SOFT_CORRECT_BEHAVIOR_NONE = 0; |
58 | /*private*/ const SOFT_CORRECT_BEHAVIOR_NONE = 0; |
59 | /*private*/ const SOFT_CORRECT_BEHAVIOR_LOWERCASE_BEGINNING = 1; |
59 | /*private*/ const SOFT_CORRECT_BEHAVIOR_LOWERCASE_BEGINNING = 1; |
60 | /*private*/ const SOFT_CORRECT_BEHAVIOR_ALL_POSSIBLE = 2; |
60 | /*private*/ const SOFT_CORRECT_BEHAVIOR_ALL_POSSIBLE = 2; |
61 | 61 | ||
62 | /*public*/ const DEFAULT_ILLEGALITY_RULE_FILE = __DIR__ . '/oid_illegality_rules'; |
62 | /*public*/ const DEFAULT_ILLEGALITY_RULE_FILE = __DIR__ . '/oid_illegality_rules'; |
63 | 63 | ||
64 | # --- Part 1: "Ping API" for checking if OIDs are available or allowed to create |
64 | # --- Part 1: "Ping API" for checking if OIDs are available or allowed to create |
65 | 65 | ||
66 | public $verbosePingProviders = array('https://misc.daniel-marschall.de/oid-repository/ping_oid.php?oid={OID}'); |
66 | public $verbosePingProviders = array('https://misc.daniel-marschall.de/oid-repository/ping_oid.php?oid={OID}'); |
67 | 67 | ||
68 | private $pingCache = array(); |
68 | private $pingCache = array(); |
69 | 69 | ||
70 | public $pingCacheMaxAge = 3600; |
70 | public $pingCacheMaxAge = 3600; |
71 | 71 | ||
72 | public function clearPingCache() { |
72 | public function clearPingCache() { |
73 | $this->pingCache = array(); |
73 | $this->pingCache = array(); |
74 | } |
74 | } |
75 | 75 | ||
76 | public function checkOnlineExists($oid) { |
76 | public function checkOnlineExists($oid) { |
77 | if (!self::strictCheckSyntax($oid)) return false; |
77 | if (!self::strictCheckSyntax($oid)) return false; |
78 | 78 | ||
79 | $pingResult = $this->pingOID($oid); |
79 | $pingResult = $this->pingOID($oid); |
80 | $ret = $pingResult[self::PING_IDX_EXISTS] >= 1; |
80 | $ret = $pingResult[self::PING_IDX_EXISTS] >= 1; |
81 | return $ret; |
81 | return $ret; |
82 | } |
82 | } |
83 | 83 | ||
84 | public function checkOnlineAvailable($oid) { |
84 | public function checkOnlineAvailable($oid) { |
85 | if (!self::strictCheckSyntax($oid)) return false; |
85 | if (!self::strictCheckSyntax($oid)) return false; |
86 | 86 | ||
87 | $pingResult = $this->pingOID($oid); |
87 | $pingResult = $this->pingOID($oid); |
88 | $ret = $pingResult[self::PING_IDX_EXISTS] == 2; |
88 | $ret = $pingResult[self::PING_IDX_EXISTS] == 2; |
89 | return $ret; |
89 | return $ret; |
90 | } |
90 | } |
91 | 91 | ||
92 | public function checkOnlineAllowed($oid) { |
92 | public function checkOnlineAllowed($oid) { |
93 | if (!self::strictCheckSyntax($oid)) return false; |
93 | if (!self::strictCheckSyntax($oid)) return false; |
94 | 94 | ||
95 | $pingResult = $this->pingOID($oid); |
95 | $pingResult = $this->pingOID($oid); |
96 | return $pingResult[self::PING_IDX_MAY_CREATE] == 1; |
96 | return $pingResult[self::PING_IDX_MAY_CREATE] == 1; |
97 | } |
97 | } |
98 | 98 | ||
99 | public function checkOnlineMayCreate($oid) { |
99 | public function checkOnlineMayCreate($oid) { |
100 | if (!self::strictCheckSyntax($oid)) return false; |
100 | if (!self::strictCheckSyntax($oid)) return false; |
101 | 101 | ||
102 | $pingResult = $this->pingOID($oid); |
102 | $pingResult = $this->pingOID($oid); |
103 | 103 | ||
104 | // OID is either illegal, or one of their parents are leaf or frozen |
104 | // OID is either illegal, or one of their parents are leaf or frozen |
105 | # if (!checkOnlineAllowed($oid)) return false; |
105 | # if (!checkOnlineAllowed($oid)) return false; |
106 | if ($pingResult[self::PING_IDX_MAY_CREATE] == 0) return false; |
106 | if ($pingResult[self::PING_IDX_MAY_CREATE] == 0) return false; |
107 | 107 | ||
108 | // The OID exists already, so we don't need to create it again |
108 | // The OID exists already, so we don't need to create it again |
109 | # if ($this->checkOnlineExists($oid)) return false; |
109 | # if ($this->checkOnlineExists($oid)) return false; |
110 | if ($pingResult[self::PING_IDX_EXISTS] >= 1) return false; |
110 | if ($pingResult[self::PING_IDX_EXISTS] >= 1) return false; |
111 | 111 | ||
112 | return true; |
112 | return true; |
113 | } |
113 | } |
114 | 114 | ||
115 | protected function pingOID($oid) { |
115 | protected function pingOID($oid) { |
116 | if (isset($this->pingCache[$oid])) { |
116 | if (isset($this->pingCache[$oid])) { |
117 | $cacheAge = $this->pingCache[$oid][0] - time(); |
117 | $cacheAge = $this->pingCache[$oid][0] - time(); |
118 | if ($cacheAge <= $this->pingCacheMaxAge) { |
118 | if ($cacheAge <= $this->pingCacheMaxAge) { |
119 | return $this->pingCache[$oid][1]; |
119 | return $this->pingCache[$oid][1]; |
120 | } |
120 | } |
121 | } |
121 | } |
122 | 122 | ||
123 | if (count($this->verbosePingProviders) == 0) { |
123 | if (count($this->verbosePingProviders) == 0) { |
124 | throw new OIDInfoException("No verbose ping provider available!"); |
124 | throw new OIDInfoException("No verbose ping provider available!"); |
125 | } |
125 | } |
126 | 126 | ||
127 | $res = false; |
127 | $res = false; |
128 | foreach ($this->verbosePingProviders as $url) { |
128 | foreach ($this->verbosePingProviders as $url) { |
129 | $url = str_replace('{OID}', $oid, $url); |
129 | $url = str_replace('{OID}', $oid, $url); |
130 | $cn = @file_get_contents($url); |
130 | $cn = @file_get_contents($url); |
131 | if ($cn === false) continue; |
131 | if ($cn === false) continue; |
132 | $loc_res = trim($cn); |
132 | $loc_res = trim($cn); |
133 | if (strpos($loc_res, '-') === false) { |
133 | if (strpos($loc_res, '-') === false) { |
134 | $res = $loc_res; |
134 | $res = $loc_res; |
135 | break; |
135 | break; |
136 | } |
136 | } |
137 | } |
137 | } |
138 | if ($res === false) { |
138 | if ($res === false) { |
139 | throw new OIDInfoException("Could not ping OID $oid status!"); |
139 | throw new OIDInfoException("Could not ping OID $oid status!"); |
140 | } |
140 | } |
141 | 141 | ||
142 | // if ($this->pingCacheMaxAge >= 0) { |
142 | // if ($this->pingCacheMaxAge >= 0) { |
143 | $this->pingCache[$oid] = array(time(), $res); |
143 | $this->pingCache[$oid] = array(time(), $res); |
144 | //} |
144 | //} |
145 | 145 | ||
146 | return $res; |
146 | return $res; |
147 | } |
147 | } |
148 | 148 | ||
149 | # --- PART 2: Syntax checking |
149 | # --- PART 2: Syntax checking |
150 | 150 | ||
151 | public static function strictCheckSyntax($oid) { |
151 | public static function strictCheckSyntax($oid) { |
152 | return oid_valid_dotnotation($oid, false, false, 1); |
152 | return oid_valid_dotnotation($oid, false, false, 1); |
153 | } |
153 | } |
154 | 154 | ||
155 | // Returns false if $oid has wrong syntax |
155 | // Returns false if $oid has wrong syntax |
156 | // Return an OID without leading dot or zeroes, if the syntax is acceptable |
156 | // Return an OID without leading dot or zeroes, if the syntax is acceptable |
157 | public static function trySanitizeOID($oid) { |
157 | public static function trySanitizeOID($oid) { |
158 | // Allow leading dots and leading zeroes, but remove then afterwards |
158 | // Allow leading dots and leading zeroes, but remove then afterwards |
159 | $ok = oid_valid_dotnotation($oid, true, true, 1); |
159 | $ok = oid_valid_dotnotation($oid, true, true, 1); |
160 | if ($ok === false) return false; |
160 | if ($ok === false) return false; |
161 | 161 | ||
162 | return sanitizeOID($oid, $oid[0] == '.'); |
162 | return sanitizeOID($oid, $oid[0] == '.'); |
163 | } |
163 | } |
164 | 164 | ||
165 | # --- PART 3: XML file creation |
165 | # --- PART 3: XML file creation |
166 | 166 | ||
167 | protected static function eMailValid($email) { |
167 | protected static function eMailValid($email) { |
168 | # TODO: use isemail project |
168 | # TODO: use isemail project |
169 | 169 | ||
170 | if (empty($email)) return false; |
170 | if (empty($email)) return false; |
171 | 171 | ||
172 | if (strpos($email, '@') === false) return false; |
172 | if (strpos($email, '@') === false) return false; |
173 | 173 | ||
174 | $ary = explode('@', $email, 2); |
174 | $ary = explode('@', $email, 2); |
175 | if (!isset($ary[1])) return false; |
175 | if (!isset($ary[1])) return false; |
176 | if (strpos($ary[1], '.') === false) return false; |
176 | if (strpos($ary[1], '.') === false) return false; |
177 | 177 | ||
178 | return true; |
178 | return true; |
179 | } |
179 | } |
180 | 180 | ||
181 | public function softCorrectEMail($email, $params) { |
181 | public function softCorrectEMail($email, $params) { |
182 | $params = $this->init_params($params); |
182 | $params = $this->init_params($params); |
183 | 183 | ||
184 | $email = str_replace(' ', '', $email); |
184 | $email = str_replace(' ', '', $email); |
185 | $email = str_replace('&', '@', $email); |
185 | $email = str_replace('&', '@', $email); |
186 | $email = str_replace('(at)', '@', $email); |
186 | $email = str_replace('(at)', '@', $email); |
187 | $email = str_replace('[at]', '@', $email); |
187 | $email = str_replace('[at]', '@', $email); |
188 | $email = str_replace('(dot)', '.', $email); |
188 | $email = str_replace('(dot)', '.', $email); |
189 | $email = str_replace('[dot]', '.', $email); |
189 | $email = str_replace('[dot]', '.', $email); |
190 | $email = trim($email); |
190 | $email = trim($email); |
191 | 191 | ||
192 | if (!$params['allow_illegal_email'] && !self::eMailValid($email)) { |
192 | if (!$params['allow_illegal_email'] && !self::eMailValid($email)) { |
193 | return ''; |
193 | return ''; |
194 | } |
194 | } |
195 | 195 | ||
196 | return $email; |
196 | return $email; |
197 | } |
197 | } |
198 | 198 | ||
199 | public function softCorrectPhone($phone, $params) { |
199 | public function softCorrectPhone($phone, $params) { |
200 | $params = $this->init_params($params); |
200 | $params = $this->init_params($params); |
201 | 201 | ||
202 | // TODO: if no "+", add "+1" , but only if address is in USA |
202 | // TODO: if no "+", add "+1" , but only if address is in USA |
203 | // TODO: or use param to fixate country if it is not known |
203 | // TODO: or use param to fixate country if it is not known |
204 | /* |
204 | /* |
205 | NOTE: with german phone numbers, this will cause trouble, even if we assume "+49" |
205 | NOTE: with german phone numbers, this will cause trouble, even if we assume "+49" |
206 | 06223 / 1234 |
206 | 06223 / 1234 |
207 | shall be |
207 | shall be |
208 | +49 6223 1234 |
208 | +49 6223 1234 |
209 | and not |
209 | and not |
210 | +49 06223 1234 |
210 | +49 06223 1234 |
211 | */ |
211 | */ |
212 | 212 | ||
213 | $phone = str_replace('-', ' ', $phone); |
213 | $phone = str_replace('-', ' ', $phone); |
214 | $phone = str_replace('.', ' ', $phone); |
214 | $phone = str_replace('.', ' ', $phone); |
215 | $phone = str_replace('/', ' ', $phone); |
215 | $phone = str_replace('/', ' ', $phone); |
216 | $phone = str_replace('(', ' ', $phone); |
216 | $phone = str_replace('(', ' ', $phone); |
217 | $phone = str_replace(')', ' ', $phone); |
217 | $phone = str_replace(')', ' ', $phone); |
218 | 218 | ||
219 | // HL7 registry has included this accidently |
219 | // HL7 registry has included this accidently |
220 | $phone = str_replace('"', '', $phone); |
220 | $phone = str_replace('"', '', $phone); |
221 | 221 | ||
222 | $phone = trim($phone); |
222 | $phone = trim($phone); |
223 | 223 | ||
224 | return $phone; |
224 | return $phone; |
225 | } |
225 | } |
226 | 226 | ||
227 | private static function strip_to_xhtml_light($str, $allow_strong_text=false) { |
227 | private static function strip_to_xhtml_light($str, $allow_strong_text=false) { |
228 | // <strong> is allowed in the XSD, but not <b> |
228 | // <strong> is allowed in the XSD, but not <b> |
229 | $str = str_ireplace('<b>', '<strong>', $str); |
229 | $str = str_ireplace('<b>', '<strong>', $str); |
230 | $str = str_ireplace('</b>', '</strong>', $str); |
230 | $str = str_ireplace('</b>', '</strong>', $str); |
231 | 231 | ||
232 | if (!$allow_strong_text) { |
232 | if (!$allow_strong_text) { |
233 | // <strong> is only used for very important things like the word "deprecated". It should therefore not used for anything else |
233 | // <strong> is only used for very important things like the word "deprecated". It should therefore not used for anything else |
234 | $str = str_ireplace('<strong>', '', $str); |
234 | $str = str_ireplace('<strong>', '', $str); |
235 | $str = str_ireplace('</strong>', '', $str); |
235 | $str = str_ireplace('</strong>', '', $str); |
236 | } |
236 | } |
237 | 237 | ||
238 | $str = preg_replace('@<\s*script.+<\s*/script.*>@isU', '', $str); |
238 | $str = preg_replace('@<\s*script.+<\s*/script.*>@isU', '', $str); |
239 | $str = preg_replace('@<\s*style.+<\s*/style.*>@isU', '', $str); |
239 | $str = preg_replace('@<\s*style.+<\s*/style.*>@isU', '', $str); |
240 | 240 | ||
241 | $str = preg_replace_callback( |
241 | $str = preg_replace_callback( |
242 | '@<(\s*/{0,1}\d*)([^\s/>]+)(\s*[^>]*)>@i', |
242 | '@<(\s*/{0,1}\d*)([^\s/>]+)(\s*[^>]*)>@i', |
243 | function ($treffer) { |
243 | function ($treffer) { |
244 | // see http://oid-info.com/xhtml-light.xsd |
244 | // see http://oid-info.com/xhtml-light.xsd |
245 | $whitelist = array('a', 'br', 'code', 'em', 'font', 'img', 'li', 'strong', 'sub', 'sup', 'ul'); |
245 | $whitelist = array('a', 'br', 'code', 'em', 'font', 'img', 'li', 'strong', 'sub', 'sup', 'ul'); |
246 | 246 | ||
247 | $pre = $treffer[1]; |
247 | $pre = $treffer[1]; |
248 | $tag = $treffer[2]; |
248 | $tag = $treffer[2]; |
249 | $attrib = $treffer[3]; |
249 | $attrib = $treffer[3]; |
250 | if (in_array($tag, $whitelist)) { |
250 | if (in_array($tag, $whitelist)) { |
251 | return '<'.$pre.$tag.$attrib.'>'; |
251 | return '<'.$pre.$tag.$attrib.'>'; |
252 | } else { |
252 | } else { |
253 | return ''; |
253 | return ''; |
254 | } |
254 | } |
255 | }, $str); |
255 | }, $str); |
256 | 256 | ||
257 | return $str; |
257 | return $str; |
258 | } |
258 | } |
259 | 259 | ||
260 | const OIDINFO_CORRECT_DESC_OPTIONAL_ENDING_DOT = 0; |
260 | const OIDINFO_CORRECT_DESC_OPTIONAL_ENDING_DOT = 0; |
261 | const OIDINFO_CORRECT_DESC_ENFORCE_ENDING_DOT = 1; |
261 | const OIDINFO_CORRECT_DESC_ENFORCE_ENDING_DOT = 1; |
262 | const OIDINFO_CORRECT_DESC_DISALLOW_ENDING_DOT = 2; |
262 | const OIDINFO_CORRECT_DESC_DISALLOW_ENDING_DOT = 2; |
263 | 263 | ||
264 | public function correctDesc($desc, $params, $ending_dot_policy=self::OIDINFO_CORRECT_DESC_OPTIONAL_ENDING_DOT, $enforce_xhtml_light=false) { |
264 | public function correctDesc($desc, $params, $ending_dot_policy=self::OIDINFO_CORRECT_DESC_OPTIONAL_ENDING_DOT, $enforce_xhtml_light=false) { |
265 | $params = $this->init_params($params); |
265 | $params = $this->init_params($params); |
266 | 266 | ||
267 | $desc = trim($desc); |
267 | $desc = trim($desc); |
268 | 268 | ||
269 | $desc = preg_replace('@<!\\[CDATA\\[(.+)\\]\\]>@ismU', '\\1', $desc); |
269 | $desc = preg_replace('@<!\\[CDATA\\[(.+)\\]\\]>@ismU', '\\1', $desc); |
270 | 270 | ||
271 | if (substr_count($desc, '>') != substr_count($desc, '<')) { |
271 | if (substr_count($desc, '>') != substr_count($desc, '<')) { |
272 | $params['allow_html'] = false; |
272 | $params['allow_html'] = false; |
273 | } |
273 | } |
274 | 274 | ||
275 | $desc = str_replace("\r", '', $desc); |
275 | $desc = str_replace("\r", '', $desc); |
276 | 276 | ||
277 | if (!$params['allow_html']) { |
277 | if (!$params['allow_html']) { |
278 | // htmlentities_numeric() does this for us |
278 | // htmlentities_numeric() does this for us |
279 | /* |
279 | /* |
280 | $desc = str_replace('&', '&', $desc); |
280 | $desc = str_replace('&', '&', $desc); |
281 | $desc = str_replace('<', '<', $desc); |
281 | $desc = str_replace('<', '<', $desc); |
282 | $desc = str_replace('>', '>', $desc); |
282 | $desc = str_replace('>', '>', $desc); |
283 | $desc = str_replace('"', '"', $desc); |
283 | $desc = str_replace('"', '"', $desc); |
284 | $desc = str_replace("'", ''', $desc); // ' is not HTML. It is XML |
284 | $desc = str_replace("'", ''', $desc); // ' is not HTML. It is XML |
285 | */ |
285 | */ |
286 | 286 | ||
287 | $desc = str_replace("\n", '<br />', $desc); |
287 | $desc = str_replace("\n", '<br />', $desc); |
288 | } else { |
288 | } else { |
289 | // Some problems we had with HL7 registry |
289 | // Some problems we had with HL7 registry |
290 | $desc = preg_replace('@<(/{0,1}(p|i|b|u|ul|li))>@ismU', '<\\1>', $desc); |
290 | $desc = preg_replace('@<(/{0,1}(p|i|b|u|ul|li))>@ismU', '<\\1>', $desc); |
291 | # preg_match_all('@<[^ :\\@]+>@ismU', $desc, $m); |
291 | # preg_match_all('@<[^ :\\@]+>@ismU', $desc, $m); |
292 | # if (count($m[0]) > 0) print_r($m); |
292 | # if (count($m[0]) > 0) print_r($m); |
293 | 293 | ||
294 | $desc = preg_replace('@<i>(.+)<i/>@ismU', '<i>\\1</i>', $desc); |
294 | $desc = preg_replace('@<i>(.+)<i/>@ismU', '<i>\\1</i>', $desc); |
295 | $desc = str_replace('<p><p>', '</p><p>', $desc); |
295 | $desc = str_replace('<p><p>', '</p><p>', $desc); |
296 | 296 | ||
297 | // <p> are not supported by oid-info.com |
297 | // <p> are not supported by oid-info.com |
298 | $desc = str_replace('<p>', '<br /><br />', $desc); |
298 | $desc = str_replace('<p>', '<br /><br />', $desc); |
299 | $desc = str_replace('</p>', '', $desc); |
299 | $desc = str_replace('</p>', '', $desc); |
300 | } |
300 | } |
301 | 301 | ||
302 | // Escape unicode characters as numeric &#...; |
302 | // Escape unicode characters as numeric &#...; |
303 | // The XML 1.0 standard does only has a few entities, but nothing like e.g. € , so we prefer numeric |
303 | // The XML 1.0 standard does only has a few entities, but nothing like e.g. € , so we prefer numeric |
304 | 304 | ||
305 | //$desc = htmlentities_numeric($desc, $params['allow_html']); |
305 | //$desc = htmlentities_numeric($desc, $params['allow_html']); |
306 | if (!$params['allow_html']) $desc = htmlentities($desc); |
306 | if (!$params['allow_html']) $desc = htmlentities($desc); |
307 | $desc = html_named_to_numeric_entities($desc); |
307 | $desc = html_named_to_numeric_entities($desc); |
308 | 308 | ||
309 | // Remove HTML tags which are not allowed |
309 | // Remove HTML tags which are not allowed |
310 | if ($params['allow_html'] && (!$params['ignore_xhtml_light']) && $enforce_xhtml_light) { |
310 | if ($params['allow_html'] && (!$params['ignore_xhtml_light']) && $enforce_xhtml_light) { |
311 | // oid-info.com does only allow a few HTML tags |
311 | // oid-info.com does only allow a few HTML tags |
312 | // see http://oid-info.com/xhtml-light.xsd |
312 | // see http://oid-info.com/xhtml-light.xsd |
313 | $desc = self::strip_to_xhtml_light($desc); |
313 | $desc = self::strip_to_xhtml_light($desc); |
314 | } |
314 | } |
315 | 315 | ||
316 | // Solve some XML problems... |
316 | // Solve some XML problems... |
317 | $desc = preg_replace('@<\s*br\s*>@ismU', '<br/>', $desc); // auto close <br> |
317 | $desc = preg_replace('@<\s*br\s*>@ismU', '<br/>', $desc); // auto close <br> |
318 | $desc = preg_replace('@(href\s*=\s*)(["\'])(.*)&([^#].*)(\2)@ismU', '\1\2\3&\4\5', $desc); // fix "&" inside href-URLs to & |
318 | $desc = preg_replace('@(href\s*=\s*)(["\'])(.*)&([^#].*)(\2)@ismU', '\1\2\3&\4\5', $desc); // fix "&" inside href-URLs to & |
319 | // TODO: what do we do if there are more XHTML errors (e.g. additional open tags) which would make the XML invalid? |
319 | // TODO: what do we do if there are more XHTML errors (e.g. additional open tags) which would make the XML invalid? |
320 | 320 | ||
321 | // "Trim" <br/> |
321 | // "Trim" <br/> |
322 | $count = 0; |
322 | $count = 0; |
323 | do { $desc = preg_replace('@^\s*<\s*br\s*/{0,1}\s*>@isU', '', $desc, -1, $count); } while ($count > 0); // left trim |
323 | do { $desc = preg_replace('@^\s*<\s*br\s*/{0,1}\s*>@isU', '', $desc, -1, $count); } while ($count > 0); // left trim |
324 | do { $desc = preg_replace('@<\s*br\s*/{0,1}\s*>\s*$@isU', '', $desc, -1, $count); } while ($count > 0); // right trim |
324 | do { $desc = preg_replace('@<\s*br\s*/{0,1}\s*>\s*$@isU', '', $desc, -1, $count); } while ($count > 0); // right trim |
325 | 325 | ||
326 | // Correct double-encoded stuff |
326 | // Correct double-encoded stuff |
327 | if (!isset($params['tolerant_htmlentities']) || $params['tolerant_htmlentities']) { |
327 | if (!isset($params['tolerant_htmlentities']) || $params['tolerant_htmlentities']) { |
328 | do { |
328 | do { |
329 | $old_desc = $desc; |
329 | $old_desc = $desc; |
330 | # Full list of entities: https://www.freeformatter.com/html-entities.html |
330 | # Full list of entities: https://www.freeformatter.com/html-entities.html |
331 | # Max: 8 chars ( ϑ ) |
331 | # Max: 8 chars ( ϑ ) |
332 | # Min: 2 chars ( lt,gt,ni,or,ne,le,ge,Mu,Nu,Xi,Pi,mu,nu,xi,pi ) |
332 | # Min: 2 chars ( lt,gt,ni,or,ne,le,ge,Mu,Nu,Xi,Pi,mu,nu,xi,pi ) |
333 | $desc = preg_replace('@(&|&)(#|#)(\d+);@ismU', '&#\3;', $desc); |
333 | $desc = preg_replace('@(&|&)(#|#)(\d+);@ismU', '&#\3;', $desc); |
334 | $desc = preg_replace('@(&|&)([a-zA-Z0-9]{2,8});@ismU', '&\2;', $desc); |
334 | $desc = preg_replace('@(&|&)([a-zA-Z0-9]{2,8});@ismU', '&\2;', $desc); |
335 | } while ($old_desc != $desc); |
335 | } while ($old_desc != $desc); |
336 | } |
336 | } |
337 | 337 | ||
338 | // TODO: use the complete list of oid-info.com |
338 | // TODO: use the complete list of oid-info.com |
339 | // TODO: Make this step optional using $params |
339 | // TODO: Make this step optional using $params |
340 | /* |
340 | /* |
341 | Array |
341 | Array |
342 | ( |
342 | ( |
343 | [0] => Root OID for |
343 | [0] => Root OID for |
344 | [1] => OID for |
344 | [1] => OID for |
345 | [2] => OID identifying |
345 | [2] => OID identifying |
346 | [3] => Top arc for |
346 | [3] => Top arc for |
347 | [4] => Arc for |
347 | [4] => Arc for |
348 | [5] => arc root |
348 | [5] => arc root |
349 | [6] => Node for |
349 | [6] => Node for |
350 | [7] => Leaf node for |
350 | [7] => Leaf node for |
351 | [8] => This OID describes |
351 | [8] => This OID describes |
352 | [9] => [tT]his oid |
352 | [9] => [tT]his oid |
353 | [10] => This arc describes |
353 | [10] => This arc describes |
354 | [11] => This identifies |
354 | [11] => This identifies |
355 | [12] => Identifies a |
355 | [12] => Identifies a |
356 | [13] => [Oo]bject [Ii]dentifier |
356 | [13] => [Oo]bject [Ii]dentifier |
357 | [14] => Identifier for |
357 | [14] => Identifier for |
358 | [15] => This [Ii]dentifier is for |
358 | [15] => This [Ii]dentifier is for |
359 | [16] => Identifiers used by |
359 | [16] => Identifiers used by |
360 | [17] => identifier$ |
360 | [17] => identifier$ |
361 | [18] => This branch |
361 | [18] => This branch |
362 | [19] => Branch for |
362 | [19] => Branch for |
363 | [20] => Child tree for |
363 | [20] => Child tree for |
364 | [21] => Child for |
364 | [21] => Child for |
365 | [22] => Subtree for |
365 | [22] => Subtree for |
366 | [23] => Sub-OID |
366 | [23] => Sub-OID |
367 | [24] => Tree for |
367 | [24] => Tree for |
368 | [25] => Child object |
368 | [25] => Child object |
369 | [26] => Parent OID |
369 | [26] => Parent OID |
370 | [27] => root for |
370 | [27] => root for |
371 | [28] => Assigned for |
371 | [28] => Assigned for |
372 | [29] => Used to identify |
372 | [29] => Used to identify |
373 | [30] => Used in |
373 | [30] => Used in |
374 | [31] => Used for |
374 | [31] => Used for |
375 | [32] => For use by |
375 | [32] => For use by |
376 | [33] => Entry for |
376 | [33] => Entry for |
377 | [34] => This is for |
377 | [34] => This is for |
378 | [35] => ["]?OID["]? |
378 | [35] => ["]?OID["]? |
379 | [36] => ^OID |
379 | [36] => ^OID |
380 | [37] => OID$ |
380 | [37] => OID$ |
381 | [38] => oid |
381 | [38] => oid |
382 | [39] => oid$ |
382 | [39] => oid$ |
383 | [40] => OIDs |
383 | [40] => OIDs |
384 | ) |
384 | ) |
385 | $x = 'Root OID for ; OID for ; OID identifying ; Top arc for ; Arc for ; arc root; Node for ; Leaf node for ; This OID describes ; [tT]his oid ; This arc describes ; This identifies ; Identifies a ; [Oo]bject [Ii]dentifier; Identifier for ; This [Ii]dentifier is for ; Identifiers used by ; identifier$; This branch ; Branch for ; Child tree for ; Child for ; Subtree for ; Sub-OID; Tree for ; Child object; Parent OID; root for ; Assigned for ; Used to identify ; Used in ; Used for ; For use by ; Entry for ; This is for ; ["]?OID["]? ; ^OID ; OID$; oid ; oid$; OIDs'; |
385 | $x = 'Root OID for ; OID for ; OID identifying ; Top arc for ; Arc for ; arc root; Node for ; Leaf node for ; This OID describes ; [tT]his oid ; This arc describes ; This identifies ; Identifies a ; [Oo]bject [Ii]dentifier; Identifier for ; This [Ii]dentifier is for ; Identifiers used by ; identifier$; This branch ; Branch for ; Child tree for ; Child for ; Subtree for ; Sub-OID; Tree for ; Child object; Parent OID; root for ; Assigned for ; Used to identify ; Used in ; Used for ; For use by ; Entry for ; This is for ; ["]?OID["]? ; ^OID ; OID$; oid ; oid$; OIDs'; |
386 | $ary = explode('; ', $x); |
386 | $ary = explode('; ', $x); |
387 | print_r($ary); |
387 | print_r($ary); |
388 | */ |
388 | */ |
389 | $desc = preg_replace("@^Root OID for the @i", '', $desc); |
389 | $desc = preg_replace("@^Root OID for the @i", '', $desc); |
390 | $desc = preg_replace("@^Root OID for @i", '', $desc); |
390 | $desc = preg_replace("@^Root OID for @i", '', $desc); |
391 | $desc = preg_replace("@^OID root for the @i", '', $desc); |
391 | $desc = preg_replace("@^OID root for the @i", '', $desc); |
392 | $desc = preg_replace("@^OID root for @i", '', $desc); |
392 | $desc = preg_replace("@^OID root for @i", '', $desc); |
393 | $desc = preg_replace("@^This OID will be used for @i", '', $desc); |
393 | $desc = preg_replace("@^This OID will be used for @i", '', $desc); |
394 | $desc = preg_replace("@^This will be a generic OID for the @i", '', $desc); |
394 | $desc = preg_replace("@^This will be a generic OID for the @i", '', $desc); |
395 | $desc = preg_replace("@^OID for @i", '', $desc); |
395 | $desc = preg_replace("@^OID for @i", '', $desc); |
396 | $desc = preg_replace("@ Root OID$@i", '', $desc); |
396 | $desc = preg_replace("@ Root OID$@i", '', $desc); |
397 | $desc = preg_replace("@ OID$@i", '', $desc); |
397 | $desc = preg_replace("@ OID$@i", '', $desc); |
398 | $desc = preg_replace("@ OID Namespace$@i", '', $desc); |
398 | $desc = preg_replace("@ OID Namespace$@i", '', $desc); |
399 | $desc = preg_replace("@^OID for @i", '', $desc); |
399 | $desc = preg_replace("@^OID for @i", '', $desc); |
400 | $desc = preg_replace("@OID root$@i", '', $desc); |
400 | $desc = preg_replace("@OID root$@i", '', $desc); |
401 | $desc = preg_replace("@Object Identifier$@i", '', $desc); |
401 | $desc = preg_replace("@Object Identifier$@i", '', $desc); |
402 | $desc = preg_replace("@^The @i", '', $desc); |
402 | $desc = preg_replace("@^The @i", '', $desc); |
403 | 403 | ||
404 | $desc = rtrim($desc); |
404 | $desc = rtrim($desc); |
405 | if ($ending_dot_policy == self::OIDINFO_CORRECT_DESC_ENFORCE_ENDING_DOT) { |
405 | if ($ending_dot_policy == self::OIDINFO_CORRECT_DESC_ENFORCE_ENDING_DOT) { |
406 | if (($desc != '') && (substr($desc, -1)) != '.') $desc .= '.'; |
406 | if (($desc != '') && (substr($desc, -1)) != '.') $desc .= '.'; |
407 | } else if ($ending_dot_policy == self::OIDINFO_CORRECT_DESC_DISALLOW_ENDING_DOT) { |
407 | } else if ($ending_dot_policy == self::OIDINFO_CORRECT_DESC_DISALLOW_ENDING_DOT) { |
408 | $desc = preg_replace('@\\.$@', '', $desc); |
408 | $desc = preg_replace('@\\.$@', '', $desc); |
409 | } |
409 | } |
410 | 410 | ||
411 | // Required for XML importer of oid-info.com (E-Mail 09.12.2021) |
411 | // Required for XML importer of oid-info.com (E-Mail 09.12.2021) |
412 | $desc = str_replace('&', '&amp;', $desc); |
412 | $desc = str_replace('&', '&amp;', $desc); |
413 | 413 | ||
414 | return $desc; |
414 | return $desc; |
415 | } |
415 | } |
416 | 416 | ||
417 | public function xmlAddHeader($firstName, $lastName, $email) { |
417 | public function xmlAddHeader($firstName, $lastName, $email) { |
418 | // TODO: encode |
418 | // TODO: encode |
419 | 419 | ||
420 | $firstName = htmlentities_numeric($firstName); |
420 | $firstName = htmlentities_numeric($firstName); |
421 | if (empty($firstName)) { |
421 | if (empty($firstName)) { |
422 | throw new OIDInfoException("Please supply a first name"); |
422 | throw new OIDInfoException("Please supply a first name"); |
423 | } |
423 | } |
424 | 424 | ||
425 | $lastName = htmlentities_numeric($lastName); |
425 | $lastName = htmlentities_numeric($lastName); |
426 | if (empty($lastName)) { |
426 | if (empty($lastName)) { |
427 | throw new OIDInfoException("Please supply a last name"); |
427 | throw new OIDInfoException("Please supply a last name"); |
428 | } |
428 | } |
429 | 429 | ||
430 | $email = htmlentities_numeric($email); |
430 | $email = htmlentities_numeric($email); |
431 | if (empty($email)) { |
431 | if (empty($email)) { |
432 | throw new OIDInfoException("Please supply an email address"); |
432 | throw new OIDInfoException("Please supply an email address"); |
433 | } |
433 | } |
434 | 434 | ||
435 | // $out = "<!DOCTYPE oid-database>\n\n"; |
435 | // $out = "<!DOCTYPE oid-database>\n\n"; |
436 | $out = '<?xml version="1.0" encoding="UTF-8" ?>'."\n"; |
436 | $out = '<?xml version="1.0" encoding="UTF-8" ?>'."\n"; |
437 | $out .= '<oid-database xmlns="http://oid-info.com"'."\n"; |
437 | $out .= '<oid-database xmlns="http://oid-info.com"'."\n"; |
438 | $out .= ' xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"'."\n"; |
438 | $out .= ' xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"'."\n"; |
439 | $out .= ' xsi:schemaLocation="http://oid-info.com '."\n"; |
439 | $out .= ' xsi:schemaLocation="http://oid-info.com '."\n"; |
440 | $out .= ' http://oid-info.com/oid.xsd">'."\n"; |
440 | $out .= ' http://oid-info.com/oid.xsd">'."\n"; |
441 | $out .= "\t<submitter>\n"; |
441 | $out .= "\t<submitter>\n"; |
442 | $out .= "\t\t<first-name>$firstName</first-name>\n"; |
442 | $out .= "\t\t<first-name>$firstName</first-name>\n"; |
443 | $out .= "\t\t<last-name>$lastName</last-name>\n"; |
443 | $out .= "\t\t<last-name>$lastName</last-name>\n"; |
444 | $out .= "\t\t<email>$email</email>\n"; |
444 | $out .= "\t\t<email>$email</email>\n"; |
445 | $out .= "\t</submitter>\n"; |
445 | $out .= "\t</submitter>\n"; |
446 | 446 | ||
447 | if (!self::eMailValid($email)) { |
447 | if (!self::eMailValid($email)) { |
448 | throw new OIDInfoException("eMail address '$email' is invalid"); |
448 | throw new OIDInfoException("eMail address '$email' is invalid"); |
449 | } |
449 | } |
450 | 450 | ||
451 | return $out; |
451 | return $out; |
452 | } |
452 | } |
453 | 453 | ||
454 | public function xmlAddFooter() { |
454 | public function xmlAddFooter() { |
455 | return "</oid-database>\n"; |
455 | return "</oid-database>\n"; |
456 | } |
456 | } |
457 | 457 | ||
458 | /* |
458 | /* |
459 | -- CODE TEMPLATE -- |
459 | -- CODE TEMPLATE -- |
460 | 460 | ||
461 | $params['allow_html'] = false; // Allow HTML in <description> and <information> |
461 | $params['allow_html'] = false; // Allow HTML in <description> and <information> |
462 | $params['allow_illegal_email'] = true; // We should allow it, because we don't know if the user has some kind of human-readable anti-spam technique |
462 | $params['allow_illegal_email'] = true; // We should allow it, because we don't know if the user has some kind of human-readable anti-spam technique |
463 | $params['soft_correct_behavior'] = OIDInfoAPI::SOFT_CORRECT_BEHAVIOR_NONE; |
463 | $params['soft_correct_behavior'] = OIDInfoAPI::SOFT_CORRECT_BEHAVIOR_NONE; |
464 | $params['do_online_check'] = false; // Flag to disable this online check, because it generates a lot of traffic and runtime. |
464 | $params['do_online_check'] = false; // Flag to disable this online check, because it generates a lot of traffic and runtime. |
465 | $params['do_illegality_check'] = true; |
465 | $params['do_illegality_check'] = true; |
466 | $params['do_simpleping_check'] = true; |
466 | $params['do_simpleping_check'] = true; |
467 | $params['auto_extract_name'] = ''; |
467 | $params['auto_extract_name'] = ''; |
468 | $params['auto_extract_url'] = ''; |
468 | $params['auto_extract_url'] = ''; |
469 | $params['always_output_comment'] = false; // Also output comment if there was an error (e.g. OID already existing) |
469 | $params['always_output_comment'] = false; // Also output comment if there was an error (e.g. OID already existing) |
470 | $params['creation_allowed_check'] = true; |
470 | $params['creation_allowed_check'] = true; |
471 | $params['tolerant_htmlentities'] = true; |
471 | $params['tolerant_htmlentities'] = true; |
472 | $params['ignore_xhtml_light'] = false; |
472 | $params['ignore_xhtml_light'] = false; |
473 | 473 | ||
474 | $elements['synonymous-identifier'] = ''; // string or array |
474 | $elements['synonymous-identifier'] = ''; // string or array |
475 | $elements['description'] = ''; |
475 | $elements['description'] = ''; |
476 | $elements['information'] = ''; |
476 | $elements['information'] = ''; |
477 | 477 | ||
478 | $elements['first-registrant']['first-name'] = ''; |
478 | $elements['first-registrant']['first-name'] = ''; |
479 | $elements['first-registrant']['last-name'] = ''; |
479 | $elements['first-registrant']['last-name'] = ''; |
480 | $elements['first-registrant']['address'] = ''; |
480 | $elements['first-registrant']['address'] = ''; |
481 | $elements['first-registrant']['email'] = ''; |
481 | $elements['first-registrant']['email'] = ''; |
482 | $elements['first-registrant']['phone'] = ''; |
482 | $elements['first-registrant']['phone'] = ''; |
483 | $elements['first-registrant']['fax'] = ''; |
483 | $elements['first-registrant']['fax'] = ''; |
484 | $elements['first-registrant']['creation-date'] = ''; |
484 | $elements['first-registrant']['creation-date'] = ''; |
485 | 485 | ||
486 | $elements['current-registrant']['first-name'] = ''; |
486 | $elements['current-registrant']['first-name'] = ''; |
487 | $elements['current-registrant']['last-name'] = ''; |
487 | $elements['current-registrant']['last-name'] = ''; |
488 | $elements['current-registrant']['address'] = ''; |
488 | $elements['current-registrant']['address'] = ''; |
489 | $elements['current-registrant']['email'] = ''; |
489 | $elements['current-registrant']['email'] = ''; |
490 | $elements['current-registrant']['phone'] = ''; |
490 | $elements['current-registrant']['phone'] = ''; |
491 | $elements['current-registrant']['fax'] = ''; |
491 | $elements['current-registrant']['fax'] = ''; |
492 | $elements['current-registrant']['modification-date'] = ''; |
492 | $elements['current-registrant']['modification-date'] = ''; |
493 | 493 | ||
494 | $oid = '1.2.3'; |
494 | $oid = '1.2.3'; |
495 | 495 | ||
496 | $comment = 'test'; |
496 | $comment = 'test'; |
497 | 497 | ||
498 | echo $oa->createXMLEntry($oid, $elements, $params, $comment); |
498 | echo $oa->createXMLEntry($oid, $elements, $params, $comment); |
499 | */ |
499 | */ |
500 | private function init_params($params) { |
500 | private function init_params($params) { |
501 | // Backward compatibility |
501 | // Backward compatibility |
502 | if (!isset($params['do_csv_check'])) $params['do_simpleping_check'] = true; |
502 | if (!isset($params['do_csv_check'])) $params['do_simpleping_check'] = true; |
503 | 503 | ||
504 | // Set default behavior |
504 | // Set default behavior |
505 | if (!isset($params['allow_html'])) $params['allow_html'] = false; // Allow HTML in <description> and <information> |
505 | if (!isset($params['allow_html'])) $params['allow_html'] = false; // Allow HTML in <description> and <information> |
506 | if (!isset($params['allow_illegal_email'])) $params['allow_illegal_email'] = true; // We should allow it, because we don't know if the user has some kind of human-readable anti-spam technique |
506 | if (!isset($params['allow_illegal_email'])) $params['allow_illegal_email'] = true; // We should allow it, because we don't know if the user has some kind of human-readable anti-spam technique |
507 | if (!isset($params['soft_correct_behavior'])) $params['soft_correct_behavior'] = self::SOFT_CORRECT_BEHAVIOR_NONE; |
507 | if (!isset($params['soft_correct_behavior'])) $params['soft_correct_behavior'] = self::SOFT_CORRECT_BEHAVIOR_NONE; |
508 | if (!isset($params['do_online_check'])) $params['do_online_check'] = false; // Flag to disable this online check, because it generates a lot of traffic and runtime. |
508 | if (!isset($params['do_online_check'])) $params['do_online_check'] = false; // Flag to disable this online check, because it generates a lot of traffic and runtime. |
509 | if (!isset($params['do_illegality_check'])) $params['do_illegality_check'] = true; |
509 | if (!isset($params['do_illegality_check'])) $params['do_illegality_check'] = true; |
510 | if (!isset($params['do_simpleping_check'])) $params['do_simpleping_check'] = true; |
510 | if (!isset($params['do_simpleping_check'])) $params['do_simpleping_check'] = true; |
511 | if (!isset($params['auto_extract_name'])) $params['auto_extract_name'] = ''; |
511 | if (!isset($params['auto_extract_name'])) $params['auto_extract_name'] = ''; |
512 | if (!isset($params['auto_extract_url'])) $params['auto_extract_url'] = ''; |
512 | if (!isset($params['auto_extract_url'])) $params['auto_extract_url'] = ''; |
513 | if (!isset($params['always_output_comment'])) $params['always_output_comment'] = false; // Also output comment if there was an error (e.g. OID already existing) |
513 | if (!isset($params['always_output_comment'])) $params['always_output_comment'] = false; // Also output comment if there was an error (e.g. OID already existing) |
514 | if (!isset($params['creation_allowed_check'])) $params['creation_allowed_check'] = true; |
514 | if (!isset($params['creation_allowed_check'])) $params['creation_allowed_check'] = true; |
515 | if (!isset($params['tolerant_htmlentities'])) $params['tolerant_htmlentities'] = true; |
515 | if (!isset($params['tolerant_htmlentities'])) $params['tolerant_htmlentities'] = true; |
516 | if (!isset($params['ignore_xhtml_light'])) $params['ignore_xhtml_light'] = false; |
516 | if (!isset($params['ignore_xhtml_light'])) $params['ignore_xhtml_light'] = false; |
517 | if (!isset($params['show_errors'])) $params['show_errors'] = true; |
517 | if (!isset($params['show_errors'])) $params['show_errors'] = true; |
518 | 518 | ||
519 | return $params; |
519 | return $params; |
520 | } |
520 | } |
521 | public function createXMLEntry($oid, $elements, $params, $comment='') { |
521 | public function createXMLEntry($oid, $elements, $params, $comment='') { |
522 | $params = $this->init_params($params); |
522 | $params = $this->init_params($params); |
523 | 523 | ||
524 | $out = ''; |
524 | $out = ''; |
525 | if (!empty($comment)) $out .= "\t\t<!-- $comment -->\n"; |
525 | if (!empty($comment)) $out .= "\t\t<!-- $comment -->\n"; |
526 | 526 | ||
527 | if ($params['always_output_comment']) { |
527 | if ($params['always_output_comment']) { |
528 | $err = $out; |
528 | $err = $out; |
529 | } else { |
529 | } else { |
530 | $err = false; |
530 | $err = false; |
531 | } |
531 | } |
532 | 532 | ||
533 | if (isset($elements['dotted_oid'])) { |
533 | if (isset($elements['dotted_oid'])) { |
534 | throw new OIDInfoException("'dotted_oid' in the \$elements array is not supported. Please use the \$oid argument."); |
534 | throw new OIDInfoException("'dotted_oid' in the \$elements array is not supported. Please use the \$oid argument."); |
535 | } |
535 | } |
536 | if (isset($elements['value'])) { |
536 | if (isset($elements['value'])) { |
537 | // TODO: WHAT SHOULD WE DO WITH THAT? |
537 | // TODO: WHAT SHOULD WE DO WITH THAT? |
538 | throw new OIDInfoException("'value' in the \$elements array is currently not supported."); |
538 | throw new OIDInfoException("'value' in the \$elements array is currently not supported."); |
539 | } |
539 | } |
540 | 540 | ||
541 | $bak_oid = $oid; |
541 | $bak_oid = $oid; |
542 | $oid = self::trySanitizeOID($oid); |
542 | $oid = self::trySanitizeOID($oid); |
543 | if ($oid === false) { |
543 | if ($oid === false) { |
544 | if ($params['show_errors']) fwrite(STDOUT/*STDERR*/,"<!-- ERROR: Ignored '$bak_oid', because it is not a valid OID -->\n"); |
544 | if ($params['show_errors']) fwrite(STDOUT/*STDERR*/,"<!-- ERROR: Ignored '$bak_oid', because it is not a valid OID -->\n"); |
545 | return $err; |
545 | return $err; |
546 | } |
546 | } |
547 | 547 | ||
548 | if ($params['creation_allowed_check']) { |
548 | if ($params['creation_allowed_check']) { |
549 | if (!$this->oidMayCreate($oid, $params['do_online_check'], $params['do_simpleping_check'], $params['do_illegality_check'])) { |
549 | if (!$this->oidMayCreate($oid, $params['do_online_check'], $params['do_simpleping_check'], $params['do_illegality_check'])) { |
550 | if ($params['show_errors']) fwrite(STDOUT/*STDERR*/,"<!-- ERROR: Creation of $oid disallowed -->\n"); |
550 | if ($params['show_errors']) fwrite(STDOUT/*STDERR*/,"<!-- ERROR: Creation of $oid disallowed -->\n"); |
551 | return $err; |
551 | return $err; |
552 | } |
552 | } |
553 | } else { |
553 | } else { |
554 | if ($params['do_illegality_check'] && ($this->illegalOid($oid))) { |
554 | if ($params['do_illegality_check'] && ($this->illegalOid($oid))) { |
555 | if ($params['show_errors']) fwrite(STDOUT/*STDERR*/,"<!-- ERROR: Creation of $oid disallowed -->\n"); |
555 | if ($params['show_errors']) fwrite(STDOUT/*STDERR*/,"<!-- ERROR: Creation of $oid disallowed -->\n"); |
556 | return $err; |
556 | return $err; |
557 | } |
557 | } |
558 | } |
558 | } |
559 | 559 | ||
560 | if (!isset($elements['description'])) $elements['description'] = ''; |
560 | if (!isset($elements['description'])) $elements['description'] = ''; |
561 | if (!isset($elements['information'])) $elements['information'] = ''; |
561 | if (!isset($elements['information'])) $elements['information'] = ''; |
562 | 562 | ||
563 | $elements['description'] = $this->correctDesc($elements['description'], $params, self::OIDINFO_CORRECT_DESC_DISALLOW_ENDING_DOT, true); |
563 | $elements['description'] = $this->correctDesc($elements['description'], $params, self::OIDINFO_CORRECT_DESC_DISALLOW_ENDING_DOT, true); |
564 | $elements['information'] = $this->correctDesc($elements['information'], $params, self::OIDINFO_CORRECT_DESC_ENFORCE_ENDING_DOT, true); |
564 | $elements['information'] = $this->correctDesc($elements['information'], $params, self::OIDINFO_CORRECT_DESC_ENFORCE_ENDING_DOT, true); |
565 | 565 | ||
566 | // Request by O.D. 26 August 2019 |
566 | // Request by O.D. 26 August 2019 |
567 | $elements['description'] = trim($elements['description']); |
567 | $elements['description'] = trim($elements['description']); |
568 | $m = array(); |
568 | $m = array(); |
569 | if (preg_match('@^[a-z]@', $elements['description'], $m)) { |
569 | if (preg_match('@^[a-z]@', $elements['description'], $m)) { |
570 | $ending_dot_policy = self::OIDINFO_CORRECT_DESC_DISALLOW_ENDING_DOT; // for description |
570 | $ending_dot_policy = self::OIDINFO_CORRECT_DESC_DISALLOW_ENDING_DOT; // for description |
571 | if (($ending_dot_policy != self::OIDINFO_CORRECT_DESC_ENFORCE_ENDING_DOT) && (strpos($elements['description'], ' ') === false)) { // <-- added by DM |
571 | if (($ending_dot_policy != self::OIDINFO_CORRECT_DESC_ENFORCE_ENDING_DOT) && (strpos($elements['description'], ' ') === false)) { // <-- added by DM |
572 | $elements['description'] = '"' . $elements['description'] . '"'; |
572 | $elements['description'] = '"' . $elements['description'] . '"'; |
573 | } |
573 | } |
574 | } |
574 | } |
575 | // End request by O.D. 26. August 2019 |
575 | // End request by O.D. 26. August 2019 |
576 | 576 | ||
577 | if ($params['auto_extract_name'] || $params['auto_extract_url']) { |
577 | if (($params['auto_extract_name'] != '') || ($params['auto_extract_url'] != '')) { |
578 | if (!empty($elements['information'])) $elements['information'] .= '<br /><br />'; |
578 | if (!empty($elements['information'])) $elements['information'] .= '<br /><br />'; |
579 | if ($params['auto_extract_name'] || $params['auto_extract_url']) { |
579 | if (($params['auto_extract_name'] != '') || ($params['auto_extract_url'] != '')) { |
580 | $elements['information'] .= 'Automatically extracted from <a href="'.$params['auto_extract_url'].'">'.$params['auto_extract_name'].'</a>.'; |
580 | $elements['information'] .= 'Automatically extracted from <a href="'.$params['auto_extract_url'].'">'.$params['auto_extract_name'].'</a>.'; |
581 | } else if ($params['auto_extract_name']) { |
581 | } else if ($params['auto_extract_name'] != '') { |
582 | $elements['information'] .= 'Automatically extracted from '.$params['auto_extract_name']; |
582 | $elements['information'] .= 'Automatically extracted from '.$params['auto_extract_name']; |
583 | } else if ($params['auto_extract_url']) { |
583 | } else if ($params['auto_extract_url'] != '') { |
584 | $hr_url = $params['auto_extract_url']; |
584 | $hr_url = $params['auto_extract_url']; |
585 | // $hr_url = preg_replace('@^https{0,1}://@ismU', '', $hr_url); |
585 | // $hr_url = preg_replace('@^https{0,1}://@ismU', '', $hr_url); |
586 | $hr_url = preg_replace('@^http://@ismU', '', $hr_url); |
586 | $hr_url = preg_replace('@^http://@ismU', '', $hr_url); |
587 | $elements['information'] .= 'Automatically extracted from <a href="'.$params['auto_extract_url'].'">'.$hr_url.'</a>.'; |
587 | $elements['information'] .= 'Automatically extracted from <a href="'.$params['auto_extract_url'].'">'.$hr_url.'</a>.'; |
588 | } |
588 | } |
589 | } |
589 | } |
590 | 590 | ||
591 | // Validate ASN.1 ID |
591 | // Validate ASN.1 ID |
592 | if (isset($elements['synonymous-identifier'])) { |
592 | if (isset($elements['synonymous-identifier'])) { |
593 | if (!is_array($elements['synonymous-identifier'])) { |
593 | if (!is_array($elements['synonymous-identifier'])) { |
594 | $elements['synonymous-identifier'] = array($elements['synonymous-identifier']); |
594 | $elements['synonymous-identifier'] = array($elements['synonymous-identifier']); |
595 | } |
595 | } |
596 | foreach ($elements['synonymous-identifier'] as &$synid) { |
596 | foreach ($elements['synonymous-identifier'] as &$synid) { |
597 | if ($synid == '') { |
597 | if ($synid == '') { |
598 | $synid = null; |
598 | $synid = null; |
599 | continue; |
599 | continue; |
600 | } |
600 | } |
601 | 601 | ||
602 | $behavior = $params['soft_correct_behavior']; |
602 | $behavior = $params['soft_correct_behavior']; |
603 | 603 | ||
604 | if ($behavior == self::SOFT_CORRECT_BEHAVIOR_NONE) { |
604 | if ($behavior == self::SOFT_CORRECT_BEHAVIOR_NONE) { |
605 | if (!oid_id_is_valid($synid)) $synid = null; |
605 | if (!oid_id_is_valid($synid)) $synid = null; |
606 | } else if ($behavior == self::SOFT_CORRECT_BEHAVIOR_LOWERCASE_BEGINNING) { |
606 | } else if ($behavior == self::SOFT_CORRECT_BEHAVIOR_LOWERCASE_BEGINNING) { |
607 | $synid[0] = strtolower($synid[0]); |
607 | $synid[0] = strtolower($synid[0]); |
608 | if (!oid_id_is_valid($synid)) $synid = null; |
608 | if (!oid_id_is_valid($synid)) $synid = null; |
609 | } else if ($behavior == self::SOFT_CORRECT_BEHAVIOR_ALL_POSSIBLE) { |
609 | } else if ($behavior == self::SOFT_CORRECT_BEHAVIOR_ALL_POSSIBLE) { |
610 | $synid = oid_soft_correct_id($synid); |
610 | $synid = oid_soft_correct_id($synid); |
611 | // if (!oid_id_is_valid($synid)) $synid = null; |
611 | // if (!oid_id_is_valid($synid)) $synid = null; |
612 | } else { |
612 | } else { |
613 | throw new OIDInfoException("Unexpected soft-correction behavior for ASN.1 IDs"); |
613 | throw new OIDInfoException("Unexpected soft-correction behavior for ASN.1 IDs"); |
614 | } |
614 | } |
615 | } |
615 | } |
616 | } |
616 | } |
617 | 617 | ||
618 | // ATTENTION: the XML-generator will always add <dotted-oid> , but what will happen if additionally an |
618 | // ATTENTION: the XML-generator will always add <dotted-oid> , but what will happen if additionally an |
619 | // asn1-path (<value>) is given? (the resulting OIDs might be inconsistent/mismatch) |
619 | // asn1-path (<value>) is given? (the resulting OIDs might be inconsistent/mismatch) |
620 | if (isset($elements['value']) && (!asn1_path_valid($elements['value']))) { |
620 | if (isset($elements['value']) && (!asn1_path_valid($elements['value']))) { |
621 | unset($elements['value']); |
621 | unset($elements['value']); |
622 | } |
622 | } |
623 | 623 | ||
624 | // Validate IRI (currently not supported by oid-info.com, but the tag name is reserved) |
624 | // Validate IRI (currently not supported by oid-info.com, but the tag name is reserved) |
625 | if (isset($elements['iri'])) { |
625 | if (isset($elements['iri'])) { |
626 | if (!is_array($elements['iri'])) { |
626 | if (!is_array($elements['iri'])) { |
627 | $elements['iri'] = array($elements['iri']); |
627 | $elements['iri'] = array($elements['iri']); |
628 | } |
628 | } |
629 | foreach ($elements['iri'] as &$iri) { |
629 | foreach ($elements['iri'] as &$iri) { |
630 | // Do not allow Numeric-only. It would only be valid in an IRI path, but not in a single identifier |
630 | // Do not allow Numeric-only. It would only be valid in an IRI path, but not in a single identifier |
631 | if (!iri_arc_valid($iri, false)) $iri = null; |
631 | if (!iri_arc_valid($iri, false)) $iri = null; |
632 | } |
632 | } |
633 | } |
633 | } |
634 | 634 | ||
635 | if (isset($elements['first-registrant']['phone'])) |
635 | if (isset($elements['first-registrant']['phone'])) |
636 | $elements['first-registrant']['phone'] = $this->softCorrectPhone($elements['first-registrant']['phone'], $params); |
636 | $elements['first-registrant']['phone'] = $this->softCorrectPhone($elements['first-registrant']['phone'], $params); |
637 | 637 | ||
638 | if (isset($elements['current-registrant']['phone'])) |
638 | if (isset($elements['current-registrant']['phone'])) |
639 | $elements['current-registrant']['phone'] = $this->softCorrectPhone($elements['current-registrant']['phone'], $params); |
639 | $elements['current-registrant']['phone'] = $this->softCorrectPhone($elements['current-registrant']['phone'], $params); |
640 | 640 | ||
641 | if (isset($elements['first-registrant']['fax'])) |
641 | if (isset($elements['first-registrant']['fax'])) |
642 | $elements['first-registrant']['fax'] = $this->softCorrectPhone($elements['first-registrant']['fax'], $params); |
642 | $elements['first-registrant']['fax'] = $this->softCorrectPhone($elements['first-registrant']['fax'], $params); |
643 | 643 | ||
644 | if (isset($elements['current-registrant']['fax'])) |
644 | if (isset($elements['current-registrant']['fax'])) |
645 | $elements['current-registrant']['fax'] = $this->softCorrectPhone($elements['current-registrant']['fax'], $params); |
645 | $elements['current-registrant']['fax'] = $this->softCorrectPhone($elements['current-registrant']['fax'], $params); |
646 | 646 | ||
647 | if (isset($elements['first-registrant']['email'])) |
647 | if (isset($elements['first-registrant']['email'])) |
648 | $elements['first-registrant']['email'] = $this->softCorrectEMail($elements['first-registrant']['email'], $params); |
648 | $elements['first-registrant']['email'] = $this->softCorrectEMail($elements['first-registrant']['email'], $params); |
649 | 649 | ||
650 | if (isset($elements['current-registrant']['email'])) |
650 | if (isset($elements['current-registrant']['email'])) |
651 | $elements['current-registrant']['email'] = $this->softCorrectEMail($elements['current-registrant']['email'], $params); |
651 | $elements['current-registrant']['email'] = $this->softCorrectEMail($elements['current-registrant']['email'], $params); |
652 | 652 | ||
653 | // TODO: if name is empty, but address has 1 line, take it as firstname (but remove hyperlink) |
653 | // TODO: if name is empty, but address has 1 line, take it as firstname (but remove hyperlink) |
654 | 654 | ||
655 | $ignore_current_registrant = false; |
655 | $ignore_current_registrant = false; |
656 | if (isset($elements['current-registrant'])) { |
656 | if (isset($elements['current-registrant'])) { |
657 | $test_keys = array_keys($elements['current-registrant']); |
657 | $test_keys = array_keys($elements['current-registrant']); |
658 | if ((count($test_keys) == 1) && ($test_keys[0] == 'modification-date')) { |
658 | if ((count($test_keys) == 1) && ($test_keys[0] == 'modification-date')) { |
659 | // Modification dates without information about the current RA which are rejected by the OID repository |
659 | // Modification dates without information about the current RA which are rejected by the OID repository |
660 | $ignore_current_registrant = true; |
660 | $ignore_current_registrant = true; |
661 | } |
661 | } |
662 | } |
662 | } |
663 | 663 | ||
664 | $out_loc = ''; |
664 | $out_loc = ''; |
665 | foreach ($elements as $name => $val) { |
665 | foreach ($elements as $name => $val) { |
666 | if (($name == 'first-registrant') || ($name == 'current-registrant')) { |
666 | if (($name == 'first-registrant') || ($name == 'current-registrant')) { |
667 | if (($name != 'current-registrant') || !$ignore_current_registrant) { |
667 | if (($name != 'current-registrant') || !$ignore_current_registrant) { |
668 | $out_loc2 = ''; |
668 | $out_loc2 = ''; |
669 | foreach ($val as $name2 => $val2) { |
669 | foreach ($val as $name2 => $val2) { |
670 | if (is_null($val2)) continue; |
670 | if (is_null($val2)) continue; |
671 | if (empty($val2)) continue; |
671 | if (empty($val2)) continue; |
672 | 672 | ||
673 | if (!is_array($val2)) $val2 = array($val2); |
673 | if (!is_array($val2)) $val2 = array($val2); |
674 | 674 | ||
675 | foreach ($val2 as $val3) { |
675 | foreach ($val2 as $val3) { |
676 | // if (is_null($val3)) continue; |
676 | // if (is_null($val3)) continue; |
677 | if (empty($val3)) continue; |
677 | if (empty($val3)) continue; |
678 | 678 | ||
679 | if ($name2 == 'address') { |
679 | if ($name2 == 'address') { |
680 | // $val3 = htmlentities_numeric($val3); |
680 | // $val3 = htmlentities_numeric($val3); |
681 | $val3 = $this->correctDesc($val3, $params, self::OIDINFO_CORRECT_DESC_DISALLOW_ENDING_DOT, true); |
681 | $val3 = $this->correctDesc($val3, $params, self::OIDINFO_CORRECT_DESC_DISALLOW_ENDING_DOT, true); |
682 | } else { |
682 | } else { |
683 | // $val3 = htmlentities_numeric($val3); |
683 | // $val3 = htmlentities_numeric($val3); |
684 | $val3 = $this->correctDesc($val3, $params, self::OIDINFO_CORRECT_DESC_DISALLOW_ENDING_DOT, false); |
684 | $val3 = $this->correctDesc($val3, $params, self::OIDINFO_CORRECT_DESC_DISALLOW_ENDING_DOT, false); |
685 | } |
685 | } |
686 | $out_loc2 .= "\t\t\t<$name2>".$val3."</$name2>\n"; |
686 | $out_loc2 .= "\t\t\t<$name2>".$val3."</$name2>\n"; |
687 | } |
687 | } |
688 | } |
688 | } |
689 | 689 | ||
690 | if (!empty($out_loc2)) { |
690 | if (!empty($out_loc2)) { |
691 | $out_loc .= "\t\t<$name>\n"; |
691 | $out_loc .= "\t\t<$name>\n"; |
692 | $out_loc .= $out_loc2; |
692 | $out_loc .= $out_loc2; |
693 | $out_loc .= "\t\t</$name>\n"; |
693 | $out_loc .= "\t\t</$name>\n"; |
694 | } |
694 | } |
695 | } |
695 | } |
696 | } else { |
696 | } else { |
697 | // if (is_null($val)) continue; |
697 | // if (is_null($val)) continue; |
698 | if (empty($val) && ($name != 'description')) continue; // description is mandatory, according to http://oid-info.com/oid.xsd |
698 | if (empty($val) && ($name != 'description')) continue; // description is mandatory, according to http://oid-info.com/oid.xsd |
699 | 699 | ||
700 | if (!is_array($val)) $val = array($val); |
700 | if (!is_array($val)) $val = array($val); |
701 | 701 | ||
702 | foreach ($val as $val2) { |
702 | foreach ($val as $val2) { |
703 | // if (is_null($val2)) continue; |
703 | // if (is_null($val2)) continue; |
704 | if (empty($val2) && ($name != 'description')) continue; // description is mandatory, according to http://oid-info.com/oid.xsd |
704 | if (empty($val2) && ($name != 'description')) continue; // description is mandatory, according to http://oid-info.com/oid.xsd |
705 | 705 | ||
706 | if (($name != 'description') && ($name != 'information')) { // don't correctDesc description/information, because we already did it above. |
706 | if (($name != 'description') && ($name != 'information')) { // don't correctDesc description/information, because we already did it above. |
707 | // $val2 = htmlentities_numeric($val2); |
707 | // $val2 = htmlentities_numeric($val2); |
708 | $val2 = $this->correctDesc($val2, $params, self::OIDINFO_CORRECT_DESC_OPTIONAL_ENDING_DOT, false); |
708 | $val2 = $this->correctDesc($val2, $params, self::OIDINFO_CORRECT_DESC_OPTIONAL_ENDING_DOT, false); |
709 | } |
709 | } |
710 | $out_loc .= "\t\t<$name>".$val2."</$name>\n"; |
710 | $out_loc .= "\t\t<$name>".$val2."</$name>\n"; |
711 | } |
711 | } |
712 | } |
712 | } |
713 | } |
713 | } |
714 | 714 | ||
715 | if (!empty($out)) { |
715 | if (!empty($out)) { |
716 | $out = "\t<oid>\n"."\t\t".trim($out)."\n"; |
716 | $out = "\t<oid>\n"."\t\t".trim($out)."\n"; |
717 | } else { |
717 | } else { |
718 | $out = "\t<oid>\n"; |
718 | $out = "\t<oid>\n"; |
719 | } |
719 | } |
720 | $out .= "\t\t<dot-notation>$oid</dot-notation>\n"; |
720 | $out .= "\t\t<dot-notation>$oid</dot-notation>\n"; |
721 | $out .= $out_loc; |
721 | $out .= $out_loc; |
722 | $out .= "\t</oid>\n"; |
722 | $out .= "\t</oid>\n"; |
723 | 723 | ||
724 | return $out; |
724 | return $out; |
725 | } |
725 | } |
726 | 726 | ||
727 | # --- PART 4: Offline check if OIDs are illegal |
727 | # --- PART 4: Offline check if OIDs are illegal |
728 | 728 | ||
729 | protected $illegality_rules = array(); |
729 | protected $illegality_rules = array(); |
730 | 730 | ||
731 | public function clearIllegalityRules() { |
731 | public function clearIllegalityRules() { |
732 | $this->illegality_rules = array(); |
732 | $this->illegality_rules = array(); |
733 | } |
733 | } |
734 | 734 | ||
735 | public function loadIllegalityRuleFile($file) { |
735 | public function loadIllegalityRuleFile($file) { |
736 | if (!file_exists($file)) { |
736 | if (!file_exists($file)) { |
737 | throw new OIDInfoException("Error: File '$file' does not exist"); |
737 | throw new OIDInfoException("Error: File '$file' does not exist"); |
738 | } |
738 | } |
739 | 739 | ||
740 | $lines = file($file); |
740 | $lines = file($file); |
741 | 741 | ||
742 | if ($lines === false) { |
742 | if ($lines === false) { |
743 | throw new OIDInfoException("Error: Could not load '$file'"); |
743 | throw new OIDInfoException("Error: Could not load '$file'"); |
744 | } |
744 | } |
745 | 745 | ||
746 | $signature = trim(array_shift($lines)); |
746 | $signature = trim(array_shift($lines)); |
747 | if (($signature != '[1.3.6.1.4.1.37476.3.1.5.1]') && ($signature != '[1.3.6.1.4.1.37476.3.1.5.2]')) { |
747 | if (($signature != '[1.3.6.1.4.1.37476.3.1.5.1]') && ($signature != '[1.3.6.1.4.1.37476.3.1.5.2]')) { |
748 | throw new OIDInfoException("'$file' does not seem to a valid illegality rule file (file format OID does not match. Signature $signature unexpected)"); |
748 | throw new OIDInfoException("'$file' does not seem to a valid illegality rule file (file format OID does not match. Signature $signature unexpected)"); |
749 | } |
749 | } |
750 | 750 | ||
751 | foreach ($lines as $line) { |
751 | foreach ($lines as $line) { |
752 | // Remove comments |
752 | // Remove comments |
753 | $ary = explode('--', $line); |
753 | $ary = explode('--', $line); |
754 | $rule = trim($ary[0]); |
754 | $rule = trim($ary[0]); |
755 | 755 | ||
756 | if ($rule !== '') $this->addIllegalityRule($rule); |
756 | if ($rule !== '') $this->addIllegalityRule($rule); |
757 | } |
757 | } |
758 | } |
758 | } |
759 | 759 | ||
760 | public function addIllegalityRule($rule) { |
760 | public function addIllegalityRule($rule) { |
761 | $test = $rule; |
761 | $test = $rule; |
762 | $test = preg_replace('@\\.\\(!\\d+\\)@ismU', '.0', $test); // added in ver 2 |
762 | $test = preg_replace('@\\.\\(!\\d+\\)@ismU', '.0', $test); // added in ver 2 |
763 | $test = preg_replace('@\\.\\(\\d+\\+\\)@ismU', '.0', $test); |
763 | $test = preg_replace('@\\.\\(\\d+\\+\\)@ismU', '.0', $test); |
764 | $test = preg_replace('@\\.\\(\\d+\\-\\)@ismU', '.0', $test); |
764 | $test = preg_replace('@\\.\\(\\d+\\-\\)@ismU', '.0', $test); |
765 | $test = preg_replace('@\\.\\(\\d+\\-\\d+\\)@ismU', '.0', $test); |
765 | $test = preg_replace('@\\.\\(\\d+\\-\\d+\\)@ismU', '.0', $test); |
766 | $test = preg_replace('@\\.\\*@ismU', '.0', $test); |
766 | $test = preg_replace('@\\.\\*@ismU', '.0', $test); |
767 | 767 | ||
768 | if (!oid_valid_dotnotation($test, false, false, 1)) { |
768 | if (!oid_valid_dotnotation($test, false, false, 1)) { |
769 | throw new OIDInfoException("Illegal illegality rule '$rule'."); |
769 | throw new OIDInfoException("Illegal illegality rule '$rule'."); |
770 | } |
770 | } |
771 | 771 | ||
772 | $this->illegality_rules[] = $rule; |
772 | $this->illegality_rules[] = $rule; |
773 | } |
773 | } |
774 | 774 | ||
775 | private static function bigint_cmp($a, $b) { |
775 | private static function bigint_cmp($a, $b) { |
776 | if (function_exists('bccomp')) { |
776 | if (function_exists('bccomp')) { |
777 | return bccomp($a, $b); |
777 | return bccomp($a, $b); |
778 | } |
778 | } |
779 | 779 | ||
780 | if (function_exists('gmp_cmp')) { |
780 | if (function_exists('gmp_cmp')) { |
781 | return gmp_cmp($a, $b); |
781 | return gmp_cmp($a, $b); |
782 | } |
782 | } |
783 | 783 | ||
784 | if ($a > $b) return 1; |
784 | if ($a > $b) return 1; |
785 | if ($a < $b) return -1; |
785 | if ($a < $b) return -1; |
786 | return 0; |
786 | return 0; |
787 | } |
787 | } |
788 | 788 | ||
789 | public function illegalOID($oid, &$illegal_root='') { |
789 | public function illegalOID($oid, &$illegal_root='') { |
790 | $bak = $oid; |
790 | $bak = $oid; |
791 | $oid = self::trySanitizeOID($oid); |
791 | $oid = self::trySanitizeOID($oid); |
792 | if ($oid === false) { |
792 | if ($oid === false) { |
793 | $illegal_root = $bak; |
793 | $illegal_root = $bak; |
794 | return true; // is illegal |
794 | return true; // is illegal |
795 | } |
795 | } |
796 | 796 | ||
797 | $rules = $this->illegality_rules; |
797 | $rules = $this->illegality_rules; |
798 | 798 | ||
799 | foreach ($rules as $rule) { |
799 | foreach ($rules as $rule) { |
800 | $rule = str_replace(array('(', ')'), '', $rule); |
800 | $rule = str_replace(array('(', ')'), '', $rule); |
801 | 801 | ||
802 | $oarr = explode('.', $oid); |
802 | $oarr = explode('.', $oid); |
803 | $rarr = explode('.', $rule); |
803 | $rarr = explode('.', $rule); |
804 | 804 | ||
805 | if (count($oarr) < count($rarr)) continue; |
805 | if (count($oarr) < count($rarr)) continue; |
806 | 806 | ||
807 | $rulefit = true; |
807 | $rulefit = true; |
808 | 808 | ||
809 | $illrootary = array(); |
809 | $illrootary = array(); |
810 | 810 | ||
811 | $vararcs = 0; |
811 | $vararcs = 0; |
812 | $varsfit = 0; |
812 | $varsfit = 0; |
813 | for ($i=0; $i<count($rarr); $i++) { |
813 | for ($i=0; $i<count($rarr); $i++) { |
814 | $oelem = $oarr[$i]; |
814 | $oelem = $oarr[$i]; |
815 | $relem = $rarr[$i]; |
815 | $relem = $rarr[$i]; |
816 | 816 | ||
817 | $illrootary[] = $oelem; |
817 | $illrootary[] = $oelem; |
818 | 818 | ||
819 | if ($relem == '*') $relem = '0+'; |
819 | if ($relem == '*') $relem = '0+'; |
820 | 820 | ||
821 | $startchar = substr($relem, 0, 1); |
821 | $startchar = substr($relem, 0, 1); |
822 | $endchar = substr($relem, -1, 1); |
822 | $endchar = substr($relem, -1, 1); |
823 | if ($startchar == '!') { // added in ver 2 |
823 | if ($startchar == '!') { // added in ver 2 |
824 | $vararcs++; |
824 | $vararcs++; |
825 | $relem = substr($relem, 1, strlen($relem)-1); // cut away first char |
825 | $relem = substr($relem, 1, strlen($relem)-1); // cut away first char |
826 | $cmp = self::bigint_cmp($oelem, $relem) != 0; |
826 | $cmp = self::bigint_cmp($oelem, $relem) != 0; |
827 | if ($cmp) $varsfit++; |
827 | if ($cmp) $varsfit++; |
828 | } else if ($endchar == '+') { |
828 | } else if ($endchar == '+') { |
829 | $vararcs++; |
829 | $vararcs++; |
830 | $relem = substr($relem, 0, strlen($relem)-1); // cut away last char |
830 | $relem = substr($relem, 0, strlen($relem)-1); // cut away last char |
831 | $cmp = self::bigint_cmp($oelem, $relem) >= 0; |
831 | $cmp = self::bigint_cmp($oelem, $relem) >= 0; |
832 | if ($cmp) $varsfit++; |
832 | if ($cmp) $varsfit++; |
833 | } else if ($endchar == '-') { |
833 | } else if ($endchar == '-') { |
834 | $vararcs++; |
834 | $vararcs++; |
835 | $relem = substr($relem, 0, strlen($relem)-1); // cut away last char |
835 | $relem = substr($relem, 0, strlen($relem)-1); // cut away last char |
836 | $cmp = self::bigint_cmp($oelem, $relem) <= 0; |
836 | $cmp = self::bigint_cmp($oelem, $relem) <= 0; |
837 | if ($cmp) $varsfit++; |
837 | if ($cmp) $varsfit++; |
838 | } else if (strpos($relem, '-') !== false) { |
838 | } else if (strpos($relem, '-') !== false) { |
839 | $vararcs++; |
839 | $vararcs++; |
840 | $limarr = explode('-', $relem); |
840 | $limarr = explode('-', $relem); |
841 | $limmin = $limarr[0]; |
841 | $limmin = $limarr[0]; |
842 | $limmax = $limarr[1]; |
842 | $limmax = $limarr[1]; |
843 | $cmp_min = self::bigint_cmp($oelem, $limmin) >= 0; |
843 | $cmp_min = self::bigint_cmp($oelem, $limmin) >= 0; |
844 | $cmp_max = self::bigint_cmp($oelem, $limmax) <= 0; |
844 | $cmp_max = self::bigint_cmp($oelem, $limmax) <= 0; |
845 | if ($cmp_min && $cmp_max) $varsfit++; |
845 | if ($cmp_min && $cmp_max) $varsfit++; |
846 | } else { |
846 | } else { |
847 | if ($relem != $oelem) { |
847 | if ($relem != $oelem) { |
848 | $rulefit = false; |
848 | $rulefit = false; |
849 | break; |
849 | break; |
850 | } |
850 | } |
851 | } |
851 | } |
852 | } |
852 | } |
853 | 853 | ||
854 | if ($rulefit && ($vararcs == $varsfit)) { |
854 | if ($rulefit && ($vararcs == $varsfit)) { |
855 | $illegal_root = implode('.', $illrootary); |
855 | $illegal_root = implode('.', $illrootary); |
856 | return true; // is illegal |
856 | return true; // is illegal |
857 | } |
857 | } |
858 | } |
858 | } |
859 | 859 | ||
860 | $illegal_root = ''; |
860 | $illegal_root = ''; |
861 | return false; // not illegal |
861 | return false; // not illegal |
862 | } |
862 | } |
863 | 863 | ||
864 | # --- PART 5: Misc functions |
864 | # --- PART 5: Misc functions |
865 | 865 | ||
866 | function __construct() { |
866 | function __construct() { |
867 | if (file_exists(self::DEFAULT_ILLEGALITY_RULE_FILE)) { |
867 | if (file_exists(self::DEFAULT_ILLEGALITY_RULE_FILE)) { |
868 | $this->loadIllegalityRuleFile(self::DEFAULT_ILLEGALITY_RULE_FILE); |
868 | $this->loadIllegalityRuleFile(self::DEFAULT_ILLEGALITY_RULE_FILE); |
869 | } |
869 | } |
870 | } |
870 | } |
871 | 871 | ||
872 | public static function getPublicURL($oid) { |
872 | public static function getPublicURL($oid) { |
873 | return "http://oid-info.com/get/$oid"; |
873 | return "http://oid-info.com/get/$oid"; |
874 | } |
874 | } |
875 | 875 | ||
876 | public function oidExisting($oid, $onlineCheck=true, $useSimplePingProvider=true) { |
876 | public function oidExisting($oid, $onlineCheck=true, $useSimplePingProvider=true) { |
877 | $bak_oid = $oid; |
877 | $bak_oid = $oid; |
878 | $oid = self::trySanitizeOID($oid); |
878 | $oid = self::trySanitizeOID($oid); |
879 | if ($oid === false) { |
879 | if ($oid === false) { |
880 | throw new OIDInfoException("'$bak_oid' is not a valid OID"); |
880 | throw new OIDInfoException("'$bak_oid' is not a valid OID"); |
881 | } |
881 | } |
882 | 882 | ||
883 | $canuseSimplePingProvider = $useSimplePingProvider && $this->simplePingProviderAvailable(); |
883 | $canuseSimplePingProvider = $useSimplePingProvider && $this->simplePingProviderAvailable(); |
884 | if ($canuseSimplePingProvider) { |
884 | if ($canuseSimplePingProvider) { |
885 | if ($this->simplePingProviderCheckOID($oid)) return true; |
885 | if ($this->simplePingProviderCheckOID($oid)) return true; |
886 | } |
886 | } |
887 | if ($onlineCheck) { |
887 | if ($onlineCheck) { |
888 | return $this->checkOnlineExists($oid); |
888 | return $this->checkOnlineExists($oid); |
889 | } |
889 | } |
890 | if ((!$canuseSimplePingProvider) && (!$onlineCheck)) { |
890 | if ((!$canuseSimplePingProvider) && (!$onlineCheck)) { |
891 | throw new OIDInfoException("No simple or verbose checking method chosen/available"); |
891 | throw new OIDInfoException("No simple or verbose checking method chosen/available"); |
892 | } |
892 | } |
893 | return false; |
893 | return false; |
894 | } |
894 | } |
895 | 895 | ||
896 | public function oidMayCreate($oid, $onlineCheck=true, $useSimplePingProvider=true, $illegalityCheck=true) { |
896 | public function oidMayCreate($oid, $onlineCheck=true, $useSimplePingProvider=true, $illegalityCheck=true) { |
897 | $bak_oid = $oid; |
897 | $bak_oid = $oid; |
898 | $oid = self::trySanitizeOID($oid); |
898 | $oid = self::trySanitizeOID($oid); |
899 | if ($oid === false) { |
899 | if ($oid === false) { |
900 | throw new OIDInfoException("'$bak_oid' is not a valid OID"); |
900 | throw new OIDInfoException("'$bak_oid' is not a valid OID"); |
901 | } |
901 | } |
902 | 902 | ||
903 | if ($illegalityCheck && $this->illegalOID($oid)) return false; |
903 | if ($illegalityCheck && $this->illegalOID($oid)) return false; |
904 | 904 | ||
905 | $canuseSimplePingProvider = $useSimplePingProvider && $this->simplePingProviderAvailable(); |
905 | $canuseSimplePingProvider = $useSimplePingProvider && $this->simplePingProviderAvailable(); |
906 | if ($canuseSimplePingProvider) { |
906 | if ($canuseSimplePingProvider) { |
907 | if ($this->simplePingProviderCheckOID($oid)) return false; |
907 | if ($this->simplePingProviderCheckOID($oid)) return false; |
908 | } |
908 | } |
909 | if ($onlineCheck) { |
909 | if ($onlineCheck) { |
910 | return $this->checkOnlineMayCreate($oid); |
910 | return $this->checkOnlineMayCreate($oid); |
911 | } |
911 | } |
912 | if ((!$canuseSimplePingProvider) && (!$onlineCheck)) { |
912 | if ((!$canuseSimplePingProvider) && (!$onlineCheck)) { |
913 | throw new OIDInfoException("No simple or verbose checking method chosen/available"); |
913 | throw new OIDInfoException("No simple or verbose checking method chosen/available"); |
914 | } |
914 | } |
915 | return true; |
915 | return true; |
916 | } |
916 | } |
917 | 917 | ||
918 | # --- PART 6: Simple Ping Providers |
918 | # --- PART 6: Simple Ping Providers |
919 | # TODO: Question ... can't these provider concepts (SPP and VPP) not somehow be combined? |
919 | # TODO: Question ... can't these provider concepts (SPP and VPP) not somehow be combined? |
920 | 920 | ||
921 | protected $simplePingProviders = array(); |
921 | protected $simplePingProviders = array(); |
922 | 922 | ||
923 | public function addSimplePingProvider($addr) { |
923 | public function addSimplePingProvider($addr) { |
924 | if (!isset($this->simplePingProviders[$addr])) { |
924 | if (!isset($this->simplePingProviders[$addr])) { |
925 | if (strtolower(substr($addr, -4, 4)) == '.csv') { |
925 | if (strtolower(substr($addr, -4, 4)) == '.csv') { |
926 | $this->simplePingProviders[$addr] = new CSVSimplePingProvider($addr); |
926 | $this->simplePingProviders[$addr] = new CSVSimplePingProvider($addr); |
927 | } else { |
927 | } else { |
928 | $this->simplePingProviders[$addr] = new OIDSimplePingProvider($addr); |
928 | $this->simplePingProviders[$addr] = new OIDSimplePingProvider($addr); |
929 | // $this->simplePingProviders[$addr]->connect(); |
929 | // $this->simplePingProviders[$addr]->connect(); |
930 | } |
930 | } |
931 | } |
931 | } |
932 | return $this->simplePingProviders[$addr]; |
932 | return $this->simplePingProviders[$addr]; |
933 | } |
933 | } |
934 | 934 | ||
935 | public function removeSimplePingProvider($addr) { |
935 | public function removeSimplePingProvider($addr) { |
936 | $this->simplePingProviders[$addr]->disconnect(); |
936 | $this->simplePingProviders[$addr]->disconnect(); |
937 | unset($this->simplePingProviders[$addr]); |
937 | unset($this->simplePingProviders[$addr]); |
938 | } |
938 | } |
939 | 939 | ||
940 | public function removeAllSimplePingProviders() { |
940 | public function removeAllSimplePingProviders() { |
941 | foreach ($this->simplePingProviders as $addr => $obj) { |
941 | foreach ($this->simplePingProviders as $addr => $obj) { |
942 | $this->removeSimplePingProvider($addr); |
942 | $this->removeSimplePingProvider($addr); |
943 | } |
943 | } |
944 | } |
944 | } |
945 | 945 | ||
946 | public function listSimplePingProviders() { |
946 | public function listSimplePingProviders() { |
947 | $out = array(); |
947 | $out = array(); |
948 | foreach ($this->simplePingProviders as $addr => $obj) { |
948 | foreach ($this->simplePingProviders as $addr => $obj) { |
949 | $out[] = $addr; |
949 | $out[] = $addr; |
950 | } |
950 | } |
951 | return $out; |
951 | return $out; |
952 | } |
952 | } |
953 | 953 | ||
954 | public function simplePingProviderCheckOID($oid) { |
954 | public function simplePingProviderCheckOID($oid) { |
955 | if (!$this->simplePingProviderAvailable()) { |
955 | if (!$this->simplePingProviderAvailable()) { |
956 | throw new OIDInfoException("No simple ping providers available."); |
956 | throw new OIDInfoException("No simple ping providers available."); |
957 | } |
957 | } |
958 | 958 | ||
959 | $one_null = false; |
959 | $one_null = false; |
960 | foreach ($this->simplePingProviders as /*$addr =>*/ $obj) { |
960 | foreach ($this->simplePingProviders as /*$addr =>*/ $obj) { |
961 | $res = $obj->queryOID($oid); |
961 | $res = $obj->queryOID($oid); |
962 | if ($res) return true; |
962 | if ($res) return true; |
963 | if ($res !== false) $one_null = true; |
963 | if ($res !== false) $one_null = true; |
964 | } |
964 | } |
965 | 965 | ||
966 | return $one_null ? null : false; |
966 | return $one_null ? null : false; |
967 | } |
967 | } |
968 | 968 | ||
969 | public function simplePingProviderAvailable() { |
969 | public function simplePingProviderAvailable() { |
970 | return count($this->simplePingProviders) >= 1; |
970 | return count($this->simplePingProviders) >= 1; |
971 | } |
971 | } |
972 | 972 | ||
973 | } |
973 | } |
974 | 974 | ||
975 | interface IOIDSimplePingProvider { |
975 | interface IOIDSimplePingProvider { |
976 | public function queryOID($oid); |
976 | public function queryOID($oid); |
977 | public function disconnect(); |
977 | public function disconnect(); |
978 | public function connect(); |
978 | public function connect(); |
979 | } |
979 | } |
980 | 980 | ||
981 | class CSVSimplePingProvider implements IOIDSimplePingProvider { |
981 | class CSVSimplePingProvider implements IOIDSimplePingProvider { |
982 | protected $csvfile = ''; |
982 | protected $csvfile = ''; |
983 | protected $lines = array(); |
983 | protected $lines = array(); |
984 | protected $filemtime = 0; |
984 | protected $filemtime = 0; |
985 | 985 | ||
986 | public function queryOID($oid) { |
986 | public function queryOID($oid) { |
987 | $this->reloadCSV(); |
987 | $this->reloadCSV(); |
988 | return in_array($oid, $this->lines); |
988 | return in_array($oid, $this->lines); |
989 | } |
989 | } |
990 | 990 | ||
991 | public function disconnect() { |
991 | public function disconnect() { |
992 | // Nothing |
992 | // Nothing |
993 | } |
993 | } |
994 | 994 | ||
995 | public function connect() { |
995 | public function connect() { |
996 | // Nothing |
996 | // Nothing |
997 | } |
997 | } |
998 | 998 | ||
999 | // TODO: This cannot handle big CSVs. We need to introduce the old code of "2016-09-02_old_oidinfo_api_with_csv_reader.zip" here. |
999 | // TODO: This cannot handle big CSVs. We need to introduce the old code of "2016-09-02_old_oidinfo_api_with_csv_reader.zip" here. |
1000 | protected function reloadCSV() { |
1000 | protected function reloadCSV() { |
1001 | if (!file_exists($this->csvfile)) { |
1001 | if (!file_exists($this->csvfile)) { |
1002 | throw new OIDInfoException("File '".$this->csvfile."' does not exist"); |
1002 | throw new OIDInfoException("File '".$this->csvfile."' does not exist"); |
1003 | } |
1003 | } |
1004 | $filemtime = filemtime($this->csvfile); |
1004 | $filemtime = filemtime($this->csvfile); |
1005 | if ($filemtime != $this->filemtime) { |
1005 | if ($filemtime != $this->filemtime) { |
1006 | $this->lines = file($this->csvfile); |
1006 | $this->lines = file($this->csvfile); |
1007 | $this->filemtime = $filemtime; |
1007 | $this->filemtime = $filemtime; |
1008 | } |
1008 | } |
1009 | } |
1009 | } |
1010 | 1010 | ||
1011 | function __construct($csvfile) { |
1011 | function __construct($csvfile) { |
1012 | $this->csvfile = $csvfile; |
1012 | $this->csvfile = $csvfile; |
1013 | $this->reloadCSV(); |
1013 | $this->reloadCSV(); |
1014 | } |
1014 | } |
1015 | } |
1015 | } |
1016 | 1016 | ||
1017 | 1017 | ||
1018 | class OIDSimplePingProvider implements IOIDSimplePingProvider { |
1018 | class OIDSimplePingProvider implements IOIDSimplePingProvider { |
1019 | protected $addr = ''; |
1019 | protected $addr = ''; |
1020 | protected $connected = false; |
1020 | protected $connected = false; |
1021 | protected $socket = null; |
1021 | protected $socket = null; |
1022 | 1022 | ||
1023 | const SPP_MAX_CONNECTION_ATTEMPTS = 3; // TODO: Put into an OIDInfoAPI class...? |
1023 | const SPP_MAX_CONNECTION_ATTEMPTS = 3; // TODO: Put into an OIDInfoAPI class...? |
1024 | 1024 | ||
1025 | const DEFAULT_PORT = 49500; |
1025 | const DEFAULT_PORT = 49500; |
1026 | 1026 | ||
1027 | protected function spp_reader_init() { |
1027 | protected function spp_reader_init() { |
1028 | $this->spp_reader_uninit(); |
1028 | $this->spp_reader_uninit(); |
1029 | 1029 | ||
1030 | $ary = explode(':', $this->addr); // TODO: does not work with an IPv6 address |
1030 | $ary = explode(':', $this->addr); // TODO: does not work with an IPv6 address |
1031 | $host = $ary[0]; |
1031 | $host = $ary[0]; |
1032 | $service_port = isset($ary[1]) ? $ary[1] : self::DEFAULT_PORT; |
1032 | $service_port = isset($ary[1]) ? $ary[1] : self::DEFAULT_PORT; |
1033 | 1033 | ||
1034 | $is_ip = filter_var($host, FILTER_VALIDATE_IP) !== false; |
1034 | $is_ip = filter_var($host, FILTER_VALIDATE_IP) !== false; |
1035 | if (!$is_ip) { |
1035 | if (!$is_ip) { |
1036 | $address = @gethostbyname($host); |
1036 | $address = @gethostbyname($host); |
1037 | if ($address === $host) { |
1037 | if ($address === $host) { |
1038 | $msg = "gethostbyname() failed.\n"; // TODO: exceptions? (also all "echos" below) |
1038 | $msg = "gethostbyname() failed.\n"; // TODO: exceptions? (also all "echos" below) |
1039 | throw new Exception($msg); |
1039 | throw new Exception($msg); |
1040 | // echo $msg; |
1040 | // echo $msg; |
1041 | // return false; |
1041 | // return false; |
1042 | } |
1042 | } |
1043 | } else { |
1043 | } else { |
1044 | $address = $host; |
1044 | $address = $host; |
1045 | } |
1045 | } |
1046 | 1046 | ||
1047 | $this->socket = @socket_create(AF_INET, SOCK_STREAM, SOL_TCP); |
1047 | $this->socket = @socket_create(AF_INET, SOCK_STREAM, SOL_TCP); |
1048 | if ($this->socket === false) { |
1048 | if ($this->socket === false) { |
1049 | $msg = "socket_create() failed: " . socket_strerror(socket_last_error()) . "\n"; |
1049 | $msg = "socket_create() failed: " . socket_strerror(socket_last_error()) . "\n"; |
1050 | throw new Exception($msg); |
1050 | throw new Exception($msg); |
1051 | // echo $msg; |
1051 | // echo $msg; |
1052 | // return false; |
1052 | // return false; |
1053 | } |
1053 | } |
1054 | $result = @socket_connect($this->socket, $address, $service_port); |
1054 | $result = @socket_connect($this->socket, $address, $service_port); |
1055 | if ($result === false) { |
1055 | if ($result === false) { |
1056 | $msg = "socket_connect() failed: " . socket_strerror(socket_last_error($this->socket)) . "\n"; |
1056 | $msg = "socket_connect() failed: " . socket_strerror(socket_last_error($this->socket)) . "\n"; |
1057 | throw new Exception($msg); |
1057 | throw new Exception($msg); |
1058 | // echo $msg; |
1058 | // echo $msg; |
1059 | // return false; |
1059 | // return false; |
1060 | } |
1060 | } |
1061 | 1061 | ||
1062 | $this->connected = true; |
1062 | $this->connected = true; |
1063 | } |
1063 | } |
1064 | 1064 | ||
1065 | protected function spp_reader_avail($oid, $failcount=0) { |
1065 | protected function spp_reader_avail($oid, $failcount=0) { |
1066 | $in = "${oid}\n\0"; // PHP's socket_send() does not send a trailing \n . There needs to be something after the \n ... :( |
1066 | $in = "${oid}\n\0"; // PHP's socket_send() does not send a trailing \n . There needs to be something after the \n ... :( |
1067 | 1067 | ||
1068 | if ($failcount >= self::SPP_MAX_CONNECTION_ATTEMPTS) { |
1068 | if ($failcount >= self::SPP_MAX_CONNECTION_ATTEMPTS) { |
1069 | $msg = "Query $oid: CONNECTION TO SIMPLE PING PROVIDER FAILED!\n"; |
1069 | $msg = "Query $oid: CONNECTION TO SIMPLE PING PROVIDER FAILED!\n"; |
1070 | throw new Exception($msg); |
1070 | throw new Exception($msg); |
1071 | // echo $msg; |
1071 | // echo $msg; |
1072 | // return null; |
1072 | // return null; |
1073 | } |
1073 | } |
1074 | 1074 | ||
1075 | if (!$this->connected) { |
1075 | if (!$this->connected) { |
1076 | $this->spp_reader_init(); |
1076 | $this->spp_reader_init(); |
1077 | } |
1077 | } |
1078 | 1078 | ||
1079 | $s = @socket_send($this->socket, $in, strlen($in), 0); |
1079 | $s = @socket_send($this->socket, $in, strlen($in), 0); |
1080 | if ($s != strlen($in)) { |
1080 | if ($s != strlen($in)) { |
1081 | // echo "Query $oid: Sending failed\n"; |
1081 | // echo "Query $oid: Sending failed\n"; |
1082 | $this->spp_reader_init(); |
1082 | $this->spp_reader_init(); |
1083 | if (!$this->socket) return null; |
1083 | if (!$this->socket) return null; |
1084 | return $this->spp_reader_avail($oid, $failcount+1); |
1084 | return $this->spp_reader_avail($oid, $failcount+1); |
1085 | } |
1085 | } |
1086 | 1086 | ||
1087 | $out = @socket_read($this->socket, 2048); |
1087 | $out = @socket_read($this->socket, 2048); |
1088 | if (trim($out) == '1') { |
1088 | if (trim($out) == '1') { |
1089 | return true; |
1089 | return true; |
1090 | } else if (trim($out) == '0') { |
1090 | } else if (trim($out) == '0') { |
1091 | return false; |
1091 | return false; |
1092 | } else { |
1092 | } else { |
1093 | // echo "Query $oid: Receiving failed\n"; |
1093 | // echo "Query $oid: Receiving failed\n"; |
1094 | $this->spp_reader_init(); |
1094 | $this->spp_reader_init(); |
1095 | if (!$this->socket) return null; |
1095 | if (!$this->socket) return null; |
1096 | return $this->spp_reader_avail($oid, $failcount+1); |
1096 | return $this->spp_reader_avail($oid, $failcount+1); |
1097 | } |
1097 | } |
1098 | } |
1098 | } |
1099 | 1099 | ||
1100 | protected function spp_reader_uninit() { |
1100 | protected function spp_reader_uninit() { |
1101 | if (!$this->connected) return; |
1101 | if (!$this->connected) return; |
1102 | @socket_close($this->socket); |
1102 | @socket_close($this->socket); |
1103 | $this->connected = false; |
1103 | $this->connected = false; |
1104 | } |
1104 | } |
1105 | 1105 | ||
1106 | public function queryOID($oid) { |
1106 | public function queryOID($oid) { |
1107 | if (trim($oid) === 'bye') return null; |
1107 | if (trim($oid) === 'bye') return null; |
1108 | return $this->spp_reader_avail($oid); |
1108 | return $this->spp_reader_avail($oid); |
1109 | } |
1109 | } |
1110 | 1110 | ||
1111 | public function disconnect() { |
1111 | public function disconnect() { |
1112 | return $this->spp_reader_uninit(); |
1112 | return $this->spp_reader_uninit(); |
1113 | } |
1113 | } |
1114 | 1114 | ||
1115 | public function connect() { |
1115 | public function connect() { |
1116 | return $this->spp_reader_init(); |
1116 | return $this->spp_reader_init(); |
1117 | } |
1117 | } |
1118 | 1118 | ||
1119 | function __construct($addr='localhost:49500') { |
1119 | function __construct($addr='localhost:49500') { |
1120 | $this->addr = $addr; |
1120 | $this->addr = $addr; |
1121 | } |
1121 | } |
1122 | 1122 | ||
1123 | } |
1123 | } |
1124 | 1124 |