Laravel dynamic rerouting - php

Hey guys i have a little problem i need to solve and i cant seem to find a way to do so.
I have an app that need to use different databases dynamically according to which user uses it. I thought that i would give each user an URL that contains hes unique alphanumeric id. So the URL would be something like ww.mydomain.com/app/1kh1h3as/
So i have 2 problems:
where should i put the database switch code. Is it better of in config file or should i use it in model classes so i have use of URI class to parse out the id?
how can i make the router understand that it needs to offset all the calls by one segment so it wont go looking for 1kh1h3as controller and ww.mydomain.com/app/1kh1h3as/users/all will launch all() method within Users controller?

Use this
DB::connection('mysql')->config['database']='your_user_database_name';
Try
Route::any('app/1kh1h3as/(:bundle)', function() {
return 'Welcome to the Admin bundle!';
});

Related

Defining Laravel routes when certain query strings are present

Say I want to be able to submit a search form on any page that will append a ?s= to the current url but return a SERP: https://example.com/my-page?s=foobar. (I've seen a few sites do this instead of pointing to /search?s=.* - not the way I'd do it, but it illustrates my question.)
In my Laravel web.php routes, is there currently a way to register this other than maybe using a wonky regex?
<?php
Route::get('.+?\?.+?\bs={search}', 'SearchController#search');
// This regex is probably wrong, but you get what I was going for,
// and that kinda highlights why this is not an ideal way to do it
?>
This gets uglier when, say, you want to capture multiple $_GET params:
https://example.com/my-page?s=foobar&dept=clothing
I haven't found anything in Laravel docs that let you define query string options on the Route $uri parameter. The recommended option is to just use pretty URLs (https://example.com/search/foobar), but there are definitely valid use cases for keeping query strings.
1: Create a middleware (https://laravel.com/docs/5.7/middleware)
2: Validate incoming request using $request->query('s')
3: If validation successfull return to next else redirect to wherever or display an error response
That is very simple that depends on the parts of a url. The Route class uses the "path string" of the url and you try to use the "parameters" of the url.
https://doepud.co.uk/blog/anatomy-of-a-url
In modern websites you should work with that structure because you get a better URL structure and it's much better for SEO and search engines.
You should use the parameters only in the function you call for small things which you can call over the $request->get('s'); method but then you have to redirect or you have to work in that function.
So don't fight the framework and work in that structure what is defined from the framework that all people who know the framework know how to work with it.

Creating the Post-Redirect-Get pattern with Laravel

I have been used laravel, and I find it's by far the best PHP Framework there is. But even so, I still think that to be able to understand it and PHP MVC's in general, I need to make my own first.
So, as of now, I'm in the process of making my own MVC, I got most things covered. But I wanted to add a feature that is identical to Laravel, which is the Post-Redirect-Get feature, (or so I think).
What I mean is, for those unaware, that if a person visits a link, say localhost/project/laravel/public/profile using the Route::get('localhost/project/laravel/public/profile', 'SomeController#action) He will only be able to view the profile page, from the action() function in SomeController. But when he uses the Route::post('localhost/project/laravel/public/profile', 'SomeController#action2), only when does is the POST request sent from the localhost/project/laravel/public/profile URL, will the action2() function activate.
So, My question is,
How can I make my own Route::get() and Route::post() to work like in laravel
If you want have get and post in the same route you should try this methods
POST and GET in the same pattern

Avoiding duplicate code in two controllers in Laravel 5.1

I have a route in Laravel 5.1 that will accept a generic permalink and will need to determine what object it belongs to (for example is it a permalink for a "Blog" or a "Story"?).
The route looks like this:
// .... Every other route in the routes.php file //
Route::get('{generic_url}', 'CMSController#generic');
Then the code in the my controller looks like this:
public function generic($generic_url) {
$blog = Blog::where('permalink', $generic_url)->first();
if(!is_null($blog)) {
// Load a blog entry page
}
// Something basically the same as above but for Story
}
I also have this route in my routes.php file to view a blog post:
Route::get('/blog/{blog_id}', 'BlogController#view');
The purpose of that second route was for me rough in the view a blog post page as well as a quick way for me to debug a particular post.
I am hoping to avoid having to put view code in two separate controllers. My first thought was to try and find a way to have CMSController call the view action in the BlogController. It sounds like a terrible idea to me and some searching around confirms that it is a terrible idea.
My question is, what is the best way to handle this situation?
For the time being I decided to add a static method to my Blog model and place it in the controllers:
return Blog::RenderFrontendView($blog_id);
I know this seems a bit strange considering I have already loaded the model in one of the spots I am using this code, but in the context of what I am doing it makes sense. It looks in the cache to retrieve all the info and I intend to do further optimization to only load the ID instead of the entire model.
Update: I am no longer using this method as using a trait was a much better solution

Use cases for generated URLs in Symfony2?

Coming from a straight PHP and Drupal background, I am recently learning the Symfony2 framework. Currently I am in the routing chapter of the book. This is probably a simple question.
What are some real world use cases for why one would want to generate URLs in a Symfony app? I understand the code but I'm having a bit of trouble determining its practical applications.
I'm referring to this section should you need a refresher.
As always, thank you!
P.S. Symfony is amazing. :)
Basically, you need to generate a URL whenever you need to link to anywhere in your application.
Let's say that you have an application that needs to manage some users. This means that you will probably have URLs like /user/create, /user/edit/(user id) and /user/remove/(user id).
Whenever you display a link to edit a user you need to know on what URL you can find the page that allows you to edit a user. So you need to link to /user/edit/(user id). One solution would be to have this as a fixed link so that in your code you could just write
edit this user
But what if you want to change this URL scheme? Let's say someone is unhappy with the term "user", after all the humans managed by this system are not only users, they are actually "person"s! So now you need to change all the URLs containing "user". Probably there are quite a few places in your app where you have had to hardcode these URLs and now you will need to find and change all of them. Eugh.
But fear not, for Symfony routing comes to the rescue!
Instead of hardcoding these URLs, we can simply let the Symfony router generate them for us. This means that we first need to tell Symfony which routes we have, e.g. by adding the following YAML code to our routes config file:
user_edit:
path: /user/edit/{userId}
defaults: { _controller: AppBundle:User:edit }
requirements:
userId: \d+
This tells our application "Okay, whenever somebody requests a page that looks like /user/edit/{userId}, then you need to call the editAction method in our UserController class in the AppBundle namespace and you need to pass the userId as a parameter. Oh, and also you should only call the controller if userId is a valid integer with at least one number."
So this is how Symfony knows how to map URLs to controllers. But the goodness that comes along with it is that we can use this information for the reverse way as well.
Usually, in our application we do not really care about what the URL looks like for a certain action we want to perform. All we know is that when clicking a certain link, then the browser should jump to a page that allows me to edit a user. And since we just defined a route that takes us right there, we can have Symfony generate the correct URL to achieve just that.
So in your view you can now discard the hardcoded URL from earlier and instead replace it with a route generated by the Symfony router:
edit this user
Now whenever you need to change what the URL actually looks like all you need to do is edit your routing config and not a lot of separate views.
Because, imagine you want to change a given page URL and you've hardcoded it in 10 Twig templates. You will have to modify all these files. On the opposite, when using the routing component:
You would only have to change the URL where the route is defined.
The routing component "takes" care of the current environment you are using (dev, prod...)
Also note that is a bad practice to "switch environment", a typical issue is to hardcode an URL in a Javascript. In this case you can expose your Symfony2 routes in the Javascript by using a bundle like FOSJsRoutingBundle.
I almost immediately realized their use and now I feel silly. :) For those who stop by this question in the future:
Notes about Generating URLs:
Similar to the Drupal l() function, sometimes you need to generate links inside your application based on a variety of parameters.
You don't always want to hardcode your links in case you decide to change paths sometime down the line.
In summary: Think of this as an alternative to using straight anchor tags with href elements all over the app and, instead, keeping things dynamic.
Use case
In the project I'm working I use generateUrl to redirect the user
after creating, editing an entity.
For example after creating a Service entity, I redirect the user to the view
of the just created Service.
Controller
return $this->redirect($this->generateUrl('myentity_view', array('id'=> $id)));
Additional note
In twig files, you can use the path function which call the routing component and generate url with given route name and parameters.

