* @copyright 2024 Project-Pro * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) */ if (!defined('_PS_VERSION_')) { exit; } require_once __DIR__ . '/classes/BlogCategory.php'; require_once __DIR__ . '/classes/BlogPost.php'; class Projectproblog extends Module { const POSTS_PER_PAGE = 9; public function __construct() { $this->name = 'projectproblog'; $this->tab = 'content_management'; $this->version = '1.0.0'; $this->author = 'Project-Pro'; $this->author_uri = 'https://www.project-pro.pl'; $this->need_instance = 0; $this->bootstrap = true; $this->ps_versions_compliancy = [ 'min' => '1.7.0.0', 'max' => _PS_VERSION_, ]; parent::__construct(); $this->displayName = $this->l('Project-Pro Blog'); $this->description = $this->l('Moduł bloga z obsługą kategorii, podkategorii i wpisów wielojęzycznych.'); } /* ------------------------------------------------------------------ */ /* INSTALL / UNINSTALL */ /* ------------------------------------------------------------------ */ public function install() { $this->createImgDir(); return parent::install() && $this->installSql() && $this->installTabs() && $this->registerHook('moduleRoutes') && $this->registerHook('displayHome'); } protected function createImgDir() { $dir = _PS_MODULE_DIR_ . 'projectproblog/views/img/posts/'; if (!is_dir($dir)) { @mkdir($dir, 0755, true); } } public function uninstall() { return $this->uninstallTabs() && $this->uninstallSql() && parent::uninstall(); } /* ------------------------------------------------------------------ */ /* SQL */ /* ------------------------------------------------------------------ */ protected function installSql() { $sql = file_get_contents(__DIR__ . '/sql/install.sql'); $sql = str_replace('PREFIX_', _DB_PREFIX_, $sql); foreach (array_filter(array_map('trim', explode(';', $sql))) as $query) { if (!Db::getInstance()->execute($query)) { return false; } } return true; } protected function uninstallSql() { $sql = file_get_contents(__DIR__ . '/sql/uninstall.sql'); $sql = str_replace('PREFIX_', _DB_PREFIX_, $sql); foreach (array_filter(array_map('trim', explode(';', $sql))) as $query) { if (!Db::getInstance()->execute($query)) { return false; } } return true; } /* ------------------------------------------------------------------ */ /* TABS (menu admina) */ /* ------------------------------------------------------------------ */ protected function installTabs() { // Szukamy odpowiedniego rodzica w menu BO — fallback do 0 (główne menu) $parentCandidates = ['AdminParentContent', 'AdminParentCmsContent', 'AdminParentThemes']; $idMenuParent = 0; foreach ($parentCandidates as $candidate) { $found = (int) Tab::getIdFromClassName($candidate); if ($found > 0) { $idMenuParent = $found; break; } } // Tab-rodzic (bez kontrolera — tylko nagłówek w menu) $idParent = $this->addTab( 'AdminProjectproBlog', 'Project-Pro Blog', $idMenuParent, '' ); if (!$idParent) { return false; } // Podmenu: Kategorie if (!$this->addTab( 'AdminProjectproBlogCategories', 'Kategorie bloga', $idParent, $this->name )) { return false; } // Podmenu: Wpisy if (!$this->addTab( 'AdminProjectproBlogPosts', 'Wpisy bloga', $idParent, $this->name )) { return false; } return true; } protected function addTab($className, $name, $idParent, $module) { $tab = new Tab(); $tab->active = 1; $tab->class_name = $className; $tab->id_parent = (int) $idParent; $tab->module = $module; $tab->name = []; foreach (Language::getLanguages(false) as $lang) { $tab->name[$lang['id_lang']] = $name; } if (!$tab->add()) { return false; } return (int) $tab->id; } protected function uninstallTabs() { $tabs = [ 'AdminProjectproBlogCategories', 'AdminProjectproBlogPosts', 'AdminProjectproBlog', ]; foreach ($tabs as $className) { $id = (int) Tab::getIdFromClassName($className); if ($id) { $tab = new Tab($id); $tab->delete(); } } return true; } /* ------------------------------------------------------------------ */ /* ROUTING */ /* ------------------------------------------------------------------ */ public function hookModuleRoutes() { $this->ensureDisplayHomeHookRegistration(); return [ 'module-projectproblog-list' => [ 'controller' => 'list', 'rule' => 'blog', 'keywords' => [], 'params' => [ 'fc' => 'module', 'module' => $this->name, ], ], 'module-projectproblog-category' => [ 'controller' => 'list', 'rule' => 'blog/kategoria/{slug}', 'keywords' => [ 'slug' => [ 'regexp' => '[_a-zA-Z0-9\-]+', 'param' => 'slug', ], ], 'params' => [ 'fc' => 'module', 'module' => $this->name, ], ], 'module-projectproblog-post' => [ 'controller' => 'post', 'rule' => 'blog/wpis/{slug}', 'keywords' => [ 'slug' => [ 'regexp' => '[_a-zA-Z0-9\-]+', 'param' => 'slug', ], ], 'params' => [ 'fc' => 'module', 'module' => $this->name, ], ], ]; } /** * Zapewnia podpiecie hooka displayHome takze dla istniejacych instalacji. */ protected function ensureDisplayHomeHookRegistration() { $idHook = (int) Hook::getIdByName('displayHome'); if ($idHook <= 0) { return; } if (!$this->isRegisteredInHook('displayHome')) { $this->registerHook('displayHome'); } } /* ------------------------------------------------------------------ */ /* HELPERS — generowanie linków */ /* ------------------------------------------------------------------ */ public static function getBlogUrl($idLang = null) { return Context::getContext()->link->getModuleLink('projectproblog', 'list', [], true, $idLang); } public static function getCategoryUrl($linkRewrite, $idLang = null) { return Context::getContext()->link->getModuleLink( 'projectproblog', 'list', ['slug' => $linkRewrite], true, $idLang ); } public static function getPostUrl($linkRewrite, $idLang = null) { return Context::getContext()->link->getModuleLink( 'projectproblog', 'post', ['slug' => $linkRewrite], true, $idLang ); } /* ------------------------------------------------------------------ */ /* HOMEPAGE HOOK */ /* ------------------------------------------------------------------ */ public function hookDisplayHome() { $idLang = (int) $this->context->language->id; $posts = BlogPost::getLatest($idLang, 3); if (empty($posts)) { return ''; } $base = $this->context->link->getBaseLink(); foreach ($posts as &$post) { $post['thumbnail_url'] = $post['thumbnail'] ? $base . 'modules/projectproblog/views/img/posts/' . $post['thumbnail'] : null; $post['url'] = self::getPostUrl($post['link_rewrite'], $idLang); } unset($post); if (isset($this->context->controller)) { $this->context->controller->registerStylesheet( 'module-projectproblog-blog', 'modules/projectproblog/views/css/blog.css', ['media' => 'all', 'priority' => 200] ); } $this->context->smarty->assign([ 'blog_home_title' => $this->l('Najnowsze na blogu'), 'blog_home_posts' => $posts, 'blog_url' => self::getBlogUrl($idLang), ]); return $this->display(__FILE__, 'views/templates/hook/home.tpl'); } }