| @@ -6,8 +6,11 @@ | ||
| 6 | 6 | use LearnPress; |
| 7 | 7 | use LearnPress\Ajax\AbstractAjax; |
| 8 | 8 | use LearnPress\Helpers\Config; |
| 9 | 9 | use LearnPress\Helpers\Template; |
| 10 | +use LearnPress\Models\CourseModel; | |
| 11 | +use LearnPress\Models\CoursePostModel; | |
| 12 | +use LearnPress\Models\PostModel; | |
| 10 | 13 | use LearnPress\Models\QuizPostModel; |
| 11 | 14 | use LearnPress\Models\UserModel; |
| 12 | 15 | use LearnPress\Services\CourseService; |
| 13 | 16 | use LearnPress\Services\OpenAiService; |
| @@ -16,8 +19,9 @@ | ||
| 16 | 19 | use LearnPress\TemplateHooks\Admin\AI\AdminEditWithAITemplate; |
| 17 | 20 | use LP_Helper; |
| 18 | 21 | use LP_Request; |
| 19 | 22 | use LP_REST_Response; |
| 23 | +use LP_WP_Filesystem; | |
| 20 | 24 | use Throwable; |
| 21 | 25 | |
| 22 | 26 | /** |
| 23 | 27 | * class OpenAiAjax |
| @@ -202,10 +206,9 @@ | ||
| 202 | 206 | $course_edit_url = $coursePostModel->get_edit_link(); |
| 203 | 207 | if ( $is_course_builder ) { |
| 204 | 208 | $course_edit_url = \LearnPress\CourseBuilder\CourseBuilder::get_tab_link( |
| 205 | 209 | 'courses', |
| 206 | - $coursePostModel->get_id(), | |
| 207 | - 'overview' | |
| 210 | + $coursePostModel->get_id() | |
| 208 | 211 | ); |
| 209 | 212 | } |
| 210 | 213 | |
| 211 | 214 | $response->data->edit_course_url = $course_edit_url; |
| @@ -368,9 +371,9 @@ | ||
| 368 | 371 | $prompt = $params['lp-openai-prompt-generated-field'] ?? ''; |
| 369 | 372 | $args = [ |
| 370 | 373 | 'prompt' => $prompt, |
| 371 | 374 | 'n' => intval( $params['outputs'] ?? 1 ), |
| 372 | - 'size' => $params['size'] ?? '', | |
| 375 | + 'size' => '1024x1024', | |
| 373 | 376 | ]; |
| 374 | 377 | |
| 375 | 378 | $result = OpenAiService::instance()->send_request_create_image( $args ); |
| 376 | 379 | $html_image = ''; |
| @@ -433,9 +436,9 @@ | ||
| 433 | 436 | * Apply image feature to post |
| 434 | 437 | * Upload image to media and set as feature image for post |
| 435 | 438 | * |
| 436 | 439 | * @since 4.3.0 |
| 437 | - * @version 1.0.0 | |
| 440 | + * @version 1.0.2 | |
| 438 | 441 | */ |
| 439 | 442 | public function openai_apply_image_feature() { |
| 440 | 443 | $response = new LP_REST_Response(); |
| 441 | 444 | |
| @@ -460,8 +463,31 @@ | ||
| 460 | 463 | if ( empty( $post_id ) ) { |
| 461 | 464 | throw new Exception( __( 'Invalid post ID.', 'learnpress' ) ); |
| 462 | 465 | } |
| 463 | 466 | |
| 467 | + // Check permission | |
| 468 | + $post_type = get_post_type( $post_id ); | |
| 469 | + if ( $post_type === LP_COURSE_CPT ) { | |
| 470 | + $coursePostModel = CoursePostModel::find( $post_id, true ); | |
| 471 | + if ( ! $coursePostModel ) { | |
| 472 | + throw new Exception( __( 'Invalid course ID.', 'learnpress' ) ); | |
| 473 | + } | |
| 474 | + | |
| 475 | + if ( ! $coursePostModel->check_capabilities_update() ) { | |
| 476 | + throw new Exception( | |
| 477 | + __( 'You do not have permission to perform this action.', 'learnpress' ) | |
| 478 | + ); | |
| 479 | + } | |
| 480 | + } else { | |
| 481 | + $course_item_types = CourseModel::item_types_support(); | |
| 482 | + if ( ! in_array( $post_type, $course_item_types ) ) { | |
| 483 | + throw new Exception( __( 'Invalid post type.', 'learnpress' ) ); | |
| 484 | + } | |
| 485 | + | |
| 486 | + $postModel = PostModel::find_by_id( $post_id, true ); | |
| 487 | + $postModel->check_capabilities_update_item_course(); | |
| 488 | + } | |
| 489 | + | |
| 464 | 490 | if ( ! function_exists( 'media_handle_sideload' ) ) { |
| 465 | 491 | require_once ABSPATH . 'wp-admin/includes/media.php'; |
| 466 | 492 | require_once ABSPATH . 'wp-admin/includes/file.php'; |
| 467 | 493 | require_once ABSPATH . 'wp-admin/includes/image.php'; |
| @@ -466,17 +492,26 @@ | ||
| 466 | 492 | require_once ABSPATH . 'wp-admin/includes/file.php'; |
| 467 | 493 | require_once ABSPATH . 'wp-admin/includes/image.php'; |
| 468 | 494 | } |
| 469 | 495 | |
| 470 | - if ( ! empty( $image_url ) ) { | |
| 471 | - $tmp = download_url( $image_url ); | |
| 472 | - $fileExt = pathinfo( parse_url( $image_url, PHP_URL_PATH ), PATHINFO_EXTENSION ); | |
| 473 | - $filename = sanitize_file_name( $post_slug . '-' . uniqid() . '.' . $fileExt ); | |
| 496 | + // model gpt-image-1 only return base64, so don't need to download from url | |
| 497 | + if ( ! empty( $image_base64 ) ) { | |
| 498 | + $decoded_image = base64_decode( $image_base64 ); | |
| 499 | + if ( false === $decoded_image || '' === $decoded_image ) { | |
| 500 | + throw new Exception( __( 'Invalid image data.', 'learnpress' ) ); | |
| 501 | + } | |
| 474 | 502 | |
| 475 | - } elseif ( ! empty( $image_base64 ) ) { | |
| 476 | - $decoded_image = base64_decode( $image_base64 ); | |
| 477 | - $tmp = wp_tempnam(); | |
| 478 | - file_put_contents( $tmp, $decoded_image ); | |
| 503 | + $image_info = @getimagesizefromstring( $decoded_image ); | |
| 504 | + if ( false === $image_info ) { | |
| 505 | + throw new Exception( __( 'Decoded data is not a valid image.', 'learnpress' ) ); | |
| 506 | + } | |
| 507 | + | |
| 508 | + $tmp = wp_tempnam(); | |
| 509 | + $lp_wp_filesystem = LP_WP_Filesystem::instance(); | |
| 510 | + $put_contents_result = $lp_wp_filesystem->put_contents( $tmp, $decoded_image ); | |
| 511 | + if ( ! $put_contents_result || ! is_readable( $tmp ) ) { | |
| 512 | + throw new Exception( __( 'Decoded image is not readable.', 'learnpress' ) ); | |
| 513 | + } | |
| 479 | 514 | $filename = sanitize_file_name( $post_slug . '-' . uniqid() . '.png' ); |
| 480 | 515 | } else { |
| 481 | 516 | throw new Exception( __( 'No image data provided.', 'learnpress' ) ); |
| 482 | 517 | } |