I have been using Codeigniter for a while, and I would like to have business objects that handle the logic, something like this:
$comment = new Comment($this->input->post());
$blog = new Blog();
$current_post = $blog->get_current_post();
$current_post->add_comment($comment);
$data['current_post'] = $current_post;
$this->load->view('post_view',$data);
Instead of this approach:
$this->load->model('comment_model');
$this->load->model('blog_model');
$this->load->model('post_model');
$comment = $this->comment_model->create_from_array($this->input->post());
$blog = $this->blog_model->get_blog();
$current_post = $this->post_model->get_current_post($blog);
$this->post_model->add_comment($current_post,$comment);
$data['current_post'] = $current_post;
$this->load->view('post_view',$data);
What you want is changing how codeigniter works, without loading models how will it know where to fetch the data from? If you want to do it the way you suggested you are going to have to extend the Core controller class and make alot of assumptions about your code. For example when you make a new instance Comment() it should load a model, and an argument passed to it should access a certain method in that model.
You will simply be making a nice wrapper for the functionality that exists already, which is fine, but in the end you code may look nicer but it will still work the same.
Related
I am stuck with it and i couldn't find any appropriate solution for this. what i want to achieve is in my admin panel based upon check box value i want to change active status of specific control and update database value using ajax. I want to make a common ajax function in controller to avoid repeatedly writing same ajax function for other controls like menu manager content manager, documents manager etc.So i want to send Model name to the ajax controller so that same function can be used. Ajax call is working perfectly but couldn't make appropriate models. for example:
$m = new App\Model.$request->model OR $m = 'App\Model\'.$request->model (adding last \ gives an error) or answer provided in Dynamically use model in laravel is not helping either. Is there any better ways if yes please suggest. I can do this below but it is hardcoded so i want to make model dynamic models
if($request->model ==='Menu')
$model = new \App\Http\Models\Menu;
else if($request->model === 'News')
$this->model = new \App\Http\Models\News;
else if($request->model === 'Document')
$this->model = new \App\Http\Models\Document;
Thankyou !!!
You can just use:
$modelName = '\\App\\Http\\Models\\'.$request->model;
$this->model = new $modelName;
However you should add validation to make sure only some allowed models would be used or at least do something like this:
if (! in_array($request->model, ['Menu', 'News', 'Document']))
{
throw new \Exception('Invalid model');
}
$modelName = '\\App\\Http\\Models\\'.$request->model;
$this->model = new $modelName;
This is because you don't want to expose probably all the models data for security reasons.
Try the below code
if($request->model){
$m = '\App'. '\' .$request->model;
//other code
}
I have a piece of data I want passed to every view. I am using CodeIgniter 3 and have PHP 7 available to me. The current way I do it is using something like this in every function.
$data['foobar'] = $this->general_model->foobar();
// More code
$this->load->view('homepage', $data);
I'd prefer not to have to call $data['foobar'] = $this->general_model->foobar(); on every single function.
I've tried many approaches to fix this without resorting to anything that makes the code too goofy. I've tried constructors, autoload, and hooks. The problem in each case boils down to the fact that $data is local to each function. The best I've gotten is usually something like this.
$data['foobar'] = $this->foobar;
// More code
$this->load->view('homepage', $data);
This is slightly nicer, but it still results in me placing this line in every function.
I'd like my functions to in someway inherit $data with the index foobar already set. I'd prefer to avoid a solution that requires every function receiving $data as a parameter. How can I accomplish this?
Option 1:
Not sure if you have tried this but you could set $data as a property of your class
protected $data = [];
Then in your constructor set it.
$this->data['foobar'] = $this->general_model->foobar();
This would mean your $data becomes accessible to all your methods in your controller and you would need to refer to them as $this->data['data_name'] and use it in a view like
$this->load->view('homepage', $this->data);
Option 2:
A second way is to create a method like render() which is common to all your methods that load views and replaces your existing view calls.
So you would have something like...
public function one_of_my_methods(){
$data['content'] = 'This is content 1';
$this->render('test_view',$data); // Call the new view handler
}
// All methods using views now call this to load the final view
public function render($view,$data){
$data['foobar'] = 'I am common'; // DRY
$this->load->view($view, $data);
}
I am experimenting with using the MVC pattern to set local vars in some code ie
$action=basename(__FILE__, '.php'); // load action from filename for consistancy (index for this case)
$controller = new seoController($action . '-seo'); // register controller with page action and parameter
$controller->invoke(); // invoke controller for processing
$page_title = "<insert page title here>";
$page_desc = "<insert page desc here>";
$page_keys = "<insert page keywords here>";
Of course the controller calls the model and does all the backend stuff parsing the input, getting the data and then returning.
What I would like is a clean way to set the local $page_title etc vars from the seoModel that is instantiated in setController without using the $_SESSION or any other hacky kind of way.
Is it ok from a design POV to put methods in the controller to get the info? ie
$page_title = seoController->getPageTitle();
My controllers as of now are not being used in this type of way as all they do is connect my models to the views.
I hope I'm being clear enough with my explanation.
Is it ok from a design POV to put methods in the controller to get the info?
Yes, thats what Controller is meant for.
What I would like is a clean way to set the local $page_title etc vars from the seoModel that is instantiated in setController without using the $_SESSION or any other hacky kind of way.
To avoid using $_SESSION that seems to be a bit overkill for this particular case you can set seoController attributes, for example,
Class seoController
{
$public $page_tile = '';
public method getPageTitle()
{
$model = new seoModel();
$page_title = $model->get_page_title();
$this->page_tile = $page_title;
//you could also return the page title here, skipping that
}
}
And access them from the caller
$controller = new seoController;
$controller->getPageTitle();
$page_title = $controller->page_title;
You would normally have things like meta tags stored with the model it’s describing. So if you’re loading say, a product from a model, then that model may also return the meta tags for that product:
public function show($productId)
{
$product = $this->productModel->findById($productId);
// Meta title may be available at $product->meta_title
return new ViewModel(array(
'product' => $product,
));
}
Your controller action would then return the data needed to be displayed in a view, which could be a HTML template, JSON, XML etc.
In a joomla custom made component there are multiple posts on a page, and every post contains multiple comment, so in view i want to call comments by post id. please suggest a good method to make it working.
You have two options. The first, is to attach the comment id as a URL paramater and retrieve it within the model as needed like so:
$comment_id = JRequest::getApplication()->input->get('comment_id');
If you wish to pass in a parameter when calling the model from the view class, you need to get an instance of the MVC path model instead of using the short cut method. So, instead of using this in the JView class:
$this->items = $this->get('Items');
You would do this instead:
$model = $this->getModel();
$this->items = $model->getItems($comment_id);
Hope this helps.
Using PHP, If I have a model (a class) where I various queries, whatever I need, and in my controller, I use myModel = new CustomerModel(); and later in the controller, say I call myMyodel in the controller (I know looks like codeigniter but I am not using a framework) to:
$data['query'] = myModel.OrderByLastName();
how do I pass that $data['query'] to a view, a separate .php page?
I don't wan to echo anything from my controller.
Also, was hoping this design, the way I explained it makes sense. Or am I wasting time with the model class?
Typically, you'd instantiate a view object:
$view = new View();
Pass it the info it needs():
$view->set($name1, $value1);
$view->set($name2, $value2);
...
Then invoke the view's renderer:
$view->render();
The way Django works is the controller basically renders a template using a templating system. It passes the data in Contexts, like this:
data['query'] = myModel.OrderByLastName();
context = {'data': data['query']}
page = loader.get_template('folder/template.phtml')
return render_to_page(page, context)
roughly.
Obviously, you're writing your own system so you've got some room on exactly how you implement it. I don't know if that's exactly what you want, but it might give you a workable idea.