Repository: Laravel-Backpack/demo Branch: main Commit: 0e78adfbf221 Files: 412 Total size: 902.5 KB Directory structure: gitextract_prmjevic/ ├── .gitattributes ├── .github/ │ ├── config.yml │ ├── dependabot.yml │ ├── issue_template.md │ ├── pull_request_template.md │ ├── stale.yml │ ├── support.yml │ └── workflows/ │ └── add-to-project.yml ├── .gitignore ├── .travis.yml ├── Dockerfile ├── LICENSE.md ├── app/ │ ├── Console/ │ │ ├── Commands/ │ │ │ ├── Inspire.php │ │ │ └── RefreshDb.php │ │ └── Kernel.php │ ├── Enums/ │ │ ├── MonsterStatus.php │ │ ├── ProductCondition.php │ │ └── ProductStatus.php │ ├── Events/ │ │ └── Event.php │ ├── Exceptions/ │ │ └── Handler.php │ ├── Http/ │ │ ├── Controllers/ │ │ │ ├── Admin/ │ │ │ │ ├── AdminPageController.php │ │ │ │ ├── CaveCrudController.php │ │ │ │ ├── Charts/ │ │ │ │ │ ├── LatestUsersChartController.php │ │ │ │ │ ├── Lines/ │ │ │ │ │ │ ├── ChartjsLineChartController.php │ │ │ │ │ │ ├── EchartsLineChartController.php │ │ │ │ │ │ ├── FrappeLineChartController.php │ │ │ │ │ │ └── HighchartsLineChartController.php │ │ │ │ │ ├── NewEntriesChartController.php │ │ │ │ │ └── Pies/ │ │ │ │ │ ├── ChartjsPieController.php │ │ │ │ │ ├── EchartsPieController.php │ │ │ │ │ ├── FrappePieController.php │ │ │ │ │ └── HighchartsPieController.php │ │ │ │ ├── ColumnMonsterCrudController.php │ │ │ │ ├── DummyCrudController.php │ │ │ │ ├── EditableMonsterCrudController.php │ │ │ │ ├── FieldMonsterCrudController.php │ │ │ │ ├── FluentMonsterCrudController.php │ │ │ │ ├── HeroCrudController.php │ │ │ │ ├── IconCrudController.php │ │ │ │ ├── MeetingCrudController.php │ │ │ │ ├── MonsterCrudController.php │ │ │ │ ├── Operations/ │ │ │ │ │ └── SMSOperation.php │ │ │ │ ├── PetShop/ │ │ │ │ │ ├── BadgeCrudController.php │ │ │ │ │ ├── CommentCrudController.php │ │ │ │ │ ├── InvoiceCrudController.php │ │ │ │ │ ├── OwnerCrudController.php │ │ │ │ │ ├── OwnerPetsCrudController.php │ │ │ │ │ ├── PassportCrudController.php │ │ │ │ │ ├── PetCrudController.php │ │ │ │ │ └── SkillCrudController.php │ │ │ │ ├── ProductCrudController.php │ │ │ │ ├── StoryCrudController.php │ │ │ │ └── UserCrudController.php │ │ │ ├── Api/ │ │ │ │ └── ArticleController.php │ │ │ └── Controller.php │ │ ├── Kernel.php │ │ ├── Middleware/ │ │ │ ├── Authenticate.php │ │ │ ├── CheckIfAdmin.php │ │ │ ├── EncryptCookies.php │ │ │ ├── RedirectIfAuthenticated.php │ │ │ ├── Theme.php │ │ │ ├── ValidateSignature.php │ │ │ └── VerifyCsrfToken.php │ │ └── Requests/ │ │ ├── BadgeRequest.php │ │ ├── CaveRequest.php │ │ ├── CommentRequest.php │ │ ├── DummyRequest.php │ │ ├── HeroRequest.php │ │ ├── IconRequest.php │ │ ├── InvoiceRequest.php │ │ ├── MeetingRequest.php │ │ ├── MonsterRequest.php │ │ ├── OwnerRequest.php │ │ ├── PassportRequest.php │ │ ├── PetRequest.php │ │ ├── ProductRequest.php │ │ ├── Request.php │ │ ├── SkillRequest.php │ │ └── StoryRequest.php │ ├── Jobs/ │ │ └── Job.php │ ├── Library/ │ │ └── Elfinder.php │ ├── Listeners/ │ │ └── .gitkeep │ ├── Models/ │ │ ├── Address.php │ │ ├── Article.php │ │ ├── Ball.php │ │ ├── Bill.php │ │ ├── Category.php │ │ ├── Cave.php │ │ ├── Country.php │ │ ├── Dummy.php │ │ ├── Graffiti.php │ │ ├── Hero.php │ │ ├── Icon.php │ │ ├── Meeting.php │ │ ├── MenuItem.php │ │ ├── Monster.php │ │ ├── Page.php │ │ ├── PetShop/ │ │ │ ├── Avatar.php │ │ │ ├── Badge.php │ │ │ ├── Comment.php │ │ │ ├── Invoice.php │ │ │ ├── InvoiceItem.php │ │ │ ├── Owner.php │ │ │ ├── Passport.php │ │ │ ├── Pet.php │ │ │ └── Skill.php │ │ ├── PostalBox.php │ │ ├── PostalBoxer.php │ │ ├── Product.php │ │ ├── Recommend.php │ │ ├── Sentiment.php │ │ ├── Star.php │ │ ├── Story.php │ │ ├── Tag.php │ │ ├── Traits/ │ │ │ └── LogsActivity.php │ │ ├── Universe.php │ │ └── Wish.php │ ├── PageTemplates.php │ ├── Policies/ │ │ └── .gitkeep │ ├── Providers/ │ │ ├── AppServiceProvider.php │ │ ├── AuthServiceProvider.php │ │ ├── BroadcastServiceProvider.php │ │ ├── EventServiceProvider.php │ │ └── RouteServiceProvider.php │ ├── User.php │ └── helpers.php ├── artisan ├── bootstrap/ │ ├── app.php │ ├── autoload.php │ └── cache/ │ └── .gitignore ├── composer.json ├── config/ │ ├── app.php │ ├── auth.php │ ├── backpack/ │ │ ├── base.php │ │ ├── crud.php │ │ ├── pagemanager.php │ │ ├── permissionmanager.php │ │ ├── testing.php │ │ ├── theme-tabler.php │ │ └── ui.php │ ├── backup.php │ ├── broadcasting.php │ ├── cache.php │ ├── compile.php │ ├── database.php │ ├── debugbar.php │ ├── elfinder.php │ ├── filesystems.php │ ├── gravatar.php │ ├── image.php │ ├── logging.php │ ├── mail.php │ ├── permission.php │ ├── prologue/ │ │ └── alerts.php │ ├── queue.php │ ├── services.php │ ├── session.php │ ├── sluggable.php │ └── view.php ├── database/ │ ├── .gitignore │ ├── factories/ │ │ ├── ArticleFactory.php │ │ ├── BillFactory.php │ │ ├── CategoryFactory.php │ │ ├── CaveFactory.php │ │ ├── HeroFactory.php │ │ ├── MeetingFactory.php │ │ ├── MenuItemFactory.php │ │ ├── MonsterFactory.php │ │ ├── PageFactory.php │ │ ├── PetShop/ │ │ │ ├── BadgeFactory.php │ │ │ ├── InvoiceFactory.php │ │ │ ├── InvoiceItemFactory.php │ │ │ ├── OwnerFactory.php │ │ │ ├── PassportFactory.php │ │ │ ├── PetFactory.php │ │ │ ├── SkillFactory.php │ │ │ └── StoryFactory.php │ │ ├── PostalBoxerFactory.php │ │ ├── ProductFactory.php │ │ ├── RecommendFactory.php │ │ ├── TagFactory.php │ │ └── UserFactory.php │ ├── migrations/ │ │ ├── .gitkeep │ │ ├── 2013_04_09_062329_create_backpack_revisions_table.php │ │ ├── 2014_10_12_000000_create_users_table.php │ │ ├── 2014_10_12_100000_create_password_resets_table.php │ │ ├── 2015_08_04_130507_create_article_tag_table.php │ │ ├── 2015_08_04_130520_create_articles_table.php │ │ ├── 2015_08_04_130551_create_categories_table.php │ │ ├── 2015_08_04_131614_create_settings_table.php │ │ ├── 2015_08_04_131626_create_tags_table.php │ │ ├── 2016_05_05_115641_create_menu_items_table.php │ │ ├── 2016_05_25_121918_create_pages_table.php │ │ ├── 2016_07_24_060017_add_slug_to_categories_table.php │ │ ├── 2016_07_24_060101_add_slug_to_tags_table.php │ │ ├── 2017_04_20_100848_create_monsters_table.php │ │ ├── 2017_04_21_052454_create_monster_tag_table.php │ │ ├── 2017_04_21_052455_create_monster_articles_table.php │ │ ├── 2017_04_21_052456_create_monster_category_table.php │ │ ├── 2017_12_18_075638_create_icons_table.php │ │ ├── 2017_12_19_081247_create_products_table.php │ │ ├── 2018_12_12_075319_create_permission_tables.php │ │ ├── 2019_09_13_093251_create_failed_jobs_table.php │ │ ├── 2019_12_02_101119_add_browse_multiple_to_monsters_table.php │ │ ├── 2020_03_12_100831_alter_monsters_table_add_relationship_columns.php │ │ ├── 2020_03_12_100831_alter_monsters_table_remove_address.php │ │ ├── 2020_03_29_054416_create_dummy_table.php │ │ ├── 2020_03_31_114745_add_columns_to_monster_table.php │ │ ├── 2020_03_31_114745_create_address_table.php │ │ ├── 2020_03_31_114745_create_pivotable_relations_tables.php │ │ ├── 2020_03_31_114745_remove_backpackuser_model.php │ │ ├── 2020_03_31_114745_rename_address_column_from_monsters.php │ │ ├── 2021_05_07_151146_make_notes_nullable_on_monster_product.php │ │ ├── 2021_08_08_130950_change_upload_multiple_column_in_monsters_table.php │ │ ├── 2021_10_13_081033_remove_simplemde_attribute_from_monsters.php │ │ ├── 2022_01_17_083405_create_owners_table.php │ │ ├── 2022_01_17_083526_create_invoices_table.php │ │ ├── 2022_01_17_083644_create_invoice_items_table.php │ │ ├── 2022_01_17_114317_create_pets_table.php │ │ ├── 2022_01_17_114318_create_owner_pet_table.php │ │ ├── 2022_01_17_114741_create_passports_table.php │ │ ├── 2022_01_17_120235_create_skills_table.php │ │ ├── 2022_01_17_120236_create_pet_skill_table.php │ │ ├── 2022_01_17_133436_create_avatars_table.php │ │ ├── 2022_01_17_135143_create_comments_table.php │ │ ├── 2022_01_17_141636_create_badges_table.php │ │ ├── 2022_01_17_141725_create_badgeables_table.php │ │ ├── 2022_01_21_153540_create_countries_table.php │ │ ├── 2022_01_21_155236_create_graffitis_table.php │ │ ├── 2022_01_21_165125_add_country_id_addresses_table.php │ │ ├── 2022_01_21_165552_create_wishes_table.php │ │ ├── 2022_01_21_165553_create_balls_table.php │ │ ├── 2022_01_21_165554_create_universes_table.php │ │ ├── 2022_01_22_063032_create_heroes_table.php │ │ ├── 2022_01_22_063323_add_hero_id_to_monsters_table.php │ │ ├── 2022_01_22_072809_create_stories_table.php │ │ ├── 2022_01_22_074008_add_story_id_to_monsters_table.php │ │ ├── 2022_01_22_145356_create_caves_table.php │ │ ├── 2022_01_22_145812_add_cave_id_to_monsters_table.php │ │ ├── 2022_10_08_084702_add_status_to_products.php │ │ ├── 2022_11_20_221518_create_activity_log_table.php │ │ ├── 2022_11_20_221519_add_event_column_to_activity_log_table.php │ │ ├── 2022_11_20_221520_add_batch_uuid_column_to_activity_log_table.php │ │ ├── 2022_12_30_162821_add_soft_deletes_to_pets.php │ │ ├── 2023_01_23_174016_add_status_to_monsters_table.php │ │ ├── 2023_01_23_194158_add_features_to_monsters_table.php │ │ ├── 2023_01_23_195752_add_ckeditor_to_monsters_table.php │ │ ├── 2023_02_22_191429_create_media_table.php │ │ ├── 2023_05_31_101941_add_dropzone_column_to_monsters_table.php │ │ ├── 2023_07_13_071933_add_soft_deletes_to_invoices_table.php │ │ ├── 2023_07_16_114745_rename_address_to_google_column_from_monsters.php │ │ ├── 2023_08_30_093542_add_email_verified_at_column_to_users.php │ │ ├── 2023_11_23_111148_add_category_relationship_column_to_monsters_table.php │ │ ├── 2024_02_03_225118_create_meetings_table.php │ │ ├── 2024_04_11_085730_create_language_lines_table.php │ │ ├── 2024_04_24_115407_add_json_api_fields_to_monster_table.php │ │ └── 2024_10_14_000001_create_pan_analytics_table.php │ └── seeders/ │ ├── .gitkeep │ ├── BadgeSeeder.php │ ├── CaveSeeder.php │ ├── CountryTableSeeder.php │ ├── DatabaseSeeder.php │ ├── HeroSeeder.php │ ├── IconsTableSeeder.php │ ├── InvoiceItemSeeder.php │ ├── InvoiceSeeder.php │ ├── MeetingSeeder.php │ ├── MillionCommentsSeeder.php │ ├── OwnerSeeder.php │ ├── PassportSeeder.php │ ├── PermissionManagerTablesSeeder.php │ ├── PetSeeder.php │ ├── PetShopSeeder.php │ ├── ReportDemoSeeder.php │ ├── SkillSeeder.php │ ├── StorySeeder.php │ ├── UniversesSeeder.php │ └── UsersTableSeeder.php ├── docker/ │ └── infra/ │ └── certs/ │ ├── local-dev-key.pem │ └── local-dev.pem ├── docker-compose.yml ├── entrypoint.d/ │ └── 51-after.sh ├── install.sh ├── lang/ │ ├── en/ │ │ ├── auth.php │ │ ├── pagination.php │ │ ├── passwords.php │ │ └── validation.php │ └── vendor/ │ ├── backpack/ │ │ ├── en/ │ │ │ └── crud.php │ │ └── tr/ │ │ └── crud.php │ └── backup/ │ ├── ar/ │ │ └── notifications.php │ ├── bg/ │ │ └── notifications.php │ ├── bn/ │ │ └── notifications.php │ ├── cs/ │ │ └── notifications.php │ ├── da/ │ │ └── notifications.php │ ├── de/ │ │ └── notifications.php │ ├── en/ │ │ └── notifications.php │ ├── es/ │ │ └── notifications.php │ ├── fa/ │ │ └── notifications.php │ ├── fi/ │ │ └── notifications.php │ ├── fr/ │ │ └── notifications.php │ ├── hi/ │ │ └── notifications.php │ ├── id/ │ │ └── notifications.php │ ├── it/ │ │ └── notifications.php │ ├── ja/ │ │ └── notifications.php │ ├── nl/ │ │ └── notifications.php │ ├── no/ │ │ └── notifications.php │ ├── pl/ │ │ └── notifications.php │ ├── pt/ │ │ └── notifications.php │ ├── pt-BR/ │ │ └── notifications.php │ ├── ro/ │ │ └── notifications.php │ ├── ru/ │ │ └── notifications.php │ ├── tr/ │ │ └── notifications.php │ ├── uk/ │ │ └── notifications.php │ ├── zh-CN/ │ │ └── notifications.php │ └── zh-TW/ │ └── notifications.php ├── package.json ├── phpunit.xml ├── public/ │ ├── .htaccess │ ├── assets/ │ │ ├── css/ │ │ │ └── backpack_electric_purple_overlay.css │ │ └── js/ │ │ ├── ga.js │ │ ├── meetings.js │ │ └── monster/ │ │ ├── fields.js │ │ ├── test-custom-field.js │ │ ├── test-disable-field.js │ │ ├── test-enable-field.js │ │ ├── test-hide-field.js │ │ ├── test-onchange-field.js │ │ ├── test-require-field.js │ │ ├── test-show-field.js │ │ ├── test-top-scenarios.js │ │ └── test-unrequire-field.js │ ├── index.php │ ├── robots.txt │ ├── uploads/ │ │ └── .gitkeep │ └── web.config ├── readme.md ├── reload.sh ├── resources/ │ ├── assets/ │ │ └── sass/ │ │ └── app.scss │ └── views/ │ ├── admin/ │ │ ├── metrics/ │ │ │ └── top_products.blade.php │ │ ├── new-in-v7.blade.php │ │ ├── partials/ │ │ │ ├── chip-examples.blade.php │ │ │ ├── dataform-examples.blade.php │ │ │ ├── dataform-modal-examples.blade.php │ │ │ ├── datagrid-examples.blade.php │ │ │ ├── datalist-examples.blade.php │ │ │ └── datatable-examples.blade.php │ │ └── petshop_about.blade.php │ ├── vendor/ │ │ ├── .gitkeep │ │ └── backpack/ │ │ ├── crud/ │ │ │ ├── buttons/ │ │ │ │ ├── fake-editable-columns.blade.php │ │ │ │ └── passports.blade.php │ │ │ ├── chips/ │ │ │ │ ├── invoice.blade.php │ │ │ │ └── owner.blade.php │ │ │ ├── columns/ │ │ │ │ └── custom_view_column_example.blade.php │ │ │ └── details_row/ │ │ │ └── monster.blade.php │ │ ├── theme-coreuiv2/ │ │ │ ├── auth/ │ │ │ │ └── login.blade.php │ │ │ ├── dashboard.blade.php │ │ │ └── inc/ │ │ │ ├── alerts.blade.php │ │ │ └── topbar_right_content.blade.php │ │ ├── theme-coreuiv4/ │ │ │ ├── auth/ │ │ │ │ └── login.blade.php │ │ │ ├── dashboard.blade.php │ │ │ └── inc/ │ │ │ ├── alerts.blade.php │ │ │ └── topbar_right_content.blade.php │ │ ├── theme-tabler/ │ │ │ ├── auth/ │ │ │ │ └── login/ │ │ │ │ └── inc/ │ │ │ │ └── form.blade.php │ │ │ ├── dashboard.blade.php │ │ │ ├── inc/ │ │ │ │ ├── alerts.blade.php │ │ │ │ ├── commercial.blade.php │ │ │ │ └── topbar_right_content.blade.php │ │ │ └── layouts/ │ │ │ └── partials/ │ │ │ └── sidebar_shortcuts.blade.php │ │ └── ui/ │ │ └── inc/ │ │ └── menu_items.blade.php │ └── welcome.blade.php ├── routes/ │ ├── api.php │ ├── backpack/ │ │ ├── custom.php │ │ └── permissionmanager.php │ ├── console.php │ └── web.php ├── start.sh ├── storage/ │ ├── app/ │ │ └── .gitignore │ ├── clockwork/ │ │ └── .gitignore │ ├── debugbar/ │ │ └── .gitignore │ ├── framework/ │ │ ├── .gitignore │ │ ├── cache/ │ │ │ └── .gitignore │ │ ├── sessions/ │ │ │ └── .gitignore │ │ └── views/ │ │ └── .gitignore │ └── logs/ │ └── .gitignore ├── tests/ │ └── Feature/ │ ├── Admin/ │ │ ├── CaveCrudControllerTest.php │ │ ├── ColumnMonsterCrudControllerTest.php │ │ ├── DummyCrudControllerTest.php │ │ ├── EditableMonsterCrudControllerTest.php │ │ ├── FieldMonsterCrudControllerTest.php │ │ ├── FluentMonsterCrudControllerTest.php │ │ ├── HeroCrudControllerTest.php │ │ ├── IconCrudControllerTest.php │ │ ├── MeetingCrudControllerTest.php │ │ ├── MonsterCrudControllerTest.php │ │ ├── PetShop/ │ │ │ ├── BadgeCrudControllerTest.php │ │ │ ├── CommentCrudControllerTest.php │ │ │ ├── InvoiceCrudControllerTest.php │ │ │ ├── OwnerCrudControllerTest.php │ │ │ ├── OwnerPetsCrudControllerTest.php │ │ │ ├── PassportCrudControllerTest.php │ │ │ ├── PetCrudControllerTest.php │ │ │ └── SkillCrudControllerTest.php │ │ ├── ProductCrudControllerTest.php │ │ ├── StoryCrudControllerTest.php │ │ └── UserCrudControllerTest.php │ └── Backpack/ │ ├── DefaultCreateTests.php │ ├── DefaultDeleteTests.php │ ├── DefaultListTests.php │ ├── DefaultShowTests.php │ ├── DefaultTestBase.php │ └── DefaultUpdateTests.php └── vite.config.js ================================================ FILE CONTENTS ================================================ ================================================ FILE: .gitattributes ================================================ * text=auto *.css linguist-vendored *.scss linguist-vendored ================================================ FILE: .github/config.yml ================================================ # Configuration for welcome - https://github.com/behaviorbot/welcome # Configuration for new-issue-welcome - https://github.com/behaviorbot/new-issue-welcome # Comment to be posted to on first time issues newIssueWelcomeComment: > Hello there! Thanks for opening your first issue on this repo! Just a heads-up: **Here at Backpack we use Github Issues only for tracking bugs**. Talk about new features is also acceptable. This helps _a lot_ in keeping our focus on improving Backpack. **If you issue is not a bug/feature, please help us out by closing the issue yourself and posting in the appropriate medium (see below)**. If you're not sure where it fits, it's ok, a community member will probably reply to help you with that. Backpack communication mediums: - Bug Reports, Feature Requests - Github Issues (here); - Quick help (_How do I do X_) - [Gitter Chatroom](https://gitter.im/BackpackForLaravel/Lobby); - Long questions (_I have done X and Y and it won't do Z wtf_) - [Stackoverflow](https://stackoverflow.com/questions/tagged/backpack-for-laravel), using the ```backpack-for-laravel``` tag; Please keep in mind Backpack offers no official / paid support. Whatever help you receive here, on Gitter, Slack or Stackoverflow is thanks to our awesome _awesome_ community members, who give up some of their time to help their peers. If you want to join our community, just start pitching in. We take pride in being a welcoming bunch. Thank you! -- Justin Case The Backpack Robot # Configuration for new-pr-welcome - https://github.com/behaviorbot/new-pr-welcome # Comment to be posted to on PRs from first time contributors in your repository newPRWelcomeComment: > BOOM! Your first PR with us, thank you so much! Someone will take a look at it shortly. Please keep in mind that: - **if this constitutes a breaking change, it might take quite a while for this to get merged**; we try to emulate the Laravel release cycle as much as possible, so developers can upgrade both software once; this means a new big release every ~6 months; - **even if it's a non-breaking change, it might take a few days/weeks for the PR to get merged**; unless it's a no-brainer, **we like to have some community feedback on new features, before we merge them**; this leads to higher-quality code, in the end; we learnt this the hard way :-) - **not all PRs get merged**; sometimes we just have to hold out new features, to keep the packages lean; sometimes we don't include features that only apply to niche use cases; - **we're not perfect**; if you think we're wrong, call us out on it; but in a kind way :-) we all make mistakes, best we learn from them and build better software together; Thank you! -- Justin Case The Backpack Robot # Configuration for first-pr-merge - https://github.com/behaviorbot/first-pr-merge # Comment to be posted to on pull requests merged by a first time user firstPRMergeComment: > WHOOP-WHOOP! Congrats, your first PR on this repo has officialy been merged. ![party](https://media1.giphy.com/media/3KC2jD2QcBOSc/giphy.gif "Party!!!") If you want to help out the community in other ways, you can: - **give your opinion on other Github Issues & PRs**; - **chat with others** in the [Gitter Chatroom](https://gitter.im/BackpackForLaravel/Lobby) (usually for quick help: _How do I do X_); - **answer Backpack questions on [Stackoverflow](https://stackoverflow.com/questions/tagged/backpack-for-laravel)**; you get points, people get help; you can subscribe to the ```backpack-for-laravel``` tag by [adding a new filter](https://stackexchange.com/filters/256210/my-filter-3); that will send you emails when new questions come up with our tag; Again. Thank you for the PR. You are a wonderful person. Keep 'em coming :-) Cheers! -- Justin Case The Backpack Robot P.S. **Help in the Backpack community is rewarded with free Backpack commercial licenses**. It's the least we can do. If you feel you've helped the community with PRs, help & other stuff, please [shoot Tabacitu an email](mailto:hello@tabacitu.ro) and ask him if you qualify for free licenses. You scratch my back, I scratch your back. Thank you! # It is recommend to include as many gifs and emojis as possible # # --------------------------------------------------------------------------------------------- # # Configuration for request-info - https://github.com/behaviorbot/request-info # *OPTIONAL* Comment to reply with # Can be either a string : requestInfoReplyComment: > Hi there! Could you please provide us with more info about this? Looks like you skipped the title/body. Thank you! -- Justin Case The Backpack Robot # Or an array: # requestInfoReplyComment: # - Ah no! young blade! That was a trifle short! # - Tell me more ! # - I am sure you can be more effusive # *OPTIONAL* default titles to check against for lack of descriptiveness # MUST BE ALL LOWERCASE requestInfoDefaultTitles: # - update readme.md - updates # *OPTIONAL* Label to be added to Issues and Pull Requests with insufficient information given requestInfoLabelToAdd: needs-more-info # *OPTIONAL* Only warn about insufficient information on these events type # Keys must be lowercase. Valid values are 'issue' and 'pullRequest' requestInfoOn: pullRequest: true issue: true # *OPTIONAL* Add a list of people whose Issues/PRs will not be commented on # keys must be GitHub usernames requestInfoUserstoExclude: - tabacitu # --------------------------------------------------------------------------------------------- # ================================================ FILE: .github/dependabot.yml ================================================ version: 2 updates: - package-ecosystem: composer directory: "/" schedule: interval: monthly open-pull-requests-limit: 10 ignore: - dependency-name: symfony/dom-crawler versions: - 5.2.2 - dependency-name: laravel/framework versions: - 8.25.0 - dependency-name: backpack/pagemanager versions: - 3.0.6 - dependency-name: backpack/generators versions: - 3.1.6 - dependency-name: facade/ignition versions: - 2.5.9 - dependency-name: laravel/tinker versions: - 2.6.0 - dependency-name: barryvdh/laravel-debugbar versions: - 3.5.2 - dependency-name: phpunit/phpunit versions: - 9.5.1 - dependency-name: backpack/crud versions: - 4.1.31 ================================================ FILE: .github/issue_template.md ================================================ # Bug report ### What I did: ### What I expected to happen: ### What happened: ### What I've already tried to fix it: ### Backpack, Laravel, PHP, DB version: ================================================ FILE: .github/pull_request_template.md ================================================ ## WHY ### BEFORE - What was wrong? What was happening before this PR? ?? ### AFTER - What is happening after this PR? ?? ## HOW ### How did you achieve that, in technical terms? ?? ### Is it a breaking change or non-breaking change? ?? ### How can we test the before & after? ?? ================================================ FILE: .github/stale.yml ================================================ ##################################### # Github Stale Probot Configuration # # ################################### # https://probot.github.io/apps/stale/ # Number of days of inactivity before an issue becomes stale daysUntilStale: 60 # Number of days of inactivity before a stale issue is closed daysUntilClose: 14 # Issues with these labels will never be considered stale exemptLabels: - pinned - security - feature - urgent - ready - working on it - bug # Label to use when marking an issue as stale staleLabel: stale # Comment to post when marking an issue as stale. Set to `false` to disable markComment: > Hi there! **Is this still an issue?** No activity in 60 days. I'm going to mark it as stale for now, and close it in 14 days if no further activity occurs. I know you guys are all busy, but if this is important to you please reply or something, so I know not to close it. Thank you! -- Justin Case The Backpack Robot # Comment to post when closing a stale issue. Set to `false` to disable closeComment: true ================================================ FILE: .github/support.yml ================================================ # Configuration for support-requests - https://github.com/dessant/support-requests # Label used to mark issues as support requests supportLabel: Ask-It-On-Stack-Overflow # Comment to post on issues marked as support requests. Add a link # to a support page, or set to `false` to disable supportComment: > Oups! Looks like this is a support request, not a bug/feature. **Could you please [repost on StackOverflow](https://stackoverflow.com/questions/tagged/backpack-for-laravel), using the ```backpack-for-laravel``` tag**? Background: **Here at Backpack we use Github Issues only for tracking bugs and features**, not individual implementation issues. This helps _a lot_ in keeping our focus on improving Backpack. Thanks a lot for understanding! Here are all the Backpack communication mediums: - Long questions (_I have done X and Y and it won't do Z wtf_) - [Stackoverflow](https://stackoverflow.com/questions/tagged/backpack-for-laravel), using the ```backpack-for-laravel``` tag; this is recommended for most questions, since other developers can then find the answer on a simple Google search; also, people get points for answering - and who doesn't like StackOverflow points?! - Quick help (_How do I do X_) - [Gitter Chatroom](https://gitter.im/BackpackForLaravel/Lobby); - Bug Reports, Feature Requests - Github Issues (here); Please keep in mind Backpack offers no official / paid support. Whatever help you receive here, on Gitter, Slack or StackOverflow is thanks to our awesome _awesome_ community members, who give up some of their time to help their peers. If you want to join our community, just start pitching in. We take pride in being a welcoming bunch. Thank you! -- Justin Case The Backpack Robot PS. In case I mistakenly closed your issue, yell :-) I'm a robot, I make mistakes. # Whether to close issues marked as support requests close: true # Whether to lock issues marked as support requests lock: false ================================================ FILE: .github/workflows/add-to-project.yml ================================================ name: Add new bugs & PRs to This Week project on: issues: types: - opened - transferred pull_request: types: - opened jobs: add-to-project: name: Add new bugs and PRs to This Week project runs-on: ubuntu-latest steps: - uses: actions/add-to-project@main with: project-url: https://github.com/orgs/Laravel-Backpack/projects/13 github-token: ${{ secrets.ADD_TO_PROJECT_PAT }} ================================================ FILE: .gitignore ================================================ /vendor /node_modules /public/storage /storage/backups Homestead.yaml Homestead.json .env .idea .DS_Store .packages .quarantine .tmb /.vapor /packages /.vscode /packages /_volumes /public/basset ================================================ FILE: .travis.yml ================================================ language: php php: - 7.3 - 7.4 - 8.0 - nightly matrix: allow_failures: - php: 7.2 - php: 7.3 - php: 8.0 - php: nightly env: global: - APP_ENV=local - APP_DEBUG=true - APP_KEY=base64:jNI+qJRj1eqN3RWMeBWo6sxMwKzgDP7Py2AfRJ1luyA= - APP_URL=http://localhost - DB_CONNECTION=mysql - DB_HOST=127.0.0.1 - DB_PORT=3306 - DB_DATABASE=test - DB_USERNAME=root - DB_PASSWORD= - CACHE_DRIVER=file - SESSION_DRIVER=file - QUEUE_DRIVER=sync - REDIS_HOST=127.0.0.1 - REDIS_PASSWORD=null - REDIS_PORT=6379 - MAIL_DRIVER=smtp - MAIL_HOST=mailtrap.io - MAIL_PORT=2525 - MAIL_USERNAME=null - MAIL_PASSWORD=null - MAIL_ENCRYPTION=null sudo: false services: mysql before_install: - mysql -e "create database IF NOT EXISTS test;" -uroot install: travis_retry composer install --no-interaction --prefer-source script: vendor/bin/phpunit --coverage-clover=coverage.clover after_script: - wget https://scrutinizer-ci.com/ocular.phar - php ocular.phar code-coverage:upload --format=php-clover coverage.clover ================================================ FILE: Dockerfile ================================================ FROM serversideup/php:8.3-fpm-nginx as base ENV S6_CMD_WAIT_FOR_SERVICES=1 COPY --chmod=755 ./entrypoint.d/ /etc/entrypoint.d/ COPY ./docker/infra/certs /etc/nginx/certs USER root # run the docker-php-serversideup-s6-init script RUN docker-php-serversideup-s6-init USER www-data # uncomment if you need to install chrome. eg. for spatie browser shot projects. #USER root # ENV PUPPETEER_SKIP_CHROMIUM_DOWNLOAD true #RUN apt-get update \ # && apt-get install -y wget gnupg \ # && wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add - \ # && sh -c 'echo "deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google.list' \ # && apt-get -y update \ # && apt-get install -y google-chrome-stable fonts-ipafont-gothic fonts-wqy-zenhei fonts-thai-tlwg fonts-kacst fonts-freefont-ttf libxss1 \ #--no-install-recommends \ # && rm -rf /var/lib/apt/lists/* \ # && usermod -a -G video www-data \ # && usermod -a -G audio www-data \ # && mkdir -p /home/www-data/Downloads \ # && chown -R www-data:www-data /home/www-data FROM base as development # We can pass USER_ID and GROUP_ID as build arguments # to ensure the www-data user has the same UID and GID # as the user running Docker. ARG USER_ID ARG GROUP_ID # Switch to root so we can set the user ID and group ID USER root RUN docker-php-serversideup-set-id www-data $USER_ID:$GROUP_ID && \ docker-php-serversideup-set-file-permissions --owner $USER_ID:$GROUP_ID --service nginx # make npm & node available in the container COPY --chown=www-data:www-data --from=node:22.4.1 /usr/local/bin /usr/local/bin COPY --chown=www-data:www-data --from=node:22.4.1 /usr/local/lib/node_modules/npm /usr/local/lib/node_modules/npm USER www-data ================================================ FILE: LICENSE.md ================================================ # YUMMY License **YoU make Money, I make MoneY.** The license holder is allowed to use the software for free, as long as he doesn't make money by using it. Copyright (c) 2015-2017 Cristian Tabacitu ## FREE for non-commercial use, PAID for commercial use > Permission is hereby granted to any person obtaining a copy of this software > and associated documentation files (the "Software"), to use the Software. > This includes the rights to use, copy, modify and/or merge the Sofware > or copies of the Software, and to permit persons to whom the Software is > furnished to do so, subject to the following conditions: > > **1. Should the Sofware be used for non-commercial purposes (personal use, not-profits, > testing, education), no financial reward is expected and the above rights are given FREE OF CHARGE.** > > **2. Should the Software be used for commercial purposes (the user of this Sofware, > its employer, employees or clients make money by using this Software), the user is > required to purchase a "Single Domain License" on [backpackforlaravel.com](https://backpackforlaravel.com), for each > domain name this sofware will be used on, before its usage in production. > Failure to do so will constitute as illegal commercial use.** > > **3. This license does not include the rights to publish or sublicense > this Sofware, its copies or any derivations, with or without the purpose of commercial profit. > For inclusion in commercial packages or SaaS products, an "Unlimited License" is required, which can be purchased on [backpackforlaravel.com](https://backpackforlaravel.com). For inclusion in free open-source packages, express permission is needed from .** > > **4. The above copyright notice and this permission notice shall be included in > all copies or substantial portions of the Software.** > > THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR > IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, > FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE > AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER > LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, > OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN > THE SOFTWARE. ================================================ FILE: app/Console/Commands/Inspire.php ================================================ comment(PHP_EOL.Inspiring::quote().PHP_EOL); } } ================================================ FILE: app/Console/Commands/RefreshDb.php ================================================ command('db:fresh')->hourly(); } } ================================================ FILE: app/Enums/MonsterStatus.php ================================================ 'Is working', MonsterStatus::NOTWORKING => 'Is not working', MonsterStatus::DONTKNOW => 'We didn\'t know', }; } } ================================================ FILE: app/Enums/ProductCondition.php ================================================ 'New Product', ProductCondition::USED => 'Used Product', ProductCondition::BROKEN => '!!BROKEN!!', }; } } ================================================ FILE: app/Enums/ProductStatus.php ================================================ 'Is in Stock', ProductStatus::NOSTOCK => 'Is out of stock', ProductStatus::ONHOLD => 'Is on hold', }; } } ================================================ FILE: app/Events/Event.php ================================================ 'New in v7', 'description' => 'Discover the new features and improvements in Backpack v7.', ]); } } ================================================ FILE: app/Http/Controllers/Admin/CaveCrudController.php ================================================ attribute('text'); } /** * Define what happens when the Create operation is loaded. * * @see https://backpackforlaravel.com/docs/crud-operation-create * * @return void */ protected function setupCreateOperation() { CRUD::setValidation(CaveRequest::class); CRUD::setOperationSetting('contentClass', 'col-md-12'); CRUD::field('name'); if (env('GOOGLE_PLACES_KEY')) { CRUD::field('location')->label('Cave Location')->type('google_map')->map_options([ 'default_lat' => 38.6915837, 'default_lng' => -9.2159772, ]); } CRUD::field('monster') ->label('Monster '.backpack_new_badge()) ->subfields(self::getMonsterSubfields()) ->hint('Define the related Monster over a hasOne relationship (1-1).'); } /** * Define what happens when the Update operation is loaded. * * @see https://backpackforlaravel.com/docs/crud-operation-update * * @return void */ protected function setupUpdateOperation() { $this->setupCreateOperation(); } public static function getMonsterSubfields() { $field_types_that_dont_work = [ 'date_range', // TODO 'upload', 'upload_multiple', 'select_grouped', // TODO 'select2_grouped', // TODO ]; $subfields = array_merge( MonsterCrudController::getFieldsArrayForSimpleTab(), [[ // CustomHTML 'name' => 'separator', 'type' => 'custom_html', 'value' => '
', ]], MonsterCrudController::getFieldsArrayForTimeAndSpaceTab(), [[ // CustomHTML 'name' => 'separator', 'type' => 'custom_html', 'value' => '
', ]], MonsterCrudController::getFieldsArrayForSelectsTab(), [[ // CustomHTML 'name' => 'separator', 'type' => 'custom_html', 'value' => '
', ]], MonsterCrudController::getFieldsArrayForRelationshipsTab(), [[ // CustomHTML 'name' => 'separator', 'type' => 'custom_html', 'value' => '
', ]], MonsterCrudController::getFieldsArrayForUploadsTab(), [[ // CustomHTML 'name' => 'separator', 'type' => 'custom_html', 'value' => '
', ]], MonsterCrudController::getFieldsArrayForWysiwygEditorsTab(), [[ // CustomHTML 'name' => 'separator', 'type' => 'custom_html', 'value' => '
', ]], MonsterCrudController::getFieldsArrayForMiscellaneousTab(), ); foreach ($subfields as $key => $subfield) { if (isset($subfield['subfields'])) { unset($subfields[$key]); } if (!isset($subfield['type'])) { continue; } if (in_array($subfield['type'], $field_types_that_dont_work)) { unset($subfields[$key]); } } return $subfields; } public function ajaxUpload() { if (app('env') === 'production') { return response()->json(['errors' => [ 'message' => 'Uploads are disabled in production.', ]], 500); } return $this->traitAjaxUpload(); } } ================================================ FILE: app/Http/Controllers/Admin/Charts/LatestUsersChartController.php ================================================ chart = new Chart(); // MANDATORY. Set the labels for the dataset points $this->chart->labels(['6 days ago', '5 days ago', '4 days ago', '3 days ago', '2 days ago', 'Yesterday', 'Today']); // RECOMMENDED. Set URL that the ChartJS library should call, to get its data using AJAX. $this->chart->load(backpack_url('charts/users')); // OPTIONAL $this->chart->minimalist(false); $this->chart->displayLegend(true); } /** * Respond to AJAX calls with all the chart data points. * * @return json */ public function data() { $today_users = User::whereDate('created_at', today())->count(); $yesterday_users = User::whereDate('created_at', today()->subDays(1))->count(); $users_2_days_ago = User::whereDate('created_at', today()->subDays(2))->count(); $users_3_days_ago = User::whereDate('created_at', today()->subDays(3))->count(); $users_4_days_ago = User::whereDate('created_at', today()->subDays(4))->count(); $users_5_days_ago = User::whereDate('created_at', today()->subDays(5))->count(); $users_6_days_ago = User::whereDate('created_at', today()->subDays(6))->count(); $this->chart->dataset('Users Created', 'bar', [ $users_6_days_ago, $users_5_days_ago, $users_4_days_ago, $users_3_days_ago, $users_2_days_ago, $yesterday_users, $today_users, ])->color('rgb(66, 186, 150, 1)') ->backgroundColor('rgb(66, 186, 150, 0.4)'); } } ================================================ FILE: app/Http/Controllers/Admin/Charts/Lines/ChartjsLineChartController.php ================================================ chart = new Chart(); $this->chart->dataset('Red', 'line', [1, 2, 8, 3]) ->color('rgba(205, 32, 31, 1)') ->backgroundColor('rgba(205, 32, 31, 0.4)'); $this->chart->dataset('Blue', 'line', [4, 3, 5, 1]) ->color('rgba(70, 127, 208, 1)') ->backgroundColor('rgba(70, 127, 208, 0.4)'); $this->chart->dataset('Yellow', 'line', [8, 1, 4, 3]) ->color('rgb(255, 193, 7)') ->backgroundColor('rgba(255, 193, 7, 0.4)'); $this->chart->dataset('Green', 'line', [1, 4, 7, 11]) ->color('rgb(66, 186, 150)') ->backgroundColor('rgba(66, 186, 150, 0.4)'); $this->chart->dataset('Purple', 'line', [2, 10, 5, 3]) ->color('rgb(96, 92, 168)') ->backgroundColor('rgba(96, 92, 168, 0.4)'); // MANDATORY. Set the labels for the dataset points $this->chart->labels(['One', 'Two', 'Three', 'Four']); } } ================================================ FILE: app/Http/Controllers/Admin/Charts/Lines/EchartsLineChartController.php ================================================ chart = new Chart(); $this->chart->dataset('Red', 'line', [1, 2, 8, 3]) ->color('rgba(205, 32, 31, 1)'); $this->chart->dataset('Blue', 'line', [4, 3, 5, 1]) ->color('rgba(70, 127, 208, 1)'); $this->chart->dataset('Yellow', 'line', [8, 1, 4, 3]) ->color('rgb(255, 193, 7)'); $this->chart->dataset('Green', 'line', [1, 4, 7, 11]) ->color('rgb(66, 186, 150)'); $this->chart->dataset('Purple', 'line', [2, 10, 5, 3]) ->color('rgb(96, 92, 168)'); // MANDATORY. Set the labels for the dataset points $this->chart->labels(['One', 'Two', 'Three', 'Four']); } } ================================================ FILE: app/Http/Controllers/Admin/Charts/Lines/FrappeLineChartController.php ================================================ chart = new Chart(); $this->chart->dataset('Red', 'line', [1, 2, 8, 3]) ->color('rgba(205, 32, 31, 1)'); $this->chart->dataset('Blue', 'line', [4, 3, 5, 1]) ->color('rgba(70, 127, 208, 1)'); $this->chart->dataset('Yellow', 'line', [8, 1, 4, 3]) ->color('#FFC107'); $this->chart->dataset('Green', 'line', [1, 4, 7, 11]) ->color('rgb(66, 186, 150)'); $this->chart->dataset('Purple', 'line', [2, 10, 5, 3]) ->color('rgb(96, 92, 168)'); // MANDATORY. Set the labels for the dataset points $this->chart->labels(['One', 'Two', 'Three', 'Four']); } } ================================================ FILE: app/Http/Controllers/Admin/Charts/Lines/HighchartsLineChartController.php ================================================ chart = new Chart(); $this->chart->dataset('Red', 'line', [1, 2, 8, 3]) ->color('rgba(205, 32, 31, 1)'); $this->chart->dataset('Blue', 'line', [4, 3, 5, 1]) ->color('rgba(70, 127, 208, 1)'); $this->chart->dataset('Yellow', 'line', [8, 1, 4, 3]) ->color('rgb(255, 193, 7)'); $this->chart->dataset('Green', 'line', [1, 4, 7, 11]) ->color('rgb(66, 186, 150)'); $this->chart->dataset('Purple', 'line', [2, 10, 5, 3]) ->color('rgb(96, 92, 168)'); // MANDATORY. Set the labels for the dataset points $this->chart->labels(['One', 'Two', 'Three', 'Four']); } } ================================================ FILE: app/Http/Controllers/Admin/Charts/NewEntriesChartController.php ================================================ chart = new Chart(); // MANDATORY. Set the labels for the dataset points $labels = []; for ($days_backwards = 30; $days_backwards >= 0; $days_backwards--) { if ($days_backwards == 1) { } $labels[] = $days_backwards.' days ago'; } $this->chart->labels($labels); // RECOMMENDED. Set URL that the ChartJS library should call, to get its data using AJAX. $this->chart->load(backpack_url('charts/new-entries')); // OPTIONAL $this->chart->minimalist(false); $this->chart->displayLegend(true); } /** * Respond to AJAX calls with all the chart data points. * * @return json */ public function data() { for ($days_backwards = 30; $days_backwards >= 0; $days_backwards--) { // Could also be an array_push if using an array rather than a collection. $users[] = User::whereDate('created_at', today()->subDays($days_backwards)) ->count(); $articles[] = Article::whereDate('created_at', today()->subDays($days_backwards)) ->count(); $categories[] = Category::whereDate('created_at', today()->subDays($days_backwards)) ->count(); $tags[] = Tag::whereDate('created_at', today()->subDays($days_backwards)) ->count(); } $this->chart->dataset('Users', 'line', $users) ->color('rgb(66, 186, 150)') ->backgroundColor('rgba(66, 186, 150, 0.4)'); $this->chart->dataset('Articles', 'line', $articles) ->color('rgb(96, 92, 168)') ->backgroundColor('rgba(96, 92, 168, 0.4)'); $this->chart->dataset('Categories', 'line', $categories) ->color('rgb(255, 193, 7)') ->backgroundColor('rgba(255, 193, 7, 0.4)'); $this->chart->dataset('Tags', 'line', $tags) ->color('rgba(70, 127, 208, 1)') ->backgroundColor('rgba(70, 127, 208, 0.4)'); } } ================================================ FILE: app/Http/Controllers/Admin/Charts/Pies/ChartjsPieController.php ================================================ chart = new Chart(); $this->chart->dataset('Red', 'pie', [10, 20, 80, 30]) ->backgroundColor([ 'rgb(70, 127, 208)', 'rgb(66, 186, 150)', 'rgb(96, 92, 168)', 'rgb(255, 193, 7)', ]); // OPTIONAL $this->chart->displayAxes(false); $this->chart->displayLegend(true); // MANDATORY. Set the labels for the dataset points $this->chart->labels(['HTML', 'CSS', 'PHP', 'JS']); } } ================================================ FILE: app/Http/Controllers/Admin/Charts/Pies/EchartsPieController.php ================================================ chart = new Chart(); $this->chart->dataset('Red', 'pie', [10, 20, 80, 30]) ->color([ 'rgb(70, 127, 208)', 'rgb(66, 186, 150)', 'rgb(96, 92, 168)', 'rgb(255, 193, 7)', ]); // OPTIONAL $this->chart->displayAxes(false); $this->chart->displayLegend(true); // MANDATORY. Set the labels for the dataset points $this->chart->labels(['HTML', 'CSS', 'PHP', 'JS']); } } ================================================ FILE: app/Http/Controllers/Admin/Charts/Pies/FrappePieController.php ================================================ chart = new Chart(); $this->chart->dataset('Red', 'pie', [10, 20, 80, 30]); // ->color([ // 'rgb(70, 127, 208)', // 'rgb(66, 186, 150)', // 'rgb(96, 92, 168)', // 'rgb(255, 193, 7)' // ]); // OPTIONAL // $this->chart->displayAxes(false); // $this->chart->displayLegend(true); // MANDATORY. Set the labels for the dataset points $this->chart->labels(['HTML', 'CSS', 'PHP', 'JS']); } } ================================================ FILE: app/Http/Controllers/Admin/Charts/Pies/HighchartsPieController.php ================================================ chart = new Chart(); $this->chart->dataset('Red', 'pie', [10, 20, 80, 30]) ->color([ 'rgb(70, 127, 208)', 'rgb(66, 186, 150)', 'rgb(96, 92, 168)', 'rgb(255, 193, 7)', ]); // OPTIONAL $this->chart->displayAxes(false); $this->chart->displayLegend(true); // MANDATORY. Set the labels for the dataset points $this->chart->labels(['HTML', 'CSS', 'PHP', 'JS']); } } ================================================ FILE: app/Http/Controllers/Admin/ColumnMonsterCrudController.php ================================================ crud->set('show.setFromDb', false); } /** * Define what happens when the List operation is loaded. * * @see https://backpackforlaravel.com/docs/crud-operation-list-entries * * @return void */ public function setupListOperation() { $this->crud->disableResponsiveTable(); $timeSpaceColumns = static::getFieldsArrayForTimeAndSpaceTab(); foreach ($timeSpaceColumns as $columnKey => $column) { // transform field array names into comma separated string if (is_array($column['name'])) { $timeSpaceColumns[$columnKey]['name'] = implode(',', $column['name']); } } $this->crud->addColumns(static::getFieldsArrayForSimpleTab()); $this->crud->addColumns($timeSpaceColumns); $this->crud->addColumns(static::getFieldsArrayForSelectsTab()); $this->crud->addColumns(static::getFieldsArrayForRelationshipsTab()); $this->crud->addColumns(static::getFieldsArrayForUploadsTab()); $this->crud->addColumns(static::getFieldsArrayForWysiwygEditorsTab()); $this->crud->addColumns(static::getFieldsArrayForMiscellaneousTab()); foreach ($this->crud->columns() as $columnKey => $column) { // remove all custom_html columns if (isset($column['type']) && $column['type'] === 'custom_html') { $this->crud->removeColumn($columnKey); continue; } // unset the `col-` bootstrap size classes as they would break the columns in the table. if (isset($column['wrapper']['class'])) { $column['wrapper']['class'] = $this->removeBootstrapSizingClasses($column['wrapper']['class']); } if (isset($column['subfields'])) { $subfields = $column['subfields']; foreach ($subfields as $subfieldKey => $subfield) { if (isset($subfield['wrapper']['class'])) { $subfields[$subfieldKey]['wrapper']['class'] = $this->removeBootstrapSizingClasses($subfield['wrapper']['class']); } } $column['subfields'] = $subfields; } $this->crud->modifyColumn($columnKey, $column); } } private function removeBootstrapSizingClasses($classes) { $classes = explode(' ', $classes); $newClasses = []; foreach ($classes as $class) { if (!str_starts_with($class, 'col-')) { array_push($newClasses, $class); } } return implode(' ', $newClasses); } } ================================================ FILE: app/Http/Controllers/Admin/DummyCrudController.php ================================================ crud->setModel(\App\Models\Dummy::class); $this->crud->setRoute(config('backpack.base.route_prefix').'/dummy'); $this->crud->setEntityNameStrings('dummy', 'dummies'); } public function fetchProduct() { return $this->fetch(\App\Models\Product::class); } public function fetchProducts() { return $this->fetch(\App\Models\Product::class); } public function fetchIcon() { return $this->fetch(\App\Models\Icon::class); } protected function setupListOperation() { CRUD::addColumn('name'); CRUD::addColumn('description'); foreach ($this->groups() as $groupKey => $groupFields) { CRUD::addColumn([ 'name' => $groupKey, 'label' => str_replace('_', ' ', Str::title($groupKey)), 'type' => 'array_count', ]); } } protected function setupCreateOperation() { $this->crud->setValidation(DummyRequest::class); $this->crud->setOperationSetting('contentClass', 'col-md-12'); CRUD::addField('name'); CRUD::addField('description'); foreach ($this->groups() as $groupKey => $groupFields) { CRUD::addField([ 'name' => $groupKey, 'label' => str_replace('_', ' ', Str::title($groupKey)), 'type' => 'repeatable', 'fake' => true, 'store_in' => 'extras', 'subfields' => $groupFields, ]); } } protected function setupUpdateOperation() { $this->setupCreateOperation(); } protected function setupShowOperation() { $this->setupListOperation(); $this->crud->setOperationSetting('contentClass', 'col-md-12'); // for field types that have multiple name (ex: date_range) // split those into two separate text columns foreach ($this->groups() as $groupKey => $groupFields) { CRUD::removeColumn($groupKey); foreach ($groupFields as $key => $field) { if (is_array($field['name'])) { foreach ($field['name'] as $name) { $newField = $field; $newField['name'] = $name; $newField['type'] = 'text'; $groupFields[] = $newField; } unset($groupFields[$key]); } } // only consider fields that have both name and label (needed for table column) // reject custom_html fields (since they have no value) $validFields = collect($groupFields)->reject(function ($value, $key) { $is_custom_html_field = $value['type'] ?? '' == 'custom_html'; $does_not_have_label = !isset($value['label']); $does_not_have_name = !isset($value['name']); return $is_custom_html_field || $does_not_have_label || $does_not_have_name; })->pluck('label', 'name'); CRUD::addColumn([ 'name' => $groupKey, 'label' => str_replace('_', ' ', Str::title($groupKey)), 'type' => 'table', 'columns' => $validFields, ]); } CRUD::addColumn([ 'name' => 'created_at', 'type' => 'datetime', ]); CRUD::addColumn([ 'name' => 'updated_at', 'type' => 'datetime', ]); } protected function groups() { // instead of manually defining all the field type here too // let's pull all field types defined in MonsterCrudController instead // since they're already nicely split by tab, // we can split them exactly the same here, but into groups instead of tabs // (one repeatable field for each tab in MonsterCrudController) $groups['simple'] = MonsterCrudController::getFieldsArrayForSimpleTab(); $groups['time_and_space'] = MonsterCrudController::getFieldsArrayForTimeAndSpaceTab(); $groups['selects'] = MonsterCrudController::getFieldsArrayForSelectsTab(); $groups['uploads'] = MonsterCrudController::getFieldsArrayForUploadsTab(); $groups['big_texts'] = MonsterCrudController::getFieldsArrayForWysiwygEditorsTab(); $groups['miscellaneous'] = MonsterCrudController::getFieldsArrayForMiscellaneousTab(); // some fields do not make sense, or do not work inside repeatable, so let's exclude them $excludedFieldTypes = [ 'address', // TODO 'address_google', // TODO 'checklist_dependency', // only available in PermissionManager package // 'custom_html', // this works (of course), it's only used for heading, but the page looks better without them 'enum', // doesn't make sense inside repeatable 'page_or_link', // only available in PageManager package 'upload', // currently impossible to make it work inside repeatable; 'upload_multiple', // currently impossible to make it work inside repeatable; ]; foreach ($groups as $groupKey => $fields) { $groups[$groupKey] = Arr::where($fields, function ($field) use ($excludedFieldTypes) { // eliminate fields that have 1-1 relationships // (determined by the fact that their names use dot notation) if (is_string($field['name']) && strpos($field['name'], '.') != 0) { return false; } // eliminate the heading for 1-1 relationships // since those are not available inside repeatable, the heading should be hidden too if (is_string($field['name']) && $field['name'] == 'select_1_1_heading') { return false; } // if no field type was set, the system will probably use text, number or relationship // and all of those are fine, they work well inside repeatable fields if (!isset($field['type'])) { return true; } // exclude all field types that we KNOW don't work inside repeatable return !in_array($field['type'], $excludedFieldTypes); }); } return $groups; } public function ajaxUpload() { if (app('env') === 'production') { return response()->json(['errors' => [ 'message' => 'Uploads are disabled in production.', ]], 500); } return $this->traitAjaxUpload(); } } ================================================ FILE: app/Http/Controllers/Admin/EditableMonsterCrudController.php ================================================ query->get('fake')) { return $this->setupListOperationFake(); } // demo editable_text column CRUD::column('text') ->label('Text') ->type('editable_text'); CRUD::column('email') ->label('Email') ->type('editable_text'); // demo editable_switch column CRUD::column('checkbox') ->label('Switch') ->type('editable_switch'); // demo editable_checkbox column // CRUD::column('editable_checkbox') // ->label('Editable checkbox') // ->type('editable_checkbox'); // demo editable_select column CRUD::column('select_from_array') ->label('Select') ->type('editable_select') ->options(['one' => 'One', 'two' => 'Two', 'three' => 'Three']); CRUD::column('text_and_email'); } public function setupListOperationFake() { CRUD::addButtonFromView('top', 'fake-editable-columns', 'fake-editable-columns'); // demo fake editable_text column CRUD::column('fake-text') ->label('Fake Text') ->type('editable_text') ->fake(true); // demo fake editable_switch column CRUD::column('fake-switch') ->label('Fake Switch') ->type('editable_switch') ->fake(true); // demo fake editable_checkbox column CRUD::column('fake-checkbox') ->label('Fake Checkbox') ->type('editable_checkbox') ->fake(true); // demo fake editable_select column CRUD::column('fake-select') ->label('Fake Select') ->type('editable_select') ->options(['one' => 'One', 'two' => 'Two', 'three' => 'Three']) ->fake(true); } protected function setupMinorUpdateOperation() { $this->crud->setValidation(MonsterRequest::class); } } ================================================ FILE: app/Http/Controllers/Admin/FieldMonsterCrudController.php ================================================ crud->setModel(\App\Models\Monster::class); $this->crud->setRoute(config('backpack.base.route_prefix').'/field-monster'); $this->crud->setEntityNameStrings('field monster', 'field monsters'); $this->crud->set('show.setFromDb', false); } protected function setupCreateOperation() { $this->setupFieldsForTopScenarios(); parent::setupCreateOperation(); // load all the fields as a JS array Widget::add()->type('script')->content('assets/js/monster/fields.js'); // then test each crud.field() method individually Widget::add()->type('script')->content('assets/js/monster/test-hide-field.js'); Widget::add()->type('script')->content('assets/js/monster/test-show-field.js'); Widget::add()->type('script')->content('assets/js/monster/test-disable-field.js'); Widget::add()->type('script')->content('assets/js/monster/test-enable-field.js'); Widget::add()->type('script')->content('assets/js/monster/test-require-field.js'); Widget::add()->type('script')->content('assets/js/monster/test-unrequire-field.js'); Widget::add()->type('script')->content('assets/js/monster/test-custom-field.js'); Widget::add()->type('script')->content('assets/js/monster/test-onchange-field.js'); } protected function setupFieldsForTopScenarios() { Widget::add()->type('script')->content('assets/js/monster/test-top-scenarios.js'); CRUD::field('notice')->type('custom_html')->value('This tab shows the Top 10 Scenarios that the crud.field() JS library covers. These fields will NOT hide/show/etc when the buttons above are clicked, that\'s ok, don\'t worry.
')->tab('Top 10 Scenarios'); // MUST: when a checkbox is checked, show a second field; CRUD::field('visible')->type('checkbox')->fake(true)->tab('Top 10 Scenarios'); CRUD::field('visible_where')->type('text')->fake(true)->wrapperAttributes(['class' => 'form-group col-sm-11 offset-1'])->tab('Top 10 Scenarios'); // MUST: when a checkbox is checked, show a second field AND un-disable/un-readonly it; CRUD::field('displayed')->type('checkbox')->fake(true)->tab('Top 10 Scenarios'); CRUD::field('displayed_where')->type('text')->fake(true)->wrapperAttributes(['class' => 'form-group col-sm-11 offset-1'])->tab('Top 10 Scenarios'); // MUST: when a radio has something specific selected, show a second field; CRUD::field('type')->type('radio')->options(['Type A', 'Type B', 'Type C', 'Other'])->inline(true)->fake(true)->tab('Top 10 Scenarios'); // when type is Other, show an input to specify its type CRUD::field('custom_type')->type('text')->fake(true)->wrapperAttributes(['class' => 'form-group col-sm-11 offset-1'])->tab('Top 10 Scenarios'); // MUST: when a select has something specific selected, show a second field; CRUD::field('parent')->type('select_from_array')->options([ 1 => 'Parent 1', 2 => 'Parent 2', 3 => 'Parent 3', 4 => 'Parent 4', 5 => 'Parent 5', 6 => 'Parent 6', 6 => 'Other', ])->fake(true)->wrapperAttributes(['class' => 'form-group col-sm-6'])->tab('Top 10 Scenarios'); CRUD::field('custom_parent')->type('text')->fake(true)->wrapperAttributes(['class' => 'form-group col-sm-6'])->tab('Top 10 Scenarios'); CRUD::field('another_separator')->type('custom_html')->value('
')->tab('Top 10 Scenarios'); // MUST: when a checkbox is checked AND a select has a certain value, then show a third field; // done, re-used displayed and parent // MUST: when a checkbox is checked OR a select has a certain value, then show a third field; // done, re-used displayed and parent // SHOULD: when a select is a certain value, show a second field; if it's another value, show a third field; // done, re-used category // SHOULD: when a checkbox is checked, automatically check a different checkbox or radio; // done, re-used visible, it now checks displayed // COULD: when a text input is written into, write into a second input (eg. slug); CRUD::field('title')->size(6)->tab('Top 10 Scenarios'); CRUD::field('title_url_segment')->size(6)->tab('Top 10 Scenarios'); // COULD: when multiple inputs change, change a last input to calculate the total or smth; CRUD::field('full_price')->type('number')->size(4)->tab('Top 10 Scenarios'); CRUD::field('discounted_price')->type('number')->size(4)->tab('Top 10 Scenarios'); CRUD::field('discount_percentage')->type('number')->size(4)->tab('Top 10 Scenarios'); CRUD::field('repeatable_example_1')->type('repeatable')->tab('Top 10 Scenarios')->store_in('extras')->subfields([ [ 'name' => 'yes_or_no', 'type' => 'select2_from_array', 'label' => 'Yes or No', 'options' => ['no' => 'no', 'yes'=> 'yes'], ], [ 'name' => 'if_no', 'type' => 'text', ], [ 'name' => 'if_yes', 'type' => 'text', ], ]); CRUD::field('repeatable_example_2')->type('repeatable')->tab('Top 10 Scenarios')->store_in('extras')->subfields([ [ 'name' => 'how_many', 'type' => 'number', 'label' => 'How Many?', 'min' => 1, 'step' => 1, ], [ 'name' => 'if_more_than_10', 'type' => 'text', ], [ 'name' => 'if_more_than_20', 'type' => 'text', ], ]); CRUD::field('live_validation_select')->type('select2_from_array')->options([ 'Zero', 'One', 'Two', 'Three', ])->tab('Top 10 Scenarios')->size(4); CRUD::field('live_validation_text')->type('text')->tab('Top 10 Scenarios')->size(4); CRUD::field('live_validation_number')->type('number')->step(1)->tab('Top 10 Scenarios')->size(4); } } ================================================ FILE: app/Http/Controllers/Admin/FluentMonsterCrudController.php ================================================ fetch(\App\Models\Product::class); } public function fetchIcon() { return $this->fetch(\App\Models\Icon::class); } public function setupListOperation() { CRUD::setOperationSetting('responsiveTable', false); CRUD::column('text'); CRUD::column('textarea'); CRUD::column('image')->type('image'); CRUD::column('base64_image')->type('image')->label('Base64 Image'); CRUD::column('checkbox') ->type('boolean') ->label('Boolean') ->options([0 => 'Yes', 1 => 'No']) ->wrapper([ 'element' => 'span', 'class' => static function ($crud, $column, $entry) { return 'badge rounded-pill bg-'.($entry->{$column['name']} ? 'danger' : 'success'); }, ]); CRUD::column('checkbox')->key('check')->label('Agreed')->type('check'); CRUD::column('created_at')->type('closure')->label('Created At')->function(function ($entry) { return 'Created on '.$entry->created_at; }); CRUD::column('date')->type('date'); CRUD::column('datetime')->type('datetime'); CRUD::column('email')->type('email')->label('Email Address'); // show both text and email values in one column // this column is here to demo and test the custom searchLogic functionality CRUD::column('model_function') ->type('model_function') ->label('Text and Email') ->function_name('getTextAndEmailAttribute') ->searchLogic(function ($query, $column, $searchTerm) { $query->orWhere('email', 'like', '%'.$searchTerm.'%'); $query->orWhere('text', 'like', '%'.$searchTerm.'%'); }); CRUD::column('number')->type('number'); CRUD::column('radio') ->type('radio') ->options([0 => 'Draft', 1 => 'Published', 2 => 'Other']); CRUD::column('select') ->type('select') ->entity('category') ->attribute('name') ->model("Backpack\NewsCRUD\app\Models\Category") ->wrapper([ 'href' => function ($crud, $column, $entry, $related_key) { return backpack_url('category/'.$related_key.'/show'); }, ]); CRUD::column('select_from_array') ->type('select_from_array') ->label('Select_from_array') ->options(['one' => 'One', 'two' => 'Two', 'three' => 'Three']); CRUD::column('tags') ->type('select_multiple') ->label('Select_multiple') ->entity('tags') ->attribute('name') ->model('Backpack\NewsCRUD\app\Models\Tag') ->wrapper([ 'href' => function ($crud, $column, $entry, $related_key) { return backpack_url('tag/'.$related_key.'/show'); }, ]); CRUD::column('video')->type('video'); CRUD::enableDetailsRow(); CRUD::setDetailsRowView('vendor.backpack.crud.details_row.monster'); CRUD::enableExportButtons(); CRUD::button('open_google')->stack('line')->modelFunction('openGoogle')->makeFirst(); $this->addCustomCrudFilters(); } public function setupShowOperation() { $this->setupListOperation(); CRUD::set('show.contentClass', 'col-md-12'); CRUD::column('easymde')->type('markdown')->label('Markdown (EasyMDE)'); CRUD::column('table')->type('table')->columns([ 'name' => 'Name', 'desc' => 'Description', 'price' => 'Price', ]); CRUD::column('name')->type('array_count')->key('table_count')->label('Array count'); CRUD::column('extras')->type('array')->key('array')->label('Array'); CRUD::column('table') ->key('multidimensional_array') ->type('multidimensional_array') ->label('Multidimensional Array') ->visible_key('name'); CRUD::column('category') ->label('Model Function Attribute') ->type('model_function_attribute') ->function_name('getCategory') ->attribute('name'); CRUD::column('number')->type('phone')->label('Phone')->key('phone'); CRUD::column('upload_multiple')->type('upload_multiple')->prefix('uploads/'); } protected function setupCreateOperation() { CRUD::setValidation(StoreRequest::class); CRUD::setOperationSetting('contentClass', 'col-md-12 bold-labels'); CRUD::field('text')->type('text')->label('Text') ->tab('Simple')->size(6); CRUD::field('email')->type('email')->label('Email') ->tab('Simple')->wrapper(['class' => 'form-group col-md-6']); CRUD::field('textarea')->type('textarea')->label('Textarea')->tab('Simple'); CRUD::field('number')->type('number')->label('Number') ->tab('Simple')->wrapper(['class' => 'form-group col-md-3']); CRUD::field('float')->type('number')->label('Float')->attributes(['step' => 'any']) ->tab('Simple')->wrapper(['class' => 'form-group col-md-3']); CRUD::field('number_with_prefix')->type('number') ->prefix('$')->fake(true)->store_in('extras') ->tab('Simple')->wrapper(['class' => 'form-group col-md-3']); CRUD::field('number_with_suffix')->type('number') ->suffix('.00')->fake(true)->store_in('extras') ->tab('Simple')->wrapper(['class' => 'form-group col-md-3']); CRUD::field('text_with_both_prefix_and_suffix')->type('number') ->prefix('@')->suffix("")->fake(true)->store_in('extras') ->tab('Simple')->wrapper(['class' => 'form-group col-md-6']); CRUD::field('password')->type('password') ->tab('Simple')->wrapper(['class' => 'form-group col-md-6']); CRUD::field('radio')->type('radio')->label('Status (radio)')->options([ // the key will be stored in the db, the value will be shown as label; 0 => 'Draft', 1 => 'Published', 2 => 'Other', ])->inline(true)->tab('Simple'); CRUD::field('checkbox')->type('checkbox')->label('I have not read the terms and conditions and I never will (checkbox)')->tab('Simple'); CRUD::field('switch')->type('switch')->label('I have not read the terms and conditions and I never will (switch)')->tab('Simple')->fake(true); CRUD::field('hidden')->type('hidden')->default('hidden value')->tab('Simple'); // ----------------- // DATE, TIME AND SPACE tab // ----------------- CRUD::field('week') ->type('week') ->wrapper(['class' => 'form-group col-md-6']) ->tab('Time and space'); CRUD::field('month') ->type('month') ->wrapper(['class' => 'form-group col-md-6']) ->tab('Time and space'); CRUD::field('date') ->type('date') ->label('Date (HTML5 spec)') ->attributes([ 'pattern' => '[0-9]{4}-[0-9]{2}-[0-9]{2}', 'placeholder' => 'yyyy-mm-dd', ]) ->wrapper(['class' => 'form-group col-md-6']) ->tab('Time and space'); CRUD::field('date_picker') ->type('date_picker') ->label('Date (jQuery plugin)') ->date_picker_options([ 'todayBtn' => true, 'format' => 'dd-mm-yyyy', 'language' => 'en', ]) ->wrapper(['class' => 'form-group col-md-6']) ->tab('Time and space'); CRUD::field('datetime') ->type('datetime') ->label('Datetime (HTML5 spec)') ->wrapper(['class' => 'form-group col-md-6']) ->tab('Time and space'); CRUD::field('datetime_picker') ->type('datetime_picker') ->label('Datetime picker (jQuery plugin)') ->datetime_picker_options([ 'format' => 'DD/MM/YYYY HH:mm', 'language' => 'en', ]) ->wrapper(['class' => 'form-group col-md-6']) ->tab('Time and space'); CRUD::field('start_date,end_date') ->type('date_range') ->label('Date Range') ->default(['2020-03-28 01:01', '2020-04-05 02:00']) ->date_range_options([ 'timePicker' => true, 'locale' => ['format' => 'DD/MM/YYYY HH:mm'], ]) ->tab('Time and space'); // ----------------- // SELECTS tab // ----------------- CRUD::field('select_1_n_heading')->type('custom_html')->tab('Selects') ->value('
1-n Relationships (HasOne, BelongsTo)
'); CRUD::field('select') ->type('select') ->label('Select (HTML Spec Select Input for 1-n relationship)') ->entity('category') ->attribute('name') ->model('Backpack\NewsCRUD\app\Models\Category') ->wrapper(['class' => 'form-group col-md-6']) ->tab('Selects'); CRUD::field('select2') ->type('select2') ->label('Select2 (1-n relationship)') ->entity('category') ->attribute('name') ->model('Backpack\NewsCRUD\app\Models\Category') ->wrapper(['class' => 'form-group col-md-6']) ->tab('Selects'); CRUD::field('select2_from_ajax') ->type('select2_from_ajax') ->label("Article (select2_from_ajax for a 1-n relationship)") ->entity('article') ->attribute('title') ->model('Backpack\NewsCRUD\app\Models\Article') ->data_source(url('api/article')) ->method('POST') ->placeholder('Select an article') ->minimum_input_length(2) ->wrapper(['class' => 'form-group col-md-6']) ->tab('Selects'); CRUD::field('icon_id') ->type('relationship') ->label('Relationship (1-n with InlineCreate; no AJAX)'.backpack_new_badge('New in 4.1')) // ->entity('icon') ->attribute('name') // ->data_source(backpack_url('monster/fetch/icon')) ->inline_create(true) ->wrapper(['class' => 'form-group col-md-6']) ->tab('Selects'); CRUD::field('select_n_n_heading')->type('custom_html')->tab('Selects') ->value('
n-n Relationship with Pivot Table (HasMany, BelongsToMany)
'); CRUD::field('tags') ->type('select_multiple') ->label('Select_multiple (n-n relationship with pivot table)') ->entity('tags') ->attribute('name') ->model('Backpack\NewsCRUD\app\Models\Tag') ->pivot(true) ->tab('Selects'); CRUD::field('categories') ->type('select2_multiple') ->label('Select2_multiple (n-n relationship with pivot table)') ->entity('categories') ->attribute('name') ->model(\Backpack\NewsCRUD\app\Models\Category::class) ->allows_null(true) ->pivot(true) ->wrapper(['class' => 'form-group col-md-6']) ->tab('Selects'); CRUD::field('articles') ->type('select2_from_ajax_multiple') ->label("Articles (select2_from_ajax_multiple for an n-n relationship with pivot table)") ->entity('articles') ->attribute('title') ->model(\Backpack\NewsCRUD\app\Models\Article::class) ->data_source(url('api/article')) ->placeholder('Select one or more articles') ->minimum_input_length(2) ->method('post') ->pivot(true) ->wrapper(['class' => 'form-group col-md-6']) ->tab('Selects'); CRUD::field('products') ->type('relationship') ->label('Relationship (n-n with InlineCreate; Fetch using AJAX)'.backpack_new_badge('New in 4.1')) ->entity('products') // ->attribute('name') ->ajax(true) ->data_source(backpack_url('monster/fetch/product')) // ->inline_create(true) // TODO: make it work this way too ->inline_create(['entity' => 'product']) // ->wrapper(['class' => 'form-group col-md-6']) ->tab('Selects'); CRUD::field('select_heading')->type('custom_html')->tab('Selects') ->value('
No Relationship
'); CRUD::field('select_from_array') ->type('select_from_array') ->label('Select_from_array (no relationship, 1-1 or 1-n)') ->options(['one' => 'One', 'two' => 'Two', 'three' => 'Three']) ->allows_null(true) ->allows_multiple(false) ->wrapper(['class' => 'form-group col-md-6']) ->tab('Selects'); CRUD::field('select2_from_array') ->type('select2_from_array') ->label('Select2_from_array (no relationship, 1-1 or 1-n)') ->options(['one' => 'One', 'two' => 'Two', 'three' => 'Three']) ->allows_null(true) ->allows_multiple(false) ->wrapper(['class' => 'form-group col-md-6']) ->tab('Selects'); CRUD::field('select_and_order') ->type('select_and_order') ->label('Select and order') ->options([ 1 => 'Option 1', 2 => 'Option 2', 3 => 'Option 3', 4 => 'Option 4', 5 => 'Option 5', 6 => 'Option 6', 7 => 'Option 7', 8 => 'Option 8', 9 => 'Option 9', ]) ->fake(true) ->tab('Selects'); CRUD::field('wysiwyg')->type('summernote')->label('WYSIWYG')->tab('Editors'); CRUD::field('icondummy') ->type('relationship') ->label('Relationship to non-nullable model (belongs_to_non_nullable)') ->entity('icondummy') ->attribute('icon') ->model(\App\Models\Icon::class) ->allows_null(false) ->tab('Selects'); // ----------------- // UPLOADS tab // ----------------- if (app('env') == 'production') { CRUD::field('separator') ->type('custom_html') ->value('

Note: In the online demo we\'ve restricted the upload and media library fields a lot, or hidden them entirely. To test them out, you can download and install this demo admin panel in your local environment.

') ->tab('Uploads'); } CRUD::field('browse') ->type('browse') ->label('Browse (using elFinder)') ->tab('Uploads'); CRUD::field('browse_multiple') ->type('browse_multiple') ->label('Browse multiple') ->sortable(true) // ->multiple(true) // ->mime_types(null) ->tab('Uploads'); CRUD::field('upload') ->type('upload') ->label('Upload') ->upload(true) ->disk('uploads') ->tab('Uploads'); CRUD::field('upload_multiple') ->type('upload_multiple') ->upload(true) ->tab('Uploads'); CRUD::field('base64_image') ->type('base64_image') ->label('Base64 Image - includes cropping') ->crop(true) ->filename(null) ->aspect_ratio(1) ->src(null) // null to read straight from DB, else model accessor ->tab('Uploads'); CRUD::field('image') ->type('image') ->label('Image - includes cropping') ->upload(true) ->crop(true) ->aspect_ratio(1) ->src(null) // null to read straight from DB, else model accessor ->tab('Uploads'); // ----------------- // BIG TEXTS tab // ----------------- CRUD::field('easymde') ->type('easymde') ->label('EasyMDE - markdown editor') ->tab('Big texts') ->fake(true); CRUD::field('summernote') ->type('summernote') ->label('Summernote editor') ->tab('Big texts'); CRUD::field('tinymce') ->type('tinymce') ->label('TinyMCE') ->tab('Big texts'); // ----------------- // MISCELLANEOUS tab // ----------------- CRUD::field('color') ->type('color') ->label('Color picker (HTML5 spec)') ->wrapper(['class' => 'form-group col-md-6']) ->tab('Miscellaneous'); CRUD::field('video') ->type('video') ->label('Video - link to video file on Youtube or Vimeo') ->tab('Miscellaneous') ->wrapper(['class' => 'form-group col-md-5']); CRUD::field('range') ->type('range') ->label('range') // optional ->attributes([ 'min' => 0, 'max' => 10, ]) ->tab('Miscellaneous') ->wrapper(['class' => 'form-group col-md-5']); CRUD::field('icon_picker') ->type('icon_picker') ->label('Icon Picker') ->iconset('fontawesome') ->wrapper(['class' => 'form-group col-md-2']) ->tab('Miscellaneous'); CRUD::field('table') ->type('table') ->label('Table') ->columns([ 'name' => 'Name', 'desc' => 'Description', 'price' => 'Price', ]) ->min(0) ->max(5) ->tab('Miscellaneous'); CRUD::field('fake_table') ->type('table') ->label('Fake Table') ->fake(true) ->columns([ 'name' => 'Name', 'desc' => 'Description', 'price' => 'Price', ]) ->min(0) ->max(5) ->tab('Miscellaneous'); CRUD::field('url') ->type('url') ->label('URL') ->tab('Miscellaneous'); CRUD::field('url')->remove(); } protected function setupUpdateOperation() { $this->setupCreateOperation(); } protected function addCustomCrudFilters() { CRUD::filter('checkbox') ->type('simple') ->label('Simple') ->whenActive(function () { CRUD::addClause('where', 'checkbox', '1'); }); CRUD::filter('select_from_array') ->type('dropdown') ->label('Dropdown') ->values(['one' => 'One', 'two' => 'Two', 'three' => 'Three']) ->whenActive(function ($value) { CRUD::addClause('where', 'select_from_array', $value); }); CRUD::filter('text') ->type('text') ->label('Text') ->whenActive(function ($value) { CRUD::addClause('where', 'text', 'LIKE', "%$value%"); }); CRUD::filter('number') ->type('range') ->label('Range') ->label_from('min value') ->label_to('max value') ->whenActive(function ($value) { $range = json_decode($value); if ($range->from && $range->to) { CRUD::addClause('where', 'number', '>=', (float) $range->from); CRUD::addClause('where', 'number', '<=', (float) $range->to); } }); CRUD::filter('date') ->type('date') ->label('Date') ->whenActive(function ($value) { CRUD::addClause('where', 'date', '=', $value); }); CRUD::filter('date_range') ->type('date_range') ->label('Date range') ->whenActive(function ($value) { $dates = json_decode($value); CRUD::addClause('where', 'date', '>=', $dates->from); CRUD::addClause('where', 'date', '<=', $dates->to); }); CRUD::filter('select2') ->type('select2') ->label('Select2') ->values(function () { return \Backpack\NewsCRUD\app\Models\Category::all()->keyBy('id')->pluck('name', 'id')->toArray(); })->whenActive(function ($value) { CRUD::addClause('where', 'select2', $value); }); CRUD::filter('select2_multiple') ->type('select2_multiple') ->label('S2 multiple') ->values(function () { return \Backpack\NewsCRUD\app\Models\Category::all()->keyBy('id')->pluck('name', 'id')->toArray(); })->whenActive(function ($values) { foreach (json_decode($values) as $key => $value) { CRUD::addClause('orWhere', 'select2', $value); } }); CRUD::filter('select2_from_ajax') ->type('select2_ajax') ->label('S2 Ajax') ->placeholder('Pick an article') ->values(url('api/article-search')) ->method('POST') ->whenActive(function ($value) { CRUD::addClause('where', 'select2_from_ajax', $value); }); } } ================================================ FILE: app/Http/Controllers/Admin/HeroCrudController.php ================================================ label('Stories'.backpack_new_badge()) ->subfields([ [ 'name' => 'name', ], [ 'name' => 'monsters', 'type' => 'select2_multiple', 'model' => \App\Models\Monster::class, 'entity' => 'monsters', 'attribute' => 'text', 'pivot' => true, ], ]) ->hint('Select the related Story over a belongsToMany relationship (n-n) with extra pivot fields.'); } /** * Define what happens when the Update operation is loaded. * * @see https://backpackforlaravel.com/docs/crud-operation-update * * @return void */ protected function setupUpdateOperation() { $this->setupCreateOperation(); } public static function getMonsterSubfields() { $subfields = CaveCrudController::getMonsterSubfields(); /* foreach ($subfields as $key => $subfield) { // fake fields don't work here for some reason // TODO: fix the problem and remove this if (isset($subfield['fake']) && $subfield['fake']) { unset($subfields[$key]); continue; } // multiple fields don't work here for some reason // TODO: fix the problem and remove this if (isset($subfield['pivot']) && $subfield['pivot']) { unset($subfields[$key]); continue; } // fields from the "relationship" tab don't work here for some reason // TODO: fix the problem and remove this if (isset($subfield['tab']) && $subfield['tab'] == 'Relationships') { unset($subfields[$key]); continue; } } */ return $subfields; } } ================================================ FILE: app/Http/Controllers/Admin/IconCrudController.php ================================================ crud->setModel(\App\Models\Icon::class); $this->crud->setRoute(config('backpack.base.route_prefix').'/icon'); $this->crud->setEntityNameStrings('icon', 'icons'); } protected function setupListOperation() { $this->crud->addColumns(['name', 'icon']); $this->crud->addFilter([ 'type' => 'date_range', 'name' => 'created_at', 'label' => 'Created At', ], null, function ($value) { $value = json_decode($value, true); // if the filter is active if ($value) { $this->crud->addClause('where', 'created_at', '>=', $value['from']); $this->crud->addClause('where', 'created_at', '<=', $value['to']); } }); } protected function setupCreateOperation() { $this->crud->setValidation(StoreRequest::class); $this->crud->addField('name'); $this->crud->addField([ 'label' => 'Icon', 'name' => 'icon', 'type' => 'icon_picker', 'iconset' => 'fontawesome4', // options: fontawesome, glyphicon, ionicon, weathericon, mapicon, octicon, typicon, elusiveicon, materialdesign ]); } protected function setupUpdateOperation() { $this->setupCreateOperation(); } } ================================================ FILE: app/Http/Controllers/Admin/MeetingCrudController.php ================================================ 'informational', 'title' => 'Informational', 'location' => 'In-person'], ['id' => 'brainstorming', 'title' => 'Brainstorming', 'location' => 'In-person'], ['id' => 'decision-making', 'title' => 'Decision Making', 'location' => 'In-person'], ['id' => 'problem-solving', 'title' => 'Problem Solving', 'location' => 'In-person'], ['id' => 'status-update', 'title' => 'Status Update', 'location' => 'In-person'], ['id' => 'training', 'title' => 'Training', 'location' => 'Virtual'], ['id' => 'feedback', 'title' => 'Feedback', 'location' => 'Virtual'], ['id' => 'performance-review', 'title' => 'Performance Review', 'location' => 'Virtual'], ['id' => 'planning', 'title' => 'Planning', 'location' => 'Virtual'], ['id' => 'social', 'title' => 'Social', 'location' => 'Virtual'], ['id' => 'networking', 'title' => 'Networking', 'location' => 'Hybrid'], ['id' => 'interview', 'title' => 'Interview', 'location' => 'Hybrid'], ['id' => 'presentation', 'title' => 'Presentation', 'location' => 'Hybrid'], ['id' => 'review', 'title' => 'Review', 'location' => 'Hybrid'], ['id' => 'other', 'title' => 'Other', 'location' => 'Hybrid'], ]; /** * Configure the CrudPanel object. Apply settings to all operations. */ public function setup(): void { CRUD::setModel(Meeting::class); CRUD::setRoute(config('backpack.base.route_prefix').'/meeting'); CRUD::setEntityNameStrings(__('meeting'), __('meetings')); } public function getCalendarFieldsMap() { return [ 'title' => 'title', 'start' => 'start', 'end' => 'end', 'background_color' => 'background_color', 'text_color' => 'text_color', 'all_day' => 'all_day', 'email' => 'email', 'number' => 'number', ]; } public function setupCalendarOperation() { $this->crud->setOperationSetting('initial-view', 'dayGridMonth'); $this->crud->setOperationSetting('views', ['dayGridMonth', 'timeGridWeek', 'timeGridDay']); $this->crud->setOperationSetting('editable', true); $this->crud->setOperationSetting('background_color', '#3788d8'); $this->crud->setOperationSetting('text_color', '#ffffff'); $this->addCalendarLineButton( action: 'sms', label: 'Send SMS', url: fn (Meeting $entry) => url($this->crud->route.'/'.$entry->id.'/s-m-s'), group: 'send' ); $this->addCalendarLineButton( action: 'email', label: 'Send Email', url: fn (Meeting $entry) => url($this->crud->route.'/'.$entry->id.'/s-m-s?email='.$entry->email), group: 'send' ); $this->addCalendarLineButton( action: 'call', label: 'Call', url: fn (Meeting $entry) => url($this->crud->route.'/'.$entry->id.'/s-m-s?call='.$entry->number), group: 'call' ); $this->addCalendarLineButton( action: 'alert', label: 'Javascript Event', group: 'alert', properties: [ 'message' => 'Alert message!', ], ); Widget::add() ->type('script') ->content('assets/js/meetings.js'); } /** * Define what happens when the List operation is loaded. */ protected function setupListOperation(): void { CRUD::column('title') ->type('text'); CRUD::column('types') ->type('text') ->value(fn (Meeting $entry): string => collect($entry->types)->map(fn ($type) => ($type['title'] ?? '').' ('.($type['location'] ?? '').')')->join(', ')); CRUD::column('start') ->type('datetime'); CRUD::column('end') ->type('datetime'); CRUD::column('background_color') ->showColorHex(false) ->type('color'); } /** * Define what happens when the Create operation is loaded. */ protected function setupCreateOperation(): void { CRUD::setValidation(MeetingRequest::class); $start = request()->has('start') ? Carbon::parse(request('start')) : null; $end = request()->has('end') ? Carbon::parse(request('end')) : null; CRUD::field('title') ->type('text'); CRUD::field('types') ->type('select2_json_from_api') ->data_source(backpack_url('meeting/fetch/types')) ->method('POST') ->default($this->meetingTypes[0]) ->attributes_to_store(['id', 'title', 'location']) ->attribute('title') ->multiple(true) ->minimum_input_length(0); CRUD::field('email') ->wrapper(['class' => 'form-group col-md-6']) ->type('text'); CRUD::field('number') ->wrapper(['class' => 'form-group col-md-6']) ->type('phone'); CRUD::field('all_day') ->type('switch'); CRUD::field('start') ->type('datetime') ->wrapper(['class' => 'form-group col-md-6']) ->value($start); CRUD::field('end') ->type('datetime') ->wrapper(['class' => 'form-group col-md-6']) ->value($end); CRUD::field('separator') ->type('custom_html') ->value(''); CRUD::field('background_color') ->type('color') ->wrapper(['class' => 'form-group col-md-6']) ->default('#3788d8'); CRUD::field('text_color') ->type('color') ->wrapper(['class' => 'form-group col-md-6']) ->default('#ffffff'); Widget::add() ->type('script') ->content('assets/js/meeting.js'); } /** * Define what happens when the Update operation is loaded. */ protected function setupUpdateOperation(): void { $this->setupCreateOperation(); } /** * Define the types to fetch. */ public function fetchTypes() { return collect($this->meetingTypes) ->filter(fn ($value): bool => str_contains(strtolower($value['title']), strtolower(request('q')))); } } ================================================ FILE: app/Http/Controllers/Admin/MonsterCrudController.php ================================================ crud->setModel(\App\Models\Monster::class); $this->crud->setRoute(config('backpack.base.route_prefix').'/monster'); $this->crud->setEntityNameStrings('monster', 'monsters'); $this->crud->set('show.setFromDb', false); } public function fetchProduct() { return $this->fetch(\App\Models\Product::class); } public function fetchProducts() { return $this->fetch(\App\Models\Product::class); } public function fetchIcon() { return $this->fetch(\App\Models\Icon::class); } public function fetchArticle() { return $this->fetch(\App\Models\Article::class); } public function fetchPaginatedTypes() { $types = [ ['id' => 'informational', 'title' => 'Informational', 'location' => 'In-person'], ['id' => 'brainstorming', 'title' => 'Brainstorming', 'location' => 'In-person'], ['id' => 'decision-making', 'title' => 'Decision Making', 'location' => 'In-person'], ['id' => 'problem-solving', 'title' => 'Problem Solving', 'location' => 'In-person'], ['id' => 'training', 'title' => 'Training', 'location' => 'Virtual'], ['id' => 'planning', 'title' => 'Planning', 'location' => 'Virtual'], ['id' => 'social', 'title' => 'Social', 'location' => 'Virtual'], ['id' => 'networking', 'title' => 'Networking', 'location' => 'Hybrid'], ['id' => 'interview', 'title' => 'Interview', 'location' => 'Hybrid'], ['id' => 'review', 'title' => 'Review', 'location' => 'Hybrid'], ]; Collection::macro('paginate', function (int $perPage = 15, ?int $page = null, array $options = []) { $page ??= \Illuminate\Pagination\Paginator::resolveCurrentPage() ?? 1; return new \Illuminate\Pagination\LengthAwarePaginator($this->forPage($page, $perPage)->toArray(), $this->count(), $perPage, $page, $options); }); return collect($types) ->filter(fn (array $value): bool => str_contains(strtolower($value['title']), strtolower(request('q')))) ->paginate(4); } public function fetchSimpleTypes() { $types = [ 'informational' => 'Informational', 'brainstorming' => 'Brainstorming', 'decision-making' => 'Decision Making', 'problem-solving' => 'Problem Solving', 'training' => 'Training', 'planning' => 'Planning', 'social' => 'Social', 'networking' => 'Networking', 'interview' => 'Interview', 'review' => 'Review', ]; return collect($types)->filter(fn (string $value): bool => str_contains(strtolower($value), strtolower(request('q')))); } public function setupListOperation() { $this->crud->addColumns([ [ 'name' => 'text', 'tab' => 'Simple', ], [ 'name' => 'textarea', 'tab' => 'Simple', ], [ 'name' => 'articles', // relationship column 'tab' => 'Simple', ], [ 'name' => 'image', // The db column name 'label' => 'Image', // Table column heading 'type' => 'image', 'tab' => 'Uploads', ], [ 'name' => 'base64_image', // The db column name 'label' => 'Base64 Image'.backpack_pro_badge(), // Table column heading 'type' => 'image', 'tab' => 'Uploads', ], [ 'name' => 'checkbox', 'label' => 'Boolean', 'type' => 'boolean', // optionally override the Yes/No texts 'options' => [0 => 'Yes', 1 => 'No'], 'tab' => 'Simple', 'wrapper' => [ 'element' => 'span', 'class' => function ($crud, $column, $entry, $related_key) { if ($column['text'] == 'Yes') { return 'badge rounded-pill bg-success text-white'; } return 'badge rounded-pill bg-danger text-white'; }, ], ], [ 'name' => 'checkbox', // The db column name 'key' => 'agreed', 'label' => 'Agreed', // Table column heading 'type' => 'checkbox', 'tab' => 'Simple', ], [ 'name' => 'created_at', 'label' => 'Created At', 'type' => 'closure', 'function' => function ($entry) { return 'Created on '.$entry->created_at; }, 'tab' => 'Miscellaneous', ], [ 'name' => 'date', // The db column name 'label' => 'Date', // Table column heading 'type' => 'date', 'tab' => 'Time and space', ], [ 'name' => 'datetime', // The db column name 'label' => 'Datetime', // Table column heading 'type' => 'datetime', 'tab' => 'Time and space', ], [ 'name' => 'email', // The db column name 'label' => 'Email Address', // Table column heading 'type' => 'email', 'tab' => 'Simple', ], [ 'name' => 'status', 'type' => 'enum', 'label' => 'Enum', 'enum_function' => 'getReadableStatus', 'tab' => 'Simple', ], [ // show both text and email values in one column // this column is here to demo and test the custom searchLogic functionality 'name' => 'model_function', 'label' => 'Text and Email', // Table column heading 'type' => 'model_function', 'function_name' => 'getTextAndEmailAttribute', // the method in your Model 'searchLogic' => function ($query, $column, $searchTerm) { $query->orWhere('email', 'like', '%'.$searchTerm.'%'); $query->orWhere('text', 'like', '%'.$searchTerm.'%'); }, 'escaped' => true, 'tab' => 'Miscellaneous', ], [ 'name' => 'number', // The db column name 'label' => 'Number', // Table column heading 'type' => 'number', 'tab' => 'Simple', ], [ 'name' => 'radio', 'label' => 'Radio', 'type' => 'radio', 'options' => [0 => 'Draft', 1 => 'Published', 2 => 'Other'], 'tab' => 'Simple', ], [ // 1-n relationship 'label' => 'Select', // Table column heading 'type' => 'select', 'name' => 'select', // the column that contains the ID of that connected entity; 'entity' => 'category', // the method that defines the relationship in your Model 'attribute' => 'name', // foreign key attribute that is shown to user 'model' => "Backpack\NewsCRUD\app\Models\Category", // foreign key model 'tab' => 'Selects', 'wrapper' => [ 'href' => function ($crud, $column, $entry, $related_key) { return backpack_url('category/'.$related_key.'/show'); }, ], ], [ // select_from_array 'name' => 'select_from_array', 'label' => 'Select_from_array', 'type' => 'select_from_array', 'options' => ['one' => 'One', 'two' => 'Two', 'three' => 'Three'], 'tab' => 'Selects', ], [ // select_multiple: n-n relationship (with pivot table) 'label' => 'Select_multiple', // Table column heading 'type' => 'select_multiple', 'name' => 'tags', // the method that defines the relationship in your Model 'entity' => 'tags', // the method that defines the relationship in your Model 'attribute' => 'name', // foreign key attribute that is shown to user 'model' => "Backpack\NewsCRUD\app\Models\Tag", // foreign key model 'tab' => 'Selects', 'wrapper' => [ 'href' => function ($crud, $column, $entry, $related_key) { return backpack_url('tag/'.$related_key.'/show'); }, ], ], [ // select_multiple: n-n relationship (with pivot table) 'label' => 'Relationship_count', // Table column heading 'type' => 'relationship_count', 'name' => 'categories', // the method that defines the relationship in your Model 'entity' => 'categories', // the method that defines the relationship in your Model 'tab' => 'Relationship', 'wrapper' => [ 'href' => function ($crud, $column, $entry, $related_key) { return backpack_url('category'); }, ], ], ]); $this->crud->enableDetailsRow(); $this->crud->setDetailsRowView('vendor.backpack.crud.details_row.monster'); $this->crud->enableExportButtons(); $this->crud->addButtonFromModelFunction('line', 'open_google', 'openGoogle', 'beginning'); //quickly create a button $this->crud->button('email')->stack('top')->view('crud::buttons.quick')->meta([ 'access' => true, 'label' => 'Quick Button', 'icon' => 'la la-fast-forward', 'wrapper' => [ // 'element' => 'a', 'href' => 'https://backpackforlaravel.com/docs/crud-buttons#creating-a-quick-button-1', 'target' => '_blank', 'title' => 'Creating a quick button', ], ]); $this->addCustomCrudFilters(); } public function setupShowOperation() { // add a widget Widget::add([ 'type' => 'datatable', 'controller' => 'App\Http\Controllers\Admin\IconCrudController', 'name' => 'icon_crud', 'section' => 'after_content', 'content' => [ 'header' => 'Icons for this monster', ], 'wrapper' => ['class'=> 'mb-3'], ]); Widget::add([ 'type' => 'datatable', 'controller' => 'App\Http\Controllers\Admin\ProductCrudController', 'name' => 'products_datatable', 'section' => 'after_content', 'content' => [ 'header' => 'Products for this monster', ], 'wrapper' => ['class'=> 'mb-3'], 'configure' => function ($crud, $entry = null) { // Customize which columns to show $crud->removeAllColumns(); $crud->addColumn(['name' => 'name', 'label' => 'Product Name']); $crud->addColumn(['name' => 'price', 'label' => 'Price']); // Get the current monster's products if ($entry) { $productIds = $entry->products->pluck('id')->toArray(); if (count($productIds) > 0) { // Configure the controller to only show products related to this monster $crud->addClause('whereIn', 'id', $productIds); } else { // Force an empty result when there are no products $crud->addClause('where', 'id', 0); // This will match no products } // Remove buttons that aren't needed for this embedded view // Disable features that aren't needed $crud->denyAccess(['create', 'update', 'delete']); $crud->disableResponsiveTable(); } }, ]); $this->crud->setOperationSetting('tabsEnabled', true); $this->setupListOperation(); $this->crud->set('show.contentClass', 'col-md-12'); $this->crud->addColumn([ // EasyMDE 'name' => 'easymde', 'key' => 'easymde_markdown', 'label' => 'Markdown'.backpack_pro_badge(), 'type' => 'markdown', 'tab' => 'WYSIWYG Editors', ]); $this->crud->addColumn([ // EasyMDE 'name' => 'easymde', 'label' => 'EasyMDE'.backpack_pro_badge(), 'type' => 'easymde', 'tab' => 'WYSIWYG Editors', ]); $this->crud->addColumn([ 'name' => 'ckeditor', 'type' => 'ckeditor', 'label' => 'Ckeditor'.backpack_pro_badge(), 'tab' => 'WYSIWYG Editors', ]); $this->crud->addColumn([ 'name' => 'summernote', 'type' => 'summernote', 'label' => 'Summernote', 'tab' => 'WYSIWYG Editors', ]); $this->crud->addColumn([ 'name' => 'tinymce', 'type' => 'tinymce', 'label' => 'TinyMCE'.backpack_pro_badge(), 'tab' => 'WYSIWYG Editors', ]); $this->crud->addColumn([ 'name' => 'features', 'label' => 'Features'.backpack_pro_badge(), 'type' => 'repeatable', 'fake' => true, 'subfields' => [ [ 'name' => 'feature', 'wrapper' => [ 'class' => 'col-md-3', ], ], [ 'name' => 'value', 'wrapper' => [ 'class' => 'col-md-6', ], ], [ 'name' => 'quantity', 'type' => 'number', 'wrapper' => [ 'class' => 'col-md-3', ], ], ], 'tab' => 'Miscellaneous', ]); $this->crud->addColumn([ 'name' => 'table', 'label' => 'Table'.backpack_pro_badge(), 'type' => 'table', 'tab' => 'Miscellaneous', 'columns' => [ 'name' => 'Name', 'desc' => 'Description', 'price' => 'Price', ], ]); $this->crud->addColumn([ 'name' => 'browse_multiple', // The db column name 'key' => 'browse_multiple_array', 'label' => 'Array'.backpack_pro_badge(), // Table column heading 'type' => 'array', 'tab' => 'Miscellaneous', ]); $this->crud->addColumn([ 'name' => 'table', // The db column name 'key' => 'table_count', 'label' => 'Array count'.backpack_pro_badge(), // Table column heading 'type' => 'array_count', 'tab' => 'Miscellaneous', ]); $this->crud->addColumn([ 'name' => 'table', // The db column name 'key' => 'multidimensional_array', 'label' => 'Multidimensional Array', // Table column heading 'type' => 'multidimensional_array', 'visible_key' => 'name', 'tab' => 'Miscellaneous', ]); $this->crud->addColumn([ 'name' => 'category', 'key' => 'category_name', 'label' => 'Model Function Attribute', // Table column heading 'type' => 'model_function_attribute', 'function_name' => 'getCategory', // the method in your Model 'attribute' => 'name', 'tab' => 'Miscellaneous', ]); $this->crud->addColumn([ 'name' => 'number', // The db column name 'key' => 'phone', 'label' => 'Phone', // Table column heading 'type' => 'phone', 'tab' => 'Simple', ]); $this->crud->addColumn([ 'name' => 'switch', 'label' => 'Switch', 'type' => 'switch', 'tab' => 'Simple', ]); $this->crud->addColumn([ 'name' => 'switch', 'key' => 'check', 'label' => 'Check', 'type' => 'check', 'tab' => 'Simple', ]); $this->crud->addColumn([ 'name' => 'my_custom_html', 'label' => 'Custom HTML', 'type' => 'custom_html', 'value' => 'Something', 'tab' => 'Miscellaneous', ]); $this->crud->addColumn([ 'name' => 'view', 'label' => 'Custom View', 'type' => 'view', 'view' => 'crud::columns.custom_view_column_example', 'tab' => 'Miscellaneous', ]); $this->crud->addColumn([ 'name' => 'features', 'key' => 'json_features', 'label' => 'JSON', 'type' => 'json', 'tab' => 'Miscellaneous', ]); $this->crud->addColumn([ 'name' => 'id', 'type' => 'number', 'label' => '#', 'orderable' => false, 'tab' => 'Simple', ]); $this->crud->addColumn([ 'name' => 'dummyproducts', 'type' => 'relationship', 'label' => 'Relationship'.backpack_pro_badge(), 'tab' => 'Relationship', ]); $this->crud->addColumn([ 'name' => 'address_google', 'type' => 'address_google', 'label' => 'Address Google'.backpack_pro_badge(), 'tab' => 'Time and space', ]); $this->crud->addColumn([ 'name' => 'roles', 'type' => 'checklist', 'label' => 'Checklist', 'entity' => 'roles', 'attribute' => 'name', 'tab' => 'Selects', ]); $this->crud->addColumn([ 'name' => 'color', 'type' => 'color', 'label' => 'Color', 'tab' => 'Miscellaneous', ]); $this->crud->addColumn([ 'name' => 'date_picker', 'type' => 'date_picker', 'label' => 'Date Picker'.backpack_pro_badge(), 'tab' => 'Time and space', ]); $this->crud->addColumn([ // Date_range 'name' => 'start_date,end_date', // two columns with a comma 'label' => 'Date Range'.backpack_pro_badge(), 'type' => 'date_range', 'tab' => 'Time and space', ]); $this->crud->addColumn([ 'name' => 'datetime_picker', 'type' => 'datetime_picker', 'label' => 'Datetime Picker'.backpack_pro_badge(), 'tab' => 'Time and space', ]); $this->crud->addColumn([ 'name' => 'location', 'type' => 'google_map', 'label' => 'Google Map'.backpack_pro_badge(), 'tab' => 'Time and space', ]); $this->crud->addColumn([ 'name' => 'icon_picker', 'type' => 'icon_picker', 'label' => 'Icon Picker'.backpack_pro_badge(), 'iconset' => 'fontawesome', 'tab' => 'Miscellaneous', ]); $this->crud->addColumn([ 'name' => 'month', 'type' => 'month', 'label' => 'Month', 'tab' => 'Time and space', ]); $this->crud->addColumn([ 'name' => 'range', 'type' => 'range', 'label' => 'Range', 'tab' => 'Miscellaneous', ]); $this->crud->addColumn([ 'name' => 'select_and_order', 'type' => 'select_and_order', 'label' => 'Select And Order'.backpack_pro_badge(), 'tab' => 'Selects', ]); $this->crud->addColumn([ 'name' => 'select_grouped_id', 'type' => 'select_grouped', 'label' => 'Select Grouped', 'entity' => 'article', 'tab' => 'Selects', ]); $this->crud->addColumn([ 'name' => 'select2', 'type' => 'select2', 'label' => 'Select2'.backpack_pro_badge(), 'entity' => 'categorySelect2', 'tab' => 'Selects', ]); $this->crud->addColumn([ 'name' => 'select2_from_ajax', 'type' => 'select2_from_ajax', 'label' => 'Select2 From Ajax'.backpack_pro_badge(), 'entity' => 'article', 'tab' => 'Selects', ]); $this->crud->addColumn([ 'name' => 'select2_from_array', 'type' => 'select2_from_array', 'label' => 'Select2 From Array'.backpack_pro_badge(), 'tab' => 'Selects', ]); $this->crud->addColumn([ 'name' => 'select2_grouped_id', 'type' => 'select2_grouped', 'label' => 'Select2 Grouped'.backpack_pro_badge(), 'entity' => 'article', 'tab' => 'Selects', ]); $this->crud->addColumn([ 'name' => 'categories', 'type' => 'select2_multiple', 'label' => 'Select2 Multiple'.backpack_pro_badge(), 'tab' => 'Selects', ]); $this->crud->addColumn([ 'name' => 'select2_nested_id', 'type' => 'select2_nested', 'label' => 'Select2 Nested'.backpack_pro_badge(), 'entity' => 'category', 'tab' => 'Selects', ]); $this->crud->addColumn([ 'name' => 'slug', 'type' => 'slug', 'label' => 'Slug'.backpack_pro_badge(), 'tab' => 'Miscellaneous', ]); $this->crud->addColumn([ 'name' => 'time', 'type' => 'time', 'label' => 'Time', 'tab' => 'Time and space', ]); $this->crud->addColumn([ 'name' => 'upload', 'type' => 'upload', 'label' => 'Upload', 'disk' => 'uploads', 'tab' => 'Uploads', ]); $this->crud->addColumn([ // Upload 'name' => 'upload_multiple', 'label' => 'Upload Multiple', 'type' => 'upload_multiple', 'disk' => 'public', 'tab' => 'Uploads', ]); $this->crud->addColumn([ 'name' => 'browse', 'type' => 'browse', 'label' => 'Browse'.backpack_pro_badge(), 'tab' => 'Uploads', ]); $this->crud->addColumn([ 'name' => 'browse_multiple', 'type' => 'browse_multiple', 'label' => 'Browse Multiple'.backpack_pro_badge(), 'tab' => 'Uploads', ]); $this->crud->addColumn([ 'label' => 'Dropzone'.backpack_pro_badge(), 'name' => 'dropzone', 'type' => 'dropzone', 'tab' => 'Uploads', ]); $this->crud->addColumn([ 'name' => 'url', 'type' => 'url', 'label' => 'URL', 'tab' => 'Miscellaneous', ]); $this->crud->addColumn([ 'name' => 'week', 'type' => 'week', 'label' => 'Week', 'tab' => 'Time and space', ]); $this->crud->addColumn([ 'name' => 'video', // The db column name 'label' => 'Video'.backpack_pro_badge(), // Table column heading 'type' => 'video', 'youtube_api_key' => env('YOUTUBE_API_KEY'), 'tab' => 'Miscellaneous', ]); $this->crud->addColumn([ 'name' => 'browse_multiple', 'key' => 'browse_multiple_array', 'type' => 'array', 'label' => 'Array'.backpack_pro_badge(), 'tab' => 'Miscellaneous', ]); } protected function setupCreateOperation() { $this->crud->setValidation(StoreRequest::class); $this->crud->setOperationSetting('contentClass', 'col-md-12 bold-labels'); $this->crud->addFields(static::getFieldsArrayForSimpleTab()); $this->crud->addFields(static::getFieldsArrayForTimeAndSpaceTab()); $this->crud->addFields(static::getFieldsArrayForSelectsTab()); $this->crud->addFields(static::getFieldsArrayForRelationshipsTab()); $this->crud->addFields(static::getFieldsArrayForUploadsTab()); $this->crud->addFields(static::getFieldsArrayForWysiwygEditorsTab()); $this->crud->addFields(static::getFieldsArrayForMiscellaneousTab()); if (env('GOOGLE_PLACES_KEY')) { $this->crud->addField([ // Address_google 'name' => 'address_google', 'label' => 'Address_google '.backpack_pro_badge(), 'type' => 'address_google', 'fake' => true, 'store_as_json' => true, 'tab' => 'Time and space', ]); $this->crud->addField([ 'name' => 'location', 'label' => 'Google_map '.backpack_pro_badge(), 'type' => 'google_map', 'fake' => true, 'tab' => 'Time and space', ]); } // if you want to test removeField, uncomment the following line // $this->crud->removeField('url'); } protected function setupUpdateOperation() { $this->setupCreateOperation(); // disable editing the slug when editing $this->crud->field('slug')->target('')->attributes(['readonly' => 'readonly']); } protected function addCustomCrudFilters() { $this->crud->addFilter( [ // add a "simple" filter called Draft 'type' => 'simple', 'name' => 'checkbox_filter', 'label' => 'Simple', ], false, // the simple filter has no values, just the "Draft" label specified above function () { // if the filter is active (the GET parameter "draft" exits) $this->crud->addClause('where', 'checkbox', '1'); } ); $this->crud->addFilter([ // dropdown filter 'name' => 'select_from_array', 'type' => 'dropdown', 'label'=> 'Dropdown', ], ['one' => 'One', 'two' => 'Two', 'three' => 'Three'], function ($value) { // if the filter is active $this->crud->addClause('where', 'select_from_array', $value); }); $this->crud->addFilter( [ // text filter 'type' => 'text', 'name' => 'text', 'label' => 'Text', ], false, function ($value) { // if the filter is active $this->crud->addClause('where', 'text', 'LIKE', "%$value%"); } ); $this->crud->addFilter( [ 'name' => 'number', 'type' => 'range', 'label' => 'Range', 'label_from' => 'min value', 'label_to' => 'max value', ], false, function ($value) { // if the filter is active $range = json_decode($value); if ($range->from && $range->to) { $this->crud->addClause('where', 'number', '>=', (float) $range->from); $this->crud->addClause('where', 'number', '<=', (float) $range->to); } } ); $this->crud->addFilter( [ // date filter 'type' => 'date', 'name' => 'date', 'label' => 'Date', ], false, function ($value) { // if the filter is active, apply these constraints $this->crud->addClause('where', 'date', '=', $value); } ); $this->crud->addFilter( [ // daterange filter 'type' => 'date_range', 'name' => 'date_range', 'label'=> 'Date range', // 'date_range_options' => [ // 'format' => 'YYYY/MM/DD', // 'locale' => ['format' => 'YYYY/MM/DD'], // 'showDropdowns' => true, // 'showWeekNumbers' => true // ] ], false, function ($value) { // if the filter is active, apply these constraints $dates = json_decode($value); $this->crud->addClause('where', 'date', '>=', $dates->from); $this->crud->addClause('where', 'date', '<=', $dates->to); } ); $this->crud->addFilter([ // select2 filter 'name' => 'select2', 'type' => 'select2', 'label'=> 'Select2', ], function () { return \Backpack\NewsCRUD\app\Models\Category::all()->keyBy('id')->pluck('name', 'id')->toArray(); }, function ($value) { // if the filter is active $this->crud->addClause('where', 'select2', $value); }); $this->crud->addFilter([ // select2_multiple filter 'name' => 'select2_multiple', 'type' => 'select2_multiple', 'label'=> 'S2 multiple', ], function () { return \Backpack\NewsCRUD\app\Models\Category::all()->keyBy('id')->pluck('name', 'id')->toArray(); }, function ($values) { // if the filter is active foreach (json_decode($values) as $key => $value) { $this->crud->addClause('orWhere', 'select2', $value); } }); $this->crud->addFilter( [ // select2_ajax filter 'name' => 'select2_from_ajax', 'type' => 'select2_ajax', 'label' => 'S2 Ajax', 'placeholder' => 'Pick an article', 'method' => 'POST', ], url('api/article-search'), // the ajax route function ($value) { // if the filter is active $this->crud->addClause('where', 'select2_from_ajax', $value); } ); } public static function getFieldsArrayForSimpleTab() { return [ [ 'name' => 'text', 'label' => 'Text'.backpack_free_badge(), 'type' => 'text', 'tab' => 'Simple', 'wrapperAttributes' => [ 'class' => 'form-group col-md-4', ], ], [ 'name' => 'slug', 'label' => 'Slug'.backpack_pro_badge(), 'type' => 'slug', 'target' => 'text', 'tab' => 'Simple', 'fake' => true, 'wrapperAttributes' => [ 'class' => 'form-group col-md-4', ], ], [ 'name' => 'email', 'label' => 'Email'.backpack_free_badge(), 'type' => 'email', 'tab' => 'Simple', 'wrapperAttributes' => [ 'class' => 'form-group col-md-4', ], ], [ // Textarea 'name' => 'textarea', 'label' => 'Textarea'.backpack_free_badge(), 'type' => 'textarea', 'tab' => 'Simple', ], [ // Number 'name' => 'number', 'label' => 'Number'.backpack_free_badge(), 'type' => 'number', 'tab' => 'Simple', 'wrapperAttributes' => ['class' => 'form-group col-md-3'], ], [ // Number 'name' => 'float', 'label' => 'Float'.backpack_free_badge(), 'type' => 'number', 'attributes' => ['step' => 'any'], // allow decimals 'tab' => 'Simple', 'wrapperAttributes' => ['class' => 'form-group col-md-3'], ], [ // Number 'name' => 'number_with_prefix', 'label' => 'Number with prefix'.backpack_free_badge(), 'type' => 'number', 'prefix' => '$', 'fake' => true, 'store_in' => 'extras', 'tab' => 'Simple', 'wrapperAttributes' => ['class' => 'form-group col-md-3'], ], [ // Number 'name' => 'number_with_suffix', 'label' => 'Number with suffix'.backpack_free_badge(), 'type' => 'number', 'suffix' => '.00', 'fake' => true, 'store_in' => 'extras', 'tab' => 'Simple', 'wrapperAttributes' => ['class' => 'form-group col-md-3'], ], [ // Number 'name' => 'text_with_both_prefix_and_suffix', 'label' => 'Text with both prefix and suffix'.backpack_free_badge(), 'type' => 'number', 'prefix' => '@', 'suffix' => "", 'fake' => true, 'store_in' => 'extras', 'tab' => 'Simple', 'wrapperAttributes' => ['class' => 'form-group col-md-4'], ], [ // Phone 'name' => 'phone', 'label' => 'Phone'.backpack_pro_badge(), 'type' => 'phone', 'fake' => true, 'store_in' => 'extras', 'tab' => 'Simple', 'wrapperAttributes' => ['class' => 'form-group col-md-4'], ], [ // Password 'name' => 'password', 'label' => 'Password'.backpack_free_badge(), 'type' => 'password', 'tab' => 'Simple', 'wrapperAttributes' => ['class' => 'form-group col-md-4'], ], [ 'name' => 'radio', // the name of the db column 'label' => 'Status (radio)'.backpack_free_badge(), // the input label 'type' => 'radio', 'options' => [ // the key will be stored in the db, the value will be shown as label; 0 => 'Draft', 1 => 'Published', 2 => 'Other', ], // optional 'inline' => true, // show the radios all on the same line? 'tab' => 'Simple', ], [ 'name' => 'status', 'label' => 'Status (enum)'.backpack_free_badge(), 'type' => 'enum', 'tab' => 'Simple', ], [ // Checkbox 'name' => 'checkbox', 'label' => 'I have not read the terms and conditions and I never will (checkbox)'.backpack_free_badge(), 'type' => 'checkbox', 'tab' => 'Simple', ], [ // Switch 'name' => 'switch', 'label' => 'I have not read the terms and conditions and I never will (switch)'.backpack_free_badge(), 'type' => 'switch', 'tab' => 'Simple', 'fake' => true, ], [ // Hidden 'name' => 'hidden', 'type' => 'hidden', 'default' => '6318', 'tab' => 'Simple', ], ]; } public static function getFieldsArrayForTimeAndSpaceTab() { // ----------------- // DATE, TIME AND SPACE tab // ----------------- $fields = [ [ // Time 'name' => 'time', 'label' => 'Time'.backpack_free_badge(), 'type' => 'time', 'wrapperAttributes' => ['class' => 'form-group col-md-4'], 'tab' => 'Time and space', 'fake' => true, ], [ // Month 'name' => 'week', 'label' => 'Week'.backpack_free_badge(), 'type' => 'week', 'wrapperAttributes' => ['class' => 'form-group col-md-4'], 'tab' => 'Time and space', ], [ // Month 'name' => 'month', 'label' => 'Month'.backpack_free_badge(), 'type' => 'month', 'wrapperAttributes' => ['class' => 'form-group col-md-4'], 'tab' => 'Time and space', ], [ // Date 'name' => 'date', 'label' => 'Date (HTML5 spec)'.backpack_free_badge(), 'type' => 'date', 'attributes' => [ 'pattern' => '[0-9]{4}-[0-9]{2}-[0-9]{2}', 'placeholder' => 'yyyy-mm-dd', ], 'wrapperAttributes' => ['class' => 'form-group col-md-6'], 'tab' => 'Time and space', ], [ // Date // PRO 'name' => 'date_picker', 'label' => 'Date picker (jQuery plugin)'.backpack_pro_badge(), 'type' => 'date_picker', // optional: 'date_picker_options' => [ 'todayBtn' => true, 'format' => 'dd-mm-yyyy', 'language' => 'en', ], 'wrapperAttributes' => ['class' => 'form-group col-md-6'], 'tab' => 'Time and space', ], [ // DateTime 'name' => 'datetime', 'label' => 'Datetime (HTML5 spec)'.backpack_free_badge(), 'type' => 'datetime', 'wrapperAttributes' => ['class' => 'form-group col-md-6'], 'tab' => 'Time and space', ], [ // DateTime 'name' => 'datetime_picker', 'label' => 'Datetime picker (jQuery plugin)'.backpack_pro_badge(), 'type' => 'datetime_picker', // optional: 'datetime_picker_options' => [ 'format' => 'DD/MM/YYYY HH:mm', 'language' => 'en', ], 'wrapperAttributes' => ['class' => 'form-group col-md-6'], 'tab' => 'Time and space', ], [ // Date_range 'name' => 'start_date,end_date', // a unique name for this field 'label' => 'Date Range'.backpack_pro_badge(), 'type' => 'date_range', 'default' => ['2020-03-28 01:01', '2020-04-05 02:00'], // OPTIONALS 'date_range_options' => [ // options sent to daterangepicker.js 'timePicker' => true, 'locale' => ['format' => 'DD/MM/YYYY HH:mm'], ], 'tab' => 'Time and space', ], ]; if (env('GOOGLE_PLACES_KEY')) { $fields[] = [ // Address_google 'name' => 'address_google', 'label' => 'Address_google '.backpack_pro_badge(), 'type' => 'address_google', 'fake' => true, 'store_as_json' => true, 'tab' => 'Time and space', ]; } return $fields; } public static function getFieldsArrayForRelationshipsTab() { // ----------------- // RELATIONSHIPS tab // ----------------- return [ [ // CustomHTML 'name' => 'relationship_heading', 'type' => 'custom_html', 'value' => "

All the examples in this tab relationship field type. This field type changes its interface depending on what relationship it is used on, and whether or not you've defined 'subfields' for it. So we've provided examples for each relationship type. Then examples for a few extra features of the repeatable field.

", 'tab' => 'Relationship', ], [ // CustomHTML 'name' => 'relationship_direct_relationships', 'type' => 'custom_html', 'value' => '
Direct Relationships '.backpack_pro_badge().'
', 'tab' => 'Relationship', ], // -------------------- // Direct relationships // -------------------- [ 'name' => 'address.street', 'label' => 'HasOne (1-1) towards an attribute on related model', 'wrapper' => [ 'class' => 'form-group col-md-6', ], 'tab' => 'Relationship', ], [ 'name' => 'address.country', 'label' => 'HasOne (1-1) towards a relationship on related model', 'wrapper' => [ 'class' => 'form-group col-md-6', ], 'tab' => 'Relationship', ], [ 'name' => 'categoryRelationship', 'label' => 'BelongsTo (n-1)', 'tab' => 'Relationship', 'wrapper' => [ 'class' => 'form-group col-md-6', ], ], [ 'name' => 'postalboxer', 'label' => 'HasMany (1-n)', 'tab' => 'Relationship', 'wrapper' => [ 'class' => 'form-group col-md-6', ], ], [ 'name' => 'countries', 'label' => 'BelongsToMany (n-n)', 'tab' => 'Relationship', ], // ----------------------------------- // Direct relationships with subfields // ----------------------------------- [ // CustomHTML 'name' => 'relationship_direct_relationships_with_subfields', 'type' => 'custom_html', 'value' => '
Direct Relationships + Subfields '.backpack_pro_badge().'
', 'tab' => 'Relationship', ], [ 'name' => 'wish', 'label' => 'HasOne (1-1) + subfields'.backpack_new_badge(), 'subfields' => [ [ 'name' => 'country', ], [ 'name' => 'body', 'wrapper' => [ 'class' => 'text-danger', ], ], [ 'name' => 'universes', ], ], 'wrapper' => [ 'class' => 'form-group col-md-4', ], 'tab' => 'Relationship', ], [ 'name' => 'postalboxes', 'label' => 'HasMany (1-n) + subfields'.backpack_new_badge(), 'subfields' => [ [ 'name' => 'postal_name', 'type' => 'text', ], ], 'wrapper' => [ 'class' => 'form-group col-md-4', ], 'tab' => 'Relationship', ], [ 'name' => 'dummyproducts', 'label' => 'BelongsToMany (n-n) + subfields for pivot table'.backpack_new_badge(), 'wrapper' => [ 'class' => 'form-group col-md-4', ], 'pivotSelect' => [ 'wrapper' => [ 'class' => 'form-group col-md-6', ], ], 'subfields' => [ [ 'name' => 'notes', 'type' => 'text', 'wrapper' => [ 'class' => 'form-group col-md-6', ], ], ], 'tab' => 'Relationship', ], // ------------------------- // Polymorphic Relationships // ------------------------- [ // CustomHTML 'name' => 'relationship_polymorphic_relationships', 'type' => 'custom_html', 'value' => '
Polymorphic Relationships '.backpack_pro_badge().'
', 'tab' => 'Relationship', ], [ 'name' => 'sentiment.text', 'label' => 'MorphOne (1-1 polymorphic) towards an attribute'.backpack_new_badge(), 'type' => 'relationship', 'wrapper' => [ 'class' => 'form-group col-md-6', ], 'tab' => 'Relationship', ], [ 'name' => 'sentiment.user', 'label' => 'MorphOne (1-1 polymorphic) towards a relation'.backpack_new_badge(), 'wrapper' => [ 'class' => 'form-group col-md-6', ], 'tab' => 'Relationship', ], [ 'name' => 'universes', 'label' => 'MorphMany (1-n)'.backpack_new_badge(), 'wrapper' => [ 'class' => 'form-group col-md-6', ], 'tab' => 'Relationship', ], [ 'name' => 'bills', 'label' => 'MorphToMany (n-n)'.backpack_new_badge(), 'wrapper' => [ 'class' => 'form-group col-md-6', ], 'tab' => 'Relationship', ], // ------------------------------------- // Polymorphic Relationships + Subfields // ------------------------------------- [ // CustomHTML 'name' => 'relationship_polymorphic_relationships_with_subfields', 'type' => 'custom_html', 'value' => '
Polymorphic Relationships + Subfields '.backpack_pro_badge().'
', 'tab' => 'Relationship', ], [ 'name' => 'ball', 'label' => 'MorphOne (1-1 polymorphic) + subfields'.backpack_new_badge(), 'wrapper' => [ 'class' => 'form-group col-md-4', ], 'subfields' => [ [ 'name' => 'name', 'wrapper' => [ 'class' => 'form-group col-md-6', ], ], [ 'name' => 'country_id', 'entity' => 'country', 'type' => 'relationship', 'wrapper' => [ 'class' => 'form-group col-md-6', ], ], ], 'tab' => 'Relationship', ], [ 'name' => 'stars', 'label' => 'MorphMany (1-n) + subfields'.backpack_new_badge(), 'wrapper' => [ 'class' => 'form-group col-md-4', ], 'subfields' => [ [ 'name' => 'title', 'type' => 'text', ], ], 'tab' => 'Relationship', ], [ 'name' => 'recommends', 'label' => 'MorphToMany (n-n) + subfields for pivot table'.backpack_new_badge(), 'wrapper' => [ 'class' => 'form-group col-md-4', ], 'subfields' => [ [ 'name' => 'text', 'type' => 'text', ], ], 'tab' => 'Relationship', ], // ---------------------------- // Relationships Extra Features // ---------------------------- [ 'name' => 'relationship_extra_features', 'type' => 'custom_html', 'value' => '
Extra Features '.backpack_pro_badge().'
', 'tab' => 'Relationship', ], [ // Relationship - everything is explicitly defined 'label' => 'BelongsTo + InlineCreate', 'type' => 'relationship', 'name' => 'fallback_icon', 'fake' => true, 'entity' => 'icon', 'attribute' => 'name', 'tab' => 'Relationship', 'inline_create' => true, // 'data_source' => backpack_url('monster/fetch/icon'), 'wrapperAttributes' => ['class' => 'form-group col-md-6'], ], [ // Relationship 'label' => 'BelongsToMany + AJAX + InlineCreate', 'type' => 'relationship', 'name' => 'products', 'entity' => 'products', // 'attribute' => 'name', 'tab' => 'Relationship', 'ajax' => true, // 'inline_create' => true, // TODO: make it work like this too 'inline_create' => [ 'entity' => 'product', 'modal_class' => 'modal-dialog modal-xl', ], 'data_source' => backpack_url('monster/fetch/product'), 'wrapperAttributes' => ['class' => 'form-group col-md-6'], ], [ // Relationship - nothing is explicitly defined, not even the field type 'label' => 'Relationship (all field attributes are guessed)', 'name' => 'icondummy', 'tab' => 'Relationship', // 'data_source' => backpack_url('monster/fetch/icon'), 'wrapperAttributes' => ['class' => 'form-group col-md-12'], ], ]; } public static function getFieldsArrayForSelectsTab() { // ----------------- // SELECTS tab // ----------------- return [ [ // CustomHTML 'name' => 'selects_no_relationship_heading', 'type' => 'custom_html', 'value' => '
No Relationship
', 'tab' => 'Selects', ], [ // select_from_array 'name' => 'select_from_array', 'label' => 'Select_from_array (no relationship, 1-1 or 1-n)'.backpack_free_badge(), 'type' => 'select_from_array', 'options' => ['one' => 'One', 'two' => 'Two', 'three' => 'Three'], 'allows_null' => true, 'tab' => 'Selects', 'allows_multiple' => false, // OPTIONAL; needs you to cast this to array in your model; 'wrapperAttributes' => ['class' => 'form-group col-md-6'], ], [ // select2_from_array 'name' => 'select2_from_array', 'label' => 'Select2_from_array (no relationship, 1-1 or 1-n)'.backpack_pro_badge(), 'type' => 'select2_from_array', 'options' => ['one' => 'One', 'two' => 'Two', 'three' => 'Three'], 'allows_null' => true, 'tab' => 'Selects', 'allows_multiple' => false, // OPTIONAL; needs you to cast this to array in your model; 'wrapperAttributes' => ['class' => 'form-group col-md-6'], ], [ // select_and_order 'name' => 'select_and_order', 'label' => 'Select_and_order'.backpack_pro_badge(), 'type' => 'select_and_order', 'options' => [ 1 => 'Option 1', 2 => 'Option 2', 3 => 'Option 3', 4 => 'Option 4', 5 => 'Option 5', 6 => 'Option 6', 7 => 'Option 7', 8 => 'Option 8', 9 => 'Option 9', ], 'fake' => true, 'tab' => 'Selects', ], // ----------------- // 1-n relationships // ----------------- [ // CustomHTML 'name' => 'selects_1_n_heading', 'type' => 'custom_html', 'value' => '
1-n Relationship (belongsTo, morphTo)
', 'tab' => 'Selects', ], [ // select 'label' => 'Select'.backpack_free_badge(), 'type' => 'select', //https://github.com/Laravel-Backpack/CRUD/issues/502 'name' => 'select', 'entity' => 'category', 'attribute' => 'name', 'model' => 'Backpack\NewsCRUD\app\Models\Category', 'fake' => true, 'tab' => 'Selects', 'wrapperAttributes' => ['class' => 'form-group col-md-4'], ], [ // select_grouped 'label' => 'Select_grouped'.backpack_free_badge(), 'type' => 'select_grouped', //https://github.com/Laravel-Backpack/CRUD/issues/502 'name' => 'select_grouped_id', 'fake' => true, 'entity' => 'article', 'model' => 'Backpack\NewsCRUD\app\Models\Article', 'attribute' => 'title', 'group_by' => 'category', // the relationship to entity you want to use for grouping 'group_by_attribute' => 'name', // the attribute on related model, that you want shown 'group_by_relationship_back' => 'articles', // relationship from related model back to this model 'tab' => 'Selects', 'wrapperAttributes' => ['class' => 'form-group col-md-4'], ], [ // select2_grouped 'label' => 'Select2_grouped'.backpack_pro_badge(), 'type' => 'select2_grouped', //https://github.com/Laravel-Backpack/CRUD/issues/502 'name' => 'select2_grouped_id', 'fake' => true, 'entity' => 'article', 'model' => 'Backpack\NewsCRUD\app\Models\Article', 'attribute' => 'title', 'group_by' => 'category', // the relationship to entity you want to use for grouping 'group_by_attribute' => 'name', // the attribute on related model, that you want shown 'group_by_relationship_back' => 'articles', // relationship from related model back to this model 'tab' => 'Selects', 'wrapperAttributes' => ['class' => 'form-group col-md-4'], ], [ // SELECT2 'label' => 'Select2'.backpack_pro_badge(), 'type' => 'select2', 'name' => 'select2', 'entity' => 'categorySelect2', 'attribute' => 'name', 'model' => "Backpack\NewsCRUD\app\Models\Category", 'tab' => 'Selects', 'wrapperAttributes' => ['class' => 'form-group col-md-4'], ], [ // select2_nested 'name' => 'select2_nested_id', 'label' => 'Select2_nested'.backpack_pro_badge(), 'type' => 'select2_nested', 'fake' => true, 'entity' => 'category', // the method that defines the relationship in your Model 'attribute' => 'name', // foreign key attribute that is shown to user 'model' => "Backpack\NewsCRUD\app\Models\Category", // force foreign key model 'tab' => 'Selects', 'wrapperAttributes' => ['class' => 'form-group col-md-4'], ], [ // select2_from_ajax: 1-n relationship 'label' => 'Select2_from_ajax'.backpack_pro_badge(), // Table column heading 'type' => 'select2_from_ajax', 'name' => 'select2_from_ajax', // the column that contains the ID of that connected entity; 'entity' => 'article', // the method that defines the relationship in your Model 'attribute' => 'title', // foreign key attribute that is shown to user 'model' => "Backpack\NewsCRUD\app\Models\Article", // foreign key model 'data_source' => url('api/article'), // url to controller search function (with /{id} should return model) 'method' => 'POST', // route method, either GET or POST 'placeholder' => 'Select an article', // placeholder for the select 'minimum_input_length' => 2, // minimum characters to type before querying results 'tab' => 'Selects', 'wrapperAttributes' => ['class' => 'form-group col-md-4'], ], [ // CustomHTML 'name' => 'selects_n_n_heading', 'type' => 'custom_html', 'value' => '
n-n Relationship (belongsToMany, morphToMany)
', 'tab' => 'Selects', ], [ 'label' => 'Checklist'.backpack_free_badge(), 'type' => 'checklist', 'name' => 'roles', 'entity' => 'roles', 'attribute' => 'name', 'model' => "Backpack\PermissionManager\app\Models\Role", 'pivot' => true, 'tab' => 'Selects', ], [ // Select_Multiple = n-n relationship 'label' => 'Select_multiple'.backpack_free_badge(), 'type' => 'select_multiple', 'name' => 'tags', // the method that defines the relationship in your Model 'entity' => 'tags', // the method that defines the relationship in your Model 'attribute' => 'name', // foreign key attribute that is shown to user 'model' => "Backpack\NewsCRUD\app\Models\Tag", // foreign key model 'pivot' => true, // on create&update, do you need to add/delete pivot table entries? 'tab' => 'Selects', // 'wrapperAttributes' => ['class' => 'form-group col-md-12'], ], [ // Select2Multiple = n-n relationship (with pivot table) 'label' => 'Select2_multiple'.backpack_pro_badge(), 'type' => 'select2_multiple', 'name' => 'categories', // the method that defines the relationship in your Model 'entity' => 'categories', // the method that defines the relationship in your Model 'attribute' => 'name', // foreign key attribute that is shown to user 'model' => "Backpack\NewsCRUD\app\Models\Category", // foreign key model 'allows_null' => true, 'pivot' => true, // on create&update, do you need to add/delete pivot table entries? 'tab' => 'Selects', 'wrapperAttributes' => ['class' => 'form-group col-md-6'], ], [ // Select2_from_ajax_multiple: n-n relationship with pivot table 'label' => 'Select2_from_ajax_multiple'.backpack_pro_badge(), // Table column heading 'type' => 'select2_from_ajax_multiple', 'name' => 'articles', // the column that contains the ID of that connected entity; 'entity' => 'articles', // the method that defines the relationship in your Model 'attribute' => 'title', // foreign key attribute that is shown to user 'model' => "Backpack\NewsCRUD\app\Models\Article", // foreign key model 'data_source' => url('api/article'), // url to controller search function (with /{id} should return model) 'method' => 'POST', // route method, either GET or POST 'placeholder' => 'Select one or more articles', // placeholder for the select 'minimum_input_length' => 2, // minimum characters to type before querying results 'pivot' => true, // on create&update, do you need to add/delete pivot table entries? 'tab' => 'Selects', 'wrapperAttributes' => ['class' => 'form-group col-md-6'], ], [ // Select2_json_from_api paginated 'label' => 'Select2_json_from_api (paginated)'.backpack_pro_badge(), // Table column heading 'type' => 'select2_json_from_api', 'name' => 'select2_json_from_api', // the column that contains the ID of that connected entity; 'attribute' => 'title', // foreign key attribute that is shown to user 'data_source' => backpack_url('monster/fetch/paginated-types'), // url to controller search function (with /{id} should return model) 'method' => 'POST', // route method, either GET or POST 'placeholder' => 'Select one or more types', // placeholder for the select 'minimum_input_length' => 0, // minimum characters to type before querying results 'tab' => 'Selects', 'wrapperAttributes' => ['class' => 'form-group col-md-6'], 'attributes_to_store' => ['id', 'title', 'location'], 'multiple' => true, ], [ // Select2_json_from_api not paginated 'label' => 'Select2_json_from_api (simple array)'.backpack_pro_badge(), // Table column heading 'type' => 'select2_json_from_api', 'name' => 'select2_json_from_api_simple', // the column that contains the ID of that connected entity; 'data_source' => backpack_url('monster/fetch/simple-types'), // url to controller search function (with /{id} should return model) 'method' => 'POST', // route method, either GET or POST 'placeholder' => 'Select one or more types', // placeholder for the select 'minimum_input_length' => 0, // minimum characters to type before querying results 'tab' => 'Selects', 'wrapperAttributes' => ['class' => 'form-group col-md-6'], 'multiple' => true, ], ]; } public static function getFieldsArrayForUploadsTab() { // ----------------- // UPLOADS tab // ----------------- $fields = []; if (app('env') == 'production') { $fields[] = [ // CustomHTML 'name' => 'separator', 'type' => 'custom_html', 'value' => '

Note: In the online demo we\'ve restricted the upload and media library fields a lot, or hidden them entirely. To test them out, you can download and install this demo admin panel in your local environment.

', 'tab' => 'Uploads', ]; } $fields[] = [ // Browse 'name' => 'browse', 'label' => 'Browse (using elFinder)'.backpack_pro_badge(), 'type' => 'browse', 'tab' => 'Uploads', 'mime_types' => ['image/png', 'image/jpeg'], // visible mime prefixes; ex. ['image'] or ['application/pdf'] ]; $fields[] = [ // Browse multiple 'name' => 'browse_multiple', 'label' => 'Browse multiple'.backpack_pro_badge(), 'type' => 'browse_multiple', 'tab' => 'Uploads', 'sortable' => true, // 'multiple' => true, // enable/disable the multiple selection functionality // 'mime_types' => null, // visible mime prefixes; ex. ['image'] or ['application/pdf'] ]; $fields[] = [ // Upload 'name' => 'upload', 'label' => 'Upload'.backpack_free_badge(), 'type' => 'upload', 'upload' => true, 'disk' => 'uploads', // if you store files in the /public folder, please ommit this; if you store them in /storage or S3, please specify it; // optional: // 'temporary' => 10 // if using a service, such as S3, that requires you to make temporary URL's this will make a URL that is valid for the number of minutes specified 'tab' => 'Uploads', ]; $fields[] = [ // Upload 'name' => 'upload_multiple', 'label' => 'Upload Multiple'.backpack_free_badge(), 'type' => 'upload_multiple', 'upload' => true, // 'disk' => 'uploads', // if you store files in the /public folder, please ommit this; if you store them in /storage or S3, please specify it; // optional: // 'temporary' => 10 // if using a service, such as S3, that requires you to make temporary URL's this will make a URL that is valid for the number of minutes specified 'tab' => 'Uploads', ]; $fields[] = [ // base64_image 'label' => 'Base64 Image - includes cropping'.backpack_pro_badge(), 'name' => 'base64_image', 'filename' => null, // set to null if not needed 'type' => 'base64_image', 'aspect_ratio' => 1, // set to 0 to allow any aspect ratio 'crop' => true, // set to true to allow cropping, false to disable 'src' => null, // null to read straight from DB, otherwise set to model accessor function 'tab' => 'Uploads', ]; $fields[] = [ // image 'label' => 'Image - includes cropping'.backpack_pro_badge(), 'name' => 'image', 'type' => 'image', 'upload' => true, 'crop' => true, // set to true to allow cropping, false to disable 'aspect_ratio' => 1, // ommit or set to 0 to allow any aspect ratio // 'disk' => config('backpack.base.root_disk_name'), // in case you need to show images from a different disk // 'prefix' => 'uploads/images/profile_pictures/' // in case your db value is only the file name (no path), you can use this to prepend your path to the image src (in HTML), before it's shown to the user; 'tab' => 'Uploads', ]; $fields[] = [ 'label' => 'Dropzone - drag&drop '.backpack_pro_badge(), 'name' => 'dropzone', 'type' => 'dropzone', 'tab' => 'Uploads', 'withFiles' => true, ]; return $fields; } public static function getFieldsArrayForWysiwygEditorsTab() { // ----------------- // BIG TEXTS tab // ----------------- return [ [ // EasyMDE 'name' => 'easymde', 'label' => 'EasyMDE - markdown editor'.backpack_pro_badge(), 'type' => 'easymde', 'tab' => 'WYSIWYG Editors', ], [ // Summernote 'name' => 'summernote', 'label' => 'Summernote editor'.backpack_free_badge(), 'type' => 'summernote', 'tab' => 'WYSIWYG Editors', 'withFiles' => true, ], [ // CKEditor 'name' => 'ckeditor', 'label' => 'CKEditor - also called the WYSIWYG field'.backpack_pro_badge(), 'type' => 'ckeditor', 'tab' => 'WYSIWYG Editors', ], [ // TinyMCE 'name' => 'tinymce', 'label' => 'TinyMCE'.backpack_pro_badge(), 'type' => 'tinymce', 'tab' => 'WYSIWYG Editors', ], ]; } public static function getFieldsArrayForMiscellaneousTab() { // ----------------- // MISCELLANEOUS tab // ----------------- return [ [ // Color 'name' => 'color', 'label' => 'Color picker (HTML5 spec)'.backpack_free_badge(), 'type' => 'color', // 'wrapperAttributes' => ['class' => 'col-md-6'], 'tab' => 'Miscellaneous', 'wrapperAttributes' => ['class' => 'form-group col-md-6'], ], [ // Video 'name' => 'video', 'label' => 'Video - link to video file on Youtube or Vimeo'.backpack_pro_badge(), 'type' => 'video', 'tab' => 'Miscellaneous', 'wrapperAttributes' => ['class' => 'form-group col-md-6'], ], [ // Range 'name' => 'range', 'label' => 'Range'.backpack_free_badge(), 'type' => 'range', //optional 'attributes' => [ 'min' => 0, 'max' => 10, ], 'tab' => 'Miscellaneous', 'wrapperAttributes' => ['class' => 'form-group col-md-6'], ], [ // Icon picker 'label' => 'Icon Picker'.backpack_pro_badge(), 'name' => 'icon_picker', 'type' => 'icon_picker', 'iconset' => 'fontawesome', // options: fontawesome, glyphicon, ionicon, weathericon, mapicon, octicon, typicon, elusiveicon, materialdesign 'tab' => 'Miscellaneous', 'wrapperAttributes' => ['class' => 'form-group col-md-2'], ], [ // Table 'name' => 'table', 'label' => 'Table'.backpack_pro_badge(), 'type' => 'table', 'entity_singular' => 'subentry', // used on the "Add X" button 'columns' => [ 'name' => 'Name', 'desc' => 'Description', 'price' => 'Price', ], 'max' => 5, // maximum rows allowed in the table 'min' => 0, // minimum rows allowed in the table 'tab' => 'Miscellaneous', ], [ // Table 'name' => 'fake_table', 'label' => 'Fake Table'.backpack_pro_badge(), 'type' => 'table', 'entity_singular' => 'subentry', // used on the "Add X" button 'columns' => [ 'name' => 'Name', 'desc' => 'Description', 'price' => 'Price', ], 'fake' => true, 'max' => 5, // maximum rows allowed in the table 'min' => 0, // minimum rows allowed in the table 'tab' => 'Miscellaneous', ], [ 'name' => 'url', 'type' => 'url', 'label' => 'URL'.backpack_free_badge(), 'tab' => 'Miscellaneous', ], [ 'name' => 'features', 'label' => 'Features'.backpack_pro_badge(), 'type' => 'repeatable', 'fake' => true, 'subfields' => [ [ 'name' => 'feature', 'wrapper' => [ 'class' => 'col-md-3', ], ], [ 'name' => 'value', 'wrapper' => [ 'class' => 'col-md-6', ], ], [ 'name' => 'quantity', 'type' => 'number', 'wrapper' => [ 'class' => 'col-md-3', ], ], ], 'tab' => 'Miscellaneous', ], ]; } public function ajaxUpload() { if (app('env') === 'production') { return response()->json(['errors' => [ 'dropzone' => ['Uploads are disabled in production'], 'easymde' => ['Uploads are disabled in production'], 'summernote' => ['Uploads are disabled in production'], ], ], 500); } return $this->traitAjaxUpload(); } protected function setupReportOperation() { // --- Override the content class for a narrower layout --- $this->crud->setOperationSetting('contentClass', 'col-md-10 mx-auto'); // --- Remove the interval filter (not needed for stat-heavy reports) --- $this->crud->removeFilter('report_interval'); // --- Stat: total monsters (count + previous period comparison + custom wrapper) --- $this->addMetric('total_monsters', [ 'type' => 'stat', 'label' => 'Total Monsters', 'aggregate' => 'count', 'period' => 'created_at', 'compare' => 'previous_period', 'wrapper' => ['class' => 'col-md-3'], ]); // --- Stat: query scope to filter rows --- $this->addMetric('working_monsters', [ 'type' => 'stat', 'label' => 'Working', 'aggregate' => 'count', 'period' => 'created_at', 'query' => fn ($q) => $q->where('status', 'working'), 'wrapper' => ['class' => 'col-md-3'], ]); // --- Stat: min aggregate --- $this->addMetric('min_number', [ 'type' => 'stat', 'label' => 'Min Number', 'column' => 'number', 'aggregate' => 'min', 'wrapper' => ['class' => 'col-md-3'], ]); // --- Stat: max aggregate --- $this->addMetric('max_number', [ 'type' => 'stat', 'label' => 'Max Number', 'column' => 'number', 'aggregate' => 'max', 'wrapper' => ['class' => 'col-md-3'], ]); // --- Demonstrate removeMetric (add then remove) --- $this->addMetric('temp_metric', [ 'type' => 'stat', 'label' => 'Should Not Appear', ]); $this->removeMetric('temp_metric'); // --- Line chart: full width --- $this->addMetric('monsters_over_time', [ 'type' => 'line', 'label' => 'Monsters Created Over Time', 'aggregate' => 'count', 'period' => 'created_at', 'wrapper' => ['class' => 'col-md-12'], ]); // --- Group stats into one request --- $this->groupMetrics('monster_stats', ['total_monsters', 'working_monsters', 'min_number', 'max_number']); } } ================================================ FILE: app/Http/Controllers/Admin/Operations/SMSOperation.php ================================================ formRoutes( operationName: 'SMS', routesHaveIdSegment: true, segment: $segment, routeName: $routeName, controller: $controller ); } /** * Add the default settings, buttons, etc that this operation needs. */ protected function setupSMSDefaults(): void { $this->formDefaults( operationName: 'SMS', buttonStack: 'line', // alternatives: top, bottom buttonMeta: [ 'icon' => 'las la-sms', 'label' => 'SMS', ], ); } /** * Method to handle the GET request and display the View with a Backpack form. */ public function getSMSForm(?int $id = null): \Illuminate\Contracts\View\View { $this->crud->hasAccessOrFail('SMS'); $this->crud->addField('text'); return $this->formView($id); } /** * Method to handle the POST request and perform the operation. * * @return array|\Illuminate\Http\RedirectResponse */ public function postSMSForm(?int $id = null) { $this->crud->hasAccessOrFail('SMS'); return $this->formAction($id, function ($inputs, $entry) { // You logic goes here... // dd('got to ' . __METHOD__, $inputs, $entry); // show a success message \Alert::success('SMS Sent: '.$inputs['text'])->flash(); }); } } ================================================ FILE: app/Http/Controllers/Admin/PetShop/BadgeCrudController.php ================================================ type('number'); * - CRUD::addColumn(['name' => 'price', 'type' => 'number']);. */ } /** * Define what happens when the Create operation is loaded. * * @see https://backpackforlaravel.com/docs/crud-operation-create * * @return void */ protected function setupCreateOperation() { CRUD::setValidation(BadgeRequest::class); CRUD::field('name'); /** * Fields can be defined using the fluent syntax or array syntax: * - CRUD::field('price')->type('number'); * - CRUD::addField(['name' => 'price', 'type' => 'number']));. */ } /** * Define what happens when the Update operation is loaded. * * @see https://backpackforlaravel.com/docs/crud-operation-update * * @return void */ protected function setupUpdateOperation() { $this->setupCreateOperation(); } } ================================================ FILE: app/Http/Controllers/Admin/PetShop/CommentCrudController.php ================================================ fetch(Pet::class); } /** * Configure the CrudPanel object. Apply settings to all operations. * * @return void */ public function setup() { CRUD::setModel(\App\Models\PetShop\Comment::class); CRUD::setRoute(config('backpack.base.route_prefix').'/pet-shop/comment'); CRUD::setEntityNameStrings('comment', 'comments'); } /** * Define what happens when the List operation is loaded. * * @see https://backpackforlaravel.com/docs/crud-operation-list-entries * * @return void */ protected function setupListOperation() { CRUD::column('body'); // CRUD::column('commentable_type'); // CRUD::column('commentable_id'); CRUD::column('user'); CRUD::setOperationSetting('showEntryCount', false); } /** * Define what happens when the Create operation is loaded. * * @see https://backpackforlaravel.com/docs/crud-operation-create * * @return void */ protected function setupCreateOperation() { CRUD::setValidation(CommentRequest::class); CRUD::field('body')->type('easymde'); CRUD::field('commentable') ->label('For') ->addMorphOption('App\Models\PetShop\Owner', 'Owner', ['attribute' => 'name']) ->addMorphOption('monster') ->addMorphOption('App\Models\PetShop\Pet', 'Pet', [ 'data_source' => backpack_url('pet-shop/comment/fetch/pets'), 'minimum_input_length' => 2, 'placeholder' => 'Select a fluffy pet', ]) ->addMorphOption('user') ->morphTypeField(['wrapper' => ['class' => 'form-group col-md-4']]) ->morphIdField(['wrapper' => ['class' => 'form-group col-md-8']]); CRUD::field('user'); } /** * Define what happens when the Update operation is loaded. * * @see https://backpackforlaravel.com/docs/crud-operation-update * * @return void */ protected function setupUpdateOperation() { $this->setupCreateOperation(); } } ================================================ FILE: app/Http/Controllers/Admin/PetShop/InvoiceCrudController.php ================================================ =', now()->subYears(5)->format('Y-m-d')); } /** * Define what happens when the List operation is loaded. * * @see https://backpackforlaravel.com/docs/crud-operation-list-entries * * @return void */ protected function setupListOperation() { CRUD::addColumn([ 'name' => 'info', 'type' => 'view', 'view' => 'crud::chips.invoice', ]); CRUD::column('issuance_date'); CRUD::column('due_date'); CRUD::column('total'); CRUD::filter('series') ->type('dropdown') ->values(\App\Models\PetShop\Invoice::select('series')->distinct()->pluck('series', 'series')->toArray()) ->label('Series') ->placeholder('Search by series') ->whenActive(function ($value) { CRUD::addClause('where', 'series', '=', $value); }); CRUD::filter('issuance_date') ->type('date_range') ->label('Issuance Date') ->placeholder('Search by issuance date') ->whenActive(function ($value) { $dates = json_decode($value); CRUD::addClause('whereBetween', 'issuance_date', [$dates->from, $dates->to]); }); $this->runCustomViews(); } /** * Define what happens when the Create operation is loaded. * * @see https://backpackforlaravel.com/docs/crud-operation-create * * @return void */ protected function setupCreateOperation() { CRUD::setValidation(InvoiceRequest::class); CRUD::setOperationSetting('contentClass', 'col-md-12'); CRUD::field('owner')->ajax(true)->minimum_input_length(0)->inline_create(true); CRUD::field('series')->size(3)->default('INV'); CRUD::field('number')->size(3)->default((\App\Models\PetShop\Invoice::max('number') ?? 0) + 1); CRUD::field('issuance_date')->size(3)->default(date('Y-m-d')); CRUD::field('due_date')->size(3); CRUD::field('items')->subfields([ [ 'name' => 'description', 'type' => 'text', 'wrapper' => [ 'class' => 'form-group col-md-8', ], ], [ 'name' => 'quantity', 'type' => 'number', 'attributes' => ['step' => 'any'], 'wrapper' => [ 'class' => 'form-group col-md-2', ], ], [ 'name' => 'unit_price', 'type' => 'number', 'attributes' => ['step' => 'any'], 'wrapper' => [ 'class' => 'form-group col-md-2', ], ], ])->reorder('order')->hint('Create/update/delete InvoiceItem entries over a hasMany relationship (1-n).'); } /** * Define what happens when the Update operation is loaded. * * @see https://backpackforlaravel.com/docs/crud-operation-update * * @return void */ protected function setupUpdateOperation() { $this->setupCreateOperation(); } protected function setupShowOperation() { $this->autoSetupShowOperation(); CRUD::column('total'); // get the owner with important relationships $owner = CRUD::getCurrentEntry()->owner()->with('avatar', 'invoices')->first(); // add a chip widget for the owner Widget::add() ->to('after_content') ->type('chip') ->view('crud::chips.owner') ->title('Owner') ->entry($owner); } public function fetchOwner() { return $this->fetch(\App\Models\PetShop\Owner::class); } protected function setupReportOperation() { // --- Stat cards row --- $this->addMetricGroup([ 'class' => 'row', ], function () { $this->addMetric('total_invoices', [ 'type' => 'stat', 'label' => 'Total Invoices', 'aggregate' => 'count', 'period' => 'issuance_date', 'compare' => 'previous_period', 'refreshInterval' => 5, 'wrapper' => ['class' => 'col-md-4'], ]); $this->addMetric('series_count', [ 'type' => 'stat', 'label' => 'Unique Series', 'wrapper' => ['class' => 'col-md-4'], 'resolve' => fn ($query, $filters) => [ 'value' => $query->distinct('series')->count('series'), ], ]); $this->addMetric('total_items_value', [ 'type' => 'stat', 'label' => 'Total Items Value', 'column' => 'unit_price', 'aggregate' => 'sum', 'format' => '$:value', 'period' => 'created_at', 'wrapper' => ['class' => 'col-md-4'], 'query' => fn ($q) => $q->setModel(new \App\Models\PetShop\InvoiceItem()), ]); }); // --- Charts row --- $this->addMetricGroup([ 'class' => 'row mt-2', ], function () { $this->addMetric('invoices_bar', [ 'type' => 'bar', 'label' => 'Invoices Per Period', 'aggregate' => 'count', 'period' => 'issuance_date', ]); $this->addMetric('items_per_invoice', [ 'type' => 'line', 'label' => 'Avg Items Per Invoice', 'resolve' => function ($query, $filters) { $rows = $query ->selectRaw('DATE_FORMAT(issuance_date, "%Y-%m") as label') ->selectRaw('AVG((SELECT COUNT(*) FROM invoice_items WHERE invoice_items.invoice_id = invoices.id)) as value') ->groupBy('label') ->orderBy('label') ->get(); return [ 'labels' => $rows->pluck('label')->toArray(), 'data' => $rows->pluck('value')->map(fn ($v) => round((float) $v, 1))->toArray(), ]; }, ]); }); // --- Stacked chart row --- $this->addMetricGroup([ 'class' => 'row mt-2', ], function () { $this->addMetric('invoices_by_series', [ 'type' => 'stacked-bar', 'label' => 'Invoices by Series', 'aggregate' => 'count', 'period' => 'issuance_date', 'stack_by' => 'series', ]); }); } } ================================================ FILE: app/Http/Controllers/Admin/PetShop/OwnerCrudController.php ================================================ fetch('App\Models\PetShop\Comment'); } /** * Configure the CrudPanel object. Apply settings to all operations. * * @return void */ public function setup() { CRUD::setModel(\App\Models\PetShop\Owner::class); CRUD::setRoute(config('backpack.base.route_prefix').'/pet-shop/owner'); CRUD::setEntityNameStrings('owner', 'owners'); } /** * Define what happens when the List operation is loaded. * * @see https://backpackforlaravel.com/docs/crud-operation-list-entries * * @return void */ protected function setupListOperation() { CRUD::column('name')->size(6); CRUD::column('avatar.url')->type('image')->label('Avatar')->size(6); CRUD::column('pets')->label('Pets')->linkTo('pet.show'); CRUD::column('invoices')->linkTo('invoice.show'); CRUD::column('badges')->label('Badges')->linkTo('badge.show'); CRUD::button('view_pets')->stack('line')->view('crud::buttons.quick')->meta([ 'access' => true, 'label' => 'View Pets', 'icon' => 'la la-paw', 'wrapper' => [ 'href' => function ($entry, $crud) { return url($crud->route.'/'.$entry->getKey().'/pets'); }, 'title' => 'view owner pets', ], ]); } /** * Define what happens when the Create operation is loaded. * * @see https://backpackforlaravel.com/docs/crud-operation-create * * @return void */ protected function setupCreateOperation() { CRUD::setValidation(OwnerRequest::class); CRUD::field('name'); CRUD::field('avatar.url')->type('browse')->label('Avatar')->hint('Edit one attribute on a morphOne related item (1-1).'); CRUD::field('pets')->subfields([ ['name' => 'role', 'type' => 'text'], ])->hint('Choose related entries with a belongsToMany relationship and pivot fields (n-n with pivot).'); CRUD::field('comments')->ajax('true')->hint('Choose related entries with a morphMany relationship (1-n).'); CRUD::field('badges')->subfields([ ['name' => 'note', 'type' => 'text'], ])->hint('Choose related entries with a morphToMany relationship and pivot fields (n-n with pivot).'); } /** * Define what happens when the Update operation is loaded. * * @see https://backpackforlaravel.com/docs/crud-operation-update * * @return void */ protected function setupUpdateOperation() { $this->setupCreateOperation(); } protected function setupReportOperation() { // --- Grouped stats with different refreshIntervals --- // Both metrics share a group, so the lowest interval (30s) wins for the whole group. $this->addMetricGroup([ 'class' => 'row', ], function () { $this->addMetric('total_owners', [ 'type' => 'stat', 'label' => 'Total Owners', 'aggregate' => 'count', 'period' => 'created_at', 'compare' => true, 'refreshInterval' => 30, 'wrapper' => ['class' => 'col-md-4'], ]); $this->addMetric('total_invoices', [ 'type' => 'stat', 'label' => 'Total Invoices', 'aggregate' => 'count', 'period' => 'issuance_date', 'query' => fn ($q) => $q->setModel(new \App\Models\PetShop\Invoice()), 'refreshInterval' => 60, 'wrapper' => ['class' => 'col-md-4'], ]); $this->addMetric('avg_pets_per_owner', [ 'type' => 'stat', 'label' => 'Avg Pets Per Owner', 'wrapper' => ['class' => 'col-md-4'], 'resolve' => fn ($query, $filters) => [ 'value' => round($query->withCount('pets')->get()->avg('pets_count'), 1), ], ]); }); // --- Charts --- $this->addMetricGroup([ 'class' => 'row mt-2', ], function () { $this->addMetric('owners_over_time', [ 'type' => 'line', 'label' => 'Owners Over Time', 'aggregate' => 'count', 'period' => 'created_at', ]); $this->addMetric('invoices_by_series', [ 'type' => 'pie', 'label' => 'Invoices by Series', 'column' => 'series', 'query' => fn ($q) => $q->setModel(new \App\Models\PetShop\Invoice()), ]); }); } protected function setupShowOperation() { $this->setupListOperation(); Widget::add([ 'type' => 'datatable', 'controller' => 'App\Http\Controllers\Admin\PetShop\PetCrudController', 'name' => 'pets_crud', 'section' => 'after_content', 'wrapper' => ['class' => 'mt-3'], 'content' => [ 'header' => 'Pets for this owner', // COULD-DO: maybe add support for a subheader? // 'subheader' => 'This is a list of all pets owned by this owner.', ], 'setup' => function ($crud, $parent) { // change some column attributes just inside this instance $crud->column('skills')->label('Pet skills'); $crud->column('passport.number')->label('Passport Number'); // only show the pets of this owner (owner is an n-n relationship) $crud->addClause('whereHas', 'owners', function ($query) use ($parent) { $query->where('id', $parent->id); }); }, ]); Widget::add([ 'type' => 'datatable', 'controller' => 'App\Http\Controllers\Admin\PetShop\InvoiceCrudController', 'name' => 'invoices_crud', 'section' => 'after_content', 'wrapper' => ['class' => 'mt-3'], 'content' => [ 'header' => 'Invoices for this owner', ], // MUST-DO: How the fuck do I make this only show related pets?!?! 'setup' => function ($crud, $parent) { // only show the pets of this owner (owner is an n-n relationship) $crud->addClause('where', 'owner_id', $parent->id); }, ]); } } ================================================ FILE: app/Http/Controllers/Admin/PetShop/OwnerPetsCrudController.php ================================================ owner = \Route::current()?->parameter('owner'); if (!$this->owner) { abort(404); } // set a different route for the admin panel CRUD::setRoute(config('backpack.base.route_prefix').'/pet-shop/owner/'.$this->owner.'/pets'); // show only that owner's pets CRUD::addBaseClause(function (Builder $query) { $query->whereHas('owners', function (Builder $query) { $query->where('owner_id', $this->owner) ->where('role', 'Owner'); }); }); } protected function setupCreateOperation() { parent::setupCreateOperation(); // remove the relationship field CRUD::removeField('owners'); // add an hidden field so that our stripRequest allow that key to go through. CRUD::field('owners')->type('hidden'); } protected function setupUpdateOperation() { parent::setupUpdateOperation(); // remove the relationship field CRUD::removeField('owners'); // add an hidden field so that our stripRequest allow that key to go through. CRUD::field('owners')->type('hidden'); } public function store() { CRUD::setRequest($this->addOwnerToRequest()); return $this->traitStore(); } public function update() { CRUD::setRequest($this->addOwnerToRequest()); return $this->traitUpdate(); } private function addOwnerToRequest() { return CRUD::getRequest()->merge([ 'owners' => [ [ 'owners' => $this->owner, 'role' => 'Owner', ], ], ]); } } ================================================ FILE: app/Http/Controllers/Admin/PetShop/PassportCrudController.php ================================================ 'number', 'type' => 'number', 'wrapperAttributes' => ['class' => 'form-group col-md-6']], ['name' => 'country', 'type' => 'select_from_array', 'options' => [ 'Austria' => 'Austria', 'Belgium' => 'Belgium', 'Bulgaria' => 'Bulgaria', 'Croatia' => 'Croatia', 'Republic of Cyprus' => 'Republic of Cyprus', 'Czech Republic' => 'Czech Republic', 'Denmark' => 'Denmark', 'Estonia' => 'Estonia', 'Finland' => 'Finland', 'France' => 'France', 'Germany' => 'Germany', 'Greece' => 'Greece', 'Hungary' => 'Hungary', 'Ireland' => 'Ireland', 'Italy' => 'Italy', 'Latvia' => 'Latvia', 'Lithuania' => 'Lithuania', 'Luxembourg' => 'Luxembourg', 'Malta' => 'Malta', 'Netherlands' => 'Netherlands', 'Poland' => 'Poland', 'Portugal' => 'Portugal', 'Romania' => 'Romania', 'Slovakia' => 'Slovakia', 'Slovenia' => 'Slovenia', 'Spain' => 'Spain', 'Sweden' => 'Sweden', ], 'wrapperAttributes' => ['class' => 'form-group col-md-6']], ['name' => 'issuance_date', 'type' => 'date', 'wrapperAttributes' => ['class' => 'form-group col-md-6']], ['name' => 'expiry_date', 'type' => 'date', 'wrapperAttributes' => ['class' => 'form-group col-md-6']], ['name' => 'first_name', 'type' => 'text', 'wrapperAttributes' => ['class' => 'form-group col-md-4']], ['name' => 'middle_name', 'type' => 'text', 'wrapperAttributes' => ['class' => 'form-group col-md-4']], ['name' => 'last_name', 'type' => 'text', 'wrapperAttributes' => ['class' => 'form-group col-md-4']], ['name' => 'birth_date', 'type' => 'date'], ['name' => 'species', 'type' => 'text', 'wrapperAttributes' => ['class' => 'form-group col-md-4']], ['name' => 'breed', 'type' => 'text', 'wrapperAttributes' => ['class' => 'form-group col-md-4']], ['name' => 'colour', 'type' => 'text', 'wrapperAttributes' => ['class' => 'form-group col-md-4']], ['name' => 'notes', 'type' => 'textarea'], ]; } /** * Define what happens when the Update operation is loaded. * * @see https://backpackforlaravel.com/docs/crud-operation-update * * @return void */ protected function setupUpdateOperation() { $this->setupCreateOperation(); } } ================================================ FILE: app/Http/Controllers/Admin/PetShop/PetCrudController.php ================================================ fetch('App\Models\PetShop\Comment'); } /** * Configure the CrudPanel object. Apply settings to all operations. * * @return void */ public function setup() { CRUD::setModel(\App\Models\PetShop\Pet::class); CRUD::setRoute(config('backpack.base.route_prefix').'/pet-shop/pet'); CRUD::setEntityNameStrings('pet', 'pets'); } /** * Define what happens when the List operation is loaded. * * @see https://backpackforlaravel.com/docs/crud-operation-list-entries * * @return void */ protected function setupListOperation() { CRUD::column('nickname'); CRUD::column('passport.number')->attribute('number')->linkTo('passport.show'); CRUD::column('owners')->linkTo('owner.show'); CRUD::column('skills')->linkTo('skill.show'); CRUD::column('avatar.url')->type('image')->label('Avatar'); CRUD::addButtonFromView('top', 'passports', 'passports'); CRUD::filter('skills') ->type('select2_multiple') ->values(function () { return \App\Models\Petshop\Skill::all()->keyBy('id')->pluck('name', 'id')->toArray(); }) ->whenActive(function ($values) { $values = json_decode($values, true); $this->crud->addClause('whereHas', 'skills', function ($query) use ($values) { $query->whereIn('id', $values); }); }); } /** * Define what happens when the Create operation is loaded. * * @see https://backpackforlaravel.com/docs/crud-operation-create * * @return void */ protected function setupCreateOperation() { CRUD::setValidation(PetRequest::class); CRUD::field('nickname'); CRUD::field('avatar.url')->type('browse')->label('Avatar')->hint('Edit one attribute on a morphMany related item (1-1).'); CRUD::field('owners')->subfields([['name' => 'role', 'type' => 'text']])->hint('Choose related Owners over a belongsToMany relationship, and edit "role" on the pivot table (n-n).'); CRUD::field('skills')->hint('Choose related Skills over a belongsToMany relationship (n-n).'); CRUD::field('passport')->subfields(\App\Http\Controllers\Admin\PetShop\PassportCrudController::passportFields())->hint('Create, update or delete a related hasOne entry entirely (1-n).'); CRUD::field('comments')->ajax('true')->hint('Choose related Comments over a morphMany relationship (n-n).'); CRUD::field('badges')->hint('Choose related Badges over a morphToMany relationship (n-n).'); } /** * Define what happens when the Update operation is loaded. * * @see https://backpackforlaravel.com/docs/crud-operation-update * * @return void */ protected function setupUpdateOperation() { $this->setupCreateOperation(); } protected function setupReportOperation() { // --- Static metric with auto-refresh: always shows the current total, polls every 30s --- $this->addMetric('total_pets_ever', [ 'type' => 'stat', 'label' => 'Total Pets (All Time)', 'aggregate' => 'count', 'section' => 'static', 'refreshInterval' => 5, 'wrapper' => ['class' => 'col-md-4'], ]); // --- Stat cards --- $this->addMetricGroup([ 'class' => 'row', ], function () { $this->addMetric('new_pets', [ 'type' => 'stat', 'label' => 'New Pets', 'aggregate' => 'count', 'period' => 'created_at', 'compare' => true, 'wrapper' => ['class' => 'col-md-4'], ]); $this->addMetric('trashed_pets', [ 'type' => 'stat', 'label' => 'Trashed Pets', 'description' => 'Soft-deleted pets in the selected period.', 'aggregate' => 'count', 'period' => 'deleted_at', 'query' => fn ($q) => $q->onlyTrashed(), 'wrapper' => ['class' => 'col-md-4'], ]); $this->addMetric('avg_skills', [ 'type' => 'stat', 'label' => 'Avg Skills Per Pet', 'wrapper' => ['class' => 'col-md-4'], 'resolve' => fn ($query, $filters) => [ 'value' => round($query->withCount('skills')->get()->avg('skills_count'), 1), ], ]); }); // --- Chart --- $this->addMetric('pets_over_time', [ 'type' => 'line', 'label' => 'Pets Over Time', 'aggregate' => 'count', 'period' => 'created_at', ]); } } ================================================ FILE: app/Http/Controllers/Admin/PetShop/SkillCrudController.php ================================================ type('relationship_count'); } /** * Define what happens when the Create operation is loaded. * * @see https://backpackforlaravel.com/docs/crud-operation-create * * @return void */ protected function setupCreateOperation() { CRUD::setValidation(SkillRequest::class); CRUD::field('name'); CRUD::field('pets'); } /** * Define what happens when the Update operation is loaded. * * @see https://backpackforlaravel.com/docs/crud-operation-update * * @return void */ protected function setupUpdateOperation() { $this->setupCreateOperation(); } } ================================================ FILE: app/Http/Controllers/Admin/ProductCrudController.php ================================================ 'status', 'type' => 'enum', 'enum_function' => 'getReadableStatus', ]); CRUD::addColumn([ 'name' => 'condition', 'type' => 'enum', 'enum_class' => 'App\Enums\ProductCondition', 'enum_function' => 'getReadableCondition', ]); CRUD::addColumn([ 'name' => 'price', 'type' => 'number', 'label' => 'Price', 'visibleInTable' => false, 'visibleInModal' => true, ]); CRUD::addColumn([ // 1-n relationship 'label' => 'Category', // Table column heading 'type' => 'select', 'name' => 'category_id', // the column that contains the ID of that connected entity; 'entity' => 'category', // the method that defines the relationship in your Model 'attribute' => 'name', // foreign key attribute that is shown to user 'visibleInTable' => true, 'visibleInModal' => false, ]); } protected function setupCreateOperation() { CRUD::setValidation(StoreRequest::class); CRUD::addField([ // Text 'name' => 'name', 'label' => 'Name', 'type' => 'text', 'tab' => 'Texts', // optional //'prefix' => '', //'suffix' => '', //'default' => 'some value', // default value //'hint' => 'Some hint text', // helpful text, show up after input //'attributes' => [ //'placeholder' => 'Some text when empty', //'class' => 'form-control some-class' //], // extra HTML attributes and values your input might need //'wrapperAttributes' => [ //'class' => 'form-group col-md-12' //], // extra HTML attributes for the field wrapper - mostly for resizing fields //'readonly'=>'readonly', ]); CRUD::addField([ // Textarea 'name' => 'description', 'label' => 'Description', 'type' => 'textarea', 'tab' => 'Texts', ]); CRUD::addField([ // summernote 'name' => 'details', 'label' => 'Details', 'type' => 'summernote', 'tab' => 'Texts', ]); CRUD::addField([ // Table 'name' => 'features', 'label' => 'Features', 'type' => 'table', 'entity_singular' => 'feature', // used on the "Add X" button 'columns' => [ 'name' => 'Feature', 'desc' => 'Value', ], 'max' => 25, // maximum rows allowed in the table 'min' => 0, // minimum rows allowed in the table 'tab' => 'Texts', ]); // Fake repeatable with translations CRUD::addField([ // Extra Features 'name' => 'extra_features', 'label' => 'Extra Features', 'type' => 'repeatable', 'tab' => 'Texts', 'store_in' => 'extras', 'fake' => true, 'subfields' => [ [ 'name' => 'feature', 'wrapper' => [ 'class' => 'col-md-3', ], ], [ 'name' => 'value', 'wrapper' => [ 'class' => 'col-md-6', ], ], [ 'name' => 'quantity', 'type' => 'number', 'wrapper' => [ 'class' => 'col-md-3', ], ], ], ]); CRUD::addField([ // Select2 'label' => 'Category', 'type' => 'select2', 'name' => 'category_id', // the db column for the foreign key 'entity' => 'category', // the method that defines the relationship in your Model 'attribute' => 'name', // foreign key attribute that is shown to user // 'wrapperAttributes' => [ // 'class' => 'form-group col-md-6' // ], // extra HTML attributes for the field wrapper - mostly for resizing fields 'tab' => 'Basic Info', ]); CRUD::addField([ // Number 'name' => 'price', 'label' => 'Price', 'type' => 'number', // optionals // 'attributes' => ["step" => "any"], // allow decimals 'prefix' => '$', 'suffix' => '.00', // 'wrapperAttributes' => [ // 'class' => 'form-group col-md-6' // ], // extra HTML attributes for the field wrapper - mostly for resizing fields 'tab' => 'Basic Info', ]); CRUD::addField([ // Number 'name' => 'status', 'label' => 'Status', 'type' => 'enum', 'tab' => 'Basic Info', ]); CRUD::addField([ // Number 'name' => 'condition', 'label' => 'Condition', 'type' => 'enum', 'tab' => 'Basic Info', 'enum_class' => 'App\Enums\ProductCondition', 'enum_function' => 'getReadableCondition', ]); CRUD::addFields([ [ // Text 'name' => 'meta_title', 'label' => 'Meta Title', 'type' => 'text', 'fake' => true, 'tab' => 'Metas', ], [ // Text 'name' => 'meta_description', 'label' => 'Meta Description', 'type' => 'text', 'fake' => true, 'tab' => 'Metas', ], [ // Text 'name' => 'meta_keywords', 'label' => 'Meta Keywords', 'type' => 'text', 'fake' => true, 'tab' => 'Metas', ], ]); CRUD::field('main_image') ->label('Main Image') ->type('image') ->tab('Media') ->wrapper(['class' => 'form-group col-md-4']) ->disabledInProduction() ->withMedia(); CRUD::field('privacy_policy') ->label('Privacy policy document') ->type('upload') ->tab('Media') ->wrapper(['class' => 'form-group col-md-4']) ->disabledInProduction() ->withMedia(); CRUD::field('specifications') ->label('Specifications') ->type('upload_multiple') ->tab('Media') ->wrapper(['class' => 'form-group col-md-4']) ->disabledInProduction() ->withMedia(); CRUD::field('gallery') ->type('repeatable') ->tab('Media') ->subfields([ [ 'name' => 'image_title', 'type' => 'text', 'wrapper' => [ 'class' => 'form-group col-md-6', ], ], [ 'name' => 'gallery_image', 'label' => 'image', 'type' => 'image', 'wrapper' => [ 'class' => 'form-group col-md-6', ], 'withMedia' => true, ], [ 'name' => 'gallery_image_drm', 'label' => 'Image DRM', 'type' => 'upload', 'wrapper' => [ 'class' => 'form-group col-md-6', ], 'withMedia' => true, ], [ 'name' => 'gallery_image_specifications', 'label' => 'Image Specifications', 'type' => 'upload_multiple', 'wrapper' => [ 'class' => 'form-group col-md-6', ], 'withMedia' => true, ], [ 'name' => 'gallery_image_certificates', 'label' => 'Image Certificates', 'type' => 'dropzone', 'wrapper' => [ 'class' => 'form-group col-md-6', ], 'withMedia' => true, ], ]) ->when(app('env') == 'production', function ($field) { return $field->remove(); }); $this->crud->setOperationSetting('contentClass', 'col-md-12'); } protected function setupUpdateOperation() { $this->setupCreateOperation(); } public function ajaxUpload() { if (app('env') === 'production') { return response()->json(['errors' => [ 'dropzone' => ['Uploads are disabled in production'], ], ], 500); } return $this->traitAjaxUpload(); } protected function setupReportOperation() { // --- Stat cards --- $this->addMetricGroup([ 'class' => 'row', ], function () { $this->addMetric('total_products', [ 'type' => 'stat', 'label' => 'Total Products', 'aggregate' => 'count', 'period' => 'created_at', 'compare' => 'previous_period', 'wrapper' => ['class' => 'col-md-6'], ]); $this->addMetric('avg_price', [ 'type' => 'stat', 'label' => 'Avg Price', 'column' => 'price', 'aggregate' => 'avg', 'format' => '$:value', 'period' => 'created_at', 'wrapper' => ['class' => 'col-md-6'], ]); }); // --- Charts --- $this->addMetricGroup([ 'class' => 'row mt-2', ], function () { $this->addMetric('products_over_time', [ 'type' => 'line', 'label' => 'Products Over Time', 'aggregate' => 'count', 'period' => 'created_at', ]); $this->addMetric('price_sum_over_time', [ 'type' => 'bar', 'label' => 'Total Price Per Period', 'column' => 'price', 'aggregate' => 'sum', 'period' => 'created_at', ]); }); // --- Pie chart --- $this->addMetricGroup([ 'class' => 'row mt-2', ], function () { $this->addMetric('products_by_status', [ 'type' => 'pie', 'label' => 'Products by Status', 'column' => 'status', 'colors' => [ 'in-stock' => 'rgba(0, 200, 83, 0.8)', 'out-of-stock' => 'rgba(255, 99, 132, 0.8)', 'on-hold' => 'rgba(255, 206, 86, 0.8)', ], ]); }); // --- Table metric --- $this->addMetric('top_products_table', [ 'type' => 'table', 'label' => 'Top Products by Price', 'group_by' => 'status', 'columns' => [ 'status' => 'Status', 'product_count' => ['label' => 'Products', 'aggregate' => 'count'], 'avg_price' => ['label' => 'Avg Price', 'aggregate' => 'avg', 'column' => 'price', 'format' => '$:value'], 'total_price' => ['label' => 'Total Price', 'aggregate' => 'sum', 'column' => 'price', 'format' => '$:value'], ], ]); } } ================================================ FILE: app/Http/Controllers/Admin/StoryCrudController.php ================================================ attribute('text'); CRUD::column('heroes'); } /** * Define what happens when the Create operation is loaded. * * @see https://backpackforlaravel.com/docs/crud-operation-create * * @return void */ protected function setupCreateOperation() { CRUD::setValidation(StoryRequest::class); CRUD::setOperationSetting('contentClass', 'col-md-12'); CRUD::field('name'); CRUD::field('monsters') ->label('Monsters'.backpack_new_badge()) ->subfields(self::getMonsterSubfields()) ->hint('Create/update/delete related Monsters over a hasMany relationship (1-n).'); } /** * Define what happens when the Update operation is loaded. * * @see https://backpackforlaravel.com/docs/crud-operation-update * * @return void */ protected function setupUpdateOperation() { $this->setupCreateOperation(); } public static function getMonsterSubfields() { return CaveCrudController::getMonsterSubfields(); } public function ajaxUpload() { if (app('env') === 'production') { return response()->json(['errors' => [ 'message' => 'This operation is not available in production.', ]], 500); } return $this->traitAjaxUpload(); } } ================================================ FILE: app/Http/Controllers/Admin/UserCrudController.php ================================================ input('q'); $keys = $request->input('keys'); // keys are present when select2_from_ajax fields are initialized inside a repeatable field if ($keys) { return Article::findMany($keys); } if ($search_term) { return Article::where('title', 'LIKE', '%'.$search_term.'%')->paginate(10); } else { return Article::paginate(10); } } // used by the select2_from_ajax FILTER // inside MonsterCrudController and FluentMonsterCrudController public function search(Request $request) { $term = $request->input('term'); $options = Article::where('title', 'like', '%'.$term.'%')->get()->pluck('title', 'id'); return $options; } } ================================================ FILE: app/Http/Controllers/Controller.php ================================================ [ \App\Http\Middleware\EncryptCookies::class, \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class, \Illuminate\Session\Middleware\StartSession::class, \Illuminate\View\Middleware\ShareErrorsFromSession::class, \App\Http\Middleware\VerifyCsrfToken::class, \App\Http\Middleware\Theme::class, ], 'api' => [ 'throttle:60,1', ], ]; /** * The application's route middleware. * * These middleware may be assigned to groups or used individually. * * @var array */ protected $middlewareAliases = [ 'auth' => \App\Http\Middleware\Authenticate::class, 'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class, 'can' => \Illuminate\Foundation\Http\Middleware\Authorize::class, 'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class, 'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class, 'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class, 'signed' => \App\Http\Middleware\ValidateSignature::class, ]; } ================================================ FILE: app/Http/Middleware/Authenticate.php ================================================ guest()) { if ($request->ajax() || $request->wantsJson()) { return response('Unauthorized.', 401); } else { return redirect()->guest('login'); } } return $next($request); } } ================================================ FILE: app/Http/Middleware/CheckIfAdmin.php ================================================ is_admin == 1); return true; } /** * Answer to unauthorized access request. * * @param [type] $request [description] * * @return [type] [description] */ private function respondToUnauthorizedRequest($request) { if ($request->ajax() || $request->wantsJson()) { return response(trans('backpack::base.unauthorized'), 401); } else { return redirect()->guest(backpack_url('login')); } } /** * Handle an incoming request. * * @param \Illuminate\Http\Request $request * @param \Closure $next * * @return mixed */ public function handle($request, Closure $next) { if (backpack_auth()->guest()) { return $this->respondToUnauthorizedRequest($request); } if (!$this->checkIfUserIsAdmin(backpack_user())) { return $this->respondToUnauthorizedRequest($request); } return $next($request); } } ================================================ FILE: app/Http/Middleware/EncryptCookies.php ================================================ check()) { return redirect('/'); } return $next($request); } } ================================================ FILE: app/Http/Middleware/Theme.php ================================================ */ protected $except = [ // 'fbclid', // 'utm_campaign', // 'utm_content', // 'utm_medium', // 'utm_source', // 'utm_term', ]; } ================================================ FILE: app/Http/Middleware/VerifyCsrfToken.php ================================================ check(); } /** * Get the validation rules that apply to the request. * * @return array */ public function rules() { return [ 'name' => 'required|string', ]; } /** * Get the validation attributes that apply to the request. * * @return array */ public function attributes() { return [ // ]; } /** * Get the validation messages that apply to the request. * * @return array */ public function messages() { return [ // ]; } } ================================================ FILE: app/Http/Requests/CaveRequest.php ================================================ check(); } /** * Get the validation rules that apply to the request. * * @return array */ public function rules() { return [ 'name' => 'required|string', 'monster.*.text' => 'required|string', 'monster.*.status' => 'required', ]; } /** * Get the validation attributes that apply to the request. * * @return array */ public function attributes() { return [ // ]; } /** * Get the validation messages that apply to the request. * * @return array */ public function messages() { return [ 'monster.*.text.required' => 'The "Monster > Text" field is required.', 'monster.*.status.required' => 'The "Monster > Status" field is required.', ]; } } ================================================ FILE: app/Http/Requests/CommentRequest.php ================================================ check(); } /** * Get the validation rules that apply to the request. * * @return array */ public function rules() { return [ 'body' => 'required|string', 'commentable.commentable_type' => 'required|string', 'commentable.commentable_id' => 'required|integer', 'user' => 'required', ]; } /** * Get the validation attributes that apply to the request. * * @return array */ public function attributes() { return [ // ]; } /** * Get the validation messages that apply to the request. * * @return array */ public function messages() { return [ 'commentable.commentable_id' => 'This field is required.', ]; } } ================================================ FILE: app/Http/Requests/DummyRequest.php ================================================ check(); } /** * Get the validation rules that apply to the request. * * @return array */ public function rules() { return [ 'name' => 'required|min:5|max:255', 'description' => 'required', 'simple.*.text' => 'required|min:10|max:255', 'simple.*.email' => 'required|email', ]; } /** * Get the validation attributes that apply to the request. * * @return array */ public function attributes() { return [ // ]; } /** * Get the validation messages that apply to the request. * * @return array */ public function messages() { return [ 'simple.*.text.required' => 'The "Simple > Text" field is required.', 'simple.*.text.min' => 'The "Simple > Text" field must be at least :min characters long.', 'simple.*.email.required' => 'The "Simple > Email" field is required.', ]; } } ================================================ FILE: app/Http/Requests/HeroRequest.php ================================================ check(); } /** * Get the validation rules that apply to the request. * * @return array */ public function rules() { return [ 'name' => 'required|string', ]; } /** * Get the validation attributes that apply to the request. * * @return array */ public function attributes() { return [ // ]; } /** * Get the validation messages that apply to the request. * * @return array */ public function messages() { return [ // ]; } } ================================================ FILE: app/Http/Requests/IconRequest.php ================================================ check(); } /** * Get the validation rules that apply to the request. * * @return array */ public function rules() { return [ 'name' => 'required|min:5|max:255', 'icon' => 'required', ]; } /** * Get the validation attributes that apply to the request. * * @return array */ public function attributes() { return [ // ]; } /** * Get the validation messages that apply to the request. * * @return array */ public function messages() { return [ // ]; } } ================================================ FILE: app/Http/Requests/InvoiceRequest.php ================================================ check(); } /** * Get the validation rules that apply to the request. * * @return array */ public function rules() { return [ 'owner' => 'required|integer|exists:owners,id', 'series' => 'required|string', 'number' => 'required|integer', 'issuance_date' => 'required|date', 'due_date' => 'nullable|date', 'items' => 'required', 'items.*.order' => 'nullable|integer', 'items.*.description' => 'required|string', 'items.*.quantity' => 'required|numeric', 'items.*.unit_price' => 'required|numeric', ]; } /** * Get the validation attributes that apply to the request. * * @return array */ public function attributes() { return [ // ]; } /** * Get the validation messages that apply to the request. * * @return array */ public function messages() { return [ // ]; } } ================================================ FILE: app/Http/Requests/MeetingRequest.php ================================================ check(); } /** * Get the validation rules that apply to the request. * * @return array */ public function rules() { return [ 'start' => 'required|date', 'end' => 'nullable|date|after:start', 'background_color' => 'nullable|hex_color', 'text_color' => 'nullable|hex_color', ]; } } ================================================ FILE: app/Http/Requests/MonsterRequest.php ================================================ check(); } /** * Get the validation rules that apply to the request. * * @return array */ public function rules() { return [ 'text' => 'required|min:5|max:255', 'email' => 'nullable|email', // 'icondummy' => 'required', ]; } /** * Get the validation attributes that apply to the request. * * @return array */ public function attributes() { return [ // ]; } /** * Get the validation messages that apply to the request. * * @return array */ public function messages() { return [ 'icondummy.required' => 'The field "Relationships (all field attributes are guessed)" in #Relationships tab is required.', ]; } } ================================================ FILE: app/Http/Requests/OwnerRequest.php ================================================ check(); } /** * Get the validation rules that apply to the request. * * @return array */ public function rules() { return [ 'name' => 'required|string', 'avatar.url' => 'required|string', 'pets.*.pets' => 'required', 'pets.*.role' => 'required|string', ]; } /** * Get the validation attributes that apply to the request. * * @return array */ public function attributes() { return [ // ]; } /** * Get the validation messages that apply to the request. * * @return array */ public function messages() { return [ // ]; } } ================================================ FILE: app/Http/Requests/PassportRequest.php ================================================ check(); } /** * Get the validation rules that apply to the request. * * @return array */ public function rules() { return [ 'pet' => 'required|integer|exists:pets,id', 'number' => 'required|string', 'issuance_date' => 'required|date', 'expiry_date' => 'nullable|date', 'first_name' => 'required|string', 'middle_name' => 'nullable|string', 'last_name' => 'required|string', 'birth_date' => 'required|date', 'species' => 'required|string', 'breed' => 'nullable|string', 'colour' => 'nullable|string', 'notes' => 'nullable|string', 'country' => 'required|string', ]; } /** * Get the validation attributes that apply to the request. * * @return array */ public function attributes() { return [ // ]; } /** * Get the validation messages that apply to the request. * * @return array */ public function messages() { return [ // ]; } } ================================================ FILE: app/Http/Requests/PetRequest.php ================================================ check(); } /** * Get the validation rules that apply to the request. * * @return array */ public function rules() { return [ 'nickname' => 'required|string', 'avatar.url' => 'required', ]; } /** * Get the validation attributes that apply to the request. * * @return array */ public function attributes() { return [ // ]; } /** * Get the validation messages that apply to the request. * * @return array */ public function messages() { return [ // ]; } } ================================================ FILE: app/Http/Requests/ProductRequest.php ================================================ check(); } /** * Get the validation rules that apply to the request. * * @return array */ public function rules() { return [ 'name' => 'required|min:3|max:255', 'category_id' => 'required', 'price' => 'required|integer', ]; } /** * Get the validation attributes that apply to the request. * * @return array */ public function attributes() { return [ // ]; } /** * Get the validation messages that apply to the request. * * @return array */ public function messages() { return [ // ]; } } ================================================ FILE: app/Http/Requests/Request.php ================================================ check(); } /** * Get the validation rules that apply to the request. * * @return array */ public function rules() { return [ 'name' => 'required|string', ]; } /** * Get the validation attributes that apply to the request. * * @return array */ public function attributes() { return [ // ]; } /** * Get the validation messages that apply to the request. * * @return array */ public function messages() { return [ // ]; } } ================================================ FILE: app/Http/Requests/StoryRequest.php ================================================ check(); } /** * Get the validation rules that apply to the request. * * @return array */ public function rules() { return [ 'name' => 'required|string', 'monsters.*.text' => 'required|string', 'monsters.*.status' => 'required', ]; } /** * Get the validation attributes that apply to the request. * * @return array */ public function attributes() { return [ // ]; } /** * Get the validation messages that apply to the request. * * @return array */ public function messages() { return [ 'monsters.*.text.required' => 'The "Monsters > Text" field is required.', 'monsters.*.status.required' => 'The "Monsters > Status" field is required.', ]; } } ================================================ FILE: app/Jobs/Job.php ================================================ belongsTo(\App\Models\Monster::class, 'monster_id'); } public function country() { return $this->belongsTo(\App\Models\Country::class); } } ================================================ FILE: app/Models/Article.php ================================================ 'integer', ]; /* |-------------------------------------------------------------------------- | GLOBAL VARIABLES |-------------------------------------------------------------------------- */ protected $table = 'balls'; protected $primaryKey = 'id'; public $timestamps = true; protected $guarded = ['id']; // protected $hidden = []; /* |-------------------------------------------------------------------------- | FUNCTIONS |-------------------------------------------------------------------------- */ /* |-------------------------------------------------------------------------- | RELATIONS |-------------------------------------------------------------------------- */ public function ballable() { return $this->morphTo(); } public function country() { return $this->belongsTo(\App\Models\Country::class); } /* |-------------------------------------------------------------------------- | SCOPES |-------------------------------------------------------------------------- */ /* |-------------------------------------------------------------------------- | ACCESORS |-------------------------------------------------------------------------- */ /* |-------------------------------------------------------------------------- | MUTATORS |-------------------------------------------------------------------------- */ } ================================================ FILE: app/Models/Bill.php ================================================ morphedByMany(\App\Models\Monster::class, 'billable'); } public function icons() { return $this->morphedByMany(\App\Models\Icon::class, 'billable'); } /* |-------------------------------------------------------------------------- | SCOPES |-------------------------------------------------------------------------- */ /* |-------------------------------------------------------------------------- | ACCESORS |-------------------------------------------------------------------------- */ /* |-------------------------------------------------------------------------- | MUTATORS |-------------------------------------------------------------------------- */ } ================================================ FILE: app/Models/Category.php ================================================ 'integer', ]; public function monster() { return $this->hasOne(\App\Models\Monster::class); } public function category() { return $this->monster()->getRelated()->category(); } protected function location(): \Illuminate\Database\Eloquent\Casts\Attribute { return \Illuminate\Database\Eloquent\Casts\Attribute::make( get: function ($value, $attributes) { return json_encode([ 'lat' => $attributes['lat'], 'lng' => $attributes['lng'], 'formatted_address' => $attributes['full_address'] ?? '', ], JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_AMP | JSON_HEX_QUOT | JSON_THROW_ON_ERROR); }, set: function ($value) { $location = json_decode($value); return [ 'lat' => $location->lat, 'lng' => $location->lng, 'full_address' => $location->formatted_address ?? '', ]; } ); } } ================================================ FILE: app/Models/Country.php ================================================ hasMany(\App\Models\Address::class); } /* |-------------------------------------------------------------------------- | SCOPES |-------------------------------------------------------------------------- */ /* |-------------------------------------------------------------------------- | ACCESORS |-------------------------------------------------------------------------- */ /* |-------------------------------------------------------------------------- | MUTATORS |-------------------------------------------------------------------------- */ } ================================================ FILE: app/Models/Dummy.php ================================================ 'array', ]; /* |-------------------------------------------------------------------------- | FUNCTIONS |-------------------------------------------------------------------------- */ /* |-------------------------------------------------------------------------- | RELATIONS |-------------------------------------------------------------------------- */ public function article() { return $this->belongsTo(\Backpack\NewsCRUD\app\Models\Article::class, 'select2_from_ajax'); } public function category() { return $this->belongsTo(\Backpack\NewsCRUD\app\Models\Category::class, 'select'); } public function categories() { return $this->belongsToMany(\Backpack\NewsCRUD\app\Models\Category::class, 'monster_category', 'monster_id', 'category_id'); } public function tags() { return $this->belongsToMany(\Backpack\NewsCRUD\app\Models\Tag::class, 'monster_tag', 'monster_id', 'category_id'); } public function icon() { return $this->belongsTo(\App\Models\Icon::class, 'icon_id'); } public function products() { return $this->belongsToMany(\App\Models\Product::class, 'monster_product', 'monster_id', 'product_id'); } public function articles() { return $this->belongsToMany(\Backpack\NewsCRUD\app\Models\Article::class, 'monster_article', 'monster_id', 'article_id'); } public function categorySelect2() { return $this->belongsTo(\Backpack\NewsCRUD\app\Models\Category::class, 'select2'); } /* |-------------------------------------------------------------------------- | SCOPES |-------------------------------------------------------------------------- */ /* |-------------------------------------------------------------------------- | ACCESSORS |-------------------------------------------------------------------------- */ /* |-------------------------------------------------------------------------- | MUTATORS |-------------------------------------------------------------------------- */ } ================================================ FILE: app/Models/Graffiti.php ================================================ 'integer', ]; /* |-------------------------------------------------------------------------- | GLOBAL VARIABLES |-------------------------------------------------------------------------- */ protected $table = 'graffitis'; protected $primaryKey = 'id'; public $timestamps = true; protected $guarded = ['id']; // protected $hidden = []; /* |-------------------------------------------------------------------------- | FUNCTIONS |-------------------------------------------------------------------------- */ /* |-------------------------------------------------------------------------- | RELATIONS |-------------------------------------------------------------------------- */ public function user() { return $this->belongsTo(\App\User::class); } public function monsters() { return $this->hasMany(\App\Models\Monster::class, 'graffiti_id'); } /* |-------------------------------------------------------------------------- | SCOPES |-------------------------------------------------------------------------- */ /* |-------------------------------------------------------------------------- | ACCESORS |-------------------------------------------------------------------------- */ /* |-------------------------------------------------------------------------- | MUTATORS |-------------------------------------------------------------------------- */ } ================================================ FILE: app/Models/Hero.php ================================================ 'integer', ]; public function stories() { return $this->belongsToMany(\App\Models\Story::class, 'monsters') ->withPivot(array_filter((new \App\Models\Monster())->getFillable(), function ($item) { // fields that are on fillable but are not part of model table $columnsToRemove = ['fake-text', 'fake-switch', 'fake-select', 'fake-checkbox', 'editable_checkbox']; return !in_array($item, $columnsToRemove); })); } } ================================================ FILE: app/Models/Icon.php ================================================ morphToMany(\App\Models\Recommend::class, 'recommendable'); } /* |-------------------------------------------------------------------------- | SCOPES |-------------------------------------------------------------------------- */ /* |-------------------------------------------------------------------------- | ACCESORS |-------------------------------------------------------------------------- */ /* |-------------------------------------------------------------------------- | MUTATORS |-------------------------------------------------------------------------- */ } ================================================ FILE: app/Models/Meeting.php ================================================ 'array', ]; } ================================================ FILE: app/Models/MenuItem.php ================================================ 'object', 'video' => 'array', 'upload_multiple' => 'array', 'browse_multiple' => 'array', 'status' => MonsterStatus::class, 'features' => 'array', 'table' => 'array', 'extras' => 'array', // optional casts for select from array fields that allow multiple selection // 'select_from_array' => 'array', // 'select2_from_array' => 'array' ]; public $identifiableAttribute = 'text'; /* |-------------------------------------------------------------------------- | FUNCTIONS |-------------------------------------------------------------------------- */ public function openGoogle($crud = false) { return ' Google it'; } public function getCategory() { return $this->category; } /* |-------------------------------------------------------------------------- | RELATIONS |-------------------------------------------------------------------------- */ public function article() { return $this->belongsTo(\Backpack\NewsCRUD\app\Models\Article::class, 'select2_from_ajax'); } public function wish() { return $this->hasOne(\App\Models\Wish::class); } public function address() { return $this->hasOne(\App\Models\Address::class); } public function cave() { return $this->belongsTo(\App\Models\Cave::class, 'cave_id'); } public function hero() { return $this->belongsTo(\App\Models\Hero::class, 'hero_id'); } public function story() { return $this->belongsTo(\App\Models\Story::class, 'story_id'); } public function graffiti() { return $this->belongsTo(\App\Models\Graffiti::class, 'graffiti_id'); } public function category() { return $this->belongsTo(\Backpack\NewsCRUD\app\Models\Category::class, 'select'); } public function categorySelect2() { return $this->belongsTo(\Backpack\NewsCRUD\app\Models\Category::class, 'select2'); } public function categoryRelationship() { return $this->belongsTo(\Backpack\NewsCRUD\app\Models\Category::class, 'category_relationship'); } public function icon() { return $this->belongsTo(\App\Models\Icon::class, 'icon_id'); } public function icondummy() { return $this->belongsTo(\App\Models\Icon::class, 'belongs_to_non_nullable'); } public function postalboxes() { return $this->hasMany(\App\Models\PostalBox::class); } public function postalboxer() { return $this->hasMany(\App\Models\PostalBoxer::class); } public function articles() { return $this->belongsToMany(\Backpack\NewsCRUD\app\Models\Article::class, 'monster_article'); } public function categories() { return $this->belongsToMany(\Backpack\NewsCRUD\app\Models\Category::class, 'monster_category'); } public function tags() { return $this->belongsToMany(\Backpack\NewsCRUD\app\Models\Tag::class, 'monster_tag'); } public function products() { return $this->belongsToMany(\App\Models\Product::class, 'monster_product'); } public function dummyproducts() { return $this->belongsToMany(\App\Models\Product::class, 'monster_productdummy')->withPivot('notes'); } public function countries() { return $this->belongsToMany(\App\Models\Country::class, 'countries_monsters'); } public function sentiment() { return $this->morphOne(\App\Models\Sentiment::class, 'sentimentable'); } public function ball() { return $this->morphOne(\App\Models\Ball::class, 'ballable'); } public function recommends() { return $this->morphToMany(\App\Models\Recommend::class, 'recommendable')->withPivot('text'); } public function bills() { return $this->morphToMany(\App\Models\Bill::class, 'billable'); } public function stars() { return $this->morphMany(\App\Models\Star::class, 'starable'); } public function universes() { return $this->morphMany(\App\Models\Universe::class, 'universable'); } /* |-------------------------------------------------------------------------- | SCOPES |-------------------------------------------------------------------------- */ /* |-------------------------------------------------------------------------- | ACCESORS |-------------------------------------------------------------------------- */ public function getTextAndEmailAttribute() { return $this->text.' '.$this->email; } /** * Because we don't trust that the 'easymde' db column does not already * have some JS or HTML stored inside it, we will run strip_tags() on * the value before it's ever used (both in Backpack and in the app). */ public function getEasymdeAttribute($value) { return strip_tags($value); } /** * Because we don't trust that the 'summernote' db column does not already * have some JS stored inside the HTML, we will sanitize the output using * https://github.com/mewebstudio/Purifier. */ public function getSummernoteAttribute($value) { return clean($value); } /* |-------------------------------------------------------------------------- | MUTATORS |-------------------------------------------------------------------------- */ public function setBase64ImageAttribute($value) { if (app('env') == 'production') { \Alert::warning('In the online demo the base64 images don\'t get stored.'); return true; } $this->attributes['base64_image'] = $value; } public function setDropzoneAttribute($value) { if (app('env') === 'production') { \Alert::warning('In the online demo the dropzone files don\'t get stored.'); return true; } $this->attributes['dropzone'] = $value; } public function setImageAttribute($value) { if (app('env') == 'production') { \Alert::warning('In the online demo the images don\'t get uploaded.')->flash(); return true; } $attribute_name = 'image'; $disk = 'public'; // use Backpack's root disk; or your own $destination_path = 'uploads/monsters/image_field'; // if the image was erased if ($value == null) { // delete the image from disk if ($this->{$attribute_name}) { \Storage::disk($disk)->delete($this->{$attribute_name}); } // set null in the database column $this->attributes[$attribute_name] = null; } // if a base64 was sent, store it in the db if (Str::startsWith($value, 'data:image')) { // 0. Make the image $image = \Image::make($value)->encode('jpg', 90); // 1. Generate a filename. $filename = md5($value.time()).'.jpg'; // 2. Store the image on disk. \Storage::disk($disk)->put($destination_path.'/'.$filename, $image->stream()); // delete previous image from the disk if ($this->{$attribute_name}) { \Storage::disk($disk)->delete($this->{$attribute_name}); } // 4. Save the public path to the database // but first, remove "public/" from the path, since we're pointing to it from the root folder // that way, what gets saved in the database is the user-accesible URL $public_destination_path = Str::replaceFirst('public/', '', $destination_path); $this->attributes[$attribute_name] = $public_destination_path.'/'.$filename; } } public function setUploadAttribute($value) { if (app('env') == 'production') { \Alert::warning('In the online demo the files don\'t get uploaded.'); return true; } $attribute_name = 'upload'; $disk = 'public'; $destination_path = 'uploads/monsters/upload_field'; $this->uploadFileToDisk($value, $attribute_name, $disk, $destination_path); // return $this->attributes[{$attribute_name}]; // uncomment if this is a translatable field } public function setUploadMultipleAttribute($value) { if (app('env') == 'production') { \Alert::warning('In the online demo the files don\'t get uploaded.')->flash(); return true; } $attribute_name = 'upload_multiple'; $disk = 'public'; $destination_path = 'uploads/monsters/upload_multiple_field'; $this->uploadMultipleFilesToDisk($value, $attribute_name, $disk, $destination_path); } public function setIcondummyAttribute($value) { $this->attributes['belongs_to_non_nullable'] = $value; } } ================================================ FILE: app/Models/Page.php ================================================ 'integer', ]; public function avatarable() { return $this->morphTo(); } } ================================================ FILE: app/Models/PetShop/Badge.php ================================================ 'integer', ]; public function owners() { return $this->morphedByMany(\App\Models\PetShop\Owner::class, 'badgeable'); } public function pets() { return $this->morphedByMany(\App\Models\PetShop\Pet::class, 'badgeable'); } } ================================================ FILE: app/Models/PetShop/Comment.php ================================================ 'integer', ]; /* |-------------------------------------------------------------------------- | GLOBAL VARIABLES |-------------------------------------------------------------------------- */ protected $table = 'comments'; protected $primaryKey = 'id'; public $timestamps = true; protected $guarded = ['id']; // protected $hidden = []; /* |-------------------------------------------------------------------------- | FUNCTIONS |-------------------------------------------------------------------------- */ /* |-------------------------------------------------------------------------- | RELATIONS |-------------------------------------------------------------------------- */ public function commentable() { return $this->morphTo(); } public function user() { return $this->belongsTo(\App\User::class); } /* |-------------------------------------------------------------------------- | SCOPES |-------------------------------------------------------------------------- */ /* |-------------------------------------------------------------------------- | ACCESORS |-------------------------------------------------------------------------- */ /* |-------------------------------------------------------------------------- | MUTATORS |-------------------------------------------------------------------------- */ } ================================================ FILE: app/Models/PetShop/Invoice.php ================================================ 'integer', 'owner_id' => 'integer', 'issuance_date' => 'date', 'due_date' => 'date', ]; protected $appends = [ 'total', ]; /* |-------------------------------------------------------------------------- | FUNCTIONS |-------------------------------------------------------------------------- */ protected static function booted() { static::forceDeleting(function (Invoice $invoice) { $invoice->items()->delete(); }); } /* |-------------------------------------------------------------------------- | RELATIONS |-------------------------------------------------------------------------- */ public function owner() { return $this->belongsTo(\App\Models\PetShop\Owner::class, 'owner_id'); } public function items() { return $this->hasMany(\App\Models\PetShop\InvoiceItem::class); } /* |-------------------------------------------------------------------------- | SCOPES |-------------------------------------------------------------------------- */ /* |-------------------------------------------------------------------------- | ACCESORS |-------------------------------------------------------------------------- */ public function getTotalAttribute() { return $this->items->sum('subtotal'); } /* |-------------------------------------------------------------------------- | MUTATORS |-------------------------------------------------------------------------- */ } ================================================ FILE: app/Models/PetShop/InvoiceItem.php ================================================ 'integer', 'invoice_id' => 'integer', 'quantity' => 'float', 'unit_price' => 'float', ]; protected $appends = [ 'subtotal', ]; /* |-------------------------------------------------------------------------- | FUNCTIONS |-------------------------------------------------------------------------- */ /* |-------------------------------------------------------------------------- | RELATIONS |-------------------------------------------------------------------------- */ public function invoice() { return $this->belongsTo(\App\Models\PetShop\Invoice::class); } /* |-------------------------------------------------------------------------- | SCOPES |-------------------------------------------------------------------------- */ /* |-------------------------------------------------------------------------- | ACCESORS |-------------------------------------------------------------------------- */ public function getSubtotalAttribute() { return $this->quantity * $this->unit_price; } /* |-------------------------------------------------------------------------- | MUTATORS |-------------------------------------------------------------------------- */ } ================================================ FILE: app/Models/PetShop/Owner.php ================================================ 'integer', ]; public function invoices() { return $this->hasMany(\App\Models\PetShop\Invoice::class); } public function pets() { return $this->belongsToMany(\App\Models\PetShop\Pet::class)->withPivot('role'); } public function avatar() { return $this->morphOne(\App\Models\PetShop\Avatar::class, 'avatarable'); } public function comments() { return $this->morphMany(Comment::class, 'commentable'); } public function badges() { return $this->morphToMany(\App\Models\PetShop\Badge::class, 'badgeable')->withPivot('note'); } } ================================================ FILE: app/Models/PetShop/Passport.php ================================================ 'integer', 'pet_id' => 'integer', 'issuance_date' => 'date:Y-m-d', 'expiry_date' => 'date:Y-m-d', 'birth_date' => 'date:Y-m-d', ]; public function pet() { return $this->belongsTo(\App\Models\PetShop\Pet::class, 'pet_id'); } } ================================================ FILE: app/Models/PetShop/Pet.php ================================================ 'integer', ]; public function owners() { return $this->belongsToMany(\App\Models\PetShop\Owner::class)->withPivot('role'); } public function skills() { return $this->belongsToMany(\App\Models\PetShop\Skill::class); } public function passport() { return $this->hasOne(\App\Models\PetShop\Passport::class); } public function avatar() { return $this->morphOne(\App\Models\PetShop\Avatar::class, 'avatarable'); } public function comments() { return $this->morphMany(\App\Models\PetShop\Comment::class, 'commentable'); } public function badges() { return $this->morphToMany(\App\Models\PetShop\Badge::class, 'badgeable')->withPivot('note'); } } ================================================ FILE: app/Models/PetShop/Skill.php ================================================ 'integer', ]; public function pets() { return $this->belongsToMany(\App\Models\PetShop\Pet::class); } } ================================================ FILE: app/Models/PostalBox.php ================================================ belongsTo(\App\Models\Monster::class, 'monster_id'); } } ================================================ FILE: app/Models/PostalBoxer.php ================================================ belongsTo(\App\Models\Monster::class, 'monster_id'); } /* |-------------------------------------------------------------------------- | SCOPES |-------------------------------------------------------------------------- */ /* |-------------------------------------------------------------------------- | ACCESORS |-------------------------------------------------------------------------- */ /* |-------------------------------------------------------------------------- | MUTATORS |-------------------------------------------------------------------------- */ } ================================================ FILE: app/Models/Product.php ================================================ 'object', 'extra_features' => 'object', 'status' => ProductStatus::class, 'gallery' => 'json', 'specifications' => 'array', ]; public function mainImage(): Attribute { return Attribute::make( set: function ($item) { if (app('env') === 'production') { return null; } return $item; }, ); } public function privacyPolicy(): Attribute { return Attribute::make( set: function ($item) { if (app('env') === 'production') { return null; } return $item; }, ); } public function specifications(): Attribute { return Attribute::make( set: function ($item) { if (app('env') === 'production') { return null; } return json_encode($item); }, ); } public function gallery(): Attribute { return Attribute::make( set: function ($item) { if (app('env') === 'production') { $item = is_string($item) ? json_decode($item, true) : ($item ?? []); array_walk($item, function (&$row) { unset($row['gallery_image'], $row['gallery_image_drm'], $row['gallery_image_specifications'], $row['gallery_image_certificates']); return $row; }); } return json_encode($item); }, ); } /* |-------------------------------------------------------------------------- | FUNCTIONS |-------------------------------------------------------------------------- */ /* |-------------------------------------------------------------------------- | RELATIONS |-------------------------------------------------------------------------- */ public function category() { return $this->belongsTo('Backpack\NewsCRUD\app\Models\Category', 'category_id'); } /* |-------------------------------------------------------------------------- | SCOPES |-------------------------------------------------------------------------- */ /* |-------------------------------------------------------------------------- | ACCESORS |-------------------------------------------------------------------------- */ /* |-------------------------------------------------------------------------- | MUTATORS |-------------------------------------------------------------------------- */ } ================================================ FILE: app/Models/Recommend.php ================================================ morphedByMany(\App\Models\Monster::class, 'recommendable'); } public function icons() { return $this->morphedByMany(\App\Models\Icon::class, 'recommendable'); } /* |-------------------------------------------------------------------------- | SCOPES |-------------------------------------------------------------------------- */ /* |-------------------------------------------------------------------------- | ACCESORS |-------------------------------------------------------------------------- */ /* |-------------------------------------------------------------------------- | MUTATORS |-------------------------------------------------------------------------- */ } ================================================ FILE: app/Models/Sentiment.php ================================================ 'integer', ]; /* |-------------------------------------------------------------------------- | GLOBAL VARIABLES |-------------------------------------------------------------------------- */ protected $table = 'sentiments'; protected $primaryKey = 'id'; public $timestamps = true; protected $guarded = ['id']; // protected $hidden = []; /* |-------------------------------------------------------------------------- | FUNCTIONS |-------------------------------------------------------------------------- */ /* |-------------------------------------------------------------------------- | RELATIONS |-------------------------------------------------------------------------- */ public function sentimentable() { return $this->morphTo(); } public function user() { return $this->belongsTo(\App\User::class); } /* |-------------------------------------------------------------------------- | SCOPES |-------------------------------------------------------------------------- */ /* |-------------------------------------------------------------------------- | ACCESORS |-------------------------------------------------------------------------- */ /* |-------------------------------------------------------------------------- | MUTATORS |-------------------------------------------------------------------------- */ } ================================================ FILE: app/Models/Star.php ================================================ morphTo(); } /* |-------------------------------------------------------------------------- | SCOPES |-------------------------------------------------------------------------- */ /* |-------------------------------------------------------------------------- | ACCESORS |-------------------------------------------------------------------------- */ /* |-------------------------------------------------------------------------- | MUTATORS |-------------------------------------------------------------------------- */ } ================================================ FILE: app/Models/Story.php ================================================ 'integer', ]; public function monsters() { return $this->hasMany(\App\Models\Monster::class); } public function heroes() { return $this->belongsToMany(\App\Models\Hero::class, 'monsters') ->withPivot(array_filter((new \App\Models\Monster())->getFillable(), function ($item) { // fields that are on fillable but are not part of model table $columnsToRemove = ['fake-text', 'fake-switch', 'fake-select', 'fake-checkbox', 'editable_checkbox']; return !in_array($item, $columnsToRemove); })); } } ================================================ FILE: app/Models/Tag.php ================================================ logAll() ->logOnlyDirty(); } } ================================================ FILE: app/Models/Universe.php ================================================ morphTo(); } /* |-------------------------------------------------------------------------- | SCOPES |-------------------------------------------------------------------------- */ /* |-------------------------------------------------------------------------- | ACCESORS |-------------------------------------------------------------------------- */ /* |-------------------------------------------------------------------------- | MUTATORS |-------------------------------------------------------------------------- */ } ================================================ FILE: app/Models/Wish.php ================================================ 'integer', ]; /* |-------------------------------------------------------------------------- | GLOBAL VARIABLES |-------------------------------------------------------------------------- */ protected $table = 'wishes'; protected $primaryKey = 'id'; public $timestamps = true; protected $guarded = ['id']; // protected $hidden = []; /* |-------------------------------------------------------------------------- | FUNCTIONS |-------------------------------------------------------------------------- */ /* |-------------------------------------------------------------------------- | RELATIONS |-------------------------------------------------------------------------- */ public function monster() { return $this->belongsTo(\App\Models\Monster::class); } public function country() { return $this->belongsTo(\App\Models\Country::class); } public function universes() { return $this->belongsToMany(\App\Models\Universe::class, 'universes_wishes'); } /* |-------------------------------------------------------------------------- | SCOPES |-------------------------------------------------------------------------- */ /* |-------------------------------------------------------------------------- | ACCESORS |-------------------------------------------------------------------------- */ /* |-------------------------------------------------------------------------- | MUTATORS |-------------------------------------------------------------------------- */ } ================================================ FILE: app/PageTemplates.php ================================================ crud->addField([ // CustomHTML 'name' => 'metas_separator', 'type' => 'custom_html', 'value' => '

Metas


', ]); $this->crud->addField([ 'name' => 'meta_title', 'label' => 'Meta Title', 'fake' => true, 'store_in' => 'extras', ]); $this->crud->addField([ 'name' => 'meta_description', 'label' => 'Meta Description', 'fake' => true, 'store_in' => 'extras', ]); $this->crud->addField([ 'name' => 'meta_keywords', 'type' => 'textarea', 'label' => 'Meta Keywords', 'fake' => true, 'store_in' => 'extras', ]); $this->crud->addField([ // CustomHTML 'name' => 'content_separator', 'type' => 'custom_html', 'value' => '

Content


', ]); $this->crud->addField([ 'name' => 'content', 'label' => 'Content', 'type' => 'summernote', 'placeholder' => 'Your content here', ]); } private function about_us() { $this->crud->addField([ 'name' => 'content', 'label' => 'Content', 'type' => 'summernote', 'placeholder' => 'Your content here', ]); } } ================================================ FILE: app/Policies/.gitkeep ================================================ ================================================ FILE: app/Providers/AppServiceProvider.php ================================================ 'App\Models\Monster', 'user' => 'App\User', ]); PanConfiguration::allowedAnalytics([ 'my-button', 'welcome-page', 'welcome-login-link', 'welcome-docs-link', 'welcome-github-link', 'welcome-contact-link', 'login-form', 'menu-item-dashboard', 'menu-item-addons', 'menu-item-petshop', 'menu-item-news', 'menu-item-auth', 'menu-item-filemanager', 'menu-item-activity-log', 'menu-item-translation-manager', 'menu-item-calendar-operation', 'menu-item-backup-manager', 'menu-item-log-manager', 'menu-item-settings', 'menu-item-page-manager', 'menu-item-menu-manager', 'menu-item-analytics', ]); } /** * Register any application services. * * @return void */ public function register() { // override user crud controller $this->app->bind( \Backpack\PermissionManager\app\Http\Controllers\UserCrudController::class, \App\Http\Controllers\Admin\UserCrudController::class ); // a simple helper to make fields disabled in production CrudField::macro('disabledInProduction', function () { if (app('env') !== 'production') { return $this; } return $this->attributes(['disabled' => 'disabled']) ->hint('Uploads are disabled in production.'); }); } } ================================================ FILE: app/Providers/AuthServiceProvider.php ================================================ 'App\Policies\ModelPolicy', ]; /** * Register any authentication / authorization services. * * @return void */ public function boot() { $this->registerPolicies(); // } } ================================================ FILE: app/Providers/BroadcastServiceProvider.php ================================================ id === (int) $userId; }); } } ================================================ FILE: app/Providers/EventServiceProvider.php ================================================ [ 'App\Listeners\EventListener', ], ]; /** * Register any events for your application. * * @return void */ public function boot() { parent::boot(); // } } ================================================ FILE: app/Providers/RouteServiceProvider.php ================================================ mapWebRoutes(); $this->mapApiRoutes(); // } /** * Define the "web" routes for the application. * * These routes all receive session state, CSRF protection, etc. * * @return void */ protected function mapWebRoutes() { Route::group([ 'middleware' => 'web', 'namespace' => $this->namespace, ], function ($router) { require base_path('routes/web.php'); }); } /** * Define the "api" routes for the application. * * These routes are typically stateless. * * @return void */ protected function mapApiRoutes() { Route::group([ 'middleware' => 'api', 'namespace' => $this->namespace, 'prefix' => 'api', ], function ($router) { require base_path('routes/api.php'); }); } } ================================================ FILE: app/User.php ================================================ runningInConsole() && !app()->runningUnitTests()) { Alert::warning('User editing is disabled in the demo.'); return true; } return parent::save($options); } } ================================================ FILE: app/helpers.php ================================================ '.$string.''; } } if (!function_exists('backpack_new_badge')) { /** * Echo a yellow badge to tell the viewer this is a NEW feature. * * @param string $string * * @return string */ function backpack_new_badge(string $string = 'NEW') { return ''.$string.''; } } if (!function_exists('backpack_free_badge')) { /** * Echo a green badge to tell the viewer this is a FREE feature. * * @param string $string * * @return string */ function backpack_free_badge(string $string = 'FREE') { return ''.$string.''; } } ================================================ FILE: artisan ================================================ #!/usr/bin/env php make(Illuminate\Contracts\Console\Kernel::class); $status = $kernel->handle( $input = new Symfony\Component\Console\Input\ArgvInput, new Symfony\Component\Console\Output\ConsoleOutput ); /* |-------------------------------------------------------------------------- | Shutdown The Application |-------------------------------------------------------------------------- | | Once Artisan has finished running. We will fire off the shutdown events | so that any final work may be done by the application before we shut | down the process. This is the last thing to happen to the request. | */ $kernel->terminate($input, $status); exit($status); ================================================ FILE: bootstrap/app.php ================================================ singleton( Illuminate\Contracts\Http\Kernel::class, App\Http\Kernel::class ); $app->singleton( Illuminate\Contracts\Console\Kernel::class, App\Console\Kernel::class ); $app->singleton( Illuminate\Contracts\Debug\ExceptionHandler::class, App\Exceptions\Handler::class ); /* |-------------------------------------------------------------------------- | Return The Application |-------------------------------------------------------------------------- | | This script returns the application instance. The instance is given to | the calling script so we can separate the building of the instances | from the actual running of the application and sending responses. | */ return $app; ================================================ FILE: bootstrap/autoload.php ================================================ env('APP_ENV', 'production'), /* |-------------------------------------------------------------------------- | Application Debug Mode |-------------------------------------------------------------------------- | | When your application is in debug mode, detailed error messages with | stack traces will be shown on every error that occurs within your | application. If disabled, a simple generic error page is shown. | */ 'debug' => env('APP_DEBUG', false), /* |-------------------------------------------------------------------------- | Application URL |-------------------------------------------------------------------------- | | This URL is used by the console to properly generate URLs when using | the Artisan command line tool. You should set this to the root of | your application so that it is used when running Artisan tasks. | */ 'url' => env('APP_URL', 'http://localhost'), /* |-------------------------------------------------------------------------- | Application Timezone |-------------------------------------------------------------------------- | | Here you may specify the default timezone for your application, which | will be used by the PHP date and date-time functions. We have gone | ahead and set this to a sensible default for you out of the box. | */ 'timezone' => 'UTC', /* |-------------------------------------------------------------------------- | Application Locale Configuration |-------------------------------------------------------------------------- | | The application locale determines the default locale that will be used | by the translation service provider. You are free to set this value | to any of the locales which will be supported by the application. | */ 'locale' => 'en', /* |-------------------------------------------------------------------------- | Application Fallback Locale |-------------------------------------------------------------------------- | | The fallback locale determines the locale to use when the current one | is not available. You may change the value to correspond to any of | the language folders that are provided through your application. | */ 'fallback_locale' => 'en', /* |-------------------------------------------------------------------------- | Encryption Key |-------------------------------------------------------------------------- | | This key is used by the Illuminate encrypter service and should be set | to a random, 32 character string, otherwise these encrypted strings | will not be safe. Please do this before deploying an application! | */ 'key' => env('APP_KEY'), 'cipher' => 'AES-256-CBC', /* |-------------------------------------------------------------------------- | Logging Configuration |-------------------------------------------------------------------------- | | Here you may configure the log settings for your application. Out of | the box, Laravel uses the Monolog PHP logging library. This gives | you a variety of powerful log handlers / formatters to utilize. | | Available Settings: "single", "daily", "syslog", "errorlog" | */ 'log' => env('APP_LOG', 'daily'), /* |-------------------------------------------------------------------------- | Autoloaded Service Providers |-------------------------------------------------------------------------- | | The service providers listed here will be automatically loaded on the | request to your application. Feel free to add your own services to | this array to grant expanded functionality to your applications. | */ 'providers' => [ /* * Laravel Framework Service Providers... */ Illuminate\Auth\AuthServiceProvider::class, Illuminate\Broadcasting\BroadcastServiceProvider::class, Illuminate\Bus\BusServiceProvider::class, Illuminate\Cache\CacheServiceProvider::class, Illuminate\Foundation\Providers\ConsoleSupportServiceProvider::class, Illuminate\Cookie\CookieServiceProvider::class, Illuminate\Database\DatabaseServiceProvider::class, Illuminate\Encryption\EncryptionServiceProvider::class, Illuminate\Filesystem\FilesystemServiceProvider::class, Illuminate\Foundation\Providers\FoundationServiceProvider::class, Illuminate\Hashing\HashServiceProvider::class, Illuminate\Mail\MailServiceProvider::class, Illuminate\Pagination\PaginationServiceProvider::class, Illuminate\Pipeline\PipelineServiceProvider::class, Illuminate\Queue\QueueServiceProvider::class, Illuminate\Redis\RedisServiceProvider::class, Illuminate\Auth\Passwords\PasswordResetServiceProvider::class, Illuminate\Session\SessionServiceProvider::class, // Illuminate\Translation\TranslationServiceProvider::class, Spatie\TranslationLoader\TranslationServiceProvider::class, Illuminate\Validation\ValidationServiceProvider::class, Illuminate\View\ViewServiceProvider::class, Illuminate\Notifications\NotificationServiceProvider::class, /* * Application Service Providers... */ App\Providers\AppServiceProvider::class, App\Providers\AuthServiceProvider::class, App\Providers\EventServiceProvider::class, App\Providers\RouteServiceProvider::class, /* * Other Service Providers... */ ], /* |-------------------------------------------------------------------------- | Class Aliases |-------------------------------------------------------------------------- | | This array of class aliases will be registered when this application | is started. However, feel free to register as many as you wish as | the aliases are "lazy" loaded so they don't hinder performance. | */ 'aliases' => Facade::defaultAliases()->merge([ /* * Other Aliases... */ ])->toArray(), ]; ================================================ FILE: config/auth.php ================================================ [ 'guard' => 'web', 'passwords' => 'users', ], /* |-------------------------------------------------------------------------- | Authentication Guards |-------------------------------------------------------------------------- | | Next, you may define every authentication guard for your application. | Of course, a great default configuration has been defined for you | here which uses session storage and the Eloquent user provider. | | All authentication drivers have a user provider. This defines how the | users are actually retrieved out of your database or other storage | mechanisms used by this application to persist your user's data. | | Supported: "session", "token" | */ 'guards' => [ 'web' => [ 'driver' => 'session', 'provider' => 'users', ], 'api' => [ 'driver' => 'token', 'provider' => 'users', ], ], /* |-------------------------------------------------------------------------- | User Providers |-------------------------------------------------------------------------- | | All authentication drivers have a user provider. This defines how the | users are actually retrieved out of your database or other storage | mechanisms used by this application to persist your user's data. | | If you have multiple user tables or models you may configure multiple | sources which represent each model / table. These sources may then | be assigned to any extra authentication guards you have defined. | | Supported: "database", "eloquent" | */ 'providers' => [ 'users' => [ 'driver' => 'eloquent', 'model' => App\User::class, ], // 'users' => [ // 'driver' => 'database', // 'table' => 'users', // ], ], /* |-------------------------------------------------------------------------- | Resetting Passwords |-------------------------------------------------------------------------- | | Here you may set the options for resetting passwords including the view | that is your password reset e-mail. You may also set the name of the | table that maintains all of the reset tokens for your application. | | You may specify multiple password reset configurations if you have more | than one user table or model in the application and you want to have | separate password reset settings based on the specific user types. | | The expire time is the number of minutes that the reset token should be | considered valid. This security feature keeps tokens short-lived so | they have less time to be guessed. You may change this as needed. | */ 'passwords' => [ 'users' => [ 'provider' => 'users', 'email' => 'auth.emails.password', 'table' => 'password_resets', 'expire' => 60, ], ], ]; ================================================ FILE: config/backpack/base.php ================================================ env('BACKPACK_REGISTRATION_OPEN', env('APP_ENV') === 'local'), /* |-------------------------------------------------------------------------- | Routing |-------------------------------------------------------------------------- */ // The prefix used in all base routes (the 'admin' in admin/dashboard) // You can make sure all your URLs use this prefix by using the backpack_url() helper instead of url() 'route_prefix' => 'admin', // Set this to false if you would like to use your own AuthController and PasswordController // (you then need to setup your auth routes manually in your routes.php file) 'setup_auth_routes' => true, // Set this to false if you would like to skip adding the dashboard routes // (you then need to overwrite the login route on your AuthController) 'setup_dashboard_routes' => true, // Set this to false if you would like to skip adding "my account" routes // (you then need to manually define the routes in your web.php) 'setup_my_account_routes' => true, // Set this to true if you would like to enable email verification for your user model. // Make sure your user model implements the MustVerifyEmail contract and your database // table contains the `email_verified_at` column. Read the following before enabling: // https://backpackforlaravel.com/docs/6.x/base-how-to#enable-email-verification-in-backpack-routes 'setup_email_verification_routes' => (env('APP_ENV') === 'local'), // When email verification is enabled, automatically add the Verified middleware to Backpack routes? // Set false if you want to use your own Verified middleware in `middleware_class`. 'setup_email_verification_middleware' => true, // How many times in any given time period should the user be allowed to // request a new verification email? // Defaults to 1,10 - 1 time in 10 minutes. 'email_verification_throttle_access' => '3,15', /* |-------------------------------------------------------------------------- | Authentication |-------------------------------------------------------------------------- */ // Fully qualified namespace of the User model 'user_model_fqn' => App\User::class, // The classes for the middleware to check if the visitor is an admin // Can be a single class or an array of clases 'middleware_class' => [ App\Http\Middleware\CheckIfAdmin::class, \Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class, \Backpack\LanguageSwitcher\Http\Middleware\LanguageSwitcherMiddleware::class, // \Backpack\CRUD\app\Http\Middleware\UseBackpackAuthGuardInsteadOfDefaultAuthGuard::class, ], // Alias for that middleware 'middleware_key' => 'admin', // Note: It's recommended to use the backpack_middleware() helper everywhere, which pulls this key for you. // Username column for authentication // The Backpack default is the same as the Laravel default (email) // If you need to switch to username, you also need to create that column in your db 'authentication_column' => 'email', 'authentication_column_name' => 'Email', // The guard that protects the Backpack admin panel. // If null, the config.auth.defaults.guard value will be used. 'guard' => 'backpack', // The password reset configuration for Backpack. // If null, the config.auth.defaults.passwords value will be used. 'passwords' => 'backpack', // What kind of avatar will you like to show to the user? // Default: gravatar (automatically use the gravatar for his email) // Other options: // - placehold (generic image with his first letter) // - example_method_name (specify the method on the User model that returns the URL) 'avatar_type' => 'gravatar', /* |-------------------------------------------------------------------------- | File System |-------------------------------------------------------------------------- */ // Backpack\Base sets up its own filesystem disk, just like you would by // adding an entry to your config/filesystems.php. It points to the root // of your project and it's used throughout all Backpack packages. // // You can rename this disk here. Default: root 'root_disk_name' => 'root', ]; ================================================ FILE: config/backpack/crud.php ================================================ [ /* * List Operation */ 'list' => [ // Define the size/looks of the content div for all CRUDs // To override per view use $this->crud->setListContentClass('class-string') 'contentClass' => 'col-md-12', // enable the datatables-responsive plugin, which hides columns if they don't fit? // if not, a horizontal scrollbar will be shown instead 'responsiveTable' => true, // stores pagination and filters in localStorage for two hours // whenever the user tries to see that page, backpack loads the previous pagination and filtration 'persistentTable' => true, // How many items should be shown by default by the Datatable? // This value can be overwritten on a specific CRUD by calling // $this->crud->setDefaultPageLength(50); 'defaultPageLength' => 10, // A 1D array of options which will be used for both the displayed option and the value, or // A 2D array in which the first array is used to define the value options and the second array the displayed options // If a 2D array is used, strings in the right hand array will be automatically run through trans() 'pageLengthMenu' => [[10, 25, 50, 100, -1], [10, 25, 50, 100, 'backpack::crud.all']], // How important is it for the action buttons to be visible? // - 0 - most important // - 1 - as important as bulk buttons // - 2-3 - more important than the rest of the columns // - 4 - less important than most columns 'actionsColumnPriority' => 1, ], /* * Create Operation */ 'create' => [ // Define the size/looks of the content div for all CRUDs // To override per view use $this->crud->setCreateContentClass('class-string') 'contentClass' => 'col-md-8 bold-labels', // When using tabbed forms (create & update), what kind of tabs would you like? 'tabsType' => 'horizontal', //options: horizontal, vertical // How would you like the validation errors to be shown? 'groupedErrors' => true, 'inlineErrors' => true, // when the page loads, put the cursor on the first input? 'autoFocusOnFirstField' => true, // Where do you want to redirect the user by default, save? // options: save_and_back, save_and_edit, save_and_new 'defaultSaveAction' => 'save_and_back', // When the user chooses "save and back" or "save and new", show a bubble // for the fact that the default save action has been changed? 'showSaveActionChange' => true, //options: true, false ], /* * Update Operation */ 'update' => [ // Define the size/looks of the content div for all CRUDs // To override per view use $this->crud->setEditContentClass('class-string') 'contentClass' => 'col-md-8 bold-labels', // When using tabbed forms (create & update), what kind of tabs would you like? 'tabsType' => 'horizontal', //options: horizontal, vertical // How would you like the validation errors to be shown? 'groupedErrors' => true, 'inlineErrors' => true, // when the page loads, put the cursor on the first input? 'autoFocusOnFirstField' => true, // Where do you want to redirect the user by default, save? // options: save_and_back, save_and_edit, save_and_new 'defaultSaveAction' => 'save_and_back', // When the user chooses "save and back" or "save and new", show a bubble // for the fact that the default save action has been changed? 'showSaveActionChange' => true, //options: true, false ], /* * Show Operation */ 'show' => [ // Define the size/looks of the content div for all CRUDs // To override per Controller use $this->crud->setShowContentClass('class-string') 'contentClass' => 'col-md-8', ], /* * Reorder Operation */ 'reorder' => [ // Define the size/looks of the content div for all CRUDs // To override per Controller use $this->crud->setReorderContentClass('class-string') 'contentClass' => 'col-md-8 col-md-offset-2', ], /* * Revise Operation */ 'revise' => [ // Define the size/looks of the content div for all CRUDs // To override per view use $this->crud->set('revise.timelineContentClass') 'timelineContentClass' => 'col-md-11', ], ], /* |------------------- | TRANSLATABLE CRUDS |------------------- */ 'show_translatable_field_icon' => true, 'translatable_field_icon_position' => 'right', // left or right 'locales' => [ // "af_NA" => "Afrikaans (Namibia)", // "af_ZA" => "Afrikaans (South Africa)", // "af" => "Afrikaans", // "ak_GH" => "Akan (Ghana)", // "ak" => "Akan", // "sq_AL" => "Albanian (Albania)", // "sq" => "Albanian", // "am_ET" => "Amharic (Ethiopia)", // "am" => "Amharic", // "ar_DZ" => "Arabic (Algeria)", // "ar_BH" => "Arabic (Bahrain)", // "ar_EG" => "Arabic (Egypt)", // "ar_IQ" => "Arabic (Iraq)", // "ar_JO" => "Arabic (Jordan)", // "ar_KW" => "Arabic (Kuwait)", // "ar_LB" => "Arabic (Lebanon)", // "ar_LY" => "Arabic (Libya)", // "ar_MA" => "Arabic (Morocco)", // "ar_OM" => "Arabic (Oman)", // "ar_QA" => "Arabic (Qatar)", // "ar_SA" => "Arabic (Saudi Arabia)", // "ar_SD" => "Arabic (Sudan)", // "ar_SY" => "Arabic (Syria)", // "ar_TN" => "Arabic (Tunisia)", // "ar_AE" => "Arabic (United Arab Emirates)", // "ar_YE" => "Arabic (Yemen)", // "ar" => "Arabic", // "hy_AM" => "Armenian (Armenia)", // "hy" => "Armenian", // "as_IN" => "Assamese (India)", // "as" => "Assamese", // "asa_TZ" => "Asu (Tanzania)", // "asa" => "Asu", // "az_Cyrl" => "Azerbaijani (Cyrillic)", // "az_Cyrl_AZ" => "Azerbaijani (Cyrillic, Azerbaijan)", // "az_Latn" => "Azerbaijani (Latin)", // "az_Latn_AZ" => "Azerbaijani (Latin, Azerbaijan)", // "az" => "Azerbaijani", // "bm_ML" => "Bambara (Mali)", // "bm" => "Bambara", // "eu_ES" => "Basque (Spain)", // "eu" => "Basque", // "be_BY" => "Belarusian (Belarus)", // "be" => "Belarusian", // "bem_ZM" => "Bemba (Zambia)", // "bem" => "Bemba", // "bez_TZ" => "Bena (Tanzania)", // "bez" => "Bena", // "bn_BD" => "Bengali (Bangladesh)", // "bn_IN" => "Bengali (India)", // "bn" => "Bengali", // "bs_BA" => "Bosnian (Bosnia and Herzegovina)", // "bs" => "Bosnian", // "bg_BG" => "Bulgarian (Bulgaria)", // "bg" => "Bulgarian", // "my_MM" => "Burmese (Myanmar [Burma])", // "my" => "Burmese", // "ca_ES" => "Catalan (Spain)", // "ca" => "Catalan", // "tzm_Latn" => "Central Morocco Tamazight (Latin)", // "tzm_Latn_MA" => "Central Morocco Tamazight (Latin, Morocco)", // "tzm" => "Central Morocco Tamazight", // "chr_US" => "Cherokee (United States)", // "chr" => "Cherokee", // "cgg_UG" => "Chiga (Uganda)", // "cgg" => "Chiga", // "zh_Hans" => "Chinese (Simplified Han)", // "zh_Hans_CN" => "Chinese (Simplified Han, China)", // "zh_Hans_HK" => "Chinese (Simplified Han, Hong Kong SAR China)", // "zh_Hans_MO" => "Chinese (Simplified Han, Macau SAR China)", // "zh_Hans_SG" => "Chinese (Simplified Han, Singapore)", // "zh_Hant" => "Chinese (Traditional Han)", // "zh_Hant_HK" => "Chinese (Traditional Han, Hong Kong SAR China)", // "zh_Hant_MO" => "Chinese (Traditional Han, Macau SAR China)", // "zh_Hant_TW" => "Chinese (Traditional Han, Taiwan)", // "zh" => "Chinese", // "kw_GB" => "Cornish (United Kingdom)", // "kw" => "Cornish", // "hr_HR" => "Croatian (Croatia)", // "hr" => "Croatian", // "cs_CZ" => "Czech (Czech Republic)", // "cs" => "Czech", // "da_DK" => "Danish (Denmark)", // "da" => "Danish", // "nl_BE" => "Dutch (Belgium)", // "nl_NL" => "Dutch (Netherlands)", // "nl" => "Dutch", // "ebu_KE" => "Embu (Kenya)", // "ebu" => "Embu", // "en_AS" => "English (American Samoa)", // "en_AU" => "English (Australia)", // "en_BE" => "English (Belgium)", // "en_BZ" => "English (Belize)", // "en_BW" => "English (Botswana)", // "en_CA" => "English (Canada)", // "en_GU" => "English (Guam)", // "en_HK" => "English (Hong Kong SAR China)", // "en_IN" => "English (India)", // "en_IE" => "English (Ireland)", // "en_JM" => "English (Jamaica)", // "en_MT" => "English (Malta)", // "en_MH" => "English (Marshall Islands)", // "en_MU" => "English (Mauritius)", // "en_NA" => "English (Namibia)", // "en_NZ" => "English (New Zealand)", // "en_MP" => "English (Northern Mariana Islands)", // "en_PK" => "English (Pakistan)", // "en_PH" => "English (Philippines)", // "en_SG" => "English (Singapore)", // "en_ZA" => "English (South Africa)", // "en_TT" => "English (Trinidad and Tobago)", // "en_UM" => "English (U.S. Minor Outlying Islands)", // "en_VI" => "English (U.S. Virgin Islands)", // "en_GB" => "English (United Kingdom)", // "en_US" => "English (United States)", // "en_ZW" => "English (Zimbabwe)", 'en' => 'English', // "eo" => "Esperanto", // "et_EE" => "Estonian (Estonia)", // "et" => "Estonian", // "ee_GH" => "Ewe (Ghana)", // "ee_TG" => "Ewe (Togo)", // "ee" => "Ewe", // "fo_FO" => "Faroese (Faroe Islands)", // "fo" => "Faroese", // "fil_PH" => "Filipino (Philippines)", // "fil" => "Filipino", // "fi_FI" => "Finnish (Finland)", // "fi" => "Finnish", // "fr_BE" => "French (Belgium)", // "fr_BJ" => "French (Benin)", // "fr_BF" => "French (Burkina Faso)", // "fr_BI" => "French (Burundi)", // "fr_CM" => "French (Cameroon)", // "fr_CA" => "French (Canada)", // "fr_CF" => "French (Central African Republic)", // "fr_TD" => "French (Chad)", // "fr_KM" => "French (Comoros)", // "fr_CG" => "French (Congo - Brazzaville)", // "fr_CD" => "French (Congo - Kinshasa)", // "fr_CI" => "French (Côte d’Ivoire)", // "fr_DJ" => "French (Djibouti)", // "fr_GQ" => "French (Equatorial Guinea)", // "fr_FR" => "French (France)", // "fr_GA" => "French (Gabon)", // "fr_GP" => "French (Guadeloupe)", // "fr_GN" => "French (Guinea)", // "fr_LU" => "French (Luxembourg)", // "fr_MG" => "French (Madagascar)", // "fr_ML" => "French (Mali)", // "fr_MQ" => "French (Martinique)", // "fr_MC" => "French (Monaco)", // "fr_NE" => "French (Niger)", // "fr_RW" => "French (Rwanda)", // "fr_RE" => "French (Réunion)", // "fr_BL" => "French (Saint Barthélemy)", // "fr_MF" => "French (Saint Martin)", // "fr_SN" => "French (Senegal)", // "fr_CH" => "French (Switzerland)", // "fr_TG" => "French (Togo)", 'fr' => 'French', // "ff_SN" => "Fulah (Senegal)", // "ff" => "Fulah", // "gl_ES" => "Galician (Spain)", // "gl" => "Galician", // "lg_UG" => "Ganda (Uganda)", // "lg" => "Ganda", // "ka_GE" => "Georgian (Georgia)", // "ka" => "Georgian", // "de_AT" => "German (Austria)", // "de_BE" => "German (Belgium)", // "de_DE" => "German (Germany)", // "de_LI" => "German (Liechtenstein)", // "de_LU" => "German (Luxembourg)", // "de_CH" => "German (Switzerland)", // "de" => "German", // "el_CY" => "Greek (Cyprus)", // "el_GR" => "Greek (Greece)", // "el" => "Greek", // "gu_IN" => "Gujarati (India)", // "gu" => "Gujarati", // "guz_KE" => "Gusii (Kenya)", // "guz" => "Gusii", // "ha_Latn" => "Hausa (Latin)", // "ha_Latn_GH" => "Hausa (Latin, Ghana)", // "ha_Latn_NE" => "Hausa (Latin, Niger)", // "ha_Latn_NG" => "Hausa (Latin, Nigeria)", // "ha" => "Hausa", // "haw_US" => "Hawaiian (United States)", // "haw" => "Hawaiian", // "he_IL" => "Hebrew (Israel)", // "he" => "Hebrew", // "hi_IN" => "Hindi (India)", // "hi" => "Hindi", // "hu_HU" => "Hungarian (Hungary)", // "hu" => "Hungarian", // "is_IS" => "Icelandic (Iceland)", // "is" => "Icelandic", // "ig_NG" => "Igbo (Nigeria)", // "ig" => "Igbo", // "id_ID" => "Indonesian (Indonesia)", // "id" => "Indonesian", // "ga_IE" => "Irish (Ireland)", // "ga" => "Irish", // "it_IT" => "Italian (Italy)", // "it_CH" => "Italian (Switzerland)", // 'it' => 'Italian', // "ja_JP" => "Japanese (Japan)", // "ja" => "Japanese", // "kea_CV" => "Kabuverdianu (Cape Verde)", // "kea" => "Kabuverdianu", // "kab_DZ" => "Kabyle (Algeria)", // "kab" => "Kabyle", // "kl_GL" => "Kalaallisut (Greenland)", // "kl" => "Kalaallisut", // "kln_KE" => "Kalenjin (Kenya)", // "kln" => "Kalenjin", // "kam_KE" => "Kamba (Kenya)", // "kam" => "Kamba", // "kn_IN" => "Kannada (India)", // "kn" => "Kannada", // "kk_Cyrl" => "Kazakh (Cyrillic)", // "kk_Cyrl_KZ" => "Kazakh (Cyrillic, Kazakhstan)", // "kk" => "Kazakh", // "km_KH" => "Khmer (Cambodia)", // "km" => "Khmer", // "ki_KE" => "Kikuyu (Kenya)", // "ki" => "Kikuyu", // "rw_RW" => "Kinyarwanda (Rwanda)", // "rw" => "Kinyarwanda", // "kok_IN" => "Konkani (India)", // "kok" => "Konkani", // "ko_KR" => "Korean (South Korea)", // "ko" => "Korean", // "khq_ML" => "Koyra Chiini (Mali)", // "khq" => "Koyra Chiini", // "ses_ML" => "Koyraboro Senni (Mali)", // "ses" => "Koyraboro Senni", // "lag_TZ" => "Langi (Tanzania)", // "lag" => "Langi", // "lv_LV" => "Latvian (Latvia)", // "lv" => "Latvian", // "lt_LT" => "Lithuanian (Lithuania)", // "lt" => "Lithuanian", // "luo_KE" => "Luo (Kenya)", // "luo" => "Luo", // "luy_KE" => "Luyia (Kenya)", // "luy" => "Luyia", // "mk_MK" => "Macedonian (Macedonia)", // "mk" => "Macedonian", // "jmc_TZ" => "Machame (Tanzania)", // "jmc" => "Machame", // "kde_TZ" => "Makonde (Tanzania)", // "kde" => "Makonde", // "mg_MG" => "Malagasy (Madagascar)", // "mg" => "Malagasy", // "ms_BN" => "Malay (Brunei)", // "ms_MY" => "Malay (Malaysia)", // "ms" => "Malay", // "ml_IN" => "Malayalam (India)", // "ml" => "Malayalam", // "mt_MT" => "Maltese (Malta)", // "mt" => "Maltese", // "gv_GB" => "Manx (United Kingdom)", // "gv" => "Manx", // "mr_IN" => "Marathi (India)", // "mr" => "Marathi", // "mas_KE" => "Masai (Kenya)", // "mas_TZ" => "Masai (Tanzania)", // "mas" => "Masai", // "mer_KE" => "Meru (Kenya)", // "mer" => "Meru", // "mfe_MU" => "Morisyen (Mauritius)", // "mfe" => "Morisyen", // "naq_NA" => "Nama (Namibia)", // "naq" => "Nama", // "ne_IN" => "Nepali (India)", // "ne_NP" => "Nepali (Nepal)", // "ne" => "Nepali", // "nd_ZW" => "North Ndebele (Zimbabwe)", // "nd" => "North Ndebele", // "nb_NO" => "Norwegian Bokmål (Norway)", // "nb" => "Norwegian Bokmål", // "nn_NO" => "Norwegian Nynorsk (Norway)", // "nn" => "Norwegian Nynorsk", // "nyn_UG" => "Nyankole (Uganda)", // "nyn" => "Nyankole", // "or_IN" => "Oriya (India)", // "or" => "Oriya", // "om_ET" => "Oromo (Ethiopia)", // "om_KE" => "Oromo (Kenya)", // "om" => "Oromo", // "ps_AF" => "Pashto (Afghanistan)", // "ps" => "Pashto", // "fa_AF" => "Persian (Afghanistan)", // "fa_IR" => "Persian (Iran)", // "fa" => "Persian", // "pl_PL" => "Polish (Poland)", // "pl" => "Polish", // "pt_BR" => "Portuguese (Brazil)", // "pt_GW" => "Portuguese (Guinea-Bissau)", // "pt_MZ" => "Portuguese (Mozambique)", // "pt_PT" => "Portuguese (Portugal)", 'pt' => 'Portuguese', // "pa_Arab" => "Punjabi (Arabic)", // "pa_Arab_PK" => "Punjabi (Arabic, Pakistan)", // "pa_Guru" => "Punjabi (Gurmukhi)", // "pa_Guru_IN" => "Punjabi (Gurmukhi, India)", // "pa" => "Punjabi", // "ro_MD" => "Romanian (Moldova)", // "ro_RO" => "Romanian (Romania)", 'ro' => 'Romanian', // "rm_CH" => "Romansh (Switzerland)", // "rm" => "Romansh", // "rof_TZ" => "Rombo (Tanzania)", // "rof" => "Rombo", // "ru_MD" => "Russian (Moldova)", // "ru_RU" => "Russian (Russia)", // "ru_UA" => "Russian (Ukraine)", // "ru" => "Russian", // "rwk_TZ" => "Rwa (Tanzania)", // "rwk" => "Rwa", // "saq_KE" => "Samburu (Kenya)", // "saq" => "Samburu", // "sg_CF" => "Sango (Central African Republic)", // "sg" => "Sango", // "seh_MZ" => "Sena (Mozambique)", // "seh" => "Sena", // "sr_Cyrl" => "Serbian (Cyrillic)", // "sr_Cyrl_BA" => "Serbian (Cyrillic, Bosnia and Herzegovina)", // "sr_Cyrl_ME" => "Serbian (Cyrillic, Montenegro)", // "sr_Cyrl_RS" => "Serbian (Cyrillic, Serbia)", // "sr_Latn" => "Serbian (Latin)", // "sr_Latn_BA" => "Serbian (Latin, Bosnia and Herzegovina)", // "sr_Latn_ME" => "Serbian (Latin, Montenegro)", // "sr_Latn_RS" => "Serbian (Latin, Serbia)", // "sr" => "Serbian", // "sn_ZW" => "Shona (Zimbabwe)", // "sn" => "Shona", // "ii_CN" => "Sichuan Yi (China)", // "ii" => "Sichuan Yi", // "si_LK" => "Sinhala (Sri Lanka)", // "si" => "Sinhala", // "sk_SK" => "Slovak (Slovakia)", // "sk" => "Slovak", // "sl_SI" => "Slovenian (Slovenia)", // "sl" => "Slovenian", // "xog_UG" => "Soga (Uganda)", // "xog" => "Soga", // "so_DJ" => "Somali (Djibouti)", // "so_ET" => "Somali (Ethiopia)", // "so_KE" => "Somali (Kenya)", // "so_SO" => "Somali (Somalia)", // "so" => "Somali", // "es_AR" => "Spanish (Argentina)", // "es_BO" => "Spanish (Bolivia)", // "es_CL" => "Spanish (Chile)", // "es_CO" => "Spanish (Colombia)", // "es_CR" => "Spanish (Costa Rica)", // "es_DO" => "Spanish (Dominican Republic)", // "es_EC" => "Spanish (Ecuador)", // "es_SV" => "Spanish (El Salvador)", // "es_GQ" => "Spanish (Equatorial Guinea)", // "es_GT" => "Spanish (Guatemala)", // "es_HN" => "Spanish (Honduras)", // "es_419" => "Spanish (Latin America)", // "es_MX" => "Spanish (Mexico)", // "es_NI" => "Spanish (Nicaragua)", // "es_PA" => "Spanish (Panama)", // "es_PY" => "Spanish (Paraguay)", // "es_PE" => "Spanish (Peru)", // "es_PR" => "Spanish (Puerto Rico)", // "es_ES" => "Spanish (Spain)", // "es_US" => "Spanish (United States)", // "es_UY" => "Spanish (Uruguay)", // "es_VE" => "Spanish (Venezuela)", // "es" => "Spanish", // "sw_KE" => "Swahili (Kenya)", // "sw_TZ" => "Swahili (Tanzania)", // "sw" => "Swahili", // "sv_FI" => "Swedish (Finland)", // "sv_SE" => "Swedish (Sweden)", // "sv" => "Swedish", // "gsw_CH" => "Swiss German (Switzerland)", // "gsw" => "Swiss German", // "shi_Latn" => "Tachelhit (Latin)", // "shi_Latn_MA" => "Tachelhit (Latin, Morocco)", // "shi_Tfng" => "Tachelhit (Tifinagh)", // "shi_Tfng_MA" => "Tachelhit (Tifinagh, Morocco)", // "shi" => "Tachelhit", // "dav_KE" => "Taita (Kenya)", // "dav" => "Taita", // "ta_IN" => "Tamil (India)", // "ta_LK" => "Tamil (Sri Lanka)", // "ta" => "Tamil", // "te_IN" => "Telugu (India)", // "te" => "Telugu", // "teo_KE" => "Teso (Kenya)", // "teo_UG" => "Teso (Uganda)", // "teo" => "Teso", // "th_TH" => "Thai (Thailand)", // "th" => "Thai", // "bo_CN" => "Tibetan (China)", // "bo_IN" => "Tibetan (India)", // "bo" => "Tibetan", // "ti_ER" => "Tigrinya (Eritrea)", // "ti_ET" => "Tigrinya (Ethiopia)", // "ti" => "Tigrinya", // "to_TO" => "Tonga (Tonga)", // "to" => "Tonga", // "tr_TR" => "Turkish (Turkey)", // "tr" => "Turkish", // "uk_UA" => "Ukrainian (Ukraine)", // "uk" => "Ukrainian", // "ur_IN" => "Urdu (India)", // "ur_PK" => "Urdu (Pakistan)", // "ur" => "Urdu", // "uz_Arab" => "Uzbek (Arabic)", // "uz_Arab_AF" => "Uzbek (Arabic, Afghanistan)", // "uz_Cyrl" => "Uzbek (Cyrillic)", // "uz_Cyrl_UZ" => "Uzbek (Cyrillic, Uzbekistan)", // "uz_Latn" => "Uzbek (Latin)", // "uz_Latn_UZ" => "Uzbek (Latin, Uzbekistan)", // "uz" => "Uzbek", // "vi_VN" => "Vietnamese (Vietnam)", // "vi" => "Vietnamese", // "vun_TZ" => "Vunjo (Tanzania)", // "vun" => "Vunjo", // "cy_GB" => "Welsh (United Kingdom)", // "cy" => "Welsh", // "yo_NG" => "Yoruba (Nigeria)", // "yo" => "Yoruba", // "zu_ZA" => "Zulu (South Africa)", // "zu" => "Zulu" ], ]; ================================================ FILE: config/backpack/pagemanager.php ================================================ 'Backpack\PageManager\app\Http\Controllers\Admin\PageCrudController', // Change this class if you wish to extend the Page model 'page_model_class' => 'Backpack\PageManager\app\Models\Page', ]; ================================================ FILE: config/backpack/permissionmanager.php ================================================ [ 'user' => App\User::class, 'permission' => Backpack\PermissionManager\app\Models\Permission::class, 'role' => Backpack\PermissionManager\app\Models\Role::class, ], /* |-------------------------------------------------------------------------- | Disallow the user interface for creating/updating permissions or roles. |-------------------------------------------------------------------------- | Roles and permissions are used in code by their name | - ex: $user->hasPermissionTo('edit articles'); | | So after the developer has entered all permissions and roles, the administrator should either: | - not have access to the panels | or | - creating and updating should be disabled */ 'allow_permission_create' => true, 'allow_permission_update' => true, 'allow_permission_delete' => true, 'allow_role_create' => true, 'allow_role_update' => true, 'allow_role_delete' => true, /* |-------------------------------------------------------------------------- | Multiple-guards functionality |-------------------------------------------------------------------------- | */ 'multiple_guards' => false, ]; ================================================ FILE: config/backpack/testing.php ================================================ app_path('Http/Controllers'), ]; ================================================ FILE: config/backpack/theme-tabler.php ================================================ 'horizontal', /** * Pick a login page layout. * Possible values: default, illustration, cover. */ 'auth_layout' => 'default', // default, illustration, cover /** * Here you can easily load your own extra css styles. * Note: if you want to customize the style to create your own custom skin colors: * - make a copy of the file "vendor/backpack/theme-tabler/resources/assets/css/colors.css" into your project * - adjust colors variables as you wish * - replace "base_path('vendor/backpack/theme-tabler/resources/assets/css/backpack-color-palette.css')," with the path to the file created above * - boom! */ 'styles' => [ base_path('vendor/backpack/theme-tabler/resources/assets/css/skins/backpack-color-palette.css'), base_path('vendor/backpack/theme-tabler/resources/assets/css/skins/glass.css'), base_path('vendor/backpack/theme-tabler/resources/assets/css/skins/vertical-lines-background.css'), base_path('vendor/backpack/theme-tabler/resources/assets/css/skins/pinstripe-background.css'), base_path('vendor/backpack/theme-tabler/resources/assets/css/skins/paper-background.css'), base_path('vendor/backpack/theme-tabler/resources/assets/css/skins/dotted-background.css'), base_path('vendor/backpack/theme-tabler/resources/assets/css/skins/fuzzy-background.css'), ], /** * 2nd Layer of customization. * * If you need to further customize the way your panel looks, * these options will help you achieve that. */ 'options' => [ /** * The available color modes. */ 'colorModes' => [ 'system' => 'la-desktop', 'light' => 'la-sun', 'dark' => 'la-moon', ], /** * The color mode used by default. */ 'defaultColorMode' => 'system', // system, light, dark /** * When true, a switch is displayed to let admins choose their favorite theme mode. * When false, the theme will only use the "defaultColorMode" set above. * In case "defaultColorMode" is null, system is the default. */ 'showColorModeSwitcher' => true, /** * Fix the top-header component (present in "vertical_transparent") and the menu when the layout type is set as "horizontal". * This value is skipped when the layout type is horizontal-overlap, using false as default. */ 'useStickyHeader' => false, /** * When true, the content area will take the whole screen width. */ 'useFluidContainers' => true, /** * When true, the sidebar content for vertical layouts will not scroll with the rest of the content. */ 'sidebarFixed' => false, /** * When true, horizontal layouts will display the classic top bar on top to free some space when multiple nav items are used. */ 'doubleTopBarInHorizontalLayouts' => false, /** * When true, the password input will have a toggle button to show/hide the password. */ 'showPasswordVisibilityToggler' => false, ], /** * 3rd Layer of customization. * * In case the first two steps were not enough, here you have full control over * the classes that make up the look of your panel. */ 'classes' => [ /** * Use this to pass classes to the HTML element, on all pages. */ 'body' => null, /** * For background colors use: * bg-dark, bg-primary, bg-secondary, bg-danger, bg-warning, bg-success, bg-info, bg-blue, bg-light-blue, * bg-indigo, bg-purple, bg-pink, bg-red, bg-orange, bg-yellow, bg-green, bg-teal, bg-cyan, bg-white. * * For links to be visible on different background colors use: "navbar-dark", "navbar-light". */ 'topHeader' => null, /** * Applies only for Vertical Menu Layout * For standard sidebar look (transparent): * - Remove "navbar-dark/light" * - Remove "navbar-light/dark" from 'classes.topHeader' and instead use "bg-light" * You can also add a background class like bg-dark, bg-primary, bg-secondary, bg-danger, bg-warning, bg-success, * bg-info, bg-blue, bg-light-blue, bg-indigo, bg-purple, bg-pink, bg-red, bg-orange, bg-yellow, bg-green, bg-teal, bg-cyan. */ 'sidebar' => null, /** * Used in the top container menu when the layout is of horizontal type. */ 'menuHorizontalContainer' => null, /** * Used in the top menu content when the layout is of horizontal type. */ 'menuHorizontalContent' => null, /** * Make transparent with footer-transparent. * Hide it with d-none. * * Change background color with bg-dark, bg-primary, bg-secondary, bg-danger, bg-warning, bg-success, bg-info, * bg-blue, bg-light-blue, bg-indigo, bg-purple, bg-pink, bg-red, bg-orange, bg-yellow, bg-green, bg-teal, bg-cyan, bg-white. */ 'footer' => null, /** * Use this to pass classes to the table displayed in List Operation * It defaults to: "table table-striped table-hover nowrap rounded card-table table-vcenter card-table shadow-xs border-xs". */ 'table' => null, /** * Use this to pass classes to the table wrapper component displayed in List Operation. */ 'tableWrapper' => null, ], /** * 4th Layer of customization. * * Alright, if nothing so far met your need, then you still have an easy way to build * a custom layout using the already existing components of this theme. * * 1. Create a new blade file in resources/views/layouts/your-custom-layout.blade.php * 2. Replace the value of layout on this file with "your-custom-layout" * 3. Customize the blade and place components such as sidebar, header, top-bar, where you need them! */ ]; ================================================ FILE: config/backpack/ui.php ================================================ 'backpack.theme-tabler::', 'view_namespace_fallback' => 'backpack.theme-tabler::', /* |-------------------------------------------------------------------------- | Look & feel customizations |-------------------------------------------------------------------------- | | To make the UI feel yours. | | Note that values set here might be overriden by theme config files | (eg. config/backpack/theme-tabler.php) when that theme is in use. | */ // Date & Datetime Format Syntax: https://carbon.nesbot.com/docs/#api-localization 'default_date_format' => 'D MMM YYYY', 'default_datetime_format' => 'D MMM YYYY, HH:mm', // Direction, according to language // (left-to-right vs right-to-left) 'html_direction' => 'ltr', // ---- // HEAD // ---- // Project name - shown in the window title 'project_name' => 'Backpack Admin Panel', // Content of the HTML meta robots tag to prevent indexing and link following 'meta_robots_content' => 'noindex, nofollow', // ------ // HEADER // ------ // When clicking on the admin panel's top-left logo/name, // where should the user be redirected? // The string below will be passed through the url() helper. // - default: '' (project root) // - alternative: 'admin' (the admin's dashboard) 'home_link' => '', // Menu logo. You can replace this with an tag if you have a logo. 'project_logo' => '', // Show / hide breadcrumbs on admin panel pages. 'breadcrumbs' => true, // ------ // FOOTER // ------ // Developer or company name. Shown in footer. 'developer_name' => 'Cristian Tabacitu', // Developer website. Link in footer. Type false if you want to hide it. 'developer_link' => 'http://tabacitu.ro', // Show powered by Laravel Backpack in the footer? true/false 'show_powered_by' => true, // --------- // DASHBOARD // --------- // Show "Getting Started with Backpack" info block? 'show_getting_started' => env('APP_ENV') == 'local', // ------------- // GLOBAL STYLES // ------------- // CSS files that are loaded in all pages, using Laravel's asset() helper 'styles' => [ // 'styles/example.css', // 'https://some-cdn.com/example.css', ], // CSS files that are loaded in all pages, using Laravel's mix() helper 'mix_styles' => [ // file_path => manifest_directory_path // 'css/app.css' => '', ], // CSS files that are loaded in all pages, using Laravel's @vite() helper // Please note that support for Vite was added in Laravel 9.19. Earlier versions are not able to use this feature. 'vite_styles' => [ // resource file_path // 'resources/css/app.css' => '', ], // -------------- // GLOBAL SCRIPTS // -------------- // JS files that are loaded in all pages, using Laravel's asset() helper 'scripts' => [ // 'js/example.js', // 'https://unpkg.com/vue@2.4.4/dist/vue.min.js', // 'https://unpkg.com/react@16/umd/react.production.min.js', // 'https://unpkg.com/react-dom@16/umd/react-dom.production.min.js', ], // JS files that are loaded in all pages, using Laravel's mix() helper 'mix_scripts' => [ // file_path => manifest_directory_path // 'js/app.js' => '', ], // JS files that are loaded in all pages, using Laravel's @vite() helper 'vite_scripts' => [ // resource file_path // 'resources/js/app.js', ], ]; ================================================ FILE: config/backup.php ================================================ [ /* -------------------------------------- * Backpack\BackupManager Command Flags * -------------------------------------- * These flags will be attached every time a backup is triggered * by Backpack\BackupManager. By default only notifications are disabled. * * https://docs.spatie.be/laravel-backup/v4/taking-backups/overview * --only-to-disk=name-of-your-disk * --only-db * --only-files * --disable-notifications */ 'backpack_flags' => [ '--disable-notifications'=> true, ], /* * The name of this application. You can use this name to monitor * the backups. */ 'name' => env('APP_NAME', 'laravel-backup'), 'source' => [ 'files' => [ /* * The list of directories and files that will be included in the backup. */ 'include' => [ base_path(), ], /* * These directories and files will be excluded from the backup. * * Directories used by the backup process will automatically be excluded. */ 'exclude' => [ base_path('vendor'), base_path('node_modules'), ], /* * Determines if symlinks should be followed. */ 'follow_links' => false, /* * Determines if it should avoid unreadable folders. */ 'ignore_unreadable_directories' => false, /* * This path is used to make directories in resulting zip-file relative * Set to `null` to include complete absolute path * Example: base_path() */ 'relative_path' => null, ], /* * The names of the connections to the databases that should be backed up * MySQL, PostgreSQL, SQLite and Mongo databases are supported. * * The content of the database dump may be customized for each connection * by adding a 'dump' key to the connection settings in config/database.php. * E.g. * 'mysql' => [ * ... * 'dump' => [ * 'excludeTables' => [ * 'table_to_exclude_from_backup', * 'another_table_to_exclude' * ] * ], * ], * * If you are using only InnoDB tables on a MySQL server, you can * also supply the useSingleTransaction option to avoid table locking. * * E.g. * 'mysql' => [ * ... * 'dump' => [ * 'useSingleTransaction' => true, * ], * ], * * For a complete list of available customization options, see https://github.com/spatie/db-dumper */ 'databases' => [ 'mysql', ], ], /* * The database dump can be compressed to decrease diskspace usage. * * Out of the box Laravel-backup supplies * Spatie\DbDumper\Compressors\GzipCompressor::class. * * You can also create custom compressor. More info on that here: * https://github.com/spatie/db-dumper#using-compression * * If you do not want any compressor at all, set it to null. */ 'database_dump_compressor' => null, /* * The file extension used for the database dump files. * * If not specified, the file extension will be .archive for MongoDB and .sql for all other databases * The file extension should be specified without a leading . */ 'database_dump_file_extension' => '', 'destination' => [ /* * The compression algorithm to be used for creating the zip archive. * * If backing up only database, you may choose gzip compression for db dump and no compression at zip. * * Some common algorithms are listed below: * ZipArchive::CM_STORE (no compression at all; set 0 as compression level) * ZipArchive::CM_DEFAULT * ZipArchive::CM_DEFLATE * ZipArchive::CM_BZIP2 * ZipArchive::CM_XZ * * For more check https://www.php.net/manual/zip.constants.php and confirm it's supported by your system. */ 'compression_method' => ZipArchive::CM_DEFAULT, /* * The compression level corresponding to the used algorithm; an integer between 0 and 9. * * Check supported levels for the chosen algorithm, usually 1 means the fastest and weakest compression, * while 9 the slowest and strongest one. * * Setting of 0 for some algorithms may switch to the strongest compression. */ 'compression_level' => 9, /* * The filename prefix used for the backup zip file. */ 'filename_prefix' => '', /* * The disk names on which the backups will be stored. */ 'disks' => [ 'local', ], ], /* * The directory where the temporary files will be stored. */ 'temporary_directory' => storage_path('app/backup-temp'), /* * The password to be used for archive encryption. * Set to `null` to disable encryption. */ 'password' => env('BACKUP_ARCHIVE_PASSWORD'), /* * The encryption algorithm to be used for archive encryption. * You can set it to `null` or `false` to disable encryption. * * When set to 'default', we'll use ZipArchive::EM_AES_256 if it is * available on your system. */ 'encryption' => 'default', ], /* * You can get notified when specific events occur. Out of the box you can use 'mail' and 'slack'. * For Slack you need to install laravel/slack-notification-channel. * * You can also use your own notification classes, just make sure the class is named after one of * the `Spatie\Backup\Notifications\Notifications` classes. */ 'notifications' => [ 'notifications' => [ Spatie\Backup\Notifications\Notifications\BackupHasFailedNotification::class => [], Spatie\Backup\Notifications\Notifications\UnhealthyBackupWasFoundNotification::class => [], Spatie\Backup\Notifications\Notifications\CleanupHasFailedNotification::class => [], Spatie\Backup\Notifications\Notifications\BackupWasSuccessfulNotification::class => [], Spatie\Backup\Notifications\Notifications\HealthyBackupWasFoundNotification::class => [], Spatie\Backup\Notifications\Notifications\CleanupWasSuccessfulNotification::class => [], ], /* * Here you can specify the notifiable to which the notifications should be sent. The default * notifiable will use the variables specified in this config file. */ 'notifiable' => Spatie\Backup\Notifications\Notifiable::class, 'mail' => [ 'to' => 'your@example.com', 'from' => [ 'address' => env('MAIL_FROM_ADDRESS', 'hello@example.com'), 'name' => env('MAIL_FROM_NAME', 'Example'), ], ], 'slack' => [ 'webhook_url' => '', /* * If this is set to null the default channel of the webhook will be used. */ 'channel' => null, 'username' => null, 'icon' => null, ], 'discord' => [ 'webhook_url' => '', 'username' => '', 'avatar_url' => '', ], ], /* * Here you can specify which backups should be monitored. * If a backup does not meet the specified requirements the * UnHealthyBackupWasFound event will be fired. */ 'monitor_backups' => [ [ 'name' => env('APP_NAME', 'laravel-backup'), 'disks' => ['local'], 'health_checks' => [ Spatie\Backup\Tasks\Monitor\HealthChecks\MaximumAgeInDays::class => 1, Spatie\Backup\Tasks\Monitor\HealthChecks\MaximumStorageInMegabytes::class => 5000, ], ], /* [ 'name' => 'name of the second app', 'disks' => ['local', 's3'], 'health_checks' => [ \Spatie\Backup\Tasks\Monitor\HealthChecks\MaximumAgeInDays::class => 1, \Spatie\Backup\Tasks\Monitor\HealthChecks\MaximumStorageInMegabytes::class => 5000, ], ], */ ], 'cleanup' => [ /* * The strategy that will be used to cleanup old backups. The default strategy * will keep all backups for a certain amount of days. After that period only * a daily backup will be kept. After that period only weekly backups will * be kept and so on. * * No matter how you configure it the default strategy will never * delete the newest backup. */ 'strategy' => Spatie\Backup\Tasks\Cleanup\Strategies\DefaultStrategy::class, 'default_strategy' => [ /* * The number of days for which backups must be kept. */ 'keep_all_backups_for_days' => 7, /* * The number of days for which daily backups must be kept. */ 'keep_daily_backups_for_days' => 16, /* * The number of weeks for which one weekly backup must be kept. */ 'keep_weekly_backups_for_weeks' => 8, /* * The number of months for which one monthly backup must be kept. */ 'keep_monthly_backups_for_months' => 4, /* * The number of years for which one yearly backup must be kept. */ 'keep_yearly_backups_for_years' => 2, /* * After cleaning up the backups remove the oldest backup until * this amount of megabytes has been reached. */ 'delete_oldest_backups_when_using_more_megabytes_than' => 5000, ], ], ]; ================================================ FILE: config/broadcasting.php ================================================ env('BROADCAST_DRIVER', 'pusher'), /* |-------------------------------------------------------------------------- | Broadcast Connections |-------------------------------------------------------------------------- | | Here you may define all of the broadcast connections that will be used | to broadcast events to other systems or over websockets. Samples of | each available type of connection are provided inside this array. | */ 'connections' => [ 'pusher' => [ 'driver' => 'pusher', 'key' => env('PUSHER_APP_KEY'), 'secret' => env('PUSHER_APP_SECRET'), 'app_id' => env('PUSHER_APP_ID'), 'options' => [ 'cluster' => env('PUSHER_APP_CLUSTER'), 'useTLS' => true, ], 'client_options' => [ // Guzzle client options: https://docs.guzzlephp.org/en/stable/request-options.html ], ], 'redis' => [ 'driver' => 'redis', 'connection' => 'default', ], 'log' => [ 'driver' => 'log', ], ], ]; ================================================ FILE: config/cache.php ================================================ env('CACHE_DRIVER', 'file'), /* |-------------------------------------------------------------------------- | Cache Stores |-------------------------------------------------------------------------- | | Here you may define all of the cache "stores" for your application as | well as their drivers. You may even define multiple stores for the | same cache driver to group types of items stored in your caches. | */ 'stores' => [ 'apc' => [ 'driver' => 'apc', ], 'array' => [ 'driver' => 'array', ], 'database' => [ 'driver' => 'database', 'table' => 'cache', 'connection' => null, ], 'file' => [ 'driver' => 'file', 'path' => storage_path('framework/cache'), ], 'memcached' => [ 'driver' => 'memcached', 'servers' => [ [ 'host' => env('MEMCACHED_HOST', '127.0.0.1'), 'port' => env('MEMCACHED_PORT', 11211), 'weight' => 100, ], ], ], 'redis' => [ 'driver' => 'redis', 'connection' => 'default', ], ], /* |-------------------------------------------------------------------------- | Cache Key Prefix |-------------------------------------------------------------------------- | | When utilizing a RAM based store such as APC or Memcached, there might | be other applications utilizing the same cache. So, we'll specify a | value to get prefixed to all our keys so we can avoid collisions. | */ 'prefix' => 'laravel', ]; ================================================ FILE: config/compile.php ================================================ [ // ], /* |-------------------------------------------------------------------------- | Compiled File Providers |-------------------------------------------------------------------------- | | Here you may list service providers which define a "compiles" function | that returns additional files that should be compiled, providing an | easy way to get common files from any packages you are utilizing. | */ 'providers' => [ // ], ]; ================================================ FILE: config/database.php ================================================ PDO::FETCH_CLASS, /* |-------------------------------------------------------------------------- | Default Database Connection Name |-------------------------------------------------------------------------- | | Here you may specify which of the database connections below you wish | to use as your default connection for all database work. Of course | you may use many connections at once using the Database library. | */ 'default' => env('DB_CONNECTION', 'mysql'), /* |-------------------------------------------------------------------------- | Database Connections |-------------------------------------------------------------------------- | | Here are each of the database connections setup for your application. | Of course, examples of configuring each database platform that is | supported by Laravel is shown below to make development simple. | | | All database work in Laravel is done through the PHP PDO facilities | so make sure you have the driver for your particular database of | choice installed on your machine before you begin development. | */ 'connections' => [ 'sqlite' => [ 'driver' => 'sqlite', 'url' => env('DATABASE_URL'), 'database' => env('DB_DATABASE', database_path('database.sqlite')), 'prefix' => '', 'foreign_key_constraints' => env('DB_FOREIGN_KEYS', true), ], 'mysql' => [ 'driver' => 'mysql', 'host' => env('DB_HOST', 'localhost'), 'port' => env('DB_PORT', '3306'), 'database' => env('DB_DATABASE', 'backpack_demo'), 'username' => env('DB_USERNAME', 'root'), 'password' => env('DB_PASSWORD', ''), 'charset' => 'utf8', 'collation' => 'utf8_unicode_ci', 'prefix' => '', 'strict' => false, 'engine' => null, 'options' => extension_loaded('pdo_mysql') ? array_filter([ Pdo\Mysql::ATTR_SSL_CA => env('MYSQL_ATTR_SSL_CA'), ]) : [], 'dump' => [ 'dump_binary_path' => env('MYSQL_DUMP_PATH', '/opt/homebrew/bin/'), 'use_single_transaction', 'timeout' => 60 * 5, // 5 minute timeout // 'exclude_tables' => ['table1', 'table2'], // 'add_extra_option' => '--optionname=optionvalue', ], ], 'pgsql' => [ 'driver' => 'pgsql', 'url' => env('DATABASE_URL'), 'host' => env('DB_HOST', '127.0.0.1'), 'port' => env('DB_PORT', '5432'), 'database' => env('DB_DATABASE', 'forge'), 'username' => env('DB_USERNAME', 'forge'), 'password' => env('DB_PASSWORD', ''), 'charset' => 'utf8', 'prefix' => '', 'prefix_indexes' => true, 'search_path' => 'public', 'sslmode' => 'prefer', ], ], /* |-------------------------------------------------------------------------- | Migration Repository Table |-------------------------------------------------------------------------- | | This table keeps track of all the migrations that have already run for | your application. Using this information, we can determine which of | the migrations on disk haven't actually been run in the database. | */ 'migrations' => 'migrations', /* |-------------------------------------------------------------------------- | Redis Databases |-------------------------------------------------------------------------- | | Redis is an open source, fast, and advanced key-value store that also | provides a richer set of commands than a typical key-value systems | such as APC or Memcached. Laravel makes it easy to dig right in. | */ 'redis' => [ 'cluster' => false, 'default' => [ 'host' => env('REDIS_HOST', 'localhost'), 'password' => env('REDIS_PASSWORD', null), 'port' => env('REDIS_PORT', 6379), 'database' => 0, ], ], ]; ================================================ FILE: config/debugbar.php ================================================ env('DEBUGBAR_ENABLED', null), 'except' => [ 'telescope*', ], /* |-------------------------------------------------------------------------- | Storage settings |-------------------------------------------------------------------------- | | DebugBar stores data for session/ajax requests. | You can disable this, so the debugbar stores data in headers/session, | but this can cause problems with large data collectors. | By default, file storage (in the storage folder) is used. Redis and PDO | can also be used. For PDO, run the package migrations first. | */ 'storage' => [ 'enabled' => true, 'driver' => 'file', // redis, file, pdo, custom 'path' => storage_path('debugbar'), // For file driver 'connection' => null, // Leave null for default connection (Redis/PDO) 'provider' => '', // Instance of StorageInterface for custom driver 'open' => true, ], /* |-------------------------------------------------------------------------- | Vendors |-------------------------------------------------------------------------- | | Vendor files are included by default, but can be set to false. | This can also be set to 'js' or 'css', to only include javascript or css vendor files. | Vendor files are for css: font-awesome (including fonts) and highlight.js (css files) | and for js: jquery and and highlight.js | So if you want syntax highlighting, set it to true. | jQuery is set to not conflict with existing jQuery scripts. | */ 'include_vendors' => true, /* |-------------------------------------------------------------------------- | Capture Ajax Requests |-------------------------------------------------------------------------- | | The Debugbar can capture Ajax requests and display them. If you don't want this (ie. because of errors), | you can use this option to disable sending the data through the headers. | | Optionally, you can also send ServerTiming headers on ajax requests for the Chrome DevTools. */ 'capture_ajax' => true, 'add_ajax_timing' => false, /* |-------------------------------------------------------------------------- | Custom Error Handler for Deprecated warnings |-------------------------------------------------------------------------- | | When enabled, the Debugbar shows deprecated warnings for Symfony components | in the Messages tab. | */ 'error_handler' => false, /* |-------------------------------------------------------------------------- | Clockwork integration |-------------------------------------------------------------------------- | | The Debugbar can emulate the Clockwork headers, so you can use the Chrome | Extension, without the server-side code. It uses Debugbar collectors instead. | */ 'clockwork' => false, /* |-------------------------------------------------------------------------- | DataCollectors |-------------------------------------------------------------------------- | | Enable/disable DataCollectors | */ 'collectors' => [ 'phpinfo' => true, // Php version 'messages' => true, // Messages 'time' => true, // Time Datalogger 'memory' => true, // Memory usage 'exceptions' => true, // Exception displayer 'log' => true, // Logs from Monolog (merged in messages if enabled) 'db' => true, // Show database (PDO) queries and bindings 'views' => true, // Views with their data 'route' => true, // Current route information 'auth' => false, // Display Laravel authentication status 'gate' => false, // Display Laravel Gate checks 'session' => true, // Display session data 'symfony_request' => true, // Only one can be enabled.. 'mail' => true, // Catch mail messages 'laravel' => false, // Laravel version and environment 'events' => false, // All events fired 'default_request' => false, // Regular or special Symfony request logger 'logs' => false, // Add the latest log messages 'files' => false, // Show the included files 'config' => false, // Display config settings 'cache' => false, // Display cache events 'models' => true, // Display models ], /* |-------------------------------------------------------------------------- | Extra options |-------------------------------------------------------------------------- | | Configure some DataCollectors | */ 'options' => [ 'auth' => [ 'show_name' => true, // Also show the users name/email in the debugbar ], 'db' => [ 'with_params' => true, // Render SQL with the parameters substituted 'backtrace' => true, // Use a backtrace to find the origin of the query in your files. 'timeline' => false, // Add the queries to the timeline 'explain' => [ // Show EXPLAIN output on queries 'enabled' => false, 'types' => ['SELECT'], // // workaround ['SELECT'] only. https://github.com/barryvdh/laravel-debugbar/issues/888 ['SELECT', 'INSERT', 'UPDATE', 'DELETE']; for MySQL 5.6.3+ ], 'hints' => true, // Show hints for common mistakes ], 'mail' => [ 'full_log' => false, ], 'views' => [ 'data' => false, //Note: Can slow down the application, because the data can be quite large.. ], 'route' => [ 'label' => true, // show complete route on bar ], 'logs' => [ 'file' => null, ], 'cache' => [ 'values' => true, // collect cache values ], ], /* |-------------------------------------------------------------------------- | Inject Debugbar in Response |-------------------------------------------------------------------------- | | Usually, the debugbar is added just before , by listening to the | Response after the App is done. If you disable this, you have to add them | in your template yourself. See http://phpdebugbar.com/docs/rendering.html | */ 'inject' => true, /* |-------------------------------------------------------------------------- | DebugBar route prefix |-------------------------------------------------------------------------- | | Sometimes you want to set route prefix to be used by DebugBar to load | its resources from. Usually the need comes from misconfigured web server or | from trying to overcome bugs like this: http://trac.nginx.org/nginx/ticket/97 | */ 'route_prefix' => '_debugbar', /* |-------------------------------------------------------------------------- | DebugBar route domain |-------------------------------------------------------------------------- | | By default DebugBar route served from the same domain that request served. | To override default domain, specify it as a non-empty value. */ 'route_domain' => null, ]; ================================================ FILE: config/elfinder.php ================================================ ['uploads'], /* |-------------------------------------------------------------------------- | Filesystem disks (Flysytem) |-------------------------------------------------------------------------- | | Define an array of Filesystem disks, which use Flysystem. | You can set extra options, example: | | 'my-disk' => [ | 'URL' => url('to/disk'), | 'alias' => 'Local storage', | ] */ 'disks' => [ // 'uploads', ], /* |-------------------------------------------------------------------------- | Routes group config |-------------------------------------------------------------------------- | | The default group settings for the elFinder routes. | */ 'route' => [ 'prefix' => config('backpack.base.route_prefix', 'admin').'/elfinder', 'middleware' => ['web', config('backpack.base.middleware_key', 'admin')], //Set to null to disable middleware filter ], /* |-------------------------------------------------------------------------- | Access filter |-------------------------------------------------------------------------- | | Filter callback to check the files | */ 'access' => 'App\Library\Elfinder::checkAccess', /* |-------------------------------------------------------------------------- | Roots |-------------------------------------------------------------------------- | | By default, the roots file is LocalFileSystem, with the above public dir. | If you want custom options, you can set your own roots below. | */ 'roots' => null, /* |-------------------------------------------------------------------------- | Options |-------------------------------------------------------------------------- | | These options are merged, together with 'roots' and passed to the Connector. | See https://github.com/Studio-42/elFinder/wiki/Connector-configuration-options-2.1 | */ 'options' => [], ]; ================================================ FILE: config/filesystems.php ================================================ env('FILESYSTEM_DISK', 'local'), /* |-------------------------------------------------------------------------- | Default Cloud Filesystem Disk |-------------------------------------------------------------------------- | | Many applications store files both locally and in the cloud. For this | reason, you may specify a default "cloud" driver here. This driver | will be bound as the Cloud disk implementation in the container. | */ 'cloud' => 's3', /* |-------------------------------------------------------------------------- | Filesystem Disks |-------------------------------------------------------------------------- | | Here you may configure as many filesystem "disks" as you wish, and you | may even configure multiple disks of the same driver. Defaults have | been setup for each driver as an example of the required options. | */ 'disks' => [ 'local' => [ 'driver' => 'local', 'root' => storage_path('app'), ], 'public' => [ 'driver' => 'local', 'root' => storage_path('app/public'), 'url' => env('APP_URL').'/storage', 'visibility' => 'public', 'throw' => false, ], 'uploads' => [ // used for Backpack/CRUD (in elFinder) 'driver' => 'local', 'root' => public_path('uploads'), ], 'backups' => [ // used for Backpack/BackupManager 'driver' => 'local', 'root' => storage_path('backups'), // that's where your backups are stored by default: storage/backups ], 'storage' => [ // used for Backpack/LogManager 'driver' => 'local', 'root' => storage_path(), ], 's3' => [ 'driver' => 's3', 'key' => env('AWS_ACCESS_KEY_ID'), 'secret' => env('AWS_SECRET_ACCESS_KEY'), 'region' => env('AWS_DEFAULT_REGION'), 'bucket' => env('AWS_BUCKET'), 'url' => env('AWS_URL'), 'endpoint' => env('AWS_ENDPOINT'), 'use_path_style_endpoint' => env('AWS_USE_PATH_STYLE_ENDPOINT', false), 'visibility' => 'public', ], ], 'links' => [ public_path('storage') => storage_path('app/public'), ], ]; ================================================ FILE: config/gravatar.php ================================================ [ // By default, images are presented at 80px by 80px if no size parameter is supplied. // You may request a specific image size, which will be dynamically delivered from Gravatar // by passing a single pixel dimension (since the images are square): 'size' => 45, // the fallback image, can be a string or a url // for more info, visit: http://en.gravatar.com/site/implement/images/#default-image 'fallback' => 'mm', // would you like to return a https://... image 'secure' => true, // Gravatar allows users to self-rate their images so that they can indicate if an image // is appropriate for a certain audience. By default, only 'G' rated images are displayed // unless you indicate that you would like to see higher ratings. // Available options: // g: suitable for display on all websites with any audience type. // pg: may contain rude gestures, provocatively dressed individuals, the lesser swear words, or mild violence. // r: may contain such things as harsh profanity, intense violence, nudity, or hard drug use. // x: may contain hardcore sexual imagery or extremely disturbing violence. 'maximumRating' => 'g', // If for some reason you wanted to force the default image to always load, you can do that setting this to true 'forceDefault' => false, // If you require a file-type extension (some places do) then you may also add an (optional) .jpg extension to that URL 'forceExtension' => 'jpg', ], ]; ================================================ FILE: config/image.php ================================================ 'gd', ]; ================================================ FILE: config/logging.php ================================================ env('LOG_CHANNEL', 'stack'), /* |-------------------------------------------------------------------------- | Log Channels |-------------------------------------------------------------------------- | | Here you may configure the log channels for your application. Out of | the box, Laravel uses the Monolog PHP logging library. This gives | you a variety of powerful log handlers / formatters to utilize. | | Available Drivers: "single", "daily", "slack", "syslog", | "errorlog", "custom", "stack" | */ 'channels' => [ 'stack' => [ 'driver' => 'stack', 'channels' => ['single'], ], 'single' => [ 'driver' => 'single', 'path' => storage_path('logs/laravel.log'), 'level' => 'debug', ], 'daily' => [ 'driver' => 'daily', 'path' => storage_path('logs/laravel.log'), 'level' => 'debug', 'days' => 7, ], 'slack' => [ 'driver' => 'slack', 'url' => env('LOG_SLACK_WEBHOOK_URL'), 'username' => 'Laravel Log', 'emoji' => ':boom:', 'level' => 'critical', ], 'syslog' => [ 'driver' => 'syslog', 'level' => 'debug', ], 'errorlog' => [ 'driver' => 'errorlog', 'level' => 'debug', ], ], ]; ================================================ FILE: config/mail.php ================================================ env('MAIL_MAILER', 'smtp'), /* |-------------------------------------------------------------------------- | Mailer Configurations |-------------------------------------------------------------------------- | | Here you may configure all of the mailers used by your application plus | their respective settings. Several examples have been configured for | you and you are free to add your own as your application requires. | | Laravel supports a variety of mail "transport" drivers to be used while | sending an e-mail. You will specify which one you are using for your | mailers below. You are free to add additional mailers as required. | | Supported: "smtp", "sendmail", "mailgun", "ses", | "postmark", "log", "array" | */ 'mailers' => [ 'smtp' => [ 'transport' => 'smtp', 'host' => env('MAIL_HOST', 'smtp.mailgun.org'), 'port' => env('MAIL_PORT', 587), 'encryption' => env('MAIL_ENCRYPTION', 'tls'), 'username' => env('MAIL_USERNAME'), 'password' => env('MAIL_PASSWORD'), 'auth_mode' => null, ], 'ses' => [ 'transport' => 'ses', ], 'sendmail' => [ 'transport' => 'sendmail', 'path' => '/usr/sbin/sendmail -bs', ], 'log' => [ 'transport' => 'log', 'channel' => env('MAIL_LOG_CHANNEL'), ], 'array' => [ 'transport' => 'array', ], ], /* |-------------------------------------------------------------------------- | Global "From" Address |-------------------------------------------------------------------------- | | You may wish for all e-mails sent by your application to be sent from | the same address. Here, you may specify a name and address that is | used globally for all e-mails that are sent by your application. | */ 'from' => [ 'address' => env('MAIL_FROM_ADDRESS', 'demo@backpackforlaravel.com'), 'name' => env('MAIL_FROM_NAME', 'Backpack Demo'), ], /* |-------------------------------------------------------------------------- | Markdown Mail Settings |-------------------------------------------------------------------------- | | If you are using Markdown based email rendering, you may configure your | theme and component paths here, allowing you to customize the design | of the emails. Or, you may simply stick with the Laravel defaults! | */ 'markdown' => [ 'theme' => 'default', 'paths' => [ resource_path('views/vendor/mail'), ], ], ]; ================================================ FILE: config/permission.php ================================================ [ /* * When using the "HasPermissions" trait from this package, we need to know which * Eloquent model should be used to retrieve your permissions. Of course, it * is often just the "Permission" model but you may use whatever you like. * * The model you want to use as a Permission model needs to implement the * `Spatie\Permission\Contracts\Permission` contract. */ 'permission' => Spatie\Permission\Models\Permission::class, /* * When using the "HasRoles" trait from this package, we need to know which * Eloquent model should be used to retrieve your roles. Of course, it * is often just the "Role" model but you may use whatever you like. * * The model you want to use as a Role model needs to implement the * `Spatie\Permission\Contracts\Role` contract. */ 'role' => Spatie\Permission\Models\Role::class, ], 'table_names' => [ /* * When using the "HasRoles" trait from this package, we need to know which * table should be used to retrieve your roles. We have chosen a basic * default value but you may easily change it to any table you like. */ 'roles' => 'roles', /* * When using the "HasPermissions" trait from this package, we need to know which * table should be used to retrieve your permissions. We have chosen a basic * default value but you may easily change it to any table you like. */ 'permissions' => 'permissions', /* * When using the "HasPermissions" trait from this package, we need to know which * table should be used to retrieve your models permissions. We have chosen a * basic default value but you may easily change it to any table you like. */ 'model_has_permissions' => 'model_has_permissions', /* * When using the "HasRoles" trait from this package, we need to know which * table should be used to retrieve your models roles. We have chosen a * basic default value but you may easily change it to any table you like. */ 'model_has_roles' => 'model_has_roles', /* * When using the "HasRoles" trait from this package, we need to know which * table should be used to retrieve your roles permissions. We have chosen a * basic default value but you may easily change it to any table you like. */ 'role_has_permissions' => 'role_has_permissions', ], 'column_names' => [ /* * Change this if you want to name the related model primary key other than * `model_id`. * * For example, this would be nice if your primary keys are all UUIDs. In * that case, name this `model_uuid`. */ 'model_morph_key' => 'model_id', ], /* * When set to true, the required permission/role names are added to the exception * message. This could be considered an information leak in some contexts, so * the default setting is false here for optimum safety. */ 'display_permission_in_exception' => false, 'cache' => [ /* * By default all permissions will be cached for 24 hours unless a permission or * role is updated. Then the cache will be flushed immediately. */ 'expiration_time' => 60 * 24, /* * The key to use when tagging and prefixing entries in the cache. */ 'key' => 'spatie.permission.cache', /* * When checking for a permission against a model by passing a Permission * instance to the check, this key determines what attribute on the * Permissions model is used to cache against. * * Ideally, this should match your preferred way of checking permissions, eg: * `$user->can('view-posts')` would be 'name'. */ 'model_key' => 'name', /* * You may optionally indicate a specific cache driver to use for permission and * role caching using any of the `store` drivers listed in the cache.php config * file. Using 'default' here means to use the `default` set in cache.php. */ 'store' => 'default', ], ]; ================================================ FILE: config/prologue/alerts.php ================================================ [ 'info', 'warning', 'error', 'success', ], /* |-------------------------------------------------------------------------- | Session Key |-------------------------------------------------------------------------- | | The session key which is used to store flashed messages into the current | session. This can be changed if it conflicts with another key. | */ 'session_key' => 'alert_messages', ]; ================================================ FILE: config/queue.php ================================================ env('QUEUE_DRIVER', 'sync'), /* |-------------------------------------------------------------------------- | Queue Connections |-------------------------------------------------------------------------- | | Here you may configure the connection information for each server that | is used by your application. A default configuration has been added | for each back-end shipped with Laravel. You are free to add more. | */ 'connections' => [ 'sync' => [ 'driver' => 'sync', ], 'database' => [ 'driver' => 'database', 'table' => 'jobs', 'queue' => 'default', 'expire' => 60, ], 'beanstalkd' => [ 'driver' => 'beanstalkd', 'host' => 'localhost', 'queue' => 'default', 'ttr' => 60, ], 'sqs' => [ 'driver' => 'sqs', 'key' => 'your-public-key', 'secret' => 'your-secret-key', 'prefix' => 'https://sqs.us-east-1.amazonaws.com/your-account-id', 'queue' => 'your-queue-name', 'region' => 'us-east-1', ], 'redis' => [ 'driver' => 'redis', 'connection' => 'default', 'queue' => 'default', 'expire' => 60, ], ], /* |-------------------------------------------------------------------------- | Failed Queue Jobs |-------------------------------------------------------------------------- | | These options configure the behavior of failed queue job logging so you | can control which database and table are used to store the jobs that | have failed. You may change them to any database / table you wish. | */ 'failed' => [ 'database' => env('DB_CONNECTION', 'mysql'), 'table' => 'failed_jobs', ], ]; ================================================ FILE: config/services.php ================================================ [ 'domain' => env('MAILGUN_DOMAIN'), 'secret' => env('MAILGUN_SECRET'), ], 'ses' => [ 'key' => env('SES_KEY'), 'secret' => env('SES_SECRET'), 'region' => 'us-east-1', ], 'sparkpost' => [ 'secret' => env('SPARKPOST_SECRET'), ], 'stripe' => [ 'model' => App\User::class, 'key' => env('STRIPE_KEY'), 'secret' => env('STRIPE_SECRET'), ], 'google_places' => [ 'key' => env('GOOGLE_PLACES_KEY'), ], ]; ================================================ FILE: config/session.php ================================================ env('SESSION_DRIVER', 'file'), /* |-------------------------------------------------------------------------- | Session Lifetime |-------------------------------------------------------------------------- | | Here you may specify the number of minutes that you wish the session | to be allowed to remain idle before it expires. If you want them | to immediately expire on the browser closing, set that option. | */ 'lifetime' => 120, 'expire_on_close' => false, /* |-------------------------------------------------------------------------- | Session Encryption |-------------------------------------------------------------------------- | | This option allows you to easily specify that all of your session data | should be encrypted before it is stored. All encryption will be run | automatically by Laravel and you can use the Session like normal. | */ 'encrypt' => false, /* |-------------------------------------------------------------------------- | Session File Location |-------------------------------------------------------------------------- | | When using the native session driver, we need a location where session | files may be stored. A default has been set for you but a different | location may be specified. This is only needed for file sessions. | */ 'files' => storage_path('framework/sessions'), /* |-------------------------------------------------------------------------- | Session Database Connection |-------------------------------------------------------------------------- | | When using the "database" or "redis" session drivers, you may specify a | connection that should be used to manage these sessions. This should | correspond to a connection in your database configuration options. | */ 'connection' => null, /* |-------------------------------------------------------------------------- | Session Database Table |-------------------------------------------------------------------------- | | When using the "database" session driver, you may specify the table we | should use to manage the sessions. Of course, a sensible default is | provided for you; however, you are free to change this as needed. | */ 'table' => 'sessions', /* |-------------------------------------------------------------------------- | Session Sweeping Lottery |-------------------------------------------------------------------------- | | Some session drivers must manually sweep their storage location to get | rid of old sessions from storage. Here are the chances that it will | happen on a given request. By default, the odds are 2 out of 100. | */ 'lottery' => [2, 100], /* |-------------------------------------------------------------------------- | Session Cookie Name |-------------------------------------------------------------------------- | | Here you may change the name of the cookie used to identify a session | instance by ID. The name specified here will get used every time a | new session cookie is created by the framework for every driver. | */ 'cookie' => 'laravel_session', /* |-------------------------------------------------------------------------- | Session Cookie Path |-------------------------------------------------------------------------- | | The session cookie path determines the path for which the cookie will | be regarded as available. Typically, this will be the root path of | your application but you are free to change this when necessary. | */ 'path' => '/', /* |-------------------------------------------------------------------------- | Session Cookie Domain |-------------------------------------------------------------------------- | | Here you may change the domain of the cookie used to identify a session | in your application. This will determine which domains the cookie is | available to in your application. A sensible default has been set. | */ 'domain' => null, /* |-------------------------------------------------------------------------- | HTTPS Only Cookies |-------------------------------------------------------------------------- | | By setting this option to true, session cookies will only be sent back | to the server if the browser has a HTTPS connection. This will keep | the cookie from being sent to you if it can not be done securely. | */ 'secure' => env('SESSION_SECURE_COOKIE', null), 'same_site' => 'lax', /* |-------------------------------------------------------------------------- | HTTP Access Only |-------------------------------------------------------------------------- | | Setting this value to true will prevent JavaScript from accessing the | value of the cookie and the cookie will only be accessible through | the HTTP protocol. You are free to modify this option if needed. | */ 'http_only' => true, ]; ================================================ FILE: config/sluggable.php ================================================ name; * * Or it can be an array of fields, like ("name", "company"), which builds a slug from: * * $model->name . ' ' . $model->company; * * If you've defined custom getters in your model, you can use those too, * since Eloquent will call them when you request a custom attribute. * * Defaults to null, which uses the toString() method on your model. */ 'source' => null, /* * The maximum length of a generated slug. Defaults to "null", which means * no length restrictions are enforced. Set it to a positive integer if you * want to make sure your slugs aren't too long. */ 'maxLength' => null, /* * If left to "null", then use the cocur/slugify package to generate the slug * (with the separator defined below). * * Set this to a closure that accepts two parameters (string and separator) * to define a custom slugger. e.g.: * * 'method' => function( $string, $sep ) { * return preg_replace('/[^a-z]+/i', $sep, $string); * }, * * Otherwise, this will be treated as a callable to be used. e.g.: * * 'method' => array('Str','slug'), */ 'method' => null, /* * Separator to use when generating slugs. Defaults to a hyphen. */ 'separator' => '-', /* * Enforce uniqueness of slugs? Defaults to true. * If a generated slug already exists, an incremental numeric * value will be appended to the end until a unique slug is found. e.g.: * * my-slug * my-slug-1 * my-slug-2 */ 'unique' => true, /* * If you are enforcing unique slugs, the default is to add an * incremental value to the end of the base slug. Alternatively, you * can change this value to a closure that accepts three parameters: * the base slug, the separator, and a Collection of the other * "similar" slugs. The closure should return the new unique * suffix to append to the slug. */ 'uniqueSuffix' => null, /* * Should we include the trashed items when generating a unique slug? * This only applies if the softDelete property is set for the Eloquent model. * If set to "false", then a new slug could duplicate one that exists on a trashed model. * If set to "true", then uniqueness is enforced across trashed and existing models. */ 'includeTrashed' => false, /* * An array of slug names that can never be used for this model, * e.g. to prevent collisions with existing routes or controller methods, etc.. * Defaults to null (i.e. no reserved names). * Can be a static array, e.g.: * * 'reserved' => array('add', 'delete'), * * or a closure that returns an array of reserved names. * If using a closure, it will accept one parameter: the model itself, and should * return an array of reserved names, or null. e.g. * * 'reserved' => function( Model $model) { * return $model->some_method_that_returns_an_array(); * } * * In the case of a slug that gets generated with one of these reserved names, * we will do: * * $slug .= $separator + "1" * * and continue from there. */ 'reserved' => null, /* * Whether to update the slug value when a model is being * re-saved (i.e. already exists). Defaults to false, which * means slugs are not updated. * * Be careful! If you are using slugs to generate URLs, then * updating your slug automatically might change your URLs which * is probably not a good idea from an SEO point of view. * Only set this to true if you understand the possible consequences. */ 'onUpdate' => false, ]; ================================================ FILE: config/view.php ================================================ [ realpath(base_path('resources/views')), ], /* |-------------------------------------------------------------------------- | Compiled View Path |-------------------------------------------------------------------------- | | This option determines where all the compiled Blade templates will be | stored for your application. Typically, this is within the storage | directory. However, as usual, you are free to change this value. | */ 'compiled' => realpath(storage_path('framework/views')), ]; ================================================ FILE: database/.gitignore ================================================ *.sqlite ================================================ FILE: database/factories/ArticleFactory.php ================================================ rand(1, 8), 'title' => ucfirst($this->faker->unique()->sentence()), 'content' => $this->faker->text(800), 'status' => $this->faker->randomElement(['PUBLISHED', 'DRAFT']), 'date' => $this->faker->date(), 'featured' => $this->faker->boolean(), 'created_at' => Carbon::now()->subDays(rand(0, 30)), ]; } } ================================================ FILE: database/factories/BillFactory.php ================================================ faker->unique()->words(rand(1, 3), true)); return [ 'title' => $title, ]; } } ================================================ FILE: database/factories/CategoryFactory.php ================================================ ucfirst($this->faker->unique()->word), 'created_at' => Carbon::now()->subDays(rand(0, 30)), ]; } } ================================================ FILE: database/factories/CaveFactory.php ================================================ $this->faker->name, ]; } } ================================================ FILE: database/factories/HeroFactory.php ================================================ $this->faker->name, ]; } } ================================================ FILE: database/factories/MeetingFactory.php ================================================ faker->randomElement([ 'Meeting with '.$this->faker->name, 'Lunch with '.$this->faker->name, 'Dinner with '.$this->faker->name, 'Drink with '.$this->faker->name, ]); $start = Carbon::now()->addDays(30)->subMinutes(rand(0, Carbon::now()->diffInMinutes(Carbon::now()->subDays(90))))->floorHour(); $end = rand(0, 2) ? $start->copy()->addMinutes($this->faker->randomElement([60, 60, 60, 120, 240])) : null; [$backgroundColor, $textColor] = $this->faker->randomElement([ ['#5e9ecd', '#ffffff'], ['#009688', '#ffffff'], ]); return [ 'title' => $title, 'start' => $start, 'end' => $end, 'email' => $this->faker->email, 'number' => $this->faker->phoneNumber, 'background_color' => $backgroundColor, 'text_color' => $textColor, ]; } } ================================================ FILE: database/factories/MenuItemFactory.php ================================================ faker->unique()->words(rand(1, 3), true)); $type = $this->faker->randomElement([MenuItem::$pageLink, MenuItem::$externalLink, MenuItem::$internalLink]); $link = null; $page_id = null; switch ($type) { case MenuItem::$externalLink: $link = $this->faker->url; break; case MenuItem::$internalLink: $link = $this->faker->slug; break; case MenuItem::$pageLink: $page_id = Page::all()->random()->id; break; } return [ 'name' => $name, 'type' => $type, 'link' => $link, 'page_id' => $page_id, ]; } } ================================================ FILE: database/factories/MonsterFactory.php ================================================ ucfirst($this->faker->unique()->sentence()), 'summernote' => '

'.$this->faker->text(800).'

', 'tinymce' => $this->faker->text(800), 'textarea' => $this->faker->text(250), 'text' => $this->faker->text(120), 'date' => $this->faker->date(), 'start_date' => $this->faker->date(), 'end_date' => $this->faker->date(), 'datetime' => $this->faker->dateTime()->format('Y-m-d H:i:s'), 'datetime_picker' => $this->faker->dateTime()->format('Y-m-d H:i:s'), 'email' => $this->faker->email(), 'checkbox' => 0, 'number' => rand(), 'float' => rand(), 'belongs_to_non_nullable' => 0, 'select' => null, 'icon_id' => null, 'status' => \App\Enums\MonsterStatus::WORKING->value, 'select2_json_from_api' => null, 'select2_json_from_api_simple' => null, ]; } } ================================================ FILE: database/factories/PageFactory.php ================================================ faker->unique()->words(rand(2, 5), true)); return [ 'template' => $this->faker->randomElement(['services', 'about_us']), 'name' => $title, 'title' => $title, 'slug' => Str::slug($title), 'content' => $this->faker->paragraphs(rand(3, 18), true), ]; } } ================================================ FILE: database/factories/PetShop/BadgeFactory.php ================================================ $this->faker->name, ]; } } ================================================ FILE: database/factories/PetShop/InvoiceFactory.php ================================================ faker->date(); return [ 'owner_id' => Owner::factory(), 'series' => Arr::random(['SRV', 'PRD']), 'number' => $this->faker->randomNumber(4), 'issuance_date' => $date, 'due_date' => Carbon::parse($date)->addDays(15), ]; } } ================================================ FILE: database/factories/PetShop/InvoiceItemFactory.php ================================================ Invoice::factory(), 'order' => $this->faker->randomNumber(), 'description' => $this->faker->text, 'quantity' => $this->faker->randomFloat(0, 0, 9999999999.), 'unit_price' => $this->faker->randomFloat(0, 0, 9999999999.), ]; } } ================================================ FILE: database/factories/PetShop/OwnerFactory.php ================================================ $this->faker->name, ]; } public function configure() { return $this->afterCreating(function (Owner $owner) { $owner->avatar()->create([ 'url' => 'https://placekitten.com/'.rand(200, 400).'/'.rand(200, 400), ]); }); } } ================================================ FILE: database/factories/PetShop/PassportFactory.php ================================================ Pet::factory(), 'number' => $this->faker->word, 'issuance_date' => $this->faker->date(), 'expiry_date' => $this->faker->date(), 'first_name' => $this->faker->firstName, 'middle_name' => $this->faker->word, 'last_name' => $this->faker->lastName, 'birth_date' => $this->faker->date(), 'species' => $this->faker->word, 'breed' => $this->faker->word, 'colour' => $this->faker->colorName(), 'notes' => $this->faker->text, 'country' => $this->faker->country, ]; } } ================================================ FILE: database/factories/PetShop/PetFactory.php ================================================ Arr::random($this->petNames), ]; } public function configure() { return $this->afterCreating(function (Pet $pet) { $pet->avatar()->create([ 'url' => 'https://placekitten.com/'.rand(200, 400).'/'.rand(200, 400), ]); }); } } ================================================ FILE: database/factories/PetShop/SkillFactory.php ================================================ Arr::random($skills), ]; } } ================================================ FILE: database/factories/PetShop/StoryFactory.php ================================================ $this->faker->name, ]; } } ================================================ FILE: database/factories/PostalBoxerFactory.php ================================================ faker->unique()->words(rand(1, 3), true)); return [ 'postal_name' => $title, ]; } } ================================================ FILE: database/factories/ProductFactory.php ================================================ ucfirst($this->faker->unique()->sentence()), 'description' => $this->faker->text(50), 'details' => $this->faker->text(800), 'price' => random_int(10, 1000), 'category_id' => function () { if (rand(1, 100) % 50 == 0) { return Category::factory()->create()->id; } else { return Category::inRandomOrder()->first()->id ?? Category::factory()->create()->id; } }, ]; } } ================================================ FILE: database/factories/RecommendFactory.php ================================================ faker->unique()->words(rand(1, 3), true)); return [ 'title' => $title, ]; } } ================================================ FILE: database/factories/TagFactory.php ================================================ ucfirst($this->faker->unique()->word), 'created_at' => Carbon::now()->subDays(rand(0, 30)), ]; } } ================================================ FILE: database/factories/UserFactory.php ================================================ $this->faker->name, 'email' => $this->faker->unique()->safeEmail, 'password' => bcrypt(Str::random(10)), 'remember_token' => null, 'email_verified_at' => null, ]; } } ================================================ FILE: database/migrations/.gitkeep ================================================ ================================================ FILE: database/migrations/2013_04_09_062329_create_backpack_revisions_table.php ================================================ increments('id'); $table->string('revisionable_type'); $table->integer('revisionable_id'); $table->integer('user_id')->nullable(); $table->string('key'); $table->text('old_value')->nullable(); $table->text('new_value')->nullable(); $table->timestamps(); $table->index(['revisionable_id', 'revisionable_type']); } ); } } /** * Reverse the migrations. * * @return void */ public function down() { if (Schema::hasTable('revisions')) { Schema::drop('revisions'); } } } ================================================ FILE: database/migrations/2014_10_12_000000_create_users_table.php ================================================ increments('id'); $table->string('name'); $table->string('email')->unique(); $table->string('password'); $table->rememberToken(); $table->timestamps(); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::drop('users'); } } ================================================ FILE: database/migrations/2014_10_12_100000_create_password_resets_table.php ================================================ string('email')->index(); $table->string('token')->index(); $table->timestamp('created_at'); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::drop('password_resets'); } } ================================================ FILE: database/migrations/2015_08_04_130507_create_article_tag_table.php ================================================ increments('id'); $table->integer('article_id')->unsigned(); $table->integer('tag_id')->unsigned(); $table->nullableTimestamps(); $table->softDeletes(); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::drop('article_tag'); } } ================================================ FILE: database/migrations/2015_08_04_130520_create_articles_table.php ================================================ increments('id'); $table->integer('category_id')->unsigned(); $table->string('title'); $table->string('slug')->default(''); $table->text('content'); $table->string('image')->nullable(); $table->string('status')->default('PUBLISHED'); $table->date('date'); $table->boolean('featured')->default(0); $table->timestamps(); $table->softDeletes(); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::drop('articles'); } } ================================================ FILE: database/migrations/2015_08_04_130551_create_categories_table.php ================================================ increments('id'); $table->integer('parent_id')->default(0)->nullable(); $table->integer('lft')->unsigned()->nullable(); $table->integer('rgt')->unsigned()->nullable(); $table->integer('depth')->unsigned()->nullable(); $table->string('name'); $table->timestamps(); $table->softDeletes(); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::drop('categories'); } } ================================================ FILE: database/migrations/2015_08_04_131614_create_settings_table.php ================================================ increments('id'); $table->string('key'); $table->string('name'); $table->string('description')->nullable(); $table->string('value')->nullable(); $table->text('field'); $table->tinyInteger('active'); $table->timestamps(); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::drop('settings'); } } ================================================ FILE: database/migrations/2015_08_04_131626_create_tags_table.php ================================================ increments('id'); $table->string('name'); $table->timestamps(); $table->softDeletes(); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::drop('tags'); } } ================================================ FILE: database/migrations/2016_05_05_115641_create_menu_items_table.php ================================================ increments('id'); $table->string('name', 100); $table->string('type', 20)->nullable(); $table->string('link', 255)->nullable(); $table->integer('page_id')->unsigned()->nullable(); $table->integer('parent_id')->unsigned()->nullable(); $table->integer('lft')->unsigned()->nullable(); $table->integer('rgt')->unsigned()->nullable(); $table->integer('depth')->unsigned()->nullable(); $table->timestamps(); $table->softDeletes(); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::drop('menu_items'); } } ================================================ FILE: database/migrations/2016_05_25_121918_create_pages_table.php ================================================ increments('id'); $table->string('template'); $table->string('name'); $table->string('title'); $table->string('slug'); $table->text('content')->nullable(); $table->text('extras')->nullable(); $table->timestamps(); $table->softDeletes(); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::drop('pages'); } } ================================================ FILE: database/migrations/2016_07_24_060017_add_slug_to_categories_table.php ================================================ string('slug')->unique()->after('name'); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::table('categories', function (Blueprint $table) { $table->dropColumn('slug'); }); } } ================================================ FILE: database/migrations/2016_07_24_060101_add_slug_to_tags_table.php ================================================ string('slug')->unique()->after('name'); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::table('tags', function (Blueprint $table) { $table->dropColumn('slug'); }); } } ================================================ FILE: database/migrations/2017_04_20_100848_create_monsters_table.php ================================================ increments('id'); $table->string('address')->nullable(); if (!isset($columnType)) { $table->binary('base64_image'); } $table->string('browse')->nullable(); $table->boolean('checkbox')->nullable(); $table->text('wysiwyg')->nullable(); $table->string('color')->nullable(); $table->date('date')->nullable(); $table->date('date_picker')->nullable(); $table->date('start_date')->nullable(); $table->date('end_date')->nullable(); $table->dateTime('datetime')->nullable(); $table->dateTime('datetime_picker')->nullable(); $table->string('email')->nullable(); $table->integer('hidden')->nullable(); $table->string('icon_picker')->nullable(); $table->string('image')->nullable(); $table->string('month')->nullable(); $table->integer('number')->nullable(); $table->float('float')->nullable(); $table->string('password')->nullable(); $table->string('radio')->nullable(); $table->string('range')->nullable(); $table->integer('select')->nullable(); $table->string('select_from_array')->nullable(); // select_multiple $table->integer('select2')->nullable(); $table->string('select2_from_ajax')->nullable(); $table->string('select2_from_array')->nullable(); // select2_from_ajax_multiple $table->text('simplemde')->nullable(); $table->text('summernote')->nullable(); $table->text('table')->nullable(); $table->text('textarea')->nullable(); $table->string('text'); $table->text('tinymce')->nullable(); $table->string('upload')->nullable(); $table->string('upload_multiple')->nullable(); $table->string('url')->nullable(); $table->text('video')->nullable(); $table->string('week')->nullable(); $table->text('extras')->nullable(); $table->timestamps(); }); if (isset($columnType)) { DB::statement("ALTER TABLE {$prefix}monsters ADD base64_image {$columnType} NULL"); } } /** * Reverse the migrations. * * @return void */ public function down() { Schema::drop('monsters'); } } ================================================ FILE: database/migrations/2017_04_21_052454_create_monster_tag_table.php ================================================ increments('id'); $table->integer('monster_id')->unsigned(); $table->integer('tag_id')->unsigned(); $table->nullableTimestamps(); $table->softDeletes(); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::drop('monster_tag'); } } ================================================ FILE: database/migrations/2017_04_21_052455_create_monster_articles_table.php ================================================ increments('id'); $table->integer('monster_id')->unsigned(); $table->integer('article_id')->unsigned(); $table->nullableTimestamps(); $table->softDeletes(); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::drop('monster_article'); } } ================================================ FILE: database/migrations/2017_04_21_052456_create_monster_category_table.php ================================================ increments('id'); $table->integer('monster_id')->unsigned(); $table->integer('category_id')->unsigned(); $table->nullableTimestamps(); $table->softDeletes(); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::drop('monster_category'); } } ================================================ FILE: database/migrations/2017_12_18_075638_create_icons_table.php ================================================ increments('id'); $table->string('name'); $table->string('icon'); $table->timestamps(); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::drop('icons'); } } ================================================ FILE: database/migrations/2017_12_19_081247_create_products_table.php ================================================ increments('id'); $table->json('name'); $table->json('description')->nullable(); $table->json('details')->nullable(); $table->json('features')->nullable(); $table->integer('price'); $table->integer('category_id'); $table->json('gallery')->nullable(); $table->json('extras')->nullable(); $table->string('main_image')->nullable(); $table->string('privacy_policy')->nullable(); $table->text('specifications')->nullable(); $table->timestamps(); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::drop('products'); } } ================================================ FILE: database/migrations/2018_12_12_075319_create_permission_tables.php ================================================ increments('id'); $table->string('name'); $table->string('guard_name'); $table->timestamps(); }); Schema::create($tableNames['roles'], function (Blueprint $table) { $table->increments('id'); $table->string('name'); $table->string('guard_name'); $table->timestamps(); }); Schema::create($tableNames['model_has_permissions'], function (Blueprint $table) use ($tableNames, $columnNames) { $table->unsignedInteger('permission_id'); $table->string('model_type'); $table->unsignedBigInteger($columnNames['model_morph_key']); $table->index([$columnNames['model_morph_key'], 'model_type']); $table->foreign('permission_id') ->references('id') ->on($tableNames['permissions']) ->onDelete('cascade'); $table->primary( ['permission_id', $columnNames['model_morph_key'], 'model_type'], 'model_has_permissions_permission_model_type_primary' ); }); Schema::create($tableNames['model_has_roles'], function (Blueprint $table) use ($tableNames, $columnNames) { $table->unsignedInteger('role_id'); $table->string('model_type'); $table->unsignedBigInteger($columnNames['model_morph_key']); $table->index([$columnNames['model_morph_key'], 'model_type']); $table->foreign('role_id') ->references('id') ->on($tableNames['roles']) ->onDelete('cascade'); $table->primary( ['role_id', $columnNames['model_morph_key'], 'model_type'], 'model_has_roles_role_model_type_primary' ); }); Schema::create($tableNames['role_has_permissions'], function (Blueprint $table) use ($tableNames) { $table->unsignedInteger('permission_id'); $table->unsignedInteger('role_id'); $table->foreign('permission_id') ->references('id') ->on($tableNames['permissions']) ->onDelete('cascade'); $table->foreign('role_id') ->references('id') ->on($tableNames['roles']) ->onDelete('cascade'); $table->primary(['permission_id', 'role_id']); app('cache')->forget('spatie.permission.cache'); }); } /** * Reverse the migrations. * * @return void */ public function down() { $tableNames = config('permission.table_names'); Schema::drop($tableNames['role_has_permissions']); Schema::drop($tableNames['model_has_roles']); Schema::drop($tableNames['model_has_permissions']); Schema::drop($tableNames['roles']); Schema::drop($tableNames['permissions']); } } ================================================ FILE: database/migrations/2019_09_13_093251_create_failed_jobs_table.php ================================================ bigIncrements('id'); $table->text('connection'); $table->text('queue'); $table->longText('payload'); $table->longText('exception'); $table->timestamp('failed_at')->useCurrent(); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::dropIfExists('failed_jobs'); } } ================================================ FILE: database/migrations/2019_12_02_101119_add_browse_multiple_to_monsters_table.php ================================================ text('browse_multiple')->nullable()->after('week'); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::table('monsters', function (Blueprint $table) { $table->dropColumn('browse_multiple'); }); } } ================================================ FILE: database/migrations/2020_03_12_100831_alter_monsters_table_add_relationship_columns.php ================================================ integer('icon_id')->nullable()->after('week'); }); Schema::create('monster_product', function (Blueprint $table) { $table->increments('id'); $table->integer('monster_id')->unsigned(); $table->integer('product_id')->unsigned(); $table->string('notes'); $table->nullableTimestamps(); $table->softDeletes(); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::table('monsters', function (Blueprint $table) { $table->dropColumn('icon_id'); }); Schema::drop('monster_product'); } } ================================================ FILE: database/migrations/2020_03_12_100831_alter_monsters_table_remove_address.php ================================================ dropColumn('address'); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::table('monsters', function (Blueprint $table) { $table->text('address')->nullable(); }); } } ================================================ FILE: database/migrations/2020_03_29_054416_create_dummy_table.php ================================================ increments('id'); $table->string('name'); $table->text('description'); $table->json('extras'); $table->timestamps(); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::dropIfExists('dummies'); } } ================================================ FILE: database/migrations/2020_03_31_114745_add_columns_to_monster_table.php ================================================ integer('belongs_to_nullable')->nullable(); $table->integer('belongs_to_non_nullable'); } }); } public function down() { Schema::table('monsters', function (Blueprint $table) { $table->dropColumn('belongs_to_nullable'); $table->dropColumn('belongs_to_non_nullable'); }); } } ================================================ FILE: database/migrations/2020_03_31_114745_create_address_table.php ================================================ increments('id'); $table->string('street')->nullable(); $table->string('country'); $table->integer('icon_id')->nullable(); $table->integer('monster_id')->unique(); }); Schema::create('postalboxes', function (Blueprint $table) { $table->increments('id'); $table->string('postal_name')->nullable(); $table->integer('monster_id'); }); } public function down() { Schema::dropIfExists('addresses'); Schema::dropIfExists('postalboxes'); } } ================================================ FILE: database/migrations/2020_03_31_114745_create_pivotable_relations_tables.php ================================================ bigIncrements('id'); $table->string('text')->nullable(); $table->string('sentimentable_type'); $table->bigInteger('sentimentable_id'); $table->bigInteger('user_id')->nullable(); $table->timestamps(); }); Schema::create('recommendables', function (Blueprint $table) { $table->bigIncrements('id'); $table->string('text')->nullable(); $table->string('recommendable_type'); $table->bigInteger('recommendable_id'); $table->bigInteger('recommend_id'); $table->timestamps(); }); Schema::create('billables', function (Blueprint $table) { $table->bigIncrements('id'); $table->string('text')->nullable(); $table->string('billable_type'); $table->bigInteger('billable_id'); $table->bigInteger('bill_id'); $table->timestamps(); }); Schema::create('monster_productdummy', function (Blueprint $table) { $table->increments('id'); $table->integer('monster_id')->unsigned(); $table->integer('product_id')->unsigned(); $table->string('notes'); $table->nullableTimestamps(); }); Schema::create('recommends', function (Blueprint $table) { $table->bigIncrements('id'); $table->string('title')->nullable(); $table->timestamps(); }); Schema::create('postalboxers', function (Blueprint $table) { $table->increments('id'); $table->string('postal_name')->nullable(); $table->integer('monster_id')->nullable(); }); Schema::create('bills', function (Blueprint $table) { $table->bigIncrements('id'); $table->string('title')->nullable(); $table->timestamps(); }); Schema::create('stars', function (Blueprint $table) { $table->bigIncrements('id'); $table->string('starable_type'); $table->bigInteger('starable_id'); $table->string('title')->nullable(); }); } public function down() { Schema::dropIfExists('recommendables'); Schema::dropIfExists('sentiments'); Schema::dropIfExists('recommends'); Schema::dropIfExists('stars'); Schema::dropIfExists('billables'); Schema::dropIfExists('bills'); Schema::dropIfExists('monster_productdummy'); Schema::dropIfExists('postalboxers'); } } ================================================ FILE: database/migrations/2020_03_31_114745_remove_backpackuser_model.php ================================================ replaceModels($model_has_roles); $this->replaceModels($model_has_permissions); } public function replaceModels($table_name) { Log::info('Replacing BackpackUser model in '.$table_name); // if you've ended up with duplicate entries (both for App\User and App\Models\BackpackUser) // we can just delete them $userEntries = DB::table($table_name) ->where('model_type', \App\User::class) ->get(); foreach ($userEntries as $entry) { DB::table($table_name) ->where('role_id', $entry->role_id) ->where('model_type', 'App\Models\BackpackUser') ->where('model_id', $entry->model_id) ->delete(); } // for the rest of them, we can just replace the BackpackUser model with User DB::table($table_name) ->where('model_type', "App\Models\BackpackUser") ->update([ 'model_type' => \App\User::class, ]); } } ================================================ FILE: database/migrations/2020_03_31_114745_rename_address_column_from_monsters.php ================================================ text('address_algolia')->nullable()->after('week'); } }); } } ================================================ FILE: database/migrations/2021_05_07_151146_make_notes_nullable_on_monster_product.php ================================================ string('notes')->nullable()->change(); }); } /** * Reverse the migrations. * * @return void */ public function down() { // } } ================================================ FILE: database/migrations/2021_08_08_130950_change_upload_multiple_column_in_monsters_table.php ================================================ text('upload_multiple')->nullable()->change(); }); } /** * Reverse the migrations. * * @return void */ public function down() { // } } ================================================ FILE: database/migrations/2021_10_13_081033_remove_simplemde_attribute_from_monsters.php ================================================ dropColumn('simplemde'); $table->text('easymde')->nullable(); }); } } ================================================ FILE: database/migrations/2022_01_17_083405_create_owners_table.php ================================================ id(); $table->string('name'); $table->timestamps(); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::dropIfExists('owners'); } } ================================================ FILE: database/migrations/2022_01_17_083526_create_invoices_table.php ================================================ id(); $table->foreignId('owner_id')->constrained(); $table->string('series'); $table->unsignedInteger('number'); $table->date('issuance_date'); $table->date('due_date')->nullable(); $table->timestamps(); }); Schema::enableForeignKeyConstraints(); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::dropIfExists('invoices'); } } ================================================ FILE: database/migrations/2022_01_17_083644_create_invoice_items_table.php ================================================ id(); $table->foreignId('invoice_id')->constrained(); $table->unsignedInteger('order')->nullable(); $table->text('description'); $table->float('quantity'); $table->float('unit_price'); $table->timestamps(); }); Schema::enableForeignKeyConstraints(); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::dropIfExists('invoice_items'); } } ================================================ FILE: database/migrations/2022_01_17_114317_create_pets_table.php ================================================ id(); $table->string('nickname'); $table->timestamps(); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::dropIfExists('pets'); } } ================================================ FILE: database/migrations/2022_01_17_114318_create_owner_pet_table.php ================================================ foreignId('owner_id'); $table->foreignId('pet_id'); $table->string('role'); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::dropIfExists('owner_pet'); } } ================================================ FILE: database/migrations/2022_01_17_114741_create_passports_table.php ================================================ id(); $table->foreignId('pet_id')->constrained()->onDelete('cascade'); $table->string('number'); $table->date('issuance_date'); $table->date('expiry_date')->nullable(); $table->string('first_name'); $table->string('middle_name')->nullable(); $table->string('last_name'); $table->date('birth_date'); $table->string('species'); $table->string('breed')->nullable(); $table->string('colour')->nullable(); $table->text('notes')->nullable(); $table->string('country'); $table->timestamps(); }); Schema::enableForeignKeyConstraints(); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::dropIfExists('passports'); } } ================================================ FILE: database/migrations/2022_01_17_120235_create_skills_table.php ================================================ id(); $table->string('name'); $table->timestamps(); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::dropIfExists('skills'); } } ================================================ FILE: database/migrations/2022_01_17_120236_create_pet_skill_table.php ================================================ foreignId('pet_id'); $table->foreignId('skill_id'); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::dropIfExists('pet_skill'); } } ================================================ FILE: database/migrations/2022_01_17_133436_create_avatars_table.php ================================================ id(); $table->string('url'); $table->integer('avatarable_id'); $table->string('avatarable_type'); $table->timestamps(); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::dropIfExists('avatars'); } } ================================================ FILE: database/migrations/2022_01_17_135143_create_comments_table.php ================================================ id(); $table->text('body'); $table->string('commentable_type'); $table->integer('commentable_id'); $table->string('user_id'); $table->timestamps(); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::dropIfExists('comments'); } } ================================================ FILE: database/migrations/2022_01_17_141636_create_badges_table.php ================================================ id(); $table->string('name'); $table->timestamps(); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::dropIfExists('badges'); } } ================================================ FILE: database/migrations/2022_01_17_141725_create_badgeables_table.php ================================================ id(); $table->integer('badge_id'); $table->integer('badgeable_id'); $table->string('badgeable_type'); $table->text('note'); $table->timestamps(); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::dropIfExists('badgeables'); } } ================================================ FILE: database/migrations/2022_01_21_153540_create_countries_table.php ================================================ id(); $table->string('name'); $table->string('code'); }); Schema::create('countries_monsters', function (Blueprint $table) { $table->id(); $table->bigInteger('monster_id'); $table->bigInteger('country_id'); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::dropIfExists('countries'); Schema::dropIfExists('countries_monsters'); } } ================================================ FILE: database/migrations/2022_01_21_155236_create_graffitis_table.php ================================================ bigInteger('graffiti_id')->nullable(); }); Schema::create('graffitis', function (Blueprint $table) { $table->id(); $table->string('image'); $table->bigInteger('user_id'); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::table('monsters', function (Blueprint $table) { $table->dropColumn('graffiti_id'); }); Schema::dropIfExists('graffitis'); } } ================================================ FILE: database/migrations/2022_01_21_165125_add_country_id_addresses_table.php ================================================ dropColumn('country'); $table->dropColumn('icon_id'); }); Schema::table('addresses', function (Blueprint $table) { $table->bigInteger('country_id')->nullable(); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::table('addresses', function (Blueprint $table) { $table->string('country')->nullable(); $table->bigInteger('icon_id')->nullable(); }); Schema::table('addresses', function (Blueprint $table) { $table->dropColumn('country_id'); }); } } ================================================ FILE: database/migrations/2022_01_21_165552_create_wishes_table.php ================================================ id(); $table->bigInteger('monster_id'); $table->bigInteger('country_id')->nullable(); $table->text('body'); $table->timestamps(); }); Schema::create('universes_wishes', function (Blueprint $table) { $table->id(); $table->bigInteger('universe_id'); $table->bigInteger('wish_id'); $table->string('name')->nullable(); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::dropIfExists('wishes'); Schema::dropIfExists('universes_wishes'); } } ================================================ FILE: database/migrations/2022_01_21_165553_create_balls_table.php ================================================ id(); $table->morphs('ballable'); $table->bigInteger('country_id')->nullable(); $table->text('name'); $table->timestamps(); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::dropIfExists('balls'); } } ================================================ FILE: database/migrations/2022_01_21_165554_create_universes_table.php ================================================ id(); $table->morphs('universable'); $table->string('title')->nullable(); $table->timestamps(); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::dropIfExists('universes'); } } ================================================ FILE: database/migrations/2022_01_22_063032_create_heroes_table.php ================================================ id(); $table->string('name'); $table->timestamps(); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::dropIfExists('heroes'); } } ================================================ FILE: database/migrations/2022_01_22_063323_add_hero_id_to_monsters_table.php ================================================ integer('hero_id')->nullable(); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::table('monsters', function (Blueprint $table) { $table->dropColumn('hero_id'); }); } } ================================================ FILE: database/migrations/2022_01_22_072809_create_stories_table.php ================================================ id(); $table->string('name'); $table->timestamps(); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::dropIfExists('stories'); } } ================================================ FILE: database/migrations/2022_01_22_074008_add_story_id_to_monsters_table.php ================================================ integer('story_id')->nullable(); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::table('monsters', function (Blueprint $table) { $table->dropColumn('story_id'); }); } } ================================================ FILE: database/migrations/2022_01_22_145356_create_caves_table.php ================================================ id(); $table->string('name'); $table->string('lat')->nullable(); $table->string('lng')->nullable(); $table->string('full_address')->nullable(); $table->timestamps(); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::dropIfExists('caves'); } } ================================================ FILE: database/migrations/2022_01_22_145812_add_cave_id_to_monsters_table.php ================================================ integer('cave_id')->nullable(); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::table('monsters', function (Blueprint $table) { $table->dropColumn('cave_id'); }); } } ================================================ FILE: database/migrations/2022_10_08_084702_add_status_to_products.php ================================================ string('status')->default('out-of-stock'); $table->string('condition')->default('NEW'); }); } }; ================================================ FILE: database/migrations/2022_11_20_221518_create_activity_log_table.php ================================================ create(config('activitylog.table_name'), function (Blueprint $table) { $table->bigIncrements('id'); $table->string('log_name')->nullable(); $table->text('description'); $table->nullableMorphs('subject', 'subject'); $table->nullableMorphs('causer', 'causer'); $table->json('properties')->nullable(); $table->timestamps(); $table->index('log_name'); }); } public function down() { Schema::connection(config('activitylog.database_connection'))->dropIfExists(config('activitylog.table_name')); } } ================================================ FILE: database/migrations/2022_11_20_221519_add_event_column_to_activity_log_table.php ================================================ table(config('activitylog.table_name'), function (Blueprint $table) { $table->string('event')->nullable()->after('subject_type'); }); } public function down() { Schema::connection(config('activitylog.database_connection'))->table(config('activitylog.table_name'), function (Blueprint $table) { $table->dropColumn('event'); }); } } ================================================ FILE: database/migrations/2022_11_20_221520_add_batch_uuid_column_to_activity_log_table.php ================================================ table(config('activitylog.table_name'), function (Blueprint $table) { $table->uuid('batch_uuid')->nullable()->after('properties'); }); } public function down() { Schema::connection(config('activitylog.database_connection'))->table(config('activitylog.table_name'), function (Blueprint $table) { $table->dropColumn('batch_uuid'); }); } } ================================================ FILE: database/migrations/2022_12_30_162821_add_soft_deletes_to_pets.php ================================================ softDeletes(); }); } }; ================================================ FILE: database/migrations/2023_01_23_174016_add_status_to_monsters_table.php ================================================ string('status')->default('working'); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::table('monsters', function (Blueprint $table) { $table->dropColumn('status'); }); } }; ================================================ FILE: database/migrations/2023_01_23_194158_add_features_to_monsters_table.php ================================================ json('features')->nullable(); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::table('monsters', function (Blueprint $table) { $table->dropColumn('features'); }); } }; ================================================ FILE: database/migrations/2023_01_23_195752_add_ckeditor_to_monsters_table.php ================================================ text('ckeditor')->nullable(); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::table('monsters', function (Blueprint $table) { $table->dropColumn('ckeditor'); }); } }; ================================================ FILE: database/migrations/2023_02_22_191429_create_media_table.php ================================================ id(); $table->morphs('model'); $table->uuid('uuid')->nullable()->unique(); $table->string('collection_name'); $table->string('name'); $table->string('file_name'); $table->string('mime_type')->nullable(); $table->string('disk'); $table->string('conversions_disk')->nullable(); $table->unsignedBigInteger('size'); $table->json('manipulations'); $table->json('custom_properties'); $table->json('generated_conversions'); $table->json('responsive_images'); $table->unsignedInteger('order_column')->nullable()->index(); $table->nullableTimestamps(); }); } public function down(): void { Schema::dropIfExists('media'); } }; ================================================ FILE: database/migrations/2023_05_31_101941_add_dropzone_column_to_monsters_table.php ================================================ text('dropzone')->nullable(); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::table('monsters', function (Blueprint $table) { $table->dropColumn('dropzone'); }); } }; ================================================ FILE: database/migrations/2023_07_13_071933_add_soft_deletes_to_invoices_table.php ================================================ softDeletes(); }); } /** * Reverse the migrations. */ public function down(): void { Schema::table('invoices', function (Blueprint $table) { $table->dropSoftDeletes(); }); } }; ================================================ FILE: database/migrations/2023_07_16_114745_rename_address_to_google_column_from_monsters.php ================================================ renameColumn('address_algolia', 'address_google'); } }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::table('monsters', function (Blueprint $table) { if (Schema::hasColumn('monsters', 'address_google') && !Schema::hasColumn('monsters', 'address_algolia')) { $table->renameColumn('address_google', 'address_algolia'); } }); } } ================================================ FILE: database/migrations/2023_08_30_093542_add_email_verified_at_column_to_users.php ================================================ addColumn('timestamp', 'email_verified_at', ['nullable' => true])->after('email'); }); } /** * Reverse the migrations. */ public function down(): void { Schema::table('users', function (Blueprint $table) { $table->dropColumn(['email_verified_at']); }); } }; ================================================ FILE: database/migrations/2023_11_23_111148_add_category_relationship_column_to_monsters_table.php ================================================ integer('category_relationship')->nullable()->unsigned(); }); } /** * Reverse the migrations. */ public function down(): void { Schema::table('monsters', function (Blueprint $table) { $table->dropColumn('category_relationship'); }); } }; ================================================ FILE: database/migrations/2024_02_03_225118_create_meetings_table.php ================================================ id(); $table->string('title'); $table->string('email')->nullable(); $table->string('number')->nullable(); $table->json('types')->nullable(); $table->dateTime('start'); $table->dateTime('end')->nullable(); $table->string('background_color')->nullable(); $table->string('text_color')->nullable(); $table->timestamps(); }); } /** * Reverse the migrations. */ public function down(): void { Schema::dropIfExists('meetings'); } }; ================================================ FILE: database/migrations/2024_04_11_085730_create_language_lines_table.php ================================================ bigIncrements('id'); $table->string('group')->index(); $table->string('key'); $table->json('text'); $table->timestamps(); }); } /** * Reverse the migrations. * * @return void */ public function down(): void { Schema::dropIfExists('language_lines'); } }; ================================================ FILE: database/migrations/2024_04_24_115407_add_json_api_fields_to_monster_table.php ================================================ json('select2_json_from_api')->nullable(); $table->json('select2_json_from_api_simple')->nullable(); }); } /** * Reverse the migrations. */ public function down(): void { Schema::table('monsters', function (Blueprint $table) { $table->dropColumn('select2_json_from_api'); $table->dropColumn('select2_json_from_api_simple'); }); } }; ================================================ FILE: database/migrations/2024_10_14_000001_create_pan_analytics_table.php ================================================ id(); $table->string('name'); $table->unsignedBigInteger('impressions')->default(0); $table->unsignedBigInteger('hovers')->default(0); $table->unsignedBigInteger('clicks')->default(0); }); } /** * Reverse the migrations. */ public function down(): void { Schema::dropIfExists('pan_analytics'); } }; ================================================ FILE: database/seeders/.gitkeep ================================================ ================================================ FILE: database/seeders/BadgeSeeder.php ================================================ $badge, 'created_at' => Carbon::now(), 'updated_at' => Carbon::now()]; }, $this->badges)); } } ================================================ FILE: database/seeders/CaveSeeder.php ================================================ count(5)->create(); } } ================================================ FILE: database/seeders/CountryTableSeeder.php ================================================ 'US', 'name' => 'United States'], ['code' => 'CA', 'name' => 'Canada'], ['code' => 'AU', 'name' => 'Australia'], ['code' => 'FR', 'name' => 'France'], ['code' => 'DE', 'name' => 'Germany'], ['code' => 'IS', 'name' => 'Iceland'], ['code' => 'IE', 'name' => 'Ireland'], ['code' => 'IT', 'name' => 'Italy'], ['code' => 'ES', 'name' => 'Spain'], ['code' => 'SE', 'name' => 'Sweden'], ['code' => 'AT', 'name' => 'Austria'], ['code' => 'BE', 'name' => 'Belgium'], ['code' => 'FI', 'name' => 'Finland'], ['code' => 'CZ', 'name' => 'Czech Republic'], ['code' => 'DK', 'name' => 'Denmark'], ['code' => 'NO', 'name' => 'Norway'], ['code' => 'GB', 'name' => 'United Kingdom'], ['code' => 'CH', 'name' => 'Switzerland'], ['code' => 'NZ', 'name' => 'New Zealand'], ['code' => 'RU', 'name' => 'Russian Federation'], ['code' => 'PT', 'name' => 'Portugal'], ['code' => 'NL', 'name' => 'Netherlands'], ['code' => 'IM', 'name' => 'Isle of Man'], ['code' => 'AF', 'name' => 'Afghanistan'], ['code' => 'AX', 'name' => 'Aland Islands '], ['code' => 'AL', 'name' => 'Albania'], ['code' => 'DZ', 'name' => 'Algeria'], ['code' => 'AS', 'name' => 'American Samoa'], ['code' => 'AD', 'name' => 'Andorra'], ['code' => 'AO', 'name' => 'Angola'], ['code' => 'AI', 'name' => 'Anguilla'], ['code' => 'AQ', 'name' => 'Antarctica'], ['code' => 'AG', 'name' => 'Antigua and Barbuda'], ['code' => 'AR', 'name' => 'Argentina'], ['code' => 'AM', 'name' => 'Armenia'], ['code' => 'AW', 'name' => 'Aruba'], ['code' => 'AZ', 'name' => 'Azerbaijan'], ['code' => 'BS', 'name' => 'Bahamas'], ['code' => 'BH', 'name' => 'Bahrain'], ['code' => 'BD', 'name' => 'Bangladesh'], ['code' => 'BB', 'name' => 'Barbados'], ['code' => 'BY', 'name' => 'Belarus'], ['code' => 'BZ', 'name' => 'Belize'], ['code' => 'BJ', 'name' => 'Benin'], ['code' => 'BM', 'name' => 'Bermuda'], ['code' => 'BT', 'name' => 'Bhutan'], ['code' => 'BO', 'name' => 'Bolivia, Plurinational State of'], ['code' => 'BQ', 'name' => 'Bonaire, Sint Eustatius and Saba'], ['code' => 'BA', 'name' => 'Bosnia and Herzegovina'], ['code' => 'BW', 'name' => 'Botswana'], ['code' => 'BV', 'name' => 'Bouvet Island'], ['code' => 'BR', 'name' => 'Brazil'], ['code' => 'IO', 'name' => 'British Indian Ocean Territory'], ['code' => 'BN', 'name' => 'Brunei Darussalam'], ['code' => 'BG', 'name' => 'Bulgaria'], ['code' => 'BF', 'name' => 'Burkina Faso'], ['code' => 'BI', 'name' => 'Burundi'], ['code' => 'KH', 'name' => 'Cambodia'], ['code' => 'CM', 'name' => 'Cameroon'], ['code' => 'CV', 'name' => 'Cape Verde'], ['code' => 'KY', 'name' => 'Cayman Islands'], ['code' => 'CF', 'name' => 'Central African Republic'], ['code' => 'TD', 'name' => 'Chad'], ['code' => 'CL', 'name' => 'Chile'], ['code' => 'CN', 'name' => 'China'], ['code' => 'CX', 'name' => 'Christmas Island'], ['code' => 'CC', 'name' => 'Cocos (Keeling) Islands'], ['code' => 'CO', 'name' => 'Colombia'], ['code' => 'KM', 'name' => 'Comoros'], ['code' => 'CG', 'name' => 'Congo'], ['code' => 'CD', 'name' => 'Congo, the Democratic Republic of the'], ['code' => 'CK', 'name' => 'Cook Islands'], ['code' => 'CR', 'name' => 'Costa Rica'], ['code' => 'CI', 'name' => 'Cote d\'Ivoire'], ['code' => 'HR', 'name' => 'Croatia'], ['code' => 'CU', 'name' => 'Cuba'], ['code' => 'CW', 'name' => 'Curaçao'], ['code' => 'CY', 'name' => 'Cyprus'], ['code' => 'DJ', 'name' => 'Djibouti'], ['code' => 'DM', 'name' => 'Dominica'], ['code' => 'DO', 'name' => 'Dominican Republic'], ['code' => 'EC', 'name' => 'Ecuador'], ['code' => 'EG', 'name' => 'Egypt'], ['code' => 'SV', 'name' => 'El Salvador'], ['code' => 'GQ', 'name' => 'Equatorial Guinea'], ['code' => 'ER', 'name' => 'Eritrea'], ['code' => 'EE', 'name' => 'Estonia'], ['code' => 'ET', 'name' => 'Ethiopia'], ['code' => 'FK', 'name' => 'Falkland Islands (Malvinas)'], ['code' => 'FO', 'name' => 'Faroe Islands'], ['code' => 'FJ', 'name' => 'Fiji'], ['code' => 'GF', 'name' => 'French Guiana'], ['code' => 'PF', 'name' => 'French Polynesia'], ['code' => 'TF', 'name' => 'French Southern Territories'], ['code' => 'GA', 'name' => 'Gabon'], ['code' => 'GM', 'name' => 'Gambia'], ['code' => 'GE', 'name' => 'Georgia'], ['code' => 'GH', 'name' => 'Ghana'], ['code' => 'GI', 'name' => 'Gibraltar'], ['code' => 'GR', 'name' => 'Greece'], ['code' => 'GL', 'name' => 'Greenland'], ['code' => 'GD', 'name' => 'Grenada'], ['code' => 'GP', 'name' => 'Guadeloupe'], ['code' => 'GU', 'name' => 'Guam'], ['code' => 'GT', 'name' => 'Guatemala'], ['code' => 'GG', 'name' => 'Guernsey'], ['code' => 'GN', 'name' => 'Guinea'], ['code' => 'GW', 'name' => 'Guinea-Bissau'], ['code' => 'GY', 'name' => 'Guyana'], ['code' => 'HT', 'name' => 'Haiti'], ['code' => 'HM', 'name' => 'Heard Island and McDonald Islands'], ['code' => 'VA', 'name' => 'Holy See (Vatican City State)'], ['code' => 'HN', 'name' => 'Honduras'], ['code' => 'HK', 'name' => 'Hong Kong'], ['code' => 'HU', 'name' => 'Hungary'], ['code' => 'IN', 'name' => 'India'], ['code' => 'ID', 'name' => 'Indonesia'], ['code' => 'IR', 'name' => 'Iran, Islamic Republic of'], ['code' => 'IQ', 'name' => 'Iraq'], ['code' => 'IL', 'name' => 'Israel'], ['code' => 'JM', 'name' => 'Jamaica'], ['code' => 'JP', 'name' => 'Japan'], ['code' => 'JE', 'name' => 'Jersey'], ['code' => 'JO', 'name' => 'Jordan'], ['code' => 'KZ', 'name' => 'Kazakhstan'], ['code' => 'KE', 'name' => 'Kenya'], ['code' => 'KI', 'name' => 'Kiribati'], ['code' => 'KP', 'name' => 'Korea, Democratic People\'s Republic of'], ['code' => 'KR', 'name' => 'Korea, Republic of'], ['code' => 'KW', 'name' => 'Kuwait'], ['code' => 'KG', 'name' => 'Kyrgyzstan'], ['code' => 'LA', 'name' => 'Lao People\'s Democratic Republic'], ['code' => 'LV', 'name' => 'Latvia'], ['code' => 'LB', 'name' => 'Lebanon'], ['code' => 'LS', 'name' => 'Lesotho'], ['code' => 'LR', 'name' => 'Liberia'], ['code' => 'LY', 'name' => 'Libyan Arab Jamahiriya'], ['code' => 'LI', 'name' => 'Liechtenstein'], ['code' => 'LT', 'name' => 'Lithuania'], ['code' => 'LU', 'name' => 'Luxembourg'], ['code' => 'MO', 'name' => 'Macao'], ['code' => 'MK', 'name' => 'Macedonia'], ['code' => 'MG', 'name' => 'Madagascar'], ['code' => 'MW', 'name' => 'Malawi'], ['code' => 'MY', 'name' => 'Malaysia'], ['code' => 'MV', 'name' => 'Maldives'], ['code' => 'ML', 'name' => 'Mali'], ['code' => 'MT', 'name' => 'Malta'], ['code' => 'MH', 'name' => 'Marshall Islands'], ['code' => 'MQ', 'name' => 'Martinique'], ['code' => 'MR', 'name' => 'Mauritania'], ['code' => 'MU', 'name' => 'Mauritius'], ['code' => 'YT', 'name' => 'Mayotte'], ['code' => 'MX', 'name' => 'Mexico'], ['code' => 'FM', 'name' => 'Micronesia, Federated States of'], ['code' => 'MD', 'name' => 'Moldova, Republic of'], ['code' => 'MC', 'name' => 'Monaco'], ['code' => 'MN', 'name' => 'Mongolia'], ['code' => 'ME', 'name' => 'Montenegro'], ['code' => 'MS', 'name' => 'Montserrat'], ['code' => 'MA', 'name' => 'Morocco'], ['code' => 'MZ', 'name' => 'Mozambique'], ['code' => 'MM', 'name' => 'Myanmar'], ['code' => 'NA', 'name' => 'Namibia'], ['code' => 'NR', 'name' => 'Nauru'], ['code' => 'NP', 'name' => 'Nepal'], ['code' => 'NC', 'name' => 'New Caledonia'], ['code' => 'NI', 'name' => 'Nicaragua'], ['code' => 'NE', 'name' => 'Niger'], ['code' => 'NG', 'name' => 'Nigeria'], ['code' => 'NU', 'name' => 'Niue'], ['code' => 'NF', 'name' => 'Norfolk Island'], ['code' => 'MP', 'name' => 'Northern Mariana Islands'], ['code' => 'OM', 'name' => 'Oman'], ['code' => 'PK', 'name' => 'Pakistan'], ['code' => 'PW', 'name' => 'Palau'], ['code' => 'PS', 'name' => 'Palestinian Territory, Occupied'], ['code' => 'PA', 'name' => 'Panama'], ['code' => 'PG', 'name' => 'Papua New Guinea'], ['code' => 'PY', 'name' => 'Paraguay'], ['code' => 'PE', 'name' => 'Peru'], ['code' => 'PH', 'name' => 'Philippines'], ['code' => 'PN', 'name' => 'Pitcairn'], ['code' => 'PL', 'name' => 'Poland'], ['code' => 'PR', 'name' => 'Puerto Rico'], ['code' => 'QA', 'name' => 'Qatar'], ['code' => 'RE', 'name' => 'Reunion'], ['code' => 'RO', 'name' => 'Romania'], ['code' => 'RW', 'name' => 'Rwanda'], ['code' => 'BL', 'name' => 'Saint Barthélemy'], ['code' => 'SH', 'name' => 'Saint Helena'], ['code' => 'KN', 'name' => 'Saint Kitts and Nevis'], ['code' => 'LC', 'name' => 'Saint Lucia'], ['code' => 'MF', 'name' => 'Saint Martin (French part)'], ['code' => 'PM', 'name' => 'Saint Pierre and Miquelon'], ['code' => 'VC', 'name' => 'Saint Vincent and the Grenadines'], ['code' => 'WS', 'name' => 'Samoa'], ['code' => 'SM', 'name' => 'San Marino'], ['code' => 'ST', 'name' => 'Sao Tome and Principe'], ['code' => 'SA', 'name' => 'Saudi Arabia'], ['code' => 'SN', 'name' => 'Senegal'], ['code' => 'RS', 'name' => 'Serbia'], ['code' => 'SC', 'name' => 'Seychelles'], ['code' => 'SL', 'name' => 'Sierra Leone'], ['code' => 'SG', 'name' => 'Singapore'], ['code' => 'SX', 'name' => 'Sint Maarten (Dutch part)'], ['code' => 'SK', 'name' => 'Slovakia'], ['code' => 'SI', 'name' => 'Slovenia'], ['code' => 'SB', 'name' => 'Solomon Islands'], ['code' => 'SO', 'name' => 'Somalia'], ['code' => 'ZA', 'name' => 'South Africa'], ['code' => 'GS', 'name' => 'South Georgia and the South Sandwich Islands'], ['code' => 'LK', 'name' => 'Sri Lanka'], ['code' => 'SD', 'name' => 'Sudan'], ['code' => 'SR', 'name' => 'Suriname'], ['code' => 'SJ', 'name' => 'Svalbard and Jan Mayen'], ['code' => 'SZ', 'name' => 'Swaziland'], ['code' => 'SY', 'name' => 'Syrian Arab Republic'], ['code' => 'TW', 'name' => 'Taiwan, Province of China'], ['code' => 'TJ', 'name' => 'Tajikistan'], ['code' => 'TZ', 'name' => 'Tanzania, United Republic of'], ['code' => 'TH', 'name' => 'Thailand'], ['code' => 'TL', 'name' => 'Timor-Leste'], ['code' => 'TG', 'name' => 'Togo'], ['code' => 'TK', 'name' => 'Tokelau'], ['code' => 'TO', 'name' => 'Tonga'], ['code' => 'TT', 'name' => 'Trinidad and Tobago'], ['code' => 'TN', 'name' => 'Tunisia'], ['code' => 'TR', 'name' => 'Turkey'], ['code' => 'TM', 'name' => 'Turkmenistan'], ['code' => 'TC', 'name' => 'Turks and Caicos Islands'], ['code' => 'TV', 'name' => 'Tuvalu'], ['code' => 'UG', 'name' => 'Uganda'], ['code' => 'UA', 'name' => 'Ukraine'], ['code' => 'AE', 'name' => 'United Arab Emirates'], ['code' => 'UM', 'name' => 'United States Minor Outlying Islands'], ['code' => 'UY', 'name' => 'Uruguay'], ['code' => 'UZ', 'name' => 'Uzbekistan'], ['code' => 'VU', 'name' => 'Vanuatu'], ['code' => 'VE', 'name' => 'Venezuela, Bolivarian Republic of'], ['code' => 'VN', 'name' => 'Viet Nam'], ['code' => 'VG', 'name' => 'Virgin Islands, British'], ['code' => 'VI', 'name' => 'Virgin Islands, U.S.'], ['code' => 'WF', 'name' => 'Wallis and Futuna'], ['code' => 'EH', 'name' => 'Western Sahara'], ['code' => 'YE', 'name' => 'Yemen'], ['code' => 'ZM', 'name' => 'Zambia'], ['code' => 'ZW', 'name' => 'Zimbabwe'], ]; /** * Run the database seeds. * * @return void */ public function run() { Country::insert($this->countries); } } ================================================ FILE: database/seeders/DatabaseSeeder.php ================================================ call([ IconsTableSeeder::class, \Backpack\Settings\database\seeds\SettingsTableSeeder::class, PermissionManagerTablesSeeder::class, UsersTableSeeder::class, CountryTableSeeder::class, UniversesSeeder::class, PetShopSeeder::class, ]); // Faker factories Recommend::factory()->count(30)->create(); PostalBoxer::factory()->count(30)->create(); Bill::factory()->count(30)->create(); Tag::factory()->count(21)->create(); Category::factory()->count(40)->create(); Article::factory()->count(1031)->create(); Product::factory()->count(210)->create(); Monster::factory()->count(140)->create(); Page::factory()->count(16)->create(); MenuItem::factory()->count(7)->create(); Meeting::factory()->count(50)->create(); } } ================================================ FILE: database/seeders/HeroSeeder.php ================================================ count(5)->create(); } } ================================================ FILE: database/seeders/IconsTableSeeder.php ================================================ 'Tao', 'icon' => 'fa-fas fa-adjust', ], [ 'name' => 'Left', 'icon' => 'fa-fas fa-angle-left', ], [ 'name' => 'Right', 'icon' => 'fa-fas fa-angle-right', ], [ 'name' => 'Home page', 'icon' => 'fa-fas fa-home', ], ]; /** * Run the database seeds. * * @return void */ public function run() { foreach ($this->icons as $icon) { Icon::create($icon); } $entry = Icon::find(rand(1, 4)); $entry->name = 'Archive'; $entry->icon = 'fa-fas fa-archive'; $entry->save(); } } ================================================ FILE: database/seeders/InvoiceItemSeeder.php ================================================ count(5)->create(); } } ================================================ FILE: database/seeders/InvoiceSeeder.php ================================================ count(5)->create(); } } ================================================ FILE: database/seeders/MeetingSeeder.php ================================================ count(5)->create(); } } ================================================ FILE: database/seeders/MillionCommentsSeeder.php ================================================ faker = app()->make(Generator::class); $this->owners = Owner::all(); $this->pets = Pet::all(); } /** * Run the database seeds. * * @return void */ public function run() { DB::disableQueryLog(); DB::beginTransaction(); for ($i = 1; $i <= 100; $i++) { $body = $this->faker->text; $commentable = $i % 2 == 0 ? $this->owners->random() : $this->pets->random(); $commentable_type = get_class($commentable); $commentable_id = $commentable->getKey(); $comments = array_fill(0, 100, [ 'body' => $body, 'commentable_type' => $commentable_type, 'commentable_id' => $commentable_id, 'user_id' => rand(1, 50), ]); DB::table('comments')->insertOrIgnore($comments); } DB::commit(); DB::enableQueryLog(); } } ================================================ FILE: database/seeders/OwnerSeeder.php ================================================ make(Generator::class); Owner::factory()->count(5)->create(); $owners = Owner::all(); foreach ($owners as $owner) { // owner avatars $avatar = rand(1, 2); $owner->avatar()->create([ 'url' => 'uploads/person'.$avatar.'.jpg', ]); // owner invoices $invoices = rand(1, 3); while ($invoices) { $inssuanceDate = CarbonImmutable::parse($faker->dateTimeThisDecade()); $dueDate = $inssuanceDate->addMonths(1); $invoice = Invoice::create([ 'owner_id' => $owner->id, 'series' => Arr::random(['SRV', 'PRD']), 'number' => $faker->numerify('####'), 'issuance_date' => $inssuanceDate->toDateString(), 'due_date' => $dueDate->addDays(15)->toDateString(), ]); // invoice items $invoiceItems = rand(2, 5); while ($invoiceItems) { InvoiceItem::create([ 'invoice_id' => $invoice->id, 'order' => $faker->randomNumber(2), 'description' => $faker->text, 'quantity' => $faker->randomFloat(0, 0, 999), 'unit_price' => $faker->randomFloat(0, 0, 9999), ]); $invoiceItems--; } $invoices--; } } } } ================================================ FILE: database/seeders/PassportSeeder.php ================================================ count(5)->create(); } } ================================================ FILE: database/seeders/PermissionManagerTablesSeeder.php ================================================ [1, 2], 'manage pages' => [1, 2], 'manage menu items' => [1, 2], 'manage users' => [1, 2], 'manage roles' => [1], 'manage permissions' => [1], 'file manager' => [1, 2], 'logs' => [1], 'backups' => [1], ]; /** * Disable foreign key checks based on database driver. */ protected function disableForeignKeyChecks() { $driver = DB::getDriverName(); switch ($driver) { case 'mysql': DB::statement('SET FOREIGN_KEY_CHECKS=0;'); break; case 'sqlite': DB::statement('PRAGMA foreign_keys=OFF;'); break; case 'pgsql': // PostgreSQL doesn't have a global setting, would need to defer constraints break; } } /** * Enable foreign key checks based on database driver. */ protected function enableForeignKeyChecks() { $driver = DB::getDriverName(); switch ($driver) { case 'mysql': DB::statement('SET FOREIGN_KEY_CHECKS=1;'); break; case 'sqlite': DB::statement('PRAGMA foreign_keys=ON;'); break; case 'pgsql': // PostgreSQL doesn't have a global setting, would need to defer constraints break; } } /** * Run the database seeds. * * @return void */ public function run() { $this->disableForeignKeyChecks(); DB::table(Config::get('permission.table_names.model_has_roles'))->truncate(); DB::table(Config::get('permission.table_names.role_has_permissions'))->truncate(); Permission::truncate(); Role::truncate(); $this->enableForeignKeyChecks(); foreach ($this->roles as $role) { Role::create(['name' => $role, 'guard_name' => 'web']); } foreach ($this->permissionsRoles as $permission => $roles) { Permission::create(['name' => $permission, 'guard_name' => 'web'])->roles()->sync($roles); } // Super admin on first user Role::find(1)->users()->sync([1]); } } ================================================ FILE: database/seeders/PetSeeder.php ================================================ count(30)->create(); } } ================================================ FILE: database/seeders/PetShopSeeder.php ================================================ ['Yorkshire', 'Bulldog', 'Bull Terrier'], 'Cat' => ['Sphynx', 'Persa', 'Ragdoll'], 'Bird' => ['Pidgeon', 'Parrot'], ]; /** * Run the database seeds. * * @return void */ public function run() { $faker = app()->make(Generator::class); $this->call(PetSeeder::class); $this->call(OwnerSeeder::class); $this->call(SkillSeeder::class); $this->call(BadgeSeeder::class); $this->call(MillionCommentsSeeder::class); $pets = Pet::all(); $owners = Owner::all(); $skills = Skill::all(); $badges = Badge::all(); // deal with pet stuff foreach ($pets as $pet) { // add one owner for the pet owners list $owner = $owners->random(); $pet->owners()->sync([$owner->id => ['role' => Arr::random($this->ownerRoles)]]); // add 1-3 skills for each pet $petSkills = $skills->random(rand(1, 3))->pluck('id')->toArray(); $pet->skills()->sync($petSkills); // add the pet passport $petSpecie = array_rand($this->petSpeciesAndBreeds, 1); $petBreed = Arr::random($this->petSpeciesAndBreeds[$petSpecie]); $birthDate = CarbonImmutable::parse($faker->dateTimeThisDecade()); $passportDate = $birthDate->addDays(rand(11, 25)); $passportExpiryDate = $passportDate->addYears(5); $pet->passport()->create([ 'number' => $faker->ean13(), 'issuance_date' => $passportDate->toDateString(), 'expiry_date' => $passportExpiryDate->toDateString(), 'first_name' => $faker->firstName, 'middle_name' => $faker->word, 'last_name' => $faker->lastName, 'birth_date' => $birthDate->toDateString(), 'species' => $petSpecie, 'breed' => $petBreed, 'colour' => $faker->colorName(), 'notes' => $faker->text, 'country' => $faker->country, ]); // add the avatar $avatar = rand(1, 3); $pet->avatar()->create([ 'url' => 'uploads/animal'.$avatar.'.jpg', ]); // add comments $comments = rand(1, 5); while ($comments) { Comment::create([ 'body' => $faker->text, 'commentable_type' => get_class($pet), 'commentable_id' => $pet->id, 'user_id' => 1, ]); $comments--; } // add badges $petBadges = []; $badgesToAdd = array_map(function ($badge) use ($faker) { return [$badge => ['note' => $faker->sentence]]; }, $badges->random(3)->pluck('id')->toArray()); foreach ($badgesToAdd as $badge) { $petBadges[array_key_first($badge)] = $badge[array_key_first($badge)]; } $pet->badges()->sync($petBadges); } } } ================================================ FILE: database/seeders/ReportDemoSeeder.php ================================================ command?->info('Seeding report demo data...'); $this->seedInvoices(); $this->seedMonsters(); $this->seedProducts(); $this->command?->info('Report demo data seeded successfully!'); } // ─── INVOICES ──────────────────────────────────────────────────────── private function seedInvoices(): void { $this->command?->info(' → Invoices & Invoice Items...'); // Ensure we have owners to attach invoices to $ownerIds = Owner::pluck('id')->toArray(); if (count($ownerIds) < 10) { Owner::factory()->count(10 - count($ownerIds))->create(); $ownerIds = Owner::pluck('id')->toArray(); } $faker = fake(); $series = ['SRV', 'PRD', 'WEB', 'CON']; $itemDescriptions = [ 'Consultation fee', 'Vaccination', 'Grooming service', 'Pet food (premium)', 'Medication', 'Surgery', 'X-Ray', 'Blood test', 'Dental cleaning', 'Boarding (per night)', 'Training session', 'Microchip implant', 'Nail trimming', 'Flea treatment', 'Pet insurance premium', ]; $period = CarbonPeriod::create( Carbon::now()->subMonths(24)->startOfMonth(), '1 day', Carbon::now() ); $invoiceNumber = Invoice::max('number') ?? 1000; $invoices = []; $items = []; $now = Carbon::now()->format('Y-m-d H:i:s'); foreach ($period as $day) { // More invoices on weekdays, seasonal bump in spring/summer $month = (int) $day->format('m'); $dayOfWeek = (int) $day->format('N'); // 1=Mon, 7=Sun $baseRate = 3; // Seasonal: more activity in spring (Mar-May) and winter holidays (Nov-Dec) if (in_array($month, [3, 4, 5])) { $baseRate = 5; } elseif (in_array($month, [11, 12])) { $baseRate = 6; } elseif (in_array($month, [7, 8])) { $baseRate = 4; } // Weekends are quieter if ($dayOfWeek >= 6) { $baseRate = max(1, intdiv($baseRate, 2)); } // Add growth trend: more recent = slightly more invoices $monthsAgo = Carbon::now()->diffInMonths($day); $growthMultiplier = 1 + (24 - $monthsAgo) * 0.015; // ~1.0 to ~1.36 $count = max(0, (int) round($baseRate * $growthMultiplier + rand(-1, 2))); for ($i = 0; $i < $count; $i++) { $invoiceNumber++; $issuanceDate = $day->copy()->addHours(rand(8, 18))->addMinutes(rand(0, 59)); $dueDate = $issuanceDate->copy()->addDays(rand(7, 30)); $createdAt = $issuanceDate->format('Y-m-d H:i:s'); $invoiceId = null; $invoices[] = [ 'owner_id' => Arr::random($ownerIds), 'series' => Arr::random($series), 'number' => $invoiceNumber, 'issuance_date' => $issuanceDate->format('Y-m-d'), 'due_date' => $dueDate->format('Y-m-d'), 'created_at' => $createdAt, 'updated_at' => $createdAt, ]; } } // Bulk insert invoices in chunks foreach (array_chunk($invoices, 500) as $chunk) { Invoice::insert($chunk); } // Now create items for the newly created invoices $newInvoices = Invoice::where('number', '>', 1000) ->select('id', 'issuance_date') ->get(); foreach ($newInvoices as $invoice) { $itemCount = rand(1, 5); for ($j = 1; $j <= $itemCount; $j++) { $quantity = rand(1, 4); $unitPrice = Arr::random([15, 25, 35, 50, 75, 100, 150, 200, 299, 499]); $items[] = [ 'invoice_id' => $invoice->id, 'order' => $j, 'description' => Arr::random($itemDescriptions), 'quantity' => $quantity, 'unit_price' => $unitPrice, 'created_at' => $invoice->issuance_date.' 12:00:00', 'updated_at' => $invoice->issuance_date.' 12:00:00', ]; } } foreach (array_chunk($items, 500) as $chunk) { InvoiceItem::insert($chunk); } $this->command?->info(' ✓ '.count($invoices).' invoices with '.count($items).' items'); } // ─── MONSTERS ──────────────────────────────────────────────────────── private function seedMonsters(): void { $this->command?->info(' → Monsters...'); $faker = fake(); $statuses = ['working', 'not-working', 'dont-know']; $statusWeights = [60, 25, 15]; // working is most common $period = CarbonPeriod::create( Carbon::now()->subMonths(24)->startOfMonth(), '1 day', Carbon::now() ); $monsters = []; foreach ($period as $day) { $month = (int) $day->format('m'); $dayOfWeek = (int) $day->format('N'); // Base: 1-2 monsters per day, with some variation $baseRate = 2; // Seasonal spikes if (in_array($month, [1, 2])) { $baseRate = 3; // New year burst } elseif (in_array($month, [6, 7])) { $baseRate = 1; // Summer dip } elseif ($month === 10) { $baseRate = 4; // Halloween spike! } // Growth trend $monthsAgo = Carbon::now()->diffInMonths($day); $growthMultiplier = 1 + (24 - $monthsAgo) * 0.02; $count = max(0, (int) round($baseRate * $growthMultiplier + rand(-1, 1))); for ($i = 0; $i < $count; $i++) { $createdAt = $day->copy()->addHours(rand(0, 23))->addMinutes(rand(0, 59))->addSeconds(rand(0, 59)); // Weighted random status $roll = rand(1, 100); if ($roll <= $statusWeights[0]) { $status = $statuses[0]; } elseif ($roll <= $statusWeights[0] + $statusWeights[1]) { $status = $statuses[1]; } else { $status = $statuses[2]; } $number = rand(1, 10000); $ts = $createdAt->format('Y-m-d H:i:s'); $monsters[] = [ 'text' => $faker->unique()->sentence(rand(3, 6)), 'textarea' => $faker->text(200), 'email' => $faker->email(), 'number' => $number, 'float' => round($faker->randomFloat(2, 0, 1000), 2), 'status' => $status, 'checkbox' => rand(0, 1), 'date' => $createdAt->format('Y-m-d'), 'datetime' => $ts, 'start_date' => $createdAt->format('Y-m-d'), 'end_date' => $createdAt->copy()->addDays(rand(1, 90))->format('Y-m-d'), 'select' => null, 'icon_id' => null, 'belongs_to_non_nullable' => 0, 'created_at' => $ts, 'updated_at' => $ts, ]; } } foreach (array_chunk($monsters, 500) as $chunk) { Monster::insert($chunk); } $this->command?->info(' ✓ '.count($monsters).' monsters'); } // ─── PRODUCTS ──────────────────────────────────────────────────────── private function seedProducts(): void { $this->command?->info(' → Products...'); $faker = fake(); $statuses = ['in-stock', 'out-of-stock', 'on-hold']; $conditions = ['NEW', 'USED', 'BROKEN']; $categoryIds = Category::pluck('id')->toArray(); if (empty($categoryIds)) { Category::factory()->count(10)->create(); $categoryIds = Category::pluck('id')->toArray(); } $productNames = [ 'Widget', 'Gadget', 'Gizmo', 'Thingamajig', 'Doohickey', 'Contraption', 'Apparatus', 'Device', 'Mechanism', 'Instrument', 'Module', 'Component', 'Unit', 'Assembly', 'Kit', 'Tool', 'Accessory', 'Attachment', 'Adapter', 'Connector', ]; $adjectives = [ 'Premium', 'Deluxe', 'Ultra', 'Pro', 'Basic', 'Advanced', 'Compact', 'Heavy-Duty', 'Lightweight', 'Portable', 'Smart', 'Digital', 'Analog', 'Wireless', 'Turbo', 'Eco', 'Mini', 'Mega', ]; $period = CarbonPeriod::create( Carbon::now()->subMonths(24)->startOfMonth(), '1 day', Carbon::now() ); $products = []; foreach ($period as $day) { $month = (int) $day->format('m'); // Products added more frequently over time (catalog growth) $baseRate = 1; // Q4 and Q1 see more product launches if (in_array($month, [1, 10, 11, 12])) { $baseRate = 2; } $monthsAgo = Carbon::now()->diffInMonths($day); $growthMultiplier = 1 + (24 - $monthsAgo) * 0.025; $count = max(0, (int) round($baseRate * $growthMultiplier + rand(-1, 1))); for ($i = 0; $i < $count; $i++) { $createdAt = $day->copy()->addHours(rand(8, 20))->addMinutes(rand(0, 59)); $ts = $createdAt->format('Y-m-d H:i:s'); // Price distribution: mostly mid-range, some cheap, some expensive $priceRoll = rand(1, 100); if ($priceRoll <= 20) { $price = rand(5, 50); // budget } elseif ($priceRoll <= 70) { $price = rand(50, 300); // mid-range } elseif ($priceRoll <= 90) { $price = rand(300, 800); // premium } else { $price = rand(800, 2500); // luxury } // Status weighted: 60% in-stock, 25% out-of-stock, 15% on-hold $statusRoll = rand(1, 100); if ($statusRoll <= 60) { $status = 'in-stock'; } elseif ($statusRoll <= 85) { $status = 'out-of-stock'; } else { $status = 'on-hold'; } // Condition weighted: 70% new, 20% used, 10% broken $conditionRoll = rand(1, 100); if ($conditionRoll <= 70) { $condition = 'NEW'; } elseif ($conditionRoll <= 90) { $condition = 'USED'; } else { $condition = 'BROKEN'; } $name = Arr::random($adjectives).' '.Arr::random($productNames).' #'.rand(10000, 99999).'-'.rand(100, 999); $products[] = [ 'name' => json_encode(['en' => $name]), 'description' => json_encode(['en' => $faker->sentence(10)]), 'details' => json_encode(['en' => $faker->paragraph(3)]), 'price' => $price, 'category_id' => Arr::random($categoryIds), 'status' => $status, 'condition' => $condition, 'created_at' => $ts, 'updated_at' => $ts, ]; } } foreach (array_chunk($products, 500) as $chunk) { Product::insert($chunk); } $this->command?->info(' ✓ '.count($products).' products'); } } ================================================ FILE: database/seeders/SkillSeeder.php ================================================ $skill, 'created_at' => Carbon::now(), 'updated_at' => Carbon::now()]; }, $skills)); } } ================================================ FILE: database/seeders/StorySeeder.php ================================================ count(5)->create(); } } ================================================ FILE: database/seeders/UniversesSeeder.php ================================================ 'universe 1', 'universable_type' => '', 'universable_id' => 0, ], [ 'title' => 'universe 2', 'universable_type' => '', 'universable_id' => 0, ], [ 'title' => 'universe 3', 'universable_type' => '', 'universable_id' => 0, ], ]); } } ================================================ FILE: database/seeders/UsersTableSeeder.php ================================================ 'Demo Admin', 'email' => 'admin@example.com', 'password' => bcrypt('admin'), 'email_verified_at' => now(), ]); User::factory()->count(131)->create(); } } ================================================ FILE: docker/infra/certs/local-dev-key.pem ================================================ -----BEGIN PRIVATE KEY----- MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCwirez1D5LTCkc GRSRMWuG5iJTfh6mqFCqBgLKloSsOLLy+7KdmcvWFkNIxM9ceHTf+EDvsc4dCCpM 9vClIZP1azX1DUJtng31bK+xIm30QeTg2ggPfM2OhPayN5lDgz48HZgN7anmEm53 phhXtcLiU5jCX5LjgzN9MOgJ6JobixdBDlTvku69pvAw+pUd6eBsvBS+bjsDJyM7 2dwRvANMWJEfsPFelXXpFEAopasprE7qJmO4U2V4KCc+1Z/BhdDvtB22qKqyyok2 uhGJf1r2z4Grrt9W9pNmuel2UfjKpRX6jFUqPygcYqGXGE4eRy7nynj+BU2srm94 AlcjsE9fAgMBAAECggEAD0uVauEinId2sFaD76hmdoONycoNgcbnZjOrHj44NGud JWwlJ35hqKS5I57ZkFtnVNg/WAUBpIZGk/B5HPVxyjuFqzuA29prvy2xcxlWiWkE GW8Kb70SWhyu+vXSM4U1aSPvPpWuuJ40L+2WAlNfFRjFDWIWadu+JESOdf1PDL+1 Z58cRhEcKQS9hBrizPFgxb2QZa3gXQpdTwKXU8IsNKGocuX9tnZPQfctRkRNvHs6 OX2ZEatXlcO/zD6heKHGYRypDUyX+WgtArMG1PS7Kuec253S0/bDxCMKXIGcGH/J cLgzyhp4D5odu6dCbdDz//i0WO3auNtLrMgntkDXYQKBgQDVVeDwIBSZ/QybisZF /1AsCAq5O7xYrIg0LkXqChzDHAm6taMNtZGbHY42dVP8ybnbAOkNrQrHGxB1MdrM 5Q39FrWe+ctxNvAay6c+49Wtp9mqt2/CX3r+wJUhJAf+am7QTwCJglWW1Kz/RD61 OFZMeoVxq/YgbjWyPh5axmyp1wKBgQDT2R6cNq3AaaLIZIpiEEFCGB8ASjwG0SHw V/mOAznl+td9kbXacTJ8jWAE8kdPqH4ZKkMU+PXImsz2T8dB/LGVIz/c4Tg9z+Mo w/tmK5a8NA2/AL/zIt/GSx+HsCjynbcKlY9hJfZGQNkxKtvZDXbjpcausojs6z3V Hk4v1Z6luQKBgBQmTl6fyRJaUkyGqP+Hg90EzW59c+a0NREopbXbSqgrB8g4y7PJ yHzsJ7iBEHO54fILffeqtm/j4IQRN2dO4ylaccEYOtzwoXEGdz97aX1Dc02qkcW8 GvPg4LUGoDKpftnx/E0AoHDkmYpqubmIHq6Oi/gWk+KwRiYVs+xC/ZR1AoGAbJ/z th3DUdnYgfArlMTI8V705m0qAkTRpi814r98vJO2UsiX+n34aS0EgwTH0+yNW9Hz u5k8TbQyTEnz3b34QIRmhpdlAyzJSWnUSjsnezElqz5zLfQ/0alLbYPCO0TrSh4N +r5AXR17QF69g7oHsAqcqY8Z7oFgnxp+9MAQLOECgYEA1IfgKXmUY10XK2GFPUl2 YdxF9Bf0F1oCt8ExtY3bv8BXRcDgp7YaLk9uI9xWpXQ2Bv0sRSi+m8a9YYyrzeoL eOaJ35qkxm2lUbDTSxk4g5VhF3Yfe4rQQUY5Hy49RKBzDIPstod34P5vnKd+zhzC rUE1ChWqXUJawuhVE3rg3MU= -----END PRIVATE KEY----- ================================================ FILE: docker/infra/certs/local-dev.pem ================================================ -----BEGIN CERTIFICATE----- MIIEbzCCAtegAwIBAgIQLnQ/klzIW/vkgsn5Oh1qITANBgkqhkiG9w0BAQsFADCB hTEeMBwGA1UEChMVbWtjZXJ0IGRldmVsb3BtZW50IENBMS0wKwYDVQQLDCRMQVBU T1AtTk5RNk5QOEpcQVNVU0BMQVBUT1AtTk5RNk5QOEoxNDAyBgNVBAMMK21rY2Vy dCBMQVBUT1AtTk5RNk5QOEpcQVNVU0BMQVBUT1AtTk5RNk5QOEowHhcNMjQwNzEx MDg1MTE4WhcNMjYxMDExMDg1MTE4WjBIMScwJQYDVQQKEx5ta2NlcnQgZGV2ZWxv cG1lbnQgY2VydGlmaWNhdGUxHTAbBgNVBAsMFHB4cG1ATEFQVE9QLU5OUTZOUDhK MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsIq3s9Q+S0wpHBkUkTFr huYiU34epqhQqgYCypaErDiy8vuynZnL1hZDSMTPXHh03/hA77HOHQgqTPbwpSGT 9Ws19Q1CbZ4N9WyvsSJt9EHk4NoID3zNjoT2sjeZQ4M+PB2YDe2p5hJud6YYV7XC 4lOYwl+S44MzfTDoCeiaG4sXQQ5U75LuvabwMPqVHengbLwUvm47AycjO9ncEbwD TFiRH7DxXpV16RRAKKWrKaxO6iZjuFNleCgnPtWfwYXQ77QdtqiqssqJNroRiX9a 9s+Bq67fVvaTZrnpdlH4yqUV+oxVKj8oHGKhlxhOHkcu58p4/gVNrK5veAJXI7BP XwIDAQABo4GWMIGTMA4GA1UdDwEB/wQEAwIFoDATBgNVHSUEDDAKBggrBgEFBQcD ATAfBgNVHSMEGDAWgBT8EZlbG4vysChbCCfU5S4B8n7ENzBLBgNVHREERDBCggVs b2NhbIILKi5kZW1vLnRlc3SCCWRlbW8udGVzdIIJbG9jYWxob3N0hwR/AAABhxAA AAAAAAAAAAAAAAAAAAABMA0GCSqGSIb3DQEBCwUAA4IBgQA1TSqxEkDYwBoQiwaC xmxWoJmd/q9XROXjReTKTpdSSXUCnWB45OmzzZGMtyOZIO1qJUOBRphVURjun3ut i2szlA+k1gLBihGm8jMJQ3C9epK3qwIOqATKBzdVCI/qncXKXbENCXsFwyLvvrrB WTeY0SsYaFq5kGm013Mx9TwGZbXNhC4P0d/a1+S2miR4Jssh9a5w+geDddWbePR3 rv8HIn6BRlxUtaovBxGXP9KhHCz5YD64h1Tz7gs0KeIvudgRz9BHBEiAhrcQ4mLt EipQvluy31GOw23jE3WQyGFEa67VOu8oyNx6Hn5LARhut0T40yJ7suYkCHxpPxAk f5Ik2BQ41bmkk393OckilU6BH8zOLqWzcRChNtycPSl1nlQDtdJcRLYZfTd6XlwG udpbFujlhapJK1NkpoHKiPGBaKxfmaYAdi8gOPD9zQrnFtZcA1LDbP4Y0meB9tOH B+CfkWfG3vuCrCJG3oIiJfuUk1KXv8hVKXG09qCtBJ4+yFc= -----END CERTIFICATE----- ================================================ FILE: docker-compose.yml ================================================ services: php: build: context: . dockerfile: Dockerfile target: development args: USER_ID: ${UID:-1000} GROUP_ID: ${GID:-1000} volumes: - .:/var/www/html/ restart: unless-stopped networks: - development ports: - 80:8080 - 443:8443 - 5173:5173 depends_on: - mariadb environment: SSL_MODE: "full" SSL_CERTIFICATE_FILE: "certs/local-dev.pem" SSL_PRIVATE_KEY_FILE: "certs/local-dev-key.pem" # docker-php configs AUTORUN_ENABLED: "true" AUTORUN_LARAVEL_MIGRATION: "true" AUTORUN_LARAVEL_CONFIG_CACHE: "false" AUTORUN_LARAVEL_EVENT_CACHE: "false" AUTORUN_LARAVEL_ROUTE_CACHE: "false" AUTORUN_LARAVEL_STORAGE_LINK: "true" AUTORUN_LARAVEL_VIEW_CACHE: "false" mariadb: image: mariadb:11 networks: - development volumes: - ./_volumes/mysql/mysqsl_data:/var/lib/mysql environment: MYSQL_ROOT_PASSWORD: '${DB_ROOT_PASSWORD}' MYSQL_ROOT_HOST: "%" MYSQL_DATABASE: '${DB_DATABASE}' MYSQL_USER: '${DB_USERNAME}' MYSQL_PASSWORD: '${DB_PASSWORD}' MYSQL_ALLOW_EMPTY_PASSWORD: 'no' ports: - "3306:3306" mailpit: image: axllent/mailpit networks: - development networks: development: ================================================ FILE: entrypoint.d/51-after.sh ================================================ #!/bin/sh echo "hey there after running laravel automations" ================================================ FILE: install.sh ================================================ #!/usr/bin/env bash # if env file exists abort if [ -f .env ]; then echo "Env file already exists. Use the start.sh script to start the project." exit 1 fi # copy the env file cp .env.docker.example .env # Install the dependencies composer install --no-interaction --ansi # remove backpack packages and install with --prefer-source so they are cloned from the git repositories # comment the following line if you are not a backpack maintainer. rm -rf vendor/backpack composer install --no-interaction --prefer-source --ansi php artisan key:generate bash start.sh ================================================ FILE: lang/en/auth.php ================================================ 'These credentials do not match our records.', 'throttle' => 'Too many login attempts. Please try again in :seconds seconds.', ]; ================================================ FILE: lang/en/pagination.php ================================================ '« Previous', 'next' => 'Next »', ]; ================================================ FILE: lang/en/passwords.php ================================================ 'Passwords must be at least six characters and match the confirmation.', 'reset' => 'Your password has been reset!', 'sent' => 'We have e-mailed your password reset link!', 'token' => 'This password reset token is invalid.', 'user' => "We can't find a user with that e-mail address.", ]; ================================================ FILE: lang/en/validation.php ================================================ 'The :attribute must be accepted.', 'active_url' => 'The :attribute is not a valid URL.', 'after' => 'The :attribute must be a date after :date.', 'alpha' => 'The :attribute may only contain letters.', 'alpha_dash' => 'The :attribute may only contain letters, numbers, and dashes.', 'alpha_num' => 'The :attribute may only contain letters and numbers.', 'array' => 'The :attribute must be an array.', 'before' => 'The :attribute must be a date before :date.', 'between' => [ 'numeric' => 'The :attribute must be between :min and :max.', 'file' => 'The :attribute must be between :min and :max kilobytes.', 'string' => 'The :attribute must be between :min and :max characters.', 'array' => 'The :attribute must have between :min and :max items.', ], 'boolean' => 'The :attribute field must be true or false.', 'confirmed' => 'The :attribute confirmation does not match.', 'date' => 'The :attribute is not a valid date.', 'date_format' => 'The :attribute does not match the format :format.', 'different' => 'The :attribute and :other must be different.', 'digits' => 'The :attribute must be :digits digits.', 'digits_between' => 'The :attribute must be between :min and :max digits.', 'distinct' => 'The :attribute field has a duplicate value.', 'email' => 'The :attribute must be a valid email address.', 'exists' => 'The selected :attribute is invalid.', 'filled' => 'The :attribute field is required.', 'image' => 'The :attribute must be an image.', 'in' => 'The selected :attribute is invalid.', 'in_array' => 'The :attribute field does not exist in :other.', 'integer' => 'The :attribute must be an integer.', 'ip' => 'The :attribute must be a valid IP address.', 'json' => 'The :attribute must be a valid JSON string.', 'max' => [ 'numeric' => 'The :attribute may not be greater than :max.', 'file' => 'The :attribute may not be greater than :max kilobytes.', 'string' => 'The :attribute may not be greater than :max characters.', 'array' => 'The :attribute may not have more than :max items.', ], 'mimes' => 'The :attribute must be a file of type: :values.', 'min' => [ 'numeric' => 'The :attribute must be at least :min.', 'file' => 'The :attribute must be at least :min kilobytes.', 'string' => 'The :attribute must be at least :min characters.', 'array' => 'The :attribute must have at least :min items.', ], 'not_in' => 'The selected :attribute is invalid.', 'numeric' => 'The :attribute must be a number.', 'present' => 'The :attribute field must be present.', 'regex' => 'The :attribute format is invalid.', 'required' => 'The :attribute field is required.', 'required_if' => 'The :attribute field is required when :other is :value.', 'required_unless' => 'The :attribute field is required unless :other is in :values.', 'required_with' => 'The :attribute field is required when :values is present.', 'required_with_all' => 'The :attribute field is required when :values is present.', 'required_without' => 'The :attribute field is required when :values is not present.', 'required_without_all' => 'The :attribute field is required when none of :values are present.', 'same' => 'The :attribute and :other must match.', 'size' => [ 'numeric' => 'The :attribute must be :size.', 'file' => 'The :attribute must be :size kilobytes.', 'string' => 'The :attribute must be :size characters.', 'array' => 'The :attribute must contain :size items.', ], 'string' => 'The :attribute must be a string.', 'timezone' => 'The :attribute must be a valid zone.', 'unique' => 'The :attribute has already been taken.', 'url' => 'The :attribute format is invalid.', /* |-------------------------------------------------------------------------- | Custom Validation Language Lines |-------------------------------------------------------------------------- | | Here you may specify custom validation messages for attributes using the | convention "attribute.rule" to name the lines. This makes it quick to | specify a specific custom language line for a given attribute rule. | */ 'custom' => [ 'attribute-name' => [ 'rule-name' => 'custom-message', ], ], /* |-------------------------------------------------------------------------- | Custom Validation Attributes |-------------------------------------------------------------------------- | | The following language lines are used to swap attribute place-holders | with something more reader friendly such as E-Mail Address instead | of "email". This simply helps us make messages a little cleaner. | */ 'attributes' => [], ]; ================================================ FILE: lang/vendor/backpack/en/crud.php ================================================ 'Are you sure you want to delete this item?', 'delete_confirmation_title' => 'Item Deleted', 'delete_confirmation_message' => 'The item has been deleted successfully.', 'delete_confirmation_not_title' => 'Not Deleted', 'delete_confirmation_not_message' => "Deleting entries is disabled in the online demo. Dooh.", 'delete_confirmation_not_deleted_title' => 'Not deleted', 'delete_confirmation_not_deleted_message' => 'Nothing happened. Your item is safe.', // Bulk actions 'bulk_no_entries_selected_title' => 'No entries selected', 'bulk_no_entries_selected_message' => 'Please select one or more items to perform a bulk action on them.', // Bulk confirmation 'bulk_delete_are_you_sure' => 'Are you sure you want to delete these :number entries?', 'bulk_delete_sucess_title' => 'Entries deleted', 'bulk_delete_sucess_message' => ' items have been deleted', 'bulk_delete_error_title' => 'Delete failed', 'bulk_delete_error_message' => 'You can\'t bulk delete items in the online Demo.', // Ajax errors 'ajax_error_title' => 'Error', 'ajax_error_text' => 'Error loading page. Please refresh the page.', ]; ================================================ FILE: lang/vendor/backpack/tr/crud.php ================================================ 'Bu öğeyi silmek istediğinizden emin misiniz?', 'delete_confirmation_title' => 'Öğe Silindi', 'delete_confirmation_message' => 'Öğe başarıyla silindi.', 'delete_confirmation_not_title' => 'Sillinmedi', 'delete_confirmation_not_message' => "Demo sürümde verileri silme devre dışı bırakılmıştır.", 'delete_confirmation_not_deleted_title' => 'Sillinmedi', 'delete_confirmation_not_deleted_message' => 'Öğeniz silinmedi, güvende!', // Bulk actions 'bulk_no_entries_selected_title' => 'Hiç bir öğe seçilmedi', 'bulk_no_entries_selected_message' => 'Lütfen öğelerin üzerinde toplu işlem yapmak için bir veya daha fazla öğe seçin.', // Bulk confirmation 'bulk_delete_are_you_sure' => ':number adet öğeyi gerçekten silmek istediğinize eminmisiniz?', 'bulk_delete_sucess_title' => 'Öğeler silindi', 'bulk_delete_sucess_message' => ' öğe silindi', 'bulk_delete_error_title' => 'Silinemedi', 'bulk_delete_error_message' => 'Demo sürümünde toplu olarak öğeleri silemezsiniz.', // Ajax errors 'ajax_error_title' => 'Hata', 'ajax_error_text' => 'Sayfa yüklenirken hata oluştu. Lütfen sayfayı yenileyin.', ]; ================================================ FILE: lang/vendor/backup/ar/notifications.php ================================================ 'رسالة استثناء: :message', 'exception_trace' => 'تتبع الإستثناء: :trace', 'exception_message_title' => 'رسالة استثناء', 'exception_trace_title' => 'تتبع الإستثناء', 'backup_failed_subject' => 'أخفق النسخ الاحتياطي لل :application_name', 'backup_failed_body' => 'مهم: حدث خطأ أثناء النسخ الاحتياطي :application_name', 'backup_successful_subject' => 'نسخ احتياطي جديد ناجح ل :application_name', 'backup_successful_subject_title' => 'نجاح النسخ الاحتياطي الجديد!', 'backup_successful_body' => 'أخبار عظيمة، نسخة احتياطية جديدة ل :application_name تم إنشاؤها بنجاح على القرص المسمى :disk_name.', 'cleanup_failed_subject' => 'فشل تنظيف النسخ الاحتياطي للتطبيق :application_name .', 'cleanup_failed_body' => 'حدث خطأ أثناء تنظيف النسخ الاحتياطية ل :application_name', 'cleanup_successful_subject' => 'تنظيف النسخ الاحتياطية ل :application_name تمت بنجاح', 'cleanup_successful_subject_title' => 'تنظيف النسخ الاحتياطية تم بنجاح!', 'cleanup_successful_body' => 'تنظيف النسخ الاحتياطية ل :application_name على القرص المسمى :disk_name تم بنجاح.', 'healthy_backup_found_subject' => 'النسخ الاحتياطية ل :application_name على القرص :disk_name صحية', 'healthy_backup_found_subject_title' => 'النسخ الاحتياطية ل :application_name صحية', 'healthy_backup_found_body' => 'تعتبر النسخ الاحتياطية ل :application_name صحية. عمل جيد!', 'unhealthy_backup_found_subject' => 'مهم: النسخ الاحتياطية ل :application_name غير صحية', 'unhealthy_backup_found_subject_title' => 'مهم: النسخ الاحتياطية ل :application_name غير صحية. :problem', 'unhealthy_backup_found_body' => 'النسخ الاحتياطية ل :application_name على القرص :disk_name غير صحية.', 'unhealthy_backup_found_not_reachable' => 'لا يمكن الوصول إلى وجهة النسخ الاحتياطي. :error', 'unhealthy_backup_found_empty' => 'لا توجد نسخ احتياطية لهذا التطبيق على الإطلاق.', 'unhealthy_backup_found_old' => 'تم إنشاء أحدث النسخ الاحتياطية في :date وتعتبر قديمة جدا.', 'unhealthy_backup_found_unknown' => 'عذرا، لا يمكن تحديد سبب دقيق.', 'unhealthy_backup_found_full' => 'النسخ الاحتياطية تستخدم الكثير من التخزين. الاستخدام الحالي هو :disk_usage وهو أعلى من الحد المسموح به من :disk_limit.', ]; ================================================ FILE: lang/vendor/backup/bg/notifications.php ================================================ 'Съобщение за изключение: :message', 'exception_trace' => 'Проследяване на изключение: :trace', 'exception_message_title' => 'Съобщение за изключение', 'exception_trace_title' => 'Проследяване на изключение', 'backup_failed_subject' => 'Неуспешно резервно копие на :application_name', 'backup_failed_body' => 'Важно: Възникна грешка при архивиране на :application_name', 'backup_successful_subject' => 'Успешно ново резервно копие на :application_name', 'backup_successful_subject_title' => 'Успешно ново резервно копие!', 'backup_successful_body' => 'Чудесни новини, ново резервно копие на :application_name беше успешно създадено на диска с име :disk_name.', 'cleanup_failed_subject' => 'Почистването на резервните копия на :application_name не бе успешно.', 'cleanup_failed_body' => 'Възникна грешка при почистването на резервните копия на :application_name', 'cleanup_successful_subject' => 'Почистването на архивите на :application_name е успешно', 'cleanup_successful_subject_title' => 'Почистването на резервните копия е успешно!', 'cleanup_successful_body' => 'Почистването на резервни копия на :application_name на диска с име :disk_name беше успешно.', 'healthy_backup_found_subject' => 'Резервните копия за :application_name на диск :disk_name са здрави', 'healthy_backup_found_subject_title' => 'Резервните копия за :application_name са здрави', 'healthy_backup_found_body' => 'Резервните копия за :application_name се считат за здрави. Добра работа!', 'unhealthy_backup_found_subject' => 'Важно: Резервните копия за :application_name не са здрави', 'unhealthy_backup_found_subject_title' => 'Важно: Резервните копия за :application_name не са здрави. :проблем', 'unhealthy_backup_found_body' => 'Резервните копия за :application_name на диск :disk_name не са здрави.', 'unhealthy_backup_found_not_reachable' => 'Дестинацията за резервни копия не може да бъде достигната. :грешка', 'unhealthy_backup_found_empty' => 'Изобщо няма резервни копия на това приложение.', 'unhealthy_backup_found_old' => 'Последното резервно копие, направено на :date, се счита за твърде старо.', 'unhealthy_backup_found_unknown' => 'За съжаление не може да се определи точна причина.', 'unhealthy_backup_found_full' => 'Резервните копия използват твърде много място за съхранение. Текущото използване е :disk_usage, което е по-високо от разрешеното ограничение на :disk_limit.', 'no_backups_info' => 'Все още не са правени резервни копия', 'application_name' => 'Име на приложението', 'backup_name' => 'Име на резервно копие', 'disk' => 'Диск', 'newest_backup_size' => 'Най-новият размер на резервно копие', 'number_of_backups' => 'Брой резервни копия', 'total_storage_used' => 'Общо използвано дисково пространство', 'newest_backup_date' => 'Най-нова дата на резервно копие', 'oldest_backup_date' => 'Най-старата дата на резервно копие', ]; ================================================ FILE: lang/vendor/backup/bn/notifications.php ================================================ 'এক্সসেপশন বার্তা: :message', 'exception_trace' => 'এক্সসেপশন ট্রেস: :trace', 'exception_message_title' => 'এক্সসেপশন message', 'exception_trace_title' => 'এক্সসেপশন ট্রেস', 'backup_failed_subject' => ':application_name এর ব্যাকআপ ব্যর্থ হয়েছে।', 'backup_failed_body' => 'গুরুত্বপূর্ণঃ :application_name ব্যাক আপ করার সময় একটি ত্রুটি ঘটেছে।', 'backup_successful_subject' => ':application_name এর নতুন ব্যাকআপ সফল হয়েছে।', 'backup_successful_subject_title' => 'নতুন ব্যাকআপ সফল হয়েছে!', 'backup_successful_body' => 'খুশির খবর, :application_name এর নতুন ব্যাকআপ :disk_name ডিস্কে সফলভাবে তৈরি হয়েছে।', 'cleanup_failed_subject' => ':application_name ব্যাকআপগুলি সাফ করতে ব্যর্থ হয়েছে।', 'cleanup_failed_body' => ':application_name ব্যাকআপগুলি সাফ করার সময় একটি ত্রুটি ঘটেছে।', 'cleanup_successful_subject' => ':application_name এর ব্যাকআপগুলি সফলভাবে সাফ করা হয়েছে।', 'cleanup_successful_subject_title' => 'ব্যাকআপগুলি সফলভাবে সাফ করা হয়েছে!', 'cleanup_successful_body' => ':application_name এর ব্যাকআপগুলি :disk_name ডিস্ক থেকে সফলভাবে সাফ করা হয়েছে।', 'healthy_backup_found_subject' => ':application_name এর ব্যাকআপগুলি :disk_name ডিস্কে স্বাস্থ্যকর অবস্থায় আছে।', 'healthy_backup_found_subject_title' => ':application_name এর ব্যাকআপগুলি স্বাস্থ্যকর অবস্থায় আছে।', 'healthy_backup_found_body' => ':application_name এর ব্যাকআপগুলি স্বাস্থ্যকর বিবেচনা করা হচ্ছে। Good job!', 'unhealthy_backup_found_subject' => 'গুরুত্বপূর্ণঃ :application_name এর ব্যাকআপগুলি অস্বাস্থ্যকর অবস্থায় আছে।', 'unhealthy_backup_found_subject_title' => 'গুরুত্বপূর্ণঃ :application_name এর ব্যাকআপগুলি অস্বাস্থ্যকর অবস্থায় আছে। :problem', 'unhealthy_backup_found_body' => ':disk_name ডিস্কের :application_name এর ব্যাকআপগুলি অস্বাস্থ্যকর অবস্থায় আছে।', 'unhealthy_backup_found_not_reachable' => 'ব্যাকআপ গন্তব্যে পৌঁছানো যায় নি। :error', 'unhealthy_backup_found_empty' => 'এই অ্যাপ্লিকেশনটির কোনও ব্যাকআপ নেই।', 'unhealthy_backup_found_old' => 'সর্বশেষ ব্যাকআপ যেটি :date এই তারিখে করা হয়েছে, সেটি খুব পুরানো।', 'unhealthy_backup_found_unknown' => 'দুঃখিত, সঠিক কারণ নির্ধারণ করা সম্ভব হয়নি।', 'unhealthy_backup_found_full' => 'ব্যাকআপগুলি অতিরিক্ত স্টোরেজ ব্যবহার করছে। বর্তমান ব্যবহারের পরিমান :disk_usage যা অনুমোদিত সীমা :disk_limit এর বেশি।', 'no_backups_info' => 'কোনো ব্যাকআপ এখনও তৈরি হয়নি', 'application_name' => 'আবেদনের নাম', 'backup_name' => 'ব্যাকআপের নাম', 'disk' => 'ডিস্ক', 'newest_backup_size' => 'নতুন ব্যাকআপ আকার', 'number_of_backups' => 'ব্যাকআপের সংখ্যা', 'total_storage_used' => 'ব্যবহৃত মোট সঞ্চয়স্থান', 'newest_backup_date' => 'নতুন ব্যাকআপের তারিখ', 'oldest_backup_date' => 'পুরানো ব্যাকআপের তারিখ', ]; ================================================ FILE: lang/vendor/backup/cs/notifications.php ================================================ 'Zpráva výjimky: :message', 'exception_trace' => 'Stopa výjimky: :trace', 'exception_message_title' => 'Zpráva výjimky', 'exception_trace_title' => 'Stopa výjimky', 'backup_failed_subject' => 'Záloha :application_name neuspěla', 'backup_failed_body' => 'Důležité: Při záloze :application_name se vyskytla chyba', 'backup_successful_subject' => 'Úspěšná nová záloha :application_name', 'backup_successful_subject_title' => 'Úspěšná nová záloha!', 'backup_successful_body' => 'Dobrá zpráva, na disku jménem :disk_name byla úspěšně vytvořena nová záloha :application_name.', 'cleanup_failed_subject' => 'Vyčištění záloh :application_name neuspělo.', 'cleanup_failed_body' => 'Při vyčištění záloh :application_name se vyskytla chyba', 'cleanup_successful_subject' => 'Vyčištění záloh :application_name úspěšné', 'cleanup_successful_subject_title' => 'Vyčištění záloh bylo úspěšné!', 'cleanup_successful_body' => 'Vyčištění záloh :application_name na disku jménem :disk_name bylo úspěšné.', 'healthy_backup_found_subject' => 'Zálohy pro :application_name na disku :disk_name jsou zdravé', 'healthy_backup_found_subject_title' => 'Zálohy pro :application_name jsou zdravé', 'healthy_backup_found_body' => 'Zálohy pro :application_name jsou považovány za zdravé. Dobrá práce!', 'unhealthy_backup_found_subject' => 'Důležité: Zálohy pro :application_name jsou nezdravé', 'unhealthy_backup_found_subject_title' => 'Důležité: Zálohy pro :application_name jsou nezdravé. :problem', 'unhealthy_backup_found_body' => 'Zálohy pro :application_name na disku :disk_name Jsou nezdravé.', 'unhealthy_backup_found_not_reachable' => 'Nelze se dostat k cíli zálohy. :error', 'unhealthy_backup_found_empty' => 'Tato aplikace nemá vůbec žádné zálohy.', 'unhealthy_backup_found_old' => 'Poslední záloha vytvořená dne :date je považována za příliš starou.', 'unhealthy_backup_found_unknown' => 'Omlouváme se, nemůžeme určit přesný důvod.', 'unhealthy_backup_found_full' => 'Zálohy zabírají příliš mnoho místa na disku. Aktuální využití disku je :disk_usage, což je vyšší než povolený limit :disk_limit.', ]; ================================================ FILE: lang/vendor/backup/da/notifications.php ================================================ 'Fejlbesked: :message', 'exception_trace' => 'Fejl trace: :trace', 'exception_message_title' => 'Fejlbesked', 'exception_trace_title' => 'Fejl trace', 'backup_failed_subject' => 'Backup af :application_name fejlede', 'backup_failed_body' => 'Vigtigt: Der skete en fejl under backup af :application_name', 'backup_successful_subject' => 'Ny backup af :application_name oprettet', 'backup_successful_subject_title' => 'Ny backup!', 'backup_successful_body' => 'Gode nyheder - der blev oprettet en ny backup af :application_name på disken :disk_name.', 'cleanup_failed_subject' => 'Oprydning af backups for :application_name fejlede.', 'cleanup_failed_body' => 'Der skete en fejl under oprydning af backups for :application_name', 'cleanup_successful_subject' => 'Oprydning af backups for :application_name gennemført', 'cleanup_successful_subject_title' => 'Backup oprydning gennemført!', 'cleanup_successful_body' => 'Oprydningen af backups for :application_name på disken :disk_name er gennemført.', 'healthy_backup_found_subject' => 'Alle backups for :application_name på disken :disk_name er OK', 'healthy_backup_found_subject_title' => 'Alle backups for :application_name er OK', 'healthy_backup_found_body' => 'Alle backups for :application_name er ok. Godt gået!', 'unhealthy_backup_found_subject' => 'Vigtigt: Backups for :application_name fejlbehæftede', 'unhealthy_backup_found_subject_title' => 'Vigtigt: Backups for :application_name er fejlbehæftede. :problem', 'unhealthy_backup_found_body' => 'Backups for :application_name på disken :disk_name er fejlbehæftede.', 'unhealthy_backup_found_not_reachable' => 'Backup destinationen kunne ikke findes. :error', 'unhealthy_backup_found_empty' => 'Denne applikation har ingen backups overhovedet.', 'unhealthy_backup_found_old' => 'Den seneste backup fra :date er for gammel.', 'unhealthy_backup_found_unknown' => 'Beklager, en præcis årsag kunne ikke findes.', 'unhealthy_backup_found_full' => 'Backups bruger for meget plads. Nuværende disk forbrug er :disk_usage, hvilket er mere end den tilladte grænse på :disk_limit.', ]; ================================================ FILE: lang/vendor/backup/de/notifications.php ================================================ 'Fehlermeldung: :message', 'exception_trace' => 'Fehlerverfolgung: :trace', 'exception_message_title' => 'Fehlermeldung', 'exception_trace_title' => 'Fehlerverfolgung', 'backup_failed_subject' => 'Backup von :application_name konnte nicht erstellt werden', 'backup_failed_body' => 'Wichtig: Beim Backup von :application_name ist ein Fehler aufgetreten', 'backup_successful_subject' => 'Erfolgreiches neues Backup von :application_name', 'backup_successful_subject_title' => 'Erfolgreiches neues Backup!', 'backup_successful_body' => 'Gute Nachrichten, ein neues Backup von :application_name wurde erfolgreich erstellt und in :disk_name gepeichert.', 'cleanup_failed_subject' => 'Aufräumen der Backups von :application_name schlug fehl.', 'cleanup_failed_body' => 'Beim aufräumen der Backups von :application_name ist ein Fehler aufgetreten', 'cleanup_successful_subject' => 'Aufräumen der Backups von :application_name backups erfolgreich', 'cleanup_successful_subject_title' => 'Aufräumen der Backups erfolgreich!', 'cleanup_successful_body' => 'Aufräumen der Backups von :application_name in :disk_name war erfolgreich.', 'healthy_backup_found_subject' => 'Die Backups von :application_name in :disk_name sind gesund', 'healthy_backup_found_subject_title' => 'Die Backups von :application_name sind Gesund', 'healthy_backup_found_body' => 'Die Backups von :application_name wurden als gesund eingestuft. Gute Arbeit!', 'unhealthy_backup_found_subject' => 'Wichtig: Die Backups für :application_name sind nicht gesund', 'unhealthy_backup_found_subject_title' => 'Wichtig: Die Backups für :application_name sind ungesund. :problem', 'unhealthy_backup_found_body' => 'Die Backups für :application_name in :disk_name sind ungesund.', 'unhealthy_backup_found_not_reachable' => 'Das Backup Ziel konnte nicht erreicht werden. :error', 'unhealthy_backup_found_empty' => 'Es gibt für die Anwendung noch gar keine Backups.', 'unhealthy_backup_found_old' => 'Das letzte Backup am :date ist zu lange her.', 'unhealthy_backup_found_unknown' => 'Sorry, ein genauer Grund konnte nicht gefunden werden.', 'unhealthy_backup_found_full' => 'Die Backups verbrauchen zu viel Platz. Aktuell wird :disk_usage belegt, dass ist höher als das erlaubte Limit von :disk_limit.', ]; ================================================ FILE: lang/vendor/backup/en/notifications.php ================================================ 'Exception message: :message', 'exception_trace' => 'Exception trace: :trace', 'exception_message_title' => 'Exception message', 'exception_trace_title' => 'Exception trace', 'backup_failed_subject' => 'Failed backup of :application_name', 'backup_failed_body' => 'Important: An error occurred while backing up :application_name', 'backup_successful_subject' => 'Successful new backup of :application_name', 'backup_successful_subject_title' => 'Successful new backup!', 'backup_successful_body' => 'Great news, a new backup of :application_name was successfully created on the disk named :disk_name.', 'cleanup_failed_subject' => 'Cleaning up the backups of :application_name failed.', 'cleanup_failed_body' => 'An error occurred while cleaning up the backups of :application_name', 'cleanup_successful_subject' => 'Clean up of :application_name backups successful', 'cleanup_successful_subject_title' => 'Clean up of backups successful!', 'cleanup_successful_body' => 'The clean up of the :application_name backups on the disk named :disk_name was successful.', 'healthy_backup_found_subject' => 'The backups for :application_name on disk :disk_name are healthy', 'healthy_backup_found_subject_title' => 'The backups for :application_name are healthy', 'healthy_backup_found_body' => 'The backups for :application_name are considered healthy. Good job!', 'unhealthy_backup_found_subject' => 'Important: The backups for :application_name are unhealthy', 'unhealthy_backup_found_subject_title' => 'Important: The backups for :application_name are unhealthy. :problem', 'unhealthy_backup_found_body' => 'The backups for :application_name on disk :disk_name are unhealthy.', 'unhealthy_backup_found_not_reachable' => 'The backup destination cannot be reached. :error', 'unhealthy_backup_found_empty' => 'There are no backups of this application at all.', 'unhealthy_backup_found_old' => 'The latest backup made on :date is considered too old.', 'unhealthy_backup_found_unknown' => 'Sorry, an exact reason cannot be determined.', 'unhealthy_backup_found_full' => 'The backups are using too much storage. Current usage is :disk_usage which is higher than the allowed limit of :disk_limit.', ]; ================================================ FILE: lang/vendor/backup/es/notifications.php ================================================ 'Mensaje de la excepción: :message', 'exception_trace' => 'Traza de la excepción: :trace', 'exception_message_title' => 'Mensaje de la excepción', 'exception_trace_title' => 'Traza de la excepción', 'backup_failed_subject' => 'Copia de seguridad de :application_name fallida', 'backup_failed_body' => 'Importante: Ocurrió un error al realizar la copia de seguridad de :application_name', 'backup_successful_subject' => 'Se completó con éxito la copia de seguridad de :application_name', 'backup_successful_subject_title' => '¡Nueva copia de seguridad creada con éxito!', 'backup_successful_body' => 'Buenas noticias, una nueva copia de seguridad de :application_name fue creada con éxito en el disco llamado :disk_name.', 'cleanup_failed_subject' => 'La limpieza de copias de seguridad de :application_name falló.', 'cleanup_failed_body' => 'Ocurrió un error mientras se realizaba la limpieza de copias de seguridad de :application_name', 'cleanup_successful_subject' => 'La limpieza de copias de seguridad de :application_name se completó con éxito', 'cleanup_successful_subject_title' => '!Limpieza de copias de seguridad completada con éxito!', 'cleanup_successful_body' => 'La limpieza de copias de seguridad de :application_name en el disco llamado :disk_name se completo con éxito.', 'healthy_backup_found_subject' => 'Las copias de seguridad de :application_name en el disco :disk_name están en buen estado', 'healthy_backup_found_subject_title' => 'Las copias de seguridad de :application_name están en buen estado', 'healthy_backup_found_body' => 'Las copias de seguridad de :application_name se consideran en buen estado. ¡Buen trabajo!', 'unhealthy_backup_found_subject' => 'Importante: Las copias de seguridad de :application_name están en mal estado', 'unhealthy_backup_found_subject_title' => 'Importante: Las copias de seguridad de :application_name están en mal estado. :problem', 'unhealthy_backup_found_body' => 'Las copias de seguridad de :application_name en el disco :disk_name están en mal estado.', 'unhealthy_backup_found_not_reachable' => 'No se puede acceder al destino de la copia de seguridad. :error', 'unhealthy_backup_found_empty' => 'No existe ninguna copia de seguridad de esta aplicación.', 'unhealthy_backup_found_old' => 'La última copia de seguriad hecha en :date es demasiado antigua.', 'unhealthy_backup_found_unknown' => 'Lo siento, no es posible determinar la razón exacta.', 'unhealthy_backup_found_full' => 'Las copias de seguridad están ocupando demasiado espacio. El espacio utilizado actualmente es :disk_usage el cual es mayor que el límite permitido de :disk_limit.', ]; ================================================ FILE: lang/vendor/backup/fa/notifications.php ================================================ 'پیغام خطا: :message', 'exception_trace' => 'جزییات خطا: :trace', 'exception_message_title' => 'پیغام خطا', 'exception_trace_title' => 'جزییات خطا', 'backup_failed_subject' => 'پشتیبان‌گیری :application_name با خطا مواجه شد.', 'backup_failed_body' => 'پیغام مهم: هنگام پشتیبان‌گیری از :application_name خطایی رخ داده است. ', 'backup_successful_subject' => 'نسخه پشتیبان جدید :application_name با موفقیت ساخته شد.', 'backup_successful_subject_title' => 'پشتیبان‌گیری موفق!', 'backup_successful_body' => 'خبر خوب, به تازگی نسخه پشتیبان :application_name بر روی دیسک :disk_name با موفقیت ساخته شد. ', 'cleanup_failed_subject' => 'پاک‌‌سازی نسخه پشتیبان :application_name انجام نشد.', 'cleanup_failed_body' => 'هنگام پاک‌سازی نسخه پشتیبان :application_name خطایی رخ داده است.', 'cleanup_successful_subject' => 'پاک‌سازی نسخه پشتیبان :application_name با موفقیت انجام شد.', 'cleanup_successful_subject_title' => 'پاک‌سازی نسخه پشتیبان!', 'cleanup_successful_body' => 'پاک‌سازی نسخه پشتیبان :application_name بر روی دیسک :disk_name با موفقیت انجام شد.', 'healthy_backup_found_subject' => 'نسخه پشتیبان :application_name بر روی دیسک :disk_name سالم بود.', 'healthy_backup_found_subject_title' => 'نسخه پشتیبان :application_name سالم بود.', 'healthy_backup_found_body' => 'نسخه پشتیبان :application_name به نظر سالم میاد. دمت گرم!', 'unhealthy_backup_found_subject' => 'خبر مهم: نسخه پشتیبان :application_name سالم نبود.', 'unhealthy_backup_found_subject_title' => 'خبر مهم: نسخه پشتیبان :application_name سالم نبود. :problem', 'unhealthy_backup_found_body' => 'نسخه پشتیبان :application_name بر روی دیسک :disk_name سالم نبود.', 'unhealthy_backup_found_not_reachable' => 'مقصد پشتیبان‌گیری در دسترس نبود. :error', 'unhealthy_backup_found_empty' => 'برای این برنامه هیچ نسخه پشتیبانی وجود ندارد.', 'unhealthy_backup_found_old' => 'آخرین نسخه پشتیبان برای تاریخ :date است. که به نظر خیلی قدیمی میاد. ', 'unhealthy_backup_found_unknown' => 'متاسفانه دلیل دقیق مشخص نشده است.', 'unhealthy_backup_found_full' => 'نسخه‌های پشتیبانی که تهیه کرده اید حجم زیادی اشغال کرده اند. میزان دیسک استفاده شده :disk_usage است که از میزان مجاز :disk_limit فراتر رفته است. ', ]; ================================================ FILE: lang/vendor/backup/fi/notifications.php ================================================ 'Virheilmoitus: :message', 'exception_trace' => 'Virhe, jäljitys: :trace', 'exception_message_title' => 'Virheilmoitus', 'exception_trace_title' => 'Virheen jäljitys', 'backup_failed_subject' => ':application_name varmuuskopiointi epäonnistui', 'backup_failed_body' => 'HUOM!: :application_name varmuuskoipionnissa tapahtui virhe', 'backup_successful_subject' => ':application_name varmuuskopioitu onnistuneesti', 'backup_successful_subject_title' => 'Uusi varmuuskopio!', 'backup_successful_body' => 'Hyviä uutisia! :application_name on varmuuskopioitu levylle :disk_name.', 'cleanup_failed_subject' => ':application_name varmuuskopioiden poistaminen epäonnistui.', 'cleanup_failed_body' => ':application_name varmuuskopioiden poistamisessa tapahtui virhe.', 'cleanup_successful_subject' => ':application_name varmuuskopiot poistettu onnistuneesti', 'cleanup_successful_subject_title' => 'Varmuuskopiot poistettu onnistuneesti!', 'cleanup_successful_body' => ':application_name varmuuskopiot poistettu onnistuneesti levyltä :disk_name.', 'healthy_backup_found_subject' => ':application_name varmuuskopiot levyllä :disk_name ovat kunnossa', 'healthy_backup_found_subject_title' => ':application_name varmuuskopiot ovat kunnossa', 'healthy_backup_found_body' => ':application_name varmuuskopiot ovat kunnossa. Hieno homma!', 'unhealthy_backup_found_subject' => 'HUOM!: :application_name varmuuskopiot ovat vialliset', 'unhealthy_backup_found_subject_title' => 'HUOM!: :application_name varmuuskopiot ovat vialliset. :problem', 'unhealthy_backup_found_body' => ':application_name varmuuskopiot levyllä :disk_name ovat vialliset.', 'unhealthy_backup_found_not_reachable' => 'Varmuuskopioiden kohdekansio ei ole saatavilla. :error', 'unhealthy_backup_found_empty' => 'Tästä sovelluksesta ei ole varmuuskopioita.', 'unhealthy_backup_found_old' => 'Viimeisin varmuuskopio, luotu :date, on liian vanha.', 'unhealthy_backup_found_unknown' => 'Virhe, tarkempaa tietoa syystä ei valitettavasti ole saatavilla.', 'unhealthy_backup_found_full' => 'Varmuuskopiot vievät liikaa levytilaa. Tällä hetkellä käytössä :disk_usage, mikä on suurempi kuin sallittu tilavuus (:disk_limit).', 'no_backups_info' => 'Varmuuskopioita ei vielä tehty', 'application_name' => 'Sovelluksen nimi', 'backup_name' => 'Varmuuskopion nimi', 'disk' => 'Levy', 'newest_backup_size' => 'Uusin varmuuskopion koko', 'number_of_backups' => 'Varmuuskopioiden määrä', 'total_storage_used' => 'Käytetty tallennustila yhteensä', 'newest_backup_date' => 'Uusin varmuuskopion koko', 'oldest_backup_date' => 'Vanhin varmuuskopion koko', ]; ================================================ FILE: lang/vendor/backup/fr/notifications.php ================================================ 'Message de l\'exception : :message', 'exception_trace' => 'Trace de l\'exception : :trace', 'exception_message_title' => 'Message de l\'exception', 'exception_trace_title' => 'Trace de l\'exception', 'backup_failed_subject' => 'Échec de la sauvegarde de :application_name', 'backup_failed_body' => 'Important : Une erreur est survenue lors de la sauvegarde de :application_name', 'backup_successful_subject' => 'Succès de la sauvegarde de :application_name', 'backup_successful_subject_title' => 'Sauvegarde créée avec succès !', 'backup_successful_body' => 'Bonne nouvelle, une nouvelle sauvegarde de :application_name a été créée avec succès sur le disque nommé :disk_name.', 'cleanup_failed_subject' => 'Le nettoyage des sauvegardes de :application_name a echoué.', 'cleanup_failed_body' => 'Une erreur est survenue lors du nettoyage des sauvegardes de :application_name', 'cleanup_successful_subject' => 'Succès du nettoyage des sauvegardes de :application_name', 'cleanup_successful_subject_title' => 'Sauvegardes nettoyées avec succès !', 'cleanup_successful_body' => 'Le nettoyage des sauvegardes de :application_name sur le disque nommé :disk_name a été effectué avec succès.', 'healthy_backup_found_subject' => 'Les sauvegardes pour :application_name sur le disque :disk_name sont saines', 'healthy_backup_found_subject_title' => 'Les sauvegardes pour :application_name sont saines', 'healthy_backup_found_body' => 'Les sauvegardes pour :application_name sont considérées saines. Bon travail !', 'unhealthy_backup_found_subject' => 'Important : Les sauvegardes pour :application_name sont corrompues', 'unhealthy_backup_found_subject_title' => 'Important : Les sauvegardes pour :application_name sont corrompues. :problem', 'unhealthy_backup_found_body' => 'Les sauvegardes pour :application_name sur le disque :disk_name sont corrompues.', 'unhealthy_backup_found_not_reachable' => 'La destination de la sauvegarde n\'est pas accessible. :error', 'unhealthy_backup_found_empty' => 'Il n\'y a aucune sauvegarde pour cette application.', 'unhealthy_backup_found_old' => 'La dernière sauvegarde du :date est considérée trop vieille.', 'unhealthy_backup_found_unknown' => 'Désolé, une raison exacte ne peut être déterminée.', 'unhealthy_backup_found_full' => 'Les sauvegardes utilisent trop d\'espace disque. L\'utilisation actuelle est de :disk_usage alors que la limite autorisée est de :disk_limit.', ]; ================================================ FILE: lang/vendor/backup/hi/notifications.php ================================================ 'गलती संदेश: :message', 'exception_trace' => 'गलती निशान: :trace', 'exception_message_title' => 'गलती संदेश', 'exception_trace_title' => 'गलती निशान', 'backup_failed_subject' => ':application_name का बैकअप असफल रहा', 'backup_failed_body' => 'जरूरी सुचना: :application_name का बैकअप लेते समय असफल रहे', 'backup_successful_subject' => ':application_name का बैकअप सफल रहा', 'backup_successful_subject_title' => 'बैकअप सफल रहा!', 'backup_successful_body' => 'खुशखबरी, :application_name का बैकअप :disk_name पर संग्रहित करने मे सफल रहे.', 'cleanup_failed_subject' => ':application_name के बैकअप की सफाई असफल रही.', 'cleanup_failed_body' => ':application_name के बैकअप की सफाई करते समय कुछ बाधा आयी है.', 'cleanup_successful_subject' => ':application_name के बैकअप की सफाई सफल रही', 'cleanup_successful_subject_title' => 'बैकअप की सफाई सफल रही!', 'cleanup_successful_body' => ':application_name का बैकअप जो :disk_name नाम की डिस्क पर संग्रहित है, उसकी सफाई सफल रही.', 'healthy_backup_found_subject' => ':disk_name नाम की डिस्क पर संग्रहित :application_name के बैकअप स्वस्थ है', 'healthy_backup_found_subject_title' => ':application_name के सभी बैकअप स्वस्थ है', 'healthy_backup_found_body' => 'बहुत बढ़िया! :application_name के सभी बैकअप स्वस्थ है.', 'unhealthy_backup_found_subject' => 'जरूरी सुचना : :application_name के बैकअप अस्वस्थ है', 'unhealthy_backup_found_subject_title' => 'जरूरी सुचना : :application_name के बैकअप :problem के बजेसे अस्वस्थ है', 'unhealthy_backup_found_body' => ':disk_name नाम की डिस्क पर संग्रहित :application_name के बैकअप अस्वस्थ है', 'unhealthy_backup_found_not_reachable' => ':error के बजेसे बैकअप की मंजिल तक पोहोच नहीं सकते.', 'unhealthy_backup_found_empty' => 'इस एप्लीकेशन का कोई भी बैकअप नहीं है.', 'unhealthy_backup_found_old' => 'हालहीमें :date को लिया हुआ बैकअप बहुत पुराना है.', 'unhealthy_backup_found_unknown' => 'माफ़ कीजिये, सही कारण निर्धारित नहीं कर सकते.', 'unhealthy_backup_found_full' => 'सभी बैकअप बहुत ज्यादा जगह का उपयोग कर रहे है. फ़िलहाल सभी बैकअप :disk_usage जगह का उपयोग कर रहे है, जो की :disk_limit अनुमति सीमा से अधिक का है.', ]; ================================================ FILE: lang/vendor/backup/id/notifications.php ================================================ 'Pesan pengecualian: :message', 'exception_trace' => 'Jejak pengecualian: :trace', 'exception_message_title' => 'Pesan pengecualian', 'exception_trace_title' => 'Jejak pengecualian', 'backup_failed_subject' => 'Gagal backup :application_name', 'backup_failed_body' => 'Penting: Sebuah error terjadi ketika membackup :application_name', 'backup_successful_subject' => 'Backup baru sukses dari :application_name', 'backup_successful_subject_title' => 'Backup baru sukses!', 'backup_successful_body' => 'Kabar baik, sebuah backup baru dari :application_name sukses dibuat pada disk bernama :disk_name.', 'cleanup_failed_subject' => 'Membersihkan backup dari :application_name yang gagal.', 'cleanup_failed_body' => 'Sebuah error teradi ketika membersihkan backup dari :application_name', 'cleanup_successful_subject' => 'Sukses membersihkan backup :application_name', 'cleanup_successful_subject_title' => 'Sukses membersihkan backup!', 'cleanup_successful_body' => 'Pembersihan backup :application_name pada disk bernama :disk_name telah sukses.', 'healthy_backup_found_subject' => 'Backup untuk :application_name pada disk :disk_name sehat', 'healthy_backup_found_subject_title' => 'Backup untuk :application_name sehat', 'healthy_backup_found_body' => 'Backup untuk :application_name dipertimbangkan sehat. Kerja bagus!', 'unhealthy_backup_found_subject' => 'Penting: Backup untuk :application_name tidak sehat', 'unhealthy_backup_found_subject_title' => 'Penting: Backup untuk :application_name tidak sehat. :problem', 'unhealthy_backup_found_body' => 'Backup untuk :application_name pada disk :disk_name tidak sehat.', 'unhealthy_backup_found_not_reachable' => 'Tujuan backup tidak dapat terjangkau. :error', 'unhealthy_backup_found_empty' => 'Tidak ada backup pada aplikasi ini sama sekali.', 'unhealthy_backup_found_old' => 'Backup terakhir dibuat pada :date dimana dipertimbahkan sudah sangat lama.', 'unhealthy_backup_found_unknown' => 'Maaf, sebuah alasan persisnya tidak dapat ditentukan.', 'unhealthy_backup_found_full' => 'Backup menggunakan terlalu banyak kapasitas penyimpanan. Penggunaan terkini adalah :disk_usage dimana lebih besar dari batas yang diperbolehkan yaitu :disk_limit.', ]; ================================================ FILE: lang/vendor/backup/it/notifications.php ================================================ 'Messaggio dell\'eccezione: :message', 'exception_trace' => 'Traccia dell\'eccezione: :trace', 'exception_message_title' => 'Messaggio dell\'eccezione', 'exception_trace_title' => 'Traccia dell\'eccezione', 'backup_failed_subject' => 'Fallito il backup di :application_name', 'backup_failed_body' => 'Importante: Si è verificato un errore durante il backup di :application_name', 'backup_successful_subject' => 'Creato nuovo backup di :application_name', 'backup_successful_subject_title' => 'Nuovo backup creato!', 'backup_successful_body' => 'Grande notizia, un nuovo backup di :application_name è stato creato con successo sul disco :disk_name.', 'cleanup_failed_subject' => 'Pulizia dei backup di :application_name fallita.', 'cleanup_failed_body' => 'Si è verificato un errore durante la pulizia dei backup di :application_name', 'cleanup_successful_subject' => 'Pulizia dei backup di :application_name avvenuta con successo', 'cleanup_successful_subject_title' => 'Pulizia dei backup avvenuta con successo!', 'cleanup_successful_body' => 'La pulizia dei backup di :application_name sul disco :disk_name è avvenuta con successo.', 'healthy_backup_found_subject' => 'I backup per :application_name sul disco :disk_name sono sani', 'healthy_backup_found_subject_title' => 'I backup per :application_name sono sani', 'healthy_backup_found_body' => 'I backup per :application_name sono considerati sani. Bel Lavoro!', 'unhealthy_backup_found_subject' => 'Importante: i backup per :application_name sono corrotti', 'unhealthy_backup_found_subject_title' => 'Importante: i backup per :application_name sono corrotti. :problem', 'unhealthy_backup_found_body' => 'I backup per :application_name sul disco :disk_name sono corrotti.', 'unhealthy_backup_found_not_reachable' => 'Impossibile raggiungere la destinazione di backup. :error', 'unhealthy_backup_found_empty' => 'Non esiste alcun backup di questa applicazione.', 'unhealthy_backup_found_old' => 'L\'ultimo backup fatto il :date è considerato troppo vecchio.', 'unhealthy_backup_found_unknown' => 'Spiacenti, non è possibile determinare una ragione esatta.', 'unhealthy_backup_found_full' => 'I backup utilizzano troppa memoria. L\'utilizzo corrente è :disk_usage che è superiore al limite consentito di :disk_limit.', ]; ================================================ FILE: lang/vendor/backup/ja/notifications.php ================================================ '例外のメッセージ: :message', 'exception_trace' => '例外の追跡: :trace', 'exception_message_title' => '例外のメッセージ', 'exception_trace_title' => '例外の追跡', 'backup_failed_subject' => ':application_name のバックアップに失敗しました。', 'backup_failed_body' => '重要: :application_name のバックアップ中にエラーが発生しました。', 'backup_successful_subject' => ':application_name のバックアップに成功しました。', 'backup_successful_subject_title' => 'バックアップに成功しました!', 'backup_successful_body' => '朗報です。ディスク :disk_name へ :application_name のバックアップが成功しました。', 'cleanup_failed_subject' => ':application_name のバックアップ削除に失敗しました。', 'cleanup_failed_body' => ':application_name のバックアップ削除中にエラーが発生しました。', 'cleanup_successful_subject' => ':application_name のバックアップ削除に成功しました。', 'cleanup_successful_subject_title' => 'バックアップ削除に成功しました!', 'cleanup_successful_body' => 'ディスク :disk_name に保存された :application_name のバックアップ削除に成功しました。', 'healthy_backup_found_subject' => 'ディスク :disk_name への :application_name のバックアップは正常です。', 'healthy_backup_found_subject_title' => ':application_name のバックアップは正常です。', 'healthy_backup_found_body' => ':application_name へのバックアップは正常です。いい仕事してますね!', 'unhealthy_backup_found_subject' => '重要: :application_name のバックアップに異常があります。', 'unhealthy_backup_found_subject_title' => '重要: :application_name のバックアップに異常があります。 :problem', 'unhealthy_backup_found_body' => ':disk_name への :application_name のバックアップに異常があります。', 'unhealthy_backup_found_not_reachable' => 'バックアップ先にアクセスできませんでした。 :error', 'unhealthy_backup_found_empty' => 'このアプリケーションのバックアップは見つかりませんでした。', 'unhealthy_backup_found_old' => ':date に保存された直近のバックアップが古すぎます。', 'unhealthy_backup_found_unknown' => '申し訳ございません。予期せぬエラーです。', 'unhealthy_backup_found_full' => 'バックアップがディスク容量を圧迫しています。現在の使用量 :disk_usage は、許可された限界値 :disk_limit を超えています。', 'no_backups_info' => 'バックアップはまだ作成されていません', 'application_name' => 'アプリケーション名', 'backup_name' => 'バックアップ名', 'disk' => 'ディスク', 'newest_backup_size' => '最新のバックアップサイズ', 'number_of_backups' => 'バックアップ数', 'total_storage_used' => '使用された合計ストレージ', 'newest_backup_date' => '最新のバックアップ日時', 'oldest_backup_date' => '最も古いバックアップ日時', ]; ================================================ FILE: lang/vendor/backup/nl/notifications.php ================================================ 'Fout bericht: :message', 'exception_trace' => 'Fout trace: :trace', 'exception_message_title' => 'Fout bericht', 'exception_trace_title' => 'Fout trace', 'backup_failed_subject' => 'Back-up van :application_name mislukt', 'backup_failed_body' => 'Belangrijk: Er ging iets fout tijdens het maken van een back-up van :application_name', 'backup_successful_subject' => 'Succesvolle nieuwe back-up van :application_name', 'backup_successful_subject_title' => 'Succesvolle nieuwe back-up!', 'backup_successful_body' => 'Goed nieuws, een nieuwe back-up van :application_name was succesvol aangemaakt op de schijf genaamd :disk_name.', 'cleanup_failed_subject' => 'Het opschonen van de back-ups van :application_name is mislukt.', 'cleanup_failed_body' => 'Er ging iets fout tijdens het opschonen van de back-ups van :application_name', 'cleanup_successful_subject' => 'Opschonen van :application_name back-ups was succesvol.', 'cleanup_successful_subject_title' => 'Opschonen van back-ups was succesvol!', 'cleanup_successful_body' => 'Het opschonen van de :application_name back-ups op de schijf genaamd :disk_name was succesvol.', 'healthy_backup_found_subject' => 'De back-ups voor :application_name op schijf :disk_name zijn gezond', 'healthy_backup_found_subject_title' => 'De back-ups voor :application_name zijn gezond', 'healthy_backup_found_body' => 'De back-ups voor :application_name worden als gezond beschouwd. Goed gedaan!', 'unhealthy_backup_found_subject' => 'Belangrijk: De back-ups voor :application_name zijn niet meer gezond', 'unhealthy_backup_found_subject_title' => 'Belangrijk: De back-ups voor :application_name zijn niet gezond. :problem', 'unhealthy_backup_found_body' => 'De back-ups voor :application_name op schijf :disk_name zijn niet gezond.', 'unhealthy_backup_found_not_reachable' => 'De back-upbestemming kon niet worden bereikt. :error', 'unhealthy_backup_found_empty' => 'Er zijn geen back-ups van deze applicatie beschikbaar.', 'unhealthy_backup_found_old' => 'De laatste back-up gemaakt op :date is te oud.', 'unhealthy_backup_found_unknown' => 'Sorry, een exacte reden kon niet worden bepaald.', 'unhealthy_backup_found_full' => 'De back-ups gebruiken te veel opslagruimte. Momenteel wordt er :disk_usage gebruikt wat hoger is dan de toegestane limiet van :disk_limit.', ]; ================================================ FILE: lang/vendor/backup/no/notifications.php ================================================ 'Exception: :message', 'exception_trace' => 'Exception trace: :trace', 'exception_message_title' => 'Exception', 'exception_trace_title' => 'Exception trace', 'backup_failed_subject' => 'Backup feilet for :application_name', 'backup_failed_body' => 'Viktg: En feil oppstod under backing av :application_name', 'backup_successful_subject' => 'Gjennomført backup av :application_name', 'backup_successful_subject_title' => 'Gjennomført backup!', 'backup_successful_body' => 'Gode nyheter, en ny backup av :application_name ble opprettet på disken :disk_name.', 'cleanup_failed_subject' => 'Opprydding av backup for :application_name feilet.', 'cleanup_failed_body' => 'En feil oppstod under opprydding av backups for :application_name', 'cleanup_successful_subject' => 'Opprydding av backup for :application_name gjennomført', 'cleanup_successful_subject_title' => 'Opprydding av backup gjennomført!', 'cleanup_successful_body' => 'Oppryddingen av backup for :application_name på disken :disk_name har blitt gjennomført.', 'healthy_backup_found_subject' => 'Alle backups for :application_name på disken :disk_name er OK', 'healthy_backup_found_subject_title' => 'Alle backups for :application_name er OK', 'healthy_backup_found_body' => 'Alle backups for :application_name er ok. Godt jobba!', 'unhealthy_backup_found_subject' => 'Viktig: Backups for :application_name ikke OK', 'unhealthy_backup_found_subject_title' => 'Viktig: Backups for :application_name er ikke OK. :problem', 'unhealthy_backup_found_body' => 'Backups for :application_name på disken :disk_name er ikke OK.', 'unhealthy_backup_found_not_reachable' => 'Kunne ikke finne backup-destinasjonen. :error', 'unhealthy_backup_found_empty' => 'Denne applikasjonen mangler backups.', 'unhealthy_backup_found_old' => 'Den siste backupem fra :date er for gammel.', 'unhealthy_backup_found_unknown' => 'Beklager, kunne ikke finne nøyaktig årsak.', 'unhealthy_backup_found_full' => 'Backups bruker for mye lagringsplass. Nåværende diskbruk er :disk_usage, som er mer enn den tillatte grensen på :disk_limit.', 'no_backups_info' => 'Ingen sikkerhetskopier ble gjort ennå', 'application_name' => 'Programnavn', 'backup_name' => 'Navn på sikkerhetskopi', 'disk' => 'Disk', 'newest_backup_size' => 'Nyeste backup-størrelse', 'number_of_backups' => 'Antall sikkerhetskopier', 'total_storage_used' => 'Total lagring brukt', 'newest_backup_date' => 'Nyeste backup-størrelse', 'oldest_backup_date' => 'Eldste sikkerhetskopistørrelse', ]; ================================================ FILE: lang/vendor/backup/pl/notifications.php ================================================ 'Błąd: :message', 'exception_trace' => 'Zrzut błędu: :trace', 'exception_message_title' => 'Błąd', 'exception_trace_title' => 'Zrzut błędu', 'backup_failed_subject' => 'Tworzenie kopii zapasowej aplikacji :application_name nie powiodło się', 'backup_failed_body' => 'Ważne: Wystąpił błąd podczas tworzenia kopii zapasowej aplikacji :application_name', 'backup_successful_subject' => 'Pomyślnie utworzono kopię zapasową aplikacji :application_name', 'backup_successful_subject_title' => 'Nowa kopia zapasowa!', 'backup_successful_body' => 'Wspaniała wiadomość, nowa kopia zapasowa aplikacji :application_name została pomyślnie utworzona na dysku o nazwie :disk_name.', 'cleanup_failed_subject' => 'Czyszczenie kopii zapasowych aplikacji :application_name nie powiodło się.', 'cleanup_failed_body' => 'Wystąpił błąd podczas czyszczenia kopii zapasowej aplikacji :application_name', 'cleanup_successful_subject' => 'Kopie zapasowe aplikacji :application_name zostały pomyślnie wyczyszczone', 'cleanup_successful_subject_title' => 'Kopie zapasowe zostały pomyślnie wyczyszczone!', 'cleanup_successful_body' => 'Czyszczenie kopii zapasowych aplikacji :application_name na dysku :disk_name zakończone sukcecem.', 'healthy_backup_found_subject' => 'Kopie zapasowe aplikacji :application_name na dysku :disk_name są poprawne', 'healthy_backup_found_subject_title' => 'Kopie zapasowe aplikacji :application_name są poprawne', 'healthy_backup_found_body' => 'Kopie zapasowe aplikacji :application_name są poprawne. Dobra robota!', 'unhealthy_backup_found_subject' => 'Ważne: Kopie zapasowe aplikacji :application_name są niepoprawne', 'unhealthy_backup_found_subject_title' => 'Ważne: Kopie zapasowe aplikacji :application_name są niepoprawne. :problem', 'unhealthy_backup_found_body' => 'Kopie zapasowe aplikacji :application_name na dysku :disk_name są niepoprawne.', 'unhealthy_backup_found_not_reachable' => 'Miejsce docelowe kopii zapasowej nie jest osiągalne. :error', 'unhealthy_backup_found_empty' => 'W aplikacji nie ma żadnej kopii zapasowych tej aplikacji.', 'unhealthy_backup_found_old' => 'Ostatnia kopia zapasowa wykonania dnia :date jest zbyt stara.', 'unhealthy_backup_found_unknown' => 'Niestety, nie można ustalić dokładnego błędu.', 'unhealthy_backup_found_full' => 'Kopie zapasowe zajmują zbyt dużo miejsca. Obecne użycie dysku :disk_usage jest większe od ustalonego limitu :disk_limit.', ]; ================================================ FILE: lang/vendor/backup/pt/notifications.php ================================================ 'Exception message: :message', 'exception_trace' => 'Exception trace: :trace', 'exception_message_title' => 'Exception message', 'exception_trace_title' => 'Exception trace', 'backup_failed_subject' => 'Falha no backup da aplicação :application_name', 'backup_failed_body' => 'Importante: Ocorreu um erro ao executar o backup da aplicação :application_name', 'backup_successful_subject' => 'Backup realizado com sucesso: :application_name', 'backup_successful_subject_title' => 'Backup Realizado com Sucesso!', 'backup_successful_body' => 'Boas notícias, foi criado um novo backup no disco :disk_name referente à aplicação :application_name.', 'cleanup_failed_subject' => 'Falha na limpeza dos backups da aplicação :application_name.', 'cleanup_failed_body' => 'Ocorreu um erro ao executar a limpeza dos backups da aplicação :application_name', 'cleanup_successful_subject' => 'Limpeza dos backups da aplicação :application_name concluída!', 'cleanup_successful_subject_title' => 'Limpeza dos backups concluída!', 'cleanup_successful_body' => 'Concluída a limpeza dos backups da aplicação :application_name no disco :disk_name.', 'healthy_backup_found_subject' => 'Os backups da aplicação :application_name no disco :disk_name estão em dia', 'healthy_backup_found_subject_title' => 'Os backups da aplicação :application_name estão em dia', 'healthy_backup_found_body' => 'Os backups da aplicação :application_name estão em dia. Bom trabalho!', 'unhealthy_backup_found_subject' => 'Importante: Os backups da aplicação :application_name não estão em dia', 'unhealthy_backup_found_subject_title' => 'Importante: Os backups da aplicação :application_name não estão em dia. :problem', 'unhealthy_backup_found_body' => 'Os backups da aplicação :application_name no disco :disk_name não estão em dia.', 'unhealthy_backup_found_not_reachable' => 'O destino dos backups não pode ser alcançado. :error', 'unhealthy_backup_found_empty' => 'Não existem backups para essa aplicação.', 'unhealthy_backup_found_old' => 'O último backup realizado em :date é demasiado antigo.', 'unhealthy_backup_found_unknown' => 'Desculpe, impossível determinar a razão exata.', 'unhealthy_backup_found_full' => 'Os backups estão a utilizar demasiado espaço de armazenamento. A utilização atual é de :disk_usage, o que é maior que o limite permitido de :disk_limit.', 'no_backups_info' => 'Nenhum backup foi feito ainda', 'application_name' => 'Nome da Aplicação', 'backup_name' => 'Nome de backup', 'disk' => 'Disco', 'newest_backup_size' => 'Tamanho de backup mais recente', 'number_of_backups' => 'Número de backups', 'total_storage_used' => 'Armazenamento total usado', 'newest_backup_date' => 'Tamanho de backup mais recente', 'oldest_backup_date' => 'Tamanho de backup mais antigo', ]; ================================================ FILE: lang/vendor/backup/pt-BR/notifications.php ================================================ 'Exception message: :message', 'exception_trace' => 'Exception trace: :trace', 'exception_message_title' => 'Exception message', 'exception_trace_title' => 'Exception trace', 'backup_failed_subject' => 'Falha no backup da aplicação :application_name', 'backup_failed_body' => 'Importante: Ocorreu um erro ao fazer o backup da aplicação :application_name', 'backup_successful_subject' => 'Backup realizado com sucesso: :application_name', 'backup_successful_subject_title' => 'Backup Realizado com sucesso!', 'backup_successful_body' => 'Boas notícias, um novo backup da aplicação :application_name foi criado no disco :disk_name.', 'cleanup_failed_subject' => 'Falha na limpeza dos backups da aplicação :application_name.', 'cleanup_failed_body' => 'Um erro ocorreu ao fazer a limpeza dos backups da aplicação :application_name', 'cleanup_successful_subject' => 'Limpeza dos backups da aplicação :application_name concluída!', 'cleanup_successful_subject_title' => 'Limpeza dos backups concluída!', 'cleanup_successful_body' => 'A limpeza dos backups da aplicação :application_name no disco :disk_name foi concluída.', 'healthy_backup_found_subject' => 'Os backups da aplicação :application_name no disco :disk_name estão em dia', 'healthy_backup_found_subject_title' => 'Os backups da aplicação :application_name estão em dia', 'healthy_backup_found_body' => 'Os backups da aplicação :application_name estão em dia. Bom trabalho!', 'unhealthy_backup_found_subject' => 'Importante: Os backups da aplicação :application_name não estão em dia', 'unhealthy_backup_found_subject_title' => 'Importante: Os backups da aplicação :application_name não estão em dia. :problem', 'unhealthy_backup_found_body' => 'Os backups da aplicação :application_name no disco :disk_name não estão em dia.', 'unhealthy_backup_found_not_reachable' => 'O destino dos backups não pode ser alcançado. :error', 'unhealthy_backup_found_empty' => 'Não existem backups para essa aplicação.', 'unhealthy_backup_found_old' => 'O último backup realizado em :date é considerado muito antigo.', 'unhealthy_backup_found_unknown' => 'Desculpe, a exata razão não pode ser encontrada.', 'unhealthy_backup_found_full' => 'Os backups estão usando muito espaço de armazenamento. A utilização atual é de :disk_usage, o que é maior que o limite permitido de :disk_limit.', ]; ================================================ FILE: lang/vendor/backup/ro/notifications.php ================================================ 'Cu excepția mesajului: :message', 'exception_trace' => 'Urmă excepţie: :trace', 'exception_message_title' => 'Mesaj de excepție', 'exception_trace_title' => 'Urmă excepţie', 'backup_failed_subject' => 'Nu s-a putut face copie de rezervă pentru :application_name', 'backup_failed_body' => 'Important: A apărut o eroare în timpul generării copiei de rezervă pentru :application_name', 'backup_successful_subject' => 'Copie de rezervă efectuată cu succes pentru :application_name', 'backup_successful_subject_title' => 'O nouă copie de rezervă a fost efectuată cu succes!', 'backup_successful_body' => 'Vești bune, o nouă copie de rezervă pentru :application_name a fost creată cu succes pe discul cu numele :disk_name.', 'cleanup_failed_subject' => 'Curățarea copiilor de rezervă pentru :application_name nu a reușit.', 'cleanup_failed_body' => 'A apărut o eroare în timpul curățirii copiilor de rezervă pentru :application_name', 'cleanup_successful_subject' => 'Curățarea copiilor de rezervă pentru :application_name a fost făcută cu succes', 'cleanup_successful_subject_title' => 'Curățarea copiilor de rezervă a fost făcută cu succes!', 'cleanup_successful_body' => 'Curățarea copiilor de rezervă pentru :application_name de pe discul cu numele :disk_name a fost făcută cu succes.', 'healthy_backup_found_subject' => 'Copiile de rezervă pentru :application_name de pe discul :disk_name sunt în regulă', 'healthy_backup_found_subject_title' => 'Copiile de rezervă pentru :application_name sunt în regulă', 'healthy_backup_found_body' => 'Copiile de rezervă pentru :application_name sunt considerate în regulă. Bună treabă!', 'unhealthy_backup_found_subject' => 'Important: Copiile de rezervă pentru :application_name nu sunt în regulă', 'unhealthy_backup_found_subject_title' => 'Important: Copiile de rezervă pentru :application_name nu sunt în regulă. :problem', 'unhealthy_backup_found_body' => 'Copiile de rezervă pentru :application_name de pe discul :disk_name nu sunt în regulă.', 'unhealthy_backup_found_not_reachable' => 'Nu se poate ajunge la destinația copiilor de rezervă. :error', 'unhealthy_backup_found_empty' => 'Nu există copii de rezervă ale acestei aplicații.', 'unhealthy_backup_found_old' => 'Cea mai recentă copie de rezervă făcută la :date este considerată prea veche.', 'unhealthy_backup_found_unknown' => 'Ne pare rău, un motiv exact nu poate fi determinat.', 'unhealthy_backup_found_full' => 'Copiile de rezervă folosesc prea mult spațiu de stocare. Utilizarea curentă este de :disk_usage care este mai mare decât limita permisă de :disk_limit.', ]; ================================================ FILE: lang/vendor/backup/ru/notifications.php ================================================ 'Сообщение об ошибке: :message', 'exception_trace' => 'Сведения об ошибке: :trace', 'exception_message_title' => 'Сообщение об ошибке', 'exception_trace_title' => 'Сведения об ошибке', 'backup_failed_subject' => 'Не удалось сделать резервную копию :application_name', 'backup_failed_body' => 'Внимание: Произошла ошибка во время резервного копирования :application_name', 'backup_successful_subject' => 'Успешно создана новая резервная копия :application_name', 'backup_successful_subject_title' => 'Успешно создана новая резервная копия!', 'backup_successful_body' => 'Отличная новость, новая резервная копия :application_name успешно создана и сохранена на диск :disk_name.', 'cleanup_failed_subject' => 'Не удалось очистить резервные копии :application_name', 'cleanup_failed_body' => 'Произошла ошибка при очистке резервных копий :application_name', 'cleanup_successful_subject' => 'Очистка от резервных копий :application_name прошла успешно', 'cleanup_successful_subject_title' => 'Очистка резервных копий прошла удачно!', 'cleanup_successful_body' => 'Очистка от старых резервных копий :application_name на диске :disk_name прошла удачно.', 'healthy_backup_found_subject' => 'Резервная копия :application_name с диска :disk_name установлена', 'healthy_backup_found_subject_title' => 'Резервная копия :application_name установлена', 'healthy_backup_found_body' => 'Резервная копия :application_name успешно установлена. Хорошая работа!', 'unhealthy_backup_found_subject' => 'Внимание: резервная копия :application_name не установилась', 'unhealthy_backup_found_subject_title' => 'Внимание: резервная копия для :application_name не установилась. :problem', 'unhealthy_backup_found_body' => 'Резервная копия для :application_name на диске :disk_name не установилась.', 'unhealthy_backup_found_not_reachable' => 'Резервная копия не смогла установиться. :error', 'unhealthy_backup_found_empty' => 'Резервные копии для этого приложения отсутствуют.', 'unhealthy_backup_found_old' => 'Последнее резервное копирование создано :date является устаревшим.', 'unhealthy_backup_found_unknown' => 'Извините, точная причина не может быть определена.', 'unhealthy_backup_found_full' => 'Резервные копии используют слишком много памяти. Используется :disk_usage что выше допустимого предела: :disk_limit.', ]; ================================================ FILE: lang/vendor/backup/tr/notifications.php ================================================ 'Hata mesajı: :message', 'exception_trace' => 'Hata izleri: :trace', 'exception_message_title' => 'Hata mesajı', 'exception_trace_title' => 'Hata izleri', 'backup_failed_subject' => 'Yedeklenemedi :application_name', 'backup_failed_body' => 'Önemli: Yedeklenirken bir hata oluştu :application_name', 'backup_successful_subject' => 'Başarılı :application_name yeni yedeklemesi', 'backup_successful_subject_title' => 'Başarılı bir yeni yedekleme!', 'backup_successful_body' => 'Harika bir haber, :application_name âit yeni bir yedekleme :disk_name adlı diskte başarıyla oluşturuldu.', 'cleanup_failed_subject' => ':application_name yedeklemeleri temizlenmesi başarısız.', 'cleanup_failed_body' => ':application_name yedeklerini temizlerken bir hata oluştu ', 'cleanup_successful_subject' => ':application_name yedeklemeleri temizlenmesi başarılı.', 'cleanup_successful_subject_title' => 'Yedeklerin temizlenmesi başarılı!', 'cleanup_successful_body' => ':application_name yedeklemeleri temizlenmesi ,:disk_name diskinden silindi', 'healthy_backup_found_subject' => ':application_name yedeklenmesi ,:disk_name adlı diskte sağlıklı', 'healthy_backup_found_subject_title' => ':application_name yedeklenmesi sağlıklı', 'healthy_backup_found_body' => ':application_name için yapılan yedeklemeler sağlıklı sayılır. Aferin!', 'unhealthy_backup_found_subject' => 'Önemli: :application_name için yedeklemeler sağlıksız', 'unhealthy_backup_found_subject_title' => 'Önemli: :application_name için yedeklemeler sağlıksız. :problem', 'unhealthy_backup_found_body' => 'Yedeklemeler: :application_name disk: :disk_name sağlıksız.', 'unhealthy_backup_found_not_reachable' => 'Yedekleme hedefine ulaşılamıyor. :error', 'unhealthy_backup_found_empty' => 'Bu uygulamanın yedekleri yok.', 'unhealthy_backup_found_old' => ':date tarihinde yapılan en son yedekleme çok eski kabul ediliyor.', 'unhealthy_backup_found_unknown' => 'Üzgünüm, kesin bir sebep belirlenemiyor.', 'unhealthy_backup_found_full' => 'Yedeklemeler çok fazla depolama alanı kullanıyor. Şu anki kullanım: :disk_usage, izin verilen sınırdan yüksek: :disk_limit.', ]; ================================================ FILE: lang/vendor/backup/uk/notifications.php ================================================ 'Повідомлення про помилку: :message', 'exception_trace' => 'Деталі помилки: :trace', 'exception_message_title' => 'Повідомлення помилки', 'exception_trace_title' => 'Деталі помилки', 'backup_failed_subject' => 'Не вдалось зробити резервну копію :application_name', 'backup_failed_body' => 'Увага: Трапилась помилка під час резервного копіювання :application_name', 'backup_successful_subject' => 'Успішне резервне копіювання :application_name', 'backup_successful_subject_title' => 'Успішно створена резервна копія!', 'backup_successful_body' => 'Чудова новина, нова резервна копія :application_name успішно створена і збережена на диск :disk_name.', 'cleanup_failed_subject' => 'Не вдалось очистити резервні копії :application_name', 'cleanup_failed_body' => 'Сталася помилка під час очищення резервних копій :application_name', 'cleanup_successful_subject' => 'Успішне очищення від резервних копій :application_name', 'cleanup_successful_subject_title' => 'Очищення резервних копій пройшло вдало!', 'cleanup_successful_body' => 'Очищенно від старих резервних копій :application_name на диску :disk_name пойшло успішно.', 'healthy_backup_found_subject' => 'Резервна копія :application_name з диску :disk_name установлена', 'healthy_backup_found_subject_title' => 'Резервна копія :application_name установлена', 'healthy_backup_found_body' => 'Резервна копія :application_name успішно установлена. Хороша робота!', 'unhealthy_backup_found_subject' => 'Увага: резервна копія :application_name не установилась', 'unhealthy_backup_found_subject_title' => 'Увага: резервна копія для :application_name не установилась. :problem', 'unhealthy_backup_found_body' => 'Резервна копія для :application_name на диску :disk_name не установилась.', 'unhealthy_backup_found_not_reachable' => 'Резервна копія не змогла установитись. :error', 'unhealthy_backup_found_empty' => 'Резервні копії для цього додатку відсутні.', 'unhealthy_backup_found_old' => 'Останнє резервне копіювання створено :date є застарілим.', 'unhealthy_backup_found_unknown' => 'Вибачте, але ми не змогли визначити точну причину.', 'unhealthy_backup_found_full' => 'Резервні копії використовують занадто багато пам`яті. Використовується :disk_usage що вище за допустиму межу :disk_limit.', ]; ================================================ FILE: lang/vendor/backup/zh-CN/notifications.php ================================================ '异常信息: :message', 'exception_trace' => '异常跟踪: :trace', 'exception_message_title' => '异常信息', 'exception_trace_title' => '异常跟踪', 'backup_failed_subject' => ':application_name 备份失败', 'backup_failed_body' => '重要说明:备份 :application_name 时发生错误', 'backup_successful_subject' => ':application_name 备份成功', 'backup_successful_subject_title' => '备份成功!', 'backup_successful_body' => '好消息, :application_name 备份成功,位于磁盘 :disk_name 中。', 'cleanup_failed_subject' => '清除 :application_name 的备份失败。', 'cleanup_failed_body' => '清除备份 :application_name 时发生错误', 'cleanup_successful_subject' => '成功清除 :application_name 的备份', 'cleanup_successful_subject_title' => '成功清除备份!', 'cleanup_successful_body' => '成功清除 :disk_name 磁盘上 :application_name 的备份。', 'healthy_backup_found_subject' => ':disk_name 磁盘上 :application_name 的备份是健康的', 'healthy_backup_found_subject_title' => ':application_name 的备份是健康的', 'healthy_backup_found_body' => ':application_name 的备份是健康的。干的好!', 'unhealthy_backup_found_subject' => '重要说明::application_name 的备份不健康', 'unhealthy_backup_found_subject_title' => '重要说明::application_name 备份不健康。 :problem', 'unhealthy_backup_found_body' => ':disk_name 磁盘上 :application_name 的备份不健康。', 'unhealthy_backup_found_not_reachable' => '无法访问备份目标。 :error', 'unhealthy_backup_found_empty' => '根本没有此应用程序的备份。', 'unhealthy_backup_found_old' => '最近的备份创建于 :date ,太旧了。', 'unhealthy_backup_found_unknown' => '对不起,确切原因无法确定。', 'unhealthy_backup_found_full' => '备份占用了太多存储空间。当前占用了 :disk_usage ,高于允许的限制 :disk_limit。', 'no_backups_info' => '尚未进行任何备份', 'application_name' => '应用名称', 'backup_name' => '备份名称', 'disk' => '磁盘', 'newest_backup_size' => '最新备份大小', 'number_of_backups' => '备份数量', 'total_storage_used' => '使用的总存储量', 'newest_backup_date' => '最新备份大小', 'oldest_backup_date' => '最旧的备份大小', ]; ================================================ FILE: lang/vendor/backup/zh-TW/notifications.php ================================================ '異常訊息: :message', 'exception_trace' => '異常追蹤: :trace', 'exception_message_title' => '異常訊息', 'exception_trace_title' => '異常追蹤', 'backup_failed_subject' => ':application_name 備份失敗', 'backup_failed_body' => '重要說明:備份 :application_name 時發生錯誤', 'backup_successful_subject' => ':application_name 備份成功', 'backup_successful_subject_title' => '備份成功!', 'backup_successful_body' => '好消息, :application_name 備份成功,位於磁盤 :disk_name 中。', 'cleanup_failed_subject' => '清除 :application_name 的備份失敗。', 'cleanup_failed_body' => '清除備份 :application_name 時發生錯誤', 'cleanup_successful_subject' => '成功清除 :application_name 的備份', 'cleanup_successful_subject_title' => '成功清除備份!', 'cleanup_successful_body' => '成功清除 :disk_name 磁盤上 :application_name 的備份。', 'healthy_backup_found_subject' => ':disk_name 磁盤上 :application_name 的備份是健康的', 'healthy_backup_found_subject_title' => ':application_name 的備份是健康的', 'healthy_backup_found_body' => ':application_name 的備份是健康的。幹的好!', 'unhealthy_backup_found_subject' => '重要說明::application_name 的備份不健康', 'unhealthy_backup_found_subject_title' => '重要說明::application_name 備份不健康。 :problem', 'unhealthy_backup_found_body' => ':disk_name 磁盤上 :application_name 的備份不健康。', 'unhealthy_backup_found_not_reachable' => '無法訪問備份目標。 :error', 'unhealthy_backup_found_empty' => '根本沒有此應用程序的備份。', 'unhealthy_backup_found_old' => '最近的備份創建於 :date ,太舊了。', 'unhealthy_backup_found_unknown' => '對不起,確切原因無法確定。', 'unhealthy_backup_found_full' => '備份佔用了太多存儲空間。當前佔用了 :disk_usage ,高於允許的限制 :disk_limit。', 'no_backups_info' => '尚未進行任何備份', 'application_name' => '應用名稱', 'backup_name' => '備份名稱', 'disk' => '磁碟', 'newest_backup_size' => '最新備份大小', 'number_of_backups' => '備份數量', 'total_storage_used' => '使用的總存儲量', 'newest_backup_date' => '最新備份大小', 'oldest_backup_date' => '最早的備份大小', ]; ================================================ FILE: package.json ================================================ { "private": true, "type": "module", "scripts": { "dev": "vite", "build": "vite build" }, "devDependencies": { "axios": "^1.6.4", "laravel-vite-plugin": "^1.0", "vite": "^5.0" } } ================================================ FILE: phpunit.xml ================================================ tests/Feature app ================================================ FILE: public/.htaccess ================================================ Options -MultiViews -Indexes RewriteEngine On # Handle Authorization Header RewriteCond %{HTTP:Authorization} . RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}] # Handle X-XSRF-Token Header RewriteCond %{HTTP:x-xsrf-token} . RewriteRule .* - [E=HTTP_X_XSRF_TOKEN:%{HTTP:X-XSRF-Token}] # Redirect Trailing Slashes If Not A Folder... RewriteCond %{REQUEST_FILENAME} !-d RewriteCond %{REQUEST_URI} (.+)/$ RewriteRule ^ %1 [L,R=301] # Send Requests To Front Controller... RewriteCond %{REQUEST_FILENAME} !-d RewriteCond %{REQUEST_FILENAME} !-f RewriteRule ^ index.php [L] ================================================ FILE: public/assets/css/backpack_electric_purple_overlay.css ================================================ /* Replace standard blue with electric purple to match Backpack's 2020 front-end redesign. */ .btn-primary, .dataTables_wrapper .dataTables_paginate .paginate_button.current { color: #fff; background-color: #7C69EF; border-color: #7C69EF; } .btn-primary:hover, .dataTables_wrapper .dataTables_paginate .paginate_button.current:hover { background-color: #6956de; } .btn-primary:not(:disabled):not(.disabled).active, .btn-primary:not(:disabled):not(.disabled):active, .btn-outline-primary:not(:disabled):not(.disabled):active, .dataTables_wrapper .dataTables_paginate .paginate_button.current:not(:disabled):not(.disabled).active, .dataTables_wrapper .dataTables_paginate .paginate_button.current:not(:disabled):not(.disabled):active, .dataTables_wrapper .dataTables_paginate .show>.dropdown-toggle.paginate_button.current, .show>.btn-primary.dropdown-toggle { background-color: #5844d0; border-color: #5844d0; } .dropdown-item.active, .dropdown-item:active { color: #fff; background-color: #5844d0; } .text-primary { color: #7C69EF!important; } h1 { color: #7C69EF!important; } .btn-link { color: #7C69EF; } .btn-outline-primary { color: #7C69EF; border-color: #7C69EF; } .btn-outline-primary:hover { color: #fff; background-color: #7C69EF; border-color: #7C69EF; } .btn:hover, .dataTables_wrapper .dataTables_paginate .paginate_button:hover { color: #4024e8; } .page-item.active .page-link { z-index: 1; color: #fff; background-color: #7C69EF; border-color: #7C69EF; } .page-link:hover { color: #7C69EF; } a { color: #7C69EF; } a:hover { color: #4024e8; } .table-hover tbody tr:hover, #crudTable tbody tr:hover { background-color: rgba(124, 105, 239, 0.1); } .sidebar.sidebar-pills .nav-link.active .nav-icon, .sidebar.sidebar-pills .nav-link:hover .nav-icon, .sidebar.sidebar-pills .nav-link.active, .sidebar.sidebar-pills .nav-link:hover, .sidebar-pills .nav-link:hover .nav-icon { color: #7C69EF!important; } .card.bg-primary { border-color: #7C69EF; } .bg-primary { background-color: #7C69EF!important; } .daterangepicker .ranges li.active, .daterangepicker td.active, .daterangepicker td.active:hover { background-color: #7C69EF!important; } .pace .pace-progress { background: #7C69EF; } body { /*border-top: 3px solid #7C69EF;*/ } ================================================ FILE: public/assets/js/ga.js ================================================ window.dataLayer = window.dataLayer || []; function gtag() { dataLayer.push(arguments); } gtag('js', new Date()); gtag('config', 'UA-16782706-13'); ================================================ FILE: public/assets/js/meetings.js ================================================ // calendar view operation document.getElementById("calendar")?.addEventListener("menuClick", (e) => { let { action, event, properties } = e.detail; if (action === "alert") alert(`Event ${event.id} — ${properties?.message}`); }); ================================================ FILE: public/assets/js/monster/fields.js ================================================ /** * This file includes all the fields inside Monster, * as an array, in order to be used for testing * the crud.field() JS library. */ var monsterFields = [ // --------------------------------- // Monster Fields, by Name and Type // --------------------------------- // syntax: 'fieldName', // fieldType // --------------------------------- 'checkbox', // checkbox 'roles', // checklist // checklist_dependency 'color', // color // custom_html 'date', // date 'datetime', // datetime 'email', // email 'status', //enum 'hidden', // hidden 'month', // month 'number', 'float', 'number_with_prefix', 'number_with_suffix', 'text_with_both_prefix_and_suffix', // number 'phone', // phone 'password', // password 'radio', // radio 'range', // range 'select', // select (1-n relationship) 'select_grouped_id', // select_grouped 'tags', // select_multiple (n-n relationship) 'select_from_array', // select_from_array 'summernote', // summernote 'text', // text 'textarea', // textarea 'time', // time 'upload', // upload 'upload_multiple', // upload_multiple 'url', // url 'switch', // switch 'dropzone', //dropzone // view 'week', // week 'address_google', 'location', //google_map 'browse', // browse PRO 'browse_multiple', // browse_multiple PRO 'base64_image', // base64_image PRO 'wysiwyg', // ckeditor PRO 'start_date', 'end_date', // date_range PRO 'date_picker', // date_picker PRO 'datetime_picker', // datetime_picker PRO 'easymde', // easymde PRO 'icon_picker', // icon_picker PRO 'image', // image PRO 'address.street', 'address.country', 'sentiment.text', 'sentiment.user', 'category', 'postalboxer', 'countries', 'universes', 'bills', 'fallback_icon', 'icondummy', 'wish', 'postalboxes', 'ball', 'stars', 'recommends', 'products', 'dummyproducts', // relationship PRO // repeatable PRO 'repeatable_example_2', 'select2', // select2 (1-n relationship) PRO 'categories', // select2_multiple (n-n relationship) PRO 'select2_nested_id', // select2_nested PRO 'select2_grouped_id', // select2_grouped PRO 'select_and_order', // select_and_order PRO 'select2_from_array', // select2_from_array PRO 'select2_from_ajax', // select2_from_ajax PRO 'articles', // select2_from_ajax_multiple PRO 'table', 'fake_table', // table PRO 'tinymce', // tinymce PRO 'video', // video PRO 'slug', // slug PRO // 'wysiwyg', // wysiwyg PRO - included in ckeditor and summernote ]; // console.log(monsterFields); ================================================ FILE: public/assets/js/monster/test-custom-field.js ================================================ /** * This file tests custom crud.field('name').something() methods * on SOME Monster field types. */ $('nav[aria-label=breadcrumb]').append('custom methods'); function testCustomFieldMethods() { alert('Tab 1 > checkbox will been checked... then unchecked after 3 seconds'); crud.field('checkbox').check(); setTimeout(function(){ crud.field('checkbox').uncheck(); // console.log('Tab 1 > checkbox has been unchecked'); }, 3000); } ================================================ FILE: public/assets/js/monster/test-disable-field.js ================================================ /** * This file tests the crud.field('name').disable() method * on all Monster field types, assuming the fields.js * file is already loaded. */ $('nav[aria-label=breadcrumb]').append('disable()'); function testCrudFieldDisable() { // go through all Monster fields and disable them for (var i = 0; i <= monsterFields.length - 1; i++) { crud.field(monsterFields[i]).disable(); } alert('Calling disable() on all monster fields. If you can see a field that is NOT disabled... then disable() might not work on it, please investigate.'); } ================================================ FILE: public/assets/js/monster/test-enable-field.js ================================================ /** * This file tests the crud.field('name').enable() method * on all Monster field types, assuming the fields.js * file is already loaded. */ $('nav[aria-label=breadcrumb]').append('enable()'); function testCrudFieldEnable() { // go through all Monster fields and enable them for (var i = 0; i <= monsterFields.length - 1; i++) { crud.field(monsterFields[i]).enable(); } alert('Calling enable() on all monster fields. If you can see a field that is still disabled... then enable() might not work on it, please investigate.'); } ================================================ FILE: public/assets/js/monster/test-hide-field.js ================================================ /** * This file tests the crud.field('name').hide() method * on all Monster field types, assuming the fields.js * file is already loaded. */ $('nav[aria-label=breadcrumb]').append('hide()'); function testCrudFieldHide() { // go through all Monster fields and hide them for (var i = 0; i <= monsterFields.length - 1; i++) { crud.field(monsterFields[i]).hide(); } alert('Calling hide() on all monster fields. If you can see a field... then hide() doesn\'t work on it, please investigate.'); } ================================================ FILE: public/assets/js/monster/test-onchange-field.js ================================================ /** * This file tests the crud.field('name').onChange() method * on all Monster field types, assuming the fields.js * file is already loaded. */ $('nav[aria-label=breadcrumb]').append('onChange()'); function testCrudFieldOnChange() { alert('Open your browser\'s console, then use each field you want to test. A line should be output in your console, every time a change event is triggered.'); // add an onChange event on all fields monsterFields.forEach(name => { crud.field(name).onChange(field => { console.log(`Value for field ${field.name} (type ${field.type}) was changed to ${field.value}`); }); }); } ================================================ FILE: public/assets/js/monster/test-require-field.js ================================================ /** * This file tests the crud.field('name').require() method * on all Monster field types, assuming the fields.js * file is already loaded. */ $('nav[aria-label=breadcrumb]').append('require()'); function testCrudFieldRequire() { // go through all Monster fields and require them for (var i = 0; i <= monsterFields.length - 1; i++) { crud.field(monsterFields[i]).require(); } alert('Calling require() on all monster fields. If you can see a field WITHOUT an asterisk... then require() doesn\'t work on it, please investigate.'); } ================================================ FILE: public/assets/js/monster/test-show-field.js ================================================ /** * This file tests the crud.field('name').show() method * on all Monster field types, assuming the fields.js * file is already loaded. */ $('nav[aria-label=breadcrumb]').append('show()'); function testCrudFieldShow() { // go through all Monster fields and hide them for (var i = 0; i <= monsterFields.length - 1; i++) { crud.field(monsterFields[i]).show(); } alert('Calling show() on all monster fields. If you can\'t see a field... then show() doesn\'t work on it, please investigate.'); } ================================================ FILE: public/assets/js/monster/test-top-scenarios.js ================================================ // EXAMPLE 1 // when a checkbox is checked, show a second field; crud.field('visible').onChange(field => { crud.field('visible_where').show(field.value == 1); }).change(); // EXAMPLE 2 // when a checkbox is checked, show a second field AND un-disable/un-readonly it; crud.field('displayed').onChange(field => { crud.field('displayed_where') .show(field.value == 1) .enable(field.value == 1); }).change(); // EXAMPLE 3 // when a radio has something specific selected, show a second field; crud.field('type').onChange(field => { crud.field('custom_type').show(field.value == 3); }).change(); // EXAMPLE 4 // when a select has something specific selected, show a second field; crud.field('parent').onChange(field => { crud.field('custom_parent').show(field.value == 6); }).change(); // EXAMPLE 5 // when a checkbox is checked AND a select has a certain value, then do something; let do_something = () => { console.log('Displayed AND custom parent.'); } crud.field('displayed').onChange(field => { if (field.value === 1 && crud.field('parent').value == 6) { do_something(); } }); crud.field('parent').onChange(field => { if (field.value === 6 && crud.field('displayed').value == 1) { do_something(); } }); // EXAMPLE 6 // when a checkbox is checked OR a select has a certain value, then show a third field; let do_something_else = () => { console.log('Displayed OR custom parent.'); } crud.field('displayed').onChange(field => { if (field.value === 1 || crud.field('parent').value == 6) { do_something_else(); } }); crud.field('parent').onChange(field => { if (field.value === 6 || crud.field('displayed').value == 1) { do_something_else(); } }); // EXAMPLE 7 // when a select is a certain value, show a second field; if it's another value, show a third field; crud.field('parent').onChange(field => { switch(field.value) { case 2: console.log('fake showing a second field'); break; case 3: console.log('fake showing a third field'); break; default: console.log('not doing anything'); } }); // EXAMPLE 8 // when a checkbox is checked, automatically check a different checkbox or radio; crud.field('visible').onChange(field => { crud.field('displayed').check(field.value == 1); }); // EXAMPLE 9 // when a text input is written into, write into a second input (eg. slug); crud.field('title').onChange(function(field) { crud.field('title_url_segment').input.value = field.value.toString().toLowerCase().trim() .normalize('NFD') // separate accent from letter .replace(/[\u0300-\u036f]/g, '') // remove all separated accents .replace(/\s+/g, '-') // replace spaces with - .replace(/[^\w\-]+/g, '') // remove all non-word chars .replace(/\-\-+/g, '-') // replace multiple '-' with single '-'; }); // EXAMPLE 10 // when multiple inputs change, change a last input to calculate the total or smth; let calculate_discount_percentage = () => { let full_price = Number(crud.field('full_price').value); let discounted_price = Number(crud.field('discounted_price').value); let discount_percentage = (full_price - discounted_price) * 100 / full_price; crud.field('discount_percentage').input.value = discount_percentage; } crud.fields(['full_price', 'discounted_price']).forEach(field => { field.onChange(calculate_discount_percentage); }); // EXAMPLE 11 // when dropdown subfield changes, disable another subfield // TODO: change the example to a dedicated repeatable, in the last tab // (right now it's in the Relationship tab, under Direct Relationships + Subfields... HasOne) crud.field('wish').subfield('country').onChange(function(field) { console.log(field.value, field.rowNumber, field.value == ''); crud.field('wish').subfield('body', field.rowNumber).enable(field.value == ''); }); // EXAMPLE 11 // Using subfields crud.field('repeatable_example_1').subfield('yes_or_no').onChange(function(field) { crud.field('repeatable_example_1').subfield('if_no', field.rowNumber).show(field.value == 'no').enable(field.value == 'no'); crud.field('repeatable_example_1').subfield('if_yes', field.rowNumber).show(field.value == 'yes').enable(field.value == 'yes'); }).change(); // EXAMPLE 12 // USING LIVE VALIDATION // When the value of the select changes: // - if empty value, we will hide and disable the `NUMBER` and disable the `TEXT` field clearing the value. // - Any other selected value will update the `NUMBER` value with the selected number and enable the `TEXT` field // The `TEXT` field will display a error red border while it has less than 5 characters. // The `NUMBER` field will highlight the `odd` numbers with a red border crud.field('live_validation_select').onChange(function(field) { let textInput = crud.field('live_validation_text'); let numberInput = crud.field('live_validation_number'); if(field.value === '') { textInput.input.value = ''; textInput.input.classList.remove('is-invalid'); // if it was invalid before the value changed, also remove the invalid class textInput.disable(); numberInput.disable().hide(); } else { textInput.enable(); numberInput.enable().show(); numberInput.input.value = field.value; numberInput.change() } }).change(); crud.field('live_validation_text').onChange(function(field) { field.input.classList.toggle('is-invalid', field.value.length < 5); }); crud.field('live_validation_number').onChange(function(field) { field.input.classList.toggle('is-invalid', field.value % 2 != 0); }); // EXAMPLE 13 // In date_range, when start_date and date_range are less than 7 days apart, show a bubble function checkIfOneWeekOrMore() { let start_date = new Date(crud.field('start_date').value); let end_date = new Date(crud.field('end_date').value); let days_between = parseInt((end_date - start_date)/1000/60/60)/24; if (days_between < 7) { new Noty({ type: 'warning', text: 'We recommend you choose a time interval that is 7 days or more.', }).show(); } } // Solution 1: we target the "fake" date_range input directly crud.field('start_date,end_date').onChange(checkIfOneWeekOrMore); // Solution 2: we can target start_date and end_date individually // but then when the date_range changes, there will be multiple // events triggered, so muultiple bubbles triggered // crud.field('start_date').onChange(field => checkIfOneWeekOrMore()); // crud.field('end_date').onChange(field => checkIfOneWeekOrMore()); ================================================ FILE: public/assets/js/monster/test-unrequire-field.js ================================================ /** * This file tests the crud.field('name').unrequire() method * on all Monster field types, assuming the fields.js * file is already loaded. */ $('nav[aria-label=breadcrumb]').append('unrequire()'); function testCrudFieldUnrequire() { // go through all Monster fields and unrequire them for (var i = 0; i <= monsterFields.length - 1; i++) { crud.field(monsterFields[i]).unrequire(); } alert('Calling unrequire() on all monster fields. If you can see a field WITH asterisk... then unrequire() doesn\'t work on it, please investigate.'); } ================================================ FILE: public/index.php ================================================ */ /* |-------------------------------------------------------------------------- | Register The Auto Loader |-------------------------------------------------------------------------- | | Composer provides a convenient, automatically generated class loader for | our application. We just need to utilize it! We'll simply require it | into the script here so that we don't have to worry about manual | loading any of our classes later on. It feels nice to relax. | */ require __DIR__.'/../bootstrap/autoload.php'; /* |-------------------------------------------------------------------------- | Turn On The Lights |-------------------------------------------------------------------------- | | We need to illuminate PHP development, so let us turn on the lights. | This bootstraps the framework and gets it ready for use, then it | will load up this application so that we can run it and send | the responses back to the browser and delight our users. | */ $app = require_once __DIR__.'/../bootstrap/app.php'; /* |-------------------------------------------------------------------------- | Run The Application |-------------------------------------------------------------------------- | | Once we have the application, we can handle the incoming request | through the kernel, and send the associated response back to | the client's browser allowing them to enjoy the creative | and wonderful application we have prepared for them. | */ $kernel = $app->make(Illuminate\Contracts\Http\Kernel::class); $response = $kernel->handle( $request = Illuminate\Http\Request::capture() ); $response->send(); $kernel->terminate($request, $response); ================================================ FILE: public/robots.txt ================================================ User-agent: * Disallow: ================================================ FILE: public/uploads/.gitkeep ================================================ ================================================ FILE: public/web.config ================================================ ================================================ FILE: readme.md ================================================




Website | Documentation | Add-ons | Pricing | Services | Stack Overflow | Reddit | Blog | Newsletter

# Backpack\Demo Laravel BackPack's demo, which includes all Backpack packages. > ### Security updates and breaking changes > Please **[subscribe to the Backpack Newsletter](http://backpackforlaravel.com/newsletter)** so you can find out about any security updates, breaking changes or major features. We send an email every 1-2 months. ![image](https://github.com/Laravel-Backpack/demo/assets/7188159/a8caa891-75fe-4df5-bf97-5593a334540b) ## How to Use You can find the demo online at [demo.backpackforlaravel.com](https://demo.backpackforlaravel.com/admin), and play around. But some functionality is disabled, for security reasons (uploads, edits to users). If you want to run the demo without restrictions and/or make code edits and see how they're applied, you can install it on your own machine. See below. ## Install > **IMPORTANT**. This demo requires ALL our premium packages. If you _do not_ have access to one of them, you will _not_ be able to install it. To install this demo yourself, make sure you've purchased all our premium add-ons individually, or our Everything bundle - https://backpackforlaravel.com/pricing 1) Run in your terminal: ``` bash git clone https://github.com/Laravel-Backpack/demo.git backpack-demo ``` 2) Set your database information in your .env file (use the .env.example as an example); 3) Make sure the `APP_URL` in your .env file is correctly pointing to the URL you use to access your application in the browser, for example: `http:127.0.0.1:8000` or `http://something.test` 4) Run in your backpack-demo folder: ``` bash composer install php artisan key:generate php artisan migrate php artisan db:seed ``` ## Usage 1. Your admin panel is available at http://localhost/backpack-demo/admin 2. Login with email ```admin@example.com```, password ```admin``` 3. [optional] You can register a different account, to check out the process and see your gravatar inside the admin panel. 4. By default, registration is open only in your local environment. Check out ```config/backpack/base.php``` to change this and other preferences. Note: Depending on your configuration you may need to define a site within NGINX or Apache; Your URL domain may change from localhost to what you have defined. ![Example generated CRUD interface](https://backpackforlaravel.com/uploads/docs-4-0/getting_started/tag_crud_list_entries.png) ## If using docker This package provides an example `docker-compose.yml` to launch your database and web server easily ``` composer install cp .env.example .env php artisan key:generate ``` Use these parameters in your .env file ``` APP_URL=http://localhost DB_CONNECTION=mysql DB_HOST=db DB_PORT=3306 DB_DATABASE=backpackdemo DB_USERNAME=root DB_PASSWORD=asdf ``` Launch docker ``` docker-compose up -d ``` Create your database with following command ``` docker-compose exec db mysql -u root -pasdf -e "create database if not exists backpackdemo;" ``` Migrate and seed ``` php artisan migrate --seed ``` You should see the demo in your browser now ``` http://localhost/admin ``` To stop the server simply run ``` docker-compose down ``` Note: In docker, to connect to your database from your GUI use `127.0.0.1` as your database host, instead of `localhost` ## Change log Please see [CHANGELOG](CHANGELOG.md) for more information what has changed recently. ## Contributing Please see [CONTRIBUTING](CONTRIBUTING.md) and [CONDUCT](CONDUCT.md) for details. ## Security If you discover any security related issues, please email tabacitu@backpackforlaravel.com instead of using the issue tracker. Please **[subscribe to the Backpack Newsletter](http://backpackforlaravel.com/newsletter)** so you can find out about any security updates, breaking changes or major features. We send an email every 1-2 months. ## Credits - [Cristian Tabacitu][link-author] - [All Contributors][link-contributors] ## License Backpack is free for non-commercial use and 69 EUR/project for commercial use. Please see [License File](LICENSE.md) and [backpackforlaravel.com](https://backpackforlaravel.com/#pricing) for more information. ## Hire us We've spend more than 10.000 hours creating, polishing and maintaining administration panels on Laravel. We've developed e-Commerce, e-Learning, ERPs, social networks, payment gateways and much more. We've worked on admin panels _so much_, that we've created one of the most popular software in its niche - just from making public what was repetitive in our projects. If you are looking for a developer/team to help you build an admin panel on Laravel, look no further. You'll have a difficult time finding someone with more experience & enthusiasm for this. This is _what we do_. [Contact us - let's see if we can work together](https://backpackforlaravel.com/need-freelancer-or-development-team). [link-author]: http://tabacitu.ro [link-contributors]: ../../contributors ================================================ FILE: reload.sh ================================================ #!/usr/bin/env bash docker compose down --remove-orphans "${args[@]}" docker compose build docker compose up --remove-orphans "${args[@]}" ================================================ FILE: resources/assets/sass/app.scss ================================================ // @import "node_modules/bootstrap-sass/assets/stylesheets/bootstrap"; ================================================ FILE: resources/views/admin/metrics/top_products.blade.php ================================================ {{-- Example "view" metric: a custom table rendered server-side --}} @php $products = $query->clone() ->orderByDesc('price') ->limit(5) ->get(['name', 'price', 'status']); @endphp @forelse ($products as $product) @empty @endforelse
Product Price Status
{{ $product->name }} ${{ number_format($product->price, 2) }} {{ $product->status }}
No products found
================================================ FILE: resources/views/admin/new-in-v7.blade.php ================================================ @extends(backpack_view('blank')) @php // Add the form widget to the 'after_content' section of the widgets array // $widgets['after_content'][] = [ // 'type' => 'div', // 'class' => 'row', // 'content' => [ // widgets // [ // 'type' => 'dataform', // 'wrapper' => [ // 'class' => 'col-md-12 mt-3', // ], // 'controller' => \App\Http\Controllers\Admin\PetShop\SkillCrudController::class, // 'formOperation' => 'update', // 'entry' => \App\Models\PetShop\Skill::find(1), // 'content' => [ // 'header' => 'Edit Skill (TODO: move this to the right place on page)', // optional // 'body' => 'This form should make it easy to update an existing skill.

', // optional // ], // ] // ] // ]; $widgets['after_content'][] = [ 'type' => 'view', 'view' => 'backpack.theme-tabler::inc.commercial', 'wrapper' => [ 'class' => 'mt-3', ], ]; @endphp @section('content')
Views

Chips

Include more information about an Eloquent model, in a small space. Hover over the headings to understand more about the examples.

@include('admin.partials.chip-examples')
Components

Datagrid

Show the most important info about an Eloquent entry, anywhere you want.

@include('admin.partials.datagrid-examples')
Components

Datalist

Show the most important info about an Eloquent entry, anywhere you want.

@include('admin.partials.datalist-examples')
Components

Datatable

Include your complex datatable, anywhere you want.

@include('admin.partials.datatable-examples')
Components

Dataform

Show a form for an Eloquent entry, anywhere you want.

@include('admin.partials.dataform-examples')
Components

Dataform Modal

Show a form for an Eloquent entry, in a modal.

@include('admin.partials.dataform-modal-examples') @endsection ================================================ FILE: resources/views/admin/partials/chip-examples.blade.php ================================================ @php $user = \App\User::inRandomOrder()->first(); $invoices = \App\Models\PetShop\Invoice::inRandomOrder()->take(3)->get(); $products = \App\Models\Product::inRandomOrder()->take(3)->get(); $owners = \App\Models\PetShop\Owner::inRandomOrder()->take(3)->get(); @endphp
{{-- Example of General chip for a person, with hardcoded complete data --}} @include('crud::chips.general', [ 'heading' => [ 'content' => 'John Doe', 'href' => 'https://google.com', 'target' => '_blank', 'title' => 'Example of a chip without URL', ], 'image' => [ 'content' => asset('uploads/person1.jpg'), 'element' => 'a', 'href' => 'https://chatgpt.com', 'target' => '_blank', 'title' => 'Image can have its own URL, but why?! Falls back to the one in the heading', ], 'details' => [ [ 'icon' => 'la la-hashtag', 'content' => '8AH13A7', 'url' => 'mailto:john.doe@example.com', 'title' => 'Click to email', ], [ 'icon' => 'la la-envelope', 'content' => 'john.doe@example.com', 'url' => 'mailto:john.doe@example.com', 'title' => 'Click to email', ], [ 'icon' => 'la la-phone', 'content' => '+1 (555) 123-4567', 'url' => 'tel:+15551234567', 'title' => 'Click to call', ] ] ])
{{-- Example of General chip for a person, with hardcoded data, missing URL and image --}} @include('crud::chips.general', [ 'heading' => [ 'content' => 'Adam Mancinello', 'title' => 'Example of a chip without URL or image', 'element' => 'span', // can be a span, a div, or an anchor ], 'details' => [ [ 'icon' => 'la la-hashtag', 'content' => '8AH13A7', 'url' => 'mailto:adam.mancinello@example.com', 'title' => 'Click to email', ], [ 'icon' => 'la la-envelope', 'content' => 'adam.mancinello@example.com', 'url' => 'mailto:adam.mancinello@example.com', 'title' => 'Click to email', ], [ 'icon' => 'la la-phone', 'content' => '+1 (555) 123-4567', 'url' => 'tel:+15551234567', 'title' => 'Click to call', ] ] ])
{{-- Example of General chip for a person, with data from Eloquent model --}} @include('crud::chips.general', [ 'heading' => [ 'content' => $user->name, 'href' => backpack_url('user/'.$user->id.'/show'), 'title' => 'Click to preview', ], 'image' => [ 'content' => backpack_avatar_url($user), // doesn't work well with dummy data 'element' => 'a', 'href' => backpack_url('user/'.$user->id.'/show'), 'title' => 'Because of dummy data, this image is not available, but it would show a profile image', ], 'details' => [ [ 'icon' => 'la la-hashtag', 'content' => $user->id, 'url' => backpack_url('user/'.$user->id.'/show'), 'title' => 'Click to preview', ], [ 'icon' => 'la la-envelope', 'content' => $user->email, 'url' => 'mailto:'.$user->email, 'title' => 'Click to email', ], [ 'icon' => 'la la-calendar', 'content' => $user->created_at->format('F j, Y'), 'title' => 'Created at '.$user->created_at, ] ] ])

Works well for people - in this demo, the most obvious example is pet owners:

@foreach ($owners as $owner)
{{-- Example of General chip for a person, with data from Eloquent model --}} @include('crud::chips.owner', ['entry' => $owner])
@endforeach

But it's particularly useful for entities where the name alone can't identify an entity, eg. Invoice:

@foreach ($invoices as $invoice)
{{-- Example of General chip for a person, with data from Eloquent model --}} @include('crud::chips.invoice', ['entry' => $invoice])
@endforeach

Or entities that can sometimes have duplicated names, like Products:

@foreach ($products as $product)
{{-- Example of General chip for a person, with data from Eloquent model --}} @include('crud::chips.general', [ 'heading' => [ 'content' => $product->name, 'href' => backpack_url('product/'.$product->id.'/show'), 'title' => 'Click to preview', ], 'details' => [ [ 'icon' => 'la la-dollar', 'content' => $product->price, 'title' => 'Priced at $'.$product->price, ], [ 'icon' => 'la la-tag', 'content' => $product->category->name, 'url' => backpack_url('category/'.$product->category->id.'/show'), 'title' => 'Product category: '.$product->category->name, ], [ 'icon' => 'la la-tag', 'content' => $product->status, 'title' => 'Product status: '.$product->status->value, ], [ 'icon' => 'la la-traffic-light', 'content' => $product->condition, 'title' => 'Production condition: '.$product->condition, ] ] ])
@endforeach
================================================ FILE: resources/views/admin/partials/dataform-examples.blade.php ================================================

Create Invoice

Quick Add Tag (With Extra Field)

Quick Edit Tag

================================================ FILE: resources/views/admin/partials/dataform-modal-examples.blade.php ================================================

Quickly Add/Edit Invoices Showing latest invoices in a custom table, with buttons to create or edit an invoice in a modal form.

@php $newestInvoices = \App\Models\Petshop\Invoice::orderBy('updated_at')->take(5)->get(); @endphp
@foreach ($newestInvoices as $invoice) @endforeach
Actions Invoice Customer Total Created
Edit {{ $invoice->series.' '.$invoice->number }} {{ $invoice->owner->name }} ${{ number_format($invoice->total, 0) }} {{ $invoice->created_at->diffForHumans() }}

Didn't find what you're looking for? Create a new invoice

================================================ FILE: resources/views/admin/partials/datagrid-examples.blade.php ================================================ ================================================ FILE: resources/views/admin/partials/datalist-examples.blade.php ================================================ ================================================ FILE: resources/views/admin/partials/datatable-examples.blade.php ================================================

Invoices Showing all invoices in the DB, pulling the entire setup from InvoiceCrudController.

================================================ FILE: resources/views/admin/petshop_about.blade.php ================================================ @extends(backpack_view('blank')) @section('content')
Pet Shop Example
This mock admin panel is here to highlight all the things you can do using the relationship field in Backpack, as it's using all relationship types Laravel supports. You can use the diagram below to better understand the database structure and where each relationship type is being used:
Petshop ERD Diagram @endsection ================================================ FILE: resources/views/vendor/.gitkeep ================================================ ================================================ FILE: resources/views/vendor/backpack/crud/buttons/fake-editable-columns.blade.php ================================================ @if(request()->boolean('fake')) Editable Columns @else Fake Editable Columns @endif ================================================ FILE: resources/views/vendor/backpack/crud/buttons/passports.blade.php ================================================ See Passports ================================================ FILE: resources/views/vendor/backpack/crud/chips/invoice.blade.php ================================================ @include('crud::chips.general', [ 'heading' => [ 'content' => 'Invoice '.$entry->series.' '.$entry->number.' - '.$entry->owner->name, 'href' => backpack_url('pet-shop/invoice/'.$entry->id.'/show'), ], 'details' => [ [ 'icon' => 'la la-dollar', 'content' => $entry->total, 'title' => 'Total invoice amount $'.$entry->total, ], [ 'icon' => 'la la-tags', 'content' => $entry->items->count().' items', ], [ 'icon' => 'la la-calendar', 'content' => $entry->issuance_date->format('F j, Y'), 'title' => 'Issuance date: '.$entry->issuance_date, ] ] ]) ================================================ FILE: resources/views/vendor/backpack/crud/chips/owner.blade.php ================================================ @php $last_purchase = $entry->invoices()->orderBy('issuance_date', 'DESC')->first()->issuance_date; @endphp @include('crud::chips.general', [ 'heading' => [ 'content' => $entry->name, 'href' => backpack_url('pet-shop/owner/'.$entry->id.'/show'), ], 'image' => [ 'content' => asset($entry->avatar->url), ], 'details' => [ [ 'icon' => 'la la-dog', 'content' => $entry->pets->count().' pets', 'title' => 'Number of pets: '.$entry->pets->count(), ], [ 'icon' => 'la la-shopping-cart', 'content' => $entry->invoices->count(). ' purchases', 'title' => 'Number of purchases: '.$entry->invoices->count(), ], [ 'icon' => 'la la-calendar', 'content' => $last_purchase->format('F j, Y'), 'title' => 'Last purchase: '.$last_purchase, ] ] ]) ================================================ FILE: resources/views/vendor/backpack/crud/columns/custom_view_column_example.blade.php ================================================ {{-- Used for 'custom_view' column example --}} BadGood ================================================ FILE: resources/views/vendor/backpack/crud/details_row/monster.blade.php ================================================
Use the details_row functionality to show more information about the entry, when that information does not fit inside the table column.

Text: {{ $entry->text }}
Textarea: {{ $entry->textarea }}
Email: {{ $entry->email }}
Number: {{ $entry->number }}
Float: {{ $entry->float }}
Week: {{ $entry->week }}
Month: {{ $entry->month }}
etc.
================================================ FILE: resources/views/vendor/backpack/theme-coreuiv2/auth/login.blade.php ================================================ {{-- BACKPACK DEMO FILE --}} {{-- It makes sure the login inputs are pre-populated with the default admin user. --}} @extends(backpack_view('layouts.plain')) @section('content')

{{ trans('backpack::base.login') }}

{!! csrf_field() !!}
@if ($errors->has($username)) {{ $errors->first($username) }} @endif
@if ($errors->has('password')) {{ $errors->first('password') }} @endif
@if (backpack_users_have_email()) @endif @if (config('backpack.base.registration_open')) @endif
@endsection ================================================ FILE: resources/views/vendor/backpack/theme-coreuiv2/dashboard.blade.php ================================================ @extends(backpack_view('blank')) @php // --------------------- // JUMBOTRON widget demo // --------------------- // Widget::add([ // 'type' => 'jumbotron', // 'name' => 'jumbotron', // 'wrapperClass'=> 'shadow-xs', // 'heading' => trans('backpack::base.welcome'), // 'content' => trans('backpack::base.use_sidebar'), // 'button_link' => backpack_url('logout'), // 'button_text' => trans('backpack::base.logout'), // ])->to('before_content')->makeFirst(); // ------------------------- // FLUENT SYNTAX for widgets // ------------------------- // Using the progress_white widget // // Obviously, you should NOT do any big queries directly in the view. // In fact, it can be argued that you shouldn't add Widgets from blade files when you // need them to show information from the DB. // // But you do whatever you think it's best. Who am I, your mom? $productCount = App\Models\Product::count(); $userCount = App\User::count(); $articleCount = \Backpack\NewsCRUD\app\Models\Article::count(); $lastArticle = \Backpack\NewsCRUD\app\Models\Article::orderBy('date', 'DESC')->first(); $lastArticleDaysAgo = $lastArticle !== null ? \Carbon\Carbon::parse($lastArticle->date)->diffInDays(\Carbon\Carbon::today()).' days' : 'No articles'; // notice we use Widget::add() to add widgets to a certain group Widget::add()->to('before_content')->type('div')->class('row')->content([ // notice we use Widget::make() to add widgets as content (not in a group) Widget::make() ->type('progress') ->class('card border-0 text-white bg-primary') ->progressClass('progress-bar') ->value($userCount) ->description('Registered users.') ->progress(100*(int)$userCount/1000) ->hint(1000-$userCount.' more until next milestone.'), // alternatively, to use widgets as content, we can use the same add() method, // but we need to use onlyHere() or remove() at the end Widget::add() ->type('progress') ->class('card border-0 text-white bg-success') ->progressClass('progress-bar') ->value($articleCount) ->description('Articles.') ->progress(80) ->hint('Great! Don\'t stop.') ->onlyHere(), // alternatively, you can just push the widget to a "hidden" group Widget::make() ->group('hidden') ->type('progress') ->class('card border-0 text-white bg-warning') ->value($lastArticleDaysAgo) ->progressClass('progress-bar') ->description('Since last article.') ->progress(30) ->hint('Post an article every 3-4 days.'), // both Widget::make() and Widget::add() accept an array as a parameter // if you prefer defining your widgets as arrays Widget::make([ 'type' => 'progress', 'class'=> 'card border-0 text-white bg-dark', 'progressClass' => 'progress-bar', 'value' => $productCount, 'description' => 'Products.', 'progress' => (int)$productCount/75*100, 'hint' => $productCount>75?'Try to stay under 75 products.':'Good. Good.', ]), ]); $widgets['after_content'][] = [ 'type' => 'div', 'class' => 'row', 'content' => [ // widgets [ 'type' => 'card', // 'wrapperClass' => 'col-sm-6 col-md-4', // optional // 'class' => 'card bg-dark text-white', // optional 'content' => [ 'header' => 'Some card title', // optional 'body' => 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis non mi nec orci euismod venenatis. Integer quis sapien et diam facilisis facilisis ultricies quis justo. Phasellus sem turpis, ornare quis aliquet ut, volutpat et lectus. Aliquam a egestas elit. Nulla posuere, sem et porttitor mollis, massa nibh sagittis nibh, id porttitor nibh turpis sed arcu.', ] ], [ 'type' => 'card', // 'wrapperClass' => 'col-sm-6 col-md-4', // optional // 'class' => 'card bg-dark text-white', // optional 'content' => [ 'header' => 'Another card title', // optional 'body' => 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis non mi nec orci euismod venenatis. Integer quis sapien et diam facilisis facilisis ultricies quis justo. Phasellus sem turpis, ornare quis aliquet ut, volutpat et lectus. Aliquam a egestas elit. Nulla posuere, sem et porttitor mollis, massa nibh sagittis nibh, id porttitor nibh turpis sed arcu.', ] ], [ 'type' => 'card', // 'wrapperClass' => 'col-sm-6 col-md-4', // optional // 'class' => 'card bg-dark text-white', // optional 'content' => [ 'header' => 'Yet another card title', // optional 'body' => 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis non mi nec orci euismod venenatis. Integer quis sapien et diam facilisis facilisis ultricies quis justo. Phasellus sem turpis, ornare quis aliquet ut, volutpat et lectus. Aliquam a egestas elit. Nulla posuere, sem et porttitor mollis, massa nibh sagittis nibh, id porttitor nibh turpis sed arcu.', ] ], ] ]; $widgets['after_content'][] = [ 'type' => 'alert', 'class' => 'alert alert-warning bg-dark border-0 mb-4', 'heading' => 'Demo Refreshes Every Hour on the Hour', 'content' => 'At hh:00, all custom entries are deleted, all files, everything. This cleanup is necessary because developers like to joke with their test entries, and mess with stuff. But you know that :-) Go ahead - make a developer smile.' , 'close_button' => true, // show close button or not ]; $widgets['before_content'][] = [ 'type' => 'div', 'class' => 'row', 'content' => [ // widgets [ 'type' => 'chart', 'wrapperClass' => 'col-md-6', // 'class' => 'col-md-6', 'controller' => \App\Http\Controllers\Admin\Charts\LatestUsersChartController::class, 'content' => [ 'header' => 'New Users Past 7 Days', // optional // 'body' => 'This chart should make it obvious how many new users have signed up in the past 7 days.

', // optional ] ], [ 'type' => 'chart', 'wrapperClass' => 'col-md-6', // 'class' => 'col-md-6', 'controller' => \App\Http\Controllers\Admin\Charts\NewEntriesChartController::class, 'content' => [ 'header' => 'New Entries', // optional // 'body' => 'This chart should make it obvious how many new users have signed up in the past 7 days.

', // optional ] ], ] ]; $widgets['after_content'][] = [ 'type' => 'div', 'class' => 'row', 'content' => [ // widgets [ 'type' => 'chart', 'wrapperClass' => 'col-md-4', // 'class' => 'col-md-6', 'controller' => \App\Http\Controllers\Admin\Charts\Pies\ChartjsPieController::class, 'content' => [ 'header' => 'Pie Chart - Chartjs', // optional // 'body' => 'This chart should make it obvious how many new users have signed up in the past 7 days.

', // optional ] ], [ 'type' => 'chart', 'wrapperClass' => 'col-md-4', // 'class' => 'col-md-6', 'controller' => \App\Http\Controllers\Admin\Charts\Pies\EchartsPieController::class, 'content' => [ 'header' => 'Pie Chart - Echarts', // optional // 'body' => 'This chart should make it obvious how many new users have signed up in the past 7 days.

', // optional ] ], [ 'type' => 'chart', 'wrapperClass' => 'col-md-4', // 'class' => 'col-md-6', 'controller' => \App\Http\Controllers\Admin\Charts\Pies\HighchartsPieController::class, 'content' => [ 'header' => 'Pie Chart - Highcharts', // optional // 'body' => 'This chart should make it obvious how many new users have signed up in the past 7 days.

', // optional ] ], ] ]; $widgets['after_content'][] = [ 'type' => 'div', 'class' => 'row', 'content' => [ // widgets [ 'type' => 'chart', 'wrapperClass' => 'col-md-6', // 'class' => 'col-md-6', 'controller' => \App\Http\Controllers\Admin\Charts\Lines\ChartjsLineChartController::class, 'content' => [ 'header' => 'Line Chart - Chartjs', // optional // 'body' => 'This chart should make it obvious how many new users have signed up in the past 7 days.

', // optional ] ], [ 'type' => 'chart', 'wrapperClass' => 'col-md-6', // 'class' => 'col-md-6', 'controller' => \App\Http\Controllers\Admin\Charts\Lines\EchartsLineChartController::class, 'content' => [ 'header' => 'Line Chart - Echarts', // optional // 'body' => 'This chart should make it obvious how many new users have signed up in the past 7 days.

', // optional ] ], [ 'type' => 'chart', 'wrapperClass' => 'col-md-6', // 'class' => 'col-md-6', 'controller' => \App\Http\Controllers\Admin\Charts\Lines\HighchartsLineChartController::class, 'content' => [ 'header' => 'Line Chart - Highcharts', // optional // 'body' => 'This chart should make it obvious how many new users have signed up in the past 7 days.

', // optional ] ], [ 'type' => 'chart', 'wrapperClass' => 'col-md-6', // 'class' => 'col-md-6', 'controller' => \App\Http\Controllers\Admin\Charts\Lines\FrappeLineChartController::class, 'content' => [ 'header' => 'Line Chart - Frappe', // optional // 'body' => 'This chart should make it obvious how many new users have signed up in the past 7 days.

', // optional ] ], ] ]; @endphp @section('content')
{{-- In case widgets have been added to a 'content' group, show those widgets. --}} @include(backpack_view('inc.widgets'), [ 'widgets' => app('widgets')->where('group', 'content')->toArray() ]) @endsection ================================================ FILE: resources/views/vendor/backpack/theme-coreuiv2/inc/alerts.blade.php ================================================ {{-- Bootstrap Notifications using Prologue Alerts & PNotify JS --}} ================================================ FILE: resources/views/vendor/backpack/theme-coreuiv2/inc/topbar_right_content.blade.php ================================================ @push('after_scripts') @endpush @include('backpack.language-switcher::language-switcher') ================================================ FILE: resources/views/vendor/backpack/theme-coreuiv4/auth/login.blade.php ================================================ {{-- BACKPACK DEMO FILE --}} {{-- It makes sure the login inputs are pre-populated with the default admin user. --}} @extends(backpack_view('layouts.plain')) @section('content')

{{ trans('backpack::base.login') }}

{!! csrf_field() !!}
@if ($errors->has($username)) {{ $errors->first($username) }} @endif
@if ($errors->has('password')) {{ $errors->first('password') }} @endif
@if (backpack_users_have_email()) @endif @if (config('backpack.base.registration_open')) @endif
@endsection ================================================ FILE: resources/views/vendor/backpack/theme-coreuiv4/dashboard.blade.php ================================================ @extends(backpack_view('blank')) @php // --------------------- // JUMBOTRON widget demo // --------------------- // Widget::add([ // 'type' => 'jumbotron', // 'name' => 'jumbotron', // 'wrapperClass'=> 'shadow-xs', // 'heading' => trans('backpack::base.welcome'), // 'content' => trans('backpack::base.use_sidebar'), // 'button_link' => backpack_url('logout'), // 'button_text' => trans('backpack::base.logout'), // ])->to('before_content')->makeFirst(); // ------------------------- // FLUENT SYNTAX for widgets // ------------------------- // Using the progress_white widget // // Obviously, you should NOT do any big queries directly in the view. // In fact, it can be argued that you shouldn't add Widgets from blade files when you // need them to show information from the DB. // // But you do whatever you think it's best. Who am I, your mom? $productCount = App\Models\Product::count(); $userCount = App\User::count(); $articleCount = \Backpack\NewsCRUD\app\Models\Article::count(); $lastArticle = \Backpack\NewsCRUD\app\Models\Article::orderBy('date', 'DESC')->first(); $lastArticleDaysAgo = $lastArticle !== null ? \Carbon\Carbon::parse($lastArticle->date)->diffInDays(\Carbon\Carbon::today()).' days' : 'No articles'; // notice we use Widget::add() to add widgets to a certain group Widget::add()->to('before_content')->type('div')->class('row')->content([ // notice we use Widget::make() to add widgets as content (not in a group) Widget::make() ->type('progress') ->class('card border-0 text-white bg-info') ->progressClass('progress-bar') ->value($userCount) ->description('Registered users.') ->progress(100*(int)$userCount/1000) ->hint(1000-$userCount.' more until next milestone.'), // alternatively, to use widgets as content, we can use the same add() method, // but we need to use onlyHere() or remove() at the end Widget::add() ->type('progress') ->class('card border-0 text-white bg-success') ->progressClass('progress-bar') ->value($articleCount) ->description('Articles.') ->progress(80) ->hint('Great! Don\'t stop.') ->onlyHere(), // alternatively, you can just push the widget to a "hidden" group Widget::make() ->group('hidden') ->type('progress') ->class('card border-0 text-white bg-warning') ->value($lastArticleDaysAgo) ->progressClass('progress-bar') ->description('Since last article.') ->progress(30) ->hint('Post an article every 3-4 days.'), // both Widget::make() and Widget::add() accept an array as a parameter // if you prefer defining your widgets as arrays Widget::make([ 'type' => 'progress', 'class'=> 'card border-0 text-white bg-danger', 'progressClass' => 'progress-bar', 'value' => $productCount, 'description' => 'Products.', 'progress' => (int)$productCount/75*100, 'hint' => $productCount>75?'Try to stay under 75 products.':'Good. Good.', ]), ]); $widgets['after_content'][] = [ 'type' => 'div', 'class' => 'row', 'content' => [ // widgets [ 'type' => 'card', // 'wrapperClass' => 'col-sm-6 col-md-4', // optional // 'class' => 'card bg-dark text-white', // optional 'content' => [ 'header' => 'Some card title', // optional 'body' => 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis non mi nec orci euismod venenatis. Integer quis sapien et diam facilisis facilisis ultricies quis justo. Phasellus sem turpis, ornare quis aliquet ut, volutpat et lectus. Aliquam a egestas elit. Nulla posuere, sem et porttitor mollis, massa nibh sagittis nibh, id porttitor nibh turpis sed arcu.', ] ], [ 'type' => 'card', // 'wrapperClass' => 'col-sm-6 col-md-4', // optional // 'class' => 'card bg-dark text-white', // optional 'content' => [ 'header' => 'Another card title', // optional 'body' => 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis non mi nec orci euismod venenatis. Integer quis sapien et diam facilisis facilisis ultricies quis justo. Phasellus sem turpis, ornare quis aliquet ut, volutpat et lectus. Aliquam a egestas elit. Nulla posuere, sem et porttitor mollis, massa nibh sagittis nibh, id porttitor nibh turpis sed arcu.', ] ], [ 'type' => 'card', // 'wrapperClass' => 'col-sm-6 col-md-4', // optional // 'class' => 'card bg-dark text-white', // optional 'content' => [ 'header' => 'Yet another card title', // optional 'body' => 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis non mi nec orci euismod venenatis. Integer quis sapien et diam facilisis facilisis ultricies quis justo. Phasellus sem turpis, ornare quis aliquet ut, volutpat et lectus. Aliquam a egestas elit. Nulla posuere, sem et porttitor mollis, massa nibh sagittis nibh, id porttitor nibh turpis sed arcu.', ] ], ] ]; $widgets['after_content'][] = [ 'type' => 'alert', 'class' => 'alert bg-dark text-bg-dark border-0 mb-4', 'heading' => 'Demo Refreshes Every Hour on the Hour', 'content' => 'At hh:00, all custom entries are deleted, all files, everything. This cleanup is necessary because developers like to joke with their test entries, and mess with stuff. But you know that :-) Go ahead - make a developer smile.' , 'close_button' => true, // show close button or not ]; $widgets['before_content'][] = [ 'type' => 'div', 'class' => 'row', 'content' => [ // widgets [ 'type' => 'chart', 'wrapperClass' => 'col-md-6', // 'class' => 'col-md-6', 'controller' => \App\Http\Controllers\Admin\Charts\LatestUsersChartController::class, 'content' => [ 'header' => 'New Users Past 7 Days', // optional // 'body' => 'This chart should make it obvious how many new users have signed up in the past 7 days.

', // optional ] ], [ 'type' => 'chart', 'wrapperClass' => 'col-md-6', // 'class' => 'col-md-6', 'controller' => \App\Http\Controllers\Admin\Charts\NewEntriesChartController::class, 'content' => [ 'header' => 'New Entries', // optional // 'body' => 'This chart should make it obvious how many new users have signed up in the past 7 days.

', // optional ] ], ] ]; $widgets['after_content'][] = [ 'type' => 'div', 'class' => 'row', 'content' => [ // widgets [ 'type' => 'chart', 'wrapperClass' => 'col-md-4', // 'class' => 'col-md-6', 'controller' => \App\Http\Controllers\Admin\Charts\Pies\ChartjsPieController::class, 'content' => [ 'header' => 'Pie Chart - Chartjs', // optional // 'body' => 'This chart should make it obvious how many new users have signed up in the past 7 days.

', // optional ] ], [ 'type' => 'chart', 'wrapperClass' => 'col-md-4', // 'class' => 'col-md-6', 'controller' => \App\Http\Controllers\Admin\Charts\Pies\EchartsPieController::class, 'content' => [ 'header' => 'Pie Chart - Echarts', // optional // 'body' => 'This chart should make it obvious how many new users have signed up in the past 7 days.

', // optional ] ], [ 'type' => 'chart', 'wrapperClass' => 'col-md-4', // 'class' => 'col-md-6', 'controller' => \App\Http\Controllers\Admin\Charts\Pies\HighchartsPieController::class, 'content' => [ 'header' => 'Pie Chart - Highcharts', // optional // 'body' => 'This chart should make it obvious how many new users have signed up in the past 7 days.

', // optional ] ], ] ]; $widgets['after_content'][] = [ 'type' => 'div', 'class' => 'row', 'content' => [ // widgets [ 'type' => 'chart', 'wrapperClass' => 'col-md-6', // 'class' => 'col-md-6', 'controller' => \App\Http\Controllers\Admin\Charts\Lines\ChartjsLineChartController::class, 'content' => [ 'header' => 'Line Chart - Chartjs', // optional // 'body' => 'This chart should make it obvious how many new users have signed up in the past 7 days.

', // optional ] ], [ 'type' => 'chart', 'wrapperClass' => 'col-md-6', // 'class' => 'col-md-6', 'controller' => \App\Http\Controllers\Admin\Charts\Lines\EchartsLineChartController::class, 'content' => [ 'header' => 'Line Chart - Echarts', // optional // 'body' => 'This chart should make it obvious how many new users have signed up in the past 7 days.

', // optional ] ], [ 'type' => 'chart', 'wrapperClass' => 'col-md-6', // 'class' => 'col-md-6', 'controller' => \App\Http\Controllers\Admin\Charts\Lines\HighchartsLineChartController::class, 'content' => [ 'header' => 'Line Chart - Highcharts', // optional // 'body' => 'This chart should make it obvious how many new users have signed up in the past 7 days.

', // optional ] ], [ 'type' => 'chart', 'wrapperClass' => 'col-md-6', // 'class' => 'col-md-6', 'controller' => \App\Http\Controllers\Admin\Charts\Lines\FrappeLineChartController::class, 'content' => [ 'header' => 'Line Chart - Frappe', // optional // 'body' => 'This chart should make it obvious how many new users have signed up in the past 7 days.

', // optional ] ], ] ]; @endphp @section('content')
{{-- In case widgets have been added to a 'content' group, show those widgets. --}} @include(backpack_view('inc.widgets'), [ 'widgets' => app('widgets')->where('group', 'content')->toArray() ]) @endsection ================================================ FILE: resources/views/vendor/backpack/theme-coreuiv4/inc/alerts.blade.php ================================================ {{-- Bootstrap Notifications using Prologue Alerts & PNotify JS --}} ================================================ FILE: resources/views/vendor/backpack/theme-coreuiv4/inc/topbar_right_content.blade.php ================================================ @push('after_scripts') @endpush @include('backpack.language-switcher::language-switcher') ================================================ FILE: resources/views/vendor/backpack/theme-tabler/auth/login/inc/form.blade.php ================================================

{{ trans('backpack::base.login') }}

@csrf
@if ($errors->has($username))
{{ $errors->first($username) }}
@endif
@if ($errors->has('password'))
{{ $errors->first('password') }}
@endif
@if (backpack_users_have_email()) @endif
================================================ FILE: resources/views/vendor/backpack/theme-tabler/dashboard.blade.php ================================================ @extends(backpack_view('blank')) @php // --------------------- // JUMBOTRON widget demo // --------------------- // Widget::add([ // 'type' => 'jumbotron', // 'name' => 'jumbotron', // 'wrapperClass'=> 'shadow-xs', // 'heading' => trans('backpack::base.welcome'), // 'content' => trans('backpack::base.use_sidebar'), // 'button_link' => backpack_url('logout'), // 'button_text' => trans('backpack::base.logout'), // ])->to('before_content')->makeFirst(); // ------------------------- // FLUENT SYNTAX for widgets // ------------------------- // Using the progress_white widget // // Obviously, you should NOT do any big queries directly in the view. // In fact, it can be argued that you shouldn't add Widgets from blade files when you // need them to show information from the DB. // // But you do whatever you think it's best. Who am I, your mom? $productCount = App\Models\Product::count(); $userCount = App\User::count(); $articleCount = \Backpack\NewsCRUD\app\Models\Article::count(); $lastArticle = \Backpack\NewsCRUD\app\Models\Article::orderBy('date', 'DESC')->first(); $lastArticleDaysAgo = $lastArticle !== null ? \Carbon\Carbon::parse($lastArticle->date)->diffInDays(\Carbon\Carbon::today()).' days' : 'No articles'; // notice we use Widget::add() to add widgets to a certain group Widget::add()->to('before_content')->type('div')->class('row mt-3')->content([ // notice we use Widget::make() to add widgets as content (not in a group) Widget::make() ->type('progress') ->class('card mb-1') ->statusBorder('start') // start|top|bottom ->accentColor('success') // primary|secondary|warning|danger|info ->ribbon(['top', 'la-user']) // ['top|right|bottom'] ->progressClass('progress-bar') ->value($userCount) ->description('Registered users.') ->progress(100*(int)$userCount/1000) ->hint(1000-$userCount.' more until next milestone.'), // alternatively, to use widgets as content, we can use the same add() method, // but we need to use onlyHere() or remove() at the end Widget::add() ->type('progress') ->class('card mb-1') ->statusBorder('start') // start|top|bottom ->accentColor('danger') // primary|secondary|warning|danger|info ->ribbon(['top', 'la-bell']) // ['top|right|bottom'] ->description('Registered users.') ->progressClass('progress-bar') ->value($articleCount) ->description('Articles.') ->progress(80) ->hint('Great! Don\'t stop.') ->onlyHere(), // alternatively, you can just push the widget to a "hidden" group Widget::make() ->group('hidden') ->type('progress') ->class('card mb-1') ->statusBorder('start') // start|top|bottom ->accentColor('info') // primary|secondary|warning|danger|info ->ribbon(['top', 'la-star']) // ['top|right|bottom'] ->value($lastArticleDaysAgo) ->progressClass('progress-bar') ->description('Since last article.') ->progress(30) ->hint('Post an article every 3-4 days.'), // both Widget::make() and Widget::add() accept an array as a parameter // if you prefer defining your widgets as arrays Widget::make([ 'type' => 'progress', 'class'=> 'card mb-1', 'statusBorder' => 'start', // start|top|bottom 'accentColor' => 'warning', // primary|secondary|warning|danger|info 'ribbon' => ['top', 'la-lock'], // ['top|right|left|bottom', 'la-xxx'] 'progressClass' => 'progress-bar', 'value' => $productCount, 'description' => 'Products.', 'progress' => (int)$productCount/75*100, 'hint' => $productCount>75?'Try to stay under 75 products.':'Good. Good.', ]), ]); $widgets['after_content'][] = [ 'type' => 'div', 'class' => 'row', 'content' => [ // widgets [ 'type' => 'card', // 'wrapperClass' => 'col-sm-6 col-md-4', // optional 'class' => 'card my-3', // optional 'accentColor' => 'warning', 'ribbon' => ['bottom', 'la-star'], // ['top|right|left|bottom', 'la-xxx'] 'statusBorder' => 'top', // start|top|bottom 'content' => [ 'header' => 'Some card title', // optional 'body' => 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis non mi nec orci euismod venenatis. Integer quis sapien et diam facilisis facilisis ultricies quis justo. Phasellus sem turpis, ornare quis aliquet ut, volutpat et lectus. Aliquam a egestas elit. Nulla posuere, sem et porttitor mollis, massa nibh sagittis nibh, id porttitor nibh turpis sed arcu.', 'link' => [ 'labelText' => 'See more', 'href' => backpack_url('user'), ], ], ], [ 'type' => 'card', // 'wrapperClass' => 'col-sm-6 col-md-4', // optional 'accentColor' => 'info', 'ribbon' => ['right', 'la-trophy'], // ['top|right|left|bottom', 'la-xxx'] 'statusBorder' => 'top', // start|top|bottom 'class' => 'card my-3', // optional 'content' => [ 'header' => 'Another card title', // optional 'body' => 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis non mi nec orci euismod venenatis. Integer quis sapien et diam facilisis facilisis ultricies quis justo. Phasellus sem turpis, ornare quis aliquet ut, volutpat et lectus. Aliquam a egestas elit. Nulla posuere, sem et porttitor mollis, massa nibh sagittis nibh, id porttitor nibh turpis sed arcu.', 'link' => [ 'labelText' => 'See list', 'href' => backpack_url('user'), ], ], ], [ 'type' => 'card', 'wrapperClass' => 'col-md-12 col-lg-4', // optional 'class' => 'card my-3', // optional 'accentColor' => 'secondary', 'ribbon' => ['bottom', 'la-list'], // ['top|right|left|bottom', 'la-xxx'] 'statusBorder' => 'top', // start|top|bottom 'content' => [ 'header' => 'Yet another card title', // optional 'body' => 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis non mi nec orci euismod venenatis. Integer quis sapien et diam facilisis facilisis ultricies quis justo. Phasellus sem turpis, ornare quis aliquet ut, volutpat et lectus. Aliquam a egestas elit. Nulla posuere, sem et porttitor mollis, massa nibh sagittis nibh, id porttitor nibh turpis sed arcu.', 'link' => [ 'labelText' => 'See all', 'href' => backpack_url('user'), ], ], ], ] ]; $widgets['after_content'][] = [ 'type' => 'alert', 'class' => 'alert alert-danger mb-3', 'heading' => 'Demo Refreshes Every Hour on the Hour', 'content' => 'At hh:00, all custom entries are deleted, all files, everything. This cleanup is necessary because developers like to joke with their test entries, and mess with stuff. But you know that :-) Go ahead - make a developer smile.' , 'close_button' => true, // show close button or not ]; $widgets['after_content'][] = [ 'type' => 'div', 'class' => 'row', 'content' => [ // widgets [ 'type' => 'chart', 'wrapperClass' => 'col-md-6', // 'class' => 'col-md-6', 'controller' => \App\Http\Controllers\Admin\Charts\LatestUsersChartController::class, 'content' => [ 'header' => 'New Users Past 7 Days', // optional // 'body' => 'This chart should make it obvious how many new users have signed up in the past 7 days.

', // optional ] ], [ 'type' => 'chart', 'wrapperClass' => 'col-md-6', // 'class' => 'col-md-6', 'controller' => \App\Http\Controllers\Admin\Charts\NewEntriesChartController::class, 'content' => [ 'header' => 'New Entries', // optional // 'body' => 'This chart should make it obvious how many new users have signed up in the past 7 days.

', // optional ] ], ] ]; $widgets['after_content'][] = [ 'type' => 'div', 'class' => 'row', 'content' => [ // widgets [ 'type' => 'chart', 'wrapperClass' => 'col-md-4 mt-3 mb-3', // 'class' => 'col-md-6', 'controller' => \App\Http\Controllers\Admin\Charts\Pies\ChartjsPieController::class, 'content' => [ 'header' => 'Pie Chart - Chartjs', // optional // 'body' => 'This chart should make it obvious how many new users have signed up in the past 7 days.

', // optional ] ], [ 'type' => 'chart', 'wrapperClass' => 'col-md-4 mt-3 mb-3', // 'class' => 'col-md-6', 'controller' => \App\Http\Controllers\Admin\Charts\Pies\EchartsPieController::class, 'content' => [ 'header' => 'Pie Chart - Echarts', // optional // 'body' => 'This chart should make it obvious how many new users have signed up in the past 7 days.

', // optional ] ], [ 'type' => 'chart', 'wrapperClass' => 'col-md-4 mt-3 mb-3', // 'class' => 'col-md-6', 'controller' => \App\Http\Controllers\Admin\Charts\Pies\HighchartsPieController::class, 'content' => [ 'header' => 'Pie Chart - Highcharts', // optional // 'body' => 'This chart should make it obvious how many new users have signed up in the past 7 days.

', // optional ] ], ] ]; $widgets['after_content'][] = [ 'type' => 'div', 'class' => 'row', 'content' => [ // widgets [ 'type' => 'chart', 'wrapperClass' => 'col-md-6', // 'class' => 'col-md-6', 'controller' => \App\Http\Controllers\Admin\Charts\Lines\ChartjsLineChartController::class, 'content' => [ 'header' => 'Line Chart - Chartjs', // optional // 'body' => 'This chart should make it obvious how many new users have signed up in the past 7 days.

', // optional ] ], [ 'type' => 'chart', 'wrapperClass' => 'col-md-6 mb-3', // 'class' => 'col-md-6', 'controller' => \App\Http\Controllers\Admin\Charts\Lines\EchartsLineChartController::class, 'content' => [ 'header' => 'Line Chart - Echarts', // optional // 'body' => 'This chart should make it obvious how many new users have signed up in the past 7 days.

', // optional ] ], [ 'type' => 'chart', 'wrapperClass' => 'col-md-6 mb-3', // 'class' => 'col-md-6', 'controller' => \App\Http\Controllers\Admin\Charts\Lines\HighchartsLineChartController::class, 'content' => [ 'header' => 'Line Chart - Highcharts', // optional // 'body' => 'This chart should make it obvious how many new users have signed up in the past 7 days.

', // optional ] ], [ 'type' => 'chart', 'wrapperClass' => 'col-md-6 mb-3', // 'class' => 'col-md-6', 'controller' => \App\Http\Controllers\Admin\Charts\Lines\FrappeLineChartController::class, 'content' => [ 'header' => 'Line Chart - Frappe', // optional // 'body' => 'This chart should make it obvious how many new users have signed up in the past 7 days.

', // optional ] ] ] ]; @endphp @section('content') {{-- In case widgets have been added to a 'content' group, show those widgets. --}} @include(backpack_view('inc.widgets'), [ 'widgets' => app('widgets')->where('group', 'content')->toArray() ]) @endsection ================================================ FILE: resources/views/vendor/backpack/theme-tabler/inc/alerts.blade.php ================================================ {{-- Bootstrap Notifications using Prologue Alerts & PNotify JS --}} ================================================ FILE: resources/views/vendor/backpack/theme-tabler/inc/commercial.blade.php ================================================
Help us polish Backpack v7 public beta

If you find any problems, let us know in a discussion on Github.

================================================ FILE: resources/views/vendor/backpack/theme-tabler/inc/topbar_right_content.blade.php ================================================ @include('backpack.language-switcher::language-switcher') @section('before_scripts') @endsection @section('after_scripts') @endsection ================================================ FILE: resources/views/vendor/backpack/theme-tabler/layouts/partials/sidebar_shortcuts.blade.php ================================================ ================================================ FILE: resources/views/vendor/backpack/ui/inc/menu_items.blade.php ================================================ {{-- This file is used for menu items by any Backpack v6 theme --}} @includeWhen(class_exists(\Backpack\DevTools\DevToolsServiceProvider::class), 'backpack.devtools::buttons.sidebar_item') {{-- Addons --}} {{-- Pets --}} {{-- Monsters --}} ================================================ FILE: resources/views/welcome.blade.php ================================================ Backpack for Laravel {{-- Plausibile.io analytics, proxied through a CloudFlare Worker --}}
@if (Route::has('login')) @endif
Backpack for Laravel
* No front-end pages are provided in this demo. Only the admin panel.
================================================ FILE: routes/api.php ================================================ user(); })->middleware('auth:api'); ================================================ FILE: routes/backpack/custom.php ================================================ config('backpack.base.route_prefix', 'admin'), 'middleware' => ['web', config('backpack.base.middleware_key', 'admin')], 'namespace' => 'App\Http\Controllers\Admin', ], function () { // custom admin routes // ------------ // Custom Pages // ------------ Route::get('new-in-v7', 'AdminPageController@newInV7')->name('new-in-v7'); // ---------------- // Monsters & Stuff // ---------------- Route::crud('monster', 'MonsterCrudController'); Route::crud('hero', 'HeroCrudController'); Route::crud('story', 'StoryCrudController'); Route::crud('cave', 'CaveCrudController'); // ---------------- // Other entities // ---------------- Route::crud('column-monster', 'ColumnMonsterCrudController'); Route::crud('fluent-monster', 'FluentMonsterCrudController'); Route::crud('field-monster', 'FieldMonsterCrudController'); Route::crud('editable-monster', 'EditableMonsterCrudController'); Route::crud('icon', 'IconCrudController'); Route::crud('product', 'ProductCrudController'); Route::crud('dummy', 'DummyCrudController'); Route::crud('meeting', 'MeetingCrudController'); // Allow demo users to switch between available themes and layouts Route::post('switch-layout', function (Request $request) { $theme = 'backpack.theme-'.$request->get('theme', 'tabler').'::'; // if the theme has changed, let's show a success message if (Session::get('backpack.ui.view_namespace') !== $theme) { Alert::success('Now using theme: '.$request->get('theme', 'tabler'))->flash(); } Session::put('backpack.ui.view_namespace', $theme); if ($theme === 'backpack.theme-tabler::') { // if the layout has changed, let's show a success message if (Session::get('backpack.theme-tabler.layout') !== $request->get('layout', 'horizontal')) { Alert::success('Now using layout: '.$request->get('layout', 'horizontal'))->flash(); } Session::put('backpack.theme-tabler.layout', $request->get('layout', 'horizontal')); // Handle styles selection $selectedStyles = $request->get('styles', []); $currentStyles = Session::get('backpack.theme-tabler.styles', []); // Only show success message if styles have actually changed if ($selectedStyles !== $currentStyles) { $styleCount = count($selectedStyles); Alert::success("Applied {$styleCount} style(s)")->flash(); } // Handle direction selection if ($request->has('direction')) { $direction = $request->get('direction', 'ltr'); // if the direction has changed, let's show a success message if (Session::get('backpack.ui.html_direction') !== $direction) { Alert::success('Now using direction: '.$direction)->flash(); } Session::put('backpack.ui.html_direction', $direction); } Session::put('backpack.theme-tabler.styles', $selectedStyles); } return Redirect::back(); })->name('tabler.switch.layout'); // ------------------ // AJAX Chart Widgets // ------------------ Route::get('charts/users', 'Charts\LatestUsersChartController@response'); Route::get('charts/new-entries', 'Charts\NewEntriesChartController@response'); // --------------------------- // Backpack DEMO Custom Routes // Prevent people from doing nasty stuff in the online demo // --------------------------- if (app('env') == 'production') { // disable delete and bulk delete for all CRUDs $cruds = ['article', 'category', 'tag', 'monster', 'icon', 'product', 'page', 'menu-item', 'user', 'role', 'permission', 'hero', 'story', 'cave', 'owner', 'invoice', 'pet', 'passport', 'skill', 'comment', 'badge']; foreach ($cruds as $name) { Route::delete($name.'/{id}', function () { return false; }); Route::post($name.'/bulk-delete', function () { return false; }); } } Route::group([ 'prefix' => 'pet-shop', 'namespace' => 'PetShop', ], function () { Route::get('about', function () { return view('admin.petshop_about'); }); Route::crud('invoice', 'InvoiceCrudController'); Route::crud('pet', 'PetCrudController'); Route::crud('passport', 'PassportCrudController'); Route::crud('skill', 'SkillCrudController'); Route::crud('comment', 'CommentCrudController'); Route::crud('badge', 'BadgeCrudController'); Route::crud('owner', 'OwnerCrudController'); // nested crud panel for owner pets Route::group(['prefix' => 'owner/{owner}'], function () { Route::crud('pets', 'OwnerPetsCrudController'); }); }); }); // this should be the absolute last line of this file ================================================ FILE: routes/backpack/permissionmanager.php ================================================ 'Backpack\PermissionManager\app\Http\Controllers', 'prefix' => config('backpack.base.route_prefix', 'admin'), 'middleware' => ['web', backpack_middleware()], ], function () { Route::crud('permission', 'PermissionCrudController'); Route::crud('role', 'RoleCrudController'); Route::crud('user', 'UserCrudController'); if (app('env') == 'production') { // disable delete and bulk delete for all CRUDs $cruds = ['user', 'role', 'permission']; foreach ($cruds as $name) { Route::delete($name.'/{id}', function () { return false; }); Route::post($name.'/bulk-delete', function () { return false; }); } } }); ================================================ FILE: routes/console.php ================================================ comment(Inspiring::quote()); }); ================================================ FILE: routes/web.php ================================================ 1] public array $routeParameters = []; } ================================================ FILE: tests/Feature/Admin/ColumnMonsterCrudControllerTest.php ================================================ 1] public array $routeParameters = []; } ================================================ FILE: tests/Feature/Admin/EditableMonsterCrudControllerTest.php ================================================ 1] public array $routeParameters = []; } ================================================ FILE: tests/Feature/Admin/IconCrudControllerTest.php ================================================ 1] public array $routeParameters = []; } ================================================ FILE: tests/Feature/Admin/MeetingCrudControllerTest.php ================================================ 1] public array $routeParameters = []; } ================================================ FILE: tests/Feature/Admin/MonsterCrudControllerTest.php ================================================ 1] public array $routeParameters = []; public function setup(): void { parent::setUp(); $this->createInput = array_merge($this->model::factory()->make()->toArray(), [ 'icondummy' => 1, ]); $this->assertCreateInput = array_merge($this->testHelper->getDatabaseAssertInput($this->model, $this->createInput), [ 'belongs_to_non_nullable' => 1, ]); } } ================================================ FILE: tests/Feature/Admin/PetShop/BadgeCrudControllerTest.php ================================================ 1] public array $routeParameters = []; } ================================================ FILE: tests/Feature/Admin/PetShop/CommentCrudControllerTest.php ================================================ 1] public array $routeParameters = []; } ================================================ FILE: tests/Feature/Admin/PetShop/InvoiceCrudControllerTest.php ================================================ 1] public array $routeParameters = []; } ================================================ FILE: tests/Feature/Admin/PetShop/OwnerCrudControllerTest.php ================================================ 1] public array $routeParameters = []; public function setup(): void { parent::setUp(); $this->createInput = $this->updateInput = array_merge($this->model::factory()->make()->toArray(), [ 'avatar' => [ 'url' => 'https://lorempixel.com/400/200/animals', ], ]); } } ================================================ FILE: tests/Feature/Admin/PetShop/OwnerPetsCrudControllerTest.php ================================================ 1] public array $routeParameters = ['owner' => 1]; public function setup(): void { parent::setUp(); $this->createInput = $this->updateInput = array_merge($this->model::factory()->make()->toArray(), [ 'avatar' => [ 'url' => 'https://lorempixel.com/400/200/animals', ], ]); \App\Models\PetShop\Owner::factory()->create(['id' => 1]); // create an owner with id 1 } /** * Test logic for update operation. */ public function test_update_page_loads_successfully(): void { $this->skipIfModelDoesNotHaveFactory(); $entry = $this->model::factory()->create(); $entry->owners()->attach(1, ['role' => 'Owner']); // attach the pet to the owner with id 1 $entry->save(); $response = $this->get($this->testHelper->getCrudUrl($entry->getKey().'/edit')); $response->assertStatus(200); $response->assertSee($this->entityName ?? ''); } /** * Test logic for show operation. */ public function test_show_page_loads_successfully(): void { $this->skipIfModelDoesNotHaveFactory(); $entry = $this->model::factory()->create(); $entry->owners()->attach(1, ['role' => 'Owner']); // attach the pet to the owner with id 1 $entry->save(); $response = $this->get($this->testHelper->getCrudUrl($entry->getKey().'/show')); $response->assertStatus(200); $response->assertSee($this->entityName ?? ''); } } ================================================ FILE: tests/Feature/Admin/PetShop/PassportCrudControllerTest.php ================================================ 1] public array $routeParameters = []; public function setup(): void { parent::setUp(); $this->createInput = $this->updateInput = array_merge($this->model::factory()->make()->toArray(), [ 'pet' => 1, ]); } } ================================================ FILE: tests/Feature/Admin/PetShop/PetCrudControllerTest.php ================================================ 1] public array $routeParameters = []; public function setup(): void { parent::setUp(); $this->createInput = $this->updateInput = array_merge($this->model::factory()->make()->toArray(), [ 'avatar' => [ 'url' => 'https://lorempixel.com/400/200/animals', ], ]); } } ================================================ FILE: tests/Feature/Admin/PetShop/SkillCrudControllerTest.php ================================================ 1] public array $routeParameters = []; } ================================================ FILE: tests/Feature/Admin/ProductCrudControllerTest.php ================================================ 1] public array $routeParameters = []; } ================================================ FILE: tests/Feature/Admin/StoryCrudControllerTest.php ================================================ 1] public array $routeParameters = []; } ================================================ FILE: tests/Feature/Admin/UserCrudControllerTest.php ================================================ 1] public array $routeParameters = []; public function setup(): void { parent::setUp(); $user = $this->model::factory()->raw(); $this->createInput = $this->updateInput = array_merge($user, ['password_confirmation' => $user['password']]); $assertion = $this->testHelper->getDatabaseAssertInput($this->model, $this->createInput); unset($assertion['password']); unset($assertion['password_confirmation']); $this->assertCreateInput = $this->assertUpdateInput = $assertion; } } ================================================ FILE: tests/Feature/Backpack/DefaultCreateTests.php ================================================ get($this->testHelper->getCrudUrl('create')); $response->assertStatus(200); $fields = $this->testHelper->getOperationSetting('fields', [], 'create'); foreach ($fields as $field) { $response->assertSee('name="'.$field['name'].'"', false); } } /** * Test that entry is added to the database. */ public function test_create_endpoint_adds_entry_to_database(): void { $this->skipIfModelDoesNotHaveFactory(); $data = $this->createInput ?? $this->model::factory()->raw(); $response = $this->post($this->testHelper->getCrudUrl(), $data); $response->assertSessionHasNoErrors(); $response->assertStatus(302); $this->assertDatabaseHasModel($this->model, $this->assertCreateInput ?? $this->testHelper->getDatabaseAssertInput($this->model, $data)); } /** * Test that the create form validates wrong form data. */ public function test_create_endpoint_rejects_invalid_input(): void { $response = $this->post($this->testHelper->getCrudUrl(), []); $response->assertStatus(302); $response->assertSessionHasErrors(); } } ================================================ FILE: tests/Feature/Backpack/DefaultDeleteTests.php ================================================ skipIfModelDoesNotHaveFactory(); $entry = $this->model::factory()->create(); $response = $this->delete($this->testHelper->getCrudUrl($entry->getKey())); $response->assertStatus(200); if ($this->testHelper->modelUsesSoftDeletes()) { $this->assertSoftDeleted($entry); } else { $this->assertDatabaseMissing($this->model, [$entry->getKeyName() => $entry->getKey()]); } } } ================================================ FILE: tests/Feature/Backpack/DefaultListTests.php ================================================ get($this->testHelper->getCrudUrl()); $response->assertStatus(200); } public function test_datatables_returns_compatible_data(): void { $this->skipIfModelDoesNotHaveFactory(); $response = $this->post($this->testHelper->getCrudUrl('search')); $response->assertStatus(200); $response->assertJsonStructure([ 'draw', 'recordsTotal', 'recordsFiltered', 'data', ]); } /** * Test that filters are on page. */ public function test_filters_are_on_page(): void { $filters = $this->testHelper->getOperationSetting('filters', [], 'list'); if (count($filters) > 0) { $response = $this->get($this->testHelper->getCrudUrl()); $response->assertStatus(200); foreach ($filters as $filter) { $response->assertSee('filter-name="'.$filter->name.'"', false); } } else { $this->assertTrue(true); } } } ================================================ FILE: tests/Feature/Backpack/DefaultShowTests.php ================================================ skipIfModelDoesNotHaveFactory(); $entry = $this->model::factory()->create(); $response = $this->get($this->testHelper->getCrudUrl($entry->getKey().'/show')); $response->assertStatus(200); } } ================================================ FILE: tests/Feature/Backpack/DefaultTestBase.php ================================================ afterApplicationCreated(function () { $userModel = config('backpack.base.user_model_fqn', 'App\Models\User'); $user = $userModel::find(1) ?? $userModel::factory()->create(); $guard = config('backpack.base.guard') ?? config('auth.defaults.guard'); $this->actingAs($user, $guard); }); parent::setUp(); } } ================================================ FILE: tests/Feature/Backpack/DefaultUpdateTests.php ================================================ skipIfModelDoesNotHaveFactory(); $entry = $this->model::factory()->create(); $response = $this->get($this->testHelper->getCrudUrl($entry->getKey().'/edit')); $response->assertStatus(200); $fields = $this->testHelper->getOperationSetting('fields', [], 'update'); foreach ($fields as $field) { $response->assertSee('name="'.$field['name'].'"', false); } } /** * Test that entry is updated in the database. */ public function test_update_endpoint_modifies_entry_in_database(): void { $this->skipIfModelDoesNotHaveFactory(); $entry = $this->model::factory()->create(); $data = $this->updateInput ?? $this->model::factory()->raw(); $data = array_merge($data, [ $entry->getKeyName() => $entry->getKey(), ]); $response = $this->put($this->testHelper->getCrudUrl($entry->getKey()), $data); $response->assertSessionHasNoErrors(); $response->assertStatus(302); $this->assertDatabaseHasModel($this->model, $this->assertUpdateInput ?? $this->testHelper->getDatabaseAssertInput($this->model, $data)); } } ================================================ FILE: vite.config.js ================================================ import { defineConfig } from 'vite'; import laravel from 'laravel-vite-plugin'; export default defineConfig({ plugins: [ laravel({ input: ['resources/css/app.css', 'resources/js/app.js'], refresh: true, }), ], });