當實體(如 Activity)保存時,系統自動處理上傳的圖標文件:
if (isset($_FILES['icon']) && strpos($_FILES['icon']['type'], 'image/') === 0) {
$prefix = "activity/{$activity->guid}";
$file = new ElggFile();
$file->owner_guid = $activity->owner_guid;
$file->setFilename($prefix . ".jpg");
$file->open('write');
$file->write(get_uploaded_file('icon'));
$file->close();
// 生成四種尺寸縮略圖
$sizes = ['tiny'=>25, 'small'=>40, 'medium'=>100, 'large'=>200];
foreach ($sizes as $suffix => $size) {
$thumb = get_resized_image_from_existing_file($file->getFilenameOnFilestore(), $size, $size, true);
if ($thumb) {
$tfile = new ElggFile();
$tfile->owner_guid = $activity->owner_guid;
$tfile->setMimeType('image/jpeg');
$tfile->setFilename("{$prefix}{$suffix}.jpg");
$tfile->open('write');
$tfile->write($thumb);
$tfile->close();
}
}
}
文件按用戶 GUID 字符分目錄存儲:{dataroot}/{a}/{b}/{c}/.../{guid}{size}.jpg,例如用戶 GUID 12345 存儲於 1/2/3/4/5/ 目錄下。
$entity->getIcon($size) → 內部調用 get_entity_icon_url()entity:icon:url:$url = trigger_plugin_hook('entity:icon:url', $entity->getType(), [...], $url);start.php 註冊鉤子:register_plugin_hook('entity:icon:url', 'object', 'activity_activityicon_hook');function activity_activityicon_hook($hook, $type, $return, $params) {
global $CONFIG;
if (!$return && $hook == 'entity:icon:url' && $params['entity'] instanceof Activity) {
$entity = $params['entity'];
$size = $params['size'];
$icontime = $entity->icontime ?: 'default';
$file = new ElggFile();
$file->owner_guid = $entity->owner_guid;
$file->setFilename("activity/{$entity->guid}{$size}.jpg");
if ($file->exists()) {
return "{$CONFIG->url}pg/activityicon/{$entity->guid}/{$size}/{$icontime}.jpg";
}
}
}
icontime 參數實現瀏覽器緩存失效(更新圖標時修改該時間戳)owner_guid,配合 Elgg 權限系統控制訪問此機制體現了 Elgg 核心與插件解耦、實體文件管理統一化的設計哲學。