HTML input array name coming through as a string - php

I have an input checkbox field as follows:
<input type="checkbox" name="group_items[<?=$item_id?>][<?=$group_id?>]" value="1" />
There are several of these in a matrix grid. On submission, it should post something like this:
(array) Array
(
[1] => Array
(
[1] => 1
[3] => 1
[5] => 1
[9] => 1
[13] => 1
[15] => 1
)
[2] => Array
(
[1] => 1
[3] => 1
[5] => 1
[9] => 1
[13] => 1
[15] => 1
)
[3] => Array
(
[2] => 1
[4] => 1
[8] => 1
[10] => 1
[14] => 1
)
[4] => Array
(
[2] => 1
[4] => 1
[8] => 1
[10] => 1
[14] => 1
)
)
Most of the time, this seems to be okay.
I then run this:
if(!empty($_POST['group_items']))
{
foreach($_POST['group_items'] as $item_id => $item_groups)
{
$group_ids = array_keys($item_groups);
foreach($group_ids as $group_id)
{
// do something
}
}
}
However, on occassion, I get this error:
Uncaught PHP Error: array_keys() expects parameter 1 to be array, string given
It's as though it's posting this:
(array) Array
(
[1] => (string)
)
I am well aware that I can perform an is_array check on $item_groups, however I need to understand how this can even be a string instead of an array.
I am also aware that I could change the values from 1 to be what the key is currently set to, and have a zero-based index, like this:
(array) Array
(
[1] => Array
(
[0] => 1
[1] => 3
[2] => 5
[3] => 9
[4] => 13
[5] => 15
)
)
However this would not do anything to resolve the issue of the value of [1] being a string instead of an array.
I'm also unable to log out the post data as a client has lost data due to this error and logging the post to see what it contains would risk them losing more data. This is also why an is_array check is not the solution as it would mean the posted data has still somehow been lost and doesn't solve the actual cause.
I have checked the server limits for the maximum number of fields that can be posted and it is high enough; I can submit hundreds of checkboxes and they come through fine. This also seems to be an intermittent error and can work as expected deveral times, and then cause the error the next.
Does anybody have any suggestions on a cause?
Edit: Have now got a dump of the data when it errors.
(array) Array
(
[0] => 1
)

Related

PHP Array delete an entire array by one element value

