or condition in findByUsername() in yii2 with mongoDB - mongodb

How can i use or condition in yii2 advanced template with mongoDB:
what i want:
$sql = "SELECT * FROM admin WHERE (username = '$username' OR email = '$username');
How can i put this condition in following function:
public static function findByUsername($username)
{
return static::findOne(['username' => $username]);
}

I have solved like this:
public static function findByUsername($username)
{
$con = array('$or' => array(array('username' => $username),array('email' => $username)));
return static::findOne($con);
}

Related

Codeigniter Call to a member function where() on bool

I tried to set seen to any contact data in database, but when i try that:
public function showMessage($id){
$this->load->model('Message_Model');
$messageData = $this->Message_Model->selectMessage($id);
if($messageData[0]->messageIsSeen == 0){
$this->Message_Model->setSeenToMessage($id);
}
$data = array('messageData' => $messageData[0]);
$this->load->view('Back/MessageDetail', $data);
}
Model:
function setSeenToMessage($id){
$this->db->update('messages', array('messageIsSeen' => 1))->where('messageId', $id);
return 1;
}
It throws that error
i solved it like this change
function setSeenToMessage($id){
$this->db
->where('messageId', $id);
->update('messages', array('messageIsSeen' => 1))
return 1;
}
nevertheless, still i don't know how did it works

redirectTo() after registration is not working in laravel 7

I have a problem in my custom registration controller; the redirecTo() is not working. After registration which is completely successful (in terms of database) I get a blank page and the URL never changes.
Here is the code of my Controller:
PS : I also used the method redirectPath() which also did not work.
<?php
namespace App\Http\Controllers\Auth\Login;
use Illuminate\Support\Facades\Auth;
use App\Http\Controllers\Auth\RegisterController as DefaultRegisterController;
use Illuminate\Http\Request;
use Illuminate\Auth\Events\Registered;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Validator;
use App\{Models\Medcine, Specialite ,SpecialiteMedcine};
use App\Http\Controllers\Controller;
class RegisterMedcineController extends DefaultRegisterController
protected $redirectTo = '/medcine/home';//This 1 is not working
public function redirectTo()//nd also this method is not working
{
dd(['Heelllooooooooo']);//shows nothing -_- that means that the system never caull this cursed method
return '/medcine/home';
}
public function showRegisterationForm()
{
return view('auth.register.medcine' , [
'Specialite' => Specialite::all()
]);
}
public function register(Request $request)
{
// dd($request);
$this->validate($request, [
'inp' => 'bail|required|between:6,20',
'password' => 'bail|required|between:8,255',
'nom' => 'bail|required|max:255',
'prenom' => 'bail|required|max:255',
'dateNaissance' => 'bail|required|date',
'tel' => 'bail|required|digits_between:10,20',
]);
$medcine = new Medcine();
// $specialite = new Specialite();
$specialiteMedcine = new SpecialiteMedcine();
$medcine->inp = $request->input('inp');
$value = $request->input('password');
bcrypt($value);
$medcine->password = bcrypt($value);
$medcine->email = $request->input('email');
$medcine->nom = $request->input('nom');
$medcine->prenom = $request->input('prenom');
$medcine->dateNaissance = $request->input('dateNaissance');
$medcine->lieuNaissance = $request->input('lieuNaissance');
$medcine->tel = $request->input('tel');
$medcine->genre = $request->input('genre');
$medcine->adress = $request->input('adress');
$specialiteMedcine->specialite_id = $request->input('Specialite');
$medcine->save();
$specialiteMedcine->medcine_id = $medcine->id;
$specialiteMedcine->save();
}
}
You can simply write your redirect code at the end of the Register method. Means:
public function register(Request $request)
{
$this->validate($request, [
'inp' => 'bail|required|between:6,20',
'password' => 'bail|required|between:8,255',
'nom' => 'bail|required|max:255',
'prenom' => 'bail|required|max:255',
'dateNaissance' => 'bail|required|date',
'tel' => 'bail|required|digits_between:10,20',
]);
$medcine = new Medcine();
// $specialite = new Specialite();
$specialiteMedcine = new SpecialiteMedcine();
$medcine->inp = $request->input('inp');
$value = $request->input('password');
bcrypt($value);
$medcine->password = bcrypt($value);
$medcine->email = $request->input('email');
$medcine->nom = $request->input('nom');
$medcine->prenom = $request->input('prenom');
$medcine->dateNaissance = $request->input('dateNaissance');
$medcine->lieuNaissance = $request->input('lieuNaissance');
$medcine->tel = $request->input('tel');
$medcine->genre = $request->input('genre');
$medcine->adress = $request->input('adress');
$specialiteMedcine->specialite_id = $request->input('Specialite');
$medcine->save();
$specialiteMedcine->medcine_id = $medcine->id;
$specialiteMedcine->save();
return redirect(route('your-route-name'));
}
In last line:
return redirect(route('your-route-name'));

