I am tearing my hair out with this!
So, I have a variable file setup as follows
<?php
namespace Craft;
class TrackrVariable
{
public function startTrace()
{
if(!isset($_COOKIE['trackr_sess'])):
$sess = StringHelper::randomString(40, TRUE);
$expire = time()+60*60*24*120; // 120 days
setcookie('trackr_sess', $sess, $expire);
$_COOKIE['trackr_sess'] = $sess;
else:
$sess = $_COOKIE['trackr_sess'];
endif;
$trace = new Trackr_TraceModel();
$trace->entry_id = 1;
$trace->sess_id = $sess;
craft()->trackr_trace->saveTrace($trace);
}
}
...and I am calling the function in my template using:
{{ craft.trackr.startTrace() }}
I create the model and set the attributes and hand off to a service. The model looks like this:
<?php
namespace Craft;
class Trackr_TraceModel extends BaseModel
{
public function rules()
{
// Are there any existing rules?
$rules = parent::rules();
// Make all attributes safe
$rules[] = array(implode(',', array_keys($this->getAttributes())), 'safe');
// Send it on outta here
return $rules;
}
protected function defineAttributes()
{
return [
'entry_id' => [
'type' => AttributeType::Number,
'required' => TRUE
],
'sess_id' => [
'type' => AttributeType::String,
'required' => TRUE
]
];
}
}
and the service looks like:
<?php
namespace Craft;
class Trackr_TraceService extends BaseApplicationComponent
{
protected $traceRecord;
public function __construct($traceRecord = null)
{
$this->traceRecord = $traceRecord;
if(is_null($this->traceRecord))
{
$this->traceRecord = Trackr_TraceRecord::model();
}
}
public function saveTrace(Trackr_TraceModel &$trace)
{
if ($id = $trace->getAttribute('id')) :
if ($this->traceRecord->findByPk($id) === NULL):
throw new Exception(Craft::t('Can\'t find trace with ID "{id}"', array('id' => $id)));
endif;
else:
$this->traceRecord->create();
endif;
if ($trace->validate()):
$dt = DateTimeHelper::currentTimeForDb();
$attributes = array(
'entry_id' => $trace->entry_id,
'sess_id' => $trace->sess_id,
'dateCreated' => $dt,
'dateUpdated' =>$dt,
'uid' => StringHelper::UUID(),
'id' => 0
);
foreach($attributes as $k => $v) $this->traceRecord->setAttribute($k,$v);
if($this->traceRecord->save()):
// update id on model (for new records)
$trace->setAttribute('id', $this->traceRecord->getAttribute('id'));
return TRUE;
else:
$model->addErrors($this->traceRecord->getErrors());
return FALSE;
endif;
endif;
}
}
In my mind, the service should be accepting the model, assigning it's attributes to the record and saving the record to the database. Currently, $record->save() is returning TRUE and therefore passing the conditional but no record is created in the dataset, no errors, no trace of any issues whatsoever!
At first I though it might be a 'safe validation' issue as outlined in this answer but, as far as I am aware, I am following all of the advice there.
All I want to be able to do is create a random string, store it in a cookie, as use that cookie to track resources that users view by storing the entry IDs in a table.
If I print out the record and the model separately, the data is being assigned to the attributes just fine, and the cookie bit works.
Please help! Dan
EDIT
The Record file looks like this:
<?php
namespace Craft;
class Trackr_TraceRecord extends BaseRecord
{
public function getTableName()
{
return 'trackr_trace';
}
protected function defineAttributes()
{
return array(
'entry_id' => AttributeType::Number,
'sess_id' => AttributeType::String
);
}
public function defineIndexes()
{
return array(
array('columns' => array('sess_id'), 'unique' => TRUE),
);
}
/**
* Create a new instance of the current class.
*
* @return BaseRecord
*/
public function create()
{
$class = get_class($this);
$record = new $class();
return $record;
}
}
$record = $this->traceRecord;
. Try doing all of your record related operations on$this->traceRecord
directly instead of copying it to$record
. – Brad Bell Aug 14 '15 at 17:16