Suggestions on how to pragmatically allow one Laravel user to add another - laravel

I need on my Laravel set-up (which uses the standard Auth models/controller) to allow a logged-in user to create another user account on the site. As a shot in the dark, on my "add user" page, I did an include of the form from auth.register, and it showed up fine on the page (great!), but when I filled out the form and submitted it, it just reloaded the page, with no errors and the new user was not added to the database.
The things I'd need different than the standard auth.register are
1) There will be a column in the users table pairing the two users.
2) I want the verification email to be different than if they signed up on their own.
3) I was also thinking to not let the creating user choose a password, but have the new user reset their password via the initial email.
Is there any Laravel way of doing all this or will I have to write it myself?

1) There will be a column in the users table pairing the two users.
Take a look in your RegisterController and check out the use RegisterUsers trait included. Whatever you copy from this trait and move it to RegisterController, it gets overwritten by your logic rather than trait logic.
For the pairing, you can utilise create() method. A really pseudo way:
protected function create(array $data) {
$pair = // find a random user
return User::create([
'name' => $data['name'],
'email' => $data['email'],
'password' => Hash::make($data['password']),
'pair_id' => $pair->id
]);
}
2) I want the verification email to be different than if they signed up on their own.
For this, I am not sure where you trigger it already, but the email event lives in EventServiceProvider by default:
protected $listen = [
Registered::class => [
SendEmailVerificationNotification::class,
]
];
Change it your custom email and you should be good.
3) I was also thinking to not let the creating user choose a password, but have the new user reset their password via the initial email.
Again, in create() method, you can just assign a random password, and with your email, redirect them to the ResetPassword actions somehow. This needs some time to figure out for me now but see reset-password routes (with php artisan route:list), so what it accepts and in your custom email, place the button with necessary link.
Make sure you don't login the user right after registering in that case.
So, bottomline - the auth default logics live in their traits, and if you want to overwrite some, just copy/paste the method to your controller and tweak it as you wish.

Related

Laravel get redirected when opening register page when logged in

I want to create users when I'm logged in on a main account.
But everytime I open the "Sign up" page I will get redirect to http://domain/home.
I've already edited the controllers and removed /home there, but that still didn't solve the problem.
Remove $this->middleware('guest'); from your App\Http\Controllers\Auth\RegisterController's __construct() method in app\Http\Controllers\Auth\RegisterController.php
If you want to create users while you're signed in, then you will need to create them programmatically through a controller. Have a UserController with a createUser method and within that put something along the lines of:
public function createUser() {
$new_user = new User;
$new_user->email = 'foo#bar.com';
$new_user->name = 'john doe';
$new_user->save();
}
As Avik said above, since the sign up page is handled by your RegisterController, it is not going to allow anyone who is authenticated to that page.

Laravel show page only to signed in user

How do I show a page only to a specific person that's signed in. For example if I've localhost/public/article/4 that's only allowed for James, how do I make sure that Harry can't see this?
the correct way of do this is associate all users to a Role model. This way you could differenciate one user from others. But if you dont want this way you could use the ID of the user to validate this.
How validate this?
when you make a session in laravel you can access to the user data using
Auth::user()->id, Auth::user()->name, Auth::user()->last_login, etc...
in the controller's function the make the view you could do this (James ID's = 1)
if(Auth::user()->id == 1):
return View::make('path_to_view.show');
else:
return View::make('path_to_view.error');
endif;

Allow CRUD only to Auth::user that owns the ressource

