How to convert Array using CakePHP HASH class? - arrays

I am working on CakePHP. Recently I started using the CakePHP Hash Class. I want to convert an array format using the Hash Class functions.
I have the following array :
$arr = array(
0 => array(
'key1' => array(
'id' => 6
'type' => insert
'field_id' => 2
'activity' => table
),
'key2' => array(
0 => array(
'id' =>
'key1_id' => 6
)
1 => array(
'id' =>
'key1_id' => 6
)
)
)
1 => array(
'key1' => array(
'id' => 5
'type' => edit
'field_id' => 3
'activity' => list
),
'key2' => array(
0 => array(
'id' =>
'key1_id' => 5
)
1 => array(
'id' =>
'key1_id' => 5
)
)
)
2 => array(
'key1' => array(
'id' => 4
'type' => insert
'field_id' => 2
'activity' => table
),
'key2' => array(
0 => array(
'id' =>
'key1_id' => 4
)
)
)
3 => array(
'key1' => array(
'id' => 3
'type' => insert
'field_id' => 3
'activity' => list
),
'key2' => array(
0 => array(
'id' =>
'key1_id' => 3
)
)
)
4 => array(
'key1' => array(
'id' => 2
'type' => edit
'field_id' => 1
'activity' => list
),
'key2' => array(
0 => array(
'id' =>
'key1_id' => 2
)
)
)
5 => array(
'key1' => array(
'id' => 1
'type' => edit
'field_id' => 3
'activity' => list
),
'key2' => array(
0 => array(
'id' =>
'key1_id' => 1
)
)
)
);
The condition is that any key1 having type, field_id and activity exactly will result in all the key2 being merged together and the key1 that occurs later in the list gets unset.
I want to convert it into the following format :
$arr = array(
0 => array(
'key1' => array(
'id' => 6
'type' => insert
'field_id' => 2
'activity' => table
),
'key2' => array(
0 => array(
'id' =>
'key1_id' => 6
)
1 => array(
'id' =>
'key1_id' => 6
)
2 => array(
'id' =>
'key1_id' => 4
)
)
)
1 => array(
'key1' => array(
'id' => 5
'type' => edit
'field_id' => 3
'activity' => list
),
'key2' => array(
0 => array(
'id' =>
'key1_id' => 5
)
1 => array(
'id' =>
'key1_id' => 5
)
2 => array(
'id' =>
'key1_id' => 1
)
)
)
3 => array(
'key1' => array(
'id' => 3
'type' => insert
'field_id' => 3
'activity' => list
),
'key2' => array(
0 => array(
'id' =>
'key1_id' => 3
)
)
)
4 => array(
'key1' => array(
'id' => 2
'type' => edit
'field_id' => 1
'activity' => list
),
'key2' => array(
0 => array(
'id' =>
'key1_id' => 2
)
)
)
);
If you have a look key2 value for key '2' is merged with key '0' and '2' is unset.
The missing key values should basically be unset. I want to know the best possible way in which I can attain this format for the array.

What you are trying to do it's bit tricky. I recommend to achieve this by trying with some different CakePHP sql query.
Solution
$keys = Hash::extract($arr, '{n}.key1.field_id');
$vals = Hash::extract($arr, '{n}');
$result = $this->array_combine_($keys, $vals);
function array_merge_multiple(&$v) {
$z1 = array();
$z2 = array();
$len = count($v);
for ($i = 0; $i < $len; $i++) {
if ($i < ($len - 1)) {
$z1 = array_merge($v[$i]['key2'], $v[$i + 1]['key2']);
$z2 = array_merge($v[$i]['key1'], $v[$i + 1]['key1']);
} else if($len==1){
$z1 = $v[$i]['key2'];
$z2 = $v[$i]['key1'];
}
unset($v[$i]);
}
$v['key1'] = $z1;
$v['key2'] = $z2;
}
/* Modified array_combine function ( Hash::combine uses array_combine internally */
function array_combine_($keys, $values) {
$result = array();
foreach ($keys as $i => $k) {
$result[$k][] = $values[$i];
}
array_walk($result, 'array_merge_multiple');
return $result;
}

Related

How to get rid of null associated model in cakephp 2.x

