Integrate CHARGEBEE library to LARAVEL - laravel

Im starting using LARAVEL last version 7.12 and I'm having an issue trying to integrate CHARGEBEE library to make request to Chargebee api.
I was reading that I can install packages with composer, I did it:
composer require chargebee/chargebee-php:'>=2, <3'
Doing that now I have downloaded chargebee lib here: /vendor/chargebee/chargebee-php/
Now also I saw This stack overflow question here:
That for the user to correctly use this Library-Package I need to create a ServiceProvider so I did:
php artisan make:provider ChargeBeeServiceProvider
then I really don't know how to write the REGISTER() function here, I added also this line: App\Providers\ChargebeeServiceProvider::class, to /config/app.php to 'providers'
ChargebeeServiceProvider
Right now I have a controller: /app/http/controllers/PortalController and I'm trying to use this:
ChargeBee_Environment::configure("sitename","apikeyvalue");
$all = ChargeBee_Customer::all(array( "firstName[is]" => "John",
"lastName[is]" => "Doe", "email[is]" => "john#test.com" ));
foreach($all as $entry){
$customer = $entry->customer();
$card = $entry->card();
}
PortalController
BUT on the frontend it's giving me an error:
Error Class 'App\Http\Controllers\ChargeBee_Customer' not found
Not really sure how i can use this custom Chargebee library here on Laravel.
can somebody please help to integrate in the correct way ?
Thanks!

The real problem here is that ChargeBee_Environment class doesn't exists.
It should be Chargebee\ChargeBee\Environment. And the Models are in their own folder, for example the Portal is ChargeBee\ChargeBee\Models\PortalSession
WPTC-Troop's answer provides some great information on the issue of using a service provider vs library directly, but in the end you need to call the correct classes.
My working code for creating a portal session is below. It would be similar for a Customer object:
\ChargeBee\ChargeBee\Environment::configure("test-site","test_api_key");
$result = \ChargeBee\ChargeBee\Models\PortalSession::create(["customer" => ["id" => "AzZlwTSSVw9871E9g"]]);
$portalSession = $result->portalSession();
$output = $portalSession->getValues();
return $output;

Two things, you can use any third party library as Service Provider(DI) in Laravel or use it directly where ever you needed(mostly in controller)
Not just third party library you can ease the instance creation of class etc in Service Provider. Basically it's for dependency injection, Check IoC in general you'll understand it better.
You tried/mixed both in your case and didn't completely use any single approach.
You've created a Service Provider called ChargeBeeServiceProvider but it doesn't return/bind any resource or no API initialization done in register method. This is where you register and make use of DI. You can bind in properties as well. Here is the official doc to it.
You tried to use directly by initializing ChargeBee_Environment and use ChargeBee_Customer but you didn't mention where to look for this class that is the reason you get the error(Error Class 'App\Http\Controllers\ChargeBee_Customer' not found). I mean compiler will look for ChargeBee_Environment from the same local space but ChargeBee_Environment is available from global scope.
Simple solution to your same code. Add \ to the class to look from global scope or make use of use statement in the top of your file similar to import in java but still we need to require/include the file in php but don't worry, chargebee make use of autoloader(Check here -> composer.json) so it will be loaded automatically in both approach.
\ChargeBee_Environment::configure("sitename","apikeyvalue");
$all = \ChargeBee_Customer::all(array( "firstName[is]" => "John",
"lastName[is]" => "Doe", "email[is]" => "john#test.com" ));
Try the above and let me know. Answered from mobile device. Code is not tested fully(Just copied your and added \ to it).
Excuse brevity :)

I have a solution to use ChargeBee and Laravel. Don't need any: register provider, add to aliases or add path to autoload in composer.json by file path. Just add in use classes that you need in code your Service or your Controller. Like use ChargeBee_Environment and other.
use ChargeBee_Environment;
use ChargeBee_Customer;
ChargeBee_Environment::configure("sitename","apikeyvalue");
$all = ChargeBee_Customer::all(array( "firstName[is]" => "John", "lastName[is]" => "Doe", "email[is]" => "john#test.com" ));
foreach($all as $entry){
$customer = $entry->customer();
$card = $entry->card();
}

Related

route model binding doesn't work anymore with api package devolpment in in Laravel 8.x

