Совершенно неожиданно вышла новая версия Vesp - 3.0.

Как известно, Vesp состоит из Vue, Eloquent, Slim и Phinx. 3 части названия состовляет PHP бэкенд (пакет vesp/core), оставшаяся 1 часть - это фронтенд на Vue (пакет @vesp/frontend).

В новой версии обновлены они оба, но фронтенду досталось сильно больше из-за перехода на Vue 3.

Vesp/Core

Минимальная версия теперь PHP 8.1, прекрасно поддерживается и текущая стабильная 8.3.

Зависимости обновлены до последних версий: Eloquent 10, JWT 6, PhpUnit 10.

Во всех классах, где это возможно, добавлены типы переменным. Например, было так

abstract class ModelController extends Controller
{
    /** @var string $model */
    protected $model;
    protected $primaryKey = 'id';
    protected $maxLimit = 1000;

А стало вот так

abstract class ModelController extends Controller
{
    protected string $model;
    protected string|array $primaryKey = 'id';
    protected int $maxLimit = 1000;

Если вы будете обновлять на новую версию старый проект, то IDE вам обязательно должно подчеркнуть ошибки в старых контроллерах и моделях - просто укажите правильные типы, ничего сложного.

Для более удобного расширения контроллеров создан отдельный метод инициализации. Раньше для переопределения основного метода __invoke надо было прописывать кучу всего обязятельного, и только где-то в конце менять нужное, а теперь вот так:

class MyController extends Controller
{
    public function __invoke(RequestInterface $request, ResponseInterface $response): ResponseInterface
    {
        // Выставление $this->request, $this->response, $this->route, $this->user 
        // и свойств, доступных через $this->getProperties()
        $this->initController($request, $response);

        // Дальше ваша особенная логика
    }
}

Контроллеры теперь отдают не красиво распечатанный JSON, а обычный в одну строку - так расходуется меньше трафика на ответы от сервера. Флаг JSON_PRETTY_PRINT в ответах заменён на JSON_THROW_ON_ERROR.

В контроллере изображений добавлена поддержка композитного ключа. Везде эта поддержка была, а в картинках почему-то не было.

Добавил поддержку нового имени для куки авторизации auth:token, старая auth._token.local тоже осталась. Она была от фронтового пакет @nuxtjs/auth, в новой версии фронтенда его нет, так что имя куки стало проще.

Очень много изменений было в работе с файлами. Основное отличие - теперь файловые методы привязаны не к файловой системе, а к собственно модели, через новый trait FileModel.

Все методы, типа uploadFile, getFile, getSaveName теперь в нём, а значит, что вы можете создать сколько угодно моделей для разной логики работы с файлами. Файловая система может быть одна, а вот логика наименования файлов в ней зависеть от модели. Лично мне так кажется гораздо более удобно и логичнее.

Добавлена композитная модель UserFile, как пример использования нового трейта. Довольно часто в проектах нужно загружать какие-то файлы юзерам, так что лишним не будет.

Улучшена работа с большими файлами: и загрузка и отдача. Автоматическое получение размеров картинок теперь работает только для файлов <= 50 мегабайт.

composer.json и composer.lock переехали внутрь директории core. Раньше были снаружи, что как-то не согласуется с полным разделением бэкенда и фронтенда.

Тесты теперь можно быстренько прогнать через Docker.

git clone https://github.com/bezumkin/vesp-core.git
cd ./vesp-core
docker-compose up

Вам это не нужно, а мне приятно.

@Vesp/Frontend

Здесь было гораздо больше изменений, благодаря переходу на:

  • Vue 3
  • Nuxt 3
  • Typescript
  • Bootstrap 5 SCSS
  • Bootstrap Vue Next
  • Pinia вместо Vuex
  • Vue Toastification для всплывающих уведомлений

Благодаря новому композитному синтаксису пришлось переписать вообще всё. Плюс, для нового Nuxt нет многих старых привычных модулей, например авторизации и подключения Font Awesome - и мне пришлось написать их самостоятельно.

Как и раньше, @vesp/frontend является модулем для Nuxt, нужно просто подключить его и указать настройки. Работает поддержка типов, всё экспортируется, подсказки в IDE вам помогут:

Благодаря новым возможностям Nuxt больше нет разделения на 2 приложения: admin и site. Админка теперь это просто вложенные странички сайта, которые не рендерятся на сервере. А весь остальной сайт рендерится.

Соответственно, нет нужды и запускать 2 процесса Nuxt через concurrently - меньше тратится ресурсов.

Я крайне не советую обновлять старые проекты на новую версию, это равносильно переписыванию всего с нуля. Если, конечно, именно такой задачи у вас и не стоит.

Bootstrap Vue Next сейчас в очень активной разработке, и похоже будет там еще долго. Но я всё равно смог с ним подружиться и наладить нормальную работу. Поэтому версия пакета будет жёстко фиксироваться, чтобы он сам не обновлялся и не ломал уже работающее.

Я постарался, как мог, прописать поддержку собственных типов Vesp, вы увидете это в исходниках. Рекомендую пользоваться, чтобы делать меньше ошибок.

Typescript не является обязательным, он не участвует в компиляции и его ошибки ни на что не влияют, они должны просто помогать вам писать более правильный код.

SCSS файлы так же экспортируются модулем, вы можете их легко подключить в своих стилях:

@import 'bootstrap-scss/bootstrap';
@import '@vesp/frontend/assets/components';
@import '@vesp/frontend/assets/toast';
@import '@fortawesome/fontawesome-svg-core/styles.css';

Понятное дело, что там всё завязано на Bootstrap и вы можете переопределить переменные SCSS.

На данный момент модуль добавляет следующие компоненты:

  • vesp-table - компонент для вывода таблиц админки
  • vesp-modal - модалка с поддержкой отправки форм и обновления соответствующей таблицы
  • vesp-fa - иконки FontAwesome
  • vesp-change-locale - компонент для переключения языка
  • vesp-input-alias - компонент для ввода адресов страниц, использует slugify
  • vesp-input-combo-box - ввод с автодополнением через запросы к API
  • vesp-input-date-picker - ввод даты или диапазона дат, использует vue-datepicker-next
  • vesp-input-password - ввод пароля с кнопочкой "показать\скрыть"
  • vesp-input-remote-links - ввод JSON массива "название сервиса-адрес", например для ссылок на соцсети
  • vesp-input-text-mask - ввод телефонов или других данных по маске, использует text-mask-core

В основном эти компоненты расширяют что-то из BootstrapVue.

Также есть разные полезные функции:

