1 (edited by cleal 10/26/2018 06:49:07 pm)

Topic: reports_classes.inc:40: count()

I have this error when users access to report area, the error log said:

reports_classes.inc:40: count(): Parameter must be an array or an object that implements Countable

Anybody has an idea?

Thank you

cleal

2 (edited by cleal 10/26/2018 06:48:58 pm)

Re: reports_classes.inc:40: count()

I got a solution:

in reports_classes.inc change on line 40.

$class_id = count($this->ar_classes);
to
$class_id = is_array($this->ar_classes) ? count($this->ar_classes) : 0;

What do you think?

cleal

Re: reports_classes.inc:40: count()

This is the result of a change from PHP 7.1 to 7.2, as I understand it. In 7.1 and before, a count(NULL) would return zero. Now it issues an error. Your correction should work fine.

Re: reports_classes.inc:40: count()

@joe commit this fix on core

Subscription service based on FA
HRM CRM POS batch Themes

Re: reports_classes.inc:40: count()

A search for the string "= count(" reveals several places in several files:

Post's attachments

count_places.png 6.1 kb, file has never been downloaded. 

You don't have the permssions to download the attachments of this post.

Re: reports_classes.inc:40: count()

I checked it and not in all cases have to be made changes.

cleal

Re: reports_classes.inc:40: count()

The bug in report_classes.inc has been fixed and committed.
A fixed copy can be downloaded here.

Joe

Re: reports_classes.inc:40: count()

Quite a few other pages need the changes even if not all listed in my previous post. Would a generic PHP 7.2 function / class file be created with such overrides so as not to have to makes such changes everywhere?

Re: reports_classes.inc:40: count()

In my personal experiment, I added this function into ui_globals.inc

   function count_array($array){
        return (is_array($array)) ? count($array) : 0;
   }

and replace in all php files "count(" by "count_array("

At this moment, its working for me.

Let me know if my solution works for all.

cleal

Re: reports_classes.inc:40: count()

@cleal - Your solution is ok to use. If you seek other solution,

 function count_array($array){
        return ($array) ? count($array) : 0;
   }

I mean without is_array

Subscription service based on FA
HRM CRM POS batch Themes

11 (edited by cleal 10/30/2018 06:40:02 pm)

Re: reports_classes.inc:40: count()

But, if parameter is a string?  is_array() is useful to stop that error condition.

cleal

Re: reports_classes.inc:40: count()

@joe: Can we change all such each() constructs using @cleal's function?

Re: reports_classes.inc:40: count()

Yes maybe a good idea.

Joe

Re: reports_classes.inc:40: count()

All such PHP 7.x gotchas can be made into a separate php7.php file to be included if a PHP7.x version is in use.

15 (edited by cleal 10/31/2018 08:28:38 pm)

Re: reports_classes.inc:40: count()

I think, into /includes/ui/ one file named like that.  In this add all functions to fix issues of deprecated functions or fix others.

And then, add include into /includes/ui.inc

cleal

Re: reports_classes.inc:40: count()

Line 186 file maintenance_db.inc also needs array check function.
Error raising on Installation Wizard step 5.

Phuong

Re: reports_classes.inc:40: count()

I will test a solution with rename_function and override_function.
We will include a new file with specific functions with new behaviors if
  version_compare >= 7.2.0

Then we do not need to change anything in the code.

Joe

Re: reports_classes.inc:40: count()

@joe: Line 186 in admin/db/maintenance_db.inc can be preceded with:

if (!(is_array($db_connections)) $db_connections = array($db_connections);

Re: reports_classes.inc:40: count()

I see that the functions rename_function and override_function are not part of the standard PHP and therefore can not be used.

I will follow @cleal example and review all the count() calls. Where the check is needed I will use the count_array() instead of  count().

Joe

Re: reports_classes.inc:40: count()

Yes, they are part of the Advanced PHP debugger.

Re: reports_classes.inc:40: count()

I have now committed a fix, where the count() was replaced with count_array(). It was only needed in 3 files and the count_array() was added at the end in the file /includes/ui/ui_globals.inc.

The files are:
/admin/db/maintenance_db.inc(186): $cnt = max(1, count_array($db_connections));
/reporting/includes/reports_classes.inc(37): $class_id = count_array($this->ar_classes);
/sales/includes/sales_db.inc(371): if (!count_array($trans_no))

and the count_array definition:
/includes/ui/ui_globals.inc(65): function count_array($array)

I have been testing FA all over, but I will ask you who has the PHP 7.2.X installed to download a snapshot of 2.4.4 from the repo here.

There was also a problem with the 2.nd parameter in number_format2 in the file /includes/current_user.inc. We used a float value as an integer parameter. Fixed with intval().

Please help me test this snapshot so we can find more odd count() and other problems.

Thank you in advance.

Joe

22 (edited by notrinos 11/29/2018 12:20:54 pm)

Re: reports_classes.inc:40: count()

There are still some where

  1. /includes/ui/items_cart.inc line 312. Error firing on Modifying Journal Transaction

  2. /includes/ui/contacts_view.inc line 137. Error firing on Add Customer Contact without selecting Contact Category

Phuong

Re: reports_classes.inc:40: count()

These files have been committed to stable repo. Just replace the count() with count_array() in both places.

Thanks @notrinos for finding these.

Please continue testing. Thanks in advance.

/Joe

Re: reports_classes.inc:40: count()

pdf_report.inc lines 344 and 379 may need count_array() also.
And includes/ui/ui_globals.inc has to be included here since function count_array() is defined there.

Phuong

Re: reports_classes.inc:40: count()

Search for "count(" in the reporting/includes/pdf_report.inc and we find 15 occurrences that need to be replaced with "count_array("

@joe: can commit this along with the inclusion of includes/ui/ui_globals.inc in it.