PageRenderTime 39ms CodeModel.GetById 12ms RepoModel.GetById 0ms app.codeStats 0ms

/wp-content/plugins/w3-total-cache/lib/W3/PageSpeed.php

https://gitlab.com/endomorphosis/jeffersonsmithmayor
PHP | 340 lines | 195 code | 52 blank | 93 comment | 21 complexity | 923edd9d9b216e165b09820037cd0aba MD5 | raw file
  1. <?php
  2. /**
  3. * Google Page Speed API
  4. */
  5. define('W3TC_PAGESPEED_API_URL', 'https://www.googleapis.com/pagespeedonline/v1/runPagespeed');
  6. /**
  7. * Class W3_PageSpeed
  8. */
  9. class W3_PageSpeed {
  10. /**
  11. * API Key
  12. *
  13. * @var string
  14. */
  15. var $key = '';
  16. /**
  17. * PHP5-style constructor
  18. */
  19. function __construct() {
  20. $config = & w3_instance('W3_Config');
  21. $this->key = $config->get_string('widget.pagespeed.key');
  22. }
  23. /**
  24. * PHP4-style constructor
  25. */
  26. function W3_PageSpeed() {
  27. $this->__construct();
  28. }
  29. /**
  30. * Analyze URL
  31. *
  32. * @param string $url
  33. * @param bool $force
  34. * @return array|bool|mixed|null
  35. */
  36. function analyze($url, $force = false) {
  37. $results = null;
  38. if (!$force) {
  39. $results = $this->_load($url);
  40. }
  41. if ($results === null) {
  42. $json = $this->_request($url);
  43. if ($json) {
  44. $results = $this->_parse($json);
  45. if ($results) {
  46. $this->_sort($results);
  47. }
  48. }
  49. $this->_store($url, $results);
  50. }
  51. return $results;
  52. }
  53. /**
  54. * Make API request
  55. *
  56. * @param string $url
  57. * @return string
  58. */
  59. function _request($url) {
  60. require_once W3TC_INC_DIR . '/functions/http.php';
  61. require_once W3TC_INC_DIR . '/functions/url.php';
  62. $request_url = w3_url_format(W3TC_PAGESPEED_API_URL, array(
  63. 'url' => $url,
  64. 'key' => $this->key,
  65. ));
  66. $response = w3_http_get($request_url);
  67. if (!is_wp_error($response) && $response['response']['code'] == 200) {
  68. return $response['body'];
  69. }
  70. return false;
  71. }
  72. /**
  73. * Parse response
  74. *
  75. * @param string $json
  76. * @return array|bool
  77. */
  78. function _parse($json) {
  79. $data = json_decode($json);
  80. $results = false;
  81. if (isset($data->formattedResults)) {
  82. $results = array(
  83. 'url' => $data->id,
  84. 'code' => $data->responseCode,
  85. 'title' => $data->title,
  86. 'score' => $data->score,
  87. 'rules' => array()
  88. );
  89. foreach ((array) $data->formattedResults->ruleResults as $i => $rule_result) {
  90. $results['rules'][$i] = array(
  91. 'name' => $rule_result->localizedRuleName,
  92. 'score' => $rule_result->ruleScore,
  93. 'impact' => $rule_result->ruleImpact,
  94. 'priority' => $this->_get_priority($rule_result->ruleImpact),
  95. 'resolution' => $this->_get_resolution($rule_result->localizedRuleName),
  96. 'blocks' => array()
  97. );
  98. if (isset($rule_result->urlBlocks)) {
  99. foreach ((array) $rule_result->urlBlocks as $j => $url_block) {
  100. $results['rules'][$i]['blocks'][$j] = array(
  101. 'header' => $this->_format_string($url_block->header->format, $url_block->header->args),
  102. 'urls' => array()
  103. );
  104. if (isset($url_block->urls)) {
  105. foreach ((array) $url_block->urls as $k => $url) {
  106. $results['rules'][$i]['blocks'][$j]['urls'][$k] = array(
  107. 'result' => $this->_format_string($url->result->format, $url->result->args)
  108. );
  109. }
  110. }
  111. }
  112. }
  113. }
  114. }
  115. return $results;
  116. }
  117. /**
  118. * Returns rule priority by impact
  119. *
  120. * @param float $impact
  121. * @return string
  122. */
  123. function _get_priority($impact) {
  124. if ($impact < 3) {
  125. $priority = 'low';
  126. } elseif ($impact >= 3 && $impact <= 10) {
  127. $priority = 'medium';
  128. } else {
  129. $priority = 'high';
  130. }
  131. return $priority;
  132. }
  133. /**
  134. * Returns resolution
  135. *
  136. * @param string $code
  137. * @return array
  138. */
  139. function _get_resolution($code) {
  140. switch ($code) {
  141. case 'MinifyHTML':
  142. return array(
  143. 'header' => 'Enable HTML Minify',
  144. 'tab' => 'minify'
  145. );
  146. case 'MinifyJavaScript':
  147. case 'DeferParsingJavaScript':
  148. return array(
  149. 'header' => 'Enable JavaScript Minify',
  150. 'tab' => 'minify'
  151. );
  152. case 'MinifyCss':
  153. case 'PutCssInTheDocumentHead':
  154. return array(
  155. 'header' => 'Enable CSS Minify',
  156. 'tab' => 'minify'
  157. );
  158. case 'AvoidCssImport':
  159. return array(
  160. 'header' => 'Enable CSS Minify and @import processing',
  161. 'tab' => 'minify'
  162. );
  163. case 'OptimizeTheOrderOfStylesAndScripts':
  164. return array(
  165. 'header' => 'Enable JavaScript and CSS Minify',
  166. 'tab' => 'minify'
  167. );
  168. case 'PreferAsyncResources':
  169. return array(
  170. 'header' => 'Switch to non-blocking JavaScript embedding',
  171. 'tab' => 'minify'
  172. );
  173. case 'RemoveQueryStringsFromStaticResources':
  174. return array(
  175. 'header' => 'Disable the "Prevent caching of objects after settings change" feature',
  176. 'tab' => 'browsercache'
  177. );
  178. case 'LeverageBrowserCaching':
  179. return array(
  180. 'header' => 'Enable the expires header on the Browser Cache Settings tab',
  181. 'tab' => 'browsercache'
  182. );
  183. case 'SpecifyACacheValidator':
  184. return array(
  185. 'header' => 'Enable the ETag header on the Browser Cache Settings tab',
  186. 'tab' => 'browsercache'
  187. );
  188. }
  189. return array();
  190. }
  191. /**
  192. * Loads results from cache
  193. *
  194. * @param string $url
  195. * @return mixed|null
  196. */
  197. function _load($url) {
  198. $file = $this->_get_cache_file($url);
  199. if (is_readable($file)) {
  200. $data = @file_get_contents($file);
  201. if ($data) {
  202. return @unserialize($data);
  203. }
  204. }
  205. return null;
  206. }
  207. /**
  208. * Save results to cache
  209. *
  210. * @param string $url
  211. * @param array $results
  212. * @return bool|int
  213. */
  214. function _store($url, $results) {
  215. $file = $this->_get_cache_file($url);
  216. $data = serialize($results);
  217. return @file_put_contents($file, $data);
  218. }
  219. /**
  220. * Returns cache file
  221. *
  222. * @param string $url
  223. * @return string
  224. */
  225. function _get_cache_file($url) {
  226. return W3TC_TMP_DIR . '/pagespeed_' . md5($url);
  227. }
  228. var $_format_string_args = array();
  229. /**
  230. * Formats string
  231. *
  232. * @param string $format
  233. * @param array $args
  234. * @return mixed
  235. */
  236. function _format_string($format, $args) {
  237. $this->_format_string_args = $args;
  238. return preg_replace_callback('~\$([0-9]+)~', array(
  239. &$this,
  240. '_format_string_callback'
  241. ), $format);
  242. }
  243. /**
  244. * Format string callback
  245. *
  246. * @param array $matches
  247. * @return string
  248. */
  249. function _format_string_callback($matches) {
  250. $index = (int) $matches[1] - 1;
  251. if (isset($this->_format_string_args[$index]->value)) {
  252. switch ($this->_format_string_args[$index]->type) {
  253. case 'URL':
  254. return sprintf('<a href="%s">%s</a>', $this->_format_string_args[$index]->value, $this->_format_string_args[$index]->value);
  255. default:
  256. return $this->_format_string_args[$index]->value;
  257. }
  258. }
  259. return $matches[0];
  260. }
  261. /**
  262. * Sort results
  263. *
  264. * @param array $results
  265. * @return void
  266. */
  267. function _sort(&$results) {
  268. if (isset($results['rules'])) {
  269. usort($results['rules'], array(
  270. &$this,
  271. '_sort_cmp'
  272. ));
  273. }
  274. }
  275. /**
  276. * Compare function
  277. *
  278. * @param array $rule_result1
  279. * @param array $rule_result2
  280. * @return int
  281. */
  282. function _sort_cmp(&$rule_result1, &$rule_result2) {
  283. if ($rule_result1['impact'] == $rule_result2['impact']) {
  284. return 0;
  285. }
  286. return ($rule_result1['impact'] > $rule_result2['impact']) ? -1 : 1;
  287. }
  288. }