Introduzione simulazione dei widget

Nuove strutture per gestire i widget del gestionale, base per la gestione deile stampe e miglioramento del sistema di simulazione delle richieste al gestionale legacy.
This commit is contained in:
Dasc3er 2021-03-15 10:43:14 +01:00
parent 97eaa07057
commit 06439a275f
26 changed files with 1515 additions and 24 deletions

21
UPGRADING.md Normal file
View File

@ -0,0 +1,21 @@
```sql
ALTER TABLE zz_users ADD COLUMN remember_token VARCHAR (255) AFTER password;
ALTER TABLE `zz_widgets` DROP `class`, ADD `class` varchar(255) NOT NULL;
UPDATE `zz_widgets` SET `class` = 'App\\OSM\\Widgets\\Retro\\ModalWidget' WHERE `more_link_type` = 'popup';
UPDATE `zz_widgets` SET `class` = 'App\\OSM\\Widgets\\Retro\\LinkWidget' WHERE `more_link_type` = 'link';
UPDATE `zz_widgets` SET `class` = 'App\\OSM\\Widgets\\Retro\\StatsWidget' WHERE `more_link_type` = 'javascript';
UPDATE `zz_widgets` SET `class` = 'App\\OSM\\Widgets\\Retro\\StatsWidget' WHERE `type` = 'print';
UPDATE `zz_widgets` SET `class` = 'App\\OSM\\Widgets\\Retro\\StatsWidget' WHERE `class` = '';
UPDATE `zz_widgets` SET `more_link` = `php_include` WHERE `more_link` = '';
UPDATE `zz_widgets` SET `class` = 'App\\OSM\\Widgets\\Retro\\ModalWidget' WHERE `name` = 'Stampa calendario';
UPDATE `zz_widgets` SET `more_link` = REPLACE(`more_link`, 'plugins/', 'modules/');
ALTER TABLE `zz_widgets` DROP `print_link`, DROP `more_link_type`, DROP `php_include`;
UPDATE `zz_widgets` SET `more_link` = REPLACE(`more_link`, './', '/');
UPDATE `zz_widgets` SET `class` = 'Modules\\Dashboard\\NotificheWidget', `more_link` = '' WHERE `zz_widgets`.`name` = 'Note interne';
```

View File

@ -14,15 +14,46 @@ class LegacyController extends Controller
public function index(Request $request)
{
$path = substr($request->getPathInfo(), 1);
$base_path = base_path('legacy');
// Gestione dell'output
$output = self::simulate($path);
$response = response($output);
// Fix content-type per contenuti non HTML
if (ends_with($path, '.js')) {
$response = $response->header('Content-Type', 'application/javascript');
} elseif (string_contains($path, 'pdfgen.php')) {
$response = $response->header('Content-Type', 'application/pdf');
}
// Correzione header per API
elseif (self::isApiRequest($path)) {
$response = $response->header('Content-Type', 'application/json');
}
return $response;
}
protected static function isApiRequest($path)
{
// Fix per redirect all'API
$api_request = false;
if (in_array($path, ['api', 'api/', 'api/index.php'])) {
$path = 'api/index.php';
$api_request = true;
}
return $api_request;
}
public static function simulate($path)
{
$base_path = base_path('legacy');
// Fix per redirect all'API
$api_request = self::isApiRequest($path);
if ($api_request) {
$path = 'api/index.php';
}
// Ricerca del file interessato
$file = realpath($base_path.'/'.$path);
if (strpos($file, $base_path) === false) {
@ -40,17 +71,7 @@ class LegacyController extends Controller
// Gestione dell'output
$output = ob_get_clean();
$response = response($output);
// Fix content-type per contenuti non HTML
if (ends_with($path, '.js')) {
$response = $response->header('Content-Type', 'application/javascript');
} elseif (string_contains($path, 'pdfgen.php')) {
$response = $response->header('Content-Type', 'application/pdf');
} elseif ($api_request) {
$response = $response->header('Content-Type', 'application/json');
}
return $response;
return $output;
}
}

View File

@ -0,0 +1,33 @@
<?php
namespace App\Http\Controllers;
use App\OSM\Prints\Template;
use Illuminate\Http\Request;
class PrintController extends Controller
{
public function view(Request $request)
{
$link = route('print-open', [
'print_id' => $args['print_id'],
'record_id' => $args['record_id'],
]);
$args['link'] = base_url().'/assets/pdfjs/web/viewer.html?file='.$link;
$response = $this->twig->render($response, '@resources/uploads/frame.twig', $args);
return $response;
}
public function open(Request $request)
{
$print = Template::find($args['print_id']);
$manager = $print->getManager();
$pdf = $manager->render();
return response()->setContent($pdf)
->header('Content-Type', 'application/pdf');
}
}

