Commit 56ec09fe by Yuriy Frasinyuk

Initial commit

parents
root = true
[*]
charset = utf-8
end_of_line = lf
insert_final_newline = true
indent_style = space
indent_size = 4
trim_trailing_whitespace = true
[*.md]
trim_trailing_whitespace = false
[*.{yml,yaml}]
indent_size = 2
APP_NAME=Cities
APP_ENV=local
APP_KEY=
APP_DEBUG=true
APP_URL=http://localhost
# https://console.cloud.google.com/apis/credentials
GOOGLE_MAPS_GEOCODING_API_KEY=AIzaSyDfV2dRX3tcmoxtCuJ8FhvrGJzrMKrBxpE
LOG_CHANNEL=stack
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=database
DB_USERNAME=username
DB_PASSWORD=password
BROADCAST_DRIVER=log
CACHE_DRIVER=file
QUEUE_CONNECTION=sync
SESSION_DRIVER=cookie
SESSION_LIFETIME=120
REDIS_HOST=127.0.0.1
REDIS_PASSWORD=null
REDIS_PORT=6379
* text=auto
*.css linguist-vendored
*.scss linguist-vendored
*.js linguist-vendored
CHANGELOG.md export-ignore
/node_modules
/public/hot
/public/storage
/storage/*.key
/vendor
.env
.env.backup
.phpunit.result.cache
Homestead.json
Homestead.yaml
npm-debug.log
yarn-error.log
package-lock.json
composer.lock
# Default ignored files
/workspace.xml
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="JavaScriptSettings">
<option name="languageLevel" value="ES6" />
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/test-parser.iml" filepath="$PROJECT_DIR$/.idea/test-parser.iml" />
</modules>
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="PhpIncludePathManager">
<include_path>
<path value="$PROJECT_DIR$/vendor/symfony/finder" />
<path value="$PROJECT_DIR$/vendor/symfony/process" />
<path value="$PROJECT_DIR$/vendor/symfony/debug" />
<path value="$PROJECT_DIR$/vendor/symfony/polyfill-iconv" />
<path value="$PROJECT_DIR$/vendor/symfony/service-contracts" />
<path value="$PROJECT_DIR$/vendor/symfony/mime" />
<path value="$PROJECT_DIR$/vendor/symfony/browser-kit" />
<path value="$PROJECT_DIR$/vendor/symfony/polyfill-php72" />
<path value="$PROJECT_DIR$/vendor/symfony/polyfill-php73" />
<path value="$PROJECT_DIR$/vendor/symfony/error-handler" />
<path value="$PROJECT_DIR$/vendor/symfony/translation-contracts" />
<path value="$PROJECT_DIR$/vendor/symfony/filesystem" />
<path value="$PROJECT_DIR$/vendor/doctrine/dbal" />
<path value="$PROJECT_DIR$/vendor/doctrine/event-manager" />
<path value="$PROJECT_DIR$/vendor/doctrine/cache" />
<path value="$PROJECT_DIR$/vendor/doctrine/lexer" />
<path value="$PROJECT_DIR$/vendor/doctrine/inflector" />
<path value="$PROJECT_DIR$/vendor/fideloper/proxy" />
<path value="$PROJECT_DIR$/vendor/maennchen/zipstream-php" />
<path value="$PROJECT_DIR$/vendor/paragonie/random_compat" />
<path value="$PROJECT_DIR$/vendor/phpoption/phpoption" />
<path value="$PROJECT_DIR$/vendor/ralouphie/getallheaders" />
<path value="$PROJECT_DIR$/vendor/guzzlehttp/guzzle" />
<path value="$PROJECT_DIR$/vendor/guzzlehttp/promises" />
<path value="$PROJECT_DIR$/vendor/guzzlehttp/psr7" />
<path value="$PROJECT_DIR$/vendor/swiftmailer/swiftmailer" />
<path value="$PROJECT_DIR$/vendor/intervention/image" />
<path value="$PROJECT_DIR$/vendor/tijsverkoyen/css-to-inline-styles" />
<path value="$PROJECT_DIR$/vendor/dragonmantank/cron-expression" />
<path value="$PROJECT_DIR$/vendor/jakub-onderka/php-console-highlighter" />
<path value="$PROJECT_DIR$/vendor/jakub-onderka/php-console-color" />
<path value="$PROJECT_DIR$/vendor/justinrainbow/json-schema" />
<path value="$PROJECT_DIR$/vendor/koenhoeijmakers/laravel-translatable" />
<path value="$PROJECT_DIR$/vendor/composer" />
<path value="$PROJECT_DIR$/vendor/psr/container" />
<path value="$PROJECT_DIR$/vendor/psr/simple-cache" />
<path value="$PROJECT_DIR$/vendor/psr/log" />
<path value="$PROJECT_DIR$/vendor/psr/http-message" />
<path value="$PROJECT_DIR$/vendor/psy/psysh" />
<path value="$PROJECT_DIR$/vendor/opis/closure" />
<path value="$PROJECT_DIR$/vendor/seld/phar-utils" />
<path value="$PROJECT_DIR$/vendor/seld/jsonlint" />
<path value="$PROJECT_DIR$/vendor/nikic/php-parser" />
<path value="$PROJECT_DIR$/vendor/erusev/parsedown" />
<path value="$PROJECT_DIR$/vendor/fabpot/goutte" />
<path value="$PROJECT_DIR$/vendor/league/flysystem" />
<path value="$PROJECT_DIR$/vendor/league/glide" />
<path value="$PROJECT_DIR$/vendor/nesbot/carbon" />
<path value="$PROJECT_DIR$/vendor/ramsey/uuid" />
<path value="$PROJECT_DIR$/vendor/spatie/temporary-directory" />
<path value="$PROJECT_DIR$/vendor/spatie/image-optimizer" />
<path value="$PROJECT_DIR$/vendor/spatie/geocoder" />
<path value="$PROJECT_DIR$/vendor/spatie/laravel-medialibrary" />
<path value="$PROJECT_DIR$/vendor/spatie/image" />
<path value="$PROJECT_DIR$/vendor/spatie/pdf-to-image" />
<path value="$PROJECT_DIR$/vendor/vlucas/phpdotenv" />
<path value="$PROJECT_DIR$/vendor/dnoegel/php-xdg-base-dir" />
<path value="$PROJECT_DIR$/vendor/egulias/email-validator" />
<path value="$PROJECT_DIR$/vendor/laravel/tinker" />
<path value="$PROJECT_DIR$/vendor/laravel/framework" />
<path value="$PROJECT_DIR$/vendor/mcamara/laravel-localization" />
<path value="$PROJECT_DIR$/vendor/monolog/monolog" />
<path value="$PROJECT_DIR$/vendor/myclabs/php-enum" />
<path value="$PROJECT_DIR$/vendor/symfony/event-dispatcher-contracts" />
<path value="$PROJECT_DIR$/vendor/symfony/css-selector" />
<path value="$PROJECT_DIR$/vendor/symfony/console" />
<path value="$PROJECT_DIR$/vendor/symfony/var-dumper" />
<path value="$PROJECT_DIR$/vendor/symfony/event-dispatcher" />
<path value="$PROJECT_DIR$/vendor/symfony/polyfill-ctype" />
<path value="$PROJECT_DIR$/vendor/symfony/translation" />
<path value="$PROJECT_DIR$/vendor/symfony/http-client-contracts" />
<path value="$PROJECT_DIR$/vendor/symfony/polyfill-mbstring" />
<path value="$PROJECT_DIR$/vendor/symfony/dom-crawler" />
<path value="$PROJECT_DIR$/vendor/symfony/http-kernel" />
<path value="$PROJECT_DIR$/vendor/symfony/http-client" />
<path value="$PROJECT_DIR$/vendor/symfony/http-foundation" />
<path value="$PROJECT_DIR$/vendor/symfony/routing" />
<path value="$PROJECT_DIR$/vendor/symfony/polyfill-intl-idn" />
<path value="$PROJECT_DIR$/vendor/theseer/tokenizer" />
<path value="$PROJECT_DIR$/vendor/webmozart/assert" />
<path value="$PROJECT_DIR$/vendor/hamcrest/hamcrest-php" />
<path value="$PROJECT_DIR$/vendor/nunomaduro/collision" />
<path value="$PROJECT_DIR$/vendor/scrivo/highlight.php" />
<path value="$PROJECT_DIR$/vendor/phar-io/manifest" />
<path value="$PROJECT_DIR$/vendor/barryvdh/laravel-ide-helper" />
<path value="$PROJECT_DIR$/vendor/phar-io/version" />
<path value="$PROJECT_DIR$/vendor/barryvdh/reflection-docblock" />
<path value="$PROJECT_DIR$/vendor/laravel/ui" />
<path value="$PROJECT_DIR$/vendor/filp/whoops" />
<path value="$PROJECT_DIR$/vendor/myclabs/deep-copy" />
<path value="$PROJECT_DIR$/vendor/sebastian/code-unit-reverse-lookup" />
<path value="$PROJECT_DIR$/vendor/mockery/mockery" />
<path value="$PROJECT_DIR$/vendor/sebastian/version" />
<path value="$PROJECT_DIR$/vendor/sebastian/object-reflector" />
<path value="$PROJECT_DIR$/vendor/sebastian/global-state" />
<path value="$PROJECT_DIR$/vendor/sebastian/recursion-context" />
<path value="$PROJECT_DIR$/vendor/sebastian/object-enumerator" />
<path value="$PROJECT_DIR$/vendor/sebastian/exporter" />
<path value="$PROJECT_DIR$/vendor/sebastian/resource-operations" />
<path value="$PROJECT_DIR$/vendor/sebastian/comparator" />
<path value="$PROJECT_DIR$/vendor/sebastian/type" />
<path value="$PROJECT_DIR$/vendor/sebastian/environment" />
<path value="$PROJECT_DIR$/vendor/sebastian/diff" />
<path value="$PROJECT_DIR$/vendor/fzaninotto/faker" />
<path value="$PROJECT_DIR$/vendor/phpdocumentor/reflection-common" />
<path value="$PROJECT_DIR$/vendor/phpdocumentor/type-resolver" />
<path value="$PROJECT_DIR$/vendor/phpdocumentor/reflection-docblock" />
<path value="$PROJECT_DIR$/vendor/doctrine/instantiator" />
<path value="$PROJECT_DIR$/vendor/phpunit/php-text-template" />
<path value="$PROJECT_DIR$/vendor/phpunit/php-file-iterator" />
<path value="$PROJECT_DIR$/vendor/phpunit/phpunit" />
<path value="$PROJECT_DIR$/vendor/phpunit/php-token-stream" />
<path value="$PROJECT_DIR$/vendor/phpunit/php-code-coverage" />
<path value="$PROJECT_DIR$/vendor/phpunit/php-timer" />
<path value="$PROJECT_DIR$/vendor/facade/ignition-contracts" />
<path value="$PROJECT_DIR$/vendor/facade/flare-client-php" />
<path value="$PROJECT_DIR$/vendor/facade/ignition" />
<path value="$PROJECT_DIR$/vendor/phpspec/prophecy" />
</include_path>
</component>
<component name="PhpProjectSharedConfiguration" php_language_level="7.1" />
<component name="PhpUnit">
<phpunit_settings>
<PhpUnitSettings load_method="CUSTOM_LOADER" configuration_file_path="$PROJECT_DIR$/phpunit.xml" custom_loader_path="$PROJECT_DIR$/vendor/autoload.php" use_configuration_file="true" />
</phpunit_settings>
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<module type="WEB_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/app" isTestSource="false" packagePrefix="App\" />
<sourceFolder url="file://$MODULE_DIR$/tests" isTestSource="true" packagePrefix="Tests\" />
<excludeFolder url="file://$MODULE_DIR$/vendor/barryvdh/laravel-ide-helper" />
<excludeFolder url="file://$MODULE_DIR$/vendor/barryvdh/reflection-docblock" />
<excludeFolder url="file://$MODULE_DIR$/vendor/composer" />
<excludeFolder url="file://$MODULE_DIR$/vendor/dnoegel/php-xdg-base-dir" />
<excludeFolder url="file://$MODULE_DIR$/vendor/doctrine/cache" />
<excludeFolder url="file://$MODULE_DIR$/vendor/doctrine/dbal" />
<excludeFolder url="file://$MODULE_DIR$/vendor/doctrine/event-manager" />
<excludeFolder url="file://$MODULE_DIR$/vendor/doctrine/inflector" />
<excludeFolder url="file://$MODULE_DIR$/vendor/doctrine/instantiator" />
<excludeFolder url="file://$MODULE_DIR$/vendor/doctrine/lexer" />
<excludeFolder url="file://$MODULE_DIR$/vendor/dragonmantank/cron-expression" />
<excludeFolder url="file://$MODULE_DIR$/vendor/egulias/email-validator" />
<excludeFolder url="file://$MODULE_DIR$/vendor/erusev/parsedown" />
<excludeFolder url="file://$MODULE_DIR$/vendor/fabpot/goutte" />
<excludeFolder url="file://$MODULE_DIR$/vendor/facade/flare-client-php" />
<excludeFolder url="file://$MODULE_DIR$/vendor/facade/ignition" />
<excludeFolder url="file://$MODULE_DIR$/vendor/facade/ignition-contracts" />
<excludeFolder url="file://$MODULE_DIR$/vendor/fideloper/proxy" />
<excludeFolder url="file://$MODULE_DIR$/vendor/filp/whoops" />
<excludeFolder url="file://$MODULE_DIR$/vendor/fzaninotto/faker" />
<excludeFolder url="file://$MODULE_DIR$/vendor/guzzlehttp/guzzle" />
<excludeFolder url="file://$MODULE_DIR$/vendor/guzzlehttp/promises" />
<excludeFolder url="file://$MODULE_DIR$/vendor/guzzlehttp/psr7" />
<excludeFolder url="file://$MODULE_DIR$/vendor/hamcrest/hamcrest-php" />
<excludeFolder url="file://$MODULE_DIR$/vendor/intervention/image" />
<excludeFolder url="file://$MODULE_DIR$/vendor/jakub-onderka/php-console-color" />
<excludeFolder url="file://$MODULE_DIR$/vendor/jakub-onderka/php-console-highlighter" />
<excludeFolder url="file://$MODULE_DIR$/vendor/justinrainbow/json-schema" />
<excludeFolder url="file://$MODULE_DIR$/vendor/koenhoeijmakers/laravel-translatable" />
<excludeFolder url="file://$MODULE_DIR$/vendor/laravel/framework" />
<excludeFolder url="file://$MODULE_DIR$/vendor/laravel/tinker" />
<excludeFolder url="file://$MODULE_DIR$/vendor/laravel/ui" />
<excludeFolder url="file://$MODULE_DIR$/vendor/league/flysystem" />
<excludeFolder url="file://$MODULE_DIR$/vendor/league/glide" />
<excludeFolder url="file://$MODULE_DIR$/vendor/maennchen/zipstream-php" />
<excludeFolder url="file://$MODULE_DIR$/vendor/mcamara/laravel-localization" />
<excludeFolder url="file://$MODULE_DIR$/vendor/mockery/mockery" />
<excludeFolder url="file://$MODULE_DIR$/vendor/monolog/monolog" />
<excludeFolder url="file://$MODULE_DIR$/vendor/myclabs/deep-copy" />
<excludeFolder url="file://$MODULE_DIR$/vendor/myclabs/php-enum" />
<excludeFolder url="file://$MODULE_DIR$/vendor/nesbot/carbon" />
<excludeFolder url="file://$MODULE_DIR$/vendor/nikic/php-parser" />
<excludeFolder url="file://$MODULE_DIR$/vendor/nunomaduro/collision" />
<excludeFolder url="file://$MODULE_DIR$/vendor/opis/closure" />
<excludeFolder url="file://$MODULE_DIR$/vendor/paragonie/random_compat" />
<excludeFolder url="file://$MODULE_DIR$/vendor/phar-io/manifest" />
<excludeFolder url="file://$MODULE_DIR$/vendor/phar-io/version" />
<excludeFolder url="file://$MODULE_DIR$/vendor/phpdocumentor/reflection-common" />
<excludeFolder url="file://$MODULE_DIR$/vendor/phpdocumentor/reflection-docblock" />
<excludeFolder url="file://$MODULE_DIR$/vendor/phpdocumentor/type-resolver" />
<excludeFolder url="file://$MODULE_DIR$/vendor/phpoption/phpoption" />
<excludeFolder url="file://$MODULE_DIR$/vendor/phpspec/prophecy" />
<excludeFolder url="file://$MODULE_DIR$/vendor/phpunit/php-code-coverage" />
<excludeFolder url="file://$MODULE_DIR$/vendor/phpunit/php-file-iterator" />
<excludeFolder url="file://$MODULE_DIR$/vendor/phpunit/php-text-template" />
<excludeFolder url="file://$MODULE_DIR$/vendor/phpunit/php-timer" />
<excludeFolder url="file://$MODULE_DIR$/vendor/phpunit/php-token-stream" />
<excludeFolder url="file://$MODULE_DIR$/vendor/phpunit/phpunit" />
<excludeFolder url="file://$MODULE_DIR$/vendor/psr/container" />
<excludeFolder url="file://$MODULE_DIR$/vendor/psr/http-message" />
<excludeFolder url="file://$MODULE_DIR$/vendor/psr/log" />
<excludeFolder url="file://$MODULE_DIR$/vendor/psr/simple-cache" />
<excludeFolder url="file://$MODULE_DIR$/vendor/psy/psysh" />
<excludeFolder url="file://$MODULE_DIR$/vendor/ralouphie/getallheaders" />
<excludeFolder url="file://$MODULE_DIR$/vendor/ramsey/uuid" />
<excludeFolder url="file://$MODULE_DIR$/vendor/scrivo/highlight.php" />
<excludeFolder url="file://$MODULE_DIR$/vendor/sebastian/code-unit-reverse-lookup" />
<excludeFolder url="file://$MODULE_DIR$/vendor/sebastian/comparator" />
<excludeFolder url="file://$MODULE_DIR$/vendor/sebastian/diff" />
<excludeFolder url="file://$MODULE_DIR$/vendor/sebastian/environment" />
<excludeFolder url="file://$MODULE_DIR$/vendor/sebastian/exporter" />
<excludeFolder url="file://$MODULE_DIR$/vendor/sebastian/global-state" />
<excludeFolder url="file://$MODULE_DIR$/vendor/sebastian/object-enumerator" />
<excludeFolder url="file://$MODULE_DIR$/vendor/sebastian/object-reflector" />
<excludeFolder url="file://$MODULE_DIR$/vendor/sebastian/recursion-context" />
<excludeFolder url="file://$MODULE_DIR$/vendor/sebastian/resource-operations" />
<excludeFolder url="file://$MODULE_DIR$/vendor/sebastian/type" />
<excludeFolder url="file://$MODULE_DIR$/vendor/sebastian/version" />
<excludeFolder url="file://$MODULE_DIR$/vendor/seld/jsonlint" />
<excludeFolder url="file://$MODULE_DIR$/vendor/seld/phar-utils" />
<excludeFolder url="file://$MODULE_DIR$/vendor/spatie/geocoder" />
<excludeFolder url="file://$MODULE_DIR$/vendor/spatie/image" />
<excludeFolder url="file://$MODULE_DIR$/vendor/spatie/image-optimizer" />
<excludeFolder url="file://$MODULE_DIR$/vendor/spatie/laravel-medialibrary" />
<excludeFolder url="file://$MODULE_DIR$/vendor/spatie/pdf-to-image" />
<excludeFolder url="file://$MODULE_DIR$/vendor/spatie/temporary-directory" />
<excludeFolder url="file://$MODULE_DIR$/vendor/swiftmailer/swiftmailer" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/browser-kit" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/console" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/css-selector" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/debug" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/dom-crawler" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/error-handler" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/event-dispatcher" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/event-dispatcher-contracts" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/filesystem" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/finder" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/http-client" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/http-client-contracts" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/http-foundation" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/http-kernel" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/mime" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/polyfill-ctype" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/polyfill-iconv" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/polyfill-intl-idn" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/polyfill-mbstring" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/polyfill-php72" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/polyfill-php73" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/process" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/routing" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/service-contracts" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/translation" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/translation-contracts" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/var-dumper" />
<excludeFolder url="file://$MODULE_DIR$/vendor/theseer/tokenizer" />
<excludeFolder url="file://$MODULE_DIR$/vendor/tijsverkoyen/css-to-inline-styles" />
<excludeFolder url="file://$MODULE_DIR$/vendor/vlucas/phpdotenv" />
<excludeFolder url="file://$MODULE_DIR$/vendor/webmozart/assert" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>
\ No newline at end of file
php:
preset: laravel
disabled:
- unused_use
finder:
not-name:
- index.php
- server.php
js:
finder:
not-name:
- webpack.mix.js
css: true
## Testing project
###Installation:
`composer install`
`php artisan storage:link`
Migrations:
`php artisan migrate`
Start seed:
`php artisan db:seed`
To run queue:
`php artisan queue:work`
Parse data:
`php artisan data:import`
Geolocate cities:
`php artisan data:geocode`
This source diff could not be displayed because it is too large. You can view the blob instead.
<?php
namespace App\Console\Commands;
use App\Services\Geolocation\Jobs\GeolocateCity;
use Illuminate\Console\Command;
/**
* Class ImportCitiesGeolocation
* @package App\Commands
*/
class ImportCitiesGeolocation extends Command
{
/**
* {@inheritdoc}
*/
protected $signature = 'data:geocode';
/**
* {@inheritdoc}
*/
protected $name = 'Find and store coordinates for every city';
/**
* @var \App\Contracts\GeolocationContract
*/
protected $service;
/**
* ImportCitiesGeolocation constructor.
*
* @param \App\Contracts\GeolocationContract $service
*/
public function __construct(\App\Contracts\GeolocationContract $service)
{
parent::__construct();
$this->service = $service;
}
/**
* Import all cities coordinates into database.
*
* @return void
*/
public function handle(): void
{
$this->service->getCities()->each(function ($city) {
$this->output->writeln(__('parse.city.geolocate', ['name' => $city->name]));
dispatch(new GeolocateCity($this->service, $city));
});
}
}
<?php
namespace App\Console\Commands;
use App\Services\Regions\Jobs\ParseRegionDistricts;
use Illuminate\Console\Command;
/**
* Class ImportRegionsData
* @package App\Commands
*/
class ImportRegionsData extends Command
{
/**
* {@inheritdoc}
*/
protected $signature = 'data:import';
/**
* {@inheritdoc}
*/
protected $name = 'Import data into database';
/**
* @var \App\Contracts\RegionParserContract
*/
protected $service;
/**
* ImportRegionsData constructor.
*
* @param \App\Contracts\RegionParserContract $service
*/
public function __construct(\App\Contracts\RegionParserContract $service)
{
parent::__construct();
$this->service = $service;
}
/**
* Import all cities into database.
*
* @return void
*/
public function handle(): void
{
$this->service->getRegions()->each(function ($item) {
$this->output->writeln(__('parse.region.start', ['name' => $item->name]));
dispatch(new ParseRegionDistricts($this->service, $item));
$this->output->writeln(__('parse.region.queued', ['name' => $item->name]));
});
}
}
<?php
namespace App\Console;
use Illuminate\Console\Scheduling\Schedule;
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
/**
* Class Kernel
* @package App\Console
*/
class Kernel extends ConsoleKernel
{
/**
* The Artisan commands provided by your application.
*
* @var array
*/
protected $commands = [
];
/**
* Define the application's command schedule.
*
* @param \Illuminate\Console\Scheduling\Schedule $schedule
* @return void
*/
protected function schedule(Schedule $schedule)
{
}
/**
* Register the commands for the application.
*
* @return void
*/
protected function commands()
{
$this->load(__DIR__.'/Commands');
require base_path('routes/console.php');
}
}
<?php
namespace App\Contracts;
/**
* Interface CityContract
* @package App\Contracts
*/
interface CityContract extends Contract
{
/**
* @param int $id
* @param $attributes
* @return bool
*/
public function updateContacts(int $id, $attributes): bool;
}
<?php
namespace App\Contracts;
/**
* Interface Contract
* @package App\Contracts
*/
interface Contract
{
/**
* Find all items.
*
* @param array $columns
* @return \Illuminate\Support\Collection
*/
public function all(array $columns = ['*']);
/**
* Find one item by primary key.
*
* @param int $id
* @param array $columns
* @return mixed
*/
public function find($id, array $columns = ['*']);
/**
* Save item in database.
*
* @param array $attributes
* @param array $translations
*
* @return mixed
*/
public function store(array $attributes = [], array $translations = []);
/**
* Save or update item in database.
*
* @param array $find
* @param array $attributes
* @param array $translations
* @return mixed
*/
public function updateOrStore(array $find = [], array $attributes = [], array $translations = []);
}
<?php
namespace App\Contracts;
/**
* Interface DistrictContract
* @package App\Contracts
*/
interface DistrictContract extends Contract
{
}
<?php
namespace App\Contracts;
/**
* Interface GeolocationContract
* @package App\Contracts
*/
interface GeolocationContract
{
/**
* Get all cities collection.
*
* @return \Illuminate\Support\Collection
*/
public function getCities();
/**
* Find and update city coordinates.
*
* @param $city
*/
public function locateCity($city): void;
}
<?php
namespace App\Contracts;
/**
* Interface RegionContract
* @package App\Contracts
*/
interface RegionContract extends Contract
{
}
<?php
namespace App\Contracts;
/**
* Interface RegionParserContract
* @package App\Contracts
*/
interface RegionParserContract
{
/**
* Get all regions available.
*
* @return \Illuminate\Support\Collection
*/
public function getRegions();
/**
* Parse all districts by region `alias`.
*
* @param $region
* @return \Illuminate\Support\Collection
*/
public function parseRegion($region);
/**
* Parse all cities by district URL.
*
* @param string $url
* @param $district
* @return \Illuminate\Support\Collection
*/
public function parseDistrict(string $url, $district);
/**
* Parse one city.
*
* @param string $url
* @param $city
* @return mixed
*/
public function parseCity(string $url, $city);
}
<?php
namespace App\Exceptions;
use Exception;
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
/**
* Class Handler
* @package App\Exceptions
*/
class Handler extends ExceptionHandler
{
/**
* A list of the exception types that are not reported.
*
* @var array
*/
protected $dontReport = [
];
/**
* A list of the inputs that are never flashed for validation exceptions.
*
* @var array
*/
protected $dontFlash = [
'password',
'password_confirmation',
];
}
<?php
namespace App\Http\Controllers;
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
use Illuminate\Foundation\Bus\DispatchesJobs;
use Illuminate\Foundation\Validation\ValidatesRequests;
use Illuminate\Routing\Controller as BaseController;
/**
* Class Controller
* @package App\Http\Controllers
*/
class Controller extends BaseController
{
use AuthorizesRequests, DispatchesJobs, ValidatesRequests;
}
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Repositories\CityRepository;
/**
* Class HomeController
* @package App\Http\Controllers
*/
class HomeController extends Controller
{
public function index()
{
return view('home');
}
public function search(Request $request, CityRepository $cityRepository)
{
$search = $request->get('search');
$result = $cityRepository->searchBy('name', '%'. $search. '%', 'LIKE');
return response()->json($result);
}
public function city(Request $request, CityRepository $cityRepository)
{
$city = $cityRepository->getBy('name', $request->get('search'));
return view('city', ['city' => $city]);
}
}
<?php
namespace App\Http;
use Illuminate\Foundation\Http\Kernel as HttpKernel;
/**
* Class Kernel
* @package App\Http
*/
class Kernel extends HttpKernel
{
/**
* The application's global HTTP middleware stack.
*
* These middleware are run during every request to your application.
*
* @var array
*/
protected $middleware = [
\App\Http\Middleware\TrustProxies::class,
\App\Http\Middleware\CheckForMaintenanceMode::class,
\Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
\App\Http\Middleware\TrimStrings::class,
\Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
];
/**
* The application's route middleware groups.
*
* @var array
*/
protected $middlewareGroups = [
'web' => [
\App\Http\Middleware\EncryptCookies::class,
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
\Illuminate\Session\Middleware\StartSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
\App\Http\Middleware\VerifyCsrfToken::class,
\Illuminate\Routing\Middleware\SubstituteBindings::class,
],
'api' => [
'throttle:60,1',
\Illuminate\Routing\Middleware\SubstituteBindings::class,
],
];
/**
* The application's route middleware.
*
* These middleware may be assigned to groups or used individually.
*
* @var array
*/
protected $routeMiddleware = [
'auth' => \App\Http\Middleware\Authenticate::class,
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,
'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,
'can' => \Illuminate\Auth\Middleware\Authorize::class,
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
'password.confirm' => \Illuminate\Auth\Middleware\RequirePassword::class,
'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class,
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
'localize' => \Mcamara\LaravelLocalization\Middleware\LaravelLocalizationRoutes::class,
'localizationRedirect' => \Mcamara\LaravelLocalization\Middleware\LaravelLocalizationRedirectFilter::class,
'localeSessionRedirect' => \Mcamara\LaravelLocalization\Middleware\LocaleSessionRedirect::class,
'localeCookieRedirect' => \Mcamara\LaravelLocalization\Middleware\LocaleCookieRedirect::class,
'localeViewPath' => \Mcamara\LaravelLocalization\Middleware\LaravelLocalizationViewPath::class
];
/**
* The priority-sorted list of middleware.
*
* This forces non-global middleware to always be in the given order.
*
* @var array
*/
protected $middlewarePriority = [
\Illuminate\Session\Middleware\StartSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
\App\Http\Middleware\Authenticate::class,
\Illuminate\Routing\Middleware\ThrottleRequests::class,
\Illuminate\Session\Middleware\AuthenticateSession::class,
\Illuminate\Routing\Middleware\SubstituteBindings::class,
\Illuminate\Auth\Middleware\Authorize::class,
];
}
<?php
namespace App\Http\Middleware;
use Illuminate\Auth\Middleware\Authenticate as Middleware;
/**
* Class Authenticate
* @package App\Http\Middleware
*/
class Authenticate extends Middleware
{
/**
* Get the path the user should be redirected to when they are not authenticated.
*
* @param \Illuminate\Http\Request $request
* @return string|null
*/
protected function redirectTo($request): ?string
{
if (!$request->expectsJson()) {
return route('index');
}
}
}
<?php
namespace App\Http\Middleware;
use Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode as Middleware;
/**
* Class CheckForMaintenanceMode
* @package App\Http\Middleware
*/
class CheckForMaintenanceMode extends Middleware
{
/**
* The URIs that should be reachable while maintenance mode is enabled.
*
* @var array
*/
protected $except = [
];
}
<?php
namespace App\Http\Middleware;
use Illuminate\Cookie\Middleware\EncryptCookies as Middleware;
/**
* Class EncryptCookies
* @package App\Http\Middleware
*/
class EncryptCookies extends Middleware
{
/**
* The names of the cookies that should not be encrypted.
*
* @var array
*/
protected $except = [
];
}
<?php
namespace App\Http\Middleware;
use App\Providers\RouteServiceProvider;
use Closure;
use Illuminate\Support\Facades\Auth;
/**
* Class RedirectIfAuthenticated
* @package App\Http\Middleware
*/
class RedirectIfAuthenticated
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @param string|null $guard
* @return mixed
*/
public function handle($request, Closure $next, $guard = null)
{
if (Auth::guard($guard)->check()) {
return redirect(RouteServiceProvider::HOME);
}
return $next($request);
}
}
<?php
namespace App\Http\Middleware;
use Illuminate\Foundation\Http\Middleware\TrimStrings as Middleware;
/**
* Class TrimStrings
* @package App\Http\Middleware
*/
class TrimStrings extends Middleware
{
/**
* The names of the attributes that should not be trimmed.
*
* @var array
*/
protected $except = [
'password',
'password_confirmation',
];
}
<?php
namespace App\Http\Middleware;
use Fideloper\Proxy\TrustProxies as Middleware;
use Illuminate\Http\Request;
/**
* Class TrustProxies
* @package App\Http\Middleware
*/
class TrustProxies extends Middleware
{
/**
* The trusted proxies for this application.
*
* @var array|string
*/
protected $proxies;
/**
* The headers that should be used to detect proxies.
*
* @var int
*/
protected $headers = Request::HEADER_X_FORWARDED_ALL;
}
<?php
namespace App\Http\Middleware;
use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken as Middleware;
/**
* Class VerifyCsrfToken
* @package App\Http\Middleware
*/
class VerifyCsrfToken extends Middleware
{
/**
* Indicates whether the XSRF-TOKEN cookie should be set on the response.
*
* @var bool
*/
protected $addHttpCookie = true;
/**
* The URIs that should be excluded from CSRF verification.
*
* @var array
*/
protected $except = [
];
}
<?php
namespace App\Models\Regions;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Log;
use KoenHoeijmakers\LaravelTranslatable\HasTranslations;
use Spatie\MediaLibrary\HasMedia\HasMedia;
use Spatie\MediaLibrary\HasMedia\HasMediaTrait;
use Spatie\MediaLibrary\Models\Media;
/**
* Class City
* @package App\Models\Regions
*
* @property int $id
* @property string $alias
* @property string $name
* @property string $mayor
* @property string $address
* @property string $phone
* @property string $fax
* @property string $email
* @property string $web
* @property string $geo
*
* @property Collection $phones
* @property Collection $faxes
* @property Collection $emails
* @property Collection $sites
* @property Collection $location
*
* @property \App\Models\Regions\District $district
* @property \Spatie\MediaLibrary\Models\Media $emblem
*/
class City extends Model implements HasMedia
{
use HasTranslations, HasMediaTrait;
public const COLLECTION_EMBLEM = 'emblem';
/**
* {@inheritdoc}
*/
protected $translatable = ['name'];
/**
* {@inheritdoc}
*/
protected $fillable = ['name', 'district_id', 'alias', 'mayor', 'address', 'phones', 'faxes', 'emails', 'sites',
'coordinates'];
/**
* @var array Allowed mime types
*/
protected $allowedImageMimeTypes = ['image/gif', 'image/jpeg'];
/**
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
*/
public function district(): BelongsTo
{
return $this->belongsTo(District::class);
}
/**
* @param string $url
*/
public function updateEmblem(string $url): void
{
try {
$this->addMediaFromUrl($url, $this->allowedImageMimeTypes)
->toMediaCollection(static::COLLECTION_EMBLEM);
} catch (\Throwable $exception) {
Log::warning('Cannot update emblem.');
}
}
/**
* @return \Spatie\MediaLibrary\Models\Media|null $media
*/
public function getEmblemAttribute(): ?Media
{
return $this->getMedia(static::COLLECTION_EMBLEM)->last();
}
/**
* @return \Illuminate\Support\Collection
*/
public function getPhonesAttribute(): Collection
{
return $this->getMultiProps('phone');
}
/**
* @param $values
*/
public function setPhonesAttribute($values): void
{
$this->setMultiProps('phone', $values);
}
/**
* @return \Illuminate\Support\Collection
*/
public function getFaxesAttribute(): ?Collection
{
return $this->getMultiProps('fax');
}
/**
* @param $values
*/
public function setFaxesAttribute($values): void
{
$this->setMultiProps('fax', $values);
}
/**
* @return \Illuminate\Support\Collection
*/
public function getEmailsAttribute(): ?Collection
{
return $this->getMultiProps('email');
}
/**
* @param $values
*/
public function setEmailsAttribute($values): void
{
$this->setMultiProps('email', $values);
}
/**
* @return \Illuminate\Support\Collection
*/
public function getSitesAttribute(): ?Collection
{
return $this->getMultiProps('web');
}
/**
* @param $values
*/
public function setSitesAttribute($values): void
{
$this->setMultiProps('web', $values);
}
/**
* @return \Illuminate\Support\Collection
*/
public function getCoordinatesAttribute(): ?Collection
{
return (!$this->geo) ? null : collect(json_decode($this->geo, true));
}
/**
* @param $values
*/
public function setCoordinatesAttribute($values): void
{
if (($geo = collect($values)) && $geo->has('lat') && $geo->has('lng')) {
$this->geo = json_encode(['lat' => $geo->get('lat'), 'lng' => $geo->get('lng')]);
}
}
/**
* Set property as array
*
* @param string $attribute
* @param mixed $values
*/
protected function setMultiProps($attribute, $values): void
{
$this->{$attribute} = collect($values)->map('trim')->filter()->values()->toJson();
}
/**
* Get property as array
*
* @param string $attribute
* @return \Illuminate\Support\Collection
*/
protected function getMultiProps(string $attribute): Collection
{
$data = $this->{$attribute};
try {
$data = json_decode($data, true);
} catch (\Throwable $exception) {
Log::warning('Unable to decode "' . __CLASS__ . ':' . $attribute . '"');
}
return collect($data)->map('trim')->values();
}
}
<?php
namespace App\Models\Regions;
use Illuminate\Database\Eloquent\Model;
/**
* Class CityTranslation
* @package App\Models\Regions
*
* @property int $id
* @property string $name
*/
class CityTranslation extends Model
{
/**
* {@inheritdoc}
*/
protected $fillable = ['name', 'mayor', 'address'];
}
<?php
namespace App\Models\Regions;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use KoenHoeijmakers\LaravelTranslatable\HasTranslations;
/**
* Class District
* @package App\Models\Regions
*
* @property int $id
* @property string $name
* @property string $alias
*
* @property \App\Models\Regions\Region $region
*/
class District extends Model
{
use HasTranslations;
/**
* {@inheritdoc}
*/
protected $translatable = ['name'];
/**
* {@inheritdoc}
*/
protected $fillable = ['name', 'region_id', 'alias'];
/**
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
*/
public function region(): BelongsTo
{
return $this->belongsTo(Region::class);
}
}
<?php
namespace App\Models\Regions;
use Illuminate\Database\Eloquent\Model;
/**
* Class DistrictTranslation
* @package App\Models\Regions
*
* @property int $id
* @property string $name
*/
class DistrictTranslation extends Model
{
/**
* {@inheritdoc}
*/
protected $fillable = ['name'];
}
<?php
namespace App\Models\Regions;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasMany;
use KoenHoeijmakers\LaravelTranslatable\HasTranslations;
/**
* Class Region
* @package App\Models\Regions
*
* @property int $id
* @property string $name
* @property string $alias
*
* @property \App\Models\Regions\District[]|\Illuminate\Database\Eloquent\Collection $districts
*/
class Region extends Model
{
use HasTranslations;
/**
* {@inheritdoc}
*/
protected $translatable = ['name'];
/**
* {@inheritdoc}
*/
protected $fillable = ['name'];
/**
* @return \Illuminate\Database\Eloquent\Relations\HasMany
*/
public function districts(): HasMany
{
return $this->hasMany(District::class);
}
}
<?php
namespace App\Models\Regions;
use Illuminate\Database\Eloquent\Model;
/**
* Class RegionTranslation
* @package App\Models\Regions
*
* @property int $id
* @property string $name
*/
class RegionTranslation extends Model
{
/**
* {@inheritdoc}
*/
protected $fillable = ['name'];
}
<?php
namespace App\Models\Users;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
/**
* Class User
* @package App\Models\Users
*
* @property int $id
* @property string $login
* @property string $email
* @property \DateTime $email_verified_at
* @property string $password
* @property string $remember_token
*/
class User extends Authenticatable
{
use Notifiable;
/**
* {@inheritdoc}
*/
protected $fillable = [
'login', 'email', 'password',
];
/**
* {@inheritdoc}
*/
protected $hidden = [
'password', 'remember_token',
];
/**
* {@inheritdoc}
*/
protected $casts = [
'email_verified_at' => 'datetime',
];
}
<?php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
/**
* Class AppServiceProvider
* @package App\Providers
*/
class AppServiceProvider extends ServiceProvider
{
/**
* Register any application services.
*
* @return void
*/
public function register(): void
{
}
/**
* Bootstrap any application services.
*
* @return void
*/
public function boot(): void
{
}
}
<?php
namespace App\Providers;
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;
use Illuminate\Support\Facades\Gate;
/**
* Class AuthServiceProvider
* @package App\Providers
*/
class AuthServiceProvider extends ServiceProvider
{
/**
* The policy mappings for the application.
*
* @var array
*/
protected $policies = [
];
/**
* Register any authentication / authorization services.
*
* @return void
*/
public function boot(): void
{
$this->registerPolicies();
}
}
<?php
namespace App\Providers;
use Illuminate\Support\Facades\Broadcast;
use Illuminate\Support\ServiceProvider;
/**
* Class BroadcastServiceProvider
* @package App\Providers
*/
class BroadcastServiceProvider extends ServiceProvider
{
/**
* Bootstrap any application services.
*
* @return void
*/
public function boot(): void
{
Broadcast::routes();
require base_path('routes/channels.php');
}
}
<?php
namespace App\Providers;
use Illuminate\Auth\Events\Registered;
use Illuminate\Auth\Listeners\SendEmailVerificationNotification;
use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;
use Illuminate\Support\Facades\Event;
/**
* Class EventServiceProvider
* @package App\Providers
*/
class EventServiceProvider extends ServiceProvider
{
/**
* The event listener mappings for the application.
*
* @var array
*/
protected $listen = [
Registered::class => [
SendEmailVerificationNotification::class,
],
];
}
<?php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
/**
* Class ModelServiceProvider
* @package App\Providers
*/
class ModelServiceProvider extends ServiceProvider
{
/**
* {@inheritdoc}
*/
public function register(): void
{
$this->app->bind(\App\Contracts\RegionContract::class, \App\Repositories\RegionRepository::class);
$this->app->bind(\App\Contracts\DistrictContract::class, \App\Repositories\DistrictRepository::class);
$this->app->bind(\App\Contracts\CityContract::class, \App\Repositories\CityRepository::class);
}
}
<?php
namespace App\Providers;
use App\Contracts\GeolocationContract;
use App\Services\Geolocation\GeolocationService;
use Illuminate\Support\ServiceProvider;
use App\Contracts\RegionParserContract;
use App\Services\Regions\RegionParseService;
/**
* Class ParseServiceProvider
* @package App\Providers
*/
class ParseServiceProvider extends ServiceProvider
{
/**
* {@inheritdoc}
*/
public function register(): void
{
$this->app->bind(RegionParserContract::class, RegionParseService::class);
$this->app->bind(GeolocationContract::class, GeolocationService::class);
}
}
<?php
namespace App\Providers;
use Illuminate\Foundation\Support\Providers\RouteServiceProvider as ServiceProvider;
use Illuminate\Support\Facades\Route;
/**
* Class RouteServiceProvider
* @package App\Providers
*/
class RouteServiceProvider extends ServiceProvider
{
/**
* This namespace is applied to your controller routes.
*
* In addition, it is set as the URL generator's root namespace.
*
* @var string
*/
protected $namespace = 'App\Http\Controllers';
/**
* The path to the "home" route for your application.
*
* @var string
*/
public const HOME = '/';
/**
* Define your route model bindings, pattern filters, etc.
*
* @return void
*/
public function boot()
{
parent::boot();
}
/**
* Define the routes for the application.
*
* @return void
*/
public function map(): void
{
$this->mapApiRoutes();
$this->mapWebRoutes();
}
/**
* Define the "web" routes for the application.
*
* These routes all receive session state, CSRF protection, etc.
*
* @return void
*/
protected function mapWebRoutes(): void
{
Route::middleware('web')
->namespace($this->namespace)
->group(base_path('routes/web.php'));
}
/**
* Define the "api" routes for the application.
*
* These routes are typically stateless.
*
* @return void
*/
protected function mapApiRoutes(): void
{
Route::prefix('api')
->middleware('api')
->namespace($this->namespace)
->group(base_path('routes/api.php'));
}
}
<?php
namespace App\Repositories;
use App\Contracts\CityContract;
use App\Models\Regions\City;
use Illuminate\Database\Eloquent\Collection;
/**
* Class CityRepository
* @package App\Repositories
*
* @property City $model
*/
class CityRepository extends Repository implements CityContract
{
/**
* {@inheritdoc}
*/
protected function getModelClass(): string
{
return City::class;
}
/**
* @param int $id
* @param \Illuminate\Support\Collection $attributes
* @return bool
*/
public function updateContacts(int $id, $attributes): bool
{
if (!$model = $this->find($id)) {
return false;
}
if ($image = $attributes->get('image')) {
$attributes->forget('image');
$model->updateEmblem($image);
}
$model->fill($attributes->toArray())->save();
return true;
}
/**
* @param string $field
* @param string $value
* @param string $comparison
* @return Collection
*/
public function searchBy(string $field, string $value, string $comparison = '='): Collection
{
return $this->model->where($field, $comparison, $value)->get();
}
/**
* @param string $field
* @param string $value
* @return City|null
*/
public function getBy(string $field, string $value): ?City
{
return $this->model->where($field, $value)->first();
}
}
<?php
namespace App\Repositories;
use App\Contracts\DistrictContract;
use App\Models\Regions\District;
/**
* Class DistrictRepository
* @package App\Repositories
*/
class DistrictRepository extends Repository implements DistrictContract
{
/**
* {@inheritdoc}
*/
protected function getModelClass(): string
{
return District::class;
}
}
<?php
namespace App\Repositories;
use App\Contracts\RegionContract;
use App\Models\Regions\Region;
/**
* Class RegionRepository
* @package App\Repositories
*/
class RegionRepository extends Repository implements RegionContract
{
/**
* {@inheritdoc}
*/
protected function getModelClass(): string
{
return Region::class;
}
}
<?php
namespace App\Repositories;
use Illuminate\Database\Eloquent\Model;
/**
* Class Repository
* @package App\Repositories
*/
abstract class Repository
{
/**
* @var \Illuminate\Database\Eloquent\Model
*/
protected $model;
/**
* @return string
*/
abstract protected function getModelClass(): string;
/**
* Repository constructor.
*/
public function __construct()
{
$model = app($this->getModelClass());
if (!$model instanceof Model) {
throw new \InvalidArgumentException(
'Class "' . $this->getModelClass() . '" should be an instance of ' . Model::class
);
}
$this->model = $model;
}
/**
* Find all items.
*
* @param array $columns
* @return \Illuminate\Database\Eloquent\Builder[]|\Illuminate\Database\Eloquent\Collection
*/
public function all(array $columns = ['*'])
{
return $this->model::query()->get($columns);
}
/**
* Find one item by primary key.
*
* @param $id
* @param array $columns
* @return \Illuminate\Database\Eloquent\Collection|\Illuminate\Database\Eloquent\Model|null
*/
public function find($id, array $columns = ['*'])
{
return $this->model::query()->find($id, $columns);
}
/**
* Save item in database.
*
* @param array $attributes
* @param array $translations
*
* @return \Illuminate\Database\Eloquent\Builder|\Illuminate\Database\Eloquent\Model
*/
public function store(array $attributes = [], array $translations = [])
{
$result = $this->model::query()->create($attributes);
if ($translations) {
$result->storeTranslations($translations);
}
return $result;
}
/**
* Save or update item in database.
*
* @param array $find
* @param array $attributes
* @param array $translations
* @return \Illuminate\Database\Eloquent\Builder|\Illuminate\Database\Eloquent\Model
*/
public function updateOrStore(array $find = [], array $attributes = [], array $translations = [])
{
$result = $this->model::query()->updateOrCreate($find, $attributes);
if ($translations) {
$result->storeTranslations($translations);
}
return $result;
}
}
<?php
namespace App\Services\Geolocation;
use App\Contracts\CityContract;
use App\Contracts\GeolocationContract;
/**
* Class GeolocationService
* @package App\Services\Geolocation
*/
class GeolocationService implements GeolocationContract
{
/**
* @var \App\Contracts\CityContract
*/
protected $cities;
/**
* GeolocationService constructor.
*
* @param \App\Contracts\CityContract $cities
*/
public function __construct(CityContract $cities)
{
$this->cities = $cities;
}
/**
* @return \Illuminate\Support\Collection
*/
public function getCities()
{
return $this->cities->all();
}
/**
* {@inheritdoc}
*
* @param \App\Models\Regions\City $city
*/
public function locateCity($city): void
{
if ($data = collect(\Geocoder::getCoordinatesForAddress($city->address))) {
$this->cities->updateOrStore(['cities.id' => $city->id], [
'coordinates' => ['lat' => $data->get('lat'), 'lng' => $data->get('lng')]
]);
}
}
}
<?php
namespace App\Services\Geolocation\Jobs;
use App\Contracts\GeolocationContract;
use Illuminate\Bus\Queueable;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
class GeolocateCity
{
use Dispatchable, InteractsWithQueue, SerializesModels, Queueable;
/**
* @var \App\Contracts\GeolocationContract
*/
protected $service;
/**
* @var \App\Models\Regions\City $city
*/
protected $city;
/**
* @var bool
*/
protected $force = false;
/**
* GeolocateCity constructor.
*
* @param \App\Contracts\GeolocationContract $service
* @param $city
* @param bool $force
*/
public function __construct(GeolocationContract $service, $city, $force = false)
{
$this->service = $service;
$this->city = $city;
$this->force = $force;
}
/**
* Handle city geolocation.
*/
public function handle(): void
{
if ($this->force || !$this->city->location) {
$this->service->locateCity($this->city);
}
}
}
<?php
namespace App\Services\Regions\Components;
use Goutte\Client as HttpClient;
use Symfony\Component\DomCrawler\Crawler;
/**
* Class Client
* @package App\Services\Regions\Components
*/
class Client
{
/**
* @var string Base parsing URL.
*/
protected $baseUrl;
/**
* @var \Goutte\Client Crawler client.
*/
protected $client;
/**
* HttpClient constructor.
* @param string $baseUrl
*/
public function __construct(string $baseUrl)
{
$this->baseUrl = $baseUrl;
$this->client = new HttpClient();
}
/**
* Create URL for region by alias.
*
* @param string $alias
* @return string
*/
public function makeRegionUrl(string $alias): string
{
return '/kraj/' . $alias . '.html';
}
/**
* Load page.
*
* @param string $url
* @param array|null $options
* @return \Symfony\Component\DomCrawler\Crawler
*/
public function get(string $url, ?array $options = []): Crawler
{
return $this->client->request('GET', $this->makeUrl($url), $options);
}
/**
* Create valid URL.
*
* @param string $url
* @return string
*/
protected function makeUrl(string $url): string
{
return (0 === stripos($url, 'http')) ? $url : ($this->baseUrl . $url);
}
}
<?php
namespace App\Services\Regions\Components;
/**
* Class Converter
* @package App\Services\Regions\Components
*/
class Converter
{
}
<?php
namespace App\Services\Regions\Components;
use Illuminate\Support\Collection;
use Symfony\Component\DomCrawler\Crawler;
/**
* Class Parser
* @package App\Services\Regions\Components
*/
class Parser
{
/**
* @var array Additional fields relations.
*/
private static $additional = [
'Starosta' => 'mayor',
'Primátor' => 'mayor',
];
/**
* @param \Symfony\Component\DomCrawler\Crawler $html
* @return \Illuminate\Support\Collection
*/
public function parseRegion(Crawler $html): Collection
{
$result = collect();
$html->filter('td[colspan="2"][valign="top"] > a')->each(function (Crawler $node) use ($result) {
$url = $node->attr('href');
$result->put($url, $this->collectNames($node));
});
return $result;
}
/**
* @param \Symfony\Component\DomCrawler\Crawler $html
* @return \Illuminate\Support\Collection
*/
public function parseDistrict(Crawler $html): Collection
{
$result = collect();
$html->filter('table[cellspacing="3"] td[valign="top"] > a')->each(function (Crawler $node) use ($result) {
$url = $node->attr('href');
$result->put($url, $this->collectNames($node));
});
return $result;
}
/**
* @param \Symfony\Component\DomCrawler\Crawler $html
* @return \Illuminate\Support\Collection
*/
public function parseCity(Crawler $html): Collection
{
$result = collect();
$tables = $html->filter('table[cellspacing="3"]');
$tables->eq(0)->each(function (Crawler $node) use ($result) {
if ($emblem = $this->findCityEmblem($node)) {
$result->put('image', $emblem);
}
$this->collectContacts($node, $result);
$address = collect();
$node->filter('td[valign="top"]')->each(static function (Crawler $item, $index) use ($address) {
if ($index <= 3) {
return;
}
if ($line = trim($item->text())) {
$address->push($line);
}
});
$result->put('address', $address->implode(', '));
});
$tables->eq(1)->filter('tr')->each(function (Crawler $node) use ($result) {
$cells = $node->filter('td');
$title = preg_replace('|:$|u', '', $cells->eq(0)->text());
$value = $cells->eq(1)->text();
if ($field = $this->hasAdditional(trim($title))) {
$result->put($field, $value);
}
});
return $result;
}
/**
* @param string $title
* @return string|null
*/
private function hasAdditional(string $title): ?string
{
return static::$additional[$title] ?? null;
}
/**
* Collect contacts data.
*
* @param \Symfony\Component\DomCrawler\Crawler $node
* @param \Illuminate\Support\Collection $result
*/
private function collectContacts(Crawler $node, Collection $result): void
{
$node->filter('tr')->each(function (Crawler $item, $index) use ($result) {
if ($index < 3) {
return;
}
switch ($index) {
case 3:
$result->put('phones',
$this->preparePhones(
$this->collectPhone($item)
)
);
break;
case 4:
return;
case 5:
$result->put(
'faxes',
$this->preparePhones(
$this->collectFax($item)
)
);
break;
case 6:
$result->put('emails', $this->collectLinks($item, 'mailto:'));
break;
case 7:
$result->put('sites', $this->collectLinks($item));
break;
}
});
}
/**
* Collect links.
*
* @param \Symfony\Component\DomCrawler\Crawler $node
* @param string|null $replace
* @return array
*/
private function collectLinks(Crawler $node, ?string $replace = null): array
{
$result = collect();
$node->filter('a')->each(static function (Crawler $item) use ($result, $replace) {
$result->push($replace ? str_replace($replace, '', $item->attr('href')) : $item->attr('href'));
});
return $result->toArray();
}
/**
* Collect phone numbers.
*
* @param \Symfony\Component\DomCrawler\Crawler $node
* @return Collection
*/
private function collectFax(Crawler $node): Collection
{
return collect(explode(PHP_EOL, $node->filter('td')->last()->text()));
}
/**
* Collect phone numbers.
*
* @param \Symfony\Component\DomCrawler\Crawler $node
* @return Collection
*/
private function collectPhone(Crawler $node): Collection
{
$phones = collect();
$node->filter('table tr td')->each(static function (Crawler $item) use ($phones) {
$phones->push($item->text());
});
return $phones;
}
/**
* Look at city emblem.
*
* @param \Symfony\Component\DomCrawler\Crawler $node
* @return string|null
*/
private function findCityEmblem(Crawler $node): ?string
{
return ($img = $node->filter('td[rowspan="4"] img')->first()) ? $img->attr('src') : null;
}
/**
* @param Crawler $node
* @return array
*/
private function collectNames(Crawler $node): array
{
$name = $node->text();
$converted = $this->convertName($name);
$alias = $this->createUrlAlias($converted);
return [$name, $alias, $converted];
}
/**
* Generate URL alias.
*
* @param string $name
* @return string|null
*/
private function createUrlAlias(string $name): ?string
{
$name = strtolower($name);
$name = preg_replace('|[^a-z ]|u', '', $name);
$name = preg_replace('|[\s]{2,}|u', ' ', $name);
return preg_replace('|[\s]|u', '-', trim($name));
}
/**
* Convert name to ASCII (for semi-automated English translation)
*
* @param string $name
* @return string
*/
private function convertName(string $name): string
{
return str_replace(['\''], [''], iconv('UTF-8', 'ASCII//TRANSLIT', $name));
}
/**
* Prepare phone numbers.
*
* @param \Illuminate\Support\Collection $phones
* @return array
*/
private function preparePhones(Collection $phones): array
{
$result = collect();
$phones->each(function (string $phone) use (&$result) {
if ($duplicates = $this->duplicatePhone($phone)) {
$result = $result->merge($duplicates);
} else {
$result->push($phone);
}
});
return $result->toArray();
}
/**
* Duplicate phone numbers.
*
* @param string $phone
* @return \Illuminate\Support\Collection|null
*/
private function duplicatePhone(string $phone): ?Collection
{
if (false === strpos($phone, ',')) {
return null;
}
$parts = collect(explode(',', $phone))->map(static function (string $item) {
return trim($item);
});
$canonical = $parts->shift();
return $parts->map(static function (string $item) use ($canonical) {
$length = -mb_strlen($item);
return mb_substr($canonical, 0, $length) . $item;
})->push($canonical);
}
}
<?php
namespace App\Services\Regions\Jobs;
use App\Contracts\RegionParserContract;
use Illuminate\Bus\Queueable;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
/**
* Class ParseCity
* @package App\Services\Regions\Jobs
*/
class ParseCity
{
use Dispatchable, InteractsWithQueue, SerializesModels, Queueable;
/**
* @var \App\Contracts\RegionParserContract $service
*/
private $service;
/**
* @var \App\Models\Regions\City
*/
private $city;
/**
* @var string
*/
private $url;
/**
* ParseDistrictCities constructor.
*
* @param \App\Contracts\RegionParserContract $service
* @param \App\Models\Regions\City $city
* @param string $url
*/
public function __construct(RegionParserContract $service, $city, $url)
{
$this->service = $service;
$this->city = $city;
$this->url = $url;
}
/**
* Parse city.
*/
public function handle(): void
{
$this->service->parseCity($this->url, $this->city);
}
}
<?php
namespace App\Services\Regions\Jobs;
use App\Contracts\RegionParserContract;
use Illuminate\Bus\Queueable;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
/**
* Class ParseDistrictCities
* @package App\Services\Regions\Jobs
*/
class ParseDistrictCities
{
use Dispatchable, InteractsWithQueue, SerializesModels, Queueable;
/**
* @var \App\Contracts\RegionParserContract $service
*/
private $service;
/**
* @var \App\Models\Regions\District
*/
private $district;
/**
* @var string
*/
private $url;
/**
* ParseDistrictCities constructor.
*
* @param \App\Contracts\RegionParserContract $service
* @param \App\Models\Regions\District $district
* @param string $url
*/
public function __construct(RegionParserContract $service, $district, $url)
{
$this->service = $service;
$this->district = $district;
$this->url = $url;
}
/**
* Parse cities.
*/
public function handle(): void
{
$this->service->parseDistrict($this->url, $this->district)->each(function ($item, $url) {
dispatch(new ParseCity($this->service, $item, $url));
});
}
}
<?php
namespace App\Services\Regions\Jobs;
use App\Contracts\RegionParserContract;
use Illuminate\Bus\Queueable;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
/**
* Class ParseRegionDistricts
* @package App\Services\Regions\Jobs
*/
class ParseRegionDistricts
{
use Dispatchable, InteractsWithQueue, SerializesModels, Queueable;
/**
* @var \App\Contracts\RegionParserContract $service
*/
private $service;
/**
* @var \App\Models\Regions\Region
*/
private $region;
/**
* ParseRegionDistricts constructor.
*
* @param \App\Contracts\RegionParserContract $service
* @param \App\Models\Regions\Region $region
*/
public function __construct(RegionParserContract $service, $region)
{
$this->service = $service;
$this->region = $region;
}
/**
* Parse districts.
*/
public function handle(): void
{
$this->service->parseRegion($this->region)->each(function ($item, $url) {
dispatch(new ParseDistrictCities($this->service, $item, $url));
});
}
}
<?php
namespace App\Services\Regions;
use App\Contracts\CityContract;
use App\Contracts\DistrictContract;
use App\Contracts\RegionContract;
use App\Contracts\RegionParserContract;
use App\Models\Regions\District;
use App\Services\Regions\Components\Client;
use App\Services\Regions\Components\Converter;
use App\Services\Regions\Components\Parser;
use Illuminate\Support\Collection;
/**
* Class RegionParseService
* @package App\Services\Regions
*/
class RegionParseService implements RegionParserContract
{
/**
* Base site URL.
*/
public const BASE_URL = 'https://www.e-obce.sk';
/**
* @var \App\Services\Regions\Components\Client HTTP-client.
*/
protected $client;
/**
* @var \App\Services\Regions\Components\Converter
*/
protected $converter;
/**
* @var \App\Services\Regions\Components\Parser
*/
protected $parser;
/**
* @var \App\Contracts\RegionContract
*/
protected $regions;
/**
* @var \App\Contracts\DistrictContract
*/
protected $districts;
/**
* @var \App\Contracts\CityContract
*/
protected $cities;
/**
* ParseRegionService constructor.
*
* @param \App\Contracts\RegionContract $regions
* @param \App\Contracts\DistrictContract $districts
* @param \App\Contracts\CityContract $cities
*/
public function __construct(RegionContract $regions, DistrictContract $districts, CityContract $cities)
{
$this->regions = $regions;
$this->districts = $districts;
$this->cities = $cities;
$this->client = new Client(static::BASE_URL);
$this->converter = new Converter();
$this->parser = new Parser();
}
/**
* Get all regions available.
*
* @return \Illuminate\Support\Collection
*/
public function getRegions()
{
return $this->regions->all();
}
/**
* Parse region.
*
* @param \App\Models\Regions\Region $region
* @return \Illuminate\Support\Collection
*/
public function parseRegion($region): Collection
{
$result = collect();
$response = $this->client->get($this->client->makeRegionUrl($region->alias));
$this->parser->parseRegion($response)
->each(function ($item, $url) use ($result, $region) {
[$name, $alias, $converted] = $item;
$result->put($url, $this->districts->updateOrStore(
['region_id' => $region->id, 'alias' => $alias],
['name' => $converted, 'region_id' => $region->id, 'alias' => $alias],
['sk' => ['name' => $name]]
));
});
return $result;
}
/**
* Parse cities.
*
* @param string $url
* @param District $district
* @return \Illuminate\Support\Collection|void
*/
public function parseDistrict(string $url, $district)
{
$result = collect();
$response = $this->client->get($url);
$this->parser->parseDistrict($response)
->each(function ($item, $parseUrl) use ($result, $district) {
[$name, $alias, $converted] = $item;
$result->put($parseUrl, $this->cities->updateOrStore(
['district_id' => $district->id, 'alias' => $alias],
['name' => $converted, 'district_id' => $district->id, 'alias' => $alias],
['sk' => ['name' => $name]]
));
});
return $result;
}
/**
* Parse city.
*
* @param string $url
* @param $city
*/
public function parseCity(string $url, $city)
{
$response = $this->client->get($url);
if ($data = $this->parser->parseCity($response)) {
$this->cities->updateContacts($city->id, $data);
}
}
}
#!/usr/bin/env php
<?php
define('LARAVEL_START', microtime(true));
/*
|--------------------------------------------------------------------------
| Register The Auto Loader
|--------------------------------------------------------------------------
|
| Composer provides a convenient, automatically generated class loader
| for our application. We just need to utilize it! We'll require it
| into the script here so that we do not have to worry about the
| loading of any our classes "manually". Feels great to relax.
|
*/
require __DIR__.'/vendor/autoload.php';
$app = require __DIR__.'/bootstrap/app.php';
/*
|--------------------------------------------------------------------------
| Run The Artisan Application
|--------------------------------------------------------------------------
|
| When we run the console application, the current CLI command will be
| executed in this console and the response sent back to a terminal
| or another output device for the developers. Here goes nothing!
|
*/
$kernel = $app->make(Illuminate\Contracts\Console\Kernel::class);
$status = $kernel->handle(
$input = new Symfony\Component\Console\Input\ArgvInput,
new Symfony\Component\Console\Output\ConsoleOutput
);
/*
|--------------------------------------------------------------------------
| Shutdown The Application
|--------------------------------------------------------------------------
|
| Once Artisan has finished running, we will fire off the shutdown events
| so that any final work may be done by the application before we shut
| down the process. This is the last thing to happen to the request.
|
*/
$kernel->terminate($input, $status);
exit($status);
<?php
$app = new Illuminate\Foundation\Application(
$_ENV['APP_BASE_PATH'] ?? dirname(__DIR__)
);
$app->singleton(
Illuminate\Contracts\Http\Kernel::class,
App\Http\Kernel::class
);
$app->singleton(
Illuminate\Contracts\Console\Kernel::class,
App\Console\Kernel::class
);
$app->singleton(
Illuminate\Contracts\Debug\ExceptionHandler::class,
App\Exceptions\Handler::class
);
return $app;
{
"name": "testing/locations",
"type": "project",
"description": "",
"keywords": [],
"license": "MIT",
"require": {
"php": "^7.1",
"ext-json": "*",
"fabpot/goutte": "^4.0",
"fideloper/proxy": "^4.0",
"guzzlehttp/guzzle": "^6.5",
"koenhoeijmakers/laravel-translatable": "^0.5.0",
"laravel/framework": "^6.2",
"laravel/tinker": "^2.0",
"mcamara/laravel-localization": "^1.4",
"spatie/geocoder": "^3.6",
"spatie/laravel-medialibrary": "^7.17",
"symfony/polyfill-iconv": "^1.13.1"
},
"require-dev": {
"barryvdh/laravel-ide-helper": "^2.6",
"facade/ignition": "^1.4",
"fzaninotto/faker": "^1.4",
"laravel/ui": "^1.1",
"mockery/mockery": "^1.0",
"nunomaduro/collision": "^3.0",
"phpunit/phpunit": "^8.0"
},
"config": {
"optimize-autoloader": true,
"preferred-install": "dist",
"sort-packages": true
},
"extra": {
"laravel": {
"dont-discover": []
}
},
"autoload": {
"psr-4": {
"App\\": "app/"
},
"classmap": [
"database/seeds",
"database/factories"
]
},
"autoload-dev": {
"psr-4": {
"Tests\\": "tests/"
}
},
"minimum-stability": "dev",
"prefer-stable": true,
"scripts": {
"post-autoload-dump": [
"Illuminate\\Foundation\\ComposerScripts::postAutoloadDump",
"@php artisan package:discover --ansi"
],
"post-root-package-install": [
"@php -r \"file_exists('.env') || copy('.env.example', '.env');\""
],
"post-create-project-cmd": [
"@php artisan key:generate --ansi"
]
}
}
<?php
return [
'name' => env('APP_NAME', 'Laravel'),
'env' => env('APP_ENV', 'production'),
'debug' => env('APP_DEBUG', false),
'url' => env('APP_URL', 'http://localhost'),
'asset_url' => env('ASSET_URL', null),
'timezone' => 'UTC',
'locale' => env('APP_LOCALE', 'en'),
'fallback_locale' => env('APP_FALLBACK_LOCALE', 'en'),
'faker_locale' => 'en_US',
'key' => env('APP_KEY'),
'cipher' => 'AES-256-CBC',
'providers' => [
Illuminate\Auth\AuthServiceProvider::class,
Illuminate\Broadcasting\BroadcastServiceProvider::class,
Illuminate\Bus\BusServiceProvider::class,
Illuminate\Cache\CacheServiceProvider::class,
Illuminate\Foundation\Providers\ConsoleSupportServiceProvider::class,
Illuminate\Cookie\CookieServiceProvider::class,
Illuminate\Database\DatabaseServiceProvider::class,
Illuminate\Encryption\EncryptionServiceProvider::class,
Illuminate\Filesystem\FilesystemServiceProvider::class,
Illuminate\Foundation\Providers\FoundationServiceProvider::class,
Illuminate\Hashing\HashServiceProvider::class,
Illuminate\Mail\MailServiceProvider::class,
Illuminate\Notifications\NotificationServiceProvider::class,
Illuminate\Pagination\PaginationServiceProvider::class,
Illuminate\Pipeline\PipelineServiceProvider::class,
Illuminate\Queue\QueueServiceProvider::class,
Illuminate\Redis\RedisServiceProvider::class,
Illuminate\Auth\Passwords\PasswordResetServiceProvider::class,
Illuminate\Session\SessionServiceProvider::class,
Illuminate\Translation\TranslationServiceProvider::class,
Illuminate\Validation\ValidationServiceProvider::class,
Illuminate\View\ViewServiceProvider::class,
App\Providers\AppServiceProvider::class,
App\Providers\AuthServiceProvider::class,
App\Providers\EventServiceProvider::class,
App\Providers\RouteServiceProvider::class,
App\Providers\ModelServiceProvider::class,
App\Providers\ParseServiceProvider::class,
Spatie\Geocoder\GeocoderServiceProvider::class
],
'aliases' => [
'App' => Illuminate\Support\Facades\App::class,
'Arr' => Illuminate\Support\Arr::class,
'Artisan' => Illuminate\Support\Facades\Artisan::class,
'Auth' => Illuminate\Support\Facades\Auth::class,
'Blade' => Illuminate\Support\Facades\Blade::class,
'Broadcast' => Illuminate\Support\Facades\Broadcast::class,
'Bus' => Illuminate\Support\Facades\Bus::class,
'Cache' => Illuminate\Support\Facades\Cache::class,
'Config' => Illuminate\Support\Facades\Config::class,
'Cookie' => Illuminate\Support\Facades\Cookie::class,
'Crypt' => Illuminate\Support\Facades\Crypt::class,
'DB' => Illuminate\Support\Facades\DB::class,
'Eloquent' => Illuminate\Database\Eloquent\Model::class,
'Event' => Illuminate\Support\Facades\Event::class,
'File' => Illuminate\Support\Facades\File::class,
'Gate' => Illuminate\Support\Facades\Gate::class,
'Hash' => Illuminate\Support\Facades\Hash::class,
'Lang' => Illuminate\Support\Facades\Lang::class,
'Log' => Illuminate\Support\Facades\Log::class,
'Mail' => Illuminate\Support\Facades\Mail::class,
'Notification' => Illuminate\Support\Facades\Notification::class,
'Password' => Illuminate\Support\Facades\Password::class,
'Queue' => Illuminate\Support\Facades\Queue::class,
'Redirect' => Illuminate\Support\Facades\Redirect::class,
'Redis' => Illuminate\Support\Facades\Redis::class,
'Request' => Illuminate\Support\Facades\Request::class,
'Response' => Illuminate\Support\Facades\Response::class,
'Route' => Illuminate\Support\Facades\Route::class,
'Schema' => Illuminate\Support\Facades\Schema::class,
'Session' => Illuminate\Support\Facades\Session::class,
'Storage' => Illuminate\Support\Facades\Storage::class,
'Str' => Illuminate\Support\Str::class,
'URL' => Illuminate\Support\Facades\URL::class,
'Validator' => Illuminate\Support\Facades\Validator::class,
'View' => Illuminate\Support\Facades\View::class,
'Geocoder' => Spatie\Geocoder\Facades\Geocoder::class,
],
];
<?php
return [
'defaults' => [
'guard' => 'web',
'passwords' => 'users',
],
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
'api' => [
'driver' => 'token',
'provider' => 'users',
'hash' => false,
],
],
'providers' => [
'users' => [
'driver' => 'eloquent',
'model' => App\Models\Users\User::class,
],
],
'passwords' => [
'users' => [
'provider' => 'users',
'table' => 'password_resets',
'expire' => 60,
'throttle' => 60,
],
],
'password_timeout' => 10800,
];
<?php
return [
'default' => env('BROADCAST_DRIVER', 'null'),
'connections' => [
'pusher' => [
'driver' => 'pusher',
'key' => env('PUSHER_APP_KEY'),
'secret' => env('PUSHER_APP_SECRET'),
'app_id' => env('PUSHER_APP_ID'),
'options' => [
'cluster' => env('PUSHER_APP_CLUSTER'),
'useTLS' => true,
],
],
'redis' => [
'driver' => 'redis',
'connection' => 'default',
],
'log' => [
'driver' => 'log',
],
'null' => [
'driver' => 'null',
],
],
];
<?php
use Illuminate\Support\Str;
return [
'default' => env('CACHE_DRIVER', 'file'),
'stores' => [
'apc' => [
'driver' => 'apc',
],
'array' => [
'driver' => 'array',
],
'database' => [
'driver' => 'database',
'table' => 'cache',
'connection' => null,
],
'file' => [
'driver' => 'file',
'path' => storage_path('framework/cache/data'),
],
'memcached' => [
'driver' => 'memcached',
'persistent_id' => env('MEMCACHED_PERSISTENT_ID'),
'sasl' => [
env('MEMCACHED_USERNAME'),
env('MEMCACHED_PASSWORD'),
],
'options' => [
// Memcached::OPT_CONNECT_TIMEOUT => 2000,
],
'servers' => [
[
'host' => env('MEMCACHED_HOST', '127.0.0.1'),
'port' => env('MEMCACHED_PORT', 11211),
'weight' => 100,
],
],
],
'redis' => [
'driver' => 'redis',
'connection' => 'cache',
],
'dynamodb' => [
'driver' => 'dynamodb',
'key' => env('AWS_ACCESS_KEY_ID'),
'secret' => env('AWS_SECRET_ACCESS_KEY'),
'region' => env('AWS_DEFAULT_REGION', 'us-east-1'),
'table' => env('DYNAMODB_CACHE_TABLE', 'cache'),
'endpoint' => env('DYNAMODB_ENDPOINT'),
],
],
'prefix' => env('CACHE_PREFIX', Str::slug(env('APP_NAME', 'laravel'), '_').'_cache'),
];
<?php
use Illuminate\Support\Str;
return [
'default' => env('DB_CONNECTION', 'mysql'),
'connections' => [
'sqlite' => [
'driver' => 'sqlite',
'url' => env('DATABASE_URL'),
'database' => env('DB_DATABASE', database_path('database.sqlite')),
'prefix' => '',
'foreign_key_constraints' => env('DB_FOREIGN_KEYS', true),
],
'mysql' => [
'driver' => 'mysql',
'url' => env('DATABASE_URL'),
'host' => env('DB_HOST', '127.0.0.1'),
'port' => env('DB_PORT', '3306'),
'database' => env('DB_DATABASE', 'forge'),
'username' => env('DB_USERNAME', 'forge'),
'password' => env('DB_PASSWORD', ''),
'unix_socket' => env('DB_SOCKET', ''),
'charset' => 'utf8mb4',
'collation' => 'utf8mb4_unicode_ci',
'prefix' => '',
'prefix_indexes' => true,
'strict' => true,
'engine' => null,
'options' => extension_loaded('pdo_mysql') ? array_filter([
PDO::MYSQL_ATTR_SSL_CA => env('MYSQL_ATTR_SSL_CA'),
]) : [],
],
],
'migrations' => 'migrations',
'redis' => [
'client' => env('REDIS_CLIENT', 'phpredis'),
'options' => [
'cluster' => env('REDIS_CLUSTER', 'redis'),
'prefix' => env('REDIS_PREFIX', Str::slug(env('APP_NAME', 'laravel'), '_').'_database_'),
],
'default' => [
'url' => env('REDIS_URL'),
'host' => env('REDIS_HOST', '127.0.0.1'),
'password' => env('REDIS_PASSWORD', null),
'port' => env('REDIS_PORT', '6379'),
'database' => env('REDIS_DB', '0'),
],
'cache' => [
'url' => env('REDIS_URL'),
'host' => env('REDIS_HOST', '127.0.0.1'),
'password' => env('REDIS_PASSWORD', null),
'port' => env('REDIS_PORT', '6379'),
'database' => env('REDIS_CACHE_DB', '1'),
],
],
];
<?php
return [
'default' => env('FILESYSTEM_DRIVER', 'local'),
'cloud' => env('FILESYSTEM_CLOUD', 's3'),
'disks' => [
'local' => [
'driver' => 'local',
'root' => storage_path('app'),
],
'public' => [
'driver' => 'local',
'root' => storage_path('app/public'),
'url' => env('APP_URL').'/storage',
'visibility' => 'public',
],
's3' => [
'driver' => 's3',
'key' => env('AWS_ACCESS_KEY_ID'),
'secret' => env('AWS_SECRET_ACCESS_KEY'),
'region' => env('AWS_DEFAULT_REGION'),
'bucket' => env('AWS_BUCKET'),
'url' => env('AWS_URL'),
],
],
];
<?php
return [
'key' => env('GOOGLE_MAPS_GEOCODING_API_KEY', ''),
'language' => env('GOOGLE_MAPS_GEOCODING_LOCALE', 'sk'),
'region' => '',
'bounds' => '',
'country' => env('GOOGLE_MAPS_GEOCODING_COUNTRY', 'SK'),
];
<?php
return [
'driver' => 'bcrypt',
'bcrypt' => [
'rounds' => env('BCRYPT_ROUNDS', 10),
],
'argon' => [
'memory' => 1024,
'threads' => 2,
'time' => 2,
],
];
<?php
return [
'supportedLocales' => [
'sk' => ['name' => 'Slovak', 'script' => 'Latn', 'native' => 'Slovenčina', 'regional' => 'sk_SK'],
'en' => ['name' => 'English', 'script' => 'Latn', 'native' => 'English', 'regional' => 'en_GB'],
],
'useAcceptLanguageHeader' => true,
'hideDefaultLocaleInURL' => true,
'localesOrder' => [],
'localesMapping' => [],
'utf8suffix' => env('LARAVELLOCALIZATION_UTF8SUFFIX', '.UTF-8'),
'urlsIgnored' => ['/skipped'],
];
<?php
use Monolog\Handler\NullHandler;
use Monolog\Handler\StreamHandler;
use Monolog\Handler\SyslogUdpHandler;
return [
'default' => env('LOG_CHANNEL', 'stack'),
'channels' => [
'stack' => [
'driver' => 'stack',
'channels' => ['single'],
'ignore_exceptions' => false,
],
'single' => [
'driver' => 'single',
'path' => storage_path('logs/laravel.log'),
'level' => 'debug',
],
'daily' => [
'driver' => 'daily',
'path' => storage_path('logs/laravel.log'),
'level' => 'debug',
'days' => 14,
],
'slack' => [
'driver' => 'slack',
'url' => env('LOG_SLACK_WEBHOOK_URL'),
'username' => 'Laravel Log',
'emoji' => ':boom:',
'level' => 'critical',
],
'stderr' => [
'driver' => 'monolog',
'handler' => StreamHandler::class,
'formatter' => env('LOG_STDERR_FORMATTER'),
'with' => [
'stream' => 'php://stderr',
],
],
'syslog' => [
'driver' => 'syslog',
'level' => 'debug',
],
'errorlog' => [
'driver' => 'errorlog',
'level' => 'debug',
],
'null' => [
'driver' => 'monolog',
'handler' => NullHandler::class,
],
'emergency' => [
'path' => storage_path('logs/laravel.log'),
],
],
];
<?php
return [
'driver' => env('MAIL_DRIVER', 'smtp'),
'host' => env('MAIL_HOST', 'smtp.mailgun.org'),
'port' => env('MAIL_PORT', 587),
'from' => [
'address' => env('MAIL_FROM_ADDRESS', 'hello@example.com'),
'name' => env('MAIL_FROM_NAME', 'Example'),
],
'encryption' => env('MAIL_ENCRYPTION', 'tls'),
'username' => env('MAIL_USERNAME'),
'password' => env('MAIL_PASSWORD'),
'sendmail' => '/usr/sbin/sendmail -bs',
'markdown' => [
'theme' => 'default',
'paths' => [
resource_path('views/vendor/mail'),
],
],
'log_channel' => env('MAIL_LOG_CHANNEL'),
];
<?php
return [
'disk_name' => env('MEDIA_DISK', 'public'),
'max_file_size' => 1024 * 1024 * 10,
'queue_name' => '',
'media_model' => Spatie\MediaLibrary\Models\Media::class,
's3' => [
'domain' => 'https://'.env('AWS_BUCKET').'.s3.amazonaws.com',
],
'remote' => [
'extra_headers' => [
'CacheControl' => 'max-age=604800',
],
],
'responsive_images' => [
'width_calculator' => Spatie\MediaLibrary\ResponsiveImages\WidthCalculator\FileSizeOptimizedWidthCalculator::class,
'use_tiny_placeholders' => true,
'tiny_placeholder_generator' => Spatie\MediaLibrary\ResponsiveImages\TinyPlaceholderGenerator\Blurred::class,
],
'url_generator' => null,
'version_urls' => false,
'path_generator' => null,
'image_optimizers' => [
Spatie\ImageOptimizer\Optimizers\Jpegoptim::class => [
'--strip-all', // this strips out all text information such as comments and EXIF data
'--all-progressive', // this will make sure the resulting image is a progressive one
],
Spatie\ImageOptimizer\Optimizers\Pngquant::class => [
'--force', // required parameter for this package
],
Spatie\ImageOptimizer\Optimizers\Optipng::class => [
'-i0', // this will result in a non-interlaced, progressive scanned image
'-o2', // this set the optimization level to two (multiple IDAT compression trials)
'-quiet', // required parameter for this package
],
Spatie\ImageOptimizer\Optimizers\Svgo::class => [
'--disable=cleanupIDs', // disabling because it is known to cause troubles
],
Spatie\ImageOptimizer\Optimizers\Gifsicle::class => [
'-b', // required parameter for this package
'-O3', // this produces the slowest but best results
],
],
'image_generators' => [
Spatie\MediaLibrary\ImageGenerators\FileTypes\Image::class,
Spatie\MediaLibrary\ImageGenerators\FileTypes\Webp::class,
Spatie\MediaLibrary\ImageGenerators\FileTypes\Pdf::class,
Spatie\MediaLibrary\ImageGenerators\FileTypes\Svg::class,
Spatie\MediaLibrary\ImageGenerators\FileTypes\Video::class,
],
'image_driver' => 'gd',
'ffmpeg_path' => env('FFMPEG_PATH', '/usr/bin/ffmpeg'),
'ffprobe_path' => env('FFPROBE_PATH', '/usr/bin/ffprobe'),
'temporary_directory_path' => null,
'jobs' => [
'perform_conversions' => Spatie\MediaLibrary\Jobs\PerformConversions::class,
'generate_responsive_images' => Spatie\MediaLibrary\Jobs\GenerateResponsiveImages::class,
],
];
<?php
return [
'default' => env('QUEUE_CONNECTION', 'sync'),
'connections' => [
'sync' => [
'driver' => 'sync',
],
'database' => [
'driver' => 'database',
'table' => 'jobs',
'queue' => 'default',
'retry_after' => 90,
],
'beanstalkd' => [
'driver' => 'beanstalkd',
'host' => 'localhost',
'queue' => 'default',
'retry_after' => 90,
'block_for' => 0,
],
'sqs' => [
'driver' => 'sqs',
'key' => env('AWS_ACCESS_KEY_ID'),
'secret' => env('AWS_SECRET_ACCESS_KEY'),
'prefix' => env('SQS_PREFIX', 'https://sqs.us-east-1.amazonaws.com/your-account-id'),
'queue' => env('SQS_QUEUE', 'your-queue-name'),
'region' => env('AWS_DEFAULT_REGION', 'us-east-1'),
],
'redis' => [
'driver' => 'redis',
'connection' => 'default',
'queue' => env('REDIS_QUEUE', 'default'),
'retry_after' => 90,
'block_for' => null,
],
],
'failed' => [
'driver' => env('QUEUE_FAILED_DRIVER', 'database'),
'database' => env('DB_CONNECTION', 'mysql'),
'table' => 'failed_jobs',
],
];
<?php
return [
'mailgun' => [
'domain' => env('MAILGUN_DOMAIN'),
'secret' => env('MAILGUN_SECRET'),
'endpoint' => env('MAILGUN_ENDPOINT', 'api.mailgun.net'),
],
'postmark' => [
'token' => env('POSTMARK_TOKEN'),
],
'ses' => [
'key' => env('AWS_ACCESS_KEY_ID'),
'secret' => env('AWS_SECRET_ACCESS_KEY'),
'region' => env('AWS_DEFAULT_REGION', 'us-east-1'),
],
];
<?php
use Illuminate\Support\Str;
return [
'driver' => env('SESSION_DRIVER', 'cookie'),
'lifetime' => env('SESSION_LIFETIME', 120),
'expire_on_close' => false,
'encrypt' => false,
'files' => storage_path('framework/sessions'),
'connection' => env('SESSION_CONNECTION', null),
'table' => 'sessions',
'store' => env('SESSION_STORE', null),
'lottery' => [2, 100],
'cookie' => env(
'SESSION_COOKIE',
Str::slug(env('APP_NAME', 'laravel'), '_') . '_session'
),
'path' => '/',
'domain' => env('SESSION_DOMAIN', null),
'secure' => env('SESSION_SECURE_COOKIE', false),
'http_only' => true,
'same_site' => null,
];
<?php
return [
'use_saving_service' => true,
'locale_key_name' => 'locale',
];
<?php
return [
'paths' => [
resource_path('views'),
],
'compiled' => env(
'VIEW_COMPILED_PATH',
realpath(storage_path('framework/views'))
),
];
*.sqlite
*.sqlite-journal
<?php
/** @var \Illuminate\Database\Eloquent\Factory $factory */
use App\Models\Users\User;
use Faker\Generator as Faker;
use Illuminate\Support\Str;
$factory->define(User::class, static function (Faker $faker) {
return [
'login' => $faker->name,
'email' => $faker->unique()->safeEmail,
'email_verified_at' => now(),
'password' => Hash::make('Pa$$w0rD'),
'remember_token' => Str::random(10),
];
});
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
/**
* Class CreateUsersTable
*/
class CreateUsersTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up(): void
{
Schema::create('users', static function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('login');
$table->string('email')->unique();
$table->timestamp('email_verified_at')->nullable();
$table->string('password');
$table->rememberToken();
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down(): void
{
Schema::dropIfExists('users');
}
}
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
/**
* Class CreateRegionsTable
*/
class CreateRegionsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up(): void
{
Schema::create('regions', static function (Blueprint $table) {
$table->increments('id');
$table->string('alias', 2);
$table->timestamps();
$table->unique('alias');
});
Schema::create('region_translations', static function (Blueprint $table) {
$table->increments('id');
$table->unsignedInteger('region_id');
$table->string('locale');
$table->string('name');
$table->timestamps();
$table->unique(['locale', 'region_id']);
$table->foreign('region_id')->references('id')->on('regions')
->onUpdate('cascade')->onDelete('cascade');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down(): void
{
Schema::dropIfExists('region_translations');
Schema::dropIfExists('regions');
}
}
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
/**
* Class CreateDistrictsTable
*/
class CreateDistrictsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up(): void
{
Schema::create('districts', static function (Blueprint $table) {
$table->increments('id');
$table->unsignedInteger('region_id');
$table->string('alias');
$table->timestamps();
$table->foreign('region_id')->references('id')->on('regions')
->onUpdate('cascade')->onDelete('cascade');
$table->unique(['region_id', 'alias']);
});
Schema::create('district_translations', static function (Blueprint $table) {
$table->increments('id');
$table->unsignedInteger('district_id');
$table->string('locale');
$table->string('name');
$table->timestamps();
$table->unique(['locale', 'district_id']);
$table->foreign('district_id')->references('id')->on('districts')
->onUpdate('cascade')->onDelete('cascade');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down(): void
{
Schema::dropIfExists('district_translations');
Schema::dropIfExists('districts');
}
}
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateCitiesTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up(): void
{
Schema::create('cities', static function (Blueprint $table) {
$table->increments('id');
$table->unsignedInteger('district_id');
$table->string('alias');
$table->string('mayor')->nullable();
$table->string('address')->nullable();
$table->string('phone')->nullable();
$table->string('fax')->nullable();
$table->string('email')->nullable();
$table->string('web')->nullable();
$table->string('geo')->nullable();
$table->timestamps();
$table->unique(['district_id', 'alias']);
$table->foreign('district_id')->references('id')->on('districts')
->onUpdate('cascade')->onDelete('cascade');
});
Schema::create('city_translations', static function (Blueprint $table) {
$table->increments('id');
$table->unsignedInteger('city_id');
$table->string('locale');
$table->string('name');
$table->timestamps();
$table->unique(['locale', 'city_id']);
$table->foreign('city_id')->references('id')->on('cities')
->onUpdate('cascade')->onDelete('cascade');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down(): void
{
Schema::dropIfExists('cities');
Schema::dropIfExists('city_translations');
}
}
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
/**
* Class CreateMediaTable
*/
class CreateMediaTable extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('media', static function (Blueprint $table) {
$table->bigIncrements('id');
$table->morphs('model');
$table->string('collection_name');
$table->string('name');
$table->string('file_name');
$table->string('mime_type')->nullable();
$table->string('disk');
$table->unsignedBigInteger('size');
$table->json('manipulations');
$table->json('custom_properties');
$table->json('responsive_images');
$table->unsignedInteger('order_column')->nullable();
$table->nullableTimestamps();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('media');
}
}
<?php
use Illuminate\Database\Seeder;
/**
* Class DatabaseSeeder
*/
class DatabaseSeeder extends Seeder
{
/**
* Seed the application's database.
*
* @return void
*/
public function run(): void
{
$this->call([
RegionSeeder::class
]);
}
}
<?php
use Illuminate\Database\Seeder;
use App\Models\Regions\Region;
/**
* Class RegionSeeder
*/
class RegionSeeder extends Seeder
{
/**
* Seed regions.
*
* @return void
*/
public function run(): void
{
/** @var Region $region */
$region = Region::query()->firstOrCreate(['alias' => 'NR'], ['id' => 1, 'alias' => 'NR', 'name' => 'Nitra']);
$region->storeTranslation('sk', ['name' => 'Nitriansky']);
}
}
{
"private": true,
"scripts": {
"dev": "npm run development",
"development": "cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js",
"watch": "npm run development -- --watch",
"watch-poll": "npm run watch -- --watch-poll",
"hot": "cross-env NODE_ENV=development node_modules/webpack-dev-server/bin/webpack-dev-server.js --inline --hot --config=node_modules/laravel-mix/setup/webpack.config.js",
"prod": "npm run production",
"production": "cross-env NODE_ENV=production node_modules/webpack/bin/webpack.js --no-progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js"
},
"devDependencies": {
"axios": "^0.19",
"bootstrap": "^4.0.0",
"cross-env": "^5.1",
"jquery": "^3.2",
"laravel-mix": "^4.0.7",
"lodash": "^4.17.13",
"popper.js": "^1.12",
"resolve-url-loader": "^2.3.1",
"sass": "^1.15.2",
"sass-loader": "^7.1.0",
"vue-template-compiler": "^2.6.11"
},
"dependencies": {
"bootstrap-3-typeahead": "^4.0.2"
}
}
<?xml version="1.0" encoding="UTF-8"?>
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="./vendor/phpunit/phpunit/phpunit.xsd"
backupGlobals="false"
backupStaticAttributes="false"
bootstrap="vendor/autoload.php"
colors="true"
convertErrorsToExceptions="true"
convertNoticesToExceptions="true"
convertWarningsToExceptions="true"
processIsolation="false"
stopOnFailure="false">
<testsuites>
<testsuite name="Unit">
<directory suffix="Test.php">./tests/Unit</directory>
</testsuite>
<testsuite name="Feature">
<directory suffix="Test.php">./tests/Feature</directory>
</testsuite>
</testsuites>
<filter>
<whitelist processUncoveredFilesFromWhitelist="true">
<directory suffix=".php">./app</directory>
</whitelist>
</filter>
<php>
<server name="APP_ENV" value="testing"/>
<server name="BCRYPT_ROUNDS" value="4"/>
<server name="CACHE_DRIVER" value="array"/>
<server name="DB_CONNECTION" value="sqlite"/>
<server name="DB_DATABASE" value=":memory:"/>
<server name="MAIL_DRIVER" value="array"/>
<server name="QUEUE_CONNECTION" value="sync"/>
<server name="SESSION_DRIVER" value="array"/>
</php>
</phpunit>
<IfModule mod_rewrite.c>
<IfModule mod_negotiation.c>
Options -MultiViews -Indexes
</IfModule>
RewriteEngine On
# Handle Authorization Header
RewriteCond %{HTTP:Authorization} .
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
# Redirect Trailing Slashes If Not A Folder...
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} (.+)/$
RewriteRule ^ %1 [L,R=301]
# Handle Front Controller...
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [L]
</IfModule>
This source diff could not be displayed because it is too large. You can view the blob instead.
<?php
/**
* Laravel - A PHP Framework For Web Artisans
*
* @package Laravel
* @author Taylor Otwell <taylor@laravel.com>
*/
define('LARAVEL_START', microtime(true));
require __DIR__ . '/../vendor/autoload.php';
$app = require __DIR__ . '/../bootstrap/app.php';
$kernel = $app->make(Illuminate\Contracts\Http\Kernel::class);
$response = $kernel->handle(
$request = Illuminate\Http\Request::capture()
);
$response->send();
$kernel->terminate($request, $response);
This source diff could not be displayed because it is too large. You can view the blob instead.
/******/ (function(modules) { // webpackBootstrap
/******/ // install a JSONP callback for chunk loading
/******/ function webpackJsonpCallback(data) {
/******/ var chunkIds = data[0];
/******/ var moreModules = data[1];
/******/ var executeModules = data[2];
/******/
/******/ // add "moreModules" to the modules object,
/******/ // then flag all "chunkIds" as loaded and fire callback
/******/ var moduleId, chunkId, i = 0, resolves = [];
/******/ for(;i < chunkIds.length; i++) {
/******/ chunkId = chunkIds[i];
/******/ if(Object.prototype.hasOwnProperty.call(installedChunks, chunkId) && installedChunks[chunkId]) {
/******/ resolves.push(installedChunks[chunkId][0]);
/******/ }
/******/ installedChunks[chunkId] = 0;
/******/ }
/******/ for(moduleId in moreModules) {
/******/ if(Object.prototype.hasOwnProperty.call(moreModules, moduleId)) {
/******/ modules[moduleId] = moreModules[moduleId];
/******/ }
/******/ }
/******/ if(parentJsonpFunction) parentJsonpFunction(data);
/******/
/******/ while(resolves.length) {
/******/ resolves.shift()();
/******/ }
/******/
/******/ // add entry modules from loaded chunk to deferred list
/******/ deferredModules.push.apply(deferredModules, executeModules || []);
/******/
/******/ // run deferred modules when all chunks ready
/******/ return checkDeferredModules();
/******/ };
/******/ function checkDeferredModules() {
/******/ var result;
/******/ for(var i = 0; i < deferredModules.length; i++) {
/******/ var deferredModule = deferredModules[i];
/******/ var fulfilled = true;
/******/ for(var j = 1; j < deferredModule.length; j++) {
/******/ var depId = deferredModule[j];
/******/ if(installedChunks[depId] !== 0) fulfilled = false;
/******/ }
/******/ if(fulfilled) {
/******/ deferredModules.splice(i--, 1);
/******/ result = __webpack_require__(__webpack_require__.s = deferredModule[0]);
/******/ }
/******/ }
/******/
/******/ return result;
/******/ }
/******/
/******/ // The module cache
/******/ var installedModules = {};
/******/
/******/ // object to store loaded and loading chunks
/******/ // undefined = chunk not loaded, null = chunk preloaded/prefetched
/******/ // Promise = chunk loading, 0 = chunk loaded
/******/ var installedChunks = {
/******/ "/js/manifest": 0
/******/ };
/******/
/******/ var deferredModules = [];
/******/
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/
/******/ // Check if module is in cache
/******/ if(installedModules[moduleId]) {
/******/ return installedModules[moduleId].exports;
/******/ }
/******/ // Create a new module (and put it into the cache)
/******/ var module = installedModules[moduleId] = {
/******/ i: moduleId,
/******/ l: false,
/******/ exports: {}
/******/ };
/******/
/******/ // Execute the module function
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/ // Flag the module as loaded
/******/ module.l = true;
/******/
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
/******/
/******/
/******/ // expose the modules object (__webpack_modules__)
/******/ __webpack_require__.m = modules;
/******/
/******/ // expose the module cache
/******/ __webpack_require__.c = installedModules;
/******/
/******/ // define getter function for harmony exports
/******/ __webpack_require__.d = function(exports, name, getter) {
/******/ if(!__webpack_require__.o(exports, name)) {
/******/ Object.defineProperty(exports, name, { enumerable: true, get: getter });
/******/ }
/******/ };
/******/
/******/ // define __esModule on exports
/******/ __webpack_require__.r = function(exports) {
/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
/******/ }
/******/ Object.defineProperty(exports, '__esModule', { value: true });
/******/ };
/******/
/******/ // create a fake namespace object
/******/ // mode & 1: value is a module id, require it
/******/ // mode & 2: merge all properties of value into the ns
/******/ // mode & 4: return value when already ns object
/******/ // mode & 8|1: behave like require
/******/ __webpack_require__.t = function(value, mode) {
/******/ if(mode & 1) value = __webpack_require__(value);
/******/ if(mode & 8) return value;
/******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;
/******/ var ns = Object.create(null);
/******/ __webpack_require__.r(ns);
/******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value });
/******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));
/******/ return ns;
/******/ };
/******/
/******/ // getDefaultExport function for compatibility with non-harmony modules
/******/ __webpack_require__.n = function(module) {
/******/ var getter = module && module.__esModule ?
/******/ function getDefault() { return module['default']; } :
/******/ function getModuleExports() { return module; };
/******/ __webpack_require__.d(getter, 'a', getter);
/******/ return getter;
/******/ };
/******/
/******/ // Object.prototype.hasOwnProperty.call
/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
/******/
/******/ // __webpack_public_path__
/******/ __webpack_require__.p = "/";
/******/
/******/ var jsonpArray = window["webpackJsonp"] = window["webpackJsonp"] || [];
/******/ var oldJsonpFunction = jsonpArray.push.bind(jsonpArray);
/******/ jsonpArray.push = webpackJsonpCallback;
/******/ jsonpArray = jsonpArray.slice();
/******/ for(var i = 0; i < jsonpArray.length; i++) webpackJsonpCallback(jsonpArray[i]);
/******/ var parentJsonpFunction = oldJsonpFunction;
/******/
/******/
/******/ // run deferred modules from other chunks
/******/ checkDeferredModules();
/******/ })
/************************************************************************/
/******/ ([]);
\ No newline at end of file
(window["webpackJsonp"] = window["webpackJsonp"] || []).push([["/js/vendor"],[
/* 0 */,
/* 1 */
/*!************************************!*\
!*** multi bootstrap-autocomplete ***!
\************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {
!(function webpackMissingModule() { var e = new Error("Cannot find module 'bootstrap-autocomplete'"); e.code = 'MODULE_NOT_FOUND'; throw e; }());
/***/ })
],[[1,"/js/manifest"]]]);
\ No newline at end of file
{
"/js/app.js": "/js/app.js?id=b991cd6638c6e7539a57",
"/css/app.css": "/css/app.css?id=fedfd9a92a8069ce5f81"
}
User-agent: *
Disallow: /
require('./bootstrap');
require('bootstrap-3-typeahead');
window._ = require('lodash');
try {
window.Popper = require('popper.js').default;
window.$ = window.jQuery = require('jquery');
require('bootstrap');
} catch (e) {
console.warn('Can\t load bootstrap with dependencies');
}
window.axios = require('axios');
window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
$.actions = {
init: function () {
this.search();
},
search: function () {
let route = $('#search').data('route');
$('#search').typeahead({
source: function (search, process) {
return $.get(route, { search: search }, function (data) {
return process(data);
});
}
});
}
};
$(function () {
$.actions.init();
});
<?php
return [
'failed' => 'These credentials do not match our records.',
'throttle' => 'Too many login attempts. Please try again in :seconds seconds.',
];
<?php
return [
'previous' => '&laquo; Previous',
'next' => 'Next &raquo;',
];
<?php
return [
'region.start' => 'Start parsing region ":name"',
'region.queued' => 'Region ":name": all tasks were added to queue.',
'city.geolocate' => 'Start geolocation ":name".',
];
<?php
return [
'reset' => 'Your password has been reset!',
'sent' => 'We have e-mailed your password reset link!',
'throttled' => 'Please wait before retrying.',
'token' => 'This password reset token is invalid.',
'user' => "We can't find a user with that e-mail address.",
];
<?php
return [
'menu.register' => 'Registration',
];
<?php
return [
'accepted' => 'The :attribute must be accepted.',
'active_url' => 'The :attribute is not a valid URL.',
'after' => 'The :attribute must be a date after :date.',
'after_or_equal' => 'The :attribute must be a date after or equal to :date.',
'alpha' => 'The :attribute may only contain letters.',
'alpha_dash' => 'The :attribute may only contain letters, numbers, dashes and underscores.',
'alpha_num' => 'The :attribute may only contain letters and numbers.',
'array' => 'The :attribute must be an array.',
'before' => 'The :attribute must be a date before :date.',
'before_or_equal' => 'The :attribute must be a date before or equal to :date.',
'between' => [
'numeric' => 'The :attribute must be between :min and :max.',
'file' => 'The :attribute must be between :min and :max kilobytes.',
'string' => 'The :attribute must be between :min and :max characters.',
'array' => 'The :attribute must have between :min and :max items.',
],
'boolean' => 'The :attribute field must be true or false.',
'confirmed' => 'The :attribute confirmation does not match.',
'date' => 'The :attribute is not a valid date.',
'date_equals' => 'The :attribute must be a date equal to :date.',
'date_format' => 'The :attribute does not match the format :format.',
'different' => 'The :attribute and :other must be different.',
'digits' => 'The :attribute must be :digits digits.',
'digits_between' => 'The :attribute must be between :min and :max digits.',
'dimensions' => 'The :attribute has invalid image dimensions.',
'distinct' => 'The :attribute field has a duplicate value.',
'email' => 'The :attribute must be a valid email address.',
'ends_with' => 'The :attribute must end with one of the following: :values',
'exists' => 'The selected :attribute is invalid.',
'file' => 'The :attribute must be a file.',
'filled' => 'The :attribute field must have a value.',
'gt' => [
'numeric' => 'The :attribute must be greater than :value.',
'file' => 'The :attribute must be greater than :value kilobytes.',
'string' => 'The :attribute must be greater than :value characters.',
'array' => 'The :attribute must have more than :value items.',
],
'gte' => [
'numeric' => 'The :attribute must be greater than or equal :value.',
'file' => 'The :attribute must be greater than or equal :value kilobytes.',
'string' => 'The :attribute must be greater than or equal :value characters.',
'array' => 'The :attribute must have :value items or more.',
],
'image' => 'The :attribute must be an image.',
'in' => 'The selected :attribute is invalid.',
'in_array' => 'The :attribute field does not exist in :other.',
'integer' => 'The :attribute must be an integer.',
'ip' => 'The :attribute must be a valid IP address.',
'ipv4' => 'The :attribute must be a valid IPv4 address.',
'ipv6' => 'The :attribute must be a valid IPv6 address.',
'json' => 'The :attribute must be a valid JSON string.',
'lt' => [
'numeric' => 'The :attribute must be less than :value.',
'file' => 'The :attribute must be less than :value kilobytes.',
'string' => 'The :attribute must be less than :value characters.',
'array' => 'The :attribute must have less than :value items.',
],
'lte' => [
'numeric' => 'The :attribute must be less than or equal :value.',
'file' => 'The :attribute must be less than or equal :value kilobytes.',
'string' => 'The :attribute must be less than or equal :value characters.',
'array' => 'The :attribute must not have more than :value items.',
],
'max' => [
'numeric' => 'The :attribute may not be greater than :max.',
'file' => 'The :attribute may not be greater than :max kilobytes.',
'string' => 'The :attribute may not be greater than :max characters.',
'array' => 'The :attribute may not have more than :max items.',
],
'mimes' => 'The :attribute must be a file of type: :values.',
'mimetypes' => 'The :attribute must be a file of type: :values.',
'min' => [
'numeric' => 'The :attribute must be at least :min.',
'file' => 'The :attribute must be at least :min kilobytes.',
'string' => 'The :attribute must be at least :min characters.',
'array' => 'The :attribute must have at least :min items.',
],
'not_in' => 'The selected :attribute is invalid.',
'not_regex' => 'The :attribute format is invalid.',
'numeric' => 'The :attribute must be a number.',
'password' => 'The password is incorrect.',
'present' => 'The :attribute field must be present.',
'regex' => 'The :attribute format is invalid.',
'required' => 'The :attribute field is required.',
'required_if' => 'The :attribute field is required when :other is :value.',
'required_unless' => 'The :attribute field is required unless :other is in :values.',
'required_with' => 'The :attribute field is required when :values is present.',
'required_with_all' => 'The :attribute field is required when :values are present.',
'required_without' => 'The :attribute field is required when :values is not present.',
'required_without_all' => 'The :attribute field is required when none of :values are present.',
'same' => 'The :attribute and :other must match.',
'size' => [
'numeric' => 'The :attribute must be :size.',
'file' => 'The :attribute must be :size kilobytes.',
'string' => 'The :attribute must be :size characters.',
'array' => 'The :attribute must contain :size items.',
],
'starts_with' => 'The :attribute must start with one of the following: :values',
'string' => 'The :attribute must be a string.',
'timezone' => 'The :attribute must be a valid zone.',
'unique' => 'The :attribute has already been taken.',
'uploaded' => 'The :attribute failed to upload.',
'url' => 'The :attribute format is invalid.',
'uuid' => 'The :attribute must be a valid UUID.',
'custom' => [
'attribute-name' => [
'rule-name' => 'custom-message',
],
],
'attributes' => [],
];
.full-height {
height: 100vh;
}
.flex-center {
align-items: center;
display: flex;
justify-content: center;
}
// Body
$body-bg: #f8fafc;
// Typography
$font-family-sans-serif: 'Nunito', sans-serif;
$font-size-base: 0.9rem;
$line-height-base: 1.6;
// Colors
$blue: #3490dc;
$indigo: #6574cd;
$purple: #9561e2;
$pink: #f66d9b;
$red: #e3342f;
$orange: #f6993f;
$yellow: #ffed4a;
$green: #38c172;
$teal: #07d3a9;
$cyan: #0b86f2;
$grey: #dfdfdf;
$border-radius: 2px !default;
//I hate bootstrap's box-shadows
$input-btn-focus-width: 0 !default;
$theme-colors: (
"teal": $teal,
"grey": $grey,
"cyan": $cyan,
);
// Fonts
@import url('https://fonts.googleapis.com/css?family=Nunito');
// Variables
@import 'variables';
// Bootstrap
@import '~bootstrap/scss/bootstrap';
@import 'custom';
@extends('layouts.main')
@section('content')
<h1>{{__('Details')}}</h1>
<div class="content">
@if(empty($city))
{{__('City not found')}}
@else
<p>
{{__('Name')}} : {{ $city->name }}
</p>
<p>
{{__('Mayor')}} : {{ $city->mayor }}
</p>
<p>
{{__('Phone')}} : {{ $city->phones->implode(', ') }}
</p>
<p>
{{__('Fax')}}:{{ $city->faxes->implode(', ') }}
</p>
<p>
{{__('Email')}} : {{ $city->emails->implode(', ') }}
</p>
<p>
{{__('Web')}} : {{ $city->sites->implode(', ') }}
</p>
<p>
{{__('Location')}} : {{ $city->coordinates->implode(', ') }}
</p>
@endif
</div>
@endsection
<footer class="page-footer font-small bg-grey p-1">
<div class="footer-copyright text-center">&copy; {{date('Y', time())}}
<a href="{{route('home')}}">{{config('app.name')}}</a>
</div>
</footer>
@php($currentLocale = app()->getLocale())
<nav class="navbar navbar-expand-lg bg-light fixed-top border-bottom">
<div class="collapse navbar-collapse d-flex flex-row align-items-end" id="navbarSupportedContent">
<div class="logo flex-grow-1">
</div>
<div class="mr-2">
<div class="btn-group">
<button type="button" class="btn btn-light dropdown-toggle" data-toggle="dropdown" aria-haspopup="true"
aria-expanded="false">
{{strtoupper($currentLocale)}}
</button>
<div class="dropdown-menu">
@foreach(LaravelLocalization::getSupportedLocales() as $code => $locale)
@if($code !== $currentLocale)
<a class="dropdown-item" href="{{LaravelLocalization::getLocalizedURL($code, null, [], true)}}">
{{$locale['native']}}
</a>
@endif
@endforeach
</div>
</div>
</div>
</div>
</nav>
@extends('layouts.main')
@section('content')
<form action="{{ route('city') }}">
<div class="form-group">
<label for="search">Search</label>
<input type="text" name="search" id="search" autocomplete="off" data-route="{{ route('search') }}">
</div>
</form>
@endsection
<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="csrf-token" content="{{ csrf_token() }}">
<title>Laravel</title>
<!-- Styles -->
<link rel="stylesheet" type="text/css" href="{{ url(mix('css/app.css')) }}">
</head>
<body class="d-flex flex-column full-height">
@include('components.header')
<div class="flex-center position-ref full-height">
<div class="content">
@yield('content')
</div>
</div>
@include('components.footer')
<script type="text/javascript" src="{{ url(mix('js/app.js')) }}"></script>
</body>
</html>
<?php
use Illuminate\Http\Request;
use Illuminate\Http\Response;
Route::get('/', static function () {
return ['online' => true];
});
Route::group(['middleware' => 'auth:api'], static function () {
});
Route::fallback(static function () {
return Response::create(['error' => 'Not found'], 404);
});
<?php
Route::group(['prefix' => LaravelLocalization::setLocale(),
'middleware' => ['localeSessionRedirect', 'localizationRedirect', 'localeViewPath']
], static function () {
Route::get('/', 'HomeController@index')->name('home');
Route::get('home', 'HomeController@search')->name('search');
Route::get('city', 'HomeController@city')->name('city');
});
<?php
/**
* Laravel - A PHP Framework For Web Artisans
*
* @package Laravel
* @author Taylor Otwell <taylor@laravel.com>
*/
$uri = urldecode(
parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH)
);
// This file allows us to emulate Apache's "mod_rewrite" functionality from the
// built-in PHP web server. This provides a convenient way to test a Laravel
// application without having installed a "real" web server software here.
if ($uri !== '/' && file_exists(__DIR__.'/public'.$uri)) {
return false;
}
require_once __DIR__.'/public/index.php';
*
!public/
!.gitignore
config.php
routes.php
schedule-*
compiled.php
services.json
events.scanned.php
routes.scanned.php
down
const mix = require('laravel-mix');
mix
.js(['resources/js/app.js', 'resources/js/custom.js'], 'public/js')
.sass('resources/sass/app.scss', 'public/css')
.version([
'public/css/app.css',
'public/js/app.js'
]);
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment