PageRenderTime 52ms CodeModel.GetById 24ms RepoModel.GetById 0ms app.codeStats 0ms

/wp-content/plugins/query-monitor/dispatchers/Html.php

https://gitlab.com/knowthecode/ktc-sandbox
PHP | 367 lines | 255 code | 89 blank | 23 comment | 30 complexity | d477da900869faefa11a663f0446cf42 MD5 | raw file
  1. <?php
  2. /*
  3. Copyright 2009-2016 John Blackbourn
  4. This program is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation; either version 2 of the License, or
  7. (at your option) any later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details.
  12. */
  13. class QM_Dispatcher_Html extends QM_Dispatcher {
  14. public $id = 'html';
  15. public $did_footer = false;
  16. public function __construct( QM_Plugin $qm ) {
  17. add_action( 'admin_bar_menu', array( $this, 'action_admin_bar_menu' ), 999 );
  18. add_action( 'wp_ajax_qm_auth_on', array( $this, 'ajax_on' ) );
  19. add_action( 'wp_ajax_qm_auth_off', array( $this, 'ajax_off' ) );
  20. add_action( 'wp_ajax_nopriv_qm_auth_off', array( $this, 'ajax_off' ) );
  21. add_action( 'shutdown', array( $this, 'dispatch' ), 0 );
  22. add_action( 'wp_footer', array( $this, 'action_footer' ) );
  23. add_action( 'admin_footer', array( $this, 'action_footer' ) );
  24. add_action( 'login_footer', array( $this, 'action_footer' ) );
  25. add_action( 'embed_footer', array( $this, 'action_footer' ) );
  26. add_action( 'amp_post_template_footer', array( $this, 'action_footer' ) );
  27. parent::__construct( $qm );
  28. }
  29. public function action_footer() {
  30. $this->did_footer = true;
  31. }
  32. /**
  33. * Helper function. Should the authentication cookie be secure?
  34. *
  35. * @return bool Should the authentication cookie be secure?
  36. */
  37. public static function secure_cookie() {
  38. return ( is_ssl() and ( 'https' === parse_url( home_url(), PHP_URL_SCHEME ) ) );
  39. }
  40. public function ajax_on() {
  41. if ( ! current_user_can( 'view_query_monitor' ) or ! check_ajax_referer( 'qm-auth-on', 'nonce', false ) ) {
  42. wp_send_json_error( __( 'Could not set authentication cookie.', 'query-monitor' ) );
  43. }
  44. $expiration = time() + ( 2 * DAY_IN_SECONDS );
  45. $secure = self::secure_cookie();
  46. $cookie = wp_generate_auth_cookie( get_current_user_id(), $expiration, 'logged_in' );
  47. setcookie( QM_COOKIE, $cookie, $expiration, COOKIEPATH, COOKIE_DOMAIN, $secure, false );
  48. $text = __( 'Authentication cookie set. You can now view Query Monitor output while logged out or while logged in as a different user.', 'query-monitor' );
  49. wp_send_json_success( $text );
  50. }
  51. public function ajax_off() {
  52. if ( ! self::user_verified() or ! check_ajax_referer( 'qm-auth-off', 'nonce', false ) ) {
  53. wp_send_json_error( __( 'Could not clear authentication cookie.', 'query-monitor' ) );
  54. }
  55. $expiration = time() - 31536000;
  56. setcookie( QM_COOKIE, ' ', $expiration, COOKIEPATH, COOKIE_DOMAIN );
  57. $text = __( 'Authentication cookie cleared.', 'query-monitor' );
  58. wp_send_json_success( $text );
  59. }
  60. public function action_admin_bar_menu( WP_Admin_Bar $wp_admin_bar ) {
  61. if ( ! $this->user_can_view() ) {
  62. return;
  63. }
  64. $title = __( 'Query Monitor', 'query-monitor' );
  65. $wp_admin_bar->add_menu( array(
  66. 'id' => 'query-monitor',
  67. 'title' => esc_html( $title ),
  68. 'href' => '#qm',
  69. ) );
  70. $wp_admin_bar->add_menu( array(
  71. 'parent' => 'query-monitor',
  72. 'id' => 'query-monitor-placeholder',
  73. 'title' => esc_html( $title ),
  74. 'href' => '#qm',
  75. ) );
  76. }
  77. public function init() {
  78. if ( ! $this->user_can_view() ) {
  79. return;
  80. }
  81. if ( ! defined( 'DONOTCACHEPAGE' ) ) {
  82. define( 'DONOTCACHEPAGE', 1 );
  83. }
  84. add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_assets' ) );
  85. add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_assets' ) );
  86. add_action( 'login_enqueue_scripts', array( $this, 'enqueue_assets' ) );
  87. add_action( 'enqueue_embed_scripts', array( $this, 'enqueue_assets' ) );
  88. add_action( 'send_headers', 'nocache_headers' );
  89. add_action( 'amp_post_template_head', array( $this, 'enqueue_assets' ) );
  90. add_action( 'amp_post_template_head', array( $this, 'manually_print_assets' ), 11 );
  91. }
  92. public function manually_print_assets() {
  93. wp_print_scripts( array(
  94. 'query-monitor',
  95. ) );
  96. wp_print_styles( array(
  97. 'query-monitor',
  98. ) );
  99. }
  100. public function enqueue_assets() {
  101. global $wp_locale, $wp_version;
  102. wp_enqueue_style(
  103. 'query-monitor',
  104. $this->qm->plugin_url( 'assets/query-monitor.css' ),
  105. null,
  106. $this->qm->plugin_ver( 'assets/query-monitor.css' )
  107. );
  108. wp_enqueue_script(
  109. 'query-monitor',
  110. $this->qm->plugin_url( 'assets/query-monitor.js' ),
  111. array( 'jquery' ),
  112. $this->qm->plugin_ver( 'assets/query-monitor.js' ),
  113. true
  114. );
  115. wp_localize_script(
  116. 'query-monitor',
  117. 'qm_locale',
  118. (array) $wp_locale
  119. );
  120. wp_localize_script(
  121. 'query-monitor',
  122. 'qm_l10n',
  123. array(
  124. 'ajax_error' => __( 'PHP Error in AJAX Response', 'query-monitor' ),
  125. 'infinitescroll_paused' => __( 'Infinite Scroll has been paused by Query Monitor', 'query-monitor' ),
  126. 'ajaxurl' => admin_url( 'admin-ajax.php' ),
  127. 'auth_nonce' => array(
  128. 'on' => wp_create_nonce( 'qm-auth-on' ),
  129. 'off' => wp_create_nonce( 'qm-auth-off' ),
  130. ),
  131. )
  132. );
  133. if ( floatval( $wp_version ) <= 3.7 ) {
  134. wp_enqueue_style(
  135. 'query-monitor-compat',
  136. $this->qm->plugin_url( 'assets/compat.css' ),
  137. null,
  138. $this->qm->plugin_ver( 'assets/compat.css' )
  139. );
  140. }
  141. }
  142. public function dispatch() {
  143. if ( ! $this->should_dispatch() ) {
  144. return;
  145. }
  146. $this->before_output();
  147. /* @var QM_Output_Html[] */
  148. foreach ( $this->get_outputters( 'html' ) as $id => $output ) {
  149. $output->output();
  150. }
  151. $this->after_output();
  152. }
  153. protected function before_output() {
  154. require_once $this->qm->plugin_path( 'output/Html.php' );
  155. foreach ( glob( $this->qm->plugin_path( 'output/html/*.php' ) ) as $file ) {
  156. require_once $file;
  157. }
  158. $class = array(
  159. 'qm-no-js',
  160. );
  161. if ( did_action( 'wp_head' ) ) {
  162. $absolute = function_exists( 'twentyfifteen_setup' );
  163. if ( apply_filters( 'qm/output/absolute_position', $absolute ) ) {
  164. $class[] = 'qm-absolute';
  165. }
  166. $class[] = sprintf( 'qm-theme-%s', get_template() );
  167. $class[] = sprintf( 'qm-theme-%s', get_stylesheet() );
  168. }
  169. if ( !is_admin_bar_showing() ) {
  170. $class[] = 'qm-peek';
  171. }
  172. echo '<div id="qm" class="' . implode( ' ', array_map( 'esc_attr', $class ) ) . '">';
  173. echo '<div id="qm-wrapper">';
  174. echo '<div id="qm-title">';
  175. echo '<p>' . esc_html__( 'Query Monitor', 'query-monitor' ) . '</p>';
  176. echo '</div>';
  177. }
  178. protected function after_output() {
  179. echo '<div class="qm qm-half qm-clear" id="qm-authentication">';
  180. echo '<table cellspacing="0">';
  181. echo '<thead>';
  182. echo '<tr>';
  183. echo '<th>' . esc_html__( 'Authentication', 'query-monitor' ) . '</th>';
  184. echo '</tr>';
  185. echo '</thead>';
  186. echo '<tbody>';
  187. if ( ! self::user_verified() ) {
  188. echo '<tr>';
  189. echo '<td>' . esc_html__( 'You can set an authentication cookie which allows you to view Query Monitor output when you&rsquo;re not logged in.', 'query-monitor' ) . '</td>';
  190. echo '</tr>';
  191. echo '<tr>';
  192. echo '<td><a href="#" class="qm-auth" data-action="on">' . esc_html__( 'Set authentication cookie', 'query-monitor' ) . '</a></td>';
  193. echo '</tr>';
  194. } else {
  195. echo '<tr>';
  196. echo '<td>' . esc_html__( 'You currently have an authentication cookie which allows you to view Query Monitor output.', 'query-monitor' ) . '</td>';
  197. echo '</tr>';
  198. echo '<tr>';
  199. echo '<td><a href="#" class="qm-auth" data-action="off">' . esc_html__( 'Clear authentication cookie', 'query-monitor' ) . '</a></td>';
  200. echo '</tr>';
  201. }
  202. echo '</tbody>';
  203. echo '</table>';
  204. echo '</div>';
  205. echo '</div>';
  206. echo '</div>';
  207. $json = array(
  208. 'menu' => $this->js_admin_bar_menu(),
  209. 'ajax_errors' => array() # @TODO move this into the php_errors collector
  210. );
  211. echo '<script type="text/javascript">' . "\n\n";
  212. echo 'var qm = ' . json_encode( $json ) . ';' . "\n\n";
  213. ?>
  214. if ( ( 'undefined' === typeof QM_i18n ) || ( 'undefined' === typeof jQuery ) || ! jQuery ) {
  215. document.getElementById( 'qm' ).style.display = 'block';
  216. } else if ( ! document.getElementById( 'wpadminbar' ) ) {
  217. document.getElementById( 'qm' ).className += ' qm-peek';
  218. }
  219. <?php
  220. echo '</script>' . "\n\n";
  221. }
  222. public function js_admin_bar_menu() {
  223. $class = implode( ' ', apply_filters( 'qm/output/menu_class', array() ) );
  224. if ( false === strpos( $class, 'qm-' ) ) {
  225. $class .= ' qm-all-clear';
  226. }
  227. $title = implode( '&nbsp;&nbsp;&nbsp;', apply_filters( 'qm/output/title', array() ) );
  228. if ( empty( $title ) ) {
  229. $title = esc_html__( 'Query Monitor', 'query-monitor' );
  230. }
  231. $admin_bar_menu = array(
  232. 'top' => array(
  233. 'title' => sprintf( '<span class="ab-icon">QM</span><span class="ab-label">%s</span>', $title ),
  234. 'classname' => $class
  235. ),
  236. 'sub' => array()
  237. );
  238. foreach ( apply_filters( 'qm/output/menus', array() ) as $menu ) {
  239. $admin_bar_menu['sub'][ $menu['id'] ] = $menu;
  240. }
  241. return $admin_bar_menu;
  242. }
  243. public function is_active() {
  244. if ( ! $this->user_can_view() ) {
  245. return false;
  246. }
  247. if ( ! $this->did_footer ) {
  248. return false;
  249. }
  250. // If this is an async request and not a customizer preview:
  251. if ( QM_Util::is_async() && ( ! function_exists( 'is_customize_preview' ) || ! is_customize_preview() ) ) {
  252. return false;
  253. }
  254. # Don't process if the minimum required actions haven't fired:
  255. if ( is_admin() ) {
  256. if ( ! did_action( 'admin_init' ) ) {
  257. return false;
  258. }
  259. } else {
  260. if ( ! ( did_action( 'wp' ) || did_action( 'login_init' ) ) ) {
  261. return false;
  262. }
  263. }
  264. # Back-compat filter. Please use `qm/dispatch/html` instead
  265. if ( ! apply_filters( 'qm/process', true, is_admin_bar_showing() ) ) {
  266. return false;
  267. }
  268. return true;
  269. }
  270. }
  271. function register_qm_dispatcher_html( array $dispatchers, QM_Plugin $qm ) {
  272. $dispatchers['html'] = new QM_Dispatcher_Html( $qm );
  273. return $dispatchers;
  274. }
  275. add_filter( 'qm/dispatchers', 'register_qm_dispatcher_html', 10, 2 );