X7ROOT File Manager
Current Path:
/home/hamdjcne/public_html/wp-content/plugins/otter-blocks/inc/server
home
/
hamdjcne
/
public_html
/
wp-content
/
plugins
/
otter-blocks
/
inc
/
server
/
ðŸ“
..
📄
class-dashboard-server.php
(5.1 KB)
📄
class-dynamic-content-server.php
(7.18 KB)
📄
class-form-server.php
(31.92 KB)
📄
class-fse-onboarding-server.php
(2.76 KB)
📄
class-prompt-server.php
(9.13 KB)
📄
class-stripe-server.php
(3.47 KB)
Editing: class-prompt-server.php
<?php /** * Prompt server logic. * * @package ThemeIsle\GutenbergBlocks\Server */ namespace ThemeIsle\GutenbergBlocks\Server; /** * Class Prompt_Server */ class Prompt_Server { /** * The main instance var. * * @var Prompt_Server|null */ public static $instance = null; /** * Rest route namespace. * * @var string */ public $namespace = 'otter/'; /** * Rest route version. * * @var string */ public $version = 'v1'; /** * Transient name for prompts. * * @var string */ public $transient_prompts = 'otter_prompts'; /** * Timeout for prompts request. * * @var string */ public $timeout_transient = 'otter_prompts_timeout'; /** * Initialize the class */ public function init() { add_action( 'rest_api_init', array( $this, 'register_routes' ) ); } /** * Register REST API route */ public function register_routes() { $namespace = $this->namespace . $this->version; register_rest_route( $namespace, '/prompt', array( array( 'methods' => \WP_REST_Server::READABLE, 'callback' => array( $this, 'get_prompts' ), 'permission_callback' => function () { return current_user_can( 'edit_posts' ); }, ), ) ); register_rest_route( $namespace, '/generate', array( array( 'methods' => \WP_REST_Server::CREATABLE, 'callback' => array( $this, 'forward_prompt' ), 'permission_callback' => function () { return current_user_can( 'edit_posts' ); }, ), ) ); } /** * Forward the prompt to OpenAI API. * * @param \WP_REST_Request $request Request object. * @return \WP_Error|\WP_HTTP_Response|\WP_REST_Response */ public function forward_prompt( $request ) { $open_ai_endpoint = 'https://api.openai.com/v1/chat/completions'; // Get the body from request and decode it. $body = $request->get_body(); $body = json_decode( $body, true ); $api_key = get_option( 'themeisle_open_ai_api_key' ); // Extract the data from keys that start with 'otter_'. $otter_data = array_filter( $body, function ( $key ) { return 0 === strpos( $key, 'otter_' ); }, ARRAY_FILTER_USE_KEY ); // Remove the values which keys start with 'otter_'. $body = array_diff_key( $body, $otter_data ); $response = wp_remote_post( $open_ai_endpoint, array( 'method' => 'POST', 'headers' => array( 'Authorization' => 'Bearer ' . $api_key, 'Content-Type' => 'application/json', ), 'body' => wp_json_encode( $body ), 'timeout' => 2 * MINUTE_IN_SECONDS, ) ); if ( is_wp_error( $response ) ) { return $response; } $body = wp_remote_retrieve_body( $response ); $body = json_decode( $body, true ); if ( json_last_error() !== JSON_ERROR_NONE ) { return new \WP_Error( 'rest_invalid_json', __( 'Could not parse the response from OpenAI. Try again.', 'otter-blocks' ), array( 'status' => 400 ) ); } return new \WP_REST_Response( $body, wp_remote_retrieve_response_code( $response ) ); } /** * Get prompts. * * @param \WP_REST_Request $request Request object. * @return \WP_Error|\WP_HTTP_Response|\WP_REST_Response */ public function get_prompts( $request ) { $response = array( 'prompts' => array(), 'code' => '0', 'error' => '', ); // Get the saved prompts. $prompts = get_transient( $this->transient_prompts ); if ( false === $prompts ) { /** * If we don't have the prompts saved, we need to retrieve them from the server. Once retrieved, we save them in a transient and return them. */ $response = $this->retrieve_prompts_from_server(); } if ( '0' === $response['code'] ) { if ( $request->get_param( 'name' ) !== null ) { $prompts = ! empty( $prompts ) ? $prompts : $response['prompts']; // Prompt can be filtered by name. By filtering by name, we can get only the prompt we need and save some bandwidth. $single_prompt = array_values( array_filter( $prompts, function ( $prompt ) use ( $request ) { return $prompt['otter_name'] === $request->get_param( 'name' ); } ) ); if ( empty( $single_prompt ) ) { $response['prompts'] = $prompts; $response['code'] = '1'; $response['error'] = __( 'Something went wrong when preparing the data for this feature.', 'otter-blocks' ); } else { $response['prompts'] = $single_prompt; } } else { $response['prompts'] = $prompts; } } return rest_ensure_response( $response ); } /** * * Retrieve prompts from server. * * @return array */ public function retrieve_prompts_from_server() { if ( false !== get_transient( $this->timeout_transient ) ) { return array( 'response' => array(), 'code' => '3', 'error' => __( 'Timeout is active. Please try again in', 'otter-blocks' ) . 5 . __( 'minutes.', 'otter-blocks' ), ); } $url = add_query_arg( array( 'site_url' => get_site_url(), 'license_id' => apply_filters( 'product_otter_license_key', 'free' ), 'cache' => gmdate( 'u' ), 'isValid' => boolval( get_option( 'themeisle_open_ai_api_key', false ) ) ? 'true' : 'false', ), 'https://api.themeisle.com/templates-cloud/otter-prompts' ); $response = ''; if ( function_exists( 'vip_safe_wp_remote_get' ) ) { $response = vip_safe_wp_remote_get( esc_url_raw( $url ) ); } else { $response = wp_remote_get( esc_url_raw( $url ) ); // phpcs:ignore WordPressVIPMinimum.Functions.RestrictedFunctions.wp_remote_get_wp_remote_get } $response = wp_remote_retrieve_body( $response ); $response = json_decode( $response, true ); if ( ! is_array( $response ) || 0 === count( $response ) || ! $this->check_prompt_structure( $response ) ) { set_transient( $this->timeout_transient, '1', 5 * MINUTE_IN_SECONDS ); return array( 'response' => array(), 'code' => '2', 'error' => __( 'Invalid data from central server. Please try again in', 'otter-blocks' ) . 5 . __( 'minutes.', 'otter-blocks' ), ); } set_transient( $this->transient_prompts, $response, WEEK_IN_SECONDS ); return array( 'prompts' => $response, 'code' => '0', 'error' => '', ); } /** * Check if the prompt structure is valid. * * @param mixed $response Response from the server. * @return bool */ public function check_prompt_structure( $response ) { if ( ! isset( $response ) ) { return false; } if ( ! is_array( $response ) ) { return false; } if ( 0 === count( $response ) ) { return false; } return true; } /** * Record prompt usage. * * @param array $otter_metadata The metadata from the prompt usage request. * @return void * @phpstan-ignore-next-line */ private function record_prompt_usage( $otter_metadata ) { if ( ! isset( $otter_metadata['otter_used_action'] ) || ! isset( $otter_metadata['otter_user_content'] ) ) { return; } $action = $otter_metadata['otter_used_action']; $user_content = $otter_metadata['otter_user_content']; $usage = get_option( 'themeisle_otter_ai_usage' ); if ( ! is_array( $usage ) ) { $usage = array( 'usage_count' => array(), 'prompts' => array(), ); } if ( ! is_array( $usage['usage_count'] ) ) { $usage['usage_count'] = array(); } if ( ! is_array( $usage['prompts'] ) ) { $usage['prompts'] = array(); } $is_missing = true; foreach ( $usage['usage_count'] as &$u ) { if ( isset( $u['key'] ) && $u['key'] === $action ) { $u['value']++; $is_missing = false; } } unset( $u ); if ( $is_missing ) { $usage['usage_count'][] = array( 'key' => $action, 'value' => 1, ); } $is_missing = true; foreach ( $usage['prompts'] as &$u ) { if ( isset( $u['key'] ) && $u['key'] === $action ) { $u['values'][] = $user_content; $is_missing = false; // Keep only the last 10 prompts. if ( count( $u['values'] ) > 10 ) { array_shift( $u['values'] ); } } } unset( $u ); if ( $is_missing ) { $usage['prompts'][] = array( 'key' => $action, 'values' => array( $user_content ), ); } update_option( 'themeisle_otter_ai_usage', $usage ); } /** * The instance method for the static class. * Defines and returns the instance of the static class. * * @static * @since 1.7.0 * @access public * @return Prompt_Server */ public static function instance() { if ( is_null( self::$instance ) ) { self::$instance = new self(); self::$instance->init(); } return self::$instance; } /** * Throw error on object clone * * The whole idea of the singleton design pattern is that there is a single * object therefore, we don't want the object to be cloned. * * @access public * @since 1.7.0 * @return void */ public function __clone() { // Cloning instances of the class is forbidden. _doing_it_wrong( __FUNCTION__, esc_html__( 'Cheatin’ huh?', 'otter-blocks' ), '1.0.0' ); } /** * Disable unserializing of the class * * @access public * @since 1.7.0 * @return void */ public function __wakeup() { // Unserializing instances of the class is forbidden. _doing_it_wrong( __FUNCTION__, esc_html__( 'Cheatin’ huh?', 'otter-blocks' ), '1.0.0' ); } }
Upload File
Create Folder