Question about settings and plugin, etc?

7 posts by 2 authors in: Forums > CMS Builder
Last Post: October 7   (RSS)

I have a modified Settings.dat.default.php file that presets many options for me such as a list of plugins, media.ini on, admin and dev email addresses etc. It was a pain to maintain when new versions came out  and the settings file was reorganized. I was hoping for a better way. Now with the default settings file now constructed programmatically, I see an opportunity to achieve my goal.

it would be great if we could provide a list of plugins and other settings in a custom config  file or something similar that could be integrated into the install. My goal is to remove the manual necessity to make these changes on each new project as very little is different from one client to the next.

For instance my email address for dev and admin don’t change, I always want certain plugins, I always have a custom help menu pointing at a help table, I always use media.ini (which has been customized with image sizes and info1-5 titles), my custom branding doesn’t change, and the list goes on. The only thing that changes for sure is DB info.

Jeff Shields

that is what I have been doing, A couple of times recent changes to the settings file broke that approach and I had to repair the files. Anyway, I will continue with what I was doing.

Jeff Shields

I added this function to my plugin with "pluginAction_addHandlerAndLink('Activate My Plugins', 'activateMyPlugins', 'admins');"

/**
 * Activate plugins in the /_activate-plugins.php file when the plugin is
 * activated.
 *
 * This function is executed when the plugin is activated. It reads the
 * "plugins.txt" file in this folder and activates each plugin listed in
 * the file.
 *
 * @return void
 */
function activateMyPlugins()
{

    // Get a list of all active plugins
    // @var array $activePlugins
    $activePlugins = array_filter(
        // Split the string into an array
        array_map('trim', explode(',', str_replace("\n", '', settings('activePlugins')))),
        // Remove empty strings from the array
        function ($value) {
            return $value !== '';
        }
    );

    $pluginsFile = fopen(__DIR__ . '/plugins.txt', 'r');
    $pluginName = '';
    while (!feof($pluginsFile)) {
        $pluginName = fgets($pluginsFile);
        $pluginName = trim($pluginName);
        //check if plugin is active or not
        if (! in_array($pluginName, $activePlugins)) {
            if ($pluginName != '') {
                activatePlugin($pluginName);
            }
        }
    }
}

I have a simple text file that lists the plugins I always want to install. I can then run the command from the action column from my plugin to activate my standard plugins.

Jeff Shields

By kitsguru - October 7 - edited: October 7

I solved my final issue with settings. Instead of copying files into the data directory with predefined settings, I created two functions in my app plugin. This system plugin is used in all my projects and provides many functions, including adding records to specific tables, validating data entry, and more.

pluginAction_addHandlerAndLink('Settings Production', 'mySettingsProduction', 'admins');
pluginAction_addHandlerAndLink('Settings Development', 'mySettingsDevelopment', 'admins');

The two functions use Settngs::update to change the values for production and development servers. Some values are always set.

use Itools\Cmsb\Settings;

function mySettingsDevelopment()
{
    Settings::update([
        'websiteUrl' => '/',
        'programName' => 'My App',
        "advanced.login_expiry_limit" => 30,
        "advanced.login_expiry_unit" => "days",
        "advanced.showExpandedMenu" => "1",
        'advanced.useMediaLibrary' => '1',
        'advanced.useDatepicker' => '1',
        'advanced.codeGeneratorExpertMode' => '1',
        'advanced.phpHideErrors' => '0',
        'advanced.ignoreDeveloperWarnings' => '0',
        'footerHTML' => '<p>A custom app by me</p>',
        'helpUrl' => '?menu=help',
        'timezone' => 'America/Vancouver',
        'vendorLocation' => 'British Columbia, Canada',
        'vendorName' => 'me',
        'vendorUrl' => 'https://example.com',
        'mail.adminEmail' => 'me+admin@example.com',
        'mail.developerEmail' => 'me+dev@example.com',
        'mail.outgoingMail' => 'sendAndLog',
        'mail.smtp_method' => 'ssl',
        'mail.smtp_hostname' => 'mail.example.com',
        'mail.smtp_password' => '', // use password manager to set after running this
        'mail.smtp_port' => '465',
        'mail.smtp_username' => 'me@example.com',
        'mail.phpEmailErrors' => '0',
    ]);
}

