Creating a new grid field using ChannelField Model leads to exception error when field accessed
jcogs-design opened this issue · comments
Description of the problem
Created a new grid field using the ChannelField model following instructions from here.
Have confirmed by inspection of database that a grid_field entry is added to exp_channel_fields
, but it seems that an associated table of the form exp_channel_grid_field_xx
is not created.
When CP for entry concerned is subsequently viewed, exception error thrown due to missing table.
There is no documentation describing how / what is required to ensure that an associated table is created (at least that I can find).
How To Reproduce
As per description above.
Error Messages
Exception Caught
SQLSTATE[42S02]: Base table or view not found: 1146 Table 'db.exp_channel_grid_field_152' doesn't exist:
SELECT * FROM (`exp_channel_grid_field_152`) WHERE `entry_id` IN (1077) AND `fluid_field_data_id` = 0 ORDER BY `row_order` asc
ee/legacy/database/drivers/mysqli/mysqli_connection.php:146
Stack Trace: Please include when reporting this error
#0 ee/legacy/database/drivers/mysqli/mysqli_driver.php(112): CI_DB_mysqli_connection->query()
#1 ee/legacy/database/DB_driver.php(262): CI_DB_mysqli_driver->_execute()
#2 ee/legacy/database/DB_driver.php(177): CI_DB_driver->simple_query()
#3 ee/legacy/database/DB_active_rec.php(1084): CI_DB_driver->query()
#4 ee/legacy/models/grid_model.php(415): CI_DB_active_record->get()
#5 ee/ExpressionEngine/Addons/grid/libraries/Grid_lib.php(60): Grid_model->get_entry_rows()
#6 ee/ExpressionEngine/Addons/grid/ft.grid.php(199): Grid_lib->display_field()
#7 ee/legacy/fieldtypes/EE_Fieldtype.php(325): Grid_ft->display_field()
#8 ee/legacy/libraries/api/Api_channel_fields.php(444): EE_Fieldtype->display_publish_field()
#9 ee/ExpressionEngine/Model/Content/FieldFacade.php(292): Api_channel_fields->apply()
#10 ee/ExpressionEngine/Model/Content/Display/FieldDisplay.php(83): ExpressionEngine\Model\Content\FieldFacade->getForm()
#11 ee/ExpressionEngine/View/publish/partials/publish_form.php(135): ExpressionEngine\Model\Content\Display\FieldDisplay->getForm()
#12 ee/ExpressionEngine/Service/View/View.php(137): include('...')
#13 ee/ExpressionEngine/Service/View/View.php(106): ExpressionEngine\Service\View\View->parse()
#14 ee/ExpressionEngine/Service/View/View.php(165): ExpressionEngine\Service\View\View->render()
#15 ee/ExpressionEngine/View/publish/entry.php(5): ExpressionEngine\Service\View\View->embed()
#16 ee/ExpressionEngine/Service/View/View.php(137): include('...')
#17 ee/ExpressionEngine/Service/View/View.php(106): ExpressionEngine\Service\View\View->parse()
#18 ee/legacy/libraries/View.php(40): ExpressionEngine\Service\View\View->render()
#19 ee/legacy/libraries/Cp.php(344): View->render()
#20 ee/ExpressionEngine/Controller/Publish/Edit.php(562): Cp->render()
#21 [internal function]: ExpressionEngine\Controller\Publish\Edit->entry()
#22 ee/ExpressionEngine/Core/Core.php(268): call_user_func_array()
#23 ee/ExpressionEngine/Core/Core.php(124): ExpressionEngine\Core\Core->runController()
#24 ee/ExpressionEngine/Boot/boot.php(184): ExpressionEngine\Core\Core->run()
#25 public_html/_edit.php(153): require_once('...')
#25 public_html/_edit.php(153): require_once('...')
Screenshots / Videos / Template Code
The field concerned was created using the following add-on code:
// We want a grid field
$field_type = 'grid';
$field_name = 'cat_warnings';
$field_label = 'Important Cat Warnings';
// Construct the field
$field = ee('Model')->make('ChannelField');
// Set required fields.
$field->site_id = ee()->config->item('site_id');
$field->field_name = $field_name;
$field->field_label = !empty($field_label) ? $field_label : $field_name;
$field->field_type = strtolower($field_type);
$field->field_list_items = '';
// field_order: increment the last field order number of fields belonging to this site
$ordernumber = 1 + ee('Model')->get('ChannelField')->filter('site_id',$field->site_id)->order('field_order', 'DESC')->first()->field_order;
$field->field_order = $ordernumber;
// $field->field_order = 1;
$field->field_maxl = 256;
$field->enable_frontedit = 'n';
$field->field_fmt = 'none';
$field->field_show_fmt = 'n';
$field->field_content_type = 'all';
// Set field-specific settings
$settings = $field->getSettingsValues();
switch($field_type) {
case 'text':
$settings['field_settings']['field_maxl'] = '256';
$settings['field_settings']['field_show_smileys'] = 'n';
$settings['field_settings']['field_show_file_selector'] = 'n';
$settings['field_settings']['field_fmt'] = 'none';
$settings['field_settings']['field_allow_override'] = 'n';
break;
case 'grid':
$settings['field_settings']['grid_min_rows'] = '0';
$settings['field_settings']['allow_reorder'] = 'y';
break;
}
$field->setProperty('field_settings', $settings['field_settings']);
// Validate and Save.
// $result = $field->validate();
// if ($result->isValid())
// {
// Save field
$field->save();
// Return field_id
return $field->field_id;
Field validation is disabled as a work-around for this issue.
Environment Details:
- Version: 7.4.9
- PHP Version 8.3
Possible Solution
Add some kind of default behaviour to either the channelfield model methods, or the part of CP that displays grid field to either create a dummy exp_channel_grid_field_xx
table and an equivalent entry in exp_grid_columns
, or display the grid field without content area (and so avoid the exception).
and
Improve documentation to describe missing steps that lead to generation of the appropriate grid_field_xx data table.
FWIW - Seems that this code fragment will generate the correct exp_channel_grid_field_xx
table... included here in case it is helpful for anyone else with this issue.
// If grid_field created, now also generate a suitable data table
if($field_type == 'grid') {
ee()->load->model('grid_model');
ee()->grid_model->create_field($field->field_id, 'channel');
$column_data = array(
'field_id' => $field->field_id,
'content_type' => 'channel',
'col_order' => 0,
'col_type' => 'text',
'col_label' => $field_label,
'col_name' => $field_name,
'col_instructions' => '',
'col_required' => 'n',
'col_search' => 'n',
'col_width' => 0,
'col_settings' => '{"field_maxl":"256","field_fmt":"none","field_text_direction":"ltr","field_content_type":"all","field_required":"n"}'
);
ee()->grid_model->save_col_settings($column_data, '', 'channel');
}