ExpressionEngine / ExpressionEngine

ExpressionEngine is a flexible, feature-rich, free open-source content management platform that empowers hundreds of thousands of individuals and organizations around the world to easily manage their web site.

Home Page:https://expressionengine.com

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

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');
        }