Browse Source

commit inicial

0.0.1
lucascardo12 3 years ago
commit
d5a5814a55
  1. 4
      .htaccess
  2. 3
      .vscode/settings.json
  3. 501
      app/Controllers/AgentController.php
  4. 181
      app/Controllers/BilheteController.php
  5. 149
      app/Controllers/ClassificacaoController.php
  6. 45
      app/Controllers/ClientController.php
  7. 55
      app/Controllers/MessageController.php
  8. 185
      app/Controllers/QueueController.php
  9. 53
      app/Controllers/SupervisorQueueController.php
  10. 350
      app/Core/Commands.php
  11. 81
      app/Core/Connect.php
  12. 23
      app/Core/Controller.php
  13. 267
      app/Core/CoreMedia.php
  14. 174
      app/Core/Media.php
  15. 121
      app/Core/Model.php
  16. 39
      app/Interfaces/IApiMedia.php
  17. 39
      app/Middleware/Http.php
  18. 145
      app/Middleware/Middleware.php
  19. 228
      app/Models/Agent.php
  20. 103
      app/Models/Bilhete.php
  21. 49
      app/Models/Classificacao.php
  22. 63
      app/Models/EventQueue.php
  23. 21
      app/Models/ListaNegraPalavras.php
  24. 40
      app/Models/Message.php
  25. 46
      app/Models/NotificaMedia.php
  26. 19
      app/Models/Parametros.php
  27. 89
      app/Models/Pause.php
  28. 29
      app/Models/Protocol.php
  29. 53
      app/Models/Queue.php
  30. 22
      app/Models/Ramal.php
  31. 26
      app/Models/SupervisorQueue.php
  32. 523
      app/Providers/ApiTelegram.php
  33. 78
      app/Providers/Crypt.php
  34. 177
      app/Providers/Logger.php
  35. 522
      app/Providers/Positus.php
  36. 101
      app/Providers/RequestURL.php
  37. 258
      app/Providers/WebHeader.php
  38. 9
      bd
  39. 17
      composer.json
  40. 18
      composer.lock
  41. 14
      config/agent.php
  42. 59
      config/app.php
  43. 15
      config/display_errors.php
  44. 20
      config/event.php
  45. 16
      config/helpers.php
  46. 32
      config/log.php
  47. 25
      config/middleware.php
  48. 60
      config/telegram.php
  49. 60
      config/whatsapp.php
  50. 282
      database/att-v2.sql
  51. 20
      database/database.sql
  52. 117
      includes/config.php
  53. 9
      index.php
  54. 211
      scripts/service/monitora_agente_wpp.php
  55. 29
      scripts/service/request.php
  56. 8
      scripts/service/teste.php
  57. 7
      vendor/autoload.php
  58. 479
      vendor/composer/ClassLoader.php
  59. 283
      vendor/composer/InstalledVersions.php
  60. 21
      vendor/composer/LICENSE
  61. 10
      vendor/composer/autoload_classmap.php
  62. 9
      vendor/composer/autoload_namespaces.php
  63. 11
      vendor/composer/autoload_psr4.php
  64. 55
      vendor/composer/autoload_real.php
  65. 44
      vendor/composer/autoload_static.php
  66. 5
      vendor/composer/installed.json
  67. 24
      vendor/composer/installed.php

4
.htaccess

@ -0,0 +1,4 @@
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php/$1 [L]

3
.vscode/settings.json vendored

@ -0,0 +1,3 @@
{
"files.encoding": "iso88591"
}

501
app/Controllers/AgentController.php

@ -0,0 +1,501 @@
<?php
namespace app\Controllers;
use app\Core\Controller;
use app\Models\Agent;
use app\Models\Queue;
use app\Models\Ramal;
use app\Models\Pause;
use app\Models\Bilhete;
use app\Models\EventQueue;
use app\Controllers\ClassificacaoController;
use Exception;
/**
* Description of AgentController
*
* @author root
*/
class AgentController extends Controller
{
private $agent;
private $queue;
private $ramal;
private $pause;
private $bilhete;
private $eventqueue;
public function __construct()
{
$this->agent = new Agent();
$this->queue = new Queue();
$this->ramal = new Ramal();
$this->pause = new Pause();
$this->bilhete = new Bilhete();
$this->eventqueue = new EventQueue();
}
public function openService($ramal, $origemDest)
{
try {
$this->agent->begin();
$agent = $this->agent->findAgentByRamal($ramal);
$uniqueid = uniqid('', true);
$this->agent->updateAgent($agent->matricula, $ramal, CONF_AGENT_STATUS_OCUPADO, $origemDest, null, 1, $uniqueid);
$this->agent->commit();
return $uniqueid;
} catch (Exception $ex) {
$this->agent->rollback();
logger()->error($ex->getMessage());
}
return false;
}
public function closeService($telefone, $motivo, $media)
{
try {
$this->agent->begin();
$atendimento = $this->agent->findByNumber($telefone);
$agent = $this->agent->findAgentByRamal($atendimento->ramal);
if (!$atendimento || !$agent->origem_destino) {
throw new Exception('Você precisa estar em um atendimento para finalizar!');
}
$scr = $agent->origem_destino;
$dst = $agent->ramal;
$unique = ($agent->uniqueid) ? $agent->uniqueid : null;
$billsec = strtotime($agent->logado) - strtotime($agent->duracao);
$duration = $billsec;
$disposition = 'ANSWERED';
$calldate = date('Y-m-d H:i:s');
$uniqueid = $this->bilhete->addBilhete($calldate, $scr, $dst, $duration, $billsec, $disposition, $unique);
if (!$uniqueid) {
throw new Exception('Não foi possével criar o uniqueid para o bilhete!');
}
if (!$motivo) {
$motivo = $atendimento->phone == 'CLIENT' ? CONF_EVENT_WHATSAPP_TIMERMINO_CLIENTE : CONF_EVENT_WHATSAPP_TIMERMINO_AGENTE;
}
$this->eventqueue->addEventQueue($uniqueid, $agent->dac, $agent->matricula, $motivo, $media);
/*
* VERIFICA CLASSIFICACAO ATENDIMENTO
*/
$classificacao = new ClassificacaoController();
$chamadaSemClassificacao = $classificacao->agentClassificacaoPending($agent->matricula, $agent->dac);
$this->agent->updateAgent($agent->matricula, $agent->ramal, CONF_AGENT_STATUS_LIVRE, null, null, 1, null, ($chamadaSemClassificacao) ? 0 : 1);
$this->agent->commit();
return [$dst, $scr];
} catch (Exception $ex) {
$this->agent->rollback();
$this->message($ex->getMessage());
logger()->error($ex->getMessage());
}
return false;
}
public function inService($telefone)
{
try {
$atendimento = $this->agent->findByNumber($telefone);
if (!$atendimento && $this->ramal->findRamal($telefone)) {
return false;
} else {
return ($atendimento ? $atendimento : false);
}
} catch (Exception $ex) {
logger()->error($ex->getMessage());
}
return false;
}
public function login($ramal, $login, $fila, $media)
{
try {
$this->agent->begin();
$queue = $this->queue->findQueueByName(strtoupper($fila));
$agent = $this->agent->findByAgent(strtolower($login));
if ($queue->midiafila == 'N') {
throw new Exception('Fila não relacionada como WhatsApp!');
}
if (!$queue) {
throw new Exception('Fila não encontrada ou não relacionada como WhatsApp!');
}
if (!$agent) {
throw new Exception('Usuário não encontrado!');
}
if (!$this->ramal->findRamal($ramal)) {
throw new Exception('Telefone não encontrado!');
}
if ($this->agent->findByNumber($ramal)) {
throw new Exception('Agente já autenticado!');
}
/**
* VERIFICA CLASSIFICACAO ATENDIMENTO
*/
$classificacao = new ClassificacaoController();
$chamadaSemClassificacao = $classificacao->agentClassificacaoPending($agent->matricula, $fila);
if (!$this->agent->addAgent($agent->matricula, $ramal, $login, $queue->nome, $media, ($chamadaSemClassificacao ? 0 : 1))) {
throw new Exception('Não foi possével inserir o agente!');
}
if (!$this->agent->addEventoLoginAgent($agent->matricula, $ramal, $queue->id)) {
throw new Exception('Não foi possível inserir as informações de autenticação do login!');
}
$this->agent->commit();
return true;
} catch (Exception $ex) {
$this->agent->rollback();
$this->message($ex->getMessage());
logger()->error($ex->getMessage());
}
return false;
}
public function logoff($ramal)
{
try {
$this->agent->begin();
$agent = $this->agent->findAgentByRamal($ramal);
if (!$agent) {
throw new Exception('Telefone não encontrado!');
}
$queue = $this->queue->findQueueByName($agent->dac);
if (!$queue) {
throw new Exception('Agente não conectado!');
}
if ($agent->status == CONF_AGENT_STATUS_PAUSA) {
$this->message('Agente removido de pausa!');
$this->pause->updateEventoOutPause($agent->matricula, $queue->id);
}
if ($agent->status != CONF_AGENT_STATUS_LIVRE) {
throw new Exception('');
}
$this->agent->updateEventoLogoffAgent($agent->matricula, $ramal, $queue->id);
$this->agent->deleteAgent($agent->matricula, $ramal);
$this->agent->commit();
return true;
} catch (Exception $ex) {
$this->agent->rollback();
$this->message($ex->getMessage());
logger()->error($ex->getMessage());
}
return false;
}
public function enterPause($ramal, $pausa)
{
try {
$this->agent->begin();
$agent = $this->agent->findAgentByRamal($ramal);
$queue = $this->queue->findQueueByName($agent->dac);
$pause = $this->pause->findPauseByName($pausa);
if (!$agent) {
throw new Exception('Telefone não identificado!');
}
if (!$pause) {
throw new Exception('Pausa não encontrada!');
}
if (!$queue) {
throw new Exception('Usuário não conectado em uma fila!');
}
if ($agent->status != 'LIVRE') {
throw new Exception('Agente precisa estar livre para entrar em pausa!');
}
if (!$this->agent->updateAgent($agent->matricula, $ramal, CONF_AGENT_STATUS_PAUSA, null, $pause->motivo, 1)) {
throw new Exception('Não foi possível atualizar o status do agente!');
}
if (!$this->pause->addEventoPauseAgent($agent->matricula, $ramal, $pause->id, $queue->id, $pause->produtiva)) {
throw new Exception('Não foi possível atualizar informações complementares do agente!');
}
$this->agent->commit();
return true;
} catch (Exception $ex) {
$this->agent->rollback();
$this->message($ex->getMessage());
logger()->error($ex->getMessage());
}
return false;
}
public function exitPause($ramal)
{
try {
$this->agent->begin();
$agent = $this->agent->findAgentByRamal($ramal);
$queue = $this->queue->findQueueByName($agent->dac);
if (!$agent) {
throw new Exception('Telefone não identificado!');
}
if (!$queue) {
throw new Exception('Agente não está conectado!');
}
if ($agent->status != CONF_AGENT_STATUS_PAUSA) {
throw new Exception('Agente não está em pausa!');
}
$this->agent->updateAgent($agent->matricula, $ramal, CONF_AGENT_STATUS_LIVRE, null, null, 1);
$this->pause->updateEventoOutPause($agent->matricula, $queue->id);
$this->agent->commit();
return true;
} catch (Exception $ex) {
$this->agent->rollback();
$this->message($ex->getMessage());
logger()->error($ex->getMessage());
}
return false;
}
public function transfer($ramal, $ramalTransfer)
{
try {
$this->agent->begin();
$agent = $this->agent->findAgentByRamal($ramal);
if (!$agent) {
throw new Exception('Agente não conectado!');
}
$agentTransf = $this->agent->findAgentByRamal($ramalTransfer);
if (!$agentTransf || $agentTransf->status != CONF_AGENT_STATUS_LIVRE) {
throw new Exception('Agente indisponível para atendimento!');
}
/** Agente Liberado ap�s a transferencia */
$this->agent->updateAgent($agent->matricula, $ramal, CONF_AGENT_STATUS_LIVRE, null, null, 1);
/** Agente Ocupado ap�s a transferencia */
$this->agent->updateAgent($agentTransf->matricula, $ramalTransfer, CONF_AGENT_STATUS_OCUPADO, $agent->origem_destino, null, 1);
$this->agent->commit();
return [$ramal, $ramalTransfer];
} catch (Exception $ex) {
$this->agent->rollback();
$this->message($ex->getMessage());
logger()->error($ex->getMessage());
}
return false;
}
public function infoAgentes($media, $queue = null)
{
try {
$agent = $this->agent->findAllAgentes($media, $queue);
return $agent;
} catch (Exception $ex) {
$this->agent->rollback();
$this->message($ex->getMessage());
logger()->error($ex->getMessage());
}
return false;
}
public function status($ramal, $status, $origemDestino = null)
{
try {
$this->agent->begin();
$agent = $this->agent->findAgentByRamal($ramal);
if (!$agent) {
throw new Exception('Agente não conectado!');
}
$this->agent->updateAgent($agent->matricula, $ramal, strtoupper($status), $origemDestino, null, 1);
$this->agent->commit();
return true;
} catch (Exception $ex) {
$this->agent->rollback();
$this->message($ex->getMessage());
logger()->error($ex->getMessage());
}
return false;
}
public function priority($queue)
{
try {
$agents = $this->agent->findAgentByQueue($queue, CONF_AGENT_STATUS_LIVRE, 'penalidade', 'ASC');
if (!$agents) {
$this->message('Agentes não encontrado!');
return null;
}
//se tiver somente um agente livre
if (sizeof($agents) == 1) {
return $agents[0]->ramal;
}
//validar se possui penalidades iguais
if ($agents[0]->penalidade == $agents[1]->penalidade) {
return null;
}
return $agents[0]->ramal;
} catch (Exception $ex) {
logger()->error($ex->getMessage());
}
return false;
}
public function isAgent($ramal)
{
try {
if (!$this->ramal->findRamal($ramal)) {
return 0;
}
return 1;
} catch (Exception $ex) {
logger()->error($ex->getMessage());
}
return false;
}
public function inactiveAgents()
{
$agents = $this->agent->findAllAgentes();
$inactiveAgents = array();
foreach ($agents as $agent) {
$freeTime = strtotime($agent->logado) - strtotime($agent->duracao);
array_push($inactiveAgents, array(
"UNIQUEID" => $agent->uniqueid,
"MATRICULA" => $agent->matricula,
"ORIGEM_DESTINO" => $agent->origem_destino,
"RAMAL" => $agent->ramal,
"STATUS" => $agent->status,
"SALA2" => $agent->sala_2,
'SALA1' => $agent->sala_1,
"FILA" => $agent->dac,
"CLASSIFICADO" => $agent->chamada_classificado,
"FREETIME" => $freeTime
));
}
return $inactiveAgents;
}
public function refreshAgent($ramal, $sala2 = null)
{
try {
$this->agent->begin();
$agent = $this->agent->findAgentByRamal($ramal);
if (!$agent) {
throw new Exception('Telefone não identificado!');
}
$this->agent->updateRefreshAgent($agent->matricula, $ramal);
$this->agent->updateSala2Agent($agent->matricula, $ramal, $sala2);
$this->agent->commit();
return true;
} catch (Exception $ex) {
$this->agent->rollback();
$this->message($ex->getMessage());
logger()->error($ex->getMessage());
}
return false;
}
public function agentVerify($ramal)
{
try {
$this->agent->begin();
$agent = $this->agent->findAgentByRamal($ramal);
if (!$agent) {
throw new Exception('Telefone não identificado!');
}
$this->agent->updateRefreshAgent($agent->matricula, $ramal, true);
$this->agent->updateSala2Agent($agent->matricula, $ramal, null);
$this->agent->commit();
return true;
} catch (Exception $ex) {
$this->agent->rollback();
$this->message($ex->getMessage());
logger()->error($ex->getMessage());
}
return false;
}
public function timeFinishAgente($matricula, $ramal, $timer = null)
{
try {
$this->agent->begin();
if ($timer) {
$timerFinish = strtotime("+{$timer} minutes", time());
} else {
$timerFinish = null;
}
$this->agent->updateSala2Agent($matricula, $ramal, $timerFinish);
$this->agent->commit();
return true;
} catch (Exception $ex) {
$this->agent->rollback();
$this->message($ex->getMessage());
logger()->error($ex->getMessage());
}
return false;
}
public function getAgente($ramal)
{
try {
$this->agent->begin();
$agent = $this->agent->findAgentByRamal($ramal);
$agent->nome = ucwords(explode(' ', str_replace('.', ' ', $agent->nome))[0]);
if (!$agent) {
throw new Exception('Telefone não identificado!');
}
$this->agent->commit();
return $agent;
} catch (Exception $ex) {
$this->agent->rollback();
$this->message($ex->getMessage());
logger()->error($ex->getMessage());
}
return false;
}
public function findRamal($ramal)
{
try {
return $this->ramal->findRamal($ramal);
} catch (Exception $ex) {
logger()->error($ex->getMessage());
}
return false;
}
public function listaPausas()
{
try {
$pausas = $this->pause->findAllPause(true);
return $pausas;
} catch (Exception $ex) {
$this->agent->rollback();
$this->message($ex->getMessage());
logger()->error($ex->getMessage());
return false;
}
}
}

181
app/Controllers/BilheteController.php

@ -0,0 +1,181 @@
<?php
namespace app\Controllers;
use app\Core\Controller;
use app\Models\Bilhete;
use app\Models\EventQueue;
use app\Models\SupervisorQueue;
use app\Models\Parametros;
use app\Models\Protocol;
use Exception;
class BilheteController extends Controller
{
private $supervisorqueue;
private $parametros;
private $protocol;
private $bilhete;
private $eventqueue;
public function __construct()
{
$this->supervisorqueue = new SupervisorQueue();
$this->parametros = new Parametros();
$this->protocol = new Protocol();
$this->bilhete = new Bilhete();
$this->eventqueue = new EventQueue();
}
public function bilheteInQueue($src, $duration, $billsec, $disposition, $queue, $event, $dst = 'null', $agent = null, $media)
{
try {
$this->bilhete->begin();
$uniqueid = $this->bilhete->addBilhete('now', $src, $dst, $duration, $billsec, $disposition);
$this->eventqueue->addEventQueue($uniqueid, $queue, $agent, $event, $media);
$this->bilhete->commit();
return true;
} catch (Exception $ex) {
$this->bilhete->rollback();
logger()->error($ex->getMessage());
}
return false;
}
public function bilheteForaHorario($eventos, $queue = null, $data = null, $media = null)
{
try {
$bilhetes = $this->bilhete->findBilheteByEventosDacs($queue, $data, $eventos, null, $media);
return $bilhetes;
} catch (Exception $ex) {
logger()->error($ex->getMessage());
}
return false;
}
public function atenderBilheteForaHorario($uniqueid, $ramalorigem, $queue, $agent, $newuniqueid = null)
{
try {
$this->bilhete->begin();
$this->bilhete->updateBilheteForaHorario($uniqueid, $ramalorigem, '0', 'ANSWERED');
$bilhete = $this->bilhete->findByUniqueid($uniqueid);
$tempoEspera = time() - strtotime($bilhete->calldate);
$this->eventqueue->updateEventQueue($uniqueid, $queue, $agent, CONF_EVENT_WHATSAPP_TIMERMINO_AGENTE, $tempoEspera, $newuniqueid);
$this->bilhete->commit();
} catch (Exception $ex) {
$this->bilhete->rollback();
$this->message($ex->getMessage());
logger()->error($ex->getMessage());
}
return false;
}
public function cancelarBilheteForaHorario($ramal)
{
try {
$this->bilhete->begin();
$bilhetesForaHorario = $this->bilhete->findBilheteBySrc($ramal, CONF_EVENT_WHATSAPP_ESPERA);
if (!$bilhetesForaHorario) {
throw new Exception('Não foram encontrados atendimentos em espera!');
}
$this->bilhete->updateBilheteForaHorario($bilhetesForaHorario->uniqueid, $ramal, '0', CONF_EVENT_WHATSAPP_ABANDONADA);
$this->eventqueue->updateEventQueue($bilhetesForaHorario->uniqueid, $bilhetesForaHorario->fila, $bilhetesForaHorario->agente, CONF_EVENT_WHATSAPP_ABANDONADA);
$this->bilhete->commit();
return true;
} catch (Exception $ex) {
$this->bilhete->rollback();
$this->message($ex->getMessage());
logger()->error($ex->getMessage());
}
return false;
}
public function tempoEsperaSupervisor($uniqueid)
{
try {
$this->supervisorqueue->begin();
$queue = $this->eventqueue->findEventQueueByParam2($uniqueid);
if ($queue) {
$this->supervisorqueue->updateEsperaSupervisorQueue($queue->fila, $queue->param1);
}
$this->supervisorqueue->commit();
return true;
} catch (Exception $ex) {
$this->supervisorqueue->rollback();
logger()->error($ex->getMessage());
}
$this->supervisorqueue->rollback();
return false;
}
public function generateProtocol($uniqueid)
{
/*
* Função retorna numero de Protocolo de Atendimento para o agente
*/
$tentativa = 0;
while (true) {
$proto = $this->geraProtocolo($uniqueid);
if ($proto == '99') {
$proto = '0000-000000';
break;
}
if (!empty($proto) || $tentativa >= CONF_PROTOCOL_TENTATIVAS_GERAR) {
break;
}
$tentativa++;
}
return $proto;
}
private function geraProtocolo($uniqueid, $protocoloParceiro = '')
{
try {
$this->protocol->begin();
$param = $this->parametros->findProtocolByParams($uniqueid);
$useProtocolo = $param->prm_agente_proto;
$useProtoParceiro = $param->prm_use_proto_parceiro;
if (!$useProtocolo) {
return '99';
}
$numProto = $this->protocol->findProtocol($uniqueid);
if ($numProto) {
$numProto = $numProto->protocolo;
$numProtoParceiro = trim($numProto->protoparceiro);
if ($useProtoParceiro && $numProtoParceiro) {
return $numProtoParceiro;
}
return $numProto->protocolo;
}
$protoParceiro = $useProtoParceiro ? trim($protocoloParceiro) : '';
$year = date('Y');
$result = $this->protocol->findMaxProtocol($year);
if ($result) {
$numProto = $result->protocolo;
$numProto = $numProto ? $numProto + 1 : 1;
$proto = $year . str_pad($numProto, 6, '0', STR_PAD_LEFT);
$protoAgt = $year . '-' . str_pad($numProto, 6, '0', STR_PAD_LEFT);
$protoParceiro = $protoParceiro && $useProtoParceiro ? $protoParceiro : 'null';
$this->protocol->insert($uniqueid, $year, $numProto, $proto, 'null');
return $protoParceiro !== 'null' ? $protoParceiro : $protoAgt;
}
$this->protocol->commit();
} catch (Exception $ex) {
$this->protocol->rollback();
logger()->error($ex->getMessage());
}
return false;
}
}

149
app/Controllers/ClassificacaoController.php

@ -0,0 +1,149 @@
<?php
namespace app\Controllers;
use app\Core\Controller;
use app\Models\EventQueue;
use app\Models\Agent;
use app\Models\Bilhete;
use app\Models\Classificacao;
use Exception;
class ClassificacaoController extends Controller
{
private $agent;
private $eventqueue;
private $classificacao;
public function __construct()
{
$this->agent = new Agent();
$this->eventqueue = new EventQueue();
$this->classificacao = new Classificacao();
}
public function classificacaoList($queue)
{
try {
$classificacao = $this->classificacao->findClassificacaoByQueue($queue);
return $classificacao;
} catch (Exception $ex) {
$this->message($ex->getMessage());
}
return false;
}
public function classificacaoRegister($matricula, $clas_id, $clit_id, $id_bilhetes, $id_dac)
{
try {
$this->classificacao->begin();
$this->classificacao->addClassificacaoReg($matricula, $clas_id, $clit_id, $id_bilhetes, $id_dac);
$agentData = $this->agent->findAgentByMatricula($matricula);
$this->agent->updateAgent($matricula, $agentData->ramal, CONF_AGENT_STATUS_LIVRE, null, null, 1, null, 1);
$this->classificacao->commit();
return true;
} catch (Exception $ex) {
$this->classificacao->rollback();
$this->message($ex->getMessage());
}
return false;
}
public function classificacaoRegList($uniqueid)
{
try {
$classificacaoReg = $this->classificacao->findClassificacaoRegByUniqueid($uniqueid);
return $classificacaoReg;
} catch (Exception $ex) {
$this->message($ex->getMessage());
}
return false;
}
/*
* Listar classificacoes disponiveis
*/
public function agentClassificacaoList($queue)
{
try {
$classificacaoLista = $this->classificacaoList($queue);
if ($classificacaoLista) {
$strmsg = "Informe o número da classificação para o atendimento: \n";
$count = 1;
foreach ($classificacaoLista as $classificacao) {
$strmsg .= "{$count}. *{$classificacao->clas_descricao}* - _{$classificacao->clit_descricao}_ \n";
$count++;
}
$this->message($strmsg);
return $strmsg;
}
return false;
} catch (Exception $ex) {
$this->message($ex->getMessage());
}
return false;
}
/*
* Registrar uma classificacao
*/
public function agentClassificacaoRegister($matricula, $queue, $uniqueid, $option)
{
try {
$classificacaoLista = $this->classificacaoList($queue);
if ($classificacaoLista) {
$count = 1;
foreach ($classificacaoLista as $classificacao) {
if ($option == $count || $option == $classificacao->clas_descricao . '-' . $classificacao->clit_descricao) {
$registro = $this->classificacaoRegister($matricula, $classificacao->clas_id, $classificacao->clit_id, $uniqueid, $classificacao->id_dac);
if (!$registro) {
throw new Exception("Não foi possível classificar o atendimento. " . $this->message());
}
$this->message("Atendimento classificado com sucesso!");
return true;
}
$count++;
}
throw new Exception("Informe uma classificação válida!");
}
return true;
} catch (Exception $ex) {
$this->classificacao->rollback();
$this->message($ex->getMessage());
}
return false;
}
/**
* Verificar se o agente esta pendente de classificacao
* @return string uniqueid
*/
public function agentClassificacaoPending($matricula, $queue)
{
$pendenteClassificacao = null;
$classificacaoLista = $this->classificacaoList($queue); //SE NAO EXISTIR CLASSIFICACAO NAO PRECISA CLASSIFICAR
if ($classificacaoLista) {
$eventQueue = $this->eventqueue->findEventQueueByAgent($matricula, $queue);
$uniqueid = null;
if ($eventQueue) {
$uniqueid = $eventQueue->uid2;
$classificacaoReg = $this->classificacao->findClassificacaoRegByUniqueid($uniqueid);
if (!$classificacaoReg) {
$pendenteClassificacao = $uniqueid;
}
}
}
return $pendenteClassificacao;
}
}

45
app/Controllers/ClientController.php

@ -0,0 +1,45 @@
<?php
namespace app\Controllers;
use app\Core\Controller;
use app\Controllers\BilheteController;
/**
* Description of ClientController
*
* @author root
*/
class ClientController extends Controller
{
public function getClientQueueData($number)
{
$bilheteController = new BilheteController();
$atendimentoFila = $bilheteController->bilheteForaHorario(CONF_EVENT_WHATSAPP_ESPERA);
$clientInQueue = false;
$queuePosition = 0;
$clientQueue = '';
foreach ($atendimentoFila as $clientes) {
if ($clientes->src == $number) {
$clientInQueue = true;
$clientQueue = $clientes->fila;
break;
}
}
$queueClientData = array_filter($atendimentoFila, function ($data) use ($clientQueue) {
return $data->fila == $clientQueue;
});
foreach ($queueClientData as $clientes) {
$queuePosition += 1;
if ($clientes->src == $number) {
break;
}
}
return ["IN_QUEUE" => $clientInQueue, "QUEUE_POSITION" => $queuePosition, "CLIENT_QUEUE" => $clientQueue];
}
}

55
app/Controllers/MessageController.php

@ -0,0 +1,55 @@
<?php
namespace app\Controllers;
use app\Core\Controller;
use app\Models\Message;
use Exception;
/**
* Description of MessageController
*
* @author root
*/
class MessageController extends Controller
{
private $message;
public function __construct()
{
$this->message = new Message();
}
/**
* Calcula o timeout para o encerramento da chamada
* @param type $matricula
* @param type $ramal
* @param type $timer
* @return boolean
*/
public function timeoutTalk($uniqueid, $ramal)
{
try {
$message = $this->message->findLastMessage($uniqueid);
if ($message->src != $ramal) {
return null;
}
if (strtotime($message->msg_date . '+' . CONF_WHATSAPP_TIMEOUT_CLIENT_RESPOSTA . ' seconds') < time()) {
return "FINISH";
}
$timealert = strtotime($message->msg_date . '+' . (CONF_WHATSAPP_TIMEOUT_CLIENT_RESPOSTA - 60) . ' seconds');
if ($timealert < strtotime(date('Y-m-d H:i:s'))) {
return "ALERT";
}
return false;
} catch (Exception $ex) {
$this->message->rollback();
$this->message($ex->getMessage());
logger()->error($ex->getMessage());
}
return false;
}
}

185
app/Controllers/QueueController.php

@ -0,0 +1,185 @@
<?php
namespace app\Controllers;
use app\Core\Controller;
use app\Models\Queue;
use app\Models\Agent;
use app\Models\Bilhete;
use app\Controllers\ClientController;
use app\Core\Commands;
use Exception;
/**
* ringall -> 'Simultaneo'
* leastrecent -> 'Tempo Livre'
* fewesrcalls -> 'Numero de Atendimento'
* random -> 'Randomico'
* rrordered -> 'Sequencial'
*/
/**
* Description of QueueController
*
* @author Lucas Awade
*/
class QueueController extends Controller
{
private $queue;
private $agent;
private $bilhete;
private $commands;
public function __construct()
{
$this->queue = new Queue();
$this->agent = new Agent();
$this->bilhete = new Bilhete();
}
public function strategy($queue)
{
$search = $this->queue->findQueueByName($queue);
$strategy = $search->strategy;
if (method_exists(__CLASS__, $strategy)) {
return $this->$strategy($queue);
}
return false;
}
public function listAllQueueWhatsApp($option = null)
{
try {
$response = ['QUEUE' => '', 'LIST' => ''];
$search = $this->queue->findAllQueue();
$strmsg = "Informe o numero do setor para o atendimento: \n";
$count = 1;
foreach ($search as $q) {
if ($option == $count || $option == $q->nome) {
$response['QUEUE'] = $q->nome;
return $response;
}
$strmsg .= "{$count}. *{$q->nome}* \n";
$count++;
}
$response['LIST'] = $strmsg;
return $response;
} catch (Exception $ex) {
logger()->error($ex->getMessage());
}
return false;
}
public function listaAllFilas()
{
return $this->queue->findAllQueue();
}
public function clientQueueVerify($number)
{
$client = new ClientController();
$clienteFila = $client->getClientQueueData($number);
$clienteEmFila = $clienteFila['IN_QUEUE'];
$posicaoFila = $clienteFila['QUEUE_POSITION'];
if ($clienteEmFila) {
$msg = 'Você está na posição ' . $posicaoFila . ' da fila ' . $clienteFila['CLIENT_QUEUE'] . '. Aguarde ser atendido!';
$response['MESSAGE'] = $msg;
return $response;
}
return false;
}
/**
* Busca todos os agentes conectados em uma determinada fila.
* @param type $queue
* @return type
*/
private function ringall($queue)
{
$agents = $this->agent->findAgentByQueue($queue, CONF_AGENT_STATUS_LIVRE);
if (!$agents) {
return null;
}
$data = array();
foreach ($agents as $agent) {
$data[] = $agent->ramal;
}
return $data;
}
/**
* Busca o agente com o menor tempo de atendimento.
*/
private function leastrecent($queue)
{
$agents = $this->agent->findAgentByQueue($queue, CONF_AGENT_STATUS_LIVRE);
if (!$agents) {
return null;
}
$timer = ['RAMAL' => '', 'TIMER' => (9999999 * 9999999)];
foreach ($agents as $agent) {
$livre = strtotime('1970-01-01 ' . $agent->tempo_livre . 'UTC');
if ($livre < $timer['TIMER']) {
$timer['RAMAL'] = $agent->ramal;
$timer['TIMER'] = $livre;
}
}
return $timer['RAMAL'];
}
private function fewestcalls($queue)
{
$agents = $this->agent->findAgentByQueue($queue, CONF_AGENT_STATUS_LIVRE);
if (!$agents) {
return null;
}
$atendimentos = ['RAMAL' => '', 'ATENDIMENTOS' => (9999999 * 9999999)];
foreach ($agents as $agent) {
if ($agent->atendimentos <= $atendimentos['ATENDIMENTOS']) {
$atendimentos['RAMAL'] = $agent->ramal;
$atendimentos['ATENDIMENTOS'] = $agent->atendimentos;
}
}
return $atendimentos['RAMAL'];
}
private function random($queue)
{
$agents = $this->agent->findAgentByQueue($queue);
if (!$agents) {
return null;
}
$rand = rand(0, (count($agents) - 1));
return $agents[$rand]->ramal;
}
/** Busca o ultima matricula que foi atendida e pega a maior */
private function rrordered($queue, $media)
{
$calls = $this->bilhete->findBilheteByEventosDacs($queue, 'now', ['COMPLETEAGENT', 'COMPLETECALLER', 'COMPLETAAGENT', 'COMPLETACALLER', 'ABANDON', 'ATENDIDA'], null, $media);
$atendimento = end($calls);
$agents = $this->agent->findAgentByQueue($queue, CONF_AGENT_STATUS_LIVRE, 'matricula', 'DESC');
if (!$agents) {
return null;
}
if (!$calls) {
return $agents[0]->ramal;
}
foreach ($agents as $agent) {
if ($atendimento->agente > $agent->matricula) {
return $agent->ramal;
}
}
return $agents[0]->ramal;
}
}

53
app/Controllers/SupervisorQueueController.php

@ -0,0 +1,53 @@
<?php
namespace app\Controllers;
use app\Core\Controller;
use app\Models\Queue;
use app\Models\EventQueue;
use app\Models\SupervisorQueue;
use Exception;
/**
* Description of SupervisorController
*
* @author root
*/
class SupervisorQueueController extends Controller
{
private $queue;
private $eventqueue;
private $supervisorqueue;
public function __construct()
{
$this->queue = new Queue();
$this->eventqueue = new EventQueue();
$this->supervisorqueue = new SupervisorQueue();
}
public function calcTimeAwait()
{
try {
$this->supervisorqueue->begin();
$queue = $this->queue->findAllQueue();
foreach ($queue as $q) {
$timewait = 0;
$count = 0;
$waits = $this->eventqueue->findAllEventByAwait($q->nome);
foreach ($waits as $w) {
$timewait += time() - $w->uid1;
$count++;
}
$this->supervisorqueue->updateEsperaByQueue($q->nome, $timewait, $count);
}
$this->supervisorqueue->commit();
return true;
} catch (Exception $ex) {
$this->supervisorqueue->rollback();
logger()->error($ex->getMessage());
}
return false;
}
}

350
app/Core/Commands.php

@ -0,0 +1,350 @@
<?php
namespace app\Core;
use app\Controllers\AgentController;
use app\Controllers\BilheteController;
/**
*
* @author Lucas Awade
*/
class Commands
{
/*
* Permissoes
* 0 - CLIENTE & AGENTE
* 1 - AGENTE
*/
const PERMISSION = "PERMISSION";
const DESCRIPTION = "DESCRIPTION";
private $personType;
private $callback;
private $bilheteController;
private $agente;
static $instance;
public $commandsConfig = array();
public function __construct()
{
$this->agente = new AgentController();
$this->bilheteController = new BilheteController();
$this->commandsConfig = [
//"LOGIN" => [self::PERMISSION => 1, self::DESCRIPTION => "Realizar login no sistema, informando a fila e o usu�rio."],
"ENTRAR" => [
self::PERMISSION => ["MIN" => 1, "MAX" => 1],
self::DESCRIPTION => "Realizar login no sistema, informando a fila e o usuário."
],
//"LOGOFF" => [self::PERMISSION => 1, self::DESCRIPTION => "Desconcetar do sistema, digitar o comando logoff. Ex. /logoff."],
"SAIR" => [
self::PERMISSION => ["MIN" => 1, "MAX" => 1],
self::DESCRIPTION => "Desconectar do sistema."
],
"PAUSA" => [
self::PERMISSION => ["MIN" => 1, "MAX" => 1],
self::DESCRIPTION => "Entrar em pausa, passar o nome da pausa."
],
"SAIRPAUSA" => [
self::PERMISSION => ["MIN" => 1, "MAX" => 1],
self::DESCRIPTION => "Finaliza o tempo em pausa."
],
"TRANSFERIR" => [
self::PERMISSION => ["MIN" => 1, "MAX" => 1],
self::DESCRIPTION => "Transferir o atendimento para outro atendente passando o ramal."
],
//"ENCERRAR" => [self::PERMISSION => 0, self::DESCRIPTION => "Encerrar o atendimento, digitar o comando encerrar. Ex. /encerrar"],
"STATUS" => [
self::PERMISSION => ["MIN" => 1, "MAX" => 1],
self::DESCRIPTION => "Verificar o status dos agente, digitar o comando status."
],
"PRESENTE" => [
self::PERMISSION => ["MIN" => 1, "MAX" => 1],
self::DESCRIPTION => "Atuliza informações do atendente."
],
"COMANDOS" => [
self::PERMISSION => ["MIN" => 0, "MAX" => 1],
self::DESCRIPTION => "Listar comandos disponíveis."
],
"CANCELAR" => [
self::PERMISSION => ["MIN" => 0, "MAX" => 0],
self::DESCRIPTION => "Cancelar posição na fila de atendimento."
],
"FINALIZAR" => [
self::PERMISSION => ["MIN" => 0, "MAX" => 1],
self::DESCRIPTION => "Encerrar o atendimento."
]
];
}
private function permission($method)
{
return $this->commandsConfig[strtoupper($method)][self::PERMISSION] ? $this->commandsConfig[strtoupper($method)][self::PERMISSION] : ["MIX" => 0, "MAX" => 1];
}
/*
* Verificar se é um comando valido
* @param string $phone
* @param string $message
*
* return string
*/
public function isCommand($phone, $message, $type, $media)
{
$this->personType = $this->agente->isAgent($phone);
$messageParams = explode(" ", $message);
$command = $messageParams[0];
switch (strtoupper($command)) {
case '/ENTRAR':
case '/E':
return $this->entrar($phone, trim($messageParams[1]), trim($messageParams[2]), $media);
case '/SAIR':
return $this->sair($phone);
case '/PAUSA':
case '/P':
return $this->pausa($phone, trim($messageParams[1]));
case '/SAIRPAUSA':
return $this->sairPausa($phone);
case '/FINALIZAR':
return $this->finalizar($phone, $media);
case '/TRANSFERIR':
case '/T':
return $this->transferir($phone, trim($messageParams[1]));
case '/PRESENTE':
return $this->presente($phone);
case '/STATUS':
return $this->status($media);
case '/COMANDOS':
return $this->comandos();
case '/CANCELAR':
return $this->cancelar($phone);
default:
$this->callback = CONF_NAME_REPONSE . " : Comando não existente!";
return "NONE";
}
}
private function pausa($ramal, $pause)
{
if ($this->isPermitted($this->personType, $this->permission(__FUNCTION__))) {
$response = $this->agente->enterPause($ramal, $pause);
if ($response) {
$this->callback = CONF_NAME_REPONSE . " : Agente foi adicionado em pausa!";
return true;
} else {
if ($this->agente->message() == 'Pausa não encontrada!') {
return 'PAUSA';
}
$this->callback = CONF_NAME_REPONSE . " : Não foi possível adicionar a pausa! " . $this->agente->message() . "\n";
return false;
}
} else {
$this->callback = CONF_NAME_REPONSE . " : Comando não permitido!";
return false;
}
}
private function entrar($ramal, $queue, $login, $media)
{
if ($this->isPermitted($this->personType, $this->permission(__FUNCTION__))) {
$response = $this->agente->login($ramal, $login, $queue, $media);
if ($response) {
$this->callback = CONF_NAME_REPONSE . " : Login realizado com sucesso!\n";
$this->callback .= "Você se conectou na fila *{$queue}*.";
return true;
} else {
if ($this->agente->message() == 'Fila não encontrada ou não relacionada como WhatsApp!') {
return 'ENTRAR';
}
$this->callback = CONF_NAME_REPONSE . " : Não foi possível realizado o login! " . $this->agente->message();
return false;
}
} else {
$this->callback = CONF_NAME_REPONSE . " : Comando não permitido!";
return false;
}
}
private function sair($ramal)
{
if ($this->isPermitted($this->personType, $this->permission(__FUNCTION__))) {
$response = $this->agente->logoff($ramal);
if ($response) {
$this->callback = CONF_NAME_REPONSE . " : Logoff realizado com sucesso!";
return true;
} else {
$this->callback = CONF_NAME_REPONSE . " : Não foi possível realizado o logoff! " . $this->agente->message();
return false;
}
} else {
$this->callback = CONF_NAME_REPONSE . " : Comando não permitido!";
return false;
}
}
private function sairPausa($ramal)
{
if ($this->isPermitted($this->personType, $this->permission(__FUNCTION__))) {
$response = $this->agente->exitPause($ramal);
if ($response) {
$this->callback = CONF_NAME_REPONSE . " : Agente foi removido em pausa!";
return true;
} else {
$this->callback = CONF_NAME_REPONSE . " : Não foi possível remover de pausa! " . $this->agente->message();
return false;
}
} else {
$this->callback = CONF_NAME_REPONSE . " : Comando não permitido!";
return false;
}
}
private function transferir($ramal, $traferir)
{
if ($this->isPermitted($this->personType, $this->permission(__FUNCTION__))) {
$response = $this->agente->transfer($ramal, $traferir);
if ($response) {
$this->callback = CONF_NAME_REPONSE . " : Atendimento foi transferido!";
return $response;
} else {
if ('Agente indisponível para atendimento!' === $this->agente->message()) {
return 'TRANSFERIR';
}
$this->callback = CONF_NAME_REPONSE . " : Não foi possível transferir seu atendimento! " . $this->agente->message();
return false;
}
} else {
$this->callback = CONF_NAME_REPONSE . " : Comando não permitido!";
return false;
}
}
private function status($sala)
{
if ($this->isPermitted($this->personType, $this->permission(__FUNCTION__))) {
$response = $this->agente->infoAgentes($sala);
if ($response) {
$agentesStatus = '';
foreach ($response as $agente) {
$agentesStatus .= "Nome: " . $agente->nome . " Ramal: " . $agente->ramal . " Status: " . $agente->status . " Fila: " . $agente->dac . "\n\n";
}
$this->callback = $agentesStatus;
return true;
} else {
$this->callback = CONF_NAME_REPONSE . " : Não foi possível listar os status! " . $this->agente->message();
return false;
}
} else {
$this->callback = CONF_NAME_REPONSE . " : Comando não permitido!";
return false;
}
}
private function finalizar($numero, $media)
{
if ($this->isPermitted($this->personType, $this->permission(__FUNCTION__))) {
$service = $this->agente->closeService($numero, null, $media);
if ($service) {
$this->callback = CONF_NAME_REPONSE . " : Atendimento finalizado!";
return $service;
} else {
$this->callback = CONF_NAME_REPONSE . " : Não foi possível finalizar o atendimento!";
return false;
}
} else {
$this->callback = CONF_NAME_REPONSE . " : Comando não permitido!";
return false;
}
}
private function presente($ramal)
{
if ($this->isPermitted($this->personType, $this->permission(__FUNCTION__))) {
$refresh = $this->agente->agentVerify($ramal);
if ($refresh) {
$this->callback = CONF_NAME_REPONSE . " : Agente presente!";
return true;
} else {
$this->callback = CONF_NAME_REPONSE . " : Não foi possível confirmar presença!";
return false;
}
} else {
$this->callback = CONF_NAME_REPONSE . " : Comando não permitido!";
return false;
}
}
private function comandos()
{
if ($this->isPermitted($this->personType, $this->permission(__FUNCTION__))) {
$commands = $this->listCommands();
if ($commands) {
return 'COMANDOS';
} else {
$this->callback = CONF_NAME_REPONSE . " : Não foi possível listar os comandos!";
return false;
}
} else {
$this->callback = CONF_NAME_REPONSE . " : Comando não permitido!";
return false;
}
}
private function cancelar($ramal)
{
if ($this->isPermitted($this->personType, $this->permission(__FUNCTION__))) {
$bilheteCancelado = $this->bilheteController->cancelarBilheteForaHorario($ramal);
if ($bilheteCancelado) {
$this->callback = CONF_NAME_REPONSE . " : Cancelado o atendimento!";
return true;
} else {
$this->callback = CONF_NAME_REPONSE . " : Não foi possível cancelar o atendimento! " . $this->bilheteController->message();
return false;
}
} else {
$this->callback = CONF_NAME_REPONSE . " : Comando não permitido!";
return false;
}
}
function getCallback()
{
return $this->callback;
}
public function listCommands($validPersonType = false)
{
$commands = array();
$commandsConfig = $this->commandsConfig;
if ($validPersonType) {
$commandsConfig = array_filter($commandsConfig, function ($permisson) {
return $this->isPermitted($this->personType, $permisson[self::PERMISSION]);
});
}
foreach ($commandsConfig as $command => $config) {
$commandFormated = "/" . strtolower($command);
array_push($commands, ['title' => substr($commandFormated, 0, 23), 'sub' => $config[self::DESCRIPTION]]);
}
return $commands;
}
public function isPermitted($personType, $permisson)
{
return (($personType >= $permisson["MIN"]) && ($personType <= $permisson["MAX"]));
}
public function listaPausas()
{
$pausas = $this->agente->listaPausas();
$listaPausas = [];
foreach ($pausas as $key => $value) {
$value->motivo = strtolower($value->motivo);
array_push($listaPausas, ['title' => ucfirst(substr($value->motivo, 0, 23)), 'sub' => "/P {$value->motivo}"]);
}
return $listaPausas;
}
}

81
app/Core/Connect.php

@ -0,0 +1,81 @@
<?php
namespace app\Core;
use PDO;
use PDOException;
/**
* Classe de Conexao com banco de dados.
*
* - Criar uma conexao de forma mais r<EFBFBD>pida.
* - Gerar logs da conexao.
* - Fazer consultas mais r<EFBFBD>pidas.
*
* @author Lucas Awade
*/
class Connect
{
/** @conexao */
private static $instance;
const FILE_DB = __DIR__ . "/../../bd";
public static function setInstance($val)
{
self::$instance = $val;
}
public static function getInstance()
{
$credentials = [];
if (empty(self::$instance)) {
if (CONF_DB_DRIVER && CONF_DB_HOST && CONF_DB_BASE && CONF_DB_PORT && CONF_DB_USER && CONF_DB_PASSWD) {
$credentials['host_db'] = CONF_DB_HOST;
$credentials['porta_db'] = CONF_DB_PORT;
$credentials['usuario'] = CONF_DB_USER;
$credentials['senha'] = CONF_DB_PASSWD;
$credentials['base_db'] = CONF_DB_BASE;
} else {
$credentials = self::filedb();
}
self::$instance = new PDO(
CONF_DB_DRIVER .
":host=" . $credentials['host_db'] .
";port=" . $credentials['porta_db'] .
";dbname=" . $credentials['base_db'],
$credentials['usuario'],
$credentials['senha'],
[
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_OBJ,
PDO::ATTR_CASE => PDO::CASE_NATURAL
]
);
}
if (self::$instance) {
return self::$instance;
}
return null;
}
/**
* Pega as informacoes das credenciais no arquivos padrao "bd";
*/
private static function filedb()
{
if (file_exists(self::FILE_DB)) {
$credentials = array();
$contents = fopen(self::FILE_DB, 'r');
while (!feof($contents) && $contents) {
$str = fgets($contents);
$dados = explode('=', $str);
$credentials[strtolower($dados[0])] = trim(str_replace('"', '', $dados[1]));
}
fclose($contents);
$credentials = array_filter($credentials);
return $credentials;
}
}
}

