Using url parameter in route to use in conditional - php

I'm trying to find the correct way to lay this out in laravel so that I can hit one GET route which calls a single function, but within that function I want to use data from a mysql table to determine which blade to show.
Say this URL is visited with a query string parameter:
www.testsite.com?email=testEmail.com
I hit this route (But not sure how to accept the parameter)
Route::get('register', 'Data\DataController#DataForm')
->name('Data.register');
I have a mysql table called dataTable set up like so
email | type
-------------------------
test1#mail.com A
test2#mail.com B
test3#mail.com C
What's the best way to incorporate the email parameter so that I can hit the single route and single function, then use the email/type columns from mysql to determine the appropriate blade to show?
public function DataForm(Request $request)
{
//query table based on query string parameter 'email'
$email = dataTable::where('email', /*email parameter?*/)->first();
if($email['type']== A){
return view('data.typeA');
}elseif($email['type']== B){
return view('data.typeB');
}elseif($email['type']== C){
return view('data.typeC');
}
}

You can add it as a route parameter :
Route::get('register/{email}', 'Data\DataController#DataForm')->name('Data.register');
And then inside controller :
public function DataForm($email)
{
// Abort to 404 if $email is not a valid email address
if(!filter_var($email, FILTER_VALIDATE_EMAIL)) {
abort(404);
}
$typeData = Model::where('email', $email)->first();
// Email not found in the database
if(!$typeData){
abort(404);
}
switch ($typeData->type) {
case 'A':
return view('data.typeA');
case 'B':
return view('data.typeB');
case 'C':
return view('data.typeAC');
default:
abort(404);
}
}

Using a slash in the route you should be able to pass it like this:
Route::get('register/{email}', 'Data\DataController#DataForm')
->name('Data.register');
Then in your function you can just use the variable $email and it contains the email in the URL. But not sure if this URL is OK, using a slash instead of '?email=' for the passing of the parameter.
More on there here:
https://laravel.com/docs/5.7/routing#required-parameters

You'd need more logic than this, obviously:
public function DataForm(Request $request)
{
$type = (dataTable::where('email', $request->query->get('email'))->first())['type'];
return view('data.type'.$type);
}

As others said you could auto type in Request $request; however you don't have to. You can keep the function definition without the passed parameter, and use the helper functions instead:
if(request()->has('email')) {
$email = request()->input('email');
// Do stuff
} else {
// No email supplied
}

Related

Is using if else statement to load view based on parameters after controller and action part of url efficient or is there a better way of doing this

I can have the following urls
www.example.com/accounts/
www.example.com/accounts/signup
www.example.com/accounts/signup/validate
www.example.com/accounts/login
for each case, accounts becomes my controller, and index, signup, signup and login becomes my actions (or methods) respectively. I have to render different views based on what my actions are. Here is an example of what my code looks like
index
$url_segments = explode('/', $url);
$controller = !empty($url_segments[0]) ? $url_segments[0] : 'home';
array_shift($url_segments); // removes the controller name from array
$action = isset($url_segments[0]) && !empty($url_segments[0]) ? $url_segments[0] : 'index';
array_shift($url_segments); // removes the action name from array
$controller = ucfirst($controller);
$controller = new $controller($url_segments);
$controller->$action();
controller class
class Accounts{
private $url_segments;
public function __construct() {
$this->url_segments = $url_segments;
}
public function index() {
// index code here
}
public function login() {
// login code here
}
public function signup() {
if (!isset($this->url_segments[0])) {
// url entered was: example.com/signup
} else if (isset($this->url_segments[0]) && $this->url_segments[0] == 'validate') {
// url entered was: example.com/signup/validate
}
}
}
from how my code appeared above, it can be seen that as parameters keep adding after the controller and action part of the url I'll need to keep using conditional statements to run the proper code as in the case of /signup/ and signup/validate. Is this method of using conditional statement to load view based on parameters efficient or is there a better way of doing this.
I would recommend you to make use of a routing system like Symfony Routing. There you could add a new Route for every url and redirect them to your specific controller.
Example Route:
$routes = new RouteCollection();
$routes->add('/accounts_signup', route('POST', "/accounts/signup", 'App\Controller\AccountController:signup'));
return $routes;
This route would call the signup method in the AccountController calss when www.example.com/accounts/signup get called with a post request.
I recommend you to use something like this. Even if this might be a bit complicated for the beginning, after reading (and understanding) the docs this will safe you a lot of time and it will make your code more readable as well.

How to redirect different page from same controller function in laravel 5.2

I want to redirect 2 different page from this controller function along with value.Here is my code. It works but both of time url become same.what shuld I do?
//in routes.php
Route::post('/','mycontroller#check');
// in controller.php
public function check(Request $request)
{
$c_email = $request->email;
$c_pass=$request->pass;
$c_type=$request->select;
$var=DB::select("SELECT * FROM reg where email = '$c_email' and Password = '$c_pass' and type = '$c_type'");
if ($var) {
return view('farmer')->with('user',$var);
// return redirect('farmer')->with('user',$var);
}
else {
$msg="Invalid login";
return view('index')->with('show',$msg);
}
}
If you want to actually redirect u can use the redirect() helper as statet in the official docs https://laravel.com/docs/5.3/redirects
You can also pass data
redirect('/my-route')->with(['user' => $var]);
The passed data can then be accesses through the session helper
$var = session('user')
HOWEVER, it seems like you have major issues in your code. Your password does not seem to be encrypted. Also there's no reason to use plain sql instead of eloquent here.
The route that is shown in the browser is defined in your
Route::post('/','mycontroller#check');
If you just return different views, the route does not change. You need to redirect to other views.
If you redirect to other routes you will ofcourse need to add / define them.
Route::get('/my-route', function() {}); // or post etc.

