Yii pattern match for URL - php

I need to handle a SEO-friendly URL in my Yii application. My URL structures in the pattern: "domain.com/url-string/uniqueid". For example:
domain.com/properties-in-dubai/325fgd
domain.com/properties-in-USA/4577ds6
domain.com/properties-in-india/567dew
domain.com/apartments-in-anderi-mumbai/645fki
The above URL strings and ID are populated by us. When the user access this URL:
first need to validate the URL pattern.
second extract the I'd and URL string and match with my data store.
third when above URL and I'd exist in our data store pass a referenced parameters to existing search page.
Kindly, anyone help me solve this issue and give sleep to me.

First, you add a new rule to your urlManager application configuration.
'rules' => array(
'<slug>/<id:\d+>' => 'property/view'
// ...
)
Then you can retrieve the slug and ID in the action:
class PropertyController extends CController
{
public function actionView($slug, $id)
{
$id = (int) $id;
// Check if $id, $slug exist; replace line below
$exists = true;
if($exists){
// Redirect to elsewhere
$this->redirect();
}
}
}

Related

Laravel route url with query string

On laravel 4 I could generate a url with query strings using the route() helper. But on 4.1 instead of:
$url = url('admin.events', array('lang' => 'en'));
// admineventsurl/?lang=en
I get:
$url = url('admin.events', array('lang' => 'en'));
// admineventsurl/en
I did some research and all laravel methods to generate url are using the parameters like that. How can I generate the url with query strings?
Laravel's route() and action() helper methods support URL query params. The url() helper method, unfortunately does not.
Simply provide an array with key => value pairs to the route parameters. For example:
route('products.index', ['manufacturer' => 'Samsung']);
// Returns 'http://localhost/products?manufacturer=Samsung'
You can also still include your route parameters (such as ID's and models) to accompany these parameters:
route('products.show', [$product->id, 'model' => 'T9X']);
// Returns 'http://localhost/products/1?model=T9X'
Basically, any elements in the array that contain string keys will be treated as query parameter (/products?param=value). Anything with an integer array key will be treated as a URL argument (/products/{arg}).
This is also supported in action methods:
action('ProductController#index', ['manufacturer' => 'Samsung']);
You can also supply query parameters inside the link_to_route() and link_to_action() methods:
link_to_route('products.index', 'Products by Samsung', ['model' => 'Samsung');
link_to_action('ProductController#index', 'Products by Samsung', ['model' => 'Samsung']);
2019 - EDIT:
If you can't use route() or action(), you can generate a URL with query params using the Arr::query() helper:
url('/products?').\Illuminate\Support\Arr::query(['manufacturer' => 'Samsung']);
// Returns 'http://localhost/products?manufacturer=Samsung'
Or:
url('/products?').http_build_query(['manufacturer' => 'Samsung'], null, '&', PHP_QUERY_RFC3986);
// Returns 'http://localhost/products?manufacturer=Samsung'
Or create a simple helper function:
use Illuminate\Support\Arr;
use Illuminate\Support\Str;
function url_query($to, array $params = [], array $additional = []) {
return Str::finish(url($to, $additional), '?') . Arr::query($params);
}
Then call it:
url_query('products', ['manufacturer' => 'Samsung']);
// Returns 'http://localhost/products?manufacturer=Samsung'
url_query('products', ['manufacturer' => 'Samsung'], [$product->id]);
// Returns 'http://localhost/products/1?manufacturer=Samsung'
Side note.
I disagree with #Steve Bauman's idea (in his answer) that one rarely needs querystring urls, and think that Laravel should at least consider adding querystring functionality (back) in. There are plenty of cases when you want a querystring url rather than a param based "pretty url". For example, a complex search filter...
example.com/search/red/large/rabid/female/bunny
...may potentially refer to the same exact set of rodents as...
example.com/search/bunny/rabid/large/female/red
...but any way you look at it (programming, marketing analytics, SEO, user-friendliness), it's kinda terrible. Even though...
example.com/search?critter=bunny&gender=female&temperament=rabid&size=large&color=red
...is longer and "uglier", it actually is better in this not-so-rare case. Net: Friendly URLs are great for some things, querystrings are great for others.
Answer to the original question...
I needed a "querystring" version of url() -- so I copied the function, modified it, and stuck it in /app/start/global.php:
/**
* Generate a querystring url for the application.
*
* Assumes that you want a URL with a querystring rather than route params
* (which is what the default url() helper does)
*
* #param string $path
* #param mixed $qs
* #param bool $secure
* #return string
*/
function qs_url($path = null, $qs = array(), $secure = null)
{
$url = app('url')->to($path, $secure);
if (count($qs)){
foreach($qs as $key => $value){
$qs[$key] = sprintf('%s=%s',$key, urlencode($value));
}
$url = sprintf('%s?%s', $url, implode('&', $qs));
}
return $url;
}
Example:
$url = qs_url('sign-in', array('email'=>$user->email));
//http://example.loc/sign-in?email=chris%40foobar.com
Note: It appears that the url() function is pluggable, that is, you can replace it. Look in vendor/laravel/framework/src/Illuminate/Support/helpers.php: the url function is wrapped in a if ( ! function_exists('url')) conditional. But you would probably have to jump through hoops to do it (i.e. have laravel load it before its version.)
Cheers,
Chris
The following was what I needed to do:
I handle all of my routing in a service provider, where I had defined the following function:
private function registerRestfulController($prefix, $controllerClass)
{
Route::controller($prefix, $controllerClass, $controllerClass::getRouteNames());
}
getRouteNames is a static method on my BaseController that conventionally returns routes so that RESTful controllers can have automatic named routes.
The problem I was running into was that this defined the set of wildcard matchers on the route itself - in order to avoid that, I add the following to the private function above:
foreach ($controllerClass::getRoutesNames() as $name) {
$route = Route::getRoutes()->getByName($name);
$cleanUri = preg_replace('/\/\{\w*\?\}/', '', $route->getUri());
$route->setUri($cleanUri);
}
This loads all the routes you are registering at the time and immediately removes wildcards from the URI. You could easily pass a boolean or "white-list" of route names that you want to preserve wildcards for, so that it doesn't stomp all over the Laravel default without the intention. Once you run this, it automatically starts working with query string variables, which I find far preferable to path variables in this instance.
A simple way to do this, specially to use with jQuery Autocomplete, it's modify the Controller with a condition to check if has 'term' in the $request:
(Controller file)
public function list_for_autocomplete(Request $request)
{
if ($request->has('term')) {
return YourModel::select('column_name as value')
->where('column_name', 'like', '%' . $request->input('term') . '%')
->get()
}
}

How to remove action part in zend framework URLs

I`m using zend framework and my urls are like this :
http://target.net/reward/index/year/2012/month/11
the url shows that I'm in reward controller and in index action.The rest is my parameters.The problem is that I'm using index action in whole program and I want to remove that part from URL to make it sth like this :
http://target.net/reward/year/2012/month/11
But the year part is mistaken with action part.Is there any way ?!!!
Thanks in advance
Have a look at routes. With routes, you can redirect any URL-format to the controller/action you specify. For example, in a .ini config file, this will do what you want:
routes.myroute.route = "reward/year/:myyear/month/:mymonth"
routes.myroute.defaults.controller = reward
routes.myroute.defaults.action = index
routes.myroute.defaults.myyear = 2012
routes.myroute.defaults.mymonth = 11
routes.myroute.reqs.myyear = "\d+"
routes.myroute.reqs.mymonth = "\d+"
First you define the format the URL should match. Words starting with a colon : are variables. After that you define the defaults and any requirements on the parameters.
you can use controller_plugin to control url .
as you want create a plugin file (/library/plugins/controllers/myplugin.php).
then with preDispatch() method you can get requested url elements and then customize that for your controllers .
myplugin.php
class plugins_controllers_pages extends Zend_Controller_Plugin_Abstract
{
public function preDispatch(Zend_Controller_Request_Abstract $request)
{
$int = 0;
$params = $this->getRequest()->getParams();
if($params['action'] != 'index' ) AND !$int)
{
$int++;
$request->setControllerName($params['controller']);
$request->setActionName('index');
$request->setParams(array('parameter' => $params['action']));
$this->postDispatch($request);
}
}
}

in codeigniter how can i get uri segments by name?

I have the latest codeigniter version, and was wondering how can i get the segments in a url by their parameter name. For instance, here is a sample url:
www.somewebsitedomain.com/param1=something/param2=somethingelse/
now lets say i want to get the value for 'param1', which is 'something', how would i do so using the uri class?
Because by default the uri class only gets segments by number, or the order in which they appear, but i want to get segments by the parameter name in that segment. Or in general just get the parameter value. Hope that makes sense...
You could do $this->uri->uri_to_assoc(n) which will give something like the following
[array]
(
'name' => 'joe'
'location' => 'UK'
'gender' => 'male'
)
Then just just the param name you would like.
Source: http://codeigniter.com/user_guide/libraries/uri.html
You could actually put them as GET vars and use the Input Class:
$param = $this->input->get('param1'); // something
or you can do:
$params = $this->input->get(); // array('param1' => 'something', 'param2' => 'somethingelse')
to get all the parameters
I'm not sure this is what you're asking, but in many applications, URLs follow the form www.domain.com/controller/method/key1/value1/key2/value2. So I decided to extend the CI_URI class to return the value of any "key".
If you put this in your application/core folder, in a file named, MY_URI.php, it extends the built-in URI class:
class MY_URI extends CI_URI {
/* call parent constructor */
function __construct() {
parent::__construct();
}
/* return value of the URI segment
which immediately follows the named segment */
function getNamed($str=NULL) {
$key = array_search($str, $this->segments);
if ($key && isset($this->segments[$key+1])) {
return $this->segments[$key+1];
}
return false;
}
}
Then if your URLs are in the form
www.somewebsitedomain.com/param1/something/param2/somethingelse/
you can call this function as follows:
$this->uri->getNamed('param1) - returns "something"
$this->uri->getNamed('param2) - returns "somethingelse"

How to createe a URL string based on a named route and keep parameters

I need to create urls for category switching, switching category should reset page to 1st and change cat name but keep rest of url params.
Example of url:
http://example.com/cat/fruits/page/3/q/testquery/s/date/t/kcal/mine/26/maxe/844/minb/9/mint/4/maxt/93/minw/7/minbl/6/maxbl/96
Urls can contain many different params but category name and page should be always first, category without page should work too and show 1st page.
Currently I have defined two routes and I'm using Zend's url helper with named route but it resets params and as end resuls I have /cat/cat_name/page/1 url.
$category_url = $view->url(array('category'=>$list_item['url'],'page'=>1),'category',FALSE)
resources.router.routes.category_main.route = "/cat/:category/*"
resources.router.routes.category_main.defaults.module = "ilewazy"
resources.router.routes.category_main.defaults.controller = "index"
resources.router.routes.category_main.defaults.action = "results"
resources.router.routes.category_main.defaults.category =
resources.router.routes.category_main.defaults.page = 1
resources.router.routes.category.route = "/cat/:category/page/:page/*"
resources.router.routes.category.defaults.module = "ilewazy"
resources.router.routes.category.defaults.controller = "index"
resources.router.routes.category.defaults.action = "results"
resources.router.routes.category.defaults.category =
resources.router.routes.category.defaults.page = 1
Do I need to create custom method for assembling url in this case?
Things I would try:
Add module, controller and action params in $urlOptions (it's the
first array you pass to the view helper)
instead of 'category' route name try null and see what that does for
you.
Try removing this line
"resources.router.routes.category.defaults.category = "
Please specify what version are of zf are you using.
Solution is very simple, one just have to pass all current request params to url helper
(and optionaly overwrite/add some of them, page and category in my case), last variable is set to FALSE to prevent route resetting.
$view->url(
array_merge(
$params,
array('category' => $list_item['url'],
'page' => 1)
),
'category_main',
FALSE
);

Site search with CodeIgniter?

I need to make a simple site search with pagination in it; could anyone tell me how to do it without affecting the URL structure? Currently I'm using the default CodeIgniter URL structure and I have removed index.php from it. Any suggestions?
You could just use a url like /search/search_term/page_number.
Set your route like this:
$route['search/:any'] = "search/index";
And your controller like this:
function index()
{
$search_term = $this->uri->rsegment(3);
$page = ( ! $this->uri->rsegment(4)) ? 1 : $this->uri->rsegment(4);
// some VALIDATION and then do your search
}
Just to update this question. It is probably best to use the following function:
$uri = $this->uri->uri_to_assoc()
and the result will then put everything into an associative array like so:
[array]
(
'name' => 'joe'
'location' => 'UK'
'gender' => 'male'
)
Read more about the URI Class at CodeIgniter.com
Don't quite understand what you mean by "affecting the url structure". Do you mean you'd want pagination to occur without the URL changing at all?
The standard pagination class in CI would allow you to setup pagination so that the only change in the URL would be a number on the end
e.g if you had 5 results to a page your urls might be
http://www.example.com/searchresults
and then page 2 would be
http://www.example.com/searchresults/5
and page 3 would be
http://www.example.com/searchresults/10
and so on.
If you wanted to do it without any change to the URL then use ajax I guess.
Code Igniter disables GET queries by default, but you can build an alternative if you want the url to show the search string.
Your url can be in the notation
www.yoursite.com/index.php/class/function/request1:value1/request2:value2
$request = getRequests();
echo $request['request1'];
echo $request['request2'];
function getRequests()
{
//get the default object
$CI =& get_instance();
//declare an array of request and add add basic page info
$requestArray = array();
$requests = $CI->uri->segment_array();
foreach ($requests as $request)
{
$pos = strrpos($request, ':');
if($pos >0)
{
list($key,$value)=explode(':', $request);
if(!empty($value) || $value='') $requestArray[$key]=$value;
}
}
return $requestArray ;
}
source: http://codeigniter.com/wiki/alternative_to_GET/

Categories