feat: VivesPOS landing on Winter CMS 1.2 — theme + plugin + Dockerfile
Some checks are pending
Module sub-split / Sub-split (push) Waiting to run
Some checks are pending
Module sub-split / Sub-split (push) Waiting to run
- Base: wintercms/winter branch 1.2 (full framework) - Theme vivespos: Canvas 7 + Bootstrap 5 CDN, custom CSS - Layout: deferred GTM/GA4 tracking, JSON-LD SoftwareApplication - Partials: hero (offline-first), features, modes (offline/nube toggle), screenshots, pricing (3 planes), comparison, FAQ, CTA - Plugin VivesPOS.Site with ContactForm - Dockerfile: PHP 8.2 Apache, port 80, healthcheck - Added winter/wn-pages, blog, sitemap, seo plugins - Active theme set to vivespos
This commit is contained in:
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
use Winter\Storm\Database\Schema\Blueprint;
|
||||
use Winter\Storm\Database\Updates\Migration;
|
||||
|
||||
class DbBackendUsers extends Migration
|
||||
{
|
||||
public function up()
|
||||
{
|
||||
Schema::create('backend_users', function (Blueprint $table) {
|
||||
$table->engine = 'InnoDB';
|
||||
$table->increments('id');
|
||||
$table->string('first_name')->nullable();
|
||||
$table->string('last_name')->nullable();
|
||||
$table->string('login')->unique('login_unique')->index('login_index');
|
||||
$table->string('email')->unique('email_unique');
|
||||
$table->string('password');
|
||||
$table->string('activation_code')->nullable()->index('act_code_index');
|
||||
$table->string('persist_code')->nullable();
|
||||
$table->string('reset_password_code')->nullable()->index('reset_code_index');
|
||||
$table->text('permissions')->nullable();
|
||||
$table->boolean('is_activated')->default(0);
|
||||
$table->integer('role_id')->unsigned()->nullable()->index('admin_role_index');
|
||||
$table->timestamp('activated_at')->nullable();
|
||||
$table->timestamp('last_login')->nullable();
|
||||
$table->timestamps();
|
||||
$table->timestamp('deleted_at')->nullable();
|
||||
});
|
||||
}
|
||||
|
||||
public function down()
|
||||
{
|
||||
Schema::dropIfExists('backend_users');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
use Winter\Storm\Database\Schema\Blueprint;
|
||||
use Winter\Storm\Database\Updates\Migration;
|
||||
|
||||
class DbBackendUserGroups extends Migration
|
||||
{
|
||||
public function up()
|
||||
{
|
||||
Schema::create('backend_user_groups', function (Blueprint $table) {
|
||||
$table->engine = 'InnoDB';
|
||||
$table->increments('id');
|
||||
$table->string('name')->unique('name_unique');
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
public function down()
|
||||
{
|
||||
Schema::dropIfExists('backend_user_groups');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
use Winter\Storm\Database\Schema\Blueprint;
|
||||
use Winter\Storm\Database\Updates\Migration;
|
||||
|
||||
class DbBackendUsersGroups extends Migration
|
||||
{
|
||||
public function up()
|
||||
{
|
||||
Schema::create('backend_users_groups', function (Blueprint $table) {
|
||||
$table->engine = 'InnoDB';
|
||||
$table->integer('user_id')->unsigned();
|
||||
$table->integer('user_group_id')->unsigned();
|
||||
$table->primary(['user_id', 'user_group_id'], 'user_group');
|
||||
});
|
||||
}
|
||||
|
||||
public function down()
|
||||
{
|
||||
Schema::dropIfExists('backend_users_groups');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
use Winter\Storm\Database\Schema\Blueprint;
|
||||
use Winter\Storm\Database\Updates\Migration;
|
||||
|
||||
class DbBackendUserThrottle extends Migration
|
||||
{
|
||||
public function up()
|
||||
{
|
||||
Schema::create('backend_user_throttle', function (Blueprint $table) {
|
||||
$table->engine = 'InnoDB';
|
||||
$table->increments('id');
|
||||
$table->integer('user_id')->unsigned()->nullable()->index();
|
||||
$table->string('ip_address')->nullable()->index();
|
||||
$table->integer('attempts')->default(0);
|
||||
$table->timestamp('last_attempt_at')->nullable();
|
||||
$table->boolean('is_suspended')->default(0);
|
||||
$table->timestamp('suspended_at')->nullable();
|
||||
$table->boolean('is_banned')->default(0);
|
||||
$table->timestamp('banned_at')->nullable();
|
||||
});
|
||||
}
|
||||
|
||||
public function down()
|
||||
{
|
||||
Schema::dropIfExists('backend_user_throttle');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
use Winter\Storm\Database\Schema\Blueprint;
|
||||
use Winter\Storm\Database\Updates\Migration;
|
||||
|
||||
class DbBackendUserPreferences extends Migration
|
||||
{
|
||||
public function up()
|
||||
{
|
||||
Schema::create('backend_user_preferences', function (Blueprint $table) {
|
||||
$table->engine = 'InnoDB';
|
||||
$table->increments('id');
|
||||
$table->integer('user_id')->unsigned();
|
||||
$table->string('namespace', 100);
|
||||
$table->string('group', 50);
|
||||
$table->string('item', 150);
|
||||
$table->text('value')->nullable();
|
||||
$table->index(['user_id', 'namespace', 'group', 'item'], 'user_item_index');
|
||||
});
|
||||
}
|
||||
|
||||
public function down()
|
||||
{
|
||||
Schema::dropIfExists('backend_user_preferences');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
use Winter\Storm\Database\Schema\Blueprint;
|
||||
use Winter\Storm\Database\Updates\Migration;
|
||||
|
||||
class DbBackendAccessLog extends Migration
|
||||
{
|
||||
public function up()
|
||||
{
|
||||
Schema::create('backend_access_log', function (Blueprint $table) {
|
||||
$table->engine = 'InnoDB';
|
||||
$table->increments('id');
|
||||
$table->integer('user_id')->unsigned();
|
||||
$table->string('ip_address')->nullable();
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
public function down()
|
||||
{
|
||||
Schema::dropIfExists('backend_access_log');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
use Winter\Storm\Database\Schema\Blueprint;
|
||||
use Winter\Storm\Database\Updates\Migration;
|
||||
|
||||
class DbBackendAddDescriptionField extends Migration
|
||||
{
|
||||
public function up()
|
||||
{
|
||||
Schema::table('backend_user_groups', function (Blueprint $table) {
|
||||
$table->string('code')->nullable()->index('code_index');
|
||||
$table->text('description')->nullable();
|
||||
$table->boolean('is_new_user_default')->default(false);
|
||||
});
|
||||
}
|
||||
|
||||
public function down()
|
||||
{
|
||||
// Schema::table('backend_user_groups', function (Blueprint $table) {
|
||||
// $table->dropColumn('code');
|
||||
// $table->dropColumn('description');
|
||||
// $table->dropColumn('is_new_user_default');
|
||||
// });
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
use Winter\Storm\Database\Schema\Blueprint;
|
||||
use Winter\Storm\Database\Updates\Migration;
|
||||
use Backend\Models\User as AdminModel;
|
||||
|
||||
class DbBackendAddSuperuserFlag extends Migration
|
||||
{
|
||||
public function up()
|
||||
{
|
||||
Schema::table('backend_users', function (Blueprint $table) {
|
||||
$table->boolean('is_superuser')->default(false);
|
||||
});
|
||||
|
||||
AdminModel::all()->each(function ($user) {
|
||||
if ($user->hasPermission('superuser')) {
|
||||
$user->is_superuser = true;
|
||||
$user->save();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public function down()
|
||||
{
|
||||
// Schema::table('backend_users', function (Blueprint $table) {
|
||||
// $table->dropColumn('is_superuser');
|
||||
// });
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
use Winter\Storm\Database\Updates\Migration;
|
||||
|
||||
/**
|
||||
* This migration addresses a MySQL specific issue around STRICT MODE.
|
||||
* In past versions, Laravel would give timestamps a bad default value
|
||||
* of "0" considered invalid by MySQL. Strict mode is disabled and the
|
||||
* the timestamps are patched up. Credit for this work: Dave Shoreman.
|
||||
*/
|
||||
class DbBackendTimestampFix extends Migration
|
||||
{
|
||||
protected $backendTables = [
|
||||
'backend_users',
|
||||
'backend_user_groups',
|
||||
'backend_access_log',
|
||||
];
|
||||
|
||||
public function up()
|
||||
{
|
||||
DbDongle::disableStrictMode();
|
||||
|
||||
foreach ($this->backendTables as $table) {
|
||||
DbDongle::convertTimestamps($table);
|
||||
}
|
||||
|
||||
// Use this opportunity to reset backend preferences for stable
|
||||
Db::table('backend_user_preferences')
|
||||
->where('namespace', 'backend')
|
||||
->where('group', 'backend')
|
||||
->where('item', 'preferences')
|
||||
->delete();
|
||||
}
|
||||
|
||||
public function down()
|
||||
{
|
||||
// ...
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,165 @@
|
||||
<?php
|
||||
|
||||
use Backend\Models\UserRole;
|
||||
use Winter\Storm\Database\Schema\Blueprint;
|
||||
use Winter\Storm\Database\Updates\Migration;
|
||||
|
||||
class DbBackendUserRoles extends Migration
|
||||
{
|
||||
public function up()
|
||||
{
|
||||
Schema::create('backend_user_roles', function (Blueprint $table) {
|
||||
$table->engine = 'InnoDB';
|
||||
$table->increments('id');
|
||||
$table->string('name')->unique('role_unique');
|
||||
$table->string('code')->nullable()->index('role_code_index');
|
||||
$table->text('description')->nullable();
|
||||
$table->text('permissions')->nullable();
|
||||
$table->boolean('is_system')->default(0);
|
||||
$table->timestamps();
|
||||
});
|
||||
|
||||
// This detects older builds and performs a migration to include
|
||||
// the new role system. This column will exist for new installs
|
||||
// so this heavy migration process does not need to execute.
|
||||
$this->migratePreviousBuild();
|
||||
}
|
||||
|
||||
public function down()
|
||||
{
|
||||
Schema::dropIfExists('backend_user_roles');
|
||||
}
|
||||
|
||||
protected function migratePreviousBuild()
|
||||
{
|
||||
// Role not found in the users table, perform a complete migration.
|
||||
// Merging group permissions with the user and assigning the user
|
||||
// with the first available role.
|
||||
if (!Schema::hasColumn('backend_users', 'role_id')) {
|
||||
Schema::table('backend_users', function (Blueprint $table) {
|
||||
$table->integer('role_id')->unsigned()->nullable()->index('admin_role_index');
|
||||
});
|
||||
|
||||
$this->createSystemUserRoles();
|
||||
$this->migratePermissionsFromGroupsToRoles();
|
||||
}
|
||||
|
||||
// Drop permissions column on groups table as it is no longer needed.
|
||||
if (Schema::hasColumn('backend_user_groups', 'permissions')) {
|
||||
Schema::table('backend_user_groups', function (Blueprint $table) {
|
||||
$table->dropColumn('permissions');
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
protected function createSystemUserRoles()
|
||||
{
|
||||
Db::table('backend_user_roles')->insert([
|
||||
'name' => 'Publisher',
|
||||
'code' => UserRole::CODE_PUBLISHER,
|
||||
'description' => 'Site editor with access to publishing tools.',
|
||||
]);
|
||||
|
||||
Db::table('backend_user_roles')->insert([
|
||||
'name' => 'Developer',
|
||||
'code' => UserRole::CODE_DEVELOPER,
|
||||
'description' => 'Site administrator with access to developer tools.',
|
||||
]);
|
||||
}
|
||||
|
||||
protected function migratePermissionsFromGroupsToRoles()
|
||||
{
|
||||
$groups = Db::table('backend_user_groups')->get();
|
||||
$roles = [];
|
||||
$permissions = [];
|
||||
|
||||
/*
|
||||
* Carbon copy groups to roles
|
||||
*/
|
||||
foreach ($groups as $group) {
|
||||
if (!isset($group->name) || !$group->name) {
|
||||
continue;
|
||||
}
|
||||
|
||||
try {
|
||||
$roles[$group->id] = Db::table('backend_user_roles')->insertGetId([
|
||||
'name' => $group->name,
|
||||
'description' => $group->description,
|
||||
'permissions' => $group->permissions ?? null
|
||||
]);
|
||||
}
|
||||
catch (Exception $ex) {
|
||||
}
|
||||
|
||||
$permissions[$group->id] = $group->permissions ?? null;
|
||||
}
|
||||
|
||||
/*
|
||||
* Assign a user with the first available role
|
||||
*/
|
||||
$found = [];
|
||||
$joins = Db::table('backend_users_groups')->get();
|
||||
|
||||
foreach ($joins as $join) {
|
||||
if (!$roleId = array_get($roles, $join->user_group_id)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$userId = $join->user_id;
|
||||
|
||||
if (!isset($found[$userId])) {
|
||||
Db::table('backend_users')->where('id', $userId)->update([
|
||||
'role_id' => $roleId
|
||||
]);
|
||||
}
|
||||
|
||||
$found[$userId][] = $join->user_group_id;
|
||||
}
|
||||
|
||||
/*
|
||||
* Merge group permissions in to user
|
||||
*/
|
||||
foreach ($found as $userId => $groups) {
|
||||
$userPerms = [];
|
||||
|
||||
foreach ($groups as $groupId) {
|
||||
if (!$permString = array_get($permissions, $groupId)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
try {
|
||||
$perms = json_decode($permString, true);
|
||||
$userPerms = array_merge($userPerms, $perms);
|
||||
}
|
||||
catch (Exception $ex) {
|
||||
}
|
||||
}
|
||||
|
||||
if (count($userPerms) > 0) {
|
||||
$this->splicePermissionsForUser($userId, $userPerms);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected function splicePermissionsForUser($userId, $permissions)
|
||||
{
|
||||
/*
|
||||
* Look up user and splice the provided permissions in
|
||||
*/
|
||||
$user = Db::table('backend_users')->where('id', $userId)->first();
|
||||
if (!$user) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
$currentPerms = $user->permissions ? json_decode($user->permissions, true) : [];
|
||||
$newPerms = array_merge($permissions, $currentPerms);
|
||||
|
||||
Db::table('backend_users')->where('id', $userId)->update([
|
||||
'permissions' => json_encode($newPerms)
|
||||
]);
|
||||
}
|
||||
catch (Exception $ex) {
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
use Winter\Storm\Database\Schema\Blueprint;
|
||||
use Winter\Storm\Database\Updates\Migration;
|
||||
|
||||
class DbBackendAddDeletedAt extends Migration
|
||||
{
|
||||
public function up()
|
||||
{
|
||||
if (!Schema::hasColumn('backend_users', 'deleted_at')) {
|
||||
Schema::table('backend_users', function (Blueprint $table) {
|
||||
$table->timestamp('deleted_at')->nullable()->after('updated_at');
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public function down()
|
||||
{
|
||||
if (Schema::hasColumn('backend_users', 'deleted_at')) {
|
||||
Schema::table('backend_users', function (Blueprint $table) {
|
||||
$table->dropColumn('deleted_at');
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
use Winter\Storm\Database\Schema\Blueprint;
|
||||
use Winter\Storm\Database\Updates\Migration;
|
||||
|
||||
class DbBackendAddUserMetadata extends Migration
|
||||
{
|
||||
public function up()
|
||||
{
|
||||
if (!Schema::hasColumn('backend_users', 'metadata')) {
|
||||
Schema::table('backend_users', function (Blueprint $table) {
|
||||
$table->mediumText('metadata')->nullable()->after('permissions');
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public function down()
|
||||
{
|
||||
if (Schema::hasColumn('backend_users', 'metadata')) {
|
||||
Schema::table('backend_users', function (Blueprint $table) {
|
||||
$table->dropColumn('metadata');
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
use Winter\Storm\Database\Schema\Blueprint;
|
||||
use Winter\Storm\Database\Updates\Migration;
|
||||
|
||||
class DbBackendAddUsersGroupsDeleteAt extends Migration
|
||||
{
|
||||
public function up()
|
||||
{
|
||||
if (!Schema::hasColumn('backend_users_groups', 'deleted_at')) {
|
||||
Schema::table('backend_users_groups', function (Blueprint $table) {
|
||||
$table->timestamp('deleted_at')->nullable()->after('user_group_id');
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public function down()
|
||||
{
|
||||
if (Schema::hasColumn('backend_users_groups', 'deleted_at')) {
|
||||
Schema::table('backend_users_groups', function (Blueprint $table) {
|
||||
$table->dropColumn('deleted_at');
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user