350 lines
12 KiB
PHP
350 lines
12 KiB
PHP
<?php
|
|
|
|
/*
|
|
* Copyright 2008-2023 Anael MOBILIA
|
|
*
|
|
* This file is part of image-heberg.fr.
|
|
*
|
|
* image-heberg.fr is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* image-heberg.fr is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with image-heberg.fr. If not, see <http://www.gnu.org/licenses/>
|
|
*/
|
|
|
|
namespace ImageHeberg;
|
|
|
|
use ArrayObject;
|
|
|
|
/**
|
|
* Bibliothèque d'outils pour la gestion du site en tant qu'admin
|
|
*/
|
|
abstract class HelperAdmin
|
|
{
|
|
/**
|
|
* Liste des images n'ayant jamais été affichées et présentes sur le serveur depuis xx temps
|
|
* @return ArrayObject
|
|
*/
|
|
public static function getNeverUsedFiles(): ArrayObject
|
|
{
|
|
// Toutes les images jamais affichées & envoyées il y a plus de xx jours
|
|
$req = 'SELECT im.new_name
|
|
FROM images im
|
|
WHERE im.last_view = \'0000-00-00\'
|
|
AND im.date_action < DATE_SUB(CURRENT_DATE(), INTERVAL ' . _DELAI_EFFACEMENT_IMAGES_JAMAIS_AFFICHEES_ . ' DAY)
|
|
/* Préservation des fichiers des membres */
|
|
AND 0 = (
|
|
SELECT COUNT(*)
|
|
FROM possede po
|
|
WHERE po.images_id = im.id
|
|
)
|
|
/* Préservation si miniature affichée */
|
|
AND 0 = (
|
|
SELECT COUNT(*)
|
|
FROM thumbnails th
|
|
WHERE th.images_id = im.id
|
|
AND th.last_view <> \'0000-00-00\'
|
|
)';
|
|
return self::queryOnNewName($req);
|
|
}
|
|
|
|
/**
|
|
* Liste des images plus utilisées depuis au moins xx jours
|
|
* @return ArrayObject
|
|
*/
|
|
public static function getUnusedFiles(): ArrayObject
|
|
{
|
|
// Toutes les images non affichées depuis xx jours
|
|
$req = 'SELECT im.new_name
|
|
FROM images im
|
|
WHERE im.last_view < DATE_SUB(CURRENT_DATE(), INTERVAL ' . _DELAI_INACTIVITE_AVANT_EFFACEMENT_IMAGES_ . ' DAY)
|
|
/* Non prise en compte des images jamais affichées */
|
|
AND im.last_view <> \'0000-00-00\'
|
|
/* Préservation des images membres */
|
|
AND 0 = (
|
|
SELECT COUNT(*)
|
|
FROM possede po
|
|
WHERE po.images_id = im.id
|
|
)
|
|
/* Préservation si miniature affichée */
|
|
AND 0 = (
|
|
SELECT COUNT(*)
|
|
FROM thumbnails th
|
|
WHERE th.images_id = im.id
|
|
AND th.last_view > DATE_SUB(CURRENT_DATE(), INTERVAL ' . _DELAI_INACTIVITE_AVANT_EFFACEMENT_IMAGES_ . ' DAY)
|
|
)';
|
|
return self::queryOnNewName($req);
|
|
}
|
|
|
|
/**
|
|
* Liste des comptes sans images et créés depuis au moins xx jours
|
|
* @return ArrayObject
|
|
*/
|
|
public static function getUnusedAccounts(): ArrayObject
|
|
{
|
|
// Toutes les comptes créés et jamais utilisés depuis xx jours
|
|
$req = 'SELECT m.id
|
|
FROM membres m
|
|
WHERE m.date_action < DATE_SUB(CURRENT_DATE(), INTERVAL ' . _DELAI_EFFACEMENT_COMPTES_JAMAIS_UTILISES_ . ' DAY)
|
|
/* Préservation des comptes possédant des images */
|
|
AND 0 = (
|
|
SELECT COUNT(*)
|
|
FROM possede po
|
|
WHERE po.membres_id = m.id
|
|
)';
|
|
|
|
// Exécution de la requête
|
|
$resultat = MaBDD::getInstance()->query($req);
|
|
|
|
$monRetour = new ArrayObject();
|
|
// Pour chaque résultat retourné
|
|
foreach ($resultat->fetchAll() as $value) {
|
|
// J'ajoute l'ID du compte
|
|
$monRetour->append($value->id);
|
|
}
|
|
|
|
return $monRetour;
|
|
}
|
|
|
|
/**
|
|
* Liste de l'ensemble des images en BDD
|
|
* @return ArrayObject
|
|
*/
|
|
public static function getAllImagesNameBDD(): ArrayObject
|
|
{
|
|
// Toutes les images (sauf 404 & banned)
|
|
$req = 'SELECT md5 FROM images WHERE id > 2';
|
|
|
|
// Exécution de la requête
|
|
$resultat = MaBDD::getInstance()->query($req);
|
|
|
|
$monRetour = new ArrayObject();
|
|
// Pour chaque résultat retourné
|
|
foreach ($resultat->fetchAll() as $value) {
|
|
// J'ajoute le nom de l'image
|
|
$monRetour->append($value->md5);
|
|
}
|
|
|
|
return $monRetour;
|
|
}
|
|
|
|
/**
|
|
* Liste de l'ensemble des images en HDD
|
|
* @param string $path path à analyser
|
|
* @return ArrayObject
|
|
*/
|
|
public static function getAllImagesNameHDD(string $path): ArrayObject
|
|
{
|
|
$monRetour = new ArrayObject();
|
|
|
|
// Scanne le répertoire des images
|
|
$scan_rep = scandir($path);
|
|
// Pour chaque item
|
|
foreach ($scan_rep as $item) {
|
|
if (!in_array($item, ['.', '..', '_dummy', 'z_cache'])) {
|
|
if (is_dir($path . $item)) {
|
|
// Appel récursif
|
|
if ($path . $item . '/' !== _PATH_MINIATURES_) {
|
|
$monRetourTmp = self::getAllImagesNameHDD($path . $item . '/');
|
|
// Parsage et récupération des sous fichiers...
|
|
foreach ($monRetourTmp as $fichier) {
|
|
$monRetour->append($fichier);
|
|
}
|
|
}
|
|
} elseif ($item !== _IMAGE_404_ && $item !== _IMAGE_BAN_) {
|
|
$monRetour->append($item);
|
|
}
|
|
}
|
|
}
|
|
|
|
return $monRetour;
|
|
}
|
|
|
|
/**
|
|
* Liste de l'ensemble des miniatures en BDD
|
|
*/
|
|
public static function getAllMiniaturesNameBDD(): ArrayObject
|
|
{
|
|
// Toutes les images
|
|
$req = 'SELECT md5 FROM thumbnails';
|
|
|
|
// Exécution de la requête
|
|
$resultat = MaBDD::getInstance()->query($req);
|
|
|
|
|
|
$monRetour = new ArrayObject();
|
|
// Pour chaque résultat retourné
|
|
foreach ($resultat->fetchAll() as $value) {
|
|
// J'ajoute le nom de l'image
|
|
$monRetour->append($value->md5);
|
|
}
|
|
|
|
return $monRetour;
|
|
}
|
|
|
|
/**
|
|
* Toutes les images avec un même MD5
|
|
* @param string $unMd5
|
|
* @return ArrayObject
|
|
*/
|
|
public static function getImageByMd5(string $unMd5): ArrayObject
|
|
{
|
|
// Images avec le même MD5
|
|
$req = MaBDD::getInstance()->prepare('SELECT new_name FROM images WHERE md5 = :md5');
|
|
$req->bindValue(':md5', $unMd5);
|
|
$req->execute();
|
|
|
|
$monRetour = new ArrayObject();
|
|
// Pour chaque résultat retourné
|
|
foreach ($req->fetchAll() as $value) {
|
|
// J'ajoute le nom de l'image
|
|
$monRetour->append($value->new_name);
|
|
}
|
|
|
|
return $monRetour;
|
|
}
|
|
|
|
/**
|
|
* Toutes les images signalées
|
|
* @return ArrayObject
|
|
*/
|
|
public static function getImagesSignalees(): ArrayObject
|
|
{
|
|
// Images signalées
|
|
$req = 'SELECT new_name FROM images WHERE isSignalee = 1 and isBloquee = 0';
|
|
return self::queryOnNewName($req);
|
|
}
|
|
|
|
/**
|
|
* Images dont les statistiques d'affichage sont incohérentes
|
|
* @param int $nbMax Nb affichage / jour à partir duquel on veut les images
|
|
* @param bool $onlyOnImagesSuspectes Filtrer sur les images suspectes ?
|
|
* @return ArrayObject
|
|
*/
|
|
public static function getImagesTropAffichees(int $nbMax, bool $onlyOnImagesSuspectes = false): ArrayObject
|
|
{
|
|
if ($onlyOnImagesSuspectes) {
|
|
$tabNewName = [];
|
|
foreach ((array)self::getImagesPotentiellementIndesirables() as $newName) {
|
|
$tabNewName[] = '\'' . str_replace('\'', '', $newName) . '\'';
|
|
}
|
|
if (empty($tabNewName)) {
|
|
// Mettre un placeholder vide
|
|
$listeImagesForIn = '\'\'';
|
|
} else {
|
|
$listeImagesForIn = implode(',', $tabNewName);
|
|
}
|
|
}
|
|
|
|
// Images avec trop d'affichages
|
|
$req = 'SELECT im.new_name, ( im.nb_view_v4 + im.nb_view_v6 + (SELECT IFNULL(SUM(th.nb_view_v4 + th.nb_view_v6), 0) FROM thumbnails th where th.images_id = im.id) ) / IF(DATEDIFF(NOW(), im.date_action) > 0, DATEDIFF(NOW(), im.date_action), 1) as nbViewPerDay
|
|
FROM images im
|
|
WHERE im.isBloquee = 0
|
|
AND im.isSignalee = 0
|
|
AND im.isApprouvee = 0';
|
|
// Filter sur certaines images
|
|
if ($onlyOnImagesSuspectes) {
|
|
$req .= ' AND im.new_name IN (' . $listeImagesForIn . ')';
|
|
}
|
|
$req .= ' HAVING nbViewPerDay > ' . $nbMax . '
|
|
ORDER BY nbViewPerDay DESC';
|
|
return self::queryOnNewName($req);
|
|
}
|
|
|
|
/**
|
|
* Images dont les données sont proches d'images déjà bloquées
|
|
* @return ArrayObject
|
|
*/
|
|
public static function getImagesPotentiellementIndesirables(): ArrayObject
|
|
{
|
|
// Compléter les données "abuse_network" (normalement déjà fait dans ImageObject::creer())
|
|
// IPv4 - Filtrer sur un /24 || IPv6 - Filtrer sur un /56
|
|
$req = 'UPDATE images SET abuse_network =
|
|
IF(LOCATE(\'.\', remote_addr) != 0,
|
|
SUBSTRING(remote_addr, 1, (LENGTH(remote_addr) - LOCATE(\'.\', REVERSE(remote_addr)))),
|
|
SUBSTRING(HEX(INET6_ATON(remote_addr)), 1, 14)
|
|
)
|
|
WHERE abuse_network = \'\'';
|
|
MaBDD::getInstance()->query($req);
|
|
|
|
// Images potentiellement indésirables
|
|
$req = 'SELECT im.new_name
|
|
FROM images im
|
|
LEFT JOIN possede po ON po.images_id = im.id
|
|
WHERE im.isBloquee = 0
|
|
AND im.isApprouvee = 0
|
|
AND (
|
|
/* Même réseau IP */
|
|
im.abuse_network IN (SELECT DISTINCT abuse_network FROM images WHERE isBloquee = 1)
|
|
OR (
|
|
/* Même propriétaire */
|
|
po.membres_id IS NOT NULL
|
|
AND
|
|
po.membres_id IN (SELECT DISTINCT membres_id FROM possede WHERE images_id IN (SELECT id FROM images WHERE isBloquee = 1))
|
|
)
|
|
OR (
|
|
/* Même MD5 */
|
|
im.md5 IN (SELECT DISTINCT md5 FROM images WHERE isBloquee = 1)
|
|
)
|
|
)
|
|
ORDER BY im.id DESC';
|
|
return self::queryOnNewName($req);
|
|
}
|
|
|
|
/**
|
|
* Liste des réseaux avec mauvaise réputation
|
|
* @return ArrayObject ["IP" => "count()"]
|
|
*/
|
|
public static function getBadNetworks(): ArrayObject
|
|
{
|
|
$monRetour = new ArrayObject();
|
|
|
|
$req = 'SELECT COUNT(*) AS nb, abuse_network FROM images WHERE isBloquee = 1 GROUP BY abuse_network';
|
|
// Exécution de la requête
|
|
$resultat = MaBDD::getInstance()->query($req);
|
|
|
|
// Pour chaque résultat retourné
|
|
foreach ($resultat->fetchAll() as $value) {
|
|
$ip = $value->abuse_network;
|
|
// Formatter les IPv6
|
|
if (!str_contains($ip, ".")) {
|
|
$ip = implode(":", str_split($ip, 4));
|
|
$ip .= "::/56";
|
|
} else {
|
|
$ip .= ".0/24";
|
|
}
|
|
$monRetour->offsetSet($ip, $value->nb);
|
|
}
|
|
// Tri "humain"
|
|
$monRetour->ksort(SORT_NATURAL);
|
|
|
|
return $monRetour;
|
|
}
|
|
|
|
/**
|
|
* Joue une requête SQL et retourne un tableau "new_name"
|
|
* @param string $req
|
|
* @return ArrayObject
|
|
*/
|
|
public static function queryOnNewName(string $req): ArrayObject
|
|
{
|
|
// Exécution de la requête
|
|
$resultat = MaBDD::getInstance()->query($req);
|
|
|
|
$monRetour = new ArrayObject();
|
|
// Pour chaque résultat retourné
|
|
foreach ($resultat->fetchAll() as $value) {
|
|
// J'ajoute le nom de l'image
|
|
$monRetour->append($value->new_name);
|
|
}
|
|
|
|
return $monRetour;
|
|
}
|
|
}
|