forked from stekycz/nette-date-paginator
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 370ef6d
Showing
4 changed files
with
350 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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); | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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')); | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 { | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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} |