View File

@ -1,10 +0,0 @@
<?php
namespace App\Http\Controllers;
class Test extends Controller
{
public function index()
{
}
}

View File

@ -0,0 +1,23 @@
<?php
namespace App\Http\Controllers;
use App\OSM\Widgets\ModalWidget;
use App\OSM\Widgets\Widget;
use Illuminate\Http\Request;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
class WidgetModalController extends Controller
{
public function modal(Request $request, $id)
{
$widget = Widget::find($id);
$class = $widget->getManager();
if (!($class instanceof ModalWidget)) {
throw new NotFoundHttpException();
}
return $class->getModal();
}
}

View File

@ -0,0 +1,32 @@
<?php
/*
* OpenSTAManager: il software gestionale open source per l'assistenza tecnica e la fatturazione
* Copyright (C) DevCode s.r.l.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
namespace App\OSM;
use Illuminate\Database\Eloquent\Model;
abstract class ComponentManager
{
protected $model;
public function __construct(Model $model)
{
$this->model = $model;
}
}

View File

@ -0,0 +1,41 @@
<?php
/*
* OpenSTAManager: il software gestionale open source per l'assistenza tecnica e la fatturazione
* Copyright (C) DevCode s.r.l.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
namespace App\OSM;
/**
* Implementazione di base dell'interazione con i componenti a livello interno.
*
* @since 2.5
*/
trait ComponentManagerTrait
{
protected $manager_object;
public function getManager(): ComponentManager
{
if (!isset($this->manager_object)) {
$class = $this->attributes['class'];
$this->manager_object = new $class($this);
}
return $this->manager_object;
}
}

116
app/OSM/Prints/Autofill.php Normal file
View File

@ -0,0 +1,116 @@
<?php
/*
* OpenSTAManager: il software gestionale open source per l'assistenza tecnica e la fatturazione
* Copyright (C) DevCode s.r.l.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
namespace App\OSM\Prints;
/**
* Classe dedicata alla gestione delle righe fantasma per il miglioramento grafico delle stampe tabellari.
*
* @since 2.3
*/
class Autofill
{
protected $space = 0;
protected $current = 0;
protected $char_number;
protected $column_number;
protected $max_rows = 20;
protected $max_rows_first_page = 20;
protected $max_additional = 15;
public function __construct($column_number, $char_number = 70)
{
$this->column_number = $column_number;
$this->char_number = $char_number;
}
public function setRows($rows, $additional = null, $first_page = null)
{
$this->max_rows = $rows;
$this->max_additional = isset($additional) ? $additional : floor($this->max_rows - $this->max_rows / 4);
$this->max_rows_first_page = isset($first_page) ? $first_page : $rows;
}
public function count($text, $small = false)
{
$count = ceil(strlen($text) / $this->char_number);
$count += substr_count($text, PHP_EOL);
$count += substr_count($text, '<br>');
if ($small) {
$count = $count / 3;
}
$this->set($count);
}
public function set($count)
{
if ($count > $this->current) {
$this->current = $count;
}
}
public function next()
{
$this->space += $this->current;
$this->current = 0;
}
public function getAdditionalNumber()
{
$page = ceil($this->space / $this->max_rows_first_page);
if ($page > 1) {
$rows = floor($this->space) % $this->max_rows;
} else {
$rows = floor($this->space) % $this->max_rows_first_page;
}
$number = $this->max_additional - $rows;
return $number > 0 ? $number : 0;
}
public function generate()
{
$this->next();
$result = '';
$number = $this->getAdditionalNumber();
for ($i = 0; $i < $number; ++$i) {
$result .= '
<tr>';
for ($c = 0; $c < $this->column_number; ++$c) {
$result .= '
<td>&nbsp;</td>';
}
$result .= '
</tr>';
}
return $result;
}
}

View File

