PluginProbe
WP-Stateless – Google Cloud Storage / trunk
WP-Stateless – Google Cloud Storage vtrunk
4.4.3 2.1.7 2.1.8 2.1.9 2.2.0 2.2.1 2.2.2 2.2.3 2.2.4 2.2.5 2.2.6 2.2.7 2.3.0 2.3.1 2.3.2 3.0 3.0.1 3.0.2 3.0.3 3.0.4 3.1.0 3.1.1 3.2.0 3.2.1 3.2.2 All 62 releases
← All changes | lib/classes/class-bootstrap.php +804 -596 3.0.4trunk View file →
@@ -1,19 +1,27 @@
1 1 <?php
2 +
2 3 /**
3 4 * Bootstrap
4 5 *
5 6 * @since 0.2.0
6 7 */
8 +
7 9 namespace wpCloud\StatelessMedia {
8 10
9 11 use Google\Cloud\Storage\StorageClient;
10 12 use Google\Auth\HttpHandler\HttpHandlerFactory;
13 + use wpCloud\StatelessMedia\Sync\FileSync;
14 + use wpCloud\StatelessMedia\Sync\ImageSync;
15 + use wpCloud\StatelessMedia\Sync\NonLibrarySync;
16 + use wpCloud\StatelessMedia\Batch\BatchTaskManager;
11 17
12 - if( !class_exists( 'wpCloud\StatelessMedia\Bootstrap' ) ) {
18 + if (!class_exists('wpCloud\StatelessMedia\Bootstrap')) {
13 19
14 20 final class Bootstrap extends \UsabilityDynamics\WP\Bootstrap_Plugin {
15 21
22 + const REQUIRED_PHP_VERSION = '5.5';
23 +
16 24 /**
17 25 * Google Storage Client
18 26 * Use $this->get_client()
19 27 *
@@ -45,15 +53,24 @@
45 53 * Attention: MUST NOT BE CALLED DIRECTLY! USE get_instance() INSTEAD!
46 54 * @param $args
47 55 * @author peshkov@UD
48 56 */
49 - protected function __construct( $args ) {
50 - parent::__construct( $args );
57 + protected function __construct($args) {
58 + /**
59 + * Need to be loaded before plugin initialization.
60 + */
61 + if ( !(defined('WP_STATELESS_COMPATIBILITY_GAE') && !WP_STATELESS_COMPATIBILITY_GAE) ) {
62 + AppEngine::instance();
63 + }
51 64
65 + parent::__construct($args);
66 +
67 + self::$version = $args['version'] ?? self::$version;
68 +
52 69 /**
53 70 * Add custom args to api ping request
54 71 */
55 - add_filter('ud-api-client-ping-args', function($args, $_, $__) {
72 + add_filter('ud-api-client-ping-args', function ($args, $_, $__) {
56 73 $args['multisite'] = is_multisite();
57 74 $args['stateless_media'] = Utility::get_stateless_media_data_count();
58 75 return $args;
59 76 }, 10, 3);
@@ -58,16 +75,18 @@
58 75 return $args;
59 76 }, 10, 3);
60 77
61 78 //** Define our Admin Notices handler object */
62 - $this->errors = new Errors( array_merge( $args, array(
79 + $this->errors = new Errors(array_merge($args, array(
63 80 'type' => $this->type
64 - ) ) );
81 + )));
65 82
66 83 // Initialize compatibility modules.
67 - add_action( 'plugins_loaded', function(){
84 + add_action('plugins_loaded', function () {
85 + Addons::instance();
68 86 new Module();
69 - });
87 + DynamicImageSupport::instance();
88 + }, 20);
70 89
71 90 /**
72 91 * Define settings and UI.
73 92 *
@@ -79,48 +98,66 @@
79 98 * Manually Update/Add option
80 99 * $this->set( 'sm.client_id', 'zxcvv12adffse' );
81 100 */
82 101 $this->settings = new Settings($this);
102 + Status::instance();
83 103 }
84 104
85 105 /**
86 106 * Prevent loading of textdomain
87 107 */
88 - public function load_textdomain(){}
108 + public function load_textdomain() {
109 + }
89 110
90 111 /**
91 112 * Instantiate class.
92 113 */
93 114 public function init() {
94 - // Parse feature falgs, set constants.
115 + // Parse feature flags, set constants.
95 116 $this->parse_feature_flags();
96 - $sm_mode = $this->get( 'sm.mode' );
117 + $sm_mode = $this->get('sm.mode');
97 118
119 + /**
120 + * Send admin email
121 + */
122 + add_action('wp_stateless_send_admin_email', array($this, 'send_admin_email'), 10, 3);
123 +
124 + // Should be created unconditionally and as early as possible to handle batch migration requests
125 + Migrator::instance();
126 + BatchTaskManager::instance();
127 +
98 128 new SyncNonMedia();
99 129
130 + ImageSync::instance();
131 + FileSync::instance();
132 + NonLibrarySync::instance();
133 +
100 134 // Invoke REST API
101 - add_action( 'rest_api_init', array( $this, 'api_init' ) );
135 + add_action('rest_api_init', array($this, 'api_init'));
102 136
103 137 // Register meta boxes and fields for media edit page
104 - add_filter( 'rwmb_meta_boxes', array( $this, 'attachment_meta_box_callback' ) );
138 + add_filter('rwmb_meta_boxes', array($this, 'attachment_meta_box_callback'));
105 139
106 140 // Register meta boxes and fields for media modal page
107 - add_filter( 'attachment_fields_to_edit', array( $this, 'attachment_modal_meta_box_callback' ), 11, 2 );
141 + add_filter('attachment_fields_to_edit', array($this, 'attachment_modal_meta_box_callback'), 11, 2);
108 142
143 + // Get the REST API root
144 + add_filter('wp_stateless_rest_api_root', array($this, 'get_rest_api_root'));
145 +
109 146 /**
110 147 * Init hook
111 148 */
112 - add_action( 'admin_init', array( $this, 'admin_init' ) );
149 + add_action('admin_init', array($this, 'admin_init'));
113 150
114 151 /**
115 152 * Handle switch blog properly.
116 153 */
117 - add_action( 'switch_blog', array( $this, 'on_switch_blog' ), 10, 2 );
154 + add_action('switch_blog', array($this, 'on_switch_blog'), 10, 2);
118 155
119 156 /**
120 157 * Filter for getting stateless settings
121 158 */
122 - add_filter( 'stateless::get_settings', array( $this, 'get_settings' ), 10);
159 + add_filter('stateless::get_settings', array($this, 'get_settings'), 10);
123 160
124 161 /**
125 162 * Init AJAX jobs
126 163 */
@@ -128,33 +165,47 @@
128 165
129 166 /**
130 167 * Load WP-CLI Commands
131 168 */
132 - if( defined( 'WP_CLI' ) && WP_CLI ) {
169 + if (defined('WP_CLI') && WP_CLI) {
133 170 include_once($this->path('lib/cli/class-sm-cli-command.php', 'dir'));
134 171 }
135 172
136 - $this->is_network_detected();
137 -
138 173 /**
139 174 * Add scripts
140 175 */
141 - add_action( 'admin_enqueue_scripts', array( $this, 'admin_enqueue_scripts' ) );
176 + add_action('admin_enqueue_scripts', array($this, 'admin_enqueue_scripts'));
142 177
143 178 /**
144 179 * Delete table when blog is deleted.
145 180 */
146 - add_action( 'wp_delete_site', array($this, 'wp_delete_site'));
181 + add_action('wp_delete_site', array($this, 'wp_delete_site'));
147 182
148 183 /**
149 184 * To prevent fatal errors for users who use PHP 5.5 or less.
150 185 */
151 - if( version_compare(PHP_VERSION, '5.5', '<') ) {
152 - $this->errors->add( sprintf( __( 'The plugin requires PHP %s or higher. You current PHP version %s is too old.', ud_get_stateless_media()->domain ), '<b>5.5</b>', '<b>' . PHP_VERSION . '</b>' ) );
186 + if (version_compare(PHP_VERSION, self::REQUIRED_PHP_VERSION, '<')) {
187 + $this->errors->add(sprintf(__('The plugin requires PHP %s or higher. You current PHP version %s is too old.', ud_get_stateless_media()->domain), '<b>' . self::REQUIRED_PHP_VERSION . '</b>', '<b>' . PHP_VERSION . '</b>'));
153 188 }
154 189
190 + /**
191 + * Add the currently processing nag
192 + */
193 + foreach (Utility::get_available_sync_classes() as $process) {
194 + if ($process->is_running()) {
195 + $this->errors->add([
196 + 'title' => __('Media Library Synchronization Underway', ud_get_stateless_media()->domain),
197 + 'message' => __('WP-Stateless is synchronizing your media library in accordance with the Mode setting. You can view progress or stop the process via the WP-Stateless Sync settings area.', ud_get_stateless_media()->domain),
198 + 'button' => __('View Synchronization', ud_get_stateless_media()->domain),
199 + 'button_link' => admin_url('upload.php?page=stateless-settings&tab=stless_sync_tab'),
200 + 'key' => 'processing-in-progress'
201 + ], 'message');
202 + break;
203 + }
204 + }
205 +
155 206 /* Initialize plugin only if Mode is not 'disabled'. */
156 - if ( ($sm_mode !== 'disabled' && $sm_mode !== 'stateless') || ( $sm_mode === 'stateless' && wp_doing_ajax() )) {
207 + if (($sm_mode !== 'disabled' && $sm_mode !== 'stateless') || ($sm_mode === 'stateless' && (wp_doing_ajax() || wp_doing_cron()))) {
157 208
158 209 /**
159 210 * Determine if we have issues with connection to Google Storage Bucket
160 211 * if SM is not disabled.
@@ -160,38 +211,58 @@
160 211 * if SM is not disabled.
161 212 */
162 213 $is_connected = $this->is_connected_to_gs();
163 214
164 - if ( is_wp_error( $is_connected ) ) {
165 - $this->errors->add( $is_connected->get_error_message(), 'warning' );
215 + if (is_wp_error($is_connected)) {
216 + $this->errors->add($is_connected->get_error_message(), 'warning', false);
166 217 }
167 218
168 - if ( $googleSDKVersionConflictError = get_transient( "wp_stateless_google_sdk_conflict" ) ) {
169 - $this->errors->add( $googleSDKVersionConflictError, 'warning' );
219 + if ($googleSDKVersionConflictError = get_transient("wp_stateless_google_sdk_conflict")) {
220 + $this->errors->add($googleSDKVersionConflictError, 'warning', false);
170 221 }
171 222
172 223 /**
173 224 * Carry on only if we do not have errors.
174 225 */
175 - if( !$this->has_errors() ) {
226 + if (!$this->has_errors()) {
176 227
177 - if( in_array( $sm_mode , array( 'cdn', 'ephemeral', 'stateless' ) ) ) {
228 + if (in_array($sm_mode, array('cdn', 'ephemeral', 'stateless'))) {
178 229 /**
179 230 * init main filters
180 231 */
181 - $this->_init_filters( 'main' );
232 + $this->_init_filters('main');
182 233 }
183 234
184 - if( $sm_mode === 'ephemeral' || $sm_mode === 'stateless' ){
235 + if ($sm_mode === 'ephemeral' || $sm_mode === 'stateless') {
185 236 // Store attachment id in a static variable on 'intermediate_image_sizes_advanced' filter.
186 237 // Utility::store_can_delete_attachment();
187 - if(function_exists('is_wp_version_compatible') && is_wp_version_compatible('5.3-RC4-46673')){
188 - add_filter( 'intermediate_image_sizes_advanced', array('wpCloud\StatelessMedia\Utility', 'store_can_delete_attachment'), 10, 3 );
238 + if (function_exists('is_wp_version_compatible') && is_wp_version_compatible('5.3-RC4-46673')) {
239 + add_filter('intermediate_image_sizes_advanced', array('wpCloud\StatelessMedia\Utility', 'store_can_delete_attachment'), 10, 3);
189 240 }
190 241 }
191 242
192 - if ( $this->get( 'sm.delete_remote' ) == 'true' ) {
243 + if ($sm_mode === 'stateless') {
193 244 /**
245 + * Replacing local path to gs:// for using it on StreamWrapper
246 + */
247 + add_filter('upload_dir', array($this, 'filter_upload_dir'), 99);
248 +
249 + /**
250 + * Stateless mode working only with GD library
251 + */
252 + add_filter('wp_image_editors', array($this, 'select_wp_image_editors'));
253 +
254 + /**
255 + * Init GS client
256 + */
257 + global $gs_client;
258 + if ($gs_client = $this->init_gs_client()) {
259 + StreamWrapper::register($gs_client);
260 + }
261 + }
262 +
263 + if ($this->get('sm.delete_remote') == 'true') {
264 + /**
194 265 * On physical file deletion we remove any from GS
195 266 * We need priority grater than default (10) for ShortPixel plugin to work properly.
196 267 */
197 268 add_filter('delete_attachment', array($this, 'remove_media'), 11);
@@ -199,37 +270,57 @@
199 270
200 271 /**
201 272 * init client's filters
202 273 */
203 - $this->_init_filters( 'client' );
274 + $this->_init_filters('client');
204 275 }
205 -
206 - } elseif ( $sm_mode == 'stateless' ) {
276 + } elseif ($sm_mode == 'stateless') {
207 277 /**
208 - * Replacing local path to gs:// for using it on StreamWrapper
278 + * Determine if we have issues with connection to Google Storage Bucket
279 + * if SM is not disabled.
209 280 */
210 - add_filter('upload_dir', array( $this, 'filter_upload_dir' ), 99);
281 + $is_connected = $this->is_connected_to_gs();
211 282
212 - /**
213 - * Stateless mode working only with GD library
214 - */
215 - add_filter( 'wp_image_editors', array($this, 'select_wp_image_editors') );
283 + if (is_wp_error($is_connected)) {
284 + $this->errors->add($is_connected->get_error_message(), 'warning', false);
285 + }
216 286
217 - //init GS client
218 - global $gs_client;
219 - if ( $gs_client = $this->init_gs_client() ) {
220 - StreamWrapper::register($gs_client);
287 + if ($googleSDKVersionConflictError = get_transient("wp_stateless_google_sdk_conflict")) {
288 + $this->errors->add($googleSDKVersionConflictError, 'warning', false);
221 289 }
222 290
223 291 /**
224 - * init client's filters
292 + * Carry on only if we do not have errors.
225 293 */
226 - $this->_init_filters( 'client' );
294 + if (!$this->has_errors()) {
295 + /**
296 + * Replacing local path to gs:// for using it on StreamWrapper
297 + */
298 + add_filter('upload_dir', array($this, 'filter_upload_dir'), 99);
227 299
228 - /**
229 - * init main filters
230 - */
231 - $this->_init_filters( 'main' );
300 + /**
301 + * Stateless mode working only with GD library
302 + */
303 + add_filter('wp_image_editors', array($this, 'select_wp_image_editors'));
304 +
305 + /**
306 + * Init GS client
307 + */
308 + global $gs_client;
309 + if ($gs_client = $this->init_gs_client()) {
310 + StreamWrapper::register($gs_client);
311 + }
312 +
313 + /**
314 + * init client's filters
315 + */
316 + $this->_init_filters('client');
317 +
318 + /**
319 + * init main filters
320 + */
321 + $this->_init_filters('main');
322 + }
232 323 }
233 324 }
234 325
235 326 /**
@@ -235,53 +326,50 @@
235 326 /**
236 327 * Init additional filters which uses on all modes
237 328 * @param string $type
238 329 */
239 - private function _init_filters ( $type = '' ) {
240 - switch( $type) {
330 + private function _init_filters($type = '') {
331 + switch ($type) {
241 332 case 'main':
242 - add_filter( 'wp_get_attachment_image_attributes', array( $this, 'wp_get_attachment_image_attributes' ), 20, 3 );
243 - add_filter( 'wp_get_attachment_url', array( $this, 'wp_get_attachment_url' ), 20, 2 );
244 - add_filter( 'get_attached_file', array( $this, 'get_attached_file' ), 9, 2 );
245 - add_filter( 'attachment_url_to_postid', array( $this, 'attachment_url_to_postid' ), 20, 2 );
333 + add_filter('wp_get_attachment_image_attributes', array($this, 'wp_get_attachment_image_attributes'), 20, 3);
334 + add_filter('wp_get_attachment_url', array($this, 'wp_get_attachment_url'), 20, 2);
335 + add_filter('get_attached_file', array($this, 'get_attached_file'), 9, 2);
336 + add_filter('attachment_url_to_postid', array($this, 'attachment_url_to_postid'), 20, 2);
246 337
247 - if( $this->get( 'sm.body_rewrite' ) == 'true' || $this->get( 'sm.body_rewrite' ) == 'enable_editor' ) {
248 - add_filter( 'the_content', array( $this, 'the_content_filter' ), 99 );
338 + if ($this->get('sm.body_rewrite') == 'true' || $this->get('sm.body_rewrite') == 'enable_editor') {
339 + add_filter('the_content', array($this, 'the_content_filter'), 99);
249 340 }
250 341
251 - if( $this->get( 'sm.body_rewrite' ) == 'true' || $this->get( 'sm.body_rewrite' ) == 'enable_meta' ) {
252 - add_filter( 'get_post_metadata', array( $this, 'post_metadata_filter' ), 2, 4 );
342 + if ($this->get('sm.body_rewrite') == 'true' || $this->get('sm.body_rewrite') == 'enable_meta') {
343 + add_filter('get_post_metadata', array($this, 'post_metadata_filter'), 2, 4);
253 344 }
254 345
255 - add_filter( 'wp_stateless_bucket_link', array( $this, 'wp_stateless_bucket_link' ) );
346 + add_filter('wp_stateless_bucket_link', array($this, 'wp_stateless_bucket_link'));
256 347 break;
257 348 case 'client':
258 349 /**
259 350 * Add custom actions to media rows
260 351 */
261 - add_filter( 'media_row_actions', array( $this, 'add_custom_row_actions' ), 10, 3 );
352 + add_filter('media_row_actions', array($this, 'add_custom_row_actions'), 10, 3);
262 353
263 354 /**
264 355 * Hashify file name if option is enabled
265 356 */
266 - if ( $this->get( 'sm.hashify_file_name' ) == 'true' ) {
267 - add_filter('sanitize_file_name', array( 'wpCloud\StatelessMedia\Utility', 'randomize_filename' ), 10);
357 + if ($this->get('sm.hashify_file_name') == 'true') {
358 + add_filter('sanitize_file_name', array('wpCloud\StatelessMedia\Utility', 'randomize_filename'), 10);
268 359 }
269 360
270 361 /**
271 - * Override Cache Control is option is enabled
362 + * Override Cache Control if option is enabled
272 363 */
273 - $cacheControl = trim($this->get( 'sm.cache_control' ));
274 - if ( !empty($cacheControl) ) {
275 - add_filter( 'sm:item:cacheControl', array( $this, 'override_cache_control' ) );
276 - }
364 + add_filter('sm:item:cacheControl', array($this->settings, 'override_cache_control'));
277 365
278 - add_filter( 'wp_stateless_file_name', array( $this, 'handle_root_dir' ), 10, 5 );
366 + add_filter('wp_stateless_file_name', array($this, 'handle_root_dir'), 10, 4);
279 367
280 368 /**
281 369 * Extends metadata by adding GS information.
282 370 */
283 - add_filter( 'wp_get_attachment_metadata', array( $this, 'wp_get_attachment_metadata' ), 10, 2 );
371 + add_filter('wp_get_attachment_metadata', array($this, 'wp_get_attachment_metadata'), 10, 2);
284 372
285 373 /**
286 374 * Add/Edit Media
287 375 *
@@ -287,20 +375,30 @@
287 375 *
288 376 * Once added or edited we can get into Attachment ID then get all image sizes and sync them with GS
289 377 * We can't use this. That's prevent removing this filter.
290 378 */
291 - add_filter( 'wp_update_attachment_metadata', array( 'wpCloud\StatelessMedia\Utility', 'add_media' ), 999, 2 );
379 + add_filter('wp_update_attachment_metadata', array('wpCloud\StatelessMedia\Utility', 'add_media'), 999, 2);
292 380
293 381 /**
382 + * Delete original in the end of generating metadata
383 + * it does not work with PDF
384 + */
385 + // add_filter('wp_generate_attachment_metadata', function ($metadata, $attachment_id, $state) {
386 + // if (!in_array(ud_get_stateless_media()->get('sm.mode'), array('ephemeral'))) return $metadata;
387 + // @unlink(get_attached_file($attachment_id, true));
388 + // return $metadata;
389 + // }, 99, 3);
390 +
391 + /**
294 392 * Rewrite Image URLS
295 393 */
296 - add_filter( 'image_downsize', array( $this, 'image_downsize' ), 99, 3 );
297 - add_filter( 'wp_calculate_image_srcset', array($this, 'wp_calculate_image_srcset'), 10, 5 );
394 + add_filter('image_downsize', array($this, 'image_downsize'), 99, 3);
395 + add_filter('wp_calculate_image_srcset', array($this, 'wp_calculate_image_srcset'), 10, 5);
298 396
299 397 /**
300 398 * Trigger module initialization and registration.
301 399 */
302 - do_action('sm::module::init', $this->get( 'sm' ));
400 + do_action('sm::module::init', $this->get('sm'));
303 401
304 402 break;
305 403 case 'default':
306 404 break;
@@ -313,10 +411,10 @@
313 411 * array( 'WP_Image_Editor_Imagick', 'WP_Image_Editor_GD' )
314 412 * @param $editors
315 413 * @return array
316 414 */
317 - public function select_wp_image_editors( $editors ) {
318 - return array( 'WP_Image_Editor_GD' );
415 + public function select_wp_image_editors($editors) {
416 + return array('WP_Image_Editor_GD');
319 417 }
320 418
321 419 /**
322 420 * @param callable|null $httpHandler
@@ -322,12 +420,12 @@
322 420 * @param callable|null $httpHandler
323 421 * @return StorageClient
324 422 * @throws \Exception
325 423 */
326 - public function init_gs_client( callable $httpHandler = null ) {
424 + public function init_gs_client(?callable $httpHandler = null) {
327 425 // May be Loading Google SDK....
328 - if( !class_exists( 'HttpHandlerFactory' ) ) {
329 - include_once( ud_get_stateless_media()->path('lib/Google/vendor/autoload.php', 'dir') );
426 + if (!class_exists('HttpHandlerFactory')) {
427 + include_once(ud_get_stateless_media()->path('lib/Google/vendor/autoload.php', 'dir'));
330 428 }
331 429
332 430 $httpHandler = $httpHandler ? $httpHandler : HttpHandlerFactory::build();
333 431
@@ -332,18 +430,21 @@
332 430 $httpHandler = $httpHandler ? $httpHandler : HttpHandlerFactory::build();
333 431
334 432 $json_key = json_decode($this->settings->get('sm.key_json'), true);
335 433
336 - if ( !empty( $json_key ) ) {
434 + if (!empty($json_key)) {
337 435 return new StorageClient(
338 - [ 'keyFile' => $json_key,
339 - 'httpHandler' => function ( $request, $options ) use ( $httpHandler ) {
340 - $xGoogApiClientHeader = $request->getHeaderLine( 'x-goog-api-client' );
341 - $request = $request->withHeader( 'x-goog-api-client', $xGoogApiClientHeader );
436 + [
437 + 'keyFile' => $json_key,
438 + 'httpHandler' => function ($request, $options) use ($httpHandler) {
439 + $xGoogApiClientHeader = $request->getHeaderLine('x-goog-api-client');
440 + $request = $request->withHeader('x-goog-api-client', $xGoogApiClientHeader);
342 441
343 - return call_user_func_array( $httpHandler, [ $request, $options ] );
442 + return call_user_func_array($httpHandler, [$request, $options]);
344 443 },
345 - 'authHttpHandler' => HttpHandlerFactory::build(), ] );
444 + 'authHttpHandler' => HttpHandlerFactory::build(),
445 + ]
446 + );
346 447 }
347 448 }
348 449
349 450 /**
@@ -350,16 +451,16 @@
350 451 * Replacing root dir with GCS path
351 452 * @param $uploads
352 453 * @return array
353 454 */
354 - public function filter_upload_dir( $uploads ) {
455 + public function filter_upload_dir($uploads) {
355 456 global $default_dir;
356 457 if ($default_dir) return $uploads;
357 458 //Bucket
358 - $bucket = $this->get( 'sm.bucket' );
459 + $bucket = $this->get('sm.bucket');
359 460
360 461 //Bucket folder path
361 - $root_dir = $this->get( 'sm.root_dir' );
462 + $root_dir = $this->get('sm.root_dir');
362 463 $root_dir = apply_filters("wp_stateless_handle_root_dir", $root_dir);
363 464
364 465 /**
365 466 * Subdir not uses on Stateless mode
@@ -366,9 +467,9 @@
366 467 */
367 468 $uploads['subdir'] = '';
368 469
369 470 $basedir = rtrim(sprintf('gs://%s/%s', $bucket, $root_dir), '/');
370 - $baseurl = rtrim(sprintf('https://storage.googleapis.com/%s/%s', $bucket, $root_dir ), '/');
471 + $baseurl = rtrim(sprintf('https://storage.googleapis.com/%s/%s', $bucket, $root_dir), '/');
371 472
372 473 $uploads = array(
373 474 'url' => rtrim($baseurl . $uploads['subdir'], '/'),
374 475 'path' => $basedir . $uploads['subdir'],
@@ -390,24 +491,32 @@
390 491 * @param $image_meta
391 492 * @param $attachment_id
392 493 * @return array
393 494 */
394 - public function wp_calculate_image_srcset($sources, $size_array, $image_src, $image_meta, $attachment_id){
395 - $sm_mode = $this->get( 'sm.mode' );
495 + public function wp_calculate_image_srcset($sources, $size_array, $image_src, $image_meta, $attachment_id) {
496 + $sm_mode = $this->get('sm.mode');
497 +
498 + /**
499 + * In Backup mode using local URL
500 + */
501 + if ("backup" == $sm_mode) {
502 + return $sources;
503 + }
504 +
396 505 if (empty($image_meta['gs_link'])) {
397 506 $image_meta = wp_get_attachment_metadata($attachment_id);
398 507 }
399 508
400 - if(is_array($sources) && !empty( $image_meta['gs_link'] )){
509 + if (is_array($sources) && !empty($image_meta['gs_link'])) {
401 510 $gs_name = $image_meta['gs_name'];
402 511 // getting position of root_dir in gs_name.
403 512 $root_dir_pos = strpos($gs_name, $image_meta['file']);
404 513 // removing rood_dir from gs_name so we can compare to replace url with gs_link.
405 - if($root_dir_pos !== false){
514 + if ($root_dir_pos !== false) {
406 515 $gs_name = substr($gs_name, $root_dir_pos);
407 516 }
408 517
409 - if ( !isset($gs_name) || empty($gs_name) ) {
518 + if (!isset($gs_name) || empty($gs_name)) {
410 519 return [];
411 520 }
412 521
413 522 foreach ($sources as $width => &$image) {
@@ -424,9 +533,9 @@
424 533 }
425 534
426 535 $thumb_gs_name = $meta['gs_name'];
427 536 // removing rood_dir from gs_name
428 - if($root_dir_pos !== false){
537 + if ($root_dir_pos !== false) {
429 538 $thumb_gs_name = substr($thumb_gs_name, $root_dir_pos);
430 539 }
431 540
432 541 if (substr_compare($image['url'], $thumb_gs_name, -strlen($thumb_gs_name)) === 0) {
@@ -436,19 +545,19 @@
436 545 }
437 546 }
438 547
439 548 // if no size found and mode is ephemeral or stateless and nothing to show for srcset item - unset that item
440 - if (!$found && ( $sm_mode === 'ephemeral' || $sm_mode === 'stateless' )) {
549 + if (!$found && ($sm_mode === 'ephemeral' || $sm_mode === 'stateless')) {
441 550 $image = null;
442 551 }
443 552 } else {
444 553 // if mode is stateless and nothing to show for srcset item - unset that item
445 - if ( $sm_mode === 'ephemeral' || $sm_mode === 'stateless' ) {
554 + if ($sm_mode === 'ephemeral' || $sm_mode === 'stateless') {
446 555 $image = null;
447 556 }
448 557 }
449 558 }
450 - } elseif ( is_array( $sources ) && $sm_mode === 'stateless' ) {
559 + } elseif (is_array($sources) && $sm_mode === 'stateless') {
451 560 foreach ($sources as $width => &$image) {
452 561 // Set default src
453 562 $image['url'] = $image_src;
454 563 }
@@ -453,9 +562,9 @@
453 562 $image['url'] = $image_src;
454 563 }
455 564 }
456 565
457 - return array_filter( $sources );
566 + return is_array($sources) ? array_filter($sources) : $sources;
458 567 }
459 568
460 569 /**
461 570 * Return gs host.
@@ -465,9 +574,9 @@
465 574 * @param array $sm
466 575 * @return mixed|void
467 576 */
468 577 public function get_gs_host($sm = array()) {
469 - $sm = $sm?$sm: $this->get( 'sm');
578 + $sm = $sm ? $sm : $this->get('sm');
470 579 $image_host = 'https://storage.googleapis.com/';
471 580 $image_host .= $sm['bucket'];
472 581
473 582 $custom_domain = $sm['custom_domain'];
@@ -477,17 +586,29 @@
477 586
478 587 // checking whether the provided domain is valid.
479 588 // if the custom domain is same as the bucket name
480 589 // or the custom domain is using https.
481 - if ( !empty($sm['bucket']) && !empty($custom_domain) && $custom_domain !== 'storage.googleapis.com' && ( $is_ssl === 0 || $custom_domain == $sm['bucket'] ) ) {
590 + if (!empty($sm['bucket']) && !empty($custom_domain) && $custom_domain !== 'storage.googleapis.com' && ($is_ssl === 0 || $custom_domain == $sm['bucket'])) {
482 591 $image_host = $is_ssl === 0 ? 'https://' : 'http://'; // bucketname will be host
483 592 $image_host .= $custom_domain;
484 593 }
485 594
486 - return apply_filters( 'get_gs_host', $image_host, $image_host, $sm['bucket'], $is_ssl, $sm );
595 + return apply_filters('get_gs_host', $image_host, $image_host, $sm['bucket'], $is_ssl, $sm);
487 596 }
488 597
489 598 /**
599 + * Return gs:// path.
600 + *
601 + * @param array $sm
602 + * @return mixed|void
603 + */
604 + public function get_gs_path() {
605 + $path = 'gs://' . $this->get('sm.bucket');
606 +
607 + return apply_filters('get_gs_path', $path);
608 + }
609 +
610 + /**
490 611 * Filter for wp_stateless_bucket_link if custom domain is set.
491 612 * It's get attachment url and remove "storage.googleapis.com" from url.
492 613 * So that custom url can be used.
493 614 *
@@ -494,20 +615,19 @@
494 615 * @param $fileLink
495 616 * @return mixed|string
496 617 */
497 618 public function wp_stateless_bucket_link($fileLink) {
498 - $bucketname = $this->get( 'sm.bucket' );
499 - $custom_domain = $this->get( 'sm.custom_domain' );
619 + $bucketname = $this->get('sm.bucket');
620 + $custom_domain = $this->get('sm.custom_domain');
500 621 $is_ssl = strpos($custom_domain, 'https://') === 0;
501 622 $fileLink_is_ssl = strpos($fileLink, 'https://') === 0;
502 623 $custom_domain = str_replace(array('http://', 'https://'), '', $custom_domain);
503 624 $custom_domain = trim($custom_domain, '/');
504 625
505 - if ( !empty($bucketname) && $custom_domain !== 'storage.googleapis.com' && $custom_domain == $bucketname && strpos($fileLink, $bucketname) > 8 ) {
626 + if (!empty($bucketname) && $custom_domain !== 'storage.googleapis.com' && $custom_domain == $bucketname && strpos($fileLink, $bucketname) > 8) {
506 627 $fileLink = ($is_ssl ? 'https://' : 'http://') . substr($fileLink, strpos($fileLink, $bucketname));
507 - }
508 - elseif( $custom_domain !== 'storage.googleapis.com' && $custom_domain == $bucketname && $fileLink_is_ssl !== $is_ssl){
509 - if($is_ssl)
628 + } elseif ($custom_domain !== 'storage.googleapis.com' && $custom_domain == $bucketname && $fileLink_is_ssl !== $is_ssl) {
629 + if ($is_ssl)
510 630 $fileLink = str_replace(array('http://', 'https://'), 'https://', $fileLink);
511 631 else
512 632 $fileLink = str_replace(array('http://', 'https://'), 'http://', $fileLink);
513 633 }
@@ -519,19 +639,31 @@
519 639 *
520 640 * @param string $path
521 641 * @return string
522 642 */
523 - public function get_settings_page_url( $path = '' ) {
524 - $url = get_admin_url( get_current_blog_id(), ( is_network_admin() ? 'network/settings.php' : 'upload.php' ) );
643 + public function get_settings_page_url($path = '') {
644 + $url = get_admin_url(get_current_blog_id(), (is_network_admin() ? 'network/settings.php' : 'upload.php'));
525 645 return $url . $path;
526 646 }
527 647
528 648 /**
649 + * Return docs page url.
650 + *
651 + * @param string $path
652 + * @return string
653 + */
654 + public function get_docs_page_url($path = '') {
655 + $path = ltrim($path, '/');
656 +
657 + return 'https://stateless.udx.io/' . $path;
658 + }
659 +
660 + /**
529 661 * Get new blog settings once switched blog.
530 662 * @param $new_blog
531 663 * @param $prev_blog_id
532 664 */
533 - public function on_switch_blog( $new_blog, $prev_blog_id ) {
665 + public function on_switch_blog($new_blog, $prev_blog_id) {
534 666 $this->settings->refresh();
535 667 }
536 668
537 669 /**
@@ -559,21 +691,21 @@
559 691
560 692 foreach ($settings_list as $setting) {
561 693
562 694 /** If setting is already exist, just skip it */
563 - if( isset( $settings[ $setting ] ) ) {
695 + if (isset($settings[$setting])) {
564 696 continue;
565 697 }
566 698
567 - $value = $this->get( 'sm.' . $setting );
699 + $value = $this->get('sm.' . $setting);
568 700
569 701 /** Decode json to array */
570 - if( $value && is_string( $value ) && $setting === 'key_json' ) {
571 - $value = json_decode( $value, true );
702 + if ($value && is_string($value) && $setting === 'key_json') {
703 + $value = json_decode($value, true);
572 704 $setting = 'key';
573 705 }
574 706
575 - $settings[ $setting ] = $value;
707 + $settings[$setting] = $value;
576 708 }
577 709
578 710 return $settings;
579 711 }
@@ -591,26 +723,27 @@
591 723 * @param $post
592 724 * @param $detached
593 725 * @return mixed
594 726 */
595 - public function add_custom_row_actions( $actions, $post, $detached ) {
727 + public function add_custom_row_actions($actions, $post, $detached) {
596 728
597 - if ( !current_user_can( 'upload_files' ) ) return $actions;
729 + if (!current_user_can('upload_files')) return $actions;
598 730
599 - $sm_cloud = get_post_meta( $post->ID, 'sm_cloud', 1 );
600 - $sm_mode = $this->get( 'sm.mode' );
601 - if ( !empty($sm_cloud) && $sm_mode === 'stateless' ) return $actions;
731 + $sm_cloud = apply_filters('wp_stateless_get_file', [], $post->ID);
602 732
603 - if ( $post && 'attachment' == $post->post_type && 'image/' == substr( $post->post_mime_type, 0, 6 ) ) {
604 - $actions['sm_sync'] = '<a href="javascript:;" data-id="'.$post->ID.'" data-type="image" class="sm_inline_sync">' . __('Regenerate and Sync with GCS', ud_get_stateless_media()->domain) . '</a>';
733 +
734 + $sm_mode = $this->get('sm.mode');
735 + if (!empty($sm_cloud) && $sm_mode === 'stateless') return $actions;
736 +
737 + if ($post && 'attachment' == $post->post_type && 'image/' == substr($post->post_mime_type, 0, 6)) {
738 + $actions['sm_sync'] = '<a href="javascript:;" data-id="' . $post->ID . '" data-type="image" class="sm_inline_sync">' . __('Regenerate and Sync with GCS', ud_get_stateless_media()->domain) . '</a>';
605 739 }
606 740
607 - if ( $post && 'attachment' == $post->post_type && 'image/' != substr( $post->post_mime_type, 0, 6 ) ) {
608 - $actions['sm_sync'] = '<a href="javascript:;" data-id="'.$post->ID.'" data-type="other" class="sm_inline_sync">' . __('Sync with GCS', ud_get_stateless_media()->domain) . '</a>';
741 + if ($post && 'attachment' == $post->post_type && 'image/' != substr($post->post_mime_type, 0, 6)) {
742 + $actions['sm_sync'] = '<a href="javascript:;" data-id="' . $post->ID . '" data-type="other" class="sm_inline_sync">' . __('Sync with GCS', ud_get_stateless_media()->domain) . '</a>';
609 743 }
610 744
611 745 return $actions;
612 -
613 746 }
614 747
615 748 /**
616 749 * Define REST API.
@@ -621,28 +754,63 @@
621 754
622 755 $route_namespace = 'wp-stateless/v1';
623 756 $api_namespace = 'wpCloud\StatelessMedia\API';
624 757
625 - register_rest_route( $route_namespace, '/status', array(
758 + register_rest_route($route_namespace, '/status', array(
626 759 'methods' => \WP_REST_Server::READABLE,
627 - 'callback' => array( $api_namespace, 'status' ),
760 + 'callback' => array($api_namespace, 'status'),
628 761 'permission_callback' => '__return_true'
629 - ) );
762 + ));
630 763
631 - register_rest_route( $route_namespace, '/getSettings', array(
764 + register_rest_route($route_namespace, '/getSettings', array(
632 765 'methods' => \WP_REST_Server::READABLE,
633 - 'callback' => array( $api_namespace, 'getSettings' ),
634 - 'permission_callback' => array( $api_namespace, 'authCheck' )
635 - ) );
766 + 'callback' => array($api_namespace, 'getSettings'),
767 + 'permission_callback' => array($api_namespace, 'authCheck')
768 + ));
636 769
637 - register_rest_route( $route_namespace, '/updateSettings', array(
770 + register_rest_route($route_namespace, '/updateSettings', array(
638 771 'methods' => \WP_REST_Server::CREATABLE,
639 - 'callback' => array( $api_namespace, 'updateSettings' ),
640 - 'permission_callback' => array( $api_namespace, 'authCheck' )
641 - ) );
772 + 'callback' => array($api_namespace, 'updateSettings'),
773 + 'permission_callback' => array($api_namespace, 'authCheck')
774 + ));
642 775
643 - }
776 + register_rest_route($route_namespace, '/sync/getProcesses', array(
777 + 'methods' => \WP_REST_Server::READABLE,
778 + 'callback' => array($api_namespace, 'syncGetProcesses'),
779 + 'permission_callback' => array($api_namespace, 'authCheck')
780 + ));
644 781
782 + register_rest_route($route_namespace, '/sync/getProcess/(?P<id>\S+)', array(
783 + 'methods' => \WP_REST_Server::READABLE,
784 + 'callback' => array($api_namespace, 'syncGetProcess'),
785 + 'permission_callback' => array($api_namespace, 'authCheck')
786 + ));
787 +
788 + register_rest_route($route_namespace, '/sync/run', array(
789 + 'methods' => \WP_REST_Server::CREATABLE,
790 + 'callback' => array($api_namespace, 'syncRun'),
791 + 'permission_callback' => array($api_namespace, 'authCheck')
792 + ));
793 +
794 + register_rest_route($route_namespace, '/sync/stop', array(
795 + 'methods' => \WP_REST_Server::CREATABLE,
796 + 'callback' => array($api_namespace, 'syncStop'),
797 + 'permission_callback' => array($api_namespace, 'authCheck')
798 + ));
799 +
800 + register_rest_route($route_namespace, '/batch/state', array(
801 + 'methods' => \WP_REST_Server::READABLE,
802 + 'callback' => array($api_namespace, 'batchState'),
803 + 'permission_callback' => array($api_namespace, 'authCheck')
804 + ));
805 +
806 + register_rest_route($route_namespace, '/batch/action', array(
807 + 'methods' => \WP_REST_Server::CREATABLE,
808 + 'callback' => array($api_namespace, 'batchAction'),
809 + 'permission_callback' => array($api_namespace, 'authCheck')
810 + ));
811 + }
812 +
645 813 /**
646 814 * Metabox for media modal page
647 815 * @param $form_fields
648 816 * @param $post
@@ -647,23 +815,23 @@
647 815 * @param $form_fields
648 816 * @param $post
649 817 * @return array
650 818 */
651 - public function attachment_modal_meta_box_callback ( $form_fields, $post ) {
652 -
653 - //do not show on media edit page, only on modal
654 - if ( isset($_GET['post'])) {
819 + public function attachment_modal_meta_box_callback($form_fields, $post) {
820 + // Do not show on media edit page, only on modal
821 + // Do not show if we are not in Media Library
822 + if ( isset($_GET['post']) || wp_doing_ajax() ) {
655 823 return $form_fields;
656 824 }
657 825
658 826 $link = get_edit_post_link($post->ID);
659 827
660 - $form_field[ 'label' ] = '';
661 - $form_field[ 'input' ] = 'html';
662 - $form_field[ 'html' ] = sprintf("<script>jQuery('.actions').prepend('<a href=\"%s#sm-attachment-metabox\">%s</a> | ')</script>", $link, __("View stateless meta", ud_get_stateless_media()->domain));
663 - $form_field[ 'show_in_modal' ] = true;
828 + $form_field['label'] = '';
829 + $form_field['input'] = 'html';
830 + $form_field['html'] = sprintf("<script>jQuery('.sm_edit_links').remove();jQuery('.actions').prepend('<a class=\"sm_edit_links\" href=\"%s#sm-attachment-metabox\">%s</a> | ')</script>", $link, __("View stateless meta", ud_get_stateless_media()->domain));
831 + $form_field['show_in_modal'] = true;
664 832
665 - $form_fields[ 'sm_html' ] = $form_field;
833 + $form_fields['sm_html'] = $form_field;
666 834 return $form_fields;
667 835 }
668 836
669 837 /**
@@ -670,21 +838,21 @@
670 838 * Metabox for media edit page
671 839 * @param $meta_boxes
672 840 * @return array
673 841 */
674 - public function attachment_meta_box_callback( $meta_boxes ) {
842 + public function attachment_meta_box_callback($meta_boxes) {
675 843 $post_id = false;
676 - if ( isset( $_GET['post'] ) ) {
677 - $post_id = intval( $_GET['post'] );
678 - } elseif ( isset( $_POST['post_ID'] ) ) {
679 - $post_id = intval( $_POST['post_ID'] );
680 - } elseif ( isset( $_GET['item'] ) ) {
681 - $post_id = intval( $_GET['item'] );
682 - } elseif ( isset( $_POST['item'] ) ) {
683 - $post_id = intval( $_POST['item'] );
844 + if (isset($_GET['post'])) {
845 + $post_id = intval($_GET['post']);
846 + } elseif (isset($_POST['post_ID'])) {
847 + $post_id = intval($_POST['post_ID']);
848 + } elseif (isset($_GET['item'])) {
849 + $post_id = intval($_GET['item']);
850 + } elseif (isset($_POST['item'])) {
851 + $post_id = intval($_POST['item']);
684 852 }
685 -
686 - return $this->_prepare_data_for_metabox( $meta_boxes, $post_id );
853 +
854 + return $this->_prepare_data_for_metabox($meta_boxes, $post_id);
687 855 }
688 856
689 857 /**
690 858 * Prepare data for metabox fields
@@ -691,14 +859,14 @@
691 859 * @param $meta_boxes
692 860 * @param $post_id
693 861 * @return array
694 862 */
695 - private function _prepare_data_for_metabox ( $meta_boxes, $post_id ) {
696 - $post = get_post ( $post_id );
697 - $sm_cloud = get_post_meta( $post_id, 'sm_cloud', 1 );
698 - $sm_mode = $this->get( 'sm.mode' );
863 + private function _prepare_data_for_metabox($meta_boxes, $post_id) {
864 + $post = get_post($post_id);
865 + $sm_cloud = apply_filters('wp_stateless_get_file', [], $post_id, true);
866 + $sm_mode = $this->get('sm.mode');
699 867
700 - if ( empty( $post ) ) {
868 + if (empty($post)) {
701 869 return $meta_boxes;
702 870 }
703 871
704 872 $sizes = $this->get_image_sizes();
@@ -704,19 +872,19 @@
704 872 $sizes = $this->get_image_sizes();
705 873
706 874 $fields = array();
707 875
708 - if ( $sm_mode !== 'stateless' || empty( $sm_cloud ) ) {
876 + if ($sm_mode !== 'stateless' || empty($sm_cloud)) {
709 877 $fields[] = array(
710 - 'name' => __( 'Regenerate', ud_get_stateless_media()->domain ),
878 + 'name' => __('Regenerate', ud_get_stateless_media()->domain),
711 879 'id' => 'storage_bucket_url',
712 880 'type' => 'custom_html',
713 - 'std' => $this->_prepare_generate_link( $post, false, '', true, $sm_cloud ),
881 + 'std' => $this->_prepare_generate_link($post, false, '', true, $sm_cloud),
714 882 'tab' => 'thumbnails',
715 883 );
716 884 }
717 885
718 - if ( is_array( $sm_cloud ) && !empty( $sm_cloud[ 'fileLink' ] ) ) {
886 + if (is_array($sm_cloud) && !empty($sm_cloud['fileLink'])) {
719 887
720 888 $fields[] = array(
721 889 'type' => 'heading',
722 890 'name' => 'Files',
@@ -723,58 +891,57 @@
723 891 'tab' => 'thumbnails',
724 892 );
725 893
726 894 $fields[] = array(
727 - 'name' => __( 'Original', ud_get_stateless_media()->domain ),
895 + 'name' => __('Original', ud_get_stateless_media()->domain),
728 896 'id' => 'storage_bucket_url',
729 897 'type' => 'custom_html',
730 898 'media_modal' => true,
731 - 'std' => '<label><input type="text" class="widefat urlfield" readonly="readonly" value="'.esc_attr($sm_cloud[ 'fileLink' ]).'" />
732 - <a href="'.$sm_cloud[ 'fileLink' ].'" target="_blank" class="sm-view-link"><i class="dashicons dashicons-external"></i></a>&nbsp;&nbsp;&nbsp;'.$this->_prepare_generate_link( $post, true, '', false, $sm_cloud ).' </label>',
899 + 'std' => '<label><input type="text" class="widefat urlfield" readonly="readonly" value="' . esc_attr($sm_cloud['fileLink']) . '" />
900 + <a href="' . $sm_cloud['fileLink'] . '" target="_blank" class="sm-view-link"><i class="dashicons dashicons-external"></i></a>&nbsp;&nbsp;&nbsp;' . $this->_prepare_generate_link($post, true, '', false, $sm_cloud) . ' </label>',
733 901 'tab' => 'thumbnails',
734 902 );
735 903
736 - if ( !empty( $sm_cloud['sizes'] ) && is_array( $sm_cloud['sizes'] ) ) {
737 - foreach( $sm_cloud['sizes'] as $size_label => $size ) {
904 + if (!empty($sm_cloud['sizes']) && is_array($sm_cloud['sizes'])) {
905 + foreach ($sm_cloud['sizes'] as $size_label => $size) {
738 906
739 907 $fields[] = array(
740 - 'name' => __( sprintf( "%s x %s", ($size['width'] ?: $sizes[$size_label]['width']), ($size['height'] ?: $sizes[$size_label]['height']) ), ud_get_stateless_media()->domain ),
741 - 'id' => 'storage_bucket_url'.$size_label,
908 + 'name' => __(sprintf("%s x %s", ($size['width'] ?: $sizes[$size_label]['width']), ($size['height'] ?: $sizes[$size_label]['height'])), ud_get_stateless_media()->domain),
909 + 'id' => 'storage_bucket_url' . $size_label,
742 910 'type' => 'custom_html',
743 911 'media_modal' => true,
744 - 'std' => '<label><input type="text" class="widefat urlfield" readonly="readonly" value="'.esc_attr($size[ 'fileLink' ]).'" />
745 - <a href="'.$size[ 'fileLink' ].'" target="_blank" class="sm-view-link"><i class="dashicons dashicons-external"></i></a>&nbsp;&nbsp;&nbsp;'.$this->_prepare_generate_link( $post, true, $size_label, false, $sm_cloud ).' </label>',
912 + 'std' => '<label><input type="text" class="widefat urlfield" readonly="readonly" value="' . esc_attr($size['fileLink']) . '" />
913 + <a href="' . $size['fileLink'] . '" target="_blank" class="sm-view-link"><i class="dashicons dashicons-external"></i></a>&nbsp;&nbsp;&nbsp;' . $this->_prepare_generate_link($post, true, $size_label, false, $sm_cloud) . ' </label>',
746 914 'tab' => 'thumbnails',
747 915 );
748 916 }
749 917 }
750 918
751 - if( !empty( $sm_cloud[ 'cacheControl' ] ) ) {
919 + if (!empty($sm_cloud['cacheControl'])) {
752 920 $fields[] = array(
753 - 'name' => __( 'Cache Control', ud_get_stateless_media()->domain ),
921 + 'name' => __('Cache Control', ud_get_stateless_media()->domain),
754 922 'id' => 'cache_control',
755 923 'type' => 'custom_html',
756 - 'std' => '<label><input type="text" class="widefat urlfield" readonly="readonly" value="'.$sm_cloud[ 'cacheControl' ].'" /></label>',
924 + 'std' => '<label><input type="text" class="widefat urlfield" readonly="readonly" value="' . $sm_cloud['cacheControl'] . '" /></label>',
757 925 'tab' => 'meta',
758 926 );
759 927 }
760 928
761 - if ( !empty( $sm_cloud[ 'bucket' ] ) ) {
929 + if (!empty($sm_cloud['bucket'])) {
762 930 $fields[] = array(
763 - 'name' => __( 'Storage Bucket', ud_get_stateless_media()->domain ),
931 + 'name' => __('Storage Bucket', ud_get_stateless_media()->domain),
764 932 'id' => 'storage_bukcet',
765 933 'type' => 'custom_html',
766 - 'std' => '<label><input type="text" class="widefat urlfield" readonly="readonly" value="gs://'.esc_attr($sm_cloud[ 'bucket' ]).'" />
767 - <a href="https://console.cloud.google.com/storage/browser/'.esc_attr($sm_cloud[ 'bucket' ]).'" target="_blank" class="sm-view-link"><i class="dashicons dashicons-external"></i></a></label>',
934 + 'std' => '<label><input type="text" class="widefat urlfield" readonly="readonly" value="gs://' . esc_attr($sm_cloud['bucket']) . '" />
935 + <a href="https://console.cloud.google.com/storage/browser/' . esc_attr($sm_cloud['bucket']) . '" target="_blank" class="sm-view-link"><i class="dashicons dashicons-external"></i></a></label>',
768 936 'tab' => 'meta',
769 937 );
770 938 }
771 -
772 939 }
773 940
774 - $meta_boxes[] = apply_filters( 'sm::attachment::meta', array(
941 + $meta_boxes[] = apply_filters('sm::attachment::meta', array(
775 942 'id' => 'sm-attachment-metabox',
776 - 'title' => __( 'Stateless', ud_get_stateless_media()->domain ),
943 + 'title' => __('Stateless', ud_get_stateless_media()->domain),
777 944 'post_types' => 'attachment',
778 945 //'media_modal' => true,
779 946 //set context `side` for left column
780 947 'context' => 'normal',
@@ -780,13 +947,13 @@
780 947 'context' => 'normal',
781 948 'priority' => 'low',
782 949 'tabs' => array(
783 950 'thumbnails' => array(
784 - 'label' => __( 'Thumbnails', ud_get_stateless_media()->domain ),
951 + 'label' => __('Thumbnails', ud_get_stateless_media()->domain),
785 952 'icon' => 'dashicons-format-gallery',
786 953 ),
787 954 'meta' => array(
788 - 'label' => __( 'Meta', ud_get_stateless_media()->domain ),
955 + 'label' => __('Meta', ud_get_stateless_media()->domain),
789 956 'icon' => 'dashicons-admin-site',
790 957 ),
791 958 ),
792 959 // Tab style: 'default', 'box' or 'left'. Optional
@@ -793,9 +960,9 @@
793 960 'tab_style' => 'left',
794 961 // Show meta box wrapper around tabs? true (default) or false. Optional
795 962 'tab_wrapper' => true,
796 963 'fields' => $fields
797 - ), $post->ID );
964 + ), $post->ID);
798 965
799 966 return $meta_boxes;
800 967 }
801 968
@@ -807,24 +974,24 @@
807 974 * @param bool $button
808 975 * @param array $sm_cloud
809 976 * @return string
810 977 */
811 - private function _prepare_generate_link ( $post, $use_icon = false, $size = '', $button = false, $sm_cloud = array() ) {
978 + private function _prepare_generate_link($post, $use_icon = false, $size = '', $button = false, $sm_cloud = array()) {
812 979 $sync = '';
813 980
814 - $sm_mode = $this->get( 'sm.mode' );
981 + $sm_mode = $this->get('sm.mode');
815 982
816 - if ( current_user_can( 'upload_files' ) && $sm_mode !== 'disabled' && ( $sm_mode !== 'stateless' || empty($sm_cloud) ) ) {
817 - if ( $post && 'attachment' == $post->post_type && 'image/' == substr( $post->post_mime_type, 0, 6 ) ) {
818 - $sync = '<a href="javascript:;" data-type="image" data-id="'.$post->ID.'" data-size="'.$size.'" data-reload_page="'.$button.'"
819 - class="sm_inline_sync '.($button ? 'button button-primary button-large' : '').'">'. ( $use_icon ? "<i class='dashicons dashicons-image-rotate'></i>" : __( 'Regenerate and Sync with GCS', ud_get_stateless_media()->domain )).'</a>';
983 + if (current_user_can('upload_files') && $sm_mode !== 'disabled' && ($sm_mode !== 'stateless' || empty($sm_cloud))) {
984 + if ($post && 'attachment' == $post->post_type && 'image/' == substr($post->post_mime_type, 0, 6)) {
985 + $sync = '<a href="javascript:;" data-type="image" data-id="' . $post->ID . '" data-size="' . $size . '" data-reload_page="' . $button . '"
986 + class="sm_inline_sync ' . ($button ? 'button button-primary button-large' : '') . '">' . ($use_icon ? "<i class='dashicons dashicons-image-rotate'></i>" : __('Regenerate and Sync with GCS', ud_get_stateless_media()->domain)) . '</a>';
820 987 }
821 - if ( $post && 'attachment' == $post->post_type && 'image/' != substr( $post->post_mime_type, 0, 6 ) ) {
822 - $sync = '<a href="javascript:;" data-type="other" data-id="'.$post->ID.'" data-size="'.$size.'" data-reload_page="'.$button.'"
823 - class="sm_inline_sync '.($button ? 'button button-primary button-large' : '').'">'. ($use_icon ? "<i class='dashicons dashicons-image-rotate'></i>" : __( 'Sync with GCS', ud_get_stateless_media()->domain )).'</a>';
988 + if ($post && 'attachment' == $post->post_type && 'image/' != substr($post->post_mime_type, 0, 6)) {
989 + $sync = '<a href="javascript:;" data-type="other" data-id="' . $post->ID . '" data-size="' . $size . '" data-reload_page="' . $button . '"
990 + class="sm_inline_sync ' . ($button ? 'button button-primary button-large' : '') . '">' . ($use_icon ? "<i class='dashicons dashicons-image-rotate'></i>" : __('Sync with GCS', ud_get_stateless_media()->domain)) . '</a>';
824 991 }
825 - } elseif ( $button && $sm_mode !== 'stateless' ) {
826 - $sync = __('You do not have access to sync or Stateless mode is Disabled', ud_get_stateless_media()->domain );
992 + } elseif ($button && $sm_mode !== 'stateless') {
993 + $sync = __('You do not have access to sync or Stateless mode is Disabled', ud_get_stateless_media()->domain);
827 994 }
828 995 return $sync;
829 996 }
830 997
@@ -834,66 +1001,58 @@
834 1001 * 0 will be passed from various compatibilities so that the root dir is not used.
835 1002 * false will passed from some compatibilities to use the value as local path.
836 1003 * @param $attachment_id
837 1004 * @param $size
838 - * @param $use_wildcards
839 1005 * @return string
840 1006 */
841 - public function handle_root_dir( $current_path, $use_root = true, $attachment_id = '', $size = '', $use_wildcards = false ) {
842 - global $wpdb;
1007 + public function handle_root_dir($current_path, $use_root = true, $attachment_id = '', $size = '') {
1008 + //non media files
1009 + if ($use_root === 0) {
1010 + $non_media = ud_stateless_db()->get_non_library_file_name($current_path);
843 1011
844 - //for existing media
845 - $cloud_meta = get_post_meta( $attachment_id, 'sm_cloud', true );
846 -
847 - if ( !$use_wildcards && $cloud_meta ) {
848 - if ( ( !$size || $size === '__full' ) && !empty( $cloud_meta['name'] ) ) {
849 - return $cloud_meta['name'];
850 - } else {
851 - if ( !empty( $cloud_meta['sizes'] ) && isset( $cloud_meta['sizes'][$size] ) ) {
852 - return !empty( $cloud_meta['sizes'][$size]['name'] ) ? $cloud_meta['sizes'][$size]['name'] : $current_path;
853 - }
854 - }
855 - }
856 -
857 - //non media files
858 - if($use_root === 0){
859 - $table_name = $wpdb->prefix . 'sm_sync';
860 - $non_media = $wpdb->get_var($wpdb->prepare("SELECT file FROM {$table_name} WHERE file like '%%%s';", $current_path));
861 - if ( $non_media ) {
1012 + if ($non_media) {
862 1013 return $non_media;
863 1014 }
864 1015 }
865 1016
866 -
867 - $root_dir = $this->get( 'sm.root_dir' );
1017 + $root_dir = $this->get('sm.root_dir');
868 1018 $root_dir_regex = '~^' . apply_filters("wp_stateless_handle_root_dir", $root_dir, true) . '/~';
869 1019 /**
870 1020 * Retrieve Y/M and other tags from current path
871 1021 */
872 - $path_elements = apply_filters( 'wp_stateless_unhandle_root_dir', $current_path );
1022 + $path_elements = apply_filters('wp_stateless_unhandle_root_dir', $current_path);
873 1023 $root_dir = apply_filters("wp_stateless_handle_root_dir", $root_dir, false, $path_elements);
874 1024
875 1025 $upload_dir = wp_upload_dir();
876 - $current_path = str_replace( wp_normalize_path( trailingslashit( $upload_dir[ 'basedir' ] ) ), '', wp_normalize_path( $current_path ) );
877 - $current_path = str_replace( wp_normalize_path( trailingslashit( $upload_dir[ 'baseurl' ] ) ), '', wp_normalize_path( $current_path ) );
878 - $current_path = str_replace( trailingslashit( $this->get_gs_host() ), '', $current_path );
1026 + $current_path = str_replace(wp_normalize_path(trailingslashit($upload_dir['basedir'])), '', wp_normalize_path($current_path));
1027 + $current_path = str_replace(wp_normalize_path(trailingslashit($upload_dir['baseurl'])), '', wp_normalize_path($current_path));
1028 + $current_path = str_replace(trailingslashit($this->get_gs_host()), '', $current_path);
879 1029
880 1030 /**
881 1031 * Using only filename. Other parts of path included to $root_dir.
882 1032 * excluding compatibility.
883 1033 */
884 - if($use_root){
1034 + if ($use_root) {
885 1035 $current_path = basename($current_path);
886 1036 }
887 1037
888 - if(!$use_root){
889 - // removing the root dir if already exists in the begaining.
890 - return preg_replace($root_dir_regex, '', $current_path);
1038 + if (!$use_root) {
1039 + // removing the root dir if already exists in the beginning.
1040 + $raw_name = preg_replace($root_dir_regex, '', $current_path);
1041 +
1042 + if ($raw_name && is_multisite() && ($blog_id = get_current_blog_id()) != 1) {
1043 + $folder = "sites/{$blog_id}/";
1044 + if (strpos($raw_name, $folder) === 0) return $raw_name;
1045 +
1046 + return "$folder$raw_name";
1047 + }
1048 +
1049 + return $raw_name;
891 1050 }
892 1051
893 1052 // skip adding root dir if it's already added.
894 - if ( !empty( $root_dir ) && !preg_match($root_dir_regex, $current_path) ) {
895 - return $root_dir . '/' . trim( $current_path, '/ ' );
1053 + if (!empty($root_dir) && !preg_match($root_dir_regex, $current_path)) {
1054 + return $root_dir . '/' . trim($current_path, '/ ');
896 1055 }
897 1056
898 1057 return $current_path;
899 1058 }
@@ -901,22 +1060,25 @@
901 1060 /**
902 1061 * @param $content
903 1062 * @return mixed
904 1063 */
905 - public function the_content_filter( $content ) {
1064 + public function the_content_filter($content) {
906 1065
907 - if ( $upload_data = wp_upload_dir() ) {
1066 + if ($upload_data = wp_upload_dir()) {
908 1067
909 - if ( !empty( $upload_data['url'] ) && !empty( $content ) ) {
910 - $url = preg_replace('/https?:\/\//','',$upload_data['url']);
1068 + if (!empty($upload_data['url']) && !empty($content)) {
1069 + $url = preg_replace('/https?:\/\//', '', $upload_data['url']);
911 1070
912 - $root_dir = trim( $this->get( 'sm.root_dir' ), '/ ' ); // Remove any forward slash and empty space.
1071 + $root_dir = trim($this->get('sm.root_dir'), '/ '); // Remove any forward slash and empty space.
913 1072 $root_dir = apply_filters("wp_stateless_handle_root_dir", $root_dir);
914 - $root_dir = !empty( $root_dir ) ? $root_dir . '/' : false;
1073 + $root_dir = !empty($root_dir) ? $root_dir . '/' : false;
915 1074 $image_host = $this->get_gs_host();
916 1075 $file_ext = $this->replaceable_file_types();
917 - $content = preg_replace( '/(href|src)=(\'|")(https?:\/\/'.str_replace('/', '\/', $url).')\/(.+?)('.$file_ext.')(\'|")/i',
918 - '$1=$2'.$image_host.'/'.($root_dir?$root_dir:'').'$4$5$6', $content);
1076 + $content = preg_replace(
1077 + '/(href|src)=(\'|")(https?:\/\/' . str_replace('/', '\/', $url) . ')\/(.+?)(' . $file_ext . ')(\'|")/i',
1078 + '$1=$2' . $image_host . '/' . ($root_dir ? $root_dir : '') . '$4$5$6',
1079 + $content
1080 + );
919 1081 }
920 1082 }
921 1083
922 1084 return $content;
@@ -925,9 +1087,9 @@
925 1087 /**
926 1088 * Return file types supported by File URL Replacement.
927 1089 * @return string
928 1090 */
929 - public function replaceable_file_types(){
1091 + public function replaceable_file_types() {
930 1092 $types = $this->get('sm.body_rewrite_types');
931 1093
932 1094 // Removing extra space.
933 1095 $types = trim($types);
@@ -945,23 +1107,23 @@
945 1107 * @param $meta_key
946 1108 * @param $single
947 1109 * @return mixed
948 1110 */
949 - public function post_metadata_filter($value, $object_id, $meta_key, $single){
950 - if(empty($value)){
1111 + public function post_metadata_filter($value, $object_id, $meta_key, $single) {
1112 + if (empty($value)) {
951 1113 $meta_type = 'post';
952 1114 $transient_key = "stateless_{$meta_type}_meta";
953 1115
954 1116 $meta_cache = wp_cache_get($object_id, $transient_key);
955 - if(empty($meta_cache)){
1117 + if (empty($meta_cache)) {
956 1118 $meta_cache = wp_cache_get($object_id, $meta_type . '_meta');
957 1119
958 - if ( !$meta_cache ) {
959 - $meta_cache = update_meta_cache( $meta_type, array( $object_id ) );
1120 + if (!$meta_cache) {
1121 + $meta_cache = update_meta_cache($meta_type, array($object_id));
960 1122 $meta_cache = $meta_cache[$object_id];
961 1123 }
962 1124
963 - foreach($meta_cache as $key => $meta){
1125 + foreach ($meta_cache as $key => $meta) {
964 1126 $meta_cache[$key] = array_map('maybe_unserialize', $meta_cache[$key]);
965 1127 }
966 1128
967 1129 $meta_cache = $this->convert_to_gs_link($meta_cache);
@@ -967,13 +1129,13 @@
967 1129 $meta_cache = $this->convert_to_gs_link($meta_cache);
968 1130 wp_cache_set($object_id, $meta_cache, $transient_key);
969 1131 }
970 1132
971 - if ( ! $meta_key ) {
1133 + if (!$meta_key) {
972 1134 return $meta_cache;
973 1135 }
974 1136
975 - if ( isset($meta_cache[$meta_key]) ) {
1137 + if (isset($meta_cache[$meta_key])) {
976 1138 return $meta_cache[$meta_key];
977 1139 }
978 1140
979 1141 // in case no metadata is found return what was passed in $value.
@@ -981,9 +1143,8 @@
981 1143 return $value;
982 1144 }
983 1145
984 1146 return $this->convert_to_gs_link($value);
985 -
986 1147 }
987 1148
988 1149 /**
989 1150 * Replace all image link with gs link and return only if meta modified.
@@ -991,23 +1152,23 @@
991 1152 * @param $meta
992 1153 * @param $return
993 1154 * @return mixed or null when not changed.
994 1155 */
995 - public function convert_to_gs_link($meta, $return = false){
1156 + public function convert_to_gs_link($meta, $return = false) {
996 1157 $updated = $meta;
997 - if ( $meta && $upload_data = wp_upload_dir() ) {
998 - if ( !empty( $upload_data['url'] ) && !empty( $meta ) ) {
999 - $url = preg_replace('/https?:\/\//','',$upload_data['url']);
1000 - $root_dir = trim( $this->get( 'sm.root_dir' ), '/ ' ); // Remove any forward slash and empty space.
1158 + if ($meta && $upload_data = wp_upload_dir()) {
1159 + if (!empty($upload_data['url']) && !empty($meta)) {
1160 + $url = preg_replace('/https?:\/\//', '', $upload_data['url']);
1161 + $root_dir = trim($this->get('sm.root_dir'), '/ '); // Remove any forward slash and empty space.
1001 1162 $root_dir = apply_filters("wp_stateless_handle_root_dir", $root_dir);
1002 - $root_dir = !empty( $root_dir ) ? $root_dir . '/': false;
1003 - $image_host = $this->get_gs_host().'/'.($root_dir?$root_dir:'');
1163 + $root_dir = !empty($root_dir) ? $root_dir . '/' : false;
1164 + $image_host = $this->get_gs_host() . '/' . ($root_dir ? $root_dir : '');
1004 1165 $file_ext = $this->replaceable_file_types();
1005 1166 $updated = $this->_convert_to_gs_link($meta, $image_host, $url, $file_ext);
1006 1167 }
1007 1168 }
1008 1169
1009 - if($updated == $meta && !$return){
1170 + if ($updated == $meta && !$return) {
1010 1171 return null; // Not changed.
1011 1172 }
1012 1173 return $updated;
1013 1174 }
@@ -1020,21 +1181,21 @@
1020 1181 * @param $url
1021 1182 * @param $file_ext
1022 1183 * @return array|null|string|string[]
1023 1184 */
1024 - public function _convert_to_gs_link($meta, $image_host, $url, $file_ext){
1025 - if(is_array($meta)){
1185 + public function _convert_to_gs_link($meta, $image_host, $url, $file_ext) {
1186 + if (is_array($meta)) {
1026 1187 foreach ($meta as $key => $value) {
1027 1188 $meta[$key] = $this->_convert_to_gs_link($value, $image_host, $url, $file_ext);
1028 1189 }
1029 1190 return $meta;
1030 - } elseif (is_object($meta) && $meta instanceof \stdClass ) {
1191 + } elseif (is_object($meta) && $meta instanceof \stdClass) {
1031 1192 foreach (get_object_vars($meta) as $key => $value) {
1032 1193 $meta->{$key} = $this->_convert_to_gs_link($value, $image_host, $url, $file_ext);
1033 1194 }
1034 1195 return $meta;
1035 - } elseif(is_string($meta)){
1036 - return preg_replace( '/(https?:\/\/'.str_replace('/', '\/', $url).')\/(.+?)(' . $file_ext . ')/i', $image_host.'$2$3', $meta);
1196 + } elseif (is_string($meta)) {
1197 + return preg_replace('/(https?:\/\/' . str_replace('/', '\/', $url) . ')\/(.+?)(' . $file_ext . ')/i', $image_host . '$2$3', $meta);
1037 1198 }
1038 1199
1039 1200 return $meta;
1040 1201 }
@@ -1039,28 +1200,8 @@
1039 1200 return $meta;
1040 1201 }
1041 1202
1042 1203 /**
1043 - * @param $links
1044 - * @param $file
1045 - * @return mixed
1046 - */
1047 - public function plugin_action_links( $links, $file ) {
1048 -
1049 - if ($file == plugin_basename( dirname( __DIR__ ) . '/wp-stateless-media.php' ) ) {
1050 - $settings_link = '<a href="'. '' .'">'.__( 'Settings' , 'ssd').'</a>';
1051 - array_unshift( $links, $settings_link );
1052 - }
1053 -
1054 - if ($file == plugin_basename( dirname( __DIR__ ) . '/wp-stateless.php' ) ) {
1055 - $settings_link = '<a href="'. '' .'">'.__( 'Settings' , 'ssd').'</a>';
1056 - array_unshift( $links, $settings_link );
1057 - }
1058 -
1059 - return $links;
1060 - }
1061 -
1062 - /**
1063 1204 * Determines if plugin is loaded via mu-plugins
1064 1205 * or Network Enabled.
1065 1206 *
1066 1207 * @param bool $is_multisite
@@ -1069,20 +1210,20 @@
1069 1210 */
1070 1211 public function is_network_detected($is_multisite = false) {
1071 1212 /* Plugin is loaded via mu-plugins. */
1072 1213
1073 - if( strpos( Utility::normalize_path( $this->root_path ), Utility::normalize_path( WPMU_PLUGIN_DIR ) ) !== false ) {
1214 + if (strpos(Utility::normalize_path($this->root_path), Utility::normalize_path(WPMU_PLUGIN_DIR)) !== false) {
1074 1215 return true;
1075 1216 }
1076 1217
1077 - if( is_multisite() ) {
1078 - if($is_multisite) return true;
1218 + if (is_multisite()) {
1219 + if ($is_multisite) return true;
1079 1220 /* Looks through network enabled plugins to see if our one is there. */
1080 1221 foreach (wp_get_active_network_plugins() as $path) {
1081 1222 // Trying again using readlink in case it's a symlink file.
1082 1223 // boot_file is already solved.
1083 1224 // wp_normalize_path is helpfull in windows.
1084 - if (wp_normalize_path($this->boot_file) == wp_normalize_path($path) || (is_link($path) AND $this->boot_file == readlink($path))) {
1225 + if (wp_normalize_path($this->boot_file) == wp_normalize_path($path) || (is_link($path) && $this->boot_file == readlink($path))) {
1085 1226 return true;
1086 1227 }
1087 1228 }
1088 1229 }
@@ -1094,43 +1235,47 @@
1094 1235 * Register scripts and styles
1095 1236 */
1096 1237 public function admin_init() {
1097 1238 $this->show_notice_stateless_cache_busting();
1098 - wp_register_style( 'wp-stateless', $this->path( 'static/styles/wp-stateless.css', 'url' ), array(), self::$version );
1239 + wp_register_style('wp-stateless', $this->path('static/styles/wp-stateless.css', 'url'), array(), self::$version);
1099 1240
1100 1241 /**
1101 1242 * select2 styles
1102 1243 */
1103 - wp_register_style( 'wp-stateless-select2', $this->path( 'static/styles/select2.min.css', 'url' ), array(), self::$version );
1244 + wp_register_style('wp-stateless-select2', $this->path('static/styles/select2.min.css', 'url'), array(), self::$version);
1104 1245
1105 1246 /* Attachment or upload page */
1106 - wp_register_script( 'wp-stateless-uploads-js', $this->path( 'static/scripts/wp-stateless-uploads.js', 'url' ), array( 'jquery' ), self::$version );
1247 + wp_register_script('wp-stateless-uploads-js', $this->path('static/scripts/wp-stateless-uploads.js', 'url'), array('jquery'), self::$version);
1248 + wp_localize_script('wp-stateless-uploads-js', 'stateless_upload', [
1249 + 'inline_sync_nonce' => wp_create_nonce('sm_inline_sync'),
1250 + ]);
1107 1251
1108 1252 /* Setup wizard styles. */
1109 - wp_register_style( 'wp-stateless-setup-wizard', $this->path( 'static/styles/wp-stateless-setup-wizard.css', 'url' ), array(), self::$version );
1253 + // #152
1254 + // wp_register_style('wp-stateless-setup-wizard', $this->path('static/styles/wp-stateless-setup-wizard.css', 'url'), array(), self::$version);
1110 1255
1111 - wp_register_script( 'wp-stateless-select2', ud_get_stateless_media()->path( 'static/scripts/select2.min.js', 'url' ), array( 'jquery' ), self::$version, true );
1256 + wp_register_script('wp-stateless-select2', ud_get_stateless_media()->path('static/scripts/select2.min.js', 'url'), array('jquery'), self::$version, true);
1112 1257
1113 1258 /* Stateless settings page */
1114 - wp_register_script( 'wp-stateless-settings', ud_get_stateless_media()->path( 'static/scripts/wp-stateless-settings.js', 'url' ), array(), self::$version );
1115 - wp_localize_script( 'wp-stateless-settings', 'stateless_l10n', $this->get_l10n_data() );
1259 + wp_register_script('wp-stateless-settings', ud_get_stateless_media()->path('static/scripts/wp-stateless-settings.js', 'url'), array('clipboard'), self::$version);
1260 + wp_localize_script('wp-stateless-settings', 'stateless_l10n', $this->get_l10n_data());
1116 1261
1117 - wp_register_style( 'wp-stateless-settings', $this->path( 'static/styles/wp-stateless-settings.css', 'url' ), array(), self::$version );
1262 + wp_register_style('wp-stateless-settings', $this->path('static/styles/wp-stateless-settings.css', 'url'), array(), self::$version);
1263 + wp_register_style('wp-stateless-addons', $this->path('static/styles/wp-stateless-addons.css', 'url'), array(), self::$version);
1264 + wp_register_style('wp-stateless-status', $this->path('static/styles/wp-stateless-status.css', 'url'), array(), self::$version);
1118 1265
1119 1266 // Sync tab
1120 - if ( wp_script_is( 'jquery-ui-widget', 'registered' ) ){
1121 - wp_register_script( 'jquery-ui-progressbar', ud_get_stateless_media()->path('static/scripts/jquery-ui/jquery.ui.progressbar.min.js', 'url'), array( 'jquery-ui-core', 'jquery-ui-widget' ), '1.8.6' );
1122 - }
1123 - else{
1124 - wp_register_script( 'jquery-ui-progressbar', ud_get_stateless_media()->path( 'static/scripts/jquery-ui/jquery.ui.progressbar.min.1.7.2.js', 'url' ), array( 'jquery-ui-core' ), '1.7.2' );
1125 - }
1126 - wp_register_script( 'wp-stateless-angular', ud_get_stateless_media()->path( 'static/scripts/angular.min.js', 'url' ), array(), '1.5.0', true );
1127 - wp_register_script( 'wp-stateless-angular-sanitize', ud_get_stateless_media()->path( 'static/scripts/angular-sanitize.min.js', 'url' ), array('wp-stateless-angular'), '1.5.0', true );
1128 - wp_register_script( 'wp-stateless', ud_get_stateless_media()->path( 'static/scripts/wp-stateless.js', 'url' ), array( 'jquery-ui-core', 'wp-stateless-settings' ), self::$version, true );
1267 + wp_register_script('wp-stateless', ud_get_stateless_media()->path('static/scripts/wp-stateless.js', 'url'), array('jquery-ui-core', 'wp-stateless-settings', 'wp-api-request'), self::$version, true);
1129 1268
1130 - wp_localize_script( 'wp-stateless', 'stateless_l10n', $this->get_l10n_data() );
1269 + wp_localize_script('wp-stateless', 'stateless_l10n', $this->get_l10n_data());
1131 1270 wp_localize_script('wp-stateless', 'wp_stateless_configs', array(
1132 1271 'WP_DEBUG' => defined('WP_DEBUG') ? WP_DEBUG : false,
1272 + 'REST_API_TOKEN' => Utility::generate_jwt_token(['user_id' => get_current_user_id()], DAY_IN_SECONDS),
1273 + 'api_root' => apply_filters( 'wp_stateless_rest_api_root', '' ),
1274 + 'ajaxurl' => admin_url( 'admin-ajax.php' ),
1275 + 'stateless_check_ajax_nonce' => wp_create_nonce('stateless_check_ajax'),
1276 + 'text_ok' => __('Ok', ud_get_stateless_media()->domain),
1277 + 'text_fail' => __('Fail', ud_get_stateless_media()->domain),
1133 1278 ));
1134 1279
1135 1280 $settings = ud_get_stateless_media()->get('sm');
1136 1281 $settings['wildcards'] = $this->settings->wildcards;
@@ -1135,15 +1280,20 @@
1135 1280 $settings = ud_get_stateless_media()->get('sm');
1136 1281 $settings['wildcards'] = $this->settings->wildcards;
1137 1282 $settings['network_admin'] = is_network_admin();
1138 1283 $settings['is_multisite'] = is_multisite();
1139 - if(defined('WP_STATELESS_MEDIA_JSON_KEY') && WP_STATELESS_MEDIA_JSON_KEY){
1284 + if (defined('WP_STATELESS_MEDIA_JSON_KEY') && WP_STATELESS_MEDIA_JSON_KEY) {
1140 1285 $settings['key_json'] = "Currently configured via a constant.";
1141 1286 }
1142 1287 wp_localize_script('wp-stateless', 'wp_stateless_settings', $settings);
1143 - wp_localize_script('wp-stateless', 'wp_stateless_compatibility', Module::get_modules());
1144 - wp_register_style( 'jquery-ui-regenthumbs', ud_get_stateless_media()->path( 'static/scripts/jquery-ui/redmond/jquery-ui-1.7.2.custom.css', 'url' ), array(), '1.7.2' );
1145 1288
1289 + // Batch processes tab
1290 + wp_register_script('wp-stateless-batch', ud_get_stateless_media()->path('static/scripts/wp-stateless-batch.js', 'url'), array('wp-api-request'), self::$version, true);
1291 + wp_localize_script('wp-stateless-batch', 'wp_stateless_batch', array(
1292 + 'REST_API_TOKEN' => Utility::generate_jwt_token(['user_id' => get_current_user_id()], DAY_IN_SECONDS),
1293 + 'is_running' => BatchTaskManager::instance()->is_running(),
1294 + 'api_root' => apply_filters( 'wp_stateless_rest_api_root', '' ),
1295 + ));
1146 1296 }
1147 1297
1148 1298 /**
1149 1299 * Get_l10n_data
@@ -1150,10 +1300,10 @@
1150 1300 *
1151 1301 * @param string $value
1152 1302 * @return mixed
1153 1303 */
1154 - public function get_l10n_data($value=''){
1155 - include ud_get_stateless_media()->path( 'l10n.php', 'dir');
1304 + public function get_l10n_data($value = '') {
1305 + include ud_get_stateless_media()->path('l10n.php', 'dir');
1156 1306 return $l10n;
1157 1307 }
1158 1308
1159 1309 /**
@@ -1160,19 +1310,19 @@
1160 1310 * Admin Scripts
1161 1311 *
1162 1312 * @param $hook
1163 1313 */
1164 - public function admin_enqueue_scripts( $hook ) {
1314 + public function admin_enqueue_scripts($hook) {
1165 1315
1166 - switch( $hook ) {
1316 + switch ($hook) {
1167 1317
1168 1318 case 'options-media.php':
1169 - wp_enqueue_style( 'wp-stateless');
1319 + wp_enqueue_style('wp-stateless');
1170 1320 break;
1171 1321
1172 1322 case 'upload.php':
1173 - wp_enqueue_style( 'wp-stateless');
1174 - wp_enqueue_script( 'wp-stateless-uploads-js' );
1323 + wp_enqueue_style('wp-stateless');
1324 + wp_enqueue_script('wp-stateless-uploads-js');
1175 1325
1176 1326 break;
1177 1327
1178 1328 case 'post.php':
@@ -1178,51 +1328,60 @@
1178 1328 case 'post.php':
1179 1329
1180 1330 global $post;
1181 1331
1182 - if ( $post->post_type == 'attachment' ) {
1183 - wp_enqueue_style( 'wp-stateless');
1184 - wp_enqueue_script( 'wp-stateless-uploads-js' );
1332 + if ($post->post_type == 'attachment') {
1333 + wp_enqueue_style('wp-stateless');
1334 + wp_enqueue_script('wp-stateless-uploads-js');
1185 1335 }
1186 1336
1187 1337 break;
1188 1338
1189 - case 'media_page_stateless-setup':
1339 + // #152
1340 + // case 'media_page_stateless-setup':
1190 1341 case 'settings_page_stateless-setup':
1191 - wp_enqueue_style( 'wp-stateless');
1192 - wp_enqueue_style( 'wp-stateless-setup-wizard' );
1342 + wp_enqueue_style('wp-stateless');
1343 + // #152
1344 + // wp_enqueue_style('wp-stateless-setup-wizard');
1193 1345 break;
1194 1346 case 'media_page_stateless-settings':
1195 1347 case 'settings_page_stateless-settings':
1196 - wp_enqueue_style( 'wp-stateless');
1197 - wp_enqueue_style( 'wp-stateless-select2');
1198 - wp_enqueue_script( 'wp-stateless-settings' );
1199 - wp_enqueue_script( 'wp-stateless-select2' );
1200 - wp_enqueue_style( 'wp-stateless-settings' );
1348 + wp_enqueue_style('wp-stateless');
1349 + wp_enqueue_style('wp-stateless-select2');
1350 + wp_enqueue_script('wp-stateless-settings');
1351 + wp_enqueue_script('wp-stateless-select2');
1352 + wp_enqueue_style('wp-stateless-settings');
1353 + wp_enqueue_style('wp-stateless-addons');
1354 + wp_enqueue_style('wp-stateless-status');
1355 + wp_enqueue_style( 'media-views' );
1201 1356
1202 1357 // Sync tab
1203 - wp_enqueue_script( 'jquery-ui-progressbar' );
1204 - wp_enqueue_script( 'wp-stateless-angular' );
1205 - wp_enqueue_script( 'wp-stateless-angular-sanitize' );
1206 - wp_enqueue_script( 'wp-stateless' );
1207 - wp_enqueue_style( 'jquery-ui-regenthumbs' );
1358 + wp_enqueue_script('wp-stateless');
1208 1359
1360 + // Data updates
1361 + wp_enqueue_script('jquery-ui-dialog');
1362 + wp_enqueue_style('wp-jquery-ui-dialog');
1363 + wp_enqueue_script('wp-stateless-batch');
1364 +
1365 + wp_enqueue_style('wp-pointer');
1366 + wp_enqueue_script('wp-pointer');
1367 +
1209 1368 $data = array(
1210 1369 'key' => 'stateless-cache-busting',
1211 1370 'class' => 'notice',
1212 - 'title' => sprintf( __( "Stateless and Ephemeral modes enables and requires the Cache-Busting option.", ud_get_stateless_media()->domain ) ),
1213 - 'message' => sprintf( __("WordPress looks at local files to prevent files with the same filenames.
1214 - Since Stateless mode bypasses this check, there is a potential for files to be stored with the same file name. We enforce the Cache-Busting option to prevent this.
1215 - Override with the <a href='%s' target='_blank'>%s</a> constant.", ud_get_stateless_media()->domain),"https://wp-stateless.github.io/docs/constants/#wp_stateless_media_cache_busting", "WP_STATELESS_MEDIA_CACHE_BUSTING" ),
1371 + 'title' => sprintf(__("Stateless and Ephemeral modes enables and requires the Cache-Busting option.", ud_get_stateless_media()->domain)),
1372 + 'message' => sprintf(__("WordPress looks at local files to prevent files with the same filenames.
1373 + Since Stateless mode bypasses this check, there is a potential for files to be stored with the same file name. We enforce the Cache-Busting option to prevent this.
1374 + Override with the <a href='%s' target='_blank'>%s</a> constant.", ud_get_stateless_media()->domain), ud_get_stateless_media()->get_docs_page_url('docs/constants/#wpstatelessmediacachebusting'), "WP_STATELESS_MEDIA_CACHE_BUSTING"),
1216 1375 );
1217 1376 echo "<script id='template-stateless-cache-busting' type='text/html'>";
1218 - include ud_get_stateless_media()->path( '/static/views/error-notice.php', 'dir' );
1377 + include ud_get_stateless_media()->path('/static/views/error-notice.php', 'dir');
1219 1378 echo "</script>";
1220 1379
1221 1380 break;
1222 - default: break;
1381 + default:
1382 + break;
1223 1383 }
1224 -
1225 1384 }
1226 1385
1227 1386 /**
1228 1387 * Add Attributes to media HTML
@@ -1232,20 +1391,19 @@
1232 1391 * @param $attachment
1233 1392 * @param $size
1234 1393 * @return mixed
1235 1394 */
1236 - public function wp_get_attachment_image_attributes( $attr, $attachment, $size = null ) {
1237 -
1238 - $sm_cloud = get_post_meta( $attachment->ID, 'sm_cloud', true );
1239 - if( is_array( $sm_cloud ) && !empty( $sm_cloud[ 'name' ] ) ) {
1240 - $attr[ 'class' ] = $attr[ 'class' ] . ' wp-stateless-item';
1241 - $attr[ 'data-image-size' ] = is_array( $size ) ? implode( 'x', $size ) : $size;
1242 - $attr[ 'data-stateless-media-bucket' ] = isset( $sm_cloud[ 'bucket' ] ) ? $sm_cloud[ 'bucket' ] : false;
1243 - $attr[ 'data-stateless-media-name' ] = $sm_cloud[ 'name' ];
1395 + public function wp_get_attachment_image_attributes($attr, $attachment, $size = null) {
1396 +
1397 + $sm_cloud = apply_filters('wp_stateless_get_file', [], $attachment->ID);
1398 + if (is_array($sm_cloud) && !empty($sm_cloud['name'])) {
1399 + $attr['class'] = $attr['class'] . ' wp-stateless-item';
1400 + $attr['data-image-size'] = is_array($size) ? implode('x', $size) : $size;
1401 + $attr['data-stateless-media-bucket'] = isset($sm_cloud['bucket']) ? $sm_cloud['bucket'] : false;
1402 + $attr['data-stateless-media-name'] = $sm_cloud['name'];
1244 1403 }
1245 1404
1246 1405 return $attr;
1247 -
1248 1406 }
1249 1407
1250 1408 /**
1251 1409 * Adds filter link to Media Library table.
@@ -1252,10 +1410,10 @@
1252 1410 *
1253 1411 * @param $views
1254 1412 * @return mixed
1255 1413 */
1256 - public function views_upload( $views ) {
1257 - $views['stateless'] = '<a href="#">' . __( 'Stateless Media' ) . '</a>';
1414 + public function views_upload($views) {
1415 + $views['stateless'] = '<a href="#">' . __('Stateless Media') . '</a>';
1258 1416 return $views;
1259 1417 }
1260 1418
1261 1419 /**
@@ -1265,11 +1423,11 @@
1265 1423 * @param integer $id
1266 1424 * @param string $size
1267 1425 * @return mixed $false
1268 1426 */
1269 - public function image_downsize( $false = false, $id, $size ) {
1427 + public function image_downsize($false, $id, $size) {
1270 1428
1271 - if ( (!isset( $this->client ) || !$this->client || is_wp_error( $this->client )) && $this->get( 'sm.mode' ) !== 'stateless' ) {
1429 + if ((!isset($this->client) || !$this->client || is_wp_error($this->client)) && $this->get('sm.mode') !== 'stateless') {
1272 1430 return $false;
1273 1431 }
1274 1432
1275 1433 /**
@@ -1274,9 +1432,9 @@
1274 1432
1275 1433 /**
1276 1434 * Check if enabled
1277 1435 */
1278 - if ( !in_array( $this->get( 'sm.mode' ), array( 'cdn', 'stateless', 'ephemeral' ) )) {
1436 + if (!in_array($this->get('sm.mode'), array('cdn', 'stateless', 'ephemeral'))) {
1279 1437 return $false;
1280 1438 }
1281 1439
1282 1440 /** Start determine remote file */
@@ -1285,16 +1443,14 @@
1285 1443 $width = $height = 0;
1286 1444 $is_intermediate = false;
1287 1445
1288 1446 //** try for a new style intermediate size */
1289 - if ( $intermediate = image_get_intermediate_size( $id, $size ) ) {
1290 - if(!empty( $intermediate['gs_link'] )){
1447 + if ($intermediate = image_get_intermediate_size($id, $size)) {
1448 + if (!empty($intermediate['gs_link'])) {
1291 1449 $img_url = $intermediate['gs_link'];
1292 - }
1293 - else if(!empty( $intermediate['url'] )){
1450 + } else if (!empty($intermediate['url'])) {
1294 1451 $img_url = $intermediate['url'];
1295 - }
1296 - else{
1452 + } else {
1297 1453 $img_url = dirname($img_url) . $intermediate['file'];
1298 1454 }
1299 1455
1300 1456 $width = $intermediate['width'];
@@ -1306,18 +1462,18 @@
1306 1462 * maybe try to get images info from sm_cloud
1307 1463 * this case may happen when no local files
1308 1464 * @author korotkov@ud
1309 1465 */
1310 - if ( !$width && !$height ) {
1311 - $sm_cloud = get_post_meta( $id, 'sm_cloud', true );
1312 - if ( is_string($size) && !empty( $sm_cloud['sizes'] ) && !empty( $sm_cloud['sizes'][$size] ) ) {
1466 + if (!$width && !$height) {
1467 + $sm_cloud = apply_filters('wp_stateless_get_file', [], $id, true);
1468 + if (is_string($size) && !empty($sm_cloud['sizes']) && !empty($sm_cloud['sizes'][$size])) {
1313 1469 global $_wp_additional_image_sizes;
1314 1470
1315 - $img_url = !empty( $sm_cloud['sizes'][$size]['fileLink'] ) ? $sm_cloud['sizes'][$size]['fileLink'] : $img_url;
1471 + $img_url = !empty($sm_cloud['sizes'][$size]['fileLink']) ? $sm_cloud['sizes'][$size]['fileLink'] : $img_url;
1316 1472
1317 - if ( !empty( $_wp_additional_image_sizes[ $size ] ) ) {
1318 - $width = !empty( $_wp_additional_image_sizes[ $size ]['width'] ) ? $_wp_additional_image_sizes[ $size ]['width'] : $width;
1319 - $height = !empty( $_wp_additional_image_sizes[ $size ]['height'] ) ? $_wp_additional_image_sizes[ $size ]['height'] : $height;
1473 + if (!empty($_wp_additional_image_sizes[$size])) {
1474 + $width = !empty($_wp_additional_image_sizes[$size]['width']) ? $_wp_additional_image_sizes[$size]['width'] : $width;
1475 + $height = !empty($_wp_additional_image_sizes[$size]['height']) ? $_wp_additional_image_sizes[$size]['height'] : $height;
1320 1476 }
1321 1477
1322 1478 $is_intermediate = true;
1323 1479 }
@@ -1322,9 +1478,9 @@
1322 1478 $is_intermediate = true;
1323 1479 }
1324 1480 }
1325 1481
1326 - if ( !$width && !$height && isset( $meta['width'], $meta['height'] ) ) {
1482 + if (!$width && !$height && isset($meta['width'], $meta['height'])) {
1327 1483
1328 1484 //** any other type: use the real image */
1329 1485 $width = $meta['width'];
1330 1486 $height = $meta['height'];
@@ -1330,14 +1486,14 @@
1330 1486 $height = $meta['height'];
1331 1487 }
1332 1488
1333 1489
1334 - if ( $img_url) {
1490 + if ($img_url) {
1335 1491
1336 1492 //** we have the actual image size, but might need to further constrain it if content_width is narrower */
1337 - list( $width, $height ) = image_constrain_size_for_editor( $width, $height, $size );
1493 + list($width, $height) = image_constrain_size_for_editor($width, $height, $size);
1338 1494 $img_url = apply_filters('wp_stateless_bucket_link', $img_url);
1339 - return array( $img_url, $width, $height, $is_intermediate );
1495 + return array($img_url, $width, $height, $is_intermediate);
1340 1496 }
1341 1497
1342 1498
1343 1499 /**
@@ -1343,9 +1499,8 @@
1343 1499 /**
1344 1500 * All other cases work as usually
1345 1501 */
1346 1502 return $false;
1347 -
1348 1503 }
1349 1504
1350 1505 /**
1351 1506 * Extends metadata by adding GS information.
@@ -1354,61 +1509,61 @@
1354 1509 * @param $metadata
1355 1510 * @param $attachment_id
1356 1511 * @return array|mixed
1357 1512 */
1358 - public function wp_get_attachment_metadata( $metadata, $attachment_id ) {
1513 + public function wp_get_attachment_metadata($metadata, $attachment_id) {
1359 1514 global $default_dir;
1360 1515 $default_dir = false;
1361 1516 /* Determine if the media file has GS data at all. */
1362 - $sm_cloud = get_post_meta( $attachment_id, 'sm_cloud', true );
1517 + $sm_cloud = apply_filters('wp_stateless_get_file', [], $attachment_id, true);
1363 1518 // If metadata not passed the get metadata from post meta.
1364 - if(empty($metadata)){
1365 - $metadata = get_post_meta( $attachment_id, '_wp_attachment_metadata', true );
1519 + if (empty($metadata)) {
1520 + $metadata = get_post_meta($attachment_id, '_wp_attachment_metadata', true);
1366 1521 }
1367 1522
1368 - if(empty($metadata)){
1523 + if (empty($metadata)) {
1369 1524 $metadata = [];
1370 1525 }
1371 1526
1372 - if( is_array( $metadata ) && is_array( $sm_cloud ) && !empty( $sm_cloud[ 'fileLink' ] ) ) {
1373 - $metadata[ 'gs_link' ] = apply_filters('wp_stateless_bucket_link', $sm_cloud[ 'fileLink' ]);
1374 - $metadata[ 'gs_name' ] = isset( $sm_cloud[ 'name' ] ) ? $sm_cloud[ 'name' ] : false;
1375 - $metadata[ 'gs_bucket' ] = isset( $sm_cloud[ 'bucket' ] ) ? $sm_cloud[ 'bucket' ] : false;
1376 - if( !empty( $metadata[ 'sizes' ] ) && is_array( $metadata[ 'sizes' ] ) ) {
1377 - foreach( $metadata[ 'sizes' ] as $k => $v ) {
1378 - if( !empty( $sm_cloud[ 'sizes' ][ $k ][ 'name' ] ) ) {
1379 - $metadata['sizes'][$k]['gs_name'] = $sm_cloud[ 'sizes' ][ $k ][ 'name' ];
1380 - $metadata['sizes'][$k]['gs_link'] = apply_filters('wp_stateless_bucket_link', $sm_cloud[ 'sizes' ][ $k ][ 'fileLink' ]);
1527 + if (is_array($metadata) && is_array($sm_cloud) && !empty($sm_cloud['fileLink'])) {
1528 + $metadata['gs_link'] = apply_filters('wp_stateless_bucket_link', $sm_cloud['fileLink']);
1529 + $metadata['gs_name'] = isset($sm_cloud['name']) ? $sm_cloud['name'] : false;
1530 + $metadata['gs_bucket'] = isset($sm_cloud['bucket']) ? $sm_cloud['bucket'] : false;
1531 + if (!empty($metadata['sizes']) && is_array($metadata['sizes'])) {
1532 + foreach ($metadata['sizes'] as $k => $v) {
1533 + if (!empty($sm_cloud['sizes'][$k]['name'])) {
1534 + $metadata['sizes'][$k]['gs_name'] = $sm_cloud['sizes'][$k]['name'];
1535 + $metadata['sizes'][$k]['gs_link'] = apply_filters('wp_stateless_bucket_link', $sm_cloud['sizes'][$k]['fileLink']);
1381 1536 }
1382 1537 }
1383 1538 }
1384 1539 }
1385 - if(is_multisite() && !empty($metadata['file'])){
1386 - if ( $this->get('sm.mode') == 'stateless' ) {
1540 + if (is_multisite() && !empty($metadata['file'])) {
1541 + if ($this->get('sm.mode') == 'stateless') {
1387 1542 $default_dir = true;
1388 1543 $uploads = wp_get_upload_dir();
1389 1544 $default_dir = false;
1390 1545
1391 1546 $file_path_fix = $uploads['basedir'] . "/{$metadata['file']}";
1392 - if(file_exists($file_path_fix)) {
1393 - $metadata[ 'file' ] = "{$metadata['file']}";
1547 + if (file_exists($file_path_fix)) {
1548 + $metadata['file'] = "{$metadata['file']}";
1394 1549 }
1395 1550 } else {
1396 1551 $uploads = wp_get_upload_dir();
1397 1552 $blog_id = get_current_blog_id();
1398 - $file_path_fix = $uploads[ 'basedir' ] . "/sites/$blog_id/{$metadata['file']}";
1399 - if( file_exists( $file_path_fix ) ) {
1400 - $metadata[ 'file' ] = "sites/$blog_id/{$metadata['file']}";
1553 + $file_path_fix = $uploads['basedir'] . "/sites/$blog_id/{$metadata['file']}";
1554 + if (file_exists($file_path_fix)) {
1555 + $metadata['file'] = "sites/$blog_id/{$metadata['file']}";
1401 1556 }
1402 1557 }
1403 - } elseif ( empty($sm_cloud) && $this->get('sm.mode') == 'stateless' ) {
1558 + } elseif ( empty($sm_cloud) && $this->get('sm.mode') == 'stateless' && isset($metadata['file']) ) {
1404 1559 $default_dir = true;
1405 1560 $uploads = wp_get_upload_dir();
1406 1561 $default_dir = false;
1407 1562
1408 1563 $file_path_fix = $uploads['basedir'] . "/{$metadata['file']}";
1409 - if(file_exists($file_path_fix)) {
1410 - $metadata[ 'file' ] = "{$metadata['file']}";
1564 + if (file_exists($file_path_fix)) {
1565 + $metadata['file'] = "{$metadata['file']}";
1411 1566 }
1412 1567 }
1413 1568
1414 1569 return $metadata;
@@ -1419,33 +1574,31 @@
1419 1574 * @param $file
1420 1575 * @param $attachment_id
1421 1576 * @return string
1422 1577 */
1423 - public function get_attached_file($file, $attachment_id){
1578 + public function get_attached_file($file, $attachment_id) {
1424 1579 global $default_dir;
1425 - $sm_cloud = get_post_meta( $attachment_id, 'sm_cloud', 1 );
1580 +
1581 + $sm_cloud = apply_filters('wp_stateless_get_file', [], $attachment_id);
1582 + $_file = get_post_meta($attachment_id, '_wp_attached_file', true);
1583 +
1426 1584 /* Determine if the media file has GS data at all. */
1427 - if(is_multisite()){
1428 - $sm_cloud = get_post_meta( $attachment_id, 'sm_cloud', true );
1429 - $_file = get_post_meta( $attachment_id, '_wp_attached_file', true );
1430 - if($_file){
1431 - $blog_id = get_current_blog_id();
1432 - $uploads = wp_get_upload_dir();
1433 - $_file = apply_filters( 'wp_stateless_file_name', $_file, false);
1434 - $file_path_fix = $uploads['basedir'] . "/sites/$blog_id/$_file";
1435 - if(file_exists($file_path_fix)){
1436 - $file = $file_path_fix;
1437 - }
1585 + if (is_multisite() && $_file) {
1586 + $blog_id = get_current_blog_id();
1587 + $uploads = wp_get_upload_dir();
1588 + $_file = apply_filters('wp_stateless_file_name', $_file, false);
1589 + $file_path_fix = $uploads['basedir'] . "/sites/$blog_id/$_file";
1590 +
1591 + if (file_exists($file_path_fix)) {
1592 + return $file_path_fix;
1438 1593 }
1439 - } elseif ( empty($sm_cloud) && $this->get('sm.mode') == 'stateless' ) {
1440 - $_file = get_post_meta( $attachment_id, '_wp_attached_file', true );
1441 - if( $_file ) {
1442 - $default_dir = true;
1443 - $uploads = wp_get_upload_dir();
1444 - $default_dir = false;
1445 - return $uploads[ 'basedir' ] . '/' . $_file;
1446 - }
1594 + } elseif (empty($sm_cloud) && $this->get('sm.mode') == 'stateless' && $_file) {
1595 + $default_dir = true;
1596 + $uploads = wp_get_upload_dir();
1597 + $default_dir = false;
1598 + return $uploads['basedir'] . '/' . $_file;
1447 1599 }
1600 +
1448 1601 return $file;
1449 1602 }
1450 1603
1451 1604 /**
@@ -1456,24 +1609,23 @@
1456 1609 * @return object $this->client. \wpCloud\StatelessMedia\GS_Client or \WP_Error
1457 1610 */
1458 1611 public function get_client() {
1459 1612
1460 - if( null === $this->client ) {
1613 + if (null === $this->client) {
1461 1614
1462 - $key_json = $this->get( 'sm.key_json' );
1463 - if ( empty($key_json) ) {
1464 - $key_json = get_site_option( 'sm_key_json' );
1615 + $key_json = $this->get('sm.key_json');
1616 + if (empty($key_json)) {
1617 + $key_json = get_site_option('sm_key_json');
1465 1618 }
1466 1619
1467 1620 /* Try to initialize GS Client */
1468 - $this->client = GS_Client::get_instance( array(
1469 - 'bucket' => $this->get( 'sm.bucket' ),
1621 + $this->client = GS_Client::get_instance(array(
1622 + 'bucket' => $this->get('sm.bucket'),
1470 1623 'key_json' => $key_json
1471 - ) );
1624 + ));
1472 1625 }
1473 1626
1474 1627 return $this->client;
1475 -
1476 1628 }
1477 1629
1478 1630 /**
1479 1631 * Determines if we can connect to Google Storage Bucket.
@@ -1480,47 +1632,46 @@
1480 1632 *
1481 1633 * @author peshkov@UD
1482 1634 */
1483 1635 public function is_connected_to_gs() {
1636 + $trnst = get_transient('sm::is_connected_to_gs');
1484 1637
1485 - $trnst = get_transient( 'sm::is_connected_to_gs' );
1486 -
1487 - if ( empty($trnst) || false === $trnst || !isset( $trnst[ 'hash' ] ) || $trnst[ 'hash' ] != md5( serialize( $this->get( 'sm' ) ) ) ) {
1638 + if (empty($trnst) || false === $trnst || !isset($trnst['hash']) || $trnst['hash'] != md5(serialize($this->get('sm')))) {
1488 1639 $trnst = array(
1489 1640 'success' => 'true',
1490 1641 'error' => '',
1491 - 'hash' => md5( serialize( $this->get( 'sm' ) ) ),
1642 + 'hash' => md5(serialize($this->get('sm'))),
1492 1643 );
1493 1644 $client = $this->get_client();
1494 1645
1495 - if ( is_wp_error( $client ) ) {
1496 - $trnst[ 'success' ] = 'false';
1497 - $trnst[ 'error' ] = $client->get_error_message();
1646 + if (is_wp_error($client)) {
1647 + $trnst['success'] = 'false';
1648 + $trnst['error'] = $client->get_error_message();
1498 1649 } else {
1499 1650 $connected = $client->is_connected();
1500 - if( $connected !== true ) {
1501 - $trnst[ 'success' ] = 'false';
1502 - $trnst[ 'error' ] = sprintf( __( 'Could not connect to Google Storage bucket. Please, be sure that bucket with name <b>%s</b> exists.', $this->domain ), $this->get( 'sm.bucket' ) );
1651 + if ($connected !== true) {
1652 + $trnst['success'] = 'false';
1653 + $trnst['error'] = sprintf('Could not connect to Google Storage bucket. Please be sure that bucket with name <b>%s</b> exists and the access credentials are correct.', esc_html($this->get('sm.bucket')));
1503 1654
1504 - if( is_callable(array($connected, 'getHandlerContext')) && $handlerContext = $connected->getHandlerContext() ){
1505 - if(!empty($handlerContext['error'])){
1655 + if (is_callable(array($connected, 'getHandlerContext')) && $handlerContext = $connected->getHandlerContext()) {
1656 + if (!empty($handlerContext['error'])) {
1506 1657 $handlerContext['error'];
1507 - $trnst[ 'error' ] = "Could not connect to Google Storage bucket. " . make_clickable($handlerContext['error']);
1658 + $trnst['error'] = "Could not connect to Google Storage bucket. " . make_clickable($handlerContext['error']);
1508 1659 }
1509 1660 }
1510 1661
1511 - if( is_callable(array($connected, 'getErrors')) && $error = $connected->getErrors() ){
1662 + if (is_callable(array($connected, 'getErrors')) && $error = $connected->getErrors()) {
1512 1663 $error = reset($error);
1513 - if($error['reason'] == 'accessNotConfigured')
1514 - $trnst[ 'error' ] = "Could not connect to Google Storage bucket. " . make_clickable($error['message']);
1664 + if ($error['reason'] == 'accessNotConfigured')
1665 + $trnst['error'] = "Could not connect to Google Storage bucket. " . make_clickable($error['message']);
1515 1666 }
1516 1667 }
1517 1668 }
1518 - set_transient( 'sm::is_connected_to_gs', $trnst, 4 * HOUR_IN_SECONDS );
1669 + set_transient('sm::is_connected_to_gs', $trnst, 4 * HOUR_IN_SECONDS);
1519 1670 }
1520 1671
1521 - if( isset( $trnst[ 'success' ] ) && $trnst[ 'success' ] == 'false' ) {
1522 - return new \WP_Error( 'error', ( !empty( $trnst[ 'error' ] ) ? $trnst[ 'error' ] : __( 'There is an Error on connection to Google Storage.', $this->domain ) ) );
1672 + if (isset($trnst['success']) && $trnst['success'] == 'false') {
1673 + return new \WP_Error('error', (!empty($trnst['error']) ? $trnst['error'] : 'There is an Error on connection to Google Storage.'));
1523 1674 }
1524 1675
1525 1676 return true;
1526 1677 }
@@ -1529,9 +1680,9 @@
1529 1680 * Flush all plugin transients
1530 1681 *
1531 1682 */
1532 1683 public function flush_transients() {
1533 - delete_transient( 'sm::is_connected_to_gs' );
1684 + delete_transient('sm::is_connected_to_gs');
1534 1685 }
1535 1686
1536 1687 /**
1537 1688 * Plugin Activation
@@ -1537,9 +1688,9 @@
1537 1688 * Plugin Activation
1538 1689 *
1539 1690 */
1540 1691 public function activate() {
1541 - add_action( 'activated_plugin', array($this, 'redirect_to_splash'), 99 );
1692 + add_action('activated_plugin', array($this, 'redirect_to_splash'), 99);
1542 1693 $this->run_upgrade_process();
1543 1694 }
1544 1695
1545 1696 /**
@@ -1548,10 +1699,9 @@
1548 1699 * Works on even manual plugin update.
1549 1700 *
1550 1701 * @author alim@UD
1551 1702 */
1552 - public function run_install_process()
1553 - {
1703 + public function run_install_process() {
1554 1704 // calling the upgrade function because it's same as this point for fresh install or updates.
1555 1705 $this->run_upgrade_process();
1556 1706 }
1557 1707
@@ -1561,61 +1711,27 @@
1561 1711 * Works on even manual plugin update.
1562 1712 *
1563 1713 * @author alim@UD
1564 1714 */
1565 - public function run_upgrade_process()
1566 - {
1715 + public function run_upgrade_process() {
1567 1716 // Creating database on new installation.
1568 - $this->create_db();
1717 + ud_stateless_db()->create_db();
1718 +
1719 + Migrator::instance()->migrate();
1720 +
1569 1721 /**
1570 1722 * Maybe Upgrade current Version
1571 1723 */
1572 - Upgrader::call( $this->args[ 'version' ] );
1724 + Upgrader::call($this->args['version']);
1573 1725 }
1574 1726
1575 1727 /**
1576 - * Create database on plugin activation.
1577 - * @param boolean $force - whether to create db even if option exists. For debug purpose only.
1578 - */
1579 - public function create_db($force = false) {
1580 - global $wpdb;
1581 - $sm_sync_db_version = get_option( 'sm_sync_db_version' );
1582 -
1583 - if( $sm_sync_db_version && $force == false ) {
1584 - return;
1585 - }
1586 -
1587 - $table_name = $wpdb->prefix . 'sm_sync';
1588 - $charset_collate = $wpdb->get_charset_collate();
1589 -
1590 - // `expire` timestamp NULL DEFAULT NULL,
1591 - $sql = "CREATE TABLE $table_name (
1592 - `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT ,
1593 - `file` varchar(255) NOT NULL ,
1594 - `status` varchar(10) NOT NULL ,
1595 - PRIMARY KEY (`id`)
1596 - ) $charset_collate;";
1597 -
1598 - require_once( ABSPATH . 'wp-admin/includes/upgrade.php' );
1599 - dbDelta( $sql );
1600 -
1601 - add_option( 'sm_sync_db_version', $this->args[ 'version' ] );
1602 - }
1603 -
1604 - /**
1605 1728 * Delete table when blog is deleted.
1606 1729 *
1607 1730 * @param $old_site
1608 1731 */
1609 - public function wp_delete_site($old_site){
1610 - global $wpdb;
1611 -
1612 - switch_to_blog( $old_site->id );
1613 - $table_name = $wpdb->prefix . 'sm_sync';
1614 -
1615 - $sql = "DROP TABLE IF EXISTS $table_name";
1616 - $wpdb->query($sql);
1617 - restore_current_blog();
1732 + public function wp_delete_site($old_site) {
1733 + ud_stateless_db()->clear_db($old_site->id);
1618 1734 }
1619 1735
1620 1736 /**
1621 1737 * Redirect_to_splash
@@ -1621,16 +1737,16 @@
1621 1737 * Redirect_to_splash
1622 1738 *
1623 1739 * @param string $plugin
1624 1740 */
1625 - public function redirect_to_splash($plugin =''){
1741 + public function redirect_to_splash($plugin = '') {
1626 1742 // $this->settings = new Settings();
1627 1743
1628 - if(defined( 'WP_CLI' ) || $this->settings->get('sm.key_json') || isset($_POST['checked']) && count($_POST['checked']) > 1){
1744 + if (defined('WP_CLI') || $this->settings->get('sm.key_json') || isset($_POST['checked']) && count($_POST['checked']) > 1) {
1629 1745 return;
1630 1746 }
1631 1747
1632 - if(
1748 + if (
1633 1749 !$this->settings->get('sm.key_json') &&
1634 1750 defined('WP_STATELESS_MEDIA_HIDE_SETUP_ASSISTANT') && WP_STATELESS_MEDIA_HIDE_SETUP_ASSISTANT == true &&
1635 1751 defined('WP_STATELESS_MEDIA_HIDE_SETTINGS_PANEL') && WP_STATELESS_MEDIA_HIDE_SETTINGS_PANEL == true
1636 1752 ) {
@@ -1636,19 +1752,23 @@
1636 1752 ) {
1637 1753 return;
1638 1754 }
1639 1755
1640 - if( !$this->settings->get('sm.key_json') && defined('WP_STATELESS_MEDIA_HIDE_SETUP_ASSISTANT') && WP_STATELESS_MEDIA_HIDE_SETUP_ASSISTANT == true ) {
1756 + if (!$this->settings->get('sm.key_json') && defined('WP_STATELESS_MEDIA_HIDE_SETUP_ASSISTANT') && WP_STATELESS_MEDIA_HIDE_SETUP_ASSISTANT == true) {
1641 1757 $url = $this->get_settings_page_url('?page=stateless-settings');
1642 - exit( wp_redirect($url));
1758 + exit(wp_redirect($url));
1643 1759 }
1644 1760
1645 - if( $plugin == plugin_basename( $this->boot_file ) ) {
1646 - $url = $this->get_settings_page_url('?page=stateless-setup&step=splash-screen');
1647 - if(json_decode($this->settings->get('sm.key_json'))){
1761 + if ($plugin == plugin_basename($this->boot_file)) {
1762 + // #152
1763 + // $url = $this->get_settings_page_url('?page=stateless-setup&step=splash-screen');
1764 + $url = $this->get_settings_page_url('?page=stateless-settings');
1765 +
1766 + if (json_decode($this->settings->get('sm.key_json'))) {
1648 1767 $url = $this->get_settings_page_url('?page=stateless-settings');
1649 1768 }
1650 - exit( wp_redirect($url));
1769 +
1770 + exit( wp_redirect($url) );
1651 1771 }
1652 1772 }
1653 1773
1654 1774 /**
@@ -1654,24 +1774,25 @@
1654 1774 /**
1655 1775 * Plugin Deactivation
1656 1776 *
1657 1777 */
1658 - public function deactivate() {}
1778 + public function deactivate() {
1779 + }
1659 1780
1660 1781 /**
1661 1782 * Show_notice_stateless_cache_busting
1662 1783 *
1663 1784 */
1664 - public function show_notice_stateless_cache_busting(){
1665 - $this->errors->add( array(
1785 + public function show_notice_stateless_cache_busting() {
1786 + $this->errors->add(array(
1666 1787 'key' => 'stateless_cache_busting',
1667 1788 'button' => 'View Settings',
1668 1789 'button_link' => admin_url('upload.php?page=stateless-settings'),
1669 - 'title' => sprintf( __( "Stateless mode now requires the Cache-Busting option.", ud_get_stateless_media()->domain ) ),
1670 - 'message' => sprintf( __("WordPress looks at local files to prevent files with the same filenames.
1671 - Since Stateless mode bypasses this check, there is a potential for files to be stored with the same file name. We enforce the Cache-Busting option to prevent this.
1672 - Override with the <a href='%s' target='_blank'>%s</a> constant.", ud_get_stateless_media()->domain),"https://wp-stateless.github.io/docs/constants/#wp_stateless_media_cache_busting", "WP_STATELESS_MEDIA_CACHE_BUSTING" ),
1673 - ), 'notice' );
1790 + 'title' => sprintf(__("Stateless mode now requires the Cache-Busting option.", ud_get_stateless_media()->domain)),
1791 + 'message' => sprintf(__("WordPress looks at local files to prevent files with the same filenames.
1792 + Since Stateless mode bypasses this check, there is a potential for files to be stored with the same file name. We enforce the Cache-Busting option to prevent this.
1793 + Override with the <a href='%s' target='_blank'>%s</a> constant.", ud_get_stateless_media()->domain), ud_get_stateless_media()->get_docs_page_url('docs/constants/#wpstatelessmediacachebusting'), "WP_STATELESS_MEDIA_CACHE_BUSTING"),
1794 + ), 'notice');
1674 1795 }
1675 1796
1676 1797 /**
1677 1798 * Filter for wp_get_attachment_url();
@@ -1678,47 +1799,47 @@
1678 1799 * @param string $url
1679 1800 * @param string $post_id
1680 1801 * @return mixed|null|string
1681 1802 */
1682 - public function wp_get_attachment_url( $url = '', $post_id = '' ) {
1803 + public function wp_get_attachment_url($url = '', $post_id = '') {
1683 1804 global $default_dir;
1684 - $sm_cloud = get_post_meta( $post_id, 'sm_cloud', 1 );
1685 - if( is_array( $sm_cloud ) && !empty( $sm_cloud[ 'fileLink' ] ) ) {
1686 - $_url = parse_url($sm_cloud[ 'fileLink' ]);
1687 - $url = !isset($_url['scheme']) ? ( 'https:' . $sm_cloud[ 'fileLink' ] ) : $sm_cloud[ 'fileLink' ];
1688 - return apply_filters('wp_stateless_bucket_link', $url);
1689 - }
1690 - elseif(is_multisite() && empty($sm_cloud)){
1691 - $_file = get_post_meta( $post_id, '_wp_attached_file', true );
1692 - if($_file){
1693 - if ( $this->get('sm.mode') == 'stateless' ) {
1805 + $sm_cloud = apply_filters('wp_stateless_get_file', [], $post_id);
1806 + if (is_array($sm_cloud) && !empty($sm_cloud['fileLink'])) {
1807 + $_url = parse_url($sm_cloud['fileLink']);
1808 + $url = !isset($_url['scheme']) ? ('https:' . $sm_cloud['fileLink']) : $sm_cloud['fileLink'];
1809 + $url = apply_filters('wp_stateless_bucket_link', $url);
1810 + } elseif (is_multisite() && empty($sm_cloud)) {
1811 + $_file = get_post_meta($post_id, '_wp_attached_file', true);
1812 + if ($_file) {
1813 + if ($this->get('sm.mode') == 'stateless') {
1694 1814 $default_dir = true;
1695 1815 $uploads = wp_get_upload_dir();
1696 1816 $default_dir = false;
1697 - return $uploads['baseurl'].'/'.$_file;
1817 + $url = $uploads['baseurl'] . '/' . $_file;
1698 1818 } else {
1699 1819 $uploads = wp_get_upload_dir();
1700 1820 $default_dir = false;
1701 - $_file = apply_filters( 'wp_stateless_file_name', $_file, false );
1821 + $_file = apply_filters('wp_stateless_file_name', $_file, false);
1702 1822 $blog_id = get_current_blog_id();
1703 - $file_path_fix = $uploads[ 'basedir' ] . "/sites/$blog_id/$_file";
1823 + $file_path_fix = $uploads['basedir'] . "/sites/$blog_id/$_file";
1704 1824
1705 - if( file_exists( $file_path_fix ) ) {
1706 - $url = $uploads[ 'baseurl' ] . "/sites/$blog_id/$_file";
1825 + if (file_exists($file_path_fix)) {
1826 + $url = $uploads['baseurl'] . "/sites/$blog_id/$_file";
1707 1827 }
1708 1828 }
1709 1829 }
1710 - } elseif ( empty($sm_cloud) && $this->get('sm.mode') == 'stateless' ) {
1711 - $_file = get_post_meta( $post_id, '_wp_attached_file', true );
1712 - if($_file){
1830 + } elseif (empty($sm_cloud) && $this->get('sm.mode') == 'stateless') {
1831 + $_file = get_post_meta($post_id, '_wp_attached_file', true);
1832 + if ($_file) {
1713 1833 $default_dir = true;
1714 1834 $uploads = wp_get_upload_dir();
1715 1835 $default_dir = false;
1716 1836
1717 - return $uploads['baseurl'].'/'.$_file;
1837 + $url = $uploads['baseurl'] . '/' . $_file;
1718 1838 }
1719 1839 }
1720 - return $url;
1840 +
1841 + return apply_filters('wp_stateless_attachment_url', $url, $post_id);
1721 1842 }
1722 1843
1723 1844 /**
1724 1845 * Filter for attachment_url_to_postid()
@@ -1726,22 +1847,29 @@
1726 1847 * @param int|false $post_id originally found post ID (or false if not found)
1727 1848 * @param string $url the URL to find the post ID for
1728 1849 * @return int|false found post ID from cloud storage URL
1729 1850 */
1730 - public function attachment_url_to_postid( $post_id, $url ) {
1851 + public function attachment_url_to_postid($post_id, $url) {
1731 1852 global $wpdb;
1732 1853
1733 - if ( ! $post_id ) {
1854 + if (!$post_id) {
1734 1855 $post_id = get_transient("stateless_url_to_postid_" . md5($url));
1735 1856
1736 - if(defined('WP_STATELESS_LEGACY_URL_TO_POSTID')){
1857 + if (defined('WP_STATELESS_LEGACY_URL_TO_POSTID')) {
1737 1858 // User can use this constant if they change the Bucket Folder (root_dir) after uploading image.
1738 1859 // This can be little slow at first run.
1739 - if(empty($post_id)){
1740 - $query = "SELECT post_id FROM $wpdb->postmeta WHERE meta_key = 'sm_cloud' AND meta_value LIKE '%s'";
1741 - $post_id = $wpdb->get_var( $wpdb->prepare( $query, '%' . $url . '%' ) );
1860 + if (empty($post_id)) {
1861 + if ( !$this->get('sm.use_postmeta') ) {
1862 + $query = 'SELECT post_id FROM ' . ud_stateless_db()->files . ' WHERE file_link = %s';
1863 + $post_id = $wpdb->get_var($wpdb->prepare($query, $url));
1864 + }
1865 +
1866 + if (empty($post_id)) {
1867 + $query = "SELECT post_id FROM $wpdb->postmeta WHERE meta_key = 'sm_cloud' AND meta_value LIKE '%s'";
1868 + $post_id = $wpdb->get_var($wpdb->prepare($query, '%' . $url . '%'));
1869 + }
1742 1870
1743 - if($post_id){
1871 + if ($post_id) {
1744 1872 set_transient("stateless_url_to_postid_" . md5($url), $post_id);
1745 1873 }
1746 1874 }
1747 1875 return $post_id;
@@ -1746,28 +1874,27 @@
1746 1874 }
1747 1875 return $post_id;
1748 1876 }
1749 1877
1750 - if(empty($post_id)){
1878 + if (empty($post_id)) {
1751 1879 $gs_base_url = $this->get_gs_host();
1752 - $root_dir = $this->get( 'sm.root_dir' );
1753 - $path_elements = apply_filters( 'wp_stateless_unhandle_root_dir', $url );
1880 + $root_dir = $this->get('sm.root_dir');
1881 + $path_elements = apply_filters('wp_stateless_unhandle_root_dir', $url);
1754 1882 $root_dir = apply_filters("wp_stateless_handle_root_dir", $root_dir, false, $path_elements);
1755 1883 $gs_url = $this->get_gs_host() . '/' . $root_dir;
1756 1884 $site_url = parse_url($gs_url);
1757 - $image_path = parse_url( $url );
1885 + $image_path = parse_url($url);
1758 1886
1759 1887 //force the protocols to match if needed
1760 - if( isset( $image_path['scheme'] ) && ( $image_path['scheme'] !== $site_url['scheme'] ) ) {
1761 - $url = str_replace( $image_path['scheme'], $site_url['scheme'], $url );
1888 + if (isset($image_path['scheme']) && ($image_path['scheme'] !== $site_url['scheme'])) {
1889 + $url = str_replace($image_path['scheme'], $site_url['scheme'], $url);
1762 1890 }
1763 1891
1764 - if( 0 === strpos( $url, $gs_url . '/' ) ) {
1765 - $url = substr( $url, strlen( $gs_url . '/' ) );
1766 - }
1767 - else if( 0 === strpos( $url, $gs_base_url . '/' ) ) {
1892 + if (0 === strpos($url, $gs_url . '/')) {
1893 + $url = substr($url, strlen($gs_url . '/'));
1894 + } else if (0 === strpos($url, $gs_base_url . '/')) {
1768 1895 // In case user added Bucket Folder (root_dir) after uploading image.
1769 - $url = substr( $url, strlen( $gs_base_url . '/' ) );
1896 + $url = substr($url, strlen($gs_base_url . '/'));
1770 1897 }
1771 1898
1772 1899 /**
1773 1900 * If `uploads_use_yearmonth_folders` is set - adding year and month to url
@@ -1773,10 +1900,10 @@
1773 1900 * If `uploads_use_yearmonth_folders` is set - adding year and month to url
1774 1901 */
1775 1902 $organize_media = get_option('uploads_use_yearmonth_folders');
1776 1903 $path = '';
1777 - if ( $organize_media == '1' && isset ($path_elements['%date_year/date_month%']) ) {
1778 - $path .= $path_elements['%date_year/date_month%'].'/';
1904 + if ($organize_media == '1' && isset($path_elements['%date_year/date_month%'])) {
1905 + $path .= $path_elements['%date_year/date_month%'] . '/';
1779 1906 }
1780 1907 $url = $path . $url;
1781 1908
1782 1909 $sql = $wpdb->prepare(
@@ -1782,11 +1909,11 @@
1782 1909 $sql = $wpdb->prepare(
1783 1910 "SELECT post_id FROM $wpdb->postmeta WHERE meta_key = '_wp_attached_file' AND meta_value = %s",
1784 1911 $url
1785 1912 );
1786 - $post_id = $wpdb->get_var( $sql );
1913 + $post_id = $wpdb->get_var($sql);
1787 1914
1788 - if($post_id){
1915 + if ($post_id) {
1789 1916 set_transient("stateless_url_to_postid_" . md5($url), $post_id);
1790 1917 }
1791 1918 }
1792 1919 }
@@ -1799,15 +1926,14 @@
1799 1926 *
1800 1927 * @param $data
1801 1928 * @return mixed
1802 1929 */
1803 - public function upload_dir( $data ) {
1804 - $data[ 'basedir' ] = $this->get_gs_host();
1805 - $data[ 'baseurl' ] = $this->get_gs_host();
1806 - $data[ 'url' ] = $data[ 'baseurl' ] . $data[ 'subdir' ];
1930 + public function upload_dir($data) {
1931 + $data['basedir'] = $this->get_gs_host();
1932 + $data['baseurl'] = $this->get_gs_host();
1933 + $data['url'] = $data['baseurl'] . $data['subdir'];
1807 1934
1808 1935 return $data;
1809 -
1810 1936 }
1811 1937
1812 1938 /**
1813 1939 * Set Feature Flag constants by parsing composer.json
@@ -1816,42 +1942,39 @@
1816 1942 *
1817 1943 * @author potanin@UD
1818 1944 * @return array|mixed|null|object
1819 1945 */
1820 - public function parse_feature_flags( ) {
1946 + public function parse_feature_flags() {
1821 1947
1822 1948 try {
1823 1949
1824 - $_raw = file_get_contents( Utility::normalize_path( $this->root_path ) . 'composer.json' );
1950 + $_raw = file_get_contents(Utility::normalize_path($this->root_path) . 'composer.json');
1825 1951
1826 - $_parsed = json_decode( $_raw );
1952 + $_parsed = json_decode($_raw);
1827 1953
1828 1954 // @todo Catch poorly formatted JSON.
1829 - if( !is_object( $_parsed ) ) {
1955 + if (!is_object($_parsed)) {
1830 1956 // throw new Error( "unable to parse." );
1831 1957 }
1832 1958
1833 - foreach( (array) $_parsed->extra->featureFlags as $_feature ) {
1959 + foreach ((array) $_parsed->extra->featureFlags as $_feature) {
1834 1960
1835 - if( !defined( $_feature->constant ) ) {
1836 - define( $_feature->constant, $_feature->enabled );
1961 + if (!defined($_feature->constant)) {
1962 + define($_feature->constant, $_feature->enabled);
1837 1963
1838 - if( $_feature->enabled ) {
1839 - Utility::log( 'Feature flag ' . $_feature->name . ', [' . $_feature->constant . '] enabled.' );
1964 + if ($_feature->enabled) {
1965 + Utility::log('Feature flag ' . $_feature->name . ', [' . $_feature->constant . '] enabled.');
1840 1966 } else {
1841 - Utility::log( 'Feature flag ' . $_feature->name . ', [' . $_feature->constant . '] disabled.' );
1967 + Utility::log('Feature flag ' . $_feature->name . ', [' . $_feature->constant . '] disabled.');
1842 1968 }
1843 1969 }
1844 -
1845 1970 }
1846 -
1847 - } catch ( \Exception $e ) {
1848 - Utility::log( 'Unable to parse [composer.json] feature flags. Error: [' . $e->getMessage() . ']' );
1971 + } catch (\Exception $e) {
1972 + Utility::log('Unable to parse [composer.json] feature flags. Error: [' . $e->getMessage() . ']');
1849 1973 // echo 'Caught exception: ', $e->getMessage(), "\n";
1850 1974 }
1851 1975
1852 - return isset( $_parsed ) ? $_parsed : null;
1853 -
1976 + return isset($_parsed) ? $_parsed : null;
1854 1977 }
1855 1978
1856 1979 /**
1857 1980 * Determine if Utility class contains missed function
@@ -1861,11 +1984,11 @@
1861 1984 * @param $name
1862 1985 * @param $arguments
1863 1986 * @return mixed|null
1864 1987 */
1865 - public function __call( $name, $arguments ) {
1866 - if( is_callable( array( "wpCloud\\StatelessMedia\\Utility", $name ) ) ) {
1867 - return call_user_func_array( array( "wpCloud\\StatelessMedia\\Utility", $name ), $arguments );
1988 + public function __call($name, $arguments) {
1989 + if (is_callable(array("wpCloud\\StatelessMedia\\Utility", $name))) {
1990 + return call_user_func_array(array("wpCloud\\StatelessMedia\\Utility", $name), $arguments);
1868 1991 } else {
1869 1992 return NULL;
1870 1993 }
1871 1994 }
@@ -1878,35 +2001,120 @@
1878 2001 *
1879 2002 * @param boolean [$unset_disabled = true]
1880 2003 * @return array
1881 2004 */
1882 - function get_image_sizes( $unset_disabled = true ) {
1883 - $wais = & $GLOBALS['_wp_additional_image_sizes'];
2005 + function get_image_sizes($unset_disabled = true) {
2006 + $wais = &$GLOBALS['_wp_additional_image_sizes'];
1884 2007
1885 2008 $sizes = array();
1886 2009
1887 - foreach ( get_intermediate_image_sizes() as $_size ) {
1888 - if ( in_array( $_size, array('thumbnail', 'medium', 'medium_large', 'large') ) ) {
1889 - $sizes[ $_size ] = array(
1890 - 'width' => get_option( "{$_size}_size_w" ),
1891 - 'height' => get_option( "{$_size}_size_h" ),
1892 - 'crop' => (bool) get_option( "{$_size}_crop" ),
2010 + foreach (get_intermediate_image_sizes() as $_size) {
2011 + if (in_array($_size, array('thumbnail', 'medium', 'medium_large', 'large'))) {
2012 + $sizes[$_size] = array(
2013 + 'width' => get_option("{$_size}_size_w"),
2014 + 'height' => get_option("{$_size}_size_h"),
2015 + 'crop' => (bool) get_option("{$_size}_crop"),
1893 2016 );
1894 - }
1895 - elseif ( isset( $wais[$_size] ) ) {
1896 - $sizes[ $_size ] = array(
1897 - 'width' => $wais[ $_size ]['width'],
1898 - 'height' => $wais[ $_size ]['height'],
1899 - 'crop' => $wais[ $_size ]['crop'],
2017 + } elseif (isset($wais[$_size])) {
2018 + $sizes[$_size] = array(
2019 + 'width' => $wais[$_size]['width'],
2020 + 'height' => $wais[$_size]['height'],
2021 + 'crop' => $wais[$_size]['crop'],
1900 2022 );
1901 2023 }
1902 2024
1903 2025 // size registered, but has 0 width and height
1904 - if( $unset_disabled && ($sizes[ $_size ]['width'] == 0) && ($sizes[ $_size ]['height'] == 0) )
1905 - unset( $sizes[ $_size ] );
2026 + if ($unset_disabled && ($sizes[$_size]['width'] == 0) && ($sizes[$_size]['height'] == 0))
2027 + unset($sizes[$_size]);
1906 2028 }
1907 2029
1908 2030 return $sizes;
2031 + }
2032 +
2033 + /**
2034 + * Get the email for notifications
2035 + *
2036 + * @return string
2037 + */
2038 + public function get_notification_email() {
2039 + $type = $this->get( 'sm.status_email_type' );
2040 +
2041 + switch ($type) {
2042 + case 'true':
2043 + // Emails to Admin
2044 + return get_site_option('admin_email');
2045 + case 'custom':
2046 + // Emails to Custom Email
2047 + return $this->get( 'sm.status_email_address' );
2048 + }
2049 +
2050 + // Emails disabled
2051 + return '';
2052 + }
2053 +
2054 + /**
2055 + * Send admin email
2056 + *
2057 + * @param string $subject
2058 + * @param string $message
2059 + * @param string $email
2060 + */
2061 + public function send_admin_email($subject, $message, $email = '') {
2062 + $admin_email = empty($email) ? $this->get_notification_email() : $email;
2063 +
2064 + $admin_email = explode(',', $admin_email);
2065 + $admin_email = array_map( function($item) {
2066 + return strip_tags( trim($item) );
2067 + }, $admin_email);
2068 +
2069 + if ( empty($admin_email) || empty($subject) || empty($message) ) {
2070 + return;
2071 + }
2072 +
2073 + wp_mail( $admin_email, $subject, $message);
2074 + }
2075 +
2076 + /**
2077 + * Check if we are in specific mode
2078 + *
2079 + * @param string|array $mode
2080 + * @return bool
2081 + */
2082 + public function is_mode($mode) {
2083 + if ( !is_array($mode) ) {
2084 + $mode = [$mode];
2085 + }
2086 +
2087 + return in_array($this->get('sm.mode'), $mode);
2088 + }
2089 +
2090 + /**
2091 + * Get default cache control value
2092 + *
2093 + * @return string
2094 + */
2095 + public function get_default_cache_control() {
2096 + return Settings::DEFAULT_CACHE_CONTROL;
2097 + }
2098 +
2099 + /**
2100 + * Override REST API root for headless CMS
2101 + *
2102 + * @return string
2103 + */
2104 + public function get_rest_api_root($rest_api_root) {
2105 + $rest_api_root = sanitize_url( get_rest_url() );
2106 + $rest_api_root .= 'wp-stateless/v1/';
2107 +
2108 + if ( $this->get('sm.use_api_siteurl') == 'WP_SITEURL' ) {
2109 + $home = get_home_url();
2110 + $site = get_site_url();
2111 +
2112 + return str_replace( $home, $site, $rest_api_root );
2113 + }
2114 +
2115 +
2116 + return $rest_api_root;
1909 2117 }
1910 2118 }
1911 2119 }
1912 2120 }