mirror of
https://github.com/quentin-g-dev/afup.git
synced 2026-03-26 10:12:16 +01:00
226 lines
6.9 KiB
PHP
226 lines
6.9 KiB
PHP
<?php
|
|
|
|
namespace PlanetePHP;
|
|
|
|
use Afup\Site\Utils\Configuration;
|
|
use Assert\Assertion;
|
|
use Doctrine\DBAL\Connection;
|
|
use HTMLPurifier;
|
|
use HTMLPurifier_Config;
|
|
use PDO;
|
|
|
|
class FeedArticleRepository
|
|
{
|
|
const RELEVANT = 1;
|
|
const IRRELEVANT = 0;
|
|
/** @var Connection */
|
|
private $connection;
|
|
/** @var string */
|
|
private $pertinenceRegex;
|
|
|
|
public function __construct(
|
|
Connection $connection,
|
|
Configuration $configuration
|
|
) {
|
|
$this->connection = $connection;
|
|
$this->pertinenceRegex = '/'.$configuration->obtenir('planete|pertinence').'/i';
|
|
}
|
|
|
|
/**
|
|
* @param string $sort
|
|
* @param string $direction
|
|
* @param int $limit
|
|
*
|
|
* @return FeedArticle[]
|
|
*/
|
|
public function search($sort, $direction, $limit = 20)
|
|
{
|
|
$sorts = [
|
|
'title' => 'b.titre',
|
|
'content' => 'b.contenu',
|
|
'status' => 'b.etat',
|
|
];
|
|
Assertion::integer($limit);
|
|
Assertion::keyExists($sorts, $sort);
|
|
Assertion::inArray($direction, ['asc', 'desc']);
|
|
$qb = $this->connection->createQueryBuilder();
|
|
$qb->from('afup_planete_billet', 'b')
|
|
->select('b.*')
|
|
->orderBy($sorts[$sort], $direction)
|
|
->setMaxResults($limit);
|
|
|
|
return $this->hydrate($qb->execute()->fetchAll());
|
|
}
|
|
|
|
public function save(FeedArticle $billet)
|
|
{
|
|
$id = $this->findIdByKey($billet->getKey());
|
|
if (null !== $id) {
|
|
return $this->update($billet, $id);
|
|
}
|
|
|
|
return $this->insert($billet);
|
|
}
|
|
|
|
/**
|
|
* @param string $content
|
|
* @param string $url
|
|
* @param int $characters
|
|
*
|
|
* @return string
|
|
*/
|
|
public function truncateContent($content, $url, $characters = 3000)
|
|
{
|
|
$truncatedContent = $content;
|
|
$isTruncated = false;
|
|
if (mb_strlen($content) > $characters) {
|
|
$lastPeriod = mb_strpos($content, '.', $characters);
|
|
if ($lastPeriod) {
|
|
$isTruncated = true;
|
|
$truncatedContent = mb_substr($content, 0, $lastPeriod + 1);
|
|
}
|
|
}
|
|
|
|
$config = HTMLPurifier_Config::createDefault();
|
|
$config->set('Core.Encoding', 'UTF-8');
|
|
$config->set('HTML.Doctype', 'HTML 4.01 Transitional');
|
|
$purifier = new HTMLPurifier($config);
|
|
$truncatedContent = $purifier->purify($truncatedContent);
|
|
|
|
if ($isTruncated) {
|
|
$truncatedContent .= sprintf('<p><a class="btn" href="%s">Voir la suite</a></p>', $url);
|
|
}
|
|
|
|
return $truncatedContent;
|
|
}
|
|
|
|
/**
|
|
* @param int $page
|
|
* @param string $format
|
|
*
|
|
* @return DisplayableFeedArticle[]
|
|
*/
|
|
public function findLatestTruncated($page = 0, $format = DATE_ATOM)
|
|
{
|
|
return array_map(function (DisplayableFeedArticle $article) {
|
|
$article->setContent($this->truncateContent($article->getContent(), $article->getUrl()));
|
|
|
|
return $article;
|
|
}, $this->findLatest($page, $format));
|
|
}
|
|
|
|
public function findLatest($page = 0, $format = DATE_ATOM, $nombre = 10)
|
|
{
|
|
$query = $this->connection->prepare('SELECT b.titre, b.url, b.maj, b.auteur, b.contenu, f.nom feed_name, f.url feed_url
|
|
FROM afup_planete_billet b
|
|
INNER JOIN afup_planete_flux f on b.afup_planete_flux_id = f.id
|
|
WHERE b.etat = :status
|
|
ORDER BY b.maj DESC
|
|
LIMIT :start, :length
|
|
');
|
|
$query->bindValue('status', self::RELEVANT);
|
|
$query->bindValue('start', $page * $nombre, PDO::PARAM_INT);
|
|
$query->bindValue('length', $nombre, PDO::PARAM_INT);
|
|
$query->execute();
|
|
|
|
return $this->hydrateDisplayable($query->fetchAll(), $format);
|
|
}
|
|
|
|
public function isRelevant($content)
|
|
{
|
|
$content = strip_tags($content);
|
|
$relevant = self::IRRELEVANT;
|
|
if (preg_match($this->pertinenceRegex, $content)) {
|
|
$relevant = self::RELEVANT;
|
|
}
|
|
|
|
return $relevant;
|
|
}
|
|
|
|
private function findIdByKey($key)
|
|
{
|
|
$query = $this->connection->prepare('SELECT id FROM afup_planete_billet WHERE clef = :key');
|
|
$query->bindValue('key', $key);
|
|
$query->execute();
|
|
$row = $query->fetch();
|
|
|
|
return is_array($row) ? $row['id'] : null;
|
|
}
|
|
|
|
private function update(FeedArticle $billet, $id = null)
|
|
{
|
|
return $this->connection->executeUpdate('UPDATE afup_planete_billet
|
|
SET afup_planete_flux_id = :feedId,
|
|
clef= :key,
|
|
titre = :title,
|
|
url = :url,
|
|
maj = :update,
|
|
auteur = :author,
|
|
resume = :summary,
|
|
contenu = :content,
|
|
etat = :status
|
|
WHERE id = :id', [
|
|
'id' => $id ?: $billet->getId(),
|
|
'feedId' => $billet->getFeedId(),
|
|
'key' => $billet->getKey(),
|
|
'title' => $billet->getTitle(),
|
|
'url' => $billet->getUrl(),
|
|
'update' => $billet->getUpdate(),
|
|
'author' => $billet->getAuthor(),
|
|
'summary' => $billet->getSummary(),
|
|
'content' => $billet->getContent(),
|
|
'status' => $billet->getStatus(),
|
|
]);
|
|
}
|
|
|
|
private function insert(FeedArticle $billet)
|
|
{
|
|
return $this->connection->executeUpdate('INSERT INTO afup_planete_billet
|
|
(afup_planete_flux_id, clef, titre, url, maj, auteur, resume, contenu, etat)
|
|
VALUES (:feedId, :key, :title, :url, :update, :author, :summary, :content, :status)', [
|
|
'feedId' => $billet->getFeedId(),
|
|
'key' => $billet->getKey(),
|
|
'title' => $billet->getTitle(),
|
|
'url' => $billet->getUrl(),
|
|
'update' => $billet->getUpdate(),
|
|
'author' => $billet->getAuthor(),
|
|
'summary' => $billet->getSummary(),
|
|
'content' => $billet->getContent(),
|
|
'status' => $billet->getStatus(),
|
|
]);
|
|
}
|
|
|
|
private function hydrate(array $rows)
|
|
{
|
|
return array_map(static function (array $row) {
|
|
return new FeedArticle(
|
|
$row['id'],
|
|
$row['afup_planete_flux_id'],
|
|
$row['clef'],
|
|
$row['titre'],
|
|
$row['url'],
|
|
$row['maj'],
|
|
$row['auteur'],
|
|
$row['resume'],
|
|
$row['contenu'],
|
|
$row['etat']
|
|
);
|
|
}, $rows);
|
|
}
|
|
|
|
private function hydrateDisplayable(array $rows, $format = DATE_ATOM)
|
|
{
|
|
return array_map(static function (array $row) use ($format) {
|
|
return new DisplayableFeedArticle(
|
|
$row['titre'],
|
|
$row['url'],
|
|
date($format, $row['maj']),
|
|
$row['auteur'],
|
|
$row['contenu'],
|
|
$row['feed_name'],
|
|
$row['feed_url']
|
|
);
|
|
}, $rows);
|
|
}
|
|
}
|