  • useGet, usePost, usePut, usePatch, useDelete - простые запросы в API с поддержкой авторизации и безо всяких наворотов, вроде сохранения состояния и кэширования.
  • useApi - тоже самое, но с возможностью более тонкого указания параметров - функции выше используют эту функцию внутри себя
  • useCustomFetch - а это как раз запрос в API со всеми наворотами, плюс поддержка авторизации. Подробнее читать в документации Nuxt
try {
  const data = await useGet('user/profile')
  console.log(data)
} catch (e) {
  console.error(e)
}

Дальше работа с авторизацией через композит useAuth:

const {loggedIn, token, user, login, logout, loadUser, setToken} = useAuth()

console.log(loggedIn.value, user.value, token.value)

Экспортируются переменные:

  • loggedIn - computed переменная со статусом авторизации, внутри true или false.
  • token - ref на куку с токеном, может быть строкой или undefined.
  • user - ref на юзера, может быть объектом типа VespUser или undefined.

И полезные функции:

  • login(username, password) - авторизация
  • logout() - выход и удаление токена на сервере
  • loadUser() - загрузка профиля с сервера
  • setToken(string) - выставление нового токена в куку авторизации

Простейший пример авторизации:

<template>
  <div v-if="loggedIn">
    <pre>{{ user }}</pre>
    <b-button @click="() => logout()">Logout</b-button>
  </div>
  <div v-else>
    <b-form @submit.prevent="onSubmit">
      <b-form-group label="Username">
        <b-form-input v-model="form.username" required />
      </b-form-group>
      <b-form-group label="Password">
        <vesp-input-password v-model="form.password" required />
      </b-form-group>

      <b-button type="submit">Submit</b-button>
    </b-form>
  </div>
</template>

<script setup lang="ts">
const {loggedIn, user, login, logout} = useAuth()
const form = ref({username: '', password: ''})

async function onSubmit() {
  try {
    await login(form.value.username, form.value.password)
    form.value = {username: '', password: ''}
  } catch (e) {
    console.error(e)
  }
}
</script>

Дальше функции по выводу всплывающих сообщений:

  • useToastInfo(message, options)
  • useToastSuccess(message, options)
  • useToastError(message, options)
  • useToastsClear() - убирает выведенные сообщения

Всё понятно из названий. Первым параметром идёт сообщение, вторым можно указать дополнительные опции для вывода.

Если при запросе в API произошла ошибка, она будет выведена автоматически через useToastError().

Есть еще полезные функции:

  • getApiUrl() - определяет базовый адрес для запроса в API
  • getImageLink(VespFile, VespFileOptions) - формирует ссылку на вывод картинки из API, принимает переменные указанных типов
  • hasScope(permission) - проверяет, есть ли у юзера разрешение на что-то, типа users/get

Скорее всего, список всяких полезных функций еще будет расширяться.

Самое прикольное, что ничего импортировать не нужно: ни компоненты, ни функции, ни авторизацию. Оно всё просто доступно во всех vue файлах, за это отвечает Nuxt.

Docker

Новая версия рассчитана на работу в Docker. По умолчанию прописан production конфиг, который вы можете переопределить файлом docker-compose.override.yml.

Я приложил в комплект такой файлик с расширением dist, его можно переименовать и запускать контейнеры в режиме для разработки. Разница, в общем-то, только в открытии внешних портов, но вы можете переопределить и что-то еще.

Также упростил файл .env и прописал умолчания в docker-compose.yml, теперь из настроек для Docker только хост Nginx и возможность установить Xdebug в PHP.

В общем, никаких раздельных конфигов, всё оптимизировано и упрощено.

Заключение

Новая версия теперь по умолчанию в репозитории, запустить новый проект проще простого.

git clone https://github.com/bezumkin/vesp.git
cd vesp
cp .env.dist .env
cp docker-compose.override.yml.dist docker-compose.override.yml
docker-compose up --build

Если у вас уже есть проект с названием vesp в докере, нужно указать новое имя в .env перед запуском, например:

COMPOSE_PROJECT_NAME=vesp-new

Миграции и сиды теперь накатываются при первом же старте, никаких лишних телодвижений.

Дожидаемся в консоли надписи Vite client warmed up in, открываем 127.0.0.1:8080 и входим в админку, используя логин и пароль admin.

Все свои новые проекты я буду делать на этой версии, так что будут еще разные правки по мере нахождения проблем.

← Предыдущая заметка
Обновил Webstartpage.ru
Следующая заметка →
Релиз @vesp/nuxt-fontawesome
Комментарии (98)
inetloverАлександр Наумов
24.01.2024 18:26

Василий, добрый день!

Когда выполняю команды в такой последовательности:

cp .env.dist .env
cp docker-compose.override.yml.dist docker-compose.override.yml
docker-compose up --build

Получаю ошибку:

ERROR: The Compose file './../docker-compose.override.yml' is invalid because:
services.mariadb.restart contains an invalid type, it should be a string
services.nginx.restart contains an invalid type, it should be a string
services.node.restart contains an invalid type, it should be a string
services.php-fpm.restart contains an invalid type, it should be a string

Когда в такой:

cp .env.dist .env
docker-compose up --build

Все встает и работает.

inetloverАлександр Наумов
24.01.2024 19:09

Да, только вот строк** Vite client warmed up in** в консоли я не дождался, загрузка остановилось на:

Отсюда и в админку не попал.

bezumkinВасилий Наумкин
25.01.2024 02:17

То, что этих строк нет - это логично, потому что нет файла docker-compose.override.yml и фронт запустился в production режиме, а не в режиме разработки.

Но сайт всё равно должен работать по адресу 127.0.0.1:8080:

bezumkinВасилий Наумкин
25.01.2024 02:12

ERROR: The Compose file './../docker-compose.override.yml' is invalid because:

Возможно, у тебя другая версия Docker, но решается это просто. Нужно поменять все

restart: no

на

restart: "no"

То есть, сделать их строками. Внёс это исправление в репозиторий.

Если что, у меня такая версия

bezumkinВасилий Наумкин
30.01.2024 05:05

Разобрался, почему у тебя была ругань не на строки в конфиге. Это потому, что используется старая версия docker-compose v1, когда он еще был отдельным приложением на Python.

С версии 2 он встроен в Docker и вызывается как docker compose - то есть через пробел, теперь это внутренняя команда самого докера.

У меня на MacOS работает и так и эдак - у обеих команд версии 2+, а вот на Ubuntu нет. Более того, официальная инструкция по установке докера предлагает отдельный docker-compose и вовсе удалить.

А еще есть возможность создать ссылку для совместимости:

Буду менять свои инструкции на новый формат команд.

inetloverАлександр Наумов
30.01.2024 10:58

Буду менять свои инструкции на новый формат команд.

Василий, и еще просьба, добавь в инструкцию, как открыть порт для БД в режиме разработки.

Но в принципе и не помешало бы подружить с phpMyAdmin даже на сервере, хотя бы иметь инструкцию, как это безопасно сделать, мало ли если пойдет что-то не так, когда добавляешь свои наработки в рабочий проект и приходится вмешиваться. Конечно VESP не так, как MODX завязан на БД, но привычка то осталась )).

