/ Gists

Gists


On gists

12. Facade

Navrhove vzory - Bohmer

facade.php #

<?php

/*
  Návrhový vzor Facade poskytuje zjednodušené rozhraní pro sérii rozhraní. Nabízí
  rozhraní, které zjednodušuje používání základního systému.
  
  Pro implementaci návrhového vzoru Facade jsou nutné následující kroky:
  1. Identifikovat třídy a objekty systému, které mají být schované za fasádou.
  2. Definovat operace, které má fasáda umožnit.
  3. Implementovat třídy fasády a vytvořit metody, pomocí nichž je fasáda
  schopná přistupovat ke schovaným komponentám.
  4. Ve třídě fasády implementovat metody, které umožní zjednodušený přístup
  k jednotlivým komponentám systému za účelem provedení různých operací.
  
  
  Na první pohled se návrhový vzor Facade podobá vzoru Adapter. Avšak fasáda
se na rozdíl od adaptéru nevyužívá k přizpůsobení jednoho rozhraní druhému.
Fasáda zjednodušuje stávající rozhraní, redukuje počet tříd, které musí klient
používat, a zjednodušuje použitelnost určitého subsystému.
Fasáda rovněž prosazuje něco,
  
*/


/*
  Příklad v knize je takový nic moc.
*/

class FacadePurchase
{
    protected $library = null;
    protected $publishers = array();
    public function __construct(Library $library)
    {
        $this->library = $library;
    }
    public function addPublisher($id, AbstractPublisher $publisher)
    {
        $this->publishers[$id] = $publisher;
    }

    public function purchase($publisher, $pageCount)
    {
        if (!isset($this->publishers[$publisher])) {
            throw new UnknownPublisherException('Neznámý vydavatel');
        }
        $publication = $this->publishers[$publisher]->sellPublication(
            $pageCount
        );
        $id = IdGenerator::getInstance()->generateId();
        $this->library->addToLibrary($id, $publication);
        return $publication;
    }
}

// USAGE
$debugger = DebuggerEcho::getInstance();
$library = new Library($debugger);

$bookPublisher = new BookPublisher('PC');
$journalPublisher = new JournalPublisher('medicína');

$facade = new FacadePurchase($library);
$facade->addPublisher('PC', $bookPublisher);
$facade->addPublisher('MEDICINA', $journalPublisher);

$facade->purchase('PC', 460);
$facade->purchase('MEDICINA', 300);

On gists

PHP CLI colors & getopts commands

PHP CLI

cli.php #

<?php

// https://www.supercoders.in/2019/07/php-command-line-php-parsing-program_16.html
// https://misc.flogisoft.com/bash/tip_colors_and_formatting
// https://joshtronic.com/2013/09/02/how-to-use-colors-in-command-line-output/

$longopts  = array(
    "required:",     // Required value
    "optional::",    // Optional value
    "option",        // No value
    "opt",           // No value
);

$options = getopt("", $longopts);

echo "\e[0;34;41mMerry Christmas!\e[0m\n";
echo "kunda";
echo "\033[31m some colored text \033[0m some white text \n";
echo  "Normal \e[5mBlink \n";
echo "Normal \e[1mBold \n";
echo "Default \e[33mYellow \n";


On gists

Viewport utitilies (edges overlapping control)

jQuery

utitlies.js #

		/*!
			* Check if an element is out of the viewport
			* (c) 2018 Chris Ferdinandi, MIT License, https://gomakethings.com
			* @param  {Node}  elem The element to check
			* @return {Object}     A set of booleans for each side of the element
			*/
			var isOutOfViewport = function (elem) {

				// Get element's bounding
				var bounding = elem.getBoundingClientRect();

				// Check if it's out of the viewport on each side
				var out = {};
				out.top = bounding.top < 0;
				out.left = bounding.left < 0;
				out.bottom = bounding.bottom > (window.innerHeight || document.documentElement.clientHeight);
				out.right = bounding.right > (window.innerWidth || document.documentElement.clientWidth);
				out.any = out.top || out.left || out.bottom || out.right;
				out.all = out.top && out.left && out.bottom && out.right;

				return out;

		};
		
		
		
		
		// from bottom to top
		// console.table({
		// 	'tooltipHeight': $tooltip.height(),
		// 	'offsetTop': offsetPos.y,
		// 	'positionTop': position.top,
		// 	'windowHeight': $(window).height(),
		// 	'documentHeight': $(document).height(),
		// 	'scrollTop': $(window).scrollTop(),
		// });
		
		if (offsetPos.y - $(window).scrollTop() + $tooltip.outerHeight(true) >  $(window).height())
		{
			var moveUp = offsetPos.y -  $tooltip.height() - 35;
			$tooltip.css({
				top: moveUp + "px"
			})
		}
		
		
		// right side
		var offset = $(this).offset();
		var position = $(this).position();
		var offsetPos = {
			x: offset.left,
			y: offset.top + 35,
		}

		// prevent overlapping on the right edge
		if (offsetPos.x + tooltipSize.w >= winSize.w)
		{
			offsetPos.x = winSize.w - tooltipSize.w - gutter;   
		}

