Cakephp Mongodb Print array, within array, within array, using nested forloops - php

The goal is to print out data from my database, through my view.ctp file, and be able to view it in my local host.
Here's the data I am working with:
array(
'DataWriteError' => array(
'modified' => object(MongoDate) {
sec => (int) 1507762384
usec => (int) 402000
},
'created' => object(MongoDate) {
sec => (int) 1507762384
usec => (int) 402000
},
'errors' => array(
(int) 0 => array(
'index' => (int) 13370,
'code' => (int) 11000,
'message' => 'E11000 duplicate key error index: live_system.599c4ec3-0e24-408d-b8a6-067445404121.$Refcode_1 dup key: { : "VA1394315696" }'
),
(int) 1 => array(
'index' => (int) 14987,
'code' => (int) 11000,
'message' => 'E11000 duplicate key error index: live_system.599c4ec3-0e24-408d-b8a6-067445404121.$Refcode_1 dup key: { : "VA1394315697" }'
)
),
'campaign_id' => '59dea09d103fb4cb428fdef2',
'id' => '59dea0d0bed1ec43d21cf65b'
)
)
I have everything else displayed other than ERRORS. Errors has two arrays within it and I cannot for the life of me figure out where my code is wrong.
Here is my code to echo to view:
<td><?php foreach ($this->request->data['DataWriteError']['errors'] as $i => $item);
foreach ($item as $e => $etem) {
echo $this->request->data['DataWriteError']['errors']['index']['errors']['message'][$i];
echo $this->request->data['DataWriteError']['errors']['index']['code']['message'][$e];
} ?></td>
Not sure where I am going wrong. If there are any ideas, please let me know. Thanks!

Have you tried blow:
foreach ($this->request->data['DataWriteError']['errors'] as $i => $item) {
echo $item['message'];
}

Related

How can I update value in the array by a condition on the php?

I have alt array like this :
$alt = array('chelsea', 'mu', 'arsenal');
I have photoList array like this :
$photoList = array(
array(
'id' => 1,
'name' => 'chelsea.jpg',
'alt' => ''
),
array(
'id' => 2,
'name' => 'mu.jpg',
'alt' => ''
),
array(
'id' => 3,
'name' => 'arsenal.jpg',
'alt' => ''
)
);
I want to check a condition
If index plus 1 in the alt array same with id in the photoList array, it will update alt in the photoList array with value of alt array by index plus 1
I try like this :
foreach($photoList as $key1 => $value1) {
foreach ($alt as $key2 => $value2) {
if($value1['id'] == $key2+1)
$value1['alt'] = $value2;
}
}
Then I check with :
echo '<pre>';print_r($photoList);echo '</pre>';
The alt is still empty. It does not update
I hope the result like this :
photoList = array(
array(
'id' => 1,
'name' => 'chelsea.jpg',
'alt' => 'chelsea'
),
array(
'id' => 2,
'name' => 'mu.jpg',
'alt' => 'mu'
),
array(
'id' => 3,
'name' => 'arsenal.jpg',
'alt' => 'arsenal'
)
);
How can I do it?
You have to use the vars ($value1) by reference:
// THIS & is the trick
foreach($photoList as $key1 => &$value1) {
foreach ($alt as $key2 => $value2) {
if($value1['id'] == $key2+1)
$value1['alt'] = $value2;
}
}
Without that you work with an 'internal copy' of the sub-item $value1, so $photoList doesn't get updated.
A better approach will be to do that:
foreach($photoList as $key => $value)
$photoList[$key]['alt'] = $alt[$key];
This way round you use only one loop. Also, what's wrong with your original loop is that you are assigning the value to the temporary variable inside the loop. This is not affecting the array you are looping over.
EDIT:
I just figured out that you do not need to care about $photoList[$key]['id'] at all. It's irrelevant in this example as the order of the elements is the same in both arrays.

Recursive(?) algorithm design

