Drupal 8 cannot find SoapClient class - php

I'm trying to consume a remote webservice but it doesnt work and I'm new to drupal.
below is my code:
namespace Drupal\mymodule\mymoduleAPI;
class RemoteConnection {
public function create() {
$default = array(
// We shall only enable TRACING & EXCEPTION for dev
'trace' => 1,
'exceptions' => true,
'cache_wsdl' => WSDL_CACHE_NONE,
'features' => SOAP_SINGLE_ELEMENT_ARRAYS,
);
$myServerEndPointUrl = "wsdl server address";
return new SoapClient($myServerEndPointUrl , $default);
}
}
This gives me the following error
Fatal error: Class 'Drupal\mymodule\mymoduleapi\SoapClient' not found
in C:\wamp\www\drupalnew\modules\
So am I doing something wrong? I already checked the Soap extension and tested it outside drupal and found it to work fine.
Thanks

SoapClient is in the global namespace, so when accessing it from within your own namespace, use '\' in front of the class name, like:
return new \SoapClient($myServerEndPointUrl , $default);
Further info Here

You can add a use command after your namespace:
use \SoapClient;
e.g.
namespace Drupal\module_name\Plugin\Block;
use Drupal\Core\Block\BlockBase;
use SoapClient;

Related

Importing a constant PHP

I have this file
namespace Drupal\api\ConfigArrays {
const jsonApiUris = array(
'insert_publication' => array(
'method' => 'POST',
'uri' => 'node/publication'
)
);
}
But when i try to import in some class:
use const Drupal\api\ConfigArrays\jsonApiUris;
class HttpHelper
{
static public function sendToJsonAPI($content, $endpoint, $token)
{
var_dump(jsonApiUris);
die;
}
}
my IDE (PhpStorm) recognizes the variable and the autocomplete, but when I execute it, I get this error
Error: Undefined constant 'Drupal\api\ConfigArrays\jsonApiUris' in
Drupal\api\Helpers\HttpHelper::sendToJsonAPI() (line 21 of
modules/custom/api/src/Helpers/HttpHelper.php).
Your syntax is fine for PHP5.6+ but if you are running a prior version you'll need to use Drupal\api\ConfigArrays then access it via ConfigArrays\jsonApiUris
Are you sure the code in the first snippet has been included/defined by the time it reaches the second snippet?

Laravel, with NuSOAP in a controller, does not work

Having a NuSOAP web service defined in an inline route closure function works great, but having it in a route closure controller does not.
Example: working
routes.php:
Route::any('api', function() {
require_once ('nusoap.php');
$server = new \nusoap_server();
$server->configureWSDL('TestService', false, url('api'));
$server->register('test',
array('input' => 'xsd:string'),
array('output' => 'xsd:string'),
);
function test($input){
return $input;
}
$rawPostData = file_get_contents("php://input");
return \Response::make($server->service($rawPostData), 200, array('Content-Type' => 'text/xml; charset=ISO-8859-1'));
});
SOAP Test Client
require_once('nusoap.php');
$client = new \nusoap_client('http://my-laravel-installation.com/api?wsdl', true);
$result = $client->call("test", "HelloWorld");
print_r($result); exit();
response
HelloWorld
This works as expected.
Example: not working
Moving the code to a dedicated controller breaks it:
routes.php:
Route::any('api', 'SoapController#server');
SoapController.php:
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class SoapController extends Controller {
public function server() {
require_once ('nusoap.php');
$server = new \nusoap_server();
$server->configureWSDL('TestService', false, url('api'));
$server->register('test',
array('input' => 'xsd:string'),
array('output' => 'xsd:string'),
);
function test($input){
return $input;
}
$rawPostData = file_get_contents("php://input");
return \Response::make($server->service($rawPostData), 200, array('Content-Type' => 'text/xml; charset=ISO-8859-1'));
}
}
SOAP Test Client
require_once('nusoap.php');
$client = new \nusoap_client('http://my-laravel-installation.com/api?wsdl', true);
$result = $client->call("test", "HelloWorld");
print_r($result); exit();
response
"method 'test' ('test') not defined in service('' '')
Steps To Reproduce:
Install a fresh copy of Laravel v5.2.45
Download the last NuSOAP version (v0.9.5)
Define the route for the NuSOAP Web Service - copy and paste the code from above
Create the SoapController - copy and paste the code from above
Create a new temp route to act as the SOAP client, and copy and paste the code beneath SOAP Test Client above into this route's closure function
Load the temp route page in the browser to execute a SOAP call to the Web Service
Conclusion:
This indicates, that for some reason, the output is different when using an inline route function versus using a dedicated route controller.
How could this be?
Your insight greatly appreciated:
If you have:
any experience with this and you have a solution
or, you have an idea on why this could occur
or, you have any thoughts on why having the NuSOAP code in the controller generates a different response than having it in an inline route function
...please chime in.
Thank you for your thoughts!
I have a simple solution for this.
Just install nusoap via composer.
composer require econea/nusoap
Call nusoap as needed:
$client = new \nusoap_client('http://my-laravel-installation.com/api?wsdl', true);
I hope that helps.
CSRF validation should be passive for current laravel versions.
app\Http\Middleware\VerifyCsrfToken.php
    protected $except = [
        'your way'
    ];
