Load third-party non-CakePHP library - php

I'm trying to integrate a proprietary third-party library into my CakePHP app. All I could find in the manual is the App Class section but it's basically a set of examples rather than a proper explanation so I'm trying to guess.
I got the impression that you should use the App::uses() alternative when possible and at first I thought I was lucky because this code:
App::build(
array(
'Vendor' => array(
APP . 'Vendor' . DS . 'Acme' . DS. 'API-1.0' . DS . 'base',
APP . 'Vendor' . DS . 'Acme' . DS. 'API-1.0' . DS . 'foo',
APP . 'Vendor' . DS . 'Acme' . DS. 'API-1.0' . DS . 'bar',
)
)
);
debug(App::objects('Vendor'));
... produces this output:
array(
(int) 0 => 'Autoload',
(int) 1 => 'ConstantsBase',
(int) 2 => 'Foo',
(int) 3 => 'Bar',
)
However, I can't do anything like this:
App::uses('Foo', 'Vendor');
new Foo();
... triggers:
Error: Class 'Foo' not found
How comes CakePHP does know about the library classes but won't load them?

Apparently, directory paths need to have a trailing slash:
// Incorrect
APP . 'Vendor' . DS . 'Acme' . DS. 'API-1.0' . DS . 'base',
// Correct
APP . 'Vendor' . DS . 'Acme' . DS. 'API-1.0' . DS . 'base' . DS,
It's just mandatory, though its omission doesn't seem to trigger any error message.

Related

Unit testing CakePHP 3 plugin requires a config/routes.php folder to test with Router::url()

I am writing some tests for a CakePHP 3 plugin, and some of my actions use Router::url calls. When I run phpunit I get the following error: include([project dir]\\config\routes.php): failed to open stream: No such file or directory.
What I'd like to know is if this file is really required just for unit testing to work. If I create the file on that folder the testing works right. I have tried adding
DispatcherFactory::add('Asset');
DispatcherFactory::add('Routing');
DispatcherFactory::add('ControllerFactory');
to my tests/bootstrap.php file, however it did no change at all.
Since this is a standalone plugin I'd find it a little odd to have a config folder with a routes.php file in it for the sole purpose of testing. Is there any workaround to this?
The router requires a routes.php file to be present on application level, so what you should do is configure a test application environment where you can place such files.
In your tests/bootstrap.php file, define the required constants and configuration that your test environment needs. If it where just for the router, it would probably be enough if you'd define the CONFIG constant accordingly, which is being used in \Cake\Routing\Router::_loadRoutes(), like
define('CONFIG', dirname(__DIR__) . DS . 'tests' . DS . 'TestApp' . DS . 'config' . DS);
This would set the config dir to tests/TestApp/config/, where you could place the routes.php file.
Generally I'd recommend to setup all constants, and at least basic application configuration, here's an example from one of my plugins:
use Cake\Core\Configure;
use Cake\Core\Plugin;
if (!defined('DS')) {
define('DS', DIRECTORY_SEPARATOR);
}
define('ROOT', dirname(__DIR__));
define('APP_DIR', 'src');
define('APP_ROOT', ROOT . DS . 'tests' . DS . 'TestApp' . DS);
define('APP', APP_ROOT . APP_DIR . DS);
define('CONFIG', APP_ROOT . DS . 'config' . DS);
define('WWW_ROOT', APP . DS . 'webroot' . DS);
define('TESTS', ROOT . DS . 'tests' . DS);
define('TMP', APP_ROOT . DS . 'tmp' . DS);
define('LOGS', APP_ROOT . DS . 'logs' . DS);
define('CACHE', TMP . 'cache' . DS);
define('CAKE_CORE_INCLUDE_PATH', ROOT . DS . 'vendor' . DS . 'cakephp' . DS . 'cakephp');
define('CORE_PATH', CAKE_CORE_INCLUDE_PATH . DS);
define('CAKE', CORE_PATH . 'src' . DS);
require_once ROOT . DS . 'vendor' . DS . 'autoload.php';
require_once CORE_PATH . 'config' . DS . 'bootstrap.php';
$config = [
'debug' => true,
'App' => [
'namespace' => 'App',
'encoding' => 'UTF-8',
'defaultLocale' => 'en_US',
'base' => false,
'baseUrl' => false,
'dir' => 'src',
'webroot' => 'webroot',
'wwwRoot' => WWW_ROOT,
'fullBaseUrl' => 'http://localhost',
'imageBaseUrl' => 'img/',
'cssBaseUrl' => 'css/',
'jsBaseUrl' => 'js/',
'paths' => [
'plugins' => [APP_ROOT . 'plugins' . DS],
'templates' => [APP . 'Template' . DS],
'locales' => [APP . 'Locale' . DS],
],
]
];
Configure::write($config);
date_default_timezone_set('UTC');
mb_internal_encoding(Configure::read('App.encoding'));
ini_set('intl.default_locale', Configure::read('App.defaultLocale'));
Plugin::load('MyPlugin', ['path' => ROOT]);

