Skip to content

Developing

Matthew Orres edited this page Aug 23, 2019 · 8 revisions

Want to work on your own custom version of PHP Draft, or have an idea for a great feature? Awesome! The steps below will get you up and running with a virtual machine that contains everything you'll need to get started:

Tools Required

  • Git installed. (you're viewing this wiki page about developing software on Github, let's assume you're familiar with this piece of software 😸)
  • VirtualBox installed. (VirtualBox is free virtualization software from Oracle that allows you to run virtual machines)
  • Vagrant installed. (Vagrant is a free VM management tool that allows developers to share easily reproducible development environments)

Optional Mail Server

A working (or stubbed out) local SMTP server to simulate sending mail. User registration may seem broken on the front end (because the API will not get a response from an SMTP server), but you can manually enable and make the user account an admin as you do in the README.md instructions. There's a great Ruby gem called Mailcatcher that can setup a "pretend" SMTP server for local development purposes, and rather than installing Ruby and Rubygems on your local machine, just use Docker to stand one up instead:

  • Install Docker
  • Pull the tophfr/mailcatcher image into your Docker instance (using the Kitematic tool that comes with Docker provides a really nice UI), ensure there's a port mapping for port 1025 and then start the container
  • Update appsettings.php:
    • MAIL_SERVER is localhost (10.0.2.2 if using Vagrant)
    • MAIL_PORT is 1025
    • MAIL_DEVELOPMENT is true
  • Then access the web interface running on http://localhost:8080 to see all emails sent by the API

Bringing a Virtual Machine Up

So, assuming you've checked out the code from either the main repository, or your own fork of it, make sure you have your favorite terminal software opened (Powershell or cmd on Windows, iTerm or terminal in Mac for instance) and change into the base directory for the repository. The directory should include a Vagrantfile file (no filetype) in it:

Start by performing a simple command:

vagrant up

This tells Vagrant to spin up a new virtual machine according to the instructions laid out already in the project. This will take a few minutes of time, because Vagrant has a recipe script of sorts that it will follow to install and configure all software that is needed for HootDraft to run. If curious, take a look at vagrant-config/bootstrap.sh to see just what kind of things its doing.

Once completed, Vagrant should simply hand back control of your shell. Now, we can ask Vagrant to help us enter into an SSH with the new virtual machine we just asked it to create and configure for us:

vagrant ssh

Once you are inside the SSH, you should get a message similar to "Welcome to Ubuntu xx.xx.x LTS", and it will indicate that you have a shell awaiting your input: vagrant@hootdraft-dev:~$

You've Spun a VM Up... Now What?

The repository purposefully does not track any code in the /vendor or /node_modules folders. Instead, the project relies on 2 package managers to manage third party libraries: Composer, Yarn (using the npm package repository). Each time you clone the repository or pull down major changes, you'll need to run these following commands to keep the app running.

  1. Within an open SSH with the VM, first ensure you navigate to the shared folder that Vagrant helpfully keeps in sync between the VM and your host machine: cd /hootdraft

  2. Use Composer to download all of the API's third party dependencies:

composer install
  1. Have Yarn to pull down all local third party dependencies related to the build process:
sudo yarn

(note: normally, outside of a Vagrant VM you do not use sudo to perform actions with Yarn, however there are oddities with how Vagrant manages synced folders that breaks our use of Yarn, so we do that here. Elsewhere, though: be warned)

  1. Make a copy of the deploy script to the base directory and rename it with this command within the VM SSH:
cp deploy/deploy.php.release deploy.php
  1. Now use the settings wizard to create & export or import previously created settings:

    • If setting up for the first time:
    php vendor/bin/dep setup
    • If you've already run the setup wizard for your local installation before:
    php vendor/bin/dep import
  2. Optionally, if you are using either of the Backup or Import options with the settings wizard, you'll likely want to ensure Vagrant is providing a synced folder for this purpose:

    • Open Vagrantfile and find the line that starts with #NOTE: For app-specific settings:
    • Edit the first relative path enclosed in double quotes after config.vim.synced_folder to point to the folder you wish to save and retrieve settings from
    • Perform a vagrant reload to ensure that the virtual machine has this synced folder.
    • Now, when the settings wizard asks where to save or retrieve to/from, you can provide /phpdraft-settings
  3. Invoke Gulp to build the project locally:

gulp build
  1. Use Phinx to run all migrations to create the database structures necessary:
php vendor/bin/phinx migrate
  1. Now open a web browser and open the URL http://localhost:8000 and verify that everything is working.

  2. If everything works as expected, run vendor/bin/dep export to export your working settings so you can re-import them at another time (especially useful if you plan to deploy work-in-progress code to a different environment from this directory - the import command allows you to switch between the two quickly!) If you enabled a synced folder for your settings folder in step #5 above, then provide that path (/phpdraft-settings by default) to the export method.

Making MySQL Accept Network Connections

If you're like me, I prefer a GUI client to connect to MySQL (MySQL Workbench, SQLYog or Sequel Pro, for example). In order to allow this to work, we need to update the root MySQL user's privileges:

  1. Jump into an SSH in the VM:
vagrant ssh
  1. Log in to MySQL (when prompted, provide passw0rd as the password)
mysql -u root -p
  1. Execute the following command within the mysql shell:
GRANT ALL PRIVILEGES ON *.* TO root@'%' IDENTIFIED BY 'passw0rd';
  1. And that's it! (You can leave the mysql shell with a simple exit command).

Use the following credentials to connect to the MySQL server hosted within the VM:

Credential Value
Host 127.0.0.1
Username root
Password passw0rd
Port 3307

Great! You're up and running!

Just be sure to re-run gulp build in order to re-compile the application when making changes. Additionally, you can run gulp watch which asks Gulp to watch for changes on the filesystem, and re-compile the associated files (JS, CSS, or templates) as necessary. This feature may need tweaking/fixing, but PRs are welcome! 😸

Making Database Updates

You will need to create migrations if you wish to add or edit columns or tables, you'll need to do so by creating a new migration. Follow the Phinx documentation on how to do so.

Frontend Build Options

There are several flags that can be set that change how or what processes are run during the build:

Gulp Build Flag Notes
--minify boolean Run minification on all Coffeescript transpilation (greatly reduces filesize for better network performance)
--templates boolean Compile HTML Angular templates into the Javascript for better network performance
--concat boolean Concatenate similar Javascript files together into singular files like vendor.js and app.js (also for better network performance)
--env string Specify the environment to build for, corresponds to the /app/config/*.json file for environment-specific settings. Defaults to dev and compiles into js/config.js
--sourceMaps Include Javascript sourcemaps with the build (intended for dev only)

When a new PHP Draft release is made, this is the command I run (for reference):

gulp build --minify --templates --concat --env=dist

Unit Tests

To run unit tests for the project, use this command at the base directory of the code:

php vendor/bin/phpunit

Tests are located within the /tests folder.

Unit test coverage is anemic and well below where it should be - I just recently added them :) As I add new features or change existing ones, I will add test coverage as best I can.