Hi i want to remove some data. I do view where i want to delete aditional data. This is my controller veiew becouse i want to make there button where i can delete data:
public function actionView($id) {
return $this->render('view', [
'model' => $this->findModel($id),
'userDate'=>$this->findData($id)
]);
}
public function actionDelet($id) {
$this->findData($id)->delete();
return $this->redirect(['index']);
}
public function findData($id){
if (($model = Profile::findOne($id)) !== null) {
$id=$model->Rel_UserData;
$user = UserData::find()->where(['Id' => $id])->one();
return $user;
} else {
throw new NotFoundHttpException('The requested page does not st.');
}
}
I guess solution is like that:
$item = $this->findData($id);
$item->delete();
You already have a relational function calling the UrRoyalUserData class: getRelRoyalUserData(). You can simplify your code doing:
public function findData($id)
{
if (($model = Profile::findOne($id)) !== null) {
$user = $model->relRoyalUserData;
return $user;
}
throw new NotFoundHttpException('The requested page does not st.');
}
Besides that, can you change your action and check what is returning?
public function actionDelet($id)
{
var_dump($this->findData($id));
}
If it throws you the same error, that means you dont have that Profile in your table. But if don't return a UrRoyalUserData class, the problem is you don't have any UrRoyalUserData related to that Profile.
Related
I'm having a controller with some functions. In every function I get user data by sharing it from the Contoller.php
In controller.php
public function share_user_data() {
$user = Auth::user();
$this->checkValidation($user);
$this->user = $user;
View::share('user', $user);
}
public function checkValidation($user){
if($user->email_activated == 0){
var_dump($user->email_activated); // I get: int(0)
return redirect('/verifyEmail');
}
}
In the other controller
public function viewCategory(Category $category){
$this->share_user_data(); // here's the check
$this->get_site_lang();
$products = $category->products;
return view('category', compact('category','products'));
}
But I get the category view and not redirected to the verifyEmail route. How to fix this and why it's happening?
The controller function called by the route is the one responsible for the response. I guess it is viewCategory() in your example?
Your viewCategory() function is always returning view(). It must return redirect() instead. I think the main function should be responsible for picking the output of the request.
private function checkValidation($user) {
return $user->email_activated == 0;
}
public function viewCategory(Category $category) {
$user = Auth::user();
/* ... call to share_user_data() or whatever ... */
if ($this->checkValidation($user)) {
return redirect('/verifyEmail');
}
return view('category', compact('category','products'));
}
I am trying to implement email account verification.
If a user has not confirmed their email, they can still log in, but they should not be able to access any actions in the account module. So for example, if they try to access:
/account/profile/edit
/account/listing/add
it should redirect the user to /account/default/confirm, which displays a message saying:
"You have not yet confirmed your account, please click the link in the confirmation email, or click here to resend the confirmation email".
I have tried the following:
BaseController:
class BaseController extends Controller
{
protected function findUser($id)
{
if (($model = User::findOne(['id' => $id, 'deleted_at' => null])) !== null) {
if ($model->confirmed_at == null) {
return $this->redirect(['/account/default/confirm']);
}
return $model;
} else {
throw new NotFoundHttpException('The requested page does not exist.');
}
}
}
ProfileController:
class ProfileController extends BaseController
{
public function actionEdit()
{
$user = $this->findUser(Yii::$app->user->id);
$profile = $user->profile; // getProfile() relation in User model
return $this->render('index', [
'profile' => $profile,
]);
}
}
The problem I am having is that it gives me an error:
"Trying to get property 'profile' of non-object".
I think the reason for the error is because it seems to be assigning the redirect to $user, instead of actually terminating the request at the redirect.
I know instead of doing return $this->redirect() in findUser() I can do it in the controller action, but then I would have to do this for every action. Is there a better way of doing this? Maybe some kind of access rules or behaviour?
Here try to check !empty() before $model access like
class BaseController extends Controller
{
protected function findUser($id)
{
if (($model = User::findOne(['id' => $id, 'deleted_at' => null])) !== null) {
if (!empty($model->confirmed_at)) {
return $model;
}
return $this->redirect(['/account/default/confirm']);
} else {
throw new NotFoundHttpException('The requested page does not exist.');
}
}
}
$this->redirect() will return response object - it looks like really bad design if such method may return completely unrelated object (Response or User). You probably should call Application::end() to terminate application, so redirection will take effect without continuing execution of controller action.
protected function findUser($id) {
if (($model = User::findOne(['id' => $id, 'deleted_at' => null])) !== null) {
if ($model->confirmed_at == null) {
$this->redirect(['/account/default/confirm']);
Yii::$app->end();
}
return $model;
}
throw new NotFoundHttpException('The requested page does not exist.');
}
I am building a test API. I have created a Controller Page which extends from yii\rest\Controller. Actions needs to send a response.
To access actions in this controller, a service_id value needs to be posted. If present I need to evaluate if that service_id exists, if it is active and belongs to the user logged in. If validation fails, I need to send a response.
I am trying to do it using beforeAction(), but the problem is that return data is used to validate if action should continue or not.
So my temporary solution is saving service object in a Class attribute to evaluate it in the action and return response.
class PageController extends Controller
{
public $service;
public function beforeAction($action)
{
parent::beforeAction($action);
if (Yii::$app->request->isPost) {
$data = Yii::$app->request->post();
$userAccess = new UserAccess();
$userAccess->load($data);
$service = $userAccess->getService();
$this->service = $service;
}
return true;
}
public function actionConnect()
{
$response = null;
if (empty($this->service)) {
$response['code'] = 'ERROR';
$response['message'] = 'Service does not exist';
return $response;
}
}
}
But I can potentially have 20 actions which require this validation, is there a way to return the response from the beforeAction method to avoid repeating code?
You can setup response in beforeAction() and return false to avoid action call:
public function beforeAction($action) {
if (Yii::$app->request->isPost) {
$userAccess = new UserAccess();
$userAccess->load(Yii::$app->request->post());
$this->service = $userAccess->getService();
if (empty($this->service)) {
$this->asJson([
'code' => 'ERROR',
'message' => 'Service does not exist',
]);
return false;
}
}
return parent::beforeAction($action);
}
maybe paste in beforeAction after $this->service = $service;
if (empty($this->service)) {
echo json_encode(['code' => 'ERROR', 'message' => 'Service does not exist']);
exit;
}
I have this formrequest that contains rules and a withValidator as a second layer of validation.
Note: I am aware that having it unique on the rules would supress the need for this example, but I'll need to do further validations here.
public function rules(Request $request) {
return [
"name" => "required|max:191",
"begin_date" => "required|after_or_equal:today|date_format:d-m-Y",
"end_date" => "required|after:begin_date|date_format:d-m-Y",
];
}
public function withValidator($factory) {
$result = User::where('name', $this->name)->get();
if (!$result->isEmpty()) {
$factory->errors()->add('User', 'Something wrong with this guy');
}
return $factory;
}
I am positive that it enters the if as I've placed a dd previously it to check if it's going inside. However, it proceeds to this method on the Controller and I don't want it to.
public function justATest(UserRequest $request) {
dd("HI");
}
I'm an idiot and didn't read the full doc.
It needs to specify with an after function,like this:
public function withValidator($factory) {
$result = User::where('name', $this->name)->get();
$factory->after(function ($factory) use ($result) {
if (!$result->isEmpty()) {
$factory->errors()->add('User', 'Something wrong with this guy');
}
});
return $factory;
}
I was facing this problem too.
I changed my withValidator to this:
public function withValidator($validator)
{
if (!$validator->fails()) {
$validator->after(function ($validator) {
if (Cache::has($this->mobile)) {
if (Cache::get($this->mobile) != $this->code) {
$validator->errors()->add('code', 'code is incorrect!');
} else {
$this->user = User::where('mobile', $this->mobile)->first();
}
} else {
$validator->errors()->add('code', 'code not found!');
}
});
}
I'm trying to create a callback to return my views based on data from my current logged-in user. If I do something basic like echoing 'hi' it works, is there any way accomplish this?
function checkUser($type,$callback){
if( is_callable($callback) ){
call_user_func($callback);
}
}
class FichaController extends Controller
{
public function contarFichas()
{
checkUser('particular',function(){
$currentUser = Auth::user();
$countFichas = Ficha::where('user_id',$currentUser->id)->count();
return view('particular.index', array('countFichas' => $countFichas));
});
}
}
Return the result from checkUser
if( is_callable($callback) ){
return $callback();
}
public function contarFichas()
{
return checkUser('particular',function(){
$currentUser = Auth::user();
$countFichas = Ficha::where('user_id',$currentUser->id)->count();
return view('particular.index', array('countFichas' => $countFichas));
});
}