diff --git a/wordpress/wp-content/themes/saburly-headless/functions.php b/wordpress/wp-content/themes/saburly-headless/functions.php new file mode 100644 index 0000000..a24d55a --- /dev/null +++ b/wordpress/wp-content/themes/saburly-headless/functions.php @@ -0,0 +1,18 @@ + function ( $param, $request, $key ) { + return( is_string( $param ) ); + } + , + ]; + $post_slug_arg = array_merge( + $slug_arg, + [ + 'description' => 'String representing a valid WordPress post slug', + ] + ); + $page_slug_arg = array_merge( + $slug_arg, + [ + 'description' => 'String representing a valid WordPress page slug', + ] + ); + + // Register routes + register_rest_route( 'api/v1', '/post', [ + 'methods' => 'GET', + 'callback' => 'rest_get_post', + 'args' => [ + 'slug' => array_merge( + $post_slug_arg, + [ + 'required' => true, + ] + ), + ], + ] ); + + register_rest_route( 'api/v1', '/page', [ + 'methods' => 'GET', + 'callback' => 'rest_get_page', + 'args' => [ + 'slug' => array_merge( + $page_slug_arg, + [ + 'required' => true, + ] + ), + ], + ] ); + + register_rest_route('api/v1', '/post/preview', [ + 'methods' => 'GET', + 'callback' => 'rest_get_post_preview', + 'args' => [ + 'id' => [ + 'validate_callback' => function ( $param, $request, $key ) { + return ( is_numeric( $param ) ); + } + , + 'required' => true, + 'description' => 'Valid WordPress post ID', + ], + ], + 'permission_callback' => function () { + return current_user_can( 'edit_posts' ); + } + , + ] ); +} +); + + +/** +* Respond to a REST API request to get post data. + * + * @param WP_REST_Request $request Request. + * @return WP_REST_Response + */ +function rest_get_post( WP_REST_Request $request ) { + return rest_get_content( $request, 'post', __FUNCTION__ ); +} + + +/** +* Respond to a REST API request to get page data. + * + * @param WP_REST_Request $request Request. + * @return WP_REST_Response + */ +function rest_get_page( WP_REST_Request $request ) { + return rest_get_content( $request, 'page', __FUNCTION__ ); +} + + +/** +* Respond to a REST API request to get post or page data. + * * Handles changed slugs + * * Doesn't return posts whose status isn't published + * * Redirects to the admin when an edit parameter is present + * + * @param WP_REST_Request $request Request + * @param str $type Type + * @param str $function_name Function name + * @return WP_REST_Response + */ +function rest_get_content( WP_REST_Request $request, $type, $function_name ) { + $content_in_array = in_array( + $type, + [ + 'post', + 'page', + ], + true + ); + if ( ! $content_in_array ) { + $type = 'post'; + } + $slug = $request->get_param( 'slug' ); + $post = get_content_by_slug( $slug, $type ); + if ( ! $post ) { + return new WP_Error( + $function_name, + $slug . ' ' . $type . ' does not exist', + [ + 'status' => 404, + ] + ); + } + ; + + // Shortcut to WP admin page editor + $edit = $request->get_param( 'edit' ); + if ( 'true' === $edit ) { + header( 'Location: /wp-admin/post.php?post=' . $post->ID . '&action=edit' ); + exit; + } + $controller = new WP_REST_Posts_Controller( 'post' ); + $data = $controller->prepare_item_for_response( $post, $request ); + $response = $controller->prepare_response_for_collection( $data ); + + return new WP_REST_Response( $response ); +} + + +/** +* Returns a post or page given a slug. Returns false if no post matches. + * + * @param str $slug Slug + * @param str $type Valid values are 'post' or 'page' + * @return Post + */ +function get_content_by_slug( $slug, $type = 'post' ) { + $content_in_array = in_array( + $type, + [ + 'post', + 'page', + ], + true + ); + if ( ! $content_in_array ) { + $type = 'post'; + } + $args = [ + 'name' => $slug, + 'post_type' => $type, + 'post_status' => 'publish', + 'numberposts' => 1, + ]; + + // phpcs:ignore WordPress.VIP.RestrictedFunctions.get_posts_get_posts + $post_search_results = get_posts( $args ); + + if ( !$post_search_results ) { + // Maybe the slug changed + // check wp_postmeta table for old slug + $args = [ + // phpcs:ignore WordPress.VIP.SlowDBQuery.slow_db_query_meta_query + 'meta_query' => [ + [ + 'key' => '_wp_old_slug', + 'value' => $post_slug, + 'compare' => '=', + ], + ], + ]; + $query = new WP_Query( $args ); + $post_search_results = $query->posts; + } + if ( isset( $post_search_results[0] ) ) { + return $post_search_results[0]; + } + return false; +} + + +/** +* Respond to a REST API request to get a post's latest revision. + * * Requires a valid _wpnonce on the query string + * * User must have 'edit_posts' rights + * * Will return draft revisions of even published posts + * + * @param WP_REST_Request $request Rest request. + * @return WP_REST_Response + */ +function rest_get_post_preview( WP_REST_Request $request ) { + $post_id = $request->get_param( 'id' ); + // Revisions are drafts so here we remove the default 'publish' status + remove_action( 'pre_get_posts', 'set_default_status_to_publish' ); + $check_enabled = [ + 'check_enabled' => false, + ]; + if ( $revisions = wp_get_post_revisions( $post_id, $check_enabled ) ) { + $last_revision = reset( $revisions ); + $rev_post = wp_get_post_revision( $last_revision->ID ); + $controller = new WP_REST_Posts_Controller( 'post' ); + $data = $controller->prepare_item_for_response( $rev_post, $request ); + } elseif ( $post = get_post( $post_id ) ) { // There are no revisions, just return the saved parent post + $controller = new WP_REST_Posts_Controller( 'post' ); + $data = $controller->prepare_item_for_response( $post, $request ); + } else { + $not_found = [ + 'status' => 404, + ]; + $error = new WP_Error( + 'rest_get_post_preview', + 'Post ' . $post_id . ' does not exist', + $not_found + ); + return $error; + } + $response = $controller->prepare_response_for_collection( $data ); + return new WP_REST_Response( $response ); +} diff --git a/wordpress/wp-content/themes/saburly-headless/inc/cors.php b/wordpress/wp-content/themes/saburly-headless/inc/cors.php new file mode 100644 index 0000000..faf987e --- /dev/null +++ b/wordpress/wp-content/themes/saburly-headless/inc/cors.php @@ -0,0 +1,16 @@ + + // fallback - to deal with IE (or browsers that don't have console) + if (! window.console) console = {}; + console.log = console.log || function(name, data){}; + // end of fallback + + console.log('$name'); + console.log('------------------------------------------'); + console.log('$type'); + console.log($data); + console.log('\\n'); + +JSCODE; + + echo $js; // phpcs:ignore WordPress.XSS.EscapeOutput.OutputNotEscaped +} + +/** + * Log a value in wp-content/debug.log. + * To turn on, add the following to wp-config.php: + * + * define( 'WP_DEBUG', true ); + * define( 'WP_DEBUG_LOG', true ); // Turn logging to wp-content/debug.log ON + * define( 'WP_DEBUG_DISPLAY', false ); // Keep JSON response valid + * + * @ini_set( 'display_errors', 0 ); // Keep JSON responses valid + * + * NOT INTENDED FOR PRODUCTION USE. + * + * @param str $message Message + * @param str $file Filename, defaults to __FILE__ + * @param str $line Line number, defaults to __LINE__ + * @return void + */ +function log_it( $message, $file = __FILE__, $line = __LINE__ ) { + // phpcs:disable WordPress + if ( WP_DEBUG === true ) { + if ( is_array( $message ) || is_object( $message ) ) { + error_log( $file . 'L' . $line . ' ' . ( print_r( $message, true ) ) ); + } else { + error_log( $file . 'L' . $line . ' ' . $message ); + } + } + // phpcs:enable WordPress +} diff --git a/wordpress/wp-content/themes/saburly-headless/inc/menus.php b/wordpress/wp-content/themes/saburly-headless/inc/menus.php new file mode 100644 index 0000000..adc0277 --- /dev/null +++ b/wordpress/wp-content/themes/saburly-headless/inc/menus.php @@ -0,0 +1,12 @@ +ID ); +} elseif ( is_page() ) { + header( 'Location: /wp-json/wp/v2/pages/' . get_queried_object()->ID ); +} else { + header( 'Location: /wp-json/' ); +} diff --git a/wordpress/wp-content/themes/saburly-headless/post-content/sample-post.txt b/wordpress/wp-content/themes/saburly-headless/post-content/sample-post.txt new file mode 100644 index 0000000..6fe6613 --- /dev/null +++ b/wordpress/wp-content/themes/saburly-headless/post-content/sample-post.txt @@ -0,0 +1 @@ +Welcome to WordPress. This is your first post. Edit or delete it, then start writing! \ No newline at end of file diff --git a/wordpress/wp-content/themes/saburly-headless/post-content/welcome.txt b/wordpress/wp-content/themes/saburly-headless/post-content/welcome.txt new file mode 100644 index 0000000..6d0dc22 --- /dev/null +++ b/wordpress/wp-content/themes/saburly-headless/post-content/welcome.txt @@ -0,0 +1 @@ +You've successfully installed wordpress \ No newline at end of file diff --git a/wordpress/wp-content/themes/saburly-headless/screenshot.png b/wordpress/wp-content/themes/saburly-headless/screenshot.png new file mode 100644 index 0000000..d19300d Binary files /dev/null and b/wordpress/wp-content/themes/saburly-headless/screenshot.png differ diff --git a/wordpress/wp-content/themes/saburly-headless/style.css b/wordpress/wp-content/themes/saburly-headless/style.css new file mode 100644 index 0000000..e3ed297 --- /dev/null +++ b/wordpress/wp-content/themes/saburly-headless/style.css @@ -0,0 +1,7 @@ +/* +Theme Name: Saburly Website +Theme URI: https://www.saburly.com +Author: Saburly +Author URI: https://saburly.com +Description: Headless Wordpress API for Saburly.com +*/ \ No newline at end of file