@ -0,0 +1,150 @@
<?php
/*
* OpenSTAManager: il software gestionale open source per l'assistenza tecnica e la fatturazione
* Copyright (C) DevCode s.r.l.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
namespace App\OSM\Prints;
use AppLegacy;
use Mpdf\Mpdf;
/**
* Classe per la gestione delle informazioni relative alle stampe installate.
*
* @since 2.5
*/
abstract class MPDFManager extends Manager
{
public function getManager()
{
if (!isset($this->manager)) {
$settings = $this->getSettings();
// Instanziamento dell'oggetto mPDF
$manager = new Mpdf([
'mode' => 'utf-8',
'format' => $settings['format'],
'orientation' => strtoupper($settings['orientation']) == 'L' ? 'L' : 'P',
'font-size' => $settings['font-size'],
'margin_left' => $settings['margins']['left'],
'margin_right' => $settings['margins']['right'],
'setAutoBottomMargin' => 'stretch',
'setAutoTopMargin' => 'stretch',
// Abilitazione per lo standard PDF/A
//'PDFA' => true,
//'PDFAauto' => true,
]);
// Inclusione dei fogli di stile CSS
$styles = [
AppLegacy::filepath('templates/base|custom|', 'bootstrap.css'),
AppLegacy::filepath('templates/base|custom|', 'style.css'),
];
foreach ($styles as $value) {
$manager->WriteHTML(file_get_contents($value), 1);
}
// Impostazione del font-size
$manager->WriteHTML('body {font-size: '.$settings['font-size'].'pt;}', 1);
$this->manager = $manager;
}
return $this->manager;
}
/**
* Genera la stampa PDF richiesta.
*/
public function generate(?string $directory = null): array
{
$info = $this->init();
$settings = $this->getSettings();
$manager = $this->getManager();
$replaces = $this->getReplaces($info['id_cliente'], $info['id_sede']);
$args = array_merge($info, $replaces);
// Impostazione header
$this->renderHeader($args);
// Impostazione footer
$this->renderFooter($args);
// Impostazione body
$this->renderBody($args);
// Impostazione footer per l'ultima pagina
if (!empty($options['last-page-footer'])) {
$args['is_last_page'] = true;
$footer = $this->getFooter($args);
$manager->WriteHTML('<div class="fake-footer">'.$footer.'</div>');
$manager->WriteHTML('<div style="position:absolute; bottom: 13mm; margin-right: '.($settings['margins']['right']).'mm">'.$footer.'</div>');
}
$file = $this->getFileData($this->record_id, $directory, $replaces);
$title = $file['name'];
// Impostazione del titolo del PDF
$this->getManager()->SetTitle($title);
return $file;
}
/**
* Genera la stampa PDF richiesta e la visualizza nel browser.
*/
public function render(): void
{
$this->generate();
// Creazione effettiva del PDF
$this->getManager()->Output(null, \Mpdf\Output\Destination::INLINE);
}
/**
* Genera la stampa PDF richiesta e la visualizza nel browser.
*/
public function save(string $directory): void
{
parent::save($directory);
$file = $this->generate($directory);
// Creazione effettiva del PDF
$this->getManager()->Output($file['path'], \Mpdf\Output\Destination::FILE);
}
protected function renderHeader(array $args): void
{
$content = $this->getHeader($args);
// Impostazione di header
$this->getManager()->SetHTMLHeader($content);
}
protected function renderFooter(array $args): void
{
$content = $this->getFooter($args);
// Impostazione di footer
$this->getManager()->SetHTMLFooter($content);
}
}

204
app/OSM/Prints/Manager.php Normal file
View File

