Compare commits
78 Commits
Author | SHA1 | Date |
---|---|---|
|
7d85c9181d | |
|
f88fc0f819 | |
|
54d6ce2ec4 | |
|
0bab284e99 | |
|
cf7d417193 | |
|
1780233778 | |
|
666f3ca98b | |
|
1ba32d86f7 | |
|
d2213ca3e9 | |
|
c83baeee2f | |
|
cd7b78a2e5 | |
|
d854473a06 | |
|
bf197ae96b | |
|
2bbc4af068 | |
|
1cda74cd50 | |
|
3abafe2de7 | |
|
3a5eed933e | |
|
909fbc2626 | |
|
09667920a2 | |
|
ea4b85ddf7 | |
|
8ca9643fc2 | |
|
b02d72b29d | |
|
e84c880289 | |
|
1df19d9609 | |
|
a6cf2fe99b | |
|
f796e100f8 | |
|
8eed6afd46 | |
|
2cdfbe6e86 | |
|
9d3a4557c1 | |
|
acd5ff0a23 | |
|
9a3024cfa6 | |
|
20d9dc0e73 | |
|
8e123cf5f2 | |
|
8765fe22c0 | |
|
e6d6a10795 | |
|
aeb837fee5 | |
|
91aac20998 | |
|
c915bcba9e | |
|
0f868f07e2 | |
|
3943ba49b6 | |
|
8a4816a6ae | |
|
4b783a6b63 | |
|
6191d44944 | |
|
838b8ea9f2 | |
|
15c97859a4 | |
|
6199dad2c6 | |
|
cb040ee408 | |
|
2aaf2ac03f | |
|
27304513d8 | |
|
0cfa9d811e | |
|
54b998a1a8 | |
|
77e674bab5 | |
|
b6fc4a995d | |
|
ca95f3c27e | |
|
22e502c90c | |
|
ae7929b4e1 | |
|
80454de3f2 | |
|
8455a98ec5 | |
|
5d240b1dd8 | |
|
06ffde67f4 | |
|
8bbe4b6274 | |
|
001e6c5be7 | |
|
55b53ef30a | |
|
c011321403 | |
|
42f9738128 | |
|
c0c072884f | |
|
54ddc6577e | |
|
d9aaf97b81 | |
|
f76fd03794 | |
|
3e0729c6cc | |
|
16b7627b60 | |
|
c6e52df33a | |
|
7d459cf508 | |
|
350ba053e8 | |
|
efd7cd74a2 | |
|
c39e53906f | |
|
5463ea0cee | |
|
ba9d14f5d1 |
36
CHANGELOG.md
36
CHANGELOG.md
|
@ -7,16 +7,44 @@ All notable changes to this project will be documented in this file.
|
||||||
## Unreleased
|
## Unreleased
|
||||||
|
|
||||||
#### Links
|
#### Links
|
||||||
- upstream: https://code.lindeas.com/lindeas/jilo-web/compare/v0.1.1...HEAD
|
- upstream: https://code.lindeas.com/lindeas/jilo-web/compare/v0.2...HEAD
|
||||||
- codeberg: https://codeberg.org/lindeas/jilo-web/compare/v0.1.1...HEAD
|
- codeberg: https://codeberg.org/lindeas/jilo-web/compare/v0.2...HEAD
|
||||||
- github: https://github.com/lindeas/jilo-web/compare/v0.1.1...HEAD
|
- github: https://github.com/lindeas/jilo-web/compare/v0.2...HEAD
|
||||||
- gitlab: https://gitlab.com/lindeas/jilo-web/-/compare/v0.1.1...HEAD
|
- gitlab: https://gitlab.com/lindeas/jilo-web/-/compare/v0.2...HEAD
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 0.2 - 2024-08-31
|
||||||
|
|
||||||
|
#### Links
|
||||||
|
- upstream: https://code.lindeas.com/lindeas/jilo-web/compare/v0.1.1...v0.2
|
||||||
|
- codeberg: https://codeberg.org/lindeas/jilo-web/compare/v0.1.1...v0.2
|
||||||
|
- github: https://github.com/lindeas/jilo-web/compare/v0.1.1...v0.2
|
||||||
|
- gitlab: https://gitlab.com/lindeas/jilo-web/-/compare/v0.1.1...v0.2
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
- Added collapsible front page widgets
|
||||||
|
- Added widgets to conferences, participants and components pages
|
||||||
|
- Added front page widget for monthly conferences and participants number
|
||||||
|
- Added login/registration control and messages
|
||||||
|
- Added default config file locations
|
||||||
|
- Added left collapsible sidebar
|
||||||
|
- Added logo
|
||||||
|
- Added database helper functions
|
||||||
|
- Added support for multiple Jitsi platforms
|
||||||
|
- Added app environments "production" and "development"
|
||||||
|
- Added visualisation of config.js and interface_config.js per Jitsi platform
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
- MVC design - models(classes folder), views(templates folder) and controllers(pages folder)
|
||||||
|
- Changed menus - categories on sidebar menu, jitsi platforms on top menu
|
||||||
|
- Moved all the app code outside of the public web folder
|
||||||
|
- Config file now can have nested arrays
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
- Fixed SQL when conferences start and end time are not explicitly clear
|
||||||
|
- Web design fixes
|
||||||
|
- Fixed install script
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
25
README.md
25
README.md
|
@ -26,13 +26,15 @@ To see a demo install, go to https://work.lindeas.com/jilo-web-demo/
|
||||||
|
|
||||||
## version
|
## version
|
||||||
|
|
||||||
Current version: **0.1.1** released on **2024-07-25**
|
Current version: **0.2** released on **2024-08-31**
|
||||||
|
|
||||||
## license
|
## license
|
||||||
|
|
||||||
This project is licensed under the GNU General Public License version 2 (GPL-2.0). See LICENSE file.
|
This project is licensed under the GNU General Public License version 2 (GPL-2.0). See LICENSE file.
|
||||||
|
|
||||||
Bootstrap is used in this project and is licensed under the MIT License. See bootstrap-license file
|
Bootstrap is used in this project and is licensed under the MIT License. See license-bootstrap file.
|
||||||
|
|
||||||
|
JQuery is used in this project and is licensed under the MIT License. See license-jquery file.
|
||||||
|
|
||||||
## requirements
|
## requirements
|
||||||
|
|
||||||
|
@ -45,20 +47,29 @@ Bootstrap is used in this project and is licensed under the MIT License. See boo
|
||||||
You can install it in the following ways:
|
You can install it in the following ways:
|
||||||
|
|
||||||
- download the latest release from the **"Releases"** section here
|
- download the latest release from the **"Releases"** section here
|
||||||
|
```bash
|
||||||
|
tar -xzf jilo-web_*.tgz
|
||||||
|
cd jilo-web/doc/
|
||||||
|
./install.sh
|
||||||
|
```
|
||||||
- clone the **git repo**:
|
- clone the **git repo**:
|
||||||
```bash
|
```bash
|
||||||
git clone https://github.com/lindeas/jilo-web.git
|
git clone https://github.com/lindeas/jilo-web.git
|
||||||
cd jilo
|
cd jilo-web
|
||||||
|
./install.sh
|
||||||
```
|
```
|
||||||
- DEB and RPM packages are planned, but still unavailable
|
- DEB and RPM packages are planned, but not yet available. There are experimental build scripts in "packaging" folder.
|
||||||
|
|
||||||
## config
|
## config
|
||||||
|
|
||||||
- edit index.php and set the system path to the jilo-web.conf.php
|
|
||||||
- edit jilo-web.conf.php and set all the variables correctly
|
- edit jilo-web.conf.php and set all the variables correctly
|
||||||
- "database" is the sqlite db file for jilo-web itself, create it with `cat jilo-web.schema | sqlite3 jilo-web.db`
|
- "sqlite_file" is the sqlite db file for jilo-web itself, it goes to `app/jilo-web.db`, create it with
|
||||||
|
```bash
|
||||||
|
cd app
|
||||||
|
cat ../doc/jilo-web.schema | sqlite3 jilo-web.db
|
||||||
|
```
|
||||||
- "jilo_database" is the sqlite db file for jilo, with data from the Jitsi logs
|
- "jilo_database" is the sqlite db file for jilo, with data from the Jitsi logs
|
||||||
|
|
||||||
## database
|
## database
|
||||||
|
|
||||||
The database is an SQLite file. You also need the sqlite db from jilo (mysql/mariadb support is planned, but still unavailable).
|
The database is an SQLite file. You also need the sqlite db from jilo (mysql/mariadb support is planned, but not yet available).
|
||||||
|
|
6
TODO.md
6
TODO.md
|
@ -10,13 +10,13 @@
|
||||||
|
|
||||||
- - ~~add bootstrap template~~
|
- - ~~add bootstrap template~~
|
||||||
|
|
||||||
- - clean up the code to follow model-view--controller style
|
- - ~~clean up the code to follow model-view--controller style~~
|
||||||
|
|
||||||
- - no HTML inside PHP code
|
- - ~~no HTML inside PHP code~~
|
||||||
|
|
||||||
- - put all additional functions in files in a separate folder
|
- - put all additional functions in files in a separate folder
|
||||||
|
|
||||||
- - reduce try/catch usage, use it only for critical errors
|
- - ~~reduce try/catch usage, use it only for critical errors~~
|
||||||
|
|
||||||
- - move all SQL code in the model classes, one query per method
|
- - move all SQL code in the model classes, one query per method
|
||||||
|
|
||||||
|
|
|
@ -2,11 +2,9 @@
|
||||||
|
|
||||||
class Component {
|
class Component {
|
||||||
private $db;
|
private $db;
|
||||||
private $queries;
|
|
||||||
|
|
||||||
public function __construct($database) {
|
public function __construct($database) {
|
||||||
$this->db = $database->getConnection();
|
$this->db = $database->getConnection();
|
||||||
$this->queries = include('queries.php');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -21,11 +19,24 @@ class Component {
|
||||||
if (empty($until_time)) {
|
if (empty($until_time)) {
|
||||||
$until_time = '9999-12-31';
|
$until_time = '9999-12-31';
|
||||||
}
|
}
|
||||||
|
|
||||||
// this is needed for compatibility with the bash version, so we use '%s' placeholders
|
|
||||||
$from_time = htmlspecialchars(strip_tags($from_time));
|
$from_time = htmlspecialchars(strip_tags($from_time));
|
||||||
$until_time = htmlspecialchars(strip_tags($until_time));
|
$until_time = htmlspecialchars(strip_tags($until_time));
|
||||||
$sql = $this->queries['jitsi_components'];
|
|
||||||
|
// list of jitsi component events
|
||||||
|
$sql = "
|
||||||
|
SELECT
|
||||||
|
jitsi_component, loglevel, time, component_id, event_type, event_param
|
||||||
|
FROM
|
||||||
|
jitsi_components
|
||||||
|
WHERE
|
||||||
|
jitsi_component = %s
|
||||||
|
AND
|
||||||
|
component_id = %s
|
||||||
|
AND
|
||||||
|
(time >= '%s 00:00:00' AND time <= '%s 23:59:59')
|
||||||
|
ORDER BY
|
||||||
|
time";
|
||||||
|
|
||||||
$sql = sprintf($sql, $jitsi_component, $component_id, $from_time, $until_time);
|
$sql = sprintf($sql, $jitsi_component, $component_id, $from_time, $until_time);
|
||||||
|
|
||||||
$query = $this->db->prepare($sql);
|
$query = $this->db->prepare($sql);
|
|
@ -0,0 +1,293 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
class Conference {
|
||||||
|
private $db;
|
||||||
|
|
||||||
|
public function __construct($database) {
|
||||||
|
$this->db = $database->getConnection();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// search/list specific conference ID
|
||||||
|
public function conferenceById($conference_id, $from_time, $until_time) {
|
||||||
|
|
||||||
|
// time period drill-down
|
||||||
|
// FIXME make it similar to the bash version
|
||||||
|
if (empty($from_time)) {
|
||||||
|
$from_time = '0000-01-01';
|
||||||
|
}
|
||||||
|
if (empty($until_time)) {
|
||||||
|
$until_time = '9999-12-31';
|
||||||
|
}
|
||||||
|
|
||||||
|
// this is needed for compatibility with the bash version, so we use '%s' placeholders
|
||||||
|
$from_time = htmlspecialchars(strip_tags($from_time));
|
||||||
|
$until_time = htmlspecialchars(strip_tags($until_time));
|
||||||
|
|
||||||
|
// search for a conference by its ID for a time period (if given)
|
||||||
|
$sql = "
|
||||||
|
SELECT
|
||||||
|
pe.time,
|
||||||
|
c.conference_id,
|
||||||
|
c.conference_name,
|
||||||
|
c.conference_host,
|
||||||
|
pe.loglevel,
|
||||||
|
pe.event_type,
|
||||||
|
p.endpoint_id AS participant_id,
|
||||||
|
pe.event_param
|
||||||
|
FROM
|
||||||
|
conferences c
|
||||||
|
LEFT JOIN
|
||||||
|
conference_events ce ON c.conference_id = ce.conference_id
|
||||||
|
LEFT JOIN
|
||||||
|
participants p ON c.conference_id = p.conference_id
|
||||||
|
LEFT JOIN
|
||||||
|
participant_events pe ON p.endpoint_id = pe.participant_id
|
||||||
|
WHERE
|
||||||
|
c.conference_id = '%s'
|
||||||
|
AND (pe.time >= '%s 00:00:00' AND pe.time <= '%s 23:59:59')
|
||||||
|
|
||||||
|
UNION
|
||||||
|
|
||||||
|
SELECT
|
||||||
|
ce.time AS event_time,
|
||||||
|
c.conference_id,
|
||||||
|
c.conference_name,
|
||||||
|
c.conference_host,
|
||||||
|
ce.loglevel,
|
||||||
|
ce.conference_event AS event_type,
|
||||||
|
NULL AS participant_id,
|
||||||
|
ce.conference_param AS event_param
|
||||||
|
FROM
|
||||||
|
conferences c
|
||||||
|
LEFT JOIN
|
||||||
|
conference_events ce ON c.conference_id = ce.conference_id
|
||||||
|
WHERE
|
||||||
|
c.conference_id = '%s'
|
||||||
|
AND (event_time >= '%s 00:00:00' AND event_time <= '%s 23:59:59')
|
||||||
|
|
||||||
|
ORDER BY
|
||||||
|
pe.time";
|
||||||
|
|
||||||
|
$sql = sprintf($sql, $conference_id, $from_time, $until_time, $conference_id, $from_time, $until_time);
|
||||||
|
|
||||||
|
$query = $this->db->prepare($sql);
|
||||||
|
$query->execute();
|
||||||
|
|
||||||
|
return $query->fetchAll(PDO::FETCH_ASSOC);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// search/list specific conference name
|
||||||
|
public function conferenceByName($conference_name, $from_time, $until_time) {
|
||||||
|
|
||||||
|
// time period drill-down
|
||||||
|
// FIXME make it similar to the bash version
|
||||||
|
if (empty($from_time)) {
|
||||||
|
$from_time = '0000-01-01';
|
||||||
|
}
|
||||||
|
if (empty($until_time)) {
|
||||||
|
$until_time = '9999-12-31';
|
||||||
|
}
|
||||||
|
|
||||||
|
// this is needed for compatibility with the bash version, so we use '%s' placeholders
|
||||||
|
$from_time = htmlspecialchars(strip_tags($from_time));
|
||||||
|
$until_time = htmlspecialchars(strip_tags($until_time));
|
||||||
|
|
||||||
|
// search for a conference by its name for a time period (if given)
|
||||||
|
$sql = "
|
||||||
|
SELECT
|
||||||
|
pe.time,
|
||||||
|
c.conference_id,
|
||||||
|
c.conference_name,
|
||||||
|
c.conference_host,
|
||||||
|
pe.loglevel,
|
||||||
|
pe.event_type,
|
||||||
|
p.endpoint_id AS participant_id,
|
||||||
|
pe.event_param
|
||||||
|
FROM
|
||||||
|
conferences c
|
||||||
|
LEFT JOIN
|
||||||
|
conference_events ce ON c.conference_id = ce.conference_id
|
||||||
|
LEFT JOIN
|
||||||
|
participants p ON c.conference_id = p.conference_id
|
||||||
|
LEFT JOIN
|
||||||
|
participant_events pe ON p.endpoint_id = pe.participant_id
|
||||||
|
WHERE
|
||||||
|
c.conference_name = '%s'
|
||||||
|
AND (pe.time >= '%s 00:00:00' AND pe.time <= '%s 23:59:59')
|
||||||
|
|
||||||
|
UNION
|
||||||
|
|
||||||
|
SELECT
|
||||||
|
ce.time AS event_time,
|
||||||
|
c.conference_id,
|
||||||
|
c.conference_name,
|
||||||
|
c.conference_host,
|
||||||
|
ce.loglevel,
|
||||||
|
ce.conference_event AS event_type,
|
||||||
|
NULL AS participant_id,
|
||||||
|
ce.conference_param AS event_param
|
||||||
|
FROM
|
||||||
|
conferences c
|
||||||
|
LEFT JOIN
|
||||||
|
conference_events ce ON c.conference_id = ce.conference_id
|
||||||
|
WHERE
|
||||||
|
c.conference_name = '%s'
|
||||||
|
AND (event_time >= '%s 00:00:00' AND event_time <= '%s 23:59:59')
|
||||||
|
|
||||||
|
ORDER BY
|
||||||
|
pe.time";
|
||||||
|
|
||||||
|
$sql = sprintf($sql, $conference_name, $from_time, $until_time, $conference_name, $from_time, $until_time);
|
||||||
|
|
||||||
|
$query = $this->db->prepare($sql);
|
||||||
|
$query->execute();
|
||||||
|
|
||||||
|
return $query->fetchAll(PDO::FETCH_ASSOC);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// list of all conferences
|
||||||
|
public function conferencesAllFormatted($from_time, $until_time) {
|
||||||
|
|
||||||
|
// time period drill-down
|
||||||
|
// FIXME make it similar to the bash version
|
||||||
|
if (empty($from_time)) {
|
||||||
|
$from_time = '0000-01-01';
|
||||||
|
}
|
||||||
|
if (empty($until_time)) {
|
||||||
|
$until_time = '9999-12-31';
|
||||||
|
}
|
||||||
|
|
||||||
|
// this is needed for compatibility with the bash version, so we use '%s' placeholders
|
||||||
|
$from_time = htmlspecialchars(strip_tags($from_time));
|
||||||
|
$until_time = htmlspecialchars(strip_tags($until_time));
|
||||||
|
|
||||||
|
// list of conferences for time period (if given)
|
||||||
|
// fields: component, duration, conference ID, conference name, number of participants, name count (the conf name is found), conference host
|
||||||
|
$sql = "
|
||||||
|
SELECT DISTINCT
|
||||||
|
c.jitsi_component,
|
||||||
|
(SELECT COALESCE
|
||||||
|
(
|
||||||
|
(SELECT ce.time
|
||||||
|
FROM conference_events ce
|
||||||
|
WHERE
|
||||||
|
ce.conference_id = c.conference_id
|
||||||
|
AND
|
||||||
|
ce.conference_event = 'conference created'
|
||||||
|
),
|
||||||
|
(SELECT ce.time
|
||||||
|
FROM conference_events ce
|
||||||
|
WHERE
|
||||||
|
ce.conference_id = c.conference_id
|
||||||
|
AND
|
||||||
|
ce.conference_event = 'bridge selected'
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
AS start,
|
||||||
|
(SELECT COALESCE
|
||||||
|
(
|
||||||
|
(SELECT ce.time
|
||||||
|
FROM conference_events ce
|
||||||
|
WHERE
|
||||||
|
ce.conference_id = c.conference_id
|
||||||
|
AND
|
||||||
|
(ce.conference_event = 'conference expired' OR ce.conference_event = 'conference stopped')
|
||||||
|
),
|
||||||
|
(SELECT pe.time
|
||||||
|
FROM participant_events pe
|
||||||
|
WHERE
|
||||||
|
pe.event_param = c.conference_id
|
||||||
|
ORDER BY pe.time DESC
|
||||||
|
LIMIT 1
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
AS end,
|
||||||
|
c.conference_id,
|
||||||
|
c.conference_name,
|
||||||
|
(SELECT COUNT(pe.participant_id)
|
||||||
|
FROM participant_events pe
|
||||||
|
WHERE
|
||||||
|
pe.event_type = 'participant joining'
|
||||||
|
AND
|
||||||
|
pe.event_param = c.conference_id) AS participants,
|
||||||
|
name_counts.name_count,
|
||||||
|
c.conference_host
|
||||||
|
FROM
|
||||||
|
conferences c
|
||||||
|
JOIN (
|
||||||
|
SELECT
|
||||||
|
conference_name,
|
||||||
|
COUNT(*) AS name_count
|
||||||
|
FROM
|
||||||
|
conferences
|
||||||
|
GROUP BY
|
||||||
|
conference_name
|
||||||
|
) AS name_counts ON c.conference_name = name_counts.conference_name
|
||||||
|
JOIN
|
||||||
|
conference_events ce ON c.conference_id = ce.conference_id
|
||||||
|
WHERE (ce.time >= '%s 00:00:00' AND ce.time <= '%s 23:59:59')
|
||||||
|
ORDER BY
|
||||||
|
c.id";
|
||||||
|
|
||||||
|
$sql = sprintf($sql, $from_time, $until_time);
|
||||||
|
|
||||||
|
$query = $this->db->prepare($sql);
|
||||||
|
$query->execute();
|
||||||
|
|
||||||
|
return $query->fetchAll(PDO::FETCH_ASSOC);
|
||||||
|
}
|
||||||
|
|
||||||
|
// number of conferences
|
||||||
|
public function conferenceNumber($from_time, $until_time) {
|
||||||
|
|
||||||
|
// time period drill-down
|
||||||
|
// FIXME make it similar to the bash version
|
||||||
|
if (empty($from_time)) {
|
||||||
|
$from_time = '0000-01-01';
|
||||||
|
}
|
||||||
|
if (empty($until_time)) {
|
||||||
|
$until_time = '9999-12-31';
|
||||||
|
}
|
||||||
|
|
||||||
|
// this is needed for compatibility with the bash version, so we use '%s' placeholders
|
||||||
|
$from_time = htmlspecialchars(strip_tags($from_time));
|
||||||
|
$until_time = htmlspecialchars(strip_tags($until_time));
|
||||||
|
|
||||||
|
// number of conferences for time period (if given)
|
||||||
|
// NB we need to cross check with first occurrence of "bridge selected"
|
||||||
|
// as in Jicofo logs there is no way to get the time for conference ID creation
|
||||||
|
$sql = "
|
||||||
|
SELECT COUNT(c.conference_id) as conferences
|
||||||
|
FROM
|
||||||
|
conferences c
|
||||||
|
LEFT JOIN (
|
||||||
|
SELECT ce.conference_id, MIN(ce.time) as first_event_time
|
||||||
|
FROM conference_events ce
|
||||||
|
WHERE ce.conference_event = 'bridge selected'
|
||||||
|
GROUP BY ce.conference_id
|
||||||
|
) AS first_event ON c.conference_id = first_event.conference_id
|
||||||
|
LEFT JOIN
|
||||||
|
conference_events ce ON c.conference_id = ce.conference_id
|
||||||
|
WHERE
|
||||||
|
(ce.time >= '%s 00:00:00' AND ce.time <= '%s 23:59:59')
|
||||||
|
AND (ce.conference_event = 'conference created'
|
||||||
|
OR (ce.conference_event = 'bridge selected' AND ce.time = first_event.first_event_time)
|
||||||
|
)";
|
||||||
|
|
||||||
|
$sql = sprintf($sql, $from_time, $until_time);
|
||||||
|
|
||||||
|
$query = $this->db->prepare($sql);
|
||||||
|
$query->execute();
|
||||||
|
|
||||||
|
return $query->fetchAll(PDO::FETCH_ASSOC);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
?>
|
|
@ -0,0 +1,96 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
class Config {
|
||||||
|
|
||||||
|
public function getPlatformDetails($config, $platform_id) {
|
||||||
|
$platformDetails = $config['platforms'][$platform_id];
|
||||||
|
return $platformDetails;
|
||||||
|
}
|
||||||
|
|
||||||
|
// loading the config.js
|
||||||
|
public function getPlatformConfigjs($platformDetails, $raw = false) {
|
||||||
|
// constructing the URL
|
||||||
|
$configjsFile = $platformDetails['jitsi_url'] . '/config.js';
|
||||||
|
|
||||||
|
// default content, if we can't get the file contents
|
||||||
|
$platformConfigjs = "The file $configjsFile can't be loaded.";
|
||||||
|
|
||||||
|
// ssl options
|
||||||
|
$contextOptions = [
|
||||||
|
'ssl' => [
|
||||||
|
'verify_peer' => true,
|
||||||
|
'verify_peer_name' => true,
|
||||||
|
],
|
||||||
|
];
|
||||||
|
$context = stream_context_create($contextOptions);
|
||||||
|
|
||||||
|
// get the file
|
||||||
|
$fileContent = @file_get_contents($configjsFile, false, $context);
|
||||||
|
|
||||||
|
if ($fileContent !== false) {
|
||||||
|
|
||||||
|
// when we need only uncommented values
|
||||||
|
if ($raw === false) {
|
||||||
|
// remove block comments
|
||||||
|
$platformConfigjs = preg_replace('!/\*.*?\*/!s', '', $fileContent);
|
||||||
|
// remove single-line comments
|
||||||
|
$platformConfigjs = preg_replace('/\/\/[^\n]*/', '', $platformConfigjs);
|
||||||
|
// remove empty lines
|
||||||
|
$platformConfigjs = preg_replace('/^\s*[\r\n]/m', '', $platformConfigjs);
|
||||||
|
|
||||||
|
// when we need the full file as it is
|
||||||
|
} else {
|
||||||
|
$platformConfigjs = $fileContent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $platformConfigjs;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// loading the interface_config.js
|
||||||
|
public function getPlatformInterfaceConfigjs($platformDetails, $raw = false) {
|
||||||
|
// constructing the URL
|
||||||
|
$interfaceConfigjsFile = $platformDetails['jitsi_url'] . '/interface_config.js';
|
||||||
|
|
||||||
|
// default content, if we can't get the file contents
|
||||||
|
$platformInterfaceConfigjs = "The file $interfaceConfigjsFile can't be loaded.";
|
||||||
|
|
||||||
|
// ssl options
|
||||||
|
$contextOptions = [
|
||||||
|
'ssl' => [
|
||||||
|
'verify_peer' => true,
|
||||||
|
'verify_peer_name' => true,
|
||||||
|
],
|
||||||
|
];
|
||||||
|
$context = stream_context_create($contextOptions);
|
||||||
|
|
||||||
|
// get the file
|
||||||
|
$fileContent = @file_get_contents($interfaceConfigjsFile, false, $context);
|
||||||
|
|
||||||
|
if ($fileContent !== false) {
|
||||||
|
|
||||||
|
// when we need only uncommented values
|
||||||
|
if ($raw === false) {
|
||||||
|
// remove block comments
|
||||||
|
$platformInterfaceConfigjs = preg_replace('!/\*.*?\*/!s', '', $fileContent);
|
||||||
|
// remove single-line comments
|
||||||
|
$platformInterfaceConfigjs = preg_replace('/\/\/[^\n]*/', '', $platformInterfaceConfigjs);
|
||||||
|
// remove empty lines
|
||||||
|
$platformInterfaceConfigjs = preg_replace('/^\s*[\r\n]/m', '', $platformInterfaceConfigjs);
|
||||||
|
|
||||||
|
// when we need the full file as it is
|
||||||
|
} else {
|
||||||
|
$platformInterfaceConfigjs = $fileContent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $platformInterfaceConfigjs;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
?>
|
|
@ -0,0 +1,79 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
require '../app/helpers/errors.php';
|
||||||
|
|
||||||
|
class Database {
|
||||||
|
private $pdo;
|
||||||
|
|
||||||
|
public function __construct($options) {
|
||||||
|
// pdo needed
|
||||||
|
if ( !extension_loaded('pdo') ) {
|
||||||
|
$error = getError('PDO extension not loaded.');
|
||||||
|
}
|
||||||
|
|
||||||
|
// options check
|
||||||
|
if (empty($options['type'])) {
|
||||||
|
$error = getError('Database type is not set.');
|
||||||
|
}
|
||||||
|
|
||||||
|
// database type
|
||||||
|
switch ($options['type']) {
|
||||||
|
case 'sqlite':
|
||||||
|
$this->connectSqlite($options);
|
||||||
|
break;
|
||||||
|
case 'mysql' || 'mariadb':
|
||||||
|
$this->connectMysql($options);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
$error = getError("Database type \"{$options['type']}\" is not supported.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private function connectSqlite($options) {
|
||||||
|
// pdo_sqlite extension is needed
|
||||||
|
if (!extension_loaded('pdo_sqlite')) {
|
||||||
|
$error = getError('PDO extension for SQLite not loaded.');
|
||||||
|
}
|
||||||
|
|
||||||
|
// SQLite options
|
||||||
|
if (empty($options['dbFile']) || !file_exists($options['dbFile'])) {
|
||||||
|
$error = getError("SQLite database file \"{$dbFile}\" not found.");
|
||||||
|
}
|
||||||
|
|
||||||
|
// connect to SQLite
|
||||||
|
try {
|
||||||
|
$this->pdo = new PDO("sqlite:" . $options['dbFile']);
|
||||||
|
$this->pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
|
||||||
|
} catch (PDOException $e) {
|
||||||
|
$error = getError('SQLite connection failed: ', $e->getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private function connectMysql($options) {
|
||||||
|
// pdo_mysql extension is needed
|
||||||
|
if (!extension_loaded('pdo_mysql')) {
|
||||||
|
$error = getError('PDO extension for MySQL not loaded.');
|
||||||
|
}
|
||||||
|
|
||||||
|
// MySQL options
|
||||||
|
if (empty($options['host']) || empty($options['dbname']) || empty($options['user'])) {
|
||||||
|
$error = getError('MySQL connection data is missing.');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Connect to MySQL
|
||||||
|
try {
|
||||||
|
$dsn = "mysql:host={$options['host']};port={$options['port']};dbname={$options['dbname']};charset=utf8";
|
||||||
|
$this->pdo = new PDO($dsn, $options['user'], $options['password'] ?? '');
|
||||||
|
$this->pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
|
||||||
|
} catch (PDOException $e) {
|
||||||
|
$error = getError('MySQL connection failed: ', $config['environment'], $e->getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getConnection() {
|
||||||
|
return $this->pdo;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
?>
|
|
@ -0,0 +1,295 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
class Participant {
|
||||||
|
private $db;
|
||||||
|
|
||||||
|
public function __construct($database) {
|
||||||
|
$this->db = $database->getConnection();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// search/list specific participant ID
|
||||||
|
public function conferenceByParticipantId($participant_id, $from_time, $until_time) {
|
||||||
|
|
||||||
|
// time period drill-down
|
||||||
|
// FIXME make it similar to the bash version
|
||||||
|
if (empty($from_time)) {
|
||||||
|
$from_time = '0000-01-01';
|
||||||
|
}
|
||||||
|
if (empty($until_time)) {
|
||||||
|
$until_time = '9999-12-31';
|
||||||
|
}
|
||||||
|
|
||||||
|
// this is needed for compatibility with the bash version, so we use '%s' placeholders
|
||||||
|
$from_time = htmlspecialchars(strip_tags($from_time));
|
||||||
|
$until_time = htmlspecialchars(strip_tags($until_time));
|
||||||
|
|
||||||
|
// list conferences where participant ID (endpoint_id) is found
|
||||||
|
$sql = "
|
||||||
|
SELECT
|
||||||
|
pe.time,
|
||||||
|
c.conference_id,
|
||||||
|
c.conference_name,
|
||||||
|
c.conference_host,
|
||||||
|
pe.loglevel,
|
||||||
|
pe.event_type,
|
||||||
|
p.endpoint_id AS participant_id,
|
||||||
|
pe.event_param
|
||||||
|
FROM
|
||||||
|
conferences c
|
||||||
|
LEFT JOIN
|
||||||
|
conference_events ce ON c.conference_id = ce.conference_id
|
||||||
|
LEFT JOIN
|
||||||
|
participants p ON c.conference_id = p.conference_id
|
||||||
|
LEFT JOIN
|
||||||
|
participant_events pe ON p.endpoint_id = pe.participant_id
|
||||||
|
WHERE
|
||||||
|
p.endpoint_id = '%s'
|
||||||
|
AND (pe.time >= '%s 00:00:00' AND pe.time <= '%s 23:59:59')
|
||||||
|
|
||||||
|
UNION
|
||||||
|
|
||||||
|
SELECT
|
||||||
|
ce.time AS event_time,
|
||||||
|
c.conference_id,
|
||||||
|
c.conference_name,
|
||||||
|
c.conference_host,
|
||||||
|
ce.loglevel,
|
||||||
|
ce.conference_event AS event_type,
|
||||||
|
NULL AS participant_id,
|
||||||
|
ce.conference_param AS event_param
|
||||||
|
FROM
|
||||||
|
conferences c
|
||||||
|
LEFT JOIN
|
||||||
|
conference_events ce ON c.conference_id = ce.conference_id
|
||||||
|
WHERE
|
||||||
|
participant_id = '%s'
|
||||||
|
AND (event_time >= '%s 00:00:00' AND event_time <= '%s 23:59:59')
|
||||||
|
|
||||||
|
ORDER BY
|
||||||
|
pe.time";
|
||||||
|
|
||||||
|
$sql = sprintf($sql, $participant_id, $from_time, $until_time, $participant_id, $from_time, $until_time);
|
||||||
|
|
||||||
|
$query = $this->db->prepare($sql);
|
||||||
|
$query->execute();
|
||||||
|
|
||||||
|
return $query->fetchAll(PDO::FETCH_ASSOC);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// search/list specific participant name (stats_id)
|
||||||
|
public function conferenceByParticipantName($participant_name, $from_time, $until_time) {
|
||||||
|
|
||||||
|
// time period drill-down
|
||||||
|
// FIXME make it similar to the bash version
|
||||||
|
if (empty($from_time)) {
|
||||||
|
$from_time = '0000-01-01';
|
||||||
|
}
|
||||||
|
if (empty($until_time)) {
|
||||||
|
$until_time = '9999-12-31';
|
||||||
|
}
|
||||||
|
|
||||||
|
// this is needed for compatibility with the bash version, so we use '%s' placeholders
|
||||||
|
$from_time = htmlspecialchars(strip_tags($from_time));
|
||||||
|
$until_time = htmlspecialchars(strip_tags($until_time));
|
||||||
|
|
||||||
|
// list conferences where participant name (stats_id) is found
|
||||||
|
$sql = "
|
||||||
|
SELECT
|
||||||
|
pe.time,
|
||||||
|
c.conference_id,
|
||||||
|
c.conference_name,
|
||||||
|
c.conference_host,
|
||||||
|
pe.loglevel,
|
||||||
|
pe.event_type,
|
||||||
|
p.endpoint_id AS participant_id,
|
||||||
|
pe.event_param
|
||||||
|
FROM
|
||||||
|
conferences c
|
||||||
|
LEFT JOIN
|
||||||
|
conference_events ce ON c.conference_id = ce.conference_id
|
||||||
|
LEFT JOIN
|
||||||
|
participants p ON c.conference_id = p.conference_id
|
||||||
|
LEFT JOIN
|
||||||
|
participant_events pe ON p.endpoint_id = pe.participant_id
|
||||||
|
WHERE
|
||||||
|
pe.event_type = 'stats_id' AND pe.event_param LIKE '%%%s%%'
|
||||||
|
AND (pe.time >= '%s 00:00:00' AND pe.time <= '%s 23:59:59')
|
||||||
|
|
||||||
|
UNION
|
||||||
|
|
||||||
|
SELECT
|
||||||
|
ce.time AS event_time,
|
||||||
|
c.conference_id,
|
||||||
|
c.conference_name,
|
||||||
|
c.conference_host,
|
||||||
|
ce.loglevel,
|
||||||
|
ce.conference_event AS event_type,
|
||||||
|
NULL AS participant_id,
|
||||||
|
ce.conference_param AS event_param
|
||||||
|
FROM
|
||||||
|
conferences c
|
||||||
|
LEFT JOIN
|
||||||
|
conference_events ce ON c.conference_id = ce.conference_id
|
||||||
|
WHERE
|
||||||
|
event_type = 'stats_id' AND event_param LIKE '%%%s%%'
|
||||||
|
AND (event_time >= '%s 00:00:00' AND event_time <= '%s 23:59:59')
|
||||||
|
|
||||||
|
ORDER BY
|
||||||
|
pe.time";
|
||||||
|
|
||||||
|
$sql = sprintf($sql, $participant_name, $from_time, $until_time, $participant_name, $from_time, $until_time);
|
||||||
|
|
||||||
|
$query = $this->db->prepare($sql);
|
||||||
|
$query->execute();
|
||||||
|
|
||||||
|
return $query->fetchAll(PDO::FETCH_ASSOC);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// search/list specific participant IP
|
||||||
|
public function conferenceByParticipantIP($participant_ip, $from_time, $until_time) {
|
||||||
|
|
||||||
|
// time period drill-down
|
||||||
|
// FIXME make it similar to the bash version
|
||||||
|
if (empty($from_time)) {
|
||||||
|
$from_time = '0000-01-01';
|
||||||
|
}
|
||||||
|
if (empty($until_time)) {
|
||||||
|
$until_time = '9999-12-31';
|
||||||
|
}
|
||||||
|
|
||||||
|
// this is needed for compatibility with the bash version, so we use '%s' placeholders
|
||||||
|
$from_time = htmlspecialchars(strip_tags($from_time));
|
||||||
|
$until_time = htmlspecialchars(strip_tags($until_time));
|
||||||
|
|
||||||
|
// list conferences where participant IP is found
|
||||||
|
$sql = "
|
||||||
|
SELECT
|
||||||
|
pe.time,
|
||||||
|
c.conference_id,
|
||||||
|
c.conference_name,
|
||||||
|
c.conference_host,
|
||||||
|
pe.loglevel,
|
||||||
|
pe.event_type,
|
||||||
|
p.endpoint_id AS participant_id,
|
||||||
|
pe.event_param
|
||||||
|
FROM
|
||||||
|
conferences c
|
||||||
|
LEFT JOIN
|
||||||
|
conference_events ce ON c.conference_id = ce.conference_id
|
||||||
|
LEFT JOIN
|
||||||
|
participants p ON c.conference_id = p.conference_id
|
||||||
|
LEFT JOIN
|
||||||
|
participant_events pe ON p.endpoint_id = pe.participant_id
|
||||||
|
WHERE
|
||||||
|
pe.event_type = 'pair selected' AND pe.event_param = '%s'
|
||||||
|
AND (pe.time >= '%s 00:00:00' AND pe.time <= '%s 23:59:59')
|
||||||
|
|
||||||
|
UNION
|
||||||
|
|
||||||
|
SELECT
|
||||||
|
ce.time AS event_time,
|
||||||
|
c.conference_id,
|
||||||
|
c.conference_name,
|
||||||
|
c.conference_host,
|
||||||
|
ce.loglevel,
|
||||||
|
ce.conference_event AS event_type,
|
||||||
|
NULL AS participant_id,
|
||||||
|
ce.conference_param AS event_param
|
||||||
|
FROM
|
||||||
|
conferences c
|
||||||
|
LEFT JOIN
|
||||||
|
conference_events ce ON c.conference_id = ce.conference_id
|
||||||
|
WHERE
|
||||||
|
event_type = 'pair selected' AND event_param = '%s'
|
||||||
|
AND (event_time >= '%s 00:00:00' AND event_time <= '%s 23:59:59')
|
||||||
|
|
||||||
|
ORDER BY
|
||||||
|
pe.time";
|
||||||
|
|
||||||
|
$sql = sprintf($sql, $participant_ip, $from_time, $until_time, $participant_ip, $from_time, $until_time);
|
||||||
|
|
||||||
|
$query = $this->db->prepare($sql);
|
||||||
|
$query->execute();
|
||||||
|
|
||||||
|
return $query->fetchAll(PDO::FETCH_ASSOC);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// list of all participants
|
||||||
|
public function participantsAll($from_time, $until_time) {
|
||||||
|
|
||||||
|
// time period drill-down
|
||||||
|
// FIXME make it similar to the bash version
|
||||||
|
if (empty($from_time)) {
|
||||||
|
$from_time = '0000-01-01';
|
||||||
|
}
|
||||||
|
if (empty($until_time)) {
|
||||||
|
$until_time = '9999-12-31';
|
||||||
|
}
|
||||||
|
|
||||||
|
// this is needed for compatibility with the bash version, so we use '%s' placeholders
|
||||||
|
$from_time = htmlspecialchars(strip_tags($from_time));
|
||||||
|
$until_time = htmlspecialchars(strip_tags($until_time));
|
||||||
|
|
||||||
|
// list all participants
|
||||||
|
$sql = "
|
||||||
|
SELECT DISTINCT
|
||||||
|
p.jitsi_component, p.endpoint_id, p.conference_id
|
||||||
|
FROM
|
||||||
|
participants p
|
||||||
|
JOIN
|
||||||
|
participant_events pe ON p.endpoint_id = pe.participant_id
|
||||||
|
WHERE
|
||||||
|
pe.time >= '%s 00:00:00' AND pe.time <= '%s 23:59:59'
|
||||||
|
ORDER BY p.id";
|
||||||
|
|
||||||
|
$sql = sprintf($sql, $from_time, $until_time);
|
||||||
|
|
||||||
|
$query = $this->db->prepare($sql);
|
||||||
|
$query->execute();
|
||||||
|
|
||||||
|
return $query->fetchAll(PDO::FETCH_ASSOC);
|
||||||
|
}
|
||||||
|
|
||||||
|
// number of participants
|
||||||
|
public function participantNumber($from_time, $until_time) {
|
||||||
|
|
||||||
|
// time period drill-down
|
||||||
|
// FIXME make it similar to the bash version
|
||||||
|
if (empty($from_time)) {
|
||||||
|
$from_time = '0000-01-01';
|
||||||
|
}
|
||||||
|
if (empty($until_time)) {
|
||||||
|
$until_time = '9999-12-31';
|
||||||
|
}
|
||||||
|
|
||||||
|
// this is needed for compatibility with the bash version, so we use '%s' placeholders
|
||||||
|
$from_time = htmlspecialchars(strip_tags($from_time));
|
||||||
|
$until_time = htmlspecialchars(strip_tags($until_time));
|
||||||
|
|
||||||
|
// number of participants for time period (if given)
|
||||||
|
$sql = "
|
||||||
|
SELECT COUNT(DISTINCT p.endpoint_id) as participants
|
||||||
|
FROM
|
||||||
|
participants p
|
||||||
|
LEFT JOIN
|
||||||
|
participant_events pe ON p.endpoint_id = pe.participant_id
|
||||||
|
WHERE
|
||||||
|
(pe.time >= '%s 00:00:00' AND pe.time <= '%s 23:59:59')
|
||||||
|
AND pe.event_type = 'participant joining'";
|
||||||
|
|
||||||
|
$sql = sprintf($sql, $from_time, $until_time);
|
||||||
|
|
||||||
|
$query = $this->db->prepare($sql);
|
||||||
|
$query->execute();
|
||||||
|
|
||||||
|
return $query->fetchAll(PDO::FETCH_ASSOC);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
?>
|
|
@ -0,0 +1,38 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
class Router {
|
||||||
|
|
||||||
|
private $routes = [];
|
||||||
|
|
||||||
|
public function add() {
|
||||||
|
$this->routes[$pattern] = $callback;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function dispatch($url) {
|
||||||
|
// remove variables from url
|
||||||
|
$url = strtok($url, '?');
|
||||||
|
|
||||||
|
foreach ($this->routes as $pattern => $callback) {
|
||||||
|
if (preg_match('#^' . $pattern . '$#', $url, $matches)) {
|
||||||
|
// move any exact match
|
||||||
|
array_shift($matches);
|
||||||
|
return $this->invoke($callback, $matches);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// if there was no match at all, return 404
|
||||||
|
http_response_code(404);
|
||||||
|
echo '404 page not found';
|
||||||
|
}
|
||||||
|
|
||||||
|
private function invoke($callback, $params) {
|
||||||
|
list($controllerName, $methodName) = explode('@', $callback);
|
||||||
|
// $controllerClass = "\\App\\Controllers\\$controllerName";
|
||||||
|
$controllerClass = "../pages/$pageName";
|
||||||
|
$controller = new $controllerClass();
|
||||||
|
call_user_func_array([$controller, $methodName], $params);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
?>
|
|
@ -0,0 +1,57 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
return [
|
||||||
|
|
||||||
|
//*******************
|
||||||
|
// edit to customize
|
||||||
|
//*******************
|
||||||
|
|
||||||
|
// domain for the web app
|
||||||
|
'domain' => 'localhost',
|
||||||
|
// subfolder for the web app, if any
|
||||||
|
'folder' => '/jilo-web/',
|
||||||
|
// set to false to disable new registrations
|
||||||
|
'registration_enabled' => true,
|
||||||
|
// will be displayed on login screen
|
||||||
|
'login_message' => '',
|
||||||
|
|
||||||
|
//*******************************************
|
||||||
|
// edit only if needed for tests or debugging
|
||||||
|
//*******************************************
|
||||||
|
|
||||||
|
// database
|
||||||
|
'db' => [
|
||||||
|
// DB type for the web app, currently only "sqlite" is used
|
||||||
|
'db_type' => 'sqlite',
|
||||||
|
// default is ../app/jilo-web.db
|
||||||
|
'sqlite_file' => '../app/jilo-web.db',
|
||||||
|
],
|
||||||
|
// system info
|
||||||
|
'version' => '0.2',
|
||||||
|
// development has verbose error messages, production has not
|
||||||
|
'environment' => 'development',
|
||||||
|
|
||||||
|
// *************************************
|
||||||
|
// Maintained by the app, edit with care
|
||||||
|
// *************************************
|
||||||
|
|
||||||
|
'platforms' => [
|
||||||
|
'0' => [
|
||||||
|
'name' => 'lindeas',
|
||||||
|
'jitsi_url' => 'https://meet.lindeas.com',
|
||||||
|
'jilo_database' => '../../jilo/jilo-meet.lindeas.db',
|
||||||
|
],
|
||||||
|
'1' => [
|
||||||
|
'name' => 'meet.example.com',
|
||||||
|
'jitsi_url' => 'https://meet.example.com',
|
||||||
|
'jilo_database' => '../../jilo/jilo.db',
|
||||||
|
],
|
||||||
|
'2' => [
|
||||||
|
'name' => 'test3',
|
||||||
|
'jitsi_url' => 'https://test3.example.com',
|
||||||
|
'jilo_database' => '../../jilo/jilo2.db',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
];
|
||||||
|
|
||||||
|
?>
|
|
@ -0,0 +1,25 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
// Function to format arrays with square brackets
|
||||||
|
function formatArray(array $array, $indentLevel = 2) {
|
||||||
|
$indent = str_repeat(' ', $indentLevel); // 4 spaces per indent level
|
||||||
|
$output = "[\n";
|
||||||
|
|
||||||
|
foreach ($array as $key => $value) {
|
||||||
|
$output .= $indent . "'" . $key . "'" . ' => ';
|
||||||
|
|
||||||
|
if (is_array($value)) {
|
||||||
|
$output .= formatArray($value, $indentLevel + 1);
|
||||||
|
} else {
|
||||||
|
$output .= var_export($value, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
$output .= ",\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
$output .= str_repeat(' ', $indentLevel - 1) . ']';
|
||||||
|
|
||||||
|
return $output;
|
||||||
|
}
|
||||||
|
|
||||||
|
?>
|
|
@ -0,0 +1,67 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
// connect to database
|
||||||
|
function connectDB($config, $database = '', $platform_id = '') {
|
||||||
|
|
||||||
|
// connecting ti a jilo sqlite database
|
||||||
|
if ($database === 'jilo') {
|
||||||
|
try {
|
||||||
|
$dbFile = $config['platforms'][$platform_id]['jilo_database'] ?? null;
|
||||||
|
if (!$dbFile || !file_exists($dbFile)) {
|
||||||
|
throw new Exception(getError("Invalid platform ID \"{$platform_id}\", database file \"{$dbFile}\"not found."));
|
||||||
|
}
|
||||||
|
$db = new Database([
|
||||||
|
'type' => 'sqlite',
|
||||||
|
'dbFile' => $dbFile,
|
||||||
|
]);
|
||||||
|
} catch (Exception $e) {
|
||||||
|
$error = getError('Error connecting to DB.', $e->getMessage());
|
||||||
|
include '../app/templates/block-message.php';
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
|
||||||
|
// connecting to a jilo-web database of the web app
|
||||||
|
} else {
|
||||||
|
|
||||||
|
// sqlite database file
|
||||||
|
if ($config['db']['db_type'] === 'sqlite') {
|
||||||
|
try {
|
||||||
|
$db = new Database([
|
||||||
|
'type' => $config['db']['db_type'],
|
||||||
|
'dbFile' => $config['db']['sqlite_file'],
|
||||||
|
]);
|
||||||
|
$pdo = $db->getConnection();
|
||||||
|
} catch (Exception $e) {
|
||||||
|
$error = getError('Error connecting to DB.', $e->getMessage());
|
||||||
|
include '../app/templates/block-message.php';
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
// mysql/mariadb database
|
||||||
|
} elseif ($config['db']['db_type'] === 'mysql' || $config['db']['db_type'] === 'mariadb') {
|
||||||
|
try {
|
||||||
|
$db = new Database([
|
||||||
|
'type' => $config['db']['db_type'],
|
||||||
|
'host' => $config['db']['sql_host'] ?? 'localhost',
|
||||||
|
'port' => $config['db']['sql_port'] ?? '3306',
|
||||||
|
'dbname' => $config['db']['sql_database'],
|
||||||
|
'user' => $config['db']['sql_username'],
|
||||||
|
'password' => $config['db']['sql_password'],
|
||||||
|
]);
|
||||||
|
$pdo = $db->getConnection();
|
||||||
|
} catch (Exception $e) {
|
||||||
|
$error = getError('Error connecting to DB.', $e->getMessage());
|
||||||
|
include '../app/templates/block-message.php';
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
// unknown database
|
||||||
|
} else {
|
||||||
|
$error = "Error: unknow database type \"{$config['db']['db_type']}\"";
|
||||||
|
include '../app/templates/block-message.php';
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return $db;
|
||||||
|
}
|
||||||
|
?>
|
|
@ -0,0 +1,14 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
function getError($message, $error = '', $environment = null) {
|
||||||
|
global $config;
|
||||||
|
$environment = $config['environment'] ?? 'production';
|
||||||
|
|
||||||
|
if ($environment === 'production') {
|
||||||
|
return 'There was an unexpected error. Please try again.';
|
||||||
|
} else {
|
||||||
|
return $error ?: $message;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
?>
|
|
@ -0,0 +1,69 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
// render config variables array
|
||||||
|
function renderConfig($configPart, $indent, $platform=false, $parent='') {
|
||||||
|
global $app_root;
|
||||||
|
global $config;
|
||||||
|
if ($parent === 'platforms') {
|
||||||
|
?>
|
||||||
|
<div class="col-md-8 text-start">
|
||||||
|
<a class="btn btn-secondary" style="padding: 0px;" href="<?= $app_root ?>?page=config&action=add">add</a>
|
||||||
|
</div>
|
||||||
|
<div class="border bg-light" style="padding-left: <?= $indent ?>px; padding-bottom: 20px; padding-top: 20px;">
|
||||||
|
<?php } else {
|
||||||
|
?>
|
||||||
|
<div style="padding-left: <?= $indent ?>px; padding-bottom: 20px;">
|
||||||
|
<?php
|
||||||
|
}
|
||||||
|
foreach ($configPart as $config_item => $config_value) {
|
||||||
|
if ($parent === 'platforms') {
|
||||||
|
$indent = 0;
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
<div class="row mb-1" style="padding-left: <?= $indent ?>px;">
|
||||||
|
<div class="col-md-4 text-end">
|
||||||
|
<?= htmlspecialchars($config_item) ?>:
|
||||||
|
</div>
|
||||||
|
<?php
|
||||||
|
if ($parent === 'platforms') { ?>
|
||||||
|
<div class="col-md-8 text-start">
|
||||||
|
<a class="btn btn-secondary" style="padding: 2px;" href="<?= $app_root ?>?platform=<?= htmlspecialchars($config_item) ?>&page=config&action=edit">edit</a>
|
||||||
|
<?php
|
||||||
|
// we don't delete the last platform
|
||||||
|
if (count($configPart) <= 1) { ?>
|
||||||
|
<span class="btn btn-light" style="padding: 2px;" href="#" data-toggle="tooltip" data-placement="right" data-offset="30.0" title="can't delete the last platform">delete</span>
|
||||||
|
<?php } else { ?>
|
||||||
|
<a class="btn btn-danger" style="padding: 2px;" href="<?= $app_root ?>?platform=<?= htmlspecialchars($config_item) ?>&page=config&action=delete">delete</a>
|
||||||
|
<?php } ?>
|
||||||
|
</div>
|
||||||
|
<?php }
|
||||||
|
|
||||||
|
if (is_array($config_value)) {
|
||||||
|
// here we render recursively nested arrays
|
||||||
|
$indent = $indent + 50;
|
||||||
|
if ($parent === 'platforms') {
|
||||||
|
$indent = 100;
|
||||||
|
}
|
||||||
|
if ($config_item === 'platforms') {
|
||||||
|
renderConfig($config_value, $indent, $platform, 'platforms');
|
||||||
|
} else {
|
||||||
|
renderConfig($config_value, $indent, $platform);
|
||||||
|
}
|
||||||
|
$indent = 0;
|
||||||
|
} else {
|
||||||
|
// if it's not array, just display it
|
||||||
|
?>
|
||||||
|
<div class="border col-md-8 text-start">
|
||||||
|
<?= htmlspecialchars($config_value ?? '')?>
|
||||||
|
<?= $platform ?>
|
||||||
|
</div>
|
||||||
|
<?php
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
</div>
|
||||||
|
<?php
|
||||||
|
}
|
||||||
|
echo '</div>';
|
||||||
|
}
|
||||||
|
|
||||||
|
?>
|
|
@ -0,0 +1,17 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
$time_range_specified = false;
|
||||||
|
if (!isset($_REQUEST['from_time']) || (isset($_REQUEST['from_time']) && $_REQUEST['from_time'] == '')) {
|
||||||
|
$from_time = '0000-01-01';
|
||||||
|
} else {
|
||||||
|
$from_time = $_REQUEST['from_time'];
|
||||||
|
$time_range_specified = true;
|
||||||
|
}
|
||||||
|
if (!isset($_REQUEST['until_time']) || (isset($_REQUEST['until_time']) && $_REQUEST['until_time'] == '')) {
|
||||||
|
$until_time = '9999-12-31';
|
||||||
|
} else {
|
||||||
|
$until_time = $_REQUEST['until_time'];
|
||||||
|
$time_range_specified = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
?>
|
|
@ -0,0 +1,84 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
require_once '../app/classes/database.php';
|
||||||
|
require '../app/classes/component.php';
|
||||||
|
|
||||||
|
// connect to database
|
||||||
|
require '../app/helpers/database.php';
|
||||||
|
$db = connectDB($config, 'jilo', $platform_id);
|
||||||
|
|
||||||
|
// specify time range
|
||||||
|
include '../app/helpers/time_range.php';
|
||||||
|
|
||||||
|
// jitsi component events list
|
||||||
|
// we use $_REQUEST, so that both links and forms work
|
||||||
|
if (isset($_REQUEST['name']) && $_REQUEST['name'] != '') {
|
||||||
|
$jitsi_component = "'" . $_REQUEST['name'] . "'";
|
||||||
|
$component_id = 'component_id';
|
||||||
|
} elseif (isset($_REQUEST['id']) && $_REQUEST['id'] != '') {
|
||||||
|
$component_id = "'" . $_REQUEST['id'] . "'";
|
||||||
|
$jitsi_component = 'jitsi_component';
|
||||||
|
} else {
|
||||||
|
// we need the variables to use them later in sql for columnname = columnname
|
||||||
|
$jitsi_component = 'jitsi_component';
|
||||||
|
$component_id = 'component_id';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// Component events listings
|
||||||
|
//
|
||||||
|
|
||||||
|
|
||||||
|
// list of all component events (default)
|
||||||
|
$component = new Component($db);
|
||||||
|
|
||||||
|
// prepare the result
|
||||||
|
$search = $component->jitsiComponents($jitsi_component, $component_id, $from_time, $until_time);
|
||||||
|
|
||||||
|
if (!empty($search)) {
|
||||||
|
$components = array();
|
||||||
|
$components['records'] = array();
|
||||||
|
|
||||||
|
foreach ($search as $item) {
|
||||||
|
extract($item);
|
||||||
|
$component_record = array(
|
||||||
|
// assign title to the field in the array record
|
||||||
|
'component' => $jitsi_component,
|
||||||
|
'loglevel' => $loglevel,
|
||||||
|
'time' => $time,
|
||||||
|
'component ID' => $component_id,
|
||||||
|
'event' => $event_type,
|
||||||
|
'param' => $event_param,
|
||||||
|
);
|
||||||
|
// populate the result array
|
||||||
|
array_push($components['records'], $component_record);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// prepare the widget
|
||||||
|
$widget['full'] = false;
|
||||||
|
$widget['name'] = 'AllComponents';
|
||||||
|
$widget['collapsible'] = false;
|
||||||
|
$widget['collapsed'] = false;
|
||||||
|
$widget['filter'] = true;
|
||||||
|
|
||||||
|
// widget title
|
||||||
|
if (isset($_REQUEST['name']) && $_REQUEST['name'] != '') {
|
||||||
|
$widget['title'] = 'Jitsi events for component <strong>' . $_REQUEST['name'] . '</strong>';
|
||||||
|
} elseif (isset($_REQUEST['id']) && $_REQUEST['id'] != '') {
|
||||||
|
$widget['title'] = 'Jitsi events for component ID <strong>' . $_REQUEST['id'] . '</strong>';
|
||||||
|
} else {
|
||||||
|
$widget['title'] = 'Jitsi events for <strong>all components</strong>';
|
||||||
|
}
|
||||||
|
// widget records
|
||||||
|
if (!empty($components['records'])) {
|
||||||
|
$widget['full'] = true;
|
||||||
|
$widget['table_headers'] = array_keys($components['records'][0]);
|
||||||
|
$widget['table_records'] = $components['records'];
|
||||||
|
}
|
||||||
|
|
||||||
|
// display the widget
|
||||||
|
include('../app/templates/widget.php');
|
||||||
|
|
||||||
|
?>
|
|
@ -0,0 +1,133 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
require_once '../app/classes/database.php';
|
||||||
|
require '../app/classes/conference.php';
|
||||||
|
|
||||||
|
// connect to database
|
||||||
|
require '../app/helpers/database.php';
|
||||||
|
$db = connectDB($config, 'jilo', $platform_id);
|
||||||
|
|
||||||
|
// specify time range
|
||||||
|
include '../app/helpers/time_range.php';
|
||||||
|
|
||||||
|
// conference id/name are specified when searching specific conference(s)
|
||||||
|
// either id OR name, id has precedence
|
||||||
|
// we use $_REQUEST, so that both links and forms work
|
||||||
|
if (isset($_REQUEST['id']) && $_REQUEST['id'] != '') {
|
||||||
|
$conferenceId = $_REQUEST['id'];
|
||||||
|
unset($_REQUEST['name']);
|
||||||
|
unset($conferenceName);
|
||||||
|
} elseif (isset($_REQUEST['name']) && $_REQUEST['name'] != '') {
|
||||||
|
unset($conferenceId);
|
||||||
|
$conferenceName = $_REQUEST['name'];
|
||||||
|
} else {
|
||||||
|
unset($conferenceId);
|
||||||
|
unset($conferenceName);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// Conference listings
|
||||||
|
//
|
||||||
|
|
||||||
|
|
||||||
|
$conference = new Conference($db);
|
||||||
|
|
||||||
|
// search and list specific conference ID
|
||||||
|
if (isset($conferenceId)) {
|
||||||
|
$search = $conference->conferenceById($conferenceId, $from_time, $until_time);
|
||||||
|
// search and list specific conference name
|
||||||
|
} elseif (isset($conferenceName)) {
|
||||||
|
$search = $conference->conferenceByName($conferenceName, $from_time, $until_time);
|
||||||
|
// list of all conferences (default)
|
||||||
|
} else {
|
||||||
|
$search = $conference->conferencesAllFormatted($from_time, $until_time);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty($search)) {
|
||||||
|
$conferences = array();
|
||||||
|
$conferences['records'] = array();
|
||||||
|
|
||||||
|
foreach ($search as $item) {
|
||||||
|
extract($item);
|
||||||
|
|
||||||
|
// we don't have duration field, so we calculate it
|
||||||
|
if (!empty($start) && !empty($end)) {
|
||||||
|
$duration = gmdate("H:i:s", abs(strtotime($end) - strtotime($start)));
|
||||||
|
} else {
|
||||||
|
$duration = '';
|
||||||
|
}
|
||||||
|
|
||||||
|
// search and list specific conference ID
|
||||||
|
if (isset($conferenceId)) {
|
||||||
|
$conference_record = array(
|
||||||
|
// assign title to the field in the array record
|
||||||
|
'time' => $time,
|
||||||
|
'conference ID' => $conference_id,
|
||||||
|
'conference name' => $conference_name,
|
||||||
|
'conference host' => $conference_host,
|
||||||
|
'loglevel' => $loglevel,
|
||||||
|
'participant ID' => $participant_id,
|
||||||
|
'event' => $event_type,
|
||||||
|
'parameter' => $event_param
|
||||||
|
);
|
||||||
|
// search and list specific conference name
|
||||||
|
} elseif (isset($conferenceName)) {
|
||||||
|
$conference_record = array(
|
||||||
|
// assign title to the field in the array record
|
||||||
|
'time' => $time,
|
||||||
|
'conference ID' => $conference_id,
|
||||||
|
'conference name' => $conference_name,
|
||||||
|
'conference host' => $conference_host,
|
||||||
|
'loglevel' => $loglevel,
|
||||||
|
'participant ID' => $participant_id,
|
||||||
|
'event' => $event_type,
|
||||||
|
'parameter' => $event_param
|
||||||
|
);
|
||||||
|
// list of all conferences (default)
|
||||||
|
} else {
|
||||||
|
$conference_record = array(
|
||||||
|
// assign title to the field in the array record
|
||||||
|
'component' => $jitsi_component,
|
||||||
|
'start' => $start,
|
||||||
|
'end' => $end,
|
||||||
|
'duration' => $duration,
|
||||||
|
'conference ID' => $conference_id,
|
||||||
|
'conference name' => $conference_name,
|
||||||
|
'participants' => $participants,
|
||||||
|
'name count' => $name_count,
|
||||||
|
'conference host' => $conference_host
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// populate the result array
|
||||||
|
array_push($conferences['records'], $conference_record);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// prepare the widget
|
||||||
|
$widget['full'] = false;
|
||||||
|
$widget['name'] = 'Conferences';
|
||||||
|
$widget['collapsible'] = false;
|
||||||
|
$widget['collapsed'] = false;
|
||||||
|
$widget['filter'] = true;
|
||||||
|
|
||||||
|
// widget title
|
||||||
|
if (isset($_REQUEST['name']) && $_REQUEST['name'] != '') {
|
||||||
|
$widget['title'] = 'Conferences with name matching "<strong>' . $_REQUEST['name'] . '"</strong>';
|
||||||
|
} elseif (isset($_REQUEST['id']) && $_REQUEST['id'] != '') {
|
||||||
|
$widget['title'] = 'Conference with ID "<strong>' . $_REQUEST['id'] . '"</strong>';
|
||||||
|
} else {
|
||||||
|
$widget['title'] = 'All conferences';
|
||||||
|
}
|
||||||
|
// widget records
|
||||||
|
if (!empty($conferences['records'])) {
|
||||||
|
$widget['full'] = true;
|
||||||
|
$widget['table_headers'] = array_keys($conferences['records'][0]);
|
||||||
|
$widget['table_records'] = $conferences['records'];
|
||||||
|
}
|
||||||
|
|
||||||
|
// display the widget
|
||||||
|
include('../app/templates/widget.php');
|
||||||
|
|
||||||
|
?>
|
|
@ -0,0 +1,140 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
$action = $_REQUEST['action'] ?? '';
|
||||||
|
require_once '../app/classes/config.php';
|
||||||
|
require '../app/helpers/errors.php';
|
||||||
|
require '../app/helpers/config.php';
|
||||||
|
|
||||||
|
$configure = new Config();
|
||||||
|
|
||||||
|
// if a form is submitted, it's from the edit page
|
||||||
|
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
|
||||||
|
|
||||||
|
// load the config file and initialize a copy
|
||||||
|
$content = file_get_contents($config_file);
|
||||||
|
$updatedContent = $content;
|
||||||
|
|
||||||
|
// new platform adding
|
||||||
|
if (isset($_POST['new']) && $_POST['new'] === 'true') {
|
||||||
|
$newPlatform = [
|
||||||
|
'name' => $_POST['name'],
|
||||||
|
'jitsi_url' => $_POST['jitsi_url'],
|
||||||
|
'jilo_database' => $_POST['jilo_database'],
|
||||||
|
];
|
||||||
|
|
||||||
|
// Determine the next available index for the new platform
|
||||||
|
$nextIndex = count($config['platforms']);
|
||||||
|
|
||||||
|
// Add the new platform to the platforms array
|
||||||
|
$config['platforms'][$nextIndex] = $newPlatform;
|
||||||
|
|
||||||
|
// Rebuild the PHP array syntax for the platforms
|
||||||
|
$platformsArray = formatArray($config['platforms']);
|
||||||
|
|
||||||
|
// Replace the platforms section in the config file
|
||||||
|
$updatedContent = preg_replace(
|
||||||
|
'/\'platforms\'\s*=>\s*\[[\s\S]+?\],/s',
|
||||||
|
"'platforms' => {$platformsArray}",
|
||||||
|
$content
|
||||||
|
);
|
||||||
|
$updatedContent = preg_replace('/\s*\]\n/s', "\n", $updatedContent);
|
||||||
|
|
||||||
|
// deleting a platform
|
||||||
|
} elseif (isset($_POST['delete']) && $_POST['delete'] === 'true') {
|
||||||
|
$platform = $_POST['platform'];
|
||||||
|
|
||||||
|
$config['platforms'][$platform]['name'] = $_POST['name'];
|
||||||
|
$config['platforms'][$platform]['jitsi_url'] = $_POST['jitsi_url'];
|
||||||
|
$config['platforms'][$platform]['jilo_database'] = $_POST['jilo_database'];
|
||||||
|
|
||||||
|
$platformsArray = formatArray($config['platforms'][$platform], 3);
|
||||||
|
|
||||||
|
$updatedContent = preg_replace(
|
||||||
|
"/\s*'$platform'\s*=>\s*\[\s*'name'\s*=>\s*'[^']*',\s*'jitsi_url'\s*=>\s*'[^']*,\s*'jilo_database'\s*=>\s*'[^']*',\s*\],/s",
|
||||||
|
"",
|
||||||
|
$content
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
// an update to an existing platform
|
||||||
|
} else {
|
||||||
|
|
||||||
|
$platform = $_POST['platform'];
|
||||||
|
|
||||||
|
$config['platforms'][$platform]['name'] = $_POST['name'];
|
||||||
|
$config['platforms'][$platform]['jitsi_url'] = $_POST['jitsi_url'];
|
||||||
|
$config['platforms'][$platform]['jilo_database'] = $_POST['jilo_database'];
|
||||||
|
|
||||||
|
$platformsArray = formatArray($config['platforms'][$platform], 3);
|
||||||
|
|
||||||
|
$updatedContent = preg_replace(
|
||||||
|
"/\s*'$platform'\s*=>\s*\[\s*'name'\s*=>\s*'[^']*',\s*'jitsi_url'\s*=>\s*'[^']*',\s*'jilo_database'\s*=>\s*'[^']*',\s*\],/s",
|
||||||
|
"\n '{$platform}' => {$platformsArray},",
|
||||||
|
$content
|
||||||
|
);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// check if file is writable
|
||||||
|
if (!is_writable($config_file)) {
|
||||||
|
$_SESSION['error'] = getError('Configuration file is not writable.');
|
||||||
|
header("Location: $app_root?platform=$platform_id&page=config");
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
|
||||||
|
// try to update the config file
|
||||||
|
if (file_put_contents($config_file, $updatedContent) !== false) {
|
||||||
|
// update successful
|
||||||
|
$_SESSION['notice'] = "Configuration for {$_POST['name']} is updated.";
|
||||||
|
} else {
|
||||||
|
// unsuccessful
|
||||||
|
$error = error_get_last();
|
||||||
|
$_SESSION['error'] = getError('Error updating the config: ' . ($error['message'] ?? 'unknown error'));
|
||||||
|
}
|
||||||
|
|
||||||
|
// FIXME the new file is not loaded on first page load
|
||||||
|
unset($config);
|
||||||
|
header("Location: $app_root?platform=$platform_id&page=config");
|
||||||
|
exit();
|
||||||
|
|
||||||
|
// no form submitted, show the templates
|
||||||
|
} else {
|
||||||
|
|
||||||
|
// $item - config.js and interface_config.js are special case; remote loaded files
|
||||||
|
switch ($item) {
|
||||||
|
case 'configjs':
|
||||||
|
$mode = $_REQUEST['mode'] ?? '';
|
||||||
|
$raw = ($mode === 'raw');
|
||||||
|
$platformDetails = $configure->getPlatformDetails($config, $platform_id);
|
||||||
|
$platformConfigjs = $configure->getPlatformConfigjs($platformDetails, $raw);
|
||||||
|
include('../app/templates/config-list-configjs.php');
|
||||||
|
break;
|
||||||
|
case 'interfaceconfigjs':
|
||||||
|
$mode = $_REQUEST['mode'] ?? '';
|
||||||
|
$raw = ($mode === 'raw');
|
||||||
|
$platformDetails = $configure->getPlatformDetails($config, $platform_id);
|
||||||
|
$platformInterfaceConfigjs = $configure->getPlatformInterfaceConfigjs($platformDetails, $raw);
|
||||||
|
include('../app/templates/config-list-interfaceconfigjs.php');
|
||||||
|
break;
|
||||||
|
|
||||||
|
// if there is no $item, we work on the local config file
|
||||||
|
default:
|
||||||
|
switch ($action) {
|
||||||
|
case 'add':
|
||||||
|
include('../app/templates/config-add-platform.php');
|
||||||
|
break;
|
||||||
|
case 'edit':
|
||||||
|
include('../app/templates/config-edit-platform.php');
|
||||||
|
break;
|
||||||
|
case 'delete':
|
||||||
|
include('../app/templates/config-delete-platform.php');
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
include('../app/templates/config-list.php');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
?>
|
|
@ -0,0 +1,204 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
require_once '../app/classes/database.php';
|
||||||
|
require '../app/classes/conference.php';
|
||||||
|
require '../app/classes/participant.php';
|
||||||
|
|
||||||
|
// connect to database
|
||||||
|
require '../app/helpers/database.php';
|
||||||
|
$db = connectDB($config, 'jilo', $platform_id);
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// dashboard widget listings
|
||||||
|
//
|
||||||
|
|
||||||
|
|
||||||
|
////
|
||||||
|
// monthly usage
|
||||||
|
$conference = new Conference($db);
|
||||||
|
$participant = new Participant($db);
|
||||||
|
|
||||||
|
// monthly conferences for the last year
|
||||||
|
$fromMonth = (new DateTime())->sub(new DateInterval('P1Y'));
|
||||||
|
$fromMonth->modify('first day of this month');
|
||||||
|
$thisMonth = new DateTime();
|
||||||
|
$from_time = $fromMonth->format('Y-m-d');
|
||||||
|
$until_time = $thisMonth->format('Y-m-d');
|
||||||
|
|
||||||
|
$widget['records'] = array();
|
||||||
|
|
||||||
|
// loop 1 year in the past
|
||||||
|
$i = 0;
|
||||||
|
while ($fromMonth < $thisMonth) {
|
||||||
|
|
||||||
|
$untilMonth = clone $fromMonth;
|
||||||
|
$untilMonth->modify('last day of this month');
|
||||||
|
|
||||||
|
$from_time = $fromMonth->format('Y-m-d');
|
||||||
|
$until_time = $untilMonth->format('Y-m-d');
|
||||||
|
|
||||||
|
$searchConferenceNumber = $conference->conferenceNumber($from_time, $until_time);
|
||||||
|
$searchParticipantNumber = $participant->participantNumber($from_time, $until_time);
|
||||||
|
|
||||||
|
// pretty format for displaying the month in the widget
|
||||||
|
$month = $fromMonth->format('F Y');
|
||||||
|
|
||||||
|
// populate the records
|
||||||
|
$widget['records'][$i] = array(
|
||||||
|
'from_time' => $from_time,
|
||||||
|
'until_time' => $until_time,
|
||||||
|
'table_headers' => $month,
|
||||||
|
'conferences' => $searchConferenceNumber[0]['conferences'],
|
||||||
|
'participants' => $searchParticipantNumber[0]['participants'],
|
||||||
|
);
|
||||||
|
|
||||||
|
// move everything one month in future
|
||||||
|
$untilMonth->add(new DateInterval('P1M'));
|
||||||
|
$fromMonth->add(new DateInterval('P1M'));
|
||||||
|
$i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
$time_range_specified = true;
|
||||||
|
|
||||||
|
// prepare the widget
|
||||||
|
$widget['full'] = false;
|
||||||
|
$widget['name'] = 'LastYearMonths';
|
||||||
|
$widget['title'] = 'Conferences monthly stats for the last year';
|
||||||
|
$widget['collapsible'] = true;
|
||||||
|
$widget['collapsed'] = false;
|
||||||
|
$widget['filter'] = false;
|
||||||
|
if (!empty($searchConferenceNumber) && !empty($searchParticipantNumber)) {
|
||||||
|
$widget['full'] = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// display the widget
|
||||||
|
include('../app/templates/widget-monthly.php');
|
||||||
|
|
||||||
|
|
||||||
|
////
|
||||||
|
// conferences in last 2 days
|
||||||
|
$conference = new Conference($db);
|
||||||
|
|
||||||
|
// time range limit
|
||||||
|
$from_time = date('Y-m-d', time() - 60 * 60 * 24 * 2);
|
||||||
|
$until_time = date('Y-m-d', time());
|
||||||
|
$time_range_specified = true;
|
||||||
|
|
||||||
|
// prepare the result
|
||||||
|
$search = $conference->conferencesAllFormatted($from_time, $until_time);
|
||||||
|
|
||||||
|
if (!empty($search)) {
|
||||||
|
$conferences = array();
|
||||||
|
$conferences['records'] = array();
|
||||||
|
|
||||||
|
foreach ($search as $item) {
|
||||||
|
extract($item);
|
||||||
|
|
||||||
|
// we don't have duration field, so we calculate it
|
||||||
|
if (!empty($start) && !empty($end)) {
|
||||||
|
$duration = gmdate("H:i:s", abs(strtotime($end) - strtotime($start)));
|
||||||
|
} else {
|
||||||
|
$duration = '';
|
||||||
|
}
|
||||||
|
$conference_record = array(
|
||||||
|
// assign title to the field in the array record
|
||||||
|
'component' => $jitsi_component,
|
||||||
|
'start' => $start,
|
||||||
|
'end' => $end,
|
||||||
|
'duration' => $duration,
|
||||||
|
'conference ID' => $conference_id,
|
||||||
|
'conference name' => $conference_name,
|
||||||
|
'participants' => $participants,
|
||||||
|
'name count' => $name_count,
|
||||||
|
'conference host' => $conference_host
|
||||||
|
);
|
||||||
|
// populate the result array
|
||||||
|
array_push($conferences['records'], $conference_record);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// prepare the widget
|
||||||
|
$widget['full'] = false;
|
||||||
|
$widget['name'] = 'LastDays';
|
||||||
|
$widget['title'] = 'Conferences for the last 2 days';
|
||||||
|
$widget['collapsible'] = true;
|
||||||
|
$widget['collapsed'] = false;
|
||||||
|
$widget['filter'] = false;
|
||||||
|
if (!empty($conferences['records'])) {
|
||||||
|
$widget['full'] = true;
|
||||||
|
$widget['table_headers'] = array_keys($conferences['records'][0]);
|
||||||
|
$widget['table_records'] = $conferences['records'];
|
||||||
|
}
|
||||||
|
|
||||||
|
// display the widget
|
||||||
|
include('../app/templates/widget.php');
|
||||||
|
|
||||||
|
|
||||||
|
////
|
||||||
|
// last 10 conferences
|
||||||
|
$conference = new Conference($db);
|
||||||
|
|
||||||
|
// all time
|
||||||
|
$from_time = '0000-01-01';
|
||||||
|
$until_time = '9999-12-31';
|
||||||
|
$time_range_specified = false;
|
||||||
|
// number of conferences to show
|
||||||
|
$conference_number = 10;
|
||||||
|
|
||||||
|
// prepare the result
|
||||||
|
$search = $conference->conferencesAllFormatted($from_time, $until_time);
|
||||||
|
|
||||||
|
if (!empty($search)) {
|
||||||
|
$conferences = array();
|
||||||
|
$conferences['records'] = array();
|
||||||
|
|
||||||
|
$i = 0;
|
||||||
|
foreach ($search as $item) {
|
||||||
|
extract($item);
|
||||||
|
|
||||||
|
// we don't have duration field, so we calculate it
|
||||||
|
if (!empty($start) && !empty($end)) {
|
||||||
|
$duration = gmdate("H:i:s", abs(strtotime($end) - strtotime($start)));
|
||||||
|
} else {
|
||||||
|
$duration = '';
|
||||||
|
}
|
||||||
|
$conference_record = array(
|
||||||
|
// assign title to the field in the array record
|
||||||
|
'component' => $jitsi_component,
|
||||||
|
'start' => $start,
|
||||||
|
'end' => $end,
|
||||||
|
'duration' => $duration,
|
||||||
|
'conference ID' => $conference_id,
|
||||||
|
'conference name' => $conference_name,
|
||||||
|
'participants' => $participants,
|
||||||
|
'name count' => $name_count,
|
||||||
|
'conference host' => $conference_host
|
||||||
|
);
|
||||||
|
// populate the result array
|
||||||
|
array_push($conferences['records'], $conference_record);
|
||||||
|
|
||||||
|
// we only take the first 10 results
|
||||||
|
$i++;
|
||||||
|
if ($i == 10) break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// prepare the widget
|
||||||
|
$widget['full'] = false;
|
||||||
|
$widget['name'] = 'LastConferences';
|
||||||
|
$widget['title'] = 'The last ' . $conference_number . ' conferences';
|
||||||
|
$widget['collapsible'] = true;
|
||||||
|
$widget['collapsed'] = false;
|
||||||
|
$widget['filter'] = false;
|
||||||
|
|
||||||
|
if (!empty($conferences['records'])) {
|
||||||
|
$widget['full'] = true;
|
||||||
|
$widget['table_headers'] = array_keys($conferences['records'][0]);
|
||||||
|
$widget['table_records'] = $conferences['records'];
|
||||||
|
}
|
||||||
|
|
||||||
|
// display the widget
|
||||||
|
include('../app/templates/widget.php');
|
||||||
|
|
||||||
|
?>
|
|
@ -1,13 +1,17 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
require_once 'classes/database.php';
|
require_once '../app/classes/database.php';
|
||||||
require 'classes/user.php';
|
require '../app/classes/user.php';
|
||||||
|
|
||||||
// clear the global error var before login
|
// clear the global error var before login
|
||||||
unset($error);
|
unset($error);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$db = new Database($config['database']);
|
|
||||||
|
// connect to database
|
||||||
|
require '../app/helpers/database.php';
|
||||||
|
$db = connectDB($config);
|
||||||
|
|
||||||
$user = new User($db);
|
$user = new User($db);
|
||||||
|
|
||||||
if ( $_SERVER['REQUEST_METHOD'] == 'POST' ) {
|
if ( $_SERVER['REQUEST_METHOD'] == 'POST' ) {
|
||||||
|
@ -31,18 +35,6 @@ try {
|
||||||
}
|
}
|
||||||
|
|
||||||
// set session lifetime and cookies
|
// set session lifetime and cookies
|
||||||
// FIXME: need to set this before session start (otherwise we need the separate cookie)
|
|
||||||
// ini_set('session.gc_maxlifetime', $gc_maxlifetime);
|
|
||||||
// session_set_cookie_params([
|
|
||||||
// 'lifetime' => $setcookie_lifetime,
|
|
||||||
// 'samesite' => 'Strict',
|
|
||||||
// 'httponly' => true,
|
|
||||||
// 'secure' => isset($_SERVER['HTTPS']),
|
|
||||||
// 'domain' => $config['domain'],
|
|
||||||
// 'path' => $config['folder']
|
|
||||||
// ]);
|
|
||||||
// session_start();
|
|
||||||
// FIXME we use separate cookie, because the above won't work
|
|
||||||
setcookie('username', $username, [
|
setcookie('username', $username, [
|
||||||
'expires' => $setcookie_lifetime,
|
'expires' => $setcookie_lifetime,
|
||||||
'path' => $config['folder'],
|
'path' => $config['folder'],
|
||||||
|
@ -65,9 +57,14 @@ try {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (Exception $e) {
|
} catch (Exception $e) {
|
||||||
$error = $e->getMessage();
|
$error = getError('There was an unexpected error. Please try again.', $e->getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
include 'templates/form-login.php';
|
if (!empty($config['login_message'])) {
|
||||||
|
$notice = $config['login_message'];
|
||||||
|
include '../app/templates/block-message.php';
|
||||||
|
}
|
||||||
|
|
||||||
|
include '../app/templates/form-login.php';
|
||||||
|
|
||||||
?>
|
?>
|
|
@ -0,0 +1,142 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
require_once '../app/classes/database.php';
|
||||||
|
require '../app/classes/participant.php';
|
||||||
|
|
||||||
|
// connect to database
|
||||||
|
require '../app/helpers/database.php';
|
||||||
|
$db = connectDB($config, 'jilo', $platform_id);
|
||||||
|
|
||||||
|
// specify time range
|
||||||
|
include '../app/helpers/time_range.php';
|
||||||
|
|
||||||
|
// participant id/name/IP are specified when searching specific participant(s)
|
||||||
|
// participant name - this is 'stats_id' in the db
|
||||||
|
// either id, name, OR IP - in that order
|
||||||
|
// we use $_REQUEST, so that both links and forms work
|
||||||
|
if (isset($_REQUEST['id']) && $_REQUEST['id'] != '') {
|
||||||
|
$participantId = $_REQUEST['id'];
|
||||||
|
unset($_REQUEST['name']);
|
||||||
|
unset($participantName);
|
||||||
|
} elseif (isset($_REQUEST['name']) && $_REQUEST['name'] != '') {
|
||||||
|
unset($participantId);
|
||||||
|
$participantName = $_REQUEST['name'];
|
||||||
|
} elseif (isset($_REQUEST['ip']) && $_REQUEST['ip'] != '') {
|
||||||
|
unset($participantId);
|
||||||
|
$participantIp = $_REQUEST['ip'];
|
||||||
|
} else {
|
||||||
|
unset($participantId);
|
||||||
|
unset($participantName);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// Participant listings
|
||||||
|
//
|
||||||
|
|
||||||
|
$participant = new Participant($db);
|
||||||
|
|
||||||
|
// search and list specific participant ID
|
||||||
|
if (isset($participantId)) {
|
||||||
|
$search = $participant->conferenceByParticipantId($participantId, $from_time, $until_time, $participantId, $from_time, $until_time);
|
||||||
|
// search and list specific participant name (stats_id)
|
||||||
|
} elseif (isset($participantName)) {
|
||||||
|
$search = $participant->conferenceByParticipantName($participantName, $from_time, $until_time);
|
||||||
|
// search and list specific participant IP
|
||||||
|
} elseif (isset($participantIp)) {
|
||||||
|
$search = $participant->conferenceByParticipantIP($participantIp, $from_time, $until_time);
|
||||||
|
// list of all participants (default)
|
||||||
|
} else {
|
||||||
|
// prepare the result
|
||||||
|
$search = $participant->participantsAll($from_time, $until_time);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty($search)) {
|
||||||
|
$participants = array();
|
||||||
|
$participants['records'] = array();
|
||||||
|
|
||||||
|
foreach ($search as $item) {
|
||||||
|
extract($item);
|
||||||
|
|
||||||
|
// search and list specific participant ID
|
||||||
|
if (isset($participantId)) {
|
||||||
|
$participant_record = array(
|
||||||
|
// assign title to the field in the array record
|
||||||
|
'time' => $time,
|
||||||
|
'conference ID' => $conference_id,
|
||||||
|
'conference name' => $conference_name,
|
||||||
|
'conference host' => $conference_host,
|
||||||
|
'loglevel' => $loglevel,
|
||||||
|
'participant ID' => $participant_id,
|
||||||
|
'event' => $event_type,
|
||||||
|
'parameter' => $event_param
|
||||||
|
);
|
||||||
|
// search and list specific participant name (stats_id)
|
||||||
|
} elseif (isset($participantName)) {
|
||||||
|
$participant_record = array(
|
||||||
|
// assign title to the field in the array record
|
||||||
|
'time' => $time,
|
||||||
|
'conference ID' => $conference_id,
|
||||||
|
'conference name' => $conference_name,
|
||||||
|
'conference host' => $conference_host,
|
||||||
|
'loglevel' => $loglevel,
|
||||||
|
'participant ID' => $participant_id,
|
||||||
|
'event' => $event_type,
|
||||||
|
'parameter' => $event_param
|
||||||
|
);
|
||||||
|
// search and list specific participant IP
|
||||||
|
} elseif (isset($participantIp)) {
|
||||||
|
$participant_record = array(
|
||||||
|
// assign title to the field in the array record
|
||||||
|
'time' => $time,
|
||||||
|
'conference ID' => $conference_id,
|
||||||
|
'conference name' => $conference_name,
|
||||||
|
'conference host' => $conference_host,
|
||||||
|
'loglevel' => $loglevel,
|
||||||
|
'participant ID' => $participant_id,
|
||||||
|
'event' => $event_type,
|
||||||
|
'parameter' => $event_param
|
||||||
|
);
|
||||||
|
// list of all participants (default)
|
||||||
|
} else {
|
||||||
|
$participant_record = array(
|
||||||
|
// assign title to the field in the array record
|
||||||
|
'component' => $jitsi_component,
|
||||||
|
'participant ID' => $endpoint_id,
|
||||||
|
'conference ID' => $conference_id
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// populate the result array
|
||||||
|
array_push($participants['records'], $participant_record);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// prepare the widget
|
||||||
|
$widget['full'] = false;
|
||||||
|
$widget['name'] = 'Participants';
|
||||||
|
$widget['collapsible'] = false;
|
||||||
|
$widget['collapsed'] = false;
|
||||||
|
$widget['filter'] = true;
|
||||||
|
|
||||||
|
// widget title
|
||||||
|
if (isset($_REQUEST['name']) && $_REQUEST['name'] != '') {
|
||||||
|
$widget['title'] = 'Conferences with participant name (stats_id) matching "<strong>' . $_REQUEST['name'] . '"</strong>';
|
||||||
|
} elseif (isset($_REQUEST['id']) && $_REQUEST['id'] != '') {
|
||||||
|
$widget['title'] = 'Conference with participant ID matching "<strong>' . $_REQUEST['id'] . '"</strong>';
|
||||||
|
} elseif (isset($participantIp)) {
|
||||||
|
$widget['title'] = 'Conference with participant IP matching "<strong>' . $participantIp . '"</strong>';
|
||||||
|
} else {
|
||||||
|
$widget['title'] = 'All participants';
|
||||||
|
}
|
||||||
|
// widget records
|
||||||
|
if (!empty($participants['records'])) {
|
||||||
|
$widget['full'] = true;
|
||||||
|
$widget['table_headers'] = array_keys($participants['records'][0]);
|
||||||
|
$widget['table_records'] = $participants['records'];
|
||||||
|
}
|
||||||
|
|
||||||
|
// display the widget
|
||||||
|
include('../app/templates/widget.php');
|
||||||
|
|
||||||
|
?>
|
|
@ -0,0 +1,5 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
include('../app/templates/widget-profile.php');
|
||||||
|
|
||||||
|
?>
|
|
@ -0,0 +1,47 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
// registration is allowed, go on
|
||||||
|
if ($config['registration_enabled'] === true) {
|
||||||
|
|
||||||
|
require_once '../app/classes/database.php';
|
||||||
|
require '../app/classes/user.php';
|
||||||
|
unset($error);
|
||||||
|
|
||||||
|
try {
|
||||||
|
|
||||||
|
// connect to database
|
||||||
|
require '../app/helpers/database.php';
|
||||||
|
$db = connectDB($config);
|
||||||
|
|
||||||
|
$user = new User($db);
|
||||||
|
|
||||||
|
if ( $_SERVER['REQUEST_METHOD'] == 'POST' ) {
|
||||||
|
$username = $_POST['username'];
|
||||||
|
$password = $_POST['password'];
|
||||||
|
|
||||||
|
// redirect to login
|
||||||
|
if ( $user->register($username, $password) ) {
|
||||||
|
$_SESSION['notice'] = "Registration successful.<br />You can log in now.";
|
||||||
|
header('Location: index.php');
|
||||||
|
exit();
|
||||||
|
// registration fail, redirect to login
|
||||||
|
} else {
|
||||||
|
$_SESSION['error'] = "Registration failed.";
|
||||||
|
header('Location: index.php');
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception $e) {
|
||||||
|
$error = getError('There was an unexpected error. Please try again.', $e->getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
include '../app/templates/block-message.php';
|
||||||
|
include '../app/templates/form-register.php';
|
||||||
|
|
||||||
|
// registration disabled
|
||||||
|
} else {
|
||||||
|
$notice = 'Registration is disabled';
|
||||||
|
include '../app/templates/block-message.php';
|
||||||
|
}
|
||||||
|
|
||||||
|
?>
|
|
@ -0,0 +1,7 @@
|
||||||
|
<?php if (isset($error)) { ?>
|
||||||
|
<div class="error"><?php echo $error; ?></div>
|
||||||
|
<?php } ?>
|
||||||
|
|
||||||
|
<?php if (isset($notice)) { ?>
|
||||||
|
<div class="notice"><?php echo $notice; ?></div>
|
||||||
|
<?php } ?>
|
|
@ -0,0 +1,29 @@
|
||||||
|
|
||||||
|
<!-- Results filter -->
|
||||||
|
<div class="card w-auto bg-light border-light card-body text-right" style="text-align: right;">
|
||||||
|
<form method="POST" id="filter_form" action="?platform=<?= $platform_id?>&page=<?= $page ?>">
|
||||||
|
<label for="from_time">from</label>
|
||||||
|
<input type="date" id="from_time" name="from_time"<?php if (isset($_REQUEST['from_time'])) echo " value=\"" . $_REQUEST['from_time'] . "\"" ?> />
|
||||||
|
<label for="until_time">until</label>
|
||||||
|
<input type="date" id="until_time" name="until_time"<?php if (isset($_REQUEST['until_time'])) echo " value=\"" . $_REQUEST['until_time'] . "\"" ?> />
|
||||||
|
<input type="text" name="id" placeholder="ID"<?php if (isset($_REQUEST['id'])) echo " value=\"" . $_REQUEST['id'] . "\"" ?> />
|
||||||
|
<input type="text" name="name" placeholder="name"<?php if (isset($_REQUEST['name'])) echo " value=\"" . $_REQUEST['name'] . "\"" ?> />
|
||||||
|
<?php if ($page == 'participants') { ?>
|
||||||
|
<input type="text" name="ip" placeholder="ip address"<?php if (isset($_REQUEST['ip'])) echo " value=\"" . $_REQUEST['ip'] . "\"" ?> maxlength="15" size="15" />
|
||||||
|
<?php } ?>
|
||||||
|
<input type="button" onclick="clearFilter()" value="clear" />
|
||||||
|
<input type="submit" value="search" />
|
||||||
|
</form>
|
||||||
|
<script>
|
||||||
|
function clearFilter() {
|
||||||
|
document.getElementById("filter_form").reset();
|
||||||
|
const filterFields = document.querySelectorAll("#filter_form input");
|
||||||
|
filterFields.forEach(input => {
|
||||||
|
if (input.type === 'text' ||input.type === 'date') {
|
||||||
|
input.value = '';
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
</div>
|
||||||
|
<!-- /Results filter -->
|
|
@ -0,0 +1,50 @@
|
||||||
|
|
||||||
|
<!-- widget "config" -->
|
||||||
|
<div class="card text-center w-50 mx-auto">
|
||||||
|
<p class="h4 card-header">Add new Jitsi platform</p>
|
||||||
|
<div class="card-body">
|
||||||
|
<!--p class="card-text">add new platform:</p-->
|
||||||
|
<form method="POST" action="<?= $app_root ?>?platform=<?= htmlspecialchars($platform_id) ?>&page=config">
|
||||||
|
|
||||||
|
<div class="row mb-3">
|
||||||
|
<div class="col-md-4 text-end">
|
||||||
|
<label for="name" class="form-label">name</label>
|
||||||
|
<span class="text-danger" style="margin-right: -12px;">*</span>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-8">
|
||||||
|
<input class="form-control" type="text" name="name" value="" required />
|
||||||
|
<p class="text-start"><small>descriptive name for the platform</small></p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row mb-3">
|
||||||
|
<div class="col-md-4 text-end">
|
||||||
|
<label for="jitsi_url" class="form-label">Jitsi URL</label>
|
||||||
|
<span class="text-danger" style="margin-right: -12px;">*</span>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-8">
|
||||||
|
<input class="form-control" type="text" name="jitsi_url" value="https://" required />
|
||||||
|
<p class="text-start"><small>URL of the Jitsi Meet (used for checks and for loading config.js)</small></p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row mb-3">
|
||||||
|
<div class="col-md-4 text-end">
|
||||||
|
<label for="jilo_database" class="form-label">jilo_database</label>
|
||||||
|
<span class="text-danger" style="margin-right: -12px;">*</span>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-8">
|
||||||
|
<input class="form-control" type="text" name="jilo_database" value="" required />
|
||||||
|
<p class="text-start"><small>path to the database file (relative to the app root)</small></p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<input type="hidden" name="new" value="true" />
|
||||||
|
|
||||||
|
<br />
|
||||||
|
<a class="btn btn-secondary" href="<?= $app_root ?>?page=config" />Cancel</a>
|
||||||
|
<input type="submit" class="btn btn-primary" value="Save" />
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- /widget "config" -->
|
|
@ -0,0 +1,29 @@
|
||||||
|
|
||||||
|
<!-- widget "config" -->
|
||||||
|
<div class="card text-center w-50 mx-auto">
|
||||||
|
<p class="h4 card-header">Jilo web configuration for Jitsi platform "<?= htmlspecialchars($platform_id) ?>"</p>
|
||||||
|
<div class="card-body">
|
||||||
|
<p class="card-text">delete a platform:</p>
|
||||||
|
<form method="POST" action="<?= $app_root ?>?platform=<?= htmlspecialchars($platform_id) ?>&page=config">
|
||||||
|
<?php foreach ($config['platforms'][$platform_id] as $config_item => $config_value) { ?>
|
||||||
|
<div class="row mb-3">
|
||||||
|
<div class="col-md-4 text-end">
|
||||||
|
<label for="<?= htmlspecialchars($config_item) ?>" class="form-label"><?= htmlspecialchars($config_item) ?>:</label>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-8">
|
||||||
|
<div class="text-start"><?= htmlspecialchars($config_value ?? '')?></div>
|
||||||
|
<input type="hidden" name="<?= htmlspecialchars($config_item) ?>" value="<?= htmlspecialchars($config_value ?? '')?>" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<?php } ?>
|
||||||
|
<br />
|
||||||
|
<input type="hidden" name="platform" value="<?= htmlspecialchars($platform_id) ?>" />
|
||||||
|
<input type="hidden" name="delete" value="true" />
|
||||||
|
<p class="h5 text-danger">Are you sure you want to delete this platform?</p>
|
||||||
|
<br />
|
||||||
|
<a class="btn btn-secondary" href="<?= $app_root ?>?page=config" />Cancel</a>
|
||||||
|
<input type="submit" class="btn btn-danger" value="Delete" />
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- /widget "config" -->
|
|
@ -0,0 +1,33 @@
|
||||||
|
|
||||||
|
<!-- widget "config" -->
|
||||||
|
<div class="card text-center w-50 mx-auto">
|
||||||
|
<p class="h4 card-header">Jilo web configuration for Jitsi platform "<?= htmlspecialchars($platform_id) ?>"</p>
|
||||||
|
<div class="card-body">
|
||||||
|
<p class="card-text">edit the platform details:</p>
|
||||||
|
<form method="POST" action="<?= $app_root ?>?platform=<?= htmlspecialchars($platform_id) ?>&page=config">
|
||||||
|
<?php foreach ($config['platforms'][$platform_id] as $config_item => $config_value) { ?>
|
||||||
|
<div class="row mb-3">
|
||||||
|
<div class="col-md-4 text-end">
|
||||||
|
<label for="<?= htmlspecialchars($config_item) ?>" class="form-label"><?= htmlspecialchars($config_item) ?></label>
|
||||||
|
<span class="text-danger" style="margin-right: -12px;">*</span>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-8">
|
||||||
|
<input class="form-control" type="text" name="<?= htmlspecialchars($config_item) ?>" value="<?= htmlspecialchars($config_value ?? '')?>" required />
|
||||||
|
<?php if ($config_item === 'name') { ?>
|
||||||
|
<p class="text-start"><small>descriptive name for the platform</small></p>
|
||||||
|
<?php } elseif ($config_item === 'jitsi_url') { ?>
|
||||||
|
<p class="text-start"><small>URL of the Jitsi Meet (used for checks and for loading config.js)</small></p>
|
||||||
|
<?php } elseif ($config_item === 'jilo_database') { ?>
|
||||||
|
<p class="text-start"><small>path to the database file (relative to the app root)</small></p>
|
||||||
|
<?php } ?>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<?php } ?>
|
||||||
|
<br />
|
||||||
|
<input type="hidden" name="platform" value="<?= htmlspecialchars($platform_id) ?>" />
|
||||||
|
<a class="btn btn-secondary" href="<?= $app_root ?>?page=config" />Cancel</a>
|
||||||
|
<input type="submit" class="btn btn-primary" value="Save" />
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- /widget "config" -->
|
|
@ -0,0 +1,22 @@
|
||||||
|
|
||||||
|
<!-- widget "config" -->
|
||||||
|
<div class="card text-center w-75 mx-lef">
|
||||||
|
<p class="h4 card-header">Configuration of the Jitsi platform <strong><?= htmlspecialchars($platformDetails['name']) ?></strong></p>
|
||||||
|
<div class="card-body">
|
||||||
|
<p class="card-text">
|
||||||
|
<span class="m-3">URL: <?= htmlspecialchars($platformDetails['jitsi_url']) ?></span>
|
||||||
|
<span class="m-3">FILE: config.js</span>
|
||||||
|
<?php if ($mode === 'raw') { ?>
|
||||||
|
<span class="m-3"><a class="btn btn-light" href="<?= $app_root ?>?platform=<?= htmlspecialchars($platform_id) ?>&page=config&item=configjs">view only active lines</a></span>
|
||||||
|
<?php } else { ?>
|
||||||
|
<span class="m-3"><a class="btn btn-light" href="<?= $app_root ?>?platform=<?= htmlspecialchars($platform_id) ?>&page=config&item=configjs&mode=raw">view raw file contents</a></span>
|
||||||
|
<?php } ?>
|
||||||
|
</p>
|
||||||
|
<pre style="text-align: left;">
|
||||||
|
<?php
|
||||||
|
echo htmlspecialchars($platformConfigjs);
|
||||||
|
?>
|
||||||
|
</pre>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- /widget "config" -->
|
|
@ -0,0 +1,22 @@
|
||||||
|
|
||||||
|
<!-- widget "config" -->
|
||||||
|
<div class="card text-center w-75 mx-lef">
|
||||||
|
<p class="h4 card-header">Configuration of the Jitsi platform <strong><?= htmlspecialchars($platformDetails['name']) ?></strong></p>
|
||||||
|
<div class="card-body">
|
||||||
|
<p class="card-text">
|
||||||
|
<span class="m-3">URL: <?= htmlspecialchars($platformDetails['jitsi_url']) ?></span>
|
||||||
|
<span class="m-3">FILE: interface_config.js</span>
|
||||||
|
<?php if ($mode === 'raw') { ?>
|
||||||
|
<span class="m-3"><a class="btn btn-light" href="<?= $app_root ?>?platform=<?= htmlspecialchars($platform_id) ?>&page=config&item=interfaceconfigjs">view only active lines</a></span>
|
||||||
|
<?php } else { ?>
|
||||||
|
<span class="m-3"><a class="btn btn-light" href="<?= $app_root ?>?platform=<?= htmlspecialchars($platform_id) ?>&page=config&item=interfaceconfigjs&mode=raw">view raw file contents</a></span>
|
||||||
|
<?php } ?>
|
||||||
|
</p>
|
||||||
|
<pre style="text-align: left;">
|
||||||
|
<?php
|
||||||
|
echo htmlspecialchars($platformInterfaceConfigjs);
|
||||||
|
?>
|
||||||
|
</pre>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- /widget "config" -->
|
|
@ -0,0 +1,14 @@
|
||||||
|
|
||||||
|
<!-- widget "config" -->
|
||||||
|
<div class="card text-center w-75 mx-lef">
|
||||||
|
<p class="h4 card-header">Jilo web configuration</p>
|
||||||
|
<div class="card-body">
|
||||||
|
<p class="card-text">platform variables</p>
|
||||||
|
<?php
|
||||||
|
include '../app/helpers/render.php';
|
||||||
|
renderConfig($config, '0');
|
||||||
|
echo "\n";
|
||||||
|
?>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- /widget "config" -->
|
|
@ -0,0 +1,20 @@
|
||||||
|
<!-- login form -->
|
||||||
|
<div class="card text-center w-50 mx-auto">
|
||||||
|
<h2 class="card-header">Login</h2>
|
||||||
|
<div class="card-body">
|
||||||
|
<p class="card-text"><strong>Welcome to JILO!</strong><br />Please enter login credentials:</p>
|
||||||
|
<form method="POST" action="<?= $app_root ?>?page=login">
|
||||||
|
<input type="text" name="username" placeholder="Username" required />
|
||||||
|
<br />
|
||||||
|
<input type="password" name="password" placeholder="Password" required />
|
||||||
|
<br />
|
||||||
|
<label for="remember_me">
|
||||||
|
<input type="checkbox" id="remember_me" name="remember_me" />
|
||||||
|
remember me
|
||||||
|
</label>
|
||||||
|
<br /> <br />
|
||||||
|
<input type="submit" class="btn btn-primary" value="Login" />
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- /login form -->
|
|
@ -0,0 +1,15 @@
|
||||||
|
<!-- registration form -->
|
||||||
|
<div class="card text-center w-50 mx-auto">
|
||||||
|
<h2 class="card-header">Register</h2>
|
||||||
|
<div class="card-body">
|
||||||
|
<p class="card-text">Enter credentials for registration:</p>
|
||||||
|
<form method="POST" action="<?php= $app_root ?>?page=register">
|
||||||
|
<input type="text" name="username" placeholder="Username" required />
|
||||||
|
<br />
|
||||||
|
<input type="password" name="password" placeholder="Password" required />
|
||||||
|
<br /> <br />
|
||||||
|
<input type="submit" class="btn btn-primary" value="Register" />
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- /registration form -->
|
|
@ -0,0 +1,23 @@
|
||||||
|
|
||||||
|
<?php if ($page !== 'login' && $page !== 'register') { ?>
|
||||||
|
<!-- /Main content -->
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<?php } ?>
|
||||||
|
<!-- Footer -->
|
||||||
|
<div id="footer">Jilo Web <?= $config['version'] ?> ©2024 - web interface for <a href="https://lindeas.com/jilo">Jilo</a></div>
|
||||||
|
<!-- /Footer -->
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script src="static/sidebar.js"></script>
|
||||||
|
<script>
|
||||||
|
$(document).ready(function(){
|
||||||
|
$('[data-toggle="tooltip"]').tooltip();
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
|
@ -2,12 +2,21 @@
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<link rel="stylesheet" type="text/css" href="static/bootstrap.min.css">
|
<link rel="stylesheet" type="text/css" href="<?= $app_root ?>static/bootstrap.min.css">
|
||||||
<link rel="stylesheet" type="text/css" href="static/all.css">
|
<link rel="stylesheet" type="text/css" href="<?= $app_root ?>static/all.css">
|
||||||
<script src="static/bootstrap.min.js"></script>
|
|
||||||
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
|
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
|
||||||
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.12.9/dist/umd/popper.min.js" integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q" crossorigin="anonymous"></script>
|
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.12.9/dist/umd/popper.min.js" integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q" crossorigin="anonymous"></script>
|
||||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@4.0.0/dist/js/bootstrap.min.js" integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl" crossorigin="anonymous"></script>
|
<script src="https://cdn.jsdelivr.net/npm/bootstrap@4.0.0/dist/js/bootstrap.min.js" integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl" crossorigin="anonymous"></script>
|
||||||
|
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.7.0/css/all.css" integrity="sha384-lZN37f5QGtY3VHgisS14W3ExzMWZxybE1SJSEsQp9S+oqd12jhcu+A56Ebc1zFSJ" crossorigin="anonymous">
|
||||||
|
<script>
|
||||||
|
// restore sidebar state before the page is rendered
|
||||||
|
(function () {
|
||||||
|
var savedState = localStorage.getItem('sidebarState');
|
||||||
|
if (savedState === 'collapsed') {
|
||||||
|
document.documentElement.classList.add('sidebar-collapsed');
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
</script>
|
||||||
<title>Jilo Web</title>
|
<title>Jilo Web</title>
|
||||||
</head>
|
</head>
|
||||||
|
|
|
@ -0,0 +1,36 @@
|
||||||
|
|
||||||
|
<!-- Menu -->
|
||||||
|
<div class="menu-container">
|
||||||
|
<ul class="menu-left">
|
||||||
|
<div class="container">
|
||||||
|
<div class="row">
|
||||||
|
<a href="<?= $app_root ?>?platform=<?= $platform_id?>" class="logo-link"><div class="col-4"><img class="logo" src="<?= $app_root ?>static/jilo-logo.png" alt="JILO"/></div></a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<li class="font-weight-light text-uppercase" style="font-size: 0.5em; color: whitesmoke; margin-right: 70px; align-content: center;">version <?php echo $config['version']; ?></li>
|
||||||
|
|
||||||
|
<?php if ( isset($_SESSION['username']) ) { ?>
|
||||||
|
|
||||||
|
<?php foreach ($config['platforms'] as $index => $platform) { ?>
|
||||||
|
<li style="margin-right: 3px;">
|
||||||
|
<a style="background-color: #111;" href="?platform=<?= htmlspecialchars($index) ?>&page=front">
|
||||||
|
<?= htmlspecialchars($platform['name']) ?>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<?php } ?>
|
||||||
|
|
||||||
|
<?php } ?>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<ul class="menu-right">
|
||||||
|
<?php if ( isset($_SESSION['username']) ) { ?>
|
||||||
|
<li><a href="<?= $app_root ?>?page=profile"><?= $user ?></a></li>
|
||||||
|
<li><a href="<?= $app_root ?>?page=logout">logout</a></li>
|
||||||
|
<?php } else { ?>
|
||||||
|
<li><a href="<?= $app_root ?>?page=login">login</a></li>
|
||||||
|
<li><a href="<?= $app_root ?>?page=register">register</a></li>
|
||||||
|
<?php } ?>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<!-- /Menu -->
|
|
@ -0,0 +1,63 @@
|
||||||
|
<div class="row">
|
||||||
|
|
||||||
|
<!-- Sidebar -->
|
||||||
|
<div class="col-md-3 sidebar-wrapper bg-light" id="sidebar">
|
||||||
|
<div class="col-4"><button class="btn btn-sm btn-info toggle-sidebar-button" type="button" id="toggleSidebarButton" value=">>"></button></div>
|
||||||
|
<div class="sidebar-content card ml-3 mt-3">
|
||||||
|
<ul class="list-group">
|
||||||
|
|
||||||
|
<li class="list-group-item bg-light" style="border: none;"><p class="text-end mb-0"><small>statistics</small></p></li>
|
||||||
|
|
||||||
|
<a href="<?= $app_root ?>?platform=<?= $platform_id ?>&page=front">
|
||||||
|
<li class="list-group-item<?php if ($page === 'front') echo ' list-group-item-secondary'; else echo ' list-group-item-action'; ?>">
|
||||||
|
<i class="fas fa-chart-line" data-toggle="tooltip" data-placement="right" data-offset="30.0" title="general jitsi stats"></i>general stats
|
||||||
|
</li>
|
||||||
|
</a>
|
||||||
|
<a href="<?= $app_root ?>?platform=<?= $platform_id ?>&page=conferences">
|
||||||
|
<li class="list-group-item<?php if ($page === 'conferences') echo ' list-group-item-secondary'; else echo ' list-group-item-action'; ?>">
|
||||||
|
<i class="fas fa-video" data-toggle="tooltip" data-placement="right" data-offset="30.0" title="conferences"></i>conferences
|
||||||
|
</li>
|
||||||
|
</a>
|
||||||
|
<a href="<?= $app_root ?>?platform=<?= $platform_id ?>&page=participants">
|
||||||
|
<li class="list-group-item<?php if ($page === 'participants') echo ' list-group-item-secondary'; else echo ' list-group-item-action'; ?>">
|
||||||
|
<i class="fas fa-users" data-toggle="tooltip" data-placement="right" data-offset="30.0" title="participants"></i>participants
|
||||||
|
</li>
|
||||||
|
</a>
|
||||||
|
<a href="<?= $app_root ?>?platform=<?= $platform_id ?>&page=components">
|
||||||
|
<li class="list-group-item<?php if ($page === 'components') echo ' list-group-item-secondary'; else echo ' list-group-item-action'; ?>">
|
||||||
|
<i class="fas fa-puzzle-piece" data-toggle="tooltip" data-placement="right" data-offset="30.0" title="components"></i>components
|
||||||
|
</li>
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<li class="list-group-item bg-light" style="border: none;"><p class="text-end mb-0"><small>jilo-web config</small></p></li>
|
||||||
|
|
||||||
|
<a href="<?= $app_root ?>?page=config">
|
||||||
|
<li class="list-group-item<?php if ($page === 'config' && $item === '') echo ' list-group-item-secondary'; else echo ' list-group-item-action'; ?>">
|
||||||
|
<i class="fas fa-wrench" data-toggle="tooltip" data-placement="right" data-offset="30.0" title="configuration"></i>config
|
||||||
|
</li>
|
||||||
|
</a>
|
||||||
|
<a href="<?= $app_root ?>?page=logs">
|
||||||
|
<li class="list-group-item<?php if ($page === 'logs') echo ' list-group-item-secondary'; else echo ' list-group-item-action'; ?>">
|
||||||
|
<i class="fas fa-list" data-toggle="tooltip" data-placement="right" data-offset="30.0" title="logs"></i>logs
|
||||||
|
</li>
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<li class="list-group-item bg-light" style="border: none;"><p class="text-end mb-0"><small>current Jitsi platform</small></p></li>
|
||||||
|
|
||||||
|
<a href="<?= $app_root ?>?platform=<?= $platform_id ?>&page=config&item=configjs">
|
||||||
|
<li class="list-group-item<?php if ($page === 'config' && $item === 'configjs') echo ' list-group-item-secondary'; else echo ' list-group-item-action'; ?>">
|
||||||
|
<i class="fas fa-tv" data-toggle="tooltip" data-placement="right" data-offset="30.0" title="configuration"></i>config.js
|
||||||
|
</li>
|
||||||
|
</a>
|
||||||
|
<a href="<?= $app_root ?>?platform=<?= $platform_id ?>&page=config&item=interfaceconfigjs">
|
||||||
|
<li class="list-group-item<?php if ($page === 'config' && $item === 'interfaceconfigjs') echo ' list-group-item-secondary'; else echo ' list-group-item-action'; ?>">
|
||||||
|
<i class="fas fa-th" data-toggle="tooltip" data-placement="right" data-offset="30.0" title="configuration"></i>interface_config.js
|
||||||
|
</li>
|
||||||
|
</a>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- /Sidebar -->
|
||||||
|
|
||||||
|
<!-- Main content -->
|
||||||
|
<div class="col-md-9 main-content" id="mainContent">
|
|
@ -0,0 +1,60 @@
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
|
||||||
|
<?php if ($widget['collapsible'] === true) { ?>
|
||||||
|
<a style="text-decoration: none;" data-toggle="collapse" href="#collapse<?= $widget['name'] ?>" role="button" aria-expanded="true" aria-controls="collapse<?= $widget['name'] ?>">
|
||||||
|
<div class="card w-auto bg-light card-body" style="flex-direction: row;"><?= $widget['title'] ?></div>
|
||||||
|
<?php } else { ?>
|
||||||
|
<div class="card w-auto bg-light border-light card-body" style="flex-direction: row;"><?= $widget['title'] ?></div>
|
||||||
|
<?php } ?>
|
||||||
|
<?php if ($widget['filter'] === true) {
|
||||||
|
include('../app/templates/block-results-filter.php'); } ?>
|
||||||
|
<?php if ($widget['collapsible'] === true) { ?>
|
||||||
|
</a>
|
||||||
|
<?php } ?>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- widget "<?= $widget['name']; ?>" -->
|
||||||
|
<div class="collapse show" id="collapse<?= $widget['name'] ?>">
|
||||||
|
<?php if ($time_range_specified) { ?>
|
||||||
|
<p class="m-3">time period: <strong><?= $from_time ?> - <?= $until_time ?></strong></p>
|
||||||
|
<?php } ?>
|
||||||
|
<div class="mb-5">
|
||||||
|
<?php if ($widget['full'] === true) { ?>
|
||||||
|
<table class="table table-striped table-hover table-bordered">
|
||||||
|
<thead class="thead-dark">
|
||||||
|
<tr>
|
||||||
|
<th scope="col"></th>
|
||||||
|
<?php foreach ($widget['records'] as $record) { ?>
|
||||||
|
<th scope="col"><?= htmlspecialchars($record['table_headers']) ?></th>
|
||||||
|
<?php } ?>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td>conferences</td>
|
||||||
|
<?php foreach ($widget['records'] as $record) { ?>
|
||||||
|
<td><?php if (!empty($record['conferences'])) { ?>
|
||||||
|
<a href="<?= $app_root ?>?platform=<?= $platform_id?>&page=conferences&from_time=<?= $record['from_time'] ?>&until_time=<?= $record['until_time'] ?>"><?= htmlspecialchars($record['conferences']) ?></a> <?php } else { ?>
|
||||||
|
0<?php } ?>
|
||||||
|
</td>
|
||||||
|
<?php } ?>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>participants</td>
|
||||||
|
<?php foreach ($widget['records'] as $record) { ?>
|
||||||
|
<td><?php if (!empty($record['participants'])) { ?>
|
||||||
|
<a href="<?= $app_root ?>?platform=<?= $platform_id?>&page=participants&from_time=<?= $record['from_time'] ?>&until_time=<?= $record['until_time'] ?>"><?= htmlspecialchars($record['participants']) ?></a> <?php } else { ?>
|
||||||
|
0<?php } ?>
|
||||||
|
</td>
|
||||||
|
<?php } ?>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
<?php } else { ?>
|
||||||
|
<p class="m-3">No matching records found.</p>
|
||||||
|
<?php } ?>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- /widget "<?= $widget['name']; ?>" -->
|
|
@ -0,0 +1,9 @@
|
||||||
|
|
||||||
|
<!-- widget "user profile" -->
|
||||||
|
<div>
|
||||||
|
<p>Profile of <?= $user ?></p>
|
||||||
|
<ul>
|
||||||
|
<li>username: <?= $_SESSION['username'] ?></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<!-- /widget "user profile" -->
|
|
@ -0,0 +1,76 @@
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<?php if ($widget['collapsible'] === true) { ?>
|
||||||
|
<a style="text-decoration: none;" data-toggle="collapse" href="#collapse<?= $widget['name'] ?>" role="button" aria-expanded="true" aria-controls="collapse<?= $widget['name'] ?>">
|
||||||
|
<div class="card w-auto bg-light card-body" style="flex-direction: row;"><?= $widget['title'] ?></div>
|
||||||
|
<?php } else { ?>
|
||||||
|
<div class="card w-auto bg-light border-light card-body" style="flex-direction: row;"><?= $widget['title'] ?></div>
|
||||||
|
<?php } ?>
|
||||||
|
<?php if ($widget['filter'] === true) {
|
||||||
|
include('../app/templates/block-results-filter.php'); } ?>
|
||||||
|
<?php if ($widget['collapsible'] === true) { ?>
|
||||||
|
</a>
|
||||||
|
<?php } ?>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- widget "<?= $widget['name']; ?>" -->
|
||||||
|
<div class="collapse show" id="collapse<?= $widget['name'] ?>">
|
||||||
|
<?php if ($time_range_specified) { ?>
|
||||||
|
<p class="m-3">time period: <strong><?= $from_time ?> - <?= $until_time ?></strong></p>
|
||||||
|
<?php } ?>
|
||||||
|
<div class="mb-5">
|
||||||
|
<?php if ($widget['full'] === true) { ?>
|
||||||
|
<table class="table table-striped table-hover table-bordered">
|
||||||
|
<thead class="thead-dark">
|
||||||
|
<tr>
|
||||||
|
<?php foreach ($widget['table_headers'] as $header) { ?>
|
||||||
|
<th scope="col"><?= htmlspecialchars($header) ?></th>
|
||||||
|
<?php } ?>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<?php foreach ($widget['table_records'] as $row) { ?>
|
||||||
|
<tr>
|
||||||
|
<?php $stats_id = false;
|
||||||
|
$participant_ip = false;
|
||||||
|
if (isset($row['event']) && $row['event'] === 'stats_id') $stats_id = true;
|
||||||
|
if (isset($row['event']) && $row['event'] === 'pair selected') $participant_ip = true;
|
||||||
|
foreach ($row as $key => $column) {
|
||||||
|
if ($key === 'conference ID' && isset($conferenceId) && $conferenceId === $column) { ?>
|
||||||
|
<td><strong><?= htmlspecialchars($column ?? '') ?></strong></td>
|
||||||
|
<?php } elseif ($key === 'conference ID') { ?>
|
||||||
|
<td><a href="<?= $app_root ?>?platform=<?= $platform_id?>&page=conferences&id=<?= htmlspecialchars($column ?? '') ?>"><?= htmlspecialchars($column ?? '') ?></a></td>
|
||||||
|
<?php } elseif ($key === 'conference name' && isset($conferenceName) && $conferenceName === $column) { ?>
|
||||||
|
<td><strong><?= htmlspecialchars($column ?? '') ?></strong></td>
|
||||||
|
<?php } elseif ($key === 'conference name') { ?>
|
||||||
|
<td><a href="<?= $app_root ?>?platform=<?= $platform_id?>&page=conferences&name=<?= htmlspecialchars($column ?? '') ?>"><?= htmlspecialchars($column ?? '') ?></a></td>
|
||||||
|
<?php } elseif ($key === 'participant ID' && isset($participantId) && $participantId === $column) { ?>
|
||||||
|
<td><strong><?= htmlspecialchars($column ?? '') ?></strong></td>
|
||||||
|
<?php } elseif ($key === 'participant ID') { ?>
|
||||||
|
<td><a href="<?= $app_root ?>?platform=<?= $platform_id?>&page=participants&id=<?= htmlspecialchars($column ?? '') ?>"><?= htmlspecialchars($column ?? '') ?></a></td>
|
||||||
|
<?php } elseif ($key === 'component ID') { ?>
|
||||||
|
<td><a href="<?= $app_root ?>?platform=<?= $platform_id?>&page=components&id=<?= htmlspecialchars($column ?? '') ?>"><?= htmlspecialchars($column ?? '') ?></a></td>
|
||||||
|
<?php } elseif ($stats_id && $key === 'parameter' && isset($participantName) && $participantName === $column) { ?>
|
||||||
|
<td><strong><?= htmlspecialchars($column ?? '') ?></strong></td>
|
||||||
|
<?php } elseif ($stats_id && $key === 'parameter') { ?>
|
||||||
|
<td><a href="<?= $app_root ?>?platform=<?= $platform_id?>&page=participants&name=<?= htmlspecialchars($column ?? '') ?>"><?= htmlspecialchars($column ?? '') ?></a></td>
|
||||||
|
<?php } elseif ($participant_ip && $key === 'parameter' && isset($participantIp) && $participantIp === $column) { ?>
|
||||||
|
<td><strong><?= htmlspecialchars($column ?? '') ?></strong></td>
|
||||||
|
<?php } elseif ($participant_ip && $key === 'parameter') { ?>
|
||||||
|
<td><a href="<?= $app_root ?>?platform=<?= $platform_id?>&page=participants&ip=<?= htmlspecialchars($column ?? '') ?>"><?= htmlspecialchars($column ?? '') ?></a></td>
|
||||||
|
<?php } elseif ($key === 'component') { ?>
|
||||||
|
<td><a href="<?= $app_root ?>?platform=<?= $platform_id?>&page=components&name=<?= htmlspecialchars($column ?? '') ?>"><?= htmlspecialchars($column ?? '') ?></a></td>
|
||||||
|
<?php } else { ?>
|
||||||
|
<td><?= htmlspecialchars($column ?? '') ?></td>
|
||||||
|
<?php }
|
||||||
|
} ?>
|
||||||
|
</tr>
|
||||||
|
<?php } ?>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
<?php } else { ?>
|
||||||
|
<p class="m-3">No matching records found.</p>
|
||||||
|
<?php } ?>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- /widget "<?= $widget['name']; ?>" -->
|
15
config.nginx
15
config.nginx
|
@ -1,15 +0,0 @@
|
||||||
server {
|
|
||||||
listen 80;
|
|
||||||
server_name $DOMAIN;
|
|
||||||
|
|
||||||
root $INSTALL_DIR;
|
|
||||||
index index.php;
|
|
||||||
|
|
||||||
location / {
|
|
||||||
try_files \$uri \$uri/ /index.php?\$args;
|
|
||||||
}
|
|
||||||
|
|
||||||
location ~ /\.ht {
|
|
||||||
deny all;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
RewriteEngine On
|
||||||
|
|
||||||
|
# limit access to .htaccess
|
||||||
|
<Files .htaccess>
|
||||||
|
Order Allow,Deny
|
||||||
|
Deny from all
|
||||||
|
</Files>
|
||||||
|
|
||||||
|
# don't rewrite CSS, JS, etc.
|
||||||
|
RewriteCond %{REQUEST_FILENAME} !-f
|
||||||
|
RewriteCond %{REQUEST_FILENAME} !-d
|
||||||
|
|
||||||
|
# all other go to index.php
|
||||||
|
RewriteRule ^(.*)$ index.php?page=$1 [L,QSA]
|
|
@ -4,4 +4,9 @@
|
||||||
|
|
||||||
CustomLog \${APACHE_LOG_DIR}/jilo-web_access.log combined
|
CustomLog \${APACHE_LOG_DIR}/jilo-web_access.log combined
|
||||||
ErrorLog \${APACHE_LOG_DIR}/jilo-web_error.log
|
ErrorLog \${APACHE_LOG_DIR}/jilo-web_error.log
|
||||||
|
|
||||||
|
<Directory $INSTALL_DIR>
|
||||||
|
AllowOverride All
|
||||||
|
</Directory>
|
||||||
|
|
||||||
</VirtualHost>
|
</VirtualHost>
|
|
@ -0,0 +1,22 @@
|
||||||
|
server {
|
||||||
|
listen 80;
|
||||||
|
server_name $DOMAIN;
|
||||||
|
|
||||||
|
root $INSTALL_DIR;
|
||||||
|
index index.php;
|
||||||
|
|
||||||
|
location / {
|
||||||
|
try_files \$uri \$uri/ /index.php?\$args;
|
||||||
|
}
|
||||||
|
|
||||||
|
location ~ \.php$ {
|
||||||
|
include snippets/fastcgi-php.conf;
|
||||||
|
fastcgi_pass unix:/run/php/php-fpm.sock;
|
||||||
|
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
|
||||||
|
include fastcgi_params;
|
||||||
|
}
|
||||||
|
|
||||||
|
location ~ /\.ht {
|
||||||
|
deny all;
|
||||||
|
}
|
||||||
|
}
|
|
@ -6,7 +6,7 @@ if [ "$EUID" -ne 0 ] && [ -z "$SUDO_USER" ]; then
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
VERSION=`grep version jilo-web.conf.php | cut -d "'" -f 4`
|
VERSION=`grep version ../app/config/jilo-web.conf.php | cut -d "'" -f 4`
|
||||||
|
|
||||||
# main install function
|
# main install function
|
||||||
function install() {
|
function install() {
|
||||||
|
@ -20,23 +20,24 @@ function install() {
|
||||||
WEB_DIR=${WEB_DIR:-jilo-web}
|
WEB_DIR=${WEB_DIR:-jilo-web}
|
||||||
|
|
||||||
INSTALL_DIR="/opt/jilo-web/public_html"
|
INSTALL_DIR="/opt/jilo-web/public_html"
|
||||||
|
APP_DIR="/opt/jilo-web/app"
|
||||||
DOC_DIR="/opt/jilo-web/doc"
|
DOC_DIR="/opt/jilo-web/doc"
|
||||||
ETC_DIR="/opt/jilo-web/etc"
|
ETC_DIR="/opt/jilo-web/etc"
|
||||||
|
|
||||||
mkdir -p $INSTALL_DIR
|
mkdir -p $INSTALL_DIR
|
||||||
cp -r ./public_html/* $INSTALL_DIR
|
cp -r ../public_html/* $INSTALL_DIR
|
||||||
|
|
||||||
mkdir -p $DOC_DIR
|
mkdir -p $DOC_DIR
|
||||||
cp CHANGELOG.md $DOC_DIR
|
cp ../CHANGELOG.md $DOC_DIR
|
||||||
cp LICENSE $DOC_DIR
|
cp ../LICENSE $DOC_DIR
|
||||||
cp README.md $DOC_DIR
|
cp ../README.md $DOC_DIR
|
||||||
cp TODO.md $DOC_DIR
|
cp ../TODO.md $DOC_DIR
|
||||||
cp config.apache $DOC_DIR
|
cp ../license-bootstrap $DOC_DIR
|
||||||
cp config.nginx $DOC_DIR
|
cp ../license-jquery $DOC_DIR
|
||||||
|
cp -r ../doc/ $DOC_DIR
|
||||||
|
|
||||||
mkdir -p $ETC_DIR
|
mkdir -p $ETC_DIR
|
||||||
cp jilo-web.conf.php $ETC_DIR
|
cp ../app/config/jilo-web.conf.php $ETC_DIR
|
||||||
cp jilo-web.schema $ETC_DIR
|
|
||||||
|
|
||||||
#FIXME
|
#FIXME
|
||||||
#mkdir -p "jilo-web-$VERSION/usr/share/man/man8"
|
#mkdir -p "jilo-web-$VERSION/usr/share/man/man8"
|
|
@ -1,5 +1,5 @@
|
||||||
Package: jilo-web
|
Package: jilo-web
|
||||||
Version: 0.1.1
|
Version: 0.2
|
||||||
Section: web
|
Section: web
|
||||||
Priority: optional
|
Priority: optional
|
||||||
Architecture: all
|
Architecture: all
|
|
@ -1,4 +1,4 @@
|
||||||
.TH JILO-WEB "8" "July 2024" "jilo-web 0.1.1"
|
.TH JILO-WEB "8" "August 2024" "jilo-web 0.2"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
jilo-web \- PHP frontent to jilo (jitsi logs observer) database.
|
jilo-web \- PHP frontent to jilo (jitsi logs observer) database.
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
|
@ -17,7 +17,7 @@ Written and maintained by Yasen Pramatarov <yasen@lindeas.com>
|
||||||
https://lindeas.com/jilo
|
https://lindeas.com/jilo
|
||||||
|
|
||||||
.SH VERSION
|
.SH VERSION
|
||||||
0.1.1
|
0.2
|
||||||
|
|
||||||
.SH SEE ALSO
|
.SH SEE ALSO
|
||||||
jilo(8), jilo-cli(8)
|
jilo(8), jilo-cli(8)
|
|
@ -1,5 +1,5 @@
|
||||||
Name: jilo-web
|
Name: jilo-web
|
||||||
Version: 0.1.1
|
Version: 0.2
|
||||||
Release: 1%{?dist}
|
Release: 1%{?dist}
|
||||||
Summary: Jitsi logs web observer
|
Summary: Jitsi logs web observer
|
||||||
|
|
||||||
|
@ -54,6 +54,8 @@ cp %{sourcedir}/man-jilo.8 %{buildroot}/usr/share/man/man8/%{name}.8
|
||||||
/usr/share/man/man8/%{name}.8.gz
|
/usr/share/man/man8/%{name}.8.gz
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Sat Aug 31 2024 Yasen Pramatarov <yasen@lindeas.com> 0.2
|
||||||
|
- Build of upstream v0.2
|
||||||
* Thu Jul 25 2024 Yasen Pramatarov <yasen@lindeas.com> 0.1.1
|
* Thu Jul 25 2024 Yasen Pramatarov <yasen@lindeas.com> 0.1.1
|
||||||
- Build of upstream v0.1.1
|
- Build of upstream v0.1.1
|
||||||
* Wed Jul 12 2024 Yasen Pramatarov <yasen@lindeas.com> 0.1
|
* Wed Jul 12 2024 Yasen Pramatarov <yasen@lindeas.com> 0.1
|
|
@ -1,11 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
$config = [
|
|
||||||
'domain' => 'localhost',
|
|
||||||
'folder' => '/jilo-web/',
|
|
||||||
'database' => '/home/yasen/work/code/git/lindeas-code/jilo-web/jilo-web.db',
|
|
||||||
'jilo_database' => '/home/yasen/work/code/git/lindeas-code/jilo/jilo.db',
|
|
||||||
'version' => '0.1.1',
|
|
||||||
];
|
|
||||||
|
|
||||||
?>
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
Copyright OpenJS Foundation and other contributors, https://openjsf.org/
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining
|
||||||
|
a copy of this software and associated documentation files (the
|
||||||
|
"Software"), to deal in the Software without restriction, including
|
||||||
|
without limitation the rights to use, copy, modify, merge, publish,
|
||||||
|
distribute, sublicense, and/or sell copies of the Software, and to
|
||||||
|
permit persons to whom the Software is furnished to do so, subject to
|
||||||
|
the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be
|
||||||
|
included in all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||||
|
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||||
|
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||||
|
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
@ -1,90 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
class Conference {
|
|
||||||
private $db;
|
|
||||||
private $queries;
|
|
||||||
|
|
||||||
public function __construct($database) {
|
|
||||||
$this->db = $database->getConnection();
|
|
||||||
$this->queries = include('queries.php');
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// search/list specific conference ID
|
|
||||||
public function conferenceById($conference_id, $from_time, $until_time) {
|
|
||||||
|
|
||||||
// time period drill-down
|
|
||||||
// FIXME make it similar to the bash version
|
|
||||||
if (empty($from_time)) {
|
|
||||||
$from_time = '0000-01-01';
|
|
||||||
}
|
|
||||||
if (empty($until_time)) {
|
|
||||||
$until_time = '9999-12-31';
|
|
||||||
}
|
|
||||||
|
|
||||||
// this is needed for compatibility with the bash version, so we use '%s' placeholders
|
|
||||||
$from_time = htmlspecialchars(strip_tags($from_time));
|
|
||||||
$until_time = htmlspecialchars(strip_tags($until_time));
|
|
||||||
$sql = $this->queries['conference_by_id'];
|
|
||||||
$sql = sprintf($sql, $conference_id, $from_time, $until_time, $conference_id, $from_time, $until_time);
|
|
||||||
|
|
||||||
$query = $this->db->prepare($sql);
|
|
||||||
$query->execute();
|
|
||||||
|
|
||||||
return $query->fetchAll(PDO::FETCH_ASSOC);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// search/list specific conference name
|
|
||||||
public function conferenceByName($conference_name, $from_time, $until_time) {
|
|
||||||
|
|
||||||
// time period drill-down
|
|
||||||
// FIXME make it similar to the bash version
|
|
||||||
if (empty($from_time)) {
|
|
||||||
$from_time = '0000-01-01';
|
|
||||||
}
|
|
||||||
if (empty($until_time)) {
|
|
||||||
$until_time = '9999-12-31';
|
|
||||||
}
|
|
||||||
|
|
||||||
// this is needed for compatibility with the bash version, so we use '%s' placeholders
|
|
||||||
$from_time = htmlspecialchars(strip_tags($from_time));
|
|
||||||
$until_time = htmlspecialchars(strip_tags($until_time));
|
|
||||||
$sql = $this->queries['conference_by_name'];
|
|
||||||
$sql = sprintf($sql, $conference_name, $from_time, $until_time, $conference_name, $from_time, $until_time);
|
|
||||||
|
|
||||||
$query = $this->db->prepare($sql);
|
|
||||||
$query->execute();
|
|
||||||
|
|
||||||
return $query->fetchAll(PDO::FETCH_ASSOC);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// list of all conferences
|
|
||||||
public function conferencesAllFormatted($from_time, $until_time) {
|
|
||||||
|
|
||||||
// time period drill-down
|
|
||||||
// FIXME make it similar to the bash version
|
|
||||||
if (empty($from_time)) {
|
|
||||||
$from_time = '0000-01-01';
|
|
||||||
}
|
|
||||||
if (empty($until_time)) {
|
|
||||||
$until_time = '9999-12-31';
|
|
||||||
}
|
|
||||||
|
|
||||||
// this is needed for compatibility with the bash version, so we use '%s' placeholders
|
|
||||||
$from_time = htmlspecialchars(strip_tags($from_time));
|
|
||||||
$until_time = htmlspecialchars(strip_tags($until_time));
|
|
||||||
$sql = $this->queries['conferences_all_formatted'];
|
|
||||||
$sql = sprintf($sql, $from_time, $until_time);
|
|
||||||
|
|
||||||
$query = $this->db->prepare($sql);
|
|
||||||
$query->execute();
|
|
||||||
|
|
||||||
return $query->fetchAll(PDO::FETCH_ASSOC);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
?>
|
|
|
@ -1,34 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
class Database {
|
|
||||||
private $pdo;
|
|
||||||
|
|
||||||
public function __construct($dbFile) {
|
|
||||||
|
|
||||||
// pdo and pdo_sqlite needed
|
|
||||||
if ( !extension_loaded('pdo_sqlite') ) {
|
|
||||||
throw new Exception('PDO extension for SQLite not loaded.');
|
|
||||||
}
|
|
||||||
|
|
||||||
// database file check
|
|
||||||
if (empty($dbFile) || !file_exists($dbFile)) {
|
|
||||||
throw new Exception('Database file is not found.');
|
|
||||||
}
|
|
||||||
|
|
||||||
// connect to database
|
|
||||||
// FIXME: add mysql/mariadb option
|
|
||||||
try {
|
|
||||||
$this->pdo = new PDO("sqlite:" . $dbFile);
|
|
||||||
$this->pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
|
|
||||||
} catch (PDOException $e) {
|
|
||||||
throw new Exception('DB connection failed: ' . $e->getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getConnection() {
|
|
||||||
return $this->pdo;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
?>
|
|
|
@ -1,115 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
class Participant {
|
|
||||||
private $db;
|
|
||||||
private $queries;
|
|
||||||
|
|
||||||
public function __construct($database) {
|
|
||||||
$this->db = $database->getConnection();
|
|
||||||
$this->queries = include('queries.php');
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// search/list specific participant ID
|
|
||||||
public function conferenceByParticipantId($participant_id, $from_time, $until_time) {
|
|
||||||
|
|
||||||
// time period drill-down
|
|
||||||
// FIXME make it similar to the bash version
|
|
||||||
if (empty($from_time)) {
|
|
||||||
$from_time = '0000-01-01';
|
|
||||||
}
|
|
||||||
if (empty($until_time)) {
|
|
||||||
$until_time = '9999-12-31';
|
|
||||||
}
|
|
||||||
|
|
||||||
// this is needed for compatibility with the bash version, so we use '%s' placeholders
|
|
||||||
$from_time = htmlspecialchars(strip_tags($from_time));
|
|
||||||
$until_time = htmlspecialchars(strip_tags($until_time));
|
|
||||||
$sql = $this->queries['conference_by_participant_id'];
|
|
||||||
$sql = sprintf($sql, $participant_id, $from_time, $until_time, $participant_id, $from_time, $until_time);
|
|
||||||
|
|
||||||
$query = $this->db->prepare($sql);
|
|
||||||
$query->execute();
|
|
||||||
|
|
||||||
return $query->fetchAll(PDO::FETCH_ASSOC);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// search/list specific participant name (stats_id)
|
|
||||||
public function conferenceByParticipantName($participant_name, $from_time, $until_time) {
|
|
||||||
|
|
||||||
// time period drill-down
|
|
||||||
// FIXME make it similar to the bash version
|
|
||||||
if (empty($from_time)) {
|
|
||||||
$from_time = '0000-01-01';
|
|
||||||
}
|
|
||||||
if (empty($until_time)) {
|
|
||||||
$until_time = '9999-12-31';
|
|
||||||
}
|
|
||||||
|
|
||||||
// this is needed for compatibility with the bash version, so we use '%s' placeholders
|
|
||||||
$from_time = htmlspecialchars(strip_tags($from_time));
|
|
||||||
$until_time = htmlspecialchars(strip_tags($until_time));
|
|
||||||
$sql = $this->queries['participant_by_stats_id'];
|
|
||||||
$sql = sprintf($sql, $participant_name, $from_time, $until_time, $participant_name, $from_time, $until_time);
|
|
||||||
|
|
||||||
$query = $this->db->prepare($sql);
|
|
||||||
$query->execute();
|
|
||||||
|
|
||||||
return $query->fetchAll(PDO::FETCH_ASSOC);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// search/list specific participant IP
|
|
||||||
public function conferenceByParticipantIP($participant_ip, $from_time, $until_time) {
|
|
||||||
|
|
||||||
// time period drill-down
|
|
||||||
// FIXME make it similar to the bash version
|
|
||||||
if (empty($from_time)) {
|
|
||||||
$from_time = '0000-01-01';
|
|
||||||
}
|
|
||||||
if (empty($until_time)) {
|
|
||||||
$until_time = '9999-12-31';
|
|
||||||
}
|
|
||||||
|
|
||||||
// this is needed for compatibility with the bash version, so we use '%s' placeholders
|
|
||||||
$from_time = htmlspecialchars(strip_tags($from_time));
|
|
||||||
$until_time = htmlspecialchars(strip_tags($until_time));
|
|
||||||
$sql = $this->queries['participant_by_ip'];
|
|
||||||
$sql = sprintf($sql, $participant_ip, $from_time, $until_time, $participant_ip, $from_time, $until_time);
|
|
||||||
|
|
||||||
$query = $this->db->prepare($sql);
|
|
||||||
$query->execute();
|
|
||||||
|
|
||||||
return $query->fetchAll(PDO::FETCH_ASSOC);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// list of all conferences
|
|
||||||
public function participantsAll($from_time, $until_time) {
|
|
||||||
|
|
||||||
// time period drill-down
|
|
||||||
// FIXME make it similar to the bash version
|
|
||||||
if (empty($from_time)) {
|
|
||||||
$from_time = '0000-01-01';
|
|
||||||
}
|
|
||||||
if (empty($until_time)) {
|
|
||||||
$until_time = '9999-12-31';
|
|
||||||
}
|
|
||||||
|
|
||||||
// this is needed for compatibility with the bash version, so we use '%s' placeholders
|
|
||||||
$from_time = htmlspecialchars(strip_tags($from_time));
|
|
||||||
$until_time = htmlspecialchars(strip_tags($until_time));
|
|
||||||
$sql = $this->queries['participants_all'];
|
|
||||||
$sql = sprintf($sql, $from_time, $until_time);
|
|
||||||
|
|
||||||
$query = $this->db->prepare($sql);
|
|
||||||
$query->execute();
|
|
||||||
|
|
||||||
return $query->fetchAll(PDO::FETCH_ASSOC);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
?>
|
|
|
@ -1,314 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
// all sql queries for the jilo database in one place
|
|
||||||
|
|
||||||
return [
|
|
||||||
|
|
||||||
// list of conferences for time period (if given)
|
|
||||||
// fields: component, duration, conference ID, conference name, number of participants, name count (the conf name is found), conference host
|
|
||||||
'conferences_all_formatted' => "
|
|
||||||
SELECT DISTINCT
|
|
||||||
c.jitsi_component,
|
|
||||||
(SELECT ce.time
|
|
||||||
FROM conference_events ce
|
|
||||||
WHERE
|
|
||||||
ce.conference_id = c.conference_id
|
|
||||||
AND
|
|
||||||
ce.conference_event = 'conference created')
|
|
||||||
AS start,
|
|
||||||
(SELECT ce.time
|
|
||||||
FROM conference_events ce
|
|
||||||
WHERE
|
|
||||||
ce.conference_id = c.conference_id
|
|
||||||
AND
|
|
||||||
ce.conference_event = 'conference expired')
|
|
||||||
AS end,
|
|
||||||
c.conference_id,
|
|
||||||
c.conference_name,
|
|
||||||
(SELECT COUNT(pe.participant_id)
|
|
||||||
FROM participant_events pe
|
|
||||||
WHERE
|
|
||||||
pe.event_type = 'participant joining'
|
|
||||||
AND
|
|
||||||
pe.event_param = c.conference_id) AS participants,
|
|
||||||
name_counts.name_count,
|
|
||||||
c.conference_host
|
|
||||||
FROM
|
|
||||||
conferences c
|
|
||||||
JOIN (
|
|
||||||
SELECT
|
|
||||||
conference_name,
|
|
||||||
COUNT(*) AS name_count
|
|
||||||
FROM
|
|
||||||
conferences
|
|
||||||
GROUP BY
|
|
||||||
conference_name
|
|
||||||
) AS name_counts ON c.conference_name = name_counts.conference_name
|
|
||||||
JOIN
|
|
||||||
conference_events ce ON c.conference_id = ce.conference_id
|
|
||||||
WHERE (ce.time >= '%s 00:00:00' AND ce.time <= '%s 23:59:59')
|
|
||||||
ORDER BY
|
|
||||||
c.id;",
|
|
||||||
|
|
||||||
|
|
||||||
// search for a conference by its ID for a time period (if given)
|
|
||||||
'conference_by_id' => "
|
|
||||||
SELECT
|
|
||||||
pe.time,
|
|
||||||
c.conference_id,
|
|
||||||
c.conference_name,
|
|
||||||
c.conference_host,
|
|
||||||
pe.loglevel,
|
|
||||||
pe.event_type,
|
|
||||||
p.endpoint_id AS participant_id,
|
|
||||||
pe.event_param
|
|
||||||
FROM
|
|
||||||
conferences c
|
|
||||||
LEFT JOIN
|
|
||||||
conference_events ce ON c.conference_id = ce.conference_id
|
|
||||||
LEFT JOIN
|
|
||||||
participants p ON c.conference_id = p.conference_id
|
|
||||||
LEFT JOIN
|
|
||||||
participant_events pe ON p.endpoint_id = pe.participant_id
|
|
||||||
WHERE
|
|
||||||
c.conference_id = '%s'
|
|
||||||
AND (pe.time >= '%s 00:00:00' AND pe.time <= '%s 23:59:59')
|
|
||||||
|
|
||||||
UNION
|
|
||||||
|
|
||||||
SELECT
|
|
||||||
ce.time AS event_time,
|
|
||||||
c.conference_id,
|
|
||||||
c.conference_name,
|
|
||||||
c.conference_host,
|
|
||||||
ce.loglevel,
|
|
||||||
ce.conference_event AS event_type,
|
|
||||||
NULL AS participant_id,
|
|
||||||
ce.conference_param AS event_param
|
|
||||||
FROM
|
|
||||||
conferences c
|
|
||||||
LEFT JOIN
|
|
||||||
conference_events ce ON c.conference_id = ce.conference_id
|
|
||||||
WHERE
|
|
||||||
c.conference_id = '%s'
|
|
||||||
AND (event_time >= '%s 00:00:00' AND event_time <= '%s 23:59:59')
|
|
||||||
|
|
||||||
ORDER BY
|
|
||||||
pe.time;",
|
|
||||||
|
|
||||||
|
|
||||||
// search for a conference by its name for a time period (if given)
|
|
||||||
'conference_by_name' => "
|
|
||||||
SELECT
|
|
||||||
pe.time,
|
|
||||||
c.conference_id,
|
|
||||||
c.conference_name,
|
|
||||||
c.conference_host,
|
|
||||||
pe.loglevel,
|
|
||||||
pe.event_type,
|
|
||||||
p.endpoint_id AS participant_id,
|
|
||||||
pe.event_param
|
|
||||||
FROM
|
|
||||||
conferences c
|
|
||||||
LEFT JOIN
|
|
||||||
conference_events ce ON c.conference_id = ce.conference_id
|
|
||||||
LEFT JOIN
|
|
||||||
participants p ON c.conference_id = p.conference_id
|
|
||||||
LEFT JOIN
|
|
||||||
participant_events pe ON p.endpoint_id = pe.participant_id
|
|
||||||
WHERE
|
|
||||||
c.conference_name = '%s'
|
|
||||||
AND (pe.time >= '%s 00:00:00' AND pe.time <= '%s 23:59:59')
|
|
||||||
|
|
||||||
UNION
|
|
||||||
|
|
||||||
SELECT
|
|
||||||
ce.time AS event_time,
|
|
||||||
c.conference_id,
|
|
||||||
c.conference_name,
|
|
||||||
c.conference_host,
|
|
||||||
ce.loglevel,
|
|
||||||
ce.conference_event AS event_type,
|
|
||||||
NULL AS participant_id,
|
|
||||||
ce.conference_param AS event_param
|
|
||||||
FROM
|
|
||||||
conferences c
|
|
||||||
LEFT JOIN
|
|
||||||
conference_events ce ON c.conference_id = ce.conference_id
|
|
||||||
WHERE
|
|
||||||
c.conference_name = '%s'
|
|
||||||
AND (event_time >= '%s 00:00:00' AND event_time <= '%s 23:59:59')
|
|
||||||
|
|
||||||
ORDER BY
|
|
||||||
pe.time;",
|
|
||||||
|
|
||||||
|
|
||||||
// list all participants
|
|
||||||
'participants_all' => "
|
|
||||||
SELECT DISTINCT
|
|
||||||
p.jitsi_component, p.endpoint_id, p.conference_id
|
|
||||||
FROM
|
|
||||||
participants p
|
|
||||||
JOIN
|
|
||||||
participant_events pe ON p.endpoint_id = pe.participant_id
|
|
||||||
WHERE
|
|
||||||
pe.time >= '%s 00:00:00' AND pe.time <= '%s 23:59:59'
|
|
||||||
ORDER BY p.id;",
|
|
||||||
|
|
||||||
|
|
||||||
// list conferences where participant ID (endpoint_id) is found
|
|
||||||
'conference_by_participant_id' => "
|
|
||||||
SELECT
|
|
||||||
pe.time,
|
|
||||||
c.conference_id,
|
|
||||||
c.conference_name,
|
|
||||||
c.conference_host,
|
|
||||||
pe.loglevel,
|
|
||||||
pe.event_type,
|
|
||||||
p.endpoint_id AS participant_id,
|
|
||||||
pe.event_param
|
|
||||||
FROM
|
|
||||||
conferences c
|
|
||||||
LEFT JOIN
|
|
||||||
conference_events ce ON c.conference_id = ce.conference_id
|
|
||||||
LEFT JOIN
|
|
||||||
participants p ON c.conference_id = p.conference_id
|
|
||||||
LEFT JOIN
|
|
||||||
participant_events pe ON p.endpoint_id = pe.participant_id
|
|
||||||
WHERE
|
|
||||||
p.endpoint_id = '%s'
|
|
||||||
AND (pe.time >= '%s 00:00:00' AND pe.time <= '%s 23:59:59')
|
|
||||||
|
|
||||||
UNION
|
|
||||||
|
|
||||||
SELECT
|
|
||||||
ce.time AS event_time,
|
|
||||||
c.conference_id,
|
|
||||||
c.conference_name,
|
|
||||||
c.conference_host,
|
|
||||||
ce.loglevel,
|
|
||||||
ce.conference_event AS event_type,
|
|
||||||
NULL AS participant_id,
|
|
||||||
ce.conference_param AS event_param
|
|
||||||
FROM
|
|
||||||
conferences c
|
|
||||||
LEFT JOIN
|
|
||||||
conference_events ce ON c.conference_id = ce.conference_id
|
|
||||||
WHERE
|
|
||||||
participant_id = '%s'
|
|
||||||
AND (event_time >= '%s 00:00:00' AND event_time <= '%s 23:59:59')
|
|
||||||
|
|
||||||
ORDER BY
|
|
||||||
pe.time;",
|
|
||||||
|
|
||||||
|
|
||||||
// list conferences where participant name (stats_id) is found
|
|
||||||
'participant_by_stats_id' => "
|
|
||||||
SELECT
|
|
||||||
pe.time,
|
|
||||||
c.conference_id,
|
|
||||||
c.conference_name,
|
|
||||||
c.conference_host,
|
|
||||||
pe.loglevel,
|
|
||||||
pe.event_type,
|
|
||||||
p.endpoint_id AS participant_id,
|
|
||||||
pe.event_param
|
|
||||||
FROM
|
|
||||||
conferences c
|
|
||||||
LEFT JOIN
|
|
||||||
conference_events ce ON c.conference_id = ce.conference_id
|
|
||||||
LEFT JOIN
|
|
||||||
participants p ON c.conference_id = p.conference_id
|
|
||||||
LEFT JOIN
|
|
||||||
participant_events pe ON p.endpoint_id = pe.participant_id
|
|
||||||
WHERE
|
|
||||||
pe.event_type = 'stats_id' AND pe.event_param LIKE '%%%s%%'
|
|
||||||
AND (pe.time >= '%s 00:00:00' AND pe.time <= '%s 23:59:59')
|
|
||||||
|
|
||||||
UNION
|
|
||||||
|
|
||||||
SELECT
|
|
||||||
ce.time AS event_time,
|
|
||||||
c.conference_id,
|
|
||||||
c.conference_name,
|
|
||||||
c.conference_host,
|
|
||||||
ce.loglevel,
|
|
||||||
ce.conference_event AS event_type,
|
|
||||||
NULL AS participant_id,
|
|
||||||
ce.conference_param AS event_param
|
|
||||||
FROM
|
|
||||||
conferences c
|
|
||||||
LEFT JOIN
|
|
||||||
conference_events ce ON c.conference_id = ce.conference_id
|
|
||||||
WHERE
|
|
||||||
event_type = 'stats_id' AND event_param LIKE '%%%s%%'
|
|
||||||
AND (event_time >= '%s 00:00:00' AND event_time <= '%s 23:59:59')
|
|
||||||
|
|
||||||
ORDER BY
|
|
||||||
pe.time;",
|
|
||||||
|
|
||||||
|
|
||||||
// list conferences where participant IP is found
|
|
||||||
'participant_by_ip' => "
|
|
||||||
SELECT
|
|
||||||
pe.time,
|
|
||||||
c.conference_id,
|
|
||||||
c.conference_name,
|
|
||||||
c.conference_host,
|
|
||||||
pe.loglevel,
|
|
||||||
pe.event_type,
|
|
||||||
p.endpoint_id AS participant_id,
|
|
||||||
pe.event_param
|
|
||||||
FROM
|
|
||||||
conferences c
|
|
||||||
LEFT JOIN
|
|
||||||
conference_events ce ON c.conference_id = ce.conference_id
|
|
||||||
LEFT JOIN
|
|
||||||
participants p ON c.conference_id = p.conference_id
|
|
||||||
LEFT JOIN
|
|
||||||
participant_events pe ON p.endpoint_id = pe.participant_id
|
|
||||||
WHERE
|
|
||||||
pe.event_type = 'pair selected' AND pe.event_param = '%s'
|
|
||||||
AND (pe.time >= '%s 00:00:00' AND pe.time <= '%s 23:59:59')
|
|
||||||
|
|
||||||
UNION
|
|
||||||
|
|
||||||
SELECT
|
|
||||||
ce.time AS event_time,
|
|
||||||
c.conference_id,
|
|
||||||
c.conference_name,
|
|
||||||
c.conference_host,
|
|
||||||
ce.loglevel,
|
|
||||||
ce.conference_event AS event_type,
|
|
||||||
NULL AS participant_id,
|
|
||||||
ce.conference_param AS event_param
|
|
||||||
FROM
|
|
||||||
conferences c
|
|
||||||
LEFT JOIN
|
|
||||||
conference_events ce ON c.conference_id = ce.conference_id
|
|
||||||
WHERE
|
|
||||||
event_type = 'pair selected' AND event_param = '%s'
|
|
||||||
AND (event_time >= '%s 00:00:00' AND event_time <= '%s 23:59:59')
|
|
||||||
|
|
||||||
ORDER BY
|
|
||||||
pe.time;",
|
|
||||||
|
|
||||||
|
|
||||||
// list of jitsi component events
|
|
||||||
'jitsi_components' => "
|
|
||||||
SELECT jitsi_component, loglevel, time, component_id, event_type, event_param
|
|
||||||
FROM
|
|
||||||
jitsi_components
|
|
||||||
WHERE
|
|
||||||
jitsi_component = %s
|
|
||||||
AND
|
|
||||||
component_id = %s
|
|
||||||
AND
|
|
||||||
(time >= '%s 00:00:00' AND time <= '%s 23:59:59')
|
|
||||||
ORDER BY
|
|
||||||
time;",
|
|
||||||
|
|
||||||
|
|
||||||
];
|
|
||||||
|
|
||||||
?>
|
|
|
@ -8,9 +8,13 @@
|
||||||
* License: GPLv2
|
* License: GPLv2
|
||||||
* Project URL: https://lindeas.com/jilo
|
* Project URL: https://lindeas.com/jilo
|
||||||
* Year: 2024
|
* Year: 2024
|
||||||
* Version: 0.1.1
|
* Version: 0.2
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
// we start output buffering and.
|
||||||
|
// flush it later only when there is no redirect
|
||||||
|
ob_start();
|
||||||
|
|
||||||
// error reporting, comment out in production
|
// error reporting, comment out in production
|
||||||
ini_set('display_errors', 1);
|
ini_set('display_errors', 1);
|
||||||
ini_set('display_startup_errors', 1);
|
ini_set('display_startup_errors', 1);
|
||||||
|
@ -31,26 +35,46 @@ $allowed_urls = [
|
||||||
];
|
];
|
||||||
|
|
||||||
// cnfig file
|
// cnfig file
|
||||||
$config_file = '/home/yasen/work/code/git/lindeas-code/jilo-web/jilo-web.conf.php';
|
// possible locations, in order of preference
|
||||||
if (file_exists($config_file)) {
|
$config_file_locations = [
|
||||||
require_once $config_file;
|
__DIR__ . '/../app/config/jilo-web.conf.php',
|
||||||
|
__DIR__ . '/../jilo-web.conf.php',
|
||||||
|
'/srv/jilo-web/jilo-web.conf.php',
|
||||||
|
'/opt/jilo-web/jilo-web.conf.php'
|
||||||
|
];
|
||||||
|
$config_file = null;
|
||||||
|
// try to find the config file
|
||||||
|
foreach ($config_file_locations as $location) {
|
||||||
|
if (file_exists($location)) {
|
||||||
|
$config_file = $location;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// if found, use it
|
||||||
|
if ($config_file) {
|
||||||
|
$config = require $config_file;
|
||||||
} else {
|
} else {
|
||||||
die('Config file not found');
|
die('Config file not found');
|
||||||
}
|
}
|
||||||
|
|
||||||
$app_root = $config['folder'];
|
$app_root = $config['folder'];
|
||||||
|
|
||||||
|
session_name('jilo');
|
||||||
session_start();
|
session_start();
|
||||||
|
|
||||||
if (isset($_GET['page'])) {
|
if (isset($_REQUEST['page'])) {
|
||||||
$page = $_GET['page'];
|
$page = $_REQUEST['page'];
|
||||||
} elseif (isset($_POST['page'])) {
|
|
||||||
$page = $_POST['page'];
|
|
||||||
} else {
|
} else {
|
||||||
$page = 'front';
|
$page = 'front';
|
||||||
}
|
}
|
||||||
|
if (isset($_REQUEST['item'])) {
|
||||||
|
$item = $_REQUEST['item'];
|
||||||
|
} else {
|
||||||
|
$item = '';
|
||||||
|
}
|
||||||
|
|
||||||
// check if logged in
|
// check if logged in
|
||||||
|
unset($user);
|
||||||
if (isset($_COOKIE['username'])) {
|
if (isset($_COOKIE['username'])) {
|
||||||
if ( !isset($_SESSION['username']) ) {
|
if ( !isset($_SESSION['username']) ) {
|
||||||
$_SESSION['username'] = $_COOKIE['username'];
|
$_SESSION['username'] = $_COOKIE['username'];
|
||||||
|
@ -72,6 +96,9 @@ if (isset($_SESSION['error'])) {
|
||||||
$error = $_SESSION['error'];
|
$error = $_SESSION['error'];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// by default we connect ot the first configured platform
|
||||||
|
$platform_id = $_REQUEST['platform'] ?? '0';
|
||||||
|
|
||||||
// page building
|
// page building
|
||||||
if (in_array($page, $allowed_urls)) {
|
if (in_array($page, $allowed_urls)) {
|
||||||
// logout is a special case, as we can't use session vars for notices
|
// logout is a special case, as we can't use session vars for notices
|
||||||
|
@ -83,27 +110,37 @@ if (in_array($page, $allowed_urls)) {
|
||||||
setcookie('username', "", time() - 100, $config['folder'], $config['domain'], isset($_SERVER['HTTPS']), true);
|
setcookie('username', "", time() - 100, $config['folder'], $config['domain'], isset($_SERVER['HTTPS']), true);
|
||||||
|
|
||||||
$notice = "You were logged out.<br />You can log in again.";
|
$notice = "You were logged out.<br />You can log in again.";
|
||||||
include 'templates/header.php';
|
include '../app/templates/page-header.php';
|
||||||
include 'templates/menu.php';
|
include '../app/templates/page-menu.php';
|
||||||
include 'templates/message.php';
|
include '../app/templates/block-message.php';
|
||||||
include 'pages/login.php';
|
include '../app/pages/login.php';
|
||||||
|
|
||||||
// all other normal pages
|
// all other normal pages
|
||||||
} else {
|
} else {
|
||||||
include 'templates/header.php';
|
include '../app/templates/page-header.php';
|
||||||
include 'templates/menu.php';
|
include '../app/templates/page-menu.php';
|
||||||
include 'templates/message.php';
|
include '../app/templates/block-message.php';
|
||||||
include "pages/{$page}.php";
|
if (isset($user)) {
|
||||||
|
include '../app/templates/page-sidebar.php';
|
||||||
|
}
|
||||||
|
include "../app/pages/{$page}.php";
|
||||||
}
|
}
|
||||||
|
|
||||||
// the page is not in allowed urls, loading front page
|
// the page is not in allowed urls, loading front page
|
||||||
} else {
|
} else {
|
||||||
include 'templates/header.php';
|
$error = 'The page "' . $page . '" is not found';
|
||||||
include 'templates/menu.php';
|
include '../app/templates/page-header.php';
|
||||||
include 'templates/message.php';
|
include '../app/templates/page-menu.php';
|
||||||
include 'pages/front.php';
|
include '../app/templates/block-message.php';
|
||||||
|
if (isset($user)) {
|
||||||
|
include '../app/templates/page-sidebar.php';
|
||||||
|
}
|
||||||
|
include '../app/pages/front.php';
|
||||||
}
|
}
|
||||||
include 'templates/footer.php';
|
include '../app/templates/page-footer.php';
|
||||||
|
|
||||||
|
// flush the output buffer and show the page
|
||||||
|
ob_end_flush();
|
||||||
|
|
||||||
// clear errors and notices before next page just in case
|
// clear errors and notices before next page just in case
|
||||||
unset($_SESSION['error']);
|
unset($_SESSION['error']);
|
||||||
|
|
|
@ -1,150 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
require_once 'classes/database.php';
|
|
||||||
require 'classes/component.php';
|
|
||||||
|
|
||||||
// FIXME move thi sto a special function
|
|
||||||
$time_range_specified = false;
|
|
||||||
if (!isset($_REQUEST['from_time']) || (isset($_REQUEST['from_time']) && $_REQUEST['from_time'] == '')) {
|
|
||||||
$from_time = '0000-01-01';
|
|
||||||
} else {
|
|
||||||
$from_time = $_REQUEST['from_time'];
|
|
||||||
$time_range_specified = true;
|
|
||||||
}
|
|
||||||
if (!isset($_REQUEST['until_time']) || (isset($_REQUEST['until_time']) && $_REQUEST['until_time'] == '')) {
|
|
||||||
$until_time = '9999-12-31';
|
|
||||||
} else {
|
|
||||||
$until_time = $_REQUEST['until_time'];
|
|
||||||
$time_range_specified = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// jitsi component events list
|
|
||||||
// we use $_REQUEST, so that both links and forms work
|
|
||||||
if (isset($_REQUEST['name']) && $_REQUEST['name'] != '') {
|
|
||||||
$jitsi_component = "'" . $_REQUEST['name'] . "'";
|
|
||||||
$component_id = 'component_id';
|
|
||||||
} elseif (isset($_REQUEST['id']) && $_REQUEST['id'] != '') {
|
|
||||||
$component_id = "'" . $_REQUEST['id'] . "'";
|
|
||||||
$jitsi_component = 'jitsi_component';
|
|
||||||
} else {
|
|
||||||
// we need the variables to use them later in sql for columnname = columnname
|
|
||||||
$jitsi_component = 'jitsi_component';
|
|
||||||
$component_id = 'component_id';
|
|
||||||
}
|
|
||||||
|
|
||||||
// connect to database
|
|
||||||
try {
|
|
||||||
$db = new Database($config['jilo_database']);
|
|
||||||
} catch (Exception $e) {
|
|
||||||
$error = 'Error: ' . $e->getMessage();
|
|
||||||
include 'templates/message.php';
|
|
||||||
exit();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//
|
|
||||||
// Component events listings
|
|
||||||
//
|
|
||||||
|
|
||||||
|
|
||||||
// list of all component events (default)
|
|
||||||
//if ($jitsi_component) {
|
|
||||||
try {
|
|
||||||
$component = new Component($db);
|
|
||||||
|
|
||||||
// prepare the result
|
|
||||||
$search = $component->jitsiComponents($jitsi_component, $component_id, $from_time, $until_time);
|
|
||||||
|
|
||||||
if (!empty($search)) {
|
|
||||||
$components = array();
|
|
||||||
$components['records'] = array();
|
|
||||||
|
|
||||||
foreach ($search as $item) {
|
|
||||||
extract($item);
|
|
||||||
$component_record = array(
|
|
||||||
// assign title to the field in the array record
|
|
||||||
'component' => $jitsi_component,
|
|
||||||
'loglevel' => $loglevel,
|
|
||||||
'time' => $time,
|
|
||||||
'component ID' => $component_id,
|
|
||||||
'event' => $event_type,
|
|
||||||
'param' => $event_param,
|
|
||||||
);
|
|
||||||
// populate the result array
|
|
||||||
array_push($components['records'], $component_record);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} catch (Exception $e) {
|
|
||||||
$error = 'Error: ' . $e->getMessage();
|
|
||||||
include 'templates/message.php';
|
|
||||||
exit();
|
|
||||||
}
|
|
||||||
|
|
||||||
// display the result
|
|
||||||
|
|
||||||
// format the header message
|
|
||||||
echo "<div class=\"results-header\">\n";
|
|
||||||
if (isset($_REQUEST['name']) && $_REQUEST['name'] != '') {
|
|
||||||
echo "<div class=\"results-message\">Jitsi events for component <strong>" . $_REQUEST['name'] . "</strong>";
|
|
||||||
} elseif (isset($_REQUEST['id']) && $_REQUEST['id'] != '') {
|
|
||||||
echo "<div class=\"results-message\">Jitsi events for component ID <br /><strong>" . $_REQUEST['id'] . "</strong>";
|
|
||||||
} else {
|
|
||||||
echo "<div class=\"results-message\">Jitsi events for <strong>all components</strong>";
|
|
||||||
}
|
|
||||||
if ($time_range_specified) {
|
|
||||||
echo "<br />for the time period <strong>$from_time - $until_time</strong>";
|
|
||||||
}
|
|
||||||
echo "</div>\n\n";
|
|
||||||
|
|
||||||
// filters - time selection and sorting dropdowns
|
|
||||||
include 'templates/results-filter.php';
|
|
||||||
|
|
||||||
echo "</div>\n\n";
|
|
||||||
|
|
||||||
// results table
|
|
||||||
echo "<div class=\"mb-5\">\n";
|
|
||||||
|
|
||||||
if (!empty($components['records'])) {
|
|
||||||
|
|
||||||
echo "\t<table class=\"table table-striped table-hover table-bordered\">\n";
|
|
||||||
|
|
||||||
echo "\t\t<thead class=\"table-secondary\">\n";
|
|
||||||
echo "\t\t\t<tr>\n";
|
|
||||||
|
|
||||||
// table headers
|
|
||||||
foreach (array_keys($components['records'][0]) as $header) {
|
|
||||||
echo "\t\t\t\t<th scope=\"col\">" . htmlspecialchars($header) . "</th>\n";
|
|
||||||
}
|
|
||||||
echo "\t\t\t</tr>\n";
|
|
||||||
echo "\t\t</thead>\n";
|
|
||||||
|
|
||||||
echo "\t\t<tbody>\n";
|
|
||||||
|
|
||||||
//table rows
|
|
||||||
foreach ($components['records'] as $row) {
|
|
||||||
echo "\t\t\t<tr>\n";
|
|
||||||
// sometimes $column is empty, we make it '' then
|
|
||||||
foreach ($row as $key => $column) {
|
|
||||||
if ($key === 'component ID') {
|
|
||||||
echo "\t\t\t\t<td><a href=\"$app_root?page=components&id=" . htmlspecialchars($column ?? '') . "\">" . htmlspecialchars($column ?? '') . "</a></td>\n";
|
|
||||||
} elseif ($key === 'component') {
|
|
||||||
echo "\t\t\t\t<td><a href=\"$app_root?page=components&name=" . htmlspecialchars($column ?? '') . "\">" . htmlspecialchars($column ?? '') . "</a></td>\n";
|
|
||||||
} else {
|
|
||||||
echo "\t\t\t\t<td>" . htmlspecialchars($column ?? '') . "</td>\n";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
echo "\t\t\t</tr>\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
echo "\t\t</tbody>\n";
|
|
||||||
echo "\t</table>\n";
|
|
||||||
|
|
||||||
} else {
|
|
||||||
echo '<p class="m-3">No matching Jitsi component events found.</p>';
|
|
||||||
}
|
|
||||||
echo "\n</div>\n";
|
|
||||||
|
|
||||||
//}
|
|
||||||
|
|
||||||
?>
|
|
|
@ -1,359 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
require_once 'classes/database.php';
|
|
||||||
require 'classes/conference.php';
|
|
||||||
|
|
||||||
// FIXME move thi sto a special function
|
|
||||||
$time_range_specified = false;
|
|
||||||
if (!isset($_REQUEST['from_time']) || (isset($_REQUEST['from_time']) && $_REQUEST['from_time'] == '')) {
|
|
||||||
$from_time = '0000-01-01';
|
|
||||||
} else {
|
|
||||||
$from_time = $_REQUEST['from_time'];
|
|
||||||
$time_range_specified = true;
|
|
||||||
}
|
|
||||||
if (!isset($_REQUEST['until_time']) || (isset($_REQUEST['until_time']) && $_REQUEST['until_time'] == '')) {
|
|
||||||
$until_time = '9999-12-31';
|
|
||||||
} else {
|
|
||||||
$until_time = $_REQUEST['until_time'];
|
|
||||||
$time_range_specified = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// conference id/name are specified when searching specific conference(s)
|
|
||||||
// either id OR name, id has precedence
|
|
||||||
// we use $_REQUEST, so that both links and forms work
|
|
||||||
if (isset($_REQUEST['id']) && $_REQUEST['id'] != '') {
|
|
||||||
$conference_id = $_REQUEST['id'];
|
|
||||||
unset($_REQUEST['name']);
|
|
||||||
unset($conference_name);
|
|
||||||
} elseif (isset($_REQUEST['name']) && $_REQUEST['name'] != '') {
|
|
||||||
unset($conference_id);
|
|
||||||
$conference_name = $_REQUEST['name'];
|
|
||||||
} else {
|
|
||||||
unset($conference_id);
|
|
||||||
unset($conference_name);
|
|
||||||
}
|
|
||||||
|
|
||||||
// connect to database
|
|
||||||
try {
|
|
||||||
$db = new Database($config['jilo_database']);
|
|
||||||
} catch (Exception $e) {
|
|
||||||
$error = 'Error: ' . $e->getMessage();
|
|
||||||
include 'templates/message.php';
|
|
||||||
exit();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//
|
|
||||||
// Conference listings
|
|
||||||
//
|
|
||||||
|
|
||||||
|
|
||||||
// search and list specific conference ID
|
|
||||||
if (isset($conference_id)) {
|
|
||||||
|
|
||||||
try {
|
|
||||||
$conference = new Conference($db);
|
|
||||||
|
|
||||||
// prepare the result
|
|
||||||
$search = $conference->conferenceById($conference_id, $from_time, $until_time);
|
|
||||||
|
|
||||||
if (!empty($search)) {
|
|
||||||
$conferences = array();
|
|
||||||
$conferences['records'] = array();
|
|
||||||
|
|
||||||
foreach ($search as $item) {
|
|
||||||
extract($item);
|
|
||||||
$conference_record = array(
|
|
||||||
// assign title to the field in the array record
|
|
||||||
'time' => $time,
|
|
||||||
'conference ID' => $conference_id,
|
|
||||||
'conference name' => $conference_name,
|
|
||||||
'conference host' => $conference_host,
|
|
||||||
'loglevel' => $loglevel,
|
|
||||||
'participant ID' => $participant_id,
|
|
||||||
'event' => $event_type,
|
|
||||||
'parameter' => $event_param
|
|
||||||
);
|
|
||||||
// populate the result array
|
|
||||||
array_push($conferences['records'], $conference_record);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} catch (Exception $e) {
|
|
||||||
$error = 'Error: ' . $e->getMessage();
|
|
||||||
include 'templates/message.php';
|
|
||||||
exit();
|
|
||||||
}
|
|
||||||
|
|
||||||
// display the result
|
|
||||||
echo "<div class=\"results-header\">\n";
|
|
||||||
echo "<div class=\"results-message\">Conferences with ID matching \"<strong>$conference_id</strong>\"";
|
|
||||||
if ($time_range_specified) {
|
|
||||||
echo "<br />for the time period <strong>$from_time - $until_time</strong>";
|
|
||||||
}
|
|
||||||
echo "</div>\n\n";
|
|
||||||
|
|
||||||
// filters - time selection and sorting dropdowns
|
|
||||||
include 'templates/results-filter.php';
|
|
||||||
|
|
||||||
echo "</div>\n\n";
|
|
||||||
|
|
||||||
// results table
|
|
||||||
echo "<div class=\"mb-5\">\n";
|
|
||||||
|
|
||||||
if (!empty($conferences['records'])) {
|
|
||||||
|
|
||||||
echo "\t<table class=\"table table-striped table-hover table-bordered\">\n";
|
|
||||||
|
|
||||||
echo "\t\t<thead class=\"table-secondary\">\n";
|
|
||||||
echo "\t\t\t<tr>\n";
|
|
||||||
|
|
||||||
// table headers
|
|
||||||
foreach (array_keys($conferences['records'][0]) as $header) {
|
|
||||||
echo "\t\t\t\t<th scope=\"col\">" . htmlspecialchars($header) . "</th>\n";
|
|
||||||
}
|
|
||||||
echo "\t\t\t</tr>\n";
|
|
||||||
echo "\t\t</thead>\n";
|
|
||||||
|
|
||||||
echo "\t\t<tbody>\n";
|
|
||||||
|
|
||||||
//table rows
|
|
||||||
foreach ($conferences['records'] as $row) {
|
|
||||||
echo "\t\t\t<tr>\n";
|
|
||||||
$stats_id = false;
|
|
||||||
$participant_ip = false;
|
|
||||||
if ($row['event'] === 'stats_id') $stats_id = true;
|
|
||||||
if ($row['event'] === 'pair selected') $participant_ip = true;
|
|
||||||
// sometimes $column is empty, we make it '' then
|
|
||||||
foreach ($row as $key => $column) {
|
|
||||||
if ($key === 'conference ID' && $column === $conference_id) {
|
|
||||||
echo "\t\t\t\t<td><strong>" . htmlspecialchars($column ?? '') . "</strong></td>\n";
|
|
||||||
} elseif ($key === 'conference name') {
|
|
||||||
echo "\t\t\t\t<td><a href=\"$app_root?page=conferences&name=" . htmlspecialchars($column ?? '') . "\">" . htmlspecialchars($column ?? '') . "</a></td>\n";
|
|
||||||
} elseif ($stats_id && $key === 'parameter') {
|
|
||||||
echo "\t\t\t\t<td><a href=\"$app_root?page=participants&name=" . htmlspecialchars($column ?? '') . "\">" . htmlspecialchars($column ?? '') . "</a></td>\n";
|
|
||||||
} elseif ($participant_ip && $key === 'parameter') {
|
|
||||||
echo "\t\t\t\t<td><a href=\"$app_root?page=participants&ip=" . htmlspecialchars($column ?? '') . "\">" . htmlspecialchars($column ?? '') . "</a></td>\n";
|
|
||||||
} else {
|
|
||||||
echo "\t\t\t\t<td>" . htmlspecialchars($column ?? '') . "</td>\n";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
echo "\t\t\t</tr>\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
echo "\t\t</tbody>\n";
|
|
||||||
echo "\t</table>\n";
|
|
||||||
|
|
||||||
} else {
|
|
||||||
echo '<p class="m-3">No matching conferences found.</p>';
|
|
||||||
}
|
|
||||||
echo "\n</div>\n";
|
|
||||||
|
|
||||||
|
|
||||||
// search and list specific conference ID
|
|
||||||
} elseif (isset($conference_name)) {
|
|
||||||
|
|
||||||
try {
|
|
||||||
$conference = new Conference($db);
|
|
||||||
|
|
||||||
// prepare the result
|
|
||||||
$search = $conference->conferenceByName($conference_name, $from_time, $until_time);
|
|
||||||
|
|
||||||
if (!empty($search)) {
|
|
||||||
$conferences = array();
|
|
||||||
$conferences['records'] = array();
|
|
||||||
|
|
||||||
foreach ($search as $item) {
|
|
||||||
extract($item);
|
|
||||||
$conference_record = array(
|
|
||||||
// assign title to the field in the array record
|
|
||||||
'time' => $time,
|
|
||||||
'conference ID' => $conference_id,
|
|
||||||
'conference name' => $conference_name,
|
|
||||||
'conference host' => $conference_host,
|
|
||||||
'loglevel' => $loglevel,
|
|
||||||
'participant ID' => $participant_id,
|
|
||||||
'event' => $event_type,
|
|
||||||
'parameter' => $event_param
|
|
||||||
);
|
|
||||||
// populate the result array
|
|
||||||
array_push($conferences['records'], $conference_record);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} catch (Exception $e) {
|
|
||||||
$error = 'Error: ' . $e->getMessage();
|
|
||||||
include 'templates/message.php';
|
|
||||||
exit();
|
|
||||||
}
|
|
||||||
|
|
||||||
// display the result
|
|
||||||
echo "<div class=\"results-header\">\n";
|
|
||||||
echo "<div class=\"results-message\">Conferences with name matching \"<strong>$conference_name</strong>\"";
|
|
||||||
if ($time_range_specified) {
|
|
||||||
echo "<br />for the time period <strong>$from_time - $until_time</strong>";
|
|
||||||
}
|
|
||||||
echo "</div>\n\n";
|
|
||||||
|
|
||||||
// filters - time selection and sorting dropdowns
|
|
||||||
include 'templates/results-filter.php';
|
|
||||||
|
|
||||||
echo "</div>\n\n";
|
|
||||||
|
|
||||||
// results table
|
|
||||||
echo "<div class=\"mb-5\">\n";
|
|
||||||
|
|
||||||
if (!empty($conferences['records'])) {
|
|
||||||
|
|
||||||
echo "\t<table class=\"table table-striped table-hover table-bordered\">\n";
|
|
||||||
|
|
||||||
echo "\t\t<thead class=\"table-secondary\">\n";
|
|
||||||
echo "\t\t\t<tr>\n";
|
|
||||||
|
|
||||||
// table headers
|
|
||||||
foreach (array_keys($conferences['records'][0]) as $header) {
|
|
||||||
echo "\t\t\t\t<th scope=\"col\">" . htmlspecialchars($header) . "</th>\n";
|
|
||||||
}
|
|
||||||
echo "\t\t\t</tr>\n";
|
|
||||||
echo "\t\t</thead>\n";
|
|
||||||
|
|
||||||
echo "\t\t<tbody>\n";
|
|
||||||
|
|
||||||
//table rows
|
|
||||||
foreach ($conferences['records'] as $row) {
|
|
||||||
echo "\t\t\t<tr>\n";
|
|
||||||
$stats_id = false;
|
|
||||||
$participant_ip = false;
|
|
||||||
if ($row['event'] === 'stats_id') $stats_id = true;
|
|
||||||
if ($row['event'] === 'pair selected') $participant_ip = true;
|
|
||||||
// sometimes $column is empty, we make it '' then
|
|
||||||
foreach ($row as $key => $column) {
|
|
||||||
if ($key === 'conference name' && $column === $conference_name) {
|
|
||||||
echo "\t\t\t\t<td><strong>" . htmlspecialchars($column ?? '') . "</strong></td>\n";
|
|
||||||
} elseif ($key === 'conference ID') {
|
|
||||||
echo "\t\t\t\t<td><a href=\"$app_root?page=conferences&id=" . htmlspecialchars($column ?? '') . "\">" . htmlspecialchars($column ?? '') . "</a></td>\n";
|
|
||||||
} elseif ($key === 'participant ID') {
|
|
||||||
echo "\t\t\t\t<td><a href=\"$app_root?page=participants&id=" . htmlspecialchars($column ?? '') . "\">" . htmlspecialchars($column ?? '') . "</a></td>\n";
|
|
||||||
} elseif ($stats_id && $key === 'parameter') {
|
|
||||||
echo "\t\t\t\t<td><a href=\"$app_root?page=participants&name=" . htmlspecialchars($column ?? '') . "\">" . htmlspecialchars($column ?? '') . "</a></td>\n";
|
|
||||||
} elseif ($participant_ip && $key === 'parameter') {
|
|
||||||
echo "\t\t\t\t<td><a href=\"$app_root?page=participants&ip=" . htmlspecialchars($column ?? '') . "\">" . htmlspecialchars($column ?? '') . "</a></td>\n";
|
|
||||||
} else {
|
|
||||||
echo "\t\t\t\t<td>" . htmlspecialchars($column ?? '') . "</td>\n";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
echo "\t\t\t</tr>\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
echo "\t\t</tbody>\n";
|
|
||||||
echo "\t</table>\n";
|
|
||||||
|
|
||||||
} else {
|
|
||||||
echo '<p class="m-3">No matching conferences found.</p>';
|
|
||||||
}
|
|
||||||
echo "\n</div>\n";
|
|
||||||
|
|
||||||
|
|
||||||
// list of all conferences (default)
|
|
||||||
} else {
|
|
||||||
try {
|
|
||||||
$conference = new Conference($db);
|
|
||||||
|
|
||||||
// prepare the result
|
|
||||||
$search = $conference->conferencesAllFormatted($from_time, $until_time);
|
|
||||||
|
|
||||||
if (!empty($search)) {
|
|
||||||
$conferences = array();
|
|
||||||
$conferences['records'] = array();
|
|
||||||
|
|
||||||
foreach ($search as $item) {
|
|
||||||
extract($item);
|
|
||||||
|
|
||||||
// we don't have duration field, so we calculate it
|
|
||||||
if (!empty($start) && !empty($end)) {
|
|
||||||
$duration = gmdate("H:i:s", abs(strtotime($end) - strtotime($start)));
|
|
||||||
} else {
|
|
||||||
$duration = '';
|
|
||||||
}
|
|
||||||
$conference_record = array(
|
|
||||||
// assign title to the field in the array record
|
|
||||||
'component' => $jitsi_component,
|
|
||||||
'start' => $start,
|
|
||||||
'end' => $end,
|
|
||||||
'duration' => $duration,
|
|
||||||
'conference ID' => $conference_id,
|
|
||||||
'conference name' => $conference_name,
|
|
||||||
'participants' => $participants,
|
|
||||||
'name count' => $name_count,
|
|
||||||
'conference host' => $conference_host
|
|
||||||
);
|
|
||||||
// populate the result array
|
|
||||||
array_push($conferences['records'], $conference_record);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} catch (Exception $e) {
|
|
||||||
$error = 'Error: ' . $e->getMessage();
|
|
||||||
include 'templates/message.php';
|
|
||||||
exit();
|
|
||||||
}
|
|
||||||
|
|
||||||
// display the result
|
|
||||||
echo "<div class=\"results-header\">\n";
|
|
||||||
echo "<div class=\"results-message\">All conferences";
|
|
||||||
if ($time_range_specified) {
|
|
||||||
echo "<br />for the time period <strong>$from_time - $until_time</strong>";
|
|
||||||
}
|
|
||||||
echo "</div>\n\n";
|
|
||||||
|
|
||||||
// filters - time selection and sorting dropdowns
|
|
||||||
include 'templates/results-filter.php';
|
|
||||||
|
|
||||||
echo "</div>\n\n";
|
|
||||||
|
|
||||||
// results table
|
|
||||||
echo "<div class=\"mb-5\">\n";
|
|
||||||
|
|
||||||
if (!empty($conferences['records'])) {
|
|
||||||
|
|
||||||
echo "\t<table class=\"table table-striped table-hover table-bordered\">\n";
|
|
||||||
|
|
||||||
echo "\t\t<thead class=\"table-secondary\">\n";
|
|
||||||
echo "\t\t\t<tr>\n";
|
|
||||||
|
|
||||||
// table headers
|
|
||||||
foreach (array_keys($conferences['records'][0]) as $header) {
|
|
||||||
echo "\t\t\t\t<th scope=\"col\">" . htmlspecialchars($header) . "</th>\n";
|
|
||||||
}
|
|
||||||
echo "\t\t\t</tr>\n";
|
|
||||||
echo "\t\t</thead>\n";
|
|
||||||
|
|
||||||
echo "\t\t<tbody>\n";
|
|
||||||
|
|
||||||
//table rows
|
|
||||||
foreach ($conferences['records'] as $row) {
|
|
||||||
echo "\t\t\t<tr>\n";
|
|
||||||
// sometimes $column is empty, we make it '' then
|
|
||||||
foreach ($row as $key => $column) {
|
|
||||||
if ($key === 'conference ID') {
|
|
||||||
echo "\t\t\t\t<td><a href=\"$app_root?page=conferences&id=" . htmlspecialchars($column ?? '') . "\">" . htmlspecialchars($column ?? '') . "</a></td>\n";
|
|
||||||
} elseif ($key === 'conference name') {
|
|
||||||
echo "\t\t\t\t<td><a href=\"$app_root?page=conferences&name=" . htmlspecialchars($column ?? '') . "\">" . htmlspecialchars($column ?? '') . "</a></td>\n";
|
|
||||||
} else {
|
|
||||||
echo "\t\t\t\t<td>" . htmlspecialchars($column ?? '') . "</td>\n";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
echo "\t\t\t</tr>\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
echo "\t\t</tbody>\n";
|
|
||||||
echo "\t</table>\n";
|
|
||||||
|
|
||||||
} else {
|
|
||||||
echo '<p class="m-3">No matching conferences found.</p>';
|
|
||||||
}
|
|
||||||
echo "\n</div>\n";
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
?>
|
|
|
@ -1,13 +0,0 @@
|
||||||
<?php ?>
|
|
||||||
|
|
||||||
<div>
|
|
||||||
|
|
||||||
<p>Jilo web configuration</p>
|
|
||||||
|
|
||||||
<ul>
|
|
||||||
<?php foreach ($config as $config_item=>$config_value) { ?>
|
|
||||||
<li><?php echo htmlspecialchars($config_item) . ': ' . htmlspecialchars($config_value ?? ''); ?></li>
|
|
||||||
<?php } ?>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
</div>
|
|
|
@ -1,241 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
require_once 'classes/database.php';
|
|
||||||
require 'classes/conference.php';
|
|
||||||
|
|
||||||
// connect to database
|
|
||||||
try {
|
|
||||||
$db = new Database($config['jilo_database']);
|
|
||||||
} catch (Exception $e) {
|
|
||||||
$error = 'Error: ' . $e->getMessage();
|
|
||||||
include 'templates/message.php';
|
|
||||||
exit();
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// dashboard widget listings
|
|
||||||
//
|
|
||||||
|
|
||||||
// conferences in last 7 days
|
|
||||||
try {
|
|
||||||
$conference = new Conference($db);
|
|
||||||
|
|
||||||
// conferences for last 2 days
|
|
||||||
$from_time = date('Y-m-d', time() - 60 * 60 * 24 * 2);
|
|
||||||
$until_time = date('Y-m-d', time());
|
|
||||||
$time_range_specified = true;
|
|
||||||
|
|
||||||
// prepare the result
|
|
||||||
$search = $conference->conferencesAllFormatted($from_time, $until_time);
|
|
||||||
|
|
||||||
if (!empty($search)) {
|
|
||||||
$conferences = array();
|
|
||||||
$conferences['records'] = array();
|
|
||||||
|
|
||||||
foreach ($search as $item) {
|
|
||||||
extract($item);
|
|
||||||
|
|
||||||
// we don't have duration field, so we calculate it
|
|
||||||
if (!empty($start) && !empty($end)) {
|
|
||||||
$duration = gmdate("H:i:s", abs(strtotime($end) - strtotime($start)));
|
|
||||||
} else {
|
|
||||||
$duration = '';
|
|
||||||
}
|
|
||||||
$conference_record = array(
|
|
||||||
// assign title to the field in the array record
|
|
||||||
'component' => $jitsi_component,
|
|
||||||
'start' => $start,
|
|
||||||
'end' => $end,
|
|
||||||
'duration' => $duration,
|
|
||||||
'conference ID' => $conference_id,
|
|
||||||
'conference name' => $conference_name,
|
|
||||||
'participants' => $participants,
|
|
||||||
'name count' => $name_count,
|
|
||||||
'conference host' => $conference_host
|
|
||||||
);
|
|
||||||
// populate the result array
|
|
||||||
array_push($conferences['records'], $conference_record);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} catch (Exception $e) {
|
|
||||||
$error = 'Error: ' . $e->getMessage();
|
|
||||||
include 'templates/message.php';
|
|
||||||
exit();
|
|
||||||
}
|
|
||||||
|
|
||||||
// display the result
|
|
||||||
echo "<a style=\"text-decoration: none;\" data-toggle=\"collapse\" href=\"#collapseLastDays\" role=\"button\" aria-expanded=\"true\" aria-controls=\"collapseLastDays\">";
|
|
||||||
echo "<div class=\"card bg-light card-body\">Conferences for the last 2 days</div></a>";
|
|
||||||
|
|
||||||
echo "<div class=\"collapse show\" id=\"collapseLastDays\">";
|
|
||||||
|
|
||||||
if ($time_range_specified) {
|
|
||||||
echo "<p class=\"m-3\">time period: <strong>$from_time - $until_time</strong></p>";
|
|
||||||
}
|
|
||||||
|
|
||||||
//// filters - time selection and sorting dropdowns
|
|
||||||
//include 'templates/results-filter.php';
|
|
||||||
|
|
||||||
// results table
|
|
||||||
echo "<div class=\"mb-5\">\n";
|
|
||||||
|
|
||||||
if (!empty($conferences['records'])) {
|
|
||||||
|
|
||||||
echo "\t<table class=\"table table-striped table-hover table-bordered\">\n";
|
|
||||||
|
|
||||||
echo "\t\t<thead class=\"thead-dark\">\n";
|
|
||||||
echo "\t\t\t<tr>\n";
|
|
||||||
|
|
||||||
// table headers
|
|
||||||
foreach (array_keys($conferences['records'][0]) as $header) {
|
|
||||||
echo "\t\t\t\t<th scope=\"col\">" . htmlspecialchars($header) . "</th>\n";
|
|
||||||
}
|
|
||||||
echo "\t\t\t</tr>\n";
|
|
||||||
echo "\t\t</thead>\n";
|
|
||||||
|
|
||||||
echo "\t\t<tbody>\n";
|
|
||||||
|
|
||||||
//table rows
|
|
||||||
foreach ($conferences['records'] as $row) {
|
|
||||||
echo "\t\t\t<tr>\n";
|
|
||||||
// sometimes $column is empty, we make it '' then
|
|
||||||
foreach ($row as $key => $column) {
|
|
||||||
if ($key === 'conference ID' && $column === $conference_id) {
|
|
||||||
echo "\t\t\t\t<td><strong>" . htmlspecialchars($column ?? '') . "</strong></td>\n";
|
|
||||||
} elseif ($key === 'conference name') {
|
|
||||||
echo "\t\t\t\t<td><a href=\"$app_root?page=conferences&name=" . htmlspecialchars($column ?? '') . "\">" . htmlspecialchars($column ?? '') . "</a></td>\n";
|
|
||||||
} else {
|
|
||||||
echo "\t\t\t\t<td>" . htmlspecialchars($column ?? '') . "</td>\n";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
echo "\t\t\t</tr>\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
echo "\t\t</tbody>\n";
|
|
||||||
echo "\t</table>\n";
|
|
||||||
|
|
||||||
} else {
|
|
||||||
echo '<p class="m-3">No matching conferences found.</p>';
|
|
||||||
}
|
|
||||||
echo "\n</div>\n";
|
|
||||||
|
|
||||||
echo "</div>";
|
|
||||||
|
|
||||||
echo "<br />";
|
|
||||||
|
|
||||||
// last 10 conferences
|
|
||||||
try {
|
|
||||||
$conference = new Conference($db);
|
|
||||||
|
|
||||||
// all time
|
|
||||||
$from_time = '0000-01-01';
|
|
||||||
$until_time = '9999-12-31';
|
|
||||||
$time_range_specified = false;
|
|
||||||
// number of conferences to show
|
|
||||||
$conference_number = 10;
|
|
||||||
|
|
||||||
// prepare the result
|
|
||||||
$search = $conference->conferencesAllFormatted($from_time, $until_time);
|
|
||||||
|
|
||||||
if (!empty($search)) {
|
|
||||||
$conferences = array();
|
|
||||||
$conferences['records'] = array();
|
|
||||||
|
|
||||||
$i = 0;
|
|
||||||
foreach ($search as $item) {
|
|
||||||
extract($item);
|
|
||||||
|
|
||||||
// we don't have duration field, so we calculate it
|
|
||||||
if (!empty($start) && !empty($end)) {
|
|
||||||
$duration = gmdate("H:i:s", abs(strtotime($end) - strtotime($start)));
|
|
||||||
} else {
|
|
||||||
$duration = '';
|
|
||||||
}
|
|
||||||
$conference_record = array(
|
|
||||||
// assign title to the field in the array record
|
|
||||||
'component' => $jitsi_component,
|
|
||||||
'start' => $start,
|
|
||||||
'end' => $end,
|
|
||||||
'duration' => $duration,
|
|
||||||
'conference ID' => $conference_id,
|
|
||||||
'conference name' => $conference_name,
|
|
||||||
'participants' => $participants,
|
|
||||||
'name count' => $name_count,
|
|
||||||
'conference host' => $conference_host
|
|
||||||
);
|
|
||||||
// populate the result array
|
|
||||||
array_push($conferences['records'], $conference_record);
|
|
||||||
|
|
||||||
// we only take the first 10 results
|
|
||||||
$i++;
|
|
||||||
if ($i == 10) break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} catch (Exception $e) {
|
|
||||||
$error = 'Error: ' . $e->getMessage();
|
|
||||||
include 'templates/message.php';
|
|
||||||
exit();
|
|
||||||
}
|
|
||||||
|
|
||||||
// display the result
|
|
||||||
echo "<a style=\"text-decoration: none;\" data-toggle=\"collapse\" href=\"#collapseLastConferences\" role=\"button\" aria-expanded=\"true\" aria-controls=\"collapseLastConferences\">";
|
|
||||||
echo "<div class=\"card bg-light card-body\">The last $conference_number conferences</div></a>";
|
|
||||||
|
|
||||||
echo "<div class=\"collapse show\" id=\"collapseLastConferences\">";
|
|
||||||
|
|
||||||
if ($time_range_specified) {
|
|
||||||
echo "<br />for the time period <strong>$from_time - $until_time</strong>";
|
|
||||||
}
|
|
||||||
|
|
||||||
//// filters - time selection and sorting dropdowns
|
|
||||||
//include 'templates/results-filter.php';
|
|
||||||
|
|
||||||
// results table
|
|
||||||
echo "<div class=\"mb-5\">\n";
|
|
||||||
|
|
||||||
if (!empty($conferences['records'])) {
|
|
||||||
|
|
||||||
echo "\t<table class=\"table table-striped table-hover table-bordered\">\n";
|
|
||||||
|
|
||||||
echo "\t\t<thead class=\"table-secondary\">\n";
|
|
||||||
echo "\t\t\t<tr>\n";
|
|
||||||
|
|
||||||
// table headers
|
|
||||||
foreach (array_keys($conferences['records'][0]) as $header) {
|
|
||||||
echo "\t\t\t\t<th scope=\"col\">" . htmlspecialchars($header) . "</th>\n";
|
|
||||||
}
|
|
||||||
echo "\t\t\t</tr>\n";
|
|
||||||
echo "\t\t</thead>\n";
|
|
||||||
|
|
||||||
echo "\t\t<tbody>\n";
|
|
||||||
|
|
||||||
//table rows
|
|
||||||
foreach ($conferences['records'] as $row) {
|
|
||||||
echo "\t\t\t<tr>\n";
|
|
||||||
// sometimes $column is empty, we make it '' then
|
|
||||||
foreach ($row as $key => $column) {
|
|
||||||
if ($key === 'conference ID') {
|
|
||||||
echo "\t\t\t\t<td><a href=\"$app_root?page=conferences&id=" . htmlspecialchars($column ?? '') . "\">" . htmlspecialchars($column ?? '') . "</a></td>\n";
|
|
||||||
} elseif ($key === 'conference name') {
|
|
||||||
echo "\t\t\t\t<td><a href=\"$app_root?page=conferences&name=" . htmlspecialchars($column ?? '') . "\">" . htmlspecialchars($column ?? '') . "</a></td>\n";
|
|
||||||
} else {
|
|
||||||
echo "\t\t\t\t<td>" . htmlspecialchars($column ?? '') . "</td>\n";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
echo "\t\t\t</tr>\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
echo "\t\t</tbody>\n";
|
|
||||||
echo "\t</table>\n";
|
|
||||||
|
|
||||||
} else {
|
|
||||||
echo '<p class="m-3">No matching conferences found.</p>';
|
|
||||||
}
|
|
||||||
echo "\n</div>\n";
|
|
||||||
|
|
||||||
echo "</div>";
|
|
||||||
|
|
||||||
|
|
||||||
?>
|
|
|
@ -1,444 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
require_once 'classes/database.php';
|
|
||||||
require 'classes/participant.php';
|
|
||||||
|
|
||||||
// FIXME move thi sto a special function
|
|
||||||
$time_range_specified = false;
|
|
||||||
if (!isset($_REQUEST['from_time']) || (isset($_REQUEST['from_time']) && $_REQUEST['from_time'] == '')) {
|
|
||||||
$from_time = '0000-01-01';
|
|
||||||
} else {
|
|
||||||
$from_time = $_REQUEST['from_time'];
|
|
||||||
$time_range_specified = true;
|
|
||||||
}
|
|
||||||
if (!isset($_REQUEST['until_time']) || (isset($_REQUEST['until_time']) && $_REQUEST['until_time'] == '')) {
|
|
||||||
$until_time = '9999-12-31';
|
|
||||||
} else {
|
|
||||||
$until_time = $_REQUEST['until_time'];
|
|
||||||
$time_range_specified = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// participant id/name/IP are specified when searching specific participant(s)
|
|
||||||
// participant name - this is 'stats_id' in the db
|
|
||||||
// either id, name, OR IP - in that order
|
|
||||||
// we use $_REQUEST, so that both links and forms work
|
|
||||||
if (isset($_REQUEST['id']) && $_REQUEST['id'] != '') {
|
|
||||||
$participant_id = $_REQUEST['id'];
|
|
||||||
unset($_REQUEST['name']);
|
|
||||||
unset($participant_name);
|
|
||||||
} elseif (isset($_REQUEST['name']) && $_REQUEST['name'] != '') {
|
|
||||||
unset($participant_id);
|
|
||||||
$participant_name = $_REQUEST['name'];
|
|
||||||
} elseif (isset($_REQUEST['ip']) && $_REQUEST['ip'] != '') {
|
|
||||||
unset($participant_id);
|
|
||||||
$participant_ip = $_REQUEST['ip'];
|
|
||||||
} else {
|
|
||||||
unset($participant_id);
|
|
||||||
unset($participant_name);
|
|
||||||
}
|
|
||||||
|
|
||||||
// connect to database
|
|
||||||
try {
|
|
||||||
$db = new Database($config['jilo_database']);
|
|
||||||
} catch (Exception $e) {
|
|
||||||
$error = 'Error: ' . $e->getMessage();
|
|
||||||
include 'templates/message.php';
|
|
||||||
exit();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//
|
|
||||||
// Participant listings
|
|
||||||
//
|
|
||||||
|
|
||||||
|
|
||||||
// search and list specific participant ID
|
|
||||||
if (isset($participant_id)) {
|
|
||||||
|
|
||||||
try {
|
|
||||||
$participant = new Participant($db);
|
|
||||||
|
|
||||||
// prepare the result
|
|
||||||
$search = $participant->conferenceByParticipantId($participant_id, $from_time, $until_time, $participant_id, $from_time, $until_time);
|
|
||||||
|
|
||||||
if (!empty($search)) {
|
|
||||||
$conferences = array();
|
|
||||||
$conferences['records'] = array();
|
|
||||||
|
|
||||||
foreach ($search as $item) {
|
|
||||||
extract($item);
|
|
||||||
$conference_record = array(
|
|
||||||
// assign title to the field in the array record
|
|
||||||
'time' => $time,
|
|
||||||
'conference ID' => $conference_id,
|
|
||||||
'conference name' => $conference_name,
|
|
||||||
'conference host' => $conference_host,
|
|
||||||
'loglevel' => $loglevel,
|
|
||||||
'participant ID' => $participant_id,
|
|
||||||
'event' => $event_type,
|
|
||||||
'parameter' => $event_param
|
|
||||||
);
|
|
||||||
// populate the result array
|
|
||||||
array_push($conferences['records'], $conference_record);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} catch (Exception $e) {
|
|
||||||
$error = 'Error: ' . $e->getMessage();
|
|
||||||
include 'templates/message.php';
|
|
||||||
exit();
|
|
||||||
}
|
|
||||||
|
|
||||||
// display the result
|
|
||||||
echo "<div class=\"results-header\">\n";
|
|
||||||
echo "<div class=\"results-message\">Conferences with participant ID matching \"<strong>$participant_id</strong>\"";
|
|
||||||
if ($time_range_specified) {
|
|
||||||
echo "<br />for the time period <strong>$from_time - $until_time</strong>";
|
|
||||||
}
|
|
||||||
echo "</div>\n\n";
|
|
||||||
|
|
||||||
// filters - time selection and sorting dropdowns
|
|
||||||
include 'templates/results-filter.php';
|
|
||||||
|
|
||||||
echo "</div>\n\n";
|
|
||||||
|
|
||||||
// results table
|
|
||||||
echo "<div class=\"mb-5\">\n";
|
|
||||||
|
|
||||||
if (!empty($conferences['records'])) {
|
|
||||||
|
|
||||||
echo "\t<table class=\"table table-striped table-hover table-bordered\">\n";
|
|
||||||
|
|
||||||
echo "\t\t<thead class=\"table-secondary\">\n";
|
|
||||||
echo "\t\t\t<tr>\n";
|
|
||||||
|
|
||||||
// table headers
|
|
||||||
foreach (array_keys($conferences['records'][0]) as $header) {
|
|
||||||
echo "\t\t\t\t<th scope=\"col\">" . htmlspecialchars($header) . "</th>\n";
|
|
||||||
}
|
|
||||||
echo "\t\t\t</tr>\n";
|
|
||||||
echo "\t\t</thead>\n";
|
|
||||||
|
|
||||||
echo "\t\t<tbody>\n";
|
|
||||||
|
|
||||||
//table rows
|
|
||||||
foreach ($conferences['records'] as $row) {
|
|
||||||
echo "\t\t\t<tr>\n";
|
|
||||||
$stats_id = false;
|
|
||||||
$participant_ip = false;
|
|
||||||
if ($row['event'] === 'stats_id') $stats_id = true;
|
|
||||||
if ($row['event'] === 'pair selected') $participant_ip = true;
|
|
||||||
// sometimes $column is empty, we make it '' then
|
|
||||||
foreach ($row as $key => $column) {
|
|
||||||
if ($key === 'participant ID' && $column === $participant_id) {
|
|
||||||
echo "\t\t\t\t<td><strong>" . htmlspecialchars($column ?? '') . "</strong></td>\n";
|
|
||||||
} elseif ($key === 'conference ID') {
|
|
||||||
echo "\t\t\t\t<td><a href=\"$app_root?page=conferences&id=" . htmlspecialchars($column ?? '') . "\">" . htmlspecialchars($column ?? '') . "</a></td>\n";
|
|
||||||
} elseif ($key === 'conference name') {
|
|
||||||
echo "\t\t\t\t<td><a href=\"$app_root?page=conferences&name=" . htmlspecialchars($column ?? '') . "\">" . htmlspecialchars($column ?? '') . "</a></td>\n";
|
|
||||||
} elseif ($stats_id && $key === 'parameter') {
|
|
||||||
echo "\t\t\t\t<td><a href=\"$app_root?page=participants&name=" . htmlspecialchars($column ?? '') . "\">" . htmlspecialchars($column ?? '') . "</a></td>\n";
|
|
||||||
} elseif ($participant_ip && $key === 'parameter') {
|
|
||||||
echo "\t\t\t\t<td><a href=\"$app_root?page=participants&ip=" . htmlspecialchars($column ?? '') . "\">" . htmlspecialchars($column ?? '') . "</a></td>\n";
|
|
||||||
} else {
|
|
||||||
echo "\t\t\t\t<td>" . htmlspecialchars($column ?? '') . "</td>\n";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
echo "\t\t\t</tr>\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
echo "\t\t</tbody>\n";
|
|
||||||
echo "\t</table>\n";
|
|
||||||
|
|
||||||
} else {
|
|
||||||
echo '<p class="m-3">No matching conferences found.</p>';
|
|
||||||
}
|
|
||||||
echo "\n</div>\n";
|
|
||||||
|
|
||||||
|
|
||||||
// search and list specific participant name (stats_id)
|
|
||||||
} elseif (isset($participant_name)) {
|
|
||||||
|
|
||||||
try {
|
|
||||||
$participant = new Participant($db);
|
|
||||||
|
|
||||||
// prepare the result
|
|
||||||
$search = $participant->conferenceByParticipantName($participant_name, $from_time, $until_time);
|
|
||||||
|
|
||||||
if (!empty($search)) {
|
|
||||||
$conferences = array();
|
|
||||||
$conferences['records'] = array();
|
|
||||||
|
|
||||||
foreach ($search as $item) {
|
|
||||||
extract($item);
|
|
||||||
$conference_record = array(
|
|
||||||
// assign title to the field in the array record
|
|
||||||
'time' => $time,
|
|
||||||
'conference ID' => $conference_id,
|
|
||||||
'conference name' => $conference_name,
|
|
||||||
'conference host' => $conference_host,
|
|
||||||
'loglevel' => $loglevel,
|
|
||||||
'participant ID' => $participant_id,
|
|
||||||
'event' => $event_type,
|
|
||||||
'parameter' => $event_param
|
|
||||||
);
|
|
||||||
// populate the result array
|
|
||||||
array_push($conferences['records'], $conference_record);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} catch (Exception $e) {
|
|
||||||
$error = 'Error: ' . $e->getMessage();
|
|
||||||
include 'templates/message.php';
|
|
||||||
exit();
|
|
||||||
}
|
|
||||||
|
|
||||||
// display the result
|
|
||||||
echo "<div class=\"results-header\">\n";
|
|
||||||
echo "<div class=\"results-message\">Conferences with participant name (stats_id) matching \"<strong>$participant_name</strong>\"";
|
|
||||||
if ($time_range_specified) {
|
|
||||||
echo "<br />for the time period <strong>$from_time - $until_time</strong>";
|
|
||||||
}
|
|
||||||
echo "</div>\n\n";
|
|
||||||
|
|
||||||
// filters - time selection and sorting dropdowns
|
|
||||||
include 'templates/results-filter.php';
|
|
||||||
|
|
||||||
echo "</div>\n\n";
|
|
||||||
|
|
||||||
// results table
|
|
||||||
echo "<div class=\"mb-5\">\n";
|
|
||||||
|
|
||||||
if (!empty($conferences['records'])) {
|
|
||||||
|
|
||||||
echo "\t<table class=\"table table-striped table-hover table-bordered\">\n";
|
|
||||||
|
|
||||||
echo "\t\t<thead class=\"table-secondary\">\n";
|
|
||||||
echo "\t\t\t<tr>\n";
|
|
||||||
|
|
||||||
// table headers
|
|
||||||
foreach (array_keys($conferences['records'][0]) as $header) {
|
|
||||||
echo "\t\t\t\t<th scope-\"col\">" . htmlspecialchars($header) . "</th>\n";
|
|
||||||
}
|
|
||||||
echo "\t\t\t</tr>\n";
|
|
||||||
echo "\t\t</thead>\n";
|
|
||||||
|
|
||||||
echo "\t\t<tbody>\n";
|
|
||||||
|
|
||||||
//table rows
|
|
||||||
foreach ($conferences['records'] as $row) {
|
|
||||||
echo "\t\t\t<tr>\n";
|
|
||||||
// sometimes $column is empty, we make it '' then
|
|
||||||
foreach ($row as $key => $column) {
|
|
||||||
if ($key === 'parameter' && $column === $participant_name) {
|
|
||||||
echo "\t\t\t\t<td><strong>" . htmlspecialchars($column ?? '') . "</strong></td>\n";
|
|
||||||
} elseif ($key === 'conference ID') {
|
|
||||||
echo "\t\t\t\t<td><a href=\"$app_root?page=conferences&id=" . htmlspecialchars($column ?? '') . "\">" . htmlspecialchars($column ?? '') . "</a></td>\n";
|
|
||||||
} elseif ($key === 'conference name') {
|
|
||||||
echo "\t\t\t\t<td><a href=\"$app_root?page=conferences&name=" . htmlspecialchars($column ?? '') . "\">" . htmlspecialchars($column ?? '') . "</a></td>\n";
|
|
||||||
} elseif ($key === 'participant ID') {
|
|
||||||
echo "\t\t\t\t<td><a href=\"$app_root?page=participants&id=" . htmlspecialchars($column ?? '') . "\">" . htmlspecialchars($column ?? '') . "</a></td>\n";
|
|
||||||
} else {
|
|
||||||
echo "\t\t\t\t<td>" . htmlspecialchars($column ?? '') . "</td>\n";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
echo "\t\t\t</tr>\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
echo "\t\t</tbody>\n";
|
|
||||||
echo "\t</table>\n";
|
|
||||||
|
|
||||||
} else {
|
|
||||||
echo '<p class="m-3">No matching conferences found.</p>';
|
|
||||||
}
|
|
||||||
echo "\n</div>\n";
|
|
||||||
|
|
||||||
|
|
||||||
// search and list specific participant IP
|
|
||||||
} elseif (isset($participant_ip)) {
|
|
||||||
|
|
||||||
try {
|
|
||||||
$participant = new Participant($db);
|
|
||||||
|
|
||||||
// prepare the result
|
|
||||||
$search = $participant->conferenceByParticipantIP($participant_ip, $from_time, $until_time);
|
|
||||||
|
|
||||||
if (!empty($search)) {
|
|
||||||
$conferences = array();
|
|
||||||
$conferences['records'] = array();
|
|
||||||
|
|
||||||
foreach ($search as $item) {
|
|
||||||
extract($item);
|
|
||||||
$conference_record = array(
|
|
||||||
// assign title to the field in the array record
|
|
||||||
'time' => $time,
|
|
||||||
'conference ID' => $conference_id,
|
|
||||||
'conference name' => $conference_name,
|
|
||||||
'conference host' => $conference_host,
|
|
||||||
'loglevel' => $loglevel,
|
|
||||||
'participant ID' => $participant_id,
|
|
||||||
'event' => $event_type,
|
|
||||||
'parameter' => $event_param
|
|
||||||
);
|
|
||||||
// populate the result array
|
|
||||||
array_push($conferences['records'], $conference_record);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} catch (Exception $e) {
|
|
||||||
$error = 'Error: ' . $e->getMessage();
|
|
||||||
include 'templates/message.php';
|
|
||||||
exit();
|
|
||||||
}
|
|
||||||
|
|
||||||
// display the result
|
|
||||||
echo "<div class=\"results-header\">\n";
|
|
||||||
echo "<div class=\"results-message\">Conferences with participant IP matching \"<strong>$participant_ip</strong>\"";
|
|
||||||
if ($time_range_specified) {
|
|
||||||
echo "<br />for the time period <strong>$from_time - $until_time</strong>";
|
|
||||||
}
|
|
||||||
echo "</div>\n\n";
|
|
||||||
|
|
||||||
// filters - time selection and sorting dropdowns
|
|
||||||
include 'templates/results-filter.php';
|
|
||||||
|
|
||||||
echo "</div>\n\n";
|
|
||||||
|
|
||||||
// results table
|
|
||||||
echo "<div class=\"mb-5\">\n";
|
|
||||||
|
|
||||||
if (!empty($conferences['records'])) {
|
|
||||||
|
|
||||||
echo "\t<table class=\"table table-striped table-hover table-bordered\">\n";
|
|
||||||
|
|
||||||
echo "\t\t<thead class=\"table-secondary\">\n";
|
|
||||||
echo "\t\t\t<tr>\n";
|
|
||||||
|
|
||||||
// table headers
|
|
||||||
foreach (array_keys($conferences['records'][0]) as $header) {
|
|
||||||
echo "\t\t\t\t<th scope=\"col\">" . htmlspecialchars($header) . "</th>\n";
|
|
||||||
}
|
|
||||||
echo "\t\t\t</tr>\n";
|
|
||||||
echo "\t\t</thead>\n";
|
|
||||||
|
|
||||||
echo "\t\t<tbody>\n";
|
|
||||||
|
|
||||||
//table rows
|
|
||||||
foreach ($conferences['records'] as $row) {
|
|
||||||
echo "\t\t\t<tr>\n";
|
|
||||||
// sometimes $column is empty, we make it '' then
|
|
||||||
foreach ($row as $key => $column) {
|
|
||||||
if ($key === 'parameter' && $column === $participant_ip) {
|
|
||||||
echo "\t\t\t\t<td><strong>" . htmlspecialchars($column ?? '') . "</strong></td>\n";
|
|
||||||
} elseif ($key === 'conference ID') {
|
|
||||||
echo "\t\t\t\t<td><a href=\"$app_root?page=conferences&id=" . htmlspecialchars($column ?? '') . "\">" . htmlspecialchars($column ?? '') . "</a></td>\n";
|
|
||||||
} elseif ($key === 'conference name') {
|
|
||||||
echo "\t\t\t\t<td><a href=\"$app_root?page=conferences&name=" . htmlspecialchars($column ?? '') . "\">" . htmlspecialchars($column ?? '') . "</a></td>\n";
|
|
||||||
} elseif ($key === 'participant ID') {
|
|
||||||
echo "\t\t\t\t<td><a href=\"$app_root?page=participants&id=" . htmlspecialchars($column ?? '') . "\">" . htmlspecialchars($column ?? '') . "</a></td>\n";
|
|
||||||
} else {
|
|
||||||
echo "\t\t\t\t<td>" . htmlspecialchars($column ?? '') . "</td>\n";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
echo "\t\t\t</tr>\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
echo "\t\t</tbody>\n";
|
|
||||||
echo "\t</table>\n";
|
|
||||||
|
|
||||||
} else {
|
|
||||||
echo '<p class="m-3">No matching conferences found.</p>';
|
|
||||||
}
|
|
||||||
echo "\n</div>\n";
|
|
||||||
|
|
||||||
|
|
||||||
// list of all participants (default)
|
|
||||||
} else {
|
|
||||||
try {
|
|
||||||
$participant = new Participant($db);
|
|
||||||
|
|
||||||
// prepare the result
|
|
||||||
$search = $participant->participantsAll($from_time, $until_time);
|
|
||||||
|
|
||||||
if (!empty($search)) {
|
|
||||||
$participants = array();
|
|
||||||
$participants['records'] = array();
|
|
||||||
|
|
||||||
foreach ($search as $item) {
|
|
||||||
extract($item);
|
|
||||||
$participant_record = array(
|
|
||||||
// assign title to the field in the array record
|
|
||||||
'component' => $jitsi_component,
|
|
||||||
'participant ID' => $endpoint_id,
|
|
||||||
'conference ID' => $conference_id,
|
|
||||||
);
|
|
||||||
// populate the result array
|
|
||||||
array_push($participants['records'], $participant_record);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} catch (Exception $e) {
|
|
||||||
$error = 'Error: ' . $e->getMessage();
|
|
||||||
include 'templates/message.php';
|
|
||||||
exit();
|
|
||||||
}
|
|
||||||
|
|
||||||
// display the result
|
|
||||||
echo "<div class=\"results-header\">\n";
|
|
||||||
echo "<div class=\"results-message\">All participants";
|
|
||||||
if ($time_range_specified) {
|
|
||||||
echo "<br />for the time period <strong>$from_time - $until_time</strong>";
|
|
||||||
}
|
|
||||||
echo "</div>\n\n";
|
|
||||||
|
|
||||||
// filters - time selection and sorting dropdowns
|
|
||||||
include 'templates/results-filter.php';
|
|
||||||
|
|
||||||
echo "</div>\n\n";
|
|
||||||
|
|
||||||
// results table
|
|
||||||
echo "<div class=\"mb-5\">\n";
|
|
||||||
|
|
||||||
if (!empty($participants['records'])) {
|
|
||||||
|
|
||||||
echo "\t<table class=\"table table-striped table-hover table-bordered\">\n";
|
|
||||||
|
|
||||||
echo "\t\t<thead class=\"table-secondary\">\n";
|
|
||||||
echo "\t\t\t<tr>\n";
|
|
||||||
|
|
||||||
// table headers
|
|
||||||
foreach (array_keys($participants['records'][0]) as $header) {
|
|
||||||
echo "\t\t\t\t<th>" . htmlspecialchars($header) . "</th>\n";
|
|
||||||
}
|
|
||||||
echo "\t\t\t</tr>\n";
|
|
||||||
echo "\t\t</thead>\n";
|
|
||||||
|
|
||||||
echo "\t\t<tbody>\n";
|
|
||||||
|
|
||||||
//table rows
|
|
||||||
foreach ($participants['records'] as $row) {
|
|
||||||
echo "\t\t\t<tr>\n";
|
|
||||||
// sometimes $column is empty, we make it '' then
|
|
||||||
foreach ($row as $key => $column) {
|
|
||||||
if ($key === 'participant ID') {
|
|
||||||
echo "\t\t\t\t<td><a href=\"$app_root?page=participants&id=" . htmlspecialchars($column ?? '') . "\">" . htmlspecialchars($column ?? '') . "</a></td>\n";
|
|
||||||
} elseif ($key === 'conference ID') {
|
|
||||||
echo "\t\t\t\t<td><a href=\"$app_root?page=conferences&id=" . htmlspecialchars($column ?? '') . "\">" . htmlspecialchars($column ?? '') . "</a></td>\n";
|
|
||||||
} else {
|
|
||||||
echo "\t\t\t\t<td>" . htmlspecialchars($column ?? '') . "</td>\n";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
echo "\t\t\t</tr>\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
echo "\t\t</tbody>\n";
|
|
||||||
echo "\t</table>\n";
|
|
||||||
|
|
||||||
} else {
|
|
||||||
echo '<p class="m-3">No matching participants found.</p>';
|
|
||||||
}
|
|
||||||
echo "\n</div>\n";
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
?>
|
|
|
@ -1,11 +0,0 @@
|
||||||
<?php ?>
|
|
||||||
|
|
||||||
<div>
|
|
||||||
|
|
||||||
<p>Profile of <?= $user ?></p>
|
|
||||||
|
|
||||||
<ul>
|
|
||||||
<li>username: <?= $_SESSION['username'] ?></li>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
</div>
|
|
|
@ -1,34 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
require_once 'classes/database.php';
|
|
||||||
require 'classes/user.php';
|
|
||||||
unset($error);
|
|
||||||
|
|
||||||
try {
|
|
||||||
$db = new Database($config['database']);
|
|
||||||
$user = new User($db);
|
|
||||||
|
|
||||||
if ( $_SERVER['REQUEST_METHOD'] == 'POST' ) {
|
|
||||||
$username = $_POST['username'];
|
|
||||||
$password = $_POST['password'];
|
|
||||||
|
|
||||||
// redirect to login
|
|
||||||
if ( $user->register($username, $password) ) {
|
|
||||||
$_SESSION['notice'] = "Registration successful.<br />You can log in now.";
|
|
||||||
header('Location: index.php');
|
|
||||||
exit();
|
|
||||||
// registration fail, redirect to login
|
|
||||||
} else {
|
|
||||||
$_SESSION['error'] = "Registration failed.";
|
|
||||||
header('Location: index.php');
|
|
||||||
exit();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (Exception $e) {
|
|
||||||
$error = $e->getMessage();
|
|
||||||
}
|
|
||||||
|
|
||||||
include 'templates/message.php';
|
|
||||||
include 'templates/form-register.php';
|
|
||||||
|
|
||||||
?>
|
|
|
@ -78,31 +78,6 @@
|
||||||
color: white;
|
color: white;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
.results {
|
|
||||||
margin-bottom: 50px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.results table {
|
|
||||||
width: 100%;
|
|
||||||
border-collapse: collapse;
|
|
||||||
margin: 20px 0;
|
|
||||||
}
|
|
||||||
.results table, th, td {
|
|
||||||
border: 1px solid #ddd;
|
|
||||||
}
|
|
||||||
.results th, td {
|
|
||||||
padding: 8px;
|
|
||||||
text-align: left;
|
|
||||||
}
|
|
||||||
.results th {
|
|
||||||
background-color: #f2f2f2;
|
|
||||||
}
|
|
||||||
.results p {
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
.results-header {
|
.results-header {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
|
@ -120,3 +95,65 @@
|
||||||
.widget {
|
.widget {
|
||||||
border: 1px solid gray;
|
border: 1px solid gray;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* collapsing sidebar */
|
||||||
|
.toggle-sidebar-button {
|
||||||
|
position: absolute;
|
||||||
|
top: -10px;
|
||||||
|
right: -10px;
|
||||||
|
z-index: 100;
|
||||||
|
margin: 10px;
|
||||||
|
height: 22px;
|
||||||
|
width: 22px;
|
||||||
|
padding-left: 2px;
|
||||||
|
padding-top: 0px;
|
||||||
|
}
|
||||||
|
.sidebar-wrapper {
|
||||||
|
position: relative;
|
||||||
|
width: 275px;
|
||||||
|
transition: width 0.5s ease;
|
||||||
|
overflow-x: hidden;
|
||||||
|
}
|
||||||
|
.sidebar-wrapper.collapsed {
|
||||||
|
width: 3em;
|
||||||
|
}
|
||||||
|
.sidebar-collapsed .sidebar-wrapper {
|
||||||
|
width: 3em;
|
||||||
|
}
|
||||||
|
.sidebar-content {
|
||||||
|
width: 250px;
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
.list-group-item i {
|
||||||
|
margin-right: 10px;
|
||||||
|
margin-left: -8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.main-content {
|
||||||
|
flex-grow: 1;
|
||||||
|
transition: width 0.5s ease;
|
||||||
|
width: 80%;
|
||||||
|
}
|
||||||
|
.main-content.expanded {
|
||||||
|
width: calc(70% + 250px);
|
||||||
|
}
|
||||||
|
.sidebar-collapsed .main-content {
|
||||||
|
width: calc(70% + 3em);
|
||||||
|
}
|
||||||
|
|
||||||
|
.logo {
|
||||||
|
height: 35px;
|
||||||
|
margin-top: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.logo-link {
|
||||||
|
border: 1px solid white;
|
||||||
|
margin-top: 2px;
|
||||||
|
margin-left: 2px;
|
||||||
|
background-color: lightseagreen;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar-content a {
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
Binary file not shown.
After Width: | Height: | Size: 2.6 KiB |
|
@ -0,0 +1,49 @@
|
||||||
|
|
||||||
|
document.addEventListener('DOMContentLoaded', function () {
|
||||||
|
var sidebar = document.getElementById('sidebar');
|
||||||
|
var mainContent = document.getElementById('mainContent');
|
||||||
|
var toggleButton = document.getElementById('toggleSidebarButton');
|
||||||
|
|
||||||
|
// update localStorage based on the current state
|
||||||
|
function updateStorage() {
|
||||||
|
var isSidebarCollapsed = sidebar.classList.contains('collapsed');
|
||||||
|
localStorage.setItem('sidebarState', isSidebarCollapsed ? 'collapsed' : 'expanded');
|
||||||
|
}
|
||||||
|
|
||||||
|
// apply saved state
|
||||||
|
function applySavedState() {
|
||||||
|
var savedState = localStorage.getItem('sidebarState');
|
||||||
|
if (savedState === 'collapsed') {
|
||||||
|
toggleButton.value = ">>";
|
||||||
|
toggleButton.textContent = ">>";
|
||||||
|
sidebar.classList.add('collapsed');
|
||||||
|
mainContent.classList.add('expanded');
|
||||||
|
} else {
|
||||||
|
toggleButton.value = "<<";
|
||||||
|
toggleButton.textContent = "<<";
|
||||||
|
sidebar.classList.remove('collapsed');
|
||||||
|
mainContent.classList.remove('expanded');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initialize
|
||||||
|
applySavedState();
|
||||||
|
|
||||||
|
toggleButton.addEventListener('click', function () {
|
||||||
|
// toggle sidebar and main content
|
||||||
|
sidebar.classList.toggle('collapsed');
|
||||||
|
document.documentElement.classList.toggle('sidebar-collapsed');
|
||||||
|
mainContent.classList.toggle('expanded');
|
||||||
|
// Toggle the value between ">>" and "<<"
|
||||||
|
if (toggleButton.value === ">>") {
|
||||||
|
toggleButton.value = "<<";
|
||||||
|
toggleButton.textContent = "<<";
|
||||||
|
} else {
|
||||||
|
toggleButton.value = ">>";
|
||||||
|
toggleButton.textContent = ">>";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update with the new state
|
||||||
|
updateStorage();
|
||||||
|
});
|
||||||
|
});
|
|
@ -1,8 +0,0 @@
|
||||||
|
|
||||||
<div id="footer">Jilo Web <?= $config['version'] ?> ©2024 - web interface for <a href="https://lindeas.com/jilo">Jilo</a></div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</body>
|
|
||||||
|
|
||||||
</html>
|
|
|
@ -1,17 +0,0 @@
|
||||||
|
|
||||||
<h2>Login</h2>
|
|
||||||
|
|
||||||
<div class="login-form">
|
|
||||||
<form method="POST" action="?page=login">
|
|
||||||
<input type="text" name="username" placeholder="Username" required />
|
|
||||||
<br />
|
|
||||||
<input type="password" name="password" placeholder="Password" required />
|
|
||||||
<br />
|
|
||||||
<label for="remember_me">
|
|
||||||
<input type="checkbox" id="remember_me" name="remember_me" />
|
|
||||||
remember me
|
|
||||||
</label>
|
|
||||||
<br />
|
|
||||||
<input type="submit" value="Login" />
|
|
||||||
</form>
|
|
||||||
</div>
|
|
|
@ -1,12 +0,0 @@
|
||||||
|
|
||||||
<h2>Register</h2>
|
|
||||||
|
|
||||||
<div class="register-form">
|
|
||||||
<form method="POST" action="?page=register">
|
|
||||||
<input type="text" name="username" placeholder="Username" required />
|
|
||||||
<br />
|
|
||||||
<input type="password" name="password" placeholder="Password" required />
|
|
||||||
<br />
|
|
||||||
<input type="submit" value="Register" />
|
|
||||||
</form>
|
|
||||||
</div>
|
|
|
@ -1,22 +0,0 @@
|
||||||
|
|
||||||
<div class="menu-container">
|
|
||||||
<ul class="menu-left">
|
|
||||||
<li><a href="index.php">home</a></li>
|
|
||||||
<?php if ( isset($_SESSION['username']) ) { ?>
|
|
||||||
<li><a href="?page=config">config</a></li>
|
|
||||||
<li><a href="?page=conferences">conferences</a></li>
|
|
||||||
<li><a href="?page=participants">participants</a></li>
|
|
||||||
<li><a href="?page=components">components</a></li>
|
|
||||||
<?php } ?>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
<ul class="menu-right">
|
|
||||||
<?php if ( isset($_SESSION['username']) ) { ?>
|
|
||||||
<li><a href="?page=profile"><?= $user ?></a></li>
|
|
||||||
<li><a href="?page=logout">logout</a></li>
|
|
||||||
<?php } else { ?>
|
|
||||||
<li><a href="?page=login">login</a></li>
|
|
||||||
<li><a href="?page=register">register</a></li>
|
|
||||||
<?php } ?>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
|
@ -1,12 +0,0 @@
|
||||||
|
|
||||||
<?php if (isset($error)) { ?>
|
|
||||||
<div class="error">
|
|
||||||
<?php echo $error; ?>
|
|
||||||
</div>
|
|
||||||
<?php } ?>
|
|
||||||
|
|
||||||
<?php if (isset($notice)) { ?>
|
|
||||||
<div class="notice">
|
|
||||||
<?php echo $notice; ?>
|
|
||||||
</div>
|
|
||||||
<?php } ?>
|
|
|
@ -1,44 +0,0 @@
|
||||||
|
|
||||||
<div class="results-filter">
|
|
||||||
|
|
||||||
<form method="POST" id="filter_form" action="?page=<?= $page ?>">
|
|
||||||
|
|
||||||
<label for="from_time">from</label>
|
|
||||||
<input type="date" id="from_time" name="from_time"<?php if (isset($_REQUEST['from_time'])) echo " value=\"" . $_REQUEST['from_time'] . "\"" ?> />
|
|
||||||
|
|
||||||
<label for="until_time">until</label>
|
|
||||||
<input type="date" id="until_time" name="until_time"<?php if (isset($_REQUEST['until_time'])) echo " value=\"" . $_REQUEST['until_time'] . "\"" ?> />
|
|
||||||
|
|
||||||
<input type="text" name="id" placeholder="ID"<?php if (isset($_REQUEST['id'])) echo " value=\"" . $_REQUEST['id'] . "\"" ?> />
|
|
||||||
|
|
||||||
<input type="text" name="name" placeholder="name"<?php if (isset($_REQUEST['name'])) echo " value=\"" . $_REQUEST['name'] . "\"" ?> />
|
|
||||||
|
|
||||||
<?php if ($page == 'participants') { ?>
|
|
||||||
<input type="text" name="ip" placeholder="ip address"<?php if (isset($_REQUEST['ip'])) echo " value=\"" . $_REQUEST['ip'] . "\"" ?> maxlength="15" size="15" />
|
|
||||||
<?php } ?>
|
|
||||||
|
|
||||||
<br />
|
|
||||||
|
|
||||||
<div class="float-end pt-3">
|
|
||||||
|
|
||||||
<input type="button" onclick="clearFilter()" value="clear" />
|
|
||||||
|
|
||||||
<input type="submit" value="search" />
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</form>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
function clearFilter() {
|
|
||||||
document.getElementById("filter_form").reset();
|
|
||||||
const filterFields = document.querySelectorAll("#filter_form input");
|
|
||||||
filterFields.forEach(input => {
|
|
||||||
if (input.type === 'text' ||input.type === 'date') {
|
|
||||||
input.value = '';
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
</div>
|
|
Loading…
Reference in New Issue