Algolia - автозаполнение мест с использованием клиента php api

Я играл с библиотекой Algolia autocomplete places.js. Когда вы используете библиотеку, вы получаете список предложений, например.

{
  "query": "pari",
  "suggestion": {
     "name": "Paris",
     "administrative": "Île-de-France",
     "country": "France",
     "countryCode": "fr",
     "type": "city",
     "latlng": {
     "lat": 48.8546,
     "lng": 2.34771
   },
  "postcode": "75000",
  "highlight": {
      "name": "<em>Pari</em>s",
      "administrative": "Île-de-France",
      "country": "France"
   },
   "value": "Paris, Île-de-France, France"
 }
}

Мне нужно использовать php-клиент и вернуть список предложений для моих собственных приложений API, например.

$places = \AlgoliaSearch\Client::initPlaces();

$result = $places->search($term, [

        'type' => ['city', 'country', 'address'],
        'language' => 'en',
        'aroundLatLngViaIP' => false,

]);

dd($result);

Однако, когда вы используете php-клиент (обратите внимание, что в этом случае я использую laravel scout), вы не получаете список предложений, т.е. нет свойства value (полное отображаемое имя найденного места) в ответ, который вы можете вернуть вернуться к конечному пользователю - вместо этого вы получите следующий ответ?

 {
   "hits": [{
   "objectID": "145746683_7444",
      "locale_names": {
         "default": ["Paris"],
    },
   "city": {
       "default": ["Paris"],
    },
   "county": {
       "default": ["Paris"],
   },
   "administrative": ["Île-de-France"],
   "country": {
       "default": "France",
   },
   "country_code": "fr",
   "postcode": ["75000"],
   "population": 2243833,
   "_geoloc": {
       "lat": 48.8564,
       "lng": 2.3521
   },
   "_highlightResult": {
       "locale_names": {
          "default": [{
              "value": "<em>Paris</em>",
              "fullyHighlighted": true,
              "matchedWords": ["paris"],
              "matchLevel": "full"
          }]
     },

   }
 }],
 "nbHits": 1,
 "query": "Paris"
}

person adam78    schedule 15.01.2019    source источник


Ответы (1)


Если вы посмотрите на JavaScript-библиотеку Algolia Places, это данные, с которыми они имеют дело, прежде чем они будут переданы автозаполнению:

    const name = hit.locale_names[0];
    const country = hit.country;
    const administrative =
      hit.administrative && hit.administrative[0] !== name
        ? hit.administrative[0]
        : undefined;
    const city = hit.city && hit.city[0] !== name ? hit.city[0] : undefined;
    const suburb =
      hit.suburb && hit.suburb[0] !== name ? hit.suburb[0] : undefined;

    const county =
      hit.county && hit.county[0] !== name ? hit.county[0] : undefined;

    const { postcode, highlightedPostcode } =
      hit.postcode && hit.postcode.length
        ? getBestPostcode(hit.postcode, hit._highlightResult.postcode)
        : { postcode: undefined, highlightedPostcode: undefined };

    const highlight = {
      name: getBestHighlightedForm(hit._highlightResult.locale_names),
      city: city
        ? getBestHighlightedForm(hit._highlightResult.city)
        : undefined,
      administrative: administrative
        ? getBestHighlightedForm(hit._highlightResult.administrative)
        : undefined,
      country: country ? hit._highlightResult.country.value : undefined,
      suburb: suburb
        ? getBestHighlightedForm(hit._highlightResult.suburb)
        : undefined,
      county: county
        ? getBestHighlightedForm(hit._highlightResult.county)
        : undefined,
      postcode: highlightedPostcode,
    };

    const suggestion = {
      name,
      administrative,
      county,
      city,
      suburb,
      country,
      countryCode: findCountryCode(hit._tags),
      type: findType(hit._tags),
      latlng: {
        lat: hit._geoloc.lat,
        lng: hit._geoloc.lng,
      },
      postcode,
      postcodes: hit.postcode && hit.postcode.length ? hit.postcode : undefined,
    };

    // this is the value to put inside the <input value=
    const value = formatInputValue(suggestion);

Вы должны найти все, что вам нужно, в этом коде, а точнее полное отображаемое имя найденного места, оно построено из этого (где suggestion из кода выше — это контекст рендеринга для кода ниже):

 const out = `${name}${type !== 'country' && country !== undefined ? ',' : ''}
 ${city ? `${city},` : ''}
 ${administrative ? `${administrative},` : ''}
 ${country ? country : ''}`
    .replace(/\s*\n\s*/g, ' ')
    .trim();
  return out;

(находится в formatInputValue.js file`)

person Olivier Lance    schedule 18.01.2019
comment
Это не отвечает на вопрос и лучше всего указано в разделе комментариев. Переменные, используемые в файле formatInputValue.js, не используют ту же структуру массива, которую возвращает клиент PHP. - person Angel S. Moreno; 26.08.2019
comment
@AngelS.Moreno, это действительно отвечает на вопрос, если вы потратите время, чтобы сначала просмотреть код, на который я ссылаюсь. Затем вы поймете, что данные, обрабатываемые в formatInputValue.js, получены именно из того, что OP опубликовал в своем вопросе. Я обновил свой ответ, включив в него полный код, чтобы он стал более автономным. - person Olivier Lance; 26.08.2019
comment
Моя проблема заключается в том, что вопрос опубликован на PHP, а ваше решение - на JS. Я попытаюсь преобразовать код в PHP и посмотреть, работает ли он. - person Angel S. Moreno; 28.08.2019
comment
OP цитирует больше кода JSON, чем PHP, и, как выясняется, соответствующие фрагменты кода из библиотек Algolia, которые отвечают на вопрос, находятся в JS. Проблема и вопрос не специфичны для PHP, но как мне манипулировать данными, возвращаемыми клиентом, и это именно то, что я показываю :) - person Olivier Lance; 05.09.2019