mirror of
https://github.com/VueFileManager/vuefilemanager.git
synced 2026-04-06 02:33:48 +00:00
- added CzechRegisterSearchService
- oasis RouteServiceProvider.php - oasis admincontroller
This commit is contained in:
30
app/Http/Controllers/Oasis/AdminController.php
Normal file
30
app/Http/Controllers/Oasis/AdminController.php
Normal file
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Oasis;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Services\CzechRegisterSearchService;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class AdminController extends Controller
|
||||
{
|
||||
/**
|
||||
* Get company details from czech company register
|
||||
*
|
||||
* @return array|\Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\Routing\ResponseFactory|\Illuminate\Http\Response
|
||||
*/
|
||||
public function get_company_details()
|
||||
{
|
||||
$api = resolve(CzechRegisterSearchService::class);
|
||||
|
||||
$result = $api->findByIco(
|
||||
request()->get('ico')
|
||||
);
|
||||
|
||||
if (empty($result)) {
|
||||
return response('Not Found', 404);
|
||||
}
|
||||
|
||||
return response($result[0], 200);
|
||||
}
|
||||
}
|
||||
@@ -40,6 +40,8 @@ class RouteServiceProvider extends ServiceProvider
|
||||
*/
|
||||
public function map()
|
||||
{
|
||||
$this->mapOasisRoutes();
|
||||
|
||||
$this->mapApiRoutes();
|
||||
|
||||
$this->mapShareRoutes();
|
||||
@@ -100,6 +102,14 @@ class RouteServiceProvider extends ServiceProvider
|
||||
->group(base_path('routes/api.php'));
|
||||
}
|
||||
|
||||
protected function mapOasisRoutes()
|
||||
{
|
||||
Route::prefix('api/oasis')
|
||||
->middleware('api')
|
||||
->namespace($this->namespace)
|
||||
->group(base_path('routes/oasis.php'));
|
||||
}
|
||||
|
||||
protected function mapShareRoutes()
|
||||
{
|
||||
Route::prefix('api')
|
||||
|
||||
255
app/Services/CzechRegisterSearchService.php
Normal file
255
app/Services/CzechRegisterSearchService.php
Normal file
@@ -0,0 +1,255 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Parser pre vyhladavanie a vypis z obchodneho registra ČR
|
||||
* Lookup service for Czech commercial register (www.justice.cz)
|
||||
*
|
||||
* Version 1.0.0 (released 05.12.2019)
|
||||
* (c) 2019 lubosdz@gmail.com
|
||||
*
|
||||
* ------------------------------------------------------------------
|
||||
* Disclaimer / Prehlásenie:
|
||||
* Kód poskytnutý je bez záruky a môže kedykoľvek prestať fungovať.
|
||||
* Jeho funkčnosť je striktne naviazaná na generovanú štruktúru HTML elementov.
|
||||
* Autor nie je povinný udržiavať kód aktuálny a funkčný, ani neposkytuje ku nemu žiadnu podporu.
|
||||
* Autor nezodpovedá za nesprávne použitie kódu.
|
||||
* ------------------------------------------------------------------
|
||||
*
|
||||
* Usage example:
|
||||
* --------------
|
||||
* $connector = new ConnectorJusticeCz;
|
||||
* $out = $connector->findByNazev('auto');
|
||||
* $out = $connector->findByIco('44315945');
|
||||
* echo ''.print_r($out, 1).'';
|
||||
*/
|
||||
|
||||
namespace App\Services;
|
||||
|
||||
class CzechRegisterSearchService
|
||||
{
|
||||
/**
|
||||
* @var string Target server URL base
|
||||
*/
|
||||
const URL_SERVER = 'https://or.justice.cz/ias/ui/rejstrik-$firma';
|
||||
|
||||
/**
|
||||
* @var int Max. dlzka nazvu pre autocomplete options
|
||||
*/
|
||||
public $labelMaxChars = 30;
|
||||
|
||||
/**
|
||||
* Vyhlada zoznam subjektov podla presneho ICO, ciastkove ICO nie je povolene
|
||||
* @param string $ico 8-miestne cislo, e.g. 29243831 or 64612023
|
||||
*/
|
||||
public function findByIco($ico)
|
||||
{
|
||||
$response = [];
|
||||
$ico = preg_replace('/[^\d]/', '', $ico);
|
||||
|
||||
if (preg_match('/^\d{8}$/', $ico)) {
|
||||
$url = self::URL_SERVER . '?ico=' . $ico;
|
||||
$response = file_get_contents($url);
|
||||
$response = self::extractSubjects($response);
|
||||
}
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Vyhlada zoznam subjektov podla ciastkoveho nazvu
|
||||
* @param string $nazev , e.g. "pojisteni"
|
||||
*/
|
||||
public function findByNazev($nazev)
|
||||
{
|
||||
$response = [];
|
||||
|
||||
if ($nazev) {
|
||||
$nazev = trim($nazev);
|
||||
$url = self::URL_SERVER . '?nazev=' . urlencode($nazev);
|
||||
$response = file_get_contents($url);
|
||||
$response = self::extractSubjects($response);
|
||||
}
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Vyhlada zoznam subjektov podla presneho ICO, ciastkove ICO nie je povolene
|
||||
* @param string $ico 8-miestne cislo, e.g. 12345678
|
||||
*/
|
||||
public function getDetailByICO($ico)
|
||||
{
|
||||
$response = [];
|
||||
$ico = preg_replace('/[^\d]/', '', $ico);
|
||||
|
||||
if (preg_match('/^\d{8}$/', $ico)) {
|
||||
$url = self::URL_SERVER . '?ico=' . $ico;
|
||||
$response = file_get_contents($url);
|
||||
if ($response) {
|
||||
$response = self::extractSubjects($response);
|
||||
if (!empty($response[0])) {
|
||||
$response = $response[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return matched formatted for autocomplete dropdown list
|
||||
* @param string $term Searched matching string
|
||||
* @param int how many items to return, 1 - 50 (justice vrati max. 50 zaznamov)
|
||||
*/
|
||||
public function findForAutocomplete($term, $size = 15)
|
||||
{
|
||||
$out = [];
|
||||
$size = intval($size);
|
||||
|
||||
if ($term && $size > 0 && mb_strlen($term, 'utf-8') >= 3) {
|
||||
// Justice vrati vysledok pre min. 3 znaky
|
||||
if (preg_match('/^\d{8}$/', $term)) {
|
||||
$subjects = $this->findByIco($term);
|
||||
} else {
|
||||
$subjects = $this->findByNazev($term);
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($subjects) && is_array($subjects)) {
|
||||
|
||||
$subjects = array_slice($subjects, 0, $size); // return first $size matches
|
||||
|
||||
foreach ($subjects as &$subject) {
|
||||
$subject['shortname'] = $subject['name'];
|
||||
// cut off too long names
|
||||
if (mb_strlen($subject['shortname'], 'utf-8') > $this->labelMaxChars) {
|
||||
$subject['shortname'] = mb_substr($subject['shortname'], 0, $this->labelMaxChars - 3, 'utf-8') . ' ..';
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($subjects as $subject) {
|
||||
if (!empty($subject['ico'])) {
|
||||
$out[] = [
|
||||
'value' => $subject['ico'],
|
||||
'label' => "{$subject['shortname']} (IČO: {$subject['ico']})",
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $out;
|
||||
}
|
||||
|
||||
/**
|
||||
* Vrati zoznam najdenych subjektov s udajmi
|
||||
* @param string $html HTML response zo servera justice.cz
|
||||
* @return [name, ico, city, addr_streetnr, addr_city, addr_zip, ..]
|
||||
*/
|
||||
protected static function extractSubjects($html)
|
||||
{
|
||||
// ensure valid XHTML markup
|
||||
if (!extension_loaded('tidy')) {
|
||||
throw new \Exception('Missing extension [tidy].');
|
||||
}
|
||||
|
||||
$tidy = new \tidy();
|
||||
$html = $tidy->repairString($html, array(
|
||||
'output-xhtml' => true,
|
||||
'show-body-only' => true,
|
||||
), 'utf8');
|
||||
|
||||
// purify whitespaces - vkladaju \n alebo
|
||||
$html = strtr($html, [
|
||||
' ' => ' ',
|
||||
]);
|
||||
$html = preg_replace('/\s+/', ' ', $html);
|
||||
|
||||
// load XHTML into DOM document
|
||||
$xml = new \DOMDocument('1.0', 'utf-8');
|
||||
$xml->loadXML($html);
|
||||
$xpath = new \DOMXPath($xml);
|
||||
$rows = $xpath->query('//table[@class="result-details"]/tbody');
|
||||
|
||||
$out = [];
|
||||
|
||||
if ($rows->length) {
|
||||
|
||||
foreach ($rows as $row) {
|
||||
|
||||
// Nazev
|
||||
$nodeList = $xpath->query("./tr[1]/td[1]", $row);
|
||||
if (!$nodeList->length) {
|
||||
continue; // nazev je povinny
|
||||
}
|
||||
$name = $nodeList->item(0)->nodeValue;
|
||||
$name = preg_replace('/\s+/', ' ', $name); // viacnasobne inside spaces
|
||||
|
||||
// ICO
|
||||
$nodeList = $xpath->query("./tr[1]/td[2]", $row);
|
||||
$ico = $nodeList->length ? $nodeList->item(0)->nodeValue : '';
|
||||
|
||||
// adresa - neda sa spolahnut na poradie prvkov :-(
|
||||
$city = '';
|
||||
$nodeList = $xpath->query("./tr[3]/td[1]", $row);
|
||||
if ($nodeList->length) {
|
||||
|
||||
$addr = trim($nodeList->item(0)->nodeValue);
|
||||
|
||||
if (preg_match('/,\s*(\d{3} ?\d{2})\s+(.+)$/', $addr, $match)) {
|
||||
// Příborská 597, Místek, 738 01 Frýdek-Místek - nazov obce za PSC, prva je ulice a cislo
|
||||
$city = $addr_city = $match[2];
|
||||
list($addr_streetnr) = explode(',', $addr);
|
||||
$addr_zip = $match[1];
|
||||
} elseif (preg_match('/,\s*PSČ\s+(\d{3} ?\d{2})$/', $addr, $match)) {
|
||||
// Řevnice, ČSLA 118, okres Praha-západ, PSČ 25230 - PSC na konci, obec je prva, ulice a cislo druha
|
||||
list($city, $addr_streetnr) = explode(',', $addr);
|
||||
$addr_city = $city;
|
||||
$addr_zip = $match[1];
|
||||
} elseif (!preg_match('/\d{3} ?\d{2}/', $addr, $match)) {
|
||||
// Ústí nad Labem, Masarykova 74 - bez PSC - obec, ulice a cislo
|
||||
$addr_streetnr = $addr_zip = '';
|
||||
if (false !== strpos($addr, ',')) {
|
||||
list($city, $addr_streetnr) = explode(',', $addr);
|
||||
} else {
|
||||
list($city) = explode(',', $addr);
|
||||
}
|
||||
$addr_city = $city;
|
||||
}
|
||||
|
||||
// "Praha 10 - Dolní Měcholupy" -> Praha 10, pozn: Frydek-Mistek nema medzeru okolo pomlcky
|
||||
// whoops, avsak ani Ostrana-Hontice a dalsie .. :-( Pre city potrebujeme kratky nazov do 10-15 pismen
|
||||
list($city) = explode('-', $city);
|
||||
// Praha 5 -> Praha
|
||||
$city = preg_replace('/\d/', '', $city);
|
||||
// viacnasobne spaces
|
||||
$city = preg_replace('/\s+/', ' ', $city);
|
||||
}
|
||||
|
||||
$out[] = [
|
||||
'name' => self::trimQuotes($name),
|
||||
'ico' => preg_replace('/[^\d]/', '', $ico),
|
||||
'city' => self::trimQuotes($city),
|
||||
// pre polia s adresou konzistentne so smartform naseptavacem
|
||||
'addr_city' => self::trimQuotes($addr_city),
|
||||
'addr_zip' => preg_replace('/[^\d]/', '', $addr_zip),
|
||||
'addr_streetnr' => self::trimQuotes($addr_streetnr),
|
||||
// len pre kontrolu - plna povodna adresa
|
||||
'addr_full' => self::trimQuotes($addr),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
return $out;
|
||||
}
|
||||
|
||||
/**
|
||||
* Vyhodi quotes z textu, aby neposkodilo HTML atributy
|
||||
* @param string $s
|
||||
*/
|
||||
protected static function trimQuotes($s)
|
||||
{
|
||||
return trim(strtr($s, ['"' => '', "'" => '']));
|
||||
}
|
||||
|
||||
}
|
||||
8
routes/oasis.php
Normal file
8
routes/oasis.php
Normal file
@@ -0,0 +1,8 @@
|
||||
<?php
|
||||
|
||||
use App\Http\Controllers\Oasis\AdminController;
|
||||
|
||||
Route::group(['prefix' => 'admin'], function () {
|
||||
|
||||
Route::get('/company-details', [AdminController::class, 'get_company_details']);
|
||||
});
|
||||
49
tests/Feature/Oasis/OasisAdminTest.php
Normal file
49
tests/Feature/Oasis/OasisAdminTest.php
Normal file
@@ -0,0 +1,49 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Feature\Oasis;
|
||||
|
||||
use Illuminate\Foundation\Testing\DatabaseMigrations;
|
||||
use Illuminate\Support\Facades\Http;
|
||||
use Tests\TestCase;
|
||||
|
||||
class OasisAdminTest extends TestCase
|
||||
{
|
||||
use DatabaseMigrations;
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function it_get_register_by_ico()
|
||||
{
|
||||
$response = [
|
||||
"name" => "GDPR Cloud Solution, s.r.o.",
|
||||
"ico" => "08995281",
|
||||
"city" => "Praha",
|
||||
"addr_city" => "Praha 5",
|
||||
"addr_zip" => "15900",
|
||||
"addr_streetnr" => "Zbraslavská 12/11",
|
||||
"addr_full" => "Zbraslavská 12/11, Malá Chuchle, 159 00 Praha 5",
|
||||
];
|
||||
|
||||
Http::fake([
|
||||
'https://or.justice.cz/ias/ui/rejstrik-08995281' => Http::response($response, 200),
|
||||
]);
|
||||
|
||||
$this->getJson('/api/oasis/admin/company-details?ico=08995281')
|
||||
->assertStatus(200)
|
||||
->assertExactJson($response);
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function it_try_to_get_register_by_ico_with_not_found_result()
|
||||
{
|
||||
Http::fake([
|
||||
'https://or.justice.cz/ias/ui/rejstrik-0899528199' => Http::response([], 200),
|
||||
]);
|
||||
|
||||
$this->getJson('/api/oasis/admin/company-details?ico=0899528199')
|
||||
->assertNotFound();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user