23
app/Core/Controller.php

@ -0,0 +1,23 @@
<?php
namespace app\Core;
use app\Providers\Logger;
/**
* Description of Controller
*
* @author Lucas Awade
*/
abstract class Controller {
const LOGGER_ACTIVE = true;
private $message;
public function message($message = null){
if(!$message){
return $this->message;
}
$this->message = $message;
}
}

267
app/Core/CoreMedia.php

@ -0,0 +1,267 @@
<?php
namespace app\Core;
use app\Core\Commands;
use app\Core\Media;
use app\Models\Message;
use app\Providers\Crypt;
use app\Controllers\QueueController;
use app\Controllers\AgentController;
use app\Models\ListaNegraPalavras;
use app\Models\Ramal;
/**
* Description of WhatsApp
*
* @author Lucas Awade
*/
class CoreMedia
{
private $api;
private $crypt;
private $file;
private $host;
private $request;
private $commands;
private $media;
private $queue;
private $agente;
private $palavroes;
public function __construct()
{
$this->media = new Media();
$this->queue = new QueueController();
$this->commands = new Commands();
$this->agente = new AgentController();
$this->crypt = new Crypt();
$this->message = new Message();
$this->palavroes = new ListaNegraPalavras();
}
/**
* Send the file to the active contact
*
* @return null
*/
public function inicia($data, $api)
{
/** Validate $data */
if (!$this->build($data)) {
return false;
}
$this->media->media = $api->channel;
$this->api = $api;
$this->api->setHook($this->request);
if ($this->file) {
$file = $this->api->baixarMidia($this->file);
return $file;
}
/**
* VERIFICA SE N?O MENSAGEM DO POSITUS DE CONFIRMA??O
*/
if (!$this->api->getIsValidMessage()) {
return null;
}
/**
* VERIFICA SE ? UM COMANDO
*/
$command = $this->commands->isCommand($this->api->getPhone(), $this->api->getMessage(), $this->api->getType(), $this->api->channel);
if ((str_split($this->api->getMessage())[0] == '/') && ($command == "NONE")) {
$this->api->enviarMsg($this->api->getPhone(), utf8_encode($this->commands->getCallback()));
return null;
}
switch ($command) {
case 'COMANDOS':
$this->enviaLista($this->commands->listCommands(true), $this->api, $this->api->getPhone(), 'Comandos', 'C');
break;
case 'PAUSA':
$this->enviaLista($this->commands->listaPausas(), $this->api, $this->api->getPhone(), 'Pausas', 'P');
break;
case 'ENTRAR':
$this->enviaLista($this->listaFilas(), $this->api, $this->api->getPhone(), "Filas", 'P');
break;
case 'TRANSFERIR':
$agentes = $this->listaAgentesDisponivel();
if ($agentes) {
$this->enviaLista($agentes, $this->api, $this->api->getPhone(), "Transferência", 'P');
} else {
$this->api->enviarMsg($this->api->getPhone(), utf8_encode("Nenhum agente disponível para transferência."));
}
break;
default:
break;
}
if ($command !== "NONE") {
if (is_array($command)) {
foreach ($command as $val) {
$this->api->enviarMsg($val, utf8_encode($this->commands->getCallback()));
}
} else {
$this->api->enviarMsg($this->api->getPhone(), utf8_encode($this->commands->getCallback()));
}
return null;
}
$isTalk = $this->agente->inService($this->api->getPhone());
if (!$isTalk && !$this->agente->isAgent($this->api->getPhone())) {
$clientfila = $this->queue->clientQueueVerify($this->api->getPhone());
if ($clientfila['MESSAGE']) {
$this->api->enviarMsg($this->api->getPhone(), utf8_encode($clientfila['MESSAGE']));
return null;
}
$filas = $this->queue->listAllQueueWhatsApp($this->api->getMessage());
if ($filas['LIST']) {
$this->api->enviarMsg($this->api->getPhone(), utf8_encode($filas['LIST']));
return null;
}
}
/**
* VALIDA O ATENDIMENTO
*/
$this->validaAtendimento($this->api, $filas['QUEUE'], $data, $this->api->getPhone(), $this->api->channel);
}
/**
* Set variables class
* @param array $data
* @return boolean
*/
public function build($data)
{
$this->file = $data['DOWNLOAD']["FILE"];
if ($data['REQUEST']['chat']['type'] == 'group' || $data['REQUEST']['from']['is_bot'] != '') {
return false;
}
if ($data['HOST'] && $data['REQUEST']) {
$this->host = $data['HOST'];
$this->request = $data['REQUEST'];
$this->validaPalavroes();
return true;
} else if ($this->file) {
return true;
}
return false;
}
public function validaPalavroes()
{
try {
if ($this->request['text']) {
$msg = $this->request['text'];
} else {
$msg = $this->request['messages'][0]['text']['body'];
}
$palavras = $this->palavroes->getAll();
foreach ($palavras as $key => $value) {
$pattern = "/\b($value->palavra)\b/i";
$msg = preg_replace($pattern, '*' . str_repeat('*', strlen($value->palavra)) . '*', $msg);
}
if ($this->request['text']) {
$this->request['text'] = $msg;
} else {
$this->request['messages'][0]['text']['body'] = $msg;
}
} catch (\Throwable $th) {
logger('telegram')->info(print_r($th, true), true);
}
return;
}
public function validaAtendimento($api, $fila, $data, $numero, $media)
{
$response = $this->media->selecionaAtendimento($numero, $fila, $api->getMessage(), $media);
if (!$response['STATUS']) {
$api->enviarMsg($numero, utf8_encode($response['MESSAGE']));
return null;
}
if ($response['MESSAGE']) {
$api->enviarMsg($numero, utf8_encode($response['MESSAGE']));
$this->enviaLista($this->commands->listCommands(true), $api, $numero, 'Comandos', 'C');
$api->enviarMsg($numero, utf8_encode("O tempo de ociosidade é de " . ($api->timeout_client_resposta / 60) . " minutos, após esse tempo o atendimento será encerrado!"));
$api->enviarMsg($numero, utf8_encode("{$response['DATA']['apelido']}: Olá tudo bem? Como posso lhe ajudar?"));
$api->enviarMsg($response['DATA']['ramal'], utf8_encode($response['MESSAGE']));
$api->enviarMsg($response['DATA']['ramal'], utf8_encode("Novo atendimento, pelo número *{$numero}*!"));
return;
}
switch ($api->getType()) {
case 'text':
$api->enviarMsg($response['DATA']['ramal'], "{$api->getProfile()}: " . $api->getMessage());
$this->message->addMessage($response['DATA']['uniqueid'], $numero, $response['DATA']['ramal'], $api->getType(), $this->crypt->encrypt($api->getMessage()), $api->getProfile());
return null;
case 'image':
$api->enviaImagem($response['DATA']['ramal'], $api->getLinkDownload($this->host));
$this->message->addMessage($response['DATA']['uniqueid'], $numero, $response['DATA']['ramal'], $api->getType(), $this->crypt->encrypt($api->getLinkDownload($this->host)), $api->getProfile());
return null;
case 'sticker':
$api->enviaSticker($response['DATA']['ramal'], $api->getLinkDownload($this->host));
$this->message->addMessage($response['DATA']['uniqueid'], $numero, $response['DATA']['ramal'], $api->getType(), $this->crypt->encrypt($api->getLinkDownload($this->host)), $api->getProfile());
return null;
case 'video':
$api->enviaVideo($response['DATA']['ramal'], $api->getLinkDownload($this->host));
$this->message->addMessage($response['DATA']['uniqueid'], $numero, $response['DATA']['ramal'], $api->getType(), $this->crypt->encrypt($api->getLinkDownload($this->host)), $api->getProfile());
return null;
case 'voice':
case 'audio':
$api->enviaAudio($response['DATA']['ramal'], $api->getLinkDownload($this->host));
$this->message->addMessage($response['DATA']['uniqueid'], $numero, $response['DATA']['ramal'], $api->getType(), $this->crypt->encrypt($api->getLinkDownload($this->host)), $api->getProfile());
return null;
case 'document':
$api->enviaDocumento($response['DATA']['ramal'], $api->getLinkDownload($this->host), $api->retornaTituloDocument($data));
$this->message->addMessage($response['DATA']['uniqueid'], $numero, $response['DATA']['ramal'], $api->getType(), $this->crypt->encrypt($api->getLinkDownload($this->host)), $api->getProfile());
return null;
case 'contacts':
$api->enviarContato($response['DATA']['ramal'], $api->getContactFormatted(), $api->getContactPhone());
$this->message->addMessage($response['DATA']['uniqueid'], $numero, $response['DATA']['ramal'], $api->getType(), $this->crypt->encrypt(json_encode(['contact_formatted' => "{$api->getContactFormatted()}", 'contact_phone' => "{$api->getContactPhone()}"])), $api->getProfile());
return null;
case 'location':
$api->enviarLocalizacao($response['DATA']['ramal'], $api->getGeolocation('longitude'), $api->getGeolocation('latitude'));
$this->message->addMessage($response['DATA']['uniqueid'], $numero, $response['DATA']['ramal'], $api->getType(), $this->crypt->encrypt(json_encode(['longitude' => "{$api->getGeolocation('longitude')}", 'latitude' => "{$api->getGeolocation('latitude')}"])), $api->getProfile());
return null;
}
}
private function enviaLista($listas, $api, $numero, $nome, $pre = '')
{
$api->enviarMsgIterativaLista(
$numero,
"$nome disponíveis",
"$nome",
$listas,
$pre
);
}
public function listaFilas()
{
$ramal = new Ramal();
$user = $ramal->findRamal($this->api->getPhone());
$search = $this->queue->listaAllFilas();
$listaPausas = [];
foreach ($search as $key => $value) {
$value->nome = strtolower($value->nome);
array_push($listaPausas, ['title' => substr($value->nome, 0, 23), 'sub' => "/E {$value->nome} {$user->callerid}"]);
}
return $listaPausas;
}
private function listaAgentesDisponivel()
{
$user = $this->agente->infoAgentes($this->api->channel);
$listaPausas = [];
foreach ($user as $key => $value) {
if ($value->status === 'LIVRE' && $value->ramal !== $this->api->getPhone() && $value->chamada_classificado == 1) {
$value->nome = strtolower($value->nome);
array_push($listaPausas, ['title' => substr($value->nome, 0, 23), 'sub' => "/T {$value->ramal}"]);
}
}
return $listaPausas;
}
}

174
app/Core/Media.php

@ -0,0 +1,174 @@
<?php
namespace app\Core;
use app\Core\Commands;
use app\Controllers\AgentController;
use app\Controllers\QueueController;
use app\Controllers\BilheteController;
use app\Controllers\ClassificacaoController;
/**
* Description of Media
*
* @author Lucas Awade
*/
class Media
{
private $agente;
private $queue;
private $bilheteController;
private $commands;
private $classificacao;
public $media;
public function __construct()
{
$this->bilheteController = new BilheteController();
$this->agente = new AgentController();
$this->queue = new QueueController();
$this->classificacao = new ClassificacaoController();
$this->commands = new Commands();
}
public function selecionaAtendimento($number, $queue = null, $option = null, $media)
{
$atendimento = $this->agente->inService($number);
/**
* SE POSSUI ATENDIMENTO RETORNA OS DADOS DA CHAMADA
*/
if ($atendimento->origem_destino) {
$ramal = (($atendimento->phone == 'CLIENT') ? $atendimento->ramal : $atendimento->origem_destino);
return $this->response(true, ["ramal" => $ramal, "uniqueid" => $atendimento->uniqueid], null);
}
/**
* VERIFICA SE E UM AGENTE
*/
if ($this->agente->isAgent($number)) {
return $this->validacaoDoAgente($number, $option);
}
/**
* VALIDA A ESTRATEGIA USADA NA FILA
*/
$ramal = $this->agente->priority($queue);
if (!$ramal) {
$ramal = $this->queue->strategy($queue);
}
/**
* VALIDA A O ATENDIMENTO DO CLIENTE
*/
return $this->validacaoDoCliente($number, $queue, $ramal, $media);
}
private function response($status, $data, $message)
{
return array('STATUS' => $status, 'MESSAGE' => $message, 'DATA' => $data);
}
public function getClientQueueData($number, $atendimentoFila)
{
$clientInQueue = false;
$queuePosition = 0;
$clientQueue = '';
foreach ($atendimentoFila as $clientes) {
if ($clientes->src == $number) {
$clientInQueue = true;
$clientQueue = $clientes->fila;
break;
}
}
foreach ($atendimentoFila as $clientes) {
$queuePosition = $queuePosition + 1;
if ($clientes->src == $number) {
break;
}
}
return ["IN_QUEUE" => $clientInQueue, "QUEUE_POSITION" => $queuePosition, "CLIENT_QUEUE" => $clientQueue];
}
function validacaoDoAgente($number, $option)
{
$agent = $this->agente->getAgente($number);
if (!$agent) {
$msg = "Faça o login para iniciar o atendimento!\n";
return $this->response(false, '', $msg);
}
/**
* VERIFICA CLASSIFICACAO DE ATENDIMENTO
*/
$chamadaSemClassificacao = $this->classificacao->agentClassificacaoPending($agent->matricula, $agent->dac);
if ($chamadaSemClassificacao) {
$classificacaoRegisterReturn = $this->classificacao->agentClassificacaoRegister(
$agent->matricula,
$agent->dac,
$chamadaSemClassificacao,
$option
);
if ($classificacaoRegisterReturn) {
return $this->response(false, '', CONF_NAME_REPONSE . " : " . $this->classificacao->message());
}
$classificacaoList = $this->classificacao->agentClassificacaoList($agent->dac);
return $this->response(false, '', CONF_NAME_REPONSE . " : " . $classificacaoList);
}
$msg = "Você não pode abrir um atendimento conectado!\n";
return $this->response(false, '', $msg);
}
function validacaoDoCliente($number, $queue, $ramal, $media)
{
$atendimentoFila = $this->bilheteController->bilheteForaHorario(CONF_EVENT_WHATSAPP_ESPERA, null, null, $media);
$clienteFila = $this->getClientQueueData($number, $atendimentoFila);
$clienteEmFila = $clienteFila['IN_QUEUE'];
$posicaoFila = $clienteFila['QUEUE_POSITION'];
logger('deburguer')->info(print_r(["media" => $media, "cliente" => $clienteFila, "queue" => $queue], true));
if ((!$this->agente->infoAgentes($media, $queue)) && (!$clienteEmFila)) {
$this->bilheteController->bilheteInQueue($number, '0', '0', 'NO ANSWER', $queue, CONF_EVENT_WHATSAPP_ESPERA, 'null', null, $media);
$msg = 'Não temos nenhum atendente disponível no momento, iremos lhe atender assim que um atendente estiver disponível!';
return $this->response(false, '', $msg);
}
if (($clienteEmFila) && ($clienteFila['CLIENT_QUEUE'] != $queue)) {
$msg = 'Você está na posição ' . $posicaoFila . ' da fila ' . $clienteFila['CLIENT_QUEUE'] . '. Aguarde ser atendido!';
return $this->response(false, '', $msg);
}
if ((!$this->agente->infoAgentes($media, $queue)) && ($clienteEmFila)) { //CLIENTE EM FILA MAS NENHUM ATENDENTE LOGADO
$msg = 'Não temos nenhum atendente disponível no momento, iremos lhe atender assim que um atendente estiver disponível!';
return $this->response(false, '', $msg);
}
$agent = $this->agente->getAgente($ramal);
$chamadaSemClassificacao = $this->classificacao->agentClassificacaoPending($agent->matricula, $agent->dac);
if ((!$ramal) || ($chamadaSemClassificacao)) {
if (!$clienteEmFila) {
$this->bilheteController->bilheteInQueue($number, '0', '0', 'NO ANSWER', $queue, CONF_EVENT_WHATSAPP_ESPERA, 'null', null, $media);
}
$atendimentoFila = $this->bilheteController->bilheteForaHorario(CONF_EVENT_WHATSAPP_ESPERA, $queue, null, null, $media);
$posicaoFila = count($atendimentoFila);
$msg = "Nossos atendentes estão ocupados, por favor aguarde que iremos lhe atender! Você está na posição *$posicaoFila*.";
return $this->response(false, '', $msg);
}
$uniqueid = $this->agente->openService($ramal, $number);
$protocol = $this->bilheteController->generateProtocol($uniqueid);
$this->bilheteController->tempoEsperaSupervisor($uniqueid);
$msg = "Atendimento iniciado!\n";
$msg .= "Número do protocolo do atendimento é $protocol\n";
return $this->response(true, ["ramal" => $ramal, "uniqueid" => $uniqueid, "protocol" => $protocol, "apelido" => $agent->nome], $msg);
}
}

121
app/Core/Model.php

@ -0,0 +1,121 @@
<?php
namespace app\Core;
use app\Core\Connect;
use PDO;
use PDOException;
/**
* Description of WppModel
*
* @author Lucas Awade
*/
abstract class Model
{
protected $query;
protected function strquery($stmt, $params)
{
foreach ($params as $key => $value) {
if (is_null($value) || (is_string($value) && $value == '')) {
$value = null;
}
$stmt->bindValue(":{$key}", $value, (is_int($value) ? PDO::PARAM_INT : PDO::PARAM_STR));
}
}
public function begin()
{
try {
Connect::getInstance()->beginTransaction();
return 1;
} catch (PDOException $ex) {
logger('PDOExcep')->error('PDOException: ' . $ex->getMessage(), debug_backtrace());
return null;
}
}
public function commit()
{
try {
Connect::getInstance()->commit();
return 1;
} catch (PDOException $ex) {
logger('PDOExcep')->error('PDOException: ' . $ex->getMessage(), debug_backtrace());
return null;
}
}
public function rollback()
{
try {
Connect::getInstance()->rollBack();
return 1;
} catch (PDOException $ex) {
logger('PDOExcep')->error('PDOException: ' . $ex->getMessage(), debug_backtrace());
return null;
}
}
################################################################################################
################################################################################################
################################################################################################
protected function create($query, $data)
{
try {
$stmt = Connect::getInstance()->prepare($query);
$this->strquery($stmt, $data);
$stmt->execute();
return Connect::getInstance()->lastInsertId();
} catch (PDOException $ex) {
logger('PDOExcep')->error('PDOException: ' . $ex->getMessage(), debug_backtrace());
return null;
}
}
protected function read($query, $data = null)
{
try {
$stmt = Connect::getInstance()->prepare($query);
if ($data) {
$this->strquery($stmt, $data);
}
$stmt->execute();
return $stmt;
} catch (PDOException $ex) {
Connect::setInstance(null);
logger('PDOExcep')->error('PDOException: ' . $ex->getMessage(), debug_backtrace());
return null;
}
}
protected function delete($query, $data)
{
try {
$stmt = Connect::getInstance()->prepare($query);
$this->strquery($stmt, $data);
$stmt->execute();
return ($stmt->rowCount() ? 1 : 0);
} catch (PDOException $ex) {
logger('PDOExcep')->error('PDOException: ' . $ex->getMessage(), debug_backtrace());
return null;
}
}
protected function update($query, $data)
{
try {
logger('Query')->error('Query: ' . $query, debug_backtrace());
$stmt = Connect::getInstance()->prepare($query);
$this->strquery($stmt, $data);
$stmt->execute();
return ($stmt->rowCount() ? 1 : 0);
} catch (PDOException $ex) {
logger('PDOExcep')->error('PDOException: ' . $ex->getMessage(), debug_backtrace());
return null;
}
}
}

39
app/Interfaces/IApiMedia.php

@ -0,0 +1,39 @@
<?php
namespace app\Interfaces;
interface IApiMedia
{
function enviarMsg($whatsapp, $mensagem);
function enviarMsgIterativaLista($whatsapp, $mensagem, $nomeButton, $sections);
function enviarMsgIterativaBotao($whatsapp, $mensagem, $buttons);
function enviarContato($whatsapp, $nome, $contato);
function enviarLocalizacao($whatsapp, $longitude, $latitude, $nome = null, $endereco = null);
function enviaDocumento($whatsapp, $link, $titulo = null);
function enviaImagem($whatsapp, $link, $titulo = null);
function enviaSticker($whatsapp, $link);
function enviaVideo($whatsapp, $link, $titulo = null);
function enviaAudio($whatsapp, $link);
function baixarMidia($name);
function setStorage($storage);
function getProfile();
function getPhone();
function getType();
function getMimetype();
function getId();
function getIsValidMessage();
function getMessage();
function getContactFormatted();
function getContactPhone();
function getGeolocation($type);
function setHook($hook);
function setMetodo($metodo);
function setQuery($query);
function getQuery();
function getArgs($args);
function requestType($req = null);
function exec();
function response($result);
public function getLinkDownload($host);
public function retornaTituloDocument($msg);
}

39
app/Middleware/Http.php

@ -0,0 +1,39 @@
<?php
namespace app\Middleware;
/**
* Description of Http
*
* @author Lucas Awade
*/
class Http
{
private $url;
private $param;
const CONF_PAGE = 'index.php';
public function __construct()
{
$this->baseUri();
}
public function param()
{
return $this->param;
}
public function baseUri()
{
$this->url = explode(self::CONF_PAGE, $_SERVER['PHP_SELF']);
$this->url = end($this->url);
if ($this->url) {
$this->url = explode("/", $this->url);
if (isset($this->url[0])) {
$this->param = array_filter($this->url);
}
}
}
}

145
app/Middleware/Middleware.php

@ -0,0 +1,145 @@
<?php
namespace app\Middleware;
use app\Core\CoreMedia;
use app\Core\Telegram;
use app\Middleware\Http;
use app\Providers\WebHeader;
use app\Core\WhatsApp;
use app\Providers\ApiTelegram;
use app\Providers\Positus;
/**
* Description of WppController
*
* @author Lucas Awade
*/
class Middleware extends Http
{
/** @var return Positus request */
private $request;
/** @class WebHeader */
private $header;
/** @var String local downloads image|document|video|sticker|audio */
private $link;
public function __construct($config = null)
{
$this->link = $config['LINK_UPLOAD'];
$this->header = new WebHeader($config);
$this->hook();
}
/**
* Start API headers
* @param array $config
*/
public function api()
{
$this->header->API();
}
/**
* Redirect request to Media Social
* @return null
*/
private function router()
{
$coremedia = new CoreMedia();
$this->baseUri();
// logger('telegram')->info(print_r($this->request, true), true);
$data = [
"REQUEST" => $this->request,
"HOST" => $this->getLink(),
"DOWNLOAD" => $this->download()
];
switch (strtolower($this->param()[1])) {
case 'whatsapp':
$file = $coremedia->inicia($data, new Positus());
if ($file) {
$this->download($file);
}
echo json_encode(['success' => true]);
return null;
case 'telegram':
$file = $coremedia->inicia($data, new ApiTelegram());
echo json_encode(['success' => $this->request]);
return null;
default:
$this->header->redirect();
}
}
/**
* Read input requests
*/
private function hook()
{
$this->request = file_get_contents('php://input');
$this->request = json_decode($this->request, true);
$this->router();
}
/**
* Create file and download in browser
*/
private function download($file = null)
{
if ($file) {
$this->header->fileTransfer($this->param()[3], $file, base64_decode($this->param()[4]));
exit(0);
}
if ($this->param()[3] && $this->param()[4]) {
return ["FILE" => strtolower($this->param()[3]), "MIMETYPE" => $this->param()[4]];
} else {
return null;
}
}
########################################################################
##### FUNCTION UTIL #####
########################################################################
private function formatLink()
{
$link = str_split($this->link);
if (strpos($this->link, 'http://') === false && strpos($this->link, 'http://') === false) {
$this->link = "http://" . $this->link;
}
if (end($link) != "/") {
$this->link .= "/";
}
}
########################################################################
##### FUNCTION CLASS #####
########################################################################
/**
* Set new link download
* @param string $link
*/
public function setLink($link)
{
$this->link = $link;
$this->formatLink();
}
/**
* Get link download
* @return string
*/
public function getLink()
{
$this->formatLink();
return $this->link;
}
}

228
app/Models/Agent.php

