Good afternooon everyone, i'll go straight to the point. I have this code at my model:
protected $_referenceMap = Array (
"Imagens" => Array(
"columns" => Array (
'paiId'
),
"refTableClass" => "ModeloImagem",
"refColumns" => Array(
"id"
),
"onDelete" => self::CASCADE
)
);
I must delete the images on the table that's going to be called on cascade, so i wanted to know if is there something like:
protected $_referenceMap = Array (
"Imagens" => Array(
"columns" => Array (
'paiId'
),
"refTableClass" => "ModeloImagem",
"refColumns" => Array(
"id"
),
"onDelete" => function() {
foreach($image as $i) {
unlink($i);
}
return self::CASCADE
}
)
);
There is no such thing. What you can do is extend Zend_Db_Table's method _cascadeDelete($parentTableClassname, array $primaryKey)
to execute the function.
Here's one way to do it, although it's a terrible amount of code duplication; you might have to specify your own data that you want to be passed to the callback, or modify behavior depending on whether your callback or query fails:
class My_Db_Table extends Zend_Db_Table
{
const ON_DELETE_CALLBACK = 'onDeleteCallback';
/**
* Called by parent table's class during delete() method.
*
* @param string $parentTableClassname
* @param array $primaryKey
* @return int Number of affected rows
*/
public function _cascadeDelete($parentTableClassname, array $primaryKey)
{
$rowsAffected = 0;
foreach ($this->_getReferenceMapNormalized() as $map) {
if ($map[self::REF_TABLE_CLASS] == $parentTableClassname && isset($map[self::ON_DELETE])) {
switch ($map[self::ON_DELETE]) {
case self::CASCADE:
for ($i = 0; $i < count($map[self::COLUMNS]); ++$i) {
$col = $this->_db->foldCase($map[self::COLUMNS][$i]);
$refCol = $this->_db->foldCase($map[self::REF_COLUMNS][$i]);
$type = $this->_metadata[$col]['DATA_TYPE'];
$where[] = $this->_db->quoteInto(
$this->_db->quoteIdentifier($col, true) . ' = ?',
$primaryKey[$refCol], $type);
}
$this->_executeCallback($map, $where);
$rowsAffected += $this->delete($where);
break;
default:
// no action
break;
}
}
}
return $rowsAffected;
}
private function _executeCallback($map, $where) {
if (isset($map[self::ON_DELETE_CALLBACK]) && is_callable($map[self::ON_DELETE_CALLBACK])) {
call_user_func($map[self::ON_DELETE_CALLBACK], $where);
}
}
}
You then use this to define the callback function. You can't define cascade in callback function though; else all your images get deleted every time Zend_Db_Table tries to figure out whether to delete entries from images table.
protected $_referenceMap = Array (
"Images" => Array(
"columns" => Array (
'paiId'
),
"refTableClass" => "ModeloImagem",
"refColumns" => Array(
"id"
),
"onDelete" => self::CASCADE,
"onDeleteCallback" => function($where) {
// Determine which image to unlink
unlink($image);
}
)
);