I am working on development of web app, Users are supposed to register on the web app.
This is my table where data is being stored post registration.
I would like to give every user a unique url which would be stored in the same table where details of the users is being saved so that their profile url shares their society name (society_name). For example, the website domain would be www.example.com and the users' url would be www.example.com/mysociety
I would like to save the unique generated url in in the field "url"(#14) of my table.
My User Register Controller looks like this
public function actionRegister() {
$this->layout = 'society';
if (!Yii::$app->user->isGuest) {
return $this->goHome();
}
$model = new User();
$society = new \app\models\Society();
if ($model->load(Yii::$app->request->post())) {
$password= $_POST['User']['password'];
$password_hash = Yii::$app->security->generatePasswordHash($password);
$auth_key = Yii::$app->security->generateRandomString();
$mobile=$_POST['User']['mobile'];
$society = new \app\models\Society();
$random_number=mt_rand(10000, 99999);
$society->society_name = $_POST['Society']['society_name'];
$society->contact_person = $_POST['Society']['contact_person'];
$society->address = $_POST['Society']['address'];
$society->society_id =$random_number;
$society->mobile = $mobile;
$society->status =0;
$society->save();
$session = Yii::$app->session;
return $this->redirect(['regsuccess']);
}
return $this->render('society', [
'model' => $model,
'society' => $society,
]);}
PS : English is not my native language. I am newbie to yii2 and stackoverflow, please excuse me for the mistakes.
Thanks.
I solved it.
Modified my Controller
public function actionRegister() {
$this->layout = 'society';
if (!Yii::$app->user->isGuest) {
return $this->goHome();
}
$model = new User();
$society = new \app\models\Society();
if ($model->load(Yii::$app->request->post())) {
$password= $_POST['User']['password'];
$password_hash = Yii::$app->security->generatePasswordHash($password);
$auth_key = Yii::$app->security->generateRandomString();
$mobile=$_POST['User']['mobile'];
$society = new \app\models\Society();
$random_number=mt_rand(10000, 99999);
$vp_string = trim($_POST['Society']['society_name']);
$vp_string = html_entity_decode($vp_string);
$vp_string = strip_tags($vp_string);
$vp_string = strtolower($vp_string);
$vp_string = preg_replace('[^ a-z0-9_\.]', ' ', $vp_string);
$vp_string = preg_replace('~ ~', '-', $vp_string);
$society->society_name = $_POST['Society']['society_name'];
$society->contact_person = $_POST['Society']['contact_person'];
$society->address = $_POST['Society']['address'];
$society->society_id =$random_number;
$society->mobile = $mobile;
$society->url = $vp_string;
$society->status =0;
$society->save();
$session = Yii::$app->session;
return $this->redirect(['regsuccess']);
}
return $this->render('society', [
'model' => $model,
'society' => $society,
]);}
Related
I am new to Laravel so here goes:
I am creating a page for a user to register an account for his company and enter the payment method and her own login credentials. So this one page will create a Company, a User and a Payment record. The page calls the RegisterController method in Laravel.
However, each of the three objects' create methods are defined within their own controllers. Is it valid (or even good practice) to call other controller methods from within a controller like so (some boilerplate code is missing below...I just want to get my point across)
class RegisterController extends Controller {
//boilerplate code.....
protected function create(Request $request) {
//Create the company
$objCompany = CompanyController->create($request); //gets created first since it is 'top level'
//now create the user:
$objUser = UserController->create($request,$objCompany->id); //Company ID is FK in User
//Create the paymentMethod
$objPaymentMethod = PaymentMethodController->create($request,$objCompany->id); //Company ID is FK in PaymentMethod
}//end create()
}
See rather than calling distinct controllers for table creation try to store the data directly to distinct tables from one controller itself.
like this
public function store(Request $request)
{
$data = request()->validate([
...
]);
$users = new User;
$users->name = $request->name;
$users->ltname = $request->lname;
$users->dob = $request->dob;
$users->bgroup = $request->bgroup;
$users->email = $request->email;
$users->phone = $request->phone;
$users->district = $request->district;
$users->country = $request->country;
$users->state = $request->state;
$users->city = $request->city;
$users->add = $request->add;
$users->pincode = $request->pincode;
$users->password = Hash::make(request('password'));
$users->type = 'Service Center';
$users->save();
$posts = new Post;
$posts->user_id = $users->id;
$posts->fname = $request->fname;
$posts->phone1 = $request->phone1;
$posts->email1 = $request->email1;
$posts->add2 = $request->add2;
$posts->pincode1 = $request->pincode1;
$posts->district1 = $request->district1;
$posts->city1 = $request->city1;
$posts->state1 = $request->state1;
$posts->country1 = $request->country1;
$posts->cmp_id = $request->cmp_id . $users->id;
$posts->gst = $request->gst;
$posts->badd = $request->badd;
$posts->badd2 = $request->badd2;
$posts->save();
$subscribe = new Subscription;
$subscribe->user_id = $users->id;
$subscribe->post_id = $posts->id;
$subscribe->offer_id = $request->m_option_1;
$subscribe->trial_start_date = $offers->of_start_date;
$subscribe->trial_end_date = $offers->of_end_date;
$subscribe->pck_name = $offers->pck_id;
$subscribe->valid_to = $offers->validity;
$subscribe->type = $offers->of_type;
$subscribe->save();
$transactions = new Transactions;
$transactions->user_id = $users->id;
$transactions->post_id = $posts->id;
$transactions->ddl_payment = $request->ddl_payment;
$transactions->txt_ac = $request->txt_ac;
$transactions->txt_amount = $request->txt_amount;
$transactions->txt_dat = $request->txt_dat;
$transactions->txt_ref = $request->txt_ref;
$transactions->save();
return redirect('/show');
}
Here the data which I'm accepting from the form is been stored in four tables users, post, subscription & transaction.
In my user model, I have the following code
public function profile()
{
return $this->hasOne(UserProfile::class);
}
In profile model,
public function user()
{
return $this->belongsTo(User::class);
}
The create method is working, But when I try to update the profile with following code, It is creating a new profile and doesn’t update the profile information.
$profile = new UserProfile();
$profile->dob = '1999-03-20';
$profile->bio = 'A professional programmer.';
$profile->facebook = 'http://facebook.com/test/1';
$profile->github = 'http://github.com/test/1';
$profile->twitter = 'http://twitter.com/test/1';
$user = User::find($userId);
$res = $user->profile()->save($profile);
What is the correct method to update in One to One Relationship ?
I fixed it using push method. Here is the code.
$user = User::find($userId);
$user->name = "Alen";
$user->profile->dob = '1999-03-20';
$user->profile->bio = 'A professional programmer.';
$user->profile->facebook = 'http://facebook.com/test/1';
$user->profile->github = 'http://github.com/test/1';
$user->profile->twitter = 'http://twitter.com/test/1';
$user->push();
You're doing right, however i could suggest a little improvement
You may use the following
$user = User::with('profile')->findOrFail($userId);
if ($user->profile === null)
{
$profile = new UserProfile(['attr' => 'value', ....]);
$user->profile()->save($profile);
}
else
{
$user->profile()->update(['attr' => 'value', ....]);
}
you are using save method to save new record. use update query
//controller
$userObj=new User();
if(!empty($userId) && $userId!=null){
$userObj->updateByUserId($userId,[
'dob' = '1999-03-20';
'bio' = 'A professional programmer.';
'facebook' = 'http://facebook.com/test/1';
'github' = 'http://github.com/test/1';
'twitter' = 'http://twitter.com/test/1';
]);
}
//model
function updateByUserId($userId,$updateArray){
return $this->where('user_id',$userId)->update($updateArray);
}
I'm preparing joomla plugin/api to connect website with mobileapp. I cannot use cookies, I need to do this only by request.
So to login I can go to http://example.net/?user=aaa&pass=bbb and it creates session and returns token.
To go to user profile I can go to: http://example.net/profile?token=8asd7g... and if token matches session id in database then it sets session cookie (on php side) in Joomla framework
Which event should I use to:
check token and maintain session
check login, user and login/create session
check login, user and register user
The second question is how:
is it enought to set $session->set('userid',$user->id); ?
I create fake $response and $app->triggerEvent('onUserLogin', array((array) $response, array('action' => 'core.login.admin'))); is it enough?
If somebody need here is almost fnished solution. It allows users to login via user and pass taken form url or request header, it allows access to restricted parts of website based on token i url not cookie, it allows to pass params from header to JInput->get.
<?php
/**
* #package API
* #subpackage System.sittetokenlogin
*
*/
defined('_JEXEC') or die('Unauthorized Access');
jimport('joomla.filesystem.file');
class PlgSystemSittetokenlogin extends JPlugin
{
public function __construct(&$subject, $config)
{
parent::__construct($subject, $config);
}
public function onUserAuthenticate()
{
//die('onUserAuthenticate');
}
public function onUserLogin()
{//wykonuje się
//die('onUserLogin');
}
public function onUserLogout()
{//wykonuje się
//die('onUserLogout');
}
public function onAfterInitialise()
{
//wstępne ustawienie obiektów
$app = JFactory::getApplication();
if ($app->isClient('administrator')) return;
$input = JFactory::getApplication()->input;
$headers = getallheaders ();
$db = JFactory::getDbo();
//pobranie danych z rządania
$loginToken = $headers['logintoken']; if(!$loginToken) $loginToken = $input->get->get('logintoken', '', 'STRING');
$suser = $headers['suser']; if(!$suser) $suser = $input->get->get('suser', '', 'STRING');
$spass = $headers['spass']; if(!$spass) $spass = $input->get->get('spass', '', 'STRING');
if ($loginToken) // logowanie na bazie tokenu
{
JPluginHelper::importPlugin('user');
$sesja = $db->setQuery('SELECT * FROM `#__session` WHERE `session_id`='.$db->quote($loginToken).' LIMIT 1')->loadObject();
$user = $db->setQuery('SELECT * FROM `#__users` WHERE `id`='.$db->quote($sesja->userid).' LIMIT 1')->loadObject();
$response = new JAuthenticationResponse();
$response->type = 'Joomla';
$response->email = $user->email;
$response->fullname = $user->name;
$response->username = $user->username;
$response->password = '';
$response->status = JAuthentication::STATUS_SUCCESS;
$response->error_message = null;
//print_r($response);
$app->triggerEvent('onUserLogin', array((array) $response, array('action' => 'core.login.site')));
//$testuser = JFactory::getUser(); die(print_r($testuser,true));
}
elseif ($suser && $spass) //logowanie na bazie loginu i hasła
{
$error = $app->login([
'username' => $suser,
'password' => $spass,
]);
$user = JFactory::getUser();
if ($user->id>0) die(JFactory::getSession()->getId());
else die('login_error');
}
//przekazywanie parametrów
$option = $headers['option']; $input->set('option',$option);
$view = $headers['view']; $input->set('view',$view);
$id = $headers['id']; $input->set('id',$id);
$catid = $headers['catid']; $input->set('catid',$catid);
$Itemid = $headers['Itemid']; $input->set('Itemid',$Itemid);
$tmpl = $headers['tmpl']; $input->set('tmpl',$tmpl);
//$input->set('option','com_guru');
//$input->set('view','gurupcategs');
}
}
I have a log in form that checks the user email and password through the database, if it matches, it allow the user to log in. The problem is it checks the email that matches any password in the database or the password that matches any emails in the database. I want it to check this specific user email to match his password, not matches any password that exists in database.
Here's my controller that I think I did it wrong:
$loginForm = new Application_Form_UserLogin();
if ($this->getRequest()->isPost('loginForm'))
{
$email_adrress = $this->getRequest()->getParam('email_address');
$password = $this->getRequest()->getParam('password');
/************ Login Form ************/
if ($loginForm->isValid($this->getRequest()->getParams()))
{
$user = $this->_helper->model('Users')->createRow($loginForm->getValues());
$user = $this->_helper->model('Users')->fetchRowByFields(array('email' => $email_adrress, 'hash' => $password));
if($user)
{
Zend_Session::rememberMe(86400 * 14);
Zend_Auth::getInstance()->getStorage()->write($user);
$this->getHelper('redirector')->gotoRoute(array(), 'invite');
return;
}
else {
}
}
}$this->view->loginForm = $loginForm;
My form:
class Application_Form_UserLogin extends Zend_Form
{
public $email, $password, $submit;
public function init()
{
$this->setName('loginForm');
$EmailExists = new Zend_Validate_Db_RecordExists(
array(
'table' => 'users',
'field' => 'email'
)
);
//$EmailExists->setMessage('Invalid email address, please try again. *');
$PasswordExists = new Zend_Validate_Db_RecordExists(
array(
'table' => 'users',
'field' => 'hash'
)
);
$PasswordExists->setMessage('Invalid password, please try again. *');
$this->email = $this->createElement('text', 'email_address')
->setLabel('Email')
->addValidator($EmailExists)
->addValidator('EmailAddress')
->setRequired(true);
$this->password = $this->createElement('text', 'password')
->setLabel('Password')
->addValidator($PasswordExists)
->setRequired(true);
$this->submitButton = $this->createElement('button', 'btn_login')
->setLabel('Login')
->setAttrib('type', 'submit');
$this->addElements(array($this->email, $this->password, $this->submit));
$elementDecorators = array(
'ViewHelper'
);
$this->setElementDecorators($elementDecorators);
}
}
I wouldn't add this login processing as a validator on one of the elements. Instead, I would create an Zend_Auth authentication adapter with your User model, email, and password as constructor arguments. Then, in controller, call Zend_Auth::authenticate($adapter).
Something like:
class Application_Model_AuthAdapter implements Zend_Auth_Adapter_Interface
{
protected $userModel;
protected $email;
protected $pass;
public function __construct($userModel, $email, $pass)
{
$this->userModel = $userModel;
$this->email = $email;
$this->pass = $pass;
}
public function authenticate()
{
$user = $this->userModel->getByEmailAndPassword($this->email, $this->pass);
if ($user){
return new Zend_Auth_Result(Zend_Auth_Result::SUCCESS, $user);
} else {
return new Zend_Auth_Result(Zend_Auth_Result::FAILURE_CREDENTIAL_INVALID, null);
}
}
}
Then in your controller:
public function loginAction()
{
$form = new Application_Form_UserLogin();
if ($this->_request->isPost()) {
if ($form->isValid($this->_request->getPost())) {
$data = $form->getValues();
$email = $data['email'];
$pass = $data['pass'];
$userModel = $this->_helper->model('Users');
$authAdapter = new Application_Model_AuthAdapter($userModel, $email, $pass);
$result = Zend_Auth::getInstance()->authenticate($adapter);
if ($result->isValid()){
// $user= $result->getIdentity(). Use it how you like.
// Redirect someplace
} else {
$this->view->error = 'Invalid login';
}
}
}
$this->view->form = $form;
}
See Zend_Auth reference for more details.
I'm not familiar with the way you're trying to do it. Is the fetchRowByFields method one you have written yourself? If so, it's difficult to help you without seeing the code.
Have you considered using the mechanism provided by Zend Framework to perform authentication against a database?
The Zend Framework official manual contains a brief tutorial on how to implement authentication:
http://framework.zend.com/manual/1.12/en/learning.multiuser.authentication.html
You use an adapter with the Zend_Auth class to do what you want.
I am trying to delete a post from my table but the code is deleting all table data and not just the one post.
delete.php
<?php
class Form_Delete extends Zend_Form
{
public function __construct()
{
#parent::__construct($options);
$this->setName('Delete');
$id = new Zend_Form_Element_Hidden('id');
$title = new Zend_Form_Element_Hidden('Title');
$description = new Zend_Form_Element_Hidden('Description');
$submit = new Zend_Form_Element_Submit('Delete');
$submit->setAttrib('id', 'submitbutton');
$cancel = new Zend_Form_Element_Submit('cancel');
$cancel->setAttrib('id', 'cancelbutton');
$this->addElements( array( $id, $title, $description, $submit, $cancel ));
}
}
and my controller code
public function deleteAction()
{
//action body
$request = $this->getRequest();
$postid = (int)$request->getParam('id');
$post = new Model_DbTable_Posts();
$result = $post->getPost($postid);
$this->view->post = $result;
if(!Zend_Auth::getInstance()->hasIdentity()) {
$this->_redirect('posts/view/id/'.$postid);
}
$identity = Zend_Auth::getInstance()->getIdentity();
$acl = new Model_Acl();
if( $acl->isAllowed( $identity['Role'] ,'posts','edit','delete') ) {
$deleteForm = new Form_Delete();
$deleteModel = new Model_DbTable_Posts();
if ($this->getRequest()->isPost()) {
if ($deleteForm->isValid($request->getPost())) {
$deleteModel->delete($dpostid);
$this->_redirect('index/index');
}
}
$this->view->deleteForm = $deleteForm;
}
I have tried for hours to get this working but can ether get it to delete all or nothing. Any help would be great!
You need to pass delete() the where clause to evaluate. Try:
$where = $deleteModel->getAdapter()->quoteInto('id = ?', $dpostid);
$deleteModel->delete($where);
Change 'id' to whatever your primary key is.
Also #parent::__construct($options); in your form class is a little odd. Change that to parent::__construct();. No need to supress the error if you don't generate one.