These are chat archives for dru-io/Drupal

19th
Jul 2017
Evgeny
@tensor146
Jul 19 2017 05:34

Всем привет! Кто-то пользуется Drupal::httpClient (D8)? Столкнулся с проблемой, шлю запрос получаю стрим, пытаюсь читать из него данные - беру от него боди - пустой. При этом волшебный костыль

  $body = $response->getBody();
  $body->rewind();
  $data = '';
  while (!$body->eof()) {
    $data .= $body->read(1024);
  }

ответ возвращает. Есть подозрение, что я неправильно его готовлю, но всё-таки, непонятно, почему $body->rewind()->__toString() возвращает пустоту, а чтение из стрима руками возвращает необходимые мне данные?

KarmaBot
@KarmaBot
Jul 19 2017 05:34
О! @tensor146! Сто лет не виделись!) Как жизнь молодецкая? Рассказывай :)
bumble
@awd-studio
Jul 19 2017 06:01

@tensor146
Попробуй к строке привести:

$body = (string) $response->getBody();

getBody возвращает стрим

Evgeny
@tensor146
Jul 19 2017 07:01
@awd-studio пробовал же: $body->rewind()->__toString() - пустая строка
Почему-то данные из стрима получается "вытянуть" только если руками читать, побайтово.
bumble
@awd-studio
Jul 19 2017 07:03
у меня получилось таким образом читать:
$body = (string) $response->getBody();
Evgeny
@tensor146
Jul 19 2017 07:03
В других ситуациях это у меня тоже работает.
А в запросе конкретно на определённый урл - нет.
У меня была идея, что там проблема с тем, что nginx возвращает данные почанково (сервис, куда летит запрос, тоже мой), но отключение этой настройки не особо помогло.
Пробовал вот такой вот код:
      $body = $response->getBody();
      $body->rewind();
      $data = '';
      while (!$body->eof()) {
        $data .= $body->read(1024);
      }
      $body->rewind();
      $data2 = (string) $body;
$data содержит данные, $data2 - пустой.
Не могу разобраться, почему так.
bumble
@awd-studio
Jul 19 2017 07:09
попробуй просто так, без rewind'а
Evgeny
@tensor146
Jul 19 2017 07:31
Хм, сработало.
Можешь объяснить, пожалуйста, как так?
И почему он возвращает просто Response вместо JsonResponse?
bumble
@awd-studio
Jul 19 2017 07:59

давай пробовать разбираться.
вот тут указано что возвращается поток

для получения JSON'а нужно проверить в каком формате отдает API'ха, возможно там собака зарыта

