split arrays by date and other identifier - php

I have data im getting from mongodb to arrays and I want to work on the return data to split it by date and some other value , this is what I got so far and I need some help with the results
<?php
$stats=array(
array("source"=>501,"status"=>"answered","dest"=>"100","date"=>"2022-17-01"),
array("source"=>501,"status"=>"noAnswer","dest"=>"120","date"=>"2022-17-01"),
array("source"=>501,"status"=>"answered","dest"=>"100","date"=>"2022-18-01"),
array("source"=>502,"status"=>"answered","dest"=>"120","date"=>"2022-17-01"),
array("source"=>502,"status"=>"answered","dest"=>"130","date"=>"2022-17-01"),
array("source"=>502,"status"=>"answered","dest"=>"110","date"=>"2022-18-01")
);
$new1 = array();
$answer = 0;
$noanswer = 0;
$lastsrc = '';
$lastdate = '';
$dest=0;
foreach ($stats as $new) {
$src = $new['source'];
$date = $new['date'];
if ( $lastsrc == $src && $lastdate == $date ) {
$dest++;
if($new['status'] == 'answered'){ $answer++; }
if($new['status'] == 'noanswer'){ $noanswer++;}
$new1[] = array('source' => $src,
'date' => $date,
'ans' => $answer,
'nonans' => $noanswer,
'dest' => $dest );
} else if ( $lastsrc == $src && $lastdate != $date ) {
$dest++;
if($new['status'] == 'answered'){ $answer++;}
if($new['status'] == 'noanswer'){ $noanswer++;}
$new1[] = array('source' => $src,
'date' => $date,
'ans' => $answer,
'nonans' => $noanswer,
'dest' => $dest );
} else {
$dest++;
if($new['status'] == 'answered'){ $answer++; }
if($new['status'] == 'noanswer'){ $noanswer++;}
$new1[] = array('source' => $src,
'date' => $date,
'ans' => $answer,
'nonans' => $noanswer,
'dest' => $dest );
$lastsrc = $src;
$lastdate = $date;
}
}
print_r($new1);
?>
what im trying to achieve is splitting the Data by date and by source as well, so if in foreach loop I found same source and same date then I modify the array instead of create new array, if its the opposite then create new array
the result im trying to get is :
array("source"=>501,"ans"=>"1","noans" => 0,"dest"=>1,"date"=>"2022-17-01"),
array("source"=>501,"ans"=>"1","noAnswer" => 1,"dest"=>2,"date"=>"2022-18-01"),
array("source"=>502,"ans"=>"2","noans" => 0,"dest"=>2,"date"=>"2022-17-01"),
array("source"=>502,"ans"=>"1","noans" => 0,"dest"=>1,"date"=>"2022-18-01")
im not sure if its the right way ,any help will be very appreciated thanks

<?php
$stats = [
[ 'source' => 501, 'status' => 'answered', 'dest' => '100', 'date' => '2022-17-01' ],
[ 'source' => 501, 'status' => 'noAnswer', 'dest' => '120', 'date' => '2022-17-01' ],
[ 'source' => 501, 'status' => 'answered', 'dest' => '100', 'date' => '2022-18-01' ],
[ 'source' => 502, 'status' => 'answered', 'dest' => '120', 'date' => '2022-17-01' ],
[ 'source' => 502, 'status' => 'answered', 'dest' => '130', 'date' => '2022-17-01' ],
[ 'source' => 502, 'status' => 'answered', 'dest' => '110', 'date' => '2022-18-01' ]
];
$result = [];
foreach ($stats as $stat) {
$source = $stat['source'];
$date = $stat['date'];
$closure = static fn($item) => $item['source'] === $source && $item['date'] === $date;
$found = array_filter($result, $closure);
if (count($found) === 0) {
$list = array_filter($stats, $closure);
$list = array_map(static fn($item) => [ 'status' => $item['status'], 'dest' => $item['dest'] ], $list);
$result[] = [
'source' => $source,
'date' => $date,
'answered' => count(array_filter(array_column($list, 'status'), static fn($item) => $item === 'answered')),
'noAnswer' => count(array_filter(array_column($list, 'status'), static fn($item) => $item === 'noAnswer')),
'dest' => count(array_column($list, 'dest')),
];
}
}
print_r($result);

