redundant implementation in CI controller - php

I wanna ask you best practices about blog front page.
I wanna build blog application using CodeIgniter framework. I have 2 type of page (front page, and admin page)
Supposed I have several controller in my front page (home, post, page, and link). By default I have include viewer of for all of these controller: header.php, footer.php, sidebar.php.
In the sidebar, I always display categories, recent comment, recent post, links, and archived.So .., In all of my front page controller I must implement select of categories, recent comment, recent post, links, and archived. Supposed I implement in all controller's constructor.
__construct () {
//data['categories'] = CategoryModel->getlist
//data['recent_posts] = PostModel->get_recent_post
//etc
can you suggest me, where I must place this method so I mustn't implement this method in all controller.
Thanks

You can write a base controller which the other ones inherit from
class AppStartup extends Controller {
function __construct() {
// whatever you need
}
}
then
class Home extends AppStartup {
// ....
}
Also you could start accepting some of the answer given to you, or people won't be so happy to help you.

The best way to do this is to create a MY_Controller and use $this->data instead of $data. That means all your controllers will run from MY_Controller (as long as you explicitley tell your controllers to inherit from it).
http://codeigniter.com/wiki/MY_Controller_-_how_to_extend_the_CI_Controller/

Related

Multiple Models Across A Layout in CakePHP

What is the best way to achieve the following in CakePHP?
I have a layout which like many others has 3 major sections, a header, a footer and the main content. The header and footer aren't completely static and are implemented as Elements, it has hit counts and some other dynamic stuff. This dynamic stuff isn't related to the main content in any way but is more related to the overall site.
For this I think the footer needs to have a model of its own, can I have the footer run on a different controller/action than the main content? Else, I guess I would need to put the footer model in the main view's model and than pass to the footer element, which doesn't seem the neatest way.
To put it in different words, the header, the footer, the main content and possibly a few more sidebars are totally independent of each other, but are rendered from the same layout. The model that is passed from the controller to the view/layout would need to have the models needed for the header/footer/content/sidebars?
I explored and found that requestAction might be a way, but did not convinced if that's the best way. May be I haven't looked at the right places yet.
Just add what you need inside the beforeRender method of your AppController:
class AppController extends Controller {
public function beforeRender () {
$this->set('number_of_visists', /* ... */) ;
}
} ;
So you'll get the value on each page, then you can either put everything inside your layout file or split it in multiple element but you'll have access to $number_of_visits everywhere.
Edit: Little edit to answer your comment. This is one way of doing what you want, may be not the most "correct" but the first which came to my mind. I didn't test this so it may contains some mistakes...
You could use components: Let's say you have three component, one for the header, one for the footer and one for the menu.
In your AppController:
class AppController extends Controller {
public $components = array('Header', 'Menu', 'Footer');
} ;
Then your components (I'll show only one example):
class FooterComponent extends Component {
public function beforeRender(Controller $controller) {
$visitModel = ClassRegistry::init('VisitCounter');
$controller->set('number_of_visits', $visitModel->getNumberOfVisits()) ;
}
}
Then in your layout you just use elements:"
<html>
<!-- Whatever you want... -->
<?php echo $this->element('footer') ; ?>
</html>
Every developper can work on his own component (and the associated models) and his own element without disturbing the other ones.

Code Igniter - Best Practice for views to not violate DRY

Trying to determine the best way to handle views in codeigniter. Right now anything I consider seems too messy.
Currently I have 3 relevent views:
1) Header
2) Content
3) footer
Every single controller has something like this. Some controllers even have this several times (different functions in the same controller):
$this->load->view('head', $data);
$this->load->view('volunteers/add_profile.php',$content_data);
$this->load->view('foot');
It seems pretty silly to have to load header and footer on EVERY single page. However, each page will have slightly different data in the header (meta tags, style sheets, loaded scripts, etc).
Is there a cleaner way for me to do this?
Thanks!
I like to create a parent controller with a method like renderPage('content_view', $data). That method can include the header, menu, footer, ... That way, all the view loading stuff is kept in the controller and I don't have to bother with header, menu or footer on every action or view. It's also flexible as your child controllers can redefine the renderPage() method to fit their purposes.
If you need to load multiple content views, you could create a renderPage() method that takes in an array of string instead of a string.
Yes - have a template view. In your controller:
$data['header'] = xxx;
$data['content'] = xxx;
$this->load->view('my_template', $data);
Then in your my_template.php view file:
$this->load->view('head', $header);
$this->load->view('volunteers/add_profile.php',$content);
$this->load->view('foot');
Either what #TheShiftExchange suggested, or, if your application allows it, you can call header and footer views from each content view (which is the only view called from the controller then).
I've created my own controller where I create MY_Controller extends CI_Controller class then in MY_Controller I use access modifier $data and $loadviewArray.
public $data = array();
public $loadviewArray = array();
after this I create function in MY_Controller
public function loadview() {
foreach ($this->loadviewArray as $key => $val) {
$this->load->view($val, $this->data);
}
}
then I create controller Admin and extends MY_Controller like this Admin extends MY_Controller in Admin controller create function index.
public function index() {
$this->data["page_title"] = "Login";
$this->data["records"] = $data; // You can pass data
$this->loadviewArray = array("admin/header", "admin/login", "admin/footer");
$this->loadview();
}
In $data access modifier array I pass data at views and in $loadviewArray load views then call a function for loading views you can do like this also its very helpful for me now. And create header and footer views seperate...
please check https://github.com/alzalabany/codeigniter-base-controller/tree/master
So you can always use a templating lib. yet i dont like them for some reason !
codeigniter allow you to extend its core; if you go to link mentioned above u can see a small example
in this example every controller that will extend MY_controller will start with these defauls
protected $body='base/body',
$title='Codeigniter Z master',//txt
$js=array(),//filename
$inline_js='',//script
$css=array(),
$inline_css='',//style
$breadcrumb=FALSE,//<li><a>
$content=array(),//html
$noEcho = FALSE;
so if u chose to change them in MY_controller its effect will be default, otherwise use $this->title = 'Codeigniter - welcome page'; in ur controller constructor for example;
loading assist is a very easy job just call $this->_assets() and location of asset (edit MY_controller.php default location to you assets folder); if its an inline_js/css just call
$this->_assets('alert("hi");','js');
if you want to load a view into a page section use $this->outv(view_path,view_data,section_name);
and if you want to just load html into a variable u can use
$this->out('Footer','footer');
at end just call ->_flush();
some other options i use like
$noEcho ; if set it will clear all buffer to remove any echo's before it send your view content to browser;
you can also set functions like log-out or log-in inside MY_controller and it will be accessible by any of ur controllers http://localhost/ci/welcome/logout
any way :) i hope that answers your question !

