Compare commits
13 Commits
b3e9912fd8
..
main
| Author | SHA1 | Date | |
|---|---|---|---|
| 4ea8ce6569 | |||
| 23b5b4a9b2 | |||
| 3a7e8c30ac | |||
| c59993a746 | |||
| 6721186340 | |||
| 0258a707ce | |||
| d1c0794f3e | |||
| 2a58a7e3f3 | |||
| 7f5d848138 | |||
| 71c34cee77 | |||
| d5f947d59e | |||
| 222e8984fc | |||
| 8f3cc468b9 |
+3
-3
@@ -21,11 +21,11 @@ LOG_DEPRECATIONS_CHANNEL=null
|
||||
LOG_LEVEL=debug
|
||||
|
||||
DB_CONNECTION=mysql
|
||||
DB_HOST=127.0.0.1
|
||||
DB_HOST=db
|
||||
DB_PORT=3306
|
||||
DB_DATABASE=ledstarband
|
||||
DB_USERNAME=root
|
||||
DB_PASSWORD=
|
||||
DB_USERNAME=ledstarband
|
||||
DB_PASSWORD=AnotherOneBitesTheDust
|
||||
|
||||
SESSION_DRIVER=database
|
||||
SESSION_LIFETIME=120
|
||||
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
FROM php:8.2-fpm-alpine
|
||||
|
||||
# Системные зависимости для Laravel
|
||||
RUN apk add --no-cache \
|
||||
bash \
|
||||
curl \
|
||||
libpng-dev \
|
||||
libxml2-dev \
|
||||
zip \
|
||||
unzip \
|
||||
git
|
||||
|
||||
# PHP расширения
|
||||
RUN docker-php-ext-install pdo pdo_mysql bcmath gd
|
||||
|
||||
# Копирование исполняемого файла Composer из официального образа
|
||||
COPY --from=composer:latest /usr/bin/composer /usr/bin/composer
|
||||
|
||||
# Аргументы для ID пользователя (по умолчанию 1000)
|
||||
ARG USER_ID=1000
|
||||
ARG GROUP_ID=1000
|
||||
|
||||
# Создаем пользователя с теми же ID, что на вашем компьютере
|
||||
RUN addgroup -g ${GROUP_ID} www && \
|
||||
adduser -u ${USER_ID} -G www -s /bin/sh -D www
|
||||
|
||||
# Настройка Git для этого пользователя
|
||||
RUN git config --global --add safe.directory /var/www/html
|
||||
|
||||
WORKDIR /var/www/html
|
||||
|
||||
USER www
|
||||
@@ -0,0 +1,34 @@
|
||||
# Переменные для удобства изменения имён контейнеров
|
||||
DOCKER_COMPOSE = docker compose
|
||||
PHP_CONTAINER = laravel-app
|
||||
|
||||
.PHONY: up down install migrate fresh fresh-seed shell
|
||||
|
||||
# Запуск контейнеров в фоновом режиме со сборкой
|
||||
up:
|
||||
$(DOCKER_COMPOSE) up -d --build
|
||||
|
||||
# Остановка и удаление контейнеров
|
||||
down:
|
||||
$(DOCKER_COMPOSE) down
|
||||
|
||||
# Установка зависимостей Composer внутри контейнера app
|
||||
install:
|
||||
$(DOCKER_COMPOSE) exec app composer install
|
||||
$(DOCKER_COMPOSE) exec app php artisan key:generate
|
||||
|
||||
# Запуск миграций базы данных внутри контейнера app
|
||||
migrate:
|
||||
$(DOCKER_COMPOSE) exec app php artisan migrate
|
||||
|
||||
# Полный сброс и перезапуск всех миграций (очистка БД)
|
||||
fresh:
|
||||
$(DOCKER_COMPOSE) exec app php artisan migrate:fresh
|
||||
|
||||
# Полный сброс миграций с последующим наполнением базы сидами (seed)
|
||||
fresh-seed:
|
||||
$(DOCKER_COMPOSE) exec app php artisan migrate:fresh --seed
|
||||
|
||||
# Интерактивный вход внутрь контейнера (в bash) сразу в рабочую папку
|
||||
shell:
|
||||
$(DOCKER_COMPOSE) exec -it app bash
|
||||
@@ -0,0 +1,44 @@
|
||||
<?php
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use App\Library\VK\Service\VkPostImportService;
|
||||
use Illuminate\Console\Command;
|
||||
|
||||
class VkCheckStatus extends Command
|
||||
{
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'app:vk-check-status';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'Command description';
|
||||
|
||||
public function __construct(
|
||||
protected VkPostImportService $import_service
|
||||
) {
|
||||
parent::__construct();
|
||||
}
|
||||
/**
|
||||
* Execute the console command.
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
$this->import_service->run();
|
||||
|
||||
|
||||
|
||||
//
|
||||
// unset($result['response'][0]['attachments']);
|
||||
// unset($result['response'][0]['copy_history'][0]['attachments']);
|
||||
// print_r($result);
|
||||
|
||||
}
|
||||
}
|
||||
@@ -9,9 +9,10 @@ use Carbon\Carbon;
|
||||
class VkPost
|
||||
{
|
||||
private int $id;
|
||||
private string $source_name;
|
||||
private bool $post = true;
|
||||
private string $text;
|
||||
private int $author_id;
|
||||
private int $from_id;
|
||||
private int $owner_id;
|
||||
private array $attachments = [];
|
||||
private Carbon $date;
|
||||
@@ -20,11 +21,12 @@ class VkPost
|
||||
{
|
||||
return [
|
||||
'id' => $this->id,
|
||||
'post' => (int) $this->post,
|
||||
'post' => $this->post ? "post" : "copy",
|
||||
'text' => $this->text,
|
||||
'author_id' => $this->author_id,
|
||||
'from_id' => $this->from_id,
|
||||
'owner_id' => $this->owner_id,
|
||||
'date' => $this->getDate()->toIso8601String(),
|
||||
'name' => $this->getSourceName(),
|
||||
'attachments' => $this->attachments,
|
||||
];
|
||||
}
|
||||
@@ -64,9 +66,9 @@ class VkPost
|
||||
return $this->text;
|
||||
}
|
||||
|
||||
public function getAuthorId(): int
|
||||
public function getFromId(): int
|
||||
{
|
||||
return $this->author_id;
|
||||
return $this->from_id;
|
||||
}
|
||||
|
||||
public function getDate(): Carbon
|
||||
@@ -82,6 +84,11 @@ class VkPost
|
||||
return $this->owner_id;
|
||||
}
|
||||
|
||||
public function getSourceName(): string
|
||||
{
|
||||
return $this->source_name;
|
||||
}
|
||||
|
||||
public function setId(int $id): void
|
||||
{
|
||||
$this->id = $id;
|
||||
@@ -92,9 +99,9 @@ class VkPost
|
||||
$this->text = $text;
|
||||
}
|
||||
|
||||
public function setAuthorId(int $author_id): void
|
||||
public function setFromId(int $from_id): void
|
||||
{
|
||||
$this->author_id = $author_id;
|
||||
$this->from_id = $from_id;
|
||||
}
|
||||
|
||||
public function setDate(string|int $date): void
|
||||
@@ -111,4 +118,9 @@ class VkPost
|
||||
{
|
||||
$this->attachments = $attachments;
|
||||
}
|
||||
|
||||
public function setSourceName(string $source_name): void
|
||||
{
|
||||
$this->source_name = $source_name;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ class RepostStrategy implements MappingStrategyInterface
|
||||
$post = new VkPost();
|
||||
$post->setId($item['id']);
|
||||
$post->setOwnerId($item['owner_id']);
|
||||
$post->setAuthorId($item['from_id']);
|
||||
$post->setFromId($item['from_id']);
|
||||
$post->setDate($item['date']);
|
||||
$post->setIsRepost();
|
||||
$post->setText($item['text'] ?? '');
|
||||
|
||||
@@ -17,7 +17,7 @@ class SimplePostStrategy implements MappingStrategyInterface
|
||||
$post = new VkPost();
|
||||
$post->setId($item['id']);
|
||||
$post->setOwnerId($item['owner_id']);
|
||||
$post->setAuthorId($item['from_id']);
|
||||
$post->setFromId($item['from_id']);
|
||||
$post->setDate($item['date']);
|
||||
$post->setIsPost();
|
||||
$post->setText($item['text'] ?? '');
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Library\VK\Resources;
|
||||
|
||||
use App\Library\VK\VkApiClient;
|
||||
|
||||
class GroupResource
|
||||
{
|
||||
public function __construct(private VkApiClient $api) {}
|
||||
|
||||
public function getById(string $groupId): array
|
||||
{
|
||||
$result = $this->api->call('groups.getById', [
|
||||
'group_id' => $groupId,
|
||||
]);
|
||||
|
||||
return $result['response'] ?? [];
|
||||
}
|
||||
}
|
||||
@@ -4,44 +4,57 @@ declare(strict_types=1);
|
||||
|
||||
namespace App\Library\VK\Service;
|
||||
|
||||
use App\Library\VK\Entity\VkPost;
|
||||
use App\Library\VK\Mapper\PostMapper;
|
||||
use App\Library\VK\Resources\GroupResource;
|
||||
use App\Library\VK\Resources\WallResource;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Generator;
|
||||
|
||||
class VkPostImportService
|
||||
{
|
||||
public function __construct(
|
||||
private WallResource $resource,
|
||||
private PostMapper $mapper
|
||||
private WallResource $wall,
|
||||
private GroupResource $group,
|
||||
private PostMapper $mapper
|
||||
) {
|
||||
|
||||
}
|
||||
|
||||
public function run(): void
|
||||
{
|
||||
//$result = $this->resource->get('ledstarband', 1, 100);
|
||||
$group = $this->getGroupInfo('ledstarband');
|
||||
$posts = $this->getWallPosts('ledstarband', 10);
|
||||
|
||||
foreach($posts as $item) {
|
||||
$post = $this->mapper->map($item);
|
||||
$post->setSourceName($group['name']);
|
||||
|
||||
if(! $post->isEmpty()) {
|
||||
print_r($post->toArray());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/** @return Generator<int, array> */
|
||||
private function getWallPosts(string $id, int $count = 5): Generator
|
||||
{
|
||||
$result = $this->wall->get($id, $count);
|
||||
|
||||
if (empty ($result['items']) ) {
|
||||
Log::info('Post import failed: no items found');
|
||||
}
|
||||
|
||||
# echo "\nFound items: ".$result['count']."\n";
|
||||
// foreach ($result['items'] as $item) {
|
||||
// $post = $this->mapper->map($item);
|
||||
// if(! $post->isEmpty()) {
|
||||
// # print_r($post->toArray());
|
||||
// }
|
||||
// }
|
||||
|
||||
$res = $this->resource->getById('-93243530_2113');
|
||||
foreach ($res as $item) {
|
||||
$post = $this->mapper->map($item);
|
||||
if(! $post->isEmpty()) {
|
||||
print_r($post->toArray());
|
||||
}
|
||||
foreach ($result['items'] as $item) {
|
||||
yield $item;
|
||||
}
|
||||
}
|
||||
|
||||
# print_r($res);
|
||||
|
||||
private function getGroupInfo(string $groupId): ?array
|
||||
{
|
||||
$res = $this->group->getById($groupId);
|
||||
return $res[0] ?? null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
namespace App\Library\VK;
|
||||
|
||||
use Exception;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use GuzzleHttp\ClientInterface;
|
||||
use GuzzleHttp\Exception\GuzzleException;
|
||||
|
||||
@@ -32,7 +33,9 @@ final class VkApiClient
|
||||
$result = json_decode($response->getBody()->getContents(), true);
|
||||
|
||||
if (isset($result['error'])) {
|
||||
throw new Exception("VK API Error: " . $result['error']['error_msg']);
|
||||
$message = "VK API Error: " . $result['error']['error_msg'];
|
||||
Log::error($message);
|
||||
throw new Exception($message);
|
||||
}
|
||||
|
||||
return $result;
|
||||
|
||||
@@ -10,19 +10,19 @@ class GigsLoader
|
||||
public function getEvents(): array
|
||||
{
|
||||
$data = Event::select(
|
||||
"Event.Name as event",
|
||||
"Event.PlaceId as place_id",
|
||||
"events.name as event",
|
||||
"events.place_id as place_id",
|
||||
"places.name as place",
|
||||
"places.address as address",
|
||||
"places.phone as phone",
|
||||
"places.url as url",
|
||||
DB::Raw("DAY(Event.Date) as mday"),
|
||||
DB::Raw("MONTH(Event.Date) as month"),
|
||||
DB::Raw("DATE_FORMAT(Event.Time, '%H:%s') as time"),
|
||||
DB::Raw("CONCAT(DATE_FORMAT(Event.Date,'%Y-%m-%d'),
|
||||
'T',DATE_FORMAT(Event.Time, '%H:%i:%s')) as fulldate")
|
||||
DB::Raw("DAY(events.date) as mday"),
|
||||
DB::Raw("MONTH(events.date) as month"),
|
||||
DB::Raw("DATE_FORMAT(events.time, '%H:%s') as time"),
|
||||
DB::Raw("CONCAT(DATE_FORMAT(events.date,'%Y-%m-%d'),
|
||||
'T',DATE_FORMAT(events.time, '%H:%i:%s')) as fulldate")
|
||||
)->join("places", function ($join){
|
||||
$join->on("places.id", "=", "Event.PlaceId")
|
||||
$join->on("places.id", "=", "events.place_id")
|
||||
->where("places.deleted_at", NULL);
|
||||
});
|
||||
$data = $data->get();
|
||||
|
||||
@@ -9,12 +9,12 @@ class PlaylistLoader
|
||||
public function getPlaylist(): array
|
||||
{
|
||||
$data = Track::select(
|
||||
"Track.Name as Track",
|
||||
"Performer.Name as Performer"
|
||||
)->join('Performer', function ($join) {
|
||||
$join->on('Performer.Id', "=", "Track.Performer")
|
||||
->where('Performer.DeleteDate', NULL);
|
||||
})->orderBy('Performer')->get();
|
||||
"tracks.name as Track",
|
||||
"performers.name as Performer"
|
||||
)->join('performers', function ($join) {
|
||||
$join->on('performers.id', "=", "tracks.performer_id")
|
||||
->where('performers.deleted_at', NULL);
|
||||
})->orderBy('performer_id')->get();
|
||||
|
||||
return $data ? $data->toArray() : [];
|
||||
}
|
||||
|
||||
@@ -9,11 +9,11 @@ class Event extends Model
|
||||
{
|
||||
use SoftDeletes;
|
||||
|
||||
const DELETED_AT = 'DeleteDate';
|
||||
const UPDATED_AT = 'UpdatedDate';
|
||||
const CREATED_AT = 'DateOfCreation';
|
||||
const DELETED_AT = 'deleted_at';
|
||||
const UPDATED_AT = 'updated_at';
|
||||
const CREATED_AT = 'created_at';
|
||||
|
||||
protected $primaryKey = 'Id';
|
||||
protected $table = 'Event';
|
||||
protected $fillable = ['Name', 'Date', 'Time', 'Archived'];
|
||||
protected $table = 'events';
|
||||
protected $fillable = [ 'name', 'date', 'time', 'archived' ];
|
||||
}
|
||||
|
||||
@@ -6,6 +6,6 @@ use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class News extends Model
|
||||
{
|
||||
protected $table = 'allNewsView';
|
||||
protected $table = 'news';
|
||||
protected $primaryKey = 'id';
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ namespace App\Models\ORM;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
use Illuminate\Database\Eloquent\Casts\Attribute;
|
||||
|
||||
class Place extends Model
|
||||
{
|
||||
@@ -19,4 +20,27 @@ class Place extends Model
|
||||
protected $fillable = [
|
||||
'name','gps', 'phone', 'description', 'url', 'address'
|
||||
];
|
||||
|
||||
protected function formattedPhone(): Attribute
|
||||
{
|
||||
return Attribute::make(
|
||||
get: function () {
|
||||
// Берем оригинальное значение из базы (например: 79991110101)
|
||||
$phone = $this->phone;
|
||||
|
||||
// Если номер начинается с 8 или 7 и в нем 11 цифр
|
||||
if (strlen($phone) === 11) {
|
||||
return '+7 (' . substr($phone, 1, 3) . ') ' . substr($phone, 4, 3) . '-' . substr($phone, 7, 2) . '-' . substr($phone, 9, 2);
|
||||
}
|
||||
|
||||
// Если номер записан без семерки (всего 10 цифр, например: 9991110101)
|
||||
if (strlen($phone) === 10) {
|
||||
return '+7 (' . substr($phone, 0, 3) . ') ' . substr($phone, 3, 3) . '-' . substr($phone, 6, 2) . '-' . substr($phone, 8, 2);
|
||||
}
|
||||
|
||||
// Если формат странный (например, городской короткий), выводим как есть
|
||||
return $phone;
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,11 +9,11 @@ class Track extends Model
|
||||
{
|
||||
use SoftDeletes;
|
||||
|
||||
const DELETED_AT = 'DeleteDate';
|
||||
const UPDATED_AT = 'UpdatedDate';
|
||||
const CREATED_AT = 'DateOfCreation';
|
||||
const DELETED_AT = 'deleted_at';
|
||||
const UPDATED_AT = 'updated_at';
|
||||
const CREATED_AT = 'created_at';
|
||||
|
||||
protected $primaryKey = 'Id';
|
||||
protected $table = 'Track';
|
||||
protected $fillable = ['Name', 'Length'];
|
||||
protected $table = 'tracks';
|
||||
protected $fillable = [ 'name', 'length' ];
|
||||
}
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('events', function (Blueprint $table) {
|
||||
$table->integer('id', true); // int NOT NULL AUTO_INCREMENT PRIMARY KEY
|
||||
$table->date('date')->nullable()->index('idx_date');
|
||||
$table->time('time')->nullable();
|
||||
$table->string('name', 1024)->nullable();
|
||||
$table->integer('place_id')->nullable()->index('idx_placeid');
|
||||
$table->binary('description')->nullable(); // blob
|
||||
$table->tinyInteger('archived')->default(0)->index('idx_archived');
|
||||
$table->string('image', 128)->nullable();
|
||||
$table->integer('price')->nullable();
|
||||
$table->string('link', 255)->nullable();
|
||||
|
||||
// Поля дат с дефолтными значениями
|
||||
$table->dateTime('updated_at')->default(DB::raw('CURRENT_TIMESTAMP'));
|
||||
$table->dateTime('created_at')->default(DB::raw('CURRENT_TIMESTAMP'));
|
||||
$table->dateTime('deleted_at')->nullable();
|
||||
|
||||
// Настройка движка и кодировки (опционально, если нужно строго как в SQL)
|
||||
$table->engine = 'InnoDB';
|
||||
// $table->charset = 'utf8mb3';
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('events');
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('news', function (Blueprint $table) {
|
||||
// Создаем поля для составного ключа
|
||||
// unsignedInteger соответствует int(11) unsigned
|
||||
$table->unsignedInteger('id');
|
||||
$table->integer('from_id');
|
||||
|
||||
$table->unsignedInteger('copy_post_id')->nullable();
|
||||
$table->string('header', 255)->nullable();
|
||||
$table->text('long_text')->nullable();
|
||||
$table->dateTime('date')->nullable();
|
||||
$table->string('img_src', 255)->nullable();
|
||||
$table->string('post_type', 255)->nullable();
|
||||
$table->unsignedTinyInteger('author_type')->nullable();
|
||||
|
||||
// Установка составного первичного ключа
|
||||
$table->primary(['id', 'from_id']);
|
||||
|
||||
// Индексы
|
||||
$table->index('post_type', 'idx_type');
|
||||
$table->index('from_id', 'idx_from_id');
|
||||
$table->index('date', 'idx_date');
|
||||
});
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('news');
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,40 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
// Сначала удаляем, если уже существует
|
||||
DB::statement("DROP VIEW IF EXISTS `all_news_view` ");
|
||||
|
||||
// Создаем вьюху
|
||||
DB::statement("
|
||||
CREATE VIEW `all_news_view` AS
|
||||
SELECT
|
||||
`id`,
|
||||
DATE_FORMAT(`date`, '%m') AS `month`,
|
||||
DATE_FORMAT(`date`, '%d') AS `day`,
|
||||
DATE_FORMAT(`date`, '%H:%i') AS `time`,
|
||||
`header`,
|
||||
`long_text` AS `article`,
|
||||
`from_id` AS `author`,
|
||||
`img_src`,
|
||||
`author_type`,
|
||||
`copy_post_id`,
|
||||
`post_type`
|
||||
FROM
|
||||
`news`
|
||||
WHERE
|
||||
`long_text` <> ''
|
||||
ORDER BY `date` DESC
|
||||
");
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
DB::statement("DROP VIEW IF EXISTS `all_news_view` ");
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('performers', function (Blueprint $table) {
|
||||
$table->id(); // id (bigint unsigned, auto-increment)
|
||||
$table->string('name'); // name (имя исполнителя / название группы)
|
||||
$table->timestamps(); // created_at и updated_at
|
||||
$table->softDeletes(); // deleted_at (для мягкого удаления)
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('performers');
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('tracks', function (Blueprint $table) {
|
||||
$table->id(); // id (bigint unsigned, auto-increment)
|
||||
$table->string('name'); // name (varchar 255)
|
||||
$table->unsignedInteger('length'); // length (длительность трека в секундах)
|
||||
|
||||
// performer_id (внешний ключ, связываем с таблицей performers)
|
||||
$table->foreignId('performer_id')
|
||||
->constrained('performers')
|
||||
->onDelete('cascade'); // если удалить исполнителя, удалятся и его треки
|
||||
|
||||
$table->timestamps(); // created_at и updated_at
|
||||
$table->softDeletes(); // deleted_at (для мягкого удаления)
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('tracks');
|
||||
}
|
||||
};
|
||||
@@ -24,6 +24,10 @@ class DatabaseSeeder extends Seeder
|
||||
|
||||
$this->call([
|
||||
UserSeeder::class,
|
||||
EventSeeder::class,
|
||||
PlaceSeeder::class,
|
||||
PerformerSeeder::class,
|
||||
TrackSeeder::class
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
<?php
|
||||
|
||||
namespace Database\Seeders;
|
||||
|
||||
use Illuminate\Database\Seeder;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
class EventSeeder extends Seeder
|
||||
{
|
||||
/**
|
||||
* Run the database seeds.
|
||||
*/
|
||||
public function run(): void
|
||||
{
|
||||
$events = [
|
||||
['date' => '2015-05-15', 'time' => '22:30:00', 'name' => 'Cover Party Little Rock', 'place_id' => 16, 'description' => null, 'archived' => 1, 'image' => 'IXtWCA7BIEk.jpg', 'price' => 300, 'link' => '', 'updated_at' => now(), 'created_at' => '2015-05-01 17:19:49', 'deleted_at' => null],
|
||||
['date' => '2015-06-07', 'time' => '20:00:00', 'name' => 'Концерт ', 'place_id' => 18, 'description' => null, 'archived' => 1, 'image' => '6mdjt_tEMeI.jpg', 'price' => 0, 'link' => null, 'updated_at' => now(), 'created_at' => '2015-05-19 09:31:44', 'deleted_at' => null],
|
||||
['date' => '2015-08-22', 'time' => '22:00:05', 'name' => 'Новоселье клуба', 'place_id' => 16, 'description' => null, 'archived' => 1, 'image' => 'MtFnBlQEKKg.jpg', 'price' => 200, 'link' => 'house_warming2015', 'updated_at' => now(), 'created_at' => '2015-07-17 12:20:20', 'deleted_at' => null],
|
||||
['date' => '2015-08-29', 'time' => '01:00:00', 'name' => 'Boney Nem afterparty', 'place_id' => 19, 'description' => null, 'archived' => 1, 'image' => 'e2sssYErwiM.jpg', 'price' => 0, 'link' => null, 'updated_at' => now(), 'created_at' => '2015-08-09 17:09:52', 'deleted_at' => null],
|
||||
['date' => '2015-10-04', 'time' => '20:30:00', 'name' => 'Hard Cover Sunday ', 'place_id' => 18, 'description' => null, 'archived' => 1, 'image' => null, 'price' => 0, 'link' => null, 'updated_at' => now(), 'created_at' => '2015-09-07 01:25:56', 'deleted_at' => null],
|
||||
['date' => '2015-10-17', 'time' => '18:30:00', 'name' => 'ДР клуба', 'place_id' => 16, 'description' => null, 'archived' => 1, 'image' => 'Zx97qrlzYm0.jpg', 'price' => 300, 'link' => null, 'updated_at' => now(), 'created_at' => '2015-09-07 01:27:17', 'deleted_at' => null],
|
||||
['date' => '2015-09-25', 'time' => '23:00:00', 'name' => 'Sunset Strip Patry', 'place_id' => 14, 'description' => null, 'archived' => 1, 'image' => '527yTT6okIY.jpg', 'price' => 300, 'link' => null, 'updated_at' => now(), 'created_at' => '2015-09-21 11:30:03', 'deleted_at' => null],
|
||||
['date' => '2015-11-20', 'time' => '01:30:00', 'name' => 'Sunset Strip', 'place_id' => 20, 'description' => null, 'archived' => 1, 'image' => null, 'price' => 0, 'link' => null, 'updated_at' => now(), 'created_at' => '2016-09-11 16:36:04', 'deleted_at' => null],
|
||||
['date' => '2015-10-10', 'time' => '22:00:00', 'name' => 'TRAVEL CAFE', 'place_id' => 21, 'description' => null, 'archived' => 1, 'image' => null, 'price' => 0, 'link' => null, 'updated_at' => now(), 'created_at' => '2016-09-11 16:38:05', 'deleted_at' => null],
|
||||
['date' => '2016-01-15', 'time' => '21:00:00', 'name' => 'Little Rock', 'place_id' => 16, 'description' => null, 'archived' => 1, 'image' => null, 'price' => 0, 'link' => null, 'updated_at' => now(), 'created_at' => '2016-09-11 16:41:38', 'deleted_at' => null],
|
||||
['date' => '2016-02-06', 'time' => '19:00:00', 'name' => 'Ночь стриптиза', 'place_id' => 22, 'description' => null, 'archived' => 1, 'image' => null, 'price' => 300, 'link' => null, 'updated_at' => now(), 'created_at' => '2016-09-18 16:44:38', 'deleted_at' => null],
|
||||
['date' => '2016-02-27', 'time' => '21:00:00', 'name' => 'Sunset Strip', 'place_id' => 14, 'description' => null, 'archived' => 1, 'image' => null, 'price' => 0, 'link' => null, 'updated_at' => now(), 'created_at' => '2016-09-11 16:58:12', 'deleted_at' => null],
|
||||
['date' => '2016-03-12', 'time' => '21:00:00', 'name' => 'Hatat\'s Калуга', 'place_id' => 18, 'description' => null, 'archived' => 1, 'image' => null, 'price' => 0, 'link' => null, 'updated_at' => now(), 'created_at' => '2016-09-11 16:59:36', 'deleted_at' => null],
|
||||
['date' => '2016-05-06', 'time' => '20:00:00', 'name' => 'Old School Party', 'place_id' => 23, 'description' => null, 'archived' => 1, 'image' => null, 'price' => 300, 'link' => null, 'updated_at' => now(), 'created_at' => '2016-09-11 17:43:07', 'deleted_at' => null],
|
||||
['date' => '2016-09-30', 'time' => '18:00:00', 'name' => 'Back to old school', 'place_id' => 20, 'description' => null, 'archived' => 1, 'image' => null, 'price' => 300, 'link' => 'bctldschl1', 'updated_at' => now(), 'created_at' => '2016-09-11 17:47:11', 'deleted_at' => null],
|
||||
['date' => '2016-11-12', 'time' => '18:00:00', 'name' => 'Generation Rock', 'place_id' => 20, 'description' => null, 'archived' => 1, 'image' => null, 'price' => 300, 'link' => 'rock_generation_2017', 'updated_at' => now(), 'created_at' => '2016-09-11 17:57:31', 'deleted_at' => null],
|
||||
['date' => '2016-10-07', 'time' => '22:00:00', 'name' => 'Sunset Strip Pajama Party', 'place_id' => 24, 'description' => null, 'archived' => 1, 'image' => null, 'price' => 0, 'link' => 'sunset_strip_eighteen', 'updated_at' => now(), 'created_at' => '2016-09-26 15:09:53', 'deleted_at' => null],
|
||||
['date' => '2016-12-24', 'time' => '20:00:00', 'name' => 'Презентация календаря "Красота категории "А"', 'place_id' => 17, 'description' => null, 'archived' => 1, 'image' => null, 'price' => null, 'link' => 'mototetki_calendar', 'updated_at' => now(), 'created_at' => '2016-12-20 19:54:02', 'deleted_at' => null],
|
||||
['date' => '2017-03-31', 'time' => '18:00:00', 'name' => 'Generation Rock 2', 'place_id' => 20, 'description' => null, 'archived' => 1, 'image' => null, 'price' => 300, 'link' => 'rock_generation_2017', 'updated_at' => now(), 'created_at' => '2017-05-31 17:06:21', 'deleted_at' => null],
|
||||
['date' => '2017-04-16', 'time' => '18:00:00', 'name' => 'Moscow Rock House 5', 'place_id' => 25, 'description' => null, 'archived' => 1, 'image' => null, 'price' => 300, 'link' => 'moscowrockhouse5', 'updated_at' => now(), 'created_at' => '2017-04-11 18:29:22', 'deleted_at' => null],
|
||||
['date' => '2017-05-27', 'time' => '18:00:00', 'name' => 'Glam Hard Rock Weekend', 'place_id' => 25, 'description' => null, 'archived' => 1, 'image' => null, 'price' => 300, 'link' => 'rock_weekend27', 'updated_at' => now(), 'created_at' => '2017-05-23 12:28:19', 'deleted_at' => null],
|
||||
['date' => '2017-06-10', 'time' => '18:00:00', 'name' => 'OLD SCHOOL COVER PARTY', 'place_id' => 26, 'description' => null, 'archived' => 1, 'image' => null, 'price' => 300, 'link' => 'oldschoolcoverparty_les', 'updated_at' => now(), 'created_at' => '2017-05-23 12:32:32', 'deleted_at' => null],
|
||||
['date' => '2017-09-22', 'time' => '19:30:00', 'name' => 'OLD SCHOOL COVER PARTY', 'place_id' => 27, 'description' => null, 'archived' => 1, 'image' => null, 'price' => null, 'link' => null, 'updated_at' => now(), 'created_at' => '2017-09-03 16:39:12', 'deleted_at' => null],
|
||||
['date' => '2018-01-21', 'time' => '19:00:00', 'name' => 'Концерт в клубе Контора', 'place_id' => 28, 'description' => null, 'archived' => 1, 'image' => null, 'price' => 0, 'link' => null, 'updated_at' => now(), 'created_at' => '2018-01-17 09:12:14', 'deleted_at' => null],
|
||||
['date' => '2018-02-02', 'time' => '19:00:00', 'name' => 'Striptease Night', 'place_id' => 10, 'description' => null, 'archived' => 1, 'image' => null, 'price' => 800, 'link' => null, 'updated_at' => now(), 'created_at' => '2018-01-17 09:13:50', 'deleted_at' => null],
|
||||
['date' => '2017-10-28', 'time' => '19:00:00', 'name' => 'Halloween', 'place_id' => 23, 'description' => null, 'archived' => 1, 'image' => null, 'price' => 400, 'link' => null, 'updated_at' => now(), 'created_at' => '2018-01-17 09:15:31', 'deleted_at' => null],
|
||||
['date' => '2018-06-16', 'time' => '20:00:00', 'name' => 'LEDSTAR в баре для байкеров', 'place_id' => 29, 'description' => null, 'archived' => 1, 'image' => null, 'price' => null, 'link' => null, 'updated_at' => now(), 'created_at' => '2018-05-26 18:12:44', 'deleted_at' => null],
|
||||
['date' => '2018-10-06', 'time' => '20:00:00', 'name' => 'LEDSTAR на Kozloparty', 'place_id' => 30, 'description' => null, 'archived' => 1, 'image' => null, 'price' => null, 'link' => null, 'updated_at' => now(), 'created_at' => '2018-11-05 13:30:20', 'deleted_at' => null],
|
||||
['date' => '2018-11-10', 'time' => '20:00:00', 'name' => 'LEDSTAR / Wings & Winds', 'place_id' => 29, 'description' => null, 'archived' => 1, 'image' => null, 'price' => 0, 'link' => null, 'updated_at' => now(), 'created_at' => '2018-11-05 13:29:15', 'deleted_at' => null],
|
||||
['date' => '2019-03-30', 'time' => '21:30:00', 'name' => 'Kozloparty отборочный тур', 'place_id' => 29, 'description' => null, 'archived' => 1, 'image' => null, 'price' => null, 'link' => null, 'updated_at' => now(), 'created_at' => '2019-03-25 12:33:31', 'deleted_at' => null],
|
||||
['date' => '2019-04-06', 'time' => '21:00:00', 'name' => 'Kozloparty отборочный тур 2', 'place_id' => 29, 'description' => null, 'archived' => 1, 'image' => null, 'price' => 0, 'link' => null, 'updated_at' => now(), 'created_at' => '2019-04-03 21:25:35', 'deleted_at' => null],
|
||||
['date' => '2019-05-26', 'time' => '19:00:00', 'name' => 'Live in Major', 'place_id' => 31, 'description' => null, 'archived' => 1, 'image' => null, 'price' => 0, 'link' => null, 'updated_at' => now(), 'created_at' => '2019-04-08 12:06:19', 'deleted_at' => null],
|
||||
['date' => '2019-05-11', 'time' => '19:00:00', 'name' => 'Открытие сезона', 'place_id' => 32, 'description' => null, 'archived' => 1, 'image' => null, 'price' => 0, 'link' => null, 'updated_at' => now(), 'created_at' => '2019-04-17 21:00:02', 'deleted_at' => null],
|
||||
['date' => '2019-06-15', 'time' => '16:00:00', 'name' => 'Ledstar на Kozloparty', 'place_id' => 30, 'description' => null, 'archived' => 1, 'image' => null, 'price' => null, 'link' => null, 'updated_at' => now(), 'created_at' => '2019-04-20 21:56:39', 'deleted_at' => null],
|
||||
['date' => '2019-12-07', 'time' => '20:00:00', 'name' => 'Live in BFB', 'place_id' => 29, 'description' => null, 'archived' => 0, 'image' => null, 'price' => 150, 'link' => null, 'updated_at' => now(), 'created_at' => '2019-10-28 14:42:38', 'deleted_at' => null],
|
||||
];
|
||||
|
||||
DB::table('events')->insert($events);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
<?php
|
||||
|
||||
namespace Database\Seeders;
|
||||
|
||||
use Illuminate\Database\Seeder;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Carbon\Carbon;
|
||||
|
||||
class PerformerSeeder extends Seeder
|
||||
{
|
||||
/**
|
||||
* Run the database seeds.
|
||||
*/
|
||||
public function run(): void
|
||||
{
|
||||
// Массив исполнителей для вставки
|
||||
$performers = [
|
||||
['name' => 'Deep Purple'],
|
||||
['name' => 'Rainbow'],
|
||||
['name' => 'DIO'],
|
||||
['name' => 'Black Sabbath'],
|
||||
];
|
||||
|
||||
// Добавляем к каждой записи метки времени, чтобы поля не были пустыми
|
||||
$now = Carbon::now();
|
||||
foreach ($performers as &$performer) {
|
||||
$performer['created_at'] = $now;
|
||||
$performer['updated_at'] = $now;
|
||||
}
|
||||
|
||||
// Чистим таблицу перед заполнением (опционально, чтобы не дублировать)
|
||||
// DB::table('performers')->truncate();
|
||||
|
||||
// Массовая вставка в базу данных
|
||||
DB::table('performers')->insert($performers);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
namespace Database\Seeders;
|
||||
|
||||
use Illuminate\Database\Seeder;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\File;
|
||||
|
||||
class PlaceSeeder extends Seeder
|
||||
{
|
||||
public function run(): void
|
||||
{
|
||||
// Путь к вашему SQL файлу
|
||||
$path = database_path('seeders/scripts/places.sql');
|
||||
|
||||
if (!File::exists($path)) {
|
||||
$this->command->error("Файл не найден: {$path}");
|
||||
return;
|
||||
}
|
||||
|
||||
// Читаем содержимое файла
|
||||
$sql = File::get($path);
|
||||
|
||||
// Выполняем SQL запрос (unprepared позволяет выполнять множественные INSERT)
|
||||
try {
|
||||
DB::unprepared($sql);
|
||||
//$this->command->info('Данные из SQL файла успешно загружены!');
|
||||
} catch (\Exception $e) {
|
||||
$this->command->error("Ошибка при выполнении SQL: " . $e->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
<?php
|
||||
|
||||
namespace Database\Seeders;
|
||||
|
||||
use Illuminate\Database\Seeder;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Carbon\Carbon;
|
||||
|
||||
class TrackSeeder extends Seeder
|
||||
{
|
||||
/**
|
||||
* Run the database seeds.
|
||||
*/
|
||||
public function run(): void
|
||||
{
|
||||
// SQL-запрос для проверки существования таблицы
|
||||
$tableExists = DB::select("SHOW TABLES LIKE 'performers'");
|
||||
|
||||
if (empty($tableExists)) {
|
||||
$this->command->error("Таблица 'performers' отсутствует в базе данных!");
|
||||
}
|
||||
|
||||
// Очищаем таблицу перед заполнением
|
||||
DB::table('tracks')->truncate();
|
||||
|
||||
// 1. Получаем ID исполнителей из базы по их именам
|
||||
$rainbowId = DB::table('performers')->where('name', 'Rainbow')->value('id');
|
||||
$blackSabbathId = DB::table('performers')->where('name', 'Black Sabbath')->value('id');
|
||||
$dioId = DB::table('performers')->where('name', 'DIO')->value('id');
|
||||
|
||||
// Если сидер запускается отдельно и исполнителей нет, остановим процесс
|
||||
if (!$rainbowId || !$blackSabbathId || !$dioId) {
|
||||
$this->command->error('Исполнители не найдены в базе данных. Сначала запустите PerformerSeeder!');
|
||||
return;
|
||||
}
|
||||
|
||||
// 2. Список треков со связями
|
||||
$tracksData = [
|
||||
// Rainbow
|
||||
['name' => 'Gates Of Babylon', 'performer_id' => $rainbowId],
|
||||
['name' => 'Lady Of The Lake', 'performer_id' => $rainbowId],
|
||||
['name' => 'Tarot Woman', 'performer_id' => $rainbowId],
|
||||
['name' => 'Long Live Rock\'n\'Roll', 'performer_id' => $rainbowId],
|
||||
['name' => 'Man On The Silver Mountain', 'performer_id' => $rainbowId],
|
||||
['name' => 'Kill The King', 'performer_id' => $rainbowId],
|
||||
['name' => 'Can\'t Let You Go', 'performer_id' => $rainbowId],
|
||||
['name' => 'Rainbow\'s Eyes', 'performer_id' => $rainbowId],
|
||||
['name' => 'Sixteen Century Greensleeves', 'performer_id' => $rainbowId],
|
||||
|
||||
// Black Sabbath
|
||||
['name' => 'Neon Knights', 'performer_id' => $blackSabbathId],
|
||||
['name' => 'Children Of The Sea', 'performer_id' => $blackSabbathId],
|
||||
['name' => 'Heaven And Hell', 'performer_id' => $blackSabbathId],
|
||||
|
||||
// DIO
|
||||
['name' => 'Holy Diver', 'performer_id' => $dioId],
|
||||
['name' => 'Last In Line', 'performer_id' => $dioId],
|
||||
['name' => 'All The Fools Sailed Away', 'performer_id' => $dioId],
|
||||
['name' => 'One Night In The City', 'performer_id' => $dioId],
|
||||
['name' => 'Straight Through The Heart', 'performer_id' => $dioId],
|
||||
];
|
||||
|
||||
// 3. Подготовка данных (добавляем случайную длину и метки времени)
|
||||
$now = Carbon::now();
|
||||
foreach ($tracksData as &$track) {
|
||||
$track['length'] = rand(180, 420); // Генерируем длину трека от 3 до 7 минут (в секундах)
|
||||
$track['created_at'] = $now;
|
||||
$track['updated_at'] = $now;
|
||||
}
|
||||
|
||||
// 4. Массовая вставка в базу данных
|
||||
DB::table('tracks')->insert($tracksData);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
INSERT INTO `places` (`id`,`name`,`address`,`phone`,`gps`,`url`,`description`) VALUES (1,'Ресторан \"Мой Двор\"','г. Москва, м. Новогиреево, ул. Сталеваров, вл. 3л.','+7 (495) 778-52-29','55.758533|37.841869','http://www.restoranmoydvor.ru/',NULL);
|
||||
INSERT INTO `places` (`id`,`name`,`address`,`phone`,`gps`,`url`,`description`) VALUES (2,'Бар Дефакто','г. Москва, Большая Лубянка д.30/2','+7 (495) 624-44-97','55.766182|37.631424','http://defaqto.ru/',NULL);
|
||||
INSERT INTO `places` (`id`,`name`,`address`,`phone`,`gps`,`url`,`description`) VALUES (3,'Ресторан \"Serafina\"','г. Москва, Родчельская ул, 15/1','+7 (495) 653-83-73','55.756402|37.566715','http://serafinarestaurant.ru',NULL);
|
||||
INSERT INTO `places` (`id`,`name`,`address`,`phone`,`gps`,`url`,`description`) VALUES (4,'клуб MUSIC TOWN','г. Москва, ул.Каланчевская 33, м.Комсомольская','+7 (495) 937-54-19','55.776271|37.64892','http://www.musictownclub.com/',NULL);
|
||||
INSERT INTO `places` (`id`,`name`,`address`,`phone`,`gps`,`url`,`description`) VALUES (5,'Клуб \"Релакс\"','г. Москва, ул.Мельникова, д.7','+7 (495) 287-40-90','55.725926|37.67351','http://sevenclub7.ru/',NULL);
|
||||
INSERT INTO `places` (`id`,`name`,`address`,`phone`,`gps`,`url`,`description`) VALUES (6,'Клуб \"Байконур\"','г. Москва, ул. Декабристов, д. 17 ','+7 (925) 099 10-11','55.865008|37.604784','http://baikonur-club.ru/',NULL);
|
||||
INSERT INTO `places` (`id`,`name`,`address`,`phone`,`gps`,`url`,`description`) VALUES (7,'АНТРЕ бар','г. Москва, ул.Мельникова д.7, метро: Пролетарская','+7 (967) 297-26-97','55.725926|37.67351','http://vk.com/barantre',NULL);
|
||||
INSERT INTO `places` (`id`,`name`,`address`,`phone`,`gps`,`url`,`description`) VALUES (8,'FM-CLUB','г. Москва, Земляной Вал д.60/28 или Николоямская д.28/60','+7 (495) 502-99-21','55.746907|37.654807','http://afisha.yandex.ru/msk/places/2794/',NULL);
|
||||
INSERT INTO `places` (`id`,`name`,`address`,`phone`,`gps`,`url`,`description`) VALUES (9,'Blur Cafe','г. Москва, Большой Дровяной пер., д. 8 стр. 1','+7 (495) 915-76-05','55.744153|37.656924','http://blurcafe.ru/',NULL);
|
||||
INSERT INTO `places` (`id`,`name`,`address`,`phone`,`gps`,`url`,`description`) VALUES (10,'Glastonberry Pub','г. Москва, 1-ая Дубровская 13А, стр.1','+7 (915) 217-96-89','55.722856|37.675101','http://www.glastonberrypub.ru/',NULL);
|
||||
INSERT INTO `places` (`id`,`name`,`address`,`phone`,`gps`,`url`,`description`) VALUES (11,'WHITE FOX Pub','г. Истра, ул.Адасько, д.7к1','+7 (916) 684-54-20','55.912044|36.860026','http://vk.com/irishpub_whitefox',NULL);
|
||||
INSERT INTO `places` (`id`,`name`,`address`,`phone`,`gps`,`url`,`description`) VALUES (12,'Doolin House','г. Москва, Арбат 20','+7 (495) 695-92-06','55.750485|37.593378','http://doolin-house.ru/',NULL);
|
||||
INSERT INTO `places` (`id`,`name`,`address`,`phone`,`gps`,`url`,`description`) VALUES (13,'Гранд Бурбон Стрит','г. Москва, Потаповский пер., 5','+7 (495) 625-94-24','55.761692|37.640528','http://www.grand-bourbon.ru',NULL);
|
||||
INSERT INTO `places` (`id`,`name`,`address`,`phone`,`gps`,`url`,`description`) VALUES (14,'Night Train','г. Москва, 1-ый Угрешский проезд д. 7а, стр. 2 ','+7 (925) 001-26-18 ','55.716112|37.68881','http://www.nighttrain.ru/',NULL);
|
||||
INSERT INTO `places` (`id`,`name`,`address`,`phone`,`gps`,`url`,`description`) VALUES (15,'Ресторан Бюрократ','г. Москва, ул. Мневники, д. 13','+7 (499) 191-16-08','55.773334|37.484951','http://www.burocratbeer.ru/',NULL);
|
||||
INSERT INTO `places` (`id`,`name`,`address`,`phone`,`gps`,`url`,`description`) VALUES (16,'Little Rock','г. Москва, ул. Сельскохозяйственная, 15к4','+7 (968) 845-74-63','55.836729|37.638116','http://vk.com/littlerockclub',NULL);
|
||||
INSERT INTO `places` (`id`,`name`,`address`,`phone`,`gps`,`url`,`description`) VALUES (17,'China Town','г. Москва, Лубянский проезд, 25, стр. 1','+7 (495) 623-61-63 ','55.754873|37.634554','http://chinatowncafe.ru/',NULL);
|
||||
INSERT INTO `places` (`id`,`name`,`address`,`phone`,`gps`,`url`,`description`) VALUES (18,'Harat\'s Pub','г. Калуга, ул. Достоевского, 25','+7 (4842) 56-11-05 ','54.512209|36.252153','http://www.harats.ru/pubs/kaluga',NULL);
|
||||
INSERT INTO `places` (`id`,`name`,`address`,`phone`,`gps`,`url`,`description`) VALUES (19,'Швайн','г. Москва, Лефортовский пер. 12/50','+7 (499) 267-45-04','55.769782|37.678713','http://schwein.ru',NULL);
|
||||
INSERT INTO `places` (`id`,`name`,`address`,`phone`,`gps`,`url`,`description`) VALUES (20,'Jimi','Москва, Спартаковская площадь, 16/15, стр. 17','+7 (495) 053-18-88','55.780664|37.634364','http://jimiclub.ru',NULL);
|
||||
INSERT INTO `places` (`id`,`name`,`address`,`phone`,`gps`,`url`,`description`) VALUES (21,'Travel Cafe','г. Москва, ул. Верхняя Радищевская, д.7, стр.1','+7 (495) 915-73-76','55.744487|37.649539','https://vk.com/club76897606',NULL);
|
||||
INSERT INTO `places` (`id`,`name`,`address`,`phone`,`gps`,`url`,`description`) VALUES (22,'Monaclub','г. Москва, ул. Павла Корчагина, д.2А','+7 (495) 776-09-93','55.810836|37.655371','http://monaclub.ru/',NULL);
|
||||
INSERT INTO `places` (`id`,`name`,`address`,`phone`,`gps`,`url`,`description`) VALUES (23,'Клуб Театр','г. Москва, ул. Барклая, 6, строение 2','8 (965) 446-60-26','55.766581|37.663911','https://vk.com/teatrmoscow',NULL);
|
||||
INSERT INTO `places` (`id`,`name`,`address`,`phone`,`gps`,`url`,`description`) VALUES (24,'#ММ77','г. Москва, Волгоградский пр. 32к8','N/A','55.722700|37.690685','https://vk.com/motobarmm77',NULL);
|
||||
INSERT INTO `places` (`id`,`name`,`address`,`phone`,`gps`,`url`,`description`) VALUES (25,'Rock House','г. Москва, Измайловское шоссе 71 корпус 5 (Е)','+7 (495) 728-04-66','55.789859|37.749280','http://www.rock-house.ru',NULL);
|
||||
INSERT INTO `places` (`id`,`name`,`address`,`phone`,`gps`,`url`,`description`) VALUES (26,'Клуб ЛЕС','Москва, Лесная, 30А','+7 (965) 446-60-26','55.783358|37.5963319','http://www.lesmoscow.com',NULL);
|
||||
INSERT INTO `places` (`id`,`name`,`address`,`phone`,`gps`,`url`,`description`) VALUES (27,'LiveStars','Берсеневский пер. 5а ,стр.2','8-968-884-71-60','55.7414009|37.6101654','http://www.livestarsclub.ru',NULL);
|
||||
INSERT INTO `places` (`id`,`name`,`address`,`phone`,`gps`,`url`,`description`) VALUES (28,'Клуб Контора','Москва, Варсонофьевский пер., д.1','8 (499) 707-22-69','55.752180|37.617985','https://vk.com/kontora.club',NULL);
|
||||
INSERT INTO `places` (`id`,`name`,`address`,`phone`,`gps`,`url`,`description`) VALUES (29,'Bar For Bikers','Москва, Нижегородская, 32с5','8 (499) 226-40-50','55.737161|37.689490','http://barforbikers.ru',NULL);
|
||||
INSERT INTO `places` (`id`,`name`,`address`,`phone`,`gps`,`url`,`description`) VALUES (30,'Долина-Иволга','Тверская область, Конаковский район, п/о «Энергетик»','8 (499) 703 31 88','56.6711037|36.6879069','http://dolina-ivolga.ru',NULL);
|
||||
INSERT INTO `places` (`id`,`name`,`address`,`phone`,`gps`,`url`,`description`) VALUES (31,'Бар мажор','г. Калуга ул. Кирова 50','8 (4842) 56-21-33','54.513898|36.258700','https://vk.com/bar_major',NULL);
|
||||
INSERT INTO `places` (`id`,`name`,`address`,`phone`,`gps`,`url`,`description`) VALUES (32,'Б.О. Галактика','База отдыха Галактика','+7 (484) 396-72-83','55.752180|37.617985','https://www.galakticka.ru',NULL);
|
||||
INSERT INTO `places` (`id`,`name`,`address`,`phone`,`gps`,`url`,`description`) VALUES (34,'Главный офис','Москва, Новолесная, 3','79261112233','55.754|37.789','https://major.ru',NULL);
|
||||
INSERT INTO `places` (`id`,`name`,`address`,`phone`,`gps`,`url`,`description`) VALUES (35,'Клуб Б','Москва, Севастопольский проспект, 14','79203243411','55.724,37.721','http://vk.com','Новый объект');
|
||||
INSERT INTO `places` (`id`,`name`,`address`,`phone`,`gps`,`url`,`description`) VALUES (36,'Офис компании','Москва, Севастопольский проспект, 14','79203243411','55.724|37.721','https://major.ru','test');
|
||||
INSERT INTO `places` (`id`,`name`,`address`,`phone`,`gps`,`url`,`description`) VALUES (37,'Lenta.ru','Москва, Куусинена, 11','79208971142','55.724,37.721','http://lenta.ru','Самый ужасный в Москве клуб!');
|
||||
@@ -0,0 +1,51 @@
|
||||
services:
|
||||
app:
|
||||
build:
|
||||
context: .
|
||||
dockerfile: Dockerfile
|
||||
args:
|
||||
- USER_ID=1000
|
||||
- GROUP_ID=1000
|
||||
container_name: laravel-app
|
||||
restart: unless-stopped
|
||||
volumes:
|
||||
- .:/var/www/html
|
||||
depends_on:
|
||||
- db
|
||||
|
||||
nginx:
|
||||
image: nginx:alpine
|
||||
container_name: laravel-nginx
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- "127.0.0.1:8080:80"
|
||||
volumes:
|
||||
- .:/var/www/html
|
||||
- ./nginx.conf:/etc/nginx/nginx.conf:ro
|
||||
depends_on:
|
||||
- app
|
||||
|
||||
db:
|
||||
image: mariadb:10.11
|
||||
container_name: laravel-db
|
||||
restart: unless-stopped
|
||||
# Оптимизация: отключаем лишние проверки и DNS, чтобы не тупило внутри докера
|
||||
command: [
|
||||
"mysqld",
|
||||
"--skip-name-resolve",
|
||||
"--innodb-buffer-pool-size=128M", # Отрегулируй под свою RAM (256M-512M обычно за глаза)
|
||||
"--character-set-server=utf8mb4",
|
||||
"--collation-server=utf8mb4_unicode_ci"
|
||||
]
|
||||
environment:
|
||||
MARIADB_DATABASE: ledstarband
|
||||
MARIADB_ROOT_PASSWORD: ShowMeYouRoot
|
||||
MARIADB_USER: ledstarband
|
||||
MARIADB_PASSWORD: AnotherOneBitesTheDust
|
||||
ports:
|
||||
- "33060:3306" # Внешний порт 33060, внутренний 3306
|
||||
volumes:
|
||||
- db_data:/var/lib/mysql
|
||||
|
||||
volumes:
|
||||
db_data:
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
events {
|
||||
worker_connections 1024;
|
||||
}
|
||||
|
||||
http {
|
||||
include /etc/nginx/mime.types;
|
||||
default_type application/octet-stream;
|
||||
sendfile on;
|
||||
keepalive_timeout 65;
|
||||
|
||||
server {
|
||||
listen 80;
|
||||
server_name localhost;
|
||||
root /var/www/html/public;
|
||||
index index.php index.html;
|
||||
charset utf-8;
|
||||
|
||||
location / {
|
||||
try_files $uri $uri/ /index.php?$query_string;
|
||||
}
|
||||
|
||||
location = /favicon.ico { access_log off; log_not_found off; }
|
||||
location = /robots.txt { access_log off; log_not_found off; }
|
||||
|
||||
error_page 404 /index.php;
|
||||
|
||||
# Пересылка PHP-запросов в контейнер 'app' на порт 9000
|
||||
location ~ \.php$ {
|
||||
fastcgi_pass app:9000;
|
||||
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
|
||||
include fastcgi_params;
|
||||
}
|
||||
|
||||
location ~ /\.ht {
|
||||
deny all;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -44,7 +44,7 @@
|
||||
<td><a class="text-indigo-600 hover:text-indigo-900 transition-colors"
|
||||
href="{{ $place->url }}">{{ $place->name }}</a></td>
|
||||
<td>{{ $place->address ?? '—' }}</td>
|
||||
<td>{{ $place->phone }}</td>
|
||||
<td>{{ $place->formattedPhone }}</td>
|
||||
<td class="text-center">
|
||||
<a href="#" title="Показать на карте"
|
||||
class="text-gray-500 hover:text-blue-600 transition-colors flex items-center justify-center"
|
||||
|
||||
+1
-1
@@ -15,10 +15,10 @@ use App\Http\Controllers\VkBotController;
|
||||
|
||||
Route::middleware('auth')
|
||||
->group(function () {
|
||||
Route::get('/places/create', [PlacesController::class, 'create'])->name('places.create');
|
||||
Route::get('/places', [PlacesController::class, 'index'])->name('places.index');
|
||||
Route::get('/places/{id}', [PlacesController::class, 'edit'])->name('places.edit');
|
||||
Route::put('/places/{id}', [PlacesController::class, 'update'])->name('places.update');
|
||||
Route::get('/places/create', [PlacesController::class, 'create'])->name('places.create');
|
||||
Route::post('/places/store', [PlacesController::class, 'store'])->name('places.store');
|
||||
Route::delete('/places/{id}', [PlacesController::class, 'delete'])->name('places.delete');
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user