Wordpress WP API Extending - 404 on Endpoints - wordpress

I'm trying to create a few custom JSON endpoints for my plugin. I installed the WP API plugin and here's the entire contents of my plugin php.
<?php
/**
* Plugin Name: Quiz Wordpress Plugin
* Plugin URI: http://www.domain.com
* Description: This plugin handles quiz functionality.
* Version: 1.0.0
* Author: Ray Hwang
* Author URI: http://www.domain.com
* License: private
*/
function quiz_api_init() {
global $quiz_api;
$quiz_api = new QUIZ_API();
add_filter( 'json_endpoints', array( $quiz_api, 'register_routes' ) );
}
add_action( 'wp_json_server_before_serve', 'quiz_api_init' );
class QUIZ_API {
public function register_routes( $routes ) {
$routes['/api'] = array(
array( array( $this, 'get_quiz'), WP_JSON_Server::READABLE ),
array( array( $this, 'new_quiz'), WP_JSON_Server::CREATABLE | WP_JSON_Server::ACCEPT_JSON ),
);
return $routes;
}
public function get_quiz($_headers, $data = ''){
return array ('a'=>1,'b'=>2,'c'=>3,'d'=>4,'e'=>5);
}
public function new_quiz($_headers, $data = ''){
return array ('a'=>1,'b'=>2,'c'=>3,'d'=>4,'e'=>5);
}
}
There are no errors when I activate the plugin. When I request the endpoint. I get
Not Found
The requested URL /api was not found on this server.
Apache/2.4.7 (Ubuntu) Server at ec2-----.compute-1.amazonaws.com Port 80
Does it have something to do with URL rewrite or permalinks?
My permalink settings is set to default http://ec2--------.compute-1.amazonaws.com/?p=123

You will need to ensure you've gone into permalink settings and saved to force the rewrite rules to be written again.
Also a great tool I use during my plugin development to ensure that the rewrite rules are actually applied is Rewrite Rules Inspector it'll list all your current rules including your new endpoints if they have been added.

Related

How to Create a Deep Link to a Facebook App from a WP Elementor Page

I am trying to create a Facebook deep link like this - fb://profile/100079662604962 to add to an image hyperlink for a site I am building in WordPress using Elementor. I see that they do not allow this type of URI as a default. How can I create deep links to Facebook, Twitter, Instagram and Pinterest using Elementor?
I tried to insert the URI link in the Content dialog box, but found from another site that this does not work, as per this function:
function wp_allowed_protocols() {
static $protocols = array();
if ( empty( $protocols ) ) {
$protocols = array( 'http', 'https', 'ftp', 'ftps', 'mailto', 'news', 'irc', 'irc6', 'ircs', 'gopher', 'nntp', 'feed', 'telnet', 'mms', 'rtsp', 'sms', 'svn', 'tel', 'fax', 'xmpp', 'webcal', 'urn' );
}
if ( ! did_action( 'wp_loaded' ) ) {
/**
* Filters the list of protocols allowed in HTML attributes.
*
* #since 3.0.0
*
* #param string[] $protocols Array of allowed protocols e.g. 'http', 'ftp', 'tel', and more.
*/
$protocols = array_unique( (array) apply_filters( 'kses_allowed_protocols', $protocols ) );
}
return $protocols;
}
Any help would be appreciated.

Wordpress improve REST API - SHORTINIT not work