@ -0,0 +1,228 @@
<?php
namespace app\Models;
use app\Core\Connect;
use app\Core\Model;
/**
* Clase para criacao de Querys no banco de dados.
*
* Todas as querys desta classe esta especificada para o uso do WhatsApp.
*
* @author Lucas Awade
*/
class Agent extends Model
{
const USUARIOS = "pbx_usuarios";
const SUPERVISOR_AGENTE = "pbx_supervisor_agentes";
const EVENTO_AGENTE = 'pbx_eventos_agentes';
const BILHETE = 'pbx_bilhetes';
const EVENTOS_DACS = 'pbx_eventos_dacs';
public function findByNumber($number)
{
$this->query = "SELECT CASE WHEN(origem_destino = '$number') THEN 'CLIENT' ELSE 'AGENT' END AS phone, * "
. "FROM " . self::SUPERVISOR_AGENTE . " WHERE (origem_destino = :number OR ramal = :number)";
return $this->read($this->query, ['number' => $number])->fetch();
}
public function findAllAgentes($media = ['TELEGRAM', 'WHATSAPP'], $queue = null)
{
try {
$data = [];
$this->query = "SELECT * FROM " . self::SUPERVISOR_AGENTE . " WHERE 1=1 ";
$this->query .= sprintf(" AND sala_1 in(%s) ", whereIn($media));
if ($queue) {
$this->query .= " AND dac = :queue ";
$data['queue'] = $queue;
}
$ret = $this->read($this->query, $data);
if ($ret) {
return $ret->fetchAll();
} else {
return [];
}
} catch (\Throwable $th) {
Connect::setInstance(null);
logger('testeOff')->info(gettype(Connect::getInstance()), debug_backtrace());
return [];
}
}
public function findByAgent($user)
{
$this->query = "SELECT * FROM " . self::USUARIOS . " WHERE apelido = :apelido;";
return $this->read($this->query, ['apelido' => $user])->fetch();
}
public function findAgentByRamal($ramal)
{
$this->query = "SELECT * FROM " . self::SUPERVISOR_AGENTE . " WHERE ramal = :ramal;";
return $this->read($this->query, ['ramal' => $ramal])->fetch();
}
public function findAgentByMatricula($matricula)
{
$this->query = "SELECT * FROM " . self::SUPERVISOR_AGENTE . " WHERE matricula = :matricula;";
return $this->read($this->query, ['matricula' => $matricula])->fetch();
}
public function findAgentByQueue($queue, $status = 'LIVRE', $orderBy = null, $orderByType = 'ASC')
{
$data = [];
$this->query = "SELECT ramal, b.matricula, b.nome, b.apelido, penalidade, (logado - duracao) as tempo_livre,
(SELECT count(*) AS atendimentos
FROM " . self::BILHETE . " ab
INNER JOIN " . self::EVENTOS_DACS . " bc ON ab.uniqueid = bc.uid2
WHERE bc.fila = a.dac
AND bc.agente = a.matricula
AND bc.evento IN(:evento)
AND ab.data_bilhete = 'now')
FROM " . self::SUPERVISOR_AGENTE . " a
INNER JOIN " . self::USUARIOS . " b ON a.matricula = b.matricula
WHERE upper(a.dac) = upper(:queue)
AND a.status = upper(:status) ";
$data['queue'] = $queue;
$data['status'] = $status;
$data['evento'] = implode(',', [
CONF_EVENT_WHATSAPP_TIMERMINO_CLIENTE,
CONF_EVENT_WHATSAPP_TIMERMINO_AGENTE
]);
if ($orderBy && $orderByType) {
$this->query .= " ORDER BY $orderBy $orderByType;";
}
return $this->read($this->query, $data)->fetchAll();
}
########################################
### SUPERVISOR AGENTE ###
########################################
public function addAgent($matricula, $ramal, $login, $queue, $media, $chamada_classificado = 1)
{
$this->query = "INSERT INTO " . self::SUPERVISOR_AGENTE . "
(ramal, matricula, nome, tempo_login, modo_atendimento, dac, status, duracao, logado, status_time, disponivel_atendimento, sala_1, chamada_classificado)
VALUES(:ramal, :matricula, :login, :tempo_login, :modo_atendimento, :queue, :status, :duracao, :logado, :status_time, :disponivel_atendimento, :media, :chamada_classificado);";
return $this->create($this->query, [
'matricula' => $matricula,
'ramal' => $ramal,
'login' => $login,
'tempo_login' => 'now()',
'modo_atendimento' => 'Manual',
'queue' => $queue,
'status' => 'LIVRE',
'duracao' => 'now()',
'logado' => 'now()',
'status_time' => 'now()',
'disponivel_atendimento' => 1,
'media' => $media,
'chamada_classificado' => $chamada_classificado
]);
}
public function updateAgent($matricula, $ramal, $status = 'LIVRE', $origemDestino = null, $motivoPausa = null, $duracao = null, $uniqueid = null, $chamada_classificado = 1)
{
$data = [];
$this->query = "UPDATE " . self::SUPERVISOR_AGENTE . " SET logado = :logado, origem_destino = :origem_destino, status = :status, motivo_pausa = :motivo_pausa, uniqueid = :uniqueid, chamada_classificado = :chamada_classificado";
if ($duracao) {
$this->query .= ", duracao = :duracao ";
}
$this->query .= " WHERE matricula = :matricula AND ramal = :ramal;";
$data['matricula'] = $matricula;
$data['ramal'] = $ramal;
$data['logado'] = 'now()';
$data['duracao'] = 'now()';
$data['origem_destino'] = $origemDestino;
$data['status'] = $status;
$data['motivo_pausa'] = $motivoPausa;
$data['uniqueid'] = $uniqueid;
$data['chamada_classificado'] = ($chamada_classificado ? '1' : '0');
return $this->update($this->query, $data);
}
public function updateRefreshAgent($matricula, $ramal, $duracao = false)
{
$data = [];
$this->query = "UPDATE " . self::SUPERVISOR_AGENTE . " SET logado = :logado ";
if ($duracao) {
$this->query .= ", duracao = :duracao ";
$data['duracao'] = 'now()';
}
$this->query .= " WHERE matricula = :matricula AND ramal = :ramal;";
$data['logado'] = 'now()';
$data['matricula'] = $matricula;
$data['ramal'] = $ramal;
return $this->update($this->query, $data);
}
public function updateSala2Agent($matricula, $ramal, $sala2 = null)
{
$data = [];
$this->query = "UPDATE " . self::SUPERVISOR_AGENTE . " SET sala_2 = :sala_2 WHERE matricula = :matricula AND ramal = :ramal;";
$data['sala_2'] = $sala2;
$data['matricula'] = $matricula;
$data['ramal'] = $ramal;
return $this->update($this->query, $data);
}
public function deleteAgent($matricula, $ramal)
{
$data = [];
$this->query = "DELETE FROM " . self::SUPERVISOR_AGENTE . " WHERE matricula = :matricula AND ramal = :ramal;";
$data['matricula'] = $matricula;
$data['ramal'] = $ramal;
return $this->delete($this->query, $data);
}
public function updateLogadoAll($media = null)
{
$data = [];
$this->query = "UPDATE " . self::SUPERVISOR_AGENTE . " SET logado = :logado ";
if ($media) {
$this->query .= " WHERE sala_1 = :sala_1; ";
}
$data['logado'] = 'now()';
$data['sala_1'] = $media;
return $this->update($this->query, $data);
}
########################################
### EVENTOS ###
########################################
public function addEventoLoginAgent($matricula, $ramal, $idDac, $flag = 1)
{
$data = [];
$this->query = "INSERT INTO " . self::EVENTO_AGENTE . "(matricula, ramal, login, logoff, id_dac, flag) VALUES(:matricula, :ramal, :login, :logoff, :id_dac, :flag) ";
$data['matricula'] = $matricula;
$data['ramal'] = $ramal;
$data['login'] = 'now()';
$data['logoff'] = 'now()';
$data['id_dac'] = $idDac;
$data['flag'] = $flag;
return $this->create($this->query, $data);
}
public function updateEventoLogoffAgent($matricula, $ramal, $dac, $flag = 2)
{
$data = [];
$this->query = "UPDATE " . self::EVENTO_AGENTE . " SET logoff = :logoff, flag = :flag "
. "WHERE matricula = :matricula AND id_dac = :id_dac AND ramal = :ramal "
. "AND login = (SELECT MAX(login) FROM pbx_eventos_agentes WHERE matricula = :matricula AND id_dac = :id_dac AND ramal= :ramal);";
$data['logoff'] = 'now()';
$data['flag'] = $flag;
$data['matricula'] = $matricula;
$data['id_dac'] = $dac;
$data['ramal'] = $ramal;
return $this->update($this->query, $data);
}
}

103
app/Models/Bilhete.php

@ -0,0 +1,103 @@
<?php
namespace app\Models;
use app\Core\Model;
/**
* Description of Bilhete
*
* @author root
*/
class Bilhete extends Model
{
const TABLE = "pbx_bilhetes";
const EVENTOS_DACS = 'pbx_eventos_dacs';
public function addBilhete($calldate, $src, $dst, $duration, $billsec, $disposition, $unique = null, $forahorario = 0)
{
if ($unique == null) {
$unique = uniqid('', true);
}
$this->query = "INSERT INTO " . self::TABLE . " (uniqueid, calldate, src, dst, duration, billsec, disposition, fora_horario, data_bilhete) VALUES(:uniqueid, :calldate, :src, :dst, :duration, :billsec, :disposition, :fora_horario, :data_bilhete);";
$data['uniqueid'] = $unique;
$data['calldate'] = $calldate;
$data['src'] = $src;
$data['dst'] = $dst;
$data['duration'] = $duration;
$data['billsec'] = abs($billsec);
$data['disposition'] = $disposition;
$data['fora_horario'] = $forahorario;
$data['data_bilhete'] = date('Y-m-d H:i:s');
$return = $this->create($this->query, $data);
if ($return) {
return $unique;
}
return $return;
}
public function findByUniqueid($uniqueid)
{
$this->query = "SELECT * FROM " . self::TABLE . " WHERE uniqueid = :uniqueid";
return $this->read($this->query, ['uniqueid' => $uniqueid])->fetch();
}
public function findBilheteByEventosDacs($queue = null, $dataBilhete = 'now', $eventos = ['COMPLETEAGENT', 'COMPLETECALLER', 'COMPLETAAGENT', 'COMPLETACALLER', 'TRANSFER', 'ABANDON'], $agente = null, $media)
{
$this->query = "SELECT * FROM " . self::TABLE . " a
INNER JOIN " . self::EVENTOS_DACS . " b ON a.uniqueid = b.uid2
WHERE 1=1 AND evento IN(:evento) ";
$data['evento'] = is_array($eventos) ? implode(",", $eventos) : $eventos;
if ($queue) {
$this->query .= " AND b.fila = :queue ";
$data['queue'] = $queue;
}
if ($dataBilhete) {
$this->query .= " AND data_bilhete = :data_bilhete ";
$data['data_bilhete'] = $dataBilhete;
}
if ($media) {
$this->query .= " AND param2 = :param2 ";
$data['param2'] = $media;
}
if ($agente) {
$this->query .= " AND b.agente = :agente ";
$data['agente'] = $agente;
}
$this->query .= " ORDER BY calldate";
return $this->read($this->query, $data)->fetchAll();
}
public function findBilheteBySrc($src, $eventos = ['COMPLETEAGENT', 'COMPLETECALLER', 'COMPLETAAGENT', 'COMPLETACALLER', 'TRANSFER', 'ABANDON'])
{
$this->query = "SELECT * FROM " . self::TABLE . " a
INNER JOIN " . self::EVENTOS_DACS . " b ON a.uniqueid = b.uid2
WHERE 1=1 ";
$this->query .= " AND a.src = :src ";
$this->query .= " AND evento IN(:evento) ";
$this->query .= " ORDER BY calldate";
$data['src'] = $src;
$data['evento'] = is_array($eventos) ? implode(",", $eventos) : $eventos;
return $this->read($this->query, $data)->fetch();
}
public function updateBilheteForaHorario($uniqueid, $ramalorigem, $forahorario, $disposition)
{
$this->query = "UPDATE " . self::TABLE . " SET disposition = :disposition, fora_horario = :fora_horario, ramal_origem = :ramal_origem WHERE uniqueid = :uniqueid;";
$data['disposition'] = $disposition;
$data['fora_horario'] = $forahorario;
$data['ramal_origem'] = $ramalorigem;
$data['uniqueid'] = $uniqueid;
return $this->update($this->query, $data);
}
}

49
app/Models/Classificacao.php

@ -0,0 +1,49 @@
<?php
namespace app\Models;
use app\Core\Model;
/**
* Description of Classificacao
*
* @author root
*/
class Classificacao extends Model
{
const CLASSIFICACAO_ATT = "pbx_classifica_atendimento";
const CLASSIFICACAO_ITEM = "pbx_classifica_item";
const CLASSIFICACAO_DACS = "pbx_classifica_dacs";
const CLASSIFICACAO_REG = "pbx_classifica_reg";
const QUEUE_GROUPOS = "pbx_queues_grupos";
public function findClassificacaoRegByUniqueid($uniqueid)
{
$this->query = "SELECT * FROM " . self::CLASSIFICACAO_REG . " WHERE id_bilhetes = :id_bilhetes;";
return $this->read($this->query, ['id_bilhetes' => $uniqueid])->fetch();
}
public function findClassificacaoByQueue($queue)
{
$this->query = "SELECT pca.clas_descricao, pca.clas_id, pci2.clit_id, pci2.clit_descricao, pcd.id_dac FROM " . self::CLASSIFICACAO_ATT . " pca
INNER JOIN " . self::CLASSIFICACAO_ITEM . " pci2 ON pci2.clas_id = pca.clas_id
INNER JOIN " . self::CLASSIFICACAO_DACS . " pcd ON pcd.clas_id = pca.clas_id
INNER JOIN " . self::QUEUE_GROUPOS . " pqg ON pcd.id_dac = pqg.id
WHERE pqg.nome = :queue ;";
return $this->read($this->query, ['queue' => $queue])->fetchAll();
}
public function addClassificacaoReg($matricula, $clas_id, $clit_id, $id_bilhetes, $id_dac)
{
$this->query = "INSERT INTO " . self::CLASSIFICACAO_REG . "
(matricula, clas_id, clit_id, id_bilhetes, id_dac)
VALUES(:matricula, :clas_id, :clit_id, :id_bilhetes, :id_dac)";
$data['matricula'] = $matricula;
$data['clas_id'] = $clas_id;
$data['clit_id'] = $clit_id;
$data['id_bilhetes'] = $id_bilhetes;
$data['id_dac'] = $id_dac;
return $this->create($this->query, $data);
}
}

63
app/Models/EventQueue.php

@ -0,0 +1,63 @@
<?php
namespace app\Models;
use app\Core\Model;
/**
* Description of EventQueue
*
* @author root
*/
class EventQueue extends Model
{
const TABLE = 'pbx_eventos_dacs';
public function findEventQueueByAgent($agente, $queue = false)
{
$this->query = "SELECT * FROM " . self::TABLE . " WHERE agente = :agente ";
if ($queue) {
$this->query .= " AND fila = :queue ";
$data['queue'] = $queue;
}
$this->query .= " ORDER BY uid1 DESC LIMIT 1 ";
$data['agente'] = $agente;
return $this->read($this->query, $data)->fetch();
}
public function findEventQueueByParam2($uniqueid)
{
$this->query = "SELECT * FROM " . self::TABLE . " WHERE param2 = :param2 ";
return $this->read($this->query, ['param2' => $uniqueid])->fetch();
}
public function addEventQueue($uniqueid, $queue, $agent, $event, $media)
{
$this->query = "INSERT INTO " . self::TABLE . " (uid1, uid2, fila, agente, evento, param2) VALUES(:uid1, :uid2, :fila, :agente, :evento, :param2);";
$data['uid1'] = time();
$data['uid2'] = $uniqueid;
$data['fila'] = $queue;
$data['agente'] = $agent;
$data['evento'] = $event;
$data['param2'] = $media;
return $this->create($this->query, $data);
}
public function updateEventQueue($uniqueid, $queue, $agent, $event, $param1 = null, $param2 = null)
{
$this->query = "UPDATE " . self::TABLE . " SET fila = :fila, agente = :agente, evento = :evento, param1 = :param1, param2 = :param2 WHERE uid2 = :uid2;";
return $this->update($this->query, ['fila' => $queue, 'agente' => $agent, 'evento' => $event, 'param1' => $param1, 'param2' => $param2, 'uid2' => $uniqueid]);
}
public function findAllEventByAwait($queue)
{
$this->query = "SELECT * FROM " . self::TABLE . "
WHERE evento = :evento
AND fila = :fila ";
return $this->read($this->query, ['fila' => $queue, 'evento' => CONF_EVENT_WHATSAPP_ESPERA]);
}
}

21
app/Models/ListaNegraPalavras.php

@ -0,0 +1,21 @@
<?php
namespace app\Models;
use app\Core\Model;
/**
* Description of NotificaMedia
*
* @author root
*/
class ListaNegraPalavras extends Model
{
const table = "pbx_lista_negra_palavras";
public function getAll()
{
$this->query = "SELECT * FROM " . self::table;
return $this->read($this->query)->fetchAll();
}
}

40
app/Models/Message.php

@ -0,0 +1,40 @@
<?php
namespace app\Models;
use app\Core\Model;
/**
* Description of Message
*
* @author root
*/
class Message extends Model
{
const MESSAGE = "pbx_message_wpp";
public function addMessage($uniqueid, $src, $dst, $tipo, $conteudo, $nome)
{
$this->query = "INSERT INTO " . self::MESSAGE . " (uniqueid, src, dst, type, content, profile_name) VALUES(:uniqueid, :src, :dst, :type, :content, :profile_name);";
return $this->create($this->query, ['uniqueid' => $uniqueid, 'src' => $src, 'dst' => $dst, 'type' => $tipo, 'content' => utf8_decode($conteudo), 'profile_name' => utf8_decode($nome)]);
}
public function findMessageByUniqueid($uniqueid)
{
$this->query = "SELECT * FROM " . self::MESSAGE . " WHERE uniqueid = :uniqueid ORDER BY msg_date ASC";
return $this->read($this->query, ['uniqueid' => $uniqueid])->fetch();
}
public function findMessageByNumber($number)
{
$this->query = "SELECT * FROM " . self::MESSAGE . " WHERE (src = :number OR dst = :number) ORDER BY msg_date ASC, uniqueid ";
return $this->read($this->query, ['number' => $number])->fetchAll();
}
public function findLastMessage($uniqueid)
{
$this->query = "SELECT * FROM " . self::MESSAGE . " WHERE uniqueid = :uniqueid ";
$this->query .= " ORDER BY msg_date DESC LIMIT 1";
return $this->read($this->query, ['uniqueid' => $uniqueid])->fetch();
}
}

46
app/Models/NotificaMedia.php

@ -0,0 +1,46 @@
<?php
namespace app\Models;
use app\Core\Model;
/**
* Description of NotificaMedia
*
* @author root
*/
class NotificaMedia extends Model
{
const table = "pbx_notifica_media";
public function verificaNotifica($uniqueid, $src, $msg)
{
$this->query = "SELECT count(*) as quant FROM " .
self::table .
" WHERE uniqueid = :uniqueid and src = :src and msg = :msg";
return $this->read(
$this->query,
[
'uniqueid' => $uniqueid,
'src' => $src,
'msg' => $msg
]
)->fetch();
}
public function addNotifica($uniqueid, $src, $msg)
{
$data = [
'uniqueid' => $uniqueid,
'src' => $src,
'msg' => $msg,
];
$this->query = "INSERT INTO " . self::table . " (uniqueid, src, msg) VALUES(:uniqueid, :src, :msg);";
logger('notificacao')->error(print_r($data, true));
return $this->create(
$this->query,
$data
);
}
}

19
app/Models/Parametros.php

@ -0,0 +1,19 @@
<?php
namespace app\Models;
use app\Core\Model;
/**
* Description of EventQueue
*
* @author root
*/
class Parametros extends Model {
const TABLE = 'pbx_parametros';
public function findProtocolByParams($uniqueid){
$this->query = "SELECT prm_agente_proto, prm_use_proto_parceiro FROM " . self::TABLE . " WHERE id = :id;";
return $this->read($this->query, ['id' => 1])->fetch();
}
}

89
app/Models/Pause.php

@ -0,0 +1,89 @@
<?php
namespace app\Models;
use app\Core\Model;
/**
* Description of Pause
*
* @author Lucas Awade
*/
class Pause extends Model
{
const TABLE = "pbx_motivos_pausas";
const EVENTO_AGENTE = 'pbx_eventos_agentes';
public function findPauseByName($name)
{
$this->query = "SELECT * FROM " . self::TABLE . " WHERE upper(motivo) = :name";
return $this->read($this->query, ['name' => strtoupper($name)])->fetch();
}
public function addEventoPauseAgent($matricula, $ramal, $idMotivo, $idDac, $produtiva, $flag = 1)
{
$this->query = "INSERT INTO " . self::EVENTO_AGENTE . " (matricula, ramal, id_dac, id_motivo_pausa, flag, pausa_produtiva, entrada_pausa, saida_pausa)
VALUES(:matricula, :ramal, :id_dac, :id_motivo_pausa, :flag, :pausa_produtiva, :entrada_pausa, :saida_pausa);";
return $this->create(
$this->query,
[
'matricula' => $matricula,
'ramal' => $ramal,
'id_dac' => $idDac,
'id_motivo_pausa' => $idMotivo,
'flag' => $flag,
'pausa_produtiva' => $produtiva,
'entrada_pausa' => 'now()',
'saida_pausa' => 'now()'
]
);
}
public function updateEventoOutPause($matricula, $dac, $flag = 2)
{
$this->query = "UPDATE " . self::EVENTO_AGENTE . " SET saida_pausa = :saida_pausa, flag = :flag WHERE matricula = :matricula AND id_dac = :id_dac
AND entrada_pausa = (SELECT MAX(entrada_pausa) FROM " . self::EVENTO_AGENTE . " WHERE matricula = :matricula AND id_dac = :id_dac);";
return $this->update($this->query, ['saida_pausa' => 'now()', 'flag' => $flag, 'matricula' => $matricula, 'id_dac' => $dac, 'entrada_pausa']);
}
public function findGroupPause()
{
$this->query = "SELECT prm_pausa_grupo FROM pbx_parametros";
return $this->read($this->query)->fetchAll();
}
public function findPauseByGroupUser($matricula, $active = true)
{
$this->query = "SELECT d.id, d.motivo, d.produtiva, d.flag, d.tempo_alerta
FROM pbx_usuarios a
INNER JOIN pbx_grupo_usuario b ON a.id = b.user_id
INNER JOIN pbx_pausa_grupo_usuario c ON c.gp_id = b.gp_id
INNER JOIN pbx_motivos_pausas d ON d.id = c.id
WHERE matricula = :matricula ";
if ($active) {
$this->query .= " AND flag = :flag";
$data['flag'] = 1;
}
$data['matricula'] = $matricula;
return $this->read($this->query, $data)->fetchAll();
}
public function findAllPause($active = true)
{
$this->query = "SELECT * FROM " . self::TABLE . " WHERE 1=1 ";
if ($active) {
$this->query .= " AND flag = :flag";
$data['flag'] = 1;
}
$this->query .= " LIMIT 10 ";
return $this->read($this->query, $data)->fetchAll();
}
public function findAgentPause($matricula)
{
$this->query = "SELECT status, motivo_pausa FROM pbx_supervisor_agentes WHERE matricula = :matricula;";
return $this->read($this->query, ['matricula' => $matricula])->fetchAll();
}
}

29
app/Models/Protocol.php

