Skip to content

Commit

Permalink
extracted from orig repo
Browse files Browse the repository at this point in the history
  • Loading branch information
juzna committed Jul 31, 2012
0 parents commit 370ef6d
Show file tree
Hide file tree
Showing 4 changed files with 350 additions and 0 deletions.
201 changes: 201 additions & 0 deletions DatePaginator.php
@@ -0,0 +1,201 @@
<?php

namespace steky\nette\DatePaginator;
use \Nette\Object;
use \DateTime;

/**
* @author Martin Štekl <martin.stekl@gmail.com>
* @since 2012-07-21
*
* @property \DateTime $date
* @property \DateTime $oldestDate
* @property \DateTime $newestDate
* @property int $step
* @property-read bool $oldest
* @property-read bool $newest
* @property-read int $days
* @property-read \DateTime $previousDate
* @property-read \DateTime $nextDate
*/
class DatePaginator extends Object {

/** Výchozí počet dní jednoho kroku stránky */
const DEFAULT_STEP = 1;

/** @var \DateTime */
private $date = null;

/** @var \DateTime */
private $oldestDate = null;

/** @var \DateTime */
private $newestDate = null;

/** @var int */
private $step = self::DEFAULT_STEP;

/**
* Pokud zadáme datum mimo nastavené minimum a maximum,
* zarovná se autiomaticky na daný okraj.
*
* @param \DateTime $date
*/
public function setDate(DateTime $date) {
$date = $this->normalizeDate($date);
if ($this->oldestDate !== null && $this->oldestDate > $date) {
$date = clone $this->oldestDate;
} elseif ($this->newestDate !== null && $this->newestDate < $date) {
$date = clone $this->newestDate;
}
$this->date = $date;
}

/**
* @return \DateTime
*/
public function getDate() {
return clone $this->date;
}

/**
* @param \DateTime $oldestDate
* @throws InvalidArgumentException Pokud nastavuji datum novější než newest
*/
public function setOldestDate($oldestDate) {
$oldest_date = $this->normalizeDate($oldestDate);
if ($this->newestDate !== null && $this->newestDate < $oldest_date) {
throw new InvalidArgumentException('Oldest date cannot be newer than newest.');
} elseif ($this->date !== null && $oldest_date > $this->date) {
throw new InvalidArgumentException('Given oldest date in newer than current date.');
}
$this->oldestDate = $oldest_date;
}

/**
* @return \DateTime
*/
public function getOldestDate() {
return clone $this->oldestDate;
}

/**
* @param \DateTime $newestDate
* @throws InvalidArgumentException Pokud nastavuji datum starší než oldest
*/
public function setNewestDate($newestDate) {
$newest_date = $this->normalizeDate($newestDate);
if ($this->oldestDate !== null && $this->oldestDate > $newest_date) {
throw new InvalidArgumentException('Newest date cannot be older than oldest.');
} elseif ($this->date !== null && $newest_date < $this->date) {
throw new InvalidArgumentException('Given newest date in older than current date.');
}
$this->newestDate = $newest_date;
}

/**
* @return \DateTime
*/
public function getNewestDate() {
return clone $this->newestDate;
}

/**
* @return bool
*/
public function isOldest() {
return $this->oldestDate == $this->date;
}

/**
* @return bool
*/
public function isNewest() {
return $this->newestDate == $this->date;
}

/**
* @return int
*/
public function getStep() {
return $this->step;
}

/**
* Nastaví krok pro posun ve dnech.
*
* @param int $step
* @throws InvalidArgumentException Pokud je krok menší jak 1.
*/
public function setStep($step) {
if (!is_numeric($step)) {
throw new InvalidArgumentException('Step for DatePaginator must be a number.');
}
// Tohle je nutné, protože se správně převede číselný řetězec na číslo (int nebo float)
$step = 0 + $step;
if (is_float($step)) {
throw new InvalidArgumentException('Step for DatePaginator cannot be float.');
}
if ($step < 1) {
throw new InvalidArgumentException('Step for DatePaginator cannot be zero or negative.');
}
$this->step = intval($step);
}

/**
* Vrací počet dní mezi nejstarším a nejnovějším datem.
*
* @return int
* @throws InvalidStateException Pokud zjistíme, že neest date je starší než oldest
*/
public function getDays() {
if ($this->newestDate < $this->oldestDate) {
throw new InvalidStateException('Newest date is older than Oldest date.');
}
$difference = $this->newestDate->diff($this->oldestDate);
return $difference->days;
}

/**
* Vrací datum předchozího dne. Pokud bychom měli vrátit starší datum než nejstarší,
* tak vrátíme právě to nejstarší.
*
* @return \DateTime
*/
public function getPreviousDate() {
if ($this->date == $this->oldestDate) {
return $this->date;
}
$previous_date = clone $this->date;
$previous_date = $previous_date->modify('- ' . $this->step . ' days');
return $previous_date;
}

/**
* Vrací datum následujícího dne. Pokud bychom měli vrátit novější datum než nejnovější,
* tak vrátíme právě to nejnovější.
*
* @return \DateTime
*/
public function getNextDate() {
if ($this->date == $this->newestDate) {
return $this->date;
}
$next_date = clone $this->date;
$next_date = $next_date->modify('+ ' . $this->step . ' days');
return $next_date;
}

/**
* Upraví zadané datum tak, že složka hodin nebude mít vliv. Tedy nastaví
* čas na 00:00:00. Zadaný argument ale není ovlivněn.
*
* @param \DateTime $date
* @return \DateTime
*/
private function normalizeDate(DateTime $date) {
$clone = clone $date;
return $clone->setTime(0, 0, 0);
}

}
86 changes: 86 additions & 0 deletions VisualDatePaginator.php
@@ -0,0 +1,86 @@
<?php

