init laravel 10
This commit is contained in:
parent
aa4b5c0fa9
commit
9f95e1e6b5
343 changed files with 26467 additions and 23311 deletions
21
.editorconfig
Normal file
21
.editorconfig
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
root = true
|
||||
|
||||
[*]
|
||||
charset = utf-8
|
||||
end_of_line = lf
|
||||
indent_size = 4
|
||||
indent_style = space
|
||||
insert_final_newline = true
|
||||
trim_trailing_whitespace = true
|
||||
|
||||
[*.md]
|
||||
trim_trailing_whitespace = false
|
||||
|
||||
[*.{yml,yaml}]
|
||||
indent_size = 2
|
||||
|
||||
[docker-compose.yml]
|
||||
indent_size = 4
|
||||
|
||||
[*.vue]
|
||||
indent_size = 2
|
||||
53
.env.example
53
.env.example
|
|
@ -1,19 +1,18 @@
|
|||
APP_NAME=
|
||||
APP_ENV=
|
||||
APP_NAME=Laravel
|
||||
APP_ENV=local
|
||||
APP_KEY=
|
||||
APP_DEBUG=true
|
||||
APP_URL=
|
||||
ASSET_URL=storage/
|
||||
APP_URL=http://localhost
|
||||
|
||||
LOG_CHANNEL=stack
|
||||
LOG_DEPRECATIONS_CHANNEL=null
|
||||
LOG_LEVEL=debug
|
||||
|
||||
DB_CONNECTION=mysql
|
||||
DB_HOST=
|
||||
DB_PORT=
|
||||
DB_DATABASE=
|
||||
DB_USERNAME=
|
||||
DB_HOST=127.0.0.1
|
||||
DB_PORT=3306
|
||||
DB_DATABASE=laravel
|
||||
DB_USERNAME=root
|
||||
DB_PASSWORD=
|
||||
|
||||
BROADCAST_DRIVER=log
|
||||
|
|
@ -23,17 +22,37 @@ QUEUE_CONNECTION=sync
|
|||
SESSION_DRIVER=file
|
||||
SESSION_LIFETIME=120
|
||||
|
||||
MEMCACHED_HOST=127.0.0.1
|
||||
|
||||
REDIS_HOST=127.0.0.1
|
||||
REDIS_PASSWORD=null
|
||||
REDIS_PORT=6379
|
||||
|
||||
MAIL_MAILER=smtp
|
||||
MAIL_HOST=
|
||||
MAIL_PORT=
|
||||
MAIL_USERNAME=
|
||||
MAIL_PASSWORD=
|
||||
MAIL_HOST=mailpit
|
||||
MAIL_PORT=1025
|
||||
MAIL_USERNAME=null
|
||||
MAIL_PASSWORD=null
|
||||
MAIL_ENCRYPTION=null
|
||||
MAIL_FROM_ADDRESS=
|
||||
MAIL_FROM_ADDRESS="hello@example.com"
|
||||
MAIL_FROM_NAME="${APP_NAME}"
|
||||
|
||||
LDC_STATUS_CHECKER_API_KEY="MY_KEY"
|
||||
LDC_STATUS_CHECKER_UUID="UUID_PROJECT"
|
||||
LDC_WEB_API_KEY="MY_KEY"
|
||||
AWS_ACCESS_KEY_ID=
|
||||
AWS_SECRET_ACCESS_KEY=
|
||||
AWS_DEFAULT_REGION=us-east-1
|
||||
AWS_BUCKET=
|
||||
AWS_USE_PATH_STYLE_ENDPOINT=false
|
||||
|
||||
GOOGLE_MAPS_KEY=
|
||||
PUSHER_APP_ID=
|
||||
PUSHER_APP_KEY=
|
||||
PUSHER_APP_SECRET=
|
||||
PUSHER_HOST=
|
||||
PUSHER_PORT=443
|
||||
PUSHER_SCHEME=https
|
||||
PUSHER_APP_CLUSTER=mt1
|
||||
|
||||
VITE_PUSHER_APP_KEY="${PUSHER_APP_KEY}"
|
||||
VITE_PUSHER_HOST="${PUSHER_HOST}"
|
||||
VITE_PUSHER_PORT="${PUSHER_PORT}"
|
||||
VITE_PUSHER_SCHEME="${PUSHER_SCHEME}"
|
||||
VITE_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}"
|
||||
|
|
|
|||
55
.eslintrc.json
Normal file
55
.eslintrc.json
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
{
|
||||
"env": {
|
||||
"browser": true,
|
||||
"es2021": true
|
||||
},
|
||||
"extends": [
|
||||
"eslint:recommended",
|
||||
"plugin:vue/vue3-strongly-recommended",
|
||||
"@vue/eslint-config-typescript"
|
||||
],
|
||||
"overrides": [
|
||||
{
|
||||
"files": ["*.ts", "*.vue"],
|
||||
"rules": {
|
||||
"no-undef": "off"
|
||||
}
|
||||
},
|
||||
{
|
||||
"files": ["*.vue"],
|
||||
"rules": {
|
||||
"indent": "off"
|
||||
}
|
||||
}
|
||||
],
|
||||
"parser": "vue-eslint-parser",
|
||||
"parserOptions": {
|
||||
"parser": "@typescript-eslint/parser",
|
||||
"ecmaVersion": "latest",
|
||||
"sourceType": "module"
|
||||
},
|
||||
"plugins": ["vue", "@typescript-eslint"],
|
||||
"ignorePatterns": ["webpack.mix.js", "**/vendor/*.js", "**/vendor/**/*.js"],
|
||||
"rules": {
|
||||
"indent": ["error", 4, { "SwitchCase": 1 }],
|
||||
"linebreak-style": ["error", "unix"],
|
||||
"quotes": ["error", "double"],
|
||||
"semi": ["error", "always"],
|
||||
"vue/script-indent": ["error", 2, { "baseIndent": 0, "switchCase": 1 }],
|
||||
"vue/one-component-per-file": "off"
|
||||
},
|
||||
"settings": {
|
||||
"import/resolver": {
|
||||
"node": {
|
||||
"extensions": [".js", ".vue", ".ts", ".d.ts"]
|
||||
},
|
||||
"alias": {
|
||||
"extensions": [".vue", ".js", ".ts", ".scss", ".d.ts"],
|
||||
"map": [
|
||||
["~", "./resources/assets"],
|
||||
["@", "./node_modules"]
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
11
.gitattributes
vendored
Normal file
11
.gitattributes
vendored
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
* text=auto eol=lf
|
||||
|
||||
*.blade.php diff=html
|
||||
*.css diff=css
|
||||
*.html diff=html
|
||||
*.md diff=markdown
|
||||
*.php diff=php
|
||||
|
||||
/.github export-ignore
|
||||
CHANGELOG.md export-ignore
|
||||
.styleci.yml export-ignore
|
||||
26
.gitignore
vendored
26
.gitignore
vendored
|
|
@ -1,17 +1,25 @@
|
|||
/node_modules
|
||||
/public/hot
|
||||
/public/storage
|
||||
/public/build
|
||||
/storage/*.key
|
||||
/vendor
|
||||
.env
|
||||
.env.backup
|
||||
.env.production
|
||||
.phpunit.result.cache
|
||||
.stylelintcache
|
||||
/.fleet
|
||||
/.idea
|
||||
/.phpunit.cache
|
||||
/.vscode/launch.json
|
||||
/node_modules
|
||||
/public/build
|
||||
/public/cache
|
||||
/public/hot
|
||||
/public/medias
|
||||
/public/sitemap.xml
|
||||
/public/storage
|
||||
/public/uploads
|
||||
/storage/*.key
|
||||
/vendor
|
||||
auth.json
|
||||
docker-compose.override.yml
|
||||
Homestead.json
|
||||
Homestead.yaml
|
||||
npm-debug.log
|
||||
yarn-error.log
|
||||
/.idea
|
||||
/.vscode
|
||||
auth.json
|
||||
41
.stylelintrc.json
Normal file
41
.stylelintrc.json
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
{
|
||||
"extends": [
|
||||
"stylelint-config-standard-scss",
|
||||
"stylelint-config-sass-guidelines",
|
||||
"stylelint-config-idiomatic-order"
|
||||
],
|
||||
"plugins": ["stylelint-scss"],
|
||||
"files": ["**/*.css", "**/*.scss"],
|
||||
"ignoreFiles": [
|
||||
"**/vendor/*.css",
|
||||
"**/vendor/**/*.css",
|
||||
"**/vendor/*.scss",
|
||||
"**/vendor/**/*.scss",
|
||||
"**/vendor/*.sass",
|
||||
"**/vendor/**/*.sass",
|
||||
"**/vendor/*.less",
|
||||
"**/vendor/**/*.less",
|
||||
"**/vendor/*.vue",
|
||||
"**/vendor/**/*.vue"
|
||||
],
|
||||
"customSyntax": "postcss-scss",
|
||||
"rules": {
|
||||
"indentation": 4,
|
||||
"string-quotes": "double",
|
||||
"selector-max-id": null,
|
||||
"color-no-invalid-hex": true,
|
||||
"order/properties-alphabetical-order": null,
|
||||
"max-nesting-depth": 5,
|
||||
"selector-max-compound-selectors": 5,
|
||||
"scss/double-slash-comment-empty-line-before": [
|
||||
"always",
|
||||
{
|
||||
"ignore": [
|
||||
"between-comments",
|
||||
"stylelint-commands",
|
||||
"inside-block"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
23
.vscode/settings.json
vendored
Normal file
23
.vscode/settings.json
vendored
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
{
|
||||
"workbench.colorCustomizations": {
|
||||
"activityBar.activeBackground": "#d6de61",
|
||||
"activityBar.activeBorder": "#1a1d02",
|
||||
"activityBar.background": "#d6de61",
|
||||
"activityBar.foreground": "#15202b",
|
||||
"activityBar.inactiveForeground": "#15202b99",
|
||||
"activityBarBadge.background": "#21969e",
|
||||
"activityBarBadge.foreground": "#e7e7e7",
|
||||
"sash.hoverBorder": "#d6de61",
|
||||
"statusBar.background": "#cbd537",
|
||||
"statusBar.foreground": "#15202b",
|
||||
"statusBarItem.hoverBackground": "#aab326",
|
||||
"statusBarItem.remoteBackground": "#cbd537",
|
||||
"statusBarItem.remoteForeground": "#15202b",
|
||||
"titleBar.activeBackground": "#cbd537",
|
||||
"titleBar.activeForeground": "#15202b",
|
||||
"titleBar.inactiveBackground": "#cbd53799",
|
||||
"titleBar.inactiveForeground": "#15202b99",
|
||||
"commandCenter.border": "#15202b99"
|
||||
},
|
||||
"peacock.remoteColor": "#CBD537"
|
||||
}
|
||||
|
|
@ -1,4 +0,0 @@
|
|||
FROM registry.gitlab.com/service-web-lab/ldc-web-images-docker/ldcweb-production:php8.1.1
|
||||
COPY --chown=noroot:noroot . /app/srcs
|
||||
COPY --chown=noroot:noroot ./public/build /app/srcs/public/build
|
||||
COPY --chown=noroot:noroot ./vendor /app/srcs/vendor
|
||||
76
README.md
76
README.md
|
|
@ -1,16 +1,66 @@
|
|||
# Wenn dann mit Respekt
|
||||
<p align="center"><a href="https://laravel.com" target="_blank"><img src="https://raw.githubusercontent.com/laravel/art/master/logo-lockup/5%20SVG/2%20CMYK/1%20Full%20Color/laravel-logolockup-cmyk-red.svg" width="400" alt="Laravel Logo"></a></p>
|
||||
|
||||
## Crons
|
||||
Put every min in PROD :
|
||||
```
|
||||
php artisan schedule:run
|
||||
```
|
||||
<p align="center">
|
||||
<a href="https://github.com/laravel/framework/actions"><img src="https://github.com/laravel/framework/workflows/tests/badge.svg" alt="Build Status"></a>
|
||||
<a href="https://packagist.org/packages/laravel/framework"><img src="https://img.shields.io/packagist/dt/laravel/framework" alt="Total Downloads"></a>
|
||||
<a href="https://packagist.org/packages/laravel/framework"><img src="https://img.shields.io/packagist/v/laravel/framework" alt="Latest Stable Version"></a>
|
||||
<a href="https://packagist.org/packages/laravel/framework"><img src="https://img.shields.io/packagist/l/laravel/framework" alt="License"></a>
|
||||
</p>
|
||||
|
||||
## Available Commands
|
||||
```
|
||||
ldc:status-report
|
||||
ldc:send-status-report
|
||||
ldcweb:admin-secure-sync
|
||||
## About Laravel
|
||||
|
||||
sentry:test
|
||||
```
|
||||
Laravel is a web application framework with expressive, elegant syntax. We believe development must be an enjoyable and creative experience to be truly fulfilling. Laravel takes the pain out of development by easing common tasks used in many web projects, such as:
|
||||
|
||||
- [Simple, fast routing engine](https://laravel.com/docs/routing).
|
||||
- [Powerful dependency injection container](https://laravel.com/docs/container).
|
||||
- Multiple back-ends for [session](https://laravel.com/docs/session) and [cache](https://laravel.com/docs/cache) storage.
|
||||
- Expressive, intuitive [database ORM](https://laravel.com/docs/eloquent).
|
||||
- Database agnostic [schema migrations](https://laravel.com/docs/migrations).
|
||||
- [Robust background job processing](https://laravel.com/docs/queues).
|
||||
- [Real-time event broadcasting](https://laravel.com/docs/broadcasting).
|
||||
|
||||
Laravel is accessible, powerful, and provides tools required for large, robust applications.
|
||||
|
||||
## Learning Laravel
|
||||
|
||||
Laravel has the most extensive and thorough [documentation](https://laravel.com/docs) and video tutorial library of all modern web application frameworks, making it a breeze to get started with the framework.
|
||||
|
||||
You may also try the [Laravel Bootcamp](https://bootcamp.laravel.com), where you will be guided through building a modern Laravel application from scratch.
|
||||
|
||||
If you don't feel like reading, [Laracasts](https://laracasts.com) can help. Laracasts contains over 2000 video tutorials on a range of topics including Laravel, modern PHP, unit testing, and JavaScript. Boost your skills by digging into our comprehensive video library.
|
||||
|
||||
## Laravel Sponsors
|
||||
|
||||
We would like to extend our thanks to the following sponsors for funding Laravel development. If you are interested in becoming a sponsor, please visit the Laravel [Patreon page](https://patreon.com/taylorotwell).
|
||||
|
||||
### Premium Partners
|
||||
|
||||
- **[Vehikl](https://vehikl.com/)**
|
||||
- **[Tighten Co.](https://tighten.co)**
|
||||
- **[Kirschbaum Development Group](https://kirschbaumdevelopment.com)**
|
||||
- **[64 Robots](https://64robots.com)**
|
||||
- **[Cubet Techno Labs](https://cubettech.com)**
|
||||
- **[Cyber-Duck](https://cyber-duck.co.uk)**
|
||||
- **[Many](https://www.many.co.uk)**
|
||||
- **[Webdock, Fast VPS Hosting](https://www.webdock.io/en)**
|
||||
- **[DevSquad](https://devsquad.com)**
|
||||
- **[Curotec](https://www.curotec.com/services/technologies/laravel/)**
|
||||
- **[OP.GG](https://op.gg)**
|
||||
- **[WebReinvent](https://webreinvent.com/?utm_source=laravel&utm_medium=github&utm_campaign=patreon-sponsors)**
|
||||
- **[Lendio](https://lendio.com)**
|
||||
|
||||
## Contributing
|
||||
|
||||
Thank you for considering contributing to the Laravel framework! The contribution guide can be found in the [Laravel documentation](https://laravel.com/docs/contributions).
|
||||
|
||||
## Code of Conduct
|
||||
|
||||
In order to ensure that the Laravel community is welcoming to all, please review and abide by the [Code of Conduct](https://laravel.com/docs/contributions#code-of-conduct).
|
||||
|
||||
## Security Vulnerabilities
|
||||
|
||||
If you discover a security vulnerability within Laravel, please send an e-mail to Taylor Otwell via [taylor@laravel.com](mailto:taylor@laravel.com). All security vulnerabilities will be promptly addressed.
|
||||
|
||||
## License
|
||||
|
||||
The Laravel framework is open-sourced software licensed under the [MIT license](https://opensource.org/licenses/MIT).
|
||||
|
|
|
|||
|
|
@ -1,7 +0,0 @@
|
|||
PHP 8.0.2
|
||||
Laravel 9.2
|
||||
Voyager 1.5
|
||||
Mysql 5.7.20
|
||||
nodejs v16.14.2
|
||||
npm 8.7.0
|
||||
Composer version 2.2.9
|
||||
|
|
@ -1,9 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace App;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class Concept extends Model
|
||||
{
|
||||
}
|
||||
177
app/Console/Commands/CreateAdmin.php
Normal file
177
app/Console/Commands/CreateAdmin.php
Normal file
|
|
@ -0,0 +1,177 @@
|
|||
<?php
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use App\Models\User;
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
|
||||
class CreateAdmin extends Command
|
||||
{
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'user:create';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'Create a backend admin user';
|
||||
|
||||
/**
|
||||
* The firstname of the new user.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $firstname;
|
||||
|
||||
/**
|
||||
* The lastname of the new user.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $lastname;
|
||||
|
||||
/**
|
||||
* The email of the new user.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $email;
|
||||
|
||||
/**
|
||||
* The password of the new user.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $password;
|
||||
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*
|
||||
* @return integer
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
$this->firstname = null;
|
||||
$this->addFirstname();
|
||||
|
||||
$this->lastname = null;
|
||||
$this->addLastname();
|
||||
|
||||
$this->email = null;
|
||||
$this->addEmail();
|
||||
|
||||
$this->password = null;
|
||||
$this->addPassword();
|
||||
|
||||
$user = new User([
|
||||
'firstname' => $this->firstname,
|
||||
'lastname' => $this->lastname,
|
||||
'email' => $this->email,
|
||||
'password' => $this->password,
|
||||
]);
|
||||
$user->saveOrFail();
|
||||
|
||||
$this->info('User created 👌');
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a firstname to the user.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function addFirstname(): void
|
||||
{
|
||||
while (is_null($this->firstname)) {
|
||||
try {
|
||||
$tmp = $this->ask('Type the wanted user firstname', 'Admin');
|
||||
$validator = Validator::make(['firstname' => $tmp], [
|
||||
'firstname' => 'required|min:3|max:255'
|
||||
]);
|
||||
$validator->validate();
|
||||
$this->firstname = $tmp;
|
||||
} catch (ValidationException $e) {
|
||||
$this->error(sprintf(
|
||||
'Please provide a valid firstname %s',
|
||||
\implode(',', collect($e->errors())->flatten()->all())
|
||||
));
|
||||
continue;
|
||||
} //end try
|
||||
}; //end while
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a lastname to the user.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function addLastname(): void
|
||||
{
|
||||
while (is_null($this->lastname)) {
|
||||
try {
|
||||
$tmp = $this->ask('Type the wanted user lastname', 'Saïtama');
|
||||
$validator = Validator::make(['lastname' => $tmp], [
|
||||
'lastname' => 'required|min:3|max:255'
|
||||
]);
|
||||
$validator->validate();
|
||||
$this->lastname = $tmp;
|
||||
} catch (ValidationException $e) {
|
||||
$this->error(sprintf(
|
||||
'Please provide a valid lastname %s',
|
||||
\implode(',', collect($e->errors())->flatten()->all())
|
||||
));
|
||||
continue;
|
||||
} //end try
|
||||
}; //end while
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an email to the user.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function addEmail(): void
|
||||
{
|
||||
while (is_null($this->email)) {
|
||||
try {
|
||||
$tmp = $this->ask('Type the wanted user email', 'equipe.web@ldc.fr');
|
||||
$validator = Validator::make(['email' => $tmp], [
|
||||
'email' => 'required|unique:users,email|email:rfc,dns'
|
||||
]);
|
||||
$validator->validate();
|
||||
$this->email = $tmp;
|
||||
} catch (ValidationException $e) {
|
||||
$this->error(sprintf(
|
||||
'Please provide a valid email %s',
|
||||
\implode(',', collect($e->errors())->flatten()->all())
|
||||
));
|
||||
continue;
|
||||
} //end try
|
||||
}; //end while
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a password to the user.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function addPassword(): void
|
||||
{
|
||||
while (
|
||||
($this->password = $this->secret(
|
||||
(!\is_null($this->password) ? 'Failed to confirm, ' : '') . 'Type the wanted user password'
|
||||
)) !== $this->secret('Confirm the password')
|
||||
) {
|
||||
continue;
|
||||
}; //end while
|
||||
}
|
||||
}
|
||||
|
|
@ -1,9 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace App;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class Content extends Model
|
||||
{
|
||||
}
|
||||
0
app/Enums/.gitkeep
Normal file
0
app/Enums/.gitkeep
Normal file
|
|
@ -7,21 +7,12 @@ use Throwable;
|
|||
|
||||
class Handler extends ExceptionHandler
|
||||
{
|
||||
/**
|
||||
* A list of exception types with their corresponding custom log levels.
|
||||
*
|
||||
* @var array<class-string<\Throwable>, \Psr\Log\LogLevel::*>
|
||||
*/
|
||||
protected $levels = [
|
||||
];
|
||||
|
||||
/**
|
||||
* A list of the exception types that are not reported.
|
||||
*
|
||||
* @var array<int, class-string<\Throwable>>
|
||||
* @var array<int, class-string<Throwable>>
|
||||
*/
|
||||
protected $dontReport = [
|
||||
];
|
||||
protected $dontReport = [];
|
||||
|
||||
/**
|
||||
* A list of the inputs that are never flashed for validation exceptions.
|
||||
|
|
@ -42,9 +33,6 @@ class Handler extends ExceptionHandler
|
|||
public function register()
|
||||
{
|
||||
$this->reportable(function (Throwable $e) {
|
||||
if (app()->bound('sentry')) {
|
||||
app('sentry')->captureException($e);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,9 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace App;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class Home extends Model
|
||||
{
|
||||
}
|
||||
51
app/Http/Controllers/Bo/Auth/LoginController.php
Normal file
51
app/Http/Controllers/Bo/Auth/LoginController.php
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Bo\Auth;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Foundation\Auth\AuthenticatesUsers;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
|
||||
class LoginController extends Controller
|
||||
{
|
||||
use AuthenticatesUsers;
|
||||
|
||||
/**
|
||||
* Create a new controller instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->middleware('guest:backend')->except('logout');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the guard to be used during authentication.
|
||||
*
|
||||
* @return \Illuminate\Contracts\Auth\StatefulGuard
|
||||
*/
|
||||
protected function guard()
|
||||
{
|
||||
return Auth::guard('backend');
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the application's login form.
|
||||
*
|
||||
* @return \Illuminate\View\View
|
||||
*/
|
||||
public function showLoginForm()
|
||||
{
|
||||
return view('bo.auth.login');
|
||||
}
|
||||
|
||||
/**
|
||||
* Where to redirect users after login.
|
||||
* @return string
|
||||
*/
|
||||
protected function redirectTo(): string
|
||||
{
|
||||
return response()->redirectToIntended()->getTargetUrl();
|
||||
}
|
||||
}
|
||||
31
app/Http/Controllers/Bo/Auth/ResetPasswordController.php
Normal file
31
app/Http/Controllers/Bo/Auth/ResetPasswordController.php
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Bo\Auth;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Foundation\Auth\ResetsPasswords;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
|
||||
class ResetPasswordController extends Controller
|
||||
{
|
||||
use ResetsPasswords;
|
||||
|
||||
/**
|
||||
* Get the guard to be used during authentication.
|
||||
*
|
||||
* @return \Illuminate\Contracts\Auth\StatefulGuard
|
||||
*/
|
||||
protected function guard()
|
||||
{
|
||||
return Auth::guard('backend');
|
||||
}
|
||||
|
||||
/**
|
||||
* Where to redirect users after login.
|
||||
* @return string
|
||||
*/
|
||||
protected function redirectTo(): string
|
||||
{
|
||||
return \route('bo.login');
|
||||
}
|
||||
}
|
||||
18
app/Http/Controllers/Bo/DashboardController.php
Normal file
18
app/Http/Controllers/Bo/DashboardController.php
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Bo;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
|
||||
class DashboardController extends Controller
|
||||
{
|
||||
/**
|
||||
* Dashboard Page
|
||||
*
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
return view('bo.pages.dashboard');
|
||||
}
|
||||
}
|
||||
|
|
@ -1,53 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Mail;
|
||||
|
||||
class ContactController extends Controller
|
||||
{
|
||||
/**
|
||||
* Show contact page
|
||||
*
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function contactForm()
|
||||
{
|
||||
return view('pages.kontakt');
|
||||
}
|
||||
|
||||
/**
|
||||
* Submit contact form
|
||||
*
|
||||
* @param Request $request
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function sendContactForm(Request $request)
|
||||
{
|
||||
$request->validate(
|
||||
[
|
||||
'vorname' => 'required',
|
||||
'nachname' => 'required',
|
||||
'email' => 'required|email',
|
||||
'nachricht' => 'required',
|
||||
'datenschutz' => 'required',
|
||||
]
|
||||
);
|
||||
|
||||
$mailDatas = [
|
||||
'vorname' => $request->vorname,
|
||||
'nachname' => $request->nachname,
|
||||
'email' => $request->email,
|
||||
'nachricht' => $request->nachricht,
|
||||
];
|
||||
|
||||
Mail::send('contactMail', $mailDatas, function ($message) {
|
||||
$message->from('info@wenndannmitrespekt.de', 'Kontaktformular wenndannmitrespekt.de');
|
||||
$message->to('kontakt@wenndannmitrespekt.de', 'kontakt@wenndannmitrespekt.de')
|
||||
->subject('Kontaktformular wenndannmitrespekt.de');
|
||||
});
|
||||
|
||||
return redirect()->back()->with(['success' => 'Vielen Dank für Ihre Nachricht.']);
|
||||
}
|
||||
}
|
||||
|
|
@ -2,14 +2,124 @@
|
|||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
|
||||
use Illuminate\Foundation\Bus\DispatchesJobs;
|
||||
use Illuminate\Foundation\Validation\ValidatesRequests;
|
||||
use Illuminate\Routing\Controller as BaseController;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Support\Facades\Session;
|
||||
|
||||
class Controller extends BaseController
|
||||
{
|
||||
use AuthorizesRequests;
|
||||
use DispatchesJobs;
|
||||
use ValidatesRequests;
|
||||
|
||||
/**
|
||||
* Build Search query on specified fields
|
||||
* splitting search into words or using whole sentence
|
||||
*
|
||||
* @param \Illuminate\Database\Eloquent\Builder $query The eloquent query builder.
|
||||
* @param string $search The query string.
|
||||
* @param callable $searchQuery The query string.
|
||||
* @param string ...$fields Either a simple array or a string
|
||||
* in case of a string the two fields
|
||||
* would be concatenate to make the search.
|
||||
* @return \Illuminate\Database\Eloquent\Builder
|
||||
*/
|
||||
protected function searchQuery(
|
||||
Builder $query,
|
||||
string $search,
|
||||
callable $searchQuery = null,
|
||||
string ...$fields
|
||||
): Builder {
|
||||
if (count($fields)) {
|
||||
// Search using words.
|
||||
$words = explode(' ', $search);
|
||||
$query->where(function ($query) use ($searchQuery, $words, $search, $fields) {
|
||||
foreach ($words as $word) {
|
||||
if (!strlen($word)) {
|
||||
continue;
|
||||
}
|
||||
$this->searchOnFields($query, $word, $fields);
|
||||
} //end foreach
|
||||
// Search whole using whole sentence.
|
||||
$this->searchOnFields($query, $search, $fields);
|
||||
if ($searchQuery) {
|
||||
$searchQuery($query);
|
||||
}
|
||||
});
|
||||
} //end if
|
||||
return $query;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build query search on all fields
|
||||
*
|
||||
* @param \Illuminate\Database\Eloquent\Builder $query
|
||||
* @param string $search
|
||||
* @param array $fields
|
||||
* @return \Illuminate\Database\Eloquent\Builder
|
||||
*/
|
||||
private function searchOnFields(Builder $query, string $search, array $fields): Builder
|
||||
{
|
||||
$table = $query->getModel()->getTable();
|
||||
foreach ($fields as $f) {
|
||||
$f = str_replace('?', '\?', $f);
|
||||
if (is_array($f)) {
|
||||
$query->orWhereRaw(
|
||||
sprintf("UPPER(CONCAT(%s)) LIKE UPPER(?)", collect($f)->map(function ($q) use ($table) {
|
||||
return "`$table`.`$q`";
|
||||
})->implode(', \' \', ')),
|
||||
['%' . filter_var($search, FILTER_SANITIZE_STRING) . '%']
|
||||
);
|
||||
} else {
|
||||
$query->orWhereRaw(
|
||||
"UPPER(`$table`.`$f`) LIKE UPPER(?)",
|
||||
['%' . filter_var($search, FILTER_SANITIZE_STRING) . '%']
|
||||
);
|
||||
}
|
||||
}
|
||||
return $query;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sort columns with a query
|
||||
*
|
||||
* @param \Illuminate\Database\Eloquent\Builder $query
|
||||
* @param array $ignore
|
||||
* @return \Illuminate\Database\Eloquent\Builder
|
||||
*/
|
||||
protected function sortQuery(Builder $query, array $ignore = []): Builder
|
||||
{
|
||||
$rName = request()->route()->getName();
|
||||
$table = $query->getModel()->getTable();
|
||||
if (request()->sort_col) {
|
||||
Session::put("$rName.sort_col", request()->sort_col);
|
||||
Session::put("$rName.sorted", true);
|
||||
}
|
||||
if (request()->sort_way) {
|
||||
Session::put("$rName.sort_way", request()->sort_way);
|
||||
Session::put("$rName.sorted", true);
|
||||
}
|
||||
if (request()->rst) {
|
||||
Session::remove("$rName.sorted");
|
||||
Session::remove("$rName.sort_col");
|
||||
Session::remove("$rName.sort_way");
|
||||
}
|
||||
if (request()->sort_col and request()->sort_way and Schema::hasColumn($table, request()->sort_col)) {
|
||||
if (
|
||||
!isset($ignore) or
|
||||
(isset($ignore) and !in_array(request()->sort_col, $ignore))
|
||||
) {
|
||||
$query = $query->orderBy(\sprintf("$table.%s", request()->sort_col), request()->sort_way);
|
||||
}
|
||||
} elseif (Schema::hasColumn($table, 'order')) {
|
||||
$query = $query->orderBy('order', 'ASC');
|
||||
Session::put("$rName.sort_col", 'order');
|
||||
Session::put("$rName.sort_way", 'asc');
|
||||
}
|
||||
return $query;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
18
app/Http/Controllers/Fo/HomeController.php
Normal file
18
app/Http/Controllers/Fo/HomeController.php
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Fo;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
|
||||
class HomeController extends Controller
|
||||
{
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
return view('fo.pages.home');
|
||||
}
|
||||
}
|
||||
|
|
@ -1,19 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Retailgroup;
|
||||
|
||||
class GroupController extends Controller
|
||||
{
|
||||
/**
|
||||
* RetailGroup Show
|
||||
*
|
||||
* @param integer $id
|
||||
* @return \App\Retailgroup
|
||||
*/
|
||||
public function show(int $id)
|
||||
{
|
||||
return Retailgroup::find($id);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,23 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Page;
|
||||
|
||||
class PageController extends Controller
|
||||
{
|
||||
/**
|
||||
* Page show
|
||||
*
|
||||
* @param string $slug
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function index(string $slug)
|
||||
{
|
||||
$page = Page::where('slug', $slug)->first();
|
||||
if ($page == null) {
|
||||
abort(404);
|
||||
}
|
||||
return view('pages.page', compact('page'));
|
||||
}
|
||||
}
|
||||
|
|
@ -1,38 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Product;
|
||||
|
||||
class ProductController extends Controller
|
||||
{
|
||||
/**
|
||||
* Products index
|
||||
*
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
$products = Product::all()->sortby('sequence')->reverse()->groupBy('poultry');
|
||||
$poultries = $products->keys()->sort();
|
||||
return view('pages.produkte', compact(['products', 'poultries']));
|
||||
}
|
||||
|
||||
/**
|
||||
* Product show
|
||||
*
|
||||
* @param mixed $id
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function show(mixed $id)
|
||||
{
|
||||
$product = Product::where('id', $id)->first();
|
||||
if ($product == null) {
|
||||
$product = Product::where('slug', $id)->first();
|
||||
if ($product == null) {
|
||||
abort(404);
|
||||
}
|
||||
}
|
||||
return view('pages.produkt', compact('product'));
|
||||
}
|
||||
}
|
||||
|
|
@ -1,42 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Recipe;
|
||||
|
||||
class RecipeController extends Controller
|
||||
{
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
// Get recipies.
|
||||
$recipes = Recipe::where('live', '1')->get();
|
||||
// Filter poultry.
|
||||
$poultries = $recipes->unique('cat')->pluck('cat');
|
||||
// Filter difficulty.
|
||||
$difficulties = $recipes->unique('difficulty')->pluck('difficulty');
|
||||
return view('pages.rezepte', compact(['recipes', 'poultries', 'difficulties']));
|
||||
}
|
||||
|
||||
/**
|
||||
* Recipe show
|
||||
*
|
||||
* @param mixed $id
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function show(mixed $id)
|
||||
{
|
||||
$recipe = Recipe::where('id', $id)->first();
|
||||
if ($recipe == null) {
|
||||
$recipe = Recipe::where('slug', $id)->first();
|
||||
if ($recipe == null) {
|
||||
abort(404);
|
||||
}
|
||||
}
|
||||
return view('pages.rezept', compact(['recipe']));
|
||||
}
|
||||
}
|
||||
|
|
@ -1,19 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Retailregion;
|
||||
|
||||
class RegionController extends Controller
|
||||
{
|
||||
/**
|
||||
* Show retail region
|
||||
*
|
||||
* @param integer $id
|
||||
* @return \App\Retailregion;
|
||||
*/
|
||||
public function show(int $id)
|
||||
{
|
||||
return Retailregion::find($id);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,48 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class StoreController extends Controller
|
||||
{
|
||||
/**
|
||||
* Store by city
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param mixed $city
|
||||
* @return \App\Store;
|
||||
*/
|
||||
public function city(Request $request, mixed $city)
|
||||
{
|
||||
// CSRF Token check.
|
||||
if (
|
||||
!(is_string($request->session()->token()) &&
|
||||
is_string($request->header('X-CSRF-TOKEN')) &&
|
||||
hash_equals($request->session()->token(), $request->header('X-CSRF-TOKEN')))
|
||||
) {
|
||||
\abort(419);
|
||||
}
|
||||
|
||||
if (is_numeric($city)) {
|
||||
$stores = DB::table('stores')
|
||||
->join('retailregions', 'stores.region_id', '=', 'retailregions.id')
|
||||
->join('retailgroups', 'retailregions.region_group', '=', 'retailgroups.id')
|
||||
->select('stores.*', 'retailregions.*', 'retailgroups.*')
|
||||
->where('stores.zipcode', $city)
|
||||
->get();
|
||||
|
||||
return $stores;
|
||||
} else {
|
||||
$stores = DB::table('stores')
|
||||
->join('retailregions', 'stores.region_id', '=', 'retailregions.id')
|
||||
->join('retailgroups', 'retailregions.region_group', '=', 'retailgroups.id')
|
||||
->select('stores.*', 'retailregions.*', 'retailgroups.*')
|
||||
->where('stores.city', $city)
|
||||
->get();
|
||||
|
||||
return $stores;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -16,7 +16,6 @@ class Kernel extends HttpKernel
|
|||
protected $middleware = [
|
||||
\App\Http\Middleware\TrustHosts::class,
|
||||
\App\Http\Middleware\TrustProxies::class,
|
||||
\Illuminate\Http\Middleware\HandleCors::class,
|
||||
\App\Http\Middleware\PreventRequestsDuringMaintenance::class,
|
||||
\Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
|
||||
\App\Http\Middleware\TrimStrings::class,
|
||||
|
|
@ -30,12 +29,14 @@ class Kernel extends HttpKernel
|
|||
*/
|
||||
protected $middlewareGroups = [
|
||||
'web' => [
|
||||
'htmlsanitize',
|
||||
\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,
|
||||
\Illuminate\Routing\Middleware\SubstituteBindings::class,
|
||||
\App\Http\Middleware\SecureHeaders::class
|
||||
],
|
||||
|
||||
'api' => [
|
||||
|
|
@ -54,7 +55,6 @@ class Kernel extends HttpKernel
|
|||
protected $routeMiddleware = [
|
||||
'auth' => \App\Http\Middleware\Authenticate::class,
|
||||
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
|
||||
'auth.session' => \Illuminate\Session\Middleware\AuthenticateSession::class,
|
||||
'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,
|
||||
'can' => \Illuminate\Auth\Middleware\Authorize::class,
|
||||
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
|
||||
|
|
@ -62,5 +62,6 @@ class Kernel extends HttpKernel
|
|||
'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class,
|
||||
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
|
||||
'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
|
||||
'htmlsanitize' => \App\Http\Middleware\HtmlSanitizer::class,
|
||||
];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,20 +3,35 @@
|
|||
namespace App\Http\Middleware;
|
||||
|
||||
use Illuminate\Auth\Middleware\Authenticate as Middleware;
|
||||
use Illuminate\Support\Facades\Session;
|
||||
|
||||
class Authenticate extends Middleware
|
||||
{
|
||||
/**
|
||||
* Get the path the user should be redirected to when they are not authenticated.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param mixed $request
|
||||
* @return string|null
|
||||
* @phpcs:disable Squiz.Commenting.FunctionComment.TypeHintMissing
|
||||
*/
|
||||
protected function redirectTo($request)
|
||||
{
|
||||
if (! $request->expectsJson()) {
|
||||
$logins = [
|
||||
'backend' => route('bo.login')
|
||||
];
|
||||
if (!$request->expectsJson()) {
|
||||
// * Notify must login
|
||||
Session::flash('warning', trans('Veuillez vous connecter pour continuer'));
|
||||
|
||||
foreach ($request->route()->gatherMiddleware() as $middleware) {
|
||||
if (\is_string($middleware) and strpos($middleware, 'auth:') !== false) {
|
||||
$route = $logins[str_replace('auth:', '', $middleware)] ?? null;
|
||||
if ($route) {
|
||||
return $route;
|
||||
}
|
||||
}
|
||||
}
|
||||
return route('login');
|
||||
}
|
||||
abort(401);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,6 +11,5 @@ class EncryptCookies extends Middleware
|
|||
*
|
||||
* @var array<int, string>
|
||||
*/
|
||||
protected $except = [
|
||||
];
|
||||
protected $except = [];
|
||||
}
|
||||
|
|
|
|||
53
app/Http/Middleware/HtmlSanitizer.php
Normal file
53
app/Http/Middleware/HtmlSanitizer.php
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use App\Lib\Helpers\ToolboxHelper;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class HtmlSanitizer
|
||||
{
|
||||
/**
|
||||
* Handle an incoming request.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param \Closure $next
|
||||
* @param mixed ...$params
|
||||
* @return mixed
|
||||
*/
|
||||
public function handle(Request $request, \Closure $next, ...$params)
|
||||
{
|
||||
$inputs = $request->all();
|
||||
/** @var callable|null */
|
||||
$cleanInput = null;
|
||||
$cleanInput = function (&$input, $name, $rootName = null) use ($params, &$cleanInput) {
|
||||
// * Nested element array
|
||||
if (is_array($input)) {
|
||||
array_walk_recursive($input, $cleanInput, $name);
|
||||
}
|
||||
if (!is_string($input)) {
|
||||
return;
|
||||
}
|
||||
if (in_array($name, $params) or in_array($rootName ?? $name, $params)) {
|
||||
// ? Is a json input ?
|
||||
if ($isJson = \json_decode($input, true) and is_array($isJson)) {
|
||||
// ! Decode each json field recursive.
|
||||
\array_walk_recursive($isJson, function (&$item) {
|
||||
if (\is_string($item)) {
|
||||
$item = clean($item);
|
||||
$item = ToolboxHelper::stripCkEditorSchemesOnMediaInputs($item);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
$input = clean($input);
|
||||
$input = ToolboxHelper::stripCkEditorSchemesOnMediaInputs($input);
|
||||
}
|
||||
} else {
|
||||
$input = strip_tags($input);
|
||||
}
|
||||
};
|
||||
\array_walk($inputs, $cleanInput);
|
||||
$request->merge($inputs);
|
||||
return $next($request);
|
||||
}
|
||||
}
|
||||
|
|
@ -11,6 +11,5 @@ class PreventRequestsDuringMaintenance extends Middleware
|
|||
*
|
||||
* @var array<int, string>
|
||||
*/
|
||||
protected $except = [
|
||||
];
|
||||
protected $except = [];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@
|
|||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use App\Providers\RouteServiceProvider;
|
||||
use Closure;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
|
|
@ -12,10 +11,13 @@ class RedirectIfAuthenticated
|
|||
/**
|
||||
* Handle an incoming request.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param \Closure $next
|
||||
* @param string|null ...$guards
|
||||
* @phpcs:disable Generic.Files.LineLength.TooLong
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param \Closure(\Illuminate\Http\Request): (\Illuminate\Http\Response|\Illuminate\Http\RedirectResponse) $next
|
||||
* @param string|null ...$guards
|
||||
* @return \Illuminate\Http\Response|\Illuminate\Http\RedirectResponse
|
||||
* @throws \RuntimeException If guard is unhandled.
|
||||
* @phpcs:enable
|
||||
*/
|
||||
public function handle(Request $request, Closure $next, ...$guards)
|
||||
{
|
||||
|
|
@ -23,7 +25,14 @@ class RedirectIfAuthenticated
|
|||
|
||||
foreach ($guards as $guard) {
|
||||
if (Auth::guard($guard)->check()) {
|
||||
return redirect(RouteServiceProvider::HOME);
|
||||
switch ($guard) {
|
||||
case 'frontend':
|
||||
return \redirect()->route('home');
|
||||
case 'backend':
|
||||
return \redirect()->route('bo.dashboard');
|
||||
default:
|
||||
throw new \RuntimeException("Unhandled guard `{$guard}` .");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
100
app/Http/Middleware/SecureHeaders.php
Normal file
100
app/Http/Middleware/SecureHeaders.php
Normal file
|
|
@ -0,0 +1,100 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Closure;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Route;
|
||||
use Illuminate\Support\Facades\View;
|
||||
use Illuminate\Support\Facades\Vite;
|
||||
|
||||
class SecureHeaders
|
||||
{
|
||||
/**
|
||||
* Enumerate headers which you do not want in your application's responses.
|
||||
* Great starting point would be to go check out @Scott_Helme's:
|
||||
* https://securityheaders.com/
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $unwantedHeaderList = [
|
||||
'X-Powered-By',
|
||||
'Server',
|
||||
];
|
||||
|
||||
/**
|
||||
* Handle an incoming request.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param \Closure $next
|
||||
* @return \Illuminate\Http\Response|\Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function handle(Request $request, Closure $next)
|
||||
{
|
||||
View::share('nonce', $nonce = Vite::useCspNonce());
|
||||
// * For VueJS dev tool to execute
|
||||
$jsDev = config('app.debug') ? "'unsafe-eval' 'unsafe-inline'" : "'nonce-{$nonce}' 'strict-dynamic'";
|
||||
$scheme = config('app.env') === 'local' ? 'http' : 'https';
|
||||
$reportUri = Route::has('cspReportUri') ?
|
||||
\sprintf(' report-uri %s ;', \parse_url(route('cspReportUri'), \PHP_URL_PATH)) : '';
|
||||
$this->removeUnwantedHeaders($this->unwantedHeaderList);
|
||||
$response = $next($request);
|
||||
$response->headers->set('Referrer-Policy', 'no-referrer-when-downgrade');
|
||||
$response->headers->set('X-Content-Type-Options', 'nosniff');
|
||||
$response->headers->set('X-XSS-Protection', '1; mode=block');
|
||||
$response->headers->set('X-Frame-Options', 'SAMEORIGIN');
|
||||
$response->headers->set('Strict-Transport-Security', 'max-age=31536000; includeSubDomains;');
|
||||
$cspPolicies = [
|
||||
"default-src 'none';",
|
||||
"manifest-src 'self';",
|
||||
// * CKEDITOR Specific https://ckeditor.com/docs/ckeditor5/latest/installation/advanced/csp.html
|
||||
"connect-src 'self' blob:;",
|
||||
"img-src * data: blob:;",
|
||||
'frame-src ' . implode(' ', [
|
||||
'https://www.google.com/recaptcha/',
|
||||
'https://recaptcha.google.com/recaptcha/',
|
||||
'https://www.google.com/maps/'
|
||||
]) . ';',
|
||||
"font-src 'self' data: https://fonts.gstatic.com;",
|
||||
// ! Using CKEditor will must have unsafe-inline style
|
||||
// phpcs:ignore Generic.Files.LineLength.TooLong
|
||||
"style-src 'self' 'unsafe-inline' " . \implode(' ', [
|
||||
'https://cdnjs.cloudflare.com',
|
||||
// * File Manager
|
||||
'https://fonts.googleapis.com',
|
||||
'https://cdn.jsdelivr.net',
|
||||
'https://use.fontawesome.com',
|
||||
'https://fonts.googleapis.com'
|
||||
]) . ';',
|
||||
// ! If you dont use ckeditor use this
|
||||
// "style-src 'self' 'nonce-$nonce';",
|
||||
// phpcs:ignore Generic.Files.LineLength.TooLong
|
||||
"script-src 'self' {$jsDev} " . \implode(' ', [
|
||||
'https: blob:',
|
||||
'https://www.googletagmanager.com',
|
||||
'https://cdnjs.cloudflare.com',
|
||||
"$scheme://www.google-analytics.com",
|
||||
]) . ';'
|
||||
];
|
||||
|
||||
$response->headers->set(
|
||||
'Content-Security-Policy',
|
||||
implode(' ', $cspPolicies) . $reportUri
|
||||
);
|
||||
$response->headers->set('Feature-Policy', 'fullscreen \'self\';');
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove unwanted headers
|
||||
*
|
||||
* @param array $headerList
|
||||
* @return void
|
||||
*/
|
||||
private function removeUnwantedHeaders(array $headerList)
|
||||
{
|
||||
foreach ($headerList as $header) {
|
||||
header_remove($header);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -11,6 +11,5 @@ class VerifyCsrfToken extends Middleware
|
|||
*
|
||||
* @var array<int, string>
|
||||
*/
|
||||
protected $except = [
|
||||
];
|
||||
protected $except = ['/csp-report'];
|
||||
}
|
||||
|
|
|
|||
0
app/Http/Requests/Bo/.gitkeep
Normal file
0
app/Http/Requests/Bo/.gitkeep
Normal file
0
app/Http/Requests/Fo/.gitkeep
Normal file
0
app/Http/Requests/Fo/.gitkeep
Normal file
|
|
@ -1,9 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace App;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class LandingPage extends Model
|
||||
{
|
||||
}
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
<?php
|
||||
|
||||
namespace App\Lib;
|
||||
namespace App\Lib\Helpers;
|
||||
|
||||
class ExceptionsHelper
|
||||
{
|
||||
444
app/Lib/Helpers/FileStorageHelper.php
Normal file
444
app/Lib/Helpers/FileStorageHelper.php
Normal file
|
|
@ -0,0 +1,444 @@
|
|||
<?php
|
||||
|
||||
namespace App\Lib\Helpers;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Support\Facades\File;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
/**
|
||||
* This class is used to handle files in LDC Laravel stack
|
||||
*
|
||||
* * The storage strategy will be using date.
|
||||
* The file name may contain sufix timestamp highresolution time (hrtime or microtime) if is duplicate.
|
||||
* (function() { return time() . ' ' . Str::slug(microtime(true)) . ' ' . hrtime(true); })();
|
||||
*
|
||||
* posts/ - The model table name
|
||||
* 10/ - Year
|
||||
* 04/ - Month
|
||||
* 19/ - Day
|
||||
* 5f/ - First two letters of md5 file
|
||||
* black-cat-under-red-car.png - Slugified file name
|
||||
* black-cat-under-red-car-286071690833400.png - Slugified file name that is duplicated
|
||||
*
|
||||
* The final path will be storage/modelfiles/posts/10/04/19/5f/black-cat-under-red-car-286071690833400.png
|
||||
*
|
||||
* ! No limits of file per folder will be handled.
|
||||
*
|
||||
* @author Munsch Jérémy <jeremy.munsch@ldc.fr>
|
||||
*/
|
||||
class FileStorageHelper
|
||||
{
|
||||
/**
|
||||
* Destroy the file associate with the attribute.
|
||||
*
|
||||
* @param \Illuminate\Database\Eloquent\Model $model
|
||||
* @param string $attribute
|
||||
* @return void
|
||||
*/
|
||||
public static function removeFile(Model $model, string $attribute): void
|
||||
{
|
||||
$path = \ltrim(\urldecode($model->{$attribute}), '/');
|
||||
if (\strpos($path, 'storage') !== 0) {
|
||||
return;
|
||||
}
|
||||
$path = ToolboxHelper::mbReplace('storage/', '', $path);
|
||||
if (Storage::disk('public')->exists($path)) {
|
||||
Storage::disk('public')->delete($path);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroy the file associate with the attribute old value (before updated to DB).
|
||||
*
|
||||
* @param \Illuminate\Database\Eloquent\Model $model
|
||||
* @param string $attribute
|
||||
* @param boolean $onlyIfUpdated
|
||||
* @return void
|
||||
*/
|
||||
public static function removeOldFile(Model $model, string $attribute, bool $onlyIfUpdated = true): void
|
||||
{
|
||||
// * Ignore If removal has to be done only if the field has changed and it actually hasnt.
|
||||
if ($onlyIfUpdated and $model->{$attribute} === $model->getOriginal($attribute)) {
|
||||
return;
|
||||
}
|
||||
$originalPath = \ltrim(\urldecode($model->getOriginal($attribute)), '/');
|
||||
if (\strpos($originalPath, 'storage') !== 0) {
|
||||
return;
|
||||
}
|
||||
$originalPath = ToolboxHelper::mbReplace('storage/', '', $originalPath);
|
||||
if (Storage::disk('public')->exists($originalPath)) {
|
||||
Storage::disk('public')->delete($originalPath);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Store a file using optimized storage strategy
|
||||
*
|
||||
* You can use filename param to overload file name.
|
||||
*
|
||||
* @param \Illuminate\Database\Eloquent\Model $model The model that will hold the picture.
|
||||
* @param \Illuminate\Http\UploadedFile|\SplFileInfo|string $file The file, will just return itself is string.
|
||||
* @param boolean $slugify Force filename slugification.
|
||||
* @param string|null $filename This string may be used to store the file.
|
||||
* @param boolean $private To store the file in a private space.
|
||||
* @return string
|
||||
* @throws \RuntimeException If file copy fails.
|
||||
*/
|
||||
public static function storeFile(
|
||||
Model $model,
|
||||
$file,
|
||||
bool $slugify = false,
|
||||
string $filename = null,
|
||||
bool $private = false
|
||||
): string {
|
||||
$tableName = $model->getTable();
|
||||
if (\is_object($file) and $file instanceof \Illuminate\Http\UploadedFile) {
|
||||
if ($private) {
|
||||
throw new \RuntimeException('Private storage for uploaded files is unhandled');
|
||||
}
|
||||
/** @var \Illuminate\Http\UploadedFile $file */
|
||||
$filename = $filename ?: $file->getClientOriginalName();
|
||||
$filename = $slugify ? self::slugifyFileName($filename) : $filename;
|
||||
$newPath = self::prepareMoveFile($tableName, $filename);
|
||||
$newPath = str_replace(storage_path('app'), '', $newPath);
|
||||
$file->storePubliclyAs(
|
||||
pathinfo($newPath, \PATHINFO_DIRNAME),
|
||||
pathinfo($newPath, \PATHINFO_BASENAME)
|
||||
);
|
||||
return 'storage' . str_replace('/public', '', $newPath);
|
||||
}
|
||||
if (\is_object($file) and $file instanceof \SplFileInfo) {
|
||||
/** @var \SplFileInfo $file */
|
||||
$filename = $filename ?: $file->getBaseName();
|
||||
$filename = $slugify ? self::slugifyFileName($filename) : $filename;
|
||||
$newPath = self::prepareMoveFile($tableName, $filename, $private);
|
||||
if (!File::copy($file->getRealPath(), $newPath)) {
|
||||
throw new \RuntimeException(sprintf(
|
||||
'Failed to copy file %s to %s',
|
||||
$file->getRealPath(),
|
||||
$newPath
|
||||
));
|
||||
}
|
||||
return $private ?
|
||||
\ltrim(str_replace(\storage_path('app/private'), '/storage/app/private', $newPath), '/') :
|
||||
\ltrim(str_replace(\storage_path('app/public'), '/storage', $newPath), '/');
|
||||
}
|
||||
return strval($file);
|
||||
}
|
||||
|
||||
/**
|
||||
* Store all files from string attribute html
|
||||
* If oldHtmlString is passed, a diff is done with new and old files
|
||||
* to keep only files that are present in the new html string.
|
||||
*
|
||||
*
|
||||
* @param \Illuminate\Database\Eloquent\Model $model The model that will hold the picture.
|
||||
* @param string $htmlString The html string to parse and modify files.
|
||||
* @param string|null $oldHtmlString The old html string with alreadyParsed
|
||||
* files using storeModelFilesFromHtml.
|
||||
* @return string Html with files pathes replaced using storage strategy.
|
||||
*/
|
||||
public static function storeModelFilesFromHtml(
|
||||
Model $model,
|
||||
string $htmlString,
|
||||
string $oldHtmlString = null
|
||||
): string {
|
||||
\collect(self::onlyUploadedFilesWithFileManager(self::findFilesInHtml($htmlString)))
|
||||
->each(function (string $path) use ($model, &$htmlString) {
|
||||
/** @var \Illuminate\Filesystem\FilesystemAdapter */
|
||||
$disk = Storage::disk('uploads');
|
||||
$fileInfo = new \SplFileInfo($disk->path(
|
||||
ToolboxHelper::mbReplace('/uploads/', '', \urldecode($path))
|
||||
));
|
||||
$htmlString = ToolboxHelper::mbReplace(
|
||||
$path,
|
||||
'/' . self::storeFile($model, $fileInfo, true),
|
||||
$htmlString
|
||||
);
|
||||
});
|
||||
|
||||
if ($oldHtmlString) {
|
||||
self::removeOldModelFilesFromHtml($htmlString, $oldHtmlString);
|
||||
}
|
||||
|
||||
return $htmlString;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove all old files from string attribute html that are stored in public that
|
||||
* are nove present anymore on new html string
|
||||
*
|
||||
* @param string $newHtmlString The html string with alreadyParsed files using storeModelFilesFromHtml.
|
||||
* @param string $oldHtmlString The old html string with alreadyParsed files using storeModelFilesFromHtml.
|
||||
* @return void
|
||||
*/
|
||||
public static function removeOldModelFilesFromHtml(string $newHtmlString, string $oldHtmlString): void
|
||||
{
|
||||
self::removeOldFiles(self::findFilesInHtml($oldHtmlString), self::findFilesInHtml($newHtmlString));
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove all old files that are stored in public that
|
||||
* are not present anymore on new array files
|
||||
*
|
||||
* @param string[] $oldFiles The old array files.
|
||||
* @param string[] $newFiles The new array files.
|
||||
* @return void
|
||||
*/
|
||||
public static function removeOldFiles(array $oldFiles, array $newFiles): void
|
||||
{
|
||||
$oldFiles = \collect(self::onlyUploadedFilesWithFileStorageHelper($oldFiles));
|
||||
$filesToKeep = \collect(self::onlyUploadedFilesWithFileStorageHelper($newFiles));
|
||||
$filesToRemove = $oldFiles->diff($filesToKeep);
|
||||
$filesToRemove->each(function (string $publicStorageFilePath) {
|
||||
$path = ToolboxHelper::mbReplace('storage/', '', \ltrim(\urldecode($publicStorageFilePath), '/'));
|
||||
if (Storage::disk('public')->exists($path)) {
|
||||
Storage::disk('public')->delete($path);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove all files from string attribute html that are stored in public
|
||||
*
|
||||
* @param string $htmlString The html string with alreadyParsed files using storeModelFilesFromHtml.
|
||||
* @return void
|
||||
*/
|
||||
public static function removeModelFilesOfHtml(string $htmlString): void
|
||||
{
|
||||
$filesToRemove = \collect(self::onlyUploadedFilesWithFileStorageHelper(self::findFilesInHtml($htmlString)));
|
||||
$filesToRemove->each(function (string $publicStorageFilePath) {
|
||||
$path = ToolboxHelper::mbReplace('storage/', '', \ltrim(\urldecode($publicStorageFilePath), '/'));
|
||||
if (Storage::disk('public')->exists($path)) {
|
||||
Storage::disk('public')->delete($path);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Find all occurence of files in html
|
||||
* @param string $html
|
||||
* @return array
|
||||
*/
|
||||
public static function findFilesInHtml(string $html): array
|
||||
{
|
||||
preg_match_all('/href="(?P<href>.*)"|src="(?P<src>.*)"|url="(?P<url>.*)"/Um', $html, $m, PREG_SET_ORDER, 0);
|
||||
return collect($m)->pluck('href')->filter()
|
||||
->concat(collect($m)->pluck('url')->filter())
|
||||
->concat(collect($m)->pluck('src')->filter())
|
||||
->all();
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter array to get only uploaded files that exists
|
||||
* on disk 'public' (using helper storage strategy)
|
||||
*
|
||||
* @param array $urls
|
||||
* @return array
|
||||
*/
|
||||
public static function onlyUploadedFilesWithFileStorageHelper(array $urls): array
|
||||
{
|
||||
return \collect($urls)->unique()
|
||||
// * Filter to get only /uploads and using app url or empty
|
||||
->filter(function (string $url) {
|
||||
$path = \parse_url($url, \PHP_URL_PATH);
|
||||
return \strpos(\ltrim($path, '/'), 'storage/modelfiles') === 0;
|
||||
})->filter(function (string $url) {
|
||||
$path = \parse_url($url, \PHP_URL_PATH);
|
||||
return Storage::disk('public')
|
||||
->exists(ToolboxHelper::mbReplace('storage/', '', \ltrim(\urldecode($path), '/')));
|
||||
})->all();
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter array to get only uploaded files that exists
|
||||
* on disk 'uploads'
|
||||
*
|
||||
* @param array $urls
|
||||
* @return array
|
||||
*/
|
||||
private static function onlyUploadedFilesWithFileManager(array $urls): array
|
||||
{
|
||||
return \collect($urls)->unique()
|
||||
// * Filter to get only /uploads and using app url or empty
|
||||
->filter(function (string $url) {
|
||||
$host = \parse_url($url, \PHP_URL_HOST);
|
||||
$path = \parse_url($url, \PHP_URL_PATH);
|
||||
return ($host === \parse_url(config('app.url'), PHP_URL_HOST) or \is_null($host)) and
|
||||
\strpos(\ltrim($path, '/'), 'uploads') === 0;
|
||||
})->filter(function (string $url) {
|
||||
$path = \parse_url($url, \PHP_URL_PATH);
|
||||
return Storage::disk('uploads')
|
||||
->exists(ToolboxHelper::mbReplace('uploads/', '', \ltrim(\urldecode($path), '/')));
|
||||
})->all();
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare storage path and return
|
||||
* the file full path
|
||||
*
|
||||
* @param string $tableName Model table name.
|
||||
* @param string $filename The basename for the file.
|
||||
* @param boolean $private May the file be stored in a private dir.
|
||||
* @return string
|
||||
*/
|
||||
private static function prepareMoveFile(string $tableName, string $filename, bool $private = false): string
|
||||
{
|
||||
// * Security filter + beautifier
|
||||
$filename = self::sanitizeFileName($filename);
|
||||
// * Security filter
|
||||
$filename = \filter_var($filename, \FILTER_SANITIZE_STRING);
|
||||
// * Slugify filename
|
||||
$ext = \pathinfo($filename, \PATHINFO_EXTENSION);
|
||||
$filename = Str::slug(\pathinfo($filename, \PATHINFO_FILENAME)) .
|
||||
(\strlen($ext) ? ".{$ext}" : '');
|
||||
|
||||
$folderPath = self::getStoragePath(
|
||||
$private ? 'app/private/modelfiles' : 'app/public/modelfiles',
|
||||
$tableName,
|
||||
$filename,
|
||||
$private
|
||||
);
|
||||
$filename = self::getFileUniqueName($folderPath, $filename);
|
||||
return "{$folderPath}/{$filename}";
|
||||
}
|
||||
|
||||
/**
|
||||
* Create sub folders to store files using pattern
|
||||
* storage/modelfiles/posts/10/04/19/5f
|
||||
* year/month/day/md5 first 2 letters
|
||||
*
|
||||
* @param string $storage_dir
|
||||
* @param string $table
|
||||
* @param string $filename
|
||||
* @return string
|
||||
*/
|
||||
private static function getStoragePath(string $storage_dir, string $table, string $filename): string
|
||||
{
|
||||
$filenameHash = \md5($filename);
|
||||
$pathFolder = \storage_path(sprintf(
|
||||
'%s/%s/%s/%s/%s/%s',
|
||||
$storage_dir,
|
||||
$table,
|
||||
gmdate('y'),
|
||||
gmdate('m'),
|
||||
gmdate('d'),
|
||||
substr($filenameHash, 0, 2)
|
||||
));
|
||||
if (!File::exists($pathFolder)) {
|
||||
File::makeDirectory($pathFolder, 0755, true);
|
||||
}
|
||||
return $pathFolder;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get unique filename if the path is already occupied
|
||||
*
|
||||
* @param string $folderPath
|
||||
* @param string $filename
|
||||
* @return string
|
||||
* @throws \RuntimeException If a unique filename cannot be obtained.
|
||||
*/
|
||||
private static function getFileUniqueName(string $folderPath, string $filename): string
|
||||
{
|
||||
$attempts = 0;
|
||||
$maxAttempts = 20;
|
||||
while (File::exists("{$folderPath}/{$filename}")) {
|
||||
if ($attempts++ >= $maxAttempts) {
|
||||
throw new \RuntimeException("Failed to has a unique filename for {$folderPath}/{$filename}");
|
||||
}
|
||||
$filename = pathinfo($filename, \PATHINFO_FILENAME) .
|
||||
\uniqid('-') . '.' .
|
||||
pathinfo($filename, \PATHINFO_EXTENSION);
|
||||
}
|
||||
return $filename;
|
||||
}
|
||||
|
||||
/**
|
||||
* Slugify the filename
|
||||
*
|
||||
* @param string $filename
|
||||
* @return string
|
||||
*/
|
||||
public static function slugifyFileName(string $filename): string
|
||||
{
|
||||
return Str::slug(pathinfo($filename, \PATHINFO_FILENAME)) . '.' . pathinfo($filename, \PATHINFO_EXTENSION);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sanitize File name for uploaded files
|
||||
*
|
||||
* @param string $filename The original uploaded client file name.
|
||||
* @param boolean $beautify Beautify the filename.
|
||||
* @return string The sanitized file name.
|
||||
*/
|
||||
public static function sanitizeFileName(string $filename, bool $beautify = true): string
|
||||
{
|
||||
// * Sanitize filename
|
||||
// phpcs:disable Generic.Files.LineLength.TooLong
|
||||
$filename = preg_replace(
|
||||
'~
|
||||
[<>:"/\\\|?*]| # file system reserved https://en.wikipedia.org/wiki/Filename#Reserved_characters_and_words
|
||||
[\x00-\x1F]| # control characters http://msdn.microsoft.com/en-us/library/windows/desktop/aa365247%28v=vs.85%29.aspx
|
||||
[\x7F\xA0\xAD]| # non-printing characters DEL, NO-BREAK SPACE, SOFT HYPHEN
|
||||
[#\[\]@!$&\'()+,;=]| # URI reserved https://tools.ietf.org/html/rfc3986#section-2.2
|
||||
[{}^\~`] # URL unsafe characters https://www.ietf.org/rfc/rfc1738.txt
|
||||
~x',
|
||||
'-',
|
||||
$filename
|
||||
);
|
||||
// phpcs:enable
|
||||
// * Avoids '.' '..' or '.hiddenFiles' .
|
||||
$filename = Str::of($filename)->ltrim('.-');
|
||||
// * Optional beautification
|
||||
if ($beautify) {
|
||||
$filename = static::beautifyFilename($filename);
|
||||
}
|
||||
// * Maximize filename length to 255 bytes http://serverfault.com/a/9548/44086
|
||||
/** @var string */
|
||||
$extension = pathinfo($filename, \PATHINFO_EXTENSION);
|
||||
/** @var string */
|
||||
$filename = pathinfo($filename, \PATHINFO_FILENAME);
|
||||
|
||||
$encoding = mb_detect_encoding($filename);
|
||||
$encoding = $encoding ? $encoding : null;
|
||||
return \mb_strcut(
|
||||
$filename,
|
||||
0,
|
||||
255 - (!empty($extension) ? strlen($extension) + 1 : 0),
|
||||
$encoding
|
||||
) . (!empty($extension) ? ".$extension" : '');
|
||||
}
|
||||
|
||||
/**
|
||||
* Beautify a filename
|
||||
*
|
||||
* @param string $filename
|
||||
* @return string
|
||||
*/
|
||||
private static function beautifyFilename(string $filename): string
|
||||
{
|
||||
// Reduce consecutive characters.
|
||||
$filename = preg_replace([
|
||||
// * "file name.zip" becomes 'file-name.zip'
|
||||
'/ +/',
|
||||
// * "file___name.zip" becomes 'file-name.zip'
|
||||
'/_+/',
|
||||
// * "file---name.zip" becomes 'file-name.zip'
|
||||
'/-+/'
|
||||
], '-', $filename);
|
||||
$filename = preg_replace([
|
||||
// * "file--.--.-.--name.zip" becomes "file.name.zip"
|
||||
'/-*\.-*/',
|
||||
// * "file...name..zip" becomes "file.name.zip"
|
||||
'/\.{2,}/'
|
||||
], '.', $filename);
|
||||
// Lowercase for windows/unix interoperability http://support.microsoft.com/kb/100625 .
|
||||
$filename = mb_strtolower($filename, mb_detect_encoding($filename));
|
||||
// * ".file-name.-" becomes "file-name"
|
||||
$filename = trim($filename, '.-');
|
||||
return $filename;
|
||||
}
|
||||
}
|
||||
237
app/Lib/Helpers/ToolboxHelper.php
Normal file
237
app/Lib/Helpers/ToolboxHelper.php
Normal file
|
|
@ -0,0 +1,237 @@
|
|||
<?php
|
||||
|
||||
namespace App\Lib\Helpers;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Route;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
use Illuminate\Validation\Rule;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
||||
|
||||
class ToolboxHelper
|
||||
{
|
||||
/**
|
||||
* Strip scheme (https) on oembed urls
|
||||
* Only embed allowed are for MP4 self hosted videos right now
|
||||
*
|
||||
* https is force by ckeditor MediaElements which natively supports
|
||||
* only cloud hosted medias (youtube, spotify etc..)
|
||||
*
|
||||
* @param string $input
|
||||
* @return string
|
||||
*/
|
||||
public static function stripCkEditorSchemesOnMediaInputs(string $input): string
|
||||
{
|
||||
$input = \preg_replace('/(?<=<oembed url=")(https:\/\/)(?=.*?">)/m', '', $input);
|
||||
return $input;
|
||||
}
|
||||
|
||||
/**
|
||||
* Assert That no Back Office url is present on txt
|
||||
*
|
||||
* @param string $field
|
||||
* @param string $text
|
||||
* @return string
|
||||
* @throws \Illuminate\Validation\ValidationException If url is a bo url.
|
||||
*/
|
||||
public static function assertNoInternalBoUrls(string $field, string $text): string
|
||||
{
|
||||
$routes = Route::getRoutes();
|
||||
// * Url replace and email replace.
|
||||
$text = preg_replace_callback(
|
||||
// phpcs:ignore Generic.Files.LineLength.TooLong
|
||||
'/(?P<url>(?:http[s]?:\/\/.)?(?:www\.)?[-a-zA-Z0-9@%._\+~#=]{2,256}\.[a-z]{2,6}\b(?:[-a-zA-Z0-9@:%_\+.~#?&\/\/=]*))/',
|
||||
function ($matches) use ($routes, $field) {
|
||||
$match = collect($matches)->first() ?? '';
|
||||
$url = $match;
|
||||
try {
|
||||
$request = Request::create($url);
|
||||
// If a route is match then it do not throws exception.
|
||||
if (
|
||||
\parse_url(config('app.url'), \PHP_URL_HOST) === \parse_url($url, \PHP_URL_HOST) &&
|
||||
trim($routes->match($request)->getPrefix() ?? '', '/') === 'bo'
|
||||
) {
|
||||
// Removes the matched url.
|
||||
throw ValidationException::withMessages([
|
||||
$field => ':attribute : Il est interdit de coller une url du back office dans ce champ'
|
||||
]);
|
||||
}
|
||||
return $match;
|
||||
} catch (NotFoundHttpException $e) {
|
||||
return $match;
|
||||
}
|
||||
},
|
||||
$text
|
||||
);
|
||||
return $text;
|
||||
}
|
||||
|
||||
/**
|
||||
* Assert That only external url is present on txt
|
||||
*
|
||||
* @param string $field
|
||||
* @param string $text
|
||||
* @return string
|
||||
* @throws \Illuminate\Validation\ValidationException If url is a bo url.
|
||||
*/
|
||||
public static function assertNoInternalUrls(string $field, string $text): string
|
||||
{
|
||||
self::assertNoInternalBoUrls($field, $text);
|
||||
$routes = Route::getRoutes();
|
||||
// * Url replace and email replace.
|
||||
$text = preg_replace_callback(
|
||||
// phpcs:ignore Generic.Files.LineLength.TooLong
|
||||
'/(?P<url>(?:http[s]?:\/\/.)?(?:www\.)?[-a-zA-Z0-9@%._\+~#=]{2,256}\.[a-z]{2,6}\b(?:[-a-zA-Z0-9@:%_\+.~#?&\/\/=]*))/',
|
||||
function ($matches) use ($routes, $field) {
|
||||
$match = collect($matches)->first() ?? '';
|
||||
$url = $match;
|
||||
try {
|
||||
$request = Request::create($url);
|
||||
// If a route is match then it do not throws exception.
|
||||
if (
|
||||
\parse_url(config('app.url'), \PHP_URL_HOST) === \parse_url($url, \PHP_URL_HOST) &&
|
||||
$routes->match($request)
|
||||
) {
|
||||
// Removes the matched url.
|
||||
throw ValidationException::withMessages([
|
||||
$field => sprintf(
|
||||
':attribute : Il est interdit de coller une url de %s dans ce champ',
|
||||
config('app.name')
|
||||
)
|
||||
]);
|
||||
}
|
||||
return $match;
|
||||
} catch (NotFoundHttpException $e) {
|
||||
return $match;
|
||||
}
|
||||
},
|
||||
$text
|
||||
);
|
||||
return $text;
|
||||
}
|
||||
|
||||
/**
|
||||
* Mutltibyte string replace
|
||||
* @param mixed $search
|
||||
* @param mixed $replace
|
||||
* @param mixed $subject
|
||||
* @param integer $count
|
||||
* @return mixed
|
||||
*/
|
||||
public static function mbReplace($search, $replace, $subject, int &$count = 0)
|
||||
{
|
||||
if (!is_array($search) && is_array($replace)) {
|
||||
return false;
|
||||
}
|
||||
if (is_array($subject)) {
|
||||
// Call mb_replace for each single string in $subject .
|
||||
foreach ($subject as &$string) {
|
||||
$string = &self::mbReplace($search, $replace, $string, $count);
|
||||
}
|
||||
} elseif (is_array($search)) {
|
||||
if (!is_array($replace)) {
|
||||
foreach ($search as &$string) {
|
||||
$subject = self::mbReplace($string, $replace, $subject, $count);
|
||||
}
|
||||
} else {
|
||||
$n = max(count($search), count($replace));
|
||||
while ($n--) {
|
||||
$subject = self::mbReplace(current($search), current($replace), $subject, $count);
|
||||
next($search);
|
||||
next($replace);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$parts = mb_split(preg_quote($search), $subject);
|
||||
$count = count($parts) - 1;
|
||||
$subject = implode($replace, $parts);
|
||||
} //end if
|
||||
return $subject;
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the field is unique
|
||||
*
|
||||
* @param string $table
|
||||
* @param string $field
|
||||
* @param mixed $value
|
||||
* @param integer|null $id
|
||||
* @param callable|null $query
|
||||
* @return void
|
||||
* @throws \Illuminate\Validation\ValidationException If the field is not unique.
|
||||
*/
|
||||
public static function assertFieldIsUnique(
|
||||
string $table,
|
||||
string $field,
|
||||
$value,
|
||||
?int $id = null,
|
||||
?callable $query = null
|
||||
) {
|
||||
if (!$query) {
|
||||
Validator::make([$field => $value], [
|
||||
self::mbReplace('.', '\.', $field) => Rule::unique($table, $field)->ignore($id),
|
||||
], [
|
||||
self::mbReplace('.', '\.', "{$field}.unique")
|
||||
=> trans('La valeur :value pour le champ :attribute est déjà utilisé', [
|
||||
'attribute' => $field,
|
||||
'value' => $value
|
||||
])
|
||||
])->validate();
|
||||
return;
|
||||
}
|
||||
Validator::make([$field => $value], [
|
||||
$field => Rule::unique($table)->where($query)->ignore($id),
|
||||
], [
|
||||
$field . '.unique' => trans('La valeur pour le champ :attribute est déjà utilisé', [
|
||||
'attribute' => $field
|
||||
])
|
||||
])->validate();
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert deeply an object to array
|
||||
*
|
||||
* @param array|object $input
|
||||
* @return array
|
||||
* @throws \RuntimeException If $input var is a scalar value.
|
||||
*/
|
||||
public static function objectToArray($input): array
|
||||
{
|
||||
// Only process if it's an object or array being passed to the function.
|
||||
if (is_object($input) or is_array($input)) {
|
||||
$ret = (array)$input;
|
||||
foreach ($ret as &$item) {
|
||||
// Recursively process EACH element only if not scalar.
|
||||
$item = (is_object($item) or is_array($item)) ?
|
||||
self::objectToArray($item) : $item;
|
||||
}
|
||||
return $ret;
|
||||
} else {
|
||||
throw new \RuntimeException('cannot handle $input of type ' . \gettype($input));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert deeply an array to object
|
||||
*
|
||||
* @param array|object $input
|
||||
* @return object
|
||||
* @throws \RuntimeException If $input var is a scalar value.
|
||||
*/
|
||||
public static function arrayToObject($input): object
|
||||
{
|
||||
// Only process if it's an object or array being passed to the function.
|
||||
if (is_object($input) or is_array($input)) {
|
||||
$ret = (object)$input;
|
||||
foreach ($ret as &$item) {
|
||||
// Recursively process EACH element only if not scalar.
|
||||
$item = (is_object($item) or is_array($item)) ?
|
||||
self::arrayToObject($item) : $item;
|
||||
}
|
||||
return $ret;
|
||||
} else {
|
||||
throw new \RuntimeException('cannot handle $input of type ' . \gettype($input));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -3,9 +3,11 @@
|
|||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Foundation\Auth\User as Authenticatable;
|
||||
use Illuminate\Notifications\Notifiable;
|
||||
use Illuminate\Support\Facades\Hash;
|
||||
|
||||
class User extends \TCG\Voyager\Models\User
|
||||
class User extends Authenticatable
|
||||
{
|
||||
use HasFactory;
|
||||
use Notifiable;
|
||||
|
|
@ -16,7 +18,8 @@ class User extends \TCG\Voyager\Models\User
|
|||
* @var array<int, string>
|
||||
*/
|
||||
protected $fillable = [
|
||||
'name',
|
||||
'firstname',
|
||||
'lastname',
|
||||
'email',
|
||||
'password',
|
||||
];
|
||||
|
|
@ -39,4 +42,24 @@ class User extends \TCG\Voyager\Models\User
|
|||
protected $casts = [
|
||||
'email_verified_at' => 'datetime',
|
||||
];
|
||||
|
||||
/**
|
||||
* Perform any actions required after the model boots.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected static function booted()
|
||||
{
|
||||
// * EVENT CLOSURES.
|
||||
static::creating(function (User $user) {
|
||||
if (Hash::needsRehash($user->password)) {
|
||||
$user->password = Hash::make($user->password);
|
||||
}
|
||||
});
|
||||
static::updating(function (User $user) {
|
||||
if (Hash::needsRehash($user->password)) {
|
||||
$user->password = Hash::make($user->password);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
28
app/Page.php
28
app/Page.php
|
|
@ -1,28 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace App;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class Page extends Model
|
||||
{
|
||||
/**
|
||||
* Page parts relationship
|
||||
*
|
||||
* @return \Illuminate\Database\Eloquent\Relations\HasMany
|
||||
*/
|
||||
public function parts()
|
||||
{
|
||||
return $this->hasMany('App\Part');
|
||||
}
|
||||
|
||||
/**
|
||||
* Page snippets relationship
|
||||
*
|
||||
* @return \Illuminate\Database\Eloquent\Relations\HasMany
|
||||
*/
|
||||
public function snippets()
|
||||
{
|
||||
return $this->hasMany('App\Snippet');
|
||||
}
|
||||
}
|
||||
|
|
@ -1,9 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace App;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class Part extends Model
|
||||
{
|
||||
}
|
||||
|
|
@ -1,9 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace App;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class Product extends Model
|
||||
{
|
||||
}
|
||||
|
|
@ -2,20 +2,14 @@
|
|||
|
||||
namespace App\Providers;
|
||||
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
use Illuminate\Pagination\Paginator;
|
||||
use Illuminate\Support\Carbon;
|
||||
use Illuminate\Support\Facades\App;
|
||||
use Illuminate\Support\Facades\URL;
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
|
||||
class AppServiceProvider extends ServiceProvider
|
||||
{
|
||||
/**
|
||||
* Register any application services.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function register()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Bootstrap any application services.
|
||||
*
|
||||
|
|
@ -23,6 +17,47 @@ class AppServiceProvider extends ServiceProvider
|
|||
*/
|
||||
public function boot()
|
||||
{
|
||||
// * HTTPS FIX
|
||||
URL::forceScheme('https');
|
||||
|
||||
// * HA PROXY FIX
|
||||
App::singleton('clientIp', function () {
|
||||
if (config('app.env') === 'local') {
|
||||
return request()->getClientIp();
|
||||
} else {
|
||||
return request()->server('HTTP_X_FORWARDED_FOR') ??
|
||||
request()->getClientIp();
|
||||
}
|
||||
});
|
||||
|
||||
// * LOCAL FORCE eg: for Carbon
|
||||
setlocale(LC_ALL, \sprintf(
|
||||
'%s_%s.UTF-8',
|
||||
config('app.locale'),
|
||||
\strtoupper(config('app.locale'))
|
||||
));
|
||||
Carbon::setLocale(config('app.locale'));
|
||||
|
||||
$this->sharetoView();
|
||||
}
|
||||
|
||||
/**
|
||||
* Share Vars to view
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function sharetoView()
|
||||
{
|
||||
if (!app()->runningInConsole()) {
|
||||
// * FORCE BOOTSTRAP PAGINATOR (or custom if in front)
|
||||
// Early boot, request wont be filled as expected.
|
||||
if (collect(explode('/', \request()->getPathInfo()))->get(1) === 'bo') {
|
||||
Paginator::useBootstrap();
|
||||
} else {
|
||||
// FIXME: change this if needed.
|
||||
Paginator::useBootstrap();
|
||||
// Paginator::defaultview('fo.modules.pagination'); .
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,13 +6,6 @@ use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvid
|
|||
|
||||
class AuthServiceProvider extends ServiceProvider
|
||||
{
|
||||
/**
|
||||
* The policy mappings for the application.
|
||||
*
|
||||
* @var array<class-string, class-string>
|
||||
*/
|
||||
protected $policies = [];
|
||||
|
||||
/**
|
||||
* Register any authentication / authorization services.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -27,14 +27,4 @@ class EventServiceProvider extends ServiceProvider
|
|||
public function boot()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if events and listeners should be automatically discovered.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function shouldDiscoverEvents()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ class RouteServiceProvider extends ServiceProvider
|
|||
*
|
||||
* @var string
|
||||
*/
|
||||
public const HOME = '/home';
|
||||
public const HOME = '/';
|
||||
|
||||
/**
|
||||
* Define your route model bindings, pattern filters, etc.
|
||||
|
|
@ -28,15 +28,15 @@ class RouteServiceProvider extends ServiceProvider
|
|||
{
|
||||
$this->configureRateLimiting();
|
||||
|
||||
$this->routes(function () {
|
||||
Route::middleware('api')
|
||||
->prefix('api')
|
||||
->group(base_path('routes/api.php'));
|
||||
$this->cspReportRoute();
|
||||
|
||||
$this->routes(function () {
|
||||
Route::middleware('web')
|
||||
->namespace($this->namespace)
|
||||
->group(base_path('routes/web-bo.php'));
|
||||
|
||||
Route::middleware('web')
|
||||
->namespace($this->namespace)
|
||||
->group(base_path('routes/web-fo.php'));
|
||||
});
|
||||
}
|
||||
|
|
@ -49,7 +49,49 @@ class RouteServiceProvider extends ServiceProvider
|
|||
protected function configureRateLimiting()
|
||||
{
|
||||
RateLimiter::for('api', function (Request $request) {
|
||||
return Limit::perMinute(60)->by($request->user()?->id ?: $request->ip());
|
||||
return Limit::perMinute(150)->by(optional($request->user())->id ?: app('clientIp'));
|
||||
});
|
||||
RateLimiter::for('web', function (Request $request) {
|
||||
return Limit::perMinute(150)->by(optional($request->user())->id ?: app('clientIp'));
|
||||
});
|
||||
RateLimiter::for('credentials', function (Request $request) {
|
||||
return Limit::perMinute(30)->by(optional($request->user())->id ?: $request->ip());
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* * Register CSP report URI
|
||||
*
|
||||
* Put this function inside RouteServiceProvider,
|
||||
* and call it in RouteServiceProvider::boot
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function cspReportRoute()
|
||||
{
|
||||
// * CSP REPORT URI, Please add /csp-report to VerifyCsrfToken $except middleware
|
||||
\Illuminate\Support\Facades\Route::post('/csp-report', function () {
|
||||
$isCspRequest = request()->header('Content-Type') === 'application/csp-report';
|
||||
if (!$isCspRequest or !request()->json('csp-report') or !is_array(request()->json('csp-report'))) {
|
||||
abort(401);
|
||||
}
|
||||
// * Flatten if needed
|
||||
$cspReport = collect(request()->json('csp-report'))
|
||||
->flatMap(function ($v, $k) {
|
||||
return [$k => is_array($v) ? collect($v)->flatten()->implode(', ') : $v];
|
||||
})->all();
|
||||
// * Filter array keys
|
||||
$cspReport = collect(array_intersect_key($cspReport, [
|
||||
'blocked-uri' => '', 'document-uri' => '', 'original-policy' => '',
|
||||
'referrer' => '', 'violated-directive' => ''
|
||||
]));
|
||||
\Illuminate\Support\Facades\Log::warning(sprintf(
|
||||
"CSP REPORT for %s : \n %s",
|
||||
$cspReport->get('document-uri'),
|
||||
$cspReport->implode("\n")
|
||||
));
|
||||
})->middleware('throttle:5,2')
|
||||
->withoutMiddleware(\App\Http\Middleware\VerifyCsrfToken::class)
|
||||
->name('cspReportUri');
|
||||
}
|
||||
}
|
||||
|
|
|
|||
78
app/Providers/TranslationServiceProvider.php
Normal file
78
app/Providers/TranslationServiceProvider.php
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
<?php
|
||||
|
||||
namespace App\Providers;
|
||||
|
||||
use Illuminate\Support\Collection;
|
||||
use Illuminate\Support\Facades\File;
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
use Symfony\Component\Finder\SplFileInfo;
|
||||
|
||||
class TranslationServiceProvider extends ServiceProvider
|
||||
{
|
||||
/**
|
||||
* Bootstrap the application services.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function boot()
|
||||
{
|
||||
foreach ($this->collectLocalesStrings() as $locale) {
|
||||
// * Suported locales
|
||||
Cache::rememberForever(sprintf('translations.%s', $locale), function () use ($locale) {
|
||||
$translations = [
|
||||
'php' => $this->phpTranslations($locale),
|
||||
'json' => $this->jsonTranslations($locale),
|
||||
];
|
||||
return $translations;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gather provided langs checking from files
|
||||
*
|
||||
* @return Collection
|
||||
*/
|
||||
private function collectLocalesStrings(): Collection
|
||||
{
|
||||
return collect(File::allFiles(resource_path('lang/')))->flatMap(function (SplFileInfo $file) {
|
||||
if ($file->getRelativePath() and \strpos($file->getRelativePath(), 'vendor') !== 0) {
|
||||
return [$file->getRelativePath() => ''];
|
||||
}
|
||||
})->keys();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gather all php translations
|
||||
*
|
||||
* @param string $locale
|
||||
* @return array
|
||||
*/
|
||||
private function phpTranslations(string $locale): array
|
||||
{
|
||||
$path = resource_path("lang/$locale");
|
||||
|
||||
return collect(File::allFiles($path))->flatMap(function ($file) use ($locale) {
|
||||
$translation = $file->getBasename('.php');
|
||||
return [$translation => trans($translation, [], $locale)];
|
||||
})->all();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gather json translations
|
||||
*
|
||||
* @param string $locale
|
||||
* @return array
|
||||
*/
|
||||
private function jsonTranslations(string $locale): array
|
||||
{
|
||||
$path = resource_path("lang/$locale.json");
|
||||
|
||||
if (is_string($path) && is_readable($path)) {
|
||||
return json_decode(file_get_contents($path), true) ?? [];
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
|
@ -1,9 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace App;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class Recipe extends Model
|
||||
{
|
||||
}
|
||||
|
|
@ -1,9 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace App;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class RetailGroup extends Model
|
||||
{
|
||||
}
|
||||
|
|
@ -1,9 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace App;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class Retailregion extends Model
|
||||
{
|
||||
}
|
||||
|
|
@ -1,9 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace App;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class SalesRegion extends Model
|
||||
{
|
||||
}
|
||||
|
|
@ -1,9 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace App;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class Slider extends Model
|
||||
{
|
||||
}
|
||||
|
|
@ -1,9 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace App;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class Snippet extends Model
|
||||
{
|
||||
}
|
||||
|
|
@ -1,9 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace App;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class Store extends Model
|
||||
{
|
||||
}
|
||||
0
app/Traits/Controllers/.gitkeep
Normal file
0
app/Traits/Controllers/.gitkeep
Normal file
0
app/Traits/Models/.gitkeep
Normal file
0
app/Traits/Models/.gitkeep
Normal file
0
app/Traits/Requests/.gitkeep
Normal file
0
app/Traits/Requests/.gitkeep
Normal file
|
|
@ -1,63 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace App\View\Components;
|
||||
|
||||
use Illuminate\View\Component;
|
||||
|
||||
class ContentPart extends Component
|
||||
{
|
||||
/**
|
||||
* Part variable
|
||||
*
|
||||
* @var mixed
|
||||
*/
|
||||
private $part;
|
||||
|
||||
/**
|
||||
* odd variable
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
private $odd;
|
||||
|
||||
/**
|
||||
* bgcolor variable
|
||||
*
|
||||
* @var mixed
|
||||
*/
|
||||
private $bgcolor;
|
||||
|
||||
/**
|
||||
* Create a new component instance.
|
||||
*
|
||||
* @param mixed $part
|
||||
* @param integer $odd
|
||||
* @param mixed $bgcolor
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(mixed $part = null, int $odd = 0, mixed $bgcolor = null)
|
||||
{
|
||||
$this->part = null;
|
||||
if ($part != null) {
|
||||
$this->part = $part;
|
||||
}
|
||||
|
||||
$this->odd = $odd;
|
||||
if ($bgcolor != null) {
|
||||
$this->bgcolor = $bgcolor;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the view / contents that represent the component.
|
||||
*
|
||||
* @return \Illuminate\Contracts\View\View|\Closure|string
|
||||
*/
|
||||
public function render()
|
||||
{
|
||||
$part = $this->part;
|
||||
$odd = $this->odd;
|
||||
$bgcolor = $this->bgcolor;
|
||||
return view('components.content-part', compact(['part', 'odd', 'bgcolor']));
|
||||
}
|
||||
}
|
||||
|
|
@ -1,63 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace App\View\Components;
|
||||
|
||||
use Illuminate\View\Component;
|
||||
|
||||
class ContentSnippet extends Component
|
||||
{
|
||||
/**
|
||||
* snippet variable
|
||||
*
|
||||
* @var mixed
|
||||
*/
|
||||
private $snippet;
|
||||
|
||||
/**
|
||||
* odd variable
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
private $odd;
|
||||
|
||||
/**
|
||||
* bgcolor variable
|
||||
*
|
||||
* @var mixed
|
||||
*/
|
||||
private $bgcolor;
|
||||
|
||||
/**
|
||||
* Create a new component instance.
|
||||
*
|
||||
* @param mixed $snippet
|
||||
* @param integer $odd
|
||||
* @param mixed $bgcolor
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(mixed $snippet = null, int $odd = 0, mixed $bgcolor = null)
|
||||
{
|
||||
$this->snippet = null;
|
||||
if ($snippet != null) {
|
||||
$this->snippet = $snippet;
|
||||
}
|
||||
|
||||
$this->odd = $odd;
|
||||
if ($bgcolor != null) {
|
||||
$this->bgcolor = $bgcolor;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the view / contents that represent the component.
|
||||
*
|
||||
* @return \Illuminate\Contracts\View\View|\Closure|string
|
||||
*/
|
||||
public function render()
|
||||
{
|
||||
$snippet = $this->snippet;
|
||||
$odd = $this->odd;
|
||||
$bgcolor = $this->bgcolor;
|
||||
return view('components.content-snippet', compact(['snippet', 'odd', 'bgcolor']));
|
||||
}
|
||||
}
|
||||
|
|
@ -1,18 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace App\View\Components;
|
||||
|
||||
use Illuminate\View\Component;
|
||||
|
||||
class ProductCard extends Component
|
||||
{
|
||||
/**
|
||||
* Get the view / contents that represent the component.
|
||||
*
|
||||
* @return \Illuminate\Contracts\View\View|\Closure|string
|
||||
*/
|
||||
public function render()
|
||||
{
|
||||
return view('components.product-card');
|
||||
}
|
||||
}
|
||||
|
|
@ -1,44 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace App\View\Components;
|
||||
|
||||
use Illuminate\View\Component;
|
||||
use App\Recipe;
|
||||
|
||||
class RecipeCard extends Component
|
||||
{
|
||||
/**
|
||||
* @var integer
|
||||
*/
|
||||
public $id;
|
||||
|
||||
/**
|
||||
* Recipe model
|
||||
*
|
||||
* @var \App\Recipe
|
||||
*/
|
||||
public $recipe;
|
||||
|
||||
/**
|
||||
* Create a new component instance.
|
||||
*
|
||||
* @param integer $id
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(int $id)
|
||||
{
|
||||
$this->recipe = Recipe::where('id', $id)->first();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the view / contents that represent the component.
|
||||
*
|
||||
* @return \Illuminate\Contracts\View\View|\Closure|string
|
||||
*/
|
||||
public function render()
|
||||
{
|
||||
$recipe = $this->recipe;
|
||||
|
||||
return view('components.recipe-card', compact('recipe'));
|
||||
}
|
||||
}
|
||||
|
|
@ -1,44 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace App\View\Components;
|
||||
|
||||
use Illuminate\View\Component;
|
||||
use App\Recipe;
|
||||
|
||||
class RecipeCardSmall extends Component
|
||||
{
|
||||
/**
|
||||
* @var integer
|
||||
*/
|
||||
public $id;
|
||||
|
||||
/**
|
||||
* Recipe model
|
||||
*
|
||||
* @var \App\Recipe
|
||||
*/
|
||||
public $recipe;
|
||||
|
||||
/**
|
||||
* Create a new component instance.
|
||||
*
|
||||
* @param integer $id
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(int $id)
|
||||
{
|
||||
$this->recipe = Recipe::where('id', $id)->first();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the view / contents that represent the component.
|
||||
*
|
||||
* @return \Illuminate\Contracts\View\View|\Closure|string
|
||||
*/
|
||||
public function render()
|
||||
{
|
||||
$recipe = $this->recipe;
|
||||
|
||||
return view('components.recipe-card-small', compact('recipe'));
|
||||
}
|
||||
}
|
||||
|
|
@ -1,45 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace App\View\Components;
|
||||
|
||||
use Illuminate\View\Component;
|
||||
use App\Product;
|
||||
|
||||
class RecipeProductStoerer extends Component
|
||||
{
|
||||
/**
|
||||
* id variable
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
public $id;
|
||||
|
||||
/**
|
||||
* product variable
|
||||
*
|
||||
* @var \App\Product
|
||||
*/
|
||||
public $product;
|
||||
|
||||
/**
|
||||
* Create a new component instance.
|
||||
*
|
||||
* @param integer $id
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(int $id)
|
||||
{
|
||||
$this->product = Product::where('id', $id)->first();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the view / contents that represent the component.
|
||||
*
|
||||
* @return \Illuminate\Contracts\View\View|\Closure|string
|
||||
*/
|
||||
public function render()
|
||||
{
|
||||
$product = $this->product;
|
||||
return view('components.recipe-product-stoerer', compact('product'));
|
||||
}
|
||||
}
|
||||
|
|
@ -1,63 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace App\View\Components;
|
||||
|
||||
use Illuminate\View\Component;
|
||||
use App\Recipe;
|
||||
|
||||
class RecipeWidget extends Component
|
||||
{
|
||||
/**
|
||||
* limit variable
|
||||
*
|
||||
* @var mixed
|
||||
*/
|
||||
private $limit;
|
||||
|
||||
/**
|
||||
* id variable
|
||||
*
|
||||
* @var mixed
|
||||
*/
|
||||
private $id;
|
||||
|
||||
/**
|
||||
* recipes variable
|
||||
*
|
||||
* @var \App\Recipe
|
||||
*/
|
||||
private $recipes;
|
||||
|
||||
/**
|
||||
* Create a new component instance.
|
||||
*
|
||||
* @param mixed $limit
|
||||
* @param mixed $id
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(mixed $limit, mixed $id = null)
|
||||
{
|
||||
$this->limit = 3;
|
||||
if ($limit != null) {
|
||||
$this->limit = $limit;
|
||||
}
|
||||
if ($id != null) {
|
||||
$this->id = $id;
|
||||
$this->recipes = Recipe::where('live', '1')
|
||||
->where('id', '!=', $this->id)->inRandomOrder()->limit($this->limit)->get();
|
||||
} else {
|
||||
$this->recipes = Recipe::where('live', '1')->inRandomOrder()->limit($this->limit)->get();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the view / contents that represent the component.
|
||||
*
|
||||
* @return \Illuminate\Contracts\View\View|\Closure|string
|
||||
*/
|
||||
public function render()
|
||||
{
|
||||
$recipes = $this->recipes;
|
||||
return view('components.recipe-widget', compact('recipes'));
|
||||
}
|
||||
}
|
||||
0
artisan
Normal file → Executable file
0
artisan
Normal file → Executable file
|
|
@ -2,27 +2,31 @@
|
|||
"name": "laravel/laravel",
|
||||
"type": "project",
|
||||
"description": "The Laravel Framework.",
|
||||
"keywords": ["framework", "laravel"],
|
||||
"keywords": [
|
||||
"framework",
|
||||
"laravel"
|
||||
],
|
||||
"license": "MIT",
|
||||
"require": {
|
||||
"php": "^8.0.2",
|
||||
"php": "^8.1",
|
||||
"diglactic/laravel-breadcrumbs": "^8.0",
|
||||
"guzzlehttp/guzzle": "^7.2",
|
||||
"laravel/framework": "^9.2",
|
||||
"laravel/tinker": "^2.7",
|
||||
"ldc/web-admin-secure-laravel": "^1.0",
|
||||
"ldc/web-status-checker-laravel": "^1.0",
|
||||
"sentry/sentry-laravel": "^3.1",
|
||||
"simplesoftwareio/simple-qrcode": "^4.2",
|
||||
"tcg/voyager": "^1.5"
|
||||
"laravel/framework": "^10.0",
|
||||
"laravel/tinker": "^2.8",
|
||||
"laravel/ui": "^4.2",
|
||||
"mews/purifier": "^3.4"
|
||||
},
|
||||
"require-dev": {
|
||||
"fakerphp/faker": "^1.9.1",
|
||||
"laravel/sail": "^1.0.1",
|
||||
"kitloong/laravel-migrations-generator": "^6.8",
|
||||
"krlove/eloquent-model-generator": "dev-l10-compatibility",
|
||||
"laravel/pint": "^1.0",
|
||||
"laravel/sail": "^1.18",
|
||||
"mockery/mockery": "^1.4.4",
|
||||
"nunomaduro/collision": "^6.1",
|
||||
"phpunit/phpunit": "^9.5.10",
|
||||
"slevomat/coding-standard": "^8.6",
|
||||
"spatie/laravel-ignition": "^1.0"
|
||||
"nunomaduro/collision": "^7.0",
|
||||
"phpunit/phpunit": "^10.0",
|
||||
"spatie/laravel-ignition": "^2.0",
|
||||
"thedoctor0/laravel-factory-generator": "^1.2"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
|
|
@ -31,6 +35,12 @@
|
|||
"Database\\Seeders\\": "database/seeders/"
|
||||
}
|
||||
},
|
||||
"repositories": [
|
||||
{
|
||||
"type": "vcs",
|
||||
"url": "https://github.com/laravel-shift/eloquent-model-generator.git"
|
||||
}
|
||||
],
|
||||
"autoload-dev": {
|
||||
"psr-4": {
|
||||
"Tests\\": "tests/"
|
||||
|
|
@ -61,15 +71,10 @@
|
|||
"preferred-install": "dist",
|
||||
"sort-packages": true,
|
||||
"allow-plugins": {
|
||||
"dealerdirect/phpcodesniffer-composer-installer": true
|
||||
"pestphp/pest-plugin": true,
|
||||
"php-http/discovery": true
|
||||
}
|
||||
},
|
||||
"minimum-stability": "dev",
|
||||
"prefer-stable": true,
|
||||
"repositories": {
|
||||
"gitlab.com/16669037": {
|
||||
"type": "composer",
|
||||
"url": "https://gitlab.com/api/v4/group/16669037/-/packages/composer/packages.json"
|
||||
}
|
||||
}
|
||||
"minimum-stability": "stable",
|
||||
"prefer-stable": true
|
||||
}
|
||||
|
|
|
|||
5668
composer.lock
generated
5668
composer.lock
generated
File diff suppressed because it is too large
Load diff
|
|
@ -1,9 +1,6 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Support\Facades\Facade;
|
||||
|
||||
return [
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Application Name
|
||||
|
|
@ -56,7 +53,7 @@ return [
|
|||
|
||||
'url' => env('APP_URL', 'http://localhost'),
|
||||
|
||||
'asset_url' => env('ASSET_URL'),
|
||||
'asset_url' => env('ASSET_URL', null),
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
@ -82,7 +79,7 @@ return [
|
|||
|
|
||||
*/
|
||||
|
||||
'locale' => 'de',
|
||||
'locale' => 'fr',
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
@ -108,7 +105,7 @@ return [
|
|||
|
|
||||
*/
|
||||
|
||||
'faker_locale' => 'en_US',
|
||||
'faker_locale' => 'fr_FR',
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
@ -138,9 +135,10 @@ return [
|
|||
|
||||
'providers' => [
|
||||
|
||||
/**
|
||||
/*
|
||||
* Laravel Framework Service Providers...
|
||||
*/
|
||||
|
||||
Illuminate\Auth\AuthServiceProvider::class,
|
||||
Illuminate\Broadcasting\BroadcastServiceProvider::class,
|
||||
Illuminate\Bus\BusServiceProvider::class,
|
||||
|
|
@ -163,19 +161,20 @@ return [
|
|||
Illuminate\Translation\TranslationServiceProvider::class,
|
||||
Illuminate\Validation\ValidationServiceProvider::class,
|
||||
Illuminate\View\ViewServiceProvider::class,
|
||||
SimpleSoftwareIO\QrCode\QrCodeServiceProvider::class,
|
||||
|
||||
/**
|
||||
/*
|
||||
* Package Service Providers...
|
||||
*/
|
||||
|
||||
/**
|
||||
/*
|
||||
* Application Service Providers...
|
||||
*/
|
||||
|
||||
App\Providers\AppServiceProvider::class,
|
||||
App\Providers\AuthServiceProvider::class,
|
||||
App\Providers\EventServiceProvider::class,
|
||||
App\Providers\RouteServiceProvider::class,
|
||||
App\Providers\TranslationServiceProvider::class
|
||||
|
||||
],
|
||||
|
||||
|
|
@ -190,8 +189,44 @@ return [
|
|||
|
|
||||
*/
|
||||
|
||||
'aliases' => Facade::defaultAliases()->merge([
|
||||
'QrCode' => SimpleSoftwareIO\QrCode\Facades\QrCode::class,
|
||||
])->toArray(),
|
||||
|
||||
'aliases' => [
|
||||
'App' => Illuminate\Support\Facades\App::class,
|
||||
'Arr' => Illuminate\Support\Arr::class,
|
||||
'Artisan' => Illuminate\Support\Facades\Artisan::class,
|
||||
'Auth' => Illuminate\Support\Facades\Auth::class,
|
||||
'Blade' => Illuminate\Support\Facades\Blade::class,
|
||||
'Broadcast' => Illuminate\Support\Facades\Broadcast::class,
|
||||
'Bus' => Illuminate\Support\Facades\Bus::class,
|
||||
'Cache' => Illuminate\Support\Facades\Cache::class,
|
||||
'Config' => Illuminate\Support\Facades\Config::class,
|
||||
'Cookie' => Illuminate\Support\Facades\Cookie::class,
|
||||
'Crypt' => Illuminate\Support\Facades\Crypt::class,
|
||||
'Date' => Illuminate\Support\Facades\Date::class,
|
||||
'DB' => Illuminate\Support\Facades\DB::class,
|
||||
'Eloquent' => Illuminate\Database\Eloquent\Model::class,
|
||||
'Event' => Illuminate\Support\Facades\Event::class,
|
||||
'File' => Illuminate\Support\Facades\File::class,
|
||||
'Gate' => Illuminate\Support\Facades\Gate::class,
|
||||
'Hash' => Illuminate\Support\Facades\Hash::class,
|
||||
'Http' => Illuminate\Support\Facades\Http::class,
|
||||
'Js' => Illuminate\Support\Js::class,
|
||||
'Lang' => Illuminate\Support\Facades\Lang::class,
|
||||
'Log' => Illuminate\Support\Facades\Log::class,
|
||||
'Mail' => Illuminate\Support\Facades\Mail::class,
|
||||
'Notification' => Illuminate\Support\Facades\Notification::class,
|
||||
'Password' => Illuminate\Support\Facades\Password::class,
|
||||
'Queue' => Illuminate\Support\Facades\Queue::class,
|
||||
'RateLimiter' => Illuminate\Support\Facades\RateLimiter::class,
|
||||
'Redirect' => Illuminate\Support\Facades\Redirect::class,
|
||||
'Request' => Illuminate\Support\Facades\Request::class,
|
||||
'Response' => Illuminate\Support\Facades\Response::class,
|
||||
'Route' => Illuminate\Support\Facades\Route::class,
|
||||
'Schema' => Illuminate\Support\Facades\Schema::class,
|
||||
'Session' => Illuminate\Support\Facades\Session::class,
|
||||
'Storage' => Illuminate\Support\Facades\Storage::class,
|
||||
'Str' => Illuminate\Support\Str::class,
|
||||
'URL' => Illuminate\Support\Facades\URL::class,
|
||||
'Validator' => Illuminate\Support\Facades\Validator::class,
|
||||
'View' => Illuminate\Support\Facades\View::class,
|
||||
],
|
||||
];
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ return [
|
|||
*/
|
||||
|
||||
'defaults' => [
|
||||
'guard' => 'web',
|
||||
'guard' => 'frontend',
|
||||
'passwords' => 'users',
|
||||
],
|
||||
|
||||
|
|
@ -36,10 +36,16 @@ return [
|
|||
*/
|
||||
|
||||
'guards' => [
|
||||
'web' => [
|
||||
'backend' => [
|
||||
'driver' => 'session',
|
||||
'provider' => 'users',
|
||||
],
|
||||
|
||||
'frontend' => [
|
||||
'driver' => 'session',
|
||||
// ! Remplacer "users" par le model authenticable voulu
|
||||
'provider' => 'users',
|
||||
],
|
||||
],
|
||||
|
||||
/*
|
||||
|
|
|
|||
78
config/breadcrumbs.php
Normal file
78
config/breadcrumbs.php
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
<?php
|
||||
|
||||
return [
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| View Name
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Choose a view to display when Breadcrumbs::render() is called.
|
||||
| Built in templates are:
|
||||
|
|
||||
| - 'breadcrumbs::bootstrap5' - Bootstrap 5
|
||||
| - 'breadcrumbs::bootstrap4' - Bootstrap 4
|
||||
| - 'breadcrumbs::bulma' - Bulma
|
||||
| - 'breadcrumbs::foundation6' - Foundation 6
|
||||
| - 'breadcrumbs::json-ld' - JSON-LD Structured Data
|
||||
| - 'breadcrumbs::materialize' - Materialize
|
||||
| - 'breadcrumbs::tailwind' - Tailwind CSS
|
||||
| - 'breadcrumbs::uikit' - UIkit
|
||||
|
|
||||
| Or a custom view, e.g. '_partials/breadcrumbs'.
|
||||
|
|
||||
*/
|
||||
|
||||
'view' => 'breadcrumbs/breadrcumb-layout',
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Breadcrumbs File(s)
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| The file(s) where breadcrumbs are defined. e.g.
|
||||
|
|
||||
| - base_path('routes/breadcrumbs.php')
|
||||
| - glob(base_path('breadcrumbs/*.php'))
|
||||
|
|
||||
*/
|
||||
|
||||
'files' => [
|
||||
base_path('routes/breadcrumbs-bo.php'),
|
||||
base_path('routes/breadcrumbs-fo.php'),
|
||||
],
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Exceptions
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Determine when to throw an exception.
|
||||
|
|
||||
*/
|
||||
|
||||
// * When route-bound breadcrumbs are used but the current route doesn't have a name (UnnamedRouteException)
|
||||
'unnamed-route-exception' => true,
|
||||
|
||||
// * When route-bound breadcrumbs are used and the matching breadcrumb doesn't exist (InvalidBreadcrumbException)
|
||||
'missing-route-bound-breadcrumb-exception' => true,
|
||||
|
||||
// * When a named breadcrumb is used but doesn't exist (InvalidBreadcrumbException)
|
||||
'invalid-named-breadcrumb-exception' => true,
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Classes
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Subclass the default classes for more advanced customisations.
|
||||
|
|
||||
*/
|
||||
|
||||
// * Manager
|
||||
'manager-class' => Diglactic\Breadcrumbs\Manager::class,
|
||||
|
||||
// * Generator
|
||||
'generator-class' => Diglactic\Breadcrumbs\Generator::class,
|
||||
|
||||
];
|
||||
|
|
@ -39,10 +39,6 @@ return [
|
|||
'cluster' => env('PUSHER_APP_CLUSTER'),
|
||||
'useTLS' => true,
|
||||
],
|
||||
'client_options' => [
|
||||
// phpcs:ignore
|
||||
// Guzzle client options: https://docs.guzzlephp.org/en/stable/request-options.html
|
||||
],
|
||||
],
|
||||
|
||||
'ably' => [
|
||||
|
|
|
|||
|
|
@ -62,8 +62,7 @@ return [
|
|||
env('MEMCACHED_PASSWORD'),
|
||||
],
|
||||
'options' => [
|
||||
// phpcs:ignore
|
||||
// Memcached::OPT_CONNECT_TIMEOUT => 2000,
|
||||
// Memcached::OPT_CONNECT_TIMEOUT => 2000, .
|
||||
],
|
||||
'servers' => [
|
||||
[
|
||||
|
|
@ -100,12 +99,12 @@ return [
|
|||
| Cache Key Prefix
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| When utilizing the APC, database, memcached, Redis, or DynamoDB cache
|
||||
| stores there might be other applications using the same cache. For
|
||||
| that reason, you may prefix every cache key to avoid collisions.
|
||||
| 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' => env('CACHE_PREFIX', Str::slug(env('APP_NAME', 'laravel'), '_') . '_cache_'),
|
||||
'prefix' => env('CACHE_PREFIX', Str::slug(env('APP_NAME', 'laravel'), '_') . '_cache'),
|
||||
|
||||
];
|
||||
|
|
|
|||
|
|
@ -74,7 +74,7 @@ return [
|
|||
'charset' => 'utf8',
|
||||
'prefix' => '',
|
||||
'prefix_indexes' => true,
|
||||
'search_path' => 'public',
|
||||
'schema' => 'public',
|
||||
'sslmode' => 'prefer',
|
||||
],
|
||||
|
||||
|
|
@ -89,9 +89,6 @@ return [
|
|||
'charset' => 'utf8',
|
||||
'prefix' => '',
|
||||
'prefix_indexes' => true,
|
||||
// phpcs:ignore
|
||||
// 'encrypt' => env('DB_ENCRYPT', 'yes'),
|
||||
// 'trust_server_certificate' => env('DB_TRUST_SERVER_CERTIFICATE', 'false'),
|
||||
],
|
||||
|
||||
],
|
||||
|
|
@ -132,8 +129,7 @@ return [
|
|||
'default' => [
|
||||
'url' => env('REDIS_URL'),
|
||||
'host' => env('REDIS_HOST', '127.0.0.1'),
|
||||
'username' => env('REDIS_USERNAME'),
|
||||
'password' => env('REDIS_PASSWORD'),
|
||||
'password' => env('REDIS_PASSWORD', null),
|
||||
'port' => env('REDIS_PORT', '6379'),
|
||||
'database' => env('REDIS_DB', '0'),
|
||||
],
|
||||
|
|
@ -141,8 +137,7 @@ return [
|
|||
'cache' => [
|
||||
'url' => env('REDIS_URL'),
|
||||
'host' => env('REDIS_HOST', '127.0.0.1'),
|
||||
'username' => env('REDIS_USERNAME'),
|
||||
'password' => env('REDIS_PASSWORD'),
|
||||
'password' => env('REDIS_PASSWORD', null),
|
||||
'port' => env('REDIS_PORT', '6379'),
|
||||
'database' => env('REDIS_CACHE_DB', '1'),
|
||||
],
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ return [
|
|||
|
|
||||
*/
|
||||
|
||||
'default' => env('FILESYSTEM_DISK', 'local'),
|
||||
'default' => env('FILESYSTEM_DRIVER', 'local'),
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
@ -22,7 +22,7 @@ return [
|
|||
|
|
||||
| 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 set up for each driver as an example of the required values.
|
||||
| been setup for each driver as an example of the required options.
|
||||
|
|
||||
| Supported Drivers: "local", "ftp", "sftp", "s3"
|
||||
|
|
||||
|
|
@ -33,7 +33,6 @@ return [
|
|||
'local' => [
|
||||
'driver' => 'local',
|
||||
'root' => storage_path('app'),
|
||||
'throw' => false,
|
||||
],
|
||||
|
||||
'public' => [
|
||||
|
|
@ -41,7 +40,6 @@ return [
|
|||
'root' => storage_path('app/public'),
|
||||
'url' => env('APP_URL') . '/storage',
|
||||
'visibility' => 'public',
|
||||
'throw' => false,
|
||||
],
|
||||
|
||||
's3' => [
|
||||
|
|
@ -53,7 +51,6 @@ return [
|
|||
'url' => env('AWS_URL'),
|
||||
'endpoint' => env('AWS_ENDPOINT'),
|
||||
'use_path_style_endpoint' => env('AWS_USE_PATH_STYLE_ENDPOINT', false),
|
||||
'throw' => false,
|
||||
],
|
||||
|
||||
],
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ return [
|
|||
'channels' => [
|
||||
'stack' => [
|
||||
'driver' => 'stack',
|
||||
'channels' => ['single'],
|
||||
'channels' => ['single', 'sentry'],
|
||||
'ignore_exceptions' => false,
|
||||
],
|
||||
|
||||
|
|
@ -60,6 +60,11 @@ return [
|
|||
'level' => env('LOG_LEVEL', 'debug'),
|
||||
],
|
||||
|
||||
'sentry' => [
|
||||
'driver' => 'sentry',
|
||||
'level' => env('LOG_LEVEL', 'error'),
|
||||
],
|
||||
|
||||
'daily' => [
|
||||
'driver' => 'daily',
|
||||
'path' => storage_path('logs/laravel.log'),
|
||||
|
|
@ -78,11 +83,10 @@ return [
|
|||
'papertrail' => [
|
||||
'driver' => 'monolog',
|
||||
'level' => env('LOG_LEVEL', 'debug'),
|
||||
'handler' => env('LOG_PAPERTRAIL_HANDLER', SyslogUdpHandler::class),
|
||||
'handler' => SyslogUdpHandler::class,
|
||||
'handler_with' => [
|
||||
'host' => env('PAPERTRAIL_URL'),
|
||||
'port' => env('PAPERTRAIL_PORT'),
|
||||
'connectionString' => 'tls://' . env('PAPERTRAIL_URL') . ':' . env('PAPERTRAIL_PORT'),
|
||||
],
|
||||
],
|
||||
|
||||
|
|
|
|||
|
|
@ -42,6 +42,7 @@ return [
|
|||
'username' => env('MAIL_USERNAME'),
|
||||
'password' => env('MAIL_PASSWORD'),
|
||||
'timeout' => null,
|
||||
'auth_mode' => null,
|
||||
],
|
||||
|
||||
'ses' => [
|
||||
|
|
@ -58,7 +59,7 @@ return [
|
|||
|
||||
'sendmail' => [
|
||||
'transport' => 'sendmail',
|
||||
'path' => env('MAIL_SENDMAIL_PATH', '/usr/sbin/sendmail -bs -i'),
|
||||
'path' => env('MAIL_SENDMAIL_PATH', '/usr/sbin/sendmail -t -i'),
|
||||
],
|
||||
|
||||
'log' => [
|
||||
|
|
|
|||
122
config/purifier.php
Normal file
122
config/purifier.php
Normal file
|
|
@ -0,0 +1,122 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Ok, glad you are here
|
||||
* first we get a config instance, and set the settings
|
||||
* $config = HTMLPurifier_Config::createDefault();
|
||||
* $config->set('Core.Encoding', $this->config->get('purifier.encoding'));
|
||||
* $config->set('Cache.SerializerPath', $this->config->get('purifier.cachePath'));
|
||||
* if ( ! $this->config->get('purifier.finalize')) {
|
||||
* $config->autoFinalize = false;
|
||||
* }
|
||||
* $config->load [$this->getConfig());
|
||||
*
|
||||
* You must NOT delete the default settings
|
||||
* anything in settings should be compacted with params that needed to instance HTMLPurifier_Config.
|
||||
*
|
||||
* @link http://htmlpurifier.org/live/configdoc/plain.html
|
||||
*/
|
||||
|
||||
// phpcs:disable Generic.Files.LineLength.TooLong
|
||||
return [
|
||||
'encoding' => 'UTF-8',
|
||||
'finalize' => true,
|
||||
'cachePath' => storage_path('app/purifier'),
|
||||
'cacheFileMode' => 0755,
|
||||
'settings' => [
|
||||
'default' => [
|
||||
'HTML.SafeIframe' => true,
|
||||
// * For iframes
|
||||
'URI.SafeIframeRegexp' => "%^(http://|https://|//)(www.youtube.com/embed/|player.vimeo.com/video/|vimeo.com/)%",
|
||||
'HTML.Doctype' => 'HTML 4.01 Transitional',
|
||||
// TODO: Rules en FULL CKEDITOR.
|
||||
// * Legacy filter en full avec safe legacy.
|
||||
// 'HTML.Allowed' => 'h1[style],h2[style],h3[style],h4[style],h5[style],h6[style],figure[class|style],oembed[url],div[style],b,strong,i,em,u,a[href|title|target|rel],ul[style],ol[style],dl[style],li,p[style],br,span[style|class],img[width|height|alt|src|style|class|title],iframe[src|width|height|class|frameborder|style],table[style|align|border|cellspacing|cellpadding|width],thead,tbody,th[colspan|align|valign|style],tr[align|valign|style],td[style|colspan|rowspan|scope|align|valign],hr,dl,dt',
|
||||
// * Restricted basics.
|
||||
'HTML.Allowed' => 'br,p[style],b,u,i,a[href|title|target|rel],strong,span[class],ul,ol,li,h2,h3,h4,hr',
|
||||
// * Legacy filter en full avec safe legacy.
|
||||
// 'CSS.AllowedProperties' => 'font,font-size,font-weight,font-style,font-family,text-decoration,padding-left,color,background-color,text-align,list-style-type,float,width,height,vertical-align,border-color',
|
||||
// * Restricted basics.
|
||||
'CSS.AllowedProperties' => 'text-align',
|
||||
'AutoFormat.AutoParagraph' => false,
|
||||
'AutoFormat.RemoveEmpty' => false,
|
||||
'AutoFormat.RemoveEmpty.RemoveNbsp' => false,
|
||||
],
|
||||
'custom_definition' => [
|
||||
'id' => 'html5-definitions',
|
||||
'rev' => 1,
|
||||
'debug' => true,
|
||||
'elements' => [
|
||||
// * http://developers.whatwg.org/sections.html
|
||||
['section', 'Block', 'Flow', 'Common'],
|
||||
['nav', 'Block', 'Flow', 'Common'],
|
||||
['article', 'Block', 'Flow', 'Common'],
|
||||
['aside', 'Block', 'Flow', 'Common'],
|
||||
['header', 'Block', 'Flow', 'Common'],
|
||||
['footer', 'Block', 'Flow', 'Common'],
|
||||
|
||||
// * Content model actually excludes several tags, not modelled here
|
||||
['address', 'Block', 'Flow', 'Common'],
|
||||
['hgroup', 'Block', 'Required: h1 | h2 | h3 | h4 | h5 | h6', 'Common'],
|
||||
|
||||
// * http://developers.whatwg.org/grouping-content.html
|
||||
['figure', 'Block', 'Optional: (figcaption, Flow) | (Flow, figcaption) | Flow', 'Common'],
|
||||
['figcaption', 'Inline', 'Flow', 'Common'],
|
||||
['oembed', 'Inline', 'Flow', 'Common'],
|
||||
|
||||
// * http://developers.whatwg.org/the-video-element.html#the-video-element
|
||||
['video', 'Block', 'Optional: (source, Flow) | (Flow, source) | Flow', 'Common', [
|
||||
'src' => 'URI',
|
||||
'type' => 'Text',
|
||||
'width' => 'Length',
|
||||
'height' => 'Length',
|
||||
'poster' => 'URI',
|
||||
'preload' => 'Enum#auto,metadata,none',
|
||||
'controls' => 'Bool',
|
||||
]],
|
||||
['source', 'Block', 'Flow', 'Common', [
|
||||
'src' => 'URI',
|
||||
'type' => 'Text',
|
||||
]],
|
||||
|
||||
// * http://developers.whatwg.org/text-level-semantics.html
|
||||
['s', 'Inline', 'Inline', 'Common'],
|
||||
['var', 'Inline', 'Inline', 'Common'],
|
||||
['sub', 'Inline', 'Inline', 'Common'],
|
||||
['sup', 'Inline', 'Inline', 'Common'],
|
||||
['mark', 'Inline', 'Inline', 'Common'],
|
||||
['wbr', 'Inline', 'Empty', 'Core'],
|
||||
|
||||
// * http://developers.whatwg.org/edits.html
|
||||
['ins', 'Block', 'Flow', 'Common', ['cite' => 'URI', 'datetime' => 'CDATA']],
|
||||
['del', 'Block', 'Flow', 'Common', ['cite' => 'URI', 'datetime' => 'CDATA']],
|
||||
],
|
||||
'attributes' => [
|
||||
['iframe', 'allowfullscreen', 'Bool'],
|
||||
['table', 'height', 'Text'],
|
||||
['td', 'border', 'Text'],
|
||||
['th', 'border', 'Text'],
|
||||
['tr', 'width', 'Text'],
|
||||
['tr', 'height', 'Text'],
|
||||
['tr', 'border', 'Text'],
|
||||
['figure', 'class', 'Text'],
|
||||
['figure', 'style', 'Text'],
|
||||
['oembed', 'url', 'Text'],
|
||||
['span', 'style', 'Text'],
|
||||
['img', 'style', 'Text'],
|
||||
],
|
||||
],
|
||||
'custom_attributes' => [
|
||||
['a', 'target', 'Enum#_blank,_self,_target,_top'],
|
||||
['ol', 'style', 'Text'],
|
||||
['figure', 'style', 'Text'],
|
||||
['img', 'style', 'Text'],
|
||||
['span', 'style', 'Text'],
|
||||
['oembed', 'url', 'Text'],
|
||||
],
|
||||
'custom_elements' => [
|
||||
['u', 'Inline', 'Inline', 'Common'],
|
||||
['oembed', 'Inline', 'Inline', 'Common'],
|
||||
],
|
||||
],
|
||||
];
|
||||
|
|
@ -4,7 +4,7 @@ return [
|
|||
|
||||
'dsn' => env('SENTRY_LARAVEL_DSN', env('SENTRY_DSN')),
|
||||
|
||||
// The release version of your application
|
||||
// The release version of your application.
|
||||
// Example with dynamic git hash: trim(exec('git --git-dir ' . base_path('.git') . ' log --pretty="%h" -n1 HEAD')).
|
||||
'release' => env('SENTRY_RELEASE'),
|
||||
|
||||
|
|
@ -51,12 +51,11 @@ return [
|
|||
'missing_routes' => false,
|
||||
],
|
||||
|
||||
// @see: https://docs.sentry.io/platforms/php/guides/laravel/configuration/options/#send-default-pii
|
||||
// @see: https://docs.sentry.io/platforms/php/guides/laravel/configuration/options/#send-default-pii.
|
||||
'send_default_pii' => env('SENTRY_SEND_DEFAULT_PII', false),
|
||||
|
||||
// @see: https://docs.sentry.io/platforms/php/guides/laravel/configuration/options/#traces-sample-rate
|
||||
// @see: https://docs.sentry.io/platforms/php/guides/laravel/configuration/options/#traces-sample-rate.
|
||||
'traces_sample_rate' => env('SENTRY_TRACES_SAMPLE_RATE') === null ? null : (float)env('SENTRY_TRACES_SAMPLE_RATE'),
|
||||
|
||||
'before_send' => [\App\Lib\ExceptionsHelper::class, 'sentryEventHandler'],
|
||||
|
||||
'before_send' => [\App\Lib\Helpers\ExceptionsHelper::class, 'sentryEventHandler'],
|
||||
];
|
||||
|
|
|
|||
|
|
@ -18,7 +18,6 @@ return [
|
|||
'domain' => env('MAILGUN_DOMAIN'),
|
||||
'secret' => env('MAILGUN_SECRET'),
|
||||
'endpoint' => env('MAILGUN_ENDPOINT', 'api.mailgun.net'),
|
||||
'scheme' => 'https',
|
||||
],
|
||||
|
||||
'postmark' => [
|
||||
|
|
@ -31,10 +30,4 @@ return [
|
|||
'region' => env('AWS_DEFAULT_REGION', 'us-east-1'),
|
||||
],
|
||||
|
||||
'google' => [
|
||||
'maps' => [
|
||||
'key' => env('GOOGLE_MAPS_KEY')
|
||||
]
|
||||
]
|
||||
|
||||
];
|
||||
|
|
|
|||
|
|
@ -72,7 +72,7 @@ return [
|
|||
|
|
||||
*/
|
||||
|
||||
'connection' => env('SESSION_CONNECTION'),
|
||||
'connection' => env('SESSION_CONNECTION', null),
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
@ -100,7 +100,7 @@ return [
|
|||
|
|
||||
*/
|
||||
|
||||
'store' => env('SESSION_STORE'),
|
||||
'store' => env('SESSION_STORE', null),
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
@ -155,7 +155,7 @@ return [
|
|||
|
|
||||
*/
|
||||
|
||||
'domain' => env('SESSION_DOMAIN'),
|
||||
'domain' => env('SESSION_DOMAIN', null),
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -1,247 +0,0 @@
|
|||
<?php
|
||||
|
||||
return [
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| User config
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Here you can specify voyager user configs
|
||||
|
|
||||
*/
|
||||
|
||||
'user' => [
|
||||
'add_default_role_on_register' => true,
|
||||
'default_role' => 'user',
|
||||
'default_avatar' => 'users/default.png',
|
||||
'redirect' => '/admin',
|
||||
],
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Controllers config
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Here you can specify voyager controller settings
|
||||
|
|
||||
*/
|
||||
|
||||
'controllers' => [
|
||||
'namespace' => 'TCG\\Voyager\\Http\\Controllers',
|
||||
],
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Models config
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Here you can specify default model namespace when creating BREAD.
|
||||
| Must include trailing backslashes. If not defined the default application
|
||||
| namespace will be used.
|
||||
|
|
||||
*/
|
||||
|
||||
'models' => [
|
||||
// phpcs:ignore
|
||||
// 'namespace' => 'App\\Models\\',
|
||||
],
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Storage Config
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Here you can specify attributes related to your application file system
|
||||
|
|
||||
*/
|
||||
|
||||
'storage' => [
|
||||
'disk' => 'public',
|
||||
],
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Media Manager
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Here you can specify if media manager can show hidden files like(.gitignore)
|
||||
|
|
||||
*/
|
||||
|
||||
'hidden_files' => false,
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Database Config
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Here you can specify voyager database settings
|
||||
|
|
||||
*/
|
||||
|
||||
'database' => [
|
||||
'tables' => [
|
||||
'hidden' => [
|
||||
'migrations', 'data_rows', 'data_types', 'menu_items', 'password_resets', 'permission_role', 'settings'
|
||||
],
|
||||
],
|
||||
'autoload_migrations' => true,
|
||||
],
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Multilingual configuration
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Here you can specify if you want Voyager to ship with support for
|
||||
| multilingual and what locales are enabled.
|
||||
|
|
||||
*/
|
||||
|
||||
'multilingual' => [
|
||||
/**
|
||||
* Set whether or not the multilingual is supported by the BREAD input.
|
||||
*/
|
||||
'enabled' => false,
|
||||
|
||||
/**
|
||||
* Select default language
|
||||
*/
|
||||
'default' => 'en',
|
||||
|
||||
/**
|
||||
* Select languages that are supported.
|
||||
*/
|
||||
'locales' => [
|
||||
'en',
|
||||
// 'pt',
|
||||
],
|
||||
],
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Dashboard config
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Here you can modify some aspects of your dashboard
|
||||
|
|
||||
*/
|
||||
|
||||
'dashboard' => [
|
||||
// Add custom list items to navbar's dropdown.
|
||||
'navbar_items' => [
|
||||
'voyager::generic.profile' => [
|
||||
'route' => 'voyager.profile',
|
||||
'classes' => 'class-full-of-rum',
|
||||
'icon_class' => 'voyager-person',
|
||||
],
|
||||
'voyager::generic.home' => [
|
||||
'route' => '/',
|
||||
'icon_class' => 'voyager-home',
|
||||
'target_blank' => true,
|
||||
],
|
||||
'voyager::generic.logout' => [
|
||||
'route' => 'voyager.logout',
|
||||
'icon_class' => 'voyager-power',
|
||||
],
|
||||
],
|
||||
|
||||
'widgets' => [
|
||||
|
||||
],
|
||||
|
||||
],
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Automatic Procedures
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| When a change happens on Voyager, we can automate some routines.
|
||||
|
|
||||
*/
|
||||
|
||||
'bread' => [
|
||||
// When a BREAD is added, create the Menu item using the BREAD properties.
|
||||
'add_menu_item' => true,
|
||||
|
||||
// Which menu add item to.
|
||||
'default_menu' => 'admin',
|
||||
|
||||
// When a BREAD is added, create the related Permission.
|
||||
'add_permission' => true,
|
||||
|
||||
// Which role add premissions to.
|
||||
'default_role' => 'admin',
|
||||
],
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| UI Generic Config
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Here you change some of the Voyager UI settings.
|
||||
|
|
||||
*/
|
||||
|
||||
'primary_color' => '#22A7F0',
|
||||
|
||||
'show_dev_tips' => true,
|
||||
// Here you can specify additional assets you would like to be included in the master.blade.
|
||||
'additional_css' => [
|
||||
// 'css/custom.css',
|
||||
],
|
||||
|
||||
'additional_js' => [
|
||||
// 'js/custom.js',
|
||||
],
|
||||
|
||||
'googlemaps' => [
|
||||
'key' => env('GOOGLE_MAPS_KEY', ''),
|
||||
'center' => [
|
||||
'lat' => env('GOOGLE_MAPS_DEFAULT_CENTER_LAT', '32.715738'),
|
||||
'lng' => env('GOOGLE_MAPS_DEFAULT_CENTER_LNG', '-117.161084'),
|
||||
],
|
||||
'zoom' => env('GOOGLE_MAPS_DEFAULT_ZOOM', 11),
|
||||
],
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Model specific settings
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Here you change some model specific settings
|
||||
|
|
||||
*/
|
||||
|
||||
'settings' => [
|
||||
// Enables Laravel cache method for
|
||||
// Storing cache values between requests.
|
||||
'cache' => false,
|
||||
],
|
||||
|
||||
// Activate compass when environment is NOT local.
|
||||
'compass_in_production' => false,
|
||||
|
||||
'media' => [
|
||||
// The allowed mimetypes to be uploaded through the media-manager.
|
||||
'allowed_mimetypes' => [
|
||||
'image/jpeg',
|
||||
'image/png',
|
||||
'image/gif',
|
||||
'image/bmp',
|
||||
'image/webp',
|
||||
'image/svg+xml',
|
||||
'video/mp4',
|
||||
],
|
||||
// Path for media-manager. Relative to the filesystem.
|
||||
'path' => '/',
|
||||
'show_folders' => true,
|
||||
'allow_upload' => true,
|
||||
'allow_move' => true,
|
||||
'allow_delete' => true,
|
||||
'allow_create_folder' => true,
|
||||
'allow_rename' => true,
|
||||
],
|
||||
];
|
||||
|
|
@ -5,22 +5,21 @@ namespace Database\Factories;
|
|||
use Illuminate\Database\Eloquent\Factories\Factory;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
/**
|
||||
* @extends \Illuminate\Database\Eloquent\Factories\Factory<\App\Models\User>
|
||||
*/
|
||||
class UserFactory extends Factory
|
||||
{
|
||||
/**
|
||||
* Define the model's default state.
|
||||
*
|
||||
* @return array<string, mixed>
|
||||
* @return array
|
||||
*/
|
||||
public function definition()
|
||||
{
|
||||
return [
|
||||
'name' => $this->faker->name(),
|
||||
'firstname' => $this->faker->firstname(),
|
||||
'lastname' => $this->faker->lastname(),
|
||||
'email' => $this->faker->unique()->safeEmail(),
|
||||
'email_verified_at' => now(),
|
||||
// * password
|
||||
'password' => '$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi',
|
||||
'remember_token' => Str::random(10),
|
||||
];
|
||||
|
|
@ -29,7 +28,7 @@ class UserFactory extends Factory
|
|||
/**
|
||||
* Indicate that the model's email address should be unverified.
|
||||
*
|
||||
* @return static
|
||||
* @return \Illuminate\Database\Eloquent\Factories\Factory
|
||||
*/
|
||||
public function unverified()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ use Illuminate\Database\Migrations\Migration;
|
|||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
class CreateUsersTable extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
|
|
@ -15,7 +15,8 @@ return new class extends Migration
|
|||
{
|
||||
Schema::create('users', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('name');
|
||||
$table->string('firstname');
|
||||
$table->string('lastname');
|
||||
$table->string('email')->unique();
|
||||
$table->timestamp('email_verified_at')->nullable();
|
||||
$table->string('password');
|
||||
|
|
@ -33,4 +34,4 @@ return new class extends Migration
|
|||
{
|
||||
Schema::dropIfExists('users');
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ use Illuminate\Database\Migrations\Migration;
|
|||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
class CreatePasswordResetsTable extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
|
|
@ -29,4 +29,4 @@ return new class extends Migration
|
|||
{
|
||||
Schema::dropIfExists('password_resets');
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ use Illuminate\Database\Migrations\Migration;
|
|||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
class CreateFailedJobsTable extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
|
|
@ -33,4 +33,4 @@ return new class extends Migration
|
|||
{
|
||||
Schema::dropIfExists('failed_jobs');
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,36 +0,0 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::create('personal_access_tokens', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->morphs('tokenable');
|
||||
$table->string('name');
|
||||
$table->string('token', 64)->unique();
|
||||
$table->text('abilities')->nullable();
|
||||
$table->timestamp('last_used_at')->nullable();
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::dropIfExists('personal_access_tokens');
|
||||
}
|
||||
};
|
||||
|
|
@ -1,372 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Database\Seeders;
|
||||
|
||||
use Illuminate\Database\Seeder;
|
||||
use TCG\Voyager\Models\DataRow;
|
||||
use TCG\Voyager\Models\DataType;
|
||||
|
||||
class DataRowsTableSeeder extends Seeder
|
||||
{
|
||||
/**
|
||||
* Auto generated seed file.
|
||||
*/
|
||||
public function run()
|
||||
{
|
||||
$userDataType = DataType::where('slug', 'users')->firstOrFail();
|
||||
$menuDataType = DataType::where('slug', 'menus')->firstOrFail();
|
||||
$roleDataType = DataType::where('slug', 'roles')->firstOrFail();
|
||||
|
||||
$dataRow = $this->dataRow($userDataType, 'id');
|
||||
if (!$dataRow->exists) {
|
||||
$dataRow->fill([
|
||||
'type' => 'number',
|
||||
'display_name' => __('voyager::seeders.data_rows.id'),
|
||||
'required' => 1,
|
||||
'browse' => 0,
|
||||
'read' => 0,
|
||||
'edit' => 0,
|
||||
'add' => 0,
|
||||
'delete' => 0,
|
||||
'order' => 1,
|
||||
])->save();
|
||||
}
|
||||
|
||||
$dataRow = $this->dataRow($userDataType, 'name');
|
||||
if (!$dataRow->exists) {
|
||||
$dataRow->fill([
|
||||
'type' => 'text',
|
||||
'display_name' => __('voyager::seeders.data_rows.name'),
|
||||
'required' => 1,
|
||||
'browse' => 1,
|
||||
'read' => 1,
|
||||
'edit' => 1,
|
||||
'add' => 1,
|
||||
'delete' => 1,
|
||||
'order' => 2,
|
||||
])->save();
|
||||
}
|
||||
|
||||
$dataRow = $this->dataRow($userDataType, 'email');
|
||||
if (!$dataRow->exists) {
|
||||
$dataRow->fill([
|
||||
'type' => 'text',
|
||||
'display_name' => __('voyager::seeders.data_rows.email'),
|
||||
'required' => 1,
|
||||
'browse' => 1,
|
||||
'read' => 1,
|
||||
'edit' => 1,
|
||||
'add' => 1,
|
||||
'delete' => 1,
|
||||
'order' => 3,
|
||||
])->save();
|
||||
}
|
||||
|
||||
$dataRow = $this->dataRow($userDataType, 'password');
|
||||
if (!$dataRow->exists) {
|
||||
$dataRow->fill([
|
||||
'type' => 'password',
|
||||
'display_name' => __('voyager::seeders.data_rows.password'),
|
||||
'required' => 1,
|
||||
'browse' => 0,
|
||||
'read' => 0,
|
||||
'edit' => 1,
|
||||
'add' => 1,
|
||||
'delete' => 0,
|
||||
'order' => 4,
|
||||
])->save();
|
||||
}
|
||||
|
||||
$dataRow = $this->dataRow($userDataType, 'remember_token');
|
||||
if (!$dataRow->exists) {
|
||||
$dataRow->fill([
|
||||
'type' => 'text',
|
||||
'display_name' => __('voyager::seeders.data_rows.remember_token'),
|
||||
'required' => 0,
|
||||
'browse' => 0,
|
||||
'read' => 0,
|
||||
'edit' => 0,
|
||||
'add' => 0,
|
||||
'delete' => 0,
|
||||
'order' => 5,
|
||||
])->save();
|
||||
}
|
||||
|
||||
$dataRow = $this->dataRow($userDataType, 'created_at');
|
||||
if (!$dataRow->exists) {
|
||||
$dataRow->fill([
|
||||
'type' => 'timestamp',
|
||||
'display_name' => __('voyager::seeders.data_rows.created_at'),
|
||||
'required' => 0,
|
||||
'browse' => 1,
|
||||
'read' => 1,
|
||||
'edit' => 0,
|
||||
'add' => 0,
|
||||
'delete' => 0,
|
||||
'order' => 6,
|
||||
])->save();
|
||||
}
|
||||
|
||||
$dataRow = $this->dataRow($userDataType, 'updated_at');
|
||||
if (!$dataRow->exists) {
|
||||
$dataRow->fill([
|
||||
'type' => 'timestamp',
|
||||
'display_name' => __('voyager::seeders.data_rows.updated_at'),
|
||||
'required' => 0,
|
||||
'browse' => 0,
|
||||
'read' => 0,
|
||||
'edit' => 0,
|
||||
'add' => 0,
|
||||
'delete' => 0,
|
||||
'order' => 7,
|
||||
])->save();
|
||||
}
|
||||
|
||||
$dataRow = $this->dataRow($userDataType, 'avatar');
|
||||
if (!$dataRow->exists) {
|
||||
$dataRow->fill([
|
||||
'type' => 'image',
|
||||
'display_name' => __('voyager::seeders.data_rows.avatar'),
|
||||
'required' => 0,
|
||||
'browse' => 1,
|
||||
'read' => 1,
|
||||
'edit' => 1,
|
||||
'add' => 1,
|
||||
'delete' => 1,
|
||||
'order' => 8,
|
||||
])->save();
|
||||
}
|
||||
|
||||
$dataRow = $this->dataRow($userDataType, 'user_belongsto_role_relationship');
|
||||
if (!$dataRow->exists) {
|
||||
$dataRow->fill([
|
||||
'type' => 'relationship',
|
||||
'display_name' => __('voyager::seeders.data_rows.role'),
|
||||
'required' => 0,
|
||||
'browse' => 1,
|
||||
'read' => 1,
|
||||
'edit' => 1,
|
||||
'add' => 1,
|
||||
'delete' => 0,
|
||||
'details' => [
|
||||
'model' => 'TCG\\Voyager\\Models\\Role',
|
||||
'table' => 'roles',
|
||||
'type' => 'belongsTo',
|
||||
'column' => 'role_id',
|
||||
'key' => 'id',
|
||||
'label' => 'display_name',
|
||||
'pivot_table' => 'roles',
|
||||
'pivot' => 0,
|
||||
],
|
||||
'order' => 10,
|
||||
])->save();
|
||||
}
|
||||
|
||||
$dataRow = $this->dataRow($userDataType, 'user_belongstomany_role_relationship');
|
||||
if (!$dataRow->exists) {
|
||||
$dataRow->fill([
|
||||
'type' => 'relationship',
|
||||
'display_name' => __('voyager::seeders.data_rows.roles'),
|
||||
'required' => 0,
|
||||
'browse' => 1,
|
||||
'read' => 1,
|
||||
'edit' => 1,
|
||||
'add' => 1,
|
||||
'delete' => 0,
|
||||
'details' => [
|
||||
'model' => 'TCG\\Voyager\\Models\\Role',
|
||||
'table' => 'roles',
|
||||
'type' => 'belongsToMany',
|
||||
'column' => 'id',
|
||||
'key' => 'id',
|
||||
'label' => 'display_name',
|
||||
'pivot_table' => 'user_roles',
|
||||
'pivot' => '1',
|
||||
'taggable' => '0',
|
||||
],
|
||||
'order' => 11,
|
||||
])->save();
|
||||
}
|
||||
|
||||
$dataRow = $this->dataRow($userDataType, 'settings');
|
||||
if (!$dataRow->exists) {
|
||||
$dataRow->fill([
|
||||
'type' => 'hidden',
|
||||
'display_name' => 'Settings',
|
||||
'required' => 0,
|
||||
'browse' => 0,
|
||||
'read' => 0,
|
||||
'edit' => 0,
|
||||
'add' => 0,
|
||||
'delete' => 0,
|
||||
'order' => 12,
|
||||
])->save();
|
||||
}
|
||||
|
||||
$dataRow = $this->dataRow($menuDataType, 'id');
|
||||
if (!$dataRow->exists) {
|
||||
$dataRow->fill([
|
||||
'type' => 'number',
|
||||
'display_name' => __('voyager::seeders.data_rows.id'),
|
||||
'required' => 1,
|
||||
'browse' => 0,
|
||||
'read' => 0,
|
||||
'edit' => 0,
|
||||
'add' => 0,
|
||||
'delete' => 0,
|
||||
'order' => 1,
|
||||
])->save();
|
||||
}
|
||||
|
||||
$dataRow = $this->dataRow($menuDataType, 'name');
|
||||
if (!$dataRow->exists) {
|
||||
$dataRow->fill([
|
||||
'type' => 'text',
|
||||
'display_name' => __('voyager::seeders.data_rows.name'),
|
||||
'required' => 1,
|
||||
'browse' => 1,
|
||||
'read' => 1,
|
||||
'edit' => 1,
|
||||
'add' => 1,
|
||||
'delete' => 1,
|
||||
'order' => 2,
|
||||
])->save();
|
||||
}
|
||||
|
||||
$dataRow = $this->dataRow($menuDataType, 'created_at');
|
||||
if (!$dataRow->exists) {
|
||||
$dataRow->fill([
|
||||
'type' => 'timestamp',
|
||||
'display_name' => __('voyager::seeders.data_rows.created_at'),
|
||||
'required' => 0,
|
||||
'browse' => 0,
|
||||
'read' => 0,
|
||||
'edit' => 0,
|
||||
'add' => 0,
|
||||
'delete' => 0,
|
||||
'order' => 3,
|
||||
])->save();
|
||||
}
|
||||
|
||||
$dataRow = $this->dataRow($menuDataType, 'updated_at');
|
||||
if (!$dataRow->exists) {
|
||||
$dataRow->fill([
|
||||
'type' => 'timestamp',
|
||||
'display_name' => __('voyager::seeders.data_rows.updated_at'),
|
||||
'required' => 0,
|
||||
'browse' => 0,
|
||||
'read' => 0,
|
||||
'edit' => 0,
|
||||
'add' => 0,
|
||||
'delete' => 0,
|
||||
'order' => 4,
|
||||
])->save();
|
||||
}
|
||||
|
||||
$dataRow = $this->dataRow($roleDataType, 'id');
|
||||
if (!$dataRow->exists) {
|
||||
$dataRow->fill([
|
||||
'type' => 'number',
|
||||
'display_name' => __('voyager::seeders.data_rows.id'),
|
||||
'required' => 1,
|
||||
'browse' => 0,
|
||||
'read' => 0,
|
||||
'edit' => 0,
|
||||
'add' => 0,
|
||||
'delete' => 0,
|
||||
'order' => 1,
|
||||
])->save();
|
||||
}
|
||||
|
||||
$dataRow = $this->dataRow($roleDataType, 'name');
|
||||
if (!$dataRow->exists) {
|
||||
$dataRow->fill([
|
||||
'type' => 'text',
|
||||
'display_name' => __('voyager::seeders.data_rows.name'),
|
||||
'required' => 1,
|
||||
'browse' => 1,
|
||||
'read' => 1,
|
||||
'edit' => 1,
|
||||
'add' => 1,
|
||||
'delete' => 1,
|
||||
'order' => 2,
|
||||
])->save();
|
||||
}
|
||||
|
||||
$dataRow = $this->dataRow($roleDataType, 'created_at');
|
||||
if (!$dataRow->exists) {
|
||||
$dataRow->fill([
|
||||
'type' => 'timestamp',
|
||||
'display_name' => __('voyager::seeders.data_rows.created_at'),
|
||||
'required' => 0,
|
||||
'browse' => 0,
|
||||
'read' => 0,
|
||||
'edit' => 0,
|
||||
'add' => 0,
|
||||
'delete' => 0,
|
||||
'order' => 3,
|
||||
])->save();
|
||||
}
|
||||
|
||||
$dataRow = $this->dataRow($roleDataType, 'updated_at');
|
||||
if (!$dataRow->exists) {
|
||||
$dataRow->fill([
|
||||
'type' => 'timestamp',
|
||||
'display_name' => __('voyager::seeders.data_rows.updated_at'),
|
||||
'required' => 0,
|
||||
'browse' => 0,
|
||||
'read' => 0,
|
||||
'edit' => 0,
|
||||
'add' => 0,
|
||||
'delete' => 0,
|
||||
'order' => 4,
|
||||
])->save();
|
||||
}
|
||||
|
||||
$dataRow = $this->dataRow($roleDataType, 'display_name');
|
||||
if (!$dataRow->exists) {
|
||||
$dataRow->fill([
|
||||
'type' => 'text',
|
||||
'display_name' => __('voyager::seeders.data_rows.display_name'),
|
||||
'required' => 1,
|
||||
'browse' => 1,
|
||||
'read' => 1,
|
||||
'edit' => 1,
|
||||
'add' => 1,
|
||||
'delete' => 1,
|
||||
'order' => 5,
|
||||
])->save();
|
||||
}
|
||||
|
||||
$dataRow = $this->dataRow($userDataType, 'role_id');
|
||||
if (!$dataRow->exists) {
|
||||
$dataRow->fill([
|
||||
'type' => 'text',
|
||||
'display_name' => __('voyager::seeders.data_rows.role'),
|
||||
'required' => 1,
|
||||
'browse' => 1,
|
||||
'read' => 1,
|
||||
'edit' => 1,
|
||||
'add' => 1,
|
||||
'delete' => 1,
|
||||
'order' => 9,
|
||||
])->save();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* [dataRow description].
|
||||
*
|
||||
* @param [type] $type [description]
|
||||
* @param [type] $field [description]
|
||||
*
|
||||
* @return [type] [description]
|
||||
*/
|
||||
protected function dataRow($type, $field)
|
||||
{
|
||||
return DataRow::firstOrNew([
|
||||
'data_type_id' => $type->id,
|
||||
'field' => $field,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,71 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Database\Seeders;
|
||||
|
||||
use Illuminate\Database\Seeder;
|
||||
use TCG\Voyager\Models\DataType;
|
||||
|
||||
class DataTypesTableSeeder extends Seeder
|
||||
{
|
||||
/**
|
||||
* Auto generated seed file.
|
||||
*/
|
||||
public function run()
|
||||
{
|
||||
$dataType = $this->dataType('slug', 'users');
|
||||
if (!$dataType->exists) {
|
||||
$dataType->fill([
|
||||
'name' => 'users',
|
||||
'display_name_singular' => __('voyager::seeders.data_types.user.singular'),
|
||||
'display_name_plural' => __('voyager::seeders.data_types.user.plural'),
|
||||
'icon' => 'voyager-person',
|
||||
'model_name' => 'TCG\\Voyager\\Models\\User',
|
||||
'policy_name' => 'TCG\\Voyager\\Policies\\UserPolicy',
|
||||
'controller' => 'TCG\\Voyager\\Http\\Controllers\\VoyagerUserController',
|
||||
'generate_permissions' => 1,
|
||||
'description' => '',
|
||||
])->save();
|
||||
}
|
||||
|
||||
$dataType = $this->dataType('slug', 'menus');
|
||||
if (!$dataType->exists) {
|
||||
$dataType->fill([
|
||||
'name' => 'menus',
|
||||
'display_name_singular' => __('voyager::seeders.data_types.menu.singular'),
|
||||
'display_name_plural' => __('voyager::seeders.data_types.menu.plural'),
|
||||
'icon' => 'voyager-list',
|
||||
'model_name' => 'TCG\\Voyager\\Models\\Menu',
|
||||
'controller' => '',
|
||||
'generate_permissions' => 1,
|
||||
'description' => '',
|
||||
])->save();
|
||||
}
|
||||
|
||||
$dataType = $this->dataType('slug', 'roles');
|
||||
if (!$dataType->exists) {
|
||||
$dataType->fill([
|
||||
'name' => 'roles',
|
||||
'display_name_singular' => __('voyager::seeders.data_types.role.singular'),
|
||||
'display_name_plural' => __('voyager::seeders.data_types.role.plural'),
|
||||
'icon' => 'voyager-lock',
|
||||
'model_name' => 'TCG\\Voyager\\Models\\Role',
|
||||
'controller' => 'TCG\\Voyager\\Http\\Controllers\\VoyagerRoleController',
|
||||
'generate_permissions' => 1,
|
||||
'description' => '',
|
||||
])->save();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* [dataType description].
|
||||
*
|
||||
* @param [type] $field [description]
|
||||
* @param [type] $for [description]
|
||||
*
|
||||
* @return [type] [description]
|
||||
*/
|
||||
protected function dataType($field, $for)
|
||||
{
|
||||
return DataType::firstOrNew([$field => $for]);
|
||||
}
|
||||
}
|
||||
|
|
@ -2,7 +2,6 @@
|
|||
|
||||
namespace Database\Seeders;
|
||||
|
||||
use Illuminate\Database\Console\Seeds\WithoutModelEvents;
|
||||
use Illuminate\Database\Seeder;
|
||||
|
||||
class DatabaseSeeder extends Seeder
|
||||
|
|
@ -14,6 +13,5 @@ class DatabaseSeeder extends Seeder
|
|||
*/
|
||||
public function run()
|
||||
{
|
||||
// \App\Models\User::factory(10)->create();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,179 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Database\Seeders;
|
||||
|
||||
use Illuminate\Database\Seeder;
|
||||
use TCG\Voyager\Models\Menu;
|
||||
use TCG\Voyager\Models\MenuItem;
|
||||
|
||||
class MenuItemsTableSeeder extends Seeder
|
||||
{
|
||||
/**
|
||||
* Auto generated seed file.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function run()
|
||||
{
|
||||
$menu = Menu::where('name', 'admin')->firstOrFail();
|
||||
|
||||
$menuItem = MenuItem::firstOrNew([
|
||||
'menu_id' => $menu->id,
|
||||
'title' => __('voyager::seeders.menu_items.dashboard'),
|
||||
'url' => '',
|
||||
'route' => 'voyager.dashboard',
|
||||
]);
|
||||
if (!$menuItem->exists) {
|
||||
$menuItem->fill([
|
||||
'target' => '_self',
|
||||
'icon_class' => 'voyager-boat',
|
||||
'color' => null,
|
||||
'parent_id' => null,
|
||||
'order' => 1,
|
||||
])->save();
|
||||
}
|
||||
|
||||
$menuItem = MenuItem::firstOrNew([
|
||||
'menu_id' => $menu->id,
|
||||
'title' => __('voyager::seeders.menu_items.media'),
|
||||
'url' => '',
|
||||
'route' => 'voyager.media.index',
|
||||
]);
|
||||
if (!$menuItem->exists) {
|
||||
$menuItem->fill([
|
||||
'target' => '_self',
|
||||
'icon_class' => 'voyager-images',
|
||||
'color' => null,
|
||||
'parent_id' => null,
|
||||
'order' => 5,
|
||||
])->save();
|
||||
}
|
||||
|
||||
$menuItem = MenuItem::firstOrNew([
|
||||
'menu_id' => $menu->id,
|
||||
'title' => __('voyager::seeders.menu_items.users'),
|
||||
'url' => '',
|
||||
'route' => 'voyager.users.index',
|
||||
]);
|
||||
if (!$menuItem->exists) {
|
||||
$menuItem->fill([
|
||||
'target' => '_self',
|
||||
'icon_class' => 'voyager-person',
|
||||
'color' => null,
|
||||
'parent_id' => null,
|
||||
'order' => 3,
|
||||
])->save();
|
||||
}
|
||||
|
||||
$menuItem = MenuItem::firstOrNew([
|
||||
'menu_id' => $menu->id,
|
||||
'title' => __('voyager::seeders.menu_items.roles'),
|
||||
'url' => '',
|
||||
'route' => 'voyager.roles.index',
|
||||
]);
|
||||
if (!$menuItem->exists) {
|
||||
$menuItem->fill([
|
||||
'target' => '_self',
|
||||
'icon_class' => 'voyager-lock',
|
||||
'color' => null,
|
||||
'parent_id' => null,
|
||||
'order' => 2,
|
||||
])->save();
|
||||
}
|
||||
|
||||
$toolsMenuItem = MenuItem::firstOrNew([
|
||||
'menu_id' => $menu->id,
|
||||
'title' => __('voyager::seeders.menu_items.tools'),
|
||||
'url' => '',
|
||||
]);
|
||||
if (!$toolsMenuItem->exists) {
|
||||
$toolsMenuItem->fill([
|
||||
'target' => '_self',
|
||||
'icon_class' => 'voyager-tools',
|
||||
'color' => null,
|
||||
'parent_id' => null,
|
||||
'order' => 9,
|
||||
])->save();
|
||||
}
|
||||
|
||||
$menuItem = MenuItem::firstOrNew([
|
||||
'menu_id' => $menu->id,
|
||||
'title' => __('voyager::seeders.menu_items.menu_builder'),
|
||||
'url' => '',
|
||||
'route' => 'voyager.menus.index',
|
||||
]);
|
||||
if (!$menuItem->exists) {
|
||||
$menuItem->fill([
|
||||
'target' => '_self',
|
||||
'icon_class' => 'voyager-list',
|
||||
'color' => null,
|
||||
'parent_id' => $toolsMenuItem->id,
|
||||
'order' => 10,
|
||||
])->save();
|
||||
}
|
||||
|
||||
$menuItem = MenuItem::firstOrNew([
|
||||
'menu_id' => $menu->id,
|
||||
'title' => __('voyager::seeders.menu_items.database'),
|
||||
'url' => '',
|
||||
'route' => 'voyager.database.index',
|
||||
]);
|
||||
if (!$menuItem->exists) {
|
||||
$menuItem->fill([
|
||||
'target' => '_self',
|
||||
'icon_class' => 'voyager-data',
|
||||
'color' => null,
|
||||
'parent_id' => $toolsMenuItem->id,
|
||||
'order' => 11,
|
||||
])->save();
|
||||
}
|
||||
|
||||
$menuItem = MenuItem::firstOrNew([
|
||||
'menu_id' => $menu->id,
|
||||
'title' => __('voyager::seeders.menu_items.compass'),
|
||||
'url' => '',
|
||||
'route' => 'voyager.compass.index',
|
||||
]);
|
||||
if (!$menuItem->exists) {
|
||||
$menuItem->fill([
|
||||
'target' => '_self',
|
||||
'icon_class' => 'voyager-compass',
|
||||
'color' => null,
|
||||
'parent_id' => $toolsMenuItem->id,
|
||||
'order' => 12,
|
||||
])->save();
|
||||
}
|
||||
|
||||
$menuItem = MenuItem::firstOrNew([
|
||||
'menu_id' => $menu->id,
|
||||
'title' => __('voyager::seeders.menu_items.bread'),
|
||||
'url' => '',
|
||||
'route' => 'voyager.bread.index',
|
||||
]);
|
||||
if (!$menuItem->exists) {
|
||||
$menuItem->fill([
|
||||
'target' => '_self',
|
||||
'icon_class' => 'voyager-bread',
|
||||
'color' => null,
|
||||
'parent_id' => $toolsMenuItem->id,
|
||||
'order' => 13,
|
||||
])->save();
|
||||
}
|
||||
|
||||
$menuItem = MenuItem::firstOrNew([
|
||||
'menu_id' => $menu->id,
|
||||
'title' => __('voyager::seeders.menu_items.settings'),
|
||||
'url' => '',
|
||||
'route' => 'voyager.settings.index',
|
||||
]);
|
||||
if (!$menuItem->exists) {
|
||||
$menuItem->fill([
|
||||
'target' => '_self',
|
||||
'icon_class' => 'voyager-settings',
|
||||
'color' => null,
|
||||
'parent_id' => null,
|
||||
'order' => 14,
|
||||
])->save();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,21 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Database\Seeders;
|
||||
|
||||
use Illuminate\Database\Seeder;
|
||||
use TCG\Voyager\Models\Menu;
|
||||
|
||||
class MenusTableSeeder extends Seeder
|
||||
{
|
||||
/**
|
||||
* Auto generated seed file.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function run()
|
||||
{
|
||||
Menu::firstOrCreate([
|
||||
'name' => 'admin',
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,26 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Database\Seeders;
|
||||
|
||||
use Illuminate\Database\Seeder;
|
||||
use TCG\Voyager\Models\Permission;
|
||||
use TCG\Voyager\Models\Role;
|
||||
|
||||
class PermissionRoleTableSeeder extends Seeder
|
||||
{
|
||||
/**
|
||||
* Auto generated seed file.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function run()
|
||||
{
|
||||
$role = Role::where('name', 'admin')->firstOrFail();
|
||||
|
||||
$permissions = Permission::all();
|
||||
|
||||
$role->permissions()->sync(
|
||||
$permissions->pluck('id')->all()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,38 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Database\Seeders;
|
||||
|
||||
use Illuminate\Database\Seeder;
|
||||
use TCG\Voyager\Models\Permission;
|
||||
|
||||
class PermissionsTableSeeder extends Seeder
|
||||
{
|
||||
/**
|
||||
* Auto generated seed file.
|
||||
*/
|
||||
public function run()
|
||||
{
|
||||
$keys = [
|
||||
'browse_admin',
|
||||
'browse_bread',
|
||||
'browse_database',
|
||||
'browse_media',
|
||||
'browse_compass',
|
||||
];
|
||||
|
||||
foreach ($keys as $key) {
|
||||
Permission::firstOrCreate([
|
||||
'key' => $key,
|
||||
'table_name' => null,
|
||||
]);
|
||||
}
|
||||
|
||||
Permission::generateFor('menus');
|
||||
|
||||
Permission::generateFor('roles');
|
||||
|
||||
Permission::generateFor('users');
|
||||
|
||||
Permission::generateFor('settings');
|
||||
}
|
||||
}
|
||||
|
|
@ -1,29 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Database\Seeders;
|
||||
|
||||
use Illuminate\Database\Seeder;
|
||||
use TCG\Voyager\Models\Role;
|
||||
|
||||
class RolesTableSeeder extends Seeder
|
||||
{
|
||||
/**
|
||||
* Auto generated seed file.
|
||||
*/
|
||||
public function run()
|
||||
{
|
||||
$role = Role::firstOrNew(['name' => 'admin']);
|
||||
if (!$role->exists) {
|
||||
$role->fill([
|
||||
'display_name' => __('voyager::seeders.roles.admin'),
|
||||
])->save();
|
||||
}
|
||||
|
||||
$role = Role::firstOrNew(['name' => 'user']);
|
||||
if (!$role->exists) {
|
||||
$role->fill([
|
||||
'display_name' => __('voyager::seeders.roles.user'),
|
||||
])->save();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,147 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Database\Seeders;
|
||||
|
||||
use Illuminate\Database\Seeder;
|
||||
use TCG\Voyager\Models\Setting;
|
||||
|
||||
class SettingsTableSeeder extends Seeder
|
||||
{
|
||||
/**
|
||||
* Auto generated seed file.
|
||||
*/
|
||||
public function run()
|
||||
{
|
||||
$setting = $this->findSetting('site.title');
|
||||
if (!$setting->exists) {
|
||||
$setting->fill([
|
||||
'display_name' => __('voyager::seeders.settings.site.title'),
|
||||
'value' => __('voyager::seeders.settings.site.title'),
|
||||
'details' => '',
|
||||
'type' => 'text',
|
||||
'order' => 1,
|
||||
'group' => 'Site',
|
||||
])->save();
|
||||
}
|
||||
|
||||
$setting = $this->findSetting('site.description');
|
||||
if (!$setting->exists) {
|
||||
$setting->fill([
|
||||
'display_name' => __('voyager::seeders.settings.site.description'),
|
||||
'value' => __('voyager::seeders.settings.site.description'),
|
||||
'details' => '',
|
||||
'type' => 'text',
|
||||
'order' => 2,
|
||||
'group' => 'Site',
|
||||
])->save();
|
||||
}
|
||||
|
||||
$setting = $this->findSetting('site.logo');
|
||||
if (!$setting->exists) {
|
||||
$setting->fill([
|
||||
'display_name' => __('voyager::seeders.settings.site.logo'),
|
||||
'value' => '',
|
||||
'details' => '',
|
||||
'type' => 'image',
|
||||
'order' => 3,
|
||||
'group' => 'Site',
|
||||
])->save();
|
||||
}
|
||||
|
||||
$setting = $this->findSetting('site.google_analytics_tracking_id');
|
||||
if (!$setting->exists) {
|
||||
$setting->fill([
|
||||
'display_name' => __('voyager::seeders.settings.site.google_analytics_tracking_id'),
|
||||
'value' => '',
|
||||
'details' => '',
|
||||
'type' => 'text',
|
||||
'order' => 4,
|
||||
'group' => 'Site',
|
||||
])->save();
|
||||
}
|
||||
|
||||
$setting = $this->findSetting('admin.bg_image');
|
||||
if (!$setting->exists) {
|
||||
$setting->fill([
|
||||
'display_name' => __('voyager::seeders.settings.admin.background_image'),
|
||||
'value' => '',
|
||||
'details' => '',
|
||||
'type' => 'image',
|
||||
'order' => 5,
|
||||
'group' => 'Admin',
|
||||
])->save();
|
||||
}
|
||||
|
||||
$setting = $this->findSetting('admin.title');
|
||||
if (!$setting->exists) {
|
||||
$setting->fill([
|
||||
'display_name' => __('voyager::seeders.settings.admin.title'),
|
||||
'value' => 'Voyager',
|
||||
'details' => '',
|
||||
'type' => 'text',
|
||||
'order' => 1,
|
||||
'group' => 'Admin',
|
||||
])->save();
|
||||
}
|
||||
|
||||
$setting = $this->findSetting('admin.description');
|
||||
if (!$setting->exists) {
|
||||
$setting->fill([
|
||||
'display_name' => __('voyager::seeders.settings.admin.description'),
|
||||
'value' => __('voyager::seeders.settings.admin.description_value'),
|
||||
'details' => '',
|
||||
'type' => 'text',
|
||||
'order' => 2,
|
||||
'group' => 'Admin',
|
||||
])->save();
|
||||
}
|
||||
|
||||
$setting = $this->findSetting('admin.loader');
|
||||
if (!$setting->exists) {
|
||||
$setting->fill([
|
||||
'display_name' => __('voyager::seeders.settings.admin.loader'),
|
||||
'value' => '',
|
||||
'details' => '',
|
||||
'type' => 'image',
|
||||
'order' => 3,
|
||||
'group' => 'Admin',
|
||||
])->save();
|
||||
}
|
||||
|
||||
$setting = $this->findSetting('admin.icon_image');
|
||||
if (!$setting->exists) {
|
||||
$setting->fill([
|
||||
'display_name' => __('voyager::seeders.settings.admin.icon_image'),
|
||||
'value' => '',
|
||||
'details' => '',
|
||||
'type' => 'image',
|
||||
'order' => 4,
|
||||
'group' => 'Admin',
|
||||
])->save();
|
||||
}
|
||||
|
||||
$setting = $this->findSetting('admin.google_analytics_client_id');
|
||||
if (!$setting->exists) {
|
||||
$setting->fill([
|
||||
'display_name' => __('voyager::seeders.settings.admin.google_analytics_client_id'),
|
||||
'value' => '',
|
||||
'details' => '',
|
||||
'type' => 'text',
|
||||
'order' => 1,
|
||||
'group' => 'Admin',
|
||||
])->save();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* [setting description].
|
||||
*
|
||||
* @param [type] $key [description]
|
||||
*
|
||||
* @return [type] [description]
|
||||
*/
|
||||
protected function findSetting($key)
|
||||
{
|
||||
return Setting::firstOrNew(['key' => $key]);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,233 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Database\Seeders;
|
||||
|
||||
use Illuminate\Database\Seeder;
|
||||
use TCG\Voyager\Models\Category;
|
||||
use TCG\Voyager\Models\DataType;
|
||||
use TCG\Voyager\Models\MenuItem;
|
||||
use TCG\Voyager\Models\Page;
|
||||
use TCG\Voyager\Models\Translation;
|
||||
|
||||
class TranslationsTableSeeder extends Seeder
|
||||
{
|
||||
/**
|
||||
* Auto generated seed file.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function run()
|
||||
{
|
||||
$this->dataTypesTranslations();
|
||||
$this->categoriesTranslations();
|
||||
$this->pagesTranslations();
|
||||
$this->menusTranslations();
|
||||
}
|
||||
|
||||
/**
|
||||
* Auto generate Categories Translations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function categoriesTranslations()
|
||||
{
|
||||
// Adding translations for 'categories'
|
||||
//
|
||||
$cat = Category::where('slug', 'category-1')->firstOrFail();
|
||||
if ($cat->exists) {
|
||||
$this->trans('pt', $this->arr(['categories', 'slug'], $cat->id), 'categoria-1');
|
||||
$this->trans('pt', $this->arr(['categories', 'name'], $cat->id), 'Categoria 1');
|
||||
}
|
||||
$cat = Category::where('slug', 'category-2')->firstOrFail();
|
||||
if ($cat->exists) {
|
||||
$this->trans('pt', $this->arr(['categories', 'slug'], $cat->id), 'categoria-2');
|
||||
$this->trans('pt', $this->arr(['categories', 'name'], $cat->id), 'Categoria 2');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Auto generate DataTypes Translations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function dataTypesTranslations()
|
||||
{
|
||||
// Adding translations for 'display_name_singular'
|
||||
//
|
||||
$_fld = 'display_name_singular';
|
||||
$_tpl = ['data_types', $_fld];
|
||||
$dtp = DataType::where($_fld, __('voyager::seeders.data_types.post.singular'))->firstOrFail();
|
||||
if ($dtp->exists) {
|
||||
$this->trans('pt', $this->arr($_tpl, $dtp->id), 'Post');
|
||||
}
|
||||
$dtp = DataType::where($_fld, __('voyager::seeders.data_types.page.singular'))->firstOrFail();
|
||||
if ($dtp->exists) {
|
||||
$this->trans('pt', $this->arr($_tpl, $dtp->id), 'Página');
|
||||
}
|
||||
$dtp = DataType::where($_fld, __('voyager::seeders.data_types.user.singular'))->firstOrFail();
|
||||
if ($dtp->exists) {
|
||||
$this->trans('pt', $this->arr($_tpl, $dtp->id), 'Utilizador');
|
||||
}
|
||||
$dtp = DataType::where($_fld, __('voyager::seeders.data_types.category.singular'))->firstOrFail();
|
||||
if ($dtp->exists) {
|
||||
$this->trans('pt', $this->arr($_tpl, $dtp->id), 'Categoria');
|
||||
}
|
||||
$dtp = DataType::where($_fld, __('voyager::seeders.data_types.menu.singular'))->firstOrFail();
|
||||
if ($dtp->exists) {
|
||||
$this->trans('pt', $this->arr($_tpl, $dtp->id), 'Menu');
|
||||
}
|
||||
$dtp = DataType::where($_fld, __('voyager::seeders.data_types.role.singular'))->firstOrFail();
|
||||
if ($dtp->exists) {
|
||||
$this->trans('pt', $this->arr($_tpl, $dtp->id), 'Função');
|
||||
}
|
||||
|
||||
// Adding translations for 'display_name_plural'
|
||||
//
|
||||
$_fld = 'display_name_plural';
|
||||
$_tpl = ['data_types', $_fld];
|
||||
$dtp = DataType::where($_fld, __('voyager::seeders.data_types.post.plural'))->firstOrFail();
|
||||
if ($dtp->exists) {
|
||||
$this->trans('pt', $this->arr($_tpl, $dtp->id), 'Posts');
|
||||
}
|
||||
$dtp = DataType::where($_fld, __('voyager::seeders.data_types.page.plural'))->firstOrFail();
|
||||
if ($dtp->exists) {
|
||||
$this->trans('pt', $this->arr($_tpl, $dtp->id), 'Páginas');
|
||||
}
|
||||
$dtp = DataType::where($_fld, __('voyager::seeders.data_types.user.plural'))->firstOrFail();
|
||||
if ($dtp->exists) {
|
||||
$this->trans('pt', $this->arr($_tpl, $dtp->id), 'Utilizadores');
|
||||
}
|
||||
$dtp = DataType::where($_fld, __('voyager::seeders.data_types.category.plural'))->firstOrFail();
|
||||
if ($dtp->exists) {
|
||||
$this->trans('pt', $this->arr($_tpl, $dtp->id), 'Categorias');
|
||||
}
|
||||
$dtp = DataType::where($_fld, __('voyager::seeders.data_types.menu.plural'))->firstOrFail();
|
||||
if ($dtp->exists) {
|
||||
$this->trans('pt', $this->arr($_tpl, $dtp->id), 'Menus');
|
||||
}
|
||||
$dtp = DataType::where($_fld, __('voyager::seeders.data_types.role.plural'))->firstOrFail();
|
||||
if ($dtp->exists) {
|
||||
$this->trans('pt', $this->arr($_tpl, $dtp->id), 'Funções');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Auto generate Pages Translations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function pagesTranslations()
|
||||
{
|
||||
$page = Page::where('slug', 'hello-world')->firstOrFail();
|
||||
if ($page->exists) {
|
||||
$_arr = $this->arr(['pages', 'title'], $page->id);
|
||||
$this->trans('pt', $_arr, 'Olá Mundo');
|
||||
/**
|
||||
* For configuring additional languages use it e.g.
|
||||
*
|
||||
* ```
|
||||
* $this->trans('es', $_arr, 'hola-mundo');
|
||||
* $this->trans('de', $_arr, 'hallo-welt');
|
||||
* ```
|
||||
*/
|
||||
$_arr = $this->arr(['pages', 'slug'], $page->id);
|
||||
$this->trans('pt', $_arr, 'ola-mundo');
|
||||
|
||||
$_arr = $this->arr(['pages', 'body'], $page->id);
|
||||
$this->trans('pt', $_arr, '<p>Olá Mundo. Scallywag grog swab Cat o\'nine tails scuttle rigging hardtack cable nipper Yellow Jack. Handsomely spirits knave lad killick landlubber or just lubber deadlights chantey pinnace crack Jennys tea cup. Provost long clothes black spot Yellow Jack bilged on her anchor league lateen sail case shot lee tackle.</p>'
|
||||
."\r\n".'<p>Ballast spirits fluke topmast me quarterdeck schooner landlubber or just lubber gabion belaying pin. Pinnace stern galleon starboard warp carouser to go on account dance the hempen jig jolly boat measured fer yer chains. Man-of-war fire in the hole nipperkin handsomely doubloon barkadeer Brethren of the Coast gibbet driver squiffy.</p>');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Auto generate Menus Translations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function menusTranslations()
|
||||
{
|
||||
$_tpl = ['menu_items', 'title'];
|
||||
$_item = $this->findMenuItem(__('voyager::seeders.menu_items.dashboard'));
|
||||
if ($_item->exists) {
|
||||
$this->trans('pt', $this->arr($_tpl, $_item->id), 'Painel de Controle');
|
||||
}
|
||||
|
||||
$_item = $this->findMenuItem(__('voyager::seeders.menu_items.media'));
|
||||
if ($_item->exists) {
|
||||
$this->trans('pt', $this->arr($_tpl, $_item->id), 'Media');
|
||||
}
|
||||
|
||||
$_item = $this->findMenuItem(__('voyager::seeders.menu_items.posts'));
|
||||
if ($_item->exists) {
|
||||
$this->trans('pt', $this->arr($_tpl, $_item->id), 'Publicações');
|
||||
}
|
||||
|
||||
$_item = $this->findMenuItem(__('voyager::seeders.menu_items.users'));
|
||||
if ($_item->exists) {
|
||||
$this->trans('pt', $this->arr($_tpl, $_item->id), 'Utilizadores');
|
||||
}
|
||||
|
||||
$_item = $this->findMenuItem(__('voyager::seeders.menu_items.categories'));
|
||||
if ($_item->exists) {
|
||||
$this->trans('pt', $this->arr($_tpl, $_item->id), 'Categorias');
|
||||
}
|
||||
|
||||
$_item = $this->findMenuItem(__('voyager::seeders.menu_items.pages'));
|
||||
if ($_item->exists) {
|
||||
$this->trans('pt', $this->arr($_tpl, $_item->id), 'Páginas');
|
||||
}
|
||||
|
||||
$_item = $this->findMenuItem(__('voyager::seeders.menu_items.roles'));
|
||||
if ($_item->exists) {
|
||||
$this->trans('pt', $this->arr($_tpl, $_item->id), 'Funções');
|
||||
}
|
||||
|
||||
$_item = $this->findMenuItem(__('voyager::seeders.menu_items.tools'));
|
||||
if ($_item->exists) {
|
||||
$this->trans('pt', $this->arr($_tpl, $_item->id), 'Ferramentas');
|
||||
}
|
||||
|
||||
$_item = $this->findMenuItem(__('voyager::seeders.menu_items.menu_builder'));
|
||||
if ($_item->exists) {
|
||||
$this->trans('pt', $this->arr($_tpl, $_item->id), 'Menus');
|
||||
}
|
||||
|
||||
$_item = $this->findMenuItem(__('voyager::seeders.menu_items.database'));
|
||||
if ($_item->exists) {
|
||||
$this->trans('pt', $this->arr($_tpl, $_item->id), 'Base de dados');
|
||||
}
|
||||
|
||||
$_item = $this->findMenuItem(__('voyager::seeders.menu_items.settings'));
|
||||
if ($_item->exists) {
|
||||
$this->trans('pt', $this->arr($_tpl, $_item->id), 'Configurações');
|
||||
}
|
||||
}
|
||||
|
||||
private function findMenuItem($title)
|
||||
{
|
||||
return MenuItem::where('title', $title)->firstOrFail();
|
||||
}
|
||||
|
||||
private function arr($par, $id)
|
||||
{
|
||||
return [
|
||||
'table_name' => $par[0],
|
||||
'column_name' => $par[1],
|
||||
'foreign_key' => $id,
|
||||
];
|
||||
}
|
||||
|
||||
private function trans($lang, $keys, $value)
|
||||
{
|
||||
$_t = Translation::firstOrNew(array_merge($keys, [
|
||||
'locale' => $lang,
|
||||
]));
|
||||
|
||||
if (!$_t->exists) {
|
||||
$_t->fill(array_merge(
|
||||
$keys,
|
||||
['value' => $value]
|
||||
))->save();
|
||||
}
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue