I'm trying to create a react widget for WordPress using static data and rest api (for practice).
The problem: I have registered an endpoint, but can't get it to access the data at the registered endpoint. I keep getting a 404 error.
Here's the link that gets me to my worpress dashboard: http://penguin.linux.test/wordpressLocal/wp-admin and here's the full code:
<?php
/*
Plugin Name: WP Dashboard Widget
*/
function enqueue_react_scripts() {
wp_enqueue_script( 'react', 'https://unpkg.com/react#17/umd/react.development.js', array(), '17', true );
wp_enqueue_script( 'react-dom', 'https://unpkg.com/react-dom#17/umd/react-dom.development.js', array(), '17', true );
}
add_action( 'wp_enqueue_scripts', 'enqueue_react_scripts' );
function react_app_container() {
echo '<div id="react-app-container"></div>';
}
// Callback function to get the data for the chart
function get_chart_data() {
$data = array(
array(
'name' => 'Jan',
'uv' => 4000,
'pv' => 2400,
),
array(
'name' => 'Feb',
'uv' => 3000,
'pv' => 1398,
),
array(
'name' => 'Mar',
'uv' => 2000,
'pv' => 9800,
),
array(
'name' => 'Apr',
'uv' => 2780,
'pv' => 3908,
),
array(
'name' => 'May',
'uv' => 1890,
'pv' => 4800,
),
);
return rest_ensure_response( $data );
}
// Register a custom endpoint
add_action( 'rest_api_init', function () {
register_rest_route( 'getsdata/v1', '/chart_data/', array(
'methods' => 'GET',
'callback' => 'get_chart_data',
) );
} );
function react_dashboard_widget_script() {
?>
<script type= "text/javascript" >
const React = window.React;
const ReactDOM = window.ReactDOM;
const GraphWidget =()=>{
const [ChartData, setChartData]=React.useState([]);
console.log("pepper")
React.useEffect(() => {
fetch('http://penguin.linux.test/wordpressLocal/wp-json/getsdata/v1/chart_data')
.then(response => response.json())
.then(data => setChartData(data))
.catch(error => console.error(error));
},[]);
return (
<LineChart width={500} height={300} data={ChartData.length > 0 ? ChartData : ChartData}>
<XAxis dataKey="name"/>
<YAxis/>
<CartesianGrid stroke="#eee" strokeDasharray="5 5"/>
<Line type="monotone" dataKey="uv" stroke="#8884d8" />
<Line type="monotone" dataKey="pv" stroke="#82ca9d" />
</LineChart>
);
};
ReactDOM.render(
<GraphWidget />,
document.getElementById('react-app-container')
);
</script>
<?php
}
add_action('admin_footer','react_dashboard_widget_script');
function register_react_dashboard_widget() {
wp_add_dashboard_widget( 'react_dashboard_widget', 'React Dashboard Widget', 'react_app_container' );
}
add_action( 'wp_dashboard_setup', 'register_react_dashboard_widget' );
I have tried moving the callback function block and changing the namespace. I expected the api link http://penguin.linux.test/wordpressLocal/wp-json/getsdata/v1/chart_data to fetch the data from the callback function, but I'm getting a 404 error.
Related
Before I submit a form in WordPress, I try to pass some form values to a PHP script using jQuery Ajax to check whether similar posts already exist.
The first part of the jQuery works fine. However I am unsure, if the ajax passes the values to the PHP, because it always throws the alert('something went wrong');. I'm quite a bit lost, it's the first time, that I try to use Ajax.
jQuery(document).ready(function($) {
$('.madison').each(function(){
var _this = $(this) // get the loop item's div.madison
_this.find("select[name='trainingsort']").change( function() {
var _trainingsort = $("select[name='trainingsort']").val();
var vonzeit = "select[name='von-uhrzeit-" + _trainingsort + "']";
var biszeit = "select[name='bis-uhrzeit-" + _trainingsort + "']";
var _vonzeit = $(vonzeit).val();
var _biszeit = $(biszeit).val();
var _tag = $("input[name='tag']").val();
var _reitanlage_id = $("input[name='reitanlagen_id']").val();
var ort = _trainingsort + ' / ' + _vonzeit + ' / ' + _biszeit + ' / ' + _reitanlage_id + ' / ' + _tag;
alert( "Yes! " + ort );
_this.find("input[name='wpcf-rask-name-des-menschen']").val(ort);
// ----- everything works fine above this line ---------------------
$.ajax({
type: "POST",
url: "https://test.cuteberry.de/wp-content/toolset-customizations/trainingsanlagen-2-0__ajax-notification.php",
data: {trainingsort: _trainingsort, vonzeit: _vonzeit, biszeit: _biszeit, reitanlagen_id: _reitanlage_id, tag: _tag},
success: function(data){
alert(data);
},
error: function(data){
alert('something went wrong');
}
});
});
});
});
and the PHP ....
PHP:
<?php
/**
* New custom code snippet (replace this with snippet description).
*/
toolset_snippet_security_check() or die( 'Direct access is not allowed' );
// Put the code of your snippet below this comment.
// You can access the values posted by jQuery.ajax
// through the global variable $_POST, like this:
$trainingsort=isset($_POST['trainingsort'])?json_decode($_POST['trainingsort']):null; $vonzeit=isset($_POST['vonzeit'])?json_decode($_POST['vonzeit']):null; $biszeit=isset($_POST['biszeit'])?json_decode($_POST['biszeit']):null;
$reitanlagen_id=isset($_POST['reitanlagen_id'])?json_decode($_POST['reitanlagen_id']):null; $tag=isset($_POST['tag'])?json_decode($_POST['tag']):null;
$response = "";
// ----- everything works fine below this line ---------------------
if (isset($reitanlagen_id) && !empty($reitanlagen_id)) {
for ($i = $vonzeit; $i <= $biszeit; $i++) {
// Warteliste_Posts suchen
$query = new WP_Query(
array(
'post_type' => 'rask',
'post_status' => 'publish',
'posts_per_page' => -1,
'toolset_relationships' => array(
'role' => 'child',
'related_to' => $reitanlagen_id,
'relationship' => 'reitanlage-rask'
),
'meta_query' => array(
'relation' => 'AND',
array(
'key' => 'wpcf-rask-ort-des-geschehens',
'value' => $trainingsort,
'compare' => '='
),
array(
'key' => 'wpcf-rask-welches-journal-termine',
'value' => 1,
'compare' => '='
),
array(
'key' => 'wpcf-rask-von-tag',
'value' => $tag,
'type' => 'numeric',
'compare' => '='
),
array(
'key' => 'wpcf-rask-von-uhrzeit-15-minuten',
'value' => $i,
'type' => 'numeric',
'compare' => '<='
),
array(
'key' => 'wpcf-rask-bis-uhrzeit-15-minuten',
'value' => $i ,
'type' => 'numeric',
'compare' => '>='
),
)
)
);
$pferde_posts = $query->posts;
$count = count($pferde_posts);
// ----- everything works fine above this line ---------------------
if ($count >= 0) {
$response = json_encode("existiert");
break;
}
}
}
echo $response;
I'm thankfull for any hints in the right direction : )
I am at beginner level of drupal trying to Overriding the third party uc_cart_uc_cart_pane function into my own custom function custom_session_uc_cart_pane but it is duplicating the form or result
Here is sample functions
/**
* Implements hook_uc_cart_pane().
*/
function uc_cart_uc_cart_pane($items) {
$body = array();
if (!is_null($items)) {
$body = drupal_get_form('uc_cart_view_form', $items) + array(
'#prefix' => '<div id="cart-form-pane">',
'#suffix' => '</div>',
);
}
$panes['cart_form'] = array(
'title' => t('Default cart form'),
'enabled' => TRUE,
'weight' => 0,
'body' => $body,
);
return $panes;
}
function custom_session_uc_cart_pane($items){
$iframe = multi_domain_iframe();
// echo "<pre>";
// print_r($items);
// exit;
$pre_suf_fix = array(
'#prefix' => '<div id="cart-form-pane1">',
'#suffix' => '</div>'.$iframe,
);
$body = array() + $pre_suf_fix;
if (!is_null($items)) {
$body = drupal_get_form('custom_session_view_form', $items) + $pre_suf_fix;
}
$panes['cart_form'] = array(
'title' => t('Default cart form'),
'enabled' => TRUE,
'weight' => 0,
'body' => $body,
);
return $panes;
}
any thing which i am missing.
if you want to change some thing specifically for a form you can use
hook_form_alter
you do not need to override the function.
Thanks
Rather than using a plug-in I am in the process of creating my own schema markup for a home page on a WordPress site which makes use of Advananced Custom Fields (ACF) for some of the content relevant to this challenge. My aim is to give me a little more granular control over what is output and as a little personal challenge :)
So far I have successfully created a basic schema, but I have become stuck where I need to create a nested entity for a list of services.
currently I have this in my functions.php file:
function schema() {
$schema = array(
'#context' => "http://schema.org",
'#type' => "ProfessionalService",
'name' => get_bloginfo('name'),
'url' => get_home_url(),
// ... and so on
);
if ( have_rows('services_list') ) {
$schema['itemListElement'] = array();
while (have_rows('services_list')) : the_row();
$services = array(
'#type' => 'Offer',
'itemOffered' => array (
'#type' => 'Service',
'name' => get_sub_field('service')
)
);
array_push($schema['itemListElement'], $services);
endwhile;
}
echo '<script type="application/ld+json">' . json_encode($schema) . '</script>';
}
add_action('wp_head', 'schema');
Result:
{
"#context":"http:\/\/schema.org",
"#type":"ProfessionalService",
"name":"Name of Company",
"url":"http:\/\/www.whatever.com",
and so on...
"itemListElement": [
{
"#type":"Offer",
"itemOffered": {
"#type":"Service",
"name":"Service One"
}
},
{
"#type":"Offer",
"itemOffered": {
"#type":"Service",
"name":"Service Two"
}
},
... more services
]
}
This resulting markup is great, but I need to nest the itemListElement so that it outputs like so:
"hasOfferCatalog": {
"#type": "OfferCatalog",
"name": "Some Services",
"itemListElement": [
{
"#type":"Offer",
"itemOffered": {
"#type":"Service",
"name":"Service One"
}
},
{
"#type":"Offer",
"itemOffered": {
"#type":"Service",
"name":"Service Two"
}
},
... more services
I can't for the life of me work out how this is done. My current best effort is to add it like so:
if ( have_rows('services_list') ) {
'hasOfferCatalog' => array(
'#type' => 'OfferCatalog',
'name' => 'Tree Surgery'
$schema['itemListElement'] = array();
while (have_rows('services_list')) : the_row();
$services = array(
'#type' => 'Offer',
'itemOffered' => array (
'#type' => 'Service',
'name' => get_sub_field('service')
)
);
array_push($schema['itemListElement'], $services);
endwhile;
)
}
However this is not working at all. If anyone can point me in the right direction to the nested entities working in this context I'd be really grateful.
I did eventually manage to solve my issue. I never got around to posting this at he time, but since here's been a little interest here's what I did.
My 'best effort' was almost there, but I needed to make a few small adjustments. Sadly I sorted this out sometime ago and I forget the resource I used to put things right, but I hope this might be of help to someone else.
if ( have_rows('services_list') ) {
$schema['hasOfferCatalog'] = array();
$catalog = array(
'#type' => 'OfferCatalog',
'name' => 'Tree Surgery'
);
if ( have_rows('services_list') ) {
$catalog['itemListElement'] = array();
while (have_rows('services_list')) : the_row();
$services = array(
'#type' => 'Offer',
'itemOffered' => array (
'#type' => 'Service',
'name' => get_sub_field('service')
)
);
array_push($catalog['itemListElement'], $services);
endwhile;
array_push($schema['hasOfferCatalog'], $catalog);
}
}
Fr a little bit of context I have this all placed in my functions.php file and is put together like so:
function schema() {
$schema = array(
'#context' => "http://schema.org",
'#type' => "ProfessionalService",
'name' => get_bloginfo('name'),
'url' => get_home_url(),
'telephone' => '+00 0000 00000',
'address' => array(
'#type' => 'PostalAddress',
'streetAddress' => 'XXXXX',
'postalCode' => 'XXX XXX',
'addressLocality' => 'XXXXXX',
'addressRegion' => 'XXXXXXX',
'addressCountry' => 'XXXXXXXXXXXX'
),
'logo' => get_stylesheet_directory_uri() . '/path/to/your/image.svg',
'image' => get_stylesheet_directory_uri() . '/path/to/your/image.svg'
);
if ( have_rows('services_list') ) {
$schema['hasOfferCatalog'] = array();
$catalog = array(
'#type' => 'OfferCatalog',
'name' => 'Tree Surgery'
);
if ( have_rows('services_list') ) {
$catalog['itemListElement'] = array();
while (have_rows('services_list')) : the_row();
$services = array(
'#type' => 'Offer',
'itemOffered' => array (
'#type' => 'Service',
'name' => get_sub_field('service')
)
);
array_push($catalog['itemListElement'], $services);
endwhile;
array_push($schema['hasOfferCatalog'], $catalog);
}
}
echo '<script type="application/ld+json">' . json_encode($schema) . '</script>';
}
add_action('wp_head', 'schema');
It seems to do the job.
I'm currently developing a fraud detection module for PrestaShop 1.6. In this module, I need to make a call to an API just after the customer presses the button to confirm their order, but before the payment is submitted, regardless of payment gateway.
At first, after looking through all the available hooks in 1.6, I thought about using the actionValidateOrder hook to do this, the problem is that this hook is executed right after the payment is submitted/processed by the payment gateway, which is not what I'm looking for.
I also thought about using javascript to intercept the execution and then calling to a validation controller to perform, but it becomes way too specific for each gateway and the data flow between prestashop objects/ajax/javascript seems like it could turn out to be problematic.
I know you can create a custom hook, but every example I see on internet is about display hooks, none of it shows how to create a custom action hook.
This is what I was using in the actionValidateOrder hook
public function hookActionValidateOrder($params)
{
include_once(_PS_MODULE_DIR_.'bayonet/sdk/Paymethods.php');
$this->order = $params['order'];
$cart = $this->context->cart;
$address_delivery = new Address((int)$cart->id_address_delivery);
$address_invoice = new Address((int)$cart->id_address_invoice);
$state_delivery = new State((int)$address_delivery->id_state);
$country_delivery = new Country((int)$address_delivery->id_country);
$state_invoice = new State((int)$address_invoice->id_state);
$country_invoice = new Country((int)$address_invoice->id_country);
$customer = $this->context->customer;
$currency = $this->context->currency;
$products = $cart->getProducts();
$product_list = array();
foreach($products as $product)
{
$products_list[] = [
"product_id" => $product['id_product'],
"product_name" => $product['name'],
"product_price" => $product['price'],
"product_category" => $product['category']
];
}
$request = [
'channel' => 'ecommerce',
'consumer_name' => $customer->firstname.' '.$customer->lastname,
"consumer_internal_id" => $customer->id,
"transaction_amount" => $cart->getOrderTotal(),
"currency_code" => $currency->iso_code,
"telephone" => $address_invoice->phone,
"email" => $customer->email,
"payment_gateway" => $this->order->module,
"shipping_address" => [
"line_1" => $address_delivery->address1,
"line_2" => $address_delivery->address2,
"city" => $address_delivery->city,
"state" => $state_delivery->name,
"country" => convert_country_code($country_delivery->iso_code),
"zip_code" => $address_delivery->postcode
],
"billing_address" => [
"line_1" => $address_invoice->address1,
"line_2" => $address_invoice->address2,
"city" => $address_invoice->city,
"state" => $state_invoice->name,
"country" => convert_country_code($country_invoice->iso_code),
"zip_code" => $address_invoice->postcode
],
"products" => $products_list,
"order_id" => (int)$this->order->id
];
foreach ($paymentMethods as $key => $value) {
if ($this->order->module == $key)
{
$request['payment_method'] = $value;
if ($this->order->module == 'paypalmx')
$request['payment_gateway'] = 'paypal';
}
}
if (Configuration::get('BAYONET_API_MODE') == 0)
{
$this->bayonet = new BayonetClient([
'api_key' => Configuration::get('BAYONET_API_TEST_KEY'),
'version' => Configuration::get('BAYONET_API_VERSION')
]);
}
else if (Configuration::get('BAYONET_API_MODE') == 1)
{
$this->bayonet = new BayonetClient([
'api_key' => Configuration::get('BAYONET_API_LIVE_KEY_KEY'),
'version' => Configuration::get('BAYONET_API_VERSION')
]);
}
$this->bayonet->consulting([
'body' => $request,
'on_success' => function($response) {
$this->dataToInsert = array(
'id_cart' => $this->context->cart->id,
'order_no' => $this->order->id,
'status' => $response->decision,
'bayonet_tracking_id' => $response->bayonet_tracking_id,
'consulting_api' => 1,
'consulting_api_response' => json_encode(array(
'reason_code' => $response->reason_code,
'tracking_id' => $response->bayonet_tracking_id
)),
'is_executed' => 1,
);
Db::getInstance()->insert('bayonet', $this->dataToInsert);
if ($response->decision == 'decline')
{
$this->module = Module::getInstanceByName('bayonet');
Tools::redirect($this->context->link->getModuleLink($this->module->name,'rejected', array()));
}
},
'on_failure' => function($response) {
$this->dataToInsert = array(
'id_cart' => $this->context->cart->id,
'order_no' => $this->order->id,
'status' => $response->decision,
'bayonet_tracking_id' => $response->bayonet_tracking_id,
'consulting_api' => 0,
'consulting_api_response' => json_encode(array(
'reason_code' => $response->reason_code,
)),
'is_executed' => 1,
);
Db::getInstance()->insert('bayonet', $this->dataToInsert);
}
]);
}
And after detecting the issue with the hook, this is what I tried with JavaScript, which calls a validation page using ajax, this page has almost the same code as what it was in the hook
$('#form-pagar-mp').submit(function(event) {
if (lock == 1) {
params = {};
$.ajax({
url: url,
type: 'post',
data: params,
dataType: 'json',
processData: false,
success: function(data) {
if (data.error == 0) {
lock = 0;
}
else {
window.location.href = data.url;
}
}
});
}
});
I still think using a hook is the best option, but out of all available hooks, none of them meets my needs. Right now, I don't really know that else to try, that's why I need your help in how to approach this situation, any ideas are welcome and will be highly appreciated. Thank you.
You can use a hook which executes before an order payment creation
public function hookActionObjectOrderPaymentAddBefore($params)
{
/** OrderPayment $orderPayment */
$orderPayment = $params['object'];
$cart = $this->context->cart;
// to stop order payment creation you need to redirect from this hook
}
Or before order is created
public function hookActionObjectOrderAddBefore($params)
{
/** Order $order */
$order = $params['object'];
$cart = $this->context->cart;
// to stop order creation you need to redirect from this hook
}
In Yii,Iam using yii-jpegcam webcam extension used for taking photos in my application and it works fine with the following url format
index.php?r=user/newphoto
But my application is in "/" format (index.php/user/newphoto). So this extension not working with my url format. How it can be solved?
Extension Link used : http://www.yiiframew...on/yii-jpegcam/
http://www.yiiframework.com/extension/yii-jpegcam/
And my view code is :
<?php $onBeforeSnap = "document.getElementById('upload_results').innerHTML = '<h1>Uploading...</h1>';";
$completionHandler = <<<BLOCK
if (msg == 'OK') {
document.getElementById('upload_results').innerHTML = '<h1>OK! ...redirecting in 3 seconds</h1>';
// reset camera for another shot
webcam.reset();
setTimeout(function(){window.location = "index.php?r=user/index";},3000);
}
else alert("PHP Error: " + msg);
BLOCK;
$this->widget('application.extensions.jpegcam.EJpegcam', array(
'apiUrl' => 'index.php?r=user/jpegcam.saveJpg',
'shutterSound' => false,
'stealth' => true,
'buttons' => array(
'configure' => 'Configure',
'takesnapshot' => 'Take Snapshot!'
),
'onBeforeSnap' => $onBeforeSnap,
'completionHandler' => $completionHandler
)); ?>
If urlManager enabled in config, you should change apiUrl value with createUrl method :
$this->widget('application.extensions.jpegcam.EJpegcam', array(
'apiUrl' => Yii::app()->urlManager->createUrl('index.php/user/jpegcam.saveJpg'),
'shutterSound' => false,
'stealth' => true,
'buttons' => array(
'configure' => 'Configure',
'takesnapshot' => 'Take Snapshot!'
),
'onBeforeSnap' => $onBeforeSnap,
'completionHandler' => $completionHandler
));