typo3 extbase validate for multiple records - validation

I have written one extbase plugin, that creates the FE users from front end form.
The create action is something like this
/**
* action create
*
* #param \TYPO3\Usermanagement\Domain\Model\Users $newUsers
* #return void
*/
public function createAction(\TYPO3\Usermanagement\Domain\Model\Users $newUsers) {
$this->usersRepository->add($newUsers);
}
Here I want to validate for same username or email already exists or not.
How can I do this ?
Any suggestions ?
Thank you.

You don't need to bind a $newUser as an action's param, instead you can just read some fields using $this->request->hasArgument('something') and $this->request->getArgument('something') to validate properties yourself, and create new user object manually like.
public function createAction() {
$newUsers = new \TYPO3\Usermanagement\Domain\Model\Users();
// do something with $newUsers object...
$this->usersRepository->add($newUsers);
}
It will not throw an exception in case when there's no valid user object in the request, so it will allow you to handle form's error as you want/need.
It will also allow you to use some preprocessing before saving ie hashing/salting passwords.

Related

Customise Laravel Nova destructive action modal

I am defining a new destructive action in Laravel Nova using the documentation, and I am wondering if it is possible to customise the modal message, which says "Are you sure you want to run this action".
So far, all I have been able to do is replace this message with a field by doing the following:
public function fields()
{
return [
Text::make('This is a test field')
];
}
But this is bringing up a text field for the user to fill out. How can I just have text here, without having a user input field please?
According to Laravel Nova release notes, from version 2.5.0 onwards you can customise action modal's confirmation.
Override the $confirmText attribute in your Action class.
For example:
class YourAction extends Action
{
/**
* The text to be used for the action's confirmation text.
*
* #var string
*/
public $confirmText = 'Your confirmation text?';
}

Laravel form request duplicate query