@ -0,0 +1,29 @@
<?php
namespace app\Models;
use app\Core\Model;
/**
* Description of EventQueue
*
* @author root
*/
class Protocol extends Model {
const TABLE = 'pbx_protocolo_reg';
public function findProtocol($uniqueid){
$this->query = "SELECT ano::text || '-' || lpad(numproto::text,6,'0') as protocolo, protoparceiro FROM " . self::TABLE . " WHERE uniqueid = :uniqueid;";
return $this->read($this->query, ['uniqueid' => $uniqueid])->fetch();
}
public function findMaxProtocol($year){
$this->query = "SELECT MAX(numProto) AS protocolo FROM " . self::TABLE . " WHERE ano = :ano";
return $this->read($this->query, ['ano' => $year])->fetch();
}
public function insert($uniqueId, $year, $numProto, $proto, $protoParceiro){
$this->query = "INSERT INTO " . self::TABLE . "(uniqueid, ano, numProto, protocolo, protoparceiro) VALUES(:uniqueid, :ano, :numProto, :protocolo, :protoparceiro);";
return $this->create($this->query, ['uniqueid' => $uniqueId , 'ano' => $year, 'numProto' => $numProto, 'protocolo' => $proto, 'protoparceiro' => $protoParceiro]);
}
}

53
app/Models/Queue.php

@ -0,0 +1,53 @@
<?php
namespace app\Models;
use app\Core\Model;
/**
* Clase para criacao de Querys no banco de dados.
*
* Todas as querys desta classe esta especificada para o uso do WhatsApp.
*
* @author Lucas Awade
*/
class Queue extends Model
{
const TABLE = "pbx_queues_grupos";
public function findAllQueue($active = true)
{
$this->query = "SELECT * FROM " . self::TABLE . " WHERE 1=1 AND midiafila = :midiafila ";
if ($active) {
$this->query .= " AND status = :status ";
$data['status'] = 'A';
}
$data['midiafila'] = "S";
$this->query .= " LIMIT 10 ";
return $this->read($this->query, $data)->fetchAll();;
}
public function findQueueByName($nome, $active = true)
{
$this->query = "SELECT * FROM " . self::TABLE . " WHERE nome = :nome ";
if ($active) {
$this->query .= " AND status = :status ";
$data['status'] = 'A';
}
$data['nome'] = $nome;
return $this->read($this->query, $data)->fetch();
}
public function findQueueById($id, $active = true)
{
$this->query = "SELECT * FROM " . self::TABLE . " WHERE id = :id ";
if ($active) {
$this->query .= " AND status = :status ";
$data['status'] = 'A';
}
$data['id'] = $id;
return $this->read($this->query, $data)->fetch();
}
}

22
app/Models/Ramal.php

@ -0,0 +1,22 @@
<?php
namespace app\Models;
use app\Core\Model;
/**
* Description of Ramal
*
* @author Lucas Awade
*/
class Ramal extends Model
{
const TABLE = 'pbx_sip_ramais';
public function findRamal($ramal)
{
$this->query = "SELECT * FROM " . self::TABLE . " pr WHERE pr.nome = :ramal;";
return $this->read($this->query, ['ramal' => $ramal])->fetch();
}
}

26
app/Models/SupervisorQueue.php

@ -0,0 +1,26 @@
<?php
namespace app\Models;
use app\Core\Model;
/**
* Description of EventQueue
*
* @author root
*/
class SupervisorQueue extends Model {
const TABLE = 'pbx_supervisor_dacs';
public function updateEsperaSupervisorQueue($name, $time){
$this->query = "UPDATE " . self::TABLE . " SET espera = (b.espera::int + :time)
FROM (SELECT espera FROM " . self::TABLE . " b WHERE b.dac = :dac) AS b
WHERE dac = :dac;";
return $this->update($this->query, ['espera' => $time , 'dac' => $name]);
}
public function updateEsperaByQueue($queue, $time, $numberwait){
$this->query = "UPDATE " . self::TABLE . " SET tempo_espera = :tempo_espera, espera = :espera WHERE dac = :dac;";
return $this->update($this->query, ['tempo_espera' => $time , 'espera' => $numberwait, 'dac' => $queue]);
}
}

523
app/Providers/ApiTelegram.php

@ -0,0 +1,523 @@
<?php
namespace app\Providers;
use app\Interfaces\IApiMedia;
use app\Providers\RequestURL;
class ApiTelegram implements IApiMedia
{
private $token;
private $url;
private $metodo;
########################################################################
## VARIAVEIS DA CLASSE ##
########################################################################
private $query;
private $requestType;
private $request;
private $params = array();
private $hook;
private $storage = "/var/www/html/aplicativo/audio/";
public $channel = CONF_TELEGRAM_CHANNEL;
public $timeout_client_resposta = CONF_TELEGRAM_TIMEOUT_CLIENT_RESPOSTA;
function __construct()
{
$this->token = CONF_TELEGRAM_AUTH_TOKEN;
$this->url = CONF_TELEGRAM_AUTH_URL;
$this->request = new RequestURL();
}
function enviarMsgIterativaLista($telegram, $mensagem, $nomeButton, $lista, $prex = '')
{
$this->debug = debug_backtrace();
if ($this->getArgs(func_get_args())) {
$this->params = array(
"chatId" => "$telegram",
"text" => array("body" => utf8_encode("$mensagem")),
"options" => array(
"reply_markup" => array(
"inline_keyboard" => $this->montaOp($lista, $prex)
)
)
);
$this->requestType("POST");
$this->setMetodo('sendMessage');
return $this->exec();
}
return false;
}
function montaOp($lista, $prex = '')
{
$botoes = [];
for ($i = 0; $i < count($lista); $i++) {
array_push(
$botoes,
array(
array(
"text" => utf8_encode("{$lista[$i]['title']}"),
"callback_data" => $prex == "C" ? utf8_encode("{$lista[$i]['title']}") : utf8_encode("{$lista[$i]['sub']}")
),
)
);
}
return $botoes;
}
function enviarMsgIterativaBotao($telegram, $mensagem, $buttons)
{
$this->debug = debug_backtrace();
if ($this->getArgs(func_get_args())) {
$this->params = array(
"chatId" => "$telegram",
"text" => array("body" => utf8_encode("$mensagem")),
"options" => array(
"reply_markup" => array(
"inline_keyboard" => array(
array(
array(
"text" => utf8_encode("/presente"),
"callback_data" => utf8_encode("/presente")
),
)
)
)
)
);
$this->requestType("POST");
$this->setMetodo('sendMessage');
return $this->exec();
}
return false;
}
function enviarMsg($telegram, $mensagem)
{
$this->debug = debug_backtrace();
if ($this->getArgs(func_get_args())) {
$this->params = array(
"chatId" => "$telegram",
"text" => array("body" => "$mensagem")
);
$this->requestType("POST");
$this->setMetodo('sendMessage');
return $this->exec();
}
return false;
}
function enviarContato($telegram, $nome, $contato)
{
$this->debug = debug_backtrace();
if ($this->getArgs(func_get_args())) {
$this->params = array(
"chatId" => "$telegram",
"type" => "contacts",
"contacts" => array(
array(
"name" => array(
"first_name" => "$nome",
"formatted_name" => "$nome"
),
"phones" => array(
array(
"phone" => "$contato",
"type" => "CELL",
"wa_id" => "$contato"
)
)
)
)
);
$this->requestType("POST");
$this->setMetodo('sendContact');
return $this->exec();
}
return false;
}
function enviarLocalizacao($telegram, $longitude, $latitude, $nome = null, $endereco = null)
{
$this->debug = debug_backtrace();
if ($this->getArgs(func_get_args())) {
$this->params = array(
"chatId" => "$telegram",
"longitude" => "$longitude",
"latitude" => "$latitude",
);
$this->requestType("POST");
$this->setMetodo('sendLocation');
return $this->exec();
}
return false;
}
function enviaDocumento($telegram, $link, $titulo = null)
{
$this->debug = debug_backtrace();
if ($this->getArgs(func_get_args())) {
$this->params = array(
"chatId" => "$telegram",
"file" => "$link",
"options" => array(
"caption" => "$titulo"
),
"fileOptions" => array(
"filename" => "$titulo"
)
);
$this->requestType("POST");
$this->setMetodo('sendDocument');
return $this->exec();
}
return false;
}
function enviaImagem($telegram, $link, $titulo = null)
{
$this->debug = debug_backtrace();
if ($this->getArgs(func_get_args())) {
$this->params = array(
"chatId" => "$telegram",
"file" => "$link",
);
$this->requestType("POST");
$this->setMetodo('sendPhoto');
return $this->exec();
}
return false;
}
function enviaSticker($telegram, $link)
{
$this->debug = debug_backtrace();
if ($this->getArgs(func_get_args())) {
$this->params = array(
"chatId" => "$telegram",
"file" => "$link",
);
$this->requestType("POST");
$this->setMetodo('sendSticker');
return $this->exec();
}
return false;
}
function enviaVideo($telegram, $link, $titulo = null)
{
$this->debug = debug_backtrace();
if ($this->getArgs(func_get_args())) {
$this->params = array(
"chatId" => "$telegram",
"file" => "$link",
"options" => array(
"caption" => "$titulo"
)
);
$this->requestType("POST");
$this->setMetodo('sendVideo');
return $this->exec();
}
return false;
}
function enviaAudio($telegram, $link)
{
$this->debug = debug_backtrace();
if ($this->getArgs(func_get_args())) {
$this->params = array(
"chatId" => "$telegram",
"file" => "$link",
);
$this->requestType("POST");
$this->setMetodo('sendVoice');
return $this->exec();
}
return false;
}
function baixarMidia($name)
{
$this->debug = debug_backtrace();
if ($this->getArgs(func_get_args())) {
$this->requestType("GET");
$this->setMetodo('media/' . $name);
$file = $this->storage . $name;
file_put_contents($file, $this->exec());
if (file_exists($file)) {
return $file;
}
}
return false;
}
function setStorage($storage)
{
$this->storage = $storage;
}
/**
* Profile WhatsApp
* @return string
*/
public function getProfile()
{
return $this->hook['from']['first_name'];
}
/**
* Phone WhatsApp
* @return string
*/
public function getPhone()
{
if ($this->hook['chat']['id']) {
return $this->hook['chat']['id'];
} else {
return $this->hook['from']['id'];
}
}
/**
* Returns the type of the message
* @return string|boolean
*/
public function getType()
{
if ($this->hook) {
if (array_key_exists("contact", $this->hook)) {
return 'contacts';
}
if (array_key_exists("location", $this->hook)) {
return 'location';
}
if (array_key_exists("document", $this->hook)) {
return 'document';
}
if (array_key_exists("audio", $this->hook)) {
return 'audio';
}
if (array_key_exists("video", $this->hook)) {
return 'video';
}
if (array_key_exists("sticker", $this->hook)) {
return 'sticker';
}
if (array_key_exists("photo", $this->hook)) {
return 'image';
}
if (array_key_exists("text", $this->hook)) {
return 'text';
}
if (array_key_exists("data", $this->hook)) {
return 'text';
}
return $this->hook['messages'][0]['type'];
}
return false;
}
/**
* Returns the mime of the message
* @return string|boolean
*/
public function getMimetype()
{
if ($this->hook['messages'][0][$this->getType()]['mime_type']) {
return base64_encode($this->hook['messages'][0][$this->getType()]['mime_type']);
}
return false;
}
/**
* Returns the id of the message
* @return string|boolean
*/
public function getId()
{
if ($this->hook && $this->getType()) {
return $this->hook['messages'][0][$this->getType()]['id'];
}
return false;
}
/**
* Returns the (text, body) of the message
* @return string|boolean
*/
public function getIsValidMessage()
{
return true;
}
/**
* Returns the (text, body) of the message
* @return string|boolean
*/
public function getMessage()
{
if ($this->hook['data']) {
return $this->hook['data'];
}
if ($this->hook['text']) {
return $this->hook['text'];
}
$message = $this->hook['data'];
return ($message ? $message : false);
}
/**
* Returns the name of the contact
* @return string|boolean
*/
public function getContactFormatted()
{
$formatted = $this->hook['messages'][0]['contacts'][0]['name']['formatted_name'];
if ($formatted) {
return $formatted;
}
return false;
}
/**
* Returns the phone of the contact
* @return string|boolean
*/
public function getContactPhone()
{
$contact = $this->hook['messages'][0]['contacts'][0]['phones'][0]['wa_id'];
if ($contact) {
return $contact;
}
return false;
}
/**
* Returns the latitude|longitude of the location
* @return string|boolean
*/
public function getGeolocation($type)
{
$geolocation = $this->hook['location'][strtolower($type)];
if ($geolocation) {
return $geolocation;
}
return false;
}
function setHook($hook)
{
$this->hook = $hook;
}
########################################################################
## FUNCOES DO SISTEMA ##
########################################################################
function setMetodo($metodo)
{
$this->metodo = $metodo;
}
/**
* Escreve a query para ser passada para o curl
*
* @param string $query
*/
function setQuery($query)
{
return $this->query .= $query;
}
/**
* retorna a string pronta da query do curl e limpa a variavel.
*
* @return string $query
*/
function getQuery()
{
$query = $this->query;
unset($this->query);
return $query;
}
/**
* Verifica se todos os parametros passados foram completados.
*
* @param array $args
* @return true|false
*/
function getArgs($args)
{
foreach ($args as $value) {
if (!$value) {
return false;
}
}
return true;
}
/**
* Recebe o tipo de Requisi<EFBFBD><EFBFBD>o GET/POST
*
* @return boolean
*/
function requestType($req = null)
{
if (!$req) {
return $this->requestType;
}
if (strtoupper($req) == "GET") {
return $this->requestType = "GET";
} else if (strtoupper($req) == "POST") {
return $this->requestType = "POST";
}
}
function exec()
{
$this->setQuery(json_encode($this->params)); //SET QUERY
$this->request->setUrl($this->url . $this->metodo);
$header = array();
//$header[] = "Authorization: Bearer {$this->token}";
if ($this->requestType == 'POST') {
$header[] = 'Content-Type: application/json';
$this->request->post_field($this->getQuery(), true);
}
$this->request->header($header);
$this->request->method_request($this->requestType);
$response = $this->request->exec_request();
return $this->response($response);
}
function response($result)
{
if ($result) {
if (json_decode($result, true) !== null) {
return json_decode($result, true);
}
return $result;
} else {
return false;
}
}
public function getLinkDownload($host)
{
if ($this->hook['photo']) {
return end($this->hook['photo'])['file_id'];
}
if ($this->hook['sticker']) {
return $this->hook['sticker']['file_id'];
}
if ($this->hook['video']) {
return $this->hook['video']['file_id'];
}
if ($this->hook['audio']) {
return $this->hook['audio']['file_id'];
}
if ($this->hook['document']) {
return $this->hook['document']['file_id'];
}
}
public function retornaTituloDocument($msg)
{
return $this->hook['document']['file_name'];
}
}

78
app/Providers/Crypt.php

@ -0,0 +1,78 @@
<?php
namespace app\Providers;
/**
* Description of Cripto
*
* @author Lucas Awade
*/
class Crypt {
private $message;
private $key;
private $option;
private $tag;
private $cipher;
private $ivlen;
private $iv;
private $textcrypt;
const CONF_CIPHER_CRYPT = 'aes-256-cbc';
function __construct($cipher = null, $key = null, $option = OPENSSL_RAW_DATA, $tag = null) {
if (!$cipher) {
$this->cipher = self::CONF_CIPHER_CRYPT;
} else {
$this->cipher = $cipher;
}
$this->key = $key;
$this->option = $option;
$this->tag = $tag;
$this->openssl_crypt();
}
public function encrypt($message = null) {
$this->setMessage($message);
$encrypt = openssl_encrypt($this->message, $this->cipher, $this->key, $this->option, $this->iv);
$hashcode = hash_hmac('sha256', $encrypt, $this->key, true);
$this->textcrypt = base64_encode($this->iv . $hashcode . $encrypt);
return $this->textcrypt;
}
public function decrypt($textcrypt = null) {
$c = base64_decode($textcrypt);
$this->iv = substr($c, 0, $this->ivlen);
$hmac = substr($c, $this->ivlen, 32);
$ciphertext_raw = substr($c, $this->ivlen + 32);
$original_plaintext = openssl_decrypt($ciphertext_raw, $this->cipher, $this->key, $options = OPENSSL_RAW_DATA, $this->iv);
$calcmac = hash_hmac('sha256', $ciphertext_raw, $this->key, true);
if (hash_equals($hmac, $calcmac)) {
return $original_plaintext;
}
}
private function openssl_crypt() {
if (in_array(strtolower($this->cipher), openssl_get_cipher_methods())) {
$this->ivlen = openssl_cipher_iv_length($this->cipher);
$this->iv = openssl_random_pseudo_bytes($this->ivlen);
}
}
public function setKey($key) {
$this->key = $key;
}
public function setOption($option) {
$this->option = $option;
}
public function setTag($tag) {
$this->tag = $tag;
}
public function setMessage($message) {
$this->message = $message;
}
}

177
app/Providers/Logger.php

@ -0,0 +1,177 @@
<?php
namespace app\Providers;
/**
* Classe para utilizar
*
* @documentation:
* @author Lucas Awade
* @function developer
* @company SimplesIP
* @version 1.0.0
*/
class Logger
{
/*
* GENERATE LOG
*/
private $active;
private $log;
private $type;
private $text;
/*
* CONF. FILE LOG
*/
private $file;
private $path;
private $name;
/*
* CONST. MESSAGE TYPE
*/
const LOG_SUCCESS = "SUCCESS";
const LOG_DEBUG = "DEBUG";
const LOG_INFO = "INFO";
const LOG_WARNING = "WARNING";
const LOG_ERROR = "ERROR";
public function __construct($nameLog, $active = false, $path = "/var/log/asterisk/")
{
$this->name = $nameLog;
$this->path = $path;
$this->active = $active;
$this->config($nameLog);
}
########################################################################
## TYPES ##
########################################################################
public function success($log, $debug_trace = null)
{
$this->type = self::LOG_SUCCESS;
$this->text = $log;
$this->header($log, $debug_trace ? $debug_trace : debug_backtrace());
$this->write();
}
public function debug($log, $debug_trace = null)
{
$this->type = self::LOG_DEBUG;
$this->text = $log;
$this->header($log, $debug_trace ? $debug_trace : $this->name);
$this->write();
}
public function info($log, $debug_trace = null)
{
$this->type = self::LOG_INFO;
$this->text = $log;
$this->header($log, $debug_trace ? $debug_trace : $this->name);
$this->write();
}
public function error($log, $debug_trace = null)
{
$this->type = self::LOG_ERROR;
$this->text = $log;
$this->header($log, $debug_trace ? $debug_trace : $this->name);
$this->write();
}
public function warning($log, $debug_trace = null)
{
$this->type = self::LOG_WARNING;
$this->text = $log;
$this->header($log, $debug_trace ? $debug_trace : $this->name);
$this->write();
}
########################################################################
## IMPORTANT ##
########################################################################
private function write()
{
if ($this->active) {
file_put_contents($this->file, $this->log, FILE_APPEND);
}
}
private function header($log, $debug_trace)
{
$this->log = "________________________________________________________________________________________\n";
if (is_array($debug_trace)) {
$method = $debug_trace[0]['class'] ? "{$debug_trace[0]['class']}::{$debug_trace[0]['function']}" : $debug_trace[0]['function'];
$args = null;
$x = 0;
if (count($debug_trace[0]['args']) > 0) {
foreach ($debug_trace[0]['args'] as $key => $arg) {
$x++;
$args .= $arg;
if (count($debug_trace[0]['args']) != $x) {
$args .= ",";
}
}
}
$this->log .= sprintf("\n[ %s ][ LINE %s ][ %s ][ ARGS ($args) ][ %s ]\n\n", date('d/m/Y H:i:s'), $debug_trace[0]['line'], $method, $this->type);
} else {
$this->log .= sprintf("\n[ %s ][ %s ][ %s ]\n\n", date('d/m/Y H:i:s'), $debug_trace, $this->type);
}
$this->log .= "> " . $log;
$this->log .= "\n\n ---------------------------------- [ FINISH LOGGER ] ----------------------------------\n\n";
}
public function openLog()
{
//$file = fopen($this->file, 'rb');
}
public function locateLog()
{
echo "\n\n {$this->file} \n\n";
}
########################################################################
## CONFIGS ##
########################################################################
public function config($name, $exten = ".log", $prefix = null)
{
if(strpos('.log', $name) !== false){
$exten = '';
}
if (file_exists($this->file)) {
$contents = file_get_contents($this->file);
}
$this->file = trim($this->path . $prefix . ($name ? $name : $this->name) . $exten);
file_put_contents($this->file, $contents ? $contents : "", FILE_APPEND);
}
public function getType()
{
return $this->type;
}
public function getText()
{
return $this->text;
}
public function setLogger($active)
{
if ($this->active === true) {
$this->active = $active;
} else if ($active === false) {
$this->active = $active;
} else {
$this->active = true;
}
}
}

522
app/Providers/Positus.php

