Create component system to help cut down on view duplication, see #31
Some checks reported errors
timw4mail/HummingBirdAnimeClient/pipeline/head Something is wrong with the build of this commit
Some checks reported errors
timw4mail/HummingBirdAnimeClient/pipeline/head Something is wrong with the build of this commit
This commit is contained in:
parent
2f2260e0b4
commit
386938c75f
@ -20,6 +20,7 @@ use Aura\Html\HelperLocatorFactory;
|
||||
use Aura\Router\RouterContainer;
|
||||
use Aura\Session\SessionFactory;
|
||||
use Aviat\AnimeClient\API\{Anilist, Kitsu};
|
||||
use Aviat\AnimeClient\Component;
|
||||
use Aviat\AnimeClient\Model;
|
||||
use Aviat\Banker\Teller;
|
||||
use Aviat\Ion\Config;
|
||||
@ -31,6 +32,9 @@ use Monolog\Handler\RotatingFileHandler;
|
||||
use Monolog\Logger;
|
||||
use Psr\SimpleCache\CacheInterface;
|
||||
|
||||
define('APP_DIR', __DIR__);
|
||||
define('TEMPLATE_DIR', APP_DIR . '/templates');
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Setup DI container
|
||||
// -----------------------------------------------------------------------------
|
||||
@ -72,28 +76,45 @@ return static function (array $configArray = []): Container {
|
||||
// Create Aura Router Object
|
||||
$container->set('aura-router', fn() => new RouterContainer);
|
||||
|
||||
// Create Html helper Object
|
||||
// Create Html helpers
|
||||
$container->set('html-helper', static function(ContainerInterface $container) {
|
||||
$htmlHelper = (new HelperLocatorFactory)->newInstance();
|
||||
$htmlHelper->set('menu', static function() use ($container) {
|
||||
$menuHelper = new Helper\Menu();
|
||||
$menuHelper->setContainer($container);
|
||||
return $menuHelper;
|
||||
});
|
||||
$htmlHelper->set('field', static function() use ($container) {
|
||||
$formHelper = new Helper\Form();
|
||||
$formHelper->setContainer($container);
|
||||
return $formHelper;
|
||||
});
|
||||
$htmlHelper->set('picture', static function() use ($container) {
|
||||
$pictureHelper = new Helper\Picture();
|
||||
$pictureHelper->setContainer($container);
|
||||
return $pictureHelper;
|
||||
});
|
||||
$helpers = [
|
||||
'menu' => Helper\Menu::class,
|
||||
'field' => Helper\Form::class,
|
||||
'picture' => Helper\Picture::class,
|
||||
];
|
||||
|
||||
foreach ($helpers as $name => $class)
|
||||
{
|
||||
$htmlHelper->set($name, static function() use ($class, $container) {
|
||||
$helper = new $class;
|
||||
$helper->setContainer($container);
|
||||
return $helper;
|
||||
});
|
||||
}
|
||||
|
||||
return $htmlHelper;
|
||||
});
|
||||
|
||||
// Create Component helpers
|
||||
$container->set('component-helper', static function () {
|
||||
$helper = (new HelperLocatorFactory)->newInstance();
|
||||
$components = [
|
||||
'character' => Component\Character::class,
|
||||
'media' => Component\Media::class,
|
||||
'tabs' => Component\Tabs::class,
|
||||
'verticalTabs' => Component\VerticalTabs::class,
|
||||
];
|
||||
|
||||
foreach ($components as $name => $componentClass)
|
||||
{
|
||||
$helper->set($name, fn () => new $componentClass);
|
||||
}
|
||||
|
||||
return $helper;
|
||||
});
|
||||
|
||||
// Create Request Object
|
||||
$container->set('request', fn () => ServerRequestFactory::fromGlobals(
|
||||
$_SERVER,
|
||||
|
6
app/templates/character.php
Normal file
6
app/templates/character.php
Normal file
@ -0,0 +1,6 @@
|
||||
<article class="<?= $className ?>">
|
||||
<div class="name">
|
||||
<a href="<?= $link ?>"><?= $name ?></a>
|
||||
</div>
|
||||
<a href="<?= $link ?>"><?= $picture ?></a>
|
||||
</article>
|
12
app/templates/media.php
Normal file
12
app/templates/media.php
Normal file
@ -0,0 +1,12 @@
|
||||
<article class="<?= $className ?>">
|
||||
<a href="<?= $link ?>"><?= $picture ?></a>
|
||||
<div class="name">
|
||||
<a href="<?= $link ?>">
|
||||
<?= array_shift($titles) ?>
|
||||
<?php foreach ($titles as $title): ?>
|
||||
<br />
|
||||
<small><?= $title ?></small>
|
||||
<?php endforeach ?>
|
||||
</a>
|
||||
</div>
|
||||
</article>
|
23
app/templates/tabs.php
Normal file
23
app/templates/tabs.php
Normal file
@ -0,0 +1,23 @@
|
||||
<div class="tabs">
|
||||
<?php $i = 0; foreach ($data as $tabName => $tabData): ?>
|
||||
<?php if ( ! empty($tabData)): ?>
|
||||
<?php $id = "{$name}-{$i}"; ?>
|
||||
<input
|
||||
role='tab'
|
||||
aria-controls="_<?= $id ?>"
|
||||
type="radio"
|
||||
name="<?= $name ?>"
|
||||
id="<?= $id ?>"
|
||||
<?= ($i === 0) ? 'checked="checked"' : '' ?>
|
||||
/>
|
||||
<label for="<?= $id ?>"><?= ucfirst($tabName) ?></label>
|
||||
<section
|
||||
id="_<?= $id ?>"
|
||||
role="tabpanel"
|
||||
class="<?= $className ?>"
|
||||
>
|
||||
<?= $callback($tabData, $tabName) ?>
|
||||
</section>
|
||||
<?php endif ?>
|
||||
<?php $i++; endforeach ?>
|
||||
</div>
|
25
app/templates/vertical-tabs.php
Normal file
25
app/templates/vertical-tabs.php
Normal file
@ -0,0 +1,25 @@
|
||||
<div class="vertical-tabs">
|
||||
<?php $i = 0; ?>
|
||||
<?php foreach ($data as $tabName => $tabData): ?>
|
||||
<?php $id = "{$name}-{$i}" ?>
|
||||
<div class="tab">
|
||||
<input
|
||||
type="radio"
|
||||
role='tab'
|
||||
aria-controls="_<?= $id ?>"
|
||||
name="staff-roles"
|
||||
id="<?= $id ?>"
|
||||
<?= $i === 0 ? 'checked="checked"' : '' ?>
|
||||
/>
|
||||
<label for="<?= $id ?>"><?= $tabName ?></label>
|
||||
<section
|
||||
id='_<?= $id ?>'
|
||||
role="tabpanel"
|
||||
class="<?= $className ?>"
|
||||
>
|
||||
<?= $callback($tabData, $tabName) ?>
|
||||
</section>
|
||||
</div>
|
||||
<?php $i++; ?>
|
||||
<?php endforeach ?>
|
||||
</div>
|
@ -1,9 +1,11 @@
|
||||
<?php
|
||||
|
||||
use Aviat\AnimeClient\API\Kitsu;
|
||||
use function Aviat\AnimeClient\getLocalImg;
|
||||
|
||||
?>
|
||||
<main class="details fixed">
|
||||
<section class="flex">
|
||||
<section class="flex" unselectable>
|
||||
<aside class="info">
|
||||
<?= $helper->picture("images/anime/{$data['id']}-original.webp") ?>
|
||||
|
||||
@ -115,81 +117,69 @@ use function Aviat\AnimeClient\getLocalImg;
|
||||
<?php endif ?>
|
||||
<?php if ( ! empty($data['trailer_id'])): ?>
|
||||
<div class="responsive-iframe">
|
||||
<h4>Trailer</h4>
|
||||
<iframe
|
||||
width="560"
|
||||
height="315"
|
||||
src="https://www.youtube.com/embed/<?= $data['trailer_id'] ?>"
|
||||
frameborder="0"
|
||||
allow="autoplay; encrypted-media"
|
||||
allowfullscreen
|
||||
></iframe>
|
||||
<h4>Trailer</h4>
|
||||
<iframe
|
||||
width="560"
|
||||
height="315"
|
||||
role='img'
|
||||
src="https://www.youtube.com/embed/<?= $data['trailer_id'] ?>"
|
||||
allow="autoplay; encrypted-media"
|
||||
allowfullscreen
|
||||
tabindex='0'
|
||||
title="<?= $data['title'] ?> trailer video"
|
||||
></iframe>
|
||||
</div>
|
||||
<?php endif ?>
|
||||
</article>
|
||||
</section>
|
||||
|
||||
<?php if (count($data['characters']) > 0): ?>
|
||||
<section>
|
||||
<h2>Characters</h2>
|
||||
<section>
|
||||
<h2>Characters</h2>
|
||||
|
||||
<div class="tabs">
|
||||
<?php $i = 0 ?>
|
||||
<?php foreach ($data['characters'] as $role => $list): ?>
|
||||
<input
|
||||
type="radio" name="character-types"
|
||||
id="character-types-<?= $i ?>" <?= ($i === 0) ? 'checked' : '' ?> />
|
||||
<label for="character-types-<?= $i ?>"><?= ucfirst($role) ?></label>
|
||||
<section class="content media-wrap flex flex-wrap flex-justify-start">
|
||||
<?php foreach ($list as $id => $char): ?>
|
||||
<?php if ( ! empty($char['image']['original'])): ?>
|
||||
<article class="<?= $role === 'supporting' ? 'small-' : '' ?>character">
|
||||
<?php $link = $url->generate('character', ['slug' => $char['slug']]) ?>
|
||||
<div class="name">
|
||||
<?= $helper->a($link, $char['name']) ?>
|
||||
</div>
|
||||
<a href="<?= $link ?>">
|
||||
<?= $helper->picture("images/characters/{$id}.webp") ?>
|
||||
</a>
|
||||
</article>
|
||||
<?php endif ?>
|
||||
<?php endforeach ?>
|
||||
</section>
|
||||
<?php $i++; ?>
|
||||
<?php endforeach ?>
|
||||
</div>
|
||||
</section>
|
||||
<?= $component->tabs('character-types', $data['characters'], static function ($characterList, $role)
|
||||
use ($component, $url, $helper) {
|
||||
$rendered = [];
|
||||
foreach ($characterList as $id => $character):
|
||||
if (empty($character['image']['original']))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
$rendered[] = $component->character(
|
||||
$character['name'],
|
||||
$url->generate('character', ['slug' => $character['slug']]),
|
||||
$helper->picture("images/characters/{$id}.webp"),
|
||||
(strtolower($role) !== 'main') ? 'small-character' : 'character'
|
||||
);
|
||||
endforeach;
|
||||
|
||||
return implode('', array_map('mb_trim', $rendered));
|
||||
}) ?>
|
||||
</section>
|
||||
<?php endif ?>
|
||||
|
||||
<?php if (count($data['staff']) > 0): ?>
|
||||
<section>
|
||||
<h2>Staff</h2>
|
||||
<section>
|
||||
<h2>Staff</h2>
|
||||
|
||||
<div class="vertical-tabs">
|
||||
<?php $i = 0; ?>
|
||||
<?php foreach ($data['staff'] as $role => $people): ?>
|
||||
<div class="tab">
|
||||
<input type="radio" name="staff-roles" id="staff-role<?= $i ?>" <?= $i === 0 ? 'checked' : '' ?> />
|
||||
<label for="staff-role<?= $i ?>"><?= $role ?></label>
|
||||
<section class='content media-wrap flex flex-wrap flex-justify-start'>
|
||||
<?php foreach ($people as $pid => $person): ?>
|
||||
<article class='character small-person'>
|
||||
<?php $link = $url->generate('person', ['id' => $person['id'], 'slug' => $person['slug']]) ?>
|
||||
<div class="name">
|
||||
<a href="<?= $link ?>">
|
||||
<?= $person['name'] ?>
|
||||
</a>
|
||||
</div>
|
||||
<a href="<?= $link ?>">
|
||||
<?= $helper->picture(getLocalImg($person['image']['original'] ?? NULL)) ?>
|
||||
</a>
|
||||
</article>
|
||||
<?php endforeach ?>
|
||||
</section>
|
||||
</div>
|
||||
<?php $i++; ?>
|
||||
<?php endforeach ?>
|
||||
</div>
|
||||
</section>
|
||||
<?= $component->verticalTabs('staff-role', $data['staff'], static function ($staffList)
|
||||
use ($component, $url, $helper) {
|
||||
$rendered = [];
|
||||
foreach ($staffList as $id => $person):
|
||||
if (empty($person['image']['original']))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
$rendered[] = $component->character(
|
||||
$person['name'],
|
||||
$url->generate('person', ['id' => $person['id'], 'slug' => $person['slug']]),
|
||||
$helper->picture(getLocalImg($person['image']['original'] ?? NULL)),
|
||||
'character small-person',
|
||||
);
|
||||
endforeach;
|
||||
|
||||
return implode('', array_map('mb_trim', $rendered));
|
||||
}) ?>
|
||||
</section>
|
||||
<?php endif ?>
|
||||
</main>
|
@ -156,65 +156,50 @@ use Aviat\AnimeClient\API\Kitsu;
|
||||
<?php if ( ! empty($vas)): ?>
|
||||
<h4>Voice Actors</h4>
|
||||
|
||||
<div class="tabs">
|
||||
<?php $i = 0; ?>
|
||||
<?= $component->tabs('character-vas', $vas, static function ($casting) use ($url, $component, $helper) {
|
||||
$castings = [];
|
||||
foreach ($casting as $id => $c):
|
||||
$person = $component->character(
|
||||
$c['person']['name'],
|
||||
$url->generate('person', [
|
||||
'id' => $c['person']['id'],
|
||||
'slug' => $c['person']['slug']
|
||||
]),
|
||||
$helper->picture(getLocalImg($c['person']['image']))
|
||||
);
|
||||
$medias = array_map(fn ($series) => $component->media(
|
||||
array_merge([$series['title']], $series['titles']),
|
||||
$url->generate('anime.details', ['id' => $series['slug']]),
|
||||
$helper->picture(getLocalImg($series['posterImage'], TRUE))
|
||||
), $c['series']);
|
||||
$media = implode('', array_map('mb_trim', $medias));
|
||||
|
||||
<?php foreach ($vas as $language => $casting): ?>
|
||||
<input <?= $i === 0 ? 'checked="checked"' : '' ?> type="radio" id="character-va<?= $i ?>"
|
||||
name="character-vas"
|
||||
/>
|
||||
<label for="character-va<?= $i ?>"><?= $language ?></label>
|
||||
<section class="content">
|
||||
<table class="borderless max-table">
|
||||
<tr>
|
||||
<th>Cast Member</th>
|
||||
<th>Series</th>
|
||||
</tr>
|
||||
<?php foreach ($casting as $c): ?>
|
||||
<tr>
|
||||
<td>
|
||||
<article class="character">
|
||||
<?php
|
||||
$link = $url->generate('person', ['id' => $c['person']['id'], 'slug' => $c['person']['slug']]);
|
||||
?>
|
||||
<a href="<?= $link ?>">
|
||||
<?= $helper->picture(getLocalImg($c['person']['image'])) ?>
|
||||
<div class="name">
|
||||
<?= $c['person']['name'] ?>
|
||||
</div>
|
||||
</a>
|
||||
</article>
|
||||
</td>
|
||||
<td width="75%">
|
||||
<section class="align-left media-wrap-flex">
|
||||
<?php foreach ($c['series'] as $series): ?>
|
||||
<article class="media">
|
||||
<?php
|
||||
$link = $url->generate('anime.details', ['id' => $series['slug']]);
|
||||
?>
|
||||
<a href="<?= $link ?>">
|
||||
<?= $helper->picture(getLocalImg($series['posterImage'], TRUE)) ?>
|
||||
</a>
|
||||
<div class="name">
|
||||
<a href="<?= $link ?>">
|
||||
<?= $series['title'] ?>
|
||||
<?php foreach ($series['titles'] as $title): ?>
|
||||
<br />
|
||||
<small><?= $title ?></small>
|
||||
<?php endforeach ?>
|
||||
</a>
|
||||
</div>
|
||||
</article>
|
||||
<?php endforeach ?>
|
||||
</section>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach ?>
|
||||
</table>
|
||||
</section>
|
||||
<?php $i++ ?>
|
||||
<?php endforeach ?>
|
||||
</div>
|
||||
$castings[] = <<<HTML
|
||||
<tr>
|
||||
<td>{$person}</td>
|
||||
<td width="75%">
|
||||
<section class="align-left media-wrap-flex">
|
||||
{$media}
|
||||
</section>
|
||||
</td>
|
||||
</tr>
|
||||
HTML;
|
||||
endforeach;
|
||||
|
||||
$languages = implode('', array_map('mb_trim', $castings));
|
||||
|
||||
return <<<HTML
|
||||
<table class="borderless max-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Cast Member</th>
|
||||
<th>Series</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>{$languages}</tbody>
|
||||
</table>
|
||||
HTML;
|
||||
}, 'content') ?>
|
||||
<?php endif ?>
|
||||
<?php endif ?>
|
||||
</section>
|
||||
|
@ -26,7 +26,7 @@
|
||||
</head>
|
||||
<body class="<?= $escape->attr($url_type) ?> list">
|
||||
<?php include 'setup-check.php' ?>
|
||||
<header>
|
||||
<header tabindex="0">
|
||||
<?php
|
||||
include 'main-menu.php';
|
||||
if(isset($message) && is_array($message))
|
||||
@ -39,5 +39,4 @@
|
||||
}
|
||||
}
|
||||
?>
|
||||
|
||||
</header>
|
3
console
3
console
@ -9,6 +9,9 @@ use ConsoleKit\Console;
|
||||
|
||||
$_SERVER['HTTP_HOST'] = 'localhost';
|
||||
|
||||
define('APP_DIR', __DIR__ . '/app');
|
||||
define('TEMPLATE_DIR', APP_DIR . '/templates');
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Start console script
|
||||
// -----------------------------------------------------------------------------
|
||||
|
@ -94,6 +94,7 @@ a:hover, a:active {
|
||||
iframe {
|
||||
display: block;
|
||||
margin: 0 auto;
|
||||
border: 0;
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
|
31
src/AnimeClient/Component/Character.php
Normal file
31
src/AnimeClient/Component/Character.php
Normal file
@ -0,0 +1,31 @@
|
||||
<?php declare(strict_types=1);
|
||||
/**
|
||||
* Hummingbird Anime List Client
|
||||
*
|
||||
* An API client for Kitsu to manage anime and manga watch lists
|
||||
*
|
||||
* PHP version 7.4
|
||||
*
|
||||
* @package HummingbirdAnimeClient
|
||||
* @author Timothy J. Warren <tim@timshomepage.net>
|
||||
* @copyright 2015 - 2020 Timothy J. Warren
|
||||
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
||||
* @version 5.1
|
||||
* @link https://git.timshomepage.net/timw4mail/HummingBirdAnimeClient
|
||||
*/
|
||||
|
||||
namespace Aviat\AnimeClient\Component;
|
||||
|
||||
final class Character {
|
||||
use ComponentTrait;
|
||||
|
||||
public function __invoke(string $name, string $link, string $picture, string $className = 'character'): string
|
||||
{
|
||||
return $this->render('character.php', [
|
||||
'name' => $name,
|
||||
'link' => $link,
|
||||
'picture' => $picture,
|
||||
'className' => $className,
|
||||
]);
|
||||
}
|
||||
}
|
30
src/AnimeClient/Component/ComponentTrait.php
Normal file
30
src/AnimeClient/Component/ComponentTrait.php
Normal file
@ -0,0 +1,30 @@
|
||||
<?php declare(strict_types=1);
|
||||
/**
|
||||
* Hummingbird Anime List Client
|
||||
*
|
||||
* An API client for Kitsu to manage anime and manga watch lists
|
||||
*
|
||||
* PHP version 7.4
|
||||
*
|
||||
* @package HummingbirdAnimeClient
|
||||
* @author Timothy J. Warren <tim@timshomepage.net>
|
||||
* @copyright 2015 - 2020 Timothy J. Warren
|
||||
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
||||
* @version 5.1
|
||||
* @link https://git.timshomepage.net/timw4mail/HummingBirdAnimeClient
|
||||
*/
|
||||
|
||||
namespace Aviat\AnimeClient\Component;
|
||||
|
||||
/**
|
||||
* Shared logic for component-based functionality, like Tabs
|
||||
*/
|
||||
trait ComponentTrait {
|
||||
public function render(string $path, array $data): string
|
||||
{
|
||||
ob_start();
|
||||
extract($data, EXTR_OVERWRITE);
|
||||
include \TEMPLATE_DIR . '/' .$path;
|
||||
return ob_get_clean();
|
||||
}
|
||||
}
|
31
src/AnimeClient/Component/Media.php
Normal file
31
src/AnimeClient/Component/Media.php
Normal file
@ -0,0 +1,31 @@
|
||||
<?php declare(strict_types=1);
|
||||
/**
|
||||
* Hummingbird Anime List Client
|
||||
*
|
||||
* An API client for Kitsu to manage anime and manga watch lists
|
||||
*
|
||||
* PHP version 7.4
|
||||
*
|
||||
* @package HummingbirdAnimeClient
|
||||
* @author Timothy J. Warren <tim@timshomepage.net>
|
||||
* @copyright 2015 - 2020 Timothy J. Warren
|
||||
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
||||
* @version 5.1
|
||||
* @link https://git.timshomepage.net/timw4mail/HummingBirdAnimeClient
|
||||
*/
|
||||
|
||||
namespace Aviat\AnimeClient\Component;
|
||||
|
||||
final class Media {
|
||||
use ComponentTrait;
|
||||
|
||||
public function __invoke(array $titles, string $link, string $picture, string $className = 'media'): string
|
||||
{
|
||||
return $this->render('media.php', [
|
||||
'titles' => $titles,
|
||||
'link' => $link,
|
||||
'picture' => $picture,
|
||||
'className' => $className,
|
||||
]);
|
||||
}
|
||||
}
|
45
src/AnimeClient/Component/Tabs.php
Normal file
45
src/AnimeClient/Component/Tabs.php
Normal file
@ -0,0 +1,45 @@
|
||||
<?php declare(strict_types=1);
|
||||
/**
|
||||
* Hummingbird Anime List Client
|
||||
*
|
||||
* An API client for Kitsu to manage anime and manga watch lists
|
||||
*
|
||||
* PHP version 7.4
|
||||
*
|
||||
* @package HummingbirdAnimeClient
|
||||
* @author Timothy J. Warren <tim@timshomepage.net>
|
||||
* @copyright 2015 - 2020 Timothy J. Warren
|
||||
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
||||
* @version 5.1
|
||||
* @link https://git.timshomepage.net/timw4mail/HummingBirdAnimeClient
|
||||
*/
|
||||
|
||||
namespace Aviat\AnimeClient\Component;
|
||||
|
||||
final class Tabs {
|
||||
use ComponentTrait;
|
||||
|
||||
/**
|
||||
* Creates a tabbed content view
|
||||
*
|
||||
* @param string $name the name attribute for the input[type-option] form elements
|
||||
* also used to generate id attributes
|
||||
* @param array $tabData The data used to create the tab content, indexed by the tab label
|
||||
* @param callable $cb The function to generate the tab content
|
||||
* @return string
|
||||
*/
|
||||
public function __invoke(
|
||||
string $name,
|
||||
array $tabData,
|
||||
callable $cb,
|
||||
string $className = 'content media-wrap flex flex-wrap flex-justify-start'
|
||||
): string
|
||||
{
|
||||
return $this->render('tabs.php', [
|
||||
'name' => $name,
|
||||
'data' => $tabData,
|
||||
'callback' => $cb,
|
||||
'className' => $className,
|
||||
]);
|
||||
}
|
||||
}
|
45
src/AnimeClient/Component/VerticalTabs.php
Normal file
45
src/AnimeClient/Component/VerticalTabs.php
Normal file
@ -0,0 +1,45 @@
|
||||
<?php declare(strict_types=1);
|
||||
/**
|
||||
* Hummingbird Anime List Client
|
||||
*
|
||||
* An API client for Kitsu to manage anime and manga watch lists
|
||||
*
|
||||
* PHP version 7.4
|
||||
*
|
||||
* @package HummingbirdAnimeClient
|
||||
* @author Timothy J. Warren <tim@timshomepage.net>
|
||||
* @copyright 2015 - 2020 Timothy J. Warren
|
||||
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
||||
* @version 5.1
|
||||
* @link https://git.timshomepage.net/timw4mail/HummingBirdAnimeClient
|
||||
*/
|
||||
|
||||
namespace Aviat\AnimeClient\Component;
|
||||
|
||||
final class VerticalTabs {
|
||||
use ComponentTrait;
|
||||
|
||||
/**
|
||||
* Creates a vertical tab content view
|
||||
*
|
||||
* @param string $name the name attribute for the input[type-option] form elements
|
||||
* also used to generate id attributes
|
||||
* @param array $tabData The data used to create the tab content, indexed by the tab label
|
||||
* @param callable $cb The function to generate the tab content
|
||||
* @return string
|
||||
*/
|
||||
public function __invoke(
|
||||
string $name,
|
||||
array $tabData,
|
||||
callable $cb,
|
||||
string $className='content media-wrap flex flex-wrap flex-justify-start'
|
||||
): string
|
||||
{
|
||||
return $this->render('vertical-tabs.php', [
|
||||
'name' => $name,
|
||||
'data' => $tabData,
|
||||
'callback' => $cb,
|
||||
'className' => $className,
|
||||
]);
|
||||
}
|
||||
}
|
@ -39,11 +39,30 @@ final class FormGenerator {
|
||||
* @throws ContainerException
|
||||
* @throws NotFoundException
|
||||
*/
|
||||
public function __construct(ContainerInterface $container)
|
||||
private function __construct(ContainerInterface $container)
|
||||
{
|
||||
$this->helper = $container->get('html-helper');
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new FormGenerator
|
||||
*
|
||||
* @param ContainerInterface $container
|
||||
* @return $this
|
||||
*/
|
||||
public static function new(ContainerInterface $container): self
|
||||
{
|
||||
try
|
||||
{
|
||||
return new static($container);
|
||||
}
|
||||
catch (\Throwable $e)
|
||||
{
|
||||
dump($e);
|
||||
die();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate the html structure of the form
|
||||
*
|
||||
|
@ -35,6 +35,6 @@ final class Form {
|
||||
*/
|
||||
public function __invoke(string $name, array $form)
|
||||
{
|
||||
return (new FormGenerator($this->container))->generate($name, $form);
|
||||
return FormGenerator::new($this->container)->generate($name, $form);
|
||||
}
|
||||
}
|
||||
|
@ -34,8 +34,7 @@ final class Menu {
|
||||
*/
|
||||
public function __invoke($menuName)
|
||||
{
|
||||
$generator = new MenuGenerator($this->container);
|
||||
return $generator->generate($menuName);
|
||||
return MenuGenerator::new($this->container)->generate($menuName);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -44,40 +44,20 @@ final class MenuGenerator extends UrlGenerator {
|
||||
protected RequestInterface $request;
|
||||
|
||||
/**
|
||||
* MenuGenerator constructor.
|
||||
*
|
||||
* @param ContainerInterface $container
|
||||
* @throws ContainerException
|
||||
* @throws NotFoundException
|
||||
* @return static
|
||||
*/
|
||||
public function __construct(ContainerInterface $container)
|
||||
public static function new(ContainerInterface $container): self
|
||||
{
|
||||
parent::__construct($container);
|
||||
$this->helper = $container->get('html-helper');
|
||||
$this->request = $container->get('request');
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate the full menu structure from the config files
|
||||
*
|
||||
* @param array $menus
|
||||
* @return array
|
||||
*/
|
||||
protected function parseConfig(array $menus) : array
|
||||
{
|
||||
$parsed = [];
|
||||
|
||||
foreach ($menus as $name => $menu)
|
||||
try
|
||||
{
|
||||
$parsed[$name] = [];
|
||||
foreach ($menu['items'] as $pathName => $partialPath)
|
||||
{
|
||||
$title = (string)StringType::from($pathName)->humanize()->titleize();
|
||||
$parsed[$name][$title] = (string)StringType::from($menu['route_prefix'])->append($partialPath);
|
||||
}
|
||||
return new static($container);
|
||||
}
|
||||
catch (\Throwable $e)
|
||||
{
|
||||
dump($e);
|
||||
die();
|
||||
}
|
||||
|
||||
return $parsed;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -120,5 +100,42 @@ final class MenuGenerator extends UrlGenerator {
|
||||
// Create the menu html
|
||||
return (string) $this->helper->ul();
|
||||
}
|
||||
|
||||
/**
|
||||
* MenuGenerator constructor.
|
||||
*
|
||||
* @param ContainerInterface $container
|
||||
* @throws ContainerException
|
||||
* @throws NotFoundException
|
||||
*/
|
||||
private function __construct(ContainerInterface $container)
|
||||
{
|
||||
parent::__construct($container);
|
||||
$this->helper = $container->get('html-helper');
|
||||
$this->request = $container->get('request');
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate the full menu structure from the config files
|
||||
*
|
||||
* @param array $menus
|
||||
* @return array
|
||||
*/
|
||||
private function parseConfig(array $menus) : array
|
||||
{
|
||||
$parsed = [];
|
||||
|
||||
foreach ($menus as $name => $menu)
|
||||
{
|
||||
$parsed[$name] = [];
|
||||
foreach ($menu['items'] as $pathName => $partialPath)
|
||||
{
|
||||
$title = (string)StringType::from($pathName)->humanize()->titleize();
|
||||
$parsed[$name][$title] = (string)StringType::from($menu['route_prefix'])->append($partialPath);
|
||||
}
|
||||
}
|
||||
|
||||
return $parsed;
|
||||
}
|
||||
}
|
||||
// End of MenuGenerator.php
|
@ -16,7 +16,6 @@
|
||||
|
||||
namespace Aviat\Ion\View;
|
||||
|
||||
use Aura\Html\HelperLocator;
|
||||
use Aviat\Ion\Di\ContainerAware;
|
||||
use Aviat\Ion\Di\ContainerInterface;
|
||||
use Aviat\Ion\Di\Exception\ContainerException;
|
||||
@ -30,13 +29,6 @@ use const EXTR_OVERWRITE;
|
||||
class HtmlView extends HttpView {
|
||||
use ContainerAware;
|
||||
|
||||
/**
|
||||
* HTML generator/escaper helper
|
||||
*
|
||||
* @var HelperLocator
|
||||
*/
|
||||
protected HelperLocator $helper;
|
||||
|
||||
/**
|
||||
* Response mime type
|
||||
*
|
||||
@ -56,7 +48,6 @@ class HtmlView extends HttpView {
|
||||
parent::__construct();
|
||||
|
||||
$this->setContainer($container);
|
||||
$this->helper = $container->get('html-helper');
|
||||
$this->response = new HtmlResponse('');
|
||||
}
|
||||
|
||||
@ -69,8 +60,10 @@ class HtmlView extends HttpView {
|
||||
*/
|
||||
public function renderTemplate(string $path, array $data): string
|
||||
{
|
||||
$data['helper'] = $this->helper;
|
||||
$data['escape'] = $this->helper->escape();
|
||||
$helper = $this->container->get('html-helper');
|
||||
$data['component'] = $this->container->get('component-helper');
|
||||
$data['helper'] = $helper;
|
||||
$data['escape'] = $helper->escape();
|
||||
$data['container'] = $this->container;
|
||||
|
||||
ob_start();
|
||||
|
Loading…
Reference in New Issue
Block a user