Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Creating a new grid field using ChannelField Model leads to exception error when field accessed #4342

Open
jcogs-design opened this issue Jun 3, 2024 · 1 comment

Comments

@jcogs-design
Copy link
Contributor

jcogs-design commented Jun 3, 2024

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.

@jcogs-design
Copy link
Contributor Author

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant