/ Gists / PHP Patterns

Gists - PHP Patterns

On gists

Multiple params in fn - Solution

PHP DOC PHP Patterns

index.php #

<?php

// 1 config object
class FooConfig {
    public int $param1 = 0;
    public int $param2 = 0;
    public string $param3 = '';
    public string $param4 = '';
    public bool $param5 = false;
    public ?int $param6 = null;
    public int $param7 = 0;
    public string $param8 = '';
}

function Foo(FooConfig $config): void {
    // Použití: $config->param1, $config->param2, atd.
}

// Použití
$config = new FooConfig();
$config->param1 = 1;
$config->param2 = 5;
$config->param3 = "aaa";
$config->param4 = "bbb";
$config->param5 = false;
$config->param6 = null;
$config->param7 = 22;
$config->param8 = "ok";



// 2 array
/**
 * @param array{
 *   param1: int,
 *   param2: int,
 *   param3: string,
 *   param4: string,
 *   param5: bool,
 *   param6: mixed,
 *   param7: int,
 *   param8: string
 * } $params
 */
function Foo(array $params): void {
    // Použití: $params['param1'], $params['param2'], atd.
}

// Použití
Foo([
    'param1' => 1,
    'param2' => 5,
    'param3' => "aaa",
    'param4' => "bbb",
    'param5' => false,
    'param6' => null,
    'param7' => 22,
    'param8' => "ok"
]);



// 3 builder
class FooBuilder {
    private array $params = [];

    public function setParam1(int $value): self {
        $this->params['param1'] = $value;
        return $this;
    }

    public function setParam2(int $value): self {
        $this->params['param2'] = $value;
        return $this;
    }

    // Další metody pro nastavení parametrů...

    public function build(): Foo {
        return new Foo($this->params);
    }
}

class Foo {
    public function __construct(array $params) {
        // Inicializace s parametry
    }
}

// Použití
$foo = (new FooBuilder())
    ->setParam1(1)
    ->setParam2(5)
    ->setParam3("aaa")
    ->setParam4("bbb")
    ->setParam5(false)
    ->setParam6(null)
    ->setParam7(22)
    ->setParam8("ok")
    ->build();
    
    
    
  // 4 named   PHP 8+
  function Foo(
    int $param1 = 0,
    int $param2 = 0,
    string $param3 = '',
    string $param4 = '',
    bool $param5 = false,
    $param6 = null,
    int $param7 = 0,
    string $param8 = ''
) {
    // Funkční logika
}

// Použití
Foo(
    param1: 1,
    param2: 5,
    param3: "aaa",
    param4: "bbb",
    param5: false,
    param6: null,
    param7: 22,
    param8: "ok"
);



// Fluent
class FooParams {
    private int $param1 = 0;
    private int $param2 = 0;
    private string $param3 = '';
    private string $param4 = '';
    private bool $param5 = false;
    private $param6 = null;
    private int $param7 = 0;
    private string $param8 = '';

    public function param1(int $value): self {
        $this->param1 = $value;
        return $this;
    }

    public function param2(int $value): self {
        $this->param2 = $value;
        return $this;
    }

    // Další metody pro ostatní parametry...

    public function getParams(): array {
        return [
            'param1' => $this->param1,
            'param2' => $this->param2,
            // ...
        ];
    }
}

function Foo(array $params) {
    // Funkční logika
}

// Použití
$params = (new FooParams())
    ->param1(1)
    ->param2(5)
    ->param3("aaa")
    ->param4("bbb")
    ->param5(false)
    ->param6(null)
    ->param7(22)
    ->param8("ok");

Foo($params->getParams());

On gists

SelectionResolver

Nette PHP Nette-Database PHP Patterns

SelectionResolver.php #

<?php

// usage
		$this->paymentList = $this->payment->getPaymentSelectionResolver()
				->getBaseSelection()
				//->setCountry($this->order->billing__country_id)
				->setUserGroups($this->user->isLoggedIn() ? $this->user->getRoles() : NULL)
				->setOnlyForProduct($this->payment->getPaymentOnlyForProduct($this->order->getItems($this->order::ITEM_PRODUCT)))
				->toArray();
				
// ...				
    public function getPaymentSelectionResolver()
    {
        return $this->paymentSelectionResolver;
    }
    
    
// ...
class PaymentEshopOrderSelectionResolver
{
    /**
     * @var Context
     */
    protected $connection;

    /**
     * 
     * @var Nette\Database\Table\Selection
     */
    protected $selection;


    public function __construct(Context $connection)
    {
        $this->connection = $connection;
    }

    
    public function getBaseSelection()
    {
        $this->selection = $this->connection->table('payment_type')
            ->where('active = 1');
        return $this;
    }


