I've got problem with Checkout Session method in Stripe API. When I hardcode values for price and quantity, Stripe will allow me to use multiple items in checkout, but when I try to load those values dynamically, it only lists first product in cart. Here is example of hardcoded values:
$product = \Stripe\Product::create([
'name' => "{$row['product_title']}",
'images' => [
"https://moto-d.net/wp-content/uploads/2018/01/webshop.jpg"
]
]);
$price_100 = $row['product_price'] * 100;
$price = \Stripe\Price::create([
'product' => "{$product['id']}",
'unit_amount' => "{$price_100}",
'currency' => 'eur'
]);
$session = \Stripe\Checkout\Session::create([
'payment_method_types' => ['card'],
'line_items' => [[
'price' => 'price_1H1qQRAvwpgnxaFsFErrYUQs',
'quantity' => 1
], [
'price' => 'price_1H1qQSAvwpgnxaFsXR3XO8Sg',
'quantity' => 1
], [
'price' => 'price_1H1qQTAvwpgnxaFsfAAn8FMI',
'quantity' => 1
], [
'price' => 'price_1H1qQUAvwpgnxaFsX9KRfDPE',
'quantity' => 1
]],
'mode' => 'payment',
'success_url' => "http://localhost/e-com-master/public/thank_you.php",
'cancel_url' => "http://localhost/e-com-master/public/index.php",
]);
}
}
}
return $session['id'];
With this code, it works perfectly. But, problems are here (I am using array for storing theese values):
$line_items_array = array(
"price" => $price['id'],
"quantity" => $value
);
$session = \Stripe\Checkout\Session::create([
'payment_method_types' => ['card'],
'line_items' => [$line_items_array],
'mode' => 'payment',
'success_url' => "http://localhost/e-com-master/public/thank_you.php",
'cancel_url' => "http://localhost/e-com-master/public/index.php",
]);
Could anyone notice mistake I am making? I suppose that I am not pushing values in array in appropriate way.
$line_items_array = array(
'price' => "{$price['id']}",
'quantity' => "{$value}"
);
and
'line_items' => [[$line_items_array]],
I just ran into this a few weeks ago. Stripe Support wasn't interested in helping.
Overview:
Construct the line_items you want via your frontend code.
i.e.: An array of objects with keys like: product, quantity, etc.
Pass that array of objects (via JSON.stringify()) to the backend PHP.
Loop through it in the PHP and push it into an array.
Pass that array in the line_items key of \Stripe\Checkout\Session::create().
It's pretty straight forward, but was tricky to get right because I wasn't used to PHP.
These were really helpful to me, as a PHP novice:
https://jonsuh.com/blog/convert-loop-through-json-php-javascript-arrays-objects/
https://www.geeksforgeeks.org/how-to-create-an-array-for-json-using-php/
I'm including everything for your create-checkout-session.php file. Not just the foreach().
<?php
/* Standard Stripe API stuff */
require 'vendor/autoload.php';
\Stripe\Stripe::setApiKey("STRIPE_LIVE_SECRET_KEY_HERE");
header('Content-Type: application/json');
$YOUR_DOMAIN = 'http://localhost:4242';
/* Read in the JSON sent via the frontend */
$json_str = file_get_contents('php://input');
/*
* Convert to PHP object
* - NOT setting `json_decode($json_str, TRUE)` because having the data decoded into an *object* seems to work well. Also, Stripe's own sample code, for custom flows, does not set to `TRUE`.
* - https://www.php.net/manual/en/function.json-decode.php
*/
$data = json_decode($json_str);
/* Create array to accept multiple `line_item` objects */
$lineItemsArray = [];
/*
* [OPTIONAL] Create array to combine multiple keys from each`line_item` into a single one for `payment_intent_data.description`
* - Only required if you want to pass along this type of description that's either provided by the user or by your frontend logic.
* - IOW: It was useful to me, but it might not be to you.
*/
$descriptionInternal = [];
/* Convert the incoming JSON key/values into a PHP array() that the Stripe API will accept below in `\Stripe\Checkout\Session::create()` */
foreach($data as $key => $value) {
/*
* Swap frontend `price` for backend Stripe `price id`
* - If you have Products/Prices that you created in the Stripe Dashboard, you might want to keep those Ids secret (although I don't know if that matters).
* - So you'll need to convert whatever you define them as on the frontend (public), to the Stripe PriceId equivalents (private).
* - This switch statement does that.
*/
switch ($value->price) {
case 50:
$value->price = "price_1Iaxxxxxxx";
break;
case 100:
$value->price = "price_1Ibxxxxxxx";
break;
case 150:
$value->price = "price_1Icxxxxxxx";
break;
default:
$value->price = "price_1Iaxxxxxxx";
}
/* `array_push` this object shape, for each `line_item` entry, into the array created outside of this `foreach()` loop. */
array_push($lineItemsArray,
[
"price" => $value->price,
"quantity" => $value->quantity,
"customerName" => $value->customer_name,
"recipientName" => $value->recipient_name,
"description" => $value->description /* Customer facing on the Stripe "Pay" page */
/*
* Add whatever else you want to include, with each `line_item`, here.
* - Stripe API allows:
* - https://stripe.com/docs/api/checkout/sessions/create#create_checkout_session-line_items
*/
]);
/*
* [OPTIONAL] `array_push` some or all of the `line_item` key values in a combined form.
* - Handy (in some cases) if you want to see a quick readout of the entire purchase in your Stripe Dashboard "Purchases" listing (i.e.: Saves you from having click into it to see the details).
* - Or you could construct this via your frontend code and pass it as a string.
* - But I'm including this here, in case you want to do it, or something like it, in in PHP.
* - Example final result: "[Axl: 3 Guns N' Roses for Duff] [Slash: 6 Guns N' Roses for Izzy]"
*/
array_push(
$descriptionInternal,
("[" . $value->customerName . ": " . $value->quantity . " Guns N' Roses for " . $value->recipientName) . "]");
}
/* [OPTIONAL] `payment_intent_data.description` takes a string, not an array. */
$descriptionInternal = implode(" ", $descriptionInternal);
/* https://stripe.com/docs/api/checkout/sessions/create */
$checkout_session = \Stripe\Checkout\Session::create([
'payment_method_types' => ['card'],
/* Takes in the array from above */
'line_items' => $lineItemsArray,
/* [OPTIONAL] Single `payment_intent_data.description` */
'payment_intent_data' => [
'description' => $descriptionInternal, /* This version of "Description" is displayed in the Dashboard and on Customer email receipts. */
],
'mode' => 'payment',
'success_url' => $YOUR_DOMAIN . '/success.html',
'cancel_url' => $YOUR_DOMAIN . '/cancel.html',
]);
echo json_encode(['id' => $checkout_session->id]);
Probably a bit late to reply now, but anyway after much testing and trial and error here is what worked for me.
I found that passing the array list was a major pain, so I had to reassemble the array once I recieved it from input as json, before passing it to Stripe Create, which even then, only seemed to work properly when I used eval on the array when passing it. Mainly posting this to help anyone avoid the pain I went through :), I am sure there are way better ways to do it, but I could find no examples anywhere at the time and this has been working fine now for almost a year so I haven't looked to improve or modify as yet.
<?php
header("Content-Type: application/json");
require_once('stripe/vendor/autoload.php');
// Set your secret key. Remember to switch to your live secret key in production!
// See your keys here: https://dashboard.stripe.com/account/apikeys
\Stripe\Stripe::setApiKey('whateveryouroneis');
// grab the json data from the cart, sent via php input
$data = (array) json_decode(file_get_contents("php://input"), TRUE);
//get the current webpage URL
$returnToPage = $_COOKIE["whateveryoursis"];
/**
* recursive read though what we recieved, try to get it to pass by rebuilding it
*/
function displayArrayRecursively($arr) {
if ($arr) {
foreach ($arr as $key => $value) {
if (is_array($value)) {
$arrs .= displayArrayRecursively($value);
} else {
// Output
if ( $key == 'name' ) {
$arrs .= " [ \"$key\" => '$value', \n";
}
elseif ( $key == 'quantity' ) {
$arrs .= " \"$key\" => $value , ], \n";
}
elseif ( in_array($key, ['description','currency'], true )) {
$arrs .= " \"$key\" => '$value', \n";
}
elseif ( $key == 'amount' ) {
$arrs .= " \"$key\" => " . $value * 100 . ", \n";
}
else {
$arrs .= " \"$key\" => ['$value'], \n";
}
}
}
}
return $arrs;
}
$line_items_str = displayArrayRecursively($data);
$createSession_str = (
"'payment_method_types' => ['card']," .
"'success_url' => '" . $returnToPage . "?success=1'," .
"'cancel_url' => '" . $returnToPage . "'," .
"'shipping_address_collection' => [" .
"'allowed_countries' => ['GB'], ]," .
"'line_items' => [" . $line_items_str . " ], ");
// create the checkout session on Stripe
eval ( $session = "\$session = \Stripe\Checkout\Session::create( [ " .
$createSession_str . " ] );" );
$stripeSession = array($session);
// test while working on it :-
// var_dump($stripeSession);
$sessId = ($stripeSession[0]['id']);
echo $sessId;
Edited: I did some tests using the Stripe PHP library and their example code. I think your error is that you left the brackets in:
'line_items' => [$line_items_array],
It should look like this instead.
'line_items' => $line_items_array,
The readymade array for the line_items parameter should be a numeric index, with a nested multidimensional associative array.
//Here is a functional example that returns a successful checkout session:
<pre>
<?php
$currency = 'eur';
$products = array (
array (
'unit_amount' => 1000,
'name' => 'product 1',
'images' => 'https://i.imgur.com/EHyR2nP.png',
'quantity' => '1'
),
array (
'unit_amount' => 2000,
'name' => 'product 2',
'images' => 'https://i.imgur.com/EHyR2nP.png',
'quantity' => '2'
),
);
foreach ($products as $product) {
$line_items_array[] = array(
'price_data' => array(
'currency' => $currency,
'unit_amount' => $product['unit_amount'],
'product_data' => array(
'name' => $product['name'],
'images' => array($product['images']),
),
),
'quantity' => $product['quantity'],
);
}
print_r ($line_items_array);
?>
</pre>
//the output
Array
(
[0] => Array
(
[price_data] => Array
(
[currency] => eur
[unit_amount] => 1000
[product_data] => Array
(
[name] => product 1
[images] => Array
(
[0] => https://i.imgur.com/EHyR2nP.png
)
)
)
[quantity] => 1
)
[1] => Array
(
[price_data] => Array
(
[currency] => eur
[unit_amount] => 2000
[product_data] => Array
(
[name] => product 2
[images] => Array
(
[0] => https://i.imgur.com/EHyR2nP.png
)
)
)
[quantity] => 2
)
)
Related
I need your help, I tried all the mentioned suggestions (https://github.com/amzn/selling-partner-api-docs/issues/2167) but am still not able to update the inventory quantity with Amazon SP API.
I am trying to update the quantity stock without Feeds.
Below body, I am sending to update the quantity with Put Request.
The package I am using is: https://github.com/jlevers/selling-partner-api
SellingPartnerApi\Model\ListingsV20210801\ListingsItemPutRequest Object
(
[container:protected] => Array
(
[product_type] => FALSE_EYELASH
[requirements] =>
[attributes] => Array
(
[fulfillment_availability] => Array
(
[fulfillment_channel_code] => AMAZON_JP
[quantity] => 5
)
)
)
)
When I use sandbox get a response ACCEPTED but without getting an error.
........
[sku] => 2629-48KGT-2347 // TEST
[status] => INVALID
[submission_id] => 602b84b73b964e24b174a80d3a7870a3
[issues] => Array
(
[0] => SellingPartnerApi\Model\ListingsV20210801\Issue Object
(
[container:protected] => Array
(
[code] => 4000003
[message] => ������������Amazon������������������������������������������������������������������������������
[severity] => ERROR
[attribute_names] =>
)
)
)
........
=======================
To patch the request I am trying the below body.
SellingPartnerApi\Model\ListingsV20210801\ListingsItemPatchRequest Object
(
[container:protected] => Array
(
[product_type] => FALSE_EYELASH
[patches] => Array
(
[op] => replace
[operation_type] => UPDATE // Already try with or without this parameter
[path] => /attributes/fulfillment_availability
[value] => Array
(
[fulfillment_channel_code] => AMAZON_JP
[quantity] => 5
)
)
)
)
Get the below response.
Exception when calling: [400] {
"errors": [
{
"code": "InvalidInput",
"message": "Request has missing or invalid parameters and cannot be parsed.",
"details": ""
}
]
}
Is there any way to update the order status to shipped without the feeds API?
The code which I try so far is below.
$patchBody = [
'product_type' => 'BEAUTY',
'marketplaceIds' => ['A1VC38T7YXB528'], // Already try with or without
'patches' => [
[
"op" => "replace",
"operation_type" => "PARTIAL_UPDATE",
"path" => "/attributes/fulfillment_availability",
"value" => [
[
"fulfillment_channel_code" => 'DEFAULT',
"quantity" => 2
]
]
]
]
];
$putBody = [
'product_type' => 'BEAUTY',
'attributes' => [
"fulfillment_availability" => [
"fulfillment_channel_code" => "DEFAULT",
"quantity" => 2
]
]
];
$seller_id = 'MY-SELLER-ID';
$sku = '8001025974';
$marketplace_ids = array('A1VC38T7YXB528');
// Update inventory
$apiInstance = new SellingPartnerApi\Api\ListingsV20210801Api($config);
$body = new \SellingPartnerApi\Model\ListingsV20210801\ListingsItemPatchRequest($patchBody);
// $issue_locale = 'en_US';
try {
$result = $apiInstance->patchListingsItem($seller_id, $sku, $marketplace_ids, $body);
print_r($result);
} catch (Exception $e) {
echo 'Exception when calling: ', $e->getMessage(), PHP_EOL;
}
I found the solution the main issue is in the body there are many different methods which are provided by amazon feed base or listing put/patch base.
In my question, I was using the Listing base approach.
The endpoint URL is below.
{{fe_url}}/listings/2021-08-01/items/{{seller_id}}/8001025974?marketplaceIds={{jp_market_id}}
The body should be like the below. If there is an error in product type even if you pass the current product type just use "PRODUCT" instead.
Note: But if you are using a feed document then it might be changed see here
I got success with the below body.
{
"productType": "PRODUCT",
"patches": [
{
"op": "replace",
"operation_type": "PARTIAL_UPDATE",
"path": "/attributes/fulfillment_availability",
"value": [
{
"fulfillment_channel_code": "DEFAULT",
"quantity": 0
}
]
}
]
}
I have the following array to show menu's based on the order the user specified.
The array is as follows:
$menuArray = [
'Main Street' => [
['/index.php', 'Home'],
['/city.php', $cityData[$user->city][0]],
['/travel.php', 'Travel'],
['/bank.php', 'Bank'],
['/inventory.php', 'Inventory'],
['/dailies.php', 'Dailies'],
],
'Activities' => [
(!$my->hospital) ? ['/hospital.php', 'Hospital'] : [],
(!$my->hospital && !$my->prison) ? ['/crime.php', 'Crime'] : [],
['/missions.php', 'Missions'],
['/achievements.php', 'Achievements'],
],
'Services' => [
['/hospital.php', 'Hospital'],
['/prison.php', 'Prison'],
['/search.php', 'Search'],
],
'Account' => [
['/edit_account.php', 'Edit Account'],
['/notepad.php', 'Notepad'],
['/logout.php', 'Logout'],
]
];
I have a column menu_order stored in the database, which has a default value of 0,1,2,3,4, but this can change per user as they will be able to change their menu to their likes.
What I'd like to achieve:
0 => Main Street
1 => Activities
2 => Services
3 => Account
4 => Communication
To get the menu order, I do
$menuOrder = explode(',', $user->menu_order);
But I'm not sure how to handle the foreach for displaying the menu.
Here's one way to do it -- use replacement rather than a sorting algorithm.
Code: (Demo)
$menuArray = [
'Main Street' => [],
'Activities' => [],
'Services' => [],
'Account' => []
];
$lookup = [
0 => 'Main Street',
1 => 'Activities',
2 => 'Services',
3 => 'Account',
4 => 'Communication'
];
$customsort = '4,2,1,3,0';
$keys = array_flip(explode(',', $customsort)); convert string to keyed array
//var_export($keys);
$ordered_keys = array_flip(array_replace($keys, $lookup)); // apply $lookup values to keys, then invert key-value relationship
//var_export($ordered_keys);
$filtered_keys = array_intersect_key($ordered_keys, $menuArray); // remove items not on the current menu ('Communication" in this case)
//var_export($filtered_keys);
$final = array_replace($filtered_keys, $menuArray); // apply menu data to ordered&filtered keys
var_export($final);
Output:
array (
'Services' =>
array (
),
'Activities' =>
array (
),
'Account' =>
array (
),
'Main Street' =>
array (
),
)
And here's another way using uksort() and a spaceship operator:
$ordered_keys = array_flip(array_values(array_replace(array_flip(explode(',', $customsort)), $lookup)));
uksort($menuArray, function($a, $b) use ($ordered_keys) {
return $ordered_keys[$a] <=> $ordered_keys[$b];
});
var_export($menuArray);
As a consequence of how your are storing your custom sort order, most of the code involved is merely to set up the "map"/"lookup" data.
You could try something like this to produce the menu:
function display_menu($menus, $m) {
if (!isset($menus[$m])) return;
echo "<ul>";
foreach ($menus[$m] as $item) {
if (!count($item)) continue;
echo "<li>{$item[1]}\n";
}
echo "</ul>";
}
$menuMap = array(0 => 'Main Street',
1 => 'Activities',
2 => 'Services',
3 => 'Account',
4 => 'Communication');
$menuOrder = explode(',', $user->menu_order);
foreach ($menuOrder as $menuIndex) {
$thisMenu = $menuMap[$menuIndex];
display_menu($menuArray, $thisMenu);
}
Small demo on 3v4l.org
I am trying to get away from doing things manually and repetitively by correctly utilizing loops and functions (methods) in oop programming; but I have hit a major stumbling block as it regards to multidimensional array groups, in passing the correct values to the necessary abstracted function (method) responsible for a database action.
Any help at all is very much welcomed and will enable me to move on from this stumbling block that I have been trying to push away for days upon days but without progress and it is out of true frustration and much agony that I am here begging for help.
Below is the code that for simplicity I have shortened as much as possible (can be easily tested locally by copying and pasting):
// array with table properties and form values - start
$form_fields_arr = [
'group' => [
'anime' => [ // genre
'table_prop' => [ // for update query - table properties
'table_name' => 'anime_tbl',
'account_id' => 2,
'visible' => 'yes'
],
'form_data' => [ // for update query - form values
'2' => 'Attack on Titan',
'4' => 'RWBY',
'6' => 'Rurouni Kenshin',
'8' => 'A Silent Voice'
]
],
'movie' => [ // genre
'table_prop' => [ // for update query - table properties
'table_name' => 'movie_tbl',
'account_id' => 4,
'visible' => 'yes'
],
'form_data' => [ // for update query - form values
'1' => 'Queen of Katwe',
'3' => 'Forest Gump',
'5' => 'War Horse',
'7' => 'The Fault in our Stars'
]
]
]
]; // ... end
// loop through multidimensional array and pass values to function - start
foreach ($form_fields_arr['group'] as $frm_key_1 => $frm_val_1) { // 2d array
foreach ($frm_val_1 as $frm_key_2 => $frm_val_2) { // 1d array
if (strcasecmp($frm_key_1, $frm_key_1) === 0) { // group by genre
foreach ($frm_val_2 as $frm_key_3 => $frm_val_3) { // 1d array
if (strcasecmp($frm_key_2, 'form_data') === 0) {
$title = $form_fields_arr['group'][$frm_key_1]['form_data'][$frm_key_3]; // anime/movie title
}
if (isset($frm_val_2['table_name']) &&
isset($frm_val_2['account_id']) &&
isset($frm_val_2['visible']) &&
isset($title)
) {
dbUpdate(
$frm_val_2['table_name'],
$frm_val_2['account_id'],
$frm_val_2['visible'],
$title
);
}
} // 1d array
} // if block
} // 1d array
} // 2d array
// ... end
// function that receives passed values - start
function dbUpdate($table_name, $account_id, $title_col, $form_value) {
$test_val_arr = [$table_name, $account_id, $title_col, $form_value];
return print_r($test_val_arr);
} // ... end
The above code outputs:
// array values passed to and returned from function
Array (
[0] = movie_tbl
[1] = 4
[2] = yes
[3] = A Silent Voice
)
Array (
[0] = movie_tbl
[1] = 4
[2] = yes
[3] = A Silent Voice
)
Array (
[0] = movie_tbl
[1] = 4
[2] = yes
[3] = A Silent Voice
)
Array (
[0] = movie_tbl
[1] = 4
[2] = yes
[3] = A Silent Voice
)
But the desired result that I am trying to achieve is:
// for anime genre - array values passed to and returned from function
Array (
[0] = anime_tbl
[1] = 2
[2] = yes
[3] = Attack on Titan
)
Array (
[0] = anime_tbl
[1] = 2
[2] = yes
[3] = RWBY
)
Array (
[0] = anime_tbl
[1] = 2
[2] = yes
[3] = Rurouni Kenshin
)
Array (
[0] = anime_tbl
[1] = 2
[2] = yes
[3] = A Silent Voice
)
// for movie genre - array values passed to and returned from function
Array (
[0] = movies_tbl
[1] = 4
[2] = yes
[3] = Queen of Katwe
)
Array (
[0] = movies_tbl
[1] = 4
[2] = yes
[3] = Forest Gump
)
Array (
[0] = movies_tbl
[1] = 4
[2] = yes
[3] = War Horse
)
Array (
[0] = movies_tbl
[1] = 4
[2] = yes
[3] = The Fault in our Stars
)
so upon everything royally failing with me spending literally about a week trying to fix this, telling myself that it is very simple and I really shouldn't be stuck here, out of desperation I decided to go back to my repetitive ways and tried the following:
// new array without table properties - start
$new_array = [];
$new_array['group']['anime'] = $form_fields_arr['group']['anime']['form_data'];
$new_array['group']['movie'] = $form_fields_arr['group']['movie']['form_data']; // ... end
// loop through multidimensional array and pass values to function - start
foreach ($new_array['group'] as $key_1 => $val_1) { // 2d array
foreach ($val_1 as $key_2 => $val_2) { // 1d array
if (strcasecmp($key_1, $key_1) === 0) {
dbUpdate('anime_tbl', 2, 'yes', $val_2);
dbUpdate('movie_tbl', 4, 'yes', $val_2);
} // if block
} // 1d array
} // 2d array
// ... end
But the results are still very much undesirable. Everything was working fine until I started using multidimensional arrays, simply because I realized that utilizing multidimensional arrays help me to shorten my code in other areas considerably. But I am stuck here and will have to go back further up and undo quite a lot of changes if I can't get this to work. I am pleading for help from any good soul out there. Please help me someone! Anyone!
I am being optimistic here and assuming that if by any chance I do get some help in fixing the above problem, could someone please also teach me how to loop through an array structure like the one below while yet getting the desired results without duplicates (I have truly tried but have truly failed):
// array with table properties and form values - start
$form_fields_arr = [
'table_prop' => [ // table properties group
'anime' => [ // for update query - table properties
'table_name' => 'anime_tbl',
'account_id' => 2,
'visible' => 'yes'
],
'movie' => [ // for update query - table properties
'table_name' => 'movie_tbl',
'account_id' => 4,
'visible' => 'yes'
]
],
'form_data' => [ // for update query - form values
'anime' => [ // genre
'2' => 'Attack on Titan',
'4' => 'RWBY',
'6' => 'Rurouni Kenshin',
'8' => 'A Silent Voice'
],
'movie' => [ // genre
'1' => 'Queen of Katwe',
'3' => 'Forest Gump',
'5' => 'War Horse',
'7' => 'The Fault in our Stars'
]
]
]; // ... end
You got a logic mistake in your for loops. First of all your variable namings are not very intuitive. $frm_key_1, $frm_key_2, etc. look alike and force the reader to have the array structure in mind all the time to understand the variables meaning. This led to a mistake like this one: if( strcasecmp($frm_key_1, $frm_key_1) === 0 ). This is always true.
Then you had two exclusive conditions:
if (strcasecmp($frm_key_2, 'form_data') === 0)
And:
if (isset($frm_val_2['table_name']) && /* ... */) {
If $frm_key_2 is 'form_data' you are in the second child of the genre array, yet the fields 'table_name', etc. are defined only in the first one (witht the key 'table_prop'). So both conditions can never be true at the same time.
Your condition to trigger the dbUpdate() function was, that all fields of the 'table_prop' array were present (which you iterated through at the same time), and a $title was set aswell. This was only true after your third for-loop iterated for the second time. During that iterations the $title variable got overwritten constantly, but no sbUpdate() was triggered, because $frm_val_2 had the values from 'form_data' instead of 'table_prop'. So after the 3rd for loop finished the 2nd time $title was 'A Silent Voice', which is simply the last child of the first 'form_data' array. Afterwards your 2nd for loop iterated the 2nd 'table_prop' array again, which means that now the 'dbUpdate()' condition was true, so it postet 4 times (number of childs in the 'table_prop' array) the parameters with $title = 'A Silent Voice'.
You tried to make everything as generic as possible, making everything over complicated. The best solution that works here is one that respects the specific structure.
This works:
<?php
// array with table properties and form values - start
$form_fields_arr = [
'group' => [
'anime' => [ // genre
'table_prop' => [ // for update query - table properties
'table_name' => 'anime_tbl',
'account_id' => 2,
'visible' => 'yes'
],
'form_data' => [ // for update query - form values
'2' => 'Attack on Titan',
'4' => 'RWBY',
'6' => 'Rurouni Kenshin',
'8' => 'A Silent Voice'
]
],
'movie' => [ // genre
'table_prop' => [ // for update query - table properties
'table_name' => 'movie_tbl',
'account_id' => 4,
'visible' => 'yes'
],
'form_data' => [ // for update query - form values
'1' => 'Queen of Katwe',
'3' => 'Forest Gump',
'5' => 'War Horse',
'7' => 'The Fault in our Stars'
]
]
]
];
// loop through multidimensional array and pass values to function - start
foreach ($form_fields_arr['group'] as $genreData) {
$tableProperties = $genreData['table_prop'];
if (!isset($tableProperties['table_name'])
|| !isset($tableProperties['account_id'])
|| !isset($tableProperties['visible'])) {
continue;
}
$data = $genreData['form_data'];
foreach ($data as $title) {
dbUpdate(
$tableProperties['table_name'],
$tableProperties['account_id'],
$tableProperties['visible'],
$title
);
}
}
// function that receives passed values - start
function dbUpdate($table_name, $account_id, $title_col, $form_value) {
$test_val_arr = [$table_name, $account_id, $title_col, $form_value];
return print_r($test_val_arr);
} // ... end
For the last part of the question that wasn't answered, thanks to Philipp Maurer's answer, after playing around with the code I got it to work. I am just placing the answer here for anyone who might have a similar problem and would like to better understand how to group and fetch values from a multidimensional array using a foreach loop without duplicates or incorrect results. See below code:
// array with table properties and form values - start
$form_fields_arr = [
'table_prop' => [ // table properties group
'anime' => [ // for update query - table properties
'table_name' => 'anime_tbl',
'account_id' => 2,
'visible' => 'yes'
],
'movie' => [ // for update query - table properties
'table_name' => 'movie_tbl',
'account_id' => 4,
'visible' => 'yes'
]
],
'form_data' => [ // for update query - form values
'anime' => [ // genre
'2' => 'Attack on Titan',
'4' => 'RWBY',
'6' => 'Rurouni Kenshin',
'8' => 'A Silent Voice'
],
'movie' => [ // genre
'1' => 'Queen of Katwe',
'3' => 'Forest Gump',
'5' => 'War Horse',
'7' => 'The Fault in our Stars'
]
]
]; // ... end
// loop through multidimensional array and pass values to function - start
foreach ($form_fields_arr as $index => $group_array) {
foreach ($group_array as $genre_key => $genre_val) {
if (!isset($group_array[$genre_key]['table_name']) ||
!isset($group_array[$genre_key]['account_id']) ||
!isset($group_array[$genre_key]['visible'])
) {
continue;
}
foreach ($form_fields_arr['form_data'][$genre_key] as $data_key => $data_title) {
dbUpdate(
$group_array[$genre_key]['table_name'],
$group_array[$genre_key]['account_id'],
$group_array[$genre_key]['visible'],
$data_title
);
}
}
}
// ... end
// function that receives passed values - start
function dbUpdate($table_name, $account_id, $title_col, $form_value) {
$test_val_arr = [$table_name, $account_id, $title_col, $form_value];
return print_r($test_val_arr);
} // ... end
I have created a E-commerce site by using Drupal commerce which is a clone of a shopping site created by Ektron. Now my client requirement is that if he insert a product in that site(which is created in Ektron) it will also incorporated in my site when we run import.
So I need to know how drupal_commerce insert their product details in the table.Any help regarding this wold be appreciable . If anyone need any further clarification please let me know .
Also I have some entity fields as well . Like author name , least price etc how to insert those values as well
Thanks in advance
Try this one ..
$values = array (
'price' => 9271.00 ,
'currency_code' => 'USD' ,
);
$cp = commerce_product_new('product');
$cp->is_new = TRUE;
$cp->revision_id = NULL;
$cp->uid = 1;
$cp->status = 1;
$cp->created = $cp->changed = time();
$cp->sku = '#12sku';
$cp->title = 'New Title';
$cp->language = 'und';
$cp->commerce_price = array ( LANGUAGE_NONE => array ( 0 => array (
'amount' => $values[ 'price' ] ,
'currency_code' => $values[ 'currency_code' ],
) ) );
$cp->field_list_price = array ( LANGUAGE_NONE => array ( 0 => array (
'amount' => '300.00' ,
'currency_code' => $values[ 'currency_code' ],
) ) );
$cp->field_isbn = array ( LANGUAGE_NONE => array ( 0 => array (
'value' => '#isbnn' ,
) ) );
$result = $proxy->salesOrderInvoiceCreate((object)array('sessionId' => $sessionId->result, 'itemsQty' => array('order_item_id' => 15, 'qty' => '1')));
$mainarray[];
$itemarray[];
I need multiple of this
array('order_item_id' => 15, 'qty' => '1')
Which means i need a array in a array.
foreach(statement){
array_push($itemarray, "order_item_id", echo $item->product_id;);
array_push($itemarray, "qty", echo $item->qty);
array_push($mainarray, $itemarray);
}
enter code here
Request Example SOAP V2 (WS-I Compliance Mode)
http://www.magentocommerce.com/api/soap/sales/salesOrderInvoice/sales_order_invoice.create.html
In fact i'm also not sure what do i replace the current
array('order_item_id' => 15, 'qty' => '1')
with
array($mainarray) ??
That is not the correct way of using array_push your current $itemarray output will look something like
Array
(
[0] => 'order_item_id'
[1] => '200'
[2] => 'qty'
[3] => '2'
)
I would go back to basics and use something like to generate your multi dimensional array:
$itemarray[] = array("order_item_id" => $item->product_id, "qty" => $item->qty);
array_push($mainarray, $itemarray);
Edit:
Ok I reread your questions, ignore $mainArray.
$result = $proxy->salesOrderInvoiceCreate((object)array('sessionId' => $sessionId->result, 'itemsQty' => $itemarray));
That should work as with the other examples qty/itemsQty show it accepting multikey arrays.