Version 5.1 - All the GraphQL #32

Closed
timw4mail wants to merge 1160 commits from develop into master
22 changed files with 347 additions and 451 deletions
Showing only changes of commit 67819156ed - Show all commits

View File

@ -14,6 +14,7 @@
* @link https://github.com/timw4mail/HummingBirdAnimeClient * @link https://github.com/timw4mail/HummingBirdAnimeClient
*/ */
use function Aviat\AnimeClient\loadToml;
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// Lower level configuration // Lower level configuration
@ -23,7 +24,9 @@
$APP_DIR = realpath(__DIR__ . '/../'); $APP_DIR = realpath(__DIR__ . '/../');
$ROOT_DIR = realpath("{$APP_DIR}/../"); $ROOT_DIR = realpath("{$APP_DIR}/../");
$base_config = [ $tomlConfig = loadToml(__DIR__);
$base_config = array_merge($tomlConfig, [
'asset_dir' => "{$ROOT_DIR}/public", 'asset_dir' => "{$ROOT_DIR}/public",
// Template file path // Template file path
@ -34,6 +37,5 @@ $base_config = [
'img_cache_path' => "{$ROOT_DIR}/public/images", 'img_cache_path' => "{$ROOT_DIR}/public/images",
// Included config files // Included config files
'menus' => require 'menus.php',
'routes' => require 'routes.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,211 +22,189 @@ use const Aviat\AnimeClient\{
use Aviat\AnimeClient\AnimeClient; use Aviat\AnimeClient\AnimeClient;
// -------------------------------------------------------------------------
// Routing Config
//
// Maps paths to controlers and methods
// -------------------------------------------------------------------------
return [ return [
// ------------------------------------------------------------------------- // ---------------------------------------------------------------------
// Routing options // Anime List Routes
// // ---------------------------------------------------------------------
// Specify default paths and views 'anime.add.get' => [
// ------------------------------------------------------------------------- 'path' => '/anime/add',
'route_config' => [ 'action' => 'addForm',
// Path to public directory, where images/css/javascript are located, 'verb' => 'get',
// 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',
], ],
// ------------------------------------------------------------------------- 'anime.add.post' => [
// Routing Config 'path' => '/anime/add',
// 'action' => 'add',
// Maps paths to controlers and methods 'verb' => 'post',
// ------------------------------------------------------------------------- ],
'routes' => [ 'anime.details' => [
// --------------------------------------------------------------------- 'path' => '/anime/details/{id}',
// Anime List Routes 'action' => 'details',
// --------------------------------------------------------------------- 'tokens' => [
'anime.add.get' => [ 'id' => '[a-z0-9\-]+',
'path' => '/anime/add',
'action' => 'addForm',
'verb' => 'get',
], ],
'anime.add.post' => [ ],
'path' => '/anime/add', 'anime.delete' => [
'action' => 'add', 'path' => '/anime/delete',
'verb' => 'post', 'action' => 'delete',
'verb' => 'post',
],
// ---------------------------------------------------------------------
// Manga Routes
// ---------------------------------------------------------------------
'manga.search' => [
'path' => '/manga/search',
'action' => 'search',
],
'manga.add.get' => [
'path' => '/manga/add',
'action' => 'addForm',
'verb' => 'get',
],
'manga.add.post' => [
'path' => '/manga/add',
'action' => 'add',
'verb' => 'post',
],
'manga.delete' => [
'path' => '/manga/delete',
'action' => 'delete',
'verb' => 'post',
],
'manga.details' => [
'path' => '/manga/details/{id}',
'action' => 'details',
'tokens' => [
'id' => '[a-z0-9\-]+',
], ],
'anime.details' => [ ],
'path' => '/anime/details/{id}', // ---------------------------------------------------------------------
'action' => 'details', // Anime Collection Routes
'tokens' => [ // ---------------------------------------------------------------------
'id' => '[a-z0-9\-]+', 'collection.search' => [
], 'path' => '/collection/search',
'action' => 'search',
],
'collection.add.get' => [
'path' => '/collection/add',
'action' => 'form',
'params' => [],
],
'collection.edit.get' => [
'path' => '/collection/edit/{id}',
'action' => 'form',
'tokens' => [
'id' => '[0-9]+',
], ],
'anime.delete' => [ ],
'path' => '/anime/delete', 'collection.add.post' => [
'action' => 'delete', 'path' => '/collection/add',
'verb' => 'post', 'action' => 'add',
'verb' => 'post',
],
'collection.edit.post' => [
'path' => '/collection/edit',
'action' => 'edit',
'verb' => 'post',
],
'collection.view' => [
'path' => '/collection/view{/view}',
'action' => 'index',
'params' => [],
'tokens' => [
'view' => '[a-z_]+',
], ],
// --------------------------------------------------------------------- ],
// Manga Routes 'collection.delete' => [
// --------------------------------------------------------------------- 'path' => '/collection/delete',
'manga.search' => [ 'action' => 'delete',
'path' => '/manga/search', 'verb' => 'post',
'action' => 'search', ],
// ---------------------------------------------------------------------
// Manga Collection Routes
// ---------------------------------------------------------------------
// ---------------------------------------------------------------------
// Other Routes
// ---------------------------------------------------------------------
'character' => [
'path' => '/character/{slug}',
'action' => 'index',
'params' => [],
'tokens' => [
'slug' => '[a-z0-9\-]+'
]
],
'user_info' => [
'path' => '/me',
'action' => 'me',
'controller' => 'me',
'verb' => 'get',
],
// ---------------------------------------------------------------------
// Default / Shared routes
// ---------------------------------------------------------------------
'cache_purge' => [
'path' => '/cache_purge',
'action' => 'clearCache',
'controller' => DEFAULT_CONTROLLER_NAMESPACE,
'verb' => 'get',
],
'login' => [
'path' => '/login',
'action' => 'login',
'controller' => DEFAULT_CONTROLLER_NAMESPACE,
'verb' => 'get',
],
'login.post' => [
'path' => '/login',
'action' => 'loginAction',
'controller' => DEFAULT_CONTROLLER_NAMESPACE,
'verb' => 'post',
],
'logout' => [
'path' => '/logout',
'action' => 'logout',
'controller' => DEFAULT_CONTROLLER_NAMESPACE,
],
'update' => [
'path' => '/{controller}/update',
'action' => 'update',
'verb' => 'post',
'tokens' => [
'controller' => '[a-z_]+',
], ],
'manga.add.get' => [ ],
'path' => '/manga/add', 'update.post' => [
'action' => 'addForm', 'path' => '/{controller}/update_form',
'verb' => 'get', 'action' => 'formUpdate',
'verb' => 'post',
'tokens' => [
'controller' => '[a-z_]+',
], ],
'manga.add.post' => [ ],
'path' => '/manga/add', 'edit' => [
'action' => 'add', 'path' => '/{controller}/edit/{id}/{status}',
'verb' => 'post', 'action' => 'edit',
'tokens' => [
'id' => '[0-9a-z_]+',
'status' => '([a-zA-Z\-_]|%20)+',
], ],
'manga.delete' => [ ],
'path' => '/manga/delete', 'list' => [
'action' => 'delete', 'path' => '/{controller}/{type}{/view}',
'verb' => 'post', 'action' => DEFAULT_CONTROLLER_METHOD,
], 'tokens' => [
'manga.details' => [ 'type' => '[a-z_]+',
'path' => '/manga/details/{id}', 'view' => '[a-z_]+',
'action' => 'details',
'tokens' => [
'id' => '[a-z0-9\-]+',
],
],
// ---------------------------------------------------------------------
// Anime Collection Routes
// ---------------------------------------------------------------------
'collection.search' => [
'path' => '/collection/search',
'action' => 'search',
],
'collection.add.get' => [
'path' => '/collection/add',
'action' => 'form',
'params' => [],
],
'collection.edit.get' => [
'path' => '/collection/edit/{id}',
'action' => 'form',
'tokens' => [
'id' => '[0-9]+',
],
],
'collection.add.post' => [
'path' => '/collection/add',
'action' => 'add',
'verb' => 'post',
],
'collection.edit.post' => [
'path' => '/collection/edit',
'action' => 'edit',
'verb' => 'post',
],
'collection.view' => [
'path' => '/collection/view{/view}',
'action' => 'index',
'params' => [],
'tokens' => [
'view' => '[a-z_]+',
],
],
'collection.delete' => [
'path' => '/collection/delete',
'action' => 'delete',
'verb' => 'post',
],
// ---------------------------------------------------------------------
// Manga Collection Routes
// ---------------------------------------------------------------------
// ---------------------------------------------------------------------
// Other Routes
// ---------------------------------------------------------------------
'character' => [
'path' => '/character/{slug}',
'action' => 'index',
'params' => [],
'tokens' => [
'slug' => '[a-z0-9\-]+'
]
],
'user_info' => [
'path' => '/me',
'action' => 'me',
'controller' => 'me',
'verb' => 'get',
],
// ---------------------------------------------------------------------
// Default / Shared routes
// ---------------------------------------------------------------------
'cache_purge' => [
'path' => '/cache_purge',
'action' => 'clearCache',
'controller' => DEFAULT_CONTROLLER_NAMESPACE,
'verb' => 'get',
],
'login' => [
'path' => '/login',
'action' => 'login',
'controller' => DEFAULT_CONTROLLER_NAMESPACE,
'verb' => 'get',
],
'login.post' => [
'path' => '/login',
'action' => 'loginAction',
'controller' => DEFAULT_CONTROLLER_NAMESPACE,
'verb' => 'post',
],
'logout' => [
'path' => '/logout',
'action' => 'logout',
'controller' => DEFAULT_CONTROLLER_NAMESPACE,
],
'update' => [
'path' => '/{controller}/update',
'action' => 'update',
'verb' => 'post',
'tokens' => [
'controller' => '[a-z_]+',
],
],
'update.post' => [
'path' => '/{controller}/update_form',
'action' => 'formUpdate',
'verb' => 'post',
'tokens' => [
'controller' => '[a-z_]+',
],
],
'edit' => [
'path' => '/{controller}/edit/{id}/{status}',
'action' => 'edit',
'tokens' => [
'id' => '[0-9a-z_]+',
'status' => '([a-zA-Z\-_]|%20)+',
],
],
'list' => [
'path' => '/{controller}/{type}{/view}',
'action' => DEFAULT_CONTROLLER_METHOD,
'tokens' => [
'type' => '[a-z_]+',
'view' => '[a-z_]+',
],
],
'index_redirect' => [
'path' => '/',
'controller' => DEFAULT_CONTROLLER_NAMESPACE,
'action' => 'redirectToDefaultRoute',
], ],
], ],
'index_redirect' => [
'path' => '/',
'controller' => DEFAULT_CONTROLLER_NAMESPACE,
'action' => 'redirectToDefaultRoute',
],
]; ];

View File

@ -30,7 +30,11 @@
<tr id="a-<?= $item['id'] ?>"> <tr id="a-<?= $item['id'] ?>">
<?php if ($auth->isAuthenticated()): ?> <?php if ($auth->isAuthenticated()): ?>
<td> <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> </td>
<?php endif ?> <?php endif ?>
<td class="justify"> <td class="justify">

View File

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

View File

@ -1,6 +1,6 @@
<main> <main>
<?php if ($auth->isAuthenticated()): ?> <?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 endif ?>
<?php if (empty($sections)): ?> <?php if (empty($sections)): ?>
<h3>There's nothing here!</h3> <h3>There's nothing here!</h3>
@ -26,12 +26,11 @@
<tr> <tr>
<?php if($auth->isAuthenticated()): ?> <?php if($auth->isAuthenticated()): ?>
<td> <td>
<a class="bracketed" href="<?= $urlGenerator->fullUrl("collection/edit/{$item['hummingbird_id']}") ?>">Edit</a> <a class="bracketed" href="<?= $url->generate('collection.edit.get', ['id' => $item['hummingbird_id']]) ?>">Edit</a>
<?php /*<a class="bracketed" href="<?= $urlGenerator->fullUrl("collection/delete/{$item['hummingbird_id']}") ?>">Delete</a>*/ ?>
</td> </td>
<?php endif ?> <?php endif ?>
<td class="align_left"> <td class="align_left">
<a href="https://hummingbird.me/anime/<?= $item['slug'] ?>"> <a href="<?= $url->generate('anime.details', ['id' => $item['slug']]) ?>">
<?= $item['title'] ?> <?= $item['title'] ?>
</a> </a>
<?= ( ! empty($item['alternate_title'])) ? " <br /><small> " . $item['alternate_title'] . "</small>" : "" ?> <?= ( ! 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 <?= $config->get('whose_list') ?>'s <?= ucfirst($url_type) ?> List
</a> </a>
<?php if($config->get("show_{$url_type}_collection")): ?> <?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 ?> <?php endif ?>
[<a href="<?= $urlGenerator->defaultUrl($other_type) ?>"><?= ucfirst($other_type) ?> List</a>] [<a href="<?= $urlGenerator->defaultUrl($other_type) ?>"><?= ucfirst($other_type) ?> List</a>]
<?php else: ?> <?php else: ?>
<a href="<?= $urlGenerator->url('collection/view') ?>"> <a href="<?= $url->generate('collection.view') ?>">
<?= $config->get('whose_list') ?>'s <?= ucfirst($url_type) ?> Collection <?= $config->get('whose_list') ?>'s <?= ucfirst($url_type) ?> Collection
</a> </a>
[<a href="<?= $urlGenerator->defaultUrl('anime') ?>">Anime List</a>] [<a href="<?= $urlGenerator->defaultUrl('anime') ?>">Anime List</a>]

View File

@ -1,6 +1,6 @@
<main> <main>
<?php if ($auth->isAuthenticated()): ?> <?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 endif ?>
<?php if (empty($sections)): ?> <?php if (empty($sections)): ?>
<h3>There's nothing here!</h3> <h3>There's nothing here!</h3>
@ -14,6 +14,7 @@
<?php if ($auth->isAuthenticated()): ?> <?php if ($auth->isAuthenticated()): ?>
<div class="edit_buttons" hidden> <div class="edit_buttons" hidden>
<button class="plus_one_chapter">+1 Chapter</button> <button class="plus_one_chapter">+1 Chapter</button>
<?php /* <button class="plus_one_volume">+1 Volume</button> */ ?>
</div> </div>
<?php endif ?> <?php endif ?>
<img src="<?= $escape->attr($item['manga']['image']) ?>" /> <img src="<?= $escape->attr($item['manga']['image']) ?>" />
@ -29,7 +30,15 @@
<?php if ($auth->isAuthenticated()): ?> <?php if ($auth->isAuthenticated()): ?>
<div class="row"> <div class="row">
<span class="edit"> <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> </span>
</div> </div>
<?php endif ?> <?php endif ?>

View File

@ -1,6 +1,6 @@
<main> <main>
<?php if ($auth->isAuthenticated()): ?> <?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 endif ?>
<?php if (empty($sections)): ?> <?php if (empty($sections)): ?>
<h3>There's nothing here!</h3> <h3>There's nothing here!</h3>
@ -27,7 +27,11 @@
<tr id="manga-<?= $item['id'] ?>"> <tr id="manga-<?= $item['id'] ?>">
<?php if($auth->isAuthenticated()): ?> <?php if($auth->isAuthenticated()): ?>
<td> <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> </td>
<?php endif ?> <?php endif ?>
<td class="align_left"> <td class="align_left">

View File

@ -55,6 +55,7 @@ class Controller {
'config' => $this->config 'config' => $this->config
]); ]);
$this->url = $auraUrlGenerator;
$this->urlGenerator = $urlGenerator; $this->urlGenerator = $urlGenerator;
$session = $container->get('session'); $session = $container->get('session');
@ -133,7 +134,7 @@ class Controller {
} }
$this->setFlashMessage('Invalid username or password.'); $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", $this->config->get('whose_list') . "'s Anime List",
'Add' 'Add'
), ),
'action_url' => $this->urlGenerator->url('anime/add'), 'action_url' => $this->url->generate('anime.add.post'),
'status_list' => AnimeWatchingStatus::KITSU_TO_TITLE 'status_list' => AnimeWatchingStatus::KITSU_TO_TITLE
]); ]);
} }
@ -168,8 +168,9 @@ class Anime extends BaseController {
), ),
'item' => $item, 'item' => $item,
'statuses' => AnimeWatchingStatus::KITSU_TO_TITLE, 'statuses' => AnimeWatchingStatus::KITSU_TO_TITLE,
'action' => $this->container->get('url-generator') 'action' => $this->url->generate('update.post', [
->url('/anime/update_form'), 'controller' => 'anime'
]),
]); ]);
} }

