ruạṛ
<?php /** * Handles all background proccessing interactions for the Envira Gallery plugin. * * @since 1.7.0 * * @package Envira Gallery * @author Envira Gallery Team <support@enviragallery.com> */ namespace Envira\Frontend; // Exit if accessed directly. if ( ! defined( 'ABSPATH' ) ) { exit; } use Envira\Utils\Cropping; use WP_REST_Response; /** * Background Processing Class. * * @since 1.7.0 */ class Background { /** * API Namespace * * (default value: 'envira') * * @since 1.7.0 * * @var string * @access public */ public $domain = 'envira-background'; /** * API Version * * (default value: 'v1') * * @since 1.7.0 * * @var string * @access public */ public $version = 'v1'; /** * Holds API Request * * (default value: null) * * @var mixed * @access public */ public $request = null; /** * Class Constructor. * * @since 1.7.0 * * @access public */ public function __construct() { // Actions. add_action( 'rest_api_init', [ $this, 'register_api_routes' ] ); } /** * Permission callback for background processing endpoints. * * @since 1.7.0 * * @param WP_REST_Request $request Request object. * @return bool|WP_REST_Response */ public function verify_background_permission( $request ) { // Check if user is logged in. if ( ! is_user_logged_in() ) { return new WP_REST_Response( [ 'message' => __( 'You must be logged in to access this feature.', 'envira-gallery' ) ], 401 ); } // Check if user can edit posts (basic capability for gallery management). $required_capability = apply_filters( 'envira_background_processing_capability', 'edit_posts' ); if ( ! current_user_can( $required_capability ) ) { return new WP_REST_Response( [ 'message' => __( 'You do not have permission to access this feature.', 'envira-gallery' ) ], 403 ); } // Validate the request using existing validation method. $valid = $this->validate_request( $request ); if ( ! $valid ) { return new WP_REST_Response( [ 'message' => __( 'Invalid request. Security check failed.', 'envira-gallery' ) ], 403 ); } return true; } /** * Register API Routes used for background proccessing. * * @since 1.7.0 * * @access public * @return void */ public function register_api_routes() { $name = $this->domain; $version = $this->version; register_rest_route( $name . '/' . $version, '/insert-gallery', [ 'methods' => 'POST', 'callback' => [ $this, 'maybe_insert_gallery' ], 'permission_callback' => [ $this, 'verify_background_permission' ], ] ); register_rest_route( $name . '/' . $version, '/insert-album', [ 'methods' => 'POST', 'callback' => [ $this, 'maybe_insert_album' ], 'permission_callback' => [ $this, 'verify_background_permission' ], ] ); register_rest_route( $name . '/' . $version, '/insert-image', [ 'methods' => 'POST', 'callback' => [ $this, 'insert_image' ], 'permission_callback' => [ $this, 'verify_background_permission' ], ] ); register_rest_route( $name . '/' . $version, '/crop-images', [ 'methods' => 'POST', 'callback' => [ $this, 'crop_images' ], 'permission_callback' => [ $this, 'verify_background_permission' ], ] ); register_rest_route( $name . '/' . $version, '/resize-image', [ 'methods' => 'POST', 'callback' => [ $this, 'resize' ], 'permission_callback' => [ $this, 'verify_background_permission' ], ] ); do_action( 'envira_gallery_routes', $name, $version ); } /** * Insert_gallery function. * * @since 1.7.0 * * @access public * @param \WP_REST_Request $request Request. * @return void */ public function maybe_insert_gallery( \WP_REST_Request $request ) { // Set the request. $this->request = $request; // Get the body. $body = $request->get_body_params(); // Validate the request. $valid = $this->validate_request( $request ); // Setup the ID Var. $post_id = ''; // Return if request not valid. if ( ! $valid ) { return; } $defaults = [ 'ID' => 0, 'post_type' => 'envira', 'post_status' => 'publish', 'post_title' => '', ]; $post_args = wp_parse_args( $body['data']['gallery'], $defaults ); if ( isset( $body['data']['id'] ) ) { $post_id = get_post( $body['data']['id'] ); } if ( ! $post_id ) { $post = wp_insert_post( $post_args ); } else { $post = wp_update_post( $post_args ); } // make a request to insert images is. if ( is_array( $body['data']['images'] ) ) { $images = $body['data']['images']; foreach ( $images as $image => $data ) { // Build the Image Data. $image_data = [ 'gallery' => $post, 'image' => $data, ]; // Make the background request for inserting each image. $this->background_request( $image_data, 'insert-image' ); } } die(); } /** * Background request to insert images into a gallery. * * @since 1.7.0 * * @access public * @param \WP_REST_Request $request Request. * @return void */ public function insert_image( \WP_REST_Request $request ) { global $wp_filesystem; if ( empty( $wp_filesystem ) ) { require_once ABSPATH . '/wp-admin/includes/file.php'; WP_Filesystem(); } // Set the request. $this->request = $request; // Get the body. $body = $request->get_body_params(); // Validate the request. $valid = $this->validate_request( $request ); // Return if request not valid. if ( ! $valid ) { return; } // Require if the function doesnt exist. if ( ! function_exists( 'wp_handle_sideload' ) ) { require_once ABSPATH . 'wp-admin/includes/file.php'; include ABSPATH . 'wp-admin/includes/image.php'; } $post_id = $body['data']['gallery']; $image = $body['data']['image']; // Check that $post_id is a envira post_type. if ( 'envira' !== get_post_type( $post_id ) ) { return false; } $in_gallery = get_post_meta( $post_id, '_eg_in_gallery', true ); if ( empty( $in_gallery ) ) { $in_gallery = []; } $gallery_data = get_post_meta( $post_id, '_eg_gallery_data', true ); // If Gallery Data is emptyy prepare it. if ( empty( $gallery_data ) ) { $gallery_data = []; } // Set the File name from the API. $new_attachment = $image['title']; // Grab the Upload Directory. $upload_dir = wp_upload_dir(); // Set the upload path. $upload_path = str_replace( '/', DIRECTORY_SEPARATOR, $upload_dir['path'] ) . DIRECTORY_SEPARATOR; // Decode the returned image. $image_upload = $wp_filesystem->put_contents( $upload_path . $new_attachment, $wp_filesystem->get_contents( $image['src'] ) ); // Prep the new file. $file = []; $file['error'] = ''; $file['tmp_name'] = $upload_path . $new_attachment; $file['name'] = $new_attachment; $file['type'] = $gallery_data; $file['size'] = wp_filesize( $upload_path . $new_attachment ); $file_return = wp_handle_sideload( $file, [ 'test_form' => false ] ); // Setup the Attachment Data. $attachment = [ 'post_type' => 'attachment', 'post_mime_type' => 'image/jpeg', 'post_title' => preg_replace( '/\.[^.]+$/', '', basename( $new_attachment ) ), 'post_content' => '', 'post_status' => 'inherit', 'post_parent' => $post_id, ]; // Insert new attachment - check. $attachment_id = wp_insert_attachment( $attachment, $file_return['file'], $post_id ); // Generate Attachment Metadata. $meta_data = wp_generate_attachment_metadata( $attachment_id, $file_return['file'] ); // Update Attachments metadata. $update_data = wp_update_attachment_metadata( $attachment_id, $meta_data ); // Update the attachment image post meta first. $has_slider = get_post_meta( $attachment_id, '_eg_has_gallery', true ); if ( empty( $has_slider ) ) { $has_slider = []; } $has_slider[] = $post_id; // Now add the image to the slider for this particular post. $in_slider[] = $attachment_id; $slider_data = envira_prepare_gallery_data( $gallery_data, $attachment_id ); // Update the slider data. update_post_meta( $attachment_id, '_eg_has_gallery', $has_slider ); update_post_meta( $post_id, '_eg_in_gallery', $in_slider ); update_post_meta( $post_id, '_eg_gallery_data', $slider_data ); die(); } /** * Maybe insert album function. * * @since 1.7.0 * * @access public * @param \WP_REST_Request $request Request. * @return void */ public function maybe_insert_album( \WP_REST_Request $request ) { // Set the request. $this->request = $request; // Get the body. $body = $request->get_body_params(); // Validate the request. $valid = $this->validate_request( $request ); // Setup the ID Var. $post_id = ''; // Return if request not valid. if ( ! $valid ) { die(); } $defaults = [ 'ID' => 0, 'post_type' => 'envira-album', 'post_status' => 'publish', 'post_title' => '', ]; $post_args = wp_parse_args( $body['data']['album'], $defaults ); if ( isset( $body['data']['id'] ) ) { $post_id = get_post( $body['data']['id'] ); } if ( ! $post_id ) { $post = wp_insert_post( $post_args ); } else { $post = wp_update_post( $post_args ); } // make a request to insert images is. if ( is_array( $body['data']['galleries'] ) ) { $galleries = $body['data']['galleries']; foreach ( $galleries as $gallery => $data ) { // Build the Image Data. $image_data = [ 'album' => $post, 'galleries' => $data, ]; // Make the background request for inserting each image. $this->background_request( $image_data, 'insert-gallery' ); } } die(); } /** * Crop and image via background request. * * @since 1.7.0 * * @access public * @param \WP_REST_Request $request Request. * @return void */ public function crop_images( \WP_REST_Request $request ) { // Set the request. $this->request = $request; // Get the body. $body = $request->get_body_params(); // Validate the request. $valid = $this->validate_request( $request ); // Return if request not valid. if ( ! $valid ) { die(); } $data = $body['data']; $gallery_data = _envira_get_gallery( $body['data']['id'] ); $gallery_id = $body['data']['id']; $images = ! empty( $gallery_data['gallery'] ) ? $gallery_data['gallery'] : false; $align = envira_get_config( 'crop_position', $gallery_data ); // Loop through the images and crop them. if ( $images ) { foreach ( $images as $id => $item ) { // Get the full image attachment. If it does not return the data we need, skip over it. $image = wp_get_attachment_image_src( $id, 'full' ); if ( ! is_array( $image ) ) { continue; } // Check the image is a valid URL. // Some plugins decide to strip the blog's URL. if ( ! filter_var( $image[0], FILTER_VALIDATE_URL ) ) { $image[0] = get_bloginfo( 'url' ) . '/' . $image[0]; } // If the thumbnails option is checked, crop images accordingly. if ( isset( $gallery_data['config']['thumbnails'] ) && $gallery_data['config']['thumbnails'] ) { $args = [ 'align' => $align, 'width' => apply_filters( 'envira_gallery_lightbox_thumbnail_width', $gallery_data['config']['thumbnails_width'], $gallery_data ), 'height' => apply_filters( 'envira_gallery_lightbox_thumbnail_height', $gallery_data['config']['thumbnails_height'], $gallery_data ), 'quality' => 100, 'retina' => false, ]; $crop_data = [ 'args' => $args, 'gallery_id' => $gallery_id, 'image_url' => $image[0], ]; // Generate the cropped image. $this->background_request( $crop_data, 'resize-image' ); $args['retina'] = true; $crop_data = [ 'args' => $args, 'gallery_id' => $gallery_id, 'image_url' => $image[0], ]; // Generate the cropped image. $this->background_request( $crop_data, 'resize-image' ); } // If the mobile thumbnails option is checked, crop images accordingly. if ( isset( $gallery_data['config']['mobile_thumbnails'] ) && $gallery_data['config']['mobile_thumbnails'] ) { $args = [ 'align' => $align, 'width' => apply_filters( 'envira_gallery_mobile_lightbox_thumbnail_width', $gallery_data['config']['mobile_thumbnails_width'], $gallery_data ), 'height' => apply_filters( 'envira_gallery_mobile_lightbox_thumbnail_height', $gallery_data['config']['mobile_thumbnails_height'], $gallery_data ), 'quality' => 100, 'retina' => false, ]; $crop_data = [ 'args' => $args, 'gallery_id' => $gallery_id, 'image_url' => $image[0], ]; // Generate the cropped image. $this->background_request( $crop_data, 'resize-image' ); $args['retina'] = true; $crop_data = [ 'args' => $args, 'gallery_id' => $gallery_id, 'image_url' => $image[0], ]; // Generate the cropped image. $this->background_request( $crop_data, 'resize-image' ); } // If the crop option is checked, crop images accordingly. if ( isset( $gallery_data['config']['crop'] ) && $gallery_data['config']['crop'] ) { $args = [ 'align' => $align, 'width' => envira_get_config( 'crop_width', $gallery_data ), 'height' => envira_get_config( 'crop_height', $gallery_data ), 'quality' => 100, 'retina' => false, ]; $crop_data = [ 'args' => $args, 'gallery_id' => $gallery_id, 'image_url' => $image[0], ]; // Generate the cropped image. $this->background_request( $crop_data, 'resize-image' ); $args['retina'] = true; $crop_data = [ 'args' => $args, 'gallery_id' => $gallery_id, 'image_url' => $image[0], ]; // Generate the cropped image. $this->background_request( $crop_data, 'resize-image' ); } // If the mobile option is checked, crop images accordingly. if ( isset( $gallery_data['config']['mobile'] ) && $gallery_data['config']['mobile'] ) { $args = [ 'align' => $align, 'width' => envira_get_config( 'mobile_width', $gallery_data ), 'height' => envira_get_config( 'mobile_height', $gallery_data ), 'quality' => 100, 'retina' => false, ]; $crop_data = [ 'args' => $args, 'gallery_id' => $gallery_id, 'image_url' => $image[0], ]; // Generate the cropped image. $this->background_request( $crop_data, 'resize-image' ); $args['retina'] = true; $crop_data = [ 'args' => $args, 'gallery_id' => $gallery_id, 'image_url' => $image[0], ]; // Generate the cropped image. $this->background_request( $crop_data, 'resize-image' ); } } } die(); } /** * Helper Request to resize images in the background. * * @since 1.7.0 * * @access public * @param \WP_REST_Request $request Request. * @return void */ public function resize( \WP_REST_Request $request ) { // Set the request. $this->request = $request; // Validate the request. $valid = $this->validate_request( $request ); // Get the body. $body = $request->get_body_params(); // Return if request not valid. if ( ! $valid ) { wp_send_json_error(); } $defaults = [ 'url' => '', 'id' => '', 'gallery_id' => '', 'width' => null, 'height' => null, 'crop' => true, 'align' => 'c', 'quality' => 100, 'retina' => false, 'data' => [], 'force_overwrite' => false, ]; $args = wp_parse_args( $body['data']['args'], $defaults ); $cropped_image = envira_resize_image( $body['data']['image_url'], $args['width'], $args['height'], true, $args['align'], $args['quality'], $args['retina'], null, $args['force_overwrite'] ); if ( $cropped_image ) { wp_send_json_success( $cropped_image ); } else { wp_send_json_error( $cropped_image ); } } /** * Validates the API request. * * @since 1.7.0 * * @param \WP_REST_Request $request Request. * @return bool True if valid, false otherwise. */ public function validate_request( $request ) { $body = $request->get_body_params(); if ( ! is_array( $body ) ) { return false; } // Verify the request is comming from the site. $site_url = get_home_url(); if ( strpos( $body['site'], $site_url ) === false ) { return false; } $token = get_option( 'envira_rest_token' ); if ( $token !== $request->get_header( 'X-Envira-Token' ) ) { return false; } do_action( 'envira_gallery_validate_bp' ); // All checks passed. return true; } /** * Self generated token to validate background requests. * * @access public * @return string */ public function generate_token() { $rest_token = wp_generate_password( 45, false, false ); $hash = hash( 'sha256', $rest_token ); update_option( 'envira_rest_token', $hash ); return $hash; } /** * Helper function to call background requests. * * @since 1.7.0 * * @access public * @param mixed $data Request Data. * @param mixed $type Request Type. * @return void */ public function background_request( $data, $type ) { // Bail if nothing set. if ( ! is_array( $data ) || ! isset( $type ) ) { return; } $name = $this->domain; $version = $this->version; $rest_url = get_rest_url(); $nonce = wp_create_nonce( 'wp_rest' ); $token = get_option( 'envira_rest_token' ); if ( ! $token ) { $token = $this->generate_token(); } $defaults = [ 'data' => $data, 'site' => get_home_url(), 'nonce' => $nonce, ]; $body = wp_parse_args( $data, $defaults ); $headers = [ 'X-Envira-Token' => $token, ]; // Generate the background request url. $url = trailingslashit( $rest_url ) . $name . '/' . $version . '/' . $type; $args = [ 'headers' => $headers, 'body' => $body, 'user-agent' => 'Envira/' . ENVIRA_VERSION, 'timeout' => 0.5, 'blocking' => false, 'sslverify' => apply_filters( 'envira_background_ssl_verify', false ), ]; $callit = wp_remote_post( $url, $args ); } }
cải xoăn