In order for the following installation guide to work, you'll need to have a working Laravel 8 application and a database created and configured in your
.env
file.
Require the package inside your Laravel project
composer require varbox/varbox
Install the Varbox platform by running one simple command:
php artisan varbox:install
Migrate your database with the newly created Varbox migration file:
php artisan migrate
Seed your database with Varbox specific data.
For an overview of what data is seeded, take a look inside database/seeds/VarboxSeeder.php
php artisan db:seed --class="VarboxSeeder"
Now you can sign into your admin panel by accessing /admin
.
Use [email protected] / admin
to authenticate.
If for some reason you don't want to automatically install the Varbox platform, you can do so manually, by following the steps below.
The following steps also provide useful insight on what the
varbox:install
command does.
Require the package inside your Laravel project
composer require varbox/varbox
Run the following artisan commands to publish all platform specific files:
php artisan vendor:publish --tag=varbox-config
php artisan vendor:publish --tag=varbox-migrations
php artisan vendor:publish --tag=varbox-views
php artisan vendor:publish --tag=varbox-public
Append the following to your .env
file:
CACHE_ALL_QUERIES=false
CACHE_DUPLICATE_QUERIES=false
LOG_ACTIVITY=false
SAVE_ERRORS=false
In your routes/web.php
file, at the very bottom, add the following:
// this should be the last line
Route::varbox();
In your config/auth.php
config file add the following to the guards
section:
'guards' => [
...
'admin' => [
'driver' => 'session',
'provider' => 'users',
],
],
In your config/filesystems.php
config file add the following to the disks
section:
'disks' => [
...
'uploads' => [
'driver' => 'local',
'root' => storage_path('uploads'),
'url' => env('APP_URL').'/uploads',
'visibility' => 'public',
],
'wysiwyg' => [
'driver' => 'local',
'root' => storage_path('wysiwyg'),
'url' => env('APP_URL').'/wysiwyg',
'visibility' => 'public',
],
'backups' => [
'driver' => 'local',
'root' => storage_path('backups'),
],
],
In your app/Models/User.php
file change the extended class to reference:
use Varbox\Models\User as VarboxUser;
class User extends VarboxUser {
...
}
In your app/Models/User.php
file append the following to the $fillable
property:
protected $fillable = [
...
'active',
];
In your app/Models/User.php
file append the following to the $casts
property:
protected $casts = [
...
'active' => 'boolean'
];
In your app/Exceptions/Handler.php
file change the extended class to reference:
use Varbox\Exceptions\Handler as VarboxExceptionHandler;
class Handler extends VarboxExceptionHandler {
...
}
Copy all sql files from inside the varbox/database/sql
directory into your database/sql
directory.
cp varbox/database/sql/countries.sql database/sql/countries.sql
cp varbox/database/sql/states.sql database/sql/states.sql
cp varbox/database/sql/cities.sql database/sql/cities.sql
Copy all seeder classes from inside the varbox/database/seeds
directory into your own database/seeds
directory.
Also, don't forget to change the files' extensions from stub
to php
.
cp varbox/database/seeds/VarboxSeeder.stub database/seeds/VarboxSeeder.php
cp varbox/database/seeds/PermissionsSeeder.stub database/seeds/PermissionsSeeder.php
cp varbox/database/seeds/RolesSeeder.stub database/seeds/RolesSeeder.php
cp varbox/database/seeds/UsersSeeder.stub database/seeds/UsersSeeder.php
cp varbox/database/seeds/LanguagesSeeder.stub database/seeds/LanguagesSeeder.php
cp varbox/database/seeds/CountriesSeeder.stub database/seeds/CountriesSeeder.php
cp varbox/database/seeds/StatesSeeder.stub database/seeds/StatesSeeder.php
cp varbox/database/seeds/CitiesSeeder.stub database/seeds/CitiesSeeder.php
Create the necessary database tables for the Varbox platform to work properly.
php artisan migrate
Populate the database with necessary data for the Varbox platform to work properly.
composer dump-autoload
php artisan db:seed --class="VarboxSeeder"
Run the following artisan
commands:
php artisan varbox:uploads-link
php artisan varbox:wysiwyg-link
In your storage
directory create a new folder called uploads
.
mkdir storage/uploads
In your storage/uploads
directory create a new file called .gitignore
containing the following:
!.gitignore
In your storage
directory create a new folder called backups
.
mkdir storage/backups
In your storage/backups
directory create a new file called .gitignore
containing the following:
!.gitignore
In your storage
directory create a new folder called wysiwyg
.
mkdir storage/wysiwyg
In your storage/wysiwyg
directory create a new file called .gitignore
containing the following:
!.gitignore
In your app/Http/Controllers
directory create a new file called PagesController.php
containing:
<?php
namespace App\Http\Composers;
use Illuminate\Http\Request;
use Varbox\Contracts\PageModelContract;
class PagesController extends Controller
{
/**
* @var PageModelContract
*/
protected $page;
/**
* @param Request $request
* @set Page $page
*/
public function __construct(Request $request)
{
$this->page = $request->route()->action['model'] ?? null;
if (!($this->page && $this->page->exists) || $this->page->isDrafted()) {
abort(404);
}
}
/**
* @return \Illuminate\View\View
*/
public function show()
{
return view('pages.show')->with([
'page' => $this->page
]);
}
}
In your app/Http/Composers
directory create a new file called AdminMenuComposer.php
containing:
<?php
namespace App\Http\Composers;
use Illuminate\Contracts\Auth\Authenticatable;
use Illuminate\Support\Collection;
use Illuminate\View\View;
use Varbox\Helpers\AdminMenuHelper;
use Varbox\Menu\MenuItem;
class AdminMenuComposer
{
/**
* @var Authenticatable
*/
protected $user;
/**
* @var Collection
*/
protected $permissions;
/**
* @param Authenticatable $user
*/
public function __construct(Authenticatable $user)
{
$this->user = $user;
}
/**
* Construct the admin menu.
*
* @param View $view
*/
public function compose(View $view)
{
$menu = menu_admin()->make(function (AdminMenuHelper $menu) {
$menu->add(function (MenuItem $item) {
$item->name('Home')->url(route('admin'))->data('icon', 'fa-home')->active('admin');
});
$menu->add(function ($item) use ($menu) {
$auth = $item->name('Access Control')->data('icon', 'fa-sign-in-alt')
->permissions('users-list', 'admins-list', 'roles-list', 'permissions-list', 'activity-list', 'notifications-list')
->active('admin/users/*', 'admin/admins/*', 'admin/roles/*', 'admin/permissions/*', 'admin/activity/*', 'admin/notifications/*');
$menu->child($auth, function (MenuItem $item) {
$item->name('Users')->url(route('admin.users.index'))->permissions('users-list')->active('admin/users/*');
});
$menu->child($auth, function (MenuItem $item) {
$item->name('Admins')->url(route('admin.admins.index'))->permissions('admins-list')->active('admin/admins/*');
});
$menu->child($auth, function (MenuItem $item) {
$item->name('Roles')->url(route('admin.roles.index'))->permissions('roles-list')->active('admin/roles/*');
});
$menu->child($auth, function (MenuItem $item) {
$item->name('Permissions')->url(route('admin.permissions.index'))->permissions('permissions-list')->active('admin/permissions/*');
});
$menu->child($auth, function (MenuItem $item) {
$item->name('Activity')->url(route('admin.activity.index'))->permissions('activity-list')->active('admin/activity/*');
});
$menu->child($auth, function (MenuItem $item) {
$item->name('Notifications')->url(route('admin.notifications.index'))->permissions('notifications-list')->active('admin/notifications/*');
});
});
$menu->add(function ($item) use ($menu) {
$cms = $item->name('Manage Content')->data('icon', 'fa-edit')
->permissions('pages-list', 'menus-list', 'blocks-list', 'emails-list', 'layouts-list')
->active('admin/pages/*', 'admin/menus/*', 'admin/blocks/*', 'admin/emails/*', 'admin/layouts/*');
$menu->child($cms, function (MenuItem $item) {
$item->name('Pages')->url(route('admin.pages.index'))->permissions('pages-list')->active('admin/pages/*');
});
$menu->child($cms, function (MenuItem $item) {
$item->name('Menus')->url(route('admin.menus.locations'))->permissions('menus-list')->active('admin/menus/*');
});
$menu->child($cms, function (MenuItem $item) {
$item->name('Blocks')->url(route('admin.blocks.index'))->permissions('blocks-list')->active('admin/blocks/*');
});
$menu->child($cms, function (MenuItem $item) {
$item->name('Emails')->url(route('admin.emails.index'))->permissions('emails-list', 'aa')->active('admin/emails/*');
});
});
$menu->add(function ($item) use ($menu) {
$media = $item->name('Media Library')->data('icon', 'fa-copy')
->permissions('uploads-list')
->active('admin/uploads/*');
$menu->child($media, function (MenuItem $item) {
$item->name('Uploads')->url(route('admin.uploads.index'))->permissions('uploads-list')->active('admin/uploads/*');
});
});
$menu->add(function ($item) use ($menu) {
$trans = $item->name('Multi Language')->data('icon', 'fa-globe-americas')
->permissions('translations-list', 'languages-list')
->active('admin/translations/*', 'admin/languages/*');
$menu->child($trans, function (MenuItem $item) {
$item->name('Translations')->url(route('admin.translations.index'))->permissions('translations-list')->active('admin/translations/*');
});
$menu->child($trans, function (MenuItem $item) {
$item->name('Languages')->url(route('admin.languages.index'))->permissions('languages-list')->active('admin/languages/*');
});
});
$menu->add(function ($item) use ($menu) {
$geo = $item->name('Geo Location')->data('icon', 'fa-map-marker-alt')
->permissions('countries-list', 'states-list', 'cities-list')
->active('admin/countries/*', 'admin/states/*', 'admin/cities/*');
$menu->child($geo, function (MenuItem $item) {
$item->name('Countries')->url(route('admin.countries.index'))->permissions('countries-list')->active('admin/countries/*');
});
$menu->child($geo, function (MenuItem $item) {
$item->name('States')->url(route('admin.states.index'))->permissions('states-list')->active('admin/states/*');
});
$menu->child($geo, function (MenuItem $item) {
$item->name('Cities')->url(route('admin.cities.index'))->permissions('cities-list')->active('admin/cities/*');
});
});
$menu->add(function ($item) use ($menu) {
$sys = $item->name('System Settings')->data('icon', 'fa-cog')
->permissions('configs-list', 'redirects-list', 'errors-list', 'backups-list')
->active('admin/config/*', 'admin/redirects/*', 'admin/errors/*', 'admin/backups/*');
$menu->child($sys, function (MenuItem $item) {
$item->name('Configs')->url(route('admin.configs.index'))->permissions('configs-list')->active('admin/configs/*');
});
$menu->child($sys, function (MenuItem $item) {
$item->name('Redirects')->url(route('admin.redirects.index'))->permissions('redirects-list')->active('admin/redirects/*');
});
$menu->child($sys, function (MenuItem $item) {
$item->name('Errors')->url(route('admin.errors.index'))->permissions('errors-list')->active('admin/errors/*');
});
$menu->child($sys, function (MenuItem $item) {
$item->name('Backups')->url(route('admin.backups.index'))->permissions('backups-list')->active('admin/backups/*');
});
});
})->filter(function (MenuItem $item) {
return $this->user->isSuper() || $this->userHasAnyMenuPermission($item->permissions());
});
$view->with('menu', $menu);
}
/**
* Determine if the user has any of the given permissions.
*
* @param array $permissions
* @return bool
*/
protected function userHasAnyMenuPermission(array $permissions = [])
{
if (empty($permissions)) {
return true;
}
if (!$this->permissions) {
$this->permissions = $this->user->getPermissions()->pluck('name');
}
foreach ($permissions as $permission) {
if ($this->permissions->contains($permission)) {
return true;
}
}
return false;
}
}
Inside your config/varbox/bindings.php
file, change the user_model
value to \App\Models\User::class
/*
| --------------------------------------------------------------------------------------------------------------
| Model Class Bindings
| --------------------------------------------------------------------------------------------------------------
*/
'models' => [
...
/*
|
| Concrete implementation for the "user model".
| To extend or replace this functionality, change the value below with your full "user model" FQN.
|
| Your class will have to (first option is recommended):
| - extend the "Varbox\Models\User" class
| - or at least implement the "Varbox\Contracts\UserModelContract" interface.
|
| Regardless of the concrete implementation below, you can still use it like:
| - app('user.model') OR app('\Varbox\Contracts\UserModelContract')
| - or you could even use your own class as a direct implementation
|
*/
'user_model' => \App\Models\User::class,
Inside your config/varbox/bindings.php
file, change the admin_menu_view_composer
value to \App\Http\Composers\AdminMenuComposer::class
/*
| --------------------------------------------------------------------------------------------------------------
| View Composers Class Bindings
| --------------------------------------------------------------------------------------------------------------
*/
'view_composers' => [
...
/*
|
| Concrete implementation for the "admin menu view composer".
| To extend or replace this functionality, change the value below with your full "admin menu view composer" FQN.
|
| Your class will have to (first option is recommended):
| - extend the "Varbox\Composers\AdminMenuComposer" class
| - or at least implement the following methods: compose()
|
*/
'admin_menu_view_composer' => \App\Http\Composers\AdminMenuComposer::class,