Introduzione modulo Aggiornamenti con nuove strutture
This commit is contained in:
parent
c3f4abb578
commit
97eaa07057
|
@ -11,8 +11,9 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
|||
|
||||
class LegacyController extends Controller
|
||||
{
|
||||
public function index(Request $request, $path = 'index.php')
|
||||
public function index(Request $request)
|
||||
{
|
||||
$path = substr($request->getPathInfo(), 1);
|
||||
$base_path = base_path('legacy');
|
||||
|
||||
// Fix per redirect all'API
|
||||
|
|
|
@ -0,0 +1,149 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use Util\FileSystem;
|
||||
|
||||
class RequirementsController extends Controller
|
||||
{
|
||||
protected static $requirements;
|
||||
|
||||
public function index(Request $request)
|
||||
{
|
||||
$args = [
|
||||
'requirements' => self::getRequirementsList()
|
||||
];
|
||||
|
||||
return view('config.requirements', $args);
|
||||
}
|
||||
|
||||
public static function getRequirementsList($file = null)
|
||||
{
|
||||
$requirements = self::getRequirements($file);
|
||||
|
||||
$list = [
|
||||
tr('Apache') => $requirements['apache'],
|
||||
tr('PHP (_VERSION_)', [
|
||||
'_VERSION_' => phpversion(),
|
||||
]) => $requirements['php'],
|
||||
tr('Percorsi di servizio') => $requirements['paths'],
|
||||
];
|
||||
|
||||
return $list;
|
||||
}
|
||||
|
||||
public static function getRequirements($file = null)
|
||||
{
|
||||
if (empty($file) && isset(self::$requirements)) {
|
||||
return self::$requirements;
|
||||
}
|
||||
|
||||
$list = config('requirements');
|
||||
if (!empty($file)) {
|
||||
$file = realpath($file);
|
||||
if (string_starts_with($file)) {
|
||||
$list = include $file;
|
||||
}
|
||||
}
|
||||
|
||||
// Apache
|
||||
if (function_exists('apache_get_modules')) {
|
||||
$available_modules = apache_get_modules();
|
||||
}
|
||||
|
||||
$apache = $list['apache'];
|
||||
foreach ($apache as $name => $values) {
|
||||
$status = isset($available_modules) ? in_array($name, $available_modules) : false;
|
||||
$status = isset($values['server']) && isset($_SERVER[$values['server']]) ? $_SERVER[$values['server']] == 'On' : $status;
|
||||
|
||||
$apache[$name]['description'] = tr('Il modulo Apache _MODULE_ deve essere abilitato', [
|
||||
'_MODULE_' => '<i>'.$name.'</i>',
|
||||
]);
|
||||
$apache[$name]['status'] = $status;
|
||||
}
|
||||
|
||||
// PHP
|
||||
$php = $list['php'];
|
||||
foreach ($php as $name => $values) {
|
||||
if ($values['type'] == 'ext') {
|
||||
$description = !empty($values['required']) ? tr("L'estensione PHP _EXT_ deve essere abilitata", [
|
||||
'_EXT_' => '<i>'.$name.'</i>',
|
||||
]) : tr("E' consigliata l'abilitazione dell'estensione PHP _EXT_", [
|
||||
'_EXT_' => '<i>'.$name.'</i>',
|
||||
]);
|
||||
|
||||
$status = extension_loaded($name);
|
||||
} else {
|
||||
$suggested = str_replace(['>', '<'], '', $values['suggested']);
|
||||
$value = ini_get($name);
|
||||
|
||||
$description = tr("Valore consigliato per l'impostazione PHP: _VALUE_ (Valore attuale: _INI_)", [
|
||||
'_VALUE_' => $suggested,
|
||||
'_INI_' => ini_get($name),
|
||||
]);
|
||||
|
||||
$suggested = strpos($suggested, 'B') !== false ? $suggested : $suggested.'B';
|
||||
$value = strpos($value, 'B') !== false ? $value : $value.'B';
|
||||
|
||||
$ini = FileSystem::convertBytes($value);
|
||||
$real = FileSystem::convertBytes($suggested);
|
||||
|
||||
if (starts_with($values['suggested'], '>')) {
|
||||
$status = $ini >= substr($real, 1);
|
||||
} elseif (starts_with($values['suggested'], '<')) {
|
||||
$status = $ini <= substr($real, 1);
|
||||
} else {
|
||||
$status = ($real == $ini);
|
||||
}
|
||||
|
||||
$php[$name]['value'] = $value;
|
||||
|
||||
if (is_bool($suggested)) {
|
||||
$suggested = !empty($suggested) ? 'On' : 'Off';
|
||||
}
|
||||
}
|
||||
|
||||
$php[$name]['description'] = $description;
|
||||
$php[$name]['status'] = $status;
|
||||
}
|
||||
|
||||
// Percorsi di servizio
|
||||
$paths = [];
|
||||
foreach ($list['directories'] as $name) {
|
||||
$status = is_writable(base_path().DIRECTORY_SEPARATOR.$name);
|
||||
$description = tr('Il percorso _PATH_ deve risultare accessibile da parte del gestionale (permessi di lettura e scrittura)', [
|
||||
'_PATH_' => '<i>'.$name.'</i>',
|
||||
]);
|
||||
|
||||
$paths[$name]['description'] = $description;
|
||||
$paths[$name]['status'] = $status;
|
||||
}
|
||||
|
||||
$result = [
|
||||
'apache' => $apache,
|
||||
'php' => $php,
|
||||
'paths' => $paths,
|
||||
];
|
||||
|
||||
if (empty($file)) {
|
||||
self::$requirements = $result;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
public static function isSatisfied()
|
||||
{
|
||||
$general_status = true;
|
||||
|
||||
$requirements = self::getRequirements();
|
||||
foreach ($requirements as $key => $values) {
|
||||
foreach ($values as $value) {
|
||||
$general_status &= !empty($value['required']) ? $value['status'] : true;
|
||||
}
|
||||
}
|
||||
|
||||
return $general_status;
|
||||
}
|
||||
}
|
|
@ -4,6 +4,7 @@ namespace App\Http\Middleware;
|
|||
|
||||
use App\Http\Controllers\ConfigurationController;
|
||||
use App\Http\Controllers\InitializationController;
|
||||
use App\Http\Controllers\RequirementsController;
|
||||
use Closure;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
|
@ -21,6 +22,12 @@ class EnsureConfiguration
|
|||
return $next($request);
|
||||
}
|
||||
|
||||
// Test sui requisiti del gestionale
|
||||
$result = $this->checkRequirements($route);
|
||||
if ($result !== null) {
|
||||
return $result;
|
||||
}
|
||||
|
||||
// Test della connessione al database
|
||||
$result = $this->checkConfiguration($route);
|
||||
if ($result !== null) {
|
||||
|
@ -42,9 +49,28 @@ class EnsureConfiguration
|
|||
return $next($request);
|
||||
}
|
||||
|
||||
protected function checkRequirements($route)
|
||||
{
|
||||
$configuration_paths = ['requirements'];
|
||||
$requirements_satisfied = RequirementsController::isSatisfied();
|
||||
|
||||
if ($requirements_satisfied) {
|
||||
// Redirect nel caso in cui i requisiti siano soddisfatti
|
||||
if (in_array($route->getName(), $configuration_paths)) {
|
||||
return redirect(route('configuration'));
|
||||
}
|
||||
} else {
|
||||
// Redirect per requisiti incompleti
|
||||
if (!in_array($route->getName(), $configuration_paths)) {
|
||||
return redirect(route('requirements'));
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
protected function checkConfiguration($route)
|
||||
{
|
||||
// Test della connessione al database
|
||||
$configuration_paths = ['configuration', 'configuration-save', 'configuration-test'];
|
||||
$configuration_completed = ConfigurationController::isConfigured();
|
||||
|
||||
|
|
|
@ -11,8 +11,6 @@ class Language
|
|||
/**
|
||||
* Handle an incoming request.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param \Closure $next
|
||||
* @return mixed
|
||||
*/
|
||||
public function handle(Request $request, Closure $next)
|
||||
|
|
|
@ -12,7 +12,7 @@ class Input extends Component
|
|||
/**
|
||||
* Create a new component instance.
|
||||
*
|
||||
* @param string $name
|
||||
* @param string $name
|
||||
* @param string|null $id
|
||||
* @param string|null $value
|
||||
* @param bool|string $required
|
||||
|
|
|
@ -10,13 +10,13 @@ class Number extends Input
|
|||
/**
|
||||
* Create a new component instance.
|
||||
*
|
||||
* @param string $name
|
||||
* @param string $name
|
||||
* @param string|null $id
|
||||
* @param string|null $value
|
||||
* @param bool|string $required
|
||||
* @param string|null $label
|
||||
* @param string|null $placeholder
|
||||
* @param null $minValue
|
||||
* @param null $minValue
|
||||
*/
|
||||
public function __construct(
|
||||
$name,
|
||||
|
@ -44,7 +44,7 @@ class Number extends Input
|
|||
$decimals = setting('Cifre decimali per quantità');
|
||||
|
||||
// Se non è previsto un valore minimo, lo imposta a 1
|
||||
$minValue = isset($minValue) ? $minValue : '0.'.str_repeat('0', $decimals - 1).'1';
|
||||
$minValue = isset($minValue) ? $minValue : '0.'.str_repeat('0', $decimals - 1).'1';
|
||||
|
||||
$this->set([
|
||||
'decimals' => $decimals,
|
||||
|
|
|
@ -13,7 +13,6 @@ class Select extends Component
|
|||
*/
|
||||
public function __construct()
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -2,8 +2,6 @@
|
|||
|
||||
/**
|
||||
* Gets the current locale.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function locale(): string
|
||||
{
|
||||
|
@ -12,13 +10,11 @@ function locale(): string
|
|||
|
||||
/**
|
||||
* Get the language portion of the locale.
|
||||
* (ex. en_GB returns en)
|
||||
*
|
||||
* @return string
|
||||
* (ex. en_GB returns en).
|
||||
*/
|
||||
function localeLanguage(): string
|
||||
{
|
||||
$locale = locale();
|
||||
|
||||
return substr($locale, 0, strpos($locale, "_"));
|
||||
return substr($locale, 0, strpos($locale, '_'));
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
"type": "project",
|
||||
"require": {
|
||||
"php": "^7.3|^8.0",
|
||||
"ext-apache": "*",
|
||||
"ext-curl": "*",
|
||||
"ext-dom": "*",
|
||||
"ext-fileinfo": "*",
|
||||
|
@ -117,6 +118,7 @@
|
|||
"Plugins\\DettagliArticolo\\": ["legacy/plugins/dettagli_articolo/custom/src/", "legacy/plugins/dettagli_articolo/src/"],
|
||||
|
||||
"App\\": "app/",
|
||||
"Modules\\": "modules/",
|
||||
"Database\\Factories\\": "database/factories/",
|
||||
"Database\\Seeders\\": "database/seeders/"
|
||||
},
|
||||
|
|
|
@ -0,0 +1,61 @@
|
|||
<?php
|
||||
|
||||
return [
|
||||
'php' => [
|
||||
'zip' => [
|
||||
'type' => 'ext',
|
||||
'required' => 1,
|
||||
],
|
||||
'mbstring' => [
|
||||
'type' => 'ext',
|
||||
'required' => 1,
|
||||
],
|
||||
'pdo_mysql' => [
|
||||
'type' => 'ext',
|
||||
'required' => 1,
|
||||
],
|
||||
'dom' => [
|
||||
'type' => 'ext',
|
||||
'required' => 1,
|
||||
],
|
||||
'xsl' => [
|
||||
'type' => 'ext',
|
||||
'required' => 1,
|
||||
],
|
||||
'openssl' => [
|
||||
'type' => 'ext',
|
||||
'required' => 1,
|
||||
],
|
||||
'intl' => [
|
||||
'type' => 'ext',
|
||||
'required' => 1,
|
||||
],
|
||||
'curl' => [
|
||||
'type' => 'ext',
|
||||
'required' => 1,
|
||||
],
|
||||
'soap' => [
|
||||
'type' => 'ext',
|
||||
'required' => 1,
|
||||
],
|
||||
|
||||
'upload_max_filesize' => [
|
||||
'type' => 'value',
|
||||
'suggested' => '>32M',
|
||||
],
|
||||
'post_max_size' => [
|
||||
'type' => 'value',
|
||||
'suggested' => '>32M',
|
||||
],
|
||||
],
|
||||
'apache' => [
|
||||
'mod_rewrite' => [
|
||||
'server' => 'HTTP_MOD_REWRITE',
|
||||
],
|
||||
],
|
||||
'directories' => [
|
||||
'backup',
|
||||
'files',
|
||||
'logs',
|
||||
],
|
||||
];
|
2
legacy
2
legacy
|
@ -1 +1 @@
|
|||
Subproject commit 01a293d3650fcf96d8617fab2b14a0c193bca6d9
|
||||
Subproject commit 5730434cc63c67880049f6adb116791dc8af8a5b
|
|
@ -0,0 +1,5 @@
|
|||
<?php
|
||||
|
||||
return [
|
||||
'name' => 'Aggiornamenti'
|
||||
];
|
|
@ -0,0 +1,21 @@
|
|||
<?php
|
||||
|
||||
namespace Modules\Aggiornamenti\Database\Seeders;
|
||||
|
||||
use Illuminate\Database\Seeder;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class AggiornamentiDatabaseSeeder extends Seeder
|
||||
{
|
||||
/**
|
||||
* Run the database seeds.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function run()
|
||||
{
|
||||
Model::unguard();
|
||||
|
||||
// $this->call("OthersTableSeeder");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,466 @@
|
|||
<?php
|
||||
|
||||
namespace Modules\Aggiornamenti\Http;
|
||||
|
||||
use Models\Cache;
|
||||
use Models\Group;
|
||||
use App\Http\Controllers\RequirementsController as Requirements;
|
||||
use GuzzleHttp\Client;
|
||||
use InvalidArgumentException;
|
||||
use Models\Module;
|
||||
use Parsedown;
|
||||
use Symfony\Component\Finder\Finder;
|
||||
use Update;
|
||||
use Util\Ini;
|
||||
use Util\Zip;
|
||||
|
||||
class Aggiornamento
|
||||
{
|
||||
protected static $client = null;
|
||||
|
||||
protected $directory = null;
|
||||
protected $components = null;
|
||||
|
||||
protected $groups = null;
|
||||
|
||||
/**
|
||||
* Crea l'istanza dedicata all'aggiornamento presente nella cartella indicata.
|
||||
*
|
||||
* @param string $directory
|
||||
*
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
public function __construct($directory = null)
|
||||
{
|
||||
$this->directory = $directory ?: Zip::getExtractionDirectory();
|
||||
|
||||
if (!$this->isCoreUpdate() && empty($this->componentUpdates())) {
|
||||
throw new InvalidArgumentException();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Pulisce la cartella di estrazione.
|
||||
*/
|
||||
public function delete()
|
||||
{
|
||||
delete($this->directory);
|
||||
}
|
||||
|
||||
/**
|
||||
* Restituisce il percorso impostato per l'aggiornamento corrente.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getDirectory()
|
||||
{
|
||||
return $this->directory;
|
||||
}
|
||||
|
||||
/**
|
||||
* Controlla se l'aggiornamento è di tipo globale.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isCoreUpdate()
|
||||
{
|
||||
return file_exists($this->directory.'/VERSION');
|
||||
}
|
||||
|
||||
public function getChangelog()
|
||||
{
|
||||
if ($this->isCoreUpdate()) {
|
||||
$changelog = self::readChangelog($this->getDirectory(), Update::getVersion());
|
||||
} else {
|
||||
$changelogs = [];
|
||||
$elements = $this->componentUpdates();
|
||||
|
||||
$list = array_merge($elements['modules'], $elements['plugins']);
|
||||
foreach ($list as $element) {
|
||||
$changelog = self::readChangelog($element['path'], $element['version']);
|
||||
|
||||
if (!empty($changelog)) {
|
||||
$changelogs[] = '
|
||||
<h4 class="text-center">'.$element['info']['name'].'<h4>
|
||||
'.$changelog;
|
||||
}
|
||||
}
|
||||
|
||||
$changelog = implode('<hr>', $changelogs);
|
||||
}
|
||||
|
||||
return $changelog;
|
||||
}
|
||||
|
||||
public function getRequirements()
|
||||
{
|
||||
$file = $this->directory.'/config/requirements.php';
|
||||
$result = Requirements::getRequirementsList($file);
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function getVersion()
|
||||
{
|
||||
return Update::getFile($this->getDirectory().'/VERSION');
|
||||
}
|
||||
|
||||
/**
|
||||
* Individua i componenti indipendenti che compongono l'aggiornamento.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function componentUpdates()
|
||||
{
|
||||
if (!isset($this->components)) {
|
||||
$finder = Finder::create()
|
||||
->files()
|
||||
->ignoreDotFiles(true)
|
||||
->ignoreVCS(true)
|
||||
->in($this->directory);
|
||||
|
||||
$files = $finder->name('MODULE')->name('PLUGIN');
|
||||
|
||||
$results = [];
|
||||
foreach ($files as $file) {
|
||||
$is_module = basename($file->getRealPath()) == 'MODULE';
|
||||
$is_plugin = basename($file->getRealPath()) == 'PLUGIN';
|
||||
|
||||
$info = Ini::readFile($file->getRealPath());
|
||||
$installed = module($info['name']);
|
||||
if ($is_module) {
|
||||
$type = 'modules';
|
||||
} elseif ($is_plugin) {
|
||||
$type = 'plugins';
|
||||
}
|
||||
|
||||
if (!isset($results[$type])) {
|
||||
$results[$type] = [];
|
||||
}
|
||||
$results[$type][] = [
|
||||
'path' => dirname($file->getRealPath()),
|
||||
'config' => $file->getRealPath(),
|
||||
'is_installed' => !empty($installed),
|
||||
'current_version' => !empty($installed) ? $installed->version : null,
|
||||
'info' => $info,
|
||||
];
|
||||
}
|
||||
|
||||
$this->components = $results;
|
||||
}
|
||||
|
||||
return $this->components;
|
||||
}
|
||||
|
||||
/**
|
||||
* Effettua l'aggiornamento.
|
||||
*/
|
||||
public function execute()
|
||||
{
|
||||
if ($this->isCoreUpdate()) {
|
||||
$this->executeCore();
|
||||
} else {
|
||||
$components = $this->componentUpdates();
|
||||
|
||||
foreach ((array) $components['modules'] as $module) {
|
||||
$this->executeModule($module);
|
||||
}
|
||||
|
||||
foreach ((array) $components['plugins'] as $plugin) {
|
||||
$this->executeModule($plugin);
|
||||
}
|
||||
}
|
||||
|
||||
$this->delete();
|
||||
}
|
||||
|
||||
/**
|
||||
* Completa l'aggiornamento globale secondo la procedura apposita.
|
||||
*/
|
||||
public function executeCore()
|
||||
{
|
||||
// Salva il file di configurazione
|
||||
$config = file_get_contents(DOCROOT.'/config.inc.php');
|
||||
|
||||
// Copia i file dalla cartella temporanea alla root
|
||||
copyr($this->directory, DOCROOT);
|
||||
|
||||
// Ripristina il file di configurazione dell'installazione
|
||||
file_put_contents(DOCROOT.'/config.inc.php', $config);
|
||||
}
|
||||
|
||||
/**
|
||||
* Completa l'aggiornamento con le informazioni specifiche per i moduli.
|
||||
*
|
||||
* @param array $module
|
||||
*/
|
||||
public function executeModule($module)
|
||||
{
|
||||
// Informazioni dal file di configurazione
|
||||
$info = $module['info'];
|
||||
|
||||
// Informazioni aggiuntive per il database
|
||||
$insert = [
|
||||
'parent' => module($info['parent']),
|
||||
'icon' => $info['icon'],
|
||||
];
|
||||
|
||||
$id = $this->executeComponent($module['path'], 'modules', 'zz_modules', $insert, $info, $module['is_installed']);
|
||||
|
||||
if (!empty($id)) {
|
||||
// Fix per i permessi di amministratore
|
||||
$element = Module::find($id);
|
||||
|
||||
$element->groups()->syncWithoutDetaching($this->groups());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Instanzia un aggiornamento sulla base di uno zip indicato.
|
||||
* Controlla inoltre che l'aggiornamento sia fattibile.
|
||||
*
|
||||
* @param string $file
|
||||
*
|
||||
* @throws DowngradeException
|
||||
* @throws InvalidArgumentException
|
||||
*
|
||||
* @return static
|
||||
*/
|
||||
public static function make($file)
|
||||
{
|
||||
$extraction_dir = Zip::extract($file);
|
||||
|
||||
$update = new static($extraction_dir);
|
||||
|
||||
if ($update->isCoreUpdate()) {
|
||||
$version = Update::getFile($update->getDirectory().'/VERSION');
|
||||
$current = Update::getVersion();
|
||||
|
||||
if (version_compare($current, $version) >= 0) {
|
||||
$update->delete();
|
||||
|
||||
throw new DowngradeException();
|
||||
}
|
||||
} else {
|
||||
$components = $update->componentUpdates();
|
||||
|
||||
foreach ((array) $components['modules'] as $module) {
|
||||
if (version_compare($module['current_version'], $module['info']['version']) >= 0) {
|
||||
delete($module['path']);
|
||||
}
|
||||
}
|
||||
|
||||
foreach ((array) $components['plugins'] as $plugin) {
|
||||
if (version_compare($plugin['current_version'], $plugin['info']['version']) >= 0) {
|
||||
delete($plugin['path']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Instanzia nuovamente l'oggetto
|
||||
return new static($extraction_dir);
|
||||
}
|
||||
|
||||
/**
|
||||
* Controlla se è disponibile un aggiornamento nella repository GitHub.
|
||||
*
|
||||
* @return string|bool
|
||||
*/
|
||||
public static function isAvailable()
|
||||
{
|
||||
$release = self::getLastRelease();
|
||||
|
||||
$version = ltrim($release['tag_name'], 'v');
|
||||
$current = Update::getVersion();
|
||||
|
||||
$result = false;
|
||||
if (version_compare($current, $version) < 0) {
|
||||
$result = $version.($release['prerelease'] ? ' (beta)' : '');
|
||||
}
|
||||
|
||||
// Aggiornamento cache dedicata
|
||||
Cache::pool('Ultima versione di OpenSTAManager disponibile')->set($result);
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Scarica la release più recente (se presente).
|
||||
*
|
||||
* @return static
|
||||
*/
|
||||
public static function download()
|
||||
{
|
||||
if (self::isAvailable() === false) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$directory = Zip::getExtractionDirectory();
|
||||
$file = $directory.'/release.zip';
|
||||
directory($directory);
|
||||
|
||||
$release = self::getLastRelease();
|
||||
self::getClient()->request('GET', $release['assets'][0]['browser_download_url'], ['sink' => $file]);
|
||||
|
||||
$update = self::make($file);
|
||||
delete($file);
|
||||
|
||||
return $update;
|
||||
}
|
||||
|
||||
/**
|
||||
* Restituisce i contenuti JSON dell'API del progetto.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function checkFiles()
|
||||
{
|
||||
$date = date('Y-m-d', filemtime(DOCROOT.'/core.php'));
|
||||
|
||||
// Individuazione dei file tramite data di modifica
|
||||
$files = Finder::create()
|
||||
->date('<= '.$date)
|
||||
->sortByName()
|
||||
->in(DOCROOT)
|
||||
->exclude([
|
||||
'node_modules',
|
||||
'tests',
|
||||
'tmp',
|
||||
'vendor',
|
||||
])
|
||||
->name('*.php')
|
||||
->notPath('*custom*')
|
||||
->files();
|
||||
|
||||
return iterator_to_array($files);
|
||||
}
|
||||
|
||||
/**
|
||||
* Restituisce il changelog presente nel percorso indicato a partire dalla versione specificata.
|
||||
*
|
||||
* @param string $path
|
||||
* @param string $version
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected static function readChangelog($path, $version = null)
|
||||
{
|
||||
$result = file_get_contents($path.'/CHANGELOG.md');
|
||||
|
||||
$start = strpos($result, '## ');
|
||||
$result = substr($result, $start);
|
||||
if (!empty($version)) {
|
||||
$last = strpos($result, '## '.$version.' ');
|
||||
|
||||
if ($last !== false) {
|
||||
$result = substr($result, 0, $last);
|
||||
}
|
||||
}
|
||||
|
||||
$result = Parsedown::instance()->text($result);
|
||||
$result = str_replace(['h4>', 'h3>', 'h2>'], ['p>', 'b>', 'h4>'], $result);
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Completa l'aggiornamento del singolo componente come previsto dai parametri indicati.
|
||||
*
|
||||
* @param string $directory Percorso di copia dei contenuti
|
||||
* @param string $table Tabella interessata dall'aggiornamento
|
||||
* @param array $insert Informazioni per la registrazione
|
||||
* @param array $info Contenuti della configurazione
|
||||
* @param bool $is_installed
|
||||
*
|
||||
* @return int|null
|
||||
*/
|
||||
protected function executeComponent($path, $directory, $table, $insert, $info, $is_installed = false)
|
||||
{
|
||||
// Copia dei file nella cartella relativa
|
||||
copyr($path, DOCROOT.'/'.$directory.'/'.$info['directory']);
|
||||
|
||||
// Eventuale registrazione nel database
|
||||
if (empty($is_installed)) {
|
||||
$dbo = database();
|
||||
|
||||
$dbo->insert($table, array_merge($insert, [
|
||||
'name' => $info['name'],
|
||||
'title' => !empty($info['title']) ? $info['title'] : $info['name'],
|
||||
'directory' => $info['directory'],
|
||||
'options' => $info['options'],
|
||||
'version' => $info['version'],
|
||||
'compatibility' => $info['compatibility'],
|
||||
'order' => 100,
|
||||
'default' => 0,
|
||||
'enabled' => 1,
|
||||
]));
|
||||
|
||||
return $dbo->lastInsertedID();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Resituisce i permessi di default da impostare all'installazione del componente.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function groups()
|
||||
{
|
||||
if (!isset($this->groups)) {
|
||||
$groups = Group::where('nome', 'Amministratori')->get();
|
||||
|
||||
$result = [];
|
||||
foreach ($groups as $group) {
|
||||
$result[$group->id] = [
|
||||
'permission_level' => 'rw',
|
||||
];
|
||||
}
|
||||
|
||||
$this->groups = $result;
|
||||
}
|
||||
|
||||
return $this->groups;
|
||||
}
|
||||
|
||||
/**
|
||||
* Restituisce l'oggetto per la connessione all'API del progetto.
|
||||
*
|
||||
* @return Client
|
||||
*/
|
||||
protected static function getClient()
|
||||
{
|
||||
if (!isset(self::$client)) {
|
||||
self::$client = new Client([
|
||||
'base_uri' => 'https://api.github.com/repos/devcode-it/openstamanager/',
|
||||
'verify' => false,
|
||||
]);
|
||||
}
|
||||
|
||||
return self::$client;
|
||||
}
|
||||
|
||||
/**
|
||||
* Restituisce i contenuti JSON dell'API del progetto.
|
||||
*
|
||||
* @return array
|
||||
* @throws \GuzzleHttp\Exception\GuzzleException
|
||||
*/
|
||||
protected static function getLastRelease()
|
||||
{
|
||||
$response = self::getClient()->request('GET', 'releases');
|
||||
$body = $response->getBody();
|
||||
|
||||
// Impostazione per l'utilizzo o meno di versioni non stabili
|
||||
$prerelease = intval(setting('Abilita canale pre-release per aggiornamenti'));
|
||||
|
||||
// Ricerca dell'ultima release del tipi specificato
|
||||
$releases = json_decode($body, true) ?: [];
|
||||
foreach ($releases as $release) {
|
||||
if ($release['prerelease'] == $prerelease) {
|
||||
return $release;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,249 @@
|
|||
<?php
|
||||
|
||||
namespace Modules\Aggiornamenti\Http\Controllers;
|
||||
|
||||
use App\Http\Controllers\RequirementsController;
|
||||
use Illuminate\Contracts\Support\Renderable;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Routing\Controller;
|
||||
use InvalidArgumentException;
|
||||
use Modules\Aggiornamenti\Http\Aggiornamento;
|
||||
use Modules\Aggiornamenti\Http\DowngradeException;
|
||||
|
||||
class AggiornamentiController extends Controller
|
||||
{
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
* @return Renderable
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
try {
|
||||
$update = new Aggiornamento();
|
||||
|
||||
$args = [
|
||||
'update' => $update,
|
||||
'update_version' => $update->getVersion(),
|
||||
'update_requirements' => $update->getRequirements(),
|
||||
];
|
||||
|
||||
return view('aggiornamenti::update', $args);
|
||||
} catch (InvalidArgumentException $e) {
|
||||
}
|
||||
|
||||
$custom = $this->customComponents();
|
||||
$tables = $this->customTables();
|
||||
|
||||
// Aggiornamenti
|
||||
$alerts = [];
|
||||
|
||||
if (!extension_loaded('zip')) {
|
||||
$alerts[tr('Estensione ZIP')] = tr('da abilitare');
|
||||
}
|
||||
|
||||
$upload_max_filesize = ini_get('upload_max_filesize');
|
||||
$upload_max_filesize = str_replace(['k', 'M'], ['000', '000000'], $upload_max_filesize);
|
||||
// Dimensione minima: 32MB
|
||||
if ($upload_max_filesize < 32000000) {
|
||||
$alerts['upload_max_filesize'] = '32MB';
|
||||
}
|
||||
|
||||
$post_max_size = ini_get('post_max_size');
|
||||
$post_max_size = str_replace(['k', 'M'], ['000', '000000'], $post_max_size);
|
||||
// Dimensione minima: 32MB
|
||||
if ($post_max_size < 32000000) {
|
||||
$alerts['post_max_size'] = '32MB';
|
||||
}
|
||||
|
||||
$args = [
|
||||
'module' => module('Aggiornamenti'),
|
||||
'custom' => $custom,
|
||||
'tables' => $tables,
|
||||
'alerts' => $alerts,
|
||||
'enable_updates' => setting('Attiva aggiornamenti'),
|
||||
'requirements' => RequirementsController::getRequirementsList(),
|
||||
];
|
||||
|
||||
return view('aggiornamenti::index', $args);
|
||||
}
|
||||
|
||||
/**
|
||||
* Controlla se il database presenta alcune sezioni personalizzate.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function customStructure()
|
||||
{
|
||||
$results = [];
|
||||
|
||||
$dirs = [
|
||||
'modules',
|
||||
'templates',
|
||||
'plugins',
|
||||
];
|
||||
|
||||
// Controlli di personalizzazione fisica
|
||||
foreach ($dirs as $dir) {
|
||||
$files = glob(base_dir().'/'.$dir.'/*/custom/*.{php,html}', GLOB_BRACE);
|
||||
$recursive_files = glob(base_dir().'/'.$dir.'/*/custom/**/*.{php,html}', GLOB_BRACE);
|
||||
|
||||
$files = array_merge($files, $recursive_files);
|
||||
|
||||
foreach ($files as $file) {
|
||||
$file = str_replace(base_dir().'/', '', $file);
|
||||
$result = explode('/custom/', $file)[0];
|
||||
|
||||
if (!in_array($result, $results)) {
|
||||
$results[] = $result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Gestione cartella include
|
||||
$files = glob(base_dir().'/include/custom/*.{php,html}', GLOB_BRACE);
|
||||
$recursive_files = glob(base_dir().'/include/custom/**/*.{php,html}', GLOB_BRACE);
|
||||
|
||||
$files = array_merge($files, $recursive_files);
|
||||
|
||||
foreach ($files as $file) {
|
||||
$file = str_replace(base_dir().'/', '', $file);
|
||||
$result = explode('/custom/', $file)[0];
|
||||
|
||||
if (!in_array($result, $results)) {
|
||||
$results[] = $result;
|
||||
}
|
||||
}
|
||||
|
||||
return $results;
|
||||
}
|
||||
|
||||
/**
|
||||
* Controlla se il database presenta alcune sezioni personalizzate.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function customTables()
|
||||
{
|
||||
$tables = include base_dir().'/update/tables.php';
|
||||
|
||||
$names = [];
|
||||
foreach ($tables as $table) {
|
||||
$names[] = prepare($table);
|
||||
}
|
||||
|
||||
$database = database();
|
||||
|
||||
$results = $database->fetchArray('SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = '.prepare($database->getDatabaseName()).' AND TABLE_NAME NOT IN ('.implode(',', $names).") AND TABLE_NAME != 'updates'");
|
||||
|
||||
return array_column($results, 'TABLE_NAME');
|
||||
}
|
||||
|
||||
/**
|
||||
* Controlla se il database presenta alcune sezioni personalizzate.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function customDatabase()
|
||||
{
|
||||
$database = database();
|
||||
$modules = $database->fetchArray("SELECT name, CONCAT('modules/', directory) AS directory FROM zz_modules WHERE options2 != ''");
|
||||
$plugins = $database->fetchArray("SELECT name, CONCAT('plugins/', directory) AS directory FROM zz_plugins WHERE options2 != ''");
|
||||
|
||||
$results = array_merge($modules, $plugins);
|
||||
|
||||
return $results;
|
||||
}
|
||||
|
||||
protected function customComponents()
|
||||
{
|
||||
$database_check = $this->customDatabase();
|
||||
$structure_check = $this->customStructure();
|
||||
|
||||
$list = [];
|
||||
foreach ($database_check as $element) {
|
||||
$pos = array_search($element['directory'], $structure_check);
|
||||
|
||||
$list[] = [
|
||||
'path' => $element['directory'],
|
||||
'database' => true,
|
||||
'directory' => $pos !== false,
|
||||
];
|
||||
|
||||
if ($pos !== false) {
|
||||
unset($structure_check[$pos]);
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($structure_check as $element) {
|
||||
$list[] = [
|
||||
'path' => $element,
|
||||
'database' => false,
|
||||
'directory' => true,
|
||||
];
|
||||
}
|
||||
|
||||
return $list;
|
||||
}
|
||||
|
||||
public function create(Request $request)
|
||||
{
|
||||
if (!setting('Attiva aggiornamenti')) {
|
||||
die(tr('Accesso negato'));
|
||||
}
|
||||
|
||||
try {
|
||||
$update = Aggiornamento::make($_FILES['blob']['tmp_name']);
|
||||
} catch (DowngradeException $e) {
|
||||
flash()->error(tr('Il pacchetto contiene una versione precedente del gestionale'));
|
||||
} catch (InvalidArgumentException $e) {
|
||||
flash()->error(tr('Il pacchetto contiene solo componenti già installate e aggiornate'));
|
||||
}
|
||||
}
|
||||
|
||||
public function check(Request $request)
|
||||
{
|
||||
$result = Aggiornamento::isAvailable();
|
||||
$result = $result === false ? 'none' : $result;
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function download(Request $request)
|
||||
{
|
||||
Aggiornamento::download();
|
||||
}
|
||||
|
||||
public function execute(Request $request)
|
||||
{
|
||||
try {
|
||||
$update = new Aggiornamento();
|
||||
|
||||
$update->execute();
|
||||
} catch (InvalidArgumentException $e) {
|
||||
}
|
||||
|
||||
$route = $this->router->urlFor('module', [
|
||||
'module_id' => $args['module_id'],
|
||||
]);
|
||||
$response = $response->withRedirect($route);
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
public function cancel(Request $request)
|
||||
{
|
||||
try {
|
||||
$update = new Aggiornamento();
|
||||
|
||||
$update->delete();
|
||||
} catch (InvalidArgumentException $e) {
|
||||
}
|
||||
|
||||
$route = $this->router->urlFor('module', [
|
||||
'module_id' => $args['module_id'],
|
||||
]);
|
||||
$response = $response->withRedirect($route);
|
||||
|
||||
return $response;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
<?php
|
||||
|
||||
namespace Modules\Aggiornamenti\Http\Controllers;
|
||||
|
||||
use App\Http\Controllers\RequirementsController;
|
||||
use Illuminate\Contracts\Support\Renderable;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Routing\Controller;
|
||||
use InvalidArgumentException;
|
||||
use Modules\Aggiornamenti\Http\Aggiornamento;
|
||||
|
||||
class ControlliAggiuntiviController extends Controller
|
||||
{
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
<?php
|
||||
|
||||
namespace Modules\Aggiornamenti\Http;
|
||||
|
||||
use InvalidArgumentException;
|
||||
|
||||
class DowngradeException extends InvalidArgumentException
|
||||
{
|
||||
}
|
|
@ -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 Modules\Aggiornamenti\Http;
|
||||
|
||||
use GuzzleHttp\Client;
|
||||
use Hooks\CachedManager;
|
||||
use Update;
|
||||
|
||||
/**
|
||||
* Hook dedicato all'individuazione di nuove versioni del gestionale, pubblicate sulla repository ufficiale di GitHub.
|
||||
*/
|
||||
class UpdateHook extends CachedManager
|
||||
{
|
||||
protected static $client = null;
|
||||
|
||||
public function getCacheName()
|
||||
{
|
||||
return 'Ultima versione di OpenSTAManager disponibile';
|
||||
}
|
||||
|
||||
public function cacheData()
|
||||
{
|
||||
return self::isAvailable();
|
||||
}
|
||||
|
||||
public function response()
|
||||
{
|
||||
$update = $this->getCache()->content;
|
||||
if ($update == Update::getVersion()) {
|
||||
$update = null;
|
||||
}
|
||||
|
||||
$module = module('Aggiornamenti');
|
||||
$link = base_url().'/controller.php?id_module='.$module->id;
|
||||
|
||||
$message = tr("E' disponibile la versione _VERSION_ del gestionale", [
|
||||
'_VERSION_' => $update,
|
||||
]);
|
||||
|
||||
return [
|
||||
'icon' => 'fa fa-download text-info',
|
||||
'link' => $link,
|
||||
'message' => $message,
|
||||
'show' => !empty($update),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Controlla se è disponibile un aggiornamento nella repository GitHub.
|
||||
*
|
||||
* @return array|bool
|
||||
*/
|
||||
public static function isAvailable()
|
||||
{
|
||||
$api = self::getAPI();
|
||||
|
||||
if (!$api['prerelease'] or setting('Abilita canale pre-release per aggiornamenti')) {
|
||||
$version[0] = ltrim($api['tag_name'], 'v');
|
||||
$version[1] = !empty($api['prerelease']) ? 'beta' : 'stabile';
|
||||
$current = Update::getVersion();
|
||||
|
||||
if (version_compare($current, $version[0]) < 0) {
|
||||
return $version;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Restituisce l'oggetto per la connessione all'API del progetto.
|
||||
*
|
||||
* @return Client
|
||||
*/
|
||||
protected static function getClient()
|
||||
{
|
||||
if (!isset(self::$client)) {
|
||||
self::$client = new Client([
|
||||
'base_uri' => 'https://api.github.com/repos/devcode-it/openstamanager/',
|
||||
'verify' => false,
|
||||
]);
|
||||
}
|
||||
|
||||
return self::$client;
|
||||
}
|
||||
|
||||
/**
|
||||
* Restituisce i contenuti JSON dell'API del progetto.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected static function getAPI()
|
||||
{
|
||||
$response = self::getClient()->request('GET', 'releases');
|
||||
$body = $response->getBody();
|
||||
|
||||
return json_decode($body, true)[0];
|
||||
}
|
||||
}
|
|
@ -0,0 +1,112 @@
|
|||
<?php
|
||||
|
||||
namespace Modules\Aggiornamenti\Providers;
|
||||
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
use Illuminate\Database\Eloquent\Factory;
|
||||
|
||||
class AggiornamentiServiceProvider extends ServiceProvider
|
||||
{
|
||||
/**
|
||||
* @var string $moduleName
|
||||
*/
|
||||
protected $moduleName = 'Aggiornamenti';
|
||||
|
||||
/**
|
||||
* @var string $moduleNameLower
|
||||
*/
|
||||
protected $moduleNameLower = 'aggiornamenti';
|
||||
|
||||
/**
|
||||
* Boot the application events.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function boot()
|
||||
{
|
||||
$this->registerTranslations();
|
||||
$this->registerConfig();
|
||||
$this->registerViews();
|
||||
$this->loadMigrationsFrom(module_path($this->moduleName, 'Database/Migrations'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Register the service provider.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function register()
|
||||
{
|
||||
$this->app->register(RouteServiceProvider::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register config.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function registerConfig()
|
||||
{
|
||||
$this->publishes([
|
||||
module_path($this->moduleName, 'Config/config.php') => config_path($this->moduleNameLower . '.php'),
|
||||
], 'config');
|
||||
$this->mergeConfigFrom(
|
||||
module_path($this->moduleName, 'Config/config.php'), $this->moduleNameLower
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register views.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function registerViews()
|
||||
{
|
||||
$viewPath = resource_path('views/modules/' . $this->moduleNameLower);
|
||||
|
||||
$sourcePath = module_path($this->moduleName, 'Resources/views');
|
||||
|
||||
$this->publishes([
|
||||
$sourcePath => $viewPath
|
||||
], ['views', $this->moduleNameLower . '-module-views']);
|
||||
|
||||
$this->loadViewsFrom(array_merge($this->getPublishableViewPaths(), [$sourcePath]), $this->moduleNameLower);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register translations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function registerTranslations()
|
||||
{
|
||||
$langPath = resource_path('lang/modules/' . $this->moduleNameLower);
|
||||
|
||||
if (is_dir($langPath)) {
|
||||
$this->loadTranslationsFrom($langPath, $this->moduleNameLower);
|
||||
} else {
|
||||
$this->loadTranslationsFrom(module_path($this->moduleName, 'Resources/lang'), $this->moduleNameLower);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the services provided by the provider.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function provides()
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
private function getPublishableViewPaths(): array
|
||||
{
|
||||
$paths = [];
|
||||
foreach (\Config::get('view.paths') as $path) {
|
||||
if (is_dir($path . '/modules/' . $this->moduleNameLower)) {
|
||||
$paths[] = $path . '/modules/' . $this->moduleNameLower;
|
||||
}
|
||||
}
|
||||
return $paths;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,69 @@
|
|||
<?php
|
||||
|
||||
namespace Modules\Aggiornamenti\Providers;
|
||||
|
||||
use Illuminate\Support\Facades\Route;
|
||||
use Illuminate\Foundation\Support\Providers\RouteServiceProvider as ServiceProvider;
|
||||
|
||||
class RouteServiceProvider extends ServiceProvider
|
||||
{
|
||||
/**
|
||||
* The module namespace to assume when generating URLs to actions.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $moduleNamespace = 'Modules\Aggiornamenti\Http\Controllers';
|
||||
|
||||
/**
|
||||
* Called before routes are registered.
|
||||
*
|
||||
* Register any model bindings or pattern based filters.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function boot()
|
||||
{
|
||||
parent::boot();
|
||||
}
|
||||
|
||||
/**
|
||||
* Define the routes for the application.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function map()
|
||||
{
|
||||
$this->mapApiRoutes();
|
||||
|
||||
$this->mapWebRoutes();
|
||||
}
|
||||
|
||||
/**
|
||||
* Define the "web" routes for the application.
|
||||
*
|
||||
* These routes all receive session state, CSRF protection, etc.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function mapWebRoutes()
|
||||
{
|
||||
Route::middleware('web')
|
||||
->namespace($this->moduleNamespace)
|
||||
->group(module_path('Aggiornamenti', '/Routes/web.php'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Define the "api" routes for the application.
|
||||
*
|
||||
* These routes are typically stateless.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function mapApiRoutes()
|
||||
{
|
||||
Route::prefix('api')
|
||||
->middleware('api')
|
||||
->namespace($this->moduleNamespace)
|
||||
->group(module_path('Aggiornamenti', '/Routes/api.php'));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,222 @@
|
|||
@extends('modules.base')
|
||||
|
||||
@section('module_content')
|
||||
@if(!empty($custom) or !empty($tables))
|
||||
<!-- Personalizzazioni di codice -->
|
||||
<div class="box box-outline box-warning">
|
||||
<div class="box-header with-border">
|
||||
<h3 class="box-title">
|
||||
<span class="tip" title="{{ tr('Elenco delle personalizzazioni rilevabili dal gestionale') }}.">
|
||||
<i class="fa fa-edit"></i> {{ tr('Personalizzazioni') }}
|
||||
</span>
|
||||
</h3>
|
||||
</div>
|
||||
<div class="box-body">
|
||||
|
||||
@if(!empty($custom))
|
||||
<table class="table table-hover table-striped">
|
||||
<tr>
|
||||
<th width="10%">{{ tr('Percorso') }}</th>
|
||||
<th width="15%">{{ tr('Cartella personalizzata') }}</th>
|
||||
<th width="15%">{{ tr('Database personalizzato') }}</th>
|
||||
</tr>
|
||||
|
||||
@foreach($custom as $element)
|
||||
<tr>
|
||||
<td>{{ $element['path'] }}</td>
|
||||
<td>{{ $element['directory'] ? tr('Si') : tr('No') }}</td>
|
||||
<td>{{ $element['database'] ? tr('Si') : tr('No') }}</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
</table>
|
||||
|
||||
<p><strong>{{ tr("Si sconsiglia l'aggiornamento senza il supporto dell'assistenza ufficiale") }}.</strong></p>
|
||||
@else
|
||||
<p>{{ tr('Non ci sono strutture personalizzate') }}.</p>
|
||||
@endif
|
||||
|
||||
@if(!empty($tables))
|
||||
<div class="alert alert-warning">
|
||||
<i class="fa fa-warning"></i>
|
||||
<b>{{ tr('Attenzione!') }}</b> {{ tr('Ci sono delle tabelle non previste nella versione standard del gestionale: _LIST_', [
|
||||
'_LIST_' => implode(', ', $tables),
|
||||
]) }}
|
||||
</div>
|
||||
@endif
|
||||
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
@if(!empty($alerts))
|
||||
<div class="alert alert-warning">
|
||||
<p>{{ tr('Devi modificare il seguenti parametri del file di configurazione PHP (_FILE_) per poter caricare gli aggiornamenti', ['_FILE_' => '<b>php.ini</b>']) }}:</p>
|
||||
<ul>
|
||||
@foreach($alerts as $key => $value)
|
||||
<li><b>{{ $key }}</b> = {{ $value }}</li>
|
||||
@endforeach
|
||||
</ul>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<script>
|
||||
function update() {
|
||||
if ($("#blob").val()) {
|
||||
swal({
|
||||
title: "{{ tr('Avviare la procedura?') }}",
|
||||
type: "warning",
|
||||
showCancelButton: true,
|
||||
confirmButtonText: "{{ tr('Sì') }}"
|
||||
}).then(function (result) {
|
||||
$("#update").submit();
|
||||
})
|
||||
} else {
|
||||
swal({
|
||||
title: "{{ tr('Selezionare un file!') }}",
|
||||
type: "error",
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
function search(button) {
|
||||
buttonLoading(button);
|
||||
|
||||
$.ajax({
|
||||
url: "{{ route('controllo-versione') }}",
|
||||
type: "post",
|
||||
success: function(data){
|
||||
$("#update-search").addClass("hidden");
|
||||
|
||||
if (data === "none" || !data) {
|
||||
$("#update-none").removeClass("hidden");
|
||||
} else {
|
||||
if (data.includes("beta")) {
|
||||
$("#beta-warning").removeClass("hidden");
|
||||
}
|
||||
|
||||
$("#update-version").text(data);
|
||||
$("#update-download").removeClass("hidden");
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function download(button) {
|
||||
buttonLoading(button);
|
||||
$("#main_loading").show();
|
||||
|
||||
$.ajax({
|
||||
url: "{{ route('scarica-aggiornamento') }}",
|
||||
type: "post",
|
||||
success: function(){
|
||||
window.location.reload();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function checksum(button) {
|
||||
openModal("{{ tr('Controllo dei file') }}", "{{ route('checksum') }}");
|
||||
}
|
||||
|
||||
function database(button) {
|
||||
openModal("{{ tr('Controllo del database') }}", "{{ route('database') }}");
|
||||
}
|
||||
|
||||
function controlli(button) {
|
||||
openModal("{{ tr('Controlli del gestionale') }}", "{{ route('controlli') }}");
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-4">
|
||||
<div class="box box-outline box-success">
|
||||
<div class="box-header with-border">
|
||||
<h3 class="box-title">
|
||||
{{ tr('Carica un aggiornamento') }} <span class="tip" title="{{ tr('Form di caricamento aggiornamenti del gestionale e innesti di moduli e plugin') }}."><i class="fa fa-question-circle-o"></i></span>
|
||||
</h3>
|
||||
</div>
|
||||
|
||||
<div class="box-body">
|
||||
<form action="" method="post" enctype="multipart/form-data" id="update">
|
||||
<input type="hidden" name="op" value="upload">
|
||||
<input type="hidden" name="backto" value="record-list">
|
||||
|
||||
{[ "type": "file", "name": "blob", "required": 1, "accept": ".zip" ]}
|
||||
|
||||
<button type="button" class="btn btn-primary float-right" onclick="update()">
|
||||
<i class="fa fa-upload"></i> {{ tr('Carica') }}
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-md-4">
|
||||
<div class="box box-warning">
|
||||
<div class="box-header with-border">
|
||||
<h3 class="box-title">
|
||||
{{ tr("Verifica l'integrità dell'intallazione") }} <span class="tip" title="{{ tr("Verifica l'integrità della tua installazione attraverso un controllo sui checksum dei file e sulla struttura del database") }}."><i class="fa fa-question-circle-o"></i></span>
|
||||
</h3>
|
||||
</div>
|
||||
<div class="box-body">
|
||||
<button type="button" class="btn btn-primary btn-block" onclick="checksum(this)">
|
||||
<i class="fa fa-list-alt"></i> {{ tr('Controlla file') }}
|
||||
</button>
|
||||
<button type="button" class="btn btn-info btn-block" onclick="database(this)">
|
||||
<i class="fa fa-database"></i> {{ tr('Controlla database') }}
|
||||
</button>
|
||||
<button type="button" class="btn btn-block" onclick="controlli(this)">
|
||||
<i class="fa fa-stethoscope"></i> {{ tr('Controlla gestionale') }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-md-4">
|
||||
<div class="box box-outline box-info">
|
||||
<div class="box-header with-border">
|
||||
<h3 class="box-title">
|
||||
{{ tr('Ricerca aggiornamenti') }} <span class="tip" title="{{ tr('Controllo automatico della presenza di aggiornamenti per il gestionale') }}."><i class="fa fa-question-circle-o"></i></span>
|
||||
</h3>
|
||||
</div>
|
||||
|
||||
<div class="box-body">
|
||||
@if(extension_loaded('curl'))
|
||||
<div id="update-search">
|
||||
<button type="button" class="btn btn-info btn-block" onclick="search(this)">
|
||||
<i class="fa fa-search"></i> {{ tr('Ricerca') }}
|
||||
</button>
|
||||
</div>
|
||||
@else
|
||||
<button type="button" class="btn btn-warning btn-block disabled" >
|
||||
<i class="fa fa-warning"></i> {{ tr('Estensione curl non supportata') }}.
|
||||
</button>
|
||||
@endif
|
||||
|
||||
<div id="update-download" class="hidden">
|
||||
<p>{{ tr("E' stato individuato un nuovo aggiornamento") }}: <b id="update-version"></b>.</p>
|
||||
<p id="beta-warning" class="hidden"><b>{{ tr('Attenzione: la versione individuata è in fase sperimentale, e pertanto può presentare diversi bug e malfunzionamenti') }}.</b></p>
|
||||
|
||||
<p>{!! tr('Scaricalo manualmente (_LINK_) oppure in automatico', ['_LINK_' => '<a href="https://github.com/devcode-it/openstamanager/releases">https://github.com/devcode-it/openstamanager/releases</a>']) !!}:</p>
|
||||
|
||||
<button type="button" class="btn btn-success btn-block" onclick="download(this)">
|
||||
<i class="fa fa-download"></i> {{ tr('Scarica') }}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div id="update-none" class="hidden">
|
||||
<p>{{ tr('Nessun aggiornamento presente') }}.</p>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<hr>
|
||||
<div id="requirements">
|
||||
<h3>{{ tr('Requisiti') }}</h3>
|
||||
|
||||
@include('config.requirements-list')
|
||||
</div>
|
||||
@endsection
|
|
@ -0,0 +1,137 @@
|
|||
{% extends "layouts/base.twig" %}
|
||||
|
||||
{% block body_class %}hold-transition login-page{% endblock %}
|
||||
{% block title %}{{ 'Aggiornamento'|trans }}{% endblock %}
|
||||
|
||||
{% block body %}
|
||||
<div class="card card-outline card-center-large card-warning">
|
||||
<div class="card-header">
|
||||
<a class="h5" data-toggle="tab" href="#info">{{ "Informazioni sull'aggiornamento"|trans }}</a>
|
||||
|
||||
<ul class="nav nav-tabs float-right" id="tabs" role="tablist">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" data-toggle="tab" href="#changelog">{{ 'Changelog'|trans }}</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="card-body tab-content">
|
||||
<div id="info" class="tab-pane fade in active">
|
||||
|
||||
{% if update.isCoreUpdate() %}
|
||||
<p>{{ "Il pacchetto selezionato contiene un aggiornamento dell'intero gestionale"|trans }}.</p>
|
||||
<p>{{ "Si consiglia vivamente di effettuare un backup dell'installazione prima di procedere"|trans }}.</p>
|
||||
|
||||
<button type="button" class="btn btn-primary float-right" onclick="backup()">
|
||||
<i class="fa fa-database"></i> {{ 'Crea backup'|trans }}
|
||||
</button>
|
||||
|
||||
<div class="clearfix"></div>
|
||||
<hr>
|
||||
|
||||
<h3 class="text-center">{{ 'OpenSTAManager versione _VERSION_'|trans({'_VERSION_': update.getVersion()}) }}</h3>
|
||||
|
||||
{% include 'config/list.twig' with {requirements: update.getRequirements()} only %}
|
||||
|
||||
{% else %}
|
||||
{% set elements = update.componentUpdates() %}
|
||||
|
||||
<div class="alert alert-warning">
|
||||
<i class="fa fa-warning"></i>
|
||||
<b>{{ 'Attenzione!'|trans }}</b> {{ 'Verranno aggiornate le sole componenti del pacchetto che non sono già installate e aggiornate'|trans }}.
|
||||
</div>
|
||||
|
||||
{% if elements.modules is not empty %}
|
||||
<p>{{ 'Il pacchetto selezionato comprende i seguenti moduli'|trans }}:</p>
|
||||
<ul class="list-group">
|
||||
|
||||
{% for element in elements.modules %}
|
||||
<li class="list-group-item">
|
||||
<span class="badge">{{ element['info']['version'] }}</span>
|
||||
|
||||
{% if element.is_installed %}
|
||||
<span class="badge">{{ 'Installato'|trans }}</span>';
|
||||
{% endif %}
|
||||
|
||||
{{ element['info']['name'] }}
|
||||
</li>
|
||||
{% endfor %}
|
||||
|
||||
</ul>
|
||||
{% endif %}
|
||||
|
||||
{% if elements.plugins is not empty %}
|
||||
<p>{{ 'Il pacchetto selezionato comprende i seguenti plugin'|trans }}:</p>
|
||||
<ul class="list-group">';
|
||||
|
||||
{% for element in elements.plugins %}
|
||||
<li class="list-group-item">
|
||||
<span class="badge">{{ element['info']['version'] }}</span>
|
||||
|
||||
{% if element.is_installed %}
|
||||
<span class="badge">{{ 'Installato'|trans }}</span>';
|
||||
{% endif %}
|
||||
|
||||
{{ element['info']['name'] }}
|
||||
</li>
|
||||
{% endfor %}
|
||||
|
||||
</ul>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
</div>
|
||||
|
||||
<div id="changelog" class="tab-pane fade">
|
||||
{% set changelog = update.getChangelog() %}
|
||||
|
||||
{% if changelog is not empty %}
|
||||
{{ changelog|raw }}
|
||||
{% else %}
|
||||
<p>{{ 'Nessuna changelog individuabile'|trans }}.</p>
|
||||
{% endif %}
|
||||
|
||||
</div>
|
||||
|
||||
<hr>
|
||||
|
||||
<form action="{{ action_link|replace({'|action|': 'cancel'}) }}" method="post" style="display:inline-block">
|
||||
<button type="submit" class="btn btn-warning">
|
||||
<i class="fa fa-arrow-left"></i> {{ 'Annulla'|trans }}
|
||||
</button>
|
||||
</form>
|
||||
|
||||
<form action="{{ action_link|replace({'|action|': 'execute'}) }}" method="post" class="float-right" style="display:inline-block">
|
||||
<button type="submit" class="btn btn-success">
|
||||
<i class="fa fa-arrow-right"></i> {{ 'Procedi'|trans }}
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
function backup(){
|
||||
swal({
|
||||
title: "{{ 'Nuovo backup'|trans }}",
|
||||
text: "{{ 'Sei sicuro di voler creare un nuovo backup?'|trans }}",
|
||||
type: "warning",
|
||||
showCancelButton: true,
|
||||
confirmButtonClass: "btn btn-lg btn-success",
|
||||
confirmButtonText: "{{ 'Crea'|trans }}",
|
||||
}).then(function(){
|
||||
$("#main_loading").show();
|
||||
|
||||
$.ajax({
|
||||
url: "{{ url_for('module', {'module_id': module('Backup').id}) }}",
|
||||
type: "post",
|
||||
data: {
|
||||
op: "backup",
|
||||
},
|
||||
success: function(data){
|
||||
$("#main_loading").fadeOut();
|
||||
}
|
||||
});
|
||||
}, function(){});
|
||||
}
|
||||
</script>
|
||||
{% endblock %}
|
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| API Routes
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Here is where you can register API routes for your application. These
|
||||
| routes are loaded by the RouteServiceProvider within a group which
|
||||
| is assigned the "api" middleware group. Enjoy building your API!
|
||||
|
|
||||
*/
|
||||
|
||||
Route::middleware('auth:api')->get('/aggiornamenti', function (Request $request) {
|
||||
return $request->user();
|
||||
});
|
|
@ -0,0 +1,35 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Route;
|
||||
use Modules\Aggiornamenti\Http\Controllers\AggiornamentiController;
|
||||
use Modules\Aggiornamenti\Http\Controllers\ControlliAggiuntiviController;
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Web Routes
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Here is where you can register web routes for your application. These
|
||||
| routes are loaded by the RouteServiceProvider within a group which
|
||||
| contains the "web" middleware group. Now create something great!
|
||||
|
|
||||
*/
|
||||
|
||||
Route::prefix('aggiornamenti')
|
||||
->group(function () {
|
||||
Route::get('', [AggiornamentiController::class, 'index']);
|
||||
|
||||
Route::post('controllo-versione', [AggiornamentiController::class, 'check'])
|
||||
->name('controllo-versione');
|
||||
|
||||
Route::post('scarica-aggiornamento', [AggiornamentiController::class, 'download'])
|
||||
->name('scarica-aggiornamento');
|
||||
|
||||
Route::get('checksum', [ControlliAggiuntiviController::class, 'checksum'])
|
||||
->name('checksum');
|
||||
Route::get('database', [ControlliAggiuntiviController::class, 'database'])
|
||||
->name('database');
|
||||
Route::get('controlli', [ControlliAggiuntiviController::class, 'controlli'])
|
||||
->name('controlli');
|
||||
});
|
|
@ -0,0 +1,24 @@
|
|||
{
|
||||
"name": "devcode-it/osm-aggiornamenti-module",
|
||||
"description": "",
|
||||
"authors": [{
|
||||
"name": "DevCode s.n.c.",
|
||||
"email": "info@openstamanager.com"
|
||||
}],
|
||||
"require": {
|
||||
"erusev/parsedown": "^1.7"
|
||||
},
|
||||
"extra": {
|
||||
"laravel": {
|
||||
"providers": [],
|
||||
"aliases": {
|
||||
|
||||
}
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Modules\\Aggiornamenti\\": ""
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
{
|
||||
"name": "Aggiornamenti",
|
||||
"alias": "aggiornamenti",
|
||||
"description": "",
|
||||
"keywords": [],
|
||||
"priority": 0,
|
||||
"providers": [
|
||||
"Modules\\Aggiornamenti\\Providers\\AggiornamentiServiceProvider"
|
||||
],
|
||||
"aliases": {},
|
||||
"files": [],
|
||||
"requires": []
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
{
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "npm run development",
|
||||
"development": "cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js",
|
||||
"watch": "cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --watch --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js",
|
||||
"watch-poll": "npm run watch -- --watch-poll",
|
||||
"hot": "cross-env NODE_ENV=development node_modules/webpack-dev-server/bin/webpack-dev-server.js --inline --hot --config=node_modules/laravel-mix/setup/webpack.config.js",
|
||||
"prod": "npm run production",
|
||||
"production": "cross-env NODE_ENV=production node_modules/webpack/bin/webpack.js --no-progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js"
|
||||
},
|
||||
"devDependencies": {
|
||||
"cross-env": "^7.0",
|
||||
"laravel-mix": "^5.0.1",
|
||||
"laravel-mix-merge-manifest": "^0.1.2"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
const dotenvExpand = require('dotenv-expand');
|
||||
dotenvExpand(require('dotenv').config({ path: '../../.env'/*, debug: true*/}));
|
||||
|
||||
const mix = require('laravel-mix');
|
||||
require('laravel-mix-merge-manifest');
|
||||
|
||||
mix.setPublicPath('../../public').mergeManifest();
|
||||
|
||||
mix.js(__dirname + '/Resources/assets/js/app.js', 'js/aggiornamenti.js')
|
||||
.sass( __dirname + '/Resources/assets/sass/app.scss', 'css/aggiornamenti.css');
|
||||
|
||||
if (mix.inProduction()) {
|
||||
mix.version();
|
||||
}
|
|
@ -1,26 +0,0 @@
|
|||
<?php
|
||||
|
||||
include_once __DIR__.'/../../core.php';
|
||||
|
||||
switch (post('op')) {
|
||||
case 'aggiorna-listino':
|
||||
$sconto = post('sconto');
|
||||
foreach ($id_records as $id_record) {
|
||||
$dbo->query('UPDATE mg_prezzi_articoli SET sconto_percentuale='.prepare($sconto).' WHERE id='.prepare($id_record));
|
||||
}
|
||||
flash()->info(tr('Sconti modificati correttamente!'));
|
||||
break;
|
||||
}
|
||||
|
||||
return [
|
||||
'aggiorna-listino' => [
|
||||
'text' => '<span>'.tr('Modifica sconto').'</span>',
|
||||
'data' => [
|
||||
'title' => tr('Inserisci lo sconto per questi articoli'),
|
||||
'msg' => '{[ "type": "text", "label": "<small>'.tr('Nuovo sconto').'</small>","icon-after":"%", "name": "sconto" ]}',
|
||||
'button' => tr('Modifica'),
|
||||
'class' => 'btn btn-lg btn-warning',
|
||||
'blank' => false,
|
||||
],
|
||||
],
|
||||
];
|
|
@ -1,85 +0,0 @@
|
|||
<?php
|
||||
/*
|
||||
* OpenSTAManager: il software gestionale open source per l'assistenza tecnica e la fatturazione
|
||||
* Copyright (C) DevCode s.n.c.
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
include_once __DIR__.'/../../core.php';
|
||||
|
||||
use Modules\Ordini\Ordine;
|
||||
use Modules\Preventivi\Preventivo;
|
||||
|
||||
$documento_finale = Ordine::find($id_record);
|
||||
$dir = $documento_finale->direzione;
|
||||
|
||||
$id_documento = get('id_documento');
|
||||
if (!empty($id_documento)) {
|
||||
$documento = Preventivo::find($id_documento);
|
||||
|
||||
$options = [
|
||||
'op' => 'add_documento',
|
||||
'type' => 'preventivo',
|
||||
'button' => tr('Aggiungi'),
|
||||
'documento' => $documento,
|
||||
'documento_finale' => $documento_finale,
|
||||
'tipo_documento_finale' => Ordine::class,
|
||||
];
|
||||
|
||||
echo App::load('importa.php', [], $options, true);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$id_anagrafica = $documento_finale->idanagrafica;
|
||||
|
||||
echo '
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
{[ "type": "select", "label": "'.tr('Preventivo').'", "name": "id_documento", "ajax-source": "preventivi", "select-options": {"idanagrafica": '.$id_anagrafica.', "stato": "is_fatturabile=1 OR is_completato"} ]}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="righe_documento">
|
||||
|
||||
</div>
|
||||
|
||||
<div class="alert alert-info" id="box-loading">
|
||||
<i class="fa fa-spinner fa-spin"></i> '.tr('Caricamento in corso').'...
|
||||
</div>';
|
||||
|
||||
$file = basename(__FILE__);
|
||||
echo '
|
||||
<script>$(document).ready(init)</script>
|
||||
|
||||
<script>
|
||||
var content = $("#righe_documento");
|
||||
var loader = $("#box-loading");
|
||||
|
||||
$(document).ready(function() {
|
||||
loader.hide();
|
||||
});
|
||||
|
||||
$("#id_documento").on("change", function() {
|
||||
loader.show();
|
||||
|
||||
var id = $(this).selectData() ? $(this).selectData().id : "";
|
||||
|
||||
content.html("");
|
||||
content.load("'.$structure->fileurl($file).'?id_module='.$id_module.'&id_record='.$id_record.'&id_documento=" + id, function() {
|
||||
loader.hide();
|
||||
});
|
||||
});
|
||||
</script>';
|
|
@ -1,133 +0,0 @@
|
|||
<?php
|
||||
/*
|
||||
* OpenSTAManager: il software gestionale open source per l'assistenza tecnica e la fatturazione
|
||||
* Copyright (C) DevCode s.n.c.
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
include_once __DIR__.'/../../core.php';
|
||||
|
||||
use Modules\Ordini\Ordine;
|
||||
use Modules\Fatture\Fattura;
|
||||
use Modules\Fatture\Stato;
|
||||
use Modules\Fatture\Tipo;
|
||||
|
||||
$module_fatture = 'Fatture di vendita';
|
||||
|
||||
|
||||
// Segmenti
|
||||
$id_fatture = Modules::get($module_fatture)['id'];
|
||||
if (!isset($_SESSION['module_'.$id_fatture]['id_segment'])) {
|
||||
$segments = Modules::getSegments($id_fatture);
|
||||
$_SESSION['module_'.$id_fatture]['id_segment'] = isset($segments[0]['id']) ? $segments[0]['id'] : null;
|
||||
}
|
||||
$id_segment = $_SESSION['module_'.$id_fatture]['id_segment'];
|
||||
|
||||
switch (post('op')) {
|
||||
case 'crea_fattura':
|
||||
$documenti = collect();
|
||||
$numero_totale = 0;
|
||||
$descrizione_tipo = 'Fattura immediata di vendita';
|
||||
|
||||
$tipo_documento = Tipo::where('descrizione', $descrizione_tipo)->first();
|
||||
|
||||
$stato_documenti_accodabili = Stato::where('descrizione', 'Bozza')->first();
|
||||
$accodare = post('accodare');
|
||||
|
||||
$data = date('Y-m-d');
|
||||
$id_segment = post('id_segment');
|
||||
|
||||
// Lettura righe selezionate
|
||||
foreach ($id_records as $id) {
|
||||
$documento_import = Ordine::find($id);
|
||||
$anagrafica = $documento_import->anagrafica;
|
||||
$id_anagrafica = $anagrafica->id;
|
||||
|
||||
// Proseguo solo se i documenti scelti sono fatturabili
|
||||
$ordine = $dbo->fetchOne('SELECT or_statiordine.descrizione AS stato FROM or_ordini LEFT JOIN or_statiordine ON or_ordini.idstatoordine=or_statiordine.id WHERE or_ordini.id='.prepare($id))['stato'];
|
||||
if (!in_array($ordine, ['Fatturato', 'Evaso', 'Bozza', 'In attesa di conferma', 'Annullato'])) {
|
||||
$righe = $documento_import->getRighe();
|
||||
if (!empty($righe)) {
|
||||
++$numero_totale;
|
||||
|
||||
// Ricerca fattura per anagrafica tra le registrate
|
||||
$fattura = $documenti->first(function ($item, $key) use ($id_anagrafica) {
|
||||
return $item->anagrafica->id == $id_anagrafica;
|
||||
});
|
||||
|
||||
// Ricerca fattura per anagrafica se l'impostazione di accodamento è selezionata
|
||||
if (!empty($accodare) && empty($fattura)) {
|
||||
$fattura = Fattura::where('idanagrafica', $id_anagrafica)
|
||||
->where('idstatodocumento', $stato_documenti_accodabili->id)
|
||||
->where('idtipodocumento', $tipo_documento->id)
|
||||
->first();
|
||||
|
||||
if (!empty($fattura)) {
|
||||
$documenti->push($fattura);
|
||||
}
|
||||
}
|
||||
|
||||
// Creazione fattura per anagrafica
|
||||
if (empty($fattura)) {
|
||||
$fattura = Fattura::build($anagrafica, $tipo_documento, $data, $id_segment);
|
||||
$documenti->push($fattura);
|
||||
}
|
||||
|
||||
// Inserimento righe
|
||||
foreach ($righe as $riga) {
|
||||
$qta = $riga->qta_rimanente;
|
||||
|
||||
if ($qta > 0) {
|
||||
//Fix per idconto righe fattura
|
||||
$riga->idconto = $fattura->idconto;
|
||||
$copia = $riga->copiaIn($fattura, $qta);
|
||||
|
||||
// Aggiornamento seriali dalla riga dell'ordine
|
||||
if ($copia->isArticolo()) {
|
||||
$copia->serials = $riga->serials;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($numero_totale > 0) {
|
||||
flash()->info(tr('_NUM_ ordini fatturati!', [
|
||||
'_NUM_' => $numero_totale,
|
||||
]));
|
||||
} else {
|
||||
flash()->warning(tr('Nessun ordine fatturato!'));
|
||||
}
|
||||
break;
|
||||
}
|
||||
if ($module['name'] == 'Ordini cliente') {
|
||||
$operations['crea_fattura'] = [
|
||||
'text' => '<span><i class="fa fa-file-code-o"></i> '.tr('Fattura _TYPE_', ['_TYPE_' => strtolower($module['name'])]),
|
||||
'data' => [
|
||||
'title' => tr('Fatturare i _TYPE_ selezionati?', ['_TYPE_' => strtolower($module['name'])]),
|
||||
'msg' => '{[ "type": "checkbox", "label": "<small>'.tr('Aggiungere alle _TYPE_ non ancora emesse?', ['_TYPE_' => strtolower($module_fatture)]).'", "placeholder": "'.tr('Aggiungere alle _TYPE_ nello stato bozza?', ['_TYPE_' => strtolower($module_fatture)]).'</small>", "name": "accodare" ]}
|
||||
<br>{[ "type": "select", "label": "'.tr('Sezionale').'", "name": "id_segment", "required": 1, "values": "query=SELECT id, name AS descrizione FROM zz_segments WHERE id_module=\''.$id_fatture.'\' AND is_fiscale = 1 ORDER BY name", "value": "'.$id_segment.'" ]}',
|
||||
'button' => tr('Procedi'),
|
||||
'class' => 'btn btn-lg btn-warning',
|
||||
'blank' => false,
|
||||
],
|
||||
];
|
||||
}
|
||||
if($operations){
|
||||
return $operations;
|
||||
} else {
|
||||
return;
|
||||
}
|
|
@ -1,115 +0,0 @@
|
|||
<?php
|
||||
/*
|
||||
* OpenSTAManager: il software gestionale open source per l'assistenza tecnica e la fatturazione
|
||||
* Copyright (C) DevCode s.n.c.
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
include_once __DIR__.'/../../core.php';
|
||||
|
||||
switch (filter('op')) {
|
||||
case 'update':
|
||||
$descrizione = filter('descrizione');
|
||||
$dir = filter('dir');
|
||||
$codice_tipo_documento_fe = filter('codice_tipo_documento_fe');
|
||||
|
||||
if (isset($descrizione) && isset($dir) && isset($codice_tipo_documento_fe)) {
|
||||
if ($dbo->fetchNum('SELECT * FROM `co_tipidocumento` WHERE `dir`='.prepare($dir).' AND `codice_tipo_documento_fe`='.prepare($codice_tipo_documento_fe).' AND `id`!='.prepare($id_record)) == 0) {
|
||||
|
||||
$predefined = post('predefined');
|
||||
if (!empty($predefined)) {
|
||||
$dbo->query('UPDATE co_tipidocumento SET predefined = 0 WHERE dir = '.prepare($dir));
|
||||
}
|
||||
|
||||
$dbo->update('co_tipidocumento', [
|
||||
'descrizione' => $descrizione,
|
||||
'dir' => $dir,
|
||||
'codice_tipo_documento_fe' => $codice_tipo_documento_fe,
|
||||
'help' => filter('help'),
|
||||
'predefined' => $predefined,
|
||||
'enabled' => post('enabled'),
|
||||
], ['id' => $id_record]);
|
||||
|
||||
flash()->info(tr('Salvataggio completato!'));
|
||||
} else {
|
||||
flash()->error(tr("E' già presente una tipologia di _TYPE_ con la stessa combinazione di direzione e tipo documento FE", [
|
||||
'_TYPE_' => 'tipo documento',
|
||||
]));
|
||||
}
|
||||
} else {
|
||||
flash()->error(tr('Ci sono stati alcuni errori durante il salvataggio'));
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 'add':
|
||||
$descrizione = filter('descrizione');
|
||||
$dir = filter('dir');
|
||||
$codice_tipo_documento_fe = filter('codice_tipo_documento_fe');
|
||||
|
||||
if (isset($descrizione) && isset($dir) && isset($codice_tipo_documento_fe)) {
|
||||
if ($dbo->fetchNum('SELECT * FROM `co_tipidocumento` WHERE `dir`='.prepare($dir).' AND `codice_tipo_documento_fe`='.prepare($codice_tipo_documento_fe)) == 0) {
|
||||
$dbo->insert('co_tipidocumento', [
|
||||
'descrizione' => $descrizione,
|
||||
'dir' => $dir,
|
||||
'codice_tipo_documento_fe' => $codice_tipo_documento_fe,
|
||||
]);
|
||||
$id_record = $dbo->lastInsertedID();
|
||||
|
||||
if (isAjaxRequest()) {
|
||||
echo json_encode(['id' => $id_record, 'text' => $descrizione]);
|
||||
}
|
||||
|
||||
flash()->info(tr('Aggiunta nuova tipologia di _TYPE_', [
|
||||
'_TYPE_' => 'tipo documento',
|
||||
]));
|
||||
} else {
|
||||
flash()->error(tr("E' già presente una tipologia di _TYPE_ con la stessa combinazione di direzione e tipo documento FE", [
|
||||
'_TYPE_' => 'tipo documento',
|
||||
]));
|
||||
}
|
||||
} else {
|
||||
flash()->error(tr('Ci sono stati alcuni errori durante il salvataggio'));
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 'delete':
|
||||
|
||||
$documenti = $dbo->fetchNum('SELECT id FROM co_documenti WHERE idtipodocumento ='.prepare($id_record));
|
||||
|
||||
if (isset($id_record) && empty($documenti)) {
|
||||
$dbo->query('DELETE FROM `co_tipidocumento` WHERE `id`='.prepare($id_record));
|
||||
flash()->info(tr('Tipologia di _TYPE_ eliminata con successo.', [
|
||||
'_TYPE_' => 'tipo documento',
|
||||
]));
|
||||
} else {
|
||||
|
||||
$dbo->update('co_tipidocumento', [
|
||||
'deleted_at' => date(),
|
||||
'predefined' => 0,
|
||||
'enabled' => 0,
|
||||
], ['id' => $id_record]);
|
||||
|
||||
flash()->info(tr('Tipologia di _TYPE_ eliminata con successo.', [
|
||||
'_TYPE_' => 'tipo documento',
|
||||
]));
|
||||
|
||||
|
||||
//flash()->error(tr('Sono presenti dei documenti collegati a questo tipo documento'));
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
|
@ -1,46 +0,0 @@
|
|||
<?php
|
||||
/*
|
||||
* OpenSTAManager: il software gestionale open source per l'assistenza tecnica e la fatturazione
|
||||
* Copyright (C) DevCode s.n.c.
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
include_once __DIR__.'/../../core.php';
|
||||
|
||||
?><form action="" method="post" id="add-form">
|
||||
<input type="hidden" name="op" value="add">
|
||||
<input type="hidden" name="backto" value="record-edit">
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
{[ "type": "text", "label": "<?php echo tr('Descrizione'); ?>", "name": "descrizione", "required": 1 ]}
|
||||
</div>
|
||||
|
||||
<div class="col-md-6">
|
||||
{[ "type": "select", "label": "<?php echo tr('Direzione'); ?>", "name": "dir", "values": "list=\"\": \"Non specificato\", \"entrata\": \"<?php echo tr('Entrata'); ?>\", \"uscita\": \"<?php echo tr('Uscita'); ?>\"", "required": 1 ]}
|
||||
</div>
|
||||
|
||||
<div class="col-md-6">
|
||||
{[ "type": "select", "label": "<?php echo tr('Codice tipo documento FE'); ?>", "name": "codice_tipo_documento_fe", "values": "query=SELECT codice AS id, CONCAT_WS(' - ', codice, descrizione) AS descrizione FROM fe_tipi_documento", "required": 1 ]}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- PULSANTI -->
|
||||
<div class="row">
|
||||
<div class="col-md-12 text-right">
|
||||
<button type="submit" class="btn btn-primary"><i class="fa fa-plus"></i> <?php echo tr('Aggiungi'); ?></button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
|
@ -1,37 +0,0 @@
|
|||
<?php
|
||||
/*
|
||||
* OpenSTAManager: il software gestionale open source per l'assistenza tecnica e la fatturazione
|
||||
* Copyright (C) DevCode s.n.c.
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
include_once __DIR__.'/../../../core.php';
|
||||
|
||||
switch ($resource) {
|
||||
case 'tipi_documento':
|
||||
$query = 'SELECT id, descrizione FROM co_tipidocumento |where| ORDER BY descrizione ASC';
|
||||
|
||||
$where[] = 'co_tipidocumento.enabled = 1';
|
||||
$where[] = 'dir='.$superselect['dir'];
|
||||
|
||||
foreach ($elements as $element) {
|
||||
$filter[] = 'id='.prepare($element);
|
||||
}
|
||||
if (!empty($search)) {
|
||||
$search_fields[] = 'descrizione LIKE '.prepare('%'.$search.'%');
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
|
@ -1,78 +0,0 @@
|
|||
<?php
|
||||
/*
|
||||
* OpenSTAManager: il software gestionale open source per l'assistenza tecnica e la fatturazione
|
||||
* Copyright (C) DevCode s.n.c.
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
include_once __DIR__.'/../../core.php';
|
||||
|
||||
?><form action="" method="post" id="edit-form">
|
||||
<input type="hidden" name="backto" value="record-edit">
|
||||
<input type="hidden" name="op" value="update">
|
||||
|
||||
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
{[ "type": "text", "label": "<?php echo tr('Descrizione'); ?>", "name": "descrizione", "required": 1, "value": "$descrizione$" ]}
|
||||
</div>
|
||||
|
||||
<div class="col-md-3">
|
||||
{[ "type": "select", "label": "<?php echo tr('Direzione'); ?>", "name": "dir", "value": "$dir$", "values": "list=\"\": \"Non specificato\", \"entrata\": \"<?php echo tr('Entrata'); ?>\", \"uscita\": \"<?php echo tr('Uscita'); ?>\"", "required": 1 ]}
|
||||
</div>
|
||||
|
||||
<div class="col-md-3">
|
||||
{[ "type": "select", "label": "<?php echo tr('Codice tipo documento FE'); ?>", "name": "codice_tipo_documento_fe", "value": "$codice_tipo_documento_fe$", "values": "query=SELECT codice AS id, CONCAT_WS(' - ', codice, descrizione) AS descrizione FROM fe_tipi_documento", "required": 1 ]}
|
||||
</div>
|
||||
|
||||
<div class="col-md-4">
|
||||
{[ "type": "checkbox", "label": "<?php echo tr('Tipo documento predefinito'); ?>", "name": "predefined", "value": "<?php echo intval($record['predefined']); ?>", "help":"<?php echo tr('Impostare questo tipo di documento predefinto per le fatture'); ?>." ]}
|
||||
</div>
|
||||
|
||||
<div class="col-md-4">
|
||||
{[ "type": "checkbox", "label": "<?php echo tr('Attivo'); ?>", "name": "enabled", "value": "<?php echo intval($record['enabled']); ?>" ]}
|
||||
</div>
|
||||
|
||||
<div class="col-md-4">
|
||||
{[ "type": "checkbox", "label": "<?php echo tr('Reversed'); ?>", "name": "reversed", "value": "<?php echo intval($record['reversed']); ?>", "readonly": 1 ]}
|
||||
</div>
|
||||
|
||||
<div class="col-md-12">
|
||||
{[ "type": "text", "label": "<?php echo tr('Help'); ?>", "name": "help", "value": "$help$" ]}
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
</form>
|
||||
|
||||
<?php
|
||||
// Collegamenti diretti (numerici)
|
||||
$numero_documenti = $dbo->fetchNum('SELECT id FROM co_documenti WHERE idtipodocumento='.prepare($id_record));
|
||||
|
||||
if (!empty($numero_documenti)) {
|
||||
echo '
|
||||
<div class="alert alert-danger">
|
||||
'.tr('Ci sono _NUM_ documenti collegati', [
|
||||
'_NUM_' => $numero_documenti,
|
||||
]).'.
|
||||
</div>';
|
||||
}
|
||||
?>
|
||||
|
||||
<a class="btn btn-danger ask" data-backto="record-list">
|
||||
<i class="fa fa-trash"></i> <?php echo tr('Elimina'); ?>
|
||||
</a>
|
|
@ -1,24 +0,0 @@
|
|||
<?php
|
||||
/*
|
||||
* OpenSTAManager: il software gestionale open source per l'assistenza tecnica e la fatturazione
|
||||
* Copyright (C) DevCode s.n.c.
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
include_once __DIR__.'/../../core.php';
|
||||
|
||||
if (isset($id_record)) {
|
||||
$record = $dbo->fetchOne('SELECT * FROM `co_tipidocumento` WHERE id='.prepare($id_record));
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"Aggiornamenti": true
|
||||
}
|
|
@ -8,7 +8,7 @@
|
|||
'value' => $value,
|
||||
'required' => $required,
|
||||
'data-parsley-errors-container' => '#'.$unique_id.'-errors'
|
||||
]) }} onchange="$(this).parent().find(\'[type = hidden]\').val(+this.checked).trigger(\'change\')"/>
|
||||
]) }} onchange="$(this).parent().find('[type = hidden]').val(+this.checked).trigger('change')"/>
|
||||
<div class="btn-group checkbox-buttons">
|
||||
<label for="{{ $id }}" class="btn btn-default{{ $class }}">
|
||||
<span class="fa fa-check text-success"></span>
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
@foreach($requirements as $group => $elements)
|
||||
@php
|
||||
$general_status = true;
|
||||
foreach ($elements as $element){
|
||||
$general_status &= $element['status'];
|
||||
}
|
||||
@endphp
|
||||
|
||||
<div class="box box-outline box-{{ $general_status ? 'success collapsed-box' : 'danger' }}">
|
||||
<div class="box-header with-border">
|
||||
<h3 class="box-title">{{ $group }}</h3>
|
||||
|
||||
@if($general_status)
|
||||
<div class="box-tools pull-right">
|
||||
<button type="button" class="btn btn-box-tool" data-widget="collapse">
|
||||
<i class="fa fa-plus"></i>
|
||||
</button>
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
<div class="box-body no-padding">
|
||||
<table class="table">
|
||||
|
||||
@foreach($elements as $name => $element)
|
||||
<tr class="{{ $element['status'] ? 'success' : 'danger' }}">
|
||||
<td style="width: 10px"><i class="fa fa-{{ $element['status'] ? 'check' : 'times' }}"></i></td>
|
||||
<td>{{ $name }}</td>
|
||||
<td>{!! $element['description'] !!}</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
@endforeach
|
|
@ -0,0 +1,22 @@
|
|||
@extends('layouts.guest')
|
||||
|
||||
@section('title', tr("Requisiti"))
|
||||
@section('box_class', 'box-info')
|
||||
@section('box_header')
|
||||
<h3 class="box-title">{{ tr('Requisiti del software OpenSTAManager') }}</h3>
|
||||
@endsection
|
||||
|
||||
@section('content')
|
||||
<p>{!! tr('Benvenuto in _NAME_!', ['_NAME_' => '<strong>'.tr('OpenSTAManager').'</strong>']) !!}</p>
|
||||
<p>{{ tr("Prima di procedere alla configurazione e all'installazione del software, sono necessari alcuni accorgimenti per garantire il corretto funzionamento del gestionale") }}.</p>
|
||||
<br>
|
||||
|
||||
<p>{!! tr('Le estensioni e impostazioni PHP possono essere personalizzate nel file di configurazione _FILE_', ['_FILE_' => '<b>php.ini</b>']) !!}.</p>
|
||||
<hr>
|
||||
|
||||
@include('config.requirements-list')
|
||||
|
||||
<button type="button" class="btn btn-info center-block" onclick="window.location.reload()">
|
||||
<i class="fa fa-refresh"></i> {{ tr("Ricarica") }}
|
||||
</button>
|
||||
@endsection
|
|
@ -0,0 +1,10 @@
|
|||
@extends('errors.base')
|
||||
|
||||
@section('title', tr("Servizio non disponibile"))
|
||||
|
||||
@section('error_color', 'info')
|
||||
@section('error_header', '503')
|
||||
|
||||
@section('error_message', tr('Servizio non disponibile!'))
|
||||
@section('error_info', tr("E' in corso un processo di manutenzione dell'applicazione"))
|
||||
@section('error_return', tr("Torneremo attivi il più presto possibile"))
|
|
@ -276,6 +276,23 @@
|
|||
<!-- /.sidebar -->
|
||||
</aside>
|
||||
|
||||
{{-- Menu laterale per la visualizzazione dei plugin --}}
|
||||
@if($__env->yieldContent('sidebar'))
|
||||
<aside class="control-sidebar control-sidebar-light control-sidebar-shown">
|
||||
<h4 class="text-center">@yield('sidebar_title', tr('Plugin disponibili'))</h4>
|
||||
<ul class="nav nav-tabs nav-pills nav-stacked">
|
||||
<li data-toggle="control-sidebar" class="active">
|
||||
<a data-toggle="tab" href="#tab_0">
|
||||
<i class="fa fa-home"></i> {{ tr('Pagina principale') }}
|
||||
</a>
|
||||
</li>
|
||||
|
||||
@yield('sidebar')
|
||||
</ul>
|
||||
</aside>
|
||||
<div class="control-sidebar-bg"></div>
|
||||
@endif
|
||||
|
||||
<!-- Right side column. Contains the navbar and content of the page -->
|
||||
<div class="content-wrapper">
|
||||
<!-- Main content -->
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
@extends('layouts.base')
|
||||
|
||||
@section('body_class')bg-light@endsection
|
||||
@section('body_class', 'bg-light')
|
||||
|
||||
@section('body')
|
||||
@yield('before_content')
|
||||
|
|
|
@ -3,8 +3,5 @@
|
|||
use App\Http\Controllers\LegacyController;
|
||||
use Illuminate\Support\Facades\Route;
|
||||
|
||||
//Route::any('/', [LegacyController::class, 'index']);
|
||||
|
||||
Route::any('/{path}', [LegacyController::class, 'index'])
|
||||
->name('legacy')
|
||||
->where('path', '.*');
|
||||
// Route di fallback generale
|
||||
Route::fallback([LegacyController::class, 'index']);
|
||||
|
|
|
@ -4,7 +4,9 @@ use App\Http\Controllers\ConfigurationController;
|
|||
use App\Http\Controllers\HookController;
|
||||
use App\Http\Controllers\InfoController;
|
||||
use App\Http\Controllers\InitializationController;
|
||||
use App\Http\Controllers\LegacyController;
|
||||
use App\Http\Controllers\MessageController;
|
||||
use App\Http\Controllers\RequirementsController;
|
||||
use App\Http\Controllers\Test;
|
||||
use App\Http\Controllers\UserController;
|
||||
use Illuminate\Support\Facades\Route;
|
||||
|
@ -31,6 +33,10 @@ Route::get('/', function () {
|
|||
})
|
||||
->middleware(['auth']);
|
||||
|
||||
// Schermata dei requisiti
|
||||
Route::get('/requirements', [RequirementsController::class, 'index'])
|
||||
->name('requirements');
|
||||
|
||||
// Sezione di configurazione
|
||||
Route::get('/config', [ConfigurationController::class, 'index'])
|
||||
->name('configuration');
|
||||
|
|
Loading…
Reference in New Issue