Removing Controller name from URL in CodeIgniter

Currently in my CI project I have a single controller that handles all things account. Such-as register, login, activation, etc.
My routes work as such...
domain.com/account/login/ or domain.com/account/register/
How can I remove account from the route while also being about to remove the controller from other pages.
I basically want the controller to always be removed. One of my reasons for this is SEO, search engine rank the importunateness of a page based on how deep it is in a website.
The only way I have seem to achieve this is to do some thing like route['activate'] = 'account/activate'; for every single page, which would be a huge hassle.
$route['^(?!other|controllers).*'] = “account/$0″;
Try this :
$route['(:any)'] = "account/$1";
The answer to your question is that you DO have to explicitly set the routes.
How is it going to know which controller a given function is in????
You have to tell it.
use mod_rewrite (if the controller is always the same name)
Ok, I can think of one way to do this, but it is probably gonna be more of a pain than just writing out routes for each function.
You need to extend the Router.php with application/core/MY_Router.php and overide the _validate_request() method. Which basically decides if this this is a valid route or not.
it does a check to see if the controller class exists then fails if it doesn't exist.
You need to replace this with some code which assumes no controller segment, then scans thru each of your controllers and checks if it contains the method called (it will be segment 1, since theres no controller).
Now the tricky part, at this point in the CI lifecycle your controller obviously isnt loaded, so you cant examine it using method_exists() yet.
You need to load your controllers one at a time, and then for each one run
method_exists($loaded_class, $method_name)
and if its true, then set then go ahead and call:
$this->set_class('the_name_of_the_scanned_class_which_had_the_method');
Then CI can keep going on as normal and it will load your methods without the user ever know what controller it loaded from.
.. probably not worth the hassle imho. A much easier solution would be to just have one controller and one route to that controller.

Categories