Chapter 10. Extending PHPBU

You can extend PHPBU with your own Source, Check, Crypt, Sync, Cleanup and Logger implementations.

All you have to do is to register your implementation at the PHPBU Factory. You can do this by adding you own bootstrap file.

phpbu --bootstrap=extend.php

Your extend.php file could look something like this:

Example 10.1: Extend bootstrap

<?php
  // make your class accessible
  require 'Acme/MySource.php';
  // register your class as a source
  try {
      phpbu\App\Factory::register('source', 'mysource', '\\Acme\\MySource');
  } catch (Exception $e) {
      die($e->getMessage());
  }


For this to work your class Acme\MySource hast to implement the phpbu\App\Backup\Source Interface. After registering your Source you can use mysource as source-type within your XML configuration like this.

Example 10.2: Custom Source XML example

<source type="mysource"></source>


If the alias is already taken this will throw an Exception. You can force phpbu to overwrite any previously registered class using the $force Parameter. Even the phpbu sources could be replaced with custom implementations.

Example 10.3: Overwrite default sources

<?php
// make your class accessible
require 'Acme/MyMysqldump.php';
// register your class as source, override already registered class
phpbu\App\Factory::register('source', 'mysqldump', '\\Acme\\MyMysqldump', true);


Executing and simulating

If you are extending phpbu you have two options. The first is to simply implement the execution interface. This way you can execute your own Source, Check, Crypt, Sync or Cleanup tasks. The second option is to implement the respective Simulator interface. Choosing this option you not only have to implement the execution part but rather implement a simulation part as well.

Simulation is supported out of the box for every implementation, but choosing option two enables you to add viable information about the actions you perform in your code within a simulation run.

Table 10.1. Types to register:

TypeInterface for execution onlyInterface for execution and simulation
sourcephpbu\App\Backup\Sourcephpbu\App\Backup\Source\Simulator
checkphpbu\App\Backup\Checkphpbu\App\Backup\Check\Simulator
cryptphpbu\App\Backup\Cryptphpbu\App\Backup\Crypt
syncphpbu\App\Backup\Syncphpbu\App\Backup\Sync\Simulator
cleanupphpbu\App\Backup\Cleanupphpbu\App\Backup\Cleanup\Simulator
loggerphpbu\App\Backup\Logger-


Create a custom Source

A minimal custom Source class could look like this.

Example 10.4: Create a custom source

<?php
namespace Acme;

use \phpbu\App\Backup\Result;
use \phpbu\App\Backup\Source;
use \phpbu\App\Backup\Target;

class MySource implements Source
{
    /**
     * Some data that has to be configured.
     */
    private $someConfigValue;

    /**
     * Here you should validate the configuration and setup your class.
     *
     * @param array $conf
     */
    public function setup(array $conf)
    {
        // here you are getting all of your configured options
        // $conf[ <option name> ] = <option value>
        $this->someConfigValue = $conf['foo']
    }

    /**
     * In here you should create your backup.
     *
     * @return \phpub\App\Backup\Source\Status
     * @throws \phpbu\App\Backup\Source\Exception
     */
    public function backup(Target $target, Result $result)
    {
        // use these methods to store the backup at the configured location
        // $target->getPath()
        // $target->getPathname()
        // $target->getFilename()
        // to know if the backup should be compressed use
        // $target->shouldBeCompressed()
        // to get the compression settings use
        // $target->getCompressor()
        // if you want to log some debug information use
        // $result->debug('some message');
        // anything bad happens throw a \phpbu\App\Exception
        // return a backup status
        // this is important so the runner knows if it still has to compress the backup
        // return Status::create()->uncompressed($pathToUncompressedFile);
    }
}


Create a custom Check

Custom Check implementation example.

Example 10.5: Create a custom check

<?php
namespace Acme;

use \phpbu\App\Backup\Check;
use \phpbu\App\Backup\Collector;
use \phpbu\App\Backup\Target;

class MyCheck implements Check
{
    /**
     * Perform your check.
     */
    public function pass(Target $target, $value, Collector $collector)
    {
        // use Target to refer to the created backup
        // $target->getPathname()
        // $value is the configured value
        // <check type="mycheck" value="myvalue"/>
        // $value = "myvalue"
        // use the collector to get a list of previous backups array<splFileInfo>
        // $history = $collector->getBackups()
        // throw a \phpbu\App\Backup\Check\Exception if something bad is happening
        // finally return if the check passes or not
        return $boolean;
    }
}


Create a custom Sync

Implementing a custom Sync.

Example 10.6: Create a custom sync

<?php
namespace Acme;

use \phpbu\App\Backup\Sync;
use \phpbu\App\Backup\Target;

class MySync implements Sync
{
    /**
     * Some data that has to be configured.
     */
    private $someConfigValue;

    /**
     * Here you should validate the configuration and setup your class.
     */
    public function setup(array $conf)
    {
        // here you are getting all of your configured options
        // $conf[ <option name> ] = <option value>
        $this->someConfigValue = $conf['foo']
    }

