Kcko
3/26/2020 - 8:42 AM

1. Základní aplikace

<?php

interface Publication 
{
    public function open();
    public function close();
    public function setPageNumber($page);
    public function getPageNumber();
}


class Book implements Publication
{
    protected $category;
    protected $pageCount;
    protected $pageNumber = 0;
    protected $closed = TRUE;

    public function __construct($category, $pageCount)
    {
        $this->category = $category;
        $this->pageCount = $pageCount;
    }

    public function open()
    {
        $this->closed = FALSE;
    }

    public function setPageNumber($page)
    {
        if ($this->close !== FALSE &&$this->pageCount < $page)
        {
            return FALSE;
        }

        $this->pageNumber = $page;
        
        return TRUE;
    }

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

    public function close()
    {
        $this->setPageNumber(0);
        $this->closed = TRUE;
    }

    public function __destruct()
    {
        if (!$this->closed)
        {
            $this->close();
        }
    }

    public function getDailyRate($days = 1)
    {
        if ($days > 14)
            return 7.5;

        return 10;
    }

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

}


class Member
{
    protected $id;
    protected $name;

    public function __construct($id, $name)
    {
        $this->id = $id;
        $this->name = $name;
    }

    public function getId()
    {
        return $this->id;
    }

    public function getName()
    {
        return $this->name;
    }
}


class Library
{
    protected $library = [];
    protected $rentalActions = [];
    protected $debugger;

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

    public function addToLibrary($id, Publication $p)
    {
        $this->library[$id] = $p;

        $this->debug('Nová knižka v knihovně ' . $p->getCategory());
    }

    public function rentPublication(Publication $p, Member $m)
    {
        $publicationId = array_search($p, $this->library);

        if (!$publicationId)
            throw new \Exception('Tato publikace neexistuje');

        if (!$this->isPublicationAvailable($p))
            throw new \Exception('Tuto publikaci si uz nekdo pujcil');

        $this->debug('' . $m->getName() . ' si půjčil knihu ' . $p->getCategory());

        $rentalAction = new RentalAction($p, $m);
        $this->rentalActions[] = $rentalAction;

        return $rentalAction;
    }

    public function returnPublication(Publication $p)
    {
        foreach ($this->rentalActions as $rentalAction)
        {
            if ($rentalAction->getPublication() !== $p)
                continue;

            if ($rentalAction->isReturned())
                continue;

            $this->debug($rentalAction->getMember()->getName() . '  vrátil knihu ' . $p->getCategory());
            $rentalAction->markPublicationReturned();
            return FALSE;
        }

        return TRUE;
    }

    public function isPublicationAvailable(Publication $p)
    {
        foreach ($this->rentalActions as $rentalAction)
        {
            if ($rentalAction->getPublication() !== $p)
                continue;

            if ($rentalAction->isReturned())
                continue;

            return FALSE;
        }

        return TRUE;
    }

    public function getLibrary()
    {
        return $this->library;
    }
    
    public function getRentalActions()
    {
        return $this->rentalActions;
    }

    protected function debug($message)
    {
        $this->debugger->debug($message);
    }
}


class RentalAction
{
    protected $publication;
    protected $member;
    protected $rentDate;
    protected $returnDate = NULL;

    public function __construct(Publication $p, Member $m, $date = NULL)
    {
        $this->publication = $p;
        $this->member = $m;

        if ($date == NULL)
            $date = date('Y-m-d H:i:s');

        $this->rentDate = $date;
    }

	/**
	 * 
	 * @return mixed
	 */
	function getPublication() {
		return $this->publication;
	}
	
	/**
	 * 
	 * @return mixed
	 */
	function getMember() {
		return $this->member;
	}
	
	/**
	 * 
	 * @return mixed
	 */
	function getRentDate() {
		return $this->rentDate;
	}
	
	/**
	 * 
	 * @return mixed
	 */
	function getReturnDate() {
		return $this->returnDate;
    }
    

    public function markPublicationReturned($date = NULL)
    {
        if ($date == NULL)
            $date = date('Y-m-d H:i:s');

        $this->returnDate = $date;        
    }


    public function isReturned()
    {
        return $this->returnDate !== NULL;
    }
}

// DEBUGGER, kompozice
interface Debugger
{
    public function debug($message);
}

class DebuggerEcho implements Debugger
{
    public function debug($message)
    {
        echo $message . PHP_EOL;
    }
}


class DebuggerLog implements Debugger
{
    // zapis do souboru, pro demonstraci jen s prefixem ...
    public function debug($message)
    {
        echo 'LOG: ' . $message . PHP_EOL;
    }
}

class DebuggerNull implements Debugger
{
    public function debug($message)
    {
        
    }
}


$library = new Library(new DebuggerEcho);
$book1 = new Book('pc', 100);
$member1 = new Member(1, 'Roman Janko');
$member2 = new Member(2, 'Pepa Kos');

$library->addToLibrary(1, $book1);
$library->rentPublication($book1, $member1);
$library->returnPublication($book1);

$library->rentPublication($book1, $member2);
$library->returnPublication($book1);

$library->rentPublication($book1, $member1);
$library->returnPublication($book1);

$library->rentPublication($book1, $member1);


// print_r($library->getLibrary());
// print_r($library->getRentalActions());