I am trying to filter my http request by using middleware.
I want to check if the "friends_id" that i am getting from http request and "my_id" that I am passing in through Auth already don't exists in the same row, If they do I wanna redirect to home page and if they don't I wanna execute the normal request which will eventually insert the data that I am checking for
The error is "Trying to get property 'friends_id' of non-object "
Here's my "Friends" middleware:-
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
class Friends
{
public function handle($request, Closure $next)
{ $auth = Auth()->user()->id;
$dost = $request->friends_id;
$ip = DB::table('friends')
->where('my_id', '=', $auth)
->where('friends_id', '=', $dost)
->get();
if($ip->friends_id != $dost){
return $next($request);
}
return redirect('/home');
}
}
Here's my friends Table:-
public function up()
{
Schema::create('friends', function (Blueprint $table) {
$table->id();
$table->string('my_id');
$table->string('friends_id');
$table->string('name');
$table->timestamps();
});
}
This is my Route:-
Route::post('/f', 'FriendsController#store')->middleware('friends');
-ThankYou
Try this
your query will be wrong use where instead of whereColumn and when you get first record use only first() not get()
use DB;
$ip = DB::table('friends')
->select('my_id', 'friends_id')
->where([['my_id', '=', '$auth'],['friends_id', '=', '$dost']])
->first();
EDIT
public function handle($request, Closure $next)
{
$auth = Auth()->user()->id;
$dost = $request->friends_id;
$ip = DB::table('friends')
->select('my_id', 'friends_id')
->where([['my_id', '=', '$auth'],['friends_id', '=', '$dost']])
->first();
if($ip->friends_id == $dost){
return redirect('/home');
} else {
return $next($request);
}
}
The Solution is:-
Friends Middleware:-
public function handle($request, Closure $next)
{
if (auth()->check()) {
$ip = DB::table('friends')->where('my_id', '=', auth()->id())->where('friends_id', '=', $request->friends_id)->first();
if ($ip && $ip->friends_id == $request->friends_id) {
return redirect('/home');
}
}
return $next($request);
}
}
Related
To explain it in detail:
for example, i am creating posts with category, however i am saving it in a different table (post_categories), which means my posts and categories are connected through their IDs (belongToMany). Now in my HomeController i want to display posts, by the category name,
for example: $posts = post::where([['status',1],['category', 'electronics'])->orderBy('created_at', 'DESC')->limit(1)->get();
I want to display my posts by the Category-NAME and not Category-ID
I tried it but it doesnt really work, i guess i forgot something or I am using the wrong methode, pls help me
CODES
Home Controller
public function index()
{
$posts = post::where([['status',1],//here is category missing])->orderBy('created_at', 'DESC')->limit(1)->get();
$categories = Category::all();
return view('user.home', compact('posts', 'categories'));
}
public function category(category $category)
{
$posts = $category->posts();
return view('user.home',compact('posts'));
}
category Model
use HasFactory;
public function posts()
{
return $this->belongsToMany('App\Models\user\post','category_posts')->orderBy('created_at','DESC')->paginate(5);
}
public function getRouteKeyName()
{
return 'slug';
}
post Model
use HasFactory;
public function categories()
{
return $this->belongsToMany('App\Models\user\category','category_posts')->withTimestamps();;
}
public function getRouteKeyName()
{
return 'slug';
}
DATABASE
Posts_table
public function up()
{
Schema::create('posts', function (Blueprint $table) {
$table->id();
$table->string('title',1000);
$table->string('subtitle',1000);
$table->string('slug',1000)->nullable();
$table->text('body');
$table->boolean('status')->nullable();
$table->integer('posted_by')->nullable();
$table->string('image')->nullable();
$table->timestamps();
});
}
Categories_table
public function up()
{
Schema::create('categories', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->string('slug');
$table->timestamps();
});
}
category_posts
public function up()
{
Schema::create('category_posts', function (Blueprint $table) {
$table->unsignedBigInteger('post_id');
$table->unsignedInteger('category_id');
$table->foreign('post_id')->references('id')->on('posts')->onDelete('cascade');
$table->timestamps();
});
}
public function index()
{
$posts = post::with('categories')->where([['status',1],//here is category missing])->orderBy('created_at', 'DESC')->limit(1)->get();
$categories = Category::all();// don't need this line if you don't need all categires
return view('user.home', compact('posts', 'categories'));
}
i already got the answer
i removed the relation and added location to a value in order to c
I noticed that there is new afterMarshal event in 4.1.
Where to put it? In Table model? And how?
I want to do some work with results every time it's loaded.
Thanks for help
For Encryption and Decryption through model in 'CAKEPHP 4'
public $encryptedFields = ['first_name','last_name'];
public function beforeSave($event, $entity, $options)
{
foreach($this->encryptedFields as $fieldName)
{ if($entity->has($fieldName))
{ $entity->set($fieldName, encodeBeforeSave($entity->get($fieldName)));}
} return true;
}
public function beforeFind( $event, $query, $options)
{ $query->formatResults(
function ($results)
{ return $results->map(function ($row){
foreach($this->encryptedFields as $fieldName)
{
if(isset($row[$fieldName]) && !empty($row[$fieldName]) )
{
$row[$fieldName] = decodeBeforefind($row[$fieldName]);
}
}
return $row;
});
}
);
}
I have a validator that checks if a vat-number is correct. In order to do that it calls an external service. This external call slows the tests down and is unreliable, so I would like to mock it, but I don't understand how I could do it.
public function validationDefault(Validator $validator)
{
$validator->setProvider('vat', 'App\Model\Validation\VatValidation');
$validator->add('vat_no', 'isValidVatNo', [
'rule' => 'validVatNumber',
'provider' => 'vat',
]);
}
And this is the validation provider:
<?php
namespace App\Model\Validation;
use Cake\Core\Configure;
use Cake\Validation\Validation;
use VatNumberCheck\Utility\Model\VatNumberCheck;
class VatValidation extends Validation
{
public static function validVatNumber($check)
{
$vatNumberCheck = new VatNumberCheck();
try {
return $vatNumberCheck->check($check);
} catch (InternalErrorException $e) {
return false;
}
}
}
public function testValidationFail() {
$VatValidator = $this->getMockBuilder('Cake\Validation\Validator')
->setMethods(['validVatNumber'])
->getMock();
$VatValidator->expects($this->any())
->method('validVatNumber')
->will($this->returnValue(false));
$this->Users->getValidator()->setProvider('vat', $VatValidator);
$user = $this->Users->newEntity([
'vat_no' => 'asdf',
]);
$errors = $user->errors();
$this->assertArrayHasKey('vat_no', $errors);
}
am following up This tutorial to learn the jwt cool stuff. but when am testing the first bit of the server API with POSTMAN only the id,password fields are the one being inserted in the database. When I try to login with POSTMAN I get
MethodNotAllowedHttpException in RouteCollection.php line 218: from the server preview
my routes
Route::post('api/register', 'TokenAuthController#register');
Route::post('api/authenticate', 'TokenAuthController#authenticate');
Route::get('api/authenticate/user', 'TokenAuthController#getAuthenticatedUser');
my controller
<?php
namespace App\Http\Controllers;
use App\Http\Controllers\Controller;
use Tymon\JWTAuth\Facades\JWTAuth;
use Tymon\JWTAuth\Exceptions\JWTException;
use App\Http\Requests;
use Illuminate\Http\Request;
use App\User;
use Illuminate\Support\Facades\Hash;
class TokenAuthController extends Controller
{
public function authenticate(Request $request)
{
$credentials = $request->only('email', 'password');
try {
if (!$token = JWTAuth::attempt($credentials)) {
return response()->json(['error' => 'invalid_credentials'], 401);
}
} catch (JWTException $e) {
return response()->json(['error' => 'could_not_create_token'], 500);
}
// if no errors are encountered we can return a JWT
return response()->json(compact('token'));
}
public function getAuthenticatedUser()
{
try {
if (!$user = JWTAuth::parseToken()->authenticate()) {
return response()->json(['user_not_found'], 404);
}
} catch (Tymon\JWTAuth\Exceptions\TokenExpiredException $e) {
return response()->json(['token_expired'], $e->getStatusCode());
} catch (Tymon\JWTAuth\Exceptions\TokenInvalidException $e) {
return response()->json(['token_invalid'], $e->getStatusCode());
} catch (Tymon\JWTAuth\Exceptions\JWTException $e) {
return response()->json(['token_absent'], $e->getStatusCode());
}
return response()->json(compact('user'));
}
public function register(Request $request)
{
$newuser = $request->all();
$password = Hash::make($request->input('password'));
$newuser['password'] = $password;
return User::create($newuser);
}
}
I don't know where am messing out this code.
Whenever I call this function, I get the user_id correctly but the password isnt checked...
Model:
<?php
class Prometheus_model extends CI_Model {
var $tables = array(
'bots' => 'bots',
'users' => 'users'
);
function __construct() {
parent::__construct();
}
public function tablename($table = NULL) {
if(! isset($table)) return FALSE;
return $this->tables[$table];
}
public function get($table, $where = array(), $order = NULL) {
$this->db->where($where);
if(isset($order)) {
$this->db->order_by($order);
}
$q = $this->db->get_where($this->tablename($table),$where);
$result = $q->result_array();
// You should use $q->num_rows() to detect the number of returned rows
if($q->num_rows()) {
return $result[0];
}
return $result;
}
public function update($table, $where = array(), $data) {
$this->db->update($this->tablename($table),$data,$where);
return $this->db->affected_rows();
}
public function insert($table, $data) {
$this->db->insert($this->tablename($table),$data);
return $this->db->insert_id();
}
public function delete($table, $where = array()) {
$this->db->delete($this->tablename($table),$where);
return $this->db->affected_rows();
}
public function explicit($query) {
$q = $this->db->query($query);
if(is_object($q)) {
return $q->result_array();
} else {
return $q;
}
}
public function num_rows($table, $where = NULL) {
if(isset($where)){
$this->db->where($where);
}
$q = $this->db->get($table);
return $q->num_rows();
}
public function get_bot_data_by_hw_id($bot_hw_id) {
$q = $this->get('bots', array('bot_hw_id' => $bot_hw_id));
return $q;
}
public function check_user_data($user_incredials, $user_password) {
if($this->num_rows('users', array('user_name' => $user_incredials, 'user_password' => $this->encrypt->decode($user_password))) == 1){
$q = $this->get('users', array('user_name' => $this->security->xss_clean($user_incredials)));
return $q['user_id'];
}
return FALSE;
}
}
?>
My function-calling at the controller:
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
class Login extends CI_Controller {
public function index(){
if($this->input->post('user_login')){
var_dump($this->prometheus_model->check_user_data($this->input->post('user_incredials'), $this->input->post('user_password')));
}
$this->load->view('login_index');
}
}
How can i fixx this ?
In your check_user_data() method you are using
if($this->num_rows('users', array('user_name' => $user_incredials, 'user_password' => $this->encrypt->decode($user_password))) == 1)
I think (logically) following code
$this->encrypt->decode($user_password)
should be
$this->encrypt->encode($user_password)
because, you are calling num_rows() method and it is
public function num_rows($table, $where = NULL)
{
if(isset($where)){
$this->db->where($where);
}
$q = $this->db->get($table);
return $q->num_rows();
}
which is actually querying the data base something like, for example,
select * from USERS where user_name = 'heera' and password = decode('abcde12345')
In this case, the password you are trying to match is need to be encrypted using encode (not decode) method, because the user has given you a non-encrypted (plain) password and the password saved in the database is already encrypted, so encode the plain password using encode method before you query the database to match with already encoded passwords.