Skip to content

Commit

Permalink
FEATURE: Configuration as code (#553)
Browse files Browse the repository at this point in the history
* First pass at change detection from JSON config files.

* working comparision of form and text element values.

* First working version of diffing between JSON config and database with admin page output.

* Major refector for element value parsing and diff detection for forms and elements.

* Adding more element mappings.

* Simple JSON download for configuration.

* Adding form_handle to elements. updated formulize config sync to no longer deal with ids as primary identifier.

* Handling the upate case for elements with forms that are already created.

* Handling creation and removal of form data table.

* Adding some notes and moving the location of the form operations.

* working version of correctly keeping the form data table in sync with changes

* Refining the deletion of the data table and columns since they need to be done before the definitions are destroyed.

* Reorganizing and renaming to remove emphasis on JSON as the config format.

* Reverting change to add form_handle to element table.

* Refactor of config to no longer need the form_handle on the elements.

* Supporting element datatype for exporting and creating elements.

* Fixing dangling comma on sql query

* Restructuring apply operations to be atomic and improving UI with correct feedback.

* small tweaks.

* Fixing loading of config data not working corretly. Updating WRITEASNULL to just return NULL.

* Support changing element data types.

* Adding constants for translations for duration UI.

* adding backend validation in the event frontend validation fails.

* Convert all number inputs to type number with a min value. Fixing updated class name, adding styling to base theme.

* Reverting unchanged files.

* Removing duration element since it's been moved to it's own PR.

* update to help text.{

* Adding boilerplate to top of config sync files.

* Adding configuration as code docs.
  • Loading branch information
arvinsingla authored Nov 15, 2024
1 parent b670f63 commit 37cb130
Show file tree
Hide file tree
Showing 10 changed files with 1,395 additions and 67 deletions.
47 changes: 47 additions & 0 deletions docs/configuration_as_code.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
---
layout: default
permalink: developers/configuration_as_code/
---

# Configuration as code

Formulize now supports configuration-as-code for Forms and Elements. This allows you to version control your sites configuration. Since Formulize is a database driven application the configuration as code acts as a synchronization of the datatabase to match what is stored in the configuration file. The configuration file is considered the source of truth. This does not prevent you from making configuration changes in your formulize instance, instead it allows you to see if your formulize configuration has deviated from what's store in the configuration and synchronize/revert if necessary.

To access the configuration screen. Go to the formulize admin page and click on the "Configuration Synchronization" link. It can also be accessed directly by adding the following to the path of your formulize url `modules/formulize/admin/ui.php?page=config-sync`

## Configuration Files

Configuration files are stored in the `modules/formulize/config` folder as JSON files (e.g. `forms.json`)

## Supported operations

When accessing the Configuration Synchronization administrative screen you can be presented with the following operations.

### Export configuration

This will export the current state of the database as a configuration file which you can then place inside the configuration folder `modules/formulize/config`

### Create

When configuration exists in the configuration file but not in the database they can be created in the database

### Update

When the same object exists in the database and in the configuration file but they differ in some way the element in the database can be updated to match what is in the configuration file. The differing values will be displayed on othe configuration screen.

### Delete

When an object exists in the database but not in the configuration file it can be deleted so that the database matches what is in the configuration file.

## Example workflow

Here is an example of how you could use the configuation-as-code functionality when building a formulize application.

1. Build and configure your forms in the UI as you normally would.
1. Once you are happy with the set up go to the configuration synchronization page and export the configuration. Place this file in the config directory `modules/formulize/config`
1. Commit this file into your repository
1. As you continue to make changes to your application you can periodically do one of the following.
1. revert the selected changes if you aren't happy with them
1. Perform a new export and overwrite the file in the config directory

![Configuration as code example](./images/configuration-as-code.png)
1 change: 1 addition & 0 deletions docs/developer.html
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,5 @@ <h1>Developer Docs</h1>
<li><a href='./git_tips'>Git Tips and Tricks</a></li>
<li><a href='./templates'>Working With Templates</a></li>
<li><a href='./scss-sass'>Using SCSS and Sass</a></li>
<li><a href='./configuration_as_code'>Configuration as code</a></li>
</ul>
Binary file added docs/images/configuration-as-code.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
75 changes: 75 additions & 0 deletions modules/formulize/admin/config-sync.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
<?php
###############################################################################
## Formulize - ad hoc form creation and reporting module for XOOPS ##
## Copyright (c) Formulize Project ##
###############################################################################
## XOOPS - PHP Content Management System ##
## Copyright (c) 2000 XOOPS.org ##
## <http://www.xoops.org/> ##
###############################################################################
## This program is free software; you can redistribute it and/or modify ##
## it under the terms of the GNU General Public License as published by ##
## the Free Software Foundation; either version 2 of the License, or ##
## (at your option) any later version. ##
## ##
## You may not change or alter any portion of this comment or credits ##
## of supporting developers from this source code or any supporting ##
## source code which is considered copyrighted (c) material of the ##
## original comment or credit authors. ##
## ##
## This program is distributed in the hope that it will be useful, ##
## but WITHOUT ANY WARRANTY; without even the implied warranty of ##
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ##
## GNU General Public License for more details. ##
## ##
## You should have received a copy of the GNU General Public License ##
## along with this program; if not, write to the Free Software ##
## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ##
###############################################################################
## Author of this file: Formulize Project ##
## Project: Formulize ##
###############################################################################

/**
* Configuration as code synchronization admin screen
*/

// Operations may require additional memory and time to perform
ini_set('memory_limit', '1024M');
ini_set('max_execution_time', '600');
ini_set('display_errors', 1);

include_once '../include/formulizeConfigSync.php';

$breadcrumbtrail[1]['url'] = "page=home";
$breadcrumbtrail[1]['text'] = "Home";
$breadcrumbtrail[2]['text'] = "Configuration Synchronization";

$configSync = new FormulizeConfigSync('/config');
$diff = $configSync->compareConfigurations();

$adminPage['template'] = "db:admin/config-sync.html";
$adminPage['success'] = [];
$adminPage['failure'] = [];

if (isset($_POST['action']) && $_POST['action'] == 'export') {
$export = $configSync->exportConfiguration();
header('Content-Type: application/json');
header('Content-Disposition: attachment; filename="forms.json"');
echo $export;
exit();
}


if (isset($_POST['action']) && $_POST['action'] == 'apply') {
$changes = $_POST['handles'] ?? [];
$result = $configSync->applyChanges($changes);
$adminPage['success'] = $result['success'];
$adminPage['failure'] = $result['failure'];
// Compare the config again if we've applied changes so the results are up to date
$diff = $configSync->compareConfigurations();
}

$adminPage['changes'] = $diff['changes'];
$adminPage['log'] = $diff['log'];
$adminPage['errors'] = $diff['errors'];
3 changes: 3 additions & 0 deletions modules/formulize/admin/ui.php
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,9 @@
case "managepermissions":
include "managepermissions.php";
break;
case "config-sync":
include "config-sync.php";
break;
default:
case "home":
include "home.php";
Expand Down
Loading

0 comments on commit 37cb130

Please sign in to comment.