On gists

11. Proxy

Navrhove vzory - Bohmer

proxy.php #

<?php

include "1.php";


/*

    Definice
    --------
    Návrhový vzor Proxy kontroluje přístup k objektu pomocí zástupce, který se používá
    místo vlastního objektu.

    Pro implementaci zástupce typu Protection Proxy je nutné provést následující
    kroky:
    1. Vytvořit třídu, která implementuje veškerá rozhraní implementované třídou,
    jejíž instance mají být chráněné.
    2. Ve všech metodách delegovat volání na objekt, který provede požadovanou
    úlohu.
    3. Vytvořit potomka třídy z bodu 2 a v relevantních metodách implementovat
    kontrolní mechanizmy.

*/


abstract class PublicationProxy implements Publication
{
    protected $publication;

    public function __construct(Publication $publication)
    {
        $this->publication = $publication;
    }

    public function open()
    {
        return $this->publication->open();
    }

    public function close()
    {
        return $this->publication->close();
    }

    public function setPageNumber($page)
    {
        return $this->publication->setPageNumber($page);
    }

    public function getPageNumber()
    {
        return $this->publication->getPageNumber();
    }

    public function getDailyRate($days = 1)
    {
        return $this->publication->getDailyRate($days);
    }

    public function getCategory()
    {
        return $this->publication->getCategory();
    }

    public function getPageCount()
    {
        return $this->publication->getPageCount();
    }
}


class PrepaidPublicationProxy extends PublicationProxy
{
    protected $startPage;
    protected $endPage;

    public function __construct(Publication $publication, $startPage, $endPage)
    {
        parent::__construct($publication);
        $this->startPage = $startPage;

        $this->endPage = $endPage;
    }

    public function setPageNumber($page)
    {
        if ($this->startPage > $page || $this->endPage < $page) {
            throw new OutOfRangeException(
                $page,
                $this->startPage,
                $this->endPage
            );
        }
        return $this->publication->setPageNumber($page);
    }
}


class OutOfRangeException extends \Exception
{
    protected $page;
    protected $startPage;
    protected $endPage;
    public function __construct($page, $startPage, $endPage)
    {
        $this->page = $page;
        $this->startPage = $startPage;
        $this->endPage = $endPage;
        $this->message = sprintf(
            "Požadovaná strana číslo %dse nenachází v předplaceném rozsahu stran %d - %d.",
            $this->page,
            $this->startPage,
            $this->endPage
        );
    }

    public function getPage()
    {
        return $this->page;
    }

    public function getStartPage()
    {
        return $this->startPage;
    }

    public function getEndPage()
    {
        return $this->endPage;
    }
}


$book = new Book('medicína', 650);
$proxy = new PrepaidPublicationProxy($book, 261, 414);
$proxy->open();

try 
{
    $proxy->setPageNumber(300);
    print "Kniha je otevřená na straně 300.\n";
    $proxy->setPageNumber(115);
    print "Kniha je otevřená na straně 115.\n";
} 
catch (OutOfRangeException $e) {
    print $e->getMessage() . "\n";
}
$proxy->close();

/*
    Kniha je otevřená na straně 300.
    Požadovaná strana číslo 115 se nenachází
    v předplaceném rozsahu stran 261-414.
*/

On gists

jQuery plugin from literal object

jQuery-plugins

plugin.js #

/*!
 * jQuery prototypal inheritance plugin boilerplate
 * Author: Alex Sexton, Scott Gonzalez
 * Further changes: @addyosmani
 * Licensed under the MIT license
 */

// myObject - an object representing a concept that you want
// to model (e.g. a car)
var myObject = {
  init: function( options, elem ) {
    // Mix in the passed-in options with the default options
    this.options = $.extend( {}, this.options, options );

    // Save the element reference, both as a jQuery
    // reference and a normal reference
    this.elem  = elem;
    this.$elem = $(elem);

    // Build the DOM's initial structure
    this._build();

    // return this so that we can chain and use the bridge with less code.
    return this;
  },
  options: {
    name: "No name"
  },
  _build: function(){
    //this.$elem.html('<h1>'+this.options.name+'</h1>');
  },
  myMethod: function( msg ){
    // You have direct access to the associated and cached
    // jQuery element
    console.log("myMethod triggered");
    // this.$elem.append('<p>'+msg+'</p>');
  }
};

