query("SET NAMES 'utf8mb4'"); } return self::$pdo; } public static function getAll() { $pdo = self::db(); $stmt = $pdo->query("SELECT id, slug, title, date_created, date_updated, image, published, sort_order FROM articles ORDER BY sort_order DESC, id DESC"); return $pdo->result_pdo($stmt); } public static function getPublished() { $pdo = self::db(); $stmt = $pdo->query("SELECT id, slug, title, description, date_created, image FROM articles WHERE published = 1 ORDER BY sort_order DESC, id DESC"); return $pdo->result_pdo($stmt); } public static function getById($id) { $pdo = self::db(); $stmt = $pdo->queryNamed("SELECT * FROM articles WHERE id = :id LIMIT 1", array(':id' => (int)$id)); $row = $pdo->fetch_assoc($stmt); return $row ? $row : null; } public static function getBySlug($slug) { $pdo = self::db(); $stmt = $pdo->queryNamed("SELECT * FROM articles WHERE slug = :slug AND published = 1 LIMIT 1", array(':slug' => $slug)); $row = $pdo->fetch_assoc($stmt); return $row ? $row : null; } public static function create($data) { $pdo = self::db(); $pdo->queryNamed( "INSERT INTO articles (slug, title, page_title, description, content, date_created, date_updated, reading_time, image, author_name, author_img, author_job, published, sort_order) VALUES (:slug, :title, :page_title, :description, :content, :date_created, :date_updated, :reading_time, :image, :author_name, :author_img, :author_job, :published, :sort_order)", array( ':slug' => $data['slug'], ':title' => $data['title'], ':page_title' => $data['page_title'], ':description' => isset($data['description']) ? $data['description'] : '', ':content' => $data['content'], ':date_created' => $data['date_created'], ':date_updated' => $data['date_updated'], ':reading_time' => (int)$data['reading_time'], ':image' => $data['image'], ':author_name' => $data['author_name'], ':author_img' => $data['author_img'], ':author_job' => $data['author_job'], ':published' => (int)$data['published'], ':sort_order' => (int)$data['sort_order'], ) ); return (int)$pdo->insert_id(); } public static function update($id, $data) { $pdo = self::db(); $pdo->queryNamed( "UPDATE articles SET slug = :slug, title = :title, page_title = :page_title, description = :description, content = :content, date_created = :date_created, date_updated = :date_updated, reading_time = :reading_time, image = :image, author_name = :author_name, author_img = :author_img, author_job = :author_job, published = :published, sort_order = :sort_order WHERE id = :id", array( ':id' => (int)$id, ':slug' => $data['slug'], ':title' => $data['title'], ':page_title' => $data['page_title'], ':description' => isset($data['description']) ? $data['description'] : '', ':content' => $data['content'], ':date_created' => $data['date_created'], ':date_updated' => $data['date_updated'], ':reading_time' => (int)$data['reading_time'], ':image' => $data['image'], ':author_name' => $data['author_name'], ':author_img' => $data['author_img'], ':author_job' => $data['author_job'], ':published' => (int)$data['published'], ':sort_order' => (int)$data['sort_order'], ) ); } public static function delete($id) { $pdo = self::db(); $pdo->queryNamed("DELETE FROM articles WHERE id = :id", array(':id' => (int)$id)); } public static function slugExists($slug, $excludeId = 0) { $pdo = self::db(); $stmt = $pdo->queryNamed( "SELECT id FROM articles WHERE slug = :slug AND id != :exclude_id LIMIT 1", array(':slug' => $slug, ':exclude_id' => (int)$excludeId) ); return (bool)$pdo->fetch_assoc($stmt); } public static function makeSlug($title) { $title = mb_strtolower($title, 'UTF-8'); $cyr = array('а','б','в','г','д','е','ё','ж','з','и','й','к','л','м','н','о','п','р','с','т','у','ф','х','ц','ч','ш','щ','ъ','ы','ь','э','ю','я'); $lat = array('a','b','v','g','d','e','yo','zh','z','i','j','k','l','m','n','o','p','r','s','t','u','f','h','cz','ch','sh','shh','','y','','e','yu','ya'); $title = str_replace($cyr, $lat, $title); $title = preg_replace('/[^a-z0-9\s-]/', '', $title); $title = preg_replace('/[\s-]+/', '-', trim($title)); $title = trim($title, '-'); if ($title === '') { $title = 'article-' . time(); } return $title; } public static function isSlugConflictingWithFile($slug) { $path = $_SERVER['DOCUMENT_ROOT'] . '/' . $slug . '.php'; return file_exists($path); } public static function val($arr, $key, $default = '') { return (is_array($arr) && isset($arr[$key])) ? $arr[$key] : $default; } /** * Регенерирует sitemap.xml — берёт статичные публичные страницы + опубликованные статьи из БД. * Вызывается автоматически при сохранении/удалении статьи в админке. */ public static function regenerateSitemap() { $staticUrls = array( '/', '/agent.php', '/blog.php', '/tariff.php', '/reviews.php', '/company.php', '/contacts.php', '/katalog-novostroek.php', '/dlja-stroitelnoj-kompanii.php', '/srm-sistema-dlja-zastrojshhika.php', ); $articles = self::getPublished(); $today = date('Y-m-d\TH:i:sP'); $xml = '' . "\n"; $xml .= '' . "\n"; foreach ($staticUrls as $url) { $xml .= ' https://joywork.ru' . $url . '' . '' . $today . '' . 'monthly' . '1' . "\n"; } foreach ($articles as $a) { $lastmod = !empty($a['date_created']) ? date('Y-m-d\TH:i:sP', strtotime($a['date_created'])) : $today; $xml .= ' https://joywork.ru/' . htmlspecialchars($a['slug']) . '.php' . '' . $lastmod . '' . 'monthly' . '0.9' . "\n"; } $xml .= '' . "\n"; $path = $_SERVER['DOCUMENT_ROOT'] . '/sitemap.xml'; @file_put_contents($path, $xml); } }