I want to create custom permalinks on CodeIgniter, actually i bought the script but the developer left that project due to some indifference. so now the problem is i have no idea how to change permalinks on that script. The main permalinks issue is when i search anything on searchbar i get this url:
domain.com/?s=xxxxx%20yyyyy
instead of that i want this url structure:
domain.com/search/xxxxxx-yyyyy/
application/config/routes.php
$route['default_controller'] = "music";
$route['404_override'] = '';
$route['search/(:any)'] = "music/index/$0/$1/$2";
$route['search/music/(:any)'] = "music/$1";
I guess what you are asking for is not possible (directly).
Assuming your form to be,
<form action="" method="GET">
<input type="text" name="s" value="" placeholder="Search music..." />
</form>
And since the method is GET the default functionality says to add the parameter in the URL as query string.
As the specifications (RFC1866, page 46; HTML 4.x section 17.13.3) state:
If the method is "get" and the action is an HTTP URI, the user agent takes the value of action, appends a `?' to it, then appends the form data set, encoded using the "application/x-www-form-urlencoded" content type.
So, basically what you can do here is apply a hack to this. Redirect the user to the required URL when the search is applied. Here's how you can go,
Controller (controllers/music.php)
<?php
class Music extends CI_Controller
{
public function __construct()
{
parent::__construct();
$this->load->model('xyz_model');
}
public function index()
{
if($this->input->get('s'))
{
$s = $this->input->get('s');
redirect('/search/'$s);
}
$this->load->view('home.php');
}
public function search()
{
$s = $this->uri->segment(2);
/*
Now you got your search parameter.
Search in your models and display the results.
*/
$data['search_results'] = $this->xyz_model->get_search($s);
$this->load->view('search_results.php', $data);
}
}
Related
I have two forms on a page both submits the data via POST method. I want to handle both requests on the same url i.e /home and use different controllers and methods for both forms. Below are the two routes.
Route::post('home' ,'FacebookControllers\PostsController#save');
Route::post('home' , 'FacebookControllers\MessageController#storeMessage');
In PostsController#save I am checking
if(isset($_POST['submitPost']) && $_SERVER['REQUEST_METHOD']=='POST'){
//do something
}
and in MessageController#storeMessage I am doing the same for other form
if(isset($_POST['sendMessage']) && $_SERVER['REQUEST_METHOD']=='POST'){
return "got it";
}
The problem is that only second route works. I don't if I am doing right or wrong. Please lead me to the right direction.
Route::post('home' ,'FacebookControllers\PostsController#save');
Route::post('home' , 'FacebookControllers\MessageController#storeMessage');
won't work - how should laravel determine where to post to? The way I would go is to create two jobs and one route, then check for the value in Request and dispatch the correct job.
First, create two job classes with
php artisan make:job FacebookSave
php artisan make:job FacebookStoreMessage
The generated file will look much like this:
<?php
namespace App\Jobs;
use App\Jobs\Job;
use Illuminate\Contracts\Bus\SelfHandling;
class FacebookSaveMessage extends Job implements SelfHandling
{
/**
* Create a new job instance.
*
* #return void
*/
public function __construct()
{
//
}
/**
* Execute the job.
*
* #return void
*/
public function handle()
{
//
}
}
In the job's handle() method you can do what you wanted to do in your Controller.
Now the route, let's do
Route::post('home' ,'FacebookControllers\PostsController#findAction');
and according to this in your PostsController, add a method (I called it findAction) like this:
public function findAction(\Illuminate\Http\Request $request) {
if ($request->has('submitPost')) {
return $this->dispatch(new \App\Jobs\FacebookSave($request));
} else if ($request->has('storeMessage')) {
return $this->dispatch(new \App\Jobs\FacebookStoreMessage($request));
}
return 'no action found';
}
This way the correct action will be performed depending on the submitted value.
Change the job's constructor to something like:
public function __construct($data)
{
$this->data = $data;
}
And you can access the submitted values from the forms you have submitted inside the job's handle() method with $this->data
If the purpose is only to maintain the URL that appears in the browser, you may apply a trick in which you submit your post request to different ROUTES that are specifically exist for processing purpose and then redirect back to the same URL.
For example:
Route::post('home' ,'FacebookControllers\PostsController#save');
Route::post('message' , 'FacebookControllers\MessageController#storeMessage');
Then in your view , you maybe have two diffrent forms in the same view:
<!-- the first form -->
<form action="{{url('home')}}" method="post">
Enter your post:
<input type="text" name="post" />
<button type="submit" >Save</button>
</form>
<!-- the second form -->
<form action="{{url('message')}}" method="post">
Enter your post:
<input type="text" name="post" />
<button type="submit" >Save</button>
</form>
Now in your controller, in the both actions do something like :
public function save(Request $request)
{
// do stuff
$obj->save()
return redirect('home')->with('status' , 'you have saved your post')
}
public function storeMessage(Request $request)
{
// do stuff
$obj->save()
return redirect('home')->with('status' , 'your message has been saved')
}
By doing so, the URL will remain same for the user, after the process is done the user will be redirected back to the same URL with the status.
May be this is not a good coding practice, but it solve the problem by maintaining the same URL while having multiple posts to the same controller in the same view.
The most important point here is that you have to strictly prevent an error during the process by using conditions and redirect to the same URL in case of any problem, otherwise the action will try to show the user the tricky ROUTE (yoursite.com/message) for any error.
I am trying to send a url from view page to controller but it does not seem to work the way i am thinking.
View Page
Product
User
I want to get "tbl_product"
Controller admin
<?php
class Admin extends CI_Controller {
public function test() {
echo $this->uri->segment(4);
}
}
?>
but if the segment(4) is changed to segment(3), it shows up with displaying "product" in the screen
your controller function should have arguments for your url segments
for example:
public function test($product = 'product', $tbl = 'tbl_product') {
echo $tbl // contains the string tbl_product
}
Since you said your routes look like this:
$route['default_controller'] = "admin";
$route['404_override'] = ''
and your URL is like this:
<?= base_url() ?>admin/test/product/tbl_product
Then if your base_url() is localhost/my_app, your URL will be read as this:
http://localhost/my_app/admin/test/product/tbl_product
http://localhost/my_app/CONTROLLER/METHOD/PARAMETER/PARAMETER
So in your controller, you can do this:
class Admin extends CI_Controller {
public function test($product = NULL, $tbl_product = NULL) {
echo $product;
echo $tbl_product;
}
}
It's strange to use codeigniter for this purpose, because codeigniter uses as default the url format bellow.
"[base_url]/[controller]/[method]"
I think it will be better and more easy to just pass the values you want as get parameters and make some httaccess rules to make your url more readable for the user and robots. That said you can do that:
Product
<?php
class Admin extends CI_Controller {
public function test() {
echo $this->input->get('product');
//should output 'tbl_product'
}
}
?>
If you prefer to use uri instead u should route your uri's so it will be like.
In your routes file you probably I'll need something like this.
$route['product/(:any)'] = "Admin/test";
This way you will probably access the uri segments correctly.
Thank you so much for going through.
$this->uri->segment(4); // is now working :S
its not working properly after all I made changes to routes.php and came back to default again. I seriously have no idea what the reason behind not displaying the result before.
I have created a custom component with form to update prices of four product to be displayed on frontend.
My main controller code is here:
public function display($cachable = false, $urlparams = false) {
require_once JPATH_COMPONENT.'/helpers/calculator.php';
$view = JFactory::getApplication()->input->getCmd('view', 'pricetable');
$layout = JFactory::getApplication()->input->getCmd('layout', 'edit');
JFactory::getApplication()->input->set( 'layout', $layout );
JFactory::getApplication()->input->set('view', $view);
JFactory::getApplication()->input->set('id', 1);
parent::display($cachable, $urlparams);
return $this;
}
id is set to 1 so it loads only first row from database.
code for pricetable container is:
function __construct() {
$this->view_list = 'pricetable';
parent::__construct();
}
Now in admin backend the form is loaded as desired with the first row of data.
When I try to save the form it is redirected to administrator/index.php?option=com_calculator&view=pricetable and error is:
Error: You are not permitted to use that link to directly access that
page (#1).
my form action is:
<?php echo JRoute::_('index.php?option=com_calculator&task=pricetable.edit&id='.(int) $this->item->id); ?>
Please suggest where I am doing wrong. It is third day I'm scratching my head. :(
You can do updating actions (or calling them) inside your code whenever it is.
New instance or update new - just add one more if in code and hidden input on form. For example:
<input type="hidden" name="task" value="update" />
I have a filter that runs on all my controllers..
in preFilter I have:
protected function preFilter($filterChain){
Yii::app()->params->controller = Yii::app()->controller->id;
Yii::app()->params->action = Yii::app()->controller->action->id;
return true;
}
in the postFilter i have:
protected function postFilter($filterChain){
$this->controllerName = Yii::app()->params->controller ;
$this->actionName = Yii::app()->params->action;
$this->CheckTrigger();
return true;
}
The function CheckTrigger() refers to Yii::app()->params->controller and Yii::app()->params->controller.
So here is the issue.. If i have a redirect in my action this brakes. If i comment out my redirect it starts working again. It seems that when the redirect is called the Pre and Post Filter actions are also called but the Post filter is never called before the redirect is initiated.. Is there a way to ensure that the post filter is called before a redirect? Am i missing something here?
many thanks..
Try this redirect code in your controller action:
$this->redirect('url here', false);
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
}
}
}
?>