Use specific ServiceProvider in Laravel 4 - php

Laravel 4 ships with the php artisan routes command. This shows a list of registered routes on the command line. Instead of showing the registered routes on the command line, I would like to get its values within a controller.
The following method does exactly what I want:
Illuminate\Foundation\Console\RoutesCommand()
Unfortunately this is a protected method, so it doesn't work when I try something like this:
$rc = new Illuminate\Foundation\Console\RoutesCommand(new Illuminate\Routing\Router);
print_r($rc->getRoutes());
How can I access this method to display the registered routes in my Laravel 4 app?
Or even better; how can I access methods of any autoloaded service provider?

You can get all routes like this:
$routes = App::make('router')->getRoutes();
foreach($routes as $name => $route)
{
//do your stuff
}

I believe you would have to create a class that extends Illuminate\Foundation\Console\RoutesCommand and then you can run the method using print_r($this->getRoutes());

Here is a sample of how you can call an Artisan command from inside a Controller:
use Symfony\Component\Console\Input\ArrayInput;
use Symfony\Component\Console\Output\Output;
use Illuminate\Console\Application as ConsoleApplication;
class MyOutput extends Output {
protected $contents = '';
protected function doWrite($message, $newline)
{
$this->contents .= $message . ($newline ? "\n" : '');
}
public function __toString()
{
return $this->contents;
}
}
class MyController extends BaseController {
public function getRoutes()
{
$app = app();
$app->loadDeferredProviders();
$artisan = ConsoleApplication::start($app);
$command = $artisan->find('routes');
$input = new ArrayInput(array('command' => 'routes'));
$output = new MyOutput();
$command->run($input, $output);
return '<pre>' . $output . '</pre>';
}
}
In this case, the Artisan command is routes and we are not passing any parameter to it.

Related

irazasyed/telegram-bot-sdk get update object on commands

I was using irazasyed/telegram-bot-sdk for a Telegram bot in Laravel. I just wanted to access the update object on my StartCommand class and send a welcome message to a user with his name. The StartCommand class looks like this:
<?php
namespace App\TelegramCommands;
use Telegram\Bot\Commands\Command;
class StartCommand extends Command
{
protected $name = "start";
protected $description = "Lets you get started";
public function handle()
{
$this->replyWithMessage(['text' => 'Welcome ']);
}
}
And the route (which is inside api.php) is:
Route::post('/'.env('TELEGRAM_BOT_TOKEN').'/webhook', function (Request $request) {
$update = Telegram::commandsHandler(true);
return 'ok';
});
I just wanted to access users data when he sends /start command and replay with a message like, "Welcome [his name]". Thank you in advance.
I just have got the answer. It was mainly adding the following to the handle method of StartCommand class:
$update= $this->getUpdate();
So the final file will look like:
<?php
namespace App\TelegramCommands;
use Telegram\Bot\Commands\Command;
class StartCommand extends Command
{
protected $name = "start";
protected $description = "Lets you get started";
public function handle()
{
$update= $this->getUpdate();
$name = $update['message']['from']['first_name'];
$this->replyWithMessage(['text' => 'Welcome '.$name]);
}
}
A good tutorial is here

Access Arguments Input via Artisan Console Command

I want to run my command like this
php artisan update:code --code=123
I want to get the code from first argument - I can't seems to find a way to do it on Laravel site.
<?php
namespace App\Console\Commands;
use App\User;
use Illuminate\Console\Command;
class updateCode extends Command
{
protected $signature = 'update:code {code}';
protected $description = 'Update Code ... ';
public function __construct()
{
parent::__construct();
}
public function handle()
{
$code = $this->option('code');
$this->info($code);
$user = User::where('type','Admin')->first();
$user->code = bcrypt($code);
$user->active = 1;
$user->save();
$this->info($user);
}
}
I kept getting
The "--code" option does not exist.
Do I need to defind my option too ?
How can I just quickly access the first argument ?
{code} is for arguments. For options it is {--code} or {--code=}:
// option as switch:
protected $signature = 'update:code {--code}';
// option with value:
protected $signature = 'update:code {--code=}';
Just use
php artisan update:code 123

APCu Adapter & Symfony 3.3 -> Error

I am trying to plug APCu into the Symfony 3.3 test project.
I am getting an error, when I add ApcuAdapter to AppKernel.php.
Here is the list of what I have done:
in ./app/AppKernel.php i have added a "new" line to $bundles in public function registerBundles():
public function registerBundles()
{
$bundles = [
... ,
new Symfony\Component\Cache\Adapter\ApcuAdapter()
];
...
return $bundles;
}
Opened the project's site. It shows an error:
Attempted to call an undefined method named "getName" of class "Symfony\Component\Cache\Adapter\ApcuAdapter".
(./ means the root folder of the project)
Please, tell me why does this error happen and how to plug this adapter into the symfony framework. Thank you.
me have found the solution somewhere on the framework's website.
somehow, we should use not the Adapter, but the Simple instead.
seems very un-logical to me.
so, the Service now works and looks this way:
<?php
namespace AppBundle\Service;
use Symfony\Component\Cache\Simple\ApcuCache;
class ApcuTester
{
public function __construct
(
)
{
}
public function testMe()
{
$cache = new ApcuCache();
$TestVar_dv = 0;
$TestVar_vn = 'TestVar';
$TestVar = NULL;
//$cache-> deleteItem($TestVar_vn); // dbg
// Read
if ( $cache->hasItem($TestVar_vn) )
{
$TestVar = $cache->get($TestVar_vn);
}
else
{
$cache->set($TestVar_vn, $TestVar_dv);
$TestVar = $TestVar_dv;
}
// Modify
$TestVar++;
// Save
$cache->set($TestVar_vn, $TestVar);
// Return
return $TestVar;
}
}
And the Controller which executes this Service looks as this:
<?php
namespace AppBundle\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use AppBundle\Service\MessageGenerator;
use AppBundle\Service\ApcuTester;
class LuckyController extends Controller
{
/**
* #Route("/lucky/number", name="lucky")
*/
public function numberAction
(
Request $request,
MessageGenerator $messageGenerator,
ApcuTester $apcuTester
)
{
$lucky_number = mt_rand(0, 100);
$message = $messageGenerator->getHappyMessage();
$testvar = $apcuTester->testMe();
$tpl = 'default/lucky_number.html.twig';
$tpl_vars =
[
'lucky_number' => $lucky_number,
'message' => $message,
'testvar' => $testvar
];
return $this->render($tpl, $tpl_vars);
}
}
If i wrote the same thing in pure PHP i would have done it an hour earlier :) Oh these crazy frameworks...

