Wordpress custom page template returns the theme headers - json

I want to return a JSON array from a Wordpress website. I know this can be done using plugins like WP REST API and JSON API, but I am dealing with custom post types so I want to avoid complexity and write the queries myself.
I have overridden one of my pages by writing a new php file in my theme directory called page-345.php.
Inside my PHP file I have the following code
$args = array(
'post_type' => 'partner',
'post_status' => 'publish',
'posts_per_page' => -1 // all
);
$query = new WP_Query( $args );
$cars = array();
while( $query->have_posts() ) : $query->the_post();
// Add a car entry
$cars[] = array(
'name' => get_the_title()
);
endwhile;
wp_reset_query();
wp_send_json( $cars );
I code works and I get output in JSON. However, JSON in returned alongside the header of the template. (See screenshot)
I also tried entering the code
header( 'Content-type: application/json' );
at the top of my page, but then Wordpress returns an error saying that headers have already been set.

Related

Get ACF gutenberg block data from custom post type

I running into some problems with ACF Gutenberg blocks.
I have registered a Gutenberg block to be used in a custom post type called "Portfolio"
Through a normal wp_query i can display the custom post type on the homepage. But i can not get the ACF Gutenberg block data to show?
Below is the code im currently using.
<?php
// WP_Query arguments
$args = array(
'post_type' => array( 'portfolio' ),
'post_status' => array( 'publish' ),
'nopaging' => false,
'posts_per_page' => '5',
);
// The Query
$query_portfolio = new WP_Query( $args );
// The Loop
if ( $query_portfolio->have_posts() ) {
while ( $query_portfolio->have_posts() ) {
$query_portfolio->the_post();
}
// ACF group
$content = get_field('content');
?>
<!-- // ACF field from within group NOT SHOWING -->
<h1><?php echo $content['title']; ?></h1>
<h2><?php the_title(); ?></h2>
<?php
} else {
// no posts found
}
// Restore original Post Data
wp_reset_postdata();
?>
Im stuck at this point. Somehow i can not get the Gutenberg Block fields to show within the query on the homepage.
All help is appreciated.
Thanks

Populate WordPress Advanced Custom Fields with remote JSON in backend

I have custom post types called "Products". and using the AFC(Advanced Custom Fields) plugin with this post type.
Below is what ACF has in fields group
- one filed called 'Product Description' as text area
- three text fields called 'Feature 1, Feature 2,Feature 3'
What I want to achieve is to get the data from external JSON file and populate the above ACF fields in the backend. I did some research and found Wordpress offers wp_remote_get() function to request the remote file. But I have no clue where to begin with to use this function or any other approach to use external JSON and populate these fields. Will really appreciate it someone points me to the right direction or any tutorial that shows how to achieve that. Thanks
I figured it out. View the working code below.
// Get JSON and Decode
$json_request = wp_remote_get( 'http://wp-test/test/data.json');
if( is_wp_error( $json_request ) ) {
return false;
}
$json_body = wp_remote_retrieve_body( $json_request );
$json_data = json_decode( $json_body );
// Create the new post and populate the fields
foreach( $json_data->products as $item ) {
$title = $item->title;
$desc = $item->content;
$status = $item->status;
$new_post = array(
'post_title' => $title,
'post_content' => $desc,
'post_status' => $status,
'post_author' => $userID,
'post_type' => 'products'
);
$post_id = post_exists( $title );
if (!$post_id) {
$post_id = wp_insert_post($new_post);
}
}

Laravel's Maximum function nesting level of '256' reached

I'm calling an API which gives a nested mixture of JSON, STDClass, and Arrays. One of my main concerns was trying to take out specific data out of it which has been solved. The point is that the code worked until I tried to use Laravel blade. After creating a layout called master.layout.php, and creating a section called 'content' which takes the codes inside the tag, It stopped working and kept giving me "Maximum function nesting level of '256' reached" error.
There were some solutions in Stackoverflow that I tried and some tricks to even bypass it by changing the xdebug config in PHP.ini file. but unfortunately, none of them worked for me. One the members said "it's better to take a look at the structure of your code instead of trying to bypass it so I did. From what I figured out, I feel like json_decode() function keep recursing since its a recursive function. I tried to set the depth for it but it didn't work as well. I'd be glad if someone guides me about the ways to fix this issue.
Here is the code:
price.blade.php:
#extends('layouts.master')
#section('content')
#php
$btc = new \App\Http\Controllers\CoinsController();
$parameters = [
'start' => '1',
'limit' => '1',
];
$query = http_build_query($parameters);
$result = $btc->apiGet('https://pro-api.coinmarketcap.com/v1/cryptocurrency/listings/latest'."?".$query);
$price = json_decode($result['response'])->data[0]->quote->USD->price;
#endphp
<h1>Bitcoin Price Live</h1>
<h2>{{"Current Price of Bitcoin: ". $price}}</h2>
#stop
CoinsController.php:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class CoinsController extends Controller
{
function apiGet($url)
{
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => $url,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_TIMEOUT => 30000,
CURLOPT_POST => true,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => array(
// Set Here Your Requesred Headers
'Content-Type: application/json',
'Accept-Encoding: deflate, gzip',
'X-CMC_PRO_API_KEY: xxxxxxxxxxxxxxxxxxx',
),
)
);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
json_decode($response);
}
return view('index.price', compact('response'));
}
}
You shouldn't really be instantiating the controller within the blade template.
The issue is that you are essentially causing infinite loop.
Within your controller you are loading your blade view. Then within your blade view you are creating a new instance of the controller and running the method again. That method then returns the same view and so the process starts again. This will then keep going on and on and on until PHP eventually hit's a limit - and that is the issue here.
Instead you should have one controller that returns the view. You could then have a separate class that you instantiate which just returns you the value you are after as a string. That way you are not reloading the controller and getting caught in an infinite loop.

