Codeigniter 4 BadMethodCallException - codeigniter-4

I am trying to do a user login and I am getting this error which I can't figure out why. Also, I am not sure whether I can mentioned 1 more question or do I have to separate it on another topic. If I want user to login using either username or email address, how should I do it?
I have uploaded the error message here
The error seems to be at this line :
$user = $model->model('username', $this->request->getVar('username'))
->first();
Below are my code:
Controller
public function login()
{
$data = [];
helper(['form']);
$validation = \Config\Services::validation();
if($this->request->getMethod() == 'post'){
//validations
$rules = [
'username' => 'required',
'password' => 'required|validateUser[username, password]'
];
$errors = [
'password' => [
'validateUser' => 'Username or Password don\'t match'
]
];
if(!$this->validate($rules, $errors)){
$data['validation'] = $this->validator;
}else{
$model = new AccountModel();
$user = $model->model('username', $this->request->getVar('username'))
->first();
$this->setUserMethod($user);
return redirect()->to('account');
}
}
echo view('templates/header', $data);
echo view('account/login');
echo view('templates/footer');
}
Model
<?php namespace App\Models;
use CodeIgniter\Model;
class AccountModel extends Model{
protected $table = 'users';
protected $allowedFields = [
'username',
'email',
'firstname',
'lastname',
'dob',
'country',
'contact',
'password',
'created_at',
'updated_at',
'created_by'
];
protected $beforeInsert = ['beforeInsert'];
protected $beforeUpdate = ['beforeUpdate'];
protected function beforeInsert(array $data) {
$data = $this->passwordHash($data);
return $data;
}
protected function beforeUpdate(array $data) {
$data = $this->passwordHash($data);
return $data;
}
protected function passwordHash(array $data){
if(isset($data['data']['password']))
$data['data']['password'] = password_hash($data['data']['password'], PASSWORD_DEFAULT);
return $data;
}
}
?>
Hope someone can help me out here. Thanks in advance!

So you have this line trying to call a method called model which does not exist...
This is what you have...
$user = $model->model('username', $this->request->getVar('username'))
->first();
If you have read the CodeIgniter User Guide, you would see that you really want to be using where instead of model... Maybe cause you had model stuck in your head, as that happens sometimes.
$user = $model->where('username', $this->request->getVar('username'))->first();
See how that flies for you.

Related

Too few arguments to function App\Controllers\Parsys::__construct(), 0 passed in

