0

I'm using CakePHP 3.4

I'm getting visitors count from LogProfileVisits table using

$profile_visit_logs = $this->Users->LogProfileVisits->find()
   ->where(['user_id' => $user->id]);
$profile_visit_logs->select([
   'total_count' => $profile_visit_logs->func()->count('id'),
   'unique_count' => $profile_visit_logs->func()->count('DISTINCT `ip_address`'),
   'visit_date' => 'MONTH(created)'
])
->group('visit_date')
->limit(10);

But this is giving Fatal error as

Error: Call to a member function format() on boolean
File /path_to_app/vendor/cakephp/chronos/src/Traits/FrozenTimeTrait.php
Line: 161 

Same is working fine with DATE(created) and YEAR(created)

Error log

2017-06-02 12:25:45 Warning: Warning (2): DateTimeImmutable::modify() [<a href='http://php.net/datetimeimmutable.modify'>datetimeimmutable.modify</a>]: Failed to parse time string (5) at position 0 (5): Unexpected character in [/path_to_app/vendor/cakephp/chronos/src/Traits/FrozenTimeTrait.php, line 160]
Request URL: /dashboard/profile/ajax_profile_performance
Referer URL: http://example.com/dashboard
Client IP: client_ip
Trace:
Cake\Error\BaseErrorHandler::handleError() - CORE/src/Error/BaseErrorHandler.php, line 153
DateTimeImmutable::modify() - [internal], line ??
Cake\Chronos\Date::modify() - ROOT/vendor/cakephp/chronos/src/Traits/FrozenTimeTrait.php, line 160
Cake\Database\Type\DateTimeType::toPHP() - CORE/src/Database/Type/DateTimeType.php, line 139
Cake\Database\Type\DateType::toPHP() - CORE/src/Database/Type/DateType.php, line 90
Cake\Database\FieldTypeConverter::__invoke() - CORE/src/Database/FieldTypeConverter.php, line 78
Cake\Database\Statement\CallbackStatement::fetch() - CORE/src/Database/Statement/CallbackStatement.php, line 59
Cake\ORM\ResultSet::_fetchResult() - CORE/src/ORM/ResultSet.php, line 484
Cake\ORM\ResultSet::valid() - CORE/src/ORM/ResultSet.php, line 276
App\Controller\Dashboard\ProfileController::ajaxProfilePerformance() - APP/Controller/Dashboard/ProfileController.php, line 113
Cake\Controller\Controller::invokeAction() - CORE/src/Controller/Controller.php, line 440
Cake\Http\ActionDispatcher::_invoke() - CORE/src/Http/ActionDispatcher.php, line 119
Cake\Http\ActionDispatcher::dispatch() - CORE/src/Http/ActionDispatcher.php, line 93
Cake\Http\BaseApplication::__invoke() - CORE/src/Http/BaseApplication.php, line 78
Cake\Http\Runner::__invoke() - CORE/src/Http/Runner.php, line 65
Cake\Routing\Middleware\RoutingMiddleware::__invoke() - CORE/src/Routing/Middleware/RoutingMiddleware.php, line 59
Cake\Http\Runner::__invoke() - CORE/src/Http/Runner.php, line 65
Cake\Routing\Middleware\AssetMiddleware::__invoke() - CORE/src/Routing/Middleware/AssetMiddleware.php, line 88
Cake\Http\Runner::__invoke() - CORE/src/Http/Runner.php, line 65
Cake\Error\Middleware\ErrorHandlerMiddleware::__invoke() - CORE/src/Error/Middleware/ErrorHandlerMiddleware.php, line 92
Cake\Http\Runner::__invoke() - CORE/src/Http/Runner.php, line 65
Cake\Http\Runner::run() - CORE/src/Http/Runner.php, line 51
Cake\Http\Server::run() - CORE/src/Http/Server.php, line 80
[main] - ROOT/webroot/index.php, line 37



2017-06-02 12:25:45 Error: Fatal Error (1): Call to a member function format() on boolean in [/path_to_app/vendor/cakephp/chronos/src/Traits/FrozenTimeTrait.php, line 161]
Request URL: /dashboard/profile/ajax_profile_performance
Referer URL: http://profplus.in/dashboard
Client IP: client_ip
Trace:
Cake\Error\BaseErrorHandler::handleFatalError() - CORE/src/Error/BaseErrorHandler.php, line 223
Cake\Error\BaseErrorHandler::Cake\Error\{closure}() - CORE/src/Error/BaseErrorHandler.php, line 105
[main] - [internal], line ??



2017-06-02 12:25:46 Warning: Headers already sent in /path_to_app/vendor/cakephp/cakephp/src/Error/Debugger.php:822
2017-06-02 12:25:46 Error: [Cake\Error\FatalErrorException] Call to a member function format() on boolean in /path_to_app/vendor/cakephp/chronos/src/Traits/FrozenTimeTrait.php on line 161
Request URL: /dashboard/profile/ajax_profile_performance
Referer URL: http://example.com/dashboard
Client IP: client_ip
Stack Trace:
#0 /path_to_app/vendor/cakephp/cakephp/src/Error/BaseErrorHandler.php(105): Cake\Error\BaseErrorHandler->handleFatalError(1, 'Call to a membe...', '/home/thebornen...', 161)
#1 [internal function]: Cake\Error\BaseErrorHandler->Cake\Error\{closure}()
#2 {main}
Anuj TBE
  • 9,198
  • 27
  • 136
  • 285
  • Whenever receiving errors, please always post **the _complete_ error**, that is, **including the _full_ stacktrace** (ideally copied from the logs where it is available in a properly readable fashion)! And is `visit_date` possibly an existing (date-time typed) table column? – ndm Jun 02 '17 at 12:12
  • @ndm updated question with error log – Anuj TBE Jun 02 '17 at 12:29
  • And what about the `visit_date` being an existing column? – ndm Jun 02 '17 at 13:16
  • no `visit_date` is not an existing column. `MONTH(created)` is queried as `visit_date`. Same is working fine when replacing `MONTH(created)` with `DATE(created)` and `YEAR(created)` – Anuj TBE Jun 02 '17 at 13:59

2 Answers2

1

Looking at the stacktrace, the ORM seems to treat the visit_date column as a DATE type, you can tell by the line where DateType::toPHP() is being invoked:

Cake\Database\Type\DateType::toPHP() - CORE/src/Database/Type/DateType.php, line 90

This is where things start to go wrong, the number 5 (the result of MONTH(created)) is not a valid date-time value, and hence you end up with a null value, which then causes the fatal error when trying to invoke a method on it:

Warning (2): DateTimeImmutable::modify() [...] Failed to parse time string (5)

The results of DATE() or YEAR() are valid, the former obviously would return a parsable date, and the latter a year, which might not be obvious, but can be parsed too, it would be treated as a time value though, for example 2017 would be interpreted as 20:17. You would end up with a useless/wrong date object, but it won't error out.

http://www.php.net/manual/en/datetimeimmutable.modify.php

So long story short, you need to figure out why the ORM treats the column as a DATE type. This surely isn't the default, by default computed/virtual columns will be treated as strings. If visit_date isn't an existing column as you stated in the comments, then maybe it was one at one point, and you haven't cleared the cache!?

There should be no need to workaround this problem, this should be properly fixable on your end. Hover you could try changing the select/typemap to see if it makes any difference, also you should try debugging it throughout the control flow in order to get an idea where things might go wrong:

$query->getSelectTypeMap()->addDefaults(['visit_date' => 'integer']);
$query->getTypeMap()->addDefaults(['visit_date' => 'integer']);
ndm
  • 59,784
  • 9
  • 71
  • 110
0

Try this code so it knows what model to use:

    $this->loadModel('LogProfileVisits');
  • Model is already loaded and error is not with `DATE(created)` – Anuj TBE Jun 02 '17 at 12:23
  • If you check where its giving error it says its on a modify fuction, i sugest you read CakePhp documentation: https://api.cakephp.org/chronos/1.0/class-Cake.Chronos.Traits.FrozenTimeTrait.html Sorry if im not able to help, but your error was similar to mine so i don't know what i can do more. – Daniel Pereira Jun 02 '17 at 12:51