josh wrote:Well what I did was created mutators and accessory that interally called $this->property. There's no "generation" in the sense it just uses __call I believe. I meant set the field type on the table itself even though doctrine will think its a regular binary field. Doctrine should not change the field type unless you're using the migrations components
Ah got ya regarding the field type.
Regarding the accessors, __call() is not used for the columns. For example, if I have fields:
username
password_hash
password_salt
I have to do:
Code: Select all
$user->username = 'person';
$user->password_hash = '...';
$user->password_salt = '...';
Now the properties with the underscores look weird for one thing, and also I'd like to avoid revealing the logic for the salting so I'd prefer to combine password_hash and password_salt setting into a single method setPassword().
Code: Select all
$user->username = 'person';
$user->setPassword('...');
Inside the setPassword() method it deal with the salt.
It just looks weird having the combination of method calls and __set() invocations.
Granted, I could go through all of my fields as add the methods to the User class but that would be really tedious (and half the reason I adopted Doctrine was to cut out all that time wasted writing getters and setters).
What I did in the end was hacked Record::__call() to add this logic (needs optimizing, I just moved on in a hurry)...
Code: Select all
public function __call($method, $args)
{
if (($template = $this->_table->getMethodOwner($method)) !== false) {
$template->setInvoker($this);
return call_user_func_array(array($template, $method), $args);
}
foreach ($this->_table->getTemplates() as $template) {
if (is_callable(array($template, $method))) {
$template->setInvoker($this);
$this->_table->setMethodOwner($method, $template);
return call_user_func_array(array($template, $method), $args);
}
}
//Patch to add accessors (Chris Corbyn)
$accessor = substr($method, 0, 3);
if ($accessor == 'get' || $accessor == 'set') {
$transformedName = substr($method, 3);
foreach ($this->_table->getColumnNames() as $column) {
$columnParts = explode('_', $column);
foreach ($columnParts as $i => $part) {
$columnParts[$i] = ucfirst($part);
}
if (implode('', $columnParts) == $transformedName) {
if ($accessor == 'get') {
return $this->get($column);
} else {
return $this->set($column, array_shift($args));
}
}
}
}
//End patching
throw new Doctrine_Record_Exception(sprintf('Unknown method %s::%s', get_class($this), $method));
}
This turns the username, password_hash and password_salt fields into:
Code: Select all
$user->setUsername('person');
$user->setPasswordHash('...');
$user->setPasswordSalt('...');
So now when I decide to hide the hash/salt stuff and just add a setPassword() method my interface looks consistent:
Code: Select all
$user->setUsername('person');
$user->setPassword('...');
I'd have thought Doctrine would have already included this functionality, and more. Propel (almost identical to Doctrine) lets you provide names for the accessors and mutators.
But the symfony framework uses Doctrine and they have accessors and mutators generated so I'm confused how they do it. I can't find anything online about it, apart from other people asking why it's not included.
Did you just hard-code mutators and accessors for everything? That must be pretty tedious?