How to integrate Paubox with Laravel? - laravel

I try to integrate Paubox with Laravel 5 as custom mail provider.
How can I do it in best way?
I installed https://github.com/Paubox/paubox-php bot there is no description how to connect it with Laravel.

I solve it by creating new service provider and Transport class.
Change default mail service provider in config/app.php:
// Illuminate\Mail\MailServiceProvider::class,
App\Providers\PauboxServiceProvider::class,
Add credentials to config/mail.php:
'pauboxApiKey' => env('PAUBOX_API_KEY'),
'pauboxApiUser' => env('PAUBOX_API_USER')
Changes in .env
MAIL_DRIVER=paubox
PAUBOX_API_KEY=
PAUBOX_API_USER=
Create new service provider app/Providers/PauboxServiceProvider.php
<?php
namespace App\Providers;
use Illuminate\Mail\MailServiceProvider;
class PauboxServiceProvider extends MailServiceProvider {
protected function registerSwiftTransport() {
$this->app->singleton('swift.transport', function ($app) {
return new PauboxTransportManager($app);
});
}
}
Create transport manager app/Providers/PauboxTransportManager.php
<?php
namespace App\Providers;
use Illuminate\Mail\TransportManager;
class PauboxTransportManager extends TransportManager {
protected function createPauboxDriver() {
return new PauboxTransport;
}
}
Create transport app/Providers/PauboxTransport.php
<?php
namespace App\Providers;
use Illuminate\Mail\Transport\Transport;
use Swift_Mime_SimpleMessage;
use App\Vendors\Paubox as Paubox;
use Symfony\Component\HttpKernel\Exception\UnprocessableEntityHttpException;
use Illuminate\Support\Facades\Log;
class PauboxTransport extends Transport {
protected $config;
public function __construct() {
$this->config = config('mail');
}
public function send(Swift_Mime_SimpleMessage $msg, &$failedRecipients = null) {
$paubox = new Paubox\Paubox($this->config['pauboxApiUser'], $this->config['pauboxApiKey']);
$message = new Paubox\Mail\Message();
$content = new Paubox\Mail\Content();
$header = new Paubox\Mail\Header();
$content->setHtmlText($msg->getBody());
$header->setSubject($msg->getSubject());
$header->setFrom('"' . $this->config['from']['name'] . '" <' . $this->config['from']['address'] . '>');
$header->setReplyTo($this->config['from']['address']);
$recipients = [];
foreach ($msg->getTo() as $to => $val) {
recipients[] = $to;
}
$message->setHeader($header);
$message->setContent($content);
$message->setRecipients($recipients);
$sendMessageResponse = new Paubox\Mail\SendMessageResponse();
$sendMessageResponse = $paubox->sendMessage($message);
$errorMsg = '';
if (isset($sendMessageResponse->errors)) {
foreach ($sendMessageResponse->errors as $error) {
$errorMsg .= json_encode($error);
}
Log::error(PHP_EOL . "Paubox: " . $errorMsg . PHP_EOL);
throw new UnprocessableEntityHttpException('Error occurred while sending email');
}
return $sendMessageResponse;
}
}
I copied https://github.com/Paubox/paubox-php into App\Vendors\Paubox. I had to do it bacause paubox installed with composer didn't read my .env data. After copy I had to change namespaces in all files, and add Paubox constructor to pass api_key and api_user:
public function __construct($pauboxApiUser, $pauboxApiKey)
{
$this->pauboxApiUser = $pauboxApiUser;
$this->pauboxApiKey = $pauboxApiKey;
}
and below in code:
change \getenv('PAUBOX_API_USER');
into $this->pauboxApiUser;
and change \getenv('PAUBOX_API_KEY');
into $this->pauboxApiKey;
A had to also install composer require nategood/httpful

Related

With StripeClient I got error No API key provided

