diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 00000000..b909682f --- /dev/null +++ b/.editorconfig @@ -0,0 +1,20 @@ +# EditorConfig is awesome: http://EditorConfig.org + +# top-most EditorConfig file +root = true + +# Unix-style newlines with a newline ending every file +[*] +end_of_line = lf +insert_final_newline = false +charset = utf-8 +indent_style = tab +trim_trailing_whitespace = true + +[*.{cpp,c,h,hpp,cxx}] +insert_final_newline = true + +# Yaml files +[*.{yml,yaml}] +indent_style = space +indent_size = 4 \ No newline at end of file diff --git a/app/base/BaseApiModel.php b/app/Base/ApiModel.php similarity index 95% rename from app/base/BaseApiModel.php rename to app/Base/ApiModel.php index bc1edc87..0beb78b3 100644 --- a/app/base/BaseApiModel.php +++ b/app/Base/ApiModel.php @@ -2,7 +2,7 @@ /** * Base API Model */ -namespace AnimeClient; +namespace AnimeClient\Base; use \GuzzleHttp\Client; use \GuzzleHttp\Cookie\CookieJar; @@ -10,7 +10,7 @@ use \GuzzleHttp\Cookie\CookieJar; /** * Base model for api interaction */ -class BaseApiModel extends BaseModel { +class ApiModel extends Model { /** * Base url for making api requests diff --git a/app/base/Config.php b/app/Base/Config.php similarity index 93% rename from app/base/Config.php rename to app/Base/Config.php index c0e508a1..9ed8ff78 100644 --- a/app/base/Config.php +++ b/app/Base/Config.php @@ -1,6 +1,9 @@ __get('asset_path'), '/'); @@ -74,7 +77,7 @@ class Config { * @param string $type - (optional) The controller * @return string */ - function base_url($type="anime") + public function base_url($type="anime") { $config_path = trim($this->__get("{$type}_path"), "/"); $config_host = $this->__get("{$type}_host"); @@ -93,7 +96,7 @@ class Config { * @param string $type - (optional) The controller (anime or manga), defaults to anime * @return string */ - function full_url($path="", $type="anime") + public function full_url($path="", $type="anime") { $config_path = trim($this->__get("{$type}_path"), "/"); $config_host = $this->__get("{$type}_host"); diff --git a/app/base/BaseController.php b/app/Base/Controller.php similarity index 99% rename from app/base/BaseController.php rename to app/Base/Controller.php index 38dca981..910e5854 100644 --- a/app/base/BaseController.php +++ b/app/Base/Controller.php @@ -2,14 +2,14 @@ /** * Base Controller */ -namespace AnimeClient; +namespace AnimeClient\Base; use Aura\Web\WebFactory; /** * Base class for controllers, defines output methods */ -class BaseController { +class Controller { /** * The global configuration object diff --git a/app/base/BaseDBModel.php b/app/Base/DBModel.php similarity index 87% rename from app/base/BaseDBModel.php rename to app/Base/DBModel.php index ae273509..d6b51a22 100644 --- a/app/base/BaseDBModel.php +++ b/app/Base/DBModel.php @@ -2,12 +2,12 @@ /** * Base DB model */ -namespace AnimeClient; +namespace AnimeClient\Base; /** * Base model for database interaction */ -class BaseDBModel extends BaseModel { +class DBModel extends Model { /** * The query builder object * @var object $db diff --git a/app/base/BaseModel.php b/app/Base/Model.php similarity index 98% rename from app/base/BaseModel.php rename to app/Base/Model.php index 5de557ce..e0e167d3 100644 --- a/app/base/BaseModel.php +++ b/app/Base/Model.php @@ -2,14 +2,14 @@ /** * Base for base models */ -namespace AnimeClient; +namespace AnimeClient\Base; use abeautifulsite\SimpleImage; /** * Common base for all Models */ -class BaseModel { +class Model { /** * The global configuration object diff --git a/app/base/Router.php b/app/Base/Router.php similarity index 92% rename from app/base/Router.php rename to app/Base/Router.php index beeb9804..754bf6bc 100644 --- a/app/base/Router.php +++ b/app/Base/Router.php @@ -3,7 +3,7 @@ * Routing logic */ -namespace AnimeClient; +namespace AnimeClient\Base; /** * Basic routing/ dispatch @@ -68,9 +68,9 @@ class Router { $route_path = str_replace([$this->config->anime_path, $this->config->manga_path], '', $raw_route); $route_path = "/" . trim($route_path, '/'); - $defaultHandler->addDataTable('Route Info', [ + /*$defaultHandler->addDataTable('Route Info', [ 'route_path' => $route_path - ]); + ]);*/ $route = $this->router->match($route_path, $_SERVER); @@ -107,15 +107,6 @@ class Router { { $failure = $this->router->getFailedRoute(); $defaultHandler->addDataTable('failed_route', (array)$failure); - - /*$controller_name = '\\AnimeClient\\BaseController'; - $action_method = 'outputHTML'; - $params = [ - 'template' => '404', - 'data' => [ - 'title' => 'Page Not Found' - ] - ];*/ } else { @@ -194,8 +185,8 @@ class Router { public function _setup_routes() { $route_map = [ - 'anime' => '\\AnimeClient\\AnimeController', - 'manga' => '\\AnimeClient\\MangaController', + 'anime' => '\\AnimeClient\\Controller\\Anime', + 'manga' => '\\AnimeClient\\Controller\\Manga', ]; $output_routes = []; diff --git a/app/base/functions.php b/app/Base/functions.php similarity index 100% rename from app/base/functions.php rename to app/Base/functions.php diff --git a/app/base/pre_conf_functions.php b/app/Base/pre_conf_functions.php similarity index 69% rename from app/base/pre_conf_functions.php rename to app/Base/pre_conf_functions.php index b5b25dab..ab98a289 100644 --- a/app/base/pre_conf_functions.php +++ b/app/Base/pre_conf_functions.php @@ -26,18 +26,13 @@ function _setup_autoloaders() require _dir(ROOT_DIR, '/vendor/autoload.php'); spl_autoload_register(function ($class) { $class_parts = explode('\\', $class); - $class = end($class_parts); + array_shift($class_parts); + $ns_path = APP_DIR . '/' . implode('/', $class_parts) . ".php"; - $dirs = ["base", "controllers", "models"]; - - foreach($dirs as $dir) + if (file_exists($ns_path)) { - $file = _dir(APP_DIR, $dir, "{$class}.php"); - if (file_exists($file)) - { - require_once $file; - return; - } + require_once($ns_path); + return; } }); } \ No newline at end of file diff --git a/app/controllers/AnimeController.php b/app/Controller/Anime.php similarity index 93% rename from app/controllers/AnimeController.php rename to app/Controller/Anime.php index 7e8056a3..3b1541ab 100644 --- a/app/controllers/AnimeController.php +++ b/app/Controller/Anime.php @@ -3,12 +3,17 @@ * Anime Controller */ -namespace AnimeClient; +namespace AnimeClient\Controller; + +use AnimeClient\Base\Controller as BaseController; +use AnimeClient\Base\Config; +use AnimeClient\Model\Anime as AnimeModel; +use AnimeClient\Model\AnimeCollection as AnimeCollectionModel; /** * Controller for Anime-related pages */ -class AnimeController extends BaseController { +class Anime extends BaseController { /** * The anime list model diff --git a/app/controllers/MangaController.php b/app/Controller/Manga.php similarity index 90% rename from app/controllers/MangaController.php rename to app/Controller/Manga.php index 7f65dfe6..e23eb1b0 100644 --- a/app/controllers/MangaController.php +++ b/app/Controller/Manga.php @@ -2,12 +2,16 @@ /** * Manga Controller */ -namespace AnimeClient; +namespace AnimeClient\Controller; + +use AnimeClient\Base\Controller; +use AnimeClient\Base\Config; +use AnimeClient\Model\Manga as MangaModel; /** * Controller for manga list */ -class MangaController extends BaseController { +class Manga extends Controller { /** * The manga model diff --git a/app/models/AnimeModel.php b/app/Model/Anime.php similarity index 97% rename from app/models/AnimeModel.php rename to app/Model/Anime.php index e24a22c0..b7e2ab3d 100644 --- a/app/models/AnimeModel.php +++ b/app/Model/Anime.php @@ -3,12 +3,15 @@ * Anime API Model */ -namespace AnimeClient; +namespace AnimeClient\Model; + +use AnimeClient\Base\ApiModel; +use AnimeClient\Base\Config; /** * Model for handling requests dealing with the anime list */ -class AnimeModel extends BaseApiModel { +class Anime extends ApiModel { /** * The base url for api requests * @var string $base_url diff --git a/app/models/AnimeCollectionModel.php b/app/Model/AnimeCollection.php similarity index 97% rename from app/models/AnimeCollectionModel.php rename to app/Model/AnimeCollection.php index 9ec45571..418b6e42 100644 --- a/app/models/AnimeCollectionModel.php +++ b/app/Model/AnimeCollection.php @@ -3,12 +3,16 @@ * Anime Collection DB Model */ -namespace AnimeClient; +namespace AnimeClient\Model; + +use AnimeClient\Base\DBModel; +use AnimeClient\Base\Config; +use AnimeClient\Model\Anime as AnimeModel; /** * Model for getting anime collection data */ -class AnimeCollectionModel extends BaseDBModel { +class AnimeCollection extends DBModel { /** * Anime API Model diff --git a/app/models/MangaModel.php b/app/Model/Manga.php similarity index 96% rename from app/models/MangaModel.php rename to app/Model/Manga.php index b78da616..2fe270ac 100644 --- a/app/models/MangaModel.php +++ b/app/Model/Manga.php @@ -2,12 +2,15 @@ /** * Manga API Model */ -namespace AnimeClient; +namespace AnimeClient\Model; + +use AnimeClient\Base\ApiModel; +use AnimeClient\Base\Config; /** * Model for handling requests dealing with the manga list */ -class MangaModel extends BaseApiModel { +class Manga extends ApiModel { /** * The base url for api requests diff --git a/app/bootstrap.php b/app/bootstrap.php index 06f2ebcd..e9f621ae 100644 --- a/app/bootstrap.php +++ b/app/bootstrap.php @@ -1,4 +1,7 @@ pushHandler($jsonHandler); $whoops->register(); +$container->set('error-handler', $defaultHandler); + // ----------------------------------------------------------------------------- // Injected Objects // ----------------------------------------------------------------------------- // Create Config Object -$config = new Config(); -require _dir(BASE_DIR, '/functions.php'); +$config = new Base\Config(); +$container->set('config', $config); // Create Aura Router Object $router_factory = new RouterFactory(); $aura_router = $router_factory->newInstance(); +$container->set('aura-router', $aura_router); // Create Request/Response Objects $web_factory = new WebFactory([ @@ -43,13 +58,13 @@ $web_factory = new WebFactory([ '_SERVER' => $_SERVER, '_FILES' => $_FILES ]); -$request = $web_factory->newRequest(); -$response = $web_factory->newResponse(); +$container->set('request', $web_factory->newRequest()); +$container->set('response', $web_factory->newResponse()); // ----------------------------------------------------------------------------- // Router // ----------------------------------------------------------------------------- -$router = new Router($config, $aura_router, $request, $response); +$router = new Base\Router($container); $router->dispatch(); // End of bootstrap.php \ No newline at end of file diff --git a/app/config/config.php b/app/config/config.php index c1366c61..040982c9 100644 --- a/app/config/config.php +++ b/app/config/config.php @@ -1,4 +1,4 @@ - TRUE, - // path to public directory - 'asset_path' => '//' . $_SERVER['HTTP_HOST'] . '/public', - // path to public directory on the server 'asset_dir' => __DIR__ . '/../../public', // ---------------------------------------------------------------------------- // Routing - // - // Route by path, or route by domain. To route by path, set the _host suffixed - // options to an empty string, and set 'route_by' to 'path'. To route by host, set - // the _path suffixed options to an empty string, and set 'route_by' to 'host'. // ---------------------------------------------------------------------------- - 'route_by' => 'path', // host or path - 'anime_host' => '', - 'manga_host' => '', + 'routing' => [ + // Subfolder prefix for url + 'subfolder_prefix' => '', + + // Path to public directory, where images/css/javascript are located, + // appended to the url + 'asset_path' => '/public', + + // Url paths to each content type + 'anime_path' => 'anime', + 'manga_path' => 'manga', + 'collection_path' => 'collection', + 'stats_path' => 'stats', + + // Which list should be the default? + 'default_list' => 'anime', // anime or manga + + // Default pages for anime/manga + 'default_anime_path' => "/anime/watching", + 'default_manga_path' => '/manga/all', + + // Default to list view? + 'default_to_list_view' => FALSE, + ], + + // Url paths to each 'anime_path' => 'anime', 'manga_path' => 'manga', + 'collection_path' => 'collection', + 'stats_path' => 'stats', // Which list should be the default? 'default_list' => 'anime', // anime or manga // Default pages for anime/manga - 'default_anime_path' => '/watching', - 'default_manga_path' => '/all', + 'default_anime_path' => "/anime/watching", + 'default_manga_path' => '/manga/all', // Default to list view? 'default_to_list_view' => FALSE, diff --git a/app/config/routes.php b/app/config/routes.php index 02c4241f..92e46c47 100644 --- a/app/config/routes.php +++ b/app/config/routes.php @@ -22,6 +22,43 @@ return [ 'path' => '/logout', 'action' => ['logout'] ], + ], + // Routes on collection controller + 'collection' => [ + 'collection_add_form' => [ + 'path' => '/collection/add', + 'action' => ['form'], + 'params' => [], + ], + 'collection_edit_form' => [ + 'path' => '/collection/edit/{id}', + 'action' => ['form'], + 'tokens' => [ + 'id' => '[0-9]+' + ] + ], + 'collection_add' => [ + 'path' => '/collection/add', + 'action' => ['add'], + 'verb' => 'post' + ], + 'collection_edit' => [ + 'path' => '/collection/edit', + 'action' => ['edit'], + 'verb' => 'post' + ], + 'collection' => [ + 'path' => '/collection/view{/view}', + 'action' => ['index'], + 'params' => [], + 'tokens' => [ + 'view' => '[a-z_]+' + ] + ], + ], + // Routes on stats controller + 'stats' => [ + ], // Routes on anime controller 'anime' => [ @@ -34,11 +71,11 @@ return [ ] ], 'search' => [ - 'path' => '/search', + 'path' => '/anime/search', 'action' => ['search'], ], 'all' => [ - 'path' => '/all{/view}', + 'path' => '/anime/all{/view}', 'action' => ['anime_list'], 'params' => [ 'type' => 'all', @@ -49,7 +86,7 @@ return [ ] ], 'watching' => [ - 'path' => '/watching{/view}', + 'path' => '/anime/watching{/view}', 'action' => ['anime_list'], 'params' => [ 'type' => 'currently-watching', @@ -60,7 +97,7 @@ return [ ] ], 'plan_to_watch' => [ - 'path' => '/plan_to_watch{/view}', + 'path' => '/anime/plan_to_watch{/view}', 'action' => ['anime_list'], 'params' => [ 'type' => 'plan-to-watch', @@ -71,7 +108,7 @@ return [ ] ], 'on_hold' => [ - 'path' => '/on_hold{/view}', + 'path' => '/anime/on_hold{/view}', 'action' => ['anime_list'], 'params' => [ 'type' => 'on-hold', @@ -82,7 +119,7 @@ return [ ] ], 'dropped' => [ - 'path' => '/dropped{/view}', + 'path' => '/anime/dropped{/view}', 'action' => ['anime_list'], 'params' => [ 'type' => 'dropped', @@ -93,7 +130,7 @@ return [ ] ], 'completed' => [ - 'path' => '/completed{/view}', + 'path' => '/anime/completed{/view}', 'action' => ['anime_list'], 'params' => [ 'type' => 'completed', @@ -103,36 +140,6 @@ return [ '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' => [ - 'path' => '/collection/view{/view}', - 'action' => ['collection'], - 'params' => [], - 'tokens' => [ - 'view' => '[a-z_]+' - ] - ], ], 'manga' => [ 'index' => [ @@ -145,7 +152,7 @@ return [ ] ], 'all' => [ - 'path' => '/all{/view}', + 'path' => '/manga/all{/view}', 'action' => ['manga_list'], 'params' => [ 'type' => 'all', @@ -156,7 +163,7 @@ return [ ] ], 'reading' => [ - 'path' => '/reading{/view}', + 'path' => '/manga/reading{/view}', 'action' => ['manga_list'], 'params' => [ 'type' => 'Reading', @@ -167,7 +174,7 @@ return [ ] ], 'plan_to_read' => [ - 'path' => '/plan_to_read{/view}', + 'path' => '/manga/plan_to_read{/view}', 'action' => ['manga_list'], 'params' => [ 'type' => 'Plan to Read', @@ -178,7 +185,7 @@ return [ ] ], 'on_hold' => [ - 'path' => '/on_hold{/view}', + 'path' => '/manga/on_hold{/view}', 'action' => ['manga_list'], 'params' => [ 'type' => 'On Hold', @@ -189,7 +196,7 @@ return [ ] ], 'dropped' => [ - 'path' => '/dropped{/view}', + 'path' => '/manga/dropped{/view}', 'action' => ['manga_list'], 'params' => [ 'type' => 'Dropped', @@ -200,7 +207,7 @@ return [ ] ], 'completed' => [ - 'path' => '/completed{/view}', + 'path' => '/manga/completed{/view}', 'action' => ['manga_list'], 'params' => [ 'type' => 'Completed', diff --git a/composer.json b/composer.json index 49ee5c41..cddb03de 100644 --- a/composer.json +++ b/composer.json @@ -1,11 +1,17 @@ { + "name": "timw4mail/hummingbird-anime-client", + "description": "A self-hosted anime/manga client for hummingbird.", + "license":"MIT", "require": { "guzzlehttp/guzzle": "5.3.*", - "filp/whoops": "1.1.*", + "filp/whoops": "dev-php7#fe32a402b086b21360e82013e8a0355575c7c6f4", "aura/router": "2.2.*", "aura/web": "2.0.*", - "aviat4ion/query": "2.0.*", - "robmorgan/phinx": "*", - "abeautifulsite/simpleimage": "*" + "aura/html": "2.*", + "aura/session": "2.*", + "aviat4ion/query": "2.5.*", + "robmorgan/phinx": "0.4.*", + "abeautifulsite/simpleimage": "2.5.*", + "szymach/c-pchart": "1.*" } } \ No newline at end of file diff --git a/index.php b/index.php index 4e9cdc85..87e8c089 100644 --- a/index.php +++ b/index.php @@ -3,8 +3,6 @@ * Here begins everything! */ -namespace AnimeClient; - // ----------------------------------------------------------------------------- // ! Start config // ----------------------------------------------------------------------------- @@ -30,9 +28,42 @@ if ($timezone === '' || $timezone === FALSE) // Define base directories define('ROOT_DIR', __DIR__); define('APP_DIR', ROOT_DIR . DIRECTORY_SEPARATOR . 'app'); +define('SRC_DIR', ROOT_DIR . DIRECTORY_SEPARATOR . 'src'); define('CONF_DIR', APP_DIR . DIRECTORY_SEPARATOR . 'config'); -define('BASE_DIR', APP_DIR . DIRECTORY_SEPARATOR . 'base'); -require BASE_DIR . DIRECTORY_SEPARATOR . 'pre_conf_functions.php'; +define('BASE_DIR', SRC_DIR . DIRECTORY_SEPARATOR . 'Base'); + +/** + * Joins paths together. Variadic to take an + * arbitrary number of arguments + * + * @return string + */ +function _dir() +{ + return implode(DIRECTORY_SEPARATOR, func_get_args()); +} + +/** + * Set up autoloaders + * + * @codeCoverageIgnore + * @return void + */ +function _setup_autoloaders() +{ + require _dir(ROOT_DIR, '/vendor/autoload.php'); + spl_autoload_register(function ($class) { + $class_parts = explode('\\', $class); + array_shift($class_parts); + $ns_path = SRC_DIR . '/' . implode('/', $class_parts) . ".php"; + + if (file_exists($ns_path)) + { + require_once($ns_path); + return; + } + }); +} // Setup autoloaders _setup_autoloaders(); diff --git a/phpdoc.dist.xml b/phpdoc.dist.xml index 7dd06d43..49c474b6 100644 --- a/phpdoc.dist.xml +++ b/phpdoc.dist.xml @@ -11,13 +11,7 @@