I have 2 instances of codeigniter and I would like to call a function of an instance from the other instance. I have a first instance that deals with accounts (in mywebsite.com/account.php) and a second dealing with stock portfolios (mywebsite.com/portfolio.php). The aim would be that when I register a new position in my portfolio, it will register the fees in the account instance.
In account.php, I have a controller to add a transaction (account.php/transaction/add).
In portfolio.php, I have a controller to add a new position (portfolio.php/position/add).
I want to call account.php/transaction/add with some arguments (maybe in POST method) within the controller portfolio.php/position/add. Is there a simple way to do it?
Thanks a lot
There are many ways to address this need. When some functionality is needed in more than controller that points to creating a resource that both controllers can load and use.
The "resource" might be a model, or it might be a custom "library", or maybe both. (It should NOT be some other controller.) The answer depends on exactly what has to happen. Since you don't share any code it's impossible to offer precise help.
Since I have to guess that guess is that a model used by both controllers could work.
Thanks for the answer. You are right, I will try to be more accurate with some codes.
Basically, when I add a new position in my portfolio (eg: I buy 50 shares of a stock AAA), I register it in my website portfolio.php. But at the same time, I would like to register a transaction in account.php with the fees paid.
Here is the code of the portfolio.php/position/add :
public function add()
{
$this->load->helper('form');
$this->load->library('form_validation');
$this->form_validation->set_rules('portfolio', 'Portfolio', 'required');
$this->form_validation->set_rules('type', 'Type', 'required');
if ($this->form_validation->run() == FALSE)
{
$this->load->view(SHARED_VIEWS_FOLDER.'header', $this->data);
$this->load->view('menu', $this->data);
$this->load->view('transaction/add', $this->data);
$this->load->view('menu_bottom', $this->data);
$this->load->view(SHARED_VIEWS_FOLDER.'footer', $this->data);
} else {
$the_quantity=$this->input->post('quantity');
if ($this->input->post('type') == "sell") {$the_quantity = -$the_quantity;}
$this->position_model->addTransaction($this->input->post('portfolio'), $this->input->post('stock'), $the_quantity, $this->input->post('price'), $this->input->post('fees'), $this->input->post('date'));
//TO DO : ADD THE TRANSACTION IN ACCOUNT.PHP
redirect(base_url().'stock.php/transaction', 'refresh');
}
}
The aim is to send some parameters (date, fees, stock, price) to account.php in order to add a transaction. I was thinking about calling a controller such as account.php/transaction/add, but it can also be to call directly the model transaction_model.php.
In the end, I want it to behave like an API: portfolio.php is calling an API in account.php, send some parameters and it will create a transaction in account.php.
Related
I have a question more regarding style and organization that anything else. I often find myself having a single page (controller) that requires multiple ajax calls. Rather than creating a separate controller just for the AJAX calls because that would mean more controllers I just do the following:
class Management extends MY_Controller
{
public function __construct()
{
parent::__construct();
$this->protect->protect();
if ($this->uri->segment(2, 0) !== 0 && !$this->input->is_ajax_request()) {
exit('No direct script access allowed');
}
}
public function index()
{
$this->load->model('management_model');
$data['row_config'] = $this->management_model->getConfigRows();
$data['row_users'] = $this->management_model->getUsers();
$data['roles'] = $this->management_model->getRoles();
$this->tpl->head();
$this->load->view('management/scripts');
$this->tpl->body();
if ($this->messages->hasMessages()) {
$this->output->append_output($this->messages->display());
}
$this->load->view('management/manage', $data);
$this->load->view('management/current_users', $data);
$this->load->view('management/modals', $data);
$this->tpl->footer();
}
public function get_user_details()
{
$user = new \Auth\ASUser($_POST['userId']);
echo json_encode($user->getAll());
}
public function delete_user()
{
$user = new \Auth\ASUser($_POST['userId']);
$user->deleteUser(true);
}
As the index is the only page where I actually need to render a proper view, and the rest are ajax calls I just check the URI segment to see if something other than the index exists and then check if its an ajax request.
Is this bad practice? Should I separate the AJAX calls and the view controller?
Honestly, i don't think that there is a pattern on where you should add your ajax functions, especially in Codeigniter which is loosely coupled for most of it's structure.
In my opinion you should ask yourself the below, in order to find where you should place your ajax calls.
Are the returned data from the ajax call, related to the Controller i am already?
Will i ever use again the same method/functionality in another Controller or somewhere else?
Do i need the already defined constructor of the Controller, which i think i should place the ajax call?
Do i count on the DRY principle of software development?
Is my code flexible, reusable, etc.?
Each project has it's own philosophy and workflow. The design pattern and the data structure that you will decide you will follow, will solve most of your questions in your coding-style.
Your question is asking an opinion which is contrary to Stack Overflow's SOP. But I'll offer my opinion anyway.
Is this bad practice? I don't think so. That said, why make a controller larger than it needs to be? If your Ajax is handling the full CRUD functionality for some page then the controller could be quite large. You might be better served by a separate controller.
An Ajax call is a distinct request to the server - essentially the same as directing the browser to a separate page on some other browser tab. Why not make that request to a controller that is dedicated to Ajax? It could be argued that such a controller produces better "Separation of Concerns". That is good practice.
There is one technique to make certain this controller is only used when requested by an ajax call. A couple lines of code in the controller will make the determination.
class Some_ajax_handler extends CI_Controller
{
public function __construct()
{
if(!is_ajax()){
show_404();
}
parent :: __construct();
//if needed, do the rest of your construct here
}
public function get_user_details()
{
$user = new \Auth\ASUser($_POST['userId']);
echo json_encode($user->getAll());
}
}
The call to show_404(); ends with a call to exit() so you don't need a return; statement or else block in the controller. You can be confident that any method that gets called on this controller is indeed an ajax request.
On the other hand, if a controller's view uses Ajax to get the contents for a select input, or some other simple GET call, then creating a separate controller seems like overkill.
BTW, there is a CI library simplifying Ajax calls HERE that you might find interesting.
The one criticism I offer isn't about ajax but about your use of new which is contrary to the "Codeigniter way" for loading and utilizing other classes (libraries). But I guess that's a different topic.
I have such function in the controller
public function actionNext(){
$category = $this->getCategory();
$not_finished = $this->getQuestionFromCategory($category);
if(!empty($not_finished)){
$next_question_id = getNextQuestionId();
$this->updateNextQuestion();
}
else{
addNextCategory();
}
}
My question is: all fuctions
getCategory
getQuestionFromCategory
getNextQuestionId
updateNextQuestion
addNextCategory
from the example should be in model or controller too (all functions is the requests to the db).
Normally the function related to the db are in model, tipically the model extend the active record and for this contain also the related sql/schema/model related function. in your case is think the function getCategory and probably getQuestionFormCategory
The function related to service for support controller action are place in controller. in your case genNextQuestionId, updateNewQuestion, addNextQuestion.
The main rules is: what's regarding the structural knwoledge of an entity is in model, what's regarding tactical behaviuor is in controller.
Obviously the part related to sort and find are placed in ...search class.
currently i am doing a project in zend the way i am doing is working perfectly but i am sure its not the way i am suppose to do i mean i am not following MVC and i want to apply MVC in my zend app.
i am pasting code of one simple module which will describe what i am doing .kindly correct me where i am making faults.
my controller
class ContactsController extends Zend_Controller_Action{
public function contactsAction(){
if(!Zend_Auth::getInstance()->hasIdentity()){
$this->_redirect('login/login');
}
else{
$request = $this->getRequest();
$user = new Zend_Session_Namespace('user');
$phone_service_id = $user->p_id;
$instance = new Contacts();
$select = $instance->Get_Contacts($p_id);
$adapter = new Zend_Paginator_Adapter_DbSelect($select);
$paginator = new Zend_Paginator($adapter);
.
.
//more code
}
plz note this 2 line in my controller
$instance = new Contacts();
$select = $instance->Get_Contacts($pid);
this is my contacts class in models
class Contacts extends Zend_Db_Table{
function Get_Contacts($p_id){
$DB = Zend_Db_Table_Abstract::getDefaultAdapter();
$select = $DB->select()
->from('contact', array('contact_id','contact_first_name','contact_mobile_no','contact_home_no','contact_email','contact_office_no'))
->where('pid = ?', $p_id)
->order('date_created DESC');
return $select;
}
}
after this i simple assign my result to my view.
note please
as its working but there is not private data members in my class,my class is not a blue print.there are no SETTERS AND GETTERS .how can i make my code that best suits MVC and OOP??
The most simple answer: you are already almost MVC. You use a Zend_Controller_Action to grab some data and pass this on to a view layer where you render the html. The only missing part is your model, which is mixed up between the controller and your data gateway (where you implemented a table data gateway pattern, that Zend_Db_Table thing).
I gave a pretty thorough explanation in an answer to another question how I'd properly set up the relations between Controller and Model. I also combined this with a Form, to handle data input, filtering and validation. Then to bundle some common functions, I introduced a Service layer between the Model and Controller.
With the controller, you perform some actions (list all my contacts, create a new contact, modify a contact) and the model is purely containing the data (id, name, phone, address). The service helps to group some functions (findContactByName, findContactById, updateContactWithForm).
If you know how to split Controller, Mode, Form and Service, your controller can become something like this:
class ContactsController extends Zend_Controller_Action
{
public function indexAction ()
{
if (!$this->hasIdentity()) {
$this->_redirect('login/login');
}
$service = new Application_Service_Contacts;
$contacts = $service->getContacts();
$paginator = $service->getPaginator($contacts);
$this->view->paginator = $paginator;
}
protected function hasIdentity ()
{
return Zend_Auth::getInstance->hasIdentity();
}
}
It is your personal taste what you want to do in your controller: I'd say you put as less as possible in your controllers, but you need to keep the control. So: a call to get data happens in the controller, retrieving this data happens somewhere else. Also: a call to convert a dataset into something else happens in the controller, the conversion happens somewhere else.
This way you can change the outcome in controllers extremely fast if you provided enough methods to your service classes to fetch the data. (Note I took the Zend_Auth to another function: if you have other actions, you can use this same function. Also, if you want to change something in your authentication, you have one place where this is located instead of every action in the controller)
keep one thing in mind when u learn new technology so first read thier own documentation. No one can explain better than them. Its hard to understand firstly but when you study it you will usedto and than u will love it like me Zend Offical Site
I'm using the MVC PHP framework Codeigniter and I have a straight forward question about where to call redirect() from: Controller or Model?
Scenario:
A user navigates to www.example.com/item/555. In my Model I search the item database for an item with the ID of 555. If I find the item, I'll return the result to my controller. However, if an item is not found, I want to redirect the user somewhere. Should this call to redirect() come from inside the model or the controller? Why?
No your model should return false and you should check in your controller like so:
class SampleModel extends Model
{
//Construct
public function FetchItem($id)
{
$result = $this->db->select("*")->from("table")->where("item_id",$id)->get();
if($result->num_rows() == 0)
{
return false;
}
//return result
}
}
and within your controller do:
function item($id)
{
$Item = $this->SampleModel->FetchItem($id);
if(!$Item)
{
redirect("class/error/no_item");
}
}
Models are for data only either return a standard result such as an key/value object or a boolean.
all logic should be handled / controlled by the Controller.
Models are not page specific, and are used globally throughout the whole application, so if another class / method uses the model, it might get redirect to the incorrect location as its a different part of your site.
It seems like the controller would be the best place to invoke your redirect because the controller typically delegates calls to the model, view, or in your case, another controller.
However, you should use whatever makes the most sense for your application and for what will be easier to maintain in the future, but also consider that rules do exist for a reason.
In short, if a coworker were to try to fix a bug in your code, what would the "reasonable person" standard say? Where would most of them be most likely to look for your redirect?
Plus, you said you're returning the result to your controller already... perhaps that's where you should make your redirect...
I have a MVC application that receives an input from a form.
This is a login form so the only validation that is necessary is to check whether the input is non-empty.
Right now before I pass it to the model I validate it in the controller.
Is this a best practice or not? Does it belong to the model?
I don't think there's an official best practice limiting validation to any single part of the MVC pattern. For example, your view can (and should) do some up-front validation using Javascript. Your controller should also offer the same types of validation, as well as more business-logic related validation. The model can also offer forms of validation, i.e., setters not allowing null values.
There's an interesting discussion of this at joelonsoftware.
I have been thinking about this for a LONG time and after trying putting validation in both controllers and models.... finally I have come to the conclusion that for many of my applications... validation belongs in the model and not in the controller. Why? Because the same model could in the future be used by various other controller calls or APIs... and then I would have to repeat the validation process over and over again. That would violate DRY and lead to many errors. Plus philosophically its the model which interacts with the database ( or other persistent storage ) and thus is sort of a 'last call for alcohol' place to do this anyway.
So I do my get/post translation in the controller and then send raw data to the model for validation and processing. Of course I am often doing php/mysql web applications and if you are doing other things results may vary. I hope this helps someone.
Validation must be in the Model
Only the model knows the "details" of the business. only the model knows which data is acceptable and which data is not. the controller just knows how to "use" the model.
for example: let's say we need the functionality of registering new users to our system.
The Model:
public function registerUser(User $user){
//pseudo code
//primitive validation
if(!isInt($user->age)){
//log the invalid input error
return "age";
}
if(!isString($user->name)){
//log the invalid input error
return "name";
}
//business logic validation
//our buisnees only accept grown peoples
if($user->age < 18){
//log the error
return "age";
}
//our buisness accepts only users with good physique
if($user->weight > 100){
//log the error
return "weight";
}
//ervery thing is ok ? then insert the user
//data base query (insert into user (,,,) valeues (?,?,?,?))
return true;
}
Now the controller/s job is to "use" the model registerUser() function without the knowledge of how the model is going to do the validation, or even what is considered "valid" or not!
the Controller:
$user = new User();
$user->age = isset($_POST['age']) ? $_POST['age'] : null;
$user->name = isset($_POST['name']) ? $_POST['name'] : null;
$user->age = isset($_POST['weight']) ? $_POST['weight'] : null;
$result = $theModel->registerUser($user);// <- the controller uses the model
if($result === true){
//build the view(page/template) with success message and die
}
$msg = "";
//use the return value from the function or you can check the error logs
switch ($result){
case"age" :
$msg = "Sorry, you must be over 18";
break;
case "name":
$msg = "name field is not correct";
break;
case "weight":
$msg = "Sorry, you must have a good physique";
break;
}
//build the view(page/template) with error messages and die
The class user
class User {
public $age;
public $name;
public $weight;
}
having an architecture like that will "free" the controllers completely from the details of the business logic -which is a good thing-.
Suppose we want to make another form of user registration somewhere else in the website (and we will have another controller allocated for it). now the other controller will use the same method of the model registerUser().
But if we distributed the validation logic between the controller and the model they will not be separated -which is bad and against MVC- meaning that every time you need to make new view and controller to register new user you must use the same old controller AND the model together. Moreover if the business logic is changed (we now accept teenagers in our sports club) you are going only to change the code in the model registerUser() function. the controllers code is still the same.
Its business logic, so no, it doesn't belong in the model.
Within the controller you have the ModelState property to which you can add validation errors to.
See this example on the MSDN.
Assuming your application is structured like:
Model-View-Controller
Service
Persistence
Model
The user input would come to your controller, and you would use services in the service layer to validate it.
Business Logic -> Controller
Data Validation -> Model