Importing a constant PHP - 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?

Related

CakePHP 4 ConsoleOptionParser usage

In my CakePHP 4.0 project, and I'm trying to achieve what I think is a fairly trivial goal: I would like to have to have a "base" console command, with some basic setup, and other classes that extend it.
Specifically, I would like to define a [ConsoleOptionParser][1] in my base class, because all other Command classes should have access to the same options:
<?php
namespace Import\Shell;
use Cake\Command\Command;
use Cake\Console\ConsoleOptionParser;
class BaseImportCommand extends Command
{
public function __construct()
{
parent::__construct();
// setup some stuff related to my project here
}
protected function buildOptionParser(ConsoleOptionParser $parser): ConsoleOptionParser
{
// Get an empty parser from the framework.
$parser = parent::getOptionParser();
// Define your options and arguments.
$parser->addOptions(
[
'country' => [
'short' => 'c',
'help' => 'The country for which to execute the operation.',
'required' => false,
],
'author' => [
'short' => 'a',
'help' => 'The ID of the author for which to execute the operation.',
'required' => false,
],
'product' => [
'short' => 'p',
'help' => 'The ID of the product for which to execute the operation.',
'required' => false,
],
]
);
// Return the completed parser
return $parser;
}
}
<?php
namespace Import\Shell;
use Cake\Console\Arguments;
use Cake\Console\ConsoleIo;
class ProcessProductImagesCommand extends BaseImportCommand
{
public function __construct()
{
parent::__construct();
// setup some more stuff here
}
/**
* execute() method.
*
* #return bool|int|null Success or error code.
*/
public function execute(Arguments $args, ConsoleIo $io)
{
$country = $args->getOption('country');
$productId = $args->getOption('product');
// do my logic here
}
}
The problem is that when I run
bin/cake processProductImages -c CH
in the shell I get this error:
Error: Unknown short option `c`.
Why is that? I am not redefining the buildOptionParser method inside the ProcessProductImagesCommand class, so I would assume that the ConsoleOptionParser configuration is inherited from the BaseCommand class.
To fix the problem, I have tried adding this method to the ProcessProductImagesCommand class:
protected function buildOptionParser(ConsoleOptionParser $parser): ConsoleOptionParser
{
return parent::buildOptionParser($parser);
}
but what happens in this case when I run
bin/cake processProductImages -c CH
in the shell I then get this error:
Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 4096 bytes) in /var/www/repo/public/vendor/cakephp/cakephp/src/Console/ConsoleOptionParser.php on line 430
I have found out the the only actual way to have the options that I need, in the classes that I need them, is to completely repeat the initialisation of the ConsoleOptionParser in the child class by copying the whole buildOptionParser method from the BaseImportCommand class, but obviously I don't like this solution as it leads to useless code repetition.
[1]: https://book.cakephp.org/4/en/console-commands/option-parsers.html
By convention commands are supposed to live in the Command namespace, not the Shell namespace.
You cannot call parent::buildOptionParser() without any arguments.
The first argument of addArgument() is meant to be a string, or an instance of \Cake\Console\ConsoleInputArgument, not an array. Multiple arguments can be added at once using the addArguments() method (note the trailing s).
Arguments (positional values) and options are two different things, -c is an option that needs to be configured using addOption().
If you're exhausting 130+ MB of memory in the options parsing stage, then you possibly created an infinite loop.

Gas ORM - Auto Create Table show error message

In use Gas ORM for CodeIgniter.
Like what said in : http://gasorm-doc.taufanaditya.com/configuration.html
Gas ORM support auto-creation of tables. This mean you can convert your existing Gas models into a database. For security reasons, this option is disabled by default. To enable :
$config['auto_create_tables'] = TRUE;
And then i enable migration in migration.php and then create 2 class in models folder called user.php and blog.php. The code look like :
User class :
<?php
namespace Model;
use \Gas\Core;
use \Gas\ORM;
class User extends ORM {
public $primary_key = 'id';
function _init()
{
self::$relationships = array (
'blog' => ORM::has_many('\\Model\\Blog');
);
self::$fields = array(
'id' => ORM::field('auto[10]'),
'username' => ORM::field('char[64]'),
'password' => ORM::field('char[255]'),
'email' => ORM::field('char[255]'),
);
}
}
Blogclass:
<?php namespace Model;
use \Gas\Core;
use \Gas\ORM;
class Blog extends ORM {
public $primary_key = 'id';
function _init()
{
self::$relationships = array (
'user' => ORM::belongs_to('\\Model\\User')
);
self::$fields = array(
'id' => ORM::field('auto[10]'),
'title' => ORM::field('char[255]', array('required','max_length[255]')),
'body' => ORM::field('string'),
'modified_at' => ORM::field('datetime'),
'created_at' => ORM::field('datetime'),
);
$this->ts_fields = array('modified_at','[created_at]');
}
}
When i refresh the pages, the page showing error:
A PHP Error was encountered
Severity: Runtime Notice
Message: Only variables should be passed by reference
Filename: classes/core.php
Line Number: 2460
Backtrace:
File: /application/third_party/gas/classes/core.php
Line: 2460
Function: _error_handler
File: /application/third_party/gas/classes/core.php
Line: 320
Function: _generate_tables
File: /application/third_party/gas/classes/core.php
Line: 360
Function: __construct
File: /application/third_party/gas/bootstrap.php
Line: 229
Function: make
File: /application/libraries/Gas.php
Line: 111
Function: include_once
File: /application/controllers/Home_Controller.php
Line: 7
Function: __construct
File: /index.php
Line: 315
Function: require_once
I really stuck with this error. Can anyone help me to solve my problem?
I already trace my code, and the problem similar like this reference : Only variables should be passed by reference
The fact of this problem is maybe the code show error when running but actually the code completely its function. So i decide to turn the $config['auto_create_tables'] = TRUE; to $config['auto_create_tables'] = FALSE; after using this feature.

Drupal 8 cannot find SoapClient class

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;

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