Merge branch 'develop' into 'master'

Develop

See merge request !14
This commit is contained in:
Timothy Warren 2017-02-28 16:58:53 -05:00
commit 7faaa06079
126 changed files with 3434 additions and 1196 deletions

View File

@ -1,38 +1,21 @@
# Composer stores all downloaded packages in the vendor/ directory.
# Do not use the following if the vendor/ directory is commited to
# your git repository.
cache:
paths:
- vendor/
services:
- redis:latest
test:7:
stage: test
before_script:
- bash build/docker_install.sh > /dev/null
- sh build/docker_install.sh > /dev/null
- apk add --no-cache php7-phpdbg
- curl -sS https://getcomposer.org/installer | php
- php composer.phar install --no-dev
image: php:7
- php composer.phar install --ignore-platform-reqs
image: php:7-alpine
script:
- phpunit -c build --coverage-text --colors=never
test:7.1:
before_script:
- bash build/docker_install.sh > /dev/null
- curl -sS https://getcomposer.org/installer | php
- php composer.phar install --no-dev
image: php:7.1
script:
- phpunit -c build --coverage-text --colors=never
- phpdbg -qrr -- ./vendor/bin/phpunit --coverage-text --colors=never
test:hhvm:
allow_failure: true
test:7.1:
stage: test
before_script:
- /usr/local/bin/composer self-update
- curl -Lo /usr/local/bin/phpunit https://phar.phpunit.de/phpunit.phar
- chmod +x /usr/local/bin/phpunit
- composer install --no-dev --ignore-platform-reqs
image: 51systems/docker-gitlab-ci-runner-hhvm
- sh build/docker_install.sh > /dev/null
- apk add --no-cache php7.1-phpdbg
- curl -sS https://getcomposer.org/installer | php
- php composer.phar install --ignore-platform-reqs
image: php:7.1-alpine
script:
- hhvm -d hhvm.php7.all=true /usr/local/bin/phpunit -c build --coverage-text --colors=never
- phpdbg -qrr -- ./vendor/bin/phpunit --coverage-text --colors=never

View File

@ -11,10 +11,7 @@ php:
script:
- mkdir -p build/logs
- vendor/bin/phpunit -c build
services:
- redis
- phpdbg -qrr -- vendor/bin/phpunit -c build
after_script:
- CODECLIMATE_REPO_TOKEN=2cbddcebcb9256b3402867282e119dbe61de0b31039325356af3c7d72ed6d058 vendor/bin/test-reporter

View File

