I have an application I am trying to update from legacy to new driver. I am having a problem with collections being damaged when the below code is triggered. I think I have narrowed it down here.
function update($collection,$criteria,$data,$insertIfNotExists = false)
{
if(!empty($collection) && !empty($criteria) && !empty($data)) {
if (!isset($this->collection[$collection])) {
$this->collection[$collection] = (new MongoDB\Client)->hebe->{$collection};
}
if ($insertIfNotExists) {
$oldData = $this->collection[$collection]->findOne($criteria);
if ($oldData == NULL) {
$data['createdDate'] = date("Y-m-d H:i:s");
$data['modifiedDate'] = (isset($data['modifiedDate'])) ? $data['modifiedDate']:date("Y-m-d H:i:s");
/*
return ($this->collection[$collection]->insertOne($data)) ? array('status'=>'ok'):array('status'=>'error','error'=>'unknown_error');
*/
} else {
$newData = $oldData;
foreach($data as $n=>$v) {
$newData[$n] = $v;
}
$newData['modifiedDate'] = (isset($newData['modifiedDate'])) ? $newData['modifiedDate']:date("Y-m-d H:i:s");
/*
return ($this->collection[$collection]->updateOne($criteria,['$set' => $newData])) ? array('status'=>'ok'):array('status'=>'error','error'=>'unknown_error');
*/
}
} else {
/*
return ($this->collection[$collection]->updateOne($criteria,['$set' => $data])) ? array('status'=>'ok'):array('status'=>'error','error'=>'unknown_error');
*/
}
}
}
example variables are
$collection = 'customer'
$criteria = array ( 'number' => '9999',)
$data = array (
'number' => '9999',
'name' => 'Testing Account',
'reference' => 'Peter Smith',
'defaultDeliveryAddress' => 1,
'visitAddress' => '',
'address' => '',
'district' => 'Marknad',
'postAddress' => '',
'orgNumber' => '5562041771',
'phone' => '031-7802700',
'fax' => '031-193328',
'groupCode' => 'int',
'creditCustomer' => '',
'typeOfDelivery' => 'Bil',
'typeOfPayment' => '10',
'emailAddresses' =>
array (
'invoice' => 'email1#domain.com',
'order' => 'email2#domain.com',
'deliveryNote' => 'email3#domain.com',
'packingSlip' => 'email4#domain.com',
),
'orderType' => NULL,
'termsOfDelivery' => 'RC',
'creditLimit' => 100000.0,
'pricelist' => 4,
'pricelist1' => '',
'pricelist2' => '9998',
'pricelist3' => '104',
'discount' => NULL,
'countryCode' => 'SE',
'currencyCode' => 'SEK',
'blocked' => 0,
'deliveryCost' => 0,
'vatCode' => '2',
'email' => 'peremail#domain.com',
'password' => 'password',
'modifiedDate' => '2019-06-25 00:00:00',
'deliveryAddresses' =>
array (
0 =>
array (
'row' => 1,
'name' => 'Test Address',
'address' => 'Box 12345',
'postAddress' => '42246',
'default' => true,
),
1 =>
array (
'number' => '9999',
'name' => 'Testing Address',
'reference' => '13232',
'address' => 'Box 12245',
'postAddress' => '42246',
),
),
'references' =>
array (
0 =>
array (
'number' => '9999',
'name' => 'Testing',
'email' => '',
'password' => '',
),
1 =>
array (
'number' => '9999',
'name' => 'Testing2',
'email' => '',
'password' => 'password',
),
2 =>
array (
'number' => '9999',
'name' => 'Peter Smith',
'email' => '',
'password' => 'password',
),
),
)
Can someone point me in the right direction on what I am doing wrong with updateOne and insertOne. From what I understand by the docs is it supports array.
EDIT: a little background is I upgraded this system and MongoDB from 2.6 to 3.6. I also upgraded mongodb driver from legacy mongo.
The problem was the old data in the collection had quotations and the updateOne/insertOne data did not. Correcting this seem to solve the problem.
Related
Screenshot
As you see my data are loaded inside extra SNHISTORY array and I need to remove that extra array.
Code
Lines regarding to screenshot results are commented.
$array = [];
foreach($internalTransits as $key => $item) {
foreach($item->barcodes as $barcode){}
$a = $item->barcodes;
$grouped = $a->mapToGroups(function ($item, $key) {
return [
'SNHISTORY' => [ // my arrays to move out
'_attributes' => [
'operation' => 'Ret'
],
'SERIALNUMBER' => $item['serial_number'] ? $item['serial_number'] : $item['u_serial_number'],
'EXPIREDDATE' => $item['created_at']->format('Y-m-d'),
'QUANTITY' => '1',
'SNSIGN' => '-1',
],
'ITEMUNIT' => $item['product']['unit'],
'UNITPRICE' => $item['product']['price'],
];
});
$year = Carbon::createFromFormat('Y-m-d H:i:s', $item['created_at'])->year;
$month = Carbon::createFromFormat('Y-m-d H:i:s', $item['created_at'])->month;
$timeline[$key][] = [
'_attributes' => [
'operation' => 'Add'
],
'KeyID' => $barcode['product']['id'],
'ITEMNO' => $barcode['product']['sku'],
'QUANTITY' => '1',
'ITEMUNIT' => $barcode['product']['unit'],
'UNITRATIO' => '1',
'ITEMRESERVED1' => '',
'ITEMRESERVED2' => '',
'ITEMRESERVED3' => '',
'ITEMRESERVED4' => '',
'ITEMRESERVED5' => '',
'ITEMRESERVED6' => '',
'ITEMRESERVED7' => '',
'ITEMRESERVED8' => '',
'ITEMRESERVED9' => '',
'ITEMRESERVED10' => '',
'UNITPRICE' => $barcode['product']['price'],
'QTYCONTROL' => '0',
'SNHISTORY' => $grouped->toArray(), // this has extra array where my actual arrays are loaded inside of it
];
$array['TRANSACTIONS'] = [
'_attributes' => [
'OnError' => 'CONTINUE'
],
];
$array['TRANSACTIONS']['WTRAN'] = [
'_attributes' => [
'operation' => 'Add',
'REQUESTID' => '1',
],
'TRANSFERID' => $item['id'],
'TRANSACTIONID' => '',
'TRANSFERNO' => $item['transNu'],
'TRANSFERDATE' => $item['created_at']->format('Y-m-d'),
'DESCRIPTION' => $item['description'],
'FROMWHID' => $barcode['outlet'][0]['name'],
'TOWHID' => $item->toOutlet->name,
'FROMWHADDRESS' => '',
'TOWHADDRESS' => '',
];
$array['TRANSACTIONS']['WTRAN']['ITEMLINE'] = $timeline;
}
What I've tried
I cannot change 'SNHISTORY' => $grouped->toArray(), to something like $grouped->toArray(), under $timeline[$key][] = [ it will return error
I cannot add $array['TRANSACTIONS']['WTRAN']['ITEMLINE']['SNHISTORY'] = $grouped->toArray(); and remove 'SNHISTORY' => $grouped->toArray(), it will return error known bug
Question
How can I remove extra SNHISTORY around my data?
As mentioned in the comments section, you probably want to merge both arrays together:
$timeline[$key][] = [
'_attributes' => [
'operation' => 'Add'
],
'KeyID' => $barcode['product']['id'],
'ITEMNO' => $barcode['product']['sku'],
'QUANTITY' => '1',
'ITEMUNIT' => $barcode['product']['unit'],
'UNITRATIO' => '1',
'ITEMRESERVED1' => '',
'ITEMRESERVED2' => '',
'ITEMRESERVED3' => '',
'ITEMRESERVED4' => '',
'ITEMRESERVED5' => '',
'ITEMRESERVED6' => '',
'ITEMRESERVED7' => '',
'ITEMRESERVED8' => '',
'ITEMRESERVED9' => '',
'ITEMRESERVED10' => '',
'UNITPRICE' => $barcode['product']['price'],
'QTYCONTROL' => '0',
] + $grouped->toArray();
as i can see in your screen shot data
you are getting xml data you need to convert that into array
function xmlToArray($xml_string)
{
$doc = #simplexml_load_string($xml_string);
if ($doc) {
$xml = simplexml_load_string($xml_string);
$json = json_encode($xml);
return json_decode($json, true);
}
}
then u will get real array then u don't need to remove that as that is a parent key
I have this code in model User:
$hasOne = array(
'Member' => array(
'className' => 'Member',
'foreignKey' => 'user_id',
'dependent' => true
)
);
function rest_findUserById($id = NULL) {
$row = $this->find(
'first',
array(
'contain' => array(
'UserSession'=>array(
'fields'=>array('user_id', 'session_token')
) ,
'Member' => array(
'fields' => array("*")
)
),
'fields' => array('username', 'email'),
'conditions' => array('User.id' => $id)
));
if (!$row) {
return FALSE;
}
debug($row);exit;
}
and in model Member:
$virtualFields = array(
'full_name' => 'CONCAT(Member.first_name, " ",Member.last_name)'
);
$belongsTo = array(
'Country' => array(
'className' => 'Country',
'foreignKey' => 'country_id',
'conditions' => '',
'fields' => '',
'order' => ''
),
'User' => array(
'className' => 'User',
'foreignKey' => 'user_id',
'conditions' => '',
'fields' => '',
'order' => ''
)
);
?>
When I call fuction rest_findUserById() I get this output:
/app/Model/User.php (line 378)
array(
'User' => array(
'username' => 'testuser',
'email' => 'test#gmail.com',
'id' => '71'
),
'Member' => array(
'id' => '11',
'user_id' => '71',
'first_name' => 'Whjc',
'last_name' => 'test_user_lname',
'email' => '',
'phone' => '778899554455',
'image_dir' => '11',
'image' => '92e20fd0260dcc5ea289611221723b6a.jpg',
'address_line_1' => 'Shhd',
'address_line_2' => 'sdf',
'city' => 'Los Angeles Area',
'state' => 'delhi',
'country_id' => '0',
'zip_code' => '56456',
'is_address_different' => false,
'date_of_birth' => '0000-00-00',
'referred_by' => 'asdf',
'created' => '2016-07-27 13:52:30',
'created_by' => '3',
'modified' => '2016-08-02 12:25:22',
'modified_by' => '3',
'status' => false
),
'UserSession' => array(
(int) 0 => array(
'user_id' => '71',
'session_token' => 'a685b3db5ab87a928716c7d8b3272572'
)
)
)
but when I call this code:
$this->Member->recursive = -1;
debug($this->Member->find('first'));
I get this output:
/app/Model/User.php (line 377)
array(
'Member' => array(
'id' => '4',
'user_id' => '64',
'first_name' => 'SDFS SDF',
'last_name' => 'test_user_lname',
'email' => '',
'phone' => '778899554455',
'image_dir' => '',
'image' => '',
'address_line_1' => 'sdf',
'address_line_2' => 'sdf',
'city' => 'Los Angeles Area',
'state' => 'delhi',
'country_id' => '0',
'zip_code' => '56456',
'is_address_different' => false,
'date_of_birth' => '1970-01-01',
'referred_by' => 'asdf',
'created' => '2016-07-22 15:25:30',
'created_by' => '0',
'modified' => '2016-07-22 15:25:30',
'modified_by' => '0',
'status' => false,
'full_name' => 'SDFS SDF test_user_lname'
)
)
as you can see the virtual field i.e.'full_name' is coming in the second output but not in first output.
How can I fix this?
From the manual
you cannot use virtualFields on associated models
the proposed solution is to copy the virtual field into your model, this way
/app/Model/User.php
$this->virtualFields['member_full_name'] = $this->Member->virtualFields['full_name'];
Of course this does not work for hasMany or HABTM relationships. Also note that in this way you'll find the virtual field in the User data array and not in the Member data array
this is my code where i am fetching my mysql record.
$parentChildArr=array();
//mysql query for fetching parent and child record
$selectparentMenu=mysql_query("SELECT `id`,`item_name`,`menu_type`,`parent` FROM `epic_master_menu`");
if(mysql_num_rows($selectparentMenu)>1) {
while($fetchparentMenu=mysql_fetch_array($selectparentMenu)) {
$parentChildArr[]=$fetchparentMenu['id'];
$parentChildArr[]=$fetchparentMenu['item_name'];
$parentChildArr[]=$fetchparentMenu['menu_type'];
$parentChildArr[]=$fetchparentMenu['parent'];
}
var_export($parentChildArr); // exporting or printing arrays
// when i export the array i get this output.
array ( 0 => '1', 1 => 'Dashboard', 2 => 'item', 3 => '0',
4 => '2', 5 => 'Admission', 6 => 'item', 7 => '0', 8 => '3',
9 => 'Examination', 10 => 'item', 11 => '0', 12 => '4',
13 => 'CET', 14 => 'item', 15 => '0');
but the problem is that i want to build the array like this.
$newarr=array ( 'dataSource' => array ( 0 => array ( 'id' => '1',
'text' => 'Dashboard', 'expanded' => 'true', 'spriteCssClass' => 'rootfolder',
'items' => array ( 0 => array ( 'id' => '89', 'text' => 'Users',
'expanded' => true, 'spriteCssClass' => 'folder',
'items' => array ( 0 => array ( 'id' => '94', 'text' => 'Users',
'spriteCssClass' => 'html', ), 1 => array ( 'id' => '94',
'text' => 'Users', 'spriteCssClass' => 'html', ), 2 => array (
'id' => '94', 'text' => 'Users', 'spriteCssClass' => 'image' ) ) ) ) ) ));
database table view is...
i am not getting the logic that how to build the array like $newarr. thank you
not tested, but you need to defined a structure and then you need to go recursive... so you can check where is the parent entry to my child ...
function structure($data){
return array(
'id' => $data['id'],
'item_name' => $data['item_name'],
'menu_type' => $data['menu_type'],
'parent' => $data['parent'],
'expanded' => false,
'childs' => array()
);
}
function recursiveImport(&$parent, $data){
foreach($parent AS $key => $value){
if($value['id'] == $data['parent']){
$parent[$key]['childs'][] = structure($data);
$parent[$key]['expanded'] = true;
return true;
}
else{
if(count($value['childs']) > 0){
foreach($value['childs'] AS $key2 => $child){
$result = recursiveImport($parent[$key]['childs'][$key2], $data);
if($result === true) return true;
}
}
}
}
return false;
}
$newarr = array();
while($fetchparentMenu=mysql_fetch_array($selectparentMenu)) {
$result = recursiveImport($newarr , $fetchparentMenu);
if($result === false){
$newarr[] = structure($fetchparentMenu);
}
}
//output array
array ( 0 => array ( 'id' => '1', 'item_name' => 'Dashboard', 'menu_type' => 'item', 'parent' => '0', 'expanded' => false, 'childs' => array ( ), ), 1 => array ( 'id' => '2', 'item_name' => 'Admission', 'menu_type' => 'item', 'parent' => '0', 'expanded' => false, 'childs' => array ( ), ), 2 => array ( 'id' => '3', 'item_name' => 'Examination', 'menu_type' => 'item', 'parent' => '0', 'expanded' => false, 'childs' => array ( ), ), 3 => array ( 'id' => '4', 'item_name' => 'CET', 'menu_type' => 'item', 'parent' => '0', 'expanded' => false, 'childs' => array ( ), )
Use following code
$m=0;
if(mysql_num_rows($selectparentMenu)>1) {
while($fetchparentMenu=mysql_fetch_array($selectparentMenu)) {
$parentChildArr[$m][]=$fetchparentMenu['id'];
$parentChildArr[$m][]=$fetchparentMenu['item_name'];
$parentChildArr[$m][]=$fetchparentMenu['menu_type'];
$parentChildArr[$m][]=$fetchparentMenu['parent'];
$m++;
}
I have a relationship where a quote habtm applicants. I am trying to get a quote to save with multiple applicants at once. I already have an array of the applicants I need but I don't know how to format that array to get it to save when I insert it into the quote array.
The applicant array looks like this:
array(
(int) 0 => array(
'Applicant' => array(
'id' => '436',
'clientcase_id' => '66',
'archive_id' => '1',
'birthdate' => '2013-09-21 01:41:00',
'title' => '',
'first_name' => 'george',
'middle_name' => 'a',
'surname' => 'summerlane',
'email' => 'email#q.com',
'landline_number' => '88465120.',
'mobile_number' => '',
'applicant_type' => '',
'created' => '2013-09-21 01:43:10',
'modified' => '2013-09-21 01:43:10'
)
),
(int) 1 => array(
'Applicant' => array(
'id' => '435',
'clientcase_id' => '66',
'archive_id' => '1',
'birthdate' => '2013-09-21 01:41:00',
'title' => '',
'first_name' => 'mary',
'middle_name' => 's',
'surname' => 'amnn',
'email' => 'some#this.cin',
'landline_number' => '465132',
'mobile_number' => '',
'applicant_type' => '',
'created' => '2013-09-21 01:41:48',
'modified' => '2013-09-21 01:41:48'
)
),
(int) 2 => array(
'Applicant' => array(
'id' => '66',
'clientcase_id' => '66',
'archive_id' => '1',
'birthdate' => null,
'title' => null,
'first_name' => 'Tania',
'middle_name' => '',
'surname' => 'Humphreys',
'email' => 'purple67#me.com',
'landline_number' => null,
'mobile_number' => '0438854355',
'applicant_type' => 'Main applicant',
'created' => '2012-10-29 00:00:00',
'modified' => '2012-10-21 00:00:00'
)
)
)
I need one that looks like this:
array(
'Applicants' => array(
'id' => 435,
'id' => 436,
'id' => 66
)
)
How might I go about doing this?
Or is there a better way?
When I save a quote the array looks like this:
array(
'QuoteButton' => 'Submit',
'Quote' => array(
'date' => array(
'day' => '13',
'month' => '10',
'year' => '2013'
),
'description' => '',
'quote_accepted' => '0',
'research_accepted' => '0',
'cc_accepted' => '0',
'pesel_accepted' => '0',
'setfees_accepted' => '0',
'total' => '0'
),
'Applicant' => array(
'id' => '66'
),
How do I insert more than one applicant into the array?
An array can't have the same id, but can crate another array like this:
$datas = array(
(int) 0 => array(
'Applicant' => array(
'id' => '436',
'clientcase_id' => '66',
'archive_id' => '1',
'birthdate' => '2013-09-21 01:41:00',
'title' => '',
'first_name' => 'george',
'middle_name' => 'a',
'surname' => 'summerlane',
'email' => 'email#q.com',
'landline_number' => '88465120.',
'mobile_number' => '',
'applicant_type' => '',
'created' => '2013-09-21 01:43:10',
'modified' => '2013-09-21 01:43:10'
)
),
(int) 1 => array(
'Applicant' => array(
'id' => '435',
'clientcase_id' => '66',
'archive_id' => '1',
'birthdate' => '2013-09-21 01:41:00',
'title' => '',
'first_name' => 'mary',
'middle_name' => 's',
'surname' => 'amnn',
'email' => 'some#this.cin',
'landline_number' => '465132',
'mobile_number' => '',
'applicant_type' => '',
'created' => '2013-09-21 01:41:48',
'modified' => '2013-09-21 01:41:48'
)
),
(int) 2 => array(
'Applicant' => array(
'id' => '66',
'clientcase_id' => '66',
'archive_id' => '1',
'birthdate' => null,
'title' => null,
'first_name' => 'Tania',
'middle_name' => '',
'surname' => 'Humphreys',
'email' => 'purple67#me.com',
'landline_number' => null,
'mobile_number' => '0438854355',
'applicant_type' => 'Main applicant',
'created' => '2012-10-29 00:00:00',
'modified' => '2012-10-21 00:00:00'
)
)
);
$ids = array();
foreach($datas as $data => $applicants) {
$ids[] = $applicants['Applicant']['id'];
}
print_r($ids);
Output:
Array ( [0] => 436 [1] => 435 [2] => 66 )
How to use the ids? Like this:
foreach($ids as $key => $id) {
// do whatever you want with the applicant id
}
like tttony pointed out, array indexes need to be unique so i would:
$ids = array();
foreach($array as $applicant)
$ids[$applicant['Applicant']['id']] = null;
which will output:
Array
(
[436] =>
[435] =>
[66] =>
)
now id is key to $ids array...you could add something else as value rather than null
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.