I am looking to create pnr in sabre for return flight with branded fares. So basically I have 2 different branded PricedItinerary one for onward and other for return and I want to create singe PNR for both this PricedItinerary. How is it possible ? I tired sending brandId in flightsegment. PNR gets created but getting error "
{
"code": "WARN.SWS.HOST.ERROR_IN_RESPONSE",
"content": "OTA_AirPriceLLSRQ: NO COMBINABLE FARES FOR CLASS USED"
},
{
"code": "53",
"content": "NO COMBINABLE FARES FOR CLASS USED"
}
This kind of error happens when you are trying to combining non-combinable classes/fares try to use a class/branded more permissive in both segments.
To help you I have to know:
What is/are the segment/s
Class/classes sued during the pricing
In a nutshell, post your RQ payload please!
Use This Json Request Replace your PCC And RPH Information
<?php
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => 'https://api-
crt.cert.havail.sabre.com/v2.4.0/passenger/records?mode=create',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => '',
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 0,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_POSTFIELDS =>'{
"CreatePassengerNameRecordRQ":{
"targetCity":"Z01K",
"haltOnAirPriceError":true,
"TravelItineraryAddInfo":{
"AgencyInfo":{
"Address":{
"AddressLine":" Your Agency",
"CityName":"Dhaka",
"CountryCode":"BD",
"PostalCode":"1215",
"StateCountyProv":{
"StateCode":"BD"
},
"StreetNmbr":"Dhaka"
},
"Ticketing":{
"TicketType":"7TAW"
}
},
"CustomerInfo":{
"ContactNumbers":{
"ContactNumber":[
{
"NameNumber":"1.1",
"Phone":"8801685370455",
"PhoneUseType":"H"
}
]
},
"PersonName":[
{
"NameNumber":"1.1",
"GivenName":"Fahim",
"Surname":"Fahim",
"Infant":false,
"PassengerType":"ADT",
"NameReference":""
}
]
}
},
"AirBook":{
"HaltOnStatus":[
{
"Code":"HL"
},
{
"Code":"KK"
},
{
"Code":"LL"
},
{
"Code":"NN"
},
{
"Code":"NO"
},
{
"Code":"UC"
},
{
"Code":"US"
}
],
"OriginDestinationInformation":{
"FlightSegment":[
{
"DepartureDateTime":"2022-06-30T06:35:00",
"ArrivalDateTime":"2022-06-30T12:05:00",
"FlightNumber":"713",
"NumberInParty":"1",
"ResBookDesigCode":"S",
"Status":"NN",
"OriginLocation":{
"LocationCode":"DAC"
},
"DestinationLocation":{
"LocationCode":"IST"
},
"MarketingAirline":{
"Code":"TK",
"FlightNumber":"713"
}
},{
"DepartureDateTime":"2022-06-30T13:30:00",
"ArrivalDateTime":"2022-06-30T17:15:00",
"FlightNumber":"1",
"NumberInParty":"1",
"ResBookDesigCode":"S",
"Status":"NN",
"OriginLocation":{
"LocationCode":"IST"
},
"DestinationLocation":{
"LocationCode":"JFK"
},
"MarketingAirline":{
"Code":"TK",
"FlightNumber":"1"
}
}
]
},
"RedisplayReservation":{
"NumAttempts":10,
"WaitInterval":300
}
},
"AirPrice":[
{
"PriceRequestInformation":{
"Retain":true,
"OptionalQualifiers":{
"FOP_Qualifiers":{
"BasicFOP":{
"Type":"CASH"
}
},
"PricingQualifiers":{
"PassengerType":[
{
"Code":"ADT",
"Quantity":"1"
}
]
}
}
}
}
],
"SpecialReqDetails":{
"SpecialService":{
"SpecialServiceInfo":{
"AdvancePassenger":[
{
"Document":{
"Number":"BM2004955",
"IssueCountry":"BGD",
"NationalityCountry":"BGD",
"ExpirationDate":"2024-08-09",
"Type":"P"
},
"PersonName":{
"NameNumber":"1.1",
"GivenName":"Kayes Fahim",
"MiddleName":"Fuad",
"Surname":"Fahim",
"DateOfBirth":"1998-01-11",
"Gender":"M"
},
"SegmentNumber":"A"
}
],
"SecureFlight":[
{
"PersonName":{
"NameNumber":"1.1",
"GivenName":"Kayes Fahim",
"Surname":"Fuad",
"DateOfBirth":"1998-01-11",
"Gender":"M"
},
"SegmentNumber":"A",
"VendorPrefs":{
"Airline":{
"Hosted":false
}
}
}
],
"Service":[
{
"SSR_Code": "OTHS",
"Text": "CC Kayes Fahim",
"PersonName": {
"NameNumber": "1.1"
},
"SegmentNumber": "1"
},
{
"SSR_Code": "CTCM",
"Text": "Fahim",
"PersonName": {
"NameNumber": "1.1"
},
"SegmentNumber": "1"
},
{
"SSR_Code": "CTCE",
"Text": "fahim//flyfarint.com",
"PersonName": {
"NameNumber": "1.1"
},
"SegmentNumber": "1"
}
]
}
}
},
"PostProcessing":{
"EndTransaction":{
"Source":{
"ReceivedFrom":"API WEB"
}
},
"RedisplayReservation":{
"waitInterval":100
}
}
}
}',
CURLOPT_HTTPHEADER => array(
'Content-Type: application/json',
'Conversation-ID: 2021.01.DevStudio',
'Authorization: Bearer 'your TOken'
),
));
$response = curl_exec($curl);
curl_close($curl);
echo $response;
?>
Are you using the same marriage indicators that BFM is returning? Maybe it would help to copy the request that returns this error here (without any confidential data, of course).
Related
I use YARP as an API gateway and DevExpress for ASP.net Core for UI in my microservice solution.
UI code (port 7004)
gItems.AddSimpleFor(c => c.CustomerID).ColSpan(2)
.Label(l => l.Text(#L["utim_form_CustomerAbbr"]).ShowColon(false))
.Editor(e => e.SelectBox()
.DataSource(d => d.RemoteController()
.LoadUrl("/api/customer-service/customer/basic-list")
.Key("customerID")
)
.DataSourceOptions(c => c.Paginate(true).PageSize(10))
.ID("sb_customer")
.SearchEnabled(true)
.OnValueChanged("onChangedCustomerAbbr")
.ElementAttr("customerName", "customerName")
.DisplayExpr("customerAbbr")
.ValueExpr("customerID")
.ShowClearButton(true)
);
Back-end code (port 7006)
public async Task<LoadResult> GetBasicListAsync(DataSourceLoadOptions loadOptions)
{
int companyId = 1;
var customers = await _customerRepository.GetQueryableAsync();
var query = (from c in customers
where c.CompanyID == companyId
select new
{
c.CustomerID,
c.CustomerAbbr,
c.CustomerName,
c.Address
});
return await DataSourceLoader.LoadAsync(query, loadOptions);
}
DataSourceLoadOptions properties:
{
"requireTotalCount": true,
"requireGroupCount": true,
"isCountQuery": true,
"isSummaryQuery": true,
"skip": 0,
"take": 0,
"sort": [
{
"selector": "string",
"desc": true
}
],
"group": [
{
"selector": "string",
"desc": true,
"groupInterval": "string",
"isExpanded": true
}
],
"filter": [
"string"
],
"totalSummary": [
{
"selector": "string",
"summaryType": "string"
}
],
"groupSummary": [
{
"selector": "string",
"summaryType": "string"
}
],
"select": [
"string"
],
"preSelect": [
"string"
],
"remoteSelect": true,
"remoteGrouping": true,
"expandLinqSumType": true,
"primaryKey": [
"string"
],
"defaultSort": "string",
"stringToLower": true,
"paginateViaPrimaryKey": true,
"sortByPrimaryKey": true,
"allowAsyncOverSync": true
}
YARP config (port 7500)
{
"ReverseProxy": {
"Routes": {
"Customer Service": {
"ClusterId": "customerCluster",
"Match": {
"Path": "/api/customer-service/{**everything}"
}
}
},
"Clusters": {
"customerCluster": {
"Destinations": {
"destination1": {
"Address": "https://localhost:7006"
}
}
}
}
}
}
When running my solution, in Chrome Developer tool, I see client sent correct request like this: https://localhost:7004/api/customer-service/customer/basic-list?skip=0&take=10
but on the gateway, it only received this url:
2023-02-17 16:36:07.006 +07:00 [INF] Request starting HTTP/1.1 GET https://localhost:7500/api/customer-service/customer/basic-list?api-version=1.0 - -
2023-02-17 16:36:07.007 +07:00 [INF] Executing endpoint 'Customer Service'
2023-02-17 16:36:07.007 +07:00 [INF] Proxying to https://localhost:7006/api/customer-service/customer/basic-list?api-version=1.0 HTTP/2 RequestVersionOrLower no-streaming
2023-02-17 16:36:07.043 +07:00 [INF] Received HTTP/2.0 response 200.
The part skip=0&take=10 was removed and I don't know why? Any help is highly appreciated.
In the WordPress website, I have added one custom post type "inventory".To post data to that inventory created one end rest API endpoint. the created endpoint is not getting all the metadata from the inventory post type. In that inventory post type, I have an input field to enter date but while getting the data using endpoint I am not getting that date field data. I have tried register_rest_field() to get metadata using API endpoint, but in postman, I am getting only some fields.
My HTML Code looks like below
<div class="from_date inventory-form-to-input">
<input type="text" style="border: 1px solid #ddd;" class="pac-date-picker hasDatepicker"
name="nets_availability_pickup_datetime[]" value="0000-00-00 00:00:00" autocomplete="off"
id="dp1605714040849">
</div>
<div class="to_date inventory-form-to-input">
<input type="text" style="border: 1px solid #ddd;" class="pac-date-picker hasDatepicker"
name="nets_availability_dropoff_datetime[]" value="0000-00-00 00:00:00" autocomplete="off"
id="dp1605714040850">
</div>
And response in postman:
{
"id": 197794,
"date": "2020-11-03T04:33:35",
"date_gmt": "2020-11-03T10:33:35",
"guid": {
"rendered": "https://mywebsite.com.com/?post_type=inventory&p=197794"
},
"modified": "2020-11-17T10:11:24",
"modified_gmt": "2020-11-17T16:11:24",
"slug": "000-030-065x-001",
"status": "publish",
"type": "inventory",
"link": "https://mywebsite.com.com/inventory/000-030-065x-001/",
"title": {
"rendered": "000-030-065x-001"
},
"featured_media": 0,
"parent": 0,
"template": "",
"meta": {
"nets_hourly_ranges_cost": [
"a:0:{}"
],
"nets_daily_pricing": [
"a:0:{}"
],
"nets_monthly_pricing": [
"a:0:{}"
],
"nets_day_ranges_cost": [
"a:0:{}"
],
"_edit_lock": [
"1605629551:619"
],
"_edit_last": [
"619"
],
"quantity": [
"1"
],
"pricing_type": [
"general_pricing"
],
"general_price": [
"100"
],
"_yoast_wpseo_focuskeywords": [
"[]"
],
"_yoast_wpseo_keywordsynonyms": [
"[\"\"]"
]
},
"quantity": "1",
"pricing_type": "general_pricing",
"general_price": "100",
"nets_availability_block_by": [],
"nets_availability_pickup_datetime": "",
"_links": {
"self": [
{
"href": "https://mywebsite.com.com/wp-json/wp/v2/inventory/197794"
}
],
"collection": [
{
"href": "https://mywebsite.com/wp-json/wp/v2/inventory"
}
],
"about": [
{
"href": "https://mywebsite.com/wp-json/wp/v2/types/inventory"
}
],
"wp:attachment": [
{
"href": "https://mywebsite.com/wp-json/wp/v2/media?parent=197794"
}
],
"curies": [
{
"name": "wp",
"href": "https://api.w.org/{rel}",
"templated": true
}
]
}
},
tried below code to create a custom endpoint and to get metadata:
function my_plugin_rest_route_for_post( $route, $post ) {
if ( $post->post_type === 'inventory' ) {
$route = '/wp/v2/inventory/' . $post->ID;
}
return $route;
}
add_action( 'rest_api_init', function () {
register_rest_field( 'inventory', 'quantity', array(
'get_callback' => function( $post_arr ) {
return get_post_meta( $post_arr['id'], 'quantity', true );
},
) );
register_rest_field( 'inventory', 'pricing_type', array(
'get_callback' => function( $post_arr ) {
return get_post_meta( $post_arr['id'], 'pricing_type', true );
},
) );
register_rest_field( 'inventory', 'general_price', array(
'get_callback' => function( $post_arr ) {
return get_post_meta( $post_arr['id'], 'general_price', true );
},
) );
register_rest_field( 'inventory', 'nets_availability_block_by', array(
'get_callback' => function( $post_arr ) {
return get_post_meta( $post_arr['id'], 'nets_availability_block_by',false);
},
) );
register_rest_field( 'inventory', 'nets_availability_pickup_datetime', array(
'get_callback' => function( $post_arr ) {
return get_post_meta( $post_arr['id'], 'nets_availability_pickup_datetime', true );
},
) );
/*used to get all metadata*/
register_rest_field( 'inventory', 'meta', array(
'get_callback' => function( $post_arr ) {
return get_post_meta( $post_arr['id'], '', true );
},
) );
} );
please anyone suggest me how to get those datefields 'nets_availability_pickup_datetime' & 'nets_availability_dropoff_datetime'.
Thanks in advance.
You can get inspiration from one of my old code. Permission callback is used to add a security layer to your API, but is usually optional. The parameter args is also optional.
register_rest_route('v2/boutique', '/order/status', array(
'methods' => 'POST',
'permission_callback' => array($this, 'check_access'),
'callback' => array($this, "api_check_order"),
'args' => [
'transaction_id', 'order_id'
],
));
public function check_access(WP_REST_Request $request)
{
// Check credential
// if(in_array($_SERVER['REMOTE_ADDR'], self::$available_ip)){
$creds = $request->get_header('token');
if (!empty($creds)) {
if (self::verify_token(self::$creds_pass, $creds)) {
return true;
} else {
return new WP_Error(
'rest_forbidden',
__('Error'),
array('status' => 404)
);
}
} else {
return new WP_Error(
'rest_forbidden',
__('Error'),
array('status' => 404)
);
}
}
I'm setting up an action which uses push notifications. Yet, on firebase I can't get "UPDATES_USER_ID" of user to save. It returns "undefined".
I followed the guide on this link and here is my code to get UPDATES_USER_ID.
app.intent('Setup', (conv, params) => {
conv.ask(new UpdatePermission({
intent: "notificationResponseIntent"
}));
});
app.intent("FinishNotificationSetup", (conv, params) => {
if (conv.arguments.get('PERMISSION')) {
conv.data.GoogleUserID = conv.arguments.get("UPDATES_USER_ID");
console.log(conv.data.GoogleUserID);
conv.ask("some response....");
}
});
And here is my webhook request when FinishNotificationSetup intent is invoked.
{
"responseId": "2f425fe5-db42-47dc-90a1-c9bc85f725d2",
"queryResult": {
"queryText": "actions_intent_PERMISSION",
"parameters": {},
"allRequiredParamsPresent": true,
"fulfillmentMessages": [
{
"text": {
"text": [
""
]
}
}
],
"outputContexts": [
{
"name": "projects/projectname/agent/sessions/ABwppHGD33Tyho41g9Mr2vzxePlskNmvOzCTxUiDGzENcl3C7RQs94aOQ8ae_DUlOApR0VBO9DuwAWdWr2frAA/contexts/actions_capability_screen_output"
},
{
"name": "projects/projectname-10c22/agent/sessions/ABwppHGD33Tyho41g9Mr2vzxePlskNmvOzCTxUiDGzENcl3C7RQs94aOQ8ae_DUlOApR0VBO9DuwAWdWr2frAA/contexts/actions_intent_permission",
"parameters": {
"PERMISSION": true,
"text": ""
}
},
{
"name": "projects/projectname-10c22/agent/sessions/ABwppHGD33Tyho41g9Mr2vzxePlskNmvOzCTxUiDGzENcl3C7RQs94aOQ8ae_DUlOApR0VBO9DuwAWdWr2frAA/contexts/_actions_on_google",
"lifespanCount": 98,
"parameters": {
"data": "{\"***":\"***",\"***":\"***"}"
}
},
{
"name": "projects/projectname-10c22/agent/sessions/ABwppHGD33Tyho41g9Mr2vzxePlskNmvOzCTxUiDGzENcl3C7RQs94aOQ8ae_DUlOApR0VBO9DuwAWdWr2frAA/contexts/actions_capability_account_linking"
},
{
"name": "projects/projectname-10c22/agent/sessions/ABwppHGD33Tyho41g9Mr2vzxePlskNmvOzCTxUiDGzENcl3C7RQs94aOQ8ae_DUlOApR0VBO9DuwAWdWr2frAA/contexts/actions_capability_audio_output"
},
{
"name": "projects/projectname-10c22/agent/sessions/ABwppHGD33Tyho41g9Mr2vzxePlskNmvOzCTxUiDGzENcl3C7RQs94aOQ8ae_DUlOApR0VBO9DuwAWdWr2frAA/contexts/google_assistant_input_type_keyboard"
},
{
"name": "projects/projectname-10c22/agent/sessions/ABwppHGD33Tyho41g9Mr2vzxePlskNmvOzCTxUiDGzENcl3C7RQs94aOQ8ae_DUlOApR0VBO9DuwAWdWr2frAA/contexts/actions_capability_web_browser"
},
{
"name": "projects/projectname-10c22/agent/sessions/ABwppHGD33Tyho41g9Mr2vzxePlskNmvOzCTxUiDGzENcl3C7RQs94aOQ8ae_DUlOApR0VBO9DuwAWdWr2frAA/contexts/actions_capability_media_response_audio"
}
],
"intent": {
"name": "projects/projectname-10c22/agent/intents/a12b6d3f-0f24-45e9-a1b2-5649083831b0",
"displayName": "FinishNotificationSetup"
},
"intentDetectionConfidence": 1,
"languageCode": "tr"
},
"originalDetectIntentRequest": {
"source": "google",
"version": "2",
"payload": {
"isInSandbox": true,
"surface": {
"capabilities": [
{
"name": "actions.capability.SCREEN_OUTPUT"
},
{
"name": "actions.capability.WEB_BROWSER"
},
{
"name": "actions.capability.ACCOUNT_LINKING"
},
{
"name": "actions.capability.MEDIA_RESPONSE_AUDIO"
},
{
"name": "actions.capability.AUDIO_OUTPUT"
}
]
},
"requestType": "SIMULATOR",
"inputs": [
{
"rawInputs": [
{
"inputType": "KEYBOARD"
}
],
"arguments": [
{
"textValue": "true",
"name": "PERMISSION",
"boolValue": true
},
{
"name": "text"
}
],
"intent": "actions.intent.PERMISSION"
}
],
"user": {
"lastSeen": "2019-04-30T07:23:23Z",
"permissions": [
"UPDATE"
],
"locale": "tr-TR",
"userId": "ABwppHHCEdtf23ZaNg0DaCv3fvshSUXUvYGXHe6kR7jbKacwIS6vDBBL7YXbN70jYa8KaXWZqbsyhFFSdsYLiw"
},
"conversation": {
"conversationId": "ABwppHGD33Tyho41g9Mr2vzxePlskNmvOzCTxUiDGzENcl3C7RQs94aOQ8ae_DUlOApR0VBO9DuwAWdWr2frAA",
"type": "ACTIVE",
"conversationToken": "[\"_actions_on_google\"]"
},
"availableSurfaces": [
{
"capabilities": [
{
"name": "actions.capability.AUDIO_OUTPUT"
},
{
"name": "actions.capability.SCREEN_OUTPUT"
},
{
"name": "actions.capability.WEB_BROWSER"
}
]
}
]
}
},
"session": "projects/projectname-10c22/agent/sessions/ABwppHGD33Tyho41g9Mr2vzxePlskNmvOzCTxUiDGzENcl3C7RQs94aOQ8ae_DUlOApR0VBO9DuwAWdWr2frAA"
}
To send notification, I've been using userID instead of UPDATES_USER_ID and it is working. Yet, it will be deprecated soon. So, I need to find a solution to get this ID and couldn't make it working. What do I need to do to get this ID?
I've found solution for this problem. While getting UPDATES_USER_ID conv.arguments.get() only works for first attempt. So, while building your action you must save it. If you didn't store or save, you can reset your profile and try again, you will be able to get.
app.intent("FinishNotificationSetup", (conv, params) => {
if (conv.arguments.get('PERMISSION')) {
if(!conv.user.storage.GoogleUserID)
{
conv.user.storage.GoogleUserID = conv.arguments.get("UPDATES_USER_ID");
//For best case
//store ID in your db.
}
console.log(conv.user.storage.GoogleUserID);
conv.ask("some response....");
}
});
For best case, try saving this to your database because conv.user.storage does not work sometimes.
I want to do this without using any sort of plugin since these are both core wordpress features (custom fields and the REST API). Here is the documentation for custom fields for reference:
https://codex.wordpress.org/Using_Custom_Fields
Here is a screenshot from my wordpress installation:
Here is what the API response for a post looks like currently:
{
"_links": {
"about": [
{
"href": "http://example.com/wp-json/wp/v2/types/post"
}
],
"author": [
{
"embeddable": true,
"href": "http://example.com/wp-json/wp/v2/users/1"
}
],
"collection": [
{
"href": "http://example.com/wp-json/wp/v2/posts"
}
],
"curies": [
{
"href": "https://api.w.org/{rel}",
"name": "wp",
"templated": true
}
],
"replies": [
{
"embeddable": true,
"href": "http://example.com/wp-json/wp/v2/comments?post=21"
}
],
"self": [
{
"href": "http://example.com/wp-json/wp/v2/posts/21"
}
],
"version-history": [
{
"href": "http://example.com/wp-json/wp/v2/posts/21/revisions"
}
],
"wp:attachment": [
{
"href": "http://example.com/wp-json/wp/v2/media?parent=21"
}
],
"wp:featuredmedia": [
{
"embeddable": true,
"href": "http://example.com/wp-json/wp/v2/media/23"
}
],
"wp:term": [
{
"embeddable": true,
"href": "http://example.com/wp-json/wp/v2/categories?post=21",
"taxonomy": "category"
},
{
"embeddable": true,
"href": "http://example.com/wp-json/wp/v2/tags?post=21",
"taxonomy": "post_tag"
}
]
},
"author": 1,
"categories": [
5,
4
],
"comment_status": "open",
"content": {
"protected": false,
"rendered": ""
},
"date": "2017-05-14T15:25:33",
"date_gmt": "2017-05-14T15:25:33",
"excerpt": {
"protected": false,
"rendered": ""
},
"featured_media": 23,
"format": "standard",
"guid": {
"rendered": "http://example.com/?p=21"
},
"id": 21,
"link": "http://example.com/2017/05/14/post/",
"meta": [],
"modified": "2017-05-15T18:17:34",
"modified_gmt": "2017-05-15T18:17:34",
"ping_status": "open",
"slug": "",
"sticky": false,
"tags": [],
"template": "",
"title": {
"rendered": ""
},
"type": "post"
}
In case it could be relevant, here are my active plugins:
First you need to register_rest_fields to adding custom endpoints in WP REST API JSON Response
add_action( 'rest_api_init', 'add_custom_fields' );
function add_custom_fields() {
register_rest_field(
'post',
'custom_fields', //New Field Name in JSON RESPONSEs
array(
'get_callback' => 'get_custom_fields', // custom function name
'update_callback' => null,
'schema' => null,
)
);
}
Then define your functions to get custom fields
function get_custom_fields( $object, $field_name, $request ) {
//your code goes here
return $customfieldvalue;
}
Tested on local site
For those using Advanced Custom Fields: this is now offered out of the box as of v5.11 on a per-field group basis. Steps:
Edit the field group you want added to the REST API
Under Settings, click Show in REST API
For fine-grain control over what exactly the REST API shows and when, see Documentation > Guides > WP REST API Integration on the ACF website. This includes examples of how to include/exclude individual fields within a field group.
Use this plugin for this solution:
https://wordpress.org/plugins/acf-to-rest-api/ as it allows you to expose the Advanced Custom Fields into their own JSON response via new endpoints listed here https://github.com/airesvsg/acf-to-rest-api#endpoints. You can then forkJoin the two observables (if using Angular) and utilize the combined response toward your purpose.
Suppose we want to add 'sku' and 'price' meta to the 'product' postType
and the rest_api url is :
site_addresses.com/wp-json/wp/v2/product
Put this code in the functions.php
function af_create_custom_meta_in_REST()
{
$post_types = ["product"]; //post types that will include custom fields
foreach ($post_types as $post_type) {
register_rest_field(
$post_type,
'custom_fields',
[
'get_callback' => 'expose_custom_fields',
'schema' => null,
]
);
}
}
function expose_custom_fields($object)
{
$fields = ["_sku", "_price"]; //custom fields name
$post_ID = $object['id'];
$return_value = [];
foreach ($fields as $field) {
$field = strval($field);
$meta = get_post_meta($post_ID, $field);
if (count($meta) > 1)
$return_value[$field] = $meta;
else if ($meta[0])
$return_value[$field] = $meta[0];
else
$return_value[$field] = ""; //if you set this to null result will be 'null'
}
if ($return_value)
return $return_value;
return []; //if you set this to null result will be 'null'
}
add_action('rest_api_init', 'af_create_custom_meta_in_REST');
you can change $post_types or $fields to anything you want
Result image :
image of rest_api reslut
Just add it in your CMS and then it should be available inside your WP REST API.
I'm very newbie to ElasticSearch. This is how my data looks like.how can I map and query on the following data.
[parameters] => Array
(
[0] => Array
(
[param_id] => "Browser"
[param_values] => Array
(
[0] => "Firefox"
)
)
[1] => Array
(
[param_id] => "BrowserVersion"
[param_values] => Array
(
[0] => "39"
)
)
[2] => Array
(
[param_id] => "OS"
[param_values] => Array
(
[0] => "Windows"
)
)
[3] => Array
(
[param_id] => "Softwares"
[param_values] => Array
(
[0] => "Java"
[1] => "Oracle"
[2] => "PHP"
)
)
)
I have to get the results of the following query.
The Users which are using "OS" as "Windows" and "Softwares" as "Java". How to map these data and query?
Below is the Mapping JSON:
{
"response": {
"properties": {
"profile_id" : {"type" : "long"},
"timestamp" : {"type" : "string"},
"parameters" : {
"type": "nested",
"properties":{
"param_id":{"type": "string"},
"param_values": {
"type": "string"
}
}
}
}
}
}
Below is my Query JSON:
{ "query": {
"filtered": {
"query": {
"match_all": {}
},
"filter": {
"bool": {
"must": [
{
"nested": {
"path": "parameters",
"query": {
"bool": {
"must": [
{
"term": {
"parameters.param_id": "Softwares"
}
},
{
"term": {
"parameters.param_values": "Java"
}
}
]
}
}
}
}
]
}
}
} }}
So let's start off by creating the index using
curl -XPUT localhost:9200/responses -d '{
"mappings": {
"response": {
"properties": {
"profile_id": {
"type": "long"
},
"timestamp": {
"type": "string"
},
"parameters": {
"type": "nested",
"properties": {
"param_id": {
"type": "string"
},
"param_values": {
"type": "string"
}
}
}
}
}
}
}'
And then we index your sample document:
curl -XPUT localhost:9200/responses/response/1 -d '{
"profile_id": 1,
"timestamp": "2015-01-01T00:00:00",
"parameters": [
{
"param_id": "Browser",
"param_values": [
"Firefox"
]
},
{
"param_id": "BrowserVersion",
"param_values": [
"39"
]
},
{
"param_id": "OS",
"param_values": [
"Windows"
]
},
{
"param_id": "Softwares",
"param_values": [
"Java",
"Oracle",
"PHP"
]
}
]
}'
You've started off very well and your query is almost correct. If you want to query for users who are using "Windows" as "OS" and "Java" as "Softwares", you already have the constraint on the latter, now you just need one more contraint for the former (i.e. OS=Windows)
{
"size": 30,
"query": {
"filtered": {
"filter": {
"bool": {
"must": [
{
"nested": {
"path": "parameters",
"query": {
"bool": {
"must": [
{
"term": {
"parameters.param_id": "os"
}
},
{
"term": {
"parameters.param_values": "windows"
}
}
]
}
}
}
},
{
"nested": {
"path": "parameters",
"query": {
"bool": {
"must": [
{
"term": {
"parameters.param_id": "softwares"
}
},
{
"term": {
"parameters.param_values": "java"
}
}
]
}
}
}
}
]
}
}
}
}
}