Add table of contents generation and header ID processing to Articles class

- Implemented `generateTableOfContents` method to create a structured table of contents from article content.
- Added `processHeaders` method to ensure headers have unique IDs for linking.
- Updated `generateHeadersIds` to apply ID generation to headers in article content.
- Modified `article_full` method to include table of contents in rendered articles.
- Enhanced `submenu_details` and `subpages` methods in Menu class to support language ID.
- Updated caching mechanisms to include language ID for subpages and menu details.
- Refactored various methods in Articles view class for improved readability and consistency.
- Added new sftp configuration file for deployment settings.
This commit is contained in:
2026-03-05 22:38:16 +01:00
parent bfe866fec7
commit 86c704fd31
30 changed files with 851 additions and 696 deletions

View File

@@ -2,7 +2,87 @@
namespace front\factory;
class Articles
{
public static function pixieset_save_favorite_images( $hash ) {
static public function generateTableOfContents($content) {
$result = '';
$currentLevel = [];
preg_match_all('/<(h[1-6])([^>]*)>(.*?)<\/\1>/', $content, $matches, PREG_SET_ORDER);
$firstLevel = true;
foreach ($matches as $match) {
$level = intval(substr($match[1], 1));
while ($level < count($currentLevel)) {
$result .= '</li></ol>';
array_pop($currentLevel);
}
if ($level > count($currentLevel)) {
while ($level > count($currentLevel)) {
if (count($currentLevel) > 0 || $firstLevel) {
$result .= '<ol>';
$firstLevel = false;
}
array_push($currentLevel, 0);
}
$result .= '<li>';
} else {
$result .= '</li><li>';
}
$currentLevel[count($currentLevel) - 1]++;
preg_match('/\sid="([^"]*)"/', $match[2], $idMatches);
$id = isset($idMatches[1]) ? $idMatches[1] : '';
$result .= sprintf(
'<a href="#%s">%s</a>',
urlencode(strtolower($id)),
$match[3]
);
}
while (!empty($currentLevel)) {
$result .= '</li></ol>';
array_pop($currentLevel);
}
if (substr($result, 0, 8) === '<ol><ol>') {
return substr($result, 4, -5);
} else {
return $result;
}
}
// funkcja wywoływana dla każdego dopasowania do wyrażenia regularnego
static public function processHeaders( $matches )
{
$level = $matches[1];
$attrs = $matches[2];
$content = $matches[3];
$id_attr = 'id=';
$id_attr_pos = strpos($attrs, $id_attr);
if ($id_attr_pos === false) { // jeśli nie ma atrybutu id
$id = \S::seo( $content );
$attrs .= sprintf(' id="%s"', $id);
}
$html = sprintf( '<h%d%s>%s</h%d>', $level, $attrs, $content, $level );
return $html;
}
static public function generateHeadersIds( $text )
{
$pattern = '/<h([1-6])(.*?)>(.*?)<\/h\1>/si';
$text = preg_replace_callback( $pattern, array(__CLASS__, 'processHeaders'), $text );
return $text;
}
public static function pixieset_save_favorite_images( $hash )
{
global $mdb, $settings;
\S::delete_dir( 'temp/' );
@@ -149,6 +229,12 @@ class Articles
public static function get_image( $article, $skip_entry = false )
{
if ( $article['language']['main_image'] )
{
if ( file_exists( substr( $article['language']['main_image'], 1, strlen( $article['language']['main_image'] ) ) ) )
return $article['language']['main_image'];
}
if ( !$skip_entry )
{
$dom = new \DOMDocument();

View File

@@ -3,51 +3,51 @@ namespace front\factory;
class Menu
{
public static function submenu_details( $page_id )
public static function submenu_details( $page_id, $lang_id )
{
return self::subpages( $page_id );
return self::subpages( $page_id, $lang_id );
}
public static function subpages( $page_id )
static public function subpages( $page_id, $lang_id )
{
global $mdb;
if ( !$pages = \Cache::fetch( "subpages:$page_id" ) )
if ( !$pages = \Cache::fetch( "subpages:$page_id:$lang_id" ) )
{
$results = $mdb -> select( 'pp_pages', [ 'id' ], [ 'AND' => [ 'status' => 1, 'parent_id' => $page_id ], 'ORDER' => [ 'o' => 'ASC' ] ] );
if ( is_array( $results ) ) foreach ( $results as $row )
{
$page = \front\factory\Pages::page_details( $row['id'] );
$page['pages'] = self::subpages( $row['id'] );
$page['pages'] = self::subpages( $row['id'], $lang_id );
$pages[] = $page;
}
\Cache::store( "subpages:$page_id", $pages );
}
return $pages;
}
public static function menu_details( $menu_id )
{
global $mdb, $lang_id;
if ( !$menu = \Cache::fetch( "menu_details:$menu_id:$lang_id" ) )
{
$menu = $mdb -> get( 'pp_menus', '*', [ 'id' => (int)$menu_id ] );
$menu['pages'] = self::menu_pages( $menu_id );
\Cache::store( "menu_details:$menu_id:$lang_id", $menu );
}
}
return $menu;
}
public static function menu_pages( $menu_id, $parent_id = null )
{
global $mdb, $lang_id;
if ( !$pages = \Cache::fetch( "menu_pages:$menu_id:$parent_id:$lang_id" ) )
{
{
$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 )
{
@@ -56,7 +56,7 @@ class Menu
$pages[] = $page;
}
\Cache::store( "menu_pages:$menu_id:$parent_id:$lang_id", $pages );
}
return $pages;