October: [L5.5] Backend form error when attempting to access model's updated_at in fields.yaml

Created on 7 Sep 2017  Â·  10Comments  Â·  Source: octobercms/october

Expected behavior

Viewing backend form with a timestamp should display form

Actual behavior

Backend Form view is erroring out when the model timestamp is included in fields.yaml. See steps below for more detail on how to reproduce from a fresh install.

Error:
Illegal offset type in isset or empty
/var/www/public/vendor/october/rain/src/Support/Traits/KeyParser.php line 45

It has something to do with a whitespace ending or non-empty string. adding a trim($key) above line 45 fixes the issue.

Reproduce steps

First create a new empty install, set up database connection, run october:up

composer create-project october/october public dev-master
php artisan october:env 
    - configure db connection
php artisan key:generate
php artisan october:up

Next we scaffold a new plugin, create a model, create the controller, and create the db tables

php artisan create:plugin smortimer.test 
php artisan create:model smortimer.test record
    - add create_records_table.php to version.yaml
    - modify fields.yaml to include updated_at
php artisan create:controller smortimer.test records
    - Modify plugin.php to register navigation to smortimer/test/records
php artisan october:up

Here's my fields.yaml file

fields:
  id:
    label: ID
    disabled: true
  updated_at:
    label: Updated At

Create a dummy record

php artisan tinker
Psy Shell v0.8.11 (PHP 7.1.7-1+ubuntu14.04.1+deb.sury.org+1 — cli) by Justin Hileman
>>> namespace smortimer\test\models;
>>> Record::create();
=> Smortimer\Test\Models\Record {#901
     updated_at: "2017-09-07 18:14:21",
     created_at: "2017-09-07 18:14:21",
     id: "1",
   }

Click on the admin record, error occurs at the following url:
http://{$url}/backend/smortimer/test/records/update/1

Remove updated_at from fields.yaml
Reload page - no error.

October build

october/rain (v1.0.422)
october/system (v1.0.421)
october/backend (v1.0.421)
october/cms (v1.0.421)

Completed Bug

Most helpful comment

That was my bad, should have reviewed that PR closer. Thanks for spotting that @daftspunk!

All 10 comments

View your fields.yaml with invisible characters made visible, it's possible that you have a whitespace character that's not allowed in your updated_at field definition.

renamed

I don't believe that's the issue. If I rename updated_at to first_name and add that field to my model, it appears without issue. The problem only happens when accessing timestamps on the model.

fields:
    id:
        label: ID
        disabled: true
    first_name:
        label: First Name

Do you have a full stack trace?

This is from my dummy install that I set up using the steps above on a fresh setup. The issue only started when I migrated to 420/421. Up until that point the configuration was functional.


