diff --git a/.env.example b/.env.example
new file mode 100644
index 00000000..53d48bf3
--- /dev/null
+++ b/.env.example
@@ -0,0 +1,46 @@
+APP_NAME=Laravel
+APP_ENV=local
+APP_KEY=
+APP_DEBUG=true
+APP_URL=http://localhost
+
+LOG_CHANNEL=stack
+
+DB_CONNECTION=mysql
+DB_HOST=127.0.0.1
+DB_PORT=3306
+DB_DATABASE=laravel
+DB_USERNAME=root
+DB_PASSWORD=
+
+BROADCAST_DRIVER=log
+CACHE_DRIVER=file
+QUEUE_CONNECTION=sync
+SESSION_DRIVER=file
+SESSION_LIFETIME=120
+
+REDIS_HOST=127.0.0.1
+REDIS_PASSWORD=null
+REDIS_PORT=6379
+
+MAIL_DRIVER=smtp
+MAIL_HOST=smtp.mailtrap.io
+MAIL_PORT=2525
+MAIL_USERNAME=null
+MAIL_PASSWORD=null
+MAIL_ENCRYPTION=null
+MAIL_FROM_ADDRESS=null
+MAIL_FROM_NAME="${APP_NAME}"
+
+AWS_ACCESS_KEY_ID=
+AWS_SECRET_ACCESS_KEY=
+AWS_DEFAULT_REGION=us-east-1
+AWS_BUCKET=
+
+PUSHER_APP_ID=
+PUSHER_APP_KEY=
+PUSHER_APP_SECRET=
+PUSHER_APP_CLUSTER=mt1
+
+MIX_PUSHER_APP_KEY="${PUSHER_APP_KEY}"
+MIX_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}"
diff --git a/README.md b/README.md
new file mode 100644
index 00000000..81f2f62b
--- /dev/null
+++ b/README.md
@@ -0,0 +1,78 @@
+

