Changeset 3442717
- Timestamp:
- 01/19/2026 05:51:29 PM (2 months ago)
- Location:
- quick-playground
- Files:
-
- 66 added
- 10 edited
-
tags/1.2.1 (added)
-
tags/1.2.1/api.php (added)
-
tags/1.2.1/blueprint-builder.php (added)
-
tags/1.2.1/blueprint-settings-init.php (added)
-
tags/1.2.1/build.php (added)
-
tags/1.2.1/client-demo-filters.php (added)
-
tags/1.2.1/client-prompts.php (added)
-
tags/1.2.1/client-qckply_data.php (added)
-
tags/1.2.1/client-save-images.php (added)
-
tags/1.2.1/client-save-playground.php (added)
-
tags/1.2.1/client.php (added)
-
tags/1.2.1/clone.php (added)
-
tags/1.2.1/expro-api.php (added)
-
tags/1.2.1/expro-filters.php (added)
-
tags/1.2.1/expro-networkadmin.php (added)
-
tags/1.2.1/expro-quickplayground-sync.php (added)
-
tags/1.2.1/filters.php (added)
-
tags/1.2.1/getmenus.php (added)
-
tags/1.2.1/images (added)
-
tags/1.2.1/images/quick-playground.png (added)
-
tags/1.2.1/includes.php (added)
-
tags/1.2.1/key_pages.php (added)
-
tags/1.2.1/languages (added)
-
tags/1.2.1/languages/quick-playground.pot (added)
-
tags/1.2.1/makeBlueprintItem.php (added)
-
tags/1.2.1/qckply (added)
-
tags/1.2.1/qckply-iframe.php (added)
-
tags/1.2.1/qckply-loading.php (added)
-
tags/1.2.1/qckply/build (added)
-
tags/1.2.1/qckply/build/blocks-manifest.php (added)
-
tags/1.2.1/qckply/build/qckply (added)
-
tags/1.2.1/qckply/build/qckply/block.json (added)
-
tags/1.2.1/qckply/build/qckply/index-rtl.css (added)
-
tags/1.2.1/qckply/build/qckply/index.asset.php (added)
-
tags/1.2.1/qckply/build/qckply/index.css (added)
-
tags/1.2.1/qckply/build/qckply/index.js (added)
-
tags/1.2.1/qckply/build/qckply/render.php (added)
-
tags/1.2.1/qckply/build/qckply/style-index-rtl.css (added)
-
tags/1.2.1/qckply/build/qckply/style-index.css (added)
-
tags/1.2.1/qckply/build/qckply/view.asset.php (added)
-
tags/1.2.1/qckply/build/qckply/view.js (added)
-
tags/1.2.1/qckply/package-lock.json (added)
-
tags/1.2.1/qckply/package.json (added)
-
tags/1.2.1/qckply/qckply.php (added)
-
tags/1.2.1/qckply/readme.txt (added)
-
tags/1.2.1/qckply/src (added)
-
tags/1.2.1/qckply/src/qckply (added)
-
tags/1.2.1/qckply/src/qckply/block.json (added)
-
tags/1.2.1/qckply/src/qckply/edit.js (added)
-
tags/1.2.1/qckply/src/qckply/editor.scss (added)
-
tags/1.2.1/qckply/src/qckply/icon.svg (added)
-
tags/1.2.1/qckply/src/qckply/index.js (added)
-
tags/1.2.1/qckply/src/qckply/render.php (added)
-
tags/1.2.1/qckply/src/qckply/style.scss (added)
-
tags/1.2.1/qckply/src/qckply/view.js (added)
-
tags/1.2.1/qckply_upload.php (added)
-
tags/1.2.1/quick-playground.php (added)
-
tags/1.2.1/quickplayground-updates.php (added)
-
tags/1.2.1/quickplayground.css (added)
-
tags/1.2.1/quickplayground.js (added)
-
tags/1.2.1/quickplayground.min.js (added)
-
tags/1.2.1/quickplayground_design_clone.php (added)
-
tags/1.2.1/readme.txt (added)
-
tags/1.2.1/swinging-30px.png (added)
-
tags/1.2.1/swinging-99104_640.png (added)
-
tags/1.2.1/utility.php (added)
-
trunk/api.php (modified) (24 diffs)
-
trunk/blueprint-settings-init.php (modified) (1 diff)
-
trunk/client-save-images.php (modified) (5 diffs)
-
trunk/client-save-playground.php (modified) (1 diff)
-
trunk/expro-api.php (modified) (21 diffs)
-
trunk/expro-filters.php (modified) (1 diff)
-
trunk/qckply-loading.php (modified) (1 diff)
-
trunk/quick-playground.php (modified) (2 diffs)
-
trunk/readme.txt (modified) (2 diffs)
-
trunk/utility.php (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
quick-playground/trunk/api.php
r3441581 r3442717 4 4 * REST controller for managing blueprints in the playground. 5 5 */ 6 7 add_action('init', function() { 8 if (defined('REST_REQUEST') && REST_REQUEST) { 9 if (headers_sent($file, $line)) { 10 error_log("Headers sent on init during REST request in $file on line $line"); 11 } 12 } 13 }, 999); 14 15 add_action('wp_loaded', function() { 16 if (defined('REST_REQUEST') && REST_REQUEST) { 17 if (headers_sent($file, $line)) { 18 error_log("Headers sent on wp_loaded during REST request in $file on line $line"); 19 } 20 } 21 }, 999); 22 6 23 class Qckply_Blueprint extends WP_REST_Controller { 7 24 … … 13 30 $namespace = 'quickplayground/v1'; 14 31 15 $path = 'blueprint/(?P<profile>[a-z0-9_ ]+)';32 $path = 'blueprint/(?P<profile>[a-z0-9_\-]+)'; 16 33 17 34 register_rest_route( $namespace, '/' . $path, [ … … 48 65 */ 49 66 public function get_items($request) { 67 ob_start(); 50 68 $profile = sanitize_text_field($request['profile']); 51 69 do_action('qckply_fetch_blueprint',$profile); … … 77 95 $blueprint = apply_filters('qckply_blueprint',$blueprint); 78 96 qckply_hits($profile); 79 $response = new WP_REST_Response( $blueprint, 200 ); 80 $response->header( "Access-Control-Allow-Origin", "*" ); 81 return $response; 82 } 97 ob_clean(); 98 $headers = [ 99 "Access-Control-Allow-Origin" => "https://playground.wordpress.net", 100 "Access-Control-Allow-Methods" => "GET, POST, OPTIONS", 101 "Access-Control-Allow-Headers" => "Content-Type", 102 ]; 103 $response = new WP_REST_Response( $blueprint, 200, $headers ); 104 return $response; } 83 105 } 84 106 … … 95 117 $namespace = 'quickplayground/v1'; 96 118 97 $path = 'clone_posts/(?P<profile>[a-z0-9_ ]+)';119 $path = 'clone_posts/(?P<profile>[a-z0-9_\-]+)'; 98 120 99 121 register_rest_route( $namespace, '/' . $path, [ … … 132 154 */ 133 155 public function get_items($request) { 156 ob_start(); 134 157 require('getmenus.php'); 135 158 global $wpdb; … … 147 170 $clone = qckply_posts_related($clone); 148 171 $clone = qckply_get_menu_data($clone); 149 //unset($clone['ids']); 150 $response = new WP_REST_Response( $clone, 200 ); 151 $response->header( "Access-Control-Allow-Origin", "*" ); 172 unset($clone['ids']); 173 ob_clean(); 174 $headers = [ 175 "Access-Control-Allow-Origin" => "*", 176 "Access-Control-Allow-Methods" => "GET, POST, OPTIONS", 177 "Access-Control-Allow-Headers" => "Content-Type", 178 ]; 179 $response = new WP_REST_Response( $clone, 200, $headers ); 152 180 return $response; 153 181 } … … 155 183 156 184 function qckply_get_clone_posts($profile, $debug = false) { 157 if($debug)158 {159 echo $log = sprintf('qckply_get_clone_posts(%s)',$profile);160 error_log($log);161 }162 //may help free memory163 185 clearstatcache(); 164 186 global $wpdb; … … 233 255 if($debug) echo 'get_clone_posts templates sql before prepare',$sql; 234 256 $sql = $wpdb->prepare($sql, $params); 235 error_log('get_clone_posts templates sql '.$sql);236 257 if($debug) echo '<br>'.$sql; 237 258 $templates = $wpdb->get_results($sql); 238 error_log('get_clone_posts templates %d',sizeof($templates));239 259 foreach($templates as $p) { 240 260 if(!in_array($p->ID,$clone['ids'])) { … … 246 266 if(!empty($settings['copy_blogs'])) { 247 267 $blogs = get_posts(array('numberposts'=>intval($settings['copy_blogs']))); 248 error_log('get_clone_posts blogs %d',sizeof($blogs));249 268 foreach($blogs as $blog) 250 269 { … … 269 288 if(!empty($settings['qckply_key_pages'])) { 270 289 $pages = qckply_qckply_key_pages($profile); 271 error_log('get_clone_posts key_pages %d',sizeof($pages));272 290 foreach($pages as $p) 273 291 { … … 303 321 if(!empty($settings['demo_posts']) && is_array($settings['demo_posts'])) { 304 322 $clone['demo_posts'] = []; 305 error_log('get_clone_posts demo posts %d',sizeof($settings['demo_posts']));306 323 foreach($settings['demo_posts'] as $id) { 307 324 if(in_array($id, $clone['ids'])) … … 316 333 } 317 334 $clone['posts'] = $posts; 318 error_log('get_clone_posts total posts %d',sizeof($posts));319 335 320 336 $clone = apply_filters('qckply_qckply_clone_posts',$clone, $settings); 321 error_log('get_clone_posts after filter %d',sizeof($clone['posts']));322 337 return $clone; 323 338 } … … 335 350 $namespace = 'quickplayground/v1'; 336 351 337 $path = 'clone_settings/(?P<profile>[a-z0-9_ ]+)';352 $path = 'clone_settings/(?P<profile>[a-z0-9_\-]+)'; 338 353 339 354 register_rest_route( $namespace, '/' . $path, [ … … 370 385 */ 371 386 public function get_items($request) { 387 ob_start(); 372 388 require('getmenus.php'); 373 389 global $wpdb; … … 419 435 } 420 436 $clone = apply_filters('qckply_qckply_clone_settings',$clone); 421 $response = new WP_REST_Response( $clone, 200 ); 422 $response->header( "Access-Control-Allow-Origin", "*" ); 437 ob_clean(); 438 $headers = [ 439 "Access-Control-Allow-Origin" => "*", 440 "Access-Control-Allow-Methods" => "GET, POST, OPTIONS", 441 "Access-Control-Allow-Headers" => "Content-Type", 442 ]; 443 $response = new WP_REST_Response( $clone, 200, $headers ); 423 444 return $response; 424 }445 } 425 446 } 426 447 … … 437 458 $namespace = 'quickplayground/v1'; 438 459 439 $path = 'clone_taxonomy/(?P<profile>[a-z0-9_ ]+)';460 $path = 'clone_taxonomy/(?P<profile>[a-z0-9_\-]+)'; 440 461 441 462 register_rest_route( $namespace, '/' . $path, [ … … 474 495 */ 475 496 public function get_items($request) { 497 ob_start(); 476 498 $qckply_directories = qckply_get_directories(); 477 499 $qckply_site_uploads = $qckply_directories['site_uploads']; … … 519 541 } 520 542 } unset($clone['ids']); 521 $response = new WP_REST_Response( $clone, 200 ); 522 $response->header( "Access-Control-Allow-Origin", "*" ); 543 ob_clean(); 544 $headers = [ 545 "Access-Control-Allow-Origin" => "*", 546 "Access-Control-Allow-Methods" => "GET, POST, OPTIONS", 547 "Access-Control-Allow-Headers" => "Content-Type", 548 ]; 549 $response = new WP_REST_Response( $clone, 200, $headers ); 523 550 return $response; 524 551 } … … 537 564 $namespace = 'quickplayground/v1'; 538 565 539 $path = 'clone_custom/(?P<profile>[a-z0-9_ ]+)';566 $path = 'clone_custom/(?P<profile>[a-z0-9_\-]+)'; 540 567 541 568 register_rest_route( $namespace, '/' . $path, [ … … 574 601 */ 575 602 public function get_items($request) { 603 ob_start(); 576 604 $qckply_directories = qckply_get_directories(); 577 605 $qckply_site_uploads = $qckply_directories['site_uploads']; … … 586 614 $json = file_get_contents($savedfile); 587 615 if($json && $clone = json_decode($json)) { 588 $response = new WP_REST_Response( $clone, 200 ); 589 $response->header( "Access-Control-Allow-Origin", "*" ); 590 return $response; 616 ob_clean(); 617 $headers = [ 618 "Access-Control-Allow-Origin" => "*", 619 "Access-Control-Allow-Methods" => "GET, POST, OPTIONS", 620 "Access-Control-Allow-Headers" => "Content-Type", 621 ]; 622 $response = new WP_REST_Response( $clone, 200, $headers ); 623 return $response; 591 624 } 592 625 } … … 596 629 $clone = apply_filters('qckply_clone_custom',$clone,$clone['ids']); 597 630 $response = new WP_REST_Response( $clone,200 ); 598 $response->header( "Access-Control-Allow-Origin", "*" ); 631 ob_clean(); 632 $headers = [ 633 "Access-Control-Allow-Origin" => "*", 634 "Access-Control-Allow-Methods" => "GET, POST, OPTIONS", 635 "Access-Control-Allow-Headers" => "Content-Type", 636 ]; 637 $response = new WP_REST_Response( $clone, 200, $headers ); 599 638 return $response; 600 639 } … … 750 789 751 790 } 752 753 791 754 792 add_action('rest_api_init', function () { -
quick-playground/trunk/blueprint-settings-init.php
r3431953 r3442717 17 17 //iteratively applies sanitization to all values in the array 18 18 $postvars = qckply_sanitize(wp_unslash($_POST)); 19 $result = qckply_build($postvars,$profile); 20 $blueprint = $result[0]; 21 $settings = $result[1]; 19 if(isset($postvars['theme_blueprint'])) { 20 $pp = get_option('qckply_profiles',array('default')); 21 foreach($postvars['theme_blueprint'] as $index => $stylesheet) { 22 $profile = $stylesheet.'_demo'; 23 if(!in_array($profile,$pp)) 24 { 25 $pp[] = $profile; 26 } 27 $postvars['add_theme'] = [$stylesheet]; 28 $postvars['ziplocal_theme'] = array(0); 29 $postvars['settings']['stylesheet'] = $stylesheet; 30 $postvars['settings']['blogname'] = $postvars['theme_name'][$index].' Demo'; 31 $postvars['settings']['blogdescription'] = 'A virtual website demo of '.$postvars['theme_name'][$index]; 32 $result = qckply_build($postvars,$profile); 33 $blueprint = $result[0]; 34 $settings = $result[1]; 35 printf('<div class="notice notice-success"><p>Creating a Theme Demo for %s</p></div>',esc_html($postvars['theme_name'][$index])); 36 } 37 update_option('qckply_profiles',$pp); 38 } 39 else { 40 $result = qckply_build($postvars,$profile); 41 $blueprint = $result[0]; 42 $settings = $result[1]; 43 } 22 44 $cachemessage = qckply_cache_message($profile,$settings); 23 45 update_option('quickplay_clone_settings_'.$profile,$settings); -
quick-playground/trunk/client-save-images.php
r3436764 r3442717 6 6 function qckply_attachment_to_upload($attachment_id) { 7 7 global $wpdb; 8 $attpost = get_post($attachment_id); 9 if(!$attpost) 10 return; 8 11 $data = $meta = wp_get_attachment_metadata($attachment_id); // returns array or false 9 12 update_option('qckply_upload_attachment_id',$attachment_id); … … 11 14 $temp = wp_upload_dir(); 12 15 $uploads = trailingslashit($temp['basedir']); 16 $path = trailingslashit($temp['path']); 13 17 //sort largest to smallest by width 14 18 $filename = $uploads.$data['file']; 15 19 update_option('qckply_upload_image_path',$filename); 16 20 $basename = basename(str_replace('-scaled','',$filename)); 17 printf('<p>Uploading image %s</p>',esc_html($basename));18 21 update_option('qckply_upload_basename',$basename); 19 22 $filesize = filesize($filename); 20 if($filesize > 750000) { 23 $size_limit = 500000; 24 printf('<p>%s size %d</p>',$filename,$filesize); 25 if($filesize > $size_limit) { 26 echo '<p>Checking for a version < '.$size_limit.' bytes</p>'; 21 27 update_option('qckply_upload_image_usort_start',$data['sizes']); 22 28 usort($data['sizes'], function($a, $b) { … … 26 32 foreach($data['sizes'] as $img) { 27 33 update_option('qckply_upload_image_path_size_array',$img); 28 $filename = $ uploads.$img['file'];34 $filename = $path.$img['file']; 29 35 $filesize = filesize($filename); 36 printf('<p>%s size %d</p>',$filename,$filesize); 30 37 update_option('qckply_upload_image_path_size_test',$filename.':'.$filesize); 31 if($filesize < 750000)38 if($filesize < $size_limit) 32 39 break; 33 40 } … … 43 50 $updata['base64'] = base64_encode($imgcontent); 44 51 $updata['top_id'] = $wpdb->get_var($wpdb->prepare('select ID from %i ORDER BY ID DESC',$wpdb->posts)); 52 $updata['post_parent'] = $attpost->post_parent; 45 53 update_option('qckply_upload_image_base64',$updata['base64']); 46 54 $updata['filename'] = $basename; 55 $updata['path'] = $filename; 56 echo '<p>Image upload data: '; 57 foreach($updata as $key => $value) 58 { 59 echo ' <strong>'.esc_html($key).'</strong>'; 60 if('base64' == $key) { 61 echo 'length '.strlen($value); 62 } 63 else 64 echo ' '.$value; 65 } 66 echo '</p>'; 67 if(empty($updata['base64'])) 68 { 69 echo '<p>Error encoding to base64</p>'; 70 return; 71 } 47 72 $request = array( 48 73 'body' => json_encode($updata), … … 56 81 $response_code = wp_remote_retrieve_response_code( $response ); 57 82 if(200 == $response_code) { 83 printf('<p>Uploading image %s</p>',esc_html($basename)); 58 84 update_option('qckply_upload_image_result',var_export($response_data,true)); 59 85 $server_attachment_id = $response_data['sideload_meta']['attachment_id']; -
quick-playground/trunk/client-save-playground.php
r3441581 r3442717 62 62 if(!empty($returned['message'])) 63 63 printf('<p>%s</p>',esc_html('Server message: '.$returned['message'])); 64 printf('<div class="notice notice-error"><p>Error saving over the network. Try <a href="%s">downloading</a> instead.</p></div>',esc_attr(rest_url('quickplayground/v1/download_json/'.$profile)));64 printf('<div class="notice notice-error"><p>Error saving over the network. A security plugin such as WordFence could be blocking the connection. <a href="%s">Retry</a> or try <a href="%s">downloading</a> instead.</p></div>',esc_attr(admin_url('admin.php?page=qckply_save')),esc_attr(rest_url('quickplayground/v1/download_json/'.$profile))); 65 65 printf('<p><a href="%s">Retry</a></p>',esc_attr(admin_url('admin.php?page=qckply_save'))); 66 66 echo '<p>If you see this repeatedly, please report the issue via <a href="https://wordpress.org/support/plugin/quick-playground/">https://wordpress.org/support/plugin/quick-playground/</a></p>'; -
quick-playground/trunk/expro-api.php
r3436764 r3442717 51 51 */ 52 52 public function get_items($request) { 53 53 ob_start(); 54 54 global $wpdb; 55 55 $qckply_directories = qckply_get_directories(); … … 118 118 } 119 119 $sync_response['file'] = $savedfile; 120 $response = new WP_REST_Response( $sync_response, 200 ); 121 $response->header( "Access-Control-Allow-Origin", "*" ); 120 ob_clean(); 121 $headers = [ 122 "Access-Control-Allow-Origin" => "*", 123 "Access-Control-Allow-Methods" => "GET, POST, OPTIONS", 124 "Access-Control-Allow-Headers" => "Content-Type", 125 ]; 126 $response = new WP_REST_Response( $sync_response, 200, $headers ); 122 127 return $response; 123 128 } … … 170 175 */ 171 176 public function get_items($request) { 172 177 ob_start(); 173 178 global $wpdb; 174 179 $data = $request->get_json_params(); 175 180 $server_top = qckply_top_ids(true); 176 181 $client_top = $data['top_ids']; 182 $clone = array(); 177 183 foreach($client_top as $key => $value) { 178 $response[$key] = $value - $server_top[$key]; 179 } 184 $clone[$key] = $value - $server_top[$key]; 185 } 186 ob_clean(); 187 $headers = [ 188 "Access-Control-Allow-Origin" => "*", 189 "Access-Control-Allow-Methods" => "GET, POST, OPTIONS", 190 "Access-Control-Allow-Headers" => "Content-Type", 191 ]; 192 $response = new WP_REST_Response( $clone, 200, $headers ); 180 193 return $response; 181 194 } … … 231 244 */ 232 245 public function get_items($request) { 246 ob_start(); 233 247 global $wpdb; 234 248 $qckply_directories = qckply_get_directories(); … … 244 258 $sync_response['saved'] = $bytes_written; 245 259 $sync_response['file'] = $savedfile; 246 $response = new WP_REST_Response( $sync_response, 200 ); 247 $response->header( "Access-Control-Allow-Origin", "*" ); 260 ob_clean(); 261 $headers = [ 262 "Access-Control-Allow-Origin" => "*", 263 "Access-Control-Allow-Methods" => "GET, POST, OPTIONS", 264 "Access-Control-Allow-Headers" => "Content-Type", 265 ]; 266 $response = new WP_REST_Response( $sync_response, 200, $headers ); 248 267 return $response; 249 268 } … … 280 299 } 281 300 282 283 284 301 /** 285 302 * Permissions check for saving metadata. … … 300 317 public function get_items($request) { 301 318 global $wpdb; 319 ob_start(); 302 320 $qckply_directories = qckply_get_directories(); 303 321 $qckply_site_uploads = $qckply_directories['site_uploads']; … … 311 329 $sync_response['saved'] = $bytes_written; 312 330 $sync_response['file'] = $savedfile; 313 $response = new WP_REST_Response( $sync_response, 200 ); 314 $response->header( "Access-Control-Allow-Origin", "*" ); 331 ob_clean(); 332 $headers = [ 333 "Access-Control-Allow-Origin" => "*", 334 "Access-Control-Allow-Methods" => "GET, POST, OPTIONS", 335 "Access-Control-Allow-Headers" => "Content-Type", 336 ]; 337 $response = new WP_REST_Response( $sync_response, 200, $headers ); 315 338 return $response; 316 339 } … … 366 389 */ 367 390 public function get_items($request) { 391 ob_start(); 368 392 global $wpdb; 369 393 $qckply_directories = qckply_get_directories(); … … 381 405 $data = json_decode($data, true); 382 406 if(!is_array($data)){ 407 ob_clean(); 383 408 return WP_REST_Response( ['error' => 'no data'], 200 ); 384 409 } … … 387 412 $sync_response['saved'] = $bytes_written; 388 413 $sync_response['file'] = $savedfile; 389 $response = new WP_REST_Response( $sync_response, 200 ); 390 $response->header( "Access-Control-Allow-Origin", "*" ); 414 ob_clean(); 415 $headers = [ 416 "Access-Control-Allow-Origin" => "*", 417 "Access-Control-Allow-Methods" => "GET, POST, OPTIONS", 418 "Access-Control-Allow-Headers" => "Content-Type", 419 ]; 420 $response = new WP_REST_Response( $sync_response, 200, $headers ); 391 421 return $response; 392 422 } … … 448 478 public function get_items($request) { 449 479 global $wpdb; 480 ob_start(); 450 481 $profile = $request['profile']; 451 482 $qckply_image_uploads = get_option('qckply_image_uploads',[]); … … 469 500 elseif (empty($params['base64'])) { 470 501 $sync_response['message'] = 'no base 64'; 471 $response = new WP_REST_Response( $sync_response, 300 ); 502 ob_clean(); 503 $headers = [ 504 "Access-Control-Allow-Origin" => "*", 505 "Access-Control-Allow-Methods" => "GET, POST, OPTIONS", 506 "Access-Control-Allow-Headers" => "Content-Type", 507 ]; 508 $response = new WP_REST_Response( $sync_response, 300, $headers ); 509 return $response; 472 510 } 473 511 else { … … 477 515 $newurl = $qckply_site_uploads_url.'/'.$filename; 478 516 $saved = file_put_contents($newpath,$filedata); 517 $parent_id = isset($params['post_parent']) ? intval($params['post_parent']) : 0; 479 518 $sync_response['message'] = 'saving to '.$newpath .' '.var_export($saved,true); 480 $sync_response['sideload_meta'] = qckply_sideload_saved_image($newurl );519 $sync_response['sideload_meta'] = qckply_sideload_saved_image($newurl, $parent_id); 481 520 $server_attachment_id = $sync_response['sideload_meta']['attachment_id']; 482 521 if($sync_response['sideload_meta']['attachment_id'] <= $params['top_id']) … … 491 530 $qckply_image_uploads[] = $server_attachment_id; 492 531 update_option('qckply_image_uploads',$qckply_image_uploads); 493 494 $response = new WP_REST_Response( $sync_response, 200 ); 495 } 496 $response->header( "Access-Control-Allow-Origin", "*" ); 497 return $response; 498 499 500 if(empty($_FILES['playground_upload'])) { 501 return new WP_Error('no_file', 'No file uploaded', array('status' => 400)); 502 } 503 504 $file = $_FILES['playground_upload']; 505 506 // Validate file type/size as needed 507 $allowed = array('jpg','jpeg','png','gif','bmp','webp','ico','tiff','tif','avif'); 508 $ext = strtolower(pathinfo($file['name'], PATHINFO_EXTENSION)); 509 if (!in_array($ext, $allowed)) { 510 return new WP_Error('invalid_type', 'File type not allowed', array('status' => 400)); 511 } 512 513 // Use WordPress to handle the upload 514 require_once(ABSPATH . 'wp-admin/includes/file.php'); 515 require_once(ABSPATH . 'wp-admin/includes/media.php'); 516 require_once(ABSPATH . 'wp-admin/includes/image.php'); 517 require_once(ABSPATH . 'wp-admin/includes/post.php'); 518 519 $overrides = array('test_form' => false); // Allow uploads outside of form POST 520 $response = new WP_REST_Response( array('filename'=>$file['name']), 200 ); 521 $response->header( "Access-Control-Allow-Origin", "*" ); 522 return $response; 523 524 $movefile = wp_handle_upload($file, $overrides); 525 526 if ($movefile && !isset($movefile['error'])) { 527 // Prepare array for sideload 528 $sideload = array( 529 'name' => $file['name'], 530 'type' => $movefile['type'], 531 'tmp_name' => $movefile['file'], 532 'error' => 0, 533 'size' => filesize($movefile['file']), 534 ); 535 536 // Create attachment and metadata 537 $attachment_id = media_handle_sideload($sideload, 0,'quick_playground_upload'); 538 539 if (is_wp_error($attachment_id)) { 540 $sync_response = new WP_Error('attachment_error', $attachment_id->get_error_message(), array('status' => 500)); 541 } else { 542 // Get attachment metadata 543 $meta = wp_get_attachment_metadata($attachment_id); 544 $url = wp_get_attachment_url($attachment_id); 545 546 $sync_response = array( 547 'success' => true, 548 'attachment_id' => $attachment_id, 549 'file' => $movefile['file'], 550 'url' => $url, 551 'type' => $movefile['type'], 552 'meta' => $meta, 553 ); 554 555 $qckply_uploaded_images = get_option('qckply_uploaded_images',[]); 556 $qckply_uploaded_images[] = $attachment_id; 557 update_option('qckply_uploaded_images',$qckply_uploaded_images); 558 } 559 } else { 560 $sync_response = new WP_Error('upload_error', $movefile['error'], array('status' => 500)); 561 } 562 $response = new WP_REST_Response( $sync_response, 200 ); 563 $response->header( "Access-Control-Allow-Origin", "*" ); 532 ob_clean(); 533 $headers = [ 534 "Access-Control-Allow-Origin" => "*", 535 "Access-Control-Allow-Methods" => "GET, POST, OPTIONS", 536 "Access-Control-Allow-Headers" => "Content-Type", 537 ]; 538 $response = new WP_REST_Response( $sync_response, 200, $headers ); 539 } 564 540 return $response; 565 541 } … … 612 588 */ 613 589 public function get_items($request) { 590 ob_start(); 614 591 global $wpdb; 615 592 $qckply_directories = qckply_get_directories(); … … 624 601 $sync_response['saved'] = $bytes_written; 625 602 $sync_response['file'] = $savedfile; 603 ob_clean(); 626 604 $response = new WP_REST_Response( $sync_response, 200 ); 627 605 $response->header( "Access-Control-Allow-Origin", "*" ); … … 676 654 */ 677 655 public function get_items($request) { 678 656 ob_start(); 679 657 global $wpdb; 680 658 $qckply_directories = qckply_get_directories(); … … 687 665 $sync_response['saved'] = $bytes_written; 688 666 $sync_response['file'] = $savedfile; 689 $response = new WP_REST_Response( $sync_response, 200 ); 690 $response->header( "Access-Control-Allow-Origin", "*" ); 691 return $response; 667 ob_clean(); 668 $headers = [ 669 "Access-Control-Allow-Origin" => "*", 670 "Access-Control-Allow-Methods" => "GET, POST, OPTIONS", 671 "Access-Control-Allow-Headers" => "Content-Type", 672 ]; 673 $response = new WP_REST_Response( $sync_response, 200, $headers ); 674 return $response; 692 675 } 693 676 } … … 737 720 */ 738 721 public function get_items($request) { 739 722 ob_start(); 740 723 global $wpdb; 741 724 $qckply_directories = qckply_get_directories(); … … 748 731 $sync_response = json_decode($contents,true); 749 732 $sync_response['found_contents'] = !empty($contents); 750 $response = new WP_REST_Response( $sync_response, 200 ); 751 $response->header( "Access-Control-Allow-Origin", "*" ); 733 ob_clean(); 734 ob_clean(); 735 $headers = [ 736 "Access-Control-Allow-Origin" => "*", 737 "Access-Control-Allow-Methods" => "GET, POST, OPTIONS", 738 "Access-Control-Allow-Headers" => "Content-Type", 739 ]; 740 $response = new WP_REST_Response( $sync_response, 200, $headers ); 752 741 return $response; 753 742 } -
quick-playground/trunk/expro-filters.php
r3432091 r3442717 103 103 104 104 add_action('qckply_sideload_saved_image','qckply_sideload_saved_image'); 105 function qckply_sideload_saved_image($file = '' ) {105 function qckply_sideload_saved_image($file = '', $post_id = 0) { 106 106 set_transient('qckply_sideload_url',var_export($file,true)); 107 107 require_once(ABSPATH . 'wp-admin/includes/media.php'); 108 108 require_once(ABSPATH . 'wp-admin/includes/file.php'); 109 109 require_once(ABSPATH . 'wp-admin/includes/image.php'); 110 $id = media_sideload_image( $file, 0, 'playground uploaded image', 'id' );110 $id = media_sideload_image( $file, $post_id, 'playground uploaded image', 'id' ); 111 111 if(!$id) 112 112 return []; -
quick-playground/trunk/qckply-loading.php
r3436764 r3442717 14 14 <title><?php echo esc_html($title); ?> (Playground Loading)</title> 15 15 <?php 16 wp_enqueue_style( 'qckply_style', plugin_dir_url( __FILE__ ) . 'quickplayground.css', array(), '1. 2' );16 wp_enqueue_style( 'qckply_style', plugin_dir_url( __FILE__ ) . 'quickplayground.css', array(), '1.4' ); 17 17 wp_print_styles(); ?> 18 18 </head> -
quick-playground/trunk/quick-playground.php
r3441581 r3442717 4 4 * Plugin URI: https://quickplayground.com 5 5 * Description: Preview your content in different themes or test plugins using WordPress Playground. Quickly create Theme and Plugin demo, testing, and staging websites. 6 * Version: 1.2 6 * Version: 1.2.1 7 7 * Author: David F. Carr 8 8 * License: GPL2 … … 80 80 echo "<p>Your website content and settings are not shared with any external cloud service. The playground is a private instance of WordPress loaded into your web browser.</p>"; 81 81 echo '</div>'; 82 83 $settings = get_option('quickplay_clone_settings_'.$profile,array()); 84 if(!empty($settings['page_on_front'])) { 85 $page_on_front = $settings['page_on_front']; 86 } 87 88 $front = $page_options = $post_options = ''; 89 $pages = $wpdb->get_results($wpdb->prepare("SELECT ID, post_title, post_status FROM %i WHERE post_type='page' AND (post_status='publish' OR post_status='draft') ORDER BY post_status, post_title ", $wpdb->posts)); 90 foreach($pages as $page) { 91 $status = ('draft' == $page->post_status) ? '(Draft)' : ''; 92 $opt = sprintf('<option value="%d" >%s %s</option>',intval($page->ID),esc_html($page->post_title),esc_html($status)); 93 if($settings['page_on_front'] == $page->ID) 94 $front = $opt; 95 $page_options .= $opt; 96 } 97 98 printf('<form class="qckply-form" method="post" action="%s"> <input type="hidden" name="build_profile" value="1">',esc_attr(admin_url('admin.php?page=qckply_builder'))); 99 wp_nonce_field('quickplayground','playground',true,true); 100 82 101 $themes = wp_get_themes(['allowed'=>true]); 83 102 if(!empty($themes) && sizeof($themes) > 1) { 84 103 echo '<h2>Playground Design Gallery</h2><p>See how your website would look with any of the WordPress themes shown below.</p>'; 85 104 echo '<div class="qckply-theme-previews">'; 86 foreach($themes as $ theme) {105 foreach($themes as $index => $theme) { 87 106 if($theme->stylesheet == $stylesheet) 88 107 continue; 89 108 $blueprint_url = qckply_get_api_url(['profile'=>$profile,'stylesheet'=>$theme->stylesheet]); 90 109 $screenshot = $theme->get_screenshot(); ///get_stylesheet_directory_uri().'/screenshot.png'; 91 //variables are sanitized in qckply_get_button. output includes svg code not compatible with wp_kses_post. was not able to get it work with wp_kses and custom tags92 110 printf('<div class="qckply-stylesheet"><div style="">Theme: %s</div><div class="qckply-theme-screenshot"><img src="%s" width="300" /></div><div class="qckply-theme-button">',esc_html($theme->Name),esc_attr($screenshot)); 93 111 qckply_get_button(['profile'=>$profile,'stylesheet'=>$theme->stylesheet],true); 94 printf('<br /></div>%s</div>',wp_kses_post(qckply_get_blueprint_link(['profile'=>$profile,'stylesheet' =>$theme->stylesheet]))); 112 printf('<br /></div>%s',wp_kses_post(qckply_get_blueprint_link(['profile'=>$profile,'stylesheet' =>$theme->stylesheet]))); 113 printf('<p><input type="checkbox" name="theme_blueprint[]" value="%s" checked="checked" /> ',esc_attr($theme->stylesheet)); 114 printf('<input type="text" name="theme_name[]" value="%s" checked="checked" /></p>',esc_attr($theme->name)); 115 echo '</div>'; 95 116 } 96 117 echo '</div>'; 97 118 } 98 119 printf('<h2>%s</h2>',esc_html__('Theme Demos','quick-playground')); 120 printf('<p>%s</p>',esc_html__('You can create a separate playground blueprint profile based on each of the checked themes, specifying just a couple of options. If needed, you can elaborate further on the Blueprint Buidler screen.','quick-playground')); 121 printf('<p><label>%s</label> <select name="settings[page_on_front]">%s</select></p>',esc_html__('Front Page','quick-playground'),wp_kses($front.$page_options, qckply_kses_allowed())); 122 printf('<p><input type="checkbox" name="settings[qckply_key_pages]" value="1" %s > Include key pages and posts (linked to from the home page or menu)</p>',(!isset($settings['qckply_key_pages']) || $settings['qckply_key_pages']) ? ' checked="checked" ' : ''); 123 submit_button(); 124 echo '<input type="hidden" name="build_profile" value="1" /></form>'; 99 125 } 100 126 -
quick-playground/trunk/readme.txt
r3441581 r3442717 9 9 Tested up to: 6.9 10 10 11 Stable tag: 1.2 11 Stable tag: 1.2.1 12 12 13 13 License: GPLv2 or later … … 97 97 == Changelog == 98 98 99 = 1.2.1 = 100 101 * Improved sync functionality for saving images 102 * Added ob_start() / ob_clean() to API response functions to supress unwanted output. 103 99 104 = 1.2 = 100 105 -
quick-playground/trunk/utility.php
r3441581 r3442717 1044 1044 // Helper to add an attachment once 1045 1045 $added = array(); 1046 $upload = wp_upload_dir(); 1046 1047 $add_attachment = function( $att_id ) use ( &$images, &$added, $upload ) { 1047 1048 … … 1050 1051 } 1051 1052 $added[ $att_id ] = true; 1052 1053 1053 $meta = wp_get_attachment_metadata( $att_id ); 1054 1054 $file_rel = isset( $meta['file'] ) ? $meta['file'] : _wp_relative_upload_path( get_attached_file( $att_id ) );
Note: See TracChangeset
for help on using the changeset viewer.