Laravel - Creating a Dynamic URL using a Database String - php

I am with a bit of a stuggle here. I managed to create the dynamic URL using the following code:
Home Page Controller
$satellites = DB::table('satellites')->get();
return view('pages/home', ['satellites' => $satellites]);
Blade File
#foreach($satellites as $satellite)
<li>{{$satellite->satname}}</li>
#endforeach
web.php
Route::get('{norad_cat_id}', 'Satellite#show');
Controller
public function show($norad_cat_id)
{
return view('pages/satellite');
}
The URL generated is: mysite.com/12345 (where 12345 is the norad_cat_id).
This code manages to create the dynamic URLs using the norad_cat_id from the database - which is what I want. The problem is that I can replace the URL with anything and it still creates a page (ie. replace the 12345 with something not from the database and a page is still created).
What I want is only for a URL to be generated only with the norad_cat_id and if there is no matching norad_cat_id in the database, display a 404 page.

In the show method add a fetch from database if there is no record just abort
public function show($norad_cat_id)
{
$satellite = DB::table('satellites')->where('norad_cat_id', $norad_cat_id)->first();
if( ! satellite){
return abort(404);
}
return view('pages/satellite');
}
PS: abort will automatically redirect to your resources/views/errors/404.blade.php

You can do this multiple ways
Create a regex for norad_cat_id
The example shows nummeric ([0-9]+)
Route::get('{norad_cat_id}', 'Satellite#show')->where(['norad_cat_id' => '[0-9]+']);
Use findOrFail() and on fail show the 404.
try
{
$user = Satellites::findOrFail($id);
return view('norad_cats');
}
// catch(Exception $e) catch any exception
catch(ModelNotFoundException $e)
{
return view('404');
}

You can throw 404 in your controlller (for example). Just check if records exists in database - if not then return error.
Example:
public function show($cat_id)
{
$sattelites = DB::table('sattelites')->where('norad_cat_id', $cat_id)->get();
if ($satellites === NULL)
{
\App::abort(404);
}
return view('pages/sattelite', [
'satellites' => $satellites
]);
}
I think you get the idea.

