Does anyone know if it's possible to make use of URL query's within Laravel.
Example
I have the following route:
Route::get('/text', 'TextController#index');
And the text on that page is based on the following url query:
http://example.com/text?color={COLOR}
How would I approach this within Laravel?
For future visitors, I use the approach below for > 5.0. It utilizes Laravel's Request class and can help keep the business logic out of your routes and controller.
Example URL
admin.website.com/get-grid-value?object=Foo&value=Bar
Routes.php
Route::get('get-grid-value', 'YourController#getGridValue');
YourController.php
/**
* $request is an array of data
*/
public function getGridValue(Request $request)
{
// returns "Foo"
$object = $request->query('object');
// returns "Bar"
$value = $request->query('value');
// returns array of entire input query...can now use $query['value'], etc. to access data
$query = $request->all();
// Or to keep business logic out of controller, I use like:
$n = new MyClass($request->all());
$n->doSomething();
$n->etc();
}
For more on retrieving inputs from the request object, read the docs.
Yes, it is possible. Try this:
Route::get('test', function(){
return "<h1>" . Input::get("color") . "</h1>";
});
and call it by going to http://example.com/test?color=red.
You can, of course, extend it with additional arguments to your heart's content. Try this:
Route::get('test', function(){
return "<pre>" . print_r(Input::all(), true) . "</pre>";
});
and add some more arguments:
http://example.com/?color=red&time=now&greeting=bonjour`
This will give you
Array
(
[color] => red
[time] => now
[greeting] => bonjour
)
Query params are used like this:
use Illuminate\Http\Request;
class ColorController extends BaseController{
public function index(Request $request){
$color = $request->query('color');
}
public function fetchQuery(Request $request){
$object = $request->query('object');
$value = $request->query('value');
}
Related
I'm building a Laravel app, and I need to use an URL that looks like that :
/api/ads?page=Actuel&formatsQuery[]=side&formatsQuery[]=leaderboard&deviceQuery=mobile
I have 3 parameters (page, formatsQuery (as an array), and deviceQuery).
Do you now how to hold his in routing and controller in order to have the correct value inside the controller's fonction?
I tried this :
routes/api.php
//request to get ads for given parameters
Route::get('/ads', [MediaController::class, 'findAds']);
and this (MediaController.php) :
public function findAds($page, $formatsQuery, $deviceQuery) {
echo $page;
if(sizeof($formatsQuery) <= 0 || sizeof($formatsQuery) > 3){
return $this->unvalidParametersError();
}
//transform format to position depending on deviceQuery
$position = [];
$res = [];
foreach ($formatsQuery as $format) {
$res = Media::where('position', $format)->inRandomOrder()->first()->union($res);
}
echo $res;
return $res;
}
then I test it with this :
public function test_findAds()
{
$ads = Ad::factory()
->has(Media::factory()->count(3), 'medias')
->count(3)->create();
$response = $this->get('/api/ads?page=Actuel&formatsQuery[]=side&formatsQuery[]=leaderboard&deviceQuery=mobile');
$response->assertStatus(200);
}
You are using a GET request to fetch your data. GET request is a type of request that you send parameters in URL using ? after URL and separating parameters with &. You can find out more about HTTP methods here.
In laravel using request parameters is so simple. First of all you need to add Request $request to your method prototype like this:
use Illuminate\Http\Request;
public function findAds(Request $request)
Then you can simply use $request->parameter to get the values. So you need to change your code like this:
public function findAds(Request $request){
$page = $request->page;
$formatsQuery = $request->formatsQuery;
$deviceQuery = $request->deviceQuery;
// Your code
}
And as #matiaslauriti mentioned in the comments you don't need to put [] after formatsQuery[] to send an array in GET request. Using the same key more than one time automatically makes an array for you.
I began writing a webapp in Codigniter 4 and currently, i'm stuck with the pagination.
I created a controller, a model an a view to retrieve database entries für usergroups and used CI's built-in pagination-library.
UsergroupsModel:
<?php namespace App\Models;
use CodeIgniter\Model;
class UsergroupsModel extends Model{
protected $table = 'roles';
protected $allowedFields = [];
protected $beforeInsert = ['beforeInsert'];
protected $beforeUpdate = ['beforeUpdate'];
public function getGroups(){
$db = \Config\Database::connect();
$builder = $db->table('roles');
$query = $builder->get();
$results = $query->getResultArray();
return $results;
}
}
Controller (Usergroups):
<?php namespace App\Controllers;
use App\Models\UsergroupsModel;
class Usergroups extends BaseController
{
public function index()
{
//Helper laden
helper(['form','template','userrights']);
$data = [];
$data['template'] = get_template();
$data['info'] = [
"active" => "menu_dash",
"title" => "Dashboard",
"icon" => "fab fa-fort-awesome fa-lg",
"sub" => "Frontend",
];
//Check Permissions
$data['userrights'] = get_userrights(session()->get('id'));
if($data['userrights'][1] == 1)
{
foreach($data['userrights'] as $key => $value){
$data['userrights'][$key] = '1';
}
}
else
{
$data['userrights'] = $data['userrights'];
}
$model = new UsergroupsModel;
$model->getGroups();
$pager = \Config\Services::pager();
$data['usergroups'] = $model->paginate(5);
$data['pager'] = $model->pager;
//Create Views
echo view($data['template'].'/templates/header', $data);
echo view($data['template'].'/backend/navigation');
echo view($data['template'].'/templates/sidebar');
echo view($data['template'].'/backend/usergroups');
echo view($data['template'].'/templates/footer');
}
//--------------------------------------------------------------------
}
In the view, i got my pagination by using
<?= $pager->links() ?>
The default pagination works fine, but i get an URI like https://DOMAIN.DE/usergroups?page=2
In the official Codeigniter 4 docs for the pagination, you can find the following:
Specifying the URI Segment for Page
It is also possible to use a URI segment for the page number, instead of the page query parameter. >Simply specify the segment number to use as the fourth argument. URIs generated by the pager would then >look like https://domain.tld/model/[pageNumber] instead of https://domain.tld/model?page=[pageNumber].:
::
$users = $userModel->paginate(10, ‘group1’, null, 3);
Please note: $segment value cannot be greater than the number of URI segments plus 1.
So in my controller i changed
$data['usergroups'] = $model->paginate(5);
to
$data['usergroups'] = $model->paginate(5,'test',0,2);
and in the view i added 'test' as a parameter.
<?= $pager->links('test') ?>
In the Routes i added
$routes->get('usergroups/(:num)', 'Usergroups::index/$1');
and in the Controller i changed the index-function to
public function index($segment = null)
The URIs generated from the pagination now look like this:
https://DOMAIN.DE/usergroups/2
but it does not change anything in the entries and the pagination itself alway sticks to page 1.
I think, i can not use CI's built in library when switching to segment-URIs and thus i need to create a manual pagination.
Can somebody help me to fix this problem?
I currently had the same problem using segments in my pagination.
After much research I discovered that when you use segments associated with a group name in your case "test" you must assign the segment to the variable $ pager
$pager->setSegment(2, 'nameOfGroup');
You only need to change the first parameter with the segment number that you are using and the second with the name of the group that you are assigning.
It seems like there's a bug in Version 4.0.3. so it can't work out of the box. But i found a way to solve it:
The index-function needs to look like this:
public function index($page = 1)
and
within the Controller, the $data['usergroups'] need to look like this:
$data['usergroups'] = $model->paginate(5, 'test', $page, 2);
with 2 being the segment of the page-number in the URI.
Works like a charm.
How can i define a global variable such that my current_user method can work were ever i want it to, all i simple need to do is check if there is a current user my example code is below
if (isset($_SESSION['company_id'])) {
$current_user = Companies::find($_SESSION['company_id']);
}
else
{
$current_company = null;
}
how can i use the current user method where ever i want without passing it to my app->render() method just like in my header.html
{% if current_user %}
hi {{current_user.name}}
{% endif %}
You can inject a value into the app object:
$app->foo = 'bar';
More on Slim’s documentation.
Injection is not working in the callback function.
To have access to the variable in a callback function you can use "use() " function :
$mydata = array ( ... );
$app->get('/api', function(Request $request, Response $response) use($mydata) {
echo json_encode($mydata);
});
Inject the object it like this:
$app->companies = new Companies();
You can also inject it as a singleton if you want to make sure its the same one each time:
$app->container->singleton('companies', function (){
return new Companies();
});
The call it like this:
$app->companies->find($_SESSION['company_id']);
UPDATE DOC LINK:
Slim Dependency Injection
The accepted answer does not work for Slim 3 (as the hooks have been removed).
If you are trying to define a variable for all views and you are using the PhpRenderer, you can follow their example:
// via the constructor
$templateVariables = [
"title" => "Title"
];
$phpView = new PhpRenderer("./path/to/templates", $templateVariables);
// or setter
$phpView->setAttributes($templateVariables);
// or individually
$phpView->addAttribute($key, $value);
i was finally able to get it to work with this
$app->hook('slim.before.dispatch', function() use ($app) {
$current_company = null;
if (isset($_SESSION['company_id'])) {
$current_company = Company::find($_SESSION['company_id']);
}
$app->view()->setData('current_company', $current_company);
});
With twig/view
creating a middleware
<?php
namespace ETA\Middleware;
class GlobalVariableMiddleware extends Middleware {
public function __invoke($request, $response, $next) {
$current_path = $request->getUri()->getPath();
$this->container->view->getEnvironment()->addGlobal('current_path', $current_path);
return $next($request, $response);
}
}
I want to perform CRUD operations through REST, I am implementing this in codeigniter, The code whatever I pasted here is working, but I have to handle a way to fetch all the datas from the database and also a way to fetch the data by id. Is there any best way to do this?
Backbone.js
(function(){
Backbone.emulateHTTP = true;
//Backbone.emulateJSON = true;
window.App = {
Models: {},
Collections: {},
Views: {},
Router: {}
};
App.Models.Task = Backbone.Model.extend({
defaults: {
title: '',
done: 0
},
urlRoot: 'index.php/taskController/task'
});
})();
Controller
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
require(APPPATH.'libraries/REST_Controller.php');
class taskController extends REST_Controller {
public function task_get($id){
$this->load->model('Task', 'task');
$data['task'] = $this->task->findbyid($id);
}
public function tasks_get(){
$this->load->model('Task','task');
$data['task'] = $this->task->find();
$this->response($data,200);
}
public function task_put($id)
{
# code...
$this->load->model('Task', 'task');
$data = json_decode(file_get_contents('php://input'), true);
// $data['title'] = $var['title'];
// $data['done'] = $var['done'];
echo var_dump($data);
$data['task'] = $this->task->updatebyid($id,$data);
//$this->response($data,200);
}
public function task_delete($id){
$this->load->model('Task','task');
$data['task'] = $this->task->delete($id);
}
public function task_post(){
$this->load->model('Task','task');
$data = json_decode(file_get_contents('php://input'),true);
return $data['task'] = $this->task->create($data);
}
}
I use /get/id for the items and /list/number_to_show/limit
So add a list_get($number, $limit)
method
if code for a /get/id is no id is passed, Send the entire lot ?
The principle of REST is that the CRUD actions are represented by the HTTP verbs. GET = select, PUT = update, POST = create and DELETE = delete.
You use nouns in your URL to represent your resources (e.g. tasks).
From your CI code it looks like you use always GET and have verbs+nouns in your URLs.
In REST, to get all tasks you would need to do GET http://example.com/tasks. To get one specific task you would need to do GET http://example.com/tasks/1234
Please read http://info.apigee.com/Portals/62317/docs/web%20api.pdf to understand the principle.
newbie in laravel.
In laravel sample routing
Route::get('books/{genre}', 'controller#method');
The link would be something like this
link.com/books/crime or link.com/books/programming
how do i do it if I want to get both genre?
if this possible is to achieve
link.com/books?genre=crime,programming
how do i write that in routes? and also how do i get the value in controller?
I have tried something like this. But I don't have any idea how to achieve it.
Route::get('books?{genre?}', 'controller#method');
Controller part
function method($fields = null) {
return jsonData;
}
Found a way but its kinda awful...
route
Route::get('books', 'controller#method');
url
link.com/books?genre=crime,programming,love,religion
method
function method() {
$array = explode(',',$_GET['fields');
//.....
return jsonData;
}
there are few ways you can achieve that.
if want to achieve,
http://link.com/books/crime/programming
or
http://link.com/books/crime
you can use the following routes:
Route::get('books/{genre}/{genreOptional?}', function($genre, $genreOptional = null)
{
dd($genre, $genreOptional);
});
or
Route::get('books/{genre}/{genreOptional?}', 'controller#method' );
Your controller:
public function method($genre, $genreOptional = NULL)
{
//
}