Create a composite key from the fields you want to sort by and use an associative array. (A single level in the array makes sorting/merging as well as extracting the values(array_values()) afterwards easy) Then you only need to iterate over $stats and $result once each.
$result = [];
foreach($stats as $stat) {
$key = $stat['source'].'_'.$stat['date'];
if (!array_key_exists($key, $result)) {
$result[$key] = ['answered' => 0, 'noAnswer' => 0] + $stat;
}
$result[$key][$stat['status']]++;
$result[$key]['dest'][$stat['dest']] = 1;
}
$result = array_map( // Transform "destinations key store" to count
function($item) {
$item['dest'] = count($item['dest']); return $item;
},
$result
);
print_r(array_values($result));
['source' => 501, 'status' => answered, 'dest' => 2, 'date' => 2022-17-01, 'answered' => 1, 'noAnswer' => 1],
['source' => 501, 'status' => answered, 'dest' => 1, 'date' => 2022-18-01, 'answered' => 1, 'noAnswer' => 0],
['source' => 502, 'status' => answered, 'dest' => 2, 'date' => 2022-17-01, 'answered' => 2, 'noAnswer' => 0],
['source' => 502, 'status' => answered, 'dest' => 1, 'date' => 2022-18-01, 'answered' => 1, 'noAnswer' => 0]

Related

set php variable contains only selected array

I have these array but I wanted it to echo an array only for the "watch" category and wanted to store the selected array in a PHP variable, I have to try to search the web to find the solution but no success.
$arr = [
'status' => 1,
'msg' => [
'total_records' => 5,
'total_pages' => 1,
'page_number' => 1,
'per_page' => 100,
'return_count' => 5,
'page_result' => [
0 => array
(
'items' => 200052001,
'code' => 501,
'category' => 'watch',
'price' => 50,
'stock' => 1,
),
1 => array
(
'items' => 200052001,
'code' => 401,
'category' => 'shirt',
'price' =>3,
'stock' => 1,
),
2 => array
(
'items' => 200052001,
'code' => 172758801,
'category' => 'watch',
'price' => 200,
'stock' => 1,
),
],
],
'errcode' => 0,
];
This should do the trick.
$watch_array = array();
foreach($arr["msg"]["page_result"] AS $k => $item) {
if($item["category"] == "watch") {
$watch_array[] = $item;
}
}
You now have an array containing only the watch.
To display its content, use:
print_r($watch_array);
Demo Link.
Check this search function for your requirement. Its completely dynamic along with recursive nature.
function search($array, $key, $value)
{
$results = [];
if (is_array($array)) {
if (isset($array[$key]) && $array[$key] == $value) {
$results[] = $array;
}
foreach ($array as $subarray) {
$results = array_merge($results, search($subarray, $key, $value));
}
}
return $results;
}
$temp = search($arr, "category", "watch");
Source.

Converting a php array to XML Soap api

