diff --git a/build.xml b/build.xml
deleted file mode 100644
index eac5a0d..0000000
--- a/build.xml
+++ /dev/null
@@ -1,85 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/composer.json b/composer.json
new file mode 100644
index 0000000..3585a76
--- /dev/null
+++ b/composer.json
@@ -0,0 +1,16 @@
+{
+ "name": "cacti/plugin_npc",
+ "description": "Nagios Plugin for Cacti",
+ "license": "GPL-2.0-or-later",
+ "require-dev": {
+ "pestphp/pest": "^1.23"
+ },
+ "config": {
+ "allow-plugins": {
+ "pestphp/pest-plugin": true
+ }
+ },
+ "autoload-dev": {
+ "files": ["tests/bootstrap.php"]
+ }
+}
diff --git a/config.php b/config.php
index 30b8c44..b3df926 100644
--- a/config.php
+++ b/config.php
@@ -1,23 +1,5 @@
setAttribute(Doctrine::ATTR_MODEL_LOADING, Doctrine::MODEL_LOADING_CONSERVATIVE);
-
-// Load our models
-Doctrine::loadModels(dirname(__FILE__) . '/models');
+require_once(dirname(__FILE__) . '/controllers/controller.php');
diff --git a/controllers/comments.php b/controllers/comments.php
index f65980e..aca79ae 100644
--- a/controllers/comments.php
+++ b/controllers/comments.php
@@ -18,7 +18,7 @@
* Comments controller class
*
* Comments controller provides functionality, such as building the
- * Doctrine queries and formatting output.
+ * queries and formatting output.
*
* @package npc
* @subpackage npc.controllers
@@ -172,22 +172,13 @@ function deleteAllServiceComments() {
* @return array icon and alt
*/
function getHostIcon($id) {
+ $results = db_fetch_row_prepared('SELECT h.icon_image, h.icon_image_alt
+ FROM npc_services s
+ LEFT JOIN npc_hosts h ON s.host_object_id = h.host_object_id
+ WHERE s.service_object_id = ?',
+ array($id));
- $q = new Doctrine_Pager(
- Doctrine_Query::create()
- ->select('s.service_id,'
- .'h.icon_image,'
- .'h.icon_image_alt')
- ->from('NpcServices s')
- ->leftJoin('s.Host h')
- ->where("s.service_object_id = ?", $id),
- $this->currentPage,
- $this->limit
- );
-
- $results = $q->execute(array(), Doctrine::HYDRATE_ARRAY);
-
- return($results[0]['Host']);
+ return($results);
}
/**
@@ -197,57 +188,78 @@ function getHostIcon($id) {
*
* @return array The comments
*/
- function comments($id=null, $where='') {
+ function comments($id = null, $where = '') {
- // Maps searchable fields passed in from the client
+ /* Maps searchable fields passed in from the client */
$fieldMap = array('service_description' => 'o.name2',
'host_name' => 'o.name1',
'author_name' => 'c.author_name',
'comment_data' => 'c.comment_data');
+ $params = array();
if ($this->id || $id) {
if ($where != '') {
$where .= ' AND ';
}
- $where .= sprintf("c.object_id = %d", is_null($id) ? $this->id : $id);
+ $where .= 'c.object_id = ?';
+ $params[] = is_null($id) ? $this->id : $id;
}
if ($this->searchString) {
- $where = $this->searchClause($where, $fieldMap);
+ $where = $this->searchClause($where, $fieldMap, $params);
}
- if ($this->sort) {
- $orderBy = $this->sort . ' ' . $this->dir;
- } else {
- $orderBy = 'c.entry_time DESC, c.entry_time_usec DESC';
- }
-
- $q = new Doctrine_Pager(
- Doctrine_Query::create()
- ->select('i.instance_name,'
- .'o.name1 AS host_name,'
- .'o.name2 AS service_description,'
- .'s.icon_image AS svc_icon_image,'
- .'s.icon_image_alt AS svc_icon_image_alt,'
- .'h.icon_image AS host_icon_image,'
- .'h.icon_image_alt AS host_icon_image_alt,'
- .'c.*')
- ->from('NpcComments c')
- ->leftJoin('c.Object o')
- ->leftJoin('c.Instance i')
- ->leftJoin('c.Service s')
- ->leftJoin('c.Host h')
- ->where($where)
- ->orderby($orderBy),
- $this->currentPage,
- $this->limit
+ $allowedSort = array(
+ 'entry_time' => 'c.entry_time',
+ 'author_name' => 'c.author_name',
+ 'comment_data' => 'c.comment_data',
+ 'host_name' => 'o.name1',
+ 'service_description' => 'o.name2',
);
+ $sortCol = ($this->sort && isset($allowedSort[$this->sort]))
+ ? $allowedSort[$this->sort]
+ : 'c.entry_time';
+ $sortDir = (strtoupper((string) $this->dir) === 'ASC') ? 'ASC' : 'DESC';
+ $orderBy = $sortCol . ' ' . $sortDir;
+ if ($sortCol === 'c.entry_time') {
+ $orderBy .= ', c.entry_time_usec ' . $sortDir;
+ }
- $results = $q->execute(array(), Doctrine::HYDRATE_ARRAY);
+ $whereClause = '';
+ if ($where != '') {
+ $whereClause = 'WHERE ' . $where;
+ }
- // Set the total number of records
- $this->numRecords = $q->getNumResults();
+ /* Get the total count */
+ $this->numRecords = db_fetch_cell_prepared('SELECT COUNT(*)
+ FROM npc_comments c
+ LEFT JOIN npc_objects o ON c.object_id = o.object_id
+ LEFT JOIN npc_instances i ON c.instance_id = i.instance_id
+ LEFT JOIN npc_services s ON c.object_id = s.service_object_id
+ LEFT JOIN npc_hosts h ON c.object_id = h.host_object_id
+ ' . $whereClause,
+ $params);
+
+ $offset = ($this->currentPage - 1) * $this->limit;
+
+ $results = db_fetch_assoc_prepared('SELECT i.instance_name,
+ o.name1 AS host_name,
+ o.name2 AS service_description,
+ s.icon_image AS svc_icon_image,
+ s.icon_image_alt AS svc_icon_image_alt,
+ h.icon_image AS host_icon_image,
+ h.icon_image_alt AS host_icon_image_alt,
+ c.*
+ FROM npc_comments c
+ LEFT JOIN npc_objects o ON c.object_id = o.object_id
+ LEFT JOIN npc_instances i ON c.instance_id = i.instance_id
+ LEFT JOIN npc_services s ON c.object_id = s.service_object_id
+ LEFT JOIN npc_hosts h ON c.object_id = h.host_object_id
+ ' . $whereClause . '
+ ORDER BY ' . $orderBy . '
+ LIMIT ?, ?',
+ array_merge($params, array($offset, $this->limit)));
return($results);
}
diff --git a/controllers/controller.php b/controllers/controller.php
index 4ab6a53..cfcd4da 100644
--- a/controllers/controller.php
+++ b/controllers/controller.php
@@ -19,7 +19,6 @@
* @subpackage npc.controllers
*/
class Controller {
- var $conn = null;
/**
* The default state to query
@@ -313,36 +312,39 @@ function flattenArray($array=array()) {
/**
* searchClause
*
- * Appends search parameters to the passed in where clause
- * @param string $where An existing where clause
- * @param array $fieldMap Maps passed in field names
- * @return string The appended where clasue
+ * Appends search parameters to the passed in where clause.
+ * Returns both the SQL fragment and an array of bind params
+ * for use with prepared statements.
+ *
+ * @param string $where An existing where clause
+ * @param array $fieldMap Maps passed in field names
+ * @param array $params Existing bind params array (passed by reference)
+ * @return string The appended where clause
*/
- function searchClause($where, $fieldMap) {
-
- if (!$where) {
- $where = ' ( ';
- } else {
- $where .= ' AND ( ';
- }
-
- $fields = json_decode(stripslashes($this->searchFields));
- $count = count($fields);
-
- $x = 1;
- foreach ($fields as $field) {
- if (isset($fieldMap[$field])) {
- $where .= $fieldMap[$field] . " LIKE '%" . $this->searchString . "%' ";
- if ($x < $count) {
- $where .= ' OR ';
- }
- $x++;
- } else {
- $count = $count - 1;
- }
- }
-
- $where .= ' ) ';
+ function searchClause($where, $fieldMap, &$params = array()) {
+ $fields = json_decode(stripslashes($this->searchFields));
+ if (!is_array($fields)) {
+ return $where;
+ }
+
+ $searchValue = '%' . $this->searchString . '%';
+
+ $clauses = array();
+ $searchParams = array();
+ foreach ($fields as $field) {
+ if (isset($fieldMap[$field])) {
+ $clauses[] = $fieldMap[$field] . ' LIKE ?';
+ $searchParams[] = $searchValue;
+ }
+ }
+
+ if (empty($clauses)) {
+ return $where;
+ }
+
+ $params = array_merge($params, $searchParams);
+ $where .= $where ? ' AND ( ' : ' ( ';
+ $where .= implode(' OR ', $clauses) . ' ) ';
return($where);
}
@@ -483,4 +485,3 @@ function updateCsrf() {
bottom_footer();
} // end drawFrame
}
-
diff --git a/controllers/downtime.php b/controllers/downtime.php
index b07b86d..6584d44 100644
--- a/controllers/downtime.php
+++ b/controllers/downtime.php
@@ -18,7 +18,7 @@
* Downtime controller class
*
* Downtime controller provides functionality, such as building the
- * Doctrine queries and formatting output.
+ * queries and formatting output.
*
* @package npc
* @subpackage npc.controllers
@@ -125,26 +125,26 @@ function getTriggeredByCombo() {
*
* @return array
*/
- function scheduledDowntime($id=null, $where='1=1') {
+ function scheduledDowntime($id = null, $where = '1=1') {
+
+ $params = array();
if ($this->id || $id) {
- $where .= ' AND ';
- $where .= sprintf("d.object_id = %d", is_null($id) ? $this->id : $id);
+ $where .= ' AND d.object_id = ?';
+ $params[] = is_null($id) ? $this->id : $id;
}
- $q = new Doctrine_Query();
- $q->select('i.instance_name,'
- .'o.objecttype_id,'
- .'o.name1 AS host_name,'
- .'o.name2 AS service_description,'
- .'d.*')
- ->from('NpcScheduleddowntime d')
- ->leftJoin('d.Object o')
- ->leftJoin('d.Instance i')
- ->where("$where")
- ->orderby( 'd.scheduled_start_time DESC, d.scheduleddowntime_id DESC' );
-
- $results = $q->execute(array(), Doctrine::HYDRATE_ARRAY);
+ $results = db_fetch_assoc_prepared('SELECT i.instance_name,
+ o.objecttype_id,
+ o.name1 AS host_name,
+ o.name2 AS service_description,
+ d.*
+ FROM npc_scheduleddowntime d
+ LEFT JOIN npc_objects o ON d.object_id = o.object_id
+ LEFT JOIN npc_instances i ON d.instance_id = i.instance_id
+ WHERE ' . $where . '
+ ORDER BY d.scheduled_start_time DESC, d.scheduleddowntime_id DESC',
+ $params);
return($results);
}
@@ -156,34 +156,44 @@ function scheduledDowntime($id=null, $where='1=1') {
*
* @return array
*/
- function downtimeHistory($id=null, $where='') {
+ function downtimeHistory($id = null, $where = '') {
+
+ $params = array();
if ($this->id || $id) {
if ($where != '') {
$where .= ' AND ';
}
- $where .= sprintf("d.object_id = %d", is_null($id) ? $this->id : $id);
+ $where .= 'd.object_id = ?';
+ $params[] = is_null($id) ? $this->id : $id;
+ }
+
+ $whereClause = '';
+ if ($where != '') {
+ $whereClause = 'WHERE ' . $where;
}
- $q = new Doctrine_Pager(
- Doctrine_Query::create()
- ->select('i.instance_name,'
- .'o.name1 AS host_name,'
- .'o.name2 AS service_description,'
- .'d.*')
- ->from('NpcDowntimehistory d')
- ->leftJoin('d.Object o')
- ->leftJoin('d.Instance i')
- ->where("$where")
- ->orderby( 'd.scheduled_start_time DESC, d.actual_start_time DESC, d.actual_start_time_usec DESC' ),
- $this->currentPage,
- $this->limit
- );
-
- $results = $q->execute(array(), Doctrine::HYDRATE_ARRAY);
-
- // Set the total number of records
- $this->numRecords = $q->getNumResults();
+ /* Get total count */
+ $this->numRecords = db_fetch_cell_prepared('SELECT COUNT(*)
+ FROM npc_downtimehistory d
+ LEFT JOIN npc_objects o ON d.object_id = o.object_id
+ LEFT JOIN npc_instances i ON d.instance_id = i.instance_id
+ ' . $whereClause,
+ $params);
+
+ $offset = ($this->currentPage - 1) * $this->limit;
+
+ $results = db_fetch_assoc_prepared('SELECT i.instance_name,
+ o.name1 AS host_name,
+ o.name2 AS service_description,
+ d.*
+ FROM npc_downtimehistory d
+ LEFT JOIN npc_objects o ON d.object_id = o.object_id
+ LEFT JOIN npc_instances i ON d.instance_id = i.instance_id
+ ' . $whereClause . '
+ ORDER BY d.scheduled_start_time DESC, d.actual_start_time DESC, d.actual_start_time_usec DESC
+ LIMIT ?, ?',
+ array_merge($params, array($offset, $this->limit)));
return($results);
}
diff --git a/controllers/hostgroups.php b/controllers/hostgroups.php
index 13beae5..909504c 100644
--- a/controllers/hostgroups.php
+++ b/controllers/hostgroups.php
@@ -1,388 +1,240 @@
- * @copyright Copyright (c) 2007
- * @link http://trac2.assembla.com/npc
- * @package npc
- * @subpackage npc.controllers
- * @since NPC 2.0
- * @version $Id$
- */
+/*
+ +-------------------------------------------------------------------------+
+ | Nagios Plugin for Cacti |
+ | |
+ | Copyright (C) 2007 Billy Gunn (billy@gunn.org) |
+ | Copyright (C) 2004-2026 The Cacti Group |
+ +-------------------------------------------------------------------------+
+ | Cacti and Nagios are the copyright of their respective owners. |
+ +-------------------------------------------------------------------------+
+*/
if (isset($config)) {
- require_once($config["base_path"]."/plugins/npc/controllers/services.php");
+ require_once($config['base_path'] . '/plugins/npc/controllers/services.php');
} else {
- require_once("plugins/npc/controllers/services.php");
+ require_once('plugins/npc/controllers/services.php');
}
-
-/**
- * Hostgroups controller class
- *
- * Hostgroups controller provides functionality, such as building the
- * Doctrine queries and formatting output.
- *
- * @package npc
- * @subpackage npc.controllers
- */
class NpcHostgroupsController extends Controller {
- /**
- * A service status cache
- *
- * @var array
- * @access private
- */
- private $statusCache = array();
-
- /**
- * getHostgroupHostStatus
- *
- * Returns host status counts by hostgroup.
- *
- * @return string json output
- */
- function getHostgroupHostStatus() {
-
- // Initialize the output array
- $output = array();
-
- // Initialize the hosts array
- $hosts = array();
-
- $fields = array('hostgroup_object_id',
- 'alias',
- 'instance_id');
-
- $results = $this->setupResultsArray();
-
- for ($i = 0; $i < count($results); $i++) {
- $hg = $results[$i]['hostgroup_object_id'];
- if(!isset($output[$hg])) {
- $output[$hg] = array('down' => 0,
- 'unreachable' => 0,
- 'up' => 0,
- 'pending' => 0);
- }
- if (!isset($hosts[$hg][$results[$i]['host_name']])) {
- $output[$hg][$this->hostState[$results[$i]['current_state']]]++;
- $hosts[$hg][$results[$i]['host_name']] = 1;
- }
- foreach ($results[$i] as $key => $val) {
- if (in_array($key, $fields)) {
- $output[$hg][$key] = $val;
- }
- }
- }
-
- // Set the total number of records
- $this->numRecords = count($output);
-
- // Implement paging by slicing the output array
- $output = array_slice($output, $this->start, $this->limit);
-
- $response['response']['value']['items'] = $output;
- $response['response']['value']['total_count'] = $this->numRecords;
- $response['response']['value']['version'] = 1;
-
- return(json_encode($response));
- }
-
- /**
- * getHostgroupServiceStatus
- *
- * Returns service status counts by hostgroup.
- *
- * @return string json output
- */
- function getHostgroupServiceStatus() {
-
- // Initialize the output array
- $output = array();
-
- $fields = array('hostgroup_object_id',
- 'alias',
- 'hostgroup_name',
- 'instance_id');
-
- // Combine servicegroup/service/host etc. into a single record
- $results = $this->setupResultsArray();
-
- for ($i = 0; $i < count($results); $i++) {
- $hg = $results[$i]['hostgroup_object_id'];
- $ss = $this->getHostgroupMemberServiceStatus($results[$i]['host_object_id']);
- if(!isset($output[$hg])) {
- $output[$hg] = $ss;
- } else {
- foreach ($ss as $k => $v) {
- $output[$hg][$k] = $output[$hg][$k] + $v;
- }
- }
- foreach ($results[$i] as $key => $val) {
- if (in_array($key, $fields)) {
- $output[$hg][$key] = $val;
- }
- }
- }
-
- // Set the total number of records
- $this->numRecords = count($output);
-
- // Implement paging by slicing the output array
- $output = array_slice($output, $this->start, $this->limit);
-
- $response['response']['value']['items'] = $output;
- $response['response']['value']['total_count'] = $this->numRecords;
- $response['response']['value']['version'] = 1;
-
- return(json_encode($response));
- }
-
-
- /**
- * getOverview
- *
- * Returns all hosts by hostgroup. Used to populate
- * the Servicegroup Grid screen.
- *
- * @return string json output
- */
- function getOverview() {
-
- $fields = array('hostgroup_object_id',
- 'alias',
- 'instance_id',
- 'host_name');
-
- // Initialize the output array
- $output = array();
-
- // Combine servicegroup/service/host etc. into a single record
- $results = $this->setupResultsArray();
-
- /* Loop through the results array and build an output array
- * that includes a single record per host within the hostgroup
- * and the number of crit, warn , ok services within
- * that hostgroup.
- */
- for ($i = 0; $i < count($results); $i++) {
- $hg = $results[$i]['hostgroup_object_id'];
- $host = $results[$i]['host_name'];
- $ss = $this->getHostgroupMemberServiceStatus($results[$i]['host_object_id']);
- if(!isset($temp[$hg][$host])) {
- $ss['host_state'] = $results[$i]['current_state'];
- $temp[$hg][$host] = $ss;
- }
- foreach ($results[$i] as $key => $val) {
- $temp[$hg][$host][$key] = $val;
- }
- }
-
- $x = 0;
- foreach ($temp as $i => $s) {
- foreach ($s as $h => $v) {
- foreach ($v as $key => $val) {
- $output[$x][$key] = $val;
- }
- $x++;
- }
- }
-
- // Set the total number of records
- $this->numRecords = count($output);
-
- // Implement paging by slicing the output array
- $output = array_slice($output, $this->start, $this->limit);
-
- return($this->jsonOutput($output));
- }
-
-
- /**
- * getHosts
- *
- * Returns all hosts by hostgroup. Used to populate
- * the Hostgroup Grid screen.
- *
- * @return string json output
- */
- function getHosts() {
-
- $output = $this->setupResultsArray();
-
- // Set the total number of records
- $this->numRecords = count($output);
-
- // Implement paging by slicing the output array
- $output = array_slice($output, $this->start, $this->limit);
-
- return($this->jsonOutput($output));
- }
-
- /**
- * getHostList
- *
- * Retrieves all hosts in the specified hostgroup
- *
- * @return array
- */
- function getHostList($params) {
-
- $column = key($params);
- $value = $params[$column];
-
- $q = new Doctrine_Query();
- $q->select('h.host_object_id, h.display_name, h.address')
- ->from('NpcHosts h, NpcHostgroups hg, NpcHostgroupMembers hgm')
- ->where('hg.hostgroup_id = hgm.hostgroup_id AND hgm.host_object_id = h.host_object_id AND hg.'.$column.' = ?', $value);
-
- $results = $q->execute(array(), Doctrine::HYDRATE_ARRAY);
-
- return($results);
- }
-
- /**
- * getHostgroupMemberServiceStatus
- *
- * Returns a count of the status of all services for a given host.
- *
- * @return array
- */
- private function getHostgroupMemberServiceStatus($host_object_id) {
-
- if(isset($this->statusCache[$host_object_id])) {
- return($this->statusCache[$host_object_id]);
- }
-
- // initialize the status array
- $this->statusCache[$host_object_id] = array('critical' => 0,
- 'warning' => 0,
- 'unknown' => 0,
- 'ok' => 0,
- 'pending' => 0);
-
-
- $obj = new NpcServicesController;
- $results = $obj->getServiceStatesByHost($host_object_id);
-
- for ($i = 0; $i < count($results); $i++) {
- $this->statusCache[$host_object_id][$this->serviceState[$results[$i]['current_state']]]++;
- }
-
- return($this->statusCache[$host_object_id]);
- }
-
- /**
- * listHostsCli
- *
- * Retrieves all hosts in the specified hostgroup for the cli
- *
- * @return array
- */
- function listHostsCli($hg) {
-
- $q = new Doctrine_Query();
- $q->select('h.host_id, h.host_object_id AS id, h.display_name AS name, h.address')
- ->from('NpcHosts h, NpcHostgroups hg, NpcHostgroupMembers hgm')
- ->where('hg.hostgroup_id = hgm.hostgroup_id AND hgm.host_object_id = h.host_object_id AND hg.alias = ?', $hg);
-
- $results = $q->execute(array(), Doctrine::HYDRATE_ARRAY);
-
- return($results);
- }
-
-
- /**
- * listHostgroupsCli
- *
- * Returns all hostgroups and associated object ID's
- *
- * @return array Array of hostgroups/id's
- */
- function listHostgroupsCli() {
-
- $q = new Doctrine_Query();
- $q->select('alias as name, hostgroup_object_id as id')->from('NpcHostgroups')->orderBy('alias ASC');
-
- return($q->execute(array(), Doctrine::HYDRATE_ARRAY));
- }
-
-
- /**
- * getHostgroups
- *
- * Retrieves all hosts with current state by hostgroup
- *
- * @return array
- */
- function getHostgroups() {
- $where = '1 = 1';
-
- // Maps searchable fields passed in from the client
- $fieldMap = array('service_description' => 'o2.name2',
- 'host_name' => 'o2.name1',
- 'alias' => 'sg.alias',
- 'output' => 's.output');
-
- if ($this->id) {
- $where .= " AND hg.hostgroup_object_id = " . $this->id . " ";
- }
-
- if ($this->searchString) {
- $where = $this->searchClause(null, $fieldMap);
- }
-
- $q = new Doctrine_Query();
- $q->select('i.instance_name,'
- .'o1.name1 AS hostgroup_name,'
- .'hs.host_object_id,'
- .'hs.current_state,'
- .'hs.output,'
- .'o2.name1 AS host_name,'
- .'hg.*')
- ->distinct()
- ->from('NpcHostgroups hg')
- ->innerJoin('hg.HostgroupMembers hgm')
- ->innerJoin('hg.Hoststatus hs ON hgm.host_object_id = hs.host_object_id')
- ->innerJoin('hg.Object o1')
- ->innerJoin('hs.Object o2')
- ->innerJoin('hg.Instance i')
- ->where("$where")
- ->orderBy('hostgroup_name ASC, host_name ASC');
-
- $results = $q->execute(array(), Doctrine::HYDRATE_ARRAY);
-
- return($results);
- }
-
- /**
- * setupResultsArray
- *
- * A utility method to handle some common formatting tasks.
- *
- * @return array
- */
- function setupResultsArray() {
-
- // Get the servicegroups
- $results = $this->getHostgroups();
-
- // Flatten the 1st level of nested arrays
- $results = $this->flattenArray($results);
-
- // Combine servicegroup/service/host etc. into a single record.
- $results = $this->flattenNestedArray($results);
-
- return($results);
- }
-
+ private $statusCache = array();
+
+ function getHostgroupHostStatus() {
+ $output = array();
+ $hosts = array();
+
+ $fields = array('hostgroup_object_id', 'alias', 'instance_id');
+ $results = $this->setupResultsArray();
+
+ for ($i = 0; $i < count($results); $i++) {
+ $hg = $results[$i]['hostgroup_object_id'];
+ if (!isset($output[$hg])) {
+ $output[$hg] = array('down' => 0, 'unreachable' => 0, 'up' => 0, 'pending' => 0);
+ }
+ if (!isset($hosts[$hg][$results[$i]['host_name']])) {
+ $state = $results[$i]['current_state'];
+ if (isset($this->hostState[$state])) {
+ $output[$hg][$this->hostState[$state]]++;
+ }
+ $hosts[$hg][$results[$i]['host_name']] = 1;
+ }
+ foreach ($results[$i] as $key => $val) {
+ if (in_array($key, $fields, true)) {
+ $output[$hg][$key] = $val;
+ }
+ }
+ }
+
+ $this->numRecords = count($output);
+ $output = array_slice($output, $this->start, $this->limit);
+
+ $response = array(
+ 'response' => array(
+ 'value' => array(
+ 'items' => $output,
+ 'total_count' => $this->numRecords,
+ 'version' => 1,
+ )
+ )
+ );
+
+ return json_encode($response);
+ }
+
+ function getHostgroupServiceStatus() {
+ $output = array();
+ $fields = array('hostgroup_object_id', 'alias', 'hostgroup_name', 'instance_id');
+
+ $results = $this->setupResultsArray();
+
+ for ($i = 0; $i < count($results); $i++) {
+ $hg = $results[$i]['hostgroup_object_id'];
+ $ss = $this->getHostgroupMemberServiceStatus($results[$i]['host_object_id']);
+ if (!isset($output[$hg])) {
+ $output[$hg] = $ss;
+ } else {
+ foreach ($ss as $k => $v) {
+ $output[$hg][$k] = $output[$hg][$k] + $v;
+ }
+ }
+ foreach ($results[$i] as $key => $val) {
+ if (in_array($key, $fields, true)) {
+ $output[$hg][$key] = $val;
+ }
+ }
+ }
+
+ $this->numRecords = count($output);
+ $output = array_slice($output, $this->start, $this->limit);
+
+ $response = array(
+ 'response' => array(
+ 'value' => array(
+ 'items' => $output,
+ 'total_count' => $this->numRecords,
+ 'version' => 1,
+ )
+ )
+ );
+
+ return json_encode($response);
+ }
+
+ function getOverview() {
+ $fields = array('hostgroup_object_id', 'alias', 'instance_id', 'host_name');
+ $output = array();
+ $temp = array();
+
+ $results = $this->setupResultsArray();
+
+ for ($i = 0; $i < count($results); $i++) {
+ $hg = $results[$i]['hostgroup_object_id'];
+ $host = $results[$i]['host_name'];
+ $ss = $this->getHostgroupMemberServiceStatus($results[$i]['host_object_id']);
+ if (!isset($temp[$hg][$host])) {
+ $ss['host_state'] = $results[$i]['current_state'];
+ $temp[$hg][$host] = $ss;
+ }
+ foreach ($results[$i] as $key => $val) {
+ $temp[$hg][$host][$key] = $val;
+ }
+ }
+
+ $x = 0;
+ foreach ($temp as $i => $s) {
+ foreach ($s as $h => $v) {
+ foreach ($v as $key => $val) {
+ $output[$x][$key] = $val;
+ }
+ $x++;
+ }
+ }
+
+ $this->numRecords = count($output);
+ $output = array_slice($output, $this->start, $this->limit);
+
+ return $this->jsonOutput($output);
+ }
+
+ function getHosts() {
+ $output = $this->setupResultsArray();
+ $this->numRecords = count($output);
+ $output = array_slice($output, $this->start, $this->limit);
+
+ return $this->jsonOutput($output);
+ }
+
+ function getHostList($params) {
+ $allowed_columns = array('alias', 'hostgroup_object_id', 'hostgroup_id');
+ $column = key($params);
+
+ if (!in_array($column, $allowed_columns, true)) {
+ return array();
+ }
+
+ $value = $params[$column];
+
+ return db_fetch_assoc_prepared(
+ 'SELECT h.host_object_id, h.display_name, h.address
+ FROM npc_hosts h
+ INNER JOIN npc_hostgroup_members hgm ON hgm.host_object_id = h.host_object_id
+ INNER JOIN npc_hostgroups hg ON hg.hostgroup_id = hgm.hostgroup_id
+ WHERE hg.' . $column . ' = ?',
+ array($value));
+ }
+
+ private function getHostgroupMemberServiceStatus($host_object_id) {
+ if (isset($this->statusCache[$host_object_id])) {
+ return $this->statusCache[$host_object_id];
+ }
+
+ $this->statusCache[$host_object_id] = array(
+ 'critical' => 0, 'warning' => 0, 'unknown' => 0, 'ok' => 0, 'pending' => 0
+ );
+
+ $obj = new NpcServicesController;
+ $results = $obj->getServiceStatesByHost($host_object_id);
+
+ for ($i = 0; $i < count($results); $i++) {
+ $state_key = $results[$i]['current_state'];
+ if (isset($this->serviceState[$state_key])) {
+ $this->statusCache[$host_object_id][$this->serviceState[$state_key]]++;
+ }
+ }
+
+ return $this->statusCache[$host_object_id];
+ }
+
+ function listHostsCli($hg) {
+ return db_fetch_assoc_prepared(
+ 'SELECT h.host_id, h.host_object_id AS id, h.display_name AS name, h.address
+ FROM npc_hosts h
+ INNER JOIN npc_hostgroup_members hgm ON hgm.host_object_id = h.host_object_id
+ INNER JOIN npc_hostgroups hg ON hg.hostgroup_id = hgm.hostgroup_id
+ WHERE hg.alias = ?',
+ array($hg));
+ }
+
+ function listHostgroupsCli() {
+ return db_fetch_assoc('SELECT alias AS name, hostgroup_object_id AS id
+ FROM npc_hostgroups
+ ORDER BY alias ASC');
+ }
+
+ function getHostgroups() {
+ $params = array();
+ $where = '1 = 1';
+
+ if ($this->id) {
+ $where .= ' AND hg.hostgroup_object_id = ?';
+ $params[] = intval($this->id);
+ }
+
+ return db_fetch_assoc_prepared(
+ 'SELECT DISTINCT i.instance_name,
+ o1.name1 AS hostgroup_name,
+ hs.host_object_id,
+ hs.current_state,
+ hs.output,
+ o2.name1 AS host_name,
+ hg.*
+ FROM npc_hostgroups hg
+ INNER JOIN npc_hostgroup_members hgm ON hg.hostgroup_id = hgm.hostgroup_id
+ INNER JOIN npc_hoststatus hs ON hgm.host_object_id = hs.host_object_id
+ INNER JOIN npc_objects o1 ON hg.hostgroup_object_id = o1.object_id
+ INNER JOIN npc_objects o2 ON hs.host_object_id = o2.object_id
+ INNER JOIN npc_instances i ON hg.instance_id = i.instance_id
+ WHERE ' . $where . '
+ ORDER BY o1.name1 ASC, o2.name1 ASC',
+ $params);
+ }
+
+ function setupResultsArray() {
+ $results = $this->getHostgroups();
+ $results = $this->flattenArray($results);
+ $results = $this->flattenNestedArray($results);
+
+ return $results;
+ }
}
-
-
-
diff --git a/controllers/hosts.php b/controllers/hosts.php
index 3422640..47c7f63 100644
--- a/controllers/hosts.php
+++ b/controllers/hosts.php
@@ -1,347 +1,264 @@
- * @copyright Copyright (c) 2007
- * @link http://trac2.assembla.com/npc
- * @package npc
- * @subpackage npc.controllers
- * @since NPC 2.0
- * @version $Id$
- */
-
-require_once($config["base_path"]."/plugins/npc/controllers/comments.php");
-
-/**
- * Hosts controller class
- *
- * Hosts controller provides functionality, such as building the
- * Doctrine queries and formatting output.
- *
- * @package npc
- * @subpackage npc.controllers
- */
-class NpcHostsController extends Controller {
+/*
+ +-------------------------------------------------------------------------+
+ | Nagios Plugin for Cacti |
+ | |
+ | Copyright (C) 2007 Billy Gunn (billy@gunn.org) |
+ | Copyright (C) 2004-2026 The Cacti Group |
+ +-------------------------------------------------------------------------+
+ | Cacti and Nagios are the copyright of their respective owners. |
+ +-------------------------------------------------------------------------+
+*/
+
+require_once($config['base_path'] . '/plugins/npc/controllers/comments.php');
- /**
- * getHosts
- *
- * Gets and formats hosts for output.
- *
- * @return string json output
- */
- function getHosts() {
-
- $results = $this->hosts();
-
- $comments = new NpcCommentsController;
-
- $hosts = $this->flattenArray($results);
-
-
- for ($i = 0; $i < count($hosts); $i++) {
- if ($hosts[$i]['problem_has_been_acknowledged']) {
- $hosts[$i]['acknowledgement'] = $comments->getAck($hosts[$i]['host_object_id']);
- }
- // Add the last comment to the array
- $hosts[$i]['comment'] = $comments->getLastComment($hosts[$i]['host_object_id']);
-
- // Count the services and delete the entries
- $services = 0;
- foreach ($hosts[$i] as $k => $v) {
- if (is_array($v)) {
- $services++;
- unset($hosts[$i][$k]);
- }
- }
-
- $hosts[$i]['service_count'] = $services;
- }
-
- $response['response']['value']['items'] = $hosts;
- $response['response']['value']['total_count'] = $this->numRecords;
- $response['response']['value']['version'] = 1;
-
- return(json_encode($response));
- }
-
- /**
- * getStateInfo
- *
- * Gets and formats host state information
- *
- * @return string json output
- */
- function getStateInfo() {
-
- $fields = array(
- 'current_state',
- 'output',
- 'perfdata',
- 'last_state_change',
- 'check_command',
- 'address',
- 'current_check_attempt',
- 'last_check',
- 'next_check',
- 'event_handler',
- 'latency',
- 'execution_time',
- 'is_flapping',
- 'scheduled_downtime_depth',
- 'process_performance_data',
- 'active_checks_enabled',
- 'passive_checks_enabled',
- 'event_handler_enabled',
- 'flap_detection_enabled',
- 'notifications_enabled',
- 'obsess_over_host'
- );
-
- $hosts = $this->hosts();
-
- $results = $this->flattenArray($hosts);
-
- $x = 0;
- foreach ($fields as $key) {
- $output[$x] = array('name' => $this->columnAlias[$key], 'value' => $this->formatStateInfo($key, $results[0]));
- $x++;
- }
-
- return($this->jsonOutput($output));
- }
-
- /**
- * summary
- *
- * Returns a state count for all hosts
- *
- * @return string json output
- */
- function summary() {
-
- $status = array(
- 'down' => 0,
- 'unreachable' => 0,
- 'up' => 0,
- 'pending' => 0
- );
-
- $q = new Doctrine_Query();
- $q->select('hs.current_state')
- ->from('NpcHoststatus hs')
- ->leftJoin('hs.Host h')
- ->where('h.config_type = ?', $this->config_type);
-
- $hosts = $q->execute(array(), Doctrine::HYDRATE_ARRAY);
-
- for ($i = 0; $i < count($hosts); $i++) {
- $status[$this->hostState[$hosts[$i]['current_state']]]++;
- }
-
- return($this->jsonOutput($status));
- }
-
- function getPerfData($id) {
-
- $q = new Doctrine_Query();
- $q->select('perfdata')->from('NpcHostchecks')->where('host_object_id = ?', $id);
-
- return($q->execute(array(), Doctrine::HYDRATE_ARRAY));
- }
-
- /**
- * hosts
- *
- * Retrieves all hosts along with status information
- *
- * @return array
- */
- function hosts() {
-
- // Maps searchable fields passed in from the client
- $fieldMap = array('host_name' => 'o.name1',
- 'alias' => 'h.alias',
- 'output' => 'hs.output');
-
-
- // Build the where clause
- $where = " hs.current_state in (" . $this->stringToState[$this->state] . ") AND h.config_type = " . $this->config_type;
-
-
- if ($this->id) {
- $where .= sprintf(" AND hs.host_object_id = %d", $this->id);
- }
-
- if ($this->searchString) {
- $where = $this->searchClause($where, $fieldMap);
- }
-
- if ($this->sort) {
- $orderBy = $this->sort . ' ' . $this->dir;
- } else {
- $orderBy = 'i.instance_name ASC, host_name ASC';
- }
-
- $q = new Doctrine_Pager(
- Doctrine_Query::create()
- ->select('i.instance_name,'
- .'o.name1 AS host_name,'
- .'h.alias,'
- .'h.address,'
- .'h.notes,'
- .'h.notes_url,'
- .'h.action_url,'
- .'h.icon_image,'
- .'h.icon_image_alt,'
- .'s.service_object_id,'
- .'s.display_name,'
- .'g.local_graph_id,'
- .'hs.*')
- ->from('NpcHoststatus hs')
- ->leftJoin('hs.Object o')
- ->leftJoin('hs.Host h')
- ->leftJoin('hs.Instance i')
- ->leftJoin('hs.Services s')
- ->leftJoin('hs.Graph g')
- ->where($where)
- ->orderby($orderBy),
- $this->currentPage,
- $this->limit
- );
-
- $hosts = $q->execute(array(), Doctrine::HYDRATE_ARRAY);
-
- // Set the total number of records
- $this->numRecords = $q->getNumResults();
-
- return($hosts);
- }
-
- /**
- * listHostsCli
- *
- * Returns all hosts and associated object ID's
- *
- * @return array Array of hosts/id's
- */
- function listHostsCli() {
-
- $q = new Doctrine_Query();
- $q->select('display_name as name, host_object_id as id, address')->from('NpcHosts')->orderBy('display_name ASC');
-
- return($q->execute(array(), Doctrine::HYDRATE_ARRAY));
- }
-
- /**
- * getMappedGraph
- *
- * Returns the requested npc_host_graphs record
- *
- * @return string json encoded results
- */
- function getMappedGraph() {
-
- $q = new Doctrine_Query();
- $q->select('hg.*')
- ->from('NpcHostGraphs hg')
- ->where('hg.host_object_id = ?', $this->id);
-
- $results = $q->execute(array(), Doctrine::HYDRATE_ARRAY);
-
- return($this->jsonOutput($results));
- }
-
- /**
- * setMappedGraph
- *
- * Sets the graph mapping
- *
- * @return string json encoded results
- */
- function setMappedGraph($params) {
-
- $table = $this->conn->getTable('NpcHostGraphs');
-
- $results = $table->findByDql("host_object_id = ?", array($params['object_id']));
- $graph = $results[0];
-
- if (!isset($graph->local_graph_id)) {
- $graph = new NpcServiceGraphs();
- }
-
- $graph->host_object_id = $params['object_id'];
- $graph->local_graph_id = $params['local_graph_id'];
- $graph->save();
-
- return(json_encode(array('success' => true)));
- }
-
-
-
- /**
- * formatStateInfo
- *
- * Formats the host state info results for display
- *
- * @return string The formatted results
- */
- function formatStateInfo($key, $results) {
-
- // Set the default return value
- $return = $results[$key];
-
- $cs = array(
- '0' => '
',
- '1' => '
',
- '2' => '
',
- '-1' => '
'
- );
-
- if ($key == 'current_state') {
- $return = $cs[$results[$key]];
- if ($results['problem_has_been_acknowledged']) {
- $comments = new NpcCommentsController;
- $string = $comments->getAck($results['host_object_id']);
- $ack = preg_split("/\*\|\*/", $string);
- $return = '
' . $return . ' (Acknowledged by ' . $ack[0] . ')
';
- }
- }
-
- if ($key == 'current_check_attempt') {
- $return = $results[$key] . '/' . $results['max_check_attempts'];
- }
-
- if (preg_match("/_enabled/", $key) || $key == 'obsess_over_host') {
- if($results[$key]) {
- $return = '
';
- } else {
- $return = '
';
- }
- }
-
- if ($key == 'last_state_change' || $key == 'last_check' || $key == 'next_check') {
- $format = read_config_option('npc_date_format') . ' ' . read_config_option('npc_time_format');
- $return = date($format, strtotime($results[$key]));
- }
-
- if ($key == 'scheduled_downtime_depth' || $key == 'is_flapping' || $key == 'process_performance_data') {
- if ($results[$key]) {
- $return = 'Yes';
- } else {
- $return = 'No';
- }
- }
-
- if ($return == '' || !$return) {
- $return = 'NA';
- }
-
- return($return);
- }
+class NpcHostsController extends Controller {
+ function getHosts() {
+ $results = $this->hosts();
+
+ $comments = new NpcCommentsController;
+ $hosts = $this->flattenArray($results);
+
+ for ($i = 0; $i < count($hosts); $i++) {
+ if ($hosts[$i]['problem_has_been_acknowledged']) {
+ $hosts[$i]['acknowledgement'] = $comments->getAck($hosts[$i]['host_object_id']);
+ }
+ $hosts[$i]['comment'] = $comments->getLastComment($hosts[$i]['host_object_id']);
+
+ $services = 0;
+ foreach ($hosts[$i] as $k => $v) {
+ if (is_array($v)) {
+ $services++;
+ unset($hosts[$i][$k]);
+ }
+ }
+ $hosts[$i]['service_count'] = $services;
+ }
+
+ $response = array(
+ 'response' => array(
+ 'value' => array(
+ 'items' => $hosts,
+ 'total_count' => $this->numRecords,
+ 'version' => 1,
+ )
+ )
+ );
+
+ return json_encode($response);
+ }
+
+ function getStateInfo() {
+ $fields = array(
+ 'current_state', 'output', 'perfdata', 'last_state_change',
+ 'check_command', 'address', 'current_check_attempt', 'last_check',
+ 'next_check', 'event_handler', 'latency', 'execution_time',
+ 'is_flapping', 'scheduled_downtime_depth', 'process_performance_data',
+ 'active_checks_enabled', 'passive_checks_enabled',
+ 'event_handler_enabled', 'flap_detection_enabled',
+ 'notifications_enabled', 'obsess_over_host'
+ );
+
+ $hosts = $this->hosts();
+ $results = $this->flattenArray($hosts);
+ $output = array();
+
+ $x = 0;
+ foreach ($fields as $key) {
+ $output[$x] = array(
+ 'name' => $this->columnAlias[$key],
+ 'value' => $this->formatStateInfo($key, $results[0])
+ );
+ $x++;
+ }
+
+ return $this->jsonOutput($output);
+ }
+
+ function summary() {
+ $status = array(
+ 'down' => 0,
+ 'unreachable' => 0,
+ 'up' => 0,
+ 'pending' => 0
+ );
+
+ $hosts = db_fetch_assoc_prepared('SELECT hs.current_state
+ FROM npc_hoststatus hs
+ LEFT JOIN npc_hosts h ON hs.host_object_id = h.host_object_id
+ WHERE h.config_type = ?',
+ array($this->config_type));
+
+ for ($i = 0; $i < count($hosts); $i++) {
+ $state_key = $hosts[$i]['current_state'];
+ if (isset($this->hostState[$state_key])) {
+ $status[$this->hostState[$state_key]]++;
+ }
+ }
+
+ return $this->jsonOutput($status);
+ }
+
+ function getPerfData($id) {
+ return db_fetch_assoc_prepared('SELECT perfdata
+ FROM npc_hostchecks
+ WHERE host_object_id = ?',
+ array($id));
+ }
+
+ function hosts() {
+ $fieldMap = array(
+ 'host_name' => 'o.name1',
+ 'alias' => 'h.alias',
+ 'output' => 'hs.output'
+ );
+
+ $params = array();
+ $where = '';
+
+ /* State filter */
+ $states = $this->stringToState[$this->state];
+ $state_list = implode(',', array_map('intval', explode(',', $states)));
+ $where .= 'hs.current_state IN (' . $state_list . ')';
+ $where .= ' AND h.config_type = ?';
+ $params[] = $this->config_type;
+
+ if ($this->id) {
+ $where .= ' AND hs.host_object_id = ?';
+ $params[] = intval($this->id);
+ }
+
+ if ($this->searchString) {
+ $where = $this->searchClause($where, $fieldMap, $params);
+ }
+
+ $orderBy = 'i.instance_name ASC, o.name1 ASC';
+ if ($this->sort) {
+ $allowed_sorts = array(
+ 'instance_name', 'host_name', 'alias', 'address',
+ 'current_state', 'last_check', 'output', 'last_state_change'
+ );
+ if (in_array($this->sort, $allowed_sorts, true)) {
+ $dir = ($this->dir == 'DESC') ? 'DESC' : 'ASC';
+ $orderBy = $this->sort . ' ' . $dir;
+ }
+ }
+
+ /* Total count */
+ $this->numRecords = db_fetch_cell_prepared(
+ 'SELECT COUNT(*)
+ FROM npc_hoststatus hs
+ LEFT JOIN npc_objects o ON hs.host_object_id = o.object_id
+ LEFT JOIN npc_hosts h ON hs.host_object_id = h.host_object_id
+ LEFT JOIN npc_instances i ON h.instance_id = i.instance_id
+ WHERE ' . $where,
+ $params);
+
+ /* Paginated results */
+ $offset = ($this->currentPage - 1) * $this->limit;
+
+ $hosts = db_fetch_assoc_prepared(
+ 'SELECT i.instance_name,
+ o.name1 AS host_name,
+ h.alias,
+ h.address,
+ h.notes,
+ h.notes_url,
+ h.action_url,
+ h.icon_image,
+ h.icon_image_alt,
+ hg.local_graph_id,
+ hs.*
+ FROM npc_hoststatus hs
+ LEFT JOIN npc_objects o ON hs.host_object_id = o.object_id
+ LEFT JOIN npc_hosts h ON hs.host_object_id = h.host_object_id
+ LEFT JOIN npc_instances i ON h.instance_id = i.instance_id
+ LEFT JOIN npc_host_graphs hg ON hs.host_object_id = hg.host_object_id
+ WHERE ' . $where . '
+ ORDER BY ' . $orderBy . '
+ LIMIT ?, ?',
+ array_merge($params, array($offset, $this->limit)));
+
+ return $hosts;
+ }
+
+ function listHostsCli() {
+ return db_fetch_assoc('SELECT display_name AS name, host_object_id AS id, address
+ FROM npc_hosts
+ ORDER BY display_name ASC');
+ }
+
+ function getMappedGraph() {
+ $results = db_fetch_assoc_prepared(
+ 'SELECT * FROM npc_host_graphs WHERE host_object_id = ?',
+ array($this->id));
+
+ return $this->jsonOutput($results);
+ }
+
+ function setMappedGraph($params) {
+ $object_id = intval($params['object_id']);
+ $local_graph_id = intval($params['local_graph_id']);
+
+ $existing = db_fetch_row_prepared(
+ 'SELECT * FROM npc_host_graphs WHERE host_object_id = ?',
+ array($object_id));
+
+ if (cacti_sizeof($existing)) {
+ db_execute_prepared(
+ 'UPDATE npc_host_graphs SET local_graph_id = ? WHERE host_object_id = ?',
+ array($local_graph_id, $object_id));
+ } else {
+ db_execute_prepared(
+ 'INSERT INTO npc_host_graphs (host_object_id, local_graph_id) VALUES (?, ?)',
+ array($object_id, $local_graph_id));
+ }
+
+ return json_encode(array('success' => true));
+ }
+
+ function formatStateInfo($key, $results) {
+ $return = isset($results[$key]) ? $results[$key] : '';
+
+ $cs = array(
+ '0' => '',
+ '1' => '',
+ '2' => '',
+ '-1' => ''
+ );
+
+ if ($key == 'current_state') {
+ $return = isset($cs[$results[$key]]) ? $cs[$results[$key]] : '';
+ if ($results['problem_has_been_acknowledged']) {
+ $comments = new NpcCommentsController;
+ $string = $comments->getAck($results['host_object_id']);
+ $ack = preg_split('/\*\|\*/', $string);
+ $return .= ' (Acknowledged by ' . html_escape($ack[0]) . ')';
+ }
+ }
+
+ if ($key == 'current_check_attempt') {
+ $return = $results[$key] . '/' . $results['max_check_attempts'];
+ }
+
+ if (preg_match('/_enabled/', $key) || $key == 'obsess_over_host') {
+ $return = $results[$key] ? __('Yes', 'npc') : __('No', 'npc');
+ }
+
+ if ($key == 'last_state_change' || $key == 'last_check' || $key == 'next_check') {
+ $format = read_config_option('npc_date_format') . ' ' . read_config_option('npc_time_format');
+ $return = date($format, strtotime($results[$key]));
+ }
+
+ if ($key == 'scheduled_downtime_depth' || $key == 'is_flapping' || $key == 'process_performance_data') {
+ $return = $results[$key] ? __('Yes', 'npc') : __('No', 'npc');
+ }
+
+ if ($return == '' || !$return) {
+ $return = __('N/A', 'npc');
+ }
+
+ return $return;
+ }
}
diff --git a/controllers/layout.php b/controllers/layout.php
index 45396c4..77134da 100644
--- a/controllers/layout.php
+++ b/controllers/layout.php
@@ -1,87 +1,64 @@
drawCommonFrame($config['url_path'] . 'plugins/npc/npc.php?module=layout&action=drawLayout', $params);
- }
-
- function drawLayout($params) {
+ function drawFrame($params) {
$config = $params['config'];
- $npc_base = $config['url_path'] . 'plugins/npc/js/';
- $npc_ext_base = $config['url_path'] . 'plugins/npc/js/ext/';
- $npc_css_base = $config['url_path'] . 'plugins/npc/css/';
- ?>
-
-
-
-
-
-
-
-
+ general_header();
-
-
-
-
-
-
-
-
-
+
\n";
+
+ bottom_footer();
+ }
+}
diff --git a/controllers/layoutDev.php b/controllers/layoutDev.php
deleted file mode 100644
index d7f1735..0000000
--- a/controllers/layoutDev.php
+++ /dev/null
@@ -1,135 +0,0 @@
-drawCommonFrame($config['url_path'] . 'plugins/npc/npc.php?module=layoutDev&action=drawLayout', $params);
- }
-
- function drawLayout($params) {
- $config = $params['config'];
- $npc_ext_base = $config['url_path'] . 'plugins/npc/js/ext/';
- $npc_plugins_base = $config['url_path'] . 'plugins/npc/js/src/plugins/';
- $npc_monitor_base = $config['url_path'] . 'plugins/npc/js/src/monitoring/';
- $npc_common_base = $config['url_path'] . 'plugins/npc/js/src/';
- $npc_css_base = $config['url_path'] . 'plugins/npc/css/';
- ?>
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 'l.logentry_data',
'instance_name' => 'i.instance_name');
-
$where = '1 = 1';
+ $params = array();
if ($this->searchString) {
- $where = $this->searchClause($where, $fieldMap);
+ $where = $this->searchClause($where, $fieldMap, $params);
}
- $q = new Doctrine_Pager(
- Doctrine_Query::create()
- ->select('i.instance_name,'
- .'l.*')
- ->from('NpcLogentries l')
- ->leftJoin('l.Instance i')
- ->where("$where")
- ->orderby( 'l.entry_time DESC, l.entry_time_usec DESC' ),
- $this->currentPage,
- $this->limit
- );
+ /* Get total count */
+ $this->numRecords = db_fetch_cell_prepared('SELECT COUNT(*)
+ FROM npc_logentries l
+ LEFT JOIN npc_instances i ON l.instance_id = i.instance_id
+ WHERE ' . $where,
+ $params);
+
+ $offset = ($this->currentPage - 1) * $this->limit;
- $results = $this->flattenArray($q->execute(array(), Doctrine::HYDRATE_ARRAY));
+ $results = db_fetch_assoc_prepared('SELECT i.instance_name, l.*
+ FROM npc_logentries l
+ LEFT JOIN npc_instances i ON l.instance_id = i.instance_id
+ WHERE ' . $where . '
+ ORDER BY l.entry_time DESC, l.entry_time_usec DESC
+ LIMIT ?, ?',
+ array_merge($params, array($offset, $this->limit)));
- // Set the total number of records
- $this->numRecords = $q->getNumResults();
+ $results = $this->flattenArray($results);
$response['response']['value']['items'] = $results;
$response['response']['value']['total_count'] = $this->numRecords;
diff --git a/controllers/nagios.php b/controllers/nagios.php
index c05c329..2128759 100644
--- a/controllers/nagios.php
+++ b/controllers/nagios.php
@@ -91,19 +91,15 @@ function getProcessInfoGrid() {
* @return string json output
*/
function processInfo() {
- $q = new Doctrine_Query();
- $q->select('ps.*')->from('NpcProgramstatus ps');
-
- $results = $q->execute(array(), Doctrine::HYDRATE_ARRAY);
+ $results = db_fetch_assoc_prepared('SELECT ps.*
+ FROM npc_programstatus ps', array());
if (cacti_sizeof($results)) {
- $q = new Doctrine_Query();
- $q->select('p.instance_id, p.program_version, max(p.processevent_id)')
- ->from('NpcProcessevents p')
- ->where('p.instance_id = ?', $results[0]['instance_id'])
- ->groupby('p.program_version');
-
- $version = $q->execute(array(), Doctrine::HYDRATE_ARRAY);
+ $version = db_fetch_assoc_prepared('SELECT p.instance_id, p.program_version, MAX(p.processevent_id) AS max_id
+ FROM npc_processevents p
+ WHERE p.instance_id = ?
+ GROUP BY p.program_version',
+ array($results[0]['instance_id']));
$results[0]['server_time'] = date('Y-m-d H:i:s');
if (isset($version[0])) {
@@ -126,7 +122,7 @@ function processInfo() {
* @return string
*/
function command($params) {
- // Get the passed command
+ /* Get the passed command */
$cmd = $params['command'];
$globalCommands = array(
@@ -155,7 +151,7 @@ function command($params) {
$nagios = new NagiosCmd;
$args = array();
- // Do some sanity checking:
+ /* Do some sanity checking */
if (!read_config_option('npc_nagios_commands')) {
$response = array('success' => false, 'msg' => __('Remote Commands must be enabled under console->Settings->NPC', 'npc'));
@@ -172,23 +168,21 @@ function command($params) {
return(json_encode($response));
}
- // A quick hack to check that the user has permission to
- // execute the command based on realm setting
+ /* Check that the user has permission to execute the command */
if (!api_plugin_user_realm_auth('npc1.php')) {
$response = array('success' => false, 'msg' => __('You do not have permission to execute this command.', 'npc'));
return(json_encode($response));
}
- // Get the command definition
+ /* Get the command definition */
$commandDef = $nagios->getCommands($cmd);
- // Build the args array
+ /* Build the args array */
foreach ($commandDef as $k => $v) {
if (isset($params[$k])) {
$value = $params[$k];
- // Checkboxes from EXT come as a string of either "true" or "false".
- // These need to be set to 1 or 0
+ /* Checkboxes from EXT come as a string of either "true" or "false". */
if ($value == 'true') {
$value = 1;
}
@@ -198,13 +192,8 @@ function command($params) {
}
if ($k == 'comment') {
- // Replace newline characters:
$value = str_replace(array("\r", "\n"), '
', $value);
-
- // Replace html spaces
$value = str_replace(" ", ' ', $value);
-
- // Strip any semicolons
$value = str_replace(";", ' ', $value);
}
@@ -212,26 +201,25 @@ function command($params) {
}
}
- // Build the command string
+ /* Build the command string */
if (!$nagios->setCommand($cmd, $args)) {
$response = array('success' => false, 'msg' => $nagios->message);
return(json_encode($response));
}
- // Execute the command
+ /* Execute the command */
if (!$nagios->execute()) {
$response = array('success' => false, 'msg' => $nagios->message);
return(json_encode($response));
}
- // Some forms require extra business logic like running another command.
+ /* Some forms require extra business logic */
if ($cmd == "SCHEDULE_HOSTGROUP_SVC_DOWNTIME" && $params['hosts'] == 'true') {
$cmd = 'SCHEDULE_HOSTGROUP_HOST_DOWNTIME';
$nagios->setCommand($cmd, $args);
$nagios->execute();
}
- // Return success to the form
return(json_encode(array('success' => true)));
}
@@ -243,40 +231,41 @@ function command($params) {
* @return string json output
*/
function checkPerf($params) {
- // Set the resolution in days to measure check performance.
if (isset($params['resolution'])) {
$resolution = $params['resolution'];
} else {
$resolution = 7;
}
- $q = new Doctrine_Query();
- $q->select('ROUND(MIN(hc.execution_time), 3) AS min_execution,
- ROUND(MAX(hc.execution_time), 3) AS max_execution,
- ROUND(AVG(hc.execution_time), 3) AS avg_execution,
- ROUND(MIN(hc.latency), 3) AS min_latency,
- ROUND(MAX(hc.latency), 3) AS max_latency,
- ROUND(AVG(hc.latency), 3) AS avg_latency'
- );
- $q->from('NpcHostchecks hc, NpcHosts h, NpcObjects o');
- $q->where('hc.host_object_id = o.object_id AND o.is_active = 1 AND hc.start_time > DATE_SUB(NOW(),INTERVAL ? DAY) '
- . 'AND hc.host_object_id = h.host_object_id AND h.active_checks_enabled = 1');
-
- $hostPerf = $q->execute(array($resolution), Doctrine::HYDRATE_ARRAY);
-
- $q = new Doctrine_Query();
- $q->select('ROUND(MIN(sc.execution_time), 3) AS min_execution,
- ROUND(MAX(sc.execution_time), 3) AS max_execution,
- ROUND(AVG(sc.execution_time), 3) AS avg_execution,
- ROUND(MIN(sc.latency), 3) AS min_latency,
- ROUND(MAX(sc.latency), 3) AS max_latency,
- ROUND(AVG(sc.latency), 3) AS avg_latency'
- );
- $q->from('NpcServicechecks sc, NpcServices s, NpcObjects o');
- $q->where('sc.service_object_id = o.object_id AND o.is_active = 1 AND sc.start_time > DATE_SUB(NOW(),INTERVAL ? DAY) '
- . 'AND sc.service_object_id = s.service_object_id AND s.active_checks_enabled = 1');
-
- $servicePerf = $q->execute(array($resolution), Doctrine::HYDRATE_ARRAY);
+ $hostPerf = db_fetch_assoc_prepared('SELECT
+ ROUND(MIN(hc.execution_time), 3) AS min_execution,
+ ROUND(MAX(hc.execution_time), 3) AS max_execution,
+ ROUND(AVG(hc.execution_time), 3) AS avg_execution,
+ ROUND(MIN(hc.latency), 3) AS min_latency,
+ ROUND(MAX(hc.latency), 3) AS max_latency,
+ ROUND(AVG(hc.latency), 3) AS avg_latency
+ FROM npc_hostchecks hc, npc_hosts h, npc_objects o
+ WHERE hc.host_object_id = o.object_id
+ AND o.is_active = 1
+ AND hc.start_time > DATE_SUB(NOW(), INTERVAL ? DAY)
+ AND hc.host_object_id = h.host_object_id
+ AND h.active_checks_enabled = 1',
+ array($resolution));
+
+ $servicePerf = db_fetch_assoc_prepared('SELECT
+ ROUND(MIN(sc.execution_time), 3) AS min_execution,
+ ROUND(MAX(sc.execution_time), 3) AS max_execution,
+ ROUND(AVG(sc.execution_time), 3) AS avg_execution,
+ ROUND(MIN(sc.latency), 3) AS min_latency,
+ ROUND(MAX(sc.latency), 3) AS max_latency,
+ ROUND(AVG(sc.latency), 3) AS avg_latency
+ FROM npc_servicechecks sc, npc_services s, npc_objects o
+ WHERE sc.service_object_id = o.object_id
+ AND o.is_active = 1
+ AND sc.start_time > DATE_SUB(NOW(), INTERVAL ? DAY)
+ AND sc.service_object_id = s.service_object_id
+ AND s.active_checks_enabled = 1',
+ array($resolution));
$output = array(
array_merge(array('name' => __('Service Check Execution Time', 'npc')), array_slice($servicePerf[0], 0, 3)),
@@ -300,13 +289,10 @@ function checkPerf($params) {
* formatProcessInfo
*
* Formats the process info results for display.
- * This is a workaround for some of the limitations of
- * EXT property grid.
*
* @return string The formatted results
*/
function formatProcessInfo($key, $results) {
- // Set the default return value
$return = $results[$key];
$toggle = array(
@@ -322,12 +308,8 @@ function formatProcessInfo($key, $results) {
'process_performance_data'
);
- if (in_array($key, $toggle)) {
- if($results[$key]) {
- $return = '
';
- } else {
- $return = '
';
- }
+ if (in_array($key, $toggle, true)) {
+ $return = $results[$key] ? __('Yes', 'npc') : __('No', 'npc');
}
if ($key == 'program_start_time' || $key == 'status_update_time' || $key == 'last_command_check' || $key == 'last_log_rotation' || $key == 'program_end_time') {
@@ -348,4 +330,3 @@ function formatProcessInfo($key, $results) {
return($return);
}
}
-
diff --git a/controllers/notifications.php b/controllers/notifications.php
index 09ef65f..095b09f 100644
--- a/controllers/notifications.php
+++ b/controllers/notifications.php
@@ -18,7 +18,7 @@
* Notifications controller class
*
* Notifications controller provides functionality, such as building the
- * Doctrine queries and formatting output.
+ * queries and formatting output.
*
* @package npc
* @subpackage npc.controllers
@@ -35,30 +35,34 @@ class NpcNotificationsController extends Controller {
function getNotifications() {
$where = '1 = 1';
+ $params = array();
if ($this->id) {
- $where = sprintf("n.object_id = %d", $this->id);
+ $where = 'n.object_id = ?';
+ $params[] = $this->id;
}
- $q = new Doctrine_Pager(
- Doctrine_Query::create()
- ->select('i.instance_name,'
- .'o.name1 AS host_name,'
- .'o.name2 AS service_description,'
- .'n.*')
- ->from('NpcNotifications n')
- ->leftJoin('n.Object o')
- ->leftJoin('n.Instance i')
- ->where("$where")
- ->orderby( 'n.start_time DESC, n.start_time_usec DESC' ),
- $this->currentPage,
- $this->limit
- );
+ /* Get total count */
+ $this->numRecords = db_fetch_cell_prepared('SELECT COUNT(*)
+ FROM npc_notifications n
+ LEFT JOIN npc_objects o ON n.object_id = o.object_id
+ LEFT JOIN npc_instances i ON n.instance_id = i.instance_id
+ WHERE ' . $where,
+ $params);
- $results = $q->execute(array(), Doctrine::HYDRATE_ARRAY);
+ $offset = ($this->currentPage - 1) * $this->limit;
- // Set the total number of records
- $this->numRecords = $q->getNumResults();
+ $results = db_fetch_assoc_prepared('SELECT i.instance_name,
+ o.name1 AS host_name,
+ o.name2 AS service_description,
+ n.*
+ FROM npc_notifications n
+ LEFT JOIN npc_objects o ON n.object_id = o.object_id
+ LEFT JOIN npc_instances i ON n.instance_id = i.instance_id
+ WHERE ' . $where . '
+ ORDER BY n.start_time DESC, n.start_time_usec DESC
+ LIMIT ?, ?',
+ array_merge($params, array($offset, $this->limit)));
return($this->jsonOutput($results));
}
diff --git a/controllers/servicegroups.php b/controllers/servicegroups.php
index ce16296..6ea210d 100644
--- a/controllers/servicegroups.php
+++ b/controllers/servicegroups.php
@@ -1,366 +1,228 @@
- * @copyright Copyright (c) 2007
- * @link http://trac2.assembla.com/npc
- * @package npc
- * @subpackage npc.controllers
- * @since NPC 2.0
- * @version $Id$
- */
-
-require_once("include/auth.php");
-require_once("plugins/npc/controllers/comments.php");
-
-/**
- * Servicegroups controller class
- *
- * Servicegroups controller provides functionality, such as building the
- * Doctrine queries and formatting output.
- *
- * @package npc
- * @subpackage npc.controllers
- */
-class NpcServicegroupsController extends Controller {
-
- /**
- * A host status cache
- *
- * @var array
- * @access private
- */
- private $hostStatusCache = array();
-
-
- /**
- * getHostStatusPortlet
- *
- * Returns host status counts by servicegroup.
- *
- * @return string json output
- */
- function getHostStatusPortlet() {
-
- $startTime = $this->getTime();
-
- // Initialize the output array
- $output = array();
-
- // Initialize the hosts array
- $hosts = array();
-
- $fields = array('servicegroup_object_id',
- 'alias',
- 'instance_id');
-
- // Combine servicegroup/service/host etc. into a single record
- $results = $this->setupResultsArray();
-
- // Loop through the results array and build an output array
- // that includes a single record per servicegroup
- // and the number of crit, warn , ok services within
- // that servicegroup.
- for ($i = 0; $i < count($results); $i++) {
- $sg = $results[$i]['servicegroup_object_id'];
- if(!isset($output[$sg])) {
- $output[$sg] = array('down' => 0,
- 'unreachable' => 0,
- 'up' => 0,
- 'pending' => 0);
- }
- if (!isset($hosts[$sg][$results[$i]['host_name']])) {
- $hostState = $this->getServicegroupMemberHoststatus($results[$i]['host_name']);
- $output[$sg][$this->hostState[$hostState]]++;
- $hosts[$sg][$results[$i]['host_name']] = 1;
- }
- foreach ($results[$i] as $key => $val) {
- if (in_array($key, $fields)) {
- $output[$sg][$key] = $val;
- }
- }
- }
-
- // Set the total number of records
- $this->numRecords = count($output);
-
- // Implement paging by slicing the output array
- $output = array_slice($output, $this->start, $this->limit);
-
- $response['response']['value']['items'] = $output;
- $response['response']['value']['total_count'] = $this->numRecords;
- $response['response']['value']['version'] = 1;
-
- $this->logger('debug', get_class($this), 'getHostStatusPortlet', "Method execution time: ".sprintf("%01.2f", ($this->getTime() - $startTime)). " seconds");
-
- return(json_encode($response));
- }
-
- /**
- * getServicegroupServiceStatus
- *
- * Returns service status counts by servicegroup.
- *
- * @return string json output
- */
- function getServicegroupServiceStatus() {
-
- $startTime = $this->getTime();
-
- // Initialize the output array
- $output = array();
-
- $fields = array('servicegroup_object_id',
- 'alias',
- 'instance_id');
-
- // Combine servicegroup/service/host etc. into a single record
- $results = $this->setupResultsArray();
-
- for ($i = 0; $i < count($results); $i++) {
- $sg = $results[$i]['servicegroup_object_id'];
- if(!isset($output[$sg])) {
- $output[$sg] = array('critical' => 0,
- 'warning' => 0,
- 'unknown' => 0,
- 'ok' => 0,
- 'pending' => 0);
- }
- foreach ($results[$i] as $key => $val) {
- if ($key == 'current_state') {
- $output[$sg][$this->serviceState[$val]]++;
- } else if(in_array($key, $fields)) {
- $output[$sg][$key] = $val;
- }
- }
- }
-
- // Set the total number of records
- $this->numRecords = count($output);
-
- // Implement paging by slicing the output array
- $output = array_slice($output, $this->start, $this->limit);
-
- $response['response']['value']['items'] = $output;
- $response['response']['value']['total_count'] = $this->numRecords;
- $response['response']['value']['version'] = 1;
-
- $this->logger('debug', get_class($this), 'getServicegroupServiceStatus', "Method execution time: ".sprintf("%01.2f", ($this->getTime() - $startTime)). " seconds");
-
- return(json_encode($response));
- }
-
- /**
- * getOverview
- *
- * Returns all hosts by servicegroup. Used to populate
- * the Servicegroup Grid screen.
- *
- * @return string json output
- */
- function getOverview() {
-
- $startTime = $this->getTime();
-
- $fields = array('servicegroup_object_id',
- 'alias',
- 'instance_id',
- 'host_name');
-
- // Initialize the output array
- $output = array();
-
- // Combine servicegroup/service/host etc. into a single record
- $results = $this->setupResultsArray();
-
- // Loop through the results array and build an output array
- // that includes a single record per host with the servicegroup
- // and the number of crit, warn , ok services within
- // that servicegroup.
- for ($i = 0; $i < count($results); $i++) {
- $sg = $results[$i]['servicegroup_object_id'];
- $host = $results[$i]['host_name'];
- $hostState = $this->getServicegroupMemberHoststatus($host);
- if(!isset($temp[$sg][$host])) {
- $temp[$sg][$host] = array('host_state' => $hostState,
- 'critical' => 0,
- 'warning' => 0,
- 'unknown' => 0,
- 'ok' => 0,
- 'pending' => 0);
- }
- foreach ($results[$i] as $key => $val) {
- if ($key == 'current_state') {
- $temp[$sg][$host][$this->serviceState[$val]]++;
- } else if(in_array($key, $fields)) {
- $temp[$sg][$host][$key] = $val;
- }
- }
- }
-
- $x = 0;
- foreach ($temp as $i => $s) {
- foreach ($s as $h => $v) {
- foreach ($v as $key => $val) {
- $output[$x][$key] = $val;
- }
- $x++;
- }
- }
-
- // Set the total number of records
- $this->numRecords = count($output);
-
- // Implement paging by slicing the output array
- $output = array_slice($output, $this->start, $this->limit);
-
- $this->logger('debug', get_class($this), 'getOverview', "Method execution time: ".sprintf("%01.2f", ($this->getTime() - $startTime)). " seconds");
-
- return($this->jsonOutput($output));
- }
-
- /**
- * getHostSummary
- *
- * Returns host status by servicegroup
- *
- * @return string json output
- */
- function getHostSummary() {
- $status = $this->getServicegroupMemberHoststatus('workstation');
-
- print_r($status);
- exit;
- }
-
- /**
- * getServices
- *
- * Returns all services by servicegroup. Used to populate
- * the Servicegroup Grid screen.
- *
- * @return string json output
- */
- function getServices() {
-
- $startTime = $this->getTime();
-
- $results = $this->setupResultsArray();
-
- $comments = new NpcCommentsController;
-
- $services = $this->flattenArray($results);
-
- for ($i = 0; $i < count($services); $i++) {
- if ($services[$i]['problem_has_been_acknowledged']) {
- $services[$i]['acknowledgement'] = $comments->getAck($services[$i]['service_object_id']);
- }
- // Add the last comment to the array
- $services[$i]['comment'] = $comments->getLastComment($services[$i]['service_object_id']);
- }
-
- // Set the total number of records
- $this->numRecords = count($services);
-
- // Implement paging by slicing the output array
- $services = array_slice($services, $this->start, $this->limit);
-
- $this->logger('debug', get_class($this), 'getServices', "Method execution time: ".sprintf("%01.2f", ($this->getTime() - $startTime)). " seconds");
-
- return($this->jsonOutput($services));
- }
-
- function getServicegroupMemberHoststatus($hostname) {
-
- $startTime = $this->getTime();
-
- if(isset($this->hostStatusCache[$hostname])) {
- return($this->hostStatusCache[$hostname]);
- }
-
- $q = new Doctrine_Query();
- $q->select('hs.current_state')
- ->from('NpcHoststatus hs, NpcHosts h')
- ->where('hs.host_object_id = h.host_object_id AND h.display_name = ?', $hostname);
-
- $results = $q->execute(array(), Doctrine::HYDRATE_ARRAY);
-
- $this->hostStatusCache[$hostname] = $results[0]['current_state'];
-
- $this->logger('debug', get_class($this), 'getServicegroupMemberHoststatus', "Method execution time: ".sprintf("%01.2f", ($this->getTime() - $startTime)). " seconds");
-
- return($this->hostStatusCache[$hostname]);
- }
-
- function getServicegroups() {
-
- $startTime = $this->getTime();
-
- $where = '1 = 1';
-
- if ($this->id) {
- $where = "sg.servicegroup_object_id = " . $this->id;
- }
-
- // Maps searchable fields passed in from the client
- $fieldMap = array('service_description' => 'o2.name2',
- 'host_name' => 'o2.name1',
- 'alias' => 'sg.alias',
- 'output' => 'ss.output');
-
- if ($this->searchString) {
- $where .= $this->searchClause(null, $fieldMap);
- }
-
- $q = new Doctrine_Query();
- $q->select('i.instance_name,'
- .'o1.name1 AS servicegroup_name,'
- .'o2.name1 AS host_name,'
- .'o2.name2 AS service_description,'
- .'ss.*,'
- .'sg.*')
- ->from('NpcServicegroups sg')
- ->innerJoin('sg.ServicegroupMembers sgm')
- ->innerJoin('sg.Servicestatus ss ON sgm.service_object_id = ss.service_object_id')
- ->innerJoin('sg.Object o1')
- ->innerJoin('ss.Object o2')
- ->innerJoin('sg.Instance i')
- ->where("$where")
- ->orderBy('servicegroup_name ASC, host_name ASC, service_description ASC');
-
- $results = $q->execute(array(), Doctrine::HYDRATE_ARRAY);
+/*
+ +-------------------------------------------------------------------------+
+ | Nagios Plugin for Cacti |
+ | |
+ | Copyright (C) 2007 Billy Gunn (billy@gunn.org) |
+ | Copyright (C) 2004-2026 The Cacti Group |
+ +-------------------------------------------------------------------------+
+ | Cacti and Nagios are the copyright of their respective owners. |
+ +-------------------------------------------------------------------------+
+*/
+
+require_once('include/auth.php');
+require_once('plugins/npc/controllers/comments.php');
- $this->logger('debug', get_class($this), 'getServicegroups', "Method execution time: ".sprintf("%01.2f", ($this->getTime() - $startTime)). " seconds");
-
- return($results);
- }
-
- /**
- * setupResultsArray
- *
- * A utility method to handle some common formatting tasks.
- *
- * @return array
- */
- function setupResultsArray() {
-
- // Get the servicegroups
- $results = $this->getServicegroups();
-
- // Flatten the 1st level of nested arrays
- $results = $this->flattenArray($results);
-
- // Combine servicegroup/service/host etc. into a single record.
- $results = $this->flattenNestedArray($results);
-
- return($results);
- }
+class NpcServicegroupsController extends Controller {
+ private $hostStatusCache = array();
+
+ function getHostStatusPortlet() {
+ $output = array();
+ $hosts = array();
+ $fields = array('servicegroup_object_id', 'alias', 'instance_id');
+
+ $results = $this->setupResultsArray();
+
+ for ($i = 0; $i < count($results); $i++) {
+ $sg = $results[$i]['servicegroup_object_id'];
+ if (!isset($output[$sg])) {
+ $output[$sg] = array('down' => 0, 'unreachable' => 0, 'up' => 0, 'pending' => 0);
+ }
+ if (!isset($hosts[$sg][$results[$i]['host_name']])) {
+ $hostState = $this->getServicegroupMemberHoststatus($results[$i]['host_name']);
+ if (isset($this->hostState[$hostState])) {
+ $output[$sg][$this->hostState[$hostState]]++;
+ }
+ $hosts[$sg][$results[$i]['host_name']] = 1;
+ }
+ foreach ($results[$i] as $key => $val) {
+ if (in_array($key, $fields, true)) {
+ $output[$sg][$key] = $val;
+ }
+ }
+ }
+
+ $this->numRecords = count($output);
+ $output = array_slice($output, $this->start, $this->limit);
+
+ $response = array(
+ 'response' => array(
+ 'value' => array(
+ 'items' => $output,
+ 'total_count' => $this->numRecords,
+ 'version' => 1,
+ )
+ )
+ );
+
+ return json_encode($response);
+ }
+
+ function getServicegroupServiceStatus() {
+ $output = array();
+ $fields = array('servicegroup_object_id', 'alias', 'instance_id');
+
+ $results = $this->setupResultsArray();
+
+ for ($i = 0; $i < count($results); $i++) {
+ $sg = $results[$i]['servicegroup_object_id'];
+ if (!isset($output[$sg])) {
+ $output[$sg] = array('critical' => 0, 'warning' => 0, 'unknown' => 0, 'ok' => 0, 'pending' => 0);
+ }
+ foreach ($results[$i] as $key => $val) {
+ if ($key == 'current_state' && isset($this->serviceState[$val])) {
+ $output[$sg][$this->serviceState[$val]]++;
+ } elseif (in_array($key, $fields, true)) {
+ $output[$sg][$key] = $val;
+ }
+ }
+ }
+
+ $this->numRecords = count($output);
+ $output = array_slice($output, $this->start, $this->limit);
+
+ $response = array(
+ 'response' => array(
+ 'value' => array(
+ 'items' => $output,
+ 'total_count' => $this->numRecords,
+ 'version' => 1,
+ )
+ )
+ );
+
+ return json_encode($response);
+ }
+
+ function getOverview() {
+ $fields = array('servicegroup_object_id', 'alias', 'instance_id', 'host_name');
+ $output = array();
+ $temp = array();
+
+ $results = $this->setupResultsArray();
+
+ for ($i = 0; $i < count($results); $i++) {
+ $sg = $results[$i]['servicegroup_object_id'];
+ $host = $results[$i]['host_name'];
+ $hostState = $this->getServicegroupMemberHoststatus($host);
+ if (!isset($temp[$sg][$host])) {
+ $temp[$sg][$host] = array(
+ 'host_state' => $hostState,
+ 'critical' => 0,
+ 'warning' => 0,
+ 'unknown' => 0,
+ 'ok' => 0,
+ 'pending' => 0
+ );
+ }
+ foreach ($results[$i] as $key => $val) {
+ if ($key == 'current_state' && isset($this->serviceState[$val])) {
+ $temp[$sg][$host][$this->serviceState[$val]]++;
+ } elseif (in_array($key, $fields, true)) {
+ $temp[$sg][$host][$key] = $val;
+ }
+ }
+ }
+
+ $x = 0;
+ foreach ($temp as $i => $s) {
+ foreach ($s as $h => $v) {
+ foreach ($v as $key => $val) {
+ $output[$x][$key] = $val;
+ }
+ $x++;
+ }
+ }
+
+ $this->numRecords = count($output);
+ $output = array_slice($output, $this->start, $this->limit);
+
+ return $this->jsonOutput($output);
+ }
+
+ function getHostSummary() {
+ /* Placeholder; original had debug print_r/exit */
+ return $this->jsonOutput(array());
+ }
+
+ function getServices() {
+ $results = $this->setupResultsArray();
+ $comments = new NpcCommentsController;
+ $services = $this->flattenArray($results);
+
+ for ($i = 0; $i < count($services); $i++) {
+ if ($services[$i]['problem_has_been_acknowledged']) {
+ $services[$i]['acknowledgement'] = $comments->getAck($services[$i]['service_object_id']);
+ }
+ $services[$i]['comment'] = $comments->getLastComment($services[$i]['service_object_id']);
+ }
+
+ $this->numRecords = count($services);
+ $services = array_slice($services, $this->start, $this->limit);
+
+ return $this->jsonOutput($services);
+ }
+
+ function getServicegroupMemberHoststatus($hostname) {
+ if (isset($this->hostStatusCache[$hostname])) {
+ return $this->hostStatusCache[$hostname];
+ }
+
+ $result = db_fetch_row_prepared(
+ 'SELECT hs.current_state
+ FROM npc_hoststatus hs
+ INNER JOIN npc_hosts h ON hs.host_object_id = h.host_object_id
+ WHERE h.display_name = ?',
+ array($hostname));
+
+ $this->hostStatusCache[$hostname] = cacti_sizeof($result) ? $result['current_state'] : '0';
+
+ return $this->hostStatusCache[$hostname];
+ }
+
+ function getServicegroups() {
+ $fieldMap = array(
+ 'servicegroup_name' => 'o1.name1',
+ 'host_name' => 'o2.name1',
+ 'service_description' => 'o2.name2',
+ 'output' => 'ss.output'
+ );
+ $params = array();
+ $where = '1 = 1';
+
+ if ($this->id) {
+ $where .= ' AND sg.servicegroup_object_id = ?';
+ $params[] = intval($this->id);
+ }
+
+ if ($this->searchString) {
+ $where = $this->searchClause($where, $fieldMap, $params);
+ }
+
+ return db_fetch_assoc_prepared(
+ 'SELECT DISTINCT i.instance_name,
+ o1.name1 AS servicegroup_name,
+ o2.name1 AS host_name,
+ o2.name2 AS service_description,
+ ss.*,
+ sg.*
+ FROM npc_servicegroups sg
+ INNER JOIN npc_servicegroup_members sgm ON sg.servicegroup_id = sgm.servicegroup_id
+ INNER JOIN npc_servicestatus ss ON sgm.service_object_id = ss.service_object_id
+ INNER JOIN npc_objects o1 ON sg.servicegroup_object_id = o1.object_id
+ INNER JOIN npc_objects o2 ON ss.service_object_id = o2.object_id
+ INNER JOIN npc_instances i ON sg.instance_id = i.instance_id
+ WHERE ' . $where . '
+ ORDER BY o1.name1 ASC, o2.name1 ASC, o2.name2 ASC',
+ $params);
+ }
+
+ function setupResultsArray() {
+ $results = $this->getServicegroups();
+ $results = $this->flattenArray($results);
+ $results = $this->flattenNestedArray($results);
+
+ return $results;
+ }
}
-
-
-
diff --git a/controllers/services.php b/controllers/services.php
index 508daf4..c0a86b7 100644
--- a/controllers/services.php
+++ b/controllers/services.php
@@ -1,478 +1,372 @@
- * @copyright Copyright (c) 2007
- * @link http://trac2.assembla.com/npc
- * @package npc
- * @subpackage npc.controllers
- * @since NPC 2.0
- * @version $Id$
- */
-
-require_once($config["base_path"]."/plugins/npc/controllers/comments.php");
-require_once($config["base_path"]."/plugins/npc/controllers/downtime.php");
-
-/**
- * Services controller class
- *
- * Services controller provides functionality, such as building the
- * Doctrine queries and formatting output.
- *
- * @package npc
- * @subpackage npc.controllers
- */
+/*
+ +-------------------------------------------------------------------------+
+ | Nagios Plugin for Cacti |
+ | |
+ | Copyright (C) 2007 Billy Gunn (billy@gunn.org) |
+ | Copyright (C) 2004-2026 The Cacti Group |
+ +-------------------------------------------------------------------------+
+ | Cacti and Nagios are the copyright of their respective owners. |
+ +-------------------------------------------------------------------------+
+*/
+
+require_once($config['base_path'] . '/plugins/npc/controllers/comments.php');
+require_once($config['base_path'] . '/plugins/npc/controllers/downtime.php');
+
class NpcServicesController extends Controller {
- /**
- * getServices
- *
- * Gets and formats services for output.
- *
- * @return string json output
- */
- function getServices() {
-
- $services = $this->services();
-
- $comments = new NpcCommentsController;
- $downtime = new NpcDowntimeController;
-
- for ($i = 0; $i < count($services); $i++) {
-
- foreach($services[$i] as $k => $v) {
- if (is_array($v)) {
- $services[$i] = array_merge($services[$i], $v);
- unset($services[$i][$k]);
- }
- }
-
- unset($services[$i]['Host']);
- if ($services[$i]['problem_has_been_acknowledged']) {
- $services[$i]['acknowledgement'] = $comments->getAck($services[$i]['service_object_id']);
- }
-
- // Add the last comment to the array
- $services[$i]['comment'] = $comments->getLastComment($services[$i]['service_object_id']);
-
- // Set the in_downtime bit
- $services[$i]['in_downtime'] = 0;
- if ($downtime->inDowntime($services[$i]['service_object_id'])) {
- $services[$i]['in_downtime'] = 1;
- }
- }
-
- $response['response']['value']['items'] = $services;
- $response['response']['value']['total_count'] = $this->numRecords;
- $response['response']['value']['version'] = 1;
-
- return(json_encode($response));
- }
-
- /**
- * getStateInfo
- *
- * Gets and formats service state information
- *
- * @return string json output
- */
- function getStateInfo() {
-
- require_once("plugins/npc/controllers/hostgroups.php");
- $obj = new NpcHostgroupsController;
- $hg = $obj->setupResultsArray();
- // $results[$i]['hostgroup_object_id']
-
- $fields = array(
- 'current_state',
- 'output',
- 'perfdata',
- 'notes',
- 'last_state_change',
- 'check_command',
- 'command_line',
- 'host_address',
- 'Host Groups',
- 'current_check_attempt',
- 'last_check',
- 'next_check',
- 'event_handler',
- 'latency',
- 'execution_time',
- 'is_flapping',
- 'scheduled_downtime_depth',
- 'process_performance_data',
- 'active_checks_enabled',
- 'passive_checks_enabled',
- 'event_handler_enabled',
- 'flap_detection_enabled',
- 'notifications_enabled',
- 'obsess_over_service'
- );
-
- $service = $this->services();
-
- $results = $this->flattenArray($service);
-
- $hostgroups = array();
- foreach ($hg as $i => $a) {
- if ($a['host_name'] == $results[0]['host_name']) {
- $hostgroups[] = $a['hostgroup_name'];
- }
- }
-
- $x = 0;
- foreach ($fields as $key) {
- if ($key == 'Host Groups') {
- $name = 'Host Groups';
- $value = implode(", ", array_unique($hostgroups));
- } else {
- $name = $this->columnAlias[$key];
- $value = $this->formatStateInfo($key, $results[0]);
- }
-
- $output[$x] = array('name' => $name, 'value' => $value);
- $x++;
- }
-
- return($this->jsonOutput($output));
- }
-
- /**
- * summary
- *
- * Returns a summary of the state of all services.
- *
- * @return string json output
- */
- function summary() {
-
- $status = array('critical' => 0,
- 'warning' => 0,
- 'unknown' => 0,
- 'ok' => 0,
- 'pending' => 0);
-
- $q = new Doctrine_Query();
- $q->select('ss.current_state')
- ->from('NpcServicestatus ss')
- ->leftJoin('ss.Service s')
- ->where('s.config_type = ?', $this->config_type);
-
- $services = $q->execute(array(), Doctrine::HYDRATE_ARRAY);
-
- for ($i = 0; $i < count($services); $i++) {
- $status[$this->serviceState[$services[$i]['current_state']]]++;
- }
-
- return($this->jsonOutput($status));
- }
-
- /**
- * getServiceStatesByHost
- *
- * A utility method to simply return the state of every service belonging
- * to the specified host.
- *
- * @return array list of all services with status
- */
- function getServiceStatesByHost($host_object_id) {
-
- $q = new Doctrine_Query();
- $q->select('ss.current_state')
- ->from('NpcServicestatus ss, NpcServices s')
- ->where('ss.service_object_id = s.service_object_id AND s.host_object_id = ?', $host_object_id);
-
- $results = $q->execute(array(), Doctrine::HYDRATE_ARRAY);
-
- return($results);
- }
-
- /**
- * services
- *
- * Retrieves all services along with status information
- *
- * @return array list of all services with status
- */
- function services($id=null, $where=null) {
-
- // Maps searchable fields passed in from the client
- $fieldMap = array('service_description' => 'o.name2',
- 'host_name' => 'o.name1',
- 'host_alias' => 'h.alias',
- 'notes' => 's.notes',
- 'output' => 'ss.output');
-
-
- // Build the where clause
- if ($where) {
- $where .= ' AND ';
- }
-
- $where .= " ss.current_state in (" . $this->stringToState[$this->state] . ") AND s.config_type = " . $this->config_type;
-
- if (isset($this->unhandled)) {
- $where .= " AND ss.problem_has_been_acknowledged = 0 ";
- }
-
- if ($this->id || $id) {
- $where .= sprintf(" AND s.service_object_id = %d", is_null($id) ? $this->id : $id);;
- }
+ function getServices() {
+ $services = $this->services();
+
+ $comments = new NpcCommentsController;
+ $downtime = new NpcDowntimeController;
+
+ for ($i = 0; $i < count($services); $i++) {
+ foreach ($services[$i] as $k => $v) {
+ if (is_array($v)) {
+ $services[$i] = array_merge($services[$i], $v);
+ unset($services[$i][$k]);
+ }
+ }
+
+ unset($services[$i]['Host']);
+
+ if ($services[$i]['problem_has_been_acknowledged']) {
+ $services[$i]['acknowledgement'] = $comments->getAck($services[$i]['service_object_id']);
+ }
+
+ $services[$i]['comment'] = $comments->getLastComment($services[$i]['service_object_id']);
+
+ $services[$i]['in_downtime'] = 0;
+ if ($downtime->inDowntime($services[$i]['service_object_id'])) {
+ $services[$i]['in_downtime'] = 1;
+ }
+ }
+
+ $response = array(
+ 'response' => array(
+ 'value' => array(
+ 'items' => $services,
+ 'total_count' => $this->numRecords,
+ 'version' => 1,
+ )
+ )
+ );
+
+ return json_encode($response);
+ }
+
+ function getStateInfo() {
+ require_once('plugins/npc/controllers/hostgroups.php');
+ $obj = new NpcHostgroupsController;
+ $hg = $obj->setupResultsArray();
+
+ $fields = array(
+ 'current_state', 'output', 'perfdata', 'notes',
+ 'last_state_change', 'check_command', 'command_line',
+ 'host_address', 'Host Groups', 'current_check_attempt',
+ 'last_check', 'next_check', 'event_handler', 'latency',
+ 'execution_time', 'is_flapping', 'scheduled_downtime_depth',
+ 'process_performance_data', 'active_checks_enabled',
+ 'passive_checks_enabled', 'event_handler_enabled',
+ 'flap_detection_enabled', 'notifications_enabled',
+ 'obsess_over_service'
+ );
+
+ $service = $this->services();
+ $results = $this->flattenArray($service);
+
+ $hostgroups = array();
+ foreach ($hg as $i => $a) {
+ if ($a['host_name'] == $results[0]['host_name']) {
+ $hostgroups[] = $a['hostgroup_name'];
+ }
+ }
+
+ $output = array();
+ $x = 0;
+ foreach ($fields as $key) {
+ if ($key == 'Host Groups') {
+ $name = __('Host Groups', 'npc');
+ $value = implode(', ', array_unique($hostgroups));
+ } else {
+ $name = $this->columnAlias[$key];
+ $value = $this->formatStateInfo($key, $results[0]);
+ }
+ $output[$x] = array('name' => $name, 'value' => $value);
+ $x++;
+ }
+
+ return $this->jsonOutput($output);
+ }
+
+ function summary() {
+ $status = array(
+ 'critical' => 0,
+ 'warning' => 0,
+ 'unknown' => 0,
+ 'ok' => 0,
+ 'pending' => 0
+ );
+
+ $services = db_fetch_assoc_prepared('SELECT ss.current_state
+ FROM npc_servicestatus ss
+ LEFT JOIN npc_services s ON ss.service_object_id = s.service_object_id
+ WHERE s.config_type = ?',
+ array($this->config_type));
+
+ for ($i = 0; $i < count($services); $i++) {
+ $state_key = $services[$i]['current_state'];
+ if (isset($this->serviceState[$state_key])) {
+ $status[$this->serviceState[$state_key]]++;
+ }
+ }
+
+ return $this->jsonOutput($status);
+ }
+
+ function getServiceStatesByHost($host_object_id) {
+ return db_fetch_assoc_prepared('SELECT ss.current_state
+ FROM npc_servicestatus ss
+ INNER JOIN npc_services s ON ss.service_object_id = s.service_object_id
+ WHERE s.host_object_id = ?',
+ array($host_object_id));
+ }
+
+ function services($id = null, $where = null) {
+ $fieldMap = array(
+ 'service_description' => 'o.name2',
+ 'host_name' => 'o.name1',
+ 'host_alias' => 'h.alias',
+ 'notes' => 's.notes',
+ 'output' => 'ss.output'
+ );
+
+ $params = array();
+
+ if ($where) {
+ $where .= ' AND ';
+ } else {
+ $where = '';
+ }
+
+ $states = $this->stringToState[$this->state];
+ $state_list = implode(',', array_map('intval', explode(',', $states)));
+ $where .= 'ss.current_state IN (' . $state_list . ')';
+ $where .= ' AND s.config_type = ?';
+ $params[] = $this->config_type;
+
+ if (isset($this->unhandled)) {
+ $where .= ' AND ss.problem_has_been_acknowledged = 0';
+ }
+
+ $svc_id = $this->id ? $this->id : $id;
+ if ($svc_id) {
+ $where .= ' AND s.service_object_id = ?';
+ $params[] = intval($svc_id);
+ }
if (isset($this->hostgroup)) {
- $where .= sprintf(" AND hg.alias = '%s'", $this->hostgroup);
+ $where .= ' AND hg.alias = ?';
+ $params[] = $this->hostgroup;
}
- if ($this->searchString) {
- $where = $this->searchClause($where, $fieldMap);
- }
+ if ($this->searchString) {
+ $where = $this->searchClause($where, $fieldMap, $params);
+ }
+ $orderBy = 'o.name1 ASC, o.name2 ASC';
if ($this->sort) {
- $orderBy = $this->sort . ' ' . $this->dir;
+ $allowed_sorts = array(
+ 'instance_name', 'host_name', 'service_description', 'host_alias',
+ 'host_address', 'current_state', 'last_check', 'output',
+ 'last_state_change'
+ );
+ if (in_array($this->sort, $allowed_sorts, true)) {
+ $dir = ($this->dir == 'DESC') ? 'DESC' : 'ASC';
+ $orderBy = $this->sort . ' ' . $dir;
+ }
+ }
+
+ /* Total count */
+ $this->numRecords = db_fetch_cell_prepared(
+ 'SELECT COUNT(*)
+ FROM npc_servicestatus ss
+ LEFT JOIN npc_objects o ON ss.service_object_id = o.object_id
+ LEFT JOIN npc_services s ON ss.service_object_id = s.service_object_id
+ LEFT JOIN npc_hosts h ON s.host_object_id = h.host_object_id
+ LEFT JOIN npc_hostgroup_members hgm ON h.host_object_id = hgm.host_object_id
+ LEFT JOIN npc_hostgroups hg ON hgm.hostgroup_id = hg.hostgroup_id
+ LEFT JOIN npc_instances i ON s.instance_id = i.instance_id
+ WHERE ' . $where,
+ $params);
+
+ $offset = ($this->currentPage - 1) * $this->limit;
+
+ $services = db_fetch_assoc_prepared(
+ 'SELECT i.instance_name,
+ s.host_object_id,
+ s.notes,
+ s.notes_url,
+ s.action_url,
+ s.icon_image,
+ s.icon_image_alt,
+ h.alias AS host_alias,
+ h.address AS host_address,
+ h.icon_image AS host_icon_image,
+ h.icon_image_alt AS host_icon_image_alt,
+ h.host_object_id,
+ o.name1 AS host_name,
+ o.name2 AS service_description,
+ sg.local_graph_id,
+ ss.*
+ FROM npc_servicestatus ss
+ LEFT JOIN npc_objects o ON ss.service_object_id = o.object_id
+ LEFT JOIN npc_services s ON ss.service_object_id = s.service_object_id
+ LEFT JOIN npc_hosts h ON s.host_object_id = h.host_object_id
+ LEFT JOIN npc_hostgroup_members hgm ON h.host_object_id = hgm.host_object_id
+ LEFT JOIN npc_hostgroups hg ON hgm.hostgroup_id = hg.hostgroup_id
+ LEFT JOIN npc_instances i ON s.instance_id = i.instance_id
+ LEFT JOIN npc_service_graphs sg ON ss.service_object_id = sg.service_object_id
+ WHERE ' . $where . '
+ ORDER BY ' . $orderBy . '
+ LIMIT ?, ?',
+ array_merge($params, array($offset, $this->limit)));
+
+ return $services;
+ }
+
+ function getPerfData($id = null, $host = null, $service = null) {
+ $id = $this->id ? $this->id : $id;
+
+ if (!$host) {
+ $check_id = db_fetch_cell_prepared(
+ 'SELECT MAX(servicecheck_id) FROM npc_servicechecks WHERE service_object_id = ?',
+ array($id));
} else {
- $orderBy = 'host_name ASC, service_description ASC';
+ $check_id = db_fetch_cell_prepared(
+ 'SELECT MAX(n.servicecheck_id)
+ FROM npc_servicechecks n
+ INNER JOIN npc_objects o ON o.object_id = n.service_object_id
+ WHERE o.is_active = 1 AND o.name1 = ? AND o.name2 = ?',
+ array($host, $service));
}
- $q = new Doctrine_Pager(
- Doctrine_Query::create()
- ->select('i.instance_name,'
- .'s.host_object_id,'
- .'s.notes,'
- .'s.notes_url,'
- .'s.action_url,'
- .'s.icon_image,'
- .'s.icon_image_alt,'
- .'h.alias AS host_alias,'
- .'h.address AS host_address,'
- .'h.icon_image AS host_icon_image,'
- .'h.icon_image_alt AS host_icon_image_alt,'
- .'h.host_object_id,'
- .'hg.hostgroup_id,'
- .'o.name1 AS host_name,'
- .'o.name2 AS service_description,'
- .'g.local_graph_id,'
- .'ss.*')
- ->from('NpcServicestatus ss')
- ->leftJoin('ss.Object o')
- ->leftJoin('ss.Service s')
- ->leftJoin('s.Host h')
- ->leftJoin('h.Hostgroup hg')
- ->leftJoin('ss.Instance i')
- ->leftJoin('ss.Graph g')
- ->where($where)
- ->orderby($orderBy),
- $this->currentPage,
- $this->limit
- );
-
- $services = $q->execute(array(), Doctrine::HYDRATE_ARRAY);
-
- // Set the total number of records
- $this->numRecords = $q->getNumResults();
-
- return($services);
- }
-
- /**
- * Returns the last perfdata entry for a particular service
- *
- * @return array
- */
- function getPerfData($id=null, $host=null, $service=null) {
-
- $id = $this->id ? $this->id : $id;
-
-
- // Get the last update
- if (!$host) {
- $q = new Doctrine_Query();
- $q->select('max(n.servicecheck_id) AS id')
- ->from('NpcServicechecks n')
- ->where('n.service_object_id = ?', $id);
- $id = $q->execute();
- } else {
- $q = new Doctrine_Query();
- $q->select('max(n.servicecheck_id) AS id')
- ->from('NpcServicechecks n, NpcObjects o')
- ->where('o.is_active = 1 AND o.object_id = n.service_object_id')
- ->andWhere('o.name1 = ?', $host)
- ->andWhere('o.name2 = ?', $service);
- $id = $q->execute();
- }
-
- // Get the perf data
- $q = new Doctrine_Query();
- $q->select('n.*')
- ->from('NpcServicechecks n')
- ->where('n.servicecheck_id = ?', $id[0]['id']);
-
- return($q->execute(array(), Doctrine::HYDRATE_ARRAY));
- }
-
- /**
- * Returns the performance history for the specified service and period
- *
- * @return array
- */
- function getPerfHistory($host, $service, $begin, $end=null) {
-
- $q = new Doctrine_Query();
- $q->select('end_time, perfdata')
- ->from('NpcServicechecks n, NpcObjects o')
- ->where('o.is_active = 1 AND o.object_id = n.service_object_id')
- ->andWhere('o.name1 = ?', $host)
- ->andWhere('o.name2 = ?', $service)
- ->andWhere('n.end_time >= ?', $begin);
-
- if ($end) {
- $q->andWhere('n.end_time <= ?', $end);
- }
-
- return($q->execute(array(), Doctrine::HYDRATE_ARRAY));
- }
-
-
- /**
- * listServivcesCli
- *
- * Returns all services and associated object ID's
- *
- * @return array Array of services/id's
- */
- function listServicesCli($host = null) {
-
- $q = new Doctrine_Query();
- $q->select('s.*,'
- .'h.display_name AS host,'
- .'i.instance_name AS instance')
- ->from('NpcServices s, s.Host h, s.Instance i');
+ if (!$check_id) {
+ return array();
+ }
+
+ return db_fetch_assoc_prepared(
+ 'SELECT * FROM npc_servicechecks WHERE servicecheck_id = ?',
+ array($check_id));
+ }
+
+ function getPerfHistory($host, $service, $begin, $end = null) {
+ $params = array($host, $service, $begin);
+ $sql = 'SELECT n.end_time, n.perfdata
+ FROM npc_servicechecks n
+ INNER JOIN npc_objects o ON o.object_id = n.service_object_id
+ WHERE o.is_active = 1 AND o.name1 = ? AND o.name2 = ?
+ AND n.end_time >= ?';
+
+ if ($end) {
+ $sql .= ' AND n.end_time <= ?';
+ $params[] = $end;
+ }
+
+ return db_fetch_assoc_prepared($sql, $params);
+ }
+
+ function listServicesCli($host = null) {
+ $sql = 'SELECT s.*, h.display_name AS host, i.instance_name AS instance
+ FROM npc_services s
+ LEFT JOIN npc_hosts h ON s.host_object_id = h.host_object_id
+ LEFT JOIN npc_instances i ON s.instance_id = i.instance_id';
if ($host) {
- $q->where('h.display_name = ?', $host);
+ $sql .= ' WHERE h.display_name = ?';
+ return $this->flattenArray(db_fetch_assoc_prepared($sql, array($host)));
}
- return($this->flattenArray($q->execute(array(), Doctrine::HYDRATE_ARRAY)));
- }
-
- /**
- * getMappedGraph
- *
- * Returns the url to the currently mapped graph
- *
- * @return string json encoded results
- */
- function getMappedGraph() {
- $q = new Doctrine_Query();
- $q->select('sg.*')
- ->from('NpcServiceGraphs sg')
- ->where('sg.service_object_id = ?', $this->id);
-
- $results = $q->execute(array(), Doctrine::HYDRATE_ARRAY);
-
- return($this->jsonOutput($results));
- }
-
- /**
- * setMappedGraph
- *
- * Sets the graph mapping
- *
- * @return string json encoded results
- */
- function setMappedGraph($params) {
- $table = $this->conn->getTable('NpcServiceGraphs');
-
- $results = $table->findByDql("service_object_id = ?", array($params['object_id']));
- $graph = $results[0];
-
- if (!isset($graph->local_graph_id)) {
- $graph = new NpcServiceGraphs();
- }
-
- $graph->service_object_id = $params['object_id'];
- $graph->local_graph_id = $params['local_graph_id'];
- $graph->save();
-
- return(json_encode(array('success' => true)));
- }
-
- /**
- * formatStateInfo
- *
- * Formats the service state info results for display.
- * This is a workaround for some of the limitations of
- * EXT property grid.
- *
- * @return string The formatted results
- */
- function formatStateInfo($key, $results) {
-
- // Set the default return value
- if (isset($results[$key])) {
- $return = $results[$key];
- }
-
- $cs = array(
- '0' => '
',
- '1' => '
',
- '2' => '
',
- '3' => '
',
- '-1' => '
'
- );
-
- if ($key == 'current_state') {
- $return = $cs[$results[$key]];
- if ($results['problem_has_been_acknowledged']) {
- $comments = new NpcCommentsController;
- $string = $comments->getAck($results['service_object_id']);
- $ack = preg_split("/\*\|\*/", $string);
- $return = '' . $return . ' (Acknowledged by ' . $ack[0] . ')
';
- }
- }
-
- if ($key == 'current_check_attempt') {
- $return = $results[$key] . '/' . $results['max_check_attempts'];
- }
-
- if (preg_match("/_enabled/", $key) || $key == 'obsess_over_service') {
- if($results[$key]) {
- $return = '
';
- } else {
- $return = '
';
- }
- }
-
- if ($key == 'last_state_change' || $key == 'last_check' || $key == 'next_check') {
- $format = read_config_option('npc_date_format') . ' ' . read_config_option('npc_time_format');
- $return = date($format, strtotime($results[$key]));
- }
-
- if ($key == 'scheduled_downtime_depth' || $key == 'is_flapping' || $key == 'process_performance_data') {
- if ($results[$key]) {
- $return = 'Yes';
- } else {
- $return = 'No';
- }
- }
-
- // Add the full command as a tooltip
- if ($key == 'command_line') {
- $perf = $this->getPerfData($results['service_object_id']);
- $return = $perf[0]['command_line'];
- }
-
- if ($return == '' || !$return) {
- $return = 'NA';
- }
-
- return($return);
- }
-}
+ return $this->flattenArray(db_fetch_assoc($sql));
+ }
+
+ function getMappedGraph() {
+ $results = db_fetch_assoc_prepared(
+ 'SELECT * FROM npc_service_graphs WHERE service_object_id = ?',
+ array($this->id));
+
+ return $this->jsonOutput($results);
+ }
+ function setMappedGraph($params) {
+ $object_id = intval($params['object_id']);
+ $local_graph_id = intval($params['local_graph_id']);
+ $existing = db_fetch_row_prepared(
+ 'SELECT * FROM npc_service_graphs WHERE service_object_id = ?',
+ array($object_id));
+ if (cacti_sizeof($existing)) {
+ db_execute_prepared(
+ 'UPDATE npc_service_graphs SET local_graph_id = ? WHERE service_object_id = ?',
+ array($local_graph_id, $object_id));
+ } else {
+ db_execute_prepared(
+ 'INSERT INTO npc_service_graphs (service_object_id, local_graph_id) VALUES (?, ?)',
+ array($object_id, $local_graph_id));
+ }
+
+ return json_encode(array('success' => true));
+ }
+
+ function formatStateInfo($key, $results) {
+ $return = isset($results[$key]) ? $results[$key] : '';
+
+ $cs = array(
+ '0' => '',
+ '1' => '',
+ '2' => '',
+ '3' => '',
+ '-1' => ''
+ );
+
+ if ($key == 'current_state') {
+ $return = isset($cs[$results[$key]]) ? $cs[$results[$key]] : '';
+ if ($results['problem_has_been_acknowledged']) {
+ $comments = new NpcCommentsController;
+ $string = $comments->getAck($results['service_object_id']);
+ $ack = preg_split('/\*\|\*/', $string);
+ $return .= ' (Acknowledged by ' . html_escape($ack[0]) . ')';
+ }
+ }
+
+ if ($key == 'current_check_attempt') {
+ $return = $results[$key] . '/' . $results['max_check_attempts'];
+ }
+
+ if (preg_match('/_enabled/', $key) || $key == 'obsess_over_service') {
+ $return = $results[$key] ? __('Yes', 'npc') : __('No', 'npc');
+ }
+
+ if ($key == 'last_state_change' || $key == 'last_check' || $key == 'next_check') {
+ $format = read_config_option('npc_date_format') . ' ' . read_config_option('npc_time_format');
+ $return = date($format, strtotime($results[$key]));
+ }
+
+ if ($key == 'scheduled_downtime_depth' || $key == 'is_flapping' || $key == 'process_performance_data') {
+ $return = $results[$key] ? __('Yes', 'npc') : __('No', 'npc');
+ }
+
+ if ($key == 'command_line') {
+ $perf = $this->getPerfData($results['service_object_id']);
+ $return = cacti_sizeof($perf) ? $perf[0]['command_line'] : '';
+ }
+
+ if ($return == '' || !$return) {
+ $return = __('N/A', 'npc');
+ }
+
+ return $return;
+ }
+}
diff --git a/controllers/settings.php b/controllers/settings.php
index 94a7295..a154392 100644
--- a/controllers/settings.php
+++ b/controllers/settings.php
@@ -27,12 +27,12 @@
class NpcSettingsController extends Controller {
function getSettings($id) {
-
- $q = new Doctrine_Query();
- $settings = $this->conn->getTable('NpcSettings')->find($id);
+ $settings = db_fetch_row_prepared('SELECT *
+ FROM npc_settings
+ WHERE user_id = ?',
+ array($id));
return($settings);
-
}
function save($params) {
@@ -40,16 +40,17 @@ function save($params) {
$user_id = $_SESSION['sess_user_id'];
$obj = $this->getSettings($user_id);
- $settings = unserialize($obj->settings);
- if (isset($params['name'])) {
- $settings[$params['name']] = $params['value'];
- }
+ $settings = @unserialize($obj['settings'], ["allowed_classes" => false]);
+ if (isset($params['name'])) {
+ $settings[$params['name']] = $params['value'];
+ }
- $obj->settings = serialize($settings);
- $obj->save();
+ db_execute_prepared('UPDATE npc_settings
+ SET settings = ?
+ WHERE user_id = ?',
+ array(serialize($settings), $user_id));
return(true);
}
}
-
diff --git a/controllers/statehistory.php b/controllers/statehistory.php
index fecd924..dcada7b 100644
--- a/controllers/statehistory.php
+++ b/controllers/statehistory.php
@@ -18,7 +18,7 @@
* Statehistory controller class
*
* Statehistory controller provides functionality, such as building the
- * Doctrine queries and formatting output.
+ * queries and formatting output.
*
* @package npc
* @subpackage npc.controllers
@@ -35,30 +35,35 @@ class NpcStatehistoryController extends Controller {
function getStateHistory() {
$where = '1 = 1';
+ $params = array();
if ($this->id) {
- $where = sprintf("sh.object_id = %d ", $this->id);
+ $where = 'sh.object_id = ?';
+ $params[] = $this->id;
}
- $q = new Doctrine_Pager(
- Doctrine_Query::create()
- ->select('i.instance_name,'
- .'o.name1 AS host_name,'
- .'o.name2 AS service_description,'
- .'sh.*')
- ->from('NpcStatehistory sh')
- ->leftJoin('sh.Object o')
- ->leftJoin('sh.Instance i')
- ->where("$where")
- ->orderby( 'sh.state_time DESC, sh.state_time_usec DESC' ),
- $this->currentPage,
- $this->limit
- );
+ /* Get total count */
+ $this->numRecords = db_fetch_cell_prepared('SELECT COUNT(*)
+ FROM npc_statehistory sh
+ LEFT JOIN npc_objects o ON sh.object_id = o.object_id
+ LEFT JOIN npc_instances i ON sh.instance_id = i.instance_id
+ WHERE ' . $where,
+ $params);
- $results = $q->execute(array(), Doctrine::HYDRATE_ARRAY);
+ $offset = (int) (($this->currentPage - 1) * $this->limit);
+ $limit = (int) $this->limit;
- // Set the total number of records
- $this->numRecords = $q->getNumResults();
+ $results = db_fetch_assoc_prepared('SELECT i.instance_name,
+ o.name1 AS host_name,
+ o.name2 AS service_description,
+ sh.*
+ FROM npc_statehistory sh
+ LEFT JOIN npc_objects o ON sh.object_id = o.object_id
+ LEFT JOIN npc_instances i ON sh.instance_id = i.instance_id
+ WHERE ' . $where . '
+ ORDER BY sh.state_time DESC, sh.state_time_usec DESC
+ LIMIT ?, ?',
+ array_merge($params, array($offset, $limit)));
return($this->jsonOutput($results));
}
diff --git a/css/ext-ux-livegrid.css b/css/ext-ux-livegrid.css
deleted file mode 100644
index ef461b8..0000000
--- a/css/ext-ux-livegrid.css
+++ /dev/null
@@ -1,22 +0,0 @@
-.ext-ux-livegrid-drop-waiting {
- background-image:url(../images/loading.gif) !important;
-}
-
-.ext-ux-livegrid-liveScroller {
- z-index:1;
- background:none!important;
- position:absolute;
- height:3px;
- right:0px;
- width:18px;
- overflow:scroll;
- overflow-x:hidden;
-}
-
-.ext-ux-livegrid-liveScroller div {
- background:none;
- width:1px;
- overflow:hidden;
- font-size:1px;
- height:0px;
-}
\ No newline at end of file
diff --git a/css/main.css b/css/main.css
deleted file mode 100644
index 2311e6b..0000000
--- a/css/main.css
+++ /dev/null
@@ -1,229 +0,0 @@
-#msg-div {
-position:absolute;
-left:35%;
-top:10px;
-width:350px;
-z-index:20000;
-}
-
-.errorGo {
-background-image:url(../images/icons/error_go.png) !important;
-}
-
-.configuration {
-background-image:url(../images/icons/cog_go.png) !important;
-}
-
-.add {
-background-image:url(../images/icons/add.png) !important;
-}
-
-.cogAdd {
-background-image:url(../images/icons/cog_add.png) !important;
-}
-
-.appViewDetail {
-background-image:url(../images/icons/application_view_detail.png) !important;
-}
-
-.chartBar {
-background-image:url(../images/icons/chart_bar.png) !important;
-}
-
-.chartBarAdd {
-background-image:url(../images/icons/chart_bar_add.png) !important;
-}
-
-.scriptAdd {
-background-image:url(../images/icons/script_add.png) !important;
-}
-
-.commentAdd {
-background-image:url(../images/icons/comment_add.png) !important;
-}
-
-.commentsDelete {
-background-image:url(../images/icons/comments_delete.png) !important;
-}
-
-.commentDelete {
-background-image:url(../images/icons/comment_delete.png) !important;
-}
-
-.cancel {
-background-image:url(../images/icons/cancel.png) !important;
-}
-
-.reporting {
-background-image:url(../images/icons/report_go.png) !important;
-}
-
-.monitoring {
-background-image:url(../images/icons/application_view_gallery.png) !important;
-}
-
-.resultsetNext {
-background-image:url(../images/icons/resultset_next.png) !important;
-}
-
-.hosts {
-background-image:url(../images/icons/server.png) !important;
-}
-
-.tnode {
-background-image:url(../images/icons/folder.png) !important;
-}
-
-.tleaf {
-background-image:url(../images/icons/tab.png) !important;
-}
-
-.layout {
-background-image:url(../images/icons/layout.png);
-}
-
-.layoutEdit {
-background-image:url(../images/icons/layout_edit.png) !important;
-}
-
-.pageWhiteWrench {
-background-image:url(../images/icons/page_white_wrench.png) !important;
-}
-
-#navcontainer ul
-{
-list-style-type: none;
-text-align: left;
-}
-
-#navcontainer ul li a
-{
-background: transparent url(../images/list-off.gif) left center no-repeat;
-padding-left: 15px;
-text-align: left;
-font: normal 11px "Lucida Grande", "Lucida Sans Unicode", verdana, lucida, sans-serif;
-text-decoration: none;
-color: #999;
-}
-
-#navcontainer ul li a:hover
-{
-background: transparent url(../images/list-on.gif) left center no-repeat;
-color: black;
-}
-
-#navcontainer ul li a#current
-{
-background: transparent url(../images/list-active.gif) left center no-repeat;
-color: #666;
-}
-
-.x-portal .x-panel-dd-spacer {
- margin-bottom:10px;
-}
-
-.x-portlet {
- margin-bottom:10px;
-}
-
-/* Clean up the look of the portlets */
-.x-portlet .x-panel-ml {
- padding-left:2px;
-}
-.x-portlet .x-panel-mr {
- padding-right:2px;
-}
-.x-portlet .x-panel-bl {
- padding-left:2px;
-}
-
-.x-portlet .x-panel-br {
- padding-right:2px;
-}
-.x-portlet .x-panel-body {
- background:white;
-}
-.x-portlet .x-panel-mc {
- padding-top:2px;
-}
-.x-portlet .x-panel-bc .x-panel-footer {
- padding-bottom:2px;
-}
-.x-portlet .x-panel-nofooter .x-panel-bc {
- height:2px;
-}
-
-.x-form-checkbox {
- margin-top: 5px;
-}
-
-.xcheckbox-wrap {
- line-height: 18px;
- padding-top:2px;
-}
-.xcheckbox-wrap a {
- display:block;
- width:16px;
- height:16px;
-}
-.x-toolbar .xcheckbox-wrap {
- padding: 0 0 2px 0;
-}
-.xcheckbox-on {
- background:transparent url(../js/ext/resources/images/default/menu/checked.gif) no-repeat 0 0;
-}
-.xcheckbox-off {
- background:transparent url(../js/ext/resources/images/default/menu/unchecked.gif) no-repeat 0 0;
-}
-
-.x-grid3-cell-inner, .x-grid3-hd-inner{
- overflow:hidden;
- -o-text-overflow: ellipsis;
- text-overflow: ellipsis;
- padding:3px 3px 3px 5px;
- white-space: normal;
-}
-
-.status-bar {
- height:18px;
- float:left;
- width:0;
- border-top:1px solid #D1E4FD;
- border-bottom:1px solid #7FA9E4;
- border-right:1px solid #7FA9E4;
-}
-
-.status-bar-text {
- font-size:11px;
- font-weight:bold;
- color:#000000;
- padding:1px 5px;
- overflow:hidden;
- position:absolute;
- text-align:center;
-}
-.status-bar-text-back {
- color:#000000;
- line-height:16px;
-}
-
-
-.statusPENDING { background-color: #ACACAC; }
-.statusOK { background-color: #33FF00; }
-.statusRECOVERY { background-color: #33FF00; }
-.statusUNKNOWN { background-color: #FF9900; }
-.statusWARNING { background-color: #FFFF00; }
-.statusCRITICAL { background-color: #F83838; }
-
-.serviceTotalsOk { background: #33FF00; }
-.serviceTotalsWarning { background: #FFFF00; font-weight: bold; }
-.serviceTotalsUnknown { background: #FF9900; font-weight: bold; }
-.serviceTotalsCritical { background: #F83838; font-weight: bold; }
-.serviceTotalsPending { background: #0099FF; }
-.serviceTotalsProblems { background: orange; font-weight: bold; }
-
-.hostTotalsUp { background: #33FF00; }
-.hostTotalsDown { background: #F83838; }
-.hostTotalsUnreachable { background: #F83838; }
-.hostTotalsPending { background: #0099FF; }
-
diff --git a/js/ext/adapter/ext/ext-base.js b/js/ext/adapter/ext/ext-base.js
deleted file mode 100644
index b68f63d..0000000
--- a/js/ext/adapter/ext/ext-base.js
+++ /dev/null
@@ -1,10 +0,0 @@
-/*
- * Ext JS Library 2.2
- * Copyright(c) 2006-2008, Ext JS, LLC.
- * licensing@extjs.com
- *
- * http://extjs.com/license
- */
-
-Ext={version:"2.2"};window["undefined"]=window["undefined"];Ext.apply=function(C,D,B){if(B){Ext.apply(C,B)}if(C&&D&&typeof D=="object"){for(var A in D){C[A]=D[A]}}return C};(function(){var idSeed=0;var ua=navigator.userAgent.toLowerCase();var isStrict=document.compatMode=="CSS1Compat",isOpera=ua.indexOf("opera")>-1,isSafari=(/webkit|khtml/).test(ua),isSafari3=isSafari&&ua.indexOf("webkit/5")!=-1,isIE=!isOpera&&ua.indexOf("msie")>-1,isIE7=!isOpera&&ua.indexOf("msie 7")>-1,isGecko=!isSafari&&ua.indexOf("gecko")>-1,isGecko3=!isSafari&&ua.indexOf("rv:1.9")>-1,isBorderBox=isIE&&!isStrict,isWindows=(ua.indexOf("windows")!=-1||ua.indexOf("win32")!=-1),isMac=(ua.indexOf("macintosh")!=-1||ua.indexOf("mac os x")!=-1),isAir=(ua.indexOf("adobeair")!=-1),isLinux=(ua.indexOf("linux")!=-1),isSecure=window.location.href.toLowerCase().indexOf("https")===0;if(isIE&&!isIE7){try{document.execCommand("BackgroundImageCache",false,true)}catch(e){}}Ext.apply(Ext,{isStrict:isStrict,isSecure:isSecure,isReady:false,enableGarbageCollector:true,enableListenerCollection:false,SSL_SECURE_URL:"javascript:false",BLANK_IMAGE_URL:"http:/"+"/extjs.com/s.gif",emptyFn:function(){},applyIf:function(o,c){if(o&&c){for(var p in c){if(typeof o[p]=="undefined"){o[p]=c[p]}}}return o},addBehaviors:function(o){if(!Ext.isReady){Ext.onReady(function(){Ext.addBehaviors(o)});return }var cache={};for(var b in o){var parts=b.split("@");if(parts[1]){var s=parts[0];if(!cache[s]){cache[s]=Ext.select(s)}cache[s].on(parts[1],o[b])}}cache=null},id:function(el,prefix){prefix=prefix||"ext-gen";el=Ext.getDom(el);var id=prefix+(++idSeed);return el?(el.id?el.id:(el.id=id)):id},extend:function(){var io=function(o){for(var m in o){this[m]=o[m]}};var oc=Object.prototype.constructor;return function(sb,sp,overrides){if(typeof sp=="object"){overrides=sp;sp=sb;sb=overrides.constructor!=oc?overrides.constructor:function(){sp.apply(this,arguments)}}var F=function(){},sbp,spp=sp.prototype;F.prototype=spp;sbp=sb.prototype=new F();sbp.constructor=sb;sb.superclass=spp;if(spp.constructor==oc){spp.constructor=sp}sb.override=function(o){Ext.override(sb,o)};sbp.override=io;Ext.override(sb,overrides);sb.extend=function(o){Ext.extend(sb,o)};return sb}}(),override:function(origclass,overrides){if(overrides){var p=origclass.prototype;for(var method in overrides){p[method]=overrides[method]}}},namespace:function(){var a=arguments,o=null,i,j,d,rt;for(i=0;i=0){L=G[P]}if(!S||!L){return false}this.doRemove(S,O,L[this.WFN],false);delete G[P][this.WFN];delete G[P][this.FN];G.splice(P,1);return true},getTarget:function(N,M){N=N.browserEvent||N;var L=N.target||N.srcElement;return this.resolveTextNode(L)},resolveTextNode:function(L){if(Ext.isSafari&&L&&3==L.nodeType){return L.parentNode}else{return L}},getPageX:function(M){M=M.browserEvent||M;var L=M.pageX;if(!L&&0!==L){L=M.clientX||0;if(Ext.isIE){L+=this.getScroll()[1]}}return L},getPageY:function(L){L=L.browserEvent||L;var M=L.pageY;if(!M&&0!==M){M=L.clientY||0;if(Ext.isIE){M+=this.getScroll()[0]}}return M},getXY:function(L){L=L.browserEvent||L;return[this.getPageX(L),this.getPageY(L)]},getRelatedTarget:function(M){M=M.browserEvent||M;var L=M.relatedTarget;if(!L){if(M.type=="mouseout"){L=M.toElement}else{if(M.type=="mouseover"){L=M.fromElement}}}return this.resolveTextNode(L)},getTime:function(N){N=N.browserEvent||N;if(!N.time){var M=new Date().getTime();try{N.time=M}catch(L){this.lastError=L;return M}}return N.time},stopEvent:function(L){this.stopPropagation(L);this.preventDefault(L)},stopPropagation:function(L){L=L.browserEvent||L;if(L.stopPropagation){L.stopPropagation()}else{L.cancelBubble=true}},preventDefault:function(L){L=L.browserEvent||L;if(L.preventDefault){L.preventDefault()}else{L.returnValue=false}},getEvent:function(M){var L=M||window.event;if(!L){var N=this.getEvent.caller;while(N){L=N.arguments[0];if(L&&Event==L.constructor){break}N=N.caller}}return L},getCharCode:function(L){L=L.browserEvent||L;return L.charCode||L.keyCode||0},_getCacheIndex:function(Q,N,P){for(var O=0,M=G.length;O0)}var Q=[];for(var M=0,L=H.length;M0){for(var Q=0,S=T.length;Q0){O=G.length;while(O){N=O-1;M=G[N];if(M){R.removeListener(M[R.EL],M[R.TYPE],M[R.FN],N)}O=O-1}M=null;R.clearCache()}R.doRemove(window,"unload",R._unload)},getScroll:function(){var L=document.documentElement,M=document.body;if(L&&(L.scrollTop||L.scrollLeft)){return[L.scrollTop,L.scrollLeft]}else{if(M){return[M.scrollTop,M.scrollLeft]}else{return[0,0]}}},doAdd:function(){if(window.addEventListener){return function(O,M,N,L){O.addEventListener(M,N,(L))}}else{if(window.attachEvent){return function(O,M,N,L){O.attachEvent("on"+M,N)}}else{return function(){}}}}(),doRemove:function(){if(window.removeEventListener){return function(O,M,N,L){O.removeEventListener(M,N,(L))}}else{if(window.detachEvent){return function(N,L,M){N.detachEvent("on"+L,M)}}else{return function(){}}}}()}}();var D=Ext.lib.Event;D.on=D.addListener;D.un=D.removeListener;if(document&&document.body){D._load()}else{D.doAdd(window,"load",D._load)}D.doAdd(window,"unload",D._unload);D._tryPreloadAttach();Ext.lib.Ajax={request:function(K,I,E,J,F){if(F){var G=F.headers;if(G){for(var H in G){if(G.hasOwnProperty(H)){this.initHeader(H,G[H],false)}}}if(F.xmlData){if(!G||!G["Content-Type"]){this.initHeader("Content-Type","text/xml",false)}K=(K?K:(F.method?F.method:"POST"));J=F.xmlData}else{if(F.jsonData){if(!G||!G["Content-Type"]){this.initHeader("Content-Type","application/json",false)}K=(K?K:(F.method?F.method:"POST"));J=typeof F.jsonData=="object"?Ext.encode(F.jsonData):F.jsonData}}}return this.asyncRequest(K,I,E,J)},serializeForm:function(F){if(typeof F=="string"){F=(document.getElementById(F)||document.forms[F])}var G,E,H,J,K="",M=false;for(var L=0;L=200&&G<300){F=this.createResponseObject(I,J.argument);if(J.success){if(!J.scope){J.success(F)}else{J.success.apply(J.scope,[F])}}}else{switch(G){case 12002:case 12029:case 12030:case 12031:case 12152:case 13030:F=this.createExceptionObject(I.tId,J.argument,(E?E:false));if(J.failure){if(!J.scope){J.failure(F)}else{J.failure.apply(J.scope,[F])}}break;default:F=this.createResponseObject(I,J.argument);if(J.failure){if(!J.scope){J.failure(F)}else{J.failure.apply(J.scope,[F])}}}}this.releaseObject(I);F=null},createResponseObject:function(E,K){var H={};var M={};try{var G=E.conn.getAllResponseHeaders();var J=G.split("\n");for(var I=0;I=this.left&&E.right<=this.right&&E.top>=this.top&&E.bottom<=this.bottom)},getArea:function(){return((this.bottom-this.top)*(this.right-this.left))},intersect:function(I){var G=Math.max(this.top,I.top);var H=Math.min(this.right,I.right);var E=Math.min(this.bottom,I.bottom);var F=Math.max(this.left,I.left);if(E>=G&&H>=F){return new Ext.lib.Region(G,H,E,F)}else{return null}},union:function(I){var G=Math.min(this.top,I.top);var H=Math.max(this.right,I.right);var E=Math.max(this.bottom,I.bottom);var F=Math.min(this.left,I.left);return new Ext.lib.Region(G,H,E,F)},constrainTo:function(E){this.top=this.top.constrain(E.top,E.bottom);this.bottom=this.bottom.constrain(E.top,E.bottom);this.left=this.left.constrain(E.left,E.right);this.right=this.right.constrain(E.left,E.right);return this},adjust:function(G,F,E,H){this.top+=G;this.left+=F;this.right+=H;this.bottom+=E;return this}};Ext.lib.Region.getRegion=function(H){var J=Ext.lib.Dom.getXY(H);var G=J[1];var I=J[0]+H.offsetWidth;var E=J[1]+H.offsetHeight;var F=J[0];return new Ext.lib.Region(G,I,E,F)};Ext.lib.Point=function(E,F){if(Ext.isArray(E)){F=E[1];E=E[0]}this.x=this.right=this.left=this[0]=E;this.y=this.top=this.bottom=this[1]=F};Ext.lib.Point.prototype=new Ext.lib.Region();Ext.lib.Anim={scroll:function(H,F,I,J,E,G){return this.run(H,F,I,J,E,G,Ext.lib.Scroll)},motion:function(H,F,I,J,E,G){return this.run(H,F,I,J,E,G,Ext.lib.Motion)},color:function(H,F,I,J,E,G){return this.run(H,F,I,J,E,G,Ext.lib.ColorAnim)},run:function(I,F,K,L,E,H,G){G=G||Ext.lib.AnimBase;if(typeof L=="string"){L=Ext.lib.Easing[L]}var J=new G(I,F,K,L);J.animateX(function(){Ext.callback(E,H)});return J}};function C(E){if(!B){B=new Ext.Element.Flyweight()}B.dom=E;return B}if(Ext.isIE){function A(){var E=Function.prototype;delete E.createSequence;delete E.defer;delete E.createDelegate;delete E.createCallback;delete E.createInterceptor;window.detachEvent("onunload",A)}window.attachEvent("onunload",A)}Ext.lib.AnimBase=function(F,E,G,H){if(F){this.init(F,E,G,H)}};Ext.lib.AnimBase.prototype={toString:function(){var E=this.getEl();var F=E.id||E.tagName;return("Anim "+F)},patterns:{noNegatives:/width|height|opacity|padding/i,offsetAttribute:/^((width|height)|(top|left))$/,defaultUnit:/width|height|top$|bottom$|left$|right$/i,offsetUnit:/\d+(em|%|en|ex|pt|in|cm|mm|pc)$/i},doMethod:function(E,G,F){return this.method(this.currentFrame,G,F-G,this.totalFrames)},setAttribute:function(E,G,F){if(this.patterns.noNegatives.test(E)){G=(G>0)?G:0}Ext.fly(this.getEl(),"_anim").setStyle(E,G+F)},getAttribute:function(E){var G=this.getEl();var I=C(G).getStyle(E);if(I!=="auto"&&!this.patterns.offsetUnit.test(I)){return parseFloat(I)}var F=this.patterns.offsetAttribute.exec(E)||[];var J=!!(F[3]);var H=!!(F[2]);if(H||(C(G).getStyle("position")=="absolute"&&J)){I=G["offset"+F[0].charAt(0).toUpperCase()+F[0].substr(1)]}else{I=0}return I},getDefaultUnit:function(E){if(this.patterns.defaultUnit.test(E)){return"px"}return""},animateX:function(G,E){var F=function(){this.onComplete.removeListener(F);if(typeof G=="function"){G.call(E||this,this)}};this.onComplete.addListener(F,this);this.animate()},setRuntimeAttribute:function(F){var K;var G;var H=this.attributes;this.runtimeAttributes[F]={};var J=function(L){return(typeof L!=="undefined")};if(!J(H[F]["to"])&&!J(H[F]["by"])){return false}K=(J(H[F]["from"]))?H[F]["from"]:this.getAttribute(F);if(J(H[F]["to"])){G=H[F]["to"]}else{if(J(H[F]["by"])){if(K.constructor==Array){G=[];for(var I=0,E=K.length;I0&&isFinite(O)){if(K.currentFrame+O>=N){O=N-(M+1)}K.currentFrame+=O}}};Ext.lib.Bezier=new function(){this.getPosition=function(I,H){var J=I.length;var G=[];for(var F=0;F0&&!Ext.isArray(O[0])){O=[O]}else{var N=[];for(P=0,R=O.length;P0){this.runtimeAttributes[S]=this.runtimeAttributes[S].concat(O)}this.runtimeAttributes[S][this.runtimeAttributes[S].length]=L}else{I.setRuntimeAttribute.call(this,S)}};var E=function(J,L){var K=Ext.lib.Dom.getXY(this.getEl());J=[J[0]-K[0]+L[0],J[1]-K[1]+L[1]];return J};var G=function(J){return(typeof J!=="undefined")}})();(function(){Ext.lib.Scroll=function(I,H,J,K){if(I){Ext.lib.Scroll.superclass.constructor.call(this,I,H,J,K)}};Ext.extend(Ext.lib.Scroll,Ext.lib.ColorAnim);var F=Ext.lib;var G=F.Scroll.superclass;var E=F.Scroll.prototype;E.toString=function(){var H=this.getEl();var I=H.id||H.tagName;return("Scroll "+I)};E.doMethod=function(H,K,I){var J=null;if(H=="scroll"){J=[this.method(this.currentFrame,K[0],I[0]-K[0],this.totalFrames),this.method(this.currentFrame,K[1],I[1]-K[1],this.totalFrames)]}else{J=G.doMethod.call(this,H,K,I)}return J};E.getAttribute=function(H){var J=null;var I=this.getEl();if(H=="scroll"){J=[I.scrollLeft,I.scrollTop]}else{J=G.getAttribute.call(this,H)}return J};E.setAttribute=function(H,K,J){var I=this.getEl();if(H=="scroll"){I.scrollLeft=K[0];I.scrollTop=K[1]}else{G.setAttribute.call(this,H,K,J)}}})()})();
diff --git a/js/ext/adapter/jquery/ext-jquery-adapter.js b/js/ext/adapter/jquery/ext-jquery-adapter.js
deleted file mode 100644
index 40e3333..0000000
--- a/js/ext/adapter/jquery/ext-jquery-adapter.js
+++ /dev/null
@@ -1,10 +0,0 @@
-/*
- * Ext JS Library 2.2
- * Copyright(c) 2006-2008, Ext JS, LLC.
- * licensing@extjs.com
- *
- * http://extjs.com/license
- */
-
-Ext={version:"2.2"};window["undefined"]=window["undefined"];Ext.apply=function(C,D,B){if(B){Ext.apply(C,B)}if(C&&D&&typeof D=="object"){for(var A in D){C[A]=D[A]}}return C};(function(){var idSeed=0;var ua=navigator.userAgent.toLowerCase();var isStrict=document.compatMode=="CSS1Compat",isOpera=ua.indexOf("opera")>-1,isSafari=(/webkit|khtml/).test(ua),isSafari3=isSafari&&ua.indexOf("webkit/5")!=-1,isIE=!isOpera&&ua.indexOf("msie")>-1,isIE7=!isOpera&&ua.indexOf("msie 7")>-1,isGecko=!isSafari&&ua.indexOf("gecko")>-1,isGecko3=!isSafari&&ua.indexOf("rv:1.9")>-1,isBorderBox=isIE&&!isStrict,isWindows=(ua.indexOf("windows")!=-1||ua.indexOf("win32")!=-1),isMac=(ua.indexOf("macintosh")!=-1||ua.indexOf("mac os x")!=-1),isAir=(ua.indexOf("adobeair")!=-1),isLinux=(ua.indexOf("linux")!=-1),isSecure=window.location.href.toLowerCase().indexOf("https")===0;if(isIE&&!isIE7){try{document.execCommand("BackgroundImageCache",false,true)}catch(e){}}Ext.apply(Ext,{isStrict:isStrict,isSecure:isSecure,isReady:false,enableGarbageCollector:true,enableListenerCollection:false,SSL_SECURE_URL:"javascript:false",BLANK_IMAGE_URL:"http:/"+"/extjs.com/s.gif",emptyFn:function(){},applyIf:function(o,c){if(o&&c){for(var p in c){if(typeof o[p]=="undefined"){o[p]=c[p]}}}return o},addBehaviors:function(o){if(!Ext.isReady){Ext.onReady(function(){Ext.addBehaviors(o)});return }var cache={};for(var b in o){var parts=b.split("@");if(parts[1]){var s=parts[0];if(!cache[s]){cache[s]=Ext.select(s)}cache[s].on(parts[1],o[b])}}cache=null},id:function(el,prefix){prefix=prefix||"ext-gen";el=Ext.getDom(el);var id=prefix+(++idSeed);return el?(el.id?el.id:(el.id=id)):id},extend:function(){var io=function(o){for(var m in o){this[m]=o[m]}};var oc=Object.prototype.constructor;return function(sb,sp,overrides){if(typeof sp=="object"){overrides=sp;sp=sb;sb=overrides.constructor!=oc?overrides.constructor:function(){sp.apply(this,arguments)}}var F=function(){},sbp,spp=sp.prototype;F.prototype=spp;sbp=sb.prototype=new F();sbp.constructor=sb;sb.superclass=spp;if(spp.constructor==oc){spp.constructor=sp}sb.override=function(o){Ext.override(sb,o)};sbp.override=io;Ext.override(sb,overrides);sb.extend=function(o){Ext.extend(sb,o)};return sb}}(),override:function(origclass,overrides){if(overrides){var p=origclass.prototype;for(var method in overrides){p[method]=overrides[method]}}},namespace:function(){var a=arguments,o=null,i,j,d,rt;for(i=0;i10000){clearInterval(G)}var J=document.getElementById(I);if(J){clearInterval(G);E.call(D||window,J)}};var G=setInterval(F,50)},resolveTextNode:function(D){if(D&&3==D.nodeType){return D.parentNode}else{return D}},getRelatedTarget:function(E){E=E.browserEvent||E;var D=E.relatedTarget;if(!D){if(E.type=="mouseout"){D=E.toElement}else{if(E.type=="mouseover"){D=E.fromElement}}}return this.resolveTextNode(D)}};Ext.lib.Ajax=function(){var D=function(E){return function(G,F){if((F=="error"||F=="timeout")&&E.failure){E.failure.call(E.scope||window,{responseText:G.responseText,responseXML:G.responseXML,argument:E.argument})}else{if(E.success){E.success.call(E.scope||window,{responseText:G.responseText,responseXML:G.responseXML,argument:E.argument})}}}};return{request:function(K,H,E,I,F){var J={type:K,url:H,data:I,timeout:E.timeout,complete:D(E)};if(F){var G=F.headers;if(F.xmlData){J.data=F.xmlData;J.processData=false;J.type=(K?K:(F.method?F.method:"POST"));if(!G||!G["Content-Type"]){J.contentType="text/xml"}}else{if(F.jsonData){J.data=typeof F.jsonData=="object"?Ext.encode(F.jsonData):F.jsonData;J.processData=false;J.type=(K?K:(F.method?F.method:"POST"));if(!G||!G["Content-Type"]){J.contentType="application/json"}}}if(G){J.beforeSend=function(M){for(var L in G){if(G.hasOwnProperty(L)){M.setRequestHeader(L,G[L])}}}}}jQuery.ajax(J)},formRequest:function(I,H,F,J,E,G){jQuery.ajax({type:Ext.getDom(I).method||"POST",url:H,data:jQuery(I).serialize()+(J?"&"+J:""),timeout:F.timeout,complete:D(F)})},isCallInProgress:function(E){return false},abort:function(E){return false},serializeForm:function(E){return jQuery(E.dom||E).serialize()}}}();Ext.lib.Anim=function(){var D=function(E,F){var G=true;return{stop:function(H){},isAnimated:function(){return G},proxyCallback:function(){G=false;Ext.callback(E,F)}}};return{scroll:function(H,F,J,K,E,G){var I=D(E,G);H=Ext.getDom(H);if(typeof F.scroll.to[0]=="number"){H.scrollLeft=F.scroll.to[0]}if(typeof F.scroll.to[1]=="number"){H.scrollTop=F.scroll.to[1]}I.proxyCallback();return I},motion:function(H,F,I,J,E,G){return this.run(H,F,I,J,E,G)},color:function(H,F,J,K,E,G){var I=D(E,G);I.proxyCallback();return I},run:function(F,N,I,M,G,P,O){var J=D(G,P),K=Ext.fly(F,"_animrun");var E={};for(var H in N){if(N[H].from){if(H!="points"){K.setStyle(H,N[H].from)}}switch(H){case"points":var L,R;K.position();if(L=N.points.by){var Q=K.getXY();R=K.translatePoints([Q[0]+L[0],Q[1]+L[1]])}else{R=K.translatePoints(N.points.to)}E.left=R.left;E.top=R.top;if(!parseInt(K.getStyle("left"),10)){K.setLeft(0)}if(!parseInt(K.getStyle("top"),10)){K.setTop(0)}if(N.points.from){K.setXY(N.points.from)}break;case"width":E.width=N.width.to;break;case"height":E.height=N.height.to;break;case"opacity":E.opacity=N.opacity.to;break;case"left":E.left=N.left.to;break;case"top":E.top=N.top.to;break;default:E[H]=N[H].to;break}}jQuery(F).animate(E,I*1000,undefined,J.proxyCallback);return J}}}();Ext.lib.Region=function(F,G,D,E){this.top=F;this[1]=F;this.right=G;this.bottom=D;this.left=E;this[0]=E};Ext.lib.Region.prototype={contains:function(D){return(D.left>=this.left&&D.right<=this.right&&D.top>=this.top&&D.bottom<=this.bottom)},getArea:function(){return((this.bottom-this.top)*(this.right-this.left))},intersect:function(H){var F=Math.max(this.top,H.top);var G=Math.min(this.right,H.right);var D=Math.min(this.bottom,H.bottom);var E=Math.max(this.left,H.left);if(D>=F&&G>=E){return new Ext.lib.Region(F,G,D,E)}else{return null}},union:function(H){var F=Math.min(this.top,H.top);var G=Math.max(this.right,H.right);var D=Math.max(this.bottom,H.bottom);var E=Math.min(this.left,H.left);return new Ext.lib.Region(F,G,D,E)},constrainTo:function(D){this.top=this.top.constrain(D.top,D.bottom);this.bottom=this.bottom.constrain(D.top,D.bottom);this.left=this.left.constrain(D.left,D.right);this.right=this.right.constrain(D.left,D.right);return this},adjust:function(F,E,D,G){this.top+=F;this.left+=E;this.right+=G;this.bottom+=D;return this}};Ext.lib.Region.getRegion=function(G){var I=Ext.lib.Dom.getXY(G);var F=I[1];var H=I[0]+G.offsetWidth;var D=I[1]+G.offsetHeight;var E=I[0];return new Ext.lib.Region(F,H,D,E)};Ext.lib.Point=function(D,E){if(Ext.isArray(D)){E=D[1];D=D[0]}this.x=this.right=this.left=this[0]=D;this.y=this.top=this.bottom=this[1]=E};Ext.lib.Point.prototype=new Ext.lib.Region();if(Ext.isIE){function A(){var D=Function.prototype;delete D.createSequence;delete D.defer;delete D.createDelegate;delete D.createCallback;delete D.createInterceptor;window.detachEvent("onunload",A)}window.attachEvent("onunload",A)}})();
diff --git a/js/ext/adapter/jquery/jquery.js b/js/ext/adapter/jquery/jquery.js
deleted file mode 100644
index 2e43a82..0000000
--- a/js/ext/adapter/jquery/jquery.js
+++ /dev/null
@@ -1,3408 +0,0 @@
-(function(){
-/*
- * jQuery 1.2.3 - New Wave Javascript
- *
- * Copyright (c) 2008 John Resig (jquery.com)
- * Dual licensed under the MIT (MIT-LICENSE.txt)
- * and GPL (GPL-LICENSE.txt) licenses.
- *
- * $Date: 2008-02-06 00:21:25 -0500 (Wed, 06 Feb 2008) $
- * $Rev: 4663 $
- */
-
-// Map over jQuery in case of overwrite
-if ( window.jQuery )
- var _jQuery = window.jQuery;
-
-var jQuery = window.jQuery = function( selector, context ) {
- // The jQuery object is actually just the init constructor 'enhanced'
- return new jQuery.prototype.init( selector, context );
-};
-
-// Map over the $ in case of overwrite
-if ( window.$ )
- var _$ = window.$;
-
-// Map the jQuery namespace to the '$' one
-window.$ = jQuery;
-
-// A simple way to check for HTML strings or ID strings
-// (both of which we optimize for)
-var quickExpr = /^[^<]*(<(.|\s)+>)[^>]*$|^#(\w+)$/;
-
-// Is it a simple selector
-var isSimple = /^.[^:#\[\.]*$/;
-
-jQuery.fn = jQuery.prototype = {
- init: function( selector, context ) {
- // Make sure that a selection was provided
- selector = selector || document;
-
- // Handle $(DOMElement)
- if ( selector.nodeType ) {
- this[0] = selector;
- this.length = 1;
- return this;
-
- // Handle HTML strings
- } else if ( typeof selector == "string" ) {
- // Are we dealing with HTML string or an ID?
- var match = quickExpr.exec( selector );
-
- // Verify a match, and that no context was specified for #id
- if ( match && (match[1] || !context) ) {
-
- // HANDLE: $(html) -> $(array)
- if ( match[1] )
- selector = jQuery.clean( [ match[1] ], context );
-
- // HANDLE: $("#id")
- else {
- var elem = document.getElementById( match[3] );
-
- // Make sure an element was located
- if ( elem )
- // Handle the case where IE and Opera return items
- // by name instead of ID
- if ( elem.id != match[3] )
- return jQuery().find( selector );
-
- // Otherwise, we inject the element directly into the jQuery object
- else {
- this[0] = elem;
- this.length = 1;
- return this;
- }
-
- else
- selector = [];
- }
-
- // HANDLE: $(expr, [context])
- // (which is just equivalent to: $(content).find(expr)
- } else
- return new jQuery( context ).find( selector );
-
- // HANDLE: $(function)
- // Shortcut for document ready
- } else if ( jQuery.isFunction( selector ) )
- return new jQuery( document )[ jQuery.fn.ready ? "ready" : "load" ]( selector );
-
- return this.setArray(
- // HANDLE: $(array)
- selector.constructor == Array && selector ||
-
- // HANDLE: $(arraylike)
- // Watch for when an array-like object, contains DOM nodes, is passed in as the selector
- (selector.jquery || selector.length && selector != window && !selector.nodeType && selector[0] != undefined && selector[0].nodeType) && jQuery.makeArray( selector ) ||
-
- // HANDLE: $(*)
- [ selector ] );
- },
-
- // The current version of jQuery being used
- jquery: "1.2.3",
-
- // The number of elements contained in the matched element set
- size: function() {
- return this.length;
- },
-
- // The number of elements contained in the matched element set
- length: 0,
-
- // Get the Nth element in the matched element set OR
- // Get the whole matched element set as a clean array
- get: function( num ) {
- return num == undefined ?
-
- // Return a 'clean' array
- jQuery.makeArray( this ) :
-
- // Return just the object
- this[ num ];
- },
-
- // Take an array of elements and push it onto the stack
- // (returning the new matched element set)
- pushStack: function( elems ) {
- // Build a new jQuery matched element set
- var ret = jQuery( elems );
-
- // Add the old object onto the stack (as a reference)
- ret.prevObject = this;
-
- // Return the newly-formed element set
- return ret;
- },
-
- // Force the current matched set of elements to become
- // the specified array of elements (destroying the stack in the process)
- // You should use pushStack() in order to do this, but maintain the stack
- setArray: function( elems ) {
- // Resetting the length to 0, then using the native Array push
- // is a super-fast way to populate an object with array-like properties
- this.length = 0;
- Array.prototype.push.apply( this, elems );
-
- return this;
- },
-
- // Execute a callback for every element in the matched set.
- // (You can seed the arguments with an array of args, but this is
- // only used internally.)
- each: function( callback, args ) {
- return jQuery.each( this, callback, args );
- },
-
- // Determine the position of an element within
- // the matched set of elements
- index: function( elem ) {
- var ret = -1;
-
- // Locate the position of the desired element
- this.each(function(i){
- if ( this == elem )
- ret = i;
- });
-
- return ret;
- },
-
- attr: function( name, value, type ) {
- var options = name;
-
- // Look for the case where we're accessing a style value
- if ( name.constructor == String )
- if ( value == undefined )
- return this.length && jQuery[ type || "attr" ]( this[0], name ) || undefined;
-
- else {
- options = {};
- options[ name ] = value;
- }
-
- // Check to see if we're setting style values
- return this.each(function(i){
- // Set all the styles
- for ( name in options )
- jQuery.attr(
- type ?
- this.style :
- this,
- name, jQuery.prop( this, options[ name ], type, i, name )
- );
- });
- },
-
- css: function( key, value ) {
- // ignore negative width and height values
- if ( (key == 'width' || key == 'height') && parseFloat(value) < 0 )
- value = undefined;
- return this.attr( key, value, "curCSS" );
- },
-
- text: function( text ) {
- if ( typeof text != "object" && text != null )
- return this.empty().append( (this[0] && this[0].ownerDocument || document).createTextNode( text ) );
-
- var ret = "";
-
- jQuery.each( text || this, function(){
- jQuery.each( this.childNodes, function(){
- if ( this.nodeType != 8 )
- ret += this.nodeType != 1 ?
- this.nodeValue :
- jQuery.fn.text( [ this ] );
- });
- });
-
- return ret;
- },
-
- wrapAll: function( html ) {
- if ( this[0] )
- // The elements to wrap the target around
- jQuery( html, this[0].ownerDocument )
- .clone()
- .insertBefore( this[0] )
- .map(function(){
- var elem = this;
-
- while ( elem.firstChild )
- elem = elem.firstChild;
-
- return elem;
- })
- .append(this);
-
- return this;
- },
-
- wrapInner: function( html ) {
- return this.each(function(){
- jQuery( this ).contents().wrapAll( html );
- });
- },
-
- wrap: function( html ) {
- return this.each(function(){
- jQuery( this ).wrapAll( html );
- });
- },
-
- append: function() {
- return this.domManip(arguments, true, false, function(elem){
- if (this.nodeType == 1)
- this.appendChild( elem );
- });
- },
-
- prepend: function() {
- return this.domManip(arguments, true, true, function(elem){
- if (this.nodeType == 1)
- this.insertBefore( elem, this.firstChild );
- });
- },
-
- before: function() {
- return this.domManip(arguments, false, false, function(elem){
- this.parentNode.insertBefore( elem, this );
- });
- },
-
- after: function() {
- return this.domManip(arguments, false, true, function(elem){
- this.parentNode.insertBefore( elem, this.nextSibling );
- });
- },
-
- end: function() {
- return this.prevObject || jQuery( [] );
- },
-
- find: function( selector ) {
- var elems = jQuery.map(this, function(elem){
- return jQuery.find( selector, elem );
- });
-
- return this.pushStack( /[^+>] [^+>]/.test( selector ) || selector.indexOf("..") > -1 ?
- jQuery.unique( elems ) :
- elems );
- },
-
- clone: function( events ) {
- // Do the clone
- var ret = this.map(function(){
- if ( jQuery.browser.msie && !jQuery.isXMLDoc(this) ) {
- // IE copies events bound via attachEvent when
- // using cloneNode. Calling detachEvent on the
- // clone will also remove the events from the orignal
- // In order to get around this, we use innerHTML.
- // Unfortunately, this means some modifications to
- // attributes in IE that are actually only stored
- // as properties will not be copied (such as the
- // the name attribute on an input).
- var clone = this.cloneNode(true),
- container = document.createElement("div");
- container.appendChild(clone);
- return jQuery.clean([container.innerHTML])[0];
- } else
- return this.cloneNode(true);
- });
-
- // Need to set the expando to null on the cloned set if it exists
- // removeData doesn't work here, IE removes it from the original as well
- // this is primarily for IE but the data expando shouldn't be copied over in any browser
- var clone = ret.find("*").andSelf().each(function(){
- if ( this[ expando ] != undefined )
- this[ expando ] = null;
- });
-
- // Copy the events from the original to the clone
- if ( events === true )
- this.find("*").andSelf().each(function(i){
- if (this.nodeType == 3)
- return;
- var events = jQuery.data( this, "events" );
-
- for ( var type in events )
- for ( var handler in events[ type ] )
- jQuery.event.add( clone[ i ], type, events[ type ][ handler ], events[ type ][ handler ].data );
- });
-
- // Return the cloned set
- return ret;
- },
-
- filter: function( selector ) {
- return this.pushStack(
- jQuery.isFunction( selector ) &&
- jQuery.grep(this, function(elem, i){
- return selector.call( elem, i );
- }) ||
-
- jQuery.multiFilter( selector, this ) );
- },
-
- not: function( selector ) {
- if ( selector.constructor == String )
- // test special case where just one selector is passed in
- if ( isSimple.test( selector ) )
- return this.pushStack( jQuery.multiFilter( selector, this, true ) );
- else
- selector = jQuery.multiFilter( selector, this );
-
- var isArrayLike = selector.length && selector[selector.length - 1] !== undefined && !selector.nodeType;
- return this.filter(function() {
- return isArrayLike ? jQuery.inArray( this, selector ) < 0 : this != selector;
- });
- },
-
- add: function( selector ) {
- return !selector ? this : this.pushStack( jQuery.merge(
- this.get(),
- selector.constructor == String ?
- jQuery( selector ).get() :
- selector.length != undefined && (!selector.nodeName || jQuery.nodeName(selector, "form")) ?
- selector : [selector] ) );
- },
-
- is: function( selector ) {
- return selector ?
- jQuery.multiFilter( selector, this ).length > 0 :
- false;
- },
-
- hasClass: function( selector ) {
- return this.is( "." + selector );
- },
-
- val: function( value ) {
- if ( value == undefined ) {
-
- if ( this.length ) {
- var elem = this[0];
-
- // We need to handle select boxes special
- if ( jQuery.nodeName( elem, "select" ) ) {
- var index = elem.selectedIndex,
- values = [],
- options = elem.options,
- one = elem.type == "select-one";
-
- // Nothing was selected
- if ( index < 0 )
- return null;
-
- // Loop through all the selected options
- for ( var i = one ? index : 0, max = one ? index + 1 : options.length; i < max; i++ ) {
- var option = options[ i ];
-
- if ( option.selected ) {
- // Get the specifc value for the option
- value = jQuery.browser.msie && !option.attributes.value.specified ? option.text : option.value;
-
- // We don't need an array for one selects
- if ( one )
- return value;
-
- // Multi-Selects return an array
- values.push( value );
- }
- }
-
- return values;
-
- // Everything else, we just grab the value
- } else
- return (this[0].value || "").replace(/\r/g, "");
-
- }
-
- return undefined;
- }
-
- return this.each(function(){
- if ( this.nodeType != 1 )
- return;
-
- if ( value.constructor == Array && /radio|checkbox/.test( this.type ) )
- this.checked = (jQuery.inArray(this.value, value) >= 0 ||
- jQuery.inArray(this.name, value) >= 0);
-
- else if ( jQuery.nodeName( this, "select" ) ) {
- var values = value.constructor == Array ?
- value :
- [ value ];
-
- jQuery( "option", this ).each(function(){
- this.selected = (jQuery.inArray( this.value, values ) >= 0 ||
- jQuery.inArray( this.text, values ) >= 0);
- });
-
- if ( !values.length )
- this.selectedIndex = -1;
-
- } else
- this.value = value;
- });
- },
-
- html: function( value ) {
- return value == undefined ?
- (this.length ?
- this[0].innerHTML :
- null) :
- this.empty().append( value );
- },
-
- replaceWith: function( value ) {
- return this.after( value ).remove();
- },
-
- eq: function( i ) {
- return this.slice( i, i + 1 );
- },
-
- slice: function() {
- return this.pushStack( Array.prototype.slice.apply( this, arguments ) );
- },
-
- map: function( callback ) {
- return this.pushStack( jQuery.map(this, function(elem, i){
- return callback.call( elem, i, elem );
- }));
- },
-
- andSelf: function() {
- return this.add( this.prevObject );
- },
-
- data: function( key, value ){
- var parts = key.split(".");
- parts[1] = parts[1] ? "." + parts[1] : "";
-
- if ( value == null ) {
- var data = this.triggerHandler("getData" + parts[1] + "!", [parts[0]]);
-
- if ( data == undefined && this.length )
- data = jQuery.data( this[0], key );
-
- return data == null && parts[1] ?
- this.data( parts[0] ) :
- data;
- } else
- return this.trigger("setData" + parts[1] + "!", [parts[0], value]).each(function(){
- jQuery.data( this, key, value );
- });
- },
-
- removeData: function( key ){
- return this.each(function(){
- jQuery.removeData( this, key );
- });
- },
-
- domManip: function( args, table, reverse, callback ) {
- var clone = this.length > 1, elems;
-
- return this.each(function(){
- if ( !elems ) {
- elems = jQuery.clean( args, this.ownerDocument );
-
- if ( reverse )
- elems.reverse();
- }
-
- var obj = this;
-
- if ( table && jQuery.nodeName( this, "table" ) && jQuery.nodeName( elems[0], "tr" ) )
- obj = this.getElementsByTagName("tbody")[0] || this.appendChild( this.ownerDocument.createElement("tbody") );
-
- var scripts = jQuery( [] );
-
- jQuery.each(elems, function(){
- var elem = clone ?
- jQuery( this ).clone( true )[0] :
- this;
-
- // execute all scripts after the elements have been injected
- if ( jQuery.nodeName( elem, "script" ) ) {
- scripts = scripts.add( elem );
- } else {
- // Remove any inner scripts for later evaluation
- if ( elem.nodeType == 1 )
- scripts = scripts.add( jQuery( "script", elem ).remove() );
-
- // Inject the elements into the document
- callback.call( obj, elem );
- }
- });
-
- scripts.each( evalScript );
- });
- }
-};
-
-// Give the init function the jQuery prototype for later instantiation
-jQuery.prototype.init.prototype = jQuery.prototype;
-
-function evalScript( i, elem ) {
- if ( elem.src )
- jQuery.ajax({
- url: elem.src,
- async: false,
- dataType: "script"
- });
-
- else
- jQuery.globalEval( elem.text || elem.textContent || elem.innerHTML || "" );
-
- if ( elem.parentNode )
- elem.parentNode.removeChild( elem );
-}
-
-jQuery.extend = jQuery.fn.extend = function() {
- // copy reference to target object
- var target = arguments[0] || {}, i = 1, length = arguments.length, deep = false, options;
-
- // Handle a deep copy situation
- if ( target.constructor == Boolean ) {
- deep = target;
- target = arguments[1] || {};
- // skip the boolean and the target
- i = 2;
- }
-
- // Handle case when target is a string or something (possible in deep copy)
- if ( typeof target != "object" && typeof target != "function" )
- target = {};
-
- // extend jQuery itself if only one argument is passed
- if ( length == 1 ) {
- target = this;
- i = 0;
- }
-
- for ( ; i < length; i++ )
- // Only deal with non-null/undefined values
- if ( (options = arguments[ i ]) != null )
- // Extend the base object
- for ( var name in options ) {
- // Prevent never-ending loop
- if ( target === options[ name ] )
- continue;
-
- // Recurse if we're merging object values
- if ( deep && options[ name ] && typeof options[ name ] == "object" && target[ name ] && !options[ name ].nodeType )
- target[ name ] = jQuery.extend( target[ name ], options[ name ] );
-
- // Don't bring in undefined values
- else if ( options[ name ] != undefined )
- target[ name ] = options[ name ];
-
- }
-
- // Return the modified object
- return target;
-};
-
-var expando = "jQuery" + (new Date()).getTime(), uuid = 0, windowData = {};
-
-// exclude the following css properties to add px
-var exclude = /z-?index|font-?weight|opacity|zoom|line-?height/i;
-
-jQuery.extend({
- noConflict: function( deep ) {
- window.$ = _$;
-
- if ( deep )
- window.jQuery = _jQuery;
-
- return jQuery;
- },
-
- // See test/unit/core.js for details concerning this function.
- isFunction: function( fn ) {
- return !!fn && typeof fn != "string" && !fn.nodeName &&
- fn.constructor != Array && /function/i.test( fn + "" );
- },
-
- // check if an element is in a (or is an) XML document
- isXMLDoc: function( elem ) {
- return elem.documentElement && !elem.body ||
- elem.tagName && elem.ownerDocument && !elem.ownerDocument.body;
- },
-
- // Evalulates a script in a global context
- globalEval: function( data ) {
- data = jQuery.trim( data );
-
- if ( data ) {
- // Inspired by code by Andrea Giammarchi
- // http://webreflection.blogspot.com/2007/08/global-scope-evaluation-and-dom.html
- var head = document.getElementsByTagName("head")[0] || document.documentElement,
- script = document.createElement("script");
-
- script.type = "text/javascript";
- if ( jQuery.browser.msie )
- script.text = data;
- else
- script.appendChild( document.createTextNode( data ) );
-
- head.appendChild( script );
- head.removeChild( script );
- }
- },
-
- nodeName: function( elem, name ) {
- return elem.nodeName && elem.nodeName.toUpperCase() == name.toUpperCase();
- },
-
- cache: {},
-
- data: function( elem, name, data ) {
- elem = elem == window ?
- windowData :
- elem;
-
- var id = elem[ expando ];
-
- // Compute a unique ID for the element
- if ( !id )
- id = elem[ expando ] = ++uuid;
-
- // Only generate the data cache if we're
- // trying to access or manipulate it
- if ( name && !jQuery.cache[ id ] )
- jQuery.cache[ id ] = {};
-
- // Prevent overriding the named cache with undefined values
- if ( data != undefined )
- jQuery.cache[ id ][ name ] = data;
-
- // Return the named cache data, or the ID for the element
- return name ?
- jQuery.cache[ id ][ name ] :
- id;
- },
-
- removeData: function( elem, name ) {
- elem = elem == window ?
- windowData :
- elem;
-
- var id = elem[ expando ];
-
- // If we want to remove a specific section of the element's data
- if ( name ) {
- if ( jQuery.cache[ id ] ) {
- // Remove the section of cache data
- delete jQuery.cache[ id ][ name ];
-
- // If we've removed all the data, remove the element's cache
- name = "";
-
- for ( name in jQuery.cache[ id ] )
- break;
-
- if ( !name )
- jQuery.removeData( elem );
- }
-
- // Otherwise, we want to remove all of the element's data
- } else {
- // Clean up the element expando
- try {
- delete elem[ expando ];
- } catch(e){
- // IE has trouble directly removing the expando
- // but it's ok with using removeAttribute
- if ( elem.removeAttribute )
- elem.removeAttribute( expando );
- }
-
- // Completely remove the data cache
- delete jQuery.cache[ id ];
- }
- },
-
- // args is for internal usage only
- each: function( object, callback, args ) {
- if ( args ) {
- if ( object.length == undefined ) {
- for ( var name in object )
- if ( callback.apply( object[ name ], args ) === false )
- break;
- } else
- for ( var i = 0, length = object.length; i < length; i++ )
- if ( callback.apply( object[ i ], args ) === false )
- break;
-
- // A special, fast, case for the most common use of each
- } else {
- if ( object.length == undefined ) {
- for ( var name in object )
- if ( callback.call( object[ name ], name, object[ name ] ) === false )
- break;
- } else
- for ( var i = 0, length = object.length, value = object[0];
- i < length && callback.call( value, i, value ) !== false; value = object[++i] ){}
- }
-
- return object;
- },
-
- prop: function( elem, value, type, i, name ) {
- // Handle executable functions
- if ( jQuery.isFunction( value ) )
- value = value.call( elem, i );
-
- // Handle passing in a number to a CSS property
- return value && value.constructor == Number && type == "curCSS" && !exclude.test( name ) ?
- value + "px" :
- value;
- },
-
- className: {
- // internal only, use addClass("class")
- add: function( elem, classNames ) {
- jQuery.each((classNames || "").split(/\s+/), function(i, className){
- if ( elem.nodeType == 1 && !jQuery.className.has( elem.className, className ) )
- elem.className += (elem.className ? " " : "") + className;
- });
- },
-
- // internal only, use removeClass("class")
- remove: function( elem, classNames ) {
- if (elem.nodeType == 1)
- elem.className = classNames != undefined ?
- jQuery.grep(elem.className.split(/\s+/), function(className){
- return !jQuery.className.has( classNames, className );
- }).join(" ") :
- "";
- },
-
- // internal only, use is(".class")
- has: function( elem, className ) {
- return jQuery.inArray( className, (elem.className || elem).toString().split(/\s+/) ) > -1;
- }
- },
-
- // A method for quickly swapping in/out CSS properties to get correct calculations
- swap: function( elem, options, callback ) {
- var old = {};
- // Remember the old values, and insert the new ones
- for ( var name in options ) {
- old[ name ] = elem.style[ name ];
- elem.style[ name ] = options[ name ];
- }
-
- callback.call( elem );
-
- // Revert the old values
- for ( var name in options )
- elem.style[ name ] = old[ name ];
- },
-
- css: function( elem, name, force ) {
- if ( name == "width" || name == "height" ) {
- var val, props = { position: "absolute", visibility: "hidden", display:"block" }, which = name == "width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ];
-
- function getWH() {
- val = name == "width" ? elem.offsetWidth : elem.offsetHeight;
- var padding = 0, border = 0;
- jQuery.each( which, function() {
- padding += parseFloat(jQuery.curCSS( elem, "padding" + this, true)) || 0;
- border += parseFloat(jQuery.curCSS( elem, "border" + this + "Width", true)) || 0;
- });
- val -= Math.round(padding + border);
- }
-
- if ( jQuery(elem).is(":visible") )
- getWH();
- else
- jQuery.swap( elem, props, getWH );
-
- return Math.max(0, val);
- }
-
- return jQuery.curCSS( elem, name, force );
- },
-
- curCSS: function( elem, name, force ) {
- var ret;
-
- // A helper method for determining if an element's values are broken
- function color( elem ) {
- if ( !jQuery.browser.safari )
- return false;
-
- var ret = document.defaultView.getComputedStyle( elem, null );
- return !ret || ret.getPropertyValue("color") == "";
- }
-
- // We need to handle opacity special in IE
- if ( name == "opacity" && jQuery.browser.msie ) {
- ret = jQuery.attr( elem.style, "opacity" );
-
- return ret == "" ?
- "1" :
- ret;
- }
- // Opera sometimes will give the wrong display answer, this fixes it, see #2037
- if ( jQuery.browser.opera && name == "display" ) {
- var save = elem.style.outline;
- elem.style.outline = "0 solid black";
- elem.style.outline = save;
- }
-
- // Make sure we're using the right name for getting the float value
- if ( name.match( /float/i ) )
- name = styleFloat;
-
- if ( !force && elem.style && elem.style[ name ] )
- ret = elem.style[ name ];
-
- else if ( document.defaultView && document.defaultView.getComputedStyle ) {
-
- // Only "float" is needed here
- if ( name.match( /float/i ) )
- name = "float";
-
- name = name.replace( /([A-Z])/g, "-$1" ).toLowerCase();
-
- var getComputedStyle = document.defaultView.getComputedStyle( elem, null );
-
- if ( getComputedStyle && !color( elem ) )
- ret = getComputedStyle.getPropertyValue( name );
-
- // If the element isn't reporting its values properly in Safari
- // then some display: none elements are involved
- else {
- var swap = [], stack = [];
-
- // Locate all of the parent display: none elements
- for ( var a = elem; a && color(a); a = a.parentNode )
- stack.unshift(a);
-
- // Go through and make them visible, but in reverse
- // (It would be better if we knew the exact display type that they had)
- for ( var i = 0; i < stack.length; i++ )
- if ( color( stack[ i ] ) ) {
- swap[ i ] = stack[ i ].style.display;
- stack[ i ].style.display = "block";
- }
-
- // Since we flip the display style, we have to handle that
- // one special, otherwise get the value
- ret = name == "display" && swap[ stack.length - 1 ] != null ?
- "none" :
- ( getComputedStyle && getComputedStyle.getPropertyValue( name ) ) || "";
-
- // Finally, revert the display styles back
- for ( var i = 0; i < swap.length; i++ )
- if ( swap[ i ] != null )
- stack[ i ].style.display = swap[ i ];
- }
-
- // We should always get a number back from opacity
- if ( name == "opacity" && ret == "" )
- ret = "1";
-
- } else if ( elem.currentStyle ) {
- var camelCase = name.replace(/\-(\w)/g, function(all, letter){
- return letter.toUpperCase();
- });
-
- ret = elem.currentStyle[ name ] || elem.currentStyle[ camelCase ];
-
- // From the awesome hack by Dean Edwards
- // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291
-
- // If we're not dealing with a regular pixel number
- // but a number that has a weird ending, we need to convert it to pixels
- if ( !/^\d+(px)?$/i.test( ret ) && /^\d/.test( ret ) ) {
- // Remember the original values
- var style = elem.style.left, runtimeStyle = elem.runtimeStyle.left;
-
- // Put in the new values to get a computed value out
- elem.runtimeStyle.left = elem.currentStyle.left;
- elem.style.left = ret || 0;
- ret = elem.style.pixelLeft + "px";
-
- // Revert the changed values
- elem.style.left = style;
- elem.runtimeStyle.left = runtimeStyle;
- }
- }
-
- return ret;
- },
-
- clean: function( elems, context ) {
- var ret = [];
- context = context || document;
- // !context.createElement fails in IE with an error but returns typeof 'object'
- if (typeof context.createElement == 'undefined')
- context = context.ownerDocument || context[0] && context[0].ownerDocument || document;
-
- jQuery.each(elems, function(i, elem){
- if ( !elem )
- return;
-
- if ( elem.constructor == Number )
- elem = elem.toString();
-
- // Convert html string into DOM nodes
- if ( typeof elem == "string" ) {
- // Fix "XHTML"-style tags in all browsers
- elem = elem.replace(/(<(\w+)[^>]*?)\/>/g, function(all, front, tag){
- return tag.match(/^(abbr|br|col|img|input|link|meta|param|hr|area|embed)$/i) ?
- all :
- front + ">" + tag + ">";
- });
-
- // Trim whitespace, otherwise indexOf won't work as expected
- var tags = jQuery.trim( elem ).toLowerCase(), div = context.createElement("div");
-
- var wrap =
- // option or optgroup
- !tags.indexOf("", "" ] ||
-
- !tags.indexOf("", "" ] ||
-
- tags.match(/^<(thead|tbody|tfoot|colg|cap)/) &&
- [ 1, "" ] ||
-
- !tags.indexOf("
", "" ] ||
-
- // matched above
- (!tags.indexOf(" | ", "
" ] ||
-
- !tags.indexOf("", "" ] ||
-
- // IE can't serialize and