I am using CakePHP 2.3, I want to save data as follows follows:
$insertUser = array(
'Name' => $Name,
'LastName' => $lastName,
'password' => $password,
'email' => $email,
'TimeStamp' => $presentTime,
'RefererUserId' => $refererId // set the referer user id
);
$this->SystemUser->saveAll($insertUser) // save record in table.
The above code is not working. I tried another method like:
$this->SystemUser->query("INSERT INTO system_users(Name,LastName,password,email,TimeStamp,RefererUserId) VALUES ('{$Name}','{$lastName}','{$password}','{$email}','{$presentTime}','{$refererId}')");
How can I now get the last inserted id? I used getLastInsertId() to get last inserted id, as below:
$lastid = $this->SystemUser->getLastInsertId();
But it does not seem to work.
Please try the below code. SystemUser is assumed as your model name.
$this->user_data = array(
'SystemUser' => array(
'Name' => $Name,
'LastName' => $lastName,
'password' => $password,
'email' => $email,
'TimeStamp' => $presentTime,
'RefererUserId' => $refererId // set the referer user id
));
if ($this->SystemUser->save($this->user_data)) {
$lastid = $this->SystemUser->getLastInsertId();
} else {
// do something
}
Your $insertUser should be the following
$insertUser['SystemUser'] = array(
'Name' => $Name,
'LastName' => $lastName,
'password' => $password,
'email' => $email,
'TimeStamp' => $presentTime,
'RefererUserId' => $refererId // set the referer user id
);
Then you should be save data as like
if($this->SystemUser->save($insertUser)) {
$lastid = $this->SystemUser->getLastInsertId();
} else {
debug($this->SystemUser->validationErrors); die();
}
This will probably give you the info you need (assuming it's not saving because of invalid data, of course):
debug($this->SystemUser->validationErrors); die();
That's it.
Related
I'm doing cakephp4 controller test with phpUnit but when I call save my id auto_increment disapear.
My table before save():
Image before save
The test:
public function testAdd(): void
{
$this->session([
'Auth' => [
'id' => 1,
'DNI_CIF' => '22175395Z',
'name' => 'Prueba',
'lastname' => 'Prueba Prueba',
'username' => 'Pruebatesting',
'password' => 'prueba',
'email' => 'prueba#gmail.com',
'phone' => '639087621',
'role' => 'admin',
'addres_id' => 1
]
]);
$this->get('animal/add');
$this->assertResponseOk();
$data=[
'id' => 1,
'name' => 'AñadirAnimal',
'image' => '',
'specie' => 'dog',
'chip' => 'no',
'sex' => 'intact_male',
'race' => 'cat',
'age' => 1,
'information' => 'Es un animal.',
'state' => 'sick',
'animal_shelter' => [
'id' => 1,
'start_date' => '2022-11-03 10:47:38',
'end_date' => '2022-11-03 10:47:38',
'user_id' => 1,
'animal_id' => 1
]
];
$this->enableCsrfToken();
$this->post('animal/add',$data);
$this->assertResponseOk();
}
The controller:
public function add()
{
$animal = $this->Animal->newEmptyEntity();
if ($this->request->is('post')) {
$animal = $this->Animal->patchEntity($animal, $this->request->getData());
if(!$animal->getErrors){
$image = $this->request->getData('image_file');
if($image !=NULL){
$name = $image->getClientFilename();
}
if( !is_dir(WWW_ROOT.'img'.DS.'animal-img') ){
mkdir(WWW_ROOT.'img'.DS.'animal-img',0775);
if($name){
$targetPath = WWW_ROOT.'img'.DS.'animal-img'.DS.$name;
$image->moveTo($targetPath);
$animal->image = 'animal-img/'.$name;
}
}
if ($this->Animal->save($animal)) {
$this->Flash->success(__('El animal se ha añadido.'));
return $this->redirect(['action' => 'index']);
}
}
$this->Flash->error(__('El animal no se ha podido añadir, por favor intentalo de nuevo'));
}
$allUsers = $this->getTableLocator()->get('User');
$user = $allUsers->find('list', ['limit' => 200])->all();
$this->set(compact('animal','user'));
}
My table after:
Image after save
The error:
1) App\Test\TestCase\Controller\AnimalControllerTest::testAdd
Possibly related to PDOException: "SQLSTATE[HY000]: General error: 1364 Field 'id' doesn't have a default value"
…
Failed asserting that 500 is between 200 and 204.
I don't know why this is happening or how to know the reason. In the app the controller works fine. Data in the app:
Data in app
Data in test:
Data in test
I hope someone can help me, I don't know what to try anymore or how to know where the problem is...
I tried to look at the data but it doesn't apear to have any errors so I don't know where the error can be.
It was that the sql file used in the bootstrap didn't have the autoincrement value.
I want to extend validation setting another field just like that:
return Validator::make($data, [
'name' => 'required|max:255',
'email' => 'required|email|max:255|unique:users',
'password' => 'required|min:6|confirmed',
'another_field' => 'validation'
]);
you can make your own validation case by follwing the documentation :)
If you need to change the message only, you can do it by
$messages = [
'required' => 'The :attribute field is required.',
'email' => 'This is a wrong e-mail address message I wrote myself.',
];
$rules = [
'name' => 'required|max:255',
'email' => 'required|email|max:255|unique:users',
'password' => 'required|min:6|confirmed',
'another_field' => 'validation'
];
return Validator::make($input, $rules, $messages);
What i'm doing wrong?
<?php
public function login() {
$user_name = time();
User::create(array(
'name' => $user_name,
'email' => $user_name.'#test.com',
'password' => Hash::make('123123'),
));
$user = array(
'email' => $user_name.'#test.com',
'password' => '123123',
);
$m = User::where('email' , '=', $user_name.'#test.com')->first();
dd([
'Auth::attempt($user)',
Auth::attempt($user),
'Auth::check()',
Auth::check(),
'Hash::check($m->password, \'123123\')',
Hash::check($m->password, '123123')
]);
}
Result:
array(6) {
[0]=>
string(20) "Auth::attempt($user)"
[1]=>
bool(false)
[2]=>
string(13) "Auth::check()"
[3]=>
bool(false)
[4]=>
string(38) "Hash::check($user->password, '123123')"
[5]=>
bool(false)
}
Not sure what information should I add.
app/config/auth.php
'driver' => 'eloquent',
'model' => 'User',
'table' => 'users',
app/config/app.php
'key' => 'DMmiPAxSYz4O2jG44S92OcdPZN7ZsGGs',
'cipher' => MCRYPT_RIJNDAEL_256,
models/User.php
<?php
use Illuminate\Auth\UserTrait;
use Illuminate\Auth\UserInterface;
use Illuminate\Auth\Reminders\RemindableTrait;
use Illuminate\Auth\Reminders\RemindableInterface;
class User extends Eloquent implements UserInterface, RemindableInterface {
use UserTrait, RemindableTrait;
/**
* Validation rules
*/
public static $rules = array(
'name' => 'required',
'email' => 'email|required|unique',
'password' => 'min:6',
);
/**
* Validation rules
*/
public static $messages = array(
'name.required' => 'The name field is required',
'email.email' => 'The email field must contain properly formatted email.',
'email.required' => 'The email field is required',
'password.required' => 'The password field is required',
'password.min:6' => 'The password must be minimum 6 characters long',
);
protected $table = 'users';
protected $hidden = array('password', 'remember_token');
protected $guarded = array('id');
public function setPasswordAttribute($value) {
if ($value) {
$this->attributes['password'] = Hash::make($value);
}
}
}
Well here's some checks that you can do
Have you setup config/auth.php with driver, model and table?
Have you filled the fillable array of the User's model?
Have you change the key inside config/app.php ?
Also try to dd($m) in order to see what you got from that query.
I found what is wrong.
This part of code hash password for first time:
User::create(array(
'name' => $user_name,
'email' => $user_name.'#test.com',
'password' => Hash::make('123123'), // <---- first time
));
And this mutator in User model does hashing for second time before put password to database:
public function setPasswordAttribute($value) {
if ($value) {
$this->attributes['password'] = Hash::make($value); // <---- second time
}
}
So I just changed first block to this:
User::create(array(
'name' => $user_name,
'email' => $user_name.'#test.com',
'password' => '123123', // <---- no hashing here
));
Model Search Method
$criteria->alias = 'c';
$criteria->select = 'c.*,max(ca.date) AS lastactivity';
$criteria->join = 'LEFT JOIN tbl_contact_action AS ca ON (ca.contact_id=c.contact_id)';
$criteria->condition = 'c.status<>"Deleted"';
$criteria->group = 'c.contact_id';
$criteria->order = 'lastactivity DESC';
$sort = new CSort;
$sort->defaultOrder = array('lastactivity' => CSort::SORT_DESC); //'name ASC';
$sort->attributes = array(
'name' => 'name',
'email' => 'email',
'status' => 'status',
'createdon' => 'createdon',
'lastactivity' => 'lastactivity',
);
$sort->applyOrder($criteria);
return new CActiveDataProvider($this, array(
'criteria' => $criteria,
'sort' => $sort,
));
Basically, I have a 1:n relationship where in I need only latest record from child table. The parent table data will be displayed based on the comment that is done latest in child table. How to make this field sortable ?
Error
CDbCommand failed to execute the SQL statement: SQLSTATE[42S22]: Column not found: 1054 Unknown column 'c.lastactivity' in 'order clause'.
Just a theory:
because you have a join with together sql, all the data will be together in 1 result. I am not sure if you can still use $data->ca->date because your data is not a known active record type.
Try putting
$criteria->select = 'maintable.*,ca.date as ca_date';
then you should be able to use
array(
'header' => 'Last Activity',
'class' => 'gridDataColumn',
'value' => '$data->ca_date',
),
Below is the Model which will allow to have a custom/computational field that will be SORTABLE. Instead of simply writing 'lastactivity'=>'lastactivity' in sort array, passing whole array did the trick for me. Hope it helps someone :)
class Contact extends CActiveRecord {
public $verifyCode;
public $lastactivity;
public static function model($className = __CLASS__) {
return parent::model($className);
}
public function tableName() {
return '{{contact}}';
}
public function rules() {
return array(
array('name, email, subject, message', 'required', 'message' => Yii::t('app', 'MSG_ATTRIBUTE_BLANK')),
array('email', 'email'),
array('verifyCode', 'CaptchaExtendedValidator', 'allowEmpty' => !CCaptcha::checkRequirements(), 'on' => 'fContact'),
array('name, email,subject,message,lastactivity', 'safe', 'on' => 'search'),
array('name, subject, email, message, status,createdon,updatedon,verifyCode,lastactivity', 'safe'),
);
}
public function relations() {
return array(
'ca' => array(self::HAS_MANY, 'ContactAction', 'contact_id'),
);
}
public function search() {
$criteria = new CDbCriteria;
$criteria->compare('name', CommonFunctions::escapeOperator($this->name), true, 'OR');
$criteria->compare('subject', CommonFunctions::escapeOperator($this->subject), true, 'OR');
$criteria->compare('email', CommonFunctions::escapeOperator($this->email), true, 'OR');
$criteria->compare('status', CommonFunctions::escapeOperator($this->status), true,'OR');
$lastactivity_sql = '(select max(date) from tbl_contact_action ca where ca.contact_id=t.contact_id)';
$criteria->select = array('*', $lastactivity_sql . ' as lastactivity');
$criteria->addCondition('status<>"Deleted"');
$criteria->compare($lastactivity_sql, $this->lastactivity);
$sort = new CSort;
$sort->defaultOrder = array('lastactivity' => CSort::SORT_DESC); //'title ASC';
$sort->attributes = array(
'name' => 'name',
'email' => 'email',
'status' => 'status',
'createdon' => 'createdon',
'lastactivity' => array(
'asc' => 'lastactivity ASC',
'desc' => 'lastactivity DESC',
),
);
$sort->applyOrder($criteria);
return new CActiveDataProvider($this, array(
'criteria' => $criteria,
'sort' => $sort,
'pagination' => array(
'pageSize' => Yii::app()->user->getState('contactPageSize', Yii::app()->params['RECORDPERPAGE_ADMIN']),
'currentPage' => Yii::app()->user->getState('Contact_page', 0),
),
));
}
}
i am newbie in cakephp and trying to implement this query
SELECT DISTINCT textmessage.mobileNo FROM textmessage
JOIN contacts
ON textmessage.User_id=contacts.User_id AND textmessage.mobileNo = Contacts.mobileNo
i am expecting only one result here .. want to implement this query in textMessage Controller ... i have never use join query before in CAKEPHP... i have actually a mobileNo field in both the tables and i want to retrieve the mobileNo if the mobileNo of textmessage table is also in Contacts table
here is what i have modified your query according to my requirments ..
$this->bindModel(array('belongsTo' => array('Contact' => array('className' => 'Contact',
'foreignKey' => false,
'conditions' => array('Message.user_id = Contact.user_id','Message.mobileNo = Contact.mobileNo')))), true);
return $message_details = $this->find('all', array('conditions' => array(),
'fields' => array('DISTINCT mobileNo')));
Put the following code in your controller's code:
If you need only single record:
function test1()
{
$this->TextMessage->bindModel(array('belongsTo' => array('Contact' => array('className' => 'Contact',
'foreignKey' => false,
'conditions' => array('TextMessage.user_id = Contact.user_id')))), false);
$message_details = $this->TextMessage->find('all', array('conditions' => array(),
'fields' => array('DISTINCT mobileNo')));
}
If you have multiple text messages corresponding to each contact then try the following:
function test2()
{
$this->Contact->bindModel(array('hasMany' => array('TextMessage' => array('className' => 'TextMessage',
'foreignKey' => false,
'conditions' => array('TextMessage.user_id = Contact.user_id'),
'fields' => array('DISTINCT mobileNo')))
), false);
$message_details = $this->Contact->find('all', array('conditions' => array()));
}
You can also write the association in your model. I gave you an example to dynamically join any table on the fly.
According to your edited question, if you don't need two arrays. Use query() function.
Hope this will fulfill your requirement.