Getting Unusual Grammar Error in v4.0

So I have a companion plugin with the theme and for some reason this code in the boot method is throwing an error:

Error Message is: Cannot assign null to property Illuminate\Database\Schema\Blueprint::$grammar of type Illuminate\Database\Schema\Grammars\Grammar

    public function boot()
    {
        EntryRecord::extend(function ($model) {
            $model->bindEvent('model.afterSave', function () use ($model) {
                try {
                    if ($model->inSection('Content\Orders')) {

                        // Get the settings from the site
                        $settings = GlobalRecord::findForGlobal('Content\Settings');

                        // Get the order statuses
                        $order_status     = $model->order_status;
                        $sent_receipt     = $model->sent_email_receipt;
                        $sent_in_progress = $model->sent_in_progress;
                        $sent_cancelled   = $model->sent_cancelled;
                        $sent_tracking    = $model->sent_tracking_receipt;
                        $resend_email     = $model->resend_email;

                        // Remove Tailor ID from metadata
                        $unwanted_words = 'tailor_id';
                        $replace_match  = '/^.*' . $unwanted_words . '.*$(?:\r\n|\n)?/m';
                        $order_contents = preg_replace($replace_match, '', $model->order_contents);

                        // Set Mail Order Data
                        View::share('site_name', $settings->website_name);
                        $mail_data = [
                            'customer_name'        => $model->customer_name,
                            'customer_email'       => $model->customer_email,
                            'shipping_method'      => $model->shipping_method,
                            'customer_address'     => $model->customer_address,
                            'tracking_number'      => $model->tracking_number,
                            'tracking_url'         => $model->tracking_url,
                            'cancellation_message' => $model->cancellation_message,
                            'total'                => $model->total,
                            'order_contents'       => $order_contents,
                        ];

                        // New Order
                        if ($order_status == 'new' && ! $sent_receipt) {

                            // Send Customer Email
                            Mail::send('artistro08.tailorstartercompanion::mail.new_order', $mail_data, function ($message) use ($model) {
                                $message->to($model->customer_email, $model->customer_name);
                            });

                            // Send Admin Email
                            Mail::send('artistro08.tailorstartercompanion::mail.new_order_admin', $mail_data, function ($message) use ($settings, $model) {
                                $message->to($settings->notification_email, $model->notification_email_recipient_name);
                            });

                            $model->sent_email_receipt = true;
                            $model->save();
                        }

                        // Order in Progress
                        if ($order_status == 'in_progress' && ! $sent_in_progress) {

                            // Send Customer Email
                            Mail::send('artistro08.tailorstartercompanion::mail.order_in_progress', $mail_data, function ($message) use ($model) {
                                $message->to($model->customer_email, $model->customer_name);
                            });

                            $model->sent_in_progress = true;
                            $model->save();
                        }

                        // Shipped Order
                        if ($order_status == 'shipped' && ! $sent_tracking) {

                            // Send Customer Email
                            Mail::send('artistro08.tailorstartercompanion::mail.order_shipped', $mail_data, function ($message) use ($model) {
                                $message->to($model->customer_email, $model->customer_name);
                            });

                            $model->sent_tracking_receipt = true;
                            $model->save();
                        }

                        // Cancelled Order
                        if ($order_status == 'cancelled' && ! $sent_cancelled) {

                            // Send Customer Email
                            Mail::send('artistro08.tailorstartercompanion::mail.order_cancelled', $mail_data, function ($message) use ($model) {
                                $message->to($model->customer_email, $model->customer_name);
                            });

                            $model->sent_cancelled = true;
                            $model->save();
                        }

                        // Check if we need to resend any emails
                        if ($resend_email) {

                            // New Order
                            if ($order_status == 'new') {

                                // Send Customer Email
                                Mail::send('artistro08.tailorstartercompanion::mail.new_order', $mail_data, function ($message) use ($model) {
                                    $message->to($model->customer_email, $model->customer_name);
                                });

                                $model->resend_email = false;
                                $model->save();
                            }

                            // Order in Progress
                            if ($order_status == 'in_progress') {

                                // Send Customer Email
                                Mail::send('artistro08.tailorstartercompanion::mail.order_in_progress', $mail_data, function ($message) use ($model) {
                                    $message->to($model->customer_email, $model->customer_name);
                                });

                                $model->resend_email = false;
                                $model->save();
                            }

                            // Shipped Order
                            if ($order_status == 'shipped') {

                                // Send Customer Email
                                Mail::send('artistro08.tailorstartercompanion::mail.order_shipped', $mail_data, function ($message) use ($model) {
                                    $message->to($model->customer_email, $model->customer_name);
                                });

                                $model->resend_email = false;
                                $model->save();
                            }

                            // Cancelled Order
                            if ($order_status == 'cancelled') {

                                // Send Customer Email
                                Mail::send('artistro08.tailorstartercompanion::mail.order_cancelled', $mail_data, function ($message) use ($model) {
                                    $message->to($model->customer_email, $model->customer_name);
                                });

                                $model->resend_email = false;
                                $model->save();
                            }

                        }
                    }
                } catch (Exception $e) {
                    if (Config::get('app.debug') == '')
                        Log::info('Orders Model does not exist, skipping orders code');
                }
            });
        });

        // Hide Blocks if Shop, Events, or blog are disabled
        try {
            $settings      = GlobalRecord::findForGlobal('Content\Settings'); //<-- This code here throws the error
            $enable_shop   = $settings->enable_shop;
            $enable_events = $settings->enable_events;
            $enable_blog   = $settings->enable_blog;
            $enable_search = $settings->enable_search;

            Event::listen('backend.page.beforeDisplay', function ($controller, $action, $params) {
                if ($controller instanceof \Tailor\Controllers\Globals) {
                    $controller->addJs('/plugins/artistro08/tailorstartercompanion/assets/js/companion.js');
                }
            });

            if (! $enable_events)
                Event::listen('backend.page.beforeDisplay', function ($controller, $action, $params) {
                    $controller->addCss('/plugins/artistro08/tailorstartercompanion/assets/css/disable_events.css');
                    $controller->addJs('/plugins/artistro08/tailorstartercompanion/assets/js/disable_events.js');
                });

            if (! $enable_shop)
                Event::listen('backend.page.beforeDisplay', function ($controller, $action, $params) {
                    $controller->addCss('/plugins/artistro08/tailorstartercompanion/assets/css/disable_shop.css');
                    $controller->addJs('/plugins/artistro08/tailorstartercompanion/assets/js/disable_shop.js');
                });

            if (! $enable_blog)
                Event::listen('backend.page.beforeDisplay', function ($controller, $action, $params) {
                    $controller->addCss('/plugins/artistro08/tailorstartercompanion/assets/css/disable_blog.css');
                    $controller->addJs('/plugins/artistro08/tailorstartercompanion/assets/js/disable_blog.js');
                });

            if (! $enable_search)
                Event::listen('backend.page.beforeDisplay', function ($controller, $action, $params) {
                    $controller->addCss('/plugins/artistro08/tailorstartercompanion/assets/css/disable_search.css');
                    $controller->addJs('/plugins/artistro08/tailorstartercompanion/assets/js/disable_search.js');
                });

        } catch (Exception $e) {
            return null;
        }

    }