    public function setCountry($countryId)
    {
        $this->selection->where(':payment_type_country.country_id IN (?) OR all_countries = 1', (array) $countryId);
        //$this->selection->where(':transport_type_variant.country_id IS NULL OR :transport_type_variant.country_id IN (?)', (array) $countryId);
        return $this;
    }


    public function setOnlyForProduct($paymentTypeIds = NULL)
    {
        if ($paymentTypeIds === NULL)
        {
            $this->selection->where('only_for_product = 0 OR only_for_product IS NULL');
        }
        else
        {
            $this->selection->where('payment_type.id IN (?)', (array) $paymentTypeIds);
        }
        return $this;
    }


    public function setUserGroups($usegroupsId = NULL)
    {
        if ($usegroupsId === NULL)
        {
            $this->selection->where(':payment_type_usergroup.usergroup_id IS NULL');
        }
        else
        {
            $this->selection->where(':payment_type_usergroup.usergroup_id IS NULL OR :payment_type_usergroup.usergroup_id  IN (?)', $usegroupsId);
        }
        return $this;
    }


    public function toArray()
    {
        $rows = [];
        foreach ($this->selection as $row)
        {
            $rows[$row->id] = $row;
        }

        return $rows;
    }

}

On gists

AfterSaveAction, events (own Kdyby implementation)

AW PHP Patterns

aftersaveEvent.php #

<?php

final class EshopOrderAfterSaveRegister extends Nette\Object {

	/**
	 * Nette callback array of after order save actions
	 * 
	 * @var array
	 */
	public $onAfterSave;

	/**
	 * Array with IAfterSaveAction objects
	 * 
	 * @var array
	 */
	private $afterSaveActions = array();

	/**
	 * Nette callback array of actions after success payment
	 * 
	 * @var array
	 */
	public $onAfterSuccessPayment;

	/**
	 * Array with IAfterSaveAction objects
	 * 
	 * @var array
	 */
	private $afterSuccessPaymentActions = array();

	/**
	 * Nette callback array of actions after fail payment
	 * 
	 * @var array
	 */
	public $onAfterFailPayment;

	/**
	 * Array with IAfterSaveAction objects
	 * 
	 * @var array
	 */
	private $afterFailPaymentActions = array();

	/**
	 * Instance of current presenter
	 * 
	 * @var Presenter
	 */
	private $presenter;

	/**
	 * Model EshopOrder
	 * 
	 * @var EshopOrder
	 */
	private $modelEshopOrder;

	public function __construct(EshopOrder $modelEshopOrder) {
		$this->modelEshopOrder = $modelEshopOrder;
	}

	/**
	 * Register after save action
	 * 
	 * @param IAfterSaveAction
	 */
	public function addAfterSaveAction(IAfterSaveAction $action) {
		$this->afterSaveActions[] = $action;
		return $this;
	}

	/**
	 * Register after success payment action
	 * 
	 * @param IAfterSaveAction
	 */
	public function addAfterSuccessPaymentAction(IAfterSaveAction $action) {
		$this->afterSuccessPaymentActions[] = $action;
		return $this;
	}

	/**
	 * Register after success payment action
	 * 
	 * @param IAfterSaveAction
	 */
	public function addAfterFailPaymentAction(IAfterSaveAction $action) {
		$this->afterFailPaymentActions[] = $action;
		return $this;
	}

	/**
	 * Application presenter setter
	 * 
	 * @param Presenter
	 */
	public function setPresenter(Presenter $presenter) {
		$this->presenter = $presenter;
		return $this;
	}

	/**
	 * Inicialize and invoke after save actions
	 * 
	 * @param  int
	 * @return void
	 */
	public function invokeAfterSaveActions($orderId) {
		foreach($this->afterSaveActions as $action) {
			$action->setPresenter($this->presenter);
			$this->onAfterSave[] = array($action, 'doAction');
		}

		$eshopOrder 	= $this->modelEshopOrder->getOrder($orderId);
		$orderItems 	= $this->modelEshopOrder->getOrderItems($orderId);
		$orderVouchers 	= $this->modelEshopOrder->getOrderVouchers($orderId);

		$this->onAfterSave($eshopOrder, $orderItems, $orderVouchers);
	}

	/**
	 * Inicialize and invoke after success payment actions
	 * 
	 * @param  int
	 * @return void
	 */
	public function invokeAfterSuccessPaymentActions($orderId) {
		foreach($this->afterSuccessPaymentActions as $action) {
			$action->setPresenter($this->presenter);
			$this->onAfterSuccessPayment[] = array($action, 'doAction');
		}

		$eshopOrder 	= $this->modelEshopOrder->getOrder($orderId);
		$orderItems 	= $this->modelEshopOrder->getOrderItems($orderId);
		$orderVouchers 	= $this->modelEshopOrder->getOrderVouchers($orderId);

		$this->onAfterSuccessPayment($eshopOrder, $orderItems, $orderVouchers);
	}

