Guest User

482

a guest
Sep 6th, 2016
222
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 12.47 KB | None | 0 0
  1. <?php
  2. /**
  3. * @package NoNumber Framework
  4. * @version 16.8.1269
  5. *
  6. * @author Peter van Westen <[email protected]>
  7. * @link http://www.regularlabs.com
  8. * @copyright Copyright © 2016 Regular Labs All Rights Reserved
  9. * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL
  10. */
  11.  
  12. defined('_JEXEC') or die;
  13.  
  14. class NNTags
  15. {
  16. public static function getValuesFromString($string = '', $main_key = 'title', $known_boolean_keys = array())
  17. {
  18. // Only one value, so return simple key/value object
  19. if (strpos($string, '="') == false && strpos($string, '|') == false)
  20. {
  21. return (object) array($main_key => $string);
  22. }
  23.  
  24. self::protectSpecialChars($string);
  25.  
  26. // No foo="bar" syntax found, so assume old syntax
  27. if (strpos($string, '="') == false)
  28. {
  29. self::unprotectSpecialChars($string);
  30.  
  31. $values = self::getTagValues($string, array($main_key));
  32. self::convertOldSyntax($values, $known_boolean_keys);
  33.  
  34. return $values;
  35. }
  36.  
  37. // Cannot find right syntax, so return simple key/value object
  38. if (!preg_match_all('#([a-z0-9-_]+)\s*=\s*"(.*?)"#si', $string, $values))
  39. {
  40. return (object) array($main_key => $string);
  41. }
  42.  
  43. $tag = new stdClass;
  44.  
  45. foreach ($values['1'] as $i => $key)
  46. {
  47. $value = $values['2'][$i];
  48.  
  49. self::unprotectSpecialChars($value);
  50.  
  51. // Convert numeric values to ints/floats
  52. if (is_numeric($value))
  53. {
  54. $value = $value + 0;
  55. }
  56.  
  57. // Convert boolean values to actual booleans
  58. $value = ($value === 'true' ? true : $value);
  59. $value = ($value === 'false' ? false : $value);
  60.  
  61. $tag->{$key} = $value;
  62. }
  63.  
  64. return $tag;
  65. }
  66.  
  67. public static function protectSpecialChars(&$string)
  68. {
  69. $temp_equal = '[[EQUAL]]';
  70. $temp_quote = '[[QUOTE]]';
  71.  
  72. // replace escaped characters with special markup
  73. $string = str_replace(
  74. array('\\=', '\\"'),
  75. array($temp_equal, $temp_quote),
  76. $string
  77. );
  78.  
  79. if (!preg_match_all('#<.*?>#s', $string, $tags))
  80. {
  81. return;
  82. }
  83.  
  84. foreach ($tags['0'] as $tag)
  85. {
  86. // replace unescaped characters with special markup
  87. $protected = str_replace(
  88. array('=', '"'),
  89. array($temp_equal, $temp_quote),
  90. $tag
  91. );
  92. $string = str_replace($tag, $protected, $string);
  93. }
  94. }
  95.  
  96. public static function unprotectSpecialChars(&$string)
  97. {
  98. $temp_equal = '[[EQUAL]]';
  99. $temp_quote = '[[QUOTE]]';
  100.  
  101. // replace special markup with unescaped characters
  102. $string = str_replace(
  103. array($temp_equal, $temp_quote),
  104. array('=', '"'),
  105. $string
  106. );
  107. }
  108.  
  109. /* @Deprecated */
  110. public static function getTagValues($string = '', $keys = array('title'), $separator = '|', $equal = '=', $limit = 0)
  111. {
  112. $temp_separator = '[[SEPARATOR]]';
  113. $temp_equal = '[[EQUAL]]';
  114. $tag_start = '[[TAG]]';
  115. $tag_end = '[[/TAG]]';
  116.  
  117. // replace separators and equal signs with special markup
  118. $string = str_replace(array($separator, $equal), array($temp_separator, $temp_equal), $string);
  119. // replace protected separators and equal signs back to original
  120. $string = str_replace(array('\\' . $temp_separator, '\\' . $temp_equal), array($separator, $equal), $string);
  121.  
  122. // protect all html tags
  123. preg_match_all('#</?[a-z][^>]*>#si', $string, $tags, PREG_SET_ORDER);
  124.  
  125. if (!empty($tags))
  126. {
  127. foreach ($tags as $tag)
  128. {
  129. $string = str_replace(
  130. $tag['0'],
  131. $tag_start . base64_encode(str_replace(array($temp_separator, $temp_equal), array($separator, $equal), $tag['0'])) . $tag_end,
  132. $string
  133. );
  134. }
  135. }
  136.  
  137. // split string into array
  138. $vals = $limit
  139. ? explode($temp_separator, $string, (int) $limit)
  140. : explode($temp_separator, $string);
  141.  
  142. // initialize return vars
  143. $tag_values = new stdClass;
  144. $tag_values->params = array();
  145.  
  146. // loop through splits
  147. foreach ($vals as $i => $keyval)
  148. {
  149. // spit part into key and val by equal sign
  150. $keyval = explode($temp_equal, $keyval, 2);
  151. if (isset($keyval['1']))
  152. {
  153. $keyval['1'] = str_replace(array($temp_separator, $temp_equal), array($separator, $equal), $keyval['1']);
  154. }
  155.  
  156. // unprotect tags in key and val
  157. foreach ($keyval as $key => $val)
  158. {
  159. preg_match_all('#' . preg_quote($tag_start, '#') . '(.*?)' . preg_quote($tag_end, '#') . '#si', $val, $tags, PREG_SET_ORDER);
  160.  
  161. if (!empty($tags))
  162. {
  163. foreach ($tags as $tag)
  164. {
  165. $val = str_replace($tag['0'], base64_decode($tag['1']), $val);
  166. }
  167.  
  168. $keyval[trim($key)] = $val;
  169. }
  170. }
  171.  
  172. if (isset($keys[$i]))
  173. {
  174. $key = trim($keys[$i]);
  175. // if value is in the keys array add as defined in keys array
  176. // ignore equal sign
  177. $val = implode($equal, $keyval);
  178. if (substr($val, 0, strlen($key) + 1) == $key . '=')
  179. {
  180. $val = substr($val, strlen($key) + 1);
  181. }
  182. $tag_values->{$key} = $val;
  183. unset($keys[$i]);
  184. }
  185. else
  186. {
  187. // else add as defined in the string
  188. if (isset($keyval['1']))
  189. {
  190. $tag_values->{$keyval['0']} = $keyval['1'];
  191. }
  192. else
  193. {
  194. $tag_values->params[] = implode($equal, $keyval);
  195. }
  196. }
  197. }
  198.  
  199. return $tag_values;
  200. }
  201.  
  202. public static function replaceKeyAliases(&$values, $key_aliases = array())
  203. {
  204. foreach ($key_aliases as $key => $aliases)
  205. {
  206. if (isset($values->{$key}))
  207. {
  208. continue;
  209. }
  210.  
  211. foreach ($aliases as $alias)
  212. {
  213. if (!isset($values->{$alias}))
  214. {
  215. continue;
  216. }
  217.  
  218. $values->{$key} = $values->{$alias};
  219. unset($values->{$alias});
  220. }
  221. }
  222. }
  223.  
  224. public static function convertOldSyntax(&$values, $known_boolean_keys = array(), $extra_key = 'class')
  225. {
  226. $extra = isset($values->class) ? array($values->class) : array();
  227.  
  228. foreach ($values->params as $i => $param)
  229. {
  230. if (!$param)
  231. {
  232. continue;
  233. }
  234.  
  235. if (in_array($param, $known_boolean_keys))
  236. {
  237. $values->{$param} = true;
  238. continue;
  239. }
  240.  
  241. if (strpos($param, '=') == false)
  242. {
  243. $extra[] = $param;
  244. continue;
  245. }
  246.  
  247. list($key, $val) = explode('=', $param, 2);
  248.  
  249. $values->{$key} = $val;
  250. }
  251.  
  252. $values->{$extra_key} = trim(implode(' ', $extra));
  253.  
  254. unset($values->params);
  255. }
  256.  
  257. public static function getRegexSpaces($modifier = '+')
  258. {
  259. return '(?:\s|&nbsp;|&\#160;)' . $modifier;
  260. }
  261.  
  262. public static function getRegexInsideTag()
  263. {
  264. return '(?:[^\{\}]*\{[^\}]*\})*.*?';
  265. }
  266.  
  267. public static function getRegexSurroundingTagPre($elements = array('p', 'span'))
  268. {
  269. return '(?:<(?:' . implode('|', $elements) . ')(?: [^>]*)?>\s*(?:<br ?/?>\s*)*){0,3}';
  270. }
  271.  
  272. public static function getRegexSurroundingTagPost($elements = array('p', 'span'))
  273. {
  274. return '(?:(?:\s*<br ?/?>)*\s*<\/(?:' . implode('|', $elements) . ')>){0,3}';
  275. }
  276.  
  277. public static function getRegexTags($tags, $include_no_attributes = true, $include_ending = true, $required_attributes = array())
  278. {
  279. require_once __DIR__ . '/text.php';
  280.  
  281. $tags = NNText::toArray($tags);
  282. $tags = count($tags) > 1 ? '(?:' . implode('|', $tags) . ')' : $tags['0'];
  283.  
  284. $value = '(?:\s*=\s*(?:"[^"]*"|\'[^\']*\'|[a-z0-9-_]+))?';
  285. $attributes = '(?:\s+[a-z0-9-_]+' . $value . ')+';
  286.  
  287. $required_attributes = NNText::toArray($required_attributes);
  288. if (!empty($required_attributes))
  289. {
  290. $attributes = '(?:' . $attributes . ')?' . '(?:\s+' . implode('|', $required_attributes) . ')' . $value . '(?:' . $attributes . ')?';
  291. }
  292.  
  293. if ($include_no_attributes)
  294. {
  295. $attributes = '\s*(?:' . $attributes . ')?';
  296. }
  297.  
  298. if (!$include_ending)
  299. {
  300. return '<' . $tags . $attributes . '\s*/?>';
  301. }
  302.  
  303. return '<(?:\/' . $tags . '|' . $tags . $attributes . '\s*/?)\s*/?>';
  304. }
  305.  
  306. public static function cleanSurroundingTags($tags, $elements = array('p', 'span'))
  307. {
  308. require_once __DIR__ . '/text.php';
  309.  
  310. $breaks = '(?:(?:<br ?/?>|:\|:)\s*)*';
  311. $keys = array_keys($tags);
  312.  
  313. $string = implode(':|:', $tags);
  314. // Remove empty tags
  315. while (preg_match('#<(' . implode('|', $elements) . ')(?: [^>]*)?>\s*(' . $breaks . ')<\/\1>\s*#s', $string, $match))
  316. {
  317. $string = str_replace($match['0'], $match['2'], $string);
  318. }
  319.  
  320. // Remove paragraphs around block elements
  321. $block_elements = array(
  322. 'p', 'div',
  323. 'table', 'tr', 'td', 'thead', 'tfoot',
  324. 'h[1-6]',
  325. );
  326. $block_elements = '(' . implode('|', $block_elements) . ')';
  327. while (preg_match('#(<p(?: [^>]*)?>)(\s*' . $breaks . ')(<' . $block_elements . '(?: [^>]*)?>)#s', $string, $match))
  328. {
  329. if ($match['4'] == 'p')
  330. {
  331. $match['3'] = $match['1'] . $match['3'];
  332. NNText::combinePTags($match['3']);
  333. }
  334.  
  335. $string = str_replace($match['0'], $match['2'] . $match['3'], $string);
  336. }
  337. while (preg_match('#(</' . $block_elements . '>\s*' . $breaks . ')</p>#s', $string, $match))
  338. {
  339. $string = str_replace($match['0'], $match['1'], $string);
  340. }
  341.  
  342. $tags = explode(':|:', $string);
  343.  
  344. $new_tags = array();
  345.  
  346. foreach ($tags as $key => $val)
  347. {
  348. $key = isset($keys[$key]) ? $keys[$key] : $key;
  349. $new_tags[$key] = $val;
  350. }
  351.  
  352. return $new_tags;
  353. }
  354.  
  355. public static function fixSurroundingTags($tags)
  356. {
  357. $keys = array_keys($tags);
  358.  
  359. $breaks = '(?:(?:<br ?/?>|:\|:)\s*)*';
  360. $string = implode(':|:', $tags);
  361.  
  362. // Remove inline elements around block elements
  363. $string = preg_replace('#'
  364. . '<(?:' . implode('|', self::getInlineElements()) . ')(?: [^>]*)?>'
  365. . '(' . $breaks . '<(?:' . implode('|', self::getBlockElements()) . ')(?: [^>]*)?>)'
  366. . '#',
  367. '\1', $string);
  368. $string = preg_replace('#'
  369. . '(</(?:' . implode('|', self::getBlockElements()) . ')>' . $breaks . ')'
  370. . '</(?:' . implode('|', self::getInlineElements()) . ')>'
  371. . '#',
  372. '\1', $string);
  373.  
  374. // Remove inner <p> tags if outer start/end <p> tags are found
  375. $string = preg_replace('#'
  376. . '(<(?:' . implode('|', self::getBlockElementsNoDiv()) . ')(?: [^>]*)?>' . $breaks . ')'
  377. . '<p(?: [^>]*)?>(.*)</p>'
  378. . '(' . $breaks . ')'
  379. . '#',
  380. '\1\2\3', $string);
  381. $string = preg_replace('#'
  382. . '(' . $breaks . ')'
  383. . '<p(?: [^>]*)?>(.*)</p>'
  384. . '(' . $breaks . '</(?:' . implode('|', self::getBlockElementsNoDiv()) . ')>)'
  385. . '#',
  386. '\1\2\3', $string);
  387.  
  388. // Remove outer <p> tags around block elements
  389. $string = preg_replace('#'
  390. . '^\s*<p(?: [^>]*)?>'
  391. . '(' . $breaks . '</?(?:' . implode('|', self::getBlockElements()) . ')(?: [^>]*)?>)'
  392. . '#',
  393. '\1', $string);
  394. $string = preg_replace('#'
  395. . '(</?(?:' . implode('|', self::getBlockElements()) . ')>' . $breaks . ')'
  396. . '</p>\s*$'
  397. . '#',
  398. '\1', $string);
  399.  
  400. $tags = explode(':|:', $string);
  401.  
  402. $new_tags = array();
  403.  
  404. foreach ($tags as $key => $val)
  405. {
  406. $key = isset($keys[$key]) ? $keys[$key] : $key;
  407. $new_tags[$key] = $val;
  408. }
  409.  
  410. return $new_tags;
  411. }
  412.  
  413. private static function getBlockElements()
  414. {
  415. return array(
  416. 'div', 'p', 'pre',
  417. 'h1', 'h2', 'h3', 'h4', 'h5', 'h6',
  418. );
  419. }
  420.  
  421. private static function getBlockElementsNoDiv()
  422. {
  423. return array(
  424. 'p', 'pre',
  425. 'h1', 'h2', 'h3', 'h4', 'h5', 'h6',
  426. );
  427. }
  428.  
  429. private static function getInlineElements()
  430. {
  431. return array(
  432. 'span', 'code', 'a',
  433. 'strong', 'b', 'em', 'i', 'u', 'big', 'small', 'font',
  434. );
  435. }
  436.  
  437. public static function setSurroundingTags($pre, $post, $tags = 0)
  438. {
  439. if ($tags == 0)
  440. {
  441. // tags that have a matching ending tag
  442. $tags = array(
  443. 'div', 'p', 'span', 'pre', 'a',
  444. 'h1', 'h2', 'h3', 'h4', 'h5', 'h6',
  445. 'strong', 'b', 'em', 'i', 'u', 'big', 'small', 'font',
  446. // html 5 stuff
  447. 'header', 'nav', 'section', 'article', 'aside', 'footer',
  448. 'figure', 'figcaption', 'details', 'summary', 'mark', 'time',
  449. );
  450. }
  451. $a = explode('<', $pre);
  452. $b = explode('</', $post);
  453.  
  454. if (count($b) > 1 && count($a) > 1)
  455. {
  456. $a = array_reverse($a);
  457. $a_pre = array_pop($a);
  458. $b_pre = array_shift($b);
  459. $a_tags = $a;
  460. foreach ($a_tags as $i => $a_tag)
  461. {
  462. $a[$i] = '<' . trim($a_tag);
  463. $a_tags[$i] = preg_replace('#^([a-z0-9]+).*$#', '\1', trim($a_tag));
  464. }
  465. $b_tags = $b;
  466. foreach ($b_tags as $i => $b_tag)
  467. {
  468. $b[$i] = '</' . trim($b_tag);
  469. $b_tags[$i] = preg_replace('#^([a-z0-9]+).*$#', '\1', trim($b_tag));
  470. }
  471. foreach ($b_tags as $i => $b_tag)
  472. {
  473. if ($b_tag && in_array($b_tag, $tags))
  474. {
  475. foreach ($a_tags as $j => $a_tag)
  476. {
  477. if ($b_tag == $a_tag)
  478. {
  479. $a_tags[$i] = '';
  480. $b[$i] = trim(preg_replace('#^</' . $b_tag . '.*?>#', '', $b[$i]));
  481. $a[$j] = trim(preg_replace('#^<' . $a_tag . '.*?>#', '', $a[$j]));
Add Comment
Please, Sign In to add comment