<p align="center">
<img src="https://user-images.githubusercontent.com/17110935/184906978-5b1c89d6-75b5-496f-b073-d755433dd2a1.png" alt="Uplift CMS logo">
</p>

# Uplift - the Footbridge Media Content Management System (CMS)

**Version: 4**

Uplift is a proprietary content management system utilizing a MySQL database. The primary purpose of this software is to increase development and management efficiency of Footbridge websites as well as unify updating across entire ranges of websites.

Uplift CMS provides cutting edge processing speed with the use of the latest versions of PHP, slashes the time it takes to manage a website and allows it to be done in the cloud via a browser. Uplift includes a basic image manager that allows cropping, resizing, and type conversion.

## Requirements
Extension requirements are all listed in the composer.json file. However, on the surface the following major requirements must be met.
 * PHP 8.1+
 * MySQL
 
For development:
 * NodeJS (for Babel)

This list is not exhaustive and may change.

## Major Version 3 -> 4
Moving from version 3 to version 4 introduces the minimum PHP version bump to version 8. With this, new features are brought into the system including the support of attributes and attribute routing.

Additionally, the codebase has been unified to a true MVC structure with database models, instance classes, and model classes with no need for SQL queries to perform database interactions.

## The Choice to Commit the /vendor Directory
Due to the fact that we cannot always control which server Uplift is installed onto, we do not always have the necessary control to run composer commands. The vendor directory is therefore part of the publishable build.

## Babel Compilation for Client-Facing JavaScript
A working Node CLI environment is required to write JavaScript code in and for Uplift. All JavaScript was written in the `js` directory in the resources folder. After installing the necessary dependencies defined in `package.json`, run the command `npm run build` to compile vanilla JS into the legacy-compatible JS which will then be moved to the `js-prod` directory.

### TypeScript
As of April 2023, TypeScript is the preferred method of writing front-end JavaScript. You can compile the TypeScript you write in the `ts` directory to legacy-compatible JavaScript by running the CLI command `npm run build-ts` which will move it to `js-prod` after compiling.

## Installation
Upon closing or downloading this repository, move all files (excluding the README.md and the .git folder) into a new directory - your working directory - for new site development.

Then, copy the `nox-env.example.php` file and rename it to `nox-env.php`. Open this file and adjust the variables to match your current environment (such as the MySQL credentials). Additionally, change the `DEV_ENV` value from `development` to `production`

Next, point your server (typically Apache via XAMPP) to the project root directory to serve your website from. Now, visit the localhost address of your project to begin the in-browser installation. This will install the rest of the system after you fill in the necessary data fields.

### Adding a Post-Update Process
After every update, the front-end JS (for in-Uplift updates, but GuzzleHttp is used for Uplift Control Panel forced updates) will send a GET request to an UpdateController route that will run all PostUpdateProcess classes that are registered.

To create a process to be run after an update (it will run on the newly updated package code and not the old source code) you can add a **class that must inherit** from PostUpdateProcess.php into the `src/System/Updater/PostUpdate` directory. **Then** you must open the `src/System/Updater/UpdaterService.php` class file and navigate to the static method `runPostUpdateProcesses`. There, add a line of code that runs your new PostUpdateProcess `runProcess` method.

### How Does the System Check if It Is Installed?
If the database defined in the `nox-env.php` file is not empty, then Uplift will assume the system has been installed.

So, to "uninstall" a development build you would simply drop all tables in the database that you've linked.

## CLI Utility Scripts
The following are utility scripts that can be run via a CLI or SSH CLI (in the case of remote servers). Some scripts have input prompts you would need to fill out after running them.

### Creating an Account via CLI
```bash
$ php uplift-core/cli-scripts/create-account.php
```

### Manually Synchronizing Database Models to Database Tables and Columns
```bash
$ php uplift-core/cli-scripts/sync-models.php
```

### Changing an Existing Account Password
```bash
$ php uplift-core/cli-scripts/change-account-password.php
```

### Test Downloading + Installing Update
Only works in development environments. Will install to a test directory named "extraction-test"
```bash
$ php uplift-core/cli-scripts/test-update-system.php
```

## MVC Structure - Microservices
As of major version 4, Uplift follows a strict MVC architecture utilizing microservices to control the many features of the system. All backend source code directories that involve Controllers will also include a Service class for the Controller to call upon. For example
```
ImageGallerController
ImageGalleryService
```
Where a service handles the logic of performing mechanics and interfacing with the database layer, while the Controller simply accepts a request and pulls out the necessary information to pass to the controller.