// Object.create support test, and fallback for browsers without it
if ( typeof Object.create !== "function" ) {
    Object.create = function (o) {
        function F() {}
        F.prototype = o;
        return new F();
    };
}

// Create a plugin based on a defined object
$.plugin = function( name, object ) {
  $.fn[name] = function( options ) {
    return this.each(function() {
      if ( ! $.data( this, name ) ) {
        $.data( this, name, Object.create(object).init(
        options, this ) );
      }
    });
  };
};

// Usage:
// With myObject, we could now essentially do this:
// $.plugin('myobj', myObject);

// and at this point we could do the following
// $('#elem').myobj({name: "John"});
// var inst = $('#elem').data('myobj');
// inst.myMethod('I am a method');

On gists

Plugin pattern - Boilerplate

jQuery-plugins

plugin.js #

// jQuery Plugin Boilerplate
// A boilerplate for jumpstarting jQuery plugins development
// version 1.1, May 14th, 2011
// by Stefan Gabos

(function($) {

    $.pluginName = function(element, options) {

        var defaults = {
            foo: 'bar',
            onFoo: function() {}
        }

        var plugin = this;

        plugin.settings = {}

        var $element = $(element),
             element = element;

        plugin.init = function() {
            plugin.settings = $.extend({}, defaults, options);
            // code goes here
        }

        plugin.foo_public_method = function() {
            // code goes here
        }

        var foo_private_method = function() {
            // code goes here
        }

        plugin.init();

    }

    $.fn.pluginName = function(options) {

        return this.each(function() {
            if (undefined == $(this).data('pluginName')) {
                var plugin = new $.pluginName(this, options);
                $(this).data('pluginName', plugin);
            }
        });

    }

})(jQuery);



// USAGE
$(document).ready(function() {

    // attach the plugin to an element
    $('#element').pluginName({'foo': 'bar'});

    // call a public method
    $('#element').data('pluginName').foo_public_method();

    // get the value of a property
    $('#element').data('pluginName').settings.foo;

});

On gists

10. Decorator

Navrhove vzory - Bohmer

decorator.php #

<?php

include "1.php";

/*
    Definice
    --------
    Návrhový vzor Decorator rozšiřuje daný objekt o novou funkčnost nebo změní stávající
    metody za běhu programu. Tento návrhový vzor nabízí flexibilní alternativu
    k vytváření potomků tříd.

    Pro dosažení požadovaného výsledku jsou nutné následující kroky:
    1. Vytvořit základní třídu pro dekorátory, která je stejného typu jako objekt,
    který má být dekorovaný. Vytvořit potomka této třídy nebo v nové třídě
    implementovat všechny metody rozhraní.

    2. V základní třídě definovat konstruktor, jemuž bude možné předat dekorovaný
    objekt. Tento objekt uložit ve třídě dekorátoru.

    3. Implementovat všechny metody základní třídy takovým způsobem, že se
    jejich volání bude delegovat na objekt, který se má dekorovat.

    4. Implementovat libovolné konkrétní dekorátory, jež jsou potomky třídy
    z bodu 3. Konkrétního chování dekorátoru se docílí přepsáním jednotlivých
    metod.
    5. Kombinací více dekorátorů lze dosáhnout jejich vzájemným dekorováním.
*/



abstract class PublicationDecorator implements Publication
{
    protected $publication;

    public function __construct(Publication $publication)
    {
        $this->publication = $publication;
    }

    public function open()
    {
        return $this->publication->open();
    }

    public function close()
    {
        return $this->publication->close();
    }

    public function setPageNumber($page)
    {
        return $this->publication->setPageNumber($page);
    }

    public function getPageNumber()
    {
        return $this->publication->getPageNumber();
    }

    public function getDailyRate($days = 1)
    {
        return $this->publication->getDailyRate($days);
    }

    public function getCategory()
    {
        return $this->publication->getCategory();
    }

    public function getPageCount()
    {
        return $this->publication->getPageCount();
    }

    public function __call($method, $args) 
    {
        return call_user_func_array(
        array($this->publication, $method), $args
        );
    }

    public function providesMethod($method) 
    {
        if (method_exists($this->publication, $method)) 
        {
            return TRUE;
        }

        if ($this->publication instanceof PublicationDecorator) 
        {
            return $this->publication->providesMethod($method);
        }

        return FALSE;
    }

    public function getPublication()
    {
        return $this->publication;
    }

}



