How to autoload multiple classes in Yii extension? - php

I am not sure whether title of question is exactly what I want to ask.
I want to use Authorize.net in my Yii application. Authorize.net has an API consisting of multiple classes and in order for the API to work all the classes should be autoloaded. In its SDK there is one file named autoload.php that does that. Please note that autoload.php is NOT a class, it just contains a function. Here is its code:
spl_autoload_register(function($className) {
static $classMap;
if (!isset($classMap)) {
$classMap = require __DIR__ . DIRECTORY_SEPARATOR . 'classmap.php';
}
if (isset($classMap[$className])) {
include $classMap[$className];
}
});
By requiring this file in my code I can do work with API successfully. Like:
require 'sdk-php-master/autoload.php
//I can make successful API calls after requiring autoload.php to be loaded.
But now the problem is I want to make same API work in Yii. I placed the SDK folder in extensions directory. Now I need to set extension path to be able to use it in my application. Now the problem is what should I set in class name for in config.php to make it work?
I tried this:
'authorize' => array(
'class' => 'application.extensions.authorize.autoload',
),
But that does not work, and it should not since autoload.php is not a class. All the necessary classes that should be autoloaded are placed in application.extensions.authorize.lib directory. How should I autoload all of them in Yii since according to my knowledge we can only have one entry in config.php for class.
Here is the link to SDK and its directory structure. Authorize.net SDK

This library uses composer, i recommend to you to use composer in your project to manage your libraries, and you will have no hassle with autloads.
Basicly create composer.json in your root project directory and place authorize part in it (and any further things)
{
"require": {
"authorizenet/authorizenet": "~1.8"
}
}
In your main index.php place:
require '/path/to/vendor/autoload.php';
somewhere before require $yii
Then call composer install. This in in short, for more details about composer this guide should be fine.
Update:
Composer will greatly improve your workflow when your require some external libraries. However if you really don't wan't to use composer, then just require autoload.php in index.php
Then use this library classes as in docs. Do not configure it as extension - this library is not Yii specific. In any code part just use it, for example:
define("AUTHORIZENET_API_LOGIN_ID", "YOURLOGIN");
define("AUTHORIZENET_TRANSACTION_KEY", "YOURKEY");
$subscription = new AuthorizeNet_Subscription;
$subscription->name = "PHP Monthly Magazine";
...

I found the solution to this. I just imported all the required folders in config main.php like this:
'import' => array(
'application.extensions.*',
'application.models.*',
'application.components.*',
'application.extensions.authorize.*',
'application.extensions.authorize.lib.*',
'application.extensions.authorize.lib.shared.*',
),

You can autoload all Authorize.net files using the following code on your protected/config/main.php file:
Yii::setPathOfAlias('Authorize', dirname(__FILE__).'/../extensions/sdk-php-master');
Yii::import('Authorize.autoload', true);

Related

How to load Google SDK in Cakephp 3.9

