PluginProbe
Assistant – Every Day Productivity Apps / trunk
Assistant – Every Day Productivity Apps vtrunk
1.5.5 trunk 0.1.0 0.2.0 0.2.1 0.2.2 0.3.0 0.3.1 0.4 0.4.1 0.4.2 0.5.0 0.5.1 0.6.0 0.7.0 0.7.0.2 0.7.0.3 0.7.0.4 0.7.0.5 0.7.0.6 0.7.0.7 0.7.0.8 0.7.0.9 0.7.1 1.0 All 71 releases
assistant / backend / src / Services / MediaLibraryService.php

MediaLibraryService.php in Assistant – Every Day Productivity Apps trunk, at backend/src/Services/MediaLibraryService.php

219 lines 5.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace FL\Assistant\Services;
4
5 class MediaLibraryService {
6
7 /**
8 * Checks if a cloud media item was already imported.
9 *
10 * @param object $media
11 * @return int|null
12 */
13 public function is_cloud_media_imported( $media ) {
14 global $wpdb;
15
16 // Check if a file with this name and sha1 hash exists.
17 $media = (object) $media;
18 $parts = explode( '.', $media->file_name );
19 $name = array_shift( $parts );
20
21 $row = $wpdb->get_row(
22 $wpdb->prepare(
23 "SELECT * FROM $wpdb->posts
24 WHERE post_type = 'attachment'
25 AND post_name = %s",
26 $name
27 )
28 );
29
30 if ( $row ) {
31 $path = get_attached_file( $row->ID );
32 if ( $path && sha1_file( $path ) === $media->upload_hash ) {
33 return $row->ID;
34 }
35 }
36
37 // Check if we've already imported this file using the original sha1.
38 $row = $wpdb->get_row(
39 $wpdb->prepare(
40 "SELECT * FROM $wpdb->postmeta
41 WHERE meta_key = '_fl_asst_imported_media_hash'
42 AND meta_value = %s",
43 $media->upload_hash
44 )
45 );
46
47 return $row ? $row->post_id : null;
48 }
49
50 /**
51 * Import a cloud media item into the media library.
52 */
53 public function import_cloud_media( $media, $post_id = 0 ) {
54 $response = null;
55 $media = (object) $media;
56 $imported_id = $this->is_cloud_media_imported( $media );
57
58 if ( $imported_id ) {
59 return [
60 'id' => $imported_id,
61 'url' => wp_get_attachment_url( $imported_id ),
62 ];
63 }
64
65 switch ( $media->mime_type ) {
66 case 'image/jpg':
67 case 'image/jpeg':
68 case 'image/webp':
69 case 'image/png':
70 case 'image/gif':
71 case 'application/pdf':
72 case 'application/rtf':
73 case 'text/rtf':
74 $response = $this->import_file( $media->url, $media->file_name, $post_id );
75 break;
76 case 'image/svg':
77 case 'image/svg+xml':
78 $response = $this->import_svg( $media->url, $media->file_name, $post_id );
79 break;
80 }
81
82 if ( $response && isset( $response['id'] ) ) {
83 update_post_meta( $response['id'], '_fl_asst_imported_media_hash', $media->upload_hash );
84 }
85
86 return $response;
87 }
88
89 /**
90 * Import a file into the media library.
91 */
92 public function import_file( $url, $name, $post_id = 0 ) {
93 require_once( ABSPATH . 'wp-admin/includes/image.php' );
94 require_once( ABSPATH . 'wp-admin/includes/file.php' );
95 require_once( ABSPATH . 'wp-admin/includes/media.php' );
96
97 $url_filename = basename( parse_url( $url, PHP_URL_PATH ) );
98 $tmp_path = wp_tempnam( $url_filename );
99
100 if ( ! $tmp_path ) {
101 return [ 'error' => __( 'Error creating temp file.' ) ];
102 }
103
104 $response = wp_safe_remote_get(
105 $url,
106 [
107 'timeout' => 300,
108 'stream' => true,
109 'filename' => $tmp_path,
110 'sslverify' => false,
111 ]
112 );
113
114 $response_code = wp_remote_retrieve_response_code( $response );
115
116 if ( 200 !== intval( $response_code ) ) {
117 @unlink( $tmp_path );
118 return [ 'error' => __( 'Error downloading file.' ) ];
119 }
120
121 $id = media_handle_sideload(
122 [
123 'name' => sanitize_file_name( $name ),
124 'tmp_name' => $tmp_path,
125 ],
126 $post_id
127 );
128
129 if ( is_wp_error( $id ) ) {
130 @unlink( $tmp_path );
131 return [ 'error' => __( 'Error importing file.' ) ];
132 }
133
134 $alt_tag = $this->get_alt_tag_from_post_content( $post_id, $name );
135
136 if ( !empty( $alt_tag ) ) {
137 update_post_meta( $id, '_wp_attachment_image_alt', $alt_tag );
138 }
139
140 return [
141 'id' => $id,
142 'url' => wp_get_attachment_url( $id ),
143 ];
144 }
145
146 /**
147 * Get the alt tag for a filename from the post content.
148 */
149 public function get_alt_tag_from_post_content( $post_id, $filename ) {
150 $content = get_post_field( 'post_content', $post_id );
151 $alt_tag = null;
152
153 if ( !empty( $content ) ) {
154 $dom = new \DOMDocument();
155 @$dom->loadHTML( $content );
156 $images = $dom->getElementsByTagName( 'img' );
157
158 foreach ( $images as $image ) {
159 $src = $image->getAttribute( 'src' );
160 $src_filename = basename( parse_url( $src, PHP_URL_PATH ) );
161
162 // Remove dimensions to get the full size filename
163 preg_match_all( '/(-(\d+)x(\d+))\.(jpg|jpeg|png|gif|svg)/', $src_filename, $matches );
164
165 if ( isset( $matches[1] ) && ! empty( $matches[1] ) ) {
166 $src_filename = str_replace( $matches[1], '', $src_filename );
167 }
168
169 if ( $src_filename === $filename ) {
170 $alt_tag = $image->getAttribute( 'alt' );
171 break;
172 }
173 }
174 }
175
176 return $alt_tag;
177 }
178
179 /**
180 * Import an svg file into the media library.
181 */
182 public function import_svg( $url, $name, $post_id = 0 ) {
183 $this->add_svg_import_filters();
184 return $this->import_file( $url, $name, $post_id );
185 }
186
187 /**
188 * WP core media filters for allowing svg upload.
189 */
190 private function add_svg_import_filters() {
191 add_filter(
192 'upload_mimes', function( $mimes ) {
193 $mimes['svg'] = 'image/svg+xml';
194 $mimes['svgz'] = 'image/svg+xml';
195 return $mimes;
196 }, 99
197 );
198
199 add_filter(
200 'wp_check_filetype_and_ext', function ( $checked, $file, $filename, $mimes ) {
201 if ( ! $checked['type'] ) {
202 $check_filetype = wp_check_filetype( $filename, $mimes );
203 $ext = $check_filetype['ext'];
204 $type = $check_filetype['type'];
205 $proper_filename = $filename;
206
207 if ( $type && 0 === strpos( $type, 'image/' ) && 'svg' !== $ext ) {
208 $type = false;
209 $ext = false;
210 }
211
212 $checked = compact( 'ext', 'type', 'proper_filename' );
213 }
214 return $checked;
215 }, 10, 4
216 );
217 }
218 }
219