Cannot Php artisan serve cause of cannot redeclare class Composer

I can't run using php artisan serve cause of :
PHP Fatal error: Cannot redeclare class Composer\Autoload\ComposerStaticInit4783eae8fdb0bbd7059e05caa6aed997 in /var/www/html/project/config/vendor/composer/autoload_static.php
Script php artisan optimize handling the post-update-cmd event returned with error code 255
Heres is my autoload_static.php:
class ComposerStaticInit57efd0b78daf784a291fa20fc5e6edcd
{
public static $files = array (
'0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => __DIR__ . '/..' . '/symfony/polyfill-mbstring/bootstrap.php',
'667aeda72477189d0494fecd327c3641' => __DIR__ . '/..' . '/symfony/var-dumper/Resources/functions/dump.php',
'1d1b89d124cc9cb8219922c9d5569199' => __DIR__ . '/..' . '/hamcrest/hamcrest-php/hamcrest/Hamcrest.php',
'3919eeb97e98d4648304477f8ef734ba' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/Random.php',
'5255c38a0faeba867671b61dfda6d864' => __DIR__ . '/..' . '/paragonie/random_compat/lib/random.php',
'2c102faa651ef8ea5874edb585946bce' => __DIR__ . '/..' . '/swiftmailer/swiftmailer/lib/swift_required.php',
'bd9634f2d41831496de0d3dfe4c94881' => __DIR__ . '/..' . '/symfony/polyfill-php56/bootstrap.php',
'a0edc8309cc5e1d60e3047b5df6b7052' => __DIR__ . '/..' . '/guzzlehttp/psr7/src/functions_include.php',
'c964ee0ededf28c96ebd9db5099ef910' => __DIR__ . '/..' . '/guzzlehttp/promises/src/functions_include.php',
'e7223560d890eab89cda23685e711e2c' => __DIR__ . '/..' . '/psy/psysh/src/Psy/functions.php',
'f18cc91337d49233e5754e93f3ed9ec3' => __DIR__ . '/..' . '/laravelcollective/html/src/helpers.php',
'37a3dc5111fe8f707ab4c132ef1dbc62' => __DIR__ . '/..' . '/guzzlehttp/guzzle/src/functions_include.php',
'f0906e6318348a765ffb6eb24e0d0938' => __DIR__ . '/..' . '/laravel/framework/src/Illuminate/Foundation/helpers.php',
'58571171fd5812e6e447dce228f52f4d' => __DIR__ . '/..' . '/laravel/framework/src/Illuminate/Support/helpers.php',
);
}
already try composer install and update but still didnt work at all. anyone know ?
So the problem is wrong step while compose require internvention/image. i didnt check the app/config.php first. should comment the provider and the aliases. i think the case is solve. thank you everyone.

Cannot find existing key in array