I have to load a Google plugin into the Cakephp 3.9 Application and need to be used inside the controller.
Google plugin places inside the Vendor folder
vendor/Google
Anyone can help for below points
How to load Plugin
How to import into the controller
I have used below link for reference:
https://api.cakephp.org/3.9/class-Cake.Core.Plugin.html
I use Google_Client in CakePHP - you shouldn't have to do anything special to use it. If it's installed via composer it's already in Composer's autoloader, you can call it directly.
Ex. In composer.json after running ./composer.phar require google/apiclient:"^2.7" My require section lists the Google API:
"require": {
"google/apiclient": "^2.7",
Make sure you run ./composer.phar install if it wasn't already installed durring require.
Then in to use the library, I just call it directly, prefixed with \ since it's not namespaced:
public function index()
{
$client = new \Google_Client();
If you're curious how this works under the hood - Composer will generate all the information it needs to load classes durring require or install and sticks these in several files back in vendor/composer, such as autoload_namespaces.php, where it should automatically have added Google_ to the list there, ex:
<?php
// autoload_namespaces.php #generated by Composer
$vendorDir = dirname(dirname(__FILE__));
$baseDir = dirname($vendorDir);
return array(
// Lots of class prefixes, but eventually:
'Google_' => array($vendorDir . '/google/apiclient/src'),
Classes that are namespaced to industry standards like PSR-4 (like all modern PHP libs probably should be!) are probably in autoloader_psr4.php - and so on. It registers it's own autoloader in ClassLoader.php, and sticks a reference to this in vendor/autoload.php - which Cake calls essentially on near line 1 of
webroot/index.php:
require dirname(__DIR__) . '/vendor/autoload.php';
So in short - you don't need to worry about autoloading again so long as you're working through Composer.
Also - if you're able to use an IDE which helps with autocompletion of class namespaces, like PHPStorm, that might make things easier.
For libraries that specify autoload information, Composer generates a vendor/autoload.php file. You can simply include this file and start using the classes that those libraries provide without any extra work:
require __DIR__ . '/vendor/autoload.php';
For more references : https://getcomposer.org/doc/01-basic-usage.md

how to add a PHP library to TYPO3 extension without namespace?

I'm tyring to implement a custom TYPO3 extension to execute some php code. With my main class "hello world!" ist already working and i understand the use of namespaces.
But now I found a php Library that suits my needs. I pasted the lib folder in the "Classes" folder of my extension. But now I'm getting class not found errors because none of the lib classes have a namespace.
Unfortunately I couldn't find any tutorial/doc on how to add a library to a typo3 extension while dynamically adding a namespace to every class. I tried to override every class with a namespace but somehow this cant be the solution
here is a sample of my Main class that is working but as soon as I try to call "ServiceMailman" i get namespace error, well, because they have none
namespace Htwg\GiMailman;
require_once 'Service/ServiceMailman.php';
class GiMailman{
public function getMailinglists() {
$mm = new ServiceMailman('http://localhost', '', '');
}
}
I'm looking for a way to add a php library to the "Classes" folder without adding a namespace to every library class.
Update:
I installed the library on an externel path and added it to the composer.json in the classmap entry:
"autoload": {
"psr-4": {
"Htwg\\GiMailman\\": "Classes/"
},
"classmap": ["/opt/lampp/lib/php/Services"]
}
and it shows up in the autoload_classmap.php:
// autoload_classmap.php #generated by Composer
$vendorDir = dirname(dirname(__FILE__));
$baseDir = dirname($vendorDir);
return array(
...
'Services_Mailman' => $baseDir . '/../../../../lib/php/Services/Mailman.php',
'Services_Mailman_Exception' => $baseDir . '/../../../../lib/php/Services/Mailman/Exception.php',
);
But when i try to class the class in my Main php class it still can't be found:
namespace Htwg\GiMailman;
//require_once 'Services/Mailman.php';
class GiMailman{
public function getMailinglists() {
$mm = new \Service_Mailman('http://localhost:8001/3.1', '', 'password');
return "getMailinglists";
}
}
Any PHP classes that do not use namespaces are in the top level namespace. So you can use them like:
$mm = new \ServiceMailman('http://localhost', '', '');
You should not add external libraries to you Classes directory. Classes in this directory are autoloaded with the correct namespace for your extension (Vendor/ExtensionName). As external libraries have a different, or in your case no, namespace, this will cause problems. Usually we put external libraries in Resources/Private/Php/LibraryName. You will then need to require or include the library.
If you're using composer it is however better not to include external libraries inside your extension, but let composer worry about it if possible. That way you don't have to worry about autoloading (so you don't need to require or include any files manually) and any dependencies for the external library are also automatically resolved. Either require the library in your global composer.json or, if you install the extension that requires it through composer, add it to the composer.json of the extension.
If you're running composer there are two ways:
The library is available on https://packagist.org/ => Require it in your composer.json file
The library needs to be copied into e.g. Library/ServiceMailman/. After that you set it into your composer.json in the autoload section "classmap", if no namespaces exists for this library. More: https://getcomposer.org/doc/04-schema.md#classmap (If the library has namespaces, it should be in autoload section "psr-4")
If you're not running composer and want to include it in your TYPO3 extension easily, there is a good tutorial: https://insight.helhum.io/post/148112375750/how-to-use-php-libraries-in-legacy-extensions

Troubleshooting composer: classes not autoloading with CodeIgniter 3

Problem
I am trying to use the PayPal Checkout REST SDK which requires the PayPal library to be autoloaded through composer. I have gone through the steps to enable Composer in CodeIgniter 3 but when I go to my controller where I am autoloading the PayPal\Rest\ApiContext class I get the following error:
Fatal error: Class 'PayPal\Rest\ApiContext' not found in
C:\xampp\htdocs\php\toucan-talk\App\modules\paypal\controllers\Paypal.php
on line 15
What I have so far
Here is my composer.json file
{
"require": {
"paypal/rest-api-sdk-php" : "*"
}
}
I have set $config['composer_autoload'] = TRUE; in my config.php file.
Here is my controller
<?php
use PayPal\Rest\ApiContext;
class Paypal extends MX_Controller
{
public function __construct()
{
$api = new ApiContext(
);
var_dump($api);
}
}
Question
How do I troubleshoot composer and its autoloader so that I can pinpoint where the autoload process is failing.
Well here is the solution: in config.php instead of setting...
$config['composer_autoload'] = TRUE;
You need to put
$config['composer_autoload'] = FCPATH . 'vendor/autoload.php';
however I am still not certain why this works as opposed to the original documentations recommendation. Bit of a headache really.
I know this is quite an old Question but still, i want to put my input that basically CodeIgniter 3 specifically 3.1.6 have problem that when you do
$config['composer_autload'] = TRUE:
then it won't work and doesn't autoload the files from vendor folder now there are 2 possible solutions for this one solution already mentioned by "Jethro Hazelhurst".
The other simple solution is that copy composer.json inside application folder and then run composer install from the application folder or just move vendor folder along with composer.json and composer.lock to the application folder and then this TRUE value will work properly.
Thanks.
You can use composer dump-autoload in command prompt. This will regenerate list of files to be included in the project.
For anybody else that might have this issue.
Codeigniter 3 has third_party folder inside application, use that for putting vendor directory (vendor directory contains the libraries).
composer.json (/composer.json)
tell composer to use the vendor directory inside third_party folder to store libraries
"config": {
"vendor-dir": "application/third_party/vendor"
},
config.php (/application/config/config.php)
Tell Codeigniter 3 to autoload all libraries from third_party/vendor folder
$config['composer_autoload'] = APPPATH . 'third_party/vendor/autoload.php';
PS: Autoloading All Libraries On Every Request could result into a slow website if there are many dependencies and a moderate to heavy traffic site. Load libraries as needed if that is the case.

Issue with PSR-0 autoloading

I am trying to use this composer package with a new project I am working on https://packagist.org/packages/activecollab/activecollab-sdk. However when i try and create a new class I keep getting the following errors.
Fatal error: Class 'ActiveCollab\Client' not found
The file that is throwing this error looks like this.
require "vendor/autoload.php";
new ActiveCollab\Client;
Which is just being used to test if the files are being loaded in properly. The composer.json of the file which I am trying to use looks like such. And I have a feeling the problem is in this file but I can't figure out what.
stuff...
"autoload": {
"psr-0": {
"ActiveCollab\\": "ActiveCollab"
}
}
...stuff
Also looking at the autload_namespaces.php file it is being generated as such.
<?php
// autoload_namespaces.php #generated by Composer
$vendorDir = dirname(dirname(__FILE__));
$baseDir = dirname($vendorDir);
return array(
'ActiveCollab' => array($vendorDir . '/activecollab/activecollab-sdk/ActiveCollab'),
);
I have used psr-0 in some composer packages of my own and everything looks to be right except maybe the camel case in the namespace but i don't see this as being disallowed in the php proposal for psr-0.
Thanks for any help this has been driving me crazy.
The thing is: You cannot simply add a composer.json file with a random autoloading configuration and hope that it works - it actually has to match the naming scheme you are using. That is what this project got wrong, and nobody tested it. Which probably means nobody uses this library, and you can expect no support from the creators due to lack of interest.
But let's see how they react on my pull request to get things back to working again.
The composer config looks fine: Is it just the case that you omitted the leading \ from your class name?
new \ActiveCollab\Client;
You'll need that if your code is inside another namespace, as it will load it relative to the current namespace.
EDIT: I've just checked out that library, and even with the above fix, the autoloader wasn't quite working. The autoloader may also be broken due to the composer.json file for the library specifying a PSR0 autoloader, but using ".class.php" extensions (not PSR0 compatible). An autoload.php file is included with the library, so if you just require that file, you should be able to use the classes:
require 'vendor/activecollab/activecollab-sdk/ActiveCollab/autoload.php';
After doing this, I was able to use the class.

How to use composer with my Yii application

I have developed web app using Yii 1.1.3, and I am very much new with Core php, can anyone give me some detail that how I can use composer with Yii app.
I have used Bootstrap, RESTFull Yii, yii-user and some other extensions.
Your help will be appreciated.
I am assuming that you know how to create your composer.json and so on?
If so then you use Composer with Yii as you would with any other application.
You just have to modify Yii's classMap to make sure it picks up the loaded composer requirements.
Edit your index.php (and probably also your yiic.php in the protected folder if you have one) and load the Composer autoloader and pass the map onto Yii:
$loader = require(__DIR__ . '/../vendor/autoload.php');
Yii::$classMap = $loader->getClassMap();
It is possible you have to modify the include path of course (my example assumes you have a public_html-folder.
If you also want to add your application classes to the map, so that you don't have to add aliases all the time:
"autoload": {
"classmap": [
"protected/"
],
Don't forget to run composer dump-autoload after you add classes then or it won't find them.

Categories