├── .gitignore ├── README.md ├── apis ├── class-rae-register-auth-api.php ├── class-rae-register-get-post-api.php ├── class-rae-register-get-posts-api.php ├── class-rae-register-header-footer-api.php ├── class-rae-register-parse-blocks.php ├── class-rae-register-posts-api.php └── class-rae-test.php ├── create-new-post.gif ├── inc ├── class-rae-customizer.php └── custom-functions.php ├── login-endpoint-demo.gif └── rest-api-endpoints.php /.gitignore: -------------------------------------------------------------------------------- 1 | .idea/ 2 | *.log 3 | .DS_Store 4 | .cache 5 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # REST API ENDPOINT 2 | 3 | > This plugin provides you different endpoints using WordPress REST API. 4 | 5 | * :bust_in_silhouette: Login End Point 6 | * :page_with_curl: Create Post End Point 7 | 8 | ## Login Endpoint Demo :video_camera: 9 | 10 | When we access the end point on URI: `http://your-domain/wp-json/wp/v2/rae/user/login`, 11 | and we pass our username and password in the body using postman, we get the following with a status code: 12 | * User Object on success 13 | * Error when fields are empty or incorrect credentials 14 | * Any other error. 15 | 16 | ![](login-endpoint-demo.gif) 17 | 18 | ## Create a new post Endpoint Demo :video_camera: 19 | 20 | When we access the end point on URI: `http://your-domain/wp-json/wp/v2/rae/post/create`, 21 | and we pass our 'user_id', 'title' and 'content' in the body using postman, we get the following with a status code: 22 | * New post id if the post is created. 23 | * Error when fields are empty or if the user with the given id does not have capability to publish posts. 24 | * Any other error. 25 | 26 | ![](create-new-post.gif) 27 | 28 | ## Getting Started :clipboard: 29 | 30 | These instructions will get you a copy of the project up and running on your local machine for development purposes. 31 | 32 | ## Prerequisites :door: 33 | 34 | You need to have any WordPress theme activated on your WordPress project, which has REST API enabled. 35 | 36 | ## Installation :wrench: 37 | 38 | 1. Clone the plugin directory in the `/wp-content/plugins/` directory, or install a zipped directory of this plugin through the WordPress plugins screen directly. 39 | 2. Activate the plugin through the 'Plugins' screen in WordPress 40 | 41 | ## Use :ski: 42 | 43 | There are different end points that are available. Some are public while others are protected. 44 | 45 | * :bust_in_silhouette: Login End Point `http://your-domain/wp-json/wp/v2/rae/user/login` 46 | 47 | > Params to be sent in the body 48 | `username(String)` and `password(String)` 49 | Return Value: `User Object or Error (Object)` 50 | 51 | * :page_with_curl: Create Post End Point `http://your-domain/wp-json/wp/v2/rae/post/create` 52 | 53 | > Params to be sent in the body 54 | `user_id(Int)`, `title(String)` and `content(String)` 55 | Return Value: `Object with post ID and status or Error (Object)` 56 | 57 | 58 | ## Features 59 | * Adds option to add social links in customizer 60 | * Registers two custom menus for header ( menu location = rwt-menu-header ) and for footer ( menu location = rwt-menu-footer ) 61 | * Registers the following sidebars 62 | 1. RWT Footer #1 with sidebar id 'rwt-sidebar-1' 63 | 2. RWT Footer #2 with sidebar id 'rwt-sidebar-2' 64 | 65 | * Registers custom end points 66 | 67 | ## Available Endpoints: 68 | 69 | ### Get single post ( GET request ) 70 | * `http://example.com/wp-json/rae/v1/post?post_id=1` 71 | 72 | ### Get posts by page no: ( GET Request ) 73 | * `http://example.com/wp-json/rae/v1/posts?page_no=1` 74 | 75 | ### Get header and footer date: ( GET Request ) 76 | * Get the header data ( site title, site description , site logo URL, menu items ) and footer data ( footer menu items, social icons ) 77 | * `http://example.com/wp-json/rae/v1/header-footer?header_location_id=primary&footer_location_id=secondary` 78 | 79 | ### Create new post: ( POST Request ) 80 | * http://example.com/wp-json/rae/v1/post/create 81 | 82 | ## Contributing :busts_in_silhouette: 83 | 84 | Please read [CONTRIBUTING.md](https://gist.github.com/PurpleBooth/b24679402957c63ec426) for details on our code of conduct, and the process for submitting pull requests to us. 85 | 86 | ## Versioning 87 | 88 | I use [Git](https://github.com/) for versioning. 89 | 90 | ## Author :pencil: 91 | 92 | * **[Imran Sayed](https://codeytek.com)** 93 | 94 | ## License :page_facing_up: 95 | 96 | [![License](http://img.shields.io/:license-mit-blue.svg?style=flat-square)](http://badges.mit-license.org) 97 | 98 | - **[MIT license](http://opensource.org/licenses/mit-license.php)** 99 | -------------------------------------------------------------------------------- /apis/class-rae-register-auth-api.php: -------------------------------------------------------------------------------- 1 | 'POST', 35 | 'callback' => array( $this, 'rae_rest_user_login_endpoint_handler' ), 36 | )); 37 | } 38 | 39 | /** 40 | * User Login call back. 41 | * 42 | * @param WP_REST_Request $request 43 | */ 44 | function rae_rest_user_login_endpoint_handler( WP_REST_Request $request ) { 45 | $response = array(); 46 | $parameters = $request->get_params(); 47 | 48 | $username = sanitize_text_field( $parameters['username'] ); 49 | $password = sanitize_text_field( $parameters['password'] ); 50 | 51 | // Error Handling. 52 | $error = new WP_Error(); 53 | 54 | if ( empty( $username ) ) { 55 | $error->add( 56 | 400, 57 | __( "Username field is required", 'rest-api-endpoints' ), 58 | array( 'status' => 400 ) 59 | ); 60 | 61 | return $error; 62 | } 63 | 64 | if ( empty( $password ) ) { 65 | $error->add( 66 | 400, 67 | __( "Password field is required", 'rest-api-endpoints' ), 68 | array( 'status' => 400 ) 69 | ); 70 | 71 | return $error; 72 | } 73 | 74 | $user = wp_authenticate( $username, $password ); 75 | 76 | // If user found 77 | if ( ! is_wp_error( $user ) ) { 78 | $response['status'] = 200; 79 | $response['user'] = $user; 80 | } else { 81 | // If user not found 82 | $error->add( 406, __( 'User not found. Check credentials', 'rest-api-endpoints' ) ); 83 | return $error; 84 | } 85 | 86 | return new WP_REST_Response( $response ); 87 | } 88 | } 89 | 90 | new Rae_Register_Auth_API(); 91 | 92 | -------------------------------------------------------------------------------- /apis/class-rae-register-get-post-api.php: -------------------------------------------------------------------------------- 1 | post_type = 'post'; 17 | $this->route = '/post'; 18 | 19 | add_action( 'rest_api_init', [ $this, 'rest_posts_endpoints' ] ); 20 | } 21 | 22 | /** 23 | * Register posts endpoints. 24 | */ 25 | public function rest_posts_endpoints() { 26 | 27 | /** 28 | * Handle Posts Request: GET Request 29 | * 30 | * This endpoint takes 'page_no' in query params of the request. 31 | * Returns the posts data object on success 32 | * Also handles error by returning the relevant error. 33 | * 34 | * Example: http://example.com/wp-json/rae/v1/post?post_id=1 35 | */ 36 | register_rest_route( 37 | 'rae/v1', 38 | $this->route, 39 | [ 40 | 'method' => 'GET', 41 | 'callback' => [ $this, 'rest_endpoint_handler' ], 42 | ] 43 | ); 44 | } 45 | 46 | /** 47 | * Get posts call back. 48 | * 49 | * Returns the posts data object on success 50 | * 51 | * @param WP_REST_Request $request request object. 52 | * 53 | * @return WP_Error|WP_REST_Response response object. 54 | */ 55 | public function rest_endpoint_handler( WP_REST_Request $request ) { 56 | $response = []; 57 | $parameters = $request->get_params(); 58 | $post_id = ! empty( $parameters['post_id'] ) ? intval( sanitize_text_field( $parameters['post_id'] ) ) : ''; 59 | 60 | // Error Handling. 61 | $error = new WP_Error(); 62 | 63 | $post_data = $this->get_required_post_data( $post_id ); 64 | 65 | // If posts found. 66 | if ( ! empty( $post_data ) ) { 67 | 68 | $response['status'] = 200; 69 | $response['post_data'] = $post_data; 70 | 71 | } else { 72 | 73 | // If the posts not found. 74 | $error->add( 406, __( 'Post not found', 'rest-api-endpoints' ) ); 75 | 76 | return $error; 77 | 78 | } 79 | 80 | return new WP_REST_Response( $response ); 81 | 82 | } 83 | 84 | /** 85 | * Construct a post data that contains, title, excerpt and featured image. 86 | * 87 | * @param {array} $post_ID post id. 88 | * 89 | * @return array 90 | */ 91 | public function get_required_post_data( $post_ID ) { 92 | 93 | $post_data = []; 94 | 95 | if ( empty( $post_ID ) && ! is_array( $post_ID ) ) { 96 | return $post_data; 97 | } 98 | 99 | $author_id = get_post_field( 'post_author', $post_ID ); 100 | $attachment_id = get_post_thumbnail_id( $post_ID ); 101 | 102 | $post_data = []; 103 | $post_data['id'] = $post_ID; 104 | $post_data['title'] = get_the_title( $post_ID ); 105 | $post_data['excerpt'] = get_the_excerpt( $post_ID ); 106 | $post_data['date'] = get_the_date( '', $post_ID ); 107 | $post_data['attachment_image'] = [ 108 | 'img_sizes' => wp_get_attachment_image_sizes( $attachment_id ), 109 | 'img_src' => wp_get_attachment_image_src( $attachment_id, 'full' ), 110 | 'img_srcset' => wp_get_attachment_image_srcset( $attachment_id ), 111 | ]; 112 | $post_data['categories'] = get_the_category( $post_ID ); 113 | $post_data['meta'] = [ 114 | 'author_id' => $author_id, 115 | 'author_name' => get_the_author_meta( 'display_name', $author_id ) 116 | ]; 117 | 118 | 119 | return $post_data; 120 | } 121 | } 122 | 123 | new Rae_Register_Get_Post_Api(); 124 | -------------------------------------------------------------------------------- /apis/class-rae-register-get-posts-api.php: -------------------------------------------------------------------------------- 1 | post_type = 'post'; 15 | $this->route = '/posts'; 16 | $this->post_per_page = 9; 17 | 18 | add_action( 'rest_api_init', [ $this, 'rest_posts_endpoints' ] ); 19 | } 20 | 21 | /** 22 | * Register posts endpoints. 23 | */ 24 | public function rest_posts_endpoints() { 25 | 26 | /** 27 | * Handle Posts Request: GET Request 28 | * 29 | * This endpoint takes 'page_no' in query params of the request. 30 | * Returns the posts data object on success 31 | * Also handles error by returning the relevant error. 32 | * 33 | * Example: http://example.com/wp-json/rae/v1/posts?page_no=1 34 | */ 35 | register_rest_route( 36 | 'rae/v1', 37 | $this->route, 38 | [ 39 | 'method' => 'GET', 40 | 'callback' => [ $this, 'rest_endpoint_handler' ], 41 | ] 42 | ); 43 | } 44 | 45 | /** 46 | * Get posts call back. 47 | * 48 | * Returns the posts data object on success 49 | * 50 | * @param WP_REST_Request $request request object. 51 | * 52 | * @return WP_Error|WP_REST_Response response object. 53 | */ 54 | public function rest_endpoint_handler( WP_REST_Request $request ) { 55 | $response = []; 56 | $parameters = $request->get_params(); 57 | $posts_page_no = ! empty( $parameters['page_no'] ) ? intval( sanitize_text_field( $parameters['page_no'] ) ) : ''; 58 | 59 | // Error Handling. 60 | $error = new WP_Error(); 61 | 62 | $posts_data = $this->get_posts( $posts_page_no ); 63 | 64 | // If posts found. 65 | if ( ! empty( $posts_data['posts_data'] ) ) { 66 | 67 | $response['status'] = 200; 68 | $response['posts_data'] = $posts_data['posts_data']; 69 | $response['found_posts'] = $posts_data['found_posts']; 70 | $response['page_count'] = $posts_data['page_count']; 71 | 72 | } else { 73 | 74 | // If the posts not found. 75 | $error->add( 406, __( 'Posts not found', 'rest-api-endpoints' ) ); 76 | 77 | return $error; 78 | 79 | } 80 | 81 | return new WP_REST_Response( $response ); 82 | 83 | } 84 | 85 | /** 86 | * Calculate page count. 87 | * 88 | * @param int $total_found_posts Total posts found. 89 | * @param int $post_per_page Post per page count. 90 | * 91 | * @return int 92 | */ 93 | public function calculate_page_count( $total_found_posts, $post_per_page ) { 94 | return ( (int) ( $total_found_posts / $post_per_page ) + ( ( $total_found_posts % $post_per_page ) ? 1 : 0 ) ); 95 | } 96 | 97 | 98 | /** 99 | * Get posts data. 100 | * 101 | * @param integer $page_no page no. 102 | * 103 | * @return array Posts. 104 | */ 105 | public function get_posts( $page_no = 1 ) { 106 | 107 | $args = [ 108 | 'post_type' => $this->post_type, 109 | 'post_status' => 'publish', 110 | 'posts_per_page' => $this->post_per_page, 111 | 'fields' => 'ids', 112 | 'orderby' => 'date', 113 | 'paged' => $page_no, 114 | 'update_post_meta_cache' => false, 115 | 'update_post_term_cache' => false, 116 | 117 | ]; 118 | 119 | $latest_post_ids = new WP_Query( $args ); 120 | 121 | $post_result = $this->get_required_posts_data( $latest_post_ids->posts ); 122 | $found_posts = $latest_post_ids->found_posts; 123 | $page_count = $this->calculate_page_count( $found_posts, $this->post_per_page ); 124 | 125 | return [ 126 | 'posts_data' => $post_result, 127 | 'found_posts' => $found_posts, 128 | 'page_count' => $page_count, 129 | 130 | ]; 131 | } 132 | 133 | /** 134 | * Construct a post array that contains, title, excerpt and featured image. 135 | * 136 | * @param {array} $post_IDs post ids. 137 | * 138 | * @return array 139 | */ 140 | public function get_required_posts_data( $post_IDs ) { 141 | 142 | $post_result = []; 143 | 144 | if ( empty( $post_IDs ) && ! is_array( $post_IDs ) ) { 145 | return $post_result; 146 | } 147 | 148 | foreach ( $post_IDs as $post_ID ) { 149 | 150 | $author_id = get_post_field( 'post_author', $post_ID ); 151 | $attachment_id = get_post_thumbnail_id( $post_ID ); 152 | 153 | $post_data = []; 154 | $post_data['id'] = $post_ID; 155 | $post_data['title'] = get_the_title( $post_ID ); 156 | $post_data['excerpt'] = get_the_excerpt( $post_ID ); 157 | $post_data['date'] = get_the_date( '', $post_ID ); 158 | $post_data['attachment_image'] = [ 159 | 'img_sizes' => wp_get_attachment_image_sizes( $attachment_id ), 160 | 'img_src' => wp_get_attachment_image_src( $attachment_id, 'full' ), 161 | 'img_srcset' => wp_get_attachment_image_srcset( $attachment_id ), 162 | ]; 163 | $post_data['categories'] = get_the_category( $post_ID ); 164 | $post_data['meta'] = [ 165 | 'author_id' => $author_id, 166 | 'author_name' => get_the_author_meta( 'display_name', $author_id ) 167 | ]; 168 | 169 | array_push( $post_result, $post_data ); 170 | 171 | } 172 | 173 | return $post_result; 174 | } 175 | } 176 | 177 | new Rae_Register_Get_Posts_Api(); 178 | -------------------------------------------------------------------------------- /apis/class-rae-register-header-footer-api.php: -------------------------------------------------------------------------------- 1 | route = '/header-footer'; 17 | add_action( 'rest_api_init', [ $this, 'rest_posts_endpoints' ] ); 18 | } 19 | 20 | /** 21 | * Register posts endpoints. 22 | */ 23 | public function rest_posts_endpoints() { 24 | 25 | /** 26 | * Handle Posts Request: GET Request 27 | * 28 | * This api gets the header and footer of the site. 29 | * The data will include: 30 | * 1. Site Logo 31 | * 2. Header menu with the given menu location id 32 | * 3. Footer menu with the given menu location id 33 | * 34 | * The 'header_location_id' here is a string e.g. 'primary' or whatever 'header_location_id' name you have used at the time of registration of the menu. 35 | * 36 | * Example: http://example.com/wp-json/rae/v1/header-footer?header_location_id=primary&footer_location_id=secondary 37 | */ 38 | register_rest_route( 39 | 'rae/v1', 40 | $this->route, 41 | [ 42 | 'method' => 'GET', 43 | 'callback' => [ $this, 'rest_endpoint_handler' ], 44 | ] 45 | ); 46 | } 47 | 48 | /** 49 | * Get posts call back. 50 | * 51 | * Returns the menu items array of object on success 52 | * 53 | * @param WP_REST_Request $request request object. 54 | * 55 | * @return WP_Error|WP_REST_Response response object. 56 | */ 57 | public function rest_endpoint_handler( WP_REST_Request $request ) { 58 | $response = []; 59 | $parameters = $request->get_params(); 60 | $header_menu_location_id = ! empty( $parameters['header_location_id'] ) ? sanitize_text_field( $parameters['header_location_id'] ) : ''; 61 | $footer_menu_location_id = ! empty( $parameters['footer_location_id'] ) ? sanitize_text_field( $parameters['footer_location_id'] ) : ''; 62 | 63 | // Error Handling. 64 | $error = new WP_Error(); 65 | 66 | $header_menu_items = $this->get_nav_menu_items( $header_menu_location_id ); 67 | $footer_menu_items = $this->get_nav_menu_items( $footer_menu_location_id ); 68 | 69 | // If any menus found. 70 | if ( ! empty( $header_menu_items ) || ! empty( $footer_menu_items ) ) { 71 | 72 | $response['status'] = 200; 73 | $response['data'] = [ 74 | 'header' => [ 75 | 'siteLogoUrl' => $this->get_custom_logo_url( 'custom_logo' ), 76 | 'siteTitle' => get_bloginfo( 'title' ), 77 | 'siteDescription' => get_bloginfo( 'description' ), 78 | 'favicon' => get_site_icon_url(), 79 | 'headerMenuItems' => $header_menu_items, 80 | ], 81 | 'footer' => [ 82 | 'footerMenuItems' => $footer_menu_items, 83 | 'socialLinks' => $this->get_social_icons(), 84 | 'copyrightText' => $this->get_copyright_text(), 85 | 'footerSidebarOne' => $this->get_sidebar( 'rwt-sidebar-1' ), 86 | 'footerSidebarTwo' => $this->get_sidebar( 'rwt-sidebar-2' ), 87 | ] 88 | ]; 89 | 90 | } else { 91 | 92 | // If the posts not found. 93 | $error->add( 406, __( 'Data not found', 'rest-api-endpoints' ) ); 94 | 95 | return $error; 96 | 97 | } 98 | 99 | return new WP_REST_Response( $response ); 100 | 101 | } 102 | 103 | /** 104 | * Get Custom logo URL. 105 | * 106 | * @return string 107 | */ 108 | public function get_custom_logo_url( $key ) { 109 | 110 | $custom_logo_id = get_theme_mod( $key ); 111 | $image = wp_get_attachment_image_src( $custom_logo_id , 'full' ); 112 | return $image[0]; 113 | } 114 | 115 | /** 116 | * Get social icons 117 | * 118 | * @return array $social_icons 119 | */ 120 | public function get_social_icons() { 121 | 122 | $social_icons = []; 123 | $social_icons_name = [ 'facebook', 'twitter', 'instagram', 'youtube' ]; 124 | 125 | foreach ( $social_icons_name as $social_icon_name ) { 126 | 127 | $social_link = get_theme_mod( sprintf( 'rae_%s_link', $social_icon_name ) ); 128 | 129 | if ( $social_link ) { 130 | array_push( $social_icons, [ 131 | 'iconName' =>esc_attr( $social_icon_name ), 132 | 'iconUrl' => esc_url( $social_link ) 133 | ] ); 134 | } 135 | } 136 | 137 | return $social_icons; 138 | 139 | } 140 | 141 | /** 142 | * Get copyright text 143 | * 144 | * @return mixed 145 | */ 146 | public function get_copyright_text() { 147 | return get_theme_mod( 'rae_footer_text' ); 148 | } 149 | 150 | /** 151 | * Get nav menu items by location 152 | * 153 | * @param string $location The menu location id 154 | * @param array $args Arguments. 155 | * 156 | * @return array $menu_data Menu items array of Objects. 157 | */ 158 | function get_nav_menu_items( $location, $args = [] ) { 159 | 160 | if ( empty( $location ) ) { 161 | return ''; 162 | } 163 | 164 | // Get all locations 165 | $locations = get_nav_menu_locations(); 166 | 167 | // Get object id by location 168 | $object = wp_get_nav_menu_object( $locations[ $location ] ); 169 | 170 | // Get menu items by menu name 171 | $menu_data = wp_get_nav_menu_items( $object->name, $args ); 172 | $menu_items = []; 173 | 174 | if ( ! empty( $menu_data ) ) { 175 | 176 | // Menus ( Loop through the menu, and push all the parent menu items first ). 177 | foreach ( $menu_data as $item ) { 178 | if ( empty( $item->menu_item_parent ) ) { 179 | $menu_item = []; 180 | $menu_item['ID'] = $item->ID; 181 | $menu_item['title'] = $item->title; 182 | $menu_item['url'] = $item->url; 183 | $menu_item['children'] = []; 184 | 185 | // We are also getting the page slug and the page id that this menu is linked to. 186 | $menu_item['pageSlug'] = get_post_field( 'post_name', $item->object_id ); 187 | $menu_item['pageID'] = intval( $item->object_id ); 188 | 189 | array_push( $menu_items, $menu_item ); 190 | } 191 | } 192 | 193 | // Submenus: ( Loop through the menu again, and push all the child menu items ). 194 | foreach ( $menu_data as $item ) { 195 | 196 | // If the menu has a parent, it means its a child menu. 197 | if ( $item->menu_item_parent ) { 198 | 199 | // Create a child menu array. 200 | $submenu_item = []; 201 | $submenu_item['ID'] = $item->ID; 202 | $submenu_item['title'] = $item->title; 203 | $submenu_item['url'] = $item->url; 204 | 205 | // We are also getting the page slug and the page id that this menu is linked to. 206 | $submenu_item['pageSlug'] = get_post_field( 'post_name', $item->object_id ); 207 | $submenu_item['pageID'] = intval( $item->object_id ); 208 | 209 | // Loop through the menu items and find the parent whose child this is. 210 | foreach( $menu_items as $key => $parent_item ) { 211 | 212 | // if the parent id of this child menu, is same as the parent menu id. 213 | if ( intval( $item->menu_item_parent ) === $parent_item['ID'] ) { 214 | 215 | // push the child menu into its parent menu children property. 216 | array_push( $menu_items[ $key ]['children'], $submenu_item ); 217 | 218 | } 219 | } 220 | 221 | } 222 | } 223 | 224 | } 225 | 226 | $menu_items = ! empty( $menu_items ) ? $menu_items : ''; 227 | 228 | // Return menu post objects 229 | return $menu_items; 230 | 231 | } 232 | 233 | /** 234 | * Returns the content of all the sidebars with given sidebar id. 235 | * 236 | * @param $sidebar_id 237 | * 238 | * @return false|string 239 | */ 240 | public function get_sidebar( $sidebar_id ) { 241 | ob_start(); 242 | 243 | dynamic_sidebar( ); 244 | $output = ob_get_contents( $sidebar_id ); 245 | 246 | ob_end_clean(); 247 | 248 | return $output; 249 | } 250 | } 251 | 252 | new Rae_Register_Header_Footer_Api(); 253 | -------------------------------------------------------------------------------- /apis/class-rae-register-parse-blocks.php: -------------------------------------------------------------------------------- 1 | post_type = 'post'; 15 | $this->route = '/parse-block'; 16 | 17 | add_action( 'rest_api_init', [ $this, 'rest_posts_endpoints' ] ); 18 | } 19 | 20 | /** 21 | * Register posts endpoints. 22 | */ 23 | public function rest_posts_endpoints() { 24 | 25 | /** 26 | * Handle Posts Request: GET Request 27 | * 28 | * This endpoint takes 'page_no' in query params of the request. 29 | * Returns the posts data object on success 30 | * Also handles error by returning the relevant error. 31 | * 32 | * Example: http://example.com/wp-json/rae/v1/parse-block?post_id=1 33 | */ 34 | register_rest_route( 35 | 'rae/v1', 36 | $this->route, 37 | [ 38 | 'method' => 'GET', 39 | 'callback' => [ $this, 'rest_endpoint_handler' ], 40 | ] 41 | ); 42 | } 43 | 44 | /** 45 | * Get posts call back. 46 | * 47 | * Returns the posts data object on success 48 | * 49 | * @param WP_REST_Request $request request object. 50 | * 51 | * @return WP_Error|WP_REST_Response response object. 52 | */ 53 | public function rest_endpoint_handler( WP_REST_Request $request ) { 54 | $response = []; 55 | $parameters = $request->get_params(); 56 | $post_id = ! empty( $parameters['post_id'] ) ? intval( sanitize_text_field( $parameters['post_id'] ) ) : ''; 57 | 58 | // Error Handling. 59 | $error = new WP_Error(); 60 | 61 | $parsed_block = $this->get_parsed_block_content( $post_id ); 62 | 63 | // If posts found. 64 | if ( ! empty( $parsed_block ) ) { 65 | 66 | $response['status'] = 200; 67 | $response['parsed_block'] = $parsed_block; 68 | 69 | } else { 70 | 71 | // If the posts not found. 72 | $error->add( 406, __( 'Post not found', 'rest-api-endpoints' ) ); 73 | 74 | return $error; 75 | 76 | } 77 | 78 | return new WP_REST_Response( $response ); 79 | 80 | } 81 | 82 | /** 83 | * Get the parsed content of the block. 84 | * 85 | * @param {array} $post_ID post id. 86 | * 87 | * @return array 88 | */ 89 | public function get_parsed_block_content( $post_ID ) { 90 | 91 | $parsed_content = []; 92 | 93 | if ( empty( $post_ID ) && ! is_array( $post_ID ) ) { 94 | return $parsed_content; 95 | } 96 | 97 | $post_result = get_post( $post_ID ); 98 | 99 | $parsed_content = parse_blocks( $post_result->post_content ); 100 | 101 | 102 | return $parsed_content; 103 | } 104 | } 105 | 106 | new Rae_Register_Parse_Block(); 107 | -------------------------------------------------------------------------------- /apis/class-rae-register-posts-api.php: -------------------------------------------------------------------------------- 1 | 'POST', 34 | 'callback' => array( $this, 'rae_rest_create_post_endpoint_handler' ), 35 | )); 36 | } 37 | 38 | /** 39 | * Creat Post call back. 40 | * 41 | * @param WP_REST_Request $request 42 | */ 43 | function rae_rest_create_post_endpoint_handler( WP_REST_Request $request ) { 44 | $response = array(); 45 | $parameters = $request->get_params(); 46 | 47 | $user_id = sanitize_text_field( $parameters['user_id'] ); 48 | $title = sanitize_text_field( $parameters['title'] ); 49 | $content = sanitize_text_field( $parameters['content'] ); 50 | 51 | // Error Handling. 52 | $error = new WP_Error(); 53 | 54 | if ( empty( $user_id ) ) { 55 | $error->add( 56 | 400, 57 | __( "User ID field is required", 'rest-api-endpoints' ), 58 | array( 'status' => 400 ) 59 | ); 60 | 61 | return $error; 62 | } 63 | 64 | if ( empty( $title ) ) { 65 | $error->add( 66 | 400, 67 | __( "Title field is required", 'rest-api-endpoints' ), 68 | array( 'status' => 400 ) 69 | ); 70 | 71 | return $error; 72 | } 73 | 74 | if ( empty( $content ) ) { 75 | $error->add( 76 | 400, 77 | __( "Body field is required", 'rest-api-endpoints' ), 78 | array( 'status' => 400 ) 79 | ); 80 | 81 | return $error; 82 | } 83 | 84 | // Check if the user with this id can publish posts 85 | $user_can_publish_post = user_can( $user_id,'publish_posts' ); 86 | if ( ! $user_can_publish_post ) { 87 | $error->add( 88 | 400, 89 | __( "You don't have previlige to publish a post", 'rest-api-endpoints' ), 90 | array( 'status' => 400 ) 91 | ); 92 | 93 | return $error; 94 | } 95 | 96 | $my_post = array( 97 | 'post_type' => 'post', 98 | 'post_author' => $user_id, 99 | 'post_title' => sanitize_text_field( $title ), 100 | 'post_status' => 'publish', 101 | 'post_content' => $content, 102 | ); 103 | // It will return the new inserted $post_id 104 | $post_id = wp_insert_post( $my_post ); 105 | 106 | // If user found 107 | if ( ! is_wp_error( $post_id ) ) { 108 | $response['status'] = 200; 109 | $response['post_id'] = $post_id; 110 | } else { 111 | // If user not found 112 | $error->add( 406, __( 'Post creating failed', 'rest-api-endpoints' ) ); 113 | return $error; 114 | } 115 | 116 | return new WP_REST_Response( $response ); 117 | } 118 | } 119 | 120 | new Rae_Register_Posts_Api(); 121 | -------------------------------------------------------------------------------- /apis/class-rae-test.php: -------------------------------------------------------------------------------- 1 | post_type = 'post'; 25 | $this->route = '/mytest'; 26 | 27 | add_action( 'rest_api_init', array( $this, 'rae_rest_posts_endpoints' ) ); 28 | 29 | } 30 | 31 | /** 32 | * Register posts endpoints. 33 | */ 34 | public function rae_rest_posts_endpoints() { 35 | 36 | /** 37 | * Handle Get Media Releases Posts Request: GET Request 38 | * 39 | * This endpoint takes 'categories_child_id', 'audience_child_id' both optionally in query params of the request. 40 | * Returns the user object on success 41 | * Also handles error by returning the relevant error if the fields are empty. 42 | * 43 | * Example: http://example.com/wp-json/rae/v1/mytest 44 | */ 45 | register_rest_route( 46 | 'rae/v1', 47 | $this->route, 48 | array( 49 | 'methods' => 'POST', 50 | 'callback' => array( $this, 'rae_rest_endpoint_handler' ), 51 | ) 52 | ); 53 | } 54 | 55 | public function get_all_cookies( $cookies_as_string ) { 56 | $headerCookies = explode('; ', $cookies_as_string ); 57 | $cookies = array(); 58 | foreach( $headerCookies as $itm ) { 59 | list( $key, $val ) = explode( '=', $itm,2 ); 60 | $cookies[ $key ] = $val; 61 | } 62 | 63 | return $cookies ; 64 | } 65 | 66 | 67 | /** 68 | * Get posts call back. 69 | * 70 | * It will return posts with given term ids, else the default posts. 71 | * 72 | * @param WP_REST_Request $request request object. 73 | * 74 | * @return WP_Error|WP_REST_Response response object. 75 | */ 76 | public function rae_rest_endpoint_handler( WP_REST_Request $request ) { 77 | 78 | $response = []; 79 | $parameters = $request->get_params(); 80 | $posts_page_no = ! empty( $parameters['page_no'] ) ? intval( sanitize_text_field( $parameters['page_no'] ) ) : 1; 81 | 82 | 83 | // setcookie( 'hey', 'hjhj', time() + 3600, 'http://localhost:8080/' ); 84 | 85 | // header("Set-Cookie: yourCookie=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwOlwvXC9sb2NhbGhvc3Q6ODg4OFwvd29yZHByZXNzLWxvZ2luIiwiaWF0IjoxNTcxNDA5NzE5LCJuYmYiOjE1NzE0MDk3MTksImV4cCI6MTU3MjAxNDUxOSwiZGF0YSI6eyJ1c2VyIjp7ImlkIjoiMSJ9fX0.vcqPmj9lQaFHQ20Z_7gDXHAlW2Vev7lkht4Gj4WBqdA; httpOnly"); 86 | header("Set-Cookie: authToken=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwOlwvXC9sb2NhbGhvc3Q6ODg4OFwvd29yZHByZXNzLWxvZ2luIiwiaWF0IjoxNTcxNDA5NzE5LCJuYmYiOjE1NzE0MDk3MTksImV4cCI6MTU3MjAxNDUxOSwiZGF0YSI6eyJ1c2VyIjp7ImlkIjoiMSJ9fX0.vcqPmj9lQaFHQ20Z_7gDXHAlW2Vev7lkht4Gj4WBqdA; httpOnly"); 87 | // header("Set-Cookie: myCookie='sdsd'; expires=Friday, 22-Feb-14 22:03:38 GMT; httpOnly"); 88 | 89 | 90 | $header = $request->get_headers(); 91 | $cookies = $this->get_all_cookies( $header['cookie'][0] ); 92 | 93 | $result = $this->validate_token( $cookies['authToken'] ); 94 | 95 | return new WP_REST_Response( $result ); 96 | 97 | // Error Handling. 98 | $error = new WP_Error(); 99 | 100 | $cases_data = []; 101 | 102 | // If posts found. 103 | if ( ! is_wp_error( $cases_data['cases_posts'] ) && ! empty( $cases_data['cases_posts'] ) ) { 104 | $response['status'] = 200; 105 | $response['cases_posts'] = $cases_data['cases_posts']; 106 | $response['found_posts'] = $cases_data['found_posts']; 107 | 108 | $total_found_posts = intval( $cases_data['found_posts'] ); 109 | $response['page_count'] = $this->calculate_page_count( $total_found_posts, 9 ); 110 | 111 | } else { 112 | // If posts not found. 113 | $error->add( 406, __( 'Media Releases Posts not found', 'rest-api-endpoints' ) ); 114 | return $error; 115 | } 116 | 117 | return new WP_REST_Response( $response ); 118 | } 119 | 120 | /** 121 | * Main validation function, this function try to get the Autentication 122 | * headers and decoded. 123 | * 124 | * @param bool $output 125 | * 126 | * @return WP_Error | Object | Array 127 | */ 128 | public function validate_token( $token, $output = true) 129 | { 130 | 131 | /** Get the Secret Key */ 132 | $secret_key = defined('JWT_AUTH_SECRET_KEY') ? JWT_AUTH_SECRET_KEY : false; 133 | 134 | if (!$secret_key) { 135 | return new WP_Error( 136 | 'jwt_auth_bad_config', 137 | 'JWT is not configurated properly, please contact the admin', 138 | array( 139 | 'status' => 403, 140 | ) 141 | ); 142 | } 143 | 144 | /** Try to decode the token */ 145 | try { 146 | $token = JWT::decode($token, $secret_key, array('HS256')); 147 | /** The Token is decoded now validate the iss */ 148 | if ($token->iss != get_bloginfo('url')) { 149 | /** The iss do not match, return error */ 150 | return new WP_Error( 151 | 'jwt_auth_bad_iss', 152 | 'The iss do not match with this server', 153 | array( 154 | 'status' => 403, 155 | ) 156 | ); 157 | } 158 | /** So far so good, validate the user id in the token */ 159 | if (!isset($token->data->user->id)) { 160 | /** No user id in the token, abort!! */ 161 | return new WP_Error( 162 | 'jwt_auth_bad_request', 163 | 'User ID not found in the token', 164 | array( 165 | 'status' => 403, 166 | ) 167 | ); 168 | } 169 | /** Everything looks good return the decoded token if the $output is false */ 170 | if (!$output) { 171 | return $token; 172 | } 173 | /** If the output is true return an answer to the request to show it */ 174 | return array( 175 | 'code' => 'jwt_auth_valid_token', 176 | 'data' => array( 177 | 'status' => 200, 178 | ), 179 | ); 180 | } catch (Exception $e) { 181 | /** Something is wrong trying to decode the token, send back the error */ 182 | return new WP_Error( 183 | 'jwt_auth_invalid_token', 184 | $e->getMessage(), 185 | array( 186 | 'status' => 403, 187 | ) 188 | ); 189 | } 190 | } 191 | 192 | 193 | } 194 | 195 | new Rae_Test(); 196 | -------------------------------------------------------------------------------- /create-new-post.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imranhsayed/rest-api-endpoints/3f3158dfaf82ce7a084e5f446f6bb0c236adeeb8/create-new-post.gif -------------------------------------------------------------------------------- /inc/class-rae-customizer.php: -------------------------------------------------------------------------------- 1 | _setup_hooks(); 18 | } 19 | 20 | /** 21 | * To register action/filter. 22 | * 23 | * @return void 24 | */ 25 | function _setup_hooks() { 26 | /** 27 | * Actions 28 | */ 29 | add_action( 'customize_register', [ $this, 'customize_register' ] ); 30 | } 31 | 32 | /** 33 | * Customize register. 34 | * 35 | * @param \WP_Customize_Manager $wp_customize Theme Customizer object. 36 | * 37 | * @action customize_register 38 | */ 39 | public function customize_register( \WP_Customize_Manager $wp_customize ) { 40 | 41 | $this->social_icon_section( $wp_customize ); 42 | $this->footer_section( $wp_customize ); 43 | 44 | } 45 | 46 | public function footer_section( $wp_customize ) { 47 | 48 | $wp_customize->add_section( 49 | 'rae_footer', 50 | [ 51 | 'title' => esc_html__( 'Footer', 'rest-api-endpoints' ), 52 | 'description' => esc_html__( 'Footer', 'rest-api-endpoints' ), 53 | ] 54 | ); 55 | 56 | $setting_id = 'rae_footer_text'; 57 | 58 | $wp_customize->add_setting( 59 | $setting_id, 60 | [ 61 | 'default' => '', 62 | 'capability' => 'edit_theme_options', 63 | 'sanitize_callback' => 'esc_html', 64 | ] 65 | ); 66 | 67 | $wp_customize->add_control( 68 | $setting_id, 69 | [ 70 | 'label' => esc_html__( 'Copyright text', 'rest-api-endpoints' ), 71 | 'section' => 'rae_footer', 72 | 'settings' => $setting_id, 73 | 'type' => 'text', 74 | ] 75 | ); 76 | } 77 | 78 | /** 79 | * Add social icon section. 80 | * 81 | * @param $wp_customize 82 | */ 83 | public function social_icon_section( $wp_customize ) { 84 | 85 | // Social Icons 86 | $social_icons = [ 'facebook', 'twitter', 'instagram', 'youtube' ]; 87 | 88 | $wp_customize->add_section( 89 | 'rae_social_links', 90 | [ 91 | 'title' => esc_html__( 'Social Links', 'rest-api-endpoints' ), 92 | 'description' => esc_html__( 'Social links', 'rest-api-endpoints' ), 93 | ] 94 | ); 95 | 96 | foreach ( $social_icons as $social_icon ) { 97 | 98 | $setting_id = sprintf( 'rae_%s_link', $social_icon ); 99 | 100 | $wp_customize->add_setting( 101 | $setting_id, 102 | [ 103 | 'default' => '', 104 | 'capability' => 'edit_theme_options', 105 | 'sanitize_callback' => 'esc_url', 106 | ] 107 | ); 108 | 109 | $wp_customize->add_control( 110 | $setting_id, 111 | [ 112 | 'label' => esc_html( $social_icon ), 113 | 'section' => 'rae_social_links', 114 | 'settings' => $setting_id, 115 | 'type' => 'text', 116 | ] 117 | ); 118 | } 119 | } 120 | } 121 | 122 | new Rae_Customizer(); 123 | -------------------------------------------------------------------------------- /inc/custom-functions.php: -------------------------------------------------------------------------------- 1 | esc_html__( 'RWT Header Menu', 'rest-api-endpoints' ), 14 | 'rwt-menu-footer' => esc_html__( 'RWT Footer Menu', 'rest-api-endpoints' ), 15 | ] ); 16 | } 17 | add_action( 'init', 'rae_custom_new_menu' ); 18 | 19 | /** 20 | * Register Sidebar 21 | */ 22 | 23 | /** 24 | * Register widget areas. 25 | * 26 | * @link https://developer.wordpress.org/themes/functionality/sidebars/#registering-a-sidebar 27 | */ 28 | function rae_sidebar_registration() { 29 | 30 | // Arguments used in all register_sidebar() calls. 31 | $shared_args = [ 32 | 'before_title' => '

