Skip to content

Commit

Permalink
tweak: simplify iterable objects
Browse files Browse the repository at this point in the history
  • Loading branch information
g105b committed Jan 8, 2024
1 parent 57d6699 commit f35d1e2
Show file tree
Hide file tree
Showing 2 changed files with 123 additions and 1 deletion.
113 changes: 113 additions & 0 deletions examples/binding/14-iterator-aggregate.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
<?php
use Gt\Dom\HTMLDocument;
use Gt\DomTemplate\Bind;
use Gt\DomTemplate\BindableCache;
use Gt\DomTemplate\Binder;
use Gt\DomTemplate\BindGetter;
use Gt\DomTemplate\DocumentBinder;
use Gt\DomTemplate\ElementBinder;
use Gt\DomTemplate\HTMLAttributeBinder;
use Gt\DomTemplate\HTMLAttributeCollection;
use Gt\DomTemplate\ListBinder;
use Gt\DomTemplate\ListElementCollection;
use Gt\DomTemplate\PlaceholderBinder;
use Gt\DomTemplate\TableBinder;

require __DIR__ . "/../../vendor/autoload.php";

// EXAMPLE CODE: https://github.com/PhpGt/DomTemplate/wiki/Binding-objects#iterator-and-iteratoraggregate-objects

$html = <<<HTML
<!DOCTYPE html>
<h1>Events for <span data-bind:text="dateString">1st Jan 2000</span>:</h1>
<ol>
<li data-list>
<time data-bind:text="eventStartTimeText">00:00</time>
<p data-bind:text="title">Title of event</p>
</li>
</ol>
HTML;

function example(Binder $binder, CalendarDay $calendarDay):void {
$binder->bindData($calendarDay);
}

class CalendarDay implements IteratorAggregate {
private DateTime $dateTime;

public function __construct(
public int $year,
public int $month,
public int $day,
private EventRepository $eventRepository,
) {
$this->dateTime = new DateTime("$year-$month-$day");
}

#[BindGetter]
public function getDateString():string {
return $this->dateTime->format("jS M Y");
}

/** @return Traversable<CalendarEvent> */
public function getIterator():Traversable {
yield from $this->eventRepository->getEventsForDate(
$this->year,
$this->month,
$this->day,
);
}
}

class CalendarEvent {
public function __construct(
public string $id,
public DateTime $eventStart,
public string $title,
) {}

#[BindGetter]
public function getEventStartTimeText():string {
return $this->eventStart->format("H:i");
}
}

// END OF EXAMPLE CODE

class EventRepository {
public function getEventsForDate(int $y, int $m, int $d):array {
return [
new CalendarEvent(uniqid(), new DateTime(), "First event"),
new CalendarEvent(uniqid(), new DateTime("+15 mins"), "Second event"),
new CalendarEvent(uniqid(), new DateTime("+2 hours"), "Third event"),
];
}
}

$calendar = new CalendarDay(2024, 02, 14, new EventRepository());
$document = new HTMLDocument($html);
$binder = new DocumentBinder($document);
$htmlAttributeBinder = new HTMLAttributeBinder();
$tableBinder = new TableBinder();
$listBinder = new ListBinder();
$placeholderBinder = new PlaceholderBinder();
$elementBinder = new ElementBinder();
$htmlAttributeCollection = new HTMLAttributeCollection();
$elementBinder->setDependencies($htmlAttributeBinder, $htmlAttributeCollection, $placeholderBinder);
$listElementCollection = new ListElementCollection($document);
$bindableCache = new BindableCache();
$listBinder->setDependencies($elementBinder, $listElementCollection, $bindableCache, $tableBinder);
$htmlAttributeBinder->setDependencies($listBinder, $tableBinder);
$binder->setDependencies(
$elementBinder,
$placeholderBinder,
$tableBinder,
$listBinder,
$listElementCollection,
$bindableCache,
);

example($binder, $calendar);
$binder->cleanupDocument();
echo $document;
11 changes: 10 additions & 1 deletion src/DocumentBinder.php
Original file line number Diff line number Diff line change
Expand Up @@ -72,15 +72,24 @@ public function bindData(
$kvp = $kvp->asArray();
}

if(is_object($kvp) && !is_iterable($kvp)) {
// The $kvp object may be both an object with its own key-value-pairs and
// an iterable object. We can perform the two bind operations here.

$object = null;
if(is_object($kvp)) {
if($this->bindableCache->isBindable($kvp)) {
$object = $kvp;
$kvp = $this->bindableCache->convertToKvp($kvp);
}
}

foreach($kvp ?? [] as $key => $value) {
$this->bindKeyValue($key, $value, $context);
}

if(is_iterable($object)) {
$this->listBinder->bindListData($object, $context ?? $this->document);

Check warning on line 91 in src/DocumentBinder.php

View check run for this annotation

Codecov / codecov/patch

src/DocumentBinder.php#L91

Added line #L91 was not covered by tests
}
}

public function bindTable(
Expand Down

0 comments on commit f35d1e2

Please sign in to comment.