Best structure Codeigniter, constant top menu - php

Maybe a HMVC structure would have been best when I look back.
I load the following views in every controller.
$this->load->view('header');
$this->load->view('DEPENDING');
$this->load->view('header');
In my header-view I have a menu which I show Home | Inbox | Contact us and so on. Now I want to load how many new messages you have like this Home | Inbox (4) | Contact. If Im not wrong the 4 most be loaded thorugh a query every time. Which I then need to include a call to a model in EVERY controller. Like e.g.
$inbox['new_messages'] = $this->Call_the_model->get_new_messages(); // user id go through session
$this->load->view('header', $inbox);
$this->load->view('DEPENDING');
$this->load->view('header');
Am I right? Is there simple solution for me to use - even if Im not using HMVC?

One of the ideas is -
http://ellislab.com/codeigniter/user-guide/general/core_classes.html
class MY_Controller extends CI_Controller {
function __construct()
{
parent::__construct();
//load your model
$inbox_new_messages = $this->Call_the_model->get_new_messages();
//save in session
$this->session->set_userdata('sess_inbox_new_messages', $inbox_new_messages);
}
}
then just extend your controllers with new MY_Controllers and
class Welcome extends MY_Controller {
function __construct()
{
parent::__construct();
}
}
in your view files - check if that session variable is set and display the number.
Hope that helps.

Related

How is the right way to implement login on CodeIgniter?

I'm practicing Codeigniter framework using a small project from my friends. Each pages need to load layout view and content view separately. The layout show users login info (logged or not, name, picture, etc.). The question is, how to show login info for each action efficiently? Most of the action will load the layout view, so i need to do that right.
I do implement a helper to get user model, but is that right?
You can use the following method:-
In one separate model constructor function check the login details
class Auth extends CI_Model {
public function __construct(){
parent::__construct();
$this->load->model('loginModel');
$this->load->library('session');
if(!$this->loginModel->isLogin()){
$this->session->sess_destroy();
redirect('index.php/auth/login','refresh');
exit;
}
}
}
Then in required controllers include the model in the controller constructor function
class Main extends CI_Controller {
public function __construct(){
parent::__construct();
$this->load->model('auth');
}
}
No need to check all the controller action's if you added in the controller constructor it will check for all the actions
Frist Create Login Controller, in that controller
Ask User to login
Check if password is correct. If yes, set session value (say user_id) & redirect to User Controller.
Second Create User Controller, in that controller's constructor function
Check Session user_id exist or not. If no, redirect to login.
It is best to check at constructor because it will check for all the methods in that controller.
Hope it helps.

Passing data to the view through the constructor method in Codeigniter

I am currently using the codeigniter tank_auth, at the start of every controller method I have to do the following:
$data['profile'] = $this->tank_auth->get_profile();
The main reason I do this is to display the current logged in username, and also get their privilege level.
I am going over the code trying to go by the DRY principle and have moved a lot of repeated code over to the _constructor method (Like checking if the user is logged in). I am just wondering if there is a way to move this code from the start of every method to the constructor.
My current constructor method looks like so:
public function __construct()
{
parent::__construct();
// If the user isn't logged in redirect to login page.
if (!$this->tank_auth->is_logged_in())
redirect('auth/login');
}
Thanks!
Add variable $data to the controller and use it for all your view data. For example:
public function __construct()
{
parent::__construct();
$this->data['profile'] = $this->tank_auth->get_profile();
}
When calling the view remember to call it like this:
$this->load->view('my_view', $this->data);
You can also extend CI_Controller with MY_Controller and put the login check in the constructor of MY_Controller. Just extend all controllers which need this check from MY_Controller instead of CI_Controller.

Code Igniter - how would you structure this site?

I'm going to do my first site in code ignitor, a fairly basic site like this:
home
login / register
members area
protected page 1
protected page 2
protected page 3
general info section
page 1
page 2
page 3 (dynamic table of reports)
about section
page 1
page 2
blog section
listing
article page
I've gone through a couple of basic tuts and have read some of the documentation but still feel unsure on what would be the best way to structure this. Could anyone that is experienced with CI show me an example of how they' do it?
some specific Qs are:
header with nav panel will be the same on all pages. normally i'd code that as an include with if/else to show highlighted current section. I guess I'd just keep this as an include (view) and either load it first via the controller or include it in every view?
I'd envisage having a model called 'user' which will handle the login and registration, a model called 'blog' and a model called 'reports'. Does that sound right?
for static sections like about, I guess there'd be no model and i'd just have a controller with a function for each static page? i.e. about.php with page1(), page2() and all they do is load static views?
1 -> To fix this problem, I decided to use my own controller like this
Using CI 2.x, create a file under app/core called MY_Controller.php like so :
<?php
class MY_Controller extends CI_Controller {
function __construct() {
parent::__construct();
}
public function loadView($view) {
$this->load->view('header');
$this->load->view($view);
$this->load->view('footer');
}
}
And then I extend this controller instead of the CI one. Be sure that your $config['subclass_prefix'] = 'MY_'; in the config.php file.
2-> yes
3-> thats about it :D
I'm a newbie here (codeigniter) but:
For headers/footers I adopted the template strategy from here (first alternative). Worked nice.
Before models, I'd plan the controllers -roughly one per each section. I made all them inherit from a MY_controller here I place common funcionalilty. And yours models seems about right to me. I think them rathar as DAOs, or "service objects" that provide access to the database and not much more. GEneral intelligence of the site (if needed) should be in a custom library, or inside the controllers.
Yes.
You should use an CI library to handle your user registration and per page authorisation.
Here's a very simple example on how you could do it. Keep in mind that CI uses the MVC pattern
class Reports extends CI_Controller {
public function __construct() {
parent::__construct();
// load database if needed
// load a model if needed
}
public function page() {
//get the page requested
$page_id = $this->uri->segments(2);
// based on the page_id do something.
$data['somedata'] = 'About us data here';
// this is an actual file loaded from the template view
$data['maincontent'] = 'my_page';
$this->load->view('template',$data);
}
}
class About extends CI_Controller {
public function __construct() {
parent::__construct();
// load database if needed for this page
}
public function page() {
// same here
//get the page requested
$page_id = $this->uri->segments(2);
// based on the page_id do something.
$data['somedata'] = 'About us data here';
// this is an actual file loaded from the template view
$data['main_content'] = 'my_about_page';
$this->load->view('template',$data);
}
}
in the template file
$this->load->view('template/header');
$this->load->view('template/nav');
$this->load->view($main_content);
$this->load->view('template/footer');

