CloudMonitor changelog

November 17, 2020

Domain monitor

Starting today domains are checked at the same time to keep things simple.

The log will show up and downtime checks per day.

April 24, 2019

Laravel Middleware: An Introduction

In computer science a middleware is, as the name suggest, a piece of software in the middle:

Middleware is computer software that provides services to software applications beyond those available from the operating system.

https://en.wikipedia.org/wiki/Middleware

But Laravel isn’t an operating system, so what does this mean in Laravel? The term middleware is used here because it’s a piece of code that is run between the request and the process of the output. You can apply middleware to your routes, which will be run after the initial system is booted, but before the controller or similar called:

Laravel system => Middlewares => Your code

It is most commonly used with web and auth. Where web is in fact a group of middleware, but in short, it will enable common web utilities such as sessions and CSRF tokens. You can see the exact group here. auth is to guard your route from unauthorized users.

Another use case for a middleware you could try is an IP address block.
Finally, I will leave you with a simple example:

<?php

namespace App\Http\Middleware;

use Closure;

class IPFilterMiddleware
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request $request
     * @param  \Closure $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        if (getenv('REMOTE_ADDR') === 'xxx.xxx.xxx.xxx') {
            abort(403);
        }

        return $next($request);
    }
}

You could then add it to the group of web found in the earlier link.

In a real scenario, you would of course load the IPs from a database.

April 27, 2019

Laravel Route Resources: Efficient URL Handling

Routes are one of the base concepts of your Laravel application, it’s here you define where URIs are pointing to in your application. Often the route will point to a controller but it can also direct output content. I will leave it for another post how Model View Controller (MVC) is structured, to understand this post you only have to understand that a route points to a controller which loads a template (view).

A bit simplified it could be illustrated as:

Route => Controller => View

In Laravel routes are powerful because they can be assigned with
middlewares, but also easy to manage as they have built in support for RESTful resources. If you follow the principles of RESTful you could save yourself a lot of code.

RESTful

Before continuing I think it would make sense to give a brief introduction to RESTful. RESTful isn’t a language or algorithm but a concept or definition of structuring paths. Originating in designing APIs its focus is in delivering such with an easy to understand path structure.

To give an example if you want to list all users, you should think of this as the top level option of the user endpoint, which would therefor be:

GET /users

But if you would like to see just 1 user, this is a secondary option to the endpoint. It could be tempting to use query strings (?key=value), but these should be reserved for filtering and showing a specific user is more a dig down the endpoint than filtering it. Therefor it’s done by applying the id as next in the path:

GET /users/1

If you want to update a user, this is the same, but with a PUT method. However HTTP doesn’t support this, so different libraries implements differently. Laravel uses a form input called _method to convert a POST to PUT:

PUT /users/1

Same goes for deleting a user:

DELETE /users/1

If you want to create a new user, this is done to the main endpoint, since you wouldn’t know any id’s at that point:

POST /users

So hopefully you catch the idea what RESTful is all about.

How to use it with Laravel routes

In Laravel you can define a (web) route by it’s method:

Route::get();
Route::post();
..

But there’s also a neat option that allows you to directly create what’s called a route resource, which is an implementation of a RESTful route:

Route::resource('users', '...');

You can chain this by either excluding or including only a set of the resources (they both result in the same):

Route::resource('users', '..')->only(['index', 'show']);
Route::resource('users', '..')->except(['create', 'update', 'destroy', 'store']);

Now you would have access to 2 URLs:

GET /users
GET /users/1

And best of all, they will per default point to methods in the same name in your controller which you easily generate in Laravel with the Artisan command make:controller prefix by --resource:

php artisan make:controller UsersController --resource


In case you wonder. The image was taken on top of the Rock of Gibraltar looking towards Algeciras in Spain.

May 18, 2019

5 Reasons To Choose Laravel

1 Up and running fast

Laravel was build to get you up and running fast with a website with all the tools needed built in. It even comes with a boilerplate page so you literally have a website in a few seconds, although a little more time is needed to implement your necessary business logic of course.

