1 | <?php
|
---|
2 |
|
---|
3 | define('CONTACT_CATEGORY_EMAIL', 4);
|
---|
4 |
|
---|
5 | class ModuleNotify extends Module
|
---|
6 | {
|
---|
7 | public array $Checks;
|
---|
8 |
|
---|
9 | function __construct(System $System)
|
---|
10 | {
|
---|
11 | parent::__construct($System);
|
---|
12 | $this->Name = 'Notify';
|
---|
13 | $this->Version = '1.0';
|
---|
14 | $this->Creator = 'Chronos';
|
---|
15 | $this->License = 'GNU/GPLv3';
|
---|
16 | $this->Description = 'Send notification messages to selected users';
|
---|
17 | $this->Dependencies = array(ModuleUser::GetName(), ModuleRSS::GetName());
|
---|
18 | $this->Models = array(NotifyCategory::GetClassName(), NotifyUser::GetClassName());
|
---|
19 |
|
---|
20 | $this->Checks = array();
|
---|
21 | }
|
---|
22 |
|
---|
23 | function DoStart(): void
|
---|
24 | {
|
---|
25 | $this->System->FormManager->RegisterClass('NotifyUser', array(
|
---|
26 | 'Title' => 'Upozornění uživatelé',
|
---|
27 | 'Table' => 'NotifyUser',
|
---|
28 | 'Items' => array(
|
---|
29 | 'User' => array('Type' => 'TUser', 'Caption' => 'Uživatel', 'Default' => ''),
|
---|
30 | 'Contact' => array('Type' => 'TContact', 'Caption' => 'Kontakt', 'Default' => ''),
|
---|
31 | 'Period' => array('Type' => 'Integer', 'Caption' => 'Interval', 'Default' => '60'),
|
---|
32 | ),
|
---|
33 | ));
|
---|
34 | $this->System->FormManager->RegisterClass('NotifyCategory', array(
|
---|
35 | 'Title' => 'Kategorie upozornění',
|
---|
36 | 'Table' => 'NotifyCategory',
|
---|
37 | 'Items' => array(
|
---|
38 | 'Name' => array('Type' => 'String', 'Caption' => 'Jméno', 'Default' => ''),
|
---|
39 | 'SysName' => array('Type' => 'String', 'Caption' => 'Systémové jméno', 'Default' => ''),
|
---|
40 | ),
|
---|
41 | ));
|
---|
42 | $this->System->RegisterPage(['notify'], 'PageNotify');
|
---|
43 | $this->System->RegisterCommandLine('notify', 'Perform notifications processing.', array($this, 'RunCheck'));
|
---|
44 | ModuleRSS::Cast($this->System->GetModule('RSS'))->RegisterRSS(array('Title' => 'Notify log',
|
---|
45 | 'Channel' => 'notifylog', 'Callback' => array($this, 'ShowLogRSS'),
|
---|
46 | 'Permission' => array('Module' => 'Notify', 'Operation' => 'RSS')));
|
---|
47 | }
|
---|
48 |
|
---|
49 | function RegisterCheck(string $Name, callable $Callback): void
|
---|
50 | {
|
---|
51 | if (array_key_exists($Name, $this->Checks))
|
---|
52 | throw new Exception('Check function "'.$Name.'" already registered.');
|
---|
53 | $this->Checks[$Name] = array('Callback' => $Callback);
|
---|
54 | }
|
---|
55 |
|
---|
56 | function UnregisterCheck(string $Name): void
|
---|
57 | {
|
---|
58 | if (!array_key_exists($Name, $this->Checks))
|
---|
59 | throw new Exception('Check function "'.$Name.'" not registered.');
|
---|
60 | unset($this->Checks[$Name]);
|
---|
61 | }
|
---|
62 |
|
---|
63 | function Check(): string
|
---|
64 | {
|
---|
65 | $Output = '';
|
---|
66 | $Content = '';
|
---|
67 | $Title = '';
|
---|
68 |
|
---|
69 | // Get output from checks
|
---|
70 | $DbResult2 = $this->Database->query('SELECT `Id`, `Name`, `SysName` FROM `NotifyCategory`');
|
---|
71 | while ($Category = $DbResult2->fetch_assoc())
|
---|
72 | {
|
---|
73 | if (array_key_exists($Category['SysName'], $this->Checks))
|
---|
74 | {
|
---|
75 | $Status = call_user_func($this->Checks[$Category['SysName']]['Callback']);
|
---|
76 | if ($Status['Report'] != '')
|
---|
77 | {
|
---|
78 | $Output .= 'Kategorie: '.$Category['Name'].":\n";
|
---|
79 | $Content .= 'Kategorie: '.$Category['Name']."<br>\n";
|
---|
80 | $Content .= $Status['Report'];
|
---|
81 | }
|
---|
82 | if (strlen($Title) > 0) $Title .= ', ';
|
---|
83 | $Title .= $Status['Title'].':'.$Status['Count'];
|
---|
84 | }
|
---|
85 | }
|
---|
86 |
|
---|
87 | $Time = time();
|
---|
88 |
|
---|
89 | // Send content to users
|
---|
90 | $DbResult = $this->Database->query('SELECT `NotifyUser`.`Id`, `NotifyUser`.`LastTime`, `User`.`Name`, `Contact`.`Value`, `Contact`.`Category` FROM `NotifyUser` '.
|
---|
91 | 'LEFT JOIN `User` ON `User`.`Id` = `NotifyUser`.`User` '.
|
---|
92 | 'LEFT JOIN `Contact` ON `Contact`.`Id` = `NotifyUser`.`Contact`');
|
---|
93 | while ($User = $DbResult->fetch_assoc())
|
---|
94 | {
|
---|
95 | $Output .= 'User '.$User['Name'].'<br/>';
|
---|
96 |
|
---|
97 | $this->Database->update('NotifyUser', '`Id`='.$User['Id'], array('LastTime' => TimeToMysqlDateTime($Time)));
|
---|
98 |
|
---|
99 | if (($User['Category'] == CONTACT_CATEGORY_EMAIL) and ($Content != ''))
|
---|
100 | {
|
---|
101 | $Mail = new Mail();
|
---|
102 | $Mail->Subject = $Title;
|
---|
103 | $Mail->From = $this->System->Config['Web']['Title'].' <noreplay@zdechov.net>';
|
---|
104 | $Mail->AddTo($User['Value'], $User['Name']);
|
---|
105 | $Mail->AddBody(strip_tags($Content), 'text/plain');
|
---|
106 | $Mail->AddBody('<style>
|
---|
107 | table { border-collapse: collapse; }
|
---|
108 | table, th, td { border: 1px solid black; }
|
---|
109 | td { padding: 5px; }
|
---|
110 | </style>'.$Content, 'text/html');
|
---|
111 | $Mail->Send();
|
---|
112 | $Output .= 'Sent email to '.$User['Value'].' ('.$User['Name'].')<br/>';
|
---|
113 | $Output .= strip_tags(str_replace("</", " </", str_replace('<br/>', "\n", $Content)));
|
---|
114 | }
|
---|
115 | }
|
---|
116 |
|
---|
117 | if ($Content != '')
|
---|
118 | {
|
---|
119 | $this->Database->insert('NotifyLog', array(
|
---|
120 | 'Time' => TimeToMysqlDateTime($Time),
|
---|
121 | 'Title' => $Title,
|
---|
122 | 'Content' => $Content)
|
---|
123 | );
|
---|
124 | }
|
---|
125 |
|
---|
126 | return $Output;
|
---|
127 | }
|
---|
128 |
|
---|
129 | function RunCheck(array $Parameters): void
|
---|
130 | {
|
---|
131 | RepeatFunction(30, array($this, 'Check'));
|
---|
132 | }
|
---|
133 |
|
---|
134 | function DoInstall(): void
|
---|
135 | {
|
---|
136 | $this->Database->query("INSERT INTO `NotifyCategory` (`Id`, `Name`, `SysName`) VALUES
|
---|
137 | (1, 'Dostupnost zařízení (ping)', 'NetworkReachability'),
|
---|
138 | (2, 'Dostupnost URL', 'URL'),
|
---|
139 | (3, 'Minimální úroveň signálu', 'WirelessSignal'),
|
---|
140 | (4, 'Dostupnost síťového portu', 'NetworkPort'),
|
---|
141 | (5, 'Minimální odezva', 'NetworkLatency'),
|
---|
142 | (6, 'Minimální propustnost', 'NetworkBandwidth');");
|
---|
143 | }
|
---|
144 |
|
---|
145 | function ShowLogRSS(): string
|
---|
146 | {
|
---|
147 | Header('Content-Type: text/xml');
|
---|
148 | $Count = 20;
|
---|
149 |
|
---|
150 | $Items = array();
|
---|
151 | $sql = 'SELECT `Id`,`Title`,`Content`, UNIX_TIMESTAMP(`Time`) AS `Time` FROM `NotifyLog`'.
|
---|
152 | ' ORDER BY `Time` DESC LIMIT '.$Count;
|
---|
153 | $DbResult = $this->System->Database->query($sql);
|
---|
154 | while ($Line = $DbResult->fetch_assoc())
|
---|
155 | {
|
---|
156 | $Items[] = array
|
---|
157 | (
|
---|
158 | 'Title' => $Line['Title'],
|
---|
159 | 'Link' => 'https://'.$this->System->Config['Web']['Host'].$this->System->Link('/notify/?i='.$Line['Id']),
|
---|
160 | 'Description' => $Line['Content'],
|
---|
161 | 'Time' => $Line['Time'],
|
---|
162 | );
|
---|
163 | }
|
---|
164 |
|
---|
165 | $RSS = new RSS();
|
---|
166 | $RSS->Title = $this->System->Config['Web']['Title'].' - Záznamy upozornění';
|
---|
167 | $RSS->Link = 'https://'.$this->System->Config['Web']['Host'].'/';
|
---|
168 | $RSS->Description = 'Záznam upozornění '.$this->System->Config['Web']['Description'];
|
---|
169 | $RSS->WebmasterEmail = $this->System->Config['Web']['AdminEmail'];
|
---|
170 | $RSS->Items = $Items;
|
---|
171 | return $RSS->Generate();
|
---|
172 | }
|
---|
173 |
|
---|
174 | static function Cast(Module $Module): ModuleNotify
|
---|
175 | {
|
---|
176 | if ($Module instanceof ModuleNotify)
|
---|
177 | {
|
---|
178 | return $Module;
|
---|
179 | }
|
---|
180 | throw new Exception('Expected ModuleNotify type but got '.gettype($Module));
|
---|
181 | }
|
---|
182 | }
|
---|
183 |
|
---|
184 | class PageNotify extends Page
|
---|
185 | {
|
---|
186 | function __construct(System $System)
|
---|
187 | {
|
---|
188 | parent::__construct($System);
|
---|
189 | $this->Title = 'Upozornění';
|
---|
190 | $this->Description = 'Upozornění';
|
---|
191 | $this->ParentClass = 'PagePortal';
|
---|
192 | }
|
---|
193 |
|
---|
194 | function Show(): string
|
---|
195 | {
|
---|
196 | if (!ModuleUser::Cast($this->System->GetModule('User'))->User->CheckPermission('Notify', 'Show'))
|
---|
197 | return 'Nemáte oprávnění';
|
---|
198 |
|
---|
199 | $Output = '<style>
|
---|
200 | table { border-collapse: collapse; }
|
---|
201 | table, th, td { border: 1px solid gray; }
|
---|
202 | td { padding: 5px; }
|
---|
203 | </style>';
|
---|
204 | if (!array_key_exists('i', $_GET) or !is_numeric($_GET['i'])) return 'Položka nenalezena';
|
---|
205 | $Id = $_GET['i'] * 1;
|
---|
206 | $DbResult = $this->Database->select('NotifyLog', 'Title,Content, UNIX_TIMESTAMP(`Time`) AS `Time`', 'Id='.$Id);
|
---|
207 | if ($DbResult->num_rows > 0)
|
---|
208 | {
|
---|
209 | $DbRow = $DbResult->fetch_assoc();
|
---|
210 | $Output .= '<h3>'.$DbRow['Title'].'</h3>'.
|
---|
211 | '<div>Čas: '.TimeToMysqlDateTime($DbRow['Time']).'</div>'.
|
---|
212 | '<p>'.$DbRow['Content'].'</p>';
|
---|
213 | } else $Output = 'Položka nenalezena';
|
---|
214 | return $Output;
|
---|
215 | }
|
---|
216 | }
|
---|
217 |
|
---|
218 | class NotifyCategory extends Model
|
---|
219 | {
|
---|
220 | static function GetModelDesc(): ModelDesc
|
---|
221 | {
|
---|
222 | $Desc = new ModelDesc(self::GetClassName());
|
---|
223 | $Desc->AddString('Name');
|
---|
224 | $Desc->AddString('SysName');
|
---|
225 | return $Desc;
|
---|
226 | }
|
---|
227 | }
|
---|
228 |
|
---|
229 | class NotifyUser extends Model
|
---|
230 | {
|
---|
231 | static function GetModelDesc(): ModelDesc
|
---|
232 | {
|
---|
233 | $Desc = new ModelDesc(self::GetClassName());
|
---|
234 | $Desc->AddReference('User', User::GetClassName());
|
---|
235 | $Desc->AddReference('Contact', Contact::GetClassName());
|
---|
236 | $Desc->AddInteger('Period');
|
---|
237 | return $Desc;
|
---|
238 | }
|
---|
239 | }
|
---|