/ Gists / Nette

Gists - Nette

On gists

Latte component

Nette Nette-Latte

any.latte #

<!-- component definition  -->
{define badge, bool $show = true, string $title = '', $class = null}
	<span class="badge ms-2 font-size-small {$class ?? 'bg-body-secondary text-body'}" n:if="$show" title="{$title}">
		{block content}{/block}
	</span>
{/define}


<!-- usage -->
{embed badge, $client !== null, 'Uhrazeno'}
	{block content}
		<i class="mdi mdi-check text-success"></i>
		{$client->totalInvoicePricePaid|price:0}
	{/block}
{/embed}

On gists

Transaction via callback ;)

Nette PHP

example.php #

<?php

// https://forum.nette.org/cs/22304-zavislost-jednoho-modelu-na-jinych

	/**
	 * @param Closure $callback
	 */
	private function doInTransaction(Closure $callback)
	{
		$this->isInTransaction = TRUE;
		$callback();
		$this->isInTransaction = FALSE;
	}
	
	
	// usage
	// any class
	private $isInTransaction = FALSE;
	
	
	
	/**
	 * @param int $id
	 * @param Player $owner
	 */
	public function __construct($id, Player $owner)
	{
		$this->id = $id;
		$this->owner = $owner;

		$this->doInTransaction(function () use ($owner) {
			$owner->receiveItem($this);
		});
	}



	/**
	 * @param Player $newOwner
	 */
	public function changeOwner(Player $newOwner)
	{
		if ($this->owner !== $newOwner) {
		  $this->doInTransaction(function () use ($newOwner) {
				$this->owner->giveItem($this);
				$this->owner = $newOwner;
				$this->owner->receiveItem($this);
			});
		}
	}

On gists

IconList (scan)

Nette

IconListPresenter.php #

class IconListPresenter extends \App\Presenters\BasePresenter
{

	/**
	 * @var Context
	 * @inject
	 */
	public $connection;

	public function actionDefault()
	{

		$icons = scandir(INDEX_DIR . '/../webapp/frontapp/svg');
		$list = [];
		foreach ($icons as $icon) {
			if (!strpos($icon, 'svg')) {
				continue;
			}

			$list[] = $icon;
		}


		$this->template->occurrences = $this->findOccurrences($list);
		$this->template->list = $list;

		
		$scan = array_diff(scandir(INDEX_DIR.'/../app/ServiceModule/templates/IconList/icons-list/'), ['.', '..']);
		$urls = [];
		foreach ($scan as $iconName) {
			if (is_file($file = INDEX_DIR.'/../app/ServiceModule/templates/IconList/icons-list/' . $iconName)) {
				$urls[str_replace('.txt', '', $iconName)] = file_get_contents($file);
			}
		}

		$this->template->urls = $urls;
	}

	public function actionUpdateIcons()
	{

		$icons = scandir(INDEX_DIR . '/../webapp/frontapp/svg');
		$list = [];
		foreach ($icons as $icon) {
			if (!strpos($icon, 'svg')) {
				continue;
			}

			$list[] = $icon;
		}
		
		$scan = array_diff(scandir(INDEX_DIR.'/../app/ServiceModule/templates/IconList/icons-list/'), ['.', '..']);
		$urls = [];
		foreach ($scan as $iconName) {
			if (is_file($file = INDEX_DIR.'/../app/ServiceModule/templates/IconList/icons-list/' . $iconName)) {
				$urls[str_replace('.txt', '', $iconName)] = file_get_contents($file);
			}
		}

		foreach ($list as $icon) {
			if (isset($urls[$icon])) {
				$url = $urls[$icon];
				$url = str_replace('48px.svg', '20px.svg', $url);

				$fetchIcon = file_get_contents($url);
				$fetchIcon = str_replace('><path', ' viewBox="0 0 20 20"><path fill="currentColor" ', $fetchIcon);
				file_put_contents(INDEX_DIR.'/../webapp/frontapp/svg/' . $icon, $fetchIcon);

				// save what we saved
				//file_put_contents(INDEX_DIR.'/../app/ServiceModule/templates/IconList/icons-list/' . $icon . '.txt', $url);
			}
		}

		$this->terminate();
	}


	private function createListFiles()
	{
		$allFiles = [];

		foreach (Finder::findFiles('*.latte')->from(INDEX_DIR . '/../app/BrandCloudModule/') as $key => $splFile) {
			$fileResouce = file_get_contents($key);
			$allFiles[$key] = $fileResouce;
		}

		foreach (Finder::findFiles('*.vue')->from(INDEX_DIR . '/../webapp/frontapp/components/') as $key => $splFile) {
			$fileResouce = file_get_contents($key);
			$allFiles[$key] = $fileResouce;
		}

		return $allFiles;
	}

	private function findOccurrences($icons)
	{
		$allFiles = $this->createListFiles();
		$all = [];

		foreach ($allFiles as $filePath => $fileResource) {
			foreach ($icons as $icon) {
				$icon = str_replace('.svg', '', $icon);
				//$nicePath = explode('..', $filePath)[1];
				$nicePath = $filePath;

				preg_match_all('~<aw-icon.+icon=("|\')' . preg_quote($icon) . '("|\')~', $fileResource, $m1);
				preg_match_all('~("|\')' . preg_quote($icon) . '("|\')~', $fileResource, $m2);

				if (!isset($all[$icon][$nicePath])) {
					$all[$icon][$nicePath] = 0;
				}

				if (count($m1[0])) {
					$all[$icon][$nicePath] += count($m1[0]);
				}

				if (count($m2[0])) {
					$all[$icon][$nicePath] += count($m2[0]);
				}
			}
		}

		return $all;
	}