With bootstrap, and Laravels pre-configurations of it, it’s fairly easy to obtain a template and be ready in no time.

2 Tons of pre-made packages

If you want a little more logic to your website than just a cool template, and I bet you do, the deep integration of Composer and it’s Packagist will make it an easy job for you to extend the features of Laravel. Want to create a newsletter? Install Mailchimp and you are ready and so on.

The great thing is that you get used to Composer just by setting up Laravel, so you will quickly become familiar with the package manager and there are literally millions of available free packages for you.

3 Custom packages

If you could’t find your desired package or you want to wrap one, maybe you found an easier way to configure it, Laravel is also very handy here. Since it’s deeply integrated with Composer, this means it’s easy for you to built your custom logic into a package yourself and either host it public or just internal use.

Sometimes I find other vendors setup for a package too complex, at least for my cases, so I create a wrapper that pre-configures it to my needs. This way I only have to set it up once although I might use it 10+ times.

4 Target audience

Laravel was built with a specific audience in mind: Web developers. It’s core is based on Symfony, but Laravel takes it to the next level in terms of usability for the developer. It’s focus is solely on web applications which means it’s an excellent platform to build upon.

A lot of common needs in any web applications have already been build in and more are coming all the time.

5 Attention to detail

Last but not least. Taylor Otwell, the creator of Laravel, has his focus on details to the extend where not many can follow. If you read through block comments, you will realise every line is always exactly 3 characters shorter than the line above. Methods are highly specified too, which means they never have more than 1 responsibility.

This and the huge community makes Laravel so robust.

June 16, 2019

Introduction to Vuex

This a short introduction to Vuex a State Management tool for Vue.js. To understand all it’s complexities I would recommend you to read the documentations, this article is intended as an introduction only.

What is the use of Vuex

Let me first quote the official documentation, for it describe Vuex precisely, although a bit technically:

Vuex is a state management pattern + library for Vue.js applications. It serves as a centralized store for all the components in an application, with rules ensuring that the state can only be mutated in a predictable fashion.

What Vuex is in other words are is a central unit of your application to store the global state of your variables. This can for example be the current logged in user, you could save that to $store.state.user in that way whenever a component needs to access, let’s say the user id, it can be done through this.$store.state.user.id.

The Vuex can also have getters, so you could take advantage of this, and have a getter for retrieving the user object. If the user hasn’t currently been loaded it could take responsibility for loading it the first time, and after that return the value in the store.

It could also be used to tell if the application is online or offline, if you make a PWA (Progressive Web Application).

How it’s structured and implemented

To use Vuex you must first create a store. This I usually do by creating a store.js file with the content:

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

export const store = new Vuex.Store({
    state: {},
    mutations: {},
    actions: {},
    getters: {}
})

In your index.js, app.js or what other name it might have, where you initialise Vue, you must tell it to also load your Vuex Store:

// Include Vuex Store
import { store } from './store'

const app = new Vue({
    el: '#app',
    store // Load Vuex as `store`
});

Now you can access the store from any component by referring to $store:

this.$store.state.myState

I would suggest to take a look at Core Concepts in order to get a better understanding of the different parts: https://vuex.vuejs.org/

Vuex namespacing and modules

As with most things it’s a lot easier to maintain if you keep things organised. To help you with this Vuex has feature for modules and namespaces.

To install a module from a file unrelated to the store.js use the Vue.use({}) mechanism to install your additional features.

I have created a small implementation I call bind, although it don’t use namespaces – and this would increase the complexity anyway – it demonstrates how to build modules. This module is intended to serve as an easy access to a state. I also included the mixin that gives some nice handy features:

Vue.mixin({
    methods: {
        /**
         * Connect every component to the bind operator.
         *
         * @param  {string} property Node to bind to
         * @param  {mixed}  value    Value to assign
         * @return {mixed}           Value that was assigned
         */
        bind(property, value = undefined) {
            if (value === undefined) {
                return _.get(this.$store.state.base.bindings, property, null)
            }

            this.$store.commit('bind', [property, value])
        },
        /**
         * Detele a bound variable.
         *
         * @param {string} property
         */
        unbind(property) {
            this.$store.commit('unbind', property)
        },
        /**
         * Is property bound.
         *
         * @param {string} property
         * @return {bool}
         */
        hasBind(property) {
            return this.bind(property) !== null
        },
        /**
         * Alternate method name for hasBind().
         *
         * @param {string} property
         * @return {bool}
         */
        isBound(property) {
            return this.hasBind(property)
        }
    }
})