    /**
     * Execute your sync.
     */
    public function sync(Target $target, Result $result)
    {
        // use Target to refer to the created backup
        // $target->getPathname()
        // execute your sync
        // if you want to log some debug information use
        // $result->debug('some message');
        // throw a \phpbu\App\Backup\Sync\Exception if something is going wrong
    }
}


Create a custom Cleaner

Implementing a custom cleaner.

Example 10.7: Create a custom cleaner

<?php
namespace Acme;

use \phpbu\App\Backup\Collector;
use \phpbu\App\Backup\Sync;
use \phpbu\App\Backup\Target;

class MyCleaner implements Sync
{
    /**
     * Some data that has to be configured.
     */
    private $someConfigValue;

    /**
     * Here you should validate the configuration and setup your class.
     */
    public function setup(array $conf)
    {
        // here you are getting all of your configured options
        // $conf[ <option name> ] = <option value>
        $this->someConfigValue = $conf['foo']
    }

    /**
     * Execute your cleanup.
     */
    public function cleanup(Target $target, Collector $collector, Result $result)
    {
        // use Target to refer to the created backup
        // $target->getPathname()
        // use the collector to get a list of previous backups array<splFileInfo>
        // delete files matching your cleanup rules
        // $history = $collector->getBackups()
        // if you want to log some debug information use
        // $result->debug('some message');
        // throw a \phpbu\App\Backup\Cleaner\Exception if something is going wrong
    }
}


Create a custom Logger

List of available events:

  • phpbu.debug

  • phpbu.app_start

  • phpbu.app_end

  • phpbu.backup_start

  • phpbu.backup_failed

  • phpbu.backup_end

  • phpbu.crypt_start

  • phpbu.crypt_failed

  • phpbu.crypt_end

  • phpbu.check_start

  • phpbu.check_failed

  • phpbu.check_end

  • phpbu.sync_start

  • phpbu.sync_failed

  • phpbu.sync_skipped

  • phpbu.sync_end

  • phpbu.cleanup_start

  • phpbu.cleanup_failed

  • phpbu.cleanup_skipped

  • phpbu.cleanup_end

Implementing a custom logger.

Example 10.8: Create a custom logger

<?php
namespace Acme;

use phpbu\App\Event;
use phpbu\App\Log\Logger;

class MyLogger implements Logger
{
    /**
     * Logger interface requires 'getSubscribedEvents' method.
     * Define the events you want to get notified about.
     */
    public static function getSubscribedEvents()
    {
        return array(
            'phpbu.debug'   => 'onDebug',
            'phpbu.app_end' => 'onPhpbuEnd',
        );
    }

    /**
     * Logger interface requires 'setup' method to configure your logger.
     * Here you should validate the configuration and setup your class.
     */
    public function setup(array $conf)
    {
        // here you are getting all of your configured options
        // $conf[ <option name> ] = <option value>
    }

    /**
     * Handle the debug event.
     */
    public function onDebug(Event\Debug $event)
    {
        // use $event->getMessage() to get the debug message
    }

    /**
     * Handle phpbuEnd event
     */
    public function onPhpbuEnd(Event\App\End $event)
    {
        // handle the phpbuEnd
        // use $event->getResult() to get the application result
    }
}


Summary

Example 10.9: Example file structure

acme/
├── backup/
├── src/
|  ├── bootstrap.php
|  ├── MyCheck.php
|  ├── MyCleaner.php
|  ├── MyCrypt.php
|  ├── MySource.php
|  └── MySync.php
|
├── phpbu.phar
└── phpbu.xml.dist


Example 10.10: Example bootstrap.php

<?php
// use your autoloader or require your classes manually
// so phpbu can find them while executing you backup
// register your class as source, you may override already registered classes
phpbu\App\Factory::register('source', 'mysource', '\\Acme\\MySource');
phpbu\App\Factory::register('check', 'mycheck', '\\Acme\\MyCheck');
phpbu\App\Factory::register('cleanup', 'mycleanup', '\\Acme\\MyCleaner');


Example 10.11: Example phpbu.xml.dist

<?xml version="1.0" encoding="UTF-8"?>
<phpbu xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:noNamespaceSchemaLocation="http://schema.phpbu.de/3.2/phpbu.xsd">
  <backups>
    <backup>
      <!-- source -->
      <source type="mysource">
        <option name="foo" value="bar"/>
      </source>
      <!-- where should the backup be stored -->
      <target dirname="backup"
              filename="mysource-%Y%m%d-%H%i.backup"
              compress="bzip2"/>
      <!-- check the created backup -->
      <check type="mycheck" value="100"/>
      <!-- cleanup the backup location -->
      <cleanup type="mycleanup">
        <option name="foo" value="bar"/>
      </cleanup>
    </backup>
  </backups>
</phpbu>


Please open a ticket on GitHub to suggest improvements to this page. Thanks!