I am trying to get the item types that Order.Item.ItemType.show_type = 1. I have written the query but I want to show only Items that their ItemType.show_type = 1 not all items.
$brief = $this->Order->find('first', array(
'fields' => array(
'Order.*'
),
'conditions' => array(
'Order.order_id' => $orderId,
),
'contain' => array(
'Item' => array(
'fields' => array(
'Item.*', 'CHAR(64 + Item.num) AS letter'
),
'conditions' => array(
'Item.deleted' => 0,
),
'ItemType' => array(
'conditions' => array(
'ItemType.show_type' => 1
),
)
),
)
));
The query shouldn't show Item id = 25741
Associations:
// Order
public $hasMany = array(
'BriefInstalment' => array(
'foreignKey' => 'order_id'
)
);
// Item Model
public $belongsTo = array(
'Order',
'ItemType' => array(
'type' => 'inner'
)
);
// ItemType Model
public $hasMany = array('Item');
Print:
array(
'Order' => array(
'order_id' => '67817',
'service' => '',
),
'Item' => array(
(int) 0 => array(
'id' => '25741',
'order_id' => '67817',
'num' => '2',
'item_type_id' => '8',
'name' => '3-5 titles active',
'deleted' => false,
'ItemType' => array(), // <= how to remove this empty model
'Item' => array(
(int) 0 => array(
'letter' => 'B'
)
)
),
(int) 1 => array(
'id' => '25742',
'order_id' => '67817',
'num' => '3',
'item_type_id' => '2',
'name' => '1,000 pro active',
'deleted' => false,
'ItemType' => array(
'id' => '2',
'name' => 'Part Instalment',
'show_type' => true,
'deleted' => false
),
'Item' => array(
(int) 0 => array(
'letter' => 'C'
)
)
)
)
)
This could not be done using Countaible behaviour, but iwth the joins method, set the recursive to -1
$brief = $this->Order->find('first', array(
'recursive' => -1,
'fields' => array(
'Order.*'
),
'conditions' => array(
'Order.order_id' => $orderId,
),
'joins' => array(
array(
'table' => 'items',
'alias' => 'Item',
'type' => 'inner',
'conditions' => array(
'Order.id = Item.order_id'
)
),
array(
'table' => 'item_types',
'alias' => 'ItemType',
'type' => 'inner',
'conditions' => array(
'ItemType.id = Item.item_type_id'
)
),
)
));
You have to check if the table names are correct and also the foreign keys names.
Another solution would be to go through your results, and unset the empty ones
foreach($brief as $k => $v){
foreach($v['Item'] as $kk => $vv){
if(empty($vv['ItemType'])){
unset($brief[$k]['Item'][$kk];
}
}
}
debug($brief);

CakePHP 2.x retriving data with i18n in a loop

I'm looping trough Features (belongTo FeatureType) and find() FeatureType.name for each Feature.feature_type_id.
I'm getting first record correct (with i18n translation) but in all the rest the i18n translation is not in place, but given as separate record.
What I am doing wrong?
this is the debug of my result table:
array(
'FeatureType' => array(
'id' => '28',
'name' => 'kolor suwaka',
'comment' => 'kolor suwaka etui notebook',
'locale' => 'pol'
)
)
array(
'FeatureType' => array(
'id' => '7',
'name' => '',
'comment' => '',
'locale' => 'pol'
),
(int) 0 => array(
'FeatureType__i18n_name' => 'kolor materiału',
'FeatureType__i18n_comment' => 'gra w klasy'
)
)
array(
'FeatureType' => array(
'id' => '11',
'name' => '',
'comment' => '',
'locale' => 'pol'
),
(int) 0 => array(
'FeatureType__i18n_name' => 'kolor',
'FeatureType__i18n_comment' => 'kółko i krzyżyk (jasnoszare i ciemnoszare)'
)
)
array(
'FeatureType' => array(
'id' => '27',
'name' => '',
'comment' => '',
'locale' => 'pol'
),
(int) 0 => array(
'FeatureType__i18n_name' => 'obwód głowy',
'FeatureType__i18n_comment' => 'rozmiar kapelusza czarownicy'
)
)
This is the code:
$features_str = "";
if (!empty($product['Features'])) {
foreach ($product['Features'] as $featureIndex => $feature) {
$featureTypeModel = new FeatureType();
$feature_type = $featureTypeModel->find("first", array("conditions" => array("FeatureType.id" => $feature['feature_type_id'])));
if (strlen($features_str) > 0) $features_str .= ", ";
$features_str .= $feature_type['FeatureType']['name'] . ': ' . $feature['name'];
unset($featureTypeModel);
}
}

find by conditions with 'members'

I have 3 model:
Association HasMany Service
Service HasBelongs Association and HasMany Member
Member HasBelongs Service
I want find member by association but I find Service by association.
$associations = $this->Member->Service->Association->find('all',
array(
'fields'=>array('id','libelle')
));
the result debug is:
array(
(int) 0 => array(
'Association' => array(
'id' => '1',
'libelle' => 'الادارة العامة للصحة العسكرية'
),
'Service' => array(
(int) 0 => array(
'id' => '1',
'libelle' => 'Divers',
'association_id' => '1'
),
(int) 1 => array(
'id' => '2',
'association_id' => '1'
),
(int) 2 => array(
'id' => '3',
'libelle' => 'مكتب الضبط BO',
'association_id' => '1'
)
)
),
(int) 1 => array(
'Association' => array(
'id' => '2',
'libelle' => 'أعضاء الديوان والمديرين'
),
'Service' => array()
),
(int) 2 => array(
'Association' => array(
'id' => '3',
'libelle' => 'المستشفات والمراكز والمصحات '
),
'Service' => array()
),
(int) 3 => array(
'Association' => array(
'id' => '4',
'libelle' => 'المستشفى العسكري الاصلي للتعليم '
),
'Service' => array()
)
I want find the member by association example: all member that belong to the Association الادارة العامة للصحة العسكرية ie all members of the services 1, 2, 3
You can use 'contain' to do that.
There are some examples in the book: http://book.cakephp.org/2.0/en/core-libraries/behaviors/containable.html

Saving many datas HasMany trough

I want to save 2+ datas in a model hasMany trough. But this is not saving.
$data[] = array('User' => array('id' => 5), 'Solicitation' => array('id' => $this->Solicitation->id));
$data[] = array('User' => array('id' => 6), 'Solicitation' => array('id' => $this->Solicitation->id));
debug($data);
$this->SolicitationUser->saveAll($data);
Result of debug($data)
array(
(int) 0 => array(
'User' => array(
'id' => (int) 5
),
'Solicitation' => array(
'id' => '70'
)
),
(int) 1 => array(
'User' => array(
'id' => (int) 6
),
'Solicitation' => array(
'id' => '70'
)
)
)
It's hard to tell what you're going after, since there's little description, but I assume you'd want it more like this to save two rows in your HasMany Through table:
array(
(int) 0 => array(
'user_id' => (int) 5
'solicitation_id' => '70'
),
(int) 1 => array(
'user_id' => (int) 6
'solicitation_id' => '70'
)
)

Create a hierarchy from an array

I've an array as follows.
array(
0 => array(
'parent' => 'Bigboss',
'middle' => 'Technicians',
'child' => 'Players'
),
1 => array(
'parent' => 'Company',
'middle' => 'Manager',
'child' => 'Employees'
),
2 => array(
'parent' => 'Bigboss',
'middle' => 'Manager',
'child' => 'Workers'
),
3 => array(
'parent' => 'Company',
'middle' => 'Techinical Lead',
'child' => 'Employees'
),
4 => array(
'parent' => 'Bigboss',
'middle' => 'Workers',
'child' => 'Employees'
)
);
I want this array in hierarchy way like
parent
=> middle
=> child
parent
=> middle
=> child
Exactly like as follows.
array(
'Biggboss' => array(
'Technicians' => array(
0 => 'Players'
),
'Manager' => array(
0 => 'Workers'
),
'Workers' => array(
0 => 'Employees'
)
),
'Company' => array(
'Manager' => array(
0 => 'Employees'
),
'Techinical Lead' => array(
0 => 'Employees'
)
)
);
if anyone could solve it would be more appreciated.
I believe this works...
$input = array(
0 => array(
'parent' => 'Bigboss',
'middle' => 'Technicians',
'child' => 'Players'
),
1 => array(
'parent' => 'Company',
'middle' => 'Manager',
'child' => 'Employees'
),
2 => array(
'parent' => 'Bigboss',
'middle' => 'Manager',
'child' => 'Workers'
),
3 => array(
'parent' => 'Company',
'middle' => 'Techinical Lead',
'child' => 'Employees'
),
4 => array(
'parent' => 'Bigboss',
'middle' => 'Workers',
'child' => 'Employees'
)
);
$output = array();
foreach($input as $key => $value){
if(!isset($output[$value['parent']])){
$output[$value['parent']] = array();
}
$output[$value['parent']][$value['middle']] = array($value['child']);
}
print_r($output);
If you want to allow multiple values in the last dimension then change:
$output[$value['parent']][$value['middle']] = array($value['child']);
to
$output[$value['parent']][$value['middle']][] = $value['child'];

Resources