@ -0,0 +1,204 @@
<?php
/*
* OpenSTAManager: il software gestionale open source per l'assistenza tecnica e la fatturazione
* Copyright (C) DevCode s.r.l.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
namespace App\OSM\Prints;
use App;
use AppLegacy;
abstract class Manager extends App\OSM\ComponentManager
{
protected $record_id;
protected $manager;
protected $replaces;
public function setRecord(?int $record_id = null)
{
$this->record_id = $record_id;
}
/**
* Genera e salva la stampa PDF richiesta.
*/
public function save(string $directory): void
{
if (empty($directory) || !directory($directory)) {
throw new \InvalidArgumentException();
}
}
/**
* Genera la stampa PDF richiesta e la visualizza nel browser.
*/
abstract public function render(array $args = []): string;
/**
* Genera la stampa PDF richiesta.
*/
abstract public function generate(?string $directory = null): array;
protected function getSettings(): array
{
// Impostazioni di default
$default = include AppLegacy::filepath('templates/base|custom|', 'settings.php');
// Impostazioni personalizzate della stampa
$custom = $this->getTemplateSettings();
// Individuazione delle impostazioni finali
$settings = array_merge($default, (array) $custom);
return $settings;
}
protected function getHeader(array $args): string
{
$content = $this->getTemplateHeader($args);
return !empty($content) ? $content : '$default_header$';
}
protected function getFooter(array $args): string
{
$content = $this->getTemplateFooter($args);
return !empty($content) ? $content : '$default_footer$';
}
protected function getReplaces(?int $id_cliente = null, ?int $id_sede = null): array
{
if (isset($this->replaces)) {
return $this->replaces;
}
$database = $this->database;
$id_record = $this->record_id;
// Informazioni cliente
$query = 'SELECT an_anagrafiche.*, an_sedi.*,
IF(an_sedi.codice_fiscale != "", an_sedi.codice_fiscale, sede_legale.codice_fiscale) AS codice_fiscale,
IF(an_sedi.piva != "", an_sedi.piva, sede_legale.piva) AS piva
FROM an_anagrafiche
INNER JOIN an_sedi ON an_anagrafiche.idanagrafica = an_sedi.idanagrafica
INNER JOIN an_sedi AS sede_legale ON an_anagrafiche.id_sede_legale = an_sedi.id
WHERE an_sedi.idanagrafica='.prepare($id_cliente);
if (empty($id_sede)) {
$query .= ' AND `an_sedi`.`id`=`an_anagrafiche`.`id_sede_legale`';
} else {
$query .= ' AND `an_sedi`.`id`='.prepare($id_sede);
}
$cliente = $database->fetchOne($query);
// Informazioni azienda
$id_azienda = setting('Azienda predefinita');
$azienda = $database->fetchOne('SELECT *, (SELECT iban FROM co_banche WHERE id IN (SELECT idbanca FROM co_documenti WHERE id = '.prepare($id_record).' ) ) AS codiceiban, (SELECT nome FROM co_banche WHERE id IN (SELECT idbanca FROM co_documenti WHERE id = '.prepare($id_record).' ) ) AS appoggiobancario, (SELECT bic FROM co_banche WHERE id IN (SELECT idbanca FROM co_documenti WHERE id = '.prepare($id_record).' ) ) AS bic FROM an_anagrafiche WHERE idanagrafica = '.prepare($id_azienda));
// Prefissi e contenuti del replace
$results = [
'cliente' => $cliente,
'azienda' => $azienda,
];
foreach ($results as $prefix => $values) {
// Eventuali estensioni dei contenuti
$citta = '';
if (!empty($values['cap'])) {
$citta .= $values['cap'];
}
if (!empty($values['citta'])) {
$citta .= ' '.$values['citta'];
}
if (!empty($values['provincia'])) {
$citta .= ' ('.$values['provincia'].')';
}
$results[$prefix]['citta_full'] = $citta;
}
// Header di default
$header_file = AppLegacy::filepath('templates/base|custom|/header.php');
$default_header = include $header_file;
$default_header = !empty($options['hide-header']) ? '' : $default_header;
// Footer di default
$footer_file = AppLegacy::filepath('templates/base|custom|/footer.php');
$default_footer = include $footer_file;
$default_footer = !empty($options['hide-footer']) ? '' : $default_footer;
// Logo di default
$default_logo = AppLegacy::filepath('templates/base|custom|/logo_azienda.jpg');
// Logo generico
if (!empty(setting('Logo stampe'))) {
$default_logo = AppLegacy::filepath('files/anagrafiche/'.setting('Logo stampe'));
}
// Valori aggiuntivi per la sostituzione
$this->replaces = array_merge($results, [
'default_header' => $default_header,
'default_footer' => $default_footer,
'default_logo' => $default_logo,
]);
return $this->replaces;
}
protected function getFileData($directory, $original_replaces)
{
$id_record = $this->record_id;
$module = $this->print->module;
$name = $this->print->filename.'.pdf';
$name = $module->replacePlaceholders($id_record, $name);
$replaces = [];
foreach ($original_replaces as $key => $value) {
$key = str_replace('$', '', $key);
$replaces['{'.$key.'}'] = $value;
}
$name = replace($name, $replaces);
$filename = sanitizeFilename($name);
$file = rtrim($directory, '/').'/'.$filename;
return [
'name' => $name,
'path' => $file,
];
}
abstract protected function init(): array;
abstract protected function getManager();
abstract protected function renderHeader(array $args): void;
abstract protected function renderFooter(array $args): void;
abstract protected function renderBody(array $args): void;
abstract protected function getTemplateSettings(): array;
abstract protected function getTemplateHeader(array $args): string;
abstract protected function getTemplateFooter(array $args): string;
}

View File