Must be.

Phalcon's universal class loader can't find my class

As a total php and phalcon newbie, I'm trying to use the recommended universal class loader using this code:
$loader = new \Phalcon\Loader();
// Register some directories
$loader->registerDirs(
array(
"php/assistants/"
)
);
// register autoloader
$loader->register();
$test = new dbAssistant();
as I understand I have to reffer to the php file as a class what I have inside of php/assistants/dbAssistant.php is the following code, trying to connect to a database:
<?php
function connect() {
$connection = new Phalcon\Db\Adapter\Pdo\Mysql(array(
'host' => 'localhost',
'username' => 'root',
'password' => 'tt',
'dbname' => 'testdb',
'port' => '3306'
));
echo 'Connected!!!';
}
again what I understand is that I have to refer to dbAssistant.php as a class and that's why I'm using $test = new dbAssistant();, but it gives me the following error:
Fatal error: Class 'dbAssistant' not found in /var/www/html/test/test.php on line 18
I know that it seeme normal, but the strange thing is that if I remove the connect() function and place the code out of it, I can see the Connected!!! echo, but it is followed by the same(above) error. I know that I'm missing something really small here, but as a complete php newbie, I really can't spot the problem.
Can you give me a push?
php/assistants/dbAssistant.php is not a class but a plain Php file. There should be a class in there with the name dbAssistant.
class dbConnect {
public function connect() {
///Do your stuff
}
}

PHP Amazon Ses as an abstract class gives use fatal error