function mySettingsProduction()
{
    Settings::update([
        'websiteUrl' => '/',
        'programName' => 'My App',
        "advanced.login_expiry_limit" => 30,
        "advanced.login_expiry_unit" => "hours",
        "advanced.showExpandedMenu" => "1",
        'advanced.useMediaLibrary' => '1',
        'advanced.useDatepicker' => '1',
        'advanced.codeGeneratorExpertMode' => '1',
        'advanced.phpHideErrors' => '1',
        'advanced.ignoreDeveloperWarnings' => '1',
        'footerHTML' => '<p>A custom app by me</p>',
        'helpUrl' => '?menu=help',
        'timezone' => 'America/Vancouver',
        'vendorLocation' => 'British Columbia, Canada',
        'vendorName' => 'me',
        'vendorUrl' => 'https://example.com',
        'mail.adminEmail' => 'me+admin@example.com',
        'mail.developerEmail' => 'me+dev@example.com',
        'mail.outgoingMail' => 'sendOnly',
        'mail.smtp_method' => 'php',
        'mail.smtp_hostname' => '',
        'mail.smtp_password' => '',
        'mail.smtp_port' => '',
        'mail.smtp_username' => '',
        'mail.phpEmailErrors' => '1',
    ]);
}
Jeff Shields

Hi Jeff, 

That's great!  Thanks for sharing your elegant solution.  I like how you can enable all your custom settings from the plugin menu.

It can be useful to see all the strategies everyone uses for managing their dev/prod environments.  

Here's how I have mine setup.  I work with a lot of websites so this setup is optimized for the use-case: 

  • I run WampServer on Windows for an instant WAMP stack that let's me toggle between PHP versions as needed for testing
  • My dev web server on my desktop responds to anything at *.localhost and automatically maps it to a folder 
  • So, for example, https://example.com.localhost/ automatically maps to my local drive C:/vhosts/example.com/htdocs/ use Apache <VirtualHost *> rules
  • If a folder doesn't exist a specialized 404 page gives me the option to create it with a click
  • Then I use hostname-specific settings files for dev environments such as /data/settings.example.com.localhost.dat so there's no possibility of overwriting a live settings file
  • I'll often change the title and color of the dev CMSB so it's clear when I'm on which

Mine only works locally though, not helpful if you need to show something to a remote user.

Thanks for sharing!

Dave Edis - Senior Developer
interactivetools.com

I use Zoom and screen sharing to show users/clients things I am running locally. I also set up a staging environment on my production VPS for them to test and review. Each project has three environments: development (local), staging (VPS), and production (VPS). The staging and production environments are identical except for the database and HTML directories. I use "git FTP" to copy files up to the server.

My development setup is on a Mac Mini M2 Pro (16GB RAM) with a Samsung M7 monitor. I use the appropriate setup guides from https://getgrav.org/blog. I have used his guides for each new version of MaxOS since version 10.12 (Sierra), when I switched back to Mac from Windows and Linux (2 machine setup) in 2016.

Each project (approximately 50) is its own subdomain of yaa.test. I use dnsmasq for local DNS resolution of my development domains: client1.yaa.test, client2.yaa.test ...

I also use host-specific settings files like you do.

My staging/production VPS is on DigitalOcean and runs CloudLInux 9 (almalinux 9) with cPanel. My Mac setup uses the same Apache, PHP and MariaDB versions on my VPS. 

I use git for version control with private remote repositories on bitbucket.com.

I use nodejs and bash to write tooling scripts for creating new projects, updating existing projects, transferring data between databases, creating directories, coping files, compiling CSS and JS, and any necessary build processes. What used to take 3 to 4 hours to set up a new project manually takes less than 5 minutes with my automated processes.

I use a CSS file to add a text overlay in the top left corner of the window to show that I am in development and which breakpoint is currently in effect to test responsive layouts. This only loads in my development environment. I am presently using Bootstrap 5.3.3 for my projects.

// dev.css

@media screen {
  body::before {
    font-size: 16px;
    content: "dev";
    color: #fff;
    background-color: #f00;
    position: fixed;
    top: 0;
    left: 0;
    padding: 5px;
    z-index: 9999;
  }
}
@media screen and (min-width: 576px) {
  body::before {
    content: "dev sm";
  }
}
@media screen and (min-width: 768px) {
  body::before {
    content: "dev md";
  }
}
@media screen and (min-width: 992px) {
  body::before {
    content: "dev lg";
  }
}
@media screen and (min-width: 1200px) {
  body::before {
    content: "dev xl";
  }
}
@media screen and (min-width: 1400px) {
  body::before {
    content: "dev xxl";
  }
}
Jeff Shields