Vue.use({
    install(Vue) {
        window.Vuex.registerModule('base', {
            state: {
                /**
                 * Bounded variables
                 *
                 * @var {object}
                 */
                bindings: {}
            },
            mutations: {
                /**
                 * Variable bindings to the store.
                 *
                 * @param  {Object} state   Current state
                 * @param  {Array}  payload First parameter should be the binding path, second is the value
                 */
                bind(state, payload) {
                    state.bindings = Object.assign({}, state.bindings, _.set(state.bindings, payload[0], payload[1]))
                },
                /**
                 * Delete a binding.
                 *
                 * @param {Object} state
                 * @param {string} payload
                 */
                unbind(state, payload) {
                    let bindings = state.bindings

                    if (Array.isArray(payload))
                        _.get(bindings, payload[0]).splice(payload[1], 1)
                    else
                        delete _.get(bindings, payload)

                    state.bindings = Object.assign({}, bindings)
                }
            }
        })
    }
})

This allows you to call this.bind('user', user) to save a user object and this.bind('user') to retrieve it again. If it doesn’t exist a null will be returned to prevent errors.
Use this.hasBind('user') to check whether the use is already know:

if (! this.hasBind('user')) {
  this.bind('user', user)
}

I also created isBound() just in the sense that it sounds more correct.

I hope this brief introduction gave an idea what Vuex and State Management can do.


This article was requested from @samyek sonawane

June 17, 2019

What is Multitenancy Software

Multitenancy is a software architecture where different clients can sign-up to the same installation of your software, but have separated their data.

I have listed from a simple authorisation concept towards multitenancy, hoping that will clarify what it is.

single-tenant-vs-multi-tenant.png

Concept A

A basic application has 1 login for all members who needs to access member areas and sometimes more, but they are all given the same rights. This is the simplest form of an authorised application.

Concept B

A bit more complex is it when the different users can be assigned different roles. Let user A have access to create and manage other users, but user B can only view other users but not create or manage. This is an authorised application with roles.

Multitenancy

Then there’s a multitenancy, where it’s the same as concept B but different clients are attached to the same software, meaning they are on the same installation but in a sort of virtual environment, where they can’t access other clients data. User A can still manage and create users, so can User C but it’s within a different tenancy and A and C therefor can’t see the data from each other. A SaaS application is a typical multitenancy concept.

Pros

The reason to use multitenancy can often be found in either of 2 cases:

  • Reduced server cost
  • Large scale application

The cost reduction is achieved since your clients will share physical resources (servers, etc) across. It’s a similar concept to a cloud environment where you buy a part of a larger resource.

For large scale applications it’s a necessity to scale that you don’t have increasing operating costs per client you make. If you want to sell a product for $10 each to 1,000 clients, it would be a shame if you had to manage 1,000 servers and installations instead of 1.

Reason 2 is the most applicable since cloud servers today are cheap.

Cons

If you don’t think your application is going to sell to a lot of clients or there’s no reason to share the running costs, then multitenancy might not be relevant as it is, without doubt, a huge increase in the complexity of your application.

October 21, 2019

Laravel installed with Docker in just 5 minutes

In this guide I will teach you to setup your Laravel project for a dev environment. After you finish with this article you will have Laravel running in Docker, without the need to understand Docker as I have prebuild it for you.

Prerequisites

Before you are moving on with the guide, you should have installed Docker. The setup works indifferently on MacOS and Windows and should also work on Linux. You can download Docker here: https://www.docker.com/products/docker-desktop

Setup environment

Make a new project as per according to Laravel documentation:

composer new MyProject