кстати, так тоже должно работать:
$body = $response->getBody()->__toString();
Evgeny
@tensor146
Jul 19 2017 08:06
Вот я так делал =/
Более того, локально у меня возвращается адекватный JsonResponse, откуда ->getBody() тоже всё возвращает.
А на дев-инстансе - лажа =/
bumble
@awd-studio
Jul 19 2017 08:07
сорри, привод к строке не убрал
Evgeny
@tensor146
Jul 19 2017 08:08
Хотя тут докер, по идее nginx'ы и прочее должно одинаково работать.
bumble
@awd-studio
Jul 19 2017 08:09
а апиха друпальная?
Evgeny
@tensor146
Jul 19 2017 08:10
Нет, там практически голый php. Но я на уровне сервера глянул, всё, что надо - возвращается.
Спасибо, @awd-studio
KarmaBot
@KarmaBot
Jul 19 2017 08:14
Спасибо (+1) для @awd-studio принято! Текущая карма +183.
bumble
@awd-studio
Jul 19 2017 08:15
хедер попробуй передать
['headers' => ['Accept' => 'application/json']]
Evgeny
@tensor146
Jul 19 2017 08:15
Уже
:)
bumble
@awd-studio
Jul 19 2017 08:16
не?
Evgeny
@tensor146
Jul 19 2017 08:16
Сейчас проверяю, оно деплоилось.
[response class] => GuzzleHttp\Psr7\Response
Неа..
bumble
@awd-studio
Jul 19 2017 08:18
чертовщина...
Evgeny
@tensor146
Jul 19 2017 08:19
Ага, то же чувство. Уже думал голым курлом фигачить, для надёжности. А то сломается в послединй момент по неизвестной причине..
bumble
@awd-studio
Jul 19 2017 08:19
там не нужно в запросе передавать никаких параметров чтоб в JSON'е отдавал?
Evgeny
@tensor146
Jul 19 2017 08:19
Можно ему отдельным параметром жестко указать, что-то вроде decode_to => json.
bumble
@awd-studio
Jul 19 2017 08:20
попробуй укажи. просто, если текстом отдает - значит работает.
Evgeny
@tensor146
Jul 19 2017 08:20
Но по умолчанию автодетект должен работать (видимо, на Content-Type смотрит).
bumble
@awd-studio
Jul 19 2017 08:22
так а приходит JSON?
Evgeny
@tensor146
Jul 19 2017 08:22
Да
bumble
@awd-studio
Jul 19 2017 08:23
погодь, так а в чем беда использовать Response?
просто декодь:
$body = json_decode((string) $response->getBody());
Evgeny
@tensor146
Jul 19 2017 08:24
Да ни в чём, на самом деле, я так и делаю сейчас. Просто по нему можно детектить, что пришло, плюс, он сам по себе декодит, с какими-то особенными параметрами.
Вроде как правильнее его использовать.
Соль в том, что (string) $response->getBody() не работал вчера. А сегодня звёзды поменялись - и оно заработало.
bumble
@awd-studio
Jul 19 2017 08:31
вот пример для получения JsonResponse
Evgeny
@tensor146
Jul 19 2017 08:32
Чёт лажа какая-то. Сам \Drupal::httpClient()->{method} должен возвращать такой класс (по заголовкам, конечно).
Аааа.
Ты не тот JsonResponse смотришь.
Их там 2.
Один - это Response от Друпала, такие отдаются в контроллере.
Другие - приходят из guzzle, после заврешения запроса из Друпала.
bumble
@awd-studio
Jul 19 2017 08:43
Symfony\Component\HttpFoundation\JsonResponse этот же?
Evgeny
@tensor146
Jul 19 2017 08:43
Zend\Diactoros\Response\JsonResponse
bumble
@awd-studio
Jul 19 2017 08:56
я на сколько понял, этот Zend\Diactoros\Response\JsonResponse для преобразования в JSON используется
например, если с нашей стороны АПИха, и нужно отдавать в JSON'е
она там автоматом ставит все хедеры и энкодит "по-правильному"
и в текущем случае его применять незачем
Evgeny
@tensor146
Jul 19 2017 08:57
Как бы да, но локально у меня \Drupal::httpClient()->{method}именно его и возвращает.
Сам по себе.
Когда получает json.
Собственно, если с нашей стороны АПИха, то нужен Symfony\Component\HttpFoundation\JsonResponse.
bumble
@awd-studio
Jul 19 2017 08:59
блин, не могу сообразить как он туда может попасть... :(
Anatoly
@politsin
Jul 19 2017 13:02

Колеги, здравствуйте!
Есть Иванов Иван и Петров Пётр
Мы их принимаем на работу (тип материала "приём на работу"):
1 января приняли обоих на должность кладовщик с зп 10 тыс (2 записи приём на работу)
1 апреля Иванова Ивана перевели на должность старший кладовщик с зп 20 тыс (новая запись приём на работу)
1 июня Иванова Ивана перевели на должность начальник склада с зп 30 тыс (новая запись приём на работу)

Итого имеем 4 записи "приём на работу"
Дальше нам нужно выбрать ситуацию на 1 марта, 1 мая и 1 августа
В каждой выборке мы оджны получить 2 записи (по штуке на человека) с актуальной информацией на эту дату:
1 марта: Иванов - кладовщик, Петров - кладовщик
1 мая: Иванов - старший кладовщик, Петров - кладовщик
1 августа: Иванов - начальник склада, Петров - кладовщик

Паттерн достаточно популярный.
Можно ли его реализовать стандартным вьювсом или есть для этого какие-то модули?
Даже не представяю как такое лучше гуглить.

KarmaBot
@KarmaBot
Jul 19 2017 13:02
Будь как дома, @politsin, я ни в чем не откажу. Много мануалов, коль желаешь, покажу :)
Evgeny
@tensor146
Jul 19 2017 13:10
@politsin а какая проблема? У каждой записи должно быть свойство "created_at" и ссылка на профиль сотрудника. Поставь date фильтр и пиши туда значения "<= 1 марта", поставь сортировку по "created_at" и группируй по ссылке на сотрудника.
Anatoly
@politsin
Jul 19 2017 13:15
@tensor146 стандартный вьювс вполне справится с такой проблемой?
Evgeny
@tensor146
Jul 19 2017 13:16
Справится.