Simplify routing code a bit

This commit is contained in:
Timothy Warren 2017-03-30 16:16:40 -04:00
parent 2d33663318
commit fb567e85e9
22 changed files with 347 additions and 451 deletions

View File

@ -14,6 +14,7 @@
* @link https://github.com/timw4mail/HummingBirdAnimeClient
*/
use function Aviat\AnimeClient\loadToml;
// ----------------------------------------------------------------------------
// Lower level configuration
@ -23,7 +24,9 @@
$APP_DIR = realpath(__DIR__ . '/../');
$ROOT_DIR = realpath("{$APP_DIR}/../");
$base_config = [
$tomlConfig = loadToml(__DIR__);
$base_config = array_merge($tomlConfig, [
'asset_dir' => "{$ROOT_DIR}/public",
// Template file path
@ -34,6 +37,5 @@ $base_config = [
'img_cache_path' => "{$ROOT_DIR}/public/images",
// Included config files
'menus' => require 'menus.php',
'routes' => require 'routes.php',
];
]);

View File

@ -1,41 +0,0 @@
<?php declare(strict_types=1);
/**
* Hummingbird Anime List Client
*
* An API client for Kitsu and MyAnimeList to manage anime and manga watch lists
*
* PHP version 7
*
* @package HummingbirdAnimeClient
* @author Timothy J. Warren <tim@timshomepage.net>
* @copyright 2015 - 2017 Timothy J. Warren
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version 4.0
* @link https://github.com/timw4mail/HummingBirdAnimeClient
*/
return [
'anime_list' => [
'route_prefix' => '/anime',
'items' => [
'watching' => '/watching',
'plan_to_watch' => '/plan_to_watch',
'on_hold' => '/on_hold',
'dropped' => '/dropped',
'completed' => '/completed',
'all' => '/all'
]
],
'manga_list' => [
'route_prefix' => '/manga',
'items' => [
'reading' => '/reading',
'plan_to_read' => '/plan_to_read',
'on_hold' => '/on_hold',
'dropped' => '/dropped',
'completed' => '/completed',
'all' => '/all'
]
]
];

19
app/appConf/menus.toml Normal file
View File

@ -0,0 +1,19 @@
[anime_list]
route_prefix = "/anime"
[anime_list.items]
watching = '/watching'
plan_to_watch = '/plan_to_watch'
on_hold = '/on_hold'
dropped = '/dropped'
completed = '/completed'
all = '/all'
[manga_list]
route_prefix = "/manga"
[manga_list.items]
reading = '/reading'
plan_to_read = '/plan_to_read'
on_hold = '/on_hold'
dropped = '/dropped'
completed = '/completed'
all = '/all'

View File

@ -0,0 +1,19 @@
################################################################################
# Route config
#
# Default views and paths
################################################################################
# Path to public directory, where images/css/javascript are located,
# appended to the url
asset_path = "/public"
# Which list should be the default?
default_lis = "anime" # anime or manga
# Default pages for anime/manga
default_anime_list_path = "watching" # watching|plan_to_watch|on_hold|dropped|completed|all
default_manga_list_path = "reading" # reading|plan_to_read|on_hold|dropped|completed|all
# Default view type (cover_view/list_view)
default_view_type = "cover_view"

View File

@ -22,33 +22,12 @@ use const Aviat\AnimeClient\{
use Aviat\AnimeClient\AnimeClient;
// -------------------------------------------------------------------------
// Routing Config
//
// Maps paths to controlers and methods
// -------------------------------------------------------------------------
return [
// -------------------------------------------------------------------------
// Routing options
//
// Specify default paths and views
// -------------------------------------------------------------------------
'route_config' => [
// Path to public directory, where images/css/javascript are located,
// appended to the url
'asset_path' => '/public',
// Which list should be the default?
'default_list' => 'anime', // anime or manga
// Default pages for anime/manga
'default_anime_list_path' => "watching", // watching|plan_to_watch|on_hold|dropped|completed|all
'default_manga_list_path' => "reading", // reading|plan_to_read|on_hold|dropped|completed|all
// Default view type (cover_view/list_view)
'default_view_type' => 'cover_view',
],
// -------------------------------------------------------------------------
// Routing Config
//
// Maps paths to controlers and methods
// -------------------------------------------------------------------------
'routes' => [
// ---------------------------------------------------------------------
// Anime List Routes
// ---------------------------------------------------------------------
@ -228,5 +207,4 @@ return [
'controller' => DEFAULT_CONTROLLER_NAMESPACE,
'action' => 'redirectToDefaultRoute',
],
],
];

View File

@ -30,7 +30,11 @@
<tr id="a-<?= $item['id'] ?>">
<?php if ($auth->isAuthenticated()): ?>
<td>
<a class="bracketed" href="<?= $urlGenerator->url("/anime/edit/{$item['id']}/{$item['watching_status']}") ?>">Edit</a>
<a class="bracketed" href="<?= $url->generate('edit', [
'controller' => 'anime',
'id' => $item['id'],
'status' => $item['watching_status']
]) ?>">Edit</a>
</td>
<?php endif ?>
<td class="justify">

