Create Nested Array - eloquent

How can i create this array comes from my form, I have tried like below but it created array: 0 and 1 but array 2 does not created, i know it because am using this if (count($request->pid) > 0) { foreach ($request->pid as $key => $v) {
request->all()
array:12 [▼
"_token" => "aXAkdBEVfO8nLMtxjUoHgxbvBkxMbJz4zIonOvFm"
"projectdate" => "2021-08-30"
"clientName" => "Emmanuel"
"garamakaz" => "600"
"amountpaid" => "7888"
"Note" => "madirsha 50"
"pid" => array:2 [▼
0 => "1"
1 => "1"
]
"qty" => array:2 [▼
0 => "10"
1 => "10"
]
"discount" => array:2 [▼
0 => "500"
1 => "500"
]
"subtotal" => array:2 [▼
0 => "479500"
1 => "479500"
]
"descExps" => array:3 [▼
0 => "Ex1"
1 => "Ex2"
2 => "Ex3"
]
"amountExps" => array:3 [▼
0 => "45666"
1 => "45666"
2 => "45666"
]
]
Controller
this is my controller i used to created those data.
public function store(Request $request)
{
if (count($request->pid) > 0) {
foreach ($request->pid as $key => $v) {
$data2 = ([
'projectno' => $fk,
'user_id'=>Auth::user()->id,
'pid' => $request->pid[$key],
'project_date' => $date,
'discount' => $request->discount[$key],
'qty' => $request->qty[$key],
'clientName'=>$request->clientName,
'costproject'=>$request->garamakaz,
'comment'=>$request->Note,
'amountpaid'=>$request->amountpaid,
'amount' =>$request->subtotal[$key],
'description_expenses' =>$request->descExps[$key],
'amount_expenses' =>$request->amountExps[$key]
]);
$creatdata=Project::create($data2);
}
}
what can i do to create all data comes from my form?, someone can help me on this

Related

Find on the basis of field of last element of embedded document in mongo db php

I have a collection studentTbl which contains records like
Record 1
"_id": ObjectId("5b45d89bbbc51e2c2c006973")
"first_name": "Pooja",
...
contact_details[
{
..
},
{
..
}
]
transport_details[
{
allotment_id:"68998546878",
..
status:"Inactive"
},
{
allotment_id:"25799856890",
..
status:"Active"
}
]
}
Record 2
"_id": ObjectId("5b45d89bbbc51e2c2533")
"first_name": "Poornima",
...
contact_details[
{
..
},
{
..
}
]
transport_details[
{
allotment_id:"68998546878",
..
status:"Inactive"
}
]
}
Record 3
"_id": ObjectId("5b45d89bbbc51e2c2c00646")
"first_name": "Poonam",
...
contact_details[
{
..
},
{
..
}
]
transport_details[
{
allotment_id:"68998546878",
..
status:"Inactive"
},
{
allotment_id:"25799856890",
..
status:"Active"
}
]
}
I am trying to tweak the below lines of code in order to fetch those students whose first_name or middle_name or last_name contains "poo" and inside the last element of embedded document transport_details, status should be "Active". How to write such a query which will find students on the name basis and traverse through the last element of embedded document transport_details and checks whether the status is active? For e.g in the above collection, pooja and poonam should be returned.
The code is like
// default if nothing is filled
$query = array("schoolId"=> new MongoDB\BSON\ObjectID($this->schoolId));
// if name = filled, class = null, year = null
if(!empty($this->name) && empty($this->academicYearName) && empty($this->programId))
{
$param = preg_replace('!\s+!', ' ', $this->name);
$arg = trim($param);
$query = array(
'$or' => array(
array("first_name" => new MongoDB\BSON\Regex($arg, 'i')),
array("middle_name" => new MongoDB\BSON\Regex($arg, 'i')),
array("last_name" => new MongoDB\BSON\Regex($arg, 'i')),
array("registration_temp_perm_no" => $arg)
),
"schoolId"=> new MongoDB\BSON\ObjectID($this->schoolId)
);
}
...
...
...
$pipeline = array(
array(
'$match' => $query
),
array(
'$lookup' => array(
'from' => 'programTbl',
'localField' => 'classId',
'foreignField' => '_id',
'as' => 'ClassDetails'
)
),
);
try
{
$cursor = $this->collection->aggregate($pipeline);
}
catch (Exception $e) {
}
return $cursor->toArray();
Note that the actual code contains more conditional $query variable...
You can use below query in 3.6.
array(
'$or' => array(
array("first_name" => new MongoDB\BSON\Regex("/poo/i")),
array("middle_name" => new MongoDB\BSON\Regex("/poo/i")),
array("last_name" => new MongoDB\BSON\Regex("/poo/i"))
),
"$expr" => array(
"$eq" => array(
array("$arrayElemAt" => array("$transport_details.status", -1)),
"Active"
)
)
);
You can add below stages in your pipeline
array(
"$match" => array(
"$expr" => array(
"$and" => [
array(
"$or" => [
array( "$eq" => [ array( "$strcasecmp" => [ "$first_name", "Poo" ] ), 1 ] ),
array( "$eq" => [ array( "$strcasecmp" => [ "$last_name", "Poo" ] ), 1 ] ),
array( "$eq" => [ array( "$strcasecmp" => [ "$middle_name", "Poo" ] ), 1 ] ),
],
),
array(
"$eq" => [
array( "$arrayElemAt" => [ array( "$slice"=> [ "$transport_details.status", -1 ] ), 0 ] ),
"Active"
]
)
]
)
)
)

