Drupal 服务 - 直接文件 URL 而不是文件资源引用
Drupal Services - Direct file URL instead of file resource reference
我正在使用 Drupal services 和 services_entity 模块来构建 Web 服务。问题是,当使用字段等将文件附加到实体时,服务端点将文件显示为资源引用:
array (
resource: file,
id: xx,
uri: /entity_file/xx.json
)
事实是,每次您希望显示一个文件时,您都必须发出 2 个或更多请求:
- 首先,获取文件实体URI
- 其次,通过id检索文件实体的详细信息,得到文件的直接url(可以嵌入到应用程序中或用作src ="xx" 用于 img 标签。
问题是,如何直接获取文件 URL 而无需进行额外请求。因此,首选响应是:
array (
resource: file,
id: xx,
uri: /entity_file/xx.json,
url: http://.../sites/.../files/foo/bar/b-reft.jpg
)
我找了几个小时但没有找到答案,所以我想我会分享我找到的解决方案。我相信它会帮助很多人(我也希望我可以分享我的模块,以支持 services_entity 模块的复杂索引查询参数)。
声明资源控制器
由于数据由 ServicesEntityResourceController 返回,我决定使用 hook_services_entity_resource_info() 声明我自己的资源控制器.
/**
* Implements hook_entity_resource_info()
*/
function c11n_services_entity_resource_info() {
$output = array();
$output['c11n'] = array (
'title' => 'Clean Entity Processor - Customized',
'description' => 'An entity wrapper based on the "Clean Entity Wrapper" wrapper with certain fixes and improvements.',
'class' => 'ServicesEntityResourceControllerC11n',
);
return $output;
}
声明控制器Class
在此之后,我声明了控制器 class:
ServicesEntityResourceControllerC11n extends ServicesEntityResourceControllerClean
覆盖 get_resource_reference() 方法
最后一步 (toque final) 是添加文件 URL。我决定处理 parent class 的输出并在 URL 中添加一个文件。实际数据由 ServicesEntityResourceController::get_resource_reference() 方法返回。所以,我就这样覆盖了它,就完成了。
protected function get_resource_reference($resource, $id) {
$output = parent::get_resource_reference($resource, $id);
switch ($resource):
case 'file':
$file = file_load($id);
if ($file)
$output['url'] = file_create_url($file->uri);
break;
case 'taxonomy_term':
// Do something for taxonomy terms
break;
endswitch;
return $output;
}
它解决了这个问题。但是,我并不认为它是最好的解决方案,但有一些解决方案比 none.
更好
备选方案
您可以更改 entity_file 资源并添加名为 download 的 targeted_action 或 嵌入 。在回调中,只需为文件 mime-type 发送 headers,然后使用 fpasthru()[=46= 呈现文件内容] 或 echo file_get_contents().
我正在使用 Drupal services 和 services_entity 模块来构建 Web 服务。问题是,当使用字段等将文件附加到实体时,服务端点将文件显示为资源引用:
array (
resource: file,
id: xx,
uri: /entity_file/xx.json
)
事实是,每次您希望显示一个文件时,您都必须发出 2 个或更多请求:
- 首先,获取文件实体URI
- 其次,通过id检索文件实体的详细信息,得到文件的直接url(可以嵌入到应用程序中或用作src ="xx" 用于 img 标签。
问题是,如何直接获取文件 URL 而无需进行额外请求。因此,首选响应是:
array (
resource: file,
id: xx,
uri: /entity_file/xx.json,
url: http://.../sites/.../files/foo/bar/b-reft.jpg
)
我找了几个小时但没有找到答案,所以我想我会分享我找到的解决方案。我相信它会帮助很多人(我也希望我可以分享我的模块,以支持 services_entity 模块的复杂索引查询参数)。
声明资源控制器
由于数据由 ServicesEntityResourceController 返回,我决定使用 hook_services_entity_resource_info() 声明我自己的资源控制器.
/**
* Implements hook_entity_resource_info()
*/
function c11n_services_entity_resource_info() {
$output = array();
$output['c11n'] = array (
'title' => 'Clean Entity Processor - Customized',
'description' => 'An entity wrapper based on the "Clean Entity Wrapper" wrapper with certain fixes and improvements.',
'class' => 'ServicesEntityResourceControllerC11n',
);
return $output;
}
声明控制器Class
在此之后,我声明了控制器 class:
ServicesEntityResourceControllerC11n extends ServicesEntityResourceControllerClean
覆盖 get_resource_reference() 方法
最后一步 (toque final) 是添加文件 URL。我决定处理 parent class 的输出并在 URL 中添加一个文件。实际数据由 ServicesEntityResourceController::get_resource_reference() 方法返回。所以,我就这样覆盖了它,就完成了。
protected function get_resource_reference($resource, $id) {
$output = parent::get_resource_reference($resource, $id);
switch ($resource):
case 'file':
$file = file_load($id);
if ($file)
$output['url'] = file_create_url($file->uri);
break;
case 'taxonomy_term':
// Do something for taxonomy terms
break;
endswitch;
return $output;
}
它解决了这个问题。但是,我并不认为它是最好的解决方案,但有一些解决方案比 none.
更好备选方案
您可以更改 entity_file 资源并添加名为 download 的 targeted_action 或 嵌入 。在回调中,只需为文件 mime-type 发送 headers,然后使用 fpasthru()[=46= 呈现文件内容] 或 echo file_get_contents().