/modules/asterisk-1.0/libraries/Asterisk.php
https://github.com/robertleeplummerjr/bluebox · PHP · 269 lines · 163 code · 42 blank · 64 comment · 24 complexity · f433215b59043050e8a1216fcfa3dfc3 MD5 · raw file
- <?php defined('SYSPATH') or die('No direct access allowed.');
- /**
- * @package Asterisk
- * @author K Anderson <bitbashing@gmail.com>
- * @license Mozilla Public License (MPL)
- * @created Oct 5, 2009
- */
- class Asterisk extends Telephony_Driver
- {
- /**
- * Multi-dimensional array. Key is the filename, which contains an array generated by parse_ini_file
- * @var array
- */
- public $config;
- /**
- * An instance of the AsteriskManager object, allowing configuration remotely via the AMI interface.
- * @var AsteriskManager
- */
- public $ami;
- /**
- * Instance of AsteriskDoc. Keeps a working copy of any relevant loaded/modified Asterisk configuration files in memory
- * for committing later to disk or AMI.
- * @var AsteriskDoc
- */
- public $doc;
- /**
- *
- * @return Asterisk
- */
- public static function getInstance()
- {
- // create a new instance if there isnt one already
- if (!isset(self::$instance))
- {
- self::$instance = new self();
- Kohana::log('debug', 'Asterisk -> New instance of Asterisk telephony driver created.');
- // reset all the accumulators in this driver
- self::reset();
- }
- // return this instance
- return self::$instance;
- }
- /**
- * Loads a context/section from an Asterisk config file.
- * @param array $options Array with keys for filename and context (both are required)
- * @param boolean $useCache OK to use cache if already in memory? Defaults to TRUE
- * @return string String object containing loaded data, if any, or FALSE if failed
- *
- * TODO: Add ability to load an entire file (should just be the built-in php ini options command, but need to check AMI equiv)
- */
- public function load($options, $useCache = TRUE)
- {
- // sanity check on our necessary vars
- if (empty($options['filename']) || empty($options['context']))
- {
- return FALSE;
- }
- else
- {
- extract($options);
- }
- // CACHE: check if this file's config section is already loaded and if we're allowed to use it
- if ($useCache and isset(self::$instance->doc->fileCache[$filename][$context]))
- {
- // Already loaded
- Kohana::log('debug', 'Asterisk -> Using cached file ' . $filename . ' for context ' . $context);
-
- return self::$instance->doc->fileCache[$filename][$context];
- }
- Kohana::log('debug', 'Asterisk -> Loading file ' . $filename . ' for context ' . $context . ' into cache');
- // get the asterisk manager interface
- $ami = self::$instance->ami;
- // make sure we are connected/can connect
- if (!self::connectAMI($ami)) {
- return FALSE;
- }
- // load the config section and store it in the active in-memory document
- self::$instance->doc->fileCache[$filename][$context] = $ami->loadConfigContext($filename, $context);
- //Kohana::log('debug', 'Loaded ' . $filename . ' / context ' . $context . ":\n" . print_r(self::$instance->doc->fileCache, TRUE));
- return self::$instance->doc->fileCache[$filename][$context];;
- }
- public function save($options = NULL)
- {
- // Make sure there is something to do
- if (empty(self::$instance->doc->fileCache))
- {
- Kohana::log('debug', 'Asterisk -> Not saving - nothing was changed!');
-
- return TRUE;
- }
- Kohana::log('debug', 'Asterisk -> Saving queued changes to Asterisk config files (via AMI)');
- // get the asterisk manager interface
- $ami = self::$instance->ami;
- // make sure we are connected/can connect
- if (!self::connectAMI($ami))
- {
- Kohana::log('error', 'Asterisk -> Failed to connect to Asterisk AMI interface.');
-
- return FALSE;
- }
- // Loop through all the filenames and contexts that have changed
- foreach(self::$instance->doc->fileCache as $filename => $contexts)
- {
- // Loop through all the config contexts
- foreach($contexts as $context => $lines)
- {
- // Remove this config section (ignoring any errors during) and re-create and empty one
- if ($context != 'general')
- {
- $ami->queueConfigUpdate($filename, 'DelCat', $context, NULL, NULL, array(
- 'ignoreResponse' => AsteriskManager::AMI_DEL_FAIL2
- ));
- }
- // Only re-add this context if there's something actually in it
- if ($lines)
- {
- // Go through and add the category and all associated lines back to the file
- if ($context != 'general')
- {
- $ami->queueConfigUpdate($filename, 'NewCat', $context);
- }
- // Loop through all the updates for this config section
- foreach($lines as $lineNum => $line)
- {
- // try to split the update on the =
- $lineParts = explode('=', $line, 2);
- // if the split returned false (no = found) or fewer than two parts
- if (!empty($lineParts) && count($lineParts) == 2)
- {
- $ami->queueConfigUpdate($filename, 'Append', $context, $lineParts[0], $lineParts[1], array(
- 'skippredelete' => TRUE
- ));
- }
- else
- {
- Kohana::log('error', 'Asterisk -> Unable to queue \'' . $line . '\' for [' . $context . '] in ' . $filename);
- }
- }
- }
- }
- // Clear the internal queue of actions
- try
- {
- $ami->commitConfigUpdates();
- }
- catch(AsteriskManager_Exception $e)
- {
- // This is a place holder for later error checking
- Kohana::log('error', 'Asterisk -> Exception during commit for [' . $context . '] in ' . $filename . ': ' . $e->getMessage());
- }
- }
- }
- public function commit()
- {
- // get the asterisk manager interface
- $ami = self::$instance->ami;
- // make sure we are connected/can connect
- if (!self::connectAMI($ami))
- {
- Kohana::log('error', 'Asterisk -> Failed to connect to Asterisk AMI interface.');
- return FALSE;
- }
- $ami->send('reload');
- return TRUE;
- }
- public function render()
- {
-
- }
- public function reset()
- {
- // Are we already instantiated? If not, create an instance.
- if (!is_object(self::$instance->ami) || get_class(self::$instance->ami) != 'AsteriskManager')
- {
- self::$instance->ami = new AsteriskManager();
- }
- else
- {
- // We are instantiated - close any existing AMI connections
- Kohana::log('debug', 'Asterisk -> Disconnecting from active Asterisk server');
- try
- {
- //self::$instance->ami->logoff();
- }
- catch(Exception $e)
- {
- // If we can't disconnect, no biggie. Ignore
- }
- self::$instance->ami->cancelConfigUpdates();
- }
- // Reset the in-memory config document
- if (self::$instance->doc)
- {
- self::$instance->doc->reset();
- }
- else
- {
- self::$instance->doc = new AsteriskDoc();
- }
- }
- private static function connectAMI($ami)
- {
- // is the $ami a valid AsteriskManager object?
- if (!is_object($ami) || get_class($ami) != 'AsteriskManager')
- {
- return FALSE;
- }
- // Are we already connected? Don't connect again.
- if (!$ami->connected())
- {
- $config = array(
- 'host' => Kohana::config('asterisk.AmiHost') ,
- 'port' => Kohana::config('asterisk.AmiPort') ,
- 'username' => Kohana::config('asterisk.AmiUser') ,
- 'password' => Kohana::config('asterisk.AmiPass')
- );
- $ami->setConfig($config);
- try
- {
- $ami->connect();
- }
- catch(AsteriskManager_Exception $e)
- {
- // Server unavailable for whatever reason.
- Kohana::log('error', 'Unable to connect to Asterisk AMI interface: ' . $e->getMessage());
- return FALSE;
- }
- }
- return TRUE;
- }
- }