Site search with CodeIgniter? - php

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/

Related

CakePHP redirect form post with querystring

I'm a Cake newbie, and I'm looking to post a querystring value into a controller method, but always reload the view with the querystring intact. Currently I have the below snippet.
public function something()
{
if($this->request->query !=null )
$date = $this->request->query["date"];
}
<?php echo $this->Form->create('setup',array('action' => 'something?date=2013','id'=>'setup-form','role'=>'form') ); ?>
Any advice on why something() doesn't redirect to something?date=2013 on its default render? Do I need to do some special routing?
In CakePHP 2, you can include query string parameters in $url parameters like so:
array('action' => 'something', '?' => array('date' => '2013'))
CakePHP will build the query string and append it to the matched URL in your routing configuration.
(Note: You may need to pass FormHelper::create an entire URL, generated from HtmlHelper::url, instead of using the "shorthand" technique.)

Using URL data in laravel views

struggling to figure out how to best do what I would normally in simple PHP.
I have the following URL:
/viewbuild/2
The aim is that viewbuild is the view and 2 is the id of the database row.
Normally It would simply be:
$id = $_GET['id'];
But cant figure out to do it PROPERLY using laravel.
This is my route:
Route::get('viewbuild', function()
{
return View::make('viewbuild');
});
And on my view I have done e.g.:
<?php
$build = Build::find(20);
?>
{{ $build->id }}
This correctly searches the builds table for a row with the id of 2 and then displays its id.
What I now want to do is pull the '20' value from the URL.
I have tried:
Route::get('/viewbuild/{build_id}', function($build_id = null)
{
$data = array(
'build_id' => $build_id,
);
return View::make('viewbuild', $data);
});
And then on my view:
$build = Build::find(build_id);
But I get undefined constant errors.
Any help on this?
Basically i can see two things from quick looking at your code:
A typo when setting the array to be passed to the view build_ud should be build_id i presume
You are referencing a constant for the build_id (no $ sign) in your view instead of the passed variable which is passed to the view. Ie:
$build = Build::find(build_id);
should be:
$build = Build::find($build_id);
Your route closure should look like this:
Route::get('/viewbuild/{build_id?}', function($build_id = null)
{
// Query the database here instead of inside the view
$build = Build::find($build_id);
return View::make('viewbuild', compact('build'));
});

CakePHP: Redirect in routes.php

OK, I dont know if I am taking the wrong approach or not but am stuck here...
We have developed our website and we have many controllers expecting ids and special variables, links already redirecting to the controllers passing what is expected.
The new requirement is to use friendlyUrls and the idea is that instead of having:
http://domain.com/search/advanced/term:head/city:/set:show-all/sort:basic-relevance
it now reads
http://domain.com/search/head
or passing options.
http://domain.com/search/in-edinburgh-scotland/by-rating/head
My idea was to, at the beginning of the Routes.php have a simple if such as:
$friendlyUrl = $_SERVER['REQUEST_URI'];
$friendlyUrl = split('/', $friendlyUrl);
foreach ($friendlyUrl as $key => $params) {
if(empty($params)){
unset($friendlyUrl[$key]);
}
if($params == 'search'){
Router::connect('/search/*', array('plugin'=>'Search','controller' => 'Search', 'action' => 'advancedSearch', 'term'=>'head));
}elseif ($params == 'employers') {
# code...
}elseif ($params == 'employer-reviews') {
# code...
}elseif ($params == 'jobs') {
# code...
}
}
That didn't work, then I tried adding something similar in my AppController and nothing.
All in all the the thing that has to do is:
Url be in the format of: /search/{term}
Actually be redirecting to: /search/advanced/{term}/city:{optional}/set:show-all/sort:basic-relevance
URL bar to keep reading: /search/{term}
Anyone has an idea?! Thank you
You definitely want to have a look at the routing page in the book
http://book.cakephp.org/2.0/en/development/routing.html
There are tons of options there to match url patterns to pass parameters to the controllers.
Router::connect(
'/search/:term',
array('controller' => 'search', 'action' => 'advanced'),
array(
'pass' => array( 'term')
)
);
You should probably set the defaults for city & set & sort in the actions function parameters definitions:
public function advanced($term, $city='optional', $sort = 'basic'){
// your codes
}
The great thing about doing it this way, is that your $this->Html->link's will reflect the routes in the paths they generate. (reverse routing)
The routes in cake are quite powerful, you should be able to get some decent friendly urls with them. One extra thing I've used is to use a behaviour - sluggable - to generate a searchable field from the content items title - for pages / content types in the cms.
good luck!

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);
}
}
}

Routing a subdomain in CakePHP with HTML-Helper

I have a mobile page running on a subdomain "m.mydomain.com". This is all working fine, but I would like to remove the controller in the URL when using the subdomain.
m.mydomain.com/mobiles/tips
should become
m.mydomain.com/tips
by using the HTML-Helper.
At the moment a link looks like that:
$html->link('MyLink', array('controller' => 'mobiles', 'action'=> 'tips'));
I tried several possible solutions with the routes and also some hacks in the bootstrap but it did not work out for me.
In the CakeBakery I found this but that does not solve my issue.
Does anyone have an idea for this issue?
Gathering code from the page you mentioned:
Constraint: you cannot have a controller called tips or foo in this setup
In /config/routes.php:
$subdomain = substr( env("HTTP_HOST"), 0, strpos(env("HTTP_HOST"), ".") );
if( strlen($subdomain)>0 && $subdomain != "m" ) {
Router::connect('/tips',array('controller'=>'mobiles','action'=>'tips'));
Router::connect('/foo', array('controller'=>'mobiles','action'=>'foo'));
Configure::write('Site.type', 'mobile');
}
/* The following is available via default routes '/{:controller}/{:action}'*/
// Router::connect('/mobiles/tips',
// array('controller' => 'mobiles', 'action'=>'tips'));
// Router::connect('/mobiles/foo',
// array('controller' => 'mobiles', 'action'=>'foo'));
In your Controller action:
$site_is_mobile = Configure::read('Site.type') ?: '';
Then in your view:
<?php
if ( $site_is_mobile ) {
// $html will take care of the 'm.example.com' part
$html->link('Cool Tips', '/tips');
$html->link('Hot Foo', '/foo');
} else {
// $html will just output 'www.example.com' in this case
$html->link('Cool Tips', '/mobiles/tips');
$html->link('Hot Foo', '/mobiles/foo');
}
?>
This will allow you to output the right links in your views (in a bit I'll show you how to write even less code) but the $html helper will not be able -- by no amount of magic -- to use controller-action routes to another domain. Be aware that m.example.com and www.example.com are different domains as far as the $html helper is concerned.
Now, if you want you can do the following in your controller to take some logic off your view:
<?php
$site_is_mobile = Configure::read('Site.type') ?: '';
if ( $site_is_mobile !== '' ) {
$tips_url = '/tips';
$foo_url = '/foo';
} else {
$tips_url = '/mobile/tips';
$foo_url = '/mobile/foo';
}
// make "urls" available to the View
$this->set($tips_url);
$this->set($foo_url);
?>
And in your view you don't need to worry about checking whether the site is being accessed via m.example.com/tips or www.example.com/mobile/tips:
<?php echo $html->link("Get some kewl tips", $tips_url); ?>
For more advanced routing in CakePHP-1.3 refer to Mark Story's article on custom Route classes
Let us know ;)

Categories