mirror of
https://github.com/OpenXE-org/OpenXE.git
synced 2024-12-30 16:40:28 +01:00
589 lines
18 KiB
PHP
589 lines
18 KiB
PHP
<?php
|
|
|
|
namespace Xentral\Modules\Report;
|
|
|
|
use PHPUnit\Runner\Exception;
|
|
use Xentral\Components\Database\Database;
|
|
use Xentral\Modules\Report\Data\ReportColumn;
|
|
use Xentral\Modules\Report\Data\ReportColumnCollection;
|
|
use Xentral\Modules\Report\Data\ReportData;
|
|
use Xentral\Modules\Report\Data\ReportParameter;
|
|
use Xentral\Modules\Report\Data\ReportParameterCollection;
|
|
|
|
final class ReportGateway
|
|
{
|
|
/** @var Database $db */
|
|
private $db;
|
|
|
|
/**
|
|
* @param Database $database
|
|
*/
|
|
public function __construct(Database $database)
|
|
{
|
|
$this->db = $database;
|
|
}
|
|
|
|
/**
|
|
* @param string $category
|
|
* @param string $searchTerm
|
|
* @param int $userId
|
|
* @param bool $onlyOwn
|
|
* @param bool $onlyFavorites
|
|
*
|
|
* @return array
|
|
*/
|
|
public function getReportList($category = '', $searchTerm = '', $userId = 0, $onlyOwn = false, $onlyFavorites = false)
|
|
{
|
|
$result = [];
|
|
$select = $this->db->select();
|
|
$select->cols([
|
|
'r.id',
|
|
'r.name',
|
|
'r.description',
|
|
'r.project',
|
|
'r.category',
|
|
'IF(rs.file_public = 1 OR ru.file_enabled = 1 OR u.type = \'admin\', 1, 0) as allow_download',
|
|
'IF(rs.file_csv_enabled = 1 OR u.type = \'admin\', 1, 0) as allow_csv',
|
|
'IF(rs.file_pdf_enabled = 1 OR u.type = \'admin\', 1, 0) as allow_pdf',
|
|
'IF(rs.menu_public = 1 OR ru.menu_enabled = 1 OR u.type = \'admin\', 1, 0) as allow_menu',
|
|
'IF(rs.tab_public = 1 OR ru.tab_enabled = 1 OR u.type = \'admin\', 1, 0) as allow_tab',
|
|
'IF( (rs.chart_public = 1 OR ru.chart_enabled = 1 OR u.type = \'admin\') AND rs.chart_x_column <> \'\', 1, 0) as allow_chart',
|
|
'IF(rf.id IS NULL, 0, 1) as is_favorite',
|
|
'r.readonly'
|
|
]);
|
|
$select->from('report AS r');
|
|
try {
|
|
$select->leftJoin('report_share AS rs', 'r.id = rs.report_id')
|
|
->leftJoin('report_favorite AS rf', '(r.id = rf.report_id AND rf.user_id = :userId)')
|
|
->leftJoin('report_user AS ru', '(r.id = ru.report_id AND ru.user_id = :userId)')
|
|
->leftJoin('user AS u', 'u.id = :userId');
|
|
} catch (\Aura\SqlQuery\Exception $e) {
|
|
return [];
|
|
}
|
|
|
|
if ($userId > 0) {
|
|
$select->where(
|
|
'(
|
|
(
|
|
ru.id IS NOT NULL
|
|
OR rs.file_public = 1
|
|
OR rs.menu_public = 1
|
|
OR rs.chart_public = 1
|
|
OR rs.tab_public = 1
|
|
)
|
|
AND
|
|
(r.project = 0 OR r.project IN (SELECT ar.projekt
|
|
FROM adresse_rolle AS ar
|
|
LEFT JOIN user as u ON ar.adresse = u.adresse
|
|
WHERE u.id = :userId)
|
|
)
|
|
OR :userId IN (SELECT u.id as `c` FROM `user` AS u WHERE u.id = :userId AND u.type = \'admin\')
|
|
)
|
|
'
|
|
);
|
|
}
|
|
|
|
if ($category !== '') {
|
|
$select->Where('r.category LIKE :filterCategory');
|
|
}
|
|
if ($searchTerm !== '') {
|
|
$select->Where('(r.name LIKE :searchTerm OR r.description LIKE :searchTerm)');
|
|
}
|
|
if ($userId > 0 && $onlyFavorites === true) {
|
|
$select->Where('rf.user_id IS NOT NULL');
|
|
}
|
|
if ($onlyOwn === true) {
|
|
$select->Where('r.readonly = 0');
|
|
}
|
|
|
|
$select->orderBy(['rf.user_id DESC', 'r.readonly ASC', 'r.name']);
|
|
|
|
$sql = $select->getStatement();
|
|
$values = [
|
|
'filterCategory' => $category,
|
|
'searchTerm' => sprintf('%%%s%%', $searchTerm),
|
|
'userId' => $userId
|
|
];
|
|
$list = $this->db->fetchAll($sql, $values);
|
|
if (is_array($list) && count($list) > 0) {
|
|
$result = $list;
|
|
}
|
|
|
|
return $result;
|
|
}
|
|
|
|
/**
|
|
* @param int $id
|
|
*
|
|
* @return ReportData|null
|
|
*/
|
|
public function getReportById($id)
|
|
{
|
|
$report = $this->getOnlyReportById($id);
|
|
if ($report === null) {
|
|
return null;
|
|
}
|
|
$columns = $this->getColumnsByReportId($id);
|
|
$report->setColumns($columns);
|
|
$params = $this->getParametersByReportId($id);
|
|
$report->setParameters($params);
|
|
|
|
return $report;
|
|
}
|
|
|
|
/**
|
|
* @param string $name
|
|
*
|
|
* @return ReportData|null
|
|
*/
|
|
public function findReportByName($name)
|
|
{
|
|
$sql = 'SELECT r.id FROM `report` AS `r` WHERE r.name=:name ORDER BY r.id LIMIT 1';
|
|
$row = $this->db->fetchRow($sql, ['name' => $name]);
|
|
if (!is_array($row) || count($row) < 1) {
|
|
return null;
|
|
}
|
|
|
|
return $this->getReportById($row['id']);
|
|
}
|
|
|
|
/**
|
|
* @param int $id
|
|
*
|
|
* @return ReportData|null
|
|
*/
|
|
public function getOnlyReportById($id)
|
|
{
|
|
$sql = 'SELECT r.id, r.name, r.description, r.project, r.sql_query, r.remark, r.category, r.readonly,
|
|
r.csv_delimiter, r.csv_enclosure
|
|
FROM `report` AS `r`
|
|
WHERE r.id=:idvalue';
|
|
$values = ['idvalue' => $id];
|
|
$row = $this->db->fetchRow($sql, $values);
|
|
if ($row === null || count($row) === 0) {
|
|
return null;
|
|
}
|
|
|
|
return ReportData::fromFormData($row);
|
|
}
|
|
|
|
/**
|
|
* @param int $id
|
|
*
|
|
* @return ReportColumnCollection
|
|
*/
|
|
public function getColumnsByReportId($id)
|
|
{
|
|
$sql = 'SELECT c.id, c.key_name, c.title, c.width, c.alignment, c.sorting, c.sum, c.sequence, c.format_type,
|
|
c.format_statement
|
|
FROM `report_column` AS `c`
|
|
WHERE c.report_id=:idvalue
|
|
ORDER BY c.sequence';
|
|
$values = ['idvalue' => $id];
|
|
$rows = $this->db->fetchAll($sql, $values);
|
|
|
|
$objects = [];
|
|
foreach ($rows as $row) {
|
|
$objects[] = new ReportColumn(
|
|
$row['key_name'],
|
|
$row['title'],
|
|
$row['width'],
|
|
$row['alignment'],
|
|
$row['sum'],
|
|
$row['id'],
|
|
$row['sequence'],
|
|
$row['sorting'],
|
|
$row['format_type'],
|
|
$row['format_statement']
|
|
);
|
|
}
|
|
|
|
return new ReportColumnCollection($objects);
|
|
}
|
|
|
|
/**
|
|
* @param int $id
|
|
*
|
|
* @return ReportParameterCollection
|
|
*/
|
|
public function getParametersByReportId($id)
|
|
{
|
|
$sql = 'SELECT p.id, p.varname, p.displayname, p.default_value, p.options, p.description,
|
|
p.editable, p.control_type
|
|
FROM `report_parameter` AS `p`
|
|
WHERE p.report_id = :idvalue';
|
|
$values = ['idvalue' => $id];
|
|
$rows = $this->db->fetchAll($sql, $values);
|
|
|
|
return ReportParameterCollection::fromFormData($rows);
|
|
}
|
|
|
|
/**
|
|
* @param int $id
|
|
*
|
|
* @return bool
|
|
*/
|
|
public function reportExists($id)
|
|
{
|
|
if ((int)$id < 1) {
|
|
return false;
|
|
}
|
|
|
|
$sql = 'SELECT r.id FROM `report` AS `r` WHERE r.id = :idvalue';
|
|
$values = ['idvalue' => (int)$id];
|
|
$idResult = $this->db->fetchRow($sql, $values);
|
|
|
|
return (isset($idResult['id']) && $idResult['id'] === $id);
|
|
}
|
|
|
|
/**
|
|
* @param $id
|
|
*
|
|
* @return bool
|
|
*/
|
|
public function isReportReadonly($id)
|
|
{
|
|
if ((int)$id < 1) {
|
|
return false;
|
|
}
|
|
|
|
$sql = 'SELECT r.readonly FROM `report` AS `r` WHERE r.id = :idvalue';
|
|
$values = ['idvalue' => (int)$id];
|
|
$result = $this->db->fetchRow($sql, $values);
|
|
|
|
return (isset($result['readonly']) && $result['readonly'] === 1);
|
|
}
|
|
|
|
/**
|
|
* @param int $id
|
|
*
|
|
* @return bool
|
|
*/
|
|
public function columnExists($id)
|
|
{
|
|
if ((int)$id < 1) {
|
|
return false;
|
|
}
|
|
$sql = 'SELECT c.id FROM `report_column` AS `c` WHERE c.id = :idvalue';
|
|
$values = ['idvalue' => (int)$id];
|
|
$idResult = $this->db->fetchRow($sql, $values);
|
|
|
|
return (isset($idResult['id']) && $idResult['id'] === $id);
|
|
}
|
|
|
|
/**
|
|
* @param int $columnId
|
|
*
|
|
* @return int
|
|
*/
|
|
public function getReportIdByColumn($columnId)
|
|
{
|
|
$sql = 'SELECT r.id
|
|
FROM `report` AS `r`
|
|
JOIN `report_column` AS `rc` ON r.id = rc.report_id
|
|
WHERE rc.id = :idValue';
|
|
$values = ['idValue' => $columnId];
|
|
|
|
return (int)$this->db->fetchValue($sql, $values);
|
|
}
|
|
|
|
/**
|
|
* @param int $id
|
|
*
|
|
* @return bool
|
|
*/
|
|
public function parameterExists($id)
|
|
{
|
|
if ((int)$id < 1) {
|
|
return false;
|
|
}
|
|
|
|
$sql = 'SELECT p.id FROM `report_parameter` AS `p` WHERE p.id = :idvalue';
|
|
$values = ['idvalue' => (int)$id];
|
|
$idResult = $this->db->fetchRow($sql, $values);
|
|
|
|
return (isset($idResult['id']) && $idResult['id'] === $id);
|
|
}
|
|
|
|
/**
|
|
* @param int $parameterId
|
|
*
|
|
* @return int
|
|
*/
|
|
public function getReportIdByParameter($parameterId)
|
|
{
|
|
$sql = 'SELECT r.id
|
|
FROM `report` AS `r`
|
|
JOIN `report_parameter` AS `rp` ON r.id = rp.report_id
|
|
WHERE rp.id = :idValue';
|
|
$values = ['idValue' => $parameterId];
|
|
|
|
return (int)$this->db->fetchValue($sql, $values);
|
|
}
|
|
|
|
/**
|
|
* @param int $id
|
|
*
|
|
* @return ReportParameter
|
|
*/
|
|
public function getParameterById($id)
|
|
{
|
|
$sql = 'SELECT p.id, p.varname, p.displayname, p.default_value, p.options, p.editable, p.description,
|
|
p.control_type
|
|
FROM `report_parameter` AS `p`
|
|
WHERE id = :idValue';
|
|
$values = ['idValue' => $id];
|
|
$data = $this->db->fetchRow($sql, $values);
|
|
|
|
return ReportParameter::fromDbState($data);
|
|
}
|
|
|
|
/**
|
|
* @param int $id
|
|
*
|
|
* @return ReportColumn
|
|
*/
|
|
public function getColumnById($id)
|
|
{
|
|
$sql = 'SELECT c.id, c.key_name, c.title, c.width, c.alignment, c.sorting, c.sum, c.sequence, c.format_type,
|
|
c.format_statement
|
|
FROM `report_column` AS `c`
|
|
WHERE c.id = :idValue';
|
|
$values = ['idValue' => $id];
|
|
$data = $this->db->fetchRow($sql, $values);
|
|
|
|
return ReportColumn::fromDbState($data);
|
|
}
|
|
|
|
/**
|
|
* @param int $id
|
|
*
|
|
* @return array
|
|
*/
|
|
public function findTransferArrayByReportId($id)
|
|
{
|
|
$sql = 'SELECT id, report_id, ftp_active, ftp_passive, ftp_type, ftp_host, ftp_port, ftp_user, ftp_password,
|
|
ftp_interval_mode, ftp_interval_value, ftp_daytime, ftp_format, ftp_filename, ftp_last_transfer,
|
|
email_active, email_recipient, email_subject, email_interval_mode, email_interval_value,
|
|
email_daytime, email_format, email_filename, email_last_transfer, url_format, url_begin,
|
|
url_end, url_address, api_active, api_account_id, api_format
|
|
FROM `report_transfer` AS `t`
|
|
WHERE report_id=:idValue';
|
|
$array = $this->db->fetchRow($sql, ['idValue' => $id]);
|
|
if ($array === null || empty($array)) {
|
|
return [];
|
|
}
|
|
|
|
return $array;
|
|
}
|
|
|
|
/**
|
|
* @param int $userId
|
|
* @param string $module
|
|
* @param string $action
|
|
*
|
|
* @return array
|
|
*/
|
|
public function findShareByModuleAction($userId, $module, $action)
|
|
{
|
|
$sql = "SELECT s.id, s.report_id, s.chart_public, s.chart_axislabel, s.chart_dateformat, s.chart_interval_value,
|
|
s.chart_interval_mode, s.file_public, s.file_pdf_enabled, s.file_csv_enabled,
|
|
s.file_xls_enabled, s.menu_public, s.menu_doctype, s.menu_label, s.menu_format, s.tab_public,
|
|
s.tab_module, s.tab_action, IF(s.tab_label <> '', s.tab_label, r.name) as `tab_label`,
|
|
s.tab_position, s.chart_type, s.chart_x_column, s.data_columns, s.chart_group_column
|
|
FROM `report_share` AS `s`
|
|
JOIN `report` AS `r` on s.report_id = r.id
|
|
LEFT JOIN `report_user` AS `ru` ON r.id = ru.report_id AND ru.user_id = :userid
|
|
WHERE (s.tab_public = 1 OR NOT ISNULL(ru.id)) AND s.tab_module = :module
|
|
AND (s.tab_action = '' OR s.tab_action = :action)";
|
|
$array = $this->db->fetchAll(
|
|
$sql,
|
|
[
|
|
'userid' => (int)$userId,
|
|
'module' => (string)$module,
|
|
'action' => (string)$action
|
|
]
|
|
);
|
|
if ($array === null || empty($array)) {
|
|
return [];
|
|
}
|
|
|
|
return $array;
|
|
}
|
|
|
|
/**
|
|
* @param int $id
|
|
*
|
|
* @return array
|
|
*/
|
|
public function findShareArrayByReportId($id)
|
|
{
|
|
$sql = 'SELECT s.id,s.report_id, s.chart_public, s.chart_axislabel, s.chart_dateformat, s.chart_interval_value,
|
|
s.chart_interval_mode, s.file_public, s.file_pdf_enabled, s.file_csv_enabled,
|
|
s.file_xls_enabled, s.menu_public, s.menu_doctype, s.menu_label, s.menu_format, s.tab_public,
|
|
s.tab_module, s.tab_action, s.tab_label, s.tab_position, s.chart_type,
|
|
s.chart_x_column, s.data_columns, s.chart_group_column
|
|
FROM `report_share` AS `s`
|
|
WHERE s.report_id=:idValue';
|
|
$array = $this->db->fetchRow($sql, ['idValue' => $id]);
|
|
if ($array === null || empty($array)) {
|
|
return [];
|
|
}
|
|
|
|
return $array;
|
|
}
|
|
|
|
/**
|
|
* @param int $id
|
|
*
|
|
* @return array
|
|
*/
|
|
public function findSharedUserById($id)
|
|
{
|
|
$sql = 'SELECT ru.id, ru.report_id, ru.user_id, ru.name, ru.chart_enabled, ru.file_enabled,
|
|
ru.menu_enabled, ru.tab_enabled
|
|
FROM `report_user` AS `ru`
|
|
WHERE ru.id=:idValue';
|
|
$array = $this->db->fetchRow($sql, ['idValue' => $id]);
|
|
if ($array === null || empty($array)) {
|
|
return [];
|
|
}
|
|
|
|
return $array;
|
|
}
|
|
|
|
/**
|
|
* @param int $userId
|
|
* @param int $reportId
|
|
*
|
|
* @return bool
|
|
*/
|
|
public function isSharedUserOfReport($userId, $reportId)
|
|
{
|
|
$sql = 'SELECT ru.id FROM `report_user` AS `ru` WHERE ru.user_id = :userId AND ru.report_id = :reportId';
|
|
$values = ['userId' => $userId, 'reportId' => $reportId];
|
|
$id = $this->db->fetchValue($sql, $values);
|
|
|
|
return !empty($id);
|
|
}
|
|
|
|
/**
|
|
* @param string $doctype
|
|
* @param int $userId
|
|
*
|
|
* @return array
|
|
*/
|
|
public function getDocumentAddActionMenuData($doctype, $userId = 0)
|
|
{
|
|
$sql = 'SELECT r.id, r.name, s.menu_doctype, s.menu_format, s.menu_label
|
|
FROM `report` as `r`
|
|
JOIN `report_share` as `s` ON r.id = s.report_id
|
|
LEFT JOIN `report_user` as `u` ON r.id = u.report_id
|
|
WHERE (s.menu_doctype = :docType AND (s.menu_public = 1 OR (u.user_id = :userId AND u.menu_enabled = 1))
|
|
AND
|
|
(r.project = 0 OR r.project IN (SELECT ar.projekt
|
|
FROM `adresse_rolle` AS `ar`
|
|
LEFT JOIN `user` as `u` ON ar.adresse = u.adresse
|
|
WHERE u.id = :userId)
|
|
OR :userId IN (SELECT u.id as `c` FROM `user` AS `u`
|
|
WHERE u.id = :userId AND u.type = \'admin\'))
|
|
|
|
|
|
)';
|
|
$data = $this->db->fetchAll($sql, ['docType' => strtolower($doctype), 'userId' => $userId]);
|
|
if (empty($data)) {
|
|
return [];
|
|
}
|
|
|
|
return $data;
|
|
}
|
|
|
|
/**
|
|
* @param int $reportId
|
|
* @param int $userId
|
|
*
|
|
* @return bool
|
|
*/
|
|
public function isFavoriteReportOfUser($reportId, $userId)
|
|
{
|
|
if ($reportId < 1 || $userId < 0){
|
|
return false;
|
|
}
|
|
$sql = 'SELECT rf.id
|
|
FROM `report_favorite` AS `rf`
|
|
WHERE rf.report_id = :reportID AND rf.user_id = :userId
|
|
LIMIT 1';
|
|
$id = $this->db->fetchValue($sql, ['reportID' => $reportId, 'userId' => $userId]);
|
|
|
|
return !empty($id);
|
|
}
|
|
|
|
/**
|
|
* @param $reportId
|
|
* @param $userId
|
|
*
|
|
* @return bool
|
|
*/
|
|
public function userCanDownloadCsv($reportId, $userId)
|
|
{
|
|
return $this->userCanDownload($reportId, $userId, 'csv');
|
|
}
|
|
|
|
/**
|
|
* @param $reportId
|
|
* @param $userId
|
|
*
|
|
* @return bool
|
|
*/
|
|
public function userCanDownloadPdf($reportId, $userId)
|
|
{
|
|
return $this->userCanDownload($reportId, $userId, 'pdf');
|
|
}
|
|
|
|
/**
|
|
* @todo: implement when xls exporter is ready
|
|
*
|
|
* @param $reportId
|
|
* @param $userId
|
|
*
|
|
* @return bool
|
|
*/
|
|
public function userCanDownloadXls($reportId, $userId)
|
|
{
|
|
//return $this->userCanDownload($reportId, $userId, 'xls');
|
|
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* @param $reportId
|
|
* @param $userId
|
|
*
|
|
* @param $filetype 'csv', 'pdf' or 'xls'
|
|
*
|
|
* @return bool
|
|
*/
|
|
private function userCanDownload($reportId, $userId, $filetype)
|
|
{
|
|
try {
|
|
$sql = sprintf(
|
|
'SELECT r.id
|
|
FROM `report` AS `r`
|
|
LEFT JOIN `report_share` AS `s` ON r.id = s.report_id
|
|
LEFT JOIN `report_user` AS `u` ON r.id = u.report_id
|
|
WHERE r.id = :reportId AND (
|
|
:userId IN (SELECT `u`.`id` AS `c` FROM `user` AS `u` WHERE `u`.`id` = :userId AND `u`.`type` = \'admin\')
|
|
OR
|
|
(s.file_%s_enabled = 1 AND (s.file_public = 1 OR (u.user_id = :userId AND u.file_enabled = 1)))
|
|
)',
|
|
$filetype
|
|
);
|
|
$data = $this->db->fetchAll($sql, ['reportId' => $reportId, 'userId' => $userId]);
|
|
|
|
return !empty($data);
|
|
} catch (Exception $e) {
|
|
return false;
|
|
}
|
|
}
|
|
}
|