How to call controller function in other php file - codigniter

First just look at my code than i will explain my problem.
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
class Category extends CI_Controller {
function Category()
{
parent::__construct();
$this->load->model('category_model');
}
public function index()
{
}
public function _left()
{
echo "side";
$data['all_categories'] = $this->category_model->getallcategory();
$this->load->view('include/left', $data);
}
}
this is my category controller, i have a left() function in which i listed all category in the left bar of my website.
I just want to know that how can i show left() function data in another php file ?
You really shouldn't have a function you would call repeatedly or from another file in a controller... typically you would want to put them in a Helper library or as a Plugin...
For the function you have created, I am wondering if you know that you can have a view, that calls other views. For example, you have a template view that would load the header view, the view referenced in $data from your controller, and your left view, etc...
I would read more about MVC and how it's setup and how you lay out your files a bit more as it will save you a huge headache and some messy code.
Best of luck!
you call create one function and call many view from this.
or create one main view and other top,left ,right,center view and load from main view
I would consider writing a helper and autoloading it in your config file
For more information about creating helpers go here CodeIgniter: Create new helper? or check CodeIgniter's user guide.
DISCLAIMER: THIS IS A RANT
I know everyone is trying to be "helpful" but please, please, please stop using "helper" classes and "helper" files. Models get there own data, they persist their own data, in short, they do the helping!!
Ex:
DO NOT create a file called "userhelper.php", just put the methods in a file called "user.php". This is called a model. You might say at this point, "What if I need to share the model with another part of my project or just somewhere else but make it look different or something or whatever??" That's where you would use a viewmodel. The viewmodel has no persistence information in it, in fact it should be significantly different from the model enough to justify its own existence.
To wrap up, just put the CRUD into the model itself. Don't build "managers" or "helpers' or whatever the hell you want to call them.
And I don't care if CodeIgniter encourages this with it's "helper" framework. It's still WRONG and is not OOP. You will end up writing messy code and duplicating effort all over the place.

