Add list views and additional configuration options
This commit is contained in:
parent
aedfc743c6
commit
9afe5379aa
@ -1,4 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
|
/**
|
||||||
|
* Base API Model
|
||||||
|
*/
|
||||||
|
|
||||||
use \GuzzleHttp\Client;
|
use \GuzzleHttp\Client;
|
||||||
use \GuzzleHttp\Cookie\CookieJar;
|
use \GuzzleHttp\Cookie\CookieJar;
|
||||||
|
@ -1,4 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
|
/**
|
||||||
|
* Base Controller
|
||||||
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Base class for controllers, defines output methods
|
* Base class for controllers, defines output methods
|
||||||
@ -24,26 +27,30 @@ class BaseController {
|
|||||||
* Output a template to HTML, using the provided data
|
* Output a template to HTML, using the provided data
|
||||||
*
|
*
|
||||||
* @param string $template
|
* @param string $template
|
||||||
* @param array/object $data
|
* @param array|object $data
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function outputHTML($template, $data=[])
|
public function outputHTML($template, $data=[])
|
||||||
{
|
{
|
||||||
global $router;
|
global $router, $defaultHandler;
|
||||||
$route = $router->get_route();
|
$route = $router->get_route();
|
||||||
$data['route_path'] = ($route) ? $router->get_route()->path : "";
|
$data['route_path'] = ($route) ? $router->get_route()->path : "";
|
||||||
|
|
||||||
$path = _dir(APP_DIR, 'views', "{$template}.php");
|
$defaultHandler->addDataTable('Template Data', $data);
|
||||||
|
|
||||||
if ( ! is_file($path))
|
$template_path = _dir(APP_DIR, 'views', "{$template}.php");
|
||||||
|
|
||||||
|
if ( ! is_file($template_path))
|
||||||
{
|
{
|
||||||
throw new Exception("Invalid template : {$path}");
|
throw new Exception("Invalid template : {$path}");
|
||||||
|
die();
|
||||||
}
|
}
|
||||||
|
|
||||||
ob_start();
|
ob_start();
|
||||||
extract($data);
|
extract($data);
|
||||||
include _dir(APP_DIR, 'views', 'header.php');
|
include _dir(APP_DIR, 'views', 'header.php');
|
||||||
include $path;
|
include $template_path;
|
||||||
|
include _dir(APP_DIR, 'views', 'footer.php');
|
||||||
$buffer = ob_get_contents();
|
$buffer = ob_get_contents();
|
||||||
ob_end_clean();
|
ob_end_clean();
|
||||||
|
|
||||||
@ -55,7 +62,7 @@ class BaseController {
|
|||||||
/**
|
/**
|
||||||
* Output json with the proper content type
|
* Output json with the proper content type
|
||||||
*
|
*
|
||||||
* @param mixed data
|
* @param mixed $data
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function outputJSON($data)
|
public function outputJSON($data)
|
||||||
@ -68,5 +75,27 @@ class BaseController {
|
|||||||
header("Content-type: application/json");
|
header("Content-type: application/json");
|
||||||
echo $data;
|
echo $data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Redirect to the selected page
|
||||||
|
*
|
||||||
|
* @param string $url
|
||||||
|
* @param int $code
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function redirect($url, $code, $type="anime")
|
||||||
|
{
|
||||||
|
$url = full_url($url, $type);
|
||||||
|
|
||||||
|
$codes = [
|
||||||
|
301 => 'Moved Permanently',
|
||||||
|
302 => 'Found',
|
||||||
|
303 => 'See Other'
|
||||||
|
];
|
||||||
|
|
||||||
|
header("HTTP/1.1 {$code} {$codes[$code]}");
|
||||||
|
header("Location: {$url}");
|
||||||
|
die();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// End of BaseController.php
|
// End of BaseController.php
|
@ -1,4 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
|
/**
|
||||||
|
* Base DB model
|
||||||
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Base model for database interaction
|
* Base model for database interaction
|
||||||
|
@ -1,4 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
|
/**
|
||||||
|
* Base for base models
|
||||||
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Common base for all Models
|
* Common base for all Models
|
||||||
@ -35,6 +38,12 @@ class BaseModel {
|
|||||||
$path = current($path_parts);
|
$path = current($path_parts);
|
||||||
$ext_parts = explode('.', $path);
|
$ext_parts = explode('.', $path);
|
||||||
$ext = end($ext_parts);
|
$ext = end($ext_parts);
|
||||||
|
|
||||||
|
// Workaround for some broken extensions
|
||||||
|
if ($ext == "jjpg") $ext = "jpg";
|
||||||
|
|
||||||
|
// Failsafe for weird urls
|
||||||
|
if (strlen($ext) > 3) return $api_path;
|
||||||
|
|
||||||
$cached_image = "{$series_slug}.{$ext}";
|
$cached_image = "{$series_slug}.{$ext}";
|
||||||
$cached_path = "{$this->config->img_cache_path}/{$type}/{$cached_image}";
|
$cached_path = "{$this->config->img_cache_path}/{$type}/{$cached_image}";
|
||||||
|
@ -1,4 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
|
/**
|
||||||
|
* Routing logic
|
||||||
|
*/
|
||||||
|
|
||||||
use Aura\Router\RouterFactory;
|
use Aura\Router\RouterFactory;
|
||||||
|
|
||||||
@ -90,11 +93,23 @@ class Router {
|
|||||||
$controller_name = $route->params['controller'];
|
$controller_name = $route->params['controller'];
|
||||||
$action_method = $route->params['action'];
|
$action_method = $route->params['action'];
|
||||||
$params = (isset($route->params['params'])) ? $route->params['params'] : [];
|
$params = (isset($route->params['params'])) ? $route->params['params'] : [];
|
||||||
|
|
||||||
|
if ( ! empty($route->tokens))
|
||||||
|
{
|
||||||
|
foreach($route->tokens as $key => $v)
|
||||||
|
{
|
||||||
|
if (array_key_exists($key, $route->params))
|
||||||
|
{
|
||||||
|
$params[$key] = $route->params[$key];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$controller = new $controller_name();
|
$controller = new $controller_name();
|
||||||
|
|
||||||
// Run the appropriate controller method
|
// Run the appropriate controller method
|
||||||
|
$defaultHandler->addDataTable('controller_args', $params);
|
||||||
call_user_func_array([$controller, $action_method], $params);
|
call_user_func_array([$controller, $action_method], $params);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -123,7 +138,20 @@ class Router {
|
|||||||
{
|
{
|
||||||
$path = $route['path'];
|
$path = $route['path'];
|
||||||
unset($route['path']);
|
unset($route['path']);
|
||||||
$this->router->add($name, $path)->addValues($route);
|
|
||||||
|
if ( ! array_key_exists('tokens', $route))
|
||||||
|
{
|
||||||
|
$this->router->add($name, $path)->addValues($route);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$tokens = $route['tokens'];
|
||||||
|
unset($route['tokens']);
|
||||||
|
|
||||||
|
$this->router->add($name, $path)
|
||||||
|
->addValues($route)
|
||||||
|
->addTokens($tokens);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,25 +17,50 @@ function is_selected($a, $b)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generate full url path from the route path based on config
|
* Inverse of selected helper function
|
||||||
*
|
*
|
||||||
* @param string $path - The route path
|
* @param string $a - First item to compare
|
||||||
* @param [string] $host - The controller (anime or manga), defaults to anime
|
* @param string $b - Second item to compare
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
function full_url($path, $type="anime")
|
function is_not_selected($a, $b)
|
||||||
|
{
|
||||||
|
return ($a !== $b) ? 'selected' : '';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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
|
||||||
|
*/
|
||||||
|
function full_url($path="", $type="anime")
|
||||||
{
|
{
|
||||||
global $config;
|
global $config;
|
||||||
|
|
||||||
$config_path = $config->{"{$type}_path"};
|
$config_path = $config->{"{$type}_path"};
|
||||||
$config_host = $config->{"{$type}_host"};
|
$config_host = $config->{"{$type}_host"};
|
||||||
|
$config_default_route = $config->{"default_{$type}_path"};
|
||||||
|
|
||||||
// Remove beginning/trailing slashes
|
// Remove beginning/trailing slashes
|
||||||
$config_path = trim($config_path, '/');
|
$config_path = trim($config_path, '/');
|
||||||
$path = trim($path, '/');
|
$path = trim($path, '/');
|
||||||
|
|
||||||
|
// Remove any optional parameters from the route
|
||||||
|
$path = preg_replace('`{/.*?}`i', '', $path);
|
||||||
|
|
||||||
|
// Set the default view
|
||||||
|
if ($path === '')
|
||||||
|
{
|
||||||
|
$path .= trim($config_default_route, '/');
|
||||||
|
if ($config->default_to_list_view) $path .= '/list';
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the appropriate HTTP host
|
||||||
$host = ($config_host !== '') ? $config_host : $_SERVER['HTTP_HOST'];
|
$host = ($config_host !== '') ? $config_host : $_SERVER['HTTP_HOST'];
|
||||||
|
|
||||||
|
// Set an leading folder
|
||||||
if ($config_path !== '')
|
if ($config_path !== '')
|
||||||
{
|
{
|
||||||
$path = "{$config_path}/{$path}";
|
$path = "{$config_path}/{$path}";
|
||||||
@ -44,4 +69,16 @@ function full_url($path, $type="anime")
|
|||||||
return "//{$host}/{$path}";
|
return "//{$host}/{$path}";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the last segment of the current url
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
function last_segment()
|
||||||
|
{
|
||||||
|
$path = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);
|
||||||
|
$segments = explode('/', $path);
|
||||||
|
return end($segments);
|
||||||
|
}
|
||||||
|
|
||||||
// End of functions.php
|
// End of functions.php
|
@ -3,6 +3,10 @@ return (object)[
|
|||||||
// Username for feeds
|
// Username for feeds
|
||||||
'hummingbird_username' => 'timw4mail',
|
'hummingbird_username' => 'timw4mail',
|
||||||
|
|
||||||
|
// Included config files
|
||||||
|
'routes' => require _dir(CONF_DIR, 'routes.php'),
|
||||||
|
'database' => require _dir(CONF_DIR, 'database.php'),
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// Routing
|
// Routing
|
||||||
//
|
//
|
||||||
@ -15,11 +19,14 @@ return (object)[
|
|||||||
'anime_path' => '',
|
'anime_path' => '',
|
||||||
'manga_path' => '',
|
'manga_path' => '',
|
||||||
|
|
||||||
|
// Default pages for anime/manga
|
||||||
|
'default_anime_path' => '/watching',
|
||||||
|
'default_manga_path' => '/all',
|
||||||
|
|
||||||
|
// Default to list view?
|
||||||
|
'default_to_list_view' => FALSE,
|
||||||
|
|
||||||
// Cache paths
|
// Cache paths
|
||||||
'data_cache_path' => _dir(APP_DIR, 'cache'),
|
'data_cache_path' => _dir(APP_DIR, 'cache'),
|
||||||
'img_cache_path' => _dir(ROOT_DIR, 'public/images'),
|
'img_cache_path' => _dir(ROOT_DIR, 'public/images'),
|
||||||
|
|
||||||
// Included config files
|
|
||||||
'routes' => require _dir(CONF_DIR, 'routes.php'),
|
|
||||||
'database' => require _dir(CONF_DIR, 'database.php'),
|
|
||||||
];
|
];
|
@ -2,120 +2,178 @@
|
|||||||
|
|
||||||
return [
|
return [
|
||||||
'anime' => [
|
'anime' => [
|
||||||
|
'index' => [
|
||||||
|
'path' => '/',
|
||||||
|
'controller' => 'AnimeController',
|
||||||
|
'action' => 'redirect',
|
||||||
|
'params' => [
|
||||||
|
'url' => '', // Determined by config
|
||||||
|
'code' => '301'
|
||||||
|
]
|
||||||
|
],
|
||||||
'all' => [
|
'all' => [
|
||||||
'path' => '/all',
|
'path' => '/all{/view}',
|
||||||
'controller' => 'AnimeController',
|
'controller' => 'AnimeController',
|
||||||
'action' => 'anime_list',
|
'action' => 'anime_list',
|
||||||
'params' => [
|
'params' => [
|
||||||
'type' => 'all',
|
'type' => 'all',
|
||||||
'title' => WHOSE . " Anime List · All"
|
'title' => WHOSE . " Anime List · All"
|
||||||
|
],
|
||||||
|
'tokens' => [
|
||||||
|
'view' => '[a-z_]+'
|
||||||
]
|
]
|
||||||
],
|
],
|
||||||
'index' => [
|
'watching' => [
|
||||||
'path' => '/',
|
'path' => '/watching{/view}',
|
||||||
'controller' => 'AnimeController',
|
'controller' => 'AnimeController',
|
||||||
'action' => 'anime_list',
|
'action' => 'anime_list',
|
||||||
'params' => [
|
'params' => [
|
||||||
'type' => 'currently-watching',
|
'type' => 'currently-watching',
|
||||||
'title' => WHOSE . " Anime List · Watching"
|
'title' => WHOSE . " Anime List · Watching"
|
||||||
|
],
|
||||||
|
'tokens' => [
|
||||||
|
'view' => '[a-z_]+'
|
||||||
]
|
]
|
||||||
],
|
],
|
||||||
'plan_to_watch' => [
|
'plan_to_watch' => [
|
||||||
'path' => '/plan_to_watch',
|
'path' => '/plan_to_watch{/view}',
|
||||||
'controller' => 'AnimeController',
|
'controller' => 'AnimeController',
|
||||||
'action' => 'anime_list',
|
'action' => 'anime_list',
|
||||||
'params' => [
|
'params' => [
|
||||||
'type' => 'plan-to-watch',
|
'type' => 'plan-to-watch',
|
||||||
'title' => WHOSE . " Anime List · Plan to Watch"
|
'title' => WHOSE . " Anime List · Plan to Watch"
|
||||||
|
],
|
||||||
|
'tokens' => [
|
||||||
|
'view' => '[a-z_]+'
|
||||||
]
|
]
|
||||||
],
|
],
|
||||||
'on_hold' => [
|
'on_hold' => [
|
||||||
'path' => '/on_hold',
|
'path' => '/on_hold{/view}',
|
||||||
'controller' => 'AnimeController',
|
'controller' => 'AnimeController',
|
||||||
'action' => 'anime_list',
|
'action' => 'anime_list',
|
||||||
'params' => [
|
'params' => [
|
||||||
'type' => 'on-hold',
|
'type' => 'on-hold',
|
||||||
'title' => WHOSE . " Anime List · On Hold"
|
'title' => WHOSE . " Anime List · On Hold"
|
||||||
|
],
|
||||||
|
'tokens' => [
|
||||||
|
'view' => '[a-z_]+'
|
||||||
]
|
]
|
||||||
],
|
],
|
||||||
'dropped' => [
|
'dropped' => [
|
||||||
'path' => '/dropped',
|
'path' => '/dropped{/view}',
|
||||||
'controller' => 'AnimeController',
|
'controller' => 'AnimeController',
|
||||||
'action' => 'anime_list',
|
'action' => 'anime_list',
|
||||||
'params' => [
|
'params' => [
|
||||||
'type' => 'dropped',
|
'type' => 'dropped',
|
||||||
'title' => WHOSE . " Anime List · Dropped"
|
'title' => WHOSE . " Anime List · Dropped"
|
||||||
|
],
|
||||||
|
'tokens' => [
|
||||||
|
'view' => '[a-z_]+'
|
||||||
]
|
]
|
||||||
],
|
],
|
||||||
'completed' => [
|
'completed' => [
|
||||||
'path' => '/completed',
|
'path' => '/completed{/view}',
|
||||||
'controller' => 'AnimeController',
|
'controller' => 'AnimeController',
|
||||||
'action' => 'anime_list',
|
'action' => 'anime_list',
|
||||||
'params' => [
|
'params' => [
|
||||||
'type' => 'completed',
|
'type' => 'completed',
|
||||||
'title' => WHOSE . " Anime List · Completed"
|
'title' => WHOSE . " Anime List · Completed"
|
||||||
|
],
|
||||||
|
'tokens' => [
|
||||||
|
'view' => '[a-z_]+'
|
||||||
]
|
]
|
||||||
],
|
],
|
||||||
'collection' => [
|
'collection' => [
|
||||||
'path' => '/collection',
|
'path' => '/collection{/view}',
|
||||||
'controller' => 'AnimeController',
|
'controller' => 'AnimeController',
|
||||||
'action' => 'collection',
|
'action' => 'collection',
|
||||||
'params' => []
|
'params' => [],
|
||||||
|
'tokens' => [
|
||||||
|
'view' => '[a-z_]+'
|
||||||
|
]
|
||||||
]
|
]
|
||||||
],
|
],
|
||||||
'manga' => [
|
'manga' => [
|
||||||
|
'index' => [
|
||||||
|
'path' => '/',
|
||||||
|
'controller' => 'MangaController',
|
||||||
|
'action' => 'redirect',
|
||||||
|
'params' => [
|
||||||
|
'url' => '', // Determined by config
|
||||||
|
'code' => '301',
|
||||||
|
'type' => 'manga'
|
||||||
|
]
|
||||||
|
],
|
||||||
'all' => [
|
'all' => [
|
||||||
'path' => '/all',
|
'path' => '/all{/view}',
|
||||||
'controller' => 'MangaController',
|
'controller' => 'MangaController',
|
||||||
'action' => 'manga_list',
|
'action' => 'manga_list',
|
||||||
'params' => [
|
'params' => [
|
||||||
'type' => 'all',
|
'type' => 'all',
|
||||||
'title' => WHOSE . " Manga List · All"
|
'title' => WHOSE . " Manga List · All"
|
||||||
|
],
|
||||||
|
'tokens' => [
|
||||||
|
'view' => '[a-z_]+'
|
||||||
]
|
]
|
||||||
],
|
],
|
||||||
'index' => [
|
'reading' => [
|
||||||
'path' => '/',
|
'path' => '/reading{/view}',
|
||||||
'controller' => 'MangaController',
|
'controller' => 'MangaController',
|
||||||
'action' => 'manga_list',
|
'action' => 'manga_list',
|
||||||
'params' => [
|
'params' => [
|
||||||
'type' => 'Reading',
|
'type' => 'Reading',
|
||||||
'title' => WHOSE . " Manga List · Reading"
|
'title' => WHOSE . " Manga List · Reading"
|
||||||
|
],
|
||||||
|
'tokens' => [
|
||||||
|
'view' => '[a-z_]+'
|
||||||
]
|
]
|
||||||
],
|
],
|
||||||
'plan_to_read' => [
|
'plan_to_read' => [
|
||||||
'path' => '/plan_to_read',
|
'path' => '/plan_to_read{/view}',
|
||||||
'controller' => 'MangaController',
|
'controller' => 'MangaController',
|
||||||
'action' => 'manga_list',
|
'action' => 'manga_list',
|
||||||
'params' => [
|
'params' => [
|
||||||
'type' => 'Plan to Read',
|
'type' => 'Plan to Read',
|
||||||
'title' => WHOSE . " Manga List · Plan to Read"
|
'title' => WHOSE . " Manga List · Plan to Read"
|
||||||
|
],
|
||||||
|
'tokens' => [
|
||||||
|
'view' => '[a-z_]+'
|
||||||
]
|
]
|
||||||
],
|
],
|
||||||
'on_hold' => [
|
'on_hold' => [
|
||||||
'path' => '/on_hold',
|
'path' => '/on_hold{/view}',
|
||||||
'controller' => 'MangaController',
|
'controller' => 'MangaController',
|
||||||
'action' => 'manga_list',
|
'action' => 'manga_list',
|
||||||
'params' => [
|
'params' => [
|
||||||
'type' => 'On Hold',
|
'type' => 'On Hold',
|
||||||
'title' => WHOSE . " Manga List · On Hold"
|
'title' => WHOSE . " Manga List · On Hold"
|
||||||
|
],
|
||||||
|
'tokens' => [
|
||||||
|
'view' => '[a-z_]+'
|
||||||
]
|
]
|
||||||
],
|
],
|
||||||
'dropped' => [
|
'dropped' => [
|
||||||
'path' => '/dropped',
|
'path' => '/dropped{/view}',
|
||||||
'controller' => 'MangaController',
|
'controller' => 'MangaController',
|
||||||
'action' => 'manga_list',
|
'action' => 'manga_list',
|
||||||
'params' => [
|
'params' => [
|
||||||
'type' => 'Dropped',
|
'type' => 'Dropped',
|
||||||
'title' => WHOSE . " Manga List · Dropped"
|
'title' => WHOSE . " Manga List · Dropped"
|
||||||
|
],
|
||||||
|
'tokens' => [
|
||||||
|
'view' => '[a-z_]+'
|
||||||
]
|
]
|
||||||
],
|
],
|
||||||
'completed' => [
|
'completed' => [
|
||||||
'path' => '/completed',
|
'path' => '/completed{/view}',
|
||||||
'controller' => 'MangaController',
|
'controller' => 'MangaController',
|
||||||
'action' => 'manga_list',
|
'action' => 'manga_list',
|
||||||
'params' => [
|
'params' => [
|
||||||
'type' => 'Completed',
|
'type' => 'Completed',
|
||||||
'title' => WHOSE . " Manga List · Completed"
|
'title' => WHOSE . " Manga List · Completed"
|
||||||
|
],
|
||||||
|
'tokens' => [
|
||||||
|
'view' => '[a-z_]+'
|
||||||
]
|
]
|
||||||
],
|
],
|
||||||
]
|
]
|
||||||
|
@ -1,4 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
|
/**
|
||||||
|
* Anime Controller
|
||||||
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Controller for Anime-related pages
|
* Controller for Anime-related pages
|
||||||
@ -17,18 +20,24 @@ class AnimeController extends BaseController {
|
|||||||
*/
|
*/
|
||||||
private $collection_model;
|
private $collection_model;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Data to ve sent to all routes in this controller
|
||||||
|
* @var array $base_data
|
||||||
|
*/
|
||||||
|
private $base_data;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Route mapping for main navigation
|
* Route mapping for main navigation
|
||||||
* @var array $nav_routes
|
* @var array $nav_routes
|
||||||
*/
|
*/
|
||||||
private $nav_routes = [
|
private $nav_routes = [
|
||||||
'Watching' => '/',
|
'Watching' => '/watching{/view}',
|
||||||
'Plan to Watch' => '/plan_to_watch',
|
'Plan to Watch' => '/plan_to_watch{/view}',
|
||||||
'On Hold' => '/on_hold',
|
'On Hold' => '/on_hold{/view}',
|
||||||
'Dropped' => '/dropped',
|
'Dropped' => '/dropped{/view}',
|
||||||
'Completed' => '/completed',
|
'Completed' => '/completed{/view}',
|
||||||
'Collection' => '/collection',
|
'Collection' => '/collection{/view}',
|
||||||
'All' => '/all'
|
'All' => '/all{/view}'
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -39,6 +48,12 @@ class AnimeController extends BaseController {
|
|||||||
parent::__construct();
|
parent::__construct();
|
||||||
$this->model = new AnimeModel();
|
$this->model = new AnimeModel();
|
||||||
$this->collection_model = new AnimeCollectionModel();
|
$this->collection_model = new AnimeCollectionModel();
|
||||||
|
|
||||||
|
$this->base_data = [
|
||||||
|
'url_type' => 'anime',
|
||||||
|
'other_type' => 'manga',
|
||||||
|
'nav_routes' => $this->nav_routes,
|
||||||
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -48,17 +63,21 @@ class AnimeController extends BaseController {
|
|||||||
* @param string $title - The title of the page
|
* @param string $title - The title of the page
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function anime_list($type, $title)
|
public function anime_list($type, $title, $view)
|
||||||
{
|
{
|
||||||
|
$view_map = [
|
||||||
|
'' => 'cover',
|
||||||
|
'list' => 'list'
|
||||||
|
];
|
||||||
|
|
||||||
$data = ($type != 'all')
|
$data = ($type != 'all')
|
||||||
? $this->model->get_list($type)
|
? $this->model->get_list($type)
|
||||||
: $this->model->get_all_lists();
|
: $this->model->get_all_lists();
|
||||||
|
|
||||||
$this->outputHTML('anime/list', [
|
$this->outputHTML('anime/' . $view_map[$view], array_merge($this->base_data, [
|
||||||
'title' => $title,
|
'title' => $title,
|
||||||
'nav_routes' => $this->nav_routes,
|
|
||||||
'sections' => $data
|
'sections' => $data
|
||||||
]);
|
]));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -66,15 +85,19 @@ class AnimeController extends BaseController {
|
|||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function collection()
|
public function collection($view)
|
||||||
{
|
{
|
||||||
|
$view_map = [
|
||||||
|
'' => 'collection',
|
||||||
|
'list' => 'collection_list'
|
||||||
|
];
|
||||||
|
|
||||||
$data = $this->collection_model->get_collection();
|
$data = $this->collection_model->get_collection();
|
||||||
|
|
||||||
$this->outputHTML('anime/collection', [
|
$this->outputHTML('anime/' . $view_map[$view], array_merge($this->base_data, [
|
||||||
'title' => WHOSE . " Anime Collection",
|
'title' => WHOSE . " Anime Collection",
|
||||||
'nav_routes' => $this->nav_routes,
|
|
||||||
'sections' => $data
|
'sections' => $data
|
||||||
]);
|
]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// End of AnimeController.php
|
// End of AnimeController.php
|
@ -1,56 +1,67 @@
|
|||||||
<?php
|
<?php
|
||||||
|
/**
|
||||||
/**
|
* Manga Controller
|
||||||
* Controller for manga list
|
*/
|
||||||
*/
|
|
||||||
class MangaController extends BaseController {
|
/**
|
||||||
|
* Controller for manga list
|
||||||
/**
|
*/
|
||||||
* The manga model
|
class MangaController extends BaseController {
|
||||||
* @var object $model
|
|
||||||
*/
|
/**
|
||||||
private $model;
|
* The manga model
|
||||||
|
* @var object $model
|
||||||
/**
|
*/
|
||||||
* Route mapping for main navigation
|
private $model;
|
||||||
* @var array $nav_routes
|
|
||||||
*/
|
/**
|
||||||
private $nav_routes = [
|
* Route mapping for main navigation
|
||||||
'Reading' => '/',
|
* @var array $nav_routes
|
||||||
'Plan to Read' => '/plan_to_read',
|
*/
|
||||||
'On Hold' => '/on_hold',
|
private $nav_routes = [
|
||||||
'Dropped' => '/dropped',
|
'Reading' => '/reading{/view}',
|
||||||
'Completed' => '/completed',
|
'Plan to Read' => '/plan_to_read{/view}',
|
||||||
'All' => '/all'
|
'On Hold' => '/on_hold{/view}',
|
||||||
];
|
'Dropped' => '/dropped{/view}',
|
||||||
|
'Completed' => '/completed{/view}',
|
||||||
/**
|
'All' => '/all{/view}'
|
||||||
* Constructor
|
];
|
||||||
*/
|
|
||||||
public function __construct()
|
/**
|
||||||
{
|
* Constructor
|
||||||
parent::__construct();
|
*/
|
||||||
$this->model = new MangaModel();
|
public function __construct()
|
||||||
}
|
{
|
||||||
|
parent::__construct();
|
||||||
/**
|
$this->model = new MangaModel();
|
||||||
* Get a section of the manga list
|
}
|
||||||
*
|
|
||||||
* @param string $status
|
/**
|
||||||
* @param string $title
|
* Get a section of the manga list
|
||||||
* @return void
|
*
|
||||||
*/
|
* @param string $status
|
||||||
public function manga_list($status, $title)
|
* @param string $title
|
||||||
{
|
* @param string $view
|
||||||
$data = ($status !== 'all')
|
* @return void
|
||||||
? [$status => $this->model->get_list($status)]
|
*/
|
||||||
: $this->model->get_all_lists();
|
public function manga_list($status, $title, $view)
|
||||||
|
{
|
||||||
$this->outputHTML('manga/list', [
|
$view_map = [
|
||||||
'title' => $title,
|
'' => 'cover',
|
||||||
'nav_routes' => $this->nav_routes,
|
'list' => 'list'
|
||||||
'sections' => $data
|
];
|
||||||
]);
|
|
||||||
}
|
$data = ($status !== 'all')
|
||||||
}
|
? [$status => $this->model->get_list($status)]
|
||||||
|
: $this->model->get_all_lists();
|
||||||
|
|
||||||
|
$this->outputHTML('manga/' . $view_map[$view], [
|
||||||
|
'url_type' => 'manga',
|
||||||
|
'other_type' => 'anime',
|
||||||
|
'title' => $title,
|
||||||
|
'nav_routes' => $this->nav_routes,
|
||||||
|
'sections' => $data
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
// End of MangaController.php
|
// End of MangaController.php
|
@ -1,4 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
|
/**
|
||||||
|
* Anime Collection DB Model
|
||||||
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Model for getting anime collection data
|
* Model for getting anime collection data
|
||||||
|
@ -1,4 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
|
/**
|
||||||
|
* Anime API Model
|
||||||
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Model for handling requests dealing with the anime list
|
* Model for handling requests dealing with the anime list
|
||||||
@ -203,7 +206,7 @@ class AnimeModel extends BaseApiModel {
|
|||||||
/**
|
/**
|
||||||
* Sort the list by title
|
* Sort the list by title
|
||||||
*
|
*
|
||||||
* @param array &$array
|
* @param array $array
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
private function sort_by_name(&$array)
|
private function sort_by_name(&$array)
|
||||||
|
@ -1,164 +1,168 @@
|
|||||||
<?php
|
<?php
|
||||||
/**
|
/**
|
||||||
* Model for handling requests dealing with the manga list
|
* Manga API Model
|
||||||
*/
|
*/
|
||||||
class MangaModel extends BaseApiModel {
|
|
||||||
|
/**
|
||||||
/**
|
* Model for handling requests dealing with the manga list
|
||||||
* @var string $base_url - The base url for api requests
|
*/
|
||||||
*/
|
class MangaModel extends BaseApiModel {
|
||||||
protected $base_url = "https://hummingbird.me";
|
|
||||||
|
/**
|
||||||
/**
|
* @var string $base_url - The base url for api requests
|
||||||
* Constructor
|
*/
|
||||||
*/
|
protected $base_url = "https://hummingbird.me";
|
||||||
public function __construct()
|
|
||||||
{
|
/**
|
||||||
parent::__construct();
|
* Constructor
|
||||||
}
|
*/
|
||||||
|
public function __construct()
|
||||||
/**
|
{
|
||||||
* Get the full set of anime lists
|
parent::__construct();
|
||||||
*
|
}
|
||||||
* @return array
|
|
||||||
*/
|
/**
|
||||||
public function get_all_lists()
|
* Get the full set of anime lists
|
||||||
{
|
*
|
||||||
$data = $this->_get_list();
|
* @return array
|
||||||
|
*/
|
||||||
foreach ($data as $key => &$val)
|
public function get_all_lists()
|
||||||
{
|
{
|
||||||
$this->sort_by_name($val);
|
$data = $this->_get_list();
|
||||||
}
|
|
||||||
|
foreach ($data as $key => &$val)
|
||||||
return $data;
|
{
|
||||||
}
|
$this->sort_by_name($val);
|
||||||
|
}
|
||||||
/**
|
|
||||||
* Get a category out of the full list
|
return $data;
|
||||||
*
|
}
|
||||||
* @param string $status
|
|
||||||
* @return array
|
/**
|
||||||
*/
|
* Get a category out of the full list
|
||||||
public function get_list($status)
|
*
|
||||||
{
|
* @param string $status
|
||||||
$data = $this->_get_list($status);
|
* @return array
|
||||||
|
*/
|
||||||
$this->sort_by_name($data);
|
public function get_list($status)
|
||||||
|
{
|
||||||
return $data;
|
$data = $this->_get_list($status);
|
||||||
}
|
|
||||||
|
$this->sort_by_name($data);
|
||||||
/**
|
|
||||||
* Massage the list of manga entries into something more usable
|
return $data;
|
||||||
*
|
}
|
||||||
* @param string $status
|
|
||||||
* @return array
|
/**
|
||||||
*/
|
* Massage the list of manga entries into something more usable
|
||||||
private function _get_list($status="all")
|
*
|
||||||
{
|
* @param string $status
|
||||||
global $defaultHandler;
|
* @return array
|
||||||
|
*/
|
||||||
$cache_file = _dir($this->config->data_cache_path, 'manga.json');
|
private function _get_list($status="all")
|
||||||
|
{
|
||||||
$config = [
|
global $defaultHandler;
|
||||||
'query' => [
|
|
||||||
'user_id' => $this->config->hummingbird_username
|
$cache_file = _dir($this->config->data_cache_path, 'manga.json');
|
||||||
],
|
|
||||||
'allow_redirects' => false
|
$config = [
|
||||||
];
|
'query' => [
|
||||||
|
'user_id' => $this->config->hummingbird_username
|
||||||
$response = $this->client->get($this->_url('/manga_library_entries'), $config);
|
],
|
||||||
|
'allow_redirects' => false
|
||||||
$defaultHandler->addDataTable('response', (array)$response);
|
];
|
||||||
|
|
||||||
if ($response->getStatusCode() != 200)
|
$response = $this->client->get($this->_url('/manga_library_entries'), $config);
|
||||||
{
|
|
||||||
if ( ! file_exists($cache_file))
|
$defaultHandler->addDataTable('response', (array)$response);
|
||||||
{
|
|
||||||
throw new Exception($response->getEffectiveUrl());
|
if ($response->getStatusCode() != 200)
|
||||||
}
|
{
|
||||||
else
|
if ( ! file_exists($cache_file))
|
||||||
{
|
{
|
||||||
$raw_data = json_decode(file_get_contents($cache_file), TRUE);
|
throw new Exception($response->getEffectiveUrl());
|
||||||
}
|
}
|
||||||
}
|
else
|
||||||
else
|
{
|
||||||
{
|
$raw_data = json_decode(file_get_contents($cache_file), TRUE);
|
||||||
// Reorganize data to be more usable
|
}
|
||||||
$raw_data = $response->json();
|
}
|
||||||
|
else
|
||||||
// Cache data in case of downtime
|
{
|
||||||
file_put_contents($cache_file, json_encode($raw_data));
|
// Reorganize data to be more usable
|
||||||
}
|
$raw_data = $response->json();
|
||||||
|
|
||||||
$data = [
|
// Cache data in case of downtime
|
||||||
'Reading' => [],
|
file_put_contents($cache_file, json_encode($raw_data));
|
||||||
'Plan to Read' => [],
|
}
|
||||||
'On Hold' => [],
|
|
||||||
'Dropped' => [],
|
$data = [
|
||||||
'Completed' => [],
|
'Reading' => [],
|
||||||
];
|
'Plan to Read' => [],
|
||||||
$manga_data = [];
|
'On Hold' => [],
|
||||||
|
'Dropped' => [],
|
||||||
// Massage the two lists into one
|
'Completed' => [],
|
||||||
foreach($raw_data['manga'] as $manga)
|
];
|
||||||
{
|
$manga_data = [];
|
||||||
$manga_data[$manga['id']] = $manga;
|
|
||||||
}
|
// Massage the two lists into one
|
||||||
|
foreach($raw_data['manga'] as $manga)
|
||||||
// Filter data by status
|
{
|
||||||
foreach($raw_data['manga_library_entries'] as &$entry)
|
$manga_data[$manga['id']] = $manga;
|
||||||
{
|
}
|
||||||
$entry['manga'] = $manga_data[$entry['manga_id']];
|
|
||||||
|
// Filter data by status
|
||||||
// Cache poster images
|
foreach($raw_data['manga_library_entries'] as &$entry)
|
||||||
$entry['manga']['poster_image'] = $this->get_cached_image($entry['manga']['poster_image'], $entry['manga_id'], 'manga');
|
{
|
||||||
|
$entry['manga'] = $manga_data[$entry['manga_id']];
|
||||||
switch($entry['status'])
|
|
||||||
{
|
// Cache poster images
|
||||||
case "Plan to Read":
|
$entry['manga']['poster_image'] = $this->get_cached_image($entry['manga']['poster_image'], $entry['manga_id'], 'manga');
|
||||||
$data['Plan to Read'][] = $entry;
|
|
||||||
break;
|
switch($entry['status'])
|
||||||
|
{
|
||||||
case "Dropped":
|
case "Plan to Read":
|
||||||
$data['Dropped'][] = $entry;
|
$data['Plan to Read'][] = $entry;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "On Hold":
|
case "Dropped":
|
||||||
$data['On Hold'][] = $entry;
|
$data['Dropped'][] = $entry;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "Currently Reading":
|
case "On Hold":
|
||||||
$data['Reading'][] = $entry;
|
$data['On Hold'][] = $entry;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "Completed":
|
case "Currently Reading":
|
||||||
default:
|
$data['Reading'][] = $entry;
|
||||||
$data['Completed'][] = $entry;
|
break;
|
||||||
break;
|
|
||||||
}
|
case "Completed":
|
||||||
}
|
default:
|
||||||
|
$data['Completed'][] = $entry;
|
||||||
return (array_key_exists($status, $data)) ? $data[$status] : $data;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
/**
|
|
||||||
* Sort the manga entries by their title
|
return (array_key_exists($status, $data)) ? $data[$status] : $data;
|
||||||
*
|
}
|
||||||
* @param array $array
|
|
||||||
* @return void
|
/**
|
||||||
*/
|
* Sort the manga entries by their title
|
||||||
private function sort_by_name(&$array)
|
*
|
||||||
{
|
* @param array $array
|
||||||
$sort = array();
|
* @return void
|
||||||
|
*/
|
||||||
foreach($array as $key => $item)
|
private function sort_by_name(&$array)
|
||||||
{
|
{
|
||||||
$sort[$key] = $item['manga']['romaji_title'];
|
$sort = array();
|
||||||
}
|
|
||||||
|
foreach($array as $key => $item)
|
||||||
array_multisort($sort, SORT_ASC, $array);
|
{
|
||||||
}
|
$sort[$key] = $item['manga']['romaji_title'];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
array_multisort($sort, SORT_ASC, $array);
|
||||||
|
}
|
||||||
|
}
|
||||||
// End of MangaModel.php
|
// End of MangaModel.php
|
@ -1,32 +1,27 @@
|
|||||||
<body class="anime collection">
|
<main>
|
||||||
<h1><?= WHOSE ?> Anime Collection [<a href="<?= full_url('', 'manga') ?>">Manga List</a>]</h1>
|
<?php foreach ($sections as $name => $items): ?>
|
||||||
<?php include 'nav.php' ?>
|
<section class="status">
|
||||||
<main>
|
<h2><?= $name ?></h2>
|
||||||
<?php foreach ($sections as $name => $items): ?>
|
<section class="media-wrap">
|
||||||
<section class="status">
|
<?php foreach($items as $item): ?>
|
||||||
<h2><?= $name ?></h2>
|
<a href="https://hummingbird.me/anime/<?= $item['slug'] ?>">
|
||||||
<section class="media-wrap">
|
<article class="media" id="a-<?= $item['hummingbird_id'] ?>">
|
||||||
<?php foreach($items as $item): ?>
|
<img src="<?= $item['cover_image'] ?>" />
|
||||||
<a href="https://hummingbird.me/anime/<?= $item['slug'] ?>">
|
<div class="name">
|
||||||
<article class="media" id="a-<?= $item['hummingbird_id'] ?>">
|
<?= $item['title'] ?>
|
||||||
<img src="<?= $item['cover_image'] ?>" />
|
<?= ($item['alternate_title'] != "") ? "<br />({$item['alternate_title']})" : ""; ?>
|
||||||
<div class="name">
|
</div>
|
||||||
<?= $item['title'] ?>
|
<div class="media_metadata">
|
||||||
<?= ($item['alternate_title'] != "") ? "<br />({$item['alternate_title']})" : ""; ?>
|
<div class="completion">Episodes: <?= $item['episode_count'] ?></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="media_metadata">
|
<div class="medium_metadata">
|
||||||
<div class="completion">Episodes: <?= $item['episode_count'] ?></div>
|
<div class="media_type"><?= $item['show_type'] ?></div>
|
||||||
</div>
|
<div class="age_rating"><?= $item['age_rating'] ?></div>
|
||||||
<div class="medium_metadata">
|
</div>
|
||||||
<div class="media_type"><?= $item['show_type'] ?></div>
|
</article>
|
||||||
<div class="age_rating"><?= $item['age_rating'] ?></div>
|
</a>
|
||||||
</div>
|
<?php endforeach ?>
|
||||||
</article>
|
|
||||||
</a>
|
|
||||||
<?php endforeach ?>
|
|
||||||
</section>
|
|
||||||
</section>
|
</section>
|
||||||
<?php endforeach ?>
|
</section>
|
||||||
</main>
|
<?php endforeach ?>
|
||||||
</body>
|
</main>
|
||||||
</html>
|
|
43
app/views/anime/collection_list.php
Normal file
43
app/views/anime/collection_list.php
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
<main>
|
||||||
|
<?php foreach ($sections as $name => $items): ?>
|
||||||
|
<h2><?= $name ?></h2>
|
||||||
|
<table>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Title</th>
|
||||||
|
<th>Alternate Title</th>
|
||||||
|
<th>Episode Count</th>
|
||||||
|
<th>Episode Length</th>
|
||||||
|
<th>Show Type</th>
|
||||||
|
<th>Age Rating</th>
|
||||||
|
<th>Notes</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<?php foreach($items as $item): ?>
|
||||||
|
<tr>
|
||||||
|
<td class="align_left">
|
||||||
|
<a href="https://hummingbird.me/anime/<?= $item['slug'] ?>">
|
||||||
|
<?= $item['title'] ?>
|
||||||
|
</a>
|
||||||
|
</td>
|
||||||
|
<td class="align_left"><?= $item['alternate_title'] ?></td>
|
||||||
|
<td><?= $item['episode_count'] ?></td>
|
||||||
|
<td><?= $item['episode_length'] ?></td>
|
||||||
|
<td><?= $item['show_type'] ?></td>
|
||||||
|
<td><?= $item['age_rating'] ?></td>
|
||||||
|
<td class="align_left"><?= $item['notes'] ?></td>
|
||||||
|
</tr>
|
||||||
|
<?php endforeach ?>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
<br />
|
||||||
|
<?php endforeach ?>
|
||||||
|
</main>
|
||||||
|
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
|
||||||
|
<script src="/public/js/table_sorter/jquery.tablesorter.min.js"></script>
|
||||||
|
<script>
|
||||||
|
$(function() {
|
||||||
|
$('table').tablesorter();
|
||||||
|
});
|
||||||
|
</script>
|
29
app/views/anime/cover.php
Normal file
29
app/views/anime/cover.php
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
<main>
|
||||||
|
<?php foreach ($sections as $name => $items): ?>
|
||||||
|
<section class="status">
|
||||||
|
<h2><?= $name ?></h2>
|
||||||
|
<section class="media-wrap">
|
||||||
|
<?php foreach($items as $item): ?>
|
||||||
|
<a href="<?= $item['anime']['url'] ?>">
|
||||||
|
<article class="media" id="a-<?= $item['anime']['id'] ?>">
|
||||||
|
<img class="round_all" src="<?= $item['anime']['cover_image'] ?>" />
|
||||||
|
<div class="round_all name">
|
||||||
|
<?= $item['anime']['title'] ?>
|
||||||
|
<?= ($item['anime']['alternate_title'] != "") ? "<br />({$item['anime']['alternate_title']})" : ""; ?>
|
||||||
|
</div>
|
||||||
|
<div class="media_metadata">
|
||||||
|
<div class="round_top airing_status"><?= $item['anime']['status'] ?></div>
|
||||||
|
<div class="user_rating"><?= (int)($item['rating']['value'] * 2) ?> / 10</div>
|
||||||
|
<div class="round_bottom completion">Episodes: <?= $item['episodes_watched'] ?> / <?= $item['anime']['episode_count'] ?></div>
|
||||||
|
</div>
|
||||||
|
<div class="medium_metadata">
|
||||||
|
<div class="round_top media_type"><?= $item['anime']['show_type'] ?></div>
|
||||||
|
<div class="round_bottom age_rating"><?= $item['anime']['age_rating'] ?></div>
|
||||||
|
</div>
|
||||||
|
</article>
|
||||||
|
</a>
|
||||||
|
<?php endforeach ?>
|
||||||
|
</section>
|
||||||
|
</section>
|
||||||
|
<?php endforeach ?>
|
||||||
|
</main>
|
@ -1,34 +1,42 @@
|
|||||||
<body class="anime list">
|
<main>
|
||||||
<h1><?= WHOSE ?> Anime List [<a href="<?= full_url('', 'manga') ?>">Manga List</a>]</h1>
|
<?php foreach ($sections as $name => $items): ?>
|
||||||
<?php include 'nav.php' ?>
|
<h2><?= $name ?></h2>
|
||||||
<main>
|
<table>
|
||||||
<?php foreach ($sections as $name => $items): ?>
|
<thead>
|
||||||
<section class="status">
|
<tr>
|
||||||
<h2><?= $name ?></h2>
|
<th>Title</th>
|
||||||
<section class="media-wrap">
|
<th>Alternate Title</th>
|
||||||
<?php foreach($items as $item): ?>
|
<th>Airing Status</th>
|
||||||
|
<th>Score</th>
|
||||||
|
<th>Type</th>
|
||||||
|
<th>Progress</th>
|
||||||
|
<th>Rated</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<?php foreach($items as $item): ?>
|
||||||
|
<tr id="a-<?= $item['anime']['id'] ?>">
|
||||||
|
<td class="align_left">
|
||||||
<a href="<?= $item['anime']['url'] ?>">
|
<a href="<?= $item['anime']['url'] ?>">
|
||||||
<article class="media" id="a-<?= $item['anime']['id'] ?>">
|
<?= $item['anime']['title'] ?>
|
||||||
<img class="round_all" src="<?= $item['anime']['cover_image'] ?>" />
|
|
||||||
<div class="round_all name">
|
|
||||||
<?= $item['anime']['title'] ?>
|
|
||||||
<?= ($item['anime']['alternate_title'] != "") ? "<br />({$item['anime']['alternate_title']})" : ""; ?>
|
|
||||||
</div>
|
|
||||||
<div class="media_metadata">
|
|
||||||
<div class="round_top airing_status"><?= $item['anime']['status'] ?></div>
|
|
||||||
<div class="user_rating"><?= (int)($item['rating']['value'] * 2) ?> / 10</div>
|
|
||||||
<div class="round_bottom completion">Episodes: <?= $item['episodes_watched'] ?> / <?= $item['anime']['episode_count'] ?></div>
|
|
||||||
</div>
|
|
||||||
<div class="medium_metadata">
|
|
||||||
<div class="round_top media_type"><?= $item['anime']['show_type'] ?></div>
|
|
||||||
<div class="round_bottom age_rating"><?= $item['anime']['age_rating'] ?></div>
|
|
||||||
</div>
|
|
||||||
</article>
|
|
||||||
</a>
|
</a>
|
||||||
<?php endforeach ?>
|
</td>
|
||||||
</section>
|
<td class="align_left"><?= $item['anime']['alternate_title'] ?></td>
|
||||||
</section>
|
<td class="align_left"><?= $item['anime']['status'] ?></td>
|
||||||
<?php endforeach ?>
|
<td><?= (int)($item['rating']['value'] * 2) ?> / 10 </td>
|
||||||
</main>
|
<td><?= $item['anime']['show_type'] ?></td>
|
||||||
</body>
|
<td>Episodes: <?= $item['episodes_watched'] ?> / <?= $item['anime']['episode_count'] ?></td>
|
||||||
</html>
|
<td><?= $item['anime']['age_rating'] ?></td>
|
||||||
|
</tr>
|
||||||
|
<?php endforeach ?>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
<?php endforeach ?>
|
||||||
|
</main>
|
||||||
|
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
|
||||||
|
<script src="/public/js/table_sorter/jquery.tablesorter.min.js"></script>
|
||||||
|
<script>
|
||||||
|
$(function() {
|
||||||
|
$('table').tablesorter();
|
||||||
|
});
|
||||||
|
</script>
|
@ -1,7 +0,0 @@
|
|||||||
<nav>
|
|
||||||
<ul>
|
|
||||||
<?php foreach($nav_routes as $title => $path): ?>
|
|
||||||
<li class="<?= is_selected($path, $route_path) ?>"><a href="<?= full_url($path) ?>"><?= $title ?></a></li>
|
|
||||||
<?php endforeach ?>
|
|
||||||
</ul>
|
|
||||||
</nav>
|
|
2
app/views/footer.php
Normal file
2
app/views/footer.php
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
</body>
|
||||||
|
</html>
|
@ -1,7 +1,24 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<title><?= $title ?></title>
|
<title><?= $title ?></title>
|
||||||
<link rel="stylesheet" href="/public/css/marx.css" />
|
<link rel="stylesheet" href="/public/css/marx.css" />
|
||||||
<link rel="stylesheet" href="/public/css/base.css" />
|
<link rel="stylesheet" href="/public/css/base.css" />
|
||||||
</head>
|
</head>
|
||||||
|
<body class="<?= $url_type ?> list">
|
||||||
|
<h1><?= WHOSE ?> <?= ucfirst($url_type) ?> <?= (strpos($route_path, 'collection') !== FALSE) ? 'Collection' : 'List' ?> [<a href="<?= full_url("", $other_type) ?>"><?= ucfirst($other_type) ?> List</a>]</h1>
|
||||||
|
<nav>
|
||||||
|
<ul>
|
||||||
|
<?php foreach($nav_routes as $title => $nav_path): ?>
|
||||||
|
<li class="<?= is_selected($nav_path, $route_path) ?>"><a href="<?= full_url($nav_path, $url_type) ?>"><?= $title ?></a></li>
|
||||||
|
<?php endforeach ?>
|
||||||
|
</ul>
|
||||||
|
</nav>
|
||||||
|
<br />
|
||||||
|
<nav>
|
||||||
|
<ul>
|
||||||
|
<li class="<?= is_not_selected('list', last_segment()) ?>"><a href="<?= full_url($route_path, $url_type) ?>">Cover View</a></li>
|
||||||
|
<li class="<?= is_selected('list', last_segment()) ?>"><a href="<?= full_url("{$route_path}/list", $url_type) ?>">List View</a></li>
|
||||||
|
</ul>
|
||||||
|
</nav>
|
||||||
|
<br />
|
30
app/views/manga/cover.php
Normal file
30
app/views/manga/cover.php
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
<main>
|
||||||
|
<?php foreach ($sections as $name => $items): ?>
|
||||||
|
<section class="status">
|
||||||
|
<h2><?= $name ?></h2>
|
||||||
|
<section class="media-wrap">
|
||||||
|
<?php foreach($items as $item): ?>
|
||||||
|
<a href="https://hummingbird.me/manga/<?= $item['manga']['id'] ?>">
|
||||||
|
<article class="media" id="manga-<?= $item['manga']['id'] ?>">
|
||||||
|
<img src="<?= $item['manga']['poster_image'] ?>" />
|
||||||
|
<div class="name">
|
||||||
|
<?= $item['manga']['romaji_title'] ?>
|
||||||
|
<?= (isset($item['manga']['english_title'])) ? "<br />({$item['manga']['english_title']})" : ""; ?>
|
||||||
|
</div>
|
||||||
|
<div class="media_metadata">
|
||||||
|
<div class="user_rating"><?= ($item['rating'] > 0) ? (int)($item['rating'] * 2) : '-' ?> / 10</div>
|
||||||
|
<div class="completion">
|
||||||
|
Chapters: <?= $item['chapters_read'] ?> / <?= ($item['manga']['chapter_count'] > 0) ? $item['manga']['chapter_count'] : "-" ?><?php /*<br />
|
||||||
|
Volumes: <?= $item['volumes_read'] ?> / <?= ($item['manga']['volume_count'] > 0) ? $item['manga']['volume_count'] : "-" ?>*/ ?>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<?php /*<div class="medium_metadata">
|
||||||
|
<div class="media_type"><?= $item['manga']['manga_type'] ?></div>
|
||||||
|
</div> */ ?>
|
||||||
|
</article>
|
||||||
|
</a>
|
||||||
|
<?php endforeach ?>
|
||||||
|
</section>
|
||||||
|
</section>
|
||||||
|
<?php endforeach ?>
|
||||||
|
</main>
|
@ -1,35 +1,40 @@
|
|||||||
<body class="manga list">
|
<main>
|
||||||
<h1><?= WHOSE ?> Manga List [<a href="<?= full_url("", "anime") ?>">Anime List</a>]</h1>
|
<?php foreach ($sections as $name => $items): ?>
|
||||||
<?php include 'nav.php' ?>
|
<h2><?= $name ?></h2>
|
||||||
<main>
|
<table>
|
||||||
<?php foreach ($sections as $name => $items): ?>
|
<thead>
|
||||||
<section class="status">
|
<tr>
|
||||||
<h2><?= $name ?></h2>
|
<th>Title</th>
|
||||||
<section class="media-wrap">
|
<th>Alternate Title</th>
|
||||||
<?php foreach($items as $item): ?>
|
<th>Rating</th>
|
||||||
<a href="https://hummingbird.me/manga/<?= $item['manga']['id'] ?>">
|
<th>Chapters</th>
|
||||||
<article class="media" id="manga-<?= $item['manga']['id'] ?>">
|
<!-- <th>Volumes</th> -->
|
||||||
<img src="<?= $item['manga']['poster_image'] ?>" />
|
<th>Type</th>
|
||||||
<div class="name">
|
</tr>
|
||||||
<?= $item['manga']['romaji_title'] ?>
|
</thead>
|
||||||
<?= (isset($item['manga']['english_title'])) ? "<br />({$item['manga']['english_title']})" : ""; ?>
|
<tbody>
|
||||||
</div>
|
<?php foreach($items as $item): ?>
|
||||||
<div class="media_metadata">
|
<tr id="manga-<?= $item['manga']['id'] ?>">
|
||||||
<div class="user_rating"><?= ($item['rating'] > 0) ? (int)($item['rating'] * 2) : '-' ?> / 10</div>
|
<td class="align_left">
|
||||||
<div class="completion">
|
<a href="https://hummingbird.me/manga/<?= $item['manga']['id'] ?>">
|
||||||
Chapters: <?= $item['chapters_read'] ?> / <?= ($item['manga']['chapter_count'] > 0) ? $item['manga']['chapter_count'] : "-" ?><?php /*<br />
|
<?= $item['manga']['romaji_title'] ?>
|
||||||
Volumes: <?= $item['volumes_read'] ?> / <?= ($item['manga']['volume_count'] > 0) ? $item['manga']['volume_count'] : "-" ?>*/ ?>
|
</a>
|
||||||
</div>
|
</td>
|
||||||
</div>
|
<td class="align_left"><?= (array_key_exists('english_title', $item['manga'])) ? $item['manga']['english_title'] : "" ?></td>
|
||||||
<?php /*<div class="medium_metadata">
|
<td><?= ($item['rating'] > 0) ? (int)($item['rating'] * 2) : '-' ?> / 10</td>
|
||||||
<div class="media_type"><?= $item['manga']['manga_type'] ?></div>
|
<td><?= $item['chapters_read'] ?> / <?= ($item['manga']['chapter_count'] > 0) ? $item['manga']['chapter_count'] : "-" ?></td>
|
||||||
</div> */ ?>
|
<!-- <td><?= $item['volumes_read'] ?> / <?= ($item['manga']['volume_count'] > 0) ? $item['manga']['volume_count'] : "-" ?></td> -->
|
||||||
</article>
|
<td><?= $item['manga']['manga_type'] ?></td>
|
||||||
</a>
|
</tr>
|
||||||
<?php endforeach ?>
|
<?php endforeach ?>
|
||||||
</section>
|
</tbody>
|
||||||
</section>
|
</table>
|
||||||
<?php endforeach ?>
|
<?php endforeach ?>
|
||||||
</main>
|
</main>
|
||||||
</body>
|
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
|
||||||
</html>
|
<script src="/public/js/table_sorter/jquery.tablesorter.min.js"></script>
|
||||||
|
<script>
|
||||||
|
$(function() {
|
||||||
|
$('table').tablesorter();
|
||||||
|
});
|
||||||
|
</script>
|
@ -1,7 +0,0 @@
|
|||||||
<nav>
|
|
||||||
<ul>
|
|
||||||
<?php foreach($nav_routes as $title => $path): ?>
|
|
||||||
<li class="<?= is_selected($path, $route_path) ?>"><a href="<?= full_url($path, 'manga') ?>"><?= $title ?></a></li>
|
|
||||||
<?php endforeach ?>
|
|
||||||
</ul>
|
|
||||||
</nav>
|
|
@ -1,4 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
|
/**
|
||||||
|
* Here begins everything!
|
||||||
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Joins paths together. Variadic to take an
|
* Joins paths together. Variadic to take an
|
||||||
@ -8,13 +11,15 @@
|
|||||||
*/
|
*/
|
||||||
function _dir() { return implode(DIRECTORY_SEPARATOR, func_get_args()); }
|
function _dir() { return implode(DIRECTORY_SEPARATOR, func_get_args()); }
|
||||||
|
|
||||||
// Base paths
|
|
||||||
define('ROOT_DIR', __DIR__);
|
define('ROOT_DIR', __DIR__);
|
||||||
define('APP_DIR', _dir(ROOT_DIR, 'app'));
|
define('APP_DIR', _dir(ROOT_DIR, 'app'));
|
||||||
define('CONF_DIR', _dir(APP_DIR, 'config'));
|
define('CONF_DIR', _dir(APP_DIR, 'config'));
|
||||||
define('BASE_DIR', _dir(APP_DIR, 'base'));
|
define('BASE_DIR', _dir(APP_DIR, 'base'));
|
||||||
|
|
||||||
// Who's list is it?
|
/**
|
||||||
|
* Well, whose list is it?
|
||||||
|
*/
|
||||||
define('WHOSE', "Tim's");
|
define('WHOSE', "Tim's");
|
||||||
|
|
||||||
// Load config and global functions
|
// Load config and global functions
|
||||||
|
@ -2,6 +2,23 @@ body {
|
|||||||
margin: 0.5em;
|
margin: 0.5em;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
table {
|
||||||
|
width:85%;
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
tbody > tr:nth-child(odd) {
|
||||||
|
background: #ddd;
|
||||||
|
}
|
||||||
|
|
||||||
|
.align_left {
|
||||||
|
text-align:left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.align_right {
|
||||||
|
text-align:right;
|
||||||
|
}
|
||||||
|
|
||||||
.round_all {
|
.round_all {
|
||||||
border-radius:0.5em;
|
border-radius:0.5em;
|
||||||
}
|
}
|
||||||
|
122
public/js/table_sorter/jquery.metadata.js
Normal file
122
public/js/table_sorter/jquery.metadata.js
Normal file
@ -0,0 +1,122 @@
|
|||||||
|
/*
|
||||||
|
* Metadata - jQuery plugin for parsing metadata from elements
|
||||||
|
*
|
||||||
|
* Copyright (c) 2006 John Resig, Yehuda Katz, J<EFBFBD>örn Zaefferer, Paul McLanahan
|
||||||
|
*
|
||||||
|
* Dual licensed under the MIT and GPL licenses:
|
||||||
|
* http://www.opensource.org/licenses/mit-license.php
|
||||||
|
* http://www.gnu.org/licenses/gpl.html
|
||||||
|
*
|
||||||
|
* Revision: $Id$
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the type of metadata to use. Metadata is encoded in JSON, and each property
|
||||||
|
* in the JSON will become a property of the element itself.
|
||||||
|
*
|
||||||
|
* There are three supported types of metadata storage:
|
||||||
|
*
|
||||||
|
* attr: Inside an attribute. The name parameter indicates *which* attribute.
|
||||||
|
*
|
||||||
|
* class: Inside the class attribute, wrapped in curly braces: { }
|
||||||
|
*
|
||||||
|
* elem: Inside a child element (e.g. a script tag). The
|
||||||
|
* name parameter indicates *which* element.
|
||||||
|
*
|
||||||
|
* The metadata for an element is loaded the first time the element is accessed via jQuery.
|
||||||
|
*
|
||||||
|
* As a result, you can define the metadata type, use $(expr) to load the metadata into the elements
|
||||||
|
* matched by expr, then redefine the metadata type and run another $(expr) for other elements.
|
||||||
|
*
|
||||||
|
* @name $.metadata.setType
|
||||||
|
*
|
||||||
|
* @example <p id="one" class="some_class {item_id: 1, item_label: 'Label'}">This is a p</p>
|
||||||
|
* @before $.metadata.setType("class")
|
||||||
|
* @after $("#one").metadata().item_id == 1; $("#one").metadata().item_label == "Label"
|
||||||
|
* @desc Reads metadata from the class attribute
|
||||||
|
*
|
||||||
|
* @example <p id="one" class="some_class" data="{item_id: 1, item_label: 'Label'}">This is a p</p>
|
||||||
|
* @before $.metadata.setType("attr", "data")
|
||||||
|
* @after $("#one").metadata().item_id == 1; $("#one").metadata().item_label == "Label"
|
||||||
|
* @desc Reads metadata from a "data" attribute
|
||||||
|
*
|
||||||
|
* @example <p id="one" class="some_class"><script>{item_id: 1, item_label: 'Label'}</script>This is a p</p>
|
||||||
|
* @before $.metadata.setType("elem", "script")
|
||||||
|
* @after $("#one").metadata().item_id == 1; $("#one").metadata().item_label == "Label"
|
||||||
|
* @desc Reads metadata from a nested script element
|
||||||
|
*
|
||||||
|
* @param String type The encoding type
|
||||||
|
* @param String name The name of the attribute to be used to get metadata (optional)
|
||||||
|
* @cat Plugins/Metadata
|
||||||
|
* @descr Sets the type of encoding to be used when loading metadata for the first time
|
||||||
|
* @type undefined
|
||||||
|
* @see metadata()
|
||||||
|
*/
|
||||||
|
|
||||||
|
(function($) {
|
||||||
|
|
||||||
|
$.extend({
|
||||||
|
metadata : {
|
||||||
|
defaults : {
|
||||||
|
type: 'class',
|
||||||
|
name: 'metadata',
|
||||||
|
cre: /({.*})/,
|
||||||
|
single: 'metadata'
|
||||||
|
},
|
||||||
|
setType: function( type, name ){
|
||||||
|
this.defaults.type = type;
|
||||||
|
this.defaults.name = name;
|
||||||
|
},
|
||||||
|
get: function( elem, opts ){
|
||||||
|
var settings = $.extend({},this.defaults,opts);
|
||||||
|
// check for empty string in single property
|
||||||
|
if ( !settings.single.length ) settings.single = 'metadata';
|
||||||
|
|
||||||
|
var data = $.data(elem, settings.single);
|
||||||
|
// returned cached data if it already exists
|
||||||
|
if ( data ) return data;
|
||||||
|
|
||||||
|
data = "{}";
|
||||||
|
|
||||||
|
if ( settings.type == "class" ) {
|
||||||
|
var m = settings.cre.exec( elem.className );
|
||||||
|
if ( m )
|
||||||
|
data = m[1];
|
||||||
|
} else if ( settings.type == "elem" ) {
|
||||||
|
if( !elem.getElementsByTagName )
|
||||||
|
return undefined;
|
||||||
|
var e = elem.getElementsByTagName(settings.name);
|
||||||
|
if ( e.length )
|
||||||
|
data = $.trim(e[0].innerHTML);
|
||||||
|
} else if ( elem.getAttribute != undefined ) {
|
||||||
|
var attr = elem.getAttribute( settings.name );
|
||||||
|
if ( attr )
|
||||||
|
data = attr;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( data.indexOf( '{' ) <0 )
|
||||||
|
data = "{" + data + "}";
|
||||||
|
|
||||||
|
data = eval("(" + data + ")");
|
||||||
|
|
||||||
|
$.data( elem, settings.single, data );
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the metadata object for the first member of the jQuery object.
|
||||||
|
*
|
||||||
|
* @name metadata
|
||||||
|
* @descr Returns element's metadata object
|
||||||
|
* @param Object opts An object contianing settings to override the defaults
|
||||||
|
* @type jQuery
|
||||||
|
* @cat Plugins/Metadata
|
||||||
|
*/
|
||||||
|
$.fn.metadata = function( opts ){
|
||||||
|
return $.metadata.get( this[0], opts );
|
||||||
|
};
|
||||||
|
|
||||||
|
})(jQuery);
|
1031
public/js/table_sorter/jquery.tablesorter.js
Normal file
1031
public/js/table_sorter/jquery.tablesorter.js
Normal file
File diff suppressed because it is too large
Load Diff
4
public/js/table_sorter/jquery.tablesorter.min.js
vendored
Normal file
4
public/js/table_sorter/jquery.tablesorter.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue
Block a user