Hey with big thanks to Armin, we've came up with a good way to handle thumbnails.
Here is the code if you can figure it out, but I would need to cover that in an screencast.
Class Model_Picture ...
inside init:
$this->hasOne('User');
$this->hasOne('Image','filestore_file_id');
$this->addField('type'); // for different picture types of a user
/* Creates a sophisticated query for getting image paths */
function getPathExpression($field='thumb_url',$is_thumb=true){
// We will be building sub-query for the picture
$p=$this->newInstance();
// Picture needs to be joined with filestore
$pic=$p
->join('filestore_file','filestore_file_id')
;
// If we need thumbnail, that's few more joins
if($is_thumb){
$pic=$pic
->join('filestore_image.original_file_id')
->join('filestore_file','thumb_file_id')
;
}
// Finally we need volume
$v=$pic->join('filestore_volume');
// Construct the field
$p->addExpression($field,function($m,$s)use($v,$p,$pic){
return $s->expr(
'COALESCE(
concat("'.$p->api->pm->base_path.'",'.
$v->fieldExpr('dirname').
',"/",'.
$pic->fieldExpr('filename').
')
, "'.$p->api->locateURL('template','images/portrait.jpg').'") ');
});
return $p;
}
Inside User mode:
$this->addExpression('profile_pic_url')->set(function($m){ return $m->getPictureExpr('profile',true); })->display(array('grid'=>'picture'));
// formatter for the picture is defined in Grid::format_picture(), formatter for the picture is set by display() method
$this->addExpression('cover_pic_url')->set(function($m){ return $m->getPictureExpr('cover', true); })->display(array('grid'=>'picture'));
$this->addExpression('profile_pic_thumb')->set(function($m){ return $m->getPictureExpr('profile'); })->display(array('grid'=>'picture'));
$this->addExpression('cover_pic_thumb')->set(function($m){ return $m->getPictureExpr('cover'); })->display(array('grid'=>'picture'));
// method builds sub-select for the picture joined with filestore
function getPictureExpr($type='pr',$is_thumb=false){
$p=$this->add('Model_Picture')->getPathExpression('pic_url',$is_thumb);
// Need
$p->addCondition('type',$type);
$p->addCondition('user_id',$this->getElement('id'));
$query=$p->dsql()->del('fields');
$p->getElement('pic_url')->updateSelectQuery($query);
return $query;
}
Finally if you want this in grid as a picture, you would need formatter:
function format_picture($field){
$this->current_row_html[$field] =
"<img src='" . $this->current_row[$field] . "' height='100'></a>";
}
Works awesome, easy to join from any model and only extends the original master select.