unable to access env variables in app bootstrap - laravel

I am trying to use Slack to post my debug messages to. i have followed some exmaple code and have this in my app.php file
$app->configureMonologUsing(function ($monolog) {
$monolog->pushHandler($chromeHandler = new \Monolog\Handler\ChromePHPHandler());
$chromeHandler->setFormatter(new \Monolog\Formatter\ChromePHPFormatter());
$slackHandler = new \Monolog\Handler\SlackHandler('xoxp-dasdasdzxczxcasdasdasdas', '#general');
$slackHandler->setLevel(\Monolog\Logger::INFO);
$slackHandler->setFormatter(new \Monolog\Formatter\LineFormatter());
$monolog->pushHandler($slackHandler);
});
which works and send mesages to slack using the following command
Log::info('thing to log');
I want to only send debug messages to slack if I am on a local machine.
I have tried reading in the the APP_ENV variable using env() but it is not returning anything.
I can access it using the same code in the controller. THerefore I assume it has not been loaded in the app.php file when I am trying to get it.
is there a better place to add the slack code, or anther way to detect the env variable?

Related

laravel event dispatch from controller

Alright so I have been trying to set up a spreadsheet application with concurrent editing. I went down the laravel echo, redis, sockets route. (Any advice to just use pusher will be summarily dismissed). Now for the most part I have this working and I can call my event from tinker and see the data I want flow through redis to sockets and get picked up by my frontend. However the call simply does not work when placed in a controller; its like its just being ignored. For simplicity sake I removed all code from the controller function except for event(new SalesPricingReportEdit($request)); I can use this exact code in tinker storing the exact source of the request from dev tools {"change":[[0,"future contract price",null,750]],"customer_id":101443,"item_id":"MOFT0602-1-550"} and my ws responds on multiple instances of the page across different computers with the data attached to the WS. I can post any code anyone needs to help just let me know what you want to see.
EDIT(resolved): Alright so now that I am mostly finished with this project I have my write up I figured Id post it for posterity this is a process guide that lead me to successfully using laravel events with redis and socket-io via echo.
Register your new Event in laravel go to app/Providers/EventServiceProvider.php and put in the fully namespaced path for your Event that doesnt exist yet. Using the default namespace will save you a headache in implemntation but you can use a non-default
if you wish to gouge your own eyes out while you attempt to route the events on your frontend.
protected $listen = [ 'App\Events\EventName.php' => [
//you would put a handler here but for my case i was only dealing with an
//Event generated by server and handled by the client(browser)
//so it wasn't needed. KISS
],
Once you save that you just use the artisan generate event command and it will read the listener array and scaffold you up an event.
note: While we are in the providers folder lets just note the broadcastServiceProvider and its reference to the routes/channel file this isn't very important for me now but its good to remember
In your app/Events/EventName.php we will be configuring our event. Most of this is standard but there will be a few gotchas I dont want to forget about.
your class should by default implement ShouldBroadcast ... I changed this to shouldBroadcastNow as well as setting my default QUE_DRIVER=sync in global .env and config to sync .. this just avoids an extra overhead of queing the jobs..probably dumb in the long term but, for now queing is a bit overkill.
continue in app/Events/EventName.php
Next notice your construct function. To pass data through an event you need to declare a public variable in the class and set the value for that inside your constructor. By Default laravel will/should/suppposed to pass any public variable in the
class with the event.
public $change;
public function __construct($request){
$this->change = json_decode($request, true);
}
Next in your broadcastOn() function you want to return a new channel...essencially
return new [Type]Channel([channel-name]);
make sure you have all the facades you need in your header.
the broadcastWith() function will let you manipulate the data sent with the event.
I did not use the broadcastAs() function but, it is supposed to allow you to change the Event Name rather than using the default class name.
Now we are going to go to our controller file where we plan to actually fire the event from app/Http/Controllers/xxxxxxxxxController.php
use the syntax
event(new EventName($data))
when you want the event to get kicked off. this will not work as we have not set up redis or sockets but to test this is all in working order go to your .env and change the BROADCAST_DRIVER=log. once done wipe cache and do whatever it is you need to do to get the controller function to run(either by using tinker or by a frontend path you plan on using with the event). you should then be able to see the storage/app/logs/laravel.log contain the information from your event.
Go ahead and install redis on your server and use basic laravel configuration in .env and in config/database.php the only thing to change is to add in the .env BROADCAST_DRIVER=redis.
To avoid some complications go ahead and make sure your CACHE_DRIVER to file.
I have not yet set up multi connections with redis to let redis work both as broadcast and cache; ik its possible but I havent done it. so for now cache_driver can go away.
Also I tried to set this up using PHPredis but I admitted defeat and just used predis. Anyone that can figure this out I will venmo 50 bucks.
Finally to test that you have done this correctly go into
redis-cli > PING ...resp: PONG
Also you can use redis-cli monitor to verify that event data is indeed being pushed to redis.
Now we will start setup with npm we are going install laravel-echo-server, I will also get the pm2 package to act as my daemonizer for echo server.bash it up with
` #!/var/www/repoting/ bash
laravel-echo-server start`
then just run pm2 start socket.sh
when testing you might want to run laravel-echo-server start straight from the cli because the output stream will let you know when it observed an event broadcast in redis.
we will also need the
npm --save socket.io-client
or websockets don't work.
Lets go to resources/assets/js/bootstrap.js
import Echo from "laravel-echo";
window.io = require('socket.io-client');
if (typeof io !== 'undefined') {
window.Echo = new Echo({
broadcaster: 'socket.io',
host: window.location.hostname + ':6001',
});
}
This is initializing our websocket connection.
Now in our blade file we are going to subscribe to the channel and listen for events. Make sure to include the :6001/socket.io/socket.io.js file or your callbacks will fail
Why are we not doing this in the bootstrap.js you ask? because part of the channel name I am using is being passed by the controller with the view so to subscribe to the right channel I need something like
channel-name-{{$customer_id}}.
What you say I should have properly set up vue and done things the way they were designed to be done in vue....go home your drunk.
So now in resources/views/xxxxx.blade.php
I am using this in conjunction with handsontables so I am going to insert my listener in the afterRender hook.
Echo.channel('EventName-{{$customer_id}}')
.listen('EventName',function(data){
console.log(data);
});
any confusion here about what goes in the channel vs what goes in the listen clause can think of it as using the channelName and then the eventName by default the class name. There seems like in the past to have been some issues
with the class name being namespaced properly but I did not experience any problems.
this should all lead to seeing a console.log with your event data on any page subscribed to the the channel. But for prosperity sake here is the testing order to help verify each step along the way.
Troubleshooting steps
Is the event configured properly in laravel? Change the BROADCAST_DRIVER=log and verify you get a log entry when you run your controller.
Is the data actually being pushed to redis? with the right channel, etc? open redis-cli montior while you trigger an event and you should see feedback like "PUBLISH" "channel-name" "message"
Is echo server/socketio-server registering the event? look at your terminal that is running the laravel-echo-server start command you should see the event propagate from redis to echo there
Is your bootstrap.js file giving you an open web socket? go to dev-tools and check the network->ws if you see an entry click it and then on messages; make sure you see sent and recieved data. If you dont something is wrong in bootstrap.js
Is your clientside js retrieving data from the websocket event? if not you probably forgot to include you socket.io.js file.
Next Steps
-Implement whisper channels to notify the page of who is currently using the page as well as to unsubscribe the from the echo channel and remove any unneeded listeners
-pass handsontable selected data through the whisper channel and set those cells to readonly where the user is different from the current user
I ended up just adding the redis facade and calling Redis::publish(). My guess here is that I couldn't call an event without having a listener setup. I don't need a listener I just needed the event to fire and push it to redis. the real confusing part is why this works without a hitch in tinker and not in a controller is still a mystery but, I solved the immediate problem so this just gets chalked up to an edge case where I implemented something differently than it was probably designed to be.

Laravel - Domain API?

I'm trying to figure something out. I want to make a page where a user can check for domain names and if they're available or not. I'm asking for advice because I don't know where to look. TransIP does have an API but I can't understand their documentation. What can I do? I want to make this work in laravel
There are many API wrappers you can grab from github, here is one I found on a google search. https://github.com/verschoof/transip-api
Just install with composer, put your login and private key in your .env perhaps and then include it in whatever file you want.
$client = new Transip\Client(env('TRANSIP_LOGIN'), env('TRANSIP_KEY'), true);
$domainApi = $client->api('domain');
$domainInfo = $domainApi->getInfo('user-input-domain.com');
$status = $domainApi->checkAvailability();
I would put env variables into a config file and access with config('key') but this is a basic example.

Codeigniter Ion Auth configuration

I am using Ion Auth for registration, and everything is working fine on local, So when I wanted to move Live server I need email activation for new registrations [I am not using SMTP, there is no email config file in my config folder], So I made changes in ion_auth.php in config file as follows::
$config['email_activation'] = TRUE;
$config['manual_activation'] = FALSE;
$config['use_ci_email'] = TRUE;
as far as I know about this library (I am new to CodeIgniter), that's it. But unfortunately these configurations are not taking effect. When I var dump the following items inside constructor of ion_auth.php library file returns null
$this->config->item('use_ci_email','ion_auth') or
$this->config->item('email_activation','ion_auth')
And other config items like 'admin_email' has no issues, I can fetch the value. So, what is wrong with my config file, I am using very basic file provided by the library repo.
When I set the values, inside the constructor of library file as below, it works.
$this->config->set_item('use_ci_email', TRUE);
$this->config->set_item('email_activation', TRUE);
Is there anything wrong I am doing to get this weird behavior.
Ok, so I opened an issue on Ion Auth Git repo, and the Author, Ben Edmunds responded with the solution, If anybody facing this issue, with latest CodeIgniter, please pull the latest commit of IonAuth library and test, It will work.
For more on the issue, please refer the isse,
Codeigniter Ion Auth configuration and Email Activation

Laravel 5.2 reset password + Mandrill

I have Laravel 5.2 fresh installation.
I did following:
I have set up my .env file
MAIL_DRIVER=mandrill
SECRET=my_mandrill_api_key
I have installed Guzzle (https://github.com/guzzle/guzzle)
I have setup my email in view (https://github.com/laravel/laravel/blob/5.0/resources/views/emails/password.blade.php)
I have fixed the certificate issue (PHP cURL error code 60)
So it seems everything is done correctly.
When I fill email to reset password and press Send Password Reset Link button, I get following error
Server error: POST
https://mandrillapp.com/api/1.0/messages/send-raw.json resulted in a
500 Internal Server Error response:
{"status":"error","code":-1,"name":"ValidationError","message":"You
must specify a key value"}
I have check my log in Mandrill (https://mandrillapp.com/settings/api) there is no logs for my action.
From the error of Mandrill, I know it does not get the api key, so for some reason the api key and other values is not passing over to Mandrill api.
Question: What is missing/wrong?
Note: right now I am working on my local environment building the app. My local environment Windows 10/Bitnami WAMP stack 7/ I am also using Mandrill API.
If you are using the Mandrill driver then you must set the MANDRILL_SECRET in your .env file.
The other settings MAIL_HOST, MAIL_PORT and so on are for use with other drivers.
See the documentation here about using the Mandrill driver. It mentions that you should set the Mandrill key in config/services.php but you should really set that using an environment variable, so if you have customized the file change it back to
'mandrill' => [
'secret' => env('MANDRILL_SECRET'),
],
Then you will be able to read the MANDRILL_SECRET value from the .env file.
So in your .env file you'll have;
MAIL_DRIVER=mandrill
MANDRILL_SECRET=your_mandrill_key_here

Bitbucket - Webhook keep returning error 500

Would like to check, I am fairly new to Bitbucket's new introduced webhook where previously i was using services where Bitbucket will execute a link to my site thus triggering a deployment script.
So since the old service is going to be depreciated soon, we all migrated to webhook instead. With the same implementation, I keep getting an error 500 upon commit/push/merge and there is no way for us to see the details for the error given. At first I thought it was my server giving problem but when i call the link manually via browsers and everything was fine. The deployment script can be executed successfully so then why bitbucket's webhook keeps telling me error 500?
Subsequently I find the guide given by Bitbucket was not helpful. There is no specified call method to the url stated so is the webhook initiates a GET or POST request? previously using services initiates a POST request. Then, are there any necessary payloads i need to include into the webhook URL? None is stated. Then, if there is an error at least let me see the error so I can fix it instead of telling me error 500.
I hope someone here can help me with this issue. Below are some specification of the site.
Server : Ubuntu LEMP 14.04 x64 Laravel framework 5.0
Webhook Url: bot.example.com/bitbucket/deploy/{Site API}
Method : GET
And when the abode link is call, it reaches a controller that does
public function attemptDeploy($site_api)
{
$script = 'nohup setsid php ~/scripts/deploy.php ' . $site_api. ' > /dev/null 2>&1 &';
exec($script);
return response('Deploy running.', 200);
}
Note that when i call this link manually either form browser or console everything works perfectly except from bitbucket's webhook. How can i solve this issue?
I was in the same situation. Bitbucket trims the body of the response and I couldn't see the error given by my server.
I've looked into the logs storage/logs/laravel.log and saw TokenMismatchException. Webhooks being API calls they don't store cookies or sessions so CSRF from Laravel breaks.
You need to add an exception from CSRF for the bitbucket deploy route. You can add this exception in app/Http/Middleware/VerifyCsrfToken.php. For example if your link is www.your_site.com/bit_deploy you will have:
<?php
namespace App\Http\Middleware;
use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken as BaseVerifier;
class VerifyCsrfToken extends BaseVerifier
{
/**
* The URIs that should be excluded from CSRF verification.
*
* #var array
*/
protected $except = [
'bit_deploy'
];
}
Hope that this helps you ... as I've lost 3 hours on this.
PS: at the time of writing this answer, bitbucket webhooks performs POST calls (not GET)

Resources