Download my script to your project folder (feel free to open the URL and investigate it):

curl https://raw.githubusercontent.com/EmilMoe/vm/master/vm --output vm

On MacOS and Linux you might have to make the file executable:

chmod +x vm

Configure Laravel settings

Before you build your project, you must change a few things in your .env. If you change this after you build the environment, the setup won’t work.

Open .env in Sublime Text or any other text editor and change these variables:

# Set App name, the Docker container will use this name
APP_NAME=YOUR_APP

# Database should be configured to the Docker environment. Database name is optionally but I like to name it after my project
DB_CONNECTION=mysql
DB_HOST=database
DB_PORT=3306
DB_DATABASE=YOUR_APP
DB_USERNAME=root
DB_PASSWORD=secret

Build environment

You are now ready to build your environment:

./vm build

Press Y to begin the process.

After it’s done, you can browse to http://localhost to verify that Laravel works.

Using the script

Your Docker instance is already up and running, to stop it again simply run

./vm stop

And to start it

./vm start

There are a few more commands such as composer and npm but that would executive them inside the container where they should generally be run outside on your host machine.

To get a list of available commands use:

./vm

You can also read this post on my blog at https://emil.moe/index.php/2019/10/21/laravel-installed-with-docker-in-just-5-minutes/

October 22, 2019

Laravel Packages – How to build and deploy

Why using packages (Introduction)

Developing with a package approach in Laravel is a great way to split different logic apart in your application. By time as your application grow it will be easier to maintain when the code has been kept in separation, if the feature turns out to be generic and useful in another application it’s also easier to pull it out to a independent project, that can be used accross several of your applications.

Prerequisities

Before reading this article, I assume you are already familiar with some of the basic Laravel. You don’t need to know it in depth, but knowing terms such as schedulers, migrations, routes will help you.

Also I assume that you have set up composer globally so that you can type composer in your terminal and it’s list of commands will output.

You should also be familiar with using a terminal and how to navigate directories. On Linux and MacOS it’s simply called Terminal, on Windows you could be using Command Prompt or, as I prefer, Git Bash, but that choice is yours of course.

I don’t expect you to know anything about Composer packages before reading this article.

My reasons for developing with packages in mind

At first when I started using Laravel, I wrote my code directly in the installation insides folders as app or resources. This was what felt most natural to me, as it’s where the boilerplate invites you to start. However as a project grows it gets more complex to differ features and maintain which areas should have what responsibilty. It eventually leads to a lot of breaking changes.

Structuring a package

How you structure a package is an individual choice, but you must at a minimum include a composer.json file in it’s root to have a valid Composer package. It’s also optional where to store them. I like to keep my packages in a folder called packages in the root of my project, but you could place it anywhere you want, as long as it’s inside your project. For this article I will use packages. If you later give the package it’s own repository, it will of course be moved to vendors.

Set up your package environment

First create a folder packages in the root of your project. This is where folders such as app, public and vendorsare too.

First time I made packages, that was not vendors, I mistakenly defined the second level as my namespace, this isn’t really adding anything as you could see the project itself as the namespace, or simply the term packages as a namespace. Instead, inside packages folder, create the name of your desired package. This could be permission. Whether your choose singular or plural naming is optional, but as far as I can tell, Laravel tend to use singular.

Creating composer.json

This is fairly easy, when located in your package folder type composer init and composer will guide you through the steps.

Here’s an example on how to initialize the package permission given the name of the folder is so too:

[] indiciates a keyboard key, “” indicates a string value.

Composer outputActionNote
Package name (<vendor>/<name>) [emil/permission]:[Enter]Will then use what’s inside the brackets
Description []:“Handling user permissions.”
Author [Firstname Lastname  **@**.**, n to skip]:[Enter]Again using what’s inside the brackets.
Minimum Stability []:“dev”Suggested, you might prefer something different.
Package Type (e.g. library, project, metapackage, composer-plugin) []:[Enter]Skip.
License []:“MIT”MIT for open source, Proprietary if not, or you might prefer something different.
Would you like to define your dependencies (require) interactively [yes]?“n”We don’t dependencies for this example.
Do you confirm generation [yes]?[Enter]Create composer.json

