Location: PHPKode > projects > phpWatch > src/Monitor.php
<?php
    require_once(PW2_PATH . '/src/DbObject.php');
    // The monitor is online as of the last polling.
    define('STATUS_ONLINE', 0x01);
    // The monitor is offline as of the last polling.
    define('STATUS_OFFLINE', 0x02);
    // The monitor is paused.  Poll data is discarded.
    define('STATUS_PAUSED', 0x03);
    // The monitor is in a scheduled-downtime mode.
    define('STATUS_DOWNTIME', 0x04);
    // The monitor has no polling data available.
    define('STATUS_UNPOLLED', 0x05);

    abstract class Monitor implements DbObject
    {
        protected $id;
        protected $hostname;
        protected $port;
        protected $alias;
        protected $status;
        protected $downtime_start;
        protected $downtime_end;
        protected $notification_channels;
        protected $send_notifications;
        protected $last_query;
        protected $fail_count;
        protected $fail_threshold;
        protected $config;

        public function __construct($data = null)
        {
            if(is_int($data))
            {
                $this->loadById($id);
            }
            elseif(is_array($data))
            {
                $this->loadByRow($data);
            }
            else
            {
                $this->id = null;
                $this->hostname = $hostname;
                $this->port = $port;
                $this->alias = $alias;
                $this->status = STATUS_UNPOLLED;
                $this->downtime_start = 0;
                $this->downtime_end = 0;
                $this->notification_channels = array();
                $this->send_notifications = true;
                $this->last_query = 0;
                $this->fail_count = 0;
                $this->fail_threshold = 1;
                $this->config = array();
            }
        }

        public function getId()
        {
            return $this->id;
        }

        public function getHostname()
        {
            return $this->hostname;
        }

        public function getPort()
        {
            return $this->port;
        }

        public function getAlias()
        {
            return $this->alias;
        }

        public function getStatus()
        {
            return $this->status;
        }

        public function getLastQuery()
        {
            return $this->last_query;
        }

        public function getFailThreshold()
        {
            return $this->fail_threshold;
        }

        public function getDowntimeStart()
        {
            return $this->downtime_start;
        }

        public function getDowntimeEnd()
        {
            return $this->downtime_end;
        }

        public function loadById($id)
        {
            $db_row = $GLOBALS['PW_DB']->executeSelectOne('*', 'monitors', 'WHERE id=' . intval($id));
            $this->loadByRow($db_row);
        }

        public function loadByRow($db_row)
        {
            $this->id = $db_row['id'];
            $this->hostname = $db_row['hostname'];
            $this->port = $db_row['port'];
            $this->alias = $db_row['alias'];
            $this->status = $db_row['status'];
            $this->downtime_start = $db_row['downtime_start'];
            $this->downtime_end = $db_row['downtime_end'];
            $this->notification_channels = array();
            $this->send_notifications = $db_row['send_notifications'];
            $this->last_query = $db_row['last_query'];
            $this->fail_count = $db_row['fail_count'];
            $this->fail_threshold = $db_row['fail_threshold'];
            $this->config = unserialize($db_row['config']);

            if(strlen($db_row['notification_channels']) > 0)
                foreach(explode(',', $db_row['notification_channels']) as $channel)
                    $this->notification_channels[] = Channel::fetch(intval($channel));
        }

        public function saveToDb()
        {
            $values = array(
                'type' => get_class($this),
                'hostname' => $this->hostname,
                'port' => $this->port,
                'alias' => $this->alias,
                'status' => $this->status,
                'downtime_start' => $this->downtime_start,
                'downtime_end' => $this->downtime_end,
                'notification_channels' => implode(',', $this->getChanIds()),
                'send_notifications' => $this->send_notifications,
                'last_query' => $this->last_query,
                'fail_count' => $this->fail_count,
                'fail_threshold' => $this->fail_threshold,
                'config' => serialize($this->config),
            );
            if($this->id === null)
                $this->id = $GLOBALS['PW_DB']->executeInsert($values, 'monitors');
            else
                $GLOBALS['PW_DB']->executeUpdate($values, 'monitors', 'WHERE id=' . intval($this->id));
        }

        public function addChannel($channel)
        {
            $index = array_search($channel, $this->notification_channels);
            if($index === false)
                $this->notification_channels[] = $channel;
        }

        public function deleteChannel($channel)
        {
            $index = array_search($channel, $this->notification_channels);
            if($index !== false)
                unset($this->notification_channels[$index]);
        }

        public function sendNotifications()
        {
            foreach($this->notification_channels as $channel)
            {
                $channel->doNotify($this);
            }
        }

        public function poll()
        {
            $up = $this->queryMonitor();
            $this->last_query = time();

            if($this->downtime_start != 0 && $this->downtime_start < time())
                $this->status = STATUS_DOWNTIME;

            if($this->status == STATUS_DOWNTIME && $this->downtime_end <= time())
            {
                $this->status = UNPOLLED;
                $this->downtime_start = 0;
                $this->downtime_end = 0;
            }

            switch($this->status)
            {
                case STATUS_UNPOLLED:
                case STATUS_ONLINE:
                case STATUS_OFFLINE:
                    if($this->id != 0)
                        Statistics::add('monitor' . $this->id, time(), $up ? 1 : 0);
                    if($up)
                    {
                        $this->status = STATUS_ONLINE;
                        $this->fail_count = 0;
                        $this->send_notifications = true;
                    }
                    else
                    {
                        $this->status = STATUS_OFFLINE;
                        $this->fail_count++;
                    }
                    break;
                case STATUS_PAUSED:
                    break;
            }
            if( $this->send_notifications && 
                $this->status == STATUS_OFFLINE && 
                $this->fail_count >= $this->fail_threshold)
            {
                $this->sendNotifications();
                $this->send_notifications = false;
            }
            return $up;
        }

        public function getChanIds()
        {
            $ids = array();
            foreach($this->notification_channels as $channel)
            {
                $ids[] = $channel->getId();
            }
            return $ids;
        }

        public function processAddEdit($data)
        {
            $errors = array();
            if(strlen($data['hostname']) == 0)
                $errors['hostname'] = 'Hostname cannot be blank.';
            $this->hostname = $data['hostname'];

            if(!is_numeric($data['port']))
                $errors['port'] = 'Port must be numeric.';
            $this->port = intval($data['port']);

            $this->alias = $data['alias'];

            if(!is_numeric($data['fail_threshold']) || intval($data['fail_threshold']) <= 0)
                $errors['fail_threshold'] = 'Failure threshold must be a positive integer.';
            $this->fail_threshold = intval($data['fail_threshold']);

            $this->notification_channels = array();
            if(is_array($data['notification_channels']))
            {
                foreach($data['notification_channels'] as $id)
                    $this->notification_channels[] = Channel::fetch(intval($id));
            }

            $this->status = intval($data['status']);
            if($this->status == STATUS_DOWNTIME)
            {
                if(!is_numeric($data['downtime_start_hours']) ||
                   !is_numeric($data['downtime_start_minutes']) ||
                   !is_numeric($data['downtime_end_hours']) ||
                   !is_numeric($data['downtime_end_minutes'])
                  )
                {
                    $errors['interval'] = 'Invalid time or interval.';
                }
                $this->downtime_start = time() + intval($data['downtime_start_hours']) * 60 +
                intval($data['downtime_start_minutes']);
                $this->downtime_end = time() + intval($data['downtime_end_hours']) * 60 +
                intval($data['downtime_end_minutes']);
            }
            else
            {
                $this->downtime_start = 0;
                $this->downtime_end = 0;
            }

            $errors = $this->customProcessAddEdit($data, $errors);
            return $errors;
        }

        public function processDelete($data)
        {
            $this->customProcessDelete($data);
            return $GLOBALS['PW_DB']->executeDelete('monitors', 'WHERE id=' . intval($this->id));
        }

        public abstract function queryMonitor();
        public abstract function customProcessAddEdit($data, $errors);
        public abstract function customProcessDelete();
        public abstract function getName();
        public abstract function getDescription();

        public static function fetch($db_row)
        {
            if(is_int($db_row))
                $db_row = $GLOBALS['PW_DB']->executeSelectOne('*', 'monitors', 'WHERE id=' . intval($db_row));
            $monitor_type = $db_row['type'];
            return new $monitor_type($db_row);
        }
    }
?>
Return current item: phpWatch