Laravel - returning SSH output - php

Thanks for interest to this topic. I'm pretty new in Laravel and i have a little question. Maybe it's easy!
I have an SSH module in my Laravel that works this way:
The user fills the textarea element with Linux commands.
The command is passed with Ajax to a method called getExecute() located in the 'controllers' folder
I would like that this method returns me the full response of my SSH server, but this isn't happening. The only thing that the method returns is a blank space.
For example: I pass the command 'ls -la', and my response is all folders that the Linux find, like on terminal.
Can someone help me please?
Here is my code:
public function getExecute()
{
if(\Request::ajax()):
$ssh_command = \Input::get('ssh_command');
$ssh_response = null;
\SSH::run($ssh_command, function($line)
{
return $line.PHP_EOL;
});
endif;
}
OBS: The Ajax connection was tested and it's ok!
Thank you!

Finally solved! Solution below:
First i've created a variable called $output in my class.
private $output;
Then i modified my method to this:
public function postExecute()
{
$ssh_command = \Input::get('ssh_command');
$ssh_response = \SSH::run($ssh_command, function($line)
{
$this->output = $line.PHP_EOL;
});
return $this->output;
}
My method is not more Ajax, but i hope that all that i have to do is rollback to my ajax method like before.Thanks for all!

Related

How to get the current console command in Laravel

I can see if a script is running in the console with the App::runningInConsole() command, but I would like to know (for audit logging purposes) which command has been run from console.
To add some context - I need to log whenever a system or user accesses a certain type of data. For users, that's pretty simple - I can use Auth::user() and get their IP address from Request, but for console commands, it's a little more difficult.
I can figure out if a console command is running, which is good, but I need to be able to record which console command is running.
I do not see a way to get that information directly Laravel. I'm also not sure how that would be possible, as you can have one command executing other commands or even creating a new application instance like some test tools do.
There is however a way to achieve that using plain PHP. You can check the server/environment variables to identify how application was executed.
Have a look at
dd($_SERVER['argv']);
If you run a command this should give you the command name in $_SERVER['argv'][1]
You can find more information here: http://php.net/manual/en/reserved.variables.argv.php
To get console command together with arguments you should use something like that:
$command = \Request::server('argv', null);
if (is_array($command)) {
$command = implode(' ', $command);
}
In Laravel you can use \Request:server to get $_SERVER variables.
The problem with $SERVER['arg'] is that it doesnt work when you execute the command on the GUI.
I fixed the problem adding the next code on the command.
private function getAttributes()
{
$arguments = $this->arguments();
unset($arguments[0]);
$arguments = collect($arguments)->implode(' ');
$options = collect($this->options())->filter(function($item) {
return $item;
})->map(function($item, $key) {
$return = '--'.$key;
if($item!==true) {
$return .= '='.$item;
}
return $return;
})->implode(' ');
return $arguments.' '.$options;
}
and you get it calling $this->getAttributes() and you will get all the command with the attributes

Laravel resource controller testing gives NotFoundHttpException the second time