Folders

In your package folder (permission) create 2 folders src and tests so that the content is now:

  • src/
  • tests/
  • composer.json

As I will not cover here how to write tests, this folder is left empty, but that’s where your tests should be.

Inside src is where all your custom code is going.

Structure inside src

I like to keep the structure as close to how Laravel does it. This is not necessary, but it makes it easier when I come back to remember how it’s structure and also work as a fixed guideline for, how I should structure my files. If you are working multiple people on the package(s), then you also have a ruleset on how your files should be placed.

Efficient integration

Down to the actual implementation of your package. Most code will be just like you are used to do it in Laravel, but inside the package. Where the magic differs is often in your ServiceProvider. I will walk you through the different options you have to integrate as much here, making the package more seamless to incorporate.

The following section you will be working in the file src/PermissionServiceProvider.php.

The base of your PermissionServiceProvider.php looks like this:

<?php

namespace Packages\Permission;

use Illuminate\Console\Scheduling\Schedule;
use Illuminate\Support\ServiceProvider;

class AccountServiceProvider extends ServiceProvider
{
    /**
     * Perform post-registration booting of services.
     *
     * @return void
     */
    public function boot()
    {
        //
    }

    /**
     * Register any package services.
     *
     * @return void
     */
    public function register()
    {
        //
    }
}

When to use boot() and when to use register()

This question is something I asked myself several times and can best be answered by quoting this answer: https://laracasts.com/discuss/channels/general-discussion/difference-between-boot-and-register-method

The register one is just for binding. The boot one is to actually trigger something to happen.

It’s concluded from Taylor Otwells book where he states:

“After all providers have been registered, they are “booted”. This will fire the boot method on each provider. A common mistake when using service providers is attempting to use the services provided by another provider in the register method. Since, within the register method, we have no gurantee all other providers have been loaded, the service you are trying to use may not be available yet. So, service provider code that uses other services should always live in the boot method. The register method should only be used for, you guessed it, registering services with the container. Within the boot method, you may do whatever you like: register event listeners, include a routes file, register filters, or anything else you can imagine.”

If you keep the first quote in mind, it should be without a headache to continue.

Schedulers

Task Scheduling is Laravels interface for your cronjobs. In the past you would have to manage a dozen of cronjobs on your server, making it more complex to migrate your application to a new server or install it on multiple. With Task Scheduling you define 1 cronjob on the server pointing to Laravel, from there Laravel takes care of the jobs. Even better as you define those inside Laravel, they benefit from human readable methods such as everyMinute or hourlyAt(17) instead of a bunch of asterixes (*) and slashes (/).

In order to use the scheduler, you’ll first have to import the namespace:

use Illuminate\Console\Scheduling\Schedule;

The schedulers has to be placed in the boot() method and must be encapsulated in a closure method booted:

$this->app->booted(function () {
    $schedule = $this->app->make(Schedule::class);

    // Your schedulers goes here...
});

For the actual schedulers you need to use, I will refer to Laravels documentation: https://laravel.com/docs/5.8/scheduling

For example if you want to run a command every midnight, your PermissionServiceProvider.php might look like this:

<?php

namespace Packages\Permission;

use Illuminate\Console\Scheduling\Schedule;
use Illuminate\Support\ServiceProvider;

class AccountServiceProvider extends ServiceProvider
{
    /**
     * Perform post-registration booting of services.
     *
     * @return void
     */
    public function boot()
    {
        $this->app->booted(function () {
            $schedule = $this->app->make(Schedule::class);

            $schedule->command('permission:command')->daily()->at('00:00');
        });
    }

    /**
     * Register any package services.
     *
     * @return void
     */
    public function register()
    {
        //
    }
}

Config

Sometimes you want to allow applications to modify variables or behaviour of your packages. To do this config files are a great option. They function in the way that you define a default config, or multiple configs, inside your package and register them to your Service Provider. When installed in an application they can be published and changed, then the published config will be used. You have probably already experienced this from other packages you have installed.

