Route with non-English characters doesn't work with Laravel Collective - laravel

I'm trying to use routes with non-English characters (Russian cyrillic) and these routes work just fine:
Route::resource('франшизы/подкатегории', 'Franch\SubCategoryController');
However when I'm trying to use same route with Form:: construction and sending the form, I get a NotFoundHttpException in RouteCollection.php line 161 exception:
// generates: http://localhost:8000/франшизы/подкатегории/20/edit?
{!! Form::open(array('method' => 'Get', 'route' => array('франшизы.подкатегории.edit', $subCategory->id))) !!}
I've copy-pasted code and added new route and Form:: with English only characters which works just fine:
// generates: http://localhost:8000/franch/sub/20/edit?
{!! Form::open(array('method' => 'Get', 'route' => array('franch.sub.edit', $subCategory->id))) !!}
Route::resource('franch/sub', 'Franch\SubCategoryController');
My question is how can I make non-English routes work? If it's impossible, what alternatives are there?

I've asked this questions at four forums, but noone was able to help me with it. I still do not know the best solution to the issue, but I have done this:
Route::get('франшизы/подкатегории', 'Franch\SubCategoryController#index')->name('franch_sub_categories_index');
Route::resource('franchises/subcategories', 'Franch\SubCategoryController', ['except' => ['index']]);
And it works just fine.
I'm using URL with utf-8 characters in the first route for the simple
#index requests which is important for SEO and URL readability.
The
second route handles all RESTful requries.
Hope it'll be helpful for some of you.

Related

GET (405) method not allowed [duplicate]

Im trying to do a POST request with jQuery but im getting a error 405 (Method Not Allowed), Im working with Laravel 5
THis is my code:
jQuery
<script type="text/javascript">
$(document).ready(function () {
$('.delete').click(function (e){
e.preventDefault();
var row = $(this).parents('tr');
var id = row.data('id');
var form = $('#formDelete');
var url = form.attr('action').replace(':USER_ID', id);
var data = form.serialize();
$.post(url, data, function (result){
alert(result);
});
});
});
</script>
HTML
{!! Form::open(['route' => ['companiesDelete', ':USER_ID'], 'method' =>'DELETE', 'id' => 'formDelete']) !!}
{!!Form::close() !!}
Controller
public function delete($id, \Request $request){
return $id;
}
The Jquery error is http://localhost/laravel5.1/public/empresas/eliminar/5 405 (Method Not Allowed).
The url value is
http://localhost/laravel5.1/public/empresas/eliminar/5
and the data value is
_method=DELETE&_token=pCETpf1jDT1rY615o62W0UK7hs3UnTNm1t0vmIRZ.
If i change to $.get request it works fine, but i want to do a post request.
Anyone could help me?
Thanks.
EDIT!!
Route
Route::post('empresas/eliminar/{id}', ['as' => 'companiesDelete', 'uses' => 'CompaniesController#delete']);
The methodNotAllowed exception indicates that a route doesn't exist for the HTTP method you are requesting.
Your form is set up to make a DELETE request, so your route needs to use Route::delete() to receive this.
Route::delete('empresas/eliminar/{id}', [
'as' => 'companiesDelete',
'uses' => 'CompaniesController#delete'
]);
Your routes.php file needs to be setup correctly.
What I am assuming your current setup is like:
Route::post('/empresas/eliminar/{id}','CompanyController#companiesDelete');
or something. Define a route for the delete method instead.
Route::delete('/empresas/eliminar/{id}','CompanyController#companiesDelete');
Now if you are using a Route resource, the default route name to be used for the 'DELETE' method is .destroy. Define your delete logic in that function instead.
In my case the route in my router was:
Route::post('/new-order', 'Api\OrderController#initiateOrder')->name('newOrder');
and from the client app I was posting the request to:
https://my-domain/api/new-order/
So, because of the trailing slash I got a 405. Hope it helps someone
If you didn't have such an error during development and it props up only in production try
php artisan route:list to see if the route exists.
If it doesn't try
php artisan route:clear to clear your cache.
That worked for me.
This might help someone so I'll put my inputs here as well.
I've encountered the same (or similar) problem. Apparently, the problem was the POST request was blocked by Modsec by the following rules: 350147, 340147, 340148, 350148
After blocking the request, I was redirected to the same endpoint but as a GET request of course and thus the 405.
I whitelisted those rules and voila, the 405 error was gone.
Hope this helps someone.
If you're using the resource routes, then in the HTML body of the form, you can use method_field helper like this:
<form>
{{ csrf_field() }}
{{ method_field('PUT') }}
<!-- ... -->
</form>
It will create hidden form input with method type, that is correctly interpereted by Laravel 5.5+.
Since Laravel 5.6 you can use following Blade directives in the templates:
<form>
#method('put')
#csrf
<!-- ... -->
</form>
Hope this might help someone in the future.
When use method delete in form then must have to set route delete
Route::delete("empresas/eliminar/{id}", "CompaniesController#delete");
I solved that issue by running php artisan route:cache which cleared the cache and it's start working.
For Laravel 7 +, just in case you run into this, you should check if the route exists using
php artisan route:list
if it exists then you need to cache your routes
php artisan route:cache

