I would like to have a variable from request ($request->getUri()->getBasePath();) always available on the templates. How can I do this e.g. with a middleware without having to pass the above as parameter to renderer->render on all routes each time ?
$app->get(...
...
$args['basepath']=$request->getUri()->getBasePath();
return $this->renderer->render($response, 'test.php', $args);
});
UPDATE:
This can be done after php-view 2.1.0 as so:
dependencies.php:
$container['renderer'] = function ($c) {
$settings = $c->get('settings')['renderer'];
return new Slim\Views\PhpRenderer($settings['template_path']);
};
middleware.php:
$app->add(function (Request $request, Response $response, callable $next) {
$uri = $request->getUri();
$renderer = $this->get('renderer');
$renderer->addAttribute('uri', $request->getUri());
return $next($request, $response);
});
Then, inside the template:
<?php
$basePath=$uri->getBasePath();
$rpath=$uri->getPath();
?>
Version 2.1.0 of PHP-View now supports setting template variables before you render. See https://github.com/slimphp/PHP-View#template-variables.
While looking into the Code of the PhpRenderer you will see currently there is no way to specify data outside of the render() function.
You could create an issue and/or make a pull request to support that functionality.
Related
Hi Folks i upgrading my slim framework from slim 2 to slim 4 for older project
for one route i added the one value before route using slim 2 slim.before in index.php
example code:
$app->hook('slim.before', function () use ($app) {
$env = $app->environment();
$path = $env['PATH_INFO'];
// spliting the route and adding the dynamic value to the route
$uriArray = explode('/', $path);
$dynamicvalue = 'value';
if(array_key_exists($uriArray[1], array)) {
$dynamicvalue = $uriArray[1];
//we are trimming the api route
$path_trimmed = substr($path, strlen($dynamicvalue) + 1);
$env['PATH_INFO'] = $path_trimmed;
}
});
i read about the add beforemiddleware but cannot able find correct way to add it and i cannot able to find the replacement for $app->environment();
i want to append the dynamic value directly to route
for example
i have one route like this
https://api.fakedata.com/fakeid
by using the above route splitting code i appending the value route using slim.before in slim 2
for example take the dynamic value as test
the route will be
https://api.fakedata.com/test/fakeid
the response of the both api will be same we want to just add value to the route
can any one help me how to do with slim 4
I assume you need to and PATH_INFO to the environment so you can later refer to it in the route callback. You can add a middleware to add attributes to the $request the route callback receives:
use Psr\Http\Message\ServerRequestInterface as Request;
use Psr\Http\Server\RequestHandlerInterface as RequestHandler;
use Slim\Psr7\Response;
class PathInfoMiddleware {
public function __invoke(Request $request, RequestHandler $handler) : Response {
$info = 'some value, path_trimmed for example...'; // this could be whatever you need it to be
$request = $request->withAttribute('PATH_INFO', $info);
return $handler->handle($request);
}
}
// Add middleware to all routes
$app->add(PathInfoMiddleware::class);
// Use the attribute in a route
$app->get('/pathinfo', function(Request $request, Response $response){
$response->getBody()->write($request->getAttribute('PATH_INFO'));
return $response;
});
Now visiting /pathinfo gives the following output:
some value, path_trimmed for example...
I'm working thru a tutorial on the Slim framework. The author uses Twig, and I'd prefer to use the Plates template engine. I've been able to modify all lessons to use the Plates template, until the author started using baseUrl and pathFor extensions.
I see that Plates has an extension called URI, which I think is synonymous with Twig's pathFor.
Unfortunately, I can't for the life of me figure out how to get it enabled. Reading the documentation, I thought the following code would do it, but so far no luck.
require 'vendor/autoload.php';
$app = new Slim\App([
'settings' => [
'displayErrorDetails' => true
]
]);
$container = $app->getContainer();
$container['view'] = function ($container) {
$plates = new League\Plates\Engine(__DIR__ . '/templates');
$plates->loadExtension(new League\Plates\Extension\URI($_SERVER['PATH_INFO']));
return $plates;
};
$app->get('/contact', function($request, $response) {
return $this->view->render('contact');
});
$app->post('/contact', function($request, $response) {
return $response->withRedirect('http://slim-local.com/contact/confirm');
})->setName('contact');
$app->get('/contact/confirm', function($request, $response) {
return $this->view->render('contact_confirm');
});
$app->run();
And then in the template, the author used the pathFor extension to populate a form's action parameter. I am trying to use Plates' URI extention to do the same like so:
<form action="<?=$this->uri('contact')?>" method="post">
Has anybody used this template engine and the URI extension with Slim specifically? Am I mistaken that it is basically synonymous with Twig's pathFor extension? Should I give up and just use Twig? thanks for your advice.
You can use the URI from the environment.
Slim 3 example:
$container['view'] = function ($container) {
$plates = new \League\Plates\Engine(__DIR__ . '/templates');
$uri = \Slim\Http\Uri::createFromEnvironment(new \Slim\Http\Environment($_SERVER));
$plates->loadExtension(new \League\Plates\Extension\URI($uri->__toString()));
return $plates;
};
I'm using Woocommerce webhooks to listen out for every time an order is created/updated/deleted.
I've setup the webhook in Woocommerce as follows
In my Laravel routes file I have set up the route as follows:
use Illuminate\Http\Request;
// API routes...
Route::post('api/v1/orders/create', function (Request $request) {
Log::debug($request->all());
return $request->all();
});
However, when I view the logs as well as the return data in POSTMAN, all I get is an empty array.
Any HTTP method other than 'GET' throws a MethodNotAllowedException
I'm not sure of any other way in Laravel to consume data other than with Request $request.
According to my understanding of routing in Laravel, the input that you pass in to the function is meant to actually be variables for your route.
So if you had a route in your API:
api/v1/orders/{id}/create then in the route function you'd pass in id as the method argument. So this would be correct:
Route::post('api/v1/orders/{id}/create', function ($id) {
Log::debug($id);
return $id;
});
It's looking for request in your route definition.
Rather create a controller. Then in your routes.php use this:
Route::post('api/v1/orders/create', 'OrdersController#create')
That tells your routing to redirect all HTTP POST calls to api/v1/orders/create to the OrdersController.php and the create() method within that controller.
In your controller, you'll be able to use the $request variable as an input argument and it should work.
So in OrdersController.php:
class OrdersController extends Controller {
public function create(Request $request) {
Log::debug($request->all());
return $request->all();
}
}
Good Luck!
This worked for me. My route in api.php is as follow.
Route::post('/woocommerce/webhook/', 'Api\WoocommerceController#test');
And my controller action is as follow.
public function test()
{
$payload = #file_get_contents('php://input');
$payload = json_decode( $payload, true);
\Log::info(json_encode( $payload));
return response()->json([ 'data' => $payload, 'status' => \Symfony\Component\HttpFoundation\Response::HTTP_OK]);
}
I'm trying to implement json-schema validator from justinrainbow as middleware in Slim 3.
I can't figure out how to get the clients input from GET/POST requests in middleware.
tried like this:
$mw = function ($request, $response, $next) {
$data = $request->getParsedBody();
print_r($data); // prints nothing
$id = $request->getAttribute('loan_id');
print_r($id); // prints nothing
// here I need to validate the user input from GET/POST requests with json-schema library and send the result to controller
$response = $next($request, $response);
return $response;
};
$app->get('/loan/{loan_id}', function (Request $request, Response $response) use ($app, $model) {
$loanId = $request->getAttribute('loan_id'); // here it works
$data = $model->getLoan($loanId);
$newResponse = $response->withJson($data, 201);
return $newResponse;
})->add($mw);
There are 2 possible ways of how I need it. what i'm doing wrong ?
validate it in middleware and send some array/json response to the controller, which i will then get as I understood with $data = $request->getParsedBody();
validate it in middleware but final check will be in controller like this:
$app->get('/loan/{loan_id}', function (Request $request, Response $response) use ($app, $model) {
if($validator->isValid()){
//
}
$loanId = $request->getAttribute('loan_id'); // here it works
$data = $model->getLoan($loanId);
$newResponse = $response->withJson($data, 201);
return $newResponse;
})->add($mw);
Best option for me it do something like here
but I don't understand what should i return in container, and how to pass get/post input to container
Your code in the first point seems alright, you only try to access route parameter from within middleware. At that point the route is not yet resolved and therefore parameters are not parsed from the URL.
This is a known use case and is described in Slim's documentation. Add the following setting to your app configuration to get your code working:
$app = new App([
'settings' => [
// Only set this if you need access to route within middleware
'determineRouteBeforeAppMiddleware' => true
]
]);
In order to understand how middleware works and how to manipulate response object, I suggest you read the User Guide - it's not that long and explains it really well.
I am trying to use Steam's Login With Slim Framework!
For this I am trying to use steamauth library (https://github.com/SmItH197/SteamAuthentication)
I am able to successfully require the files to slim via that start.php but how do I call the steamlogin() and logout functions?
Please help me!
You will need to add a middleware for the auth step.
Here's a simple example, assuming you are using Slim 3:
$middleware = function (Request $request, Response $response, $next) {
$this->user = null;
if(!isset($_SESSION['steamid'])) {
//don't interfere with unmatched routes
$route = $request->getAttribute('route');
if ($route && !in_array($route->getName(), ['login'])) {
return $response->withStatus(403)->withHeader('Location', $this->router->pathFor('login'));
}
} else {
include ('steamauth/userInfo.php'); //To access the $steamprofile array
//Protected content
}
return $next($request, $response);
};
$app->add($middleware);
In your /login route just include a view with steamlogin(). You can use the basic php-view template for this.