bezumkinВасилий Наумкин
30.01.2024 12:07

когда добавляешь свои наработки в рабочий проект и приходится вмешиваться

Для этого и придуманы миграции. Тестируешь всё локально и в продакшене они так же работают. Смысл переходить на Docker, если ты на живом сервере собираешься что-то делать?

Это же главная фишка, что у тебя локально и на сервере одна и та же система, которая ведёт себя одинаково.

PhpMyAdmin просто некуда подключаться, в рабочем режиме открыт только порт 8080, а БД изолирована. К ней можно подключиться только через консоль докера:

docker exec -ti имяконтейнера mariadb -uvesp -pvesp vesp

inetloverАлександр Наумов
30.01.2024 14:23

Василий, спасибо! А за это: docker exec -ti имяконтейнера mariadb -uvesp -pvesp vesp- отдельное спасибо!

Для этого и придуманы миграции. Тестируешь всё локально и в продакшене они так же работают. Смысл переходить на Docker, если ты на живом сервере собираешься что-то делать?

Я это все прекрасно понимаю и благодаря тебе сейчас пытаюсь всему этому научится )).

inetloverАлександр Наумов
25.01.2024 18:41

Василий, добрый день! Спасибо!

Решил данную проблему полной переустановкой Докера, видимо была сильно старая версия.

Сейчас у меня проблема с входом в админк. Дождался в консоли появления Vite server warmed up in 32919ms и пошел смотреть админку http://127.0.0.1:8080/admin, а там ошибка 401:

А в консоли ошибка 404 не может обнаружить файл Service Worker:

inetloverАлександр Наумов
25.01.2024 22:30

Василий, с этой проблемой разобрался.

Но сейчас не пускает в админку. Пароль принимает, toast показывает приветствие, а больше ничего не происходит.

bezumkinВасилий Наумкин
26.01.2024 01:54

Попробуй из анонимного режима.

Есть подозрение, что у тебя браузер что-то закэшировал по этому адресу от старых проектов. Не зря же он ищет несуществующий sw.js.

inetloverАлександр Наумов
27.01.2024 00:12

Спасибо, попробовал разные варианты и браузеры менял но не вышло, буду переустанавливать.

Но вот Орбита встала, как надо и в админку впускает!

bezumkinВасилий Наумкин
27.01.2024 03:06

Это странно, учитывая, что новый Vesp и сделан на базе Орбиты - я оттуда всё перетаскивал, включая конфиги.

Смотри тогда, что в консоли браузера и докера - должна быть какая-то ошибка. И еще, попробуй всё сделать заново - я вчера закомитил разные улучшения в Vesp, надо обновить исходники.

Если не разберёшься, напиши мне в телеграм, помогу.

inetloverАлександр Наумов
29.01.2024 14:35

Василий, добрый день!

Понял откуда ноги растут, почему не впускает в админку:

Если устанавливаю так, то проблемы нет:

git clone https://github.com/bezumkin/vesp.git vesp
cd vesp
cp .env.dist .env
docker-compose up --build

А если так, то в админку не впускает:

git clone https://github.com/bezumkin/vesp.git vesp
cd vesp
cp .env.dist .env
cp docker-compose.override.yml.dist docker-compose.override.yml
docker-compose up --build

Может у меня проблема в установленном Docker, устанавливал его по этой инструкции https://drive.google.com/file/d/1aZxgFjnIFDLTw57jMbIHq7oyK_2xi6Ro/view на Ubuntu 22.04, Docker 24.0.5?

bezumkinВасилий Наумкин
30.01.2024 01:44

На будущее - Docker нужно ставить по инструкции с официального сайта, так надёжнее.

У тебя, получается, вся разница только в файле docker-compose.override.yml, но я не вижу там ничего такого, что бы могло сломать авторизацию.

Просто открытые порты и restart: no сервисам, чтобы они не стартовали автоматически при старте системы. Видимо, дело в том, что frontend запускается в development режиме и что-то не работает.

Сейчас попробую загрузиться с Ubuntu Live USB и там проверить.

bezumkinВасилий Наумкин
30.01.2024 07:20

Поставил Ubuntu 22.04.3 LTS на внешний HDD (офигел от тормозов, конечно, после SSD) и всё у меня заработало.

Контейнер с node запустился только со второго раза, первый раз yarn выдавал ошибку ENOSYS Function not implemented. Второй раз всё ок. Ну и разрешения на upload и tmp указал 777.

Авторизация работает в режиме разработки, всё хорошо.

inetloverАлександр Наумов
30.01.2024 09:54

Спасибо!

Я еще сразу же после запуска получаю ошибку 500 и только после Ctrl + F5 я могу видеть кнопку входа.

Буду дальше пробовать, переустановлю Докер по оф. инструкции, может версия Docker Compose у меня не подходящая.

inetloverАлександр Наумов
02.02.2024 18:06

В принципе я понял в чем у меня проблема, все дело правах на папки которые создал движок по команде: docker-compose up --build .

Я не мог авторизоваться, потому что у папки docker/mariadb/ был какой-то загадочный владелец user #999.

Сейчас ставлю в такой последовательности:

git clone https://github.com/bezumkin/vesp.git vesp
cd vesp
cp .env.dist .env
docker-compose up --build

После, как все новые папки созданы, устанавливаю на все права 777, а потом:

cp docker-compose.override.yml.dist docker-compose.override.yml
docker-compose up --build

И вроде все работает как надо.

bezumkinВасилий Наумкин
02.02.2024 21:26

У меня такой же владелец 999 с группой 999 и это никак не мешает.

Более того, у тебя вроде как на той же машине нет проблем с Орбитой, у которой наверняка те же права на директорию. В общем, мистика.

inetloverАлександр Наумов
03.02.2024 14:04

Спасибо, буду разбираться!

У Орбиты в инструкции не было команды: cp docker-compose.override.yml.dist docker-compose.override.yml, отсюда на начальном этапе и проблем не заметил.

Василий, а ты команду docker с sudo в Ubunte запускал?

bezumkinВасилий Наумкин
04.02.2024 05:09

Василий, а ты команду docker с sudo в Ubunte запускал?

Вроде да, не помню уже.