I am have trouble converting array to xml here as the CustomerOrderLines are getting repeated, the xml generated gets only the last [CustomerOrderLines] value, how do i generate an xml with all the objects.
public function ProcessOrderAction(){
$subTotal = Mage::getModel('checkout/cart')->getQuote()->getSubtotal();
$grandTotal = Mage::getModel('checkout/cart')->getQuote()->getGrandTotal();
$quoteId = Mage::getSingleton('checkout/session')->getQuoteId();
$quote = Mage::getModel("sales/quote")->load($quoteId);
Mage::app()->setCurrentStore(Mage_Core_Model_App::ADMIN_STORE_ID);
if(Mage::getSingleton('customer/session')->isLoggedIn()) {
$customerData = Mage::getSingleton('customer/session')->getCustomer();
$customerAddress = array();
$_orders = Mage::getModel('sales/order')->getCollection()- >addFieldToFilter('customer_id',$customerData->getId());
$_orderCnt = $_orders->count(); //orders count
if($_orderCnt == 0){
$CustomerOperation="Create";
}else{
$CustomerOperation="Find";
}
$soapClient = new SoapClient("https://api.ongoingsystems.se/Colliflow/service.asmx?wsdl", array('trace' => 1));
$items = Mage::getSingleton('checkout/session')->getQuote()->getAllItems();
$store = Mage::app('checkout/session')->getStore();
$ap_param = array(
'GoodsOwnerCode'=>'Test',
'UserName' => 'test',
'Password' => 'test',
'co'=> [
'OrderInfo'=>[
'OrderIdentification' => 'SystemId',
'OrderOperation' => 'Create',
'GoodsOwnerOrderNumber' => '1111',
'OrderId' => '',
'GoodsOwnerOrderId' => '102',
'DeliveryDate' => '2016-05-14T22:16:00',
'OrderType'=> [
'OrderTypeOperation' => 'CreateOrFind',
'OrderTypeIdentification' => 'OrderTypeCode'
]
],
'Customer'=> [
'CustomerOperation' => $CustomerOperation,
'CustomerIdentification' => 'CustomerNumber',
'ExternalCustomerCode' => 'ExternalCustomerCode',
'CustomerNumber' => ''.$customerData->getId(),
'CustomerId' => ''.$customerData->getId(),
'Name' => ''.$customerData->getName(),
'Address' => ''.$customerAddress['region'],
'PostCode' => ''.$customerAddress['postcode'],
'City' => ''.$customerAddress['city'],
'TelePhone' => ''.$customerAddress['telephone'],
'Remark' => 'Remarks',
'IsVisible'=>'true',
'NotifyBySMS'=> 'true',
'NotifyByEmail'=> 'false',
'NotifyByTelephone'=>'false',
'Email' => ''.$customerData->getEmail(),
'MobilePhone' => ''.$customerAddress['telephone'],
'CountryCode' =>'NO',
'CountryStateCode' => '90'
],
'CustomerOrderLines' => [
'CustomerOrderLine'=> [
'OrderLineIdentification' => 'ArticleNumber',
'ArticleIdentification' => 'ArticleNumber',
'OrderLineSystemId' => '123',
'ExternalOrderLineCode' => 'ExternalOrderLineId',
'ArticleSystemId' => '123',
'ArticleNumber' => ''.$item->getSku(),
'ArticleName' => ''.$item->getName(),
'NumberOfItems' => '6',
'ProductCode' => ''.$item->getProductId()
],
'CustomerOrderLine'=> [
'OrderLineIdentification' => 'ArticleNumber',
'ArticleIdentification' => 'ArticleNumber',
'OrderLineSystemId' => '1231',
'ExternalOrderLineCode' => 'ExternalOrderLineId',
'ArticleSystemId' => '1230',
'ArticleNumber' => '0000099',
'ArticleName' => 'test222',
'NumberOfItems' => '6',
'ProductCode' => '6786978'
]
]
]
);
print_r($ap_param);
$error = 0;
try {
$info = $soapClient->__call("ProcessOrder", array($ap_param));
}catch (SoapFault $fault) {
$error = 1;
print("
alert('Sorry, returned the following ERROR: ".$fault->faultcode."-".$fault->faultstring.". We will now take you back to our home page.');
window.location = 'main.php'; ");
}
if ($error == 0) {
$auth_num = $info->ProcessOrderResult;
print_r($auth_num);
}
}

return inside foreach php and laravel

I trying to return data every time inside the foreach() but i keep on getting the data on the first iteration of the loop here is my code
for ($i = 0 ;$i<4;$i++)
{
var_dump($i);
$publisher = Publisher::find($results[$i]->publisherId);
//pr($publisher);
$channels =$publisher->channels()->get() ;
pr($channels[0]);
$data = ReviveAgent::getPublisherDailyStatistics($channels[0],$start,$end);
pr($data);
return Response::json($data);
}
on the var_dump($i);
It only shows data for the first 0 only.So how can i return the data also for 1,2,3
here is my output when pr($data) for var_dump($i) = 1
array (
0 =>
array (
'impressions' => 1867,
'clicks' => 14,
'requests' => 44,
'revenue' => 2.79,
'day' =>
stdClass::__set_state(array(
'scalar' => '20150518T00:00:00',
'timestamp' => 1431907200,
'xmlrpc_type' => 'datetime',
)),
),
1 =>
array (
'impressions' => 2197,
'clicks' => 17,
'requests' => 382,
'revenue' => 19.829999999999998,
'day' =>
stdClass::__set_state(array(
'scalar' => '20150519T00:00:00',
'timestamp' => 1431993600,
'xmlrpc_type' => 'datetime',
)),
),
2 =>
array (
'impressions' => 5484,
'clicks' => 3,
'requests' => 3680,
'revenue' => 6.7300000000000004,
'day' =>
stdClass::__set_state(array(
'scalar' => '20150520T00:00:00',
'timestamp' => 1432080000,
'xmlrpc_type' => 'datetime',
)),
),
3 =>
array (
'impressions' => 6909,
'clicks' => 105,
'requests' => 5141,
'revenue' => 378.88499999999999,
'day' =>
stdClass::__set_state(array(
'scalar' => '20150521T00:00:00',
'timestamp' => 1432166400,
'xmlrpc_type' => 'datetime',
)),
),
The return operator implicitly ends the current execution scope. The context of your usage is not given, but you could put your $data into an array prior to JSON encoding and returning it. It might look something like this:
$data = array();
for ($i = 0; $i < 4; $i++) {
...
$record = ReviveAgent::getPublisherDailyStatistics($channels[0], $start, $end));
pr($record);
$data[] = $record;
}
return Response::json($data);
You can take this example in laravel
Here I am returning multiple Prices
$prices = $this->Prices;
foreach ($prices as $price) {
$res[] = [
'travel_mode_id' =>$price->travel_mode_id,
'occupancy_id' => $price->occupancy_id,
'rider_id' => $price->occupancy_id,
'price' => $price->price,
];
}
return $res;

PHP find dependencies of multi-dimensional array

I am able to traverse a multi-dimensional array, but I also need information about dependencies. Here is what I am trying to do. I have an array like this:
array(
'top1' => 'sth',
'top2' => array(
'sub1' => 'sth',
'sub2' => array(
'line1' => 'sth',
'line2' => 'sth'
)
)
'top3' => 'sth'
)
I am able to traverse the array to get all the keys, result is this:
array([0] => 'top1', [1] => 'top2', [2] => 'sub1', [3] => 'sub2', ...)
However, I need to know the parent of the current element. So I hope I could get something like this:
array(
[top1] => array('parent' => 0, 'id' => 1),
[top2] => array('parent' => 0, 'id' => 2),
[sub1] => array('parent' => 2, 'id' => 2.1),
[sub2] => array('parent' => 2, 'id' => 2.2),
[line1] => array('parent' => 2.2, 'id' => 2.2.1),
...
[top3] => array('parent' => 0, 'id' => 3)
)
I have been trying many ways, but couldn't always get the correct result. Can anyone solve this out? Thanks!
here is a working example for you
function traverse(array $input, $parent = null) {
$result = array();
$current = 1;
foreach ($input as $key => $value) {
$id = null !== $parent ? $parent . '.' . $current : $current;
$result[$key] = array('parent' => null !== $parent ? $parent : 0, 'id' => $id);
if (is_array($value)) {
$result = array_merge($result, traverse($value, $id));
}
$current++;
}
return $result;
}
$input = array(
'top1' => 'sth',
'top2' => array(
'sub1' => 'sth',
'sub2' => array(
'line1' => 'sth',
'line2' => 'sth'
)
),
'top3' => 'sth'
);
echo '<pre>';
print_r($input);
echo '<hr>';
print_r(traverse($input));
echo '</pre>';

PHP: Help with Sorting Array

How can I sort an associative array by a weight AND type?
Input
array(
'a' => array( 'type' => 't1', 'weight' => 1, 'text' => 'text1' ),
'b' => array( 'type' => 't1', 'weight' => 3, 'text' => 'text2' ),
'c' => array( 'type' => 't2', 'weight' => 5, 'text' => 'text3' ),
'd' => array( 'type' => 't1', 'weight' => 2, 'text' => 'text4' ),
'e' => array( 'type' => 't2', 'weight' => 4, 'text' => 'text5' ),
'f' => array( 'type' => 't2', 'weight' => 4, 'text' => 'text6' )
);
Desired Output
array(
'a' => array( 'type' => 't1', 'weight' => 1, 'text' => 'text1' ),
'd' => array( 'type' => 't1', 'weight' => 2, 'text' => 'text4' ),
'b' => array( 'type' => 't1', 'weight' => 3, 'text' => 'text2' ),
'e' => array( 'type' => 't2', 'weight' => 1, 'text' => 'text5' ),
'f' => array( 'type' => 't2', 'weight' => 1, 'text' => 'text6' ),
'c' => array( 'type' => 't2', 'weight' => 5, 'text' => 'text3' )
);
Type "t2" must appear at end of array, all other types at start.
Weight must be sorted after type.
I am using uasort with a custom compare function, but am struggling. Here is what I have, but it doesn't work:
function my_comparer($a, $b) {
return ( $a['type'] !== 't2' && $b['type'] === 't2' )
? -1
: $a['weight'] - $b['weight'];
}
Your function doesn't take account of ($a['type']=='t2')
function my_comparer($a, $b) {
if ( ($a['type']==='t2') && ($b['type']!=='t2')) return -1;
if ( ($b['type']==='t2') && ($a['type']!=='t2')) return 1;
return ($a['weight'] - $b['weight']);
}
Try this:
function my_comparer($a, $b) {
if( $a['type'] == $b['type'] ){
return $a['weight'] - $b['weight'];
}else{
if( $a['type'] > $b['type'] ) return 1;
else return -1;
}
}
(warning, this is untested)
Simpler way would be array_multisort
$data = array(
'a' => array( 'type' => 't1', 'weight' => 1, 'text' => 'text1' ),
'b' => array( 'type' => 't1', 'weight' => 3, 'text' => 'text2' ),
'c' => array( 'type' => 't2', 'weight' => 5, 'text' => 'text3' ),
'd' => array( 'type' => 't1', 'weight' => 2, 'text' => 'text4' ),
'e' => array( 'type' => 't2', 'weight' => 4, 'text' => 'text5' ),
'f' => array( 'type' => 't2', 'weight' => 4, 'text' => 'text6' )
);
// Obtain a list of columns
foreach ($data as $key => $row) {
$type[$key] = $row['type'];
$weight[$key] = $row['weight'];
}
array_multisort($type, SORT_ASC, $weight, SORT_ASC, $data);
Plus this works if you add any number of types you want sorted in the same way.
Helper function:
function arrayColumnSort(&$array, $directions) {
// collect columns
$columnNames = array_keys($directions);
$columns = array();
foreach ($array as $row) {
foreach ($columnNames as $columnName) {
if (!isset($columns[$columnName])) {
$columns[$columnName] = array();
}
$columns[$columnName][] = isset($row[$columnName]) ? $row[$columnName] : null;
}
}
// build array_multisort params
$params = array();
foreach ($directions as $columnName => $direction) {
$params = array_merge(
$params,
array($columns[$columnName]),
is_array($direction) ? $direction : array($direction)
);
}
$params[] =& $array;
// sort
call_user_func_array('array_multisort', $params);
}
Call:
arrayColumnSort($data, array(
'type' => SORT_ASC,
'weight' => SORT_ASC,
));

Categories