I'm making a shopping cart in MongoDB and I want to update the quantity field if the user adds a product that's already added.
This is my document:
{
"_id" : "mzipdNS2Xyw-IqV085KrBe5RZucp9M_KqDSYjPinq20",
"products" : [
{
"productId" : "27122",
"quantity" : NumberLong(1),
"displayPrice" : "€ 599.00",
"price" : NumberLong(599),
"name" : "APPLE IPHONE 5S 16GB SPACE GRAY"
}
]
}
I'm running the following code to update my document, but it's not working, can anyone assist me?
$collection->update(array("_id" => $userId, array("products" => array("productId" => $productId))),
array('$set' => array("quantity" => $newQuantity
))
);
In order to update the correct item in the products array you'll have to use the positional $ operator.
$collection->update(
array(
"_id" => $userId,
"products.productId" => $productId,
),
array('$set' => array("products.$.quantity" => $newQuantity))
);
Related
I have this code and it creates a product but no price and image. I tried to replace each on array with default value but still it does not add image and price. What is wrong with this code/array? Thanks!
$products_array = array(
"product"=>array(
"title"=> "title",
"body_html"=> "description",
"vendor"=> "vendor",
"product_type"=> "type",
"published"=> false ,
"variants" => array
(
array
(
"price" => 15.00,
)
),
"images" => array(
array(
"src" => "https://example.com/wp-content/uploads/2019/06/PIC2-3.jpg",
)
)
)
);
according to doc It should be array of object
"variants" => [
{
"price" => 15.00,
}
],
"images": [
{
"src": "http://example.com/rails_logo.gif"
}
]
SquareConnect API newbie here.
I am attempting to add an item to Square using the PHP method:
$api_instance = new SquareConnect\Api\V1ItemsApi();
$body = new \SquareConnect\Model\V1Item($request_body);
$result = $api_instance->createItem($location_id, $body);
My request_body definition:
$request_body = array(
"name" => "**ITEM NAME**",
"description" => "**ITEM DESCRIPTION**",
"category" => array(
"id" => "**CATEGORY ID**",
"name" => "**CATEGORY NAME**"
),
"variations" => array(
array(
"name" => "**VARIATION NAME**",
"sku" => "**SKU**",
"pricing_type" => "FIXED_PRICING",
"price_money" => array(
"currency_code" => "USD",
"amount" => "**AMOUNT**"
)
)
),
"fees" => array(
"enabled" => "1",
"name" => "Sales Tax",
"rate" => "0.0775",
"calculation_phase" => "FEE_SUBTOTAL_PHASE",
"adjustment_type" => "TAX",
"inclusion_type" => "ADDITIVE",
"type" => "US_SALES_TAX"
)
);
The item and variation data are being added to Square, but the "category" and "fees" definitions are not being included. As a result the item is ending up in flat space, which requires me to log into the main Square interface, add the item to the appropriate category AND set its tax information. I do not want to have to take these additional steps if they can be avoided.
The tax information in the "fees" section is taken verbatim from the definitions found in items added via the Square interface. I have confirmed and re-confirmed that the category id and category name match those of the desired category. I also tried replacing the "category" array with a simple "category_id" => "CATEGORY ID" definition. Same result.
Can anyone assist? Also, if there is a better method for adding an item to Square via the API, please let me know!
Thank you in advance.
Part one, categories
If you look at the docs about specifying a item category during item creation:
You are specifing an array:
"category" => array(
"id" => "**CATEGORY ID**",
"name" => "**CATEGORY NAME**"
),
you should instead be using a string:
"category" => "**CATEGORY ID**",
Part two, fees
If you look again at the docs, you won't see any reference to fees in V1 items create. That is because you cannot create a fee with that endpoint. Instead you should create a new fee. You can see some sample code here: https://github.com/square/connect-php-sdk/blob/master/docs/Api/V1ItemsApi.md#createfee
I'm going to focus on the category_id since you seemed to have figured out the "fees" issue based on the comments.
I just used this as test code, and the category was set successfully:
$items_api = new \SquareConnect\Api\V1ItemsApi();
$body = array(
"name" => "Test Item",
"category_id" => "YFIHMKYXNFJ7TE5FRBWQAGU6",
"variations" => array(
array(
"name" => "Small",
"pricing_type" => "FIXED_PRICING",
"price_money" => array(
"amount" => 100,
"currency_code" => "USD"
)
))
);
$result = $items_api->createItem($location_id, $body);
echo $result;
Location_id was created earlier, but everything else is there.
I have "_id" and "ProductLot". How can I Update Qty "0" to "1 " in the Lot array if ProductLot if present or append a new Lot element if it is not present?
"_id" : ObjectId("5462e44c599e5c6c1300000a"),
"LocationName" : "Putaway",
"Owner" : "",
"Status" : "1",
"Scrap" : "0",
"Lot" : [{
"Qty" :"6",
"ProductLot" : ObjectId("5462dbd9599e5c200e000000"),
"Product" : ObjectId("543ca7be4cf59d400c000004"),
"Movement" :[ {"OriginId" : "266",Qty:2,Type:"DN"},
{"OriginId" : "267" , Qty:1 , Type:"DN"},
{"OriginId" : "2" , Qty:3 , Type:"IM"},
]
},
{
"Qty" :"0",
"ProductLot" : ObjectId("5462dbd9599e5c200e000003"),
"Product" : ObjectId("543ca7be4cf59d400c000004"),
"Movement" :[ {"OriginId" : "266",Qty:2,Type:"DN"},
{"OriginId" : "267" , Qty:1 , Type:"DN"},
{"OriginId" : "2" , Qty:-3 , Type:"IM"},
]
}]
}
EG: I have "ProductLot" : ObjectId("5462dbd9599e5c200e000000") present in array so it should update qty 0 to 1; however, "ProductLot" : ObjectId("5462dbd9599e5c200e00000a") is not available in array so that should append a new element to the array.
PHP code, which is not updating creating appending array at every time:
$inventoryId = new \MongoId($_POST["inventoryid"]);
$productLotId = new \MongoId($invlotid);
$originId = $_POST['id'];
//$lotcontent = [ /* whatever this looks like */ ];
$lotcontent = array(
'Qty' => $invqty,
'ProductLot' => new \MongoId($invlotid),
'Product'=>$invproduct,
'Movement'=> array(
array(
'OriginId' => $_POST['id'],
'Qty' => $invqty,
'Type'=> 'DN',
), )
);
$invcolname = 'Inventory';
$result = $mongo->$dbname->$invcolname->update(
// Match an inventory without the specific ProductLot/OriginId element
array(
'_id' => $inventoryId,
'Lot' => array(
'$not' => array(
'$elemMatch' => array(
'ProductLot' => $productLotId,
//'OriginId' => $originId,
),
),
),
),
// Append a new element to the Lot array field
array('$push' => array( 'Lot' => $lotcontent ))
);
$movementcontent = array(
'OriginId' => $_POST['id'],
'Qty' => $invqty,
'Type'=> 'DN',
);
$result = $mongo->$dbname->$invcolname->update(
// Match an inventory without the specific ProductLot/OriginId element
array(
'_id' => $inventoryId,
'Lot' => array(
//'$not' => array(
'$elemMatch' => array(
'ProductLot' => $productLotId,
'Movement'=>array(
'$not' => array(
'$elemMatch' => array(
'OriginId' => $originId,
)
)
)
),
// ),
),
),
// Append a new element to the Lot.Movement array field
array('$push' => array( 'Lot.$.Movement' => $movementcontent ))
);
$result = $mongo->$dbname->$invcolname->update(
// Match an inventory with a specific ProductLot/OriginId element
array(
'_id' => $inventoryId,
'Lot' => array(
'$elemMatch' => array(
'ProductLot' => $productLotId,
//'OriginId' => $originId,
'Movement'=>array(
'$elemMatch' => array(
'OriginId' => $originId,
)
)
),
),
),
// Update the "Qty" field of the first array element matched (if any)
//array( '$set' => array( 'Lot.$.Qty' => 'Updated' )),
array( '$set' => array( 'Lot.$.Movement.$.Qty' => $invqty )),
array('upsert' => true));
Please anyone help me to resolve this?
Using $addToSet is problematic in this case, because the following lot elements would be considered different:
{
"Qty" :0,
"ProductLot" : ObjectId("5462dbd9599e5c200e000003"),
"Product" : ObjectId("543ca7be4cf59d400c000004"),
"OriginId" : "266"
}
{
"Qty" :5,
"ProductLot" : ObjectId("5462dbd9599e5c200e000003"),
"Product" : ObjectId("543ca7be4cf59d400c000004"),
"OriginId" : "266"
}
The first element is likely what you would be adding (either with quantity 0 or 1), and the second element would be the same logical lot element, just with an incremented quantity. If the latter element already existed in the array, I imagine you'd like for your application to increment the quantity from 5 to 6 instead of adding the first element, which is essentially a duplicate.
We definitely need two updates here, but I would propose the following:
// Let's assume the following identifiers...
$inventoryId = new MongoId($_POST['inventoryid']);
$productLotId = new MongoId($invlotid);
$originId = new MongoId($_POST['id']);
$lotcontent = [ /* whatever this looks like */ ];
$result = $collection->update(
// Match an inventory without the specific ProductLot/OriginId element
[
'_id' => $inventoryId,
'Lot' => [
'$not' => [
'$elemMatch' => [
'ProductLot' => $productLotId,
'OriginId' => $originId,
],
],
],
],
// Append a new element to the Lot array field
[ '$push' => [ 'Lot' => $lotcontent ] ]
);
MongoCollection::update() will return a result document with an n field indicating the number of affected documents. Since we aren't using the multiple option and are also matching at most one document by _id, we can expect n to be either 0 or 1. If n was 0, we either couldn't find an inventory document with that _id or we found one but it already had a Lot element with the product and origin identifiers (i.e. our $elemMatch criteria matched something, invalidating our negation). If n was 1, that means we found the inventory document, it did not contain a matching Lot element, and we appended it (i.e. our job is done).
Assuming n was 0, we should issue another update and attempt to increment the quantity:
$result = $collection->update(
// Match an inventory with a specific ProductLot/OriginId element
[
'_id' => $inventoryId,
'Lot' => [
'$elemMatch' => [
'ProductLot' => $productLotId,
'OriginId' => $originId,
],
],
],
// Update the "Qty" field of the first array element matched (if any)
[ '$inc' => [ 'Lot.$.Qty' => 1 ] ]
);
Here, I'm using the $ positional update operator to access a specific array element that was matched in the criteria. This allows us to craft an $inc without worrying about the index of the matched element.
Again, we can check $result['n'] here. If it's still 0, then we can assume that no document matches our _id (a completely separate error). But if n is 1 at this point, we successfully incremented the quantity and our job is done.
So I am trying to make a JSON object that should hold some information about some questions for me. This is a pseudo-code of how I want it to be presented:
{
"page" : 1,
"info" :
{
"id" : 1,
"type" : 3,
"description": "How to do JSON?",
"alternatives" :
{
"id" : 1,
"description" : "Dunno"
}
{
"id" : 2,
"description" : "Let me show you"
}
{
"id" : 3,
"description" : "I refuse to show you"
}
}
"id" : 2,
"type" : 1,
"description": "Do you get it?",
"alternatives" :
{
"id" : 1,
"description" : "Yes"
}
{
"id" : 2,
"description" : "No"
}
}
}
So the code underneath is from Nightmare (one of the answers), and it does exactly what I want to do with the page and the questions, but I can't seem to figure out how to connect alternatives to each question. You can see a snippet at the bottom where I have tried but it's not correctly spelled and I've been hammering at this for a while now.
$before_json_encode[$row['page']][] = array(
'id' => $row['id'],
'type' => $row['type'],
'description' => $row['description'],
'alternatives' => $alternativesarray//im not sure about here,dont know the structure of the alternative array
);
Another illustration on how I want the hierarchy of the JSON data to appear. I need to be able to pick for instance: All alternatives to all questions on a specific page. So if I want to generate page 3 in my poll I can first find the questions within the page 3 sub-array, and then again from each question gain access to all of it's connected alternatives in that questions's own sub-array. Sorry for the poor explanation of my issue, it's just a bit complicated :/
Page
Question
Alternative
Alternative
Alternative
Question
Alternative
Alternative
Alternative
Question
Alternative
Alternative
Page
Question
Alternative
Alternative
Question
Alternative
Alternative
Update: 3rd layer:
$rows_test2[$r['page']]
['id' => $r['id'],
'type' => $r['type'],
'description' => $r['description']]
[] =
array (
'altid' => $t['altid'],
'altdesc' => $t['altdesc']);
$rows[] = array(
"page" => 1,
"info" => array(
"id" => 1,
"type" => 3,
"description" => 'desc',
)
);
echo json_encode($rows); // [{"page":1,"info":{"id":1,"type":3,"description":"desc"}}]
Update:
$alternativesarray[]=array('id'=>'1', 'description'=>'yes');
$alternativesarray[]=array('id'=>'2', 'description'=>'no');
$rows[] = array(
"page" => 1,
"info" => array(
"id" => 2,
"type" => 3,
"description" => 'desc',
"alternatives" => $alternativesarray
)
);
print json_encode($rows); // [{"page":1,"info":{"id":2,"type":3,"description":"desc","alternatives":[{"id":"1","description":"yes"},{"id":"2","description":"no"}]}}]
maybe like this?
$before_json_encode[$row['page']][] = array(
'id' => $row['id'],
'type' => $row['type'],
'description' => $row['description'],
'alternatives' => $alternativesarray//im not sure about here,dont know the structure of the alternative array
);
Trying to push some data to record using php
array('$push' => array(
"value" => 1,
"comment" => $data['comment'],
"status" => 1,
))
But in db I see following records like array :
And it's should be like a normal values :
Seems that you want to use $set instead of $push.
array('$set' => array(
"value" => 1,
"comment" => $data['comment'],
"status" => 1,
))
$push is for appending elements to embedded arrays. $set is for replacing field values.