Enable or disable DebugKit depending on user setting


#1

Hi,
I am developing a cms (content management system) using cakephp 3, and would like the user of the cms to be able to enable and disable the debugkit through an administrator form.

I store this choice in database. Problem is, DebugKit is initiated in bootstrap.php, before the value are read from database. I read the value in AppController::initialize(), way too late in the cakephp page load ride.

Is there a better way to let the user enable/disable debugging than letting them edit app.php?

Thank’s for any tips or heads-ups!


#2

Just to clarify:

For some reason I cannot use the TableRegistry in bootstrap.php. I get the following exception:
Fatal error: Uncaught Cake\Datasource\Exception\MissingDatasourceConfigException: The datasource configuration “default” was not found.

I have the following line:

use Cake\ORM\TableRegistry;

Further down in code:

$kitchenSink = TableRegistry::get(‘KitchenSink’);

And it is this line of code where the exception happens.


#3

You should put the code at the bottom of the bootstrap, after all the calls to Configure are made


#4

Hi raul338,
that is what I have done, it is at the very bottom of the file bootstrap.php.

I never checked in the code with the kitchensink, but the it was at line 256 here at github:
/madskullcreations/simplicity/blob/master/config/bootstrap.php
(sorry for the incomplete url, I am not allowed to put full links)


#5

I have done this using ConfigEngineInterface
https://api.cakephp.org/3.4/class-Cake.Core.Configure.ConfigEngineInterface.html
Read key/values from database and set with Configure::load()

src/Configure/Engine/DataBaseConfig.php

namespace App\Configure\Engine;

use Cake\Core\Configure\ConfigEngineInterface;
use Cake\ORM\TableRegistry;

class DataBaseConfig implements ConfigEngineInterface
{
    public function __construct($configureClass = null)
    {
        if (!$configureClass) {
            $configureClass = 'ConfigDB';
        }
        $this->_configureClass = $configureClass;
    }

    public function read($key)
    {
        $configArray = [];
        $configureDB = TableRegistry::get($this->_configureClass);
        $configArray = $configureDB->getDbConfig();
        /*
          Muffin plugin fix - https://github.com/UseMuffin/Footprint#warning
        */
        TableRegistry::remove($this->_configureClass);
        return $configArray;
    }
}

src/Model/Table/ConfigDBTable.php

namespace App\Model\Table;

use Cake\ORM\Table;
use Cake\Validation\Validator;

class ConfigDBTable extends Table
{
    public function initialize(array $config)
    {
        $this->setTable('my_config_table');
        //  id | key | value | type_id | enabled | description 
        // key should be the configure() array key ex: AppConfig.DebugKit.enable
        // value example: true/false
        $this->setPrimaryKey('id');
        
        $this->addBehavior('Timestamp', [
            'events' => [
                'Model.beforeSave' => [
                    'created' => 'new',
                    'modified' => 'always'
                ]
            ]
        ]);

    public function validationDefault(Validator $validator)
    {
        $validator
            ->notEmpty('key')
            ->notEmpty('value')
            ->notEmpty('description')
        return $validator;
    }

    public function parseVar($var, $type)
    {
        $parsedVar = $var;
        switch ($type) {
            case 1:
                $parsedVar = strval($var);
                break;
            case 2:
                $parsedVar = intval($var);
                break;
            case 3:
                $parsedVar = floatval($var);
                break;
            case 4:
                $parsedVar = boolval($var);
                break;
            default:
                $parsedVar = $var;
        }
        return $parsedVar;
    }

    public function getDbConfig()
    {
        $configVars = $this->find()
            ->select(['key', 'value', 'type_id'])
            ->where(['enabled' => 1]);
        
        if (empty($configVars )) {
            return;
        }
        foreach ($configVars as $configVar) {
            $configArray[$configVar->key] = $this->parseVar($configVar->value, $configVar->type_id);
        }
        return $configArray;
    }
}

bootstrap.php:

try {
    Configure::config('db', new DataBaseConfig());
    Configure::load('db-setup', 'db', false);
} catch (\Exception $e) {
    exit($e->getMessage() . "\n");
}

use in debugkit or email config etc

'debug' => filter_var(env('DEBUG', \Cake\Core\ConfigureConfigure::read('AppConfig.DebugKit.enable')), FILTER_VALIDATE_BOOLEAN),

'EmailTransport' => [
        'default' => [
            'className' => 'Cake\Mailer\Transport\SmtpTransport',
            // The following keys are used in SMTP transports
            'host' => Configure::read('Email.Contact.host'),
            'port' => Configure::read('Email.Contact.port'),