class-helpscout.php 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263
  1. <?php
  2. /**
  3. * WPSEO plugin file.
  4. *
  5. * @package WPSEO\Admin
  6. */
  7. /**
  8. * Class WPSEO_HelpScout
  9. */
  10. class WPSEO_HelpScout implements WPSEO_WordPress_Integration {
  11. /**
  12. * The id for the beacon.
  13. *
  14. * @var string
  15. */
  16. protected $beacon_id;
  17. /**
  18. * The pages where the beacon is loaded.
  19. *
  20. * @var array
  21. */
  22. protected $pages;
  23. /**
  24. * The products the beacon is loaded for.
  25. *
  26. * @var array
  27. */
  28. protected $products;
  29. /**
  30. * Whether to asks the user's consent before loading in HelpScout.
  31. *
  32. * @var bool
  33. */
  34. protected $ask_consent;
  35. /**
  36. * WPSEO_HelpScout constructor.
  37. *
  38. * @param string $beacon_id The beacon id.
  39. * @param array $pages The pages where the beacon is loaded.
  40. * @param array $products The products the beacon is loaded for.
  41. * @param bool $ask_consent Optional. Whether to ask for consent before loading in HelpScout.
  42. */
  43. public function __construct( $beacon_id, array $pages, array $products, $ask_consent = false ) {
  44. $this->beacon_id = $beacon_id;
  45. $this->pages = $pages;
  46. $this->products = $products;
  47. $this->ask_consent = $ask_consent;
  48. }
  49. /**
  50. * @inheritDoc
  51. */
  52. public function register_hooks() {
  53. if ( ! $this->is_beacon_page() ) {
  54. return;
  55. }
  56. add_action( 'admin_enqueue_scripts', [ $this, 'enqueue_help_scout_script' ] );
  57. add_action( 'admin_footer', [ $this, 'output_beacon_js' ] );
  58. }
  59. /**
  60. * Enqueues the HelpScout script.
  61. */
  62. public function enqueue_help_scout_script() {
  63. $asset_manager = new WPSEO_Admin_Asset_Manager();
  64. $asset_manager->enqueue_script( 'help-scout-beacon' );
  65. }
  66. /**
  67. * Outputs a small piece of javascript for the beacon.
  68. */
  69. public function output_beacon_js() {
  70. printf(
  71. '<script type="text/javascript">window.%1$s(\'%2$s\', %3$s)</script>',
  72. ( $this->ask_consent ) ? 'wpseoHelpScoutBeaconConsent' : 'wpseoHelpScoutBeacon',
  73. esc_html( $this->beacon_id ),
  74. wp_json_encode( $this->get_session_data() )
  75. );
  76. }
  77. /**
  78. * Checks if the current page is a page containing the beacon.
  79. */
  80. private function is_beacon_page() {
  81. return in_array( $this->get_current_page(), $this->pages, true );
  82. }
  83. /**
  84. * Retrieves the value of the current page.
  85. *
  86. * @return string The current page.
  87. */
  88. private function get_current_page() {
  89. $page = filter_input( INPUT_GET, 'page' );
  90. if ( isset( $page ) && $page !== false ) {
  91. return $page;
  92. }
  93. return '';
  94. }
  95. /**
  96. * Retrieves the identifying data.
  97. *
  98. * @return string The data to pass as identifying data.
  99. */
  100. protected function get_session_data() {
  101. /** @noinspection PhpUnusedLocalVariableInspection */
  102. // Do not make these strings translatable! They are for our support agents, the user won't see them!
  103. $current_user = wp_get_current_user();
  104. $data = [
  105. 'name' => trim( $current_user->user_firstname . ' ' . $current_user->user_lastname ),
  106. 'email' => $current_user->user_email,
  107. 'WordPress Version' => $this->get_wordpress_version(),
  108. 'Server' => $this->get_server_info(),
  109. '<a href="' . admin_url( 'themes.php' ) . '">Theme</a>' => $this->get_theme_info(),
  110. '<a href="' . admin_url( 'plugins.php' ) . '">Plugins</a>' => $this->get_active_plugins(),
  111. ];
  112. if ( ! empty( $this->products ) ) {
  113. $addon_manager = new WPSEO_Addon_Manager();
  114. foreach ( $this->products as $product ) {
  115. $subscription = $addon_manager->get_subscription( $product );
  116. if ( ! $subscription ) {
  117. continue;
  118. }
  119. $data[ $subscription->product->name ] = $this->get_product_info( $subscription );
  120. }
  121. }
  122. return wp_json_encode( $data );
  123. }
  124. /**
  125. * Returns basic info about the server software.
  126. *
  127. * @return string
  128. */
  129. private function get_server_info() {
  130. $server_tracking_data = new WPSEO_Tracking_Server_Data();
  131. $server_data = $server_tracking_data->get();
  132. $server_data = $server_data['server'];
  133. $fields_to_use = [
  134. 'IP' => 'ip',
  135. 'Hostname' => 'Hostname',
  136. 'OS' => 'os',
  137. 'PHP' => 'PhpVersion',
  138. 'CURL' => 'CurlVersion',
  139. ];
  140. $server_data['CurlVersion'] = $server_data['CurlVersion']['version'] . '(SSL Support' . $server_data['CurlVersion']['sslSupport'] . ')';
  141. $server_info = '<table>';
  142. foreach ( $fields_to_use as $label => $field_to_use ) {
  143. if ( isset( $server_data[ $field_to_use ] ) ) {
  144. $server_info .= sprintf( '<tr><td>%1$s</td><td>%2$s</td></tr>', esc_html( $label ), esc_html( $server_data[ $field_to_use ] ) );
  145. }
  146. }
  147. $server_info .= '</table>';
  148. return $server_info;
  149. }
  150. /**
  151. * Returns info about the Yoast SEO plugin version and license.
  152. *
  153. * @param object $plugin The plugin.
  154. *
  155. * @return string The product info.
  156. */
  157. private function get_product_info( $plugin ) {
  158. if ( empty( $plugin ) ) {
  159. return '';
  160. }
  161. $product_info = '<table>';
  162. $product_info .= '<tr><td>Version</td><td>' . $plugin->product->version . '</td></tr>';
  163. $product_info .= '<tr><td>Expiration date</td><td>' . $plugin->expiry_date . '</td></tr>';
  164. $product_info .= '</table>';
  165. return $product_info;
  166. }
  167. /**
  168. * Returns the WordPress version + a suffix if current WP is multi site.
  169. *
  170. * @return string The WordPress version string.
  171. */
  172. private function get_wordpress_version() {
  173. global $wp_version;
  174. $wordpress_version = $wp_version;
  175. if ( is_multisite() ) {
  176. $wordpress_version .= ' MULTI-SITE';
  177. }
  178. return $wordpress_version;
  179. }
  180. /**
  181. * Returns a formatted HTML string for the current theme.
  182. *
  183. * @return string The theme info as string.
  184. */
  185. private function get_theme_info() {
  186. $theme = wp_get_theme();
  187. $theme_info = sprintf(
  188. '<a href="%1$s">%2$s</a> v%3$s by %4$s',
  189. esc_attr( $theme->display( 'ThemeURI' ) ),
  190. esc_html( $theme->display( 'Name' ) ),
  191. esc_html( $theme->display( 'Version' ) ),
  192. esc_html( $theme->display( 'Author' ) )
  193. );
  194. if ( is_child_theme() ) {
  195. $theme_info .= sprintf( '<br />Child theme of: %1$s', esc_html( $theme->display( 'Template' ) ) );
  196. }
  197. return $theme_info;
  198. }
  199. /**
  200. * Returns a formatted HTML list of all active plugins.
  201. *
  202. * @return string The active plugins.
  203. */
  204. private function get_active_plugins() {
  205. $updates_available = get_site_transient( 'update_plugins' );
  206. $active_plugins = '';
  207. foreach ( wp_get_active_and_valid_plugins() as $plugin ) {
  208. $plugin_data = get_plugin_data( $plugin );
  209. $plugin_file = str_replace( trailingslashit( WP_PLUGIN_DIR ), '', $plugin );
  210. if ( isset( $updates_available->response[ $plugin_file ] ) ) {
  211. $active_plugins .= '<i class="icon-close1"></i> ';
  212. }
  213. $active_plugins .= sprintf(
  214. '<a href="%1$s">%2$s</a> v%3$s',
  215. esc_attr( $plugin_data['PluginURI'] ),
  216. esc_html( $plugin_data['Name'] ),
  217. esc_html( $plugin_data['Version'] )
  218. );
  219. }
  220. return $active_plugins;
  221. }
  222. }