I am working on a sales laravelcollective form whereby the sale_quantity entered should not be more than the stock_quantity in DB. When I use the idea at: Laravel validate dynamically added input with custom messages there is one answer with:
'orderQty.*' => 'required|numeric|min:1|max:'.$product['productQty']
I have done this as you will see in my function store and function update in the SalesController.php, no error occurs but the form refuses to submit and shows this as a flash message:
The sale quantity may not be greater than '.$stocks['stock_quantity'].
It does not mean what it shows because their is a greater stock_quantity in the database.
SalesController.php
<?php
namespace App\Http\Controllers;
use Illuminate\Support\Facades\DB;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use App\Sale;
use App\Stock;
class SalesController extends Controller
{
/**
* Display a listing of the resource.
*
* #return \Illuminate\Http\Response
*/
function __construct()
{
$this->middleware('permission:sales-list');
$this->middleware('permission:sales-create', ['only' => ['create', 'store']]);
$this->middleware('permission:sales-edit', ['only' => ['edit', 'update']]);
$this->middleware('permission:sales-delete', ['only' => ['destroy']]);
}
/**
* Display a listing of the resource.
*
* #return \Illuminate\Http\Response
*/
public function index()
{
$sales = Sale::orderBy('updated_at', 'desc')->get();
return view('sales.index')->with('sales', $sales);
}
/**
* Show the form for creating a new resource.
*
* #return \Illuminate\Http\Response
*/
public function create()
{
$stocks = Stock::all();
//dd($stocks);
return view('sales.create', compact('stocks'));
//$sales = Sale::pluck('stock_id')->prepend('stock_id');
//$sales = DB::table('stocks')->select('stock_id')->get();
//return view('sales.create')->with('sales',$sales);
}
public function getUnitSellingPrice(Request $request, $stock_name)
{
$stock = Stock::where('stock_name', $stock_name)->first();
if ($stock == null) {
return null;
}
return response()->json($stock->unit_selling_price);
}
public function store(Request $request)
{
$this->validate($request, [
'stock_name' => 'required',
'sale_quantity' => 'required|numeric|min:1|max:\'.$stock[\'stock_quantity\']',
'unit_selling_price' => 'required',
'total_sales_cost' => 'required'
]);
//create stock
$sale = new Sale;
$sale->stock_name = $request->input('stock_name');
$sale->sale_quantity = $request->input('sale_quantity');
$sale->unit_selling_price = $request->input('unit_selling_price');
$sale->total_sales_cost = $request->input('total_sales_cost');
$sale->save();
DB::table('stocks')->where('stock_name', $request->input('stock_name'))->decrement('stock_quantity', $request->input('sale_quantity'));
return redirect('/sales')->with('success', 'Sale Saved');
}
public function show($sales_id)
{
$sale = Sale::find($sales_id);
return view('sales.show')->with('sale', $sale);
}
/**
* Show the form for editing the specified resource.
*
* #param int $sales_id
* #return \Illuminate\Http\Response
*/
public function edit($sales_id)
{
$sale = Sale::findOrFail($sales_id);
$stocks = Stock::latest('stock_name', 'unit_selling_price')->get();
return view('sales.edit', compact('sale', 'stocks'));
}
/**
* Update the specified resource in storage.
*
* #param \Illuminate\Http\Request $request
* #param int $sales_id
* #return \Illuminate\Http\Response
*/
public function update(Request $request, $sales_id)
{
$this->validate($request, [
'stock_name' => 'required',
'sale_quantity' => 'required|numeric|min:1|max:\'.$stock[\'stock_quantity\']',
'unit_selling_price' => 'required',
'total_sales_cost' => 'required'
]);
//create stock
$sale = Sale::find($sales_id);
$sale->stock_name = $request->input('stock_name');
$sale->sale_quantity = $request->input('sale_quantity');
$sale->unit_selling_price = $request->input('unit_selling_price');
$sale->total_sales_cost = $request->input('total_sales_cost');
$sale->save();
return redirect('/sales')->with('success', 'Sale Updated');
}
/**
* Remove the specified resource from storage.
*
* #param int $sales_id
* #return \Illuminate\Http\Response
*/
public function destroy($sales_id)
{
$sale = Sale::find($sales_id);
$sale->delete();
return redirect('/sales')->with('success', 'Sale Removed');
}
}
create.blade.php
#extends('layouts.app')
#section('content')
<br>
<h1>Add Sale</h1>
{!! Form::open(['action' => 'SalesController#store', 'method' => 'POST', 'enctype' => 'multipart/form-data']) !!}
<div class="form-group">
<label>Product Name</label>
<select name="stock_name" id="stock_name" class="form-control">
#foreach ($stocks as $stock)
<option value="{{ $stock->stock_name }}">{{ $stock->stock_name}}</option>
#endforeach
</select>
</div>
<div class="form-group">
{{Form::label('sale_quantity', 'Quantity')}}
{{Form::text('sale_quantity', '', ['class' => 'form-control', 'placeholder' => 'Quantity', 'id' => 'sales_quantity'])}}
</div>
<div class="form-group">
{{Form::label('unit_selling_price', 'Unit Selling Price')}}
{{Form::text('unit_selling_price', '', ['class' => 'form-control', 'placeholder' => 'Unit Selling Price', 'id' => 'unit_selling_price'])}}
</div>
<div class="form-group">
{{Form::label('total_sales_cost', 'Total Sales Cost')}}
{{Form::text('total_sales_cost', '', ['class' => 'form-control', 'placeholder' => 'Total Sales Cost', 'id' => 'total_sales_cost', 'readonly' => 'true', 'cursor: pointer' => 'true' ])}}
</div>
{{Form::submit('Submit', ['class' => 'btn btn-primary'])}}
{!! Form::close() !!}
<script>
$(document).ready(function () {
$("#stock_name").on('change', function () {
var stock_name = $(this).val();
$.ajax({
url: '/sales-price/getunitsellingprice/'+stock_name,
method: 'GET',
success: function (response) {
console.log(response);
$("#unit_selling_price").val(response);
},
});
});
});
</script>
<script>
$(document).ready(function () {
$("#total_sales_cost").click(function () {
var sales_quantity = $("#sales_quantity").val();
var unit_selling_price = $("#unit_selling_price").val();
var total_sales_cost = (sales_quantity * unit_selling_price);
$('#total_sales_cost').val(total_sales_cost);
});
});
</script>
#endsection
SalesController.php changes at function store and update.
Those are the only changes, the blade was Okay.
<?php
namespace App\Http\Controllers;
use App\Http\Requests;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use App\Sale;
use DB;
use App\Stock;
class SalesController extends Controller
{
function __construct()
{
$this->middleware('permission:sales-list');
$this->middleware('permission:sales-create', ['only' => ['create', 'store']]);
$this->middleware('permission:sales-edit', ['only' => ['edit', 'update']]);
$this->middleware('permission:sales-delete', ['only' => ['destroy']]);
}
public function index()
{
$sales = Sale::orderBy('updated_at', 'desc')->get();
return view('sales.index')->with('sales', $sales);
}
public function create()
{
$stocks = Stock::all();
//dd($stocks);
return view('sales.create', compact('stocks'));
//$sales = Sale::pluck('stock_id')->prepend('stock_id');
//$sales = DB::table('stocks')->select('stock_id')->get();
//return view('sales.create')->with('sales',$sales);
}
public function getUnitSellingPrice(Request $request, $stock_name)
{
$stock = Stock::where('stock_name', $stock_name)->first();
if ($stock == null) {
return null;
}
return response()->json($stock->unit_selling_price);
}
public function getStockUnitCost(Request $request, $stock_name)
{
$stock = Stock::where('stock_name', $stock_name)->first();
if ($stock == null) {
return null;
}
return response()->json($stock->stock_unit_cost);
}
public function salesWebReport(){
$sales = Sale::orderBy('updated_at', 'desc')->get();
return view('sales.saleswebreport')->with('sales', $sales);
}
public function photocopying(){
$stocks = Stock::all();
//dd($stocks);
return view('sales.photocopy', compact('stocks'));
}
public function store(Request $request)
{
//get retrieves an array
//$stock = \App\Stock::where('stock_name', $request->input('stock_name'))->get();
//first retrieves an array BUT removes everything and produces only the required field value
$stock = Stock::where('stock_name', $request->input('stock_name'))->firstOrFail();
$qty = $stock->stock_quantity;
$this->validate($request, [
'stock_name' => 'required',
'sale_quantity' => 'required|numeric|min:1|max:'.$qty,
'unit_selling_price' => 'required',
'total_sales_cost' => 'required',
'stock_profit' => 'required'
]);
//create stock
$sale = new Sale;
$sale->stock_name = $request->input('stock_name');
$sale->sale_quantity = $request->input('sale_quantity');
$sale->unit_selling_price = $request->input('unit_selling_price');
$sale->total_sales_cost = $request->input('total_sales_cost');
$sale->stock_profit = $request->input('stock_profit');
$sale->save();
DB::table('stocks')->where('stock_name', $request->input('stock_name'))->decrement('stock_quantity', $request->input('sale_quantity'));
return redirect('/sales')->with('success', 'Sale Saved');
}
public function show($sales_id)
{
$sale = Sale::find($sales_id);
return view('sales.show')->with('sale', $sale);
}
public function edit($sales_id)
{
$sale = Sale::findOrFail($sales_id);
$stocks = Stock::latest('stock_name', 'unit_selling_price')->get();
return view('sales.edit', compact('sale', 'stocks'));
}
public function update(Request $request, $sales_id)
{
//get retrieves an array
//$stock = \App\Stock::where('stock_name', $request->input('stock_name'))->get();
//first retrieves an array BUT removes everything and produces only the required field value
$stock = Stock::where('stock_name', $request->input('stock_name'))->firstOrFail();
$qty = $stock->stock_quantity;
$this->validate($request, [
'stock_name' => 'required',
'sale_quantity' => 'required|numeric|min:1|max:'.$qty,
'unit_selling_price' => 'required',
'total_sales_cost' => 'required',
'stock_profit' => 'required'
]);
//create stock
$sale = Sale::find($sales_id);
$sale->stock_name = $request->input('stock_name');
$sale->sale_quantity = $request->input('sale_quantity');
$sale->unit_selling_price = $request->input('unit_selling_price');
$sale->total_sales_cost = $request->input('total_sales_cost');
$sale->stock_profit = $request->input('stock_profit');
$sale->save();
return redirect('/sales')->with('success', 'Sale Updated');
}
public function destroy($sales_id)
{
$sale = Sale::find($sales_id);
$sale->delete();
return redirect('/sales')->with('success', 'Sale Removed');
}
}
According to the error shown, it may be that it is taking your variable and array data as a literal string in this line:
'sale_quantity' => 'required|numeric|min:1|max:\'.$stock[\'stock_quantity\']',
Give a try with php double quotes:
'sale_quantity' => "required|numeric|min:1|max:$stock['stock_quantity']",
Or, to make it even easier for the interpreter, assign a simple variable before the validation step:
$qty = $stock['stock_quantity'];
and then in the validator:
'sale_quantity' => "required|numeric|min:1|max:$qty",
You may wish to consider using some type of validation on the client side to make this even stronger as well as to help users. Perhaps pass that $qty value from your edit/create methods on your controller to the blade page, and then use something like JQuery Validation to check on the form before the user even submits it to the server.
So - to solve it, something like this:
public function store(Request $request)
{
$stock = \App\Stock::find($someIdOfYourChoiceOrFromTheForm)
$qty = $stock->stock_quantity;
$this->validate($request, [
'stock_name' => 'required',
'sale_quantity' => "required|numeric|min:1|max:$qty",
'unit_selling_price' => 'required',
'total_sales_cost' => 'required'
]);
Related
I am using Laravel 5.5.14 (php artisan --version). I am using Laravel to create just a REST API.
When I get errors, the shape of it looks like this:
[
'message' => 'The given data was invalid.',
'errors' => [
'email' => ['The email field is required.'],
'password' => ['The password field is required.']
]
]
My
We see inside the errors array, each field (email, password) instead of being strings, is an array of a single string. Can there ever be more then one error is this why it is an array? Even if there is more then one error, I wanted to tell Laravel just report the first error without an array, is this possible?
In my api.php I have this:
Route::post('login', 'Auth\LoginController#login');
Route::post('logout', 'Auth\LoginController#logout');
Route::post('register', 'Auth\RegisterController#register');
My LoginController.php looks like this:
public function __construct()
{
$this->middleware('guest')->except('logout');
}
public function login(Request $request)
{
$this->validateLogin($request);
if ($this->attemptLogin($request)) {
$user = $this->guard()->user()->load('pets');
$user->generateToken();
return $user;
}
return $this->sendFailedLoginResponse($request);
}
public function logout(Request $request)
{
$user = Auth::guard('api')->user();
if ($user) {
$user->api_token = null;
$user->save();
}
return ['ok' => true];
}
And my RegisterController.php looks like this:
public function __construct()
{
$this->middleware('guest');
}
/**
* The user has been registered.
*
* #param \Illuminate\Http\Request $request
* #param mixed $user
* #return mixed
*/
protected function registered(Request $request, $user)
{
$user->generateToken();
return response()->json($user, 201);
}
/**
* Get a validator for an incoming registration request.
*
* #param array $data
* #return \Illuminate\Contracts\Validation\Validator
*/
protected function validator(array $data)
{
return Validator::make($data, [
'name' => 'required|string|max:255',
'email' => 'required|string|email|max:255|unique:users',
'password' => 'required|string|min:6|confirmed',
]);
}
/**
* Create a new user instance after a valid registration.
*
* #param array $data
* #return \App\User
*/
protected function create(array $data)
{
return User::create([
'name' => $data['name'],
'email' => $data['email'],
'password' => bcrypt($data['password']),
]);
}
Override validateLogin to the following or you could give it a different name and call it from your controller function-
public function validateLogin($request){
$rules = [
'user_name' => 'required|string',
'password' => 'required|string',
];
$validator = Validator::make($request->all(), $rules);
if ($validator->fails()) {
$errorResponse = $this->validationErrorsToString($validator->errors());
return response()->json(['message' => 'The given data was invalid.', 'errors' => $errorResponse],400);
}
}
And make another function to transform your response to expected format with this method-
private function validationErrorsToString($errArray) {
$valArr = array();
foreach ($errArray->toArray() as $key => $value) {
$valArr[$key] = $value[0];
}
return $valArr;
}
And don't forget to add this at the start of your controller file-
use Validator;
Hope this helps you :)
From the docs:
The $errors variable will be an instance of Illuminate\Support\MessageBag
An example of displaying errors from the docs:
#if ($errors->any())
<div class="alert alert-danger">
<ul>
#foreach ($errors->all() as $error)
<li>{{ $error }}</li>
#endforeach
</ul>
</div>
#endif
I have an asset_category table(columns 'asset_category_id', 'category') and an asset table(columns 'asset_id', 'asset_category_id') and want display the (columns 'asset_id', 'asset_category_id.category,') from the asset table instead of just the 'asset_id' n 'asset_category_id' columns.
Asset_CatoriesController
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Asset_category;
class Asset_CategoriesController extends Controller
{
public function asset_category(){
$asset_categories = Asset_category::all();
return view('category', ['asset_categories' => $asset_categories]);
}
public function add(Request $request){
$this->validate($request, [
'asset_category_id' => '',
'category' => 'required'
]);
$asset_categories = new Asset_category;
$asset_categories ->asset_category_id = $request->input('asset_category_id');
$asset_categories ->category = $request->input('category');
$asset_categories ->save();
return redirect('/category') ->with('info', 'New Category Saved Successfully!');
}
public function update($id){
$asset_categories = Asset_category::find($id);
return view('update', ['asset_categories' => $asset_categories]);
}
public function edit(Request $request, $id){
$this->validate($request, [
'asset_category_id' => '',
'category' => 'required'
]);
$data = array(
'category' => $request ->input('category')
);
Asset_category::where('asset_category_id', $id)->update($data);
return redirect('/category') ->with('info', 'Category Updated Successfully!');
}
public function delete($id){
Asset_category::where('asset_category_id', $id)
->delete();
return redirect('/category') ->with('info', 'Category Deleted Successfully!');
}
}
AssetController
<?php
namespace App\Http\Controllers;
use App\Asset;
use App\Asset_category;
use App\Manufacturer;
use App\Department;
use Illuminate\Http\Request;
class AssetController extends Controller
{
public function asset(){
$assets = Asset::all();
// return view::make('viewAsset')->with('assets', $assets);
return view('viewAsset', ['assets' => $assets]);
}
public function manufacturer(){
$manufacturers = Manufacturer::all();
return view('asset', ['manufacturers' => $manufacturers]);
}
public function add(Request $request){
$this->validate($request, [
'asset_id' => '',
'asset_category_id' => 'required',
'manufacturer_id' => 'required',
'department_id' => 'required',
]);
$assets = new Asset;
$assets ->asset_id = $request->input('asset_id');
$assets ->asset_category_id = $request->input('asset_category_id');
$assets ->manufacturer_id = $request->input('manufacturer_id');
$assets ->department_id = $request->input('department_id');
$assets ->save();
return redirect('/viewAsset') ->with('info', 'New Asset Saved Successfully!');
}
public function update($id){
$assets = Asset::find($id);
return view('updateAsset', ['assets' => $assets]);
}
public function edit(Request $request, $id){
$this->validate($request, [
'asset_id' => '',
'asset_category_id' => 'required',
'manufacturer_id'=> 'required',
'department_id' => 'required'
]);
$data = array(
'asset_category_id' => $request ->input('asset_category_id'),
'manufacturer_id' => $request ->input('manufacturer_id'),
'department_id' => $request ->input('department_id')
);
Asset::where('asset_id', $id)->update($data);
return redirect('/viewAsset') ->with('info', 'Asset Updated Successfully!');
}
public function delete($id){
Asset::where('asset_id', $id)
->delete();
return redirect('/viewAsset') ->with('info', 'Asset Deleted Successfully!');
}
}
Asset.php
namespace App;
use Illuminate\Database\Eloquent\Model;
use App\Asset_category;
class Asset extends Model
{
protected $primaryKey = 'asset_id';
public function category(){
return $this->belongsTo('Asset_category');
//$this->belongsTo('Asset_category');
//Asset_category::where('asset_category_id', $this->asset_category_id)->first()->category;
}
}
Asset_category.php
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
use App\Asset;
class Asset_category extends Model
{
protected $primaryKey = 'asset_category_id';
public function asset() {
return $this->hasMany('Asset', 'asset_category_id');
}
}
viewAsset.php
#foreach($assets->all() as $asset)
<tr>
<td>{{ $asset->asset_id}}</td>
<td>{{ $asset->category->category}}</td>
when i run the project i get a FatalErrorExeception which says
Class 'Asset_category' not found in HasRelationships.php
You have Asset_category in a namespace. Try changing this:
return $this->belongsTo('Asset_category');
to this:
return $this->belongsTo(Asset_category::class);
You must end #foreach with #endforeach
You must declare protected $table = 'table_name'; in model because in default laravel generate table name to plural form of model's class name
Try to return this:
return $this->belongsTo('Asset_category');
return $this->hasMany('Asset', 'asset_category_id');
to this:
return $this->belongsTo(Asset_category::class);
return $this->hasMany(Asset::class, 'asset_category_id');
i want to add profile avatar in frontend/web/site/signup but there is an error
it said
Unknown Method – yii\base\UnknownMethodException
Calling unknown method: frontend\models\SignupForm::save()
this is the signup.php on frontend/views/site/signup.php
<?php
/* #var $this yii\web\View */
/* #var $form yii\bootstrap\ActiveForm */
/* #var $model \frontend\models\SignupForm */
use yii\helpers\Html;
use yii\bootstrap\ActiveForm;
$this->title = 'Signup';
$this->params['breadcrumbs'][] = $this->title;
?>
<div class="site-signup">
<h1><?= Html::encode($this->title) ?></h1>
<p>Please fill out the following fields to signup:</p>
<div class="row">
<div class="col-lg-5">
<?php $form = ActiveForm::begin(['id' => 'form-signup'],['options' => ['enctype' => 'multipart/form-data']]); ?>
<?= $form->field($model, 'first_name')->textInput(['placeholder' => "First Name"]) ?>
<?= $form->field($model, 'last_name')->textInput(['placeholder' => "Last Name"]) ?>
<?= $form->field($model, 'username')->textInput(['placeholder' => "Username"]) ?>
<?= $form->field($model, 'email')->textInput(['placeholder' => "Email"]) ?>
<?= $form->field($model, 'password')->passwordInput(['placeholder' => "Password"]) ?>
<?= $form->field($model, 'file')->fileInput() ?>
<div class="form-group">
<?= Html::submitButton('Signup', ['class' => 'btn btn-primary', 'name' => 'signup-button']) ?>
</div>
<?php ActiveForm::end(); ?>
</div>
</div>
</div>
this is the SiteController.php
<?php namespace frontend\controllers;
use Yii; use yii\base\InvalidParamException; use yii\web\BadRequestHttpException; use yii\web\Controller; use yii\web\UploadedFile; use yii\filters\VerbFilter; use yii\filters\AccessControl; use common\models\LoginForm; use frontend\models\PasswordResetRequestForm; use frontend\models\ResetPasswordForm; use frontend\models\SignupForm; use frontend\models\ContactForm;
/** * Site controller */ class SiteController extends Controller {
/**
* #inheritdoc
*/
public function behaviors()
{
return [
'access' => [
'class' => AccessControl::className(),
'only' => ['logout', 'signup'],
'rules' => [
[
'actions' => ['signup'],
'allow' => true,
'roles' => ['?'],
],
[
'actions' => ['logout'],
'allow' => true,
'roles' => ['#'],
],
],
],
'verbs' => [
'class' => VerbFilter::className(),
'actions' => [
'logout' => ['post'],
],
],
];
}
/**
* #inheritdoc
*/
public function actions()
{
return [
'error' => [
'class' => 'yii\web\ErrorAction',
],
'captcha' => [
'class' => 'yii\captcha\CaptchaAction',
'fixedVerifyCode' => YII_ENV_TEST ? 'testme' : null,
],
];
}
/**
* Displays homepage.
*
* #return mixed
*/
public function actionIndex()
{
return $this->render('index');
}
/**
* Logs in a user.
*
* #return mixed
*/
public function actionLogin()
{
if (!Yii::$app->user->isGuest) {
return $this->goHome();
}
$model = new LoginForm();
if ($model->load(Yii::$app->request->post()) && $model->login()) {
return $this->goBack();
} else {
return $this->render('login', [
'model' => $model,
]);
}
}
/**
* Logs out the current user.
*
* #return mixed
*/
public function actionLogout()
{
Yii::$app->user->logout();
return $this->goHome();
}
/**
* Displays contact page.
*
* #return mixed
*/
public function actionContact()
{
$model = new ContactForm();
if ($model->load(Yii::$app->request->post()) && $model->validate()) {
if ($model->sendEmail(Yii::$app->params['adminEmail'])) {
Yii::$app->session->setFlash('success', 'Thank you for contacting us. We will respond to you as soon as possible.');
} else {
Yii::$app->session->setFlash('error', 'There was an error sending your message.');
}
return $this->refresh();
} else {
return $this->render('contact', [
'model' => $model,
]);
}
}
/**
* Displays about page.
*
* #return mixed
*/
public function actionAbout()
{
return $this->render('about');
}
/**
* Signs user up.
*
* #return mixed
*/
public function actionSignup()
{
$model = new SignupForm();
if ($model->load(Yii::$app->request->post())) {
//upload file
$path = Yii::getAlias('#frontend') .'/web/upload/';
$imageName = $model->username;
$model->file = UploadedFile::getInstance($model,'file');
$model->file->saveAs( 'uploads/img/user'.$imageName.'.'.$model->file->extension );
$model->file->saveAs( $path.$imageName.'.'.$model->file->extension );
//save in database
$model->avatar = 'uploads/'.$imageName.'.'.$model->file->extension;
$model->save();
if ($user = $model->signup()) {
if (Yii::$app->getUser()->login($user)) {
return $this->goHome();
}
}
}else{
return $this->render('signup', [
'model' => $model,
]);
}
}
/**
* Requests password reset.
*
* #return mixed
*/
public function actionRequestPasswordReset()
{
$model = new PasswordResetRequestForm();
if ($model->load(Yii::$app->request->post()) && $model->validate()) {
if ($model->sendEmail()) {
Yii::$app->session->setFlash('success', 'Check your email for further instructions.');
return $this->goHome();
} else {
Yii::$app->session->setFlash('error', 'Sorry, we are unable to reset password for the provided email address.');
}
}
return $this->render('requestPasswordResetToken', [
'model' => $model,
]);
}
/**
* Resets password.
*
* #param string $token
* #return mixed
* #throws BadRequestHttpException
*/
public function actionResetPassword($token)
{
try {
$model = new ResetPasswordForm($token);
} catch (InvalidParamException $e) {
throw new BadRequestHttpException($e->getMessage());
}
if ($model->load(Yii::$app->request->post()) && $model->validate() && $model->resetPassword()) {
Yii::$app->session->setFlash('success', 'New password saved.');
return $this->goHome();
}
return $this->render('resetPassword', [
'model' => $model,
]);
} }
<?php
namespace frontend\controllers;
use Yii;
use yii\base\InvalidParamException;
use yii\web\BadRequestHttpException;
use yii\web\Controller;
use yii\web\UploadedFile;
use yii\filters\VerbFilter;
use yii\filters\AccessControl;
use common\models\LoginForm;
use frontend\models\PasswordResetRequestForm;
use frontend\models\ResetPasswordForm;
use frontend\models\SignupForm;
use frontend\models\ContactForm;
/**
* Site controller
*/
class SiteController extends Controller
and this is the SignupForm.php on frontend/models/SignupForm.php
<?php
namespace frontend\models;
use yii\base\Model;
use common\models\User;
/**
* Signup form
*/
class SignupForm extends Model
{
public $first_name;
public $last_name;
public $username;
public $email;
public $password;
public $avatar;
public $file;
/**
* #inheritdoc
*/
public function rules()
{
return [
['first_name', 'required'],
['last_name', 'required'],
[['file'],'file', 'extensions'=>'jpg, gif, png'],
['username', 'trim'],
['username', 'required'],
['username', 'unique', 'targetClass' => '\common\models\User', 'message' => 'This username has already been taken.'],
['username', 'string', 'min' => 2, 'max' => 255],
['email', 'trim'],
['email', 'required'],
['email', 'email'],
['email', 'string', 'max' => 255],
['email', 'unique', 'targetClass' => '\common\models\User', 'message' => 'This email address has already been taken.'],
['password', 'required'],
['password', 'string', 'min' => 6],
];
}
/**
* Signs user up.
*
* #return User|null the saved model or null if saving fails
*/
public function signup()
{
if (!$this->validate()) {
return null;
}
$user = new User();
$user->first_name = $this->first_name;
$user->first_name = $this->first_name;
$user->username = $this->username;
$user->email = $this->email;
$user->setPassword($this->password);
$user->generateAuthKey();
$user->avatar = $this->file;
return $user->save() ? $user : null;
}
}
In your controller SiteController, in action actionSignup() youre using:
$model->save()
Your model doesn't extends ActiveRecord class, so it don't have method save().
Remove this $model->save() from controller, youre saving user anyway in method signup().
I want to implement a backend user management but how can i set up a hased password for a user?
my controller:
public function store(Request $request)
{
$this->validate($request, ['email' => 'required', 'name' => 'required', 'password' => 'required', 'surname' => 'required', ]);
$user = new User($request->all());
$user->password=bcrypt($request);
$user->save();
return redirect('dash/users');
}
view
<div class="form-group {{ $errors->has('password') ? 'has-error' : ''}}">
{!! Form::label('password', trans('users.password'), ['class' => 'col-sm-3 control-label']) !!}
<div class="col-sm-6">
{!! Form::text('password', null, ['class' => 'form-control', 'required' => 'required']) !!}
{!! $errors->first('password', '<p class="help-block">:message</p>') !!}
</div>
</div>
fixed now, the function work and my new user are stored in database, but when i try to login with them the loginform say me "nothing record found"
why?
You need to pass the password text to bcrypt instead of whole $request
$user->password=bcrypt('yourpasswordtext');
<?php
namespace App\Http\Controllers\Dash;
use App\Http\Requests;
use App\Http\Controllers\Controller;
use Auth;
use App\User;
use App\Report;
use App\Category;
use Illuminate\Http\Request;
use Carbon\Carbon;
use Session;
class UsersController extends Controller
{
/**
* Display a listing of the resource.
*
* #return void
*/
public function index()
{
$users = User::paginate(15);
return view('dash.users.index', compact('users'));
}
/**
* Show the form for creating a new resource.
*
* #return void
*/
public function create()
{
return view('dash.users.create');
}
/**
* Store a newly created resource in storage.
*
* #return void
*/
public function store(Request $request)
{
$this->validate($request, ['email' => 'required', 'name' => 'required', 'password' => 'required', 'surname' => 'required', ]);
$user = new User($request->all());
$user->password = bcrypt($request);
$user->save();
return redirect('dash/users');
}
/**
* Display the specified resource.
*
* #param int $id
*
* #return void
*/
public function show($id)
{
$user = User::findOrFail($id);
return view('dash.users.show', compact('user'));
}
/**
* Show the form for editing the specified resource.
*
* #param int $id
*
* #return void
*/
public function edit($id)
{
$user = User::findOrFail($id);
return view('dash.users.edit', compact('user'));
}
/**
* Update the specified resource in storage.
*
* #param int $id
*
* #return void
*/
public function update($id, Request $request)
{
$this->validate($request, ['email' => 'required', 'name' => 'required', 'password' => 'required', 'surname' => 'required', ]);
$user = User::findOrFail($id);
$user->update($request->all());
Session::flash('flash_message', 'User updated!');
return redirect('dash/users');
}
/**
* Remove the specified resource from storage.
*
* #param int $id
*
* #return void
*/
public function destroy($id)
{
User::destroy($id);
Session::flash('flash_message', 'User deleted!');
return redirect('dash/users');
}
}
update, this is controller
<?php
/*
|--------------------------------------------------------------------------
| Application Routes
|--------------------------------------------------------------------------
|
| Here is where you can register all of the routes for an application.
| It's a breeze. Simply tell Laravel the URIs it should respond to
| and give it the controller to call when that URI is requested.
|
*/
/* ruote for Admin */
Route::group(['middleware' => ['web']], function () {
Route::resource('dash/reports', 'Dash\\ReportsController');
});
Route::group(['middleware' => ['role:admin']], function () {
Route::resource('dash/categories', 'Dash\\CategoriesController');
});
Route::group(['middleware' => ['role:admin']], function () {
Route::resource('dash/roles', 'Dash\\RolesController');
});
Route::group(['middleware' => ['role:admin']], function () {
Route::resource('dash/permissions', 'Dash\\PermissionsController');
});
Route::group(['middleware' => ['role:admin']], function () {
Route::resource('dash/users', 'Dash\\UsersController');
});
/* another routes */
Route::auth();
Route::get('/provola', 'HomeController#autorizzazione');
Route::get('/home', 'HomeController#index');
Route::get('/', function () {return view('welcome');});
/* injection for user roles
Route::get('/start', 'HomeController#inject');
*/
my routes
For Laravel 5.6+
Password should be hashed using Hash::make($password)
Ajax validation is not triggered, need help finding what is wrong with my code, struggle took long enough to make me seek help here so please help. There is some commented code, that was used while trying to make it work. Getting 500 internal server error:
{"name":"Exception","message":"Attribute name must contain word
characters only."
UserController
public function actionRegister()
{
$model = new Users();
if (Yii::$app->request->isAjax && $model->load(Yii::$app->request->post())) {
$model->scenario = 'ajax';
Yii::$app->response->format = Response::FORMAT_JSON;
Yii::error($model);
$model->validate();
return ActiveForm::validate($model);
//both ways not working the way it should
//return $model->validate();
}
if ($model->load(Yii::$app->request->post())) {
if ($user = $model->register()) {
if (Yii::$app->getUser()->login($user)) {
return $this->goHome();
}
}
}
return $this->render('register', [
'model' => $model,
]);
}
register.php
use yii\helpers\Html;
use yii\bootstrap\ActiveForm;
<?php $form = ActiveForm::begin(['id' => 'form-signsup',
'enableAjaxValidation' => false,
'enableClientValidation' => true,
'id' => 'ajax'
]); ?>
<?= $form->field($model, 'UserName') ?>
<?= $form->field($model, 'Name', ['enableAjaxValidation' => true]) ?>
<?= $form->field($model, 'LastName', ['enableAjaxValidation' => true]) ?>
<?= $form->field($model, 'Email') ?>
<?= $form->field($model, 'PasswordHash', ['enableAjaxValidation' => true])->passwordInput() ?>
<?= $form->field($model, 'repeatPassword', ['enableAjaxValidation' => true])->passwordInput() ?>
<?= Html::submitButton('Register', ['class' => 'btn btn-primary', 'name' => 'signup-button']) ?>
Users.php
<?php
namespace app\models;
use Yii;
use yii\db\ActiveRecord;
use yii\web\IdentityInterface;
use yii\base\NotSupportedException;
use yii\behaviors\TimestampBehavior;
use yii\base\Model;
use yii\web\Response;
use yii\widgets\ActiveForm;
class Users extends ActiveRecord implements IdentityInterface
{
public $rememberMe;
public $repeatPassword;
/**
* #inheritdoc
*/
public static function tableName()
{
return 'users';
}
/**
* #inheritdoc
*/
public function rules()
{
return [
[['UserName', 'PasswordHash', 'Name', 'LastName', 'Email'], 'required'],
[['Name', 'LastName'], 'validateLetters', 'skipOnError' => false, 'on'=>'ajax'],
[['repeatPassword'], 'validatePasswordRepeat', 'skipOnEmpty' => false, 'on'=>'ajax'],
[['IsEnabled'], 'boolean'],
[['rememberMe'], 'boolean'],
[['UserName', 'Name', 'LastName'], 'string', 'max' => 50],
[['Email'], 'email', 'message'=>'Netinkamai įvestas el. paštas.'],
[['PasswordHash', 'repeatPassword' ], 'string', 'max' => 20],
[['Email'], 'string', 'max' => 80]
];
}
public function scenarios()
{
$scenarios = parent::scenarios();
$scenarios['ajax'] = ['Name', 'LastName', 'repeatPassword', 'PasswordHash'];//Scenario Values Only Accepted
//$scenarios['default'] = ['Name','LastName', 'passwordRepeat', 'PasswordHash', 'Email'];
return $scenarios;
// return [
// ['some_scenario' => ['UserName', 'PasswordHash', 'Name', 'LastName', 'Email', 'IsEnabled']],
// ];
}
/**
* #inheritdoc
*/
public function attributeLabels()
{
return [
'Id' => 'ID',
'UserName' => 'Prisijungimo vardas',
'PasswordHash' => 'Slaptažodis',
'Name' => 'Vardas',
'LastName' => 'Pavardė',
'Email' => 'El. paštas',
'IsEnabled' => 'Is Enabled',
'rememberMe' => 'Prisiminti?',
'AuthKey' => 'Authentication key',
'repeatPassword' => 'Pakartoti slaptažodį',
];
}
/**
* #return \yii\db\ActiveQuery
*/
public function getUserRoles()
{
return $this->hasMany(UserRole::className(), ['User_ID' => 'Id']);
}
/**
* Validates password
*
* #param string $password password to validate
* #return boolean if password provided is valid for current user
*/
public function validatePasswordRepeat($attribute)
{
//if(!($this->$attribute == $this->PasswordHash)){
// $this->clearErrors();
$this->addError($this->repeatPassword, 'Slaptažodis nesutampa.');
return $this->addError($this->repeatPassword, 'Slaptažodis nesutampa.');
// }
//$this->addError($attribute, 'Slaptažodis nesutampa.');
// return Yii::$app->security->validatePassword($attribute, $this->PasswordHash);
//return Yii::$app->security->validatePassword($attribute, $this->PasswordHash);
}
/**
* Validates name / last name string so it has no numbers or random symbols
*
* #param string $password password to validate
* #return boolean if password provided is valid for current user
*/
public function validateLetters($attribute)
{
Yii::error($attribute);Yii::error($this->$attribute);
if(!preg_match('/^[a-zA-ZąčęėįšųūžĄČĘĖĮŠŲŪŽ]+$/', $this->$attribute)){
$this->addError($attribute, 'Galima naudoti tik raides.');
}
}
public function register()
{
if ($this->validate()) {
$user = new Users();
$user->UserName = $this->UserName;
$user->Email = $this->Email;
$user->Name = $this->Name;
$user->LastName = $this->LastName;
$user->setPassword($this->PasswordHash);
if ($user->save()) {
return $user;
}
}
// var_dump($user->getErrors()); die();
}
public function login()
{
// $user = $this->getUser();
//var_dump($user);
//echo "----------------------";
//$this->PasswordHash = md5($this->PasswordHash);
//var_dump($this->PasswordHash);
// die();
// if ($this->validate()) {
// $this->PasswordHash = md5($this->PasswordHash);
// return Yii::$app->user->login($this->getUser(), $this->rememberMe ? 3600*24*30 : 0);
// } else {
// return false;
// }
if ($this->validate()) {
//die();
return Yii::$app->user->login($this->getUser(), $this->rememberMe ? 3600 * 24 * 30 : 0);
} else {
return false;
}
}
/**
* #inheritdoc
*/
public static function findIdentity($id)
{
return static::findOne(['id' => $id]);
}
/**
* #inheritdoc
*/
public static function findIdentityByAccessToken($token, $type = null)
{
throw new NotSupportedException('"findIdentityByAccessToken" is not implemented.');
}
/**
* Finds user by username
*
* #param string $username
* #return static|null
*/
public static function findByUsername($UserName)
{
return static::findOne(['UserName' => $UserName]);
}
/**
* Finds user by password reset token
*
* #param string $token password reset token
* #return static|null
*/
public static function findByPasswordResetToken($token)
{
if (!static::isPasswordResetTokenValid($token)) {
return null;
}
return static::findOne([
'password_reset_token' => $token,
'status' => self::STATUS_ACTIVE,
]);
}
/**
* Finds out if password reset token is valid
*
* #param string $token password reset token
* #return boolean
*/
public static function isPasswordResetTokenValid($token)
{
if (empty($token)) {
return false;
}
$expire = Yii::$app->params['user.passwordResetTokenExpire'];
$parts = explode('_', $token);
$timestamp = (int) end($parts);
return $timestamp + $expire >= time();
}
/**
* #inheritdoc
*/
public function getId()
{
return $this->getPrimaryKey();
}
/**
* #inheritdoc
*/
public function getAuthKey()
{
return $this->AuthKey;
}
/**
* #inheritdoc
*/
public function validateAuthKey($authKey)
{
return $this->getAuthKey() === $authKey;
}
/**
* Generates password hash from password and sets it to the model
*
* #param string $password
*/
public function setPassword($password)
{
$this->PasswordHash = Yii::$app->security->generatePasswordHash($password);
}
/**
* Generates "remember me" authentication key
*/
public function generateAuthKey()
{
$this->AuthKey = Yii::$app->security->generateRandomString();
}
/**
* Generates new password reset token
*/
public function generatePasswordResetToken()
{
Hey your code is fine but your mistake is that you provide two id for single form one is form-signsup and ajax. try using only one...:)
<?php $form = ActiveForm::begin(['id' => 'form-signsup',
'enableAjaxValidation' => false,
'enableClientValidation' => true,
//'id' => 'ajax'
]); ?>
In your register.php change the line:
And set it true, and that's it, hope it was helpful 'form-signsup',
'enableAjaxValidation' => 'true',
]); ?>
<?= $form->field($model, 'UserName') ?>
<?= $form->field($model, 'Name') ?>
<?= $form->field($model, 'LastName') ?>
<?= $form->field($model, 'Email') ?>
<?= $form->field($model, 'PasswordHash')->passwordInput() ?>
<?= $form->field($model, 'repeatPassword')->passwordInput() ?>
<?= Html::submitButton('Register', ['class' => 'btn btn-primary', 'name' => 'signup-button']) ?>
I found that AJAX Validation required:
use yii\widgets\ActiveForm;
To be at the top of both the form and the controller.