All admin/user functions checking if he/she is logged in - How to avoid this?

I am very, very new with MVC (just started yesterday) so this question is probably stupid, but I need to know how to check automatically if user is logged in on my functions that are in admin/user models.
I can put the checking in construct, this would help, but I have several models and maybe there is some even better way. I hope you will understand better what I want after you see my folder structure and code. Oh, and by the way - I use Code Igniter 2.0
Folders:
controllers/
../admin/
../../item.php
../../cat.php
Let's see my item.php file...
<?php
class Item extends CI_Controller
{
function Index()
{
//Checking if admin is logged in on every function is bad
/*
* Is it possible to somehow make all admin functions go through
* some kind of Admin class that will check automatically?
*/
$isLogged = $this->session->userdata('is_logged_in');
if ($isLogged == true)
{
$this->load->view('admin/item/main');
}
else
{
$this->load->view('admin/login');
}
}
function Add()
{
$this->load->view('admin/item/add');
}
function Edit()
{
$this->load->view('admin/item/edit');
}
function Delete()
{
$this->load->view('admin/item/delete');
}
}
I hope that this is easy question, thanks in advance :)
I would implement the login-function in CI_Controller.
Then I would set an protected variable in Item protected $loginRequired = true;.
In function __construct() or Item() I would call parent::isLoginRequired($this->loginRequired) which checks if a login is required.
I would also redirect to a specific login page with a parameter which redirects the user back to the page he needs to be logged in.
Make a new class, for example, My_Controller extends Ci_Controller and write some auth checker code in it... in controller file just extend My_Controller
what i usually do is -like Teeed recommends- Create my own controller Class which is between the CI_Controller and each controller you might create.
In that class (MY_Controller) you can instantiate a model which handles all user related data and logics (loading session data, executing specific checks, etc..) and finally set as class variables those results, so you will end up having:
$this->isLogged ;
$this->isPaying ;
$this->isPlatinumMember ;
etc..
in any of your classes extending from MY_Controller
that makes very easy to check any condition within any of your Controllers.

How to make user object available across pages in CodeIgniter?

I'm fairly new to CodeIgniter and I'm using Ion Auth for user authorization. With the Ion Auth library, you get a user object like:
$user = $this->ion_auth->get_user();
echo $user->email;
If a user is logged in, I want the $user object to be available on any of the pages (in any of the controllers). How can I do this? (I'm using CodeIgniter 2)
This blog post of mine goes into a lot of detail in specifically using Ion_Auth to allow your entire application (including views) to access your current user's information.
The short version... (specifically for the topic at hand)
Adding this to your MY_Controller.php file
class User_Controller extends CI_Controller {
protected $the_user;
public function __construct() {
parent::__construct();
if($this->ion_auth->logged_in()) {
$data->the_user = $this->ion_auth->get_user();
$this->the_user = $data->the_user;
$this->load->vars($data);
}
else {
redirect('/');
}
}
}
Then in your application just create your controller like this
class App_Controller extends User_Controller {
public function __construct() {
parent::__construct();
}
function index() {
//do stuff
}
}
Then not only in your controller will you have access to $this->the_user but you will also have $the_user loaded into every view with $this->load->vars()
Normally you'd cache something like this in the session, however I've moved away from that in most of my CI apps.
An example: you log the user in (caching the user data) and then they go to update their email on their profile page. You now have to reload you cache. Many other things could drive this reload. Usually the most I cache any more is the ID, then I do what you're doing and get the user's data on any page I need it.
One thing I found that helps is to have base controllers. For example I have a RegisteredUserController. Any controller whose actions all require the user to be logged in extend this. That way I can keep the logged in check and things like get the user data in one spot (in the constructor). For example:
class RegisteredUserController extends CI_Controller {
var $user;
function __construct() {
parent::__construct();
$this->user = $this->ion_auth->get_user();
}
}
Then any controller that extends RegisteredUserController instead of just controller can get to the user with $this->user. Following this pattern would get it on every page (that extends the controller) without resorting to caching.

Categories