YetiForceCompany/YetiForceCRM

View on GitHub
app/Map/Address/OpenCageGeocoder.php

Summary

Maintainability
A
3 hrs
Test Coverage
F
0%
<?php

/**
 * Address finder OpenCageGeocoder file.
 *
 * @see       https://geocoder.opencagedata.com/api Documentation  of OpenCage Geocoder API
 *
 * @package App
 *
 * @copyright YetiForce S.A.
 * @license   YetiForce Public License 6.5 (licenses/LicenseEN.txt or yetiforce.com)
 * @author    Mariusz Krzaczkowski <m.krzaczkowski@yetiforce.com>
 * @author    Radosław Skrzypczak <r.skrzypczak@yetiforce.com>
 */

namespace App\Map\Address;

/**
 * Address finder OpenCageGeocoder class.
 */
class OpenCageGeocoder extends Base
{
    /** {@inheritdoc} */
    public $customFields = [
        'country_codes' => [
            'uitype' => 1,
            'label' => 'LBL_COUNTRY_CODES',
            'purifyType' => \App\Purifier::TEXT,
            'maximumlength' => '100',
            'typeofdata' => 'V~O',
            'tooltip' => 'LBL_COUNTRY_CODES_PLACEHOLDER',
            'link' => [
                'title' => 'LBL_COUNTRY_CODES_INFO',
                'url' => 'https://wikipedia.org/wiki/List_of_ISO_3166_country_codes',
            ]
        ],
        'key' => [
            'validator' => [['name' => 'AlphaNumeric']],
            'uitype' => 1,
            'label' => 'LBL_KEY',
            'purifyType' => \App\Purifier::ALNUM,
            'maximumlength' => '200',
            'typeofdata' => 'V~M',
            'tooltip' => 'LBL_KEY_PLACEHOLDER',
        ],
    ];

    /** {@inheritdoc} */
    public $docUrl = 'https://opencagedata.com/api/';
    /**
     * API Address to retrieve data.
     *
     * @var string
     */
    protected static $url = 'https://api.opencagedata.com/geocode/v1/';

    /** {@inheritdoc} */
    public function find($value)
    {
        if (empty($value) || !\App\RequestUtil::isNetConnection()) {
            return [];
        }
        $config = \App\Map\Address::getConfig();
        $urlAddress = static::$url . 'json?q=' . $value . '&pretty=1';
        $urlAddress .= '&language=' . \App\Language::getLanguage();
        $urlAddress .= '&limit=' . $config['global']['result_num'];
        $urlAddress .= '&key=' . $config['OpenCageGeocoder']['key'];
        if (!empty($this->config['country_codes'])) {
            $urlAddress .= '&countrycode=' . $this->config['country_codes'];
        }
        try {
            \App\Log::beginProfile("GET|OpenCageGeocoder::find|{$urlAddress}", __NAMESPACE__);
            $response = (new \GuzzleHttp\Client(\App\RequestHttp::getOptions()))->request('GET', $urlAddress);
            \App\Log::endProfile("GET|OpenCageGeocoder::find|{$urlAddress}", __NAMESPACE__);
            if (200 !== $response->getStatusCode()) {
                \App\Log::warning('Error: ' . $urlAddress . ' | ' . $response->getStatusCode() . ' ' . $response->getReasonPhrase(), __CLASS__);
                return false;
            }
            $body = \App\Json::decode($response->getBody());
            $rows = [];
            if ($body['total_results']) {
                $mainMapping = \App\Config::component('AddressFinder', 'remappingOpenCage');
                if (!\is_callable($mainMapping)) {
                    $mainMapping = [$this, 'parseRow'];
                }
                $countryMapping = \App\Config::component('AddressFinder', 'remappingOpenCageForCountry');
                foreach ($body['results'] as $row) {
                    $mappingFunction = $mainMapping;
                    if (isset($row['components']['country'], $countryMapping[$row['components']['country']])) {
                        $mappingFunction = $countryMapping[$row['components']['country']];
                    }
                    $rows[] = [
                        'label' => $row['formatted'],
                        'address' => \call_user_func_array($mappingFunction, [$row]),
                        'coordinates' => ['lat' => $row['geometry']['lat'], 'lon' => $row['geometry']['lng']],
                        'countryCode' => strtolower($row['components']['ISO_3166-1_alpha-2'] ?? ''),
                    ];
                }
            }
        } catch (\Throwable $e) {
            \App\Log::error('Error - ' . $e->getMessage(), __CLASS__);
            return false;
        }
        return $rows;
    }

    /**
     * Main function to parse information about address.
     *
     * @param array $row
     *
     * @return array
     */
    private function parseRow(array $row)
    {
        return [
            'addresslevel1' => [$row['components']['country'] ?? '', $row['components']['ISO_3166-1_alpha-2'] ?? ''],
            'addresslevel2' => $row['components']['state'] ?? '',
            'addresslevel3' => $row['components']['state_district'] ?? '',
            'addresslevel4' => $row['components']['county'] ?? '',
            'addresslevel5' => $row['components']['city'] ?? $row['components']['town'] ?? $row['components']['village'] ?? '',
            'addresslevel6' => $row['components']['suburb'] ?? $row['components']['neighbourhood'] ?? $row['components']['city_district'] ?? '',
            'addresslevel7' => $row['components']['postcode'] ?? '',
            'addresslevel8' => $row['components']['road'] ?? '',
            'buildingnumber' => $row['components']['house_number'] ?? '',
            'localnumber' => $row['components']['local_number'] ?? '',
            'company_name_' => $row['components']['office'] ?? '',
        ];
    }
}