Here's an example using query builder which is what I assume you're using:
public function show($norad_cat_id)
{
$norad_cat_data = DB::table('satellites')->where('norad_cat_id', $norad_cat_id)->get();
if (!is_null($norad_cat_id)
{
return view('pages/satellite');
}
\App::abort(404);
}

Related

How to treat 'No query results for model' in Laravel

We have a DB with 100 users.. for example
And here is the route
Route::get('/users/{user}/edit', 'UserController#edit');
Here is the method
public function edit(User $user)
{
$hi = 'Hello';
return $hi;
}
Ok.. if I do something like this
http://localhost/users/99/edit | WORKS
http://localhost/users/100/edit | WORKS
http://localhost/users/101/edit | PROBLEM
How to solve when the user change the value from URL with an inexistent record..?
In this case I would pass the user id as a parameter rather than explicit binding:
Route::get('/users/{userId}/edit', 'UserController#edit');
When a model is not found you will get a ModelNotFoundException exception thrown, you can catch it and treat this case
Controller:
use Illuminate/Database/Eloquent/ModelNotFoundException;
[...]
public function edit($userId)
{
try{
$user = User::find($userId);
//do some stuff
} catch (ModelNotFoundException $e){
//treat error (log the activity, redirect to a certain page)
//or display a 404 page
//dealer's choice
}
}
In your case the user can't be found, which is a 404:
public function edit(User $user)
{
$user = false; // dummy/example
if ($user) {
return $your_results;
} else {
return view('errors.404');
// assuming you have a folder called 'errors' inside your 'views' folder
// and the file name is `404.blade.php`
// and are using blade files.
}
}
If the user can be found, show whatever you need to, else, show a 404 blade view.
A little late, but it is an useful question.
To suppress the error message you can set the debug mode in the (dot)ENV file to false APP_DEBUG=true. Due to the route model binding, the other solutions above won't help you, because if the model is not found, you won't get into the controller. Unless you don't get the model but only the id or slug etc. and then make a query against the database within the function.

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

laravel 4.1 validate url input

Okay after get almost every thing work in my code
and its pretty Good
i need help about how to validate the user url Input
and if he did insert a non Url how to foreword it to 404 page
and here is my Route file
Route::get('/', function()
{
return View::make('hello');
});
Route::post('/', function()
{
$url = Input::get('url');
$record = Url::where('urls', '=', $url)->first();
if ($record) {
return View::make('result')
->with('shortend', $record->shortend);
}
function get_uniqe_short_url()
{
$shortend = base_convert(rand(1000,99999), 10, 36);
if (Url::where('shortend', '=' ,$shortend)->first() ){
get_uniqe_short_url();
}
return $shortend;
}
$shortend = get_uniqe_short_url();
// otherwise add new row and return shortned url
$row = new URl;
$row->urls = $url;
$row->shortend = $shortend;
$row->save();
// create a results view and present the short url to the usr
if ($row){
return View::make('result')->with('shortend',$shortend);
}
});
Route::get('{shortend}', function($shortend)
{
// query the DB For the row with that short url
$row = Url::where('shortend', '=', $shortend)->first();
// if not found redirect to home page
if (is_null($row) ) return Redirect::to('/');
// else grab the url and redirect
return Redirect::to($row->urls);
});
forgive me for my many questions but i am totally new to laravel
First, as a tip, you have logic like this in your routes.php. A URL router is meant to take HTTP requests and "route" them to the correct controllers and methods. See the documentation to get started with controllers.
I am never a fan of "redirecting to a 404 page", instead I believe if a page isn't found it should display a 404 page there. To do this with laravel, you can call App::abort(404); which will kill the application and return a 404 status to the browser. You can take this a step further by "listening" to 404 errors and returning your own custom view:
App::missing(function()
{
return View::make('errors/404');
});
Let me know if you need more help validating a URL, but I think you should start by restructuring your code by using controllers. You can check this question for regular expressions to match URLs. This is how you would use a regular expression in PHP:
if(!preg_match('/expression/', $url)) {
App::abort(404);
}

How to detect missing parameter route and show relevant message

Working on Laravel 4, I created following route and able to fetch ID:
Route::get('details/{ID}', 'Exchange#details');
Issue is when I miss ID in route then it shows: NotFoundHttpException error. I want to avoid this. How do I proceed? Even in global.php I added following but did not work:
App::missing(function($exception)
{
print "Not Found";
// return Response::make(
// View::make('errors/404')
// , 404);
});
Controller Method
public function details($exchangeID)
{
echo "Print Details";
echo $exchangeID;
if(intval($exchangeID) == 0)
{
throw new NotFoundException;
}
}
Update: Recommendation of redirecting to 404 works but I am more interested to detect missing ID and load my Own View with proper message information instead of showing plain 404 page.
I would try something like this
# file routes.php
Route::get('{ID?}', 'SomeController#getDetails')
# file SomeController.php
function getDetails($ID=null) {
if empty($ID) {
return Redirect::to('PREVIOUS PAGE')
->withInput()
->with('error', 'invalid value');
}
}
Try like this :
App::missing(function($exception)
{
return View::make('errors.404');
});
The view is located in views/errors/404.blade.php

SEO url gives 404-error in CodeIgniter

I am pretty new to codeigniter. I do know php.
How can I accomplish to load the right view?
My url: /blog/this-is-my-title
I’ve told the controller something like
if end($this->uri->segment_array()) does exist in DB then load this data into some view.
I am getting an 404-error everytime I access /blog/whatever
What am i seeing wrong?
unless you're using routing, the url /blog/this-is-my-title will always 404 because CI is looking for a method called this-is-my-title, which of course doesn't exist.
A quick fix is to put your post display code in to another function and edit the URLs to access posts from say: /blog/view/the-post-title
A route like:
$route['blog/(:any)'] = "blog/view/$1";
may also achieve what you want, if you want the URI to stay as just `/blog/this-is-my-title'
The may be more possibilities:
The most common - mod_rewrite is not active
.htaccess is not configured correctly (if u didn't edited it try /blog/index.php/whatever)
The controller does not exist or is placed in the wrong folder
Suggestion: if you only need to change data use another view in the same controller
if (something)
{
$this->load->view('whatever');
}
else
{
$this->load->view('somethingelse');
}
If none of those works post a sample of code and configuration of .htaccess and I'll take a look.
The best way to solve this problem is to remap the controller. That way, you can still use the same controller to do other things too.
No routing required!
enter code here
<?php
class Blog extends Controller {
function __construct()
{
parent::__construct();
}
public function _remap($method, $params = array())
{
if (method_exists($this, $method))
{
$this->$method();
}
else
{
$this->show_post();
}
}
function index()
{
// show blog front page
echo 'blog';
}
function edit()
{
// edit blog entry
}
function category()
{
// list entries for this category
}
function show_post()
{
$url_title = $this->uri->segment(2);
// get the post by the url_title
if(NO RESULTS)
{
show_404();
}
else
{
// show post
}
}
}
?>

Categories