class PublicationDecoratorAppendix extends PublicationDecorator
{
    public function getDailyRate($days = 1)
    {
        $rate = $this->publication->getDailyRate($days);
        return $rate + 2;
    }

    public function getPageCount()
    {
        $pageCount = $this->publication->getPageCount();
        return $pageCount + 30;
    }
}

// Použití
$book = new Book('medicína', 100);
$withAppendix = new PublicationDecoratorAppendix($book);

printf("Celkový počet stran s přílohou: %d\n",
$withAppendix->getPageCount()
);

printf("Denní sazba: %.2f Kč\n",
$withAppendix->getDailyRate()
);

/*
    Celkový počet stran s přílohou: 130
    Denní sazba: 12.00 Kč
*/


// Další decorator
class PublicationDecoratorNews extends PublicationDecorator 
{
    public function getDailyRate($days = 1) 
    {
        $rate = $this->publication->getDailyRate($days);
        return round($rate * 0.8, 2);
    }
}

$newsWithAppendix = new PublicationDecoratorNews($withAppendix);

printf("Celkový počet stran s přílohou: %d\n",
$newsWithAppendix->getPageCount()
);

printf("Denní sazba: %.2f Kč\n",
$newsWithAppendix->getDailyRate()
);

/*
    Celkový počet stran s přílohou: 130
    Denní sazba: 9.60 Kč
*/


/* 
    Další využití
    -------------
    Lze doplnit i nové metody

*/

class PublicationDecoratorCd extends PublicationDecorator
{
    protected $track = 1;

    public function getTrack()
    {
        return $this->track;
    }

    public function setTrack($track)
    {
        $this->track = $track;
    }

    public function getDailyRate($days = 1)
    {
        $rate = $this->publication->getDailyRate($days);
        return $rate * 1.3;
    }
}

$book = new Book('italská kuchyně', 280);
$withCd = new PublicationDecoratorCd($book);

printf("Denní sazba: %.2f Kč\n", $withCd->getDailyRate());

$withCd->setTrack(10);
printf("Aktuální stopa: %d \n", $withCd->getTrack());

/*
    Denní sazba: 13.00 Kč
    Aktuální stopa: 10
*/



/*
    Může vzniknout problém, že jiný dekorátor tyto metody nevidí,
    odchytne se to pres __call, ale je to takové magické...
*/
$book = new Book('italská kuchyně', 280);
$withCd = new PublicationDecoratorCd($book);
$newsWithCd = new PublicationDecoratorNews($withCd);

printf("Denní sazba: %.2f Kč\n", $newsWithCd->getDailyRate());
$newsWithCd->setTrack(10);
// printf("Aktuální stopa: %d \n", $newsWithCd->getTrack());

/*
    Denní sazba: 10.40 Kč
    Aktuální stopa: 10
*/


/* 
    Dá se to vyřešit lépe... 
    viz vlastní metoda na existenci providesMethods()
*/

$book = new Book('italská kuchyně', 280);
$withCd = new PublicationDecoratorCd($book);
$newsWithCd = new PublicationDecoratorNews($withCd);

if ($newsWithCd->providesMethod('setTrack')) 
{

   var_dump($newsWithCd->getPublication());
    $newsWithCd->setTrack(30);
}

printf("Aktuální stopa: %d \n", $newsWithCd->getTrack());

On gists

Css modal window 2 (ghost)

CSS CSS trick

modal.html #

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>JS Bin</title>
  <style>
.blocker
{
  position: fixed;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
    width: 100%;
    height: 100%;
    overflow: auto;
    z-index: 1;
    padding: 20px;
    box-sizing: border-box;
    background-color: #000;
    background-color: #000000bf;
    text-align: center;
}

.blocker::before
{
    content: "";
    display: inline-block;
    height: 100%;
    vertical-align: middle;
    margin-right: -0.05em;
}

.modal
{
  
    vertical-align: middle;
    position: relative;
    z-index: 2;
    max-width: 500px;
    box-sizing: border-box;
    width: 90%;
    background: #fff;
    padding: 15px 30px
}
  </style>
</head>
<body>

<!-- https://jquerymodal.com/ -->
  
  <div class="jquery-modal blocker current">
    <div class="modal" style="display: inline-block;">
        <h1>Hello there!</h1>
        <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p><a href="#close-modal" rel="modal:close" class="close-modal ">Close</a></div>
    </div>
  </div>
</body>
</html>

On gists

Css modal window

CSS CSS trick

index.html #

<!-- https://jsbin.com/pecarecezu/edit?html,css,output -->

<div class="modal">
  <div class="header">
    <h1>Some heading</h1>
  </div>
  <div class="content">
    <p>
      lorem
    </p>
  </div>
</div>