I want to fetch a record and perform validation with that.
So I see two option using validation in the controller and using form request
I prefer using form request
So according to a document I can fetch a record in Form request and use it.
But the problem is I need that record in the controller too, So if I going this way I load one record twice.
I'm solving my problem with property in the form request
for example
/**
* Get the validation rules that apply to the request.
*
* #return array
*/
public function rules()
{
$this->post = Post::find($this->input('id'));
return [
... // my rules base on $this->post
];
}
and then in the controller, I can access the post value
public function store(PostPublishCreate $request)
{
$request->post;
....
1.But I'm confused in this way, Is there a problem in my way? Is there a better solution to do it in laravel?
2.In this example I don't use dependency injection, So how I can approach this with dependency injection?
public function store(PostPublishCreate $request,Post $post)
{
// how to prevent to my record provided twice
// PostPublishCreate load post because of the rules
// Post loaded again with DI
....
I try to use the Rule class for my custom validation, But I'm not sure how to pass the record to Rule without reloading it
Form Request is not loading the record. It just validates the parameters present in the $request object. In the second example, $post is automatically retrieved by DI where then you can manipulate your record as you wish.

Add extra question to Laravel forgotten password form and custom its error messages

I'd like to customize the forgotten password form in Laravel.
When asking to reset the password, the user will have to answer a simple question (the name your first pet, the name of your childhood best friend, etc) besides inserting his/her email. This is to avoid other people asking password reset if they know the account's email, but are not the owner of the account.
I also would like to custom the errors messages to, actually, not show errors. For example, if an invalid email is inserted, it would not show the error message "We can't find a user with that e-mail address." I don't like it because someone may guess the email of a user by trying different emails until she/he stops getting the error message. Instead, I would like to show the message "If the information provided is correct, you will receive an email with the link to reset your password."
How to add these functionalities to Laravel auth?
I am looking for a solution that I don't have to create an entire login system from scratch (I think that if I try to design everything from scratch I'd probably miss something and create security vulnerabilities). I'd like to keep the Laravel auth system and just add these two features.
Feel free to suggest other ways to achieve the desired result and to make my question clearer. I'll appreciate that.
The good news is you don't need to rewrite everything.
The bad news is, you need to understand traits and how to extend/override them, which can be a little confusing.
The default controller that Laravel creates ForgotPasswordController doesn't do much. Everything it does is in the trait. The trait SendsPasswordResetEmails contains a few methods, most importantly for the validation in validateEmail method.
You can override this validateEmail method with one that checks for an answered question. You override traits by altering the 'use' statement.
For example change;
use SendsPasswordResetEmails
to:
use SendsPasswordResetEmails {
validateEmail as originValidateEmail
}
This will tell the code to re-name the original method validateEmail to originValidateEmail allowing you to create a new validateEmail in your own ForgotPasswordController.
You can then, inside ForgotPasswordController add a replacement which will be called by the default reset password code:
protected function validateEmail(Request $request)
{
// add in your own validation rules, etc.
$request->validate(['email' => 'required|email', 'questionfield' => 'required']);
}
To alter the error message, you can simply edit the language file found in resources/lang/en/passwords.php
Hope that helps.
Thanks to the user #Darryl E. Clarke, I managed to solve the problem. Here is what I did:
Add this line at the top of the file ForgotPasswordController, after namespace:
use App\User;
Add these 3 methods in the same file:
/**
* Send a reset link to the given user.
*
* #param \Illuminate\Http\Request $request
* #return \Illuminate\Http\RedirectResponse|\Illuminate\Http\JsonResponse
*/
public function sendResetLinkEmail(Request $request)
{
$this->validateRequest($request);
// We will send the password reset link to this user. Regardless if that
// worked, we will send the same response. We won't display error messages
// That is because we do not want people guessing the users' email. If we
// send an error message telling that the email is wrong, then a malicious
// person may guess a user' email by trying until he/she stops getting that
// error message.
$user = User::whereEmail($request->email)->first();
if ($user == null) {
return $this->sendResponse();
}
if ($user->secrete_question != $request->secrete_question) {
return $this->sendResponse();
}
$this->broker()->sendResetLink(
$this->credentials($request)
);
return $this->sendResponse();
}
/**
* Validate the given request.
*
* #param \Illuminate\Http\Request $request
* #return void
*/
protected function validateRequest(Request $request)
{
$request->validate(['email' => 'required|email', 'secrete_question' => 'required|string']);
}
/**
* Get the response for a password reset link.
*
* #return \Illuminate\Http\RedirectResponse|\Illuminate\Http\JsonResponse
*/
protected function sendResponse()
{
$response = 'If the information provided is correct, you will receive an email with a link to reset your password.';
return back()->with('status', $response);
}
Customize it the way you want.
Hope that it will helps others!!

Typo3 extbase validating custom or manual objects

I have created extbase extension, there for some reason I need to create object manually in create action.
My create action looks like this,
/**
* action create
*
* #return void
*/
public function createAction() {
$newObj = new \TYPO3\Myext\Domain\Model\Modelname();
$newObj->setMyval('value');
$this->myrepository->add($newObj);
}
Here the problem is its not validating for require field, captcha etc even if I mention #validate NotEmpty in model.
So how to make the validation of manually created object ?
It should throw error to form like out-of-the-box features.
Thank you.
Out of the box validation is only triggered on constructing model objects from GET/POST parameters according to your controller actions signature.
It should look something like this:
/**
* action create
* #param \TYPO3\Myext\Domain\Model\Modelname $newObject
* #return void
*/
public function createAction(\TYPO3\Myext\Domain\Model\Modelname $newObject) {
$this->myrepository->add($newObj);
}
Take a look at the extension_builder, create a model and let the new/create action be generated for you. That will give you a good example on the create action as well as on the new action where the form is being rendered.

Drupal: Getting user name on user account page without breaking performance

I have multiple blocks shown on the user profile page, user/uid
On each of them, I need to print the user name.
I've been doing a $user = user_load(arg(1)); print $user->name; on each block. Since there is no caching, as you can image the performance is HORRIBLE.
Is there either a way to get the user name more efficiently or to cache user_load.
Thanks.
Just add an intermediate function to provide the static caching yourself:
/**
* Proxy for user_load(), providing static caching
* NOTE: Only works for the common use of user_load($uid) - will NOT load by name or email
*
* #param int $uid - The uid of the user to load
* #param bool $reset - Wether to reset the static cache for the given uid, defaults to FALSE
* #return stdClass - A fully-loaded $user object upon successful user load or FALSE if user cannot be loaded.
*/
function yourModule_user_load_cached($uid, $reset = FALSE) {
static $users = array();
// Do we need to (re)load the user?
if (!isset($users[$uid]) || $reset) {
$users[$uid] = user_load($uid);
}
return $users[$uid];
}
Use menu_get_object() which is the proper way to retrieve an object (user, node, etc.) loaded from the URL of a properly declared page. It will return the user object that has already been loaded using the uid found at arg(1) for a menu item which use %user in its path (ie. $items['user/%user'], $items['user/%user/view'], etc. in user_menu().
$account = menu_get_object('user');
The user is a global.
function myfunction() {
global $user;
}

Resources