Overhauling the module part, the way the actions are processed (see
setActions()), automatic method detection for these actions and some more.pull/18/head^2
parent
355daae51c
commit
90b1ba5705
|
@ -41,9 +41,10 @@ $allowed_types = array('servers', 'users', 'log', 'config', 'status');
|
||||||
if(!in_array($type, $allowed_types)) {
|
if(!in_array($type, $allowed_types)) {
|
||||||
$type = $allowed_types[0];
|
$type = $allowed_types[0];
|
||||||
}
|
}
|
||||||
|
$tpl = new \psm\Service\Template();
|
||||||
|
|
||||||
eval('$mod = new psm\Module\\'.ucfirst($type).'();');
|
eval('$mod = new psm\Module\\'.ucfirst($type).'($db, $tpl);');
|
||||||
// let the module prepare it's HTML code
|
// let the module prepare it's HTML code
|
||||||
$mod->createHTML();
|
$mod->initialize();
|
||||||
|
|
||||||
?>
|
?>
|
|
@ -26,13 +26,10 @@
|
||||||
**/
|
**/
|
||||||
|
|
||||||
namespace psm\Module;
|
namespace psm\Module;
|
||||||
|
use psm\Service\Database;
|
||||||
|
use psm\Service\Template;
|
||||||
|
|
||||||
abstract class Core {
|
abstract class AbstractModule implements ModuleInterface {
|
||||||
/**
|
|
||||||
* Custom message
|
|
||||||
* @var string $message
|
|
||||||
*/
|
|
||||||
public $message;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Current mode. Can be used by modules to determine
|
* Current mode. Can be used by modules to determine
|
||||||
|
@ -41,6 +38,27 @@ abstract class Core {
|
||||||
*/
|
*/
|
||||||
public $mode;
|
public $mode;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Current action
|
||||||
|
* @var string $action
|
||||||
|
*/
|
||||||
|
protected $action;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default action
|
||||||
|
* @var string $action_default
|
||||||
|
* @see setActions()
|
||||||
|
*/
|
||||||
|
protected $action_default;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Actions available for this module
|
||||||
|
* @var array $actions
|
||||||
|
* @see setActions()
|
||||||
|
* @see getAction()
|
||||||
|
*/
|
||||||
|
protected $actions = array();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add footer to page?
|
* Add footer to page?
|
||||||
* @var boolean $add_footer
|
* @var boolean $add_footer
|
||||||
|
@ -48,14 +66,21 @@ abstract class Core {
|
||||||
protected $add_footer = true;
|
protected $add_footer = true;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* smDatabase object
|
* Messages to show the user
|
||||||
* @var object $db
|
* @var array $messages
|
||||||
|
* @see getMessage()
|
||||||
|
*/
|
||||||
|
protected $messages = array();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Database object
|
||||||
|
* @var \psm\Service\Database $db
|
||||||
*/
|
*/
|
||||||
protected $db;
|
protected $db;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \psm\Template object
|
* Template object
|
||||||
* @var object $tpl
|
* @var \psm\Service\Template $tpl
|
||||||
*/
|
*/
|
||||||
protected $tpl;
|
protected $tpl;
|
||||||
|
|
||||||
|
@ -66,13 +91,48 @@ abstract class Core {
|
||||||
*/
|
*/
|
||||||
protected $tpl_id;
|
protected $tpl_id;
|
||||||
|
|
||||||
function __construct() {
|
function __construct(Database $db, Template $tpl) {
|
||||||
global $db;
|
$this->db = $db;
|
||||||
|
$this->tpl = $tpl;
|
||||||
|
}
|
||||||
|
|
||||||
$this->db = ($db) ? $db : new \psm\Service\Database();
|
/**
|
||||||
$this->tpl = new \psm\Service\Template();
|
* Initialize the module
|
||||||
|
*/
|
||||||
|
public function initialize() {
|
||||||
|
// yeh baby, "initialize" me..
|
||||||
|
// right, anyway, lets determine the aciton
|
||||||
|
$action = null;
|
||||||
|
|
||||||
|
if(isset($_GET['action'])) {
|
||||||
|
$action = $_GET['action'];
|
||||||
|
} elseif(isset($_POST['action'])) {
|
||||||
|
$action = $_POST['action'];
|
||||||
|
}
|
||||||
|
if($action !== null && in_array($action, $this->actions)) {
|
||||||
|
// we have an action
|
||||||
|
$this->initializeAction($action);
|
||||||
|
} elseif($this->action_default !== null) {
|
||||||
|
$this->initializeAction($this->action_default);
|
||||||
|
} else {
|
||||||
|
// else what..?
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->createHTML();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Run a specified action
|
||||||
|
*
|
||||||
|
* For it to run, the "execute$action" method must exist
|
||||||
|
* @param string $action
|
||||||
|
*/
|
||||||
|
protected function initializeAction($action) {
|
||||||
|
$this->action = $action;
|
||||||
|
$method = 'execute' . ucfirst($action);
|
||||||
|
if(method_exists($this, $method)) {
|
||||||
|
$this->$method();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -80,7 +140,7 @@ abstract class Core {
|
||||||
* First the createHTMLLabels() will be called to add all labels to the template,
|
* First the createHTMLLabels() will be called to add all labels to the template,
|
||||||
* Then the tpl_id set in $this->getTemplateId() will be added to the main template automatically
|
* Then the tpl_id set in $this->getTemplateId() will be added to the main template automatically
|
||||||
*/
|
*/
|
||||||
public function createHTML() {
|
protected function createHTML() {
|
||||||
// add footer to page?
|
// add footer to page?
|
||||||
if($this->add_footer) {
|
if($this->add_footer) {
|
||||||
$this->tpl->newTemplate('main_footer', 'main.tpl.html');
|
$this->tpl->newTemplate('main_footer', 'main.tpl.html');
|
||||||
|
@ -101,7 +161,7 @@ abstract class Core {
|
||||||
'main',
|
'main',
|
||||||
array(
|
array(
|
||||||
'content' => $this->tpl->getTemplate($this->getTemplateId()),
|
'content' => $this->tpl->getTemplate($this->getTemplateId()),
|
||||||
'message' => ($this->message == '') ? ' ' : $this->message,
|
'message' => (empty($this->messages)) ? ' ' : implode('<br/>', $this->messages),
|
||||||
'html_footer' => $html_footer,
|
'html_footer' => $html_footer,
|
||||||
'label_back_to_top' => psm_get_lang('system', 'back_to_top'),
|
'label_back_to_top' => psm_get_lang('system', 'back_to_top'),
|
||||||
)
|
)
|
||||||
|
@ -187,6 +247,51 @@ abstract class Core {
|
||||||
protected function addFooter($value) {
|
protected function addFooter($value) {
|
||||||
$this->add_footer = $value;
|
$this->add_footer = $value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set actions available
|
||||||
|
* @param string|array $actions
|
||||||
|
* @param string $default default action
|
||||||
|
* @param boolean $append if TRUE, the actions will be added to the current actions
|
||||||
|
* @return psm\Module\AbstractModule
|
||||||
|
* @see getAction()
|
||||||
|
*/
|
||||||
|
protected function setActions($actions, $default = null, $append = true) {
|
||||||
|
if(!is_array($actions)) {
|
||||||
|
$actions = array($actions);
|
||||||
|
}
|
||||||
|
if($append) {
|
||||||
|
$this->actions = array_merge($actions);
|
||||||
|
} else {
|
||||||
|
$this->actions = $actions;
|
||||||
|
}
|
||||||
|
if($default !== null) {
|
||||||
|
$this->action_default = $default;
|
||||||
|
}
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the current action
|
||||||
|
* @return string
|
||||||
|
* @see setActions()
|
||||||
|
*/
|
||||||
|
public function getAction() {
|
||||||
|
return $this->action;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add one or multiple message to the stack to be displayed to the user
|
||||||
|
* @param string|array $msg
|
||||||
|
* @return \psm\Module\AbstractModule
|
||||||
|
*/
|
||||||
|
public function addMessage($msg) {
|
||||||
|
if(!is_array($msg)) {
|
||||||
|
$msg = array($msg);
|
||||||
|
}
|
||||||
|
$this->messages = array_merge($this->messages, $msg);
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
?>
|
?>
|
|
@ -26,30 +26,25 @@
|
||||||
**/
|
**/
|
||||||
|
|
||||||
namespace psm\Module;
|
namespace psm\Module;
|
||||||
|
use psm\Service\Database;
|
||||||
|
use psm\Service\Template;
|
||||||
|
|
||||||
class Config extends Core {
|
class Config extends AbstractModule {
|
||||||
|
|
||||||
function __construct() {
|
function __construct(Database $db, Template $tpl) {
|
||||||
parent::__construct();
|
parent::__construct($db, $tpl);
|
||||||
|
|
||||||
if(!empty($_POST)) {
|
$this->setActions(array(
|
||||||
$this->executeSave();
|
'index', 'save',
|
||||||
}
|
), 'index');
|
||||||
}
|
|
||||||
|
|
||||||
// override parent::createHTML()
|
|
||||||
public function createHTML() {
|
|
||||||
$this->setTemplateId('config', 'config.tpl.html');
|
|
||||||
|
|
||||||
$this->populateFields();
|
|
||||||
|
|
||||||
return parent::createHTML();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Populate all the config fields with values from the database
|
* Populate all the config fields with values from the database
|
||||||
*/
|
*/
|
||||||
public function populateFields() {
|
protected function executeIndex() {
|
||||||
|
$this->setTemplateId('config', 'config.tpl.html');
|
||||||
|
|
||||||
$config_db = $this->db->select(
|
$config_db = $this->db->select(
|
||||||
PSM_DB_PREFIX . 'config',
|
PSM_DB_PREFIX . 'config',
|
||||||
null,
|
null,
|
||||||
|
@ -105,53 +100,56 @@ class Config extends Core {
|
||||||
* and save it to the database
|
* and save it to the database
|
||||||
*/
|
*/
|
||||||
protected function executeSave() {
|
protected function executeSave() {
|
||||||
// save new config
|
if(!empty($_POST)) {
|
||||||
$clean = array(
|
// save new config
|
||||||
'language' => $_POST['language'],
|
$clean = array(
|
||||||
'show_update' => (isset($_POST['show_update'])) ? '1' : '0',
|
'language' => $_POST['language'],
|
||||||
'email_status' => (isset($_POST['email_status'])) ? '1' : '0',
|
'show_update' => (isset($_POST['show_update'])) ? '1' : '0',
|
||||||
'email_from_name' => $_POST['email_from_name'],
|
'email_status' => (isset($_POST['email_status'])) ? '1' : '0',
|
||||||
'email_from_email' => $_POST['email_from_email'],
|
'email_from_name' => $_POST['email_from_name'],
|
||||||
'sms_status' => (isset($_POST['sms_status'])) ? '1' : '0',
|
'email_from_email' => $_POST['email_from_email'],
|
||||||
'sms_gateway' => $_POST['sms_gateway'],
|
'sms_status' => (isset($_POST['sms_status'])) ? '1' : '0',
|
||||||
'sms_gateway_username' => $_POST['sms_gateway_username'],
|
'sms_gateway' => $_POST['sms_gateway'],
|
||||||
'sms_gateway_password' => $_POST['sms_gateway_password'],
|
'sms_gateway_username' => $_POST['sms_gateway_username'],
|
||||||
'sms_from' => $_POST['sms_from'],
|
'sms_gateway_password' => $_POST['sms_gateway_password'],
|
||||||
'alert_type' => $_POST['alert_type'],
|
'sms_from' => $_POST['sms_from'],
|
||||||
'log_status' => (isset($_POST['log_status'])) ? '1' : '0',
|
'alert_type' => $_POST['alert_type'],
|
||||||
'log_email' => (isset($_POST['log_email'])) ? '1' : '0',
|
'log_status' => (isset($_POST['log_status'])) ? '1' : '0',
|
||||||
'log_sms' => (isset($_POST['log_sms'])) ? '1' : '0',
|
'log_email' => (isset($_POST['log_email'])) ? '1' : '0',
|
||||||
'auto_refresh_servers' => (isset($_POST['auto_refresh_servers'])) ? intval($_POST['auto_refresh_servers']) : '0',
|
'log_sms' => (isset($_POST['log_sms'])) ? '1' : '0',
|
||||||
);
|
'auto_refresh_servers' => (isset($_POST['auto_refresh_servers'])) ? intval($_POST['auto_refresh_servers']) : '0',
|
||||||
|
);
|
||||||
|
|
||||||
// save all values to the database
|
// save all values to the database
|
||||||
foreach($clean as $key => $value) {
|
foreach($clean as $key => $value) {
|
||||||
// check if key already exists, otherwise add it
|
// check if key already exists, otherwise add it
|
||||||
if(psm_get_conf($key) === null) {
|
if(psm_get_conf($key) === null) {
|
||||||
// not yet set, add it
|
// not yet set, add it
|
||||||
$this->db->save(
|
$this->db->save(
|
||||||
PSM_DB_PREFIX . 'config',
|
PSM_DB_PREFIX . 'config',
|
||||||
array(
|
array(
|
||||||
'key' => $key,
|
'key' => $key,
|
||||||
'value' => $value,
|
'value' => $value,
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
// update
|
// update
|
||||||
$this->db->save(
|
$this->db->save(
|
||||||
PSM_DB_PREFIX . 'config',
|
PSM_DB_PREFIX . 'config',
|
||||||
array('value' => $value),
|
array('value' => $value),
|
||||||
array('key' => $key)
|
array('key' => $key)
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->addMessage(psm_get_lang('config', 'updated'));
|
||||||
|
|
||||||
|
if($clean['language'] != psm_get_conf('language')) {
|
||||||
|
header('Location: ' . $_SERVER['REQUEST_URI']);
|
||||||
|
die();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
$this->initializeAction('index');
|
||||||
$this->message = psm_get_lang('config', 'updated');
|
|
||||||
|
|
||||||
if($clean['language'] != psm_get_conf('language')) {
|
|
||||||
header('Location: ' . $_SERVER['REQUEST_URI']);
|
|
||||||
die();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// override parent::createHTMLLabels()
|
// override parent::createHTMLLabels()
|
||||||
|
|
|
@ -26,27 +26,24 @@
|
||||||
**/
|
**/
|
||||||
|
|
||||||
namespace psm\Module;
|
namespace psm\Module;
|
||||||
|
use psm\Service\Database;
|
||||||
|
use psm\Service\Template;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Log module. Create the page to view previous log messages
|
* Log module. Create the page to view previous log messages
|
||||||
*/
|
*/
|
||||||
class Log extends Core {
|
class Log extends AbstractModule {
|
||||||
|
|
||||||
function __construct() {
|
function __construct(Database $db, Template $tpl) {
|
||||||
parent::__construct();
|
parent::__construct($db, $tpl);
|
||||||
}
|
|
||||||
|
|
||||||
// override parent::createHTML()
|
$this->setActions('index', 'index');
|
||||||
public function createHTML() {
|
|
||||||
$this->createHTMLList();
|
|
||||||
|
|
||||||
return parent::createHTML();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Prepare the template with a list of all log entries
|
* Prepare the template with a list of all log entries
|
||||||
*/
|
*/
|
||||||
protected function createHTMLList() {
|
protected function executeIndex() {
|
||||||
$this->setTemplateId('log_list', 'log.tpl.html');
|
$this->setTemplateId('log_list', 'log.tpl.html');
|
||||||
|
|
||||||
$entries = array();
|
$entries = array();
|
||||||
|
@ -97,7 +94,6 @@ class Log extends Core {
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -0,0 +1,46 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* PHP Server Monitor
|
||||||
|
* Monitor your servers and websites.
|
||||||
|
*
|
||||||
|
* This file is part of PHP Server Monitor.
|
||||||
|
* PHP Server Monitor 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.
|
||||||
|
*
|
||||||
|
* PHP Server Monitor 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 PHP Server Monitor. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* @package phpservermon
|
||||||
|
* @author Pepijn Over <pep@neanderthal-technology.com>
|
||||||
|
* @copyright Copyright (c) 2008-2014 Pepijn Over <pep@neanderthal-technology.com>
|
||||||
|
* @license http://www.gnu.org/licenses/gpl.txt GNU GPL v3
|
||||||
|
* @version Release: @package_version@
|
||||||
|
* @link http://phpservermon.neanderthal-technology.com/
|
||||||
|
* @since phpservermon 2.1
|
||||||
|
**/
|
||||||
|
|
||||||
|
namespace psm\Module;
|
||||||
|
use psm\Service\Database;
|
||||||
|
use psm\Service\Template;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Public API for all modules
|
||||||
|
*/
|
||||||
|
interface ModuleInterface {
|
||||||
|
|
||||||
|
public function __construct(Database $db, Template $tpl);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize the module
|
||||||
|
*/
|
||||||
|
public function initialize();
|
||||||
|
}
|
||||||
|
|
||||||
|
?>
|
|
@ -26,99 +26,26 @@
|
||||||
**/
|
**/
|
||||||
|
|
||||||
namespace psm\Module;
|
namespace psm\Module;
|
||||||
|
use psm\Service\Database;
|
||||||
|
use psm\Service\Template;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Server module. Add/edit/delete servers, show a list of all servers etc.
|
* Server module. Add/edit/delete servers, show a list of all servers etc.
|
||||||
*/
|
*/
|
||||||
class Servers extends Core {
|
class Servers extends AbstractModule {
|
||||||
|
|
||||||
function __construct() {
|
function __construct(Database $db, Template $tpl) {
|
||||||
parent::__construct();
|
parent::__construct($db, $tpl);
|
||||||
|
|
||||||
// check mode
|
$this->setActions(array(
|
||||||
if (isset($_GET['edit']) && is_numeric($_GET['edit'])) {
|
'index', 'edit', 'save', 'delete',
|
||||||
// edit mode or insert mode
|
), 'index');
|
||||||
$this->mode = 'update';
|
|
||||||
} else {
|
|
||||||
$this->mode = 'list';
|
|
||||||
|
|
||||||
if(!empty($_POST)) {
|
|
||||||
$this->executeSave();
|
|
||||||
}
|
|
||||||
if(isset($_GET['delete']) && is_numeric($_GET['delete'])) {
|
|
||||||
$this->executeDelete();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// override parent::createHTML()
|
|
||||||
public function createHTML() {
|
|
||||||
switch($this->mode) {
|
|
||||||
case 'list':
|
|
||||||
$this->createHTMLList();
|
|
||||||
break;
|
|
||||||
case 'update':
|
|
||||||
$this->createHTMLUpdate();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return parent::createHTML();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Prepare the template to show the update screen for a single server
|
|
||||||
*/
|
|
||||||
protected function createHTMLUpdate() {
|
|
||||||
$this->setTemplateId('servers_update', 'servers.tpl.html');
|
|
||||||
|
|
||||||
$server_id = $_GET['edit'];
|
|
||||||
|
|
||||||
$tpl_data = array();
|
|
||||||
|
|
||||||
switch(intval($server_id)) {
|
|
||||||
case 0:
|
|
||||||
// insert mode
|
|
||||||
$tpl_data['titlemode'] = psm_get_lang('system', 'insert');
|
|
||||||
$tpl_data['edit_server_id'] = '0';
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
// edit mode
|
|
||||||
|
|
||||||
// get server entry
|
|
||||||
$edit_server = $this->db->selectRow(
|
|
||||||
PSM_DB_PREFIX.'servers',
|
|
||||||
array('server_id' => $server_id)
|
|
||||||
);
|
|
||||||
if (empty($edit_server)) {
|
|
||||||
$this->message = 'Invalid server id';
|
|
||||||
return $this->createHTMLList();
|
|
||||||
}
|
|
||||||
|
|
||||||
$tpl_data = array_merge($tpl_data, array(
|
|
||||||
'titlemode' => psm_get_lang('system', 'edit') . ' ' . $edit_server['label'],
|
|
||||||
'edit_server_id' => $edit_server['server_id'],
|
|
||||||
'edit_value_label' => $edit_server['label'],
|
|
||||||
'edit_value_ip' => $edit_server['ip'],
|
|
||||||
'edit_value_port' => $edit_server['port'],
|
|
||||||
'edit_type_selected_' . $edit_server['type'] => 'selected="selected"',
|
|
||||||
'edit_active_selected_' . $edit_server['active'] => 'selected="selected"',
|
|
||||||
'edit_email_selected_' . $edit_server['email'] => 'selected="selected"',
|
|
||||||
'edit_sms_selected_' . $edit_server['sms'] => 'selected="selected"',
|
|
||||||
));
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->tpl->addTemplateData(
|
|
||||||
$this->getTemplateId(),
|
|
||||||
$tpl_data
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Prepare the template to show a list of all servers
|
* Prepare the template to show a list of all servers
|
||||||
*/
|
*/
|
||||||
protected function createHTMLList() {
|
protected function executeIndex() {
|
||||||
$this->setTemplateId('servers_list', 'servers.tpl.html');
|
$this->setTemplateId('servers_list', 'servers.tpl.html');
|
||||||
|
|
||||||
// get servers from database
|
// get servers from database
|
||||||
|
@ -171,7 +98,55 @@ class Servers extends Core {
|
||||||
$this->tpl->addTemplateData('main_auto_refresh', array('seconds' => $auto_refresh));
|
$this->tpl->addTemplateData('main_auto_refresh', array('seconds' => $auto_refresh));
|
||||||
$this->tpl->addTemplateData('main', array('auto_refresh' => $this->tpl->getTemplate('main_auto_refresh')));
|
$this->tpl->addTemplateData('main', array('auto_refresh' => $this->tpl->getTemplate('main_auto_refresh')));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prepare the template to show the update screen for a single server
|
||||||
|
*/
|
||||||
|
protected function executeEdit() {
|
||||||
|
$this->setTemplateId('servers_update', 'servers.tpl.html');
|
||||||
|
|
||||||
|
$server_id = isset($_GET['id']) ? intval($_GET['id']) : 0;
|
||||||
|
|
||||||
|
$tpl_data = array();
|
||||||
|
|
||||||
|
switch(intval($server_id)) {
|
||||||
|
case 0:
|
||||||
|
// insert mode
|
||||||
|
$tpl_data['titlemode'] = psm_get_lang('system', 'insert');
|
||||||
|
$tpl_data['edit_server_id'] = '0';
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// edit mode
|
||||||
|
// get server entry
|
||||||
|
$edit_server = $this->db->selectRow(
|
||||||
|
PSM_DB_PREFIX.'servers',
|
||||||
|
array('server_id' => $server_id)
|
||||||
|
);
|
||||||
|
if (empty($edit_server)) {
|
||||||
|
$this->addMessage('Invalid server id');
|
||||||
|
return $this->initializeAction('index');
|
||||||
|
}
|
||||||
|
|
||||||
|
$tpl_data = array_merge($tpl_data, array(
|
||||||
|
'titlemode' => psm_get_lang('system', 'edit') . ' ' . $edit_server['label'],
|
||||||
|
'edit_server_id' => $edit_server['server_id'],
|
||||||
|
'edit_value_label' => $edit_server['label'],
|
||||||
|
'edit_value_ip' => $edit_server['ip'],
|
||||||
|
'edit_value_port' => $edit_server['port'],
|
||||||
|
'edit_type_selected_' . $edit_server['type'] => 'selected="selected"',
|
||||||
|
'edit_active_selected_' . $edit_server['active'] => 'selected="selected"',
|
||||||
|
'edit_email_selected_' . $edit_server['email'] => 'selected="selected"',
|
||||||
|
'edit_sms_selected_' . $edit_server['sms'] => 'selected="selected"',
|
||||||
|
));
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->tpl->addTemplateData(
|
||||||
|
$this->getTemplateId(),
|
||||||
|
$tpl_data
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -179,11 +154,14 @@ class Servers extends Core {
|
||||||
*/
|
*/
|
||||||
protected function executeSave() {
|
protected function executeSave() {
|
||||||
// check for add/edit mode
|
// check for add/edit mode
|
||||||
if (isset($_POST['label']) && isset($_POST['ip']) && isset($_POST['port'])) {
|
if(isset($_POST['label']) && isset($_POST['ip']) && isset($_POST['port'])) {
|
||||||
|
$server_id = isset($_GET['id']) ? intval($_GET['id']) : 0;
|
||||||
|
|
||||||
$clean = array(
|
$clean = array(
|
||||||
'label' => strip_tags($_POST['label']),
|
'label' => strip_tags($_POST['label']),
|
||||||
'ip' => strip_tags($_POST['ip']),
|
'ip' => strip_tags($_POST['ip']),
|
||||||
'port' => strip_tags($_POST['port']),
|
'port' => strip_tags($_POST['port']),
|
||||||
|
// @todo validate the following values
|
||||||
'type' => $_POST['type'],
|
'type' => $_POST['type'],
|
||||||
'active' => $_POST['active'],
|
'active' => $_POST['active'],
|
||||||
'email' => $_POST['email'],
|
'email' => $_POST['email'],
|
||||||
|
@ -191,35 +169,40 @@ class Servers extends Core {
|
||||||
);
|
);
|
||||||
|
|
||||||
// check for edit or add
|
// check for edit or add
|
||||||
if ((int) $_POST['server_id'] > 0) {
|
if($server_id > 0) {
|
||||||
// edit
|
// edit
|
||||||
$this->db->save(
|
$this->db->save(
|
||||||
PSM_DB_PREFIX.'servers',
|
PSM_DB_PREFIX.'servers',
|
||||||
$clean,
|
$clean,
|
||||||
array('server_id' => $_POST['server_id'])
|
array('server_id' => $server_id)
|
||||||
);
|
);
|
||||||
$this->message = psm_get_lang('servers', 'updated');
|
$this->addMessage(psm_get_lang('servers', 'updated'));
|
||||||
} else {
|
} else {
|
||||||
// add
|
// add
|
||||||
$clean['status'] = 'on';
|
$clean['status'] = 'on';
|
||||||
$this->db->save(PSM_DB_PREFIX.'servers', $clean);
|
$this->db->save(PSM_DB_PREFIX.'servers', $clean);
|
||||||
$this->message = psm_get_lang('servers', 'inserted');
|
$this->addMessage(psm_get_lang('servers', 'inserted'));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
$this->initializeAction('index');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Executes the deletion of one of the servers
|
* Executes the deletion of one of the servers
|
||||||
*/
|
*/
|
||||||
protected function executeDelete() {
|
protected function executeDelete() {
|
||||||
// do delete
|
if(isset($_GET['id'])) {
|
||||||
$this->db->delete(
|
$id = intval($_GET['id']);
|
||||||
PSM_DB_PREFIX . 'servers',
|
// do delete
|
||||||
array(
|
$this->db->delete(
|
||||||
'server_id' => $_GET['delete']
|
PSM_DB_PREFIX . 'servers',
|
||||||
)
|
array(
|
||||||
);
|
'server_id' => $id,
|
||||||
$this->message = psm_get_lang('system', 'deleted');
|
)
|
||||||
|
);
|
||||||
|
$this->addMessage(psm_get_lang('system', 'deleted'));
|
||||||
|
}
|
||||||
|
$this->initializeAction('index');
|
||||||
}
|
}
|
||||||
|
|
||||||
// override parent::createHTMLLabels()
|
// override parent::createHTMLLabels()
|
||||||
|
|
|
@ -27,28 +27,25 @@
|
||||||
**/
|
**/
|
||||||
|
|
||||||
namespace psm\Module;
|
namespace psm\Module;
|
||||||
|
use psm\Service\Database;
|
||||||
|
use psm\Service\Template;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Status module
|
* Status module
|
||||||
*/
|
*/
|
||||||
class Status extends Core {
|
class Status extends AbstractModule {
|
||||||
|
|
||||||
function __construct() {
|
function __construct(Database $db, Template $tpl) {
|
||||||
parent::__construct();
|
parent::__construct($db, $tpl);
|
||||||
}
|
|
||||||
|
|
||||||
// override parent::createHTML()
|
$this->setActions('index', 'index');
|
||||||
public function createHTML() {
|
|
||||||
$this->createHTMLList();
|
|
||||||
|
|
||||||
return parent::createHTML();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Prepare the template to show a list of all servers
|
* Prepare the template to show a list of all servers
|
||||||
* @todo move the background colurs to the config
|
* @todo move the background colurs to the config
|
||||||
*/
|
*/
|
||||||
protected function createHTMLList() {
|
protected function executeIndex() {
|
||||||
$this->setTemplateId('status', 'status.tpl.html');
|
$this->setTemplateId('status', 'status.tpl.html');
|
||||||
$this->addFooter(false);
|
$this->addFooter(false);
|
||||||
|
|
||||||
|
|
|
@ -26,56 +26,33 @@
|
||||||
**/
|
**/
|
||||||
|
|
||||||
namespace psm\Module;
|
namespace psm\Module;
|
||||||
|
use psm\Service\Database;
|
||||||
|
use psm\Service\Template;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* User module. Add, edit and delete users, or assign
|
* User module. Add, edit and delete users, or assign
|
||||||
* servers to users.
|
* servers to users.
|
||||||
*/
|
*/
|
||||||
class Users extends Core {
|
class Users extends AbstractModule {
|
||||||
public $servers;
|
public $servers;
|
||||||
|
|
||||||
function __construct() {
|
function __construct(Database $db, Template $tpl) {
|
||||||
parent::__construct();
|
parent::__construct($db, $tpl);
|
||||||
|
|
||||||
// check mode
|
$this->setActions(array(
|
||||||
if (isset($_GET['edit']) && is_numeric($_GET['edit'])) {
|
'index', 'edit', 'delete', 'save',
|
||||||
// edit mode or insert mode
|
), 'index');
|
||||||
$this->mode = 'update';
|
|
||||||
} else {
|
|
||||||
$this->mode = 'list';
|
|
||||||
|
|
||||||
if(!empty($_POST)) {
|
|
||||||
$this->executeSave();
|
|
||||||
}
|
|
||||||
if(isset($_GET['delete']) && is_numeric($_GET['delete'])) {
|
|
||||||
$this->executeDelete();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->servers = $this->db->select(PSM_DB_PREFIX.'servers', null, array('server_id', 'label'));
|
$this->servers = $this->db->select(PSM_DB_PREFIX.'servers', null, array('server_id', 'label'));
|
||||||
}
|
}
|
||||||
|
|
||||||
// override parent::createHTML()
|
|
||||||
public function createHTML() {
|
|
||||||
switch($this->mode) {
|
|
||||||
case 'list':
|
|
||||||
$this->createHTMLList();
|
|
||||||
break;
|
|
||||||
case 'update':
|
|
||||||
$this->createHTMLUpdate();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return parent::createHTML();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Prepare the template to show the update screen for a user
|
* Prepare the template to show the update screen for a user
|
||||||
*/
|
*/
|
||||||
protected function createHTMLUpdate() {
|
protected function executeEdit() {
|
||||||
$this->setTemplateId('users_update', 'users.tpl.html');
|
$this->setTemplateId('users_update', 'users.tpl.html');
|
||||||
|
|
||||||
$user_id = $_GET['edit'];
|
$user_id = isset($_GET['id']) ? intval($_GET['id']) : 0;
|
||||||
|
|
||||||
$tpl_data = array();
|
$tpl_data = array();
|
||||||
$servers_count = count($this->servers);
|
$servers_count = count($this->servers);
|
||||||
|
@ -94,15 +71,13 @@ class Users extends Core {
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
// edit mode
|
// edit mode
|
||||||
|
|
||||||
// get user entry
|
|
||||||
$edit_user = $this->db->selectRow(
|
$edit_user = $this->db->selectRow(
|
||||||
PSM_DB_PREFIX.'users',
|
PSM_DB_PREFIX.'users',
|
||||||
array('user_id' => $user_id)
|
array('user_id' => $user_id)
|
||||||
);
|
);
|
||||||
if (empty($edit_user)) {
|
if (empty($edit_user)) {
|
||||||
$this->message = 'Invalid user id';
|
$this->addMessage('Invalid user.');
|
||||||
return $this->createHTMLList();
|
return $this->initializeAction('index');
|
||||||
}
|
}
|
||||||
|
|
||||||
$tpl_data = array_merge($tpl_data, array(
|
$tpl_data = array_merge($tpl_data, array(
|
||||||
|
@ -137,7 +112,7 @@ class Users extends Core {
|
||||||
/**
|
/**
|
||||||
* Prepare the template to show a list of all users
|
* Prepare the template to show a list of all users
|
||||||
*/
|
*/
|
||||||
protected function createHTMLList() {
|
protected function executeIndex() {
|
||||||
$this->setTemplateId('users_list', 'users.tpl.html');
|
$this->setTemplateId('users_list', 'users.tpl.html');
|
||||||
|
|
||||||
// build label array for the next loop
|
// build label array for the next loop
|
||||||
|
@ -174,7 +149,6 @@ class Users extends Core {
|
||||||
}
|
}
|
||||||
// add servers to template
|
// add servers to template
|
||||||
$this->tpl->addTemplateDataRepeat($this->getTemplateId(), 'users', $users);
|
$this->tpl->addTemplateDataRepeat($this->getTemplateId(), 'users', $users);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -182,7 +156,6 @@ class Users extends Core {
|
||||||
*/
|
*/
|
||||||
protected function executeSave() {
|
protected function executeSave() {
|
||||||
// check for add/edit mode
|
// check for add/edit mode
|
||||||
|
|
||||||
if (isset($_POST['name']) && isset($_POST['mobile']) && isset($_POST['email'])) {
|
if (isset($_POST['name']) && isset($_POST['mobile']) && isset($_POST['email'])) {
|
||||||
$clean = array(
|
$clean = array(
|
||||||
'name' => $_POST['name'],
|
'name' => $_POST['name'],
|
||||||
|
@ -190,36 +163,42 @@ class Users extends Core {
|
||||||
'email' => $_POST['email'],
|
'email' => $_POST['email'],
|
||||||
'server_id' => (isset($_POST['server_id'])) ? implode(',', $_POST['server_id']) : ''
|
'server_id' => (isset($_POST['server_id'])) ? implode(',', $_POST['server_id']) : ''
|
||||||
);
|
);
|
||||||
|
$id = (isset($_GET['id'])) ? intval($_GET['id']) : 0;
|
||||||
|
|
||||||
// check for edit or add
|
// check for edit or add
|
||||||
if ((int) $_POST['user_id'] > 0) {
|
if ((int) $id > 0) {
|
||||||
// edit
|
// edit
|
||||||
$this->db->save(
|
$this->db->save(
|
||||||
PSM_DB_PREFIX.'users',
|
PSM_DB_PREFIX.'users',
|
||||||
$clean,
|
$clean,
|
||||||
array('user_id' => $_POST['user_id'])
|
array('user_id' => $id)
|
||||||
);
|
);
|
||||||
$this->message = psm_get_lang('users', 'updated');
|
$this->addMessage(psm_get_lang('users', 'updated'));
|
||||||
} else {
|
} else {
|
||||||
// add
|
// add
|
||||||
$this->db->save(PSM_DB_PREFIX.'users', $clean);
|
$this->db->save(PSM_DB_PREFIX.'users', $clean);
|
||||||
$this->message = psm_get_lang('users', 'inserted');
|
$this->addMessage(psm_get_lang('users', 'inserted'));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
$this->initializeAction('index');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Executes the deletion of a user
|
* Executes the deletion of a user
|
||||||
*/
|
*/
|
||||||
protected function executeDelete() {
|
protected function executeDelete() {
|
||||||
// do delete
|
$id = (isset($_GET['id'])) ? intval($_GET['id']) : 0;
|
||||||
$this->db->delete(
|
|
||||||
PSM_DB_PREFIX . 'users',
|
if($id > 0) {
|
||||||
array(
|
$this->db->delete(
|
||||||
'user_id' => $_GET['delete']
|
PSM_DB_PREFIX . 'users',
|
||||||
)
|
array(
|
||||||
);
|
'user_id' => $id,
|
||||||
$this->message = psm_get_lang('system', 'deleted');
|
)
|
||||||
|
);
|
||||||
|
$this->addMessage(psm_get_lang('system', 'deleted'));
|
||||||
|
}
|
||||||
|
$this->initializeAction('index');
|
||||||
}
|
}
|
||||||
|
|
||||||
// override parent::createHTMLLabels()
|
// override parent::createHTMLLabels()
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<!--%tpl_config-->
|
<!--%tpl_config-->
|
||||||
{config_update}
|
{config_update}
|
||||||
<div class="span12">
|
<div class="span12">
|
||||||
<form class="form-horizontal well" action="index.php?type=config" id="edit_config" method="post">
|
<form class="form-horizontal well" action="index.php?type=config&action=save" id="edit_config" method="post">
|
||||||
<fieldset>
|
<fieldset>
|
||||||
<legend>{label_general}</legend>
|
<legend>{label_general}</legend>
|
||||||
<div class="control-group">
|
<div class="control-group">
|
||||||
|
@ -118,9 +118,7 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-actions">
|
<div class="form-actions">
|
||||||
<input type="hidden" name="server_id" value="{edit_server_id}" />
|
|
||||||
<button class="btn btn-success" type="submit">Save</button>
|
<button class="btn btn-success" type="submit">Save</button>
|
||||||
<button class="btn" onclick="history.back();" >Cancel</button>
|
|
||||||
</div>
|
</div>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
</form>
|
</form>
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="top_buutons">
|
<div class="top_buutons">
|
||||||
<a class="btn btn-success" href="index.php?type=servers&edit=0">
|
<a class="btn btn-success" href="index.php?type=servers&action=edit">
|
||||||
<i class="icon-plus icon-white"></i>
|
<i class="icon-plus icon-white"></i>
|
||||||
{label_add_new}
|
{label_add_new}
|
||||||
</a>
|
</a>
|
||||||
|
@ -48,7 +48,7 @@
|
||||||
<td>{email}</td>
|
<td>{email}</td>
|
||||||
<td>{sms}</td>
|
<td>{sms}</td>
|
||||||
<td>
|
<td>
|
||||||
<a class="btn btn-small" href="index.php?type=servers&edit={server_id}" title="{label_edit}">
|
<a class="btn btn-small" href="index.php?type=servers&action=edit&id={server_id}" title="{label_edit}">
|
||||||
<i class="icon-pencil"></i>
|
<i class="icon-pencil"></i>
|
||||||
</a>
|
</a>
|
||||||
<a class="btn btn-small btn-danger" href="javascript:sm_delete('{server_id}', 'servers');" title="{label_delete}">
|
<a class="btn btn-small btn-danger" href="javascript:sm_delete('{server_id}', 'servers');" title="{label_delete}">
|
||||||
|
@ -66,7 +66,7 @@
|
||||||
|
|
||||||
<!--%tpl_servers_update-->
|
<!--%tpl_servers_update-->
|
||||||
<div class="span12">
|
<div class="span12">
|
||||||
<form class="form-horizontal well" action="index.php?type=servers" id="edit_server" method="post">
|
<form class="form-horizontal well" action="index.php?type=servers&action=save&id={edit_server_id}" method="post">
|
||||||
<fieldset>
|
<fieldset>
|
||||||
<legend>{titlemode}</legend>
|
<legend>{titlemode}</legend>
|
||||||
<div class="control-group">
|
<div class="control-group">
|
||||||
|
@ -124,9 +124,8 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-actions">
|
<div class="form-actions">
|
||||||
<input type="hidden" name="server_id" value="{edit_server_id}" />
|
|
||||||
<button class="btn btn-success" type="submit">Save</button>
|
<button class="btn btn-success" type="submit">Save</button>
|
||||||
<button class="btn" onclick="history.back();" >Cancel</button>
|
<button class="btn" onclick="history.back();return false;" >Cancel</button>
|
||||||
</div>
|
</div>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
</form>
|
</form>
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
{message}
|
{message}
|
||||||
</div>
|
</div>
|
||||||
<div class="top_buutons">
|
<div class="top_buutons">
|
||||||
<a class="btn btn-success" href="index.php?type=users&edit=0">
|
<a class="btn btn-success" href="index.php?type=users&action=edit">
|
||||||
<i class="icon-plus icon-white"></i>
|
<i class="icon-plus icon-white"></i>
|
||||||
{label_add_new}
|
{label_add_new}
|
||||||
</a>
|
</a>
|
||||||
|
@ -27,7 +27,7 @@
|
||||||
<td>{email}</td>
|
<td>{email}</td>
|
||||||
<td>{emp_servers}</td>
|
<td>{emp_servers}</td>
|
||||||
<td>
|
<td>
|
||||||
<a class="btn btn-small" href="index.php?type=users&edit={user_id}" title="{label_edit}">
|
<a class="btn btn-small" href="index.php?type=users&action=edit&id={user_id}" title="{label_edit}">
|
||||||
<i class="icon-pencil"></i>
|
<i class="icon-pencil"></i>
|
||||||
</a>
|
</a>
|
||||||
<a class="btn btn-small btn-danger" href="javascript:sm_delete('{user_id}', 'users');" title="{label_delete}">
|
<a class="btn btn-small btn-danger" href="javascript:sm_delete('{user_id}', 'users');" title="{label_delete}">
|
||||||
|
@ -44,7 +44,7 @@
|
||||||
|
|
||||||
<!--%tpl_users_update-->
|
<!--%tpl_users_update-->
|
||||||
<div class="span12">
|
<div class="span12">
|
||||||
<form class="form-horizontal well" action="index.php?type=users" id="edit_server" method="post">
|
<form class="form-horizontal well" action="index.php?type=users&action=save&id={edit_user_id}" method="post">
|
||||||
<fieldset>
|
<fieldset>
|
||||||
<legend>{titlemode}</legend>
|
<legend>{titlemode}</legend>
|
||||||
<div class="control-group">
|
<div class="control-group">
|
||||||
|
@ -81,9 +81,8 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-actions">
|
<div class="form-actions">
|
||||||
<input type="hidden" name="user_id" value="{edit_user_id}" />
|
|
||||||
<button class="btn btn-success" type="submit">Save</button>
|
<button class="btn btn-success" type="submit">Save</button>
|
||||||
<button class="btn" onclick="history.back();" >Cancel</button>
|
<button class="btn" onclick="history.back();return false;" >Cancel</button>
|
||||||
</div>
|
</div>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
</form>
|
</form>
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
function sm_delete(id, type) {
|
function sm_delete(id, type) {
|
||||||
var del = confirm("Are you sure you want to delete this record?");
|
var del = confirm("Are you sure you want to delete this record?");
|
||||||
if (del == true) {
|
if (del == true) {
|
||||||
var loc = 'index.php?delete=' + id + '&type=' + type;
|
var loc = 'index.php?action=delete&id=' + id + '&type=' + type;
|
||||||
window.location = loc;
|
window.location = loc;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,7 @@ function sm_delete(id, type) {
|
||||||
function trim(str) {
|
function trim(str) {
|
||||||
return str.replace(/^\s+|\s+$/g,"");
|
return str.replace(/^\s+|\s+$/g,"");
|
||||||
}
|
}
|
||||||
|
|
||||||
//left trim
|
//left trim
|
||||||
function ltrim(str) {
|
function ltrim(str) {
|
||||||
return str.replace(/^\s+/,"");
|
return str.replace(/^\s+/,"");
|
||||||
|
@ -18,4 +18,4 @@ function ltrim(str) {
|
||||||
//right trim
|
//right trim
|
||||||
function rtrim(str) {
|
function rtrim(str) {
|
||||||
return str.replace(/\s+$/,"");
|
return str.replace(/\s+$/,"");
|
||||||
}
|
}
|
Loading…
Reference in New Issue