@ -0,0 +1,176 @@
<?php
/*
* OpenSTAManager: il software gestionale open source per l'assistenza tecnica e la fatturazione
* Copyright (C) DevCode s.r.l.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
namespace App\OSM\Prints\Retro;
use App;
use AppLegacy;
use App\OSM\Prints\MPDFManager;
class Manager extends MPDFManager
{
protected $body;
protected $header;
protected $footer;
protected function renderBody(array $args): void
{
$this->load($args);
$this->getManager()->WriteHTML($this->body);
}
protected function load(array $args): void
{
if (isset($this->body)) {
return;
}
// Fix per le variabili in PHP
foreach ($args['cliente'] as $key => $value) {
$args['c_'.$key] = $value;
}
foreach ($args['azienda'] as $key => $value) {
$args['f_'.$key] = $value;
}
extract($args);
$dbo = $database = database();
ob_start();
include $this->filepath('header.php');
$content = ob_get_clean();
$this->header = $this->replace($content);
ob_start();
include $this->filepath('body.php');
$content = ob_get_clean();
if (!empty($autofill)) {
$result = $autofill->generate();
$content = str_replace('|autofill|', $result, $content);
}
$this->body = $this->replace($content);
ob_start();
include $this->filepath('footer.php');
$content = ob_get_clean();
$this->footer = $this->replace($content);
}
protected function getReplaces(?int $id_cliente = null, ?int $id_sede = null): array
{
$replaces = parent::getReplaces($id_cliente, $id_sede);
// Logo specifico della stampa
$logo = \Prints::filepath($this->print->id, 'logo_azienda.jpg');
$logo = $logo ?: $replaces['default_logo'];
// Valori aggiuntivi per la sostituzione
$this->replaces = array_merge($replaces, [
'logo' => $logo,
]);
return $this->replaces;
}
protected function replace($content): string
{
$info = $this->init();
$replaces = $this->getReplaces($info['id_cliente'], $info['id_sede']);
$replaces = array_merge($replaces, (array) $info['custom']);
$list = [];
foreach ($replaces as $key => $value) {
if (!is_array($value)) {
$list[$key] = $value;
}
}
foreach ($replaces['cliente'] as $key => $value) {
$list['c_'.$key] = $value;
}
foreach ($replaces['azienda'] as $key => $value) {
$list['f_'.$key] = $value;
}
$results = [];
foreach ($list as $key => $value) {
$results['$'.$key.'$'] = $value;
}
return replace($content, $results);
}
protected function getPath(): string
{
return base_path().'/templates/'.$this->print->directory;
}
protected function filepath($file): ?string
{
return AppLegacy::filepath($this->getPath().'|custom|', $file);
}
protected function init(): array
{
$record_id = $id_record = $this->record_id;
$module_id = $id_module = $this->print->module->id;
$print_id = $id_print = $this->print->id;
$dbo = $database = database();
// Individuazione delle variabili fondamentali per la sostituzione dei contenuti
include $this->filepath('init.php');
return get_defined_vars();
}
protected function getTemplateSettings(): array
{
$file = $this->filepath('settings.php');
if (file_exists($file)) {
return include $file;
}
return [];
}
protected function getTemplateHeader(array $args): string
{
$this->load($args);
return $this->header;
}
protected function getTemplateFooter(array $args): string
{
$this->load($args);
return $this->footer;
}
}

View File

@ -0,0 +1,83 @@
<?php
/*
* OpenSTAManager: il software gestionale open source per l'assistenza tecnica e la fatturazione
* Copyright (C) DevCode s.r.l.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
namespace App\OSM\Prints;
use App\OSM\ComponentManagerTrait;
use Common\SimpleModelTrait;
use Models\Group;
use Common\Model;
use Illuminate\Database\Eloquent\Builder;
use Models\Module;
use Traits\LocalPoolTrait;
class Template extends Model
{
use SimpleModelTrait;
use LocalPoolTrait;
use ComponentManagerTrait;
protected $table = 'zz_prints';
protected $main_folder = 'templates';
// Attributi Eloquent
/**
* Restituisce un array associativo dalla codifica JSON delle opzioni di stampa.
*
* @param string $string
*
* @return array
*/
public function getOptionsAttribute()
{
// Fix per contenuti con newline integrate
$string = str_replace(["\n", "\r"], ['\\n', '\\r'], $this->options);
$result = (array) json_decode($string, true);
return $result;
}
/* Relazioni Eloquent */
public function module()
{
return $this->belongsTo(Module::class, 'id_module');
}
/*
public function groups()
{
return $this->morphToMany(Group::class, 'permission', 'zz_permissions', 'external_id', 'group_id')->where('permission_level', '!=', '-')->withPivot('permission_level');
}*/
protected static function boot()
{
parent::boot();
static::addGlobalScope('enabled', function (Builder $builder) {
$builder->where('enabled', true);
});
static::addGlobalScope('permission', function (Builder $builder) {
//$builder->with('groups');
});
}
}