', 33 | 'after_title' => '

', 34 | 'before_widget' => '
', 35 | 'after_widget' => '
', 36 | ]; 37 | 38 | // Footer #1. 39 | register_sidebar( 40 | array_merge( 41 | $shared_args, 42 | [ 43 | 'name' => __( 'RWT Footer #1', 'rest-api-endpoints' ), 44 | 'id' => 'rwt-sidebar-1', 45 | 'description' => __( 'Widgets in this area will be displayed in the first column in the footer.', 'rest-api-endpoints' ), 46 | ] 47 | ) 48 | ); 49 | 50 | // Footer #2. 51 | register_sidebar( 52 | array_merge( 53 | $shared_args, 54 | [ 55 | 'name' => __( 'RWT Footer #2', 'rest-api-endpoints' ), 56 | 'id' => 'rwt-sidebar-2', 57 | 'description' => __( 'Widgets in this area will be displayed in the second column in the footer.', 'rest-api-endpoints' ), 58 | ] 59 | ) 60 | ); 61 | 62 | } 63 | 64 | add_action( 'widgets_init', 'rae_sidebar_registration' ); 65 | 66 | 67 | if ( function_exists( 'register_sidebar' ) ) { 68 | register_sidebar(); 69 | } 70 | 71 | -------------------------------------------------------------------------------- /login-endpoint-demo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imranhsayed/rest-api-endpoints/3f3158dfaf82ce7a084e5f446f6bb0c236adeeb8/login-endpoint-demo.gif -------------------------------------------------------------------------------- /rest-api-endpoints.php: -------------------------------------------------------------------------------- 1 |