/ Gists / 8. Facade
On gists

8. Facade

PHP Patterns

pic.md Raw #

Facade1.php Raw #

<?php

use \Imagick;
use \SplFileInfo;

class Image {

    private $imagick;

    public function __construct () {
        $this->imagick = new Imagick();
    }

    public  function thumbnail (string $filePath, int $width, int $height) {
        $this->imagick->readImage($filePath);
        $this->imagick->setbackgroundcolor('rgb(0, 0, 0)');
        $this->imagick->thumbnailImage($width, $height, true, true);

        $fileInfo = new SplFileInfo($filePath);
        $thumbPath = $fileInfo->getBasename('.' . $fileInfo->getExtension()) . '_thumb' . "." . $fileInfo->getExtension();

        if (file_put_contents($thumbPath, $this->imagick)) {
            return true;
        } else {
            throw new \Exception("Could not create thumbnail.");
        }
    }
}

Facade2.php Raw #

<?php

class YouTube
{
    public function fetchVideo(): string { /* ... */ }

    public function saveAs(string $path): void { /* ... */ }

    // ...more methods and classes...
}


class FFMpeg
{
    public static function create(): FFMpeg { /* ... */ }

    public function open(string $video): void { /* ... */ }

    // ...more methods and classes... RU: ...дополнительные методы и классы...
}

class FFMpegVideo
{
    public function filters(): self { /* ... */ }

    public function resize(): self { /* ... */ }

    public function synchronize(): self { /* ... */ }

    public function frame(): self { /* ... */ }

    public function save(string $path): self { /* ... */ }

    // ...more methods and classes... RU: ...дополнительные методы и классы...
}


class YouTubeDownloader
{
    protected $youtube;
    protected $ffmpeg;

    /**
     * It is handy when the Facade can manage the lifecycle of the subsystem it
     * uses.
     */
    public function __construct(string $youtubeApiKey)
    {
        $this->youtube = new YouTube($youtubeApiKey);
        $this->ffmpeg = new FFMpeg;
    }

    /**
     * The Facade provides a simple method for downloading video and encoding it
     * to a target format (for the sake of simplicity, the real-world code is
     * commented-out).
     */
    public function downloadVideo(string $url): void
    {
        echo "Fetching video metadata from youtube...\n";
        // $title = $this->youtube->fetchVideo($url)->getTitle();
        echo "Saving video file to a temporary file...\n";
        // $this->youtube->saveAs($url, "video.mpg");

        echo "Processing source video...\n";
        // $video = $this->ffmpeg->open('video.mpg');
        echo "Normalizing and resizing the video to smaller dimensions...\n";
        // $video
        //     ->filters()
        //     ->resize(new FFMpeg\Coordinate\Dimension(320, 240))
        //     ->synchronize();
        echo "Capturing preview image...\n";
        // $video
        //     ->frame(FFMpeg\Coordinate\TimeCode::fromSeconds(10))
        //     ->save($title . 'frame.jpg');
        echo "Saving video in target formats...\n";
        // $video
        //     ->save(new FFMpeg\Format\Video\X264, $title . '.mp4')
        //     ->save(new FFMpeg\Format\Video\WMV, $title . '.wmv')
        //     ->save(new FFMpeg\Format\Video\WebM, $title . '.webm');
        echo "Done!\n";
    }
}


// USAGE
function clientCode(YouTubeDownloader $facade)
{
    // ...

    $facade->downloadVideo("https://www.youtube.com/watch?v=QH2-TGUlwu4");

    // ...
}

$facade = new YouTubeDownloader("APIKEY-XXXXXXXXX");
clientCode($facade);

Facade3.php Raw #

<?php
// only wrapper on one repository, for better simplify API & usage


/**
 * Ok so this looks pretty terrible, right? Everything is public and crappy method names!
 */
interface SendMailInterface
{
    public function setSendToEmailAddress($emailAddress);
    public function setSubjectName($subject);
    public function setTheEmailContents($body);
    public function setTheHeaders($headers);
    public function getTheHeaders();
    public function getTheHeadersText();
    public function sendTheEmailNow();
}
 
/**
 * Implementing that crappy interface
 */
class SendMail implements SendMailInterface
{
    public $to, $subject, $body;
    public $headers = array();
 
    public function setSendToEmailAddress($emailAddress)
    {
        $this->to = $emailAddress;
    }
    
    public function setSubjectName($subject)
    {
        $this->subject = $subject;
    }
 
    public function setTheEmailContents($body)
    {
        $this->body = $body;
    }
 
    public function setTheHeaders($headers)
    {
        $this->headers = $headers;
    }
 
    public function getTheHeaders()
    {
        return $this->headers;
    }
 
    public function getTheHeadersText()
    {
        $headers = "";
        foreach ($this->getTheHeaders() as $header) {
            $headers .= $header . "\r\n";
        }
    }
 
    public function sendTheEmailNow()
    {
        mail($this->to, $this->subject, $this->body, $this->getTheHeadersText());
    }
}
 
/**
 * A facade wrapper around the crappy SendMail, to improve method names.
 */
class SendMailFacade
{
    private $sendMail;
 
    public function __construct(SendMailInterface $sendMail)
    {
        $this->sendMail = $sendMail;
    }
 
    public function setTo($to)
    {
        $this->sendMail->setSendToEmailAddress($to);
        return $this;
    }
    
    public function setSubject($subject)
    {
        $this->sendMail->setSubjectName($subject);
        return $this;
    }
 
    public function setBody($body)
    {
        $this->sendMail->setTheEmailContents($body);
        return $this;
    }
 
    public function setHeaders($headers)
    {
        $this->sendMail->setTheHeaders($headers);
        return $this;
    }
 
    public function send()
    {
        $this->sendMail->sendTheEmailNow();
    }
}
 

// USAGE 
 
$to      = "bob@marley.com";
$subject = "Bob Marley and the Wailers";
$body    = "Bob Marley and the Wailers were a Jamaican reggae band created by Bob Marley, Peter Tosh and Bunny Wailer.";
$headers = array(
    "From: Steve@Irwin.com"
);
 
// Using the minging SendMail class
$sendMail = new SendMail();
$sendMail->setSendToEmailAddress($to);
$sendMail->setSubjectName($subject);
$sendMail->setTheEmailContents($body);
$sendMail->setTheHeaders($headers);
$sendMail->sendTheEmailNow();
 
// Using the sexy SendMailFacade class
$sendMail       = new SendMail();
$sendMailFacade = new sendMailFacade($sendMail);
$sendMailFacade->setTo($to)->setSubject($subject)->setBody($body)->setHeaders($headers)->send();