mangadex/scripts/classes/mangas.class.req.php
2021-03-14 14:31:55 -07:00

511 lines
19 KiB
PHP

<?php
class Mangas {
public function __construct($search) {
global $sql;
$this->sql = $sql;
$search_string = "";
$left_join_alt_names = "";
$pdo_bind = [];
$multi_langs_string = "";
$multi_lang_id_array = [];
$distinct = '';
$cache_time = 60;
$tag_mode_inc = $search['tag_mode_inc'] ?? 'all';
$tag_mode_exc = $search['tag_mode_exc'] ?? 'any';
foreach ($search as $key => $value) {
switch ($key) {
case "tag_mode_inc":
case "tag_mode_exc":
break;
case "manga_genres_inc":
if (!empty($value)) {
$terms = is_array($value) ? $value : explode(',', $value);
$terms = array_map(function($t) { return (int)$t; }, $terms);
$terms = array_filter($terms, function($t) { return (bool)$t; });
$terms_count = sizeof($terms);
$terms = implode(',', $terms);
if ($tag_mode_inc === 'all') {
// include if manga has all of the included tags
$search_string .= $terms_count.' = (SELECT count(*) AS genre_count FROM mangadex_manga_genres genres WHERE genres.manga_id = mangas.manga_id AND genres.genre_id IN ('.$terms.')) AND ';
} else {
// include if manga has any of the included tags
$search_string .= 'EXISTS (SELECT genre_id FROM mangadex_manga_genres genres WHERE genres.manga_id = mangas.manga_id AND genres.genre_id IN ('.$terms.')) AND ';
}
}
break;
case 'excluded_genres':
case "manga_genres_exc":
if (!empty($value)) {
$terms = is_array($value) ? $value : explode(',', $value);
$terms = array_map(function($t) { return (int)$t; }, $terms);
$terms = array_filter($terms, function($t) { return (bool)$t; });
$terms_count = sizeof($terms);
$terms = implode(',', $terms);
if ($tag_mode_exc === 'all') {
// include if manga doesn't have all of the excluded tags
$search_string .= $terms_count.' != (SELECT count(*) AS genre_count FROM mangadex_manga_genres genres WHERE genres.manga_id = mangas.manga_id AND genres.genre_id IN ('.$terms.')) AND ';
} else {
// include if manga doesn't have any of the excluded tags
$search_string .= 'NOT EXISTS (SELECT genre_id FROM mangadex_manga_genres genres WHERE genres.manga_id = mangas.manga_id AND genres.genre_id IN ('.$terms.')) AND ';
}
}
break;
case "manga_name":
$terms = explode(" ", $value);
foreach ($terms as $term) {
$search_string .= "(mangas.manga_name LIKE ? OR alt_names.alt_name LIKE ?) AND ";
$pdo_bind[] = "%$term%";
$pdo_bind[] = "%$term%";
}
$left_join_alt_names = "LEFT JOIN mangadex_manga_alt_names AS alt_names ON alt_names.manga_id = mangas.manga_id";
$distinct = 'DISTINCT';
break;
case "manga_alpha":
if ($value == "~")
$search_string .= "manga_name REGEXP '^[0-9._\+\#]' AND ";
else {
$search_string .= "manga_name LIKE ? AND ";
$pdo_bind[] = "$value%";
}
break;
case "manga_artist":
case "manga_author":
$field = prepare_identifier("$key");
$search_string .= "$field LIKE ? AND ";
$pdo_bind[] = "%$value%";
break;
case "manga_ids_array":
$in = prepare_in($value);
$search_string .= "mangas.manga_id IN ($in) AND ";
$pdo_bind = array_merge($pdo_bind, $value);
break;
case 'multi_lang_id':
$in = prepare_in($value);
$multi_langs_string = "AND chapters.lang_id IN ($in) ";
$multi_lang_id_array = $value;
break;
case 'demos':
if (!empty($value)) {
$in = prepare_in($value);
$search_string .= "mangas.manga_demo_id IN ($in) AND ";
$pdo_bind = array_merge($pdo_bind, $value);
}
break;
case 'statuses':
if (!empty($value)) {
$in = prepare_in($value);
$search_string .= "mangas.manga_status_id IN ($in) AND ";
$pdo_bind = array_merge($pdo_bind, $value);
}
break;
/*
case 'excluded_genres':
if (is_array($value))
$value = implode(',', array_map('intval', $value));
$search_string .= 'mangas.manga_id NOT IN (SELECT manga_id FROM mangadex_manga_genres genres WHERE genres.genre_id IN ('.$value.')) AND';
break;
*/
default:
$field = prepare_identifier("$key");
$search_string .= "$field = ? AND ";
$pdo_bind[] = $value;
break;
}
}
$this->hash = hash_array($search);
$this->num_rows = $sql->prep("mangas_query_{$this->hash}_num_rows", "
SELECT count(*) FROM
(SELECT DISTINCT mangas.manga_id
FROM mangadex_mangas AS mangas
$left_join_alt_names
WHERE $search_string 1=1) AS temp
", $pdo_bind, 'fetchColumn', '', 60);
$this->search_string = $search_string;
$this->left_join_alt_names = $left_join_alt_names;
$this->pdo_bind = $pdo_bind;
$this->multi_langs_string = $multi_langs_string;
$this->multi_lang_id_array = $multi_lang_id_array;
$this->distinct = $distinct;
$this->cache_time = $cache_time;
}
public function query_read($order, $limit, $current_page) {
$orderby = prepare_orderby($order, SORT_ARRAY_MANGA);
$limit = prepare_numeric($limit);
$offset = prepare_numeric($limit * ($current_page - 1));
$results = $this->sql->prep("mangas_query_{$this->hash}_orderby_{$orderby}_limit_{$limit}_offset_$offset", "
SELECT $this->distinct mangas.manga_id, manga_image, manga_name, manga_author, manga_hentai, manga_rating, manga_bayesian, manga_rated_users, manga_views, manga_follows, manga_comments, manga_description,
lang_name, lang_flag, thread_posts, manga_last_uploaded AS manga_last_updated
FROM mangadex_mangas AS mangas
$this->left_join_alt_names
LEFT JOIN mangadex_languages AS lang
ON lang.lang_id = mangas.manga_lang_id
LEFT JOIN mangadex_threads AS threads
ON threads.thread_id = mangas.thread_id
WHERE $this->search_string 1=1
ORDER BY $orderby
LIMIT $limit OFFSET $offset
", array_merge($this->pdo_bind), 'fetchAll', PDO::FETCH_UNIQUE, -1);
return get_results_as_object($results, 'manga_id');
}
public function getIds($order, $limit, $current_page) {
$orderby = prepare_orderby($order, SORT_ARRAY_MANGA);
$limit = prepare_numeric($limit);
$offset = prepare_numeric($limit * ($current_page - 1));
$results = $this->sql->prep("manga_ids_query_" . hash_array($this->pdo_bind) . "_orderby_{$orderby}_limit_{$limit}_offset_$offset", "
SELECT manga_id, manga_last_uploaded AS manga_last_updated
FROM mangadex_mangas AS mangas
LEFT JOIN mangadex_threads AS threads
ON threads.thread_id = mangas.thread_id
WHERE $this->search_string 1=1
ORDER BY $orderby
LIMIT $limit OFFSET $offset
", array_merge($this->pdo_bind), 'fetchAll', PDO::FETCH_COLUMN, -1);
return $results;
}
}
class Manga {
public function __construct($id) {
global $sql;
$this->sql = $sql;
$id = (int)prepare_numeric($id);
$row = $sql->prep("manga_$id", "
SELECT mangadex_mangas.*, lang_name, lang_flag, thread_posts
FROM mangadex_mangas
LEFT JOIN mangadex_languages ON mangadex_languages.lang_id = mangadex_mangas.manga_lang_id
LEFT JOIN mangadex_threads ON mangadex_mangas.thread_id = mangadex_threads.thread_id
WHERE mangadex_mangas.manga_id = ?
", [$id], 'fetch', PDO::FETCH_OBJ, 86400);
//copy $row into $this
if ($row) {
foreach ($row as $key => $value) {
$this->$key = $value;
}
}
}
public function get_comments() {
$results = $this->sql->prep("manga_{$this->manga_id}_get_comments", "
SELECT posts.*, users.username, users.avatar, user_levels.level_colour, user_levels.level_id, user_levels.level_name,
editor.username AS editor_username,
editor_levels.level_colour AS editor_level_colour,
(SELECT (count(*) -1) DIV 20 + 1 FROM mangadex_forum_posts
WHERE mangadex_forum_posts.post_id <= posts.post_id
AND mangadex_forum_posts.thread_id = posts.thread_id
AND mangadex_forum_posts.deleted = 0) AS thread_page
FROM mangadex_forum_posts AS posts
LEFT JOIN mangadex_users AS users
ON posts.user_id = users.user_id
LEFT JOIN mangadex_user_levels AS user_levels
ON users.level_id = user_levels.level_id
LEFT JOIN mangadex_users AS editor
ON posts.edit_user_id = editor.user_id
LEFT JOIN mangadex_user_levels AS editor_levels
ON editor.level_id = editor_levels.level_id
WHERE posts.thread_id = ? AND posts.deleted = 0
ORDER BY timestamp DESC
LIMIT 20
", [$this->thread_id], 'fetchAll', PDO::FETCH_UNIQUE, -1);
return get_results_as_object($results, 'post_id');
}
public function get_total_chapters($multi_lang) {
if ($multi_lang) {
$arr = explode(',', $multi_lang);
$in = prepare_in($arr);
return $this->sql->prep("manga_{$this->manga_id}_total_chapters_lang_$multi_lang", "
SELECT count(*)
FROM mangadex_chapters
WHERE manga_id = ? AND chapter_deleted = 0 AND lang_id IN ($in)
", array_merge([$this->manga_id], $arr), 'fetchColumn', '', 60);
}
else
return $this->sql->prep("manga_{$this->manga_id}_total_chapters", "
SELECT count(*)
FROM mangadex_chapters
WHERE manga_id = ? AND chapter_deleted = 0
", [$this->manga_id], 'fetchColumn', '', 60);
}
public function get_missing_chapters($lang_id) {
$chapter_array = $this->sql->prep("manga_{$this->manga_id}_missing_chapters_lang_$lang_id", "
SELECT chapter
FROM mangadex_chapters
WHERE manga_id = ? AND lang_id = ? AND chapter_deleted = 0 AND available = 1
ORDER BY abs(chapter) DESC
", [$this->manga_id, $lang_id], 'fetchAll', PDO::FETCH_COLUMN, 60);
if (count($chapter_array) && $chapter_array[0] && $chapter_array[0] < 1500) {
$diff_array = array_diff(range(1, $chapter_array[0]), $chapter_array);
$string = "";
foreach($diff_array as $value) {
$string .= $value . " ";
}
return $string;
}
}
public function get_manga_genres() {
return $this->sql->prep("manga_{$this->manga_id}_genres", "
SELECT genre_id
FROM mangadex_manga_genres
WHERE manga_id = ?
", [$this->manga_id], 'fetchAll', PDO::FETCH_COLUMN);
}
public function get_manga_alt_names() {
return $this->sql->prep("manga_{$this->manga_id}_alt_names", "
SELECT alt_name
FROM mangadex_manga_alt_names
WHERE manga_id = ?
", [$this->manga_id], 'fetchAll', PDO::FETCH_COLUMN);
}
public function get_follows_user_id() {
return $this->sql->prep("manga_{$this->manga_id}_follows_user_id", "
SELECT user_id, follow_type
FROM mangadex_follow_user_manga
WHERE manga_id = ?
", [$this->manga_id], 'fetchAll', PDO::FETCH_KEY_PAIR);
}
public function get_user_follow_info($user_id){
return $this->sql->prep("manga_{$this->manga_id}_follows_user_{$user_id}",
"SELECT follow_type, volume, chapter
FROM mangadex_follow_user_manga
WHERE user_id = ? AND manga_id = ?",
[$user_id, $this->manga_id], 'fetchAll', PDO::FETCH_ASSOC) ?: ["follow_type" => 0, "volume" => 0, "chapter" => 0];
}
public function get_user_rating($user_id) {
return $this->sql->prep("manga_{$this->manga_id}_user_rating_$user_id", "
SELECT rating
FROM mangadex_manga_ratings
WHERE manga_id = ? AND user_id = ?
", [$this->manga_id, $user_id], 'fetchColumn', '');
}
public function get_user_ratings() {
return $this->sql->prep("manga_{$this->manga_id}_user_ratings", "
SELECT rating
FROM mangadex_manga_ratings
WHERE manga_id = ?
", [$this->manga_id], 'fetchAll', PDO::FETCH_COLUMN);
}
public function get_related_manga() {
return $this->sql->prep("manga_{$this->manga_id}_related_manga", "
SELECT relations.relation_id, relations.related_manga_id, mangas.manga_name, mangas.manga_hentai
FROM mangadex_manga_relations AS relations
LEFT JOIN mangadex_mangas AS mangas
ON relations.related_manga_id = mangas.manga_id
WHERE relations.manga_id = ?
ORDER BY relations.relation_id ASC, mangas.manga_name ASC
", [$this->manga_id], 'fetchAll', PDO::FETCH_ASSOC);
}
public function get_covers() {
return $this->sql->prep("manga_{$this->manga_id}_covers", "
SELECT covers.*, users.username, user_levels.level_colour, user_levels.level_id
FROM mangadex_manga_covers AS covers
LEFT JOIN mangadex_users AS users
ON covers.user_id = users.user_id
LEFT JOIN mangadex_user_levels AS user_levels
ON users.level_id = user_levels.level_id
WHERE covers.manga_id = ?
ORDER BY covers.volume + 0 ASC
", [$this->manga_id], 'fetchAll', PDO::FETCH_ASSOC);
}
}
class Genres {
protected $genres = [];
public function __construct() {
global $sql;
$results = $sql->query_read('genres', 'SELECT * FROM mangadex_genres ORDER BY genre_name ASC', 'fetchAll', PDO::FETCH_ASSOC, 600);
foreach ($results AS $row) {
$this->genres[$row['genre_id']] = $row['genre_name'];
}
}
public function toArray()
{
return $this->genres;
}
}
class Genre
{
public function __construct($id)
{
global $sql;
$id = prepare_numeric($id);
$row = $sql->prep("genre_$id", " SELECT * FROM mangadex_genres WHERE genre_id = ? ", [$id], 'fetch', PDO::FETCH_OBJ, -1);
//copy $row into $this
if ($row) {
foreach ($row as $key => $value) {
$this->$key = $value;
}
}
}
}
class Grouped_Genres {
protected $results = [];
public function __construct() {
global $sql;
$this->results = $sql->query_read('grouped_genres', '
SELECT *
FROM mangadex_genres AS genres
LEFT JOIN mangadex_genre_groups AS _groups
ON genres.genre_group_id = _groups.genre_group_id
ORDER BY genres.genre_group_id ASC, genres.genre_name ASC', 'fetchAll', PDO::FETCH_ASSOC);
}
public function toGenreArray()
{
$genres = [];
foreach ($this->results AS $row) {
$genres[$row['genre_id']] = ['id' => $row['genre_id'], 'name' => $row['genre_name'], 'group' => $row['genre_group_name'], 'description' => $row['genre_description']];
}
ksort($genres);
return $genres;
}
public function toGroupedArray() {
$genres = [];
foreach ($this->results AS $row) {
if ($row['genre_group_id'] != 0) {
$genres[$row['genre_group_name']][] = ['id' => $row['genre_id'], 'name' => $row['genre_name'], 'description' => $row['genre_description']];
}
}
ksort($genres);
return $genres;
}
}
class Manga_Lists {
public function __construct() {
global $sql;
$this->sql = $sql;
$results = $sql->query_read('manga_lists', 'SELECT * FROM mangadex_manga_lists', 'fetchAll', PDO::FETCH_UNIQUE);
foreach ($results as $i => $row) {
$this->{$i} = new \stdClass();
foreach ($row as $key => $value) {
$this->{$i}->$key = $value;
}
$this->{$i}->list_id = $i;
}
}
function get_manga_list($id) {
$id = prepare_numeric($id);
return $this->sql->prep("manga_list_$id", " SELECT manga_id FROM mangadex_manga_featured WHERE list_id = ? ORDER BY manga_id DESC ", [$id], 'fetchAll', PDO::FETCH_COLUMN);
}
}
class Follow_Types {
public function __construct() {
global $sql;
$results = $sql->query_read('follow_types', 'SELECT * FROM mangadex_follow_types', 'fetchAll', PDO::FETCH_UNIQUE);
foreach ($results as $i => $row) {
$this->{$i} = new \stdClass();
foreach ($row as $key => $value) {
$this->{$i}->$key = $value;
}
$this->{$i}->type_id = $i;
}
}
}
class Relation_Types {
public function __construct() {
global $sql;
$results = $sql->query_read('relation_types', 'SELECT * FROM mangadex_relation_types', 'fetchAll', PDO::FETCH_UNIQUE);
foreach ($results as $i => $row) {
$this->{$i} = new \stdClass();
foreach ($row as $key => $value) {
$this->{$i}->$key = $value;
}
$this->{$i}->relation_id = $i;
}
}
}
class Manga_reports {
public function __construct($age, $limit = 300) {
global $sql;
$age_operator = ($age == "new") ? "=" : ">";
$limit = prepare_numeric($limit);
//$offset = prepare_numeric($offset);
$results = $sql->query_read("manga_reports", "
SELECT reports.*,
reporter.username AS reported_name,
actioned.username AS actioned_name,
reporter_levels.level_colour AS reported_level_colour,
actioned_levels.level_colour AS actioned_level_colour
FROM mangadex_reports_manga AS reports
LEFT JOIN mangadex_users AS reporter ON reports.report_user_id = reporter.user_id
LEFT JOIN mangadex_user_levels AS reporter_levels ON reporter.level_id = reporter_levels.level_id
LEFT JOIN mangadex_users AS actioned ON reports.report_mod_user_id = actioned.user_id
LEFT JOIN mangadex_user_levels AS actioned_levels ON actioned.level_id = actioned_levels.level_id
WHERE reports.report_mod_user_id $age_operator 0
ORDER BY reports.report_timestamp DESC
LIMIT $limit
", 'fetchAll', PDO::FETCH_UNIQUE, -1);
foreach ($results as $i => $report) {
$this->{$i} = new \stdClass();
foreach ($report as $key => $value) {
$this->{$i}->$key = $value;
}
$this->{$i}->report_id = $i;
}
}
}