namespace steky\nette\DatePaginator;
use \Nette\Application\UI\Control;
use \Nette\Application\UI\Form;
use \DateTime;

/**
* Visual paginator control.
*
* @author Martin Štekl <martin.stekl@gmail.com>
* @since 2012-07-21
*/
class VisualDatePaginator extends Control {

/** @persistent */
public $date = null;

/** @var DatePaginator */
private $paginator = null;

/**
* @return \Nette\Forms\Form
*/
public function createComponentDateForm() {
$form = new Form();
$form->getElementPrototype()->style = 'margin: 0;';

$form->addDatePicker('paginatorDate')
->addRule(Form::VALID, 'Entered date is not valid!')
->addCondition(Form::FILLED)
->addRule(Form::RANGE, 'Entered date is not within allowed range.', array($this->getPaginator()->getOldestDate(), $this->getPaginator()->getNewestDate()));

$form['paginatorDate']->setDefaultValue($this->getPaginator()->getDate());

$form->onSuccess[] = callback($this, 'formSubmitted');

return $form;
}

/**
* @param \Nette\Forms\Form $form
*/
public function formSubmitted(Form $form) {
$values = $form->getValues();

$this->getPaginator()->setDate($values['paginatorDate']);
$this->date = $values['paginatorDate']->format('Y-m-d');

$this->redirect('this', array('date' => $this->date, ));
}

/**
* @return DatePaginator
*/
public function getPaginator() {
if (!$this->paginator) {
$this->paginator = new DatePaginator();
}
return $this->paginator;
}

/**
* Renders paginator.
*
* @return void
*/
public function render() {
$paginator = $this->getPaginator();
$this->template->paginator = $paginator;
$this->template->setFile(__DIR__ . '/template.latte');
$this->template->render();
}

/**
* Loads state informations.
*
* @param array
* @return void
*/
public function loadState(array $params) {
parent::loadState($params);
$this->getPaginator()->setDate(new DateTime($this->date ?: 'now'));
}

}
18 changes: 18 additions & 0 deletions exceptions.php
@@ -0,0 +1,18 @@
<?php

namespace steky\nette\DatePaginator;
use \Nette;

/**
* @author Martin Štekl <martin.stekl@gmail.com>
* @since 2012-07-21
*/
class InvalidArgumentException extends Nette\InvalidArgumentException {
}

/**
* @author Martin Štekl <martin.stekl@gmail.com>
* @since 2012-07-23
*/
class InvalidStateException extends Nette\InvalidStateException {
}
45 changes: 45 additions & 0 deletions template.latte
@@ -0,0 +1,45 @@
{*
* @param DatePaginator $paginator
*}

{if $paginator->days > 1}
<div class="date-paginator btn-toolbar">
<div class="btn-group">
{if $paginator->isOldest()}
<span class="btn disabled"><i class="icon-fast-backward"></i> Oldest</span>
{else}
<a n:href="this, 'date' => $paginator->getOldestDate()->format('Y-m-d')" class="btn"><i class="icon-fast-backward"></i> Oldest</a>
{/if}

{if $paginator->isOldest()}
<span class="btn disabled"><i class="icon-step-backward"></i> Previous</span>
{else}
<a n:href="this, 'date' => $paginator->getPreviousDate()->format('Y-m-d')" class="btn"><i class="icon-step-backward"></i> Previous</a>
{/if}
</div>

<div class="btn-group" style="top: -0.8em;">
{form dateForm class => 'form-inline'}
<div n:if="$form->hasErrors()" n:foreach="$form->errors as $error"class="alert alert-error">{$error}</div>

<div class="input-append date">
{input paginatorDate class => "input-small"}<span class="add-on"><i class="icon-calendar"></i></span>
</div>
{/form dateForm}
</div>

<div class="btn-group">
{if $paginator->isNewest()}
<span class="btn disabled">Next <i class="icon-step-forward"></i></span>
{else}
<a n:href="this, 'date' => $paginator->getNextDate()->format('Y-m-d')" class="btn">Next <i class="icon-step-forward"></i></a>
{/if}

{if $paginator->isNewest()}
<span class="btn disabled">Newest <i class="icon-fast-forward"></i></span>
{else}
<a n:href="this, 'date' => $paginator->getNewestDate()->format('Y-m-d')" class="btn">Newest <i class="icon-fast-forward"></i></a>
{/if}
</div>
</div>
{/if}

0 comments on commit 370ef6d

Please sign in to comment.