$Item2['Index'] ? -1 : 1; } class ModuleNews extends Module { public int $NewsCountPerCategory = 3; public string $UploadedFilesFolder = 'files/news/'; public array $NewsSetting; function __construct(System $System) { parent::__construct($System); $this->Name = 'News'; $this->Version = '1.0'; $this->Creator = 'Chronos'; $this->License = 'GNU/GPLv3'; $this->Description = 'News and news groups management'; $this->Dependencies = array(ModuleUser::GetName(), ModuleLog::GetName(), ModuleFile::GetName()); $this->Models = array(NewsCategory::GetClassName(), News::GetClassName()); } function DoStart(): void { $this->System->RegisterPage(['aktuality'], 'PageNews'); $this->System->RegisterPage(['aktuality', 'subscription'], 'PageNewsSubscription'); $this->System->RegisterPage(['aktuality', 'rss'], 'PageNewsRss'); $this->System->RegisterPage(['aktuality', 'aktualizace'], 'PageNewsUpdate'); Core::Cast($this->System)->FormManager->RegisterClass('News', array( 'Title' => 'Aktualita', 'Table' => 'News', 'DefaultSortColumn' => 'Date', 'DefaultSortOrder' => 1, 'Items' => array( 'Category' => array('Type' => 'TNewsCategory', 'Caption' => 'Kategorie', 'Default' => 0), 'Title' => array('Type' => 'String', 'Caption' => 'Nadpis', 'Default' => ''), 'Content' => array('Type' => 'Text', 'Caption' => 'Obsah', 'Default' => ''), 'Date' => array('Type' => 'Date', 'Caption' => 'Datum', 'Default' => ''), 'Author' => array('Type' => 'String', 'Caption' => 'Autor', 'Default' => ''), 'Enclosure' => array('Type' => 'String', 'Caption' => 'Přílohy', 'Default' => ''), 'User' => array('Type' => 'TUser', 'Caption' => 'Uživatel', 'Default' => ''), 'IP' => array('Type' => 'IPv4Address', 'Caption' => 'IP adresa', 'Default' => '', 'ReadOnly' => true), 'Link' => array('Type' => 'Hyperlink', 'Caption' => 'Odkaz', 'Default' => ''), ), )); Core::Cast($this->System)->FormManager->RegisterClass('NewsCategory', array( 'Title' => 'Kategorie aktualit', 'Table' => 'NewsCategory', 'Items' => array( 'Caption' => array('Type' => 'String', 'Caption' => 'Titulek', 'Default' => ''), 'RSS' => array('Type' => 'Hyperlink', 'Caption' => 'Zdroj RSS', 'Default' => ''), 'Permission' => array('Type' => 'Boolean', 'Caption' => 'Veřejné upravitelné', 'Default' => ''), 'Sequence' => array('Type' => 'Integer', 'Caption' => 'Pořadí', 'Default' => ''), 'Group' => array('Type' => 'Integer', 'Caption' => 'Skupina', 'Default' => ''), 'News' => array('Type' => 'TNewsList', 'Caption' => 'Aktuality', 'Default' => ''), ), )); Core::Cast($this->System)->FormManager->RegisterFormType('TNewsCategory', array( 'Type' => 'Reference', 'Table' => 'NewsCategory', 'Id' => 'Id', 'Name' => 'Caption', 'Filter' => '1', )); Core::Cast($this->System)->FormManager->RegisterFormType('TNewsList', array( 'Type' => 'ManyToOne', 'Table' => 'News', 'Id' => 'Id', 'Ref' => 'Category', 'Filter' => '1', )); if ($this->System->ModuleManager->ModulePresent('Search')) { ModuleSearch::Cast($this->System->GetModule('Search'))->RegisterSearch('Novinky', 'News', array('Title', 'Content')); } } function GetIntranetCondition(): string { if (IsInternetAddr()) return ' AND (`Intranet`=0)'; else return ''; } function ShowNews(string $Category, int $ItemCount, int $DaysAgo): string { $ItemCount = abs($ItemCount); $DaysAgo = abs($DaysAgo); $DbResult = $this->Database->select('NewsCategory', '*', 'Id='.$Category); $Row = $DbResult->fetch_array(); $Output = '
'.$Row['Caption']; $Output .= '
Zobrazit'; if (ModuleUser::Cast($this->System->GetModule('User'))->User->CheckPermission('News', 'Insert', 'Group', $Category)) $Output .= ' Přidat'; $Output .= '
'; $DbResult = $this->Database->query('SELECT `News`.*, `User`.`Name` FROM `News` LEFT JOIN `User` ON `User`.`Id`=`News`.`User`'. ' WHERE (`News`.`Category`='.$Category.') AND (DATE_SUB(NOW(), INTERVAL '.$DaysAgo.' DAY) < `News`.`Date`)'.$this->GetIntranetCondition(). ' ORDER BY `News`.`Date` DESC LIMIT 0,'.$ItemCount); $Index = 0; $FontSize = 12; if ($DbResult->num_rows > 0) { $Output .= ''; while ($Row = $DbResult->fetch_array()) { if ($Row['Name'] == '') $Author = $Row['Author']; else $Author = $Row['Name']; $Output .= ''; $Index = $Index + 1; $FontSize = $FontSize - 1; } $Output .= '
'. ''. '
'.$Row['Title'].''.$Author.' ('.HumanDate($Row['Date']).')
'; $Output .= '
'.$this->ModifyContent($Row['Content']); if ($Row['Link'] != '') $Output .= '
Odkaz'; if ($Row['Enclosure'] != '') { $Output .= '
Přílohy: '; $Enclosures = explode(';', $Row['Enclosure']); foreach ($Enclosures as $Enclosure) { if (file_exists($this->UploadedFilesFolder.$Enclosure)) $Output .= ' '.$Enclosure.''; } } $Output .= '
'; } $Output .= '
'; return $Output; } function LoadSettingsFromCookies(): void { // Initialize default news setting $this->NewsSetting = array(); $I = 1; $DbResult = $this->Database->select('NewsCategory', '*', '1 ORDER BY Sequence'); while ($NewsCategory = $DbResult->fetch_array()) { $this->NewsSetting[] = array('CategoryId' => $NewsCategory['Id'], 'Index' => $I, 'Enabled' => 1, 'ItemCount' => Core::Cast($this->System)->Config['Web']['News']['Count'], 'DaysAgo' => Core::Cast($this->System)->Config['Web']['News']['DaysAgo'], 'Group' => $NewsCategory['Group']); $I++; } // Merge defaults with user setting if (array_key_exists('NewsSetting', $_COOKIE)) { $NewsSettingCookie = unserialize($_COOKIE['NewsSetting']); foreach ($this->NewsSetting as $Index => $this->NewsSetting) { if (array_key_exists($Index, $NewsSettingCookie)) $this->NewsSetting[$Index] = array_merge($this->NewsSetting, $NewsSettingCookie[$Index]); } } } function Show(): string { $Output = ''; $this->LoadSettingsFromCookies(); if (array_key_exists('Action', $_GET)) { // Show news customize menu if ($_GET['Action'] == 'CustomizeNews') { $Output .= $this->ShowCustomizeMenu(); } } $Output .= '
'; $ColumnCount = 2; $Output .= ''; for ($Column = 1; $Column <= $ColumnCount; $Column++) { $Output .= ''; } $Output .= '
'; foreach ($this->NewsSetting as $SettingItem) if (($SettingItem['Enabled'] == 1) and ($SettingItem['Group'] == $Column)) $Output .= $this->ShowNews($SettingItem['CategoryId'], $SettingItem['ItemCount'], $SettingItem['DaysAgo']); $Output .= '
'; $Output .= 'Aktuality přes RSS Automatické sledování novinek'; $Output .= '
'; return $Output; } function ShowCustomizeMenu(): string { $Output = '
'; $Output .= '
'; $Output .= ''; $I = 0; foreach ($this->NewsSetting as $SettingItem) { $DbResult = $this->Database->select('NewsCategory', '*', 'Id='.$SettingItem['CategoryId']); $NewsCategory = $DbResult->fetch_array(); $Output .= ''. ''. ''; $I++; } $Output .= '
KategoriePoziceZobrazitMax. početPosledních dnůSloupec
'.$NewsCategory['Caption'].''. '

'; return $Output; } function CustomizeSave(): void { $Checkbox = array('' => 0, 'on' => 1); $Setting = array(); for ($I = 0; $I < $_POST['NewsCategoryCount']; $I++) { if (($_POST['NewsCategoryDaysAgo'.$I] * 1) < 0) $_POST['NewsCategoryIndex'.$I] = 0; if (($_POST['NewsCategoryCount'.$I] * 1) < 0) $_POST['NewsCategoryCount'.$I] = 0; if (($_POST['NewsColumn'.$I] * 1) < 1) $_POST['NewsColumn'.$I] = 1; if (!array_key_exists('NewsCategoryEnabled'.$I, $_POST)) $_POST['NewsCategoryEnabled'.$I] = ''; $Setting[] = array('CategoryId' => $_POST['NewsCategoryId'.$I], 'Enabled' => $Checkbox[$_POST['NewsCategoryEnabled'.$I]], 'ItemCount' => ($_POST['NewsCategoryCount'.$I]*1), 'DaysAgo' => ($_POST['NewsCategoryDaysAgo'.$I]*1), 'Index' => ($_POST['NewsCategoryIndex'.$I]*1), 'Group' => $_POST['NewsColumn'.$I]); } // Sort indexes usort($Setting, 'CategoryItemCompare'); $Setting = array_reverse($Setting); // Normalize indexes foreach ($Setting as $Index => $Item) $Setting[$Index]['Index'] = $Index + 1; // Store new cookie value $_COOKIE['NewsSetting'] = serialize($Setting); setcookie('NewsSetting', $_COOKIE['NewsSetting'], time() + 60 * 60 * 24 * 365); } function ModifyContentPrefix(string $Content, string $Prefix): string { $Result = ''; // Make HTML link from URL $I = 0; while (strpos($Content, $Prefix) !== false) { $I = strpos($Content, $Prefix); if (($I > 0) and ($Content[$I - 1] != '"')) { $Result .= substr($Content, 0, $I); $Content = substr($Content, $I); if (strpos($Content, ' ') !== false) $URL = substr($Content, 0, strpos($Content, ' ')); else $URL = substr($Content, 0); $Result .= ''.$URL.''; $Content = substr($Content, strlen($URL)); } else { $Result .= substr($Content, 0, $I + 1); $Content = substr($Content, $I + 1); } } $Result .= $Content; return $Result; } function ModifyContent(string $Content): string { return $this->ModifyContentPrefix($this->ModifyContentPrefix($Content, 'http://'), 'https://'); } static function Cast(Module $Module): ModuleNews { if ($Module instanceof ModuleNews) { return $Module; } throw new Exception('Expected ModuleNews type but got '.gettype($Module)); } } class News extends Model { static function GetModelDesc(): ModelDesc { $Desc = new ModelDesc(self::GetClassName()); $Desc->AddReference('Category', NewsCategory::GetClassName(), true); $Desc->AddString('Title'); $Desc->AddText('Content'); $Desc->AddDate('Date'); $Desc->AddString('Author'); $Desc->AddString('Enclosure'); $Desc->AddReference('User', User::GetClassName()); $Desc->AddString('IP'); $Desc->AddString('Link'); return $Desc; } } class NewsCategory extends Model { static function GetModelDesc(): ModelDesc { $Desc = new ModelDesc(self::GetClassName()); $Desc->AddString('Caption'); $Desc->AddString('RSS'); $Desc->AddBoolean('Permission'); $Desc->AddInteger('Sequence'); $Desc->AddInteger('Group'); return $Desc; } }