Add links on Wordpress custom endpoint - wordpress

I created a custom endpoint for specific data from a custom table in my Wordpress plugin. It get's all the data from the table with the getHelpers() function. After that it will be merged by some user data. I would like to add the profile_image as a link to the response so we can get it with the embed parameter.
What is the best way to add the link to the response? I know the $response->add_link() function but this would add it to the response and not to each contributor.
I tried to add the link as an array but this won't react on the _embed parameter.
This is my code for the custom endpoint:
class VEMS_Rest_Contributors extends WP_REST_Controller {
protected $namespace = 'vems/v2';
protected $rest_base = 'contributors';
/**
* Register the routes for coupons.
*/
public function register_routes() {
register_rest_route( $this->namespace, '/' . $this->rest_base, array(
'methods' => WP_REST_Server::READABLE,
'callback' => array( $this, 'get_items' ),
'args' => $this->get_collection_params(),
) );
}
public function get_items( WP_REST_Request $request ) {
$project_id = $request->get_param( 'project_id' );
$contributors = array();
if( !empty($project_id) ) {
$project = new VEMS_Project( $request['project_id'] );
$helpers = $project->getHelpers();
foreach($helpers as $helper) {
$contributor = array();
if( !empty($helper->contributor_id) ) {
$user = get_user_by( 'ID', $helper->contributor_id );
$user_meta = get_user_meta( $helper->contributor_id );
$contributor['ID'] = $helper->contributor_id;
$contributor['user_nicename'] = $user->data->display_name;
$contributor['user_profile_image'] = $user_meta['contributor_profile_image'][0];
} else {
$contributor['user_nicename'] = $helper->name;
$contributor['user_profile_image'] = $helper->image_id;
}
$contributor['item_total'] = $helper->item_total;
$contributor['checked'] = $helper->checked;
$contributor['helper_date'] = $helper->helper_date;
/*
$contributor['_links']['profile_image'] = array(
'href' => rest_url( '/wp/v2/media/' . $contributor['user_profile_image'] ),
'embeddable' => true
);
*/
$contributors[] = $contributor;
}
}
$response = rest_ensure_response( $contributors );
return $response;
}
public function get_collection_params() {
$params['project_id'] = array(
'description' => __( 'Limit result set to contributors assigned a specific project.', 'vems' ),
'type' => 'integer',
'sanitize_callback' => 'absint',
'validate_callback' => 'rest_validate_request_arg',
);
return $params;
}
}

to handle links on route vems/v2/contributors?_embed, the element profile_image must be an array of links and then you can do that
$contributor['_links']['profile_image'] = [
[
'href' => rest_url( '/wp/v2/media/' . $contributor['ID'] ),
'embeddable' => true,
],
];

Related

orderby parameter is not added to query string

I have created a Wordpress plugin with an admin part displaying a table.
To accomplish this, I have created a class extending WP_List_Table all works perfectly but sorting.
When I see the header link, this is displayed:
https://example.com/wp-admin/admin.php?page=myplugin&order=asc
Notice that the orderby parameter is not present. Only the order parameter.
This the implementation of get_columns and get_sortable_columns method:
function get_columns() {
return $columns = array(
'col_alumno_id' => __('ID'),
'col_alumno_nombres' => __('Nombres'),
'col_alumno_apellidos' => __('Apellidos'),
'col_alumno_rut' => __('RUT'),
'col_alumno_curso' => __('Curso'),
'col_alumno_apoderados' => __('Apoderados')
);
}
public function get_sortable_columns() {
return $sortable = array(
'col_alumno_id' => 'ID',
'col_alumno_nombres' => 'alumno_nombres',
'col_alumno_apellidos' => 'alumno_apellidos',
'col_alumno_rut' => 'alumno_rut',
'col_alumno_curso' => 'curso_nombre'
);
}
Also, I have this at the end of prepare_items method:
$columns = $this->get_columns();
$hidden = array();
$sortable = $this->get_sortable_columns();
$_wp_column_headers[$screen->id] = $columns;
$this->_column_headers = array($columns, $hidden, $sortable);
/* -- Fetch the items -- */
$this->items = $wpdb->get_results($wpdb->prepare($query, $this->colegio));
What is missing here?

Custom post type API custom endpoint for single post by ID