Если получаешь access denied, значит нужно использовать sudo. Если нет - нет.

inetloverАлександр Наумов
04.02.2024 16:38

Спасибо!

futurisFuturis
26.01.2024 07:17

Если речь идет о WSL - не лишне будет выполнить

sudo chmod -R 777 tmp

У меня тоже не пускало, теперь я команды установки последовательно выполняю. Сначала клонирую репозиторий, потом расшариваю папку tmp и далее запуск. Во всяком случае теперь админка работает.

bezumkinВасилий Наумкин
26.01.2024 07:55

Только что проверял на Windows с Docker на Hyper-V - и там никаких проблем с разрешениями не было.

Судя по цвету терминала у Александа вообще Ubuntu =)

futurisFuturis
26.01.2024 08:06

да, глупость сморозил))

futurisFuturis
26.01.2024 08:11

Василий, есть пара вопросов по запуску в Докере. Буду благодарен, если прокомментируешь.

Сначала про production. Как понял, если я не переименовывать файл docker-compose.override.yml.dist, то проект запускается в режиме production. Об этом же выводится сообщение - vite v5.0.11 building SSR bundle for production... В этом случае при запуске не выводится сообщение - Vite client warmed up in ... Вместо этого - Listening on http://[::]:3000 . На локалке в этом режиме все запускается и админка работает. Правильно ли я понимаю, что в качестве инструкции по дальнейшей настройке рабочего сервера можно использовать твой пост про запуск Орбиты?

bezumkinВасилий Наумкин
26.01.2024 08:47

Да, верно.

У тебя на сеервере образуется локальный порт 8080, на который нужно направить Nginx с настроенными сертификатами и правильным доменным именем. Если проектов несколько, то нужно поменять им порты, чтобы не пересекались.

У меня, например, все порты от 10000.

futurisFuturis
26.01.2024 09:29

Понял, спасибо! А порты меняются в docker-compose.yml - NGINX_PORT=${NGINX_PORT:-8080} ? А "нодовский" порт 3000 - это чисто внутри Докера? Если у меня на сервере порт 3000 занят - они не пересекаются?

bezumkinВасилий Наумкин
26.01.2024 09:58

docker-compose.yml менять не нужно, просто укажи новый порт в .env файле

NGINX_PORT=10002

Порты внутри докера не пересекаются. Если что-то пересечется - увидишь ошибку.

futurisFuturis
26.01.2024 12:07

Ок, спасибо! А при запуска в "локальном режиме" (с активированным файлом docker-compose.override.yml) у меня почему-то контейнер php-fpm автоматом не запускается вместе с другими контейнерами. Выдает ошибку php-fpm-1 exited with code 255 . Правда лечится это элементароно - ручным запуском контейнера. После чего все прекрасно работает. Может особенность Докера в WSL.

bezumkinВасилий Наумкин
26.01.2024 13:17

Посмотри предыдущие сообщения от этого php-from контейнера, может там разгадка.

futurisFuturis
27.01.2024 07:11

Может быть, там упоминается об ошибках, но что с этим делать (кроме запуска контейнера вручную) я пока не знаю.

In Connector.php line 65:
SQLSTATE[HY000] [2002] Connection refused
migrate [-c|--configuration CONFIGURATION] [-p|--parser PARSER] [--no-info] [-e|--environment ENVIRONMENT] [-t|--target TARGET] [-d|--date DATE] [-x|--dry-run] [--fake]

bezumkinВасилий Наумкин
28.01.2024 03:57

Connection refused

Это значит, что БД не принимает подключение и поэтому контейнер PHP не может выполнить команду и останавливается.

Если ты затем руками его запускаешь и всё хорошо, значит БД просто не успевает запуститься и принять первое подключение от PHP. Почему не успевает - непонятно.

Чтобы такого не было в конфиге докера для php-fpm прописана зависимость

    depends_on:
      - mariadb

Можно попробовать поменять команду на запуск в override файле таким образом:

    command: sh -c 'composer install && sleep 5 && composer db:migrate && php-fpm'

То есть, добавить таймаут 5 секунд перед попыткой выполнения миграций.

futurisFuturis
28.01.2024 06:23

Ну да! Теперь все запускается. Спасибо!

futurisFuturis
30.01.2024 07:05

В качестве дополнительной информации опишу "результаты дальнейших тестов".) VESP в нынешней редакции у меня запускается, только если я запускаю его с "дефолтными" значениями DB_DATABASE, DB_USERNAME и DB_PASSWORD - vesp. Звучит как бред, но это факт.)) Т.е. я запускаю единой командой:

git clone https://github.com/bezumkin/vesp.git
cd vesp
cp .env.dist .env
cp docker-compose.override.yml.dist docker-compose.override.yml
docker-compose up --build

Далее чтобы контейнер php-fpm-1 "не брыкался" я добавляю && sleep 5 && в docker-compose.override.yml как ты советовал. В админку пускает, в моем случае по-крайней мере, только после расшаривания прав на папку tmp, что проблемой, разумеется не является. И после этого я запускаю и все ОК.

Но далее, я решил изменить данные DB. Поскольку я не знаю как это сделать в Докере, и можно ли вообще это сделать - я переустановил VESP и изменил значения DB_DATABASE, DB_USERNAME и DB_PASSWORD в .env. Предварительно вычистил Докер. И вот в этом случае php-fpm-1 отказывается работать, даже если добавить && sleep 5 && или запустить его вручную. Причем в обоих режимах - на продакшене то же самое. Выдается ошибка:

SQLSTATE[HY000] [1045] Access denied for user 'vesp3'@'172.19.0.3' (using password: YES) - vesp3 я проставил значения DB.

bezumkinВасилий Наумкин
30.01.2024 09:59

И вот в этом случае php-fpm-1 отказывается работать, даже если добавить && sleep 5 && или запустить его вручную.

Ну так а ты поменял настройки БД в файле .env? PHP же использует их для подключения, видимо они не совпадают.

VESP в нынешней редакции у меня запускается, только если я запускаю его с "дефолтными" значениями DB_DATABASE, DB_USERNAME и DB_PASSWORD - vesp. Звучит как бред, но это факт.))

А зачем тебе их вообще менять? Они не имеют никакого значения: БД внутри докера, закрыта по умолчанию для подключения снаружи. При разработке порт открывается, но это же на локальном компе.

БД изолирована внутри докера, поэтому логин и пароль вообще без разницы, нужны только для подключения соседних контейнеров, таких как PHP.

futurisFuturis
30.01.2024 11:23

Ну так а ты поменял настройки БД в файле .env? PHP же использует их для подключения, видимо они не совпадают.

