I have written a custom calendar module for use with Beaver Builder.
I want to fetch posts from a custom post_type of 'event' to populate the calendar.
In my beaver builder module I have the following:
wp_enqueue_script( 'axios', 'https://unpkg.com/axios/dist/axios.min.js');
wp_enqueue_script( 'qs', 'https://unpkg.com/qs/dist/qs.js');
function get_ajax_event_calendar_posts() {
// Query Arguments
$args = array(
'post_type' => array('event'),
'post_status' => array('publish'),
'posts_per_page' => 40,
'nopaging' => true,
'order' => 'DESC',
'orderby' => 'date',
'cat' => 1,
);
// The Query
$ajaxposts = get_posts( $args ); // changed to get_posts from wp_query, because `get_posts` returns an array
echo json_encode( $ajaxposts );
wp_die(); // this is required to terminate immediately and return a proper response
}
// Fire AJAX action for both logged in and non-logged in users
add_action('wp_ajax_get_ajax_event_calendar_posts','get_ajax_event_calendar_posts');
add_action('wp_ajax_nopriv_get_ajax_event_calendar_posts', 'get_ajax_event_calendar_posts');
and in my modules JavaScript (frontend.php) I have:
var data = { action: "get_ajax_event_calendar_posts" };
axios.post("<?php echo admin_url('admin-ajax.php');?>", Qs.stringify(data))
.then(function(response) {
console.log(JSON.stringify(response.data));
})
.catch(function(error) {
console.log(error);
});
I have one post in 'event'. In the browser, I test the endpoint by visiting xxx.flywheelsites.com/wp-admin/admin-ajax.php?action=get_ajax_event_calendar_posts and receive an empty array []. I expect to receive a single event. I've looked in the admin and can see the post.
When clicking on the button in my module to make the Ajax request, I receive a 400 error
Checking the logs, I receive the following error message:
(MISSING)127.0.0.1 - 04/Jan/2020:16:41:40 +0000 "POST /.wordpress/wp-admin/admin-ajax.php" 400 /www/.wordpress/wp-admin/admin-ajax.php 64263000 4103576 709.963 4096 35.21%!
This error message doesn't really tell me anything. I also altered my axios method to use a GET - however, I receive the same error.
Any advice on how I can debug this would be really helpful. Thanks!
Wordpress, Astra Theme, Beaver Builder, hosted on flywheel.
** Edit **
To test, in my get_ajax_event_calendar_posts method I am echo'ing out 'hello world'
function get_ajax_event_calendar_posts() {
// Query Arguments
$args = array(
'post_type' => array('event'),
'post_status' => array('publish'),
'posts_per_page' => 40,
'nopaging' => true,
'order' => 'DESC',
'orderby' => 'date',
'cat' => 1,
);
// The Query
$ajaxposts = get_posts( $args ); // changed to get_posts from wp_query, because `get_posts` returns an array
echo 'hello world'; //json_encode( $ajaxposts );
wp_die(); // this is required to terminate immediately and return a proper response
}
I visit the url in my browser and see 'hello world' - so it seems there might be a problem in querying the data? The logs don't contain anything useful. However, from this I can see I can hit the route and get a response from it.
** Edit **
I can now view the posts when hitting the url directly. Appears to be an issue of cacheing.... I have updated my JS - yet the old files persist. I'm hopeful this is just a cacheing issue...
Using Beaver Builder, I had to clear Beaver Builders cache. To clear it, go into settings -> beaver-builder -> tools and click the clear cache button.
Related
I am trying to integrate a Stripe payment method in a web application. I am stuck: payment_init.php does not load, when I am redirected to the page. I get 403 Forbidden error code ("Forbidden. You don't have permission to access this resource.
Additionally, a 400 Bad Request error was encountered while trying to use an ErrorDocument to handle the request").
Here is my payment_init.php file's code:
<?php
// Include the Stripe PHP library
require_once 'stripe-php/init.php';
// Include the configuration file
require_once 'config.php';
$chosenService = $_POST['submitService'];
printf($chosenService);
// Product Details
if ($chosenService === "1") {
$productName = "Hajvágás (6900 HUF)";
$productID = "hc001";
$productPrice = 6900;
} elseif ($chosenService === "2") {
$productName = 'Hajvágás + Szakáll (9900 HUF)';
$productID = "hc002";
$productPrice = 9900;
};
$currency = "huf";
$description = "20% előleg Mobil Barber";
printf($productName);
// Set API key
\Stripe\Stripe::setApiKey(STRIPE_API_KEY);
$response = array(
'status' => 0,
'error' => array(
'message' => 'Invalid Request!'
)
);
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
$input = file_get_contents('php://input');
$request = json_decode($input);
}
if (json_last_error() !== JSON_ERROR_NONE) {
http_response_code(400);
echo json_encode($response);
exit;
}
if (!empty($request->createCheckoutSession)) {
printf($productName);
// Convert product price to cent
$stripeAmount = round($productPrice * 100, 2);
// Create new Checkout Session for the order
try {
printf($productName);
$checkout_session = \Stripe\Checkout\Session::create([
'line_items' => [[
'price_data' => [
'currency' => $currency,
'unit_amount' => $productPrice,
'product_data' => [
'name' => $productName,
'description' => $description,
],
],
'quantity' => 1,
]],
'mode' => 'payment',
'success_url' => STRIPE_SUCCESS_URL . '?session_id={CHECKOUT_SESSION_ID}',
'cancel_url' => STRIPE_CANCEL_URL,
]);
} catch (Exception $e) {
$api_error = $e->getMessage();
}
if (empty($api_error) && $checkout_session) {
$response = array(
'status' => 1,
'message' => 'Checkout Session created successfully!',
'sessionId' => $checkout_session->id
);
} else {
$response = array(
'status' => 0,
'error' => array(
'message' => 'Checkout Session creation failed! ' . $api_error
)
);
}
}
// Return response
echo json_encode($response);
When I print $chosenService and $productName variables outside the "if (!empty($request->createCheckoutSession)) {...}" condition, I get the parameters, so they are not NULL. But inside the condition I do not get anything back, neither NULL (does this mean that the $request is empty?). I even checked the Logs in Stripe dashboard, this is the err message there:
"parameter_missing - line_items[0][price_data][product_data][name]
Looks like you are missing the name field tied to a given line item's product_data.
This field is required in that it contains the name that will show up on associated invoice line item descriptions."
I would be really grateful, if someone could help me with this. Thank you in advance.
I don't think your problem is the $productName. I tested out the code you provided and it looks like the issue has to do with the price value. You convert the $productPrice to $stripeAmount but then you don't use it. Without the conversion the amounts for either of the services are less than the $0.50 threshold (with the USD = HUF conversion).
As their docs point out, Stripe requires your charge amounts to be valued between $0.50 and $999,999.00
I don't think this impacted your attempt here but it might also be worth updating the way in which you are invoking/using the Stripe PHP library to conform to the current standard: https://github.com/stripe/stripe-php#getting-started
It will mean you can more easily use the code snippets displayed in the API docs
I'm using Minishlink/WebPush package to send a push notification from my server to my client but I'm getting this error:
array(3) {
["success"]=>
bool(false)
["endpoint"]=>
string(188) "***"
["message"]=>
string(179) "cURL error 77: error setting certificate verify locations:
CAfile: C:\xampp\apache\bin\curl-ca-bundle.crt
CApath: none (see https://curl.haxx.se/libcurl/c/libcurl-errors.html)"
}
This is my code:
require __DIR__ . '../../../vendor/autoload.php';
use Minishlink\WebPush\WebPush;
$vapidAuth = array(
'VAPID' => array(
'subject' => 'https://github.com/Minishlink/web-push-php-example/',
'publicKey' => '***',
'privateKey' => '***'
)
);
$webPush = new WebPush($vapidAuth);
$res = $webPush->sendNotification(
$subscription['ius_endpoint'],
'hello world!',
$subscription['ius_p256dh'],
$subscription['ius_auth'],
true
);
My sw code on my client is working because I've tried to manually push a notification using javascript to my registered sw.
I found out an answer here
Download the certificate from: https://curl.haxx.se/ca/cacert.pem
Rename the cacert.pem file into curl-ca-bundle.crt
Copy the file into path/to/xampp/apache/bin
Restart apache
i am using laravel with pusher to send an event message to pusher. the code is in my controller which is a post controller, triggered when an input form is submitted. below is my code. what am i doing wrong? there is no event received.
this is an ajax call route based controller.
$pusher = new Pusher( env('PUSHER_KEY'), env('PUSHER_SECRET'), env('PUSHER_APP_ID'), array( 'encrypted' => true ) );
$pusher->trigger( 'test_channel', 'my_event', 'hello world' );
I am also assuming you have set up your Pusher account correctly and that your environment variables are correct.
If so, you may need to ensure you are using the correct Cluster (the default is fine for the US, but outside the East coast of the US for example, the cluster must be explicitly defined).
Update:
Controller code:
<?php
namespace App\Http\Controllers;
use Vinkla\Pusher\Facades\Pusher;
use Illuminate\Foundation\Bus\DispatchesJobs;
use Illuminate\Routing\Controller as BaseController;
use Illuminate\Foundation\Validation\ValidatesRequests;
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
class TestPusherController extends BaseController
{
use AuthorizesRequests, DispatchesJobs, ValidatesRequests;
public function test(){
$arr = array('test' => 'hello world 2') ;
$pusher = new Pusher( env('PUSHER_KEY'), env('PUSHER_SECRET'), env('PUSHER_APP_ID'), array( 'encrypted' => true, 'cluster' => 'ap1' ) );
$pusher::trigger( 'test_channel', 'my_event', $arr);
return $arr;
}
public function shortenedTest(){
$message = 'Hello world';
Pusher::trigger('my-channel', 'my-event', ['message' => $message]);
}
}
In web routes:
Route::get('testPusherController', 'TestPusherController#test');
Route::get('shortenedTestPusherController', 'TestPusherController#shortenedTest');
I have got this working on a fresh install of vinkla/pusher following the setup steps in https://github.com/vinkla/laravel-pusher, on Laravel 5.3, using the built in PHP server and Connecting to the EU server (I do not have any Pusher apps using ap1 at this time).
You will notice a small number of changes to the coding in the controller to get the correct format. You must 'use' the Pusher facade above the controller.
For completeness, I have added a neater way of working with this where you can set the Pusher credentials in the Config/pusher.php file without the need to setup the connection for each use. This can be seen in the shortenedTest() method on the controller.
<?php
return [
'connections' => [
'main' => [
'auth_key' => env('PUSHER_KEY'),
'secret' => env('PUSHER_SECRET'),
'app_id' => env('PUSHER_APP_ID'),
'options' => [
'cluster' => env('PUSHER_CLUSTER')
],
'host' => null,
'port' => null,
'timeout' => null,
],
'alternative' => [
'auth_key' => 'your-auth-key',
'secret' => 'your-secret',
'app_id' => 'your-app-id',
'options' => [],
'host' => null,
'port' => null,
'timeout' => null,
],
],
];
I am trying to make ZF2 respond in REST way to different request type.
In my module.config.php I have this router config.
'router' => array(
'routes' => array(
'student' => array(
'type' => 'segment',
'options' => array(
'route' => '/student[/:action][/:id]',
'constraints' => array(
'action' => '[a-zA-Z][a-zA-Z0-9_-]*',
'id' => '[0-9]+',
),
'defaults' => array(
'controller' => 'Student\Controller\Student',
'action' => 'index',
),
),
),
),
),
On frontend I am using Backbone to send GET, POST, DELETE requests to server based on user interactions.
When user trigger action to delete student with id of n, backbone will send /somePath/student/n using DELETE request.
When user trigger action to get student with id of n, backbone will send /somePath/student/n using GET request.
If I want current setup to work I have to change Backbone request and change URL from student/n to student/delete/n if I want to delete student with that id and similarly for GET.
This is what I did on client side which I would like to avoid.
define(['backbone'], function(Backbone){
return Backbone.Model.extend({
defaults:{
//set default model values
},
initialize: function(){
//initialize
},
methodToURL: {
'delete': '/student/delete'
},
sync: function(method, model, options) {
options = options || {};
var id = arguments[1]['id']
options.url = model.methodToURL[method.toLowerCase()] + '/' + id;
return Backbone.sync.apply(this, arguments);
}
});
});
In controller on server side I have different action methods I would like to run for different request types.
public function deleteAction()
{
//some code
}
public function getAction()
{
//some code
}
I don't want to change default backbone behaviour (intercepting and altering requests).
Is there a way to configure ZF2 router to use same route but trigger different actions based on request method type?
You can use Method route as child route of segment route. http://framework.zend.com/manual/2.3/en/modules/zend.mvc.routing.html
There is a example named A complex example with child routes where author for blog literal route create child routes each of which is different type.
Simply You can create child routes in your student route which will be type Method for each method You want to use and then change only action for this method types.
'router' => array(
'routes' => array(
'student' => array(
'type' => 'segment',
'options' => array(
'route' => '/student[/:action][/:id]',
'constraints' => array(
'action' => '[a-zA-Z][a-zA-Z0-9_-]*',
'id' => '[0-9]+',
),
'defaults' => array(
'controller' => 'Student\Controller\Student',
'action' => 'index',
),
),
'may_terminate' => true,
'child_routes' => array(
'delete' => array(
'type' => 'method',
'options' => array(
'verb' => 'delete',
'defaults' => array(
'action' => 'delete'
),
),
),
'put' => array(
'type' => 'method',
'options' => array(
'verb' => 'put',
'defaults' => array(
'action' => 'put'
),
),
),//and so on...
),
),
),
),
You can use the Zend\Mvc\Controller\AbstractRestfulController
It will call Certain function depending on the HTTP request method
class StudentRest extends AbstractRestfulController {
/**
* will be called with a GET request when it detects that route
* matches paramater id has been set
*/
public function get($id) {
/*load studentdata*/
return new JsonModel($data);
}
/**
* Will be called on a POST request, and data should be sent with a $_POST
* This should create a new object/row in db and return 201
*/
public function Create($data) {
/*create student*/
$this->response->setStatusCode(201); // if new student was created.
return JsonModel();
}
/**
* Will be called on a PUT request. Data should be sent via $_POST
* It also requires that the $id parameter is set in the route match
*/
public function Update($id, $data) {}
/**
* Will be called on a DELETE request, It requires that the $id parameter is set in the route match
*/
public function Delete($id) {}
}
with that u can just link to the controller via the route as so
'student' => array(
'type' => 'segment',
'options' => array(
'route' => '/student[/:id]',
'constraints' => array(
'id' => '[0-9]+',
),
'defaults' => array(
'controller' => 'Student\Controller\StudentRest ',
),
),
),
there are also some function for getList which will be called when not suppling $id in route parameters.
Also might be worth saying that the default implementation of all the functions returns a 405 with a ['content' => 'Method Not Allowed']
Documentation how to use it
As per the documentation :
http://framework.zend.com/manual/1.12/en/zend.controller.request.html
Determining the Request Method
getMethod() allows you to determine the HTTP request method used to request the current resource. Additionally, a variety of methods exist that allow you to get boolean responses when asking if a specific type of request has been made:
isGet()
isPost()
isPut()
isDelete()
isHead()
isOptions()
The primary use case for these is for creating RESTful MVC architectures.
Well, I have a CakePHP 2.2.5 app which is basically management of users, and a user has a photo, and I create a PhotosController (as suggestion of this tutorial). I tested it and it works perfectly on Photos/View, including the ajax elements to be possible send a photo in a form without redirecting. And now I'm trying to connect all of this, but it ins't as easy as I think it should be.
My Photo add method:
public function add()
{
if ( $this->request->is( 'post' ) ) {
$this->Photo->create();
$json = array( 'result' => array( 'files' => array() ) );
if ( $this->Photo->save( $this->request->data ) ) {
$photo = $this->Photo->findById( $this->Photo->id );
$json['files'][0]['name'] = $photo['Photo']['basename'];
$json['files'][0]['size'] = $this->request->data['Photo']['file']['size'];
$json['files'][0]['url'] = $this->webroot . 'media/transfer/img/' . $photo['Photo']['basename'];
$json['files'][0]['thumbnail_url'] = $this->webroot . 'media/filter/thumbnail/img/' . $photo['Photo']['basename'];
}
else {
$json = 'Error';
$this->Session->setFlash( __( 'The photo could not be saved. Please, try again.' ) );
}
$this->RequestHandler->renderAs( $this , 'ajax' );
Configure::write( 'debug' , 0 );
$this->set( 'json' , json_encode( $json ) );
$this->render( '/Elements/ajax' );
}
My test View (on users controller):
<?php echo $this->Form->create(
'Photo' ,
array( 'url' => array( 'controller' => 'photos' ,
'action' => 'add'
) ,
'id' => 'fileupload' ,
'enctype' => 'multipart/form-data'
)
); ?>
<-- Some HTML HERE-->
<?php
echo $this->TB->input(
'Photo.file' ,
array(
'prepend' => 'Upload' ,
'type' => 'file' ,
'class' => 'fileUpload' ,
//'multiple' => 'multiple',
'div' => FALSE ,
'between' => FALSE ,
'after' => FALSE ,
'label' => FALSE ,
'help' => NULL ,
)
);
?>
</form>
<-- Some (already tested) Javascript to make this work HERE-->
The view renders without php errors, but when I upload a file I get an Javascript error, and the debug says:
GET http://<server>/<app>/users/add 404 (Not Found) jquery.min.js:1960
send jquery.min.js:1960
b.extend.ajax jquery.min.js:1840
(anonymous function) main.js:59
c jquery.min.js:215
p.fireWith jquery.min.js:249
b.extend.ready jquery.min.js:69
H jquery.min.js:10
Actually, I get this error on both, GET and POST methods (with some different line of jQuery of course).
Even the action is set to the PhotosController it is trying to access the Users. I think because of the view, as I din't specify users anywhere. I am trying to solve this problem for a week and I don't have more ideas.
Any help would be greatly appreciated.
Thanks in advance.