@ -58,40 +58,6 @@ or
### Server Setup
#### Caching
Update `app/config/cache.toml` based on the instructions [here](https://git.timshomepage.net/timw4mail/banker/blob/master/README.md).
#### nginx
Basic nginx setup
```nginx
server {
location / {
try_files $uri $uri/ /index.php$uri?$args;
}
location ~ ^(.+\.php)($|/) {
fastcgi_split_path_info ^(.+\.php)(.*)$;
fastcgi_index index.php;
}
location ^~ /vendor {
deny all;
}
}
```
#### Apache
Make sure to have `mod_rewrite` and `AllowOverride All` enabled in order to take
advantage of the included `.htaccess` file. If you don't wish to use an `.htaccess` file,
include the contents of the `.htaccess` file in your Apache configuration.
#### Anime Collection Additional Installation
* Run `php /vendor/bin/phinx migrate -e development` to create the database tables
* For importing anime:
1. Login
2. Use the form to select your media
3. Save & Repeat as needed
See the [wiki](https://git.timshomepage.net/timw4mail/HummingBirdAnimeClient/wikis/home)
for more in-depth information

View File

@ -1,4 +1,7 @@
<?php
<?php declare(strict_types=1);
use Robo\Tasks;
if ( ! function_exists('glob_recursive'))
{
// Does not support flag GLOB_BRACE
@ -20,7 +23,7 @@ if ( ! function_exists('glob_recursive'))
*
* @see http://robo.li/
*/
class RoboFile extends \Robo\Tasks {
class RoboFile extends Tasks {
/**
* Directories used by analysis tools
@ -102,10 +105,7 @@ class RoboFile extends \Robo\Tasks {
*/
public function coverage()
{
$this->taskPhpUnit()
->configFile('build/phpunit.xml')
->printed(true)
->run();
$this->_run(['vendor/bin/phpunit -c build']);
}
/**
@ -114,9 +114,7 @@ class RoboFile extends \Robo\Tasks {
public function docs()
{
$cmd_parts = [
'cd build',
'../vendor/bin/phpdox',
'cd ..'
'phpdox',
];
$this->_run($cmd_parts, ' && ');
}
@ -128,7 +126,7 @@ class RoboFile extends \Robo\Tasks {
{
$files = $this->getAllSourceFiles();
$chunks = array_chunk($files, 6);
$chunks = array_chunk($files, 12);
foreach($chunks as $chunk)
{
@ -136,29 +134,6 @@ class RoboFile extends \Robo\Tasks {
}
}
/**
* Run mutation tests with humbug
*
* @param bool $stats - if true, generates stats rather than running mutation tests
*/
public function mutate($stats = FALSE)
{
$test_parts = [
'vendor/bin/humbug'
];
$stat_parts = [
'vendor/bin/humbug',
'--skip-killed=yes',
'-v',
'./build/humbug.json'
];
$cmd_parts = ($stats) ? $stat_parts : $test_parts;
$this->_run($cmd_parts);
}
/**
* Run the phpcs tool
*
@ -226,10 +201,8 @@ class RoboFile extends \Robo\Tasks {
public function test()
{
$this->lint();
$this->taskPHPUnit()
->configFile('phpunit.xml')
->printed(true)
->run();
$this->_run(['phpunit']);
}
/**
@ -275,7 +248,9 @@ class RoboFile extends \Robo\Tasks {
$files = array_merge(
glob_recursive('build/*.php'),
glob_recursive('src/*.php'),
glob_recursive('src/**/*.php'),
glob_recursive('tests/*.php'),
glob_recursive('tests/**/*.php'),
glob('*.php')
);

View File

@ -1,19 +1,20 @@
<?php
<?php declare(strict_types=1);
/**
* Hummingbird Anime Client
* Hummingbird Anime List Client
*
* An API client for Hummingbird to manage anime and manga watch lists
* An API client for Kitsu and MyAnimeList to manage anime and manga watch lists
*
* PHP version 5.6
* PHP version 7
*
* @package HummingbirdAnimeClient
* @author Timothy J. Warren <tim@timshomepage.net>
* @copyright 2015 - 2016 Timothy J. Warren
* @copyright 2015 - 2017 Timothy J. Warren
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version 3.1
* @version 4.0
* @link https://github.com/timw4mail/HummingBirdAnimeClient
*/
// ----------------------------------------------------------------------------
// Lower level configuration
//

View File

@ -1,19 +1,20 @@
<?php
<?php declare(strict_types=1);
/**
* Hummingbird Anime Client
* Hummingbird Anime List Client
*
* An API client for Hummingbird to manage anime and manga watch lists
* An API client for Kitsu and MyAnimeList to manage anime and manga watch lists
*
* PHP version 5.6
* PHP version 7
*
* @package HummingbirdAnimeClient
* @author Timothy J. Warren <tim@timshomepage.net>
* @copyright 2015 - 2016 Timothy J. Warren
* @copyright 2015 - 2017 Timothy J. Warren
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version 3.1
* @version 4.0
* @link https://github.com/timw4mail/HummingBirdAnimeClient
*/
return [
'anime_list' => [
'route_prefix' => '/anime',

View File

@ -1,16 +1,16 @@
<?php
<?php declare(strict_types=1);
/**
* Hummingbird Anime Client
* Hummingbird Anime List Client
*
* An API client for Hummingbird to manage anime and manga watch lists
* An API client for Kitsu and MyAnimeList to manage anime and manga watch lists
*
* PHP version 5.6
* PHP version 7
*
* @package HummingbirdAnimeClient
* @author Timothy J. Warren <tim@timshomepage.net>
* @copyright 2015 - 2016 Timothy J. Warren
* @copyright 2015 - 2017 Timothy J. Warren
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version 3.1
* @version 4.0
* @link https://github.com/timw4mail/HummingBirdAnimeClient
*/

View File

@ -1,19 +1,20 @@
<?php
<?php declare(strict_types=1);
/**
* Hummingbird Anime Client
* Hummingbird Anime List Client
*
* An API client for Hummingbird to manage anime and manga watch lists
* An API client for Kitsu and MyAnimeList to manage anime and manga watch lists
*
* PHP version 5.6
* PHP version 7
*
* @package HummingbirdAnimeClient
* @author Timothy J. Warren <tim@timshomepage.net>
* @copyright 2015 - 2016 Timothy J. Warren
* @copyright 2015 - 2017 Timothy J. Warren
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version 3.1
* @version 4.0
* @link https://github.com/timw4mail/HummingBirdAnimeClient
*/
// --------------------------------------------------------------------------
/**

View File

@ -1,19 +1,20 @@
<?php
<?php declare(strict_types=1);
/**
* Hummingbird Anime Client
* Hummingbird Anime List Client
*
* An API client for Hummingbird to manage anime and manga watch lists
* An API client for Kitsu and MyAnimeList to manage anime and manga watch lists
*
* PHP version 5.6
* PHP version 7
*
* @package HummingbirdAnimeClient
* @author Timothy J. Warren <tim@timshomepage.net>
* @copyright 2015 - 2016 Timothy J. Warren
* @copyright 2015 - 2017 Timothy J. Warren
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version 3.1
* @version 4.0
* @link https://github.com/timw4mail/HummingBirdAnimeClient
*/
// --------------------------------------------------------------------------
/**

View File

@ -1,19 +1,20 @@
<?php
<?php declare(strict_types=1);
/**
* Hummingbird Anime Client
* Hummingbird Anime List Client
*
* An API client for Hummingbird to manage anime and manga watch lists
* An API client for Kitsu and MyAnimeList to manage anime and manga watch lists
*
* PHP version 5.6
* PHP version 7
*
* @package HummingbirdAnimeClient
* @author Timothy J. Warren <tim@timshomepage.net>
* @copyright 2015 - 2016 Timothy J. Warren
* @copyright 2015 - 2017 Timothy J. Warren
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version 3.1
* @version 4.0
* @link https://github.com/timw4mail/HummingBirdAnimeClient
*/
use const Aviat\AnimeClient\{
DEFAULT_CONTROLLER_METHOD,
DEFAULT_CONTROLLER_NAMESPACE
@ -53,7 +54,7 @@ return [
// ---------------------------------------------------------------------
'anime.add.get' => [
'path' => '/anime/add',
'action' => 'add_form',
'action' => 'addForm',
'verb' => 'get',
],
'anime.add.post' => [
@ -82,7 +83,7 @@ return [
],
'manga.add.get' => [
'path' => '/manga/add',
'action' => 'add_form',
'action' => 'addForm',
'verb' => 'get',
],
'manga.add.post' => [
@ -183,7 +184,7 @@ return [
],
'update.post' => [
'path' => '/{controller}/update_form',
'action' => 'form_update',
'action' => 'formUpdate',
'verb' => 'post',
'tokens' => [
'controller' => '[a-z_]+',

View File

@ -1,12 +1,12 @@
<?php declare(strict_types=1);
/**
* Anime List Client
* Hummingbird Anime List Client
*
* An API client for Kitsu and MyAnimeList to manage anime and manga watch lists
*
* PHP version 7
*
* @package AnimeListClient
* @package HummingbirdAnimeClient
* @author Timothy J. Warren <tim@timshomepage.net>
* @copyright 2015 - 2017 Timothy J. Warren
* @license http://www.opensource.org/licenses/mit-license.html MIT License

View File

@ -11,14 +11,8 @@ whose_list = "Tim"
# do you wish to show the anime collection?
show_anime_collection = true
# do you wish to show the manga collection?
show_manga_collection = false
# do you have a My Anime List account set up in mal.toml?
use_mal_api = false
# cache driver for api calls (NullDriver, SQLDriver, RedisDriver)
cache_driver = "NullDriver"
# path to public directory on the server
asset_dir = "/../../public"

View File

@ -8,16 +8,5 @@ host = ""
user = ""
pass = ""
port = ""
name = "default"
database = ""
file = "anime_collection.sqlite"
[cache]
type = "sqlite"
host = ""
user = ""
pass = ""
port = ""
name = "default"
database = ""
file = "anime_collection.sqlite"

View File

@ -1,4 +1,4 @@
<?php if ($auth->is_authenticated()): ?>
<?php if ($auth->isAuthenticated()): ?>
<main>
<h2>Add Anime to your List</h2>
<form action="<?= $action_url ?>" method="post">
@ -36,5 +36,5 @@
</table>
</form>
</main>
<script src="<?= $urlGenerator->asset_url('js.php/g/anime_collection') ?>"></script>
<script defer="defer" src="<?= $urlGenerator->assetUrl('js.php/g/anime_collection') ?>"></script>
<?php endif ?>

View File

@ -1,5 +1,5 @@
<main>
<?php if ($auth->is_authenticated()): ?>
<?php if ($auth->isAuthenticated()): ?>
<a class="bracketed" href="<?= $url->generate('anime.add.get') ?>">Add Item</a>
<?php endif ?>
<?php if (empty($sections)): ?>
@ -10,9 +10,9 @@
<h2><?= $escape->html($name) ?></h2>
<section class="media-wrap">
<?php foreach($items as $item): ?>
<?php if ($item['private'] && ! $auth->is_authenticated()) continue; ?>
<?php if ($item['private'] && ! $auth->isAuthenticated()) continue; ?>
<article class="media" data-kitsu-id="<?= $item['id'] ?>" data-mal-id="<?= $item['mal_id'] ?>">
<?php if ($auth->is_authenticated()): ?>
<?php if ($auth->isAuthenticated()): ?>
<button title="Increment episode count" class="plus_one" hidden>+1 Episode</button>
<?php endif ?>
<img src="<?= $item['anime']['image'] ?>" alt="" />
@ -25,10 +25,16 @@
</a>
</div>
<div class="table">
<?php if ($auth->is_authenticated()): ?>
<?php if ($auth->isAuthenticated()): ?>
<div class="row">
<span class="edit">
<a class="bracketed" title="Edit information about this anime" href="<?= $urlGenerator->url("anime/edit/{$item['id']}/{$item['watching_status']}") ?>">Edit</a>
<a class="bracketed" title="Edit information about this anime" href="<?=
$url->generate('edit', [
'controller' => 'anime',
'id' => $item['id'],
'status' => $item['watching_status']
]);
?>">Edit</a>
</span>
</div>
<?php endif ?>
@ -55,10 +61,10 @@
<div class="cover_streaming_link">
<?php if($link['meta']['link']): ?>
<a href="<?= $link['link']?>" title="Stream '<?= $item['anime']['title'] ?>' on <?= $link['meta']['name'] ?>">
<?= $link['meta']['logo'] ?>
<img class="streaming-logo" width="20" height="20" src="<?= $urlGenerator->assetUrl('images', $link['meta']['image']) ?>" alt="<?= $link['meta']['name'] ?> logo" />
</a>
<?php else: ?>
<?= $link['meta']['logo'] ?>
<img class="streaming-logo" width="20" height="20" src="<?= $urlGenerator->assetUrl('images', $link['meta']['image']) ?>" alt="<?= $link['meta']['name'] ?> logo" />
<?php endif ?>
</div>
<?php endforeach ?>
@ -85,6 +91,6 @@
<?php endforeach ?>
<?php endif ?>
</main>
<?php if ($auth->is_authenticated()): ?>
<script src="<?= $urlGenerator->asset_url('js.php/g/edit') ?>"></script>
<?php if ($auth->isAuthenticated()): ?>
<script defer="defer" src="<?= $urlGenerator->assetUrl('js.php/g/edit') ?>"></script>
<?php endif ?>

View File

@ -1,7 +1,7 @@
<main class="details">
<section class="flex flex-no-wrap">
<div>
<img class="cover" src="<?= $data['cover_image'] ?>" alt="" />
<img class="cover" width="402" height="284" src="<?= $data['cover_image'] ?>" alt="" />
<br />
<br />
<table class="media_details">
@ -54,21 +54,21 @@
</tr>
</thead>
<tbody>
<?php foreach($data['streaming_links'] as $streaming_link): ?>
<?php foreach($data['streaming_links'] as $link): ?>
<tr>
<td class="align_left">
<?php if ($streaming_link['meta']['link'] !== FALSE): ?>
<a href="<?= $streaming_link['link'] ?>">
<?= $streaming_link['meta']['logo'] ?>
&nbsp;&nbsp;<?= $streaming_link['meta']['name'] ?>
<?php if ($link['meta']['link'] !== FALSE): ?>
<a href="<?= $link['link'] ?>" title="Stream '<?= $data['title'] ?>' on <?= $link['meta']['name'] ?>">
<img class="streaming-logo" width="50" height="50" src="<?= $urlGenerator->assetUrl('images', $link['meta']['image']) ?>" alt="<?= $link['meta']['name'] ?> logo" />
&nbsp;&nbsp;<?= $link['meta']['name'] ?>
</a>
<?php else: ?>
<?= $streaming_link['meta']['logo'] ?>
&nbsp;&nbsp;<?= $streaming_link['meta']['name'] ?>
<img class="streaming-logo" width="50" height="50" src="<?= $urlGenerator->assetUrl('images', $link['meta']['image']) ?>" alt="<?= $link['meta']['name'] ?> logo" />
&nbsp;&nbsp;<?= $link['meta']['name'] ?>
<?php endif ?>
</td>
<td><?= implode(', ', $streaming_link['subs']) ?></td>
<td><?= implode(', ', $streaming_link['dubs']) ?></td>
<td><?= implode(', ', $link['subs']) ?></td>
<td><?= implode(', ', $link['dubs']) ?></td>
</tr>
<?php endforeach ?>
</tbody>

View File

@ -1,4 +1,4 @@
<?php if ($auth->is_authenticated()): ?>
<?php if ($auth->isAuthenticated()): ?>
<main>
<h2>Edit Anime List Item</h2>
<form action="<?= $action ?>" method="post">
@ -107,5 +107,5 @@
</form>
</fieldset>
</main>
<script src="<?= $urlGenerator->asset_url('js.php/g/edit') ?>"></script>
<script defer="defer" src="<?= $urlGenerator->assetUrl('js.php/g/edit') ?>"></script>
<?php endif ?>

View File

@ -1,5 +1,5 @@
<main>
<?php if ($auth->is_authenticated()): ?>
<?php if ($auth->isAuthenticated()): ?>
<a class="bracketed" href="<?= $url->generate('anime.add.get') ?>">Add Item</a>
<?php endif ?>
<?php if (empty($sections)): ?>
@ -10,7 +10,7 @@
<table>
<thead>
<tr>
<?php if($auth->is_authenticated()): ?>
<?php if($auth->isAuthenticated()): ?>
<td class="no_border">&nbsp;</td>
<?php endif ?>
<th>Title</th>
@ -26,9 +26,9 @@
</thead>
<tbody>
<?php foreach($items as $item): ?>
<?php if ($item['private'] && ! $auth->is_authenticated()) continue; ?>
<?php if ($item['private'] && ! $auth->isAuthenticated()) continue; ?>
<tr id="a-<?= $item['id'] ?>">
<?php if ($auth->is_authenticated()): ?>
<?php if ($auth->isAuthenticated()): ?>
<td>
<a class="bracketed" href="<?= $urlGenerator->url("/anime/edit/{$item['id']}/{$item['watching_status']}") ?>">Edit</a>
</td>
@ -64,11 +64,11 @@
<td>
<?php foreach($item['anime']['streaming_links'] as $link): ?>
<?php if ($link['meta']['link'] !== FALSE): ?>
<a href="<?= $link['link'] ?>">
<?= $link['meta']['logo'] ?>
<a href="<?= $link['link'] ?>" title="Stream '<?= $item['anime']['title'] ?>' on <?= $link['meta']['name'] ?>">
<img class="streaming-logo" width="50" height="50" src="<?= $urlGenerator->assetUrl('images', $link['meta']['image']) ?>" alt="<?= $link['meta']['name'] ?> logo" />
</a>
<?php else: ?>
<?= $link['meta']['logo'] ?>
<img class="streaming-logo" width="50" height="50" src="<?= $urlGenerator->assetUrl('images', $link['meta']['image']) ?>" alt="<?= $link['meta']['name'] ?> logo" />
<?php endif ?>
<?php endforeach ?>
</td>
@ -86,5 +86,5 @@
<?php endforeach ?>
<?php endif ?>
</main>
<?php $group = ($auth->is_authenticated()) ? 'table_edit' : 'table' ?>
<script src="<?= $urlGenerator->asset_url("js.php/g/{$group}") ?>"></script>
<?php $group = ($auth->isAuthenticated()) ? 'table_edit' : 'table' ?>
<script defer="defer" src="<?= $urlGenerator->assetUrl("js.php/g/{$group}") ?>"></script>

View File

@ -1,4 +1,4 @@
<?php if ($auth->is_authenticated()): ?>
<?php if ($auth->isAuthenticated()): ?>
<main>
<h2>Add Anime to your Collection</h2>
<form action="<?= $action_url ?>" method="post">
@ -39,5 +39,5 @@
</table>
</form>
</main>
<script src="<?= $urlGenerator->asset_url('js.php/g/anime_collection') ?>"></script>
<script defer="defer" src="<?= $urlGenerator->assetUrl('js.php/g/anime_collection') ?>"></script>
<?php endif ?>

View File

@ -1,5 +1,5 @@
<main>
<?php if ($auth->is_authenticated()): ?>
<?php if ($auth->isAuthenticated()): ?>
<a class="bracketed" href="<?= $url->generate('collection.add.get') ?>">Add Item</a>
<?php endif ?>
<?php if (empty($sections)): ?>
@ -19,7 +19,7 @@
</a>
</div>
<div class="table">
<?php if ($auth->is_authenticated()): ?>
<?php if ($auth->isAuthenticated()): ?>
<div class="row">
<span class="edit"><a class="bracketed" href="<?= $urlGenerator->url("collection/edit/{$item['hummingbird_id']}") ?>">Edit</a></span>
<?php /*<span class="delete"><a class="bracketed" href="<?= $urlGenerator->url("collection/delete/{$item['hummingbird_id']}") ?>">Delete</a></span> */ ?>

View File

@ -1,4 +1,4 @@
<?php if ($auth->is_authenticated()): ?>
<?php if ($auth->isAuthenticated()): ?>
<main>
<h2>Edit Anime Collection Item</h2>
<form action="<?= $action_url ?>" method="post">
@ -62,5 +62,5 @@
</form>
</fieldset>
</main>
<script src="<?= $urlGenerator->asset_url('js.php/g/anime_collection') ?>"></script>
<script defer="defer" src="<?= $urlGenerator->assetUrl('js.php/g/anime_collection') ?>"></script>
<?php endif ?>

View File

@ -1,6 +1,6 @@
<main>
<?php if ($auth->is_authenticated()): ?>
<a class="bracketed" href="<?= $urlGenerator->full_url('collection/add', 'anime') ?>">Add Item</a>
<?php if ($auth->isAuthenticated()): ?>
<a class="bracketed" href="<?= $urlGenerator->fullUrl('collection/add', 'anime') ?>">Add Item</a>
<?php endif ?>
<?php if (empty($sections)): ?>
<h3>There's nothing here!</h3>
@ -10,7 +10,7 @@
<table>
<thead>
<tr>
<?php if($auth->is_authenticated()): ?>
<?php if($auth->isAuthenticated()): ?>
<th>Actions</th>
<?php endif ?>
<th>Title</th>
@ -24,10 +24,10 @@
<tbody>
<?php foreach($items as $item): ?>
<tr>
<?php if($auth->is_authenticated()): ?>
<?php if($auth->isAuthenticated()): ?>
<td>
<a class="bracketed" href="<?= $urlGenerator->full_url("collection/edit/{$item['hummingbird_id']}") ?>">Edit</a>
<?php /*<a class="bracketed" href="<?= $urlGenerator->full_url("collection/delete/{$item['hummingbird_id']}") ?>">Delete</a>*/ ?>
<a class="bracketed" href="<?= $urlGenerator->fullUrl("collection/edit/{$item['hummingbird_id']}") ?>">Edit</a>
<?php /*<a class="bracketed" href="<?= $urlGenerator->fullUrl("collection/delete/{$item['hummingbird_id']}") ?>">Delete</a>*/ ?>
</td>
<?php endif ?>
<td class="align_left">
@ -49,4 +49,4 @@
<?php endforeach ?>
<?php endif ?>
</main>
<script src="<?= $urlGenerator->asset_url('js.php/g/table') ?>"></script>
<script defer="defer" src="<?= $urlGenerator->assetUrl('js.php/g/table') ?>"></script>

View File

@ -1,3 +1,3 @@
<script src="<?= $urlGenerator->asset_url('js.php/g/event') ?>"></script>
<script defer="defer" src="<?= $urlGenerator->assetUrl('js.php/g/event') ?>"></script>
</body>
</html>

View File

@ -6,15 +6,18 @@
<meta http-equiv="cache-control" content="no-store" />
<meta http-equiv="Content-Security-Policy" content="script-src 'self'" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1, user-scalable=0" />
<link rel="icon" href="/favicon.ico" />
<link rel="stylesheet" href="<?= $urlGenerator->asset_url('css.php/g/base') ?>" />
<script src="<?= $urlGenerator->asset_url('js.php/g/base') ?>"></script>
<link rel="icon" href="<?= $urlGenerator->assetUrl('favicon.ico') ?>" />
<link rel="stylesheet" href="<?= $urlGenerator->assetUrl('css.php/g/base/debug') ?>" />
<script defer="defer" src="<?= $urlGenerator->assetUrl('js.php/g/base') ?>"></script>
</head>
<body class="<?= $escape->attr($url_type) ?> list">
<header>
<?php include 'main-menu.php' ?>
<?php if(isset($message) && is_array($message)):
extract($message);
include 'message.php';
foreach($message as $m)
{
extract($m);
include 'message.php';
}
endif ?>
</header>

View File

@ -2,22 +2,22 @@
<h1 class="flex flex-align-end flex-wrap">
<span class="flex-no-wrap grow-1">
<?php if(strpos($route_path, 'collection') === FALSE): ?>
<a href="<?= $escape->attr($urlGenerator->default_url($url_type)) ?>">
<a href="<?= $escape->attr($urlGenerator->defaultUrl($url_type)) ?>">
<?= $config->get('whose_list') ?>'s <?= ucfirst($url_type) ?> List
</a>
<?php if($config->get("show_{$url_type}_collection")): ?>
[<a href="<?= $urlGenerator->url('collection/view') ?>"><?= ucfirst($url_type) ?> Collection</a>]
<?php endif ?>
[<a href="<?= $urlGenerator->default_url($other_type) ?>"><?= ucfirst($other_type) ?> List</a>]
[<a href="<?= $urlGenerator->defaultUrl($other_type) ?>"><?= ucfirst($other_type) ?> List</a>]
<?php else: ?>
<a href="<?= $urlGenerator->url('collection/view') ?>">
<?= $config->get('whose_list') ?>'s <?= ucfirst($url_type) ?> Collection
</a>
[<a href="<?= $urlGenerator->default_url('anime') ?>">Anime List</a>]
[<a href="<?= $urlGenerator->default_url('manga') ?>">Manga List</a>]
[<a href="<?= $urlGenerator->defaultUrl('anime') ?>">Anime List</a>]
[<a href="<?= $urlGenerator->defaultUrl('manga') ?>">Manga List</a>]
<?php endif ?>
</span>
<?php if ($auth->is_authenticated()): ?>
<?php if ($auth->isAuthenticated()): ?>
<span class="flex-no-wrap">&nbsp;</span>
<span class="flex-no-wrap small-font">
<button type="button" class="js-clear-cache user-btn">Clear API Cache</button>
@ -25,7 +25,7 @@
<span class="flex-no-wrap">&nbsp;</span>
<?php endif ?>
<span class="flex-no-wrap small-font">
<?php if ($auth->is_authenticated()): ?>
<?php if ($auth->isAuthenticated()): ?>
<a class="bracketed" href="<?= $url->generate('logout') ?>">Logout</a>
<?php else: ?>
[<a href="<?= $url->generate('login'); ?>"><?= $config->get('whose_list') ?>'s Login</a>]
@ -33,12 +33,12 @@
</span>
</h1>
<nav>
<?php if ($container->get('util')->is_view_page()): ?>
<?php if ($container->get('util')->isViewPage()): ?>
<?= $helper->menu($menu_name) ?>
<br />
<ul>
<li class="<?= Util::is_not_selected('list', $urlGenerator->last_segment()) ?>"><a href="<?= $urlGenerator->url($route_path) ?>">Cover View</a></li>
<li class="<?= Util::is_selected('list', $urlGenerator->last_segment()) ?>"><a href="<?= $urlGenerator->url("{$route_path}/list") ?>">List View</a></li>
<li class="<?= Util::isNotSelected('list', $urlGenerator->lastSegment()) ?>"><a href="<?= $urlGenerator->url($route_path) ?>">Cover View</a></li>
<li class="<?= Util::isSelected('list', $urlGenerator->lastSegment()) ?>"><a href="<?= $urlGenerator->url("{$route_path}/list") ?>">List View</a></li>
</ul>
<?php endif ?>
</nav>

View File

@ -1,4 +1,4 @@
<?php if ($auth->is_authenticated()): ?>
<?php if ($auth->isAuthenticated()): ?>
<main>
<h2>Add Manga to your List</h2>
<form action="<?= $action_url ?>" method="post">
@ -36,5 +36,5 @@
</table>
</form>
</main>
<script src="<?= $urlGenerator->asset_url('js.php/g/manga_collection') ?>"></script>
<script defer="defer" src="<?= $urlGenerator->assetUrl('js.php/g/manga_collection') ?>"></script>
<?php endif ?>

View File

@ -1,5 +1,5 @@
<main>
<?php if ($auth->is_authenticated()): ?>
<?php if ($auth->isAuthenticated()): ?>
<a class="bracketed" href="<?= $urlGenerator->url('manga/add') ?>">Add Item</a>
<?php endif ?>
<?php if (empty($sections)): ?>
@ -11,7 +11,7 @@
<section class="media-wrap">
<?php foreach($items as $item): ?>
<article class="media" id="manga-<?= $item['id'] ?>">
<?php if ($auth->is_authenticated()): ?>
<?php if ($auth->isAuthenticated()): ?>
<div class="edit_buttons" hidden>
<button class="plus_one_chapter">+1 Chapter</button>
</div>
@ -26,7 +26,7 @@
</a>
</div>
<div class="table">
<?php if ($auth->is_authenticated()): ?>
<?php if ($auth->isAuthenticated()): ?>
<div class="row">
<span class="edit">
<a class="bracketed" title="Edit information about this manga" href="<?= $urlGenerator->url("manga/edit/{$item['id']}/{$name}") ?>">Edit</a>
@ -55,6 +55,6 @@
<?php endforeach ?>
<?php endif ?>
</main>
<?php if ($auth->is_authenticated()): ?>
<script src="<?= $urlGenerator->asset_url('js.php/g/edit') ?>"></script>
<?php if ($auth->isAuthenticated()): ?>
<script defer="defer" src="<?= $urlGenerator->assetUrl('js.php/g/edit') ?>"></script>
<?php endif ?>

View File

@ -1,4 +1,4 @@
<?php if ($auth->is_authenticated()): ?>
<?php if ($auth->isAuthenticated()): ?>
<main>
<h1>
Edit <?= $item['manga']['titles'][0] ?>

View File

@ -1,7 +1,7 @@
<main>
<?php /*if ($auth->is_authenticated()): ?>
<?php if ($auth->isAuthenticated()): ?>
<a class="bracketed" href="<?= $urlGenerator->url('manga/add') ?>">Add Item</a>
<?php endif*/ ?>
<?php endif ?>
<?php if (empty($sections)): ?>
<h3>There's nothing here!</h3>
<?php else: ?>
@ -10,7 +10,7 @@
<table>
<thead>
<tr>
<?php if ($auth->is_authenticated()): ?>
<?php if ($auth->isAuthenticated()): ?>
<th>&nbsp;</th>
<?php endif ?>
<th>Title</th>
@ -23,7 +23,7 @@
<tbody>
<?php foreach($items as $item): ?>
<tr id="manga-<?= $item['id'] ?>">
<?php if($auth->is_authenticated()): ?>
<?php if($auth->isAuthenticated()): ?>
<td>
<a class="bracketed" href="<?= $urlGenerator->url("manga/edit/{$item['id']}/{$name}") ?>">Edit</a>
</td>
@ -47,4 +47,4 @@
<?php endforeach ?>
<?php endif ?>
</main>
<script src="<?= $urlGenerator->asset_url('js.php/g/table') ?>"></script>
<script defer="defer" src="<?= $urlGenerator->assetUrl('js.php/g/table') ?>"></script>

View File

@ -65,7 +65,7 @@ class LogicalNotSpacingSniff implements Sniff
$next_token = $tokens[$stackPtr + 1];
if (T_WHITESPACE !== $previous_token['code'] || T_WHITESPACE !== $next_token['code']) {
$error = 'Logical operator ! should always be preceded and followed with a whitespace.';
$phpcsFile->addError($error, $stackPtr);
$phpcsFile->addError($error, $stackPtr, 'badNot');
}
}//end process()

View File

@ -3,27 +3,10 @@
# We need to install dependencies only for Docker
[[ ! -e /.dockerenv ]] && [[ ! -e /.dockerinit ]] && exit 0
# Where am I?
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
set -xe
# Install git (the php image doesn't have it) which is required by composer
apt-get update -yqq
apt-get install \
git \
libxslt1-dev \
libxslt1.1 \
zlib1g-dev \
unzip \
-yqq
# Install phpunit, the tool that we will use for testing
curl -Lo /usr/local/bin/phpunit https://phar.phpunit.de/phpunit.phar
chmod +x /usr/local/bin/phpunit
# Install extensions
pecl install xdebug
echo "zend_extension=$(find /usr/local/lib/php/extensions/ -name xdebug.so)" > /usr/local/etc/php/conf.d/xdebug.ini
docker-php-ext-install xsl
docker-php-ext-install zip
echo -e 'http://dl-cdn.alpinelinux.org/alpine/edge/main\nhttp://dl-cdn.alpinelinux.org/alpine/edge/community\nhttp://dl-cdn.alpinelinux.org/alpine/edge/testing' > /etc/apk/repositories
apk upgrade --update && apk add --no-cache \
curl \
git

View File

@ -1,11 +1,11 @@
/**
* Anime List Client
* Hummingbird Anime List Client
*
* An API client for Kitsu and MyAnimeList to manage anime and manga watch lists
*
* PHP version 7
*
* @package AnimeListClient
* @package HummingbirdAnimeClient
* @author Timothy J. Warren <tim@timshomepage.net>
* @copyright 2015 - 2017 Timothy J. Warren
* @license http://www.opensource.org/licenses/mit-license.html MIT License

View File

@ -5,7 +5,9 @@ $file_patterns = [
'app/bootstrap.php',
'migrations/*.php',
'src/**/*.php',
'src/*.php',
'tests/**/*.php',
'tests/*.php'
];
if ( ! function_exists('glob_recursive'))
@ -60,6 +62,7 @@ function get_tokens($source)
function replace_files(array $files, $template)
{
print_r($files);
foreach ($files as $file)
{
$source = file_get_contents($file);

View File

@ -1,5 +1,5 @@
{
"name": "timw4mail/hummingbird-anime-client",
"name": "aviat/hummingbird-anime-client",
"description": "A self-hosted anime/manga client for Kitsu.",
"license":"MIT",
"autoload": {
@ -21,7 +21,7 @@
"aura/router": "^3.0",
"aura/session": "^2.0",
"aviat/banker": "^1.0.0",
"aviat/ion": "1.0.*",
"aviat/ion": "dev-master",
"filp/whoops": "^2.1.5",
"monolog/monolog": "^1.0",
"psr/http-message": "~1.0",
@ -34,18 +34,23 @@
"require-dev": {
"pdepend/pdepend": "^2.2",
"sebastian/phpcpd": "^3.0",
"theseer/phpdox": "^0.9.0",
"theseer/phpdox": "0.9.0",
"phploc/phploc": "^3.0",
"phpmd/phpmd": "^2.4",
"phpunit/phpunit": "^6.0",
"robmorgan/phinx": "^0.6.4",
"robmorgan/phinx": "~0.6.4",
"consolidation/robo": "~1.0",
"henrikbjorn/lurker": "^1.1.0",
"symfony/var-dumper": "^3.1",
"squizlabs/php_codesniffer": "^3.0.0@beta"
"squizlabs/php_codesniffer": "^3.0.0@beta",
"phpstan/phpstan": "^0.6.4"
},
"scripts": {
"build:css": "cd public && npm run build && cd ..",
"watch:css": "cd public && npm run watch"
"coverage": "phpdbg -qrr -- vendor/bin/phpunit -c build",
"docs": "vendor/bin/phpdox",
"phpstan": "phpstan analyse src tests",
"watch:css": "cd public && npm run watch",
"test": "vendor/bin/phpunit"
}
}
}

View File

@ -28,25 +28,14 @@ if ($timezone === '' || $timezone === FALSE)
ini_set('date.timezone', 'GMT');
}
/**
* Joins paths together. Variadic to take an
* arbitrary number of arguments
*
* @return string
*/
function _dir()
{
return implode(DIRECTORY_SEPARATOR, func_get_args());
}
// Load composer autoloader
require __DIR__ . '/vendor/autoload.php';
// Define base directories
$APP_DIR = _dir(__DIR__, 'app');
$APPCONF_DIR = _dir($APP_DIR, 'appConf');
$CONF_DIR = _dir($APP_DIR, 'config');
// Load composer autoloader
require _dir(__DIR__, 'vendor/autoload.php');
// -------------------------------------------------------------------------
// Setup error handling
// -------------------------------------------------------------------------

View File

@ -8,11 +8,11 @@
<target>phpdoc</target>
</transformer>
<transformations>
<template name="zend" />
<template name="clean" />
</transformations>
<files>
<directory>src</directory>
<directory>vendor/aviat/ion/src</directory>
<directory>vendor/container-interop/container-interop/src</directory>
<!-- <directory>vendor/aviat/ion/src</directory>
<directory>vendor/container-interop/container-interop/src</directory> -->
</files>
</phpdoc>

View File

@ -9,7 +9,7 @@
<bootstrap />
<!-- A phpDox project to process, you can have multiple projects in one config file -->
<project name="Hummingbird Anime Client" source="../src" workdir="phpdox/xml">
<project name="Hummingbird Anime Client" source="src" workdir="build/phpdox/xml">
<!-- @name - The name of the project -->
<!-- @source - The source directory of the application to process -->
<!-- @workdir - The directory to store the xml data files in -->
@ -56,12 +56,12 @@
</collector>
<!-- Configuration of generation process -->
<generator output="../docs">
<generator output="docs">
<!-- @output - (Base-)Directory to store output data in -->
<!-- A generation process consists of one or more build tasks and of (optional) enrich sources -->
<enrich base="logs">
<enrich base="build/logs">
<!-- @base - (Base-)Directory of datafiles used for enrich process -->
<!--<source type="...">-->
@ -117,10 +117,10 @@
<!-- An engine and thus build node can have additional configuration child nodes, please check the documentation for the engine to find out more -->
<!-- default engine "html" -->
<build engine="html" enabled="true">
<template dir="${phpDox.home}/templates/html" />
<build engine="html" output="html" />
<!-- <template dir="${phpDox.home}/templates/html" /> -
<file extension="html" />
</build>
</build> -->
</generator>
</project>

View File

@ -1,19 +1,20 @@
<?php declare(strict_types=1);
/**
* Hummingbird Anime Client
* Hummingbird Anime List Client
*
* An API client for Hummingbird to manage anime and manga watch lists
* An API client for Kitsu and MyAnimeList to manage anime and manga watch lists
*
* PHP version 7
*
* @package HummingbirdAnimeClient
* @author Timothy J. Warren <tim@timshomepage.net>
* @copyright 2015 - 2016 Timothy J. Warren
* @copyright 2015 - 2017 Timothy J. Warren
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version 3.1
* @version 4.0
* @link https://github.com/timw4mail/HummingBirdAnimeClient
*/
namespace Aviat\EasyMin;
require_once('./min.php');
@ -23,21 +24,21 @@ require_once('./min.php');
*/
class CSSMin extends BaseMin {
protected $css_root;
protected $path_from;
protected $path_to;
protected $cssRoot;
protected $pathFrom;
protected $pathTo;
protected $group;
protected $last_modified;
protected $requested_time;
protected $lastModified;
protected $requestedTime;
public function __construct(array $config, array $groups)
{
$group = $_GET['g'];
$this->css_root = $config['css_root'];
$this->path_from = $config['path_from'];
$this->path_to = $config['path_to'];
$this->cssRoot = $config['css_root'];
$this->pathFrom = $config['path_from'];
$this->pathTo = $config['path_to'];
$this->group = $groups[$group];
$this->last_modified = $this->get_last_modified();
$this->lastModified = $this->getLastModified();
$this->send();
}
@ -49,14 +50,14 @@ class CSSMin extends BaseMin {
*/
protected function send()
{
if($this->last_modified >= $this->get_if_modified() && $this->is_not_debug())
if($this->lastModified >= $this->getIfModified() && $this->isNotDebug())
{
throw new FileNotChangedException();
}
$css = ( ! array_key_exists('debug', $_GET))
? $this->compress($this->get_css())
: $this->get_css();
? $this->compress($this->getCss())
: $this->getCss();
$this->output($css);
}
@ -74,7 +75,7 @@ class CSSMin extends BaseMin {
//Remove tabs, spaces, newlines, etc.
$buffer = preg_replace('`\s+`', ' ', $buffer);
$replace = array(
$replace = [
' )' => ')',
') ' => ')',
' }' => '}',
@ -84,7 +85,7 @@ class CSSMin extends BaseMin {
', ' => ',',
': ' => ':',
'; ' => ';',
);
];
//Eradicate every last space!
$buffer = trim(strtr($buffer, $replace));
@ -99,17 +100,17 @@ class CSSMin extends BaseMin {
*
* @return int
*/
protected function get_last_modified()
protected function getLastModified()
{
$modified = array();
$modified = [];
// Get all the css files, and concatenate them together
if(isset($this->group))
{
foreach($this->group as $file)
{
$new_file = realpath("{$this->css_root}{$file}");
$modified[] = filemtime($new_file);
$newFile = realpath("{$this->cssRoot}{$file}");
$modified[] = filemtime($newFile);
}
}
@ -127,19 +128,19 @@ class CSSMin extends BaseMin {
*
* @return string
*/
protected function get_css()
protected function getCss()
{
$css = '';
foreach($this->group as $file)
{
$new_file = realpath("{$this->css_root}{$file}");
$css .= file_get_contents($new_file);
$newFile = realpath("{$this->cssRoot}{$file}");
$css .= file_get_contents($newFile);
}
// Correct paths that have changed due to concatenation
// based on rules in the config file
$css = str_replace($this->path_from, $this->path_to, $css);
$css = str_replace($this->pathFrom, $this->pathTo, $css);
return $css;
}
@ -151,7 +152,7 @@ class CSSMin extends BaseMin {
*/
protected function output($css)
{
$this->send_final_output($css, 'text/css', $this->last_modified);
$this->sendFinalOutput($css, 'text/css', $this->lastModified);
}
}

View File

@ -371,7 +371,7 @@ hr
img
{
height:auto;
max-width:100%;
/* max-width:100%; */
vertical-align:baseline;
}
@ -1035,6 +1035,10 @@ a:hover, a:active {
margin:0.25em 0.125em;
}
.media > img {
width: 100%;
}
.media .edit_buttons > button {
margin:0.5em auto;
}
@ -1044,6 +1048,7 @@ a:hover, a:active {
.medium_metadata > div,
.row {
text-shadow:1px 2px 1px rgba(0, 0, 0, .85);
background:#000;
background:rgba(0, 0, 0, .45);
color:#ffffff;
padding:0.25em 0.125em;
@ -1127,6 +1132,7 @@ a:hover, a:active {
.anime .row, .manga .row {
width:100%;
background:#000;
background:rgba(0, 0, 0, .45);
display: -webkit-box;
display: -ms-flexbox;
@ -1316,6 +1322,7 @@ a:hover, a:active {
.streaming-logo {
width: 50px;
height: 50px;
vertical-align:middle;
}
.cover_streaming_link .streaming-logo {

View File

@ -4,6 +4,7 @@
--link-shadow: 1px 1px 1px #000;
--shadow: 1px 2px 1px rgba(0, 0, 0, 0.85);
--title-overlay: rgba(0, 0, 0, 0.45);
--title-overlay-fallback: #000;
--text-color: #ffffff;
--normal-padding: 0.25em 0.125em;
--link-hover-color: #7d12db;
@ -306,6 +307,10 @@ a:hover, a:active {
margin: var(--normal-padding);
}
.media > img {
width: 100%;
}
.media .edit_buttons > button {
margin:0.5em auto;
}
@ -315,6 +320,7 @@ a:hover, a:active {
.medium_metadata > div,
.row {
text-shadow: var(--shadow);
background: var(--title-overlay-fallback);
background: var(--title-overlay);
color: var(--text-color);
padding: var(--normal-padding);
@ -398,6 +404,7 @@ a:hover, a:active {
.anime .row, .manga .row {
width:100%;
background: var(--title-overlay-fallback);
background: var(--title-overlay);
display: flex;
align-content: space-around;
@ -568,6 +575,7 @@ a:hover, a:active {
.streaming-logo {
width: 50px;
height: 50px;
vertical-align:middle;
}
.cover_streaming_link .streaming-logo {

View File

@ -337,7 +337,7 @@ hr
img
{
height:auto;
max-width:100%;
/* max-width:100%; */
vertical-align:baseline;
}

View File

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@ -1,16 +1,16 @@
<?php declare(strict_types=1);
/**
* Hummingbird Anime Client
* Hummingbird Anime List Client
*
* An API client for Hummingbird to manage anime and manga watch lists
* An API client for Kitsu and MyAnimeList to manage anime and manga watch lists
*
* PHP version 7
*
* @package HummingbirdAnimeClient
* @author Timothy J. Warren <tim@timshomepage.net>
* @copyright 2015 - 2016 Timothy J. Warren
* @copyright 2015 - 2017 Timothy J. Warren
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version 3.1
* @version 4.0
* @link https://github.com/timw4mail/HummingBirdAnimeClient
*/
@ -29,27 +29,27 @@ require_once('./min.php');
*/
class JSMin extends BaseMin {
protected $js_root;
protected $js_group;
protected $js_groups_file;
protected $cache_file;
protected $jsRoot;
protected $jsGroup;
protected $jsGroupsFile;
protected $cacheFile;
protected $last_modified;
protected $requested_time;
protected $cache_modified;
protected $lastModified;
protected $requestedTime;
protected $cacheModified;
public function __construct(array $config, array $groups)
{
$group = $_GET['g'];
$this->js_root = $config['js_root'];
$this->js_group = $groups[$group];
$this->js_groups_file = $config['js_groups_file'];
$this->cache_file = "{$this->js_root}cache/{$group}";
$this->last_modified = $this->get_last_modified();
$this->jsRoot = $config['js_root'];
$this->jsGroup = $groups[$group];
$this->jsGroupsFile = $config['js_groups_file'];
$this->cacheFile = "{$this->jsRoot}cache/{$group}";
$this->lastModified = $this->getLastModified();
$this->cache_modified = (is_file($this->cache_file))
? filemtime($this->cache_file)
$this->cacheModified = (is_file($this->cacheFile))
? filemtime($this->cacheFile)
: 0;
// Output some JS!
@ -59,24 +59,24 @@ class JSMin extends BaseMin {
protected function send()
{
// Override caching if debug key is set
if($this->is_debug_call())
if($this->isDebugCall())
{
return $this->output($this->get_files());
return $this->output($this->getFiles());
}
// If the browser's cached version is up to date,
// don't resend the file
if($this->last_modified == $this->get_if_modified() && $this->is_not_debug())
if($this->lastModified == $this->getIfModified() && $this->isNotDebug())
{
throw new FileNotChangedException();
}
if($this->cache_modified < $this->last_modified)
if($this->cacheModified < $this->lastModified)
{
$js = $this->minify($this->get_files());
$js = $this->minify($this->getFiles());
//Make sure cache file gets created/updated
if (file_put_contents($this->cache_file, $js) === FALSE)
if (file_put_contents($this->cacheFile, $js) === FALSE)
{
echo 'Cache file was not created. Make sure you have the correct folder permissions.';
return;
@ -86,7 +86,7 @@ class JSMin extends BaseMin {
}
else
{
return $this->output(file_get_contents($this->cache_file));
return $this->output(file_get_contents($this->cacheFile));
}
}
@ -96,7 +96,7 @@ class JSMin extends BaseMin {
* @param array $options - Form parameters
* @return object
*/
protected function closure_call(array $options)
protected function closureCall(array $options)
{
$formFields = http_build_query($options);
@ -123,19 +123,19 @@ class JSMin extends BaseMin {
* @param array $options
* @return void
*/
protected function check_minify_errors($options)
protected function checkMinifyErrors($options)
{
$error_res = $this->closure_call($options);
$error_json = $error_res->getBody();
$error_obj = Json::decode($error_json) ?: (object)[];
$errorRes = $this->closureCall($options);
$errorJson = $errorRes->getBody();
$errorObj = Json::decode($errorJson) ?: (object)[];
// Show error if exists
if ( ! empty($error_obj->errors) || ! empty($error_obj->serverErrors))
if ( ! empty($errorObj->errors) || ! empty($errorObj->serverErrors))
{
$error_json = Json::encode($error_obj, JSON_PRETTY_PRINT);
$errorJson = Json::encode($errorObj, JSON_PRETTY_PRINT);
header('Content-type: application/javascript');
echo "console.error(${error_json});";
echo "console.error(${errorJson});";
die();
}
}
@ -148,14 +148,14 @@ class JSMin extends BaseMin {
*
* @return string
*/
protected function get_files()
protected function getFiles()
{
$js = '';
foreach($this->js_group as $file)
foreach($this->jsGroup as $file)
{
$new_file = realpath("{$this->js_root}{$file}");
$js .= file_get_contents($new_file) . "\n\n";
$newFile = realpath("{$this->jsRoot}{$file}");
$js .= file_get_contents($newFile) . "\n\n";
}
return $js;
@ -166,24 +166,24 @@ class JSMin extends BaseMin {
*
* @return int
*/
protected function get_last_modified()
protected function getLastModified()
{
$modified = array();
$modified = [];
foreach($this->js_group as $file)
foreach($this->jsGroup as $file)
{
$new_file = realpath("{$this->js_root}{$file}");
$modified[] = filemtime($new_file);
$newFile = realpath("{$this->jsRoot}{$file}");
$modified[] = filemtime($newFile);
}
//Add this page too, as well as the groups file
$modified[] = filemtime(__FILE__);
$modified[] = filemtime($this->js_groups_file);
$modified[] = filemtime($this->jsGroupsFile);
rsort($modified);
$last_modified = $modified[0];
$lastModified = $modified[0];
return $last_modified;
return $lastModified;
}
/**
@ -205,11 +205,11 @@ class JSMin extends BaseMin {
];
// Check for errors
$this->check_minify_errors($options);
$this->checkMinifyErrors($options);
// Now actually retrieve the compiled code
$options['output_info'] = 'compiled_code';
$res = $this->closure_call($options);
$res = $this->closureCall($options);
$json = $res->getBody();
$obj = Json::decode($json);
@ -225,7 +225,7 @@ class JSMin extends BaseMin {
*/
protected function output($js)
{
$this->send_final_output($js, 'application/javascript', $this->last_modified);
$this->sendFinalOutput($js, 'application/javascript', $this->lastModified);
}
}
@ -235,11 +235,11 @@ class JSMin extends BaseMin {
$config = require_once('../app/appConf/minify_config.php');
$groups = require_once($config['js_groups_file']);
$cache_dir = "{$config['js_root']}cache";
$cacheDir = "{$config['js_root']}cache";
if ( ! is_dir($cache_dir))
if ( ! is_dir($cacheDir))
{
mkdir($cache_dir);
mkdir($cacheDir);
}
if ( ! array_key_exists($_GET['g'], $groups))

View File

@ -4,7 +4,7 @@
const search = (tempHtml, query) => {
_.$('.cssload-loader')[0].removeAttribute('hidden');
_.get(_.url('/collection/search'), {'query':query}, (searchResults, status) => {
_.get(_.url('/collection/search'), {query}, (searchResults, status) => {
searchResults = JSON.parse(searchResults);
_.$('.cssload-loader')[0].setAttribute('hidden', 'hidden');
@ -18,7 +18,7 @@
});
};
_.get('/public/templates/anime-ajax-search-results.html', tempHtml => {
_.get('/public/templates/anime-ajax-search-results.html', (tempHtml) => {
_.on('#search', 'keyup', _.throttle(250, function(e) {
let query = encodeURIComponent(this.value);
if (query === '') {

View File

@ -6,48 +6,47 @@
'use strict';
// Action to increment episode count
_.on('body.anime.list', 'click', '.plus_one', e => {
let parent_sel = _.closestParent(e.target, 'article');
let watched_count = parseInt(_.$('.completed_number', parent_sel)[0].textContent, 10);
let total_count = parseInt(_.$('.total_number', parent_sel)[0].textContent, 10);
let title = _.$('.name a', parent_sel)[0].textContent;
_.on('body.anime.list', 'click', '.plus_one', (e) => {
let parentSel = _.closestParent(e.target, 'article');
let watchedCount = parseInt(_.$('.completed_number', parentSel)[0].textContent, 10);
let totalCount = parseInt(_.$('.total_number', parentSel)[0].textContent, 10);
let title = _.$('.name a', parentSel)[0].textContent;
// Setup the update data
let data = {
id: parent_sel.dataset.kitsuId,
mal_id: parent_sel.dataset.malId,
id: parentSel.dataset.kitsuId,
mal_id: parentSel.dataset.malId,
data: {
progress: watched_count + 1
progress: watchedCount + 1
}
};
// If the episode count is 0, and incremented,
// change status to currently watching
if (isNaN(watched_count) || watched_count === 0) {
if (isNaN(watchedCount) || watchedCount === 0) {
data.data.status = 'current';
}
// If you increment at the last episode, mark as completed
if (( ! isNaN(watched_count)) && (watched_count + 1) == total_count) {
if (( ! isNaN(watchedCount)) && (watchedCount + 1) === totalCount) {
data.data.status = 'completed';
}
// okay, lets actually make some changes!
_.ajax(_.url('/anime/update'), {
data: data,
data,
dataType: 'json',
type: 'POST',
success: () => {
if (data.data.status == 'completed') {
_.hide(parent_sel);
if (data.data.status === 'completed') {
_.hide(parentSel);
}
_.showMessage('success', `Successfully updated ${title}`);
_.$('.completed_number', parent_sel)[0].textContent = ++watched_count;
_.$('.completed_number', parentSel)[0].textContent = ++watchedCount;
_.scrollToTop();
},
error: (xhr, errorType, error) => {
console.error(error);
_.showMessage('error', `Failed to update ${title}. `);
_.scrollToTop();
}

View File

@ -26,7 +26,7 @@ var AnimeClient = (function(w) {
* @return {array} - array of dom elements
*/
$(selector, context) {
if (typeof selector != "string" || selector === undefined) {
if (typeof selector !== 'string') {
return selector;
}
@ -78,10 +78,10 @@ var AnimeClient = (function(w) {
*/
showMessage(type, message) {
let template =
`<div class="message ${type}">
<span class="icon"></span>
`<div class='message ${type}'>
<span class='icon'></span>
${message}
<span class="close"></span>
<span class='close'></span>
</div>`;
let sel = AnimeClient.$('.message');
@ -200,7 +200,7 @@ var AnimeClient = (function(w) {
delegateEvent(el, target, event, listener);
});
}
}
};
// -------------------------------------------------------------------------
// ! Ajax
@ -225,8 +225,8 @@ var AnimeClient = (function(w) {
pairs.push(`${name}=${value}`);
});
return pairs.join("&");
};
return pairs.join('&');
}
/**
* Make an ajax request
@ -255,7 +255,7 @@ var AnimeClient = (function(w) {
let request = new XMLHttpRequest();
let method = String(config.type).toUpperCase();
if (method === "GET") {
if (method === 'GET') {
url += (url.match(/\?/))
? ajaxSerialize(config.data)
: `?${ajaxSerialize(config.data)}`;
@ -267,7 +267,7 @@ var AnimeClient = (function(w) {
if (request.readyState === 4) {
let responseText = '';
if (request.responseType == 'json') {
if (request.responseType === 'json') {
responseText = JSON.parse(request.responseText);
} else {
responseText = request.responseText;
@ -291,7 +291,7 @@ var AnimeClient = (function(w) {
request.setRequestHeader('Content-Type', config.mimeType);
switch (method) {
case "GET":
case 'GET':
request.send(null);
break;
@ -308,7 +308,7 @@ var AnimeClient = (function(w) {
}
return _.ajax(url, {
data: data,
data,
success: callback
});
};

View File

@ -11,8 +11,8 @@
});
// Confirm deleting of list or library items
ac.on('form.js-delete', 'submit', function (event) {
let proceed = confirm("Are you ABSOLUTELY SURE you want to delete this item?");
ac.on('form.js-delete', 'submit', (event) => {
const proceed = confirm('Are you ABSOLUTELY SURE you want to delete this item?');
if (proceed === false) {
event.preventDefault();
@ -21,9 +21,9 @@
});
// Clear the api cache
ac.on('.js-clear-cache', 'click', function () {
ac.on('.js-clear-cache', 'click', () => {
ac.get('/cache_purge', () => {
ac.showMessage('success', `Sucessfully purged api cache`);
ac.showMessage('success', 'Successfully purged api cache');
});
});

View File

@ -4,7 +4,7 @@
const search = (tempHtml, query) => {
_.$('.cssload-loader')[0].removeAttribute('hidden');
_.get(_.url('/manga/search'), {'query':query,}, (searchResults, status) => {
_.get(_.url('/manga/search'), {query}, (searchResults, status) => {
searchResults = JSON.parse(searchResults);
_.$('.cssload-loader')[0].setAttribute('hidden', 'hidden');
@ -13,7 +13,7 @@
});
};
_.get('/public/templates/manga-ajax-search-results.html', tempHtml => {
_.get('/public/templates/manga-ajax-search-results.html', (tempHtml) => {
_.on('#search', 'keyup', _.throttle(250, function(e) {
let query = encodeURIComponent(this.value);
if (query === '') {

View File

@ -5,14 +5,14 @@
'use strict';
_.on('.manga.list', 'click', '.edit_buttons button', e => {
let this_sel = e.target;
let parent_sel = _.closestParent(e.target, 'article');
let manga_id = parent_sel.id.replace("manga-", "");
let type = this_sel.classList.contains("plus_one_chapter") ? 'chapter' : 'volume';
let completed = parseInt(_.$(`.${type}s_read`, parent_sel)[0].textContent, 10);
let total = parseInt(_.$(`.${type}_count`, parent_sel)[0].textContent, 10);
let manga_name = _.$('.name', parent_sel)[0].textContent;
_.on('.manga.list', 'click', '.edit_buttons button', (e) => {
let thisSel = e.target;
let parentSel = _.closestParent(e.target, 'article');
let mangaId = parentSel.id.replace('manga-', '');
let type = thisSel.classList.contains('plus_one_chapter') ? 'chapter' : 'volume';
let completed = parseInt(_.$(`.${type}s_read`, parentSel)[0].textContent, 10);
let total = parseInt(_.$(`.${type}_count`, parentSel)[0].textContent, 10);
let mangaName = _.$('.name', parentSel)[0].textContent;
if (isNaN(completed)) {
completed = 0;
@ -20,7 +20,7 @@
// Setup the update data
let data = {
id: manga_id,
id: mangaId,
data: {
progress: completed
}
@ -33,7 +33,7 @@
}
// If you increment at the last chapter, mark as completed
if (( ! isNaN(completed)) && (completed + 1) == total) {
if (( ! isNaN(completed)) && (completed + 1) === total) {
data.data.status = 'completed';
}
@ -41,22 +41,21 @@
data.data.progress = ++completed;
_.ajax(_.url('/manga/update'), {
data: data,
data,
dataType: 'json',
type: 'POST',
mimeType: 'application/json',
success: () => {
if (data.data.status == 'completed') {
_.hide(parent_sel);
if (data.data.status === 'completed') {
_.hide(parentSel);
}
_.$(`.${type}s_read`, parent_sel)[0].textContent = completed;
_.showMessage('success', `Sucessfully updated ${manga_name}`);
_.$(`.${type}s_read`, parentSel)[0].textContent = completed;
_.showMessage('success', `Sucessfully updated ${mangaName}`);
_.scrollToTop();
},
error: (xhr, errorType, error) => {
console.error(error);
_.showMessage('error', `Failed to updated ${manga_name}`);
error: () => {
_.showMessage('error', `Failed to updated ${mangaName}`);
_.scrollToTop();
}
});

View File

@ -1,26 +1,30 @@
<?php
<?php declare(strict_types=1);
/**
* Hummingbird Anime Client
* Hummingbird Anime List Client
*
* An API client for Hummingbird to manage anime and manga watch lists
* An API client for Kitsu and MyAnimeList to manage anime and manga watch lists
*
* @package HummingbirdAnimeClient
* @author Timothy J. Warren
* @copyright Copyright (c) 2015 - 2016
* @link https://github.com/timw4mail/HummingBirdAnimeClient
* @license MIT
* PHP version 7
*
* @package HummingbirdAnimeClient
* @author Timothy J. Warren <tim@timshomepage.net>
* @copyright 2015 - 2017 Timothy J. Warren
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version 4.0
* @link https://github.com/timw4mail/HummingBirdAnimeClient
*/
namespace Aviat\EasyMin;
//Creative rewriting of /g/groupname to ?g=groupname
$pi = $_SERVER['PATH_INFO'];
$pia = explode('/', $pi);
$pia_len = count($pia);
$piaLen = count($pia);
$i = 1;
while($i < $pia_len)
while($i < $piaLen)
{
$j = $i+1;
$j = (isset($pia[$j])) ? $j : $i;
@ -38,7 +42,7 @@ class BaseMin {
*
* @return int - timestamp to compare for cache control
*/
protected function get_if_modified()
protected function getIfModified()
{
return (array_key_exists('HTTP_IF_MODIFIED_SINCE', $_SERVER))
? strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE'])
@ -50,7 +54,7 @@ class BaseMin {
*
* @return string - the etag to compare
*/
protected function get_if_none_match()
protected function getIfNoneMatch()
{
return (array_key_exists('HTTP_IF_NONE_MATCH', $_SERVER))
? $_SERVER['HTTP_IF_NONE_MATCH']
@ -62,9 +66,9 @@ class BaseMin {
*
* @return boolean
*/
protected function is_not_debug()
protected function isNotDebug()
{
return ! $this->is_debug_call();
return ! $this->isDebugCall();
}
/**
@ -72,7 +76,7 @@ class BaseMin {
*
* @return boolean
*/
protected function is_debug_call()
protected function isDebugCall()
{
return array_key_exists('debug', $_GET);
}
@ -81,24 +85,24 @@ class BaseMin {
* Send actual output to browser
*
* @param string $content - the body of the response
* @param string $mime_type - the content type
* @param int $last_modified - the last modified date
* @param string $mimeType - the content type
* @param int $lastModified - the last modified date
* @return void
*/
protected function send_final_output($content, $mime_type, $last_modified)
protected function sendFinalOutput($content, $mimeType, $lastModified)
{
//This GZIPs the CSS for transmission to the user
//making file size smaller and transfer rate quicker
ob_start("ob_gzhandler");
$expires = $last_modified + 691200;
$last_modified_date = gmdate('D, d M Y H:i:s', $last_modified);
$expires_date = gmdate('D, d M Y H:i:s', $expires);
$expires = $lastModified + 691200;
$lastModifiedDate = gmdate('D, d M Y H:i:s', $lastModified);
$expiresDate = gmdate('D, d M Y H:i:s', $expires);
header("Content-Type: {$mime_type}; charset=utf8");
header("Content-Type: {$mimeType}; charset=utf8");
header("Cache-control: public, max-age=691200, must-revalidate");
header("Last-Modified: {$last_modified_date} GMT");
header("Expires: {$expires_date} GMT");
header("Last-Modified: {$lastModifiedDate} GMT");
header("Expires: {$expiresDate} GMT");
echo $content;

1979
public/yarn.lock Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1,12 +1,12 @@
<?php declare(strict_types=1);
/**
* Anime List Client
* Hummingbird Anime List Client
*
* An API client for Kitsu and MyAnimeList to manage anime and manga watch lists
*
* PHP version 7
*
* @package AnimeListClient
* @package HummingbirdAnimeClient
* @author Timothy J. Warren <tim@timshomepage.net>
* @copyright 2015 - 2017 Timothy J. Warren
* @license http://www.opensource.org/licenses/mit-license.html MIT License
@ -207,6 +207,7 @@ class APIRequestBuilder {
*
* @param string $type
* @param string $uri
* @throws InvalidArgumentException
* @return self
*/
public function newRequest(string $type, string $uri): self

View File

@ -1,12 +1,12 @@
<?php declare(strict_types=1);
/**
* Anime List Client
* Hummingbird Anime List Client
*
* An API client for Kitsu and MyAnimeList to manage anime and manga watch lists
*
* PHP version 7
*
* @package AnimeListClient
* @package HummingbirdAnimeClient
* @author Timothy J. Warren <tim@timshomepage.net>
* @copyright 2015 - 2017 Timothy J. Warren
* @license http://www.opensource.org/licenses/mit-license.html MIT License

View File

@ -1,12 +1,12 @@
<?php declare(strict_types=1);
/**
* Anime List Client
* Hummingbird Anime List Client
*
* An API client for Kitsu and MyAnimeList to manage anime and manga watch lists
*
* PHP version 7
*
* @package AnimeListClient
* @package HummingbirdAnimeClient
* @author Timothy J. Warren <tim@timshomepage.net>
* @copyright 2015 - 2017 Timothy J. Warren
* @license http://www.opensource.org/licenses/mit-license.html MIT License

View File

@ -1,12 +1,12 @@
<?php declare(strict_types=1);
/**
* Anime List Client
* Hummingbird Anime List Client
*
* An API client for Kitsu and MyAnimeList to manage anime and manga watch lists
*
* PHP version 7
*
* @package AnimeListClient
* @package HummingbirdAnimeClient
* @author Timothy J. Warren <tim@timshomepage.net>
* @copyright 2015 - 2017 Timothy J. Warren
* @license http://www.opensource.org/licenses/mit-license.html MIT License
@ -18,6 +18,9 @@ namespace Aviat\AnimeClient\API;
use UnexpectedValueException;
/**
* Exception for an API Request that fails validation
*/
class FailedResponseException extends UnexpectedValueException {
}

View File

@ -1,12 +1,12 @@
<?php declare(strict_types=1);
/**
* Anime List Client
* Hummingbird Anime List Client
*
* An API client for Kitsu and MyAnimeList to manage anime and manga watch lists
*
* PHP version 7
*
* @package AnimeListClient
* @package HummingbirdAnimeClient
* @author Timothy J. Warren <tim@timshomepage.net>
* @copyright 2015 - 2017 Timothy J. Warren
* @license http://www.opensource.org/licenses/mit-license.html MIT License
@ -27,7 +27,7 @@ class JsonAPI {
* The full data array
*
* Basic structure is generally like so:
* @example [
* [
* 'id' => '12016665',
* 'type' => 'libraryEntries',
* 'links' => [

View File

@ -1,12 +1,12 @@
<?php declare(strict_types=1);
/**
* Anime List Client
* Hummingbird Anime List Client
*
* An API client for Kitsu and MyAnimeList to manage anime and manga watch lists
*
* PHP version 7
*
* @package AnimeListClient
* @package HummingbirdAnimeClient
* @author Timothy J. Warren <tim@timshomepage.net>
* @copyright 2015 - 2017 Timothy J. Warren
* @license http://www.opensource.org/licenses/mit-license.html MIT License
@ -74,7 +74,7 @@ class Kitsu {
* @param string $endDate
* @return string
*/
public static function getAiringStatus(string $startDate = null, string $endDate = null): string
public static function getAiringStatus(string $startDate = NULL, string $endDate = NULL): string
{
$startAirDate = new DateTimeImmutable($startDate ?? 'tomorrow');
$endAirDate = new DateTimeImmutable($endDate ?? 'next year');
@ -83,7 +83,7 @@ class Kitsu {
$isDoneAiring = $now > $endAirDate;
$isCurrentlyAiring = ($now > $startAirDate) && ! $isDoneAiring;
switch (true)
switch (TRUE)
{
case $isCurrentlyAiring:
return AnimeAiringStatus::AIRING;
@ -102,29 +102,29 @@ class Kitsu {
* @param string $hostname
* @return array
*/
protected static function getServiceMetaData(string $hostname = null): array
protected static function getServiceMetaData(string $hostname = NULL): array
{
switch($hostname)
{
case 'www.crunchyroll.com':
return [
'name' => 'Crunchyroll',
'link' => true,
'logo' => '<svg class="streaming-logo" viewBox="0 0 50 50" xmlns="http://www.w3.org/2000/svg"><g fill="#F78B24" fill-rule="evenodd"><path d="M22.549 49.145c-.815-.077-2.958-.456-3.753-.663-6.873-1.79-12.693-6.59-15.773-13.009C1.335 31.954.631 28.807.633 24.788c.003-4.025.718-7.235 2.38-10.686 1.243-2.584 2.674-4.609 4.706-6.66 3.8-3.834 8.614-6.208 14.067-6.936 1.783-.239 5.556-.161 7.221.148 3.463.642 6.571 1.904 9.357 3.797 5.788 3.934 9.542 9.951 10.52 16.861.21 1.48.332 4.559.19 4.816-.077.14-.117-.007-.167-.615-.25-3.015-1.528-6.66-3.292-9.388C40.253 7.836 30.249 4.32 20.987 7.467c-7.15 2.43-12.522 8.596-13.997 16.06-.73 3.692-.51 7.31.658 10.882a21.426 21.426 0 0 0 13.247 13.518c1.475.515 3.369.944 4.618 1.047 1.496.122 1.119.239-.727.224-1.006-.008-2.013-.032-2.237-.053z"></path><path d="M27.685 46.1c-7.731-.575-14.137-6.455-15.474-14.204-.243-1.41-.29-4.047-.095-5.345 1.16-7.706 6.97-13.552 14.552-14.639 1.537-.22 4.275-.143 5.746.162 1.28.266 2.7.737 3.814 1.266l.865.411-.814.392c-2.936 1.414-4.748 4.723-4.323 7.892.426 3.173 2.578 5.664 5.667 6.56 1.112.322 2.812.322 3.925 0 1.438-.417 2.566-1.1 3.593-2.173.346-.362.652-.621.68-.576.027.046.106.545.176 1.11.171 1.395.07 4.047-.204 5.371-.876 4.218-3.08 7.758-6.463 10.374-3.2 2.476-7.434 3.711-11.645 3.399z"></path></g></svg>'
'link' => TRUE,
'image' => 'streaming-logos/crunchyroll.svg',
];
case 'www.funimation.com':
return [
'name' => 'Funimation',
'link' => true,
'logo' => '<svg class="streaming-logo" viewBox="0 0 50 50" xmlns="http://www.w3.org/2000/svg"><path d="M24.066.017a24.922 24.922 0 0 1 13.302 3.286 25.098 25.098 0 0 1 7.833 7.058 24.862 24.862 0 0 1 4.207 9.575c.82 4.001.641 8.201-.518 12.117a24.946 24.946 0 0 1-4.868 9.009 24.98 24.98 0 0 1-7.704 6.118 24.727 24.727 0 0 1-10.552 2.718A24.82 24.82 0 0 1 13.833 47.3c-5.815-2.872-10.408-8.107-12.49-14.25-2.162-6.257-1.698-13.375 1.303-19.28C5.483 8.07 10.594 3.55 16.602 1.435A24.94 24.94 0 0 1 24.066.017zm-8.415 33.31c.464 2.284 1.939 4.358 3.99 5.48 2.174 1.217 4.765 1.444 7.202 1.181 2.002-.217 3.986-.992 5.455-2.397 1.173-1.151 2.017-2.648 2.33-4.267-1.189-.027-2.378 0-3.566-.03-.568.082-1.137-.048-1.705.014-1.232.012-2.465.003-3.697-.01-.655.066-1.309-.035-1.963.013-1.166-.053-2.334.043-3.5-.025-1.515.08-3.03-.035-4.546.042z" fill="#411299" fill-rule="evenodd"></path></svg>'
'link' => TRUE,
'image' => 'streaming-logos/funimation.svg',
];
case 'www.hulu.com':
return [
'name' => 'Hulu',
'link' => true,
'logo' => '<svg class="streaming-logo" viewBox="0 0 34 50" xmlns="http://www.w3.org/2000/svg"><path d="M22.222 13.889h-11.11V0H0v50h11.111V27.778c0-1.39 1.111-2.778 2.778-2.778h5.555c1.39 0 2.778 1.111 2.778 2.778V50h11.111V25c0-6.111-5-11.111-11.11-11.111z" fill="#8BC34A" fill-rule="evenodd"></path></svg>'
'link' => TRUE,
'image' => 'streaming-logos/hulu.svg',
];
// Default to Netflix, because the API links are broken,
@ -132,8 +132,8 @@ class Kitsu {
default:
return [
'name' => 'Netflix',
'link' => false,
'logo' => '<svg class="streaming-logo" viewBox="0 0 26 50" xmlns="http://www.w3.org/2000/svg"><path d="M.057.258C2.518.253 4.982.263 7.446.253c2.858 7.76 5.621 15.556 8.456 23.324.523 1.441 1.003 2.897 1.59 4.312.078-9.209.01-18.42.034-27.631h7.763v46.36c-2.812.372-5.637.627-8.457.957-1.203-3.451-2.396-6.902-3.613-10.348-1.796-5.145-3.557-10.302-5.402-15.428.129 8.954.015 17.912.057 26.871-2.603.39-5.227.637-7.815 1.119C.052 33.279.06 16.768.057.258z" fill="#E21221" fill-rule="evenodd"></path></svg>'
'link' => FALSE,
'image' => 'streaming-logos/netflix.svg',
];
}
}
@ -172,6 +172,7 @@ class Kitsu {
* Reorganize streaming links for the current list item
*
* @param array $included
* @param string $animeId
* @return array
*/
public static function parseListItemStreamingLinks(array $included, string $animeId): array
@ -235,11 +236,11 @@ class Kitsu {
* @param array $existingTitles
* @return bool
*/
private static function titleIsUnique(string $title = null, array $existingTitles): bool
private static function titleIsUnique(string $title = NULL, array $existingTitles = []): bool
{
if (empty($title))
{
return false;
return FALSE;
}
foreach($existingTitles as $existing)
@ -248,12 +249,12 @@ class Kitsu {
$diff = levenshtein($existing, $title);
$onlydifferentCase = (mb_strtolower($existing) === mb_strtolower($title));
if ($diff < 3 || $isSubset || $onlydifferentCase)
if ($diff < 3 OR $isSubset OR $onlydifferentCase)
{
return false;
return FALSE;
}
}
return true;
return TRUE;
}
}

View File

@ -1,12 +1,12 @@
<?php declare(strict_types=1);
/**
* Anime List Client
* Hummingbird Anime List Client
*
* An API client for Kitsu and MyAnimeList to manage anime and manga watch lists
*
* PHP version 7
*
* @package AnimeListClient
* @package HummingbirdAnimeClient
* @author Timothy J. Warren <tim@timshomepage.net>
* @copyright 2015 - 2017 Timothy J. Warren
* @license http://www.opensource.org/licenses/mit-license.html MIT License
@ -36,14 +36,14 @@ class Auth {
/**
* Anime API Model
*
* @var \Aviat\AnimeClient\API\Kitsu\Model
* @var Model
*/
protected $model;
/**
* Session object
*
* @var Aura\Session\Segment
* @var \Aura\Session\Segment
*/
protected $segment;
@ -102,7 +102,7 @@ class Auth {
*
* @return boolean
*/
public function is_authenticated()
public function isAuthenticated()
{
return ($this->get_auth_token() !== FALSE);
}

View File

@ -1,12 +1,12 @@
<?php declare(strict_types=1);
/**
* Anime List Client
* Hummingbird Anime List Client
*
* An API client for Kitsu and MyAnimeList to manage anime and manga watch lists
*
* PHP version 7
*
* @package AnimeListClient
* @package HummingbirdAnimeClient
* @author Timothy J. Warren <tim@timshomepage.net>
* @copyright 2015 - 2017 Timothy J. Warren
* @license http://www.opensource.org/licenses/mit-license.html MIT License

View File

@ -1,12 +1,12 @@
<?php declare(strict_types=1);
/**
* Anime List Client
* Hummingbird Anime List Client
*
* An API client for Kitsu and MyAnimeList to manage anime and manga watch lists
*
* PHP version 7
*
* @package AnimeListClient
* @package HummingbirdAnimeClient
* @author Timothy J. Warren <tim@timshomepage.net>
* @copyright 2015 - 2017 Timothy J. Warren
* @license http://www.opensource.org/licenses/mit-license.html MIT License

View File

@ -1,12 +1,12 @@
<?php declare(strict_types=1);
/**
* Anime List Client
* Hummingbird Anime List Client
*
* An API client for Kitsu and MyAnimeList to manage anime and manga watch lists
*
* PHP version 7
*
* @package AnimeListClient
* @package HummingbirdAnimeClient
* @author Timothy J. Warren <tim@timshomepage.net>
* @copyright 2015 - 2017 Timothy J. Warren
* @license http://www.opensource.org/licenses/mit-license.html MIT License

View File

@ -1,12 +1,12 @@
<?php declare(strict_types=1);
/**
* Anime List Client
* Hummingbird Anime List Client
*
* An API client for Kitsu and MyAnimeList to manage anime and manga watch lists
*
* PHP version 7
*
* @package AnimeListClient
* @package HummingbirdAnimeClient
* @author Timothy J. Warren <tim@timshomepage.net>
* @copyright 2015 - 2017 Timothy J. Warren
* @license http://www.opensource.org/licenses/mit-license.html MIT License
@ -16,8 +16,10 @@
namespace Aviat\AnimeClient\API\Kitsu;
use Aviat\AnimeClient\API\APIRequestBuilder;
use Aviat\AnimeClient\API\Kitsu as K;
use Aviat\AnimeClient\API\{
APIRequestBuilder,
Kitsu as K
};
use Aviat\Ion\Json;
class KitsuRequestBuilder extends APIRequestBuilder {

View File

@ -1,12 +1,12 @@
<?php declare(strict_types=1);
/**
* Anime List Client
* Hummingbird Anime List Client
*
* An API client for Kitsu and MyAnimeList to manage anime and manga watch lists
*
* PHP version 7
*
* @package AnimeListClient
* @package HummingbirdAnimeClient
* @author Timothy J. Warren <tim@timshomepage.net>
* @copyright 2015 - 2017 Timothy J. Warren
* @license http://www.opensource.org/licenses/mit-license.html MIT License
@ -65,7 +65,7 @@ trait KitsuTrait {
->get('session')
->getSegment(SESSION_SEGMENT);
if ($sessionSegment->get('auth_token') !== null && $url !== K::AUTH_URL)
if ($sessionSegment->get('auth_token') !== NULL && $url !== K::AUTH_URL)
{
$token = $sessionSegment->get('auth_token');
$request = $request->setAuth('bearer', $token);
@ -104,14 +104,6 @@ trait KitsuTrait {
$response = wait((new Client)->request($request));
/* $logger->debug('Kitsu api response', [
'status' => $response->getStatus(),
'reason' => $response->getReason(),
'body' => $response->getBody(),
'headers' => $response->getAllHeaders(),
'requestHeaders' => $request->getAllHeaders(),
]); */
return $response;
}
@ -125,7 +117,7 @@ trait KitsuTrait {
*/
private function request(string $type, string $url, array $options = []): array
{
$logger = null;
$logger = NULL;
if ($this->getContainer())
{
$logger = $this->container->getLogger('kitsu-request');
@ -133,7 +125,7 @@ trait KitsuTrait {
$response = $this->getResponse($type, $url, $options);
if ((int) $response->getStatus() > 299 || (int) $response->getStatus() < 200)
if ((int) $response->getStatus() > 299 OR (int) $response->getStatus() < 200)
{
if ($logger)
{
@ -147,7 +139,7 @@ trait KitsuTrait {
/**
* Remove some boilerplate for get requests
*
* @param array $args
* @param mixed ...$args
* @return array
*/
protected function getRequest(...$args): array
@ -158,7 +150,7 @@ trait KitsuTrait {
/**
* Remove some boilerplate for patch requests
*
* @param array $args
* @param mixed ...$args
* @return array
*/
protected function patchRequest(...$args): array
@ -169,12 +161,12 @@ trait KitsuTrait {
/**
* Remove some boilerplate for post requests
*
* @param array $args
* @param mixed ...$args
* @return array
*/
protected function postRequest(...$args): array
{
$logger = null;
$logger = NULL;
if ($this->getContainer())
{
$logger = $this->container->getLogger('kitsu-request');
@ -197,7 +189,7 @@ trait KitsuTrait {
/**
* Remove some boilerplate for delete requests
*
* @param array $args
* @param mixed ...$args
* @return bool
*/
protected function deleteRequest(...$args): bool

View File

@ -1,12 +1,12 @@
<?php declare(strict_types=1);
/**
* Anime List Client
* Hummingbird Anime List Client
*
* An API client for Kitsu and MyAnimeList to manage anime and manga watch lists
*
* PHP version 7
*
* @package AnimeListClient
* @package HummingbirdAnimeClient
* @author Timothy J. Warren <tim@timshomepage.net>
* @copyright 2015 - 2017 Timothy J. Warren
* @license http://www.opensource.org/licenses/mit-license.html MIT License
@ -37,7 +37,7 @@ class ListItem extends AbstractListItem {
->get('session')
->getSegment(SESSION_SEGMENT);
if ($sessionSegment->get('auth_token') !== null)
if ( ! is_null($sessionSegment->get('auth_token')))
{
$token = $sessionSegment->get('auth_token');
return "bearer {$token}";

View File

@ -1,12 +1,12 @@
<?php declare(strict_types=1);
/**
* Anime List Client
* Hummingbird Anime List Client
*
* An API client for Kitsu and MyAnimeList to manage anime and manga watch lists
*
* PHP version 7
*
* @package AnimeListClient
* @package HummingbirdAnimeClient
* @author Timothy J. Warren <tim@timshomepage.net>
* @copyright 2015 - 2017 Timothy J. Warren
* @license http://www.opensource.org/licenses/mit-license.html MIT License
@ -17,9 +17,11 @@
namespace Aviat\AnimeClient\API\Kitsu;
use Amp\Artax\Request;
use Aviat\AnimeClient\API\CacheTrait;
use Aviat\AnimeClient\API\JsonAPI;
use Aviat\AnimeClient\API\Kitsu as K;
use Aviat\AnimeClient\API\{
CacheTrait,
JsonAPI,
Kitsu as K
};
use Aviat\AnimeClient\API\Kitsu\Transformer\{
AnimeTransformer,
AnimeListTransformer,
@ -68,7 +70,9 @@ class Model {
/**
* Constructor.
* Constructor
*
* @param ListItem $listItem
*/
public function __construct(ListItem $listItem)
{
@ -136,7 +140,7 @@ class Model {
return $data;
}
return false;
return FALSE;
}
/**
@ -189,7 +193,7 @@ class Model {
}
}
return null;
return NULL;
}
/**
@ -233,6 +237,8 @@ class Model {
/**
* Get and transform the entirety of the user's anime list
*
* @param int $limit
* @param int $offset
* @return Request
*/
public function getFullAnimeList(int $limit = 100, int $offset = 0): Request

View File

@ -1,12 +1,12 @@
<?php declare(strict_types=1);
/**
* Anime List Client
* Hummingbird Anime List Client
*
* An API client for Kitsu and MyAnimeList to manage anime and manga watch lists
*
* PHP version 7
*
* @package AnimeListClient
* @package HummingbirdAnimeClient
* @author Timothy J. Warren <tim@timshomepage.net>
* @copyright 2015 - 2017 Timothy J. Warren
* @license http://www.opensource.org/licenses/mit-license.html MIT License
@ -33,7 +33,6 @@ class AnimeListTransformer extends AbstractTransformer {
*/
public function transform($item)
{
/* ?><pre><?= json_encode($item, \JSON_PRETTY_PRINT) ?></pre><?php */
$included = $item['included'];
$animeId = $item['relationships']['media']['data']['id'];
$anime = $included['anime'][$animeId];
@ -95,7 +94,7 @@ class AnimeListTransformer extends AbstractTransformer {
'rewatching' => (bool) $item['attributes']['reconsuming'],
'rewatched' => (int) $item['attributes']['reconsumeCount'],
'user_rating' => ($rating === 0) ? '-' : (int) $rating,
'private' => (bool) $item['attributes']['private'] ?? false,
'private' => (bool) $item['attributes']['private'] ?? FALSE,
];
}
@ -113,7 +112,7 @@ class AnimeListTransformer extends AbstractTransformer {
$untransformed = [
'id' => $item['id'],
'mal_id' => $item['mal_id'] ?? null,
'mal_id' => $item['mal_id'] ?? NULL,
'data' => [
'status' => $item['watching_status'],
'reconsuming' => $rewatching,

View File

@ -1,12 +1,12 @@
<?php declare(strict_types=1);
/**
* Anime List Client
* Hummingbird Anime List Client
*
* An API client for Kitsu and MyAnimeList to manage anime and manga watch lists
*
* PHP version 7
*
* @package AnimeListClient
* @package HummingbirdAnimeClient
* @author Timothy J. Warren <tim@timshomepage.net>
* @copyright 2015 - 2017 Timothy J. Warren
* @license http://www.opensource.org/licenses/mit-license.html MIT License

View File

@ -1,12 +1,12 @@
<?php declare(strict_types=1);
/**
* Anime List Client
* Hummingbird Anime List Client
*
* An API client for Kitsu and MyAnimeList to manage anime and manga watch lists
*
* PHP version 7
*
* @package AnimeListClient
* @package HummingbirdAnimeClient
* @author Timothy J. Warren <tim@timshomepage.net>
* @copyright 2015 - 2017 Timothy J. Warren
* @license http://www.opensource.org/licenses/mit-license.html MIT License
@ -35,18 +35,17 @@ class MangaListTransformer extends AbstractTransformer {
*/
public function transform($item)
{
/*?><pre><?= print_r($item, TRUE) ?></pre><?php*/
$manga =& $item['manga'];
$rating = (is_numeric($item['attributes']['rating']))
? intval(2 * $item['attributes']['rating'])
: '-';
$total_chapters = ($manga['attributes']['chapterCount'] > 0)
$totalChapters = ($manga['attributes']['chapterCount'] > 0)
? $manga['attributes']['chapterCount']
: '-';
$total_volumes = ($manga['attributes']['volumeCount'] > 0)
$totalVolumes = ($manga['attributes']['volumeCount'] > 0)
? $manga['attributes']['volumeCount']
: '-';
@ -54,11 +53,11 @@ class MangaListTransformer extends AbstractTransformer {
'id' => $item['id'],
'chapters' => [
'read' => $item['attributes']['progress'],
'total' => $total_chapters
'total' => $totalChapters
],
'volumes' => [
'read' => '-', //$item['attributes']['volumes_read'],
'total' => $total_volumes
'total' => $totalVolumes
],
'manga' => [
'titles' => Kitsu::filterTitles($manga['attributes']),

View File

@ -1,12 +1,12 @@
<?php declare(strict_types=1);
/**
* Anime List Client
* Hummingbird Anime List Client
*
* An API client for Kitsu and MyAnimeList to manage anime and manga watch lists
*
* PHP version 7
*
* @package AnimeListClient
* @package HummingbirdAnimeClient
* @author Timothy J. Warren <tim@timshomepage.net>
* @copyright 2015 - 2017 Timothy J. Warren
* @license http://www.opensource.org/licenses/mit-license.html MIT License
@ -58,7 +58,7 @@ class MangaTransformer extends AbstractTransformer {
];
}
private function count(int $value = null)
private function count(int $value = NULL)
{
return ((int)$value === 0)
? '-'

View File

@ -1,12 +1,12 @@
<?php declare(strict_types=1);
/**
* Anime List Client
* Hummingbird Anime List Client
*
* An API client for Kitsu and MyAnimeList to manage anime and manga watch lists
*
* PHP version 7
*
* @package AnimeListClient
* @package HummingbirdAnimeClient
* @author Timothy J. Warren <tim@timshomepage.net>
* @copyright 2015 - 2017 Timothy J. Warren
* @license http://www.opensource.org/licenses/mit-license.html MIT License

View File

@ -1,12 +1,12 @@
<?php declare(strict_types=1);
/**
* Anime List Client
* Hummingbird Anime List Client
*
* An API client for Kitsu and MyAnimeList to manage anime and manga watch lists
*
* PHP version 7
*
* @package AnimeListClient
* @package HummingbirdAnimeClient
* @author Timothy J. Warren <tim@timshomepage.net>
* @copyright 2015 - 2017 Timothy J. Warren
* @license http://www.opensource.org/licenses/mit-license.html MIT License
@ -73,7 +73,7 @@ class MAL {
'completed' => MangaReadingStatus::COMPLETED,
'onhold' => MangaReadingStatus::ON_HOLD,
'dropped' => MangaReadingStatus::DROPPED,
'plantoread' => MangaReadingStatus::PLAN_TO_WATCH
'plantoread' => MangaReadingStatus::PLAN_TO_READ
];
}
}

View File

@ -1,12 +1,12 @@
<?php declare(strict_types=1);
/**
* Anime List Client
* Hummingbird Anime List Client
*
* An API client for Kitsu and MyAnimeList to manage anime and manga watch lists
*
* PHP version 7
*
* @package AnimeListClient
* @package HummingbirdAnimeClient
* @author Timothy J. Warren <tim@timshomepage.net>
* @copyright 2015 - 2017 Timothy J. Warren
* @license http://www.opensource.org/licenses/mit-license.html MIT License

View File

@ -1,12 +1,12 @@
<?php declare(strict_types=1);
/**
* Anime List Client
* Hummingbird Anime List Client
*
* An API client for Kitsu and MyAnimeList to manage anime and manga watch lists
*
* PHP version 7
*
* @package AnimeListClient
* @package HummingbirdAnimeClient
* @author Timothy J. Warren <tim@timshomepage.net>
* @copyright 2015 - 2017 Timothy J. Warren
* @license http://www.opensource.org/licenses/mit-license.html MIT License

View File

@ -1,12 +1,12 @@
<?php declare(strict_types=1);
/**
* Anime List Client
* Hummingbird Anime List Client
*
* An API client for Kitsu and MyAnimeList to manage anime and manga watch lists
*
* PHP version 7
*
* @package AnimeListClient
* @package HummingbirdAnimeClient
* @author Timothy J. Warren <tim@timshomepage.net>
* @copyright 2015 - 2017 Timothy J. Warren
* @license http://www.opensource.org/licenses/mit-license.html MIT License

View File

@ -1,12 +1,12 @@
<?php declare(strict_types=1);
/**
* Anime List Client
* Hummingbird Anime List Client
*
* An API client for Kitsu and MyAnimeList to manage anime and manga watch lists
*
* PHP version 7
*
* @package AnimeListClient
* @package HummingbirdAnimeClient
* @author Timothy J. Warren <tim@timshomepage.net>
* @copyright 2015 - 2017 Timothy J. Warren
* @license http://www.opensource.org/licenses/mit-license.html MIT License

View File

@ -1,12 +1,12 @@
<?php declare(strict_types=1);
/**
* Anime List Client
* Hummingbird Anime List Client
*
* An API client for Kitsu and MyAnimeList to manage anime and manga watch lists
*
* PHP version 7
*
* @package AnimeListClient
* @package HummingbirdAnimeClient
* @author Timothy J. Warren <tim@timshomepage.net>
* @copyright 2015 - 2017 Timothy J. Warren
* @license http://www.opensource.org/licenses/mit-license.html MIT License
@ -118,7 +118,7 @@ trait MALTrait {
*/
private function getResponse(string $type, string $url, array $options = [])
{
$logger = null;
$logger = NULL;
if ($this->getContainer())
{
$logger = $this->container->getLogger('mal-request');
@ -148,7 +148,7 @@ trait MALTrait {
*/
private function request(string $type, string $url, array $options = []): array
{
$logger = null;
$logger = NULL;
if ($this->getContainer())
{
$logger = $this->container->getLogger('mal-request');
@ -156,7 +156,7 @@ trait MALTrait {
$response = $this->getResponse($type, $url, $options);
if ((int) $response->getStatus() > 299 || (int) $response->getStatus() < 200)
if ((int) $response->getStatus() > 299 OR (int) $response->getStatus() < 200)
{
if ($logger)
{
@ -170,7 +170,7 @@ trait MALTrait {
/**
* Remove some boilerplate for get requests
*
* @param array $args
* @param mixed ...$args
* @return array
*/
protected function getRequest(...$args): array
@ -181,12 +181,12 @@ trait MALTrait {
/**
* Remove some boilerplate for post requests
*
* @param array $args
* @param mixed ...$args
* @return array
*/
protected function postRequest(...$args): array
{
$logger = null;
$logger = NULL;
if ($this->getContainer())
{
$logger = $this->container->getLogger('mal-request');

View File

@ -1,12 +1,12 @@
<?php declare(strict_types=1);
/**
* Anime List Client
* Hummingbird Anime List Client
*
* An API client for Kitsu and MyAnimeList to manage anime and manga watch lists
*
* PHP version 7
*
* @package AnimeListClient
* @package HummingbirdAnimeClient
* @author Timothy J. Warren <tim@timshomepage.net>
* @copyright 2015 - 2017 Timothy J. Warren
* @license http://www.opensource.org/licenses/mit-license.html MIT License
@ -34,9 +34,16 @@ class Model {
* @var AnimeListTransformer
*/
protected $animeListTransformer;
/**
* @var ListItem
*/
protected $listItem;
/**
* MAL Model constructor.
*
* @param ListItem $listItem
*/
public function __construct(ListItem $listItem)
{

View File

@ -1,12 +1,12 @@
<?php declare(strict_types=1);
/**
* Anime List Client
* Hummingbird Anime List Client
*
* An API client for Kitsu and MyAnimeList to manage anime and manga watch lists
*
* PHP version 7
*
* @package AnimeListClient
* @package HummingbirdAnimeClient
* @author Timothy J. Warren <tim@timshomepage.net>
* @copyright 2015 - 2017 Timothy J. Warren
* @license http://www.opensource.org/licenses/mit-license.html MIT License
@ -24,7 +24,7 @@ use Aviat\Ion\Transformer\AbstractTransformer;
*/
class AnimeListTransformer extends AbstractTransformer {
const statusMap = [
const STATUS_MAP = [
AnimeWatchingStatus::WATCHING => '1',
AnimeWatchingStatus::COMPLETED => '2',
AnimeWatchingStatus::ON_HOLD => '3',
@ -45,7 +45,7 @@ class AnimeListTransformer extends AbstractTransformer {
return [
'id' => $item['mal_id'],
'data' => [
'status' => self::statusMap[$item['watching_status']],
'status' => self::STATUS_MAP[$item['watching_status']],
'rating' => $item['user_rating'],
'rewatch_value' => (int) $rewatching,
'times_rewatched' => $item['rewatched'],
@ -58,7 +58,7 @@ class AnimeListTransformer extends AbstractTransformer {
/**
* Transform Kitsu episode data to MAL episode data
*
* @param array $item
* @param array $item
* @return array
*/
public function untransform(array $item): array
@ -93,7 +93,7 @@ class AnimeListTransformer extends AbstractTransformer {
break;
case 'status':
$map['data']['status'] = self::statusMap[$value];
$map['data']['status'] = self::STATUS_MAP[$value];
break;
default:

View File

@ -0,0 +1,82 @@
<?php declare(strict_types=1);
/**
* Hummingbird Anime List Client
*
* An API client for Kitsu and MyAnimeList to manage anime and manga watch lists
*
* PHP version 7
*
* @package HummingbirdAnimeClient
* @author Timothy J. Warren <tim@timshomepage.net>
* @copyright 2015 - 2017 Timothy J. Warren
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version 4.0
* @link https://github.com/timw4mail/HummingBirdAnimeClient
*/
namespace Aviat\AnimeClient\API;
use Amp;
use Amp\Artax\Client;
/**
* Class to simplify making and validating simultaneous requests
*/
class ParallelAPIRequest {
/**
* Set of requests to make in parallel
*
* @var array
*/
protected $requests = [];
/**
* Add a request
*
* @param string|Request $request
* @param string|number $key
* @return self
*/
public function addRequest($request, $key = NULL): self
{
if ( ! is_null($key))
{
$this->requests[$key] = $request;
return $this;
}
$this->requests[] = $request;
return $this;
}
/**
* Add multiple requests
*
* @param string[]|Request[] $requests
* @return self
*/
public function addRequests(array $requests): self
{
array_walk($requests, [$this, 'addRequest']);
return $this;
}
/**
* Actually make the requests
*
* @param bool $allowFailingRequests
* @return array
*/
public function makeRequests(bool $allowFailingRequests = FALSE): array
{
$client = new Client();
$promises = $client->requestMulti($this->requests);
$func = ($allowFailingRequests) ? '\Amp\some' : '\Amp\all';
$results = Amp\wait($func($promises));
return $results;
}
}

View File

@ -1,12 +1,12 @@
<?php declare(strict_types=1);
/**
* Anime List Client
* Hummingbird Anime List Client
*
* An API client for Kitsu and MyAnimeList to manage anime and manga watch lists
*
* PHP version 7
*
* @package AnimeListClient
* @package HummingbirdAnimeClient
* @author Timothy J. Warren <tim@timshomepage.net>
* @copyright 2015 - 2017 Timothy J. Warren
* @license http://www.opensource.org/licenses/mit-license.html MIT License
@ -39,6 +39,9 @@ class XML {
/**
* XML constructor
*
* @param string $xml
* @param array $data
*/
public function __construct(string $xml = '', array $data = [])
{
@ -47,6 +50,8 @@ class XML {
/**
* Serialize the data to an xml string
*
* @return string
*/
public function __toString(): string
{
@ -67,7 +72,7 @@ class XML {
* Set the data to create xml from
*
* @param array $data
* @return $this
* @return self
*/
public function setData(array $data): self
{
@ -89,7 +94,7 @@ class XML {
* Set the xml to parse the data from
*
* @param string $xml
* @return $this
* @return self
*/
public function setXML(string $xml): self
{
@ -161,20 +166,28 @@ class XML {
return static::toXML($this->getData());
}
/**
* Strip whitespace from raw xml to remove irrelevant text nodes
*
* @param string $xml
* @return string
*/
private static function stripXMLWhitespace(string $xml): string
{
// Get rid of unimportant text nodes by removing
// whitespace characters from between xml tags,
// except for the xml declaration tag, Which looks
// something like:
/* <?xml version="1.0" encoding="UTF-8"?> */
return preg_replace('/([^\?])>\s+</', '$1><', $xml);
}
/**
* Recursively create array structure based on xml structure
*
* @param array &$root A reference to the current array location
* @param array $root A reference to the current array location
* @param DOMNodeList $nodeList The current NodeList object
* @return void
*/
@ -187,7 +200,7 @@ class XML {
$current =& $root[$el->nodeName];
// It's a top level element!
if (is_a($el->childNodes->item(0), 'DomText') || ( ! $el->hasChildNodes()))
if (is_a($el->childNodes->item(0), 'DomText') OR ( ! $el->hasChildNodes()))
{
$current = $el->textContent;
continue;

View File

@ -1,16 +1,16 @@
<?php declare(strict_types=1);
/**
* Hummingbird Anime Client
* Hummingbird Anime List Client
*
* An API client for Hummingbird to manage anime and manga watch lists
* An API client for Kitsu and MyAnimeList to manage anime and manga watch lists
*
* PHP version 7
*
* @package HummingbirdAnimeClient
* @author Timothy J. Warren <tim@timshomepage.net>
* @copyright 2015 - 2016 Timothy J. Warren
* @copyright 2015 - 2017 Timothy J. Warren
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version 3.1
* @version 4.0
* @link https://github.com/timw4mail/HummingBirdAnimeClient
*/
@ -28,6 +28,18 @@ const NOT_FOUND_METHOD = 'notFound';
const ERROR_MESSAGE_METHOD = 'errorPage';
const SRC_DIR = SRC_DIR;
/**
* Joins paths together. Variadic to take an
* arbitrary number of arguments
*
* @param string[] ...$args
* @return string
*/
function _dir(...$args)
{
return implode(DIRECTORY_SEPARATOR, $args);
}
/**
* Load configuration options from .toml files
*

View File

@ -1,12 +1,12 @@
<?php declare(strict_types=1);
/**
* Anime List Client
* Hummingbird Anime List Client
*
* An API client for Kitsu and MyAnimeList to manage anime and manga watch lists
*
* PHP version 7
*
* @package AnimeListClient
* @package HummingbirdAnimeClient
* @author Timothy J. Warren <tim@timshomepage.net>
* @copyright 2015 - 2017 Timothy J. Warren
* @license http://www.opensource.org/licenses/mit-license.html MIT License
@ -72,7 +72,7 @@ class BaseCommand extends Command {
$config = loadToml($CONF_DIR);
$config_array = array_merge($base_config, $config);
$di = function ($config_array) use ($APP_DIR) {
$di = function ($config_array) {
$container = new Container();
// -------------------------------------------------------------------------

View File

@ -1,12 +1,12 @@
<?php declare(strict_types=1);
/**
* Anime List Client
* Hummingbird Anime List Client
*
* An API client for Kitsu and MyAnimeList to manage anime and manga watch lists
*
* PHP version 7
*
* @package AnimeListClient
* @package HummingbirdAnimeClient
* @author Timothy J. Warren <tim@timshomepage.net>
* @copyright 2015 - 2017 Timothy J. Warren
* @license http://www.opensource.org/licenses/mit-license.html MIT License
@ -21,7 +21,7 @@ namespace Aviat\AnimeClient\Command;
*/
class ClearCache extends BaseCommand {
/**
* Run the image conversion script
* Clear the API cache
*
* @param array $args
* @param array $options

View File

@ -1,12 +1,12 @@
<?php declare(strict_types=1);
/**
* Anime List Client
* Hummingbird Anime List Client
*
* An API client for Kitsu and MyAnimeList to manage anime and manga watch lists
*
* PHP version 7
*
* @package AnimeListClient
* @package HummingbirdAnimeClient
* @author Timothy J. Warren <tim@timshomepage.net>
* @copyright 2015 - 2017 Timothy J. Warren
* @license http://www.opensource.org/licenses/mit-license.html MIT License
@ -29,7 +29,16 @@ use Aviat\Ion\Json;
*/
class SyncKitsuWithMal extends BaseCommand {
/**
* Model for making requests to Kitsu API
* @var \Aviat\AnimeClient\API\Kitsu\Model
*/
protected $kitsuModel;
/**
* Model for making requests to MAL API
* @var \Aviat\AnimeClient\API\MAL\Model
*/
protected $malModel;
/**
@ -56,12 +65,11 @@ class SyncKitsuWithMal extends BaseCommand {
$data = $this->diffLists();
$this->echoBox("Number of items that need to be added to MAL: " . count($data));
if (! empty($data['addToMAL']))
if ( ! empty($data['addToMAL']))
{
$this->echoBox("Adding missing list items to MAL");
$this->createMALListItems($data['addToMAL']);
}
}
public function getKitsuList()
@ -80,7 +88,7 @@ class SyncKitsuWithMal extends BaseCommand {
}
$promiseArray = (new Client())->requestMulti($requests);
$responses = wait(all($promiseArray));
$output = [];
@ -89,7 +97,7 @@ class SyncKitsuWithMal extends BaseCommand {
$data = Json::decode($response->getBody());
$output = array_merge_recursive($output, $data);
}
return $output;
}
@ -113,8 +121,6 @@ class SyncKitsuWithMal extends BaseCommand {
return $output;
}
// 2015-05-20T23:48:47.731Z
public function formatMALList()
{
$orig = $this->getMALList();
@ -155,7 +161,7 @@ class SyncKitsuWithMal extends BaseCommand {
{
$animeId = $listItem['relationships']['anime']['data']['id'];
$potentialMappings = $includes['anime'][$animeId]['relationships']['mappings'];
$malId = null;
$malId = NULL;
foreach ($potentialMappings as $mappingId)
{
@ -166,7 +172,7 @@ class SyncKitsuWithMal extends BaseCommand {
}
// Skip to the next item if there isn't a MAL ID
if ($malId === null)
if (is_null($malId))
{
continue;
}
@ -238,11 +244,11 @@ class SyncKitsuWithMal extends BaseCommand {
$data = $transformer->untransform($item);
$requests[] = $this->malModel->createFullListItem($data);
}
$promiseArray = (new Client())->requestMulti($requests);
$responses = wait(all($promiseArray));
foreach($responses as $key => $response)
{
$id = $itemsToAdd[$key]['mal_id'];

View File

@ -1,16 +1,16 @@
<?php declare(strict_types=1);
/**
* Hummingbird Anime Client
* Hummingbird Anime List Client
*
* An API client for Hummingbird to manage anime and manga watch lists
* An API client for Kitsu and MyAnimeList to manage anime and manga watch lists
*
* PHP version 7
*
* @package HummingbirdAnimeClient
* @author Timothy J. Warren <tim@timshomepage.net>
* @copyright 2015 - 2016 Timothy J. Warren
* @copyright 2015 - 2017 Timothy J. Warren
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version 3.1
* @version 4.0
* @link https://github.com/timw4mail/HummingBirdAnimeClient
*/
@ -18,6 +18,8 @@ namespace Aviat\AnimeClient;
use const Aviat\AnimeClient\SESSION_SEGMENT;
use function Aviat\AnimeClient\_dir;
use Aviat\Ion\Di\{ContainerAware, ContainerInterface};
use Aviat\Ion\View\{HtmlView, HttpView, JsonView};
use InvalidArgumentException;
@ -33,13 +35,13 @@ class Controller {
/**
* Cache manager
* @var \Aviat\Ion\Cache\CacheInterface
* @var \Psr\Cache\CacheItemPoolInterface
*/
protected $cache;
/**
* The global configuration object
* @var Aviat\Ion\ConfigInterface $config
* @var \Aviat\Ion\ConfigInterface $config
*/
protected $config;
@ -69,7 +71,7 @@ class Controller {
/**
* Session segment
* @var [type]
* @var \Aura\Session\Segment
*/
protected $session;
@ -77,7 +79,7 @@ class Controller {
* Common data to be sent to views
* @var array
*/
protected $base_data = [
protected $baseData = [
'url_type' => 'anime',
'other_type' => 'manga',
'menu_name' => ''
@ -97,24 +99,28 @@ class Controller {
$this->config = $container->get('config');
$this->request = $container->get('request');
$this->response = $container->get('response');
$this->base_data['url'] = $auraUrlGenerator;
$this->base_data['urlGenerator'] = $urlGenerator;
$this->base_data['auth'] = $container->get('auth');
$this->base_data['config'] = $this->config;
$this->baseData = array_merge((array)$this->baseData, [
'url' => $auraUrlGenerator,
'urlGenerator' => $urlGenerator,
'auth' => $container->get('auth'),
'config' => $this->config
]);
$this->urlGenerator = $urlGenerator;
$session = $container->get('session');
$this->session = $session->getSegment(SESSION_SEGMENT);
// Set a 'previous' flash value for better redirects
$server_params = $this->request->getServerParams();
if (array_key_exists('HTTP_REFERER', $server_params))
$serverParams = $this->request->getServerParams();
if (array_key_exists('HTTP_REFERER', $serverParams))
{
$this->session->setFlash('previous', $server_params['HTTP_REFERER']);
$this->session->setFlash('previous', $serverParams['HTTP_REFERER']);
}
// Set a message box if available
$this->base_data['message'] = $this->session->getFlash('message');
$this->baseData['message'] = $this->session->getFlash('message');
}
/**
@ -124,8 +130,8 @@ class Controller {
*/
public function redirectToDefaultRoute()
{
$default_type = $this->config->get(['routes', 'route_config', 'default_list']);
$this->redirect($this->urlGenerator->default_url($default_type), 303);
$defaultType = $this->config->get(['routes', 'route_config', 'default_list']);
$this->redirect($this->urlGenerator->defaultUrl($defaultType), 303);
}
/**
@ -133,7 +139,7 @@ class Controller {
*
* @return void
*/
public function redirect_to_previous()
public function redirectToPrevious()
{
$previous = $this->session->getFlash('previous');
$this->redirect($previous, 303);
@ -145,31 +151,31 @@ class Controller {
* @param string|null $url
* @return void
*/
public function set_session_redirect($url = NULL)
public function setSessionRedirect($url = NULL)
{
$server_params = $this->request->getServerParams();
$serverParams = $this->request->getServerParams();
if ( ! array_key_exists('HTTP_REFERER', $server_params))
if ( ! array_key_exists('HTTP_REFERER', $serverParams))
{
return;
}
$util = $this->container->get('util');
$double_form_page = $server_params['HTTP_REFERER'] === $this->request->getUri();
$doubleFormPage = $serverParams['HTTP_REFERER'] === $this->request->getUri();
// Don't attempt to set the redirect url if
// the page is one of the form type pages,
// and the previous page is also a form type page_segments
if ($double_form_page)
if ($doubleFormPage)
{
return;
}
if (is_null($url))
{
$url = $util->is_view_page()
$url = $util->isViewPage()
? $this->request->url->get()
: $server_params['HTTP_REFERER'];
: $serverParams['HTTP_REFERER'];
}
$this->session->set('redirect_url', $url);
@ -180,7 +186,7 @@ class Controller {
*
* @return void
*/
public function session_redirect()
public function sessionRedirect()
{
$target = $this->session->get('redirect_url');
if (empty($target))
@ -221,27 +227,27 @@ class Controller {
* @throws InvalidArgumentException
* @return string
*/
protected function load_partial($view, $template, array $data = [])
protected function loadPartial($view, $template, array $data = [])
{
$router = $this->container->get('dispatcher');
if (isset($this->base_data))
if (isset($this->baseData))
{
$data = array_merge($this->base_data, $data);
$data = array_merge($this->baseData, $data);
}
$route = $router->getRoute();
$data['route_path'] = $route ? $router->getRoute()->path : '';
$template_path = _dir($this->config->get('view_path'), "{$template}.php");
$templatePath = _dir($this->config->get('view_path'), "{$template}.php");
if ( ! is_file($template_path))
if ( ! is_file($templatePath))
{
throw new InvalidArgumentException("Invalid template : {$template}");
}
return $view->renderTemplate($template_path, (array)$data);
return $view->renderTemplate($templatePath, (array)$data);
}
/**
@ -252,17 +258,17 @@ class Controller {
* @param array $data
* @return void
*/
protected function render_full_page($view, $template, array $data)
protected function renderFullPage($view, $template, array $data)
{
$view->appendOutput($this->load_partial($view, 'header', $data));
$view->appendOutput($this->loadPartial($view, 'header', $data));
if (array_key_exists('message', $data) && is_array($data['message']))
{
$view->appendOutput($this->load_partial($view, 'message', $data['message']));
$view->appendOutput($this->loadPartial($view, 'message', $data['message']));
}
$view->appendOutput($this->load_partial($view, $template, $data));
$view->appendOutput($this->load_partial($view, 'footer', $data));
$view->appendOutput($this->loadPartial($view, $template, $data));
$view->appendOutput($this->loadPartial($view, 'footer', $data));
}
/**
@ -280,11 +286,11 @@ class Controller {
if ($status !== '')
{
$message = $this->show_message($view, 'error', $status);
$message = $this->showMessage($view, 'error', $status);
}
// Set the redirect url
$this->set_session_redirect();
$this->setSessionRedirect();
$this->outputHTML('login', [
'title' => 'Api login',
@ -303,10 +309,11 @@ class Controller {
$post = $this->request->getParsedBody();
if ($auth->authenticate($post['password']))
{
return $this->session_redirect();
$this->sessionRedirect();
return;
}
$this->set_flash_message('Invalid username or password.');
$this->setFlashMessage('Invalid username or password.');
$this->redirect($this->urlGenerator->url('login'), 303);
}
@ -338,19 +345,19 @@ class Controller {
/**
* Display a generic error page
*
* @param int $http_code
* @param int $httpCode
* @param string $title
* @param string $message
* @param string $long_message
* @return void
*/
public function errorPage($http_code, $title, $message, $long_message = "")
public function errorPage($httpCode, $title, $message, $long_message = "")
{
$this->outputHTML('error', [
'title' => $title,
'message' => $message,
'long_message' => $long_message
], NULL, $http_code);
], NULL, $httpCode);
}
/**
@ -361,12 +368,21 @@ class Controller {
* @param string $type
* @return void
*/
public function set_flash_message($message, $type = "info")
public function setFlashMessage($message, $type = "info")
{
$this->session->setFlash('message', [
static $messages;
if ( ! $messages)
{
$messages = [];
}
$messages[] = [
'message_type' => $type,
'message' => $message
]);
];
$this->session->setFlash('message', $messages);
}
/**
@ -393,7 +409,7 @@ class Controller {
*/
protected function showMessage($view, $type, $message)
{
return $this->load_partial($view, 'message', [
return $this->loadPartial($view, 'message', [
'message_type' => $type,
'message' => $message
]);
@ -416,7 +432,7 @@ class Controller {
}
$view->setStatusCode($code);
$this->render_full_page($view, $template, $data);
$this->renderFullPage($view, $template, $data);
}
/**

View File

@ -1,12 +1,12 @@
<?php declare(strict_types=1);
/**
* Anime List Client
* Hummingbird Anime List Client
*
* An API client for Kitsu and MyAnimeList to manage anime and manga watch lists
*
* PHP version 7
*
* @package AnimeListClient
* @package HummingbirdAnimeClient
* @author Timothy J. Warren <tim@timshomepage.net>
* @copyright 2015 - 2017 Timothy J. Warren
* @license http://www.opensource.org/licenses/mit-license.html MIT License
@ -39,13 +39,13 @@ class Anime extends BaseController {
/**
* Data to be sent to all routes in this controller
* @var array $base_data
* @var array $baseData
*/
protected $base_data;
protected $baseData;
/**
* Data cache
* @var Aviat\Ion\Cache\CacheInterface
* @var \Psr\Cache\CachePoolInterface
*/
protected $cache;
@ -60,7 +60,7 @@ class Anime extends BaseController {
$this->model = $container->get('anime-model');
$this->base_data = array_merge($this->base_data, [
$this->baseData = array_merge($this->baseData, [
'menu_name' => 'anime_list',
'url_type' => 'anime',
'other_type' => 'manga',
@ -79,16 +79,16 @@ class Anime extends BaseController {
*/
public function index($type = AnimeWatchingStatus::WATCHING, string $view = NULL)
{
$type_title_map = [
$typeTitleMap = [
'all' => 'All',
AnimeWatchingStatus::WATCHING => 'Currently Watching',
AnimeWatchingStatus::PLAN_TO_WATCH => 'Plan to Watch',
AnimeWatchingStatus::ON_HOLD => 'On Hold',
AnimeWatchingStatus::DROPPED => 'Dropped',
AnimeWatchingStatus::COMPLETED => 'Completed'
'watching' => 'Currently Watching',
'plan_to_watch' => 'Plan to Watch',
'on_hold' => 'On Hold',
'dropped' => 'Dropped',
'completed' => 'Completed'
];
$model_map = [
$modelMap = [
'watching' => AnimeWatchingStatus::WATCHING,
'plan_to_watch' => AnimeWatchingStatus::PLAN_TO_WATCH,
'on_hold' => AnimeWatchingStatus::ON_HOLD,
@ -97,21 +97,21 @@ class Anime extends BaseController {
'completed' => AnimeWatchingStatus::COMPLETED
];
$title = (array_key_exists($type, $type_title_map))
$title = (array_key_exists($type, $typeTitleMap))
? $this->config->get('whose_list') .
"'s Anime List &middot; {$type_title_map[$type]}"
"'s Anime List &middot; {$typeTitleMap[$type]}"
: '';
$view_map = [
$viewMap = [
'' => 'cover',
'list' => 'list'
];
$data = ($type !== 'all')
? $this->model->getList($model_map[$type])
? $this->model->getList($modelMap[$type])
: $this->model->get_all_lists();
$this->outputHTML('anime/' . $view_map[$view], [
$this->outputHTML('anime/' . $viewMap[$view], [
'title' => $title,
'sections' => $data
]);
@ -122,7 +122,7 @@ class Anime extends BaseController {
*
* @return void
*/
public function add_form()
public function addForm()
{
$statuses = [
AnimeWatchingStatus::WATCHING => 'Currently Watching',
@ -132,7 +132,7 @@ class Anime extends BaseController {
AnimeWatchingStatus::COMPLETED => 'Completed'
];
$this->set_session_redirect();
$this->setSessionRedirect();
$this->outputHTML('anime/add', [
'title' => $this->config->get('whose_list') .
"'s Anime List &middot; Add",
@ -158,15 +158,15 @@ class Anime extends BaseController {
if ($result)
{
$this->set_flash_message('Added new anime to list', 'success');
$this->setFlashMessage('Added new anime to list', 'success');
$this->cache->clear();
}
else
{
$this->set_flash_message('Failed to add new anime to list', 'error');
$this->setFlashMessage('Failed to add new anime to list', 'error');
}
$this->session_redirect();
$this->sessionRedirect();
}
/**
@ -179,19 +179,19 @@ class Anime extends BaseController {
public function edit($id, $status = "all")
{
$item = $this->model->getLibraryItem($id, $status);
$raw_status_list = AnimeWatchingStatus::getConstList();
$rawStatusList = AnimeWatchingStatus::getConstList();
$statuses = [];
foreach ($raw_status_list as $status_item)
foreach ($rawStatusList as $statusItem)
{
$statuses[$status_item] = (string) $this->string($status_item)
$statuses[$statusItem] = (string) $this->string($statusItem)
->underscored()
->humanize()
->titleize();
}
$this->set_session_redirect();
$this->setSessionRedirect();
$this->outputHTML('anime/edit', [
'title' => $this->config->get('whose_list') .
@ -220,27 +220,27 @@ class Anime extends BaseController {
*
* @return void
*/
public function form_update()
public function formUpdate()
{
$data = $this->request->getParsedBody();
// Do some minor data manipulation for
// large form-based updates
$transformer = new AnimeListTransformer();
$post_data = $transformer->untransform($data);
$full_result = $this->model->updateLibraryItem($post_data);
$postData = $transformer->untransform($data);
$fullResult = $this->model->updateLibraryItem($postData);
if ($full_result['statusCode'] === 200)
if ($fullResult['statusCode'] === 200)
{
$this->set_flash_message("Successfully updated.", 'success');
$this->setFlashMessage("Successfully updated.", 'success');
$this->cache->clear();
}
else
{
$this->set_flash_message('Failed to update anime.', 'error');
$this->setFlashMessage('Failed to update anime.', 'error');
}
$this->session_redirect();
$this->sessionRedirect();
}
/**
@ -277,26 +277,26 @@ class Anime extends BaseController {
if ((bool)$response === TRUE)
{
$this->set_flash_message("Successfully deleted anime.", 'success');
$this->setFlashMessage("Successfully deleted anime.", 'success');
$this->cache->clear();
}
else
{
$this->set_flash_message('Failed to delete anime.', 'error');
$this->setFlashMessage('Failed to delete anime.', 'error');
}
$this->session_redirect();
$this->sessionRedirect();
}
/**
* View details of an anime
*
* @param string $anime_id
* @param string $animeId
* @return void
*/
public function details($anime_id)
public function details($animeId)
{
$data = $this->model->getAnime($anime_id);
$data = $this->model->getAnime($animeId);
$this->outputHTML('anime/details', [
'title' => 'Anime &middot ' . $data['titles'][0],

View File

@ -1,12 +1,12 @@
<?php declare(strict_types=1);
/**
* Anime List Client
* Hummingbird Anime List Client
*
* An API client for Kitsu and MyAnimeList to manage anime and manga watch lists
*
* PHP version 7
*
* @package AnimeListClient
* @package HummingbirdAnimeClient
* @author Timothy J. Warren <tim@timshomepage.net>
* @copyright 2015 - 2017 Timothy J. Warren
* @license http://www.opensource.org/licenses/mit-license.html MIT License
@ -17,8 +17,10 @@
namespace Aviat\AnimeClient\Controller;
use Aviat\AnimeClient\Controller as BaseController;
use Aviat\AnimeClient\Model\Anime as AnimeModel;
use Aviat\AnimeClient\Model\AnimeCollection as AnimeCollectionModel;
use Aviat\AnimeClient\Model\{
Anime as AnimeModel,
AnimeCollection as AnimeCollectionModel
};
use Aviat\AnimeClient\UrlGenerator;
use Aviat\Ion\Di\ContainerInterface;
@ -29,21 +31,21 @@ class Collection extends BaseController {
/**
* The anime collection model
* @var AnimeCollectionModel $anime_collection_model
* @var AnimeCollectionModel $animeCollectionModel
*/
private $anime_collection_model;
private $animeCollectionModel;
/**
* The anime API model
* @var AnimeModel $anime_model
* @var AnimeModel $animeModel
*/
private $anime_model;
private $animeModel;
/**
* Data to ve sent to all routes in this controller
* @var array $base_data
* Data to be sent to all routes in this controller
* @var array $baseData
*/
protected $base_data;
protected $baseData;
/**
* Url Generator class
@ -61,9 +63,9 @@ class Collection extends BaseController {
parent::__construct($container);
$this->urlGenerator = $container->get('url-generator');
$this->anime_model = $container->get('anime-model');
$this->anime_collection_model = $container->get('anime-collection-model');
$this->base_data = array_merge($this->base_data, [
$this->animeModel = $container->get('anime-model');
$this->animeCollectionModel = $container->get('anime-collection-model');
$this->baseData = array_merge($this->baseData, [
'menu_name' => 'collection',
'url_type' => 'anime',
'other_type' => 'manga',
@ -80,7 +82,7 @@ class Collection extends BaseController {
{
$queryParams = $this->request->getQueryParams();
$query = $queryParams['query'];
$this->outputJSON($this->anime_model->search($query));
$this->outputJSON($this->animeModel->search($query));
}
/**
@ -91,17 +93,17 @@ class Collection extends BaseController {
*/
public function index($view)
{
$view_map = [
$viewMap = [
'' => 'cover',
'list' => 'list'
];
$data = $this->anime_collection_model->get_collection();
$data = $this->animeCollectionModel->getCollection();
$this->outputHTML('collection/' . $view_map[$view], [
$this->outputHTML('collection/' . $viewMap[$view], [
'title' => $this->config->get('whose_list') . "'s Anime Collection",
'sections' => $data,
'genres' => $this->anime_collection_model->get_genre_list()
'genres' => $this->animeCollectionModel->getGenreList()
]);
}
@ -113,16 +115,16 @@ class Collection extends BaseController {
*/
public function form($id = NULL)
{
$this->set_session_redirect();
$this->setSessionRedirect();
$action = (is_null($id)) ? "Add" : "Edit";
$this->outputHTML('collection/' . strtolower($action), [
'action' => $action,
'action_url' => $this->urlGenerator->full_url('collection/' . strtolower($action)),
'action_url' => $this->urlGenerator->fullUrl('collection/' . strtolower($action)),
'title' => $this->config->get('whose_list') . " Anime Collection &middot; {$action}",
'media_items' => $this->anime_collection_model->get_media_type_list(),
'item' => ($action === "Edit") ? $this->anime_collection_model->get($id) : []
'media_items' => $this->animeCollectionModel->getMediaTypeList(),
'item' => ($action === "Edit") ? $this->animeCollectionModel->get($id) : []
]);
}
@ -136,15 +138,15 @@ class Collection extends BaseController {
$data = $this->request->getParsedBody();
if (array_key_exists('hummingbird_id', $data))
{
$this->anime_collection_model->update($data);
$this->set_flash_message('Successfully updated collection item.', 'success');
$this->animeCollectionModel->update($data);
$this->setFlashMessage('Successfully updated collection item.', 'success');
}
else
{
$this->set_flash_message('Failed to update collection item', 'error');
$this->setFlashMessage('Failed to update collection item', 'error');
}
$this->session_redirect();
$this->sessionRedirect();
}
/**
@ -157,15 +159,15 @@ class Collection extends BaseController {
$data = $this->request->getParsedBody();
if (array_key_exists('id', $data))
{
$this->anime_collection_model->add($data);
$this->set_flash_message('Successfully added collection item', 'success');
$this->animeCollectionModel->add($data);
$this->setFlashMessage('Successfully added collection item', 'success');
}
else
{
$this->set_flash_message('Failed to add collection item.', 'error');
$this->setFlashMessage('Failed to add collection item.', 'error');
}
$this->session_redirect();
$this->sessionRedirect();
}
/**
@ -181,8 +183,8 @@ class Collection extends BaseController {
$this->redirect("/collection/view", 303);
}
$this->anime_collection_model->delete($data);
$this->set_flash_message("Successfully removed anime from collection.", 'success');
$this->animeCollectionModel->delete($data);
$this->setFlashMessage("Successfully removed anime from collection.", 'success');
$this->redirect("/collection/view", 303);
}

View File

@ -1,12 +1,12 @@
<?php declare(strict_types=1);
/**
* Anime List Client
* Hummingbird Anime List Client
*
* An API client for Kitsu and MyAnimeList to manage anime and manga watch lists
*
* PHP version 7
*
* @package AnimeListClient
* @package HummingbirdAnimeClient
* @author Timothy J. Warren <tim@timshomepage.net>
* @copyright 2015 - 2017 Timothy J. Warren
* @license http://www.opensource.org/licenses/mit-license.html MIT License
@ -39,9 +39,9 @@ class Manga extends Controller {
/**
* Data to ve sent to all routes in this controller
* @var array $base_data
* @var array $baseData
*/
protected $base_data;
protected $baseData;
/**
* Constructor
@ -53,7 +53,7 @@ class Manga extends Controller {
parent::__construct($container);
$this->model = $container->get('manga-model');
$this->base_data = array_merge($this->base_data, [
$this->baseData = array_merge($this->baseData, [
'menu_name' => 'manga_list',
'config' => $this->config,
'url_type' => 'manga',
@ -101,7 +101,7 @@ class Manga extends Controller {
*
* @return void
*/
public function add_form()
public function addForm()
{
$raw_status_list = MangaReadingStatus::getConstList();
@ -115,7 +115,7 @@ class Manga extends Controller {
->titleize();
}
$this->set_session_redirect();
$this->setSessionRedirect();
$this->outputHTML('manga/add', [
'title' => $this->config->get('whose_list') .
"'s Manga List &middot; Add",
@ -141,15 +141,15 @@ class Manga extends Controller {
if ($result)
{
$this->set_flash_message('Added new manga to list', 'success');
$this->setFlashMessage('Added new manga to list', 'success');
$this->cache->clear();
}
else
{
$this->set_flash_message('Failed to add new manga to list' . $result['body'], 'error');
$this->setFlashMessage('Failed to add new manga to list' . $result['body'], 'error');
}
$this->session_redirect();
$this->sessionRedirect();
}
/**
@ -161,7 +161,7 @@ class Manga extends Controller {
*/
public function edit($id, $status = "All")
{
$this->set_session_redirect();
$this->setSessionRedirect();
$item = $this->model->getLibraryItem($id);
$title = $this->config->get('whose_list') . "'s Manga List &middot; Edit";
@ -190,7 +190,7 @@ class Manga extends Controller {
*
* @return void
*/
public function form_update()
public function formUpdate()
{
$data = $this->request->getParsedBody();
@ -202,16 +202,16 @@ class Manga extends Controller {
if ($full_result['statusCode'] === 200)
{
$this->set_flash_message("Successfully updated manga.", 'success');
$this->setFlashMessage("Successfully updated manga.", 'success');
$this->cache->clear();
}
else
{
$this->set_flash_message('Failed to update manga.', 'error');
$this->setFlashMessage('Failed to update manga.', 'error');
}
$this->session_redirect();
$this->sessionRedirect();
}
/**
@ -249,15 +249,15 @@ class Manga extends Controller {
if ($response)
{
$this->set_flash_message("Successfully deleted manga.", 'success');
$this->setFlashMessage("Successfully deleted manga.", 'success');
$this->cache->clear();
}
else
{
$this->set_flash_message('Failed to delete manga.', 'error');
$this->setFlashMessage('Failed to delete manga.', 'error');
}
$this->session_redirect();
$this->sessionRedirect();
}
/**

View File

@ -1,16 +1,16 @@
<?php declare(strict_types=1);
/**
* Hummingbird Anime Client
* Hummingbird Anime List Client
*
* An API client for Hummingbird to manage anime and manga watch lists
* An API client for Kitsu and MyAnimeList to manage anime and manga watch lists
*
* PHP version 7
*
* @package HummingbirdAnimeClient
* @author Timothy J. Warren <tim@timshomepage.net>
* @copyright 2015 - 2016 Timothy J. Warren
* @copyright 2015 - 2017 Timothy J. Warren
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version 3.1
* @version 4.0
* @link https://github.com/timw4mail/HummingBirdAnimeClient
*/
@ -24,6 +24,8 @@ use const Aviat\AnimeClient\{
SRC_DIR
};
use function Aviat\AnimeClient\_dir;
use Aviat\Ion\Di\ContainerInterface;
use Aviat\Ion\Friend;
@ -46,15 +48,15 @@ class Dispatcher extends RoutingBase {
/**
* Class wrapper for input superglobals
* @var Psr\Http\Message\ServerRequestInterface
* @var \Psr\Http\Message\ServerRequestInterface
*/
protected $request;
/**
* Routes added to router
* @var array $output_routes
* @var array $outputRoutes
*/
protected $output_routes;
protected $outputRoutes;
/**
* Constructor
@ -68,7 +70,7 @@ class Dispatcher extends RoutingBase {
$this->matcher = $container->get('aura-router')->getMatcher();
$this->request = $container->get('request');
$this->output_routes = $this->_setupRoutes();
$this->outputRoutes = $this->setupRoutes();
}
/**
@ -80,12 +82,12 @@ class Dispatcher extends RoutingBase {
{
$logger = $this->container->getLogger('default');
$raw_route = $this->request->getUri()->getPath();
$route_path = "/" . trim($raw_route, '/');
$rawRoute = $this->request->getUri()->getPath();
$routePath = "/" . trim($rawRoute, '/');
$logger->info('Dispatcher - Routing data from get_route method');
$logger->info(print_r([
'route_path' => $route_path
'route_path' => $routePath
], TRUE));
return $this->matcher->match($this->request);
@ -98,7 +100,7 @@ class Dispatcher extends RoutingBase {
*/
public function getOutputRoutes()
{
return $this->output_routes;
return $this->outputRoutes;
}
/**
@ -131,10 +133,10 @@ class Dispatcher extends RoutingBase {
{
// If not route was matched, return an appropriate http
// error message
$error_route = $this->getErrorParams();
$errorRoute = $this->getErrorParams();
$controllerName = DEFAULT_CONTROLLER;
$actionMethod = $error_route['action_method'];
$params = $error_route['params'];
$actionMethod = $errorRoute['action_method'];
$params = $errorRoute['params'];
}
$this->call($controllerName, $actionMethod, $params);
@ -152,7 +154,7 @@ class Dispatcher extends RoutingBase {
{
if (array_key_exists('controller', $route->attributes))
{
$controller_name = $route->attributes['controller'];
$controllerName = $route->attributes['controller'];
}
else
{
@ -160,13 +162,13 @@ class Dispatcher extends RoutingBase {
}
// Get the full namespace for a controller if a short name is given
if (strpos($controller_name, '\\') === FALSE)
if (strpos($controllerName, '\\') === FALSE)
{
$map = $this->getControllerList();
$controller_name = $map[$controller_name];
$controllerName = $map[$controllerName];
}
$action_method = (array_key_exists('action', $route->attributes))
$actionMethod = (array_key_exists('action', $route->attributes))
? $route->attributes['action']
: NOT_FOUND_METHOD;
@ -186,8 +188,8 @@ class Dispatcher extends RoutingBase {
$logger->info(json_encode($params));
return [
'controller_name' => $controller_name,
'action_method' => $action_method,
'controller_name' => $controllerName,
'action_method' => $actionMethod,
'params' => $params
];
}
@ -199,16 +201,16 @@ class Dispatcher extends RoutingBase {
*/
public function getController()
{
$route_type = $this->__get('default_list');
$request_uri = $this->request->getUri()->getPath();
$path = trim($request_uri, '/');
$routeType = $this->__get('default_list');
$requestUri = $this->request->getUri()->getPath();
$path = trim($requestUri, '/');
$segments = explode('/', $path);
$controller = reset($segments);
if (empty($controller))
{
$controller = $route_type;
$controller = $routeType;
}
return $controller;
@ -221,22 +223,22 @@ class Dispatcher extends RoutingBase {
*/
public function getControllerList()
{
$default_namespace = DEFAULT_CONTROLLER_NAMESPACE;
$path = str_replace('\\', '/', $default_namespace);
$defaultNamespace = DEFAULT_CONTROLLER_NAMESPACE;
$path = str_replace('\\', '/', $defaultNamespace);
$path = str_replace('Aviat/AnimeClient/', '', $path);
$path = trim($path, '/');
$actual_path = realpath(_dir(SRC_DIR, $path));
$class_files = glob("{$actual_path}/*.php");
$actualPath = realpath(_dir(SRC_DIR, $path));
$classFiles = glob("{$actualPath}/*.php");
$controllers = [];
foreach ($class_files as $file)
foreach ($classFiles as $file)
{
$raw_class_name = basename(str_replace(".php", "", $file));
$path = strtolower(basename($raw_class_name));
$class_name = trim($default_namespace . '\\' . $raw_class_name, '\\');
$rawClassName = basename(str_replace(".php", "", $file));
$path = strtolower(basename($rawClassName));
$className = trim($defaultNamespace . '\\' . $rawClassName, '\\');
$controllers[$path] = $class_name;
$controllers[$path] = $className;
}
return $controllers;
@ -260,6 +262,7 @@ class Dispatcher extends RoutingBase {
// Run the appropriate controller method
$logger->debug('Dispatcher - controller arguments');
$logger->debug(print_r($params, TRUE));
call_user_func_array([$controller, $method], $params);
}
@ -277,7 +280,7 @@ class Dispatcher extends RoutingBase {
$logger->info('Dispatcher - failed route');
$logger->info(print_r($failure, TRUE));
$action_method = ERROR_MESSAGE_METHOD;
$actionMethod = ERROR_MESSAGE_METHOD;
$params = [];
@ -300,13 +303,13 @@ class Dispatcher extends RoutingBase {
default:
// Fall back to a 404 message
$action_method = NOT_FOUND_METHOD;
$actionMethod = NOT_FOUND_METHOD;
break;
}
return [
'params' => $params,
'action_method' => $action_method
'action_method' => $actionMethod
];
}
@ -315,9 +318,9 @@ class Dispatcher extends RoutingBase {
*
* @return array
*/
protected function _setupRoutes()
protected function setupRoutes()
{
$route_type = $this->getController();
$routeType = $this->getController();
// Add routes
$routes = [];
@ -326,18 +329,18 @@ class Dispatcher extends RoutingBase {
$path = $route['path'];
unset($route['path']);
$controller_map = $this->getControllerList();
$controller_class = (array_key_exists($route_type, $controller_map))
? $controller_map[$route_type]
$controllerMap = $this->getControllerList();
$controllerClass = (array_key_exists($routeType, $controllerMap))
? $controllerMap[$routeType]
: DEFAULT_CONTROLLER;
if (array_key_exists($route_type, $controller_map))
if (array_key_exists($routeType, $controllerMap))
{
$controller_class = $controller_map[$route_type];
$controllerClass = $controllerMap[$routeType];
}
// Prepend the controller to the route parameters
$route['controller'] = $controller_class;
$route['controller'] = $controllerClass;
// Select the appropriate router method based on the http verb
$add = (array_key_exists('verb', $route))

View File

@ -1,12 +1,12 @@
<?php declare(strict_types=1);
/**
* Anime List Client
* Hummingbird Anime List Client
*
* An API client for Kitsu and MyAnimeList to manage anime and manga watch lists
*
* PHP version 7
*
* @package AnimeListClient
* @package HummingbirdAnimeClient
* @author Timothy J. Warren <tim@timshomepage.net>
* @copyright 2015 - 2017 Timothy J. Warren
* @license http://www.opensource.org/licenses/mit-license.html MIT License
@ -28,13 +28,13 @@ class Menu {
/**
* Create the html for the selected menu
*
* @param string $menu_name
* @param string $menuName
* @return string
*/
public function __invoke($menu_name)
public function __invoke($menuName)
{
$generator = new MenuGenerator($this->container);
return $generator->generate($menu_name);
return $generator->generate($menuName);
}
}

View File

@ -1,16 +1,16 @@
<?php declare(strict_types=1);
/**
* Hummingbird Anime Client
* Hummingbird Anime List Client
*
* An API client for Hummingbird to manage anime and manga watch lists
* An API client for Kitsu and MyAnimeList to manage anime and manga watch lists
*
* PHP version 7
*
* @package HummingbirdAnimeClient
* @author Timothy J. Warren <tim@timshomepage.net>
* @copyright 2015 - 2016 Timothy J. Warren
* @copyright 2015 - 2017 Timothy J. Warren
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version 3.1
* @version 4.0
* @link https://github.com/timw4mail/HummingBirdAnimeClient
*/
@ -33,14 +33,14 @@ class MenuGenerator extends UrlGenerator {
/**
* Html generation helper
*
* @var Aura\Html\HelperLocator
* @var \Aura\Html\HelperLocator
*/
protected $helper;
/**
* Request object
*
* @var Aura\Web\Request
* @var \Psr\Http\Message\RequestInterface
*/
protected $request;
@ -62,7 +62,7 @@ class MenuGenerator extends UrlGenerator {
* @param array $menus
* @return array
*/
protected function parse_config(array $menus)
protected function parseConfig(array $menus)
{
$parsed = [];
@ -88,17 +88,17 @@ class MenuGenerator extends UrlGenerator {
public function generate($menu)
{
$menus = $this->config->get('menus');
$parsed_config = $this->parse_config($menus);
$parsedConfig = $this->parseConfig($menus);
// Bail out early on invalid menu
if ( ! $this->arr($parsed_config)->hasKey($menu))
if ( ! $this->arr($parsedConfig)->hasKey($menu))
{
return '';
}
$menu_config = $parsed_config[$menu];
$menuConfig = $parsedConfig[$menu];
foreach ($menu_config as $title => $path)
foreach ($menuConfig as $title => $path)
{
$has = $this->string($this->path())->contains($path);
$selected = ($has && strlen($this->path()) >= strlen($path));

View File

@ -1,12 +1,12 @@
<?php declare(strict_types=1);
/**
* Anime List Client
* Hummingbird Anime List Client
*
* An API client for Kitsu and MyAnimeList to manage anime and manga watch lists
*
* PHP version 7
*
* @package AnimeListClient
* @package HummingbirdAnimeClient
* @author Timothy J. Warren <tim@timshomepage.net>
* @copyright 2015 - 2017 Timothy J. Warren
* @license http://www.opensource.org/licenses/mit-license.html MIT License
@ -16,54 +16,26 @@
namespace Aviat\AnimeClient\Model;
use Aviat\Ion\Di\{ContainerAware, ContainerInterface};
use Aviat\Ion\Model;
/**
* Base model for api interaction
*/
class API extends Model {
use ContainerAware;
/**
* Config manager
* @var ConfigInterface
*/
protected $config;
/**
* Cache manager
* @var \Psr\Cache\CacheItemPoolInterface
*/
protected $cache;
/**
* Constructor
*
* @param ContainerInterface $container
*/
public function __construct(ContainerInterface $container)
{
$this->container = $container;
$this->config = $container->get('config');
}
class API extends AbstractModel {
/**
* Sort the list entries by their title
*
* @codeCoverageIgnore
* @param array $array
* @param string $sort_key
* @param string $sortKey
* @return void
*/
protected function sortByName(array &$array, string $sort_key)
protected function sortByName(array &$array, string $sortKey)
{
$sort = [];
foreach ($array as $key => $item)
{
$sort[$key] = $item[$sort_key]['titles'][0];
$sort[$key] = $item[$sortKey]['titles'][0];
}
array_multisort($sort, SORT_ASC, $array);

View File

@ -0,0 +1,26 @@
<?php declare(strict_types=1);
/**
* Hummingbird Anime List Client
*
* An API client for Kitsu and MyAnimeList to manage anime and manga watch lists
*
* PHP version 7
*
* @package HummingbirdAnimeClient
* @author Timothy J. Warren <tim@timshomepage.net>
* @copyright 2015 - 2017 Timothy J. Warren
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version 4.0
* @link https://github.com/timw4mail/HummingBirdAnimeClient
*/
namespace Aviat\AnimeClient\Model;
use Aviat\Ion\StringWrapper;
/**
* Base class for Models
*/
abstract class AbstractModel {
use StringWrapper;
}

View File

@ -1,12 +1,12 @@
<?php declare(strict_types=1);
/**
* Anime List Client
* Hummingbird Anime List Client
*
* An API client for Kitsu and MyAnimeList to manage anime and manga watch lists
*
* PHP version 7
*
* @package AnimeListClient
* @package HummingbirdAnimeClient
* @author Timothy J. Warren <tim@timshomepage.net>
* @copyright 2015 - 2017 Timothy J. Warren
* @license http://www.opensource.org/licenses/mit-license.html MIT License
@ -18,7 +18,9 @@ namespace Aviat\AnimeClient\Model;
use function Amp\some;
use function Amp\wait;
use Amp\Artax\Client;
use Aviat\AnimeClient\API\ParallelAPIRequest;
use Aviat\AnimeClient\API\Kitsu\Enum\AnimeWatchingStatus;
use Aviat\Ion\Di\ContainerInterface;
use Aviat\Ion\Json;
@ -47,19 +49,34 @@ class Anime extends API {
AnimeWatchingStatus::COMPLETED => self::COMPLETED,
];
/**
* Model for making requests to Kitsu API
*
* @var \Aviat\AnimeClient\API\Kitsu\Model
*/
protected $kitsuModel;
/**
* Model for making requests to MAL API
*
* @var \Aviat\AnimeClient\API\MAL\Model
*/
protected $malModel;
/**
* Whether to use the MAL api
*
* @var boolean
*/
protected $useMALAPI;
/**
* Anime constructor.
*
* @param ContainerInterface $container
*/
public function __construct(ContainerInterface $container) {
parent::__construct($container);
public function __construct(ContainerInterface $container)
{
$config = $container->get('config');
$this->kitsuModel = $container->get('kitsu-model');
$this->malModel = $container->get('mal-model');
@ -137,7 +154,7 @@ class Anime extends API {
*/
public function createLibraryItem(array $data): bool
{
$requests = [];
$requester = new ParallelAPIRequest();
if ($this->useMALAPI)
{
@ -147,15 +164,13 @@ class Anime extends API {
if ( ! is_null($malId))
{
$malData['id'] = $malId;
$requests['mal'] = $this->malModel->createListItem($malData);
$requester->addRequest($this->malModel->createListItem($malData), 'mal');
}
}
$requester->addRequest($this->kitsuModel->createListItem($data), 'kitsu');
$requests['kitsu'] = $this->kitsuModel->createListItem($data);
$promises = (new Client)->requestMulti($requests);
$results = wait(some($promises));
$results = $requester->makeRequests(TRUE);
return count($results[1]) > 0;
}
@ -168,18 +183,16 @@ class Anime extends API {
*/
public function updateLibraryItem(array $data): array
{
$requests = [];
$requester = new ParallelAPIRequest();
if ($this->useMALAPI)
{
$requests['mal'] = $this->malModel->updateListItem($data);
$requester->addRequest($this->malModel->updateListItem($data), 'mal');
}
$requests['kitsu'] = $this->kitsuModel->updateListItem($data);
$promises = (new Client)->requestMulti($requests);
$requester->addRequest($this->kitsuModel->updateListItem($data), 'kitsu');
$results = wait(some($promises));
$results = $requester->makeRequests(TRUE);
return [
'body' => Json::decode($results[1]['kitsu']->getBody()),
@ -194,18 +207,18 @@ class Anime extends API {
* @param string|null $malId
* @return bool
*/
public function deleteLibraryItem(string $id, string $malId = null): bool
public function deleteLibraryItem(string $id, string $malId = NULL): bool
{
$requests = [];
$requester = new ParallelAPIRequest();
if ($this->useMALAPI && ! is_null($malId))
{
$requests['mal'] = $this->malModel->deleteListItem($malId);
$requester->addRequest($this->malModel->deleteListItem($malId), 'MAL');
}
$requests['kitsu'] = $this->kitsuModel->deleteListItem($id);
$requester->addRequest($this->kitsuModel->deleteListItem($id), 'kitsu');
$results = wait(some((new Client)->requestMulti($requests)));
$results = $requester->makeRequests(TRUE);
return count($results[1]) > 0;
}

View File

@ -1,12 +1,12 @@
<?php declare(strict_types=1);
/**
* Anime List Client
* Hummingbird Anime List Client
*
* An API client for Kitsu and MyAnimeList to manage anime and manga watch lists
*
* PHP version 7
*
* @package AnimeListClient
* @package HummingbirdAnimeClient
* @author Timothy J. Warren <tim@timshomepage.net>
* @copyright 2015 - 2017 Timothy J. Warren
* @license http://www.opensource.org/licenses/mit-license.html MIT License
@ -31,13 +31,13 @@ class AnimeCollection extends Collection {
*
* @return array
*/
public function get_collection()
public function getCollection()
{
$raw_collection = $this->_get_collection();
$rawCollection = $this->getCollectionFromDatabase();
$collection = [];
foreach ($raw_collection as $row)
foreach ($rawCollection as $row)
{
if (array_key_exists($row['media'], $collection))
{
@ -57,7 +57,7 @@ class AnimeCollection extends Collection {
*
* @return array
*/
public function get_media_type_list()
public function getMediaTypeList()
{
$output = [];
@ -79,7 +79,7 @@ class AnimeCollection extends Collection {
* @param int $id
* @return array
*/
public function get_collection_entry($id)
public function getCollectionEntry($id)
{
$query = $this->db->from('anime_set')
->where('hummingbird_id', (int)$id)
@ -93,9 +93,9 @@ class AnimeCollection extends Collection {
*
* @return array
*/
private function _get_collection()
private function getCollectionFromDatabase()
{
if ( ! $this->valid_database)
if ( ! $this->validDatabase)
{
return [];
}
@ -119,9 +119,7 @@ class AnimeCollection extends Collection {
*/
public function add($data)
{
$anime = (object)$this->anime_model->getAnimeById($data['id']);
$util = $this->container->get('util');
$anime = (object)$this->animeModel->getAnimeById($data['id']);
$this->db->set([
'hummingbird_id' => $data['id'],
'slug' => $anime->slug,
@ -136,7 +134,7 @@ class AnimeCollection extends Collection {
'notes' => $data['notes']
])->insert('anime_set');
$this->update_genre($data['id']);
$this->updateGenre($data['id']);
}
/**
@ -185,13 +183,13 @@ class AnimeCollection extends Collection {
/**
* Get the details of a collection item
*
* @param int $hummingbird_id
* @param int $kitsuId
* @return array
*/
public function get($hummingbird_id)
public function get($kitsuId)
{
$query = $this->db->from('anime_set')
->where('hummingbird_id', $hummingbird_id)
->where('hummingbird_id', $kitsuId)
->get();
return $query->fetch(PDO::FETCH_ASSOC);
@ -200,16 +198,16 @@ class AnimeCollection extends Collection {
/**
* Update genre information for selected anime
*
* @param int $anime_id The current anime
* @param int $animeId The current anime
* @return void
*/
private function update_genre($anime_id)
private function updateGenre($animeId)
{
$genre_info = $this->get_genre_data();
extract($genre_info);
$genreInfo = $this->getGenreData();
extract($genreInfo);
// Get api information
$anime = $this->anime_model->getAnimeById($anime_id);
$anime = $this->animeModel->getAnimeById($animeId);
foreach ($anime['genres'] as $genre)
{
@ -224,23 +222,23 @@ class AnimeCollection extends Collection {
// Update link table
// Get id of genre to put in link table
$flipped_genres = array_flip($genres);
$flippedGenres = array_flip($genres);
$insert_array = [
'hummingbird_id' => $anime_id,
'genre_id' => $flipped_genres[$genre]
$insertArray = [
'hummingbird_id' => $animeId,
'genre_id' => $flippedGenres[$genre]
];
if (array_key_exists($anime_id, $links))
if (array_key_exists($animeId, $links))
{
if ( ! in_array($flipped_genres[$genre], $links[$anime_id]))
if ( ! in_array($flippedGenres[$genre], $links[$animeId]))
{
$this->db->set($insert_array)->insert('genre_anime_set_link');
$this->db->set($insertArray)->insert('genre_anime_set_link');
}
}
else
{
$this->db->set($insert_array)->insert('genre_anime_set_link');
$this->db->set($insertArray)->insert('genre_anime_set_link');
}
}
}
@ -250,7 +248,7 @@ class AnimeCollection extends Collection {
*
* @return array
*/
private function get_genre_data()
private function getGenreData()
{
$genres = [];
$links = [];
@ -285,21 +283,5 @@ class AnimeCollection extends Collection {
'links' => $links
];
}
/**
* Update genre information for the entire collection
*
* @return void
*/
private function update_genres()
{
// Get the anime collection
$collection = $this->_get_collection();
foreach ($collection as $anime)
{
// Get api information
$this->update_genre($anime['hummingbird_id']);
}
}
}
// End of AnimeCollectionModel.php

View File

@ -1,12 +1,12 @@
<?php declare(strict_types=1);
/**
* Anime List Client
* Hummingbird Anime List Client
*
* An API client for Kitsu and MyAnimeList to manage anime and manga watch lists
*
* PHP version 7
*
* @package AnimeListClient
* @package HummingbirdAnimeClient
* @author Timothy J. Warren <tim@timshomepage.net>
* @copyright 2015 - 2017 Timothy J. Warren
* @license http://www.opensource.org/licenses/mit-license.html MIT License
@ -16,10 +16,8 @@
namespace Aviat\AnimeClient\Model;
use Aviat\Ion\Di\ContainerAware;
use Aviat\Ion\Di\ContainerInterface;
use Aviat\Ion\Model\DB;
use Aviat\AnimeClient\Model\DB;
use Aviat\Ion\Di\{ContainerAware, ContainerInterface};
use PDO;
use PDOException;
@ -32,15 +30,15 @@ class Collection extends DB {
/**
* Anime API Model
* @var object $anime_model
* @var object $animeModel
*/
protected $anime_model;
protected $animeModel;
/**
* Whether the database is valid for querying
* @var boolean
*/
protected $valid_database = FALSE;
protected $validDatabase = FALSE;
/**
* Create a new collection object
@ -48,41 +46,39 @@ class Collection extends DB {
* @param ContainerInterface $container
*/
public function __construct(ContainerInterface $container)
{
$this->container = $container;
parent::__construct($container->get('config'));
{
parent::__construct($container);
try
{
$this->db = \Query($this->db_config['collection']);
$this->db = \Query($this->dbConfig['collection']);
}
catch (PDOException $e)
{
//$this->valid_database = FALSE;
//$this->validDatabase = FALSE;
//return FALSE;
}
$this->anime_model = $container->get('anime-model');
$this->animeModel = $container->get('anime-model');
// Is database valid? If not, set a flag so the
// app can be run without a valid database
if ($this->db_config['collection']['type'] === 'sqlite')
if ($this->dbConfig['collection']['type'] === 'sqlite')
{
$db_file_name = $this->db_config['collection']['file'];
$dbFileName = $this->dbConfig['collection']['file'];
if ($db_file_name !== ':memory:' && file_exists($db_file_name))
if ($dbFileName !== ':memory:' && file_exists($dbFileName))
{
$db_file = file_get_contents($db_file_name);
$this->valid_database = (strpos($db_file, 'SQLite format 3') === 0);
$dbFile = file_get_contents($dbFileName);
$this->validDatabase = (strpos($dbFile, 'SQLite format 3') === 0);
}
else
{
$this->valid_database = FALSE;
$this->validDatabase = FALSE;
}
}
else
{
$this->valid_database = TRUE;
$this->validDatabase = TRUE;
}
}
@ -92,7 +88,7 @@ class Collection extends DB {
* @param array $filter
* @return array
*/
public function get_genre_list($filter = [])
public function getGenreList($filter = [])
{
$this->db->select('hummingbird_id, genre')
->from('genre_anime_set_link gl')

View File

@ -1,12 +1,12 @@
<?php declare(strict_types=1);
/**
* Anime List Client
* Hummingbird Anime List Client
*
* An API client for Kitsu and MyAnimeList to manage anime and manga watch lists
*
* PHP version 7
*
* @package AnimeListClient
* @package HummingbirdAnimeClient
* @author Timothy J. Warren <tim@timshomepage.net>
* @copyright 2015 - 2017 Timothy J. Warren
* @license http://www.opensource.org/licenses/mit-license.html MIT License
@ -16,14 +16,13 @@
namespace Aviat\AnimeClient\Model;
use Aviat\Ion\Di\ContainerInterface;
use Aviat\Ion\Model;
use Aviat\Ion\Di\{ContainerAware, ContainerInterface};
/**
* Base model for database interaction
*/
class DB extends Model {
use \Aviat\Ion\Di\ContainerAware;
class DB extends AbstractModel {
use ContainerAware;
/**
* The query builder object
@ -33,9 +32,9 @@ class DB extends Model {
/**
* The database connection information array
* @var array $db_config
* @var array $dbConfig
*/
protected $db_config;
protected $dbConfig = [];
/**
* Constructor
@ -44,7 +43,7 @@ class DB extends Model {
*/
public function __construct(ContainerInterface $container)
{
$this->db_config = $container->get('config')->get('database');
$this->dbConfig = $container->get('config')->get('database');
$this->setContainer($container);
}
}

View File

@ -1,12 +1,12 @@
<?php declare(strict_types=1);
/**
* Anime List Client
* Hummingbird Anime List Client
*
* An API client for Kitsu and MyAnimeList to manage anime and manga watch lists
*
* PHP version 7
*
* @package AnimeListClient
* @package HummingbirdAnimeClient
* @author Timothy J. Warren <tim@timshomepage.net>
* @copyright 2015 - 2017 Timothy J. Warren
* @license http://www.opensource.org/licenses/mit-license.html MIT License
@ -36,7 +36,7 @@ class Manga extends API
* Map API constants to display constants
* @var array
*/
protected $const_map = [
protected $constMap = [
MangaReadingStatus::READING => self::READING,
MangaReadingStatus::PLAN_TO_READ => self::PLAN_TO_READ,
MangaReadingStatus::ON_HOLD => self::ON_HOLD,
@ -44,7 +44,11 @@ class Manga extends API
MangaReadingStatus::COMPLETED => self::COMPLETED
];
protected $status_map = [
/**
* Maps url segments to their title equivalents
* @var array
*/
protected $statusMap = [
'current' => self::READING,
'planned' => self::PLAN_TO_READ,
'completed' => self::COMPLETED,
@ -53,15 +57,26 @@ class Manga extends API
];
/**
* @var Aviat\AnimeClient\API\Kitsu\KitsuModel
* Model for making requests to Kitsu API
* @var \Aviat\AnimeClient\API\Kitsu\Model
*/
protected $kitsuModel;
/**
* Model for making requests to MAL API
* @var \Aviat\AnimeClient\API\MAL\Model
*/
protected $malModel;
/**
* Constructor
*
* @param ContainerInterface $container
*/
public function __construct(ContainerInterface $container)
{
parent::__construct($container);
$this->kitsuModel = $container->get('kitsu-model');
$this->malModel = $container->get('mal-model');
}
/**
@ -72,7 +87,7 @@ class Manga extends API
*/
public function getList($status)
{
$APIstatus = array_flip($this->const_map)[$status];
$APIstatus = array_flip($this->constMap)[$status];
$data = $this->kitsuModel->getMangaList($APIstatus);
return $this->mapByStatus($data)[$status];
}
@ -161,7 +176,7 @@ class Manga extends API
];
foreach ($data as &$entry) {
$key = $this->status_map[$entry['reading_status']];
$key = $this->statusMap[$entry['reading_status']];
$output[$key][] = $entry;
}

View File

@ -1,29 +1,30 @@
<?php declare(strict_types=1);
/**
* Hummingbird Anime Client
* Hummingbird Anime List Client
*
* An API client for Hummingbird to manage anime and manga watch lists
* An API client for Kitsu and MyAnimeList to manage anime and manga watch lists
*
* PHP version 7
*
* @package HummingbirdAnimeClient
* @author Timothy J. Warren <tim@timshomepage.net>
* @copyright 2015 - 2016 Timothy J. Warren
* @copyright 2015 - 2017 Timothy J. Warren
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version 3.1
* @version 4.0
* @link https://github.com/timw4mail/HummingBirdAnimeClient
*/
namespace Aviat\AnimeClient;
use Aviat\Ion\Di\ContainerInterface;
use Aviat\Ion\StringWrapper;
/**
* Base for routing/url classes
*/
class RoutingBase {
use \Aviat\Ion\StringWrapper;
use StringWrapper;
/**
* Injection Container
@ -33,7 +34,7 @@ class RoutingBase {
/**
* Config Object
* @var Config
* @var \Aviat\Ion\Config
*/
protected $config;
@ -47,7 +48,7 @@ class RoutingBase {
* Route configuration options
* @var array
*/
protected $route_config;
protected $routeConfig;
/**
* Constructor
@ -58,9 +59,9 @@ class RoutingBase {
{
$this->container = $container;
$this->config = $container->get('config');
$base_routes = $this->config->get('routes');
$this->routes = $base_routes['routes'];
$this->route_config = $base_routes['route_config'];
$baseRoutes = $this->config->get('routes');
$this->routes = $baseRoutes['routes'];
$this->routeConfig = $baseRoutes['route_config'];
}
/**
@ -71,11 +72,11 @@ class RoutingBase {
*/
public function __get($key)
{
$routing_config =& $this->route_config;
$routingConfig =& $this->routeConfig;
if (array_key_exists($key, $routing_config))
if (array_key_exists($key, $routingConfig))
{
return $routing_config[$key];
return $routingConfig[$key];
}
}
@ -88,13 +89,13 @@ class RoutingBase {
{
$request = $this->container->get('request');
$path = $request->getUri()->getPath();
$cleaned_path = $this->string($path)
$cleanedPath = $this->string($path)
->replace('%20', '')
->trim()
->trimRight('/')
->ensureLeft('/');
return (string)$cleaned_path;
return (string)$cleanedPath;
}
/**
@ -114,7 +115,7 @@ class RoutingBase {
* @param int $num
* @return string|null
*/
public function get_segment($num)
public function getSegment($num)
{
$segments = $this->segments();
return (array_key_exists($num, $segments)) ? $segments[$num] : NULL;
@ -125,7 +126,7 @@ class RoutingBase {
*
* @return string
*/
public function last_segment()
public function lastSegment()
{
$segments = $this->segments();
return end($segments);

View File

@ -1,22 +1,23 @@
<?php declare(strict_types=1);
/**
* Hummingbird Anime Client
* Hummingbird Anime List Client
*
* An API client for Hummingbird to manage anime and manga watch lists
* An API client for Kitsu and MyAnimeList to manage anime and manga watch lists
*
* PHP version 7
*
* @package HummingbirdAnimeClient
* @author Timothy J. Warren <tim@timshomepage.net>
* @copyright 2015 - 2016 Timothy J. Warren
* @copyright 2015 - 2017 Timothy J. Warren
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version 3.1
* @version 4.0
* @link https://github.com/timw4mail/HummingBirdAnimeClient
*/
namespace Aviat\AnimeClient;
use Aviat\Ion\Di\ContainerInterface;
use InvalidArgumentException;
/**
* UrlGenerator class.
@ -43,42 +44,26 @@ class UrlGenerator extends RoutingBase {
/**
* Get the base url for css/js/images
*
* @param string ...$args url segments to apend to the base asset url
* @return string
*/
public function asset_url()
public function assetUrl(...$args): string
{
$args = func_get_args();
$base_url = rtrim($this->url(""), '/');
$baseUrl = rtrim($this->url(""), '/');
$baseUrl = "{$baseUrl}" . $this->__get("asset_path");
$base_url = "{$base_url}" . $this->__get("asset_path");
array_unshift($args, $base_url);
array_unshift($args, $baseUrl);
return implode("/", $args);
}
/**
* Get the base url from the config
*
* @param string $type - (optional) The controller
* @return string
*/
public function base_url($type = "anime")
{
$config_path = trim($this->__get("{$type}_path"), "/");
$path = ($config_path !== '') ? $config_path : "";
return implode("/", ['/', $this->host, $path]);
}
/**
* Generate a proper url from the path
*
* @param string $path
* @return string
*/
public function url($path)
public function url(string $path): string
{
$path = trim($path, '/');
@ -108,20 +93,20 @@ class UrlGenerator extends RoutingBase {
* Full default path for the list pages
*
* @param string $type
* @throws \InvalidArgumentException
* @throws InvalidArgumentException
* @return string
*/
public function default_url($type)
public function defaultUrl(string $type): string
{
$type = trim($type);
$default_path = $this->__get("default_{$type}_list_path");
$defaultPath = $this->__get("default_{$type}_list_path");
if ( ! is_null($default_path))
if ( ! is_null($defaultPath))
{
return $this->url("{$type}/{$default_path}");
return $this->url("{$type}/{$defaultPath}");
}
throw new \InvalidArgumentException("Invalid default type: '{$type}'");
throw new InvalidArgumentException("Invalid default type: '{$type}'");
}
/**
@ -131,9 +116,9 @@ class UrlGenerator extends RoutingBase {
* @param string $type - (optional) The controller (anime or manga), defaults to anime
* @return string
*/
public function full_url($path = "", $type = "anime")
public function fullUrl(string $path = "", string $type = "anime"): string
{
$config_default_route = $this->__get("default_{$type}_path");
$configDefaultRoute = $this->__get("default_{$type}_path");
// Remove beginning/trailing slashes
$path = trim($path, '/');
@ -141,7 +126,7 @@ class UrlGenerator extends RoutingBase {
// Set the default view
if ($path === '')
{
$path .= trim($config_default_route, '/');
$path .= trim($configDefaultRoute, '/');
if ($this->__get('default_to_list_view'))
{
$path .= '/list';

Some files were not shown because too many files have changed in this diff Show More