I currently work on a project where the User creates Models, that only he/she is allowed to see, edit or delete.
The Create Part done by Eloquent Relationships, but for the other operations I would like to combine it with Route Model binding and not manually in the controller. I tried solving it with middlewares, but I couldn't access the Ressource.
Can somebody point me to the right Direction, any best Practices are welcome!
Personally I use route model binding, but only allow the model to bind if the user owns the record.
This means that no matter what - people can never access someone elses record. So for example, in my route I can do
$router->get('property/{property}, ['uses' => PropertyController#show]);
Then in my RouteServiceProvider:
$router->bind('property', function($value) {
$property = \App\Property::findOrFail($value);
if ((int)$property->user_id !== (int)auth()->id()) {
abort (404);
}
return $property;
});
So in the example above - we have a property route, and it will try and find the property record given. It will then check that the user owns the record, otherwise it throws a 404 (but you could just redirect or something - up to you).

CakePHP soft deleted data still showing up in model associations

I am using the SoftDeletableBehavior for my addresses model.
This sets it so when you delete an address it doesnt really delete it, instead sets a deleted column in the database to 1.
This also changes your query in the beforeFind function of the Address model to only pull entries where deleted != 1
This works when I am viewing addresses via the addresses controller like /addresses/show/43.
However my Users controller hasMany addresses. So when I am in the users controller and I call $this->find('first'); To get the user, I also get the associated addresses. I am expecting this to NOT give me the (softly) deleted addresses but it DOES. The beforeFilter on the Address Model is never called either.
What is the right way to handle this?
Update.
Apparently when I do this:
$data = $this->User->find('first',array('conditions' => array('User.id' => $id),'recursive' => 2));
I have a $data['User] array and a $data['Address] array (along with others).
But this does not use the beforeFind filter in the Address Model. So I get the wrong data.
But if I do this:
$data = $this->User->find('first',array('conditions' => array('User.id' => $id),'recursive' => 2));
$data['Address'] = $this->User->Address->find('all',array('conditions'=>array('user_id'=>$id)));
Then it does use the beforeFind filter on the Address model and returns the right data.
(Of course in a different format [Address][0][id] vs [Address][0][Address][id])
What I do not understand is if the associated data thats pulled does not use its own model to find its data, then whats the point? Isn't this one of the main purposes of MVC?
Maybe I just don't understand? Or I am missing something?
Can someone please enlighten me?
Can't you put this condition in your association?
<?php
class User extends AppModel {
var $hasMany = array(
'Address' => array(
'conditions' => array('NOT' => array('Address.deleted' => '1')),
)
);
}
?>
Personally, I would add a condition to the find query for users
$this->Users->find->('all',array('conditions'=>array('Address.deleted !='=>'1')));
(haven't tested the code for exact syntax, but this is the general idea)
When you use $this->User->find(...) and include Addresses, you will only see the User model's callbacks fire, because that is the model you are using to drive the find.
This is why you have to use extra conditions in your User model's associations to filter out the soft-deleted Addresses.
If the Address model's callbacks were fired during every find on the User model when recursion scope included Addresses, you'd have no control as to when to include the soft-deleted Addresses and would risk clashes in functionality and param manipulation by those callbacks. Not to mention the serious performance impact this could have.

Anyone know how to access the magento gift card sku in transactional email template?

I had a custom utility task that allowed users to choose an image to accompany the gift card notice that is sent to the recipient when a gift card is purchased at the magento run shop. In the template, there is an assortment of variables available so you can customize the email that is sent. However, in order to add the correct image, I need to have access to the gift card sku number since my method for handling this was to simply create many gift cards and apply separate images for each one, then use javascript to swap the sku numbers when the user clicks the images. Simple enough.
In the app/code/core/Enterprise/GiftCard/Model/Observer.php file, the variables are set:
$templateData = array(
'name' => $item->getProductOptionByCode('giftcard_recipient_name'),
'email' => $item->getProductOptionByCode('giftcard_recipient_email'),
'sender_name_with_email' => $sender,
'sender_name' => $senderName,
'gift_message' => $item->getProductOptionByCode('giftcard_message'),
'giftcards' => $codeList->toHtml(),
'balance' => $balance,
'is_multiple_codes' => 1 < $goodCodes,
'store' => $order->getStore(),
'store_name' => $order->getStore()->getName(), // #deprecated after 1.4.0.0-beta1
'is_redeemable' => $isRedeemable,
);
So I could add the product sku to this array and it would be available in the template system. Problem is, I don't know where to trace this back to even know how to get the Sku. I assume it is somehow available in the $item var, but magento has no documentation on this particular case and I can't guess since there is no method for testing. The email script is activated when the card is purchased so I can't just click a "Send test" button to see what comes out in the email that is sent to the user. The preview button dismisses variables.
Anyone happen to know about this? Possibly something like $item->getSku()
Any input helps.
Thanks
That snippet is from the method Enterprise_GiftCard_Model_Observer::generateGiftCardAccounts() which is registered as a handler for sales_order_save_after event. That event is passed the same 'order' object as the "new order placed" emails have. You can experiment by altering that email template and triggering a new email by resending from the order page in admin.
$item->getSku() is almost certainly right.

Resources