PluginProbe
Search Atlas SEO – OTTO AI SEO Automation for WordPress / 2.6.21
Search Atlas SEO – OTTO AI SEO Automation for WordPress v2.6.21
2.6.26 2.6.25 2.6.24 2.6.23 2.6.22 2.6.21 2.6.20 2.6.19 2.6.18 2.6.17 2.6.16 2.6.15 2.6.14 2.6.13 2.6.12 2.6.11 2.6.10 2.6.9 2.6.8 2.6.7 2.6.6 2.6.5 2.6.4 2.6.3 2.5.23 All 138 releases
metasync / includes / class-metasync-common.php

class-metasync-common.php in Search Atlas SEO – OTTO AI SEO Automation for WordPress 2.6.21, at includes/class-metasync-common.php

280 lines 8.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 /**
4 * The database operations for the 404 error monitor.
5 *
6 * @since 1.0.0
7 * @package Metasync
8 * @subpackage Metasync/404-monitor
9 * @author Engineering Team <support@searchatlas.com>
10 */
11 class Metasync_Common
12 {
13 /**
14 * Sanitize a array with urls and text field.
15 * @param $data Pass a Array.
16 */
17 public function sanitize_array($data)
18 {
19 // Ensure $data is always an array from the start
20 if (!is_array($data)) {
21 $data = (array) $data;
22 }
23
24 foreach ($data as $key => $value) {
25 if (is_array($value) && !empty($value)) {
26 $data[$key] = $this->sanitize_array($value);
27 } else {
28 if ($value) {
29 // Ensure $value is a string before processing
30 if (!is_string($value) && !is_numeric($value)) {
31 $value = (string) $value;
32 }
33
34 if (filter_var($value, FILTER_VALIDATE_URL)) {
35 $data[$key] = sanitize_url($value);
36 } else {
37 $data[$key] = sanitize_text_field($value);
38 }
39 }
40 }
41 }
42 return $data;
43 }
44
45 /**
46 * Get post by post name.
47 * @param $attachment_name Attachment name will be string.
48 */
49 public function get_attachment_by_name($attachment_name)
50 {
51 global $wpdb;
52 $post = $wpdb->get_row(
53 $wpdb->prepare(
54 "SELECT * FROM $wpdb->posts WHERE `post_name` = %s and `post_type` = 'attachment' LIMIT 1",
55 $attachment_name
56 )
57 );
58 return get_post($post);
59 }
60
61 public function get_permalink_from_url($url)
62 {
63 $parse_url = wp_parse_url($url);
64 $path = isset($parse_url['path']) ? $parse_url['path'] : '';
65 return end(array_diff(explode('/', $path), array('')));
66 }
67
68 /**
69 * Get file name from a URL.
70 * @param $url Valid URL as string.
71 */
72 public function get_file_name_by_url($url)
73 {
74 if (stripos($url, "https://cdn.midjourney.com/") !== false) {
75 return pathinfo(str_replace("/", "_", parse_url($url, PHP_URL_PATH) ?? ''), PATHINFO_FILENAME);
76 } elseif (stripos($url, "https://drive.google.com/") !== false) {
77 $parse_url = wp_parse_url($url);
78 $args = [];
79 wp_parse_str($parse_url['query'], $args);
80 return $args['id'];
81 } else {
82 return pathinfo(parse_url($url, PHP_URL_PATH), PATHINFO_FILENAME);
83 }
84 }
85
86 public function allowedDownloadSources($url)
87 {
88 return false;
89 $allowed_sources = array(
90 "https://storage.googleapis.com",
91 "https://drive.google.com"
92 );
93 foreach ($allowed_sources as $source) {
94 if (stripos($url, $source) !== false)
95 return true;
96 }
97 return false;
98 }
99
100 public function get_media_id_from_url($url) {
101 global $wpdb;
102
103 // Search for any attachment matching the URL
104 $query = $wpdb->prepare("
105 SELECT ID
106 FROM $wpdb->posts
107 WHERE post_type = 'attachment'
108 AND guid = %s
109 LIMIT 1
110 ", $url);
111
112 $attachment_id = $wpdb->get_var($query);
113
114 // Return the attachment ID if found, otherwise return false
115 return $attachment_id ? intval($attachment_id) : false;
116 }
117 /**
118 * Upload image to media library if URL is valid.
119 * @param $url Valid URL.
120 * add title to the image default value value is empty string
121 */
122 public function upload_image_by_url($url,$alt='',$title_text='')
123 {
124 require_once(ABSPATH . "/wp-load.php");
125 require_once(ABSPATH . "/wp-admin/includes/image.php");
126 require_once(ABSPATH . "/wp-admin/includes/file.php");
127 require_once(ABSPATH . "/wp-admin/includes/media.php");
128
129 $tmp = download_url($url);
130 if (is_wp_error($tmp)){
131 $attachment_id = $this->get_media_id_from_url($url);
132 error_log($attachment_id);
133 return $attachment_id;
134 }
135
136 $filename = $this->get_file_name_by_url($url);
137 // $filename = pathinfo($url, PATHINFO_FILENAME);
138 // eliminating query params from file name
139 $filename = explode("?", $filename)[0];
140 $extension = pathinfo($url, PATHINFO_EXTENSION);
141
142 if (!$extension || strlen($extension) > 4) {
143 // fileinfo extension is not always enabled on shared hosts — guard the call
144 // and fall back to WordPress's extension-based detection.
145 if (function_exists('mime_content_type')) {
146 $mime = mime_content_type($tmp);
147 } else {
148 $filetype = wp_check_filetype(basename($url));
149 $mime = $filetype['type'] ?? false;
150 }
151 $mime = is_string($mime) ? sanitize_mime_type($mime) : false;
152
153 $mime_extensions = array(
154 'image/jpe' => 'jpe',
155 'image/jpg' => 'jpg',
156 'image/jpeg' => 'jpeg',
157 'image/gif' => 'gif',
158 'image/png' => 'png',
159 'image/webp' => 'webp'
160 );
161
162 if (isset($mime_extensions[$mime])) {
163 $extension = $mime_extensions[$mime];
164 } else {
165 // Safely delete temporary file if it exists
166 if (file_exists($tmp)) {
167 unlink($tmp);
168 }
169 return false;
170 }
171 }
172
173 $args = array(
174 'name' => "$filename.$extension",
175 /*
176 Generate a sanitized post_name by replacing double dashes with a single dash
177 and appending the file extension with a hyphen
178 */
179 'post_name' => str_replace('--', '-', $filename ?? '') ."-".$extension,
180 'tmp_name' => $tmp,
181 );
182
183 $get_attachment = $this->get_attachment_by_name($args['post_name']);
184
185 # remove if null logic check on 11 march 2025 for issue 264 and merge request 320
186 if (empty($get_attachment)) {
187 $attachment_id = media_handle_sideload($args, 0, $args['name']);
188 update_post_meta($attachment_id, '_wp_attachment_image_alt', $alt);
189 // check if the title is empty or not if it's has title update the title
190 if($title_text !== ''){
191 wp_update_post(
192 array (
193 'ID' => $attachment_id,
194 'post_title' => $title_text
195 )
196 );
197 }
198 $attach_data = wp_generate_attachment_metadata(
199 $attachment_id,
200 wp_get_original_image_path($attachment_id)
201 );
202 wp_update_attachment_metadata($attachment_id, $attach_data);
203
204 // Safely delete temporary file if it exists
205 if (file_exists($tmp)) {
206 unlink($tmp);
207 }
208
209 if (is_wp_error($attachment_id)) return false;
210 return $attachment_id;
211 } else {
212 // An attachment record can outlive its file (e.g. the file was
213 // deleted from disk outside WordPress). Since we already have a
214 // fresh download, restore it into the existing attachment so its
215 // URL stops 404ing — reusing the record keeps post references
216 // intact and avoids piling up duplicate attachments.
217 $existing_file = get_attached_file($get_attachment->ID);
218 if (empty($existing_file) || !file_exists($existing_file)) {
219 // wp_handle_sideload() takes $file by reference, so the
220 // argument must be a variable — a literal array here is a
221 // runtime fatal that kills the whole sync request.
222 $file_array = array(
223 'name' => $args['name'],
224 'tmp_name' => $tmp,
225 );
226 $upload = wp_handle_sideload($file_array, array('test_form' => false));
227 if (empty($upload['error']) && !empty($upload['file'])) {
228 update_attached_file($get_attachment->ID, $upload['file']);
229 $attach_data = wp_generate_attachment_metadata($get_attachment->ID, $upload['file']);
230 wp_update_attachment_metadata($get_attachment->ID, $attach_data);
231 }
232 }
233
234 // Delete the temporary file unless the sideload above moved it
235 if (file_exists($tmp)) {
236 unlink($tmp);
237 }
238
239 // check if the title attribute is set on the image tag and then update the title
240 if($title_text !== ''){
241 wp_update_post(
242 array (
243 'ID' => $get_attachment->ID,
244 'post_title' => $title_text
245 )
246 );
247 }
248 // update the alt attribute in the image
249 update_post_meta($get_attachment->ID, '_wp_attachment_image_alt', $alt);
250 return $get_attachment->ID;
251 }
252 }
253 /**
254 * Check if Gutenberg is enabled as the default page editor
255 */
256 protected function is_gutenberg_enabled() {
257 $current_screen = get_current_screen();
258 return method_exists($current_screen, 'is_block_editor') && $current_screen->is_block_editor();
259 }
260 /**
261 * Check if Elementor is active
262 */
263 protected function is_elementor_active() {
264 return class_exists('Elementor\Plugin') && \Elementor\Plugin::$instance->preview->is_preview_mode();
265 }
266 /**
267 * Check if Gutenberg is enabled or Elementor is active
268 */
269 public static function check_default_page_editor() {
270 $instance = new self();
271 if ($instance->is_gutenberg_enabled()) {
272 return 'gutenberg';
273 } elseif ($instance->is_elementor_active()) {
274 return 'elementor';
275 } else {
276 return 'neither';
277 }
278 }
279 }
280