Приложение SF-AdTech — это трекер трафика, созданный для организации взаимодействия компаний (рекламодателей), которые хотят привлечь к себе на сайт посетителей и покупателей (клиентов), и владельцев сайтов (веб-мастеров), на которые люди приходят, например, чтобы почитать новости или пообщаться на форуме.
Рекламодатель создаёт предложение (offer), определяя URL страницы, на которую он хочет приводить людей. Например, это страница товара, который он хочет продавать. В offer-е он также определяет стоимость перехода по ссылке. Скажем, 1 рубль за переход.
Веб-мастера в системе видят создаваемые офферы, подписываются на них, после чего система выдаёт им специальные ссылки, которые они должны разместить в любом виде у себя на ресурсе. Ссылка эта ведёт не на целевой URL, а на систему-редиректор, которая фиксирует переход, а затем перенаправляет клиента на страницу сайта рекламодателя.
По итогам рекламодатель получает N посетителей и платит за это системе N рублей (согласно ставке в 1 рубль за переход).
Система определяет комиссию (например, 20%) за свои услуги. Таким образом, веб-мастер за привлечение клиентов, получит 0.8N рублей, а система заработает 0.2N рублей.
Посредники App\Http\Middleware\Roles\IsAdmin
, App\Http\Middleware\Roles\IsAdvertiser
, App\Http\Middleware\Roles\IsStatisticsPage
ограничивают доступ к страницам ролей.
- users - пользователи
- user_roles - роли пользователей
- advertisers - рекламодатели
- webmasters - вебмастеры
- offers - офферы
- offer_themes - темы офферов
- offer_subscriptions - подписки на офферы
- offer_clicks - переходы по реферальным ссылкам
- system_options - конфиг системы
- failed_offer_clicks - неудачные переходы по ссылкам
Адрес вебсокета можно изменить в .env: WEBSOCKET_PORT
, WEBSOCKET_ADDR
.
Вебсокет применяется для обновления данных на страницах при добавлении данных в БД в режиме реального времени. Используются библиотеки: для cервера веб-сокета cboden/ratchet
, серверного клиента ratchet/pawl
, JS-клиента стандартный Websocket
. Для отправки сообщений в вебсокет сервером используется класс App\Services\WebsocketService
, метод send
. Серверный вебсокет использует класс App\ServerWebsocket
, для принятий сообщений клиентами от сервера используются клиентские вебсокет классы из папки /public/js/websockets. Клиентские вебсокеты расширяют базовый класс ClientWebsocket
. Название соответствует странице, на которой он применяется:
AdminClientWebsocket
- dashboard администратора,AdvertiserClientWebsocket
- dashboard рекламодателя,WebmasterClientWebsocket
- dashboard вебмастера,RegisterClientWebsocket
- страница пользователей администратораMainClientWebsocket
- главная страница,StatisticsClientWebsocket
- страница статистики
Посредник App\Http\Middleware\IsActiveWebsocket
проверяет активность вебсокета и запускает, если выключен.
Серверный вебсокет запускается как отдельный процесс php-файл app/offer-service.php с помощью класса App\ScriptLinuxProcess
.
Статистика вебсокета: /storage/logs/websocket.log
- Для работы сайта требуется Javascript. При отключенном JS редирект на страницу /noscript.
- Верстка страниц основана на blade-шаблонах. app.blade - шаблон страниц. Контент берется из соответствующей blade-страницы папки /resources /views/pages. blade-шаблоны страниц регистрации и входа в папке /resources/views/auth.
- js-скрипты и css-файлы расположены в /public и подключаются через blade-шаблоны.
База данных (БД) имеет четыре таблицы для пользователей: пользователи (users
), роли (user_roles
), рекламодатели (advertisers
), веб-мастеры (webmasters
).
Есть три роли пользователя: рекламодатель, веб-мастер, администратор. Можно зарегистирироваться как рекламодатель или веб-мастер. Администратор может создавать и удалять пользователей, в том числе новых администраторов. В целях безопасности таблица пользователей администратора не отображает администратора admin.
Таблица рекламодателей и веб-мастеров создана для разделения отношений. БД имеет следующие отношения: таблица офферов offers
-> таблица рекламодателей advertisers
-> таблица пользователей users
и таблица подписок на офферы offer_subscriptions
-> таблица веб-мастеров webmasters
-> таблица пользователей users
.
Регистрация пользователя происходит через средства Laravel, контроллер регистрации App\Http\Controllers\Auth\RegisteredUserController
. Добавлена защита от подделки данных: проверяется, что выбрана роль рекламодатель или веб-мастер. Иначе редирект а страницу 404. В зависимости от роли добавляется запись в advertisers
или webmasters
. В случае успешной регистрации вебсокет отправляет клиенту-администратору сообщение NEW_REGISTRATION о появлении нового пользователя. На странице администратора появляется новый пользователь.
Авторизация пользователя вынесена в контроллер пользователей - App\Http\Controllers\UserController
, метод authenticate
. При авторизации проверяется наличие пользователя в системе и активность учетной записи, которую может выключить администратор.
Администратор может отключить и удалить учетную запись. В случае удаления удаляются все связанные данные. Страницы сайта кроме главной страницы могут просматривать только авторизованные пользователи.
Имеются по умолчанию 7 пользователей:
- admin@mail.ru - админ
- advertiser1@mail.ru, advertiser2@mail.ru, advertiser3@mail.ru - рекламодатели
- webmaster1@mail.ru, webmaster2@mail.ru, webmaster3@mail.ru - вебмастеры
Пароль у всех пользователей: AAAAaaaa1111
Рекламодатель создаёт предложение (offer), определяя URL страницы, на которую он хочет приводить людей. В offer-е он указывает стоимость перехода по ссылке. Система определяет комиссию за свои услуги. Сервер после добавления оффера в БД расслылает клиентам в вебсокете сообщение NEW_OFFER веб-мастерам. Вебмастера видят ту долю стоимости оффера, которую получат они. Рекламодатель может включать/выключать и удалять свои офферы. При выключении оффер пропадает из страницы веб-мастеров, независимо того, подписаны ли они, в вебсокет посылается сообщение VISIBLE_OFFER или UNVISIBLE_OFFER. При удалении в вебсокет отправляется сообщение DELETE_OFFER. При создании оффера или переключении его статуса, на страницах вебмастеров данные обновляются без перезагрузки. При удалении оффера удаляются все записи о нем (подписки, переходы, из статистики системы и рекламодателя), исчезают с главной страницы и страниц веб-мастеров. Если сервер совершает описанные выше действия, то отправляет эту информацию клиентам (браузерам) через вебсокет. Браузер при получении информации из вебсокета динамически изменит содержание страницы.
Веб-мастера в системе видят активные офферы, подписываются на них, после чего система выдаёт им специальные ссылки, которые они должны разместить в любом виде у себя на ресурсе. Ссылка эта ведёт не на целевой URL, а на систему-редиректор, которая фиксирует переход, а затем перенаправляет клиента на страницу сайта рекламодателя. При подписке или отписке клиентам в вебсокете отправляется сообщение SUBSCRIBE или UNSUBSCRIBE.
Браузер управляет данными таблицы офферов через JS-контроллер OfferTableClientController
и JS-класс OfferStatus
, данными подписок - JS-класс SubscriptionStatus
. Клиентский контроллер офферов обменивается данными с серверным контроллером офферов App\Http\Controllers\OfferController
, класс подписок - сервисом App\Services\SubscriptionService
.
- На странице dashboard администратора отображена общая статистика системы.
- Администратору доступна страница пользователей /users, где он может добавлять, удалять и включать или отключать пользователей. Клиентский контроллер
TableClientControllers/UserTableClientController
управляет данными таблицы пользователей и отправляет изменения в серверный контроллерApp\Http\Controllers\UserController
. - Администратору доступна страница тем офферов /offer-theme, где он может их добавлять и удалять. Клиентский контроллер
TableClientControllers/OfferThemeTableClientController
управляет данными таблицы и отправляет изменения в серверный контроллерApp\Http\Controllers\OfferThemeController
. - Администратор может изменить комиссию системы в % от стоимости оффера. Комиссия изменяется и отправляется на сервер через js-класс
CommissionCtl
. Сервер записывает комиссию в БД через контроллерSystemOptionController
, методset_commission
.
При входе на страницу /dashboard рекламодатель и веб-мастер видят схожую по структуре таблицу. За отображение страницы отвечает одиночный контроллер App\Http\Controllers\DashboardController
. Рекламодатель видит список созданных им офферов, веб-мастер - список подписок и видимых офферов (выключенные офферы не отображаются). Таблица имеет две колонки, которые отображают активность. Для изменения статуса нужно мышью перенести оффер или подписку в соответствующую колонку. У каждого оффера рекламодателя отображается число подписчиков и кнопка удаления. За добавление, удаление, изменение активности офферов отвечает ресурсный контроллер App\Http\Controllers\OfferController
, изменение подписок - сервис App\Services\SubscriptionService
. Число подписчиков динамически меняется через вебсокет. Рекламодатель имеет кнопку добавить новый оффер. Вебмастер видит реферальные ссылки своих подписок, которые можно скопировать. При наведении на ссылку показывается ее название. Администратор видит статистику системы и комиссию системы, которую может изменить.
У рекламодателя и веб-мастера на странице /dashboard есть ссылка на статистику /offer/statistics, где у рекламодателя отображается временная статистика расходов офферов , у вебмастеров - доходов подписок. За отображение статистики отвечает класс App\Http\Controllers\StatisticController
, метод index
.
На странице в верстке находятся четыре таблицы статистики (последний день, последний месяц, последний год, все время), но отображается одна. При изменении переключателя времени показывается соответствующая таблица. Сервер формирует данные для страницы статистики через посредник App\Services\OfferStatistics
. Данный сервис формирует четыре таблицы для четырех промежутков времени.
Администратору доступна страница тем офферов, где он может создавать и удалять темы.
В рамках работы все доступные реферальные ссылки отображаются на главной странице offer-tracker.local. Реферальная ссылка имеет вид offer-tracker.local?A@B, где A - id вебмастера, B - id оффера. Посредник App\Http\Middleware\IsOfferReference
проверяет реферальную ссылку на корректность данных. Если такой реферальной ссылки не существует, то редирект на 404 страницу. В противном случае сервер делает запись в таблицу БД offer_clicks
о переходе с указанием времени перехода и переходит на страницу рекламодателя. Факт перехода или ошибочной реферальной ссылки записывается в лог /storage/logs/offer_clicks.log и отправляет в вебсокет сообщение CLICK или FAILED_OFFER.
- создать файл .env по аналогии .env.example
composer install
npm install
- создать базу
offer-tracker
php artisan migrate --seed
- для полной остановки сайта выполнить
pkill -f offer-service
для остановки вебсокета. - В файле .env в параметре
TIMEZONE
прописать номер часового пояса сервера, где запускается проект. В противном случае дата в БД и серверной части кода будет различаться, не будет корректно отображаться статистика офферов и подписок. php artisan serve