# New Wiaas

Wiaas implementation based on wordpress [woocommerce](https://woocommerce.com/) plugin.

## Dependencies

- PHP (7.0)
- MySQL server (5.7)
- [Composer](http://getcomposer.org)
- [WP CLI](https://wp-cli.org/#installing)
- [PHPUnit](https://phpunit.de/getting-started/phpunit-6.html) for Unit testing
- NodeJS (for building & developing frontend)

## Local Docker setup

1) Copy environment.env file and rename it to .env 
    
        cp environment.env .env

2) Edit .env file and add needed information

 * `MYSQL_ROOT_PASSWORD` - MySQL database root password for MySQL docker image
 * `MYSQL_DATABASE` - Wordpress database name
 * `MYSQL_USER` - Wordpress database user
 * `MYSQL_PASSWORD` - Wordpress database password
 * `API_URL` - Full URL to WordPress home (http://localhost:8081 if you are testing locally)
 * `WP_ENV` - Set to environment (`development`, `staging`, `production`)
 * `WP_AUTH_KEY`, `WP_SECURE_AUTH_KEY`, `WP_LOGGED_IN_KEY`, `WP_NONCE_KEY`, `WP_AUTH_SALT`, `WP_SECURE_AUTH_SALT`, `WP_LOGGED_IN_SALT`, `WP_NONCE_SALT`, `WP_JWT_AUTH_SECRET_KEY`
    
3) Execute in the root of the project :
        
       sudo docker-compose build
       sudo docker-compose up

Frontend is running on http://localhost:8080 and backend on http://localhost:8081 


    
## Local development setup


### DB setup

1) Create MYSQL database / user

       CREATE DATABASE ${MYSQL_DATABASE};
       CREATE USER '${MYSQL_USER}'@'localhost' IDENTIFIED BY '${MYSQL_PASSWORD}';
       GRANT ALL PRIVILEGES ON ${MYSQL_DATABASE}.* TO '${MYSQL_USER}'@localhost;

2) Seed database with `new-wiaas/database/clean-dump.sql`

### Backend setup

1) Environment variables


For handling wordpress environment variables during local development we use [dotenv](https://github.com/vlucas/phpdotenv) library
which enables loading variables  from `.env` file.

If you wish to keep your docker and development setup different then generate `development.env` file which will then
be loaded by dotenv insted of default `.env` file.

    cp environment.env development.env
   
Update `development.env` with your local environment variables overrides.

2) Apache

Point your apache server to `new-wiaas/backend` by updating apache default host files to point to it.  
(do not copy folder content to `/var/www/html`, since then dotenv will not be able to load `local.env` file since it is placed one folder above.)

Copy .htaccess from `/docker/php` to `backend`.

3) Wordpress

Run setup commands to install wordpress and required plugins with composer:

        cd backend
        composer install
        composer update-db
   


### Frondend setup

1) Install dependencies

        cd frontend
        npm install
        
2) Start local server
  
        cd frontend
        npm start
 
      
## Contribution

### Backend
 
#### Project structure
 