To find out more about config files, it’s very well explained in the official documentation: https://laravel.com/docs/5.8/packages#configuration

Let’s say you create a folder in src/config, just like Laravel, and in that folder you could create permission.php. Then in your register() method in your ServiceProvider you load the config file:

$this->mergeConfigFrom(
        __DIR__ .'/config/permission.php', 'permission'
);

Blade Namespaces

Blades are great and using them in a package is also great. You can either provide Blade components or or utilize views from the package, that would be necessary for most installations or you might create a package that provides layout templates that your applications inherits.

When I first started with Blades in my packages, I had to create symbolic links (symlinks) from my resources/views folder to my package in order for them to be loaded. Later I discovered how you can create view namespaces that allows you to work with Blades inside your package and without any symlinks or other dark magic.

Using the namespaces

First create a controller in src/Http/Controllers. Add a constructor and set the namespace to i.e. Packages\Permission and define where your views are for this namespace:

/**
 * Controller constructor.
 */
public function __construct()
{
    view()->addNamespace('Packages\Permission', base_path('packages/permission/src/resources/views'));
}

Now in order to use it, instead of referering to just a Blade, you prefix it your namespace like this, if you wanted to refer to index.blade.php in your package:

view('Packages\Permission::index')

Migrations

If you want to add tables to the database, this is done in your migrations folder src/database/migrations.

You will find the official documentation for the migrations at https://laravel.com/docs/5.8/packages#migrations.

Migrations are working just like in your main app but should be placed in the before mentioned folder. To make your package able to find the migrations you must define it it’s boot() method where they are located:

/**
 * Perform post-registration booting of services.
 *
 * @return void
 */
public function boot()
{
    $this->loadMigrationsFrom(__DIR__ .'/database/migrations');
}

I prefer to prefix my package migrations with the name of the package, in this case it would be permission_. Let’s say I wanted to store some additional configurations in the database, this might be configurations that can be changed from the interface and not only in a config by a technical administrator, that would be permission_configurations. Whether you call it configs or configurations is up to you, but I like my naming to be explicit for better readability.

Rember that Laravel expects your database tables to be in plural, except if it’s a relation between 2 tables

Models

Since we prefix the tables, the tradoff is that you need to be explicit in your models. For the before mentioned configurations example, it would be tempting to call the model PermissionConfiguration, but I find this tedious as the package is called Permission and would prefer to use Configuration, letting the import be use Packages\Permission\Configuration; and not Permission twice.

As the name of the model and the database table are inconsistent, you must therefor define the table name as a property:

/**
 * Related database table name.
 * 
 * @var String
 */
protected $table = 'permission_configurations';

Console Commands

If you want to implement maintenance to your package or doing administrative tasks that doesn’t require a web interface because not everyone should access it, Console Commands are a great way to achieve this. You will find the official documentation at https://laravel.com/docs/5.8/packages#commands, but here I will explain how to add it to your package. Commands are often defined in group and command like group:command. You might know it from various Laravel commands such as php artisan cache:clear. My preference here is to name the group after your package, and whatever the command might be, that could be permission:refresh or permission:clear.

The Console Commands should be defined in your boot() method in the ServiceProvider.

<?php

namespace Packages\Permission;

use Illuminate\Support\ServiceProvider;
use Package\Permission\Console\Commands\Clear;

class AccountServiceProvider extends ServiceProvider
{
    /**
     * Perform post-registration booting of services.
     *
     * @return void
     */
    public function boot()
    {
        if ($this->app->runningInConsole()) {
            $this->commands([
                Clear::class,
            ]);
        }
    }

    /**
     * Register any package services.
     *
     * @return void
     */
    public function register()
    {
        //
    }
}

Routes

Since we have already looked at Blades it’s probably a good idea to take a look at the routes as well.

Laravel has 4 different types of routes:

  • API
  • Channel
  • Console
  • Web

In this article I will only be focusing on the Web as these are the most essential. API and Channel are better suited for their own article and Console is partly covered in the section above, although this is the new way Laravel suggests defining your Console Commands.