Конечно поменял. DB_DATABASE, DB_USERNAME и DB_PASSWORD вместо vesp поставил vesp3. А что, эта версия ставится с предустановленными настройками бд, юзера и пароля? Наверное поэтому она и устанавливается командой docker-compose up --build, а прошлая - просто docker-compose up? Насколько помню в прошлой редакции VESP я мог изменять данные DB.

А зачем тебе их вообще менять? Они не имеют никакого значения: БД внутри докера, закрыта по умолчанию для подключения снаружи. При разработке порт открывается, но это же на локальном компе.

Дело не в том, что мне нужно их менять. Просто я поменял и вижу проблему, а пока еще толком не знаю как правильно нужно работать с Докером. Если менять не нужно и это снимет вопросы - значит и не буду менять. Я просто подумал, а если на сервере у меня будет висеть несколько проектов на VESP - как к базам подключаться из PHPMyAdmin? Короче по-старинке еще мыслю - как будто "не в Докере".)

bezumkinВасилий Наумкин
30.01.2024 12:01

А что, эта версия ставится с предустановленными настройками бд, юзера и пароля?

Открой файл docker-compose.yml - там прописаны все значения по умолчанию. Их можно переопределить, указав в .env:

# Это для инициализации БД в Docker
MARIADB_DATABASE=
MARIADB_USER=
MARIADB_PASSWORD=

# Это для подключения PHP
DB_DATABASE=
DB_USERNAME=
DB_PASSWORD=

Указанные значения в этих переменных должны совпадать.

а пока еще толком не знаю как правильно нужно работать с Докером

Ну так может уже пора книжку почитать какую, или видеокурсы посмотреть по Docker?

как к базам подключаться из PHPMyAdmin?

Никак, в рабочем режиме контейнеры закрыты от подключения снаружи. Можно зайти только через docker exec -ti имяконтейнера mariadb

futurisFuturis
30.01.2024 13:53

