diff --git a/autoload/Domain/Layouts/LayoutsRepository.php b/autoload/Domain/Layouts/LayoutsRepository.php index 49b2d3f..ca185fa 100644 --- a/autoload/Domain/Layouts/LayoutsRepository.php +++ b/autoload/Domain/Layouts/LayoutsRepository.php @@ -227,6 +227,183 @@ class LayoutsRepository ]; } + // ── Frontend methods ────────────────────────────────────────── + + public function categoryDefaultLayoutId() + { + return $this->db->get('pp_layouts', 'id', ['categories_default' => 1]); + } + + public function getDefaultLayout(): ?array + { + $cacheHandler = new \Shared\Cache\CacheHandler(); + $cacheKey = 'LayoutsRepository::getDefaultLayout'; + + $objectData = $cacheHandler->get($cacheKey); + if ($objectData) { + $cached = @unserialize($objectData); + if (is_array($cached) && !empty($cached)) { + return $cached; + } + $cacheHandler->delete($cacheKey); + } + + $layout = $this->db->get('pp_layouts', '*', ['status' => 1]); + if (!is_array($layout) || empty($layout)) { + return null; + } + + $cacheHandler->set($cacheKey, $layout); + return $layout; + } + + public function getProductLayout(int $productId): ?array + { + $cacheHandler = new \Shared\Cache\CacheHandler(); + $cacheKey = "LayoutsRepository::getProductLayout:$productId"; + + $objectData = $cacheHandler->get($cacheKey); + if ($objectData) { + $cached = @unserialize($objectData); + if (is_array($cached) && !empty($cached)) { + return $cached; + } + $cacheHandler->delete($cacheKey); + } + + $layoutRows = $this->db->query( + "SELECT pp_layouts.* + FROM pp_layouts + JOIN pp_shop_products ON pp_layouts.id = pp_shop_products.layout_id + WHERE pp_shop_products.id = " . (int)$productId . " + ORDER BY pp_layouts.id DESC" + )->fetchAll(\PDO::FETCH_ASSOC); + + if (is_array($layoutRows) && isset($layoutRows[0])) { + $layout = $layoutRows[0]; + } else { + $layoutRows = $this->db->query( + "SELECT pp_layouts.* + FROM pp_layouts + JOIN pp_layouts_categories ON pp_layouts.id = pp_layouts_categories.layout_id + JOIN pp_shop_products_categories ON pp_shop_products_categories.category_id = pp_layouts_categories.category_id + WHERE pp_shop_products_categories.product_id = " . (int)$productId . " + ORDER BY pp_shop_products_categories.o ASC, pp_layouts.id DESC" + )->fetchAll(\PDO::FETCH_ASSOC); + + if (is_array($layoutRows) && isset($layoutRows[0])) { + $layout = $layoutRows[0]; + } else { + $layout = $this->db->get('pp_layouts', '*', ['categories_default' => 1]); + } + } + + if (!$layout) { + $layout = $this->db->get('pp_layouts', '*', ['status' => 1]); + } + + if (!is_array($layout) || empty($layout)) { + return null; + } + + $cacheHandler->set($cacheKey, $layout); + return $layout; + } + + public function getArticleLayout(int $articleId): ?array + { + $cacheHandler = new \Shared\Cache\CacheHandler(); + $cacheKey = "LayoutsRepository::getArticleLayout:$articleId"; + + $objectData = $cacheHandler->get($cacheKey); + if ($objectData) { + $cached = @unserialize($objectData); + if (is_array($cached)) { + return $cached; + } + $cacheHandler->delete($cacheKey); + } + + $layout = $this->db->get('pp_layouts', ['[><]pp_articles' => ['id' => 'layout_id']], '*', ['pp_articles.id' => (int)$articleId]); + + if (is_array($layout)) { + $cacheHandler->set($cacheKey, $layout); + return $layout; + } + + return null; + } + + public function getCategoryLayout(int $categoryId): ?array + { + $cacheHandler = new \Shared\Cache\CacheHandler(); + $cacheKey = "LayoutsRepository::getCategoryLayout:$categoryId"; + + $objectData = $cacheHandler->get($cacheKey); + if ($objectData) { + $cached = @unserialize($objectData); + if (is_array($cached) && !empty($cached)) { + return $cached; + } + $cacheHandler->delete($cacheKey); + } + + $layoutRows = $this->db->query( + "SELECT pp_layouts.* + FROM pp_layouts + JOIN pp_layouts_categories ON pp_layouts.id = pp_layouts_categories.layout_id + WHERE pp_layouts_categories.category_id = " . (int)$categoryId . " + ORDER BY pp_layouts.id DESC" + )->fetchAll(\PDO::FETCH_ASSOC); + + if (is_array($layoutRows) && isset($layoutRows[0])) { + $layout = $layoutRows[0]; + } else { + $layout = $this->db->get('pp_layouts', '*', ['categories_default' => 1]); + } + + if (!$layout) { + $layout = $this->db->get('pp_layouts', '*', ['status' => 1]); + } + + if (!is_array($layout) || empty($layout)) { + return null; + } + + $cacheHandler->set($cacheKey, $layout); + return $layout; + } + + public function getActiveLayout(int $pageId): ?array + { + $cacheHandler = new \Shared\Cache\CacheHandler(); + $cacheKey = "LayoutsRepository::getActiveLayout:$pageId"; + + $objectData = $cacheHandler->get($cacheKey); + if ($objectData) { + $cached = @unserialize($objectData); + if (is_array($cached)) { + return $cached; + } + $cacheHandler->delete($cacheKey); + } + + $layout = $this->db->get('pp_layouts', ['[><]pp_layouts_pages' => ['id' => 'layout_id']], '*', ['page_id' => (int)$pageId]); + + if (!$layout) { + $layout = $this->db->get('pp_layouts', '*', ['status' => 1]); + } + + if (is_array($layout)) { + $cacheHandler->set($cacheKey, $layout); + return $layout; + } + + return null; + } + + // ── Private helpers ────────────────────────────────────────── + private function syncPages(int $layoutId, $pages): void { foreach ($this->normalizeIds($pages) as $pageId) { diff --git a/autoload/Domain/Pages/PagesRepository.php b/autoload/Domain/Pages/PagesRepository.php index 210d590..8548d7c 100644 --- a/autoload/Domain/Pages/PagesRepository.php +++ b/autoload/Domain/Pages/PagesRepository.php @@ -628,4 +628,158 @@ class PagesRepository $value = trim((string)$value); return $value === '' ? null : $value; } + + // ── Frontend methods ────────────────────────────────────────── + + public function frontPageDetails($id = '', $langId = ''): ?array + { + $langId = (string)$langId; + + if (!$id) { + $id = $this->frontMainPageId(); + } + + $cacheHandler = new \Shared\Cache\CacheHandler(); + $cacheKey = "PagesRepository::frontPageDetails:$id:$langId"; + + $objectData = $cacheHandler->get($cacheKey); + if ($objectData) { + $cached = @unserialize($objectData); + if (is_array($cached)) { + return $cached; + } + $cacheHandler->delete($cacheKey); + } + + $page = $this->db->get('pp_pages', '*', ['id' => (int)$id]); + if (!is_array($page)) { + return null; + } + + $page['language'] = $this->db->get('pp_pages_langs', '*', ['AND' => ['page_id' => (int)$id, 'lang_id' => $langId]]); + + $cacheHandler->set($cacheKey, $page); + return $page; + } + + public function frontPageSort(int $pageId) + { + $cacheHandler = new \Shared\Cache\CacheHandler(); + $cacheKey = "PagesRepository::frontPageSort:$pageId"; + + $objectData = $cacheHandler->get($cacheKey); + if ($objectData) { + $cached = @unserialize($objectData); + if ($cached !== false) { + return $cached; + } + $cacheHandler->delete($cacheKey); + } + + $sort = $this->db->get('pp_pages', 'sort_type', ['id' => $pageId]); + + $cacheHandler->set($cacheKey, $sort); + return $sort; + } + + public function frontMainPageId() + { + $cacheHandler = new \Shared\Cache\CacheHandler(); + $cacheKey = 'PagesRepository::frontMainPageId'; + + $objectData = $cacheHandler->get($cacheKey); + if ($objectData) { + $cached = @unserialize($objectData); + if ($cached) { + return $cached; + } + $cacheHandler->delete($cacheKey); + } + + $id = $this->db->get('pp_pages', 'id', ['AND' => ['status' => 1, 'start' => 1]]); + if (!$id) { + $id = $this->db->get('pp_pages', 'id', ['status' => 1, 'ORDER' => ['menu_id' => 'ASC', 'o' => 'ASC'], 'LIMIT' => 1]); + } + + $cacheHandler->set($cacheKey, $id); + return $id; + } + + public function frontLangUrl(int $pageId, string $langId): string + { + $page = $this->frontPageDetails($pageId, $langId); + if (!is_array($page) || !is_array($page['language'] ?? null)) { + return '/'; + } + + $seoLink = $page['language']['seo_link'] ?? ''; + $title = $page['language']['title'] ?? ''; + $url = $seoLink ? '/' . $seoLink : '/s-' . $page['id'] . '-' . \Shared\Helpers\Helpers::seo($title); + + $defaultLang = (new \Domain\Languages\LanguagesRepository($this->db))->defaultLanguage(); + if ($langId !== $defaultLang && $url !== '#') { + $url = '/' . $langId . $url; + } + + return $url; + } + + public function frontMenuDetails(int $menuId, string $langId): ?array + { + $cacheHandler = new \Shared\Cache\CacheHandler(); + $cacheKey = "PagesRepository::frontMenuDetails:$menuId:$langId"; + + $objectData = $cacheHandler->get($cacheKey); + if ($objectData) { + $cached = @unserialize($objectData); + if (is_array($cached)) { + return $cached; + } + $cacheHandler->delete($cacheKey); + } + + $menu = $this->db->get('pp_menus', '*', ['id' => (int)$menuId]); + if (!is_array($menu)) { + return null; + } + + $menu['pages'] = $this->frontMenuPages($menuId, $langId); + + $cacheHandler->set($cacheKey, $menu); + return $menu; + } + + public function frontMenuPages(int $menuId, string $langId, $parentId = null): ?array + { + $cacheHandler = new \Shared\Cache\CacheHandler(); + $cacheKey = "PagesRepository::frontMenuPages:$menuId:$langId:$parentId"; + + $objectData = $cacheHandler->get($cacheKey); + if ($objectData) { + $cached = @unserialize($objectData); + if (is_array($cached)) { + return $cached; + } + $cacheHandler->delete($cacheKey); + } + + $results = $this->db->select('pp_pages', ['id'], [ + 'AND' => ['status' => 1, 'menu_id' => (int)$menuId, 'parent_id' => $parentId], + 'ORDER' => ['o' => 'ASC'], + ]); + + $pages = []; + if (is_array($results)) { + foreach ($results as $row) { + $page = $this->frontPageDetails($row['id'], $langId); + if (is_array($page)) { + $page['pages'] = $this->frontMenuPages($menuId, $langId, $row['id']); + $pages[] = $page; + } + } + } + + $cacheHandler->set($cacheKey, $pages); + return $pages; + } } diff --git a/autoload/Shared/Helpers/Helpers.php b/autoload/Shared/Helpers/Helpers.php index 0398e29..baeab72 100644 --- a/autoload/Shared/Helpers/Helpers.php +++ b/autoload/Shared/Helpers/Helpers.php @@ -445,13 +445,14 @@ class Helpers // // PRODUCENCI // - $htaccess_data .= 'RewriteRule ^producenci$ index.php?module=shop_producer&action=list&layout_id=' . \front\factory\Layouts::category_default_layout() . '&%{QUERY_STRING} [L]' . PHP_EOL; + $categoryDefaultLayoutId = ( new \Domain\Layouts\LayoutsRepository( $mdb ) )->categoryDefaultLayoutId(); + $htaccess_data .= 'RewriteRule ^producenci$ index.php?module=shop_producer&action=list&layout_id=' . $categoryDefaultLayoutId . '&%{QUERY_STRING} [L]' . PHP_EOL; $rows = $mdb -> select( 'pp_shop_producer', '*', [ 'status' => 1 ] ); if ( self::is_array_fix( $rows ) ) foreach ( $rows as $row ) { - $htaccess_data .= 'RewriteRule ^producent/' . self::seo( $row['name'] ) . '$ index.php?module=shop_producer&action=products&producer_id=' . $row['id'] . '&layout_id=' . \front\factory\Layouts::category_default_layout() . '&%{QUERY_STRING} [L]' . PHP_EOL; - $htaccess_data .= 'RewriteRule ^producent/' . self::seo( $row['name'] ) . '/([0-9]+)$ index.php?module=shop_producer&action=products&producer_id=' . $row['id'] . '&layout_id=' . \front\factory\Layouts::category_default_layout() . '&bs=$1&%{QUERY_STRING} [L]' . PHP_EOL; + $htaccess_data .= 'RewriteRule ^producent/' . self::seo( $row['name'] ) . '$ index.php?module=shop_producer&action=products&producer_id=' . $row['id'] . '&layout_id=' . $categoryDefaultLayoutId . '&%{QUERY_STRING} [L]' . PHP_EOL; + $htaccess_data .= 'RewriteRule ^producent/' . self::seo( $row['name'] ) . '/([0-9]+)$ index.php?module=shop_producer&action=products&producer_id=' . $row['id'] . '&layout_id=' . $categoryDefaultLayoutId . '&bs=$1&%{QUERY_STRING} [L]' . PHP_EOL; } $results = $mdb -> select( 'pp_langs', [ 'id', 'start' ], [ 'status' => 1, 'ORDER' => [ 'o' => 'ASC' ] ] ); diff --git a/autoload/front/Views/Menu.php b/autoload/front/Views/Menu.php new file mode 100644 index 0000000..0a91b02 --- /dev/null +++ b/autoload/front/Views/Menu.php @@ -0,0 +1,22 @@ +pages = $pages; + $tpl->level = $level; + $tpl->current_page = $current_page; + return $tpl->render('menu/pages'); + } + + public static function menu($menu, $current_page) + { + $tpl = new \Shared\Tpl\Tpl; + $tpl->menu = $menu; + $tpl->current_page = $current_page; + return $tpl->render('menu/menu'); + } +} diff --git a/autoload/front/controls/class.Site.php b/autoload/front/controls/class.Site.php index 058e7ad..e382bbb 100644 --- a/autoload/front/controls/class.Site.php +++ b/autoload/front/controls/class.Site.php @@ -133,7 +133,9 @@ class Site switch ( $a ) { case 'page': - $page = \front\factory\Pages::page_details( \Shared\Helpers\Helpers::get( 'id' ) ); + global $lang_id; + $pagesRepo = new \Domain\Pages\PagesRepository( $GLOBALS['mdb'] ); + $page = $pagesRepo->frontPageDetails( \Shared\Helpers\Helpers::get( 'id' ), $lang_id ?? '' ); \Shared\Helpers\Helpers::set_session( 'page', $page ); break; diff --git a/autoload/front/factory/class.Layouts.php b/autoload/front/factory/class.Layouts.php deleted file mode 100644 index 30f06a3..0000000 --- a/autoload/front/factory/class.Layouts.php +++ /dev/null @@ -1,172 +0,0 @@ - get( 'pp_layouts', 'id', [ 'categories_default' => 1 ] ); - } - - static public function default_layout() - { - global $mdb; - - $cacheHandler = new \Shared\Cache\CacheHandler(); - $cacheKey = "\front\factory\Layouts::default_layout"; - - $objectData = $cacheHandler -> get( $cacheKey ); - if ( $objectData ) - { - $cachedLayout = @unserialize( $objectData ); - if ( is_array( $cachedLayout ) and !empty( $cachedLayout ) ) - return $cachedLayout; - - $cacheHandler -> delete( $cacheKey ); - } - - $layout = $mdb -> get( 'pp_layouts', '*', [ 'status' => 1 ] ); - $cacheHandler -> set( $cacheKey, $layout ); - - return $layout; - } - - static public function product_layout( $product_id ) - { - global $mdb; - - $cacheHandler = new \Shared\Cache\CacheHandler(); - $cacheKey = "\front\factory\Layouts::product_layout:$product_id"; - - $objectData = $cacheHandler -> get( $cacheKey ); - if ( $objectData ) - { - $cachedLayout = @unserialize( $objectData ); - if ( is_array( $cachedLayout ) and !empty( $cachedLayout ) ) - return $cachedLayout; - - $cacheHandler -> delete( $cacheKey ); - } - - $layoutRows = $mdb -> query( - "SELECT pp_layouts.* - FROM pp_layouts - JOIN pp_shop_products ON pp_layouts.id = pp_shop_products.layout_id - WHERE pp_shop_products.id = " . (int)$product_id . " - ORDER BY pp_layouts.id DESC" - ) -> fetchAll( \PDO::FETCH_ASSOC ); - - if ( is_array( $layoutRows ) and isset( $layoutRows[0] ) ) - $layout = $layoutRows[0]; - else - { - $layoutRows = $mdb -> query( - "SELECT pp_layouts.* - FROM pp_layouts - JOIN pp_layouts_categories ON pp_layouts.id = pp_layouts_categories.layout_id - JOIN pp_shop_products_categories ON pp_shop_products_categories.category_id = pp_layouts_categories.category_id - WHERE pp_shop_products_categories.product_id = " . (int)$product_id . " - ORDER BY pp_shop_products_categories.o ASC, pp_layouts.id DESC" - ) -> fetchAll( \PDO::FETCH_ASSOC ); - - if ( is_array( $layoutRows ) and isset( $layoutRows[0] ) ) - $layout = $layoutRows[0]; - else - $layout = $mdb -> get( 'pp_layouts', '*', [ 'categories_default' => 1 ] ); - } - - if ( !$layout ) - $layout = $mdb -> get( 'pp_layouts', '*', [ 'status' => 1 ] ); - - $cacheHandler -> set( $cacheKey, $layout ); - - return $layout; - } - - static public function article_layout( $article_id ) - { - global $mdb; - - $cacheHandler = new \Shared\Cache\CacheHandler(); - $cacheKey = "\front\factory\Layouts::article_layout:$article_id"; - - $objectData = $cacheHandler -> get( $cacheKey ); - - if ( !$objectData ) - { - $layout = $mdb -> get( 'pp_layouts', [ '[><]pp_articles' => [ 'id' => 'layout_id' ] ], '*', [ 'pp_articles.id' => (int)$article_id ] ); - - $cacheHandler -> set( $cacheKey, $layout ); - } - else - { - return unserialize( $objectData ); - } - - return $layout; - } - - static public function category_layout( $category_id ) - { - global $mdb; - - $cacheHandler = new \Shared\Cache\CacheHandler(); - $cacheKey = "\front\factory\Layouts::category_layout:$category_id"; - - $objectData = $cacheHandler -> get( $cacheKey ); - if ( $objectData ) - { - $cachedLayout = @unserialize( $objectData ); - if ( is_array( $cachedLayout ) and !empty( $cachedLayout ) ) - return $cachedLayout; - - $cacheHandler -> delete( $cacheKey ); - } - - $layoutRows = $mdb -> query( - "SELECT pp_layouts.* - FROM pp_layouts - JOIN pp_layouts_categories ON pp_layouts.id = pp_layouts_categories.layout_id - WHERE pp_layouts_categories.category_id = " . (int)$category_id . " - ORDER BY pp_layouts.id DESC" - ) -> fetchAll( \PDO::FETCH_ASSOC ); - - if ( is_array( $layoutRows ) and isset( $layoutRows[0] ) ) - $layout = $layoutRows[0]; - else - $layout = $mdb -> get( 'pp_layouts', '*', [ 'categories_default' => 1 ] ); - - if ( !$layout ) - $layout = $mdb -> get( 'pp_layouts', '*', [ 'status' => 1 ] ); - - $cacheHandler -> set( $cacheKey, $layout ); - - return $layout; - } - - static public function active_layout( $page_id ) - { - global $mdb; - - $cacheHandler = new \Shared\Cache\CacheHandler(); - $cacheKey = "\front\factory\Layouts::active_layout:$page_id"; - - $objectData = $cacheHandler -> get( $cacheKey ); - - if ( !$objectData ) - { - $layout = $mdb -> get( 'pp_layouts', [ '[><]pp_layouts_pages' => [ 'id' => 'layout_id' ] ], '*', [ 'page_id' => (int)$page_id ] ); - - if ( !$layout ) - $layout = $mdb -> get( 'pp_layouts', '*', [ 'status' => 1 ] ); - - $cacheHandler -> set( $cacheKey, $layout ); - } - else - { - return unserialize( $objectData ); - } - - return $layout; - } -} diff --git a/autoload/front/factory/class.Menu.php b/autoload/front/factory/class.Menu.php deleted file mode 100644 index f1f8fb6..0000000 --- a/autoload/front/factory/class.Menu.php +++ /dev/null @@ -1,59 +0,0 @@ - get( $cacheKey ); - - if ( !$objectData ) - { - $menu = $mdb -> get( 'pp_menus', '*', [ 'id' => (int)$menu_id ] ); - $menu['pages'] = self::menu_pages( $menu_id ); - - $cacheHandler -> set( $cacheKey, $menu ); - } - else - { - return unserialize( $objectData ); - } - - return $menu; - } - - public static function menu_pages( $menu_id, $parent_id = null ) - { - global $mdb; - - $cacheHandler = new \Shared\Cache\CacheHandler(); - $cacheKey = "\front\factory\Menu::menu_pages:$menu_id:$parent_id"; - - $objectData = $cacheHandler->get($cacheKey); - - if ( !$objectData ) - { - $results = $mdb -> select( 'pp_pages', [ 'id' ], [ 'AND' => [ 'status' => 1, 'menu_id' => (int)$menu_id, 'parent_id' => $parent_id ], 'ORDER' => [ 'o' => 'ASC' ] ] ); - if ( is_array( $results ) ) foreach ( $results as $row ) - { - $page = \front\factory\Pages::page_details( $row['id'] ); - $page['pages'] = self::menu_pages( $menu_id, $row['id'] ); - - $pages[] = $page; - } - - $cacheHandler -> set( $cacheKey, $pages ); - } - else - { - return unserialize($objectData); - } - - return $pages; - } -} diff --git a/autoload/front/factory/class.Pages.php b/autoload/front/factory/class.Pages.php deleted file mode 100644 index e4484c7..0000000 --- a/autoload/front/factory/class.Pages.php +++ /dev/null @@ -1,92 +0,0 @@ - get( $cacheKey ); - - if ( !$objectData ) - { - $sort = $mdb -> get( 'pp_pages', 'sort_type', [ 'id' => $page_id ] ); - - $cacheHandler -> set( $cacheKey, $sort ); - } - else - { - return unserialize( $objectData ); - } - - return $sort; - } - - public static function lang_url( $page_id, $lang_id ) - { - $page = self::page_details( $page_id, $lang_id ); - - $page['language']['seo_link'] ? $url = '/' . $page['language']['seo_link'] : $url = '/s-' . $page['id'] . '-' . \Shared\Helpers\Helpers::seo( $page['language']['title'] ); - - if ( $lang_id != ( new \Domain\Languages\LanguagesRepository( $GLOBALS['mdb'] ) )->defaultLanguage() and $url != '#' ) - $url = '/' . $lang_id . $url; - - return $url; - } - - public static function page_details( $id = '', $lang_tmp = '' ) - { - global $mdb, $lang_id; - - if ( !$id ) - $id = self::main_page_id(); - - if ( $lang_tmp ) - $lang_id = $lang_tmp; - - $cacheHandler = new \Shared\Cache\CacheHandler(); - $cacheKey = "\front\factory\Pages::page_details:$id:$lang_id"; - - $objectData = $cacheHandler->get($cacheKey); - - if ( !$objectData ) { - $page = $mdb->get('pp_pages', '*', ['id' => (int)$id]); - $page['language'] = $mdb->get('pp_pages_langs', '*', ['AND' => ['page_id' => (int)$id, 'lang_id' => $lang_id]]); - - $cacheHandler->set($cacheKey, $page); - } else { - return unserialize($objectData); - } - - return $page; - } - - public static function main_page_id() - { - global $mdb; - - $cacheHandler = new \Shared\Cache\CacheHandler(); - $cacheKey = "\front\factory\Pages::main_page_id"; - - $objectData = $cacheHandler->get($cacheKey); - - if ( !$objectData ) - { - $id = $mdb -> get( 'pp_pages', 'id', [ 'AND' => [ 'status' => 1, 'start' => 1 ] ] ); - if ( !$id ) - $id = $mdb -> get( 'pp_pages', 'id', [ 'status' => 1, 'ORDER' => [ 'menu_id' => 'ASC', 'o' => 'ASC' ], 'LIMIT' => 1 ] ); - - $cacheHandler -> set( $cacheKey, $id ); - } - else - { - return unserialize($objectData); - } - - return $id; - } -} diff --git a/autoload/front/view/class.Menu.php b/autoload/front/view/class.Menu.php deleted file mode 100644 index bedb43f..0000000 --- a/autoload/front/view/class.Menu.php +++ /dev/null @@ -1,22 +0,0 @@ - pages = $pages; - $tpl -> level = $level; - $tpl -> current_page = $current_page; - return $tpl -> render( 'menu/pages' ); - } - - public static function menu( $menu, $current_page ) - { - $tpl = new \Shared\Tpl\Tpl; - $tpl -> menu = $menu; - $tpl -> current_page = $current_page; - return $tpl -> render( 'menu/menu' ); - } -} diff --git a/autoload/front/view/class.Site.php b/autoload/front/view/class.Site.php index 9403f85..3b070e1 100644 --- a/autoload/front/view/class.Site.php +++ b/autoload/front/view/class.Site.php @@ -24,24 +24,26 @@ class Site $articleRepo = new \Domain\Article\ArticleRepository( $GLOBALS['mdb'] ); $bannerRepo = new \Domain\Banner\BannerRepository( $GLOBALS['mdb'] ); + $layoutsRepo = new \Domain\Layouts\LayoutsRepository( $GLOBALS['mdb'] ); + $pagesRepo = new \Domain\Pages\PagesRepository( $GLOBALS['mdb'] ); if ( (int) \Shared\Helpers\Helpers::get( 'layout_id' ) ) $layout = new \cms\Layout( (int) \Shared\Helpers\Helpers::get( 'layout_id' ) ); if ( \Shared\Helpers\Helpers::get( 'article' ) ) - $layout = \front\factory\Layouts::article_layout( \Shared\Helpers\Helpers::get( 'article' ) ); + $layout = $layoutsRepo->getArticleLayout( (int) \Shared\Helpers\Helpers::get( 'article' ) ); if ( \Shared\Helpers\Helpers::get( 'product' ) ) - $layout = \front\factory\Layouts::product_layout( \Shared\Helpers\Helpers::get( 'product' ) ); + $layout = $layoutsRepo->getProductLayout( (int) \Shared\Helpers\Helpers::get( 'product' ) ); if ( \Shared\Helpers\Helpers::get( 'category' ) ) - $layout = \front\factory\Layouts::category_layout( \Shared\Helpers\Helpers::get( 'category' ) ); + $layout = $layoutsRepo->getCategoryLayout( (int) \Shared\Helpers\Helpers::get( 'category' ) ); if ( !$layout and \Shared\Helpers\Helpers::get( 'module' ) ) - $layout = \front\factory\Layouts::default_layout(); + $layout = $layoutsRepo->getDefaultLayout(); if ( !$layout ) - $layout = \front\factory\Layouts::active_layout( $page['id'] ); + $layout = $layoutsRepo->getActiveLayout( $page['id'] ); if ( $settings['devel'] == true and file_exists( 'devel.html' ) ) $html = file_get_contents( 'devel.html' ); @@ -120,7 +122,7 @@ class Site if ( is_array( $menu[0] ) ) foreach( $menu[0] as $menu_tmp ) { $menu_tmp = explode( ':', $menu_tmp ); - $html = str_replace( '[MENU:' . $menu_tmp[1] . ']', \front\view\Menu::menu( \front\factory\Menu::menu_details( $menu_tmp[1] ), $page['id'] ), $html ); + $html = str_replace( '[MENU:' . $menu_tmp[1] . ']', \front\Views\Menu::menu( $pagesRepo->frontMenuDetails( (int) $menu_tmp[1], $lang_id ), $page['id'] ), $html ); } preg_match_all( self::menu_main_pattern, $html, $menu ); @@ -130,7 +132,7 @@ class Site $html = str_replace( '[MENU_GLOWNE:' . $menu_tmp[1] . ']', \Shared\Tpl\Tpl::view( 'menu/main-menu', [ - 'menu' => \front\factory\Menu::menu_details( $menu_tmp[1] ) + 'menu' => $pagesRepo->frontMenuDetails( (int) $menu_tmp[1], $lang_id ) ] ), $html ); } diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index 694ca11..f291750 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -4,6 +4,30 @@ Logi zmian z migracji na Domain-Driven Architecture. Najnowsze na gorze. --- +## ver. 0.286 (2026-02-17) - Layouts, Menu, Pages frontend migration + +- **Layouts (frontend)** — migracja na Domain + - NOWE METODY w `LayoutsRepository`: `categoryDefaultLayoutId()`, `getDefaultLayout()`, `getProductLayout()`, `getArticleLayout()`, `getCategoryLayout()`, `getActiveLayout()` — z Redis cache, 3-level fallback (product→category→default) + - USUNIETA: `front\factory\class.Layouts.php` — logika przeniesiona do `LayoutsRepository` + - UPDATE: `front\view\Site::show()` — przepiecie na `$layoutsRepo` + - UPDATE: `Shared\Helpers\Helpers::htacces()` — optymalizacja z 3 wywolan `category_default_layout()` do jednej zmiennej +- **Menu + Pages (frontend)** — migracja na Domain + Views + - NOWE METODY w `PagesRepository`: `frontPageDetails()`, `frontPageSort()`, `frontMainPageId()`, `frontLangUrl()`, `frontMenuDetails()`, `frontMenuPages()` — z Redis cache, rekurencja stron + - NOWY: `front\Views\Menu` — czysty VIEW (`pages()`, `menu()`) + - USUNIETA: `front\factory\class.Menu.php` — logika przeniesiona do `PagesRepository` + - USUNIETA: `front\factory\class.Pages.php` — logika przeniesiona do `PagesRepository` + - USUNIETA: `front\view\class.Menu.php` — zastapiona przez `front\Views\Menu` + - USUNIETA: `templates\menu\submenu.php` — martwy kod (wola nieistniejaca metode `Menu::submenu()`) + - UPDATE: `front\controls\Site::check_url_params()` — przepiecie na `$pagesRepo->frontPageDetails()` + - UPDATE: `index.php` — przepiecie na `$pagesRepo->frontPageDetails()` + - UPDATE: `templates/site/languages.php` — przepiecie na `$pagesRepo->frontLangUrl()` + - UPDATE: `templates/menu/menu.php`, `pages.php`, `main-menu.php` — przepiecie na `\front\Views\Menu::` + - FIX: `frontPageDetails()` — usuniety type hint `string` z `$langId` + cast `(string)` (null $lang_id przy wczesnym wywolaniu `check_url_params()`) + - FIX: `front\controls\class.Site.php` — dodano `$lang_id ?? ''` przy przekazywaniu do `frontPageDetails()` +- Testy: 470 OK, 1484 asercji (+16 testow: 8 LayoutsRepository frontend, 8 PagesRepository frontend) + +--- + ## ver. 0.285 (2026-02-17) - Tpl namespace, CurlServer removal, thumb.php fix - **Shared\Tpl\Tpl** — migracja silnika szablonow do namespace Shared @@ -653,4 +677,4 @@ Logi zmian z migracji na Domain-Driven Architecture. Najnowsze na gorze. - Metoda `clear_product_cache()` w klasie S --- -*Dokument aktualizowany: 2026-02-14* +*Dokument aktualizowany: 2026-02-17* diff --git a/docs/FRONTEND_REFACTORING_PLAN.md b/docs/FRONTEND_REFACTORING_PLAN.md index 6618c7f..a45f6e4 100644 --- a/docs/FRONTEND_REFACTORING_PLAN.md +++ b/docs/FRONTEND_REFACTORING_PLAN.md @@ -39,10 +39,10 @@ Panel administratora (33 moduły) został w pełni zmigrowany na architekturę D | Newsletter | ZMIGROWANA (Domain) — usunięta | — | | Settings | Fasada (BUG: get_single_settings_value ignoruje $param) | NISKI | | Languages | USUNIĘTA — przepięta na Domain | — | -| Layouts | Fasada | NISKI | +| Layouts | USUNIETA — przepieta na Domain | — | | Banners | USUNIETA — przepieta na Domain | — | -| Menu | Fasada | NISKI | -| Pages | Fasada | NISKI | +| Menu | USUNIETA — przepieta na Domain | — | +| Pages | USUNIETA — przepieta na Domain | — | | ShopAttribute | Fasada | NISKI | | ShopCoupon | Model danych | NISKI | @@ -51,7 +51,8 @@ Panel administratora (33 moduły) został w pełni zmigrowany na architekturę D |-------|--------| | Site | KRYTYCZNY — show() ~600 linii, pattern substitution engine | | ShopCategory | VIEW z logiką routingu (infinite scroll vs pagination) | -| Articles, Menu, Scontainers | Czyste VIEW | +| Articles, Scontainers | Czyste VIEW | +| Menu | PRZENIESIONA do `front\Views\Menu` | | Banners | PRZENIESIONA do `front\Views\Banners` | | Languages, Newsletter | PRZENIESIONE do `front\Views\` (nowy namespace) | | ShopClient, ShopOrder, ShopPaymentMethod | Czyste VIEW | @@ -266,20 +267,36 @@ Legacy Cleanup --- -### Etap: Menu, Pages, Layouts Frontend Services +### Etap: Menu, Pages, Layouts Frontend Services — ZREALIZOWANY **Cel:** Migracja pozostałych fabryk "liściowych". +**UWAGA:** Zamiast tworzenia osobnych FrontendService, metody dodano do istniejących repozytoriów Domain (zgodnie z wzorcem projektu). + +**DODANE METODY (do istniejących klas):** +- `Domain/Layouts/LayoutsRepository` — `categoryDefaultLayoutId()`, `getDefaultLayout()`, `getProductLayout()`, `getArticleLayout()`, `getCategoryLayout()`, `getActiveLayout()` (Redis cache, 3-level fallback) +- `Domain/Pages/PagesRepository` — `frontPageDetails()`, `frontPageSort()`, `frontMainPageId()`, `frontLangUrl()`, `frontMenuDetails()`, `frontMenuPages()` (Redis cache, rekurencja) +- Testy: +8 w `LayoutsRepositoryTest`, +8 w `PagesRepositoryTest` + **NOWE:** -- `Domain/Menu/MenuFrontendService.php` — `menuDetails()`, `menuPages()` (rekurencja) -- `Domain/Pages/PagesFrontendService.php` — `pageDetails()`, `mainPageId()`, `langUrl()`, `pageSort()` -- `Domain/Layouts/LayoutsFrontendService.php` — `activeLayout()`, `articleLayout()`, `productLayout()`, `categoryLayout()`, `defaultLayout()`, `categoryDefaultLayout()` -- Testy: 3 pliki testowe +- `front\Views\Menu` — czysty VIEW (`pages()`, `menu()`) **ZMIANA:** -- `front/factory/Menu`, `Pages`, `Layouts` → fasady +- `front/factory/Layouts` → USUNIETA (logika w `LayoutsRepository`) +- `front/factory/Menu` → USUNIETA (logika w `PagesRepository`) +- `front/factory/Pages` → USUNIETA (logika w `PagesRepository`) +- `front/view/Menu` → USUNIETA (zastapiona przez `front\Views\Menu`) +- `templates/menu/submenu.php` → USUNIETA (martwy kod) +- `front\view\Site::show()` — przepiecie na `$layoutsRepo` + `$pagesRepo` +- `front\controls\Site::check_url_params()` — przepiecie na `$pagesRepo->frontPageDetails()` +- `index.php` — przepiecie na `$pagesRepo->frontPageDetails()` +- `Shared\Helpers\Helpers::htacces()` — optymalizacja 3→1 wywolan +- Szablony `templates/menu/*` — przepiecie na `\front\Views\Menu::` +- `templates/site/languages.php` — przepiecie na `$pagesRepo->frontLangUrl()` -**BUG FIX:** `cms\Layout::__get()` — poprawka referencji do `$this->data` +**BUG FIX:** `frontPageDetails()` — null `$lang_id` przy wczesnym `check_url_params()` (usuniety string type hint + cast + `?? ''` na call site) + +**Testy:** 470 OK, 1484 asercji --- @@ -522,7 +539,7 @@ front\factory\ShopPromotion::promotion_type_XX() → shop\Product::is_product_on |------|--------|-----------|-------------------|-------| | Settings + Languages | Fundamenty | FUNDAMENT | 2 serwisy | 2 | | Category Frontend | Kategorie | WYSOKI | 1 serwis | 1 | -| Banners/Menu/Pages/Articles/Layouts | Treści | ŚREDNI | 5 serwisów | 5 | +| ~~Banners/Menu/Pages/Articles/Layouts~~ | ~~Treści~~ | ZREALIZOWANY | — | — | | Promotion Engine | Promocje | KRYTYCZNY | 1 serwis | 1 | | Product Frontend | Produkty | KRYTYCZNY | 1 serwis | 1 | | Client/Auth (security fix) | Klienci | KRYTYCZNY | 1 serwis | 1 | diff --git a/docs/PROJECT_STRUCTURE.md b/docs/PROJECT_STRUCTURE.md index dab1c1e..f0b12e7 100644 --- a/docs/PROJECT_STRUCTURE.md +++ b/docs/PROJECT_STRUCTURE.md @@ -109,7 +109,7 @@ shopPRO/ │ │ └── Tpl/ # Tpl (silnik szablonow) │ ├── front/ # Klasy frontendu │ │ ├── Controllers/ # Nowe kontrolery DI (Newsletter) -│ │ ├── Views/ # Nowe widoki (Newsletter, Articles, Languages, Banners) +│ │ ├── Views/ # Nowe widoki (Newsletter, Articles, Languages, Banners, Menu) │ │ ├── controls/ # Kontrolery legacy (Site, ShopBasket, ...) │ │ ├── view/ # Widoki legacy (Site, ...) │ │ └── factory/ # Fabryki/helpery (fasady) @@ -243,7 +243,7 @@ autoload/ │ └── view/ # Widoki (statyczne - bez zmian) ├── front/ │ ├── Controllers/ # Nowe kontrolery frontendowe (namespace \front\Controllers\) z DI -│ ├── Views/ # Nowe widoki (namespace \front\Views\) — czyste VIEW, statyczne +│ ├── Views/ # Nowe widoki (namespace \front\Views\) — czyste VIEW, statyczne (Menu, Newsletter, Articles, Languages, Banners) │ ├── controls/ # Legacy kontrolery (fallback) │ ├── factory/ # Legacy helpery (stopniowo migrowane) │ └── view/ # Legacy widoki @@ -423,6 +423,16 @@ Pelna dokumentacja testow: `TESTING.md` - NOWY: `tests/stubs/Helpers.php` — stub klasy Helpers dla testow. - USUNIETA: `autoload/class.S.php` — zastapiona przez `Shared\Helpers\Helpers`. +## Aktualizacja 2026-02-17 (ver. 0.286) - Layouts, Menu, Pages frontend migration +- NOWE METODY w `Domain/Layouts/LayoutsRepository.php`: `categoryDefaultLayoutId()`, `getDefaultLayout()`, `getProductLayout()`, `getArticleLayout()`, `getCategoryLayout()`, `getActiveLayout()`. +- NOWE METODY w `Domain/Pages/PagesRepository.php`: `frontPageDetails()`, `frontPageSort()`, `frontMainPageId()`, `frontLangUrl()`, `frontMenuDetails()`, `frontMenuPages()`. +- NOWY: `front\Views\Menu` — czysty VIEW (`pages()`, `menu()`). +- USUNIETA: `front\factory\class.Layouts.php` — logika przeniesiona do `LayoutsRepository`. +- USUNIETA: `front\factory\class.Menu.php` — logika przeniesiona do `PagesRepository`. +- USUNIETA: `front\factory\class.Pages.php` — logika przeniesiona do `PagesRepository`. +- USUNIETA: `front\view\class.Menu.php` — zastapiona przez `front\Views\Menu`. +- USUNIETA: `templates\menu\submenu.php` — martwy kod. + ## Aktualizacja 2026-02-17 - Tpl namespace, CurlServer removal, thumb.php fix - NOWY: `autoload/Shared/Tpl/Tpl.php` — silnik szablonow w namespace `Shared\Tpl`. - USUNIETA: `autoload/class.Tpl.php` — zastapiona przez `Shared\Tpl\Tpl`. @@ -432,4 +442,4 @@ Pelna dokumentacja testow: `TESTING.md` - FIX: `Tpl::render()` branch 3 — sprawdzal `../templates_user/` ale ladowal `../templates/`. --- -*Dokument aktualizowany: 2026-02-17* +*Dokument aktualizowany: 2026-02-17 (ver. 0.286)* diff --git a/docs/TESTING.md b/docs/TESTING.md index a32606b..6b8f839 100644 --- a/docs/TESTING.md +++ b/docs/TESTING.md @@ -33,10 +33,17 @@ Alternatywnie (Git Bash): ## Aktualny stan suite -Ostatnio zweryfikowano: 2026-02-16 +Ostatnio zweryfikowano: 2026-02-17 ```text -OK (454 tests, 1449 assertions) +OK (470 tests, 1484 assertions) +``` + +Aktualizacja po migracji Layouts + Menu/Pages frontend (2026-02-17, ver. 0.286): +```text +Pelny suite: OK (470 tests, 1484 assertions) +Nowe testy: LayoutsRepositoryTest (+8: categoryDefaultLayoutId, getDefaultLayout, getProductLayout fallback, getArticleLayout, getCategoryLayout fallback, getActiveLayout, getActiveLayout fallback, getActiveLayout null) +Nowe testy: PagesRepositoryTest (+8: frontPageDetails, frontPageDetailsNull, frontMainPageId, frontMainPageIdFallback, frontPageSort, frontMenuDetails, frontMenuDetailsNull, frontMenuPages) ``` Aktualizacja po migracji Banners frontend (2026-02-16, ver. 0.281): @@ -505,3 +512,14 @@ OK (351 tests, 1091 assertions) Nowe testy dodane 2026-02-15: - `tests/Unit/Domain/Product/ProductRepositoryTest.php` (rozszerzenie: `allProductsForMassEdit`, `getProductsByCategory`, `applyDiscountPercent`) - `tests/Unit/admin/Controllers/ShopProductControllerTest.php` (7 testow: kontrakty metod, return types, DI konstruktora) + +## Aktualizacja suite (Layouts + Menu/Pages frontend, ver. 0.286) +Ostatnio zweryfikowano: 2026-02-17 + +```text +OK (470 tests, 1484 assertions) +``` + +Nowe testy dodane 2026-02-17: +- `tests/Unit/Domain/Layouts/LayoutsRepositoryTest.php` (rozszerzenie: +8 testow frontend: categoryDefaultLayoutId, getDefaultLayout, getProductLayout, getArticleLayout, getCategoryLayout, getActiveLayout) +- `tests/Unit/Domain/Pages/PagesRepositoryTest.php` (rozszerzenie: +8 testow frontend: frontPageDetails, frontMainPageId, frontPageSort, frontLangUrl, frontMenuDetails, frontMenuPages) diff --git a/docs/UPDATE_INSTRUCTIONS.md b/docs/UPDATE_INSTRUCTIONS.md index ff3c65a..d776f51 100644 --- a/docs/UPDATE_INSTRUCTIONS.md +++ b/docs/UPDATE_INSTRUCTIONS.md @@ -18,16 +18,16 @@ Aktualizacje znajdują się w folderze `updates/0.XX/` gdzie XX oznacza dziesią ## Procedura tworzenia nowej aktualizacji -## Status biezacej aktualizacji (ver. 0.285) +## Status biezacej aktualizacji (ver. 0.286) -- Wersja udostepniona: `0.285` (data: 2026-02-17). +- Wersja udostepniona: `0.286` (data: 2026-02-17). - Pliki publikacyjne: - - `updates/0.20/ver_0.285.zip`, `ver_0.285_files.txt` + - `updates/0.20/ver_0.286.zip`, `ver_0.286_files.txt` - Pliki metadanych aktualizacji: - - `updates/changelog.php` (dodany wpis `ver. 0.285`) - - `updates/versions.php` (`$current_ver = 285`) + - `updates/changelog.php` (dodany wpis `ver. 0.286`) + - `updates/versions.php` (`$current_ver = 286`) - Weryfikacja testow przed publikacja: - - `OK (454 tests, 1449 assertions)` + - `OK (470 tests, 1484 assertions)` ### 1. Określ numer wersji Sprawdź ostatnią wersję w `updates/` i zwiększ o 1. diff --git a/index.php b/index.php index 82ffcae..a3b8b23 100644 --- a/index.php +++ b/index.php @@ -132,9 +132,11 @@ if ($request_uri != '') } } +$pagesRepo = new \Domain\Pages\PagesRepository( $mdb ); + if ( \Shared\Helpers\Helpers::get( 'a' ) == 'page' and \Shared\Helpers\Helpers::get( 'id' ) ) { - $page = \front\factory\Pages::page_details( \Shared\Helpers\Helpers::get( 'id' ) ); + $page = $pagesRepo->frontPageDetails( \Shared\Helpers\Helpers::get( 'id' ), $lang_id ); \Shared\Helpers\Helpers::set_session( 'page', $page ); } @@ -145,7 +147,7 @@ if ( !is_array( $page ) or !(int)$page['id'] ) if ( !is_array( $page ) or !(int)$page['id'] ) { - $page = \front\factory\Pages::page_details(); + $page = $pagesRepo->frontPageDetails( '', $lang_id ); \Shared\Helpers\Helpers::set_session( 'page', $page ); } diff --git a/templates/menu/main-menu.php b/templates/menu/main-menu.php index f015fa5..000881a 100644 --- a/templates/menu/main-menu.php +++ b/templates/menu/main-menu.php @@ -3,7 +3,7 @@
diff --git a/templates/menu/menu.php b/templates/menu/menu.php index 31f1726..3c6ee50 100644 --- a/templates/menu/menu.php +++ b/templates/menu/menu.php @@ -1,5 +1,5 @@ \ No newline at end of file diff --git a/templates/menu/pages.php b/templates/menu/pages.php index ce56f84..1311385 100644 --- a/templates/menu/pages.php +++ b/templates/menu/pages.php @@ -47,7 +47,7 @@ if ( is_array( $this -> pages ) ) { echo ''; if ( is_array( $page['pages'] ) ) echo ''; - echo \front\view\Menu::pages( $page['pages'], $this -> level + 1, $this -> current_page ); + echo \front\Views\Menu::pages( $page['pages'], $this -> level + 1, $this -> current_page ); echo ''; } echo ''; diff --git a/templates/menu/submenu.php b/templates/menu/submenu.php deleted file mode 100644 index f1b3a16..0000000 --- a/templates/menu/submenu.php +++ /dev/null @@ -1,26 +0,0 @@ - -if ( is_array( $this -> pages ) ) -{ - - echo ''; -} \ No newline at end of file diff --git a/templates/site/languages.php b/templates/site/languages.php index dc443f1..b1eaa2a 100644 --- a/templates/site/languages.php +++ b/templates/site/languages.php @@ -7,7 +7,7 @@