/phpmyadmin/libraries/Scripts.php

https://gitlab.com/luyxtran264/myproject · PHP · 292 lines · 171 code · 20 blank · 101 comment · 24 complexity · 142e05e4c854722735cfe9e05fff7002 MD5 · raw file

  1. <?php
  2. /* vim: set expandtab sw=4 ts=4 sts=4: */
  3. /**
  4. * JavaScript management
  5. *
  6. * @package PhpMyAdmin
  7. */
  8. namespace PMA\libraries;
  9. /**
  10. * Collects information about which JavaScript
  11. * files and objects are necessary to render
  12. * the page and generates the relevant code.
  13. *
  14. * @package PhpMyAdmin
  15. */
  16. class Scripts
  17. {
  18. /**
  19. * An array of SCRIPT tags
  20. *
  21. * @access private
  22. * @var array of strings
  23. */
  24. private $_files;
  25. /**
  26. * An array of discrete javascript code snippets
  27. *
  28. * @access private
  29. * @var array of strings
  30. */
  31. private $_code;
  32. /**
  33. * An array of event names to bind and javascript code
  34. * snippets to fire for the corresponding events
  35. *
  36. * @access private
  37. * @var array
  38. */
  39. private $_events;
  40. /**
  41. * Returns HTML code to include javascript file.
  42. *
  43. * @param array $files The list of js file to include
  44. *
  45. * @return string HTML code for javascript inclusion.
  46. */
  47. private function _includeFiles($files)
  48. {
  49. $first_dynamic_scripts = "";
  50. $dynamic_scripts = "";
  51. $scripts = array();
  52. $separator = PMA_URL_getArgSeparator();
  53. foreach ($files as $value) {
  54. if (mb_strpos($value['filename'], "?") !== false) {
  55. $file_name = $value['filename'] . $separator
  56. . Header::getVersionParameter();
  57. if ($value['before_statics'] === true) {
  58. $first_dynamic_scripts
  59. .= "<script data-cfasync='false' type='text/javascript' "
  60. . "src='js/" . $file_name . "'></script>";
  61. } else {
  62. $dynamic_scripts .= "<script data-cfasync='false' "
  63. . "type='text/javascript' src='js/" . $file_name
  64. . "'></script>";
  65. }
  66. continue;
  67. }
  68. $include = true;
  69. if ($value['conditional_ie'] !== false
  70. && PMA_USR_BROWSER_AGENT === 'IE'
  71. ) {
  72. if ($value['conditional_ie'] === true) {
  73. $include = true;
  74. } else if ($value['conditional_ie'] == PMA_USR_BROWSER_VER) {
  75. $include = true;
  76. } else {
  77. $include = false;
  78. }
  79. }
  80. if ($include) {
  81. $scripts[] = "scripts%5B%5D=" . $value['filename'];
  82. }
  83. }
  84. $separator = PMA_URL_getArgSeparator();
  85. $static_scripts = '';
  86. // Using chunks of 20 files to avoid too long URLs
  87. $script_chunks = array_chunk($scripts, 20);
  88. foreach ($script_chunks as $script_chunk) {
  89. $url = 'js/get_scripts.js.php?'
  90. . implode($separator, $script_chunk)
  91. . $separator . Header::getVersionParameter();
  92. $static_scripts .= sprintf(
  93. '<script data-cfasync="false" type="text/javascript" src="%s">' .
  94. '</script>',
  95. htmlspecialchars($url)
  96. );
  97. }
  98. return $first_dynamic_scripts . $static_scripts . $dynamic_scripts;
  99. }
  100. /**
  101. * Generates new Scripts objects
  102. *
  103. */
  104. public function __construct()
  105. {
  106. $this->_files = array();
  107. $this->_code = '';
  108. $this->_events = array();
  109. }
  110. /**
  111. * Adds a new file to the list of scripts
  112. *
  113. * @param string $filename The name of the file to include
  114. * @param bool $conditional_ie Whether to wrap the script tag in
  115. * conditional comments for IE
  116. * @param bool $before_statics Whether this dynamic script should be
  117. * included before the static ones
  118. *
  119. * @return void
  120. */
  121. public function addFile(
  122. $filename,
  123. $conditional_ie = false,
  124. $before_statics = false
  125. ) {
  126. $hash = md5($filename);
  127. if (!empty($this->_files[$hash])) {
  128. return;
  129. }
  130. $has_onload = $this->_eventBlacklist($filename);
  131. $this->_files[$hash] = array(
  132. 'has_onload' => $has_onload,
  133. 'filename' => $filename,
  134. 'conditional_ie' => $conditional_ie,
  135. 'before_statics' => $before_statics
  136. );
  137. }
  138. /**
  139. * Add new files to the list of scripts
  140. *
  141. * @param array $filelist The array of file names
  142. * @param bool $conditional_ie Whether to wrap the script tag in
  143. * conditional comments for IE
  144. *
  145. * @return void
  146. */
  147. public function addFiles($filelist, $conditional_ie = false)
  148. {
  149. foreach ($filelist as $filename) {
  150. $this->addFile($filename, $conditional_ie);
  151. }
  152. }
  153. /**
  154. * Determines whether to fire up an onload event for a file
  155. *
  156. * @param string $filename The name of the file to be checked
  157. * against the blacklist
  158. *
  159. * @return int 1 to fire up the event, 0 not to
  160. */
  161. private function _eventBlacklist($filename)
  162. {
  163. if (strpos($filename, 'jquery') !== false
  164. || strpos($filename, 'codemirror') !== false
  165. || strpos($filename, 'messages.php') !== false
  166. || strpos($filename, 'ajax.js') !== false
  167. || strpos($filename, 'get_image.js.php') !== false
  168. || strpos($filename, 'cross_framing_protection.js') !== false
  169. ) {
  170. return 0;
  171. }
  172. return 1;
  173. }
  174. /**
  175. * Adds a new code snippet to the code to be executed
  176. *
  177. * @param string $code The JS code to be added
  178. *
  179. * @return void
  180. */
  181. public function addCode($code)
  182. {
  183. $this->_code .= "$code\n";
  184. }
  185. /**
  186. * Adds a new event to the list of events
  187. *
  188. * @param string $event The name of the event to register
  189. * @param string $function The code to execute when the event fires
  190. * E.g: 'function () { doSomething(); }'
  191. * or 'doSomething'
  192. *
  193. * @return void
  194. */
  195. public function addEvent($event, $function)
  196. {
  197. $this->_events[] = array(
  198. 'event' => $event,
  199. 'function' => $function
  200. );
  201. }
  202. /**
  203. * Returns a list with filenames and a flag to indicate
  204. * whether to register onload events for this file
  205. *
  206. * @return array
  207. */
  208. public function getFiles()
  209. {
  210. $retval = array();
  211. foreach ($this->_files as $file) {
  212. //If filename contains a "?", continue.
  213. if (strpos($file['filename'], "?") !== false) {
  214. continue;
  215. }
  216. if (! $file['conditional_ie'] || PMA_USR_BROWSER_AGENT == 'IE') {
  217. $retval[] = array(
  218. 'name' => $file['filename'],
  219. 'fire' => $file['has_onload']
  220. );
  221. }
  222. }
  223. return $retval;
  224. }
  225. /**
  226. * Renders all the JavaScript file inclusions, code and events
  227. *
  228. * @return string
  229. */
  230. public function getDisplay()
  231. {
  232. $retval = '';
  233. if (count($this->_files) > 0) {
  234. $retval .= $this->_includeFiles(
  235. $this->_files
  236. );
  237. }
  238. $code = 'AJAX.scriptHandler';
  239. foreach ($this->_files as $file) {
  240. $code .= sprintf(
  241. '.add("%s",%d)',
  242. PMA_escapeJsString($file['filename']),
  243. $file['has_onload'] ? 1 : 0
  244. );
  245. }
  246. $code .= ';';
  247. $this->addCode($code);
  248. $code = '$(function() {';
  249. foreach ($this->_files as $file) {
  250. if ($file['has_onload']) {
  251. $code .= 'AJAX.fireOnload("';
  252. $code .= PMA_escapeJsString($file['filename']);
  253. $code .= '");';
  254. }
  255. }
  256. $code .= '});';
  257. $this->addCode($code);
  258. $retval .= '<script data-cfasync="false" type="text/javascript">';
  259. $retval .= "// <![CDATA[\n";
  260. $retval .= $this->_code;
  261. foreach ($this->_events as $js_event) {
  262. $retval .= sprintf(
  263. "$(window).bind('%s', %s);\n",
  264. $js_event['event'],
  265. $js_event['function']
  266. );
  267. }
  268. $retval .= '// ]]>';
  269. $retval .= '</script>';
  270. return $retval;
  271. }
  272. }