@ -0,0 +1,522 @@
<?php
namespace app\Providers;
use app\Interfaces\IApiMedia;
use app\Providers\RequestURL;
class Positus implements IApiMedia
{
private $token;
private $url;
private $metodo;
########################################################################
## VARIAVEIS DA CLASSE ##
########################################################################
private $query;
private $requestType;
private $request;
private $params = array();
private $hook;
private $storage = "/var/www/html/aplicativo/audio/";
public $channel = CONF_WHATSAPP_CHANNEL;
public $timeout_client_resposta = CONF_WHATSAPP_TIMEOUT_CLIENT_RESPOSTA;
########################################################################
## RECURSOS DA API ##
########################################################################
function enviarMsg($whatsapp, $mensagem)
{
$this->debug = debug_backtrace();
if ($this->getArgs(func_get_args())) {
$this->params = array(
"to" => "+$whatsapp",
"type" => "text",
"text" => array("body" => "$mensagem")
);
$this->requestType("POST");
$this->setMetodo('messages');
return $this->exec();
}
return false;
}
function enviarMsgIterativaLista($whatsapp, $mensagem, $nomeButton, $lista, $prex = '')
{
$this->debug = debug_backtrace();
if ($this->getArgs(func_get_args())) {
$this->params = array(
"to" => "+$whatsapp",
"type" => "interactive",
"interactive" => array(
"type" => "list",
"body" => array(
"text" => utf8_encode($mensagem)
),
"action" => array(
"button" => utf8_encode($nomeButton),
"sections" => $this->montaSection($lista, $prex)
)
)
);
logger('positus')->info(print_r($this->params, true));
$this->requestType("POST");
$this->setMetodo('messages');
$ret = $this->exec();
logger('positus')->info(print_r($ret, true));
return $ret;
}
return false;
}
function montaSection($lista, $prex = '')
{
$sections = [];
for ($i = 0; $i < count($lista); $i++) {
array_push(
$sections,
array(
"id" => "$prex$i",
"title" => utf8_encode("{$lista[$i]['title']}"),
"description" => utf8_encode("{$lista[$i]['sub']}")
)
);
}
return array(
array(
"title" => utf8_encode("Comandos"),
"rows" => $sections
),
);
}
function enviarMsgIterativaBotao($whatsapp, $mensagem, $buttons)
{
$this->debug = debug_backtrace();
if ($this->getArgs(func_get_args())) {
$this->params = array(
"to" => "+$whatsapp",
"type" => "interactive",
"recipient_type" => "individual",
"interactive" => array(
"type" => "button",
"body" => array(
"text" => utf8_encode($mensagem)
),
"action" => array(
"buttons" => $buttons
)
)
);
logger('positus')->info(print_r($this->params, true));
$this->requestType("POST");
$this->setMetodo('messages');
$ret = $this->exec();
logger('positus')->info(print_r($ret, true));
return $ret;
}
return false;
}
function enviarContato($whatsapp, $nome, $contato)
{
$this->debug = debug_backtrace();
if ($this->getArgs(func_get_args())) {
$this->params = array(
"to" => "+$whatsapp",
"type" => "contacts",
"contacts" => array(
array(
"name" => array(
"first_name" => "$nome",
"formatted_name" => "$nome"
),
"phones" => array(
array(
"phone" => "+$contato",
"type" => "CELL",
"wa_id" => "$contato"
)
)
)
)
);
$this->requestType("POST");
$this->setMetodo('messages');
return $this->exec();
}
return false;
}
function enviarLocalizacao($whatsapp, $longitude, $latitude, $nome = null, $endereco = null)
{
$this->debug = debug_backtrace();
if ($this->getArgs(func_get_args())) {
$this->params = array(
"to" => "+$whatsapp",
"type" => "location",
"location" => array(
"longitude" => "$longitude",
"latitude" => "$latitude",
"name" => "$nome",
"address" => utf8_encode("$endereco")
)
);
$this->requestType("POST");
$this->setMetodo('messages');
return $this->exec();
}
return false;
}
function enviaDocumento($whatsapp, $link, $titulo = null)
{
$this->debug = debug_backtrace();
if ($this->getArgs(func_get_args())) {
$this->params = array(
"to" => "+$whatsapp",
"type" => "document",
"document" => array("link" => "$link", "caption" => "$titulo")
);
$this->requestType("POST");
$this->setMetodo('messages');
return $this->exec();
}
return false;
}
function enviaImagem($whatsapp, $link, $titulo = null)
{
$this->debug = debug_backtrace();
if ($this->getArgs(func_get_args())) {
$this->params = array(
"to" => "+$whatsapp",
"type" => "image",
"image" => array("link" => "$link", "caption" => "$titulo")
);
$this->requestType("POST");
$this->setMetodo('messages');
return $this->exec();
}
return false;
}
function enviaSticker($whatsapp, $link)
{
$this->debug = debug_backtrace();
if ($this->getArgs(func_get_args())) {
$this->params = array(
"to" => "+$whatsapp",
"type" => "sticker",
"sticker" => array("link" => "$link")
);
$this->requestType("POST");
$this->setMetodo('messages');
return $this->exec();
}
return false;
}
function enviaVideo($whatsapp, $link, $titulo = null)
{
$this->debug = debug_backtrace();
if ($this->getArgs(func_get_args())) {
$this->params = array(
"to" => "+$whatsapp",
"type" => "video",
"video" => array("link" => "$link", "caption" => "$titulo")
);
$this->requestType("POST");
$this->setMetodo('messages');
return $this->exec();
}
return false;
}
function enviaAudio($whatsapp, $link)
{
$this->debug = debug_backtrace();
if ($this->getArgs(func_get_args())) {
$this->params = array(
"to" => "+$whatsapp",
"type" => "audio",
"audio" => array("link" => "$link")
);
$this->requestType("POST");
$this->setMetodo('messages');
return $this->exec();
}
return false;
}
function baixarMidia($name)
{
$this->debug = debug_backtrace();
if ($this->getArgs(func_get_args())) {
$this->requestType("GET");
$this->setMetodo('media/' . $name);
$file = $this->storage . $name;
file_put_contents($file, $this->exec());
if (file_exists($file)) {
return $file;
}
}
return false;
}
function setStorage($storage)
{
$this->storage = $storage;
}
/**
* Profile WhatsApp
* @return string
*/
public function getProfile()
{
return $this->hook['contacts'][0]['profile']['name'];
}
/**
* Phone WhatsApp
* @return string
*/
public function getPhone()
{
return $this->hook['contacts'][0]['wa_id'];
}
/**
* Returns the type of the message
* @return string|boolean
*/
public function getType()
{
if ($this->hook) {
return $this->hook['messages'][0]['type'];
}
return false;
}
/**
* Returns the mime of the message
* @return string|boolean
*/
public function getMimetype()
{
if ($this->hook['messages'][0][$this->getType()]['mime_type']) {
return base64_encode($this->hook['messages'][0][$this->getType()]['mime_type']);
}
return false;
}
/**
* Returns the id of the message
* @return string|boolean
*/
public function getId()
{
if ($this->hook && $this->getType()) {
return $this->hook['messages'][0][$this->getType()]['id'];
}
return false;
}
/**
* Returns the (text, body) of the message
* @return string|boolean
*/
public function getIsValidMessage()
{
$message = $this->hook['messages'];
return ($message ? $message : false);
}
/**
* Returns the (text, body) of the message
* @return string|boolean
*/
public function getMessage()
{
logger('positus')->info(print_r($this->hook, true));
if ($this->hook['messages'][0]['interactive']) {
if ($this->hook['messages'][0]['interactive']['list_reply']) {
$id = $this->hook['messages'][0]['interactive']['list_reply']['id'];
if (strpos($id, 'P') === 0) {
return $this->hook['messages'][0]['interactive']['list_reply']['description'];
}
return $this->hook['messages'][0]['interactive']['list_reply']['title'];
} else {
return $this->hook['messages'][0]['interactive']['button_reply']['title'];
}
}
$message = $this->hook['messages'][0]['text']['body'];
return ($message ? $message : false);
}
/**
* Returns the name of the contact
* @return string|boolean
*/
public function getContactFormatted()
{
$formatted = $this->hook['messages'][0]['contacts'][0]['name']['formatted_name'];
if ($formatted) {
return $formatted;
}
return false;
}
/**
* Returns the phone of the contact
* @return string|boolean
*/
public function getContactPhone()
{
$contact = $this->hook['messages'][0]['contacts'][0]['phones'][0]['wa_id'];
if ($contact) {
return $contact;
}
return false;
}
/**
* Returns the latitude|longitude of the location
* @return string|boolean
*/
public function getGeolocation($type)
{
$geolocation = $this->hook['messages'][0]['location'][strtolower($type)];
if ($geolocation) {
return $geolocation;
}
return false;
}
function setHook($hook)
{
$this->hook = $hook;
}
########################################################################
## FUNCOES DO SISTEMA ##
########################################################################
function __construct()
{
$this->token = CONF_WHATSAPP_AUTH_TOKEN;
$this->url = CONF_WHATSAPP_AUTH_URL;
$this->request = new RequestURL();
}
function setMetodo($metodo)
{
$this->metodo = $metodo;
}
/**
* Escreve a query para ser passada para o curl
*
* @param string $query
*/
function setQuery($query)
{
return $this->query .= $query;
}
/**
* retorna a string pronta da query do curl e limpa a variavel.
*
* @return string $query
*/
function getQuery()
{
$query = $this->query;
unset($this->query);
return $query;
}
/**
* Verifica se todos os parametros passados foram completados.
*
* @param array $args
* @return true|false
*/
function getArgs($args)
{
foreach ($args as $value) {
if (!$value) {
return false;
}
}
return true;
}
/**
* Recebe o tipo de Requisi<EFBFBD><EFBFBD>o GET/POST
*
* @return boolean
*/
function requestType($req = null)
{
if (!$req) {
return $this->requestType;
}
if (strtoupper($req) == "GET") {
return $this->requestType = "GET";
} else if (strtoupper($req) == "POST") {
return $this->requestType = "POST";
}
}
function exec()
{
$this->setQuery(json_encode($this->params)); //SET QUERY
$this->request->setUrl($this->url . $this->metodo);
$header = array();
$header[] = "Authorization: Bearer {$this->token}";
if ($this->requestType == 'POST') {
$header[] = 'Content-Type: application/json';
$this->request->post_field($this->getQuery(), true);
}
$this->request->header($header);
$this->request->method_request($this->requestType);
$response = $this->request->exec_request();
return $this->response($response);
}
function response($result)
{
if ($result) {
if (json_decode($result, true) !== null) {
return json_decode($result, true);
}
return $result;
} else {
return false;
}
}
/**
* Create file and download in browser
*/
public function getLinkDownload($host)
{
return $host . "whatsapp/download/{$this->getId()}/{$this->getMimetype()}";
}
public function retornaTituloDocument($msg)
{
$titulo = $msg['REQUEST']['messages'][0]['document']['filename'];
$titulo = substr($titulo, 0, strrpos($titulo, "."));
return $titulo;
}
}

101
app/Providers/RequestURL.php

