{"id":22199433,"url":"https://github.com/ilyamur/myposts_app","last_synced_at":"2025-03-24T23:44:37.196Z","repository":{"id":206737054,"uuid":"437666333","full_name":"IlyaMur/myposts_app","owner":"IlyaMur","description":"The blog app with rich auth functionality build from scratch on the PHP On Rails framework","archived":false,"fork":false,"pushed_at":"2022-05-23T12:30:34.000Z","size":264,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-01-30T02:43:07.688Z","etag":null,"topics":["authentication","aws-api","blog-app","from-scratch","mailjet-api"],"latest_commit_sha":null,"homepage":"","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/IlyaMur.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null}},"created_at":"2021-12-12T22:02:53.000Z","updated_at":"2023-07-16T21:54:50.000Z","dependencies_parsed_at":"2023-11-12T00:20:17.722Z","dependency_job_id":"6e1bc3b5-3c10-4145-b375-d6fcf687691c","html_url":"https://github.com/IlyaMur/myposts_app","commit_stats":null,"previous_names":["ilyamur/myposts_app"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/IlyaMur%2Fmyposts_app","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/IlyaMur%2Fmyposts_app/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/IlyaMur%2Fmyposts_app/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/IlyaMur%2Fmyposts_app/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/IlyaMur","download_url":"https://codeload.github.com/IlyaMur/myposts_app/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245372220,"owners_count":20604489,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["authentication","aws-api","blog-app","from-scratch","mailjet-api"],"created_at":"2024-12-02T15:14:17.601Z","updated_at":"2025-03-24T23:44:37.170Z","avatar_url":"https://github.com/IlyaMur.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"# MyPosts\n\n![CodeSniffer-PSR-12](https://github.com/IlyaMur/myposts_app/workflows/CodeSniffer-PSR-12/badge.svg)\n![PHPUnit-Tests](https://github.com/IlyaMur/myposts_app/workflows/PHPUnit-Tests/badge.svg)\n[![Maintainability](https://api.codeclimate.com/v1/badges/0273c0de648a6f356cf3/maintainability)](https://codeclimate.com/github/IlyaMur/myposts_app/maintainability)\n\n**[🇬🇧 English readme](https://github.com/IlyaMur/myposts_app/blob/master/README_en.md)**\n\n**Содержание**\n  - [О приложении](#о-приложении)\n  - [Установка](#установка)\n    - [Сборка в Docker](#сборка-в-docker)\n    - [Установка локально](#установка-локально)\n    - [Конфигурация](#конфигурация)\n    - [Использованные библиотеки](#использованные-библиотеки)\n  - [Как работает приложение](#как-работает-приложение)\n    - [Системы аутентификации и авторизации](#система-аутентификации-и-авторизации)\n    - [Работа с постами](#работа-с-постами)\n    - [Работа с комментариями](#работа-с-комментариями)\n    - [Хэштеги](#хэштеги)\n    - [Хранение изображений](#хранение-изображений)\n    - [Шаблоны](#шаблоны)\n    - [Административная составляющая](#административная-составляющая)\n    - [Ошибки](#ошибки)\n\n## О Приложении  \n\n**MyPosts** - приложение-блог созданное на базе фреймворка [PHP On Rails](https://github.com/IlyaMur/php_on_rails_mvc).  \nБлог создан в процессе обучения, но обладает богатым функционалом.  \n\nДеплой приложения осуществлен на сервис Heroku.   \nMyPosts доступен по адресу - http://myposts-app.herokuapp.com (на данный момент не доступна загрузка изображений из-за ограничений со стороны AWS S3).\n\nВ приложении реализованы:\n- Полноценные системы аутентификации и авторизации пользователей.\n- Активация аккаунта и сброс пароля по почте (рассылка писем осуществлена на базе сервиса MailJet).\n- Хранение данных пользователей, как локально, так и на стороннем сервисе (AWS S3).\n- Система комментариев.\n- Хэштеги.\n- Профили пользователей.\n- CAPTCHA и базовая защита от спама.\n- Административная составляющая.\n\nБольшая часть функционала написана с нуля, готовые решение по возможности избегались.  \nОсновой для представлений был выбран шаблонизатор [Twig](https://twig.symfony.com/), как гибкое и безопасное решение с лаконичным синтаксисом.\n\n![Главная страница](https://i.imgur.com/AUtFld3.png)   \n\n## Установка  \n\nУстановка предлагается в двух вариантах: сборки в Docker и локальной установки.\n\nПрежде всего, необходимо склонировать репозиторий\n\n    $ git clone https://github.com/IlyaMur/myposts_app.git  \n    $ cd myposts_app\n\nИ подготовить файл `.env`\n\n    $ make env-prepare  \n\nОпционально, изменить параметры БД и сервера в файле `.env`, а так же изменить данные для сервисов AWS и MailJet. \n\n```dotenv\nMYSQL_USER='user'\nMYSQL_HOST='mariadb'\nAPACHE_DEFAULT_PORT='80'\nMYSQL_PASSWORD='testpassword'\n...\n```\n\n### Сборка в Docker\n\nПриложение доступно для сборки в Docker.   \n\nСобрать и запустить приложение\n\n    $ make docker-start  \n\nОстановить и удалить контейнеры\n\n    $ make docker-stop  \n\nТак же доступны:\n\n    $ make docker-bash  # запустить сессию bash в контейнере  \n    $ make docker-test  # запустить тесты в контейнере \n\nПо умолчанию приложение будет доступно: `http://localhost`\n\n### Установка локально\n\n`PHP \u003e= 8.0` \n\nДля установки зависимостей:  \n\n    $ make install   \n\nВ настройках веб-сервера установить root в директории `public/`  \n\nВ выбранную СУБД импортировать SQL из файла `database/myposts_db.sql`    \nВ `config/config.php` заполнить данные для доступа к БД, настройки хранения и хэширования.  \n\n### Конфигурация  \n\nНастройки конфигурации доступны в файле [config.php](config/config.php)\n\nНастройки по умолчанию включают в себя:\n- Данные подключения к серверу БД. \n- Логирование ошибок.\n- Возможность выбора между локальным и удаленным хранением пользовательских изображений.\n- Установки для вывода/скрытия детализации ошибок.\n- Настройка секретного ключа для хэширования токенов.\n\nДля переопределения настроек в конфигурационном файле доступны соответствующие константы.\n\n### Использованные библиотеки  \n\nНе смотря на то, что в процессе написания приложения в первую очередь стояла цель создания функционала с нуля, в MyPosts присутствуют некоторые зависимости:\n\n- Twig Template Engine\n- SDK Mailjet\n- SDK AWS\n- Gregwar/Captcha\n- vlucas/phpdotenv\n\n## Как Работает Приложение\n\n### Система аутентификации и авторизации\n\nВ приложении с нуля реализованы системы регистрации и авторизации пользователей.  \n\nФорма аутентификации валидируется как на стороне сервера, так и клиента.  \nПосле регистрации на почту пользователя высылается письмо с ссылкой для активации.  \nСоздана возможность сброса существущего пароля на почту. У токена сброса имеется срок годности.\n\nРассылка писем осуществлена посредством сервиса MailJet и служебного класса [Mail](src/Service/Mail.php), шаблоны для работы с паролями и токенами пользователей доступны в [src/Views/Password](src/Views/Password) \n\nЛогин пользователя доступен через [RememberedLogin](src/Models/RememberedLogin.php). Токен логина так же имеет срок давности.  \nДля взаимодействия с сессиями и куки используется класс [Auth](src/Service/Auth.php), предоставляющий инструменты для работы с авторизациями пользователей.\n\n### Работа с постами\n\nОсновой блога являются посты пользователей. Они удобно выведены на главной странице, так же доступна пагинация.\nПользователи могут добавлять изображения к постам, редактировать свои посты и комментировать чужие и свои посты.  \nТак же внимание уделено безопасности и в частности XSS-атакам.  \nВалидация содержимого поста происходит как на клиенте (посредством библиотеки JS и HTML5-валидации), так и на сервере в модели [Post](src/Models/Post.php), ошибки возвращаются пользователю.\n\n### Работа с комментариями\n\nПользователи могут оставлять комментарии под своими и чужими постами. Для работы с комментариями создана модель [Comment](src/Models/Comment.php) и контроллер [Comments](src/Controllers/Comments.php).   \nРеализована и анонимная отправка комментариев, но для этого необходимо пройти проверку через ввод CAPTCHA.  \nКомментарии пользователя доступны в его профиле.  \nКомментарии так же валидируются и проверяются на XSS.\n\n### Хэштеги\n\nКак и любой современный блог MyPosts поддерживает хэштеги. Содержимое поста при добавлении и редактировании парсится на наличие хэштегов.  \nЛогика по работе с хэштегами находится в модели [Hashtag](src/Controllers/Hashtag.php).   \nПоследние 10 добавленных хэштегов доступны на главной странице. При клике по хэштегу выводятся связанные с ним посты.\n\n### Хранение изображений\n\nДля хранения изображений доступны два варианта.\n- Хранение изображений на базе сервиса AWS S3. С помощью AWS SDK.\n- Хранение изображений локально.\n\nДля использования AWS S3 необходимо ввести данные своего аккаунта в файле [config.php](config/config.php) и установить в константу `AWS_STORING` в значение `true`.  \nДля работы воспользоваться классом [S3Helper](src/Service/S3Helper.php), который использует SDK и предоставляет интерфейс для взаимодействия с облачным хранилищем.\n\nДля локального хранения данных необходимо установить `AWS_STORING` в `false`. Картинки будут сохраняться в директорию `public/upload/`.\n\nВсе изображения перед загрузкой на сервер валидируются.\n\n### Шаблоны\n\nПредставления организованы посредством шаблонизатора [Twig](https://twig.symfony.com/), который поддерживает наследование шаблонов.  \nШаблоны находятся в директории `src/Views`, базовый шаблон - [base.html.twig](src/Views/base.html.twig).  \nДля переиспользования кода и улучшения читаемости в директорию `src/Views/partials` вынесены часто используемые элементы Представлений.\n\nДля приятного и лаконичного внешнего вида был выбран CSS Framework - Bootstrap.\n\n### Административная составляющая\n\nАдминистратор блога имеет свою панель управления, взаимодействие с которой происходит в отдельном неймспейсе `Ilyamur\\PhpMvc\\Controllers\\Admin`.\nАдминистратор видит подробную информацию о созданных постах и может модерировать их.\n\n### Ошибки\n\nОшибки преобразуются в исключения. Обработчиками обозначены:\n```\nset_error_handler('Ilyamur\\PhpMvc\\Service\\ErrorHandler::errorHandler');\nset_exception_handler('Ilyamur\\PhpMvc\\Service\\ErrorHandler::exceptionHandler');\n```\n\nПри константе `SHOW_ERRORS` (настраивается в [config.php](config/config.php)) равной `true`, в случае исключения или ошибки в браузер будет выведена полная детализация.   \nЕсли `SHOW_ERRORS` присвоено значение `false` будет показано лишь общее сообщение из шаблонов [404.html.twig](src/Views/404.html.twig) или [500.html.twig](src/Views/500.html.twig) в зависимости от ошибки.  \nДетализированная информация в данном случае будет логироваться в директории `logs/`.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Filyamur%2Fmyposts_app","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Filyamur%2Fmyposts_app","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Filyamur%2Fmyposts_app/lists"}