Trouble loading PHP Class within the same project - php

Someone could help me on the issue of referencing php files within the same project (calling classes) using "namespace","use" ( php v5.3 or higher) [My Screenshoot][http://i.imgur.com/6GC4UUK.png?1]
Zoho\
CRM\
Common\
-HttpClientInterface.php
Config\
Entities\
Exception\
Request\
Wrapper\
index.php
I've read about autoloading classes but I don't undersand very well..
Fatal error: Class 'Zoho\CRM\Common\HttpClientInterface' not found in C:\root\zohocrm-master\src\Zoho\CRM\index.php on line 73
<?php namespace Zoho\CRM;
use Zoho\CRM\Common\HttpClientInterface;
use Zoho\CRM\Common\FactoryInterface;
use Zoho\CRM\Request\HttpClient;
use Zoho\CRM\Request\Factory;
use Zoho\CRM\Wrapper\Element;
.
.
.
public function __construct($authtoken, HttpClientInterface $client =null , FactoryInterface $factory = null )
{
$this->authtoken = $authtoken;
// Only XML format is supported for the time being
$this->format = 'xml';
$this->client = new HttpClientInterface();
$this->factory = $factory ;
$this->module = "Leads";
return $this;
}
This is my class file :
<?php namespace Zoho\CRM\Common;
/**
* Common interface for Http clients
*
* #package Zoho\CRM\Common
* #version 1.0.0
*/
interface HttpClientInterface
{
/**
* Performs POST request.
*
* #param string $uri Direction to make the post
* #param string $postBody Post data
*/
public function post($uri, $postBody);
}

Related

Symfony incompatibilities. The LoaderInterface and the XmlFileLoader have an issue

Situation:
This is the screen message I became after installing tikiwiki 24.
Fatal error: Declaration of Symfony\Component\DependencyInjection\Loader\XmlFileLoader::load($resource, ?string $type = NULL) must be compatible with Symfony\Component\Config\Loader\LoaderInterface::load($resource, $type = NULL) in /var/www/contiki/vendor/symfony/dependency-injection/Loader/XmlFileLoader.php on line 46
So please, does anyone have a clue what's going on here? I'm quite new to composer, solved many compatibility issues but this is out of my range.
I don't understand why they are incompatible.
These are (part) of the files:
My /var/www/contiki/vendor_bundled/vendor/symfony/config/Loader/LoaderInterface.php
interface LoaderInterface
{
/**
* Loads a resource.
*
* #param mixed $resource The resource
* #param string|null $type The resource type or null if unknown
*
* #throws \Exception If something went wrong
*/
public function load($resource, $type = null);
/**
* Returns whether this class supports the given resource.
*
* #param mixed $resource A resource
* #param string|null $type The resource type or null if unknown
*
* #return bool True if this class supports the given resource, false otherwise
*/
public function supports($resource, $type = null);
/**
* Gets the loader resolver.
*
* #return LoaderResolverInterface A LoaderResolverInterface instance
*/
public function getResolver();
/**
* Sets the loader resolver.
*/
public function setResolver(LoaderResolverInterface $resolver);
}
The first part of the /var/www/contiki/vendor_bundled/vendor/symfony/dependency-injection/Loader/XmlFileLoader.php file
namespace Symfony\Component\DependencyInjection\Loader;
use Symfony\Component\Config\Util\XmlUtils;
use Symfony\Component\DependencyInjection\Alias;
use Symfony\Component\DependencyInjection\Argument\BoundArgument;
use Symfony\Component\DependencyInjection\Argument\IteratorArgument;
use Symfony\Component\DependencyInjection\Argument\TaggedIteratorArgument;
use Symfony\Component\DependencyInjection\ChildDefinition;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
use Symfony\Component\DependencyInjection\Exception\RuntimeException;
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\ExpressionLanguage\Expression;
/**
* XmlFileLoader loads XML files service definitions.
*
* #author Fabien Potencier <fabien#symfony.com>
*/
class XmlFileLoader extends FileLoader
{
const NS = 'http://symfony.com/schema/dic/services';
/**
* {#inheritdoc}
*/
public function load($resource, $type = null)
{
$path = $this->locator->locate($resource);
$xml = $this->parseFileToDOM($path);
$this->container->fileExists($path); <-- This is rule 46
$defaults = $this->getServiceDefaults($xml, $path);
// anonymous services
$this->processAnonymousServices($xml, $path, $defaults);
// imports
$this->parseImports($xml, $path);
// parameters
$this->parseParameters($xml, $path);
// extensions
$this->loadFromExtensions($xml);
// services
try {
$this->parseDefinitions($xml, $path, $defaults);
} finally {
$this->instanceof = [];
}
}```
Sounds like something's got tangled up here, Tiki 24 is not out yet but will be branching soon, so if you want a stable safe Tiki now, probably best to use a stable released branch, i.e. 23.x? Also, we are still on Smarty 3.x and plan to upgrade to 4.x (and PHP 8+) after the release of 24 which is our next LTS version, so not sure where that is coming from... did you run sh setup.sh?
As Nico said above, this is probably more Tiki-specific than is suitable for here, so the best thing would be to come and chat with the community in our new Gitter room, here?
Welcome to Tiki! :)

Missing system injecting dependencies using vanilla php

I'm trying to get my app working, Its a vanilla php, I have 2 services with one dependent on other. I'm running service from the bootstrap, which requires simple SplClassLoader.
The directory structure (Slightly simplified):
-src
-logic
-Service
-CustomService.php
-DataProviderService.php
-SplClassLoader.php
-test
-bootstrap.php
Bootstrap:
<?php
require __DIR__ . '/../src/SplClassLoader.php';
$oClassLoader = new \SplClassLoader('logic', __DIR__ . '/../src');
$oClassLoader->register();
$service = new logic\Service\CustomService;
$service->execute();
SplClassLoader:
<?php
/**
* SplClassLoader implementation that implements the technical interoperability
* standards for PHP 5.3 namespaces and class names.
*
* http://groups.google.com/group/php-standards/web/final-proposal
*
* // Example which loads classes for the Doctrine Common package in the
* // Doctrine\Common namespace.
* $classLoader = new SplClassLoader('Doctrine\Common', '/path/to/doctrine');
* $classLoader->register();
*
* #author Jonathan H. Wage <jonwage#gmail.com>
* #author Roman S. Borschel <roman#code-factory.org>
* #author Matthew Weier O'Phinney <matthew#zend.com>
* #author Kris Wallsmith <kris.wallsmith#gmail.com>
* #author Fabien Potencier <fabien.potencier#symfony-project.org>
*/
class SplClassLoader
{
private $_fileExtension = '.php';
private $_namespace;
private $_includePath;
private $_namespaceSeparator = '\\';
/**
* Creates a new <tt>SplClassLoader</tt> that loads classes of the
* specified namespace.
*
* #param string $ns The namespace to use.
*/
public function __construct($ns = null, $includePath = null)
{
$this->_namespace = $ns;
$this->_includePath = $includePath;
}
/**
* Sets the namespace separator used by classes in the namespace of this class loader.
*
* #param string $sep The separator to use.
*/
public function setNamespaceSeparator($sep)
{
$this->_namespaceSeparator = $sep;
}
/**
* Gets the namespace seperator used by classes in the namespace of this class loader.
*
* #return void
*/
public function getNamespaceSeparator()
{
return $this->_namespaceSeparator;
}
/**
* Sets the base include path for all class files in the namespace of this class loader.
*
* #param string $includePath
*/
public function setIncludePath($includePath)
{
$this->_includePath = $includePath;
}
/**
* Gets the base include path for all class files in the namespace of this class loader.
*
* #return string $includePath
*/
public function getIncludePath()
{
return $this->_includePath;
}
/**
* Sets the file extension of class files in the namespace of this class loader.
*
* #param string $fileExtension
*/
public function setFileExtension($fileExtension)
{
$this->_fileExtension = $fileExtension;
}
/**
* Gets the file extension of class files in the namespace of this class loader.
*
* #return string $fileExtension
*/
public function getFileExtension()
{
return $this->_fileExtension;
}
/**
* Installs this class loader on the SPL autoload stack.
*/
public function register()
{
spl_autoload_register(array($this, 'loadClass'));
}
/**
* Uninstalls this class loader from the SPL autoloader stack.
*/
public function unregister()
{
spl_autoload_unregister(array($this, 'loadClass'));
}
/**
* Loads the given class or interface.
*
* #param string $className The name of the class to load.
* #return void
*/
public function loadClass($className)
{
if (null === $this->_namespace || $this->_namespace.$this->_namespaceSeparator === substr($className, 0, strlen($this->_namespace.$this->_namespaceSeparator))) {
$fileName = '';
$namespace = '';
if (false !== ($lastNsPos = strripos($className, $this->_namespaceSeparator))) {
$namespace = substr($className, 0, $lastNsPos);
$className = substr($className, $lastNsPos + 1);
$fileName = str_replace($this->_namespaceSeparator, DIRECTORY_SEPARATOR, $namespace) . DIRECTORY_SEPARATOR;
}
$fileName .= str_replace('_', DIRECTORY_SEPARATOR, $className) . $this->_fileExtension;
require ($this->_includePath !== null ? $this->_includePath . DIRECTORY_SEPARATOR : '') . $fileName;
}
}
}
So yeah, Im running php php bootstrap.php and getting error that too few arguments passed into contructor. How to make bootstrap load dependency injections? How I should make it work? Can I use some kind of service container of phpunit maybe? Its a clue I have been given. No idea if I did explain problem well enough, but hope I did! :)
Error message:
PHP Fatal error: Uncaught ArgumentCountError: Too few arguments to function logic\Service\CustomService::execute(), 0 passed in /.../test/bootstrap.php on line 12 and exactly 1 expected in /.../Service/CustomService.php:23
Stack trace:
#0 /.../test/bootstrap.php(12): logic\Service\CustomService->execute()
#1 {main}
thrown in /.../logic/Service/CustomService.php on line 23

PHP SwiftMailer StringReplacementFilter bug workaround

Trying to implement a temp workaround to deal with this weird SwiftMailer bug:
https://github.com/swiftmailer/swiftmailer/issues/762
When reading a file that has a length of exactly n*8192 bytes (n >= 1), the last > value of $bytes is an empty string which triggers the error.
#raffomania's comment on GitHub:
we found that the following adaption of AbstractFilterableInputStream.write would fix the problem for us:
public function write($bytes)
{
$this->_writeBuffer .= $bytes;
if (empty($this->_writeBuffer)) {
return;
}
foreach ($this->_filters as $filter) {
if ($filter->shouldBuffer($this->_writeBuffer)) {
return;
}
}
$this->_doWrite($this->_writeBuffer);
return ++$this->_sequence;
}
I'd like to extend the AbstractFilterableInputStream class and call this modified write method when AbstractFilterableInputStream is called by SwiftMailer.
I'm using the Laravel framework.
The best way to solve this is to have the swiftmailer forked and fixed and you use your own forked version of swiftmailer. However if you do not want to do this, this fix is rather lengthy but it should work. Give it a shot. If there is any issue do let me know.
1. Create app/Mail/CustomFileByteStream.php: This is to have your own version of write.
<?php
namespace App\Mail;
/**
* Allows reading and writing of bytes to and from a file.
*
* #author Chris Corbyn
*/
class CustomFileByteStream extends \Swift_ByteStream_FileByteStream
{
public function write($bytes)
{
$this->_writeBuffer .= $bytes;
if (empty($this->_writeBuffer)) {
return;
}
foreach ($this->_filters as $filter) {
if ($filter->shouldBuffer($this->_writeBuffer)) {
return;
}
}
$this->_doWrite($this->_writeBuffer);
return ++$this->_sequence;
}
}
2. Create app/Mail/CustomSwiftAttachment.php: So that it uses the custom FileByteStream
<?php
namespace App\Mail;
/**
* Attachment class for attaching files to a {#link Swift_Mime_Message}.
*
* #author Chris Corbyn
*/
class CustomSwiftAttachment extends \Swift_Attachment
{
/**
* Create a new Attachment from a filesystem path.
*
* #param string $path
* #param string $contentType optional
*
* #return Swift_Mime_Attachment
*/
public static function fromPath($path, $contentType = null)
{
return self::newInstance()->setFile(
new CustomFileByteStream($path),
$contentType
);
}
}
3. Create app/Mail/CustomSwiftImage.php: So that it uses the custom FileByteStream
<?php
namespace App\Mail;
/**
* An image, embedded in a multipart message.
*
* #author Chris Corbyn
*/
class CustomSwiftImage extends \Swift_Image
{
/**
* Create a new Image from a filesystem path.
*
* #param string $path
*
* #return Swift_Image
*/
public static function fromPath($path)
{
$image = self::newInstance()->setFile(
new CustomFileByteStream($path)
);
return $image;
}
}
4. Create app/Mail/Message.php: So that it uses your own custom Swift_Image and Swift_Attachment
<?php
namespace App\Mail;
use Illuminate\Mail\Message as DefaultMessage;
class Message extends DefaultMessage
{
/**
* Create a Swift Attachment instance.
*
* #param string $file
* #return CustomSwiftAttachment
*/
protected function createAttachmentFromPath($file)
{
return CustomSwiftAttachment::fromPath($file);
}
/**
* Embed a file in the message and get the CID.
*
* #param string $file
* #return string
*/
public function embed($file)
{
return $this->swift->embed(CustomSwiftImage::fromPath($file));
}
}
5. Create app/Mail/Mailer.php: So it uses your custom Message class
<?php
namespace App\Mail;
use Swift_Message;
use Illuminate\Mail\Mailer as DefaultMailer;
class Mailer extends DefaultMailer
{
/**
* Create a new message instance. Notice this is complete replacement of parent's version.
* We uses our own "Message" class instead of theirs.
*
* #return \Illuminate\Mail\Message
*/
protected function createMessage()
{
$message = new Message(new Swift_Message);
// If a global from address has been specified we will set it on every message
// instances so the developer does not have to repeat themselves every time
// they create a new message. We will just go ahead and push the address.
if (! empty($this->from['address'])) {
$message->from($this->from['address'], $this->from['name']);
}
return $message;
}
}
6. Create app/Mail/MailServiceProvider.php: So it uses your custom Mailer class
<?php
namespace App\Mail;
use Illuminate\Mail\MailServiceProvider as DefaultMailServiceProvider;
use App\Mail\Mailer;
/**
* This mail service provider is almost identical with the illuminate version, with the exception that
* we are hijacking with our own Message class
*/
class MailServiceProvider extends DefaultMailServiceProvider
{
/**
* Complete replacement of parent register class so we can
* overwrite the use of mailer class. Notice the "Mailer" class is points to our own
* version of mailer, so we can hijack the message class.
*
* #return void
*/
public function register()
{
$this->registerSwiftMailer();
$this->app->singleton('mailer', function ($app) {
// Once we have create the mailer instance, we will set a container instance
// on the mailer. This allows us to resolve mailer classes via containers
// for maximum testability on said classes instead of passing Closures.
$mailer = new Mailer(
$app['view'], $app['swift.mailer'], $app['events']
);
$this->setMailerDependencies($mailer, $app);
// If a "from" address is set, we will set it on the mailer so that all mail
// messages sent by the applications will utilize the same "from" address
// on each one, which makes the developer's life a lot more convenient.
$from = $app['config']['mail.from'];
if (is_array($from) && isset($from['address'])) {
$mailer->alwaysFrom($from['address'], $from['name']);
}
$to = $app['config']['mail.to'];
if (is_array($to) && isset($to['address'])) {
$mailer->alwaysTo($to['address'], $to['name']);
}
return $mailer;
});
}
}
7. Edit config/app.php
Comment out Illuminate\Mail\MailServiceProvider::class,
Add this below of the line above App\Mail\MailServiceProvider::class,
So this will use your custom MailServiceProvider. At any point of time if you wish to revert this, just delete all the files above and reverse this edit.
Calling sequence:
So here you go. This should hijack the MailServiceProvider to use your own custom Swift_ByteStream_FileByteStream. Hopefully no typos!

phpspec Call to a member function on a non-object

I'm pretty new to Symfony and phpspec so please feel free to criticize heavily. So the issue is that I'm constantly getting PHP Fatal error: Call to a member function write() on a non-object.
Basically the class which is tested should write output to the console. In the constructor first I'm creating stream and then passing this stream to another class which is responsible for the output in the console. This is the main code.
Class ScreenshotTaker :
<?php
namespace Bex\Behat\ScreenshotExtension\Service;
use Behat\Mink\Mink;
use Behat\Testwork\Output\Printer\StreamOutputPrinter;
use Bex\Behat\ScreenshotExtension\Driver\ImageDriverInterface;
use Behat\Testwork\Output\Printer\Factory\ConsoleOutputFactory;
/**
* This class is responsible for taking screenshot by using the Mink session
*
* #license http://opensource.org/licenses/MIT The MIT License
*/
class ScreenshotTaker
{
/** #var Mink $mink */
private $mink;
/** #var ConsoleOutputFactory $output */
private $output;
/** #var ImageDriverInterface[] $imageDrivers */
private $imageDrivers;
/** #var StreamOutputPrinter $outputStream */
private $outputStream;
/**
* Constructor
*
* #param Mink $mink
* #param ConsoleOutputFactory $output
* #param ImageDriverInterface[] $imageDrivers
*/
public function __construct(Mink $mink, ConsoleOutputFactory $output, array $imageDrivers)
{
$this->mink = $mink;
$this->output = $output;
$this->imageDrivers = $imageDrivers;
$this->outputStream = new StreamOutputPrinter ($output);
}
/**
* Save the screenshot as the given filename
*
* #param string $fileName
*/
public function takeScreenshot($fileName = 'failure.png')
{
try {
$screenshot = $this->mink->getSession()->getScreenshot();
foreach ($this->imageDrivers as $imageDriver) {
$imageUrl = $imageDriver->upload($screenshot, $fileName);
$this->outputStream->writeln('Screenshot has been taken. Open image at ' . $imageUrl);
}
} catch (\Exception $e) {
$this->outputStream->writeln($e->getMessage());
}
}
}
Now this is the phpspec test.I'm passing the ConsoleOutputFactory which is used in the constructor but I'm getting
PHP Fatal error: Call to a member function write() on a non-object in
Behat/Testwork/Output/Printer/StreamOutputPrinter.php on line 125
This write method is part of StreamOutputPrinter. Can you tell me what Im missing here?
ScreenshotTakerSpec:
<?php
namespace spec\Bex\Behat\ScreenshotExtension\Service;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
use Behat\Mink\Mink;
use Behat\Mink\Session;
use Behat\Testwork\Output\Printer\Factory\ConsoleOutputFactory;
use Bex\Behat\ScreenshotExtension\Driver\Local;
use Behat\Testwork\Output\Printer\StreamOutputPrinter;
/**
* Unit test of the class ScreenshotTaker
*
* #license http://opensource.org/licenses/MIT The MIT License
*/
class ScreenshotTakerSpec extends ObjectBehavior
{
function let(Mink $mink, ConsoleOutputFactory $output, Local $localImageDriver)
{
$this->beConstructedWith($mink, $output, [$localImageDriver]);
}
function it_is_initializable()
{
$this->shouldHaveType('Bex\Behat\ScreenshotExtension\Service\ScreenshotTaker');
}
function it_should_call_the_image_upload_with_correct_params(Mink $mink, Session $session, Local $localImageDriver)
{
$mink->getSession()->willReturn($session);
$session->getScreenshot()->willReturn('binary-image');
$localImageDriver->upload('binary-image', 'test.png')->shouldBeCalled();
$this->takeScreenshot('test.png');
}
}
You should mock the call to outputFactory->createOutput() that is in StreamOutputPrinter line 144, but mocking something that is in another class is a smell. So I'd recommend to move the stream logic to a new class, eg StreamOutputPrinterFactory, and inject this factory:
public function __construct(Mink $mink, StreamOutputPrinterFactory $factory, array $imageDrivers)
{
$this->mink = $mink;
$this->imageDrivers = $imageDrivers;
$this->outputStream = $factory->createNew();
}
Now you can mock any calls to $this->outputStream.
You should also call createNew() when it's needed, not in the constructor. Let me know if you need further help.

Class 'Aws\Common\Aws' not found cakephp

I am using AWS PHP SDK V2.8 in my cakephp. I am working on AWS ec2 ubuntu machine.
I use zip files not any composer.
I am getting following error.
Class 'Aws\Common\Aws' not found
I create a custom component for accessing all features of SDK. with the reference of https://github.com/Ali1/cakephp-amazon-aws-sdk
My folder structure is as follows
Here is my AmazonComponent.php
<?php
App::uses('Component', 'Controller');
use Aws\Common\Aws;
/**
* AmazonComponent
*
* Provides an entry point into the Amazon SDK.
*/
class AmazonComponent extends Component {
/**
* Constructor
* saves the controller reference for later use
* #param ComponentCollection $collection A ComponentCollection this component can use to lazy load its components
* #param array $settings Array of configuration settings.
*/
public function __construct(ComponentCollection $collection, $settings = array()) {
$this->_controller = $collection->getController();
parent::__construct($collection, $settings);
}
/**
* Initialization method. Triggered before the controller's `beforeFilfer`
* method but after the model instantiation.
*
* #param Controller $controller
* #param array $settings
* #return null
* #access public
*/
public function initialize(Controller $controller) {
// Handle loading our library firstly...
$this->Aws = Aws::factory(Configure::read('Amazonsdk.credentials'));
}
/**
* PHP magic method for satisfying requests for undefined variables. We
* will attempt to determine the service that the user is requesting and
* start it up for them.
*
* #var string $variable
* #return mixed
* #access public
*/
public function __get($variable) {
$this->$variable = $this->Aws->get($variable);
return $this->$variable;
}
}
I add these two line on the top on file with the reference of this question
How to load AWS SDK into CakePHP?
ini_set('include_path', ROOT . DS . 'lib' . PATH_SEPARATOR . ini_get('include_path'). PATH_SEPARATOR . ROOT .DS . 'app/Plugin/Amazonsdk/Vendor/aws');
require ROOT . DS . 'app/Plugin/Amazonsdk/Vendor/aws/aws-autoloader.php';
Where I am wrong and how can I fix that?
#urfusion Could you pls move AWS SDK folder from app/Plugin to app/Vendor In Side the app/Vendor And then try to import aws-sdk AmazonComponent having Function initialize.
I am using AWS PHP SDK V3
// Handle loading our library firstly...
App::import('Vendor','aws-autoloader',array('file'=>'aws'.DS.'aws-autoloader.php'));

Categories