I'm trying to learn how to use Laravel and until now I haven't had any problem.
Then I tried to implements an example of Authentication.
1) I created a migration file where i set the User table (password is set to 60, the token is set to 100 following the instructions on laravel site)
2) I used a seeder to generate fake users:
$faker = Faker::create();
foreach(range(1, 10) as $index)
{
User::create([
'firstname' => $faker->firstName(),
'lastname' => $faker->lastName(),
'email' => $faker->email(),
'password' => Hash::make('password'),
'telephone' => $faker->phoneNumber(),
'admin' => rand(0,1)
]);
}
The table in the database is perfectly seeded without problem.
3) I created a controller UserController with the following function
public function postCreate() {
$validator = Validator::make($data = Input::all(), User::$rules);
if ($validator->fails()) {
return Redirect::to('users/newaccount')->with('message','error')->withInput()->withErrors($validator);
}
unset($data['password_confirmation']);
$data['password'] = Hash::make(Input::get('password'));
User::create($data);
return Redirect::to('users/signin')->with('message','thanks');
}
4) I created a form for register the user
{{ Form::open(array('route'=>array('users.createaccount'), 'method' => 'post')) }}
.....
{{ Form::label('password') }}
{{ Form::password('password') }}
....
{{ Form::submit('Create new account') }}
{{ Form::close() }}
Problem is when i check on the DB table the user is register and saved, and all the fields are filled except for the password (and the token that remains null)..
But if i do a dd($data) before calling User::create($data) this is what i can see:
array(6) { ["_token"]=> string(40) "5bSkWYHLfeBh8E2agiB15J2cQSzs6orI7m5ruFhx" ["firstname"]=> string(4) "mark" ["lastname"]=> string(4) "mark" ["email"]=> string(13) "mark#mark.com" ["password"]=> string(60) "$2y$10$J3eM3nBZ0l8eNa1BxpoDc.BzeQUKzTc7dwwbu7g7GdQLj4gJgjWxe" ["telephone"]=> string(8) "12345678" }
Anyone can tell me why only the password and the token fields are not saved with the Eloquent method in the database, while they are saved using the seeder?
thk
All fields you want to pass to create need to be defined inside the $fillable array. Also password
protected $fillable = array('firstname', 'lastname', 'email', 'password', 'telephone', 'admin');
^^
_token definitely doesn't need to be in there. It's just a token Laravel adds for CSRF protection
Related
I want to show user name that user has booked to slot on calender and i have already made relation how can i show username please help me thanks.
Booking Model
public function users(){
return $this->hasOne('App\Models\User','id','user_id');
}
Controller
public function getBookingSlot(Request $request){
$userBookings = Booking::with('users')->where('room_id',$request->room_id)->where('booking_holding_status',1)->get();
foreach($userBookings as $booking){
$events [] = [
'id' => $booking->id,
'calendarId' => $booking->id,
'title' => 'user name',
'category' => 'time',
'dueDateClass' => '',
'bgColor' => "#e6515f",
'color' => "#ffffff",
'isPending' => 'false',
'isFocused' =>'false',
'start' => $booking->start_datetime,
'end' => $booking->end_datetime,
];
}
return \Response::json([
'events' => $events ?? null
]);
}
$booking->users[0]->username;
booking object contains booking details in it along with the object of users which it selects from the user table... I am not sure about hasOne() relationship. I have used it with belongsToMany().
so you get the user object from the booking object than for the first user [0] get its username.
If this does not work then the booking object may have only 1 user object, not an array of objects.. then access it like this...
$booking->users->username;
I'm not sure if this is a new bug or what's going on, but I'm having trouble getting the Yii2 validator to recognize a file is there after it's been uploaded. The client side validation works fine.
Rules for the model:
return [
[['store_id', 'name', 'csv'], 'required'],
[['store_id', 'created_at', 'updated_at'], 'integer'],
[['name'], 'string', 'max' => 255],
[['csv'], 'file', 'skipOnEmpty' => false, 'maxSize'=>1024 * 1024 * 2],
];
Controller Action:
public function actionUploadFromCsv()
{
$store = Yii::$app->user->identity->store;
$store_csv = new StoreCsv;
$store_csv->store_id = $store->id;
$store_csv->name = $store_csv->getDefaultName();
if (Yii::$app->request->isPost) {
$store_csv->csv = UploadedFile::getInstance($store_csv, 'csv');
if ($store_csv->upload()) {
return $this->redirect(['view-csv', 'id'=>$store_csv->id]);
}
return json_encode($store_csv->getErrors());
}
return $this->render('csv_upload', [
'store'=>$store,
'csv'=>$store_csv
]);
}
Model Upload() Function:
public function upload()
{
if ($this->validate()) {
$file_name = uniqid(rand(), false) . '.' . $this->csv->extension;
$this->csv->saveAs(Yii::getAlias('#backend') . '/web/store/' . $this->store_id . '/csv/' . $file_name);
$this->csv = $file_name;
return $this->save();
}
return false;
}
Form Markup:
<?php $form = ActiveForm::begin(['options' => ['enctype' => 'multipart/form-data']]); ?>
<?= $form->field($csv, 'csv')->fileInput() ?>
<div class="form-group">
<?= Html::submitButton('Submit', ['class' => 'btn btn-primary']) ?>
</div>
<?php ActiveForm::end(); ?>
Currently when I perform the upload I get this error after validation fails:
{"csv":["Please upload a file."]}
If I change 'skipOnEmpty' to true, however, it works fine. It saves the model and moves and renames the temporary file. I would like to get validation working though, so I can restrict to certain extensions. What's the deal? I've spent hours trouble shooting this.
I figured out what my problem here is. After saving the file I try to rename it, however, the way I do it here takes away the association of this attribute as a file.
Wrong:
$this->csv = $file_name;
Right:
$this->csv->name = $file_name;
In addition, I originally asked this question because I was having trouble getting the validator to work, restricting extensions. It would not recognize "xls" or "csv" after the client side validation when I did $model->validate(). I just found that this is a known issue due to the MIME TYPE validator:
https://github.com/yiisoft/yii2/issues/6148
The solution to the extension issue is to set checkExtensionByMimeType to false:
[['csv'], 'file', 'skipOnEmpty' => false, 'extensions'=>['xls', 'csv'], 'checkExtensionByMimeType'=>false, 'maxSize'=>1024 * 1024 * 2],
What is your FORM markup? View the page source within the browser. Files are ignored unless the form markup has has multipart/form-data.
<form action="upload.php" method="post" enctype="multipart/form-data">
I extracted YiiPassword extension into protected/components/YiiPassword
main.php:
.
.
.
'import'=>array(
'application.models.*',
'application.components.*',
'application.components.YiiPassword.*',
'application.helpers.*',
),
.
.
.
User.php: (model)
.
.
.
public function behaviors()
{
return array(
"APasswordBehavior" => array(
"class" => "APasswordBehavior",
"defaultStrategyName" => "bcrypt",
"strategies" => array(
"bcrypt" => array(
"class" => "ABcryptPasswordStrategy",
"workFactor" => 14
),
"legacy" => array(
"class" => "ALegacyMd5PasswordStrategy",
)
),
)
);
}
.
.
.
Ans also added thees three fields into tbl_user:
salt - holds the per user salt used for hashing passwords
password - holds the hashed password (Exist already)
passwordStrategy - holds the name of the current password strategy for this user
requiresNewPassword - a boolean field that determines whether the user should change their password or not
and Now i only want use bcrypt, how to encode the user password and verify it at user-login?
You simply have to retrieve the user and call the verifyPassword method! The description of this method:
Compares the given password to the stored password for this model
So you could do something like:
$user = User::model()->findByPK(1);
if($user->verifyPassword("password")){
//Password verified
}
SOLVED
The following test successfully done, ABcryptPasswordStrategyTest.php :
<?php
Yii::import("application.components.passwordStrategy.*");
Yii::import("application.models.*");
/**
* Tests for the {#link ABcryptPasswordStrategy} class.
* #author Charles Pick
* #package packages.passwordStrategy
*/
class ABcryptPasswordStrategyTest extends CTestCase
{
public function testEncode()
{
$user=User::model()->findByAttributes(array('username'=>'user'));
$strategy = new ABcryptPasswordStrategy();
$strategy->getSalt(true);
$user->password = 'pass';
$user->save();
$this->assertTrue($user->verifyPassword("pass"));
}
}
more info
I'm trying to integrate a cart-synchronisation-solution for my rest-clients.
The goal should be that I can have the same cart wherever I access my store from.
So I'll have to first of all deliver the existing items out to the client using the authenticated api-user.
But I get stuck at the very beginning:
protected function _retrieveCollection()
{
$cart = Mage::getSingleton('checkout/cart')->getQuote();
$cart->setCustomerId($this->getApiUser()->getUserId());
$cart->setStoreId(4);
$cart->load();
return $cart->getAllItems();
}
returns an empty array even though I have products in my cart.
Anyone any hints? Have that feeling I'm totally on the wrong side...
Found a solution. Getting the quote by Customer which is the other way around worked pretty well:
Mage::app()->setCurrentStore(4);
$cart = Mage::getModel('sales/quote')->loadByCustomer($this->getApiUser()->getUserId());
$items = array();
foreach ($cart->getAllVisibleItems() as $key => $item) {
$items[] = array(
'name' => $item->getName(),
'entity_id' => $item->getProductId(),
'description' => $item->getDescription(),
'final_price_with_tax' => $item->getBasePriceInclTax(),
'qty' => $item->getQty()
);
}
I followed this tutorial to create multilingual site.
http://nuts-and-bolts-of-cakephp.com/2008/11/28/cakephp-url-based-language-switching-for-i18n-and-l10n-internationalization-and-localization/
However although I can get to the login page at example.com/en/users/login when i try to login, the login wouldn't go through. I get thrown at example.com/users/login without the /en/ and I don't know if this matters, but the password does not contain 4 letters/stars/dots like the password i tried, but about 40.
Also, I noticed that the example.com/en/users/logout function does work to log me out, but takes me to example.com/users/login instead of example.com/en/users/logout
I managed to get to the fact that the function that breaks it is the:
class AppHelper extends Helper {
function url($url = null, $full = false) {
if(!isset($url['language']) && isset($this->params['language'])) {
$url['language'] = $this->params['language'];
}
return parent::url($url, $full);
}
}
However, without it, no urls work at all in terms of the /en/ addition in the URL.
Can anyone help? I will provide any code needed.
This was quite a journey to make it work. Some of the things I still don't get, but at least I know they work. If you make an improvement on this let me know, I'd like to be aware of it.
This tutorial in the question only gets you half way.
In addition, here are a few things that need to be moded to get this working:
Routes.php:
/**
* LANGUAGES
*/
Router::connect( '/:language/:plugin/:controller/:action/*', array(), array('language' => '[a-z]{3}')); // PLUGIN FIX
Router::connect('/:language/:controller/:action/*', array('plugin' => null), array('language' => '[a-z]{3}'));
Router::connect('/:language', array('controller'=>'static', 'plugin'=>null), array('language' => '[a-z]{3}'));
App_controller.php:
function beforeFilter(){
$this->_setLanguage();
$this->Auth->logoutRedirect = array( 'controller' => 'static', 'action' => 'index', 'language'=>$this->Session->read('Config.language'));
$this->Auth->loginRedirect = array( 'controller' => 'static', 'action' => 'dashboard', 'language'=>$this->Session->read('Config.language'));
$this->Auth->loginAction = array( 'controller'=>'users', 'action'=>'login', 'language'=>$this->Session->read('Config.language'));
}
function _setLanguage() {
if ($this->Cookie->read('lang') && !$this->Session->check('Config.language')) {
// If ... don't really get this.
$this->Session->write('Config.language', $this->Cookie->read('lang'));
}
else if (isset($this->params['language']) && ($this->params['language']
!= $this->Session->read('Config.language'))) {
// Had a language set, but different from the one in the URL, set to URL
$this->Session->write('Config.language', $this->params['language']);
$this->Cookie->write('lang',$this->params['language'], false, '360 days');
}else{
// First time comer
$this->Session->write('Config.language', Configure::read('Config.language' ));
$this->Cookie->write('lang', Configure::read('Config.language' ), false, '360 days');
}
}
function redirect( $url, $status = NULL, $exit = true ) {
if (!isset($url['language']) && $this->Session->check('Config.language')) {
$url['language'] = $this->Session->read('Config.language');
}
parent::redirect($url,$status,$exit);
}
app_helper.php:
function url($url = null, $full = false) {
if(!isset($url['language']) && isset($this->params['language'])) {
$url['language'] = $this->params['language'];
}else if (!isset($url['language']) && !isset($this->params['language'])){
if($_COOKIE['lang']){
$url['language'] = $_COOKIE['lang'];
}else{
$url['language'] = Configure::read('Config.language');
}
}
return parent::url($url, $full);
}
And this should be it. Hope that helps all of you lost souls with multilingual cakephp stuff
pp
I used the same resource to make cakephp multilingual, but today got stuck with that problem that by default login action loses language. When I found this post, the only thing that I need in addition to the original manual is the following code in controller_app.php beforeFilter:
$this->Auth->logoutRedirect = array( 'language'=>$this->Session->read('Config.language'));
$this->Auth->loginRedirect = array( 'language'=>$this->Session->read('Config.language'));
$this->Auth->loginAction = array( 'controller'=>'users', 'action'=>'login', 'language'=>$this->Session->read('Config.language'));
I saw your other question about multilingual setting. I was going to say that just make the default language to be 'en'. But I'm uncertain how that would affect SEO, so I didn't say anything. But yeah, the way you are doing right now might interfere with many Cake automagic, like the Auth problem you are having.
Here what I'd suggest: In app_controller:
function beforeFilter(){
$this->Auth->loginAction = array(
'controller' => 'users',
'action' => 'login' // insert the language option that you use here
);
$this->Auth->logoutRedirect = array(
'controller' => 'users',
'action' => 'index'
);// you can set where to redirect after logout here
}
I would advise not to redirect to /users/logout, unless you want to do something there. And you would need to change the logout function in users_controller too.
One thing that helped me, (not perfect but it's a start)
is i created exceptions for the 'loginPage' (the login action for the auto component)
so the language of the url doesn't get populated when logging in.
this helped me as i wasn't able to login until i did this
i added this to the app_helper.php
> //exceptions to allow to login
> if (isset($url['action'])) {
> if ($url['action'] == 'loginPage') $url['language'] = false;
> }