I have a model register.php (under app/model/register.php)
<?PHP
// Load the [default] db group
$this->load->database();
// Get Input from init form, sanitize, plop into variables.
class Register extends Model{
function formModel(){
//load parent constructor
parent::Model();
}
function sanitizeInput(){
var $name = mysql_real_escape_string($_POST['fullname']);
var $email = mysql_real_escape_string($_POST['email']);
var $pass = mysql_real_escape_string($_POST['password']);
var $dySalt = mt_rand(20,100);
var $pass = hash('sha512',$dySalt.$pass);
}
// Set form variables into object; define db table
$registeredObject = new getSanitizeNewRegistrant();
$tbl = 'Fan';
function SendRequestForData(){
if{
$this->db->insert($tbl,$object);
// .. redirect()
echo "Sent";
}
else{
echo "Oops, could not register you";
}
}
}
?>
I'm loading this model into a controller registerUsers.php (under app/controller/registerUsers.php)
<?PHP
$this->load->model('register'),'', TRUE);
?>
I'm confused how I go about implementing this in a view from here?
The MVC framework works as follows:
Model interacts with the database:
Here is where you want to put all of your functions that do nothing more than insert and return data to/from the database.
Views are what the user sees:
Here is where you'll have your html pages that make use of the data you got through your model
Controllers simply connect the two:
The controller preps data, uses the model to interact with the database, and loads the views for the user to see
If you had a function registerUser() in your register model, you would do something like this to actually use it within a function in the controller:
$this->load->model( 'register' ); // Load register model
$return = $this->register->registerUser( $_POST['username'], $_POST['email'], $_POST['password'] ); // Try to register the user to the database
if( $return === "TRUE" ) {
$this->load->view( 'success' ); // Hooray!
}
else {
$this->load->view( 'fail' ); // :(
}
Here, the controller loads the register model, tries to save the username, email and password using the registerUser() function within the model, and loads the correct view accordingly.
Obviously you'll want to clean $_POST data and everything before writing it to the database. This should be done within the controller.
Related
I want to ask this question if how can we make a session in code igniter specially in logging in and logging out on the account. I want to know the step by step following the MVC of code igniter.
At the login time after executing query set session data in set_userdata function and passing data array whos you want to set.
$this->session->set_userdata('session data here');
And at the time of logout you have to call unset_userdata function and passing array of array whos you have to set at login time.
$this->session->unset_userdata('session data here');
using my code as an example you can do this i have a controller called iris.php and a model called script.php. i use the iris to call and make use of the script model.
class Iris extends CI_Controller {
function __construct(){
parent::__construct();
$this->load->model('script');
$this->load->model('alert');
}
public function index()
{ $this->load->view('index');
}
public function login_in()
{
$login = $this->script->check_login();
if($login->num_rows() == 1){
foreach ($login->result_array() as $row) {
$newdata = array(
'fullname' => $row['fullname'],
'email' => $row['email'],
'member_id' => $row['member_id'],
'transtatus'=>$row['transtatus']
);
$this->session->set_userdata($newdata);
}
redirect('iris/user_home');
}else
{
$data = array('alert'=>$this->alert->log_alert());
$this->load->view('common/header');
$this->load->view('login',$data);
$this->load->view('common/footer');
}
}`
i first load the model script model under the constructor and in the login function of the iris controller i called the function in the script $login=$this->script->check_login();
in the script.php we have the following code.
{public function check_login(){
$email = $this->input->post('email');
$password = $this->input->post('password');
$query = "SELECT * FROM `iris_user`
WHERE`email`=? AND`password`= ? ";
$result = $this->db->query($query, array($email, $password));
return $result;
}
remember you have to have loader the session class helper form the application/config/autoload.php file in the CIfolder
$autoload['libraries'] = array('database', 'session');
the session is alway start once it has been autoloaded, but can be destroyed when maybe creating a logout function.
also note when adding to the session data variable to access the session variable you will have to use the name that was used when declaring the session variable. e.g to access the fullname you would do this in code
echo $_SESSION['fullname'];
In the controller load library session :
$this->load->library('session');
Use below sentence for session create :
$this->session->set_userdata("session_name",session_value);
For Session Unset:
$this->session->unset_userdata("session_name");
I'm trying to learn MVC pattern but,even if I'm trying hard, it seems I still got big issues.
I have got a controller,named baseController that do the following:
class baseController {
public $model;
public $user;
...
$activeuser = $this->model->getlogin();
if ($activeuser != 'invalid user' && $activeuser != "") {
$this->user=$activeuser;
header("Location:home.php");
}
I have got a model.php file which contains the getlogin() function:
public function getlogin() {
if (isset($_REQUEST['username']) && isset($_REQUEST['password'])) {
$username = mysql_real_escape_string($_REQUEST['username']);
$pwd = mysql_real_escape_string($_REQUEST['password']);
$pwd = md5($pwd);
$query = mysql_query("SELECT * FROM users WHERE username='$username' AND password ='$pwd' AND attivato =1;");
if (mysql_num_rows($query) == 1) {
require_once 'User.php';
$sql=mysql_fetch_array($query);
$activeuser = new User();
$activeuser->username=$sql['username'];
$activeuser->email=$sql['email'];
return $activeuser;
} else {
return 'invalid user'; //TO-DO
}
}
}
The home.php create a new homeController and calls its invoke() function.The homeController file include the view page,that's called afterlogin.php.
In the afterlogin.php I've got the "ERROR":
if (isset($activeuser)){
echo "<p>Utente ".$activeuser->username."</p>";
echo "<p>Email ".$activeuser->email."</p>";}
//echo "<p>Pass ".$activeuser->pwd."</p>";
echo"<h1> HOMEPAGE, LOGIN OK </h1>";
It seems the homeController,and so the afterlogin page cannot access the user created in the baseController file. If I try an echo inside the baseController of $this->user->username everything is working. What should I do?? HELP!!
The client-server lifecycle is effectively stateless; on every page load, your variables and objects are wiped out.
There are the client-sourced $_POST and $_GET superglobals, which is part of the standard form submission and url query processes.
The server has databases, file writing (sketchy from a security POV) and the $_SESSION superglobal. These are the ways the server can manage a data state between pageloads.
Understand that if you're using objects, you need to have them instantiated on every page load for them to work. You can store your user_ID in $_SESSION['user_ID'] and instantiate the user object from it every time, making appropriate changes according to how the data changes.
I have this controller: Resales, and I am in the Administrator controller and need to create a new Resale.. how should I do that?
first option:
Administrator form calls /resales/addResales
second option: Administrator has a method addResale that loads the Resale model and inserts it.
What should I do?
thanks
Administrator controller shouldn't be loading the Resales controller - that should be a model that both controllers use. You should load your Resales model into the Administrator controller in the $uses = array() property at the top of your controller file:
class AdministratorController extends AppController {
var $uses = array('Resale', //the rest of your models);
public function createResale() {
$this->Resale->create();
$this->Resale->set($this->data['Resale']);
$this->Resale->save();
}
}
Other options are that you could use Ajax to post the request for you, or you could use $this->requestAction() in your Administrator controller to use a processing function in your Resales controller:
// administrator controller
public function createResale() {
// define your data here
$result = $this->requestAction('resales/create', array($data_array));
}
Have a look at the manual for more information on requestAction:
http://book.cakephp.org/2.0/en/controllers.html
EDIT
You've just asked about views. In this case, there's no real need to create a view for createResale(), what you might want to do instead is set a Session flash message, then redirect back to your form. You will need to ensure you've included the Session helper at the top of your controller:
class AdministratorController extends AppController {
var $helpers = array('Session', // any others here);
Then you prevent the layout and render of views, do your thing and set a session flash with the results message:
public function createResale() {
// don't render a view or layout
$this->layout = '';
$this->render(false);
// process your request
$result = // do stuff... return true or false for result
$msg = $result ? 'Added successfully!' : 'Error adding resale!';
// set flash message
$this->Session->setFlash($msg);
// return to that form
$this->redirect(array('action' => 'formYouCameFrom'));
}
Now on your form, you'll simply do this:
echo $this->Session->flash();
... which will output the results.
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"...?
I cant seem to figure out how to create a flexible sidebar containing and login form (Zend_Form) and various module/controller specific links.
The most common solution seems to be using:
echo $this->action('login', 'authentication', 'default');
But apperently this isnt the 'best' way? I've read that this apprently triggers a dispatchloop and thereby take a performance hit?
I've thought about sing a View_Helper for the sidebar:
class Zend_View_Helper_Sidebar extends Zend_View_Helper_Abstract
{
public function sidebar()
{
$sidebar = $this->view->placeholder('sidebar');
$sidebar->setPrefix('<div class="sidebar-element">')
->setSeparator('</div><div class="sidebar-element">')
->setPostfix('</div>');
$sidebar->append(new Form_Login);
$sidebar->append(new Model_Category->getList());
return $sidebar
}
}
In my Form_Login i have action set to /auth/login which contains the following code:
public function loginAction()
{
$request = $this->getRequest();
if($request->isPost()) {
$form = new Form_Login();
$data = $request->getPost();
if($form->isValid($data)) {
$username = $form->getValue('username');
$password = $form->getValue('password');
$users = new Model_DbTable_Users();
$authenticated = $users->login($username, $password);
if($authenticated) {
//Succes - show identity instead of loginForm
} else {
$this->view->loginForm = $form;
$this->render('/index');
}
}
}
}
If I provide the wrong username/password it renders indexAction which is currently empty. This is fine. It also renders my sidebar containing the loginForm as needed, but the form is empty (The user input is not displayed. Neither is no message that the form failed to validate).
The username-field in the form should display the input that the user provided before submitting. And a error message should be displayed.
Any help as to why this is not happing, is very much appriciated.
You are doing your form validation in a loginAction and you said you are currently posting to index action, is that a typo?
Besides that, you are creating two copies of the Form_Login. Once, in the action and once in view helper. If you validate on one instance in the action, you need to display that same instance of the form in the view helper. You could either move all the validation logic into the view helper or you could share the instance between the view helper and the action. I'm going to suggest the latter.
Check in your view helper if a form already exists in the registry. If it does, just use that instance. Otherwise you can create a new instance. Here's a rough example of what I mean:
class Zend_View_Helper_Sidebar extends Zend_View_Helper_Abstract
{
public function sidebar()
{
$sidebar = $this->view->placeholder('sidebar');
$sidebar->setPrefix('<div class="sidebar-element">')
->setSeparator('</div><div class="sidebar-element">')
->setPostfix('</div>');
if(Zend_Registry::isReigistered('loginForm')) {
$loginForm = Zend_Registry::get('loginForm');
} else {
$loginForm = new Form_Login();
}
$sidebar->append($loginForm);
$sidebar->append(new Model_Category->getList());
return $sidebar
}
}
public function loginAction()
{
$form = new Form_Login();
Zend_Registry::set('loginForm', $form);
$request = $this->getRequest();
if($request->isPost()) {
$data = $request->getPost();
if($form->isValid($data)) {
$username = $form->getValue('username');
$password = $form->getValue('password');
$users = new Model_DbTable_Users();
$authenticated = $users->login($username, $password);
if($authenticated) {
//Succes - show identity instead of loginForm
} else {
$this->view->loginForm = $form;
$this->render('/index');
}
}
}
}
Edit:
No, there is no self checking if an instance of a form already exists. You must do this yourself.
I'm pretty sure the suggested way is to use a view helper. As you said in your question, using the action view helper causes another dispatch loop which is bad for performance. I don't know what the verdict is on whether all logic should be kept in the view helper or not.