I am encountering a very strange thing while doing testing with Laravel 4. It looks like a bug but there's probably a logical explanation.
I have replicated the "bug" in a clean Laravel install and here's my code:
My resource controller /app/controllers/TestController.php:
(Created with php artisan controller:make TestController)
class TestController extends \BaseController {
/**
* Display a listing of the resource.
*
* #return Response
*/
public function index()
{
return Response::json(array());
}
// The end of the file is unchanged
In my app/routes.php:
Route::get('/', function()
{
return View::make('hello');
});
// Note the composed part of the URL.
// My problem isn't present if I just use `myapi` or `path` as a url
Route::resource('myapi/path', 'TestController');
Added in /app/test/ExampleTest.php:
public function testTest()
{
$res = $this->call('GET', 'myapi/path');
// Until here everything works right
$this->assertEquals(json_decode($res->getContent()), array());
// Now I call the same URL a second time
$res = $this->call('GET', 'myapi/path');
$this->assertEquals(json_decode($res->getContent()), array());
}
Now I run phpunit and here's what I get:
There was 1 error:
1) ExampleTest::testTest
Symfony\Component\HttpKernel\Exception\NotFoundHttpException:
/home/me/Web/laraveltest/bootstrap/compiled.php:5531
/home/me/Web/laraveltest/bootstrap/compiled.php:4848
/home/me/Web/laraveltest/bootstrap/compiled.php:4836
/home/me/Web/laraveltest/bootstrap/compiled.php:4828
/home/me/Web/laraveltest/bootstrap/compiled.php:721
/home/me/Web/laraveltest/bootstrap/compiled.php:702
/home/me/Web/laraveltest/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Client.php:81
/home/me/Web/laraveltest/vendor/symfony/browser-kit/Symfony/Component/BrowserKit/Client.php:332
/home/me/Web/laraveltest/vendor/laravel/framework/src/Illuminate/Foundation/Testing/ApplicationTrait.php:51
/home/me/Web/laraveltest/app/tests/ExampleTest.php:25
In my other project I get a slightly different backtrace, but I have the impression that's the same problem: (but I have no idea of why the other is compiled and this one not)
2) UnitModelTest::testOther
Symfony\Component\HttpKernel\Exception\NotFoundHttpException:
/home/me/Web/my-project/vendor/laravel/framework/src/Illuminate/Routing/RouteCollection.php:148
/home/me/Web/my-project/vendor/laravel/framework/src/Illuminate/Routing/Router.php:1049
/home/me/Web/my-project/vendor/laravel/framework/src/Illuminate/Routing/Router.php:1017
/home/me/Web/my-project/vendor/laravel/framework/src/Illuminate/Routing/Router.php:996
/home/me/Web/my-project/vendor/laravel/framework/src/Illuminate/Foundation/Application.php:775
/home/me/Web/my-project/vendor/laravel/framework/src/Illuminate/Foundation/Application.php:745
/home/me/Web/my-project/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Client.php:81
/home/me/Web/my-project/vendor/symfony/browser-kit/Symfony/Component/BrowserKit/Client.php:327
/home/me/Web/my-project/vendor/laravel/framework/src/Illuminate/Foundation/Testing/ApplicationTrait.php:51
/home/me/Web/my-project/app/tests/UnitModelTest.php:32
In both case the line given in the trace for the test file corresponds to the second call of the test.
As I noted in the comments of the routes.php file, if I use a simple url with no slash, the test passes without problem.
I have no problem when I use the api from the browser.
I found many topics related to the NotFoundHttpException on StackOverflow, but none looks like mine. This one is specifically present when testing and only trigger an error at the second call.
So what am I doing wrong here ? Or is it really a bug ?
The problem is that calls made with the same client will use the provided URI relatively. That means what you actually call is:
myapi/path
myapi/myapi/path
You can fix this if you add a preface the urls with a / to make them absolute to the root of the application.
public function testTest()
{
$res = $this->call('GET', '/myapi/path');
// Until here everything works right
$this->assertEquals(json_decode($res->getContent()), array());
// Now I call the same URL a second time
$res = $this->call('GET', '/myapi/path');
$this->assertEquals(json_decode($res->getContent()), array());
}
If you experience other issues like that it often helps to call
$this->refreshApplication();
(This would also create a new client and therefore solve this issue as well)
In my case this error happened because i change public directory name to public_html my solution was put this in the \App\Providers\AppServiceProvider register method.
public function register()
{
// ...
$this->app->bind('path.public', function() {
return base_path('public_html');
});
}

Get output of a Symfony command and save it to a file

