admin管理员组文章数量:1122846
I need to create an endpoint that when called returns an XML with the products of the store. I have the XML generated, but I don't know how to make the endpoint return it in XML format, because now it returns it in JSON format, and being an XML, it does not return it well.
This is my code:
<?php
/**
* Plugin Name: example
* Plugin URI: /
* Description: example
* Version: 1.0
* Author: example
* Author URI: /
*/
function smg_feed() {
$args = array( 'post_status' => 'publish', numberposts => -1 );
$products = wc_get_products($args);
$xml_header = '<?xml version="1.0" encoding="UTF-8"?><Document></Document>';
$xml = new SimpleXMLElement($xml_header);
foreach($products as $product) {
$data = $product->get_data();
$sku = $data['sku'];
$categoriasNombres = array();
$subcategoriasNombres = array();
foreach( wp_get_post_terms( $data['id'], 'product_cat' ) as $term ){
if( $term ){
if ($term->name == 'XXXX' || $term->name == 'YYYY') {
array_push($categoriasNombres, $term->name);
} else {
array_push($subcategoriasNombres, $term->name);
}
}
}
$categoriasNombres = implode(',', $categoriasNombres);
$subcategoriasNombres = implode(',', $subcategoriasNombres);
$propiedadesNombres = array();
foreach( wp_get_post_terms( $data['id'], 'product_tag' ) as $term ){
if( $term ){
array_push($propiedadesNombres, $term->name);
}
}
$propiedadesNombres = implode(',', $propiedadesNombres);
$nombre = $data['name'];
$formatosNombres = array();
foreach( wp_get_post_terms( $data['id'], 'pa_formato' ) as $term ){
if( $term ){
array_push($formatosNombres, $term->name);
}
}
$formatosNombres = implode(',', $formatosNombres);
$metaData = $data['meta_data'];
foreach($metaData as $item) {
if ($item->key == '_role_based_price') {
$obj = $item->value;
$precio = $obj['api1']['regular_price'];
$precioEspecial = $obj['api2']['regular_price'];
}
}
$row = $xml->addChild('row');
$row->addChild('sku', $sku);
$row->addChild('categorias', $categoriasNombres);
$row->addChild('subcategorias', $subcategoriasNombres);
$row->addChild('propiedades', $propiedadesNombres);
$row->addChild('nombre', $nombre);
// $row->addChild('imagen', );
$row->addChild('formatos', $formatosNombres);
$row->addChild('precio', $data['regular_price']);
$row->addChild('precio_especial', $precioEspecial);
}
$output = $xml->asXML();
return $output;
}
add_action('rest_api_init', function() {
register_rest_route('smg/v1', 'feed', [
'methods' => 'GET',
'callback' => 'smg_feed',
]);
});
But when I make the call to the endpoint what it returns is this:
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n
<Document>
<row>
<sku\/>
<categorias>Nutrici\u00f3n<\/categorias>
<subcategorias>Nutridefense Plus<\/subcategorias>
<propiedades>todo<\/propiedades>
<nombre>NutriDefense plus<\/nombre>
<formatos\/>
<precio>29,90<\/precio>
<precio_especial>26,52<\/precio_especial>
<\/row>
<\/Document>\n"
How can I make it return it in XML format? Thank you very much.
Regards.
I need to create an endpoint that when called returns an XML with the products of the store. I have the XML generated, but I don't know how to make the endpoint return it in XML format, because now it returns it in JSON format, and being an XML, it does not return it well.
This is my code:
<?php
/**
* Plugin Name: example
* Plugin URI: https://www.example.es/
* Description: example
* Version: 1.0
* Author: example
* Author URI: https://www.example.es/
*/
function smg_feed() {
$args = array( 'post_status' => 'publish', numberposts => -1 );
$products = wc_get_products($args);
$xml_header = '<?xml version="1.0" encoding="UTF-8"?><Document></Document>';
$xml = new SimpleXMLElement($xml_header);
foreach($products as $product) {
$data = $product->get_data();
$sku = $data['sku'];
$categoriasNombres = array();
$subcategoriasNombres = array();
foreach( wp_get_post_terms( $data['id'], 'product_cat' ) as $term ){
if( $term ){
if ($term->name == 'XXXX' || $term->name == 'YYYY') {
array_push($categoriasNombres, $term->name);
} else {
array_push($subcategoriasNombres, $term->name);
}
}
}
$categoriasNombres = implode(',', $categoriasNombres);
$subcategoriasNombres = implode(',', $subcategoriasNombres);
$propiedadesNombres = array();
foreach( wp_get_post_terms( $data['id'], 'product_tag' ) as $term ){
if( $term ){
array_push($propiedadesNombres, $term->name);
}
}
$propiedadesNombres = implode(',', $propiedadesNombres);
$nombre = $data['name'];
$formatosNombres = array();
foreach( wp_get_post_terms( $data['id'], 'pa_formato' ) as $term ){
if( $term ){
array_push($formatosNombres, $term->name);
}
}
$formatosNombres = implode(',', $formatosNombres);
$metaData = $data['meta_data'];
foreach($metaData as $item) {
if ($item->key == '_role_based_price') {
$obj = $item->value;
$precio = $obj['api1']['regular_price'];
$precioEspecial = $obj['api2']['regular_price'];
}
}
$row = $xml->addChild('row');
$row->addChild('sku', $sku);
$row->addChild('categorias', $categoriasNombres);
$row->addChild('subcategorias', $subcategoriasNombres);
$row->addChild('propiedades', $propiedadesNombres);
$row->addChild('nombre', $nombre);
// $row->addChild('imagen', );
$row->addChild('formatos', $formatosNombres);
$row->addChild('precio', $data['regular_price']);
$row->addChild('precio_especial', $precioEspecial);
}
$output = $xml->asXML();
return $output;
}
add_action('rest_api_init', function() {
register_rest_route('smg/v1', 'feed', [
'methods' => 'GET',
'callback' => 'smg_feed',
]);
});
But when I make the call to the endpoint what it returns is this:
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n
<Document>
<row>
<sku\/>
<categorias>Nutrici\u00f3n<\/categorias>
<subcategorias>Nutridefense Plus<\/subcategorias>
<propiedades>todo<\/propiedades>
<nombre>NutriDefense plus<\/nombre>
<formatos\/>
<precio>29,90<\/precio>
<precio_especial>26,52<\/precio_especial>
<\/row>
<\/Document>\n"
How can I make it return it in XML format? Thank you very much.
Regards.
Share Improve this question asked Nov 10, 2020 at 12:02 pmjpmj 631 silver badge3 bronze badges 3 |2 Answers
Reset to default 6By default, the output returned by your endpoint/callback will always be sent as a JSON-encoded string (and the Content-Type
header would also be/contain application/json
), so you can't use that callback for sending an XML feed.
However, you can use the rest_pre_serve_request
hook if you want your REST API route to serve a different type of content like the XML feed in your case.
So for example, you can do:
Set your callback (
smg_feed()
) to return the XML data which will be echoed in themaybe_smg_feed()
below: (note that thepermission_callback
should always be set, check the REST API handbook for more details)function smg_feed( $request ) { // ... your code ... return 'your XML data'; } add_action( 'rest_api_init', function () { register_rest_route( 'smg/v1', 'feed', [ 'methods' => 'GET', 'callback' => 'smg_feed', // make sure it returns an XML string 'permission_callback' => '__return_true', ]); });
Then send the XML response like so:
function maybe_smg_feed( $served, $result, $request, $server ) { // Bail if the route of the current REST API request is not our custom route. if ( '/smg/v1/feed' !== $request->get_route() || // Also check that the callback is smg_feed(). 'smg_feed' !== $request->get_attributes()['callback'] ) { return $served; } // Send headers. $server->send_header( 'Content-Type', 'text/xml' ); // Echo the XML that's returned by smg_feed(). echo $result->get_data(); // And then exit. exit; } add_filter( 'rest_pre_serve_request', 'maybe_smg_feed', 10, 4 );
Alternatively (as I mentioned in the original answer), without using the REST API (which does work), you can use add_feed()
to deliver the XML feed.
( PS: Thanks to @TimothyJacobs for his help/comment. :) )
function smg_feed( $request ) {
....
echo $xml->asXML();
return new WP_REST_Response( null, 200, ['Content-Type' => 'text/xml'] );
}
本文标签: plugin developmentCustom endpoint that returns an xml
版权声明:本文标题:plugin development - Custom endpoint that returns an xml 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1736288666a1928140.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
register_rest_route('smg/v1', 'feed', ... );
so this will be /wp-json/smg/v1/feed on your site. – Rup Commented Feb 18, 2021 at 9:49