So this is how my Array ($dataArray) looks oks like:
Array
(
[0] => Array
(
[0] => Date
[1] => Time
[2] => Duration
[3] => Info
[4] => Client
)
[1] => Array
(
[0] => 2021-12-01
[1] => 10:45:43
[2] => 237
[3] => Some text from
[4] => Client 1
)
[2] => Array
(
[0] => 2021-12-01
[1] => 11:29:13
[2] => 77
[3] => Nothing important
[4] => Client 2
)
[3] => Array
(
[0] => 2021-12-01
[1] => 11:53:03
[2] => 44
[3] => anonymous
[4] => Client 1
)
I need to Loop trough it to search the Client Names, and if i find the matching name in the Element 4 then delete the entire Array.
$ExportKDname = "Client 1"
foreach($dataArray as $key => $sub_array) {
if($sub_array[4] == $ExportKDname) {
unset($dataArray[$key]);
break;
}
}
print_r($dataArray);
But with this code none of the arrays will be deleted. And I just can not find the right way to do it.
The Final array what I need to look like if we find the "Client 1" in the array would be like this:
Array
(
[0] => Array
(
[0] => Date
[1] => Time
[2] => Duration
[3] => Info
[4] => Client
)
[1] => Array
(
[0] => 2021-12-01
[1] => 11:29:13
[2] => 77
[3] => Nothing important
[4] => Client 2
)
In the if condition you are saying "if u match with $sub_arr[4] == $ExportKDname unset it and stop the loop". the machine doing that. when it matched first time it removes and stoping. If u wanna delete all match do not write break; let it continue. So delete or make it comment break; line.
You can array_filter your variable and check if value is in_array.
With PHP 7.4+ syntax it should look like this:
$result = array_filter($dataArray, fn ($innerArray) => !in_array('Client 1', $innerArray));

Get value multidimensional array and combine product group

I have created a multidimensional array using a csv file.
I get the following array:
Array
(
[0] => Array
(
[0] => Product
[1] => Price
[2] => Quantity
[3] => Date
)
[1] => Array
(
[0] => Teddybear
[1] => 3.789,33
[2] => 2
[3] => 2018-08-14
)
[2] => Array
(
[0] => Teddybear
[1] => 2.702,17
[2] => 1
[3] => 2018-02-17
)
[3] => Array
(
[0] => Table
[1] => 2.932,29
[2] => 5
[3] => 2018-10-09
)
[4] => Array
(
[0] => Lamp
[1] => 671,70
[2] => 3
[3] => 2018-12-11
)
[5] => Array
(
[0] => Teddybear
[1] => 481,21
[2] => 3
[3] => 2018-03-24
)
[6] => Array
(
[0] => Table
[1] => 456,52
[2] => 3
[3] => 2018-05-14
)
[7] => Array
(
[0] => Chair
[1] => 2.960,20
[2] => 2
[3] => 2018-06-20
)
[8] =>
)
I need to create a json file, but before that, I need to count al products and turnover per month
I'm a novice / junior PHP developer and I'm more specialized in WordPress, so forgive me for my bad code and/or bad practices. I'm here to learn.
I really don't know how to select for example all the Teddybears. I know I could do $csv[1][1]; to select turnover for the first Tedybear.
ok here there should be everything you need, I did 3 functions that you can chain together to get what you need, like in the example
$data=[
["Product","Price","Quantity","Date"], // <-- if you want to remove the header remove all the lines with this symbol *
["Teddybear",3789.33,2,"2018-08-14"],
["Teddybear",2702.17,1,"2018-02-17"],
["Table",2932.29,5,"2018-10-09"],
["Lamp",671.70,3,"2018-12-11"],
["Teddybear",481.21,3,"2018-03-24"],
["Table",45.52,3,"2018-05-14"],
["Chair",2960.20,2,"2018-06-20"]
];
function WhereFromColum($data,$colum,$equal){
$ret=[];
array_push($ret,$data[0]); // *
$colum = is_numeric($colum)?$colum:array_search($colum,$data[0]);
for($i=1/* 0 if you remove the header to data*/;$i!=count($data);$i++)
if ($data[$i][$colum]==$equal)
array_push($ret,$data[$i]);
return $ret;
}
function CountFromColum($data,$colum){
$ret=0;
$colum = is_numeric($colum)?$colum:array_search($colum,$data[0]);
for($i=1/* 0 if you remove the header to data*/;$i!=count($data);$i++)
$ret+=$data[$i][$colum];
return $ret;
}
function WhereFromColumData($data,$colum,$min,$max){
$contractDateBegin = new DateTime($min);
$contractDateEnd = new DateTime($max);
$ret=[];
array_push($ret,$data[0]); // *
$colum = is_numeric($colum)?$colum:array_search($colum,$data[0]);
for($i=1/* 0 if you remove the header to data*/;$i!=count($data);$i++){
$paymentDate = new DateTime($data[$i][$colum]);
if ($paymentDate->getTimestamp() > $contractDateBegin->getTimestamp() &&
$paymentDate->getTimestamp() < $contractDateEnd->getTimestamp())
array_push($ret,$data[$i]);
}
return $ret;
}
var_dump(WhereFromColum($data,"Product","Teddybear")); // get all Teddybear's Product
var_dump(CountFromColum($data,"Quantity")); // get all Quantity
var_dump(CountFromColum(WhereFromColum($data,"Product","Teddybear"),"Quantity")); // get all Quantity of Teddybear's Product
var_dump(WhereFromColumData($data,"Date","2018-08-01","2018-12-01")); // get all between 2018-08-01 and 2018-12-01
var_dump(WhereFromColumData(WhereFromColum($data,"Product","Teddybear"),"Date","2018-08-01","2018-12-01")); // get all Teddybear's Product between 2018-08-01 and 2018-12-01
usually I don't usually write code but explain how to do it but in your case it was too complex so please kindly read the three functions carefully and try to understand how they work, ps if you want to improve your skils in php I suggest you play a with these functions and modify them to fit what you need best. when you understand how they work you can also create another one with the same logic of nesting that allows you to make much more advanced filters.

MVC model how to transfer data between multiple views

Hello im trying to create a semi MVC project and im new to this so what ive done so far and what ill explain as my problem here may be completely bad on itself so sorry if that is the case.
View 1 tables.phtml
View 2 Calc.phtml
View 3 Result.phtml
Controller Tables.php
Model Tables.php
On my first view is an Form where you input 2 numbers to generate an multiplication table and it puts this in an variable called $aTempArray it looks like this:
Array (
[0] => Array ( [0] => 10 [1] => 6 [2] => 60 )
[1] => Array ( [0] => 7 [1] => 6 [2] => 42 )
[2] => Array ( [0] => 10 [1] => 6 [2] => 60 )
[3] => Array ( [0] => 7 [1] => 6 [2] => 42 )
[4] => Array ( [0] => 2 [1] => 6 [2] => 12 )
[5] => Array ( [0] => 1 [1] => 6 [2] => 6 )
[6] => Array ( [0] => 10 [1] => 6 [2] => 60 )
[7] => Array ( [0] => 6 [1] => 6 [2] => 36 )
[8] => Array ( [0] => 3 [1] => 6 [2] => 18 )
[9] => Array ( [0] => 5 [1] => 6 [2] => 30 )
)
On my second view it generates a form based on the array like this:
10 * 6 = ... <(this is a textbox)
7 * 6 = ... <(this is a textbox)
So when the user submits this second form on the second view I want it to OR send the $aTempArray, OR generate a new one like this:
Array (
[0] => Array ( [0] => 10 [1] => 6 ['answer'] => ... )
[1] => Array ( [0] => 7 [1] => 6 ['answer'] => ... )
)
However, I have no clue on how to send the $aTempArray becouse on the second submit it is empty becouse of the new controller/model that gets generated(or just reset becouse it reloads), and also I dont have a specific idea on how to get the sum data back when I submit the form on the second page. (the 10 * 6 for example becouse this is just text at this point.)
Ive tried a lot and found some things that do make this work but I want to know if there are better ways to do this.
1 is Saving the array in a session variable for example works but I want to avoid using sessions.
2 is making hidden input fields where I save the sums numbers without the answer like this: <input type="hidden" name="rebuildArray" value="10,6/7,6 etc">
And to recreate the array I do something like:
Str_split on /
Put in array
str_split on ,
Put this in arrays inside the main array.
Foreach over every item in the array
if((currentsubarray[0] * currentsubarray[1]) == answersarray[currentpos])
Answer is correct
else
answer is not correct
So can someone say if one of these ways is a semi correct way to do it or give me a push in a direction on how to so this correctly in an MVC stylish way.
And again, I just started with MVC so if this is completely wrong in general im sorry.

Search by Many2One Field odoo PHP XMLRPC

i'm using this class for accessing odoo through PHP XMLRPC.
Everything works fine almost. I can't search many2one fields just by placing the id of the referenced record. I guess there should be a special way to code the many2one id in the search.
EG: searching in product.supplierinfo by the product_tmpl_id using this code i get emtpy array returned:
$rpc->searchread(array(array("product_tmpl_id","=","3673")),"product.supplierinfo");
Searching for the record by id i get this result:
$rpc->read(array(1),"", "product.supplierinfo");
Array
(
[0] => Array
(
[create_uid] => Array
(
[0] => xxxxx
[1] => xxxxx xxxxx
)
[product_code] =>
[create_date] => 2016-06-22 11:08:00
[name] => Array
(
[0] => 1438
[1] => Provider one
)
[product_uom] => Array
(
[0] => 1
[1] => Unit(s)
)
[sequence] => 1
[product_name] =>
[__last_update] => 2016-06-22 11:42:28
[company_id] => Array
(
[0] => 1
[1] => Company Name
)
[write_uid] => Array
(
[0] => xxxx
[1] => xxxxxx xxxxx
)
[delay] => 1
[write_date] => 2016-06-22 11:42:28
[pricelist_ids] => Array
(
)
[display_name] => Provider One
[min_qty] => 0
[qty] => 0
[product_tmpl_id] => Array
(
[0] => 3673
[1] => Product Name
)
[id] => 1
)
)
How should i code the id of a many2one field?
Any help will be appreciated.
Finally i had the solution. As #czoellner suggested was a problem was the type of the ID was a string and must be an integer. So, this code worked fine.
$rpc->searchread(array(array("product_tmpl_id","=",3673)),"product.supplierinfo");
On the other hand must consider the issue between the id of the product.product and the id of the product.template because they are differents. The table product.supplierinfo uses the id of product.template instead product.product. That causes for searching through the table produc.supplierinfo is necessary to find first the product_tmpl_id of the product to refer to the product. So for finding a all the providers of a product:
#search it by id
$prod_odoo = $rpc->read(array(1),"product.product",array());
#every search returns a 2 dimension array
$prod_suppliers = $rpc->searchread(array(array("product_tmpl_id","=",(int)$prod_odoo[0]["product_tmpl_id"][0])),"product.supplierinfo");
Hope this helps.

Sorting Multidimensional Array by Specific Key

EDIT: For anyone who might come across this post with a similar problem, It was solved by taking konforce's supplied answer and tweaking around a bit with the custom sorting function:
function cmp($a, $b) {
if ($a[5] == $b[5]) {
return ($a[3] < $b[3]) ? -1 :1;
}
return ($a[5] > $b[5]) ? -1 : 1;
}
Notice $a[5] == $b[5] does not return zero. It was changed to check who has the most losses and then sort it in ASC order. I'm sure you can even keep going and add another if-statement in there in-case they have the same losses.
Lastly, all you do is usort($ARRAY, "cmp"); and finito!!!
Original Post
My apologies for coming up with yet another MD Array sorting question but I'm just not getting it. I've searched aplenty
for a solution and although many sites have provided what seemed like a logical answer I still have not been able to figure it out.
My problem is since I'm still learning its been rather difficult for me to grasp the concept of using usort with a custom comparing
function. Atleast, thats what I have seen the most when others have tried to sort MD Arrays.
I'm working on a small project to sharpen up on my php skills. Its a very basic tournament standings script that holds a team's information within an array. I would like to sort the array by most points($array[X][X][5]).
So the array looks something like this:
Array (
[0] => Array (
[0] => Array (
[0] => cooller
[1] => 6
[2] => 6
[3] => 0
[4] => 0
[5] => 18
)
)
[1] => Array (
[0] => Array (
[0] => strenx
[1] => 9
[2] => 5
[3] => 1
[4] => 3
[5] => 18
)
)
[2] => Array (
[0] => Array (
[0] => rapha
[1] => 10
[2] => 8
[3] => 1
[4] => 1
[5] => 25
)
) [3] => Array (
[0] => Array (
[0] => ronald reagan
[1] => 5
[2] => 4
[3] => 0
[4] => 1
[5] => 13
)
)
)
I would like to sort it by most points(cell #5), so it would look like this after sorting:
Array (
[0] => Array (
[0] => Array (
[0] => rapha
[1] => 10
[2] => 8
[3] => 1
[4] => 1
[5] => 25
)
)
[1] => Array (
[0] => Array (
[0] => cooller
[1] => 6
[2] => 6
[3] => 0
[4] => 0
[5] => 18
)
)
[2] => Array (
[0] => Array (
[0] => strenx
[1] => 9
[2] => 5
[3] => 1
[4] => 3
[5] => 18
)
)
[3] => Array (
[0] => Array (
[0] => ronald reagan
[1] => 5
[2] => 4
[3] => 0
[4] => 1
[5] => 13
)
)
)
The player with 25 points would be at the top, followed by 18, 18, and lastly 13. Sorry for my earlier post, was having difficulty wording my question correctly. Thanks in advanced!
I think you want something like this:
usort($standings, function($a, $b) { return $b[0][5] - $a[0][5]; });
Or prior to PHP 5.3:
function cmp($a, $b) { return $b[0][5] - $a[0][5]; }
usort($standings, 'cmp');
When using usort, the $a and $b parameters will be one "layer" into the supplied array. So in your case, an example of $a or $b will be:
[0] => Array (
[0] => cooller
[1] => 6
[2] => 6
[3] => 0
[4] => 0
[5] => 18
)
I'm not sure why you have an extra containing array there, but as you can see, you want to sort based on the [0][5] position.
usort($standings[0][0][5], 'cmp') won't work because the first parameter isn't an array to sort, it's just a single number, the points.

Categories