ver. 0.293: Code review fixes — 6 repositories, 16 fixes
- ArticleRepository: SQL injection fix (addslashes→parameterized), DRY refactor topArticles/newsListArticles
- AttributeRepository: dead class_exists('\S') blocking cache/temp clear
- CategoryRepository: dead class_exists('\S') blocking SEO link generation (critical)
- BannerRepository: parameterize $today in SQL + null guard on query()
- BasketCalculator: null guard checkProductQuantityInStock + optional DI params
- PromotionRepository: null guard on $basket (production fatal)
- OrderRepository/ShopBasketController/ajax.php: explicit DI in BasketCalculator callers
614 tests, 1821 assertions (+4 new)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -844,13 +844,14 @@ class ArticleRepository
|
||||
/**
|
||||
* Pobiera artykuly opublikowane w podanym zakresie dat.
|
||||
*/
|
||||
public function articlesByDateAdd( string $dateStart, string $dateEnd ): array
|
||||
public function articlesByDateAdd( string $dateStart, string $dateEnd, string $langId = 'pl' ): array
|
||||
{
|
||||
$stmt = $this->db->query(
|
||||
'SELECT id FROM pp_articles '
|
||||
. 'WHERE status = 1 '
|
||||
. 'AND date_add BETWEEN \'' . addslashes( $dateStart ) . '\' AND \'' . addslashes( $dateEnd ) . '\' '
|
||||
. 'ORDER BY date_add DESC'
|
||||
. 'AND date_add BETWEEN :date_start AND :date_end '
|
||||
. 'ORDER BY date_add DESC',
|
||||
[':date_start' => $dateStart, ':date_end' => $dateEnd]
|
||||
);
|
||||
|
||||
$articles = [];
|
||||
@@ -858,7 +859,7 @@ class ArticleRepository
|
||||
|
||||
if ( is_array( $rows ) ) {
|
||||
foreach ( $rows as $row ) {
|
||||
$articles[] = $this->articleDetailsFrontend( $row['id'], 'pl' );
|
||||
$articles[] = $this->articleDetailsFrontend( $row['id'], $langId );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -889,24 +890,18 @@ class ArticleRepository
|
||||
return null;
|
||||
}
|
||||
|
||||
$results = $this->db->select('pp_articles_langs', '*', [
|
||||
$langRow = $this->db->get('pp_articles_langs', '*', [
|
||||
'AND' => ['article_id' => $articleId, 'lang_id' => $langId]
|
||||
]);
|
||||
|
||||
if (is_array($results)) {
|
||||
foreach ($results as $row) {
|
||||
if ($row['copy_from']) {
|
||||
$results2 = $this->db->select('pp_articles_langs', '*', [
|
||||
'AND' => ['article_id' => $articleId, 'lang_id' => $row['copy_from']]
|
||||
]);
|
||||
if (is_array($results2)) {
|
||||
foreach ($results2 as $row2) {
|
||||
$article['language'] = $row2;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$article['language'] = $row;
|
||||
}
|
||||
if ($langRow) {
|
||||
if ($langRow['copy_from']) {
|
||||
$copyRow = $this->db->get('pp_articles_langs', '*', [
|
||||
'AND' => ['article_id' => $articleId, 'lang_id' => $langRow['copy_from']]
|
||||
]);
|
||||
$article['language'] = $copyRow ? $copyRow : $langRow;
|
||||
} else {
|
||||
$article['language'] = $langRow;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -955,7 +950,7 @@ class ArticleRepository
|
||||
return unserialize($objectData);
|
||||
}
|
||||
|
||||
$results = $this->db->query(
|
||||
$stmt = $this->db->query(
|
||||
'SELECT * FROM ( '
|
||||
. 'SELECT '
|
||||
. 'a.id, date_modify, date_add, o, '
|
||||
@@ -971,12 +966,14 @@ class ArticleRepository
|
||||
. 'INNER JOIN pp_articles AS a ON a.id = ap.article_id '
|
||||
. 'INNER JOIN pp_articles_langs AS al ON al.article_id = ap.article_id '
|
||||
. 'WHERE '
|
||||
. 'status = 1 AND page_id = ' . (int)$pageId . ' AND lang_id = \'' . $langId . '\' '
|
||||
. 'status = 1 AND page_id = ' . (int)$pageId . ' AND lang_id = :lang_id '
|
||||
. ') AS q1 '
|
||||
. 'WHERE q1.title IS NOT NULL '
|
||||
. 'ORDER BY q1.' . $order . ' '
|
||||
. 'LIMIT ' . (int)$from . ',' . (int)$limit
|
||||
)->fetchAll();
|
||||
. 'LIMIT ' . (int)$from . ',' . (int)$limit,
|
||||
[':lang_id' => $langId]
|
||||
);
|
||||
$results = $stmt ? $stmt->fetchAll() : [];
|
||||
|
||||
if (is_array($results) && !empty($results)) {
|
||||
foreach ($results as $row) {
|
||||
@@ -1003,7 +1000,7 @@ class ArticleRepository
|
||||
return (int)unserialize($objectData);
|
||||
}
|
||||
|
||||
$results = $this->db->query(
|
||||
$stmt = $this->db->query(
|
||||
'SELECT COUNT(0) FROM ( '
|
||||
. 'SELECT '
|
||||
. 'a.id, '
|
||||
@@ -1019,10 +1016,12 @@ class ArticleRepository
|
||||
. 'INNER JOIN pp_articles AS a ON a.id = ap.article_id '
|
||||
. 'INNER JOIN pp_articles_langs AS al ON al.article_id = ap.article_id '
|
||||
. 'WHERE '
|
||||
. 'status = 1 AND page_id = ' . (int)$pageId . ' AND lang_id = \'' . $langId . '\' '
|
||||
. 'status = 1 AND page_id = ' . (int)$pageId . ' AND lang_id = :lang_id '
|
||||
. ') AS q1 '
|
||||
. 'WHERE q1.title IS NOT NULL'
|
||||
)->fetchAll();
|
||||
. 'WHERE q1.title IS NOT NULL',
|
||||
[':lang_id' => $langId]
|
||||
);
|
||||
$results = $stmt ? $stmt->fetchAll() : [];
|
||||
|
||||
$count = isset($results[0][0]) ? (int)$results[0][0] : 0;
|
||||
|
||||
@@ -1106,14 +1105,30 @@ class ArticleRepository
|
||||
* Pobiera najpopularniejsze artykuly ze strony (wg views DESC, z Redis cache).
|
||||
*/
|
||||
public function topArticles(int $pageId, int $limit, string $langId): ?array
|
||||
{
|
||||
return $this->fetchArticlesByPage('topArticles', $pageId, $limit, $langId, 'views DESC');
|
||||
}
|
||||
|
||||
/**
|
||||
* Pobiera najnowsze artykuly ze strony (wg date_add DESC, z Redis cache).
|
||||
*/
|
||||
public function newsListArticles(int $pageId, int $limit, string $langId): ?array
|
||||
{
|
||||
return $this->fetchArticlesByPage('newsListArticles', $pageId, $limit, $langId, 'date_add DESC');
|
||||
}
|
||||
|
||||
/**
|
||||
* Wspolna logika dla topArticles/newsListArticles (z Redis cache).
|
||||
*/
|
||||
private function fetchArticlesByPage(string $cachePrefix, int $pageId, int $limit, string $langId, string $orderBy): ?array
|
||||
{
|
||||
$cacheHandler = new \Shared\Cache\CacheHandler();
|
||||
$cacheKey = "ArticleRepository::topArticles:{$pageId}:{$limit}:{$langId}";
|
||||
$cacheKey = "ArticleRepository::{$cachePrefix}:{$pageId}:{$limit}:{$langId}";
|
||||
|
||||
$objectData = $cacheHandler->get($cacheKey);
|
||||
|
||||
if (!$objectData) {
|
||||
$articlesData = $this->db->query(
|
||||
$stmt = $this->db->query(
|
||||
'SELECT * FROM ( '
|
||||
. 'SELECT '
|
||||
. 'a.id, date_add, views, '
|
||||
@@ -1129,61 +1144,14 @@ class ArticleRepository
|
||||
. 'INNER JOIN pp_articles AS a ON a.id = ap.article_id '
|
||||
. 'INNER JOIN pp_articles_langs AS al ON al.article_id = ap.article_id '
|
||||
. 'WHERE '
|
||||
. 'status = 1 AND page_id = ' . (int)$pageId . ' AND lang_id = \'' . $langId . '\' '
|
||||
. 'status = 1 AND page_id = ' . (int)$pageId . ' AND lang_id = :lang_id '
|
||||
. ') AS q1 '
|
||||
. 'WHERE q1.title IS NOT NULL '
|
||||
. 'ORDER BY q1.views DESC '
|
||||
. 'LIMIT 0, ' . (int)$limit
|
||||
)->fetchAll(\PDO::FETCH_ASSOC);
|
||||
|
||||
$cacheHandler->set($cacheKey, $articlesData);
|
||||
} else {
|
||||
$articlesData = unserialize($objectData);
|
||||
}
|
||||
|
||||
$articles = null;
|
||||
if (\Shared\Helpers\Helpers::is_array_fix($articlesData)) {
|
||||
foreach ($articlesData as $row) {
|
||||
$articles[] = $this->articleDetailsFrontend((int)$row['id'], $langId);
|
||||
}
|
||||
}
|
||||
|
||||
return $articles;
|
||||
}
|
||||
|
||||
/**
|
||||
* Pobiera najnowsze artykuly ze strony (wg date_add DESC, z Redis cache).
|
||||
*/
|
||||
public function newsListArticles(int $pageId, int $limit, string $langId): ?array
|
||||
{
|
||||
$cacheHandler = new \Shared\Cache\CacheHandler();
|
||||
$cacheKey = "ArticleRepository::newsListArticles:{$pageId}:{$limit}:{$langId}";
|
||||
|
||||
$objectData = $cacheHandler->get($cacheKey);
|
||||
|
||||
if (!$objectData) {
|
||||
$articlesData = $this->db->query(
|
||||
'SELECT * FROM ( '
|
||||
. 'SELECT '
|
||||
. 'a.id, date_add, '
|
||||
. '( CASE '
|
||||
. 'WHEN copy_from IS NULL THEN title '
|
||||
. 'WHEN copy_from IS NOT NULL THEN ( '
|
||||
. 'SELECT title FROM pp_articles_langs '
|
||||
. 'WHERE lang_id = al.copy_from AND article_id = a.id '
|
||||
. ') '
|
||||
. 'END ) AS title '
|
||||
. 'FROM '
|
||||
. 'pp_articles_pages AS ap '
|
||||
. 'INNER JOIN pp_articles AS a ON a.id = ap.article_id '
|
||||
. 'INNER JOIN pp_articles_langs AS al ON al.article_id = ap.article_id '
|
||||
. 'WHERE '
|
||||
. 'status = 1 AND page_id = ' . (int)$pageId . ' AND lang_id = \'' . $langId . '\' '
|
||||
. ') AS q1 '
|
||||
. 'WHERE q1.title IS NOT NULL '
|
||||
. 'ORDER BY q1.date_add DESC '
|
||||
. 'LIMIT 0, ' . (int)$limit
|
||||
)->fetchAll(\PDO::FETCH_ASSOC);
|
||||
. 'ORDER BY q1.' . $orderBy . ' '
|
||||
. 'LIMIT 0, ' . (int)$limit,
|
||||
[':lang_id' => $langId]
|
||||
);
|
||||
$articlesData = $stmt ? $stmt->fetchAll(\PDO::FETCH_ASSOC) : [];
|
||||
|
||||
$cacheHandler->set($cacheKey, $articlesData);
|
||||
} else {
|
||||
|
||||
Reference in New Issue
Block a user