Project structure is inspired with [Roots Bedrock structure](https://roots.io/bedrock/).
                    
        
            ├── composer.json             # → Manage versions of WordPress, plugins & dependencies
            ├── config                    # → WordPress configuration files
            │   ├── application.php       # → Primary WP config file (wp-config.php equivalent)
            │   └── environments          # → Environment specific configs
            │       ├── development.php   # → Development config
            │       ├── local.php         # → Local config
            │       └── production.php    # → Production config
            ├── vendor                    # → Composer packages (never edit)
            ├── app                       # → wp-content equivalent
            │   ├── mu-plugins            # → Must use plugins
            │   └── plugins               # → Plugins
            │      ├── wiaas              # → Our code goes here
            │   ├── themes                # → Themes
            │   └── uploads               # → Uploads
            ├── wp-config.php             # → Required by WP (never edit)
            ├── index.php                 # → WordPress view bootstrapper
            └── wp                        # → WordPress core (never edit)
            
        
This approach enables:
- Better folder structure
   - wordpress core is in separate folder and is treated as dependency
   - separate environment config file for non sensitive wordpress config (ex: SCRIPT_DEBUG, DISALLOW_FILE_MODS)
   - dedicated plugin folder for dev team under version control management (wiaas)   
- Dependency management with Composer (wordpress core and plugins)
- Environment variables with [Dotenv](https://github.com/vlucas/phpdotenv)
- Enhanced security (all sensitive information is accessed with environment variables) 
- Secure passwords with [wp-password-bcrypt](https://github.com/roots/wp-password-bcrypt)
- Composer as task runner for automatic wordpress db updates

#### Dependencies management
   
Wordpress core (`"johnpbloch/wordpress"`) and wordpress plugins code are managed with `composer.json` file.

But using combination of [Composer scripts](https://getcomposer.org/doc/articles/scripts.md) and [WP CLI commands](https://developer.wordpress.org/cli/commands/)
we can automate database updates as well (mainly plugin activation and db updates after plugin version change);

##### Adding new plugin
For adding new plugin from wordpress official repo add `"wpackagist-plugin/{plugin_name}": "{plugin_version}"`  to `composer.json`.

    composer require wpackagist-plugin/{plugin_name} --version={plugin_version}

Then add package to `"activate-plugins"` composer script in  `composer.json` file in order in which you wish them to be activated.

    "scripts": {
        "activate-plugins": [
            ...,
            wp plugin activate woocommerce {plugin_name}
        ]
    }

If plugin exposes wp cli command for database updates add it to `"update-db"` composer script in  `composer.json` file
(ex: woocommerce plugin exposes `wp wc update` which will apply pending database plugins for woocommerce).
Make sure that wiaas always applies its changes last.

    "scripts": {
        "update-db": [
              "wp core update-db",
              "composer activate-plugins",
              ...
              {add wp cli command here},
              "wp wiaas update-db"
        ]
    }

For updating wordpress core or plugins, update version for package
wordpress core database changes will be applied with `wp core update-db` cli command ).

After any of these actions run:
        
    composer update         # → Will download latest code and update lock file
    composer update-db      # → Activate plugins and calls all exposed wp cli commands for db updates
     
##### Removing existing plugin
   
1) Remove it from composer.json with:

       composer remove wpackagist-plugin/{plugin_name}
    
2) Remove it from `"activate-plugins"` and `"update-db"` scripts.

3) Then run:

       composer update

If plugin has database changes that we wish to be removed that is oneoff migration that can be done from
admin panel or using script:

    wp plugin deactivate {plugin_name} && composer remove wpackagist-plugin/{plugin_name}
    
WP CLI is very powerful tool for writing automation scripts without need to track and copy mysql dumps.
But if need arises we can think about using tool for db migration scripts.
    
#####  Wiaas plugin

Our code is placed inside `backend/app/plugins/wiaas` folder.

######  Wiaas plugin folder structure:

            ├── includes                                # → Location for src files
            │   ├── cli                                 # → CLI commands exposed to WP CLI
            │   └── db-updates                          # → DB updates
            │       ├── wiaas-db-updates-functions.php  # → Contains functions for db updates
            ├── wiaas.php                               # → Entry point
            

This folder will be managed by git and commited to repository (check `backend/.gitignore`).

######  Wiaas plugin DB changes

Wiaas exposes WP CLI command which will execute pending db updates for wiaas:

    wp wiaas update-db


If your feature requires some database updates that can be easily executed from wordpress code, then:

1) Place this update to `wiaas/includes/db-updates/wiaas-db-update-functions.php` as a function named `wiaas_db_update_{name}`
 
2) Add this function to  `wiaas/includes/class-wiaas-db-update.php` with its timestamp.

This way after `composer update-db` is executed your database update will be applied.

#### Unit testing

1) Install [PHPUnit](https://phpunit.de/getting-started/phpunit-6.html) 

       wget -O phpunit https://phar.phpunit.de/phpunit-6.phar
       cp phpunit /usr/local/bin/phpunit
       sudo chmod +x /usr/local/bin/phpunit
    
2) Setup wiaas plugin unit testing

       cd backend/app/plugins/wiaas
       ./tests/bin/setup.sh [db-root] [db-root-pass]

Script will install test environment in `/tmp/wiaas-backend-test`

3) Now you can run `phpunit` inside `wiaas` directory