I created an api which is delivered with package development composer. in Laravel 7 it was possible to add the route model binding with:
Route::group(['namespace' => 'Acme\Package\app\Http\Controllers\Api'], function () {
// fomer possibility:
Route::apiResource('api/comments/', 'CommentController')->middleware('bindings');});
In Laravel 8 that's not possible anymore. I've tried almost everything the last days, but either the route-model-binding is not working, or the class can't be found:
Target class [bindings] does not exist.
I really hope someone can post an answer to the problem, or a hint or anything useful.
many thanks in advance
EDIT:
Thanks for the answers, including the middleware in the Route::group like mentioned:
Route::group(['namespace' => 'Acme\Package\app\Http\Controllers\Api', 'middleware' => 'Illuminate\Routing\Middleware\SubstituteBindings']
did it.
In Laravel 8 the alias for this middleware has been removed. You can either use it by its full class name
Illuminate\Routing\Middleware\SubstituteBindings
or add the alias back in to your app/Http/Kernels.php in $routeMiddleware as follows:
protected $routeMiddleware = [
'auth' => Authenticate::class,
'bindings' => Illuminate\Routing\Middleware\SubstituteBindings,
/*...*/
You have to be careful if you are relying on values in someones application to exist. I could use a different name/alias for that middleware if I wanted to in my HTTP Kernel. You should be using the FQCN for that middleware that comes from the framework when referencing it like that.
In a default Laravel 8 install there is no middleware named/aliased as 'bindings'. It is referenced by its FQCN, Illuminate\Routing\Middleware\SubstituteBindings, which is how you should probably be referencing it from a package.
You can provide a config file for someone to alter these things if you would like. Then you can use your configuration to know which middleware to reference.

Laravel app deployment in Heroku fails with handling the post-autoload-dump event returned with error code 1 [duplicate]

I have been using Eloquent as a standalone package in Slim Framework 2 successfully.
But now that I want to make use of Illuminate\Support\Facades\DB since I need to show some statistics by getting the info from 2 tables and using a Left Join and a Counter from the database like this:
use Illuminate\Support\Facades\DB;
$projectsbyarea = DB::table('projects AS p')
->select(DB::raw('DISTINCT a.area, COUNT(a.area) AS Quantity'))
->leftJoin('areas AS a','p.area_id','=','a.id')
->where('p.status','in_process')
->where('a.area','<>','NULL')
->orderBy('p.area_id');
I get the following error:
Type: RuntimeException
Message: A facade root has not been set.
File: ...\vendor\illuminate\support\Facades\Facade.php
Line: 206
How can I solve it?
So far I have found out, in this link that I need to create a new app container and then bind it to the Facade. But I haven't found out how to make it work.
This is how I started the rest of my Eloquent and working fine:
use Illuminate\Database\Capsule\Manager as Capsule;
$capsule = new Capsule();
$capsule->addConnection([
'my' => $app->config->get('settings'),
/* more settings ...*/
]);
/*booting Eloquent*/
$capsule->bootEloquent();
How do I fix this?
Fixed
As #user5972059 said, I had to add $capsule->setAsGlobal();//This is important to make work the DB (Capsule) just above $capsule->bootEloquent();
Then, the query is executed like this:
use Illuminate\Database\Capsule\Manager as Capsule;
$projectsbyarea = Capsule::table('projects AS p')
->select(DB::raw('DISTINCT a.area, COUNT(a.area) AS Quantity'))
->leftJoin('areas AS a','p.area_id','=','a.id')
->where('p.status','in_process')
->where('a.area','<>','NULL')
->orderBy('p.area_id')
->get();
You have to change your code to:
$Capsule = new Capsule;
$Capsule->addConnection(config::get('database'));
$Capsule->setAsGlobal(); //this is important
$Capsule->bootEloquent();
And at the beginning of your class file you have to import:
use Illuminate\Database\Capsule\Manager as DB;
I have just solved this problem by uncommenting $app->withFacades(); in bootstrap/app.php
Had the same issue with laravel 8. I replaced
use PHPUnit\Framework\TestCase;
with:
use Tests\TestCase;
Try uncommenting in app.php $app->withFacades();
Do not forget to call parent::setUp(); before.
fails
public function setUp(): void {
Config::set('something', true);
}
works
public function setUp(): void {
parent::setUp();
Config::set('something', true);
}
One random problem using phpUnit tests for laravel is that the laravel facades have not been initialized when testing.
Instead of using the standard PHPUnit TestCase class
class MyTestClass extends PHPUnit\Framework\TestCase
one can use
class UserTest extends Illuminate\Foundation\Testing\TestCase
and this problem is solved.
I got this error after running:
$ php artisan config:cache
The solution for me was to delete the /bootstrap/cache/config.php file. I'm running Laravel 5.5.
The seems to arise in multiple situation, and not just about facades.
I received the following message while running tests using PHPUnit v.9.5.4, PHP v.8.0.3 and Lumen v. 8.2.2:
PHP Fatal error: Uncaught RuntimeException: A facade root has not
been set. in path_to_project/vendor/illuminate/support/Facades/Facade.php:258
And that happened although I had apparently already configured my app.php to enable facades ($app->withFacades();), still I received this error message whenever I tried to run tests using Illuminate\Support\Facades\DB. Unfortunately, none of the other answers helped me.
This error was actually been thrown due to my configs in phpunit.xml, which didn't point to my app.php file, where I actually enabled facades.
I just had to change
<phpunit (...OTHER_PARAMS_HERE) bootstrap="vendor/autoload.php">
to
<phpunit (...OTHER_PARAMS_HERE) bootstrap="bootstrap/app.php">
Hope it helps.
wrong way
public function register()
{
$this->app->bind('Activity', function($app)
{
new Activity;
});
}
right way 👍
public function register()
{
$this->app->bind('Activity', function($app)
{
return new Activity;
});
}
---------------------------------- don't forget return
Upgrade version for php, I encountered this error while calling the interface.
$ php artisan config:cache
Deleting the /bootstrap/cache/config.php file is a very effective way.
In my project, I managed to fix this issue by using Laravel Dependency Injection when instantiating the object. Previously I had it like this:
$class = new MyClass(
new Client(),
env('client_id', 'test'),
Config::get('myapp.client_secret')
);
The same error message happened when I used Laravel env() and Config().
I introduced the Client and env in the AppServiceProvider like this:
$this->app->bind(
MyClass::class,
function () {
return new MyClass(
new Client(),
env('client_id', 'test')),
Config::get('myapp.client_secret')
);
}
and then instantiated the class like this:
$class = app(MyClass::class);
See more from https://laravel.com/docs/5.8/container .
In my case, for a while a ran a PHP project in PHP version 8, and that time I used some PHP 8 features like param definition and method's multiple return type declarations supported by only PHP 8 and above. When I downgraded from PHP 8 to PHP 7.4 I faced this issue. After removing the return types and param hinting the problems are gone.
Tested on Laravel 8.78
tests/bootstrap.php
<?php
use Illuminate\Foundation\Bootstrap\RegisterFacades;
use Illuminate\Foundation\Bootstrap\LoadConfiguration;
require_once __DIR__ . '/../vendor/autoload.php';
$app = require_once __DIR__ . '/../bootstrap/app.php';
(new LoadConfiguration())->bootstrap($app);// <------- Required for next line
(new RegisterFacades())->bootstrap($app);// <------- Add this line
Here is yet another instance of this error, happened to me after upgrading Laravel 8 to 9.
I had feature tests with a #dataProvider to supply data to those tests. Some of the data supplied by the data provider methods came from an application service. It was being initialised like this:
/**
* #dataProvider myDataProvider
*/
public function testSomeStuff(...)
{
...
}
public function myDataProvider()
{
$myService = app(Service::class); // This is trouble
return [
['test1_data' => $myService::SOME_CONSTANT],
[...],
...
];
}
This worked under Laravel 8, but not in Laravel 9. All other solutions listed in this SO thread were checked and were correctly set up.
The problem is that the application is not being inititialised until after the data provider method is run. It was presumably initialised before this stage in the Laravel 8 install. So app(Service::class) was failing due to it using facades internally.
One workaround could be to force the application to initialise earlier, in the data provider function: $this->createApplication(). I would not recommend this due to potential side effects of the test parts running in the wrong order, though it does appear to work when I tried it.
Best solution is to avoid accessing any part of the application functionality in the data provider methods. In my case it was easy to replace $myService::SOME_CONSTANT with MyService::SOME_CONSTANT after making sure those constants were public.
Hopefully this will help somebody suddenly hitting this problem running feature tests after a Laravel 9 upgrade.
If you recently upgrade Laravel on Homestead & VirtualBox environment or do not find any reason that causing please be sure your Vagrant is up to date.
Referance
I had Taylor lock this thread. The past several replies have restated the solution, which is to Upgrade to Virtualbox 6.x, the thread is locked to prevent other issues that are not related from being dogpiled on here.
#melvin's answer above works correctly.
In case someone is wondering about it, the mistake people do is to choose Yes when VSCode asks them if they are making a Unit Test. Remember, Unit Tests should really be unit tests, independent of other application features (models, factories, routes; basically anything that would require the Laravel app to be fired up). In most scenarios, people really actually want to make Feature Tests and therefore should answer No to the above question. A feature test inherits from Tests\TestCase class (which takes care of firing up Laravel app before running the test) unlike unit tests that inherit from the class PHPUnit\Framework\TestCase which use just PHPUnit and are therefore much faster.
credit with thanks to #Aken Roberts's answer here.
From Laravel Documentation: Generally, most of your tests should be feature tests. These types of tests provide the most confidence that your system as a whole is functioning as intended.

OctoberCMS and BotMan

I want to integrate a chatbot (BotMan version 2.0) into an existing OctoberCMS project , here is what I did till now :
1- I added BotMan to the projct using the following command :
composer require botman/botman
2- I created a routes.php file in the same directory as the plugin.php file
<?php
use BotMan\BotMan\BotMan;
use BotMan\BotMan\BotManFactory;
use BotMan\BotMan\Drivers\DriverManager;
//Route::match(['get', 'post'], '/botman', 'BotManController#handle');
//Route::get('/botman/tinker', 'October\Demo\BotManController#tinker');
// Create an instance
$botman = BotManFactory::create($config);
// Give the bot something to listen for.
$botman->hears('hello', function (BotMan $bot) {
$bot->reply('Hello yourself.');
});
// Start listening
$botman->listen();
My questions are :
1- Where I have to add the BotManController.php file
2- I tried to add BotManController.php in the same directory as the routes.php file but I get the following error :
Class 'App\Http\Controllers\Controller' not found
( and thats because its an OctoberCMS project not Laravel project ... I dont have the App directory )
Can anyone please provide me a solution to that or another way to integrate Botman into OctoberCMS !
First off, read https://luketowers.ca/blog/how-to-use-laravel-packages-in-october-cms-plugins/ as well as https://octobercms.com/docs/plugin/composer.
Secondly, you can put the BotManController file anywhere in your plugin you want as long as you understand PHP namespaces and how to properly reference it where you want to. I would probably recommend putting it in a /classes/ directory under your plugin folder, and then changing the App\Http\Controllers\Controller reference to instead reference the base Illuminate\Routing\Controller class. You could also put it in a /controllers/ directory, but in OctoberCMS that is typically reserved for your backend controllers so I wouldn't recommend mixing the two.

Hot to use emcconville/google-map-polyline-encoding-tool in laravel

Hi i have installed emcconville/google-map-polyline-encoding-tool in Laravel, with composer, but cant see any references to the extension when i try yo use it in a class.
Do i need to register the extension anywhere in Laravel?
You don't need to register the package as an extension, the class Polyline coming from the package is automatically loaded with PHP/Composer autoload mechanism, so you can use it directly in your code (as per docs):
$points = array(
array(41.89084,-87.62386),
array(41.89086,-87.62279),
array(41.89028,-87.62277),
array(41.89028,-87.62385),
array(41.89084,-87.62386)
);
$encoded = \Polyline::encode($points);

Why can't my class be found, when it's in the same namespace?

I have created a modules folder in my Laravel app. There are two modules so far, but I'm just concentrating on core here.
I'm using Confide and Entrust to build User functionality, like so:
namespace App\Modules\Core;
use Zizaco\Confide\ConfideUser;
use Zizaco\Entrust\HasRole;
class User extends ConfideUser {
use HasRole;
}
and Permissions:
namespace App\Modules\Core;
use Zizaco\Entrust\EntrustPermission;
class Permission extends EntrustPermission
{
}
and Roles:
namespace App\Modules\Core;
use Zizaco\Entrust\EntrustRole;
class Role extends EntrustRole
{
}
My Composer.json autoload reads:
"autoload": {
"classmap": [
"app/commands",
"app/controllers",
"app/models",
"app/database/migrations",
"app/database/seeds",
"app/tests/TestCase.php",
"app/modules"
],
"psr-0": {
"App\\Modules\\": "modules/"
}
},
I put the psr-0 stuff in there because I couldn't get things to work. They still don't work, though the output autoload files when I run composer seem to have promising entries in them.
The database has been migrated, and now I'm trying to run the database seeding. My seeding script reads:
use App\Modules\Core\User;
use App\Modules\Core\Role;
use App\Modules\Core\Permission;
class UserTablesSeeder extends Seeder {
public function run()
{
DB::table('users')->insert(array(
'email' => 'xxx',
'first_name' => 'xxx',
'password' => 'xxxx',
'active' => 1
));
$admin = new Role;
$admin->name = 'Admin';
$admin->save();
$manageUsers = new Permission;
$manageUsers->name = 'manage_standard_users';
$manageUsers->display_name = 'Manage Users';
$manageUsers->save();
$admin->perms()->sync(array($manageUsers->id));
$user = User::where('email','=','xxx')->first();
$user->attachRole($admin);
}
}
But when I run php artisan db:seed I get an error:
PHP Fatal error: Class 'Permission' not found in /home/wedding/quincy/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php on line 604
{"error":{"type":"Symfony\\Component\\Debug\\Exception\\FatalErrorException","message":"Class 'Permission' not found","file":"\/home\/wedding\/quincy\/vendor\/laravel\/framework\/src\/Illuminate\/Database\/Eloquent\/Model.php","line":604}}
If I get rid of all the namespacing it all works just fine, but I think I should keep the namespaces because of the modularity I'm trying to create.
I've run composer dump-autoload, and install for when I added the psr-0 entry. So I'm not sure what else I need to do. I'm very new to composer, so at this point I'm lost as to what the problem is.
Thanks in advance.
Don't know if you found your answer.
I think you need to update your role and permission namespaced class names here:
File: vendor/entrust/config/config.php:
(Default is just "Role" and "Permission" without a namespace, so it doesn't work when you move your implementations into one).
You also have two other options:
add an alias for the fully namedspaced permission and role class on the app/config.php (Role => "Namespace").
there's a mechanism to override package config settings with appropriately named files. You can override just the two entries you need (the Role and Permission namespaces).
Confide and Entrust both are looking for Role and Permission model in global namespace. As you have changed namespace of both these models, Confide and Entrust are not able to find it. To solve this problem, you need to override Entrust configuration.
Create directory "app/config/packages/zizaco/entrust"
Copy file "vendor/zizaco/entrust/src/config/config.php" to "app/config/packages/zizaco/entrust/config.php"
Edit "app/config/packages/zizaco/entrust/config.php" and change following two lines
'role' => 'App\Modules\Core\Role',
'permission' => 'App\Modules\Core\Permission',
php artisan clear-compiled
php artisan optimize
You should rely on Laravel's packages (created thru Workbench, for instance) while developing localy.
Packages are the primary way of adding functionality to Laravel.
Workbench packages and their classes are handled automaticaly by Laravel - no need to configure anything.
More informations here: http://laravel.com/docs/packages
if you want to use your own modules instead of standard workbench packages, check out this article that depics how to achieve that:
http://creolab.hr/2013/05/modules-in-laravel-4/
summary by the author ( Boris Strahija ):
Laravel 4 is heavily based on composer packages, which is a good thing, but sometimes developers (like myself) like to separate their code into modules. This is especially nice when building larger projects. Now this was fairly easy to do in Laravel 3 with the bundles system, but in Laravel 4 many people just recommend building packages since L4 has a nice workbench feature. This is all good, but sometimes I like to separate my app specific controllers and views into modules, and not have to go through it with the workbench.
In short, you have to
put your modules code somwhere (for example /app/modules/)
include the directory in composer.json file, under autoload/classmap
create an appropriate service providers (Laravel 4 uses service providers to register and boot up the packages, you can use it with modules as well)
register the service providers - add them to app config in “app/config/app.php” under the providers array
So now we have out modules fully working. You can add module specific routes, group your controllers/views/models, get module configuration like this:
Config::get('content::channels');
Or get translated phrases like this:
Lang::get('shop::errors.no_items_in_cart');
Finally, to test your modules you can create some routes, but that is up to you how you use your code.
If you look at Doctrine composer.json, for example /vendor/doctrine/cache/composer.json:
"autoload": {
"psr-0": { "Doctrine\\Common\\Cache\\": "lib/" }
},
The files are located in:
/vendor/doctrine/cache/lib/Doctrine/Common/Cache/ArrayCache.php
/vendor/doctrine/cache/lib/Doctrine/Common/Cache/Cache.php
... and so on
By that logic, I think you should put your files in:
modules/App/Modules/Core/User.php
modules/App/Modules/Core/Permission.php
modules/App/Modules/Core/Role.php
From you screenshot the Permission class is located in the models folder so when you include your namespace you should type
use App\Modules\Core\Models\Permission;

Resources