* @copyright 2024 Project-Pro */ if (!defined('_PS_VERSION_')) { exit; } class BlogPost extends ObjectModel { /** @var bool */ public $active = true; /** @var string|null */ public $thumbnail; /** @var string */ public $date_add; /** @var string */ public $date_upd; // --- multilang --- /** @var string */ public $title; /** @var string */ public $intro; /** @var string */ public $content; /** @var string */ public $link_rewrite; /** @var string */ public $meta_title; /** @var string */ public $meta_keywords; /** @var string */ public $meta_description; public static $definition = [ 'table' => 'projectproblog_post', 'primary' => 'id_post', 'multilang' => true, 'fields' => [ // główna tabela 'active' => ['type' => self::TYPE_BOOL, 'validate' => 'isBool'], 'thumbnail' => ['type' => self::TYPE_STRING, 'validate' => 'isFileName', 'size' => 255], 'date_add' => ['type' => self::TYPE_DATE, 'validate' => 'isDate'], 'date_upd' => ['type' => self::TYPE_DATE, 'validate' => 'isDate'], // multilang 'title' => ['type' => self::TYPE_STRING, 'lang' => true, 'validate' => 'isGenericName', 'required' => true, 'size' => 255], 'intro' => ['type' => self::TYPE_HTML, 'lang' => true, 'validate' => 'isCleanHtml'], 'content' => ['type' => self::TYPE_HTML, 'lang' => true, 'validate' => 'isCleanHtml'], 'link_rewrite' => ['type' => self::TYPE_STRING, 'lang' => true, 'validate' => 'isLinkRewrite', 'required' => true, 'size' => 255], 'meta_title' => ['type' => self::TYPE_STRING, 'lang' => true, 'validate' => 'isGenericName', 'size' => 255], 'meta_keywords' => ['type' => self::TYPE_STRING, 'lang' => true, 'validate' => 'isGenericName', 'size' => 255], 'meta_description' => ['type' => self::TYPE_STRING, 'lang' => true, 'validate' => 'isGenericName', 'size' => 512], ], ]; /* ------------------------------------------------------------------ */ /* Delete — sprzątanie pliku i relacji z kategoriami */ /* ------------------------------------------------------------------ */ public function delete() { if ($this->thumbnail) { $file = _PS_MODULE_DIR_ . 'projectproblog/views/img/posts/' . $this->thumbnail; if (file_exists($file)) { @unlink($file); } } Db::getInstance()->delete( 'projectproblog_post_category', 'id_post = ' . (int) $this->id ); return parent::delete(); } /* ------------------------------------------------------------------ */ /* Relacje z kategoriami */ /* ------------------------------------------------------------------ */ /** * Zwraca tablicę ID kategorii przypisanych do wpisu. */ public static function getCategories($idPost) { $rows = Db::getInstance()->executeS( 'SELECT `id_category` FROM `' . _DB_PREFIX_ . 'projectproblog_post_category` WHERE `id_post` = ' . (int) $idPost ); return is_array($rows) ? array_column($rows, 'id_category') : []; } /** * Zapisuje relacje wpis↔kategorie (zastępuje stare). */ public static function setCategories($idPost, array $categoryIds) { Db::getInstance()->delete( 'projectproblog_post_category', 'id_post = ' . (int) $idPost ); if (empty($categoryIds)) { return; } $rows = []; foreach ($categoryIds as $idCat) { if ((int) $idCat > 0) { $rows[] = [ 'id_post' => (int) $idPost, 'id_category' => (int) $idCat, ]; } } if ($rows) { Db::getInstance()->insert('projectproblog_post_category', $rows); } } /* ------------------------------------------------------------------ */ /* Zapytania dla frontu */ /* ------------------------------------------------------------------ */ /** * Lista wpisów do wyświetlenia na stronie (z opcjonalnym filtrem kategorii). */ public static function getList($idLang, $page, $perPage, $idCategory = null) { $page = max(1, (int) $page); $perPage = max(1, (int) $perPage); $offset = ($page - 1) * $perPage; $join = $idCategory ? 'INNER JOIN `' . _DB_PREFIX_ . 'projectproblog_post_category` pc ON p.`id_post` = pc.`id_post` AND pc.`id_category` = ' . (int) $idCategory : ''; return Db::getInstance()->executeS( 'SELECT p.`id_post`, p.`thumbnail`, p.`date_add`, pl.`title`, pl.`intro`, pl.`link_rewrite` FROM `' . _DB_PREFIX_ . 'projectproblog_post` p LEFT JOIN `' . _DB_PREFIX_ . 'projectproblog_post_lang` pl ON p.`id_post` = pl.`id_post` AND pl.`id_lang` = ' . (int) $idLang . ' ' . $join . ' WHERE p.`active` = 1 ORDER BY p.`date_add` DESC LIMIT ' . (int) $offset . ', ' . (int) $perPage ); } /** * Pobiera najnowsze aktywne wpisy (bez paginacji) do sekcji homepage. */ public static function getLatest($idLang, $limit = 3) { $limit = max(1, (int) $limit); return Db::getInstance()->executeS( 'SELECT p.`id_post`, p.`thumbnail`, p.`date_add`, pl.`title`, pl.`intro`, pl.`link_rewrite` FROM `' . _DB_PREFIX_ . 'projectproblog_post` p LEFT JOIN `' . _DB_PREFIX_ . 'projectproblog_post_lang` pl ON p.`id_post` = pl.`id_post` AND pl.`id_lang` = ' . (int) $idLang . ' WHERE p.`active` = 1 ORDER BY p.`date_add` DESC LIMIT ' . (int) $limit ); } /** * Liczba wpisów (do paginacji). */ public static function getCount($idLang, $idCategory = null) { $join = $idCategory ? 'INNER JOIN `' . _DB_PREFIX_ . 'projectproblog_post_category` pc ON p.`id_post` = pc.`id_post` AND pc.`id_category` = ' . (int) $idCategory : ''; return (int) Db::getInstance()->getValue( 'SELECT COUNT(DISTINCT p.`id_post`) FROM `' . _DB_PREFIX_ . 'projectproblog_post` p ' . $join . ' WHERE p.`active` = 1' ); } /** * Pobiera wpis po link_rewrite dla danego języka. */ public static function getByLinkRewrite($linkRewrite, $idLang) { $row = Db::getInstance()->getRow( 'SELECT p.`id_post` FROM `' . _DB_PREFIX_ . 'projectproblog_post` p INNER JOIN `' . _DB_PREFIX_ . 'projectproblog_post_lang` pl ON p.`id_post` = pl.`id_post` AND pl.`id_lang` = ' . (int) $idLang . ' WHERE pl.`link_rewrite` = \'' . pSQL($linkRewrite) . '\' AND p.`active` = 1' ); return $row ? new BlogPost((int) $row['id_post'], $idLang) : null; } /* ------------------------------------------------------------------ */ /* Helper URL miniaturki */ /* ------------------------------------------------------------------ */ public function getThumbnailUrl() { if (!$this->thumbnail) { return null; } return Context::getContext()->link->getBaseLink() . 'modules/projectproblog/views/img/posts/' . $this->thumbnail; } }