I'm using the Amazon Simple Email Service and am trying to implement it as an abstract class so that I can simply use it throughout as needed.
Problem
The problem occurs with the use, I cannot work out how to require the files and classes needed to use Ses as an abstract class without incurring errors.
require 'lib/aws/aws-autoloader.php';
use Aws\Common\Enum\Region;
use Aws\Ses\SesClient;
abstract class simpleemail {
function sendSesEmail($to, $subject, $body, $bodyHtml){
try {
$client = SesClient::factory(array(
'key' => "",
'secret' => "",
'region' => Region::US_EAST_1
));
$send = $client->sendEmail(array(
'Source' => 'Name <no-reply#contact.com>',
'Destination' => array('ToAddresses' => array($to)),
'Message' => array('Subject' => array('Data' => $subject), 'Body' => array('Html' => array('Data' => $bodyHtml)))));
return true;
}
catch(Exception $e){
echo $e->getMessage();
return false;
}
}
}
Error Messages
Fatal error: Class 'Aes\Ses\SesClient' not found in ....
I have tried changing the use to require but then get:
require 'lib/aws/Aws/Common/Enum/Region.php';
require 'lib/aws/Aws/Ses/SesClient.php';
Fatal error: 'SesClient' not found in ...
Solution?
How can I use/require the files I need to get this working inside an abstract class?
This doesn't work:
abstract class simpleemail
{
public function sendSesEmail()
{
use Aws\Common\Enum\Region;
use Aws\Ses\SesClient;
//...
}
}
use statements are, basically, imports, that are processed at compile-time, so they can't be scoped. They have to move to the outer scope (outside of the class).
If you want to scope them, you'll have to either, manually require them, or use class_alias.
Check my answer to this question for more details. Even more details can, as ever, be found on php.net
Side-notes:
Please, follow the coding standards as described by PHP-FIG. They're not official, but Zend, Symfony... all major players, in fact, subscribe to them.
Please get in the habbit of always specifying the accessmodifiers (public, protected and private)
When creating instances like you do $client = SesClient::factory, assign them to a property, to only create the instance once. At the moment, each method call creates the same instance over and over again. That's bad
When using properties: include them in the class definition!
You're calling sendEmail on an instance, and assign the return value to $send. You don't check the return value, nor do you return it. Either ignore the return value, or return it, so it can be checked!
Never use require, use require_once if you have to. Using require can cause errors when executing the same block of code twice: redeclaring functions/classes. If time is of the essence, you could opt for require (as require_once causes more overhead), but you have to know what you're doing.
don't require an autoloader, use spl_autoloader_register
Remember: Abstract classes can't be instantiated, only their children... children can also override the methods declared in the abstract class. Declare critical methods as final
So, the answer:
use Aws\Common\Enum\Region;
use Aws\Ses\SesClient;
abstract class simpleemail
{
protected $client = null;
final public function sendSesEmail()
{
$client = $this->getClient();//lazy-loads the client instance
return $client->sendEmail(/* ... */);//return the result
}
//lazy-loader
protected function getClient()
{
if ($this->client === null)
{
$this->client = SesClient::factory(array(
'key' => "",
'secret' => "",
'region' => Region::US_EAST_1
));
}
return $this->client;
}
}

ZF2: Return JSON only for Ajax Call

I'm trying to learn ZF2. I have a page that uses Ajax to get some data. The ZF2 function should return an JSON string.
<?php
namespace Application\Controller;
use Zend\Mvc\Controller\AbstractActionController;
use Zend\View\Model\ViewModel;
use Zend\View\Model\JsonModel;
class DocumentsController extends AbstractActionController {
public function indexAction() {
}
public function getTreeDataAction() {
$json = new JsonModel(array(
'title' => 'Some Title'
));
return $json;
}
}
But I keep getting this Fatal Error:
( ! ) Fatal error: Uncaught exception 'Zend\View\Exception\RuntimeException' with message 'Zend\View\Renderer\PhpRenderer::render: Unable to render template "application/documents/get-tree-data"; resolver could not resolve to a file' in ../vendor/ZF2/library/Zend/View/Renderer/PhpRenderer.php on line 451
I have been searching around for this error and the best way to make ajax calls in ZF2, however results for ZF1 or ZF2 betas keep coming up and do not work. Thank you for any advice you can give.
Hmm, that error pretty much implies that it tries to access the default rendering strategy, which is quite weird... Have you added the JsonStrategy to your view_manager?
//module.config.php
return array(
'view_manager' => array(
'strategies' => array(
'ViewJsonStrategy',
),
),
)
Furthermore it's a good idea to set the correct accept header for within you ajax calls to only accept application/json content type. With this set, it should actually work. Out of curiousity though, does modules/__NAMESPACE__/view/__namespace__/documents/get-tree-data.phtml exist?
Try something like this...
$response = $this->getResponse();
$response->setStatusCode(200);
$jsonArray = {.....}
$response->setBody($jsonArray);
return $response;
And make sure you add ViewJsonStrategy to your module config as well.

Categories