	public function actionSaveUrlIcon()
	{
		// RAW POST DATA
		$data = json_decode(file_get_contents("php://input"));

		// icon fetch & save
		$url = str_replace('48px.svg', '20px.svg', $data->url);
		$fetchIcon = file_get_contents($url);
		$fetchIcon = str_replace('><path', ' viewBox="0 0 20 20"><path fill="currentColor" ', $fetchIcon);
		file_put_contents(INDEX_DIR.'/../webapp/frontapp/svg/' . $data->icon, $fetchIcon);

		// save what we saved
		file_put_contents(INDEX_DIR.'/../app/ServiceModule/templates/IconList/icons-list/'.$data->icon . '.txt', $data->url);

		// data
		echo json_encode($data);

		$this->terminate();
	}
}

On gists

Auto komponenty (Parent -> Children)

Nette Nette-Controls Nette-Tricks

ParentControl.php #

<?php

class OrderAction extends FrontControl 
{
  
  	public function __construct(, 
		Order $order, 
		Model\OrderAction $orderAction,
		Container $container
	) 
	{
		parent::__construct();

		$this->order = $order;
		$this->orderAction = $orderAction;
		$this->actions = $this->orderAction->getActions($this->pageByState);
	}
	
	
	
	public function render(array $config = [])
	{
		$config = $this->getCurrentConfig($config);

		$this->template->order = $this->order;
		$this->template->actions = $this->actions;

		$this->vueRender($config);
	}

	public function createComponent(string $name): ?Nette\ComponentModel\IComponent
	{
		if (!Strings::startsWith($name, 'action')) {
			return parent::createComponent($name);
		}

		return $this->container->createInstance('App\\FrontModule\\Components\\' . $this->actions[Strings::after($name, 'action')]->action, [
			'orderAction' => $this->actions[Strings::after($name, 'action')],
			'order' => $this->order
		]);
	}
	

}

On gists

PHP router - languages

Nette

router.php #

<?php

$sections = [
	'cs' => 'clanky',
	'sk' => 'blog',
	'en' => 'articles',
];

$router->addRoute('[<locale=sk en|cs|sk>/]<section clanky|blog|articles>', [
	'presenter' => 'Blog',
	'action' => 'default',
	null => [
		Route::FILTER_IN => function (array $params) use ($sections) {
			$params['section'] = $sections[$params['locale'] ?? 'sk'];
			return $params;
		},
		Route::FILTER_OUT => function (array $params) use ($sections) {
			$params['section'] = $sections[$params['locale'] ?? 'sk'];
			return $params;
		},
	],
]);

On gists

Nette find template file if not exists

Nette Nette-Controls

findTemplate.php #

<?php

 if (!$this->template->getFile()) {
		$files = $this->formatTemplateFiles();
		foreach ($files as $file) {
			if (is_file($file)) {
				$this->template->setFile($file);
				break;
			}
		}
 }

On gists

MatchResult component

Nette Nette-Controls PHP

MatchResultControl.php #

<?php


class MatchResult extends Control{

	const TEMPLATE_FULL = 'full';
	const TEMPLATE_INLINE = 'inline';

	public function renderFull($match){
		$this->render($match, self::TEMPLATE_FULL);
	}

	public function renderInline($match){
		$this->render($match, self::TEMPLATE_INLINE);
	}

	private function render($match, $templateName){
		$template = $this->createTemplate();
		$template->setFile(__DIR__.'/'.$templateName.'.latte');
		$template->match = $this->evaluateResult($match);
		$template->render();
	}

	private function evaluateResult($match){
		return //...
	}
}

On gists

Nette: Admin LastUserEdit Trait

Nette

LastEditTrait.php #

<?php

trait FastAdminLastChangeTrait {

	/**
	 * Bootstrap trait
	 * 
	 * @return void
	 */
	public function injectFastAdminLastChangeTrait()
	{
		$this->onBeforeSave[] = function($editRow, $values, $form) { 
            $values['lastchange'] = new \DateTime();
            $values['lastchange__user_id'] = $this->getUser()->getId();
        };

        $this->onCreateForm[] = function($form) 
        {
            if(isset($form['lastchange'])) 
                $form['lastchange']->getControlPrototype()->addClass('deactivateInput');

            if(isset($form['lastchange__user_id'])) 
                $form['lastchange__user_id']->getControlPrototype()->addClass('deactivateInput');
        };
	}


}

On gists

Nette - multiple db connections

Nette Nette-Database

connetionsModel.php #

<?php

namespace Model;

use Nette;

class Connections
{

	/** @var Nette\Di\Container */
	private $container;


	public function __construct(Nette\Di\Container $container)
	{
		$this->container = $container;
	}


	public function getOld()
	{
		return $this->container->getService('nette.database.main');
	}


	public function getNew()
	{
		return $this->container->getService('nette.database.msp22');
	}

}

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;
    }

}