Zend TableGateway can't execute 2 consecutive query

It's been weeks since I start learning Slim using Zend TableGateway from slim-api-skeleton.
It seems I can't run 2 consecutive query using TableGateway. It's always produce (not just UPDATE):
"Statement couldn't be produced with sql: UPDATE `users` SET `last_access` = NOW() WHERE `id` = ?"
Here's the code inside ZendUserRepository class:
public function __construct(array $config) {
$adapter = new Adapter($config);
$this->table = new TableGateway("users", $adapter);
}
...
public function footprint(int $id): void {
$data = ['last_access' => new Predicate\Expression('NOW()')];
$where = ['id' => $id];
$this->table->update($data, $where);
}
public function authenticate(string $username, string $password): bool {
$where = [
'username' => $username,
new Predicate\IsNotNull('roles')
];
$rowset = $this->table->select($where);
if (null === $row = $rowset->current()) {
return false;
}
$data = (array) $row;
if(password_verify($password, $data['password'])) {
$this->footprint($data['id']);
return true;
}
return false;
}
This frustrate me for days. Since the update function also use 2 consecutive query.
public function update(User $user): void {
$data = $this->hydrator->extract($user);
if (!$this->contains($user)) {
throw new UserNotFoundException;
}
$where = ["id" => $user->getId()];
$this->table->update($data, $where);
}
public function contains(User $user): bool {
try {
$this->get($user->getId());
} catch (UserNotFoundException $exception) {
return false;
}
return true;
}
Thank you.
Using PHPUnit test, I got the following result:
Zend\Db\Adapter\Exception\InvalidQueryException: Statement couldn't be produced with sql: UPDATE `users` SET `last_access` = NOW() WHERE `id` = ?
/vagrant/vendor/zendframework/zend-db/src/Adapter/Driver/Mysqli/Statement.php:208
/vagrant/vendor/zendframework/zend-db/src/Adapter/Driver/Mysqli/Statement.php:229
/vagrant/vendor/zendframework/zend-db/src/TableGateway/AbstractTableGateway.php:391
/vagrant/vendor/zendframework/zend-db/src/TableGateway/AbstractTableGateway.php:349
/vagrant/src/Infrastructure/ZendUserRepository.php:90
/vagrant/src/Infrastructure/ZendUserRepository.php:104
/vagrant/src/Application/User/UserAuthenticationHandler.php:19
/vagrant/tests/Application/User/UserAuthenticationHandlerTest.php:41
Caused by
Zend\Db\Adapter\Exception\ErrorException: Commands out of sync; you can't run this command now
And from google lead to https://stackoverflow.com/a/614741/3164944
You can't have two simultaneous queries because mysqli uses unbuffered queries by
default (for prepared statements; it's the opposite for vanilla
mysql_query). You can either fetch the first one into an array and
loop through that, or tell mysqli to buffer the queries (using $stmt->store_result()).
Solved with additional configuration:
[
"driver" => "Mysqli",
"database" => getenv("DB_NAME"),
"username" => getenv("DB_USER"),
"password" => getenv("DB_PASSWORD"),
"hostname" => getenv("DB_HOST"),
"charset" => "utf8",
'options' => ['buffer_results' => true],
]
From https://stackoverflow.com/a/43863554/3164944

Laravel-MongoDB, how order result by relevant

I use jenssegers/laravel-mongodb. I make scope
public function scopeWhereFullText($query, $search)
{
return $query->whereRaw(['$text' => ['$search' => $search]],['score'=>['$meta'=>'textScore']]);
}
How I can order By score field like in MongoDB js example:
db.products.find({$text:{$search:"SomeText"}},{score:{$meta:'textScore'}}).sort({score:{$meta:'textScore'}})
What is the solution without crutch:
public function scopeWhereFullText($query, $search)
{
$query->getQuery()->projections = ['score'=>['$meta'=>'textScore']];
return $query->whereRaw(['$text' => ['$search' => $search]]);
}
and in result
$products = Product::whereFullText($request->get('q',''))
->orderBy('score',['$meta'=>'textScore'])->get();
$max = $products->max('score');
$min = $products->min('score');
$products = $products->filter(function($item) use($max,$min){
return $item->score > ($max+$min)/2;
});
Use
$results = DB::connection()->collection('_User')->whereRaw(['$text' => ['$search' => 'SEARCH QUERY']])->project(['score'=>['$meta'=>'textScore']])->orderBy('score', ['$meta' => "textScore"])->limit(10)->get();

Yii form model validation- either one is required