@ -0,0 +1,101 @@
<?php
namespace app\Providers;
class RequestURL
{
private $method;
private $curl;
private $ssl;
private $post_field;
private $header;
const CONF_TIMEOUT = 30;
public function setUrl($url, $ssl = true)
{
$this->debug = debug_backtrace();
$this->curl = curl_init($url);
$this->ssl = is_bool($ssl) ? $ssl : true;
}
public function header($header)
{
$this->debug = debug_backtrace();
if (is_array($header)) {
$this->header = $header;
} else {
$this->header = array($header);
}
}
public function post_field($data, $json = false)
{
$this->debug = debug_backtrace();
if ($json) {
$this->post_field = $data;
} else {
$this->post_field = http_build_query($data);
}
}
public function method_request($method = 'GET')
{
$this->debug = debug_backtrace();
$this->method = strtoupper($method);
}
public function exec_request()
{
$this->debug = debug_backtrace();
$this->conf_request();
if (curl_error($this->curl)) {
return false;
}
$this->response = curl_exec($this->curl);
curl_close($this->curl);
return $this->response($this->response);
}
public function convert_xml_to_object()
{
$this->debug = debug_backtrace();
if (!$this->response) {
return false;
}
return simplexml_load_string($this->response);
}
private function response($result)
{
if ($result) {
if (json_decode($result, true) !== null) {
return json_decode($result, true);
}
return $result;
} else {
return false;
}
}
############################################################################
### CONFIG. CURL ###
############################################################################
private function conf_request()
{
curl_setopt($this->curl, CURLOPT_HTTPHEADER, $this->header);
curl_setopt($this->curl, CURLOPT_CUSTOMREQUEST, $this->method);
curl_setopt($this->curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($this->curl, CURLOPT_SSL_VERIFYHOST, $this->ssl);
curl_setopt($this->curl, CURLOPT_SSL_VERIFYPEER, $this->ssl);
if ($this->post_field) {
curl_setopt($this->curl, CURLOPT_POSTFIELDS, $this->post_field);
}
curl_setopt($this->curl, CURLOPT_CONNECTTIMEOUT, self::CONF_TIMEOUT);
curl_setopt($this->curl, CURLOPT_TIMEOUT, self::CONF_TIMEOUT);
}
}

258
app/Providers/WebHeader.php

@ -0,0 +1,258 @@
<?php
namespace app\Providers;
/**
* Description of WebHeader
*
* @author Lucas Awade
*/
class WebHeader
{
/** @class support headers * */
private $headers = [
"Access-Control-Allow-Headers",
"Access-Control-Allow-Methods",
"Access-Control-Allow-Origin",
"Cache-Control",
"Connection",
"Content-Description",
"Content-Disposition",
"Content-Length",
"Access-Control-Max-Age",
"Content-Transfer-Encoding",
"Content-Type",
"Expires",
"Pragma",
"Location"
];
/** @codes https://http.cat/ * */
const HTTP_CODE_RESPONSE = [
100 => 'Continue',
101 => 'Switching Protocols',
102 => 'Processing',
200 => 'OK',
201 => 'Created',
202 => 'Accepted',
204 => 'No Content',
206 => 'Partial Content',
207 => 'Multi-Status',
300 => 'Multiple Choices',
301 => 'Moves Permanently',
302 => 'Found',
303 => 'See Other',
304 => 'Not Modified',
305 => 'Use Proxy',
307 => 'Temporary Redirect',
308 => 'Permanent Redirect',
400 => 'Bad Request',
401 => 'Unauthorized',
402 => 'Payment Required',
403 => 'Forbidden',
404 => 'Not Found',
405 => 'Method Not Allowed',
406 => 'Not Acceptable',
408 => 'Request Timeout',
409 => 'Conflict',
410 => 'Gone',
411 => 'Length Required',
412 => 'Precondition Failed',
413 => 'Payload Too Large',
414 => 'Request-URI Too Long',
415 => 'Unsupported Media Type',
416 => 'Request Range Not Satisfiable',
417 => 'Expectation Failed',
418 => 'Im a teapot',
420 => 'Enhance Your Calm',
421 => 'Misdirected Request',
422 => 'Unprocessable Entity',
423 => 'Locked',
424 => 'Failed Dependency',
425 => 'Too Early',
426 => 'Upgrade Required',
429 => 'Too Many Requests',
431 => 'Request Header Fields Too Large',
444 => 'No Response',
450 => 'Blocked by Windows Parental Controls',
451 => 'Unavailable For Legal Reasons',
499 => 'Client Closed Request',
500 => 'Internal Server Error',
501 => 'Not Implemented',
502 => 'Bad Gateway',
503 => 'Service Unavailable',
504 => 'Gateway Timeout',
506 => 'Variant Also Negotiates',
507 => 'Insufficient Storage',
508 => 'Loop Detected',
509 => 'Bandwidth Limit Exceeded',
510 => 'Not Extended',
511 => 'Network Authentication Required',
599 => 'Network Connect Timeout Error'
];
/**
* This variable set methods to use headers
* @var $methods
*/
private $methods = [];
/**
* This variable for logs
* @var $log
*/
private $log;
/**
* This variable for set new configs.
* @var $config
*/
private $config;
########################################################################
##### CLASS METHODS #####
########################################################################
function __construct($config = null)
{
$this->config($config);
$this->blockRequest();
}
public function config($config)
{
if ($config) {
foreach ($config as $key => $val) {
$this->config[strtoupper($key)] = $val;
}
}
return $this->config;
}
public function API()
{
$this->methods([
"Access-Control-Allow-Origin" => ['*'],
"Content-Type" => "application/json; charset=UTF-8",
"Access-Control-Allow-Methods" => ['GET', 'POST', 'PUT', 'DELETE'],
"Access-Control-Max-Age" => 0,
"Access-Control-Allow-Headers" => ['Origin', 'X-Requested-With', 'Content-Type', 'Accept', 'Authorization']
]);
$this->bootstrap();
}
public function response($code)
{
if (array_key_exists($code, self::HTTP_CODE_RESPONSE)) {
header("HTTP/1.0 {$code} " . self::HTTP_CODE_RESPONSE[$code]);
}
}
public function redirect($url = null)
{
$redirect = ($url ? $url : $this->config['REDIRECT']);
if (strpos('http://', $redirect) === false && strpos('https://', $redirect) === false) {
$redirect = "http://$redirect";
}
$this->methods([
"Location" => ($redirect)
]);
$this->bootstrap();
}
public function fileTransfer($name, $file, $mimetype)
{
$this->methods([
"Content-Description" => 'File Transfer',
"Content-Transfer-Encoding" => "binary",
"Content-Type" => $mimetype,
"Cache-Control" => "must-revalidate",
"Content-Length" => filesize($file),
"Content-Disposition" => "attachment; filename=" . basename($name . "." . explode('/', $mimetype)[1]),
"Expires" => 0,
"Pragma" => 'public'
]);
$this->bootstrap();
ob_end_clean();
ob_start();
readfile($file);
unlink($file);
ob_flush();
}
########################################################################
##### PRIVATE METHODS #####
########################################################################
private function bootstrap($header = null)
{
if (!$header && !$this->getMethods()) {
return null;
}
foreach ($header as $key => $val) {
if (!in_array($key, $this->headers)) {
array_push($this->headers, $key);
}
}
$this->methods($header);
$this->headers();
$this->clean();
}
private function blockRequest()
{
if ($this->config['BLOCK_REQUEST']) {
if (is_array($this->config['BLOCK_REQUEST'])) {
if (in_array($_SERVER['REMOTE_ADDR'], $this->config['BLOCK_REQUEST'])) {
$this->log->info("BLOCK REQUEST: " . $_SERVER['REMOTE_ADDR']);
$this->response(301);
$this->redirect(($this->config['REDIRECT'] ? $this->config['REDIRECT'] : 'index.php'));
exit(0);
}
} else if ($_SERVER['REMOTE_ADDR'] == $this->config['BLOCK_REQUEST']) {
$this->log->info("BLOCK REQUEST: " . $_SERVER['REMOTE_ADDR']);
$this->response(301);
$this->redirect($this->config['REDIRECT']);
exit(0);
}
}
}
private function headers()
{
foreach ($this->methods as $key => $header) {
if (in_array($key, $this->headers)) {
header("{$key}: {$header}");
}
}
}
private function methods($header)
{
foreach ($header as $key => $val) {
$method = str_replace(' ', '-', ucwords(str_replace('-', ' ', $key)));
if (is_array($val)) {
$this->methods[$method] = implode(',', $val);
} else {
$this->methods[$method] = $val;
}
}
}
private function clean()
{
unset($this->methods);
}
########################################################################
##### GETS AND SETTERS #####
########################################################################
function getMethods()
{
return $this->methods;
}
}

9
bd

@ -0,0 +1,9 @@
HOST_DB="127.0.0.1"
BASE_DB="pbx"
USUARIO="contacte"
SENHA="ctepgSQL"
PORTA_DB="5432"
HOST_SCK="127.0.0.1"
PORTA_SCK="5038"
USUARIO_SCK="manager"
SENHA_SCK="manager007"

17
composer.json

@ -0,0 +1,17 @@
{
"name": "simplesip/whatsapp",
"description": "Projeto WhatsApp",
"authors": [
{
"name": "Simples IP Desenvolvimento",
"email": "lucasawade46@gmail.com"
}
],
"autoload": {
"psr-4": {
"app\\": "app/",
"scripts\\": "scripts/"
}
},
"require": {}
}

18
composer.lock generated

@ -0,0 +1,18 @@
{
"_readme": [
"This file locks the dependencies of your project to a known state",
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "824e80b41f5059974728f7d2650347b2",
"packages": [],
"packages-dev": [],
"aliases": [],
"minimum-stability": "stable",
"stability-flags": [],
"prefer-stable": false,
"prefer-lowest": false,
"platform": [],
"platform-dev": [],
"plugin-api-version": "2.0.0"
}

14
config/agent.php

@ -0,0 +1,14 @@
<?php
/*
|--------------------------------------------------------------------------
| Eventos
|--------------------------------------------------------------------------
|
| Eventos utilizados pelo gerenciamento dos atendimentos.
|
*/
define("CONF_AGENT_STATUS_LIVRE", 'LIVRE');
define("CONF_AGENT_STATUS_OCUPADO", 'OCUPADO');
define("CONF_AGENT_STATUS_PAUSA", 'PAUSA');
define("CONF_AGENT_STATUS_CHAMANDO", 'CHAMANDO');

59
config/app.php

@ -0,0 +1,59 @@
<?php
/*
|--------------------------------------------------------------------------
| Nome Agente Resposta
|--------------------------------------------------------------------------
|
| Nome que apresentará as mensages de comando
|
*/
define("CONF_NAME_REPONSE", 'Simples IP');
/*
|--------------------------------------------------------------------------
| Log
|--------------------------------------------------------------------------
|
| Local para armazenar os dados referente a API utilzada.
|
*/
define("CONF_LOG_PATH", '/var/www/html/aplicativo/integracao/media/storage/log/');
/*
|--------------------------------------------------------------------------
| Configuracao de Middleware
|--------------------------------------------------------------------------
|
| Redirecionamento para página inicial do projeto
|
*/
define('CONF_MIDDLEWARE_REDIRECT', '192.168.115.65');
define('CONF_MIDDLEWARE_LINKUPLOAD', 'http://devwpp.simplesip.com.br:8090/integracao/media/');
/*
|--------------------------------------------------------------------------
| Configuracao do Banco de dados
|--------------------------------------------------------------------------
|
| Credencias para a conexão com o banco de dados
|
*/
define('CONF_DB_DRIVER', 'pgsql');
define('CONF_DB_HOST', '127.0.0.1');
define('CONF_DB_PORT', '5432');
define('CONF_DB_BASE', 'pbx');
define('CONF_DB_USER', '');
define('CONF_DB_PASSWD', '');
/*
|--------------------------------------------------------------------------
| Configuracao de Protocolo
|--------------------------------------------------------------------------
|
| Configuração geral de protocolo
|
*/
define('CONF_PROTOCOL_TENTATIVAS_GERAR', 5);

15
config/display_errors.php

@ -0,0 +1,15 @@
<?php
error_reporting(E_ERROR | E_WARNING);
ini_set('display_errors', CONF_LOG_DISPLAY_ACTIVE);
ini_set("memory_limit", "512M");
$filename = CONF_LOG_PATH . CONF_LOG_DISPLAY_NAME;
if (!file_exists($filename)) {
file_put_contents($filename, '');
exec(" chown pbx:pbx {$filename}");
}
ini_set('log_errors', CONF_LOG_DISPLAY_ACTIVE);
ini_set('error_log', $filename);
ini_set('log_errors_max_len', 4096);

20
config/event.php

@ -0,0 +1,20 @@
<?php
/*
|--------------------------------------------------------------------------
| Eventos
|--------------------------------------------------------------------------
|
| Eventos utilizados pelo gerenciamento dos atendimentos.
|
*/
// define("CONF_EVENT_WHATSAPP_ATENDIDA", 'MD_ATENDIDA');
define("CONF_EVENT_WHATSAPP_ESPERA", 'MD_EMESPERA');
// define("CONF_EVENT_WHATSAPP_CANCELADA", 'MD_CANCELADO');
define("CONF_EVENT_WHATSAPP_TIMEOUT_CLIENTE", 'MD_TIMEOUT_CALLER');
define("CONF_EVENT_WHATSAPP_TIMEOUT_AGENTE", 'MD_TIMEOUT_AGENT');
define("CONF_EVENT_WHATSAPP_TIMERMINO_CLIENTE", 'MD_COMPLETE_CALLER');
define("CONF_EVENT_WHATSAPP_TIMERMINO_AGENTE", 'MD_COMPLETE_AGENT');
define("CONF_EVENT_WHATSAPP_ABANDONADA", 'MD_ABANDON');
// define("CONF_EVENT_WHATSAPP_OCUPADO", 'MD_OCUPADO');

16
config/helpers.php

@ -0,0 +1,16 @@
<?php
use app\Providers\Logger;
function logger($name = null, $active = true)
{
return new Logger(($name ? $name . "_" . date('Ymd') : 'logger_' . date('Ymd')), $active, CONF_LOG_PATH);
}
function whereIn($array)
{
if (is_array($array)) {
return "'" . implode("','", $array) . "'";
}
return "'$array'";
}

32
config/log.php

@ -0,0 +1,32 @@
<?php
/*
|--------------------------------------------------------------------------
| Display Error
|--------------------------------------------------------------------------
|
| Configuracao do arquivo log display_error
|
*/
define("CONF_LOG_DISPLAY_ACTIVE", true);
define("CONF_LOG_DISPLAY_NAME",'display_errors.log');
/*
|--------------------------------------------------------------------------
| Log Controllers
|--------------------------------------------------------------------------
|
|
*/
define("CONF_LOG_CONTROLLERS_ACTIVE", true);
define("CONF_LOG_CONTROLLERS_NAME",'controllers.log');
/*
|--------------------------------------------------------------------------
| Log Database
|--------------------------------------------------------------------------
|
|
*/
define("CONF_LOG_DATABASE_ACTIVE", true);
define("CONF_LOG_DATABASE_NAME",'database.log');

25
config/middleware.php

@ -0,0 +1,25 @@
<?php
/*
|--------------------------------------------------------------------------
| Configuracao do Middleware
|--------------------------------------------------------------------------
|
| Variaveis gerenericas para serem iniciadas no momento que o projeto for
| executado.
|
*/
return $config = [
'REDIRECT' => CONF_MIDDLEWARE_REDIRECT,
/** @BLOCK_REQUEST CONDUZ REDIRECIONAMENTOS DE REQUISICOES INVALIDAS E BLOQUEADAS * */
'BLOCK_REQUEST' => [],
/** @ACCEPT_HEADERS LIBERA HEADERS PARA SEREM UTILIZANDOS * */
'ACCEPT_HEADERS' => ['Location', 'Access-Control-Allow-Origin', 'Access-Control-Max-Age', 'Expires'],
/** @API_HEADER DEFINE OS HEADERS E SEUS VALORES PARA COMPOR A ESTRUTURA DAS API * */
'API_HEADER' => [],
/** @DOWNLOAD_HEADER DEFINE OS HEADERS E SEUS VALORES PARA TRANSFERENCIA DE ARQUIVOS * */
'DOWNLOAD_HEADER' => ["Cache-Control" => 'must-revalidate', 'Connection' => 'close'],
/** @LINK_UPLOAD DEFINE A URL QUE SERA UTILIZADA PARA FAZER O UPLOAD DOS ARQUIVOS DE WHATSAPP * */
'LINK_UPLOAD' => CONF_MIDDLEWARE_LINKUPLOAD
];

60
config/telegram.php

@ -0,0 +1,60 @@
<?php
/*
|--------------------------------------------------------------------------
| Auth
|--------------------------------------------------------------------------
|
| Local para armazenar os dados referente a API utilzada.
|
*/
define("CONF_TELEGRAM_AUTH_TOKEN", 'eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJhdWQiOiIxIiwianRpIjoiNGViZDYxOTJmMThhNTU2OGVlMDQ5ZDM3NDYzYTZmNDg5YjcxYjQyMGNhYzZmYWM0OWI5MjBkMmIxM2MzMzFmZDExMjAzMzhiZDhiODE5NWUiLCJpYXQiOjE2MjA4MzI1MTYsIm5iZiI6MTYyMDgzMjUxNiwiZXhwIjoxNjUyMzY4NTE2LCJzdWIiOiIyOTQ1Iiwic2NvcGVzIjpbXX0.mPLDDdSZuL6XlZbJ_xRNxebZgKKnYPS7Ecuit_8nPKRwLkY4MCuUA7UVWgt7Z7IG6PfNaxWzZtld7qQ_grV469Va_UbGbD342FJnL6iMVrXRv8_ybArS5J65zRR50zclexaKklplRxfebMIo6eovTJrc9kOeUPbfD-vztVB-MEXdW8sH4BTl23p8XVSxRhAegCcd9eA_IDymUpRJ8XPjJ_ZD2KkOXgucBwotl4srE3CweTdbKtCLqZfQcePE0rxxcDN6d4R0vj5TU2ze0iL-jwNUV1Gk4CF6lHqTr-8xqEzNsPHlJSsLFwmrlAqokgVFLA4ktfywBYZmzI6VJRODyqNuA-sf1KKDcWmVy6y1wdbX0pKiE96yHp86IO0Dqb7nZTH035rC7Ml0UTAo0-AmO-1WRS2BCtirBTpP9EGzWtBElwKLpPzokwbiae-GZgykDO9HUbGSm5GV8zvVGRhRNys_kbXjJaL_0DcHevHlcnEQDHqIX0-3fP5uvC5NhFSXBOtzJ796DLYpUXCunAsh5KzDFGdK_VTP6Xhsf2YGofn1okyHgU0J1B-a9F3AZpMYdnv7_FQC_SuZJ8mXFcoFSGI8F6RfjsO9dVY-N6MHsNQ8vWCkf4c4bv0XhBgPz5Uo3kOETpvzQjgmeptC7Wl4G_jG4RoVSjnH-QnLpdrO9zg');
define("CONF_TELEGRAM_AUTH_URL", 'http://192.168.115.75:3003/message/');
/*
|--------------------------------------------------------------------------
| Channel
|--------------------------------------------------------------------------
|
| Informa o tipo de midia utilizado para gravar no banco de dados.
| -> Facilita da identificacao durante um atendimento.
|
*/
define("CONF_TELEGRAM_CHANNEL", 'TELEGRAM');
/*
|--------------------------------------------------------------------------
| Database
|--------------------------------------------------------------------------
|
| Anexa um prefixo nas tabelas do banco de dados.
| -> Em caso de tabelas separadas para o controle de dados.
|
*/
define("CONF_TELEGRAM_DATABASE", '');
/*
|--------------------------------------------------------------------------
| Timeout
|--------------------------------------------------------------------------
|
| Informa o tempo em segundos para os tipos de alertas.
|
*/
define("CONF_TELEGRAM_TIMEOUT_CLIENT_AVISO_RESPOSTA", 120);
define("CONF_TELEGRAM_TIMEOUT_CLIENT_RESPOSTA", 180);
define("CONF_TELEGRAM_TIMEOUT_AGENT_AVISO", 1800);
define("CONF_TELEGRAM_TIMEOUT_AGENT_DESCONEXAO", 1980);
define("CONF_TELEGRAM_TIMEOUT_AGENT_CLASSIFICACAO", 180);
/*
|--------------------------------------------------------------------------
| Log
|--------------------------------------------------------------------------
|
| Informacoes de local e atividade do registro de log e o nome do arquivo.
|
*/
define("CONF_TELEGRAM_LOG_NAME_PATH", 'whatsapp');
define("CONF_TELEGRAM_LOG_ACTIVE", true);

60
config/whatsapp.php

@ -0,0 +1,60 @@
<?php
/*
|--------------------------------------------------------------------------
| Auth
|--------------------------------------------------------------------------
|
| Local para armazenar os dados referente a API utilzada.
|
*/
define("CONF_WHATSAPP_AUTH_TOKEN", 'eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJhdWQiOiIxIiwianRpIjoiNGViZDYxOTJmMThhNTU2OGVlMDQ5ZDM3NDYzYTZmNDg5YjcxYjQyMGNhYzZmYWM0OWI5MjBkMmIxM2MzMzFmZDExMjAzMzhiZDhiODE5NWUiLCJpYXQiOjE2MjA4MzI1MTYsIm5iZiI6MTYyMDgzMjUxNiwiZXhwIjoxNjUyMzY4NTE2LCJzdWIiOiIyOTQ1Iiwic2NvcGVzIjpbXX0.mPLDDdSZuL6XlZbJ_xRNxebZgKKnYPS7Ecuit_8nPKRwLkY4MCuUA7UVWgt7Z7IG6PfNaxWzZtld7qQ_grV469Va_UbGbD342FJnL6iMVrXRv8_ybArS5J65zRR50zclexaKklplRxfebMIo6eovTJrc9kOeUPbfD-vztVB-MEXdW8sH4BTl23p8XVSxRhAegCcd9eA_IDymUpRJ8XPjJ_ZD2KkOXgucBwotl4srE3CweTdbKtCLqZfQcePE0rxxcDN6d4R0vj5TU2ze0iL-jwNUV1Gk4CF6lHqTr-8xqEzNsPHlJSsLFwmrlAqokgVFLA4ktfywBYZmzI6VJRODyqNuA-sf1KKDcWmVy6y1wdbX0pKiE96yHp86IO0Dqb7nZTH035rC7Ml0UTAo0-AmO-1WRS2BCtirBTpP9EGzWtBElwKLpPzokwbiae-GZgykDO9HUbGSm5GV8zvVGRhRNys_kbXjJaL_0DcHevHlcnEQDHqIX0-3fP5uvC5NhFSXBOtzJ796DLYpUXCunAsh5KzDFGdK_VTP6Xhsf2YGofn1okyHgU0J1B-a9F3AZpMYdnv7_FQC_SuZJ8mXFcoFSGI8F6RfjsO9dVY-N6MHsNQ8vWCkf4c4bv0XhBgPz5Uo3kOETpvzQjgmeptC7Wl4G_jG4RoVSjnH-QnLpdrO9zg');
define("CONF_WHATSAPP_AUTH_URL", 'https://api.positus.global/v2/whatsapp/numbers/ea4c9088-e34e-49ce-ba02-8ea55e6fdaa4/');
/*
|--------------------------------------------------------------------------
| Channel
|--------------------------------------------------------------------------
|
| Informa o tipo de midia utilizado para gravar no banco de dados.
| -> Facilita da identificacao durante um atendimento.
|
*/
define("CONF_WHATSAPP_CHANNEL", 'WHATSAPP');
/*
|--------------------------------------------------------------------------
| Database
|--------------------------------------------------------------------------
|
| Anexa um prefixo nas tabelas do banco de dados.
| -> Em caso de tabelas separadas para o controle de dados.
|
*/
define("CONF_WHATSAPP_DATABASE", '');
/*
|--------------------------------------------------------------------------
| Timeout
|--------------------------------------------------------------------------
|
| Informa o tempo em segundos para os tipos de alertas.
|
*/
define("CONF_WHATSAPP_TIMEOUT_CLIENT_AVISO_RESPOSTA", 120);
define("CONF_WHATSAPP_TIMEOUT_CLIENT_RESPOSTA", 180);
define("CONF_WHATSAPP_TIMEOUT_AGENT_AVISO", 1800);
define("CONF_WHATSAPP_TIMEOUT_AGENT_DESCONEXAO", 1980);
define("CONF_WHATSAPP_TIMEOUT_AGENT_CLASSIFICACAO", 180);
/*
|--------------------------------------------------------------------------
| Log
|--------------------------------------------------------------------------
|
| Informacoes de local e atividade do registro de log e o nome do arquivo.
|
*/
define("CONF_WHATSAPP_LOG_NAME_PATH", 'whatsapp');
define("CONF_WHATSAPP_LOG_ACTIVE", true);

282
database/att-v2.sql

@ -0,0 +1,282 @@
CREATE TABLE pbx_notifica_media (
id SERIAL NOT NULL PRIMARY KEY,
uniqueid character varying NOT NULL,
src character varying NOT NULL,
msg character varying NOT NULL,
notif_date timestamp WITHOUT TIME ZONW DEFAULT(NOW())
);
CREATE TABLE pbx_lista_negra_palavras (
id SERIAL NOT NULL PRIMARY KEY,
palavra character varying NOT NULL,
date_create timestamp WITHOUT TIME ZONW DEFAULT(NOW())
);
INSERT INTO
pbx_lista_negra_palavras (palavra)
VALUES
('Anus'),
('Baba-ovo'),
('Babaovo'),
('Babaca'),
('Bacura'),
('Bagos'),
('Baitola'),
('Bebum'),
('Besta'),
('Bicha'),
('Bisca'),
('Bixa'),
('Boazuda'),
('Boceta'),
('Boco'),
('Boiola'),
('Bolagato'),
('Boquete'),
('Bolcat'),
('Bosseta'),
('Bosta'),
('Bostana'),
('Brecha'),
('Brexa'),
('Brioco'),
('Bronha'),
('Buca'),
('Buceta'),
('Bunda'),
('Bunduda'),
('Burra'),
('Burro'),
('Busseta'),
('Cachorra'),
('Cachorro'),
('Cadela'),
('Caga'),
('Cagado'),
('Cagao'),
('Cagona'),
('Canalha'),
('Caralho'),
('Casseta'),
('Cassete'),
('Checheca'),
('Chereca'),
('Chibumba'),
('Chibumbo'),
('Chifruda'),
('Chifrudo'),
('Chota'),
('Chochota'),
('Chupada'),
('Chupado'),
('Clitoris'),
('Cocaina'),
('Coco'),
('Corna'),
('Corno'),
('Cornuda'),
('Cornudo'),
('Corrupta'),
('Corrupto'),
('Cretina'),
('Cretino'),
('Cruz-credo'),
('Cu'),
('Culhao'),
('Curalho'),
('Cuzao'),
('Cuzuda'),
('Cuzudo'),
('Debil'),
('Debiloide'),
('Defunto'),
('Demonio'),
('Difunto'),
('Doida'),
('Doido'),
('Egua'),
('Escrota'),
('Escroto'),
('Esporrada'),
('Esporrado'),
('Esporro'),
('Estupida'),
('Estupidez'),
('Estupido'),
('Fedida'),
('Fedido'),
('Fedor'),
('Fedorenta'),
('Feia'),
('Feio'),
('Feiosa'),
('Feioso'),
('Feioza'),
('Feiozo'),
('Felacao'),
('Fenda'),
('Foda'),
('Fodao'),
('Fode'),
('FodidaFodido'),
('Fornica'),
('Fudendo'),
('Fudecao'),
('Fudida'),
('Fudido'),
('Furada'),
('Furado'),
('Furão'),
('Furnica'),
('Furnicar'),
('Furo'),
('Furona'),
('Gaiata'),
('Gaiato'),
('Gay'),
('Gonorrea'),
('Gonorreia'),
('Gosma'),
('Gosmenta'),
('Gosmento'),
('Grelinho'),
('Grelo'),
('Homo-sexual'),
('Homossexual'),
('Homossexual'),
('Idiota'),
('Idiotice'),
('Imbecil'),
('Iscrota'),
('Iscroto'),
('Japa'),
('Ladra'),
('Ladrao'),
('Ladroeira'),
('Ladrona'),
('Lalau'),
('Leprosa'),
('Leproso'),
('Lésbica'),
('Macaca'),
('Macaco'),
('Machona'),
('Machorra'),
('Manguaca'),
('Mangua¦a'),
('Masturba'),
('Meleca'),
('Merda'),
('Mija'),
('Mijada'),
('Mijado'),
('Mijo'),
('Mocrea'),
('Mocreia'),
('Moleca'),
('Moleque'),
('Mondronga'),
('Mondrongo'),
('Naba'),
('Nadega'),
('Nojeira'),
('Nojenta'),
('Nojento'),
('Nojo'),
('Olhota'),
('Otaria'),
('Ot-ria'),
('Otario'),
('Ot-rio'),
('Paca'),
('Paspalha'),
('Paspalhao'),
('Paspalho'),
('Pau'),
('Peia'),
('Peido'),
('Pemba'),
('Pênis'),
('Pentelha'),
('Pentelho'),
('Perereca'),
('Peru'),
('Pica'),
('Picao'),
('Pilantra'),
('Piranha'),
('Piroca'),
('Piroco'),
('Piru'),
('Porra'),
('Prega'),
('Prostibulo'),
('Prost-bulo'),
('Prostituta'),
('Prostituto'),
('Punheta'),
('Punhetao'),
('Pus'),
('Pustula'),
('Puta'),
('Puto'),
('Puxa-saco'),
('Puxasaco'),
('Rabao'),
('Rabo'),
('Rabuda'),
('Rabudao'),
('Rabudo'),
('Rabudona'),
('Racha'),
('Rachada'),
('Rachadao'),
('Rachadinha'),
('Rachadinho'),
('Rachado'),
('Ramela'),
('Remela'),
('Retardada'),
('Retardado'),
('Ridícula'),
('Rola'),
('Rolinha'),
('Rosca'),
('Sacana'),
('Safada'),
('Safado'),
('Sapatao'),
('Sifilis'),
('Siririca'),
('Tarada'),
('Tarado'),
('Testuda'),
('Tezao'),
('Tezuda'),
('Tezudo'),
('Trocha'),
('Trolha'),
('Troucha'),
('Trouxa'),
('Troxa'),
('Vaca'),
('Vagabunda'),
('Vagabundo'),
('Vagina'),
('Veada'),
('Veadao'),
('Veado'),
('Viada'),
('Víado'),
('Viado'),
('Viadao'),
('Xavasca'),
('Xerereca'),
('Xexeca'),
('Xibiu'),
('Xibumba'),
('Xota'),
('Xochota'),
('Xoxota'),
('Xana'),
('Xaninha');

20
database/database.sql

@ -0,0 +1,20 @@
CREATE TABLE pbx_message_wpp (
id SERIAL NOT NULL PRIMARY KEY,
uniqueid character varying NOT NULL,
src character varying NOT NULL,
dst character varying NOT NULL,
type character varying NOT NULL,
content character varying NOT NULL,
profile_name character varying NOT NULL,
msg_date timestamp WITHOUT TIME ZONW DEFAULT(NOW())
);
ALTER TABLE
pbx_queues_grupos
ADD
COLUMN midiafila VARCHAR(1);
ALTER TABLE
pbx_sip_ramais
ADD
COLUMN midiaramal VARCHAR(1);

117
includes/config.php

@ -0,0 +1,117 @@
<?php
/*
|--------------------------------------------------------------------------
| Realiza todos os includes do projeto para objeter as variaveis gerais
|--------------------------------------------------------------------------
|
| Para que o projeto fique organizado todos os novas variaveis devem conter
| um arquivo de configuracao dentro da pasta "/config" e seu respectivo nome
| intuitivo, para uma melhor entendimento.
|
*/
/*
|--------------------------------------------------------------------------
| Configuracao GERAL
|--------------------------------------------------------------------------
|
| Arquivo padrao de gerar logs do projeto.
|
*/
if (file_exists(__DIR__ . '/../config/app.php')) {
require __DIR__ . '/../config/app.php';
}
/*
|--------------------------------------------------------------------------
| Functions Helpers
|--------------------------------------------------------------------------
|
| Inclusão para funções de terceiros ou utilitario para ser acessado de forma
| rápida.
|
*/
if (file_exists(__DIR__ . '/../config/helpers.php')) {
require __DIR__ . '/../config/helpers.php';
}
/*
|--------------------------------------------------------------------------
| Configuracao de Logs
|--------------------------------------------------------------------------
|
| Arquivo padrao de gerar logs do projeto.
|
*/
if (file_exists(__DIR__ . '/../config/log.php')) {
require __DIR__ . '/../config/log.php';
}
/*
|--------------------------------------------------------------------------
| Configuracao dos Eventos
|--------------------------------------------------------------------------
|
| Importacao das variaveis de eventos a serem utilizadas para gravas os tipos
| no banco de dados.
|
*/
if (file_exists(__DIR__ . '/../config/event.php')) {
require __DIR__ . '/../config/event.php';
}
/*
|--------------------------------------------------------------------------
| Configuracao do WhatsApp
|--------------------------------------------------------------------------
|
| Variaveis de configuracao do WhatsApp.
|
*/
if (file_exists(__DIR__ . '/../config/whatsapp.php')) {
require __DIR__ . '/../config/whatsapp.php';
}
/*
|--------------------------------------------------------------------------
| Configuracao do Middleware
|--------------------------------------------------------------------------
|
| Variaveis para inicializacao do Middleware.
|
*/
if (file_exists(__DIR__ . '/../config/middleware.php')) {
require __DIR__ . '/../config/middleware.php';
}
/*
|--------------------------------------------------------------------------
| Configuracao do Agent
|--------------------------------------------------------------------------
|
*/
if (file_exists(__DIR__ . '/../config/agent.php')) {
require __DIR__ . '/../config/agent.php';
}
/*
|--------------------------------------------------------------------------
| Configuracao do Display Erros
|--------------------------------------------------------------------------
|
*/
if (file_exists(__DIR__ . '/../config/display_errors.php')) {
require __DIR__ . '/../config/display_errors.php';
}
/*
|--------------------------------------------------------------------------
| Configuracao do telegram
|--------------------------------------------------------------------------
|
| Variaveis de configuracao do telegram.
|
*/
if (file_exists(__DIR__ . '/../config/telegram.php')) {
require __DIR__ . '/../config/telegram.php';
}

9
index.php

@ -0,0 +1,9 @@
<?php
require __DIR__ . '/vendor/autoload.php';
include __DIR__ . '/includes/config.php';
use app\Middleware\Middleware;
$middle = new Middleware($config);
$middle->api();

211
scripts/service/monitora_agente_wpp.php

@ -0,0 +1,211 @@
#!/usr/bin/php -q
<?php
require __DIR__ . '/../../vendor/autoload.php';
require __DIR__ . '/../../includes/config.php';
error_reporting(E_ERROR);
ini_set('display_errors', 0);
use app\Controllers\AgentController;
use app\Controllers\BilheteController;
use app\Controllers\MessageController;
use app\Controllers\ClassificacaoController;
use app\Controllers\SupervisorQueueController;
use app\Core\Connect;
use app\Core\CoreMedia;
use app\Providers\Positus;
use app\Core\Media;
use app\Core\WhatsApp;
use app\Models\Message;
use app\Models\NotificaMedia;
use app\Providers\ApiTelegram;
$agente = new AgentController();
$bilhete = new BilheteController();
$message = new MessageController();
$media = new CoreMedia();
$media2 = new Media();
$notificaMedia = new NotificaMedia();
$mensages = new Message();
$classificacao = new ClassificacaoController();
$supervisor = new SupervisorQueueController();
/*
* Para rodar como um processo normal é preciso passar "N" como primeiro parametro.
*/
$notDaemon = isset($argv[1]) && (strtoupper($argv[1]) === 'N');
/*
* Inicializa o daemom quando N não for informado.
*/
GetDaemon($notDaemon);
declare(ticks=1);
$statusSignal = 0;
pcntl_signal(SIGTERM, "sig_handler");
pcntl_signal(SIGHUP, "sig_handler");
pcntl_signal(SIGUSR1, "sig_handler");
pcntl_signal(SIGINT, "sig_handler");
$timeout_agent_alert = (CONF_WHATSAPP_TIMEOUT_AGENT_AVISO / 60);
$timeout_agent_desconexao = (CONF_WHATSAPP_TIMEOUT_AGENT_DESCONEXAO / 60);
$timeout_agent_classificacao = (CONF_WHATSAPP_TIMEOUT_AGENT_CLASSIFICACAO / 60);
$mensagem = [
"ALERTA_INATIVIDADE" => "Você será desconectado em " . ($timeout_agent_desconexao - $timeout_agent_alert) . " minutos, para permanecer em atendimento clique em '/presente'",
"ALERTA_DESCONECTADO" => "Você foi desconectado por inatividade!",
"ALERTA_CLIENTE" => "Olá, como podemos lhe ajudar!",
"TIMEOUT_CLIENT_INATIVIDADE" => "O tempo da conversa foi expirado, por favor volte novamente a fila para um novo atendimento!",
"TALK_FINISHED" => "O atendimento foi finalizado!",
"TALK_ALERT_FINISH" => "Por favor, volte a comunicação com nosso atendimento em 1 minuto ou atendimento será encerrado!"
];
while (true) {
try {
$agentesLista = $agente->inactiveAgents();
foreach ($agentesLista as $item) {
$positus = retornaApiMedia($item['SALA1']);
$freetime = $item['FREETIME'] / 60;
if (($freetime >= $timeout_agent_alert) && ($freetime < $timeout_agent_desconexao) && !$item['SALA2'] && $item['STATUS'] == CONF_AGENT_STATUS_LIVRE) {
$agente->timeFinishAgente($item['MATRICULA'], $item['RAMAL'], ($timeout_agent_desconexao - $timeout_agent_alert));
$positus->enviarMsgIterativaBotao($item['RAMAL'], $mensagem['ALERTA_INATIVIDADE'], [
[
"type" => "reply",
"reply" => [
"id" => "unique-postback-id-1",
"title" => utf8_encode("/presente")
]
]
]);
} else if ($freetime >= $timeout_agent_desconexao && $item['STATUS'] == CONF_AGENT_STATUS_LIVRE) {
$agente->logoff($item['RAMAL']);
$positus->enviarMsg($item['RAMAL'], utf8_encode($mensagem['ALERTA_DESCONECTADO']));
} else {
$agente->refreshAgent($item['RAMAL'], $item['SALA2']);
}
if ($item['STATUS'] == CONF_AGENT_STATUS_LIVRE) {
$chamadaSemClassificacao = $classificacao->agentClassificacaoPending($item['MATRICULA'], $item['FILA']);
if ($chamadaSemClassificacao) { //BLOQUEAR ATENDIMENTO SEM CLASSIFICACAO
if ($item['FREETIME'] % $timeout_agent_classificacao == 0) {
$classificacaoList = $classificacao->agentClassificacaoList($item['FILA']);
$retorno = $notificaMedia->verificaNotifica(
$chamadaSemClassificacao,
$item['RAMAL'],
utf8_encode(CONF_NAME_REPONSE . " : " . $classificacaoList)
);
if ($retorno->quant == 0) {
$notificaMedia->addNotifica(
$chamadaSemClassificacao,
$item['RAMAL'],
utf8_encode(CONF_NAME_REPONSE . " : " . $classificacaoList)
);
$positus->enviarMsg(
$item['RAMAL'],
utf8_encode(CONF_NAME_REPONSE . " : " . $classificacaoList)
);
}
}
continue;
}
$atendimento = $bilhete->bilheteForaHorario(CONF_EVENT_WHATSAPP_ESPERA, $item['FILA'], null, $item['SALA1']);
if ($atendimento) {
/**
* VALIDA O ATENDIMENTO
*/
$response = $media->validaAtendimento($positus, $atendimento[0]->fila, null, $atendimento[0]->src, $item['SALA1']);
$bilhete->atenderBilheteForaHorario($atendimento[0]->uniqueid, $atendimento[0]->src, $atendimento[0]->fila, $item['MATRICULA'], $response['DATA']['uniqueid']);
$atendimento = $bilhete->bilheteForaHorario(CONF_EVENT_WHATSAPP_ESPERA, $item['FILA'], null, $item['SALA1']);
foreach ($atendimento as $cliente) {
$mensagemFila = 'Você está na posição ' . $media2->getClientQueueData($cliente->src, $atendimento)['QUEUE_POSITION'] . '. Aguarde ser atendido!';
$positus->enviarMsg($cliente->src, utf8_encode($mensagemFila));
}
}
}
if ($item['STATUS'] == CONF_AGENT_STATUS_OCUPADO) {
if ($message->timeoutTalk($item['UNIQUEID'], $item['RAMAL']) == 'FINISH' && $agente->closeService($item['ORIGEM_DESTINO'], CONF_EVENT_WHATSAPP_TIMEOUT_CLIENTE, $item['SALA1'])) {
$positus->enviarMsg($item['ORIGEM_DESTINO'], utf8_encode($mensagem['TIMEOUT_CLIENT_INATIVIDADE']));
$positus->enviarMsg($item['ORIGEM_DESTINO'], utf8_encode($mensagem['TALK_FINISHED']));
$positus->enviarMsg($item['RAMAL'], utf8_encode($mensagem['TALK_FINISHED']));
}
if ($message->timeoutTalk($item['UNIQUEID'], $item['RAMAL']) == 'ALERT') {
$msg = $mensages->findLastMessage($item['UNIQUEID']);
$retorno = $notificaMedia->verificaNotifica(
$item['UNIQUEID'],
$item['ORIGEM_DESTINO'],
utf8_encode($mensagem['TALK_ALERT_FINISH']) . $msg->id
);
if ($retorno->quant == 0) {
$notificaMedia->addNotifica(
$item['UNIQUEID'],
$item['ORIGEM_DESTINO'],
utf8_encode($mensagem['TALK_ALERT_FINISH']) . $msg->id
);
$positus->enviarMsg(
$item['ORIGEM_DESTINO'],
utf8_encode($mensagem['TALK_ALERT_FINISH'])
);
}
}
}
$supervisor->calcTimeAwait();
}
sleep(3);
ignore_user_abort(true);
/*
* Verifica se o processo deve ser encerrado
*/
if (sig_status()) {
break;
}
} catch (Exception $ex) {
sleep(3);
Connect::setInstance(null);
logger('testeOff')->info($th->getMessage(), debug_backtrace());
}
}
function retornaApiMedia($media = '')
{
switch ($media) {
case CONF_TELEGRAM_CHANNEL:
return new ApiTelegram();
case CONF_WHATSAPP_CHANNEL:
return new Positus();;
default:
break;
}
}
function GetDaemon($notDaemon)
{
/*
* Se o script não for chamado com daemon sai sem executar nada.
*/
if ($notDaemon) {
return 0;
}
$pid = pcntl_fork();
if ($pid) {
exit(0); //success
}
}
function sig_handler($signo)
{
global $statusSignal;
$statusSignal = 1;
}
function sig_status()
{
global $statusSignal;
pcntl_signal_dispatch();
return $statusSignal;
}

29
scripts/service/request.php

@ -0,0 +1,29 @@
#!/usr/bin/php -q
<?php
require __DIR__ . '/../../vendor/autoload.php';
require __DIR__ . '/../../includes/config.php';
error_reporting(E_ERROR);
ini_set('display_errors', 0);
use app\Controllers\AgentController;
use app\Controllers\BilheteController;
use app\Controllers\MessageController;
use app\Controllers\ClassificacaoController;
use app\Controllers\SupervisorQueueController;
use app\Providers\Positus;
use app\Core\Media;
$agente = new AgentController();
$bilhete = new BilheteController();
$message = new MessageController();
$positus = new Positus();
$media = new Media();
$classificacao = new ClassificacaoController();
$supervisor = new SupervisorQueueController();
$info = $agente->findRamal('556581282842');
print_r($info);

8
scripts/service/teste.php

@ -0,0 +1,8 @@
<?php
$google_url = 'https://translate.google.com.br/translate_tts?ie=UTF-8&q=%se&tl=pt-BR&total=1&idx=0&textlen=5&tk=489936&client=t&prev=input&ttsspeed=0.50';
$text = urlencode('Ola tamba');
$url = sprintf($google_url, $text);
copy($url, 'meu_arquivo.mp3');

7
vendor/autoload.php vendored

@ -0,0 +1,7 @@
<?php
// autoload.php @generated by Composer
require_once __DIR__ . '/composer/autoload_real.php';
return ComposerAutoloaderInit16f85458e9b741f7f2b22e1ee483f627::getLoader();

479
vendor/composer/ClassLoader.php vendored

@ -0,0 +1,479 @@
<?php
/*
* This file is part of Composer.
*
* (c) Nils Adermann <naderman@naderman.de>
* Jordi Boggiano <j.boggiano@seld.be>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Composer\Autoload;
/**
* ClassLoader implements a PSR-0, PSR-4 and classmap class loader.
*
* $loader = new \Composer\Autoload\ClassLoader();
*
* // register classes with namespaces
* $loader->add('Symfony\Component', __DIR__.'/component');
* $loader->add('Symfony', __DIR__.'/framework');
*
* // activate the autoloader
* $loader->register();
*
* // to enable searching the include path (eg. for PEAR packages)
* $loader->setUseIncludePath(true);
*
* In this example, if you try to use a class in the Symfony\Component
* namespace or one of its children (Symfony\Component\Console for instance),
* the autoloader will first look for the class under the component/
* directory, and it will then fallback to the framework/ directory if not
* found before giving up.
*
* This class is loosely based on the Symfony UniversalClassLoader.
*
* @author Fabien Potencier <fabien@symfony.com>
* @author Jordi Boggiano <j.boggiano@seld.be>
* @see https://www.php-fig.org/psr/psr-0/
* @see https://www.php-fig.org/psr/psr-4/
*/
class ClassLoader
{
private $vendorDir;
// PSR-4
private $prefixLengthsPsr4 = array();
private $prefixDirsPsr4 = array();
private $fallbackDirsPsr4 = array();
// PSR-0
private $prefixesPsr0 = array();
private $fallbackDirsPsr0 = array();
private $useIncludePath = false;
private $classMap = array();
private $classMapAuthoritative = false;
private $missingClasses = array();
private $apcuPrefix;
private static $registeredLoaders = array();
public function __construct($vendorDir = null)
{
$this->vendorDir = $vendorDir;
}
public function getPrefixes()
{
if (!empty($this->prefixesPsr0)) {
return call_user_func_array('array_merge', array_values($this->prefixesPsr0));
}
return array();
}
public function getPrefixesPsr4()
{
return $this->prefixDirsPsr4;
}
public function getFallbackDirs()
{
return $this->fallbackDirsPsr0;
}
public function getFallbackDirsPsr4()
{
return $this->fallbackDirsPsr4;
}
public function getClassMap()
{
return $this->classMap;
}
/**
* @param array $classMap Class to filename map
*/
public function addClassMap(array $classMap)
{
if ($this->classMap) {
$this->classMap = array_merge($this->classMap, $classMap);
} else {
$this->classMap = $classMap;
}
}
/**
* Registers a set of PSR-0 directories for a given prefix, either
* appending or prepending to the ones previously set for this prefix.
*
* @param string $prefix The prefix
* @param array|string $paths The PSR-0 root directories
* @param bool $prepend Whether to prepend the directories
*/
public function add($prefix, $paths, $prepend = false)
{
if (!$prefix) {
if ($prepend) {
$this->fallbackDirsPsr0 = array_merge(
(array) $paths,
$this->fallbackDirsPsr0
);
} else {
$this->fallbackDirsPsr0 = array_merge(
$this->fallbackDirsPsr0,
(array) $paths
);
}
return;
}
$first = $prefix[0];
if (!isset($this->prefixesPsr0[$first][$prefix])) {
$this->prefixesPsr0[$first][$prefix] = (array) $paths;
return;
}
if ($prepend) {
$this->prefixesPsr0[$first][$prefix] = array_merge(
(array) $paths,
$this->prefixesPsr0[$first][$prefix]
);
} else {
$this->prefixesPsr0[$first][$prefix] = array_merge(
$this->prefixesPsr0[$first][$prefix],
(array) $paths
);
}
}
/**
* Registers a set of PSR-4 directories for a given namespace, either
* appending or prepending to the ones previously set for this namespace.
*
* @param string $prefix The prefix/namespace, with trailing '\\'
* @param array|string $paths The PSR-4 base directories
* @param bool $prepend Whether to prepend the directories
*
* @throws \InvalidArgumentException
*/
public function addPsr4($prefix, $paths, $prepend = false)
{
if (!$prefix) {
// Register directories for the root namespace.
if ($prepend) {
$this->fallbackDirsPsr4 = array_merge(
(array) $paths,
$this->fallbackDirsPsr4
);
} else {
$this->fallbackDirsPsr4 = array_merge(
$this->fallbackDirsPsr4,
(array) $paths
);
}
} elseif (!isset($this->prefixDirsPsr4[$prefix])) {
// Register directories for a new namespace.
$length = strlen($prefix);
if ('\\' !== $prefix[$length - 1]) {
throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
}
$this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
$this->prefixDirsPsr4[$prefix] = (array) $paths;
} elseif ($prepend) {
// Prepend directories for an already registered namespace.
$this->prefixDirsPsr4[$prefix] = array_merge(
(array) $paths,
$this->prefixDirsPsr4[$prefix]
);
} else {
// Append directories for an already registered namespace.
$this->prefixDirsPsr4[$prefix] = array_merge(
$this->prefixDirsPsr4[$prefix],
(array) $paths
);
}
}
/**
* Registers a set of PSR-0 directories for a given prefix,
* replacing any others previously set for this prefix.
*
* @param string $prefix The prefix
* @param array|string $paths The PSR-0 base directories
*/
public function set($prefix, $paths)
{
if (!$prefix) {
$this->fallbackDirsPsr0 = (array) $paths;
} else {
$this->prefixesPsr0[$prefix[0]][$prefix] = (array) $paths;
}
}
/**
* Registers a set of PSR-4 directories for a given namespace,
* replacing any others previously set for this namespace.
*
* @param string $prefix The prefix/namespace, with trailing '\\'
* @param array|string $paths The PSR-4 base directories
*
* @throws \InvalidArgumentException
*/
public function setPsr4($prefix, $paths)
{
if (!$prefix) {
$this->fallbackDirsPsr4 = (array) $paths;
} else {
$length = strlen($prefix);
if ('\\' !== $prefix[$length - 1]) {
throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
}
$this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
$this->prefixDirsPsr4[$prefix] = (array) $paths;
}
}
/**
* Turns on searching the include path for class files.
*
* @param bool $useIncludePath
*/
public function setUseIncludePath($useIncludePath)
{
$this->useIncludePath = $useIncludePath;
}
/**
* Can be used to check if the autoloader uses the include path to check
* for classes.
*
* @return bool
*/
public function getUseIncludePath()
{
return $this->useIncludePath;
}
/**
* Turns off searching the prefix and fallback directories for classes
* that have not been registered with the class map.
*
* @param bool $classMapAuthoritative
*/
public function setClassMapAuthoritative($classMapAuthoritative)
{
$this->classMapAuthoritative = $classMapAuthoritative;
}
/**
* Should class lookup fail if not found in the current class map?
*
* @return bool
*/
public function isClassMapAuthoritative()
{
return $this->classMapAuthoritative;
}
/**
* APCu prefix to use to cache found/not-found classes, if the extension is enabled.
*
* @param string|null $apcuPrefix
*/
public function setApcuPrefix($apcuPrefix)
{
$this->apcuPrefix = function_exists('apcu_fetch') && filter_var(ini_get('apc.enabled'), FILTER_VALIDATE_BOOLEAN) ? $apcuPrefix : null;
}
/**
* The APCu prefix in use, or null if APCu caching is not enabled.
*
* @return string|null
*/
public function getApcuPrefix()
{
return $this->apcuPrefix;
}
/**
* Registers this instance as an autoloader.
*
* @param bool $prepend Whether to prepend the autoloader or not
*/
public function register($prepend = false)
{
spl_autoload_register(array($this, 'loadClass'), true, $prepend);
if (null === $this->vendorDir) {
return;
}
if ($prepend) {
self::$registeredLoaders = array($this->vendorDir => $this) + self::$registeredLoaders;
} else {
unset(self::$registeredLoaders[$this->vendorDir]);
self::$registeredLoaders[$this->vendorDir] = $this;
}
}
/**
* Unregisters this instance as an autoloader.
*/
public function unregister()
{
spl_autoload_unregister(array($this, 'loadClass'));
if (null !== $this->vendorDir) {
unset(self::$registeredLoaders[$this->vendorDir]);
}
}
/**
* Loads the given class or interface.
*
* @param string $class The name of the class
* @return bool|null True if loaded, null otherwise
*/
public function loadClass($class)
{
if ($file = $this->findFile($class)) {
includeFile($file);
return true;
}
}
/**
* Finds the path to the file where the class is defined.
*
* @param string $class The name of the class
*
* @return string|false The path if found, false otherwise
*/
public function findFile($class)
{
// class map lookup
if (isset($this->classMap[$class])) {
return $this->classMap[$class];
}
if ($this->classMapAuthoritative || isset($this->missingClasses[$class])) {
return false;
}
if (null !== $this->apcuPrefix) {
$file = apcu_fetch($this->apcuPrefix.$class, $hit);
if ($hit) {
return $file;
}
}
$file = $this->findFileWithExtension($class, '.php');
// Search for Hack files if we are running on HHVM
if (false === $file && defined('HHVM_VERSION')) {
$file = $this->findFileWithExtension($class, '.hh');
}
if (null !== $this->apcuPrefix) {
apcu_add($this->apcuPrefix.$class, $file);
}
if (false === $file) {
// Remember that this class does not exist.
$this->missingClasses[$class] = true;
}
return $file;
}
/**
* Returns the currently registered loaders indexed by their corresponding vendor directories.
*
* @return self[]
*/
public static function getRegisteredLoaders()
{
return self::$registeredLoaders;
}
private function findFileWithExtension($class, $ext)
{
// PSR-4 lookup
$logicalPathPsr4 = strtr($class, '\\', DIRECTORY_SEPARATOR) . $ext;
$first = $class[0];
if (isset($this->prefixLengthsPsr4[$first])) {
$subPath = $class;
while (false !== $lastPos = strrpos($subPath, '\\')) {
$subPath = substr($subPath, 0, $lastPos);
$search = $subPath . '\\';
if (isset($this->prefixDirsPsr4[$search])) {
$pathEnd = DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $lastPos + 1);
foreach ($this->prefixDirsPsr4[$search] as $dir) {
if (file_exists($file = $dir . $pathEnd)) {
return $file;
}
}
}
}
}
// PSR-4 fallback dirs
foreach ($this->fallbackDirsPsr4 as $dir) {
if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr4)) {
return $file;
}
}
// PSR-0 lookup
if (false !== $pos = strrpos($class, '\\')) {
// namespaced class name
$logicalPathPsr0 = substr($logicalPathPsr4, 0, $pos + 1)
. strtr(substr($logicalPathPsr4, $pos + 1), '_', DIRECTORY_SEPARATOR);
} else {
// PEAR-like class name
$logicalPathPsr0 = strtr($class, '_', DIRECTORY_SEPARATOR) . $ext;
}
if (isset($this->prefixesPsr0[$first])) {
foreach ($this->prefixesPsr0[$first] as $prefix => $dirs) {
if (0 === strpos($class, $prefix)) {
foreach ($dirs as $dir) {
if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
return $file;
}
}
}
}
}
// PSR-0 fallback dirs
foreach ($this->fallbackDirsPsr0 as $dir) {
if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
return $file;
}
}
// PSR-0 include paths.
if ($this->useIncludePath && $file = stream_resolve_include_path($logicalPathPsr0)) {
return $file;
}
return false;
}
}
/**
* Scope isolated include.
*
* Prevents access to $this/self from included files.
*/
function includeFile($file)
{
include $file;
}