Models are in a models directory and represent MySQL database tables and their structure. Any PHP class extending the Nox\ORM\ModelClass parent class can be used to create or fetch rows from the database tables in a pure PHP syntax utilizing the Nox Abyss ORM.

## Initial Page Generation
The definition of which pages are available for generation upon install are found in `uplift-core/resources/initial-pages`

## Uplift Master Control Panel
The master control panel is hosted on https://uplift.footbridgemedia.com and is where the production environment will direct requests for master control panel communication.

For **development environments** all control panel communication is, instead, directed to http://localhost:1337

### Attribute Route Authentication
To protect a route with remote header authentication for being communicated with by the remote master control panel, you can use the `AuthorizeByAPIKey` attribute located in the `\APIPublic` namespace. This will check for an `Authorization` header with the API key as a value.

### Assigning the API Key
The API key is assigned by the Uplift master control panel to the local instance during the installation of the Uplift CMS. This API key is unique to the installation and is what is used for bi-direction communication to and from the Uplift master control panel.

## The Update Process
As of version 4, the update process works by querying the GitHub API using an access token from a repository owner.

This is done via the Uplift Master Control Panel API and isn't tied to any specific build. An individual build will query the master control panel API and send the current build version to it. The master control panel will then check the Footbridge-CMS repository (this repository) for its latest releases. The `tag_name` **must** be a valid version number. The build version and the latest release tag_name are then compared to see if the latest release is more current.

If it is more current, the Uplift Master Control Panel API endpoint will send back the necessary information (including the URL to download the release zip file) to the individual build asking for update information.

The individual build will then unzip the archive and install the update.

**Make sure to** release builds that have the correct version set in the `src\System\System.php` class in the version constant.

#### What Files Get Installed in an Update?
The JSON file `install-entries.json` in this repository's root is a JSON array of entries that the updater will install after downloading the updated release. Directories or files can be listed here. All entries must start with a `/` and are relative to the repository root.

### Releasing an Update
To release an update, simply publish a new Release on this GitHub repository. You **must** update the version number in `uplift-core/src/System/System.php` adjusting the `VERSION` constant to represent the new version number. If this isn't done before performing a release then the released build will consistently believe it is outdated when checking the master server for the latest build version. 

### Test Updates
When the NoxEnv::DEV_ENV is set to "development" - any updates performed will be extracted to a repository-root directory named `extraction_test`. If this directory doesn't exist, the updater will create it.

## Internal Cron System
Because it is a hassle - and sometimes not possible - to set up cron jobs for every build, Uplift CMS includes an internal cron-job handler. It is a synthetic cron system that is based on requests to the system being made in general - for any page request on the public front end.

### Registering a Cron
View or copy one of the cron jobs in the `uplift-core/Crons/Jobs` directory. All crons should extend from the `Crons\Jobs\Job` abstract class. Once you've created your cron and added its logic, register it by editing the `uplift-core/Crons/CronsService.php` file and manually adding it to the array that `getRegisteredCrons` returns.

Your array value should look like the below
```php
(new YOUR_CRON_CLASS(self::getLastCronRunTimestamp(YOUR_CRON_CLASS::class))),
```

## System Logging
Caught exceptions and system logging can be found in /uplift-data/logs

## Exporting a Website
You don't have to set up a local virtual host to do this - you just have to have the website files in a folder and have a valid database connection with a database that has the information for the build.

After confirming this, run the following export script
```bash
php uplift-core/cli-scripts/export-build.php
```

An exported zip, `export.zip`, will be placed into the project root. This will contain all the pages and necessary resources as well as redirects for the site to now be a raw site export.

## Sub-Documentation
View the README files for these pages (scroll down in GitHub to see them) for documentation on the below objects.
* Pages: https://github.com/footbridge-media-development/Footbridge-CMS/tree/master/uplift-core/src/Page
* ImageManager: https://github.com/footbridge-media-development/Footbridge-CMS/tree/master/uplift-core/resources/static/js/image-manager

## Contributing
All contributions should be done via a separate branch and will be reviewed in a pull request. Do your best to keep contributions to small pull requests to make reviewing easier and faster.

## License
None. This is private and proprietary software not meant for redistributing.