View File

@ -0,0 +1,36 @@
<?php
/*
* OpenSTAManager: il software gestionale open source per l'assistenza tecnica e la fatturazione
* Copyright (C) DevCode s.r.l.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
namespace App\OSM\Widgets;
/**
* Tipologia di widget indirizzato alla presentazione di un link ausiliario per l'utente finale.
* Presenta esclusivamente un tiolo e al click prevede il reindirizzamento a un indirizzo specifico.
*
* @since 2.5
*/
abstract class LinkWidget extends Manager
{
abstract public function getLink(): string;
public function getAttributes(): string
{
return 'href="'.$this->getLink().'"';
}
}

View File

@ -0,0 +1,68 @@
<?php
/*
* OpenSTAManager: il software gestionale open source per l'assistenza tecnica e la fatturazione
* Copyright (C) DevCode s.r.l.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
namespace App\OSM\Widgets;
use App\OSM\ComponentManager;
/**
* Classe dedicata alla gestione di base dei widget del gestionale.
* Introduce un rendering di base e definisce i comportamenti standard da estendere per un utilizzo più completo.
*
* @since 2.5
*/
abstract class Manager extends ComponentManager
{
protected $record_id;
public function setRecord(?int $record_id = null)
{
$this->record_id = $record_id;
}
/**
* Get the view / contents that represent the component.
*
* @return \Illuminate\Contracts\View\View|string
*/
public function render()
{
$widget = $this->model;
$title = $this->getTitle();
$content = $this->getContent();
$attributes = $this->getAttributes();
return view('components.widget', [
'widget' => $widget,
'title' => $title,
'content' => $content,
'attrs' => $attributes,
]);
}
abstract public function getTitle(): string;
abstract public function getContent(): string;
public function getAttributes(): string
{
return 'href="#"';
}
}

View File

@ -0,0 +1,40 @@
<?php
/*
* OpenSTAManager: il software gestionale open source per l'assistenza tecnica e la fatturazione
* Copyright (C) DevCode s.r.l.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
namespace App\OSM\Widgets;
/**
* Tipologia di widget dedicato alla gestione di un modal aperto al click
* Presenta un titolo e una valore personalizzato; al click produce l'apertura del modal specificato.
*
* @since 2.5
*/
abstract class ModalWidget extends Manager
{
abstract public function getModal(): string;
abstract public function getLink(): string;
public function getAttributes(): string
{
$title = $this->getTitle();
return 'data-href="'.$this->getLink().'" data-toggle="modal" data-title="'.$title.'"';
}
}

View File

