I have your standard contact form. (Name, email etc.)
When the user clicks "save" I want to capture what was entered via a plugin & have a CP page to show the people who have filled out the form. I'll get there eventually, but for now I am stuck actually inserting the record.
I am able to insert a record, but it's completely empty. So I know I'm getting close, just not passing off the right information to the right spot.
Model:
public function defineAttributes()
{
return[
'firstName' => [
'type' => AttributeType::String,
'required' => TRUE
]
....
];
}
Controller:
public function actionSaveContact() {
$this->requirePostRequest();
$model = new Model();
$model->firstName = craft()->request->getPost('firstName');
....
if ($model->validate())
{
craft->service->saveContact($model);
}
}
Service:
public function saveContact(Model, $contact) {
error_log(print_r($contact, true));
// I know the data is showing, I can see it in the log
// [_attributes:Craft\BaseModel:private] => Array(
// [firstName] => Bob
// )
// Here is where I am hung up. I don't know what to do next.
// $record = new Record();
// $record->save($contact); This creates an empty record in my db
}
I feel really silly asking for help on what seems like such an elementary task. I'm close - just need a little shove in the right direction I think.
Thank you!
EDIT
Thank you to Mats Mikkel Rummelhoff for your suggestion. It pointed me in the right direction. It seems what I am encountering now has been found in the past? Now it seems I am only saving one field? Using this post I was able to "manually" collect all data and save to my DB. I'm not sure why though - all of the data seemed to be available.
Service
....
$attributes = array(
'firstName' => $model->getAttribute( 'firstName' )
....
);
foreach($attributes as $k => $v) {
$record->setAttribute($k,$v);
}
if ( $record->save() )
{
error_log('SUCCESS');
}
else
{
....
}
EDIT
Thank you so much for everyone's contribution(s). I'm going to keep updating this in the event that someone else comes across this same problem.
Going along with @Stuart Whitehead comments, right here is proof: "AttributeType::String does not apply any validation rules." Which is why that field was not getting populated.
Which is what I was setting as my firstName
, lastName
and so on.
I have also found this article: The Definitive Guide to Validation in Craft Which, is making more and more sense each time I go though it.
The tricky part (for me) is that there isn't a direct corolation between craft and Yii. Meaning that Yii doesn't have a defineAttributes()
method where the rules are defined. Craft uses this method, and translates it (for lack of better words) into the Yii equivalent. Pretty cool, just increases the learning curve a bit.
Light bulbs are coming on!
EDIT
This is probably pretty elementry, but I have also discovered that the attribute type that you define in your model, must match the same attribute type in your record. For example:
Record
public function defineAttributes() {
'firstName' => AttributeType::Name,
'lastName' => AttributeType::Name,
....
}
Model
public function defineAttributes() {
return [
'firstName' => [
'type' => AttributeType::Name,
'required' => TRUE
],
'lastName' => [
'type' => AttributeType::Name,
'required' => TRUE
],
....
];
}
Now with things starting to get in the correct way of doing things, gasp stuff is working. Now using @Mats Mikkel Rummelhoff's comment (having all fields validate now) I am able to use:
$record->setAttributes( $model->getAttributes() );