Version 5.1 - All the GraphQL #32
@ -54,6 +54,7 @@ class BaseController {
|
|||||||
public function __construct(Config &$config, Array $web)
|
public function __construct(Config &$config, Array $web)
|
||||||
{
|
{
|
||||||
$this->config = $config;
|
$this->config = $config;
|
||||||
|
$this->base_data['config'] = $config;
|
||||||
|
|
||||||
list($request, $response) = $web;
|
list($request, $response) = $web;
|
||||||
$this->request = $request;
|
$this->request = $request;
|
||||||
@ -70,6 +71,24 @@ class BaseController {
|
|||||||
$this->output();
|
$this->output();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a class member
|
||||||
|
*
|
||||||
|
* @param string $key
|
||||||
|
* @return object
|
||||||
|
*/
|
||||||
|
public function __get($key)
|
||||||
|
{
|
||||||
|
$allowed = ['request', 'response', 'config'];
|
||||||
|
|
||||||
|
if (in_array($key, $allowed))
|
||||||
|
{
|
||||||
|
return $this->$key;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the string output of a partial template
|
* Get the string output of a partial template
|
||||||
*
|
*
|
||||||
@ -95,7 +114,7 @@ class BaseController {
|
|||||||
|
|
||||||
if ( ! is_file($template_path))
|
if ( ! is_file($template_path))
|
||||||
{
|
{
|
||||||
throw new Exception("Invalid template : {$path}");
|
throw new InvalidArgumentException("Invalid template : {$path}");
|
||||||
}
|
}
|
||||||
|
|
||||||
ob_start();
|
ob_start();
|
||||||
@ -152,16 +171,9 @@ class BaseController {
|
|||||||
*/
|
*/
|
||||||
public function redirect($url, $code, $type="anime")
|
public function redirect($url, $code, $type="anime")
|
||||||
{
|
{
|
||||||
$url = full_url($url, $type);
|
$url = $this->config->full_url($url, $type);
|
||||||
|
|
||||||
$codes = [
|
$this->response->redirect->to($url, $code);
|
||||||
301 => 'Moved Permanently',
|
|
||||||
302 => 'Found',
|
|
||||||
303 => 'See Other'
|
|
||||||
];
|
|
||||||
|
|
||||||
header("HTTP/1.1 {$code} {$codes[$code]}");
|
|
||||||
header("Location: {$url}");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -189,7 +201,7 @@ class BaseController {
|
|||||||
public function logout()
|
public function logout()
|
||||||
{
|
{
|
||||||
session_destroy();
|
session_destroy();
|
||||||
$this->response->redirect->seeOther(full_url(''));
|
$this->response->redirect->seeOther($this->config->full_url(''));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -228,7 +240,7 @@ class BaseController {
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
$this->response->redirect->afterPost(full_url('', $this->base_data['url_type']));
|
$this->response->redirect->afterPost($this->config->full_url('', $this->base_data['url_type']));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -73,7 +73,7 @@ class BaseModel {
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
throw new Exception("Couldn't cache images because they couldn't be downloaded.");
|
throw new DomainException("Couldn't cache images because they couldn't be downloaded.");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Resize the image
|
// Resize the image
|
||||||
|
@ -52,5 +52,77 @@ class Config {
|
|||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the base url for css/js/images
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
function asset_url(/*...*/)
|
||||||
|
{
|
||||||
|
$args = func_get_args();
|
||||||
|
$base_url = rtrim($this->__get('asset_path'), '/');
|
||||||
|
|
||||||
|
array_unshift($args, $base_url);
|
||||||
|
|
||||||
|
return implode("/", $args);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the base url from the config
|
||||||
|
*
|
||||||
|
* @param string $type - (optional) The controller
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
function base_url($type="anime")
|
||||||
|
{
|
||||||
|
$config_path = trim($this->__get("{$type}_path"), "/");
|
||||||
|
$config_host = $this->__get("{$type}_host");
|
||||||
|
|
||||||
|
// Set the appropriate HTTP host
|
||||||
|
$host = ($config_host !== '') ? $config_host : $_SERVER['HTTP_HOST'];
|
||||||
|
$path = ($config_path !== '') ? $config_path : "";
|
||||||
|
|
||||||
|
return implode("/", ['/', $host, $path]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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")
|
||||||
|
{
|
||||||
|
$config_path = trim($this->__get("{$type}_path"), "/");
|
||||||
|
$config_host = $this->__get("{$type}_host");
|
||||||
|
$config_default_route = $this->__get("default_{$type}_path");
|
||||||
|
|
||||||
|
// Remove beginning/trailing slashes
|
||||||
|
$config_path = trim($config_path, '/');
|
||||||
|
$path = trim($path, '/');
|
||||||
|
|
||||||
|
// Remove any optional parameters from the route
|
||||||
|
$path = preg_replace('`{/.*?}`i', '', $path);
|
||||||
|
|
||||||
|
// Set the appropriate HTTP host
|
||||||
|
$host = ($config_host !== '') ? $config_host : $_SERVER['HTTP_HOST'];
|
||||||
|
|
||||||
|
// Set the default view
|
||||||
|
if ($path === '')
|
||||||
|
{
|
||||||
|
$path .= trim($config_default_route, '/');
|
||||||
|
if ($this->__get('default_to_list_view')) $path .= '/list';
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set an leading folder
|
||||||
|
if ($config_path !== '')
|
||||||
|
{
|
||||||
|
$path = "{$config_path}/{$path}";
|
||||||
|
}
|
||||||
|
|
||||||
|
return "//{$host}/{$path}";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// End of config.php
|
// End of config.php
|
@ -64,7 +64,7 @@ class Router {
|
|||||||
{
|
{
|
||||||
global $defaultHandler;
|
global $defaultHandler;
|
||||||
|
|
||||||
$raw_route = $this->request->server->get('REQUEST_URI');
|
$raw_route = parse_url($this->request->server->get('REQUEST_URI'), \PHP_URL_PATH);
|
||||||
$route_path = str_replace([$this->config->anime_path, $this->config->manga_path], '', $raw_route);
|
$route_path = str_replace([$this->config->anime_path, $this->config->manga_path], '', $raw_route);
|
||||||
$route_path = "/" . trim($route_path, '/');
|
$route_path = "/" . trim($route_path, '/');
|
||||||
|
|
||||||
@ -108,14 +108,14 @@ class Router {
|
|||||||
$failure = $this->router->getFailedRoute();
|
$failure = $this->router->getFailedRoute();
|
||||||
$defaultHandler->addDataTable('failed_route', (array)$failure);
|
$defaultHandler->addDataTable('failed_route', (array)$failure);
|
||||||
|
|
||||||
$controller_name = '\\AnimeClient\\BaseController';
|
/*$controller_name = '\\AnimeClient\\BaseController';
|
||||||
$action_method = 'outputHTML';
|
$action_method = 'outputHTML';
|
||||||
$params = [
|
$params = [
|
||||||
'template' => '404',
|
'template' => '404',
|
||||||
'data' => [
|
'data' => [
|
||||||
'title' => 'Page Not Found'
|
'title' => 'Page Not Found'
|
||||||
]
|
]
|
||||||
];
|
];*/
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -148,7 +148,7 @@ class Router {
|
|||||||
*/
|
*/
|
||||||
public function get_route_type()
|
public function get_route_type()
|
||||||
{
|
{
|
||||||
$route_type = "";
|
$route_type = $this->config->default_list;
|
||||||
|
|
||||||
$host = $this->request->server->get("HTTP_HOST");
|
$host = $this->request->server->get("HTTP_HOST");
|
||||||
$request_uri = $this->request->server->get('REQUEST_URI');
|
$request_uri = $this->request->server->get('REQUEST_URI');
|
||||||
|
@ -38,87 +38,6 @@ function is_not_selected($a, $b)
|
|||||||
return ($a !== $b) ? 'selected' : '';
|
return ($a !== $b) ? 'selected' : '';
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the base url for css/js/images
|
|
||||||
*
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
function asset_url(/*...*/)
|
|
||||||
{
|
|
||||||
global $config;
|
|
||||||
|
|
||||||
$args = func_get_args();
|
|
||||||
$base_url = rtrim($config->asset_path, '/');
|
|
||||||
|
|
||||||
array_unshift($args, $base_url);
|
|
||||||
|
|
||||||
return implode("/", $args);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the base url from the config
|
|
||||||
*
|
|
||||||
* @param string $type - (optional) The controller
|
|
||||||
# @param object $config - (optional) Config
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
function base_url($type="anime", $config=NULL)
|
|
||||||
{
|
|
||||||
if (is_null($config)) global $config;
|
|
||||||
|
|
||||||
|
|
||||||
$config_path = trim($config->{"{$type}_path"}, "/");
|
|
||||||
$config_host = $config->{"{$type}_host"};
|
|
||||||
|
|
||||||
// Set the appropriate HTTP host
|
|
||||||
$host = ($config_host !== '') ? $config_host : $_SERVER['HTTP_HOST'];
|
|
||||||
$path = ($config_path !== '') ? $config_path : "";
|
|
||||||
|
|
||||||
return implode("/", ['/', $host, $path]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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
|
|
||||||
# @param object $config - (optional) Config
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
function full_url($path="", $type="anime", $config=NULL)
|
|
||||||
{
|
|
||||||
if (is_null($config)) global $config;
|
|
||||||
|
|
||||||
$config_path = trim($config->{"{$type}_path"}, "/");
|
|
||||||
$config_host = $config->{"{$type}_host"};
|
|
||||||
$config_default_route = $config->{"default_{$type}_path"};
|
|
||||||
|
|
||||||
// Remove beginning/trailing slashes
|
|
||||||
$config_path = trim($config_path, '/');
|
|
||||||
$path = trim($path, '/');
|
|
||||||
|
|
||||||
// Remove any optional parameters from the route
|
|
||||||
$path = preg_replace('`{/.*?}`i', '', $path);
|
|
||||||
|
|
||||||
// Set the appropriate HTTP host
|
|
||||||
$host = ($config_host !== '') ? $config_host : $_SERVER['HTTP_HOST'];
|
|
||||||
|
|
||||||
// Set the default view
|
|
||||||
if ($path === '')
|
|
||||||
{
|
|
||||||
$path .= trim($config_default_route, '/');
|
|
||||||
if ($config->default_to_list_view) $path .= '/list';
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set an leading folder
|
|
||||||
if ($config_path !== '')
|
|
||||||
{
|
|
||||||
$path = "{$config_path}/{$path}";
|
|
||||||
}
|
|
||||||
|
|
||||||
return "//{$host}/{$path}";
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the last segment of the current url
|
* Get the last segment of the current url
|
||||||
*
|
*
|
||||||
@ -131,4 +50,19 @@ function last_segment()
|
|||||||
return end($segments);
|
return end($segments);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine whether to show the sub-menu
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
function is_view_page()
|
||||||
|
{
|
||||||
|
$blacklist = ['edit', 'add', 'update', 'login', 'logout'];
|
||||||
|
$page_segments = explode("/", $_SERVER['REQUEST_URI']);
|
||||||
|
|
||||||
|
$intersect = array_intersect($page_segments, $blacklist);
|
||||||
|
|
||||||
|
return empty($intersect);
|
||||||
|
}
|
||||||
|
|
||||||
// End of functions.php
|
// End of functions.php
|
@ -32,6 +32,9 @@ $config = [
|
|||||||
'anime_path' => '',
|
'anime_path' => '',
|
||||||
'manga_path' => '',
|
'manga_path' => '',
|
||||||
|
|
||||||
|
// Which list should be the default?
|
||||||
|
'default_list' => 'anime', // anime or manga
|
||||||
|
|
||||||
// Default pages for anime/manga
|
// Default pages for anime/manga
|
||||||
'default_anime_path' => '/watching',
|
'default_anime_path' => '/watching',
|
||||||
'default_manga_path' => '/all',
|
'default_manga_path' => '/all',
|
||||||
|
@ -34,6 +34,12 @@ return [
|
|||||||
'show_message.js',
|
'show_message.js',
|
||||||
'anime_edit.js',
|
'anime_edit.js',
|
||||||
'manga_edit.js'
|
'manga_edit.js'
|
||||||
|
],
|
||||||
|
'collection' => [
|
||||||
|
'lib/jquery.min.js',
|
||||||
|
'lib/jquery.throttle-debounce.js',
|
||||||
|
'lib/jsrender.js',
|
||||||
|
'collection.js'
|
||||||
]
|
]
|
||||||
];
|
];
|
||||||
|
|
||||||
|
@ -33,6 +33,10 @@ return [
|
|||||||
'code' => '301'
|
'code' => '301'
|
||||||
]
|
]
|
||||||
],
|
],
|
||||||
|
'search' => [
|
||||||
|
'path' => '/search',
|
||||||
|
'action' => ['search'],
|
||||||
|
],
|
||||||
'all' => [
|
'all' => [
|
||||||
'path' => '/all{/view}',
|
'path' => '/all{/view}',
|
||||||
'action' => ['anime_list'],
|
'action' => ['anime_list'],
|
||||||
@ -99,14 +103,36 @@ return [
|
|||||||
'view' => '[a-z_]+'
|
'view' => '[a-z_]+'
|
||||||
]
|
]
|
||||||
],
|
],
|
||||||
|
'collection_add_form' => [
|
||||||
|
'path' => '/collection/add',
|
||||||
|
'action' => ['collection_form'],
|
||||||
|
'params' => [],
|
||||||
|
],
|
||||||
|
'collection_edit_form' => [
|
||||||
|
'path' => '/collection/edit/{id}',
|
||||||
|
'action' => ['collection_form'],
|
||||||
|
'tokens' => [
|
||||||
|
'id' => '[0-9]+'
|
||||||
|
]
|
||||||
|
],
|
||||||
|
'collection_add' => [
|
||||||
|
'path' => '/collection/add',
|
||||||
|
'action' => ['collection_add'],
|
||||||
|
'verb' => 'post'
|
||||||
|
],
|
||||||
|
'collection_edit' => [
|
||||||
|
'path' => '/collection/edit',
|
||||||
|
'action' => ['collection_edit'],
|
||||||
|
'verb' => 'post'
|
||||||
|
],
|
||||||
'collection' => [
|
'collection' => [
|
||||||
'path' => '/collection{/view}',
|
'path' => '/collection/view{/view}',
|
||||||
'action' => ['collection'],
|
'action' => ['collection'],
|
||||||
'params' => [],
|
'params' => [],
|
||||||
'tokens' => [
|
'tokens' => [
|
||||||
'view' => '[a-z_]+'
|
'view' => '[a-z_]+'
|
||||||
]
|
]
|
||||||
]
|
],
|
||||||
],
|
],
|
||||||
'manga' => [
|
'manga' => [
|
||||||
'index' => [
|
'index' => [
|
||||||
|
@ -38,7 +38,7 @@ class AnimeController extends BaseController {
|
|||||||
'On Hold' => '/on_hold{/view}',
|
'On Hold' => '/on_hold{/view}',
|
||||||
'Dropped' => '/dropped{/view}',
|
'Dropped' => '/dropped{/view}',
|
||||||
'Completed' => '/completed{/view}',
|
'Completed' => '/completed{/view}',
|
||||||
'Collection' => '/collection{/view}',
|
'Collection' => '/collection/view{/view}',
|
||||||
'All' => '/all{/view}'
|
'All' => '/all{/view}'
|
||||||
];
|
];
|
||||||
|
|
||||||
@ -61,9 +61,21 @@ class AnimeController extends BaseController {
|
|||||||
'url_type' => 'anime',
|
'url_type' => 'anime',
|
||||||
'other_type' => 'manga',
|
'other_type' => 'manga',
|
||||||
'nav_routes' => $this->nav_routes,
|
'nav_routes' => $this->nav_routes,
|
||||||
|
'config' => $this->config,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Search for anime
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function search()
|
||||||
|
{
|
||||||
|
$query = $this->request->query->get('query');
|
||||||
|
$this->outputJSON($this->model->search($query));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Show a portion, or all of the anime list
|
* Show a portion, or all of the anime list
|
||||||
*
|
*
|
||||||
@ -104,10 +116,66 @@ class AnimeController extends BaseController {
|
|||||||
|
|
||||||
$this->outputHTML('anime/' . $view_map[$view], [
|
$this->outputHTML('anime/' . $view_map[$view], [
|
||||||
'title' => WHOSE . " Anime Collection",
|
'title' => WHOSE . " Anime Collection",
|
||||||
'sections' => $data
|
'sections' => $data,
|
||||||
|
'genres' => $this->collection_model->get_genre_list()
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show the anime collection add/edit form
|
||||||
|
*
|
||||||
|
* @param int $id
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function collection_form($id=NULL)
|
||||||
|
{
|
||||||
|
$action = (is_null($id)) ? "Add" : "Edit";
|
||||||
|
|
||||||
|
$this->outputHTML('anime/collection_' . strtolower($action), [
|
||||||
|
'action' => $action,
|
||||||
|
'action_url' => $this->config->full_url("collection/" . strtolower($action)),
|
||||||
|
'title' => WHOSE . " Anime Collection · {$action}",
|
||||||
|
'media_items' => $this->collection_model->get_media_type_list(),
|
||||||
|
'item' => ($action === "Edit") ? $this->collection_model->get($id) : []
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update a collection item
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function collection_edit()
|
||||||
|
{
|
||||||
|
$data = $this->request->post->get();
|
||||||
|
if ( ! array_key_exists('hummingbird_id', $data))
|
||||||
|
{
|
||||||
|
$this->redirect("collection/view", 303, "anime");
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->collection_model->update($data);
|
||||||
|
|
||||||
|
$this->redirect("collection/view", 303, "anime");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a collection item
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function collection_add()
|
||||||
|
{
|
||||||
|
$data = $this->request->post->get();
|
||||||
|
if ( ! array_key_exists('id', $data))
|
||||||
|
{
|
||||||
|
$this->redirect("collection/view", 303, "anime");
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->collection_model->add($data);
|
||||||
|
|
||||||
|
$this->redirect("collection/view", 303, "anime");
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update an anime item
|
* Update an anime item
|
||||||
*
|
*
|
||||||
@ -115,7 +183,7 @@ class AnimeController extends BaseController {
|
|||||||
*/
|
*/
|
||||||
public function update()
|
public function update()
|
||||||
{
|
{
|
||||||
print_r($this->model->update($this->request->post->get()));
|
$this->outputJSON($this->model->update($this->request->post->get()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// End of AnimeController.php
|
// End of AnimeController.php
|
@ -43,6 +43,7 @@ class MangaController extends BaseController {
|
|||||||
parent::__construct($config, $web);
|
parent::__construct($config, $web);
|
||||||
$this->model = new MangaModel($config);
|
$this->model = new MangaModel($config);
|
||||||
$this->base_data = [
|
$this->base_data = [
|
||||||
|
'config' => $this->config,
|
||||||
'url_type' => 'manga',
|
'url_type' => 'manga',
|
||||||
'other_type' => 'anime',
|
'other_type' => 'anime',
|
||||||
'nav_routes' => $this->nav_routes
|
'nav_routes' => $this->nav_routes
|
||||||
|
@ -42,6 +42,49 @@ class AnimeCollectionModel extends BaseDBModel {
|
|||||||
$this->json_import();
|
$this->json_import();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get genres for anime collection items
|
||||||
|
*
|
||||||
|
* @param array $filter
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function get_genre_list($filter=[])
|
||||||
|
{
|
||||||
|
$this->db->select('hummingbird_id, genre')
|
||||||
|
->from('genre_anime_set_link gl')
|
||||||
|
->join('genres g', 'g.id=gl.genre_id', 'left');
|
||||||
|
|
||||||
|
|
||||||
|
if ( ! empty($filter)) $this->db->where_in('hummingbird_id', $filter);
|
||||||
|
|
||||||
|
$query = $this->db->order_by('hummingbird_id')
|
||||||
|
->order_by('genre')
|
||||||
|
->get();
|
||||||
|
|
||||||
|
$output = [];
|
||||||
|
|
||||||
|
foreach($query->fetchAll(\PDO::FETCH_ASSOC) as $row)
|
||||||
|
{
|
||||||
|
$id = $row['hummingbird_id'];
|
||||||
|
$genre = $row['genre'];
|
||||||
|
|
||||||
|
// Empty genre names aren't useful
|
||||||
|
if (empty($genre)) continue;
|
||||||
|
|
||||||
|
|
||||||
|
if (array_key_exists($id, $output))
|
||||||
|
{
|
||||||
|
array_push($output[$id], $genre);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$output[$id] = [$genre];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $output;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get collection from the database, and organize by media type
|
* Get collection from the database, and organize by media type
|
||||||
*
|
*
|
||||||
@ -68,6 +111,42 @@ class AnimeCollectionModel extends BaseDBModel {
|
|||||||
return $collection;
|
return $collection;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get list of media types
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function get_media_type_list()
|
||||||
|
{
|
||||||
|
$output = array();
|
||||||
|
|
||||||
|
$query = $this->db->select('id, type')
|
||||||
|
->from('media')
|
||||||
|
->get();
|
||||||
|
|
||||||
|
foreach($query->fetchAll(\PDO::FETCH_ASSOC) as $row)
|
||||||
|
{
|
||||||
|
$output[$row['id']] = $row['type'];
|
||||||
|
}
|
||||||
|
|
||||||
|
return $output;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get item from collection for editing
|
||||||
|
*
|
||||||
|
* @param int $id
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function get_collection_entry($id)
|
||||||
|
{
|
||||||
|
$query = $this->db->from('anime_set')
|
||||||
|
->where('hummingbird_id', (int) $id)
|
||||||
|
->get();
|
||||||
|
|
||||||
|
return $query->fetch(\PDO::FETCH_ASSOC);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get full collection from the database
|
* Get full collection from the database
|
||||||
*
|
*
|
||||||
@ -87,6 +166,67 @@ class AnimeCollectionModel extends BaseDBModel {
|
|||||||
return $query->fetchAll(\PDO::FETCH_ASSOC);
|
return $query->fetchAll(\PDO::FETCH_ASSOC);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add an item to the anime collection
|
||||||
|
*
|
||||||
|
* @param array $data
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function add($data)
|
||||||
|
{
|
||||||
|
$anime = (object) $this->anime_model->get_anime($data['id']);
|
||||||
|
|
||||||
|
$this->db->set([
|
||||||
|
'hummingbird_id' => $data['id'],
|
||||||
|
'slug' => $anime->slug,
|
||||||
|
'title' => $anime->title,
|
||||||
|
'alternate_title' => $anime->alternate_title,
|
||||||
|
'show_type' => $anime->show_type,
|
||||||
|
'age_rating' => $anime->age_rating,
|
||||||
|
'cover_image' => basename($this->get_cached_image($anime->cover_image, $anime->slug, 'anime')),
|
||||||
|
'episode_count' => $anime->episode_count,
|
||||||
|
'episode_length' => $anime->episode_length,
|
||||||
|
'media_id' => $data['media_id'],
|
||||||
|
'notes' => $data['notes']
|
||||||
|
])->insert('anime_set');
|
||||||
|
|
||||||
|
$this->update_genre($data['id']);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update a collection item
|
||||||
|
*
|
||||||
|
* @param array $data
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function update($data)
|
||||||
|
{
|
||||||
|
// If there's no id to update, don't update
|
||||||
|
if ( ! array_key_exists('hummingbird_id', $data)) return;
|
||||||
|
|
||||||
|
$id = $data['hummingbird_id'];
|
||||||
|
unset($data['hummingbird_id']);
|
||||||
|
|
||||||
|
$this->db->set($data)
|
||||||
|
->where('hummingbird_id', $id)
|
||||||
|
->update('anime_set');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the details of a collection item
|
||||||
|
*
|
||||||
|
* @param int $hummingbird_id
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function get($hummingbird_id)
|
||||||
|
{
|
||||||
|
$query = $this->db->from('anime_set')
|
||||||
|
->where('hummingbird_id', $hummingbird_id)
|
||||||
|
->get();
|
||||||
|
|
||||||
|
return $query->fetch(\PDO::FETCH_ASSOC);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Import anime into collection from a json file
|
* Import anime into collection from a json file
|
||||||
*
|
*
|
||||||
@ -108,7 +248,7 @@ class AnimeCollectionModel extends BaseDBModel {
|
|||||||
'alternate_title' => $item->alternate_title,
|
'alternate_title' => $item->alternate_title,
|
||||||
'show_type' => $item->show_type,
|
'show_type' => $item->show_type,
|
||||||
'age_rating' => $item->age_rating,
|
'age_rating' => $item->age_rating,
|
||||||
'cover_image' => $this->get_cached_image($item->cover_image, $item->slug, 'anime'),
|
'cover_image' => basename($this->get_cached_image($item->cover_image, $item->slug, 'anime')),
|
||||||
'episode_count' => $item->episode_count,
|
'episode_count' => $item->episode_count,
|
||||||
'episode_length' => $item->episode_length
|
'episode_length' => $item->episode_length
|
||||||
])->insert('anime_set');
|
])->insert('anime_set');
|
||||||
@ -122,22 +262,67 @@ class AnimeCollectionModel extends BaseDBModel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update genre information
|
* Update genre information for selected anime
|
||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
private function update_genres()
|
private function update_genre($anime_id)
|
||||||
|
{
|
||||||
|
$genre_info = $this->get_genre_data();
|
||||||
|
extract($genre_info);
|
||||||
|
|
||||||
|
// Get api information
|
||||||
|
$anime = $this->anime_model->get_anime($anime_id);
|
||||||
|
|
||||||
|
foreach($anime['genres'] as $genre)
|
||||||
|
{
|
||||||
|
// Add genres that don't currently exist
|
||||||
|
if ( ! in_array($genre['name'], $genres))
|
||||||
|
{
|
||||||
|
$this->db->set('genre', $genre['name'])
|
||||||
|
->insert('genres');
|
||||||
|
|
||||||
|
$genres[] = $genre['name'];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update link table
|
||||||
|
// Get id of genre to put in link table
|
||||||
|
$flipped_genres = array_flip($genres);
|
||||||
|
|
||||||
|
$insert_array = [
|
||||||
|
'hummingbird_id' => $anime['id'],
|
||||||
|
'genre_id' => $flipped_genres[$genre['name']]
|
||||||
|
];
|
||||||
|
|
||||||
|
if (array_key_exists($anime['id'], $links))
|
||||||
|
{
|
||||||
|
if ( ! in_array($flipped_genres[$genre['name']], $links[$anime['id']]))
|
||||||
|
{
|
||||||
|
$this->db->set($insert_array)->insert('genre_anime_set_link');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$this->db->set($insert_array)->insert('genre_anime_set_link');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get list of existing genres
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
private function get_genre_data()
|
||||||
{
|
{
|
||||||
$genres = [];
|
$genres = [];
|
||||||
$flipped_genres = [];
|
|
||||||
|
|
||||||
$links = [];
|
$links = [];
|
||||||
|
|
||||||
// Get existing genres
|
// Get existing genres
|
||||||
$query = $this->db->select('id, genre')
|
$query = $this->db->select('id, genre')
|
||||||
->from('genres')
|
->from('genres')
|
||||||
->get();
|
->get();
|
||||||
foreach($query->fetchAll(PDO::FETCH_ASSOC) as $genre)
|
foreach($query->fetchAll(\PDO::FETCH_ASSOC) as $genre)
|
||||||
{
|
{
|
||||||
$genres[$genre['id']] = $genre['genre'];
|
$genres[$genre['id']] = $genre['genre'];
|
||||||
}
|
}
|
||||||
@ -146,7 +331,7 @@ class AnimeCollectionModel extends BaseDBModel {
|
|||||||
$query = $this->db->select('hummingbird_id, genre_id')
|
$query = $this->db->select('hummingbird_id, genre_id')
|
||||||
->from('genre_anime_set_link')
|
->from('genre_anime_set_link')
|
||||||
->get();
|
->get();
|
||||||
foreach($query->fetchAll(PDO::FETCH_ASSOC) as $link)
|
foreach($query->fetchAll(\PDO::FETCH_ASSOC) as $link)
|
||||||
{
|
{
|
||||||
if (array_key_exists($link['hummingbird_id'], $links))
|
if (array_key_exists($link['hummingbird_id'], $links))
|
||||||
{
|
{
|
||||||
@ -158,48 +343,25 @@ class AnimeCollectionModel extends BaseDBModel {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return [
|
||||||
|
'genres' => $genres,
|
||||||
|
'links' => $links
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update genre information for the entire collection
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
private function update_genres()
|
||||||
|
{
|
||||||
// Get the anime collection
|
// Get the anime collection
|
||||||
$collection = $this->_get_collection();
|
$collection = $this->_get_collection();
|
||||||
foreach($collection as $anime)
|
foreach($collection as $anime)
|
||||||
{
|
{
|
||||||
// Get api information
|
// Get api information
|
||||||
$api = $this->anime_model->get_anime($anime['hummingbird_id']);
|
$this->update_genre($anime['hummingbird_id']);
|
||||||
|
|
||||||
|
|
||||||
foreach($api['genres'] as $genre)
|
|
||||||
{
|
|
||||||
// Add genres that don't currently exist
|
|
||||||
if ( ! in_array($genre['name'], $genres))
|
|
||||||
{
|
|
||||||
$this->db->set('genre', $genre['name'])
|
|
||||||
->insert('genres');
|
|
||||||
|
|
||||||
$genres[] = $genre['name'];
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Update link table
|
|
||||||
|
|
||||||
// Get id of genre to put in link table
|
|
||||||
$flipped_genres = array_flip($genres);
|
|
||||||
|
|
||||||
$insert_array = [
|
|
||||||
'hummingbird_id' => $anime['hummingbird_id'],
|
|
||||||
'genre_id' => $flipped_genres[$genre['name']]
|
|
||||||
];
|
|
||||||
|
|
||||||
if (array_key_exists($anime['hummingbird_id'], $links))
|
|
||||||
{
|
|
||||||
if ( ! in_array($flipped_genres[$genre['name']], $links[$anime['hummingbird_id']]))
|
|
||||||
{
|
|
||||||
$this->db->set($insert_array)->insert('genre_anime_set_link');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
$this->db->set($insert_array)->insert('genre_anime_set_link');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -157,7 +157,7 @@ class AnimeModel extends BaseApiModel {
|
|||||||
|
|
||||||
if ($response->getStatusCode() != 200)
|
if ($response->getStatusCode() != 200)
|
||||||
{
|
{
|
||||||
throw new Exception($response->getEffectiveUrl());
|
throw new RuntimeException($response->getEffectiveUrl());
|
||||||
}
|
}
|
||||||
|
|
||||||
return $response->json();
|
return $response->json();
|
||||||
@ -192,7 +192,7 @@ class AnimeModel extends BaseApiModel {
|
|||||||
{
|
{
|
||||||
if ( ! file_exists($cache_file))
|
if ( ! file_exists($cache_file))
|
||||||
{
|
{
|
||||||
throw new Exception($response->getEffectiveUrl());
|
throw new DomainException($response->getEffectiveUrl());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -101,7 +101,7 @@ class MangaModel extends BaseApiModel {
|
|||||||
{
|
{
|
||||||
if ( ! file_exists($cache_file))
|
if ( ! file_exists($cache_file))
|
||||||
{
|
{
|
||||||
throw new Exception($response->getEffectiveUrl());
|
throw new DomainException($response->getEffectiveUrl());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -124,7 +124,7 @@ class MangaModel extends BaseApiModel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Bail out early if there isn't any manga data
|
// Bail out early if there isn't any manga data
|
||||||
if (empty($raw_data)) return [];
|
if ( ! array_key_exists('manga', $raw_data)) return [];
|
||||||
|
|
||||||
$data = [
|
$data = [
|
||||||
'Reading' => [],
|
'Reading' => [],
|
||||||
@ -174,8 +174,6 @@ class MangaModel extends BaseApiModel {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//file_put_contents(_dir($this->config->data_cache_path, "manga-processed.json"), json_encode($data, JSON_PRETTY_PRINT));
|
|
||||||
|
|
||||||
return (array_key_exists($status, $data)) ? $data[$status] : $data;
|
return (array_key_exists($status, $data)) ? $data[$status] : $data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,15 +1,22 @@
|
|||||||
<main>
|
<main>
|
||||||
|
<?php if (is_logged_in()): ?>
|
||||||
|
[<a href="<?= $config->full_url('collection/add', 'anime') ?>">Add Item</a>]
|
||||||
|
<?php endif ?>
|
||||||
|
<?php if (empty($sections)): ?>
|
||||||
|
<h3>There's nothing here!</h3>
|
||||||
|
<?php else: ?>
|
||||||
<?php foreach ($sections as $name => $items): ?>
|
<?php foreach ($sections as $name => $items): ?>
|
||||||
<section class="status">
|
<section class="status">
|
||||||
<h2><?= $name ?></h2>
|
<h2><?= $name ?></h2>
|
||||||
<section class="media-wrap">
|
<section class="media-wrap">
|
||||||
<?php foreach($items as $item): ?>
|
<?php foreach($items as $item): ?>
|
||||||
<a href="https://hummingbird.me/anime/<?= $item['slug'] ?>">
|
|
||||||
<article class="media" id="a-<?= $item['hummingbird_id'] ?>">
|
<article class="media" id="a-<?= $item['hummingbird_id'] ?>">
|
||||||
<img src="<?= $item['cover_image'] ?>" />
|
<img src="<?= $config->asset_url('images', 'anime', basename($item['cover_image'])) ?>" />
|
||||||
<div class="name">
|
<div class="name">
|
||||||
|
<a href="https://hummingbird.me/anime/<?= $item['slug'] ?>">
|
||||||
<?= $item['title'] ?>
|
<?= $item['title'] ?>
|
||||||
<?= ($item['alternate_title'] != "") ? "<br />({$item['alternate_title']})" : ""; ?>
|
<?= ($item['alternate_title'] != "") ? "<br />({$item['alternate_title']})" : ""; ?>
|
||||||
|
</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="table">
|
<div class="table">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
@ -18,11 +25,14 @@
|
|||||||
<div class="age_rating"><?= $item['age_rating'] ?></div>
|
<div class="age_rating"><?= $item['age_rating'] ?></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</article>
|
</article>
|
||||||
</a>
|
|
||||||
|
<?php if (is_logged_in()): ?>
|
||||||
|
<span>[<a href="<?= $config->full_url("collection/edit/{$item['hummingbird_id']}", "anime") ?>">Edit</a>]</span>
|
||||||
|
<?php endif ?>
|
||||||
<?php endforeach ?>
|
<?php endforeach ?>
|
||||||
</section>
|
</section>
|
||||||
</section>
|
</section>
|
||||||
<?php endforeach ?>
|
<?php endforeach ?>
|
||||||
|
<?php endif ?>
|
||||||
</main>
|
</main>
|
38
app/views/anime/collection_add.php
Normal file
38
app/views/anime/collection_add.php
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
<?php if (is_logged_in()): ?>
|
||||||
|
<main>
|
||||||
|
<form action="<?= $action_url ?>" method="post">
|
||||||
|
<dl>
|
||||||
|
<dt>Series</dt>
|
||||||
|
<dd><label>Search for anime name: <input type="search" id="search" /></label></dd>
|
||||||
|
<dd>
|
||||||
|
<section id="series_list" class="media-wrap">
|
||||||
|
</section>
|
||||||
|
</dd>
|
||||||
|
|
||||||
|
<dt><label for="media_id">Media</label></dt>
|
||||||
|
<dd>
|
||||||
|
<select name="media_id" id="media_id">
|
||||||
|
<?php foreach($media_items as $id => $name): ?>
|
||||||
|
<option value="<?= $id ?>"><?= $name ?></option>
|
||||||
|
<?php endforeach ?>
|
||||||
|
</select>
|
||||||
|
</dd>
|
||||||
|
|
||||||
|
<dt><label for="notes">Notes</label></dt>
|
||||||
|
<dd><textarea id="notes" name="notes"></textarea></dd>
|
||||||
|
|
||||||
|
<dt> </dt>
|
||||||
|
<dd>
|
||||||
|
<button type="submit">Save</button>
|
||||||
|
</dd>
|
||||||
|
</dl>
|
||||||
|
</form>
|
||||||
|
</main>
|
||||||
|
<template id="show_list">
|
||||||
|
<article class="media">
|
||||||
|
<div class="name"><label><input type="radio" name="id" value="{{:id}}" /> <span>{{:title}}<br />{{:alternate_title}}</span></label></div>
|
||||||
|
<img src="{{:cover_image}}" alt="{{:title}}" />
|
||||||
|
</article>
|
||||||
|
</template>
|
||||||
|
<script src="<?= $config->asset_url('js.php?g=collection&debug=1') ?>"></script>
|
||||||
|
<?php endif ?>
|
@ -0,0 +1,37 @@
|
|||||||
|
<?php if (is_logged_in()): ?>
|
||||||
|
<main>
|
||||||
|
<form action="<?= $action_url ?>" method="post">
|
||||||
|
<dl>
|
||||||
|
<h2><?= $item['title'] ?></h2>
|
||||||
|
<h3><?= $item['alternate_title'] ?></h3>
|
||||||
|
|
||||||
|
<dt><label for="media_id">Media</label></dt>
|
||||||
|
<dd>
|
||||||
|
<select name="media_id" id="media_id">
|
||||||
|
<?php foreach($media_items as $id => $name): ?>
|
||||||
|
<option <?= $item['media_id'] == $id ? 'selected="selected"' : '' ?> value="<?= $id ?>"><?= $name ?></option>
|
||||||
|
<?php endforeach ?>
|
||||||
|
</select>
|
||||||
|
</dd>
|
||||||
|
|
||||||
|
<dt><label for="notes">Notes</label></dt>
|
||||||
|
<dd><textarea id="notes" name="notes"><?= $item['notes'] ?></textarea></dd>
|
||||||
|
|
||||||
|
<dt> </dt>
|
||||||
|
<dd>
|
||||||
|
<?php if($action === 'Edit'): ?>
|
||||||
|
<input type="hidden" name="hummingbird_id" value="<?= $item['hummingbird_id'] ?>" />
|
||||||
|
<?php endif ?>
|
||||||
|
<button type="submit">Save</button>
|
||||||
|
</dd>
|
||||||
|
</dl>
|
||||||
|
</form>
|
||||||
|
</main>
|
||||||
|
<template id="show_list">
|
||||||
|
<article class="media">
|
||||||
|
<div class="name"><label><input type="radio" name="id" value="{{:id}}" /> <span>{{:title}}<br />{{:alternate_title}}</span></label></div>
|
||||||
|
<img src="{{:cover_image}}" alt="{{:title}}" />
|
||||||
|
</article>
|
||||||
|
</template>
|
||||||
|
<script src="<?= $config->asset_url('js.php?g=collection&debug=1') ?>"></script>
|
||||||
|
<?php endif ?>
|
@ -1,16 +1,25 @@
|
|||||||
<main>
|
<main>
|
||||||
|
<?php if (is_logged_in()): ?>
|
||||||
|
[<a href="<?= $config->full_url('collection/add', 'anime') ?>">Add Item</a>]
|
||||||
|
<?php endif ?>
|
||||||
|
<?php if (empty($sections)): ?>
|
||||||
|
<h3>There's nothing here!</h3>
|
||||||
|
<?php else: ?>
|
||||||
<?php foreach ($sections as $name => $items): ?>
|
<?php foreach ($sections as $name => $items): ?>
|
||||||
<h2><?= $name ?></h2>
|
<h2><?= $name ?></h2>
|
||||||
<table>
|
<table>
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th>Title</th>
|
<th>Title</th>
|
||||||
<th>Alternate Title</th>
|
<?php /*<th>Alternate Title</th>*/ ?>
|
||||||
<th>Episode Count</th>
|
<th>Episode Count</th>
|
||||||
<th>Episode Length</th>
|
<th>Episode Length</th>
|
||||||
<th>Show Type</th>
|
<th>Show Type</th>
|
||||||
<th>Age Rating</th>
|
<th>Age Rating</th>
|
||||||
<th>Notes</th>
|
<th>Notes</th>
|
||||||
|
<?php if (is_logged_in()): ?>
|
||||||
|
<th> </th>
|
||||||
|
<?php endif ?>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
@ -20,24 +29,28 @@
|
|||||||
<a href="https://hummingbird.me/anime/<?= $item['slug'] ?>">
|
<a href="https://hummingbird.me/anime/<?= $item['slug'] ?>">
|
||||||
<?= $item['title'] ?>
|
<?= $item['title'] ?>
|
||||||
</a>
|
</a>
|
||||||
|
<?= ( ! empty($item['alternate_title'])) ? " · " . $item['alternate_title'] : "" ?>
|
||||||
</td>
|
</td>
|
||||||
<td class="align_left"><?= $item['alternate_title'] ?></td>
|
<?php /*<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_count'] ?></td>
|
||||||
<td><?= $item['episode_length'] ?></td>
|
<td><?= $item['episode_length'] ?></td>
|
||||||
<td><?= $item['show_type'] ?></td>
|
<td><?= $item['show_type'] ?></td>
|
||||||
<td><?= $item['age_rating'] ?></td>
|
<td><?= $item['age_rating'] ?></td>
|
||||||
<td class="align_left"><?= $item['notes'] ?></td>
|
<td class="align_left"><?= $item['notes'] ?></td>
|
||||||
|
<?php if (is_logged_in()): ?>
|
||||||
|
<td>[<a href="<?= $config->full_url("collection/edit/{$item['hummingbird_id']}", "anime") ?>">Edit</a>]</td>
|
||||||
|
<?php endif ?>
|
||||||
</tr>
|
</tr>
|
||||||
<?php endforeach ?>
|
<?php endforeach ?>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
<br />
|
<br />
|
||||||
<?php endforeach ?>
|
<?php endforeach ?>
|
||||||
|
<?php endif ?>
|
||||||
</main>
|
</main>
|
||||||
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
|
<script src="<?= $config->asset_url('js.php?g=table') ?>"></script>
|
||||||
<script src="/public/js/table_sorter/jquery.tablesorter.min.js"></script>
|
|
||||||
<script>
|
|
||||||
$(function() {
|
|
||||||
$('table').tablesorter();
|
|
||||||
});
|
|
||||||
</script>
|
|
@ -1,4 +1,7 @@
|
|||||||
<main>
|
<main>
|
||||||
|
<?php if (empty($sections)): ?>
|
||||||
|
<h3>There's nothing here!</h3>
|
||||||
|
<?php else: ?>
|
||||||
<?php foreach ($sections as $name => $items): ?>
|
<?php foreach ($sections as $name => $items): ?>
|
||||||
<section class="status">
|
<section class="status">
|
||||||
<h2><?= $name ?></h2>
|
<h2><?= $name ?></h2>
|
||||||
@ -34,7 +37,8 @@
|
|||||||
</section>
|
</section>
|
||||||
</section>
|
</section>
|
||||||
<?php endforeach ?>
|
<?php endforeach ?>
|
||||||
|
<?php endif ?>
|
||||||
</main>
|
</main>
|
||||||
<?php if (is_logged_in()): ?>
|
<?php if (is_logged_in()): ?>
|
||||||
<script src="<?= asset_url('js.php?g=edit') ?>"></script>
|
<script src="<?= $config->asset_url('js.php?g=edit') ?>"></script>
|
||||||
<?php endif ?>
|
<?php endif ?>
|
||||||
|
@ -1,4 +1,7 @@
|
|||||||
<main>
|
<main>
|
||||||
|
<?php if (empty($sections)): ?>
|
||||||
|
<h3>There's nothing here!</h3>
|
||||||
|
<?php else: ?>
|
||||||
<?php foreach ($sections as $name => $items): ?>
|
<?php foreach ($sections as $name => $items): ?>
|
||||||
<h2><?= $name ?></h2>
|
<h2><?= $name ?></h2>
|
||||||
<table>
|
<table>
|
||||||
@ -11,6 +14,7 @@
|
|||||||
<th>Type</th>
|
<th>Type</th>
|
||||||
<th>Progress</th>
|
<th>Progress</th>
|
||||||
<th>Rated</th>
|
<th>Rated</th>
|
||||||
|
<th>Genres</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
@ -27,10 +31,17 @@
|
|||||||
<td><?= $item['anime']['show_type'] ?></td>
|
<td><?= $item['anime']['show_type'] ?></td>
|
||||||
<td>Episodes: <?= $item['episodes_watched'] ?> / <?= $item['anime']['episode_count'] ?></td>
|
<td>Episodes: <?= $item['episodes_watched'] ?> / <?= $item['anime']['episode_count'] ?></td>
|
||||||
<td><?= $item['anime']['age_rating'] ?></td>
|
<td><?= $item['anime']['age_rating'] ?></td>
|
||||||
|
<td class="flex flex-justify-space-around align-left">
|
||||||
|
<?php sort($item['anime']['genres']) ?>
|
||||||
|
<?php foreach($item['anime']['genres'] as $genre): ?>
|
||||||
|
<span><?= $genre['name'] ?></span>
|
||||||
|
<?php endforeach ?>
|
||||||
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<?php endforeach ?>
|
<?php endforeach ?>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
<?php endforeach ?>
|
<?php endforeach ?>
|
||||||
|
<?php endif ?>
|
||||||
</main>
|
</main>
|
||||||
<script src="<?= asset_url('js.php?g=table') ?>"></script>
|
<script src="<?= $config->asset_url('js.php?g=table') ?>"></script>
|
@ -3,24 +3,24 @@
|
|||||||
<head>
|
<head>
|
||||||
<title><?= $title ?></title>
|
<title><?= $title ?></title>
|
||||||
<meta charset="utf-8" />
|
<meta charset="utf-8" />
|
||||||
<link rel="stylesheet" href="<?= asset_url('css.php?g=base') ?>" />
|
<link rel="stylesheet" href="<?= $config->asset_url('css.php?g=base') ?>" />
|
||||||
<script>
|
<script>
|
||||||
var BASE_URL = "<?= base_url($url_type) ?>";
|
var BASE_URL = "<?= $config->base_url($url_type) ?>";
|
||||||
var CONTROLLER = "<?= $url_type ?>";
|
var CONTROLLER = "<?= $url_type ?>";
|
||||||
</script>
|
</script>
|
||||||
</head>
|
</head>
|
||||||
<body class="<?= $url_type ?> list">
|
<body class="<?= $url_type ?> list">
|
||||||
<h1 class="flex flex-align-end flex-wrap">
|
<h1 class="flex flex-align-end flex-wrap">
|
||||||
<span class="flex-no-wrap grow-1">
|
<span class="flex-no-wrap grow-1">
|
||||||
<a href="<?= full_url("", $url_type) ?>">
|
<a href="<?= $config->full_url("", $url_type) ?>">
|
||||||
<?= WHOSE ?> <?= ucfirst($url_type) ?> <?= (strpos($route_path, 'collection') !== FALSE) ? 'Collection' : 'List' ?>
|
<?= WHOSE ?> <?= ucfirst($url_type) ?> <?= (strpos($route_path, 'collection') !== FALSE) ? 'Collection' : 'List' ?>
|
||||||
</a> [<a href="<?= full_url("", $other_type) ?>"><?= ucfirst($other_type) ?> List</a>]
|
</a> [<a href="<?= $config->full_url("", $other_type) ?>"><?= ucfirst($other_type) ?> List</a>]
|
||||||
</span>
|
</span>
|
||||||
<span class="flex-no-wrap small-font">
|
<span class="flex-no-wrap small-font">
|
||||||
<?php if (is_logged_in()): ?>
|
<?php if (is_logged_in()): ?>
|
||||||
[<a href="<?= full_url("/logout", $url_type) ?>">Logout</a>]
|
[<a href="<?= $config->full_url("/logout", $url_type) ?>">Logout</a>]
|
||||||
<?php else: ?>
|
<?php else: ?>
|
||||||
[<a href="<?= full_url("/login", $url_type) ?>"><?= WHOSE ?> Login</a>]
|
[<a href="<?= $config->full_url("/login", $url_type) ?>"><?= WHOSE ?> Login</a>]
|
||||||
<?php endif ?>
|
<?php endif ?>
|
||||||
</span>
|
</span>
|
||||||
</h1>
|
</h1>
|
||||||
@ -28,14 +28,16 @@
|
|||||||
<nav>
|
<nav>
|
||||||
<ul>
|
<ul>
|
||||||
<?php foreach($nav_routes as $title => $nav_path): ?>
|
<?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>
|
<li class="<?= is_selected($nav_path, $route_path) ?>"><a href="<?= $config->full_url($nav_path, $url_type) ?>"><?= $title ?></a></li>
|
||||||
<?php endforeach ?>
|
<?php endforeach ?>
|
||||||
</ul>
|
</ul>
|
||||||
|
<?php if (is_view_page()): ?>
|
||||||
<br />
|
<br />
|
||||||
<ul>
|
<ul>
|
||||||
<li class="<?= is_not_selected('list', last_segment()) ?>"><a href="<?= full_url($route_path, $url_type) ?>">Cover View</a></li>
|
<li class="<?= is_not_selected('list', last_segment()) ?>"><a href="<?= $config->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>
|
<li class="<?= is_selected('list', last_segment()) ?>"><a href="<?= $config->full_url("{$route_path}/list", $url_type) ?>">List View</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
|
<?php endif ?>
|
||||||
</nav>
|
</nav>
|
||||||
<br />
|
<br />
|
||||||
<?php endif ?>
|
<?php endif ?>
|
@ -1,7 +1,7 @@
|
|||||||
<main>
|
<main>
|
||||||
<?= $message ?>
|
<?= $message ?>
|
||||||
<aside>
|
<aside>
|
||||||
<form method="post" action="<?= full_url('/login', $url_type) ?>">
|
<form method="post" action="<?= $config->full_url('/login', $url_type) ?>">
|
||||||
<dl>
|
<dl>
|
||||||
<?php /*<dt><label for="username">Username: </label></dt>
|
<?php /*<dt><label for="username">Username: </label></dt>
|
||||||
<dd><input type="text" id="username" name="username" required="required" /></dd>*/ ?>
|
<dd><input type="text" id="username" name="username" required="required" /></dd>*/ ?>
|
||||||
@ -10,7 +10,7 @@
|
|||||||
<dd><input type="password" id="password" name="password" required="required" /></dd>
|
<dd><input type="password" id="password" name="password" required="required" /></dd>
|
||||||
|
|
||||||
<dt> </dt>
|
<dt> </dt>
|
||||||
<dd><input type="submit" value="Login" /></dd>
|
<dd><button type="submit">Login</button></dd>
|
||||||
</dl>
|
</dl>
|
||||||
</form>
|
</form>
|
||||||
</aside>
|
</aside>
|
||||||
|
@ -1,4 +1,7 @@
|
|||||||
<main>
|
<main>
|
||||||
|
<?php if (empty($sections)): ?>
|
||||||
|
<h3>There's nothing here!</h3>
|
||||||
|
<?php else: ?>
|
||||||
<?php foreach ($sections as $name => $items): ?>
|
<?php foreach ($sections as $name => $items): ?>
|
||||||
<section class="status">
|
<section class="status">
|
||||||
<h2><?= $name ?></h2>
|
<h2><?= $name ?></h2>
|
||||||
@ -43,7 +46,8 @@
|
|||||||
</section>
|
</section>
|
||||||
</section>
|
</section>
|
||||||
<?php endforeach ?>
|
<?php endforeach ?>
|
||||||
|
<?php endif ?>
|
||||||
</main>
|
</main>
|
||||||
<?php if (is_logged_in()): ?>
|
<?php if (is_logged_in()): ?>
|
||||||
<script src="<?= asset_url('js.php?g=edit') ?>"></script>
|
<script src="<?= $config->asset_url('js.php?g=edit') ?>"></script>
|
||||||
<?php endif ?>
|
<?php endif ?>
|
@ -1,4 +1,7 @@
|
|||||||
<main>
|
<main>
|
||||||
|
<?php if (empty($sections)): ?>
|
||||||
|
<h3>There's nothing here!</h3>
|
||||||
|
<?php else: ?>
|
||||||
<?php foreach ($sections as $name => $items): ?>
|
<?php foreach ($sections as $name => $items): ?>
|
||||||
<h2><?= $name ?></h2>
|
<h2><?= $name ?></h2>
|
||||||
<table>
|
<table>
|
||||||
@ -29,5 +32,6 @@
|
|||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
<?php endforeach ?>
|
<?php endforeach ?>
|
||||||
|
<?php endif ?>
|
||||||
</main>
|
</main>
|
||||||
<script src="<?= asset_url('js.php?g=table') ?>"></script>
|
<script src="<?= $config->asset_url('js.php?g=table') ?>"></script>
|
@ -1,3 +1,7 @@
|
|||||||
|
template {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
body {
|
body {
|
||||||
margin: 0.5em;
|
margin: 0.5em;
|
||||||
}
|
}
|
||||||
@ -35,8 +39,22 @@ tbody > tr:nth-child(odd) {
|
|||||||
align-items: flex-end;
|
align-items: flex-end;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.flex-align-space-around {
|
||||||
|
-webkit-align-content: space-around;
|
||||||
|
-ms-flex-line-pack: distribute;
|
||||||
|
align-content: space-around;
|
||||||
|
}
|
||||||
|
|
||||||
.flex-justify-space-around {
|
.flex-justify-space-around {
|
||||||
jusify-content: space-around;
|
-webkit-justify-content: space-around;
|
||||||
|
-ms-flex-pack: distribute;
|
||||||
|
justify-content: space-around;
|
||||||
|
}
|
||||||
|
|
||||||
|
.flex-self-center {
|
||||||
|
-webkit-align-self: center;
|
||||||
|
-ms-flex-item-align: center;
|
||||||
|
align-self: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.flex {
|
.flex {
|
||||||
@ -49,6 +67,10 @@ tbody > tr:nth-child(odd) {
|
|||||||
font-size: 1.6rem;
|
font-size: 1.6rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.align_center {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
.align_left {
|
.align_left {
|
||||||
text-align: left;
|
text-align: left;
|
||||||
}
|
}
|
||||||
@ -57,22 +79,6 @@ tbody > tr:nth-child(odd) {
|
|||||||
text-align: right;
|
text-align: right;
|
||||||
}
|
}
|
||||||
|
|
||||||
.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 {
|
.media-wrap {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
|
@ -3,12 +3,11 @@
|
|||||||
--title-overlay: rgba(0, 0, 0, 0.45);
|
--title-overlay: rgba(0, 0, 0, 0.45);
|
||||||
--text-color: #ffffff;
|
--text-color: #ffffff;
|
||||||
--normal-padding: 0.25em;
|
--normal-padding: 0.25em;
|
||||||
--radius: 0.5em;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
body {
|
template {display:none}
|
||||||
margin: 0.5em;
|
|
||||||
}
|
body {margin: 0.5em;}
|
||||||
|
|
||||||
table {
|
table {
|
||||||
width:85%;
|
width:85%;
|
||||||
@ -23,36 +22,18 @@ tbody > tr:nth-child(odd) {
|
|||||||
.flex-wrap {flex-wrap: wrap}
|
.flex-wrap {flex-wrap: wrap}
|
||||||
.flex-no-wrap {flex-wrap: nowrap}
|
.flex-no-wrap {flex-wrap: nowrap}
|
||||||
.flex-align-end {align-items: flex-end}
|
.flex-align-end {align-items: flex-end}
|
||||||
.flex-justify-space-around {jusify-content: space-around}
|
.flex-align-space-around {align-content: space-around}
|
||||||
|
.flex-justify-space-around {justify-content: space-around}
|
||||||
|
.flex-self-center {align-self:center}
|
||||||
.flex {display: flex}
|
.flex {display: flex}
|
||||||
|
|
||||||
.small-font {
|
.small-font {
|
||||||
font-size:1.6rem;
|
font-size:1.6rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.align_left {
|
.align_center {text-align:center}
|
||||||
text-align:left;
|
.align_left {text-align:left;}
|
||||||
}
|
.align_right {text-align:right;}
|
||||||
|
|
||||||
.align_right {
|
|
||||||
text-align:right;
|
|
||||||
}
|
|
||||||
|
|
||||||
.round_all {
|
|
||||||
border-radius:var(--radius);
|
|
||||||
}
|
|
||||||
|
|
||||||
.round_top {
|
|
||||||
border-radius: 0;
|
|
||||||
border-top-right-radius:var(--radius);
|
|
||||||
border-top-left-radius:var(--radius);
|
|
||||||
}
|
|
||||||
|
|
||||||
.round_bottom {
|
|
||||||
border-radius: 0;
|
|
||||||
border-bottom-right-radius:var(--radius);
|
|
||||||
border-bottom-left-radius:var(--radius);
|
|
||||||
}
|
|
||||||
|
|
||||||
.media-wrap {
|
.media-wrap {
|
||||||
text-align:center;
|
text-align:center;
|
||||||
|
@ -40,7 +40,7 @@ function get_files()
|
|||||||
foreach($groups[$_GET['g']] as $file)
|
foreach($groups[$_GET['g']] as $file)
|
||||||
{
|
{
|
||||||
$new_file = realpath($js_root.$file);
|
$new_file = realpath($js_root.$file);
|
||||||
$js .= file_get_contents($new_file);
|
$js .= file_get_contents($new_file) . "\n\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
return $js;
|
return $js;
|
||||||
@ -57,14 +57,32 @@ function get_files()
|
|||||||
*/
|
*/
|
||||||
function google_min($new_file)
|
function google_min($new_file)
|
||||||
{
|
{
|
||||||
|
$options = [
|
||||||
|
'output_info' => 'compiled_code',
|
||||||
|
'output_format' => 'json',
|
||||||
|
'compilation_level' => 'SIMPLE_OPTIMIZATIONS',
|
||||||
|
'js_code' => urlencode($new_file),
|
||||||
|
'warning_level' => 'QUIET',
|
||||||
|
'language' => 'ECMASCRIPT5'
|
||||||
|
];
|
||||||
|
|
||||||
|
$option_pairs = [];
|
||||||
|
foreach($options as $key => $value)
|
||||||
|
{
|
||||||
|
$option_pairs[] = "{$key}={$value}";
|
||||||
|
}
|
||||||
|
$option_string = implode("&", $option_pairs);
|
||||||
|
|
||||||
//Get a much-minified version from Google's closure compiler
|
//Get a much-minified version from Google's closure compiler
|
||||||
$ch = curl_init('http://closure-compiler.appspot.com/compile');
|
$ch = curl_init('http://closure-compiler.appspot.com/compile');
|
||||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
|
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
|
||||||
curl_setopt($ch, CURLOPT_POST, 1);
|
curl_setopt($ch, CURLOPT_POST, 1);
|
||||||
curl_setopt($ch, CURLOPT_POSTFIELDS, 'output_info=compiled_code&output_format=text&compilation_level=SIMPLE_OPTIMIZATIONS&js_code=' . urlencode($new_file));
|
curl_setopt($ch, CURLOPT_POSTFIELDS, $option_string);
|
||||||
$output = curl_exec($ch);
|
$json = curl_exec($ch);
|
||||||
curl_close($ch);
|
curl_close($ch);
|
||||||
return $output;
|
|
||||||
|
$obj = json_decode($json);
|
||||||
|
return $obj->compiledCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
// --------------------------------------------------------------------------
|
||||||
@ -146,7 +164,12 @@ if($last_modified === $requested_time)
|
|||||||
// --------------------------------------------------------------------------
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
//Determine what to do: rebuild cache, send files as is, or send cache.
|
//Determine what to do: rebuild cache, send files as is, or send cache.
|
||||||
if($cache_modified < $last_modified)
|
// If debug is set, just concatenate
|
||||||
|
if(isset($_GET['debug']))
|
||||||
|
{
|
||||||
|
$js = get_files();
|
||||||
|
}
|
||||||
|
else if($cache_modified < $last_modified)
|
||||||
{
|
{
|
||||||
$js = google_min(get_files());
|
$js = google_min(get_files());
|
||||||
|
|
||||||
@ -156,11 +179,6 @@ if($cache_modified < $last_modified)
|
|||||||
die("Cache file was not created. Make sure you have the correct folder permissions.");
|
die("Cache file was not created. Make sure you have the correct folder permissions.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// If debug is set, just concatenate
|
|
||||||
else if(isset($_GET['debug']))
|
|
||||||
{
|
|
||||||
$js = get_files();
|
|
||||||
}
|
|
||||||
// Otherwise, send the cached file
|
// Otherwise, send the cached file
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
$(".media button.plus_one").on("click", function(e) {
|
$(".media button.plus_one").on("click", function(e) {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
|
|
||||||
|
var self = this;
|
||||||
var this_sel = $(this);
|
var this_sel = $(this);
|
||||||
var parent_sel = $(this).closest("article");
|
var parent_sel = $(this).closest("article");
|
||||||
var self = this;
|
var self = this;
|
||||||
@ -41,7 +42,7 @@
|
|||||||
$.post(BASE_URL + 'update', data, function(res) {
|
$.post(BASE_URL + 'update', data, function(res) {
|
||||||
if (res.status === 'completed')
|
if (res.status === 'completed')
|
||||||
{
|
{
|
||||||
this_sel.parent('article').hide();
|
$(self).closest('article').hide();
|
||||||
}
|
}
|
||||||
|
|
||||||
add_message('success', "Sucessfully updated " + title);
|
add_message('success', "Sucessfully updated " + title);
|
||||||
|
17
public/js/collection.js
Normal file
17
public/js/collection.js
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
(function($, undefined) {
|
||||||
|
|
||||||
|
function search(query, callback)
|
||||||
|
{
|
||||||
|
$.get(BASE_URL + 'search', {'query':query}, callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
$("#search").on('keypress', $.throttle(250, function(e) {
|
||||||
|
var query = encodeURIComponent($(this).val());
|
||||||
|
search(query, function(res) {
|
||||||
|
var template = $.templates("#show_list");
|
||||||
|
var html = template.render(res);
|
||||||
|
$('#series_list').html(html);
|
||||||
|
});
|
||||||
|
}));
|
||||||
|
|
||||||
|
}(jQuery));
|
252
public/js/lib/jquery.throttle-debounce.js
Normal file
252
public/js/lib/jquery.throttle-debounce.js
Normal file
@ -0,0 +1,252 @@
|
|||||||
|
/*!
|
||||||
|
* jQuery throttle / debounce - v1.1 - 3/7/2010
|
||||||
|
* http://benalman.com/projects/jquery-throttle-debounce-plugin/
|
||||||
|
*
|
||||||
|
* Copyright (c) 2010 "Cowboy" Ben Alman
|
||||||
|
* Dual licensed under the MIT and GPL licenses.
|
||||||
|
* http://benalman.com/about/license/
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Script: jQuery throttle / debounce: Sometimes, less is more!
|
||||||
|
//
|
||||||
|
// *Version: 1.1, Last updated: 3/7/2010*
|
||||||
|
//
|
||||||
|
// Project Home - http://benalman.com/projects/jquery-throttle-debounce-plugin/
|
||||||
|
// GitHub - http://github.com/cowboy/jquery-throttle-debounce/
|
||||||
|
// Source - http://github.com/cowboy/jquery-throttle-debounce/raw/master/jquery.ba-throttle-debounce.js
|
||||||
|
// (Minified) - http://github.com/cowboy/jquery-throttle-debounce/raw/master/jquery.ba-throttle-debounce.min.js (0.7kb)
|
||||||
|
//
|
||||||
|
// About: License
|
||||||
|
//
|
||||||
|
// Copyright (c) 2010 "Cowboy" Ben Alman,
|
||||||
|
// Dual licensed under the MIT and GPL licenses.
|
||||||
|
// http://benalman.com/about/license/
|
||||||
|
//
|
||||||
|
// About: Examples
|
||||||
|
//
|
||||||
|
// These working examples, complete with fully commented code, illustrate a few
|
||||||
|
// ways in which this plugin can be used.
|
||||||
|
//
|
||||||
|
// Throttle - http://benalman.com/code/projects/jquery-throttle-debounce/examples/throttle/
|
||||||
|
// Debounce - http://benalman.com/code/projects/jquery-throttle-debounce/examples/debounce/
|
||||||
|
//
|
||||||
|
// About: Support and Testing
|
||||||
|
//
|
||||||
|
// Information about what version or versions of jQuery this plugin has been
|
||||||
|
// tested with, what browsers it has been tested in, and where the unit tests
|
||||||
|
// reside (so you can test it yourself).
|
||||||
|
//
|
||||||
|
// jQuery Versions - none, 1.3.2, 1.4.2
|
||||||
|
// Browsers Tested - Internet Explorer 6-8, Firefox 2-3.6, Safari 3-4, Chrome 4-5, Opera 9.6-10.1.
|
||||||
|
// Unit Tests - http://benalman.com/code/projects/jquery-throttle-debounce/unit/
|
||||||
|
//
|
||||||
|
// About: Release History
|
||||||
|
//
|
||||||
|
// 1.1 - (3/7/2010) Fixed a bug in <jQuery.throttle> where trailing callbacks
|
||||||
|
// executed later than they should. Reworked a fair amount of internal
|
||||||
|
// logic as well.
|
||||||
|
// 1.0 - (3/6/2010) Initial release as a stand-alone project. Migrated over
|
||||||
|
// from jquery-misc repo v0.4 to jquery-throttle repo v1.0, added the
|
||||||
|
// no_trailing throttle parameter and debounce functionality.
|
||||||
|
//
|
||||||
|
// Topic: Note for non-jQuery users
|
||||||
|
//
|
||||||
|
// jQuery isn't actually required for this plugin, because nothing internal
|
||||||
|
// uses any jQuery methods or properties. jQuery is just used as a namespace
|
||||||
|
// under which these methods can exist.
|
||||||
|
//
|
||||||
|
// Since jQuery isn't actually required for this plugin, if jQuery doesn't exist
|
||||||
|
// when this plugin is loaded, the method described below will be created in
|
||||||
|
// the `Cowboy` namespace. Usage will be exactly the same, but instead of
|
||||||
|
// $.method() or jQuery.method(), you'll need to use Cowboy.method().
|
||||||
|
|
||||||
|
(function(window,undefined){
|
||||||
|
'$:nomunge'; // Used by YUI compressor.
|
||||||
|
|
||||||
|
// Since jQuery really isn't required for this plugin, use `jQuery` as the
|
||||||
|
// namespace only if it already exists, otherwise use the `Cowboy` namespace,
|
||||||
|
// creating it if necessary.
|
||||||
|
var $ = window.jQuery || window.Cowboy || ( window.Cowboy = {} ),
|
||||||
|
|
||||||
|
// Internal method reference.
|
||||||
|
jq_throttle;
|
||||||
|
|
||||||
|
// Method: jQuery.throttle
|
||||||
|
//
|
||||||
|
// Throttle execution of a function. Especially useful for rate limiting
|
||||||
|
// execution of handlers on events like resize and scroll. If you want to
|
||||||
|
// rate-limit execution of a function to a single time, see the
|
||||||
|
// <jQuery.debounce> method.
|
||||||
|
//
|
||||||
|
// In this visualization, | is a throttled-function call and X is the actual
|
||||||
|
// callback execution:
|
||||||
|
//
|
||||||
|
// > Throttled with `no_trailing` specified as false or unspecified:
|
||||||
|
// > ||||||||||||||||||||||||| (pause) |||||||||||||||||||||||||
|
||||||
|
// > X X X X X X X X X X X X
|
||||||
|
// >
|
||||||
|
// > Throttled with `no_trailing` specified as true:
|
||||||
|
// > ||||||||||||||||||||||||| (pause) |||||||||||||||||||||||||
|
||||||
|
// > X X X X X X X X X X
|
||||||
|
//
|
||||||
|
// Usage:
|
||||||
|
//
|
||||||
|
// > var throttled = jQuery.throttle( delay, [ no_trailing, ] callback );
|
||||||
|
// >
|
||||||
|
// > jQuery('selector').bind( 'someevent', throttled );
|
||||||
|
// > jQuery('selector').unbind( 'someevent', throttled );
|
||||||
|
//
|
||||||
|
// This also works in jQuery 1.4+:
|
||||||
|
//
|
||||||
|
// > jQuery('selector').bind( 'someevent', jQuery.throttle( delay, [ no_trailing, ] callback ) );
|
||||||
|
// > jQuery('selector').unbind( 'someevent', callback );
|
||||||
|
//
|
||||||
|
// Arguments:
|
||||||
|
//
|
||||||
|
// delay - (Number) A zero-or-greater delay in milliseconds. For event
|
||||||
|
// callbacks, values around 100 or 250 (or even higher) are most useful.
|
||||||
|
// no_trailing - (Boolean) Optional, defaults to false. If no_trailing is
|
||||||
|
// true, callback will only execute every `delay` milliseconds while the
|
||||||
|
// throttled-function is being called. If no_trailing is false or
|
||||||
|
// unspecified, callback will be executed one final time after the last
|
||||||
|
// throttled-function call. (After the throttled-function has not been
|
||||||
|
// called for `delay` milliseconds, the internal counter is reset)
|
||||||
|
// callback - (Function) A function to be executed after delay milliseconds.
|
||||||
|
// The `this` context and all arguments are passed through, as-is, to
|
||||||
|
// `callback` when the throttled-function is executed.
|
||||||
|
//
|
||||||
|
// Returns:
|
||||||
|
//
|
||||||
|
// (Function) A new, throttled, function.
|
||||||
|
|
||||||
|
$.throttle = jq_throttle = function( delay, no_trailing, callback, debounce_mode ) {
|
||||||
|
// After wrapper has stopped being called, this timeout ensures that
|
||||||
|
// `callback` is executed at the proper times in `throttle` and `end`
|
||||||
|
// debounce modes.
|
||||||
|
var timeout_id,
|
||||||
|
|
||||||
|
// Keep track of the last time `callback` was executed.
|
||||||
|
last_exec = 0;
|
||||||
|
|
||||||
|
// `no_trailing` defaults to falsy.
|
||||||
|
if ( typeof no_trailing !== 'boolean' ) {
|
||||||
|
debounce_mode = callback;
|
||||||
|
callback = no_trailing;
|
||||||
|
no_trailing = undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The `wrapper` function encapsulates all of the throttling / debouncing
|
||||||
|
// functionality and when executed will limit the rate at which `callback`
|
||||||
|
// is executed.
|
||||||
|
function wrapper() {
|
||||||
|
var that = this,
|
||||||
|
elapsed = +new Date() - last_exec,
|
||||||
|
args = arguments;
|
||||||
|
|
||||||
|
// Execute `callback` and update the `last_exec` timestamp.
|
||||||
|
function exec() {
|
||||||
|
last_exec = +new Date();
|
||||||
|
callback.apply( that, args );
|
||||||
|
};
|
||||||
|
|
||||||
|
// If `debounce_mode` is true (at_begin) this is used to clear the flag
|
||||||
|
// to allow future `callback` executions.
|
||||||
|
function clear() {
|
||||||
|
timeout_id = undefined;
|
||||||
|
};
|
||||||
|
|
||||||
|
if ( debounce_mode && !timeout_id ) {
|
||||||
|
// Since `wrapper` is being called for the first time and
|
||||||
|
// `debounce_mode` is true (at_begin), execute `callback`.
|
||||||
|
exec();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clear any existing timeout.
|
||||||
|
timeout_id && clearTimeout( timeout_id );
|
||||||
|
|
||||||
|
if ( debounce_mode === undefined && elapsed > delay ) {
|
||||||
|
// In throttle mode, if `delay` time has been exceeded, execute
|
||||||
|
// `callback`.
|
||||||
|
exec();
|
||||||
|
|
||||||
|
} else if ( no_trailing !== true ) {
|
||||||
|
// In trailing throttle mode, since `delay` time has not been
|
||||||
|
// exceeded, schedule `callback` to execute `delay` ms after most
|
||||||
|
// recent execution.
|
||||||
|
//
|
||||||
|
// If `debounce_mode` is true (at_begin), schedule `clear` to execute
|
||||||
|
// after `delay` ms.
|
||||||
|
//
|
||||||
|
// If `debounce_mode` is false (at end), schedule `callback` to
|
||||||
|
// execute after `delay` ms.
|
||||||
|
timeout_id = setTimeout( debounce_mode ? clear : exec, debounce_mode === undefined ? delay - elapsed : delay );
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Set the guid of `wrapper` function to the same of original callback, so
|
||||||
|
// it can be removed in jQuery 1.4+ .unbind or .die by using the original
|
||||||
|
// callback as a reference.
|
||||||
|
if ( $.guid ) {
|
||||||
|
wrapper.guid = callback.guid = callback.guid || $.guid++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return the wrapper function.
|
||||||
|
return wrapper;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Method: jQuery.debounce
|
||||||
|
//
|
||||||
|
// Debounce execution of a function. Debouncing, unlike throttling,
|
||||||
|
// guarantees that a function is only executed a single time, either at the
|
||||||
|
// very beginning of a series of calls, or at the very end. If you want to
|
||||||
|
// simply rate-limit execution of a function, see the <jQuery.throttle>
|
||||||
|
// method.
|
||||||
|
//
|
||||||
|
// In this visualization, | is a debounced-function call and X is the actual
|
||||||
|
// callback execution:
|
||||||
|
//
|
||||||
|
// > Debounced with `at_begin` specified as false or unspecified:
|
||||||
|
// > ||||||||||||||||||||||||| (pause) |||||||||||||||||||||||||
|
||||||
|
// > X X
|
||||||
|
// >
|
||||||
|
// > Debounced with `at_begin` specified as true:
|
||||||
|
// > ||||||||||||||||||||||||| (pause) |||||||||||||||||||||||||
|
||||||
|
// > X X
|
||||||
|
//
|
||||||
|
// Usage:
|
||||||
|
//
|
||||||
|
// > var debounced = jQuery.debounce( delay, [ at_begin, ] callback );
|
||||||
|
// >
|
||||||
|
// > jQuery('selector').bind( 'someevent', debounced );
|
||||||
|
// > jQuery('selector').unbind( 'someevent', debounced );
|
||||||
|
//
|
||||||
|
// This also works in jQuery 1.4+:
|
||||||
|
//
|
||||||
|
// > jQuery('selector').bind( 'someevent', jQuery.debounce( delay, [ at_begin, ] callback ) );
|
||||||
|
// > jQuery('selector').unbind( 'someevent', callback );
|
||||||
|
//
|
||||||
|
// Arguments:
|
||||||
|
//
|
||||||
|
// delay - (Number) A zero-or-greater delay in milliseconds. For event
|
||||||
|
// callbacks, values around 100 or 250 (or even higher) are most useful.
|
||||||
|
// at_begin - (Boolean) Optional, defaults to false. If at_begin is false or
|
||||||
|
// unspecified, callback will only be executed `delay` milliseconds after
|
||||||
|
// the last debounced-function call. If at_begin is true, callback will be
|
||||||
|
// executed only at the first debounced-function call. (After the
|
||||||
|
// throttled-function has not been called for `delay` milliseconds, the
|
||||||
|
// internal counter is reset)
|
||||||
|
// callback - (Function) A function to be executed after delay milliseconds.
|
||||||
|
// The `this` context and all arguments are passed through, as-is, to
|
||||||
|
// `callback` when the debounced-function is executed.
|
||||||
|
//
|
||||||
|
// Returns:
|
||||||
|
//
|
||||||
|
// (Function) A new, debounced, function.
|
||||||
|
|
||||||
|
$.debounce = function( delay, at_begin, callback ) {
|
||||||
|
return callback === undefined
|
||||||
|
? jq_throttle( delay, at_begin, false )
|
||||||
|
: jq_throttle( delay, callback, at_begin !== false );
|
||||||
|
};
|
||||||
|
|
||||||
|
})(this);
|
1958
public/js/lib/jsrender.js
Normal file
1958
public/js/lib/jsrender.js
Normal file
File diff suppressed because it is too large
Load Diff
@ -8,7 +8,8 @@ class ConfigTest extends AnimeClient_TestCase {
|
|||||||
{
|
{
|
||||||
$this->config = new Config([
|
$this->config = new Config([
|
||||||
'config' => [
|
'config' => [
|
||||||
'foo' => 'bar'
|
'foo' => 'bar',
|
||||||
|
'asset_path' => '//localhost/assets/'
|
||||||
],
|
],
|
||||||
'base_config' => [
|
'base_config' => [
|
||||||
'bar' => 'baz'
|
'bar' => 'baz'
|
||||||
@ -18,7 +19,9 @@ class ConfigTest extends AnimeClient_TestCase {
|
|||||||
|
|
||||||
public function testConfig__get()
|
public function testConfig__get()
|
||||||
{
|
{
|
||||||
|
$this->assertEquals($this->config->foo, $this->config->__get('foo'));
|
||||||
$this->assertEquals($this->config->bar, $this->config->__get('bar'));
|
$this->assertEquals($this->config->bar, $this->config->__get('bar'));
|
||||||
|
$this->assertEquals(NULL, $this->config->baz);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testGetNonExistentConfigItem()
|
public function testGetNonExistentConfigItem()
|
||||||
@ -26,4 +29,81 @@ class ConfigTest extends AnimeClient_TestCase {
|
|||||||
$this->assertEquals(NULL, $this->config->foobar);
|
$this->assertEquals(NULL, $this->config->foobar);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function assetUrlProvider()
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'single argument' => [
|
||||||
|
'args' => [
|
||||||
|
'images'
|
||||||
|
],
|
||||||
|
'expected' => '//localhost/assets/images',
|
||||||
|
],
|
||||||
|
'multiple arguments' => [
|
||||||
|
'args' => [
|
||||||
|
'images', 'anime', 'foo.png'
|
||||||
|
],
|
||||||
|
'expected' => '//localhost/assets/images/anime/foo.png'
|
||||||
|
]
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dataProvider assetUrlProvider
|
||||||
|
*/
|
||||||
|
public function testAssetUrl($args, $expected)
|
||||||
|
{
|
||||||
|
$result = call_user_func_array([$this->config, 'asset_url'], $args);
|
||||||
|
|
||||||
|
$this->assertEquals($expected, $result);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function fullUrlProvider()
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'default_view' => [
|
||||||
|
'config' => [
|
||||||
|
'anime_host' => '',
|
||||||
|
'manga_host' => '',
|
||||||
|
'anime_path' => 'anime',
|
||||||
|
'manga_path' => 'manga',
|
||||||
|
'route_by' => 'host',
|
||||||
|
'default_list' => 'manga',
|
||||||
|
'default_anime_path' => '/watching',
|
||||||
|
'default_manga_path' => '/all',
|
||||||
|
'default_to_list_view' => FALSE,
|
||||||
|
],
|
||||||
|
'path' => '',
|
||||||
|
'type' => 'manga',
|
||||||
|
'expected' => '//localhost/manga/all',
|
||||||
|
],
|
||||||
|
'default_view_list' => [
|
||||||
|
'config' => [
|
||||||
|
'anime_host' => '',
|
||||||
|
'manga_host' => '',
|
||||||
|
'anime_path' => 'anime',
|
||||||
|
'manga_path' => 'manga',
|
||||||
|
'route_by' => 'host',
|
||||||
|
'default_list' => 'manga',
|
||||||
|
'default_anime_path' => '/watching',
|
||||||
|
'default_manga_path' => '/all',
|
||||||
|
'default_to_list_view' => TRUE,
|
||||||
|
],
|
||||||
|
'path' => '',
|
||||||
|
'type' => 'manga',
|
||||||
|
'expected' => '//localhost/manga/all/list',
|
||||||
|
]
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dataProvider fullUrlProvider
|
||||||
|
*/
|
||||||
|
public function testFullUrl($config, $path, $type, $expected)
|
||||||
|
{
|
||||||
|
$this->config = new Config(['config' => $config, 'base_config' => []]);
|
||||||
|
|
||||||
|
$result = $this->config->full_url($path, $type);
|
||||||
|
|
||||||
|
$this->assertEquals($expected, $result);
|
||||||
|
}
|
||||||
}
|
}
|
@ -4,21 +4,6 @@ use \AnimeClient\Config;
|
|||||||
|
|
||||||
class FunctionsTest extends AnimeClient_TestCase {
|
class FunctionsTest extends AnimeClient_TestCase {
|
||||||
|
|
||||||
public function setUp()
|
|
||||||
{
|
|
||||||
parent::setUp();
|
|
||||||
|
|
||||||
global $config;
|
|
||||||
$config = new Config([
|
|
||||||
'config' => [
|
|
||||||
'asset_path' => '//localhost/assets/'
|
|
||||||
],
|
|
||||||
'base_config' => [
|
|
||||||
|
|
||||||
]
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Basic sanity test for _dir function
|
* Basic sanity test for _dir function
|
||||||
*/
|
*/
|
||||||
@ -45,34 +30,6 @@ class FunctionsTest extends AnimeClient_TestCase {
|
|||||||
$this->assertEquals('', is_not_selected('foo', 'foo'));
|
$this->assertEquals('', is_not_selected('foo', 'foo'));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function assetUrlProvider()
|
|
||||||
{
|
|
||||||
return [
|
|
||||||
'single argument' => [
|
|
||||||
'args' => [
|
|
||||||
'images'
|
|
||||||
],
|
|
||||||
'expected' => '//localhost/assets/images',
|
|
||||||
],
|
|
||||||
'multiple arguments' => [
|
|
||||||
'args' => [
|
|
||||||
'images', 'anime', 'foo.png'
|
|
||||||
],
|
|
||||||
'expected' => '//localhost/assets/images/anime/foo.png'
|
|
||||||
]
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @dataProvider assetUrlProvider
|
|
||||||
*/
|
|
||||||
public function testAssetUrl($args, $expected)
|
|
||||||
{
|
|
||||||
$result = call_user_func_array('asset_url', $args);
|
|
||||||
|
|
||||||
$this->assertEquals($expected, $result);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function testIsLoggedIn()
|
public function testIsLoggedIn()
|
||||||
{
|
{
|
||||||
$this->assertFalse(is_logged_in());
|
$this->assertFalse(is_logged_in());
|
||||||
|
@ -34,6 +34,34 @@ class RouterTest extends AnimeClient_TestCase {
|
|||||||
$this->assertTrue(is_object($this->router));
|
$this->assertTrue(is_object($this->router));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected function _set_up($config, $uri, $host)
|
||||||
|
{
|
||||||
|
$this->config = new Config($config);
|
||||||
|
|
||||||
|
// Set up the environment
|
||||||
|
$_SERVER = array_merge($_SERVER, [
|
||||||
|
'REQUEST_METHOD' => 'GET',
|
||||||
|
'REQUEST_URI' => $uri,
|
||||||
|
'HTTP_HOST' => $host,
|
||||||
|
'SERVER_NAME' => $host
|
||||||
|
]);
|
||||||
|
|
||||||
|
$router_factory = new RouterFactory();
|
||||||
|
$this->aura_router = $router_factory->newInstance();
|
||||||
|
|
||||||
|
// Create Request/Response Objects
|
||||||
|
$web_factory = new WebFactory([
|
||||||
|
'_GET' => [],
|
||||||
|
'_POST' => [],
|
||||||
|
'_COOKIE' => [],
|
||||||
|
'_SERVER' => $_SERVER,
|
||||||
|
'_FILES' => []
|
||||||
|
]);
|
||||||
|
$this->request = $web_factory->newRequest();
|
||||||
|
$this->response = $web_factory->newResponse();
|
||||||
|
$this->router = new Router($this->config, $this->aura_router, $this->request, $this->response);
|
||||||
|
}
|
||||||
|
|
||||||
public function RouteTestProvider()
|
public function RouteTestProvider()
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
@ -45,6 +73,7 @@ class RouterTest extends AnimeClient_TestCase {
|
|||||||
'anime_path' => 'anime',
|
'anime_path' => 'anime',
|
||||||
'manga_path' => 'manga',
|
'manga_path' => 'manga',
|
||||||
'route_by' => 'path',
|
'route_by' => 'path',
|
||||||
|
'default_list' => 'anime'
|
||||||
],
|
],
|
||||||
'base_config' => []
|
'base_config' => []
|
||||||
),
|
),
|
||||||
@ -61,6 +90,7 @@ class RouterTest extends AnimeClient_TestCase {
|
|||||||
'anime_path' => '',
|
'anime_path' => '',
|
||||||
'manga_path' => '',
|
'manga_path' => '',
|
||||||
'route_by' => 'host',
|
'route_by' => 'host',
|
||||||
|
'default_list' => 'anime'
|
||||||
],
|
],
|
||||||
'base_config' => []
|
'base_config' => []
|
||||||
),
|
),
|
||||||
@ -77,6 +107,7 @@ class RouterTest extends AnimeClient_TestCase {
|
|||||||
'anime_path' => 'anime',
|
'anime_path' => 'anime',
|
||||||
'manga_path' => 'manga',
|
'manga_path' => 'manga',
|
||||||
'route_by' => 'path',
|
'route_by' => 'path',
|
||||||
|
'default_list' => 'manga'
|
||||||
],
|
],
|
||||||
'base_config' => [
|
'base_config' => [
|
||||||
'routes' => []
|
'routes' => []
|
||||||
@ -95,6 +126,7 @@ class RouterTest extends AnimeClient_TestCase {
|
|||||||
'anime_path' => '',
|
'anime_path' => '',
|
||||||
'manga_path' => '',
|
'manga_path' => '',
|
||||||
'route_by' => 'host',
|
'route_by' => 'host',
|
||||||
|
'default_list' => 'manga'
|
||||||
],
|
],
|
||||||
'base_config' => []
|
'base_config' => []
|
||||||
),
|
),
|
||||||
@ -102,7 +134,7 @@ class RouterTest extends AnimeClient_TestCase {
|
|||||||
'host' => 'anime.host.me',
|
'host' => 'anime.host.me',
|
||||||
'uri' => '/watching',
|
'uri' => '/watching',
|
||||||
'check_var' => 'anime_host'
|
'check_var' => 'anime_host'
|
||||||
)
|
),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -147,30 +179,7 @@ class RouterTest extends AnimeClient_TestCase {
|
|||||||
]
|
]
|
||||||
];
|
];
|
||||||
|
|
||||||
$this->config = new Config($config);
|
$this->_set_up($config, $uri, $host);
|
||||||
|
|
||||||
// Set up the environment
|
|
||||||
$_SERVER = array_merge($_SERVER, [
|
|
||||||
'REQUEST_METHOD' => 'GET',
|
|
||||||
'REQUEST_URI' => $uri,
|
|
||||||
'HTTP_HOST' => $host,
|
|
||||||
'SERVER_NAME' => $host
|
|
||||||
]);
|
|
||||||
|
|
||||||
$router_factory = new RouterFactory();
|
|
||||||
$this->aura_router = $router_factory->newInstance();
|
|
||||||
|
|
||||||
// Create Request/Response Objects
|
|
||||||
$web_factory = new WebFactory([
|
|
||||||
'_GET' => [],
|
|
||||||
'_POST' => [],
|
|
||||||
'_COOKIE' => [],
|
|
||||||
'_SERVER' => $_SERVER,
|
|
||||||
'_FILES' => []
|
|
||||||
]);
|
|
||||||
$this->request = $web_factory->newRequest();
|
|
||||||
$this->response = $web_factory->newResponse();
|
|
||||||
$this->router = new Router($this->config, $this->aura_router, $this->request, $this->response);
|
|
||||||
|
|
||||||
// Check route setup
|
// Check route setup
|
||||||
$this->assertEquals($config['base_config']['routes'], $this->config->routes);
|
$this->assertEquals($config['base_config']['routes'], $this->config->routes);
|
||||||
@ -189,4 +198,53 @@ class RouterTest extends AnimeClient_TestCase {
|
|||||||
$route = $this->router->get_route();
|
$route = $this->router->get_route();
|
||||||
$this->assertInstanceOf('Aura\\Router\\Route', $route, "Route is valid, and matched");
|
$this->assertInstanceOf('Aura\\Router\\Route', $route, "Route is valid, and matched");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*public function testDefaultRoute()
|
||||||
|
{
|
||||||
|
$config = [
|
||||||
|
'config' => [
|
||||||
|
'anime_host' => '',
|
||||||
|
'manga_host' => '',
|
||||||
|
'anime_path' => 'anime',
|
||||||
|
'manga_path' => 'manga',
|
||||||
|
'route_by' => 'host',
|
||||||
|
'default_list' => 'manga'
|
||||||
|
],
|
||||||
|
'base_config' => [
|
||||||
|
'routes' => [
|
||||||
|
'common' => [
|
||||||
|
'login_form' => [
|
||||||
|
'path' => '/login',
|
||||||
|
'action' => ['login'],
|
||||||
|
'verb' => 'get'
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'anime' => [
|
||||||
|
'index' => [
|
||||||
|
'path' => '/',
|
||||||
|
'action' => ['redirect'],
|
||||||
|
'params' => [
|
||||||
|
'url' => '', // Determined by config
|
||||||
|
'code' => '301'
|
||||||
|
]
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'manga' => [
|
||||||
|
'index' => [
|
||||||
|
'path' => '/',
|
||||||
|
'action' => ['redirect'],
|
||||||
|
'params' => [
|
||||||
|
'url' => '', // Determined by config
|
||||||
|
'code' => '301',
|
||||||
|
'type' => 'manga'
|
||||||
|
]
|
||||||
|
],
|
||||||
|
]
|
||||||
|
]
|
||||||
|
]
|
||||||
|
];
|
||||||
|
|
||||||
|
$this->_set_up($config, "/", "localhost");
|
||||||
|
$this->assertEquals($this->config->full_url('', 'manga'), $this->response->headers->get('location'));
|
||||||
|
}*/
|
||||||
}
|
}
|
@ -32,7 +32,9 @@ class AnimeClient_TestCase extends PHPUnit_Framework_TestCase {
|
|||||||
|
|
||||||
global $config;
|
global $config;
|
||||||
$this->config = new Config([
|
$this->config = new Config([
|
||||||
'config' => [],
|
'config' => [
|
||||||
|
'asset_path' => '//localhost/assets/'
|
||||||
|
],
|
||||||
'base_config' => [
|
'base_config' => [
|
||||||
'databaase' => [],
|
'databaase' => [],
|
||||||
'routes' => [
|
'routes' => [
|
||||||
|
Loading…
Reference in New Issue
Block a user