Блин вот стыдоба то(( . Замылилась голова от переустановок и в двух конфигах запутался)

Ну так может уже пора книжку почитать какую, или видеокурсы посмотреть по Docker?

Конечно пора. Спасибо большое за помощь!

inetloverАлександр Наумов
01.02.2024 10:54

Василий, добрый день!

Столкнулся с проблемой, что бы изменения вступили в силу, приходится остановить контейнеры и заново их запустить.

Что сделать, что бы стало работать без перезагрузки?

inetloverАлександр Наумов
01.02.2024 11:05

Может быть проблема моя в том, что я работаю без файла docker-compose.override.yml?

bezumkinВасилий Наумкин
02.02.2024 00:47

Естественно.

Когда у тебя frontend в production режиме - он собран в готовые файлы, которые не меняются от того, что ты поменял их исходники.

Именно для этого и нужен development режим, чтобы было отслеживание изменений и пересборка.

Там же команды разные в yml файлах: или yarn start или yarn dev - не обратил внимания?

inetloverАлександр Наумов
02.02.2024 10:49

Спасибо!!

futurisFuturis
05.02.2024 08:58

Василий, возник вопрос, напрямую не связанный с VESP, но может у тебя будет возможность подсказать в каком направлении копать. Я добавил в админку страницу для постов - frontend\src\pages\admin\posts.vue . И далее страницу редактирования постов (frontend\src\pages\admin\posts\[id]\edit.vue) и форму создания - frontend\src\pages\admin\posts\create.vue .

Форма создания поста, по аналогии с user-roles\create.vue (содержит тег <forms-user-role v-model="record" />) и users\create.vue (<forms-user v-model="record" />) должна содержать тег <forms-post v-model="record" />. Но в таком виде модал не вызывается. Но стоит мне заменить код моей формы на код формы из Орбиты, или просто заменить тег <forms-post v-model="record" /> на <forms-page v-model="record" /> как модал начинает вызываться. Форма, при этом, конечно вызывается без полей, т.к. она никак не связана с моей моделью Post, но модал даже в таком виде работает. И я не могу понять, почему не вызывается модал с моим тегом <forms-post v-model="record" />? Ведь именно так должно быть правильно. P.S. Добавил картинку с анимацией, как это происходит.

bezumkinВасилий Наумкин
05.02.2024 22:55

И я не могу понять, почему не вызывается модал с моим тегом ? Ведь именно так должно быть правильно.

Да, так и должно быть. Раз модалка не появляется, значит в твоей форме какая-то ошибка. Открывай консоль браузера и смотри, на что ругается. Без консоли при разработке фронтенда ловить вообще нечего.

Ты сам файл-то создал в components/forms/post.vue? С таким кодом компонента модалка работать должна:

<template>
    <div>Привет!</div>
</template>

<script setup lang="ts"></script>

Ну а дальше добавляй поля формы по образу и подобию. Если сломается - будет понятно, от чего.

Добавил картинку с анимацией, как это происходит.

На этот сайт можно грузить короткие MP4 видосики.

futurisFuturis
06.02.2024 06:12

Файл-то components/forms/post.vue у меня был. Я взял за основу файл с Орбиты и переделал под свои поля. Но, очевидно там были ошибки. С твоим "минималистичным" кодом формы модал заработал! Спасибо за помощь! Буду разбираться дальше.

inetloverАлександр Наумов
09.02.2024 22:08

Василий, добрый день!

Если есть возможность, перепиши, пожалуйста, кусок кода на Vue 3 в Composition API. Читаю документацию, но пока во многом не разобрался, думаю на этом примере получится быстрее понять как оно устроено.

  mounted() {
    window.addEventListener("scroll", this.handleScroll);
  },
  methods: {
    // Скролинг Вверх - Вниз
    handleScroll() {
      if (process.client) {
        const currentScrollPosition = window.scrollY;

        if (currentScrollPosition < this.scrollPosition) {
          console.log("Scrolling up");
          this.showFullNav = true;
        } else {
          console.log("Scrolling down");
          this.showFullNav = false;
        }

        this.scrollPosition = window.scrollY;
      }
    },
}
bezumkinВасилий Наумкин
10.02.2024 08:40

Примерно так:

const showFullNav = ref()
const scrollPosition = ref()

function handleScroll() {
    if (process.client) {
        const currentScrollPosition = window.scrollY;

        if (currentScrollPosition < scrollPosition.value) {
            console.log("Scrolling up");
           showFullNav.value = true;
        } else {
            console.log("Scrolling down");
            showFullNav.value = false;
        }

        scrollPosition.value = window.scrollY;
    }
}

onMounted(() => {
    window.addEventListener("scroll", handleScroll)
})
inetloverАлександр Наумов
10.02.2024 12:56

Василий, спасибо большое!

Еще пару вопросов:

  1. this в Composition API не используем?

  2. Плагины не нужно регистрировать в nuxt.config.ts?

bezumkinВасилий Наумкин
10.02.2024 15:07

this в Composition API не используем?

Именно! Нет никакого this в новом синтаксисе, в этом весь смысл - использовать везде функции, не зависящие от контекста исполнения, то есть от this.

Плагины не нужно регистрировать в nuxt.config.ts?

Не нужно, да. Если они лежат в директории plugins, то новый Nuxt автоматически их регистрирует. То же самое и с components.

inetloverАлександр Наумов
10.02.2024 15:58

Спасибо, большое, сэкономил мне кучу времени!

inetloverАлександр Наумов
16.02.2024 23:07

Василий, добрый день!

Подключаю модуль в nuxt.config.ts

  modules: ['@vesp/frontend', '@nuxtjs/color-mode'],

В итоге ошибка:

ERROR  Cannot find module '/vesp/frontend/@nuxtjs/color-mode'

Почему-то модуль ищет в пакете Vesp.

Подскажи, пожалуйста, как регистрировать установленный модуль?

Устанавливаю так:

 cd /frontend 
yarn add --dev @nuxtjs/color-mode
bezumkinВасилий Наумкин
17.02.2024 01:29

Почему-то модуль ищет в пакете Vesp.

Нет, это путь к зависимостям на диске внутри Docker - /vesp/frontend/node_modules. Что-то ты куда-то не туда установил, похоже сделал это не внутри контейнера Docker.

Меня настораживает, что ты делаешь cd /frontend. Во-первых, это путь от корня твоего диска, а во-вторых - при открытии консоли фронтенда, ты уже должен быть в нужной директории:

В любом случае, этот модуль тебе не нужен, потому что useColorMode уже есть в BootstrapVue.

Лучше использовать его, чтобы не было такого предупреждения:

inetloverАлександр Наумов
17.02.2024 15:34

похоже сделал это не внутри контейнера Docker.

Да, так точно. Устанавливаю не внутри контейнера vesp-node-1, спасибо, буду знать.

В любом случае, этот модуль тебе не нужен, потому что useColorMode уже есть в BootstrapVue.

О, за это, спасибо, большое! Так конечно правильнее и легче будет.

inetloverАлександр Наумов
24.02.2024 19:57

Василий, добрый день!

Подключаюсь в тестовом режиме к БД через MySQL Workbench - работает. Хочу просмотреть таблицы - Workbench схлопывается. В файл docker-compose.yml добавил phpMyAdmin

  phpmyadmin:
    image: phpmyadmin
    restart: always
    ports:
      - 8888:80
    depends_on:
      - mariadb
    environment:
      - PMA_ARBITRARY=1

Хочу подключится через него - тоже не выходит.

Подскажи, пожалуйста, в чем может быть проблема. Записал коротенькое видео:

inetloverАлександр Наумов
24.02.2024 22:06

С Workbench я вроде разобрался, хотелось бы еще, ради эксперимента, phpMyAdmin таким способом подключить.

bezumkinВасилий Наумкин
25.02.2024 01:19

хотелось бы еще, ради эксперимента, phpMyAdmin таким способом подключить.

Зачем? Есть же нормальные десктопные приложения для работы с БД, в тот же PhpStorm встроен DataGrip.

Я никогда не ставил PhpMyAdmin в Docker, так что ничего подсказать не могу.

inetloverАлександр Наумов
25.02.2024 12:54

Зачем? Есть же нормальные десктопные приложения для работы с БД, в тот же PhpStorm встроен DataGrip.

Василий, спасибо, уже так делаю!

inetloverАлександр Наумов
26.02.2024 23:27

Василий, добрый день!

Тебе случайно не встречалась ошибка запрета нижнего подчеркивания в названии css селектора?

bezumkinВасилий Наумкин
27.02.2024 03:28

Это Stylelint, такие правила прописаны в Vesp.

Можешь прописать свои - https://stylelint.io

inetloverАлександр Наумов
27.02.2024 18:12

Спасибо большое!

inetloverАлександр Наумов
01.03.2024 21:15

Василий, добрый день!

можешь прописать свои

Укажи, пожалуйста, где это сделать?

Я только один файл .stylelintcache в корне нашел, а в модуле @vesp ничего не нашел.

bezumkinВасилий Наумкин
02.03.2024 06:21

Всё верно, этот файл тебе и нужно менять.

inetloverАлександр Наумов
29.02.2024 20:38

Василий, добрый день!

Может быть ты имел дело с PWA в Nuxt 3, не подскажешь какой модуль лучше выбрать:

Есть официальный модуль: vite-pwa-nuxt, есть как будто второй официальный модуль @nuxtjs/pwa?

inetloverАлександр Наумов
29.02.2024 21:04

Похоже с вопросом поспешил, судя по обновлениям на Гитхабе @nuxtjs/pwa для Nuxt 2.

bezumkinВасилий Наумкин
01.03.2024 04:30

С PWA пока не разбирался, мне кажется это не особо популярная штука.

Если надо просто иконки добавить, то вот приятный сервис - https://realfavicongenerator.net

inetloverАлександр Наумов
01.03.2024 21:20

Если надо просто иконки добавить, то вот приятный сервис - https://realfavicongenerator.net

А сюда public/favicons с помощью этого сервиса иконки сгенерированы?

bezumkinВасилий Наумкин
02.03.2024 06:20

Честно говоря, не помню как именно было на этом сайте, он уже давно работает.

А так этот сервис у меня в закладках и я его регулярно использую.

inetloverАлександр Наумов
05.03.2024 22:54

С PWA пока не разбирался, мне кажется это не особо популярная штука.

Я подписан на PWA — русскоязычное сообщество в Телеграмме, правда не сильно успеваю читать все что там пишут, но по ощущениям есть надежда, что PWA потеснит нативные приложения. Даже iphone 14 стал принимать push-уведомления и разрешил ставить на iphone приложения из других store, хотя Apple долго держался так как хорошо зарабатывал на размещении приложений в Apple Store и ему было не выгодно развитие PWA.

Василий, подскажи, пожалуйста:

Есть сборка Nuxt3 + @vite-pwa/nuxt https://github.com/jahidanowar/nuxt3-pwa, делаю все так же на VESP 3 но никак не могу добиться, что бы сгенерировался манифест, перепробовал кучу вариантов.

Вопрос: в nuxt.config.ts мы пишем:

 modules: [
    '@vite-pwa/nuxt'
  ],
  pwa: {
    /* PWA options */
  }

И этого достаточно, что бы в теории заработало?

bezumkinВасилий Наумкин
06.03.2024 04:39

И этого достаточно, что бы в теории заработало?

По идее - да. Во всяком случае, именно так модули устанавливаются в Nuxt.

inetloverАлександр Наумов
06.03.2024 12:21

Ок, спасибо!

inetloverАлександр Наумов
06.03.2024 19:06

Нашел проблему, закомментировал в nuxt.config.ts строку:

{rel: 'manifest', href: '/favicons/site.webmanifest', color: '#fff'},

Теперь манифест создается.

inetloverАлександр Наумов
05.03.2024 23:15

Вот список крупных сайтов с PWA https://github.com/FluorescentHallucinogen/pwa-awesome-ru?tab=readme-ov-file#%D0%BF%D1%80%D0%B8%D0%BC%D0%B5%D1%80%D1%8B-pwa у Тинькова очень хорошо сделан, из-за реактивных технологий не поймешь, что не нативное приложение.

egorИван
04.03.2024 07:53

Правильно ли я понял, что это только для тех, у кого есть Apple Laptop и 10+ лет опыта бэкенд разработки?

запустить новый проект проще простого.

То, что я вижу тут комментариях, это как люди с виндой натурально "пляшут" с бубнами (у всех разные).

Василий, уточните пожалуйста, на modhost работать не будет, верно? Потому что:

-bash: docker: command not found

-bash: apt: command not found

-bash: sudo: command not found

-bash: apt-get: command not found

Ну и так далее. Т.е. никакие нужные допы я не смог поставить. Вероятно, я что то не так делаю. Ладно. Спасибо. Короче, зачем я вообще это тут пишу.

bezumkinВасилий Наумкин
04.03.2024 14:54

на modhost работать не будет, верно?

Верно, там нет Docker.

Нужен свой сервер, но я бы советовал начать с разработки на локальной машине.

inetloverАлександр Наумов
14.03.2024 20:39

Василий, добрый день!

Не подскажешь, как подключить плагины bootstrap-vue-next?

В Vesp 2 мы подключали нужные плагины в nuxt.config.js, а в Vesp 3 не пойму где их подключать, например тот же navbar в Орбите не нашел как он подключен.

bezumkinВасилий Наумкин
15.03.2024 01:05

А здесь ничего не надо вручную подключать, всё само автоматически импортируется.

Просто используй любые нужные компоненты BootstrapVue в коде и будет работать.

inetloverАлександр Наумов
15.03.2024 23:29

Спасибо, понял!

inetloverАлександр Наумов
16.03.2024 23:56

Василий добрый день!

Скажи, пожалуйста, как формируется ключ vueuse-color-scheme?

Пересмотрел все твои правки https://github.com/bezumkin/orbita/commit/1bdc25082af220669d469d0f2204dfe29f859c78, когда ты добавил Орбите темную тему, так и не понял, как VueUse генерирует этот ключ.

И еще скажи, в сохранении выбранной темы участвует только localStorage, в Pinia не участвует?

Помню, что в Vesp 2 при сохранении корзины данные писались в localStorage и Vuex.

bezumkinВасилий Наумкин
18.03.2024 02:57

Орбита использует Bootstrap 5.3, а он поддерживает смену темы прямо из коробки.

useColorMode нужен только для переключаения атрибута data-bs-theme у тега body:

const {system, store} = useColorMode({attribute: 'data-bs-theme', selector: 'body'})
console.log(system) // это системное значение темы - тёмная или светлая
store.value = 'dark' // а это переключение темы в браузере

Дальше уже работает Bootstrap, никакие ключи я не формирую.

И еще скажи, в сохранении выбранной темы участвует только localStorage, в Pinia не участвует?

Нет, я не знаю зачем это писать в общее хранилище, если вся работа идёт в одном месте и другим компонентам эти данные не нужны.

inetloverАлександр Наумов
18.03.2024 22:19

Василий, спасибо!!!

Дело в том, что я решил добавить на главную страницу сайта анимированную презентацию, и сделать ее отключение для тех, кто ее уже видел и ему она надоела.

Я считал что Vuex, Pinia нужны для vue router для сохранения данных при переходе между страницами без перезагрузки, а если страница перезагружается то данные берутся с localStorage. Сейчас смотрю на компонент переключения темы с светлой на темную и понимаю, что он не использует Pinia а использует только localStorage.

Вот сейчас не могу понять, а как правильно, нужно ли в моей задачи использовать Pinia и localStorage или только один localStorage?

Нашел мануал, как совместно использовать Pinia и localStorage https://runthatline.com/how-to-use-local-storage-pinia/.

bezumkinВасилий Наумкин
19.03.2024 03:45

Pinia, как и Vuex нужны для обмена данными между компонентами.

Хранилища - реактивные. Если вывод формы авторизации завязан на значение в хранилище, то он отреагирует сразу после изменения этого значения. Таким образом форму авторизации можно показывать при попытке оставить комментарий, или голосовании - то есть из любого места приложения.

А в случае с localStorage, никакой реакции не будет, потому что компонент должен сам как-то следить за обновлением значения. Поэтому localStorage годится только для хранения данных между обновлениями страницы.

Для VueRouter ни реактивные хранилища, ни localStorage не нужны. Для твой задачи достаточно одного localStorage, просто запоминать, что юзер скрыл анимацию.

inetloverАлександр Наумов
19.03.2024 10:06

Спасибо большое за такой развернутый ответ!!

futurisFuturis
24.03.2024 07:51

У меня вопрос по оформлению страниц на фронте. Понятно, что это не вопрос VESP-а... На стороне бэкенда я создал некое подобие блоговой ленты, содержащей все посты и страницу отдельного поста. Т.е. API отдает страницы http://127.0.0.1:8080/api/admin/posts и http://127.0.0.1:8080/api/web/posts/post-1 . Как понимаю, это означает, что бэкенд работает и данные в JSON отдает. Вопрос только в том, как это вывести на фронте? Вообще область бэкенда стала более понятной. Не на уровне детального понимания, но свет в конце туннеля забрезжил.) Плюс php подучиваю. А вот с фронтом пока беда - в "Data fetching" на Nuxt 3 я пока не могу въехать. Смотрю код отдельных страниц на Орбите, но там более сложная модель данных.

bezumkinВасилий Наумкин
25.03.2024 01:07

Как понимаю, это означает, что бэкенд работает и данные в JSON отдает.

Верно.

Вопрос только в том, как это вывести на фронте?

Если это Vesp 3, то примерно так:

<template>
    <div class="wrapper">
        <div v-for="item in items" :key="item.id">
            <pre>{{ item }}</pre>
            <b-link :to="{name: 'posts-alias', params: {alias: item.alias}}">{{ item.title }}</b-link>
        </div>
    </div>
</template>

<script setup>
const url = 'web/posts'
const items = ref([])

try {
    items.value = await useGet(url)
} catch (e) {}
</script>

Это для вывода списка заметок со ссылкой на страницу каждой заметки.

futurisFuturis
26.03.2024 07:39

Страница отдельного поста заработала сразу в том виде, как ты написал.) А вот в ленте постов контент не выводился - выдавалось