I'm working with composer and I have the following classmap:
return array(
'Wit\\Cache\\CacheAdapterInterface' => $baseDir . '/src/Wit/Cache/CacheAdapterInterface.php',
'Wit\\Cache\\CacheManager' => $baseDir . '/src/Wit/Cache/CacheManager.php',
'Wit\\Cache\\FileAdapter' => $baseDir . '/src/Wit/Cache/FileAdapter.php',
'Wit\\Cache\\RedisAdapter' => $baseDir . '/src/Wit/Cache/RedisAdapter.php',
'Wit\\Request\\Request' => $baseDir . '/src/Wit/Request/Request.php',
'Wit\\Zenpoint\\ZenpointUser' => $baseDir . '/src/Wit/Zenpoint/ZenpointUser.php',
'Wit\\Zenpoint\\ZenpointConfig' => $baseDir . '/src/Wit/Zenpoint/ZenpointConfig.php',
'Wit\\Zenpoint\\ZenpointCarrello' => $baseDir . '/src/Wit/Zenpoint/ZenpointCarrello.php',
'Wit\\Zenpoint\\ZenpointAcquisitions' => $baseDir . '/src/Wit/Zenpoint/ZenpointAcquisitions.php',
'Wit\\Zenpoint\\ZenpointAcquisition' => $baseDir . '/src/Wit/Zenpoint/ZenpointAcquisition.php',
'Wit\\Cart\\ZipCodeChecker' => $baseDir . '/src/Wit/Cart/ZipCodeChecker.php',
'Wit\\Cart\\ZipCodeLoader' => $baseDir . '/src/Wit/Cart/ZipCodeLoader.php',
'Wit\\Complimentary\\OmaggioOrdine' => $baseDir . '/src/Wit/Complimentary/OmaggioOrdine.php',
'Wit\\Complimentary\\PacchettoOmaggio' => $baseDir . '/src/Wit/Complimentary/PacchettoOmaggio.php',
'Wit\\Complimentary\\ProdottiAScelta' => $baseDir . '/src/Wit/Complimentary/ProdottiAScelta.php',
'Wit\\Complimentary\\OmaggioLoader' => $baseDir . '/src/Wit/Complimentary/OmaggioLoader.php',
'Wit\\Complimentary\\PacchettoLoader' => $baseDir . '/src/Wit/Complimentary/PacchettoLoader.php',
'Wit\\Complimentary\\ProdottiASceltaLoader' => $baseDir . '/src/Wit/Complimentary/ProdottiASceltaLoader.php',
'Wit\\Complimentary\\ProdottiLoader' => $baseDir . '/src/Wit/Complimentary/ProdottiLoader.php',
);
I then have the following in a file: use WIT\Complimentary\OmaggioLoader;
The problem is that PHP says it cannot find the class:
Fatal error: Class 'WIT\ComplimentaryProducts\OmaggioLoader' not found.
The first thing I thought was that the path was wrong, but it doesn't seem so. So I tried to see what was happening in the Composer ClassLoader.php file and dumped the following:
var_dump($class); //string(31) "WIT\Complimentary\OmaggioLoader"
var_dump(array_keys($this->classMap)); //[15]=> string(31) "Wit\Complimentary\OmaggioLoader"
var_dump(array_key_exists($class, $this->classMap)); //bool(false)
var_dump($this->classMap[$class]); //NULL
var_dump($this->classMap['Wit\\Complimentary\\OmaggioLoader']);//string(69) "/path/to/Wit/Complimentary/OmaggioLoader.php"
So, why PHP cannot find the array element if the key is correct? Why if I insert it manually, will PHP finds it?
Class names in PHP are case insensitive, array keys are not. They have different beginning.

creating a zf2 module without controllers with some autoloaded classes