i'm trying to improve the performance of Wordpress API custom endpoints.
I created a plugin, simple file under plugin/PLUGIN_NAME folder where I call "register_rest_route" function to set the endpoints.
To improve the performance I am trying to load not all the plugins, but only what I need, Wordpress CORE to query users and posts and Ultimate Members.
That's my code:
define('SHORTINIT', true);
require_once dirname(__FILE__) . '/../../../wp-load.php';
require_once dirname(__FILE__) . '/../ultimate-member/ultimate-member.php';
add_action('rest_api_init', function () {
register_rest_route( 'my-api/v1', 'test/me',array(
'methods' => 'POST',
'callback' => 'test'
}
));
...
...
It work, but the problem is that works also if I not load "wp-load.php" script. In my test method I use WP_User_Query, WP_Query and ultimate member method like um_user().
It seems like SHORTINIT didn't work.
What I wrong ?
Reading the source code of wp-settings.php shows a problem:
// lines 144 to 147 of wp-settings.php
// Stop most of WordPress from being loaded if we just want the basics.
if ( SHORTINIT ) {
return false;
}
// lines 359 to 373 of wp-settings.php
// Load active plugins.
foreach ( wp_get_active_and_valid_plugins() as $plugin ) {
wp_register_plugin_realpath( $plugin );
include_once( $plugin );
/**
* Fires once a single activated plugin has loaded.
*
* #since 5.1.0
*
* #param string $plugin Full path to the plugin's main file.
*/
do_action( 'plugin_loaded', $plugin );
}
unset( $plugin );
The check for SHORTINIT is done before plugins are loaded. So your "define('SHORTINIT', true);" is executed after not before SHORTINIT is checked and has no effect.
Further wp-settings.php is included indirectly from wp-load.php so when your plugin code is executed wp-load.php has already been included.
Who have my same problem, I recommend using Plugin Load Filter, a wordpress plugin that let you select which plugins to activate in the REST API.

Restrict WordPress Rest API requests to my domain

I have a WordPress website which I use just to populate blog posts and some private posts under custom post types. In another website, I am using the REST API to display the posts. If I use software like Postman, I can display data from the REST API.
How can I prevent any unauthorized REST API requests to domain www.example.com ? so if the request is not coming from www.mysite.com, it is blocked?
Basically prevent my custom post types (example.com) to be visible to the rest api if it is not coming from mysite.com
You can Disable External request by adding this in your wp-config.php ( Also, you can specify domain which you don't want to block like this).
define( 'WP_HTTP_BLOCK_EXTERNAL', TRUE );
define( 'WP_ACCESSIBLE_HOSTS', 'example.com, domain.com' );
apply_filters( 'rest_authentication_errors', WP_Error|null|bool )
Filters REST authentication errors.Put code in functions.php in your theme directory.
Complete description : https://developer.wordpress.org/reference/hooks/rest_authentication_errors/
add_filter( 'rest_authentication_errors', 'wpse150207_filter_incoming_connections' );
function wpse150207_filter_incoming_connections( $errors ){
$allowed_ips = array( '127.0.0.1' );
$request_server = $_SERVER['REMOTE_ADDR'];
if( ! in_array( $request_server, $allowed_ips ) )
return new WP_Error( 'forbidden_access', 'Access denied', array( 'status' => 403 ) );
return $errors;
}
One way to restrict REST requests is to hook at rest_api_init with priority 1, and whitelist the IP's you want. In this example, I restrict REST access to the server itself only:
/**
* Disables WordPress Rest API for external requests
*/
add_action('rest_api_init', function() {
$whitelist = ['127.0.0.1', "::1"];
if(!in_array($_SERVER['REMOTE_ADDR'], $whitelist)){
die('REST API is disabled.');
}
}, 1);

Algolia - WordPress - instantsearch page how do I exclude post with certain ID

On Algolia instantsearch page (WordPress plugin) how do I exclude post with certain ID?
This is the default instantsearch setup. How do I add filter to exclude post ID from the search?
var search = instantsearch({
appId: algolia.application_id,
apiKey: algolia.search_api_key,
indexName: algolia.indices.searchable_posts.name,
urlSync: {
mapping: {'q': 's'},
trackedParameters: ['query']
},
searchParameters: {
facetingAfterDistinct: true,
highlightPreTag: '__ais-highlight__',
highlightPostTag: '__/ais-highlight__'
}
});
The only good solution to not display posts as part of the results is to not index them.
Indexing with the Algolia plugin for WordPress is explained here in detail: https://community.algolia.com/wordpress/indexing-flow.html#indexing-decision
Here is a code snippet that should get you started:
<?php
// to put in the functions.php file of your active theme.
/**
* #param bool $should_index
* #param WP_Post $post
*
* #return bool
*/
function exclude_post_ids( $should_index, WP_Post $post )
{
// Add all post IDs you don't want to make searchable.
$excluded_ids = array( 14, 66 );
if ( false === $should_index ) {
return false;
}
return ! in_array( $post->ID, $excluded_ids, true );
}
// Hook into Algolia to manipulate the post that should be indexed.
add_filter( 'algolia_should_index_searchable_post', 'exclude_post_ids', 10, 2 );
Go to plug in folder > includes > class-algolia-search.php
and find this code
$query->set( 'post__in', $post_ids );
exactly after that code add this code
$query->set( 'post__not_in', array(1,2,3));
Then let me know the result.
In my code 1,2,3 are post ids which you want to exclude.
Thanks

Wordpress Rest API

Is it possible to access pluggin's data from WordPress database with some Rest API. I saw WP REST API but it doesn't give access to pluggin's data.
More specifically I use LearnDash pluggin and I want to access courses infos but they doesn't provide any API to access it.
Thanks
Overall you need to search Google for things having to do with "Wordpress rest api custom post type" and eventually you'll be dealing with registering custom post types and endpoints in your theme's functions.php
Here is the manual: https://developer.wordpress.org/rest-api/extending-the-rest-api
As an example, here is my situation: I'm using WordPress (4.7) and The Events Calendar ("TEC") plugin. I'm querying the WP DB from an Android app using the REST API, however the only data that's available to REST is basic WP post stuff. I need to expose the custom data in the TEC plugin to the REST API. In order to do that, I've included the following into my functions.php in my theme:
functions.php
/* Exposing the custom post type of the plugin to the REST API.
* In this case, for The Tribe Events Calendar plugin, the custom post type is
* "tribe_events". For other plugins it will be different. */
add_action( 'init', 'my_custom_post_type_rest_support', 25 );
function my_custom_post_type_rest_support() {
global $wp_post_types;
//be sure to set this to the name of your post type!
$post_type_name = 'tribe_events';
if( isset( $wp_post_types[ $post_type_name ] ) ) {
$wp_post_types[$post_type_name]->show_in_rest = true;
$wp_post_types[$post_type_name]->rest_base = $post_type_name;
$wp_post_types[$post_type_name]->rest_controller_class = 'WP_REST_Posts_Controller';
}
}
/* Exposing the custom taxonomy of the plugin to the REST API.
* In this case, for The Tribe Events Calendar plugin, the custom
* taxonomy is "tribe_events_cat". For other plugins it will be different.
*/
add_action( 'init', 'my_custom_taxonomy_rest_support', 25 );
function my_custom_taxonomy_rest_support() {
global $wp_taxonomies;
//be sure to set this to the name of your taxonomy!
$taxonomy_name = 'tribe_events_cat';
if ( isset( $wp_taxonomies[ $taxonomy_name ] ) ) {
$wp_taxonomies[ $taxonomy_name ]->show_in_rest = true;
// Optionally customize the rest_base or controller class
$wp_taxonomies[ $taxonomy_name ]->rest_base = $taxonomy_name;
$wp_taxonomies[ $taxonomy_name ]->rest_controller_class = 'WP_REST_Terms_Controller';
}
}
With the above in my functions.php, now I can query just the custom post type and taxonomy with the REST API. Here's a sample query:
http://www.mywebsite.com/wp-json/wp/v2/tribe_events?tribe_events_cat=64
However, I still don't see any of the custom plugin data per-event. All I see are the basic standard WP fields.
So now I have to add more to my functions.php:
/* Add specific endpoints to REST API.
* The TEC plugin has good documentation, and they have a
* list of the variables. With any other plugin, you might
* have to do more detective work. */
add_action( 'rest_api_init', 'slug_register_event_venue' );
function slug_register_event_venue() {
register_rest_field( 'tribe_events',
'_EventVenueID',
array(
'get_callback' => 'slug_get_event_venue',
'schema' => null
)
);
}
function slug_get_event_venue( $object, $field_name, $request ) {
$postId = tribe_get_venue_id( $object[ 'id' ]);
if ( class_exists( 'Tribe__Events__Pro__Geo_Loc' ) ) {
$output[ 'locid' ] = (float) $postId;
$output[ 'lat' ] = (float) get_post_meta( $postId, Tribe__Events__Pro__Geo_Loc::LAT, true );
$output[ 'lng' ] = (float) get_post_meta( $postId, Tribe__Events__Pro__Geo_Loc::LNG, true );
} else {
$output = array(
'locid' => 0,
'lat' => 0,
'lng' => 0,
);
}
return $output;
}
... and a bunch more endpoint definitions of which I'm excluding the code here.
Now when I run the same query from earlier, new data fields are present in the JSON: all of the endpoints I've added.
At this point I want to exclude a ton of things from the REST API output (all the miscellaneous WP stuff) and just return the event fields I'm interested in. To do that I just add a "&fields" parameter to my query, with fields seperated by comma. There's also a per_page and order parameters too.
http://www.mywebsite.com/wp-json/wp/v2/tribe_events?tribe_events_cat=64&per_page=100&order=asc&fields=id,title.rendered,_EventVenueID.lat,_EventVenueID.lng,_EventVenueID.locid,_EventStartDate.startdate,tribe_events_cat
This returns JSON data with only the data I'm interested in.
The TEC plugin maker has stated they'll be introducing official REST API support sometime soon. This means in the future I can probably eliminate all of this code in functions.php, and just utilize whatever interface the plugin maker comes up with... hopefully a nice sexy page inside the plugin settings.
Now that WP (4.7) has more or less a fully featured REST API, the ball is in the court of the plugin makers to build support for it. So this year you should see plugins be updated accordingly.
When you are creating the custom post type in WordPress just add one more parameter show_in_rest as true for the support the rest API for Custom post type.
/**
* Register a book post type, with REST API support
*
* Based on example at:
https://codex.wordpress.org/Function_Reference/register_post_type
*/
add_action( 'init', 'my_book_cpt' );
function my_book_cpt() {
$args = array(
'public' => true,
'show_in_rest' => true,
'label' => 'Books'
);
register_post_type( 'book', $args );
}
Please visit here.
Then you can use the custom endpoint by the URL like this:
https://example.com/wp-json/wp/v2/book

Resources