how to write a phptest for controller in fuelphp

I only have a controller and view, I want to mock a http request to test this controller, I use fuelphp, hope someone can give me some advice or demo
class Controller_Index extends Controller_Template{
public function action_index(){
$view = View::forge('index');
$this->template->content = $view;
}
}
I write like this
class Test_Controller_index extends TestCase{
public function TestController(){
$expected = View::forge('index');
$response = Request::forge('index')
->set_method('GET')
->execute()
->response();
$assertValue = $response->body->content;
$this->assertSame($expected, $assertValue);
}
}
php oil test result
There was 1 failure:
1) Warning
No tests found in class "Test_Controller_index".
what's wrong
All unit tests in fuelphp need to take the form of test_ or they won't be recognised.
Try this: (not the different function name)
class Test_Controller_index extends TestCase{
public function test_controller(){
$expected = View::forge('index');
$response = Request::forge('index')
->set_method('GET')
->execute()
->response();
$assertValue = $response->body->content;
$this->assertSame($expected, $assertValue);
}
}

How do I access the Router through an artisan command?

I need access to the RouteCollection that Laravel possesses when it gets ran normally and all ServiceProviders are booted. I need the RouteCollection because a legacy app needs to know if Laravel has the particular route, so if it doesn't, legacy code can take care of the route.
I figure if I can somehow get a hold of Illuminate\Routing\Router in an artisan command, I could simply call the getRoutes() function and output a JSON file containing an array of all the routes. Then when the legacy code needs to determine if Laravel supports the Route, it could read that file.
In order to do that though, I need access to the Router class. Not sure how to accomplish that... I looked at Illuminate\Foundation\Console\RoutesCommand source code and I can't figure out how it works. What's really odd is it looks like the Router class is being injected, but when I do Artisan::resolve('MyCommand'), I get an empty RouteCollection.
EDIT
I never did figure out how to accomplish this question, but for those in a similar situation, I found this works for the most part, although I'm not sure how bad the overhead is starting Laravel each request just to check the routes. Right now it doesn't seem like that much.
// Start laravel, so we can see if it should handle the request
require_once(__DIR__.'/laravel/bootstrap/autoload.php');
$app = require_once(__DIR__.'/laravel/bootstrap/start.php');
$app->boot();
// Create the fake request for laravel router
$request = Request::createFromGlobals();
$request->server->set('PHP_SELF', '/laravel/public/index.php/'.$_REQUEST['modname']);
$request->server->set('SCRIPT_NAME', '/laravel/public/index.php');
$request->server->set('SCRIPT_FILENAME', __DIR__.'/laravel/public/index.php');
$request->server->set('REQUEST_URI', '/laravel/public/'.$_REQUEST['modname']);
$routes = Route::getRoutes();
foreach($routes as $route) {
if ($route->matches($request)) {
$app->run($request);
exit;
}
}
Here is a simplified implementation
JsonRoutes.php
<?php
use Illuminate\Console\Command;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Input\InputArgument;
use Illuminate\Routing\Route;
use Illuminate\Routing\Router;
class JsonRoutes extends Command {
protected $name = 'routes:json';
protected $description = 'Spits route information in JSON format.';
protected $router;
protected $routes;
public function __construct(Router $router) {
parent::__construct();
$this->router = $router;
$this->routes = $router->getRoutes();
}
public function fire() {
$result = [];
foreach ($this->routes as $route) {
$result[] = [
'methods' => implode(',', $route->methods()),
'host' => $route->domain(),
'uri' => $route->uri(),
'name' => $route->getName(),
'action' => $route->getActionName(),
];
}
$file = $this->option('file');
if ($file) {
File::put($file, json_encode($result));
return;
}
$this->info(json_encode($result));
}
protected function getArguments() { return []; }
protected function getOptions() {
return [
['file', 'f', InputOption::VALUE_OPTIONAL, 'File name.'],
];
}
}
You register it in artisan.php:
Artisan::resolve('JsonRoutes');
Sample usage:
Spit it out to stdout
$ artisan routes:json
[{"methods":"GET,HEAD","host":null,"uri":"\/","name":null,"action":"Closure"}]
Write it to a file
$ artisan routes:json -f /tmp/routes.json

Categories