View File

@ -21,8 +21,11 @@
<div class="table">
<?php if ($auth->isAuthenticated()): ?>
<div class="row">
<span class="edit"><a class="bracketed" href="<?= $urlGenerator->url("collection/edit/{$item['hummingbird_id']}") ?>">Edit</a></span>
<?php /*<span class="delete"><a class="bracketed" href="<?= $urlGenerator->url("collection/delete/{$item['hummingbird_id']}") ?>">Delete</a></span> */ ?>
<span class="edit">
<a class="bracketed" href="<?= $url->generate('collection.edit.get', [
'id' => $item['hummingbird_id']
]) ?>">Edit</a>
</span>
</div>
<?php endif ?>
<div class="row">

View File

@ -1,6 +1,6 @@
<main>
<?php if ($auth->isAuthenticated()): ?>
<a class="bracketed" href="<?= $urlGenerator->fullUrl('collection/add', 'anime') ?>">Add Item</a>
<a class="bracketed" href="<?= $url->generate('collection.add.get') ?>">Add Item</a>
<?php endif ?>
<?php if (empty($sections)): ?>
<h3>There's nothing here!</h3>
@ -26,12 +26,11 @@
<tr>
<?php if($auth->isAuthenticated()): ?>
<td>
<a class="bracketed" href="<?= $urlGenerator->fullUrl("collection/edit/{$item['hummingbird_id']}") ?>">Edit</a>
<?php /*<a class="bracketed" href="<?= $urlGenerator->fullUrl("collection/delete/{$item['hummingbird_id']}") ?>">Delete</a>*/ ?>
<a class="bracketed" href="<?= $url->generate('collection.edit.get', ['id' => $item['hummingbird_id']]) ?>">Edit</a>
</td>
<?php endif ?>
<td class="align_left">
<a href="https://hummingbird.me/anime/<?= $item['slug'] ?>">
<a href="<?= $url->generate('anime.details', ['id' => $item['slug']]) ?>">
<?= $item['title'] ?>
</a>
<?= ( ! empty($item['alternate_title'])) ? " <br /><small> " . $item['alternate_title'] . "</small>" : "" ?>

View File

@ -6,11 +6,11 @@
<?= $config->get('whose_list') ?>'s <?= ucfirst($url_type) ?> List
</a>
<?php if($config->get("show_{$url_type}_collection")): ?>
[<a href="<?= $urlGenerator->url('collection/view') ?>"><?= ucfirst($url_type) ?> Collection</a>]
[<a href="<?= $url->generate('collection.view') ?>"><?= ucfirst($url_type) ?> Collection</a>]
<?php endif ?>
[<a href="<?= $urlGenerator->defaultUrl($other_type) ?>"><?= ucfirst($other_type) ?> List</a>]
<?php else: ?>
<a href="<?= $urlGenerator->url('collection/view') ?>">
<a href="<?= $url->generate('collection.view') ?>">
<?= $config->get('whose_list') ?>'s <?= ucfirst($url_type) ?> Collection
</a>
[<a href="<?= $urlGenerator->defaultUrl('anime') ?>">Anime List</a>]

View File

@ -1,6 +1,6 @@
<main>
<?php if ($auth->isAuthenticated()): ?>
<a class="bracketed" href="<?= $urlGenerator->url('manga/add') ?>">Add Item</a>
<a class="bracketed" href="<?= $url->generate('manga.add.get') ?>">Add Item</a>
<?php endif ?>
<?php if (empty($sections)): ?>
<h3>There's nothing here!</h3>
@ -14,6 +14,7 @@
<?php if ($auth->isAuthenticated()): ?>
<div class="edit_buttons" hidden>
<button class="plus_one_chapter">+1 Chapter</button>
<?php /* <button class="plus_one_volume">+1 Volume</button> */ ?>
</div>
<?php endif ?>
<img src="<?= $escape->attr($item['manga']['image']) ?>" />
@ -29,7 +30,15 @@
<?php if ($auth->isAuthenticated()): ?>
<div class="row">
<span class="edit">
<a class="bracketed" title="Edit information about this manga" href="<?= $urlGenerator->url("manga/edit/{$item['id']}/{$name}") ?>">Edit</a>
<a class="bracketed"
title="Edit information about this manga"
href="<?= $url->generate('edit', [
'controller' => 'manga',
'id' => $item['id'],
'status' => $name
]) ?>">
Edit
</a>
</span>
</div>
<?php endif ?>

View File

