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 +807 -596 3.0.3trunk 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,63 +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.
1032 + * excluding compatibility.
882 1033 */
883 - $current_path = basename($current_path);
1034 + if ($use_root) {
1035 + $current_path = basename($current_path);
1036 + }
884 1037
885 - if(!$use_root){
886 - // removing the root dir if already exists in the begaining.
887 - 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;
888 1050 }
889 1051
890 1052 // skip adding root dir if it's already added.
891 - if ( !empty( $root_dir ) && !preg_match($root_dir_regex, $current_path) ) {
892 - 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, '/ ');
893 1055 }
894 1056
895 1057 return $current_path;
896 1058 }
@@ -898,22 +1060,25 @@
898 1060 /**
899 1061 * @param $content
900 1062 * @return mixed
901 1063 */
902 - public function the_content_filter( $content ) {
1064 + public function the_content_filter($content) {
903 1065
904 - if ( $upload_data = wp_upload_dir() ) {
1066 + if ($upload_data = wp_upload_dir()) {
905 1067
906 - if ( !empty( $upload_data['url'] ) && !empty( $content ) ) {
907 - $url = preg_replace('/https?:\/\//','',$upload_data['url']);
1068 + if (!empty($upload_data['url']) && !empty($content)) {
1069 + $url = preg_replace('/https?:\/\//', '', $upload_data['url']);
908 1070
909 - $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.
910 1072 $root_dir = apply_filters("wp_stateless_handle_root_dir", $root_dir);
911 - $root_dir = !empty( $root_dir ) ? $root_dir . '/' : false;
1073 + $root_dir = !empty($root_dir) ? $root_dir . '/' : false;
912 1074 $image_host = $this->get_gs_host();
913 1075 $file_ext = $this->replaceable_file_types();
914 - $content = preg_replace( '/(href|src)=(\'|")(https?:\/\/'.str_replace('/', '\/', $url).')\/(.+?)('.$file_ext.')(\'|")/i',
915 - '$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 + );
916 1081 }
917 1082 }
918 1083
919 1084 return $content;
@@ -922,9 +1087,9 @@
922 1087 /**
923 1088 * Return file types supported by File URL Replacement.
924 1089 * @return string
925 1090 */
926 - public function replaceable_file_types(){
1091 + public function replaceable_file_types() {
927 1092 $types = $this->get('sm.body_rewrite_types');
928 1093
929 1094 // Removing extra space.
930 1095 $types = trim($types);
@@ -942,23 +1107,23 @@
942 1107 * @param $meta_key
943 1108 * @param $single
944 1109 * @return mixed
945 1110 */
946 - public function post_metadata_filter($value, $object_id, $meta_key, $single){
947 - if(empty($value)){
1111 + public function post_metadata_filter($value, $object_id, $meta_key, $single) {
1112 + if (empty($value)) {
948 1113 $meta_type = 'post';
949 1114 $transient_key = "stateless_{$meta_type}_meta";
950 1115
951 1116 $meta_cache = wp_cache_get($object_id, $transient_key);
952 - if(empty($meta_cache)){
1117 + if (empty($meta_cache)) {
953 1118 $meta_cache = wp_cache_get($object_id, $meta_type . '_meta');
954 1119
955 - if ( !$meta_cache ) {
956 - $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));
957 1122 $meta_cache = $meta_cache[$object_id];
958 1123 }
959 1124
960 - foreach($meta_cache as $key => $meta){
1125 + foreach ($meta_cache as $key => $meta) {
961 1126 $meta_cache[$key] = array_map('maybe_unserialize', $meta_cache[$key]);
962 1127 }
963 1128
964 1129 $meta_cache = $this->convert_to_gs_link($meta_cache);
@@ -964,13 +1129,13 @@
964 1129 $meta_cache = $this->convert_to_gs_link($meta_cache);
965 1130 wp_cache_set($object_id, $meta_cache, $transient_key);
966 1131 }
967 1132
968 - if ( ! $meta_key ) {
1133 + if (!$meta_key) {
969 1134 return $meta_cache;
970 1135 }
971 1136
972 - if ( isset($meta_cache[$meta_key]) ) {
1137 + if (isset($meta_cache[$meta_key])) {
973 1138 return $meta_cache[$meta_key];
974 1139 }
975 1140
976 1141 // in case no metadata is found return what was passed in $value.
@@ -978,9 +1143,8 @@
978 1143 return $value;
979 1144 }
980 1145
981 1146 return $this->convert_to_gs_link($value);
982 -
983 1147 }
984 1148
985 1149 /**
986 1150 * Replace all image link with gs link and return only if meta modified.
@@ -988,23 +1152,23 @@
988 1152 * @param $meta
989 1153 * @param $return
990 1154 * @return mixed or null when not changed.
991 1155 */
992 - public function convert_to_gs_link($meta, $return = false){
1156 + public function convert_to_gs_link($meta, $return = false) {
993 1157 $updated = $meta;
994 - if ( $meta && $upload_data = wp_upload_dir() ) {
995 - if ( !empty( $upload_data['url'] ) && !empty( $meta ) ) {
996 - $url = preg_replace('/https?:\/\//','',$upload_data['url']);
997 - $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.
998 1162 $root_dir = apply_filters("wp_stateless_handle_root_dir", $root_dir);
999 - $root_dir = !empty( $root_dir ) ? $root_dir . '/': false;
1000 - $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 : '');
1001 1165 $file_ext = $this->replaceable_file_types();
1002 1166 $updated = $this->_convert_to_gs_link($meta, $image_host, $url, $file_ext);
1003 1167 }
1004 1168 }
1005 1169
1006 - if($updated == $meta && !$return){
1170 + if ($updated == $meta && !$return) {
1007 1171 return null; // Not changed.
1008 1172 }
1009 1173 return $updated;
1010 1174 }
@@ -1017,21 +1181,21 @@
1017 1181 * @param $url
1018 1182 * @param $file_ext
1019 1183 * @return array|null|string|string[]
1020 1184 */
1021 - public function _convert_to_gs_link($meta, $image_host, $url, $file_ext){
1022 - if(is_array($meta)){
1185 + public function _convert_to_gs_link($meta, $image_host, $url, $file_ext) {
1186 + if (is_array($meta)) {
1023 1187 foreach ($meta as $key => $value) {
1024 1188 $meta[$key] = $this->_convert_to_gs_link($value, $image_host, $url, $file_ext);
1025 1189 }
1026 1190 return $meta;
1027 - } elseif (is_object($meta) && $meta instanceof \stdClass ) {
1191 + } elseif (is_object($meta) && $meta instanceof \stdClass) {
1028 1192 foreach (get_object_vars($meta) as $key => $value) {
1029 1193 $meta->{$key} = $this->_convert_to_gs_link($value, $image_host, $url, $file_ext);
1030 1194 }
1031 1195 return $meta;
1032 - } elseif(is_string($meta)){
1033 - 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);
1034 1198 }
1035 1199
1036 1200 return $meta;
1037 1201 }
@@ -1036,28 +1200,8 @@
1036 1200 return $meta;
1037 1201 }
1038 1202
1039 1203 /**
1040 - * @param $links
1041 - * @param $file
1042 - * @return mixed
1043 - */
1044 - public function plugin_action_links( $links, $file ) {
1045 -
1046 - if ($file == plugin_basename( dirname( __DIR__ ) . '/wp-stateless-media.php' ) ) {
1047 - $settings_link = '<a href="'. '' .'">'.__( 'Settings' , 'ssd').'</a>';
1048 - array_unshift( $links, $settings_link );
1049 - }
1050 -
1051 - if ($file == plugin_basename( dirname( __DIR__ ) . '/wp-stateless.php' ) ) {
1052 - $settings_link = '<a href="'. '' .'">'.__( 'Settings' , 'ssd').'</a>';
1053 - array_unshift( $links, $settings_link );
1054 - }
1055 -
1056 - return $links;
1057 - }
1058 -
1059 - /**
1060 1204 * Determines if plugin is loaded via mu-plugins
1061 1205 * or Network Enabled.
1062 1206 *
1063 1207 * @param bool $is_multisite
@@ -1066,20 +1210,20 @@
1066 1210 */
1067 1211 public function is_network_detected($is_multisite = false) {
1068 1212 /* Plugin is loaded via mu-plugins. */
1069 1213
1070 - 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) {
1071 1215 return true;
1072 1216 }
1073 1217
1074 - if( is_multisite() ) {
1075 - if($is_multisite) return true;
1218 + if (is_multisite()) {
1219 + if ($is_multisite) return true;
1076 1220 /* Looks through network enabled plugins to see if our one is there. */
1077 1221 foreach (wp_get_active_network_plugins() as $path) {
1078 1222 // Trying again using readlink in case it's a symlink file.
1079 1223 // boot_file is already solved.
1080 1224 // wp_normalize_path is helpfull in windows.
1081 - 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))) {
1082 1226 return true;
1083 1227 }
1084 1228 }
1085 1229 }
@@ -1091,43 +1235,47 @@
1091 1235 * Register scripts and styles
1092 1236 */
1093 1237 public function admin_init() {
1094 1238 $this->show_notice_stateless_cache_busting();
1095 - 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);
1096 1240
1097 1241 /**
1098 1242 * select2 styles
1099 1243 */
1100 - 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);
1101 1245
1102 1246 /* Attachment or upload page */
1103 - 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 + ]);
1104 1251
1105 1252 /* Setup wizard styles. */
1106 - 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);
1107 1255
1108 - 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);
1109 1257
1110 1258 /* Stateless settings page */
1111 - wp_register_script( 'wp-stateless-settings', ud_get_stateless_media()->path( 'static/scripts/wp-stateless-settings.js', 'url' ), array(), self::$version );
1112 - 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());
1113 1261
1114 - 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);
1115 1265
1116 1266 // Sync tab
1117 - if ( wp_script_is( 'jquery-ui-widget', 'registered' ) ){
1118 - 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' );
1119 - }
1120 - else{
1121 - 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' );
1122 - }
1123 - wp_register_script( 'wp-stateless-angular', ud_get_stateless_media()->path( 'static/scripts/angular.min.js', 'url' ), array(), '1.5.0', true );
1124 - 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 );
1125 - 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);
1126 1268
1127 - wp_localize_script( 'wp-stateless', 'stateless_l10n', $this->get_l10n_data() );
1269 + wp_localize_script('wp-stateless', 'stateless_l10n', $this->get_l10n_data());
1128 1270 wp_localize_script('wp-stateless', 'wp_stateless_configs', array(
1129 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),
1130 1278 ));
1131 1279
1132 1280 $settings = ud_get_stateless_media()->get('sm');
1133 1281 $settings['wildcards'] = $this->settings->wildcards;
@@ -1132,15 +1280,20 @@
1132 1280 $settings = ud_get_stateless_media()->get('sm');
1133 1281 $settings['wildcards'] = $this->settings->wildcards;
1134 1282 $settings['network_admin'] = is_network_admin();
1135 1283 $settings['is_multisite'] = is_multisite();
1136 - 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) {
1137 1285 $settings['key_json'] = "Currently configured via a constant.";
1138 1286 }
1139 1287 wp_localize_script('wp-stateless', 'wp_stateless_settings', $settings);
1140 - wp_localize_script('wp-stateless', 'wp_stateless_compatibility', Module::get_modules());
1141 - 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' );
1142 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 + ));
1143 1296 }
1144 1297
1145 1298 /**
1146 1299 * Get_l10n_data
@@ -1147,10 +1300,10 @@
1147 1300 *
1148 1301 * @param string $value
1149 1302 * @return mixed
1150 1303 */
1151 - public function get_l10n_data($value=''){
1152 - 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');
1153 1306 return $l10n;
1154 1307 }
1155 1308
1156 1309 /**
@@ -1157,19 +1310,19 @@
1157 1310 * Admin Scripts
1158 1311 *
1159 1312 * @param $hook
1160 1313 */
1161 - public function admin_enqueue_scripts( $hook ) {
1314 + public function admin_enqueue_scripts($hook) {
1162 1315
1163 - switch( $hook ) {
1316 + switch ($hook) {
1164 1317
1165 1318 case 'options-media.php':
1166 - wp_enqueue_style( 'wp-stateless');
1319 + wp_enqueue_style('wp-stateless');
1167 1320 break;
1168 1321
1169 1322 case 'upload.php':
1170 - wp_enqueue_style( 'wp-stateless');
1171 - wp_enqueue_script( 'wp-stateless-uploads-js' );
1323 + wp_enqueue_style('wp-stateless');
1324 + wp_enqueue_script('wp-stateless-uploads-js');
1172 1325
1173 1326 break;
1174 1327
1175 1328 case 'post.php':
@@ -1175,51 +1328,60 @@
1175 1328 case 'post.php':
1176 1329
1177 1330 global $post;
1178 1331
1179 - if ( $post->post_type == 'attachment' ) {
1180 - wp_enqueue_style( 'wp-stateless');
1181 - 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');
1182 1335 }
1183 1336
1184 1337 break;
1185 1338
1186 - case 'media_page_stateless-setup':
1339 + // #152
1340 + // case 'media_page_stateless-setup':
1187 1341 case 'settings_page_stateless-setup':
1188 - wp_enqueue_style( 'wp-stateless');
1189 - wp_enqueue_style( 'wp-stateless-setup-wizard' );
1342 + wp_enqueue_style('wp-stateless');
1343 + // #152
1344 + // wp_enqueue_style('wp-stateless-setup-wizard');
1190 1345 break;
1191 1346 case 'media_page_stateless-settings':
1192 1347 case 'settings_page_stateless-settings':
1193 - wp_enqueue_style( 'wp-stateless');
1194 - wp_enqueue_style( 'wp-stateless-select2');
1195 - wp_enqueue_script( 'wp-stateless-settings' );
1196 - wp_enqueue_script( 'wp-stateless-select2' );
1197 - 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' );
1198 1356
1199 1357 // Sync tab
1200 - wp_enqueue_script( 'jquery-ui-progressbar' );
1201 - wp_enqueue_script( 'wp-stateless-angular' );
1202 - wp_enqueue_script( 'wp-stateless-angular-sanitize' );
1203 - wp_enqueue_script( 'wp-stateless' );
1204 - wp_enqueue_style( 'jquery-ui-regenthumbs' );
1358 + wp_enqueue_script('wp-stateless');
1205 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 +
1206 1368 $data = array(
1207 1369 'key' => 'stateless-cache-busting',
1208 1370 'class' => 'notice',
1209 - 'title' => sprintf( __( "Stateless and Ephemeral modes enables and requires the Cache-Busting option.", ud_get_stateless_media()->domain ) ),
1210 - 'message' => sprintf( __("WordPress looks at local files to prevent files with the same filenames.
1211 - 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.
1212 - 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"),
1213 1375 );
1214 1376 echo "<script id='template-stateless-cache-busting' type='text/html'>";
1215 - 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');
1216 1378 echo "</script>";
1217 1379
1218 1380 break;
1219 - default: break;
1381 + default:
1382 + break;
1220 1383 }
1221 -
1222 1384 }
1223 1385
1224 1386 /**
1225 1387 * Add Attributes to media HTML
@@ -1229,20 +1391,19 @@
1229 1391 * @param $attachment
1230 1392 * @param $size
1231 1393 * @return mixed
1232 1394 */
1233 - public function wp_get_attachment_image_attributes( $attr, $attachment, $size = null ) {
1234 -
1235 - $sm_cloud = get_post_meta( $attachment->ID, 'sm_cloud', true );
1236 - if( is_array( $sm_cloud ) && !empty( $sm_cloud[ 'name' ] ) ) {
1237 - $attr[ 'class' ] = $attr[ 'class' ] . ' wp-stateless-item';
1238 - $attr[ 'data-image-size' ] = is_array( $size ) ? implode( 'x', $size ) : $size;
1239 - $attr[ 'data-stateless-media-bucket' ] = isset( $sm_cloud[ 'bucket' ] ) ? $sm_cloud[ 'bucket' ] : false;
1240 - $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'];
1241 1403 }
1242 1404
1243 1405 return $attr;
1244 -
1245 1406 }
1246 1407
1247 1408 /**
1248 1409 * Adds filter link to Media Library table.
@@ -1249,10 +1410,10 @@
1249 1410 *
1250 1411 * @param $views
1251 1412 * @return mixed
1252 1413 */
1253 - public function views_upload( $views ) {
1254 - $views['stateless'] = '<a href="#">' . __( 'Stateless Media' ) . '</a>';
1414 + public function views_upload($views) {
1415 + $views['stateless'] = '<a href="#">' . __('Stateless Media') . '</a>';
1255 1416 return $views;
1256 1417 }
1257 1418
1258 1419 /**
@@ -1262,11 +1423,11 @@
1262 1423 * @param integer $id
1263 1424 * @param string $size
1264 1425 * @return mixed $false
1265 1426 */
1266 - public function image_downsize( $false = false, $id, $size ) {
1427 + public function image_downsize($false, $id, $size) {
1267 1428
1268 - 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') {
1269 1430 return $false;
1270 1431 }
1271 1432
1272 1433 /**
@@ -1271,9 +1432,9 @@
1271 1432
1272 1433 /**
1273 1434 * Check if enabled
1274 1435 */
1275 - if ( !in_array( $this->get( 'sm.mode' ), array( 'cdn', 'stateless', 'ephemeral' ) )) {
1436 + if (!in_array($this->get('sm.mode'), array('cdn', 'stateless', 'ephemeral'))) {
1276 1437 return $false;
1277 1438 }
1278 1439
1279 1440 /** Start determine remote file */
@@ -1282,16 +1443,14 @@
1282 1443 $width = $height = 0;
1283 1444 $is_intermediate = false;
1284 1445
1285 1446 //** try for a new style intermediate size */
1286 - if ( $intermediate = image_get_intermediate_size( $id, $size ) ) {
1287 - if(!empty( $intermediate['gs_link'] )){
1447 + if ($intermediate = image_get_intermediate_size($id, $size)) {
1448 + if (!empty($intermediate['gs_link'])) {
1288 1449 $img_url = $intermediate['gs_link'];
1289 - }
1290 - else if(!empty( $intermediate['url'] )){
1450 + } else if (!empty($intermediate['url'])) {
1291 1451 $img_url = $intermediate['url'];
1292 - }
1293 - else{
1452 + } else {
1294 1453 $img_url = dirname($img_url) . $intermediate['file'];
1295 1454 }
1296 1455
1297 1456 $width = $intermediate['width'];
@@ -1303,18 +1462,18 @@
1303 1462 * maybe try to get images info from sm_cloud
1304 1463 * this case may happen when no local files
1305 1464 * @author korotkov@ud
1306 1465 */
1307 - if ( !$width && !$height ) {
1308 - $sm_cloud = get_post_meta( $id, 'sm_cloud', true );
1309 - 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])) {
1310 1469 global $_wp_additional_image_sizes;
1311 1470
1312 - $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;
1313 1472
1314 - if ( !empty( $_wp_additional_image_sizes[ $size ] ) ) {
1315 - $width = !empty( $_wp_additional_image_sizes[ $size ]['width'] ) ? $_wp_additional_image_sizes[ $size ]['width'] : $width;
1316 - $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;
1317 1476 }
1318 1477
1319 1478 $is_intermediate = true;
1320 1479 }
@@ -1319,9 +1478,9 @@
1319 1478 $is_intermediate = true;
1320 1479 }
1321 1480 }
1322 1481
1323 - if ( !$width && !$height && isset( $meta['width'], $meta['height'] ) ) {
1482 + if (!$width && !$height && isset($meta['width'], $meta['height'])) {
1324 1483
1325 1484 //** any other type: use the real image */
1326 1485 $width = $meta['width'];
1327 1486 $height = $meta['height'];
@@ -1327,14 +1486,14 @@
1327 1486 $height = $meta['height'];
1328 1487 }
1329 1488
1330 1489
1331 - if ( $img_url) {
1490 + if ($img_url) {
1332 1491
1333 1492 //** we have the actual image size, but might need to further constrain it if content_width is narrower */
1334 - list( $width, $height ) = image_constrain_size_for_editor( $width, $height, $size );
1493 + list($width, $height) = image_constrain_size_for_editor($width, $height, $size);
1335 1494 $img_url = apply_filters('wp_stateless_bucket_link', $img_url);
1336 - return array( $img_url, $width, $height, $is_intermediate );
1495 + return array($img_url, $width, $height, $is_intermediate);
1337 1496 }
1338 1497
1339 1498
1340 1499 /**
@@ -1340,9 +1499,8 @@
1340 1499 /**
1341 1500 * All other cases work as usually
1342 1501 */
1343 1502 return $false;
1344 -
1345 1503 }
1346 1504
1347 1505 /**
1348 1506 * Extends metadata by adding GS information.
@@ -1351,61 +1509,61 @@
1351 1509 * @param $metadata
1352 1510 * @param $attachment_id
1353 1511 * @return array|mixed
1354 1512 */
1355 - public function wp_get_attachment_metadata( $metadata, $attachment_id ) {
1513 + public function wp_get_attachment_metadata($metadata, $attachment_id) {
1356 1514 global $default_dir;
1357 1515 $default_dir = false;
1358 1516 /* Determine if the media file has GS data at all. */
1359 - $sm_cloud = get_post_meta( $attachment_id, 'sm_cloud', true );
1517 + $sm_cloud = apply_filters('wp_stateless_get_file', [], $attachment_id, true);
1360 1518 // If metadata not passed the get metadata from post meta.
1361 - if(empty($metadata)){
1362 - $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);
1363 1521 }
1364 1522
1365 - if(empty($metadata)){
1523 + if (empty($metadata)) {
1366 1524 $metadata = [];
1367 1525 }
1368 1526
1369 - if( is_array( $metadata ) && is_array( $sm_cloud ) && !empty( $sm_cloud[ 'fileLink' ] ) ) {
1370 - $metadata[ 'gs_link' ] = apply_filters('wp_stateless_bucket_link', $sm_cloud[ 'fileLink' ]);
1371 - $metadata[ 'gs_name' ] = isset( $sm_cloud[ 'name' ] ) ? $sm_cloud[ 'name' ] : false;
1372 - $metadata[ 'gs_bucket' ] = isset( $sm_cloud[ 'bucket' ] ) ? $sm_cloud[ 'bucket' ] : false;
1373 - if( !empty( $metadata[ 'sizes' ] ) && is_array( $metadata[ 'sizes' ] ) ) {
1374 - foreach( $metadata[ 'sizes' ] as $k => $v ) {
1375 - if( !empty( $sm_cloud[ 'sizes' ][ $k ][ 'name' ] ) ) {
1376 - $metadata['sizes'][$k]['gs_name'] = $sm_cloud[ 'sizes' ][ $k ][ 'name' ];
1377 - $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']);
1378 1536 }
1379 1537 }
1380 1538 }
1381 1539 }
1382 - if(is_multisite() && !empty($metadata['file'])){
1383 - if ( $this->get('sm.mode') == 'stateless' ) {
1540 + if (is_multisite() && !empty($metadata['file'])) {
1541 + if ($this->get('sm.mode') == 'stateless') {
1384 1542 $default_dir = true;
1385 1543 $uploads = wp_get_upload_dir();
1386 1544 $default_dir = false;
1387 1545
1388 1546 $file_path_fix = $uploads['basedir'] . "/{$metadata['file']}";
1389 - if(file_exists($file_path_fix)) {
1390 - $metadata[ 'file' ] = "{$metadata['file']}";
1547 + if (file_exists($file_path_fix)) {
1548 + $metadata['file'] = "{$metadata['file']}";
1391 1549 }
1392 1550 } else {
1393 1551 $uploads = wp_get_upload_dir();
1394 1552 $blog_id = get_current_blog_id();
1395 - $file_path_fix = $uploads[ 'basedir' ] . "/sites/$blog_id/{$metadata['file']}";
1396 - if( file_exists( $file_path_fix ) ) {
1397 - $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']}";
1398 1556 }
1399 1557 }
1400 - } elseif ( empty($sm_cloud) && $this->get('sm.mode') == 'stateless' ) {
1558 + } elseif ( empty($sm_cloud) && $this->get('sm.mode') == 'stateless' && isset($metadata['file']) ) {
1401 1559 $default_dir = true;
1402 1560 $uploads = wp_get_upload_dir();
1403 1561 $default_dir = false;
1404 1562
1405 1563 $file_path_fix = $uploads['basedir'] . "/{$metadata['file']}";
1406 - if(file_exists($file_path_fix)) {
1407 - $metadata[ 'file' ] = "{$metadata['file']}";
1564 + if (file_exists($file_path_fix)) {
1565 + $metadata['file'] = "{$metadata['file']}";
1408 1566 }
1409 1567 }
1410 1568
1411 1569 return $metadata;
@@ -1416,33 +1574,31 @@
1416 1574 * @param $file
1417 1575 * @param $attachment_id
1418 1576 * @return string
1419 1577 */
1420 - public function get_attached_file($file, $attachment_id){
1578 + public function get_attached_file($file, $attachment_id) {
1421 1579 global $default_dir;
1422 - $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 +
1423 1584 /* Determine if the media file has GS data at all. */
1424 - if(is_multisite()){
1425 - $sm_cloud = get_post_meta( $attachment_id, 'sm_cloud', true );
1426 - $_file = get_post_meta( $attachment_id, '_wp_attached_file', true );
1427 - if($_file){
1428 - $blog_id = get_current_blog_id();
1429 - $uploads = wp_get_upload_dir();
1430 - $_file = apply_filters( 'wp_stateless_file_name', $_file, false);
1431 - $file_path_fix = $uploads['basedir'] . "/sites/$blog_id/$_file";
1432 - if(file_exists($file_path_fix)){
1433 - $file = $file_path_fix;
1434 - }
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;
1435 1593 }
1436 - } elseif ( empty($sm_cloud) && $this->get('sm.mode') == 'stateless' ) {
1437 - $_file = get_post_meta( $attachment_id, '_wp_attached_file', true );
1438 - if( $_file ) {
1439 - $default_dir = true;
1440 - $uploads = wp_get_upload_dir();
1441 - $default_dir = false;
1442 - return $uploads[ 'basedir' ] . '/' . $_file;
1443 - }
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;
1444 1599 }
1600 +
1445 1601 return $file;
1446 1602 }
1447 1603
1448 1604 /**
@@ -1453,24 +1609,23 @@
1453 1609 * @return object $this->client. \wpCloud\StatelessMedia\GS_Client or \WP_Error
1454 1610 */
1455 1611 public function get_client() {
1456 1612
1457 - if( null === $this->client ) {
1613 + if (null === $this->client) {
1458 1614
1459 - $key_json = $this->get( 'sm.key_json' );
1460 - if ( empty($key_json) ) {
1461 - $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');
1462 1618 }
1463 1619
1464 1620 /* Try to initialize GS Client */
1465 - $this->client = GS_Client::get_instance( array(
1466 - 'bucket' => $this->get( 'sm.bucket' ),
1621 + $this->client = GS_Client::get_instance(array(
1622 + 'bucket' => $this->get('sm.bucket'),
1467 1623 'key_json' => $key_json
1468 - ) );
1624 + ));
1469 1625 }
1470 1626
1471 1627 return $this->client;
1472 -
1473 1628 }
1474 1629
1475 1630 /**
1476 1631 * Determines if we can connect to Google Storage Bucket.
@@ -1477,47 +1632,46 @@
1477 1632 *
1478 1633 * @author peshkov@UD
1479 1634 */
1480 1635 public function is_connected_to_gs() {
1636 + $trnst = get_transient('sm::is_connected_to_gs');
1481 1637
1482 - $trnst = get_transient( 'sm::is_connected_to_gs' );
1483 -
1484 - 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')))) {
1485 1639 $trnst = array(
1486 1640 'success' => 'true',
1487 1641 'error' => '',
1488 - 'hash' => md5( serialize( $this->get( 'sm' ) ) ),
1642 + 'hash' => md5(serialize($this->get('sm'))),
1489 1643 );
1490 1644 $client = $this->get_client();
1491 1645
1492 - if ( is_wp_error( $client ) ) {
1493 - $trnst[ 'success' ] = 'false';
1494 - $trnst[ 'error' ] = $client->get_error_message();
1646 + if (is_wp_error($client)) {
1647 + $trnst['success'] = 'false';
1648 + $trnst['error'] = $client->get_error_message();
1495 1649 } else {
1496 1650 $connected = $client->is_connected();
1497 - if( $connected !== true ) {
1498 - $trnst[ 'success' ] = 'false';
1499 - $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')));
1500 1654
1501 - if( is_callable(array($connected, 'getHandlerContext')) && $handlerContext = $connected->getHandlerContext() ){
1502 - if(!empty($handlerContext['error'])){
1655 + if (is_callable(array($connected, 'getHandlerContext')) && $handlerContext = $connected->getHandlerContext()) {
1656 + if (!empty($handlerContext['error'])) {
1503 1657 $handlerContext['error'];
1504 - $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']);
1505 1659 }
1506 1660 }
1507 1661
1508 - if( is_callable(array($connected, 'getErrors')) && $error = $connected->getErrors() ){
1662 + if (is_callable(array($connected, 'getErrors')) && $error = $connected->getErrors()) {
1509 1663 $error = reset($error);
1510 - if($error['reason'] == 'accessNotConfigured')
1511 - $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']);
1512 1666 }
1513 1667 }
1514 1668 }
1515 - 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);
1516 1670 }
1517 1671
1518 - if( isset( $trnst[ 'success' ] ) && $trnst[ 'success' ] == 'false' ) {
1519 - 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.'));
1520 1674 }
1521 1675
1522 1676 return true;
1523 1677 }
@@ -1526,9 +1680,9 @@
1526 1680 * Flush all plugin transients
1527 1681 *
1528 1682 */
1529 1683 public function flush_transients() {
1530 - delete_transient( 'sm::is_connected_to_gs' );
1684 + delete_transient('sm::is_connected_to_gs');
1531 1685 }
1532 1686
1533 1687 /**
1534 1688 * Plugin Activation
@@ -1534,9 +1688,9 @@
1534 1688 * Plugin Activation
1535 1689 *
1536 1690 */
1537 1691 public function activate() {
1538 - add_action( 'activated_plugin', array($this, 'redirect_to_splash'), 99 );
1692 + add_action('activated_plugin', array($this, 'redirect_to_splash'), 99);
1539 1693 $this->run_upgrade_process();
1540 1694 }
1541 1695
1542 1696 /**
@@ -1545,10 +1699,9 @@
1545 1699 * Works on even manual plugin update.
1546 1700 *
1547 1701 * @author alim@UD
1548 1702 */
1549 - public function run_install_process()
1550 - {
1703 + public function run_install_process() {
1551 1704 // calling the upgrade function because it's same as this point for fresh install or updates.
1552 1705 $this->run_upgrade_process();
1553 1706 }
1554 1707
@@ -1558,61 +1711,27 @@
1558 1711 * Works on even manual plugin update.
1559 1712 *
1560 1713 * @author alim@UD
1561 1714 */
1562 - public function run_upgrade_process()
1563 - {
1715 + public function run_upgrade_process() {
1564 1716 // Creating database on new installation.
1565 - $this->create_db();
1717 + ud_stateless_db()->create_db();
1718 +
1719 + Migrator::instance()->migrate();
1720 +
1566 1721 /**
1567 1722 * Maybe Upgrade current Version
1568 1723 */
1569 - Upgrader::call( $this->args[ 'version' ] );
1724 + Upgrader::call($this->args['version']);
1570 1725 }
1571 1726
1572 1727 /**
1573 - * Create database on plugin activation.
1574 - * @param boolean $force - whether to create db even if option exists. For debug purpose only.
1575 - */
1576 - public function create_db($force = false) {
1577 - global $wpdb;
1578 - $sm_sync_db_version = get_option( 'sm_sync_db_version' );
1579 -
1580 - if( $sm_sync_db_version && $force == false ) {
1581 - return;
1582 - }
1583 -
1584 - $table_name = $wpdb->prefix . 'sm_sync';
1585 - $charset_collate = $wpdb->get_charset_collate();
1586 -
1587 - // `expire` timestamp NULL DEFAULT NULL,
1588 - $sql = "CREATE TABLE $table_name (
1589 - `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT ,
1590 - `file` varchar(255) NOT NULL ,
1591 - `status` varchar(10) NOT NULL ,
1592 - PRIMARY KEY (`id`)
1593 - ) $charset_collate;";
1594 -
1595 - require_once( ABSPATH . 'wp-admin/includes/upgrade.php' );
1596 - dbDelta( $sql );
1597 -
1598 - add_option( 'sm_sync_db_version', $this->args[ 'version' ] );
1599 - }
1600 -
1601 - /**
1602 1728 * Delete table when blog is deleted.
1603 1729 *
1604 1730 * @param $old_site
1605 1731 */
1606 - public function wp_delete_site($old_site){
1607 - global $wpdb;
1608 -
1609 - switch_to_blog( $old_site->id );
1610 - $table_name = $wpdb->prefix . 'sm_sync';
1611 -
1612 - $sql = "DROP TABLE IF EXISTS $table_name";
1613 - $wpdb->query($sql);
1614 - restore_current_blog();
1732 + public function wp_delete_site($old_site) {
1733 + ud_stateless_db()->clear_db($old_site->id);
1615 1734 }
1616 1735
1617 1736 /**
1618 1737 * Redirect_to_splash
@@ -1618,16 +1737,16 @@
1618 1737 * Redirect_to_splash
1619 1738 *
1620 1739 * @param string $plugin
1621 1740 */
1622 - public function redirect_to_splash($plugin =''){
1741 + public function redirect_to_splash($plugin = '') {
1623 1742 // $this->settings = new Settings();
1624 1743
1625 - 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) {
1626 1745 return;
1627 1746 }
1628 1747
1629 - if(
1748 + if (
1630 1749 !$this->settings->get('sm.key_json') &&
1631 1750 defined('WP_STATELESS_MEDIA_HIDE_SETUP_ASSISTANT') && WP_STATELESS_MEDIA_HIDE_SETUP_ASSISTANT == true &&
1632 1751 defined('WP_STATELESS_MEDIA_HIDE_SETTINGS_PANEL') && WP_STATELESS_MEDIA_HIDE_SETTINGS_PANEL == true
1633 1752 ) {
@@ -1633,19 +1752,23 @@
1633 1752 ) {
1634 1753 return;
1635 1754 }
1636 1755
1637 - 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) {
1638 1757 $url = $this->get_settings_page_url('?page=stateless-settings');
1639 - exit( wp_redirect($url));
1758 + exit(wp_redirect($url));
1640 1759 }
1641 1760
1642 - if( $plugin == plugin_basename( $this->boot_file ) ) {
1643 - $url = $this->get_settings_page_url('?page=stateless-setup&step=splash-screen');
1644 - 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'))) {
1645 1767 $url = $this->get_settings_page_url('?page=stateless-settings');
1646 1768 }
1647 - exit( wp_redirect($url));
1769 +
1770 + exit( wp_redirect($url) );
1648 1771 }
1649 1772 }
1650 1773
1651 1774 /**
@@ -1651,24 +1774,25 @@
1651 1774 /**
1652 1775 * Plugin Deactivation
1653 1776 *
1654 1777 */
1655 - public function deactivate() {}
1778 + public function deactivate() {
1779 + }
1656 1780
1657 1781 /**
1658 1782 * Show_notice_stateless_cache_busting
1659 1783 *
1660 1784 */
1661 - public function show_notice_stateless_cache_busting(){
1662 - $this->errors->add( array(
1785 + public function show_notice_stateless_cache_busting() {
1786 + $this->errors->add(array(
1663 1787 'key' => 'stateless_cache_busting',
1664 1788 'button' => 'View Settings',
1665 1789 'button_link' => admin_url('upload.php?page=stateless-settings'),
1666 - 'title' => sprintf( __( "Stateless mode now requires the Cache-Busting option.", ud_get_stateless_media()->domain ) ),
1667 - 'message' => sprintf( __("WordPress looks at local files to prevent files with the same filenames.
1668 - 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.
1669 - 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" ),
1670 - ), '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');
1671 1795 }
1672 1796
1673 1797 /**
1674 1798 * Filter for wp_get_attachment_url();
@@ -1675,47 +1799,47 @@
1675 1799 * @param string $url
1676 1800 * @param string $post_id
1677 1801 * @return mixed|null|string
1678 1802 */
1679 - public function wp_get_attachment_url( $url = '', $post_id = '' ) {
1803 + public function wp_get_attachment_url($url = '', $post_id = '') {
1680 1804 global $default_dir;
1681 - $sm_cloud = get_post_meta( $post_id, 'sm_cloud', 1 );
1682 - if( is_array( $sm_cloud ) && !empty( $sm_cloud[ 'fileLink' ] ) ) {
1683 - $_url = parse_url($sm_cloud[ 'fileLink' ]);
1684 - $url = !isset($_url['scheme']) ? ( 'https:' . $sm_cloud[ 'fileLink' ] ) : $sm_cloud[ 'fileLink' ];
1685 - return apply_filters('wp_stateless_bucket_link', $url);
1686 - }
1687 - elseif(is_multisite() && empty($sm_cloud)){
1688 - $_file = get_post_meta( $post_id, '_wp_attached_file', true );
1689 - if($_file){
1690 - 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') {
1691 1814 $default_dir = true;
1692 1815 $uploads = wp_get_upload_dir();
1693 1816 $default_dir = false;
1694 - return $uploads['baseurl'].'/'.$_file;
1817 + $url = $uploads['baseurl'] . '/' . $_file;
1695 1818 } else {
1696 1819 $uploads = wp_get_upload_dir();
1697 1820 $default_dir = false;
1698 - $_file = apply_filters( 'wp_stateless_file_name', $_file, false );
1821 + $_file = apply_filters('wp_stateless_file_name', $_file, false);
1699 1822 $blog_id = get_current_blog_id();
1700 - $file_path_fix = $uploads[ 'basedir' ] . "/sites/$blog_id/$_file";
1823 + $file_path_fix = $uploads['basedir'] . "/sites/$blog_id/$_file";
1701 1824
1702 - if( file_exists( $file_path_fix ) ) {
1703 - $url = $uploads[ 'baseurl' ] . "/sites/$blog_id/$_file";
1825 + if (file_exists($file_path_fix)) {
1826 + $url = $uploads['baseurl'] . "/sites/$blog_id/$_file";
1704 1827 }
1705 1828 }
1706 1829 }
1707 - } elseif ( empty($sm_cloud) && $this->get('sm.mode') == 'stateless' ) {
1708 - $_file = get_post_meta( $post_id, '_wp_attached_file', true );
1709 - 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) {
1710 1833 $default_dir = true;
1711 1834 $uploads = wp_get_upload_dir();
1712 1835 $default_dir = false;
1713 1836
1714 - return $uploads['baseurl'].'/'.$_file;
1837 + $url = $uploads['baseurl'] . '/' . $_file;
1715 1838 }
1716 1839 }
1717 - return $url;
1840 +
1841 + return apply_filters('wp_stateless_attachment_url', $url, $post_id);
1718 1842 }
1719 1843
1720 1844 /**
1721 1845 * Filter for attachment_url_to_postid()
@@ -1723,22 +1847,29 @@
1723 1847 * @param int|false $post_id originally found post ID (or false if not found)
1724 1848 * @param string $url the URL to find the post ID for
1725 1849 * @return int|false found post ID from cloud storage URL
1726 1850 */
1727 - public function attachment_url_to_postid( $post_id, $url ) {
1851 + public function attachment_url_to_postid($post_id, $url) {
1728 1852 global $wpdb;
1729 1853
1730 - if ( ! $post_id ) {
1854 + if (!$post_id) {
1731 1855 $post_id = get_transient("stateless_url_to_postid_" . md5($url));
1732 1856
1733 - if(defined('WP_STATELESS_LEGACY_URL_TO_POSTID')){
1857 + if (defined('WP_STATELESS_LEGACY_URL_TO_POSTID')) {
1734 1858 // User can use this constant if they change the Bucket Folder (root_dir) after uploading image.
1735 1859 // This can be little slow at first run.
1736 - if(empty($post_id)){
1737 - $query = "SELECT post_id FROM $wpdb->postmeta WHERE meta_key = 'sm_cloud' AND meta_value LIKE '%s'";
1738 - $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 + }
1739 1870
1740 - if($post_id){
1871 + if ($post_id) {
1741 1872 set_transient("stateless_url_to_postid_" . md5($url), $post_id);
1742 1873 }
1743 1874 }
1744 1875 return $post_id;
@@ -1743,28 +1874,27 @@
1743 1874 }
1744 1875 return $post_id;
1745 1876 }
1746 1877
1747 - if(empty($post_id)){
1878 + if (empty($post_id)) {
1748 1879 $gs_base_url = $this->get_gs_host();
1749 - $root_dir = $this->get( 'sm.root_dir' );
1750 - $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);
1751 1882 $root_dir = apply_filters("wp_stateless_handle_root_dir", $root_dir, false, $path_elements);
1752 1883 $gs_url = $this->get_gs_host() . '/' . $root_dir;
1753 1884 $site_url = parse_url($gs_url);
1754 - $image_path = parse_url( $url );
1885 + $image_path = parse_url($url);
1755 1886
1756 1887 //force the protocols to match if needed
1757 - if( isset( $image_path['scheme'] ) && ( $image_path['scheme'] !== $site_url['scheme'] ) ) {
1758 - $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);
1759 1890 }
1760 1891
1761 - if( 0 === strpos( $url, $gs_url . '/' ) ) {
1762 - $url = substr( $url, strlen( $gs_url . '/' ) );
1763 - }
1764 - 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 . '/')) {
1765 1895 // In case user added Bucket Folder (root_dir) after uploading image.
1766 - $url = substr( $url, strlen( $gs_base_url . '/' ) );
1896 + $url = substr($url, strlen($gs_base_url . '/'));
1767 1897 }
1768 1898
1769 1899 /**
1770 1900 * If `uploads_use_yearmonth_folders` is set - adding year and month to url
@@ -1770,10 +1900,10 @@
1770 1900 * If `uploads_use_yearmonth_folders` is set - adding year and month to url
1771 1901 */
1772 1902 $organize_media = get_option('uploads_use_yearmonth_folders');
1773 1903 $path = '';
1774 - if ( $organize_media == '1' && isset ($path_elements['%date_year/date_month%']) ) {
1775 - $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%'] . '/';
1776 1906 }
1777 1907 $url = $path . $url;
1778 1908
1779 1909 $sql = $wpdb->prepare(
@@ -1779,11 +1909,11 @@
1779 1909 $sql = $wpdb->prepare(
1780 1910 "SELECT post_id FROM $wpdb->postmeta WHERE meta_key = '_wp_attached_file' AND meta_value = %s",
1781 1911 $url
1782 1912 );
1783 - $post_id = $wpdb->get_var( $sql );
1913 + $post_id = $wpdb->get_var($sql);
1784 1914
1785 - if($post_id){
1915 + if ($post_id) {
1786 1916 set_transient("stateless_url_to_postid_" . md5($url), $post_id);
1787 1917 }
1788 1918 }
1789 1919 }
@@ -1796,15 +1926,14 @@
1796 1926 *
1797 1927 * @param $data
1798 1928 * @return mixed
1799 1929 */
1800 - public function upload_dir( $data ) {
1801 - $data[ 'basedir' ] = $this->get_gs_host();
1802 - $data[ 'baseurl' ] = $this->get_gs_host();
1803 - $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'];
1804 1934
1805 1935 return $data;
1806 -
1807 1936 }
1808 1937
1809 1938 /**
1810 1939 * Set Feature Flag constants by parsing composer.json
@@ -1813,42 +1942,39 @@
1813 1942 *
1814 1943 * @author potanin@UD
1815 1944 * @return array|mixed|null|object
1816 1945 */
1817 - public function parse_feature_flags( ) {
1946 + public function parse_feature_flags() {
1818 1947
1819 1948 try {
1820 1949
1821 - $_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');
1822 1951
1823 - $_parsed = json_decode( $_raw );
1952 + $_parsed = json_decode($_raw);
1824 1953
1825 1954 // @todo Catch poorly formatted JSON.
1826 - if( !is_object( $_parsed ) ) {
1955 + if (!is_object($_parsed)) {
1827 1956 // throw new Error( "unable to parse." );
1828 1957 }
1829 1958
1830 - foreach( (array) $_parsed->extra->featureFlags as $_feature ) {
1959 + foreach ((array) $_parsed->extra->featureFlags as $_feature) {
1831 1960
1832 - if( !defined( $_feature->constant ) ) {
1833 - define( $_feature->constant, $_feature->enabled );
1961 + if (!defined($_feature->constant)) {
1962 + define($_feature->constant, $_feature->enabled);
1834 1963
1835 - if( $_feature->enabled ) {
1836 - Utility::log( 'Feature flag ' . $_feature->name . ', [' . $_feature->constant . '] enabled.' );
1964 + if ($_feature->enabled) {
1965 + Utility::log('Feature flag ' . $_feature->name . ', [' . $_feature->constant . '] enabled.');
1837 1966 } else {
1838 - Utility::log( 'Feature flag ' . $_feature->name . ', [' . $_feature->constant . '] disabled.' );
1967 + Utility::log('Feature flag ' . $_feature->name . ', [' . $_feature->constant . '] disabled.');
1839 1968 }
1840 1969 }
1841 -
1842 1970 }
1843 -
1844 - } catch ( \Exception $e ) {
1845 - 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() . ']');
1846 1973 // echo 'Caught exception: ', $e->getMessage(), "\n";
1847 1974 }
1848 1975
1849 - return isset( $_parsed ) ? $_parsed : null;
1850 -
1976 + return isset($_parsed) ? $_parsed : null;
1851 1977 }
1852 1978
1853 1979 /**
1854 1980 * Determine if Utility class contains missed function
@@ -1858,11 +1984,11 @@
1858 1984 * @param $name
1859 1985 * @param $arguments
1860 1986 * @return mixed|null
1861 1987 */
1862 - public function __call( $name, $arguments ) {
1863 - if( is_callable( array( "wpCloud\\StatelessMedia\\Utility", $name ) ) ) {
1864 - 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);
1865 1991 } else {
1866 1992 return NULL;
1867 1993 }
1868 1994 }
@@ -1875,35 +2001,120 @@
1875 2001 *
1876 2002 * @param boolean [$unset_disabled = true]
1877 2003 * @return array
1878 2004 */
1879 - function get_image_sizes( $unset_disabled = true ) {
1880 - $wais = & $GLOBALS['_wp_additional_image_sizes'];
2005 + function get_image_sizes($unset_disabled = true) {
2006 + $wais = &$GLOBALS['_wp_additional_image_sizes'];
1881 2007
1882 2008 $sizes = array();
1883 2009
1884 - foreach ( get_intermediate_image_sizes() as $_size ) {
1885 - if ( in_array( $_size, array('thumbnail', 'medium', 'medium_large', 'large') ) ) {
1886 - $sizes[ $_size ] = array(
1887 - 'width' => get_option( "{$_size}_size_w" ),
1888 - 'height' => get_option( "{$_size}_size_h" ),
1889 - '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"),
1890 2016 );
1891 - }
1892 - elseif ( isset( $wais[$_size] ) ) {
1893 - $sizes[ $_size ] = array(
1894 - 'width' => $wais[ $_size ]['width'],
1895 - 'height' => $wais[ $_size ]['height'],
1896 - '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'],
1897 2022 );
1898 2023 }
1899 2024
1900 2025 // size registered, but has 0 width and height
1901 - if( $unset_disabled && ($sizes[ $_size ]['width'] == 0) && ($sizes[ $_size ]['height'] == 0) )
1902 - unset( $sizes[ $_size ] );
2026 + if ($unset_disabled && ($sizes[$_size]['width'] == 0) && ($sizes[$_size]['height'] == 0))
2027 + unset($sizes[$_size]);
1903 2028 }
1904 2029
1905 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;
1906 2117 }
1907 2118 }
1908 2119 }
1909 2120 }