in my Laravel 8 / with stripe/stripe-php": "^7.75" I try to connect and create account on stripe side
and got error :
No API key provided. Set your API key when constructing the StripeClient instance, or provide it on a per-request basis using the `api_key` key in the $opts argument.
with code:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Session;
use Stripe;
use Stripe\StripeClient;
use App\Http\Controllers\Controller;
use Illuminate\Database\DatabaseManager;
use App\Models\Settings;
use Carbon\Carbon;
use Illuminate\Support\Arr;
use App\Models\User;
use App\Models\StripeToken;
class SellerController extends Controller
{
protected StripeClient $stripeClient;
protected DatabaseManager $databaseManager;
public function __construct(StripeClient $stripeClient, DatabaseManager $databaseManager)
{
\Log::info(varDump($stripeClient, ' -1 SellerController ::'));
$this->stripeClient = $stripeClient;
$this->databaseManager = $databaseManager;
}
public function showProfile($id)
{
\Log::info('-1 showProfile $id ::' . print_r($id, true));
$seller = User::find($id);
if (!$seller) {
abort(404);
}
return view('market.seller', [
'seller' => $seller,
'balance' => null
]); // /_wwwroot/lar/tAdsBack/resources/views/admin/stripe/stripe.blade.php
} // public function showProfile($id)
public function redirectToStripe($id)
{
\Log::info('-1 redirectToStripe $id ::' . print_r($id, true));
$seller = User::find($id);
if (!$seller) {
abort(404);
}
$appEnv = strtolower(config('app.env'));
if ($appEnv == 'local' or $appEnv == 'dev') {
\Log::info('-1 config(app.STRIPE_TEST_KEY)::' . print_r(config('app.STRIPE_TEST_KEY'), true));
\Stripe\Stripe::setApiKey(config('app.STRIPE_TEST_KEY')); // LOOKS LIKE THAT IS NOT APPLIED
$this->stripeClient->apiKey = config('app.STRIPE_TEST_KEY'); // THIS DOES NOT HELP
$this->stripeClient->api_key = config('app.STRIPE_TEST_KEY'); // THIS DOES NOT HELP
}
if ($appEnv == 'production') {
\Stripe\Stripe::setApiKey(config('app.STRIPE_LIVE_KEY'));
$this->stripeClient->opts['api_key'] = config('app.STRIPE_LIVE_KEY');
}
if (!$seller->completed_stripe_onboarding) { // Complete onboarding process
$str = \Str::random();
$stripeToken = new StripeToken();
$stripeToken->token = $str;
$stripeToken->seller_id = $id;
$stripeToken->save();
if (empty($seller->stripe_connect_id)) { // if has no stripe account
// // Create a new Stripe Connect Account object.
\Log::info('-1 $$this->stripeClient ::' . print_r($this->stripeClient, true));
Checking log I see :
[2021-03-22 05:40:30] local.INFO: -1 $$this->stripeClient ::Stripe\StripeClient Object
(
[coreServiceFactory:Stripe\StripeClient:private] =>
[config:Stripe\BaseStripeClient:private] => Array
(
[api_key] =>
[client_id] =>
[stripe_account] =>
[stripe_version] =>
[api_base] => https://api.stripe.com
[connect_base] => https://connect.stripe.com
[files_base] => https://files.stripe.com
)
[defaultOpts:Stripe\BaseStripeClient:private] => Stripe\Util\RequestOptions Object
(
[apiKey] =>
[headers] => Array
(
[Stripe-Account] =>
[Stripe-Version] =>
)
[apiBase] =>
)
[api_key] => sk_test_NNNNNN
How to fix this error ?
I suppose I need to set api_key in some other way, not
$this->stripeClient->apiKey = config('app.STRIPE_TEST_KEY'); // THIS DOES NOT HELP
$this->stripeClient->api_key = config('app.STRIPE_TEST_KEY'); // THIS DOES NOT HELP
but how?
Thanks!
Before using stripe/stripe-php directly, check out Laravel Cashier.
https://laravel.com/docs/8.x/billing

Class not found in Laravel 7

I have installed a package for Laravel 7, the package in question is this http://paypal.github.io/PayPal-PHP-SDK/ to manage payments with Paypal.
I created everything, controller, web route, everything.
But the moment I go to the page to test I can't find the class.
Target class [App\Http\Controllers\PaypalController] does not exist.
PaypalController.php
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use PayPal\Rest\ApiContext;
use PayPal\Auth\OAuthTokenCredential;
// use to process billing agreements
use PayPal\Api\Agreement;
use PayPal\Api\Payer;
use PayPal\Api\Plan;
use PayPal\Api\ShippingAddress;
class PaypalController extends Controller
{
private $apiContext;
private $mode;
private $client_id;
private $secret;
private $plan_id;
// Create a new instance with our paypal credentials
public function __construct()
{
// Detect if we are running in live mode or sandbox
if(config('paypal.settings.mode') == 'live'){
$this->client_id = config('paypal.live_client_id');
$this->secret = config('paypal.live_secret');
$this->plan_id = env('PAYPAL_LIVE_PLAN_ID', '');
} else {
$this->client_id = config('paypal.sandbox_client_id');
$this->secret = config('paypal.sandbox_secret');
$this->plan_id = env('PAYPAL_SANDBOX_PLAN_ID', '');
}
// Set the Paypal API Context/Credentials
$this->apiContext = new ApiContext(new OAuthTokenCredential($this->client_id, $this->secret));
$this->apiContext->setConfig(config('paypal.settings'));
}
public function paypalRedirect(){
// Create new agreement
$agreement = new Agreement();
$agreement->setName('App Name Monthly Subscription Agreement')
->setDescription('Basic Subscription')
->setStartDate(\Carbon\Carbon::now()->addMinutes(5)->toIso8601String());
// Set plan id
$plan = new Plan();
$plan->setId($this->plan_id);
$agreement->setPlan($plan);
// Add payer type
$payer = new Payer();
$payer->setPaymentMethod('paypal');
$agreement->setPayer($payer);
try {
// Create agreement
$agreement = $agreement->create($this->apiContext);
// Extract approval URL to redirect user
$approvalUrl = $agreement->getApprovalLink();
return redirect($approvalUrl);
} catch (PayPal\Exception\PayPalConnectionException $ex) {
echo $ex->getCode();
echo $ex->getData();
die($ex);
} catch (Exception $ex) {
die($ex);
}
}
public function paypalReturn(Request $request){
$token = $request->token;
$agreement = new \PayPal\Api\Agreement();
try {
// Execute agreement
$result = $agreement->execute($token, $this->apiContext);
$user = Auth::user();
$user->role = 'subscriber';
$user->paypal = 1;
if(isset($result->id)){
$user->paypal_agreement_id = $result->id;
}
$user->save();
echo 'New Subscriber Created and Billed';
} catch (\PayPal\Exception\PayPalConnectionException $ex) {
echo 'You have either cancelled the request or your session has expired';
}
}
}
Routes
Route::get('/subscribe/paypal', 'PaypalController#paypalRedirect');
Route::get('/subscribe/paypal/return', 'PaypalController#paypalReturn');
I can't understand what the problem is! Thank you all
Just run:
composer dump-autoload
to regenerate all classes, see: https://getcomposer.org/doc/03-cli.md
Mention the Laravel 7 route:
Route::post('create_paypal_plan','App\Http\Controllers\PaypallController#create_plan');
just like this.

Laravel/Lumen file response

I need to stream file content (such as images and other mime types) from a Lumen resource server to a Laravel client server. I know in Laravel I can use:
$headers = ['Content-Type' => 'image/png'];
$path = storage_path('/mnt/somestorage/example.png')
return response()->file($path, $headers);
However, the file method is absent in Laravel\Lumen\Http\ResponseFactory.
Any suggestions are very welcome.
In Lumen you can use Symfony's BinaryFileResponse.
use Symfony\Component\HttpFoundation\BinaryFileResponse
$type = 'image/png';
$headers = ['Content-Type' => $type];
$path = '/path/to/you/your/file.png';
$response = new BinaryFileResponse($path, 200 , $headers);
return $response;
You can find the documentation here.
There is a function in Lumen:
https://lumen.laravel.com/docs/8.x/responses#file-downloads
<?php
namespace App\Http\Controllers;
use App\Models\Attachment;
use Illuminate\Http\Request;
class AttachmentController extends AbstractController
{
/**
* Downloads related document by id
*/
public function attachment(Request $request)
{
$path = "path/to/file.pdf";
return response()->download($path);
}
}

Events not being triggered in Application Module

I cannot seem to get my events to fire off. This is my first time playing around with them. If you look, i create an event in the init method and then i try to fire it off in the onBootstrap method. The event should produce a die with the string, but its not. any help would be appreciated.
namespace Application;
use Zend\ModuleManager\Feature\AutoloaderProviderInterface;
use Zend\ModuleManager\Feature\ControllerProviderInterface;
use Zend\ModuleManager\Feature\BootstrapListenerInterface;
use Zend\ModuleManager\Feature\ServiceProviderInterface;
use Zend\ModuleManager\Feature\ConfigProviderInterface;
use Zend\ModuleManager\Feature\InitProviderInterface;
use Zend\ModuleManager\Feature\ViewHelperProviderInterface;
use Zend\ModuleManager\ModuleManagerInterface;
use Zend\Mvc\ModuleRouteListener;
use Zend\Mvc\MvcEvent;
use Zend\EventManager\EventInterface;
use Doctrine\DBAL\DriverManager;
class Module implements
AutoloaderProviderInterface,
ControllerProviderInterface,
BootstrapListenerInterface,
ServiceProviderInterface,
ConfigProviderInterface,
InitProviderInterface,
ViewHelperProviderInterface
{
public function init(ModuleManagerInterface $manager)
{
$eventManager = $manager->getEventManager();
$eventManager->attach('do',function($e){
$event = $e->getName();
$target = get_class($e->getTarget());
$params = $e->getParams();
$str = sprintf(
'Handled event \"%s\" on target \"%s\", with parameters %s',
$event,
$target,
json_encode($params)
);
die($str);
});
}
public function onBootstrap(EventInterface $e)
{
$this->attachEventManagerToModuleRouteListener($e);
$this->setupDoctrineConnectionMappings($e);
$eventManager = $e->getApplication()->getEventManager();
$eventManager->trigger('do',$this,array('j','o','n'));
}
public function getConfig()
{
return array_merge(
include __DIR__ . '/config/module.config.php',
include __DIR__ . '/config/routes.config.php'
);
}
public function getServiceConfig()
{
return include __DIR__ . '/config/services.config.php';
}
public function getControllerConfig()
{
return include __DIR__ . '/config/controllers.config.php';
}
public function getViewHelperConfig()
{
return include __DIR__ . '/config/view.config.php';
}
public function getAutoloaderConfig()
{
return array(
'Zend\Loader\StandardAutoloader' => array(
'namespaces' => array(
__NAMESPACE__ => __DIR__ . '/src/' . __NAMESPACE__
),
),
);
}
private function attachEventManagerToModuleRouteListener(MvcEvent $e)
{
$eventManager = $e->getApplication()->getEventManager();
$moduleRouteListener = new ModuleRouteListener();
$moduleRouteListener->attach($eventManager);
}
private function setupDoctrineConnectionMappings(MvcEvent $e)
{
$driver = $e->getApplication()->getServiceManager()->get('doctrine.connection.orm_default');
$platform = $driver->getDatabasePlatform();
$platform->registerDoctrineTypeMapping('enum', 'string');
$platform->registerDoctrineTypeMapping('set', 'string');
}
}
The EventManager you're getting from the ModuleManager is a different EventManager than the Application's EventManager which you let trigger the event do.
Since during Module initialization the Application is not yet available, you've to bind your listener to the event via the SharedManager.
So attaching to Application's event do would go like this
$sharedManager = $manager->getEventManager()->getSharedManager();
$sharedManager->attach(Application::class, 'do', function($e) {
// event code
});
Please note that the shared manager requires the (an) identifier of the EventManager that's expected to trigger the event which in this case is (and often is) the classname of Application.

How to cache model attributes in Laravel

In my current configuration, a user's email is stored on a remote server that I need to hit with a curl quest.
Luckily, I only need the email once a day when a certain process runs. However, when that process does run it will need to reference the email multiple times.
This is the current accessor I have set up for email. The problem is the curl request is being called every time I use $user->email. What's the best way to avoid this?
in UserModel:
public function getEmailAttribute(){
$curl = new Curl;
$responseJson = $curl->post('https://www.dailycred.com/admin/api/user.json',array(
'client_id'=>getenv('dailycredId')
,'client_secret'=>getenv('dailycredSecret')
,'user_id'=>$this->id
));
$response = json_decode($responseJson);
return $response->email;
}
private $cached_email = false;
public function getEmailAttribute(){
if ($this->cached_email){
// if set return cached value
return $this->cached_email;
}
// get the email
$curl = new Curl;
$responseJson = $curl->post('https://www.dailycred.com/admin/api/user.json',array(
'client_id'=>getenv('dailycredId')
,'client_secret'=>getenv('dailycredSecret')
,'user_id'=>$this->id
));
$response = json_decode($responseJson);
// cache the value
$this->cached_email = $response->email;
// and return
return $this->cached_email;
}
Depending on your use case make adjustments (ie. session, cache , static property...).
Extend a the Eloquent Model class
namespace App\Models\Utils;
use Illuminate\Database\Eloquent\Model as OldModel;
class MyModel extends OldModel
{
private $cachedAttributes = [];
public function getCachedAttribute(string $key, Callable $callable)
{
if (!array_key_exists($key, $this->cachedAttributes)) {
$this->setCachedAttribute($key, call_user_func($callable));
}
return $this->cachedAttributes[$key];
}
public function setCachedAttribute(string $key, $value)
{
return $this->cachedAttributes[$key] = $value;
}
public function refresh()
{
unset($this->cachedAttributes);
return parent::refresh();
}
}
make your class
class ElementWithEmail extends MyModel
{
const ATTRIBUTE_KEY_FOR_EMAIL = 'Email';
public function getEmailAttribute(){
$key = self::ATTRIBUTE_KEY_FOR_EMAIL;
$callable = [$this, 'getEmail'];
return $this->getCachedAttribute($key, $callable);
}
protected function getEmail()
{
$curl = new Curl;
$responseJson = $curl->post('https://www.dailycred.com/admin/api/user.json',array(
'client_id'=>getenv('dailycredId')
,'client_secret'=>getenv('dailycredSecret')
,'user_id'=>$this->id
));
$response = json_decode($responseJson);
return $response->email;
}
}
Call it from your code
$element = new ElementWithEmail();
echo $element->email;

Resources