@ -1,6 +1,6 @@
<main>
<?php if ($auth->isAuthenticated()): ?>
<a class="bracketed" href="<?= $urlGenerator->url('manga/add') ?>">Add Item</a>
<a class="bracketed" href="<?= $url->generate('manga.add.get') ?>">Add Item</a>
<?php endif ?>
<?php if (empty($sections)): ?>
<h3>There's nothing here!</h3>
@ -27,7 +27,11 @@
<tr id="manga-<?= $item['id'] ?>">
<?php if($auth->isAuthenticated()): ?>
<td>
<a class="bracketed" href="<?= $urlGenerator->url("manga/edit/{$item['id']}/{$name}") ?>">Edit</a>
<a class="bracketed" href="<?= $url->generate('edit', [
'controller' => 'manga',
'id' => $item['id'],
'status' => $name
]) ?>">Edit</a>
</td>
<?php endif ?>
<td class="align_left">

View File

@ -55,6 +55,7 @@ class Controller {
'config' => $this->config
]);
$this->url = $auraUrlGenerator;
$this->urlGenerator = $urlGenerator;
$session = $container->get('session');
@ -133,7 +134,7 @@ class Controller {
}
$this->setFlashMessage('Invalid username or password.');
$this->redirect($this->urlGenerator->url('login'), 303);
$this->redirect($this->url->generate('login'), 303);
}
/**

View File

@ -116,7 +116,7 @@ class Anime extends BaseController {
$this->config->get('whose_list') . "'s Anime List",
'Add'
),
'action_url' => $this->urlGenerator->url('anime/add'),
'action_url' => $this->url->generate('anime.add.post'),
'status_list' => AnimeWatchingStatus::KITSU_TO_TITLE
]);
}
@ -168,8 +168,9 @@ class Anime extends BaseController {
),
'item' => $item,
'statuses' => AnimeWatchingStatus::KITSU_TO_TITLE,
'action' => $this->container->get('url-generator')
->url('/anime/update_form'),
'action' => $this->url->generate('update.post', [
'controller' => 'anime'
]),
]);
}

View File

@ -41,18 +41,6 @@ class Collection extends BaseController {
*/
private $animeModel;
/**
* Data to be sent to all routes in this controller
* @var array $baseData
*/
protected $baseData;
/**
* Url Generator class
* @var UrlGenerator
*/
protected $urlGenerator;
/**
* Constructor
*
@ -62,7 +50,6 @@ class Collection extends BaseController {
{
parent::__construct($container);
$this->urlGenerator = $container->get('url-generator');
$this->animeModel = $container->get('anime-model');
$this->animeCollectionModel = $container->get('anime-collection-model');
$this->baseData = array_merge($this->baseData, [
@ -118,10 +105,11 @@ class Collection extends BaseController {
$this->setSessionRedirect();
$action = (is_null($id)) ? "Add" : "Edit";
$urlAction = strtolower($action);
$this->outputHTML('collection/' . strtolower($action), [
$this->outputHTML('collection/' . $urlAction, [
'action' => $action,
'action_url' => $this->urlGenerator->fullUrl('collection/' . strtolower($action)),
'action_url' => $this->url->generate("collection.{$urlAction}.post"),
'title' => $this->formatTitle(
$this->config->get('whose_list') . "'s Anime Collection",
$action

View File

@ -106,7 +106,7 @@ class Manga extends Controller {
$this->config->get('whose_list') . "'s Manga List",
'Add'
),
'action_url' => $this->urlGenerator->url('manga/add'),
'action_url' => $this->url->generate('manga.add.post'),
'status_list' => $statuses
]);
}
@ -159,8 +159,9 @@ class Manga extends Controller {
'title' => $title,
'status_list' => MangaReadingStatus::KITSU_TO_TITLE,
'item' => $item,
'action' => $this->container->get('url-generator')
->url('/manga/update_form'),
'action' => $this->url->generate('update.post', [
'controller' => 'manga'
]),
]);
}

View File

@ -65,6 +65,12 @@ trait ControllerTrait {
*/
protected $urlGenerator;
/**
* Aura url generator
* @var \Aura\Router\Generator
*/
protected $url;
/**
* Session segment
* @var \Aura\Session\Segment

View File

@ -16,10 +16,7 @@
namespace Aviat\AnimeClient;
use Aviat\Ion\
{
ArrayWrapper, StringWrapper
};
use Aviat\Ion\{ArrayWrapper, StringWrapper};
use Aviat\Ion\Di\ContainerInterface;
/**

View File

@ -59,9 +59,8 @@ class RoutingBase {
{
$this->container = $container;
$this->config = $container->get('config');
$baseRoutes = $this->config->get('routes');
$this->routes = $baseRoutes['routes'];
$this->routeConfig = $baseRoutes['route_config'];
$this->routes = $this->config->get('routes');
$this->routeConfig = $this->config->get('route_config');
}
/**

View File

@ -108,32 +108,5 @@ class UrlGenerator extends RoutingBase {
throw new InvalidArgumentException("Invalid default type: '{$type}'");
}
/**
* Generate full url path from the route path based on config
*
* @param string $path - (optional) The route path
* @param string $type - (optional) The controller (anime or manga), defaults to anime
* @return string
*/
public function fullUrl(string $path = "", string $type = "anime"): string
{
$configDefaultRoute = $this->__get("default_{$type}_path");
// Remove beginning/trailing slashes
$path = trim($path, '/');
// Set the default view
if ($path === '')
{
$path .= trim($configDefaultRoute, '/');
if ($this->__get('default_to_list_view'))
{
$path .= '/list';
}
}
return $this->url($path);
}
}
// End of UrlGenerator.php

