PluginProbe
Media Cloud Sync / 1.3.10
Media Cloud Sync v1.3.10
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 1.3.0 All 34 releases
media-cloud-sync / includes / integrations / acf.php

acf.php in Media Cloud Sync 1.3.10, at includes/integrations/acf.php

275 lines 7.0 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 use DirectoryIterator;
7 use Exception;
8
9 class Acf {
10 private static $instance = null;
11 private $assets_url;
12 private $version;
13 private $token;
14
15 protected $settings;
16 protected $content_filter;
17 protected $compatibility;
18
19 /**
20 * Admin constructor.
21 * @since 1.0.0
22 */
23 private function __construct() {
24 $this->assets_url = WPMCS_ASSETS_URL;
25 $this->version = WPMCS_VERSION;
26 $this->token = WPMCS_TOKEN;
27 $this->settings = Utils::get_settings();
28 $this->content_filter = FilterContent::instance();
29 $this->compatibility = Compatibility::instance();
30
31 if (self::is_installed()) {
32 // Register actions
33 $this->registerActions();
34 }
35 }
36
37 /**
38 * Register integration access
39 * @since 1.0.0
40 * @access public
41 *
42 * @return void
43 */
44 public function registerActions() {
45 /*
46 * Content Filtering
47 */
48
49 add_filter( 'acf/load_value/type=text', array( $this->content_filter, 'filter_post' ) );
50 add_filter( 'acf/load_value/type=textarea', array( $this->content_filter, 'filter_post' ) );
51 add_filter( 'acf/load_value/type=wysiwyg', array( $this->content_filter, 'filter_post' ) );
52 add_filter( 'acf/load_value/type=url', array( $this->content_filter, 'filter_post' ) );
53 add_filter( 'acf/load_value/type=link', array( $this, 'filter_link_server' ) );
54 add_filter( 'acf/update_value/type=text', array( $this->content_filter, 'filter_post_backward' ) );
55 add_filter( 'acf/update_value/type=textarea', array( $this->content_filter, 'filter_post_backward' ) );
56 add_filter( 'acf/update_value/type=wysiwyg', array( $this->content_filter, 'filter_post_backward' ) );
57 add_filter( 'acf/update_value/type=url', array( $this->content_filter, 'filter_post_backward' ) );
58 add_filter( 'acf/update_value/type=link', array( $this, 'filter_link_provider' ) );
59
60 /*
61 * Image Crop Add-on
62 * https://en-gb.wordpress.org/plugins/acf-image-crop-add-on/
63 */
64 if ( class_exists( 'acf_field_image_crop' ) ) {
65 add_filter( 'wp_get_attachment_metadata', array( $this, 'download_image' ), 10, 2 );
66 add_filter( 'sanitize_file_name', array( $this, 'remove_original_after_download' ) );
67 }
68
69 /*
70 * Rewrite URLs in field and field group config.
71 */
72 add_filter( 'acf/load_fields', array( $this, 'acf_load_config' ) );
73 add_filter( 'acf/load_field_group', array( $this, 'acf_load_config' ) );
74 }
75
76 /**
77 * Rewrites URLs from server to remote inside ACF field and field group config. If the
78 * rewriting process fails, it will return the original config.
79 *
80 * @handles acf/load_fields
81 * @handles acf/load_field_group
82 *
83 * @param array $config
84 *
85 * @return array
86 */
87 public function acf_load_config( array $config ): array {
88 try {
89 $filtered_config = Utils::maybe_unserialize( $this->content_filter->filter_post( Utils::maybe_serialize( $config ) ) );
90 } catch ( Exception $e ) {
91 return $config;
92 }
93
94 return is_array( $filtered_config ) ? $filtered_config : $config;
95 }
96
97 /**
98 * Remove the original image downloaded for the cropping after it has been processed
99 *
100 * @param string $filename
101 *
102 * @return mixed
103 */
104 public function remove_original_after_download( $filename ) {
105 $this->maybe_remove_original_after_download();
106
107 return $filename;
108 }
109
110 /**
111 * Remove the original image from the server
112 *
113 * @return bool|WP_Error
114 */
115 public function maybe_remove_original_after_download() {
116 if ( false === $this->compatibility->maybe_process_on_action( 'acf_image_crop_perform_crop', true ) ) {
117 return false;// Not ACF crop process
118 }
119
120 $original_attachment_id = Utils::filter_input( 'id', INPUT_POST, FILTER_VALIDATE_INT );
121
122 if ( ! isset( $original_attachment_id ) ) {
123 // Can't find the original attachment id
124 return false; // Attachment ID not available
125 }
126
127 $item = Item::instance()->get( $original_attachment_id );
128
129 if ( ! $item ) {
130 return false; //Attachment not offloaded
131 }
132
133 if ( ! Utils::get_meta($original_attachment_id, 'acf_cropped_to_remove', false) ) {
134 // Original attachment should exist serverly, no need to delete
135 return false; //Attachment not to be removed from server
136 }
137
138 // Remove the original file from the server
139 Item::instance()->may_be_delete_server_files_by_id($original_attachment_id, true);
140
141 // Remove marker
142 Utils::delete_meta($original_attachment_id, 'acf_cropped_to_remove');
143
144 return true;
145 }
146
147
148
149 /**
150 * Copy back the S3 image for cropping
151 *
152 * @param array $data
153 * @param int $post_id
154 *
155 * @return array
156 */
157 public function download_image( $data, $post_id ) {
158 $this->maybe_download_image( $post_id );
159
160 return $data;
161 }
162
163
164 /**
165 * Copy back the S3 image
166 *
167 * @param int $post_id
168 *
169 * @return bool|WP_Error
170 */
171 public function maybe_download_image( $post_id ) {
172 if ( false === $this->compatibility->maybe_process_on_action( 'acf_image_crop_perform_crop', true ) ) {
173 return false; // Skip not a proper action
174 }
175
176 $file = get_attached_file( $post_id, true );
177
178 if ( file_exists( $file ) ) {
179 return false; // skip file already exist
180 }
181
182 $item = Item::instance()->get( $post_id );
183
184 if ( ! $item ) {
185 return false; // Failed not offloaded
186 }
187
188 $callers = debug_backtrace(); // phpcs:ignore
189 foreach ( $callers as $caller ) {
190 if ( isset( $caller['function'] ) && 'image_downsize' === $caller['function'] ) {
191 // Don't copy when downsizing the image, which would result in bringing back
192 // the newly cropped image from S3.
193 return false; // 'Skip when Copying back cropped file'
194 }
195 }
196
197 // Copy back the original file for cropping
198 $result = $this->compatibility->copy_provider_file_to_server( $post_id, $file );
199
200 if ( false === $result ) {
201 return false; //Copy back failed
202 }
203
204 // Mark the attachment so we know to remove it later after the crop
205 Utils::update_meta($post_id, 'acf_cropped_to_remove', true);
206
207 return true;
208 }
209
210
211 /**
212 * Filter a link field's URL from server to provider.
213 *
214 * @param array $link
215 *
216 * @return array
217 */
218 public function filter_link_server( $link ) {
219 if ( is_array( $link ) && ! empty( $link['url'] ) ) {
220 $url = $this->content_filter->filter_post( $link['url'] );
221
222 if ( ! empty( $url ) ) {
223 $link['url'] = $url;
224 }
225 }
226
227 return $link;
228 }
229
230
231 /**
232 * Filter a link field's URL from provider to server.
233 *
234 * @param array $link
235 *
236 * @return array
237 */
238 public function filter_link_provider( $link ) {
239 if ( is_array( $link ) && ! empty( $link['url'] ) ) {
240 $url = $this->content_filter->filter_post_backward( $link['url'] );
241
242 if ( ! empty( $url ) ) {
243 $link['url'] = $url;
244 }
245 }
246
247 return $link;
248 }
249
250
251 /**
252 * Is installed?
253 *
254 * @return bool
255 */
256 public static function is_installed(): bool {
257 if ( class_exists( 'acf', false ) ) {
258 return true;
259 }
260
261 return false;
262 }
263
264 /**
265 * Singleton instance
266 */
267 public static function instance() {
268 if (is_null(self::$instance)) {
269 self::$instance = new self();
270 }
271
272 return self::$instance;
273 }
274 }
275