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

/wp-content/plugins/wp-mail-smtp/class-wpms-am-notification.php

https://bitbucket.org/babinkochana/triptrills
PHP | 455 lines | 278 code | 55 blank | 122 comment | 58 complexity | 61585e1e8bf5fcf612ef198c9b34215b MD5 | raw file
Possible License(s): MIT, Apache-2.0, GPL-3.0, 0BSD, GPL-2.0
  1. <?php
  2. /**
  3. * Awesome Motive Notifications.
  4. *
  5. * This creates a custom post type (if it doesn't exist) and calls the API to
  6. * retrieve notifications for this product.
  7. *
  8. * @package AwesomeMotive
  9. * @author AwesomeMotive Team
  10. * @license GPL-2.0+
  11. * @copyright Copyright (c) 2018, Awesome Motive LLC
  12. * @version 1.0.7
  13. */
  14. class WPMS_AM_Notification {
  15. /**
  16. * The api url we are calling.
  17. *
  18. * @since 1.0.0
  19. *
  20. * @var string
  21. */
  22. public $api_url = 'https://api.awesomemotive.com/v1/notification/';
  23. /**
  24. * A unique slug for this plugin.
  25. * (Not the WordPress plugin slug)
  26. *
  27. * @since 1.0.0
  28. *
  29. * @var string
  30. */
  31. public $plugin;
  32. /**
  33. * The current plugin version.
  34. *
  35. * @since 1.0.0
  36. *
  37. * @var string
  38. */
  39. public $plugin_version;
  40. /**
  41. * Flag if a notice has been registered.
  42. *
  43. * @since 1.0.0
  44. *
  45. * @var bool
  46. */
  47. public static $registered = false;
  48. /**
  49. * Construct.
  50. *
  51. * @since 1.0.0
  52. *
  53. * @param string $plugin The plugin slug.
  54. * @param mixed $version The version of the plugin.
  55. */
  56. public function __construct( $plugin = '', $version = 0 ) {
  57. $this->plugin = $plugin;
  58. $this->plugin_version = $version;
  59. add_action( 'init', array( $this, 'custom_post_type' ) );
  60. add_action( 'admin_init', array( $this, 'get_remote_notifications' ), 100 );
  61. add_action( 'admin_notices', array( $this, 'display_notifications' ) );
  62. add_action( 'wp_ajax_am_notification_dismiss', array( $this, 'dismiss_notification' ) );
  63. }
  64. /**
  65. * Registers a custom post type.
  66. *
  67. * @since 1.0.0
  68. */
  69. public function custom_post_type() {
  70. register_post_type( 'amn_' . $this->plugin, array(
  71. 'label' => $this->plugin . ' Announcements',
  72. 'can_export' => false,
  73. 'supports' => false,
  74. 'capability_type' => 'manage_options',
  75. ) );
  76. }
  77. /**
  78. * Retrieve the remote notifications if the time has expired.
  79. *
  80. * @since 1.0.0
  81. */
  82. public function get_remote_notifications() {
  83. if ( ! apply_filters( 'am_notifications_display', is_super_admin() ) ) {
  84. return;
  85. }
  86. $last_checked = get_option( '_amn_' . $this->plugin . '_last_checked', strtotime( '-1 week' ) );
  87. if ( $last_checked < strtotime( 'today midnight' ) ) {
  88. $plugin_notifications = $this->get_plugin_notifications( 1 );
  89. $notification_id = null;
  90. if ( ! empty( $plugin_notifications ) ) {
  91. // Unset it from the array.
  92. $notification = $plugin_notifications[0];
  93. $notification_id = get_post_meta( $notification->ID, 'notification_id', true );
  94. }
  95. $response = wp_remote_retrieve_body( wp_remote_post( $this->api_url, array(
  96. 'body' => array(
  97. 'slug' => $this->plugin,
  98. 'version' => $this->plugin_version,
  99. 'last_notification' => $notification_id,
  100. ),
  101. ) ) );
  102. $data = json_decode( $response );
  103. if ( ! empty( $data->id ) ) {
  104. $notifications = array();
  105. foreach ( (array) $data->slugs as $slug ) {
  106. $notifications = array_merge(
  107. $notifications,
  108. (array) get_posts(
  109. array(
  110. 'post_type' => 'amn_' . $slug,
  111. 'post_status' => 'all',
  112. 'meta_key' => 'notification_id',
  113. 'meta_value' => $data->id,
  114. )
  115. )
  116. );
  117. }
  118. if ( empty( $notifications ) ) {
  119. $new_notification_id = wp_insert_post(
  120. array(
  121. 'post_content' => wp_kses_post( $data->content ),
  122. 'post_type' => 'amn_' . $this->plugin,
  123. )
  124. );
  125. update_post_meta( $new_notification_id, 'notification_id', absint( $data->id ) );
  126. update_post_meta( $new_notification_id, 'type', sanitize_text_field( trim( $data->type ) ) );
  127. update_post_meta( $new_notification_id, 'dismissable', (bool) $data->dismissible ? 1 : 0 );
  128. update_post_meta( $new_notification_id, 'location', function_exists( 'wp_json_encode' ) ? wp_json_encode( $data->location ) : json_encode( $data->location ) );
  129. update_post_meta( $new_notification_id, 'version', sanitize_text_field( trim( $data->version ) ) );
  130. update_post_meta( $new_notification_id, 'viewed', 0 );
  131. update_post_meta( $new_notification_id, 'expiration', $data->expiration ? absint( $data->expiration ) : false );
  132. update_post_meta( $new_notification_id, 'plans', function_exists( 'wp_json_encode' ) ? wp_json_encode( $data->plans ) : json_encode( $data->plans ) );
  133. }
  134. }
  135. // Possibly revoke notifications.
  136. if ( ! empty( $data->revoked ) ) {
  137. $this->revoke_notifications( $data->revoked );
  138. }
  139. // Set the option now so we can't run this again until after 24 hours.
  140. update_option( '_amn_' . $this->plugin . '_last_checked', strtotime( 'today midnight' ) );
  141. }
  142. }
  143. /**
  144. * Get local plugin notifications that have already been set.
  145. *
  146. * @since 1.0.0
  147. *
  148. * @param integer $limit Set the limit for how many posts to retrieve.
  149. * @param array $args Any top-level arguments to add to the array.
  150. *
  151. * @return WP_Post[] WP_Post that match the query.
  152. */
  153. public function get_plugin_notifications( $limit = - 1, $args = array() ) {
  154. return get_posts(
  155. array(
  156. 'posts_per_page' => $limit,
  157. 'post_type' => 'amn_' . $this->plugin,
  158. ) + $args
  159. );
  160. }
  161. /**
  162. * Display any notifications that should be displayed.
  163. *
  164. * @since 1.0.0
  165. */
  166. public function display_notifications() {
  167. if ( ! apply_filters( 'am_notifications_display', is_super_admin() ) ) {
  168. return;
  169. }
  170. $plugin_notifications = $this->get_plugin_notifications( - 1, array(
  171. 'post_status' => 'all',
  172. 'meta_key' => 'viewed',
  173. 'meta_value' => '0',
  174. ) );
  175. $plugin_notifications = $this->validate_notifications( $plugin_notifications );
  176. if ( ! empty( $plugin_notifications ) && ! self::$registered ) {
  177. foreach ( $plugin_notifications as $notification ) {
  178. $dismissable = get_post_meta( $notification->ID, 'dismissable', true );
  179. $type = get_post_meta( $notification->ID, 'type', true );
  180. ?>
  181. <div class="am-notification am-notification-<?php echo absint( $notification->ID ); ?> notice notice-<?php echo esc_attr( $type ); ?><?php echo $dismissable ? ' is-dismissible' : ''; ?>">
  182. <?php echo wp_kses_post( $notification->post_content ); ?>
  183. </div>
  184. <script type="text/javascript">
  185. jQuery( document ).ready( function ( $ ) {
  186. $( document ).on( 'click', '.am-notification-<?php echo absint( $notification->ID ); ?> button.notice-dismiss', function ( event ) {
  187. $.post( ajaxurl, {
  188. action: 'am_notification_dismiss',
  189. notification_id: '<?php echo absint( $notification->ID ); ?>'
  190. } );
  191. } );
  192. } );
  193. </script>
  194. <?php
  195. }
  196. self::$registered = true;
  197. }
  198. }
  199. /**
  200. * Validate the notifications before displaying them.
  201. *
  202. * @since 1.0.0
  203. *
  204. * @param array $plugin_notifications An array of plugin notifications.
  205. *
  206. * @return array A filtered array of plugin notifications.
  207. */
  208. public function validate_notifications( $plugin_notifications ) {
  209. global $pagenow;
  210. foreach ( $plugin_notifications as $key => $notification ) {
  211. // Location validation.
  212. $location = (array) json_decode( get_post_meta( $notification->ID, 'location', true ) );
  213. $continue = false;
  214. if ( ! in_array( 'everywhere', $location, true ) ) {
  215. if ( in_array( 'index.php', $location, true ) && 'index.php' === $pagenow ) {
  216. $continue = true;
  217. }
  218. if ( in_array( 'plugins.php', $location, true ) && 'plugins.php' === $pagenow ) {
  219. $continue = true;
  220. }
  221. if ( ! $continue ) {
  222. unset( $plugin_notifications[ $key ] );
  223. }
  224. }
  225. // Plugin validation (OR conditional).
  226. $plugins = (array) json_decode( get_post_meta( $notification->ID, 'plugins', true ) );
  227. $continue = false;
  228. if ( ! empty( $plugins ) ) {
  229. foreach ( $plugins as $plugin ) {
  230. if ( is_plugin_active( $plugin ) ) {
  231. $continue = true;
  232. }
  233. }
  234. if ( ! $continue ) {
  235. unset( $plugin_notifications[ $key ] );
  236. }
  237. }
  238. // Theme validation.
  239. $theme = get_post_meta( $notification->ID, 'theme', true );
  240. $continue = (string) wp_get_theme() === $theme;
  241. if ( ! empty( $theme ) && ! $continue ) {
  242. unset( $plugin_notifications[ $key ] );
  243. }
  244. // Version validation.
  245. $version = get_post_meta( $notification->ID, 'version', true );
  246. $continue = false;
  247. if ( ! empty( $version ) ) {
  248. if ( version_compare( $this->plugin_version, $version, '<=' ) ) {
  249. $continue = true;
  250. }
  251. if ( ! $continue ) {
  252. unset( $plugin_notifications[ $key ] );
  253. }
  254. }
  255. // Expiration validation.
  256. $expiration = get_post_meta( $notification->ID, 'expiration', true );
  257. $continue = false;
  258. if ( ! empty( $expiration ) ) {
  259. if ( $expiration > time() ) {
  260. $continue = true;
  261. }
  262. if ( ! $continue ) {
  263. unset( $plugin_notifications[ $key ] );
  264. }
  265. }
  266. // Plan validation.
  267. $plans = (array) json_decode( get_post_meta( $notification->ID, 'plans', true ) );
  268. $continue = false;
  269. if ( ! empty( $plans ) ) {
  270. $level = $this->get_plan_level();
  271. if ( in_array( $level, $plans, true ) ) {
  272. $continue = true;
  273. }
  274. if ( ! $continue ) {
  275. unset( $plugin_notifications[ $key ] );
  276. }
  277. }
  278. }
  279. return $plugin_notifications;
  280. }
  281. /**
  282. * Grab the current plan level.
  283. *
  284. * @since 1.0.0
  285. *
  286. * @return string The current plan level.
  287. */
  288. public function get_plan_level() {
  289. // Prepare variables.
  290. $key = '';
  291. $level = '';
  292. switch ( $this->plugin ) {
  293. case 'wpforms':
  294. $option = get_option( 'wpforms_license' );
  295. $key = is_array( $option ) && isset( $option['key'] ) ? $option['key'] : '';
  296. $level = is_array( $option ) && isset( $option['type'] ) ? $option['type'] : '';
  297. // Possibly check for a constant.
  298. if ( empty( $key ) && defined( 'WPFORMS_LICENSE_KEY' ) ) {
  299. $key = WPFORMS_LICENSE_KEY;
  300. }
  301. break;
  302. case 'mi-lite':
  303. case 'mi':
  304. if ( version_compare( MONSTERINSIGHTS_VERSION, '6.9.0', '>=' ) ) {
  305. if ( MonsterInsights()->license->get_site_license_type() ) {
  306. $key = MonsterInsights()->license->get_site_license_key();
  307. $type = MonsterInsights()->license->get_site_license_type();
  308. } else if ( MonsterInsights()->license->get_network_license_type() ) {
  309. $key = MonsterInsights()->license->get_network_license_key();
  310. $type = MonsterInsights()->license->get_network_license_type();
  311. }
  312. // Check key fallbacks
  313. if ( empty( $key ) ) {
  314. $key = MonsterInsights()->license->get_license_key();
  315. }
  316. } else {
  317. $option = get_option( 'monsterinsights_license' );
  318. $key = is_array( $option ) && isset( $option['key'] ) ? $option['key'] : '';
  319. $level = is_array( $option ) && isset( $option['type'] ) ? $option['type'] : '';
  320. // Possibly check for a constant.
  321. if ( empty( $key ) && defined( 'MONSTERINSIGHTS_LICENSE_KEY' ) && is_string( MONSTERINSIGHTS_LICENSE_KEY ) && strlen( MONSTERINSIGHTS_LICENSE_KEY ) > 10 ) {
  322. $key = MONSTERINSIGHTS_LICENSE_KEY;
  323. }
  324. }
  325. break;
  326. case 'om':
  327. $option = get_option( 'optin_monster_api' );
  328. $key = is_array( $option ) && isset( $option['api']['apikey'] ) ? $option['api']['apikey'] : '';
  329. // Possibly check for a constant.
  330. if ( empty( $key ) && defined( 'OPTINMONSTER_REST_API_LICENSE_KEY' ) ) {
  331. $key = OPTINMONSTER_REST_API_LICENSE_KEY;
  332. }
  333. // If the key is still empty, check for the old legacy key.
  334. if ( empty( $key ) ) {
  335. $key = is_array( $option ) && isset( $option['api']['key'] ) ? $option['api']['key'] : '';
  336. }
  337. break;
  338. }
  339. // Possibly set the level to 'none' if the key is empty and no level has been set.
  340. if ( empty( $key ) && empty( $level ) ) {
  341. $level = 'none';
  342. }
  343. // Possibly set the level to 'unknown' if a key is entered, but no level can be determined (such as manually entered key)
  344. if ( ! empty( $key ) && empty( $level ) ) {
  345. $level = 'unknown';
  346. }
  347. // Normalize the level.
  348. switch ( $level ) {
  349. case 'bronze':
  350. case 'personal':
  351. $level = 'basic';
  352. break;
  353. case 'silver':
  354. case 'multi':
  355. $level = 'plus';
  356. break;
  357. case 'gold':
  358. case 'developer':
  359. $level = 'pro';
  360. break;
  361. case 'platinum':
  362. case 'master':
  363. $level = 'ultimate';
  364. break;
  365. }
  366. // Return the plan level.
  367. return $level;
  368. }
  369. /**
  370. * Dismiss the notification via AJAX.
  371. *
  372. * @since 1.0.0
  373. */
  374. public function dismiss_notification() {
  375. if ( ! apply_filters( 'am_notifications_display', is_super_admin() ) ) {
  376. die;
  377. }
  378. $notification_id = intval( $_POST['notification_id'] );
  379. update_post_meta( $notification_id, 'viewed', 1 );
  380. die;
  381. }
  382. /**
  383. * Revokes notifications.
  384. *
  385. * @since 1.0.0
  386. *
  387. * @param array $ids An array of notification IDs to revoke.
  388. */
  389. public function revoke_notifications( $ids ) {
  390. // Loop through each of the IDs and find the post that has it as meta.
  391. foreach ( (array) $ids as $id ) {
  392. $notifications = $this->get_plugin_notifications( - 1, array( 'post_status' => 'all', 'meta_key' => 'notification_id', 'meta_value' => $id ) );
  393. if ( $notifications ) {
  394. foreach ( $notifications as $notification ) {
  395. update_post_meta( $notification->ID, 'viewed', 1 );
  396. }
  397. }
  398. }
  399. }
  400. }