cakephp : getting pagination link in json format

I am developing a REST API using CakePHP and want to implement the Instagram API pagination style which looks something like this:
{
...
"pagination": {
"next_url": "https://api.instagram.com/v1/tags/puppy/media/recent?access_token=fb2e77d.47a0479900504cb3ab4a1f626d174d2d&max_id=13872296",
"next_max_id": "13872296"
}
}
I have not used any authorization or whatever, so the access_token part can be ignored. My main motive is to get the pagination links (jump links preferably) as JSON data, so I can use it in my JSON serialized view. Because the usual code:
echo $this->Paginator->prev('< ' . __('previous'), array(), null, array('class' => 'prev disabled'));
echo $this->Paginator->numbers(array('separator' => ''));
echo $this->Paginator->next(__('next') . ' >', array(), null, array('class' => 'next disabled'));
doesn't work and simply displays the equivalent HTML code.
Is there any way I can get it like the Instagram API?
Thanks to noslone, i have got the answer. here is the final edited code:
$url = 'http://yourapp.com/pages/index/limit:7';
$returnArray = array(
.....
'pagination' => array(
'next_url' => null,
'prev_url' => null
)
);
if($this->Paginator->hasNext()) {
$temp = intval($this->Paginator->current())+1;
$returnArray['pagination']['next_url'] = $url."/page:".$temp;
}
if($this->Paginator->hasPrev()) {
$temp = intval($this->Paginator->current())-1;
$returnArray['pagination']['next_url'] = $url."/page:".$temp;
}
echo json_encode($returnArray);
just two changes : first don't forget to add limit:value" to your url and secondly use intval with the Paginator->current.
Try something as follow
$url = 'http://yourapp.com/pages/index';
$returnArray = array(
.....
'pagination' => array(
'next_url' => null,
'prev_url' => null
)
);
if($this->Paginator->hasNext()) {
$returnArray['pagination']['next_url'] = $url.'/page:'. ($this->Paginator->current()+1);
}
if($this->Paginator->hasPrev()) {
$returnArray['pagination']['prev_url'] = $url.'/page:'. ($this->Paginator->current()-1);
}
echo json_encode($returnArray);
If you want, you can add more named params to the url:
$params['pagination']['next_url'] = $url.'/page:'.$this->Paginator->current()+1.'/order:name/direction:asc';
As far as I know, Paginator helper generates the front-end link, and when you click on it, it will generate next link.
I do not think you can use it directly to form the Instagram alike API.

Google Map V3 Cakephp helper and multiple markers

I am using the Cakephp Google Map V3 Helper. I can get the google map to show up but the markers do not. Here is my view code:
<?php
echo $this->GoogleMapV3->map();
foreach ($allcondos as $condo) {
$options = array(
'lat' => $condo['Unit']['lat'],
'lng' => $condo['Unit']['lon']
);
$this->GoogleMapV3->addMarker($options);
}
?>
I know that if I just tell the app to echo out my $condo['Unit']['lat'] or ['lon'] it will do so in the foreach loop (so it is pulling my data). What I don't know how to do is how to write the code for the $options array. I have also tried this:
foreach ($allcondos as $condo) {
$lat=$condo['Unit']['lat'];
$lon=$condo['Unit']['lon'];
$options = array(
'lat' => $lat,
'lng' => $lon
);
$this->GoogleMapV3->addMarker($options);
}
How do I write this correctly?
A couple easy steps to get this to work:
Download
Download from https://github.com/dereuromark/cakephp-google-map-v3-helper and place the GoogleMapV3Helper.php file in /app/view/helper/GoogleMapV3Helper.php.
Load Helper
Either modify your appcontroller so that the top of it reads like the following:
<?php
class AppController extends Contoller{
public $helpers = array('Html','Javascript','GoogleMapV3');
}
?>
Or load it in a single controller by adding it to the helpers array as such:
<?php
class DemoController extends AppContoller{
function map() {
$this->helpers[] = 'GoogleMapV3';
# rest of your code
}
}
?
Include Scripts
Include Jquery in your header. Include the following as well:
<?php
echo '<script type="text/javascript" src="'.$this->GoogleMapV3->apiUrl().'"></script>';
?>
Create Map Container
Put this in your view where you want your map to appear. Feel free to modify the properties of the div.
<?php echo $this->GoogleMapV3->map(array('div'=>array('id'=>'my_map', 'height'=>'400', 'width'=>'100%'))); ?>
Note: you can change the default position of the map by including more options than just 'div':
<?php echo $this->GoogleMapV3->map(array('map'=>array(
'defaultLat' => 40, # only last fallback, use Configure::write('Google.lat', ...); to define own one
'defaultLng' => -74, # only last fallback, use Configure::write('Google.lng', ...); to define own one
'defaultZoom' => 5,
),'div'=>array('id'=>'my_map', 'height'=>'400', 'width'=>'100%'))); ?>
Add markers
Can be in a loop or whatever, but this is done in the view after your container is created.
<?php
$options = array(
'lat'=>40.770272,
'lng'=>-73.974037,
'title' => 'Some title', # optional
'content' => '<b>HTML</b> Content for the Bubble/InfoWindow' # optional
);
$this->GoogleMapV3->addMarker($options);
?>
note: only set the 'icon' key in the array if you want to use a custom image. Otherwise, they will not show up.
Include the script for the markers
<?php echo $this->GoogleMapV3->script() ?>
All done!
Alternately, you can use finalize() instead of script() if you do not want to echo the javascript right away, but write it to the buffer for later output in your layout:
<?php $this->GoogleMapV3->finalize(); ?>
See http://www.dereuromark.de/2010/12/21/googlemapsv3-cakephp-helper/ for details.