When using the TablesService directly from a PHP script instead of through an API endpoint, calling createTable or updateTable with a data parameter that includes an options structure will result in errors that seem to indicate a misinterpretation of the nested array structure. Placing the exact same code in an web API endpoint context will function as expected.
I'm not sure that my attempt to use this internal service class is supported at all, however for my use case it is the most straightforward method and even if this use is not intended, the issue described is still probably a bug.
I have put together a minimal reproducing test case.
bug.php.zip
PHP Notice: Undefined index: column in /usr/local/directus/vendor/zendframework/zend-db/src/Sql/AbstractSql.php on line 419
PHP Stack trace:
PHP 1. {main}() /usr/local/directus/bug.php:0
PHP 2. Directus\Services\TablesService->createTable() /usr/local/directus/bug.php:64
PHP 3. Directus\Services\TablesService->addColumnsInfo() /usr/local/directus/src/core/Directus/Services/TablesService.php:361
PHP 4. Directus\Services\TablesService->addOrUpdateFieldInfo() /usr/local/directus/src/core/Directus/Services/TablesService.php:821
PHP 5. Directus\Services\TablesService->addFieldInfo() /usr/local/directus/src/core/Directus/Services/TablesService.php:847
PHP 6. Directus\Database\TableGateway\RelationalTableGateway->createRecord() /usr/local/directus/src/core/Directus/Services/TablesService.php:888
PHP 7. Directus\Database\TableGateway\RelationalTableGateway->addRecordByArray() /usr/local/directus/src/core/Directus/Database/TableGateway/RelationalTableGateway.php:410
PHP 8. Directus\Database\TableGateway\RelationalTableGateway->insert() /usr/local/directus/src/core/Directus/Database/TableGateway/BaseTableGateway.php:411
PHP 9. Directus\Database\TableGateway\RelationalTableGateway->executeInsert() /usr/local/directus/vendor/zendframework/zend-db/src/TableGateway/AbstractTableGateway.php:264
PHP 10. Directus\Database\TableGateway\RelationalTableGateway->executeInsert() /usr/local/directus/src/core/Directus/Database/TableGateway/BaseTableGateway.php:820
PHP 11. Zend\Db\Sql\Sql->prepareStatementForSqlObject() /usr/local/directus/vendor/zendframework/zend-db/src/TableGateway/AbstractTableGateway.php:307
PHP 12. Zend\Db\Sql\Platform\Platform->prepareStatement() /usr/local/directus/vendor/zendframework/zend-db/src/Sql/Sql.php:140
PHP 13. Zend\Db\Sql\Insert->prepareStatement() /usr/local/directus/vendor/zendframework/zend-db/src/Sql/Platform/Platform.php:103
PHP 14. Zend\Db\Sql\Insert->buildSqlString() /usr/local/directus/vendor/zendframework/zend-db/src/Sql/AbstractPreparableSql.php:34
PHP 15. Zend\Db\Sql\Insert->processInsert() /usr/local/directus/vendor/zendframework/zend-db/src/Sql/AbstractSql.php:64
PHP 16. Zend\Db\Sql\Insert->resolveColumnValue() /usr/local/directus/vendor/zendframework/zend-db/src/Sql/Insert.php:193
I expect the stub script to create a collection named 'foo', with two fields (ID and Name). The created text-input field 'Name' should receive the correct options structure (in the JSON field in the directus_fields table) as specified in the script.
The collection is added, but the options field in the directus_fields table is NULL.
The error indicates that the 'options' key in the supplied field structure is incorrectly interpreted. However, the supplied field structure is exactly the same as when supplied through the API, in which case it functions just fine. I realize that I'm artificially setting up (part of) the context that allows the Directus services to function when directly called from PHP, and that this is not normal use. However, everything else seems to function just fine, and while there may be a context variable responsible for this discrepancy, I expect it not to be intended behavior and thus a bug.
master branchHello @naub
I have placed bug.php file in root folder and called it(In my API setup, URL is : http://localhost/directus/directus-api/bug.php) and collection created successfully.
Can you please check and confirm that you are using latest release of directus/api?
Hi @itsmerhp
Try executing it as a shell command (that's what the bug is about). It will behave differently, which is the problem that I'm trying to solve.
Hello @naub
Data parameters structure you are passing is perfectly fine.
But, in your script below code line is missing :
\Directus\Database\TableGateway\BaseTableGateway::setHookEmitter($app->getContainer()->get('hook_emitter'));
It is been used to format parameters before inserting in DB, in APIs it has been included via TableGatewayMiddleware(ROOT_FOLDER/src/core/Directus/Application/Http/Middleware/TableGatewayMiddleware.php).
Due to missing Emitter Hooks in your script the options value is not converting in json and that's why NULL value is storing in directus_fields table for that field.
Please check attachment : bug.php.zip, I have modified your script accordingly.
Thank you so much @itsmerhp, that's exactly what I was looking for! I suspected I was missing something along the lines of an initialization step, but the problem seemed so disconnected from that phase.
Thanks again.
Most helpful comment
Thank you so much @itsmerhp, that's exactly what I was looking for! I suspected I was missing something along the lines of an initialization step, but the problem seemed so disconnected from that phase.
Thanks again.