sccp_manager/sccpManClasses/Sccp.class.php.v433
steve-lad 3475efc2c6 Database request modifications and page improvements
Add device to extensions page - permits to see unassigned  lines and shared lines easily
Reformat status to centred
change 'replace' in sccp class to only 'insert on duplicate key' (UPSET equivalent)
Change request in phoneGrid to left join to show all lines, even unassigned to a device
2021-07-21 11:30:50 +02:00

465 lines
23 KiB
PHP
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
// vim: set ai ts=4 sw=4 ft=php:
// Version for SCCP Manager 13.0.X
//
/* This is the driver for Sccp_manager in FreePBX.
It is loaded via an include, written by the installer, at
modules/core/functions.inc/drivers
and provides the following required methods. it provides the interface between
FreePBX extensions and sccp_manager lines
*
* getInfo
* addDevice
* delDevice
* getDevice - Called by core to read sccpline returning fields in data_fld
* getDefaultDeviceSettings -
* getDeviceDisplay - Called by functionsInc to load sccp tab using values from Device and getDevice.
*
*/
//
namespace FreePBX\modules\Core\Drivers;
class Sccp extends \FreePBX\modules\Core\Driver {
// This is a map between sccpline fields and FreePBX fields.
// TODO: List needs to be extended. Missing fields, not necessarily all required              
/* adhocNumber
              meetme
                meetmenum
               meetmeopts
                 regexten
          directed_pickup
  directed_pickup_context
        pickup_modeanswer
                 amaflags
setvar
            phonecodepage
                  trnsfvm
                    vmnum
*/
private $data_fld = array("pin"=>'pin', "label" => 'label', "accountcode" => 'account',
"context" =>'context',"incominglimit"=>'incominglimit',
"callgroup"=>'callgroup',"pickupgroup"=>'pickupgroup',
"transfer" => 'transfer', "echocancel" => 'echocancel',
"language" => 'language', "description" => 'callerid',
"cid_num" => 'cid_num', "cid_name" => 'label', "mailbox" => 'mailbox',
"musicclass" => 'musicclass', "allow" => 'allow',"disallow" => 'disallow',
"videomode" => 'videomode', 'pickup_modeanswer' => 'pickup_modeanswer',
"dnd" => 'dnd', "silencesuppression" => 'silencesuppression',
"secondary_dialtone_digits" => 'secondary_dialtone_digits', "secondary_dialtone_tone" => 'secondary_dialtone_tone',
'namedcallgroup'=>'namedcallgroup', 'namedpickupgroup' => 'namedpickupgroup'
);
// These are gui defaults used by freePBX for the elements in the SCCP tab in add/edit phone.
private $guiDefaults =array(
'gui_checkset' => array( "elemname" => "",
"prompttext" => "", //ok
"helptext" => "",
"currentvalue" => "",
"valarray" => array(),
"jsonclick" => '',
"jsvalidation" => "", //ok
"failvalidationmsg" => "", //ok
"canbeempty" => true,
"maxchars" => 0,
"disable" => false, //ok
"inputgroup" => false,
"class" => "",
"cblabel" => 'Enable',
"disabled_value" => 'DEFAULT',
"check_enables" => 'true',
"cbdisable" => false,
"cbclass" => '')
);
private $line_defaults = array();
public function __construct($parent_class = null) {
$this->freepbx = $parent_class;
$this->database = $parent_class->Database();
// Get system defaults [systemdefault] and sitedefaults [data] from sccpsettings.
$stmt = $this->database->prepare("SELECT * FROM sccpsettings WHERE systemdefault !=''");
$stmt->execute();
$raw_settings = $stmt->fetchAll(\PDO::FETCH_ASSOC);
foreach ($raw_settings as $key => $valueArray) {
$sccpDefaults[$valueArray['keyword']] = $valueArray['systemdefault'];
$siteDefaults[$valueArray['keyword']] = $valueArray['data'];
}
// This will produce an array where site defaults take precedence over system defaults
$this->line_defaults = array_intersect_key($siteDefaults,$sccpDefaults);
// If have no site codecs, use system defaults - must have a codec!
if (empty($this->line_defaults['allow'])) {
$this->line_defaults['allow'] = $sccpDefaults['allow'];
}
if (empty($this->line_defaults['disallow'])) {
$this->line_defaults['disallow'] = $sccpDefaults['disallow'];
}
unset($raw_settings, $siteDefaults, $sccpDefaults);
}
public function getInfo() {
return array(
"rawName" => "sccp",
"hardware" => "sccp_custom",
"prettyName" => _("Sccp Custom Driver"),
"shortName" => "SCCP",
"description" => _("Sccp Device"),
"Version" => "11.5",
"about" => "Sccp class Base ver: 11.5, Sccp ver: default"
);
}
public function addDevice($id, $settings) {
// This is actually save line and is used by add and edit.
$add_fld = array ("name"=>'label',"outboundcid"=>'cid_num',"langcode"=>'language',"extdisplay"=>'description','devinfo_mailbox'=>'mailbox');
$settings['cid_num']['value'] = '';
$settings['cid_name']['value'] = '';
$settings['mailbox']['value']= '';
// Add $_REQUEST values to settings
if (isset($_REQUEST)){
foreach($add_fld as $key => $val) {
if (!empty($_REQUEST[$key])){
$settings[$val]['value'] = $_REQUEST[$key];
}
}
}
$allow_codec = array();
foreach($settings as $key => $val) {
if (strncmp($key,'codec_',6) === 0 ) {
$allow_codec[] = str_replace('codec_','',$key);
}
}
$settings['allow']['value'] = implode(";", $allow_codec);
// Reset to line defaults if no value selected
if (empty($settings['allow']['value'])) {
$settings['allow']['value'] = $this->line_defaults['allow'];
}
// If set, parse outboundcid content into cid_num and cid_name sccpline fields
if (!empty($settings['cid_num']['value'])) {
$outboundcid = $settings['cid_num']['value'];
if (preg_match('/"(.*)"\s?<(.*)>/', $outboundcid, $matches)) {
$settings['cid_num']['value'] = $matches[2];
$settings['cid_name']['value'] = $matches[1];
} else if (is_integer($outboundcid)) {
$settings['cid_num']['value'] = $outboundcid;
}
}
if ($this->line_defaults['dndFeature'] == 'off') {
$settings['dnd']['value'] = 'off';
}
if (!empty($_REQUEST['vm']) && ($_REQUEST['vm'] =='enabled')){ // mailbox
if (empty($settings['mailbox']['value'])) {
$settings['mailbox']['value']= $id;
}
}
// only store values that have been set; if need to display a default, must show in page.
$sqlSet = "name='{$id}'";
foreach($this->data_fld as $key => $val) {
if (!empty($settings[$val]['value'])) {
$sqlSet .= ", {$key}='{$settings[$val]['value']}'";
}
}
$stmt = "INSERT INTO sccpline SET {$sqlSet} ON DUPLICATE KEY UPDATE {$sqlSet}";
$sth = $this->database->prepare($stmt);
$sth->execute();
/*
If called from SCCP Phone, redirect to SCCP Phone page on submit.
This was last function in add so should be safe.
Prefer to add in Hooks, but is not followed even if set for $currentComponent
Do nothing if called from QuickCreateExtension when display is not set
*/
if (isset($_REQUEST['display'])) {
redirect("config.php?display=sccp_phone", false);
}
// Have changed something so need to reload the device
// TODO: are we reloading the device or reloading Asterisk
$this->reload_line($id);
return true;
}
public function delDevice($id) {
//Required by FreePBX
$sql = "DELETE FROM sccpline WHERE name = ?";
$sth = $this->database->prepare($sql);
$sth->execute(array($id));
return true;
}
public function getDevice($id) {
// FreePBX required method
$sql = "SELECT name AS id, name AS name ";
foreach($this->data_fld as $key => $val) {
$sql .= ", {$key} AS {$val}";
}
$sql .= " FROM sccpline WHERE name = '{$id}'";
$sth = $this->database->prepare($sql);
$tech = array();
try {
$sth->execute(array($id));
$tech = $sth->fetch(\PDO::FETCH_ASSOC);
$tech['dial']="SCCP/{$id}";
} catch(\Exception $e) {}
return $tech;
}
public function getDefaultDeviceSettings($id, $displayname, &$flag) {
// FreePBX required method
$settingsFields = array('mailbox', 'incominglimit', 'context', 'directed_pickup_context', 'callgroup', 'pickupgroup', 'namedcallgroup',
'namedpickupgroup', 'adhocNumber', 'secondary_dialtone_digits', 'secondary_dialtone_tone', 'directed_pickup', 'pickup_modeanswer',
'transfer', 'echocancel', 'dnd', 'silencesuppression', 'musicclass', 'pin', 'allow', 'disallow');
foreach ($settingsFields as $key) {
$settings[$key] = array('value' => $this->line_defaults['$key'], 'flag' => $flag++);
}
return array('dial' => 'SCCP', 'settings' => $settings);
}
public function getDeviceDisplay($display, $deviceInfo, $currentComponent, $primarySection) {
$activeCodecs = array();
// load xml data to get help from same source as rest of module
$xml_vars = $_SERVER['DOCUMENT_ROOT'] . '/admin/modules/sccp_manager/conf/sccpgeneral.xml.v433';
$this->xml_data = simplexml_load_file($xml_vars);
// load metainfo from chan-sccp - help information if not in xml. Only load first time as static data.
if (empty($this->sccpHelpInfo)) {
$sysConfiguration = \FreePbx::sccp_manager()->aminterface->getSCCPConfigMetaData('general');
foreach ($sysConfiguration['Options'] as $key => $valueArray) {
foreach ($valueArray['Description'] as $descKey => $descValue) {
$this->sccpHelpInfo[$valueArray['Name']] .= $descValue . '<br>';
}
}
unset($sysConfiguration);
}
$section = _("SCCP Extension Details");
$section_с = _("SCCP Codec Details");
$gn_category = "sccp";
//add sccp category
$currentComponent->addTabTranslation('sccp',_('SCCP'));
// get site and system defaults
$systemCodecs = array_fill_keys(explode(';',$this->line_defaults['allow']),true);
$siteAudioCodecs = array_intersect_key($systemCodecs, $this->freepbx->Codecs->getAudio());
$siteVideoCodecs = array_intersect_key($systemCodecs, $this->freepbx->Codecs->getVideo());
if (empty($deviceInfo['allow'])) {
// No allowed codecs so reset to site defaults
foreach ($systemCodecs as $lineCodec => $dummyVal) {
$activeCodecs[] = "devinfo_codec_{$lineCodec}";
}
} else {
// have allowed codecs for this line
foreach (explode(';',$deviceInfo['allow']) as $lineCodec) {
$activeCodecs[] = "devinfo_codec_{$lineCodec}";
}
}
// Fill Audio codecs information
foreach ($siteAudioCodecs as $key => $value) {
$audioCodecButtons[] = array('value' => "devinfo_codec_{$key}", 'text' => $key);
}
// Fill Video codecs information
foreach ($siteVideoCodecs as $key => $value) {
$videoCodecButtons[] = array('value' => "devinfo_codec_{$key}", 'text' => $key);
}
$tmparr['disallow'] = array('prompttext' => _('Disallowed Codecs'),
'value' => $this->line_defaults['disallow'],
'tt' => 'Codecs that are disallowed. Default and recommended value is all',
'level' => 1,
'section' => $section_с,
'category' => $gn_category
);
$el = array(
"elemname" => "devinfo_sccp_codec",
"prompttext" => _('Line Audio Codec:'),
"helptext" => _("Line Audio Codec. Uncheck all Audio and Video codecs to return to site defaults"),
"currentvalue" => $activeCodecs,
"valarray" => $audioCodecButtons,
"class" => $section_с,
"disable" => 0
);
// Override defaults with $el
$currentComponent->addguielem($section_с, new \gui_checkset(array_merge($this->guiDefaults['gui_checkset'],$el)), $gn_category);
unset($el);
$el = array(
"elemname" => "devinfo_sccp_vcodec",
"prompttext" => _('Line Video Codec:'),
"helptext" => _("Line Video Codec"),
"currentvalue" => $activeCodecs,
"valarray" => $videoCodecButtons,
"class" => $section_с,
"disable" => 0
);
$currentComponent->addguielem($section_с, new \gui_checkset(array_merge($this->guiDefaults['gui_checkset'],$el)), $gn_category);
$pageGroup = $this->xml_data->xpath('//page_group[@name="sccp_extension_config"]');
$elements = $pageGroup[0]->children();
foreach ($elements as $child) {
if (empty($child->help)) {
$child->help = 'Help is not available.';
$child->meta_help = '1';
}
switch ($child['type']) {
case 'IE':
$elementID = (string)$child->input[0]->name;
if (!empty($metainfo[$elementID])) {
if ($child->meta_help == '1' || $child->help == 'Help!') {
$child->help = $metainfo[$shortId];
}
}
$tmparr[$elementID] = array('prompttext' => _((string)$child->label),
'value' => $this->line_defaults[$elementID],
'tt' => (string)$child->help,
'level' => 1,
'section' => $section,
'category' => $gn_category
);
break;
case 'IS':
$select = array();
foreach ($child->xpath('button') as $value) {
$select[] = array('value' => strtolower((string)$value[@value]), 'text' => (string)$value);
}
$hideButton = false;
if (($this->line_defaults['dndFeature'] == 'off') && ($child['id'] == 5)) {
$hideButton = true;
}
$tmparr[(string)$child->name] = array('prompttext' => _((string)$child->label),
'value' => $this->line_defaults[(string)$child->name],
'tt' => (string)$child->help,
'select' => $select,
'level' => 1,
'disable' => $hideButton,
'hidden' => $hideButton,
'type' => 'radio',
'section' => $section,
'category' => $gn_category
);
unset($select);
break;
case 'SLD':
$select = array(
array( 'value' => '0x21', 'text' => 'Inside Dial Tone'),
array( 'value' => '0x22', 'text' => 'Outside Dial Tone'),
array( 'value' => '0x23', 'text' => 'Line Busy Tone'),
array( 'value' => '0x24', 'text' => 'Alerting Tone'),
array( 'value' => '0x25', 'text' => 'Reorder Tone'),
array( 'value' => '0x26', 'text' => 'Recorder Warning Tone'),
array( 'value' => '0x27', 'text' => 'Recorder Detected Tone'),
array( 'value' => '0x28', 'text' => 'Reverting Tone'),
array( 'value' => '0x29', 'text' => 'Receiver OffHook Tone'),
array( 'value' => '0x2A', 'text' => 'Partial Dial Tone'),
array( 'value' => '0x2B', 'text' => 'No Such Number Tone'),
array( 'value' => '0x2C', 'text' => 'Busy Verification Tone'),
array( 'value' => '0x2D', 'text' => 'Call Waiting Tone'),
array( 'value' => '0x2E', 'text' => 'Confirmation Tone'),
array( 'value' => '0x2F', 'text' => 'Camp On Indication Tone'),
array( 'value' => '0x30', 'text' => 'Recall Dial Tone'),
array( 'value' => '0x31', 'text' => 'Zip Zip'),
array( 'value' => '0x32', 'text' => 'Zip'),
array( 'value' => '0x33', 'text' => 'Beep Bonk'),
array( 'value' => '0x34', 'text' => 'Music Tone'),
array( 'value' => '0x35', 'text' => 'Hold Tone'),
array( 'value' => '0x36', 'text' => 'Test Tone'),
array( 'value' => '0x37', 'text' => 'DT Monitor Warning Tone'),
array( 'value' => '0x40', 'text' => 'Add Call Waiting'),
array( 'value' => '0x41', 'text' => 'Priority Call Wait'),
array( 'value' => '0x42', 'text' => 'Recall Dial'),
array( 'value' => '0x43', 'text' => 'Barg In'),
array( 'value' => '0x44', 'text' => 'Distinct Alert'),
array( 'value' => '0x45', 'text' => 'Priority Alert'),
array( 'value' => '0x46', 'text' => 'Reminder Ring'),
array( 'value' => '0x47', 'text' => 'Precedence RingBank'),
array( 'value' => '0x48', 'text' => 'Pre-EmptionTone'),
array( 'value' => '0x67', 'text' => '2105 HZ'),
array( 'value' => '0x68', 'text' => '2600 HZ'),
array( 'value' => '0x69', 'text' => '440 HZ'),
array( 'value' => '0x6A', 'text' => '300 HZ'),
array( 'value' => '0x77', 'text' => 'MLPP Pala'),
array( 'value' => '0x78', 'text' => 'MLPP Ica'),
array( 'value' => '0x79', 'text' => 'MLPP Vca'),
array( 'value' => '0x7A', 'text' => 'MLPP Bpa'),
array( 'value' => '0x7B', 'text' => 'MLPP Bnea'),
array( 'value' => '0x7C', 'text' => 'MLPP Upa')
);
$tmparr[(string)$child->name] = array('prompttext' => _((string)$child->label),
'value' => $this->line_defaults[(string)$child->name],
'tt' => (string)$child->help,
'select' => $select,
'level' => 1,
'type' => 'select',
'section' => $section,
'category' => $gn_category
);
unset($select);
break;
case 'SLG':
$elementID = (string)$child->name;
$named_group = \FreePbx::sccp_manager()->dbinterface->getNamedGroup($elementID);
if (!empty($named_group[$elementID])) {
foreach ($named_group[$elementID] as $val) {
$select[] = array('value' => $val, 'text' => $val);
}
}
// Disable and hide list elements if there are no valid values
$tmparr[(string)$child->name] = array('prompttext' => _((string)$child->label),
'value' => $this->line_defaults[(string)$child->name],
'tt' => (string)$child->help,
'select' => $select,
'level' => 1,
'disable' => empty($named_group[$elementID][0]),
'hidden' => empty($named_group[$elementID][0]),
'section' => $section,
'category' => $gn_category
);
unset($select);
break;
case 'SLM':
if (function_exists('music_list')){
foreach (music_list() as $value) {
$select[] = array('value' => $value, 'text' => _($value));
}
} else {
$select[] = array('value' => 'default', 'text' => _('default'));
}
$tmparr[(string)$child->name] = array('prompttext' => _((string)$child->label),
'value' => $this->line_defaults[(string)$child->name],
'tt' => (string)$child->help,
'select' => $select,
'level' => 1,
'type' => 'select',
'section' => $section,
'category' => $gn_category
);
unset($select);
break;
}
}
return $tmparr;
}
public function reload_line($id) {
global $astman;
// TODO: Change to use amInterfaceClasses
$result = $astman->Command('sccp reload line ' . $id);
return $result;
}
public function getDeviceHeaders() {
return array(
'secret' => array('identifier' => _('Secret'), 'description' => sprintf(_('Secret [Enter "%s" to regenerate]'),"REGEN")),
);
}
}