@ -0,0 +1,40 @@
<?php
/*
* OpenSTAManager: il software gestionale open source per l'assistenza tecnica e la fatturazione
* Copyright (C) DevCode s.r.l.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
namespace App\OSM\Widgets\Retro;
use App\OSM\Widgets\LinkWidget as Original;
class LinkWidget extends Original
{
public function getLink(): string
{
return base_url().$this->model['more_link'];
}
public function getTitle(): string
{
return $this->model['text'];
}
public function getContent(): string
{
return '';
}
}

View File

@ -0,0 +1,84 @@
<?php
/*
* OpenSTAManager: il software gestionale open source per l'assistenza tecnica e la fatturazione
* Copyright (C) DevCode s.r.l.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
namespace App\OSM\Widgets\Retro;
use App\Http\Controllers\LegacyController;
use Models\Module;
use Util\Query;
use App\OSM\Widgets\ModalWidget as Original;
class ModalWidget extends Original
{
public function getModal(): string
{
$content = '';
$widget = $this->model;
if (!empty($widget['more_link'])) {
$content = LegacyController::simulate($widget['more_link']);
}
return $content;
}
public function getLink(): string
{
$id = $this->model->id;
return route('widget-modal', [
'id' => $id,
]);
}
public function getTitle(): string
{
return $this->model['text'] ?: '';
}
public function getContent(): string
{
$content = '';
$widget = $this->model;
if (!empty($widget['query'])) {
$query = $widget['query'];
$module = Module::pool($widget['id_module']);
$additionals = \Modules::getAdditionalsQuery($widget['id_module']);
//$additionals = $module->getAdditionalsQuery();
if (!empty($additionals)) {
$query = str_replace('1=1', '1=1 '.$additionals, $query);
}
$query = Query::replacePlaceholder($query);
// Individuazione del risultato della query
$database = database();
$value = '-';
if (!empty($query)) {
$value = $database->fetchArray($query)[0]['dato'];
}
$content = preg_match('/\\d/', $value) ? $value : '-';
}
return $content;
}
}

View File

@ -0,0 +1,47 @@
<?php
/*
* OpenSTAManager: il software gestionale open source per l'assistenza tecnica e la fatturazione
* Copyright (C) DevCode s.r.l.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
namespace App\OSM\Widgets\Retro;
use App\OSM\Widgets\StatsWidget as Original;
class StatsWidget extends Original
{
public function getQuery(): string
{
return $this->model['query'] ?: 'SELECT 0 AS dato';
}
public function getAttributes(): string
{
$attributes = parent::getAttributes();
$js = $this->model['more_link'];
if (!empty($js)) {
return $attributes.' onclick="'.$js.'"';
}
return $attributes;
}
public function getTitle(): string
{
return $this->model['text'];
}
}

View File

@ -0,0 +1,64 @@
<?php
/*
* OpenSTAManager: il software gestionale open source per l'assistenza tecnica e la fatturazione
* Copyright (C) DevCode s.r.l.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
namespace App\OSM\Widgets;
use Models\Module;
use Util\Query;
/**
* Tipologia di widget indirizzato alla visualizzazione di una statistica informativa per l'utente finale.
* Presenta un titolo e una valore personalizzato; al click non prevede particolari operazioni.
*
* @since 2.5
*/
abstract class StatsWidget extends Manager
{
abstract public function getQuery(): string;
public function getContent(): string
{
$widget = $this->model;
// Individuazione della query relativa
$query = $this->getQuery();
$module = Module::pool($widget['id_module']);
$additionals = \Modules::getAdditionalsQuery($widget['id_module']);
//$additionals = $module->getAdditionalsQuery();
if (!empty($additionals)) {
$query = str_replace('1=1', '1=1 '.$additionals, $query);
}
$query = Query::replacePlaceholder($query);
// Individuazione del risultato della query
$database = database();
$value = null;
if (!empty($query)) {
$value = $database->fetchArray($query)[0]['dato'];
if (!preg_match('/\\d/', $value)) {
$value = '-';
}
}
return $value;
}
}

View File

@ -0,0 +1,70 @@
<?php
/*
* OpenSTAManager: il software gestionale open source per l'assistenza tecnica e la fatturazione
* Copyright (C) DevCode s.r.l.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
namespace App\OSM\Widgets;
use App\OSM\ComponentManagerTrait;
use Common\SimpleModelTrait;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;
use Models\Module;
/**
* Modello Eloquent per i widget del gestionale.
*
* @since 2.5
*/
class Widget extends Model
{
use SimpleModelTrait;
use ComponentManagerTrait;
protected $table = 'zz_widgets';
protected $appends = [
'permission',
];
/* Relazioni Eloquent */
public function module()
{
return $this->belongsTo(Module::class, 'id_module');
}
/*
public function groups()
{
return $this->morphToMany(Group::class, 'permission', 'zz_permissions', 'external_id', 'group_id')->where('permission_level', '!=', '-')->withPivot('permission_level');
}
*/
protected static function boot()
{
parent::boot();
static::addGlobalScope('enabled', function (Builder $builder) {
$builder->where('enabled', true);
});
static::addGlobalScope('permission', function (Builder $builder) {
//$builder->with('groups');
});
}
}

View File

@ -0,0 +1,40 @@
<?php
namespace App\View\Components;
use App\OSM\Widgets\Manager;
use App\OSM\Widgets\Widget as Model;
use Illuminate\View\Component;
class Widget extends Component
{
protected $widget;
/**
* @var Manager
*/
protected $manager;
/**
* Create a new component instance.
*
* @param $id
*/
public function __construct(
$id
) {
$this->widget = Model::find($id);
$this->manager = $this->widget->getManager();
}
/**
* Get the view / contents that represent the component.
*
* @return \Illuminate\Contracts\View\View|string
*/
public function render()
{
$manager = $this->manager;
return $manager->render();
}
}

2
legacy

@ -1 +1 @@
Subproject commit 5730434cc63c67880049f6adb116791dc8af8a5b
Subproject commit 767e211f4c616315618e222b6d55338f92d247a5

View File

