I'm trying to get to grips with Laravel and not finding the documentation any help at all. It seems to assume you know so much instead of actually walking new users through each section step by step.
I've got to the point where I need to make an internal call to another class, and sticking with MVC I can't seem to do what should be a simple thing.
My code:
class UsersController extends BaseController {
protected $layout = 'layouts.templates.page';
protected $messages;
public function getIndex()
{
$input = array('where', array('field' => 'email', 'operator' => '=', 'value' => 'tony#fluidstudiosltd.com'));
$request = Request::create('user/read', 'GET');
$users = json_decode(Route::dispatch($request)->getContent());
var_dump($users); exit;
$this->pageTitle = 'Fluid Customer Status :: Admin Users';
$this->content = View::make('layouts.admin.users');
}
}
Class UserController extends Base Controller
public function getRead()
{
$userId = (int) Request::segment(3);
if ($userId)
{
$user = User::findOrFail($userId);
return $user;
}
else
{
$users = new User;
var_dump(Input::all()); exit;
if (Input::has('where'))
{
var_dump(Input::get('where')); exit;
}
return $users->get();
}
}
Why isn't the input data from UsersController#getIndex available in UserController#getRead
Related
I want to build a login system using Codeigniter 4.
But I face some error.
I have some data in Users_model;
Here is my some codes:
Controller/Signin.php
<?php
namespace App\Controllers;
use App\models\Users_model;
class Signin extends BaseController {
public function index() {
return view('signin/index');
}
public function authenticate() {
if ($this->exists($_POST['email'], $_POST['password']) != NULL) {
$session = session();
$session->set('email', $_POST['email']);
return $this->response->redirect(site_url('signin/profile'));
} else {
$data['msg'] = 'wrong';
return view('signin', $data);
}
}
public function profile() {
return view('signin/profile');
}
private function exists($email, $password) {
$model = new Users_model();
$account = $model->where('email', $email)->first();
if ($account != NULL) {
if (password_verify($password, $account['password'])) {
return $account;
}
}
return NULL;
}
}
Models/Users_model.php
<?php
namespace App\models;
use CodeIgniter\Model;
class Users_model extends Model {
protected $table = 'users';
protected $primaryKey = 'id';
protected $allowedFields = ['first_name', 'last_name', 'email', 'password'];
}
But I face this error:
Please help me.
Or please someone suggest me a login system in another way in Codeigniter 4?
If you want to make login system, I suggest you to use validation to make user is valid and redirect to another controller or view. Then you can use filter to check that user is logged in or not and adding some routes filter to protect other controller.
First read this Codeigniter 4.0.4 documentation https://codeigniter4.github.io/userguide/libraries/validation.html
You could search anything you need there.
return view('signin', $data);
for
return view('signin/index', $data);
I have opted out of using Laravel's built in User Authentication due to my application's requirements. We rely on a Third Party SSO to authenticate our users, and I was unable to get Socialite to work with their SSO, so I am having to custom build a Controller to handle the authentication process. The Controller is performing b-e-a-utifully up until the part when I need to redirect the user from the Callback Route & Controller to the Member Route & Controller. It won't redirect. Period. I have tried every method I know how to redirect to another route from within the controller and it will not work.
Here is my custom AuthController for Laravel 5.3:
<?php
namespace App\Http\Controllers;
use App\User;
use Curl\Curl;
use App\Http\Controllers\PhealController as Pheal;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator;
use Illuminate\Support\Facades\Auth;
use Illuminate\Routing\Redirector;
class AuthController extends Controller
{
protected $curl;
private $data;
public function __construct ()
{
$this->curl = new Curl();
$this->pheal = new Pheal();
$this->data = [];
}
public function sendToSSO()
{
$url = env('EVE_SSO_LOGIN')."?response_type=code&redirect_uri=".env('EVE_CALLBACK_URL')."&client_id=".env('EVE_CLIENT_ID')."&scope=".env('EVE_SCOPES');
return redirect($url);
}
public function handleCallback(Request $request)
{
$this->curl->setHeader('Authorization', "Basic ". base64_encode(env('EVE_CLIENT_ID').":".env('EVE_SECRET')));
$this->curl->setHeader('Content-Type', "application/x-www-form-urlencoded");
$this->curl->setHeader('Host', "login.eveonline.com");
$this->curl->post('https://login.eveonline.com/oauth/token', [
'grant_type' => 'authorization_code',
'code' => $request->code
]);
$response = $this->curl->response;
if (isset($response->error)) {
throw new \Exception($response->error_description);
}
$this->data = [
'accessToken' => $response->access_token,
'refreshToken' => $response->refresh_token
];
$this->verifyToken();
}
public function verifyToken ()
{
$this->curl->setHeader('User-Agent', "David Douglas ddouglas#douglaswebdev.net");
$this->curl->setHeader('Authorization', "Bearer ". $this->data['accessToken']);
$this->curl->setHeader('Host', "login.eveonline.com");
$this->curl->get('https://login.eveonline.com/oauth/verify');
$response = $this->curl->response;
if (isset($response->error)) {
throw new \Exception($response->error_description);
}
$this->data['characterID'] = $response->CharacterID;
$this->data['characterName'] = $response->CharacterName;
$this->data['accessTokenExpire'] = $response->ExpiresOn;
try {
$characterInfo = $this->pheal->call('eve', 'CharacterInfo', ['characterID' => $this->data['characterID']])['result'];
} catch (\Exceoption $e) {
abort(404);
}
if (!isset($characterInfo['allianceID'])) {
abort(403, "Care Factor Alliance Members Only. Sorry :-(");
}
if ($characterInfo['allianceID'] !== env('CF-ALLIANCE-ID')) {
abort(403, "Care Factor Alliance Members Only. Sorry :-(");
}
$this->data['corporationID'] = $characterInfo['corporationID'];
$this->data['corporation'] = $characterInfo['corporation'];
$user = User::find($this->data['characterID']);
if ($user) {
$this->updateUserAndLogin($user);
} else {
$this->createNewUserAndLogin();
}
}
private function getData()
{
return $this->data;
}
public function createNewUserAndLogin()
{
dd('To be Created');
}
public function updateUserAndLogin($user)
{
$user->corporationID = $this->data['corporationID'];
$user->corporation = $this->data['corporation'];
$user->accessToken = $this->data['accessToken'];
$user->refreshToken = $this->data['refreshToken'];
$user->accessTokenExpire = $this->data['accessTokenExpire'];
$user->save();
//Auth::login($user);
return redirect('member/dashboard/');
}
}
I have also tried:
return redirect()->route('member.dashboard');
With no luck.
You mean the $this->createNewUserAndLogin()? Maybe trying return $this->updateUserAndLogin($user); and return $this->verifyToken(); so you return the response on the main method of the route?
For some reason I can't save to the database. No errors, just nothing updating. I know the commands are correctly working, because returning the $user afterwards gives me the respective fields modified. But somewhere the information isn't getting put into the database.
The blade can be found here: http://pastebin.com/8bAEsjtj
The request form can be found here: http://pastebin.com/ZCD1Xvjn
This is the controller:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Http\Requests\UserFormRequest;
use App\UserEdit;
use DB;
use App\Http\Requests;
class EditUserController extends Controller
{
public function index()
{
$array = UserEdit::all()->toArray();
return view('UserEntry', compact('array'));
}
public function create()
{
//
}
public function store()
{
//
}
public function show($ID)
{
try {
$array = UserEdit::findorFail($ID)->toArray();
return view('UserEdit')->with('array', $array);
} catch(\Exception $e) {
return \Redirect::route('users.index')
->withMessage('This user does not exist');
}
}
public function edit(UserEdit $user)
{
return view('EditUser', compact('user'));
}
public function update(UserFormRequest $request, UserEdit $user)
{
//$input->$request->all();
//$user->fill(Input::all());
$user->fill([
'name' => $request->get('name'),
'email' => $request->get('email'),
'First_Name' => $request->get('First_Name'),
'Last_Name' => $request->get('Last_Name')
]);
//$user->name = Input::get('name');
//$user->email = Input::get('email');
//$user->First_Name = Input::get('First_Name');
//$user->Last_Name = Input::get('Last_Name');
$user->save();
//$user->save();
// return redirect()->route('users.index')->with('message', 'Details Updated!');
return $user;
}
public function destroy($id)
{
//
}
}
Pretty sure that's all above board, so why wouldn't it work? Am I missing some detail somewhere? This is the model: http://pastebin.com/vJBzfUVu
Ok. Found the answer, there's a difference between how mysql and php handle the 'id' in a database table.
In this instance, because I've inherited the database from other devs, the id column was capitalised.
This probably made the php laravel generates throw an error as it was looking for 'id' and didn't find anything.
I didn't notice this because it didn't actually print that error, and my other code was accounting for the capitalisation.
Changing the ID to id and fixing the references in my code seems to have solved the problem.
Is there a way that the below code can be shortened? It's starting to look a bit messy and I wanted to know if there was a better way.
/**
* Update user.
*
* #param $request
* #param $id
* #return mixed
*/
public function updateUser($request, $id)
{
// Get user
$user = $this->user->find($id);
// Sync job titles
if($request->has('job_title'))
{
$user->jobTitles()->sync((array)$request->get('job_title'));
} else {
$user->jobTitles()->detach();
}
// Sync employee types
if($request->has('employee_type'))
{
$user->employeeTypes()->sync((array)$request->get('employee_type'));
} else {
$user->employeeTypes()->detach();
}
if($request->has('status')) {
$data = $request->only('first_name', 'last_name', 'email', 'status');
} else {
$data = $request->only('first_name', 'last_name', 'email');
}
// Save user changes
return $this->user->whereId($id)->update($data);
}
Any help would be appreciated.
Here is what I would have done:
Extracted the ManyToMany relationships to their own methods.
Initialized the $data variable and overridden it if necessary.
Removed the comments. The code is readable enough, no need for them
Code:
public function updateUser($request, $id)
{
$user = $this->user->find($id);
$data = $request->only('first_name', 'last_name', 'email');
$this->syncJobTitles($user);
$this->syncEmployeeTypes($user);
if($request->has('status')) {
$data['status'] = $request->status;
}
return $user->update($data);
}
private function syncJobTitles($user)
{
if(request()->has('job_title'))
{
$user->jobTitles()->sync((array) request()->get('job_title'));
} else {
$user->jobTitles()->detach();
}
}
private function syncEmployeeTypes($user)
{
if(request()->has('employee_type'))
{
$user->employeeTypes()->sync((array) request()->get('employee_type'));
} else {
$user->employeeTypes()->detach();
}
}
There are different ways to refactor that code:
If that code is only used on that part of your code you could leave it there or
Option 1
Move that business logic to the user model
class User extends Eloquent
{
...
public function applySomeRule($request)
{
if($request->has('job_title')) {
$this->jobTitles()->sync((array)$request->get('job_title'));
} else {
$this->jobTitles()->detach();
}
// Sync employee types
if($request->has('employee_type')) {
$this->employeeTypes()->sync((array)$request->get('employee_type'));
} else {
$this->employeeTypes()->detach();
}
}
}
And your controller could finish like
public function updateUser($request, $id)
{
// Get user
$user = $this->user->find($id);
$user->applySomeRule($request);
if($request->has('status')) {
$data = $request->only('first_name', 'last_name', 'email', 'status');
} else {
$data = $request->only('first_name', 'last_name', 'email');
}
// Save user changes
return $this->user->whereId($id)->update($data);
}
Option 2 If that business logic is used on different controller methods you can use Middlewares, so that you move that logic to middleware and in your route definition you use the middleware you created, let's say SomeRuleMiddleware.
Your routes would look like:
Route::put('user/{id}', [
'middleware' => 'SomeRuleMiddleware',
'uses' => 'YourController#updateUser'
]);
Option 3 You could move all your business logic to Repositories (read about Repository Pattern) and SOLID principles, that way your logic and rules will keep on Repositories and your controllers would keep clean, something like this:
class YourController extends Controller
{
protected $userRepo;
public function __construct(UserRepository $userRepo)
{
$this->userRepo = $userRepo;
}
public function updateUser($request, $id)
{
$data = $request->all();
$result = $this->userRepo->updateUser($id, $data);
return $result;
}
}
From a user login form i need to use their username ($this->input->post('username')) to query against the membership table in my database so that I can retrieve the users firstname and lastname, which I believe should be done via a model called from my controller. I then need to pass that data back to my controller to use the firstname and lastname to add in to my session userdata which is set in my controller, as shown below.
$data = array(
'username' => $this->input->post('username'),
'firstname' => //need to retrieve value from database,
'lastname' => //need to retrieve value from database,
'is_logged_in' => true
);
$this->session->set_userdata($data);
Thanks,
Kristan.
In your model, make a function to retrieve the first and last name of a user:
public function get_user_details($username){
// retrieve contents from db:
// the first username here is the name of the column in your table
$query = $this->db->select('firstname, lastname')
->where('username', $username)
->get('membership');
return $query->result_array();
}
In your controller, like you were doijng, grab the POST contents in your controller:
$username = $this->input->post('username');
Then, from your controller, call your model function but save the output of that model function in a variable:
$data = $this->user_model->get_user_details($username);
After that, you can do what you were trying to do:
$this->session->set_userdata($data);
Hope that helps. I wrote this from the top of my head but it should work. I also suggest you read the CI documentation through because it really is some of the best documentation I have ever seen for a framework. Good luck.
Please check CodeIgniter user guide for model. The example of Blog controller and Blog model will answer you.
class Blogmodel extends CI_Model {
var $title = '';
var $content = '';
var $date = '';
function __construct()
{
// Call the Model constructor
parent::__construct();
}
function get_last_ten_entries()
{
$query = $this->db->get('entries', 10);
return $query->result();
}
function insert_entry()
{
$this->title = $_POST['title']; // please read the below note
$this->content = $_POST['content'];
$this->date = time();
$this->db->insert('entries', $this);
}
function update_entry()
{
$this->title = $_POST['title'];
$this->content = $_POST['content'];
$this->date = time();
$this->db->update('entries', $this, array('id' => $_POST['id']));
}
}
class Blog_controller extends CI_Controller {
function blog()
{
$this->load->model('Blog');
$data['query'] = $this->Blog->get_last_ten_entries();
$this->load->view('blog', $data);
}
}
You first need to create a model.
class Membership_model extends CI_Model {
function __construct() {
parent::__construct();
}
function getUser($username) {
$query = $this->db->get_where('membership', array('username' => $username));
return $query->result_array();
}
}
then in your controller, use the membership model to retrieve data. Calling this function: $this->membership_model->getUser($this->input->post('username'));