MongoDB doesnt return results or ignoring lte / gte

I'm using aggregate with the following code:
$result = \DB::connection('mongodb')->collection('urls')->raw(function($collection) use ($alias)
{
$from = new \MongoDate( strtotime('2015-01-01 00:00:00') );
$to = new \MongoDate( strtotime('2015-01-31 00:00:00') );
return $collection->aggregate([
['$match' =>
[
'alias' => $alias,
'clicks.created_at' => [
'$lte' => $to,
'$gte' => $from
]
]
],
['$unwind' => '$clicks'],
['$project' => [
'clicks' => 1
]
],
['$group' => [
'_id' => [ 'day' => [ '$dateToString' => [ 'format' => '%Y-%m-%d', 'date' => '$clicks.created_at' ] ] ],
'count' => [ '$sum' => 1 ]
]
],
]);
});
return $result;
Though I do have records within this timespan, no records are returned. any idea why?

PHP mongo - projection on particular array value

I have the following query:
$aggregate = [
['$unwind' => '$positions'],
['$match' => ['positions.banner_params.project_location_id' => (int)$projectId]],
[
'$project' => [
'page_id' => '$_id',
'position_id' => '$positions.id',
'page' => [
'website_id' => '$website_id',
'rate_tic' => '$rate_tic',
],
'banner_params' => [
'title' => '$positions.banner_params.title',
'tmpl_id' => '$positions.banner_params.tmpl_id'
],
'tmpl' => '$positions.tmpls',
'_id' => 0
]
],
];
$rows = $collection->aggregate($aggregate);
It returns such result:
[0] => Array
(
[page_id] => MongoId Object
(
[$id] => 5527a3a276098d86ae9aa3aa
)
[position_id] => 1
[page] => Array
(
[website_id] => 41
[rate_tic] => 10
)
[banner_params] => Array
(
[title] => My Title
[tmpl_id] => 2
)
[tmpl] => Array
(
[0] => Array
(
[id] => 1
[width] => 500
[height] => 100
)
[1] => Array
(
[id] => 2
[width] => 160
[height] => 400
)
[2] => Array
(
[id] => 7
[width] => 384
[height] => 115
)
)
)
How do I get into the tmpl only the template that match the banner_params.tmpl_id?
first let me sure if i understand it correctly. you want to filter items in the [tmpl] => Array by [id].
you cannot do that directly as the [tmpl] is an embedded object however as the aggregate is a pipeline function you can convert the current output the way you can filter and with $unwind then filter it again with $match and finally get the document as you wanted with $group. Something like below code should achieve what you want;
$aggregate = [
['$unwind' => '$positions'],
['$match' => ['positions.banner_params.project_location_id' => (int)$projectId]],
[
'$project' => [
'page_id' => '$_id',
'position_id' => '$positions.id',
'page' => [
'website_id' => '$website_id',
'rate_tic' => '$rate_tic',
],
'banner_params' => [
'title' => '$positions.banner_params.title',
'tmpl_id' => '$positions.banner_params.tmpl_id'
],
'tmpl' => '$positions.tmpls',
'_id' => 0
]
],
['$unwind' => '$tmpl'], // makes every item as a colection
['$match' => ['tmpl.id' => (int)$your id]], //filter the records
['$group' => ['_id' => '$page_id', tmpl:{$push:"$tmpl"} ]] // rebuild collection as you wanted you can use a compound _id if this is not enough
//if you don t want to see _id apply another projections to change it.
];
$rows = $collection->aggregate($aggregate);
Might have some errors but this is the logic you should implement.
EDIT:
There is also $redact DOC to remove items in sub documents please see the example.
Restricts the contents of the documents based on information stored in
the documents themselves.
Well, thanks to Onur TOPAL's advice I found the solution. One more $unvind followed by $redact did the job.
$aggregate = [
['$unwind' => '$positions'],
['$match' => ['positions.banner_params.project_location_id' => (int)$projectId]],
[
'$project' => [
'page_id' => '$_id',
'position_id' => '$positions.id',
'page' => [
'website_id' => '$website_id',
'rate_tic' => '$rate_tic',
],
'banner_params' => [
'title' => '$positions.banner_params.title',
'tmpl_id' => '$positions.banner_params.tmpl_id'
],
'tmpl' => '$positions.tmpls',
'_id' => 0
]
],
['$unwind' => '$tmpl'],
[
'$redact' => [
'$cond' => [
'if' => ['$eq' => ['$tmpl.id', '$banner_params.tmpl_id']],
'then' => '$$KEEP',
'else' => '$$PRUNE'
]
]
]
];

