Compare commits
8 Commits
5f51c4af16
...
bd6889be4a
Author | SHA1 | Date |
---|---|---|
Dasc3er | bd6889be4a | |
Dasc3er | 8a8b1479d0 | |
Dasc3er | 4a93422974 | |
loviuz | 3fbd42e0e4 | |
Dasc3er | 43203e5385 | |
loviuz | 6b3f05b666 | |
Dasc3er | dfb5734d9b | |
Dasc3er | 5135a2c04c |
|
@ -1033,13 +1033,13 @@ div.tip {
|
|||
margin-right: 230px;
|
||||
}
|
||||
|
||||
.control-sidebar-shown {
|
||||
.control-sidebar-open {
|
||||
right: 0;
|
||||
display: block !important;
|
||||
}
|
||||
|
||||
.control-sidebar.control-sidebar-shown,
|
||||
.control-sidebar.control-sidebar-shown + .control-sidebar-bg {
|
||||
.control-sidebar.control-sidebar-open,
|
||||
.control-sidebar.control-sidebar-open + .control-sidebar-bg {
|
||||
right: 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -32,11 +32,11 @@ $(document).ready(function () {
|
|||
$(this).find('ul').stop().slideUp();
|
||||
});
|
||||
|
||||
$menulist = $('.treeview-menu > li.active');
|
||||
for (i = 0; i < $menulist.length; i++) {
|
||||
$list = $($menulist[i]);
|
||||
$list.parent().show().parent().addClass('active');
|
||||
$list.parent().parent().find('i.fa-angle-left').removeClass('fa-angle-left').addClass('fa-angle-down');
|
||||
const elenco_menu = $('.treeview-menu > li.active');
|
||||
for (i = 0; i < elenco_menu.length; i++) {
|
||||
const elemento = $(elenco_menu[i]);
|
||||
elemento.parent().show().parent().addClass('active');
|
||||
elemento.parent().parent().find('i.fa-angle-left').removeClass('fa-angle-left').addClass('fa-angle-down');
|
||||
}
|
||||
|
||||
// Menu ordinabile
|
||||
|
@ -46,7 +46,7 @@ $(document).ready(function () {
|
|||
cursor: "move",
|
||||
dropOnEmpty: true,
|
||||
scroll: true,
|
||||
})[0].addEventListener("sortupdate", function(e) {
|
||||
})[0].addEventListener("sortupdate", function (e) {
|
||||
let order = $(".sidebar-menu > .treeview[data-id]").toArray().map(a => $(a).data("id"))
|
||||
|
||||
$.post(globals.rootdir + "/actions.php", {
|
||||
|
@ -57,19 +57,52 @@ $(document).ready(function () {
|
|||
});
|
||||
}
|
||||
|
||||
$(".sidebar-toggle").click(function () {
|
||||
setTimeout(function () {
|
||||
window.dispatchEvent(new Event('resize'));
|
||||
}, 350);
|
||||
});
|
||||
|
||||
// Mostra/nasconde sidebar sx
|
||||
// Mostra/nasconde sidebar del menu principale
|
||||
$(".sidebar-toggle").on("click", function () {
|
||||
if ($("body").hasClass("sidebar-collapse")) {
|
||||
session_set("settings,sidebar-collapse", 0, 1, 0);
|
||||
} else {
|
||||
session_set("settings,sidebar-collapse", 1, 0, 0);
|
||||
}
|
||||
|
||||
setTimeout(function () {
|
||||
window.dispatchEvent(new Event('resize'));
|
||||
}, 350);
|
||||
});
|
||||
|
||||
// Barra plugin laterale
|
||||
const pluginToggle = $(".control-sidebar-toggle");
|
||||
const largeScreen = screen.width > 1200;
|
||||
|
||||
// Gestione click sul pulsante per il toggle
|
||||
pluginToggle.on("click", function () {
|
||||
$("aside.content-wrapper, .main-footer").toggleClass("with-control-sidebar");
|
||||
|
||||
toggleControlSidebar();
|
||||
});
|
||||
|
||||
// Gestione click sulla sidebar per evitare chiusura
|
||||
$(".control-sidebar").on("click", function (e) {
|
||||
if (largeScreen && e.target.tagName !== 'H4' && $(".main-footer").hasClass("with-control-sidebar")) {
|
||||
toggleControlSidebar();
|
||||
}
|
||||
});
|
||||
|
||||
// Barra plugin laterale disabilitata per schermi piccoli
|
||||
if (largeScreen && !globals.collapse_plugin_sidebar) {
|
||||
pluginToggle.click();
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Funzione dedicata alla gestione del toggle della sidebar.
|
||||
*/
|
||||
function toggleControlSidebar() {
|
||||
const sidebar = $(".control-sidebar");
|
||||
|
||||
sidebar.toggleClass("control-sidebar-open");
|
||||
|
||||
if (sidebar.hasClass("control-sidebar-open")) {
|
||||
sidebar.show();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -38,34 +38,32 @@ function start_datatables() {
|
|||
start_local_datatables();
|
||||
|
||||
$('.main-records').each(function () {
|
||||
var $this = $(this);
|
||||
const $this = $(this);
|
||||
|
||||
// Controlla che la tabella non sia già inizializzata
|
||||
if (!$.fn.DataTable.isDataTable('#' + $this.attr('id'))) {
|
||||
var id_module = $this.data('idmodule');
|
||||
var id_plugin = $this.data('idplugin');
|
||||
var id_parent = $this.data('idparent');
|
||||
const id_module = $this.data('idmodule');
|
||||
const id_plugin = $this.data('idplugin');
|
||||
const id_parent = $this.data('idparent');
|
||||
|
||||
// Parametri di ricerca da url o sessione
|
||||
var search = getTableSearch();
|
||||
const search = getTableSearch();
|
||||
|
||||
var column_search = [];
|
||||
const column_search = [];
|
||||
$this.find("th").each(function () {
|
||||
var id = $(this).attr('id').replace("th_", "");
|
||||
var single_value = search["search_" + id] ? search["search_" + id] : "";
|
||||
const id = $(this).attr('id').replace("th_", "");
|
||||
const single_value = search["search_" + id] ? search["search_" + id] : "";
|
||||
|
||||
column_search.push({
|
||||
"sSearch": single_value,
|
||||
});
|
||||
});
|
||||
|
||||
var tempo_attesa_ricerche = (globals.tempo_attesa_ricerche * 1000);
|
||||
|
||||
$this.on('preInit.dt', function (ev, settings) {
|
||||
$('#mini-loader').show();
|
||||
});
|
||||
|
||||
var table = $this.DataTable({
|
||||
const table = $this.DataTable({
|
||||
language: globals.translations.datatables,
|
||||
autoWidth: true,
|
||||
dom: "ti",
|
||||
|
@ -97,9 +95,100 @@ function start_datatables() {
|
|||
style: 'multi',
|
||||
selector: 'td:first-child'
|
||||
},
|
||||
buttons: [
|
||||
buttons: getDatatablesButtons($this),
|
||||
scroller: {
|
||||
loadingIndicator: true,
|
||||
displayBuffer: globals.dataload_page_buffer,
|
||||
},
|
||||
ajax: {
|
||||
url: "ajax_dataload.php?id_module=" + id_module + "&id_plugin=" + id_plugin + "&id_parent=" + id_parent,
|
||||
type: 'GET',
|
||||
dataSrc: "data",
|
||||
},
|
||||
initComplete: initComplete,
|
||||
drawCallback: drawCallback,
|
||||
footerCallback: footerCallback,
|
||||
});
|
||||
|
||||
table.on('processing.dt', function (e, settings, processing) {
|
||||
if (processing) {
|
||||
$('#mini-loader').show();
|
||||
} else {
|
||||
$('#mini-loader').hide();
|
||||
}
|
||||
})
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Funzione per evitare il sorting al click della colonna.
|
||||
* Utilizzata per evitare il sorting nelle ricerche.
|
||||
* @param {*} e
|
||||
*/
|
||||
function stopTableSorting(e) {
|
||||
if (!e) var e = window.event;
|
||||
e.cancelBubble = true;
|
||||
if (e.stopPropagation) e.stopPropagation();
|
||||
}
|
||||
|
||||
/**
|
||||
* Funzione per resettare il campo di ricerca in una specifica colonna.
|
||||
* @param {string} type
|
||||
*/
|
||||
function resetTableSearch(type) {
|
||||
if (type == null) $('[id^=th_] input').val('').trigger('keyup');
|
||||
else $('[id^=th_' + type + '] input').val('').trigger('keyup');
|
||||
}
|
||||
|
||||
/**
|
||||
* Sostituisce i caratteri speciali per la ricerca attraverso le tabelle Datatables.
|
||||
*
|
||||
* @param {string} field
|
||||
* @return string
|
||||
*/
|
||||
function searchFieldName(field) {
|
||||
return field.replace(' ', '-').replace('.', '');
|
||||
}
|
||||
|
||||
/**
|
||||
* Salva nella sessione la ricerca per le tabelle Datatables.
|
||||
*
|
||||
* @param {int} module_id
|
||||
* @param {string} field
|
||||
* @param {mixed} value
|
||||
*/
|
||||
function searchTable(module_id, field, value) {
|
||||
session_set('module_' + module_id + ',' + 'search_' + searchFieldName(field), value, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Restituisce i valori di ricerca impostati nell'URL della pagina.
|
||||
* @returns {{}}
|
||||
*/
|
||||
function getTableSearch() {
|
||||
// Parametri di ricerca da url o sessione
|
||||
const search = getUrlVars();
|
||||
|
||||
globals.search.forEach(function (value, index, array) {
|
||||
if (search[array[index]] === undefined) {
|
||||
search[array[index]] = array[value];
|
||||
}
|
||||
});
|
||||
|
||||
return search;
|
||||
}
|
||||
|
||||
/**
|
||||
* Restituisce i pulsanti da generare per la tabella Datatables.
|
||||
* @returns
|
||||
*/
|
||||
function getDatatablesButtons(table) {
|
||||
return [
|
||||
// Pulsante di esportazione CSV
|
||||
{
|
||||
extend: 'csv',
|
||||
footer: true,
|
||||
fieldSeparator: ";",
|
||||
exportOptions: {
|
||||
modifier: {
|
||||
|
@ -115,30 +204,36 @@ function start_datatables() {
|
|||
}
|
||||
}
|
||||
},
|
||||
// Pulsante di esportazione tramite copia
|
||||
{
|
||||
extend: 'copy',
|
||||
footer: true,
|
||||
exportOptions: {
|
||||
modifier: {
|
||||
selected: true
|
||||
}
|
||||
}
|
||||
},
|
||||
// Pulsante di esportazione via stampa della tabella
|
||||
{
|
||||
extend: 'print',
|
||||
autoPrint: true,
|
||||
footer: false, // Non funzionante in Firefox, e saltuarmente in Chrome
|
||||
customize: function (win) {
|
||||
$(win.document.body)
|
||||
.css('font-size', '10pt')
|
||||
.append(
|
||||
'<table class="main-records table table-condensed table-bordered dataTable"><tfoot><tr><td></td><td class="pull-right">' + $('#summable').text() + '</td><td></td></tr></tfoot></table>'
|
||||
);
|
||||
$(win.document.body).find('table')
|
||||
const datatable = getTable(table).datatable;
|
||||
|
||||
const footer = datatable.table().footer().children[0];
|
||||
console.log(footer);
|
||||
|
||||
const body = $(win.document.body);
|
||||
body.find('table')
|
||||
.addClass('compact')
|
||||
.css('font-size', 'inherit');
|
||||
$(win.document.body).find('td:first-child')
|
||||
.addClass('hide');
|
||||
$(win.document.body).find('th:first-child')
|
||||
.css('font-size', 'inherit')
|
||||
.append(footer);
|
||||
|
||||
body.find('td:first-child, th:first-child')
|
||||
.addClass('hide');
|
||||
|
||||
},
|
||||
exportOptions: {
|
||||
modifier: {
|
||||
|
@ -146,8 +241,10 @@ function start_datatables() {
|
|||
}
|
||||
}
|
||||
},
|
||||
// Pulsante di esportazione in formato Excel
|
||||
{
|
||||
extend: 'excel',
|
||||
footer: true,
|
||||
exportOptions: {
|
||||
modifier: {
|
||||
selected: true
|
||||
|
@ -163,37 +260,32 @@ function start_datatables() {
|
|||
}
|
||||
}
|
||||
},
|
||||
// Pulsante di esportazione in formato PDF
|
||||
{
|
||||
extend: 'pdf',
|
||||
footer: true,
|
||||
exportOptions: {
|
||||
modifier: {
|
||||
selected: true
|
||||
}
|
||||
}
|
||||
},
|
||||
],
|
||||
scroller: {
|
||||
loadingIndicator: true,
|
||||
displayBuffer: globals.dataload_page_buffer,
|
||||
},
|
||||
ajax: {
|
||||
url: "ajax_dataload.php?id_module=" + id_module + "&id_plugin=" + id_plugin + "&id_parent=" + id_parent,
|
||||
type: 'GET',
|
||||
dataSrc: "data",
|
||||
},
|
||||
initComplete: function (settings) {
|
||||
var api = this.api();
|
||||
var search = getTableSearch();
|
||||
];
|
||||
}
|
||||
|
||||
function initComplete(settings) {
|
||||
const api = this.api();
|
||||
const search = getTableSearch();
|
||||
|
||||
api.columns('.search').every(function () {
|
||||
var column = this;
|
||||
const column = this;
|
||||
|
||||
// Valore predefinito della ricerca
|
||||
var tempo;
|
||||
var header = $(column.header());
|
||||
var name = header.attr('id').replace('th_', '');
|
||||
let tempo;
|
||||
const header = $(column.header());
|
||||
const name = header.attr('id').replace('th_', '');
|
||||
|
||||
var value = search['search_' + name] ? search['search_' + name] : '';
|
||||
const value = search['search_' + name] ? search['search_' + name] : '';
|
||||
|
||||
$('<br><input type="text" style="width:100%" class="form-control' + (value ? ' input-searching' : '') + '" placeholder="' + globals.translations.filter + '..." value="' + value.replace(/"/g, '"') + '"><i class="deleteicon fa fa-times fa-2x' + (value ? '' : ' hide') + '"></i>')
|
||||
.appendTo(column.header())
|
||||
|
@ -221,12 +313,14 @@ function start_datatables() {
|
|||
}
|
||||
|
||||
// Impostazione delle sessioni per le ricerche del modulo e del campo specificati
|
||||
var module_id = $this.data('idmodule'); //+ "-" + $this.data('idplugin');
|
||||
var field = $(this).parent().attr('id').replace('th_', '');
|
||||
var value = $(this).val();
|
||||
const module_id = $this.data('idmodule'); //+ "-" + $this.data('idplugin');
|
||||
const field = $(this).parent().attr('id').replace('th_', '');
|
||||
const value = $(this).val();
|
||||
if (e.keyCode == 13 || $(this).val() == '') {
|
||||
start_search(module_id, field, value);
|
||||
} else {
|
||||
const tempo_attesa_ricerche = (globals.tempo_attesa_ricerche * 1000);
|
||||
|
||||
tempo = window.setTimeout(start_search, tempo_attesa_ricerche, module_id, field, value);
|
||||
}
|
||||
});
|
||||
|
@ -245,9 +339,11 @@ function start_datatables() {
|
|||
$('.deleteicon').on("click", function (e) {
|
||||
resetTableSearch($(this).parent().attr("id").replace("th_", ""));
|
||||
});
|
||||
},
|
||||
drawCallback: function (settings) {
|
||||
var api = new $.fn.dataTable.Api(settings);
|
||||
}
|
||||
|
||||
function drawCallback(settings) {
|
||||
const table = getTable(settings.nTable);
|
||||
const datatable = table.datatable;
|
||||
|
||||
$(".dataTables_sizing .deleteicon").addClass('hide');
|
||||
|
||||
|
@ -260,7 +356,7 @@ function start_datatables() {
|
|||
});
|
||||
|
||||
$("[data-link]").each(function () {
|
||||
var $link = $(this);
|
||||
const $link = $(this);
|
||||
$(this).parent().not('.bound').addClass('bound').click(function (event) {
|
||||
if ($link.data('type') === 'dialog') {
|
||||
launch_modal(globals.translations.details, $link.data('link'));
|
||||
|
@ -272,18 +368,19 @@ function start_datatables() {
|
|||
});
|
||||
|
||||
// Reimposto il flag sulle righe ricaricate selezionate in precedenza
|
||||
var selected = $this.data('selected') ? $this.data('selected').split(';') : [];
|
||||
table.rows().every(function (rowIdx) {
|
||||
if ($.inArray(this.id().toString(), selected) !== -1) {
|
||||
table.row(':eq(' + rowIdx + ')', {
|
||||
const selected = table.getSelectedRows();
|
||||
datatable.rows().every(function (rowIdx) {
|
||||
if (selected.includes(this.id())) {
|
||||
datatable.row(':eq(' + rowIdx + ')', {
|
||||
page: 'current'
|
||||
}).select();
|
||||
}
|
||||
});
|
||||
},
|
||||
footerCallback: function (row, data, start, end, display) {
|
||||
var i = -1;
|
||||
var json = this.api().ajax.json();
|
||||
}
|
||||
|
||||
function footerCallback(row, data, start, end, display) {
|
||||
let i = -1;
|
||||
const json = this.api().ajax.json();
|
||||
|
||||
this.api().columns().every(function () {
|
||||
if (json.summable[i] !== undefined) {
|
||||
|
@ -294,68 +391,6 @@ function start_datatables() {
|
|||
|
||||
i++;
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
table.on('processing.dt', function (e, settings, processing) {
|
||||
if (processing) {
|
||||
$('#mini-loader').show();
|
||||
} else {
|
||||
$('#mini-loader').hide();
|
||||
}
|
||||
})
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function stopTableSorting(e) {
|
||||
if (!e) var e = window.event;
|
||||
e.cancelBubble = true;
|
||||
if (e.stopPropagation) e.stopPropagation();
|
||||
}
|
||||
|
||||
function resetTableSearch(type) {
|
||||
if (type == null) $('[id^=th_] input').val('').trigger('keyup');
|
||||
else $('[id^=th_' + type + '] input').val('').trigger('keyup');
|
||||
}
|
||||
|
||||
function reset(type) {
|
||||
return resetTableSearch(type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sostituisce i caratteri speciali per la ricerca attraverso le tabelle Datatables.
|
||||
*
|
||||
* @param string field
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function searchFieldName(field) {
|
||||
return field.replace(' ', '-').replace('.', '');
|
||||
}
|
||||
|
||||
/**
|
||||
* Salva nella sessione la ricerca per le tabelle Datatables.
|
||||
*
|
||||
* @param int module_id
|
||||
* @param string field
|
||||
* @param mixed value
|
||||
*/
|
||||
function searchTable(module_id, field, value) {
|
||||
session_set('module_' + module_id + ',' + 'search_' + searchFieldName(field), value, 0);
|
||||
}
|
||||
|
||||
function getTableSearch() {
|
||||
// Parametri di ricerca da url o sessione
|
||||
var search = getUrlVars();
|
||||
|
||||
globals.search.forEach(function (value, index, array) {
|
||||
if (search[array[index]] === undefined) {
|
||||
search[array[index]] = array[value];
|
||||
}
|
||||
});
|
||||
|
||||
return search;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -424,13 +459,13 @@ function getTable(selector) {
|
|||
|
||||
// Aggiornamento del footer nel caso sia richiesto
|
||||
if (globals.restrict_summables_to_selected) {
|
||||
this.updateSelectedFooter();
|
||||
this.updateFooterForSelectedRows();
|
||||
}
|
||||
},
|
||||
addSelectedRows: function (row_ids) {
|
||||
row_ids = Array.isArray(row_ids) ? row_ids : [row_ids];
|
||||
row_ids.forEach(function (item, index) {
|
||||
selected.set(item, true);
|
||||
selected.set(item.toString(), true);
|
||||
});
|
||||
|
||||
this.saveSelectedRows();
|
||||
|
@ -438,7 +473,7 @@ function getTable(selector) {
|
|||
removeSelectedRows: function (row_ids) {
|
||||
row_ids = Array.isArray(row_ids) ? row_ids : [row_ids];
|
||||
row_ids.forEach(function (item, index) {
|
||||
selected.delete(item);
|
||||
selected.delete(item.toString());
|
||||
});
|
||||
|
||||
this.saveSelectedRows();
|
||||
|
@ -448,12 +483,14 @@ function getTable(selector) {
|
|||
this.saveSelectedRows();
|
||||
},
|
||||
|
||||
// Aggiornamento dei campi summable
|
||||
updateSelectedFooter: function () {
|
||||
let datatable = this.datatable;
|
||||
/**
|
||||
* Nuovi valori dei campi summable
|
||||
* @returns
|
||||
*/
|
||||
getSelectedRowsFooter: function () {
|
||||
let ids = this.getSelectedRows();
|
||||
|
||||
$.ajax({
|
||||
return $.ajax({
|
||||
url: globals.rootdir + "/ajax.php",
|
||||
type: "POST",
|
||||
dataType: "json",
|
||||
|
@ -462,8 +499,17 @@ function getTable(selector) {
|
|||
id_plugin: this.id_plugin,
|
||||
op: "summable-results",
|
||||
ids: ids,
|
||||
}
|
||||
});
|
||||
},
|
||||
success: function (response) {
|
||||
|
||||
/**
|
||||
* Aggiornamento dei campi summable
|
||||
*/
|
||||
updateFooterForSelectedRows: function () {
|
||||
let datatable = this.datatable;
|
||||
|
||||
this.getSelectedRowsFooter().then(function (response) {
|
||||
for (let [column, value] of Object.entries(response)) {
|
||||
let index = parseInt(column) + 1;
|
||||
let sel = datatable.column(index).footer();
|
||||
|
@ -471,7 +517,6 @@ function getTable(selector) {
|
|||
.attr("id", "summable")
|
||||
.html(value);
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
};
|
||||
|
|
|
@ -39,6 +39,8 @@
|
|||
"illuminate/database": "~5.4.0",
|
||||
"intervention/image": "^2.3",
|
||||
"league/csv": "^8.2",
|
||||
"league/oauth2-client": "^2.6",
|
||||
"league/oauth2-google": "^3.0",
|
||||
"maximebf/debugbar": "^1.15",
|
||||
"monolog/monolog": "^1.22",
|
||||
"mpdf/mpdf": "^v8.0.7",
|
||||
|
@ -55,6 +57,7 @@
|
|||
"symfony/polyfill-php70": "^1.8",
|
||||
"symfony/translation": "^3.3",
|
||||
"symfony/var-dumper": "^3.3",
|
||||
"thenetworg/oauth2-azure": "^2.0",
|
||||
"willdurand/geocoder": "^3.3"
|
||||
},
|
||||
"require-dev": {
|
||||
|
|
2
core.php
2
core.php
|
@ -55,7 +55,7 @@ $rootdir = ROOTDIR;
|
|||
$baseurl = BASEURL;
|
||||
|
||||
// Sicurezza della sessioni
|
||||
ini_set('session.cookie_samesite', 'strict');
|
||||
//ini_set('session.cookie_samesite', 'strict');
|
||||
ini_set('session.use_trans_sid', '0');
|
||||
ini_set('session.use_only_cookies', '1');
|
||||
|
||||
|
|
21
editor.php
21
editor.php
|
@ -119,30 +119,11 @@ if (empty($record) || !$has_access) {
|
|||
</a>
|
||||
</li>';
|
||||
|
||||
$hide_left_sidebar = Auth::check() && (setting('Nascondere la barra dei plugin di default'));
|
||||
|
||||
echo '
|
||||
|
||||
<li class="control-sidebar-toggle">
|
||||
<a data-toggle="control-sidebar" style="cursor: pointer">'.tr('Plugin').'</a>
|
||||
<a style="cursor: pointer">'.tr('Plugin').'</a>
|
||||
</li>
|
||||
|
||||
<script>
|
||||
$( document ).ready(function() {';
|
||||
|
||||
if (!empty($hide_left_sidebar)) {
|
||||
echo ' $(".control-sidebar").removeClass("control-sidebar-shown"); $("aside.content-wrapper, .main-footer").toggleClass("with-control-sidebar");';
|
||||
}
|
||||
|
||||
echo '
|
||||
$(".control-sidebar-toggle").bind("click", function() {
|
||||
$("aside.content-wrapper, .main-footer").toggleClass("with-control-sidebar");
|
||||
$(".control-sidebar").toggleClass("control-sidebar-shown");
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
</script>
|
||||
</ul>
|
||||
|
||||
<div class="tab-content">
|
||||
|
|
|
@ -26,7 +26,7 @@ if (Auth::check()) {
|
|||
</section><!-- /.content -->
|
||||
</aside><!-- /.content-wrapper -->
|
||||
|
||||
<footer class="main-footer '.(string_contains($_SERVER['SCRIPT_FILENAME'], 'editor.php') ? 'with-control-sidebar' : '').'">
|
||||
<footer class="main-footer">
|
||||
<a class="hidden-xs" href="'.tr('https://www.openstamanager.com').'" title="'.tr("Il gestionale open source per l'assistenza tecnica e la fatturazione").'." target="_blank"><strong>'.tr('OpenSTAManager').'</strong></a>
|
||||
<span class="pull-right hidden-xs">
|
||||
<strong>'.tr('Versione').'</strong> '.$version.'
|
||||
|
@ -59,7 +59,7 @@ if (Auth::check()) {
|
|||
</script>';
|
||||
}
|
||||
|
||||
$custom_css = setting('CSS Personalizzato');
|
||||
$custom_css = html_entity_decode( setting('CSS Personalizzato') );
|
||||
if (!empty($custom_css)) {
|
||||
echo '
|
||||
<style>'.$custom_css.'</style>';
|
||||
|
|
|
@ -115,7 +115,7 @@ if (Auth::check()) {
|
|||
'hookSingle' => tr('Hai 1 notifica'),
|
||||
'hookNone' => tr('Nessuna notifica'),
|
||||
'singleCalendar' => tr("E' presente un solo periodo!"),
|
||||
'noResults' => tr("Nessun elemento trovato"),
|
||||
'noResults' => tr('Nessun elemento trovato'),
|
||||
];
|
||||
foreach ($translations as $key => $value) {
|
||||
echo '
|
||||
|
@ -123,7 +123,7 @@ if (Auth::check()) {
|
|||
}
|
||||
echo '
|
||||
allegati: {
|
||||
messaggio: "'.tr("Clicca o trascina qui per caricare uno o più file").'",
|
||||
messaggio: "'.tr('Clicca o trascina qui per caricare uno o più file').'",
|
||||
maxFilesize: "'.tr('Max upload: _SIZE_ MB').'",
|
||||
errore: "'.tr('Errore').'",
|
||||
modifica: "'.tr('Modifica allegato').'",
|
||||
|
@ -206,6 +206,8 @@ if (Auth::check()) {
|
|||
end_date: "'.$_SESSION['period_end'].'",
|
||||
end_date_formatted: "'.Translator::dateToLocale($_SESSION['period_end']).'",
|
||||
|
||||
collapse_plugin_sidebar: '.intval(setting('Nascondere la barra dei plugin di default')).',
|
||||
|
||||
ckeditorToolbar: [
|
||||
["Undo","Redo","-","Cut","Copy","Paste","PasteText","PasteFromWord","-","SpellChecker", "Scayt", "-","Link","Unlink","-","Bold","Italic","Underline","Superscript","SpecialChar","HorizontalRule","-","JustifyLeft","JustifyCenter","JustifyRight","JustifyBlock","-","NumberedList","BulletedList","Outdent","Indent","Blockquote","-","Styles","Format","Image","Table", "TextColor", "BGColor" ],
|
||||
],
|
||||
|
@ -405,23 +407,23 @@ if (Auth::check()) {
|
|||
</ul>
|
||||
</li>
|
||||
|
||||
<li><a href="#" onclick="window.print()" class="tip nav-button" title="'.tr('Stampa').'">
|
||||
<li class="nav-button"><a href="#" onclick="window.print()" class="tip nav-button" title="'.tr('Stampa').'">
|
||||
<i class="fa fa-print"></i>
|
||||
</a></li>
|
||||
|
||||
<li><a href="'.base_path().'/bug.php" class="tip nav-button" title="'.tr('Segnalazione bug').'">
|
||||
<li class="nav-button"><a href="'.base_path().'/bug.php" class="tip nav-button" title="'.tr('Segnalazione bug').'">
|
||||
<i class="fa fa-bug"></i>
|
||||
</a></li>
|
||||
|
||||
<li><a href="'.base_path().'/log.php" class="tip nav-button" title="'.tr('Log accessi').'">
|
||||
<li class="nav-button"><a href="'.base_path().'/log.php" class="tip nav-button" title="'.tr('Log accessi').'">
|
||||
<i class="fa fa-book"></i>
|
||||
</a></li>
|
||||
|
||||
<li><a href="'.base_path().'/info.php" class="tip nav-button" title="'.tr('Informazioni').'">
|
||||
<li class="nav-button"><a href="'.base_path().'/info.php" class="tip nav-button" title="'.tr('Informazioni').'">
|
||||
<i class="fa fa-info"></i>
|
||||
</a></li>
|
||||
|
||||
<li><a href="'.base_path().'/index.php?op=logout" onclick="sessionStorage.clear()" class="bg-red tip" title="'.tr('Esci').'">
|
||||
<li class="nav-button"><a href="'.base_path().'/index.php?op=logout" onclick="sessionStorage.clear()" class="bg-red tip" title="'.tr('Esci').'">
|
||||
<i class="fa fa-power-off"></i>
|
||||
</a></li>
|
||||
</ul>
|
||||
|
@ -482,7 +484,7 @@ if (Auth::check()) {
|
|||
if (string_contains($_SERVER['SCRIPT_FILENAME'], 'editor.php')) {
|
||||
// Menu laterale per la visualizzazione dei plugin
|
||||
echo '
|
||||
<aside class="control-sidebar control-sidebar-light control-sidebar-shown">
|
||||
<aside class="control-sidebar control-sidebar-light">
|
||||
<h4 class="text-center">'.tr('Plugin disponibili').'</h4>
|
||||
<ul class="nav nav-tabs nav-pills nav-stacked">
|
||||
<li data-toggle="control-sidebar" class="active">
|
||||
|
@ -542,7 +544,7 @@ if (Auth::check()) {
|
|||
|
||||
echo '
|
||||
<!-- Right side column. Contains the navbar and content of the page -->
|
||||
<aside class="content-wrapper '.(string_contains($_SERVER['SCRIPT_FILENAME'], 'editor.php') ? 'with-control-sidebar' : '').'">
|
||||
<aside class="content-wrapper">
|
||||
|
||||
<!-- Main content -->
|
||||
<section class="content">
|
||||
|
|
2
mail.php
2
mail.php
|
@ -159,7 +159,7 @@ echo '
|
|||
<script>
|
||||
var emails = [];
|
||||
var id_anagrafica = "'.$id_anagrafica.'";
|
||||
var pec = "'.$smtp['pec']. '";
|
||||
var pec = "'.$smtp['pec'].'";
|
||||
|
||||
$(document).ready(function() {
|
||||
// Auto-completamento destinatario
|
||||
|
|
|
@ -34,6 +34,9 @@ class Account extends Model
|
|||
|
||||
protected $table = 'em_accounts';
|
||||
|
||||
/** @var OAuth2 */
|
||||
protected $gestoreOAuth2;
|
||||
|
||||
public function testConnection()
|
||||
{
|
||||
// Impostazione di connected_at a NULL
|
||||
|
@ -54,6 +57,17 @@ class Account extends Model
|
|||
return $result;
|
||||
}
|
||||
|
||||
public function getGestoreOAuth2()
|
||||
{
|
||||
if (isset($this->gestoreOAuth2)) {
|
||||
return $this->gestoreOAuth2;
|
||||
}
|
||||
|
||||
$this->gestoreOAuth2 = new OAuth2($this);
|
||||
|
||||
return $this->gestoreOAuth2;
|
||||
}
|
||||
|
||||
/* Relazioni Eloquent */
|
||||
|
||||
public function templates()
|
||||
|
|
|
@ -0,0 +1,198 @@
|
|||
<?php
|
||||
|
||||
namespace Modules\Emails;
|
||||
|
||||
use InvalidArgumentException;
|
||||
use League\OAuth2\Client\Provider\Exception\IdentityProviderException;
|
||||
use League\OAuth2\Client\Provider\Google;
|
||||
use League\OAuth2\Client\Token\AccessToken;
|
||||
use TheNetworg\OAuth2\Client\Provider\Azure;
|
||||
|
||||
class OAuth2
|
||||
{
|
||||
public static $providers = [
|
||||
'microsoft' => [
|
||||
'name' => 'Microsoft',
|
||||
'class' => Azure::class,
|
||||
'options' => [
|
||||
'scope' => [
|
||||
'offline_access',
|
||||
'https://graph.microsoft.com/SMTP.Send',
|
||||
//'https://outlook.office.com/IMAP.AccessAsUser.All'
|
||||
],
|
||||
],
|
||||
'help' => 'https://docs.openstamanager.com/faq/configurazione-oauth2#microsoft',
|
||||
],
|
||||
'google' => [
|
||||
'name' => 'Google',
|
||||
'class' => Google::class,
|
||||
'options' => [
|
||||
'scope' => ['https://mail.google.com/'],
|
||||
'accessType' => 'offline',
|
||||
],
|
||||
'help' => 'https://docs.openstamanager.com/faq/configurazione-oauth2#google',
|
||||
],
|
||||
];
|
||||
|
||||
protected $provider;
|
||||
protected $account;
|
||||
|
||||
public function __construct(Account $account)
|
||||
{
|
||||
$this->account = $account;
|
||||
|
||||
$this->init();
|
||||
}
|
||||
|
||||
/**
|
||||
* Inizializza il provider per l'autenticazione OAuth2.
|
||||
*/
|
||||
public function init()
|
||||
{
|
||||
$redirect_uri = base_url().'/oauth2.php';
|
||||
|
||||
$class = $this->getProviderConfiguration()['class'];
|
||||
|
||||
// Authorization
|
||||
$this->provider = new $class([
|
||||
'clientId' => $this->account->client_id,
|
||||
'clientSecret' => $this->account->client_secret,
|
||||
'redirectUri' => $redirect_uri,
|
||||
'accessType' => 'offline',
|
||||
]);
|
||||
|
||||
// Configurazioni specifiche per il provider di Microsoft Azure
|
||||
if ($this->provider instanceof Azure) {
|
||||
$this->provider->defaultEndPointVersion = Azure::ENDPOINT_VERSION_2_0;
|
||||
$this->provider->tenant = 'consumers';
|
||||
}
|
||||
}
|
||||
|
||||
public function getProvider()
|
||||
{
|
||||
return $this->provider;
|
||||
}
|
||||
|
||||
public function getProviderConfiguration()
|
||||
{
|
||||
return self::$providers[$this->account->provider];
|
||||
}
|
||||
|
||||
public function needsConfiguration()
|
||||
{
|
||||
$access_token = $this->getAccessToken();
|
||||
|
||||
return empty($access_token);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gestisce le operazioni di configurazione per l'autenticazione OAuth2.
|
||||
* Restituisce l'URL di redirect per le operazioni di aggiornamento dei dati, lancia un eccezione in caso di errori e restituisce null in caso di completamento della configurazione.
|
||||
*
|
||||
* Nota: l'autenticazione OAuth2 richiede una serie di richieste su una singola pagina
|
||||
* - Richiesta di autenticazione al server remoto (code, state vuoti)
|
||||
* - Conferma di autenticazione alla pagina di redirect (code, state impostati)
|
||||
* - Richiesta del token di accesso dalla pagina di redirect al server remoto
|
||||
*
|
||||
* @param string|null $code
|
||||
* @param string|null $state
|
||||
*
|
||||
* @throws IdentityProviderException
|
||||
* @throws InvalidArgumentException
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function configure($code, $state)
|
||||
{
|
||||
if (!$this->needsConfiguration()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$provider = $this->getProvider();
|
||||
$options = $this->getProviderConfiguration()['options'];
|
||||
if (empty($code)) {
|
||||
// Fetch the authorization URL from the provider; this returns the
|
||||
// urlAuthorize option and generates and applies any necessary parameters
|
||||
// (e.g. state).
|
||||
$authorization_url = $provider->getAuthorizationUrl($options);
|
||||
|
||||
// Get the state generated for you and store it to the session.
|
||||
$this->account->oauth2_state = $provider->getState();
|
||||
$this->account->save();
|
||||
|
||||
// Redirect the user to the authorization URL.
|
||||
return $authorization_url;
|
||||
} elseif (!empty($this->account->oauth2_state) && $this->account->oauth2_state !== $state) {
|
||||
$this->account->oauth2_state = null;
|
||||
$this->account->save();
|
||||
|
||||
throw new InvalidArgumentException();
|
||||
} else {
|
||||
$this->account->oauth2_state = null;
|
||||
$this->account->save();
|
||||
|
||||
// Try to get an access token using the authorization code grant
|
||||
$access_token = $provider->getAccessToken('authorization_code', [
|
||||
'code' => $code,
|
||||
]);
|
||||
$refresh_token = $access_token->getRefreshToken();
|
||||
|
||||
$this->updateTokens($access_token, $refresh_token);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public function getRefreshToken()
|
||||
{
|
||||
$this->checkTokens();
|
||||
|
||||
return $this->account->refresh_token;
|
||||
}
|
||||
|
||||
/**
|
||||
* Restituisce l'access token per l'autenticazione OAuth2.
|
||||
*
|
||||
* @return AccessToken|null
|
||||
*/
|
||||
public function getAccessToken()
|
||||
{
|
||||
$this->checkTokens();
|
||||
|
||||
return unserialize($this->account->access_token);
|
||||
}
|
||||
|
||||
/**
|
||||
* Imposta l'access token per l'autenticazione OAuth2.
|
||||
*
|
||||
* @param AccessToken|null
|
||||
*/
|
||||
public function updateTokens($access_token, $refresh_token)
|
||||
{
|
||||
$this->account->access_token = serialize($access_token);
|
||||
$this->account->refresh_token = $refresh_token;
|
||||
$this->account->save();
|
||||
}
|
||||
|
||||
protected function checkTokens()
|
||||
{
|
||||
$access_token = unserialize($this->account->access_token);
|
||||
|
||||
if (!empty($access_token) && $access_token->hasExpired()) {
|
||||
// Tentativo di refresh del token di accesso
|
||||
$refresh_token = $this->account->refresh_token;
|
||||
if (!empty($refresh_token)) {
|
||||
$access_token = $this->getProvider()->getAccessToken('refresh_token', [
|
||||
'refresh_token' => $this->account->refresh_token,
|
||||
]);
|
||||
|
||||
$refresh_token = $access_token->getRefreshToken();
|
||||
} else {
|
||||
$access_token = null;
|
||||
$refresh_token = null;
|
||||
}
|
||||
|
||||
$this->updateTokens($access_token, $refresh_token);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -414,6 +414,17 @@ $operations['registrazione-contabile'] = [
|
|||
],
|
||||
];
|
||||
|
||||
$operations['exportFE-bulk'] = [
|
||||
'text' => '<span class="'.((!extension_loaded('zip')) ? 'text-muted disabled' : '').'"><i class="fa fa-file-archive-o"></i> '.tr('Esporta stampe FE').'</span>',
|
||||
'data' => [
|
||||
'title' => '',
|
||||
'msg' => tr('Vuoi davvero esportare i PDF delle fatture elettroniche selezionate in un archivio ZIP?'),
|
||||
'button' => tr('Procedi'),
|
||||
'class' => 'btn btn-lg btn-warning',
|
||||
'blank' => true,
|
||||
],
|
||||
];
|
||||
|
||||
if ($module->name == 'Fatture di vendita') {
|
||||
$operations['genera-xml'] = [
|
||||
'text' => '<span><i class="fa fa-file-code-o"></i> '.tr('Genera fatture elettroniche').'</span>',
|
||||
|
@ -437,17 +448,6 @@ if ($module->name == 'Fatture di vendita') {
|
|||
],
|
||||
];
|
||||
|
||||
$operations['exportFE-bulk'] = [
|
||||
'text' => '<span class="'.((!extension_loaded('zip')) ? 'text-muted disabled' : '').'"><i class="fa fa-file-archive-o"></i> '.tr('Esporta stampe FE').'</span>',
|
||||
'data' => [
|
||||
'title' => '',
|
||||
'msg' => tr('Vuoi davvero esportare i PDF delle fatture elettroniche selezionate in un archivio ZIP?'),
|
||||
'button' => tr('Procedi'),
|
||||
'class' => 'btn btn-lg btn-warning',
|
||||
'blank' => true,
|
||||
],
|
||||
];
|
||||
|
||||
$operations['check-bulk'] = [
|
||||
'text' => '<span><i class="fa fa-list-alt"></i> '.tr('Controlla fatture elettroniche').'</span>',
|
||||
'data' => [
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
|
||||
include_once __DIR__.'/../../core.php';
|
||||
|
||||
switch (post('op')) {
|
||||
switch (filter('op')) {
|
||||
case 'add':
|
||||
$dbo->insert('em_accounts', [
|
||||
'name' => post('name'),
|
||||
|
@ -39,6 +39,8 @@ switch (post('op')) {
|
|||
$dbo->query('UPDATE em_accounts SET predefined = 0');
|
||||
}
|
||||
|
||||
$abilita_oauth2 = post('abilita_oauth2');
|
||||
|
||||
$dbo->update('em_accounts', [
|
||||
'name' => post('name'),
|
||||
'note' => post('note'),
|
||||
|
@ -53,10 +55,24 @@ switch (post('op')) {
|
|||
'timeout' => post('timeout'),
|
||||
'ssl_no_verify' => post('ssl_no_verify'),
|
||||
'predefined' => $predefined,
|
||||
'provider' => post('provider'),
|
||||
'client_id' => post('client_id'),
|
||||
'client_secret' => post('client_secret'),
|
||||
], ['id' => $id_record]);
|
||||
|
||||
flash()->info(tr('Informazioni salvate correttamente!'));
|
||||
|
||||
// Rimozione informazioni OAuth2 in caso di disabilitazione
|
||||
if (!$abilita_oauth2) {
|
||||
$dbo->update('em_accounts', [
|
||||
'provider' => null,
|
||||
'client_id' => null,
|
||||
'client_secret' => null,
|
||||
'access_token' => null,
|
||||
'refresh_token' => null,
|
||||
], ['id' => $id_record]);
|
||||
}
|
||||
|
||||
// Validazione indirizzo email mittente
|
||||
$check_email = Validate::isValidEmail(post('from_address'));
|
||||
|
||||
|
@ -96,5 +112,11 @@ switch (post('op')) {
|
|||
|
||||
flash()->info(tr('Account email eliminato!'));
|
||||
|
||||
break;
|
||||
|
||||
case 'oauth2':
|
||||
$redirect = base_path().'/oauth2.php?id_account='.$account->id;
|
||||
redirect($redirect);
|
||||
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -17,9 +17,11 @@
|
|||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
use Modules\Emails\OAuth2;
|
||||
|
||||
include_once __DIR__.'/../../core.php';
|
||||
|
||||
?>
|
||||
echo '
|
||||
<form action="" method="post" id="edit-form">
|
||||
<input type="hidden" name="op" value="update">
|
||||
<input type="hidden" name="backto" value="record-edit">
|
||||
|
@ -27,35 +29,35 @@ include_once __DIR__.'/../../core.php';
|
|||
<!-- DATI -->
|
||||
<div class="panel panel-primary">
|
||||
<div class="panel-heading">
|
||||
<h3 class="panel-title"><?php echo tr('Dati'); ?></h3>
|
||||
<h3 class="panel-title">'.tr('Dati').'</h3>
|
||||
</div>
|
||||
|
||||
<div class="panel-body">
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
{[ "type": "text", "label": "<?php echo tr('Nome account'); ?>", "name": "name", "value": "$name$", "required": 1 ]}
|
||||
{[ "type": "text", "label": "'.tr('Nome account').'", "name": "name", "value": "$name$", "required": 1 ]}
|
||||
</div>
|
||||
|
||||
<div class="col-md-3">
|
||||
{[ "type": "checkbox", "label": "<?php echo tr('Indirizzo PEC'); ?>", "name": "pec", "value": "$pec$" ]}
|
||||
{[ "type": "checkbox", "label": "'.tr('Indirizzo PEC').'", "name": "pec", "value": "$pec$" ]}
|
||||
</div>
|
||||
|
||||
<div class="col-md-3">
|
||||
{[ "type": "checkbox", "label": "<?php echo tr('Indirizzo predefinito'); ?>", "name": "predefined", "value": "$predefined$", "help": "<?php echo tr('Account da utilizzare per l\'invio di tutte le email dal gestionale.'); ?>" ]}
|
||||
{[ "type": "checkbox", "label": "'.tr('Indirizzo predefinito').'", "name": "predefined", "value": "$predefined$", "help": "'.tr('Account da utilizzare per l\'invio di tutte le email dal gestionale.').'" ]}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
{[ "type": "text", "label": "<?php echo tr('Nome visualizzato'); ?>", "name": "from_name", "value": "$from_name$" ]}
|
||||
{[ "type": "text", "label": "'.tr('Nome visualizzato').'", "name": "from_name", "value": "$from_name$" ]}
|
||||
</div>
|
||||
|
||||
<div class="col-md-3">
|
||||
{[ "type": "email", "label": "<?php echo tr('Email mittente'); ?>", "name": "from_address", "value": "$from_address$", "required": 1 ]}
|
||||
{[ "type": "email", "label": "'.tr('Email mittente').'", "name": "from_address", "value": "$from_address$", "required": 1 ]}
|
||||
</div>
|
||||
|
||||
<div class="col-md-3">
|
||||
{[ "type": "checkbox", "label": "<?php echo tr('Non verificare il certificato SSL'); ?>", "name": "ssl_no_verify", "value": "$ssl_no_verify$" ]}
|
||||
{[ "type": "checkbox", "label": "'.tr('Non verificare il certificato SSL').'", "name": "ssl_no_verify", "value": "$ssl_no_verify$" ]}
|
||||
</div>
|
||||
|
||||
|
||||
|
@ -63,44 +65,119 @@ include_once __DIR__.'/../../core.php';
|
|||
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
{[ "type": "text", "label": "<?php echo tr('Server SMTP'); ?>", "name": "server", "required": 1, "value": "$server$" ]}
|
||||
{[ "type": "text", "label": "'.tr('Server SMTP').'", "name": "server", "required": 1, "value": "$server$" ]}
|
||||
</div>
|
||||
|
||||
<div class="col-md-3">
|
||||
{[ "type": "number", "label": "<?php echo tr('Porta SMTP'); ?>", "name": "port", "required": 1, "class": "text-center", "decimals":"0", "max-value":"65535", "value": "$port$" ]}
|
||||
{[ "type": "number", "label": "'.tr('Porta SMTP').'", "name": "port", "required": 1, "class": "text-center", "decimals":"0", "max-value":"65535", "value": "$port$" ]}
|
||||
</div>
|
||||
|
||||
<div class="col-md-3">
|
||||
{[ "type": "select", "label": "<?php echo tr('Sicurezza SMTP'); ?>", "name": "encryption", "values": "list=\"\": \"<?php echo tr('Nessuna'); ?>\", \"tls\": \"TLS\", \"ssl\": \"SSL\"", "value": "$encryption$" ]}
|
||||
{[ "type": "select", "label": "'.tr('Sicurezza SMTP').'", "name": "encryption", "values": "list=\"\": \"'.tr('Nessuna').'\", \"tls\": \"TLS\", \"ssl\": \"SSL\"", "value": "$encryption$" ]}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
{[ "type": "text", "label": "<?php echo tr('Username SMTP'); ?>", "name": "username", "value": "$username$" ]}
|
||||
{[ "type": "text", "label": "'.tr('Username SMTP').'", "name": "username", "value": "$username$" ]}
|
||||
</div>
|
||||
|
||||
<div class="col-md-3">
|
||||
{[ "type": "password", "label": "<?php echo tr('Password SMTP'); ?>", "name": "password", "value": "$password$" ]}
|
||||
{[ "type": "password", "label": "'.tr('Password SMTP').'", "name": "password", "value": "$password$" ]}
|
||||
</div>
|
||||
|
||||
<div class="col-md-3">
|
||||
{[ "type": "number", "label": "<?php echo tr('Timeout coda di invio (millisecondi)'); ?>", "name": "timeout", "value": "$timeout$", "decimals": 1, "min-value": 100 ]}
|
||||
{[ "type": "number", "label": "'.tr('Timeout coda di invio (millisecondi)').'", "name": "timeout", "value": "$timeout$", "decimals": 1, "min-value": 100 ]}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
{[ "type": "textarea", "label": "<?php echo tr('Note'); ?>", "name": "note", "value": "$note$" ]}
|
||||
{[ "type": "textarea", "label": "'.tr('Note').'", "name": "note", "value": "$note$" ]}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>';
|
||||
|
||||
// Elenco provider disponibili
|
||||
$providers = OAuth2::$providers;
|
||||
$elenco_provider = [];
|
||||
foreach ($providers as $key => $provider) {
|
||||
$elenco_provider[] = [
|
||||
'id' => $key,
|
||||
'text' => $provider['name'],
|
||||
'help' => $provider['help'],
|
||||
];
|
||||
}
|
||||
|
||||
echo '
|
||||
<!-- OAuth2 -->
|
||||
<div class="box box-info">
|
||||
<div class="box-header">
|
||||
<h3 class="box-title">'.tr('OAuth2').'</h3>
|
||||
</div>
|
||||
|
||||
<div class="box-body">
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<span class="label label-warning pull-right hidden" id="guida-configurazione"></span>
|
||||
{[ "type": "select", "label": "'.tr('Provider account').'", "name": "provider", "value": "$provider$", "values": '.json_encode($elenco_provider).', "disabled": "'.intval(empty($account->provider)).'" ]}
|
||||
</div>
|
||||
|
||||
<div class="col-md-3">
|
||||
{[ "type": "checkbox", "label": "'.tr('Abilita OAuth2').'", "name": "abilita_oauth2", "value": "'.intval(!empty($account->provider)).'" ]}
|
||||
</div>
|
||||
|
||||
<div class="col-md-3">
|
||||
<a type="button" class="btn btn-success btn-block '.(empty($account->provider) || empty($account->client_id) || empty($account->client_secret) ? 'disabled' : '').'" style="margin-top: 25px" href="'.base_url().'/editor.php?id_module='.$id_module.'&id_record='.$id_record.'&op=oauth2">
|
||||
<i class="fa fa-refresh"></i> '.(empty($account->access_token) ? tr('Completa configurazione') : tr('Ripeti configurazione')).'
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="col-md-6">
|
||||
{[ "type": "text", "label": "'.tr('Client ID').'", "name": "client_id", "value": "$client_id$", "disabled": "'.intval(empty($account->provider)).'" ]}
|
||||
</div>
|
||||
|
||||
<div class="col-md-6">
|
||||
{[ "type": "text", "label": "'.tr('Client Secret').'", "name": "client_secret", "value": "$client_secret$", "disabled": "'.intval(empty($account->provider)).'" ]}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<?php
|
||||
<script>
|
||||
var abilita_oauth2 = input("abilita_oauth2");
|
||||
var provider = input("provider");
|
||||
var client_id = input("client_id");
|
||||
var client_secret = input("client_secret");
|
||||
var guida = $("#guida-configurazione");
|
||||
|
||||
abilita_oauth2.change(function() {
|
||||
const disable = !abilita_oauth2.get();
|
||||
provider.setDisabled(disable);
|
||||
|
||||
client_id.setDisabled(disable);
|
||||
client_secret.setDisabled(disable);
|
||||
});
|
||||
|
||||
provider.change(function() {
|
||||
const data = provider.getData();
|
||||
|
||||
if (data.id) {
|
||||
guida.removeClass("hidden");
|
||||
guida.html(`<a href="${data.help}">'.tr('Istruzioni di configurazione').' <i class="fa fa-external-link"></i></a>`);
|
||||
} else {
|
||||
guida.addClass("hidden");
|
||||
}
|
||||
})
|
||||
|
||||
$(document).ready(function() {
|
||||
provider.trigger("change");
|
||||
})
|
||||
</script>';
|
||||
|
||||
// Collegamenti diretti
|
||||
// Template email collegati a questo account
|
||||
$elementi = $dbo->fetchArray('SELECT `id`, `name` FROM `em_templates` WHERE `id_account` = '.prepare($id_record));
|
||||
|
@ -134,4 +211,3 @@ if (!empty($elementi)) {
|
|||
<i class="fa fa-trash"></i> '.tr('Elimina').'
|
||||
</a>';
|
||||
}
|
||||
?>
|
||||
|
|
|
@ -0,0 +1,53 @@
|
|||
<?php
|
||||
|
||||
use Models\Module;
|
||||
use Modules\Emails\Account;
|
||||
use Modules\Emails\OAuth2;
|
||||
|
||||
$skip_permissions = true;
|
||||
include_once __DIR__.'/core.php';
|
||||
session_write_close();
|
||||
|
||||
// Authorization information
|
||||
$state = $_GET['state'];
|
||||
$code = $_GET['code'];
|
||||
|
||||
// Account individuato via oauth2_state
|
||||
if (!empty($state)) {
|
||||
$account = Account::where('oauth2_state', '=', $state)
|
||||
->first();
|
||||
} else {
|
||||
$account = Account::find(get('id_account'));
|
||||
|
||||
// Impostazione access token a null per reimpostare la configurazione
|
||||
$account->access_token = null;
|
||||
$account->refresh_token = null;
|
||||
$account->save();
|
||||
}
|
||||
|
||||
if (empty($account)) {
|
||||
echo tr('Errore durante il completamento della configurazione: account non trovato');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Inizializzazione
|
||||
$oauth2 = new OAuth2($account);
|
||||
|
||||
// Redirect all'URL di autorizzazione del servizio esterno
|
||||
$redirect = $oauth2->configure($code, $state);
|
||||
|
||||
// Redirect automatico al record
|
||||
if (empty($redirect)) {
|
||||
$modulo_account_email = Module::pool('Account email');
|
||||
$redirect = base_path().'/editor.php?id_module='.$modulo_account_email->id.'&id_record='.$account->id;
|
||||
}
|
||||
|
||||
if (empty($_GET['error'])) {
|
||||
redirect($redirect);
|
||||
exit();
|
||||
} else {
|
||||
echo $_GET['error'].'<br>'.$_GET['error_description'].'
|
||||
<br><br>
|
||||
<a href="'.$redirect.'">'.tr('Riprova').'</a>';
|
||||
}
|
|
@ -141,7 +141,7 @@ class FileManager implements ManagerInterface
|
|||
<i class="fa fa-external-link"></i> '.$r['name'].'
|
||||
</a>
|
||||
|
||||
<small> ('.$file->extension.')'.((!empty($file->size)) ? ' ('. FileSystem::formatBytes($file->size).')' : '').' '.(((setting('Logo stampe') == $r['filename']) || (setting('Filigrana stampe') == $r['filename'])) ? '<i class="fa fa-file-text-o"></i>' : '').'</small>'.'
|
||||
<small> ('.$file->extension.')'.((!empty($file->size)) ? ' ('.FileSystem::formatBytes($file->size).')' : '').' '.(((setting('Logo stampe') == $r['filename']) || (setting('Filigrana stampe') == $r['filename'])) ? '<i class="fa fa-file-text-o"></i>' : '').'</small>'.'
|
||||
</td>
|
||||
|
||||
<td>'.timestampFormat($r['created_at']).'</td>
|
||||
|
|
|
@ -23,6 +23,8 @@ use Modules\Emails\Account;
|
|||
use Modules\Emails\Mail;
|
||||
use PHPMailer\PHPMailer\Exception;
|
||||
use PHPMailer\PHPMailer\PHPMailer;
|
||||
use PHPMailer\PHPMailer\OAuth;
|
||||
use PHPMailer\PHPMailer\SMTP;
|
||||
use Prints;
|
||||
use Uploads;
|
||||
|
||||
|
@ -35,45 +37,63 @@ class EmailNotification extends PHPMailer implements NotificationInterface
|
|||
|
||||
public function __construct($account = null, $exceptions = null)
|
||||
{
|
||||
parent::__construct($exceptions);
|
||||
parent::__construct(true);
|
||||
|
||||
$this->CharSet = 'UTF-8';
|
||||
|
||||
// Configurazione di base
|
||||
$config = Account::find($account);
|
||||
if (empty($config)) {
|
||||
$config = Account::where('predefined', true)->first();
|
||||
$account = $account instanceof Account ? $account : Account::find($account);
|
||||
if (empty($account)) {
|
||||
$account = Account::where('predefined', true)->first();
|
||||
}
|
||||
|
||||
// Preparazione email
|
||||
$this->IsHTML(true);
|
||||
|
||||
if (!empty($config['server'])) {
|
||||
$this->IsSMTP(true);
|
||||
if (!empty($account['server'])) {
|
||||
$this->IsSMTP();
|
||||
|
||||
// Impostazioni di debug
|
||||
$this->SMTPDebug = \App::debug() ? 2 : 0;
|
||||
$this->SMTPDebug = 2;
|
||||
$this->Debugoutput = function ($str, $level) {
|
||||
$this->infos[] = $str;
|
||||
};
|
||||
|
||||
// Impostazioni dell'host
|
||||
$this->Host = $config['server'];
|
||||
$this->Port = $config['port'];
|
||||
$this->Host = $account['server'];
|
||||
$this->Port = $account['port'];
|
||||
|
||||
// Impostazioni di autenticazione
|
||||
if (!empty($config['username'])) {
|
||||
if (!empty($account['username'])) {
|
||||
$this->SMTPAuth = true;
|
||||
$this->Username = $config['username'];
|
||||
$this->Password = $config['password'];
|
||||
$this->Username = $account['username'];
|
||||
|
||||
// Configurazione OAuth2
|
||||
if (!empty($account['access_token'])) {
|
||||
$oauth2 = $account->getGestoreOAuth2();
|
||||
|
||||
$this->AuthType = 'XOAUTH2';
|
||||
$this->setOAuth(
|
||||
new OAuth([
|
||||
'provider' => $oauth2->getProvider(),
|
||||
'refreshToken' => $oauth2->getRefreshToken(),
|
||||
'clientId' => $account->client_id,
|
||||
'clientSecret' => $account->client_secret,
|
||||
'userName' => $account->username,
|
||||
])
|
||||
);
|
||||
} else {
|
||||
$this->Password = $account['password'];
|
||||
}
|
||||
}
|
||||
|
||||
// Impostazioni di sicurezza
|
||||
if (in_array(strtolower($config['encryption']), ['ssl', 'tls'])) {
|
||||
$this->SMTPSecure = strtolower($config['encryption']);
|
||||
if (in_array(strtolower($account['encryption']), ['ssl', 'tls'])) {
|
||||
$this->SMTPSecure = strtolower($account['encryption']);
|
||||
}
|
||||
|
||||
if (!empty($config['ssl_no_verify'])) {
|
||||
// Disabilitazione verifica host
|
||||
if (!empty($account['ssl_no_verify'])) {
|
||||
$this->SMTPOptions = [
|
||||
'ssl' => [
|
||||
'verify_peer' => false,
|
||||
|
@ -84,8 +104,8 @@ class EmailNotification extends PHPMailer implements NotificationInterface
|
|||
}
|
||||
}
|
||||
|
||||
$this->From = $config['from_address'];
|
||||
$this->FromName = $config['from_name'];
|
||||
$this->From = $account['from_address'];
|
||||
$this->FromName = $account['from_name'];
|
||||
|
||||
$this->WordWrap = 78;
|
||||
}
|
||||
|
@ -192,6 +212,7 @@ class EmailNotification extends PHPMailer implements NotificationInterface
|
|||
// Segnalazione degli errori
|
||||
if (!$result) {
|
||||
$logger = logger();
|
||||
dd($this->infos);
|
||||
foreach ($this->infos as $info) {
|
||||
$logger->addRecord(\Monolog\Logger::ERROR, $info);
|
||||
}
|
||||
|
|
|
@ -167,7 +167,7 @@ class Query
|
|||
$search_filters = [];
|
||||
foreach ($search as $field => $original_value) {
|
||||
$pos = array_search($field, $total['fields']);
|
||||
$value = trim($original_value);
|
||||
$value = is_array($original_value) ? $original_value : trim($original_value);
|
||||
|
||||
if (isset($value) && $pos !== false) {
|
||||
$search_query = $total['search_inside'][$pos];
|
||||
|
|
|
@ -55,4 +55,3 @@ if (!empty($documento->idsede)) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -142,3 +142,11 @@ ALTER TABLE `dt_ddt` ADD `id_ddt_trasporto_interno` INT(11) NULL, ADD FOREIGN KE
|
|||
-- Aggiunto ragruppamento referenti per sede
|
||||
UPDATE `zz_plugins` SET `options` = ' { \"main_query\": [ { \"type\": \"table\", \"fields\": \"Nome, Indirizzo, Città, CAP, Provincia, Referente\", \"query\": \"SELECT an_sedi.id, an_sedi.nomesede AS Nome, an_sedi.indirizzo AS Indirizzo, an_sedi.citta AS Città, an_sedi.cap AS CAP, an_sedi.provincia AS Provincia, GROUP_CONCAT(an_referenti.nome SEPARATOR \\\", \\\") AS Referente FROM an_sedi LEFT OUTER JOIN an_referenti ON idsede = an_sedi.id WHERE 1=1 AND an_sedi.idanagrafica=|id_parent| GROUP BY an_sedi.id HAVING 2=2 ORDER BY an_sedi.id DESC\"} ]}' WHERE `zz_plugins`.`name` = 'Sedi';
|
||||
UPDATE `zz_group_module` SET `clause` = 'in_interventi.id IN (SELECT idintervento FROM in_interventi_tecnici WHERE idintervento=in_interventi.id AND idtecnico=|id_anagrafica| UNION SELECT id_intervento FROM in_interventi_tecnici_assegnati WHERE id_intervento=in_interventi.id AND id_tecnico=|id_anagrafica|)' WHERE `zz_group_module`.`name` = 'Mostra interventi ai tecnici coinvolti';
|
||||
|
||||
-- Aggiunto supporto autenticazione OAuth 2
|
||||
ALTER TABLE `em_accounts` ADD `provider` varchar(255),
|
||||
ADD `client_id` TEXT,
|
||||
ADD `client_secret` TEXT,
|
||||
ADD `oauth2_state` TEXT,
|
||||
ADD `access_token` TEXT,
|
||||
ADD `refresh_token` TEXT;
|
||||
|
|
Loading…
Reference in New Issue