+
+
+
+
+
+
+
+
+## About Laravel
+
+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.
+
+If you don't feel like reading, [Laracasts](https://laracasts.com) can help. Laracasts contains over 1500 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).
+
+- **[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)**
+- **[British Software Development](https://www.britishsoftware.co)**
+- **[Webdock, Fast VPS Hosting](https://www.webdock.io/en)**
+- **[DevSquad](https://devsquad.com)**
+- [UserInsights](https://userinsights.com)
+- [Fragrantica](https://www.fragrantica.com)
+- [SOFTonSOFA](https://softonsofa.com/)
+- [User10](https://user10.com)
+- [Soumettre.fr](https://soumettre.fr/)
+- [CodeBrisk](https://codebrisk.com)
+- [1Forge](https://1forge.com)
+- [TECPRESSO](https://tecpresso.co.jp/)
+- [Runtime Converter](http://runtimeconverter.com/)
+- [WebL'Agence](https://weblagence.com/)
+- [Invoice Ninja](https://www.invoiceninja.com)
+- [iMi digital](https://www.imi-digital.de/)
+- [Earthlink](https://www.earthlink.ro/)
+- [Steadfast Collective](https://steadfastcollective.com/)
+- [We Are The Robots Inc.](https://watr.mx/)
+- [Understand.io](https://www.understand.io/)
+- [Abdel Elrafa](https://abdelelrafa.com)
+- [Hyper Host](https://hyper.host)
+- [Appoly](https://www.appoly.co.uk)
+- [OP.GG](https://op.gg)
+
+## 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).
diff --git a/app/Http/Controllers/JS/CacheController.php b/app/Http/Controllers/JS/CacheController.php
new file mode 100644
index 00000000..43eeb29e
--- /dev/null
+++ b/app/Http/Controllers/JS/CacheController.php
@@ -0,0 +1,22 @@
+middleware('auth');
+ }
+
+ /**
+ * Show the application dashboard.
+ *
+ * @return
+ */
+ public function index()
+ {
+ $data = [];
+ $dashboard = 'dashboard_general';
+
+ if (Users::hasRole('admin')) {
+ $dashboard = 'dashboard';
+ $data = [];
+ }
+
+ return view('shop.admin.Dashboard.index', $data);
+ }
+}
diff --git a/app/Http/Controllers/Shop/Admin/HomeController.php b/app/Http/Controllers/Shop/Admin/HomeController.php
new file mode 100644
index 00000000..9d7a6ccb
--- /dev/null
+++ b/app/Http/Controllers/Shop/Admin/HomeController.php
@@ -0,0 +1,29 @@
+middleware('auth');
+ }
+
+ /**
+ * Show the application dashboard.
+ *
+ * @return \Illuminate\Contracts\Support\Renderable
+ */
+ public function index()
+ {
+ return redirect('dashboard');
+ }
+}
diff --git a/app/Http/Controllers/Shop/Admin/InventoryController.php b/app/Http/Controllers/Shop/Admin/InventoryController.php
new file mode 100644
index 00000000..b5e44994
--- /dev/null
+++ b/app/Http/Controllers/Shop/Admin/InventoryController.php
@@ -0,0 +1,86 @@
+middleware('auth');
+ }
+
+ /**
+ * Show the application dashboard.
+ *
+ * @return \Illuminate\Contracts\Support\Renderable
+ */
+ public function index()
+ {
+ return redirect('dashboard');
+ }
+}
diff --git a/app/Http/Controllers/Shop/InvoiceController.php b/app/Http/Controllers/Shop/InvoiceController.php
new file mode 100644
index 00000000..3f214e56
--- /dev/null
+++ b/app/Http/Controllers/Shop/InvoiceController.php
@@ -0,0 +1,87 @@
+ $row['civilite'],
+ 'name' => $row['nom'],
+ 'firstname' => $row['prenom'],
+ 'street1' => $row['adresse'],
+ 'zipcode' => $row['cp'],
+ 'city' => $row['ville'],
+ 'mobile' => $row['mobile'],
+ 'email' => $row['email'],
+ 'phone' => $row['telephone'],
+ ]);
+ }
+}
diff --git a/app/Install.php b/app/Install.php
new file mode 100644
index 00000000..aa663c00
--- /dev/null
+++ b/app/Install.php
@@ -0,0 +1,34 @@
+external('composer', 'install', '--no-dev', '--prefer-dist', '--optimize-autoloader')
+ ->artisan('key:generate', ['--force' => true])
+ ->artisan('migrate', ['--force' => true])
+ ->artisan('storage:link')
+// ->dispatch(new MakeCronTask)
+ ->external('npm', 'install', '--production')
+ ->external('npm', 'run', 'production')
+ ->artisan('route:cache')
+ ->artisan('config:cache')
+ ->artisan('event:cache');
+ }
+
+ public function local(Runner $run)
+ {
+ return $run
+ ->external('composer', 'install')
+ ->artisan('key:generate')
+ ->artisan('migrate')
+ ->artisan('storage:link')
+ ->external('npm', 'install')
+ ->external('npm', 'run', 'development');
+ }
+}
diff --git a/app/Menu/Shop.php b/app/Menu/Shop.php
new file mode 100644
index 00000000..57d8c7f8
--- /dev/null
+++ b/app/Menu/Shop.php
@@ -0,0 +1,29 @@
+add('Commerce', [ 'permission' => 'backend', 'icon' => 'cog' ])
+ ->id('shop')
+ ->activeIfRoute('shop')
+ ->order(1);
+
+ $menu->addTo('shop', 'Commandes', [ 'route' => 'Shop.Admin.Orders.index', 'permission' => 'backend' ])
+ ->activeIfRoute(['Shop.Admin.Orders.index'])->order(1);
+ $menu->addTo('shop', 'Factures', [ 'route' => 'Shop.Admin.Invoices.index', 'permission' => 'backend' ])
+ ->activeIfRoute(['Shop.Admin.Invoices.index'])->order(2);
+
+ $menu->addTo('shop', 'Categories', [ 'route' => 'Shop.Admin.Products.index', 'permission' => 'backend' ])
+ ->activeIfRoute(['Shop.Admin.Products.index'])->order(3);
+ $menu->addTo('shop', 'Produits', [ 'route' => 'Shop.Admin.Products.index', 'permission' => 'backend' ])
+ ->activeIfRoute(['Shop.Admin.Products.index'])->order(4);
+
+
+ }
+}
diff --git a/app/Models/Auth/Permission.php b/app/Models/Auth/Permission.php
new file mode 100644
index 00000000..966a6868
--- /dev/null
+++ b/app/Models/Auth/Permission.php
@@ -0,0 +1,49 @@
+belongsTo('App\Models\Application');
+ }
+
+ public function application_module()
+ {
+ return $this->belongsTo('App\Models\ApplicationModule');
+ }
+
+ public function getDisplayNameAttribute($value)
+ {
+ return __($value);
+ }
+
+ public function getDescriptionAttribute($value)
+ {
+ return __($value);
+ }
+}
diff --git a/app/Models/Auth/PermissionRole.php b/app/Models/Auth/PermissionRole.php
new file mode 100644
index 00000000..3ed9e8b4
--- /dev/null
+++ b/app/Models/Auth/PermissionRole.php
@@ -0,0 +1,30 @@
+belongsTo('App\Permission');
+ }
+
+ public function role()
+ {
+ return $this->belongsTo('App\Role');
+ }
+
+ public function scopeByPermission($query, $id)
+ {
+ return $query->where('permission_id', $id);
+ }
+
+ public function scopeByRole($query, $id)
+ {
+ return $query->where('role_id', $id);
+ }
+}
diff --git a/app/Models/Auth/PermissionUser.php b/app/Models/Auth/PermissionUser.php
new file mode 100644
index 00000000..ef2931e8
--- /dev/null
+++ b/app/Models/Auth/PermissionUser.php
@@ -0,0 +1,45 @@
+belongsTo('App\Permission');
+ }
+
+ public function user()
+ {
+ return $this->belongsTo('App\User');
+ }
+
+ public function team()
+ {
+ return $this->belongsTo('App\Team');
+ }
+
+ public function scopeByUser($query, $id)
+ {
+ return $query->where('user_id', $id);
+ }
+
+ public function scopeByPermission($query, $id)
+ {
+ return $query->where('permission_id', $id);
+ }
+
+ public function scopeByUserType($query, $name)
+ {
+ return $query->where('user_type', $name);
+ }
+
+ public function scopeByTeam($query, $id)
+ {
+ return $query->where('team_id', $id);
+ }
+}
diff --git a/app/Models/Auth/Role.php b/app/Models/Auth/Role.php
new file mode 100644
index 00000000..eb599ca8
--- /dev/null
+++ b/app/Models/Auth/Role.php
@@ -0,0 +1,45 @@
+name)->count();
+ }
+}
diff --git a/app/Models/Auth/RoleUser.php b/app/Models/Auth/RoleUser.php
new file mode 100644
index 00000000..d31ab60a
--- /dev/null
+++ b/app/Models/Auth/RoleUser.php
@@ -0,0 +1,41 @@
+belongsTo('App\User');
+ }
+
+ public function team()
+ {
+ return $this->belongsTo('App\Team');
+ }
+
+ public function scopeByUser($query, $id)
+ {
+ return $query->where('user_id', $id);
+ }
+
+ public function scopeByRole($query, $id)
+ {
+ return $query->where('role_id', $id);
+ }
+
+ public function scopeByUserType($query, $name)
+ {
+ return $query->where('user_type', $name);
+ }
+
+ public function scopeByTeam($query, $id)
+ {
+ return $query->where('team_id', $id);
+ }
+}
diff --git a/app/Models/Auth/Team.php b/app/Models/Auth/Team.php
new file mode 100644
index 00000000..ec235b33
--- /dev/null
+++ b/app/Models/Auth/Team.php
@@ -0,0 +1,35 @@
+hasMany('App\User');
+ }
+
+ public function society()
+ {
+ return $this->belongsTo('App\Models\Society');
+ }
+
+ public function scopeActive($query)
+ {
+ return $query->where('active', 1);
+ }
+
+ public function scopeBySociety($query, $id)
+ {
+ return $query->where('society_id', $id);
+ }
+}
diff --git a/app/Models/Auth/TeamUser.php b/app/Models/Auth/TeamUser.php
new file mode 100644
index 00000000..a796258c
--- /dev/null
+++ b/app/Models/Auth/TeamUser.php
@@ -0,0 +1,31 @@
+belongsTo('App\User');
+ }
+
+ public function team()
+ {
+ return $this->belongsTo('App\Team');
+ }
+
+ public function scopeByUser($query, $id)
+ {
+ return $query->where('user_id', $id);
+ }
+
+ public function scopeByTeam($query, $id)
+ {
+ return $query->where('team_id', $id);
+ }
+}
diff --git a/app/Models/Modules/Application.php b/app/Models/Modules/Application.php
new file mode 100644
index 00000000..e3c7bd47
--- /dev/null
+++ b/app/Models/Modules/Application.php
@@ -0,0 +1,42 @@
+hasMany('App\Models\Modules\ApplicationPage');
+ }
+
+ public function modules()
+ {
+ return $this->hasMany('App\Models\Modules\ApplicationModule');
+ }
+
+ public function scopeActive($query)
+ {
+ return $query->where('active', 1);
+ }
+
+ public function scopeVisible($query)
+ {
+ return $query->where('visible', 1);
+ }
+
+ public function scopeBySlug($query, $slug)
+ {
+ return $query->where('slug', $slug);
+ }
+
+ public function scopeByOrder($query)
+ {
+ return $query->sortBy('order');
+ }
+}
diff --git a/app/Models/Modules/ApplicationModule.php b/app/Models/Modules/ApplicationModule.php
new file mode 100644
index 00000000..fb21b978
--- /dev/null
+++ b/app/Models/Modules/ApplicationModule.php
@@ -0,0 +1,37 @@
+belongsTo('App\Models\Modules\Application');
+ }
+
+ public function permissions()
+ {
+ return $this->hasMany('App\Auth\Permission');
+ }
+
+ public function scopeActive($query)
+ {
+ return $query->where('active', 1);
+ }
+
+ public function scopeByApplication($query, $id)
+ {
+ return $query->where('application_id', $id);
+ }
+
+ public function scopeBySlug($query, $slug)
+ {
+ return $query->where('slug', $slug);
+ }
+}
diff --git a/app/Models/Modules/ApplicationPage.php b/app/Models/Modules/ApplicationPage.php
new file mode 100644
index 00000000..f966916e
--- /dev/null
+++ b/app/Models/Modules/ApplicationPage.php
@@ -0,0 +1,32 @@
+belongsTo('App\Models\Modules\Application');
+ }
+
+ public function scopeActive($query)
+ {
+ return $query->where('active', 1);
+ }
+
+ public function scopeByApplication($query, $application_id)
+ {
+ return $query->where('application_id', $application_id);
+ }
+
+ public function scopeBySlug($query, $slug)
+ {
+ return $query->where('slug', $slug);
+ }
+}
diff --git a/app/Models/Modules/Family.php b/app/Models/Modules/Family.php
new file mode 100644
index 00000000..44d86d38
--- /dev/null
+++ b/app/Models/Modules/Family.php
@@ -0,0 +1,11 @@
+hasMany('App\Models\Shop\Invoice');
+ }
+
+ /**
+ * @return \Illuminate\Database\Eloquent\Relations\HasMany
+ */
+ public function Orders()
+ {
+ return $this->hasMany('App\Models\Shop\Order');
+ }
+
+ /**
+ * @return \Illuminate\Database\Eloquent\Relations\BelongsTo
+ */
+ public function User()
+ {
+ return $this->belongsTo('App\User');
+ }
+}
\ No newline at end of file
diff --git a/app/Models/Shop/Inventory.php b/app/Models/Shop/Inventory.php
new file mode 100644
index 00000000..4e35ea44
--- /dev/null
+++ b/app/Models/Shop/Inventory.php
@@ -0,0 +1,18 @@
+belongsTo('App\Models\Shop\InventoryPlace');
+ }
+}
\ No newline at end of file
diff --git a/app/Models/Shop/InventoryPlace.php b/app/Models/Shop/InventoryPlace.php
new file mode 100644
index 00000000..d9f604c8
--- /dev/null
+++ b/app/Models/Shop/InventoryPlace.php
@@ -0,0 +1,18 @@
+hasMany('App\Models\Inventory');
+ }
+}
\ No newline at end of file
diff --git a/app/Models/Shop/Invoice.php b/app/Models/Shop/Invoice.php
new file mode 100644
index 00000000..e48881cf
--- /dev/null
+++ b/app/Models/Shop/Invoice.php
@@ -0,0 +1,26 @@
+hasMany('App\Models\Shop\InvoiceItem');
+ }
+
+ /**
+ * @return \Illuminate\Database\Eloquent\Relations\BelongsTo
+ */
+ public function Customer()
+ {
+ return $this->belongsTo('App\Models\Shop\Customer');
+ }
+}
\ No newline at end of file
diff --git a/app/Models/Shop/InvoiceItem.php b/app/Models/Shop/InvoiceItem.php
new file mode 100644
index 00000000..feb425d9
--- /dev/null
+++ b/app/Models/Shop/InvoiceItem.php
@@ -0,0 +1,26 @@
+belongsTo('App\Models\Shop\Product');
+ }
+
+ /**
+ * @return \Illuminate\Database\Eloquent\Relations\BelongsTo
+ */
+ public function Invoice()
+ {
+ return $this->belongsTo('App\Models\Shop\Invoice');
+ }
+}
\ No newline at end of file
diff --git a/app/Models/Shop/Order.php b/app/Models/Shop/Order.php
new file mode 100644
index 00000000..209169f9
--- /dev/null
+++ b/app/Models/Shop/Order.php
@@ -0,0 +1,26 @@
+belongsTo('App\Models\Shop\Customer');
+ }
+
+ /**
+ * @return \Illuminate\Database\Eloquent\Relations\HasMany
+ */
+ public function Payments()
+ {
+ return $this->hasMany('App\Models\Shop\OrderPayment');
+ }
+}
\ No newline at end of file
diff --git a/app/Models/Shop/OrderPayment.php b/app/Models/Shop/OrderPayment.php
new file mode 100644
index 00000000..4232c8f1
--- /dev/null
+++ b/app/Models/Shop/OrderPayment.php
@@ -0,0 +1,20 @@
+belongsTo('App\Models\Shop\Order');
+ }
+
+
+}
diff --git a/app/Models/Shop/Product.php b/app/Models/Shop/Product.php
new file mode 100644
index 00000000..2a882f6b
--- /dev/null
+++ b/app/Models/Shop/Product.php
@@ -0,0 +1,50 @@
+hasMany('App\Models\Shop\Inventory');
+ }
+
+ /**
+ * @return \Illuminate\Database\Eloquent\Relations\HasMany
+ */
+ public function Prices()
+ {
+ return $this->hasMany('App\Models\Shop\ProductPrice');
+ }
+
+ /**
+ * @return \Illuminate\Database\Eloquent\Relations\HasMany
+ */
+ public function ProductAttributes()
+ {
+ return $this->hasMany('App\Models\Shop\ProductAttribute');
+ }
+
+ /**
+ * @return \Illuminate\Database\Eloquent\Relations\HasMany
+ */
+ public function Categories()
+ {
+ return $this->hasMany('App\Models\Shop\CategoryProduct');
+ }
+
+ /**
+ * @return \Illuminate\Database\Eloquent\Relations\HasMany
+ */
+ public function InvoiceItems()
+ {
+ return $this->hasMany('App\Models\Shop\InvoiceItem');
+ }
+}
\ No newline at end of file
diff --git a/app/Models/Shop/ProductAttribute.php b/app/Models/Shop/ProductAttribute.php
new file mode 100644
index 00000000..c44ef62a
--- /dev/null
+++ b/app/Models/Shop/ProductAttribute.php
@@ -0,0 +1,18 @@
+belongsTo('App\Models\Shop\Product');
+ }
+}
\ No newline at end of file
diff --git a/app/Models/Shop/ProductPrice.php b/app/Models/Shop/ProductPrice.php
new file mode 100644
index 00000000..99186808
--- /dev/null
+++ b/app/Models/Shop/ProductPrice.php
@@ -0,0 +1,26 @@
+belongsTo('App\Models\Shop\Product');
+ }
+
+ /**
+ * @return \Illuminate\Database\Eloquent\Relations\BelongsTo
+ */
+ public function ProductAttribute()
+ {
+ return $this->belongsTo('App\Models\Shop\ProductAttribute');
+ }
+}
\ No newline at end of file
diff --git a/app/Models/Shop/Section.php b/app/Models/Shop/Section.php
new file mode 100644
index 00000000..8f18192d
--- /dev/null
+++ b/app/Models/Shop/Section.php
@@ -0,0 +1,19 @@
+hasMany('App\Models\Shop\Product');
+ }
+
+}
\ No newline at end of file
diff --git a/app/Repositories/ApplicationPages.php b/app/Repositories/ApplicationPages.php
new file mode 100644
index 00000000..6b5d7960
--- /dev/null
+++ b/app/Repositories/ApplicationPages.php
@@ -0,0 +1,23 @@
+byApplication($application_id)->bySlug($slug)->first();
+ return $app ? $app->toArray() : null;
+ }
+
+ // récupère toutes les pages actives pour une application
+ public static function getActiveByApplication($application_id)
+ {
+ $app = ApplicationPage::active()->byApplication($application_id)->get();
+ return $app ? $app->toArray() : null;
+ }
+}
diff --git a/app/Repositories/Applications.php b/app/Repositories/Applications.php
new file mode 100644
index 00000000..155399df
--- /dev/null
+++ b/app/Repositories/Applications.php
@@ -0,0 +1,60 @@
+toArray();
+ }
+
+ public static function getCurrent()
+ {
+ $route = explode('.', Route::currentRouteName());
+ $app = isset($route[0]) ? $route[0] : null;
+ $page = isset($route[1]) ? $route[1] : null;
+ $action = isset($route[2]) ? $route[2] : null;
+
+ if (self::getBySlug($app)) {
+ $data['current'] = self::getBySlug($app)->toArray();
+ $application_id = $data['current']['id'];
+ $data['page'] = ApplicationPages::getBySlug($application_id, $page);
+ $data['pages'] = ApplicationPages::getActiveByApplication($application_id);
+ $data['action'] = $action;
+ } else {
+ $data['current']['slug'] = $app;
+ }
+ $data['langs'] = Languages::getActive();
+ $data['lang'] = Languages::getCurrent();
+ return $data;
+ }
+
+ public static function getActives()
+ {
+ return Application::active()->get()->toArray();
+ }
+
+ public static function getActivesWithModules()
+ {
+ return Application::with('modules')->active()->get()->toArray();
+ }
+
+ public static function getVisibles()
+ {
+ return Application::visible()->get()->toArray();
+ }
+
+ public static function getBySlug($slug)
+ {
+ return Application::active()->bySlug($slug)->first();
+ }
+}
diff --git a/app/Repositories/Cities.php b/app/Repositories/Cities.php
new file mode 100644
index 00000000..75b44428
--- /dev/null
+++ b/app/Repositories/Cities.php
@@ -0,0 +1,66 @@
+where('nom', 'LIKE', "$query%")->orderBy('nom', 'ASC')->take(30)->get();
+ }
+
+ public static function getVillesByCP($query)
+ {
+ return Ville::select('id', DB::raw("concat(nom,' (',code_postal,')') as text"))->where('code_postal', 'LIKE', "%q$guery%")->orderBy('nom', 'ASC')->take(30)->get();
+ }
+
+ public static function getCPByVille($id)
+ {
+ $ville = self::get($id);
+ $codes = explode("-", $ville->code_postal);
+ return $codes;
+ }
+
+ public static function getNomByVille($id)
+ {
+ $ville = self::get($id);
+ return $ville->nom;
+ }
+
+ public static function get($id)
+ {
+ return Ville::find($id);
+ }
+
+ public static function getCoords($adresse)
+ {
+ // dd(app('geocoder')->geocode('Los Angeles, CA')->get());
+ // dd(app('geocoder')->geocode('5 boulevard du Port, Amiens, France')->get());
+ // dump($adresse);
+ $geocode = app('geocoder')->geocode($adresse)->get();
+ // dump($geocode);
+ if (count($geocode)) {
+ // dump($geocode);
+ $res = $geocode[0]->getCoordinates()->toArray();
+ // dump($res);
+ $latitude = $res[0];
+ $longitude = $res[1];
+ // dump($latitude);
+ // dump($longitude);
+ return ['latitude' => $latitude, 'longitude' => $longitude];
+ } else {
+ return false;
+ }
+ }
+
+ public static function getCoordsByVille($id)
+ {
+ $ville = Ville::find($id);
+ return ['latitude' => $ville->latitude, 'longitude' => $ville->longitude];
+ }
+}
diff --git a/app/Repositories/Config.php b/app/Repositories/Config.php
new file mode 100644
index 00000000..3786b00b
--- /dev/null
+++ b/app/Repositories/Config.php
@@ -0,0 +1,68 @@
+ [$css_client]];
+ }
+
+ $layout = new Layout();
+ $data = $layout->init($options, $appOptions, $clientOptions, $adminOptions);
+
+ if (Users::getUser()) {
+ $data['user'] = Users::getInfo();
+ $data['user']['lang'] = Session::get('locale');
+ } else {
+ Session::put('locale', 'fr');
+ }
+
+ if (Clients::isClient()) {
+ $data['isClient'] = true;
+ $data['client'] = Clients::getInfo();
+ $data['apps'] = Clients::getApplications();
+ } else {
+ $data['isClient'] = false;
+ $data['client']['publicPath'] = $partner_path;
+ $data['apps'] = Applications::getVisibles();
+ }
+ $data['client']['partner']['publicPath'] = $partner_path;
+
+ // $layout->publish('tenant_path', $data['client']['publicPath']);
+ $data['global']['tenant_path'] = $data['client']['publicPath'];
+ $data['global']['roles'] = Users::getRoles();
+ $data['global']['permissions'] = Users::getPermissions();
+ $data['app'] = Applications::getCurrent();
+
+ return $data;
+ }
+
+ public static function getCacheVersions()
+ {
+ $data = Cache::getFilesVersion('assets/apps/ContractDrive/js', 'js');
+ // $data += Cache::getFilesVersion('assets/apps/ContractDrive/css','css');
+ return $data;
+ }
+
+}
diff --git a/app/Repositories/Core/Cache.php b/app/Repositories/Core/Cache.php
new file mode 100644
index 00000000..3155096f
--- /dev/null
+++ b/app/Repositories/Core/Cache.php
@@ -0,0 +1,48 @@
+addInclude('*.'.$type);
+ // $scanner->addExclude('*filter*');
+ // $scanner->addExclude('./src/*');
+ $path = public_path() . '/' . $folder;
+
+ $data = [];
+ foreach ($scanner($path) as $i) {
+ // dump($i);
+ $sub = $i->getPath();
+ $sub = str_replace($path, '', $sub);
+ $sub = str_replace('\\', '/', $sub);
+ // dump($sub);
+ $filename = '/' . $folder . $sub . '/' . $i->getFilename();
+ // dump($filename);
+ $mtime = $i->getMTime();
+ $data[$filename] = $mtime;
+ }
+ return $data;
+ }
+}
diff --git a/app/Repositories/Core/DataTable.php b/app/Repositories/Core/DataTable.php
new file mode 100644
index 00000000..1967fa27
--- /dev/null
+++ b/app/Repositories/Core/DataTable.php
@@ -0,0 +1,341 @@
+ $success,
+ 'data' => $data,
+ 'message' => $message,
+ 'code' => $success ? 200 : 500,
+ 'recordsTotal' => $items['total'],
+ 'recordsFiltered' => $items['totalFiltered'],
+ ];
+
+ \Debugbar::disable();
+ echo json_encode($json);
+
+ return $json;
+ exit;
+
+ return response()->json($json);
+ }
+
+ public static function get($data, $options = array())
+ {
+ // Debug::fdump($options);
+ $model = self::getModel($options);
+ $select = isset($options['select']) ? $options['select'] : '';
+ $elements = new $model();
+ $table = $elements->getTable();
+ $real_id = $table . '.id';
+
+ $data2 = static::getElements($data, $options);
+ // Debug::fdump($data2);
+ $elements = $data2['elements'];
+ $length = $data2['length'];
+ $skip = $data2['skip'];
+ $order = $data2['order'];
+ $sort = $data2['sort'];
+
+ // Debug::fdump($elements->get()->toArray());
+ //
+ // Debug::fdump($order);
+ // exit;
+
+ if (strpos($order, '.')) {
+ $tab = explode('.', $order);
+ $nb_model = count($tab) - 1;
+ for ($i = 0; $i < $nb_model; $i++) {
+ $controller = $tab[$i];
+ if (isset($options['namespace'])) {
+ $namespace = $options['namespace'];
+ } else {
+ $namespace = 'App\Models\\';
+ }
+ $jointModelObj = $namespace.ucfirst(Str::camel($controller));
+ // Debug::fdump($controller);
+ $jointModel = new $jointModelObj();
+ $jointTable = $jointModel->getTable();
+ // Debug::fdump($controller);
+ // Debug::fdump($jointTable);
+ if ($table !== $jointTable) {
+ $elements = $elements->leftJoin($jointTable, $jointTable.'.id', '=', $controller.'_id');
+ }
+ $table = $controller;
+ }
+ $order = $jointTable . '.' . $tab[$nb_model];
+ }
+
+ /*
+ if (!empty($select)) {
+ $elements = $elements->select('*',"$real_id as id", $select);
+ } else {
+ $elements = $elements->select('*',"$real_id as id");
+ }
+ */
+ // Debug::fdump($order);
+ $elements = $elements->orderBy($order, $sort);
+
+ if (!empty($options['order']) && ($options['order'] !== $order)) {
+ $elements = $elements->orderBy($options['order'], $options['sort']);
+ }
+ // Debug::dump($elements);
+ if (isset($options['trash']) && $options['trash']) {
+ $elements = $elements->withTrashed()->take($length)->skip($skip)->get();
+ } else {
+ $elements = $elements->take($length)->skip($skip)->get();
+ }
+ // Debug::dump($elements);
+
+ $tab = [
+ 'elements' => $elements->toArray(),
+ 'total' => $data2['total'],
+ 'totalFiltered' => $data2['totalFiltered']
+ ];
+
+ // dump($elements->toArray());
+
+ return $tab;
+ }
+
+ public static function getModel($options)
+ {
+ // return '\App\Models\\'.$options['app'].$options['model'];
+ return $options['model'];
+ }
+
+
+ public static function getElements($data, $options)
+ {
+ $vars = static::QueryBuilder($data, $options);
+ // Debug::fdump($vars);
+ $model = self::getModel($options);
+ // Debug::dump($model);
+
+ $elements = new $model();
+ $total = $elements::count();
+
+ // Debug::dump($vars);
+ // exit;
+
+ if (is_array($vars)) {
+ extract($vars);
+ }
+ // dump($order);
+ if (empty($order)) {
+ $order = $options['order'];
+ $sort = $options['sort'];
+ }
+
+ $with = (isset($options['with'])) ? $options['with'] : null;
+ $withCount = (isset($options['withCount'])) ? $options['withCount'] : null;
+ $where = (isset($vars['where'])) ? $vars['where'] : null;
+ $searchcol = (isset($vars['searchcol'])) ? $vars['searchcol'] : null;
+ $filter = (isset($vars['filter'])) ? $vars['filter'] : null;
+
+ Debug::dump($with);
+ Debug::dump($withCount);
+ Debug::dump($where);
+ Debug::dump($searchcol);
+ Debug::dump($filter);
+
+ $elements = ($with) ? $elements->with($with) : $elements;
+ $elements = ($withCount) ? $elements->withCount($withCount) : $elements;
+ $elements = ($where) ? $elements->whereRaw($where) : $elements;
+ $elements = ($filter) ? $elements->whereRaw($filter) : $elements;
+
+ // Debug::fdump($elements->get()->toArray());
+ // Debug::message($where);
+ // exit;
+
+ $elements = static::addSearchFilter($elements, $hasfilters);
+ $elements = static::addSearch($elements, $searchcol, $search);
+
+ Debug::dump($hasfilters);
+ // dump($search);
+ //
+
+ $totalFiltered = $elements->count();
+
+ // Debug::breakpoint($elements);
+ // exit;
+
+ $data2 = [
+ 'elements' => $elements,
+ 'total' => $total,
+ 'totalFiltered' => $totalFiltered,
+ 'length' => $length,
+ 'skip' => $skip,
+ 'order' => $order,
+ 'sort' => $sort,
+ ];
+
+ // var_dump($data2['elements']->get()->toArray());
+ return $data2;
+ }
+
+ public static function addSearchFilter($elements, $hasfilters)
+ {
+ if (is_array($hasfilters)) {
+ foreach ($hasfilters as $hasfilter) {
+ if (!empty($hasfilter['search'])) {
+ $elements = $elements->whereHas($hasfilter['controller'], function ($query) use ($hasfilter) {
+ if ($hasfilter['like']) {
+ $query->where($hasfilter['field'], 'like', '%' . $hasfilter['search'] . '%');
+ } else {
+ $query->where($hasfilter['field'], '=', $hasfilter['search']);
+ }
+ });
+ }
+ }
+ }
+ return $elements;
+ }
+
+ public static function addSearch($elements, $searchcol, $search)
+ {
+ if (!empty($search)) {
+ if (strpos($searchcol, '.')) {
+ $tab = explode('.', $searchcol);
+ $searchField = [
+ 'controller' => $tab[0],
+ 'field' => $tab[1],
+ 'search' => $search,
+ ];
+ $elements = $elements->whereHas($searchField['controller'], function ($query) use ($searchField) {
+ $query->where($searchField['field'], 'like', '%' . $searchField['search'] . '%');
+ });
+ } else {
+ $elements = $elements->where($searchcol, 'like', "%$search%");
+ }
+ }
+ return $elements;
+ }
+
+
+ public static function QueryBuilder($data, $options = array())
+ {
+ $model = self::getModel($options);
+ $elements = new $model();
+ $table = $elements->getTable();
+ $filter = '';
+ $hasfilters = array();
+ // Debug::fdump($data);
+ // Debug::message($data);
+ // Debug::dump($options);
+ // Debug::dump($data);
+
+ if (is_array($options) && is_array($options['likefields'])) {
+ $likefields = $options['likefields'];
+ }
+ $length = isset($data['length']) ? (int) $data['length'] : 10;
+ $skip = isset($data['start']) ? (int) $data['start'] : 0;
+ if (isset($data['search'])) {
+ $search = ($data['search']['value'] !== '') ? $data['search']['value'] : '';
+ } else {
+ $search = null;
+ }
+
+ // Debug::fdump($data);
+ if (isset($data['order'])) {
+ if ($data['order'][0]['dir']) { //on est sur qu'un tri est en cours, pb de la colonne 0
+ $sort = ($data['order'][0]['dir']);
+ $order = self::getSortcol($data);
+ }
+ } else {
+ $order = null;
+ $sort = null;
+ }
+
+ // Debug::dump($order);
+
+ if (isset($data['columns']) && is_array($data['columns'])) {
+ foreach ($data['columns'] as $item) {
+ $filter_search = $item['search']['value'];
+ $filter_col = ($item['name']) ? $item['name'] : $item['data'];
+
+ // Debug::dump($filter_col);
+ // Debug::dump($filter_search);
+ // Debug::dump(is_null($filter_search));
+
+ if (!is_null($filter_search)) {
+ // Debug::dump($item);
+ // Debug::dump($filter_search);
+ // Debug::dump($filter_col);
+
+ if (strpos($filter_col, '.')) {
+ $tab = explode('.', $filter_col);
+ if (is_array($likefields) && in_array($filter_col, $likefields)) {
+ $like = true;
+ } else {
+ $like = false;
+ }
+
+ $hasfilters[] = [
+ 'controller' => $tab[0],
+ 'field' => $tab[1],
+ 'search' => $filter_search,
+ 'like' => $like,
+ ];
+ } else {
+ // $filter_col = $table . '.' .$item['data'];
+ $filter .= (!empty($filter)) ? ' and ' : '';
+ if (is_array($likefields) && in_array($filter_col, $likefields)) {
+ $filter .= "($table.$filter_col LIKE '%$filter_search%')";
+ } else {
+ $filter .= "($table.$filter_col = '$filter_search')";
+ }
+ }
+ }
+ }
+ }
+
+ if (isset($data['where'])) {
+ $where = $data['where'];
+ } else {
+ $where = null;
+ }
+
+ $options = [
+ 'length' => $length,
+ 'skip' => $skip,
+ 'search' => $search,
+ 'order' => $order,
+ 'sort' => $sort,
+ 'filter' => $filter,
+ 'hasfilters' => $hasfilters,
+ 'where' => $where,
+ ];
+
+ Debug::dump($options);
+ return $options;
+ }
+
+ public static function getSortcol($data)
+ {
+ $sortcol = $data['order'][0]['column'];
+ if (!is_null($sortcol) && ($sortcol !== 0)) {
+ if (!empty($data['columns'][$sortcol]['name'])) {
+ $order = $data['columns'][$sortcol]['name'];
+ } else {
+ $order = $data['columns'][$sortcol]['data'];
+ }
+ }
+ return $order;
+ }
+}
diff --git a/app/Repositories/Core/Database.php b/app/Repositories/Core/Database.php
new file mode 100644
index 00000000..e4a62ca1
--- /dev/null
+++ b/app/Repositories/Core/Database.php
@@ -0,0 +1,50 @@
+getTable());
+ foreach ($columns as &$column) {
+ $type = Schema::getColumnType($table->getTable(), $column);
+ array_push($data, ['name' => $column, 'type' => $type]);
+ }
+ return $data;
+ }
+
+ public static function getPopulate($model, $route, $id)
+ {
+ echo Form::model($model, ['route' => [$route.'.update', $id]]);
+ }
+}
diff --git a/app/Repositories/Core/DateHelper.php b/app/Repositories/Core/DateHelper.php
new file mode 100644
index 00000000..9f80e1ad
--- /dev/null
+++ b/app/Repositories/Core/DateHelper.php
@@ -0,0 +1,52 @@
+startOfDay();
+ }
+
+ public static function byWeek()
+ {
+ return Carbon::now()->startOfWeek();
+ }
+
+ public static function byMonth()
+ {
+ return Carbon::now()->startOfMonth();
+ }
+
+ public static function byQuarter()
+ {
+ return Carbon::now()->startOfQuarter();
+ }
+
+ public static function bySemester()
+ {
+ $quarter = Carbon::now()->quarter;
+ switch ($quarter) {
+ case 1:
+ case 2:
+ $date = Carbon::now()->startOfYear();
+ break;
+ case 3:
+ $date = Carbon::now()->startOfQuarter();
+ break;
+ case 4:
+ $date = Carbon::now()->subMonth(3)->startOfQuarter();
+ break;
+ }
+ return $date;
+ }
+
+ public static function byYear()
+ {
+ return Carbon::now()->startOfYear();
+ }
+}
diff --git a/app/Repositories/Core/DateRange.php b/app/Repositories/Core/DateRange.php
new file mode 100644
index 00000000..db01073e
--- /dev/null
+++ b/app/Repositories/Core/DateRange.php
@@ -0,0 +1,114 @@
+copy()->subMonth($nb);
+ return static::getPeriodsbyMonth($begin, $end);
+ }
+
+ public static function getPeriodsLastWeek($nb)
+ {
+ $end = static::lastWeek();
+ $begin = $end->copy()->subWeek($nb);
+ return static::getPeriodsbyWeek($begin, $end);
+ }
+
+ public static function getPeriodsLastDay($nb)
+ {
+ $end = static::lastDay();
+ $begin = $end->copy()->subDay($nb);
+ return static::getPeriodsbyDay($begin, $end);
+ }
+
+ public static function byDay()
+ {
+ return [Carbon::now()->startOfDay(), Carbon::now()->endOfDay()];
+ }
+
+ public static function byWeek()
+ {
+ return [Carbon::now()->startOfWeek(), Carbon::now()->endOfWeek()];
+ }
+
+ public static function byMonth()
+ {
+ return [Carbon::now()->startOfMonth(), Carbon::now()->endOfMonth()];
+ }
+
+ public static function byQuarter()
+ {
+ return [Carbon::now()->startOfQuarter(), Carbon::now()->endOfQuarter()];
+ }
+
+ public static function bySemester()
+ {
+ $quarter = Carbon::now()->quarter;
+ switch ($quarter) {
+ case 1:
+ case 2:
+ $date = Carbon::now()->startOfYear();
+ break;
+ case 3:
+ $date = Carbon::now()->startOfQuarter();
+ break;
+ case 4:
+ $date = Carbon::now()->subMonth(3)->startOfQuarter();
+ break;
+ }
+ return [$date, $date->addMonth(6)];
+ }
+
+ public static function byYear()
+ {
+ return [Carbon::now()->startOfYear(), Carbon::now()->endOfYear()];
+ }
+
+ public static function lastMonth()
+ {
+ $start = Carbon::parse('first day of last month');
+ $start->addMonth()->startOfDay();
+ return $start;
+ }
+
+ public static function lastWeek()
+ {
+ return Carbon::parse('last monday');
+ }
+
+ public static function lastDay()
+ {
+ return Carbon::parse('yesterday');
+ }
+
+ public static function getPeriodsbyMonth($begin, $end)
+ {
+ return (static::getPeriods($begin, $end, 'MONTH'));
+ }
+
+ public static function getPeriodsbyWeek($begin, $end)
+ {
+ return (static::getPeriods($begin, $end, 'WEEK'));
+ }
+
+ public static function getPeriodsbyDay($begin, $end)
+ {
+ return (static::getPeriods($begin, $end, 'DAY'));
+ }
+
+ public static function getPeriods($begin, $end, $interval)
+ {
+ $period = new Period($begin, new \DateTime($end));
+ foreach ($period->getDatePeriod("1 $interval") as $day) {
+ $daterange[] = Period::createFromDuration($day->format('Y-m-d H:i:s'), "1 $interval");
+ }
+ return ($daterange);
+ }
+}
diff --git a/app/Repositories/Core/DateTime.php b/app/Repositories/Core/DateTime.php
new file mode 100644
index 00000000..b5a72822
--- /dev/null
+++ b/app/Repositories/Core/DateTime.php
@@ -0,0 +1,59 @@
+isoFormat('Y-MM-DD') : null;
+ }
+
+ public static function convertTime($date)
+ {
+ return $date ? Carbon::createFromFormat('d/m/Y H:i', $date)->isoFormat('Y-MM-DD HH:mm:ss') : null;
+ }
+
+ public static function toFr($date)
+ {
+ return $date ? Carbon::parse($date)->isoFormat('DD/MM/Y') : null;
+ }
+
+ public static function toFrTime($date)
+ {
+ return $date ? Carbon::parse($date)->isoFormat('DD/MM/Y HH:mm:ss') : null;
+ }
+
+ public static function FromDatetimeFr($date)
+ {
+ return $date ? Carbon::createFromFormat('d/m/Y H:i:s', $date) : null;
+ }
+
+ public static function DatetimeToStamp($date)
+ {
+ return $date ? self::FromDatetimeFr($date)->isoFormat('Y-MM-DD HH:mm:ss') : null;
+ }
+
+ public static function DatetimeToDate($date)
+ {
+ return $date ? self::FromDatetimeFr($date)->isoFormat('DD/MM/Y') : null;
+ }
+
+ public static function DatetimeToTime($date)
+ {
+ return $date ? self::FromDatetimeFr($date)->isoFormat('HH:mm') : null;
+ }
+
+ public static function isPast($date)
+ {
+ return self::FromDatetimeFr($date)->isPast();
+ }
+}
diff --git a/app/Repositories/Core/Debug.php b/app/Repositories/Core/Debug.php
new file mode 100644
index 00000000..6ebdd22f
--- /dev/null
+++ b/app/Repositories/Core/Debug.php
@@ -0,0 +1,297 @@
+debugbar = DebugBar::getInstance()->debugbar;
+ }
+
+ public static function isDebugbar()
+ {
+ return class_exists('Barryvdh\Debugbar\ServiceProvider') ? true : false;
+ }
+
+ public static function isClockwork()
+ {
+ return class_exists('Clockwork\Support\Laravel\ClockworkServiceProvider') ? true : false;
+ }
+
+ public static function start($var = '', $params = array(), $txt = '')
+ {
+ if (!static::isDebug()) {
+ return false;
+ }
+ $var = (empty($var)) ? static::getMethod() : $var;
+ $params = (empty($params)) ? static::getArgs() : $params;
+ /*
+ foreach ($params as $key => $value) {
+ $params[$key] = substr($value,30);
+ }
+ */
+ // TODO Fixer la longueur des params string passés
+ if (is_null($params)) {
+ $params = array();
+ }
+
+ Timer::start($var, $params);
+
+ if (static::isDebugbar()) {
+ \Debugbar::startMeasure($var, $txt);
+ }
+
+ if (static::isClockwork()) {
+ // clock()->startEvent($var, $txt);
+ }
+ }
+
+ public static function stop($var = '')
+ {
+ if (!static::isDebug()) {
+ return false;
+ }
+ $var = (empty($var)) ? static::getMethod() : $var;
+ Timer::stop();
+
+ if (static::isDebugbar()) {
+ \Debugbar::stopMeasure($var);
+ }
+
+ if (static::isClockwork()) {
+ // clock()->endEvent($var);
+ }
+ }
+
+ public static function render($force = false)
+ {
+ static::dump((string) Timer::result(), '', $force);
+ }
+
+ public static function memory($force = false)
+ {
+ static::dump(memory_get_usage(), '', $force);
+ }
+
+ public static function breakpoint($msg = '', $cat = '', $force = true)
+ {
+ static::dump($msg, $cat, $force);
+ static::header('paramètres');
+ static::dump(static::getArgs(), '', $force);
+ static::footer('paramètres');
+ static::render($force);
+ static::backtrace($force);
+ exit;
+ }
+
+ /**
+ * dump un message uniquement si debug est true
+ * @param string $msg [description]
+ * @return [type] [description]
+ */
+ public static function message($msg, $cat = '')
+ {
+ if (static::isDebug()) {
+ static::dump($msg, $cat);
+ }
+ }
+
+ /**
+ * force la sortie d'un dump, sans passer par la debugbar ou test si debug est true
+ * @param string $msg [description]
+ * @return [type] [description]
+ */
+ public static function fdump($msg, $cat = '')
+ {
+ static::dump($msg, $cat, 3);
+ }
+
+ /**
+ * dump un message suivant le handler de sortie prévu (log, debugbar, cli, ...)
+ * @param [type] $msg [description]
+ * @param boolean $force si true, force la sortie en output direct
+ * @return [type] [description]
+ */
+ public static function dump($msg, $cat = '', $force = false)
+ {
+ $cat = $cat ? $cat : self::getClass();
+ if ($force || self::isForcedOutput()) {
+ dump(self::getLocation());
+ dump($msg);
+ }
+
+ if (self::isDebug()) {
+ if (static::isCLI()) {
+ self::dumpCli($msg, $cat);
+ }
+ if (static::isDebugbar()) {
+ self::dumpDebugbar($msg, $cat);
+ }
+ if (static::isClockwork()) {
+ self::dumpClockwork($msg, $cat);
+ }
+ }
+ }
+
+ public static function dumpDebugbar($msg, $cat = '', $force = false)
+ {
+ \Debugbar::addMessage(self::getLocation(), $cat);
+ \Debugbar::addMessage($msg, $cat);
+ }
+
+ public static function dumpClockwork($msg, $cat = '')
+ {
+ clock($msg);
+ }
+
+ public static function dumpCli($msg, $cat = '')
+ {
+ $climate = new CLImate;
+ // $climate->yellow()->bold()->out($message);
+ // $climate->white()->bold()->out($output);
+ // $climate->out($msg);
+ // dump(self::getLocation());
+ // dump($msg);
+ }
+
+ public static function header($titre = '')
+ {
+ static::dump("*********** $titre ************");
+ }
+
+ public static function footer($titre = '')
+ {
+ static::dump("*********** Fin $titre ************");
+ }
+
+ public static function isDebug()
+ {
+ return self::getIsDebug() && 1;
+ }
+
+ public static function isForcedOutput()
+ {
+ return self::getIsDebug() > 1;
+ }
+
+ public static function getIsDebug()
+ {
+ $caller = (array) static::getCaller();
+ // dump($caller);
+ if ($caller['class']) {
+ if (isset($caller['class']::$is_debug)) {
+ $is_debug = $caller['class']::$is_debug;
+ } else {
+ $is_debug = false;
+ }
+ } else {
+ dump("la isDebug::165");
+ dump($caller);
+ $is_debug = true;
+ }
+ return $is_debug;
+ }
+
+ public static function backtrace($force = false)
+ {
+ $txt = '';
+ $backtrace = debug_backtrace();
+ $backtrace = array_reverse($backtrace);
+ foreach ($backtrace as $item) {
+ $caller = isset($item['class']) ? $item['class'] . $item['type'] . $item['function'] : $item['function'];
+ $place = isset($item['file']) ? $item['file'] . ' at ' . $item['line'] : '';
+ $txt .= "$caller | $place \n";
+ }
+ static::dump($txt, '', $force);
+ // dump($backtrace);
+ }
+
+ public static function getLocation()
+ {
+ return static::getMethod() . ' at ' . static::getFile() . ' line ' . static::getLine();
+ }
+
+ public static function getMethod()
+ {
+ return (static::getClass() . static::getType() . static::getFunction());
+ }
+
+ public static function getClass()
+ {
+ return static::getCaller()->class;
+ }
+
+ public static function getFunction()
+ {
+ return static::getCaller()->function;
+ }
+
+ public static function getType()
+ {
+ return static::getCaller()->type;
+ }
+
+ public static function getArgs()
+ {
+ // dump(static::getCaller()->args);
+ return static::getCaller()->args;
+ }
+
+ public static function getLine()
+ {
+ return static::getParent()->line;
+ }
+
+ public static function getFile()
+ {
+ return static::getParent()->file;
+ }
+
+ public static function getCaller()
+ {
+ $backtrace = debug_backtrace();
+ // dump($backtrace);
+ $k = 1;
+ while ($backtrace[$k]['class'] == 'App\Repositories\Core\Debug') {
+ $k++;
+ }
+ return (object) $backtrace[$k];
+ }
+
+ public static function getParent()
+ {
+ $backtrace = debug_backtrace();
+ // dump($backtrace);
+ $k = 1;
+ while ($backtrace[$k]['class'] == 'App\Repositories\Core\Debug') {
+ $k++;
+ }
+ return (object) $backtrace[$k - 1];
+ }
+
+ public static function getRoot()
+ {
+ $backtrace = debug_backtrace();
+ $object = isset($backtrace[0]['object']) ? $backtrace[0]['object'] : null;
+ $k = 1;
+ while (isset($backtrace[$k]) && (!isset($backtrace[$k]['object']) || $object === $backtrace[$k]['object'])) {
+ $k++;
+ }
+ return isset($backtrace[$k]['object']) ? $backtrace[$k]['object'] : null;
+ }
+
+ public static function isCLI()
+ {
+ return (PHP_SAPI == 'cli');
+ }
+}
diff --git a/app/Repositories/Core/Export.php b/app/Repositories/Core/Export.php
new file mode 100644
index 00000000..7160fd08
--- /dev/null
+++ b/app/Repositories/Core/Export.php
@@ -0,0 +1,159 @@
+xls = new PHPExcel();
+ }
+
+ public function create($filename, $stockage = false)
+ {
+ $this->sheet = $this->xls->setActiveSheetIndex(0);
+ $this->filename = $filename;
+ $this->stockage = $stockage;
+ $this->lig = 1;
+ }
+
+ public function setColumnsTitle($data)
+ {
+ $col = 0;
+ foreach ($data as $value) {
+ $this->writeTitle($this->lig, $col, $value);
+ $col++;
+ }
+ $this->lig++;
+ }
+
+ public function writeTitle($lig, $col, $txt)
+ {
+ $coord = $this->conv($lig, $col);
+ $style = $this->sheet->getStyle($coord);
+ $styleFont = $style->getFont();
+ $styleFont->setBold(true);
+ $styleFont->setSize(12);
+ $styleFont->setName('Arial');
+ // $styleFont->getColor()->setARGB(PHPExcel_Style_Color::COLOR_GREEN);
+ $this->sheet->setCellValue($coord, $txt);
+ if ($this->debug) {
+ echo "Col $col Ligne $lig : $coord Text $txt
";
+ }
+ }
+
+ public function writeCell($lig, $col, $txt)
+ {
+ $coord = $this->conv($lig, $col);
+ $this->sheet->setCellValue($coord, $txt);
+ if ($this->debug) {
+ echo "Col $col Ligne $lig : $coord Text $txt
";
+ }
+ }
+
+ public function exportRow($data, $config = null)
+ {
+ if ($config) {
+ $vars = $config['vars'];
+ $options = $config['options'];
+ $multioptions = $config['multioptions'];
+ }
+ $col = 0;
+ if (is_array($vars)) {
+ foreach ($vars as $key) {
+ $txt = $data[$key];
+ if (isset($options[$key])) {
+ $txt = $options[$key][$txt];
+ }
+ if (isset($multioptions[$key])) {
+ $tabs = BaseController::getReverseMultiOptions($txt);
+ foreach ($tabs as $key2 => $value) {
+ $txt .= $multioptions[$key][$key2] . '\n';
+ }
+ }
+ $this->writeCell($this->lig, $col, $txt);
+ $this->nb++;
+ $col++;
+ }
+ } else {
+ foreach ($data as $value) {
+ $txt = $value;
+ $this->writeCell($this->lig, $col, $txt);
+ $this->nb++;
+ $col++;
+ }
+ }
+ $this->lig++;
+ }
+
+ public function header()
+ {
+ // Redirect output to a client’s web browser (Excel5)
+ header('Content-Type: application/vnd.ms-excel');
+ header('Content-Disposition: attachment;filename="' . $this->filename . '"');
+ header('Cache-Control: max-age=0');
+ // If you're serving to IE 9, then the following may be needed
+ // header('Cache-Control: max-age=1');
+
+ // If you're serving to IE over SSL, then the following may be needed
+ header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); // Date in the past
+ header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); // always modified
+ header('Cache-Control: cache, must-revalidate'); // HTTP/1.1
+ header('Pragma: public'); // HTTP/1.0
+ }
+
+ public function close()
+ {
+ if (!$this->debug) {
+ // Debug::message($this->xls);
+ $objWriter = PHPExcel_IOFactory::createWriter($this->xls, 'Excel2007');
+ // Debug::message($objWriter);
+ // exit;
+ if (!$this->stockage) {
+ $this->header();
+ $objWriter->save('php://output');
+ } else {
+ // $objWriter->save(str_replace('.php', '.xlsx', __FILE__));
+ $objWriter->save('text.xlsx');
+ }
+ }
+ }
+
+ public function conv($lig, $col)
+ {
+ $c = static::convColtoTxt($col);
+ $lig = $this->lig;
+ return ("$c$lig");
+ }
+
+ public function convColtoTxt($col)
+ {
+ $col1 = $col % 26;
+ $col2 = (int) floor($col / 26);
+ if ($col2) {
+ $c = chr(64 + $col2);
+ } else {
+ $c = '';
+ }
+ $c .= chr(65 + $col1);
+ return ($c);
+ }
+
+ public function getOption($var)
+ {
+ $data = $this->init();
+ return ($data[$var . '_options']);
+ }
+
+ public function getOptions($data)
+ {
+ $options = array();
+ foreach ($data as $key => $value) {
+ $var = substr($key, 0, -8);
+ $options[$var] = $value;
+ }
+ return $options;
+ }
+}
diff --git a/app/Repositories/Core/Geolocation.php b/app/Repositories/Core/Geolocation.php
new file mode 100644
index 00000000..9a2d24b0
--- /dev/null
+++ b/app/Repositories/Core/Geolocation.php
@@ -0,0 +1,32 @@
+geocode($address)->get();
+
+ if (count($geocode)) {
+ $res = $geocode[0]->getCoordinates()->toArray();
+ // dump($res);
+ $longitude = $res[0];
+ $latitude = $res[1];
+ // dump($latitude);
+ // dump($longitude);
+ // exit;
+ return ['latitude' => $latitude, 'longitude' => $longitude];
+ } else {
+ return false;
+ }
+ }
+ }
+
+ public static function autocomplete($query)
+ {
+ }
+}
diff --git a/app/Repositories/Core/Menu/Builder.php b/app/Repositories/Core/Menu/Builder.php
new file mode 100644
index 00000000..fef5a477
--- /dev/null
+++ b/app/Repositories/Core/Menu/Builder.php
@@ -0,0 +1,94 @@
+%s', $title);
+
+ $id = isset($options['id']) ? $options['id'] : $this->id();
+
+ $item = new Item($this, $id, $title, $options);
+
+ if (isset($options['icon'])) {
+ $item->icon($options['icon']);
+ }
+
+ if (isset($options['role']) || isset($options['permission'])) {
+ $ability = ['admin'];
+ if (isset($options['role'])) {
+ $ability = $ability + explode(',', $options['role']);
+ }
+
+ $permission = null;
+ if (isset($options['permission'])) {
+ $permission = explode(',', $options['permission']);
+ }
+
+ $currentUser = Auth::user();
+
+ if ($currentUser && $currentUser->ability($ability, $permission)) {
+ $this->items->push($item);
+ }
+
+ } else {
+ $this->items->push($item);
+ }
+
+ return $item;
+ }
+
+ /**
+ * Add an item to a existing menu item as a submenu item.
+ *
+ * @param $id Id of the menu item to attach to
+ * @param $title Title of the sub item
+ * @param string $options
+ *
+ * @return Lavary\Menu\Item
+ */
+ public function addTo($id, $title, $options = '')
+ {
+ $parent = $this->whereId($id)->first();
+
+ if (isset($parent)) {
+ if (!isset($this->root[$parent->id])) {
+ $parent->attr(['url' => '#', 'class' => 'treeview']);
+ // $str = '';
+ // $parent->append($str);
+ $this->root[$parent->id] = true;
+ }
+
+ $item = $parent->add($title, $options);
+ } else {
+ $item = $this->add($title, $options);
+ }
+
+ $item->icon('circle-o');
+
+ return $item;
+ }
+}
diff --git a/app/Repositories/Core/Menu/Item.php b/app/Repositories/Core/Menu/Item.php
new file mode 100644
index 00000000..94b47e7c
--- /dev/null
+++ b/app/Repositories/Core/Menu/Item.php
@@ -0,0 +1,77 @@
+prepend(sprintf('', $icon));
+
+ return $this;
+ }
+
+ /**
+ * Set the item order.
+ *
+ * @param $order
+ *
+ * @return self
+ */
+ public function order($order)
+ {
+ $this->data('order', $order);
+
+ return $this;
+ }
+
+ /**
+ * Make the item active.
+ *
+ * @param string|array $routes
+ *
+ * @return self
+ */
+ public function activeIfRoute($routes = null)
+ {
+ if (!empty($routes)) {
+ if (is_string($routes)) {
+ $routes = [$routes];
+ }
+
+ foreach ($routes as $pattern) {
+ $arr = [$pattern];
+ if (if_route_pattern($arr)) {
+ $this->activate();
+
+ if (strstr($this->title, 'circle-o')) {
+ $this->title = str_replace('fa-circle-o', 'fa-dot-circle-o', $this->title);
+ }
+ // dump($this);
+ return $this;
+ }
+ }
+
+ return $this;
+ }
+
+ $activeClass = $this->builder->conf('active_class');
+ $this->attributes['class'] = Builder::formatGroupClass(['class' => $activeClass], $this->attributes);
+ $this->isActive = true;
+
+ if (strstr($this->title, 'circle-o')) {
+ $this->title = str_replace('fa-circle-o', 'fa-dot-circle-o', $this->title);
+ }
+
+ return $this;
+ }
+}
diff --git a/app/Repositories/Core/Menu/Logs.php b/app/Repositories/Core/Menu/Logs.php
new file mode 100644
index 00000000..b80834f7
--- /dev/null
+++ b/app/Repositories/Core/Menu/Logs.php
@@ -0,0 +1,27 @@
+add(__('boilerplate::logs.menu.category'), ['permission' => 'logs', 'icon' => 'list'])
+ ->id('logs')
+ ->order(1100);
+
+ $menu->addTo('logs', __('boilerplate::logs.menu.stats'), [
+ 'route' => 'boilerplate.logs.dashboard',
+ 'permission' => 'logs', ])
+ ->order(1110)
+ ->activeIfRoute('boilerplate.logs.dashboard');
+
+ $menu->addTo('logs', __('boilerplate::logs.menu.reports'), [
+ 'route' => 'boilerplate.logs.list',
+ 'permission' => 'logs', ])
+ ->order(1120)
+ ->activeIfRoute(['boilerplate.logs.list', 'boilerplate.logs.show', 'boilerplate.logs.filter']);
+ }
+}
diff --git a/app/Repositories/Core/Menu/Menu.php b/app/Repositories/Core/Menu/Menu.php
new file mode 100644
index 00000000..b1d10d38
--- /dev/null
+++ b/app/Repositories/Core/Menu/Menu.php
@@ -0,0 +1,29 @@
+menu)) {
+ $this->menu[$name] = new Builder($name, $this->loadConf($name));
+ }
+
+ // Registering the items
+ call_user_func($callback, $this->menu[$name]);
+
+ // Storing each menu instance in the collection
+ $this->collection->put($name, $this->menu[$name]);
+
+ // Make the instance available in all views
+ View::share($name, $this->menu[$name]);
+
+ return $this->menu[$name];
+ }
+ }
+}
diff --git a/app/Repositories/Core/Menu/Users.php b/app/Repositories/Core/Menu/Users.php
new file mode 100644
index 00000000..7210c80d
--- /dev/null
+++ b/app/Repositories/Core/Menu/Users.php
@@ -0,0 +1,33 @@
+add(__('boilerplate::layout.access'), ['icon' => 'users'])
+ ->id('access')
+ ->order(1000);
+
+ $menu->addTo('access', __('boilerplate::users.list.title'), [
+ 'route' => 'boilerplate.users.index',
+ 'permission' => 'users_crud', ])
+ ->activeIfRoute(['boilerplate.users.index', 'boilerplate.users.edit']);
+
+ $menu->addTo('access', __('boilerplate::users.create.title'), [
+ 'route' => 'boilerplate.users.create',
+ 'permission' => 'users_crud', ])
+ ->activeIfRoute('boilerplate.users.create');
+
+ $menu->addTo('access', __('boilerplate::layout.role_management'), [
+ 'route' => 'boilerplate.roles.index',
+ 'permission' => 'roles_crud', ])
+ ->activeIfRoute('boilerplate.roles.*');
+
+ $menu->addTo('access', __('boilerplate::users.profile.title'), ['route' => 'boilerplate.user.profile'])
+ ->activeIfRoute('boilerplate.user.profile');
+ }
+}
diff --git a/app/Repositories/Core/Number.php b/app/Repositories/Core/Number.php
new file mode 100644
index 00000000..21e8492b
--- /dev/null
+++ b/app/Repositories/Core/Number.php
@@ -0,0 +1,21 @@
+setCulture('fr-FR');
+
+ $formatter->setLanguageManager($languageManager);
+
+ $price = $formatter->format($value, '0,0');
+ return $price;
+ }
+}
diff --git a/app/Repositories/Core/Stat.php b/app/Repositories/Core/Stat.php
new file mode 100644
index 00000000..49b2ae93
--- /dev/null
+++ b/app/Repositories/Core/Stat.php
@@ -0,0 +1,187 @@
+ $begin, 'end' => $end, 'count' => $item['count']];
+ }
+ return $tab;
+ }
+
+
+ /*
+ fonctions de rendus
+ */
+
+ public static function renderStatsbyMultiVar($var, $var_option = '')
+ {
+ static::renderStatsJson(static::getStatsbyMultiVar($var, $var_option));
+ }
+
+ public static function renderStatsbyVar($var)
+ {
+ static::renderStatsJson(static::getStatsbyVar($var));
+ }
+
+ public static function renderStatsbyOptions($var, $var_option = '')
+ {
+ static::renderStatsJson(static::getStatsbyOptions($var, $var_option));
+ }
+
+ public static function renderStatsJson($data)
+ {
+ Response::headers()->set('Content-Type', 'application/json');
+ Response::setBody(json_encode($data, JSON_NUMERIC_CHECK));
+ }
+
+
+ /*
+ Fonctions internes
+ */
+
+ public static function getStatsbyMultiVar($var, $var_option = '')
+ {
+ if (empty($var_option)) {
+ $var_option = $var;
+ }
+ $options = self::getInstance()->controller->getOption($var_option);
+ return self::getInstance()->getStatsbyMultiOptions($var, $options);
+ }
+
+ public static function getCountByPeriod($var, $begin, $end)
+ {
+ $count = static::getModel()
+ ->whereBetween($var, $begin, $end)
+ ->count();
+ return $count;
+ }
+
+ public static function getCountbyVar($var)
+ {
+ $db = self::getInstance()->app->db;
+ $data = static::getModel()
+ ->select($db::raw("count(id) as y, $var as name"))
+ ->groupBy($var)
+ ->get();
+ // var_Debug::message($data);
+ return ($data);
+ }
+
+
+ public static function getStatsbyOptions($var, $var_option = '')
+ {
+ if (empty($var_option)) {
+ $var_option = $var;
+ }
+ $options = self::getInstance()->controller->getOption($var_option);
+ $nb = static::getCountbyOption($var);
+ // var_Debug::message($nb);
+ foreach ($options as $key => $value) {
+ $y = (int) $nb[$key];
+ $data[] = ['y' => $y, 'name' => $value];
+ }
+ // var_Debug::message($data);
+ return ($data);
+ }
+
+ public static function getCountbyOption($var)
+ {
+ $db = self::getInstance()->app->db;
+ $data = static::getModel()
+ ->select($db::raw('count(id) as nb'))
+ ->groupBy($var)
+ ->get();
+ foreach ($data as $key => $value) {
+ if (is_array($data[$key])) {
+ $data[$key] = (int) $data[$key]['nb'];
+ } else {
+ $data[$key] = (int) $data[$key]->nb;
+ }
+ }
+ return ($data);
+ }
+
+ public static function getStatsbyMultiOptions($var, $options)
+ {
+ foreach ($options as $key => $value) {
+ $nb = static::getCountbyBin($var, $key);
+ $data[] = ['y' => $nb, 'name' => $value];
+ }
+ return ($data);
+ }
+
+ public static function getCountbyBin($var, $value)
+ {
+ $bit = pow(2, $value);
+ $count = static::getModel()
+ ->where($var, '&', $bit)
+ ->count();
+ return $count;
+ }
+
+
+ public static function getStatsbyPeriod($begin = '', $end = '', $period = 'days')
+ {
+ $end = Carbon::now();
+ $begin = Carbon::now()->subMonth(1);
+ switch ($period) {
+ case 'days':
+ $periods = DateRange::getPeriodsbyDay($begin, $end);
+ break;
+ case 'months':
+ $periods = DateRange::getPeriodsbyMonth($begin, $end);
+ break;
+ case 'weeks':
+ $periods = DateRange::getPeriodsbyWeek($begin, $end);
+ break;
+ default:
+ }
+ return ($periods);
+ }
+
+ public static function serializeValues($tab)
+ {
+ return static::serializeByVar($tab, 'count');
+ }
+
+ public static function serializeByVar($tab, $var, $n = 0)
+ {
+ $collection = collect($tab);
+
+ if ($n) {
+ $tab = $collection->pluck($var)->slice(-$n)->toArray();
+ } else {
+ $tab = $collection->pluck($var)->toArray();
+ }
+
+ return implode(",", $tab);
+ }
+
+ public static function avgByVar($tab, $var)
+ {
+ return collect($tab)->pluck($var)->avg();
+ }
+}
diff --git a/app/Repositories/Core/Upload.php b/app/Repositories/Core/Upload.php
new file mode 100644
index 00000000..cf6fdde6
--- /dev/null
+++ b/app/Repositories/Core/Upload.php
@@ -0,0 +1,101 @@
+getClientOriginalName();
+ $data['filetype'] = $file->extension();
+ $data['filesize'] = $file->getSize();
+ return $data;
+ }
+
+ public static function getUuid($file, $data)
+ {
+ $data = (is_array($data)) ? (object) $data : $data;
+ $pos = strrpos($file, '/');
+ $uuid = substr($file, $pos+1);
+ $uuid = str_replace('.' . $data->filetype, '', $uuid);
+ return $uuid;
+ }
+
+ public static function store($file, $filepath)
+ {
+ return $file->store($filepath);
+ }
+
+ public static function storePublic($file, $filepath)
+ {
+ // exit;
+ $filepath = 'public/' . $filepath;
+ return $file->store($filepath);
+ }
+
+ public static function delete($file)
+ {
+ return Storage::delete($file);
+ }
+
+ public static function createThumb($file, $size, $sub = false)
+ {
+ $thumb = self::getThumbPath($file, $sub);
+ $filename = self::getPublicPath($file);
+ return Image::make($filename)->orientate()->widen($size)->save($thumb);
+ }
+
+ /*
+ public static function getPath($file) {
+ return 'public/' . self::getFilename($file);
+ }
+ */
+
+ public static function getPublicPath($file)
+ {
+ return storage_path('app/public/' . self::getFilename($file));
+ }
+
+ public static function getPrivatePath($file)
+ {
+ return storage_path('app/' . self::getFilename($file));
+ }
+
+ public static function getSrc($file)
+ {
+ return '/storage/' . self::getFilename($file);
+ }
+
+ public static function getThumbPath($file)
+ {
+ return storage_path('app/public/' . self::getThumbFilename($file));
+ }
+
+ public static function getThumbSrc($file)
+ {
+ return '/storage/' . self::getThumbFilename($file);
+ }
+
+ public static function getFilename($file)
+ {
+ $file = (is_array($file)) ? (object) $file : $file;
+ return $file->filepath . '/' . self::getName($file);
+ }
+
+ public static function getThumbFilename($file, $sub = false)
+ {
+ $sub = $sub ? $sub : 'thumbs/';
+ $file = (is_array($file)) ? (object) $file : $file;
+ return $file->filepath . '/' . $sub . self::getName($file);
+ }
+
+ public static function getName($file)
+ {
+ $file = (is_array($file)) ? (object) $file : $file;
+ return $file->uuid . '.' .$file->filetype;
+ }
+}
diff --git a/app/Repositories/Core/User/NewUser.php b/app/Repositories/Core/User/NewUser.php
new file mode 100644
index 00000000..7dc1bc73
--- /dev/null
+++ b/app/Repositories/Core/User/NewUser.php
@@ -0,0 +1,66 @@
+markdown('notifications.email')
+ ->greeting(__('notifications.greeting', ['firstname' => $notifiable->first_name]))
+ ->subject(__('notifications.newuser.subject', ['name' => config('app.name')]))
+ ->line(__('notifications.newuser.intro', [
+ 'name' => $currentUser->first_name.' '.$currentUser->last_name,
+ ]))
+ ->action(
+ __('notifications.newuser.button'),
+ route('users.firstlogin', $notifiable->remember_token)
+ )
+ ->salutation(__('notifications.salutation', [
+ 'name' => $currentUser->first_name.' '.$currentUser->last_name,
+ ]))
+ ->line(__('notifications.newuser.outro'));
+ }
+
+ /**
+ * Get the array representation of the notification.
+ *
+ * @param mixed $notifiable
+ *
+ * @return array
+ */
+ public function toArray($notifiable)
+ {
+ return [
+ //
+ ];
+ }
+}
diff --git a/app/Repositories/Core/User/ResetPassword.php b/app/Repositories/Core/User/ResetPassword.php
new file mode 100644
index 00000000..763d1691
--- /dev/null
+++ b/app/Repositories/Core/User/ResetPassword.php
@@ -0,0 +1,31 @@
+markdown('notifications.email')
+ ->greeting(__('notifications.greeting', ['firstname' => $notifiable->first_name]))
+ ->subject(__('notifications.resetpassword.subject'))
+ ->line(__('notifications.resetpassword.intro'))
+ ->action(
+ __('notifications.resetpassword.button'),
+ route('password.reset', $this->token)
+ )
+ ->line(__('notifications.resetpassword.outro'));
+ }
+*/
+}
diff --git a/app/Repositories/Shop/Products.php b/app/Repositories/Shop/Products.php
new file mode 100644
index 00000000..5dbbe2f7
--- /dev/null
+++ b/app/Repositories/Shop/Products.php
@@ -0,0 +1,217 @@
+orderBy('name');
+ return Datatables::of($model)->make(true);
+ }
+
+ public static function select_all()
+ {
+ return Product::select('id','name','active')->orderBy('name','asc')->get()->toArray();
+ }
+
+ public static function select_by_id($id)
+ {
+ return Product::find($id)->toArray();
+ }
+
+ public static function getId($Product = false)
+ {
+ $Product = self::get($Product);
+ return $Product ? $Product->id : false;
+ }
+
+ public static function get($Product = false)
+ {
+ $website = self::getWebsite($Product);
+ return $website ? Product::byWebsite($website->id)->first() : false;
+ }
+
+ public static function store($data)
+ {
+ $id = isset($data['id']) ? $data['id'] : false;
+ if (!$id) {
+ $Product_id = self::create($data);
+ } else {
+ $Product_id = self::update($data);
+ }
+
+ ApplicationProducts::associate($Product_id, $data['applications']);
+
+ return $Product_id;
+ }
+
+ public static function create($data)
+ {
+ $slug = Str::slug($data['slug'],'-');
+ $url = $slug . '.' . Partners::getDomain();
+ $website = Websites::create($url);
+ $item = [];
+ $item['website_id'] = $website->id;
+ $item['name'] = $data['name'];
+ $item['slug'] = $slug;
+ $item['repository'] = $slug;
+ $item['session_name'] = $slug . '_sess';
+ $item['logo_image'] = 'logo.png';
+ $item['background_image'] = 'login-background.jpg';
+ $item['custom_css'] = 'Product.css';
+ $item['active'] = true;
+ $Product = Product::create($item);
+
+ $DB_system = Partners::getDBName();
+ $sql = "GRANT SELECT ON `$DB_system`.* TO '" . $website->uuid . "'@localhost";
+ DB::connection('system')->statement($sql);
+ // GRANT SELECT ON `legstack`.* TO '828656d3463e45c0a33e9cc8b5c2f265'@'127.0.0.1';
+ return $Product->id;
+ }
+
+ public static function update($data)
+ {
+ // TODO
+ }
+
+ public static function destroy($id)
+ {
+ $Product = Product::find($id);
+
+ }
+
+ public static function getPublicPath($repository = false, $Product = false)
+ {
+ return self::getLocalPath() . self::getPath($repository, $Product);
+ }
+
+ /**
+ * [getPrivatePath renvoie le chemin complet du repertoire du tenant ]
+ * @param boolean $repository [description]
+ * @param boolean $Product [description]
+ * @return [type] [description]
+ */
+ public static function getPrivatePath($repository = false, $Product = false)
+ {
+ return self::getPrivateDir($repository, $Product);
+ }
+
+ public static function getPrivateDir($repository = false, $Product = false)
+ {
+ return self::getLocalDir() . self::getPath($repository, $Product);
+ }
+
+ /**
+ * [getRelativePath renvoie le chemin relatif au storage ]
+ * @param boolean $repository [description]
+ * @param boolean $Product [description]
+ * @return [type] [description]
+ */
+ public static function getRelativePath($repository = false, $Product = false)
+ {
+ return self::getTenancyRoot() . self::getPath($repository, $Product);
+ }
+
+ /**
+ * [getPath renvoie le chemin relatif à la tenancy root]
+ * @param boolean $repository [description]
+ * @param boolean $Product [description]
+ * @return [type] [description]
+ */
+ public static function getPath($repository = false, $Product = false)
+ {
+ $path = '/'. self::getSlug($Product);
+ $path .= $repository ? $repository : '';
+ return $path;
+ }
+
+ /**
+ * [getStorage revoie le storage du tenant (local, S3, ...)]
+ * @return [type] [description]
+ */
+ public static function getStorage()
+ {
+ return Storage::disk('tenant');
+ }
+
+ public static function getDirectory()
+ {
+ return app(\Hyn\Tenancy\Website\Directory::class);
+ }
+
+ /**
+ * [getLocalDir renvoie le chemin complet vers la tenancy sur le disque]
+ * @return [type] [description]
+ */
+ public static function getLocalDir()
+ {
+ return storage_path('app' . self::getTenancyRoot());
+ }
+
+ /**
+ * [getLocalPath revnoie le chemin public vers la tenancy publique]
+ * @return [type] [description]
+ */
+ public static function getLocalPath()
+ {
+ return '/storage' . self::getTenancyRoot();
+ }
+
+ public static function getSlug($Product = false)
+ {
+ if ($Product) {
+ return $Product;
+ }
+
+ $website = self::getWebsite();
+ if ($website) {
+ return($website->uuid);
+ }
+
+ /*
+ // regarde si le Product existe et qu'il possède au moins une licence valide pour une des applications
+ $host = array_key_exists('HTTP_HOST', $_SERVER) ? $_SERVER['HTTP_HOST'] : 'legtech.legtech';
+ $url_hostname = explode(".", $host); // décompose l'url de base
+ $slug = $url_hostname[0];
+ if ($slug == 'legstack') {
+ $slug = 'legtech';
+ }
+ return $slug;
+ */
+ }
+
+ // récupère les informations de connexion à la base du Product
+ public static function getDatabaseEnvironment($Product_id)
+ {
+ return Product::byId($Product_id)->first()->toArray();
+ }
+
+ public static function isProduct()
+ {
+ $website = self::getWebsite();
+ $is_Product = $website ? true : false;
+ return $is_Product;
+ }
+
+ public static function getWebsite()
+ {
+ return \Hyn\Tenancy\Facades\TenancyFacade::website();
+ }
+
+ public static function getWebsiteByProduct($id)
+ {
+ $Product = Product::find($id);
+ return Website::find($Product->website_id);
+ }
+
+}
diff --git a/app/Repositories/Teams.php b/app/Repositories/Teams.php
new file mode 100644
index 00000000..686aa79b
--- /dev/null
+++ b/app/Repositories/Teams.php
@@ -0,0 +1,80 @@
+get();
+ }
+
+ public static function getUsersIdByTeam($id)
+ {
+ return self::getUsersByTeam($id)->pluck('user_id');
+ }
+
+ public static function getUsersByTeam2($id)
+ {
+ return Team::find($id)->users();
+ }
+
+ public static function getOptions()
+ {
+ return Team::get()->pluck('name', 'id');
+ }
+
+ public static function get($id)
+ {
+ return Team::find($id);
+ }
+
+ public static function getTable($id)
+ {
+ $datas = Team::with(['societe'])->withCount(['users']);
+ return Datatables::of($datas)->make(true);
+ }
+
+ public static function delete($id)
+ {
+ Users::destroyByUniqueTeam($id);
+ return Team::destroy($id);
+ }
+
+ public static function destroyBySociete($id)
+ {
+ $teams = Team::bySociete($id)->get();
+ foreach ($teams as $team) {
+ self::delete($team->id);
+ }
+ }
+
+ // ajoute une équipe/service/direction
+ public static function create($data)
+ {
+ return Team::create($data);
+ }
+
+ // met à jour les informations d'une équipe/service/direction
+ public static function update($data)
+ {
+ return Team::find($data['id'])->update($data);
+ }
+}
diff --git a/app/Repositories/Users.php b/app/Repositories/Users.php
new file mode 100644
index 00000000..500dc37b
--- /dev/null
+++ b/app/Repositories/Users.php
@@ -0,0 +1,177 @@
+first();
+ return $partenaire ? $partenaire->id : null;
+ }
+
+ public static function getPartenaire($user_id = false)
+ {
+ $user_id = $user_id ? $user_id : self::getId();
+ return Societe::partenaireByUser($user_id)->first();
+ }
+
+ public static function getPromoteurId($user_id = false)
+ {
+ $user_id = $user_id ? $user_id : self::getId();
+ return Promoteur::byUser($user_id)->first()->id;
+ }
+
+ public static function getPromoteur($user_id = false)
+ {
+ $user_id = $user_id ? $user_id : self::getId();
+ return Societe::promoteurByUser($user_id)->first();
+ }
+
+ public static function getInfo($id = false)
+ {
+ return self::getWithDetail($id);
+ }
+
+ public static function getWithDetail($id = false)
+ {
+ $id = $id ? $id : self::getId();
+ return User::where('id', $id)->with(['user_detail'])->first();
+ }
+
+ public static function getEmailsByRole($role) {
+ return User::select('id','email')->whereRoleIs($role)->get()->toArray();
+ }
+
+ public static function getIdsByRole($role) {
+ return User::select('id')->whereRoleIs($role)->get()->pluck('id')->toArray();
+ }
+
+ public static function getListByRole($role)
+ {
+ return self::selectOptions()->orderBy('nom', 'asc')->whereRoleIs($role)->get();
+ }
+
+ public static function getOptions()
+ {
+ return self::selectOptions()->get();
+ }
+
+ public static function selectOptions()
+ {
+ return User::select('id', DB::raw("concat(last_name,' ',first_name) as nom"));
+ }
+
+ public static function hasRole($role)
+ {
+ $user = self::get();
+ return $user ? $user->hasRole($role) : false;
+ }
+
+ public static function getId()
+ {
+ return self::getUser()->id;
+ }
+
+ public static function get($id = false)
+ {
+ $id = $id ? $id : self::getId();
+ return User::find($id);
+ }
+
+ public static function getUser()
+ {
+ return Auth::user();
+ }
+
+ public static function isConnected()
+ {
+ return Auth::check();
+ }
+
+ public static function delete($id)
+ {
+ $t = RoleUser::byUser($id)->delete();
+ return User::destroy($id);
+ }
+
+ public static function getByTeam($id)
+ {
+ return User::byTeam($id)->get();
+ }
+
+ public static function getByUniqueTeam($id)
+ {
+ return User::byTeam($id)->byUniqueTeam()->get();
+ }
+
+ public static function destroyByUniqueTeam($id)
+ {
+ return User::byTeam($id)->byUniqueTeam()->delete();
+ }
+
+ // récupère les champs de la table
+ public static function get_field_table()
+ {
+ return $this->getConnection()->getSchemaBuilder()->getColumnListing($this->getTable());
+ }
+
+ // ajoute un utilisateur
+ public static function insert($data)
+ {
+ return User::create($data);
+ }
+
+ // récupère tous les utilisateurs
+ public static function select_all()
+ {
+ return User::all()->toArray();
+ }
+
+
+ // met à jour les informations d'un utilisateur
+ public static function update(Request $request)
+ {
+ return User::find($data['id'])->update($data);
+ }
+
+ // met à jour le mot de passe d'un utilisateur
+ public static function update_password($id, $password)
+ {
+ $user = User::find($id);
+ $user->password = Hash::make($password);
+ return $user->save();
+ }
+}
diff --git a/app/Twiggy.php b/app/Twiggy.php
new file mode 100644
index 00000000..f79f51db
--- /dev/null
+++ b/app/Twiggy.php
@@ -0,0 +1,111 @@
+get('menu_admin')->asUl();
+ }
+
+ public function pretty_date($date)
+ {
+ $time = strtotime($date);
+ $now = time();
+ $ago = $now - $time;
+ $futur = 0;
+
+ if ($ago < 0) {
+ $ago = (-1 * $ago);
+ $futur = 1;
+ }
+
+ if ($ago < 60) {
+ $when = round($ago);
+ $s = ($when == 1) ? "seconde" : "secondes";
+ $txt = "$when $s";
+ } elseif ($ago < 3600) {
+ $when = round($ago / 60);
+ $m = ($when == 1) ? "minute" : "minutes";
+ $txt = "$when $m";
+ } elseif ($ago >= 3600 && $ago < 86400) {
+ $when = round($ago / 60 / 60);
+ $h = ($when == 1) ? "heure" : "heures";
+ $txt = "$when $h";
+ } elseif ($ago >= 86400 && $ago < 2629743.83) {
+ $when = round($ago / 60 / 60 / 24);
+ $d = ($when == 1) ? "jour" : "jours";
+ $txt = "$when $d";
+ } elseif ($ago >= 2629743.83 && $ago < 31556926) {
+ $when = round($ago / 60 / 60 / 24 / 30.4375);
+ $m = "mois";
+ $txt = "$when $m";
+ } else {
+ $when = round($ago / 60 / 60 / 24 / 365);
+ $y = ($when == 1) ? "an" : "ans";
+ $txt = "$when $y";
+ }
+
+ if ($futur) {
+ $txt = "dans " . $txt;
+ } else {
+ $txt = "il y a " . $txt;
+ }
+ return $txt;
+ }
+}
diff --git a/app/Update.php b/app/Update.php
new file mode 100644
index 00000000..3ebd2bb6
--- /dev/null
+++ b/app/Update.php
@@ -0,0 +1,32 @@
+external('composer', 'install', '--no-dev', '--prefer-dist', '--optimize-autoloader')
+ ->external('npm', 'install', '--production')
+ ->external('npm', 'run', 'production')
+ ->artisan('route:cache')
+ ->artisan('config:cache')
+ ->artisan('event:cache')
+ ->artisan('migrate', ['--force' => true])
+ ->artisan('cache:clear')
+ ->artisan('queue:restart'); // ->artisan('horizon:terminate');
+ }
+
+ public function local(Runner $run)
+ {
+ return $run
+ ->external('composer', 'install')
+ ->external('npm', 'install')
+ ->external('npm', 'run', 'development')
+ ->artisan('migrate')
+ ->artisan('cache:clear');
+ }
+}
diff --git a/app/User.php b/app/User.php
index e79dab7f..ebbae15a 100644
--- a/app/User.php
+++ b/app/User.php
@@ -2,32 +2,70 @@
namespace App;
+use Carbon\Carbon;
use Illuminate\Contracts\Auth\MustVerifyEmail;
+use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
+use Laratrust\Traits\LaratrustUserTrait;
+use Mpociot\Teamwork\Traits\UserHasTeams;
+use Sebastienheyd\Boilerplate\Notifications\NewUser as NewUserNotification;
+use Sebastienheyd\Boilerplate\Notifications\ResetPassword as ResetPasswordNotification;
+
+/**
+ * Sebastienheyd\Boilerplate\Models\User.
+ *
+ * @property int $id
+ * @property bool $active
+ * @property string $first_name
+ * @property string $last_name
+ * @property string $email
+ * @property string $password
+ * @property string $remember_token
+ * @property \Carbon\Carbon $created_at
+ * @property \Carbon\Carbon $updated_at
+ * @property string $deleted_at
+ * @property string $last_login
+ * @property-read string|false $avatar_path
+ * @property-read string $avatar_url
+ * @property-read mixed $name
+ * @property-read \Illuminate\Notifications\DatabaseNotificationCollection|\Illuminate\Notifications\DatabaseNotification[] $notifications
+ * @property-read \Illuminate\Database\Eloquent\Collection|\Sebastienheyd\Boilerplate\Models\Permission[] $permissions
+ * @property-read \Illuminate\Database\Eloquent\Collection|\Sebastienheyd\Boilerplate\Models\Role[] $roles
+ *
+ * @method static \Illuminate\Database\Query\Builder|\Sebastienheyd\Boilerplate\Models\User whereActive($value)
+ * @method static \Illuminate\Database\Query\Builder|\Sebastienheyd\Boilerplate\Models\User whereCreatedAt($value)
+ * @method static \Illuminate\Database\Query\Builder|\Sebastienheyd\Boilerplate\Models\User whereDeletedAt($value)
+ * @method static \Illuminate\Database\Query\Builder|\Sebastienheyd\Boilerplate\Models\User whereEmail($value)
+ * @method static \Illuminate\Database\Query\Builder|\Sebastienheyd\Boilerplate\Models\User whereFirstName($value)
+ * @method static \Illuminate\Database\Query\Builder|\Sebastienheyd\Boilerplate\Models\User whereId($value)
+ * @method static \Illuminate\Database\Query\Builder|\Sebastienheyd\Boilerplate\Models\User whereLastLogin($value)
+ * @method static \Illuminate\Database\Query\Builder|\Sebastienheyd\Boilerplate\Models\User whereLastName($value)
+ * @method static \Illuminate\Database\Query\Builder|\Sebastienheyd\Boilerplate\Models\User wherePassword($value)
+ * @method static \Illuminate\Database\Query\Builder|\Sebastienheyd\Boilerplate\Models\User whereRememberToken($value)
+ * @method static \Illuminate\Database\Query\Builder|\Sebastienheyd\Boilerplate\Models\User whereRoleIs($role = '')
+ * @method static \Illuminate\Database\Query\Builder|\Sebastienheyd\Boilerplate\Models\User whereUpdatedAt($value)
+ * @mixin \Eloquent
+ */
+
class User extends Authenticatable
{
use Notifiable;
+ use LaratrustUserTrait;
+ use SoftDeletes;
+ use UserHasTeams;
/**
* The attributes that are mass assignable.
*
* @var array
*/
- protected $fillable = [
- 'name', 'email', 'password',
- ];
+ protected $fillable = ['active', 'last_name', 'first_name', 'email', 'password', 'remember_token', 'last_login'];
- /**
- * The attributes that should be hidden for arrays.
- *
- * @var array
- */
- protected $hidden = [
- 'password', 'remember_token',
- ];
+ protected $hidden = ['password', 'remember_token'];
+
/**
* The attributes that should be cast to native types.
*
@@ -36,4 +74,169 @@ class User extends Authenticatable
protected $casts = [
'email_verified_at' => 'datetime',
];
+
+ public function user_detail()
+ {
+ return $this->hasOne('App\Models\UserDetail');
+ }
+
+ public function teams2()
+ {
+ return $this->hasManyThrough('App\Team', 'App\Models\TeamUser', 'user_id', 'id', 'id', 'team_id');
+ }
+
+ public function scopeByTeam($query, $id)
+ {
+ return $query->whereHas('teams2', function ($query) use ($id) {
+ $query->where('id', $id);
+ });
+ }
+
+ public function scopeByUniqueTeam($query)
+ {
+ return $query->has('teams2', '=', 1);
+ }
+
+ public function scopeBySociete($query, $id)
+ {
+ return $query->whereHas('teams2', function ($query) use ($id) {
+ $query->bySociete($id);
+ });
+ }
+
+ public function scopeByPartenaire($query, $id)
+ {
+ return $query->whereHas('teams2', function ($query) use ($id) {
+ $query->byPartenaire($id);
+ });
+ }
+
+ public function scopeActive($query)
+ {
+ return $query->where('active', 1);
+ }
+
+ /**
+ * Send the password reset notification.
+ *
+ * @param string $token
+ *
+ * @return void
+ */
+ public function sendPasswordResetNotification($token)
+ {
+ $this->notify(new ResetPasswordNotification($token));
+ }
+
+ /**
+ * Send notification when a new user is created.
+ *
+ * @param string $token
+ */
+ public function sendNewUserNotification($token)
+ {
+ $this->notify(new NewUserNotification($token, $this));
+ }
+
+ /**
+ * Return last name in uppercase by default.
+ *
+ * @param $value
+ *
+ * @return string
+ */
+ public function getLastNameAttribute($value)
+ {
+ return mb_strtoupper($value);
+ }
+
+ /**
+ * Return first name with first char of every word in uppercase.
+ *
+ * @param $value
+ *
+ * @return string
+ */
+ public function getFirstNameAttribute($value)
+ {
+ return mb_convert_case($value, MB_CASE_TITLE);
+ }
+
+ /**
+ * Return a concatenation of first name and last_name if field name does not exists.
+ *
+ * @param $value
+ *
+ * @return string
+ */
+ public function getNameAttribute($value)
+ {
+ if (!empty($value)) {
+ return $value;
+ }
+
+ return $this->first_name.' '.$this->last_name;
+ }
+
+ /**
+ * Return last login date formatted.
+ *
+ * @param string $format
+ * @param string $default
+ *
+ * @return mixed|string
+ */
+ public function getLastLogin($format = 'YYYY-MM-DD HH:mm:ss', $default = '')
+ {
+ if ($this->last_login === null) {
+ return $default;
+ }
+
+ return Carbon::createFromTimeString($this->last_login)->isoFormat($format);
+ }
+
+ /**
+ * Return role list as a string.
+ *
+ * @return string
+ */
+ public function getRolesList()
+ {
+ $res = [];
+ foreach ($this->roles as $role) {
+ $res[] = __($role->display_name);
+ }
+ if (empty($res)) {
+ return '-';
+ }
+
+ return implode(', ', $res);
+ }
+
+ /**
+ * Check if current user has an avatar.
+ *
+ * @return string|false
+ */
+ public function getAvatarPathAttribute()
+ {
+ return public_path('images/avatars/'.md5($this->id.$this->email).'.jpg');
+ }
+
+ /**
+ * Return current user avatar uri.
+ *
+ * @return string
+ */
+ public function getAvatarUrlAttribute()
+ {
+ if (is_file($this->avatar_path)) {
+ $ts = filemtime($this->avatar_path);
+
+ return asset('images/avatars/'.md5($this->id.$this->email).'.jpg?t='.$ts);
+ }
+
+ return asset('/assets/vendor/boilerplate/images/default-user.png');
+ }
+
}
diff --git a/artisan b/artisan
new file mode 100644
index 00000000..5c23e2e2
--- /dev/null
+++ b/artisan
@@ -0,0 +1,53 @@
+#!/usr/bin/env php
+make(Illuminate\Contracts\Console\Kernel::class);
+
+$status = $kernel->handle(
+ $input = new Symfony\Component\Console\Input\ArgvInput,
+ new Symfony\Component\Console\Output\ConsoleOutput
+);
+
+/*
+|--------------------------------------------------------------------------
+| Shutdown The Application
+|--------------------------------------------------------------------------
+|
+| Once Artisan has finished running, we will fire off the shutdown events
+| so that any final work may be done by the application before we shut
+| down the process. This is the last thing to happen to the request.
+|
+*/
+
+$kernel->terminate($input, $status);
+
+exit($status);
diff --git a/composer.json b/composer.json
index d28160c0..44ea1eae 100644
--- a/composer.json
+++ b/composer.json
@@ -1,7 +1,7 @@
{
- "name": "laravel/laravel",
+ "name": "humanet/opensem",
"type": "project",
- "description": "The Laravel Framework.",
+ "description": "Gestion ERP/E-Commerce de semences",
"keywords": [
"framework",
"laravel"
@@ -9,17 +9,91 @@
"license": "MIT",
"require": {
"php": "^7.2",
+ "arcanedev/log-viewer": "^7.0",
+ "arrilot/laravel-widgets": "^3.13",
+ "awssat/laravel-sync-migration": "^0.2",
+ "box/spout": "^3.1",
+ "browner12/helpers": "^3.0",
+ "coduo/php-humanizer": "^3.0",
+ "consoletvs/charts": "^6.5",
+ "cornford/googlmapper": "^3.0",
+ "datatables/datatables": "^1.10",
+ "eduardokum/laravel-mail-auto-embed": "^1.0",
+ "erjanmx/laravel-migrate-check": "^1.3",
+ "exyplis/eloquent-builder-macros": "^1.5",
"fideloper/proxy": "^4.0",
+ "geo6/geocoder-php-addok-provider": "^1.1",
+ "gzero/eloquent-tree": "^3.1",
+ "hassankhan/config": "^2.1",
+ "intervention/image": "^2.5",
+ "intervention/imagecache": "^2.4",
+ "jasonlewis/expressive-date": "^1.0",
+ "jenssegers/date": "^3.5",
+ "jrean/laravel-user-verification": "^8.0",
+ "kalnoy/nestedset": "^5.0",
+ "laracasts/utilities": "^3.0",
"laravel/framework": "^6.2",
- "laravel/tinker": "^2.0",
- "sebastienheyd/boilerplate": "^7.1"
+ "laravel/scout": "^7.2",
+ "laravel/ui": "^1.0",
+ "laravelcollective/html": "^6.0",
+ "league/climate": "^3.5",
+ "league/period": "^4.9",
+ "maatwebsite/excel": "^3.1",
+ "mad-web/laravel-initializer": "^3.0",
+ "mediactive-digital/migrations-generator": "^2.0",
+ "moneyphp/money": "^3.3",
+ "mpdf/mpdf": "^8.0",
+ "mpociot/teamwork": "^5.3",
+ "mtolhuys/laravel-schematics": "^0.10.1",
+ "nicmart/tree": "^0.2.7",
+ "olssonm/laravel-backup-shield": "^3.1",
+ "orangehill/iseed": "^2.6",
+ "payum/payum": "^1.6",
+ "php-console/php-console": "^3.1",
+ "proengsoft/laravel-jsvalidation": "^3.0",
+ "qoraiche/laravel-mail-editor": "^1.3",
+ "rcrowe/twigbridge": "^0.11.3",
+ "respect/validation": "^1.1",
+ "rinvex/laravel-categories": "^3.0",
+ "rtconner/laravel-tagging": "^4.0",
+ "rutorika/sortable": "^7.0",
+ "santigarcor/laratrust": "^5.2",
+ "sebastienheyd/boilerplate": "^7.0",
+ "sensiolabs/security-checker": "^6.0",
+ "sheub/ban-france-provider": "^1.0@dev",
+ "smajohusic/laravel-mail-logger": "^1.0",
+ "soved/laravel-gdpr": "^1.5",
+ "spatie/laravel-activitylog": "^3.6",
+ "spatie/laravel-backup": "^6.2",
+ "spatie/laravel-medialibrary": "^7.0",
+ "staudenmeir/eloquent-has-many-deep": "^1.8",
+ "stillat/numeral.php": "^2.0",
+ "te7a-houdini/laroute": "^1.0",
+ "themsaid/laravel-mail-preview": "^3.0",
+ "toin0u/geocoder-laravel": "^4.2",
+ "twig/extensions": "^1.5",
+ "unicodeveloper/laravel-password": "^1.0",
+ "voku/stringy": "^6.2",
+ "watson/rememberable": "^3.0",
+ "yadahan/laravel-authentication-log": "^1.2",
+ "yajra/laravel-datatables": "^1.5"
},
"require-dev": {
+ "barryvdh/laravel-debugbar": "^3.2",
+ "beyondcode/laravel-dump-server": "^1.3",
+ "beyondcode/laravel-er-diagram-generator": "^1.4",
+ "daniel-werner/php-quality-tools": "^1.2",
"facade/ignition": "^1.4",
"fzaninotto/faker": "^1.9.1",
+ "laravel/tinker": "^2.2",
"mockery/mockery": "^1.0",
"nunomaduro/collision": "^3.0",
- "phpunit/phpunit": "^8.0"
+ "nunomaduro/larastan": "^0.5.2",
+ "nunomaduro/phpinsights": "^1.13",
+ "phpunit/phpunit": "^8.0",
+ "sayeed/custom-migrate": "^1.0",
+ "theseer/phpdox": "^0.12.0",
+ "wnx/laravel-stats": "^2.0"
},
"config": {
"optimize-autoloader": true,
@@ -49,7 +123,6 @@
"prefer-stable": true,
"scripts": {
"post-autoload-dump": [
- "Illuminate\\Foundation\\ComposerScripts::postAutoloadDump",
"@php artisan package:discover --ansi"
],
"post-root-package-install": [
diff --git a/config/authentication-log.php b/config/authentication-log.php
new file mode 100644
index 00000000..4dc8e926
--- /dev/null
+++ b/config/authentication-log.php
@@ -0,0 +1,28 @@
+ env('AUTHENTICATION_LOG_NOTIFY', true),
+
+ /*
+ |--------------------------------------------------------------------------
+ | Old Logs Clear
+ |--------------------------------------------------------------------------
+ |
+ | When the clean-command is executed, all authentication logs older than
+ | the number of days specified here will be deleted.
+ |
+ */
+
+ 'older' => 365,
+
+];
diff --git a/config/backup-shield.php b/config/backup-shield.php
new file mode 100644
index 00000000..60574e04
--- /dev/null
+++ b/config/backup-shield.php
@@ -0,0 +1,12 @@
+ env('APP_KEY'),
+ 'encryption' => \Olssonm\BackupShield\Encryption::ENCRYPTION_DEFAULT
+
+ // Available encryption methods:
+ // \Olssonm\BackupShield\Encryption::ENCRYPTION_DEFAULT (PHP < 7.2: PKWARE/ZipCrypto, PHP >= 7.2: AES 128)
+ // \Olssonm\BackupShield\Encryption::ENCRYPTION_WINZIP_AES_128 (AES 128)
+ // \Olssonm\BackupShield\Encryption::ENCRYPTION_WINZIP_AES_192 (AES 192)
+ // \Olssonm\BackupShield\Encryption::ENCRYPTION_WINZIP_AES_256 (AES 256)
+ ];
diff --git a/config/backup.php b/config/backup.php
new file mode 100644
index 00000000..bdc9379e
--- /dev/null
+++ b/config/backup.php
@@ -0,0 +1,231 @@
+ [
+
+ /*
+ * The name of this application. You can use this name to monitor
+ * the backups.
+ */
+ 'name' => env('APP_NAME', 'laravel-backup'),
+
+ 'source' => [
+
+ 'files' => [
+
+ /*
+ * The list of directories and files that will be included in the backup.
+ */
+ 'include' => [
+ base_path(),
+ ],
+
+ /*
+ * These directories and files will be excluded from the backup.
+ *
+ * Directories used by the backup process will automatically be excluded.
+ */
+ 'exclude' => [
+ base_path('vendor'),
+ base_path('node_modules'),
+ ],
+
+ /*
+ * Determines if symlinks should be followed.
+ */
+ 'follow_links' => false,
+ ],
+
+ /*
+ * The names of the connections to the databases that should be backed up
+ * MySQL, PostgreSQL, SQLite and Mongo databases are supported.
+ *
+ * The content of the database dump may be customized for each connection
+ * by adding a 'dump' key to the connection settings in config/database.php.
+ * E.g.
+ * 'mysql' => [
+ * ...
+ * 'dump' => [
+ * 'excludeTables' => [
+ * 'table_to_exclude_from_backup',
+ * 'another_table_to_exclude'
+ * ]
+ * ],
+ * ],
+ *
+ * If you are using only InnoDB tables on a MySQL server, you can
+ * also supply the useSingleTransaction option to avoid table locking.
+ *
+ * E.g.
+ * 'mysql' => [
+ * ...
+ * 'dump' => [
+ * 'useSingleTransaction' => true,
+ * ],
+ * ],
+ *
+ * For a complete list of available customization options, see https://github.com/spatie/db-dumper
+ */
+ 'databases' => [
+ 'mysql',
+ ],
+ ],
+
+ /*
+ * The database dump can be compressed to decrease diskspace usage.
+ *
+ * Out of the box Laravel-backup supplies
+ * Spatie\DbDumper\Compressors\GzipCompressor::class.
+ *
+ * You can also create custom compressor. More info on that here:
+ * https://github.com/spatie/db-dumper#using-compression
+ *
+ * If you do not want any compressor at all, set it to null.
+ */
+ 'database_dump_compressor' => null,
+
+ 'destination' => [
+
+ /*
+ * The filename prefix used for the backup zip file.
+ */
+ 'filename_prefix' => '',
+
+ /*
+ * The disk names on which the backups will be stored.
+ */
+ 'disks' => [
+ 'local',
+ ],
+ ],
+
+ /*
+ * The directory where the temporary files will be stored.
+ */
+ 'temporary_directory' => storage_path('app/backup-temp'),
+ ],
+
+ /*
+ * You can get notified when specific events occur. Out of the box you can use 'mail' and 'slack'.
+ * For Slack you need to install guzzlehttp/guzzle and laravel/slack-notification-channel.
+ *
+ * You can also use your own notification classes, just make sure the class is named after one of
+ * the `Spatie\Backup\Events` classes.
+ */
+ 'notifications' => [
+
+ 'notifications' => [
+ \Spatie\Backup\Notifications\Notifications\BackupHasFailed::class => ['mail'],
+ \Spatie\Backup\Notifications\Notifications\UnhealthyBackupWasFound::class => ['mail'],
+ \Spatie\Backup\Notifications\Notifications\CleanupHasFailed::class => ['mail'],
+ \Spatie\Backup\Notifications\Notifications\BackupWasSuccessful::class => ['mail'],
+ \Spatie\Backup\Notifications\Notifications\HealthyBackupWasFound::class => ['mail'],
+ \Spatie\Backup\Notifications\Notifications\CleanupWasSuccessful::class => ['mail'],
+ ],
+
+ /*
+ * Here you can specify the notifiable to which the notifications should be sent. The default
+ * notifiable will use the variables specified in this config file.
+ */
+ 'notifiable' => \Spatie\Backup\Notifications\Notifiable::class,
+
+ 'mail' => [
+ 'to' => 'your@example.com',
+
+ 'from' => [
+ 'address' => env('MAIL_FROM_ADDRESS', 'hello@example.com'),
+ 'name' => env('MAIL_FROM_NAME', 'Example'),
+ ],
+ ],
+
+ 'slack' => [
+ 'webhook_url' => '',
+
+ /*
+ * If this is set to null the default channel of the webhook will be used.
+ */
+ 'channel' => null,
+
+ 'username' => null,
+
+ 'icon' => null,
+
+ ],
+ ],
+
+ /*
+ * Here you can specify which backups should be monitored.
+ * If a backup does not meet the specified requirements the
+ * UnHealthyBackupWasFound event will be fired.
+ */
+ 'monitor_backups' => [
+ [
+ 'name' => env('APP_NAME', 'laravel-backup'),
+ 'disks' => ['local'],
+ 'health_checks' => [
+ \Spatie\Backup\Tasks\Monitor\HealthChecks\MaximumAgeInDays::class => 1,
+ \Spatie\Backup\Tasks\Monitor\HealthChecks\MaximumStorageInMegabytes::class => 5000,
+ ],
+ ],
+
+ /*
+ [
+ 'name' => 'name of the second app',
+ 'disks' => ['local', 's3'],
+ 'health_checks' => [
+ \Spatie\Backup\Tasks\Monitor\HealthChecks\MaximumAgeInDays::class => 1,
+ \Spatie\Backup\Tasks\Monitor\HealthChecks\MaximumStorageInMegabytes::class => 5000,
+ ],
+ ],
+ */
+ ],
+
+ 'cleanup' => [
+ /*
+ * The strategy that will be used to cleanup old backups. The default strategy
+ * will keep all backups for a certain amount of days. After that period only
+ * a daily backup will be kept. After that period only weekly backups will
+ * be kept and so on.
+ *
+ * No matter how you configure it the default strategy will never
+ * delete the newest backup.
+ */
+ 'strategy' => \Spatie\Backup\Tasks\Cleanup\Strategies\DefaultStrategy::class,
+
+ 'default_strategy' => [
+
+ /*
+ * The number of days for which backups must be kept.
+ */
+ 'keep_all_backups_for_days' => 7,
+
+ /*
+ * The number of days for which daily backups must be kept.
+ */
+ 'keep_daily_backups_for_days' => 16,
+
+ /*
+ * The number of weeks for which one weekly backup must be kept.
+ */
+ 'keep_weekly_backups_for_weeks' => 8,
+
+ /*
+ * The number of months for which one monthly backup must be kept.
+ */
+ 'keep_monthly_backups_for_months' => 4,
+
+ /*
+ * The number of years for which one yearly backup must be kept.
+ */
+ 'keep_yearly_backups_for_years' => 2,
+
+ /*
+ * After cleaning up the backups remove the oldest backup until
+ * this amount of megabytes has been reached.
+ */
+ 'delete_oldest_backups_when_using_more_megabytes_than' => 5000,
+ ],
+ ],
+
+];
diff --git a/config/boilerplate/app.php b/config/boilerplate/app.php
index 4c6ed021..759b1e14 100644
--- a/config/boilerplate/app.php
+++ b/config/boilerplate/app.php
@@ -8,7 +8,7 @@ return [
'domain' => '',
// Redirect to this route after login
- 'redirectTo' => 'boilerplate.dashboard',
+ 'redirectTo' => 'Shop.Admin.dashboard',
// Backend locale
'locale' => config('app.locale'),
diff --git a/config/boilerplate/menu.php b/config/boilerplate/menu.php
index 76b54dc1..75b4f332 100644
--- a/config/boilerplate/menu.php
+++ b/config/boilerplate/menu.php
@@ -1,6 +1,6 @@
\Sebastienheyd\Boilerplate\Controllers\DashboardController::class, // Dashboard controller to use
+ 'dashboard' => \App\Http\Controllers\Shop\Admin\DashboardController::class, // Dashboard controller to use
'providers' => [], // Additional menu items providers
];
diff --git a/config/boilerplate/themes/default.php b/config/boilerplate/themes/default.php
index 281d7132..51a6e93b 100644
--- a/config/boilerplate/themes/default.php
+++ b/config/boilerplate/themes/default.php
@@ -21,15 +21,15 @@ return [
'border' => false,
'compact' => false,
'links' => [
- 'bg' => 'blue',
+ 'bg' => 'green',
'shadow' => 1,
],
'brand' => [
'bg' => 'gray-dark',
'logo' => [
- 'bg' => 'blue',
+ 'bg' => 'green',
'icon' => '',
- 'text' => 'BOilerplate',
+ 'text' => 'OpenSem',
'shadow' => 2,
],
],
@@ -40,7 +40,7 @@ return [
],
'footer' => [
'visible' => true,
- 'vendorname' => 'Boilerplate',
+ 'vendorname' => 'OpenSem',
'vendorlink' => '',
],
'card' => [
diff --git a/config/charts.php b/config/charts.php
new file mode 100644
index 00000000..b1a19c4e
--- /dev/null
+++ b/config/charts.php
@@ -0,0 +1,15 @@
+ 'Chartjs',
+];
diff --git a/config/datatables-buttons.php b/config/datatables-buttons.php
new file mode 100644
index 00000000..54bd7871
--- /dev/null
+++ b/config/datatables-buttons.php
@@ -0,0 +1,90 @@
+ [
+ /*
+ * Base namespace/directory to create the new file.
+ * This is appended on default Laravel namespace.
+ * Usage: php artisan datatables:make User
+ * Output: App\DataTables\UserDataTable
+ * With Model: App\User (default model)
+ * Export filename: users_timestamp
+ */
+ 'base' => 'DataTables',
+
+ /*
+ * Base namespace/directory where your model's are located.
+ * This is appended on default Laravel namespace.
+ * Usage: php artisan datatables:make Post --model
+ * Output: App\DataTables\PostDataTable
+ * With Model: App\Post
+ * Export filename: posts_timestamp
+ */
+ 'model' => '',
+ ],
+
+ /*
+ * Set Custom stub folder
+ */
+ //'stub' => '/resources/custom_stub',
+
+ /*
+ * PDF generator to be used when converting the table to pdf.
+ * Available generators: excel, snappy
+ * Snappy package: barryvdh/laravel-snappy
+ * Excel package: maatwebsite/excel
+ */
+ 'pdf_generator' => 'snappy',
+
+ /*
+ * Snappy PDF options.
+ */
+ 'snappy' => [
+ 'options' => [
+ 'no-outline' => true,
+ 'margin-left' => '0',
+ 'margin-right' => '0',
+ 'margin-top' => '10mm',
+ 'margin-bottom' => '10mm',
+ ],
+ 'orientation' => 'landscape',
+ ],
+
+ /*
+ * Default html builder parameters.
+ */
+ 'parameters' => [
+ 'dom' => 'Bfrtip',
+ 'order' => [[0, 'desc']],
+ 'buttons' => [
+ 'create',
+ 'export',
+ 'print',
+ 'reset',
+ 'reload',
+ ],
+ ],
+
+ /*
+ * Generator command default options value.
+ */
+ 'generator' => [
+ /*
+ * Default columns to generate when not set.
+ */
+ 'columns' => 'id,add your columns,created_at,updated_at',
+
+ /*
+ * Default buttons to generate when not set.
+ */
+ 'buttons' => 'create,export,print,reset,reload',
+
+ /*
+ * Default DOM to generate when not set.
+ */
+ 'dom' => 'Bfrtip',
+ ],
+];
diff --git a/config/datatables-fractal.php b/config/datatables-fractal.php
new file mode 100644
index 00000000..25f547a8
--- /dev/null
+++ b/config/datatables-fractal.php
@@ -0,0 +1,13 @@
+ 'include',
+
+ /*
+ * Default fractal serializer.
+ */
+ 'serializer' => League\Fractal\Serializer\DataArraySerializer::class,
+];
diff --git a/config/datatables-html.php b/config/datatables-html.php
new file mode 100644
index 00000000..2b0995fd
--- /dev/null
+++ b/config/datatables-html.php
@@ -0,0 +1,27 @@
+ [
+ 'class' => 'table',
+ 'id' => 'dataTableBuilder',
+ ],
+
+ /*
+ * Default condition to determine if a parameter is a callback or not.
+ * Callbacks needs to start by those terms or they will be casted to string.
+ */
+ 'callback' => ['$', '$.', 'function'],
+
+ /*
+ * Html builder script template.
+ */
+ 'script' => 'datatables::script',
+
+ /*
+ * Html builder script template for DataTables Editor integration.
+ */
+ 'editor' => 'datatables::editor',
+];
diff --git a/config/debug-server.php b/config/debug-server.php
new file mode 100644
index 00000000..f897262f
--- /dev/null
+++ b/config/debug-server.php
@@ -0,0 +1,8 @@
+ 'tcp://127.0.0.1:9912',
+];
diff --git a/config/debugbar.php b/config/debugbar.php
new file mode 100644
index 00000000..3275f105
--- /dev/null
+++ b/config/debugbar.php
@@ -0,0 +1,202 @@
+ env('DEBUGBAR_ENABLED', null),
+ 'except' => [
+ 'telescope*'
+ ],
+
+ /*
+ |--------------------------------------------------------------------------
+ | Storage settings
+ |--------------------------------------------------------------------------
+ |
+ | DebugBar stores data for session/ajax requests.
+ | You can disable this, so the debugbar stores data in headers/session,
+ | but this can cause problems with large data collectors.
+ | By default, file storage (in the storage folder) is used. Redis and PDO
+ | can also be used. For PDO, run the package migrations first.
+ |
+ */
+ 'storage' => [
+ 'enabled' => true,
+ 'driver' => 'file', // redis, file, pdo, custom
+ 'path' => storage_path('debugbar'), // For file driver
+ 'connection' => null, // Leave null for default connection (Redis/PDO)
+ 'provider' => '' // Instance of StorageInterface for custom driver
+ ],
+
+ /*
+ |--------------------------------------------------------------------------
+ | Vendors
+ |--------------------------------------------------------------------------
+ |
+ | Vendor files are included by default, but can be set to false.
+ | This can also be set to 'js' or 'css', to only include javascript or css vendor files.
+ | Vendor files are for css: font-awesome (including fonts) and highlight.js (css files)
+ | and for js: jquery and and highlight.js
+ | So if you want syntax highlighting, set it to true.
+ | jQuery is set to not conflict with existing jQuery scripts.
+ |
+ */
+
+ 'include_vendors' => true,
+
+ /*
+ |--------------------------------------------------------------------------
+ | Capture Ajax Requests
+ |--------------------------------------------------------------------------
+ |
+ | The Debugbar can capture Ajax requests and display them. If you don't want this (ie. because of errors),
+ | you can use this option to disable sending the data through the headers.
+ |
+ | Optionally, you can also send ServerTiming headers on ajax requests for the Chrome DevTools.
+ */
+
+ 'capture_ajax' => true,
+ 'add_ajax_timing' => false,
+
+ /*
+ |--------------------------------------------------------------------------
+ | Custom Error Handler for Deprecated warnings
+ |--------------------------------------------------------------------------
+ |
+ | When enabled, the Debugbar shows deprecated warnings for Symfony components
+ | in the Messages tab.
+ |
+ */
+ 'error_handler' => false,
+
+ /*
+ |--------------------------------------------------------------------------
+ | Clockwork integration
+ |--------------------------------------------------------------------------
+ |
+ | The Debugbar can emulate the Clockwork headers, so you can use the Chrome
+ | Extension, without the server-side code. It uses Debugbar collectors instead.
+ |
+ */
+ 'clockwork' => false,
+
+ /*
+ |--------------------------------------------------------------------------
+ | DataCollectors
+ |--------------------------------------------------------------------------
+ |
+ | Enable/disable DataCollectors
+ |
+ */
+
+ 'collectors' => [
+ 'phpinfo' => true, // Php version
+ 'messages' => true, // Messages
+ 'time' => true, // Time Datalogger
+ 'memory' => true, // Memory usage
+ 'exceptions' => true, // Exception displayer
+ 'log' => true, // Logs from Monolog (merged in messages if enabled)
+ 'db' => true, // Show database (PDO) queries and bindings
+ 'views' => true, // Views with their data
+ 'route' => true, // Current route information
+ 'auth' => false, // Display Laravel authentication status
+ 'gate' => true, // Display Laravel Gate checks
+ 'session' => true, // Display session data
+ 'symfony_request' => true, // Only one can be enabled..
+ 'mail' => true, // Catch mail messages
+ 'laravel' => false, // Laravel version and environment
+ 'events' => false, // All events fired
+ 'default_request' => false, // Regular or special Symfony request logger
+ 'logs' => false, // Add the latest log messages
+ 'files' => false, // Show the included files
+ 'config' => false, // Display config settings
+ 'cache' => false, // Display cache events
+ 'models' => false, // Display models
+ ],
+
+ /*
+ |--------------------------------------------------------------------------
+ | Extra options
+ |--------------------------------------------------------------------------
+ |
+ | Configure some DataCollectors
+ |
+ */
+
+ 'options' => [
+ 'auth' => [
+ 'show_name' => true, // Also show the users name/email in the debugbar
+ ],
+ 'db' => [
+ 'with_params' => true, // Render SQL with the parameters substituted
+ 'backtrace' => true, // Use a backtrace to find the origin of the query in your files.
+ 'timeline' => false, // Add the queries to the timeline
+ 'explain' => [ // Show EXPLAIN output on queries
+ 'enabled' => false,
+ 'types' => ['SELECT'], // // workaround ['SELECT'] only. https://github.com/barryvdh/laravel-debugbar/issues/888 ['SELECT', 'INSERT', 'UPDATE', 'DELETE']; for MySQL 5.6.3+
+ ],
+ 'hints' => true, // Show hints for common mistakes
+ ],
+ 'mail' => [
+ 'full_log' => false
+ ],
+ 'views' => [
+ 'data' => false, //Note: Can slow down the application, because the data can be quite large..
+ ],
+ 'route' => [
+ 'label' => true // show complete route on bar
+ ],
+ 'logs' => [
+ 'file' => null
+ ],
+ 'cache' => [
+ 'values' => true // collect cache values
+ ],
+ ],
+
+ /*
+ |--------------------------------------------------------------------------
+ | Inject Debugbar in Response
+ |--------------------------------------------------------------------------
+ |
+ | Usually, the debugbar is added just before