I've created a series of partial views for a page in our Yii Framework site. Each partial view has it's own model because they call subsections of the main model class. Since each partial view has it's own model, do I need separate controller classes for each?
My loadModel portion of the User controller is as follows:
public function loadModel($id,$model_name='Users')
{
$model=Users::model()->findByPk($id);
if($model===null)
throw new CHttpException(404,'The requested page does not exist.');
return $model;
}
It is being called from this section of the User Controller:
public function actionProfile($id=''){
$user = Users::model()->find('username=:id', array
(':id' => Yii::app()->user->id));
if(!$id){
$id = $user->id;
if(!$id)
$this->redirect('login');
}
if( getUserSess('user_type') == 'Sitter') {
$this->render('profile_detail', array('user_id' => $id ));
} else {
$this->render('petowner_profile_detail',array(
'model'=>$this->loadModel($id),
));
}
}
I think I understand what you are trying to do. My answer would be no, you don't need separate controller actions for each partial view. I would create a view that then calls all the partial views. If you use gii to create your CRUD functionality you will see both the create and edit views call a partial view of the form. You would do this same thing only call multiple partial views in your view file. If you need different models just make sure your controller passes them to your main view file first so that it can then pass them on to the partial views. Hopefully that helps you out.
Here is the code if there is no relationship:
$partialUser = new PartialUser::model->findByAttributes(array('uid'=>$id)); //IF NOT UID PUT WHATEVER YOU HAVE THE COLUMN NAME
$this->render('petowner_profile_detail',array(
'model'=>$this->loadModel($id),
'partialUser' => $partialUser,
));
If you did have a relationship setup you could easily just do this:
$current_user = $this->loadModel($id);
$this->render('petowner_profile_detail',array(
'model'=> $current_user,
'partialUser' => $current_user->partialUser, //whatever you set the name of the relationship as in the model
));
Related
I have started working with Codeigniter. So, I have two controller Tasks and Project. In my Task Controller I have a function to edit an existing task and after the task is edited I want to redirect to the Projects controller's display method which takes a parameter as the project_id associated with the task.
Here is my task controller:
public function edit($task_id,$task_project_id){
$this->form_validation->set_rules('task_name', 'Task Name','trim|required');
$this->form_validation->set_rules('task_description', 'Task Description','trim|required');
if ($this->form_validation->run() == FALSE){
$result=$this->task_model->get_task($task_id);
$data['task_name']=$result->task_name;
$data['due_on']=$result->due_on;
$data['task_description']=$result->task_description;
$data['id']=$task_id;
$data['task_project_id']=$task_project_id;
$data['main_view']="tasks/edit_task";
$this->load->view('layout/user', $data);
} else {
$data['task_project_id']=$task_project_id;
$data['task_name']=$this->input->post('task_name');
$data['due_on']=$this->input->post('due_on');
$data['task_description']=$this->input->post('task_description');
$data['id']=$task_id;
if ($this->task_model->edit($data)){
$this->session->set_flashdata('task_edited' ,'Task Edited Succesfully');
redirect(projects/display/$task_project_id); THIS SEEMS TO BE THE PROBLEM .
}else{
$this->session->set_flashdata('task_edited_failure' ,'Task Not Edited Succesfully');
redirect(projects/edit);
}
}
}
Here is my Projects Controller with its index and display function :
public function index()
{
$data['projects']=$this->projects_model->get_projects();
$data['main_view']="projects/home_view";
$this->load->view('layout/user.php',$data);
}
public function display($project_id){
$data['task']=$this->task_model->get_tasks($project_id);
$data['project']=$this->projects_model->get_project($project_id);
$data['main_view']="projects/display";
$this->load->view('layout/user.php',$data);
}
So, in my task controller I am trying to redirect to the projects controller's display method using redirect(projects/display/$task_project_id) as the Projects Controller's display function is display($project_id). But this is redirecting to me the Project controller's index function. What is wrong with the redirect ? I thought the URL structure in CI was controller/function/parameter1/parameter2.
You made mistake in writing redirect function. It should be like as below.
redirect('projects/display/'.$task_project_id);
redirect('projects/edit');
redirect($uri = '', $method = 'auto', $code = NULL)
redirect() function in codeigniter uses the url you define in your root. You can't directly jump to controllers.
I have this controller: Resales, and I am in the Administrator controller and need to create a new Resale.. how should I do that?
first option:
Administrator form calls /resales/addResales
second option: Administrator has a method addResale that loads the Resale model and inserts it.
What should I do?
thanks
Administrator controller shouldn't be loading the Resales controller - that should be a model that both controllers use. You should load your Resales model into the Administrator controller in the $uses = array() property at the top of your controller file:
class AdministratorController extends AppController {
var $uses = array('Resale', //the rest of your models);
public function createResale() {
$this->Resale->create();
$this->Resale->set($this->data['Resale']);
$this->Resale->save();
}
}
Other options are that you could use Ajax to post the request for you, or you could use $this->requestAction() in your Administrator controller to use a processing function in your Resales controller:
// administrator controller
public function createResale() {
// define your data here
$result = $this->requestAction('resales/create', array($data_array));
}
Have a look at the manual for more information on requestAction:
http://book.cakephp.org/2.0/en/controllers.html
EDIT
You've just asked about views. In this case, there's no real need to create a view for createResale(), what you might want to do instead is set a Session flash message, then redirect back to your form. You will need to ensure you've included the Session helper at the top of your controller:
class AdministratorController extends AppController {
var $helpers = array('Session', // any others here);
Then you prevent the layout and render of views, do your thing and set a session flash with the results message:
public function createResale() {
// don't render a view or layout
$this->layout = '';
$this->render(false);
// process your request
$result = // do stuff... return true or false for result
$msg = $result ? 'Added successfully!' : 'Error adding resale!';
// set flash message
$this->Session->setFlash($msg);
// return to that form
$this->redirect(array('action' => 'formYouCameFrom'));
}
Now on your form, you'll simply do this:
echo $this->Session->flash();
... which will output the results.
How to include a page based on its route. Example of route: page_to_be_included
Page should be included like this in view:
<?php
if (...){
include 'page_to_be_included';
}
else {
show something else
}
?>
How can i include one view in another view?
In most cases each route should lead to its own action, then each action can set its on view (or just use default).
If more then one route lead to the same action, you can check the route in the controller and set the view according:
if ( $this->getEvent()->getRouteMatch()->getMatchedRouteName() == 'the_route_name' ) {
$viewModel = new ViewModel();
$view->setTemplate('what/ever/page');
return $viewModel->setVariables(array('var2pass'=>'hi'));
}
Maybe you means to include a view script (of an other controller)?
$viewmodel = new ViewModel();
$page = $this->forward()->dispatch('thecontroller', array(
'action' => 'youractionname',
));
$viewmodel->addChild($page, 'page');
I think you mean you want to put partial into you view. If you want to do this just use partia() view helper in your view with specified string path to your partial.
Lets say you have folder structure of your Test module like this: module\Test\view\partial\name-of-partial.phtml
$this->partial('partials/name-of-partial');
I would like the home page rendered depend on the user role login.
Currently I have this in the protected/controllers/break;SiteController.php but it redirects to another page.
protected function roleBasedHomePage() {
$roles = Yii::app()->user->getState('roles'); //however you define your role, have the value output to this variable
switch($role) {
case 'admin':
$this->redirect(Yii::app()->createUrl('site/page',array('view'=>$roles.'homepage')));
break;
case 'b':
$this->redirect(Yii::app()->createUrl('site/page',array('view'=>$roles.'homepage')));
break;
case 'guest':
$this->redirect(Yii::app()->createUrl('site/page',array('view'=>'homepage')));
break;
//etc..
}
public function actionLogin()
{
$model = new LoginForm();
if (isset($_POST['ajax']) && $_POST['ajax'] === 'login-form') {
echo CActiveForm::validate($model, array('username', 'password', 'verify_code'));
Yii::app()->end();
}
if (isset($_POST['LoginForm'])) {
$model->attributes = $_POST['LoginForm'];
if ($model->validate(array('username', 'password', 'verify_code')) && $model->login()) {
Yii::app()->user->setFlash('success', 'Welcome ' . app()->user->name);
// $this->redirect(Yii::app()->user->returnUrl);
$this->roleBasedHomePage();
}
}
$this->render('login', array('model' => $model));
}
}
This works if I want to redirect the page but I want the home page url to be the same and the content to change depending on 'roles'.
e.g. if the user is 'admin' then I want 'adminhome' rendered
I'm guessing the function below has something to do with it?
public function actionIndex()
{
$this->render('index');
}
you can do this easily. first create a view for every role. then redirect every one to your home page after login, but check their role and depending on that, "renderPartial()" the view for that role. like:
switch($role){
case 'admin' :
$this->renderPartial('application.views.site._admin'); // view for admin
break;
case 'superUser':
$this->renderPartial('application.views.site._superUser');// view for super user
break;
I would use Ajax as an option, if what you want to change is the content of the page but keep the same footer and header.
For instance:
1- Create three different views, admin.php, b.php and guest.php.
2- In your controller create three different methods: renderAdmin(), renderB() and renderGuest(). Each one will render the corresponding view.
3- In the same controller define the Access rules for the specific role and methods, so an Ajax call from an invalid user will not be allowed (in case someone sees your code and tries to invoke the method based in the Ajax URL where you send the post to). This because in the default header that you use in your 'index.php' you will assign the JS script which calls the specific method, the method will return the view and thats what you render on the 'main' content div.
4- In the login() you call the index method.
5- In the index method you render the 'index' view and pass the path to the specific JS script which calls the 'adminview', for instance.
You could also use Update content in AJAX with renderPartial
HTH
Change your index action in the controller to something like this:
public function actionIndex()
{
$roles = Yii::app()->user->getState('roles');
$view = $this->getViewForRole($roles); // you have to implement this function
$this->render($view . '_index');
}
Create the view files in the views folder: admin_index.php, customer_index.php etc.
I'm using codeigniter I have this BuildTemplate function in my [HOME] controller that authenticates a user. I have another controller called [AJAXCONT] that has a function called search() that returns data to populate my search table in the view. I would like to retrieve that controller's data from it's search function right after I generate the $top_bar_data view. How can I code this. Is my approach correct here?
private function BuildTemplate($view, $data) {
if($this->session->userdata('logged_in_faculty'))
{
$session_data = $this->session->userdata('logged_in_faculty');
$top_bar_data['Firstname'] = $session_data['Firstname'];
$top_bar_data['Lastname'] = $session_data['Lastname'];
$master_data['f_top_bar'] = $this->load->view('f_top_bar', $top_bar_data, true);
//I WANT TO RETURN ALL DATA IN THE AjaxCont controller returned by the search function HERE //
//$search_data = (all data from my search function in AJAXCONT controller )
// $master_data['search_results'] = $this->load->view('search_results', $search_data, true);
}
else
{
//If no session, redirect to login page
redirect('login', 'refresh');
}
return $this->load->view('master', $master_data, true);
}
You should move all your functions to models, controllers should only retrieve the data from the models and output it by loading views. CodeIgniter's controllers are only called by URI/Routing, you cannot call a controller or controllers methods from anywhere else.
Create a model to work with users, a second model that does what your search does. Then, from controller call those in the order you wish.