db = $db; $this->gateway = $gateway; $this->resolver = $resolver; } /** * @param $sqlStatement * * @return bool */ public function isSqlStatementAllowed($sqlStatement) { $filterKeyWords = [ 'INTO', 'INSERT', 'UPDATE', 'DELETE', 'ALTER', 'SHOW', 'USE', 'TRUNCATE', 'LOAD', 'CREATE', 'DROP', 'RENAME', ]; foreach ($filterKeyWords as $keyWord) { $allOccurances = []; $escapedOccurances = []; $allPattern = sprintf('/%s/i', $keyWord); $escapedPattern = sprintf('/\W[`\'][^`\']*%s[^`\']*[`\']\W?/i', $keyWord); if (preg_match_all($allPattern, $sqlStatement, $allOccurances)) { preg_match_all($escapedPattern, $sqlStatement, $escapedOccurances); if (count($allOccurances[0]) !== count($escapedOccurances[0])) { return false; } } } return true; } /** * @param ReportData $report * * @return int */ public function saveReport(ReportData $report) { $id = $report->getId(); if ($id !== null && $id > 0 && $this->gateway->reportExists($id)) { $newId = $this->updateReport($report); } else { $newId = $this->insertReport($report); } return $newId; } /** * @param int $id * * @throws InvalidArgumentException * @throws DatabaseTransactionException * * @return int */ public function copyReport($id = 0) { $report = $this->gateway->getReportById($id); if ($report === null) { throw new InvalidArgumentException(sprintf('Report with id %s not found.', $id)); } $newParameters = null; $parameters = $report->getParameters(); if ($parameters !== null) { $newParameters = []; foreach ($parameters as $param) { $data = $param->toArray(); $data['id'] = 0; $newParameters[] = ReportParameter::fromDbState($data); } } $newColumns = null; $columns = $report->getColumns(); if ($columns !== null) { $newColumns = []; foreach ($columns as $column) { $data = $column->toArray(); $data['id'] = 0; $temp = ReportColumn::fromDbState($data); $newColumns[] = $temp; } } $newName = $this->generateIncrementedReportName($report->getName()); $newReport = new ReportData( $newName, $report->getDescription(), $report->getProjectId(), $report->getSqlQuery(), new ReportColumnCollection($newColumns), new ReportParameterCollection($newParameters), 0, $report->getRemark(), $report->getCategory(), false ); return $this->insertReport($newReport); } /** * @param ReportColumnCollection $columns * @param int $reportId */ public function saveColumnCollection(ReportColumnCollection $columns, $reportId) { foreach ($columns as $column) { $this->saveColumn($column, $reportId); } } /** * @param ReportColumn $column * @param $reportId * * @return int */ public function saveColumn(ReportColumn $column, $reportId) { $id = $column->getId(); if ($id !== null && $id > 0 && $this->gateway->columnExists($id)) { $newId = $this->updateColumn($column, $reportId); } else { $newId = $this->insertColumn($column, $reportId); } return $newId; } /** * @param ReportParameterCollection $parameters * @param int $reportId */ public function saveParameterCollection(ReportParameterCollection $parameters, $reportId) { foreach ($parameters as $param) { $this->saveParameter($param, $reportId); } } /** * @param ReportParameter $parameter * @param int $reportId * * @return int */ public function saveParameter(ReportParameter $parameter, $reportId) { $id = $parameter->getId(); if ($id !== null && $id > 0 && $this->gateway->parameterExists($id)) { $newId = $this->updateParameter($parameter, $reportId); } else { $newId = $this->insertParameter($parameter, $reportId); } return $newId; } /** * @param array $transferArray * * @return int */ public function saveTransferArray($transferArray) { $id = (int)$transferArray['id']; $reportId = (int)$transferArray['report_id']; if (!$this->gateway->reportExists($reportId)) { return 0; } if ($id !== null && $id > 0) { $newId = $this->updateTransferArray($transferArray); } else { $newId = $this->insertTransferArray($transferArray); } return $newId; } /** * @param array $shareArray * * @return int */ public function saveShareArray($shareArray) { $id = (int)$shareArray['id']; $reportId = (int)$shareArray['report_id']; if (!$this->gateway->reportExists($reportId)) { return 0; } if ($id !== null && $id > 0) { $newId = $this->updateShareArray($shareArray); } else { $newId = $this->insertShareArray($shareArray); } return $newId; } /** * @param array $reportUserArray * * @return int */ public function saveReportUserArray($reportUserArray) { $id = (int)$reportUserArray['id']; $reportId = (int)$reportUserArray['report_id']; if (!$this->gateway->reportExists($reportId)) { return 0; } if ($id !== null && $id > 0) { $newId = $this->updateReportUserArray($reportUserArray); } else { $newId = $this->insertReportUserArray($reportUserArray); } return $newId; } /** * @param int $id * * @throws InvalidArgumentException * * @return void */ public function deleteColumnById($id) { if ($id < 1) { throw new InvalidArgumentException('Cannot delete Column without valid ID.'); } $sql = 'DELETE FROM `report_column` WHERE id=:idvalue'; $values = ['idvalue' => $id]; $this->db->perform($sql, $values); } /** * @param $reportId * * @return int amount of deleted columns */ public function deleteAllColumnsByReportId($reportId) { $sql = 'DELETE FROM `report_column` WHERE report_id = :reportId'; return $this->db->fetchAffected($sql, ['reportId' => $reportId]); } /** * @param int $id * * @throws DatabaseTransactionException * * @return void */ public function deleteReportById($id) { if ($id < 1) { throw new InvalidArgumentException('Cannot delete Report without valid ID.'); } $sqlDeleteReport = 'DELETE FROM `report` WHERE id=:idValue'; $sqlDeleteParam = 'DELETE FROM `report_parameter` WHERE report_id=:idValue'; $sqlDeleteColumn = 'DELETE FROM `report_column` WHERE report_id=:idValue'; $sqlDeleteShare = 'DELETE FROM `report_share` WHERE report_id=:idValue'; $sqlDeleteTransfer = 'DELETE FROM `report_transfer` WHERE report_id=:idValue'; $sqlDeleteSharedUser = 'DELETE FROM `report_user` WHERE report_id=:idValue'; $sqlDeleteFavorites = 'DELETE FROM `report_favorite` WHERE report_id=:idValue'; $values = ['idValue' => $id]; $this->db->beginTransaction(); try { $this->db->perform($sqlDeleteParam, $values); $this->db->perform($sqlDeleteColumn, $values); $this->db->perform($sqlDeleteReport, $values); $this->db->perform($sqlDeleteShare, $values); $this->db->perform($sqlDeleteTransfer, $values); $this->db->perform($sqlDeleteSharedUser, $values); $this->db->perform($sqlDeleteFavorites, $values); } catch (Exception $e) { $this->db->rollBack(); throw new DatabaseTransactionException('Failed to delete report', $e->getCode(), $e); } $this->db->commit(); } /** * @param int $id * * @return bool true = success */ public function tryDeleteUserShare($id) { if ($id < 1) { return false; } $sql = 'DELETE FROM `report_user` WHERE id = :idValue'; $countAffected = $this->db->fetchAffected($sql, ['idValue' => $id]); return $countAffected > 0; } /** * @param int $reportId * @param DateTime $dateTime * * @return bool true = success */ public function setLastTransferFtp($reportId, DateTime $dateTime) { $sql = 'UPDATE `report_transfer` SET ftp_last_transfer = :dateValue WHERE report_id = :idValue'; $values = ['dateValue' => $dateTime->format('Y-m-d H:i:s'), 'idValue' => (int)$reportId]; $affectedRows = $this->db->fetchAffected($sql, $values); return !($affectedRows < 1); } /** * @param int $reportId * @param DateTime $dateTime * * @return bool true = success */ public function setLastTransferEmail($reportId, DateTime $dateTime) { $sql = 'UPDATE `report_transfer` SET email_last_transfer = :dateValue WHERE report_id = :idValue'; $values = ['dateValue' => $dateTime->format('Y-m-d H:i:s'), 'idValue' => (int)$reportId]; $affectedRows = $this->db->fetchAffected($sql, $values); return !($affectedRows < 1); } /** * @param $id */ public function deleteParamById($id) { if ($id < 1) { throw new InvalidArgumentException('Cannot delete Parameter without valid ID.'); } $sql = 'DELETE FROM report_parameter WHERE id=:idvalue'; $values = ['idvalue' => $id]; $this->db->perform($sql, $values); } /** * @param ReportData $report * * @param array $parameterValues * * @return string sql statement with inserted variable values */ public function resolveParameters(ReportData $report, $parameterValues = []) { return $this->resolver->resolveParameters($report, $parameterValues); } /** * @param string $statement * @param array $parameters * * @return array */ public function testSqlStatement($statement, $parameters = []) { //1. error: statement empty if ($statement === '') { $testResult['messagetype'] = 'info'; $testResult['message'] = 'Cannot execute empty statement'; return $testResult; } //2. error: invalid parameter names $testReport = new ReportData('', '', '', $statement); $params = []; foreach ($parameters as $name => $value) { try { $params[] = new ReportParameter($name, $value); } catch (ParameterNameException $e) { $testResult['messagetype'] = 'error'; $testResult['message'] = sprintf( 'Invalid Parameter name "%s". Parameter names can only contain letters, numbers and "_". Parameter names must start with a letter.', $name ); return $testResult; } } $testReport->setParameters(new ReportParameterCollection($params)); //3. error: wrong variable names in query $errorVarnames = $this->resolver->findInvalidVariableNames($statement); if (count($errorVarnames) > 0) { $testResult['messagetype'] = 'error'; $testResult['message'] = sprintf( 'Invalid Variable Names: %s. Variable names can only contain letters A-Z, numbers and "_".', implode(', ', $errorVarnames) ); return $testResult; } //4. error: unresolved Variables try { $compiled = $this->resolveParameters($testReport); } catch (UnresolvedParameterException $e) { $testResult['messagetype'] = 'error'; $testResult['message'] = $e->getMessage(); return $testResult; } //5. error: Syntax error if (!$this->isSqlStatementAllowed($compiled)) { $testResult['messagetype'] = 'error'; $testResult['message'] = 'Reports can only use SELECT statements!'; return $testResult; } //6. error: Query Semantic error if(!preg_match('/LIMIT\s*\d/', $compiled)){ $compiled .= " LIMIT 101"; } try { $rows = $this->db->fetchAll($compiled); $columnNames = []; if (is_array($rows) && count($rows) > 0) { $columnNames = array_keys($rows[0]); } } catch (Exception $e) { $testResult['messagetype'] = 'error'; $testResult['message'] = sprintf("QUERY FAILED:\n%s", $e->getMessage()); return $testResult; } //everything fine $message = "Query successful: More than 100 datasets found"; if(count($rows) < 101){ $message = sprintf('Query successful: %s datasets found', count($rows)); } $testResult = [ 'messagetype' => 'success', 'message' => $message, 'columnnames' => $columnNames, ]; return $testResult; } /** * Finds possible copied reports of the name and * generates a report name with increment if needed. * * @example generateIncrementedReportName('Existing Report') -> 'Existing Report (1)' * @example generateIncrementedReportName('Existing Report (1)') -> 'Existing Report (2)' * @example generateIncrementedReportName('New Report') -> 'New Report' * * @param string $reportName * * @param int $ignoreId * * @return string */ public function generateIncrementedReportName($reportName, $ignoreId = 0) { $newName = $this->getBaseName($reportName); $copies = $this->findReportCopyNames($newName, $ignoreId); if (count($copies) > 0) { $maxIncrement = 0; foreach ($copies as $name) { preg_match('/^.+\s*\((\d+)\)$/', $name, $matches); if (isset($matches[1]) && (int)$matches[1] > $maxIncrement) { $maxIncrement = (int)$matches[1]; } } $newName = sprintf('%s (%s)', $newName, $maxIncrement + 1); } return $newName; } /* * */ public function autoCreateColumns(ReportData $report) { try { $compiledStatement = $this->resolveParameters($report); $sampleRow = $this->db->fetchRow($compiledStatement); } catch (Exception $e) { throw new ReportSqlQueryException('Query delivered no result.'); } $resultKeys = array_keys($sampleRow); $existingKeys = []; $columns = $report->getColumns(); $columnsArray = []; $totalWidth = 0; $maxSequence = 0; if ($columns !== null) { foreach ($columns as $column) { $columnsArray[] = $column; $totalWidth += (int)$column->getWidth(); $existingKeys[] = $column->getKey(); if ($column->getSequence() > $maxSequence) { $maxSequence = $column->getSequence(); } } } $addKeys = []; foreach ($resultKeys as $key) { if (!in_array($key, $existingKeys, true)) { $addKeys[] = $key; } } if (count($addKeys) === 0) { return $report; } $width = floor((190 - $totalWidth) / count($addKeys)); $sequence = $maxSequence + 1; foreach ($addKeys as $addKey) { $newCol = new ReportColumn( $addKey, StringUtil::toTitleCase($addKey), $width, ReportColumn::ALIGN_LEFT, false, 0, $sequence ); $columnsArray[] = $newCol; $sequence++; } $columnCollection = new ReportColumnCollection($columnsArray); $report->setColumns($columnCollection); return $report; } /** * @param int $reportId * @param int $userId * * @return bool success */ public function addReportFavorite($reportId, $userId) { if ($reportId < 1 || $userId < 1) { return false; } if ($this->gateway->isFavoriteReportOfUser($reportId, $userId)) { return true; } $sql = 'INSERT INTO `report_favorite` (report_id, user_id) VALUES (:reportId, :userId)'; $affected = $this->db->fetchAffected($sql, ['reportId' => $reportId, 'userId' => $userId]); return $affected > 0; } /** * @param int $reportId * @param int $userId * * @return bool success */ public function removeReportFavorite($reportId, $userId) { if ($reportId < 1 || $userId < 1) { return false; } if (!$this->gateway->isFavoriteReportOfUser($reportId, $userId)) { return true; } $sql = 'DELETE FROM `report_favorite` WHERE report_id = :reportId AND user_id = :userId'; $affected = $this->db->fetchAffected($sql, ['reportId' => $reportId, 'userId' => $userId]); return $affected > 0; } /** * @param string $format * * @throws ColumnFormatException * * @return void */ public function validateCustomColumnFormat(string $format): void { if (!$this->isSqlStatementAllowed($format)) { throw new ColumnFormatException('invalid column format statement'); } if (preg_match('/{VALUE}/i', $format) !== 1) { throw new ColumnFormatException('Format statement must contain "{VALUE}" variable.'); } } /** * @param ReportData $report * * @throws DatabaseTransactionException * * @return int */ private function insertReport(ReportData $report) { $sql = 'INSERT INTO report (name, description, project, sql_query, remark, category, readonly, csv_delimiter, csv_enclosure) VALUES (:name, :description, :project, :sql_query, :remark, :category, :readonly, :csv_delimiter, :csv_enclosure)'; $values = [ 'name' => $report->getName(), 'description' => $report->getDescription(), 'project' => $report->getProjectId(), 'sql_query' => $report->getSqlQuery(), 'remark' => $report->getRemark(), 'category' => $report->getCategory(), 'readonly' => 0, 'csv_delimiter' => $report->getCsvDelimiter(), 'csv_enclosure' => $report->getCsvEnclosure(), ]; if ($report->isReadonly()) { $values['readonly'] = 1; } $this->db->beginTransaction(); try { $this->db->perform($sql, $values); $insertId = $this->db->lastInsertId(); $columns = $report->getColumns(); if ($columns !== null && $columns !== []) { $this->saveColumnCollection($columns, $insertId); } $params = $report->getParameters(); if ($params !== null && $params !== []) { $this->saveParameterCollection($params, $insertId); } } catch (Exception $e) { $this->db->rollBack(); throw new DatabaseTransactionException($e->getMessage(), $e->getCode(), $e); } $this->db->commit(); return $insertId; } /** * @param ReportData $report * * @return int */ private function updateReport(ReportData $report) { $id = $report->getId(); $sql = 'UPDATE report SET name=:name, description=:description, project=:project, sql_query=:sql_query, remark=:remark, category=:category, csv_delimiter=:csv_delimiter, csv_enclosure=:csv_enclosure, readonly=:readonly WHERE id=:idvalue'; $values = [ 'name' => $report->getName(), 'description' => $report->getDescription(), 'project' => $report->getProjectId(), 'sql_query' => $report->getSqlQuery(), 'idvalue' => $id, 'remark' => $report->getRemark(), 'category' => $report->getCategory(), 'csv_delimiter' => $report->getCsvDelimiter(), 'csv_enclosure' => $report->getCsvEnclosure(), 'readonly' => (int)$report->isReadonly(), ]; $this->db->beginTransaction(); try { $this->db->perform($sql, $values); $columns = $report->getColumns(); if ($columns !== null && $columns !== []) { $this->saveColumnCollection($columns, $id); } $params = $report->getParameters(); if ($params !== null && $params !== []) { $this->saveParameterCollection($params, $id); } } catch (Exception $e) { $this->db->rollBack(); throw new DatabaseTransactionException($e->getMessage(), $e->getCode(), $e); } $this->db->commit(); return $id; } /** * @param ReportColumn $column * @param int $reportId * * @return int */ private function insertColumn(ReportColumn $column, $reportId) { $sql = 'INSERT INTO report_column (report_id, key_name, title, width, alignment, sorting, sum, sequence, format_type, format_statement) VALUES (:reportId, :keyName, :title, :width, :alignment, :sorting, :sum, :sequence, :format_type, :format_statement)'; $sum = 0; if ($column->isSumColumn()) { $sum = 1; } $values = [ 'reportId' => $reportId, 'keyName' => $column->getKey(), 'title' => $column->getTitle(), 'width' => $column->getWidth(), 'alignment' => $column->getAlignment(), 'sorting' => $column->getSorting(), 'sum' => $sum, 'sequence' => $column->getSequence(), 'format_type' => $column->getFormatType(), 'format_statement' => $column->getFormatStatement(), ]; $this->db->perform($sql, $values); return $this->db->lastInsertId(); } /** * @param ReportColumn $column * @param int $reportId * * @return int */ private function updateColumn(ReportColumn $column, $reportId) { $id = $column->getId(); $sql = 'UPDATE report_column SET report_id = :reportId, key_name = :keyName, title = :title, width = :width, alignment = :alignment, sorting = :sorting, sum = :sum, sequence = :sequence, format_type = :format_type, format_statement = :format_statement WHERE id = :idvalue'; $sum = 0; if ($column->isSumColumn()) { $sum = 1; } $values = [ 'reportId' => $reportId, 'keyName' => $column->getKey(), 'title' => $column->getTitle(), 'width' => $column->getWidth(), 'alignment' => $column->getAlignment(), 'sorting' => $column->getSorting(), 'sum' => $sum, 'sequence' => $column->getSequence(), 'format_type' => $column->getFormatType(), 'format_statement' => $column->getFormatStatement(), 'idvalue' => $id, ]; $this->db->perform($sql, $values); return $id; } /** * @param ReportParameter $parameter * @param int $reportId * * @return int */ private function insertParameter(ReportParameter $parameter, $reportId) { $sql = 'INSERT INTO report_parameter (report_id, varname, displayname, default_value, options, description, editable, control_type) VALUES (:reportId, :varName, :displayName, :defaultValue, :options, :description, :editable, :controlType)'; $editable = 0; if ($parameter->isEditable()) { $editable = 1; } $values = [ 'reportId' => $reportId, 'varName' => $parameter->getVarname(), 'displayName' => $parameter->getDisplayname(), 'defaultValue' => $parameter->getDefaultValue(), 'options' => $parameter->getOptionsAsString(), 'description' => $parameter->getDescription(), 'editable' => $editable, 'controlType' => $parameter->getControlType(), ]; $this->db->perform($sql, $values); return $this->db->lastInsertId(); } /** * @param ReportParameter $parameter * @param int $reportId * * @return int */ private function updateParameter(ReportParameter $parameter, $reportId) { $id = $parameter->getId(); $sql = 'UPDATE report_parameter SET report_id=:reportId, varname=:varName, displayname=:displayName, default_value=:defaultValue, options=:options, description=:description, editable=:editable, control_type=:controlType WHERE id=:idvalue'; $editable = 0; if ($parameter->isEditable()) { $editable = 1; } $values = [ 'reportId' => $reportId, 'varName' => $parameter->getVarname(), 'displayName' => $parameter->getDisplayname(), 'defaultValue' => $parameter->getDefaultValue(), 'options' => $parameter->getOptionsAsString(), 'description' => $parameter->getDescription(), 'editable' => $editable, 'idvalue' => $id, 'controlType' => $parameter->getControlType(), ]; $this->db->perform($sql, $values); return $id; } /** * @param $transferArray * * @return array */ private function sanitizeTransferDateTimes($transferArray) { $dateTimeKeys = [ 'ftp_daytime', 'ftp_last_transfer', 'email_daytime', 'email_last_transfer', 'url_begin', 'url_end', ]; foreach ($dateTimeKeys as $key) { if (isset($transferArray[$key]) && empty($transferArray[$key])) { $transferArray[$key] = null; } } if (isset($transferArray['email_daytime']) && $transferArray['email_daytime'] !== null) { $transferArray['email_daytime'] = sprintf('%s:00', $transferArray['email_daytime']); } if (isset($transferArray['ftp_daytime']) && $transferArray['ftp_daytime'] !== null) { $transferArray['ftp_daytime'] = sprintf('%s:00', $transferArray['ftp_daytime']); } return $transferArray; } /** * @param array $transferArray * * @return int */ private function insertTransferArray($transferArray) { $sql = "INSERT INTO `report_transfer` (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, email_active, email_recipient, email_subject, email_interval_mode, email_interval_value, email_daytime, email_format, email_filename, url_format, url_begin, url_end, url_address, api_active, api_account_id, api_format, url_token) VALUES (: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, :email_active, :email_recipient, :email_subject, :email_interval_mode, :email_interval_value, :email_daytime, :email_format, :email_filename, :url_format, :url_begin, :url_end, :url_address, :api_active, :api_account_id, :api_format, '')"; $values = $this->sanitizeTransferDateTimes($transferArray); $this->db->fetchAffected($sql, $values); return $this->db->lastInsertId(); } /** * @param array $transferArray * * @return int */ private function updateTransferArray($transferArray) { $sql = 'UPDATE `report_transfer` SET report_id = :report_id, ftp_active = :ftp_active, ftp_passive = :ftp_passive, ftp_type = :ftp_type, ftp_host = :ftp_host, ftp_port = :ftp_port, ftp_user = :ftp_user, ftp_password = :ftp_password, ftp_interval_mode = :ftp_interval_mode, ftp_interval_value = :ftp_interval_value, ftp_daytime = :ftp_daytime, ftp_format = :ftp_format, ftp_filename = :ftp_filename, email_active = :email_active, email_recipient = :email_recipient, email_subject = :email_subject, email_interval_mode = :email_interval_mode, email_interval_value = :email_interval_value, email_daytime = :email_daytime, email_format = :email_format, email_filename = :email_filename, url_format = :url_format, url_begin = :url_begin, url_end = :url_end, url_address = :url_address, api_active = :api_active, api_account_id = :api_account_id, api_format = :api_format WHERE id=:id'; $values = $this->sanitizeTransferDateTimes($transferArray); $affectedRows = $this->db->fetchAffected($sql, $values); if ($affectedRows > 0) { return (int)$values['id']; } return 0; } /** * @param array $reportUserArray * * @return int */ private function insertReportUserArray($reportUserArray) { $sql = 'INSERT INTO `report_user` (report_id, user_id, name, chart_enabled, file_enabled, menu_enabled, tab_enabled) VALUES (:report_id, :user_id, :name, :chart_enabled, :file_enabled, :menu_enabled, :tab_enabled)'; $this->db->fetchAffected($sql, $reportUserArray); return $this->db->lastInsertId(); } /** * @param array $reportUserArray * * @return int */ private function updateReportUserArray($reportUserArray) { $username = $reportUserArray['name']; unset($reportUserArray['name']); $reportUserArray['userName'] = $username; $sql = 'UPDATE `report_user` SET report_id = :report_id, user_id = :user_id, name = :userName, chart_enabled = :chart_enabled, file_enabled = :file_enabled, menu_enabled = :menu_enabled, tab_enabled = :tab_enabled WHERE id = :id'; $affectedRows = $this->db->fetchAffected($sql, $reportUserArray); if ($affectedRows > 0) { return (int)$reportUserArray['id']; } return 0; } /** * @param array $shareArray * * @return int */ private function insertShareArray($shareArray) { $sql = 'INSERT INTO `report_share` (report_id, chart_public, chart_axislabel, chart_dateformat, chart_type, chart_interval_value, chart_interval_mode, file_public, file_pdf_enabled, file_csv_enabled, file_xls_enabled, menu_public, menu_doctype, menu_label, menu_format, tab_public, tab_module, tab_label, tab_position, tab_action, chart_x_column, data_columns,chart_group_column) VALUES (:report_id, :chart_public, :chart_axislabel, :chart_dateformat, :chart_type, :chart_interval_value, :chart_interval_mode, :file_public, :file_pdf_enabled, :file_csv_enabled, :file_xls_enabled, :menu_public, :menu_doctype, :menu_label, :menu_format, :tab_public, :tab_module, :tab_label, :tab_position, :tab_action, :chart_x_column, :data_columns,:chart_group_column)'; $values = $this->sanitizeTransferDateTimes($shareArray); $this->db->fetchAffected($sql, $values); return $this->db->lastInsertId(); } /** * @param array $shareArray * * @return int */ private function updateShareArray($shareArray) { $sql = 'UPDATE `report_share` SET report_id = :report_id, chart_public = :chart_public, chart_axislabel = :chart_axislabel, chart_dateformat = :chart_dateformat, chart_type = :chart_type, chart_x_column = :chart_x_column, data_columns = :data_columns, chart_group_column = :chart_group_column, chart_interval_value = :chart_interval_value, chart_interval_mode = :chart_interval_mode, file_public = :file_public, file_pdf_enabled = :file_pdf_enabled, file_csv_enabled = :file_csv_enabled, file_xls_enabled = :file_xls_enabled, menu_public = :menu_public, menu_doctype = :menu_doctype, menu_label = :menu_label, menu_format = :menu_format, tab_public = :tab_public, tab_module = :tab_module, tab_action = :tab_action, tab_label = :tab_label, tab_position = :tab_position WHERE id=:id'; $values = $shareArray; $affectedRows = $this->db->fetchAffected($sql, $values); if ($affectedRows > 0) { return (int)$values['id']; } return 0; } /** * Finds copies of the specified name. * * @param string $name * * @param int $ignoreId * * @return array */ private function findReportCopyNames($name, $ignoreId = 0) { $sql = 'SELECT r.id, r.name FROM `report` AS `r` WHERE (r.name LIKE :origName OR r.name LIKE :copyFormat1 OR r.name LIKE :copyFormat2) AND r.id <> :ignoreId'; $values = [ 'origName' => $name, 'copyFormat1' => sprintf('%s(%%)', $name), 'copyFormat2' => sprintf('%s (%%)', $name), 'ignoreId' => $ignoreId, ]; $resultArray = $this->db->fetchPairs($sql, $values); if (empty($resultArray)) { return []; } return $resultArray; } /** * @param $reportName * * @return mixed */ private function getBaseName($reportName) { $baseName = $reportName; $isCopyName = preg_match('/^(.+\S)\s*\((\d+)\)$/', $reportName, $copyNameParts); if ($isCopyName === 1 && count($copyNameParts) > 1) { $baseName = $copyNameParts[1]; } return $baseName; } }