PageRenderTime 39ms CodeModel.GetById 12ms RepoModel.GetById 0ms app.codeStats 0ms

/modules/default/actions/DiscarTronco.php

https://bitbucket.org/efepimenta/snep-3
PHP | 419 lines | 283 code | 55 blank | 81 comment | 53 complexity | 54a4709878052106a73147fb25bb04ba MD5 | raw file
Possible License(s): LGPL-3.0, GPL-3.0
  1. <?php
  2. /**
  3. * This file is part of SNEP.
  4. * Para território Brasileiro leia LICENCA_BR.txt
  5. * All other countries read the following disclaimer
  6. *
  7. * SNEP is free software: you can redistribute it and/or modify
  8. * it under the terms of the GNU Lesser General Public License as
  9. * published by the Free Software Foundation, either version 3 of
  10. * the License, or (at your option) any later version.
  11. *
  12. * SNEP is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU Lesser General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU Lesser General Public License
  18. * along with SNEP. If not, see <http://www.gnu.org/licenses/lgpl.txt>.
  19. */
  20. /**
  21. * Dial trunk
  22. *
  23. * @category Snep
  24. * @package PBX_Rule_Action
  25. * @copyright Copyright (c) 2010 OpenS Tecnologia
  26. * @author Henrique Grolli Bassotto
  27. */
  28. class DiscarTronco extends PBX_Rule_Action {
  29. /**
  30. * @var Zend_Translate
  31. */
  32. private $i18n;
  33. /**
  34. * Construtor
  35. * @param array $config configurações da ação
  36. */
  37. public function __construct() {
  38. $this->i18n = Zend_Registry::get("Zend_Translate");
  39. }
  40. /**
  41. * Retorna o nome da Ação. Geralmente o nome da classe.
  42. *
  43. * @return Name da Ação
  44. */
  45. public function getName() {
  46. return $this->i18n->translate("Dial Trunk");
  47. }
  48. /**
  49. * @return string
  50. */
  51. public function getVersion() {
  52. return SNEP_VERSION;
  53. }
  54. /**
  55. * Envia email de alerta sobre uso desse tronco
  56. *
  57. * @param array string $adresses
  58. * @param array $informations, informações a serem anexadas ao email.
  59. */
  60. private function sendMailAlert($addresses, $informations) {
  61. $log = Zend_Registry::get('log');
  62. $config = Zend_Registry::get('config');
  63. $mail = new Zend_Mail('UTF-8');
  64. $mail->setFrom($config->system->mail, 'SNEP PBX');
  65. if(is_array($addresses)) {
  66. foreach ($addresses as $address) {
  67. $mail->addTo(trim($address));
  68. }
  69. }
  70. else {
  71. $mail->addTo($addresses);
  72. }
  73. $mail->setSubject($this->i18n->translate('[snep] Warning of trunk usage'));
  74. $tronco = PBX_Trunks::get($this->config['tronco']);
  75. $msg = $this->i18n->translate("\tThis warning is being delivered to you because Snep detected the usage of a trunk marked with your email.\n");
  76. $msg .= $this->i18n->translate("Warning to trunk $tronco, the following information where gathered by the system:\n");
  77. foreach ($informations as $info => $message) {
  78. $msg .= "$info: $message\n";
  79. }
  80. $mail->setBodyText($msg);
  81. $log->info("Sending email to '{$this->config['alertEmail']}'");
  82. $mail->send();
  83. }
  84. /**
  85. * Seta as configurações da ação.
  86. *
  87. * @param array $config configurações da ação
  88. */
  89. public function setConfig($config) {
  90. if( !isset($config['tronco']) ) {
  91. throw new PBX_Exception_BadArg("Trunk is required");
  92. }
  93. $config['dial_timeout'] = (isset($config['dial_timeout'])) ? $config['dial_timeout'] : '60';
  94. $config['dial_flags'] = (isset($config['dial_flags'])) ? $config['dial_flags'] : "TWK";
  95. $config['alertEmail'] = (isset($config['alertEmail'])) ? $config['alertEmail'] : "";
  96. $this->config = $config;
  97. }
  98. /**
  99. * Retorna uma breve descrição de funcionamento da ação.
  100. * @return Descrição de funcionamento ou objetivo
  101. */
  102. public function getDesc() {
  103. return $this->i18n->translate("Dial to a Trunk");
  104. }
  105. /**
  106. * Devolve um XML com as configurações requeridas pela ação
  107. * @return String XML
  108. */
  109. public function getConfig() {
  110. $i18n = $this->i18n;
  111. $tronco = (isset($this->config['tronco']))?"<value>{$this->config['tronco']}</value>":"";
  112. $dial_timeout = (isset($this->config['dial_timeout']))?"<value>{$this->config['dial_timeout']}</value>":"";
  113. $dial_flags = (isset($this->config['dial_flags']))?"<value>{$this->config['dial_flags']}</value>":"";
  114. $dial_limit = (isset($this->config['dial_limit']))?"<value>{$this->config['dial_limit']}</value>":"";
  115. $carrier_msg = (isset($this->config['carrier_msg']))?"<value>{$this->config['carrier_msg']}</value>":"";
  116. $omit_kgsm = (isset($this->config['omit_kgsm']))?"<value>{$this->config['omit_kgsm']}</value>":"";
  117. $alertEmail = (isset($this->config['alertEmail']))?"<value>{$this->config['alertEmail']}</value>":"";
  118. $Tdialtime = $i18n->translate("Dial Timeout");
  119. $Tcallduration = $i18n->translate("Call Duration Limit");
  120. $Tmiliseconds = $i18n->translate("in milliseconds");
  121. $Tdial = $i18n->translate("Dial Flags");
  122. $Talert = $i18n->translate("Ommit origin (only for Khomp KGSM)");
  123. $Talertemail = $i18n->translate("Alert email");
  124. return <<<XML
  125. <params>
  126. <tronco>
  127. <id>tronco</id>
  128. $tronco
  129. </tronco>
  130. <int>
  131. <id>dial_timeout</id>
  132. <label>$Tdialtime</label>
  133. <unit>{$i18n->translate("segundos")}</unit>
  134. <size>2</size>
  135. <default>60</default>
  136. $dial_timeout
  137. </int>
  138. <int>
  139. <id>dial_limit</id>
  140. <default>0</default>
  141. <label>$Tcallduration</label>
  142. <size>4</size>
  143. <unit>$Tmiliseconds</unit>
  144. $dial_limit
  145. </int>
  146. <string>
  147. <id>dial_flags</id>
  148. <label>$Tdial</label>
  149. <size>10</size>
  150. <default>TWK</default>
  151. $dial_flags
  152. </string>
  153. <boolean>
  154. <id>carrier_msg</id>
  155. <default>false</default>
  156. <label>{$i18n->translate("Detectar Atendimento de Maquina e Caixa de Mensagem")}</label>
  157. $carrier_msg
  158. </boolean>
  159. <boolean>
  160. <id>omit_kgsm</id>
  161. <default>false</default>
  162. <label>$Talert</label>
  163. $omit_kgsm
  164. </boolean>
  165. <string>
  166. <id>alertEmail</id>
  167. <label>$Talertemail</label>
  168. <size>50</size>
  169. $alertEmail
  170. </string>
  171. </params>
  172. XML;
  173. }
  174. /**
  175. * Configurações padrão para todas as ações dessa classe. Essas possuem uma
  176. * tela de configuração separada.
  177. *
  178. * Os campos descritos aqui podem ser usados para controle de timout,
  179. * valores padrão e informações que não pertencem exclusivamente a uma
  180. * instancia da ação em uma regra de negócio.
  181. *
  182. * @return string XML com as configurações default para as classes
  183. */
  184. public function getDefaultConfigXML() {
  185. $i18n = $this->i18n;
  186. $play_warning_value = isset($this->defaultConfig['play_warning']) ? "<value>{$this->defaultConfig['play_warning']}</value>" : "";
  187. $warning_freq_value = isset($this->defaultConfig['warning_freq']) ? "<value>{$this->defaultConfig['warning_freq']}</value>" : "";
  188. $warning_sound_value = isset($this->defaultConfig['warning_sound']) ? "<value>{$this->defaultConfig['warning_sound']}</value>" : "";
  189. $Tsecondsleft = $i18n->translate("Seconds left to alert");
  190. $Tinmili = $i18n->translate("in milliseconds");
  191. $Trepetition = $i18n->translate("Alert repetition rate");
  192. $Talertsound = $i18n->translate("Alert sound");
  193. return <<<XML
  194. <params>
  195. <int>
  196. <id>play_warning</id>
  197. <label>$Tsecondsleft</label>
  198. <unit>$Tinmili</unit>
  199. <size>5</size>
  200. $play_warning_value
  201. </int>
  202. <int>
  203. <id>warning_freq</id>
  204. <label>$Trepetition</label>
  205. <unit>{$i18n->translate("in milliseconds")}</unit>
  206. <size>5</size>
  207. $warning_freq_value
  208. </int>
  209. <string>
  210. <id>warning_sound</id>
  211. <default>beep</default>
  212. <label>$Talertsound</label>
  213. $warning_sound_value
  214. </string>
  215. </params>
  216. XML;
  217. }
  218. /**
  219. * Executa a ação. É chamado dentro de uma instancia usando AGI.
  220. *
  221. * @param Asterisk_AGI $asterisk
  222. * @param Asterisk_AGI_Request $request
  223. */
  224. public function execute($asterisk, $request) {
  225. $log = Zend_Registry::get('log');
  226. $db = Zend_Registry::get('db');
  227. $trs = $this->i18n;
  228. $tronco = PBX_Trunks::get($this->config['tronco']);
  229. $trunkId = $tronco->getId();
  230. $validate = true;
  231. $sql = "SELECT * FROM trunks WHERE id='$trunkId' AND time_total IS NOT NULL";
  232. $trunk = $db->query($sql)->fetch();
  233. if (count($trunk) > 1) {
  234. $sql = "SELECT * FROM time_history WHERE owner='$trunkId' && owner_type='T' ";
  235. switch ($trunk['time_chargeby']) {
  236. case 'Y':
  237. $sql .= "&& year=YEAR(NOW()) && month IS NULL && day IS NULL";
  238. break;
  239. case 'M':
  240. $day = date('d');
  241. $year = date("Y");
  242. if($day < $trunk['time_initial_date']){
  243. $month = date('m');
  244. }else{
  245. $month = date("m", strtotime("+1 month"));
  246. if($month == '01'){
  247. $year = date("Y", strtotime("+1 year"));
  248. }
  249. }
  250. $sql .= "&& year='$year' && month='$month' && day IS NULL";
  251. break;
  252. case 'D':
  253. $sql .= "&& year=YEAR(NOW()) && month=MONTH(NOW()) && day=DAY(NOW())";
  254. break;
  255. }
  256. $query_result = $db->query($sql)->fetch();
  257. if (count($query_result) > 0 ){
  258. if($query_result["used"] > $trunk["time_total"]*60){
  259. $log->info("Chamada bloqueada - TRONCO -> ".$trunk['callerid']." atingiu o tempo limite");
  260. $validate = false;
  261. }
  262. }
  263. }
  264. if($validate){
  265. // Montando as Flags para limite na ligação
  266. $flags = $this->config['dial_flags'];
  267. if(isset($this->config['dial_limit']) && $this->config['dial_limit'] > 0) {
  268. $flags .= "L(" . $this->config['dial_limit'];
  269. // play_warning_value
  270. if( isset($this->defaultConfig['play_warning']) && $this->defaultConfig['play_warning'] > 0) {
  271. $flags .= ":" . $this->defaultConfig['play_warning'];
  272. // warning_freq
  273. if( isset($this->defaultConfig['warning_freq']) && $this->defaultConfig['warning_freq'] > 0) {
  274. $flags .= ":" . $this->defaultConfig['warning_freq'];
  275. }
  276. }
  277. $flags .= ")";
  278. if( isset($this->defaultConfig['warning_sound']) ) {
  279. $warning_sound = $this->defaultConfig['warning_sound'] != "" ? $this->defaultConfig['warning_sound'] : "beep";
  280. $asterisk->set_variable("LIMIT_WARNING_FILE", $warning_sound);
  281. }
  282. }
  283. if($tronco->getDtmfDialMode()) {
  284. $dst_number = $tronco->getDtmfDialNumber();
  285. $flags .= "D($request->destino)";
  286. }
  287. else {
  288. $dst_number = $request->destino;
  289. }
  290. if($tronco->getInterface() instanceof PBX_Asterisk_Interface_SIP_NoAuth || $tronco->getInterface() instanceof PBX_Asterisk_Interface_IAX2_NoAuth) {
  291. $destiny = $tronco->getInterface()->getTech() . "/" . $dst_number . "@" . $tronco->getInterface()->getHost();
  292. }else {
  293. $postfix = "/";
  294. if (isset($this->config['omit_kgsm']) && $this->config['omit_kgsm'] == "true") {
  295. $postfix .= "orig=restricted";
  296. if ( isset($this->config['carrier_msg']) && $this->config['carrier_msg'] == "true") {
  297. $postfix .= ":";
  298. }
  299. }
  300. if (isset($this->config['carrier_msg']) && $this->config['carrier_msg'] == "true") {
  301. $ret_agi = $asterisk->get_variable("CHANNEL");
  302. $postfix .= "parent=".$ret_agi['data'].":answer_info:drop_on=message_box+carrier_message";
  303. }
  304. if (strlen($postfix) == 1) {
  305. $postfix = "";
  306. }
  307. }
  308. $destiny = $tronco->getInterface()->getCanal() . "/" . $dst_number . $postfix;
  309. $log->info("Dialing to $request->destino through trunk {$tronco->getName()}($destiny)");
  310. $dialstatus = $asterisk->get_variable("DIALSTATUS");
  311. $lastdialstatus = $dialstatus['data'];
  312. if( Zend_Registry::get('outgoingNumber') !== "" ) {
  313. $asterisk->set_variable("CALLERID(num)", Zend_Registry::get('outgoingNumber') );
  314. }
  315. $log->debug("Dial($destiny, {$this->config['dial_timeout']}, $flags)");
  316. // ==== DIAL ====
  317. $asterisk->exec_dial($destiny, $this->config['dial_timeout'], $flags);
  318. $dialstatus = $asterisk->get_variable("DIALSTATUS");
  319. $log->debug("DIALSTATUS: " . $dialstatus['data']);
  320. // Enviar email de alerta.
  321. if(isset($this->config['alertEmail']) && $this->config['alertEmail'] != "") {
  322. $informations = array(
  323. $trs->translate('Rule') => $this->getRule(),
  324. $trs->translate('Call Time') => date('H:i'),
  325. $trs->translate('Call Date') => date('d/m/Y'),
  326. $trs->translate('Original Source') => $request->getOriginalCallerid(),
  327. $trs->translate('Original Destination') => $request->getOriginalExtension(),
  328. $trs->translate('Source') => $request->origem,
  329. $trs->translate('Destination') => $request->destino,
  330. $trs->translate('Call status') => $dialstatus['data']
  331. );
  332. if($lastdialstatus != "") {
  333. $lastdialaction = null;
  334. foreach ($this->getRule()->getAcoes() as $action) {
  335. if($action == $this) {
  336. break;
  337. }
  338. $cfg = $action->getConfigArray();
  339. if($action instanceof DiscarTronco) {
  340. $lastdialaction = PBX_Trunks::get($cfg['tronco']);
  341. }
  342. else if($action instanceof DiscarRamal) {
  343. $lastdialaction = $cfg['ramal'];
  344. }
  345. }
  346. $informations[$trs->translate("\nThere were a previous call attempt")] = "";
  347. $informations[$trs->translate("Last call to")] = $lastdialaction;
  348. $informations[$trs->translate("Status of last call")] = $lastdialstatus;
  349. }
  350. $this->sendMailAlert(explode(",",$this->config['alertEmail']), $informations);
  351. }
  352. switch($dialstatus['data']) {
  353. case 'ANSWER':
  354. case 'CANCEL':
  355. case 'NOANSWER':
  356. case 'BUSY':
  357. throw new PBX_Rule_Action_Exception_StopExecution("Call end");
  358. break;
  359. default:
  360. $log->err($dialstatus['data'] . " dialing to $request->destino through trunk $tronco");
  361. }
  362. }
  363. }
  364. }