diff --git a/inc/class-api.php b/inc/class-api.php new file mode 100644 index 0000000..18f4992 --- /dev/null +++ b/inc/class-api.php @@ -0,0 +1,264 @@ +register_route(); + } + + /** + * Get endpoint. + * + * @return string + */ + public function get_endpoint() { + return $this->namespace . '/' . $this->version; + } + + /** + * Register hooks and actions. + * + * @return void + */ + private function register_route() { + add_action( 'rest_api_init', array( $this, 'register_routes' ) ); + } + + /** + * Register REST API route + * + * @return void + */ + public function register_routes() { + $namespace = $this->namespace . '/' . $this->version; + + $routes = array( + 'send' => array( + 'methods' => \WP_REST_Server::CREATABLE, + 'args' => array( + 'step' => array( + 'required' => true, + 'type' => 'string', + ), + 'message' => array( + 'required' => false, + 'type' => 'string', + ), + ), + 'callback' => array( $this, 'send' ), + ), + 'status' => array( + 'methods' => \WP_REST_Server::READABLE, + 'args' => array( + 'thread_id' => array( + 'required' => true, + 'type' => 'string', + ), + 'run_id' => array( + 'required' => true, + 'type' => 'string', + ), + ), + 'callback' => array( $this, 'status' ), + ), + 'get' => array( + 'methods' => \WP_REST_Server::READABLE, + 'callback' => array( $this, 'get' ), + ), + 'images' => array( + 'methods' => \WP_REST_Server::READABLE, + 'args' => array( + 'query' => array( + 'required' => true, + 'type' => 'string', + ), + ), + 'callback' => array( $this, 'images' ), + ), + ); + + foreach ( $routes as $route => $args ) { + $args['permission_callback'] = function () { + return current_user_can( 'manage_options' ); + }; + + register_rest_route( $namespace, '/' . $route, $args ); + } + } + + /** + * Send data to the API. + * + * @param \WP_REST_Request $request Request. + * + * @return \WP_REST_Response + */ + public function send( \WP_REST_Request $request ) { + $data = $request->get_params(); + + $request = wp_remote_post( + QUICKWP_API . 'wizard/send', + array( + 'body' => array( + 'step' => $data['step'], + 'message' => $data['message'], + ), + ) + ); + + if ( is_wp_error( $request ) ) { + return new \WP_REST_Response( array( 'error' => $request->get_error_message() ), 500 ); + } + + /** + * Holds the response as a standard class object + * + * @var \stdClass $response + */ + $response = json_decode( wp_remote_retrieve_body( $request ) ); + + if ( ! isset( $response->id ) || ! $response->id ) { + return new \WP_REST_Response( array( 'error' => __( 'Error', 'quickwp' ) ), 500 ); + } + + return new \WP_REST_Response( $response, 200 ); + } + + /** + * Get status. + * + * @param \WP_REST_Request $request Request. + * + * @return \WP_REST_Response + */ + public function status( \WP_REST_Request $request ) { + $data = $request->get_params(); + + $request = wp_remote_get( // phpcs:ignore WordPressVIPMinimum.Functions.RestrictedFunctions.wp_remote_get_wp_remote_get + QUICKWP_API . 'wizard/status', + array( + 'body' => array( + 'thread_id' => $data['thread_id'], + 'run_id' => $data['run_id'], + ), + ) + ); + + if ( is_wp_error( $request ) ) { + return new \WP_REST_Response( array( 'error' => $request->get_error_message() ), 500 ); + } + + /** + * Holds the response as a standard class object + * + * @var \stdClass $response + */ + $response = json_decode( wp_remote_retrieve_body( $request ) ); + + if ( ! isset( $response->id ) || ! $response->id ) { + return new \WP_REST_Response( array( 'error' => __( 'Error', 'quickwp' ) ), 500 ); + } + + return new \WP_REST_Response( $response, 200 ); + } + + /** + * Get data. + * + * @param \WP_REST_Request $request Request. + * + * @return \WP_REST_Response + */ + public function get( \WP_REST_Request $request ) { + $data = $request->get_params(); + + $request = wp_remote_get(// phpcs:ignore WordPressVIPMinimum.Functions.RestrictedFunctions.wp_remote_get_wp_remote_get + QUICKWP_API . 'wizard/get', + array( + 'body' => array( + 'thread_id' => $data['thread_id'], + ), + ) + ); + + if ( is_wp_error( $request ) ) { + return new \WP_REST_Response( array( 'error' => $request->get_error_message() ), 500 ); + } + + /** + * Holds the response as a standard class object + * + * @var \stdClass $response + */ + $response = json_decode( wp_remote_retrieve_body( $request ) ); + + if ( ! isset( $response->data ) || ! $response->data ) { + return new \WP_REST_Response( array( 'error' => __( 'Error', 'quickwp' ) ), 500 ); + } + + return new \WP_REST_Response( $response, 200 ); + } + + /** + * Get images. + * + * @param \WP_REST_Request $request Request. + * + * @return \WP_REST_Response + */ + public function images( \WP_REST_Request $request ) { + $data = $request->get_params(); + + $request = wp_remote_get(// phpcs:ignore WordPressVIPMinimum.Functions.RestrictedFunctions.wp_remote_get_wp_remote_get + QUICKWP_API . 'wizard/images', + array( + 'body' => array( + 'query' => $data['query'], + ), + ) + ); + + if ( is_wp_error( $request ) ) { + return new \WP_REST_Response( array( 'error' => $request->get_error_message() ), 500 ); + } + + /** + * Holds the response as a standard class object + * + * @var \stdClass $response + */ + $response = json_decode( wp_remote_retrieve_body( $request ) ); + + if ( ! isset( $response->photos ) || count( $response->photos ) === 0 ) { + return new \WP_REST_Response( array( 'error' => __( 'Error', 'quickwp' ) ), 500 ); + } + + return new \WP_REST_Response( $response, 200 ); + } +} diff --git a/inc/class-main.php b/inc/class-main.php index 54aec2d..932ce52 100644 --- a/inc/class-main.php +++ b/inc/class-main.php @@ -7,16 +7,26 @@ namespace ThemeIsle\QuickWP; +use ThemeIsle\QuickWP\API; + /** * Main class. */ class Main { + /** + * API instance. + * + * @var API + */ + private $api; /** * Constructor. */ public function __construct() { $this->register_hooks(); + + $this->api = new API(); } /** @@ -62,5 +72,13 @@ public function enqueue_assets() { ); wp_set_script_translations( 'quickwp', 'quickwp' ); + + wp_localize_script( + 'quickwp', + 'quickwp', + array( + 'api' => $this->api->get_endpoint(), + ) + ); } } diff --git a/phpstan.neon b/phpstan.neon index 743b918..4b001c4 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -4,5 +4,6 @@ parameters: - %currentWorkingDirectory%/inc bootstrapFiles: - %currentWorkingDirectory%/tests/php/static-analysis-stubs/quickwp.php + checkGenericClassInNonGenericObjectType: false includes: - %currentWorkingDirectory%/vendor/szepeviktor/phpstan-wordpress/extension.neon \ No newline at end of file diff --git a/quickwp.php b/quickwp.php index c935f7e..0509da0 100644 --- a/quickwp.php +++ b/quickwp.php @@ -21,6 +21,7 @@ define( 'QUICKWP_URL', plugins_url( '/', __FILE__ ) ); define( 'QUICKWP_PATH', __DIR__ ); define( 'QUICKWP_VERSION', '1.0.0' ); +define( 'QUICKWP_API', 'https://4ab6-103-217-244-109.ngrok-free.app/api/' ); $vendor_file = QUICKWP_PATH . '/vendor/autoload.php'; diff --git a/src/App.js b/src/App.js index 3a32fa8..2538258 100644 --- a/src/App.js +++ b/src/App.js @@ -15,9 +15,21 @@ import Header from './parts/Header'; const App = () => { const isEditorLoading = useIsSiteEditorLoading(); - const currentStep = useSelect( ( select ) => - select( 'quickwp/data' ).getStep() - ); + const { + currentStep, + hasError + } = useSelect( select => { + const { + getStep, + hasError + } = select( 'quickwp/data' ); + + return { + currentStep: getStep(), + hasError: hasError() + }; + }); + const StepControls = currentStep?.view || null; if ( isEditorLoading ) { @@ -31,6 +43,22 @@ const App = () => { ); } + if ( hasError ) { + return ( +