PluginProbe
Photo Engine (Media Organizer & Lightroom) / trunk
Photo Engine (Media Organizer & Lightroom) vtrunk
6.5.5 6.5.4 6.5.3 6.5.2 trunk 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.8.2 0.8.3 0.8.4 0.8.6 0.8.8 1.2.4 1.3.0 1.3.2 1.3.3 1.3.4 1.3.5 1.3.6 All 157 releases
wplr-sync / classes / api.php

api.php in Photo Engine (Media Organizer & Lightroom) trunk, at classes/api.php

378 lines 11.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 class Meow_WPLR_Sync_API {
4
5 private $running = true;
6 private $ob_enabled = false;
7 private $ob = false;
8 private $user = null;
9 private $error = null;
10 private $result = array(
11 'success' => false,
12 'error' => array(
13 'message' => 'The API did not respond to that request. Please contact the developer.'
14 )
15 );
16
17 public function __construct() {
18 if ( $this->endsWith( $_SERVER['REQUEST_URI'], '/?wplr-sync-api' ) ) {
19 $this->ob_enabled = get_option( 'wplr_catch_errors', false );
20 add_action( 'init', array ( $this, 'handleRequest' ), 20, 0 );
21 define( 'DOING_WPLR_REQUEST', 1 );
22 }
23 }
24
25 function endsWith( $haystack, $needle ) {
26 if ( $needle === '' )
27 return true;
28 $diff = strlen( $haystack ) - strlen( $needle );
29 return $diff >= 0 && strpos( $haystack, $needle, $diff ) !== false;
30 }
31
32 public function handleRequest() {
33 global $wplr;
34 $this->initialize();
35
36 // GET could returns some information about Photo Engine
37 if ( $_SERVER['REQUEST_METHOD'] === 'GET' ) {
38 $this->response( array( 'message' => "Photo Engine says hi!" ) );
39 }
40 // Upload
41 else if ( isset( $_POST['action'] ) && $_POST['action'] === 'sync' ) {
42 if ( !$user = $this->auth( $_POST['token'] ) ) {
43 $this->response( null, false, $this->error );
44 $this->finalize();
45 }
46 $wplr->log( "Action: sync" );
47 $this->sync( $_POST );
48 }
49 // Other action
50 else {
51 $body = file_get_contents('php://input');
52 $args = json_decode( $body );
53 if ( !$user = $this->auth( $args->token ) ) {
54 $this->response( null, false, $this->error );
55 $this->finalize();
56 }
57 $wplr->log( "Action: " . $args->action );
58 if ( !$user = $this->auth( $args->token ) )
59 $this->response( null, false, $this->error );
60 else if ( $args->action === 'presync' )
61 $this->presync( $args );
62 else if ( $args->action === 'sync_collection' )
63 $this->sync_collection( $args );
64 else if ( $args->action === 'delete_collection' )
65 $this->delete_collection( $args );
66 else if ( $args->action === 'order_collection' )
67 $this->order_collection( $args );
68 else if ( $args->action === 'delete' )
69 $this->delete( $args );
70 else if ( $args->action === 'userinfo' )
71 $this->userinfo( $args );
72 else if ( $args->action === 'list_wpids' )
73 $this->list_wpids( $args );
74 else if ( $args->action === 'unlink' )
75 $this->unlink( $args );
76 else if ( $args->action === 'link' )
77 $this->link( $args );
78 else if ( $args->action === 'linkinfo_upload' )
79 $this->linkinfo_upload( $args );
80 else if ( $args->action === 'linkinfo' )
81 $this->linkinfo( $args );
82 else if ( $args->action === 'list_unlinks' )
83 $this->list_unlinks( $args );
84 else if ( $args->action === 'list_sync_media' )
85 $this->list_sync_media( $args );
86 else
87 $this->response( null, false, "Action not available." );
88 }
89 $this->finalize();
90 }
91
92 function initialize() {
93 global $wplr;
94 if ( $this->ob_enabled ) {
95 if ( ob_start( array( $this, 'buffer_end' ) ) ) {
96 $this->ob = true;
97 $wplr->log( "Output buffering started." );
98 }
99 else {
100 $wplr->log( "Output buffering did not start." );
101 }
102 }
103 $this->running = true;
104 }
105
106 function buffer_end( $buffer ) {
107 return "";
108 }
109
110 /**
111 * {@inheritDoc}
112 * @see Meow_WPLR_Sync_API::auth()
113 */
114 function auth( $token ) {
115 global $wplr, $wpdb;
116
117
118 if ( empty( $token ) ) {
119 $this->error = "Authentification is missing.";
120 $wplr->log( $this->error );
121 return false;
122 }
123
124 //* DEBUG: allow to authenticate as admin with a hardcoded token (for testing purposes only)
125 // if ( $token == "MEOW_TOKEN" ) {
126
127 // $this->user = get_userdata( 1 );
128 // if ( empty( $this->user ) ) {
129 // $this->error = "User admin does not exist.";
130 // $wplr->log( $this->error );
131 // return false;
132 // }
133
134 // $wplr->log( "Authenticated as admin" );
135 // return $this->user;
136 // }
137
138 $prefix = defined( 'BLOG_ID_CURRENT_SITE' ) ? $wpdb->get_blog_prefix( BLOG_ID_CURRENT_SITE ) : $wpdb->prefix;
139 $tbl_meta = defined('CUSTOM_USER_META_TABLE' ) ? CUSTOM_USER_META_TABLE : $prefix . "usermeta";
140 $userId = $wpdb->get_var( $wpdb->prepare( "SELECT user_id FROM $tbl_meta
141 WHERE meta_value = %s AND meta_key = %s", $token, 'wplr_auth_token' ) );
142 if ( empty( $userId ) ) {
143 $this->error = "Token '$token' seems to be invalid.";
144 $wplr->log( $this->error );
145 return false;
146 }
147 $this->user = get_userdata( $userId );
148 if ( empty( $this->user ) ) {
149 $this->error = 'User does not exist.';
150 $wplr->log( $this->error );
151 return false;
152 }
153 $wplr->log( "Authenticated as " . $this->user->user_login );
154 return $this->user;
155 }
156
157 /**
158 * The final post-process for every responce
159 * @param array|string|Meow_WPLR_Sync_LRInfo $payload
160 */
161 function response( $payload, $success = true, $error = null ) {
162 global $wplr;
163 $wplr->get_version();
164 $r = array(
165 'success' => $success,
166 'payload' => $payload,
167 'error' => is_string( $error ) ? array( 'message' => $error ) : $error,
168 'version' => $wplr->get_version(),
169 );
170 $this->result = &$r;
171 return $r;
172 }
173
174 function finalize() {
175 if ( $this->ob ) {
176 global $wplr;
177 $content = ob_get_contents();
178 if ( !empty( $content ) ) {
179 error_log( "There was unwanted activity during the Photo Engine process (probably generated by another plugin). Request: " . $_SERVER['REQUEST_URI'] . ". The output which was caught will follow: " . $content );
180 $wplr->log( "There was unwanted activity during the Photo Engine process (probably generated by another plugin). Request: " . $_SERVER['REQUEST_URI'] . ". The output which was caught will follow.\r\n" . $content, true );
181 }
182 if ( !ob_end_clean() )
183 $wplr->log( "[OB] CLEAN FAILED" );
184 $wplr->log( "[OB] END (OB level is now " . ob_get_level() . ")" );
185 if ( ob_get_level() > 0 ) {
186 while ( @ob_end_clean() ) {}
187 $wplr->log( "[OB] ALL END" );
188 }
189 }
190 $this->running = false;
191 wp_send_json( $this->result, 200 );
192 exit;
193 }
194
195 /**
196 * {@inheritDoc}
197 * @see Meow_WPLR_Sync_API::sync()
198 */
199 function sync( $args ) {
200 global $wplr;
201
202 if ( !$_FILES || !isset( $_FILES['file'] ) ) {
203 $wplr->log( 'Parameter missing.' );
204 return $this->response( null, false, 'Parameter missing.' );
205 }
206
207 $filename = isset( $args['file'] ) ? $args['file'] : '';
208
209 $allowed_mimes = get_allowed_mime_types();
210 $filetype = wp_check_filetype( $filename, $allowed_mimes );
211
212 $is_valid = $filetype['type'] && $filetype['ext'] && $filetype['ext'] !== false;
213
214 if ( !$is_valid ) {
215 $wplr->log( 'File type validation failed: ' . $filetype['type'] );
216 return $this->response( null, false, 'File type validation failed: ' . $filetype['type'] );
217 }
218
219 // Decode tags
220 $args["tags"] = json_decode( stripslashes( $args["tags"] ), true );
221 $args = apply_filters( 'wplr_sync_api_sync_args', $args );
222
223 $lrinfo = new Meow_WPLR_Sync_LRInfo();
224 $lrinfo->lr_id = $args["id"];
225 $lrinfo->lr_file = $args["file"];
226 $lrinfo->lr_title = $args["title"];
227 $lrinfo->lr_caption = $args["caption"];
228 $lrinfo->lr_desc = $args["desc"];
229 $lrinfo->lr_alt_text = $args["altText"];
230 $lrinfo->sync_title = $args["syncTitle"];
231 $lrinfo->sync_caption = $args["syncCaption"];
232 $lrinfo->sync_desc = $args["syncDesc"];
233 $lrinfo->sync_alt_text = $args["syncAltText"];
234 $lrinfo->tags = $args["tags"];
235 $file = $_FILES['file']['tmp_name'];
236
237 if ( !isset( $args["wp_col_id"] ) || $args["wp_col_id"] == null )
238 $args["wp_col_id"] = -1;
239 if ( !$sync = $wplr->sync_media( $lrinfo, $file, $args["wp_col_id"], $this->user->ID ) ) {
240 return $this->response( null, false, $wplr->get_error() );
241 }
242
243 return $this->response($sync);
244 }
245
246 function presync( $args ) {
247 global $wplr;
248 if ( defined ('HHVM_VERSION' ) ) {
249 $max_execution_time = ini_get( 'max_execution_time' ) ? (int)ini_get( 'max_execution_time' ) : 30;
250 $post_max_size = ini_get( 'post_max_size' ) ? (int)$wplr->parse_ini_size( ini_get( 'post_max_size' ) ) : (int)ini_get( 'hhvm.server.max_post_size' );
251 $upload_max_filesize = ini_get( 'upload_max_filesize' ) ? (int)$wplr->parse_ini_size( ini_get( 'upload_max_filesize' ) ) : (int)ini_get( 'hhvm.server.upload.upload_max_file_size' );
252 }
253 else {
254 $max_execution_time = (int)ini_get( 'max_execution_time' );
255 $post_max_size = (int)$wplr->parse_ini_size( ini_get( 'post_max_size' ) );
256 $upload_max_filesize = (int)$wplr->parse_ini_size( ini_get( 'upload_max_filesize' ) );
257 }
258 $max = min( $post_max_size, $upload_max_filesize );
259 $presync = array(
260 'max_execution_time' => $max_execution_time > 0 ? $max_execution_time : 666,
261 'post_max_size' => $post_max_size,
262 'upload_max_filesize' => $upload_max_filesize > 0 ? $upload_max_filesize : 66600000,
263 'max_size' => $max > 0 ? $max : 66600000
264 );
265 return $this->response( $presync );
266 }
267
268 // Order collection
269 function order_collection( $args ) {
270 global $wplr;
271 $remoteId = property_exists( $args, 'remoteId' ) ? $args->remoteId : null;
272 $lrIds = property_exists( $args, 'lrIds' ) ? $args->lrIds : null;
273 $order = property_exists( $args, 'order' ) ? $args->order : null;
274 if ( empty( $remoteId ) )
275 return $this->response( true );
276
277 if ( empty( $lrIds ) ) {
278 $res = $wplr->order_collection_by( $remoteId, $order );
279 return $this->response( $res );
280 }
281 else {
282 $res = $wplr->order_collection( $remoteId, $lrIds );
283 return $this->response( $res );
284 }
285 }
286
287 // Sync file
288 function sync_collection( $args ) {
289 global $wplr;
290 $hierarchy = $args->hierarchy;
291 if ( !$list = $wplr->sync_collection( $hierarchy ) ) {
292 return $this->response( null, false, $this->error );
293 }
294 return $this->response( $list );
295 }
296
297 // Delete collection
298 function delete_collection( $args ) {
299 global $wplr;
300 $res = false;
301 if ( property_exists( $args, 'remoteId' ) )
302 $res = $wplr->delete_collection( $args->remoteId );
303 return $this->response( $res );
304 }
305
306 // Delete file
307 function delete( $args ) {
308 global $wplr;
309 $collectionId = -1;
310 if ( property_exists( $args, 'collection_id' ) )
311 $collectionId = $args->collection_id;
312 $list = $wplr->delete_media( $args->lr_id, $collectionId );
313 return $this->response( $list );
314 }
315
316 // Get the User
317 function userinfo( $args ) {
318 return $this->response( $this->user->data );
319 }
320
321 /*******************************************************************
322 * TOTAL SYNCHRONIZATION MODULE
323 ******************************************************************/
324
325 // Get WP IDs for a given LR ID
326 function list_wpids( $args ) {
327 global $wplr;
328 $res = $wplr->list_wpids( $args->lr_id );
329 return $this->response( $res );
330 }
331
332 // Unlink
333 function unlink( $args ) {
334 global $wplr;
335 $res = $wplr->unlink_media( $args->lr_id, $args->wp_id );
336 return $this->response( $res );
337 }
338
339 // Get LinkInfo for the Media ID
340 function link( $args ) {
341 global $wplr;
342 $res = $wplr->link_media( $args->lr_id, $args->wp_id );
343 return $this->response( $res );
344 }
345
346 // Get LinkInfo for the upload
347 function linkinfo_upload( $args ) {
348 global $wplr;
349 $file = $wplr->b64_to_file( $args->file );
350 $linkinfo = $wplr->linkinfo_upload( $file, null );
351 return $this->response( $linkinfo );
352 }
353
354 // Get LinkInfo for the Media ID
355 function linkinfo( $args ) {
356 global $wplr;
357 $linkinfo = $wplr->linkinfo_media( $args->wp_id );
358 return $this->response( $linkinfo );
359 }
360
361 // List files (the Media IDs) that are not linked
362 function list_unlinks( $args ) {
363 global $wplr;
364 $list = $wplr->list_unlinks();
365 return $this->response( $list );
366 }
367
368 // List synced files
369 function list_sync_media( $args ) {
370 global $wplr;
371 $list = $wplr->list_sync_media();
372 return $this->response( $list );
373 }
374
375 }
376
377 ?>
378