@ -0,0 +1,25 @@
<a class="clickable" {!! $attrs !!}>
<div class="info-box">
<button type="button" class="close" onclick="if(confirm('Disabilitare questo widget?')) { $.post('{{ base_url() }}/actions.php?id_module={{ $widget->module->id }}', { op: 'disable_widget', id: '{{ $widget->id }}' }, function(response){ location.reload(); }); }" >
<span aria-hidden="true">&times;</span><span class="sr-only">{{ tr('Chiudi') }}</span>
</button>
<span class="info-box-icon" style="background-color:{{ $widget->bgcolor }}">
@if(!empty($widget['icon']))
<i class="{{ $widget->icon }}"></i>
@endif
</span>
<div class="info-box-content">
<span class="info-box-text {{ !empty($widget['help']) ? ' tip' : '' }}" {{ !empty($widget['help']) ? ' title="'.prepareToField($widget['help']).'" data-position="bottom"' : '' }}>
{{ $title }}
{{ !empty($widget['help']) ? '<i class="fa fa-question-circle-o"></i>' : '' }}
</span>
@if(isset($content))
<span class="info-box-number">{{ $content }}</span>
@endif
</div>
</div>
</a>

View File

@ -0,0 +1,62 @@
@extends('layouts.app')
@section('title', $module->title)
@section('content')
@yield('top_content')
<div class="nav-tabs-custom">
<ul class="nav nav-tabs pull-right" id="tabs" role="tablist">
<li class="pull-left nav-item header">
<a data-toggle="tab" href="#tab_0">
@include('modules.title')
</a>
</li>
@php($hide_sidebar = auth()->check() && setting('Nascondere la barra dei plugin di default'))
<li class="control-sidebar-toggle">
<a data-toggle="control-sidebar" style="cursor: pointer">{{ tr('Plugin') }}</a>
</li>
<script>
$(document).ready(function() {
@if($hide_sidebar)
$(".control-sidebar").removeClass("control-sidebar-shown");
$("aside.content-wrapper, .main-footer").toggleClass("with-control-sidebar");
@endif
$(".control-sidebar-toggle").bind("click", function() {
$("aside.content-wrapper, .main-footer").toggleClass("with-control-sidebar");
$(".control-sidebar").toggleClass("control-sidebar-shown");
});
});
</script>
</ul>
</div>
<div class="tab-content">
<div id="tab_0" class="tab-pane active">
@yield('module_content')
</div>
</div>
@yield('bottom_content')
<script>
$('#main_tab').click(function (e) {
$('#tabs a[href="#tab_0"]').tab('show').trigger('show.bs.tab');
removeHash();
});
</script>
@endsection
@section('top_content')
<!-- Widget in alto -->
{( "name": "widgets", "id_module": "{{ $module->id }}", "id_record": "{{ 1 }}", "position": "top", "place": "controller" )}
@endsection
@section('bottom_content')
<!-- Widget in alto -->
{( "name": "widgets", "id_module": "{{ $module->id }}", "id_record": "{{ 1 }}", "position": "right", "place": "controller" )}
@endsection

View File

@ -0,0 +1,17 @@
@if(!empty($module->help))
<span class="tip" title="{{ $module->help }}" data-position="bottom">
<i class="{{ $module->icon }}"></i> {{ $module->title }}
<i class="fa fa-question-circle-o" style="font-size:0.75em"></i>
</span>
@else
<i class="{{ $module->icon }}"></i> {{ $module->title }}
@endif
{{-- $module->hasAddFile() and --}}
@if($module->permission == 'rw')
<!-- Pulsante "Aggiungi" solo se la struttura lo supporta -->
<button type="button" class="btn btn-primary" data-toggle="modal" data-title="{{ tr('Aggiungi') }}..." data-href="{{ 'test' }}">
<i class="fa fa-plus"></i>
</button>
@endif

View File

@ -9,6 +9,7 @@ use App\Http\Controllers\MessageController;
use App\Http\Controllers\RequirementsController;
use App\Http\Controllers\Test;
use App\Http\Controllers\UserController;
use App\Http\Controllers\WidgetModalController;
use Illuminate\Support\Facades\Route;
/*
@ -119,6 +120,13 @@ Route::get('/logs', [UserController::class, 'logs'])
->middleware(['auth'])
->name('logs');
// Log di accesso
Route::get('/widget/modal/{id}', [WidgetModalController::class, 'modal'])
->whereNumber('id')
->middleware(['auth'])
->name('widget-modal');
// Informazioni sull'utente
Route::prefix('user')
->middleware(['auth'])