Подскажите, пожалуйста, как использовать в сниппете кастомный класс? Сейчас подключаю через $modx->loadClass, но возникла проблема - если запускать данный сниппет из другого сниппета методом $modx->runSnippet - то кастомный класс не виден и получаю ошибку.
В предыдущей статье мы разворачивали Graphcool Prisma с нуля. На выходе кроме всего прочего мы получили веб-интерфейс, через который можно было добавлять новые топики и публиковать их. Но это была простейшая система без каких-либо пользователей. База данных содержала одну основную таблицу - Post (топики) Сегодня мы добавим пользователей, а так же связь Пользователь-Топики и проверку на владельца записей, чтобы публиковать черновики могли только их владельцы. Добавим модель пользователя. Прежде чем связать добавить связь топик-пользователь, просто добавим самостоятельную модель User (Пользователь). Для этого откроем файл server/database/datamodel.graphql Сейчас там прописана только модель Post (Топик). Допишем ниже: Схема описана, теперь надо ее задеплоить, чтобы призма обновила структуру базы данных и сгенерировала необходимые методы для API и работы с базой данных. Для этого перейдем в папку server/ и выполним prisma deploy Результат выполнения: Теперь у нас в базе данных появилась таблица User Запустим веб-консоль, чтобы посмотреть какие методы API у нас теперь имеются. Теперь у нас есть есть схема User. Но по-прежнему нет ни запросов (Queries), ни мутаций (Mutations). query - это обычный запрос, то есть на получение данных. mutation - это запрос на изменение данных. На самом деле это все очень условно, так как GraphQL особо ничего не знает о выполняемых эти запросы/мутации резолверах (функции, обрабатывающие запросы), резолверы на query могут выполнять запросы на обновления, а мутации просто выборки данных. Но есть одна важная деталь: query за один раз можно выполнить сразу несколько и параллельно, в то время как mutation выполняется только поштучно и последовательно. В данном случае у нас получается, что модель есть, но мы не можем с ней ничего делать, то есть через API мы не можем слать запросы ни на создание пользователей, ни на получение их списков, ничего. Откроем файл server/src/schema.graphql и допишем в нем в Query users: [User!]! и в Mutation createUser(name: String!, email: String!, password: String!): User итого получится Обратите внимание на # import Post from "./generated/prisma.graphql" Это не комментарий, это так прописана подгрузка типов нашего приложения. Редактировть тот файл нельзя, он генерируется призмой при деплое. Перезапустим сервер приложения, чтобы вступила в силу новая схема (нажмем Ctrl+C и опять выполним yarn start) и обновим страницу. Вот теперь у нас появились новые методы в схеме Попробуем выполнить запрос на создание пользователя. Запрос выполняется, но результат пустой. Это происходит потому что хотя у нас схема описана, не прописан резолвер на обработку этого запроса. То есть граф обрабатывает запрос, схема вся валидная, выполнение разрешено, но данных нет и не прописана функция на обработку запроса (возврат данных). В таком случае он просто возвращает пустое значение. А вот если бы мы прописали в Query users: [User!]! вместо users: [User!], то тут бы мы получили ошибку от графа, так как знак ! сигнализирует о запрете нулевого значения, то есть обязан быть ненулевой список, и как следует из указания User!, список этот не должен содержать нулевые значения пользователей. Здесь на всякий случай еще раз объясню структуру запроса mutation, логично, указывает на то, что это именно запрос из мутаций выполняется, а не просто query. Это в графе разные группы запросов. createUser - это название конкретной операции, мы так назвали ее в схеме выше. Все что в круглых скобках - это передаваемые параметры в запрос. В фигурных - структура возвращаемых данных. То есть в результате выполнения, если будет создан пользователь, мы сразу получим в ответ указанные поля из данных этого пользователя. Итак, допишем мутацию на создание пользователя. Для этого открываем файл server/src/index.js и в Mutation дописываем наш обработчик createUser. bcrypt я подключил в этом файле выше через const bcrypt = require('bcryptjs') Так как в этой версии приложения пакет bcryptjs не был установлен, устанавливаем его через команду yarn add bcryptjs и после этого опять запускаем сервер. Вот теперь пользователь был создан и на выходе мы получили пароль не в чистом виде, как его передавали, а сразу его хеш. Остается только дописать запрос на получение пользователей в Query. Перезапускаем сервер, выполняем запрос и видим результат. Обратите внимание, что мы не писали никаких запросов на непосредственную работу с базой данных. За нас все необходимые запросы создала призма при деплое новой схемы (когда выполняли prisma deploy). Напомню, что запросы эти пишутся в файл server/src/generated/prisma.graphql А если еще более правильно выражаться, то там не запросы, а API-схемы для еще более низкого слоя всей этой системы - API-сервера призмы, что крутится на порту 4466. То есть получается, что наш проект крутится в своей папке, для него есть своя схема, через которую запросы транслируются на сервер призмы, которая в свою очередь работает с базой данных. При этом в призму мы деплоим изменения только в типах объектов схемы, запросы мы туда не деплоим, это уже наш локальный вопрос. Авторизация пользователей. Ну а теперь добавим непосредственно авторизацию пользователей. Зачем нам пользователи без этого? В схему в Mutation допишем login(email: String!, password: String!): User и там же ниже допишем еще одну модель. Это чтобы в ответ мы получали не только объект пользователя, но и токен. И допишем в резолверы. Перезапускаем сервер, выполняем запрос на авторизацию и получаем ошибку. Это потому что для работы авторизации требуется объявление произвольного секретного ключа. Остановим сервер и запустим вот так: APP_SECRET="wefewfwefwef" yarn start Вот теперь авторизация прошла успешно и мы получили не только объект пользователя, но и токен: Запрос на получение текущего пользователя. Теперь мы напишем такой запрос, который будет возвращать объект текущего пользователя в случае его идентификации. Допишем в схему Query me: User И резолвер Теперь токен, полученный при авторизации укажем в заголовок запроса Authorization. Если все ОК, мы получим пользователя. Обратите внимание на приставку Bearer, ее необходимо указывать. Вот теперь у нас есть не только создание пользователей, но и авторизация. Связываем пользователей и топики. Ну и последний штрих: настроим связи Топик-Пользователь и научимся получать топики конкретных пользователей и авторов топиков. Для этого нам надо подправить наши схемы пользователя и топика. Допишем в модель Post author: User @relation(name: "UserPosts"), а в User posts: [Post!]! @relation(name: "UserPosts"). Получится Задеплоим нашу новую схему prisma deploy. Что примечательно, призма не просто создала новую таблицу для хранения записей Топик-Пользователь, но даже настроила первичные-вторичные ключи. Перезапустим сервер, обновим страницу и у нас уже есть возможность прописывать в запрос пользователя получение топиков. Сейчас у нас список пустой, потому что мы не создавали еще топики от имени пользователя. Для удобства получение ID текущего пользователя вынесем в отдельный метод. И с его использованием чуть перепишем мутацию создания топика. Здесь мы просто дописали получение ID текущего пользователя и если был получен, то передаем в запрос создания топика объект с ID этого пользователя. При чем я специально оставил возможность передачи пустого объекта пользователя, чтобы оставить возможность публикации топиков и анонимно. Вот теперь при создании топика, если пользователь авторизован, прописывается автор в топик. А в списке топиков теперь выводятся авторы, если указаны. А в списке пользователей видны теперь топики пользователей. И совсем не сложно теперь в списке топиков у авторов получить все топики этих авторов. Я уж не буду говорить, что сейчас доступны методы и на редактирование/удаление этих сущностей. Вот так вот за вечер мы настроили себе платформу для регистрации/авторизации и публикации топиков, почти с нуля. На мой взгляд - очень неплохой результат. Я не буду сейчас расписывать программирование фронта под все это (чтобы веб-морда для авторизации была и т.п.), это будет в следующем уроке. Скажу только что материал освоен и там не менее интересно, чем этот урок. Кому интересно, поиграться можно здесь: http://prismagraphql.ru:4000/ Исходники проекта лежат под тегом Lesson2: https://github.com/MODX-Club/prismagraphql-demo/tree/Lesson2
В последнее время я много пишу про GraphQL и т.п., потому что тема действительно очень интересная, технологии очень важные и перспективные, а так же все это отлично состыкуется с MODX, дабы придать жизни внешней части сайта и получить более гибкое API для взаимодействия фронта с бэком. Сегодня я расскажу про graphcool-prisma. Вообще еще недавно они были просто graphcool (и устанавливались в систему именно как graphcool), затем они внезапно стали graphcool-framework (и еще так они вчера мне были известны, и устанавливались как graphcool-framework, хотя и во всех подсказках выводилось как graphcool, что доставляло много путаницы при наличии в системе и graphcool и graphcool-framework). А сегодня, когда я сел написать статью, они вдруг стали просто Prisma. Ну ппц... (хотя prisma, конечно же, проще запомнить и пишется проще). При этом нпм-страница prisma предлагает устанавливать prisma-cli, а там в свою очередь речь идет о graphcool. Короче, еще раз, ппц... Но это они не со зла. Проект очень быстро развивается и видимо какие-то внутренние архитектурные вещи заставляют так делать, типа, выбирайте: или название будет без изменений, или новые современные фишки. Я за современные фишки, а с названием потерплю... Уточнение к стилю изложения: я пишу по мере работы с сервером. Однозначно буду сталкиваться с какими-то подводными камнями и т.п., где-то в процессе находить ответы, поэтому в статье будет много уточнений, метаний по поверхности и т.п. Извиняюсь, если где-то запутано будет и не конкретно. Внимание! Если вы планируете просто запускать свою копию призма-сайта, внизу есть инструкция по быстрой установке одним скриптом. Итак, что же такое Prisma? Это готовое решение для создания своего собственного API на базе GraphQL+ Apollo и еще много все. Главная задача - быстро развернуть основу под то, чтобы принимать внешние запросы, выполнять операции с хранилищем данных, отдавать ответы и т.п. Отдельная строчка - готовая система авторизации и политик безопасности. В общем, там практически все есть для настройки полноценного бэкэнда. И в процессе мы рассмотрим много классных фишек. И, скорее всего, именно эта платформа послужит основой для обновленной версии ShopModxBox. К концу статьи вы поймете почему. А теперь от слов к делу. Сегодня мы развернем призму на сервере с нуля. В качестве хостинг-площадки предлагаю flops.ru (ссылка реферальная). Я не первый год с ними работаю и хотя там есть ограничения на дисковые операции, о которых они не говорят (что очень некрасиво), в целом они очень неплохи и для средних проектов годятся очень даже (под блокчейн не годятся точно, я проверял))). А еще там было 500 рублей на счет при регистрации (надо только карту по-моему указать, но с нее ничего не списывается без вас). Этого вполне достаточно на тесты. Для начала я взял 1Gb памяти, но в процессе работы ожидаемо выяснилось, что этого мало. Поднял до двух (плановая стоимость 700 руб/месяц). Но скорее всего для комфортной работы надо 3Gb (1000 рублей). Разворачиваем чистый сервер. Я работаю в основном только с ubuntu, на других версиях linux не проверял, на windows тоже. В данном случае я развернул ubuntu-16 x64. Первым же делом выполняем apt update и apt upgrade, дабы актуализировать OS. Устанавливаем nginx sudo apt install nginx Устанавливаем прочее ПО - Текстовый редактор. Необязательный шаг. Мне нравится mc, поэтому я его ставлю. Но каждый выбирает для себя свое (может даже vim). sudo apt install mc - sudo apt install git (контроль версий файлов, без него никуда). Создаем нового sudo-пользователя. Некоторые программы выполняются именно от sudo-пользователей (не обязательно root, просто с правами sudo), например docker. useradd USERNAME -d /home/USERNAME -G sudo,www-data -s /bin/bash (USERNAME конечно же заменить на свое, здесь и далее). passwd USERNAME (здесь запросит ввести и подтвердить пароль для пользователя). mkdir /home/USERNAME Чтобы у пользователя работала история команд, подсветка в консоли и т.п., надо создать заготовленный .bashrc cd /home/USERNAME wget https://gist.githubusercontent.com/Fi1osof/2f8ea23f5411c5c7a0e0025f04941aee/raw/.bashrc Установим нового пользователя владельцем своей директории со всем содержимым
chown USERNAME: /home/USERNAME -R Чтобы каждый раз при вызове sudo на новом пользователе не приходилось вводить пароль, разрешим ему sudo без пароля. Открываем для редактирования файл mcedit /etc/sudoers Находим %sudo ALL=(ALL:ALL) ALL и переписываем на %sudo ALL=(ALL:ALL) NOPASSWD: ALL Все, теперь можно авторизовываться этим пользователем и продолжать работу от его имени. Устанавливаем docker sudo apt-get install software-properties-common python-software-properties sudo apt-key adv --keyserver hkp://p80.pool.sks-keyservers.net:80 --recv-keys 58118E89F3A912897C070ADBF76221572C52609D sudo apt-add-repository 'deb https://apt.dockerproject.org/repo ubuntu-xenial main' sudo apt-get update Убедимся, что мы собираемся установить Docker из репозитория Docker, а не из репозитория по умолчанию Ubuntu 16.04: apt-cache policy docker-engine В списке должен быть apt.dockerproject.org Если да, то выполняем непосредственно установку. sudo apt-get install -y docker-engine Проверяем docker -v Docker version 17.05.0-ce, build 89658be По умолчанию, запуск команды docker требует привилегий root, что означает, что вы должны использовать sudo. Также эта команда может запускаться пользователем, включённым в группу docker, которая автоматически создаётся при установке Docker. При попытке использования команды docker пользователем без привилегий sudo или пользователем, не входящим в группу docker, вы получите такой результат: docker: Cannot connect to the Docker daemon. Is the docker daemon running on this host?. See 'docker run --help'. Для того, чтобы не вводить sudo каждый раз при запуске docker, добавьте имя своего пользователя в группу docker: sudo usermod -aG docker $(whoami) (добавляет именно текущего пользователя, поэтому убедитесь, что вы авторизованы нужным пользователем). Для добавления произвольного пользователя sudo usermod -aG docker USERNAME После этого желательно перелогиниться. Источник: https://www.digitalocean.com/community/tutorials/docker-ubuntu-16-04-ru Устанавливаем docker-compose Важно! Обратите внимание на версию в ссылке. Прежде чем качать, лучше проверить какая актуальная версия сейчас и нужную подставить в адрес. sudo curl -L https://github.com/docker/compose/releases/download/1.18.0/docker-compose-`uname -s-
uname -m` -o /usr/local/bin/docker-compose sudo chmod +x /usr/local/bin/docker-compose Источник: https://docs.docker.com/compose/install/#install-compose Устанавливаем node-js После того, как все обновится, устанавливаем node-js (с чем и npm установится). curl -sL https://deb.nodesource.com/setup_10.x | sudo -E bash - sudo apt-get install -y nodejs Проверяем node -v Должно быть типа v10.15.3 Устанавливаем yarn Yarn - совместный фейсбука с гуглом менеджер пакетов типа npm. Он здесь тоже понадобится. Способ проще: sudo npm i -g yarn Способ сложнее: curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | sudo apt-key add - echo "deb https://dl.yarnpkg.com/debian/ stable main" | sudo tee /etc/apt/sources.list.d/yarn.list sudo apt-get update && sudo apt-get install yarn Проверяем yarn -v 1.3.2 Устанавливаем призму глобально. sudo npm install -g prisma Проверяем prisma -v Должно быть типа prisma/1.0.4 (linux-x64) node-v9.4.0 Запускаем локальную службу. Выше я писал инструкцию про установку докера. Здесь докер обязателен, так что если не установили, обязательно надо установить. Локальная служба призмы - это линукс-сервер внутри нашего линукс-сервера (благодаря использованию докера). То есть призма устанавливает под себя отдельно MySQL и прочее ПО в контейнерах с минимальными рисками конфликтов с уже установленным ПО. Выполняем sudo prisma local start Запускаться будет некоторое время, так как это docker, будет установлена mysql и прочие зависимости. Если все ОК, получите типа Booting local development cluster 31.6s Вот теперь, когда локальный сервер призмы запущен, можно создавать и деплоить непосредственно проекты. Уточню, что эта служба единая и может обслуживать сразу несколько отдельных проектов. Ниже я немного раскрою эту кухню. Создаем Prisma-проект. sudo chown USERNAME /var/www -R Неоднозначный шаг, так как веб-проекты должны выполняться от имени веб-сервера и права на файлы должны быть для веб-сервера, но у нас не обычный веб-проект, да и вопросы тонкой настройки прав на веб-сервере мы сейчас не рассматриваем, но этот счет может будет отдельная статья (а может и нет, так как в сети полно материала от более опытных админов). Сейчас в этой папке ничего нет, так что я просто ее под себя резервирую, хотя npm-проект не привязывается к конкретной папке и может быть где угодно. Просто мне /var/www привычней. cd /var/www/ prisma init Выбираем GraphQL server/fullstack boilerplate (recommended) Directory for new GraphQL project (.) если папка пустая, то можно оставить так (будет создан новый проект в текущей папке). Если нет, то не позволит этого, надо указать название проекта, например, hello-world (как это принято в начале Пути делать). Далее, чтобы интересней было, выбираем react-fullstack-basic React app + GraphQL server (incl. database ), будет создан не только GraphQL-проект с АПИ, но и небольшая веб-морда на реакте. Последний шаг: выбираем local Local cluster (requires Docker), то есть полный стек будет работать на нашем сервере, а не использовать сторонние сервера graph.cool Если все прошло успешно, вы получите сообщение типа Чуть распишу указанные пять шагов со своими комментариями. 1,2. Переходим в папку hello-world/dev и запускаем API-сервер командой yarn start. Если все ОК, увидите Server is running on http://localhost:4000 Для выполнения 3-го шага придется открыть еще одну консоль, так как в текущей выполняется yarn start, и если вы закроете ее, то API-сервер остановится. 3. Открыли новую консоль и переходим в /var/www/hello-world 4,5. Запускаем веб-сервер yarn start. Этот сервер будет отвечать за пользовательский интерфейс. Если все ОК, увидите типа Local: http://localhost:3000/ On Your Network: http://10.7.112.123:3000/ В моем случае призма допустила ошибку из-за своеобразной настройки сервера хостинг-провайдером, и показала внутренний ip-адрес, а не внешний. В любом случае, если вы на localhost запускаете, то можете и указывать localhost. Если нет, то еще немного нам придется повоевать. Для это открываем файл /www/hello-world/src/index.js, находим в нем localhost и меняет на реальный ip сервера или доменное имя. После этого уже запускаем веб-сервер командой yarn start Если все у вас заработало как надо, API-консоль вы увидите в браузере на 4000 порту, например http://prismagraphql.ru:4000/ , веб-морду на 3000-ом, к примеру http://prismagraphql.ru:3000/ Веб-морда тестовая, можно перейти на вкладку http://prismagraphql.ru:3000/drafts (черновики), создать запись и, перейдя в нее, опубликовать. В API-консоли можно сформировать нужный вам запрос и выполнить, получив информацию. Пара примеров: Список опубликованных топиков: Список черновиков: Отдельная мега-фича: генерация CURL-строки для API-запросов. Кликаем кнопочку CURL и в буфер обмена попадает строка типа Эту строку можно выполнить просто в консоли на любом сервере и получить JSON-ответ с данными. Запуск демона и мониторинг. Выше я писал: Для выполнения 3-го шага придется открыть еще одну консоль, так как в текущей выполняется yarn start, и если вы закроете ее, то API-сервер остановится. Конечно же для боевого режима это совсем не годится. Надо иметь возможность запускать процесс так, чтобы он уже жил своей жизнью и можно было спокойно закрывать все консоли. В этом нам поможет очень крутая утилита pm2. Устанавливаем ее тоже глобально. sudo npm i -g pm2 Теперь запустим api-сервер через него. Переходим в server/ и выполняем pm2 --name server start npm -- start После этого посмотрим список всех запущенных процессов на pm2. pm2 list. Должна вывестись табличка со списком процессов (сейчас скорее всего только один процесс server) и если с ним все хорошо, то статус online и uptime больше нуля. Там же информация об использовании процессора и оперативки. После этого зайдите в API-консоль на 4000-ом порту и если все ОК, она работает. Чтобы остановить службу, выполняем pm2 stop server. Веб-консоль перестанет быть доступной. При этом если вы выполните pm2 list, процесс server в нем по прежнему будет, просто со статусом stopped. Если надо, можно опять его запустить уже через сам pm2 командой pm2 start server Согласитесь, так гораздо удобней :) А теперь через него же запустим и веб-морду. Для этого переходим в корень проекта cd /var/www/hello-world/, но теперь выполним еще один предварительный шаг, а именно сборку конечных скриптов, выполнив команду yarn build После выполнения этой команды у нас появится папка build со всеми готовыми скриптами. Теперь надо эти скрипты запустить. В призме пока не указана команда для запуска сервера со сжатыми скриптами, поэтому используем для запуска программу serve. Устанавливаем serve глобально. sudo npm i -g serve И запускаем server через pm2. PORT=3000 pm2 --name front start serve -- -s build Выполняем pm2 и смотрим список процессор. Теперь у нас там есть server и front. Открываем браузер на 3000 порту и должно работать. У меня работает http://prismagraphql.ru:3000/ Вот теперь мы можем закрыть все свои консоли, а веб-сервер продолжит работать :) А где же обещанный мониторинг? ОК, будет вам и мониторинг :) Для этого опять подключимся к серверу и выполним pm2 monit Вот теперь откроется более подробная информация о выполняемых процессах (в нашем случае это front и server). Но такой вид не очень радует глаз (хотя и определенно несет свою пользу). Сделаем теперь все гораздо красивее. Прервем выполнение мониторинга Ctrl+C и выполним pm2 register. В ответ вы получите вопрос есть у вас аккаунт на https://keymetrics.io/ или нет. Выберите свой ответ. Если n, вероятней всего там же будет предложена регистрация (но я не знаю, у меня уже был аккаунт). Так или иначе, дойдите до окончательной регистрации и будете вознаграждены вот таким интерфейсом мониторинга: Согласитесь, так гораздо красивее :) Плюс к этому не требуется постоянно сидеть в консоли, а можно в любое время зайти в браузер и посмотреть что у вас на сервере творится. И можно даже оттуда перезагружать службы на своем сервере И напоследок еще один момент: как я и говорил выше, призма запускает под себя мускул в контейнере докер. И вот достучаться до этого контейнера не очень-то и просто, то есть если мы хотим запустить phpMyAdmin и заглянуть в БД, то придется изрядно попотеть (точнее мне пришлось, а далее будет зависеть от того, что и где они еще поменяют, так как вчера еще одно было и все работало, а сегодня уже вчерашние примеры не работают и пришлось покопаться поглубже в поисках точек входа). Вот строка для установки докер-контейнера phpmyadmin с коннектом в нужный нам докер: sudo docker run -d --link prisma-db:db --network local_prisma -p 8080:80 phpmyadmin/phpmyadmin В версии prisma-1.15+ чуть другая строка: docker run -d -e UPLOAD_LIMIT=100M --name pma --link prisma_mysql_1:db --network prisma_default -p 8090:80 phpmyadmin/phpmyadmin Здесь две нужные нам переменные: prisma-db:db и local_prisma. UPLOAD_LIMIT=100M - задает лимит размера импортируемых файлов. Чтобы найти первую, выполняем prisma local eject В результате в домашнюю папку пользователя будут записаны два файла docker-compose.yml и env. В env мы найдем export SQL_CLIENT_HOST="prisma-db". Вот этот хост нам и нужен для формирования переменной prisma-db:db. Там же указаны и другие полезные для нас переменные типа логина и пароля для доступа к БД. Для поиска второй переменной выполняем sudo docker network ls Будет выведена таблица запущенных процессор. Там надо типа a66536c90365 local_prisma bridge local Вот local_prisma отсюда нам и нужна. Выполняем вышеуказанную команду и если все ок, на порту 8080 будет запущен phpMyAdmin (порт конечно же можно указать другой). Указываем логин и пароль из env и все, мы в БД. Структуру БД нет смысла приводить, так как вчера она еще была одна, сегодня другая, а завтра может будет третья. Единственное отмечу, что под каждый проект создается отдельная БД (все их видно в списке через phpMyAdmin). На сегодня, думаю, хватит. Впереди будет еще много сопутствующего материала типа как создавать свои типы и обработчики для API, примеры авторизации, интеграции с MODX и т.д. и т.п. Пока что осваивайте это. очень советую не пропускать этот материал, так как это отправная точка. UPD: локально у меня на имеющейся системе призма не запускалась. Долго воевал, но победил. Проблему и решение описал здесь: https://www.graph.cool/forum/t/cannot-start-prisma-local-mysql-error-0-0-0-0-3306-bind-address-already-in-use/2190 UPD2: Крайне полезная статья в плане понимания как в призме webpack устроен: https://habrahabr.ru/company/plarium/blog/326520/ А то запускаешь yarn start, дев-сервер работает, а откуда ноги растут - не понятно. UPD3: Быстрая установка одним скриптом. Если вы планируете в ознакомительных целях запустить призма-сайт, можно воспользоваться скриптом быстрой установки. Сайт будет в итоге запущен от рута, но для тестов это не страшно.
Вообще процессоры никто не открывает. Для вызова процессоров создаются коннекторы. Для connectors/system/phpthumb.php тоже есть коннектор connectors/system/phpthumb.php но он закрыт для доступа неавторизованных пользователей. Чтобы доступ открыть, создайте свой коннектор и из него уже вызывайте этот коннектор, но перед вызовом пропишите Это отключит проверку конкретно при вызове данного коннектора. Пример вызова: /connectors/system/phpthumb.php?src=assets/images/lazy/2ca4cdfbc2724655d6ca1edfad86b70a.jpg&w=300
Подскажите, пожалуйста, как использовать? Точнее как открыть доступ чтоб ананомы могли генерировать изображения?
Всем добрый день! Сегодня очень объемный и интересный релиз, За три дня более 30 рабочих часов и в коммитах более 10 000 строк кода (а сколько всего было написано-переписано строк - вообще не известно)... Прежде чем полезть в технические дебри, предлагаю сразу перейти на тестовый магазин в заказы https://shopmodx.ru/office/orders/ и кликнуть вот это: Я специально провел таким тернистым путем, чтобы показать, может, малоприметную, но очень важную деталь этого проекта - интеграцию документации и примеров непосредственно в демо-магазин. То есть постепенно каждый отдельный ключевой элемент магазина будет вынесен в отдельный компонент и в том месте где он используется будет ссылка на его отдельную демку с исходным кодом. Там вы можете изучить его код, поиграться с передаваемыми параметрами, хранимыми состояниями и т.п., а так же попробовать видоизменить. В идеале, можно даже сделать форк компонента, усовершенствовать его технически и/или визуально и предложить его в основной проект. Здесь хочу отметить, что демо-магазин - это полностью актуальная версия основной версии проекта, просто с дополнениями поверх, которые отключаются переключателем в шапке страницы. Это как бы отдельный скин, только не являющийся копией основного, а просто расширяющий его (про это я писал в предыдущей статье). Я верю, что подобный подход не только более наглядный, но и более актуальный, сильно сокращающий количество случаев, когда документация не соответствует текущей версии проекта. Что может быть проще, чем найти на сайте интересующий компонент, перейти на страницу его прототипа, проверить какие параметры он умеет принимать, как себя ведет и т.п., а так же прочитать по нему краткий мануал? Да и порог вхождения сильно снижается, ведь даже если до этого вы не программировали на JS/React, на отдельно взятом примере можно поэкспериментировать без установки какого-либо ПО на свой компьютер. А когда появится общее понимание, можно идти дальше. И еще раз уточню другой важный момент: все, что сейчас делается, это не просто внешний скин магазина. Это именно движок магазина. Это все работает и на стороне браузера, и на стороне сервера. То есть не приходится бэкэнд писать на php, шаблонизацию на MODX/Smarty/Fenom, и потом еще подключать кучу jQuery-плагинов и писать тонны JS-строк кода, чтобы еще и внешняя часть сайта как-то заиграла. В создании этого движка я стремлюсь к тому, чтобы логика почти вся необходимая была реализована из коробки, а все доработки конечного проекта сводились только к работе с JS-компонентами сайта. Поверьте, расширяемость здесь гораздо более гибкая, и я вам в дальнейшем это еще не раз докажу. А плюс к этому еще и мониторинг каждого проекта в отдельности настраивается за 1 минуту :) Тут еще одно объявление сделаю: если у вас уже есть какой-то опыт с JS, но пока не хватает опыта в настройке сервера под проект, чтобы поиграться, можете обратиться за настройкой сервера ко мне. Настройка сервера с демо-сайтом - 2500 рублей (первый месяц хостинга включен), затем каждый месяц 1500 за хостинг. Цена такая, потому что оперативки под это надо не мало (на старте одна нода съедает больше полугига). Я посмотрел тарифы на modhost.pro, там на один сайт 1Gb 1200 в месяц стоит (это предпоследняя планка), а последняя планка 2Gb стоит 2400 в месяц. Да, на modhost совсем другой функционал под другие задачи, но я смотрю просто по оперативке. Тут же у вас будет полностью выделенный сервер с возможностью размещения не одного сайта. В общем, предложение с минимальной маржой просто под развитие проекта. Деньги с этого пойдут на разработку новых функций. Ну а теперь коротко о том, что нового появилось в этом релизе: 1. Раскидал базовые запросы react-cms и shopmodx-react. 2. Добавил API-запросы: - Список пользователей. - Пользователь по ID. - Пользователь по username. - Обновление пользователя. - Цепочка Пользователь-Заказы. - Цепочка Заказы-Пользователи-Заказы (чтобы по заказу получить информацию о клиенте и список всех его заказов). - еще несколько запросов (смотрите в API). 3. Добавил регистрацию пользователей, страницу пользователя и редактирование профиля (в том числе загрузку аватарки). 4. Страница списка заказов с возможностью сортировки (пока только по ID и дате, но позже будут и другие условия сортировки). 5. Страница заказа. Повторюсь еще раз, что сердце всего этого - API. Освойте API и уже будет здорово. Далее только оформление своих компонентов меняй. А для этого на https://www.npmjs.com/ более 600 000 пакетов вам в помощь. Пожалуй, я не полезу сегодня дальше в дебри, их было выше крыши в предыдущих статьях. Если что, задавайте вопросы, буду отвечать. А там видно будет.
Кстати, с GraphQL можно и здесь поиграться: https://modxclub.ru/react-lessons/lesson2 Отдельный урок про GraphQL был здесь: https://modxclub.ru/topics/react-js.-urok-%E2%84%962.-zaprosyi-s-pomoshhyu-graphql-2693.html
Всем добрый день! Сегодня речь пойдет об API сборки. Напомню, что сердцем обновленной сборки является API на базе GraphQL. Если кто еще не видел, можно поиграться здесь: https://shopmodx.ru/db/ Как все это работает? В GraphQL есть две основные составляющие: 1. Схема, то есть структура данных, которые в принципе могут быть запрошены. К примеру, вот схема заказа, а вот схема отдельной позиции в заказе. Давайте разберем это на примере товарной позиции. Большинство таких объектов - производные от класса GraphQLObjectType (хотя есть и другие классы, но мы их не будем сейчас разбирать здесь). В таких объектах два обязательных поля: name и fields. И вот тут сразу отмечу пару тонкостей. Во-первых, в рамках всей GraphQL-схемы имена объектов должны быть уникальными. Нельзя иметь в схеме два объекта с одним именем, даже если все поля в них разные. Это необходимо для правильного разбора структуры, так как граф позволяет формировать многоуровневые запросы с зависимостями и еще на уровне сбора схемы проверяет все ли везде в порядке. Плюс ко всему на основе общей структуры генерируется документация по сформированному АПИ. Во-вторых, в качестве полей допустимо использовать не только простые поля типа GraphQLInt, GraphQLString и т.п., но и другие объекты. В данном примере это Product с типом MODXResourceType, экспортируемый из ../modResource, который, в свою очередь, экспортирует этот тип из компонента modx-react. Да, все это довольно запутанно, но зато, как я убедился уже не раз в работе с различными проектами, потом не приходится бегать по всему проекту и искать ответы на вопросы что можно получить по АПИ, а что нет. Даже на тех проектах, где предоставлялась документация, на практике оказывалось, что документация часто не соответствует действительности (разработчик внес изменения в АПИ, а в документацию забыл). Здесь же документация генерируется на лету. А если где-то в схеме оказалась какая-то ошибка, то вы в принципе запроса не выполните, пока не устраните ошибку. И даже если у вас все хорошо, то есть валидация и по типам данных, то есть в АПИ прописан для поля тип данных число, а в ответе от источника пришла строка. Все, граф на это заругается, и правильно сделает. Так что на выходе потом имеющийся порядок компенсирует все мучения. Здесь уточню, что хотя мы в поле прописали только одну сущность - Product, на выходе мы в этом месте получим всю структуру объекта Product. Вторая часть графа - это уже непосредственно тело запроса. К примеру, если у вас есть аккаунт на гитхабе, вы можете поиграться с их конструктором запросов https://developer.github.com/v4/explorer/ И здесь можно увидеть небольшую разницу в работе: у них вы можете редактировать запрос и тут же получать ответ в соответствии со структурой этого запроса. Здесь же редактирование запроса почти ничего не дает. Все потому что в ShopModxBox на сервер отправляется не зам запрос, а только название отдельной операции и параметры. Пример: query OwnOrder - это название отдельной операции. $orderGetProducts:Boolean = false и т.п. - это входящие переменные (с указанием типа данных и значения по умолчанию). Это непосредственно тело запроса: ...Order - это конструкция передачи вывода в заранее определенный фрагмент (выше его код так же приведен). @storage - директива, но директивы мы рассмотрим как-нибудь позже. Так вот, все эти запросы описаны заранее и обрабатываются на стороне сервер, то есть передавая на сервер запрос OwnOrder, граф находит эту операцию в подготовленном листинге запросов и собирает указанные данные. Вот весь этот листинг в компоненте shopmodx-react: https://github.com/MODX-Club/shopmodx-react/blob/master/components/ORM/query.js Но тут встает вопрос: а как же на конечном проекте расширять эти запросы, если они уже заранее прописаны в обновляемом компоненте? Для решения этой задачи я выпустил сегодня новый компонент react-cms-graphql-utils, в составе которого имеется полезная функция mergeQuery https://github.com/MODX-Club/react-cms-graphql-utils/blob/master/src/mergeQuery.js Передаем в нее базовый список запросов и кастомный, mergeQuery производит разбор одного и другого на отдельные сущности и мержит их, перетирая имеющиеся и дополняя новыми. Свои кастомные запросы можно писать сюда: https://github.com/MODX-Club/ShopModxBox/blob/5559089d68a1ae75b641492d4ef6395180e508fd/assets/components/modxsite/templates/shopmodx/v4.0/app/modules/Site/components/ORM/query.js#L6 Позже я покажу реальные кейсы с применением всего этого.