I've created a WordPress custom post type, then I've created REST API custom endpoint to GET all the posts works ok. Then I've created another custom endpoint to GET single post by ID. For example http://localhost:8888/wordpress/wp-json/lc/v1/cars/120
I have created a few posts, each time I change the ID at the end of the route to 118 or 116 it shows the same data for the latest post-ID 120. I need the relevant data to show based on the post ID, I would appreciate any kind of help. Thanks
public function rest_posts_endpoints(){
register_rest_route(
'lc/v1',
'/cars/(?P<id>\d+)',
[
'method' => 'GET',
'callback' => [$this, 'rest_endpoint_handler_single'],
]
);
}
public function rest_endpoint_handler_single( WP_REST_Request $request ) {
$params = $request->get_query_params();
$args = [
'post_type' => 'cars',
'id' => $params['id'],
];
$post = get_posts($args);
$data['id'] = $post[0]->ID;
$data['slug'] = $post[0]->post_name;
$data['title'] = $post[0]->post_title;
$data['content'] = $post[0]->post_content;
$data['excerpt'] = $post[0]->post_excerpt;
return $data;
}
public function rest_endpoint_handler_single( WP_REST_Request $request ) {
$params = $request->get_params();
$args = [
'post_type' => 'cars',
'id' => $params['id'],
'include' => array($params['id']),
];
$post = get_posts($args);
$data['id'] = $post[0]->ID;
$data['slug'] = $post[0]->post_name;
$data['title'] = $post[0]->post_title;
$data['content'] = $post[0]->post_content;
$data['excerpt'] = $post[0]->post_excerpt;
return $data;
}

wp_get_current_user() function not working in Rest API callback function

Please consider the following php class extends the WP_REST_Controller class of Wordpress related to Rest API:
<?php
class MCQAcademy_Endpoint extends WP_REST_Controller {
/**
* Register the routes for the objects of the controller.
*/
public function register_routes() {
$version = '1';
$namespace = 'custompath/v' . $version;
$base = 'endpointbase';
register_rest_route(
$namespace,
'/' . $base,
array(
array(
'methods' => WP_REST_Server::READABLE,
'callback' => array( $this, 'get_items' ),
'permission_callback' => array( $this, 'get_items_permissions_check' ),
'args' => array(),
)
)
);
}
/**
*
*/
public function get_items( $request ) {
$rs = array(
'data' => array(),
'request' => array(
'lang' => 'en',
),
);
$args = array();
$items = get_posts( $args );
foreach( $items as $item ) {
$itemdata = $this->prepare_item_for_response( $item, $request );
$rs['data'][] = $this->prepare_response_for_collection( $itemdata );
}
$rs['wp_get_current_user'] = wp_get_current_user(); // Does not output as expected
return new WP_REST_Response( $rs, 200 );
}
/**
* Check if a given request has access to get items
*/
public function get_items_permissions_check( $request ) {
return true; // to make readable by all
}
/**
* Prepare the item for create or update operation
*/
protected function prepare_item_for_database( $request ) {
return $request;
}
/**
* Prepare the item for the REST response
*/
public function prepare_item_for_response( $item, $request ) {
$data = array(
'ID' => $item->ID,
'post_content' => wpautop($item->post_content),
'post_title' => $item->post_title,
);
return $data;
}
/**
* Get the query params for collections
*/
public function get_collection_params() {
return array(
'page' => array(
'description' => 'Current page of the collection.',
'type' => 'integer',
'default' => 1,
'sanitize_callback' => 'absint',
),
'per_page' => array(
'description' => 'Maximum number of items to be returned in result set.',
'type' => 'integer',
'default' => 10,
'sanitize_callback' => 'absint',
),
'search' => array(
'description' => 'Limit results to those matching a string.',
'type' => 'string',
'sanitize_callback' => 'sanitize_text_field',
),
);
}
// Register our REST Server
public function hook_rest_server(){
add_action( 'rest_api_init', array( $this, 'register_routes' ) );
}
}
$myEndpoint = new MCQAcademy_Endpoint();
$myEndpoint->hook_rest_server();
Everything is going well except calling the wp_get_current_user() function in the get_items() function return empty user even though the user is loggedin in the website.
What is the solution to get the loggedin user info in Rest API endpoint function?

WordPress - Get Current Post Author ID Outside The Loop And Inside A Plugin

I am trying to modify a plugin. I need the author id of the current post to accomplish what I am doing. I have tried every other method I have found over internet that claims to get the post author id outside the loop but its not working inside the plugin. I guess its because the plugins might be loaded before the loop variables or something? Please pardon me as I am not a Pro.
Here is what I have tried so far.
1.
$author_id=$post->post_author;
2.
global $post;
$author_id=$post->post_author;
3.
$post_tmp = get_post($post_id);
$author_id = $post_tmp->post_author;
4.
$author_id = $posts[0]->post_author;
But nothing works in the plugin's directory. Can anyone help?
Detailed Explanation:
I am trying to modify woodiscuz plugin. The problem with this plugin is that it held comments of even seller for moderation. So if I am the seller and I reply to some buyer in comment, I will have to approve my own comment.
Now to overcome this problem, I am putting a condition that if the author of the post (seller) is commenting, then don't put the comment for moderation.
Here is the function of the plugin that is controlling comments.
public function comment_submit_via_ajax() {
$message_array = array();
$comment_post_ID = intval(filter_input(INPUT_POST, 'comment_post_ID'));
$comment_parent = intval(filter_input(INPUT_POST, 'comment_parent'));
if (!$this->wpc_options->wpc_options_serialized->wpc_captcha_show_hide) {
if (!is_user_logged_in()) {
$sess_captcha = $_SESSION['wpc_captcha'][$comment_post_ID . '-' . $comment_parent];
$captcha = filter_input(INPUT_POST, 'captcha');
if (md5(strtolower($captcha)) !== $sess_captcha) {
$message_array['code'] = -1;
$message_array['message'] = $this->wpc_options->wpc_options_serialized->wpc_phrases['wpc_invalid_captcha'];
echo json_encode($message_array);
exit;
}
}
}
$comment = filter_input(INPUT_POST, 'comment');
if (is_user_logged_in()) {
$user_id = get_current_user_id();
$user = get_userdata($user_id);
$name = $user->display_name;
$email = $user->user_email;
$user_url = $user->user_url;
} else {
$name = filter_input(INPUT_POST, 'name');
$email = filter_input(INPUT_POST, 'email');
$user_id = 0;
$user_url = '';
}
$comment = wp_kses($comment, array(
'br' => array(),
'a' => array('href' => array(), 'title' => array()),
'i' => array(),
'b' => array(),
'u' => array(),
'strong' => array(),
'p' => array(),
'img' => array('src' => array(), 'width' => array(), 'height' => array(), 'alt' => array())
));
$comment = $this->wpc_helper->make_clickable($comment);
if ($name && filter_var($email, FILTER_VALIDATE_EMAIL) && $comment && filter_var($comment_post_ID)) {
$held_moderate = 1;
if ($this->wpc_options->wpc_options_serialized->wpc_held_comment_to_moderate) {
$held_moderate = 0;
}
// $held_moderate = 1 -> No moderation
/*This is the part where I need to put the custom condition*/
if($post_author_id == get_current_user_id())
{
$held_moderate = 1;
}
$new_commentdata = array(
'user_id' => $user_id,
'comment_post_ID' => $comment_post_ID,
'comment_parent' => $comment_parent,
'comment_author' => $name,
'comment_author_email' => $email,
'comment_content' => $comment,
'comment_author_url' => $user_url,
'comment_type' => 'woodiscuz',
'comment_approved' => $held_moderate
);
$new_comment_id = wp_insert_comment($new_commentdata);
$new_comment = new WPC_Comment(get_comment($new_comment_id, OBJECT));
if (!$held_moderate) {
$message_array['code'] = -2;
$message_array['message'] = $this->wpc_options->wpc_options_serialized->wpc_phrases['wpc_held_for_moderate'];
} else {
$message_array['code'] = 1;
$message_array['message'] = $this->comment_tpl_builder->get_comment_template($new_comment);
}
$message_array['wpc_new_comment_id'] = $new_comment_id;
} else {
$message_array['code'] = -1;
$message_array['wpc_new_comment_id'] = -1;
$message_array['message'] = $this->wpc_options->wpc_options_serialized->wpc_phrases['wpc_invalid_field'];
}
echo json_encode($message_array);
exit;
}

JMSPaymentPaypalBundle blank order summary