I'm using Symfony 2.0.
I have created a command in Symfony and I want to take its output and write it to a file.
All I want is to take everything that is written on the standard output (on the console) and to have it in a variable. By all I mean things echoed in the command, exceptions catched in other files, called by the command and so on. I want the output both on the screen and in a variable (in order to write the content of the variable in a file). I will do the writing in the file in the end of the execute() method of the command.
Something like this:
protected function execute(InputInterface $input, OutputInterface $output)
{
// some logic and calls to services and functions
echo 'The operation was successful.';
$this->writeLogToFile($file, $output???);
}
And in the file I want to have:
[Output from the calls to other services, if any]
The operation was successful.
Can you please help me?
I tried something like this:
$stream = $output->getStream();
$content = stream_get_contents($stream, 5);
but the command doesn't finish in that way. :(
You could just forward the command output using standard shell methods with php app/console your:command > output.log. Or, if this is not an option, you could introduce a wrapper for the OutputInterface that would write to a stream and then forward calls to the wrapped output.
I needed the same thing, in my case, I wanted to email the console output for debug and audit to email, so I've made anon PHP class wrapper, which stores the line data and then passes to the original output instance, this will work only for PHP 7+.
protected function execute(InputInterface $input, OutputInterface $output) {
$loggableOutput = new class {
private $linesData;
public $output;
public function write($data) {
$this->linesData .= $data;
$this->output->write($data);
}
public function writeln($data) {
$this->linesData .= $data . "\n";
$this->output->writeln($data);
}
public function getLinesData() {
return $this->linesData;
}
};
$loggableOutput->output = $output;
//do some work with output
var_dump($loggableOutput->getLinesData());
}
Note this will only store the data written using write and writeln OutputInterface methods, this will no store any PHP warnings etc.
Sorry for bringing this up again.
I'm in a similar situation and if you browse the code for Symfony versions (2.7 onwards), there already is a solution.
You can easily adapt this to your specific problem:
// use Symfony\Component\Console\Output\BufferedOutput;
// You can use NullOutput() if you don't need the output
$output = new BufferedOutput();
$application->run($input, $output);
// return the output, don't use if you used NullOutput()
$content = $output->fetch();
This should neatly solve the problem.

Laravel 4 - created singleton class not found

My journey into Laravel 4 continues. I'm trying to develop a menu that is dynamically created on the master view. To do this I found this article, and I'm trying to implement it.
I've got the code so far but this part appears to be causing a problem:
App::before(function ($request) {
// $myApp Singleton object
App::singleton('myApp', function () {
$app = new stdClass;
$app->title = "downsCMS";
if (Sentry::check()) {
$app->user = Sentry::getUser();
$app->isLogedin = TRUE;
} else {
$app->isLogedin = FALSE;
$app->user = FALSE;
}
return $app;
});
$app = App::make('myApp');
View::share('myApp', $app);
});
WHen I try to run the app I get a class not found 'myApp'
So it appears it's not creating the class. I did a composer dump-autoload but no effect.
I must admit I don't fully understand the ioc so please be gentle. Are there simple steps I am missing here?
Try unwrapping the block of code from within App::before(). Temporarily place the block of code at the top of the routes.php file and see what happens. If this fixes the issue, look into wrapping your code in a "service provider" class. That way it won't "muck up" the routes file, and will be tucked away nicely.
I gave up trying to implement the code - I re-wrote without creating a singleton.
It may not be as efficient but it works for now
Ta

getUser() always return 0 in Codeigniter

I started to create a small application using codeigniter framework
and i have dowloaded Facebook connect from github after creating my application inside facebook, at this moment all work alright my only problem is getUser() always return 0
i have create a facebook.php inside application/config/
alse i have extracting facebook.php & base_facebook.php inside application/libraries/
this is my code
class Welcome extends CI_Controller {
private $data = array();
public function index() {
$this->data['loginUrl'] = $this->facebook->getLoginUrl();
$this->data['userId'] = $this->facebook->getUser();
$this->load->view('welcome_message', $this->data);
}
}
in autoload
i have :
$autoload['libraries'] = array('database','session','facebook');
so why getUser() return 0 and how can i fix this problem
thx
on base_facebook.php, find the makeRequest() method, and, inside the function, find this line:
$opts = self::$CURL_OPTS;
Immediately following it, add:
$opts[CURLOPT_SSL_VERIFYPEER] = false;
or read from here
It does this, sometimes. I've never worked out why, but there is a simple solution that I now always follow.
As opposed to asking for getUser, ask for api(/me) wrapped in a try catch block. If this fails, user is not logged in/token is invalid. If it works the user is logged in, and you get the user id from the resultant array.
You're probably saving a call, as you'll ask for /me anyway. Just remember the try catch for error trapping!

Categories