I'm using a Wordpress REST API for building a mobile app and did heavy customizing function on ( post type ) wooCommerce to be specific that makes the response time big when requesting, for example, an endpoint like this /wp-json/wc/v3/products
my customization is registering new fields on product post type.
What I need is checking if is it a single record like this?
/wp-json/wc/v3/products/123456
Or fetching all products like this?
/wp-json/wc/v3/products
My php code for register new fields:
add_action('rest_api_init','get_custom_field');
function get_custom_field() {
register_rest_field('product', 'custom_variations', array(
'get_callback' => 'custom_variations'
));
register_rest_field('product', 'components', array(
'get_callback' => 'product_components'
));
}
You can add filter to check if there's an id provided in the url or not.
add_filter('rest_prepare_product', 'prepareProductData', 10, 3);
function prepareProductData($response, $post, $request)
{
$params = $request->get_params();
$product_id_from_url = $params["id"];
$should_append_extra_data = !empty( $product_id_from_url);
//append extra data only when there's an id provided.
if($should_append_extra_data == true) {
//append here
}
}
So in this case the $product_id_from_url will have 123456 for /wp-json/wc/v3/products/123456
Request params can be used to get many other request parameters to modify responses for different situations.
Related
I'm trying to use the alphavantage REST API to output stock prices through Advanced Custom Fields. My issue right now is that I don't know how I can create a list of stocksymbol names (we have specific stocks we want to check) that changes each call until all stocks have been checked.
This is my current Wordpress Code in functions.php
/* Register Stock Price Custom Post Type */
add_action('init', 'register_aktienpreise_cpt');
function register_aktienpreise_cpt(){
register_post_type('aktienpreise', [
'label' => 'Aktienpreise',
'public' => true,
'capability_type' => 'post'
]);
}
add_action( 'wp_ajax_nopriv_get_aktienpreise_from_api', 'get_aktienpreise_from_api' );
add_action( 'wp_ajax_get_aktienpreise_from_api', 'get_aktienpreise_from_api' );
/* Initialize Function */
function get_aktienpreise_from_api(){
/* Set Log File */
$file = get_stylesheet_directory() . '/report.txt';
/* Declare Current Symbol Variable and check if its not empty */
$current_symbol = ( ! empty($_POST['current_symbol']) ) ? $_POST['current_symbol'] : '';
$aktienpreise = [];
/* Results output for AlphaVantage Rest API + APIKEY - Add Current Symbol Set for each API Call */
$results = wp_remote_retrieve_body( wp_remote_get('https://www.alphavantage.co/query?function=GLOBAL_QUOTE&apikey=demo&symbol=' . $current_symbol_set ));
file_put_contents($file, "Current Symbol: " . $current_symbol. "\n\n", FILE_APPEND);
// turn it into a PHP array from JSON string
$results = json_decode( $results );
// Either the API is down or something else spooky happened. Just be done.
if( ! is_array( $results ) || empty( $results ) ){
return false;
}
/* Change Current Stock Symbol for the next call until empty */
$current_symbol = $current_symbol + $current_symbol_set;
/* Repeat Calls until results are empty */
wp_remote_post( admin_url('admin-ajax.php?action=get_aktienpreise_from_api'), [
'blocking' => false,
'sslverify' => false,
'body' => [
'current_symbol' => $current_symbol
]
] );
}
At this part
/* Change Current Stock Symbol for the next call until empty */
$current_symbol = $current_symbol + $current_symbol_set;
I'd like to have a list of specific stocks I want to check (for example Apple, IBM etc.).
The goal is that on each call the variable changes to the next stock (lets say first call Apple, second IBM), then writes those into the specific ACF Fields that I can showcase in a table on our website.
If the restapi urls would just have number increases it would be easy, but how do I do it with specific terms like "IBM" etc.
Furthermore if there are easier solutions to this please tell me so since I'm fairly new to REST APIs.
The Goal in general is to just display current stockprices of specific stocks inside a table on our website, preferably inside an ACF Field so we can do math formulas on the price (for example price x 2 for another table field).
Thanks for everyone taking their time to help me out!
Why don't you use an array for the stock symbols and do the AlphaVantage API calls inside a loop?
I will give you a quick example:
$my_symbols = [
'IBM',
'Microsoft',
'Tata'
];
foreach( $my_symbols as $current_symbol ) // iterate through the array elements
{
//... make the API calls to AlphaVantage
//... do any other business logic, like storing the API result in file or update the stocks, etc..
}
One thing to keep in mind is that you should make sure the script won't get a timeout. So increase the max_execution_time to a higher value.
Also, you don't have to call your own API here. I mean you don't have to do the wp_remote_post() to your own website.
I am trying to slim down the JSON returned when using the Rest API. I am able to get it to work using the "_embed" parameter in the query, but it returns a HUGE amount of data I don't need. So, per WP best practices I want to set up a custom end point and in it's callback call a function to output the three items I need. Seems simple, however it returns NULL for all nodes when I try. In my functions.php file I have:
function get_all_posts( WP_REST_Request $request ) {
return [
'id' => $data->data['id'],
'title' => $data->data['title']['rendered'],
'link' => $data->data['link'],
'date' => $data->data['date'], //not correct
//similar calls to get thumbnail image and category
];
}
Then the route and call back for the custom endpoint
add_action( 'rest_api_init', function () {
register_rest_route( 'mydata/v1', '/all', array(
'methods' => 'GET',
'callback' => 'get_all_posts',
) );
} );
when I use the url - https://somedomain.com/blog/wp-json/mydata/v1/all I get the following on page:
{
"id": null,
"title": null,
"link": null
}
You can pass field arguments to the API
Like so:
[url]/wp-json/wp/v2/tags?fields=id,name
Note this is example is /tags, you can use /categories etc, and still specify the fields.
I recommend installing the JSONView chrome plugin so that the dump of your JSON is readable when you test the endpoint .
Okay so I am trying to set up payments in my app that I am developing, I have the dialog working and it confirms the purchase of the item. I have no idea what it does after here tbh, I have read articles after articles, but no joy. I need information on how I can update mysql database on the purchase. I know the question is vague, but any guidance will be appreciated!
The code i have so far is below.
if ($request_type == 'payments_get_items') {
// Get order info from Pay Dialog's order_info.
// Assumes order_info is a JSON encoded string.
$order_info = json_decode($request['credits']['order_info'], true);
// Get item id.
$item_id = $order_info['item_id'];
// Simulutates item lookup based on Pay Dialog's order_info.
if ($item_id == '10Kremeggs') {
$item = array(
'title' => '10 Kremeggs',
'description' => 'Spend Kremeggs in Alien Abduction.',
// Price must be denominated in credits.
'price' => 5,
'image_url' => 'https://afternoon-snow-5267.herokuapp.com/images/bung.png',
'product_url' => 'https://afternoon-snow-5267.herokuapp.com/Purchase/10xKremeggs.php'
);
// Construct response.
$response = array(
'content' => array(
0 => $item,
),
'method' => $request_type,
);
// Response must be JSON encoded.
$response = json_encode($response);
}
} else if ($request_type == "payments_status_update") {
// Get order details.
$order_details = json_decode($request['credits']['order_details'], true);
// Determine if this is an earned currency order.
$item_data = json_decode($order_details['items'][0]['data'], true);
$earned_currency_order = (isset($item_data['modified'])) ?
$item_data['modified'] : null;
// Get order status.
$current_order_status = $order_details['status'];
if ($current_order_status == 'placed') {
// Fulfill order based on $order_details unless...
if ($earned_currency_order) {
// Fulfill order based on the information below...
// URL to the application's currency webpage.
$product = $earned_currency_order['product'];
// Title of the application currency webpage.
$product_title = $earned_currency_order['product_title'];
// Amount of application currency to deposit.
$product_amount = $earned_currency_order['product_amount'];
// If the order is settled, the developer will receive this
// amount of credits as payment.
$credits_amount = $earned_currency_order['credits_amount'];
}
$next_order_status = 'settled';
// Construct response.
$response = array(
'content' => array(
'status' => $next_order_status,
'order_id' => $order_details['order_id'],
),
'method' => $request_type,
);
// Response must be JSON encoded.
$response = json_encode($response);
} else if ($current_order_status == 'disputed') {
// 1. Track disputed item orders.
// 2. Investigate user's dispute and resolve by settling or refunding the order.
// 3. Update the order status asychronously using Graph API.
} else if ($current_order_status == 'refunded') {
// Track refunded item orders initiated by Facebook. No need to respond.
} else {
// Track other order statuses.
}
}
Above is part of the payment callback
<? mysql_query("UPDATE users SET Kremeggs = Kremeggs+10 WHERE Facebook_id = '$PurchaseUpdate'");
header ("Location: http://apps.facebook.com/alien_abduction/purchaseComplete.php");
?>
</body>
</html>
Above is what i need the payment to do.
It sounds like you're attempting to handle two very separate parts of the process at the same time in one file (your second code sample). The first code sample you posted (looks like their sample code, which is fine) is the proper place to award the user - your mysql query belongs inside the block which starts on line 43 (if ($current_order_status == 'placed') {). I'll leave the details of that for you to work out.
The second half of what you want to do (redirect the user to a confirmation page) does not belong in that callback, but rather on the page with the payment dialog. If you're using the sample code there as well, it belongs inside the js_callback function - try window.location.href='purchase_complete.php' (ensuring that this only happens on successful orders, ofc).
Hope that gets you pointed in the right direction!
else if ($request_type == "payments_status_update") {mysql_query("update users_table set payment_column='isok' where kulid like 'getFacebookUserId'");}
I have the following link structure for my portfolio:
<?php echo $this->Html->link($post['Portfolio']['title'], array('controller' => 'portfolio', 'action' => 'view', Inflector::slug($post['Portfolio']['title'])), array('title' => $post['Portfolio']['title'])); ?>
Which gives urls like: http://driz.co.uk/portfolio/view/Paperview_Magazine
However how do I get my controller to show the item based on the title?
So far I have this but have not been able to get it to work and just get a blank page (so I ALSO need to check the format is correct and that their is a relevant item)
function view ( $title )
{
$posts = $this->Portfolio->find('first', array('conditions' => array('Portfolio.title' => $title)
));
if (empty($title))
{
$this->cakeError('error404');
}
$this->set(compact('posts'));
}
#Ross suggested that you search using Portfolio.slug so here's how you could do this:
Add a field to your database table called slug. You'll most likely want a VARCHAR with sufficient length to accommodate the slug.
When you create or update a "Portfolio" record, use the Inflector::slug method to generate a slug and save it to your database. You could always do this in the model's beforeSave event or if you prefer, in the controller before saving the data.
Update the find call to look for Portfolio.slug instead of Portfolio.title.
Unfortunately, there's no way to reverse the Inflector::Slug function as it removes certain characters like apostrophes, quotes, parentheses, etc. which is why you need to save the slug to your database if you want to search for it.
Here's how you could use the beforeSave event in your model:
public function beforeSave(array $options = array())
{
// If the title is not empty, create/update the slug.
if ( ! empty($this->data[$this->alias]['title'] )
$this->data[$this->alias]['slug'] = Inflector::slug($this->data[$this->alias]['title']);
// Returning true is important otherwise the save or saveAll call will fail.
return true;
}
I am modifying an already contributed drupal module (Inline Ajax Search) to handle searching of a specific content type with some search filters (i.e. when searching for help documentation, you filter out your search results by selecting for which product and version of the product you want help with).
I have modified the module some what to handle all the search filters.
I also added in similar functionality from the standard core search module to handle the presenting of the search form and search results on the actual search page ( not the block form ).
The problem is that when i submit the form, i discovered that I'd lose all my post data on that submit because somewhere, and i don't know where, drupal is either redirecting me or something else is happening that is causing me to lose everything in the $_POST array.
here's the hook_menu() implementation:
<?php
function inline_ajax_search_menu() {
$items = array();
$items['search/inline_ajax_search'] = array(
'title' => t('Learning Center Search'),
'description' => t(''),
'page callback' => 'inline_ajax_search_view',
'access arguments' => array('search with inline_ajax_search'),
'type' => MENU_LOCAL_TASK,
'file' => 'inline_ajax_search.pages.inc',
);
}
?>
the page callback is defined as such (very similar to the core search module's search_view function):
<?php
function inline_ajax_search_view() {
drupal_add_css(drupal_get_path('module', 'inline_ajax_search') . '/css/inline_ajax_search.css', 'module', 'all', FALSE );
if (isset($_POST['form_id'])) {
$keys = $_POST['keys'];
// Only perform search if there is non-whitespace search term:
$results = '';
if(trim($keys)) {
require_once( drupal_get_path( 'module', 'inline_ajax_search' ) . '/includes/inline_ajax_search.inc' );
// Collect the search results:
$results = _inline_ajax_search($keys, inline_ajax_search_get_filters(), "page" );
if ($results) {
$results = theme('box', t('Search results'), $results);
}
else {
$results = theme('box', t('Your search yielded no results'), inline_ajax_search_help('inline_ajax_search#noresults', drupal_help_arg()));
}
}
// Construct the search form.
$output = drupal_get_form('inline_ajax_search_search_form', inline_ajax_search_build_filters( variable_get( 'inline_ajax_search_filters', array() ) ) );
$output .= $results;
return $output;
}
return drupal_get_form('inline_ajax_search_search_form', inline_ajax_search_build_filters( variable_get( 'inline_ajax_search_filters', array() ) ) );
}
?>
from my understanding, things should work like this: A user goes to www.mysite.com/search/inline_ajax_search and drupal will process the path given in my url and provide me with a page that holds the themed form for my search module. When i submit the form, whose action is the same url (www.mysite.com/search/inline_ajax_search), then we go thru the same function calls, but we now have data in the $_POST array and one of them is indeed $_POST['form_id'] which is the name of the form "inline_ajax_search_search_form". so we should be able to enter into that if block and put out the search results.
but that's not what happens...somewhere from when i submit the form and get my results and theme it all up, i get redirected some how and lose all my post data.
if anybody can help me, it'd make me so happy lol.
drupal_get_form actually wipes out the $_POST array and so that's why I lose all my post data.
according to this: http://drupal.org/node/748830 $_POST should really be ignored when doing things in drupal. It's better to find a way around using it. One way is the way described in the link, making ur form data persist using the $_SESSION array. I'm sure there are various other and better ways to do this, but yeah, drupal_get_form was the culprit here...