First I code without use RequestInterface and runwell, but I when I applicate the RequestInterface from the docs here: https://codeigniter4.github.io/userguide/incoming/incomingrequest.html I got this error, What happen with my code?
<?php namespace App\Controllers;
use CodeIgniter\HTTP\RequestInterface;
class Parsys extends BaseController {
protected $request;
public function __construct(RequestInterface $request) {
$this->request = $request;
}
public function index() {
$data = [
'title' => "Parameter System",
];
return view("backend/parsys_frm", $data);
}
public function getList() {
$frm = $request->getGet('frm');
$q = $this->request->getGet('q');
$order_by = $this->request->getGet('order_by');
$page = $this->request->getGet('page');
$limit = $this->request->getGet('limit');
$limit = #$limit == 0 ? 10 : $limit;
$this->queryList($total, $current, $page, $limit, $q, [1 => 1]);
$data = $current->result_array();
header('Content-Type: application/json');
echo json_encode(compact(['total', 'page', 'limit', 'data', 'q']));
}
I use ubuntu 20.04, lampp PHP 7.4
Instead of using the __construct magic method use the built in init method.
public function initController(\CodeIgniter\HTTP\RequestInterface $request, \CodeIgniter\HTTP\ResponseInterface $response, \Psr\Log\LoggerInterface $logger)
{
parent::initController($request, $response, $logger);
}

Codeigniter 4 ErrorException Undefined variable: table

I am facing this issue of Undefined variable as shown in the image attached which I am not sure what is wrong.
My code as follows:
Routes
$routes->get('account/game_reg', 'Game::index');
$routes->match(['get', 'post'], 'account/game_reg', 'Game::game_reg');
Controller
public function index()
{
$data = [];
if(!session()->get('isLoggedIn')):
return redirect()->to(base_url('account/login'));
endif;
$games = new GamelistModel();
$data['table'] = $games->getList();
echo view('templates/header', $data);
echo view('account/game_reg');
echo view('templates/footer');
}
public function game_reg()
{
$data = [];
helper(['form']);
$validation = \Config\Services::validation();
if($this->request->getMethod() == 'post'){
$user_id = session()->get('user_id');
//validations
$rules = [
'game_id' => 'required',
'ign' => 'required|is_unique[game_reg.ign]',
'acc_id' => 'required'
];
$errors = [
'ign' => [
'is_unique' => 'IGN already exist!'
],
'acc_id' => [
'is_unique' => 'Account ID already exist!'
]
];
if(!$this->validate($rules, $errors)){
$data['validation'] = $this->validator;
}else{
//store information into database
$model = new GameregModel();
$newData = [
'game_id' => $this->request->getVar('game_id'),
'ign' => $this->request->getVar('ign'),
'acc_id' => $this->request->getVar('acc_id'),
'user_id' => session()->get('user_id'),
'created_by' => session()->get('username')
];
$model->save($newData);
$session = session();
$session->setFlashdata('success', 'Game Successfully Added!');
return redirect()->to(base_url('account/game_reg'));
}
}
echo view('templates/header', $data);
echo view('account/game_reg');
echo view('templates/footer');
}
GameregModel
<?php namespace App\Models;
use CodeIgniter\Model;
class GameregModel extends Model{
protected $table = 'game_reg';
protected $allowedFields = [
'user_id',
'game_id',
'ign',
'acc_id',
'created_at',
'updated_at',
'created_by'
];
}
?>
GamelistModel
<?php namespace App\Models;
use CodeIgniter\Model;
class GamelistModel extends Model{
protected $table = 'game_list';
protected $primarykey = 'game_id';
protected $allowedFields = [
'game_id',
'game_name'
];
public function getList()
{
return $this->orderBy('game_id', 'ASC')->findAll();
}
}
?>
Views
<select id="myDropdown">
<?php
$i = 1;
foreach($table as $t) :
$i++;
?>
<option value="<?= $t['game_id']; ?>" data-imagesrc="/img/logo_<?= strtolower($t['game_name']); ?>.jpg"><?= $t['game_name']; ?></option>
<?php endforeach; ?>
</select>
If I remove away the is_unique function, everything works perfectly fine but when I include the is_unique, I get the error. What I am trying to do is, I would retrieve a list of games updated by admin, user will then choose from this list and save into their profile.
Hope someone can help me out of this.
Thanks in advance guys!
You are only sending the data into one of your views. The one using the $table variable does not have access to it.
So in your loading views code you have to do the following:
echo view('templates/header', $data);
echo view('account/game_reg', $data);
echo view('templates/footer', $data);
It's better to just send the data across all views.
The other thing I noticed (nothing to do with the problem here) is that you're closing the php tags inside your models. Never do that. Your classes should never have the php closing tag ?>.

Always the same view content on slim framework with twig after save changes

I'm using Slim and Twig and I'm trying to change a view content, but it doesn't change after I saved the changes.
This is the controller:
<?php
use \Psr\Http\Message\ServerRequestInterface as Request;
use \Psr\Http\Message\ResponseInterface as Response;
require '../../vendor/autoload.php';
require './classes/connection.php';
$app = new \Slim\App;
$container = $app->getContainer();
$container['view'] = function ($container) {
$view = new \Slim\Views\Twig('../../views', [
'cache' => '../../views_cache'
]);
// Instantiate and add Slim specific extension
$router = $container->get('router');
$uri = \Slim\Http\Uri::createFromEnvironment(new \Slim\Http\Environment($_SERVER));
$view->addExtension(new \Slim\Views\TwigExtension($router, $uri));
return $view;
};
$app->get('/hello/{name}', function (Request $request, Response $response, array $args) {
/*$name = $args['name'];
$response->getBody()->write("Hello, $name");
echo getcwd();
return $response;*/
return $this->view->render($response, 'login.html', [
'name' => $args['name']
]);
});
$app->post('/login', function (Request $request, Response $response, array $args) {
$post_data = $request->getParsedBody();
if (isset($post_data['user']) && isset($post_data['pass'])) {
$mongo = new Connection();
$conn = $mongo->getConnection();
$collection = $conn->prueba->users;
$result = $collection->find(['user' => $post_data['user']])->toArray();
$dbUser = $result[0]['username'];
$dbPass = $result[0]['password'];
if (password_verify($post_data['pass'], $dbPass)) {
echo '¡La contraseña es válida!';
} else {
echo 'La contraseña no es válida.';
}
} else {
return $response->withJson(array('login_status' => 'ko'));
}
});
$app->run();
What I missed to see the view changes? I think it's something about compile view but I'm not sure. It's the first time I use this framework.

Kohana ORM Check if user exists and returning messages to View?

I'm using Kohana 3.3 in my project and I'm trying to get the User Registration and Login working. I am using ORM's Auth and Kostache for managing my layout/templates.
How do I:
Check if Username already exists? If it does return to error_msg.mustache a message "User already Exists"
Check if username and email is valid according to my model rules? If not return error message to
error_msg.mustache indicating what validation failed
In my controller I have:
class Controller_User extends Controller {
public function action_signup()
{
$renderer = Kostache_Layout::factory();
$this->response->body($renderer->render(new View_FrontEnd_User, 'frontend/signup'));
}
public function action_createuser()
{
try {
$user = ORM::factory('User');
$user->username = $this->request->post('username');
$user->password = $this->request->post('password');
$user->email = $this->request->post('email');
// How do I:
// Check if Username already exists? If it does return to error_msg.mustache a message "User already Exists"
// Check if email is valid? If not return error message to error_msg.mustache indicating "email is not valid"
$user->save();
}
catch (ORM_Validation_Exception $e)
{
$errors = $e->errors();
}
}
}
In my Model:
<?php
class Model_User extends Model_Auth_User
{
public function rules()
{
return array(
'username' => array(
array('not_empty'),
array('min_length', array(':value', 4)),
array('max_length', array(':value', 32)),
array('regex', array(':value', '/^[-\pL\pN_.]++$/uD')),
),
'email' => array(
array('not_empty'),
array('min_length', array(':value', 4)),
array('max_length', array(':value', 127)),
array('email'),
),
);
}
}
Thanks a lot in advance!
You can do the uniqueness check using Validation and an already-written callback. This has the advantages of keeping your validation logic together, and of being very concise:
public function rules()
{
return array(
'username' => array(
array(array($this, 'unique'), array(':field', ':value')),
// ...
As simple as that!
I originally answered this question with my own solution, which is slightly different from the pre-rolled version, but now that I know about that obviously I'll use it instead of this:
public function rules()
{
return array(
'username' => array(
// ...
array('Model_User::unique_field', array(':field', ':value', $this->pk())),
),
// ...
);
}
public static function unique_field($field, $value, $user_id = NULL)
{
return (ORM::factory('User')->where($field, '=', $value)->find()->pk() === $user_id);
}
Unfortunately I can't help you with the Kostache, but in order to check whether a username already exists you have to actually try and load it:
$user = ORM::factory('User')->where('username', '=', $this->request->post('username'));
if ($user->loaded())
{
// The username already exists
}
You probably want to do this before actually opening the try/catch block.
To use the proper error messages you need to define them in /application/messages folder as described in the ORM Validation guide.

kohana 3 incorporate file validate in orm

I cant figure out how to add file validation code to the orm model
As the code is now the text inputs are validated in the orm, but the file has no validation on it at all. I was wondering if it was possible to merge the file validation in the 'profile' model where I have the text validation?
Here is the code in my controller
public function action_public_edit()
{
$content = View::factory('profile/public_edit')
->bind('user', $user)
->bind('profile', $profile)
->bind('errors', $errors);
$user = Auth::instance()->get_user();
$profile = $user->profiles;
$this->template->content = $content;
if ($_POST)
{
if ($profile->values($_POST)->check())
{
$picture = Upload::save($_FILES['profile_picture']);
// Resize, sharpen, and save the image
Image::factory($picture)
->resize(100, 100, Image::WIDTH)
->save();
$profile->profile_picture = basename($picture);
$profile->save();
$redirect = "profile/private";
Request::instance()->redirect($redirect);
}
else
{
$errors = $profile->validate()->errors('profile/public_edit');
}
}
}
And the ORM model
protected $_belongs_to = array('user' => array());
protected $_rules = array(
'first_name' => array(
'not_empty' => NULL,
),
'last_name' => array(
'not_empty' => NULL,
),
You don't need to check() if you save() later - save will do the checking and throw ORM_Validation_Exception if validation is not passed. I suggest to create a function in your model for saving - move the lines after check() to this model. In controller you'll only need to write:
if ($this->request->method() === 'POST')
{
$errors = $profile->upload('profile_picture');
if (empty($errors))
{
try
{
$profile->your_save_function();
$this->request->redirect('profile/private');
}
catch (ORM_Validation_Exception $e)
{
$errors = $e->errors('profile');
}
}
}
In your model:
public function your_save_function()
{
// Do your stuff before uploading the picture
// Save the model
$this->save();
}
public function upload($filename)
{
// Set the default upload directory
Upload::$default_directory = 'your_path';
// Validate the file first
$validation = Validation::factory($_FILES)
->rules($filename, array(
array('not_empty'),
array('Upload::not_empty'),
array('Upload::valid'),
array('Upload::type', array(':value', array('your_valid_extensions'))),
array('Upload::size', array(':value', 'your_max_size')),
));
// Validate and upload OK
if ($validation->check())
{
$picture = Upload::save($_FILES[$filename]);
// Resize, sharpen, and save the image
Image::factory($picture)
->resize(100, 100, Image::WIDTH)
->save();
$this->profile_picture = basename($picture);
}
else
{
return $validation->errors('upload');
}
}
Much simpler and cleaner code.

Resources