I'm trying to add usage records to my subscription. using the stripe create usage record endpoint (https://stripe.com/docs/api#usage_record_create).
running my function im getting an error returning saying Class 'Stripe\UsageRecord' not found in file I havent defined the namespace because I have beeen accessing it directly referencing stripe using \Stripe\ which I brought in using composer. I've tried a composer update but that didnt seem to do the trick. I'm guessing it's missing the UsageRecord.php file from the composer install but I have no clue where to add a copy of the file to the stripe package
public function stripeUsageRecord()
{
$authUser = auth()->user();
$business = $authUser['business_id'];
$user_amount = Transactions::select("user_id")
->where("business_id", "=", $business)
->groupBy("user_id")->count();
$current_time = Carbon::now()->toDateTimeString();
\Stripe\Stripe::setApiKey(env("STRIPE_SECRET"));
\Stripe\UsageRecord::create(array(
"quantity" => $user_amount,
"timestamp" => $current_time,
"subscription_item" => 'sub_DnAKVwNY2Sc4zf',
"action" => 'set'
));
}
Most likely you're using too old version of this library. Stripe\UsageRecord was introduced in version 6.6.0, so I suggest to update library to the last version:
composer require "stripe/stripe-php:^6.19"
You definitely should not modify content of vendor directory and copy&paste classes from different version of library.
Seemed like I was missing a part of the stripe package.
I found a copy of UsageRecord.php online and created the file in path vendor\stripe\stripe-php\lib\UsageRecord.php
I then added the contents of the code that I found online and added them to the file and it worked. The contents are posted below:
<?php
namespace Stripe;
/**
* Class UsageRecord
*
* #package Stripe
*
* #property string $id
* #property string $object
* #property bool $livemode
* #property int $quantity
* #property string $subscription_item
* #property int $timestamp
*/
class UsageRecord extends ApiResource
{
const OBJECT_NAME = "usage_record";
/**
* #param array|null $params
* #param array|string|null $options
*
* #return \Stripe\ApiResource The created resource.
*/
public static function create($params = null, $options = null)
{
self::_validateParams($params);
if (!array_key_exists('subscription_item', $params)) {
throw new Error\InvalidRequest("Missing subscription_item param in request", null);
}
$subscription_item = $params['subscription_item'];
$url = "/v1/subscription_items/$subscription_item/usage_records";
$request_params = $params;
unset($request_params['subscription_item']);
list($response, $opts) = static::_staticRequest('post', $url, $request_params, $options);
$obj = \Stripe\Util\Util::convertToStripeObject($response->json, $opts);
$obj->setLastResponse($response);
return $obj;
}
}
Related
I am working in a project where I must call SOAP WS. I used WSDLtoPHP, that's really helpful.
I can READ data, and now I would like to create new item with the web services. But when I tried to insert data in the field Nom, I have an error, because the soap server thinks I am trying to insert my data ($nom) inside the attribute NomVide of the field Nom, of the generated xml structure with my code:
<ven1:Nom NomVide="$nom"></ven1:Nom>
$createClient = $SC->S001_Creation_Client(new \StructType\S001_Creation_Client(
new \StructType\RootWSReturnError(
new \StructType\Header("","","","","",array(),"","","","","","","","","","","",array(),"",0,0,"",array(),array(),"","","","","","","","","","","","","","","","","","","","",0,0,"","",array(),"","","","",0,0,0,0,0,0,0),null),
new \StructType\RootWSVenteParametres (array( new \StructType\Vente (array("secret_key")))),
new \StructType\RootWSVenteClient(
array(new \StructType\Client(
new \StructType\General(
"3333",
array(),
array(),
null,
new \StructType\Nom ($nom),
new \StructType\NomRecherche ($nomrecherche),
new \StructType\Nom2 ($nom2),
new \StructType\Marque1($marque1),
new \StructType\Marque2 ($marque2),
new \StructType\Adresse1 (),
new \StructType\Adresse2 (),
new \StructType\CodePostal(),
new \StructType\Ville (),
new \StructType\County (),
new \StructType\CountryRegion (),
new \StructType\CurrencyCode ($currencyCode),
new \StructType\CreditLimit ($creditLimit),
new \StructType\Blocked ($blocked),
new \StructType\PaymentMethodCode ($paymentMethodCode),
new \StructType\CustDiscGroup ($custDiscGroup),
new \StructType\SalespersonCode ($salespersonCode),
new \StructType\EquipeAgentCode ($equipeAgentCode),
new \StructType\LocationCode($locationCode),[...]
Logs of the SOAP server gave to me then I am trying to do this:
<ven1:Nom NomVide="$nom"></ven1:Nom>
And it is false of course...
BUT I NEED :
<ven1:Nom NomVide="">$nom</ven1:Nom>
Here is my StructType\Nom class code:
class Nom extends AbstractStructBase
{
/**
* The NomVide
* Meta information extracted from the WSDL
* - use: optional
* #var string|null
*/
protected ?string $NomVide = null;
/**
* Constructor method for Nom
* #uses Nom::setNomVide()
* #param string $nomVide
*/
public function __construct(?string $nomVide = null)
{
$this
->setNomVide($nomVide);
}
/**
* Get NomVide value
* #return string|null
*/
public function getNomVide(): ?string
{
return $this->NomVide;
}
/**
* Set NomVide value
* #param string $nomVide
* #return \StructType\Nom
*/
public function setNomVide(?string $nomVide = null): self
{
// validation for constraint: string
if (!is_null($nomVide) && !is_string($nomVide)) {
throw new InvalidArgumentException(sprintf('Invalid value %s, please provide a string, %s given', var_export($nomVide, true), gettype($nomVide)), __LINE__);
}
$this->NomVide = $nomVide;
return $this;
}
}
Per example there is no problem with the value "3333", which is just a simple string type.
I have this problem with all StructType type.
If someone knows how to help me
I have finally found the solution.
In the WSDL source, there were multiple node with the same name, and in my code only one class were generated by name with WSDLtoPHP.
We asked WSDL owner to change the name of node in the WSDL and we generated new class with WSDLtoPHP librairy.
Now it is work !
Okay, so I basically need to generate a json file using Laravel's scheduler and a custom artisan command (said list is actually a list of popular cities in our application). So I went ahead and did just that. Here's the definition of my Artisan command:
namespace App\Console\Commands;
use Illuminate\Console\Command;
use App\Services\PlaceService;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\App;
use Illuminate\Support\Facades\Log;
class CitySearch extends Command
{
/**
* The name and signature of the console command.
*
* #var string
*/
protected $signature = 'city:search {--locale=}';
/**
* The console command description.
*
* #var string
*/
protected $description = 'Generates the list of the most popular cities to be used across the application when we need it.';
private $placesService;
/**
* Create a new command instance.
*
* #return void
*/
public function __construct(PlaceService $placesService)
{
$this->placesService = $placesService;
parent::__construct();
}
/**
* Execute the console command.
*
* #return mixed
*/
public function handle()
{
App::setLocale( $this->option('locale') );
$request = Request::create(route('api.search-places'), 'GET', ['maxResults' => 3000, 'isArtisan' => true]);
$request->headers->set('Accept', 'application/json');
$request->headers->set('Api-Key', 'aaaaaaaaaaaa');
// $request->headers->set('Api-Key', '43JSOSH333KSOH555WHO99');
$request->headers->set('App-client', 'web');
$response = app()->handle($request);
$content = json_decode($response->getContent());
$results = array_map(function($element){
if($element->type == "City")
$context = ['an', 'se', 'me'];
else
$context = ['se'];
return ['displayName' => $element->displayName, 'context' => $context];
}, $content->data);
print(json_encode($results));
}
}
Then I went into the scheduler and added the following to have the command run once a week:
namespace App\Console;
use App\Console\Commands\Admin\RedFalcon\PendingTransactionNotificator;
use App\Console\Commands\Admin\RedFalcon\FraudTransactionNotificator;
use App\Console\Commands\CardGenerate;
use App\Console\Commands\Communauto\Stats;
use App\Console\Commands\CPS\Archiver;
use App\Console\Commands\CPS\AutoCasher;
use App\Console\Commands\CPS\Autofixer;
use App\Console\Commands\CPS\Beta\Testers;
use App\Console\Commands\CPS\BNC\EmailFailedBankTransaction;
use App\Console\Commands\CPS\BNC\FeedComposer;
use App\Console\Commands\CPS\BNC\Feeder;
use App\Console\Commands\CPS\BNC\FeedMediator;
use App\Console\Commands\CPS\BNC\FeedReporter;
use App\Console\Commands\CPS\BNC\Parametrizer;
use App\Console\Commands\CPS\Captor;
use App\Console\Commands\CPS\ConfirmationFix;
use App\Console\Commands\CPS\ConfirmationCodeRemoval;
use App\Console\Commands\CPS\DB\RideArchiver;
use App\Console\Commands\CPS\DB\RideFixer;
use App\Console\Commands\CPS\Rider;
use App\Console\Commands\CPS\Test\Resetter;
use App\Console\Commands\CPS\Transactor;
use App\Console\Commands\CPS\Troubleshooting\Experiment1;
use App\Console\Commands\Notifications\ApnFeedbackService;
use App\Console\Commands\RelavelTester;
use App\Console\Commands\UpdateCityPopularity;
use App\Console\Commands\Util\FixBankTransactionTable;
use App\Console\Commands\Util\FixPreauthorizationTable;
use App\Console\Commands\Util\ResetPassword;
use App\Console\Commands\CitySearch;
use Illuminate\Console\Scheduling\Schedule;
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
use Illuminate\Support\Facades\Log;
class Kernel extends ConsoleKernel
{
protected $list;
/**
* The Artisan commands provided by your application.
*
* #var array
*/
protected $commands = [
CardGenerate::class,
Rider::class,
Autofixer::class,
Captor::class,
Transactor::class,
Archiver::class,
FeedComposer::class,
FeedMediator::class,
Feeder::class,
Parametrizer::class,
RideFixer::class,
RideArchiver::class,
RelavelTester::class,
FixPreauthorizationTable::class,
PendingTransactionNotificator::class,
FraudTransactionNotificator::class,
FixBankTransactionTable::class,
Resetter::class,
Testers::class,
Stats::class,
Experiment1::class,
FeedReporter::class,
ResetPassword::class,
AutoCasher::class,
ConfirmationFix::class,
ConfirmationCodeRemoval::class,
CitySearch::class,
UpdateCityPopularity::class,
EmailFailedBankTransaction::class,
ApnFeedbackService::class
];
/**
* Define the application's command schedule.
*
* #param \Illuminate\Console\Scheduling\Schedule $schedule
* #return void
*/
protected function schedule(Schedule $schedule)
{
$schedule->command('city:search --locale=fr')
->mondays()
->at('14:40')
->sendOutputTo(storage_path() . "/app/city-fr.json");
$schedule->command('city:search --locale=en')
->mondays()
->at('14:40')
->sendOutputTo(storage_path() . "/app/city-en.json");
}
/**
* Register the Closure based commands for the application.
*
* #return void
*/
protected function commands()
{
require base_path('routes/console.php');
}
}
Now, this works relatively well... except sometimes it crashes. When that happens, the two json files become filled with error messages instead of the actual data. What I'd like to do is basically save the original list before the command executes and in case something fails, I'd like to output that list into the file and log the error. Right now, everything goes into the file and of course, I get a truckload of errors in my application because the city list is invalid.
Since I'm in Laravel 5.5 I tried using the "before" and "after" hooks (onFailure and onSuccess not available in my version of the framework) and came up with this:
$schedule->command('city:search --locale=fr')
->everyMinute()
->before( function(){
$this->list = json_decode(file_get_contents(storage_path() . "/app/city-fr.json"));
})
->after(function(){
$test = json_decode(file_get_contents(storage_path() . "/app/city-fr.json"));
Log::debug($test);
})
->sendOutputTo(storage_path() . "/app/city-fr.json");
So, while I can successfully get the original list from the file before the process begins, in the "after" hook, the file is still empty so there's no way for me to know whether the process failed or not.
Does anyone know how I should go about this? It feels like the solution is right in front of my face, but I'm just missing it.
Okay, this is a faceplant moment for me. Turns out in the 'after' hook, I did have access to the file, but the reason my output was empty was that the json_decode method returned false because the content of the file wasn't valid json (which was what I was trying to test from the start). Anyway, once I finished picking up the pieces of my scattered brain, the following turned out to work perfectly:
$schedule->command('city:search --locale=fr')
->everyMinute()
->before( function(){
$this->list = file_get_contents(storage_path() . "/app/city-fr.json");
})
->after(function(){
if(!json_decode(file_get_contents(storage_path() . "/app/city-fr.json")))
{
$fp = fopen(storage_path() . "/app/city-fr.json", 'w');
fwrite($fp, $this->list);
fclose($fp);
}
})
->sendOutputTo(storage_path() . "/app/city-fr.json");
In a symfony projects, I'm trying to persist a line of an association table (profil_role) composed of two objects (profil and role).
First, I developed The create action in the ProfilRoleController of the second project this way:
/** #var Roles $role */
$em = $this->getDoctrine()->getManager('main_project');
$role = $em->getRepository("MyBundle\Entity\Roles")->find($roleId);
$profil = $em->getRepository("MyBundle\Entity\Profil")->find($profilId);
$profilRole = new ProfilRoles();
$profilRole->setRoleId($role->getId());
$profilRole->setProfilId($profil->getId());
$em->persist($profilRole);
$em->flush();
This part of code, call then the post entity action present in the main project:
/**
* #Rest\View(statusCode=Response::HTTP_CREATED)
* #Rest\Post("/profil_roles")
*/
public function postEntityAction(ProfilRoles $profilRole)
{
$em = $this->getDoctrine()->getManager();
$em->persist($profilRole);
$em->flush();
return $profilRole;
}
When I try to execute my code i'm getting this king of error:
Execution failed for request: POST /api/profil_roles? HTTP/1.1 {"profil":{"id":"12"},"role":{"id":"3"}}: HTTPCode 500, body {"code":500,"message":"Unable to guess how to get a Doctrine instance from the request information."}
I've tried to use the #ParamConverter annotation, but I don't how to use it my case.
try this:
public function postEntityAction() {
$postData = $request->request->all();
$profileRole = $postData['profile_role']
Instead of this:
public function postEntityAction(ProfilRoles $profilRole)
#AlessandroMinoccheri I've tried to be inspired by your reply to do this and i'ts workin, i don't know if it's the correct way.
/**
* #param ProfilRoles $profilRole
* #param Request $request
* #return ProfilRoles
* #Rest\View(statusCode=Response::HTTP_CREATED)
* #Rest\Post("/profil_roles")
*/
public function postEntityAction(Request $request)
{
$profilRole = new ProfilRoles();
$em = $this->getDoctrine()->getManager();
$requete = $request->request->all();
$profilRole->setProfilId($requete['profil']['id']);
$profilRole->setRoleId($requete['role']['id']);
$em->persist($profilRole);
$em->flush();
return $profilRole;
}
I am a beginner in Symfony 2.8. I have a problem with my controller.
That is my controller:
class ExampleController extends ExtraController
{
/**
* #ParamConverter("site", class="Bundle:Site", converter="site_slug_converter")
* #Route("/formacion-example", name="example_web.front.example_training", requirements={"site": "es"})
*
* Render the Example form page
*
* #param Site $site
*
* #return Response
*/
public function example2TrainingFormAction(Site $site)
{
$options = ['site' => $site, 'projectId' => $this->get('example.doctrine.project_getter')->getProject()];
$form = $this->createForm(ExampleTrainingType::class, null, $options);
$viewData = ['form' => $form->createView()];
return $this->render('ExampleFrontContactFormBundle:Example:example_training.html.twig', $viewData);
}
}
When I go to my Route www.example.com/es/formacion-example symfony return to me:
HTTP status: Error 500
Controller: n/a
Route name:example_web.front.example_training
Has session: no
In symfony documentation I cant find a solution.
Thank you! :)
adding the answer here as well:
i.e. the site parameter was missing from the route
#Route("/{site}/formacion-example", ...
I am trying to send sms using cakephp-sms plugin
The documentation is quite clear and brief. I installed it using Composer in my app/Plugin directory. I also installed xi-sms using composer. This was installed in the Vendor directory. In my controller for sending sms. I included App::uses('CakeSms', 'Sms.Network/Sms') and implemented an InfobipSmsTransport class in the Sms/Lib/Network/Sms. Below is my class
<?php
use Xi\Sms\Gateway\InfobipGateway;
App::uses('AbstractSmsTransport', 'Sms.Network/Sms');
class InfobipSmsTransport extends AbstractSmsTransport {
const INFOBIP_USER = 'XXXXX';
const INFOBIP_PASSWORD = 'XXXXXXX';
/**
*
* #param CakeSms $sms
* #return bool Success
*/
public function send(CakeSms $sms) {
$gw = new InfobipGateway(
self::INFOBIP_USER,
self::INFOBIP_PASSWORD
);
$service = new Xi\Sms\SmsService($gw);
$msg = new Xi\Sms\SmsMessage(
$sms->message(),
$sms->from(),
$sms->to()
);
$response = $service->send($msg);
return !empty($response);
}
}
?>
When I try to send an SMS however I get the following error
Class "InfobipSmsTransport" not found.. I have no idea what am doing wrong? Any clues or suggestions are welcome.
The CakeSms class was not loading the plugin. This is the line of code where it was failing.
App::uses($transportClassname, $plugin . 'Network/Sms');.
In my app/Config/sms.php I just changed this 'transport' =>'Infobip' to
'transport' =>'Sms.Infobip'. The plugin is now being loaded properly and the class is found.