Drupal Services - прямой URL-адрес файла вместо ссылки на файловый ресурс

Я использую модуль Drupal services и services_entity для создания веб-сервиса. Проблема в том, что когда файл присоединяется к объекту с использованием полей и т. Д., Конечные точки службы отображают файл в качестве ссылки на ресурс в виде:

array (
    resource: file,
    id: xx,
    uri: /entity_file/xx.json
)

Дело в том, что каждый раз, когда вы хотите отобразить файл, вам нужно будет сделать 2 или более запросов:

  • Во-первых, получить файл URI объекта
  • Во-вторых, получить сведения о сущности файла по идентификатору, чтобы получить прямой 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).

1 ответ

Решение

Объявите контроллер ресурса

Поскольку данные возвращаются 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;

}

Объявить класс контроллера

После этого я объявил класс контроллера:

ServicesEntityResourceControllerC11n extends ServicesEntityResourceControllerClean

Переопределить метод get_resource_reference()

Последним штрихом (toque final) будет добавление URL файла. Я решил поработать с выводом родительского класса и добавить 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;

}

Это решает проблему. Однако я не утверждаю, что это лучшее решение, но иметь какое-то решение лучше, чем его не иметь.

Альтернативное решение

Вы можете изменить ресурс entity_file и добавить целевое действие с именем download или embed. В обратном вызове просто отправьте заголовки для файла mime-type, а затем отобразите содержимое файла с помощью fpasthru() или echo file_get_contents ().

Другие вопросы по тегам