PageRenderTime 45ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/content-web-clean/plugins/wp-smushit/lib/class-wp-smush-s3.php

https://bitbucket.org/Salmendrote/wordpress-clean
PHP | 452 lines | 287 code | 62 blank | 103 comment | 65 complexity | 46bea5d159f62877cfc8e98896dabb7b MD5 | raw file
Possible License(s): MPL-2.0-no-copyleft-exception, LGPL-2.1, GPL-2.0, BSD-3-Clause, MIT
  1. <?php
  2. /**
  3. * @package WP Smush
  4. * @subpackage S3
  5. * @version 2.7
  6. *
  7. * @author Umesh Kumar <umesh@incsub.com>
  8. *
  9. * @copyright (c) 2017, Incsub (http://incsub.com)
  10. */
  11. if ( ! class_exists( 'WpSmushS3' ) ) {
  12. class WpSmushS3 {
  13. private $setup_notice = '';
  14. private $message_type = 'error';
  15. function __construct() {
  16. $this->init();
  17. //Hook at the end of setting row to output a error div
  18. add_action( 'smush_setting_column_right_end', array( $this, 's3_setup_message' ) );
  19. }
  20. function init() {
  21. global $WpSmush;
  22. //Filters the setting variable to add S3 setting title and description
  23. add_filter( 'wp_smush_settings', array( $this, 'register' ), 6 );
  24. //Filters the setting variable to add S3 setting in premium features
  25. add_filter( 'wp_smush_pro_settings', array( $this, 'add_setting' ), 6 );
  26. //return if not a pro user
  27. if ( ! $WpSmush->validate_install() ) {
  28. return;
  29. }
  30. //Check if the file exists for the given path and download
  31. add_action( 'smush_file_exists', array( $this, 'maybe_download_file' ), 10, 3 );
  32. //Check if the backup file exists
  33. add_filter( 'smush_backup_exists', array( $this, 'backup_exists_on_s3' ), 10, 3 );
  34. }
  35. /**
  36. * Filters the setting variable to add S3 setting title and description
  37. *
  38. * @param $settings
  39. *
  40. * @return mixed
  41. */
  42. function register( $settings ) {
  43. $plugin_url = esc_url( "https://wordpress.org/plugins/amazon-s3-and-cloudfront/" );
  44. $settings['s3'] = array(
  45. 'label' => esc_html__( 'Enable Amazon S3 support', 'wp-smushit' ),
  46. 'short_label' => esc_html__( 'Amazon S3', 'wp-smushit' ),
  47. 'desc' => sprintf( esc_html__( "Storing your image on S3 buckets using %sWP Offload S3%s? Smush can detect and smush those assets for you, including when you're removing files from your host server.", 'wp-smushit' ), "<a href='" . $plugin_url . "' target = '_blank'>", "</a>", "<b>", "</b>" )
  48. );
  49. return $settings;
  50. }
  51. /**
  52. * Append S3 in pro feature list
  53. *
  54. * @param $pro_settings
  55. *
  56. * @return array
  57. */
  58. function add_setting( $pro_settings ) {
  59. if ( ! isset( $pro_settings['s3'] ) ) {
  60. $pro_settings[] = 's3';
  61. }
  62. return $pro_settings;
  63. }
  64. /**
  65. * Prints the message for S3 setup
  66. *
  67. * @param $setting_key
  68. *
  69. * @return null
  70. */
  71. function s3_setup_message( $setting_key ) {
  72. //Return if not S3
  73. if( 's3' != $setting_key ) {
  74. return;
  75. }
  76. global $as3cf, $WpSmush, $wpsmush_settings;
  77. $show_error = false;
  78. //If S3 integration is not enabled, return
  79. $setting_val = $WpSmush->validate_install() ? $wpsmush_settings->settings['s3'] : 0;
  80. if ( ! $setting_val ) {
  81. return;
  82. }
  83. //Check if plugin is setup or not
  84. //In case for some reason, we couldn't find the function
  85. if ( ! is_object( $as3cf ) || ! method_exists( $as3cf, 'is_plugin_setup' ) ) {
  86. $show_error = true;
  87. $support_url = esc_url( "https://premium.wpmudev.org/contact" );
  88. $this->setup_notice = sprintf( esc_html__( "We are having trouble interacting with WP Offload S3, make sure the plugin is activated. Or you can %sreport a bug%s.", "wp-smushit" ), '<a href="' . $support_url . '" target="_blank">', '</a>' );
  89. }
  90. //Plugin is not setup, or some information is missing
  91. if ( ! $as3cf->is_plugin_setup() ) {
  92. $show_error = true;
  93. $configure_url = $as3cf->get_plugin_page_url();
  94. $this->setup_notice = sprintf( esc_html__( "It seems you haven't finished setting up WP Offload S3 yet. %sConfigure%s it now to enable Amazon S3 support.", "wp-smushit" ), "<a href='" . $configure_url . "' target='_blank'>", "</a>" );
  95. } else {
  96. $this->message_type = 'notice';
  97. $this->setup_notice = esc_html__( "Amazon S3 support is active.", "wp-smushit" );
  98. }
  99. //Return Early if we don't need to do anything
  100. if ( empty( $this->setup_notice ) ) {
  101. return;
  102. }
  103. $class = 'error' == $this->message_type ? ' smush-s3-setup-error' : ' smush-s3-setup-message';
  104. $icon_class = 'error' == $this->message_type ? ' icon-fi-warning-alert' : ' icon-fi-check-tick';
  105. echo "<div class='wp-smush-notice" . $class . "'><i class='" . $icon_class . "'></i><p>$this->setup_notice</p></div>";
  106. }
  107. /**
  108. * Error message to show when S3 support is required.
  109. *
  110. * Show a error message to admins, if they need to enable S3 support. If "remove files from
  111. * server" option is enabled in WP Offload S3 plugin, we need WP Smush Pro to enable S3 support.
  112. *
  113. * @return mixed
  114. */
  115. function s3_support_required_notice() {
  116. global $wpsmushit_admin, $wpsmush_settings;
  117. // Do not display it for other users.
  118. // Do not display on network screens, if networkwide option is disabled.
  119. if ( ! current_user_can( 'manage_options' ) || ( is_network_admin() && ! $wpsmush_settings->settings['networkwide'] ) ) {
  120. return true;
  121. }
  122. // Do not display the notice on Bulk Smush Screen.
  123. global $current_screen;
  124. if ( ! empty( $current_screen->base ) && 'toplevel_page_smush' != $current_screen->base && 'toplevel_page_smush-network' != $current_screen->base && 'gallery_page_wp-smush-nextgen-bulk' != $current_screen->base && 'toplevel_page_smush-network' != $current_screen->base ) {
  125. return true;
  126. }
  127. // If already dismissed, do not show.
  128. if ( 1 == get_site_option( 'wp-smush-hide_s3support_alert' ) ) {
  129. return true;
  130. }
  131. // Return early, if support is not required.
  132. if ( ! $this->s3_support_required() ) {
  133. return true;
  134. }
  135. wp_enqueue_script( 'wp-smushit-notice-js' );
  136. // Settings link.
  137. $settings_link = is_multisite() && is_network_admin() ? network_admin_url( 'admin.php?page=smush' ) : menu_page_url( 'smush', false );
  138. if ( $wpsmushit_admin->validate_install() ) {
  139. // If premium user, but S3 support is not enabled.
  140. $message = sprintf( __( "We can see you have WP Offload S3 installed with the <strong>Remove Files From Server</strong> option activated. If you want to optimize your S3 images you'll need to enable the <a href='%s'><strong>Amazon S3 Support</strong></a> feature in Smush's settings.", 'wp-smushit' ), $settings_link );
  141. } else {
  142. // If not a premium user.
  143. $message = sprintf( __( "We can see you have WP Offload S3 installed with the <strong>Remove Files From Server</strong> option activated. If you want to optimize your S3 images you'll need to <a href='%s'><strong>upgrade to Smush Pro</strong></a>", 'wp-smushit' ), esc_url( 'https://premium.wpmudev.org/project/wp-smush-pro' ) );
  144. }
  145. echo '<div class="wp-smush-notice wp-smush-s3support-alert notice"><span class="notice-message">' . $message . '</span><i class="icon-fi-close"></i></div>';
  146. }
  147. /**
  148. * Check if S3 support is required for Smush.
  149. *
  150. * @return bool
  151. */
  152. function s3_support_required() {
  153. global $wpsmush_settings, $wpsmushit_admin, $as3cf;
  154. // Check if S3 offload plugin is active and delete file from server option is enabled.
  155. if ( ! is_object( $as3cf ) || ! method_exists( $as3cf, 'get_setting' ) || ! $as3cf->get_setting( 'remove-local-file' ) ) {
  156. return false;
  157. }
  158. // If not Pro user or S3 support is disabled.
  159. return ( ! $wpsmushit_admin->validate_install() || ! $wpsmush_settings->settings['s3'] );
  160. }
  161. /**
  162. * Checks if the given attachment is on S3 or not, Returns S3 URL or WP Error
  163. *
  164. * @param $attachment_id
  165. *
  166. * @return bool|false|string
  167. *
  168. */
  169. function is_image_on_s3( $attachment_id = '' ) {
  170. global $as3cf;
  171. if ( empty( $attachment_id ) ) {
  172. return false;
  173. }
  174. //If we only have the attachment id
  175. $full_url = $as3cf->is_attachment_served_by_s3( $attachment_id, true );
  176. //If the filepath contains S3, get the s3 URL for the file
  177. if ( ! empty( $full_url ) ) {
  178. $full_url = $as3cf->get_attachment_url( $attachment_id );
  179. } else {
  180. $full_url = false;
  181. }
  182. return $full_url;
  183. }
  184. /**
  185. * Download a specified file to local server with respect to provided attachment id
  186. * and/or Attachment path
  187. *
  188. * @param $attachment_id
  189. *
  190. * @param array $size_details
  191. *
  192. * @param string $uf_file_path
  193. *
  194. * @return string|bool Returns file path or false
  195. *
  196. */
  197. function download_file( $attachment_id, $size_details = array(), $uf_file_path = '' ) {
  198. global $WpSmush, $wpsmush_settings;
  199. if ( empty( $attachment_id ) || ! $wpsmush_settings->settings['s3'] || ! $WpSmush->validate_install() ) {
  200. return false;
  201. }
  202. global $as3cf;
  203. $renamed = $s3_object = $s3_url = $file = false;
  204. //If file path wasn't specified in argument
  205. $uf_file_path = empty( $uf_file_path ) ? get_attached_file( $attachment_id, true ) : $uf_file_path;
  206. //If we have plugin method available, us that otherwise check it ourselves
  207. if ( method_exists( $as3cf, 'is_attachment_served_by_s3' ) ) {
  208. $s3_object = $as3cf->is_attachment_served_by_s3( $attachment_id, true );
  209. $size_prefix = dirname( $s3_object['key'] );
  210. $size_file_prefix = ( '.' === $size_prefix ) ? '' : $size_prefix . '/';
  211. if ( ! empty( $size_details ) && is_array( $size_details ) ) {
  212. $s3_object['key'] = path_join( $size_file_prefix, $size_details['file'] );
  213. } elseif ( ! empty( $uf_file_path ) ) {
  214. //Get the File path using basename for given attachment path
  215. $s3_object['key'] = path_join( $size_file_prefix, wp_basename( $uf_file_path ) );
  216. }
  217. //Try to download the attachment
  218. if ( $s3_object && is_object( $as3cf->plugin_compat ) && method_exists( $as3cf->plugin_compat, 'copy_s3_file_to_server' ) ) {
  219. //Download file
  220. $file = $as3cf->plugin_compat->copy_s3_file_to_server( $s3_object, $uf_file_path );
  221. }
  222. if ( $file ) {
  223. return $file;
  224. }
  225. }
  226. //If we don't have the file, Try it the basic way
  227. if ( ! $file ) {
  228. $s3_url = $this->is_image_on_s3( $attachment_id );
  229. //If we couldn't get the image URL, return false
  230. if ( is_wp_error( $s3_url ) || empty( $s3_url ) || ! $s3_url ) {
  231. return false;
  232. }
  233. if ( ! empty( $size_details ) ) {
  234. //If size details are available, Update the URL to get the image for the specified size
  235. $s3_url = str_replace( wp_basename( $s3_url ), $size_details['file'], $s3_url );
  236. } elseif ( ! empty( $uf_file_path ) ) {
  237. //Get the File path using basename for given attachment path
  238. $s3_url = str_replace( wp_basename( $s3_url ), wp_basename( $uf_file_path ), $s3_url );
  239. }
  240. //Download the file
  241. $temp_file = download_url( $s3_url );
  242. if ( ! is_wp_error( $temp_file ) ) {
  243. $renamed = @copy( $temp_file, $uf_file_path );
  244. unlink( $temp_file );
  245. }
  246. //If we were able to successfully rename the file, return file path
  247. if ( $renamed ) {
  248. return $uf_file_path;
  249. }
  250. }
  251. return false;
  252. }
  253. /**
  254. * Check if file exists for the given path
  255. *
  256. * @param string $attachment_id
  257. * @param string $file_path
  258. *
  259. * @return bool
  260. */
  261. function does_image_exists( $attachment_id = '', $file_path = '' ) {
  262. global $as3cf;
  263. if ( empty( $attachment_id ) || empty( $file_path ) ) {
  264. return false;
  265. }
  266. //Return if method doesn't exists
  267. if ( ! method_exists( $as3cf, 'is_attachment_served_by_s3' ) ) {
  268. error_log( "Couldn't find method is_attachment_served_by_s3." );
  269. return false;
  270. }
  271. //Get s3 object for the file
  272. $s3_object = $as3cf->is_attachment_served_by_s3( $attachment_id, true );
  273. $size_prefix = dirname( $s3_object['key'] );
  274. $size_file_prefix = ( '.' === $size_prefix ) ? '' : $size_prefix . '/';
  275. //Get the File path using basename for given attachment path
  276. $s3_object['key'] = path_join( $size_file_prefix, wp_basename( $file_path ) );
  277. //Get bucket details
  278. $bucket = $as3cf->get_setting( 'bucket' );
  279. $region = $as3cf->get_setting( 'region' );
  280. if ( is_wp_error( $region ) ) {
  281. return false;
  282. }
  283. $s3client = $as3cf->get_s3client( $region );
  284. $file_exists = $s3client->doesObjectExist( $bucket, $s3_object['key'] );
  285. return $file_exists;
  286. }
  287. /**
  288. * Check if the file is served by S3 and download the file for given path
  289. *
  290. * @param string $file_path Full file path
  291. * @param string $attachment_id
  292. * @param array $size_details Array of width and height for the image
  293. *
  294. * @return bool|string False/ File Path
  295. */
  296. function maybe_download_file( $file_path = '', $attachment_id = '', $size_details = array() ) {
  297. if ( empty( $file_path ) || empty( $attachment_id ) ) {
  298. return false;
  299. }
  300. //Download if file not exists and served by S3
  301. if ( ! file_exists( $file_path ) && $this->is_image_on_s3( $attachment_id ) ) {
  302. return $this->download_file( $attachment_id, $size_details, $file_path );
  303. }
  304. return false;
  305. }
  306. /**
  307. * Checks if we've backup on S3 for the given attachment id and backup path
  308. *
  309. * @param string $attachment_id
  310. * @param string $backup_path
  311. *
  312. * @return bool
  313. */
  314. function backup_exists_on_s3( $exists, $attachment_id = '', $backup_path = '' ) {
  315. //If the file is on S3, Check if backup image object exists
  316. if ( $this->is_image_on_s3( $attachment_id ) ) {
  317. return $this->does_image_exists( $attachment_id, $backup_path );
  318. }
  319. return $exists;
  320. }
  321. }
  322. global $wpsmush_s3;
  323. $wpsmush_s3 = new WpSmushS3();
  324. }
  325. if ( class_exists( 'AS3CF_Plugin_Compatibility' ) && ! class_exists( 'wp_smush_s3_compat' ) ) {
  326. class wp_smush_s3_compat extends AS3CF_Plugin_Compatibility {
  327. function __construct() {
  328. $this->init();
  329. }
  330. function init() {
  331. //Plugin Compatibility with Amazon S3
  332. add_filter( 'as3cf_get_attached_file', array( $this, 'smush_download_file' ), 11, 4 );
  333. }
  334. /**
  335. * Download the attached file from S3 to local server
  336. *
  337. * @param $url
  338. * @param $file
  339. * @param $attachment_id
  340. * @param $s3_object
  341. */
  342. function smush_download_file( $url, $file, $attachment_id, $s3_object ) {
  343. global $as3cf, $wpsmush_settings, $WpSmush;
  344. //Return if integration is disabled, or not a pro user
  345. if ( ! $wpsmush_settings->settings['s3'] || ! $WpSmush->validate_install() ) {
  346. return $url;
  347. }
  348. //If we already have the local file at specified path
  349. if ( file_exists( $file ) ) {
  350. return $url;
  351. }
  352. //Download image for Manual and Bulk Smush
  353. $action = ! empty( $_GET['action'] ) ? $_GET['action'] : '';
  354. if ( empty( $action ) || ! in_array( $action, array( 'wp_smushit_manual', 'wp_smushit_bulk' ) ) ) {
  355. return $url;
  356. }
  357. //If the plugin compat object is not available, or the method has been updated
  358. if ( ! is_object( $as3cf->plugin_compat ) || ! method_exists( $as3cf->plugin_compat, 'copy_image_to_server_on_action' ) ) {
  359. return $url;
  360. }
  361. $as3cf->plugin_compat->copy_image_to_server_on_action( $action, true, $url, $file, $s3_object );
  362. }
  363. }
  364. global $wpsmush_s3_compat;
  365. $wpsmush_s3_compat = new wp_smush_s3_compat();
  366. }