PluginProbe
Media Cloud Sync / 1.4.1
Media Cloud Sync v1.4.1
1.4.1 1.4.0 1.3.12 1.3.11 1.3.10 trunk 1.0.0 1.0.1 1.0.2 1.0.3 1.1.0 1.1.1 1.2.0 1.2.10 1.2.11 1.2.12 1.2.13 1.2.2 1.2.3 1.2.4 1.2.5 1.2.6 1.2.7 1.2.8 1.2.9 All 35 releases
media-cloud-sync / includes / integrations / woocommerce.php

woocommerce.php in Media Cloud Sync 1.4.1, at includes/integrations/woocommerce.php

211 lines 6.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 namespace Dudlewebs\WPMCS;
3
4 defined('ABSPATH') || exit;
5
6 /**
7 * WooCommerce Compatibility.
8 *
9 * @since 1.3.7
10 */
11 if ( ! class_exists( 'WooCommerce' ) ) {
12 return;
13 }
14
15 class WooCommerce {
16 /**
17 * The singleton instance.
18 *
19 * @since 1.3.7
20 * @var WooCommerce|null
21 */
22 protected static $instance = null;
23
24 /**
25 * The image size WooCommerce is currently regenerating, captured via
26 * `intermediate_image_sizes` so the reupload can be scoped to just that size.
27 *
28 * @since 1.4.0
29 * @var string|null
30 */
31 protected $regenerating_size = null;
32
33 /**
34 * Whether the `intermediate_image_sizes` capture hook has been armed.
35 *
36 * @since 1.4.0
37 * @var bool
38 */
39 protected $size_capture_hooked = false;
40
41 /**
42 * The class constructor.
43 *
44 * @since 1.3.7
45 */
46 protected function __construct() {
47 $this->init();
48 }
49
50 /**
51 * Launch the hooks.
52 *
53 * @since 1.3.7
54 */
55 public function init() {
56 /******** FIX Size updation in WooCommerce Customizer *****/
57 // Return File path for WooCommerce image resizing to prevent url being used and causing issues with image regeneration.
58 add_filter( 'woocommerce_resize_images', [ $this, 'resize_images' ] );
59
60 // Restore the file from cloud (if missing) and return the local path during
61 // WooCommerce's on-the-fly image regeneration.
62 add_filter( 'wpmcs_get_attached_file', array( $this, 'get_attached_file' ), 10, 4 );
63
64 // Force a reupload of just the size WooCommerce is regenerating — same name/
65 // dimensions as an existing size, but different crop, so the normal
66 // "unchanged, skip reupload" check can't tell it apart from a real no-op.
67 add_filter( 'wpmcs_do_reupload_media', array( $this, 'force_reupload_during_regeneration' ), 10, 3 );
68 /******* End Fix Size updation in WooCommerce Customizer */
69 }
70
71
72 /**
73 * Resize images for WooCommerce.
74 * Used to add a filter to return the file path instead of the URL for WooCommerce image resizing,
75 * to prevent issues with image regeneration when using cloud storage.
76 *
77 * WooCommerce fires 'woocommerce_resize_images' unconditionally from
78 * maybe_resize_image(), which itself runs on every wp_get_attachment_image_src()
79 * call for any size — not just when an actual WooCommerce resize is about to
80 * happen. resize_and_return_image() (the method that genuinely needs the local
81 * path) hasn't been called yet at this point, so is_called_from() would always
82 * be false if checked here. The added filter must instead check at the time it's
83 * actually invoked — otherwise it permanently returns the local path for every
84 * wpmcs_get_attached_file call for the rest of the request, once any image has
85 * rendered anywhere (confirmed live: this broke the unrelated BuddyBoss
86 * regenerate-thumbnails restore window entirely).
87 *
88 * @param bool $resize Whether to resize images or not.
89 * @return bool The modified value of $resize.
90 * @since 1.3.7
91 */
92 public function resize_images( $resize ) {
93 add_filter( 'wpmcs_get_attached_file', function ($url, $file, $attachment_id, $item) {
94 if ( ! Utils::is_called_from( 'WC_Regenerate_Images', 'resize_and_return_image' ) ) {
95 return $url;
96 }
97 return $file;
98 }, 10, 4 );
99
100 return $resize;
101 }
102
103 /**
104 * Restore the file from cloud (all registered sizes, not just this one — the
105 * source may be needed at other sizes too) and return the local path during
106 * WooCommerce's on-the-fly image regeneration.
107 *
108 * @param string $url The original file URL.
109 * @param string $file The file path.
110 * @param int $attachment_id The attachment ID.
111 * @param array $item The item data associated with the attachment.
112 * @return string The modified file URL.
113 * @since 1.3.7
114 */
115 public function get_attached_file( $url, $file, $attachment_id, $item ) {
116 if ( ! Utils::is_called_from( 'WC_Regenerate_Images', 'resize_and_return_image' ) ) {
117 return $url;
118 }
119
120 // Always attempted, not gated on $file specifically being missing —
121 // move_to_server_by_key_and_path() already no-ops per-file on file_exists(),
122 // and gating here would leave OTHER missing sizes unrestored, which then get
123 // silently dropped (not just skipped) if a reupload is later forced without
124 // a local file present.
125 $results = Item::instance()->moveToServerByItem( $item, 'full', true );
126
127 if ( is_array( $results ) && ! empty( $results ) ) {
128 Item::instance()->track_restored_for_cleanup( array_values( $results ) );
129 }
130
131 $this->capture_regenerating_size();
132
133 return $file;
134 }
135
136 /**
137 * Arms a one-time `intermediate_image_sizes` capture so the exact size
138 * WooCommerce is regenerating is known when `wpmcs_do_reupload_media` fires.
139 * Priority 20 — after WooCommerce's own `adjust_intermediate_image_sizes`
140 * (default priority 10) has already narrowed the array to that one size.
141 *
142 * @return void
143 * @since 1.4.0
144 */
145 protected function capture_regenerating_size() {
146 if ( $this->size_capture_hooked ) {
147 return;
148 }
149 $this->size_capture_hooked = true;
150
151 add_filter( 'intermediate_image_sizes', function ( $sizes ) {
152 if ( is_array( $sizes ) && 1 === count( $sizes ) ) {
153 $this->regenerating_size = reset( $sizes );
154 }
155 return $sizes;
156 }, 20 );
157 }
158
159 /**
160 * Force a reupload of just the size WooCommerce is regenerating — an existing
161 * registered size with a different crop, which the normal same-name/dimensions
162 * check can't otherwise tell apart from an unchanged file.
163 *
164 * @param bool|array $do_reupload
165 * @param int $attachment_id
166 * @param string $source_type
167 * @return bool|array
168 * @since 1.4.0
169 */
170 public function force_reupload_during_regeneration( $do_reupload, $attachment_id, $source_type ) {
171 if ( true === $do_reupload || empty( $this->regenerating_size ) ) {
172 return $do_reupload;
173 }
174
175 $size = $this->regenerating_size;
176 $this->regenerating_size = null;
177
178 return array( $size );
179 }
180
181 /**
182 * Is installed?
183 *
184 * @return bool
185 */
186 public static function is_installed(): bool {
187 // Check if WooCommerce plugin defines its main constant.
188 if ( defined( 'WC_ABSPATH' ) ) {
189 return true;
190 }
191
192 // Alternative: check for WooCommerce version constant.
193 if ( defined( 'WC_VERSION' ) ) {
194 return true;
195 }
196
197 return false;
198 }
199
200 /**
201 * Singleton instance
202 */
203 public static function instance() {
204 if (is_null(self::$instance)) {
205 self::$instance = new self();
206 }
207
208 return self::$instance;
209 }
210 }
211