pridana implementacia backend s composerom a kniznicami TPsoft/APIlite a TPsoft/DBmodel
This commit is contained in:
257
backend/src/API.php
Normal file
257
backend/src/API.php
Normal file
@ -0,0 +1,257 @@
|
||||
<?php
|
||||
|
||||
namespace TPsoft\BugreportBackend;
|
||||
|
||||
require_once __DIR__ . '/Init.php';
|
||||
|
||||
use TPsoft\APIlite\APIlite;
|
||||
use TPsoft\BugreportBackend\Models\Reports;
|
||||
use TPsoft\BugreportBackend\Models\Attachments;
|
||||
use TPsoft\BugreportBackend\Models\Options;
|
||||
|
||||
|
||||
class API extends APIlite
|
||||
{
|
||||
/**
|
||||
* Add new report
|
||||
*
|
||||
* @param string $title
|
||||
* @param string $description
|
||||
* @param int $status 0 = Uncategorized, 1 = Waiting, 2 = InProgress, 3 = Blocked, 4 = Archived
|
||||
* @param string $group
|
||||
* @param int $priority 0 = Low, 1 = Medium, 2 = High, 3 = Urgent
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function add(string $title, string $description, int $status = 0, ?string $group = null, int $priority = 0): int
|
||||
{
|
||||
$status = intval($status);
|
||||
$priority = intval($priority);
|
||||
$reports = new Reports();
|
||||
$report_id = $reports->report(null, [
|
||||
'report_title' => $title,
|
||||
'report_description' => $description,
|
||||
'report_status' => $status,
|
||||
'report_group' => $group,
|
||||
'report_priority' => $priority,
|
||||
]);
|
||||
return $report_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update report
|
||||
*
|
||||
* @param int $report_id
|
||||
* @param array $report_data
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function update(int $report_id, array $report_data): bool
|
||||
{
|
||||
$reports = new Reports();
|
||||
$suc = $reports->report($report_id, $report_data);
|
||||
return $suc !== false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete report
|
||||
*
|
||||
* @param int $report_id
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function delete(int $report_id): bool
|
||||
{
|
||||
$reports = new Reports();
|
||||
$suc = $reports->report($report_id, null);
|
||||
return $suc !== false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get report
|
||||
*
|
||||
* @param int $report_id
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get(int $report_id): array
|
||||
{
|
||||
$reports = new Reports();
|
||||
return $reports->report($report_id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all reports
|
||||
*
|
||||
* @param array $status 0 = Uncategorized, 1 = Waiting, 2 = InProgress, 3 = Blocked, 4 = Archived
|
||||
* @param int $page Pagination from 0
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getAll(?array $status = null, int $page = 0): array
|
||||
{
|
||||
$page = intval($page);
|
||||
$reports = new Reports();
|
||||
if ($status === null) $status = array(0, 1, 2, 3);
|
||||
$ret = $reports->search('reports')
|
||||
->where(['report_status' => $status])
|
||||
->order(array('report_priority' => 'DESC', 'ordnum' => 'ASC'))
|
||||
->limit($page * 10, 10)
|
||||
->toArray();
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all reports grouped by status
|
||||
*
|
||||
* @param array $status 0 = Uncategorized, 1 = Waiting, 2 = InProgress, 3 = Blocked, 4 = Archived
|
||||
* @param int $page Pagination from 0
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getAllGrouped(?array $status = null, int $page = 0): array
|
||||
{
|
||||
$page = intval($page);
|
||||
$all = $this->getAll($status, $page);
|
||||
$groups = [];
|
||||
foreach ($all as $report) {
|
||||
$groups[$report['report_status']][] = $report;
|
||||
}
|
||||
return $groups;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get archived reports
|
||||
*
|
||||
* @param int $page Pagination from 0
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getArchived(int $page = 0): array
|
||||
{
|
||||
$page = intval($page);
|
||||
$reports = new Reports();
|
||||
$ret = $reports->search('reports')
|
||||
->where(['report_status' => 4])
|
||||
->order(array('created_dt' => 'DESC'))
|
||||
->limit($page * 10, 10)
|
||||
->toArray();
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update report order number
|
||||
*
|
||||
* @param array $ordnums report_id => ordnum
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function updateOrdNum(array $ordnums): bool
|
||||
{
|
||||
$reports = new Reports();
|
||||
$suc = true;
|
||||
foreach ($ordnums as $report_id => $ordnum) {
|
||||
$suc &= $reports->report($report_id, ['ordnum' => $ordnum]);
|
||||
}
|
||||
return $suc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update report status
|
||||
*
|
||||
* @param int $report_id
|
||||
* @param int $status 0 = Uncategorized, 1 = Waiting, 2 = InProgress, 3 = Blocked, 4 = Archived
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function updateStatus(int $report_id, int $status): bool
|
||||
{
|
||||
$reports = new Reports();
|
||||
$suc = $reports->report($report_id, ['report_status' => $status]);
|
||||
return $suc !== false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add report attachment
|
||||
*
|
||||
* @param int $report_id
|
||||
* @param string $attachment_type "comment" or "file"
|
||||
* @param string $attachment_content
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function attachmentAdd(int $report_id, string $attachment_type, string $attachment_content): bool
|
||||
{
|
||||
if ($attachment_type == 'file') {
|
||||
$data = json_decode($attachment_content, true);
|
||||
if (!is_array($data)) return false;
|
||||
$base64 = preg_replace('/^data:.*?;base64,/', '', $data['base64']);
|
||||
$base64_data = base64_decode($base64);
|
||||
$filename = 'report_' . $report_id . '_' . time() . '_' . sanitizeFilename($data['filename']);
|
||||
file_put_contents(UPLOAD_DIR_ATTACHMENTS . $filename, $base64_data);
|
||||
$attachment_content = $filename;
|
||||
}
|
||||
$attachments = new Attachments();
|
||||
$suc = $attachments->attachment(null, [
|
||||
'report_id' => $report_id,
|
||||
'attachment_type' => $attachment_type,
|
||||
'attachment_content' => $attachment_content,
|
||||
'created_dt' => date('Y-m-d H:i:s')
|
||||
]);
|
||||
return $suc !== false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update report attachment
|
||||
*
|
||||
* @param int $attachment_id
|
||||
* @param string $attachment_content
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function attachmentUpdate(int $attachment_id, string $attachment_content): bool
|
||||
{
|
||||
if (strlen(trim($attachment_content)) <= 0) return $this->attachmentDelete($attachment_id);
|
||||
$attachments = new Attachments();
|
||||
$suc = $attachments->attachment($attachment_id, [
|
||||
'attachment_content' => $attachment_content,
|
||||
'updated_dt' => date('Y-m-d H:i:s')
|
||||
]);
|
||||
return $suc !== false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all report attachments
|
||||
*
|
||||
* @param int $report_id
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function attachmentGetAll(int $report_id): array
|
||||
{
|
||||
$attachments = new Attachments();
|
||||
$all = $attachments->search('attachments')
|
||||
->where(['report_id' => $report_id])
|
||||
->order(array('created_dt' => 'ASC'))
|
||||
->toArray();
|
||||
if (is_array($all)) foreach ($all as $key => $row) {
|
||||
if ($all[$key]['attachment_type'] == 'file') {
|
||||
$all[$key]['attachment_content'] = UPLOAD_URL_ATTACHMENTS . $all[$key]['attachment_content'];
|
||||
}
|
||||
}
|
||||
return $all;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete report attachment
|
||||
*
|
||||
* @param int $attachment_id
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function attachmentDelete(int $attachment_id): bool {
|
||||
$attachments = new Attachments();
|
||||
$suc = $attachments->attachment($attachment_id, null);
|
||||
return $suc !== false;
|
||||
}
|
||||
}
|
||||
33
backend/src/Init.php
Normal file
33
backend/src/Init.php
Normal file
@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
require __DIR__ . '/../vendor/autoload.php';
|
||||
|
||||
use \Exception;
|
||||
use \TPsoft\DBmodel\DBmodel;
|
||||
|
||||
global $dbh;
|
||||
|
||||
if (Configuration::DB_TYPE == 'mysql') {
|
||||
$dbh = new DBmodel(sprintf('mysql:host=%s;dbname=%s;charset=utf8mb4', Configuration::DB_HOST, Configuration::DB_NAME), Configuration::DB_USER, Configuration::DB_PASS);
|
||||
} else if (Configuration::DB_TYPE == 'sqlite') {
|
||||
$dbh = new DBmodel(sprintf('sqlite:%s', Configuration::DB_FILEPATH));
|
||||
} else {
|
||||
throw new Exception('Unknown database type');
|
||||
}
|
||||
/*
|
||||
$dbh->tables = [
|
||||
'reports' => [
|
||||
'name' => 'reports',
|
||||
'primary_key_name' => 'report_id',
|
||||
'allow_attributes' => [
|
||||
'report_id' => 'varchar()',
|
||||
'report_title' => 'varchar()',
|
||||
'report_description' => 'varchar()',
|
||||
'report_status' => 'varchar()',
|
||||
'report_group' => 'varchar()',
|
||||
'report_priority' => 'varchar()',
|
||||
'created_dt' => 'varchar()',
|
||||
],
|
||||
],
|
||||
];
|
||||
*/
|
||||
88
backend/src/Models/Attachments.php
Normal file
88
backend/src/Models/Attachments.php
Normal file
@ -0,0 +1,88 @@
|
||||
<?php
|
||||
/*
|
||||
TPsoft.org 2000-2025
|
||||
file for controlers/*.php
|
||||
|
||||
Milestones:
|
||||
2025-09-30 22:49 Created
|
||||
*/
|
||||
|
||||
namespace TPsoft\BugreportBackend\Models;
|
||||
|
||||
class Attachments extends \TPsoft\DBmodel\DBmodel {
|
||||
|
||||
public $tables = array(
|
||||
'attachments' => array(
|
||||
'name' => 'attachments',
|
||||
'primary_key_name' => 'attachment_id',
|
||||
'allow_attributes' => array(
|
||||
'report_id' => 'INTEGER',
|
||||
'attachment_type' => 'VARCHAR(255)',
|
||||
'attachment_content' => 'TEXT',
|
||||
'created_dt' => 'DATETIME',
|
||||
'updated_dt' => 'DATETIME'
|
||||
)
|
||||
),
|
||||
);
|
||||
|
||||
public function exist($primary_key = null) {
|
||||
return $this->existRecord('attachments', $primary_key);
|
||||
}
|
||||
|
||||
public function attachment($primary_key = null, $data = array()) {
|
||||
if (is_null($primary_key)
|
||||
&& !isset($data['created_dt']))
|
||||
{
|
||||
$data['created_dt'] = date('Y-m-d H:i:s');
|
||||
}
|
||||
return $this->record('attachments', $primary_key, $data);
|
||||
}
|
||||
|
||||
public function attachmentBy($colname, $colvalue) {
|
||||
return $this->recordBy('attachments', $colname, $colvalue);
|
||||
}
|
||||
|
||||
public function attachmentSave($data = array()) {
|
||||
return $this->attachment($this->exist($data) ? $data : null, $data);
|
||||
}
|
||||
|
||||
public function attachmentEmpty() {
|
||||
return $this->recordEmpty('attachments');
|
||||
}
|
||||
|
||||
public function attachmentAttributes() {
|
||||
return $this->typesAttributes('attachments');
|
||||
}
|
||||
|
||||
public function attachmentCount() {
|
||||
return $this->count('attachments');
|
||||
}
|
||||
|
||||
public function getList($search = array(), $reverse = false, $concat_or = false) {
|
||||
return $this->search('attachments')
|
||||
->where($search, $concat_or)
|
||||
->order(array('attachment_id' => $reverse ? 'DESC' : 'ASC'))
|
||||
->toArray();
|
||||
}
|
||||
|
||||
public function getListOrganize($cola_name, $search = array(), $reverse = false, $concat_or = false) {
|
||||
$all = $this->getList($search, $reverse, $concat_or);
|
||||
$ret = array();
|
||||
if (is_array($all)) foreach ($all as $key => $row) {
|
||||
$ret[$row[$cola_name]] = $row;
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
public function getListByID($search = array(), $reverse = false, $concat_or = false) {
|
||||
return $this->getListOrganize('attachment_id', $search, $reverse, $concat_or);
|
||||
}
|
||||
|
||||
public function attachmentCombo($col_key, $col_value, $add_empty = false) {
|
||||
return $this->search('attachments')
|
||||
->toCombo($col_key, $col_value, $add_empty);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
||||
81
backend/src/Models/Options.php
Normal file
81
backend/src/Models/Options.php
Normal file
@ -0,0 +1,81 @@
|
||||
<?php
|
||||
/*
|
||||
TPsoft.org 2000-2025
|
||||
file for controlers/*.php
|
||||
|
||||
Milestones:
|
||||
2025-09-30 22:49 Created
|
||||
*/
|
||||
|
||||
namespace TPsoft\BugreportBackend\Models;
|
||||
|
||||
class Options extends \TPsoft\DBmodel\DBmodel {
|
||||
|
||||
public $tables = array(
|
||||
'options' => array(
|
||||
'name' => 'options',
|
||||
'primary_key_name' => '',
|
||||
'allow_attributes' => array(
|
||||
'key' => 'VARCHAR(64)',
|
||||
'value' => 'TEXT',
|
||||
'created_at' => 'DATETIME'
|
||||
)
|
||||
),
|
||||
);
|
||||
|
||||
public function exist($primary_key = null) {
|
||||
return $this->existRecord('options', $primary_key);
|
||||
}
|
||||
|
||||
public function option($primary_key = null, $data = array()) {
|
||||
return $this->record('options', $primary_key, $data);
|
||||
}
|
||||
|
||||
public function optionBy($colname, $colvalue) {
|
||||
return $this->recordBy('options', $colname, $colvalue);
|
||||
}
|
||||
|
||||
public function optionSave($data = array()) {
|
||||
return $this->option($this->exist($data) ? $data : null, $data);
|
||||
}
|
||||
|
||||
public function optionEmpty() {
|
||||
return $this->recordEmpty('options');
|
||||
}
|
||||
|
||||
public function optionAttributes() {
|
||||
return $this->typesAttributes('options');
|
||||
}
|
||||
|
||||
public function optionCount() {
|
||||
return $this->count('options');
|
||||
}
|
||||
|
||||
public function getList($search = array(), $reverse = false, $concat_or = false) {
|
||||
return $this->search('options')
|
||||
->where($search, $concat_or)
|
||||
->order(array('' => $reverse ? 'DESC' : 'ASC'))
|
||||
->toArray();
|
||||
}
|
||||
|
||||
public function getListOrganize($cola_name, $search = array(), $reverse = false, $concat_or = false) {
|
||||
$all = $this->getList($search, $reverse, $concat_or);
|
||||
$ret = array();
|
||||
if (is_array($all)) foreach ($all as $key => $row) {
|
||||
$ret[$row[$cola_name]] = $row;
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
public function getListByID($search = array(), $reverse = false, $concat_or = false) {
|
||||
return $this->getListOrganize('', $search, $reverse, $concat_or);
|
||||
}
|
||||
|
||||
public function optionCombo($col_key, $col_value, $add_empty = false) {
|
||||
return $this->search('options')
|
||||
->toCombo($col_key, $col_value, $add_empty);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
||||
90
backend/src/Models/Reports.php
Normal file
90
backend/src/Models/Reports.php
Normal file
@ -0,0 +1,90 @@
|
||||
<?php
|
||||
/*
|
||||
TPsoft.org 2000-2025
|
||||
file for controlers/*.php
|
||||
|
||||
Milestones:
|
||||
2025-09-30 22:21 Created
|
||||
*/
|
||||
|
||||
namespace TPsoft\BugreportBackend\Models;
|
||||
|
||||
class Reports extends \TPsoft\DBmodel\DBmodel {
|
||||
|
||||
public $tables = array(
|
||||
'reports' => array(
|
||||
'name' => 'reports',
|
||||
'primary_key_name' => 'report_id',
|
||||
'allow_attributes' => array(
|
||||
'report_title' => 'VARCHAR(255)',
|
||||
'report_description' => 'TEXT',
|
||||
'report_status' => 'INTEGER',
|
||||
'report_group' => 'VARCHAR(255)',
|
||||
'report_priority' => 'INTEGER',
|
||||
'created_dt' => 'DATETIME',
|
||||
'ordnum' => 'INTEGER'
|
||||
)
|
||||
),
|
||||
);
|
||||
|
||||
public function exist($primary_key = null) {
|
||||
return $this->existRecord('reports', $primary_key);
|
||||
}
|
||||
|
||||
public function report($primary_key = null, $data = array()) {
|
||||
if (is_null($primary_key)
|
||||
&& !isset($data['created_dt']))
|
||||
{
|
||||
$data['created_dt'] = date('Y-m-d H:i:s');
|
||||
}
|
||||
return $this->record('reports', $primary_key, $data);
|
||||
}
|
||||
|
||||
public function reportBy($colname, $colvalue) {
|
||||
return $this->recordBy('reports', $colname, $colvalue);
|
||||
}
|
||||
|
||||
public function reportSave($data = array()) {
|
||||
return $this->report($this->exist($data) ? $data : null, $data);
|
||||
}
|
||||
|
||||
public function reportEmpty() {
|
||||
return $this->recordEmpty('reports');
|
||||
}
|
||||
|
||||
public function reportAttributes() {
|
||||
return $this->typesAttributes('reports');
|
||||
}
|
||||
|
||||
public function reportCount() {
|
||||
return $this->count('reports');
|
||||
}
|
||||
|
||||
public function getList($search = array(), $reverse = false, $concat_or = false) {
|
||||
return $this->search('reports')
|
||||
->where($search, $concat_or)
|
||||
->order(array('report_id' => $reverse ? 'DESC' : 'ASC'))
|
||||
->toArray();
|
||||
}
|
||||
|
||||
public function getListOrganize($cola_name, $search = array(), $reverse = false, $concat_or = false) {
|
||||
$all = $this->getList($search, $reverse, $concat_or);
|
||||
$ret = array();
|
||||
if (is_array($all)) foreach ($all as $key => $row) {
|
||||
$ret[$row[$cola_name]] = $row;
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
public function getListByID($search = array(), $reverse = false, $concat_or = false) {
|
||||
return $this->getListOrganize('report_id', $search, $reverse, $concat_or);
|
||||
}
|
||||
|
||||
public function reportCombo($col_key, $col_value, $add_empty = false) {
|
||||
return $this->search('reports')
|
||||
->toCombo($col_key, $col_value, $add_empty);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
||||
Reference in New Issue
Block a user