I have two fields on the form ( forgotpassword form ) username and email Id . User should enter one of them . I mean to retrieve the password user can enter user name or the email id . Could some one point me the validation rule for this ?
Is there any inbuilt rule I can use ?
( Sorry if it is already discussed or if I missed)
Thanks for your help
Regards
Kiran
I was trying to solve same problem today. What I've got is the code below.
public function rules()
{
return array(
// array('username, email', 'required'), // Remove these fields from required!!
array('email', 'email'),
array('username, email', 'my_equired'), // do it below any validation of username and email field
);
}
public function my_required($attribute_name, $params)
{
if (empty($this->username)
&& empty($this->email)
) {
$this->addError($attribute_name, Yii::t('user', 'At least 1 of the field must be filled up properly'));
return false;
}
return true;
}
General idea is to move 'required' validation to custom my_required() method which can check if any of field is filled up.
I see this post is from 2011 however I couldn't find any other solution for it. I Hope it will work for you or other in the future.
Enjoy.
Something like this is a bit more generic and can be reused.
public function rules() {
return array(
array('username','either','other'=>'email'),
);
}
public function either($attribute_name, $params)
{
$field1 = $this->getAttributeLabel($attribute_name);
$field2 = $this->getAttributeLabel($params['other']);
if (empty($this->$attribute_name) && empty($this->$params['other'])) {
$this->addError($attribute_name, Yii::t('user', "either {$field1} or {$field2} is required."));
return false;
}
return true;
}
Yii2
namespace common\components;
use yii\validators\Validator;
class EitherValidator extends Validator
{
/**
* #inheritdoc
*/
public function validateAttributes($model, $attributes = null)
{
$labels = [];
$values = [];
$attributes = $this->attributes;
foreach($attributes as $attribute) {
$labels[] = $model->getAttributeLabel($attribute);
if(!empty($model->$attribute)) {
$values[] = $model->$attribute;
}
}
if (empty($values)) {
$labels = '«' . implode('» or «', $labels) . '»';
foreach($attributes as $attribute) {
$this->addError($model, $attribute, "Fill {$labels}.");
}
return false;
}
return true;
}
}
in model:
public function rules()
{
return [
[['attribute1', 'attribute2', 'attribute3', ...], EitherValidator::className()],
];
}
I don't think there is a predefined rule that would work in that case, but it would be easy enough to define your own where for username and password fields the rule was "if empty($username . $password) { return error }" - you might want to check for a min length or other field-level requirements as well.
This works for me:
['clientGroupId', 'required', 'when' => function($model) {
return empty($model->clientId);
}, 'message' => 'Client group or client selection is required'],
You can use private property inside model class for preventing displays errors two times (do not assign error to model's attribute, but only add to model without specifying it):
class CustomModel extends CFormModel
{
public $username;
public $email;
private $_addOtherOneOfTwoValidationError = true;
public function rules()
{
return array(
array('username, email', 'requiredOneOfTwo'),
);
}
public function requiredOneOfTwo($attribute, $params)
{
if(empty($this->username) && empty($this->email))
{
// if error is not already added to model, add it!
if($this->_addOtherOneOfTwoValidationError)
{
$this->addErrors(array('Please enter your username or emailId.'));
// after first error adding, make error addition impossible
$this->_addOtherOneOfTwoValidationError = false;
}
return false;
}
return true;
}
}
don't forget "skipOnEmpty" attr. It cost me some hours.
protected function customRules()
{
return [
[['name', 'surname', 'phone'], 'compositeRequired', 'skipOnEmpty' => false,],
];
}
public function compositeRequired($attribute_name, $params)
{
if (empty($this->name)
&& empty($this->surname)
&& empty($this->phone)
) {
$this->addError($attribute_name, Yii::t('error', 'At least 1 of the field must be filled up properly'));
return false;
}
return true;
}
Yii 1
It can be optimized of course but may help someone
class OneOfThemRequiredValidator extends \CValidator
{
public function validateAttribute($object, $attribute)
{
$all_empty = true;
foreach($this->attributes as $_attribute) {
if (!$this->isEmpty($object->{$_attribute})) {
$all_empty = false;
break;
}
}
if ($all_empty) {
$message = "Either of the following attributes are required: ";
$attributes_labels = array_map(function($a) use ($object) {
return $object->getAttributeLabel($a);
}, $this->attributes);
$this->addError($object, $_attribute, $message . implode(',',
$attributes_labels));
}
}
}
yii1
public function rules(): array
{
return [
[
'id', // attribute for error
'requiredOneOf', // validator func
'id', // to params array
'name', // to params array
],
];
}
public function requiredOneOf($attribute, $params): void
{
$arr = array_filter($params, function ($key) {
return isset($this->$key);
});
if (empty($arr)) {
$this->addError(
$attribute,
Yii::t('yii', 'Required one of: [{attributes}]', [
'{attributes}' => implode(', ', $params),
])
);
}
}