View File

@ -95,13 +95,11 @@ class AnimeClientTestCase extends TestCase {
'file' => ':memory:',
]
],
'routes' => [
'route_config' => [
'asset_path' => '/assets'
],
'routes' => [
]
],
'mal' => [
'username' => 'foo',

View File

@ -71,7 +71,6 @@ class DispatcherTest extends AnimeClientTestCase {
public function dataRoute()
{
$defaultConfig = [
'routes' => [
'routes' => [
'login_form' => [
'path' => '/login',
@ -104,7 +103,6 @@ class DispatcherTest extends AnimeClientTestCase {
'manga_path' => 'manga',
'default_list' => 'anime'
]
],
];
$data = [
@ -134,8 +132,8 @@ class DispatcherTest extends AnimeClientTestCase {
]
];
$data['manga_default_routing_anime']['config']['routes']['route_config']['default_list'] = 'manga';
$data['manga_default_routing_manga']['config']['routes']['route_config']['default_list'] = 'manga';
$data['manga_default_routing_anime']['config']['route_config']['default_list'] = 'manga';
$data['manga_default_routing_manga']['config']['route_config']['default_list'] = 'manga';
return $data;
}
@ -169,7 +167,6 @@ class DispatcherTest extends AnimeClientTestCase {
public function testDefaultRoute()
{
$config = [
'routes' => [
'route_config' => [
'anime_path' => 'anime',
'manga_path' => 'manga',
@ -201,7 +198,6 @@ class DispatcherTest extends AnimeClientTestCase {
]
]
]
]
];
$this->doSetUp($config, "/", "localhost");
@ -217,7 +213,6 @@ class DispatcherTest extends AnimeClientTestCase {
return [
'controller_list_sanity_check' => [
'config' => [
'routes' => [
'routes' => [
],
@ -228,7 +223,6 @@ class DispatcherTest extends AnimeClientTestCase {
'default_manga_list_path' => 'all',
'default_list' => 'manga'
],
]
],
'expected' => [
'anime' => 'Aviat\AnimeClient\Controller\Anime',
@ -239,7 +233,6 @@ class DispatcherTest extends AnimeClientTestCase {
],
'empty_controller_list' => [
'config' => [
'routes' => [
'routes' => [
],
@ -250,7 +243,6 @@ class DispatcherTest extends AnimeClientTestCase {
'default_manga_path' => '/manga/all',
'default_list' => 'manga'
],
]
],
'expected' => [
'anime' => 'Aviat\AnimeClient\Controller\Anime',

View File

@ -49,60 +49,4 @@ class UrlGeneratorTest extends AnimeClientTestCase {
$result = $urlGenerator->assetUrl(...$args);
$this->assertEquals($expected, $result);
}
public function dataFullUrl()
{
return [
'default_view' => [
'config' => [
'routes' => [
'routes' => [],
'route_config' => [
'anime_path' => 'anime',
'manga_path' => 'manga',
'default_list' => 'manga',
'default_anime_path' => '/anime/watching',
'default_manga_path' => '/manga/all',
'default_to_list_view' => FALSE,
]
],
],
'path' => '',
'type' => 'manga',
'expected' => '//localhost/manga/all',
],
'default_view_list' => [
'config' => [
'routes' => [
'routes' => [],
'route_config' => [
'anime_path' => 'anime',
'manga_path' => 'manga',
'default_list' => 'manga',
'default_anime_path' => '/anime/watching',
'default_manga_path' => '/manga/all',
'default_to_list_view' => TRUE,
]
],
],
'path' => '',
'type' => 'manga',
'expected' => '//localhost/manga/all/list',
]
];
}
/**
* @dataProvider dataFullUrl
*/
public function testFullUrl($config, $path, $type, $expected)
{
$config = new Config($config);
$this->container->setInstance('config', $config);
$urlGenerator = new UrlGenerator($this->container);
$result = $urlGenerator->fullUrl($path, $type);
$this->assertEquals($expected, $result);
}
}