"500 Missing required param "alias""

. Я пытался по-разному варьировать код и когда в ссылке вместо 'posts-alias' написал просто 'posts' ( т.е. -

<b-link :to="{name: 'posts', params: {alias: item.alias}}">{{ item.title }}</b-link>

) - получил на фронте контент, но в виде массива, как в бэкенде.)

futurisFuturis
24.03.2024 07:53

Посты у меня состоят из title, content и уникального алиаса. На фронте я создал страницу frontend/src/pages/posts/[alias].vue для вывода отдельного поста. Может ты сможешь подсказать как самым простым методом вывести пусть хоть один title, чтобы дальше можно было это изучать и развивать?

bezumkinВасилий Наумкин
25.03.2024 01:12

А страница с заметкой должна выглядеть как-то так:

<template>
    <div>
        <h1>{{ item.title }}</h1>
        <pre>{{ item }}</pre>
    </div>
</template>

<script setup>
const url = 'web/posts/' + useRoute().params.alias
const item = ref({})

try {
    item.value = await useGet(url)
} catch (e) {
    showError({statusCode: e.statusCode || 500, statusMessage: e.statusMessage || 'Server Error'})
}
</script>

Код пишу по памяти, не проверял - но примерно так всё и работает.

futurisFuturis
25.03.2024 08:52