Pagination in PHP MVC

I've written a small MVC in PHP5 and desire a pagination module to be added to some files in my views section/folder..
I was wondering.. would the Pagination class be included in the Controller or Models section/folder?
Currently i've included it in the Models folder and called the function when needed..
The way I see it, pagination is a control, allowing user to tell your database (model), which portion of data he or she wants to see.
So I would go with the Controllers module.
Well, I think a better approach would be to make a helpers folder and then load them into your application like this :
function use_helper()
{
static $helpers = array();
foreach (func_get_args() as $helper)
{
if (in_array($helper, $helpers)) continue;
$helper_file = HELPER_PATH.DIRECTORY_SEPARATOR.$helper.'.php';
if (!file_exists($helper_file))
throw new Exception("Helper file '{$helper}' not found!");
include $helper_file;
$helpers[] = $helper;
}
}
Then all you have to do is build a pagination.php file with your Pagination class.
When you need it, you call the function
use_helper('pagination');
From here of course it depends on you Pagination class.
Hope this helps.
i guess the best approach is to call the pagination from the view, referring to this MVC
A view queries the model in order to generate an appropriate user interface
(for example the view lists the shopping cart's contents).
The view gets its own data from the model.
In some implementations, the controller may issue a general instruction to the view to render itself.
In others, the view is automatically notified by the model of changes in state (Observer) that require a screen update.
and because you will be using this class almost in every view, you should make a helper and include this class inside that helper so that all the views can share its methods

MVC - Can I call more than one (or multiple) controller in class controller?

For projects written in php, can I call more than one (or multiple) controller in class controller? Example in http://img192.imageshack.us/img192/7538/mvc03.gif
ASK: I need to call an action from another controller... And if I do like the picture above, I'm being out-ethics?
Thanks,
Vinicius.
I'm sure that you can do what you want with whichever framework you're using. If you can't do it natively for whatever reason, then you can extend your framework as required.
Having said that, I personally don't like the idea of a controller calling another controller. It seems to somewhat break the MVC paradigm if only from a theoretical standpoint. What I might do instead is build a library class that contains the functionality required and then have both controllers instantiate that class as a member and call the functions required.
For example, using CodeIgniter:
libraries/MyLib.php:
class MyLib
{
public function MyFunc()
{ /* do whatever */ }
}
controllers/ControllerA.php:
class ControllerA extends Controller
{
public function index()
{
$this->load->library('MyLib');
$this->mylib->MyFunc();
}
}
controllers/ControllerB:
class ControllerB extends Controller
{
public function index()
{
$this->load->library('MyLib');
$this->mylib->MyFunc();
}
}
out-ethics? Anywhose... back to reality.
Yes, a controller can call another controller's action. For instance, in cakePHP, this functionality is afforded via requestAction
// pass uri to request action and receive vars back
$ot3 = $this->requestAction('/stories/xenu');
If you're rolling your own, the details of how to implement it will be very specific to your framework.
then you need to modify framework, find place where controller is lounched and add there your second controller.
what framework you are using?
You can do it any way that you want. You don't have to use MVC if you don't want to. However, in MVC you really should only have one controller active at a time. You probably want multiple Views or Models, not another Controller. There is nothing at all wrong in loading, say, a header and footer view for the menu and footer of the site.
If you are building another Controller, then feel that you need to access the functionality of a previous Controller to access its functionality (because it works with a specific / desired Model), then the Model you developed for the latter probably needs to be refactored. IN plain speak, your target Model may be doing too much. Break it up.
You are trying to avoid repeating yourself (DRY) by using calling the methods of a Controller that has already been developed, but in doing so your are creating TIGHT coupling between both controllers! If something changes in the borrowed controller, it will have an effect on the borrowing controller. Not good, Dr. Jones.

Categories