PluginProbe ʕ •ᴥ•ʔ
Presto Player / 4.3.0
Presto Player v4.3.0
4.3.0 4.2.4 4.2.3 4.2.2 4.2.0 4.2.1 trunk 1.10.0 1.10.1 1.10.2 1.11.0 1.12.0 1.13.0 1.14.0 1.14.1 1.5.10 1.5.11 1.5.12 1.5.13 1.5.14 1.5.15 1.5.5 1.5.6 1.5.7 1.5.8 1.5.9 1.6.0 1.6.1 1.6.10 1.6.11 1.6.12 1.6.13 1.6.2 1.6.3 1.6.4 1.6.5 1.6.6 1.6.7 1.6.8 1.6.9 1.7.0 1.7.1 1.7.2 1.8.0 1.8.1 1.8.2 1.8.3 1.8.4 1.8.5 1.8.6 1.9.0 1.9.1 1.9.10 1.9.11 1.9.12 1.9.13 1.9.14 1.9.2 1.9.3 1.9.4 1.9.5 1.9.6 1.9.7 1.9.8 1.9.9 2.0.0 2.0.1 2.0.10 2.0.11 2.0.12 2.0.13 2.0.14 2.0.15 2.0.16 2.0.2 2.0.3 2.0.4 2.0.5 2.0.6 2.0.7 2.0.8 2.0.9 2.1.0 2.2.0 2.2.1 2.2.2 2.2.3 2.2.3-beta1 2.3.0 2.3.1 2.3.2 2.3.3 3.0.0 3.0.0-beta1 3.0.1 3.0.2 3.0.3 3.0.4 3.0.5 3.0.6 3.0.7 3.0.8 3.1.0 3.1.1 3.1.2 3.1.3 4.0.0 4.0.1 4.0.2 4.0.3 4.0.4 4.0.5 4.0.6 4.0.7 4.0.8 4.1.0 4.1.1 4.1.2 4.1.3 4.1.4
presto-player / inc / Files.php
presto-player / inc Last commit date
Blocks 2 days ago Contracts 1 year ago Database 1 week ago Integrations 1 week ago Libraries 1 week ago Models 1 week ago Seeds 1 year ago Services 2 days ago Support 1 week ago config 1 week ago lib 1 month ago Activator.php 1 month ago Attachment.php 1 week ago Controller.php 1 year ago Core.php 1 year ago Deactivator.php 2 months ago Factory.php 3 months ago Files.php 1 week ago Playlist.php 1 year ago Plugin.php 1 month ago Requirements.php 1 year ago support.php 1 week ago
Files.php
314 lines
1 <?php
2 /**
3 * Handles private media files and attachment query filtering.
4 *
5 * @package PrestoPlayer
6 */
7
8 namespace PrestoPlayer;
9
10 use PrestoPlayer\Attachment;
11
12 /**
13 * Manages the private uploads folder and filters attachment queries.
14 */
15 class Files {
16
17 /**
18 * Allowed ip addresses to private folder
19 *
20 * @var array
21 */
22 protected $allowed_ips = array();
23
24 /**
25 * Privat folder name
26 *
27 * @var string
28 */
29 protected $private_folder = 'presto-player-private';
30
31 /**
32 * Store allowed ips and let user filter private folder
33 */
34 public function __construct() {
35 $this->allowed_ips = include PRESTO_PLAYER_PLUGIN_DIR . '/inc/Libraries/BunnyCDNIPs.php';
36 $this->private_folder = apply_filters( 'presto_player_private_foldername', $this->private_folder );
37 }
38
39 /**
40 * Gets the list of allowed IP addresses for the private folder.
41 *
42 * @return array List of allowed IP addresses.
43 */
44 public function getAllowedIPs() {
45 return $this->allowed_ips;
46 }
47
48 /**
49 * Register actions and filters.
50 *
51 * @return self The current instance.
52 */
53 public function register() {
54 add_filter( 'upload_dir', array( $this, 'mediaUploadFolder' ) );
55 add_filter( 'wp_prepare_attachment_for_js', array( $this, 'galleryLabel' ) );
56 add_filter( 'wp_generate_attachment_metadata', array( $this, 'privateMeta' ), 10, 2 );
57 add_action( 'ajax_query_attachments_args', array( $this, 'hidePrivate' ) );
58
59 return $this;
60 }
61
62 /**
63 * Gets a public or private type
64 *
65 * @return string
66 */
67 public function getVideoType() {
68 $query = array();
69 $url = (string) wp_get_raw_referer();
70 $parts = wp_parse_url( $url );
71 isset( $parts['query'] ) ? parse_str( $parts['query'], $query ) : '';
72 $type = isset( $query['presto_video_type'] ) ? $query['presto_video_type'] : '';
73 return is_string( $type ) ? sanitize_key( $type ) : '';
74 }
75
76 /**
77 * Hides external attachment items from ajax query.
78 *
79 * @param array $query Query arguments for the attachments query.
80 * @return array Modified query arguments.
81 */
82 public function hideAjaxExternalVideos( $query ) {
83 $query['meta_query'] = array(
84 'relation' => 'OR',
85 array(
86 'key' => 'presto_external_id',
87 'compare' => 'NOT EXISTS', // works!
88 ),
89 );
90
91 return $query;
92 }
93
94 /**
95 * Hide external videos on attachment page.
96 *
97 * @param \WP_Query $query The current attachments query.
98 * @return void
99 */
100 public function hideExternalVideos( $query ) {
101 global $pagenow;
102
103 // Disable on uploads page.
104 if ( 'upload.php' !== $pagenow ) {
105 return;
106 }
107
108 // Allow filter to fetch.
109 if ( apply_filters( 'presto_player_get_external_attachments', false ) ) {
110 return;
111 }
112
113 $query->set(
114 'meta_query',
115 array(
116 'relation' => 'OR',
117 array(
118 'key' => 'presto_external_id',
119 'compare' => 'NOT EXISTS', // works!
120 'value' => '', // This is ignored, but is necessary...
121 ),
122 )
123 );
124 }
125
126 /**
127 * Hides private/public items based on video type query.
128 *
129 * @param array $query Query arguments for the attachments query.
130 * @return array Modified query arguments.
131 */
132 public function hidePrivate( $query ) {
133 $type = $this->getVideoType();
134
135 switch ( $type ) {
136 case 'public': // Public only, don't show private.
137 $query['meta_query'] = array(
138 array(
139 'relation' => 'AND',
140 array(
141 'key' => 'presto_external_id',
142 'compare' => 'NOT EXISTS', // works!
143 'value' => '', // This is ignored, but is necessary...
144 ),
145 array(
146 'relation' => 'OR',
147 array(
148 'key' => 'presto-private-video',
149 'compare' => 'NOT EXISTS', // works!
150 'value' => '', // This is ignored, but is necessary...
151 ),
152 array(
153 'key' => 'presto-private-video',
154 'value' => false,
155 ),
156 ),
157 ),
158 );
159 break;
160 case 'private': // Private only.
161 $query['meta_query'] = array(
162 array(
163 'relation' => 'AND',
164 array(
165 'key' => 'presto_external_id',
166 'compare' => 'NOT EXISTS', // works!
167 'value' => '', // This is ignored, but is necessary...
168 ),
169 array(
170 'key' => 'presto-private-video',
171 'value' => true,
172 ),
173 ),
174 );
175 break;
176 }
177
178 return $query;
179 }
180
181 /**
182 * Add meta data to attachment so WP knows it's private.
183 *
184 * @param array $data Attachment metadata.
185 * @param int $id Attachment ID.
186 * @return array Attachment metadata.
187 */
188 public function privateMeta( $data, $id ) {
189 if ( Attachment::isPrivate( $id ) ) {
190 update_post_meta( $id, 'presto-private-video', true );
191 }
192
193 return $data;
194 }
195
196
197 /**
198 * Change media uploader folder only in case of private files.
199 *
200 * @param array $data Upload directory data.
201 * @return array Modified upload directory data.
202 */
203 public function mediaUploadFolder( $data ) {
204 if ( $this->getVideoType() === 'private' ) {
205 $data['path'] = $data['basedir'] . '/' . $this->private_folder;
206 $data['url'] = $data['baseurl'] . '/' . $this->private_folder;
207 $data['subdir'] = $this->private_folder;
208 }
209
210 return $data;
211 }
212
213 /**
214 * If the media is into private folder change response to show.
215 *
216 * @param array $response Attachment data prepared for JavaScript.
217 * @return array Modified attachment data.
218 */
219 public function galleryLabel( $response ) {
220 if ( strpos( $response['url'], $this->private_folder ) !== false || strpos( $response['url'], 'video-src' ) !== false || strpos( $response['url'], 'presto-player-token' ) !== false ) {
221 $response['filename'] = __( 'Private: ', 'presto-player' ) . $response['filename'];
222 }
223
224 return $response;
225 }
226
227 /**
228 * Adds the private folder
229 *
230 * @return void
231 */
232 public function addPrivateFolder() {
233 \WP_Filesystem();
234 global $wp_filesystem;
235
236 $private_folder = $this->makeFolder( $wp_filesystem, apply_filters( 'presto_player_private_folder_name', $this->private_folder ) );
237 $this->setHtaccess( $wp_filesystem, $private_folder );
238
239 if ( ! empty( $wp_filesystem->errors->errors ) ) {
240 add_action( 'admin_notices', array( $this, 'errorNotice' ) );
241 }
242 }
243
244 /**
245 * Show an error notice if we can't create the priate folder
246 *
247 * @return void
248 */
249 public function errorNotice() {
250 $class = 'notice notice-error';
251 $message = __( 'Irks! Error when creating a new private folder for private media', 'presto-player' );
252
253 printf( '<div class="%1$s"><p>%2$s</p></div>', esc_attr( $class ), esc_html( $message ) );
254 }
255
256 /**
257 * Makes our custom folder in the .htaccess directory.
258 *
259 * @param \WP_Filesystem_Base $wp_filesystem WordPress filesystem instance.
260 * @param string $folder_name Name of the folder to create.
261 * @return string Absolute path to the created folder.
262 */
263 private function makeFolder( $wp_filesystem, $folder_name ) {
264 $wp_upload_dir = wp_upload_dir();
265 $private_folder = trailingslashit( $wp_upload_dir['basedir'] ) . $folder_name;
266 $wp_filesystem->mkdir( $private_folder );
267
268 return $private_folder;
269 }
270
271 /**
272 * Sets htaccess rules in the new private folder.
273 *
274 * @param \WP_Filesystem_Base $wp_filesystem WordPress filesystem instance.
275 * @param string $private_folder Absolute path to the private folder.
276 * @return void
277 */
278 private function setHtaccess( $wp_filesystem, $private_folder ) {
279 $file = trailingslashit( $private_folder ) . '.htaccess';
280 $wp_filesystem->put_contents( $file, $this->return_htaccess_file_content(), FS_CHMOD_FILE );
281 }
282
283 /**
284 * Builds the Apache "allow from" whitelist for allowed IP addresses.
285 *
286 * @return string The generated allow directives.
287 */
288 public function makeIPWhiteList() {
289 $out = '';
290 foreach ( $this->allowed_ips as $ip ) {
291 $out .= "allow from $ip \n";
292 }
293 return $out;
294 }
295
296 /**
297 * Htaccess configuration
298 *
299 * @return string (heredoc)
300 */
301 private function return_htaccess_file_content() {
302 $list = $this->makeIPWhitelist();
303 return "# Deny access to everything by default\n"
304 . "Order Deny,Allow\n"
305 . "deny from all\n"
306 . $list . "\n"
307 . "# Deny access to sub directory\n"
308 . "<Files subdirectory/*>\n"
309 . " deny from all\n"
310 . ' ' . $list . "\n"
311 . '</Files>';
312 }
313 }
314