laravel route::post wrong method gets called

Starting off with a bit of background information, i have 3 models - Course, Pathway, Module.
Course HAS-MANY Pathway
Pathway HAS-MANY Module
Course HAS-MANY-THROUGH Module (through Pathway)
I have set up routes for creating Course, Pathway and Module. However, when I try to save the newly created model instance, it calls the wrong route method - does not even hit the store method of the relevant Controller
I understand that the order of the routes is important. I tried changing them around but it still does not work as intended.
Here's what I have so far
:
// modules
Route::get('/courses/{course}/edit/pathways/{pathway}/modules/create', [App\Http\Controllers\ModulesController::class, 'create'])->name('createModule');
Route::post('/courses/{course}/edit/pathways/{pathway}/modules', [App\Http\Controllers\ModulesController::class, 'store'])->name('storeModule');
// Pathways
Route::get('/courses/{course}/edit/pathways/create', [App\Http\Controllers\PathwaysController::class, 'create'])->name('createPathway');
Route::get('/courses/{course}/pathways/{pathway}/edit', [App\Http\Controllers\PathwaysController::class, 'edit'])->name('editPathway');
Route::delete('/courses/{course}/pathways/{pathway}', [App\Http\Controllers\PathwayController::class, 'destroy'])->name('destroyPathway');
Route::post('/courses/{course}/edit/pathways', [App\Http\Controllers\PathwaysController::class, 'store'])->name('storePathway');
// VQs/Qualifications
Route::resource('courses', App\Http\Controllers\CourseController::class, [
'names' => [
'index' => 'allCourses',
'create' => 'createCourse',
'store' => 'storeCourse',
'show' => 'showCourse',
'edit' => 'editCourse',
'update' => 'updateCourse',
'destroy' => 'destroyCourse',
]
]);
The problem is that when I try to store a Pathway or Module, it hits the Route::post('/courses/{course}') route.
I tried changing around the order of the routes, but none of that worked. I've also made sure that the create forms action is of the right Url Route. its all still the same.
I also can't tell which controller method is being called. Tried doing a dd() on CourseController#create, PathwaysController#create, ModulesController#create but none of them get hit.
Any help as to why this is happening will be greetly appreciated
Edit
here are some of my routes:
Since your URLs are quite similar.
How about refactoring your URL.
Also, writing a cleaner code would save you lots of headaches.
At the top:
<?php
use App\Http\Controllers\ModulesController;
use App\Http\Controllers\PathwaysController;
Route::name('modules.')->prefix('modules/courses')->group(function()
Route::get(
'{course}/edit/pathways/{pathway}/create', //e.g: modules/courses/engligh/edit/pathways/languages/create
[ModulesController::class, 'create']
)->name('create'); //modules.create
Route::post(
'{course}/edit/pathways/{pathway}',
[App\Http\Controllers\ModulesController::class, 'store']
)->name('store'); //modules.store
});
Route::name('courses.')->prefix('courses')->group(function()
Route::get(
'{course}/edit/pathways/create', //e.g: courses/english/edit/pathways/create
[PathwaysController::class, 'create']
)->name('create'); //courses.create
Route::get(
'{course}/pathways/{pathway}/edit',
[App\Http\Controllers\PathwaysController::class, 'edit']
)->name('edit');//courses.edit
Route::delete(
'{course}/pathways/{pathway}',
[App\Http\Controllers\PathwayController::class, 'destroy']
)->name('destroy');//courses.destroy
Route::post(
'{course}/edit/pathways',
[App\Http\Controllers\PathwaysController::class, 'store']
)->name('store');//courses.store
});
Run php artisan route:list to view your routes
Fixed it. Turns out there wasn't a problem with my routes at all.
The problem was that I had vertical navs and tab-panes on that page, and most of them had a form in them. I had not closed the form in one of the tab-panes and so this form was getting submitted to the action of the form above in that page.
i.e. Make sure to close forms using:
{{ Form::close() }}

Laravel href redirection

