PageRenderTime 40ms CodeModel.GetById 11ms RepoModel.GetById 0ms app.codeStats 1ms

/includes/IntuitionUtil.php

https://github.com/Hedonil/intuition
PHP | 284 lines | 171 code | 36 blank | 77 comment | 31 complexity | 82e7875b305b5005190042546c7e11e7 MD5 | raw file
Possible License(s): GPL-2.0
  1. <?php
  2. /**
  3. * Static utitlities class.
  4. *
  5. * @copyright 2011-2014 See AUTHORS.txt
  6. * @license CC-BY 3.0 <https://creativecommons.org/licenses/by/3.0/>
  7. * @package intuition
  8. */
  9. // Protect against invalid entry
  10. if ( !defined( 'INTUITION' ) ) {
  11. echo "This file is not a valid entry point\n";
  12. exit;
  13. }
  14. /**
  15. * This class contains the static utility functions for the Itui class.
  16. */
  17. class IntuitionUtil {
  18. private static $articlePath;
  19. /**
  20. * Escapes a string with one of the known method and returns it
  21. *
  22. * @param $str string The string to be escaped
  23. * @param $escape string The name of the escape routine to be used
  24. * if this is an unknown method name it will be ignored and 'plain'
  25. * will be used instead.
  26. * @return string The escaped string.
  27. */
  28. public static function strEscape( $str, $escape = 'plain' ) {
  29. switch ( $escape ) {
  30. case 'html' :
  31. case 'htmlspecialchars' :
  32. $str = htmlspecialchars( $str );
  33. break;
  34. case 'htmlentities':
  35. $str = htmlentities( $str, ENT_QUOTES, 'UTF-8' );
  36. break;
  37. // 'plain' or anything else: Do nothing
  38. }
  39. return $str;
  40. }
  41. public static function nonEmptyStr( $var ) {
  42. if ( is_string( $var ) && $var !== '' ) {
  43. return true;
  44. }
  45. return false;
  46. }
  47. /**
  48. * Pass one or more arguments which will be checked until one fails
  49. * If atleast one argument is not a non-empty string, or if no arguments / NULL passed
  50. * it will return false, otherwise true;
  51. */
  52. public static function nonEmptyStrs( /* $var .. */ ) {
  53. $args = func_get_args();
  54. if ( !isset( $args[0] ) ) {
  55. return false;
  56. }
  57. foreach ( $args as $arg) {
  58. if ( !self::nonEmptyStr( $arg ) ) {
  59. return false;
  60. }
  61. }
  62. // If we're still here, all are good
  63. return true;
  64. }
  65. /**
  66. * A return version of var_dump().
  67. * Optionally html-escaped and wrapped in a <pre>-tag.
  68. *
  69. * @return string
  70. */
  71. public static function returnDump( $var, $html = true) {
  72. $dump = null;
  73. ob_start();
  74. var_dump( $var );
  75. $dump = ob_get_contents();
  76. ob_end_clean();
  77. if ( $html ) {
  78. return '<pre>' . htmlspecialchars( $dump ) . '</pre>';
  79. }
  80. return $dump;
  81. }
  82. /* Primitive html building */
  83. /* Based on kfTag from the BaseTool class */
  84. public static function tag( $str, $wrapTag = 0, $attributes = array() ) {
  85. $selfclose = array( 'link', 'input', 'br', 'img' );
  86. if ( is_string( $str ) ) {
  87. if ( is_string( $wrapTag ) ) {
  88. $wrapTag = trim( strtolower( $wrapTag ) );
  89. $attrString = '';
  90. if ( is_array ( $attributes ) ) {
  91. foreach ( $attributes as $attrKey => $attrVal ) {
  92. $attrKey = htmlspecialchars( trim( strtolower( $attrKey ) ), ENT_QUOTES);
  93. $attrVal = htmlspecialchars( trim( $attrVal ), ENT_QUOTES);
  94. $attrString .= " $attrKey=\"$attrVal\"";
  95. }
  96. }
  97. $return = "<$wrapTag$attrString";
  98. if ( in_array( $wrapTag, $selfclose ) ) {
  99. $return .= '/>';
  100. } else {
  101. $return .= ">" . htmlspecialchars( $str ) ."</$wrapTag>";
  102. }
  103. } else {
  104. $return = $str;
  105. }
  106. return $return;
  107. } else {
  108. return '';
  109. }
  110. }
  111. /**
  112. * Return a list of acceptable languages from an Accept-Language header.
  113. * @param $rawList String List of language tags, formatted like an
  114. * HTTP Accept-Language header (optional; defaults to $_SERVER['HTTP_ACCEPT_LANGUAGE'])
  115. * @return array keyed by language codes with q-values as values.
  116. */
  117. public static function getAcceptableLanguages( $rawList = false ) {
  118. // Implementation based on MediaWiki 1.21's WebRequest::getAcceptLang
  119. // Which is based on http://www.thefutureoftheweb.com/blog/use-accept-language-header
  120. if ( $rawList === false ) {
  121. $rawList = isset( $_SERVER['HTTP_ACCEPT_LANGUAGE'] ) ?
  122. $_SERVER['HTTP_ACCEPT_LANGUAGE'] :
  123. '';
  124. }
  125. // Return the language codes in lower case
  126. $rawList = strtolower( $rawList );
  127. // The list of elements is separated by comma and optional LWS
  128. // Extract the language-range and, if present, the q-value
  129. $lang_parse = null;
  130. preg_match_all(
  131. '/([a-z]{1,8}(-[a-z]{1,8})*|\*)\s*(;\s*q\s*=\s*(1(\.0{0,3})?|0(\.[0-9]{0,3})?)?)?/',
  132. $rawList,
  133. $lang_parse
  134. );
  135. if ( !count( $lang_parse[1] ) ) {
  136. return array();
  137. }
  138. $langcodes = $lang_parse[1];
  139. $qvalues = $lang_parse[4];
  140. $indices = range( 0, count( $lang_parse[1] ) - 1 );
  141. // Set default q factor to 1
  142. foreach ( $indices as $index ) {
  143. if ( $qvalues[$index] === '' ) {
  144. $qvalues[$index] = 1;
  145. } elseif ( $qvalues[$index] == 0 ) {
  146. unset( $langcodes[$index], $qvalues[$index], $indices[$index] );
  147. } else {
  148. $qvalues[$index] = floatval( $qvalues[$index] );
  149. }
  150. }
  151. // Sort list. First by $qvalues, then by order. Reorder $langcodes the same way
  152. array_multisort( $qvalues, SORT_DESC, SORT_NUMERIC, $indices, $langcodes );
  153. // Create a list like "en" => 0.8
  154. $langs = array_combine( $langcodes, $qvalues );
  155. return $langs;
  156. }
  157. const EXT_LINK_URL_CLASS = '[^][<>"\\x00-\\x20\\x7F\p{Zs}]'; // Copied from Parser class
  158. /**
  159. * Given a text already html-escaped which contains urls in wiki format,
  160. * convert it to html.
  161. * @param $text
  162. * @return string
  163. */
  164. public static function parseExternalLinks( $text ) {
  165. static $urlProtocols = false;
  166. if ( !$urlProtocols ) {
  167. // Allow custom protocols
  168. if ( function_exists( 'wfUrlProtocols' ) ) {
  169. $urlProtocols = wfUrlProtocols();
  170. } else {
  171. $urlProtocols = 'https?:\/\/|ftp:\/\/';
  172. }
  173. }
  174. $extLinkBracketedRegex = '/(?:(<[^>]*)|' .
  175. '\[(((?i)' . $urlProtocols . ')' .
  176. self::EXT_LINK_URL_CLASS .
  177. '+)\p{Zs}*([^\]\\x00-\\x08\\x0a-\\x1F]*?)\]|' .
  178. '(((?i)' . $urlProtocols . ')' .
  179. self::EXT_LINK_URL_CLASS .
  180. '+))/Su';
  181. return preg_replace_callback(
  182. $extLinkBracketedRegex,
  183. 'self::parseExternalLinkArray',
  184. $text
  185. );
  186. }
  187. /**
  188. * Changes the matches of parseExternalLinks into html.
  189. */
  190. private static function parseExternalLinkArray( $bits ) {
  191. static $counter = 0;
  192. if ( $bits[1] != '' )
  193. return $bits[1];
  194. if ( isset( $bits[4] ) && $bits[4] != '' ) {
  195. return '<a href="' . $bits[2] . '">' . $bits[4] . '</a>';
  196. } elseif ( isset( $bits[5] ) ) {
  197. return '<a href="' . $bits[5] . '">' . $bits[5] . '</a>';
  198. } else {
  199. return '<a href="' . $bits[2] . '">[' . ++$counter . ']</a>';
  200. }
  201. }
  202. /**
  203. * Given a text already html-escaped which contains wiki links, convert them to html.
  204. * @param $text
  205. * @param $articlePath
  206. * @return string
  207. */
  208. public static function parseWikiLinks( $text, $articlePath ) {
  209. self::$articlePath = $articlePath;
  210. return preg_replace_callback(
  211. '/\[\[:?([^]|]+)(?:\|([^]]*))?\]\]/',
  212. 'self::parseWikiLinkArray',
  213. $text
  214. );
  215. }
  216. /**
  217. * Changes the matches of parseWikiLinks into html
  218. */
  219. private static function parseWikiLinkArray( $bits ) {
  220. if ( !isset( $bits[2] ) || $bits[2] == '' ) {
  221. $bits[2] = strtr( $bits[1], '_', ' ' );
  222. }
  223. $article = html_entity_decode( $bits[1], ENT_QUOTES, 'UTF-8' );
  224. return '<a href="' . htmlspecialchars(
  225. self::prettyEncodedWikiUrl( self::$articlePath, $article ), ENT_COMPAT, 'UTF-8'
  226. ) . '">' . $bits[2] . "</a>";
  227. }
  228. /**
  229. * Builds a pretty url link to a wiki article.
  230. * It assumes the wiki is not hosted on IIS7.
  231. *
  232. * Most of this logic is taken from wfUrlencode().
  233. * @param $articlePath
  234. * @param $article
  235. * @return string
  236. */
  237. public static function prettyEncodedWikiUrl( $articlePath, $article ) {
  238. $s = strtr( $article, ' ', '_' );
  239. $s = urlencode( $s );
  240. $s = str_ireplace(
  241. array( '%3B', '%40', '%24', '%21', '%2A', '%28', '%29', '%2C', '%2F', '%3A' ),
  242. array( ';', '@', '$', '!', '*', '(', ')', ',', '/', ':' ),
  243. $s
  244. );
  245. $s = str_replace( '$1', $s, $articlePath );
  246. return $s;
  247. }
  248. }