PayPal API - discount?

I'm trying to get a discount to apply to a shopping cart I've written. I'm using the Adaptive API system, but I can't seem to get it right. I've tried it in the SetPaymentOptions call:
'receiverOptions' => [
{
'receiver' => {
'email' => 'foo#live.co.uk'
},
'invoiceData' => {
'totalShipping' => '8.00',
'totalTax' => 0,
'item' => [
{
'itemPrice' => '15.00',
'name' => 'Alice in Wonderland Mechanism Necklace',
'price' => '15',
'itemCount' => 1
},
{
'itemPrice' => '30.00',
'name' => '110 Year Old Unicorn Dial Necklace',
'price' => '30',
'itemCount' => 1
}
],
'discount' => '0.15'
}
}
],
'requestEnvelope' => {
'errorLanguage' => 'en_US',
'detailLevel' => 'ReturnAll'
},
'payKey' => 'AP-2F6415163M814733M',
'SenderOptions' => {
'requireShippingAddressSelection' => bless( do{\(my $o = 1)}, 'JSON::XS::Boolean' )
}
};
..and even tried it in the initial Pay call - but neither seem to recognise the discount (and apply it).
'currencyCode' => 'GBP',
'requestEnvelope' => {
'errorLanguage' => 'en_US',
'detailLevel' => 'ReturnAll'
},
'cancelUrl' => 'https://sitedev.net/',
'discount' => '0.15',
'actionType' => 'CREATE',
'ipnNotificationUrl' => 'https://sitedev.net/cgi-bin/ipn.cgi',
'returnUrl' => 'https://sitedev.net/myorders',
'reverseAllParallelPaymentsOnError' => bless( do{\(my $o = 0)}, 'JSON::XS::Boolean' ),
'receiverList' => {
'receiver' => [
{
'email' => 'foo#live.co.uk',
'amount' => '53.00',
'invoiceId' => '47',
'paymentType' => 'GOODS'
}
]
}
};
UPDATE: Mmm ok - still having issues with this!
'item' => [
{
'itemPrice' => '25.00',
'name' => 'Cryptex - 16Gb USB Drive',
'price' => '25',
'itemCount' => 1
},
{
'name' => 'Special Discount',
'price' => '-2.50',
'itemCount' => 1
},
{
'itemPrice' => '5.00',
'name' => 'Shipping',
'price' => '5.00',
'itemCount' => 1
}
]
Thats the values I'm passing in, yet at the cart end, it shows as:
Steampunk Junkies £27.50
Cryptex - 16Gb USB Drive
£25.00
Shipping
£5.00
£0.00
The weird thing - is that the discount IS being applied... just not shown???
I'm curious where you see that there's a "discount" parameter even available in these calls..?? It's not listed in the API reference for Pay or SetPaymentOptions.
What you'll need to do is add the discount as a line item in SetPaymentOptions with a negative amount. So it would be an extra line item with -0.15 as the value. You could name the item "discount" or whatever you want, but again, there is no actual discount parameter available in these API's.

How to make this MongoDB aggregation return key:value?

I have this aggregation:
$out = $db->stats->aggregate (
array('$match' => $where),
,array( '$group' =>
array( "_id" => '$traffic.source',
'count'=> array('$sum' => 1)
)
)
,array( '$project' =>
array( "_id" => 0,
'type' => '$_id',
'count' => '$count'
)
)
);
which returns an array with:
[{type:sourceA, count:2},{type:sourceB, count:6}...]
Is it possible to make it return:
[sourceA:2, sourceB:6,....] without looping the array afterwords?