Redirect user to a self-made 404 page when users input wrong arguments

I'm using Codeigniter version 3.0.6 and now I have a controller named modifyfiles. The index function of this controller accepts an argument.
Using the given argument, the index controller will search a desired data in a model. The following code is my index function :
public function index($id){
$_SESSION['logged_in']['idmod'] = $id;
$this->data['modullist'] = $this->__getmodulbyid($id);
$this->data['lecturelist'] = $this->__getlecturelist();
if(count($this->data['modullist']) <= 0){
show_404();
} else {
$this->load->view($this->layout, $this->data);
}
}
It works very well for now, when I try to insert wrong number arguments it directs me to the codeigniter built-in 404 page.
But when I try to insert some non numbers arguments, say some characters, it directs me to my own 404 page.
Here's my routing rules :
$route['404_override'] = 'home/pagemissing';
$route['dosen/modifymodul'] = 'dosen-tools/modifymodul';
$route['dosen/modifymodul/(:num)'] = 'dosen-tools/modifymodul/index/$1';
I want when users input wrong arguments, no matter they were numbers or characters, the function will redirect to my own 404 page, not the built-in one. How can I achieve that?
I'm pretty sure the problem is in my conditional block
if(count($this->data['modullist']) <= 0){
show_404();
} else {
$this->load->view($this->layout, $this->data);
}
What should I write to replace the show_404() ?
Or if I'm not wrong, how can I replace the show_404() with an 404_override trigger?
Solved
I did a little research and ended up creating this callback in one of my routing rules
$route['dosen/modifymodul/(:num)'] =
function ($id){
if(is_numeric($id)){
return 'dosen-tools/modifymodul/index/'.$id;
} else {
return 'home/pagemissing';
}
};
Thanks everybody

kohana 3 creating routes with get

This has to do with routing. So for getting parameters via url, you basically pass the data to the url following the route format you set.
This is working with links. I created the route, passed the data into the url, and used the request method to get the parameter for use in the controller. like URL::site("site/$color/$size")
What if I am constructing the url by form submission? For example, if I want to create a basic search query.
How do I get my form submission to look like this search/orange/large and not like this search.php?color=orange&size=large when I submit a form via get method.
By definition, the GET method puts the submitted information as URL parameters. If you specifically want to end up with a URL like site/$color/$size, you can use the POST-REDIRECT-GET pattern.
A partial example, from a controller on one of my sites (there is a submit button on the page named clear_cache_button):
public function action_index()
{
$session = Session::instance();
$is_post = (Request::current()->post('submit_button') !== NULL);
$is_clear_cache = (Request::current()->post('clear_cache_button') !== NULL);
$p = Database::instance()->table_prefix();
$people = DB::query(Database::SELECT, "
SELECT *
FROM `".$p."Tabe`;
")->cached(600, $is_clear_cache)->execute()->as_array('RegID');
if ($is_clear_cache)
{
HTTP::redirect(Request::current()->uri());
}
...
...
...
}
You can use Route filters (v3.3) or callbacks (3.1, 3.2) and set route params manually.
You can do it this way...
public function action_index()
{
// this will only be executed if you submmitted a form in your page
if(Arr::get($_POST,'search')){
$errors = '';
$data = Arr::extract($_POST,array('color','size'));
// you can now access data through the $data array:
// $data['color'], $data['size']
// perform validations here
if($data['color']=='') $error = 'Color is required';
elseif($data['size']=='') $error = 'Size is required';
if($error==''){
$this->request->redirect('search/'.$data['color'].'/'.$data['size']);
}
}
// load your search page view here
echo 'this is the search page';
}
Hope this helps you out.

codeiginter no direct access to functions

I'm having this problem about direct access to functions: for example I have this code:
controller users
function index(){
//this is my users index view, user can add,edit,delete cars
}
function details($id){
//a function where 1 car can be viewed in detail..
function add(){
//function to add car
}
Now if I go to address bar and type. localhost/myapp/users/detail it will go to the url and echo an error since $id is null. What I want is only the index is directly accessible if a user would type in the address bar. I don't want the users to go directly to myapp/users/add, etc..
CI Controller functions always must be able to handle user input (i.e. url segments), which means anyone can type in whatever they wish and make a request. You can't stop that. The best practice is to either:
Always provide default arguments
Use the URI class to get your parameters, or func_get_args()
Always validate the presence of and integrity of arguments passed to the controller, as you would with any other user input
Since it's much more common, accepted, and easier to read - just make sure to always provide defaults and validate them.
An example with your controller:
function index() {
//this is my users index view
//user can add,edit,delete cars
}
function details($id = NULL) {
if ( ! $id) {
// No ID present, maybe redirect without message
redirect('users');
}
$user = $this->user_model->get($id);
if ( ! $user) {
// ID present but no user found, redirect with error message
$this->session->set_flashdata('error_message', 'User not found');
redirect('users');
}
// We found a user, load view here etc.
}
function add() {
// Check for the presence of a $_POST value
// You could also use the Form_validation lib here
if ( ! $this->input->post('add_car')
{
$this->session->set_flashdata('error_message', 'Invalid request');
redirect('users');
}
// Try to add the car here and always redirect from here
}
The only other way is to make the method private or use CI's _underscore() naming as suggested (making it inaccessible from the url). You can still call the function in other methods if you wish, as in:
function index() {
if ($this->input->post('add_car')
{
// Call the private "_add" method
$this->_add();
}
// Load index view
}
So to make a long story short: You can't stop the requests from being made, you can only decide what to do when the request is invalid.
Add an underscore before the names of functions you want to hide:
function _details($id){
//a function where 1 car can be viewed in detail..
}
function add(){
//function to add car
}

Categories