I am really new into frameworks and into ZF3, but I need to make a API, with the following logic. I receive parameters, I store them in an bd and if the call is action is to be made at this point(call Manager), I send it to the (provider caller). I was able to the first part, and the second, but now, I don't know how to do the last one... I have the following code:
IndexController.php
use Application\Service\CallManager;
use Application\Service\TropoCaller;
use Application\Service\NexmoCaller;
class IndexController extends AbstractActionController
{
/**
* Entity manager.
* @var Doctrine\ORM\EntityManager
*/
private $entityManager;
/**
* Call manager.
* @var Application\Service\CallManager
*/
private $callManager;
/**
* Call manager.
* @var Application\Service\NexmoCaller
*/
private $NexmoCaller;
/**
* Call manager.
* @var Application\Service\TropoCaller
*/
private $TropoCaller;
/**
* Constructor is used for injecting dependencies into the controller.
*/
public function __construct($entityManager, $callManager, $NexmoCaller, $TropoCaller)
{
$this->entityManager = $entityManager;
$this->callManager = $callManager;
$this->NexmoCaller = $NexmoCaller;
$this->TropoCaller = $TropoCaller;
}
public function contactUSAction()
{
$form= new ButtoncallForm();
// Check whether this post is a POST request.
if ($this->getRequest()->isPost()) {
// Get POST data.
$data = $this->params()->fromPost();
// Fill form with data.
$form->setData($data);
if ($form->isValid()) {
// Get validated form data.
$data = $form->getData();
// Use post manager service to add new call to the database
$this->callManager->CallManager($data);
return $this->redirect()->toRoute('application',
['action'=>'thankYou']);
}
}
return new ViewModel([
'form' => $form,
]);
}
public function thankYouAction()
{
return new ViewModel();
}
}
IndexControllerFactory.php
<?php
namespace Application\Controller\Factory;
use Interop\Container\ContainerInterface;
use Zend\ServiceManager\Factory\FactoryInterface;
use Application\Service\CallManager;
use Application\Service\TropoCaller;
use Application\Service\NexmoCaller;
use Application\Controller\IndexController;
/**
* This is the factory for IndexController. Its purpose is to instantiate the
* controller.
*/
class IndexControllerFactory implements FactoryInterface
{
public function __invoke(ContainerInterface $container, $requestedName, array $options = null)
{
$entityManager = $container->get('doctrine.entitymanager.orm_default');
$callManager = $container->get(CallManager::class);
$NexmoCaller = $container->get(NexmoCaller::class);
$TropoCaller = $container->get(TropoCaller::class);
// Instantiate the controller and inject dependencies
return new IndexController($entityManager, $callManager, $NexmoCaller, $TropoCaller);
}
}
My CallManager.php
<?php
namespace Application\Service;
use Zend\ServiceManager\ServiceManager;
use Zend\ServiceManager\ServiceManagerAwareInterface;
use Zend\Mvc\Controller\AbstractActionController;
use Zend\View\Model\ViewModel;
use Application\Entity\CallRequested;
use Doctrine\ORM\EntityManager;
use Stomp\Client;
use Stomp\StatefulStomp;
use Stomp\Network\Connection;
use Stomp\Transport\Message;
use Application\Service\NexmoCaller;
use Application\Service\TropoCaller;
class CallManager
{
/**
* Doctrine entity manager.
* @var Doctrine\ORM\EntityManager
*/
private $entityManager;
/**
* @var Application\Service\NexmoCaller
*/
private $NexmoCaller;
/**
* @var Application\Service\TropoCaller
*/
private $TropoCaller;
// Constructor method is used to inject dependencies to the controller.
public function __construct($entityManager)
{
$this->entityManager = $entityManager;
}
public function CallManager($data)
{
$callRequested= new CallRequested;
$callRequested-> setClientContact($data['clientContact']);
$callRequested-> setProvider($data['provider']);
$callRequested-> setCallCenter($data['callCenterContact']);
$whenCall= $data['schedule'];
$language= $data['language'];
$date = new \DateTime();
$callRequested-> setRequestTime($date);
$provider=$data['provider'];
$tropo='Tropo';
//var_dump($data);
$this->entityManager->persist($callRequested);
$this->entityManager->flush();
$id=$callRequested->getID();
//var_dump($callRequested->getID());
$data=array($id,$data);
$data=json_encode($data, true);
//confirmar onde usar esta lógica
if($whenCall==='1')
{ echo "Vamos establecer a ligaçao \n";
if (stripos($provider, $tropo) !== false) {
$destination = '/queue/tropozend';
$messages = 1;
$size = 256;
$DATA = "calls";
$body = $data;
try {
$connection = new Connection('tcp://192.168.64.3:61613');
$con1 = new StatefulStomp(new Client($connection));
$con1->send($destination, new Message($body));
//echo "Message sent $body \n" ;
} catch(StompException $e) {
echo $e->getMessage();
// TropoCall();
}
}
else{
$destination = '/queue/nexmozend';
$messages = 1;
$size = 256;
$DATA = "calls";
$body = $data;
try {
$connection = new Connection('tcp://192.168.64.3:61613');
$con1 = new StatefulStomp(new Client($connection));
$con1->send($destination, new Message($body));
//echo "Message sent $body \n" ;
} catch(StompException $e) {
echo $e->getMessage();
}
}
// NexmoCall();
}
else {echo "Vamos agendar a sua chamada \n";
}
}
}
I created the NexmoCaller and TropoCaller, but don't know how to called them. Here is one example of the logic: class NexmoCaller
{
// public function __construct($NexmoCaller)
// {
// $this->NexmoCaller = $NexmoCaller;
// }
public function NexmoCall()
{
$service= new NexmoCaller();
$serviceManager->set(NexmoCaller::class, $service);
$key = file_get_contents('scripts/application.key');
$basic = new \Nexmo\Client\Credentials\Basic($keyNexmo, $secret);
$keypair = new \Nexmo\Client\Credentials\Keypair($key, $application_id);
$client = new \Nexmo\Client(new \Nexmo\Client\Credentials\Container($basic, $keypair));
$jwt = generate_jwt($application_id, $key);
header('Content-Type: application/json', 'Authorization: Bearer'.$jwt);
$destination = '/queue/nexmozend';
$connection = new Connection('tcp://192.168.64.3:61613');
$stomp = new StatefulStomp(new Client($connection));
$stomp->subscribe($destination);
echo "Waiting for messages...\n";
while(true) {
$frame = $stomp->read();
$body = $frame->getBody();
//echo($frame);
echo "message received $body \n";
//echo $stomp->read()->body, PHP_EOL;
//print_r($frame = $stomp->read());
//print_r($stomp->read()->body);
break;
}
//codificar o json como é necessário
$json = json_decode($body, true);
var_dump($json);
}
}
My config.module.php
'controllers' => [
'factories' => [
Controller\IndexController::class => Controller\Factory\IndexControllerFactory::class,
],
],
'service_manager' => [
'factories' => [
Service\CallManager::class => Service\Factory\CallManagerFactory::class,
Service\NexmoCaller::class => InvokableFactory::class,
Service\TropoCaller::class => InvokableFactory::class,
],
],
I have tried several aproaches but none of them creates the manager or calls it... Plus, I haven't found any case of using a service inside a service, so i am not even sure it is possible... One of the solutions I've tried was: -constructing in my call manager:
/**
* Doctrine entity manager.
* @var Doctrine\ORM\EntityManager
*/
private $entityManager;
/**
* @var Application\Service\NexmoCaller
*/
private $NexmoCaller;
/**
* @var Application\Service\TropoCaller
*/
private $TropoCaller;
public function __construct($entityManager, $NexmoCaller,
$TropoCaller)
{
$this->entityManager = $entityManager;
$this->NexmoCaller = $NexmoCaller;
$this->TropoCaller = $TropoCaller;
}
And I get this error:
Too few arguments to function Application\Service\CallManager::__construct(), 1 passed in /opt/lampp/htdocs/buttoncall/skeleton-application/module/Application/src/Service/Factory/CallManagerFactory.php on line 15 and exactly 3 expected
Or simply by calling:
$this->NexmoCaller->NexmoCaller();
And get this: Call to a member function NexmoCaller() on null
I used answer gaven, in my Factory:
<?php
namespace Application\Service\Factory;
use Interop\Container\ContainerInterface;
use Zend\ServiceManager\Factory\FactoryInterface;
use Application\Service\CallManager;
use Application\Service\NexmoCaller;
use Application\Service\TropoCaller;
class CallManagerFactory implements FactoryInterface
{
public function __invoke(ContainerInterface $container, $requestedName, array $options = null)
{
$entityManager = $container->get('doctrine.entitymanager.orm_default');
$nexmoCaller = $container->get(NexmoCaller::class);
$tropoCaller = $container->get(TropoCaller::class);
return new $requestedName(
$entityManager,
$nexmoCaller,
$tropoCaller
);
}
}
And get this: Call to a member function NexmoCaller() on null
What should I do?
From what I understand you are trying to use the NexmoCaller and TropoCaller inside of the CallManager but you haven't injected them.
You are on the right path creating the constructor:
public function __construct($entityManager, $NexmoCaller, $TropoCaller)
{
$this->entityManager = $entityManager;
$this->NexmoCaller = $NexmoCaller;
$this->TropoCaller = $TropoCaller;
}
But while you are expecting 3 parameter the error tells us that the CallManagerFactory is only sending 1.
To solve this modify the CallManagerFactory so it looks something like this:
public function __invoke(ContainerInterface $container, $requestedName, array $options = null)
{
$entityManager = $container->get('doctrine.entitymanager.orm_default');
$nexmoCaller = $container->get(NexmoCaller::class);
$tropoCaller = $container->get(TropoCaller::class);
return new $requestedName(
$entityManager,
$nexmoCaller,
$tropoCaller
);
}