From c966f3823629d1a420a3c9db8d2a67235b417d88 Mon Sep 17 00:00:00 2001 From: amirghasempoor Date: Mon, 28 Apr 2025 13:20:33 +0330 Subject: [PATCH 1/2] install api --- laravel/bootstrap/app.php | 3 +- laravel/composer.json | 3 +- laravel/composer.lock | 66 ++++++++++++++- laravel/config/cors.php | 34 ++++++++ laravel/config/sanctum.php | 84 +++++++++++++++++++ ...38_create_personal_access_tokens_table.php | 33 ++++++++ laravel/routes/api.php | 8 ++ 7 files changed, 228 insertions(+), 3 deletions(-) create mode 100644 laravel/config/cors.php create mode 100644 laravel/config/sanctum.php create mode 100644 laravel/database/migrations/2025_04_28_080638_create_personal_access_tokens_table.php create mode 100644 laravel/routes/api.php diff --git a/laravel/bootstrap/app.php b/laravel/bootstrap/app.php index 7b162da..0866663 100644 --- a/laravel/bootstrap/app.php +++ b/laravel/bootstrap/app.php @@ -7,11 +7,12 @@ use Illuminate\Foundation\Configuration\Middleware; return Application::configure(basePath: dirname(__DIR__)) ->withRouting( web: __DIR__.'/../routes/web.php', + api: __DIR__.'/../routes/api.php', commands: __DIR__.'/../routes/console.php', health: '/up', ) ->withMiddleware(function (Middleware $middleware) { - // + $middleware->web()->statefulApi(); }) ->withExceptions(function (Exceptions $exceptions) { // diff --git a/laravel/composer.json b/laravel/composer.json index 7ee5043..83f714b 100644 --- a/laravel/composer.json +++ b/laravel/composer.json @@ -11,6 +11,7 @@ "require": { "php": "^8.2", "laravel/framework": "^12.0", + "laravel/sanctum": "^4.0", "laravel/tinker": "^2.10.1" }, "require-dev": { @@ -75,4 +76,4 @@ }, "minimum-stability": "stable", "prefer-stable": true -} \ No newline at end of file +} diff --git a/laravel/composer.lock b/laravel/composer.lock index 5c50b48..17d705c 100644 --- a/laravel/composer.lock +++ b/laravel/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "88970a0117c062eed55fa8728fc43833", + "content-hash": "85c1d2065f70e38b0d6bf66559fb13c5", "packages": [ { "name": "brick/math", @@ -1328,6 +1328,70 @@ }, "time": "2025-02-11T13:34:40+00:00" }, + { + "name": "laravel/sanctum", + "version": "v4.1.0", + "source": { + "type": "git", + "url": "https://github.com/laravel/sanctum.git", + "reference": "4e4ced5023e9d8949214e0fb43d9f4bde79c7166" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/laravel/sanctum/zipball/4e4ced5023e9d8949214e0fb43d9f4bde79c7166", + "reference": "4e4ced5023e9d8949214e0fb43d9f4bde79c7166", + "shasum": "" + }, + "require": { + "ext-json": "*", + "illuminate/console": "^11.0|^12.0", + "illuminate/contracts": "^11.0|^12.0", + "illuminate/database": "^11.0|^12.0", + "illuminate/support": "^11.0|^12.0", + "php": "^8.2", + "symfony/console": "^7.0" + }, + "require-dev": { + "mockery/mockery": "^1.6", + "orchestra/testbench": "^9.0|^10.0", + "phpstan/phpstan": "^1.10", + "phpunit/phpunit": "^11.3" + }, + "type": "library", + "extra": { + "laravel": { + "providers": [ + "Laravel\\Sanctum\\SanctumServiceProvider" + ] + } + }, + "autoload": { + "psr-4": { + "Laravel\\Sanctum\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylor@laravel.com" + } + ], + "description": "Laravel Sanctum provides a featherweight authentication system for SPAs and simple APIs.", + "keywords": [ + "auth", + "laravel", + "sanctum" + ], + "support": { + "issues": "https://github.com/laravel/sanctum/issues", + "source": "https://github.com/laravel/sanctum" + }, + "time": "2025-04-22T13:53:47+00:00" + }, { "name": "laravel/serializable-closure", "version": "v2.0.4", diff --git a/laravel/config/cors.php b/laravel/config/cors.php new file mode 100644 index 0000000..94f07be --- /dev/null +++ b/laravel/config/cors.php @@ -0,0 +1,34 @@ + ['api/*', 'sanctum/csrf-cookie'], + + 'allowed_methods' => ['*'], + + 'allowed_origins' => ['*'], + + 'allowed_origins_patterns' => [], + + 'allowed_headers' => ['*'], + + 'exposed_headers' => [], + + 'max_age' => 0, + + 'supports_credentials' => true, + +]; diff --git a/laravel/config/sanctum.php b/laravel/config/sanctum.php new file mode 100644 index 0000000..d530183 --- /dev/null +++ b/laravel/config/sanctum.php @@ -0,0 +1,84 @@ + explode(',', env('SANCTUM_STATEFUL_DOMAINS', sprintf( + '%s%s', + 'localhost,localhost:3000,127.0.0.1,127.0.0.1:8000,::1', + Sanctum::currentApplicationUrlWithPort(), +// Sanctum::currentRequestHost(), + ))), + + /* + |-------------------------------------------------------------------------- + | Sanctum Guards + |-------------------------------------------------------------------------- + | + | This array contains the authentication guards that will be checked when + | Sanctum is trying to authenticate a request. If none of these guards + | are able to authenticate the request, Sanctum will use the bearer + | token that's present on an incoming request for authentication. + | + */ + + 'guard' => ['web'], + + /* + |-------------------------------------------------------------------------- + | Expiration Minutes + |-------------------------------------------------------------------------- + | + | This value controls the number of minutes until an issued token will be + | considered expired. This will override any values set in the token's + | "expires_at" attribute, but first-party sessions are not affected. + | + */ + + 'expiration' => null, + + /* + |-------------------------------------------------------------------------- + | Token Prefix + |-------------------------------------------------------------------------- + | + | Sanctum can prefix new tokens in order to take advantage of numerous + | security scanning initiatives maintained by open source platforms + | that notify developers if they commit tokens into repositories. + | + | See: https://docs.github.com/en/code-security/secret-scanning/about-secret-scanning + | + */ + + 'token_prefix' => env('SANCTUM_TOKEN_PREFIX', ''), + + /* + |-------------------------------------------------------------------------- + | Sanctum Middleware + |-------------------------------------------------------------------------- + | + | When authenticating your first-party SPA with Sanctum you may need to + | customize some of the middleware Sanctum uses while processing the + | request. You may change the middleware listed below as required. + | + */ + + 'middleware' => [ + 'authenticate_session' => Laravel\Sanctum\Http\Middleware\AuthenticateSession::class, + 'encrypt_cookies' => Illuminate\Cookie\Middleware\EncryptCookies::class, + 'validate_csrf_token' => Illuminate\Foundation\Http\Middleware\ValidateCsrfToken::class, + ], + +]; diff --git a/laravel/database/migrations/2025_04_28_080638_create_personal_access_tokens_table.php b/laravel/database/migrations/2025_04_28_080638_create_personal_access_tokens_table.php new file mode 100644 index 0000000..e828ad8 --- /dev/null +++ b/laravel/database/migrations/2025_04_28_080638_create_personal_access_tokens_table.php @@ -0,0 +1,33 @@ +id(); + $table->morphs('tokenable'); + $table->string('name'); + $table->string('token', 64)->unique(); + $table->text('abilities')->nullable(); + $table->timestamp('last_used_at')->nullable(); + $table->timestamp('expires_at')->nullable(); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('personal_access_tokens'); + } +}; diff --git a/laravel/routes/api.php b/laravel/routes/api.php new file mode 100644 index 0000000..ccc387f --- /dev/null +++ b/laravel/routes/api.php @@ -0,0 +1,8 @@ +user(); +})->middleware('auth:sanctum'); From fb750a0dc84caec0f1317f6dfef895f1ff3dc123 Mon Sep 17 00:00:00 2001 From: amirghasempoor Date: Mon, 28 Apr 2025 16:32:12 +0330 Subject: [PATCH 2/2] auth with session --- docker-compose.yml | 8 +- laravel/Dockerfile | 4 +- .../app/Http/Controllers/AuthController.php | 51 ++ .../Http/Controllers/ProfileController.php | 18 + .../app/Http/Requests/Auth/LoginRequest.php | 30 ++ laravel/app/Http/Traits/ApiResponse.php | 31 ++ laravel/app/Models/City.php | 12 + laravel/app/Models/Province.php | 12 + laravel/app/Models/User.php | 35 +- laravel/bootstrap/app.php | 5 +- laravel/config/cors.php | 2 +- laravel/database/factories/CityFactory.php | 23 + .../database/factories/ProvinceFactory.php | 23 + laravel/database/factories/UserFactory.php | 43 +- ...25_04_28_101821_create_provinces_table.php | 30 ++ .../2025_04_28_102048_create_cities_table.php | 29 ++ ... 2025_04_28_110000_create_users_table.php} | 24 +- laravel/database/seeders/CitySeeder.php | 19 + laravel/database/seeders/ProvinceSeeder.php | 19 + laravel/database/seeders/UserSeeder.php | 32 ++ laravel/routes/web.php | 20 +- laravel/storage/sql-files/cities.sql | 475 ++++++++++++++++++ laravel/storage/sql-files/provinces.sql | 36 ++ 23 files changed, 900 insertions(+), 81 deletions(-) create mode 100644 laravel/app/Http/Controllers/AuthController.php create mode 100644 laravel/app/Http/Controllers/ProfileController.php create mode 100644 laravel/app/Http/Requests/Auth/LoginRequest.php create mode 100644 laravel/app/Http/Traits/ApiResponse.php create mode 100644 laravel/app/Models/City.php create mode 100644 laravel/app/Models/Province.php create mode 100644 laravel/database/factories/CityFactory.php create mode 100644 laravel/database/factories/ProvinceFactory.php create mode 100644 laravel/database/migrations/2025_04_28_101821_create_provinces_table.php create mode 100644 laravel/database/migrations/2025_04_28_102048_create_cities_table.php rename laravel/database/migrations/{0001_01_01_000000_create_users_table.php => 2025_04_28_110000_create_users_table.php} (58%) create mode 100644 laravel/database/seeders/CitySeeder.php create mode 100644 laravel/database/seeders/ProvinceSeeder.php create mode 100644 laravel/database/seeders/UserSeeder.php create mode 100644 laravel/storage/sql-files/cities.sql create mode 100644 laravel/storage/sql-files/provinces.sql diff --git a/docker-compose.yml b/docker-compose.yml index 73eb7f6..2d10b86 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -3,13 +3,15 @@ services: image: postgres:17-alpine3.21 container_name: ${PROJECT_NAME}-pgsql ports: - - "8090:5432" + - "8050:5432" environment: POSTGRES_DB: ${POSTGRES_DB} POSTGRES_USER: ${POSTGRES_USER} POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} volumes: - ./data:/var/lib/postgresql/data + profiles: + - server # redis: # image: redis:7-alpine3.21 @@ -24,5 +26,5 @@ services: - "8080:8000" volumes: - ./laravel:/var/www/${PROJECT_NAME} - depends_on: - - postgres + profiles: + - server \ No newline at end of file diff --git a/laravel/Dockerfile b/laravel/Dockerfile index 56c9274..a8892be 100644 --- a/laravel/Dockerfile +++ b/laravel/Dockerfile @@ -46,7 +46,7 @@ ENV COMPOSER_ALLOW_SUPERUSER=1 ARG MOUNT_PATH -WORKDIR /var/www/netflix +WORKDIR /var/www/crm COPY . . CMD composer install;\ @@ -54,4 +54,4 @@ CMD composer install;\ php artisan migrate ;\ php artisan db:seed;\ # php artisan storege:link;\ - php artisan serve --host=0.0.0.0 + php artisan serve --host 0.0.0.0 diff --git a/laravel/app/Http/Controllers/AuthController.php b/laravel/app/Http/Controllers/AuthController.php new file mode 100644 index 0000000..543f53c --- /dev/null +++ b/laravel/app/Http/Controllers/AuthController.php @@ -0,0 +1,51 @@ +attemptLogin($request)) + { + $request->session()->regenerate(); + $this->updateLastLogin($request); + return $this->successResponse(); + } + + return $this->errorResponse(); + } + + protected function attemptLogin(Request $request): bool + { + return Auth::guard()->attempt($request->only('username', 'password')); + } + + protected function updateLastLogin(Request $request): void + { + if (!$request->session()->exists('last_login')) { + $request->session()->put('last_login', now()); + } + + Auth::user()->update([ + 'last_login' => now(), + ]); + } + + public function logout(Request $request): JsonResponse + { + Auth::guard()->logout(); + $request->session()->invalidate(); + $request->session()->regenerateToken(); + return $this->successResponse(); + } +} diff --git a/laravel/app/Http/Controllers/ProfileController.php b/laravel/app/Http/Controllers/ProfileController.php new file mode 100644 index 0000000..15ff651 --- /dev/null +++ b/laravel/app/Http/Controllers/ProfileController.php @@ -0,0 +1,18 @@ +successResponse(User::query()->find(auth()->id())); + } +} diff --git a/laravel/app/Http/Requests/Auth/LoginRequest.php b/laravel/app/Http/Requests/Auth/LoginRequest.php new file mode 100644 index 0000000..da0f86c --- /dev/null +++ b/laravel/app/Http/Requests/Auth/LoginRequest.php @@ -0,0 +1,30 @@ + + */ + public function rules(): array + { + return [ + 'username' => 'required|exists:users,username', + 'password' => 'required|string', + ]; + } +} diff --git a/laravel/app/Http/Traits/ApiResponse.php b/laravel/app/Http/Traits/ApiResponse.php new file mode 100644 index 0000000..fb818f1 --- /dev/null +++ b/laravel/app/Http/Traits/ApiResponse.php @@ -0,0 +1,31 @@ +json([ + 'data' => $data + ], $statusCode); + } + + $message = $message ?? __('messages.successful'); + + return response()->json([ + 'message' => $message + ], $statusCode); + } + + public function errorResponse(string|array $message, int $statusCode = 422): JsonResponse + { + return response()->json([ + 'message' => $message + ], $statusCode); + } +} diff --git a/laravel/app/Models/City.php b/laravel/app/Models/City.php new file mode 100644 index 0000000..3f3ec29 --- /dev/null +++ b/laravel/app/Models/City.php @@ -0,0 +1,12 @@ + */ + use HasFactory; +} diff --git a/laravel/app/Models/Province.php b/laravel/app/Models/Province.php new file mode 100644 index 0000000..115498c --- /dev/null +++ b/laravel/app/Models/Province.php @@ -0,0 +1,12 @@ + */ + use HasFactory; +} diff --git a/laravel/app/Models/User.php b/laravel/app/Models/User.php index 749c7b7..3d3ed38 100644 --- a/laravel/app/Models/User.php +++ b/laravel/app/Models/User.php @@ -9,40 +9,9 @@ use Illuminate\Notifications\Notifiable; class User extends Authenticatable { - /** @use HasFactory<\Database\Factories\UserFactory> */ use HasFactory, Notifiable; - /** - * The attributes that are mass assignable. - * - * @var list - */ - protected $fillable = [ - 'name', - 'email', - 'password', - ]; + protected $guarded = []; - /** - * The attributes that should be hidden for serialization. - * - * @var list - */ - protected $hidden = [ - 'password', - 'remember_token', - ]; - - /** - * Get the attributes that should be cast. - * - * @return array - */ - protected function casts(): array - { - return [ - 'email_verified_at' => 'datetime', - 'password' => 'hashed', - ]; - } + protected $hidden = ['password',]; } diff --git a/laravel/bootstrap/app.php b/laravel/bootstrap/app.php index 0866663..6178ce8 100644 --- a/laravel/bootstrap/app.php +++ b/laravel/bootstrap/app.php @@ -12,7 +12,10 @@ return Application::configure(basePath: dirname(__DIR__)) health: '/up', ) ->withMiddleware(function (Middleware $middleware) { - $middleware->web()->statefulApi(); + $middleware->validateCsrfTokens(except: [ + '/auth/login' // <-- exclude this route + ]); + $middleware->statefulApi(); }) ->withExceptions(function (Exceptions $exceptions) { // diff --git a/laravel/config/cors.php b/laravel/config/cors.php index 94f07be..a76728a 100644 --- a/laravel/config/cors.php +++ b/laravel/config/cors.php @@ -15,7 +15,7 @@ return [ | */ - 'paths' => ['api/*', 'sanctum/csrf-cookie'], + 'paths' => ['*'], 'allowed_methods' => ['*'], diff --git a/laravel/database/factories/CityFactory.php b/laravel/database/factories/CityFactory.php new file mode 100644 index 0000000..3629338 --- /dev/null +++ b/laravel/database/factories/CityFactory.php @@ -0,0 +1,23 @@ + + */ +class CityFactory extends Factory +{ + /** + * Define the model's default state. + * + * @return array + */ + public function definition(): array + { + return [ + // + ]; + } +} diff --git a/laravel/database/factories/ProvinceFactory.php b/laravel/database/factories/ProvinceFactory.php new file mode 100644 index 0000000..767b375 --- /dev/null +++ b/laravel/database/factories/ProvinceFactory.php @@ -0,0 +1,23 @@ + + */ +class ProvinceFactory extends Factory +{ + /** + * Define the model's default state. + * + * @return array + */ + public function definition(): array + { + return [ + // + ]; + } +} diff --git a/laravel/database/factories/UserFactory.php b/laravel/database/factories/UserFactory.php index 584104c..d2f93f3 100644 --- a/laravel/database/factories/UserFactory.php +++ b/laravel/database/factories/UserFactory.php @@ -2,43 +2,32 @@ namespace Database\Factories; +use App\Models\Province; +use App\Models\User; use Illuminate\Database\Eloquent\Factories\Factory; use Illuminate\Support\Facades\Hash; -use Illuminate\Support\Str; /** - * @extends \Illuminate\Database\Eloquent\Factories\Factory<\App\Models\User> + * @extends Factory */ class UserFactory extends Factory { - /** - * The current password being used by the factory. - */ - protected static ?string $password; - - /** - * Define the model's default state. - * - * @return array - */ public function definition(): array { return [ - 'name' => fake()->name(), - 'email' => fake()->unique()->safeEmail(), - 'email_verified_at' => now(), - 'password' => static::$password ??= Hash::make('password'), - 'remember_token' => Str::random(10), + 'full_name' => $this->faker->name(), + 'username' => $this->faker->userName(), + 'position' => $this->faker->randomElement(['boss', 'operator']), + 'gender' => $this->faker->randomElement(['female', 'male']), + 'national_id' => $this->faker->unique()->numerify('##########'), + 'phone_number' => '09' . $this->faker->unique()->randomNumber(9, true), + 'province_id' => Province::factory(), + 'province_fa' => function (array $attributes) { + return Province::query()->find($attributes['province_id'])->name; + }, + 'password' => Hash::make('password'), + 'email' => $this->faker->email, + 'telephone_id' => $this->faker->unique()->numerify('tel-####') ]; } - - /** - * Indicate that the model's email address should be unverified. - */ - public function unverified(): static - { - return $this->state(fn (array $attributes) => [ - 'email_verified_at' => null, - ]); - } } diff --git a/laravel/database/migrations/2025_04_28_101821_create_provinces_table.php b/laravel/database/migrations/2025_04_28_101821_create_provinces_table.php new file mode 100644 index 0000000..1c2a32b --- /dev/null +++ b/laravel/database/migrations/2025_04_28_101821_create_provinces_table.php @@ -0,0 +1,30 @@ +id(); + $table->string('name'); + $table->double('lat'); + $table->double('lon'); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('provinces'); + } +}; diff --git a/laravel/database/migrations/2025_04_28_102048_create_cities_table.php b/laravel/database/migrations/2025_04_28_102048_create_cities_table.php new file mode 100644 index 0000000..cbe6b76 --- /dev/null +++ b/laravel/database/migrations/2025_04_28_102048_create_cities_table.php @@ -0,0 +1,29 @@ +id(); + $table->string('name'); + $table->foreignId('province_id')->constrained()->cascadeOnUpdate()->cascadeOnDelete(); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('cities'); + } +}; diff --git a/laravel/database/migrations/0001_01_01_000000_create_users_table.php b/laravel/database/migrations/2025_04_28_110000_create_users_table.php similarity index 58% rename from laravel/database/migrations/0001_01_01_000000_create_users_table.php rename to laravel/database/migrations/2025_04_28_110000_create_users_table.php index 05fb5d9..9f102bd 100644 --- a/laravel/database/migrations/0001_01_01_000000_create_users_table.php +++ b/laravel/database/migrations/2025_04_28_110000_create_users_table.php @@ -13,20 +13,23 @@ return new class extends Migration { Schema::create('users', function (Blueprint $table) { $table->id(); - $table->string('name'); - $table->string('email')->unique(); - $table->timestamp('email_verified_at')->nullable(); + $table->string('full_name'); + $table->string('username')->unique(); + $table->string('phone_number')->unique(); + $table->string('national_id')->unique(); + $table->string('position'); + $table->string('avatar')->nullable(); + $table->enum('gender', [1 => 'female', 2 => 'male'])->nullable(); $table->string('password'); - $table->rememberToken(); + $table->foreignId('province_id')->constrained('provinces'); + $table->string('province_fa'); + $table->string('email')->unique()->nullable(); + $table->dateTime('last_login')->nullable(); + $table->string('telephone_id')->unique(); + $table->rememberToken()->nullable(); $table->timestamps(); }); - Schema::create('password_reset_tokens', function (Blueprint $table) { - $table->string('email')->primary(); - $table->string('token'); - $table->timestamp('created_at')->nullable(); - }); - Schema::create('sessions', function (Blueprint $table) { $table->string('id')->primary(); $table->foreignId('user_id')->nullable()->index(); @@ -43,7 +46,6 @@ return new class extends Migration public function down(): void { Schema::dropIfExists('users'); - Schema::dropIfExists('password_reset_tokens'); Schema::dropIfExists('sessions'); } }; diff --git a/laravel/database/seeders/CitySeeder.php b/laravel/database/seeders/CitySeeder.php new file mode 100644 index 0000000..eb5b73d --- /dev/null +++ b/laravel/database/seeders/CitySeeder.php @@ -0,0 +1,19 @@ +create([ + 'full_name' => 'Witel Company', + 'username' => 'witel', + 'phone_number' => '09000000000', + 'national_id' => '0150257083', + 'password' => Hash::make('Witel@fani0'), + 'email' => 'witel@gmail.com', + 'position' => 'Software Engineer', + 'province_id' => 9, + 'province_fa' => "تهران", + 'telephone_id' => 0, + ]); + +// $admin->givePermissionTo(\App\Models\Permission::all()); + } +} diff --git a/laravel/routes/web.php b/laravel/routes/web.php index 86a06c5..373ade7 100644 --- a/laravel/routes/web.php +++ b/laravel/routes/web.php @@ -1,7 +1,21 @@ name('auth.') + ->controller(AuthController::class) + ->group(function () { + Route::post('/login', 'login')->name('login'); + Route::post('/logout', 'logout')->name('logout'); + }); + +Route::prefix('profile') + ->name('profile.') + ->controller(ProfileController::class) + ->group(function () { + Route::get('/info', 'info')->middleware('auth:sanctum')->name('info'); + Route::post('/change_password', 'changePassword'); + }); diff --git a/laravel/storage/sql-files/cities.sql b/laravel/storage/sql-files/cities.sql new file mode 100644 index 0000000..879770d --- /dev/null +++ b/laravel/storage/sql-files/cities.sql @@ -0,0 +1,475 @@ +insert into cities (id, name, province_id) values +('1','آبادان','14'), +('2','آباده','19'), +('3','آبدانان','7'), +('4','آبیک','20'), +('5','آذرشهر','1'), +('6','آرادان','17'), +('7','آران و بيدگل','4'), +('8','آزادشهر','27'), +('9','آستارا','28'), +('10','آستانه اشرفیه','28'), +('11','آشتيان','32'), +('12','آغاجاري','14'), +('13','آق قلا','27'), +('14','آمل','31'), +('15','آوج','20'), +('16','ابركوه','35'), +('17','ابهر','15'), +('18','ابوموسی','33'), +('19','اراك','32'), +('20','اردبيل','3'), +('21','اردستان','4'), +('22','اردكان','35'), +('23','اردل','10'), +('24','ارزوئيه','23'), +('25','ارسنجان','19'), +('26','اروميه','2'), +('27','ازنا','30'), +('28','استهبان','19'), +('29','اسدآباد','34'), +('30','اسفراين','13'), +('31','اسكو','1'), +('32','اسلام آبادغرب','25'), +('33','اسلامشهر','9'), +('34','اشتهارد','5'), +('35','اشنويه','2'), +('36','اصفهان','4'), +('37','اقليد','19'), +('38','البرز','20'), +('39','اليگودرز','30'), +('40','املش','28'), +('41','اميديه','14'), +('42','انار','23'), +('43','انديكا','14'), +('44','انديمشك','14'), +('45','اهر','1'), +('46','اهواز','14'), +('47','ايجرود','15'), +('48','ايذه','14'), +('49','ايرانشهر','6'), +('50','ايلام','7'), +('51','ايوان','7'), +('52','بابل','31'), +('53','بابلسر','31'), +('54','باخرز','12'), +('55','باشت','26'), +('56','باغ ملك','14'), +('57','بافت','23'), +('58','بافق','35'), +('59','بانه','22'), +('60','باوي','14'), +('61','بجستان','12'), +('62','بجنورد','13'), +('63','بدره','7'), +('64','برخوار','4'), +('65','بردسكن','12'), +('66','بردسير','23'), +('67','بروجرد','30'), +('68','بروجن','10'), +('69','بستان آباد','1'), +('70','بستك','33'), +('71','بشاگرد','33'), +('72','بشرويه','11'), +('73','بم','23'), +('74','بن','10'), +('75','بناب','1'), +('76','بندر انزلي','28'), +('77','بندر لنگه','33'), +('78','بندر ماهشه','14'), +('79','بندرعباس','33'), +('80','بندرگز','27'), +('81','بهاباد','35'), +('82','بهار','34'), +('83','بهارستان','9'), +('84','بهبهان','14'), +('85','بهشهر','31'), +('86','بهمئي','26'), +('87','بوئين زهرا','20'), +('88','بوئين مياندشت','4'), +('89','بوانات','19'), +('90','بوشهر','8'), +('91','بوكان','2'), +('92','بويراحمد','26'), +('93','بيجار','22'), +('94','بيرجند','11'), +('95','بيله سوار','3'), +('96','بينالود','12'), +('97','پارس آباد','3'), +('98','پارسيان','33'), +('99','پاسارگاد','19'), +('100','پاكدشت','9'), +('101','پاوه','25'), +('102','پرديس','9'), +('103','پلدختر','30'), +('104','پلدشت','2'), +('105','پيرانشهر','2'), +('106','پيشوا','9'), +('107','تاكستان','20'), +('108','تايباد','12'), +('109','تبريز','1'), +('110','تربت جام','12'), +('111','تربت حیدریه','12'), +('112','تركمن','27'), +('113','تفت','35'), +('114','تفرش','32'), +('115','تكاب','2'), +('116','تنکابن','31'), +('117','تنگستان','8'), +('118','تهران','9'), +('119','تويسركان','34'), +('120','تيران و كرون','4'), +('121','ثلاث باباج','25'), +('122','جاجرم','13'), +('123','جاسك','33'), +('124','جغتاي','12'), +('125','جلفا','1'), +('126','جم','8'), +('127','جهرم','19'), +('128','جوانرود','25'), +('129','جويبار','31'), +('130','جوين','12'), +('131','جيرفت','24'), +('132','چابهار','6'), +('133','چادگان','4'), +('134','چاراويماق','1'), +('135','چالدران','2'), +('136','چالوس','31'), +('137','چايپاره','2'), +('138','چرام','26'), +('139','چرداول','7'), +('140','چناران','12'), +('141','حاجي آباد','33'), +('142','حميديه','14'), +('143','خاتم','35'), +('144','خاش','18'), +('145','خدا آفرين','1'), +('146','خدابنده','15'), +('147','خرامه','19'), +('148','خرم آباد','30'), +('149','خرم بيد','19'), +('150','خرمدره','15'), +('151','خرمشهر','14'), +('152','خلخال','3'), +('153','خليل آباد','12'), +('154','خمير','33'), +('155','خمين','32'), +('156','خميني شهر','4'), +('157','خنج','29'), +('158','خنداب','32'), +('159','خواف','12'), +('160','خوانسار','4'), +('161','خور و بيابانک','4'), +('162','خوسف','11'), +('163','خوشاب','12'), +('164','خوي','2'), +('165','داراب','19'), +('166','دالاهو','25'), +('167','دامغان','17'), +('168','داورزن','12'), +('169','درگز','12'), +('170','درميان','11'), +('171','دره شهر','7'), +('172','دزفول','14'), +('173','دشت آزادگان','14'), +('174','دشتستان','8'), +('175','دشتي','8'), +('176','دلفان','30'), +('177','دلگان','6'), +('178','دليجان','32'), +('179','دماوند','9'), +('180','دنا','26'), +('181','دهاقان','4'), +('182','دهگلان','22'), +('183','دهلران','7'), +('184','دوره چگني','30'), +('185','دورود','30'), +('186','دير','8'), +('187','ديلم','8'), +('188','ديواندره','22'), +('189','رابر','23'), +('190','راز و جرگلا','13'), +('191','رامسر','31'), +('192','رامشير','14'), +('193','رامهرمز','14'), +('194','راميان','27'), +('195','راور','23'), +('196','رباط كريم','9'), +('197','رزن','34'), +('198','رستم','19'), +('199','رشت','28'), +('200','رشتخوار','12'), +('201','رضواشهر','28'), +('202','رفسنجان','23'), +('203','روانسر','25'), +('204','رودان','33'), +('205','رودبار','28'), +('206','رودبار جنوب','24'), +('207','رودسر','28'), +('208','رومشكان','30'), +('209','ري','9'), +('210','ريگان','23'), +('211','زابل','18'), +('212','زاهدان','18'), +('213','زاوه','12'), +('214','زرند','23'), +('215','زرنديه','32'), +('216','زرين دشت','19'), +('217','زنجان','15'), +('218','زهك','18'), +('219','زيركوه','11'), +('220','ساري','31'), +('221','سامان','10'), +('222','ساوجبلاغ','5'), +('223','ساوه','32'), +('224','سبزوار','12'), +('225','سپيدان','19'), +('226','سراب','1'), +('227','سراوان','18'), +('228','سرايان','11'), +('229','سرباز','6'), +('230','سربيشه','11'), +('231','سرپل ذهاب','25'), +('232','سرخس','12'), +('233','سرخه','17'), +('234','سردشت','2'), +('235','سرعين','3'), +('236','سروآباد','22'), +('237','سروستان','19'), +('238','سقز','22'), +('239','سلسله','30'), +('240','سلطانيه','15'), +('241','سلماس','2'), +('242','سمنان','17'), +('243','سميرم','4'), +('244','سنقر','25'), +('245','سنندج','22'), +('246','سوادکوه','31'), +('247','سوادکوه شم','31'), +('248','سياهكل','28'), +('249','سيب سوران','18'), +('250','سيرجان','23'), +('251','سيروان','7'), +('252','سيريك','33'), +('253','سيمرغ','31'), +('254','شادگان','14'), +('255','شازند','32'), +('256','شاهرود','16'), +('257','شاهين دژ','2'), +('258','شاهين شهر و میمه','4'), +('259','شبستر','1'), +('260','شفت','28'), +('261','شميرانات','9'), +('262','شهربابك','23'), +('263','شهرضا','4'), +('264','شهركرد','10'), +('265','شهريار','9'), +('266','شهميرزاد','17'), +('267','شوش','14'), +('268','شوشتر','14'), +('269','شوط','2'), +('270','شيراز','19'), +('271','شيروان','13'), +('272','صحنه','25'), +('273','صدوق','35'), +('274','صومعه سرا','28'), +('275','طارم','15'), +('276','طالقان','5'), +('277','طبس','11'), +('278','طوالش','28'), +('279','عباس آباد','31'), +('280','عجب شير','1'), +('281','عسلويه','8'), +('282','علي آباد','27'), +('283','عنبرآباد','24'), +('284','فارسان','10'), +('285','فاروج','13'), +('286','فارياب','24'), +('287','فامنين','34'), +('288','فراشبند','19'), +('289','فراهان','32'), +('290','فردوس','11'), +('291','گچسر','5'), +('292','فريدن','4'), +('293','فريدونشهر','4'), +('294','فريدونکنار','31'), +('295','فريمان','12'), +('296','فسا','19'), +('297','فلاورجان','4'), +('298','فنوج','6'), +('299','فهرج','23'), +('300','فومن','28'), +('301','فيروزآباد','19'), +('302','فيروزكوه','9'), +('303','فيروزه','12'), +('304','قائمشهر','31'), +('305','قائنات','11'), +('306','قدس','9'), +('307','قرچك','9'), +('308','قروه','22'), +('309','قزوين','20'), +('310','قشم','33'), +('311','قصر شيرين','25'), +('312','قصرقند','6'), +('313','قلعه گنج','24'), +('314','قم','21'), +('315','قوچان','12'), +('316','قيروكارزين','19'), +('317','كارون','14'), +('318','كازرون','19'), +('319','كاشان','4'), +('320','كاشمر','12'), +('321','كامياران','22'), +('322','كبودرآهنگ','34'), +('323','كرج','5'), +('324','كردكوي','27'), +('325','كرمان','23'), +('326','كرمانشاه','25'), +('327','كلات','12'), +('328','كلاردشت','31'), +('329','كلاله','27'), +('330','كليبر','1'), +('331','كميجان','32'), +('332','كنارك','6'), +('333','كنگان','8'), +('334','كنگاور','25'), +('335','كهگيلويه','26'), +('336','كهنوج','24'), +('337','كوار','19'), +('338','كوثر','3'), +('339','كوهبنان','23'), +('340','كوهدشت','30'), +('341','كوهرنگ','10'), +('342','كيار','10'), +('343','گاليكش','27'), +('344','گتوند','14'), +('345','گچساران','26'), +('346','گراش','29'), +('347','گرگان','27'), +('348','گرمسار','17'), +('349','گرمه','13'), +('350','گرمي','3'), +('351','گلپايگان','4'), +('352','گلوگاه','31'), +('353','گميشان','27'), +('354','گناباد','12'), +('355','گناوه','8'), +('356','گنبد كاووس','27'), +('357','گيلانغرب','25'), +('358','لارستان','29'), +('359','لالي','14'), +('360','لامرد','29'), +('361','لاهيجان','28'), +('362','لردگان','10'), +('363','لنجان','4'), +('364','لنده','26'), +('365','لنگرود','28'), +('366','ماسال','28'), +('367','ماكو','2'), +('368','مانه و سملقان','13'), +('369','ماهنشان','15'), +('370','مباركه','4'), +('371','محلات','32'), +('372','محمودآباد','31'), +('373','مراغه','1'), +('374','مراوه تپه','27'), +('375','مرند','1'), +('376','مرودشت','19'), +('377','مريوان','22'), +('378','مسجد سليمان','14'), +('379','مشگين شهر','3'), +('380','مشهد','12'), +('381','ملارد','9'), +('382','ملاير','34'), +('383','ملكان','1'), +('384','ملكشاهي','7'), +('385','ممسني','19'), +('386','منوجان','24'), +('387','مه ولات','12'), +('388','مهاباد','2'), +('389','مهدي شهر','17'), +('390','مهر','29'), +('391','مهران','7'), +('392','مهرستان','18'), +('393','مهريز','35'), +('394','ميامي','16'), +('395','ميان دورود','31'), +('396','مياندوآب','2'), +('397','ميانه','1'), +('398','ميبد','35'), +('399','ميرجاوه','18'), +('400','ميناب','33'), +('401','مينودشت','27'), +('402','نائين','4'), +('403','نجف آباد','4'), +('404','نرماشير','23'), +('405','نطنز','4'), +('406','نظرآباد','5'), +('407','نقده','2'), +('408','نکا','31'), +('409','نمين','3'), +('410','نهاوند','34'), +('411','نهبندان','11'), +('412','نور','31'), +('413','نوشهر','31'), +('414','ني ريز','19'), +('415','نير','3'), +('416','نيشابور','12'), +('417','نيك شهر','6'), +('418','نيمروز','18'), +('419','هامون','18'), +('420','هرسين','25'), +('421','هريس','1'), +('422','هشترود','1'), +('423','هفتگل','14'), +('424','همدان','34'), +('425','هنديجان','14'), +('426','هويزه','14'), +('427','هيرمند','18'), +('428','ورامين','9'), +('429','ورزقان','1'), +('430','يزد','35'), +('431','راسک','6'), +('432','ماراگون','26'), +('433','دشتیاری','6'), +('477','هوراند','1'), +('497','جرقويه','4'), +('510','اسپكه','6'), +('511','بمپور','6'), +('564','دزپارت','14'), +('571','زنجارود','15'), +('578','بيارجمند','16'), +('591','نصرت آباد','18'), +('592','تفتان','18'), +('593','گلشن','18'), +('607','الموت','20'), +('608','كوهين','20'), +('609','طارم','20'), +('616','سلفچگان','21'), +('630','شهرستان شهداد','23'), +('631','شهرستان گلباف','23'), +('632','شهرستان راین','23'), +('669','اوز','29'), +('670','جويم','29'), +('682','هراز','31'), +('689','غرق آباد','32'), +('711','خرانق','35'), +('713','مالخلیفه','10'), +('715','اداره بازفت','10'), +('716','ساردوئيه','24'), +('717','دیهوک','11'), +('788','زرین آباد','7'), +('789','هلیلان','7'), +('790','چوار','7'), +('791','خانمیرزا','10'), +('792','انگوت','3'), +('793','کوهپایه','4'), +('794','هرند','4'), +('795','زرآباد','6'), +('796','چهارباغ','5'), +('797','خفر','19'), +('798','کهک','21'), +('799','جعفرآباد','21'), +('805','ورزنه','4'), +('806','کرخه','14'), +('808','خمام','28'); diff --git a/laravel/storage/sql-files/provinces.sql b/laravel/storage/sql-files/provinces.sql new file mode 100644 index 0000000..636e3b3 --- /dev/null +++ b/laravel/storage/sql-files/provinces.sql @@ -0,0 +1,36 @@ +insert into provinces (id, name, lat, lon) values +('1','آذربایجان شرقی','38.0742000000','46.2962000000'), +('2','آذربایجان غربی','37.5495000000','45.0683000000'), +('3','اردبیل','38.2419000000','48.2887000000'), +('4','اصفهان','32.6709000000','51.6650000000'), +('5','البرز','35.8124000000','51.0074000000'), +('6','ایرانشهر','27.2069903000','60.6882515000'), +('7','ایلام','33.6381000000','46.4203000000'), +('8','بوشهر','28.9312000000','50.8458000000'), +('9','تهران','35.7065000000','51.3477000000'), +('10','چهارمحال و بختیاری','32.3259000000','50.8497000000'), +('11','خراسان جنوبی','32.8635000000','59.2177000000'), +('12','خراسان رضوی','36.2977000000','59.6059000000'), +('13','خراسان شمالی','37.4761000000','57.3320000000'), +('14','خوزستان','31.3231000000','48.6793000000'), +('15','زنجان','36.6782000000','48.5079000000'), +('16','سمنان شرق','36.4056260000','54.9670738726'), +('17','سمنان غرب','35.5834074000','53.3882906000'), +('18','سیستان و بلوچستان','29.4912000000','60.8674000000'), +('19','فارس','29.6061000000','52.5378000000'), +('20','قزوین','36.2816000000','50.0153000000'), +('21','قم','34.6425000000','50.8801000000'), +('22','کردستان','35.3128000000','46.9979000000'), +('23','کرمان','30.2924085000','57.0645647000'), +('24','کرمان جنوب','28.6697367000','57.7373382000'), +('25','کرمانشاه','34.3241000000','47.0736000000'), +('26','کهگیلویه و بویراحمد','30.6678000000','51.5803000000'), +('27','گلستان','36.8305000000','54.4242000000'), +('28','گیلان','37.2795000000','49.5846000000'), +('29','لارستان','27.6619203000','54.3229561000'), +('30','لرستان','33.4844000000','48.3538000000'), +('31','مازندران','36.5505000000','53.0708000000'), +('32','مرکزی','34.0883000000','49.7132000000'), +('33','هرمزگان','27.1795000000','56.2781000000'), +('34','همدان','34.7992000000','48.5148000000'), +('35','یزد','31.8888000000','54.3641000000');