Refactor EVERYTHING, for better, more configurable code
This commit is contained in:
parent
5c461adcc1
commit
aedfc743c6
57
app/base/BaseApiModel.php
Normal file
57
app/base/BaseApiModel.php
Normal file
@ -0,0 +1,57 @@
|
||||
<?php
|
||||
|
||||
use \GuzzleHttp\Client;
|
||||
use \GuzzleHttp\Cookie\CookieJar;
|
||||
|
||||
/**
|
||||
* Base model for api interaction
|
||||
*/
|
||||
class BaseApiModel extends BaseModel {
|
||||
|
||||
/**
|
||||
* The Guzzle http client object
|
||||
* @var object $client
|
||||
*/
|
||||
protected $client;
|
||||
|
||||
/**
|
||||
* Cookie jar object for api requests
|
||||
* @var object $cookieJar
|
||||
*/
|
||||
protected $cookieJar;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
$this->cookieJar = new CookieJar();
|
||||
$this->client = new Client([
|
||||
'base_url' => $this->base_url,
|
||||
'defaults' => [
|
||||
'cookies' => $this->cookieJar,
|
||||
'headers' => [
|
||||
'User-Agent' => $_SERVER['HTTP_USER_AGENT'],
|
||||
'Accept-Encoding' => 'application/json'
|
||||
],
|
||||
'timeout' => 5,
|
||||
'connect_timeout' => 5
|
||||
]
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the full url path, since the base_url in Guzzle doesn't work correctly
|
||||
*
|
||||
* @param string $path
|
||||
* @return string
|
||||
*/
|
||||
protected function _url($path)
|
||||
{
|
||||
return "{$this->base_url}{$path}";
|
||||
}
|
||||
|
||||
}
|
||||
// End of BaseApiModel.php
|
@ -1,9 +1,19 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Base class for controllers, defines output methods
|
||||
*/
|
||||
class BaseController {
|
||||
|
||||
/**
|
||||
* The global configuration object
|
||||
* @var object $config
|
||||
*/
|
||||
protected $config;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
global $config;
|
||||
@ -23,7 +33,7 @@ class BaseController {
|
||||
$route = $router->get_route();
|
||||
$data['route_path'] = ($route) ? $router->get_route()->path : "";
|
||||
|
||||
$path = realpath(__DIR__ . "/../views/{$template}.php");
|
||||
$path = _dir(APP_DIR, 'views', "{$template}.php");
|
||||
|
||||
if ( ! is_file($path))
|
||||
{
|
||||
@ -32,6 +42,7 @@ class BaseController {
|
||||
|
||||
ob_start();
|
||||
extract($data);
|
||||
include _dir(APP_DIR, 'views', 'header.php');
|
||||
include $path;
|
||||
$buffer = ob_get_contents();
|
||||
ob_end_clean();
|
||||
@ -57,4 +68,5 @@ class BaseController {
|
||||
header("Content-type: application/json");
|
||||
echo $data;
|
||||
}
|
||||
}
|
||||
}
|
||||
// End of BaseController.php
|
28
app/base/BaseDBModel.php
Normal file
28
app/base/BaseDBModel.php
Normal file
@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Base model for database interaction
|
||||
*/
|
||||
class BaseDBModel extends BaseModel {
|
||||
/**
|
||||
* The query builder object
|
||||
* @var object $db
|
||||
*/
|
||||
protected $db;
|
||||
|
||||
/**
|
||||
* The database connection information array
|
||||
* @var array $db_config
|
||||
*/
|
||||
protected $db_config;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->db_config = $this->config->database;
|
||||
}
|
||||
}
|
||||
// End of BaseDBModel.php
|
@ -1,43 +1,23 @@
|
||||
<?php
|
||||
|
||||
use \GuzzleHttp\Client;
|
||||
use \GuzzleHttp\Cookie\CookieJar;
|
||||
|
||||
/**
|
||||
* Common base for all Models
|
||||
*/
|
||||
class BaseModel {
|
||||
|
||||
protected $client;
|
||||
/**
|
||||
* The global configuration object
|
||||
* @var object $config
|
||||
*/
|
||||
protected $config;
|
||||
protected $cookieJar;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
global $config;
|
||||
|
||||
$this->config = $config;
|
||||
$this->cookieJar = new CookieJar();
|
||||
$this->client = new Client([
|
||||
'base_url' => $this->base_url,
|
||||
'defaults' => [
|
||||
'cookies' => $this->cookieJar,
|
||||
'headers' => [
|
||||
'User-Agent' => $_SERVER['HTTP_USER_AGENT'],
|
||||
'Accept-Encoding' => 'application/json'
|
||||
],
|
||||
'timeout' => 5,
|
||||
'connect_timeout' => 5
|
||||
]
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the full url path, since the base_url in Guzzle doesn't work correctly
|
||||
*
|
||||
* @param string $path
|
||||
* @return string
|
||||
*/
|
||||
protected function _url($path)
|
||||
{
|
||||
return "{$this->base_url}{$path}";
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -2,10 +2,31 @@
|
||||
|
||||
use Aura\Router\RouterFactory;
|
||||
|
||||
/**
|
||||
* Basic routing/ dispatch
|
||||
*/
|
||||
class Router {
|
||||
|
||||
/**
|
||||
* The route-matching object
|
||||
* @var object $router
|
||||
*/
|
||||
protected $router;
|
||||
|
||||
/**
|
||||
* The global configuration object
|
||||
* @var object $config
|
||||
*/
|
||||
protected $config;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
global $config;
|
||||
$this->config = $config;
|
||||
|
||||
$router_factory = new RouterFactory();
|
||||
$router = $router_factory->newInstance();
|
||||
$this->router = $router_factory->newInstance();
|
||||
@ -20,8 +41,17 @@ class Router {
|
||||
*/
|
||||
public function get_route()
|
||||
{
|
||||
//$path = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);
|
||||
$route = $this->router->match($_SERVER['REQUEST_URI'], $_SERVER);
|
||||
global $defaultHandler;
|
||||
|
||||
$raw_route = $_SERVER['REQUEST_URI'];
|
||||
$route_path = str_replace([$this->config->anime_path, $this->config->manga_path], '', $raw_route);
|
||||
$route_path = "/" . trim($route_path, '/');
|
||||
|
||||
$defaultHandler->addDataTable('Route Info', [
|
||||
'route_path' => $route_path
|
||||
]);
|
||||
|
||||
$route = $this->router->match($route_path, $_SERVER);
|
||||
|
||||
return $route;
|
||||
}
|
||||
@ -54,7 +84,6 @@ class Router {
|
||||
'title' => 'Page Not Found'
|
||||
]
|
||||
];
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -69,22 +98,25 @@ class Router {
|
||||
call_user_func_array([$controller, $action_method], $params);
|
||||
}
|
||||
|
||||
/**
|
||||
* Select controller based on the current url, and apply its relevent routes
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function _setup_routes()
|
||||
{
|
||||
$host = $_SERVER['HTTP_HOST'];
|
||||
$route_type = "";
|
||||
switch($host)
|
||||
{
|
||||
case "anime.timshomepage.net":
|
||||
$route_type = "anime";
|
||||
break;
|
||||
$route_type = "anime";
|
||||
|
||||
case "manga.timshomepage.net":
|
||||
$route_type = "manga";
|
||||
break;
|
||||
if ($this->config->manga_host !== "" && strpos($_SERVER['HTTP_HOST'], $this->config->manga_host) !== FALSE)
|
||||
{
|
||||
$route_type = "manga";
|
||||
}
|
||||
else if ($this->config->manga_path !== "" && strpos($_SERVER['REQUEST_URI'], $this->config->manga_path) !== FALSE)
|
||||
{
|
||||
$route_type = "manga";
|
||||
}
|
||||
|
||||
$routes = require __DIR__ . '/../config/routes.php';
|
||||
$routes = $this->config->routes;
|
||||
|
||||
// Add routes by the configuration file
|
||||
foreach($routes[$route_type] as $name => $route)
|
||||
|
@ -1,17 +0,0 @@
|
||||
<?php
|
||||
|
||||
function anime_autoloader($class) {
|
||||
$dirs = ["base", "controllers", "models"];
|
||||
|
||||
foreach($dirs as $dir)
|
||||
{
|
||||
$file = realpath(__DIR__ . "/../{$dir}/{$class}.php");
|
||||
if (file_exists($file))
|
||||
{
|
||||
require_once $file;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
spl_autoload_register('anime_autoloader');
|
47
app/base/functions.php
Normal file
47
app/base/functions.php
Normal file
@ -0,0 +1,47 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Global functions
|
||||
*/
|
||||
|
||||
/**
|
||||
* HTML selection helper function
|
||||
*
|
||||
* @param string $a - First item to compare
|
||||
* @param string $b - Second item to compare
|
||||
* @return string
|
||||
*/
|
||||
function is_selected($a, $b)
|
||||
{
|
||||
return ($a === $b) ? 'selected' : '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate full url path from the route path based on config
|
||||
*
|
||||
* @param string $path - The route path
|
||||
* @param [string] $host - The controller (anime or manga), defaults to anime
|
||||
* @return string
|
||||
*/
|
||||
function full_url($path, $type="anime")
|
||||
{
|
||||
global $config;
|
||||
|
||||
$config_path = $config->{"{$type}_path"};
|
||||
$config_host = $config->{"{$type}_host"};
|
||||
|
||||
// Remove beginning/trailing slashes
|
||||
$config_path = trim($config_path, '/');
|
||||
$path = trim($path, '/');
|
||||
|
||||
$host = ($config_host !== '') ? $config_host : $_SERVER['HTTP_HOST'];
|
||||
|
||||
if ($config_path !== '')
|
||||
{
|
||||
$path = "{$config_path}/{$path}";
|
||||
}
|
||||
|
||||
return "//{$host}/{$path}";
|
||||
}
|
||||
|
||||
// End of functions.php
|
@ -2,8 +2,24 @@
|
||||
return (object)[
|
||||
// Username for feeds
|
||||
'hummingbird_username' => 'timw4mail',
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Routing
|
||||
//
|
||||
// Route by path, or route by domain. To route by path, set the _host suffixed
|
||||
// options to an empty string. To route by host, set the _path suffixed options
|
||||
// to an empty string
|
||||
// ----------------------------------------------------------------------------
|
||||
'anime_host' => 'anime.timshomepage.net',
|
||||
'manga_host' => 'manga.timshomepage.net',
|
||||
'anime_path' => '',
|
||||
'manga_path' => '',
|
||||
|
||||
// Cache paths
|
||||
'data_cache_path' => __DIR__ . '/../cache',
|
||||
'img_cache_path' => __DIR__ .'/../../public/images'
|
||||
'data_cache_path' => _dir(APP_DIR, 'cache'),
|
||||
'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,21 +2,31 @@
|
||||
|
||||
return [
|
||||
'anime' => [
|
||||
'index' => [
|
||||
'path' => '/',
|
||||
'controller' => 'AnimeController'
|
||||
],
|
||||
'all' => [
|
||||
'path' => '/all',
|
||||
'controller' => 'AnimeController',
|
||||
'action' => 'all'
|
||||
'action' => 'anime_list',
|
||||
'params' => [
|
||||
'type' => 'all',
|
||||
'title' => WHOSE . " Anime List · All"
|
||||
]
|
||||
],
|
||||
'index' => [
|
||||
'path' => '/',
|
||||
'controller' => 'AnimeController',
|
||||
'action' => 'anime_list',
|
||||
'params' => [
|
||||
'type' => 'currently-watching',
|
||||
'title' => WHOSE . " Anime List · Watching"
|
||||
]
|
||||
],
|
||||
'plan_to_watch' => [
|
||||
'path' => '/plan_to_watch',
|
||||
'controller' => 'AnimeController',
|
||||
'action' => 'anime_list',
|
||||
'params' => [
|
||||
'type' => 'plan-to-watch'
|
||||
'type' => 'plan-to-watch',
|
||||
'title' => WHOSE . " Anime List · Plan to Watch"
|
||||
]
|
||||
],
|
||||
'on_hold' => [
|
||||
@ -24,7 +34,8 @@ return [
|
||||
'controller' => 'AnimeController',
|
||||
'action' => 'anime_list',
|
||||
'params' => [
|
||||
'type' => 'on-hold'
|
||||
'type' => 'on-hold',
|
||||
'title' => WHOSE . " Anime List · On Hold"
|
||||
]
|
||||
],
|
||||
'dropped' => [
|
||||
@ -32,7 +43,8 @@ return [
|
||||
'controller' => 'AnimeController',
|
||||
'action' => 'anime_list',
|
||||
'params' => [
|
||||
'type' => 'dropped'
|
||||
'type' => 'dropped',
|
||||
'title' => WHOSE . " Anime List · Dropped"
|
||||
]
|
||||
],
|
||||
'completed' => [
|
||||
@ -40,7 +52,8 @@ return [
|
||||
'controller' => 'AnimeController',
|
||||
'action' => 'anime_list',
|
||||
'params' => [
|
||||
'type' => 'completed'
|
||||
'type' => 'completed',
|
||||
'title' => WHOSE . " Anime List · Completed"
|
||||
]
|
||||
],
|
||||
'collection' => [
|
||||
@ -48,29 +61,34 @@ return [
|
||||
'controller' => 'AnimeController',
|
||||
'action' => 'collection',
|
||||
'params' => []
|
||||
],
|
||||
'anime_login' => [
|
||||
'path' => '/login',
|
||||
'controller' => 'AnimeController',
|
||||
'action' => 'login'
|
||||
]
|
||||
],
|
||||
'manga' => [
|
||||
'index' => [
|
||||
'path' => '/',
|
||||
'controller' => 'MangaController'
|
||||
],
|
||||
'all' => [
|
||||
'path' => '/all',
|
||||
'controller' => 'MangaController',
|
||||
'action' => 'all'
|
||||
'action' => 'manga_list',
|
||||
'params' => [
|
||||
'type' => 'all',
|
||||
'title' => WHOSE . " Manga List · All"
|
||||
]
|
||||
],
|
||||
'index' => [
|
||||
'path' => '/',
|
||||
'controller' => 'MangaController',
|
||||
'action' => 'manga_list',
|
||||
'params' => [
|
||||
'type' => 'Reading',
|
||||
'title' => WHOSE . " Manga List · Reading"
|
||||
]
|
||||
],
|
||||
'plan_to_read' => [
|
||||
'path' => '/plan_to_read',
|
||||
'controller' => 'MangaController',
|
||||
'action' => 'manga_list',
|
||||
'params' => [
|
||||
'type' => 'Plan to Read'
|
||||
'type' => 'Plan to Read',
|
||||
'title' => WHOSE . " Manga List · Plan to Read"
|
||||
]
|
||||
],
|
||||
'on_hold' => [
|
||||
@ -78,7 +96,8 @@ return [
|
||||
'controller' => 'MangaController',
|
||||
'action' => 'manga_list',
|
||||
'params' => [
|
||||
'type' => 'On Hold'
|
||||
'type' => 'On Hold',
|
||||
'title' => WHOSE . " Manga List · On Hold"
|
||||
]
|
||||
],
|
||||
'dropped' => [
|
||||
@ -86,7 +105,8 @@ return [
|
||||
'controller' => 'MangaController',
|
||||
'action' => 'manga_list',
|
||||
'params' => [
|
||||
'type' => 'Dropped'
|
||||
'type' => 'Dropped',
|
||||
'title' => WHOSE . " Manga List · Dropped"
|
||||
]
|
||||
],
|
||||
'completed' => [
|
||||
@ -94,7 +114,8 @@ return [
|
||||
'controller' => 'MangaController',
|
||||
'action' => 'manga_list',
|
||||
'params' => [
|
||||
'type' => 'Completed'
|
||||
'type' => 'Completed',
|
||||
'title' => WHOSE . " Manga List · Completed"
|
||||
]
|
||||
],
|
||||
]
|
||||
|
@ -1,10 +1,39 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Controller for Anime-related pages
|
||||
*/
|
||||
class AnimeController extends BaseController {
|
||||
|
||||
/**
|
||||
* The anime list model
|
||||
* @var object $model
|
||||
*/
|
||||
private $model;
|
||||
|
||||
/**
|
||||
* The anime collection model
|
||||
* @var object $collection_model
|
||||
*/
|
||||
private $collection_model;
|
||||
|
||||
/**
|
||||
* Route mapping for main navigation
|
||||
* @var array $nav_routes
|
||||
*/
|
||||
private $nav_routes = [
|
||||
'Watching' => '/',
|
||||
'Plan to Watch' => '/plan_to_watch',
|
||||
'On Hold' => '/on_hold',
|
||||
'Dropped' => '/dropped',
|
||||
'Completed' => '/completed',
|
||||
'Collection' => '/collection',
|
||||
'All' => '/all'
|
||||
];
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
@ -12,35 +41,38 @@ class AnimeController extends BaseController {
|
||||
$this->collection_model = new AnimeCollectionModel();
|
||||
}
|
||||
|
||||
public function index()
|
||||
/**
|
||||
* Show a portion, or all of the anime list
|
||||
*
|
||||
* @param string $type - The section of the list
|
||||
* @param string $title - The title of the page
|
||||
* @return void
|
||||
*/
|
||||
public function anime_list($type, $title)
|
||||
{
|
||||
$this->anime_list('currently-watching');
|
||||
}
|
||||
$data = ($type != 'all')
|
||||
? $this->model->get_list($type)
|
||||
: $this->model->get_all_lists();
|
||||
|
||||
public function all()
|
||||
{
|
||||
$data = $this->model->get_all_lists();
|
||||
$this->outputHTML('anime_list', [
|
||||
'title' => "Tim's Anime List · All",
|
||||
'sections' => $data
|
||||
]);
|
||||
}
|
||||
|
||||
public function anime_list($type, $title="Tim's Anime List")
|
||||
{
|
||||
$data = $this->model->get_list($type);
|
||||
$this->outputHTML('anime_list', [
|
||||
$this->outputHTML('anime/list', [
|
||||
'title' => $title,
|
||||
'nav_routes' => $this->nav_routes,
|
||||
'sections' => $data
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the anime collection page
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function collection()
|
||||
{
|
||||
$data = $this->collection_model->get_collection();
|
||||
|
||||
$this->outputHTML('anime_collection', [
|
||||
'title' => "Tim's Anime Collection",
|
||||
$this->outputHTML('anime/collection', [
|
||||
'title' => WHOSE . " Anime Collection",
|
||||
'nav_routes' => $this->nav_routes,
|
||||
'sections' => $data
|
||||
]);
|
||||
}
|
||||
|
@ -1,42 +1,56 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Controller for manga list
|
||||
*/
|
||||
class MangaController extends BaseController {
|
||||
|
||||
/**
|
||||
* The manga model
|
||||
* @var object $model
|
||||
*/
|
||||
private $model;
|
||||
|
||||
/**
|
||||
* Route mapping for main navigation
|
||||
* @var array $nav_routes
|
||||
*/
|
||||
private $nav_routes = [
|
||||
'Reading' => '/',
|
||||
'Plan to Read' => '/plan_to_read',
|
||||
'On Hold' => '/on_hold',
|
||||
'Dropped' => '/dropped',
|
||||
'Completed' => '/completed',
|
||||
'All' => '/all'
|
||||
];
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->model = new MangaModel();
|
||||
}
|
||||
|
||||
public function index()
|
||||
/**
|
||||
* Get a section of the manga list
|
||||
*
|
||||
* @param string $status
|
||||
* @param string $title
|
||||
* @return void
|
||||
*/
|
||||
public function manga_list($status, $title)
|
||||
{
|
||||
$this->manga_list('Reading');
|
||||
}
|
||||
$data = ($status !== 'all')
|
||||
? [$status => $this->model->get_list($status)]
|
||||
: $this->model->get_all_lists();
|
||||
|
||||
public function all()
|
||||
{
|
||||
$data = $this->model->get_all_lists();
|
||||
$this->outputHTML('manga_list', [
|
||||
'title' => "Tim's Manga List · All",
|
||||
$this->outputHTML('manga/list', [
|
||||
'title' => $title,
|
||||
'nav_routes' => $this->nav_routes,
|
||||
'sections' => $data
|
||||
]);
|
||||
}
|
||||
|
||||
public function manga_list($type, $title="Tim's Manga List")
|
||||
{
|
||||
$data = $this->model->get_list($type);
|
||||
$this->outputHTML('manga_list', [
|
||||
'title' => $title,
|
||||
'sections' => [$type => $data]
|
||||
]);
|
||||
}
|
||||
|
||||
public function login()
|
||||
{
|
||||
$data = $this->model->authenticate();
|
||||
//print_r($data);
|
||||
}
|
||||
}
|
||||
// End of MangaController.php
|
@ -3,21 +3,24 @@
|
||||
/**
|
||||
* Model for getting anime collection data
|
||||
*/
|
||||
class AnimeCollectionModel extends BaseModel {
|
||||
protected $base_url = "";
|
||||
private $db;
|
||||
private $anime_model;
|
||||
private $db_config;
|
||||
class AnimeCollectionModel extends BaseDBModel {
|
||||
|
||||
/**
|
||||
* Anime API Model
|
||||
* @var object $anime_model
|
||||
*/
|
||||
private $anime_model;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->db_config = require_once(__DIR__ . '/../config/database.php');
|
||||
$this->db = Query($this->db_config['collection']);
|
||||
|
||||
$this->anime_model = new AnimeModel();
|
||||
|
||||
parent::__construct();
|
||||
|
||||
$this->db = Query($this->db_config['collection']);
|
||||
$this->anime_model = new AnimeModel();
|
||||
|
||||
// Do an import if an import file exists
|
||||
$this->json_import();
|
||||
}
|
||||
|
@ -3,11 +3,16 @@
|
||||
/**
|
||||
* Model for handling requests dealing with the anime list
|
||||
*/
|
||||
class AnimeModel extends BaseModel {
|
||||
protected $client;
|
||||
protected $cookieJar;
|
||||
class AnimeModel extends BaseApiModel {
|
||||
/**
|
||||
* The base url for api requests
|
||||
* @var string $base_url
|
||||
*/
|
||||
protected $base_url = "https://hummingbird.me/api/v1";
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
@ -134,7 +139,7 @@ class AnimeModel extends BaseModel {
|
||||
$output = $response->json();
|
||||
$output_json = json_encode($output);
|
||||
|
||||
if (file_get_contents($cache_file) !== $output_json)
|
||||
if (( ! file_exists($cache_file)) || file_get_contents($cache_file) !== $output_json)
|
||||
{
|
||||
// Cache the call in case of downtime
|
||||
file_put_contents($cache_file, json_encode($output));
|
||||
|
@ -1,14 +1,17 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Model for handling requests dealing with the manga list
|
||||
*/
|
||||
class MangaModel extends BaseModel {
|
||||
class MangaModel extends BaseApiModel {
|
||||
|
||||
protected $client;
|
||||
protected $cookieJar;
|
||||
/**
|
||||
* @var string $base_url - The base url for api requests
|
||||
*/
|
||||
protected $base_url = "https://hummingbird.me";
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
@ -56,7 +59,7 @@ class MangaModel extends BaseModel {
|
||||
{
|
||||
global $defaultHandler;
|
||||
|
||||
$cache_file = __DIR__ . "/../cache/manga.json";
|
||||
$cache_file = _dir($this->config->data_cache_path, 'manga.json');
|
||||
|
||||
$config = [
|
||||
'query' => [
|
||||
|
@ -1,4 +1,3 @@
|
||||
<?php include 'header.php'; ?>
|
||||
<body>
|
||||
<main>
|
||||
<h1>404</h1>
|
||||
|
@ -1,19 +1,19 @@
|
||||
<?php include 'header.php' ?>
|
||||
<body>
|
||||
<h1>Tim's Anime List [<a href="//manga.timshomepage.net">Manga List</a>]</h1>
|
||||
<?php include 'anime_nav.php' ?>
|
||||
<body class="anime collection">
|
||||
<h1><?= WHOSE ?> Anime Collection [<a href="<?= full_url('', 'manga') ?>">Manga List</a>]</h1>
|
||||
<?php include 'nav.php' ?>
|
||||
<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/anime/<?= $item['slug'] ?>">
|
||||
<article class="media" id="a-<?= $item['hummingbird_id'] ?>">
|
||||
<img src="<?= $item['cover_image'] ?>" />
|
||||
<div class="name"><a href="https://hummingbird.me/anime/<?= $item['slug'] ?>">
|
||||
<div class="name">
|
||||
<?= $item['title'] ?>
|
||||
<?= ($item['alternate_title'] != "") ? "<br />({$item['alternate_title']})" : ""; ?>
|
||||
</a></div>
|
||||
</div>
|
||||
<div class="media_metadata">
|
||||
<div class="completion">Episodes: <?= $item['episode_count'] ?></div>
|
||||
</div>
|
||||
@ -22,6 +22,7 @@
|
||||
<div class="age_rating"><?= $item['age_rating'] ?></div>
|
||||
</div>
|
||||
</article>
|
||||
</a>
|
||||
<?php endforeach ?>
|
||||
</section>
|
||||
</section>
|
@ -1,5 +1,5 @@
|
||||
<body>
|
||||
<?php include 'anime_nav.php' ?>
|
||||
<?php include 'nav.php' ?>
|
||||
<main>
|
||||
<form action="<?= $action ?>" method="post">
|
||||
</form>
|
34
app/views/anime/list.php
Normal file
34
app/views/anime/list.php
Normal file
@ -0,0 +1,34 @@
|
||||
<body class="anime list">
|
||||
<h1><?= WHOSE ?> Anime List [<a href="<?= full_url('', 'manga') ?>">Manga List</a>]</h1>
|
||||
<?php include 'nav.php' ?>
|
||||
<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>
|
||||
</body>
|
||||
</html>
|
7
app/views/anime/nav.php
Normal file
7
app/views/anime/nav.php
Normal file
@ -0,0 +1,7 @@
|
||||
<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>
|
@ -1,33 +0,0 @@
|
||||
<?php include 'header.php' ?>
|
||||
<body>
|
||||
<h1>Tim's Anime List [<a href="//manga.timshomepage.net">Manga List</a>]</h1>
|
||||
<?php include 'anime_nav.php' ?>
|
||||
<main>
|
||||
<?php foreach ($sections as $name => $items): ?>
|
||||
<section class="status">
|
||||
<h2><?= $name ?></h2>
|
||||
<section class="media-wrap">
|
||||
<?php foreach($items as $item): ?>
|
||||
<article class="media" id="a-<?= $item['anime']['id'] ?>">
|
||||
<img src="<?= $item['anime']['cover_image'] ?>" />
|
||||
<div class="name"><a href="<?= $item['anime']['url'] ?>">
|
||||
<?= $item['anime']['title'] ?>
|
||||
<?= ($item['anime']['alternate_title'] != "") ? "<br />({$item['anime']['alternate_title']})" : ""; ?>
|
||||
</a></div>
|
||||
<div class="media_metadata">
|
||||
<div class="airing_status"><?= $item['anime']['status'] ?></div>
|
||||
<div class="user_rating"><?= (int)($item['rating']['value'] * 2) ?> / 10</div>
|
||||
<div class="completion">Episodes: <?= $item['episodes_watched'] ?> / <?= $item['anime']['episode_count'] ?></div>
|
||||
</div>
|
||||
<div class="medium_metadata">
|
||||
<div class="media_type"><?= $item['anime']['show_type'] ?></div>
|
||||
<div class="age_rating"><?= $item['anime']['age_rating'] ?></div>
|
||||
</div>
|
||||
</article>
|
||||
<?php endforeach ?>
|
||||
</section>
|
||||
</section>
|
||||
<?php endforeach ?>
|
||||
</main>
|
||||
</body>
|
||||
</html>
|
@ -1,11 +0,0 @@
|
||||
<nav>
|
||||
<ul>
|
||||
<li class="<?= is_selected('/', $route_path) ?>"><a href="/">Watching</a></li>
|
||||
<li class="<?= is_selected('/plan_to_watch', $route_path) ?>"><a href="/plan_to_watch">Plan to Watch</a></li>
|
||||
<li class="<?= is_selected('/on_hold', $route_path) ?>"><a href="/on_hold">On Hold</a></li>
|
||||
<li class="<?= is_selected('/dropped', $route_path) ?>"><a href="/dropped">Dropped</a></li>
|
||||
<li class="<?= is_selected('/completed', $route_path) ?>"><a href="/completed">Completed</a></li>
|
||||
<li class="<?= is_selected('/collection', $route_path) ?>"><a href="/collection">Collection</a></li>
|
||||
<li class="<?= is_selected('/all', $route_path) ?>"><a href="/all">All</a></li>
|
||||
</ul>
|
||||
</nav>
|
@ -1,28 +1,20 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title><?= $title ?></title>
|
||||
<link rel="stylesheet" href="/public/css/marx.css" />
|
||||
<link rel="stylesheet" href="/public/css/base.css" />
|
||||
<link rel="stylesheet" href="/public/css/manga.css" />
|
||||
</head>
|
||||
<body>
|
||||
<h1>Tim's Manga List [<a href="//anime.timshomepage.net">Anime List</a>]</h1>
|
||||
<?php include 'manga_nav.php' ?>
|
||||
<body class="manga list">
|
||||
<h1><?= WHOSE ?> Manga List [<a href="<?= full_url("", "anime") ?>">Anime List</a>]</h1>
|
||||
<?php include 'nav.php' ?>
|
||||
<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"><a href="https://hummingbird.me/manga/<?= $item['manga']['id'] ?>">
|
||||
<div class="name">
|
||||
<?= $item['manga']['romaji_title'] ?>
|
||||
<?= (isset($item['manga']['english_title'])) ? "<br />({$item['manga']['english_title']})" : ""; ?>
|
||||
</a></div>
|
||||
</div>
|
||||
<div class="media_metadata">
|
||||
<?php /*<div class="airing_status"><?= $item['manga']['status'] ?></div>*/ ?>
|
||||
<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 />
|
||||
@ -33,6 +25,7 @@
|
||||
<div class="media_type"><?= $item['manga']['manga_type'] ?></div>
|
||||
</div> */ ?>
|
||||
</article>
|
||||
</a>
|
||||
<?php endforeach ?>
|
||||
</section>
|
||||
</section>
|
7
app/views/manga/nav.php
Normal file
7
app/views/manga/nav.php
Normal file
@ -0,0 +1,7 @@
|
||||
<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,10 +0,0 @@
|
||||
<nav>
|
||||
<ul>
|
||||
<li class="<?= is_selected('/', $route_path) ?>"><a href="/">Reading</a></li>
|
||||
<li class="<?= is_selected('/plan_to_read', $route_path) ?>"><a href="/plan_to_read">Plan to Read</a></li>
|
||||
<li class="<?= is_selected('/on_hold', $route_path) ?>"><a href="/on_hold">On Hold</a></li>
|
||||
<li class="<?= is_selected('/dropped', $route_path) ?>"><a href="/dropped">Dropped</a></li>
|
||||
<li class="<?= is_selected('/completed', $route_path) ?>"><a href="/completed">Completed</a></li>
|
||||
<li class="<?= is_selected('/all', $route_path) ?>"><a href="/all">All</a></li>
|
||||
</ul>
|
||||
</nav>
|
47
index.php
47
index.php
@ -1,20 +1,47 @@
|
||||
<?php
|
||||
|
||||
require __DIR__ . '/vendor/autoload.php';
|
||||
require __DIR__ . '/app/base/autoloader.php';
|
||||
/**
|
||||
* Joins paths together. Variadic to take an
|
||||
* arbitrary number of arguments
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function _dir() { return implode(DIRECTORY_SEPARATOR, func_get_args()); }
|
||||
|
||||
// Base paths
|
||||
define('ROOT_DIR', __DIR__);
|
||||
define('APP_DIR', _dir(ROOT_DIR, 'app'));
|
||||
define('CONF_DIR', _dir(APP_DIR, 'config'));
|
||||
define('BASE_DIR', _dir(APP_DIR, 'base'));
|
||||
|
||||
// Who's list is it?
|
||||
define('WHOSE', "Tim's");
|
||||
|
||||
// Load config and global functions
|
||||
$config = require _dir(APP_DIR, '/config/config.php');
|
||||
require _dir(BASE_DIR, '/functions.php');
|
||||
|
||||
// Setup autoloaders
|
||||
require _dir(ROOT_DIR, '/vendor/autoload.php');
|
||||
spl_autoload_register(function ($class) {
|
||||
$dirs = ["base", "controllers", "models"];
|
||||
|
||||
foreach($dirs as $dir)
|
||||
{
|
||||
$file = _dir(APP_DIR, $dir, "{$class}.php");
|
||||
if (file_exists($file))
|
||||
{
|
||||
require_once $file;
|
||||
return;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
session_start();
|
||||
|
||||
use \Whoops\Handler\PrettyPageHandler;
|
||||
use \Whoops\Handler\JsonResponseHandler;
|
||||
|
||||
function is_selected($a, $b)
|
||||
{
|
||||
return ($a === $b) ? 'selected' : '';
|
||||
}
|
||||
|
||||
$config = require_once(__DIR__ . '/app/config/config.php');
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Setup error handling
|
||||
// -----------------------------------------------------------------------------
|
||||
@ -36,7 +63,7 @@ $whoops->register();
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
$router = new Router();
|
||||
//$defaultHandler->addDataTable('route', (array)$router->get_route());
|
||||
$defaultHandler->addDataTable('route', (array)$router->get_route());
|
||||
$router->dispatch();
|
||||
|
||||
// End of index.php
|
@ -2,6 +2,22 @@ body {
|
||||
margin: 0.5em;
|
||||
}
|
||||
|
||||
.round_all {
|
||||
border-radius:0.5em;
|
||||
}
|
||||
|
||||
.round_top {
|
||||
border-radius: 0;
|
||||
border-top-right-radius:0.5em;
|
||||
border-top-left-radius:0.5em;
|
||||
}
|
||||
|
||||
.round_bottom {
|
||||
border-radius: 0;
|
||||
border-bottom-right-radius:0.5em;
|
||||
border-bottom-left-radius:0.5em;
|
||||
}
|
||||
|
||||
.media-wrap {
|
||||
text-align:center;
|
||||
margin:0 auto;
|
||||
@ -16,9 +32,6 @@ body {
|
||||
height:319px;
|
||||
margin:0.25em;
|
||||
}
|
||||
.media > img {
|
||||
border-radius:0.5em;
|
||||
}
|
||||
|
||||
.name, .media_type, .airing_status, .user_rating, .completion, .age_rating {
|
||||
text-shadow: 1px 2px 1px rgba(0, 0, 0, 0.85);
|
||||
@ -27,7 +40,7 @@ body {
|
||||
padding:0.25em;
|
||||
text-align:right;
|
||||
}
|
||||
|
||||
|
||||
.media_type, .age_rating {
|
||||
text-align:left;
|
||||
}
|
||||
@ -37,34 +50,22 @@ body {
|
||||
bottom:0;
|
||||
right:0;
|
||||
}
|
||||
|
||||
|
||||
.media > .medium_metadata {
|
||||
position:absolute;
|
||||
bottom: 0;
|
||||
left:0;
|
||||
}
|
||||
|
||||
.media > .media_metadata > .airing_status,
|
||||
.media > .medium_metadata > .media_type
|
||||
{
|
||||
border-top-left-radius: 0.5em;
|
||||
border-top-right-radius: 0.5em;
|
||||
}
|
||||
|
||||
.media > .media_metadata > .completion,
|
||||
.media > .medium_metadata > .age_rating
|
||||
{
|
||||
border-bottom-left-radius: 0.5em;
|
||||
border-bottom-right-radius: 0.5em;
|
||||
}
|
||||
|
||||
.media > .name {
|
||||
border-radius:0.5em;
|
||||
position:absolute;
|
||||
top: 0;
|
||||
}
|
||||
|
||||
.media > .name:hover {
|
||||
.media:hover > .name,
|
||||
.media:hover > .media_metadata > div,
|
||||
.media:hover > .medium_metadata > div
|
||||
{
|
||||
background:rgba(0,0,0,0.9);
|
||||
}
|
||||
|
||||
@ -78,3 +79,28 @@ body {
|
||||
.user_rating::before {
|
||||
content: "Rating: ";
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
Manga-list-specific styles
|
||||
------------------------------------------------------------------------------*/
|
||||
|
||||
.manga .media > .name {
|
||||
padding:0.5em;
|
||||
margin:1em;
|
||||
}
|
||||
|
||||
.manga .media {
|
||||
border:1px solid #ddd;
|
||||
width:200px;
|
||||
height:290px;
|
||||
margin:0.25em;
|
||||
}
|
||||
|
||||
.manga .completion::before {
|
||||
content: "";
|
||||
}
|
||||
|
||||
.manga .media_metadata {
|
||||
padding: 0.25em;
|
||||
margin: 0.75em;
|
||||
}
|
||||
|
@ -1,29 +0,0 @@
|
||||
.media,
|
||||
.media > .name,
|
||||
.media > img,
|
||||
.media > .media_metadata > .user_rating,
|
||||
.media > .media_metadata > .completion
|
||||
{
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
.media > .name {
|
||||
padding:0.5em;
|
||||
margin:1em;
|
||||
}
|
||||
|
||||
.media {
|
||||
border:1px solid #ddd;
|
||||
width:200px;
|
||||
height:290px;
|
||||
margin:0.25em;
|
||||
}
|
||||
|
||||
.completion::before {
|
||||
content: "";
|
||||
}
|
||||
|
||||
.media_metadata {
|
||||
padding: 0.25em;
|
||||
margin: 0.75em;
|
||||
}
|
Loading…
Reference in New Issue
Block a user