I'm trying to create a Zend Framework 2 module that has some generic classes that I want to use in some of my controllers.
I created a directory called 'tux-drink-zf2-module' in 'vendor' directory.
I added that directory to 'application.config.php'.
my Module.php has the following:
<?php
namespace TuxDrink;
use Zend\ModuleManager\Feature\AutoloaderProviderInterface;
class Module implements AutoloaderProviderInterface
{
public function getAutoloaderConfig()
{
return array(
'Zend\Loader\ClassMapAutoloader' => array(
__DIR__ . '/autoload_classmap.php',
),
'Zend\Loader\StandardAutoloader' => array(
'namespaces' => array(
__NAMESPACE__ => __DIR__ . '/src/' . __NAMESPACE__,
),
),
);
}
}
update
new:
my autoload_classmap.php has the following:
<?php
// Generated by ZF2's ./bin/classmap_generator.php
return array(
'TuxDrink\Module' => __DIR__ . '/Module.php',
'TuxDbCassandra' => __DIR__ . '/src/TuxDrink/TuxDb/Cassandra/TuxDbCassandra.php',
'TuxDrink\Drink\Model\AlcoholSum' => __DIR__ . '/src/TuxDrink/TuxDb/Mysql/Drink/Model/AlcoholSum.php',
'TuxDrink\Drink\Model\AlcoholSumTable' => __DIR__ . '/src/TuxDrink/TuxDb/Mysql/Drink/Model/AlcoholSumTable.php',
'TuxDrink\Drink\Model\Drink' => __DIR__ . '/src/TuxDrink/TuxDb/Mysql/Drink/Model/Drink.php',
'TuxDrink\Drink\Model\DrinkBrand' => __DIR__ . '/src/TuxDrink/TuxDb/Mysql/Drink/Model/DrinkBrand.php',
'TuxDrink\Drink\Model\DrinkBrandTable' => __DIR__ . '/src/TuxDrink/TuxDb/Mysql/Drink/Model/DrinkBrandTable.php',
'TuxDrink\Drink\Model\DrinkCompany' => __DIR__ . '/src/TuxDrink/TuxDb/Mysql/Drink/Model/DrinkCompany.php',
'TuxDrink\Drink\Model\DrinkCompanyTable' => __DIR__ . '/src/TuxDrink/TuxDb/Mysql/Drink/Model/DrinkCompanyTable.php',
'TuxDrink\Drink\Model\DrinkFlavor' => __DIR__ . '/src/TuxDrink/TuxDb/Mysql/Drink/Model/DrinkFlavor.php',
'TuxDrink\Drink\Model\DrinkFlavorTable' => __DIR__ . '/src/TuxDrink/TuxDb/Mysql/Drink/Model/DrinkFlavorTable.php',
'TuxDrink\Drink\Model\DrinkFlavorType' => __DIR__ . '/src/TuxDrink/TuxDb/Mysql/Drink/Model/DrinkFlavorType.php',
'TuxDrink\Drink\Model\DrinkFlavorTypeTable' => __DIR__ . '/src/TuxDrink/TuxDb/Mysql/Drink/Model/DrinkFlavorTypeTable.php',
'TuxDrink\Drink\Model\DrinkIngredient' => __DIR__ . '/src/TuxDrink/TuxDb/Mysql/Drink/Model/DrinkIngredient.php',
'TuxDrink\Drink\Model\DrinkIngredientTable' => __DIR__ . '/src/TuxDrink/TuxDb/Mysql/Drink/Model/DrinkIngredientTable.php',
'TuxDrink\Drink\Model\DrinkIngredientType' => __DIR__ . '/src/TuxDrink/TuxDb/Mysql/Drink/Model/DrinkIngredientType.php',
'TuxDrink\Drink\Model\DrinkIngredientTypeTable' => __DIR__ . '/src/TuxDrink/TuxDb/Mysql/Drink/Model/DrinkIngredientTypeTable.php',
'TuxDrink\Drink\Model\DrinkTable' => __DIR__ . '/src/TuxDrink/TuxDb/Mysql/Drink/Model/DrinkTable.php',
'TuxDrink\Drink\Model\DrinkType' => __DIR__ . '/src/TuxDrink/TuxDb/Mysql/Drink/Model/DrinkType.php',
'TuxDrink\Drink\Model\DrinkTypeTable' => __DIR__ . '/src/TuxDrink/TuxDb/Mysql/Drink/Model/DrinkTypeTable.php',
'TuxDrink\Drink\Model\GlobalImage' => __DIR__ . '/src/TuxDrink/TuxDb/Mysql/Drink/Model/GlobalImage.php',
'TuxDrink\Drink\Model\GlobalImageLink' => __DIR__ . '/src/TuxDrink/TuxDb/Mysql/Drink/Model/GlobalImageLink.php',
'TuxDrink\Drink\Model\GlobalImageLinkPending' => __DIR__ . '/src/TuxDrink/TuxDb/Mysql/Drink/Model/GlobalImageLinkPending.php',
'TuxDrink\Drink\Model\GlobalImageLinkPendingTable' => __DIR__ . '/src/TuxDrink/TuxDb/Mysql/Drink/Model/GlobalImageLinkPendingTable.php',
'TuxDrink\Drink\Model\GlobalImageLinkTable' => __DIR__ . '/src/TuxDrink/TuxDb/Mysql/Drink/Model/GlobalImageLinkTable.php',
'TuxDrink\Drink\Model\GlobalImageTable' => __DIR__ . '/src/TuxDrink/TuxDb/Mysql/Drink/Model/GlobalImageTable.php',
'TuxDrink\Drink\Model\GlobalImageType' => __DIR__ . '/src/TuxDrink/TuxDb/Mysql/Drink/Model/GlobalImageType.php',
'TuxDrink\Drink\Model\GlobalImageTypeTable' => __DIR__ . '/src/TuxDrink/TuxDb/Mysql/Drink/Model/GlobalImageTypeTable.php',
'TuxDrink\Drink\Model\LiquidColor' => __DIR__ . '/src/TuxDrink/TuxDb/Mysql/Drink/Model/LiquidColor.php',
'TuxDrink\Drink\Model\LiquidColorTable' => __DIR__ . '/src/TuxDrink/TuxDb/Mysql/Drink/Model/LiquidColorTable.php',
'TuxDrink\Drink\Model\LiquidColorType' => __DIR__ . '/src/TuxDrink/TuxDb/Mysql/Drink/Model/LiquidColorType.php',
'TuxDrink\Drink\Model\LiquidColorTypeTable' => __DIR__ . '/src/TuxDrink/TuxDb/Mysql/Drink/Model/LiquidColorTypeTable.php',
'TuxDrink\Drink\Model\PendingDrinkCommits' => __DIR__ . '/src/TuxDrink/TuxDb/Mysql/Drink/Model/PendingDrinkCommits.php',
'TuxDrink\Drink\Model\PendingDrinkCommitsTable' => __DIR__ . '/src/TuxDrink/TuxDb/Mysql/Drink/Model/PendingDrinkCommitsTable.php',
'TuxDrink\TuxDb\Mysql\Drink\TuxDbMysqlDrink' => __DIR__ . '/src/TuxDrink/TuxDb/Mysql/Drink/TuxDbMysqlDrink.php',
'TuxDrink\TuxDb\Drink\Util\AlcoholCalc' => __DIR__ . '/src/TuxDrink/TuxDb/Mysql/Drink/Util/AlcoholCalc.php',
'TuxDrink\TuxDb\Mysql\TuxDbMysql' => __DIR__ . '/src/TuxDrink/TuxDb/Mysql/TuxDbMysql.php',
'TuxDrink\TuxDb\TuxDbAbstract' => __DIR__ . '/src/TuxDrink/TuxDb/TuxDbAbstract.php',
'TuxDrink\TuxDb\TuxDbInterface' => __DIR__ . '/src/TuxDrink/TuxDb/TuxDbInterface.php',
'TuxDrink\TuxDb\TuxDrinkInterface' => __DIR__ . '/src/TuxDrink/TuxDb/TuxDrinkInterface.php',
'TuxDrink\TuxDb\TuxTableInterface' => __DIR__ . '/src/TuxDrink/TuxDb/TuxTableInterface.php',
);
but still when I try to refresh my project I get the following error:
Fatal error: Uncaught exception 'Zend\ModuleManager\Exception\RuntimeException' with message 'Module (tux-drink-zf2-module) could not be initialized.' in /Volumes/2g-storage/projects/php-projects/myalcoholist/vendor/zendframework/zendframework/library/Zend/ModuleManager/ModuleManager.php on line 144
maybe i'm missing some other files in order to properly configure this as a Module?
remember, this is a package for sources, without controllers, views and actions.
any information regarding the issue would be greatly appreciated.
update
this issue was solved when i fixed the directories structure.
but when I'm trying to use the module in one the the controllers.
in my case i need to use two classes from the TuxDrink module.
class 'TuxDbMysqlDrink' and class 'TuxDbMysql'.
I need to use them in controller 'DrinkController' in action 'drink-brand-autocomplete'.
I use the following code:
use \TuxDb\Mysql\Drink\TuxDbMysqlDrink;
use \TuxDb\Mysql\TuxDbMysql;
public function drinkBrandAutocompleteAction() {
$param=$this->getRequest()->getQuery('q');
if ($param) {
$drink = new TuxDbMysqlDrink();
$result=$drink->autoCompleteDrinkBrand($param);
return $result;
}
}
and I get the following error message:
Fatal error: DrinkManagement\Controller\DrinkController cannot use TuxDrink\TuxDb\Mysql\Drink\TuxDbMysqlDrink - it is not a trait in /Volumes/2g-storage/projects/php-projects/myalcoholist/module/DrinkManagement/src/DrinkManagement/Controller/DrinkController.php on line 197
any ideas?
tried to google, couldn't understand what it means "it is not a trait"
update
resolved it with this code:
public function drinkBrandAutocompleteAction() {
$param=$this->getRequest()->getQuery('q');
if ($param) {
$drink = new \TuxDrink\TuxDb\Mysql\Drink\TuxDbMysqlDrink();
$result=$drink->autoCompleteDrinkBrand($param);
die(var_export($result,1));
...
Going by the error, the Module name is tux-drink-zf2-module. Taking sanitization into account, i'll assume your module is CamelCased like TuxDrinkZf2Module. Therefore the namespace you're assigning inside Module.php doesn't match, as it's only TuxDrink.
So my guess would be, either of your names is incorrect.

how to use Yii namespace

I'm having I confusion in understanding the namespace from the Yii documentation as their are not enough example to understand, as I'm new to Yii framework please give some easy and detailed examples so that I can understand it's purpose.
You may try read this documentation http://yiiframework.ru/doc/guide/en/basics.namespace
In general Yii namespaces - it is aliases for folders.
I.E.
'aliases' => array(
'frontend' => dirname(__FILE__) . '/../..' . '/frontend',
'common' => dirname(__FILE__) . '/../..' . '/common',
'backend' => dirname(__FILE__) . '/../..' . '/backend',
'vendor' => dirname(__FILE__) . '/../..' . '/common/lib/vendor'
),
...
'import' => array(
'common.extensions.components.*',
'common.components.*',
'common.helpers.*',
'common.models.*',
'application.controllers.*',
// In result "common" = dirname(__FILE__) . '/../..' . '/common'

Categories