de-dupe array of documents - php

I run a solr query, which returns a result set of jobs.
Some of the jobs are duplicates (but from different sources), which is decided based on if the job title, description and location are the same.
I want to loop through my result set, and combine any duplicated into one job, with that one job having multiple sources... something like:
original result:
$jobs = array(
array(
'id' => 'job1',
'title' => 'test',
'description' => 'test',
'location' => 'test',
'source' => 'source1',
),
array(
'id' => 'job2',
'title' => 'test',
'description' => 'test',
'location' => 'test',
'source' => 'source2',
),
array(
'id' => 'job3',
'title' => 'test',
'description' => 'test',
'location' => 'test',
'source' => 'source3',
),
array(
'id' => 'job4',
'title' => 'testing',
'description' => 'testing',
'location' => 'testing',
'source' => 'source1',
)
);
would become:
$jobs = array(
array(
'id' => 'job1',
'title' => 'test',
'description' => 'test',
'location' => 'test',
'source' => 'source1',
'other_sources' => array(
array(
'id' => 'job2',
'title' => 'test',
'description' => 'test',
'location' => 'test',
'source' => 'source2'
),
array(
'id' => job3,
'title' => 'test',
'description' => 'test',
'location' => 'test',
'source' => 'source3'
),
),
),
array(
'id' => 'job4',
'title' => 'testing',
'description' => 'testing',
'location' => 'testing',
'source' => 'source1'
)
);
how can I achieve this? Either in PHP or perhaps in the Solr query itself (I'm using Solarium to do my Solr querying)

How about something like this?
<?php
$result = array();
foreach ($jobs as $job) {
if (!empty($result[$job['title']])) {
$result[$job['title']]['other_sources'][] = $job;
}
else {
$result[$job['title']] = $job;
}
}
It initializes an empty array($result) and then loops through the job array. The empty array will store the jobs with the title being used as the key. If the job title does not exist in the result array, then it will add it. If the job title does exist in the job array, then it will append the job to an array inside the existing job (under the key 'other_sources')

Related

How to Recursively find secondary profiles and merge into primary one

I have a sample array, in which I would like to find the secondary ones and recursively check the secondary one until all secondary profiles gets unset from PHP array.
Here is the example array.
$testarray= array(
array(
array(
'id' => 'ccdbh-743748',
'name' => 'test',
'email' => 'testemail#test.com',
'newsletter' => 'abc,def,ghi',
'created_at' => '1546753453',
'profile_type' => 'primary'
),
array(
'id' => 'uisvuiacsiodciosd',
'name' => 'test',
'email' => 'testemail#test.com',
'newsletter' => 'def',
'created_at' => '1546753453',
'profile_type' => 'secondary'
),
array(
'id' => 'sdcisodjcosjdocij',
'name' => 'test',
'email' => 'testemail#test.com',
'newsletter' => 'ghi',
'created_at' => '1546753453',
'profile_type' => 'secondary'
)
),
array(
array(
'id' => 'sdcisodjcosjdocij',
'name' => 'test',
'email' => 'testemail#test.com',
'newsletter' => 'abc',
'created_at' => '1546753453',
'profile_type' => 'secondary'
),
array(
'id' => 'ccdbh-743748',
'name' => 'test',
'email' => 'testemail#test.com',
'newsletter' => 'abc,def',
'created_at' => '1546753453',
'profile_type' => 'primary'
)
),
array(
array(
'id' => 'sdcisodjcosjdocij',
'name' => 'test',
'email' => 'testemail#test.com',
'newsletter' => 'abc',
'created_at' => '1546753453',
'profile_type' => 'secondary'
),
array(
'id' => 'sdcisodjcoscisudhiu',
'name' => 'test',
'email' => 'testemail#test.com',
'newsletter' => 'abc,def',
'created_at' => '1515217453',
'profile_type' => 'primary'
)
)
);
What I have tried so far.
function duplicate_profiles_merger ($profiles_array) {
$innderdata = array();
foreach ($profiles_array as $key => $val) {
if (is_array($val) && in_array('secondary', $val)) {
unset($val[$key]);
// echo 'recursion';
duplicate_profiles_merger($profiles_array);
} else {
// $innderdata = $val;
//POST Request API code goes here. Like curl request.
//data '{"primary":{"email":"cool.person#company.com"}, "secondary":{"email":"cperson#gmail.com"}}'
echo 'done';
}
return $innderdata = $val;
}
}
But this gets me in an infinite state.
Below is the scenario that I want to achieve.
Here is the data that I need to pass through the API post request.
data '{"primary":{"email":"cool.person#company.com"}, "secondary":{"email":"cperson#gmail.com"}}'
Now I need the primary email and the secondary email for profile merge.
But there is more than one secondary profile that exists in the array, so for that, I need some kind of recursive functionality.
Thanks
This answer sums up the comment section:
You call your recursion method with the same exact array you started with. But PHP is passing arguments as value as default, meaning you only modify the $var element, but not the $profiles_array, because of this you are creating an infinite loop.
Plus: There is no need for recursion here because there is no "child-structure" that would profit from real recursion here. A simple loop should do the trick.
function duplicate_profiles_merger ($profiles_array) {
$innderdata = array();
foreach ($profiles_array as $key => $val) {
if (is_array($val) && $val['profile_type'] == 'primary') {
array_push($innerdata, $val);
}
}
return $innerdata;
}
This should be all there is to it. You can also modify the existing array, eg. deleting all secondary profiles. Then you have to pass the array as reference, not value: https://www.php.net/manual/en/language.references.pass.php

Get fetched result in different arrays by joined tables

I would like to make a Post object containing an instance of its associated table User and the easiest would be if I could access user results and post results separately.
The query:
$query = $this->connection->newQuery()->from('post');
$query->select(
[
'post.message',
'post.created_at',
'user.name',
'user.email',
'user.role',
'user.status',
]
)->join(['table' => 'user', 'conditions' => 'post.user_id = user.id']);
$postsRows = $query->execute()->fetchAll('assoc');
The query above outputs an array of the result rows and I have no way to know if the column is from the user table or post table.
$postsRows = array (
0 =>
array (
'message' => 'This is a test post',
'created_at' => '2021-01-01 00:00:01',
'name' => 'Admin Example',
'email' => 'admin#example.com',
'role' => 'admin',
'status' => 'active',
),
1 =>
array (
'message' => 'This is another test post',
'created_at' => '2021-01-01 00:00:01',
'name' => 'User Example',
'email' => 'user#example.com',
'role' => 'user',
'status' => 'active',
),
)
Naturally I can make aliases for each column
$query = $this->connection->newQuery()->from('post');
$query->select(
[
'post.*',
'user_name' => 'user.name',
'user_email' => 'user.email',
'user_role' => 'user.role',
'user_status' => 'user.status',
]
)->join(['table' => 'user', 'conditions' => 'post.user_id = user.id']);
$postsRows = $query->execute()->fetchAll('assoc');
But then I have to go through them and split the array manually later, I can't alias the post column names as I use the expression * and it won't work when joining the same table.
I guess what would be ideal would be the following output. Is something like this possible?
$postsRows = array(
0 => array(
'post' => array(
'message' => 'This is a test post',
'created_at' => '2021-01-01 00:00:01',
),
'user' => array(
'name' => 'Admin Example',
'email' => 'admin#example.com',
'role' => 'admin',
'status' => 'active',
)
),
1 => array(
'post' => array(
'message' => 'This is another test post',
'created_at' => '2021-01-01 00:00:01',
),
'user' => array(
'name' => 'User Example',
'email' => 'user#example.com',
'role' => 'user',
'status' => 'active',
),
),
)
As discussed here, the workflow that interests me is more "use case" based, and then it doesn't make sense to do what I requested (as it would kind of be reinventing ORM which I did first).
What works out for me is creating specific DTOs with high cohesion like UserPost in which case the origin of the table is not relevant as fields are selected individually, precisely.

Unique Merge multiple multidimensional array

I have some difficulties to merge many multidimensional array in php. I tried to do it by many way, but each time, I don't get the result wanted. I tried with array_merge(array_unique,...) and in different post I found a way with array_map, but I don't understand everything...
I can have many multi array like below:
array(
(int) 0 => array(
'User' => array(
'username' => 'testje',
'firstname' => 'jean',
'lastname' => 'test'
),
'Calendar' => array(
'period' => 'AM'
),
'Shift' => array(
'name' => 'HV',
'color' => '#b7fa00'
),
'Team' => array(
'name' => 'Proxy_B28'
)
),
(int) 1 => array(
'User' => array(
'username' => 'testje',
'firstname' => 'jean',
'lastname' => 'test'
),
'Calendar' => array(
'period' => 'PM'
),
'Shift' => array(
'name' => 'HV',
'color' => '#b7fa00'
),
'Team' => array(
'name' => 'Proxy_B28'
)
)
)
And I would like to get this kind of array :
array(
'User' => array(
'username' => 'testje',
'firstname' => 'jean',
'lastname' => 'test'
),
'Calendar' => array(
'period' => 'Full day'
),
'Shift' => array(
'name' => 'HV',
'color' => '#b7fa00'
),
'Team' => array(
'name' => 'Proxy_B28'
)
)
Do you have some advices to give me to get this result ?
Thank you very much !
I don't know if the best solution but it seems to work like this, and fastly :
foreach ($users as $k=>$v){
//$r[$k] = array_merge($v,$users[$k]);
//$unique[] = array_map("unserialize", array_unique(array_map("serialize", $users[$k])));
$s[$k] = array(
'username' => $v['User']['username'],
'team' => $v['Team']['name'],
'period' => $v['Calendar']['period']
);
if ($k > 0) {
if (in_array($v['User']['username'],$s[$k])) {
unset($s[$k-1]);
$s[$k] = array(
'username' => $v['User']['username'],
'team' => $v['Team']['name'],
'period' => "FD"
);
}
}
}
Do you have another idea or this one is enough good ?
thank you !

Put new data to specific keys in array PHP

I want to add some data to an existing array without modifying any of the existing keys or values.
The original array is like this:
array(
'sections' => array(
array(
'id' => 'sections_id',
'title' => 'sections_title'
)
),
'settings' => array(
array(
'id' => 'settings_id',
'title' => 'settings_title'
)
)
);
Now I want to be ablle to add new arrays to sections key and to settings key that will turn the following into :
array(
'sections' => array(
array(
'id' => 'sections_id',
'title' => 'sections_title'
),
array(
'id' => 'NEW_sections_id',
'title' => 'NEW_sections_title'
)
),
'settings' => array(
array(
'id' => 'settings_id',
'title' => 'settings_title'
),
array(
'id' => 'NEW_settings_id',
'title' => 'NEW_settings_title'
)
)
);
I tried using array_push and array_merge without success I hope someone can help.
Thank you!
you would do it just like you would any other array.
$array['sections'][] = array('id' => 'sec_id', 'title' => 'sec_title');

Magento: create bundle order programmatically

I have this code: http://pastebin.com/iFwyKM7G
Inside an event-observer class which executes after the customer registered. It creates an order automatically and it works for simple products. However I cannot figure out for the life of me how to make it work with Bundled product!
How can I make this work with a bundled product?
I DID IT!
I changed my code to the following:
$customer = Mage::getSingleton('customer/customer')->load($observer->getCustomer()->getId());
$session = Mage::getSingleton('adminhtml/session_quote');
$order_create_model = Mage::getSingleton('adminhtml/sales_order_create');
Mage::log($customer->debug(), null, 'toszodj_meg.log');
//$transaction = Mage::getModel('core/resource_transaction');
$storeId = $customer->getStoreId();
Mage::log($customer->getDefaultBillingAddress()->debug(), null, 'toszodj_meg.log');
$reservedOrderId = Mage::getSingleton('eav/config')->getEntityType('order')->fetchNewIncrementId($storeId);
$session->setCustomerId((int) $customer->getId());
$session->setStoreId((int) $storeId);
$orderData = array(
'session' => array(
'customer_id' => $customer->getId(),
'store_id' => $storeId,
),
'payment' => array(
'method' => 'banktransfer',
'po_number' => (string) '-',
),
// 123456 denotes the product's ID value
'add_products' =>array(
'2' => array(
'qty' => 1,
'bundle_option' => array(
2 => 2,
1 => 1,
),
'bundle_option_qty' => array(
2 => 1,
1 => 1,
),
),
),
'order' => array(
'currency' => 'EUR',
'account' => array(
'group_id' => $customer->getGroupId(),
'email' => (string) $customer->getEmail(),
),
'comment' => array('customer_note' => 'API ORDER'),
'send_confirmation' => 1,
'shipping_method' => 'flatrate_flatrate',
'billing_address' => array(
'customer_address_id' => $customer->getDefaultBillingAddress()->getEntityId(),
'prefix' => $customer->getDefaultBillingAddress()->getPrefix(),
'firstname' => $customer->getDefaultBillingAddress()->getFirstname(),
'middlename' => $customer->getDefaultBillingAddress()->getMiddlename(),
'lastname' => $customer->getDefaultBillingAddress()->getLastname(),
'suffix' => $customer->getDefaultBillingAddress()->getSuffix(),
'company' => $customer->getDefaultBillingAddress()->getCompany(),
'street' => $customer->getDefaultBillingAddress()->getStreet(),
'city' => $customer->getDefaultBillingAddress()->getCity(),
'country_id' => $customer->getDefaultBillingAddress()->getCountryId(),
'region' => $customer->getDefaultBillingAddress()->getRegion(),
'region_id' => $customer->getDefaultBillingAddress()->getRegionId(),
'postcode' => $customer->getDefaultBillingAddress()->getPostcode(),
'telephone' => $customer->getDefaultBillingAddress()->getTelephone(),
'fax' => $customer->getDefaultBillingAddress()->getFax(),
),
'shipping_address' => array(
'customer_address_id' => $customer->getDefaultShippingAddress()->getEntityId(),
'prefix' => $customer->getDefaultShippingAddress()->getPrefix(),
'firstname' => $customer->getDefaultShippingAddress()->getFirstname(),
'middlename' => $customer->getDefaultShippingAddress()->getMiddlename(),
'lastname' => $customer->getDefaultShippingAddress()->getLastname(),
'suffix' => $customer->getDefaultShippingAddress()->getSuffix(),
'company' => $customer->getDefaultShippingAddress()->getCompany(),
'street' => $customer->getDefaultShippingAddress()->getStreet(),
'city' => $customer->getDefaultShippingAddress()->getCity(),
'country_id' => $customer->getDefaultShippingAddress()->getCountryId(),
'region' => $customer->getDefaultShippingAddress()->getRegion(),
'region_id' => $customer->getDefaultShippingAddress()->getRegionId(),
'postcode' => $customer->getDefaultShippingAddress()->getPostcode(),
'telephone' => $customer->getDefaultShippingAddress()->getTelephone(),
'fax' => $customer->getDefaultShippingAddress()->getFax(),
),
),
);
$order_create_model->importPostData($orderData['order']);
$order_create_model->getBillingAddress();
$order_create_model->setShippingAsBilling(true);
$order_create_model->addProducts($orderData['add_products']);
$order_create_model->collectShippingRates();
$order_create_model->getQuote()->getPayment()->addData($orderData['payment']);
$order_create_model
->initRuleData()
->saveQuote();
$order_create_model->getQuote()->getPayment()->addData($orderData['payment']);
$order_create_model->setPaymentData($orderData['payment']);
$order_create_model
->importPostData($orderData['order'])
->createOrder();
$session->clear();
Mage::unregister('rule_data');
Mage::log('Order Successfull', null, 'siker_bammer.log');
And it works! thought the customer doesn't get notified. which iam trying to figure out now.

Categories