$settings      = GlobalRecord::findForGlobal('Content\Settings'); //<-- This code here throws the error

Stack Trace is:

#0 /home/artistro08/.sites/adonai/modules/tailor/classes/Fieldset.php(193): Illuminate\Database\Schema\Blueprint->__construct()
#1 /home/artistro08/.sites/adonai/modules/tailor/classes/BlueprintModel.php(137): Tailor\Classes\Fieldset->getContentColumnNames()
#2 /home/artistro08/.sites/adonai/modules/tailor/models/globalrecord/HasGlobalBlueprint.php(93): Tailor\Classes\BlueprintModel->getFieldsetColumnNames()
#3 /home/artistro08/.sites/adonai/modules/tailor/models/globalrecord/HasGlobalBlueprint.php(53): Tailor\Models\GlobalRecord->fetchBlueprintContent()
#4 /home/artistro08/.sites/adonai/vendor/october/rain/src/Support/Traits/Emitter.php(98): Tailor\Models\GlobalRecord->globalAfterFetchEvent()
#5 /home/artistro08/.sites/adonai/vendor/october/rain/src/Database/Concerns/HasEvents.php(41): October\Rain\Database\Model->fireEvent()
#6 /home/artistro08/.sites/adonai/vendor/laravel/framework/src/Illuminate/Events/Dispatcher.php(461): October\Rain\Database\Model->{closure:October\Rain\Database\Concerns\HasEvents::bootNicerEvents():40}()
#7 /home/artistro08/.sites/adonai/vendor/laravel/framework/src/Illuminate/Events/Dispatcher.php(288): Illuminate\Events\Dispatcher->{closure:Illuminate\Events\Dispatcher::makeListener():456}()
#8 /home/artistro08/.sites/adonai/vendor/laravel/framework/src/Illuminate/Events/Dispatcher.php(268): Illuminate\Events\Dispatcher->invokeListeners()
#9 /home/artistro08/.sites/adonai/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Concerns/HasEvents.php(224): Illuminate\Events\Dispatcher->dispatch()
#10 /home/artistro08/.sites/adonai/vendor/october/rain/src/Database/Model.php(178): Illuminate\Database\Eloquent\Model->fireModelEvent()
#11 /home/artistro08/.sites/adonai/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Builder.php(440): October\Rain\Database\Model->newFromBuilder()
#12 [internal function]: Illuminate\Database\Eloquent\Builder->{closure:Illuminate\Database\Eloquent\Builder::hydrate():439}()
#13 /home/artistro08/.sites/adonai/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Builder.php(439): array_map()
#14 /home/artistro08/.sites/adonai/vendor/laravel/framework/src/Illuminate/Support/Traits/ForwardsCalls.php(23): Illuminate\Database\Eloquent\Builder->hydrate()
#15 /home/artistro08/.sites/adonai/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php(2496): Illuminate\Database\Eloquent\Model->forwardCallTo()
#16 /home/artistro08/.sites/adonai/vendor/october/rain/src/Extension/ExtendableTrait.php(485): Illuminate\Database\Eloquent\Model->__call()
#17 /home/artistro08/.sites/adonai/vendor/october/rain/src/Database/Model.php(293): October\Rain\Database\Model->extendableCall()
#18 /home/artistro08/.sites/adonai/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Builder.php(871): October\Rain\Database\Model->__call()
#19 /home/artistro08/.sites/adonai/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Builder.php(854): Illuminate\Database\Eloquent\Builder->getModels()
#20 /home/artistro08/.sites/adonai/vendor/laravel/framework/src/Illuminate/Database/Concerns/BuildsQueries.php(366): Illuminate\Database\Eloquent\Builder->get()
#21 /home/artistro08/.sites/adonai/vendor/laravel/framework/src/Illuminate/Support/Traits/ForwardsCalls.php(23): Illuminate\Database\Eloquent\Builder->first()
#22 /home/artistro08/.sites/adonai/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php(2496): Illuminate\Database\Eloquent\Model->forwardCallTo()
#23 /home/artistro08/.sites/adonai/vendor/october/rain/src/Extension/ExtendableTrait.php(485): Illuminate\Database\Eloquent\Model->__call()
#24 /home/artistro08/.sites/adonai/vendor/october/rain/src/Database/Model.php(293): October\Rain\Database\Model->extendableCall()
#25 /home/artistro08/.sites/adonai/modules/tailor/models/GlobalRecord.php(96): October\Rain\Database\Model->__call()
#26 /home/artistro08/.sites/adonai/plugins/artistro08/tailorstartercompanion/Plugin.php(205): Tailor\Models\GlobalRecord::findForGlobalUuid()
#27 /home/artistro08/.sites/adonai/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Artistro08\TailorStarterCompanion\Plugin->boot()
#28 /home/artistro08/.sites/adonai/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\Container\BoundMethod::{closure:Illuminate\Container\BoundMethod::call():35}()
#29 /home/artistro08/.sites/adonai/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\Container\Util::unwrapIfClosure()
#30 /home/artistro08/.sites/adonai/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\Container\BoundMethod::callBoundMethod()
#31 /home/artistro08/.sites/adonai/vendor/laravel/framework/src/Illuminate/Container/Container.php(754): Illuminate\Container\BoundMethod::call()
#32 /home/artistro08/.sites/adonai/modules/system/classes/PluginManager.php(312): Illuminate\Container\Container->call()
#33 /home/artistro08/.sites/adonai/modules/system/classes/PluginManager.php(290): System\Classes\PluginManager->bootPlugin()
#34 /home/artistro08/.sites/adonai/modules/system/classes/PluginManager.php(277): System\Classes\PluginManager->bootAll()
#35 /home/artistro08/.sites/adonai/modules/system/ServiceProvider.php(94): System\Classes\PluginManager->bootFromProvider()
#36 /home/artistro08/.sites/adonai/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): System\ServiceProvider->boot()
#37 /home/artistro08/.sites/adonai/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\Container\BoundMethod::{closure:Illuminate\Container\BoundMethod::call():35}()
#38 /home/artistro08/.sites/adonai/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\Container\Util::unwrapIfClosure()
#39 /home/artistro08/.sites/adonai/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\Container\BoundMethod::callBoundMethod()
#40 /home/artistro08/.sites/adonai/vendor/laravel/framework/src/Illuminate/Container/Container.php(754): Illuminate\Container\BoundMethod::call()
#41 /home/artistro08/.sites/adonai/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1150): Illuminate\Container\Container->call()
#42 /home/artistro08/.sites/adonai/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1131): Illuminate\Foundation\Application->bootProvider()
#43 [internal function]: Illuminate\Foundation\Application->{closure:Illuminate\Foundation\Application::boot():1130}()
#44 /home/artistro08/.sites/adonai/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1130): array_walk()
#45 /home/artistro08/.sites/adonai/vendor/laravel/framework/src/Illuminate/Foundation/Bootstrap/BootProviders.php(17): Illuminate\Foundation\Application->boot()
#46 /home/artistro08/.sites/adonai/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(341): Illuminate\Foundation\Bootstrap\BootProviders->bootstrap()
#47 /home/artistro08/.sites/adonai/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(186): Illuminate\Foundation\Application->bootstrapWith()
#48 /home/artistro08/.sites/adonai/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(170): Illuminate\Foundation\Http\Kernel->bootstrap()
#49 /home/artistro08/.sites/adonai/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(144): Illuminate\Foundation\Http\Kernel->sendRequestThroughRouter()
#50 /home/artistro08/.sites/adonai/index.php(42): Illuminate\Foundation\Http\Kernel->handle()
#51 /home/artistro08/.config/composer/vendor/cpriego/valet-linux/server.php(239): require('...')