View File

@ -41,18 +41,6 @@ class Collection extends BaseController {
*/ */
private $animeModel; 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 * Constructor
* *
@ -62,7 +50,6 @@ class Collection extends BaseController {
{ {
parent::__construct($container); parent::__construct($container);
$this->urlGenerator = $container->get('url-generator');
$this->animeModel = $container->get('anime-model'); $this->animeModel = $container->get('anime-model');
$this->animeCollectionModel = $container->get('anime-collection-model'); $this->animeCollectionModel = $container->get('anime-collection-model');
$this->baseData = array_merge($this->baseData, [ $this->baseData = array_merge($this->baseData, [
@ -118,10 +105,11 @@ class Collection extends BaseController {
$this->setSessionRedirect(); $this->setSessionRedirect();
$action = (is_null($id)) ? "Add" : "Edit"; $action = (is_null($id)) ? "Add" : "Edit";
$urlAction = strtolower($action);
$this->outputHTML('collection/' . strtolower($action), [ $this->outputHTML('collection/' . $urlAction, [
'action' => $action, 'action' => $action,
'action_url' => $this->urlGenerator->fullUrl('collection/' . strtolower($action)), 'action_url' => $this->url->generate("collection.{$urlAction}.post"),
'title' => $this->formatTitle( 'title' => $this->formatTitle(
$this->config->get('whose_list') . "'s Anime Collection", $this->config->get('whose_list') . "'s Anime Collection",
$action $action

View File

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

View File

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

View File

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

View File

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

View File

@ -108,32 +108,5 @@ class UrlGenerator extends RoutingBase {
throw new InvalidArgumentException("Invalid default type: '{$type}'"); 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 // End of UrlGenerator.php

View File

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

View File

@ -72,39 +72,37 @@ class DispatcherTest extends AnimeClientTestCase {
{ {
$defaultConfig = [ $defaultConfig = [
'routes' => [ 'routes' => [
'routes' => [ 'login_form' => [
'login_form' => [ 'path' => '/login',
'path' => '/login', 'action' => 'login',
'action' => 'login', 'verb' => 'get'
'verb' => 'get' ],
], 'watching' => [
'watching' => [ 'path' => '/anime/watching{/view}',
'path' => '/anime/watching{/view}', 'action' => 'anime_list',
'action' => 'anime_list', 'params' => [
'params' => [ 'type' => 'currently-watching',
'type' => 'currently-watching', ],
], 'tokens' => [
'tokens' => [ 'view' => '[a-z_]+'
'view' => '[a-z_]+' ]
] ],
], 'plan_to_read' => [
'plan_to_read' => [ 'path' => '/manga/plan_to_read{/view}',
'path' => '/manga/plan_to_read{/view}', 'action' => 'manga_list',
'action' => 'manga_list', 'params' => [
'params' => [ 'type' => 'Plan to Read',
'type' => 'Plan to Read', ],
], 'tokens' => [
'tokens' => [ 'view' => '[a-z_]+'
'view' => '[a-z_]+' ]
]
],
], ],
'route_config' => [
'anime_path' => 'anime',
'manga_path' => 'manga',
'default_list' => 'anime'
]
], ],
'route_config' => [
'anime_path' => 'anime',
'manga_path' => 'manga',
'default_list' => 'anime'
]
]; ];
$data = [ $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_anime']['config']['route_config']['default_list'] = 'manga';
$data['manga_default_routing_manga']['config']['routes']['route_config']['default_list'] = 'manga'; $data['manga_default_routing_manga']['config']['route_config']['default_list'] = 'manga';
return $data; return $data;
} }
@ -169,36 +167,34 @@ class DispatcherTest extends AnimeClientTestCase {
public function testDefaultRoute() public function testDefaultRoute()
{ {
$config = [ $config = [
'route_config' => [
'anime_path' => 'anime',
'manga_path' => 'manga',
'default_anime_list_path' => "watching",
'default_manga_list_path' => 'all',
'default_list' => 'manga'
],
'routes' => [ 'routes' => [
'route_config' => [ 'login_form' => [
'anime_path' => 'anime', 'path' => '/login',
'manga_path' => 'manga', 'action' => ['login'],
'default_anime_list_path' => "watching", 'verb' => 'get'
'default_manga_list_path' => 'all',
'default_list' => 'manga'
], ],
'routes' => [ 'index' => [
'login_form' => [ 'path' => '/',
'path' => '/login', 'action' => ['redirect'],
'action' => ['login'], 'params' => [
'verb' => 'get' 'url' => '', // Determined by config
], 'code' => '301'
'index' => [ ]
'path' => '/', ],
'action' => ['redirect'], 'index' => [
'params' => [ 'path' => '/',
'url' => '', // Determined by config 'action' => ['redirect'],
'code' => '301' 'params' => [
] 'url' => '', // Determined by config
], 'code' => '301',
'index' => [ 'type' => 'manga'
'path' => '/',
'action' => ['redirect'],
'params' => [
'url' => '', // Determined by config
'code' => '301',
'type' => 'manga'
]
] ]
] ]
] ]
@ -218,17 +214,15 @@ class DispatcherTest extends AnimeClientTestCase {
'controller_list_sanity_check' => [ 'controller_list_sanity_check' => [
'config' => [ 'config' => [
'routes' => [ 'routes' => [
'routes' => [
], ],
'route_config' => [ 'route_config' => [
'anime_path' => 'anime', 'anime_path' => 'anime',
'manga_path' => 'manga', 'manga_path' => 'manga',
'default_anime_list_path' => "watching", 'default_anime_list_path' => "watching",
'default_manga_list_path' => 'all', 'default_manga_list_path' => 'all',
'default_list' => 'manga' 'default_list' => 'manga'
], ],
]
], ],
'expected' => [ 'expected' => [
'anime' => 'Aviat\AnimeClient\Controller\Anime', 'anime' => 'Aviat\AnimeClient\Controller\Anime',
@ -240,17 +234,15 @@ class DispatcherTest extends AnimeClientTestCase {
'empty_controller_list' => [ 'empty_controller_list' => [
'config' => [ 'config' => [
'routes' => [ 'routes' => [
'routes' => [
], ],
'route_config' => [ 'route_config' => [
'anime_path' => 'anime', 'anime_path' => 'anime',
'manga_path' => 'manga', 'manga_path' => 'manga',
'default_anime_path' => "/anime/watching", 'default_anime_path' => "/anime/watching",
'default_manga_path' => '/manga/all', 'default_manga_path' => '/manga/all',
'default_list' => 'manga' 'default_list' => 'manga'
], ],
]
], ],
'expected' => [ 'expected' => [
'anime' => 'Aviat\AnimeClient\Controller\Anime', 'anime' => 'Aviat\AnimeClient\Controller\Anime',

View File

@ -49,60 +49,4 @@ class UrlGeneratorTest extends AnimeClientTestCase {
$result = $urlGenerator->assetUrl(...$args); $result = $urlGenerator->assetUrl(...$args);
$this->assertEquals($expected, $result); $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);
}
} }