Please dont`t ask why I have more than one controller: this is what my teacher wants.
I have 3 controllers: Api.php, Token.php and Apikey.php, where Api.php is the "main" one.
PROBLEM: When I pass into the URL: http://localhost/revolution/index.php/api/registerUser/first_name/12First
it seems there are problems with loading the Token controller from Api controller.
ERROR: Fatal error: Call to a member function generateToken() on null
What can I do?
API Controller: Api.php
class api extends CI_Controller {
public function index()
{
parent::__construct();
$this->load->library("../controllers/Apikey.php");
$this->load->library("../controllers/Token.php");
}
public function registerUser ($username,$parola)
{
if ($this->isValidUserName($username) && $this->isValidPass($parola)) {
$this->load->library("../controllers/Token");
$id = $this->ApiModel->insertCredentials($username, md5($parola));
$this->Token->generateToken($id);
$this->ApiKey->generateApiKey($id);
$data['registered'] = 1;
$this->load->view('api', $data);
}
}
}
Controller Token.php
public function existsToken($token)
{
$arrayTokens = $this->ApiModel->getAllTokens();
if (in_array($token, $arrayTokens))
return existsToken(sha1($this->randomString())); //$this->isValidToken(sha1($this->randomString()));
return $token;
}
public function randomString() {
return intval(993432422 % rand());
}
public function generateToken($id_user)
{
$token = $this->existsToken(sha1($this->randomString()));
$date = $this->generateExpDate();
$result = $this->ApiModel->insertToken($token, $date, $id_user);
}
Related
I have a method with a lot of code
public function createNewObject(Request $request)
{
// Code...
}
There is another method that I plan to call, but how to pass it to the createNewObject method as a Request argument?
public function deleteAndCreateObject()
{
$this->createNewObject(???);
}
Just type-hint it in your deleteAndCreateObject() method.
class YourController
{
public function createNewObject(Request $request)
{
// Code...
}
public function deleteAndCreateObject(Request $request)
{
$this->createNewObject($request);
}
}
If that—for some reason—doesn't work for you, you can always use request():
class YourController
{
public function createNewObject()
{
$request = request();
// Code...
}
public function deleteAndCreateObject()
{
$this->createNewObject();
}
}
I am building custom mvc framework in php in order to learn and when I am trying to submit my form with an mail that already exists in the database, my validation should prevent me to do so, instead I get this error:
Fatal error: Uncaught Error: Call to a member function findUserByEmail() on null in C:\xampp\htdocs\gacho\App\Controllers\UsersController.php:
UsersController.php
<?php
namespace App\Controllers;
use App\Models\User;
use Core\Controller;
class UsersController extends Controller
{
public function __construct($controller, $action)
{
parent::__construct($controller, $action);
$this->userModel = $this->load_model('User');
}
public function registerAction()
{
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
$data = [
'email' => trim($_POST['email']),
];
}
if (empty($data['email'])) {
$data['email_err'] = "Please enter your email!!!";
} else {
if ($this->userModel->findUserByEmail($data['email'])) {
$data['email_err'] = "Email is already taken!";
}
}
}
User.php
<?php
namespace App\Models;
use Core\Database;
class User
{
private $db;
public function __construct()
{
$this->db = new Database();
}
public function findUserByEmail($email)
{
$this->db->query('SELECT * FROM users WHERE email = :email');
$this->db->bind(':email', $email);
$row = $this->db->single();
if ($this->db->rowCount() > 0) {
return true;
} else {
return false;
}
}
}
Controller.php:
<?php
namespace Core;
class Controller
{
protected $_controller;
protected $_action;
public $view;
public function __construct($controller, $action)
{
$this->_controller = $controller;
$this->_action = $action;
$this->view = new View();
}
protected function load_model($model)
{
$modelPath = 'App\Models\\' . $model;
if (class_exists($modelPath)) {
$this->{$model.'Model'} = new $modelPath();
}
}
}
I think the mistake is about $this->userModel , but I'm stuck and any help is appreciated.
The problem is that in __construct of UsersController you have:
$this->userModel = $this->load_model('User');
So you assign to userModel property the return value of load_model method.
load_model method doesn't return anything so $this->userModel is always set to NULL, doesn't matter if load_model succeeded or not.
You should just return new $modelPath(); in load_model if you want to assign it to a property by return value.
Also add throw new Exception($modelPath. 'not found'); at the end of load_model method to be sure it did load the model, and not just failed silently to find it.
Note that $this->userModel is not the same as $this->UserModel (case sensitive) and $modelPath = 'App\Models\\' . $model; - why \ after App, and two \ after Models?
I think you need to access your model in $this->UserModel, since User was passed into the load_model method.
Everything is working as expected on my local server, but when I try to run it on my live server I get an error:
Fatal error: Call to a member function call_admin_login() on null in codeigniter HMVC
What am I possibly doing wrong?
Below is my code:
<?php
class Admin_login extends MY_Controller {
public function __construct() {
parent::__construct();
//Check Login Status
$logged_info = $this->session->userdata('logged_info');
if ($logged_info != FALSE) {
redirect(base_url('admin/view_products.html', 'refresh'));
}
//Load Model
$this->load->model('admin_login_model', 'login_mdl');
}
public function index() {
$data['title'] = 'Admin Login';
$this->template->call_admin_login($data);
}
<?php
class Template extends MY_Controller {
public function __construct() {
parent::__construct();
}
public function call_admin_master($data = NULL) {
$this->load->view('admin_master_v', $data);
}
public function call_admin_login($data = NULL) {
$this->load->view('admin_login_v', $data);
}
}
I Have Defined MY_ Controller in my core folder.
Then i have two controllers:
Admin_Controller
Customer_Controller
Now i want to put a query into my Customer_Controller whose result i can access all the controller which extends to Customer_Controllers.
I have put this code in Customer_Controller
public function get_users()
{
$id = $this->session->userdata('id');
$this->db->select('*');
$this->db->join('tenant','tenant.id = sites.tenant_id');
$this->db->where('tenant.id',$id);
$this->db->from('sites');
$query = $this->db->get();
$result = $query->result();
$sitedata = json_decode(json_encode($result));
$this->session->set_userdata($sitedata);
}
Now when i have a child class something like this
<?php
class User extends Customer_Controller
{
public function__construct()
{
parent::__construct();
}
public function index()
{
//Get Results from Customer_Controller
}
}
how do this?
you can follow this:
class Customer_Controller extends My_Controller
{
public function customer()
{
return 'costomers';
}
}
then
class User extends Customer_Controller
{
//call the function from Customer_Controller
$this->customer();
}
Let me give you a suggestion. Instead of creating a controller and extending the same, why don't you create a library class.
And then load your library inside the controller you want.
for example here is your library class file.
<?php
class users{
private $session;
public function __construct(){
$CI =& get_instance();
$this->session=$CI->session;
}
public function get_users()
{
// do the code and return the
}
}
AND in your controller
<?php
class User extends CI_Controller
{
public function__construct()
{
parent::__construct();
}
public function index()
{
$this->load->library('users');
$users = new users();
$userinfo = users->get_users();
//Results from library
}
}
You Try get_instance() like this in you User Controller
public function get_users()
{
$id = $this->session->userdata('id');
$this->db->select('*');
$this->db->join('tenant','tenant.id = sites.tenant_id');
$this->db->where('tenant.id',$id);
$this->db->from('sites');
$query = $this->db->get();
$result = $query->result();
$sitedata = json_decode(json_encode($result));
$this->session->set_userdata($sitedata);
return $result;
}
class User extends CI_controller
{
public function__construct()
{
parent::__construct();
}
public function index()
{
$CI=&get_instance();
$result=$CI->get_users();
foreach($result as $row)
{
echo $row->id;//here add you table field name for id
}
}
}
Codeigniter is MVC framework.
So You will put get_users in model part.
example: you must making custom_model.php in models folder.
<?php
class custom_model extends CI_Model {
function __construct()
{
parent::__construct();
}
public function get_users($id)
{
$this->db->select('*');
$this->db->join('tenant','tenant.id = sites.tenant_id');
$this->db->where('tenant.id',$id);
$this->db->from('sites');
$query = $this->db->get();
$result = $query->result();
return $result;
}
}
?>
next step: you are remake custom_controller.
public function get_users()
{
$id = $this->session->userdata('id');
$this->load->model('custom_model');
$result=$this->cutom_model->get_users($id);
$sitedata = json_decode(json_encode($result));
$this->session->set_userdata($sitedata);
}
and next step:
class User extends Customer_Controller
{
public function__construct()
{
parent::__construct();
}
public function index()
{
//
}
public function get_users(){
parent::get_users();
}
I'm testing my CodeIgniter project with PHPUnit Testing framework (CITest.php). When the function test_model(), calls the model directly to get the details of an user, it works perfectly. But when I do the same via a controller by calling the function test_controller(), it does not output anything (When I debugged, the model itself doesn't gets called). I even verfied if the post data is passed correctly by creating a function test_post_data(). Am I missing something?
I could only find online resources to test the mdoel directly or a controller separately. But I couldn't find any useful link which calls a controller that triggers the model.
CITest.php
class CITest extends PHPUnit_Framework_TestCase
{
private $CI;
public function setUp()
{
$this->CI = &get_instance();
$this->CI->load->model('Test_model');
$this->model = $this->CI->My_model; // load the model
$this->auth = new Test_controller; // load the controller
}
public test_model() {
$user_id = 6;
print_r($this->model->getUserData($user_id));
}
public test_post_data() {
$_POST['useR_id'] = 22;
print_r($this->model->check_post_data());
}
public test_controller() {
$_POST['useR_id'] = 22;
print_r($this->model->get_user_data());
}
}
Test_controller.php
class Test_controller extends CI_Controller {
public function __construct()
{
parent::__construct();
$this->load->model('Test_model');
}
public function check_post_data() {
return $this->input->post();
}
public function get_user_data() {
$user_id = $this->input->post('user_id');
return $this->Test_model->getUserData($user_id);
}
}
Test_model.php
class Test_model extends CI_Model {
public function __construct()
{
parent::__construct();
}
public function getUserData($user_id) {
return $this->db->select("*")
->from("users")
->where("user_id", $user_id)
->get()->result_array();
}
}
The code in CITest.php
public test_controller() {
$_POST['useR_id'] = 22;
print_r($this->model->get_user_data());
}
should be like the following?
public test_controller() {
$_POST['useR_id'] = 22;
print_r($this->auth->get_user_data());
}