This question is a follow-up of this one How to properly insert time when user leaves( user_left and user_joined got the same value)
I get data when user logged in and store in in DB.
Broadcast::channel('chat', function ($user) {
$ip = Request::ip();
$time = now();
if (auth()->check() && !session()->has('name')) {
UserInfo::storeUser();
session()->put('name',$user->name);
return [
'user_id' => $user->id,
'ip' => $ip,
'name' => $user->name,
'joined' => $time,
];
}
});
I get time when user logged out and also store in DB.
public function logout() {
$info = auth()->user()->info;
$info->left = now();
$info->save();
auth()->logout();
session()->forget('name');
session()->put('left', now());
return redirect('/');
}
UserInfo model
public static function storeUser() {
UserInfo::create([
'user_id' => Auth::id(),
'ip' => Request::ip(),
'name' => Auth::user()->name,
'joined' => now(),
]);
}
This is what I've got.
The time when user left gets inserted not in the way I would like to. The first record with the name of the current user gets the time. I would like to see the LAST record of the current user receiving that data(when Syd 12 logged out Syd 10 received Syd's 12 'left' data. The same story goes with Kate.)
Related
update controller i'm trying to update a room reservation (time and date),but the condition of update (the if) does not work
update fonction
public function update(Request $request, $id)
{
$request->validate([
'date' => 'required',
'time' => 'required',
]);
$roomreservation = Roomreservation::find($id);
if ($roomreservation == null) {
return back()->with('erreur', 'The chosen room does not exist');
}
if ($roomreservation->date == $request->date && $roomreservation->time == $request->time) {
return back()->with('erreur', 'The chosen room is already reserved');
}
else {
$roomreservation->update([
"date" => $request->date,
"time" => $request->time,
]);
return back()->with('message_sent', 'room reservation edited successfully!');
}
}
I would like to implement a login at TYPO3 v8.7. Here it is so that the data comes from a foreign provider who should log in automatically with his login data of his system at TYPO3. I developed something for that.
What is wrong?
// Authentication Service
\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addService(
$_EXTKEY,
'auth',
'TEST\\Tests\\Service\\AuthenticationService',
array(
'title' => 'User authentication service',
'description' => 'Authentication with username',
'subtype' => 'getUserFE, authUserFE',
'available' => true,
'priority' => 90,
'quality' => 90,
'os' => '',
'exec' => '',
'className' => 'TEST\\Tests\\Service\\AuthenticationService',
)
);
This is in ext_localconf.php
class AuthenticationService extends \TYPO3\CMS\Sv\AuthenticationService
{
function init() {
$available = parent::init();
return $available;
}
public function getUser(){
$remoteUser = $this->getRemoteUser();
$user = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows(
'*',
'fe_users',
'username = '.$GLOBALS['TYPO3_DB']->fullQuoteStr($remoteUser, 'fe_users') . ' AND deleted = 0'
);
return $user;
}
public function authUser($user)
{
$userData = $user[0];
foreach ($user[0] as $item => $key) {
if (is_numeric($key)) {
$result_array[$item] = (int) $key;
} else {
$result_array[$item] = $key;
}
}
$this->login = $loginData = array(
'uname' => $userData["username"],
'uident_text' => $userData['password'],
'status' => 'login'
);
$ok = $this->compareUident($result_array, $loginData);
if($ok == 1) {
return 200;
}
return 100;
}
/**
* Returns the remote user.
*
* #return string
*/
protected function getRemoteUser()
{
[...]
return $user;
}
}
Is that all right, what am I doing?
In the function remoteUser I get the username of the third party provider.
Whenever I enter the GET parameter, the AuthService is triggered. However, I get the following error message:
"updateLoginTimestamp () must be of the type integer, null given"
Unfortunately I do not find the mistake I make. Hence my question if anyone sees where this is?
The getUser() Method should Return an Array of the User reccord
which is equal to a database row of fe_users
i am Guessing there is no existing fe_user for the username you get from getRemoteUser thus its the job of the Authentication service to create/update a record for this user in the table fe_users.
so in a more step by stepp manner your service should follow the following steps
in get user:
1. get Remote Username
2. check if Remote Username exists in fe_users table
3. if not create an new entry for Remote Username in fe_users
4. select the entry of Remote Username from fe_users and return the row.
I have two tables: record, user and a junction table record_user. I display the records, which are related to the logged user, using the Active Record.
In the model User I have the following functions:
public function getRecordUsers()
{
return $this->hasMany(RecordUser::className(), ['user_id' => 'id']);
}
public function getRecords()
{
return $this->hasMany(Record::className(), ['id' => 'record_id'])
->via('recordUsers');
}
See: http://www.yiiframework.com/doc-2.0/guide-db-active-record.html#junction-table
In the model RecordSearch I define the query for the Active Data Provider:
public function search($params)
{
// The Object with all records, to which has the user access (the id of the user is in the junction table record_user).
$loggedUserRecords = YiiUser::findOne(Yii::$app->user->identity->id)->records;
// From the object is extracted an array with ids.
$loggedUserRecordsIds = yii\helpers\ArrayHelper::getColumn($loggedUserRecords, 'id');
// The ids are used to filter the Record object.
$query = Record::find()->filterWhere(['id' => $loggedUserRecordsIds]);
$dataProvider = new ActiveDataProvider([
'query' => $query,
]);
...
The code works as expected. But I would like to know, if there is a more direct way to display the related records, without the extraction of ids from the object.
I guess RecordSearch has this relations
public function getRecordUsers()
{
return $this->hasMany(RecordUser::className(), ['record_id' => 'id']);
}
public function getUsers()
{
return $this->hasMany(User::className(), ['id' => 'user_id'])
->via('recordUsers');
}
Or
public function getUsers()
{
return $this->hasMany(User::className(), ['id' => 'user_id'])->viaTable('recordUsers', ['record_id' => 'id']);
}
then you should be able to check query something like:
$dataProvider = new ActiveDataProvider([
'query' => Record::find()->joinWith(['users'])->where(['user_id'=> Yii::$app->user->identity->id]),
]);
if i didn't make a mistake.
As suggested by BHoft the fastest and most simple way is probably the following.
Model Record:
public function getRecordUsers()
{
return $this->hasMany(RecordUser::className(), ['record_id' => 'id']);
}
Model RecordSearch:
$dataProvider = new ActiveDataProvider([
'query' => Record::find()->joinWith(['recordUsers'])->where(['user_id'=> Yii::$app->user->identity->id]),
]);
i tried using hybrid auth for a facebook login on my yii app, but couldn't get it to work. so decided to work on my own. i managed to get it to retrieve data and store it in my DB. but yii, still doesn't detect user as logged in. here is part of my code in my controllers/FacebookController.php
if (app()->request->isAjaxRequest) {
$user = app()->request->getParam('user');
Shared::debug($user);
// verify one last time that facebook knows this guy
if ($user['id'] === app()->facebook->getUser()) {
if (!empty($user['email']))
{
$model = User::model()->findByEmail($user['email']);
}
else if (!empty($user['username']) && empty($user['email'])) //incase we don't get an email, we use a facebook email
{
$email = $user['username'].'#facebook.com';
$model = User::model()->findByEmail($email);
}
else
{
$model = false;
}
if (!empty($model))
{
// facebook email matches one in the user database
$identity = new UserIdentity( $model->email , null );
$identity->_ssoAuth = true;
$identity->authenticate();
if ($identity->errorCode === UserIdentity::ERROR_NONE) {
print_r($identity);
app()->user->login($identity, null);
echo json_encode(array('error' => false, 'success' => url('/')));
app()->end();
}
else {
echo json_encode(array('error' => 'System Authentication Failed', 'code' => 'auth'));
app()->end();
}
}
in my code above, when i print_r($identity); the object below is echoed. and FYI, the email xxxxxx#facebook.com is stored in the DB but app()->user->isGuest() still returns true. what am i doing wrong here?
UserIdentity Object
(
[_ssoAuth] => 1
[_id:UserIdentity:private] => 19
[username] => xxxxxx#facebook.com
[password] =>
[errorCode] => 0
[errorMessage] =>
[_state:CBaseUserIdentity:private] => Array
(
)
[_e:CComponent:private] =>
[_m:CComponent:private] =>
)
http://yiiframework.com/doc/api/1.1/CWebUser#login-detail
Instead of passing a null into app()->user->login($identity, null) try passing in a duration like
$duration = 3600*24*30; //30 days
app()->user->login($identity, $duration);
I have had problems setting duration to 0. Not sure why either. But this worked for me before
I am trying to create a form which will have multiple fields , some fields will be filled by user and others will be dump into database as defined .
I really do not know how to work with this in term of syntax.
To be more Generic , For Example I have Post tble which have following fileds
id' => 'ID',
'post_head' => 'Heading',
'post_desc' => 'Description',
'post_tags' => 'Tags',
'created_time' => 'Created Time',
'created_date' => 'Created Date',
'post_image' => 'Upload Image',
'post_status' => 'Status',
'user_id' => 'User',
'category_id' => 'Category',
);
Now I want to take input from user in the following fields only :
Heading
Description
Tags
Upload Image
Now I want to know that How can I
pass current time and current date in database field without user
input. user id from session
In your model:
function beforeSave() {
if($this->getIsNewRecord()) {
$this->created_date = new CDbExpression('NOW()');
$this->created_time = new CDbExpression('NOW()');
}
$this->user_id = Yii::app()->user->id;
return parent::beforeSave();
}
1) If the you use database like MySQL you don't need created_date and created_time, just a datetime field (probably created_time is such), which will store both data!
public function behaviors()
{
return array(
'CTimestampBehavior' => array(
'class' => 'zii.behaviors.CTimestampBehavior',
'updateAttribute' => false,
'createAttribute' => 'created_time',
)
);
}
Then for two:
function beforeSave() {
if (!parent::beforeSave) {
return false;
}
$this->user_id = Yii::app()->user->id; // it should be this one, but it depends on how you implemented logging!
return true;
}
Instead of
'created_time' => 'Created Time',
'created_date' => 'Created Date',
You need just one field in your database:
create_time timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP
Many of php functions use timestamp, it's very easy to use it. You can read here.
So if you insert NULL create_time, mysql will insert default value DEFAULT CURRENT_TIMESTAMP - current time.
As said #Veseliq and #mashingan you need to add
function beforeSave() {
$this->user_id = Yii::app()->user->id;
return parent::beforeSave();
}
or try to add in your form view:
echo $form->hiddenField($model, 'user_id', array('value'=>Yii::app()->user->id));
If it doesn't work, show us var_dump(Yii::app()->user->id);