Огромное тебе спасибо!))

inetloverАлександр Наумов
25.03.2024 23:52

Василий, добрый день!

Не подскажешь, если установлено несколько копий VESP, то не будет ли проблем если они будут использовать одними и теме же контейнерами?

И еще, после обновления Докера возникла проблема, когда вторая копия VESP начала переименовывать контейнер добавляя в его имя ID:

А потом, при запуске, схлопывается после ошибки:

В итоге, сейчас могу пользоваться только первой копией VESPа, которая создала контейнеры, а все последующие установки VESPа, которые обращаются к этим контейнерам не запускаются из-за ошибки о которой написал выше.

bezumkinВасилий Наумкин
26.03.2024 01:18

Обрати внимание на настройку COMPOSE_PROJECT_NAME в файле .env.

Она должна быть уникальна для каждого проекта.

inetloverАлександр Наумов
26.03.2024 07:35

Блин, спасибо!

Совсем забыл, что в файле .env настройки хранятся, я дальше nuxt.config.ts не смотрю. Сори.

futurisFuturis
02.04.2024 07:31

Василий, ты пишешь про trait FileModel. В дефолтной установке VESP3, которую мы ставим

git clone https://github.com/bezumkin/vesp.git

его нет. Он есть только в репозитории vesp-core. Мне нужно как-то обновить ядро VESP, чтобы получить эти файлы? И еще вопрос - мне теперь нужно разобраться с добавлением изображений к постам. В предыдущем курсе (на Vesp/Nuxt2) загрузка изображений реализовывалась проще, как понимаю теперь для работы с новым Nuxt лучше освоить трейты?

bezumkinВасилий Наумкин
02.04.2024 14:37

Дефолтная установка Vesp тащит с собой и vesp/core, без него она просто не работает.

Загрузка файлов реализуется так же, просто наследуешь свою модель от Vesp\Models\File, а она уже использует нужный трейт.

Трейты к Nuxt не имеют никакого отношения, они для PHP.

futurisFuturis
02.04.2024 15:33

Я имел в виду, что в репозитории Vesp, который мы скачиваем, в отличии от репозитория vesp-core, в директории core/src/Models нет директории Traits с файлом FileModel.php. И дефолтный файл core/src/Models/File.php у нас выглядит совсем не так. Там нет ссылок на трейты.

futurisFuturis
03.04.2024 16:32

Блин, туплю. Я смотрю на файлы своего проекта и не вижу там этих трейтов. Очевидно речь идет о файлах в докеровском контейнере php-fpm-1. Там есть файл /vesp/core/vendor/vesp/core/src/Models/Traits/FileModel.php . И значит мне в своем проекте директория src/Models/Traits с ее содержимым уже не нужна?

bezumkinВасилий Наумкин
04.04.2024 03:23

И значит мне в своем проекте директория src/Models/Traits с ее содержимым уже не нужна?

Я ж не знаю, зачем ты её создавал. Если там нет ничего нужного - то, выходит, что не нужна.

futurisFuturis
04.04.2024 05:56

Я просто немного запутался. Когда в абзаце "Vesp/Core" ты пишешь про "новый trait FileModel", я подумал, что это все должно быть в директории core моего проекта, также как, например, в Орбите есть директория core/src/Models/Traits. И когда ты посоветовал просто "наследовать модель от Vesp\Models\File" и она уже может использовать все методы твоего трейта - я просто не понял откуда все это возьмется, если в директории core у меня ничего такого нет. Я упустил из виду, что vesp-core под капотом Докера и можно так просто наследовать. Ну и Namespaces я еще не успел изучить, чтобы сразу понять твою мысль про Vesp\Models\File. Спасибо за разъяснение!

bezumkin
Василий Наумкин
09.04.2024 01:45
Ошибка 500 Это не похоже на ошибку Nginx, это скорее всего ошибка PHP - надо смотреть его логи. Во...
futuris
Futuris
04.04.2024 05:56
Я просто немного запутался. Когда в абзаце &quot;Vesp/Core&quot; ты пишешь про &quot;новый trait Fil...
bezumkin
Василий Наумкин
20.03.2024 18:21
Volledig!
Андрей
14.03.2024 10:47
Василий! Как всегда очень круто! Моё почтение!
russelgal
russel gal
09.03.2024 17:17
А этот стоило написать хотя бы затем, чтобы получить комментарий от юзера, который ничего не писал ...
inetlover
Александр Наумов
27.01.2024 00:06
Василий, спасибо! Извини, тупанул.
bezumkin
Василий Наумкин
22.01.2024 04:43
Давай-давай!
bezumkin
Василий Наумкин
24.12.2023 11:26
Спасибо!
bezumkin
Василий Наумкин
27.11.2023 02:43
Ура!
bezumkin
Василий Наумкин
25.11.2023 08:30
Vesp тянет 2 зависимости: vesp-frontent для фронта и vesp-core для бэкенда. Их можно обновлять, но э...