db = $db; } public function saveArticlesOrder( $pageId, $articles ): bool { if ( is_array( $articles ) ) { $this->db->update( 'pp_articles_pages', [ 'o' => 0 ], [ 'page_id' => (int) $pageId ] ); $x = 0; for ( $i = 0; $i < count( $articles ); $i++ ) { if ( $articles[$i]['item_id'] ) { $x++; $this->db->update( 'pp_articles_pages', [ 'o' => $x ], [ 'AND' => [ 'page_id' => (int) $pageId, 'article_id' => $articles[$i]['item_id'] ] ] ); } } } return true; } public function pageArticles( $pageId ) { $results = $this->db->query( 'SELECT article_id, o, status FROM pp_articles_pages AS ap INNER JOIN pp_articles AS a ON a.id = ap.article_id WHERE page_id = ' . (int) $pageId . ' AND status != -1 ORDER BY o ASC' )->fetchAll(); $articles = []; if ( is_array( $results ) ) foreach ( $results as $row ) { $row['title'] = \admin\factory\Articles::article_title( $row['article_id'] ); $articles[] = $row; } return $articles; } public function menusList() { return $this->db->select( 'pp_menus', '*', [ 'ORDER' => [ 'name' => 'ASC' ] ] ); } public function savePagesOrder( $menuId, $pages ): bool { if ( is_array( $pages ) ) { $this->db->update( 'pp_pages', [ 'o' => 0 ], [ 'menu_id' => (int) $menuId ] ); $x = 0; for ( $i = 0; $i < count( $pages ); $i++ ) { if ( $pages[$i]['item_id'] ) { $parentId = $pages[$i]['parent_id'] ? $pages[$i]['parent_id'] : 0; if ( $pages[$i]['item_id'] && $pages[$i]['depth'] > 1 ) { if ( $pages[$i]['depth'] == 2 ) $parentId = null; $x++; $this->db->update( 'pp_pages', [ 'o' => $x, 'parent_id' => $parentId ], [ 'id' => (int) $pages[$i]['item_id'] ] ); } } } } \S::delete_cache(); return true; } public function pageDelete( $pageId ): bool { if ( $this->db->count( 'pp_pages', [ 'parent_id' => (int) $pageId ] ) ) return false; if ( $this->db->delete( 'pp_pages', [ 'id' => (int) $pageId ] ) ) { \S::delete_cache(); \S::htacces(); return true; } return false; } public function maxOrder(): int { return (int) $this->db->max( 'pp_pages', 'o' ); } public function updateSubpagesMenuId( int $parentId, int $menuId ): void { $this->updateSubpagesMenuIdRecursive( $parentId, $menuId ); } public function generateSeoLink( $title, $pageId, $articleId, $lang, $pid ) { $seoLink = \S::seo( $title ); $seoLinkCheck = false; $i = 0; while ( !$seoLinkCheck ) { if ( $this->db->count( 'pp_pages_langs', [ 'AND' => [ 'seo_link' => $seoLink, 'page_id[!]' => (int) $pageId ] ] ) ) $seoLink = $seoLink . '-' . ( ++$i ); else $seoLinkCheck = true; } $seoLinkCheck = false; while ( !$seoLinkCheck ) { if ( $this->db->count( 'pp_articles_langs', [ 'AND' => [ 'seo_link' => $seoLink, 'article_id[!]' => (int) $articleId ] ] ) ) $seoLink = $seoLink . '-' . ( ++$i ); else $seoLinkCheck = true; } return $seoLink; } public function googleUrlPreview( $pageId, $title, $lang, $pid, $id, $seoLink, $languageLink = '' ) { $prefix = $languageLink; $status = true; $idPage = $pageId; $seo = ''; do { if ( $pageId ) { $parent = $this->pageDetails( $pageId ); $parentId = $parent['parent_id']; } else $parentId = $pid; if ( $parentId ) { $results = $this->db->query( "SELECT title, seo_link, page_id FROM pp_pages_langs AS ppl, pp_langs AS pl WHERE lang_id = pl.id AND page_id = " . (int) $parentId . " AND ppl.lang_id = '" . $lang . "' " )->fetchAll(); if ( $results[0]['seo_link'] ) $seo = $results[0]['seo_link'] . '/' . $seo; else $seo = 's-' . $results[0]['page_id'] . '-' . \S::seo( $results[0]['title'] ) . '/' . $seo; $pageId = $results[0]['page_id']; } else $status = false; } while ( $status ); if ( $id ) { if ( !$seoLink ) $seo = $seo . 's-' . $id . '-' . \S::seo( $title ); else $seo = $seo . $seoLink; } else { if ( !$seoLink ) $seo = $seo . 's-' . $idPage . '-' . \S::seo( $title ); else $seo = $seo . $seoLink; } if ( $prefix ) $seo = $prefix . $seo; return $seo; } public function menuDelete( $menuId ) { if ( $this->db->count( 'pp_pages', [ 'menu_id' => (int) $menuId ] ) ) return false; return $this->db->delete( 'pp_menus', [ 'id' => (int) $menuId ] ); } public function menuDetails( $menuId ) { return $this->db->get( 'pp_menus', '*', [ 'id' => (int) $menuId ] ); } public function menuSave( $menuId, $name, $status ) { $status == 'on' ? $status = 1 : $status = 0; if ( !$menuId ) { return $this->db->insert( 'pp_menus', [ 'name' => $name, 'status' => $status ] ); } else { $this->db->update( 'pp_menus', [ 'name' => $name, 'status' => $status ], [ 'id' => (int) $menuId ] ); return true; } return false; } public function menuLists() { return $this->db->select( 'pp_menus', '*', [ 'ORDER' => [ 'id' => 'ASC' ] ] ); } public function pageDetails( $pageId ) { $page = $this->db->get( 'pp_pages', '*', [ 'id' => (int) $pageId ] ); $results = $this->db->select( 'pp_pages_langs', '*', [ 'page_id' => (int) $pageId ] ); if ( is_array( $results ) ) foreach ( $results as $row ) $page['languages'][$row['lang_id']] = $row; $page['layout_id'] = $this->db->get( 'pp_layouts_pages', 'layout_id', [ 'page_id' => (int) $pageId ] ); return $page; } public function pageUrl( $pageId ) { $results = $this->db->query( "SELECT seo_link, title lang_id FROM pp_pages_langs AS ppl, pp_langs AS pl WHERE lang_id = pl.id AND page_id = " . (int) $pageId . " AND seo_link != '' ORDER BY o ASC LIMIT 1" )->fetchAll(); if ( !$results[0]['seo_link'] ) { $title = $this->pageTitle( $article_id ); return 's-' . $pageId . '-' . \S::seo( $title ); } else return $results[0]['seo_link']; } public function pageTitle( $pageId ) { $result = $this->db->select( 'pp_pages_langs', [ '[><]pp_langs' => [ 'lang_id' => 'id' ] ], 'title', [ 'AND' => [ 'page_id' => (int) $pageId, 'title[!]' => '' ], 'ORDER' => [ 'o' => 'ASC' ], 'LIMIT' => 1 ] ); return $result[0]; } public function pageLanguages( $pageId ) { return $this->db->select( 'pp_pages_langs', '*', [ 'AND' => [ 'page_id' => (int) $pageId, 'title[!]' => null ] ] ); } public function menuPages( $menuId, $parentId = null ) { $results = $this->db->select( 'pp_pages', [ 'id', 'menu_id', 'status', 'parent_id', 'start' ], [ 'AND' => [ 'menu_id' => $menuId, 'parent_id' => $parentId ], 'ORDER' => [ 'o' => 'ASC' ] ] ); if ( !is_array( $results ) || !count( $results ) ) return null; foreach ( $results as $row ) { $row['title'] = $this->pageTitle( $row['id'] ); $row['languages'] = $this->pageLanguages( $row['id'] ); $row['subpages'] = $this->menuPages( $menuId, $row['id'] ); $pages[] = $row; } return $pages; } public function pageSave( $pageId, $title, $seoLink, $metaTitle, $metaDescription, $metaKeywords, $menuId, $parentId, $pageType, $sortType, $layoutId, $articlesLimit, $showTitle, $status, $link, $noindex, $start, $siteTitle, $blockDirectAccess, $cache, $canonical ) { $parentId = $parentId ? $parentId : null; if ( !$pageId ) return $this->createPage( $title, $seoLink, $metaTitle, $metaDescription, $metaKeywords, $menuId, $parentId, $pageType, $sortType, $layoutId, $articlesLimit, $showTitle, $status, $link, $noindex, $start, $siteTitle, $blockDirectAccess, $cache, $canonical ); return $this->updatePage( $pageId, $title, $seoLink, $metaTitle, $metaDescription, $metaKeywords, $menuId, $parentId, $pageType, $sortType, $layoutId, $articlesLimit, $showTitle, $status, $link, $noindex, $start, $siteTitle, $blockDirectAccess, $cache, $canonical ); } private function createPage( $title, $seoLink, $metaTitle, $metaDescription, $metaKeywords, $menuId, $parentId, $pageType, $sortType, $layoutId, $articlesLimit, $showTitle, $status, $link, $noindex, $start, $siteTitle, $blockDirectAccess, $cache, $canonical ) { $order = $this->maxOrder() + 1; $this->db->insert( 'pp_pages', [ 'menu_id' => (int) $menuId, 'page_type' => $pageType, 'sort_type' => $sortType, 'articles_limit' => $articlesLimit, 'show_title' => $showTitle == 'on' ? 1 : 0, 'status' => $status == 'on' ? 1 : 0, 'o' => (int) $order, 'parent_id' => $parentId, 'start' => $start == 'on' ? 1 : 0, 'cache' => $cache == 'on' ? 1 : 0, ] ); $id = $this->db->id(); if ( !$id ) return false; if ( $start ) $this->db->update( 'pp_pages', [ 'start' => 0 ], [ 'id[!]' => (int) $id ] ); if ( $layoutId ) $this->db->insert( 'pp_layouts_pages', [ 'page_id' => (int) $id, 'layout_id' => (int) $layoutId ] ); $languages = $this->activeLanguages(); $this->savePageLanguages( (int) $id, $languages, $title, $metaDescription, $metaKeywords, $metaTitle, $seoLink, $noindex, $siteTitle, $link, $blockDirectAccess, $canonical ); \S::htacces(); \S::delete_cache(); return $id; } private function updatePage( $pageId, $title, $seoLink, $metaTitle, $metaDescription, $metaKeywords, $menuId, $parentId, $pageType, $sortType, $layoutId, $articlesLimit, $showTitle, $status, $link, $noindex, $start, $siteTitle, $blockDirectAccess, $cache, $canonical ) { $this->db->update( 'pp_pages', [ 'menu_id' => (int) $menuId, 'page_type' => $pageType, 'sort_type' => $sortType, 'articles_limit' => $articlesLimit, 'show_title' => $showTitle == 'on' ? 1 : 0, 'status' => $status == 'on' ? 1 : 0, 'parent_id' => $parentId, 'start' => $start == 'on' ? 1 : 0, 'cache' => $cache == 'on' ? 1 : 0, ], [ 'id' => (int) $pageId ] ); if ( $layoutId ) { $this->db->delete( 'pp_layouts_pages', [ 'page_id' => (int) $pageId ] ); $this->db->insert( 'pp_layouts_pages', [ 'layout_id' => (int) $layoutId, 'page_id' => (int) $pageId ] ); } if ( $start ) $this->db->update( 'pp_pages', [ 'start' => 0 ], [ 'id[!]' => (int) $pageId ] ); $this->db->delete( 'pp_pages_langs', [ 'page_id' => (int) $pageId ] ); $languages = $this->activeLanguages(); $this->savePageLanguages( (int) $pageId, $languages, $title, $metaDescription, $metaKeywords, $metaTitle, $seoLink, $noindex, $siteTitle, $link, $blockDirectAccess, $canonical ); $this->updateSubpagesMenuIdRecursive( (int) $pageId, (int) $menuId ); \S::htacces(); \S::delete_cache(); return $pageId; } private function activeLanguages(): array { return $this->db->select( 'pp_langs', [ 'id' ], [ 'status' => 1, 'ORDER' => [ 'o' => 'ASC' ] ] ) ?: []; } private function savePageLanguages( int $pageId, array $languages, $title, $metaDescription, $metaKeywords, $metaTitle, $seoLink, $noindex, $siteTitle, $link, $blockDirectAccess, $canonical ): void { $isMulti = count( $languages ) > 1; foreach ( $languages as $i => $row ) { $titleValue = $this->languageValue( $title, $i, $isMulti ); $metaDescriptionValue = $this->languageValue( $metaDescription, $i, $isMulti ); $metaKeywordsValue = $this->languageValue( $metaKeywords, $i, $isMulti ); $metaTitleValue = $this->languageValue( $metaTitle, $i, $isMulti ); $seoLinkValue = $this->languageValue( $seoLink, $i, $isMulti ); $noindexValue = $this->languageValue( $noindex, $i, $isMulti ); $siteTitleValue = $this->languageValue( $siteTitle, $i, $isMulti ); $linkValue = $this->languageValue( $link, $i, $isMulti ); $blockDirectAccessValue = $this->languageValue( $blockDirectAccess, $i, $isMulti ); $canonicalValue = $this->languageValue( $canonical, $i, $isMulti ); $seo = \S::seo( $seoLinkValue ); $this->db->insert( 'pp_pages_langs', [ 'page_id' => $pageId, 'lang_id' => $row['id'], 'title' => $this->nullIfEmpty( $titleValue ), 'meta_description' => $this->nullIfEmpty( $metaDescriptionValue ), 'meta_keywords' => $this->nullIfEmpty( $metaKeywordsValue ), 'meta_title' => $this->nullIfEmpty( $metaTitleValue ), 'seo_link' => $seo != '' ? $seo : null, 'noindex' => $noindexValue, 'site_title' => $this->nullIfEmpty( $siteTitleValue ), 'link' => $this->nullIfEmpty( $linkValue ), 'block_direct_access' => $blockDirectAccessValue, 'canonical' => $this->nullIfEmpty( $canonicalValue ) ] ); } } private function languageValue( $value, int $index, bool $isMulti ) { if ( $isMulti ) return is_array( $value ) ? ( $value[$index] ?? null ) : null; return is_array( $value ) ? ( $value[0] ?? null ) : $value; } private function nullIfEmpty( $value ) { return $value != '' ? $value : null; } private function updateSubpagesMenuIdRecursive( int $parentId, int $menuId ): void { $this->db->update( 'pp_pages', [ 'menu_id' => $menuId ], [ 'parent_id' => $parentId ] ); $results = $this->db->select( 'pp_pages', [ 'id' ], [ 'parent_id' => $parentId ] ); if ( is_array( $results ) ) foreach ( $results as $row ) $this->updateSubpagesMenuIdRecursive( (int) $row['id'], $menuId ); } }