So I've started using Laravel and I found it very easy and now I'm creating my own restful services. My problem is I don't know if I am doing the href link correct, but yes it is working. Here is the code:
Add user
And in my controller I just render the blade:
public function create()
{
return view('accounts.create');
}
So if I click the link Add user, it will redirect me to localhost:8080/accounts/create which is working well. My question is, is there a better way of doing this? Like if ever I changed any in my routes file, I will not change anymore the href link?
Ideally, you will name the route in your routes file.
Something like,
Route::get('accounts/create', [as => 'createAccount', 'uses' => 'AccountsController#create']);
You will use it as follows
Add user
in your view.
This way, even if you change the url (accounts/create), or the action name (create), you will not have to change it in the view. Allows your view to be independent.
What you can do is give your route a name using the as key in the array in the second argument of your route:
Route::get('accounts/create', [
'as' => 'accounts.create',
'uses' => 'AccountController#create'
]);
Then you can refer to this route in your application by it's name and it'll go to the same place even if you happen to change the URL. For an anchor tag you can do the following:
{{ URL::route('accounts.create') }}
If you're using a resource controller there will be predefined routes which you can see here under Actions Handled By Resource Controller: http://laravel.com/docs/5.1/controllers#restful-resource-controllers
You can always get a quick overview of your available routes and their names by running php artisan route:list
http://laravel.com/docs/4.2/routing#named-routes
Example:
Route::get('accounts/create', array('as' => 'signup', 'uses' => 'UserController#create'));
Add user
This route is named as "signup" and you can change the url anytime as:
Route::get('accounts/signup', array('as' => 'signup', 'uses' => 'UserController#create'));
Yes, you can use the action() helper to call a method inside a controller and generate the route to it automatically on demand.
So let's consider you have a controller called FrontendController.php and a method called showFrontend( $section), and assuming that you have a route that matches this controller and method (let's say "frontend/show/{$section}", you can call:
action('FrontendController#showFrontend', array( 'index' ) )
That will return:
frontend/show/index
So basically it looks for the route associated to that method/controller. You can combine this with other helpers to create a whole URL.
NOTE: Consider the namespaces, in case that you have different folder for controllers, nested resources, etc.
I hope it helps!

Laravel 5 multiple paginations on one page

I'm trying to have 2 paginations on a single page.
View:
{{!! $items->appends(['page2' => Request::input('page2', 1)])->render() !!}}
But it is not working, as using custom $pageName for pagination ($items->setPageName('custom_page_parameter')) links are not working in laravel 5.
https://stackoverflow.com/questions/29035006/laravel-5-pagination-wont-move-through-pages-with-custom-page-name
Here is how I did it in laravel 4:
Laravel Multiple Pagination in one page
What is Laravel 5 way of doing this?
I've spent far too much time trying to find out how to do this, so thought I'd share my findings in case there is another poor soul like me out there. This works in 5.1...
In controller:
$newEvents = Events::where('event_date', '>=', Carbon::now()->startOfDay())
->orderBy('event_date')
->paginate(15,['*'], 'newEvents');
$oldEvents = Events::where('event_date', '<', Carbon::now()->startOfDay())
->orderBy('event_date', 'desc')
->paginate(15,['*'], 'oldEvents');
Then continue as usual in the view: `
// some code to display $newEvents
{!! $newEvents->render() !!}
// some code to display $oldEvents
{!! $oldEvents->render() !!}
Now, what this doesn't do is remember the page of $oldEvents when paging through $newEvents. Any idea on this?
References:
pull request addressing the original issue
API docs for method
$published = Article::paginate(10, ['*'], 'pubArticles');
$unpublished = Article::paginate(10, ['*'], 'unpubArticles');
The third argument for paginate() method is used in the URI as follows:
laravel/public/articles?pubArticles=3
laravel/public/articles?unpubArticles=1
In Controller:
$produk = Produk::paginate(5, ['*'], 'produk');
$region = Region::paginate(5, ['*'], 'region');
in view:
{{$produk->appends(['region' => $region->currentPage()])->links()}}
{{$region->appends(['produk' => $produk->currentPage()])->links()}}
reference to :[Laravel 5] Multi Paginate in Single Page
Try using the \Paginator::setPageName('foo'); function befor buidling your paginator object:
\Paginator::setPageName('foo');
$models = Model::paginate(1);
return view('view_foo', compact('models'));
This question might help too: Laravel 5 pagination, won't move through pages with custom page name
Also note there is a bug atm: https://github.com/laravel/framework/issues/8000

Intercepting pretty URLs in Laravel4

I am trying to implement a talking url scheme in laravel4 for SEO purposes.
What I have in my routes.php is this:
Route::get('{url}', array('as' => 'prettyurl', function($url) .........
which works for URLs such as
mywebsite.com/this-is-my-fancy-url-about-foo
mywebsite.com/bars
but doesn't for those such as
mywebsite.com/bars/this-is-my-fancy-url-about-foo
it seems that laravel splits the URL according to / before parring it to individual routes.
I could do something like
Route::get('{prefix}/{url?}', array('as' => 'prettyurl', function($prefix, $url) .........
but it seems a little contrived.
Any ideas?
You can use regular expressions to make it catch everything (including the slashes).
Route::get('{url}', ['as' => 'prettyurl', function($url)
{
})->where('url', '.*');

Resources