The documentation for the routes can be found at https://laravel.com/docs/5.8/packages#routes.

Routes should be loaded from the register() method in your ServiceProvider and be located insrc/routes :

/**
 * Register any package services.
 *
 * @return void
 */
public function register()
{
    $this->loadRoutesFrom(__DIR__ .'/routes/web.php');
}

For the content of your web.php file you should remember to define your package folder, so Laravel knows it’s not in it’s applications default:

Route::resource('permission/list', 'Packages\Permission\Http\Controllers\PermissionController')
    ->middleware(['web', 'auth'])
    ->only(['index']);

I prefer to prefix all my packages routes with the name of the package, in this case permission/.

Environments

When the time has come and you have a package ready for release, or beta release, there are 3 scenarios where you could choose to use your package.

  1. Local in the application only
  2. In several of your applications, but only for internal use
  3. Public available through packagist

Local in the application only

In case of the first (1) you are already ready to go, as you developed it inside your application and that’s where it is and is going to start, so you are good to go.

In several of your applications, but only for internal use

If the case is second (2) you could use GitHub, but their pricing is often a reason for choosing providers such as BitBucket or GitLab instead. Fortunately this is also very easy to to, but you have to be aware that since it’s a private package, you will not publish it to packagist.org and that means you can’t have versions, but only dev-master. You could set up your own private Packagist, but that isn’t free and out of the scope for this article.

Private hosted at BitBucket

In this guide I will take you through how it’s private hosted at BitBucket, if you want to use GitLab the proces should be fairly similar.

First create a new repository at BitBucket.

As long as it’s only being used in your development and all developers have acces to the repository it’s good to go. As soon as your start pushing to production, you must remember to add the production servers public ssh key to your package list of access keys.

In your composer.json add the following section somewhere after require-dev, and remember to change the lines to fit accordingly. I added an extra line just to show how to add multiple:

"repositories": [
   {"type": "vcs", "url":  "[email protected]:your_name/permission.git"},
   {"type": "vcs", "url":  "[email protected]:your_name/another_package.git"}
],

This will allow Composer to include your repository outside Packagist to be included.

Now you can install your package with the usual require comment:

composer require your_name/permission 

Public available through packagist

If you choose to distribute your package publicly so anyone can benefit from it, you need to publish your package ot GitHub and register it at Packagist.org. You should upload your package to Github before you move forward to Packagist.

First go to Packagist.org and create an account.

Next you must connect this account to your Github account, it should ask for doing so right after you login. You might have to sign in through Github too first.

Next click Submit in the top right corner in order to add your package from your Github repository. And that’s it.

Worth noting is that Packagist uses the tags you create on Github as it’s versioning system. So use tags such as 1.0, 1.5, 2.0 and so on to properly versioning your package.

Testing packages

As previously mentioned tests should go to the tests directory in your package folder, same folder where src is located. As long as you have your packages locally you can perform testing to them as well. After deploy and installing them in another project, it shouldn’t be necessary anymore to do testing.

In the root directory of your Laravel installation, open the file phpunit.xml. Find the section testsuites and change it took be accordingly to this, where the package folder is included:

<testsuites>
    <testsuite name="Feature">
        <directory suffix="Test.php">./tests/Feature</directory>
        <directory suffix="Test.php">./packages/*/tests/Feature</directory>
    </testsuite>

    <testsuite name="Unit">
        <directory suffix="Test.php">./tests/Unit</directory>
        <directory suffix="Test.php">./packages/*/tests/Unit</directory>
    </testsuite>

    <testsuite name="Acceptance">
        <directory suffix="Test.php">./packages/*/tests/Acceptance</directory>
    </testsuite>
</testsuites>

Phpunit will now also search through your packages folder for tests cases.


This was written a while ago hence the reference to 5.8

October 23, 2019

Backup MySQL to DigitalOcean

I have authored an article on how to create a dead simple backup approach for you project. My approach is for Laravel, but it could easily work for WordPress as well or any other MySQL database for that instance as it only relies on MySQL and Linux commands.

For this post I will share my final script for your convenience.

The script is

# YOUR VARIABLES
key=xxxxxxxxxxxxxxxxxxxx
secret=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
endpoint=xxxxx.digitaloceanspaces.com
bucket=my-unique-name
dbuser=root
dbpassword=secret
dbname=database

# MIGHT NOT NEED EDIT
file=db-backup.sql
dbhost=127.0.0.1

# STATIC VARIABLES
file=$(date "+%Y.%m.%d-%H.%M.%S").${file}
resource="/${bucket}/${file}"
contentType="application/sql"
dateValue=`date -R`
stringToSign="PUT\n\n${contentType}\n${dateValue}\n${resource}"
signature=`/bin/echo -en ${stringToSign} | openssl sha1 -hmac ${secret} -binary | base64`

# DUMP SQL
mysqldump --host=${dbhost} --user=${dbuser} --password=${dbpassword} ${dbname} > ~/${file}

# UPLOAD
curl -X PUT -T ~/${file} \
  -H "Host: ${bucket}.${endpoint}" \
  -H "Date: ${dateValue}" \
  -H "Content-Type: ${contentType}" \
  -H "Authorization: AWS ${key}:${signature}" \
  https://${bucket}.${endpoint}/${file}

# REMOVE FILE AFTER UPLOAD
rm ~/${file}

`

And should be schedules with a cronjob:

* */4 * * * sh ~/backup.sh >/dev/null 2>&1

October 24, 2019

Deploy Laravel packages to Packagist

You are probably already using Laravel when you read this, that means you are already using Packagist too, but might not be aware of it. In this guide you will learn how to deploy your own Laravel packages to Packagist.

Packagist is the platform behind Composer acting as the library. When you are searching for a new package for your project, you are probably doing this through Google, which works perfectly fine and I do so as well. But in fact you could do an even more targeted search on Packagist.org.

The steps

But how does Packagist work? Let’s split it into the steps necessary when creating a package for others to install through Composer:

  1. Developing the package itself
  2. Hosting it on a git platform, Github will be the easiest
  3. Submitting the repository to your Packagist account

This article will not be covering how to develop a package, if you are interested in that part I can recommend my article I wrote for Hashnode: Laravel Package – How to build and deploy

There you will also find a brief description of deployment, but that will be covered in more details here.

Push to Github

If you already know how to push your package to Github, you can skip this step.

First you must create your repository on you Github account https://github.com/new . Rememeber it must be public in order to work with Packagist.

As Github states you must initialize your repository on your computer and push the files to Github.

git init
git commit -m "initial draft"
git remote add origin [email protected]:<account>/<repository>.git
git push -u origin master

Submitting to Packagist

Navigate to Packagist and click Submit https://packagist.org/packages/submit and enter the URL of your repository

image.png

Click check and submit.

Failed to submit

If you are receiving errors concerning composer.json this means you have an invalidate or missing the file in the root of your repository. The base of composer.json should contain:

{
    "name": "MyName/repository",
    "authors": [
        {
            "name": "Firstname Lastname",
            "email": "[email protected]"
        }
    ],
    "require": {}
}

This can be created in your package with the command composer init and validated with composer valid.

Github webhook

The last step is to add a webhook to your Github repository in order for Packagist to be pinged every time you update your package.

Go to your repository’s Settings, then Webhooks and Add webhook

image-1.png

Remember to update your username in the Payload URL parameter.

Your unique Packagist token can be found at your profile: https://packagist.org/profile/

Your package can now be installed by others

composer require your-github-name/your-repository-name

Versioning

Packagist uses Git tags as version indicator. This means you could start your first tag as 1.0.0 then 1.0.1 and so on. Read more about semantic versioning at https://semver.org/

To add a tag and push the tags to your repository use the --tags parameter when you push

git tag 1.0.0
git push --tags

This can be a challenge in the beginning to keep up which version to tag. To list the tags used for a repository use the command without a value

git tag

A graphical tool such as SourceTree can also be useful when managing tags, but everything can be done from the command line, of course.


You are now set to share your packages with the world.