codeigniter uri/router checking - codeigniter

I am using codeigniter and have a controller in which I assign some search criteria's to be stored in session like this:
$srchCriteria = array(
'stockCode'=>$this->input->post('srchScode'),
'qty'=>$this->input->post('srchQty'),
'class' => $this->router->fetch_class(),
'method' => $this->router->fetch_method(),
);
$this->session->set_userdata('srchCriteria',$srchCriteria);
And on basis of this criteria output is generated. Now I need to clear this criteria if the user navigates to another page other than this page. i.e every time the user visits the search page the search criteria should be cleared except for pagination. For this purpose I checked the class and method variables in core controller like this:
$srchCriteria = $this->session->userdata('srchCriteria');
$className = $this->router->fetch_class();
$methodName = $this->router->fetch_method();
if(!empty( $srchCriteria['class'] ) && !empty( $srchCriteria['method'] )){
if( ($srchCriteria['method'] != $methodName){
$this->session->set_userdata('srchCriteria',array());
}
}
But it is not working please guide me in right way. What is my mistake here?

Try $this->session->unset_userdata('srchCriteria'); instead of $this->session->set_userdata('srchCriteria',array());

Related

Load view by current URL last segment in Codeigniter

I'm trying to load view content page when url last segment matched. When click a link which get link in url like http://192.168.20.2/vtp/attendance/rawAttendance then load the rawAttendance view and when I click other link which last segment is getAttendance then it's also load the same same view not getAttendance. How do get this done?
$last = $this->uri->total_segments();
$lastSegment = $this->uri->segment($last);
if ($this->input->post("fromAjax")) {
if($lastSegment == "rawAttendance"){
$this->load->view('attendance/rawAttendance', $data);
}else if($lastSegment == "getAttendance"){
$this->load->view('attendance/getAttendance', $data);
}else {
}
}
CI has its inbuilt helper for knowing controller name and method name.
$classname = $this->router->fetch_class();
$methodname = $this->router->fetch_method();
if ($this->input->post("fromAjax")) {
if($classname == "attendance" && $methodname == "rawAttendance"){
$this->load->view('attendance/rawAttendance', $data);
}else if($classname == "attendance" && $methodname == "getAttendance"){
$this->load->view('attendance/getAttendance', $data);
} else {
}
}
CodeIgniter is a basic MVC framework - so everything starts with the controller. From the code you've written, I assume you already have your routes, etc configured to point at the method you've placed in your question.
You can simplify things quite a bit from the way you have them. Using the CI helper for controller/method is a bit helpful, but I think you're looking for something a little more elastic in your approach to dynamically load a view based on your last URI segment.
Try something like this:
// Get your last URI segment
$last = $this->uri->total_segments();
$lastSegment = $this->uri->segment($last);
/**
* Do whatever logic you need to do to calculate your data
*/
// ...
/**
* Load the view
*/
$this->load->view( 'attendance/' . $lastSegment, $data );
This could probably be better architected using the CI routes capability though. For instance, if you have several view folders and view files within, it would be best practice to organize those and better cement your URI structures so that each URI segment plays a specific role:
CI routes.php
$route["vtp/(:any)/(:any)"] = "path_to_method";
Method
$dir = $this->uri->segment(2);
$view = $this->uri->segment(3);
$this->load->view( $dir . "/" . $view, $data );

MVC URL issues (Codeigniter)

I'm building a website using Codeigniter and I really like how in the MVC pattern URLs are used to reference controller methods. It seems very logical and intuitive however, I seem to be running in an array of issues with this very pattern!
So I am building an events website and currently I'm passing everything through one main Site controller, passing a number of parameters:
public function index($page = NULL, $city = NULL, $type_venue = NULL, $slug = NULL)
{
// if the page argument is empty show the homepage
if( ! ($page))
{
$page = 'home';
}
// create an array for passing to the views
$data = array(
'title_city' => $city,
'title_type_venue' => str_replace('-', ' ', $type_venue),
'locations' => $this->locations_model->load(),
'events' => $this->events_model->load($city, $type_venue, $slug),
'venues' => $this->venues_model->load($city, $slug)
);
// construct the page layout with the following views
$this->load->view('partials/head', $data);
$this->load->view('partials/header', $data);
$this->load->view('content/'.$page, $data);
$this->load->view('partials/footer');
}
This works fine, in that it loads content for the following URLs:
site.com/events/bristol/open-mic/city-varieties/another-incredible-event
site.com/events/bristol/open-mic/city-varieties/
site.com/events/bristol/open-mic/
site.com/events/bristol/
However if I want to pass anything else through this controller that isn't an event, i.e. register/user, I have to write a specific route for this!
Worth noting my routing is:
$route['(:any)'] = 'site/index/$1';
I could write separate controllers for each entity, i.e. events, venues, cities but each one would look largely like the above (correct?) in that each would need the parameters to get the data.
My question is - what is the best practice approach for developing long query strings like this? Is a single controller correct? It doesn't feel like it, but then multiple controllers would violate DRY, just because they all need so much similar data. Any help appreciated!
Avoid putting everything into a single controller; even further, in each controller, avoid putting everything into a single index function.
There is no need to write specific controllers for each function in Codeigniter - suggest you read that part again in the manual. Most of your routing will be done automatically for you if you follow the normal guidelines.
The more you try to use a single controller or function, the more you will have to add untestable, unmanageable, unscalable conditional code later.

"Beautifying" a URL in Yii

I want to convert a URL which is of the format
path/to/my/app/Controller_action/id/2
to
path/to/my/app/Controller_action/id/User_corresponding_to_id_2
I have already seen this tutorial from Yii, but it isnt helping me with anything. Can anyone help me with this?
EDIT: I would also like to know if this thing is even possible in the POST scenario, ie I will only have path/to/my/app/Controller_action in the URL.
Add a getUrl method in your User model
public function getUrl()
{
return Yii::app()->createUrl('controller/action', array(
'id'=>$this->id,
'username'=>$this->username,
));
}
Add the following rule urlManager component in config/main.php
'controller/action/<username:.*?>/<id: \d+>'=>'controller/action'
And use the models url virtual attribute everywhere
dInGd0nG is on the correct track, but if I understand correctly you wish to do actions based on the actual username instead of the ID as well right?
It's not that hard in Yii. I'm assuming here for simplicity the controller is user and the action is view.
Your User controller:
public function actionView($id)
{
if (is_numeric($id))
$oUser = User::model()->findByPk($id);
else
// Luckily Yii does parameter binding, wouldn't be such a good idea otherwise :)
$oUser = User::model()->findByAttributes(array('username' => $id));
...
}
Your urlManager config:
'user/view/<id: \w+>' => 'user/view',
Or more generally:
'user/<action: \w+>/<id: \w+> => 'user/<action>',
To generate a user url in a view:
$this->createUrl('user/view', array('id' => $oUser->username));

Codeigniter - best routes configuration for CMS?

I would like to create a custom CMS within Codeigniter, and I need a mechanism to route general pages to a default controller - for instance:
mydomain.com/about
mydomain.com/services/maintenance
These would be routed through my pagehandler controller. The default routing behaviour in Codeigniter is of course to route to a matching controller and method, so with the above examples it would require an About controller and a Services controller. This is obviously not a practical or even sensible approach.
I've seen the following solution to place in routes.php:
$route['^(?!admin|products).*'] = "pagehandler/$0";
But this poses it's own problems I believe. For example, it simply looks for "products" in the request uri and if found routes to the Products controller - but what if we have services/products as a CMS page? Does this not then get routed to the products controller?
Is there a perfect approach to this? I don't wish to have a routing where all CMS content is prefixed with the controller name, but I also need to be able to generically override the routing for other controllers.
If you use CodeIgniter 2.0 (which has been stable enough to use for months) then you can use:
$route['404_override'] = 'pages';
This will send anything that isn't a controller, method or valid route to your pages controller. Then you can use whatever PHP you like to either show the page or show a much nicer 404 page.
Read me guide explaining how you upgrade to CodeIgniter 2.0. Also, you might be interested in using an existing CMS such as PyroCMS which is now nearing the final v1.0 and has a massive following.
You are in luck. I am developing a CMS myself and it took me ages to find a viable solution to this. Let me explain myself to make sure that we are on the same page here, but I am fairly certain that we area.
Your URLS can be formatted the following ways:
http://www.mydomain.com/about - a top level page with no category
http://www.mydomain.com/services/maintenance - a page with a parent category
http://www.mydomain.com/services/maintenace/server-maintenance - a page with a category and sub category.
In my pages controller I am using the _remap function that basically captures all requests to your controllers and lets you do what you want with them.
Here is my code, commented for your convenience:
<?php
class Pages extends Controller {
// Captures all calls to this controller
public function _remap()
{
// Get out URL segments
$segments = $this->uri->uri_string();
$segments = explode("/", $segments);
// Remove blank segments from array
foreach($segments as $key => $value) {
if($value == "" || $value == "NULL") {
unset($segments[$key]);
}
}
// Store our newly filtered array segments
$segments = array_values($segments);
// Works out what segments we have
switch (count($segments))
{
// We have a category/subcategory/page-name
case 3:
list($cat, $subcat, $page_name) = $segments;
break;
// We have a category/page-name
case 2:
list($cat, $page_name) = $segments;
$subcat = NULL;
break;
// We just have a page name, no categories. So /page-name
default:
list($page_name) = $segments;
$cat = $subcat = NULL;
break;
}
if ($cat == '' && $subcat == '') {
$page = $this->mpages->fetch_page('', '', $page_name);
} else if ($cat != '' && $subcat == '') {
$page = $this->mpages->fetch_page($cat, '', $page_name);
} else if ($category != "" && $sub_category != "") {
$page = $this->mpages->fetch_page($cat, $subcat, $page_name);
}
// $page contains your page data, do with it what you wish.
}
?>
You of course would need to modify your page fetching model function accept 3 parameters and then pass in info depending on what page type you are viewing.
In your application/config/routes.php file simply put what specific URL's you would like to route and at the very bottom put this:
/* Admin routes, login routes etc here first */
$route['(:any)'] = "pages"; // Redirect all requests except for ones defined above to the pages controller.
Let me know if you need any more clarification or downloadable example code.

Codeigniter form validation failing when it should succeed

I'm building an admin utility for adding a bulk of images to an app I'm working on. I also need to to log certain properties that are associated with the images and then store it all into the database.
So basically the script looks into a folder, compares the contents of the folder to records in the database. All of the info must be entered in order for the database record to be complete, hence the form validation.
The validation is working, when there are no values entered it prompts the entry of the missing fields. However it happens even when the fields ARE filled.
I'm doing something a bit funny which may be the reason.
Because I'm adding a bulk of images I'm creating the data within a for loop and adding the validation rules within the same for loop.
Here is the results:
http://s75151.gridserver.com/CI_staging/index.php/admin_panel/bulk_emo_update
Right now I have default test values in the form while testing validation. The submit button is way at the bottom. I'm printing POST variable for testing purposes.
Here is the code:
function bulk_emo_update() {
$img_folder_location = 'img/moodtracker/emos/';//set an image path
$emo_files = $this->mood_model->get_emo_images('*.{png,jpg,jpeg,gif}', $img_folder_location); //grab files from folder
$emo_records = $this->mood_model->get_all_emos(); //grab records from db
$i=1; //sets a counter to be referenced in the form
$temp_emo_info = array(); //temp vairable for holding emo data that will be sent to the form
//loop through all the files in the designated folder
foreach($emo_files as $file) {
$file_path = $img_folder_location.$file;//builds the path out of the flder location and the file name
//loops through all the database reocrds for the pupose of checking to see if the image file is preasent in the record
foreach($emo_records as $record) {
//compairs file paths, if they are the
if($record->picture_url != $file_path) {
//FORM VALIDATION STUFF:
$rules['segment_radio['.$i.']'] = "required";
$rules['emo_name_text_feild['.$i.']'] = "required";
//populating the temp array which will be used to construct the form
$temp_emo_info[$i]['path'] = $file_path;
$temp_emo_info[$i]['name'] = $file;
}
}
$i++;
}
//sets the reference to validation rules
$this->validation->set_rules($rules);
//checks to see if the form has all it's required fields
if ($this->validation->run() == FALSE) { //if validation fails:
print_r($_POST);
//prepairs the data array to pass into the view to build the form
$data['title'] = 'Bulk Emo Update';
$data['intro_text'] = 'fill out all fields below. hit submit when finished';
$data['emos_info'] = $temp_emo_info;
$this->load->view('admin_bulk_emo_update_view',$data);
} else { // if it succeeds:
//printing for test purposes
print_r($_POST);
$this->load->view('form_result');
}
}
I'm new to codeigniter and php in general so if anything looks outrageously weird please tell me, don't worry about my feelings I've got thick skin.
if ($this->validation->run() == FALSE)
if you are calling the run() method of the validation class every time the script is run, will it ever return TRUE and run the else? Maybe a different return?
I'm a little cornfused by what's going on. Generally, if I'm having a problem like this, I will figure out a way to force the result I'm looking for. e.g. in your code, I'd force that else to run... once I get it to run, break down what happened to make it run. Rudimentary, but it has served me well.
You use array of rules in
$this->form_validation->set_rules()
wrong.
If you want to pass the rules in array you must stick to the key names like described here http://codeigniter.com/user_guide/libraries/form_validation.html#validationrulesasarray
So instead of
$rules['input_name'] = "required"
try this:
array(
'field' => 'input_name',
'label' => 'Name that you output in error message',
'rules' => 'required'
)

Resources