283
vendor/composer/InstalledVersions.php vendored

@ -0,0 +1,283 @@
<?php
namespace Composer;
use Composer\Autoload\ClassLoader;
use Composer\Semver\VersionParser;
class InstalledVersions
{
private static $installed = array (
'root' =>
array (
'pretty_version' => '1.0.0+no-version-set',
'version' => '1.0.0.0',
'aliases' =>
array (
),
'reference' => NULL,
'name' => 'simplesip/whatsapp',
),
'versions' =>
array (
'simplesip/whatsapp' =>
array (
'pretty_version' => '1.0.0+no-version-set',
'version' => '1.0.0.0',
'aliases' =>
array (
),
'reference' => NULL,
),
),
);
private static $canGetVendors;
private static $installedByVendor = array();
public static function getInstalledPackages()
{
$packages = array();
foreach (self::getInstalled() as $installed) {
$packages[] = array_keys($installed['versions']);
}
if (1 === \count($packages)) {
return $packages[0];
}
return array_keys(array_flip(\call_user_func_array('array_merge', $packages)));
}
public static function isInstalled($packageName)
{
foreach (self::getInstalled() as $installed) {
if (isset($installed['versions'][$packageName])) {
return true;
}
}
return false;
}
public static function satisfies(VersionParser $parser, $packageName, $constraint)
{
$constraint = $parser->parseConstraints($constraint);
$provided = $parser->parseConstraints(self::getVersionRanges($packageName));
return $provided->matches($constraint);
}
public static function getVersionRanges($packageName)
{
foreach (self::getInstalled() as $installed) {
if (!isset($installed['versions'][$packageName])) {
continue;
}
$ranges = array();
if (isset($installed['versions'][$packageName]['pretty_version'])) {
$ranges[] = $installed['versions'][$packageName]['pretty_version'];
}
if (array_key_exists('aliases', $installed['versions'][$packageName])) {
$ranges = array_merge($ranges, $installed['versions'][$packageName]['aliases']);
}
if (array_key_exists('replaced', $installed['versions'][$packageName])) {
$ranges = array_merge($ranges, $installed['versions'][$packageName]['replaced']);
}
if (array_key_exists('provided', $installed['versions'][$packageName])) {
$ranges = array_merge($ranges, $installed['versions'][$packageName]['provided']);
}
return implode(' || ', $ranges);
}
throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
}
public static function getVersion($packageName)
{
foreach (self::getInstalled() as $installed) {
if (!isset($installed['versions'][$packageName])) {
continue;
}
if (!isset($installed['versions'][$packageName]['version'])) {
return null;
}
return $installed['versions'][$packageName]['version'];
}
throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
}
public static function getPrettyVersion($packageName)
{
foreach (self::getInstalled() as $installed) {
if (!isset($installed['versions'][$packageName])) {
continue;
}
if (!isset($installed['versions'][$packageName]['pretty_version'])) {
return null;
}
return $installed['versions'][$packageName]['pretty_version'];
}
throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
}
public static function getReference($packageName)
{
foreach (self::getInstalled() as $installed) {
if (!isset($installed['versions'][$packageName])) {
continue;
}
if (!isset($installed['versions'][$packageName]['reference'])) {
return null;
}
return $installed['versions'][$packageName]['reference'];
}
throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
}
public static function getRootPackage()
{
$installed = self::getInstalled();
return $installed[0]['root'];
}
public static function getRawData()
{
return self::$installed;
}
public static function reload($data)
{
self::$installed = $data;
self::$installedByVendor = array();
}
private static function getInstalled()
{
if (null === self::$canGetVendors) {
self::$canGetVendors = method_exists('Composer\Autoload\ClassLoader', 'getRegisteredLoaders');
}
$installed = array();
if (self::$canGetVendors) {
foreach (ClassLoader::getRegisteredLoaders() as $vendorDir => $loader) {
if (isset(self::$installedByVendor[$vendorDir])) {
$installed[] = self::$installedByVendor[$vendorDir];
} elseif (is_file($vendorDir.'/composer/installed.php')) {
$installed[] = self::$installedByVendor[$vendorDir] = require $vendorDir.'/composer/installed.php';
}
}
}
$installed[] = self::$installed;
return $installed;
}
}

21
vendor/composer/LICENSE vendored

@ -0,0 +1,21 @@
Copyright (c) Nils Adermann, Jordi Boggiano
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is furnished
to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

10
vendor/composer/autoload_classmap.php vendored

@ -0,0 +1,10 @@
<?php
// autoload_classmap.php @generated by Composer
$vendorDir = dirname(dirname(__FILE__));
$baseDir = dirname($vendorDir);
return array(
'Composer\\InstalledVersions' => $vendorDir . '/composer/InstalledVersions.php',
);

9
vendor/composer/autoload_namespaces.php vendored

@ -0,0 +1,9 @@
<?php
// autoload_namespaces.php @generated by Composer
$vendorDir = dirname(dirname(__FILE__));
$baseDir = dirname($vendorDir);
return array(
);

11
vendor/composer/autoload_psr4.php vendored

@ -0,0 +1,11 @@
<?php
// autoload_psr4.php @generated by Composer
$vendorDir = dirname(dirname(__FILE__));
$baseDir = dirname($vendorDir);
return array(
'scripts\\' => array($baseDir . '/scripts'),
'app\\' => array($baseDir . '/app'),
);

55
vendor/composer/autoload_real.php vendored

@ -0,0 +1,55 @@
<?php
// autoload_real.php @generated by Composer
class ComposerAutoloaderInit16f85458e9b741f7f2b22e1ee483f627
{
private static $loader;
public static function loadClassLoader($class)
{
if ('Composer\Autoload\ClassLoader' === $class) {
require __DIR__ . '/ClassLoader.php';
}
}
/**
* @return \Composer\Autoload\ClassLoader
*/
public static function getLoader()
{
if (null !== self::$loader) {
return self::$loader;
}
spl_autoload_register(array('ComposerAutoloaderInit16f85458e9b741f7f2b22e1ee483f627', 'loadClassLoader'), true, true);
self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(\dirname(__FILE__)));
spl_autoload_unregister(array('ComposerAutoloaderInit16f85458e9b741f7f2b22e1ee483f627', 'loadClassLoader'));
$useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded());
if ($useStaticLoader) {
require __DIR__ . '/autoload_static.php';
call_user_func(\Composer\Autoload\ComposerStaticInit16f85458e9b741f7f2b22e1ee483f627::getInitializer($loader));
} else {
$map = require __DIR__ . '/autoload_namespaces.php';
foreach ($map as $namespace => $path) {
$loader->set($namespace, $path);
}
$map = require __DIR__ . '/autoload_psr4.php';
foreach ($map as $namespace => $path) {
$loader->setPsr4($namespace, $path);
}
$classMap = require __DIR__ . '/autoload_classmap.php';
if ($classMap) {
$loader->addClassMap($classMap);
}
}
$loader->register(true);
return $loader;
}
}

44
vendor/composer/autoload_static.php vendored

@ -0,0 +1,44 @@
<?php
// autoload_static.php @generated by Composer
namespace Composer\Autoload;
class ComposerStaticInit16f85458e9b741f7f2b22e1ee483f627
{
public static $prefixLengthsPsr4 = array (
's' =>
array (
'scripts\\' => 8,
),
'a' =>
array (
'app\\' => 4,
),
);
public static $prefixDirsPsr4 = array (
'scripts\\' =>
array (
0 => __DIR__ . '/../..' . '/scripts',
),
'app\\' =>
array (
0 => __DIR__ . '/../..' . '/app',
),
);
public static $classMap = array (
'Composer\\InstalledVersions' => __DIR__ . '/..' . '/composer/InstalledVersions.php',
);
public static function getInitializer(ClassLoader $loader)
{
return \Closure::bind(function () use ($loader) {
$loader->prefixLengthsPsr4 = ComposerStaticInit16f85458e9b741f7f2b22e1ee483f627::$prefixLengthsPsr4;
$loader->prefixDirsPsr4 = ComposerStaticInit16f85458e9b741f7f2b22e1ee483f627::$prefixDirsPsr4;
$loader->classMap = ComposerStaticInit16f85458e9b741f7f2b22e1ee483f627::$classMap;
}, null, ClassLoader::class);
}
}

5
vendor/composer/installed.json vendored

@ -0,0 +1,5 @@
{
"packages": [],
"dev": true,
"dev-package-names": []
}

24
vendor/composer/installed.php vendored

@ -0,0 +1,24 @@
<?php return array (
'root' =>
array (
'pretty_version' => '1.0.0+no-version-set',
'version' => '1.0.0.0',
'aliases' =>
array (
),
'reference' => NULL,
'name' => 'simplesip/whatsapp',
),
'versions' =>
array (
'simplesip/whatsapp' =>
array (
'pretty_version' => '1.0.0+no-version-set',
'version' => '1.0.0.0',
'aliases' =>
array (
),
'reference' => NULL,
),
),
);
Loading…
Cancel
Save