	/**
	 * Inicialize and invoke after success payment actions
	 * 
	 * @param  int
	 * @return void
	 */
	public function invokeAfterFailPaymentActions($orderId) {
		foreach($this->afterFailPaymentActions as $action) {
			$action->setPresenter($this->presenter);
			$this->onAfterFailPayment[] = array($action, 'doAction');
		}

		$eshopOrder 	= $this->modelEshopOrder->getOrder($orderId);
		$orderItems 	= $this->modelEshopOrder->getOrderItems($orderId);
		$orderVouchers 	= $this->modelEshopOrder->getOrderVouchers($orderId);

		$this->onAfterFailPayment($eshopOrder, $orderItems, $orderVouchers);
	}

}

On gists

MSP Vat resolver

PHP AW PHP Patterns

solution.php #

<?php

namespace Model;
use Nette;


class VatCzSkResolver
{
	private static $instance;

	public $eshopOrderFormMasoprofit;
	
	public function __construct(EshopOrderFormMasoprofit $eshopOrderFormMasoprofit)
	{
		self::$instance = $this;
		$this->eshopOrderFormMasoprofit = $eshopOrderFormMasoprofit;
	}

	public static function getDphRewrite()
	{
		if (!self::$instance) { // nejsme na frontendu
			return null;
		}
		
		if ($billingAddress = self::$instance->eshopOrderFormMasoprofit->getBillingAddress()) {
			if (isset($billingAddress['country_id']) && $billingAddress['country_id'] == 186) {
				if (isset($billingAddress['ic_vat']) && $billingAddress['ic_vat'] && isset($billingAddress['dic']) && $billingAddress['dic']) {
					return 0;
				}

				return 20;
			}
		}

		return null;
	}
}

On gists

0. Multiple constructors

PHP Patterns

multiple.php #

<?php
class File {
	protected $resource;
	
	protected function __construct() {
		// objekt nepůjde zvenku přímo vytvořit
	}
	
	static function createFromFile($filename, $mode) {
		$return = new self; // vytvoří objekt třídy File
		// od PHP 5.3 lze místo self použít static - vytvoří i potomky
		$return->resource = fOpen($filename, $mode);
		return $return;
	}
	
	static function createFromSocket($hostname, $port = -1) {
		$return = new self;
		$return->resource = fSockOpen($hostname, $port);
		return $return;
	}
}

$file = File::createFromFile(__FILE__, "r");


On gists

2. Registry

PHP Patterns

pic.md #


On gists

3. Factory

PHP Patterns

AbstractFactory.php #

<?php

// INTERFACES
interface WriterFactory
{
    public function createCsvWriter(): CsvWriter;
    public function createJsonWriter(): JsonWriter;
}


interface CsvWriter
{
    public function write(array $line): string;
}


interface JsonWriter
{
    public function write(array $data, bool $formatted): string;
}

//  WRITTERS
class UnixCsvWriter implements CsvWriter
{
    public function write(array $line): string
    {
        return join(',', $line) . "\n";
    }
}


class WinCsvWriter implements CsvWriter
{
    public function write(array $line): string
    {
        return join(',', $line) . "\r\n";
    }
}


class UnixJsonWriter implements JsonWriter
{
    public function write(array $data, bool $formatted): string
    {
        $options = 0;

        if ($formatted) {
            $options = JSON_PRETTY_PRINT;
        }

        return json_encode($data, $options);
    }
}


class WinJsonWriter implements JsonWriter
{
    public function write(array $data, bool $formatted): string
    {


        return json_encode($data, JSON_PRETTY_PRINT);
    }
}


// FACTORIES
class UnixWriterFactory implements WriterFactory
{
    public function createCsvWriter(): CsvWriter
    {
        return new UnixCsvWriter();
    }

    public function createJsonWriter(): JsonWriter
    {
        return new UnixJsonWriter();
    }
}


class WinWriterFactory implements WriterFactory
{
    public function createCsvWriter(): CsvWriter
    {
        return new WinCsvWriter();
    }

    public function createJsonWriter(): JsonWriter
    {
        return new WinJsonWriter();
    }
}


// USAGE
$writeFactory = new WinWriterFactory();
$writerFactory->createJsonWriter(); // or $writerFactory->createCsvWriter()

On gists

4. Observe

PHP Patterns

pic.md #


On gists

5. Adapter

PHP Patterns

pic.md #