I have a requirement to allow my end users to input formula much like a spreadsheet. I have an array like this:
$table = array(
1=>array(
"id"=>1,
"Name"=>"Regulating",
"Quantity"=>"[2]Quantity+[3]Value",
"Value"=>"[2]Cost"
),
...)
The first level array key is always the same value as the id key in that array.
A tabulated example follows:
id Name Quantity Value
1 Regulating [2]Quantity+[3]Value [2]Cost
2 Kerbs 3 6
3 Bricks 9 7
4 Sausages [3]Cost 3
5 Bamboo [4]Quantity [7]Cost
6 Clams [4]Quantity NULL
7 Hardcore [3]Quantity*0.5 12
8 Beetles [6]Quantity*[4]Value [2]Value
The Quantity and Value keys represent formula which reference the [id] and either Quantity, Value or Cost.
Cost is derived by multiplying the Value and Quantity.
I am using:
preg_match_all("/\[(.*?)\]([A-Z]*[a-z]*)/", $string, $matches, PREG_SET_ORDER);
which outputs an array like so for[1][Quantity]:
Array
(
[0] => Array
(
[0] => [2]Quantity
[1] => 2
[2] => Quantity
)
[1] => Array
(
[0] => [3]Value
[1] => 3
[2] => Value
)
)
Iterating through the table using something similar to:
$calcString = $table[1]['Quantity'];`
foreach ($matches as $match) {
$calcString = str_replace($match[0], $table[$match[1]][$match[2]], $calcString);
}
I can get the string to be calculated and am using a matheval class to do the sum.
For example
[1]Quantity = [2]Quantity + [3]Value
[2]Quantity = 3
[3]Value = 7 // [1]Quantity = 3 + 7 = 10
[1]Value = [2]Cost
[2]Cost = [2]Quantity * [2]Value // 3 * 6 = 18
Basically the variables in the table refer to other [id]key in the same table.
But here is my issue
I need to resolve references to other parts of the table (which may or may not themselves be formula) to fill in the blanks. This is outside my comfort zone and I would appreciate any advice (or even better functional code) which provides enlightenment on how I might be able to achieve this.
Thanks
Deep down, you already know how to solve this, you're just intimidated by the task.
A recursive approach would be to expand references instantly. For example,
expand('[1]Value') # returns '[2]Cost'
expand('[2]Cost') # returns '[2]Quantity * [2]Value'
expand('[2]Quantity') # returns 3
expand('[2]Value') # returns 6
eval('3 * 6')
# returns 18
# returns 18
# returns 18
An iterative (non-recursive) approach is to expand one reference at a time and repeat until there are unresolved references in the string.
expand('[1]Value') // returns '[2]Cost'
expand('[2]Cost') // returns '[2]Quantity + [2]Value'
expand('[2]Quantity + [2]Value') // returns 3 for [2]Quantity
expand('3 * [2]Value') // returns 6 for [2]Value
eval('3 * 6')
# returns 18
Normally, I prefer iterative solutions, because they're much less prone to stack overflows. However, recursive solutions are usually easier to write.
Here's a quickly slapped-together recursive evaluator: https://gist.github.com/stulentsev/b270bce4be67bc1a96ae (written in ruby, though)
If calcString's are reasonably sized and you don't expect replacements to get too elaborate, you could use a while loop to simulate the recursion. Here's an example that outputs the string along the way as it is being modified:
$calcString = $table[8]['Quantity'];
preg_match_all("/\[(.*?)\]([A-Z]*[a-z]*)/", $calcString, $matches, PREG_SET_ORDER);
print_r($calcString . "\n");
while (!empty($matches)){
foreach ($matches as $match) {
preg_match_all("/\[(.*?)\](Cost)/", $match[0], $matchCost, PREG_SET_ORDER);
if (!empty($matchCost)){
$cost = $table[$matchCost[0][1]]['Quantity'] . "*" . $table[$matchCost[0][1]]['Value'];
$calcString = str_replace($match[0], $cost, $calcString);
} else {
$calcString = str_replace($match[0], $table[$match[1]][$match[2]], $calcString);
}
print_r($calcString . "\n");
}
preg_match_all("/\[(.*?)\]([A-Z]*[a-z]*)/", $calcString, $matches, PREG_SET_ORDER);
}
Output:
[6]Quantity*[4]Value
[4]Quantity*[4]Value
[4]Quantity*3
[3]Cost*3
9*7*3
The table variable:
$table = array(
1 => array(
"id" => 1,
"Name" => "Regulating",
"Quantity" => "[2]Quantity+[3]Value",
"Value" => "[2]Cost"
),
2 => array(
"id" => 2,
"Name" => "Kerbs",
"Quantity" => 3,
"Value" => 6
),
3 => array(
"id" => 3,
"Name"=>"Bricks",
"Quantity"=> 9,
"Value"=> 7
),
4 => array(
"id" => 2,
"Name" => "Sausages",
"Quantity" => "[3]Cost",
"Value" => 3
),
5 => array(
"id" => 2,
"Name" => "Bamboo",
"Quantity" => "[4]Quantity",
"Value" => "[7]Cost"
),
6 => array(
"id" => 2,
"Name" => "Clams",
"Quantity" => "[4]Quantity",
"Value" => NULL
),
7 => array(
"id" => 2,
"Name" => "Hardcore",
"Quantity" => "[3]Quantity*0.5",
"Value" => 12
),
8 => array(
"id" => 2,
"Name" => "Beetles",
"Quantity" => "[6]Quantity*[4]Value",
"Value" => "[2]Value"
)
);
A dangerously easy, and your-situation-specific well-performable solution!
<?php
class solver {
private
// The final output array
$arr_evaled,
// When a cell gains its final value, the corresponding entry in the following array gets marked as being done!
$arr_done;
private $solving_iterations_count;
public function solver($array) {
$this->arr_done = array();
foreach($array as $k => $arr)
$this->arr_done[$k] = array('Quantity' => false, 'Value' => false);
// Firstly,expand all of the "[x]Cost"s to "([x]Quantity*[x]Value)"s!
$this->arr_evaled = array_map(
function($v){ return preg_replace('#\[(\d*?)\]Cost#', '([$1]Quantity*[$1]Value)', $v); },
$array
);
$this->solving_iterations_count = 0;
$this->solve();
}
private function isDone() {
foreach($this->arr_done as $a)
if($a['Quantity'] == false || $a['Value'] == false)
return false;
return true;
}
private function isCellDone($id, $fieldName) {
return $this->arr_done[$id][$fieldName];
}
private function markCellAsDone($id, $fieldName, $evaluation) {
$this->arr_done[$id][$fieldName] = true;
$this->arr_evaled[$id][$fieldName] = $evaluation;
}
private function isEvaluable($str) {
return preg_match('#^[0-9*+-\/\(\)\.]*$#', $str) == 1 || strtolower($str)=='null';
}
private function replace($from, $to) {
foreach($this->arr_evaled as &$arr) {
$arr['Quantity'] = str_replace($from, $to, $arr['Quantity']);
$arr['Value'] = str_replace($from, $to, $arr['Value']);
}
}
private function solve() {
$isSolvable = true; // YOUR TODO: I believe coding this part is also fun!) (e.g: check for "reference cycles")
if(!$isSolvable) return null;
while( !$this->isDone() )
{
foreach($this->arr_evaled as $arr) {
foreach(['Quantity', 'Value'] as $fieldName) {
if(!$this->isCellDone($arr['id'], $fieldName)) {
if($this->isEvaluable($arr[$fieldName])) {
$evaluation = eval("return {$arr[$fieldName]};");
$this->markCellAsDone($arr['id'], $fieldName, $evaluation);
$this->replace("[{$arr['id']}]$fieldName", "$evaluation");
}
}
}
}
$this->solving_iterations_count++;
}
foreach($this->arr_evaled as &$row)
$row['Cost'] = $row['Quantity'] * $row['Value'];
return $this->arr_evaled;
}
public function print_tabulated() {
echo "The count of solving iterations: {$this->solving_iterations_count}<br/><br/>";
echo '<table border="1"><tr><th>id</th><th>Name</th><th>Quantity</th><th>Value</th><th>Cost</th></tr>';
foreach($this->arr_evaled as $arr)
echo "<tr><td>{$arr['id']}</td><td>{$arr['Name']}</td><td>{$arr['Quantity']}</td><td>{$arr['Value']}</td><td>{$arr['Cost']}</td></tr>";
echo '</table>';
}
}
// Testing
$arr = array(
1 => array( 'id' => 1, 'Name' => 'Regulating', 'Quantity' => '[2]Quantity+[3]Value', 'Value' => '[2]Cost' ),
2 => array( 'id' => 2, 'Name' => 'Kerbs', 'Quantity' => '3', 'Value' => '6' ),
3 => array( 'id' => 3, 'Name' => 'Bricks', 'Quantity' => '9', 'Value' => '7' ),
4 => array( 'id' => 4, 'Name' => 'Sausages', 'Quantity' => '[3]Cost', 'Value' => '3' ),
5 => array( 'id' => 5, 'Name' => 'Bamboo', 'Quantity' => '[4]Quantity', 'Value' => '[7]Cost' ),
6 => array( 'id' => 6, 'Name' => 'Clams', 'Quantity' => '[4]Quantity', 'Value' => 'NULL' ),
7 => array( 'id' => 7, 'Name' => 'Hardcore', 'Quantity' => '[3]Quantity*0.5', 'Value' => '12' ),
8 => array( 'id' => 8, 'Name' => 'Beetles', 'Quantity' => '[6]Quantity*[4]Value', 'Value' => '[2]Value' ),
);
echo '<pre>';
(new solver($arr))->print_tabulated();
Here is the output:

PHP - Get key from another key value through a multi dimensional array

I have the following multidimensional array that is obtained through an API.
$exchangeID = array(
0 => array(
'id' => 'vcxz',
'currency' => 'GBP',
),
1 => array(
'id' => 'mnbv',
'currency' => 'EUR',
),
2 => array(
'id' => 'lkjh',
'currency' => 'USD',
),
3 => array(
'id' => 'poiuy',
'currency' => 'KRN',
),
);
I would like to obtain the id of USD which is lkjh. I know this can be obtained by simply doing $exchangeID[2]['id']. The problem is that the array is dynamic. For example when it is loaded the first subarray may be EUR instead of GBP, and the third subarray may be KRN instead of USD.
Basically, what I have in mind is to look for the subarray where there is the currency first, then accordingly find the corresponding id. E.g. if I want to find EUR. First I find the EUR, then get 'mnbv'.
I tried this $key = array_search('USD', array_column($exchangeID, 'currency')); but I got the following error in my error_log PHP Fatal error: Call to undefined function array_column() to get at least the array number e.g. in this case 2.
You can simply filter your array, like this:
$usd_exchanges = array_filter($exchangeID, function($row) {
return $row['currency'] == "USD";
}));
var_dump($usd_exchanges[0]);
You can also return the first element of the filter, using the current method:
$usd_exchange = current(array_filter($exchangeID, function($row) {
return $row['currency'] == "USD";
})));
var_dump($usd_exchange);
Try this:
foreach ($exchangeID as $key => $arr)
if($arr['currency'] == 'USD')
echo $key;
It is possible to use following custom function to get the key:
echo getKeyRecursive('USD', $exchangeID);
function getKeyRecursive($needle, $haystack, $strict = false)
{
foreach ($haystack as $key => $item){
if(($strict ? $item === $needle : $item == $needle) || (is_array($item) && getKeyRecursive($needle, $item, $strict))) return $key;
}
return false;
}
foreach($exchangeID as $key=>$value)
{
if($exchangeID[$key]['currency']=='USD'){
$usdId=$exchangeID[$key]['id'];
break;
}
}
//echo $usdId;
//Result:ikjh
<?php
$exchangeID = array(
0 => array(
'id' => 'vcxz',
'currency' => 'GBP',
),
1 => array(
'id' => 'mnbv',
'currency' => 'EUR',
),
2 => array(
'id' => 'lkjh',
'currency' => 'USD',
),
3 => array(
'id' => 'poiuy',
'currency' => 'KRN',
),
);
$db=new PDO('sqlite::memory:','','',array(PDO::ATTR_EMULATE_PREPARES => false, PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION));
$db->query('CREATE TABLE `troll` (`dbid` TEXT, `dbcurrency` TEXT);');
$stm=$db->prepare("INSERT INTO `troll` (`dbid`,`dbcurrency`) VALUES(:id,:currency);");
array_walk($exchangeID,function($arr)use($stm){$stm->execute($arr);});
$res=$db->query("SELECT `dbid` AS `id` FROM `troll` WHERE `dbcurrency` = ".$db->quote('USD').' LIMIT 1');
$id=$res->fetch(PDO::FETCH_ASSOC);
$id=$id['id'];
var_dump($id);
see working example here http://codepad.viper-7.com/1lg2Gj
Try this if this works:
foreach($exchangeID as $key => $val)
{
if(array_key_exists('currency', $val))
if($val['currency'] == 'USD'){
echo $val['id'];
echo $val['currency'];
elseif($val['currency'] == 'GBP'){a1
echo $val['id'];
echo $val['currency']);
elseif($val['currency'] == 'EUR'){
echo $val['id'];
echo $val['currency'];
}else{
echo $val['id'];
echo $val['currency'];
}
}
}

unable to delete array key from multidimensional array in cakephp

I want to delete array index which contain rating 0 here is my array
array(
(int) 0 => array(
'Gig' => array(
'id' => '1',
'rating' => (int) 5
)
),
(int) 1 => array(
'Gig' => array(
'id' => '3',
'rating' => (int) 9
)
),
(int) 2 => array(
'Gig' => array(
'id' => '4',
'rating' => '0'
)
)
)
and what I did
for($i = 0; $i<count($agetGigsItem); $i++)
{
if($agetGigsItem[$i]['Gig']['rating']==0)
{
unset($agetGigsItem[$i]);
}
$this->set('agetGigsItem', $agetGigsItem);
}
i also try foreach loop but unable to resolve this issue.
foreach ($agetGigsItem as $key => $value) {
if ($value["Gig"]["rating"] == 0) { unset($agetGigsItem[$key]); }
}
I think you need to reupdate your array.
foreach ($agetGigsItem as $key => $value) {
if ($value["Gig"]["rating"] != 0)
{
unset($agetGigsItem[$key]);
}
$this->set('agetGigsItem', $agetGigsItem);
}
I hope you are missing $this and so you cannot access the array in CakePHP.
So try this:
foreach ($this->$agetGigsItem as $key => $value) {
if ($value["Gig"]["rating"] == 0) {
unset($this->$agetGigsItem[$key]);
}
}
This code will unset arrey index with value 0.
<?php
$array=array(
array(
'Gig' => array(
'id' => '1',
'rating' =>5
)
),
array(
'Gig' => array(
'id' => '3',
'rating' =>9
)
),
array(
'Gig' => array(
'id' => '4',
'rating' =>0
)
)
);
foreach($array as $a){
if($a['Gig']['rating']==0){
unset($a['Gig']['rating']);
}
$array1[]=$a;
}
var_dump($array1);
Destroying occurances within an array you are actually processing over with a for or a foreach is always a bad idea. Each time you destroy an occurance the loop can easily get corrupted and get in a terrible mess.
If you want to remove items from an array it is better to create a copy of the array and process over that new array in the loop but remove the items from the original array.
So try this instead
$tmparray = $this->agetGigsItem; // will copy agetGigsItem into new array
foreach ($tmparray as $key => $value) {
if ($value["Gig"]["rating"] == 0) {
unset($this->agetGigsItem[$key]);
}
}
unset($tmparray);

Recursive function returning false

I have no idea why this keeps returning false.
The best part is at the echo statements it actually echo's. This function is in a plugin that I am writing for WordPress.
function find_field($field_name,$array) {
if(array_key_exists($field_name,$array)) {
echo 'Here';
echo $array[$field_name];
return $array[$field_name];
}
foreach($array as $value) {
if(is_array($value)) {
find_field($field_name,$value);
}
}
return false;
}
If I run this: echo find_field('cellphone_number',$arr);
And this is my $arr:
array(
'page' => 'wp_crm_add_new',
'wp_crm' => array(
'user_data' => array(
'user_id' => array(
(int) 0 => array(
'value' => ''
)
),
'user_pass' => array(
(int) 1428 => array(
'value' => ''
)
),
'role' => array(
(int) 2718 => array(
'value' => ''
)
),
'display_name' => array(
(int) 14454 => array(
'value' => 'Albert'
)
),
'user_email' => array(
(int) 26059 => array(
'value' => 'albert#domain.com'
)
),
'company' => array(
(int) 85772 => array(
'value' => ''
)
),
'cellphone_number' => array(
(int) 62506 => array(
'value' => '0820000000'
)
),
'last_visit' => array(
(int) 45073 => array(
'value' => ''
)
)
)
),
'meta-box-order-nonce' => '1374268beb',
'closedpostboxesnonce' => '92fffdd685',
'wp_crm_update_user' => '42d35393d7',
'show_admin_bar_front' => 'false',
'color-nonce' => 'c02f4b0a88',
'admin_color' => 'sunrise',
'original_publish' => 'Publish',
'publish' => 'Save'
)
I get false as the result, every time. What am I doing wrong?
This is happening because you return false. Here's the logic break-down:
function find_field($field_name,$array) {
if(SOMETHING) {
DO SOMETHING
return SOMETHING;
}
foreach($array as $value) {
if(SOMETHING) {
CALL RECURSIVE FUNCTION
}
}
return false;
}
Put like this... if you call the function at any point and send a value that passes the first if statement, then you return a value. If you do not pass that if statement (aka the array_key doesn't exist) then you move into a foreach loop, which does some stuff, calls a recursive function which eventually returns a value (and does nothing with it) before moving on to the final line of code... return false.
It is important to first think of a recursive function as a one-time function before compounding it into a recursive one.
Just like any other function, this recursive function is going to execute every line of code (although interrupted) before it is done. The last line of code you execute is always a "return false" which is throwing your result.
Perhaps you should be returning the inner foreach loop value when you call the recursive function:
function find_field($field_name,$array) {
if(array_key_exists($field_name,$array)) {
echo 'Here';
echo $array[$field_name];
return $array[$field_name];
}
foreach($array as $value) {
if(is_array($value)) {
return find_field($field_name,$value);
}
}
return false;
}

Categories