├── .dockerignore
├── .editorconfig
├── .env
├── .env.test
├── .eslintrc
├── .gitattributes
├── .github
└── workflows
│ ├── frankenphp.yml
│ ├── lint.yml
│ ├── mariadb.yml
│ ├── mysql.yml
│ ├── ossar-analysis.yml
│ └── postgres.yml
├── .gitignore
├── .php-cs-fixer.dist.php
├── .prettierrc
├── .travis.yml
├── CONTRIBUTING.md
├── Dockerfile
├── LICENSE
├── README.md
├── assets
├── app.js
├── controllers
│ └── .gitignore
├── js
│ ├── admin
│ │ ├── admin.js
│ │ ├── menu-sorting.js
│ │ └── settings.js
│ ├── auth
│ │ ├── _resend.js
│ │ └── auth.js
│ ├── bottom-bar.js
│ ├── city.js
│ ├── common
│ │ └── _delete_button.js
│ ├── ekko-lightbox.js
│ ├── map.js
│ ├── page.js
│ ├── photo.js
│ ├── select2.js
│ ├── slugger.js
│ └── user
│ │ ├── _property.js
│ │ ├── _sidebar.js
│ │ ├── password
│ │ ├── _update_password.js
│ │ ├── _validate_password.js
│ │ └── password.js
│ │ ├── two_factor
│ │ └── google_authenticator.js
│ │ └── user.js
├── psd
│ └── no-photo.psd
└── styles
│ ├── _variables.scss
│ ├── admin.scss
│ ├── app.scss
│ ├── bottom-bar.scss
│ ├── city.scss
│ ├── detail.scss
│ ├── ekko-lightbox.scss
│ ├── photo.scss
│ ├── select2.scss
│ └── user
│ └── security.scss
├── babel.config.js
├── bin
├── console
└── phpunit
├── compose.override.yaml
├── compose.prod.yaml
├── compose.yaml
├── composer.json
├── composer.lock
├── config
├── bundles.php
├── packages
│ ├── assets.yaml
│ ├── cache.yaml
│ ├── debug.yaml
│ ├── dev
│ │ └── easy_log_handler.yaml
│ ├── doctrine.yaml
│ ├── doctrine_migrations.yaml
│ ├── framework.yaml
│ ├── knp_paginator.yaml
│ ├── lock.yaml
│ ├── mailer.yaml
│ ├── messenger.yaml
│ ├── monolog.yaml
│ ├── notifier.yaml
│ ├── prod
│ │ ├── deprecations.yaml
│ │ └── webpack_encore.yaml
│ ├── rate_limiter.yaml
│ ├── routing.yaml
│ ├── scheb_2fa.yaml
│ ├── security.yaml
│ ├── test
│ │ ├── rate_limiter.yaml
│ │ ├── validator.yaml
│ │ └── webpack_encore.yaml
│ ├── translation.yaml
│ ├── twig.yaml
│ ├── validator.yaml
│ ├── web_profiler.yaml
│ └── webpack_encore.yaml
├── preload.php
├── routes.yaml
├── routes
│ ├── attributes.yaml
│ ├── framework.yaml
│ ├── scheb_2fa.yaml
│ ├── security.yaml
│ └── web_profiler.yaml
├── secrets
│ └── prod
│ │ └── .gitignore
└── services.yaml
├── docs
├── docker.md
└── images
│ └── screenshot.png
├── frankenphp
├── Caddyfile
├── conf.d
│ ├── 10-app.ini
│ ├── 20-app.dev.ini
│ └── 20-app.prod.ini
├── docker-entrypoint.sh
└── worker.Caddyfile
├── migrations
├── Version20200328162849.php
├── Version20200705110619.php
├── Version20210104185420.php
├── Version20210106154655.php
├── Version20210106191712.php
├── Version20210106234742.php
├── Version20210107000119.php
├── Version20210215083338.php
├── Version20210215173522.php
├── Version20210815075052.php
├── Version20210817062054.php
├── Version20220320064544.php
├── Version20220325072850.php
├── Version20220824075712.php
├── Version20230304072206.php
└── Version20230501134351.php
├── package.json
├── phpstan.dist.neon
├── phpunit.xml.dist
├── public
├── .htaccess
├── build
│ ├── css
│ │ ├── admin.832d2af4.css
│ │ ├── app.79e704be.css
│ │ ├── bottom-bar.38e93f4e.css
│ │ ├── city.830c14fb.css
│ │ ├── detail.3d2d5214.css
│ │ ├── ekko-lightbox.74df6b0a.css
│ │ ├── photo.a213acff.css
│ │ ├── security.64e38d75.css
│ │ └── select2.454a8588.css
│ ├── entrypoints.json
│ ├── fonts
│ │ ├── fa-regular-400.491974d1.ttf
│ │ ├── fa-regular-400.77206a6b.eot
│ │ ├── fa-regular-400.7a333762.woff2
│ │ ├── fa-regular-400.bb58e57c.woff
│ │ ├── fa-solid-900.1551f4f6.woff2
│ │ ├── fa-solid-900.9bbb245e.eot
│ │ ├── fa-solid-900.be9ee23c.ttf
│ │ └── fa-solid-900.eeccf4f6.woff
│ ├── images
│ │ ├── fa-regular-400.4689f52c.svg
│ │ └── fa-solid-900.7a8b4f13.svg
│ ├── js
│ │ ├── admin.32201fb1.js
│ │ ├── admin.32201fb1.js.LICENSE.txt
│ │ ├── app.2ff2670c.js
│ │ ├── app.2ff2670c.js.LICENSE.txt
│ │ ├── auth.87b05c2f.js
│ │ ├── bottom-bar.04c1ac09.js
│ │ ├── city.b1325671.js
│ │ ├── ekko-lightbox.11ef94c0.js
│ │ ├── ekko-lightbox.11ef94c0.js.LICENSE.txt
│ │ ├── google_authenticator.5fceab80.js
│ │ ├── map.7d2feb0e.js
│ │ ├── menu-sorting.287ae70d.js
│ │ ├── page.3f48afaa.js
│ │ ├── password.330d6897.js
│ │ ├── photo.03a89e47.js
│ │ ├── photo.03a89e47.js.LICENSE.txt
│ │ ├── select2.98bad6eb.js
│ │ ├── select2.98bad6eb.js.LICENSE.txt
│ │ ├── settings.e36efd93.js
│ │ ├── slugger.c09f068e.js
│ │ └── user.3e9dfb9b.js
│ ├── manifest.json
│ └── runtime.8ab7f0c8.js
├── favicon.ico
├── images
│ ├── bg-1.5.jpg
│ ├── bg.jpg
│ ├── icons
│ │ ├── apple-touch-icon.png
│ │ ├── chrome-touch-icon-192x192.png
│ │ ├── icon-128x128.png
│ │ ├── icon-144x144.png
│ │ ├── icon-152x152.png
│ │ ├── icon-192x192.png
│ │ ├── icon-256x256.png
│ │ ├── icon-512x512.png
│ │ └── icon.svg
│ ├── languages
│ │ ├── bg.png
│ │ ├── en.png
│ │ ├── hu.png
│ │ ├── nl.png
│ │ └── ru.png
│ ├── logo-square.png
│ ├── no-photo.png
│ ├── residence-logo.png
│ └── transparent.png
├── index.php
├── libs
│ └── summernote
│ │ └── 0.8.20
│ │ ├── font
│ │ ├── summernote.eot
│ │ ├── summernote.ttf
│ │ ├── summernote.woff
│ │ └── summernote.woff2
│ │ ├── summernote-bs4.css
│ │ └── summernote-bs4.min.js
├── manifest.json
├── robots.txt
└── uploads
│ └── images
│ ├── full
│ └── demo
│ │ ├── 1.jpeg
│ │ ├── 10.jpeg
│ │ ├── 11.jpeg
│ │ ├── 12.jpeg
│ │ ├── 13.jpeg
│ │ ├── 2.jpeg
│ │ ├── 3.jpeg
│ │ ├── 4.jpeg
│ │ ├── 5.jpeg
│ │ ├── 6.jpeg
│ │ ├── 7.jpeg
│ │ ├── 8.jpeg
│ │ └── 9.jpeg
│ ├── large
│ └── demo
│ │ ├── 1.jpeg
│ │ ├── 10.jpeg
│ │ ├── 11.jpeg
│ │ ├── 12.jpeg
│ │ ├── 13.jpeg
│ │ ├── 2.jpeg
│ │ ├── 3.jpeg
│ │ ├── 4.jpeg
│ │ ├── 5.jpeg
│ │ ├── 6.jpeg
│ │ ├── 7.jpeg
│ │ ├── 8.jpeg
│ │ └── 9.jpeg
│ ├── medium
│ └── demo
│ │ ├── 1.jpeg
│ │ ├── 10.jpeg
│ │ ├── 11.jpeg
│ │ ├── 12.jpeg
│ │ ├── 13.jpeg
│ │ ├── 2.jpeg
│ │ ├── 3.jpeg
│ │ ├── 4.jpeg
│ │ ├── 5.jpeg
│ │ ├── 6.jpeg
│ │ ├── 7.jpeg
│ │ ├── 8.jpeg
│ │ └── 9.jpeg
│ └── small
│ └── demo
│ ├── 1.jpeg
│ ├── 10.jpeg
│ ├── 11.jpeg
│ ├── 12.jpeg
│ ├── 13.jpeg
│ ├── 2.jpeg
│ ├── 3.jpeg
│ ├── 4.jpeg
│ ├── 5.jpeg
│ ├── 6.jpeg
│ ├── 7.jpeg
│ ├── 8.jpeg
│ └── 9.jpeg
├── rector.php
├── src
├── Command
│ ├── InstallCommand.php
│ └── ListUsersCommand.php
├── Controller
│ ├── AbstractPhotoController.php
│ ├── Admin
│ │ ├── CategoryController.php
│ │ ├── CityController.php
│ │ ├── CurrencyController.php
│ │ ├── DashboardController.php
│ │ ├── DealTypeController.php
│ │ ├── DistrictController.php
│ │ ├── FeatureController.php
│ │ ├── MenuController.php
│ │ ├── MetroController.php
│ │ ├── NeighborhoodController.php
│ │ ├── PageController.php
│ │ ├── PhotoController.php
│ │ ├── PropertyController.php
│ │ ├── Settings
│ │ │ ├── AbstractSettingsController.php
│ │ │ ├── HeaderSettingsController.php
│ │ │ ├── MainSettingsController.php
│ │ │ └── MapSettingsController.php
│ │ └── UserController.php
│ ├── Ajax
│ │ ├── Admin
│ │ │ ├── MenuController.php
│ │ │ ├── PhotoController.php
│ │ │ └── SettingsController.php
│ │ ├── AjaxController.php
│ │ ├── Auth
│ │ │ └── ResendVerificationController.php
│ │ ├── CityController.php
│ │ └── User
│ │ │ ├── PhotoController.php
│ │ │ ├── PropertyController.php
│ │ │ └── Security
│ │ │ ├── GoogleAuthenticatorController.php
│ │ │ └── PasswordController.php
│ ├── Auth
│ │ ├── AuthController.php
│ │ ├── LoginController.php
│ │ ├── RegisterController.php
│ │ ├── ResetPasswordController.php
│ │ ├── TwoFactor
│ │ │ └── EnterAuthCodeController.php
│ │ └── VerificationController.php
│ ├── BaseController.php
│ ├── CityController.php
│ ├── PageController.php
│ ├── PropertyController.php
│ ├── SitemapController.php
│ ├── Traits
│ │ └── MenuTrait.php
│ └── User
│ │ ├── PhotoController.php
│ │ ├── ProfileController.php
│ │ ├── PropertyController.php
│ │ └── SecurityController.php
├── DataFixtures
│ ├── AppFixtures.php
│ ├── CategoryFixtures.php
│ ├── CityFixtures.php
│ ├── CurrencyFixtures.php
│ ├── DealTypeFixtures.php
│ ├── DistrictFixtures.php
│ ├── FeatureFixtures.php
│ ├── MenuFixtures.php
│ ├── MetroFixtures.php
│ ├── NeighborhoodFixtures.php
│ ├── PageFixtures.php
│ ├── PhotoFixtures.php
│ ├── PropertyFixtures.php
│ └── UserFixtures.php
├── Dto
│ └── FeedbackDto.php
├── Entity
│ ├── Category.php
│ ├── City.php
│ ├── Currency.php
│ ├── DealType.php
│ ├── District.php
│ ├── Feature.php
│ ├── Menu.php
│ ├── Metro.php
│ ├── Neighborhood.php
│ ├── Page.php
│ ├── Photo.php
│ ├── Profile.php
│ ├── Property.php
│ ├── PropertyDescription.php
│ ├── Settings.php
│ ├── Traits
│ │ ├── CityTrait.php
│ │ ├── EntityIdTrait.php
│ │ ├── EntityLocationTrait.php
│ │ ├── EntityMetaTrait.php
│ │ ├── EntityNameTrait.php
│ │ ├── EntityTimestampableTrait.php
│ │ ├── PropertyTrait.php
│ │ └── TwoFactorTrait.php
│ └── User.php
├── EventListener
│ └── ExceptionListener.php
├── EventSubscriber
│ └── ControllerSubscriber.php
├── Form
│ ├── EventSubscriber
│ │ ├── AddAgentFieldSubscriber.php
│ │ ├── AddDistrictFieldSubscriber.php
│ │ ├── AddMetroFieldSubscriber.php
│ │ ├── AddNeighborhoodFieldSubscriber.php
│ │ ├── UpdateDistrictFieldSubscriber.php
│ │ ├── UpdateMetroFieldSubscriber.php
│ │ └── UpdateNeighborhoodFieldSubscriber.php
│ └── Type
│ │ ├── CategoryType.php
│ │ ├── CityType.php
│ │ ├── CurrencyType.php
│ │ ├── DealTypeType.php
│ │ ├── DistrictType.php
│ │ ├── FeatureType.php
│ │ ├── FeedbackType.php
│ │ ├── FilterSettingsType.php
│ │ ├── LanguageType.php
│ │ ├── LoginFormType.php
│ │ ├── MainSettingsType.php
│ │ ├── MapSettingsType.php
│ │ ├── MenuType.php
│ │ ├── MetroType.php
│ │ ├── NeighborhoodType.php
│ │ ├── PageType.php
│ │ ├── PasswordType.php
│ │ ├── ProfileType.php
│ │ ├── PropertyDescriptionType.php
│ │ ├── PropertyType.php
│ │ ├── RegistrationFormType.php
│ │ ├── UserEmailType.php
│ │ └── UserType.php
├── Kernel.php
├── Mailer
│ └── Mailer.php
├── Message
│ ├── DeletePhotos.php
│ ├── SendEmailConfirmationLink.php
│ ├── SendFeedback.php
│ └── SendResetPasswordLink.php
├── MessageHandler
│ ├── DeletePhotosHandler.php
│ ├── SendEmailConfirmationLinkHandler.php
│ ├── SendFeedbackHandler.php
│ └── SendResetPasswordLinkHandler.php
├── Middleware
│ ├── ThrottleRequests.php
│ └── VerifyCsrfToken.php
├── Repository
│ ├── CategoryRepository.php
│ ├── CityRepository.php
│ ├── CurrencyRepository.php
│ ├── DealTypeRepository.php
│ ├── DistrictRepository.php
│ ├── FeatureRepository.php
│ ├── FilterRepository.php
│ ├── MenuRepository.php
│ ├── MetroRepository.php
│ ├── NeighborhoodRepository.php
│ ├── PageRepository.php
│ ├── PhotoRepository.php
│ ├── ProfileRepository.php
│ ├── PropertyDescriptionRepository.php
│ ├── PropertyRepository.php
│ ├── ResettingRepository.php
│ ├── SettingsRepository.php
│ ├── SimilarRepository.php
│ ├── UserPropertyRepository.php
│ └── UserRepository.php
├── Security
│ ├── RegistrationFormAuthenticator.php
│ └── Voter
│ │ ├── PropertyVoter.php
│ │ └── UserVoter.php
├── Service
│ ├── AbstractService.php
│ ├── Admin
│ │ ├── CategoryService.php
│ │ ├── CityService.php
│ │ ├── DashboardService.php
│ │ ├── DealTypeService.php
│ │ ├── PageService.php
│ │ ├── PropertyService.php
│ │ ├── SettingsService.php
│ │ └── UserService.php
│ ├── Auth
│ │ ├── EmailVerifier.php
│ │ └── ResettingService.php
│ ├── Cache
│ │ ├── ClearCache.php
│ │ ├── GetCache.php
│ │ └── UserDataCache.php
│ ├── CityService.php
│ ├── FileUploader.php
│ ├── URLService.php
│ └── User
│ │ ├── GoogleAuthenticatorAdapter.php
│ │ ├── GoogleAuthenticatorService.php
│ │ ├── PasswordService.php
│ │ └── PropertyService.php
├── Transformer
│ ├── PropertyTransformer.php
│ ├── RequestToArrayTransformer.php
│ └── UserTransformer.php
├── Twig
│ └── AppExtension.php
├── Utils
│ ├── HtmlHelper.php
│ ├── Slugger.php
│ ├── SluggerInterface.php
│ ├── TokenGenerator.php
│ ├── TokenGeneratorInterface.php
│ └── UserFormDataSelector.php
└── Validator
│ ├── ConfirmPassword.php
│ ├── ConfirmPasswordValidator.php
│ ├── PhotoRequirements.php
│ ├── RegisteredUser.php
│ └── RegisteredUserValidator.php
├── symfony.lock
├── templates
├── admin
│ ├── category
│ │ ├── _action_form.html.twig
│ │ ├── edit.html.twig
│ │ ├── index.html.twig
│ │ └── new.html.twig
│ ├── city
│ │ ├── _action_form.html.twig
│ │ ├── edit.html.twig
│ │ ├── index.html.twig
│ │ └── new.html.twig
│ ├── currency
│ │ ├── _action_form.html.twig
│ │ ├── edit.html.twig
│ │ ├── index.html.twig
│ │ └── new.html.twig
│ ├── dashboard
│ │ └── index.html.twig
│ ├── deal_type
│ │ ├── _action_form.html.twig
│ │ ├── edit.html.twig
│ │ ├── index.html.twig
│ │ └── new.html.twig
│ ├── district
│ │ ├── _action_form.html.twig
│ │ ├── edit.html.twig
│ │ ├── index.html.twig
│ │ └── new.html.twig
│ ├── feature
│ │ ├── _action_form.html.twig
│ │ ├── edit.html.twig
│ │ ├── index.html.twig
│ │ └── new.html.twig
│ ├── layout
│ │ ├── base.html.twig
│ │ └── partials
│ │ │ ├── _navbar.html.twig
│ │ │ └── _sidebar.html.twig
│ ├── menu
│ │ ├── _action_form.html.twig
│ │ ├── edit.html.twig
│ │ ├── index.html.twig
│ │ └── new.html.twig
│ ├── metro
│ │ ├── _action_form.html.twig
│ │ ├── edit.html.twig
│ │ ├── index.html.twig
│ │ └── new.html.twig
│ ├── neighborhood
│ │ ├── _action_form.html.twig
│ │ ├── edit.html.twig
│ │ ├── index.html.twig
│ │ └── new.html.twig
│ ├── page
│ │ ├── _action_form.html.twig
│ │ ├── edit.html.twig
│ │ ├── index.html.twig
│ │ └── new.html.twig
│ ├── photo
│ │ ├── _delete_form.html.twig
│ │ └── edit.html.twig
│ ├── property
│ │ ├── _action_form.html.twig
│ │ ├── edit.html.twig
│ │ ├── index.html.twig
│ │ └── new.html.twig
│ ├── settings
│ │ ├── header_settings.html.twig
│ │ ├── main_settings.html.twig
│ │ ├── map_settings.html.twig
│ │ └── partials
│ │ │ ├── _filter_settings_form.html.twig
│ │ │ ├── _header_settings_form.html.twig
│ │ │ └── _nav_tabs.html.twig
│ └── user
│ │ ├── _action_form.html.twig
│ │ ├── edit.html.twig
│ │ ├── index.html.twig
│ │ └── new.html.twig
├── auth
│ ├── login.html.twig
│ ├── passwords
│ │ ├── password_change.html.twig
│ │ └── password_reset.html.twig
│ ├── register.html.twig
│ └── two_factor
│ │ └── two_factor_form.html.twig
├── bundles
│ └── TwigBundle
│ │ └── Exception
│ │ ├── error404.html.twig
│ │ └── error429.html.twig
├── common
│ ├── _delete_button.html.twig
│ └── _flash_messages.html.twig
├── emails
│ ├── confirmation_email.html.twig
│ └── reset.txt.twig
├── layout
│ ├── base.html.twig
│ └── partials
│ │ ├── _locale_switcher.html.twig
│ │ └── _navbar.html.twig
├── page
│ ├── partials
│ │ └── _contact_form.html.twig
│ └── show.html.twig
├── property
│ ├── index.html.twig
│ ├── map.html.twig
│ ├── partials
│ │ ├── _contact_widget.html.twig
│ │ ├── _overview.html.twig
│ │ ├── _search_form.html.twig
│ │ ├── _search_widget.html.twig
│ │ ├── _similar_properties.html.twig
│ │ └── _slider.html.twig
│ └── show.html.twig
├── sitemap
│ ├── cities.xml.twig
│ ├── properties.xml.twig
│ └── sitemap.xml.twig
└── user
│ ├── common
│ ├── _floating_action_button.html.twig
│ └── _sidebar.html.twig
│ ├── photo
│ ├── _delete_form.html.twig
│ └── edit.html.twig
│ ├── profile
│ └── profile.html.twig
│ ├── property
│ ├── edit.html.twig
│ ├── index.html.twig
│ ├── new.html.twig
│ └── partials
│ │ └── _properties.html.twig
│ └── security
│ ├── _change_password.html.twig
│ ├── _google_authenticator.html.twig
│ └── security.html.twig
├── tests
├── E2E
│ ├── Auth
│ │ └── AuthTest.php
│ ├── HomepageTest.php
│ └── User
│ │ ├── GoogleAuthenticatorTest.php
│ │ └── PasswordChangeTest.php
├── Functional
│ └── Controller
│ │ ├── Admin
│ │ ├── AbstractLocationControllerTest.php
│ │ ├── CategoryControllerTest.php
│ │ ├── CityControllerTest.php
│ │ ├── CurrencyControllerTest.php
│ │ ├── DashboardControllerTest.php
│ │ ├── DealTypeControllerTest.php
│ │ ├── DistrictControllerTest.php
│ │ ├── FeatureControllerTest.php
│ │ ├── MenuControllerTest.php
│ │ ├── MetroControllerTest.php
│ │ ├── NeighborhoodControllerTest.php
│ │ ├── PageControllerTest.php
│ │ ├── PropertyControllerTest.php
│ │ ├── Settings
│ │ │ ├── HeaderSettingsControllerTest.php
│ │ │ ├── MainSettingsControllerTest.php
│ │ │ └── MapSettingsControllerTest.php
│ │ └── UserControllerTest.php
│ │ ├── Ajax
│ │ └── CityControllerTest.php
│ │ ├── Auth
│ │ ├── RegisterControllerTest.php
│ │ ├── ResendVerificationControllerTest.php
│ │ ├── ResettingControllerTest.php
│ │ └── VerificationControllerTest.php
│ │ ├── DefaultControllerTest.php
│ │ ├── PageControllerTest.php
│ │ ├── PropertyControllerTest.php
│ │ ├── SitemapControllerTest.php
│ │ └── User
│ │ ├── PhotoControllerTest.php
│ │ ├── ProfileControllerTest.php
│ │ ├── PropertyControllerTest.php
│ │ └── Security
│ │ ├── GoogleAuthenticatorControllerTest.php
│ │ └── PasswordControllerTest.php
├── Helper
│ ├── PantherTestHelper.php
│ └── WebTestHelper.php
├── Integration
│ ├── Command
│ │ └── ListUsersCommandTest.php
│ └── Transformer
│ │ ├── RequestToArrayTransformerTest.php
│ │ └── UserTransformerTest.php
├── Unit
│ └── Utils
│ │ ├── HtmlHelperTest.php
│ │ └── SluggerTest.php
└── bootstrap.php
├── translations
├── messages.bg.xlf
├── messages.en.xlf
├── messages.hu.xlf
├── messages.nl.xlf
├── messages.ru.xlf
├── validators.en.xlf
├── validators.hu.xlf
└── validators.ru.xlf
├── webpack.config.js
└── yarn.lock
/.dockerignore:
--------------------------------------------------------------------------------
1 | **/*.log
2 | **/*.md
3 | **/*.php~
4 | **/*.dist.php
5 | **/*.dist
6 | **/*.cache
7 | **/._*
8 | **/.dockerignore
9 | **/.DS_Store
10 | **/.git/
11 | **/.gitattributes
12 | **/.gitignore
13 | **/.gitmodules
14 | **/compose.*.yaml
15 | **/compose.*.yml
16 | **/compose.yaml
17 | **/compose.yml
18 | **/docker-compose.*.yaml
19 | **/docker-compose.*.yml
20 | **/docker-compose.yaml
21 | **/docker-compose.yml
22 | **/Dockerfile
23 | **/Thumbs.db
24 | .github/
25 | docs/
26 | public/bundles/
27 | tests/
28 | var/
29 | vendor/
30 | .editorconfig
31 | .env.*.local
32 | .env.local
33 | .env.local.php
34 | .env.test
35 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | ; top-most EditorConfig file
2 | root = true
3 |
4 | ; Unix-style newlines
5 | [*]
6 | charset = utf-8
7 | end_of_line = LF
8 | insert_final_newline = true
9 | trim_trailing_whitespace = true
10 |
11 | [*.{php,html,twig}]
12 | indent_style = space
13 | indent_size = 4
14 |
15 | [*.php]
16 | ij_php_comma_after_last_array_element = true
17 | ij_php_blank_lines_before_return_statement = 1
18 | ij_php_blank_lines_after_opening_tag = 1
19 | ij_php_space_after_type_cast = true
20 |
--------------------------------------------------------------------------------
/.env.test:
--------------------------------------------------------------------------------
1 | # define your env variables for the test env here
2 | KERNEL_CLASS='App\Kernel'
3 | APP_SECRET='$ecretf0rt3st'
4 | SYMFONY_DEPRECATIONS_HELPER=999999
5 | PANTHER_APP_ENV=test
6 | PANTHER_ERROR_SCREENSHOT_DIR=./var/error-screenshots
7 | DATABASE_URL="mysql://app:!ChangeMe!@127.0.0.1:3306/app?serverVersion=8.0.35&charset=utf8mb4"
8 |
9 | PANTHER_CHROME_ARGUMENTS="--disable-dev-shm-usage"
10 | PANTHER_NO_SANDBOX="1"
11 |
--------------------------------------------------------------------------------
/.eslintrc:
--------------------------------------------------------------------------------
1 | {
2 | "parser": "@babel/eslint-parser",
3 | "env": {
4 | "node": true
5 | },
6 | "parserOptions": {
7 | "ecmaVersion": 2019,
8 | "sourceType": "module"
9 | },
10 | "rules": {
11 | "comma-dangle": [
12 | "error",
13 | {
14 | "arrays": "never",
15 | "objects": "never",
16 | "imports": "never",
17 | "exports": "never",
18 | "functions": "never"
19 | }
20 | ],
21 | "eqeqeq": ["error", "always"],
22 | "linebreak-style": ["off", "unix"],
23 | "newline-before-return": "error",
24 | "no-console": "error",
25 | "no-const-assign": "error",
26 | "no-extra-semi": "error",
27 | "no-lonely-if": "error",
28 | "no-unexpected-multiline": "error",
29 | "no-unused-vars": "error",
30 | "no-unreachable": "error",
31 | "no-var": "error",
32 | "object-curly-spacing": "off",
33 | "operator-assignment": "error",
34 | "prefer-destructuring": "error",
35 | "quotes": ["error", "single"],
36 | "semi": ["error", "always"]
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | * text=auto eol=lf
2 |
3 | *.conf text eol=lf
4 | *.html text eol=lf
5 | *.ini text eol=lf
6 | *.js text eol=lf
7 | *.json text eol=lf
8 | *.md text eol=lf
9 | *.php text eol=lf
10 | *.sh text eol=lf
11 | *.yaml text eol=lf
12 | *.yml text eol=lf
13 | bin/console text eol=lf
14 | composer.lock text eol=lf merge=ours
15 |
16 | *.ico binary
17 | *.png binary
18 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | /drivers/
2 | /.idea/
3 | /public/uploads/images/*/*.*
4 |
5 | ###> symfony/framework-bundle ###
6 | /.env.local
7 | /.env.local.php
8 | /.env.*.local
9 | /config/secrets/prod/prod.decrypt.private.php
10 | /public/bundles/
11 | /var/
12 | /vendor/
13 | ###< symfony/framework-bundle ###
14 |
15 | ###> symfony/phpunit-bridge ###
16 | .phpunit
17 | .phpunit.result.cache
18 | /phpunit.xml
19 | ###< symfony/phpunit-bridge ###
20 |
21 | ###> symfony/webpack-encore-bundle ###
22 | /node_modules/
23 | npm-debug.log
24 | yarn-error.log
25 | ###< symfony/webpack-encore-bundle ###
26 |
27 | ###> friendsofphp/php-cs-fixer ###
28 | /.php-cs-fixer.php
29 | ###< friendsofphp/php-cs-fixer ###
30 |
31 | ###> phpunit/phpunit ###
32 | /phpunit.xml
33 | .phpunit.result.cache
34 | ###< phpunit/phpunit ###
35 |
--------------------------------------------------------------------------------
/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "printWidth": 70,
3 | "semi": true,
4 | "singleQuote": true,
5 | "tabWidth": 4,
6 | "trailingComma": "none"
7 | }
8 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | Contributing
2 | ============
3 |
4 | ResidenceCMS is an open source project. Contributions made by
5 | the community are welcome. Send us your ideas, code reviews, pull requests and
6 | feature requests to help us improve this project. All contributions must follow the [usual Symfony contribution requirements](https://symfony.com/doc/current/contributing/index.html).
7 |
8 | ## Any contributions you make will be under the MIT Software License
9 | In short, when you submit code changes, your submissions are understood to be under the same [MIT License](http://choosealicense.com/licenses/mit/) that covers the project. Feel free to contact the maintainers if that's a concern.
10 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2018-2024 Valery Maslov
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining a copy
4 | of this software and associated documentation files (the "Software"), to deal
5 | in the Software without restriction, including without limitation the rights
6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 | copies of the Software, and to permit persons to whom the Software is furnished
8 | to do so, subject to the following conditions:
9 |
10 | The above copyright notice and this permission notice shall be included in all
11 | copies or substantial portions of the Software.
12 |
13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19 | THE SOFTWARE.
20 |
--------------------------------------------------------------------------------
/assets/app.js:
--------------------------------------------------------------------------------
1 | import $ from 'jquery';
2 | window.jQuery = $;
3 | window.$ = $;
4 | import 'popper.js';
5 | import 'bootstrap';
6 | import 'lazysizes';
7 | import bootbox from 'bootbox';
8 | window.bootbox = bootbox;
9 |
10 | $.ajaxSetup({
11 | headers: {
12 | 'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
13 | }
14 | });
15 |
--------------------------------------------------------------------------------
/assets/controllers/.gitignore:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Coderberg/ResidenceCMS/72ae486fb774f94143d91af695da4bbf2236e5fe/assets/controllers/.gitignore
--------------------------------------------------------------------------------
/assets/js/admin/menu-sorting.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | const changeButtons = () => {
4 | $('.js-down-one')
5 | .removeClass('js-down-one')
6 | .addClass('js-up-one')
7 | .html(' Up one');
8 |
9 | $('.js-move:first')
10 | .removeClass('js-up-one')
11 | .addClass('js-down-one')
12 | .html(' Down one');
13 | };
14 |
15 | const sendRequest = () => {
16 | const item = $('.js-move');
17 |
18 | if (item.length > 1) {
19 | let items = [];
20 |
21 | item.each(function () {
22 | items.push(parseInt($(this).attr('id'), 10));
23 | });
24 |
25 | $.ajax({
26 | method: 'POST',
27 | url: '/en/admin/menu/sort',
28 | data: { items: items }
29 | });
30 | }
31 | };
32 |
33 | $(document).ready(function () {
34 | $('body').on('click', '.js-move', function () {
35 | let row = $(this).parents('tr:first');
36 |
37 | if ($(this).is('.js-up-one')) {
38 | row.insertBefore(row.prev());
39 | } else {
40 | row.insertAfter(row.next());
41 | }
42 |
43 | changeButtons();
44 | sendRequest();
45 | });
46 | });
47 |
--------------------------------------------------------------------------------
/assets/js/admin/settings.js:
--------------------------------------------------------------------------------
1 | import Dropzone from 'dropzone';
2 |
3 | Dropzone.autoDiscover = false;
4 |
5 | $(document).ready(function () {
6 | const configureDropzone = ($form) => {
7 | const token = $form.data('token');
8 | if ($form.length) {
9 | $form.dropzone({
10 | url: $form.attr('action'),
11 | acceptedFiles: 'image/*',
12 | sending: function (file, xhr, formData) {
13 | formData.append('csrf_token', token);
14 | },
15 | queuecomplete: function () {
16 | setTimeout(function () {
17 | window.location.reload();
18 | }, 200);
19 | }
20 | });
21 | }
22 | };
23 |
24 | configureDropzone($('form[action$="upload_logo_image"]'));
25 | configureDropzone($('form[action$="upload_header_image"]'));
26 | });
27 |
--------------------------------------------------------------------------------
/assets/js/auth/_resend.js:
--------------------------------------------------------------------------------
1 | (function ($, bootbox) {
2 | 'use strict';
3 |
4 | const link = $('#resend');
5 |
6 | // Show confirmation link
7 | if (link.length > 0) {
8 | $.ajax({
9 | url: '/en/auth/should_link_be_visible',
10 | type: 'GET',
11 | success: function (response) {
12 | if (response.display === true) {
13 | link.show();
14 | }
15 | }
16 | });
17 | }
18 |
19 | const resend = () => {
20 | $.ajax({
21 | url: link.data('path'),
22 | type: 'POST',
23 | success: function (response) {
24 | link.hide();
25 | bootbox.alert(response.message);
26 | }
27 | });
28 | };
29 |
30 | link.click(resend);
31 | })($, bootbox);
32 |
--------------------------------------------------------------------------------
/assets/js/auth/auth.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | import './_resend';
4 |
--------------------------------------------------------------------------------
/assets/js/bottom-bar.js:
--------------------------------------------------------------------------------
1 | (function ($) {
2 | 'use strict';
3 |
4 | const $phone = $('#phone');
5 | const $email = $('#email');
6 |
7 | $('body').append(`
`);
15 | })(window.jQuery);
16 |
--------------------------------------------------------------------------------
/assets/js/common/_delete_button.js:
--------------------------------------------------------------------------------
1 | (function ($, bootbox) {
2 | 'use strict';
3 |
4 | // Confirm deletion
5 | $('[data-type="delete"]').click(function (e) {
6 | e.preventDefault();
7 | const $form = $(this).closest('form');
8 | const message = $(this).data('message');
9 | const confirmationText = $(this).data('confirmation-text');
10 | const cancellationText = $(this).data('cancellation-text');
11 |
12 | bootbox.confirm({
13 | message,
14 | buttons: {
15 | cancel: {
16 | label: cancellationText,
17 | className: 'btn-light'
18 | },
19 | confirm: {
20 | label: confirmationText,
21 | className: 'btn-danger'
22 | }
23 | },
24 | callback: function (result) {
25 | if (result) {
26 | $form.submit();
27 | }
28 | }
29 | });
30 | });
31 | })($, bootbox);
32 |
--------------------------------------------------------------------------------
/assets/js/ekko-lightbox.js:
--------------------------------------------------------------------------------
1 | import 'ekko-lightbox/dist/ekko-lightbox';
2 |
3 | $('body').on('click', '[data-toggle="lightbox"]', function (event) {
4 | event.preventDefault();
5 | $(this).ekkoLightbox();
6 | });
7 |
--------------------------------------------------------------------------------
/assets/js/map.js:
--------------------------------------------------------------------------------
1 | /** global: ymaps */
2 | ymaps.ready(init);
3 |
4 | const $map = $('#map');
5 | const latitude = $map.data('latitude');
6 | const longitude = $map.data('longitude');
7 | const hintContent = $map.attr('data-hintContent');
8 | const balloonContent = $map.attr('data-balloonContent');
9 |
10 | function init() {
11 | // Creating the map.
12 | let myMap = new ymaps.Map('map', {
13 | center: [latitude, longitude],
14 | zoom: 13
15 | });
16 |
17 | let currentApartment = new ymaps.Placemark(
18 | [latitude, longitude],
19 | {
20 | hintContent: hintContent,
21 | balloonContent: balloonContent
22 | },
23 | {
24 | preset: 'islands#blueHomeIcon'
25 | }
26 | );
27 |
28 | myMap.geoObjects.add(currentApartment);
29 | }
30 |
31 | $map.css({
32 | width: '100%',
33 | height: '280px',
34 | 'padding-top': '20px'
35 | });
36 |
--------------------------------------------------------------------------------
/assets/js/page.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | $(document).ready(function () {
4 | let $checkbox = $('#page_add_contact_form');
5 | let $emailContainer = $('#email-address');
6 | let $emailField = $('#page_contact_email_address');
7 |
8 | if ($checkbox.attr('checked') === 'checked') {
9 | $emailContainer.slideDown();
10 | $emailField.prop('required', true);
11 | }
12 |
13 | // Event Handler
14 | $checkbox.on('change', function () {
15 | updateDisplay();
16 | });
17 |
18 | // Action
19 |
20 | function updateDisplay() {
21 | let isChecked = $checkbox.is(':checked');
22 |
23 | if (isChecked) {
24 | $emailContainer.slideDown();
25 | $emailField.focus().prop('required', true);
26 | } else {
27 | $emailContainer.slideUp();
28 | $emailField.prop('required', false);
29 | }
30 | }
31 | });
32 |
--------------------------------------------------------------------------------
/assets/js/select2.js:
--------------------------------------------------------------------------------
1 | import 'select2/dist/js/select2.min';
2 |
3 | $(document).ready(function () {
4 | $('#property_features').select2();
5 | });
6 |
--------------------------------------------------------------------------------
/assets/js/slugger.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | const slugify = require('slugify');
4 |
5 | $(document).ready(function () {
6 | $('#name input').keyup(function () {
7 | $('#slug input').val(
8 | slugify($('#name input').val(), {
9 | lower: true,
10 | strict: true
11 | })
12 | );
13 | });
14 | });
15 |
--------------------------------------------------------------------------------
/assets/js/user/_property.js:
--------------------------------------------------------------------------------
1 | (function ($) {
2 | 'use strict';
3 |
4 | // Properties
5 | $('.btn-outline-secondary').click(function (e) {
6 | e.preventDefault();
7 | $(this).addClass('disabled');
8 |
9 | let url = $(this).attr('href');
10 | let $div = $(this).parent().parent().parent();
11 |
12 | $div.css({ opacity: '0.5' });
13 |
14 | $.get(url).done(function () {
15 | $div.fadeOut();
16 | changeCount();
17 | });
18 | });
19 |
20 | // Change count
21 | function changeCount() {
22 | let $counter = $('.js-counter');
23 | let counter = $counter.text();
24 | counter = Number.parseInt(counter);
25 | counter -= 1;
26 | $counter.text(counter);
27 | }
28 | })($);
29 |
--------------------------------------------------------------------------------
/assets/js/user/_sidebar.js:
--------------------------------------------------------------------------------
1 | (function ($) {
2 | 'use strict';
3 |
4 | let currentUrl = window.location.href;
5 |
6 | if (currentUrl.indexOf('profile') !== -1) {
7 | $('.list-group-item-action:eq(2)').addClass('active');
8 | } else if (currentUrl.indexOf('unpublished') !== -1) {
9 | $('.list-group-item-action:eq(1)').addClass('active');
10 | } else if (currentUrl.indexOf('security') !== -1) {
11 | $('.list-group-item-action:eq(3)').addClass('active');
12 | } else {
13 | $('.list-group-item-action:eq(0)').addClass('active');
14 | }
15 | })(window.jQuery);
16 |
--------------------------------------------------------------------------------
/assets/js/user/password/password.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | import './_validate_password';
4 | import './_update_password';
5 |
--------------------------------------------------------------------------------
/assets/js/user/user.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | import './_sidebar';
4 | import './_property';
5 | import '../common/_delete_button';
6 |
--------------------------------------------------------------------------------
/assets/psd/no-photo.psd:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Coderberg/ResidenceCMS/72ae486fb774f94143d91af695da4bbf2236e5fe/assets/psd/no-photo.psd
--------------------------------------------------------------------------------
/assets/styles/_variables.scss:
--------------------------------------------------------------------------------
1 |
2 | // Body
3 | $body-bg: #f5f5fa;
4 |
5 | // Code
6 | $code-color: #212529 !default;
7 | $code-font-size: 12px !default;
8 |
9 | // Lead
10 | $lead-font-size: 2.5rem !default;
11 |
12 | // Jumbotron
13 | $jumbotron-bg: transparent !default;
14 |
15 | // Fonts
16 | $fa-font-path: "../fonts";
17 |
--------------------------------------------------------------------------------
/assets/styles/bottom-bar.scss:
--------------------------------------------------------------------------------
1 | .bottom-bar {
2 | display: none;
3 | }
4 |
5 | @media (max-width: 767px) {
6 | footer {
7 | margin-bottom: 70px;
8 | }
9 | .bottom-bar {
10 | display: block !important;
11 | position: fixed;
12 | bottom: 0;
13 | left: 0;
14 | width: 100%;
15 | z-index: 50;
16 | padding: 0;
17 | margin: 0;
18 | background-color: #fff;
19 | box-shadow: 0 0 5px rgb(0 0 0 / 30%);
20 | }
21 | .bottom-bar a {
22 | width: 50%;
23 | float: left;
24 | text-align: center;
25 | font-size: 15px;
26 | line-height: 3.2em;
27 | display: inline-block;
28 | z-index: 100;
29 | vertical-align: middle;
30 | touch-action: manipulation;
31 | cursor: pointer;
32 | -webkit-user-select: none;
33 | -moz-user-select: none;
34 | -ms-user-select: none;
35 | user-select: none;
36 | }
37 | a.btn-right {
38 | background-color: #007bff;
39 | }
40 | a.btn-right, a.btn-right:active, a.btn-right:focus, a.btn-right:hover {
41 | color: #fff;
42 | text-decoration: none;
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/assets/styles/city.scss:
--------------------------------------------------------------------------------
1 | .location {
2 | font-size: 1.3rem;
3 | }
4 |
5 | .sub-location {
6 | font-size: 1rem;
7 | padding-left: 30px !important;
8 | }
9 |
--------------------------------------------------------------------------------
/assets/styles/detail.scss:
--------------------------------------------------------------------------------
1 | #map {
2 | height: 0;
3 | }
4 |
5 | // Contact widget
6 | .icon-box {
7 | background-color: #f9f9f9;
8 | border-radius: 50%;
9 | height: 50px;
10 | text-align: center;
11 | transition: all linear .15s;
12 | width: 50px;
13 | float: left;
14 | }
15 |
16 | .contact-box {
17 | margin: 10px 30px;
18 |
19 | h4 {
20 | font-weight: 400;
21 | padding-top: 2px;
22 | }
23 |
24 | p {
25 | color: #959595;
26 | line-height: 1.8;
27 |
28 | a {
29 | color: #959595;
30 |
31 | &:hover {
32 | color: #f1572f;
33 | text-decoration: none;
34 | }
35 | }
36 | }
37 |
38 | .icon-box i {
39 | color: #f1572f;
40 | }
41 | }
42 |
43 | // Overview
44 | .overview {
45 | border: 1px solid #b5b5b5;
46 | margin: 0 30px 10px 0;
47 | padding: 20px;
48 |
49 | table {
50 | th {
51 | text-align: left;
52 | padding-right: 15px;
53 | font-weight: normal;
54 | }
55 |
56 | tr {
57 | vertical-align: text-top !important;
58 | }
59 | }
60 | }
61 |
62 | @media (min-width: 992px) {
63 | .overview {
64 | float: left;
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/assets/styles/ekko-lightbox.scss:
--------------------------------------------------------------------------------
1 | @import "~ekko-lightbox/dist/ekko-lightbox";
2 |
--------------------------------------------------------------------------------
/assets/styles/select2.scss:
--------------------------------------------------------------------------------
1 | @import '~select2/dist/css/select2.css';
2 |
3 | .select2-container--default .select2-selection--multiple {
4 | border: 1px solid #ced4da;
5 | }
6 |
7 | .select2-container--default.select2-container--focus .select2-selection--multiple {
8 | border-color: #8bbafe;
9 | outline: 0;
10 | box-shadow: 0 0 0 0.2rem rgba(13, 110, 253, 0.25);
11 | }
12 |
--------------------------------------------------------------------------------
/assets/styles/user/security.scss:
--------------------------------------------------------------------------------
1 | .security-buttons a i {
2 | background-color: #fff;
3 | padding: 20px;
4 | border-radius: 50%;
5 | color: #BDC3C7;
6 | }
7 |
--------------------------------------------------------------------------------
/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | presets: [
3 | [
4 | '@babel/preset-env',
5 | {
6 | modules: 'auto',
7 | targets: { node: 'current' }
8 | }
9 | ]
10 | ],
11 | plugins: [
12 | [
13 | '@babel/plugin-proposal-class-properties',
14 | {
15 | loose: true
16 | }
17 | ]
18 | ]
19 | };
20 |
--------------------------------------------------------------------------------
/bin/console:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env php
2 | ['all' => true],
5 | Symfony\Bundle\TwigBundle\TwigBundle::class => ['all' => true],
6 | Twig\Extra\TwigExtraBundle\TwigExtraBundle::class => ['all' => true],
7 | Symfony\Bundle\WebProfilerBundle\WebProfilerBundle::class => ['dev' => true, 'test' => true],
8 | Symfony\Bundle\MonologBundle\MonologBundle::class => ['all' => true],
9 | Symfony\Bundle\DebugBundle\DebugBundle::class => ['dev' => true],
10 | Doctrine\Bundle\DoctrineBundle\DoctrineBundle::class => ['all' => true],
11 | Doctrine\Bundle\MigrationsBundle\DoctrineMigrationsBundle::class => ['all' => true],
12 | Symfony\Bundle\SecurityBundle\SecurityBundle::class => ['all' => true],
13 | Symfony\Bundle\MakerBundle\MakerBundle::class => ['dev' => true],
14 | Knp\Bundle\PaginatorBundle\KnpPaginatorBundle::class => ['all' => true],
15 | Symfony\WebpackEncoreBundle\WebpackEncoreBundle::class => ['all' => true],
16 | Doctrine\Bundle\FixturesBundle\DoctrineFixturesBundle::class => ['dev' => true, 'test' => true],
17 | SymfonyCasts\Bundle\VerifyEmail\SymfonyCastsVerifyEmailBundle::class => ['all' => true],
18 | Scheb\TwoFactorBundle\SchebTwoFactorBundle::class => ['all' => true],
19 | ];
20 |
--------------------------------------------------------------------------------
/config/packages/assets.yaml:
--------------------------------------------------------------------------------
1 | framework:
2 | assets:
3 | json_manifest_path: '%kernel.project_dir%/public/build/manifest.json'
4 |
--------------------------------------------------------------------------------
/config/packages/cache.yaml:
--------------------------------------------------------------------------------
1 | framework:
2 | cache:
3 | # Unique name of your app: used to compute stable namespaces for cache keys.
4 | #prefix_seed: your_vendor_name/app_name
5 |
6 | # The "app" cache stores to the filesystem by default.
7 | # The data in this cache should persist between deploys.
8 | # Other options include:
9 |
10 | # Redis
11 | #app: cache.adapter.redis
12 | #default_redis_provider: redis://localhost
13 |
14 | # APCu (not recommended with heavy random-write workloads as memory fragmentation can cause perf issues)
15 | #app: cache.adapter.apcu
16 |
17 | # Namespaced pools use the above "app" backend by default
18 | #pools:
19 | #my.dedicated.cache: null
20 |
--------------------------------------------------------------------------------
/config/packages/debug.yaml:
--------------------------------------------------------------------------------
1 | when@dev:
2 | debug:
3 | # Forwards VarDumper Data clones to a centralized server allowing to inspect dumps on CLI or in your browser.
4 | # See the "server:dump" command to start a new server.
5 | dump_destination: "tcp://%env(VAR_DUMPER_SERVER)%"
6 |
--------------------------------------------------------------------------------
/config/packages/dev/easy_log_handler.yaml:
--------------------------------------------------------------------------------
1 | services:
2 | EasyCorp\EasyLog\EasyLogHandler:
3 | public: false
4 | arguments: ['%kernel.logs_dir%/%kernel.environment%.log']
5 |
6 | #// FIXME: How to add this configuration automatically without messing up with the monolog configuration?
7 | #monolog:
8 | # handlers:
9 | # buffered:
10 | # type: buffer
11 | # handler: easylog
12 | # channels: ['!event']
13 | # level: debug
14 | # easylog:
15 | # type: service
16 | # id: EasyCorp\EasyLog\EasyLogHandler
17 |
--------------------------------------------------------------------------------
/config/packages/doctrine_migrations.yaml:
--------------------------------------------------------------------------------
1 | doctrine_migrations:
2 | migrations_paths:
3 | # namespace is arbitrary but should be different from App\Migrations
4 | # as migrations classes should NOT be autoloaded
5 | 'DoctrineMigrations': '%kernel.project_dir%/migrations'
6 | enable_profiler: '%kernel.debug%'
7 |
--------------------------------------------------------------------------------
/config/packages/framework.yaml:
--------------------------------------------------------------------------------
1 | # see https://symfony.com/doc/current/reference/configuration/framework.html
2 | framework:
3 | secret: '%env(APP_SECRET)%'
4 | csrf_protection: true
5 |
6 | # Note that the session will be started ONLY if you read or write from it.
7 | session: true
8 |
9 | #esi: true
10 | #fragments: true
11 |
12 | when@test:
13 | framework:
14 | test: true
15 | session:
16 | storage_factory_id: session.storage.factory.mock_file
17 |
--------------------------------------------------------------------------------
/config/packages/knp_paginator.yaml:
--------------------------------------------------------------------------------
1 | knp_paginator:
2 | page_range: 3
3 | template:
4 | pagination: '@KnpPaginator/Pagination/twitter_bootstrap_v4_pagination.html.twig'
5 |
--------------------------------------------------------------------------------
/config/packages/lock.yaml:
--------------------------------------------------------------------------------
1 | framework:
2 | lock: '%env(LOCK_DSN)%'
3 |
--------------------------------------------------------------------------------
/config/packages/mailer.yaml:
--------------------------------------------------------------------------------
1 | framework:
2 | mailer:
3 | dsn: '%env(MAILER_DSN)%'
4 |
5 | when@test:
6 | framework:
7 | mailer:
8 | # this disables delivery of messages entirely
9 | dsn: 'null://null'
10 |
--------------------------------------------------------------------------------
/config/packages/messenger.yaml:
--------------------------------------------------------------------------------
1 | framework:
2 | messenger:
3 | # reset_on_message: true
4 | # Uncomment this (and the failed transport below) to send failed messages to this transport for later handling.
5 | # failure_transport: failed
6 |
7 | transports:
8 | # https://symfony.com/doc/current/messenger.html#transport-configuration
9 | # async: '%env(MESSENGER_TRANSPORT_DSN)%'
10 | # failed: 'doctrine://default?queue_name=failed'
11 | # sync: 'sync://'
12 |
13 | routing:
14 | # Route your messages to the transports
15 | # 'App\Message\YourMessage': async
16 |
--------------------------------------------------------------------------------
/config/packages/notifier.yaml:
--------------------------------------------------------------------------------
1 | framework:
2 | notifier:
3 | #chatter_transports:
4 | # slack: '%env(SLACK_DSN)%'
5 | # telegram: '%env(TELEGRAM_DSN)%'
6 | #texter_transports:
7 | # twilio: '%env(TWILIO_DSN)%'
8 | # nexmo: '%env(NEXMO_DSN)%'
9 | channel_policy:
10 | # use chat/slack, chat/telegram, sms/twilio or sms/nexmo
11 | urgent: ['email']
12 | high: ['email']
13 | medium: ['email']
14 | low: ['email']
15 | admin_recipients:
16 | - { email: admin@example.com }
17 |
--------------------------------------------------------------------------------
/config/packages/prod/deprecations.yaml:
--------------------------------------------------------------------------------
1 | # As of Symfony 5.1, deprecations are logged in the dedicated "deprecation" channel when it exists
2 | #monolog:
3 | # channels: [deprecation]
4 | # handlers:
5 | # deprecation:
6 | # type: stream
7 | # channels: [deprecation]
8 | # path: php://stderr
9 |
--------------------------------------------------------------------------------
/config/packages/prod/webpack_encore.yaml:
--------------------------------------------------------------------------------
1 | #webpack_encore:
2 | # Cache the entrypoints.json (rebuild Symfony's cache when entrypoints.json changes)
3 | # Available in version 1.2
4 | #cache: true
5 |
--------------------------------------------------------------------------------
/config/packages/rate_limiter.yaml:
--------------------------------------------------------------------------------
1 | framework:
2 | rate_limiter:
3 | auth:
4 | policy: 'fixed_window'
5 | limit: 6
6 | interval: '100 seconds'
7 |
--------------------------------------------------------------------------------
/config/packages/routing.yaml:
--------------------------------------------------------------------------------
1 | framework:
2 | router:
3 | # Configure how to generate URLs in non-HTTP contexts, such as CLI commands.
4 | # See https://symfony.com/doc/current/routing.html#generating-urls-in-commands
5 | #default_uri: http://localhost
6 |
7 | when@prod:
8 | framework:
9 | router:
10 | strict_requirements: null
11 |
--------------------------------------------------------------------------------
/config/packages/scheb_2fa.yaml:
--------------------------------------------------------------------------------
1 | scheb_two_factor:
2 | security_tokens:
3 | - Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken
4 | - Symfony\Component\Security\Http\Authenticator\Token\PostAuthenticationToken
5 | - Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface
6 |
7 | google:
8 | enabled: true
9 | #server_name: server_name # Server name used in QR code
10 | issuer: issuer_placeholder # Issuer name used in QR code
11 | digits: 6 # Number of digits in authentication code
12 | leeway: 1 # Depends on the version of Spomky-Labs/otphp used:
13 | # Until v10: How many codes before/after the current one would be accepted
14 | # From v11: Acceptable time drift in seconds
15 | template: auth/two_factor/two_factor_form.html.twig # Template used to render the authentication form
16 | form_renderer: App\Controller\Auth\TwoFactor\EnterAuthCodeController
17 |
--------------------------------------------------------------------------------
/config/packages/test/rate_limiter.yaml:
--------------------------------------------------------------------------------
1 | framework:
2 | rate_limiter:
3 | auth:
4 | policy: 'fixed_window'
5 | limit: 30
6 | interval: '100 seconds'
7 | cache_pool: 'cache.rate_limiter'
8 |
--------------------------------------------------------------------------------
/config/packages/test/validator.yaml:
--------------------------------------------------------------------------------
1 | framework:
2 | validation:
3 | not_compromised_password: false
4 |
--------------------------------------------------------------------------------
/config/packages/test/webpack_encore.yaml:
--------------------------------------------------------------------------------
1 | #webpack_encore:
2 | # strict_mode: false
3 |
--------------------------------------------------------------------------------
/config/packages/translation.yaml:
--------------------------------------------------------------------------------
1 | framework:
2 | default_locale: '%env(LANGUAGE_CODE)%'
3 | translator:
4 | default_path: '%kernel.project_dir%/translations'
5 | fallbacks:
6 | - en
7 | providers:
8 |
--------------------------------------------------------------------------------
/config/packages/twig.yaml:
--------------------------------------------------------------------------------
1 | twig:
2 | file_name_pattern: '*.twig'
3 | globals:
4 | app_version: '%app_version%'
5 | locales: '%app_locales%'
6 | locale: '%locale%'
7 |
8 | when@test:
9 | twig:
10 | strict_variables: true
11 |
--------------------------------------------------------------------------------
/config/packages/validator.yaml:
--------------------------------------------------------------------------------
1 | framework:
2 | validation:
3 | # Enables validator auto-mapping support.
4 | # For instance, basic validation constraints will be inferred from Doctrine's metadata.
5 | auto_mapping:
6 | App\Entity\: []
7 |
--------------------------------------------------------------------------------
/config/packages/web_profiler.yaml:
--------------------------------------------------------------------------------
1 | when@dev:
2 | web_profiler:
3 | toolbar: true
4 | intercept_redirects: false
5 |
6 | framework:
7 | profiler:
8 | only_exceptions: false
9 | collect_serializer_data: true
10 |
11 | when@test:
12 | web_profiler:
13 | toolbar: false
14 | intercept_redirects: false
15 |
16 | framework:
17 | profiler: { collect: false }
18 |
--------------------------------------------------------------------------------
/config/preload.php:
--------------------------------------------------------------------------------
1 | addSql('ALTER TABLE property ADD created_at DATETIME DEFAULT CURRENT_TIMESTAMP, ADD updated_at DATETIME DEFAULT CURRENT_TIMESTAMP, DROP published_at');
24 | }
25 |
26 | public function down(Schema $schema) : void
27 | {
28 | // this down() migration is auto-generated, please modify it to your needs
29 | $this->addSql('ALTER TABLE property ADD published_at DATETIME NOT NULL, DROP created_at, DROP updated_at');
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/migrations/Version20210104185420.php:
--------------------------------------------------------------------------------
1 | addSql('ALTER TABLE menu ADD locale VARCHAR(2) NOT NULL');
24 | $this->addSql('ALTER TABLE page ADD locale VARCHAR(2) NOT NULL');
25 | }
26 |
27 | public function down(Schema $schema) : void
28 | {
29 | // this down() migration is auto-generated, please modify it to your needs
30 | $this->addSql('ALTER TABLE page DROP locale');
31 | $this->addSql('ALTER TABLE menu DROP locale');
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/migrations/Version20210106154655.php:
--------------------------------------------------------------------------------
1 | addSql('CREATE UNIQUE INDEX slug_locale_unique_key ON page (slug, locale)');
24 | }
25 |
26 | public function down(Schema $schema) : void
27 | {
28 | // this down() migration is auto-generated, please modify it to your needs
29 | $this->addSql('DROP INDEX slug_locale_unique_key ON page');
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/migrations/Version20210106191712.php:
--------------------------------------------------------------------------------
1 | addSql("INSERT INTO settings (setting_name, setting_value) VALUES ('show_filter_by_features', '0')");
23 | }
24 |
25 | public function down(Schema $schema) : void
26 | {
27 | $this->addSql("DELETE FROM settings WHERE setting_name='show_filter_by_features'");
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/migrations/Version20210106234742.php:
--------------------------------------------------------------------------------
1 | addSql('ALTER TABLE page CHANGE locale locale VARCHAR(2) DEFAULT \'en\' NOT NULL');
24 | }
25 |
26 | public function down(Schema $schema) : void
27 | {
28 | // this down() migration is auto-generated, please modify it to your needs
29 | $this->addSql('ALTER TABLE page CHANGE locale locale VARCHAR(2) CHARACTER SET utf8mb4 NOT NULL COLLATE `utf8mb4_unicode_ci`');
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/migrations/Version20210107000119.php:
--------------------------------------------------------------------------------
1 | addSql('CREATE UNIQUE INDEX url_locale_unique_key ON menu (url, locale)');
24 | }
25 |
26 | public function down(Schema $schema) : void
27 | {
28 | // this down() migration is auto-generated, please modify it to your needs
29 | $this->addSql('DROP INDEX url_locale_unique_key ON menu');
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/migrations/Version20210215083338.php:
--------------------------------------------------------------------------------
1 | addSql("INSERT INTO settings (setting_name, setting_value) VALUES ('logo_image', '')");
24 | }
25 |
26 | public function down(Schema $schema): void
27 | {
28 | // this down() migration is auto-generated, please modify it to your needs
29 | $this->addSql("DELETE FROM settings WHERE setting_name='logo_image'");
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/migrations/Version20210215173522.php:
--------------------------------------------------------------------------------
1 | addSql("INSERT INTO settings (setting_name, setting_value) VALUES ('show_language_selector', '0')");
24 | }
25 |
26 | public function down(Schema $schema): void
27 | {
28 | // this down() migration is auto-generated, please modify it to your needs
29 | $this->addSql("DELETE FROM settings WHERE setting_name='show_language_selector'");
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/migrations/Version20210815075052.php:
--------------------------------------------------------------------------------
1 | addSql('CREATE TABLE profile (id INT AUTO_INCREMENT NOT NULL, user_id INT NOT NULL, full_name VARCHAR(255) DEFAULT NULL, phone VARCHAR(255) DEFAULT NULL, UNIQUE INDEX UNIQ_8157AA0FA76ED395 (user_id), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB');
24 | $this->addSql('ALTER TABLE profile ADD CONSTRAINT FK_8157AA0FA76ED395 FOREIGN KEY (user_id) REFERENCES users (id)');
25 | }
26 |
27 | public function down(Schema $schema): void
28 | {
29 | // this down() migration is auto-generated, please modify it to your needs
30 | $this->addSql('DROP TABLE profile');
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/migrations/Version20220320064544.php:
--------------------------------------------------------------------------------
1 | addSql('ALTER TABLE users ADD email_verified_at DATETIME DEFAULT NULL');
24 | $this->addSql('UPDATE users SET email_verified_at=NOW()');
25 | }
26 |
27 | public function down(Schema $schema): void
28 | {
29 | // this down() migration is auto-generated, please modify it to your needs
30 | $this->addSql('ALTER TABLE users DROP email_verified_at');
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/migrations/Version20220325072850.php:
--------------------------------------------------------------------------------
1 | addSql("INSERT INTO settings (setting_name, setting_value) VALUES ('anyone_can_register', '0')");
24 | }
25 |
26 | public function down(Schema $schema): void
27 | {
28 | // this down() migration is auto-generated, please modify it to your needs
29 | $this->addSql("DELETE FROM settings WHERE setting_name='anyone_can_register'");
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/migrations/Version20220824075712.php:
--------------------------------------------------------------------------------
1 | addSql("INSERT INTO settings (setting_name, setting_value) VALUES ('allow_html', '1')");
24 | }
25 |
26 | public function down(Schema $schema): void
27 | {
28 | // this down() migration is auto-generated, please modify it to your needs
29 | $this->addSql("DELETE FROM settings WHERE setting_name='allow_html'");
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/migrations/Version20230304072206.php:
--------------------------------------------------------------------------------
1 | addSql("INSERT INTO settings (setting_name, setting_value) VALUES ('show_bottom_bar', '1')");
24 | }
25 |
26 | public function down(Schema $schema): void
27 | {
28 | // this down() migration is auto-generated, please modify it to your needs
29 | $this->addSql("DELETE FROM settings WHERE setting_name='show_bottom_bar'");
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/migrations/Version20230501134351.php:
--------------------------------------------------------------------------------
1 | addSql('ALTER TABLE users ADD google_authenticator_secret VARCHAR(255) DEFAULT NULL');
24 | }
25 |
26 | public function down(Schema $schema): void
27 | {
28 | // this down() migration is auto-generated, please modify it to your needs
29 | $this->addSql('ALTER TABLE users DROP google_authenticator_secret');
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/phpstan.dist.neon:
--------------------------------------------------------------------------------
1 | parameters:
2 | level: 5
3 | paths:
4 | - bin/
5 | - config/
6 | - public/
7 | - src/
8 |
--------------------------------------------------------------------------------
/public/.htaccess:
--------------------------------------------------------------------------------
1 |
2 | Options -MultiViews
3 |
4 | RewriteEngine On
5 | #RewriteBase /path/to/app
6 | RewriteCond %{REQUEST_FILENAME} !-d
7 | RewriteCond %{REQUEST_FILENAME} !-f
8 | RewriteRule ^ index.php [QSA,L]
9 |
10 |
--------------------------------------------------------------------------------
/public/build/css/bottom-bar.38e93f4e.css:
--------------------------------------------------------------------------------
1 | .bottom-bar{display:none}@media (max-width:767px){footer{margin-bottom:70px}.bottom-bar{background-color:#fff;bottom:0;box-shadow:0 0 5px rgba(0,0,0,.3);display:block!important;left:0;margin:0;padding:0;position:fixed;width:100%;z-index:50}.bottom-bar a{cursor:pointer;display:inline-block;float:left;font-size:15px;line-height:3.2em;text-align:center;touch-action:manipulation;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;vertical-align:middle;width:50%;z-index:100}a.btn-right{background-color:#007bff}a.btn-right,a.btn-right:active,a.btn-right:focus,a.btn-right:hover{color:#fff;text-decoration:none}}
--------------------------------------------------------------------------------
/public/build/css/city.830c14fb.css:
--------------------------------------------------------------------------------
1 | .location{font-size:1.3rem}.sub-location{font-size:1rem;padding-left:30px!important}
--------------------------------------------------------------------------------
/public/build/css/detail.3d2d5214.css:
--------------------------------------------------------------------------------
1 | #map{height:0}.icon-box{background-color:#f9f9f9;border-radius:50%;float:left;height:50px;text-align:center;transition:all .15s linear;width:50px}.contact-box{margin:10px 30px}.contact-box h4{font-weight:400;padding-top:2px}.contact-box p{color:#959595;line-height:1.8}.contact-box p a{color:#959595}.contact-box p a:hover{color:#f1572f;text-decoration:none}.contact-box .icon-box i{color:#f1572f}.overview{border:1px solid #b5b5b5;margin:0 30px 10px 0;padding:20px}.overview table th{font-weight:400;padding-right:15px;text-align:left}.overview table tr{vertical-align:text-top!important}@media (min-width:992px){.overview{float:left}}
--------------------------------------------------------------------------------
/public/build/css/security.64e38d75.css:
--------------------------------------------------------------------------------
1 | .security-buttons a i{background-color:#fff;border-radius:50%;color:#bdc3c7;padding:20px}
--------------------------------------------------------------------------------
/public/build/fonts/fa-regular-400.491974d1.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Coderberg/ResidenceCMS/72ae486fb774f94143d91af695da4bbf2236e5fe/public/build/fonts/fa-regular-400.491974d1.ttf
--------------------------------------------------------------------------------
/public/build/fonts/fa-regular-400.77206a6b.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Coderberg/ResidenceCMS/72ae486fb774f94143d91af695da4bbf2236e5fe/public/build/fonts/fa-regular-400.77206a6b.eot
--------------------------------------------------------------------------------
/public/build/fonts/fa-regular-400.7a333762.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Coderberg/ResidenceCMS/72ae486fb774f94143d91af695da4bbf2236e5fe/public/build/fonts/fa-regular-400.7a333762.woff2
--------------------------------------------------------------------------------
/public/build/fonts/fa-regular-400.bb58e57c.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Coderberg/ResidenceCMS/72ae486fb774f94143d91af695da4bbf2236e5fe/public/build/fonts/fa-regular-400.bb58e57c.woff
--------------------------------------------------------------------------------
/public/build/fonts/fa-solid-900.1551f4f6.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Coderberg/ResidenceCMS/72ae486fb774f94143d91af695da4bbf2236e5fe/public/build/fonts/fa-solid-900.1551f4f6.woff2
--------------------------------------------------------------------------------
/public/build/fonts/fa-solid-900.9bbb245e.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Coderberg/ResidenceCMS/72ae486fb774f94143d91af695da4bbf2236e5fe/public/build/fonts/fa-solid-900.9bbb245e.eot
--------------------------------------------------------------------------------
/public/build/fonts/fa-solid-900.be9ee23c.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Coderberg/ResidenceCMS/72ae486fb774f94143d91af695da4bbf2236e5fe/public/build/fonts/fa-solid-900.be9ee23c.ttf
--------------------------------------------------------------------------------
/public/build/fonts/fa-solid-900.eeccf4f6.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Coderberg/ResidenceCMS/72ae486fb774f94143d91af695da4bbf2236e5fe/public/build/fonts/fa-solid-900.eeccf4f6.woff
--------------------------------------------------------------------------------
/public/build/js/admin.32201fb1.js.LICENSE.txt:
--------------------------------------------------------------------------------
1 | /*!
2 | * JavaScript Cookie v2.2.1
3 | * https://github.com/js-cookie/js-cookie
4 | *
5 | * Copyright 2006, 2015 Klaus Hartl & Fagner Brack
6 | * Released under the MIT license
7 | */
8 |
--------------------------------------------------------------------------------
/public/build/js/auth.87b05c2f.js:
--------------------------------------------------------------------------------
1 | (self.webpackChunk=self.webpackChunk||[]).push([[795],{64:()=>{!function(s,e){"use strict";const t=s("#resend");t.length>0&&s.ajax({url:"/en/auth/should_link_be_visible",type:"GET",success:function(s){!0===s.display&&t.show()}});t.click((()=>{s.ajax({url:t.data("path"),type:"POST",success:function(s){t.hide(),e.alert(s.message)}})}))}($,bootbox)},298:(s,e,t)=>{"use strict";t(64)}},s=>{var e;e=298,s(s.s=e)}]);
--------------------------------------------------------------------------------
/public/build/js/bottom-bar.04c1ac09.js:
--------------------------------------------------------------------------------
1 | (self.webpackChunk=self.webpackChunk||[]).push([[576],{68:()=>{!function(t){"use strict";const a=t("#phone"),e=t("#email");t("body").append(``)}(window.jQuery)}},t=>{var a;a=68,t(t.s=a)}]);
--------------------------------------------------------------------------------
/public/build/js/city.b1325671.js:
--------------------------------------------------------------------------------
1 | (self.webpackChunk=self.webpackChunk||[]).push([[768],{368:()=>{!function(t){"use strict";const o=t=>``,e=o=>{t.each(o,(function(o,e){t(e+" option").each((function(){""!==t(this).val()&&t(this).remove()}))}))};t("body").on("change","#property_city",(function(){e(["#property_district","#property_neighborhood","#property_metro_station"]);let n=t(this).val();const p="/en/city/"+n+".json";""!==n&&t.get(p).done((e=>{let{districts:n,neighborhoods:p,metro_stations:i}=e;n=n.map((t=>o(t))),p=p.map((t=>o(t))),i=i.map((t=>o(t))),t("#property_district").append(n),t("#property_neighborhood").append(p),t("#property_metro_station").append(i)}))}))}(window.jQuery)}},t=>{var o;o=368,t(t.s=o)}]);
--------------------------------------------------------------------------------
/public/build/js/ekko-lightbox.11ef94c0.js.LICENSE.txt:
--------------------------------------------------------------------------------
1 | /*!
2 | * Lightbox for Bootstrap by @ashleydw
3 | * https://github.com/ashleydw/lightbox
4 | *
5 | * License: https://github.com/ashleydw/lightbox/blob/master/LICENSE
6 | */
7 |
--------------------------------------------------------------------------------
/public/build/js/google_authenticator.5fceab80.js:
--------------------------------------------------------------------------------
1 | (self.webpackChunk=self.webpackChunk||[]).push([[616],{5:()=>{!function(e){"use strict";const t=e("#generate_google_auth_secret"),a=e('[name="generatedSecret"]'),n=e('[name="authentication_code"]');e("#setUpAuthenticatorButton").click((function(){!0===t.data("generate-new-secret")&&e.ajax({method:"GET",url:"/en/user/google_authenticator_code"}).done((function(t){const{secret:n,qr_code:o}=t,c=new Image;c.src=o,a.val(n),e("#generatedQrCode").html(c),e("#generatedSecret").html(n)}))})),e("#enable2fa").click((function(){let o=n.val().trim();o?e.ajax({method:"PUT",url:t.attr("action"),data:{secret:a.val(),authentication_code:o}}).done((function(){location.reload()})).fail((function(t){var a;a=t.responseJSON.message,e("#twoFactorAuthErrorMessage").text(a).removeClass("d-none")})):n.addClass("is-invalid").focus()})),e("#disable2fa").click((function(){e.ajax({method:"DELETE",url:t.attr("action")}).done((function(){location.reload()})).fail((function(){location.reload()}))})),n.keyup((function(){e(this).removeClass("is-invalid")})),e("#setUpAuthenticator").on("hidden.bs.modal",(function(){n.val("").removeClass("is-invalid"),e("#twoFactorAuthErrorMessage").text("").addClass("d-none")}))}(window.jQuery)}},e=>{var t;t=5,e(e.s=t)}]);
--------------------------------------------------------------------------------
/public/build/js/map.7d2feb0e.js:
--------------------------------------------------------------------------------
1 | (self.webpackChunk=self.webpackChunk||[]).push([[997],{45:()=>{ymaps.ready((function(){let t=new ymaps.Map("map",{center:[a,e],zoom:13}),p=new ymaps.Placemark([a,e],{hintContent:n,balloonContent:o},{preset:"islands#blueHomeIcon"});t.geoObjects.add(p)}));const t=$("#map"),a=t.data("latitude"),e=t.data("longitude"),n=t.attr("data-hintContent"),o=t.attr("data-balloonContent");t.css({width:"100%",height:"280px","padding-top":"20px"})}},t=>{var a;a=45,t(t.s=a)}]);
--------------------------------------------------------------------------------
/public/build/js/menu-sorting.287ae70d.js:
--------------------------------------------------------------------------------
1 | "use strict";(self.webpackChunk=self.webpackChunk||[]).push([[843],{521:()=>{const s=()=>{const s=$(".js-move");if(s.length>1){let e=[];s.each((function(){e.push(parseInt($(this).attr("id"),10))})),$.ajax({method:"POST",url:"/en/admin/menu/sort",data:{items:e}})}};$(document).ready((function(){$("body").on("click",".js-move",(function(){let e=$(this).parents("tr:first");$(this).is(".js-up-one")?e.insertBefore(e.prev()):e.insertAfter(e.next()),$(".js-down-one").removeClass("js-down-one").addClass("js-up-one").html(' Up one'),$(".js-move:first").removeClass("js-up-one").addClass("js-down-one").html(' Down one'),s()}))}))}},s=>{var e;e=521,s(s.s=e)}]);
--------------------------------------------------------------------------------
/public/build/js/page.3f48afaa.js:
--------------------------------------------------------------------------------
1 | "use strict";(self.webpackChunk=self.webpackChunk||[]).push([[948],{436:()=>{$(document).ready((function(){let e=$("#page_add_contact_form"),c=$("#email-address"),d=$("#page_contact_email_address");"checked"===e.attr("checked")&&(c.slideDown(),d.prop("required",!0)),e.on("change",(function(){e.is(":checked")?(c.slideDown(),d.focus().prop("required",!0)):(c.slideUp(),d.prop("required",!1))}))}))}},e=>{var c;c=436,e(e.s=c)}]);
--------------------------------------------------------------------------------
/public/build/js/select2.98bad6eb.js.LICENSE.txt:
--------------------------------------------------------------------------------
1 | /*!
2 | * jQuery JavaScript Library v3.7.1
3 | * https://jquery.com/
4 | *
5 | * Copyright OpenJS Foundation and other contributors
6 | * Released under the MIT license
7 | * https://jquery.org/license
8 | *
9 | * Date: 2023-08-28T13:37Z
10 | */
11 |
12 | /*! Select2 4.1.0-rc.0 | https://github.com/select2/select2/blob/master/LICENSE.md */
13 |
--------------------------------------------------------------------------------
/public/build/js/user.3e9dfb9b.js:
--------------------------------------------------------------------------------
1 | (self.webpackChunk=self.webpackChunk||[]).push([[676],{506:()=>{!function(t,e){"use strict";t('[data-type="delete"]').click((function(a){a.preventDefault();const i=t(this).closest("form"),s=t(this).data("message"),n=t(this).data("confirmation-text"),c=t(this).data("cancellation-text");e.confirm({message:s,buttons:{cancel:{label:c,className:"btn-light"},confirm:{label:n,className:"btn-danger"}},callback:function(t){t&&i.submit()}})}))}($,bootbox)},559:()=>{!function(t){"use strict";t(".btn-outline-secondary").click((function(e){e.preventDefault(),t(this).addClass("disabled");let a=t(this).attr("href"),i=t(this).parent().parent().parent();i.css({opacity:"0.5"}),t.get(a).done((function(){i.fadeOut(),function(){let e=t(".js-counter"),a=e.text();a=Number.parseInt(a),a-=1,e.text(a)}()}))}))}($)},292:()=>{!function(t){"use strict";let e=window.location.href;-1!==e.indexOf("profile")?t(".list-group-item-action:eq(2)").addClass("active"):-1!==e.indexOf("unpublished")?t(".list-group-item-action:eq(1)").addClass("active"):-1!==e.indexOf("security")?t(".list-group-item-action:eq(3)").addClass("active"):t(".list-group-item-action:eq(0)").addClass("active")}(window.jQuery)},304:(t,e,a)=>{"use strict";a(292),a(559),a(506)}},t=>{var e;e=304,t(t.s=e)}]);
--------------------------------------------------------------------------------
/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Coderberg/ResidenceCMS/72ae486fb774f94143d91af695da4bbf2236e5fe/public/favicon.ico
--------------------------------------------------------------------------------
/public/images/bg-1.5.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Coderberg/ResidenceCMS/72ae486fb774f94143d91af695da4bbf2236e5fe/public/images/bg-1.5.jpg
--------------------------------------------------------------------------------
/public/images/bg.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Coderberg/ResidenceCMS/72ae486fb774f94143d91af695da4bbf2236e5fe/public/images/bg.jpg
--------------------------------------------------------------------------------
/public/images/icons/apple-touch-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Coderberg/ResidenceCMS/72ae486fb774f94143d91af695da4bbf2236e5fe/public/images/icons/apple-touch-icon.png
--------------------------------------------------------------------------------
/public/images/icons/chrome-touch-icon-192x192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Coderberg/ResidenceCMS/72ae486fb774f94143d91af695da4bbf2236e5fe/public/images/icons/chrome-touch-icon-192x192.png
--------------------------------------------------------------------------------
/public/images/icons/icon-128x128.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Coderberg/ResidenceCMS/72ae486fb774f94143d91af695da4bbf2236e5fe/public/images/icons/icon-128x128.png
--------------------------------------------------------------------------------
/public/images/icons/icon-144x144.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Coderberg/ResidenceCMS/72ae486fb774f94143d91af695da4bbf2236e5fe/public/images/icons/icon-144x144.png
--------------------------------------------------------------------------------
/public/images/icons/icon-152x152.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Coderberg/ResidenceCMS/72ae486fb774f94143d91af695da4bbf2236e5fe/public/images/icons/icon-152x152.png
--------------------------------------------------------------------------------
/public/images/icons/icon-192x192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Coderberg/ResidenceCMS/72ae486fb774f94143d91af695da4bbf2236e5fe/public/images/icons/icon-192x192.png
--------------------------------------------------------------------------------
/public/images/icons/icon-256x256.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Coderberg/ResidenceCMS/72ae486fb774f94143d91af695da4bbf2236e5fe/public/images/icons/icon-256x256.png
--------------------------------------------------------------------------------
/public/images/icons/icon-512x512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Coderberg/ResidenceCMS/72ae486fb774f94143d91af695da4bbf2236e5fe/public/images/icons/icon-512x512.png
--------------------------------------------------------------------------------
/public/images/languages/bg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Coderberg/ResidenceCMS/72ae486fb774f94143d91af695da4bbf2236e5fe/public/images/languages/bg.png
--------------------------------------------------------------------------------
/public/images/languages/en.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Coderberg/ResidenceCMS/72ae486fb774f94143d91af695da4bbf2236e5fe/public/images/languages/en.png
--------------------------------------------------------------------------------
/public/images/languages/hu.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Coderberg/ResidenceCMS/72ae486fb774f94143d91af695da4bbf2236e5fe/public/images/languages/hu.png
--------------------------------------------------------------------------------
/public/images/languages/nl.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Coderberg/ResidenceCMS/72ae486fb774f94143d91af695da4bbf2236e5fe/public/images/languages/nl.png
--------------------------------------------------------------------------------
/public/images/languages/ru.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Coderberg/ResidenceCMS/72ae486fb774f94143d91af695da4bbf2236e5fe/public/images/languages/ru.png
--------------------------------------------------------------------------------
/public/images/logo-square.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Coderberg/ResidenceCMS/72ae486fb774f94143d91af695da4bbf2236e5fe/public/images/logo-square.png
--------------------------------------------------------------------------------
/public/images/no-photo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Coderberg/ResidenceCMS/72ae486fb774f94143d91af695da4bbf2236e5fe/public/images/no-photo.png
--------------------------------------------------------------------------------
/public/images/residence-logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Coderberg/ResidenceCMS/72ae486fb774f94143d91af695da4bbf2236e5fe/public/images/residence-logo.png
--------------------------------------------------------------------------------
/public/images/transparent.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Coderberg/ResidenceCMS/72ae486fb774f94143d91af695da4bbf2236e5fe/public/images/transparent.png
--------------------------------------------------------------------------------
/public/index.php:
--------------------------------------------------------------------------------
1 | withPaths([
12 | __DIR__.'/src',
13 | __DIR__.'/tests',
14 | ])
15 | ->withSets([
16 | LevelSetList::UP_TO_PHP_82,
17 | SymfonySetList::SYMFONY_CODE_QUALITY,
18 | SetList::CODE_QUALITY,
19 | ]);
20 |
--------------------------------------------------------------------------------
/src/Controller/Admin/Settings/AbstractSettingsController.php:
--------------------------------------------------------------------------------
1 |
15 | */
16 | protected array $settings;
17 |
18 | public function __construct(
19 | protected SettingsRepository $repository,
20 | protected SettingsService $service,
21 | ) {
22 | $this->settings = $this->repository->findAllAsArray();
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/src/Controller/Admin/Settings/MainSettingsController.php:
--------------------------------------------------------------------------------
1 | createForm(MainSettingsType::class, $this->settings);
18 | $form->handleRequest($request);
19 | if ($form->isSubmitted() && $form->isValid()) {
20 | $this->service->updateSettings($form->getNormData());
21 |
22 | return $this->redirectToRoute('admin_settings');
23 | }
24 |
25 | return $this->render('admin/settings/main_settings.html.twig', [
26 | 'site' => $this->settings,
27 | 'form' => $form,
28 | ]);
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/src/Controller/Admin/Settings/MapSettingsController.php:
--------------------------------------------------------------------------------
1 | createForm(MapSettingsType::class, $this->settings);
18 | $form->handleRequest($request);
19 | if ($form->isSubmitted() && $form->isValid()) {
20 | $this->service->updateSettings($form->getNormData());
21 |
22 | return $this->redirectToRoute('admin_map_settings');
23 | }
24 |
25 | return $this->render('admin/settings/map_settings.html.twig', [
26 | 'site' => $this->settings,
27 | 'form' => $form,
28 | ]);
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/src/Controller/Ajax/Admin/MenuController.php:
--------------------------------------------------------------------------------
1 | getPayload()->all('items');
23 | $repository->reorderItems($items);
24 |
25 | return new JsonResponse(['status' => 'ok']);
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/src/Controller/Ajax/AjaxController.php:
--------------------------------------------------------------------------------
1 | update($request);
22 |
23 | return new JsonResponse([]);
24 | } catch (\Throwable $e) {
25 | return new JsonResponse([
26 | 'message' => $e->getMessage(),
27 | ], Response::HTTP_UNPROCESSABLE_ENTITY);
28 | }
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/src/Controller/Auth/AuthController.php:
--------------------------------------------------------------------------------
1 | 1], methods: ['GET'])]
17 | public function index(
18 | Request $request,
19 | #[MapEntity(mapping: ['slug' => 'slug'])] City $city,
20 | CityService $service): Response
21 | {
22 | $searchParams = $service->getSearchParams($request, $city);
23 | $properties = $service->getProperties($searchParams);
24 | $siteOptions = $service->decorateOptions($this->site($request), $city);
25 |
26 | return $this->render('property/index.html.twig',
27 | [
28 | 'site' => $siteOptions,
29 | 'properties' => $properties,
30 | 'searchParams' => $searchParams,
31 | ]
32 | );
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/src/Controller/Traits/MenuTrait.php:
--------------------------------------------------------------------------------
1 | doctrine = $doctrine;
18 | }
19 |
20 | protected function menu(Request $request): array
21 | {
22 | return [
23 | 'menu' => $this->doctrine->getRepository(Menu::class)
24 | ->findBy([
25 | 'locale' => $request->getLocale(),
26 | ], ['sort_order' => 'ASC']),
27 | ];
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/src/Controller/User/ProfileController.php:
--------------------------------------------------------------------------------
1 | getUser();
22 | $profile = $user->getProfile();
23 | $form = $this->createForm(ProfileType::class, $profile);
24 | $form->handleRequest($request);
25 |
26 | if ($form->isSubmitted() && $form->isValid()) {
27 | $entityManager->persist($profile);
28 | $entityManager->flush();
29 | $this->addFlash('success', 'message.updated');
30 | }
31 |
32 | return $this->render('user/profile/profile.html.twig', [
33 | 'site' => $this->site($request),
34 | 'form' => $form,
35 | ]);
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/src/Controller/User/SecurityController.php:
--------------------------------------------------------------------------------
1 | render('user/security/security.html.twig', [
18 | 'site' => $this->site($request),
19 | ]);
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/src/DataFixtures/CategoryFixtures.php:
--------------------------------------------------------------------------------
1 | getCategoryData() as [$slug, $name]) {
16 | $category = new Category();
17 | $category->setName($name);
18 | $category->setSlug($slug);
19 | $manager->persist($category);
20 | $this->addReference($name, $category);
21 | }
22 | $manager->flush();
23 | }
24 |
25 | private function getCategoryData(): array
26 | {
27 | return [
28 | // $categoryData = [$slug, $name];
29 | ['apartment', 'Apartment'],
30 | ['duplex', 'Duplex'],
31 | ['penthouse', 'Penthouse'],
32 | ['villa', 'Villa'],
33 | ];
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/src/DataFixtures/CityFixtures.php:
--------------------------------------------------------------------------------
1 | getCityData() as [$slug, $name, $title]) {
16 | $city = new City();
17 | $city->setName($name);
18 | $city->setSlug($slug);
19 | $city->setTitle($title);
20 | $city->setMetaTitle($title);
21 | $manager->persist($city);
22 | $this->addReference($name, $city);
23 | }
24 | $manager->flush();
25 | }
26 |
27 | private function getCityData(): array
28 | {
29 | return [
30 | // $cityData = [$slug, $name, $title];
31 | ['miami', 'Miami', 'Miami Luxury Real Estate'],
32 | ['palm-beach', 'Palm Beach', 'West Palm Beach, FL Apartments'],
33 | ['tampa', 'Tampa', 'Tampa Real Estate'],
34 | ];
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/src/DataFixtures/DealTypeFixtures.php:
--------------------------------------------------------------------------------
1 | getDealTypeData() as [$slug, $name]) {
16 | $dealType = new DealType();
17 | $dealType->setName($name);
18 | $dealType->setSlug($slug);
19 | $manager->persist($dealType);
20 | $this->addReference($name, $dealType);
21 | }
22 | $manager->flush();
23 | }
24 |
25 | private function getDealTypeData(): array
26 | {
27 | return [
28 | ['rent', 'Rent'],
29 | ['sale', 'Sale'],
30 | ];
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/src/DataFixtures/DistrictFixtures.php:
--------------------------------------------------------------------------------
1 | getDistrictData() as [$city, $name, $slug]) {
18 | $district = new District();
19 | $district->setCity($city);
20 | $district->setName($name);
21 | $district->setSlug($slug);
22 | $manager->persist($district);
23 | $this->addReference($name, $district);
24 | }
25 | $manager->flush();
26 | }
27 |
28 | private function getDistrictData(): array
29 | {
30 | return [
31 | [$this->getReference('Tampa', City::class), 'South Tampa', 'south-tampa'],
32 | ];
33 | }
34 |
35 | public function getDependencies(): array
36 | {
37 | return [
38 | CityFixtures::class,
39 | ];
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/src/DataFixtures/FeatureFixtures.php:
--------------------------------------------------------------------------------
1 | getFeatureData() as [$name, $icon]) {
16 | $feature = new Feature();
17 | $feature->setName($name);
18 | $feature->setIcon($icon);
19 | $manager->persist($feature);
20 | $this->addReference($name, $feature);
21 | }
22 | $manager->flush();
23 | }
24 |
25 | private function getFeatureData(): array
26 | {
27 | return [
28 | ['Air conditioning', null],
29 | ['Balcony', null],
30 | ['Elevator', null],
31 | ['Fire Alarm', null],
32 | ['First Floor Entry', null],
33 | ['High Impact Doors', null],
34 | ['Patio', null],
35 | ['Secure parking', ''],
36 | ];
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/src/DataFixtures/MenuFixtures.php:
--------------------------------------------------------------------------------
1 | getMenuData() as [$title, $url, $locale]) {
16 | $menu = new Menu();
17 | $menu->setTitle($title);
18 | $menu->setUrl($url);
19 | $menu->setLocale($locale);
20 | $manager->persist($menu);
21 | $this->addReference($title, $menu);
22 | }
23 | $manager->flush();
24 | }
25 |
26 | private function getMenuData(): array
27 | {
28 | return [
29 | ['Homepage', '/', 'en'],
30 | ['About Us', '/info/about-us', 'en'],
31 | ['Contact', '/info/contact', 'en'],
32 | ['Начало', '/', 'bg'],
33 | ['За нас', '/info/about-us', 'bg'],
34 | ['Контакти', '/info/contact', 'bg'],
35 | ['Source Code', 'https://github.com/Coderberg/ResidenceCMS', 'en'],
36 | ];
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/src/Entity/Category.php:
--------------------------------------------------------------------------------
1 | setting_name;
28 | }
29 |
30 | public function setSettingName(string $setting_name): self
31 | {
32 | $this->setting_name = $setting_name;
33 |
34 | return $this;
35 | }
36 |
37 | public function getSettingValue(): ?string
38 | {
39 | return $this->setting_value;
40 | }
41 |
42 | public function setSettingValue(?string $setting_value): self
43 | {
44 | $this->setting_value = $setting_value;
45 |
46 | return $this;
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/src/Entity/Traits/CityTrait.php:
--------------------------------------------------------------------------------
1 | city;
19 | }
20 |
21 | public function setCity(?City $city): self
22 | {
23 | $this->city = $city;
24 |
25 | return $this;
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/src/Entity/Traits/EntityIdTrait.php:
--------------------------------------------------------------------------------
1 | id;
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/src/Entity/Traits/EntityMetaTrait.php:
--------------------------------------------------------------------------------
1 | meta_title;
21 | }
22 |
23 | public function setMetaTitle(?string $meta_title): self
24 | {
25 | $this->meta_title = $meta_title;
26 |
27 | return $this;
28 | }
29 |
30 | public function getMetaDescription(): ?string
31 | {
32 | return $this->meta_description;
33 | }
34 |
35 | public function setMetaDescription(?string $meta_description): self
36 | {
37 | $this->meta_description = $meta_description;
38 |
39 | return $this;
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/src/Entity/Traits/EntityNameTrait.php:
--------------------------------------------------------------------------------
1 | name;
23 | }
24 |
25 | public function setName(string $name): self
26 | {
27 | $this->name = $name;
28 |
29 | return $this;
30 | }
31 |
32 | public function getSlug(): ?string
33 | {
34 | return $this->slug;
35 | }
36 |
37 | public function setSlug(string $slug): self
38 | {
39 | $this->slug = $slug;
40 |
41 | return $this;
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/src/Entity/Traits/EntityTimestampableTrait.php:
--------------------------------------------------------------------------------
1 | 'CURRENT_TIMESTAMP'])]
13 | private ?\DateTimeInterface $createdAt = null;
14 |
15 | #[ORM\Column(type: Types::DATETIME_MUTABLE, nullable: true, options: ['default' => 'CURRENT_TIMESTAMP'])]
16 | private ?\DateTimeInterface $updatedAt = null;
17 |
18 | public function getCreatedAt(): ?\DateTimeInterface
19 | {
20 | return $this->createdAt;
21 | }
22 |
23 | public function setCreatedAt(?\DateTimeInterface $createdAt): self
24 | {
25 | $this->createdAt = $createdAt;
26 |
27 | return $this;
28 | }
29 |
30 | public function getUpdatedAt(): ?\DateTimeInterface
31 | {
32 | return $this->updatedAt;
33 | }
34 |
35 | public function setUpdatedAt(?\DateTimeInterface $updatedAt): self
36 | {
37 | $this->updatedAt = $updatedAt;
38 |
39 | return $this;
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/src/Entity/Traits/TwoFactorTrait.php:
--------------------------------------------------------------------------------
1 | googleAuthenticatorSecret;
18 | }
19 |
20 | public function getGoogleAuthenticatorUsername(): string
21 | {
22 | return $this->username;
23 | }
24 |
25 | public function getGoogleAuthenticatorSecret(): ?string
26 | {
27 | return $this->googleAuthenticatorSecret;
28 | }
29 |
30 | public function setGoogleAuthenticatorSecret(?string $googleAuthenticatorSecret): void
31 | {
32 | $this->googleAuthenticatorSecret = $googleAuthenticatorSecret;
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/src/EventListener/ExceptionListener.php:
--------------------------------------------------------------------------------
1 | getThrowable();
16 | if ($exception instanceof TokenNotFoundException) {
17 | $customResponse = new JsonResponse([
18 | 'status' => 'fail', 'message' => $exception->getMessage(),
19 | ], 419);
20 | $event->setResponse($customResponse);
21 | }
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/src/Form/Type/CategoryType.php:
--------------------------------------------------------------------------------
1 | add('name', null, [
27 | 'attr' => [
28 | 'autofocus' => true,
29 | ],
30 | 'label' => 'label.name',
31 | ])
32 | ->add('slug', null, [
33 | 'label' => 'label.slug',
34 | ]);
35 | }
36 |
37 | /**
38 | * {@inheritdoc}
39 | */
40 | public function configureOptions(OptionsResolver $resolver): void
41 | {
42 | $resolver->setDefaults([
43 | 'data_class' => Category::class,
44 | ]);
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/src/Form/Type/DistrictType.php:
--------------------------------------------------------------------------------
1 | add('city', EntityType::class, [
23 | 'class' => City::class,
24 | 'choice_label' => 'name',
25 | 'label' => 'city',
26 | ])
27 | ->add('name', null, [
28 | 'label' => 'label.district_name',
29 | ])
30 | ->add('slug', null, [
31 | 'label' => 'label.slug',
32 | ]);
33 | }
34 |
35 | /**
36 | * {@inheritdoc}
37 | */
38 | public function configureOptions(OptionsResolver $resolver): void
39 | {
40 | $resolver->setDefaults([
41 | 'data_class' => District::class,
42 | ]);
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/src/Form/Type/FeatureType.php:
--------------------------------------------------------------------------------
1 | add('name', null, [
21 | 'attr' => [
22 | 'autofocus' => true,
23 | ],
24 | 'label' => 'label.feature',
25 | ])
26 | ->add('icon', null, [
27 | 'attr' => [
28 | 'rows' => '1',
29 | 'placeholder' => 'placeholder.example_icon',
30 | ],
31 | 'label' => 'label.custom_icon',
32 | ]);
33 | }
34 |
35 | /**
36 | * {@inheritdoc}
37 | */
38 | public function configureOptions(OptionsResolver $resolver): void
39 | {
40 | $resolver->setDefaults([
41 | 'data_class' => Feature::class,
42 | ]);
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/src/Form/Type/LanguageType.php:
--------------------------------------------------------------------------------
1 | setDefaults([
16 | 'attr' => [
17 | 'class' => 'form-control',
18 | ],
19 | 'choice_loader' => null,
20 | 'choices' => [
21 | 'Select language' => '',
22 | 'English' => 'en',
23 | 'Nederlands' => 'nl',
24 | 'Български' => 'bg',
25 | 'Русский' => 'ru',
26 | 'Magyar' => 'hu',
27 | ],
28 | 'label' => 'label.locale',
29 | ]);
30 | }
31 |
32 | public function getParent(): string
33 | {
34 | return LocaleType::class;
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/src/Form/Type/MetroType.php:
--------------------------------------------------------------------------------
1 | add('city', EntityType::class, [
23 | 'class' => City::class,
24 | 'choice_label' => 'name',
25 | 'label' => 'city',
26 | ])
27 | ->add('name', null, [
28 | 'label' => 'label.metro_station_name',
29 | ])
30 | ->add('slug', null, [
31 | 'label' => 'label.slug',
32 | ]);
33 | }
34 |
35 | /**
36 | * {@inheritdoc}
37 | */
38 | public function configureOptions(OptionsResolver $resolver): void
39 | {
40 | $resolver->setDefaults([
41 | 'data_class' => Metro::class,
42 | ]);
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/src/Form/Type/NeighborhoodType.php:
--------------------------------------------------------------------------------
1 | add('city', EntityType::class, [
23 | 'class' => City::class,
24 | 'choice_label' => 'name',
25 | 'label' => 'city',
26 | ])
27 | ->add('name', null, [
28 | 'label' => 'label.neighborhood_name',
29 | ])
30 | ->add('slug', null, [
31 | 'label' => 'label.slug',
32 | ]);
33 | }
34 |
35 | /**
36 | * {@inheritdoc}
37 | */
38 | public function configureOptions(OptionsResolver $resolver): void
39 | {
40 | $resolver->setDefaults([
41 | 'data_class' => Neighborhood::class,
42 | ]);
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/src/Form/Type/PasswordType.php:
--------------------------------------------------------------------------------
1 | add('password', null, [
22 | 'attr' => [
23 | 'autofocus' => true,
24 | ],
25 | 'label' => 'label.new_password',
26 | 'constraints' => [new Length(['min' => 5])],
27 | ])
28 | ->add('password_confirmation', null, [
29 | 'label' => 'label.confirm_password',
30 | 'constraints' => [new Length(['min' => 5]), new ConfirmPassword()],
31 | ]);
32 | }
33 |
34 | /**
35 | * {@inheritdoc}
36 | */
37 | public function configureOptions(OptionsResolver $resolver): void
38 | {
39 | $resolver->setDefaults([]);
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/src/Form/Type/UserEmailType.php:
--------------------------------------------------------------------------------
1 | add('email', EmailType::class, [
23 | 'attr' => [
24 | 'placeholder' => 'placeholder.enter_email',
25 | ],
26 | 'label' => 'label.email',
27 | 'constraints' => [new Length(['min' => 5]), new RegisteredUser()],
28 | ]);
29 | }
30 |
31 | /**
32 | * {@inheritdoc}
33 | */
34 | public function configureOptions(OptionsResolver $resolver): void
35 | {
36 | $resolver->setDefaults([]);
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/src/Kernel.php:
--------------------------------------------------------------------------------
1 | mailer->send($email);
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/src/Message/DeletePhotos.php:
--------------------------------------------------------------------------------
1 | property;
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/src/Message/SendEmailConfirmationLink.php:
--------------------------------------------------------------------------------
1 | user;
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/src/Message/SendFeedback.php:
--------------------------------------------------------------------------------
1 | feedback;
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/src/Message/SendResetPasswordLink.php:
--------------------------------------------------------------------------------
1 | user;
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/src/MessageHandler/DeletePhotosHandler.php:
--------------------------------------------------------------------------------
1 | getProperty()->getPhotos();
21 |
22 | foreach ($photos as $photo) {
23 | $this->fileUploader->remove($photo->getPhoto());
24 | }
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/src/MessageHandler/SendFeedbackHandler.php:
--------------------------------------------------------------------------------
1 | getFeedback();
24 |
25 | $subject = $this->translator->trans('email.new_message');
26 |
27 | $email = (new Email())
28 | ->from(new Address($feedback->getFromEmail(), $feedback->getFromName()))
29 | ->to($feedback->getToEmail())
30 | ->replyTo($feedback->getFromEmail())
31 | ->subject($subject)
32 | ->text($feedback->getMessage())
33 | ->html($feedback->getMessage());
34 |
35 | $this->mailer->send($email);
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/src/Middleware/ThrottleRequests.php:
--------------------------------------------------------------------------------
1 | authLimiter->create(
20 | $request->getClientIp().$request->getPathInfo().$request->getMethod()
21 | );
22 |
23 | if (!$limiter->consume(1)->isAccepted()) {
24 | throw new TooManyRequestsHttpException();
25 | }
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/src/Middleware/VerifyCsrfToken.php:
--------------------------------------------------------------------------------
1 | isCsrfTokenValid($this->getToken($request))) {
21 | throw new TokenNotFoundException('Sorry, your session has expired. Please refresh and try again.');
22 | }
23 | }
24 |
25 | private function isCsrfTokenValid(?string $token): bool
26 | {
27 | return $this->tokenManager->isTokenValid(new CsrfToken('csrf_token', $token));
28 | }
29 |
30 | private function getToken(Request $request)
31 | {
32 | return $request->headers->get('x-csrf-token')
33 | ?? $request->get('csrf_token');
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/src/Repository/CategoryRepository.php:
--------------------------------------------------------------------------------
1 | createQueryBuilder('c')
33 | ->select('count(c.id)')
34 | ->getQuery()
35 | ->getSingleScalarResult();
36 |
37 | return (int) $count;
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/src/Repository/CityRepository.php:
--------------------------------------------------------------------------------
1 | createQueryBuilder('l')
33 | ->select('count(l.id)')
34 | ->getQuery()
35 | ->getSingleScalarResult();
36 |
37 | return (int) $count;
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/src/Repository/CurrencyRepository.php:
--------------------------------------------------------------------------------
1 | createQueryBuilder('o')
33 | ->select('count(o.id)')
34 | ->getQuery()
35 | ->getSingleScalarResult();
36 |
37 | return (int) $count;
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/src/Repository/DistrictRepository.php:
--------------------------------------------------------------------------------
1 | setPassword($plainPassword);
21 | $user->setConfirmationToken(null);
22 | $user->setPasswordRequestedAt(null);
23 | $user = $this->transformer->transform($user);
24 | $this->save($user);
25 | }
26 |
27 | public function setToken(User $user, string $token): void
28 | {
29 | $user->setConfirmationToken($token);
30 | $user->setPasswordRequestedAt(new \DateTime());
31 | $this->save($user);
32 | }
33 |
34 | private function save(User $user): void
35 | {
36 | $em = $this->getEntityManager();
37 | $em->persist($user);
38 | $em->flush();
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/src/Repository/UserPropertyRepository.php:
--------------------------------------------------------------------------------
1 | createQueryBuilder('p')
15 | ->where('p.author = :id');
16 |
17 | if ('published' === $params['state']) {
18 | $qb->andWhere("p.state = 'published'");
19 | } else {
20 | $qb->andWhere("p.state != 'published'");
21 | }
22 |
23 | $qb->orderBy('p.id', 'DESC')
24 | ->setParameter('id', $params['user']);
25 |
26 | return $this->createPaginator($qb->getQuery(), $params['page']);
27 | }
28 |
29 | public function changeState(Property $property, string $state): bool
30 | {
31 | try {
32 | $property->setState($state);
33 | $em = $this->getEntityManager();
34 | $em->persist($property);
35 | $em->flush();
36 |
37 | return true;
38 | } catch (\Throwable) {
39 | return false;
40 | }
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/src/Repository/UserRepository.php:
--------------------------------------------------------------------------------
1 | createQueryBuilder('u')
33 | ->select('count(u.id)')
34 | ->getQuery()
35 | ->getSingleScalarResult();
36 |
37 | return (int) $count;
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/src/Service/Admin/DashboardService.php:
--------------------------------------------------------------------------------
1 | getCount('properties_count', Property::class);
22 | }
23 |
24 | public function countCities(): int
25 | {
26 | return $this->getCount('cities_count', City::class);
27 | }
28 |
29 | public function countDealTypes(): int
30 | {
31 | return $this->getCount('deal_types_count', DealType::class);
32 | }
33 |
34 | public function countCategories(): int
35 | {
36 | return $this->getCount('categories_count', Category::class);
37 | }
38 |
39 | public function countPages(): int
40 | {
41 | return $this->getCount('pages_count', Page::class);
42 | }
43 |
44 | public function countUsers(): int
45 | {
46 | return $this->getCount('users_count', User::class);
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/src/Service/Auth/EmailVerifier.php:
--------------------------------------------------------------------------------
1 | verifyEmailHelper->validateEmailConfirmationFromRequest(
23 | request: $request,
24 | userId: (string) $user->getId(),
25 | userEmail: $user->getEmail()
26 | );
27 |
28 | $user->setEmailVerifiedAt(new \DateTime('now'));
29 |
30 | $this->entityManager->persist($user);
31 | $this->entityManager->flush();
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/src/Service/Cache/ClearCache.php:
--------------------------------------------------------------------------------
1 | delete($key);
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/src/Service/Cache/UserDataCache.php:
--------------------------------------------------------------------------------
1 | getKey($user);
19 | $cache = new FilesystemAdapter();
20 | $sentAt = $cache->getItem($key);
21 | $sentAt->set(new \DateTime('now'));
22 | $sentAt->expiresAfter(3600);
23 | $cache->save($sentAt);
24 | }
25 |
26 | /**
27 | * @throws InvalidArgumentException
28 | */
29 | public function getConfirmationSentAt(User $user): ?\DateTimeInterface
30 | {
31 | $key = $this->getKey($user);
32 | $cache = new FilesystemAdapter();
33 | $sentAt = $cache->getItem($key);
34 |
35 | return $sentAt->get();
36 | }
37 |
38 | private function getKey(User $user): string
39 | {
40 | return \sprintf('user.%s.email_confirmation_link.sent_at', $user->getId());
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/src/Service/User/GoogleAuthenticatorAdapter.php:
--------------------------------------------------------------------------------
1 | authenticator->checkCode($user, $code);
22 | }
23 |
24 | public function getQRContent(TwoFactorInterface $user): string
25 | {
26 | return str_replace(
27 | 'issuer_placeholder',
28 | ucfirst($this->requestStack->getCurrentRequest()->getHost()),
29 | $this->authenticator->getQRContent($user)
30 | );
31 | }
32 |
33 | public function generateSecret(): string
34 | {
35 | return $this->authenticator->generateSecret();
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/src/Transformer/PropertyTransformer.php:
--------------------------------------------------------------------------------
1 | transformContent($property, HtmlHelper::text2Html(...));
15 | }
16 |
17 | public function contentToPlainText(Property $property): Property
18 | {
19 | return $this->transformContent($property, HtmlHelper::html2Text(...));
20 | }
21 |
22 | public function removeScriptsFromHtml(Property $property): Property
23 | {
24 | return $this->transformContent($property, HtmlHelper::removeScriptsFromHtml(...));
25 | }
26 |
27 | private function transformContent(Property $property, callable $transformFunction): Property
28 | {
29 | $content = $property->getPropertyDescription()->getContent();
30 | $transformedContent = \call_user_func($transformFunction, $content);
31 | $property->setPropertyDescription(
32 | $property->getPropertyDescription()->setContent($transformedContent)
33 | );
34 |
35 | return $property;
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/src/Transformer/RequestToArrayTransformer.php:
--------------------------------------------------------------------------------
1 | $request->query->getInt('city'),
15 | 'deal_type' => $request->query->getInt('deal_type'),
16 | 'category' => $request->query->getInt('category'),
17 | 'bedrooms' => $request->query->getInt('bedrooms'),
18 | 'guests' => $request->query->getInt('guests'),
19 | 'feature' => $request->query->getInt('feature'),
20 | 'sort_by' => $request->query->get('sort_by', 'priority_number'),
21 | 'state' => $request->query->get('state', 'published'),
22 | 'page' => $request->query->getInt('page', 1),
23 | ];
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/src/Transformer/UserTransformer.php:
--------------------------------------------------------------------------------
1 | setRoles($user);
19 |
20 | return $this->setEncodedPassword($user);
21 | }
22 |
23 | private function setRoles(User $user): User
24 | {
25 | if (\in_array('ROLE_ADMIN', $user->getRoles(), true)) {
26 | $user->setRoles(['ROLE_ADMIN', 'ROLE_USER']);
27 | } else {
28 | $user->setRoles(['ROLE_USER']);
29 | }
30 |
31 | return $user;
32 | }
33 |
34 | private function setEncodedPassword(User $user): User
35 | {
36 | $password = $user->getPassword();
37 | $user->setPassword($this->passwordHasher->hashPassword($user, (string) $password));
38 |
39 | return $user;
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/src/Twig/AppExtension.php:
--------------------------------------------------------------------------------
1 | showPageNumber(...)),
21 | ];
22 | }
23 |
24 | public function showPageNumber($number = 1): string
25 | {
26 | return ($number > 1) ? ' - '.$this->translator->trans('page').' '.$number : '';
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/src/Utils/HtmlHelper.php:
--------------------------------------------------------------------------------
1 | #i', "\n", $html);
12 |
13 | return strip_tags((string) $text);
14 | }
15 |
16 | public static function text2Html(string $text): string
17 | {
18 | return preg_replace("/\r\n|\r|\n/", '
', $text);
19 | }
20 |
21 | public static function removeScriptsFromHtml(string $html): string
22 | {
23 | $sanitizedHtml = preg_replace('##is', '', $html);
24 | $sanitizedHtml = preg_replace('# on\w+="[^"]*"#i', '', (string) $sanitizedHtml);
25 |
26 | return preg_replace("# on\w+='[^']*'#i", '', (string) $sanitizedHtml);
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/src/Utils/Slugger.php:
--------------------------------------------------------------------------------
1 | slug($string)->lower();
26 |
27 | return (string) $slug;
28 | }
29 |
30 | private static function ascii($value, $language = 'en'): string
31 | {
32 | return ASCII::to_ascii((string) $value, $language);
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/src/Utils/SluggerInterface.php:
--------------------------------------------------------------------------------
1 | get('email_verified')->getNormData();
14 | }
15 |
16 | public function getEmailVerifiedAt(FormInterface $form): ?\DateTime
17 | {
18 | return $this->getEmailVerified($form)
19 | ? new \DateTime('now')
20 | : null;
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/src/Validator/ConfirmPassword.php:
--------------------------------------------------------------------------------
1 | context->getRoot()->get('password')->getData();
20 |
21 | if ($password !== $value) {
22 | $this->context->buildViolation($constraint->message)
23 | ->atPath('password_confirmation')
24 | ->addViolation();
25 | }
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/src/Validator/PhotoRequirements.php:
--------------------------------------------------------------------------------
1 | 'Please select a file to upload',
18 | ]),
19 | new File([
20 | 'maxSize' => '12M',
21 | 'mimeTypes' => [
22 | 'image/*',
23 | ],
24 | ]),
25 | ];
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/src/Validator/RegisteredUser.php:
--------------------------------------------------------------------------------
1 | userRepository->findOneBy(['email' => $value]);
26 |
27 | if (!$existingUser instanceof User) {
28 | $this->context->buildViolation($constraint->message)
29 | ->addViolation();
30 | }
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/templates/admin/category/_action_form.html.twig:
--------------------------------------------------------------------------------
1 |
12 |
--------------------------------------------------------------------------------
/templates/admin/category/edit.html.twig:
--------------------------------------------------------------------------------
1 | {% extends 'admin/layout/base.html.twig' %}
2 |
3 | {% block title %}{{ 'title.edit_category' | trans }}{% endblock %}
4 |
5 | {% block body %}
6 |
7 |
8 |
9 |
10 |
11 | {% form_theme form 'bootstrap_4_layout.html.twig' %}
12 |
13 | {{ form_start(form) }}
14 | {{ form_widget(form) }}
15 |
16 |
17 |
18 |
21 |
22 |
23 |
24 | {{ form_end(form) }}
25 |
26 |
27 |
28 |
29 | {% endblock %}
30 |
--------------------------------------------------------------------------------
/templates/admin/city/_action_form.html.twig:
--------------------------------------------------------------------------------
1 |
12 |
--------------------------------------------------------------------------------
/templates/admin/city/edit.html.twig:
--------------------------------------------------------------------------------
1 | {% extends 'admin/layout/base.html.twig' %}
2 |
3 | {% block title %}{{ 'title.edit_city' | trans }}{% endblock %}
4 |
5 | {% block body %}
6 |
7 |
8 |
9 |
10 |
11 | {% form_theme form 'bootstrap_4_layout.html.twig' %}
12 |
13 | {{ form_start(form) }}
14 | {{ form_widget(form) }}
15 |
16 |
17 |
18 |
21 |
22 |
23 |
24 | {{ form_end(form) }}
25 |
26 |
27 |
28 |
29 | {% endblock %}
30 |
31 | {% block javascripts %}{% endblock %}
32 |
--------------------------------------------------------------------------------
/templates/admin/currency/_action_form.html.twig:
--------------------------------------------------------------------------------
1 |
12 |
--------------------------------------------------------------------------------
/templates/admin/currency/edit.html.twig:
--------------------------------------------------------------------------------
1 | {% extends 'admin/layout/base.html.twig' %}
2 |
3 | {% block title %}{{ 'title.edit_currency' | trans }}{% endblock %}
4 |
5 | {% block body %}
6 |
7 |
8 |
9 |
10 |
11 | {% form_theme form 'bootstrap_4_layout.html.twig' %}
12 |
13 | {{ form_start(form) }}
14 | {{ form_widget(form) }}
15 |
16 |
17 |
18 |
21 |
22 |
23 |
24 | {{ form_end(form) }}
25 |
26 |
27 |
28 |
29 | {% endblock %}
30 |
--------------------------------------------------------------------------------
/templates/admin/deal_type/_action_form.html.twig:
--------------------------------------------------------------------------------
1 |
12 |
--------------------------------------------------------------------------------
/templates/admin/deal_type/edit.html.twig:
--------------------------------------------------------------------------------
1 | {% extends 'admin/layout/base.html.twig' %}
2 |
3 | {% block title %}{{ 'title.edit_deal_type' | trans }}{% endblock %}
4 |
5 | {% block body %}
6 |
7 |
8 |
9 |
10 |
11 | {% form_theme form 'bootstrap_4_layout.html.twig' %}
12 |
13 | {{ form_start(form) }}
14 | {{ form_widget(form) }}
15 |
16 |
17 |
18 |
21 |
22 |
23 |
24 | {{ form_end(form) }}
25 |
26 |
27 |
28 |
29 | {% endblock %}
30 |
--------------------------------------------------------------------------------
/templates/admin/district/_action_form.html.twig:
--------------------------------------------------------------------------------
1 |
12 |
--------------------------------------------------------------------------------
/templates/admin/district/edit.html.twig:
--------------------------------------------------------------------------------
1 | {% extends 'admin/layout/base.html.twig' %}
2 |
3 | {% block title %}{{ 'title.edit_district' | trans }}{% endblock %}
4 |
5 | {% block body %}
6 |
7 |
8 |
9 |
12 |
13 |
14 |
15 | {% form_theme form 'bootstrap_4_layout.html.twig' %}
16 |
17 | {{ form_start(form) }}
18 | {{ form_widget(form) }}
19 |
20 |
21 |
22 |
25 |
26 |
27 |
28 | {{ form_end(form) }}
29 |
30 |
31 |
32 |
33 | {% endblock %}
34 |
--------------------------------------------------------------------------------
/templates/admin/feature/_action_form.html.twig:
--------------------------------------------------------------------------------
1 |
12 |
--------------------------------------------------------------------------------
/templates/admin/feature/edit.html.twig:
--------------------------------------------------------------------------------
1 | {% extends 'admin/layout/base.html.twig' %}
2 |
3 | {% block title %}{{ 'title.edit_feature' | trans }}{% endblock %}
4 |
5 | {% block body %}
6 |
7 |
8 |
9 |
10 |
11 | {% form_theme form 'bootstrap_4_layout.html.twig' %}
12 |
13 | {{ form_start(form) }}
14 | {{ form_widget(form) }}
15 |
16 |
17 |
18 |
21 |
22 |
23 |
24 | {{ form_end(form) }}
25 |
26 |
27 |
28 |
29 | {% endblock %}
30 |
--------------------------------------------------------------------------------
/templates/admin/menu/_action_form.html.twig:
--------------------------------------------------------------------------------
1 |
12 |
--------------------------------------------------------------------------------
/templates/admin/metro/_action_form.html.twig:
--------------------------------------------------------------------------------
1 |
12 |
--------------------------------------------------------------------------------
/templates/admin/metro/edit.html.twig:
--------------------------------------------------------------------------------
1 | {% extends 'admin/layout/base.html.twig' %}
2 |
3 | {% block title %}{{ 'title.edit_metro_station' | trans }}{% endblock %}
4 |
5 | {% block body %}
6 |
7 |
8 |
9 |
10 |
11 | {% form_theme form 'bootstrap_4_layout.html.twig' %}
12 |
13 | {{ form_start(form) }}
14 | {{ form_widget(form) }}
15 |
16 |
17 |
18 |
21 |
22 |
23 |
24 | {{ form_end(form) }}
25 |
26 |
27 |
28 |
29 | {% endblock %}
30 |
--------------------------------------------------------------------------------
/templates/admin/neighborhood/_action_form.html.twig:
--------------------------------------------------------------------------------
1 |
12 |
--------------------------------------------------------------------------------
/templates/admin/neighborhood/edit.html.twig:
--------------------------------------------------------------------------------
1 | {% extends 'admin/layout/base.html.twig' %}
2 |
3 | {% block title %}{{ 'title.edit_neighborhood' | trans }}{% endblock %}
4 |
5 | {% block body %}
6 |
7 |
8 |
9 |
12 |
13 |
14 |
15 | {% form_theme form 'bootstrap_4_layout.html.twig' %}
16 |
17 | {{ form_start(form) }}
18 | {{ form_widget(form) }}
19 |
20 |
21 |
22 |
25 |
26 |
27 |
28 | {{ form_end(form) }}
29 |
30 |
31 |
32 |
33 | {% endblock %}
34 |
--------------------------------------------------------------------------------
/templates/admin/page/_action_form.html.twig:
--------------------------------------------------------------------------------
1 |
15 |
--------------------------------------------------------------------------------
/templates/admin/photo/_delete_form.html.twig:
--------------------------------------------------------------------------------
1 |
15 |
--------------------------------------------------------------------------------
/templates/admin/property/_action_form.html.twig:
--------------------------------------------------------------------------------
1 |
16 |
--------------------------------------------------------------------------------
/templates/admin/settings/partials/_filter_settings_form.html.twig:
--------------------------------------------------------------------------------
1 | {{ form_start(form) }}
2 |
3 |
4 |
5 |
6 | {{ form_row(form.show_filter_by_city) }}
7 |
8 |
9 |
10 | {{ form_row(form.show_filter_by_deal_type) }}
11 |
12 |
13 |
14 | {{ form_row(form.show_filter_by_category) }}
15 |
16 |
17 |
18 | {{ form_row(form.show_filter_by_bedrooms) }}
19 |
20 |
21 |
22 | {{ form_row(form.show_filter_by_guests) }}
23 |
24 |
25 |
26 | {{ form_row(form.show_filter_by_features) }}
27 |
28 |
29 |
30 |
31 |
34 |
35 |
36 | {{ form_end(form) }}
37 |
--------------------------------------------------------------------------------
/templates/admin/settings/partials/_nav_tabs.html.twig:
--------------------------------------------------------------------------------
1 | {% set currentPath = path(app.request.attributes.get('_route')) %}
2 | {% set mapClass = '' %}
3 | {% set headerClass = '' %}
4 | {% set mainClass = '' %}
5 |
6 | {% if '/map' in currentPath %}
7 | {% set mapClass = 'active' %}
8 | {% elseif '/header' in currentPath %}
9 | {% set headerClass = 'active' %}
10 | {% else %}
11 | {% set mainClass = 'active' %}
12 | {% endif %}
13 |
14 |
31 |
--------------------------------------------------------------------------------
/templates/admin/user/_action_form.html.twig:
--------------------------------------------------------------------------------
1 |
12 |
--------------------------------------------------------------------------------
/templates/admin/user/edit.html.twig:
--------------------------------------------------------------------------------
1 | {% extends 'admin/layout/base.html.twig' %}
2 |
3 | {% block title %}{{ 'title.edit_user' | trans }}{% endblock %}
4 |
5 | {% block body %}
6 |
7 |
8 |
9 |
10 |
11 | {% form_theme form 'bootstrap_4_layout.html.twig' %}
12 |
13 | {{ form_start(form) }}
14 | {{ form_row(form.roles) }}
15 | {{ form_row(form.profile.full_name) }}
16 | {{ form_row(form.username) }}
17 | {{ form_row(form.profile.phone) }}
18 | {{ form_row(form.email) }}
19 | {{ form_row(form.email_verified) }}
20 | {{ form_row(form.password) }}
21 |
22 |
23 |
24 |
27 |
28 |
29 |
30 | {{ form_end(form) }}
31 |
32 |
33 |
34 |
35 | {% endblock %}
36 |
--------------------------------------------------------------------------------
/templates/auth/passwords/password_change.html.twig:
--------------------------------------------------------------------------------
1 | {% extends 'layout/base.html.twig' %}
2 |
3 | {% block title %}{{ 'title.set_new_pass' | trans }}{% endblock %}
4 |
5 | {% block body %}
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 | {% form_theme form 'bootstrap_4_layout.html.twig' %}
15 |
16 | {{ form_start(form) }}
17 | {{ form_row(form.password) }}
18 | {{ form_row(form.password_confirmation) }}
19 |
20 |
27 |
28 | {{ form_end(form) }}
29 |
30 |
31 |
32 |
33 |
34 |
35 | {% endblock %}
36 |
--------------------------------------------------------------------------------
/templates/auth/passwords/password_reset.html.twig:
--------------------------------------------------------------------------------
1 | {% extends 'layout/base.html.twig' %}
2 |
3 | {% block title %}{{ 'title.reset_password' | trans }}{% endblock %}
4 |
5 | {% block body %}
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 | {% form_theme form 'bootstrap_4_layout.html.twig' %}
14 | {{ form_start(form) }}
15 | {{ form_widget(form) }}
16 |
17 |
18 |
21 |
22 |
23 | {{ form_end(form) }}
24 |
25 |
26 |
27 |
28 |
29 | {% endblock %}
30 |
--------------------------------------------------------------------------------
/templates/bundles/TwigBundle/Exception/error404.html.twig:
--------------------------------------------------------------------------------
1 | {% extends "layout/base.html.twig" %}
2 |
3 | {% block title %}404 Not Found{% endblock %}
4 |
5 | {% block stylesheets %}
6 |
7 |
12 |
13 | {% endblock %}
14 |
15 | {% block body %}
16 |
17 |
18 |
404
19 |
page not found
20 |
Go to Homepage
21 |
22 |
23 | {% endblock %}
24 |
--------------------------------------------------------------------------------
/templates/bundles/TwigBundle/Exception/error429.html.twig:
--------------------------------------------------------------------------------
1 | {% extends "layout/base.html.twig" %}
2 |
3 | {% block title %}429 Too Many Requests{% endblock %}
4 |
5 | {% block stylesheets %}
6 |
7 |
12 |
13 | {% endblock %}
14 |
15 | {% block body %}
16 |
17 |
18 |
429
19 |
Too Many Requests
20 |
Go to Homepage
21 |
22 |
23 | {% endblock %}
24 |
--------------------------------------------------------------------------------
/templates/common/_delete_button.html.twig:
--------------------------------------------------------------------------------
1 |
9 |
--------------------------------------------------------------------------------
/templates/common/_flash_messages.html.twig:
--------------------------------------------------------------------------------
1 | {% for type, messages in app.flashes %}
2 | {% for message in messages %}
3 | {# Bootstrap alert, see https://getbootstrap.com/docs/4.4/components/alerts/ #}
4 |
5 |
8 |
9 | {{ message|trans }}
10 |
11 | {% endfor %}
12 | {% endfor %}
13 |
14 | {% if app.user %}
15 | {% if not app.user.isVerified %}
16 |
24 | {% endif %}
25 | {% endif %}
26 |
--------------------------------------------------------------------------------
/templates/emails/confirmation_email.html.twig:
--------------------------------------------------------------------------------
1 | {% set expiresAt = expiresAtMessageKey | trans(expiresAtMessageData, 'VerifyEmailBundle') %}
2 |
3 | {{
4 | 'confirmation.email.message' | trans({
5 | '%signedUrl%': signedUrl,
6 | '%expiresAt%': expiresAt
7 | }) | raw
8 | }}
9 |
--------------------------------------------------------------------------------
/templates/emails/reset.txt.twig:
--------------------------------------------------------------------------------
1 | {{
2 | 'resetting.email.message' | trans({
3 | '%username%': username,
4 | '%confirmationUrl%': confirmationUrl
5 | })
6 | }}
7 |
--------------------------------------------------------------------------------
/templates/page/partials/_contact_form.html.twig:
--------------------------------------------------------------------------------
1 | {% form_theme form 'bootstrap_4_layout.html.twig' %}
2 |
3 | {{ form_start(form) }}
4 |
5 | {{ form_widget(form) }}
6 |
7 |
10 |
11 | {{ form_end(form) }}
12 |
13 |
14 |
--------------------------------------------------------------------------------
/templates/sitemap/cities.xml.twig:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | {% for city in cities %}
7 |
8 | {{ url('city', {slug: city.slug}) }}
9 | daily
10 | 0.5
11 |
12 | {% endfor %}
13 |
14 |
15 |
--------------------------------------------------------------------------------
/templates/sitemap/properties.xml.twig:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | {% for property in properties %}
7 |
8 |
9 | {{ url('property_show', {
10 | 'id': property.id,
11 | 'citySlug': property.city.slug,
12 | 'slug': property.slug
13 | }) }}
14 |
15 | {{ property.updatedAt|date('Y-m-d\\TH:i:s+00:00') }}
16 | 0.5
17 |
18 | {% endfor %}
19 |
20 |
21 |
--------------------------------------------------------------------------------
/templates/sitemap/sitemap.xml.twig:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | {{ url('cities_sitemap') }}
5 | daily
6 |
7 |
8 | {{ url('properties_sitemap') }}
9 | daily
10 |
11 |
12 |
--------------------------------------------------------------------------------
/templates/user/common/_floating_action_button.html.twig:
--------------------------------------------------------------------------------
1 | {% if is_granted('ROLE_ADMIN') %}
2 |
3 |
4 |
5 |
6 |
7 | {% elseif app.user.isVerified %}
8 |
9 |
10 |
11 |
12 |
13 | {% endif %}
14 |
--------------------------------------------------------------------------------
/templates/user/common/_sidebar.html.twig:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
{{ 'title.menu'|trans }}
5 |
6 |
7 |
8 |
25 |
26 |
--------------------------------------------------------------------------------
/templates/user/photo/_delete_form.html.twig:
--------------------------------------------------------------------------------
1 |
15 |
--------------------------------------------------------------------------------
/templates/user/property/index.html.twig:
--------------------------------------------------------------------------------
1 | {% extends 'layout/base.html.twig' %}
2 |
3 | {% block title %}{{ 'title.my_properties'|trans }}{% endblock %}
4 |
5 | {% block body %}
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
{{ 'title.my_properties'|trans }} ({{ properties.getTotalItemCount }})
15 |
16 |
17 |
18 |
19 | {{ include('user/property/partials/_properties.html.twig') }}
20 |
21 |
22 | {{ include('user/common/_sidebar.html.twig') }}
23 |
24 |
25 |
26 | {{ include('user/common/_floating_action_button.html.twig') }}
27 |
28 | {{ knp_pagination_render(properties) }}
29 |
30 | {% endblock %}
31 |
32 | {% block javascripts %}
33 |
34 | {{ encore_entry_script_tags('js/user') }}
35 |
36 | {% endblock %}
37 |
--------------------------------------------------------------------------------
/tests/E2E/HomepageTest.php:
--------------------------------------------------------------------------------
1 | request('GET', '/');
17 | $this->assertSelectorTextContains('h1', 'Popular Listing');
18 | $this->assertPageTitleSame('Site Title');
19 | $this->assertCount(6, $crawler->filter('.card-title'));
20 |
21 | // Page 2
22 | $crawler = $client->request('GET', '/en/?page=2');
23 | $this->assertPageTitleSame('Site Title - Page 2');
24 | $this->assertCount(1, $crawler->filter('.card-title'));
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/tests/Functional/Controller/Admin/AbstractLocationControllerTest.php:
--------------------------------------------------------------------------------
1 | client = $this->authAsAdmin($this);
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/tests/Functional/Controller/Admin/DashboardControllerTest.php:
--------------------------------------------------------------------------------
1 | authAsAdmin($this);
18 | $client->request(Request::METHOD_GET, '/en/admin');
19 | $this->assertResponseIsSuccessful(\sprintf('The %s public URL loads correctly.', '/admin'));
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/tests/Functional/Controller/SitemapControllerTest.php:
--------------------------------------------------------------------------------
1 | request(Request::METHOD_GET, '/en/sitemap.xml');
18 | $this->assertResponseHeaderSame('Content-Type', self::CONTENT_TYPE);
19 | }
20 |
21 | public function testCitiesSitemap(): void
22 | {
23 | $client = self::createClient();
24 | $client->request(Request::METHOD_GET, '/en/sitemap/cities.xml');
25 | $this->assertResponseHeaderSame('Content-Type', self::CONTENT_TYPE);
26 | }
27 |
28 | public function testPropertiesSitemap(): void
29 | {
30 | $client = self::createClient();
31 | $client->request(Request::METHOD_GET, '/en/sitemap/properties.xml');
32 | $this->assertResponseHeaderSame('Content-Type', self::CONTENT_TYPE);
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/tests/Helper/PantherTestHelper.php:
--------------------------------------------------------------------------------
1 | request('GET', '/en/login');
15 | $form = $crawler->selectButton('Sign in')->form([
16 | 'login_form[username]' => $username,
17 | 'login_form[password]' => $password,
18 | ]);
19 |
20 | return $client->submit($form);
21 | }
22 |
23 | public function logout(PantherClient $client): void
24 | {
25 | $client->request('GET', '/en/logout');
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/tests/Integration/Command/ListUsersCommandTest.php:
--------------------------------------------------------------------------------
1 | find('app:list-users');
18 | $commandTester = new CommandTester($command);
19 | $commandTester->execute([]);
20 |
21 | // the output of the command in the console
22 | $output = $commandTester->getDisplay();
23 | $this->assertStringContainsString('Rhonda Jordan', $output);
24 | $this->assertStringContainsString('John Smith', $output);
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/tests/Integration/Transformer/RequestToArrayTransformerTest.php:
--------------------------------------------------------------------------------
1 | query->set('city', 3);
17 | $request->query->set('deal_type', 2);
18 | $request->query->set('category', 4);
19 | $request->query->set('bedrooms', 5);
20 | $request->query->set('page', 2);
21 |
22 | $transformer = new RequestToArrayTransformer();
23 |
24 | $array = $transformer->transform($request);
25 |
26 | $this->assertSame($array['city'], 3);
27 | $this->assertSame($array['deal_type'], 2);
28 | $this->assertSame($array['category'], 4);
29 | $this->assertSame($array['bedrooms'], 5);
30 | $this->assertSame($array['page'], 2);
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/tests/Unit/Utils/SluggerTest.php:
--------------------------------------------------------------------------------
1 | assertSame($slugIntl, Slugger::slugify($string));
25 | } else {
26 | $this->assertSame($slug, Slugger::slugify($string));
27 | }
28 | }
29 |
30 | private function getSlugs(): \Generator
31 | {
32 | yield ['Lorem Ipsum', 'lorem-ipsum', 'lorem-ipsum'];
33 | yield ['Lorem Ipsum!', 'lorem-ipsum', 'lorem-ipsum'];
34 | yield ['Русский текст', 'russkii-tekst', 'russkij-tekst'];
35 | yield [' Русский текст !!!', 'russkii-tekst', 'russkij-tekst'];
36 | yield ['Lorem Ipsum №69!', 'lorem-ipsum-69', 'lorem-ipsum-no69'];
37 | yield ['Magyar nyelvű szöveg', 'magyar-nyelvu-szoveg', 'magyar-nyelvu-szoveg'];
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/tests/bootstrap.php:
--------------------------------------------------------------------------------
1 | bootEnv(dirname(__DIR__).'/.env');
11 | }
12 |
13 | if ($_SERVER['APP_DEBUG']) {
14 | umask(0o000);
15 | }
16 |
17 | if (isset($_ENV['BOOTSTRAP_CLEAR_CACHE_ENV'])) {
18 | // executes the "php bin/console cache:clear" command
19 | passthru(sprintf(
20 | 'APP_ENV=%s php "%s/../bin/console" cache:clear --no-warmup',
21 | $_ENV['BOOTSTRAP_CLEAR_CACHE_ENV'],
22 | __DIR__
23 | ));
24 | }
25 |
--------------------------------------------------------------------------------
/translations/validators.en.xlf:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | password.mismatch
7 | The entered passwords don't match.
8 |
9 |
10 | agree_terms
11 | You should agree to our terms.
12 |
13 |
14 | user_not_found
15 | We can't find a user with that e-mail address.
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/translations/validators.hu.xlf:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | password.mismatch
7 | A megadott jelszavak nem egyeznek meg.
8 |
9 |
10 | agree_terms
11 | El kell fogadnod az általános feltételeinket.
12 |
13 |
14 | user_not_found
15 | Nem találunk felhasználót ezzel az e-mail címmel.
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/translations/validators.ru.xlf:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | password.mismatch
7 | Введённые пароли не совпадают.
8 |
9 |
10 | agree_terms
11 | Вы должны согласиться с нашими условиями.
12 |
13 |
14 | user_not_found
15 | Не удаётся найти пользователя с таким адресом e-mail.
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------