I'm re-writing an application previously written in CodeIgniter framework, my customer want have an independent app and a pure php code. Anyway don't tell me not to reinvent the wheel because I already know that my client is wrong. We come to the problem.
I'm looking for a simple Route class that allow me to call any files from any location. I found this simple and powerfull class, this is the repository.
I've implemented it in my project, copy the route.php file inside the index location and change my .htaccess as the documentation says. Instead of all, this is the structure of my project:
/ PUBLIC_HTML
/ application
/ controllers
/backend.php
/user.php
/ helpers
/ models
/ views
/backend
/backend.php
/calendar.php
/user
/users.php
/panel.php
/ assets
/ files used by frontend...
/ system
/ configuration
/ constant
/ .htaccess
/ index.php
/ route.php
when the applicationi is started from the index.php the configuration file is included for establish the connection with the database. In the same configuration file I've imported the route.php. Now my index.php page is very simple, like this:
// Check if the session is set
if(isset($_SESSION['user_info']['id_roles']))
{
switch($_SESSION['user_info']['id_roles'])
{
case 1: //Admin
$route->add('/application/controllers/backend', 'index');
$route->submit();
break;
case 2: //Provider
$route->add('/application/controllers/backend');
$route->submit();
break;
case 3: //Customer
$route->add('/application/controllers/appointments');
$route->submit();
break;
}
}
else
{
// Session isn't set, so I redirect user to login page
header('Location: application/views/user/login.php');
exit; // stop
}
so if the session is set I redirect the user type to the correct location, against, if isn't set I show the login page. The login page simply valorize the session variable, if the response is success the user is redirected again to the index page.
The problem now is that, for example when the admin is logged (so case 1), the route class doesn't valorize the $uri, a bit example:
public function submit()
{
$uri = isset($_REQUEST['uri']) ? $_REQUEST['uri'] : '/';
$uri = trim($uri, $this->_trim);
$replacementValues = array();
// Iterate on the list of URI
foreach($this->_listUri as $listKey => $listUri)
{
// Looking for a match..
if(preg_match("#^$listUri$#", $uri))
{
// Replace the values
$realUri = explode('/', $uri);
$fakeUri = explode('/', $listUri);
// Get value with .+ with real URI value
foreach($fakeUri as $key => $value)
{
if ($value == '.+')
{
$replacementValues[] = $realUri[$key];
}
}
// Pass array arguments..
call_user_func_array($this->_listCall[$listKey], $replacementValues);
}
}
}
check the full class here.
the $uri variable should be valorized with the current uri of the server but I tried with a var_dump and I get an empty value.Then the match condition is never invoked, and the correct file isn't displayed. I don't know why, I just want to understand why it is not working, I'm probably doing something wrong, someone can help me understand?
Completing the example of the admin redirect, I want to show only what is contained in the backend.php, which should be loaded from the route.
<?php
session_start();
class Backend
{
// Construct of class
public function __construct()
{
}
// Display the main backend page
public function index($appointment_hash = '')
{
$_SESSION['user_info']['hash'] = $appointment_hash;
$_SESSION['user_info']['dest_url'] = SystemConfiguration::$base_url . "backend";
// some content..
}
...
So how you can see, I simply want call the index function of the backend controller when I call ->add() for add the url of the controller to call, and ->submit() to perform the operation.
What am I doing wrong?
UPDATE - Router request task
First I updated the stack of my application.
I think at this point it's best to ask your expert advice on which OpenSource Router allow me to implement this tasks:
1. Import controller
Import all controllers that are contained in my folder called controllers. Once you imported I will simply call the instance of the router, and call up a specific function of the controller loaded. Example:
$router->backend->index();
where index(); It represents the function of controller called backend.
This must be done in my entire application. Also I would make sure that we can bring up the function also via the URL, in particular, if I insert this url:
localhost/application/controllers/backend/index
I can call the same function simply referring url.
2. Requests ajax
Delivery My Router must be able to run ajax requests from javascript, especially if I use this code:
$('#login-form').submit(function(event)
{
var postUrl = GlobalVariables.baseUrl + 'user/ajax_check_login';
var postData =
{
'username': $('#username').val(),
'password': $('#password').val()
};
$('.alert').addClass('hidden');
$.post(postUrl, postData, function(response)
{
I want to call the user function ajax_check_login.
contained in the controller user, imagine GlobalVariables.baseUrl, what is... How can we think is the url of the base application that can obviously vary.
Note that my Controller function return a json format.
3. Load view
in my application there is the view, which are saved in .php, but containing html file, an example of view (previously written in CodeIgniter) pul you find here.
I want to be able to call a view and show the new user html markup. I also need to call also more views at the same instant, for example at times I divide the body into:
header, body, footer
To simplify the understanding of what $this refers to in a view, since a view is "loaded" by a controller method, the view is still run in the same scope as that method, meaning $this can have a different context depending on which class loaded it.
For example:
class Controller1 extends CI_Controller {}
In any view file loaded in this example controller, $this refers specifically to the Controller1 class, which can access CI_Controller public and protected properties/methods as well (like the Loader or Input classes, which are assigned to the load and input properties of CI_Controller) since it extends that class.
Controllers are still just plain old PHP classes. If I were to do this:
class Controller1 extends CI_Controller {
$this->foobar = 'Hello';
}
class Controller2 extends CI_Controller {
$this->foobar = 'World';
}
...if we load the same view file in any method of either of these controllers, using $this->foobar in that view file will return a different value.
But this for now it's not important, I just want to be as clear as possible.
I start a bount and lose all my rep, but I really want to get help in this and learn.
You need to look at the index.php provided with the Router as an example. You'll see how to set the routes:
you always have to have 2 arguments: 1. uri, 2. function
according to the example the function has to be not the function name 'index', but a function body function(){...}. Maybe reference would work as well.
Routing IMHO should be not dependant on session (though it could be, but that's not the usual way to do)
instead of $router->backend->index();, I will have a common block of code at the end of the file so you don't have to copy&paste the code many times.
I'll show you with backend in your way, and then with appointments how could you make it general. So you should make your routes something like:
<?php
session_start();
include 'route.php';
$phpClass = false;
$view = false;
$func = false;
$route = new Route();
if(isset($_SESSION['user_info']) && isset($_SESSION['user_info']['id_roles'])) {
$route->add('/application/controllers/backend', function(){
echo 'You are now at backend page, and the role is ';
switch($_SESSION['user_info']['id_roles']) {
case 1: echo 'Admin'; break;
case 2: echo 'Provider'; break;
case 3: echo 'Customer'; break;
}
include 'backend.php';
$backend = new Backend();
$backend->index(/* I don't know what 'hash' could be */);
});
// more general case:
$route->add('/application/controllers/appointments', function(){
// we only set the global $phpClass variable, and the rest is common, see below
global $phpClass, $func;
$phpClass = 'Appointements';
$func = 'index'; // default is index, if it wasn't given on the url
});
$route->add('/application/controllers/appointments/add', function(){
// we only set the global $phpClass variable, and the rest is common, see below
global $phpClass, $func;
$phpClass = 'Appointements';
$func = 'add';
});
$route->add('/application/controllers/appointments/delete', function(){
// we only set the global $phpClass variable, and the rest is common, see below
global $phpClass, $func;
$phpClass = 'Appointements';
$func = 'delete';
});
$route->add('/application/controllers/foo', function(){
global $phpClass;
$phpClass = 'Foo';
});
$route->add('/application/controllers/bar', function(){
global $phpClass;
$phpClass = 'Bar';
});
$route->add('/application/views/bar', function(){
global $phpClass, $view;
$phpClass = 'View';
$func = 'show';
$view = 'bar.php';
});
$route->submit();
} else {
// Session isn't set, so I redirect user to login page
header('Location: /application/views/user/login.php');
exit; // stop
}
if ($phpClass === false || $func === false) {
die("You have to have both controller and function un the url");
}
// if we got here it means we're in the common case
// include the necessary controller. If you want you can
// include all of them at the top of the php and remove this line
include 'application/controllers/' . strtolower($phpClass) . '.php';
$controller = new $phpClass();
// this is instead of `$router->backend->index();`:
$controller->$func(/*$hash*/);
// I don't know what '$hash' could be, maybe javascript could send it via ajax
?>
controllers/view.php:
class View {
public function show() {
global $view;
include 'application/views/' . $view;
}
// here you'll need to have all the things that any of
// your views access as $this->bar :
$config = new stdClass(...);
$array = array();
function get_lang() {global $lang; return $lang;}
//...
}
Example of json response in controllers/user.php:
class User {
public function logged_in() {
$username = isset($_SESSION) && isset($_SESSION['username']) ? $_SESSION['username'] : false;
$response = array(
'success' => $username !== false ? 'OK' : 'ERROR',
'username' => $username
);
echo json_encode($response);
}
}
Related
I can have the following urls
www.example.com/accounts/
www.example.com/accounts/signup
www.example.com/accounts/signup/validate
www.example.com/accounts/login
for each case, accounts becomes my controller, and index, signup, signup and login becomes my actions (or methods) respectively. I have to render different views based on what my actions are. Here is an example of what my code looks like
index
$url_segments = explode('/', $url);
$controller = !empty($url_segments[0]) ? $url_segments[0] : 'home';
array_shift($url_segments); // removes the controller name from array
$action = isset($url_segments[0]) && !empty($url_segments[0]) ? $url_segments[0] : 'index';
array_shift($url_segments); // removes the action name from array
$controller = ucfirst($controller);
$controller = new $controller($url_segments);
$controller->$action();
controller class
class Accounts{
private $url_segments;
public function __construct() {
$this->url_segments = $url_segments;
}
public function index() {
// index code here
}
public function login() {
// login code here
}
public function signup() {
if (!isset($this->url_segments[0])) {
// url entered was: example.com/signup
} else if (isset($this->url_segments[0]) && $this->url_segments[0] == 'validate') {
// url entered was: example.com/signup/validate
}
}
}
from how my code appeared above, it can be seen that as parameters keep adding after the controller and action part of the url I'll need to keep using conditional statements to run the proper code as in the case of /signup/ and signup/validate. Is this method of using conditional statement to load view based on parameters efficient or is there a better way of doing this.
I would recommend you to make use of a routing system like Symfony Routing. There you could add a new Route for every url and redirect them to your specific controller.
Example Route:
$routes = new RouteCollection();
$routes->add('/accounts_signup', route('POST', "/accounts/signup", 'App\Controller\AccountController:signup'));
return $routes;
This route would call the signup method in the AccountController calss when www.example.com/accounts/signup get called with a post request.
I recommend you to use something like this. Even if this might be a bit complicated for the beginning, after reading (and understanding) the docs this will safe you a lot of time and it will make your code more readable as well.
I'm new to laravel and I have searched a lot for an answer to my problem but either it's not applicable or I'm not getting it.
I have a FileMaker solution for a client that handle customers and events. Each customer to my client have their own event websites that is managed via the solution. A cms simply. Each customer get a site with a url like clientsite.com/event.
Each page in the event has a page-type and I would like to address different controllers depending on the type.
In routes.php i have:
Route::group(['middleware' => ['sal', 'menu']], function () {
Route::get('/{event}/{page}', function($event, $page) {
// Query page for page-type and use controller depending on type
});
});
There are many page types (standard text/image, specialized forms etc) and therefor I would like to address different controllers.
Event names are always unique but pages are not.
You could call a controller manually inside the route closure. Though I would suggest doing the validation in a helper file to make the route file clean and readable.
Route::group(['middleware' => ['sal', 'menu']], function () {
Route::get('/{event}/{page}', function($event, $page) {
// you could do something like
$user_type = Auth::user()->user_type;
if($user_type == "organizer")
{
$controller = $app->make('OrganizerController');
return $controller->callAction('controllerFunc', $parameters = array());
}
else
{
$controller = $app->make('ClientController');
return $controller->callAction('controllerFunc', $parameters = array());
}
});
});
An alternative to the route solution could be to handle the logic in the controller itself:
First, update routes.php to something like:
Route::group(['middleware' => ['sal', 'menu']], function () {
Route::get('/{event}/{page}', 'RoutesController#index');
});
Then, in the RoutesController.php file (add to app/Http/Controllers), you can do something similar to:
public function index()
{
$event = Request::segment(1); // get the {event} part of the route
$page = Request::segment(2); // get the {page} part of the route
// get event data from database, e.g.
$event_data = Event::where( 'slug', $event )->first();
// load correct page
switch ( $page ) {
case "people":
return $this->people();
break;
case "anotherPage":
return $this->another_page();
break;
}
}
private function people()
{
// show view
return View::make('event.people');
}
This solution keeps your routes file clean, but also lets you handle the different event and page data, and load different views depending on the page being looked at. Your extra logic would be better in a controller rather than the routes file.
It all depends on where you prefer to code your page / view logic. You can use this approach call functions in the same controller, or external ones.
I am creating a custom MVC style framework from scratch and am at the point where I need to implement the code to control what happens on POST.
At the moment I have a main index.php which acts as a controller and passes data to other controllers such as:
profilecontroller.class.php
forumcontroller.class.php
At the moment I see two options as to where the POST controllers can go ..
First Approach
Firstly for site wide posts such as login that can occur on any page I would use something like this in the very first index.php to redirect all POST to a specific POST controller that then sends the data to a model to be processed:
if($_POST)
//post controller, works on specific form id's
Alternate Approach
The other option I see would be to build the POST identifier into the model construction sections but I don't think this would be very manageable/wise as they'd always be checked and resulting in more loaded code?
Are there any good/simple examples out there?
I'm creating my mvc to be as light as possible so that's my reason for going from scratch.
In a RESTful setup, you would normally have a controller for an object, say news, and then actions such as add, edit, delete etc.
Within your actions, you should then assert what HTTP method should be used to access the method, if one should be. For example:
<?php
class NewsController extends AbstractController {
public function save() {
if ($_SERVER['REQUEST_METHOD'] != 'POST') {
header('HTTP/1.1 405 Method Not Allowed');
die('Please use POST.');
}
// carry on knowing we're working with a POST request
}
}
Creating a separate controller for POST requests would, as you say, quickly becoming unruly and unmanageable.
If you're looking for a way of handling requests for different HTTP methods within different controller actions, then maybe check out ToroPHP. It's a lightweight (single file) router, where you map a request to a class that's referred to as a handler, and then that handler has methods for different HTTP methods. A quick example:
<?php
require 'lib/torophp/toro.php';
require 'classes/handlers/HomeHandler.php';
$toro = new ToroApplication(array(
array('/', 'HomeHandler')
));
$toro->serve();
And then your HomeHandler would look as follows:
<?php
class HomeHandler {
public function get() {
echo 'Hello, world!';
}
public function post() {
echo 'Try performing a GET request for the home page, buddy.';
}
// and so on...
}
Hope that helps.
This is my default Controller :
<?php
Class Controller_Home{
public $Registery = null;
final public function __construct($Registery){ $this->Registery = $Registery; }
final public function Init($Method=null){
# Quelle action on fait ?
if($Method){
$Split = explode('_', $Method);
$MethodName = 'Action';
foreach($Split as $Splitted){
$MethodName.= '_'.ucfirst($Splitted);
}
if(method_exists($this, $MethodName)){
$this->$MethodName();
} else {
echo '404';
die;
}
} else {
$this->Action_Default();
}
}
final public function Action_Default(){
$this->Registery->Import('Library.Account');
var_dump($this->Registery->Account);
echo 'Default Home';
}
}
As you can see, once you are in Action_Default, you can do whatever you want based on $_GET, $_POST, whatever you want ...
So with this code :
website.com/home/bob/ will use function Action_Bob inside the controller Home (Home::Action_Bob) ... if you see $_POST just put inside Action_Bob this
public function Action_Bob(){
if($_POST){
$this->Action_Bob_Post();
}
// continue
}
Okay, the best way I know to describe the scenario is to first give the example:
Say I have a page called index.php;
At the very top before the <html> tag, one can find;
<?php session_start();
$_SESSION['user_id'] = 1234;
require_once "db.con.php";
?>
Inside that of the <body> tag, one can find:
<div id="div_ajax">
<?php require_once "ajax.php"; ?>
</div>
Now inside the ajax.php page, there is a single button that when clicked will make an ajax request. After the request is made, a simple Db query statement to select user information based on the user_id will be made. The thing is, after the AJAX request, it seems as if the user_id session and the already included Db connection is "lost".
I know I can use a conditional statement to check for AJAX request and just add the lines...
session_start();
require_once "db.con.php";
..at the top of the ajax.php page, but I'm wondering if there's a better way to do this? I don't want to always have to add those two lines to every ajax called PHP page. It sort of defeats the purpose of having the lines on the master page (index.php) to begin with. I guess I can use one ajax called page and just include a bunch of case statements, but still wondering if there's a better way.
Thanks a lot.
As far as my experience goes, I think your problem can be solved with something called the FrontController pattern.
The basic idea is that you're whole application always calls the same file, index.php for instance (also called the single point of entry).
index.php then performs all the tasks that you need on every single page (like starting the session or including your library classes) and then calls the page you want to requested.
This could look something like this: (Can't test it now)
index.php:
<?php
session_start();
$_SESSION['user_id'] = 1234;
require_once("db.con.php");
if($_REQUEST['Request_Type'] == 'website'){
require_once("header.html");
switch($_REQUEST['Request_Url']){
case 'SomePage':
require('SomePage.php');
break;
case 'SomeOtherPage':
require('SomeOtherPage.php');
break;
default:
require('ajax.php');
}
require_once("footer.html");
}elseif($_REQUEST['Request_Type'] == 'ajax'){
switch($_REQUEST['Ajax_Function']){
case 'ProcessButton':
require('ProcessButton.php');
break;
}
}
?>
ajax.php
echo '<input type="button" onClick="ajaxRequest(\"index.php\",\"ProcessButton\")" Value="ClickMe!" />';
The ajaxRequest() Javascript function would have to send an Ajax Request to index.php setting the parameters
Request_Type = 'ajax'
Ajax_Function = 'ProcessButton'
I don't think that there is a better way, but that doesn't mean that there isn't.
Just a couple of notes from reading your question:
1) Use wrapper files for all of your header information. So, at the beginning of your page, put:
require_once('package.php'); // that's what I call mine
Then in package, I have:
require_once('session.start.php');
require_once('db.con.php');
That way, all your pages are accessing the same thing. If you ever need to change it, it's a lot easier.
There is a speed difference between require_once, include_once, include and require. I don't know how significant it is. Frameworks include like 60+ files when they make a page, so I've always assumed its not too bad.
The session information is stored in a folder on your server. PHP defaults it to /tmp (which you should change to a private folder / not web accessible).
Make sure that you are validating any information sent to the AJAX. Remember that it is just like its own web page, so any permissions or database sensitive information should be protected all the same.
"I guess I can use one ajax called page and just include a bunch of case statements, but still wondering if there's a better way."
The controller pattern is pretty good for this type of thing. Having a bunch of case statements in one file is hard on your maintenance. When you switch to having files that only have 1 or 2 functions in them, your life will get so much simpler.
Depending on the size of your project, you may want to implement a framework. Check out MVC frameworks. If I don't implement a framework, I still implement a controller pattern.
I lifted this from my blog. What I use now doesn't even look like this, but it started here:
In the Presentation layer, I am determining which elements I want to implement. For each element that I want to implement, I initiate the controller, like so:
$controller = new Controller();
$context = $controller->getContext();
$context->addParam('action', 'login');
$template->setContent( $controller->process() );
I am using the Controller from PHP Objects, Patterns, and Practice 3rd Ed by Matt Zandstra with my own modifications.
Here is what happens:
My presentation layer gets a new controller object.
The Controller object's constructor automatically creates a new CommandContext object.
The CommandContext is automatically going to load up the request variables as a Parameter, so I don't even need to worry about form data until I get to the Logic layer and need to validate and process it.
In the presentation layer, I load up any additional context parameters (or the information that I want to pass on to the controller), including most importantly, the action that I want to be taken by the Controller.
To pass the information on, I call $controller->process(). In the Logic layer, I can use a default "execute" or make a different command. So, in the Presentation layer, I set the action to "Login" which forces the login command and login view pages to open, and the command defaults to execute, but it could be anything.
When I call process, it triggers the CommandFacotry. The CommandFactory is going to first initiate a new Template child object, such as a side bar div box or main body context. It makes this determination with an optional flag that I can pass to the Controller.
The CommandFactory is then going to open up the Command file and pass the template and the context as objects to the Logic layer.
abstract class Command {
}
class CommandContext {
private $params = array();
private $error = "";
function __construct(){
$this->params = $_REQUEST;
}
function addParam( $key, $val ){
$this->params[$key] = $val;
}
function get( $key ){
return $this->params[$key];
}
function issetCheck( $key ){
if( ! empty( $this->params[$key] ) ){
return true;
}
return false;
}
function setError( $error ){
$this->error = $error;
}
function getError(){
return $this->error;
}
}
class CommandNotFoundException extends Exception { }
class CommandFactory {
private static $dir = 'include/classes/command/';
static function getCommand( $action = 'Default', $flag = 0 ){
switch( $flag ){
case 1:
$template = new TemplateQuickViewOnly();
break;
case 2:
$template = new TemplateQuickViewToggle();
break;
default:
$template = new TemplateMainBodyOnly();
break;
}
if( preg_match ( '/\W/', $action ) ){
throw new Exception("illegal characters in action");
}
$class = UCFirst(strtolower($action))."Command";
$file = ROOT_PATH."".self::$dir."{$class}.php";
if( ! file_exists( $file ) ){
throw new CommandNotFoundException( "could not find '$file'" );
}
include_once( $file );
if( ! class_exists($class) ){
throw new CommandNotFoundException( "no '$class' class located" );
}
$cmd = new $class( $template );
return array( $cmd, $template );
}
}
class Controller {
private $context;
function __construct(){
$this->context = new CommandContext();
}
function getContext(){
return $this->context;
}
function process( $method = 'execute', $flag = 0 ){
list( $cmd, $template ) = CommandFactory::getCommand( $this->context->get('action'), $flag );
if( ! $cmd->$method( $this->context ) ){
// handle failure
// $template->setMessage( UCFirst($this->context->get('action')).' failed to execute.');
return $template->getMessage();
}else{
// success dispatch view
return $template->getMessage();
}
}
}
The Logic layer is in a fixed directory. An instance of the object has already been instatiated by the Controller layer, which means the constructor has been triggered. Further, the controller layer already called the method "execute" (default) or another method, such as "getLoginForm". Also, note that when the Controller calls the method "execute", it is also passing the CommandContext to the method so we have stuff to work with.
class LoginCommand extends Command {
public function __construct( ){ }
function execute ( CommandContext $context ){
if( $context->get('login_user_name') == 'demo' ){
$this->view->setMessage('Success is true!');
return true;
}
return false;
}
function getLoginForm( CommandContext $context ){
$this->view->setMessage('Second sucess is even more true!');
return true;
}
}
You seem confused.
AJAX requests are separate requests for a webpage, nothing you did in the index.php on the server side will be available in the subsequent requests (except for any variables in the session). It works like this:
Request is sent for index.php from the browser
Server runs index.php (storing user_id in the session) and returns the HTML output to the browser at the end, the PHP script finishes and all resources are freed.
User clicks on button, creating a new request for another PHP file, say ajax.php
Server runs ajax.php and returns whatever is output to the browser. Again the PHP script finishes and all resources are freed.
Another way to think about this: From the server side, an AJAX request is almost the same as if you'd just pointed your browser to ajax.php directly.
I'm trying to create a universal header for a website built on CodeIgniter, and I'm having trouble figuring out the code that will switch the 'Login' link for the user's name (with a link to the profile page) after the user logs in.
In the controller functions, I've tried the following code:
if(!$this->session->userdata($userSessionVar))
{
$data['header_output'] = "<li><a href='" . base_url() . "index.php/main/login'>Login</a></li>";
} else
{
$data['header_output'] = $this->session->data('userFirstName');
}
(I realize this is incomplete, based on my designs, but it's just to test.) $userSessionVar holds the value "logged in" once logged in. Probably not the best way to do that. And that doesn't seem to work (and I pass the $data to the view). I've also tried making a custom function:
function check_login()
{
$CI =& get_instance();
$userSessionVar = 'logged_in';
if( ! $CI->session->userdata($userSessionVar))
{
return false;
} return true;
}
And then use the true/false return to structure the $header_output variable. None of these seem to work. I'm new to CodeIgniter and have some intermediate level of PHP/HTML/CSS, etc. I'm sure I'm missing something obvious and would appreciate any help, as well as a heads-up on how to avoid including the code in every controller function.
The variable $userSessionVar is only available within the function check_login(), so when you try to use it outside of the function, it will be blank (and therefore useless).
I recommend that you simply use $this->session->userdata('logged_in') and $CI->session->userdata('logged_in') rather than using the variable $userSessionVar to store what appears to be a constant value.
Also, you have an error in your code. You need to replace $this->session->data('userFirstName') with $this->session->userdata('userFirstName')
Here's how I typically deal with user data. First, add auth.php to the models folder:
<?php
class Auth extends Model {
private $user_data = false;
function Auth() {
parent::Model();
if ($this->input->post('action') == 'login') $this->login();
else if ($auth_id = $this->session->userdata('auth_id')) {
$user = // load user data from the database into the variable $user
if ($user) {
$this->user_data = $user;
} else $this->session->unset_userdata('auth_id');
}
}
function login() {
// process POST, check with database, and then store user_id using
// $this->session->set_userdata('auth_id', $user_id_here)
}
function me() {
return $this->user_data? (object)$this->user_data : false;
}
}
?>
Then, auto-load the model. To do this, edit config/autoload.php like so:
$autoload['model'] = array('auth');
Now your IF statement could look like this:
if ($me = $this->me()) $data['header_output'] = $me->userFirstName;
else $data['header_output'] = '<li>Login</li>';
in your model auth.php you've got the statements
class Auth extends Model
and
parent::Model();
With CodeIgniter, should these not be "CI_Model"...?