hi i was wondering on how to show order summary in paypal with JMSPaymentPaypalBundle ?!
ay tips will be greatly appreciated ..
here is my paypalController code in case needed
<?php
namespace Splurgin\EventsBundle\Controller;
use JMS\DiExtraBundle\Annotation as DI;
use JMS\Payment\CoreBundle\Entity\Payment;
use JMS\Payment\CoreBundle\PluginController\Result;
use JMS\Payment\CoreBundle\Plugin\Exception\ActionRequiredException;
use JMS\Payment\CoreBundle\Plugin\Exception\Action\VisitUrl;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
use Symfony\Component\HttpFoundation\RedirectResponse;
class PaymentController
{
/** #DI\Inject */
private $request;
/** #DI\Inject */
private $router;
/** #DI\Inject("doctrine.orm.entity_manager") */
private $em;
/** #DI\Inject("payment.plugin_controller") */
private $ppc;
/**
* #DI\Inject("service_container")
*
*/
private $container;
/**
* #Template
*/
public function detailsAction($package)
{
// note this ticket at this point in inactive ...
$order = $this->container->get('ticket')->generateTicket($package);
$order = $this->em->getRepository('SplurginEventsBundle:SplurginEventTickets')->find($order);
$packageId = $order->getPackageId();
$package = $this->em->getRepository('SplurginEventsBundle:SplurginEventPackages')->find($package);
$price = $package->getPrice();
var_dump($price);
if($price == null){
throw new \RuntimeException('Package was not found: '.$result->getReasonCode());
}
$form = $this->getFormFactory()->create('jms_choose_payment_method', null, array(
'amount' => $price,
'currency' => 'USD',
'default_method' => 'payment_paypal', // Optional
'predefined_data' => array(
'paypal_express_checkout' => array(
'return_url' => $this->router->generate('payment_complete', array(
'order' => $order->getId(),
), true),
'cancel_url' => $this->router->generate('payment_cancel', array(
'order' => $order->getId(),
), true)
),
),
));
if ('POST' === $this->request->getMethod()) {
$form->bindRequest($this->request);
if ($form->isValid()) {
$this->ppc->createPaymentInstruction($instruction = $form->getData());
$order->setPaymentInstruction($instruction);
$this->em->persist($order);
$this->em->flush($order);
return new RedirectResponse($this->router->generate('payment_complete', array(
'order' => $order->getId(),
)));
}
}
return array(
'form' => $form->createView(),
'order'=>$order->getId(),
);
}
/** #DI\LookupMethod("form.factory") */
protected function getFormFactory() { }
/**
*/
public function completeAction($order)
{
$order = $this->em->getRepository('SplurginEventsBundle:SplurginEventTickets')->find($order);
$instruction = $order->getPaymentInstruction();
if (null === $pendingTransaction = $instruction->getPendingTransaction()) {
$payment = $this->ppc->createPayment($instruction->getId(), $instruction->getAmount() - $instruction->getDepositedAmount());
} else {
$payment = $pendingTransaction->getPayment();
}
$result = $this->ppc->approveAndDeposit($payment->getId(), $payment->getTargetAmount());
if (Result::STATUS_PENDING === $result->getStatus()) {
$ex = $result->getPluginException();
if ($ex instanceof ActionRequiredException) {
$action = $ex->getAction();
if ($action instanceof VisitUrl) {
return new RedirectResponse($action->getUrl());
}
throw $ex;
}
} else if (Result::STATUS_SUCCESS !== $result->getStatus()) {
throw new \RuntimeException('Transaction was not successful: '.$result->getReasonCode());
}
}
public function cancelAction($order)
{
die('cancel the payment');
}
}
i really dont know why this is not a part of the docs , but the bundle is capable of setting checkout parameters out of the box ...
here is how i have done it
$form = $this->getFormFactory()->create('jms_choose_payment_method', null, array(
'amount' => $price,
'currency' => 'USD',
'default_method' => 'payment_paypal', // Optional
'predefined_data' => array(
'paypal_express_checkout' => array(
'return_url' => $this->router->generate('payment_complete', array(
'order' => $order->getId(),
), true),
'cancel_url' => $this->router->generate('payment_cancel', array(
'order' => $order->getId(),
), true),
'checkout_params' => array(
'L_PAYMENTREQUEST_0_NAME0' => 'event',
'L_PAYMENTREQUEST_0_DESC0' => 'some event that the user is trying to buy',
'L_PAYMENTREQUEST_0_AMT0'=> 6.00, // if you get 10413 , then visit the api errors documentation , this number should be the total amount (usually the same as the price )
// 'L_PAYMENTREQUEST_0_ITEMCATEGORY0'=> 'Digital',
),
),
),
));
error code can be found here
SetExpressCheckout Request Fields here
i will provide a pull request to the documentation as soon as i can .. :)

Resources