Am I doing something wrong or?

I just upgraded from v3 to v4 and that somehow fixed the issue. If i had to guess, it was a plugin dependency that got cached and I couldn’t remove it

Nevermind, it’s still there. Weirdly, turning debug mode on fixes the issue

Hey man

It’s an intermittent issue caused by a change in the Laravel internals.

Basically the connection grammar for the schema builder is lazy loaded now. One way to force it to load it is by calling

\Db::connection()->getSchemaBuilder();

This was added to the tailor:migrate command where it could be reproduced reliably.

I’m unsure why it is happening in your use case, however, adding a call to that method somewhere should ensure the grammar is loaded and fix the error.

1 Like

Do you think it might be because I call some Tailor functions on the layout? I use Tailor to create a form submission. Here’s some example code:

function onFormSubmit() {

    $form_input = input();
    $form_id = $form_input["form_id"];
    $form_success_message = $form_input["success_message"];
    $form = EntryRecord::inSection('Content\Forms')->find($form_id);
    $submission = EntryRecord::inSection('Content\Forms\Submissions');
    $settings = GlobalRecord::findForGlobal('Content\Settings');
    $form_validation_rules = [];
    $form_validation_messages = [];
    $form_input_formatted = '';
    $form_name = '(no data)';
    
    // Parse form validation data
    foreach ($form->fields as $field) {
        
        $field_validation_rules = [];
        $field_validation_messages = [];

        if($field->validation == true) {

            foreach ($field->validation_rules as $validation_item) {
                if($validation_item->attributes['validation_type'] == "phone") {
                    $field_validation_rules[] = "regex:/^([0-9\s\-\+\(\)]*)$/";
                    $field_validation_rules[] = "min:9";
                    $field_validation_messages[$field->slug . '.' . "regex"] = $validation_item->attributes['error_message'];
                    $field_validation_messages[$field->slug . '.' . "min"] = $validation_item->attributes['error_message'];
                } elseif ($validation_item->attributes['validation_type'] == "regex") {
                    $field_validation_rules[] = "regex:" . $validation_item->attributes['regex'];
                    $field_validation_messages[$field->slug . '.' . "regex"] = $validation_item->attributes['error_message'];
                } elseif ($validation_item->attributes['validation_type'] == "custom") {
                    $rule_name = strtok($validation_item->attributes['custom'], ':');
                    $field_validation_rules[] = $validation_item->attributes['custom'];
                    $field_validation_messages[$field->slug . '.' . $rule_name] = $validation_item->attributes['error_message'];
                } else {
                    $field_validation_rules[] = $validation_item->attributes['validation_type'];
                    $field_validation_messages[$field->slug . '.' . $validation_item->attributes['validation_type']] = $validation_item->attributes['error_message'];
                }
                
            }
            
            $form_validation_rules[] = [$field->slug => $field_validation_rules];
            $form_validation_messages[] = $field_validation_messages;
            if($form->enable_recaptcha) {
                $form_validation_rules[] = [
                    'g-recaptcha-response' => 'required|recaptcha'
                ];
                $form_validation_messages[] = [
                    'g-recaptcha-response.required' => 'Please ensure you are not a robot.'
                ];
            }
        }

    }

    // Format Rules and messages
    $form_validation_rules = array_merge(...$form_validation_rules);
    $form_validation_messages = array_merge(...$form_validation_messages);

    $form_unwanted_fields = [
        "form_id",
        "g-recaptcha-response",
        "success_message",
        "submitted",
        "_preview_token"
    ];

    // Validate Fields
    $validation = Validator::make(request()->all(), $form_validation_rules, $form_validation_messages);

    if($validation->fails()) {
        throw new ValidationException($validation);
    }
    
    foreach ($form_input as $key => $value) {
        
        if(!in_array($key, $form_unwanted_fields)) {
            if($key == array_key_first($form_input)){
                $form_name = (!empty($value)) ? $value : $form_name;
            }
            
            $key = ucwords(str_replace("-", ' ', $key));
            
            if(is_object($value)) {
                $form_input_formatted .= $key . ": " . $value->getClientOriginalName()  . "\n";
            } else {
                $form_input_formatted .= $key . ": " . $value  . "\n";
            }
        }
        
        if(is_object($value)) {
            $submission->files = $value;
        }
        
    }

    $submission->title = $form_name;
    $submission->form  = $form_input['form_id'];
    $submission->data  = $form_input_formatted;
    
    $submission->save();

    // Send Email
    $mail_data = [
        'form_name' => $form->title,
        'form_data' => $form_input_formatted,
    ];

    $mail_recipients = [];
    

    if(!$form->recipients->isEmpty()){
        foreach ($form->recipients as $recipient) {
            $mail_recipients[$recipient->email] = $recipient->name;
        }
    } else {
        if((!empty($settings->notification_email) && (!empty($settings->notification_email_recipient_name)))) {
            $mail_recipients = [
                $settings->notification_email => $settings->notification_email_recipient_name
            ];
        }
        
    }

    if(($form->enable_notifications) && (!empty($mail_recipients))) {

        Mail::send('artistro08.tailorstartercompanion::mail.form_submission', $mail_data, function($message) use ($mail_recipients, $form) {
            foreach ($mail_recipients as $email => $name) {
                $message->to($email, $name);
                $message->subject('New Form Submission from ' . $form->title);
            }
        });

    }

    Flash::success($form_success_message);

    $this['submitted'] = $form_input['submitted'];

}