ErrorException: Illegal offset type in isset or empty in /var/www/public/vendor/october/rain/src/Support/Traits/KeyParser.php:45
Stack trace:
#0 /var/www/public/vendor/october/rain/src/Support/Traits/KeyParser.php(45): Illuminate\Foundation\Bootstrap\HandleExceptions->handleError(2, 'Illegal offset ...', '/var/www/public...', 45, Array)
#1 /var/www/public/vendor/october/rain/src/Translation/Translator.php(86): October\Rain\Translation\Translator->parseKey(Object(October\Rain\Argon\Argon))
#2 /var/www/public/vendor/october/rain/src/Translation/Translator.php(224): October\Rain\Translation\Translator->get(Object(October\Rain\Argon\Argon), Array, NULL)
#3 /var/www/public/vendor/october/rain/src/Support/helpers.php(236): October\Rain\Translation\Translator->trans(Object(October\Rain\Argon\Argon), Array, 'messages', NULL)
#4 /var/www/public/modules/backend/Widgets/form/partials/_field_text.htm(9): trans(Object(October\Rain\Argon\Argon))
#5 /var/www/public/modules/system/Traits/ViewMaker.php(243): include('/var/www/public...')
#6 /var/www/public/modules/system/Traits/ViewMaker.php(97): Backend\Classes\WidgetBase->makeFileContents('/var/www/public...', Array)
#7 /var/www/public/modules/backend/Widgets/Form.php(273): Backend\Classes\WidgetBase->makePartial('_field_text.htm', Array)
#8 /var/www/public/modules/backend/Widgets/form/partials/_field.htm(22): Backend\Widgets\Form->renderFieldElement(Object(Backend\Classes\FormField))
#9 /var/www/public/modules/system/Traits/ViewMaker.php(243): include('/var/www/public...')
#10 /var/www/public/modules/system/Traits/ViewMaker.php(97): Backend\Classes\WidgetBase->makeFileContents('/var/www/public...', Array)
#11 /var/www/public/modules/backend/Widgets/form/partials/_field-container.htm(8): Backend\Classes\WidgetBase->makePartial('_field.htm', Array)
#12 /var/www/public/modules/system/Traits/ViewMaker.php(243): include('/var/www/public...')
#13 /var/www/public/modules/system/Traits/ViewMaker.php(97): Backend\Classes\WidgetBase->makeFileContents('/var/www/public...', Array)
#14 /var/www/public/modules/backend/Widgets/form/partials/_form_fields.htm(2): Backend\Classes\WidgetBase->makePartial('_field-containe...', Array)
#15 /var/www/public/modules/system/Traits/ViewMaker.php(243): include('/var/www/public...')
#16 /var/www/public/modules/system/Traits/ViewMaker.php(97): Backend\Classes\WidgetBase->makeFileContents('/var/www/public...', Array)
#17 /var/www/public/modules/backend/Widgets/form/partials/_section.htm(17): Backend\Classes\WidgetBase->makePartial('_form_fields.ht...', Array)
#18 /var/www/public/modules/system/Traits/ViewMaker.php(243): include('/var/www/public...')
#19 /var/www/public/modules/system/Traits/ViewMaker.php(97): Backend\Classes\WidgetBase->makeFileContents('/var/www/public...', Array)
#20 /var/www/public/modules/backend/Widgets/form/partials/_form.htm(3): Backend\Classes\WidgetBase->makePartial('_section.htm', Array)
#21 /var/www/public/modules/system/Traits/ViewMaker.php(243): include('/var/www/public...')
#22 /var/www/public/modules/system/Traits/ViewMaker.php(97): Backend\Classes\WidgetBase->makeFileContents('/var/www/public...', Array)
#23 /var/www/public/modules/backend/Widgets/form/partials/_form-container.htm(8): Backend\Classes\WidgetBase->makePartial('_form.htm')
#24 /var/www/public/modules/system/Traits/ViewMaker.php(243): include('/var/www/public...')
#25 /var/www/public/modules/system/Traits/ViewMaker.php(97): Backend\Classes\WidgetBase->makeFileContents('/var/www/public...', Array)
#26 /var/www/public/modules/backend/Widgets/Form.php(227): Backend\Classes\WidgetBase->makePartial('_form-container...', Array)
#27 /var/www/public/modules/backend/Behaviors/FormController.php(414): Backend\Widgets\Form->render(Array)
#28 [internal function]: Backend\Behaviors\FormController->formRender()
#29 /var/www/public/vendor/october/rain/src/Extension/ExtendableTrait.php(379): call_user_func_array(Array, Array)
#30 /var/www/public/vendor/october/rain/src/Extension/Extendable.php(46): October\Rain\Extension\Extendable->extendableCall('formRender', Array)
#31 /var/www/public/plugins/smortimer/test/controllers/records/update.htm(13): October\Rain\Extension\Extendable->__call('formRender', Array)
#32 /var/www/public/modules/system/Traits/ViewMaker.php(243): include('/var/www/public...')
#33 /var/www/public/modules/system/Traits/ViewMaker.php(109): Backend\Classes\Controller->makeFileContents('/var/www/public...')
#34 /var/www/public/modules/backend/Classes/Controller.php(369): Backend\Classes\Controller->makeView('update')
#35 /var/www/public/modules/backend/Classes/Controller.php(251): Backend\Classes\Controller->execPageAction('update', Array)
#36 /var/www/public/modules/backend/Classes/BackendController.php(112): Backend\Classes\Controller->run('update', Array)
#37 [internal function]: Backend\Classes\BackendController->run('smortimer/test/...')
#38 /var/www/public/vendor/laravel/framework/src/Illuminate/Routing/Controller.php(54): call_user_func_array(Array, Array)
#39 /var/www/public/vendor/laravel/framework/src/Illuminate/Routing/ControllerDispatcher.php(45): Illuminate\Routing\Controller->callAction('run', Array)
#40 /var/www/public/vendor/laravel/framework/src/Illuminate/Routing/Route.php(205): Illuminate\Routing\ControllerDispatcher->dispatch(Object(Illuminate\Routing\Route), Object(Backend\Classes\BackendController), 'run')
#41 /var/www/public/vendor/laravel/framework/src/Illuminate/Routing/Route.php(162): Illuminate\Routing\Route->runController()
#42 /var/www/public/vendor/laravel/framework/src/Illuminate/Routing/Router.php(610): Illuminate\Routing\Route->run()
#43 /var/www/public/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php(30): Illuminate\Routing\Router->Illuminate\Routing\{closure}(Object(Illuminate\Http\Request))
#44 /var/www/public/vendor/laravel/framework/src/Illuminate/Routing/Middleware/SubstituteBindings.php(41): Illuminate\Routing\Pipeline->Illuminate\Routing\{closure}(Object(Illuminate\Http\Request))
#45 /var/www/public/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(149): Illuminate\Routing\Middleware\SubstituteBindings->handle(Object(Illuminate\Http\Request), Object(Closure))
#46 /var/www/public/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php(53): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request))
#47 /var/www/public/vendor/laravel/framework/src/Illuminate/View/Middleware/ShareErrorsFromSession.php(49): Illuminate\Routing\Pipeline->Illuminate\Routing\{closure}(Object(Illuminate\Http\Request))
#48 /var/www/public/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(149): Illuminate\View\Middleware\ShareErrorsFromSession->handle(Object(Illuminate\Http\Request), Object(Closure))
#49 /var/www/public/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php(53): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request))
#50 /var/www/public/vendor/laravel/framework/src/Illuminate/Session/Middleware/StartSession.php(63): Illuminate\Routing\Pipeline->Illuminate\Routing\{closure}(Object(Illuminate\Http\Request))
#51 /var/www/public/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(149): Illuminate\Session\Middleware\StartSession->handle(Object(Illuminate\Http\Request), Object(Closure))
#52 /var/www/public/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php(53): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request))
#53 /var/www/public/vendor/laravel/framework/src/Illuminate/Cookie/Middleware/AddQueuedCookiesToResponse.php(37): Illuminate\Routing\Pipeline->Illuminate\Routing\{closure}(Object(Illuminate\Http\Request))
#54 /var/www/public/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(149): Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse->handle(Object(Illuminate\Http\Request), Object(Closure))
#55 /var/www/public/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php(53): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request))
#56 /var/www/public/vendor/laravel/framework/src/Illuminate/Cookie/Middleware/EncryptCookies.php(59): Illuminate\Routing\Pipeline->Illuminate\Routing\{closure}(Object(Illuminate\Http\Request))
#57 /var/www/public/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(149): Illuminate\Cookie\Middleware\EncryptCookies->handle(Object(Illuminate\Http\Request), Object(Closure))
#58 /var/www/public/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php(53): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request))
#59 /var/www/public/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(102): Illuminate\Routing\Pipeline->Illuminate\Routing\{closure}(Object(Illuminate\Http\Request))
#60 /var/www/public/vendor/laravel/framework/src/Illuminate/Routing/Router.php(612): Illuminate\Pipeline\Pipeline->then(Object(Closure))
#61 /var/www/public/vendor/laravel/framework/src/Illuminate/Routing/Router.php(571): Illuminate\Routing\Router->runRouteWithinStack(Object(Illuminate\Routing\Route), Object(Illuminate\Http\Request))
#62 /var/www/public/vendor/october/rain/src/Router/CoreRouter.php(20): Illuminate\Routing\Router->dispatchToRoute(Object(Illuminate\Http\Request))
#63 /var/www/public/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(176): October\Rain\Router\CoreRouter->dispatch(Object(Illuminate\Http\Request))
#64 /var/www/public/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php(30): Illuminate\Foundation\Http\Kernel->Illuminate\Foundation\Http\{closure}(Object(Illuminate\Http\Request))
#65 /var/www/public/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/CheckForMaintenanceMode.php(46): Illuminate\Routing\Pipeline->Illuminate\Routing\{closure}(Object(Illuminate\Http\Request))
#66 /var/www/public/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(149): Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode->handle(Object(Illuminate\Http\Request), Object(Closure))
#67 /var/www/public/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php(53): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request))
#68 /var/www/public/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(102): Illuminate\Routing\Pipeline->Illuminate\Routing\{closure}(Object(Illuminate\Http\Request))
#69 /var/www/public/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(151): Illuminate\Pipeline\Pipeline->then(Object(Closure))
#70 /var/www/public/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(116): Illuminate\Foundation\Http\Kernel->sendRequestThroughRouter(Object(Illuminate\Http\Request))
#71 /var/www/public/index.php(43): Illuminate\Foundation\Http\Kernel->handle(Object(Illuminate\Http\Request))
#72 {main}

It has something to do with a whitespace ending or non-empty string. adding a trim($key) above line 45 fixes the issue.

That's not the case, something is passing a non-string value to parseKey() https://stackoverflow.com/questions/2732451/php-how-do-i-fix-this-illegal-offset-type-error

trim() would work because it would cast the variable to a string first, but that doesn't solve the actual problem.

Don't know if this will help but if you typehint string in parseKey you see that something is passing null in:

Type error: Argument 1 passed to October\Rain\Translation\Translator::parseKey() must be of the type string, null given, called in /var/www/public/vendor/october/rain/src/Translation/Translator.php on line 86

I'm seeing the same issue for all timestamp fields in fields.yaml after moving to 421.

Adding type: datepicker is the only way I've found to get the form to render without throwing the type/cast error.

I'm having the same error in version (419). This happens when I'm clicking on a controller link, (update, create) at my own plugin developed in Builder.

Fixed by 58aa360eab10b5378e19c050713c5eef388703d5

Sorry guys, some bad code slipped that breaks PHP 7.1

This will be fixed in Build 424+

That was my bad, should have reviewed that PR closer. Thanks for spotting that @daftspunk!

Was this page helpful?
0 / 5 - 0 ratings