feat: VivesPOS landing on Winter CMS 1.2 — theme + plugin + Dockerfile
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:
2026-08-21 19:29:00 -06:00
commit 1f72193a64
3266 changed files with 531480 additions and 0 deletions

View File

@@ -0,0 +1,15 @@
<?php namespace Database\Tester;
use System\Classes\PluginBase;
class Plugin extends PluginBase
{
public function pluginDetails()
{
return [
'name' => 'Database Tester Plugin',
'description' => 'Plugin for loading tests that involve the database.',
'author' => 'Alexey Bobkov, Samuel Georges'
];
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@@ -0,0 +1,68 @@
<?php namespace Database\Tester\Models;
use Model;
class Author extends Model
{
/**
* @var string The database table used by the model.
*/
public $table = 'database_tester_authors';
/**
* @var array Guarded fields
*/
protected $guarded = [];
/**
* @var array Relations
*/
public $belongsTo = [
'user' => ['Database\Tester\Models\User', 'delete' => true],
'country' => ['Database\Tester\Models\Country'],
'user_soft' => ['Database\Tester\Models\SoftDeleteUser', 'key' => 'user_id', 'softDelete' => true],
];
public $hasMany = [
'posts' => 'Database\Tester\Models\Post',
];
public $hasOne = [
'phone' => 'Database\Tester\Models\Phone',
];
public $belongsToMany = [
'roles' => [
'Database\Tester\Models\Role',
'table' => 'database_tester_authors_roles'
],
'executive_authors' => [
'Database\Tester\Models\Role',
'table' => 'database_tester_authors_roles',
'conditions' => 'is_executive = 1'
],
];
public $morphMany = [
'event_log' => ['Database\Tester\Models\EventLog', 'name' => 'related', 'delete' => true, 'softDelete' => true],
];
public $morphOne = [
'meta' => ['Database\Tester\Models\Meta', 'name' => 'taggable'],
];
public $morphToMany = [
'tags' => [
'Database\Tester\Models\Tag',
'name' => 'taggable',
'table' => 'database_tester_taggables',
'pivot' => ['added_by']
],
];
}
class SoftDeleteAuthor extends Author
{
use \Winter\Storm\Database\Traits\SoftDelete;
}

View File

@@ -0,0 +1,40 @@
<?php namespace Database\Tester\Models;
use Model;
class Category extends Model
{
/**
* @var string The database table used by the model.
*/
public $table = 'database_tester_categories';
public $belongsToMany = [
'posts' => [
'Database\Tester\Models\Post',
'table' => 'database_tester_categories_posts',
'pivot' => ['category_name', 'post_name']
]
];
public function getCustomNameAttribute()
{
return $this->name.' (#'.$this->id.')';
}
}
class CategorySimple extends Category
{
use \Winter\Storm\Database\Traits\SimpleTree;
}
class CategoryNested extends Category
{
use \Winter\Storm\Database\Traits\NestedTree;
/**
* @var string The database table used by the model.
*/
public $table = 'database_tester_categories_nested';
}

View File

@@ -0,0 +1,35 @@
<?php namespace Database\Tester\Models;
use Model;
class Country extends Model
{
/**
* @var string The database table used by the model.
*/
public $table = 'database_tester_countries';
/**
* @var array Guarded fields
*/
protected $guarded = [];
public $hasMany = [
'users' => [
'Database\Tester\Models\User',
],
];
public $hasManyThrough = [
'posts' => [
'Database\Tester\Models\Post',
'through' => 'Database\Tester\Models\Author',
]
];
}
class SoftDeleteCountry extends Country
{
use \Winter\Storm\Database\Traits\SoftDelete;
}

View File

@@ -0,0 +1,30 @@
<?php namespace Database\Tester\Models;
use Model;
class EventLog extends Model
{
use \Winter\Storm\Database\Traits\SoftDelete;
/**
* @var string The database table used by the model.
*/
public $table = 'database_tester_event_log';
/**
* @var array Guarded fields
*/
protected $guarded = ['*'];
/**
* @var array Fillable fields
*/
protected $fillable = [];
/**
* @var array Relations
*/
public $morphTo = [
'related' => []
];
}

View File

@@ -0,0 +1,24 @@
<?php namespace Database\Tester\Models;
use Model;
class Meta extends Model
{
public $table = 'database_tester_meta';
public $timestamps = false;
public $morphTo = [
'taggable' => []
];
public $fillable = [
'meta_title',
'meta_description',
'meta_keywords',
'canonical_url',
'redirect_url',
'robot_index',
'robot_follow'
];
}

View File

@@ -0,0 +1,29 @@
<?php namespace Database\Tester\Models;
use Model;
class Phone extends Model
{
/**
* @var string The database table used by the model.
*/
public $table = 'database_tester_phones';
/**
* @var array Guarded fields
*/
protected $guarded = ['*'];
/**
* @var array Fillable fields
*/
protected $fillable = [];
/**
* @var array Relations
*/
public $belongsTo = [
'author' => 'Database\Tester\Models\Author',
];
}

View File

@@ -0,0 +1,151 @@
<?php namespace Database\Tester\Models;
use Model;
class Post extends Model
{
/**
* @var string The database table used by the model.
*/
public $table = 'database_tester_posts';
/**
* @var array Guarded fields
*/
protected $guarded = ['*'];
/**
* @var array Fillable fields
*/
protected $fillable = [];
/**
* @var array Relations
*/
public $belongsTo = [
'author' => 'Database\Tester\Models\Author',
];
public $belongsToMany = [
'categories' => [
'Database\Tester\Models\Category',
'table' => 'database_tester_categories_posts',
'pivot' => ['category_name', 'post_name']
]
];
public $morphMany = [
'event_log' => ['Database\Tester\Models\EventLog', 'name' => 'related', 'delete' => true, 'softDelete' => true],
];
public $morphOne = [
'meta' => ['Database\Tester\Models\Meta', 'name' => 'taggable'],
];
public $morphToMany = [
'tags' => [
'Database\Tester\Models\Tag',
'name' => 'taggable',
'table' => 'database_tester_taggables',
'pivot' => ['added_by']
],
];
}
class NullablePost extends Post
{
use \Winter\Storm\Database\Traits\Nullable;
/**
* @var array Guarded fields
*/
protected $guarded = [];
/**
* @var array List of attributes to nullify
*/
protected $nullable = [
'author_nickname',
];
}
class SluggablePost extends Post
{
use \Winter\Storm\Database\Traits\Sluggable;
/**
* @var array Guarded fields
*/
protected $guarded = [];
/**
* @var array List of attributes to automatically generate unique URL names (slugs) for.
*/
protected $slugs = [
'slug' => 'title',
'long_slug' => ['title', 'description']
];
}
class RevisionablePost extends Post
{
use \Winter\Storm\Database\Traits\Revisionable;
use \Winter\Storm\Database\Traits\SoftDelete;
/**
* @var array Guarded fields
*/
protected $guarded = [];
/**
* @var array Dates
*/
protected $dates = ['published_at', 'deleted_at'];
/**
* @var array Monitor these attributes for changes.
*/
protected $revisionable = [
'title',
'slug',
'description',
'is_published',
'published_at',
'deleted_at'
];
/**
* @var int Maximum number of revision records to keep.
*/
public $revisionableLimit = 8;
/**
* @var array Relations
*/
public $morphMany = [
'revision_history' => ['System\Models\Revision', 'name' => 'revisionable']
];
/**
* The user who made the revision.
*/
public function getRevisionableUser()
{
return 7;
}
}
class ValidationPost extends Post
{
use \Winter\Storm\Database\Traits\Validation;
/**
* @var array Guarded fields
*/
protected $guarded = [];
public $rules = [
'title' => 'required|min:3|max:255',
'slug' => ['required', 'regex:/^[a-z0-9\/\:_\-\*\[\]\+\?\|]*$/i', 'unique:database_tester_posts'],
];
}

View File

@@ -0,0 +1,34 @@
<?php namespace Database\Tester\Models;
use Model;
/**
* Role Model
*/
class Role extends Model
{
/**
* @var string The database table used by the model.
*/
public $table = 'database_tester_roles';
/**
* @var array Guarded fields
*/
protected $guarded = [];
/**
* @var array Fillable fields
*/
protected $fillable = [];
/**
* @var array Relations
*/
public $belongsToMany = [
'authors' => [
'Database\Tester\Models\User',
'table' => 'database_tester_authors_roles'
],
];
}

View File

@@ -0,0 +1,36 @@
<?php namespace Database\Tester\Models;
use Model;
class Tag extends Model
{
/**
* @var string The database table used by the model.
*/
public $table = 'database_tester_tags';
/**
* @var array Guarded fields
*/
protected $guarded = [];
/**
* @var array Fillable fields
*/
protected $fillable = [];
public $morphedByMany = [
'authors' => [
'Database\Tester\Models\Author',
'name' => 'taggable',
'table' => 'database_tester_taggables',
'pivot' => ['added_by'],
],
'posts' => [
'Database\Tester\Models\Post',
'name' => 'taggable',
'table' => 'database_tester_taggables',
'pivot' => ['added_by'],
],
];
}

View File

@@ -0,0 +1,69 @@
<?php namespace Database\Tester\Models;
use Model;
class User extends Model
{
/**
* @var string The database table used by the model.
*/
public $table = 'database_tester_users';
/**
* @var array Guarded fields
*/
protected $guarded = [];
/**
* @var array Relations
*/
public $hasOne = [
'author' => [
'Database\Tester\Models\Author',
]
];
public $hasOneThrough = [
'phone' => [
'Database\Tester\Models\Phone',
'through' => 'Database\Tester\Models\Author',
],
];
public $attachOne = [
'avatar' => 'System\Models\File'
];
public $attachMany = [
'photos' => 'System\Models\File'
];
}
class SoftDeleteUser extends User
{
use \Winter\Storm\Database\Traits\SoftDelete;
}
class UserWithAuthor extends User
{
public $hasOne = [
'author' => ['Database\Tester\Models\Author', 'key' => 'user_id', 'delete' => true],
];
}
class UserWithSoftAuthor extends User
{
public $hasOne = [
'author' => ['Database\Tester\Models\SoftDeleteAuthor', 'key' => 'user_id', 'softDelete' => true],
];
}
class UserWithAuthorAndSoftDelete extends UserWithAuthor
{
use \Winter\Storm\Database\Traits\SoftDelete;
}
class UserWithSoftAuthorAndSoftDelete extends UserWithSoftAuthor
{
use \Winter\Storm\Database\Traits\SoftDelete;
}

View File

@@ -0,0 +1,26 @@
<?php namespace Database\Tester\Updates;
use Schema;
use Winter\Storm\Database\Updates\Migration;
class CreateAuthorsTable extends Migration
{
public function up()
{
Schema::create('database_tester_authors', function ($table) {
$table->engine = 'InnoDB';
$table->increments('id');
$table->integer('user_id')->unsigned()->index()->nullable();
$table->integer('country_id')->unsigned()->index()->nullable();
$table->string('name')->nullable();
$table->string('email')->nullable();
$table->softDeletes();
$table->timestamps();
});
}
public function down()
{
Schema::dropIfExists('database_tester_authors');
}
}

View File

@@ -0,0 +1,46 @@
<?php namespace Database\Tester\Updates;
use Schema;
use Winter\Storm\Database\Updates\Migration;
class CreateCategoriesTable extends Migration
{
public function up()
{
Schema::create('database_tester_categories', function ($table) {
$table->engine = 'InnoDB';
$table->increments('id');
$table->integer('parent_id')->nullable();
$table->string('name')->nullable();
$table->string('slug')->nullable()->index()->unique();
$table->string('description')->nullable();
$table->integer('company_id')->unsigned()->nullable();
$table->string('language', 3)->nullable();
$table->timestamps();
$table->softDeletes();
});
Schema::create('database_tester_categories_nested', function ($table) {
$table->engine = 'InnoDB';
$table->increments('id');
$table->integer('parent_id')->nullable();
$table->integer('nest_left')->nullable();
$table->integer('nest_right')->nullable();
$table->integer('nest_depth')->nullable();
$table->string('name')->nullable();
$table->string('slug')->nullable()->index()->unique();
$table->string('description')->nullable();
$table->integer('company_id')->unsigned()->nullable();
$table->string('language', 3)->nullable();
$table->timestamps();
$table->softDeletes();
});
}
public function down()
{
Schema::dropIfExists('database_tester_categories');
Schema::dropIfExists('database_tester_categories_nested');
}
}

View File

@@ -0,0 +1,23 @@
<?php namespace Database\Tester\Updates;
use Schema;
use Winter\Storm\Database\Updates\Migration;
class CreateCountriesTable extends Migration
{
public function up()
{
Schema::create('database_tester_countries', function ($table) {
$table->engine = 'InnoDB';
$table->increments('id');
$table->string('name')->nullable();
$table->softDeletes();
$table->timestamps();
});
}
public function down()
{
Schema::dropIfExists('database_tester_countries');
}
}

View File

@@ -0,0 +1,26 @@
<?php namespace Database\Tester\Updates;
use Schema;
use Winter\Storm\Database\Updates\Migration;
class CreateEventLogTable extends Migration
{
public function up()
{
Schema::create('database_tester_event_log', function ($table) {
$table->engine = 'InnoDB';
$table->increments('id');
$table->string('action', 30)->nullable();
$table->string('related_id')->index()->nullable();
$table->string('related_type')->index()->nullable();
$table->softDeletes();
$table->timestamps();
});
}
public function down()
{
Schema::dropIfExists('database_tester_event_log');
}
}

View File

@@ -0,0 +1,30 @@
<?php namespace Database\Tester\Updates;
use Schema;
use Winter\Storm\Database\Updates\Migration;
class CreateMetaTable extends Migration
{
public function up()
{
Schema::create('database_tester_meta', function ($table) {
$table->engine = 'InnoDB';
$table->increments('id')->unsigned();
$table->integer('taggable_id')->unsigned()->index()->nullable();
$table->string('taggable_type')->nullable();
$table->string('meta_title')->nullable();
$table->string('meta_description')->nullable();
$table->string('meta_keywords')->nullable();
$table->string('canonical_url')->nullable();
$table->string('redirect_url')->nullable();
$table->string('robot_index')->nullable();
$table->string('robot_follow')->nullable();
});
}
public function down()
{
Schema::dropIfExists('database_tester_meta');
}
}

View File

@@ -0,0 +1,24 @@
<?php namespace Database\Tester\Updates;
use Schema;
use Winter\Storm\Database\Updates\Migration;
class CreatePhonesTable extends Migration
{
public function up()
{
Schema::create('database_tester_phones', function ($table) {
$table->engine = 'InnoDB';
$table->increments('id');
$table->string('number')->nullable();
$table->integer('author_id')->unsigned()->index()->nullable();
$table->timestamps();
});
}
public function down()
{
Schema::dropIfExists('database_tester_phones');
}
}

View File

@@ -0,0 +1,41 @@
<?php namespace Database\Tester\Updates;
use Schema;
use Winter\Storm\Database\Updates\Migration;
class CreatePostsTable extends Migration
{
public function up()
{
Schema::create('database_tester_posts', function ($table) {
$table->engine = 'InnoDB';
$table->increments('id');
$table->string('title')->nullable();
$table->string('slug')->nullable()->index();
$table->text('long_slug')->nullable();
$table->text('description')->nullable();
$table->boolean('is_published')->default(false);
$table->timestamp('published_at')->nullable();
$table->integer('author_id')->unsigned()->index()->nullable();
$table->string('author_nickname')->default('Winter')->nullable();
$table->softDeletes();
$table->timestamps();
});
Schema::create('database_tester_categories_posts', function ($table) {
$table->engine = 'InnoDB';
$table->integer('category_id')->unsigned();
$table->integer('post_id')->unsigned();
$table->primary(['category_id', 'post_id']);
$table->string('category_name')->nullable();
$table->string('post_name')->nullable();
});
}
public function down()
{
Schema::dropIfExists('database_tester_categories_posts');
Schema::dropIfExists('database_tester_posts');
}
}

View File

@@ -0,0 +1,34 @@
<?php namespace Database\Tester\Updates;
use Schema;
use Winter\Storm\Database\Updates\Migration;
class CreateRolesTable extends Migration
{
public function up()
{
Schema::create('database_tester_roles', function ($table) {
$table->engine = 'InnoDB';
$table->increments('id');
$table->string('name')->nullable();
$table->text('description')->nullable();
$table->timestamps();
});
Schema::create('database_tester_authors_roles', function ($table) {
$table->engine = 'InnoDB';
$table->integer('author_id')->unsigned();
$table->integer('role_id')->unsigned();
$table->primary(['author_id', 'role_id']);
$table->string('clearance_level')->nullable();
$table->boolean('is_executive')->default(false);
});
}
public function down()
{
Schema::dropIfExists('database_tester_roles');
Schema::dropIfExists('database_tester_authors_roles');
}
}

View File

@@ -0,0 +1,31 @@
<?php namespace Database\Tester\Updates;
use Schema;
use Winter\Storm\Database\Updates\Migration;
class CreateTagsTable extends Migration
{
public function up()
{
Schema::create('database_tester_tags', function ($table) {
$table->engine = 'InnoDB';
$table->increments('id');
$table->string('name');
$table->timestamps();
});
Schema::create('database_tester_taggables', function ($table) {
$table->engine = 'InnoDB';
$table->unsignedInteger('tag_id');
$table->morphs('taggable', 'testings_taggable');
$table->unsignedInteger('added_by')->nullable();
});
}
public function down()
{
Schema::dropIfExists('database_tester_taggables');
Schema::dropIfExists('database_tester_tags');
}
}

View File

@@ -0,0 +1,25 @@
<?php namespace Database\Tester\Updates;
use Schema;
use Winter\Storm\Database\Updates\Migration;
class CreateUsersTable extends Migration
{
public function up()
{
Schema::create('database_tester_users', function ($table) {
$table->engine = 'InnoDB';
$table->increments('id');
$table->string('name')->nullable();
$table->string('email')->nullable();
$table->softDeletes();
$table->timestamps();
});
}
public function down()
{
Schema::dropIfExists('database_tester_users');
}
}

View File

@@ -0,0 +1,13 @@
1.0.1: First version of Tester
1.0.2:
- Create tables
- create_posts_table.php
- create_authors_table.php
- create_phones_table.php
- create_categories_table.php
- create_roles_table.php
- create_users_table.php
- create_event_log_table.php
- create_meta_table.php
- create_countries_table.php
- create_tags_table.php

View File

@@ -0,0 +1,28 @@
<?php namespace DependencyTest\Acme;
use Backend;
use Backend\Models\UserRole;
use System\Classes\PluginBase;
/**
* Acme Plugin Information File
*/
class Plugin extends PluginBase
{
public $require = [
'DependencyTest.Dependency',
];
/**
* Returns information about this plugin.
*/
public function pluginDetails(): array
{
return [
'name' => 'ACME',
'description' => 'This is a test plugin that will be used to check dependencies are loaded first.',
'author' => 'Eric Pfeiffer',
'icon' => 'icon-leaf'
];
}
}

View File

@@ -0,0 +1,2 @@
'1.0.0':
- 'First version of Acme'

View File

@@ -0,0 +1,16 @@
<?php namespace DependencyTest\Dependency;
use System\Classes\PluginBase;
class Plugin extends PluginBase
{
public function pluginDetails()
{
return [
'name' => 'Dependency Test - Dependency',
'description' => 'This is a test plugin that will act as a dependency for the other test plugins in this
namespace.',
'author' => 'Ben Thomson'
];
}
}

View File

@@ -0,0 +1 @@
1.0.1: Initial version of the plugin

View File

@@ -0,0 +1,19 @@
<?php namespace DependencyTest\Found;
use System\Classes\PluginBase;
class Plugin extends PluginBase
{
public $require = [
'DependencyTest.Dependency'
];
public function pluginDetails()
{
return [
'name' => 'Dependency Test - Found',
'description' => 'This is a test plugin with a dependency that exists.',
'author' => 'Ben Thomson'
];
}
}

View File

@@ -0,0 +1 @@
1.0.1: Initial version of the plugin

View File

@@ -0,0 +1,19 @@
<?php namespace DependencyTest\NotFound;
use System\Classes\PluginBase;
class Plugin extends PluginBase
{
public $require = [
'DependencyTest.Missing'
];
public function pluginDetails()
{
return [
'name' => 'Dependency Test - Not Found',
'description' => 'This is a test plugin with a dependency that does not exist.',
'author' => 'Ben Thomson'
];
}
}

View File

@@ -0,0 +1 @@
1.0.1: Initial version of the plugin

View File

@@ -0,0 +1,19 @@
<?php namespace DependencyTest\WrongCase;
use System\Classes\PluginBase;
class Plugin extends PluginBase
{
public $require = [
'Dependencytest.dependency'
];
public function pluginDetails()
{
return [
'name' => 'Dependency Test - Wrong Case',
'description' => 'This is a test plugin with a dependency that exists, but is using the wrong letter case.',
'author' => 'Ben Thomson'
];
}
}

View File

@@ -0,0 +1 @@
1.0.1: Initial version of the plugin

View File

@@ -0,0 +1,15 @@
<?php namespace Mix\TestA;
use System\Classes\PluginBase;
class Plugin extends PluginBase
{
public function pluginDetails()
{
return [
'name' => 'Mix Test A',
'description' => 'Sample plugin used by unit tests.',
'author' => 'Mix Test'
];
}
}

View File

@@ -0,0 +1 @@
dist

View File

@@ -0,0 +1,8 @@
/* eslint-disable no-plusplus, no-console */
(() => {
for (let i = 0; i <= 100; i++) {
if ([2, 3].every((p) => i % p)) {
console.log(i);
}
}
})();

View File

@@ -0,0 +1,5 @@
const mix = require('laravel-mix');
mix.setPublicPath(__dirname);
mix.js('assets/src/app.js', 'assets/dist/app.js');

View File

@@ -0,0 +1,15 @@
<?php namespace Mix\TestB;
use System\Classes\PluginBase;
class Plugin extends PluginBase
{
public function pluginDetails()
{
return [
'name' => 'Mix Test B',
'description' => 'Sample plugin used by unit tests.',
'author' => 'Mix Test'
];
}
}

View File

@@ -0,0 +1 @@
dist

View File

@@ -0,0 +1,10 @@
/* eslint-disable no-plusplus, no-console, import/no-unresolved */
const missing = require('some-missing-package');
(() => {
for (let i = 0; i <= 100; i++) {
if ([2, 3].every((p) => i % p)) {
missing.log(i);
}
}
})();

View File

@@ -0,0 +1,5 @@
const mix = require('laravel-mix');
mix.setPublicPath(__dirname);
mix.js('assets/src/app.js', 'assets/dist/app.js');

View File

@@ -0,0 +1,15 @@
<?php namespace Mix\TestC;
use System\Classes\PluginBase;
class Plugin extends PluginBase
{
public function pluginDetails()
{
return [
'name' => 'Mix Test C',
'description' => 'Sample plugin used by unit tests.',
'author' => 'Mix Test'
];
}
}

View File

@@ -0,0 +1 @@
dist

View File

@@ -0,0 +1,8 @@
/* eslint-disable no-plusplus, no-console */
(() => {
for (let i = 0; i <= 100; i++) {
if ([2, 3].every((p) => i % p)) {
console.log(i);
}
}
})();

View File

@@ -0,0 +1,5 @@
const mix = require('laravel-mix');
mix.setPublicPath(__dirname);
mix.js('assets/src/app.js', 'assets/dist/app.js');

View File

@@ -0,0 +1,15 @@
<?php namespace TestVendor\Goto
use System\Classes\PluginBase;
class Plugin extends PluginBase
{
public function pluginDetails()
{
return [
'name' => 'Invalid Test Plugin',
'description' => 'Test plugin used by unit tests to detect plugins with invalid namespaces.',
'author' => 'Test Vendor'
];
}
}

View File

@@ -0,0 +1,25 @@
<?php namespace TestVendor\Test;
use System\Classes\PluginBase;
class Plugin extends PluginBase
{
public function pluginDetails()
{
return [
'name' => 'Another Test Plugin',
'description' => 'Test plugin used by unit tests with the same name.',
'author' => 'Test Vendor'
];
}
public function registerFormWidgets()
{
return [
'TestVendor\Test\FormWidgets\Sample' => [
'label' => 'Sample',
'code' => 'sample'
]
];
}
}

View File

@@ -0,0 +1,7 @@
<?php namespace TestVendor\Test\FormWidgets;
use Backend\Classes\FormWidgetBase;
class Sample extends FormWidgetBase
{
}

View File

@@ -0,0 +1,18 @@
<?php namespace Winter\InvalidReplacement;
use System\Classes\PluginBase;
class Plugin extends PluginBase
{
public function pluginDetails()
{
return [
'name' => 'Winter Sample Plugin',
'description' => 'Sample plugin used by unit tests.',
'author' => 'Alexey Bobkov, Samuel Georges',
'replaces' => [
'Winter.Tester' => '>=9.0'
]
];
}
}

View File

@@ -0,0 +1,3 @@
1.0.0: Initial build
1.0.1: Updated plugin
2.0.1: Major update

View File

@@ -0,0 +1,15 @@
<?php namespace Winter\NoUpdates;
use System\Classes\PluginBase;
class Plugin extends PluginBase
{
public function pluginDetails()
{
return [
'name' => 'Winter Empty Plugin',
'description' => 'Empty plugin used by unit tests.',
'author' => 'Alexey Bobkov, Samuel Georges'
];
}
}

View File

@@ -0,0 +1,15 @@
<?php namespace Winter\Original;
use System\Classes\PluginBase;
class Plugin extends PluginBase
{
public function pluginDetails()
{
return [
'name' => 'Winter Sample Plugin',
'description' => 'Sample plugin used by unit tests.',
'author' => 'Alexey Bobkov, Samuel Georges'
];
}
}

View File

@@ -0,0 +1 @@
1.0.0: Initial build

View File

@@ -0,0 +1,18 @@
<?php namespace Winter\Replacement;
use System\Classes\PluginBase;
class Plugin extends PluginBase
{
public function pluginDetails()
{
return [
'name' => 'Winter Sample Plugin',
'description' => 'Sample plugin used by unit tests.',
'author' => 'Alexey Bobkov, Samuel Georges',
'replaces' => [
'Winter.Original' => '<=1.0.3'
]
];
}
}

View File

@@ -0,0 +1,2 @@
1.0.0: Initial build
1.0.1: Updated plugin

View File

@@ -0,0 +1,20 @@
<?php
namespace Winter\ReplaceNotInstalled;
use System\Classes\PluginBase;
class Plugin extends PluginBase
{
public function pluginDetails()
{
return [
'name' => 'Winter Sample Plugin',
'description' => 'Sample plugin used by unit tests.',
'author' => 'Alexey Bobkov, Samuel Georges',
'replaces' => [
'Winter.NotInstalled' => '>=1.0.3'
]
];
}
}

View File

@@ -0,0 +1,2 @@
1.0.0: Initial build
1.0.1: Updated plugin

View File

@@ -0,0 +1,15 @@
<?php namespace Winter\Sample;
use System\Classes\PluginBase;
class Plugin extends PluginBase
{
public function pluginDetails()
{
return [
'name' => 'Winter Sample Plugin',
'description' => 'Sample plugin used by unit tests.',
'author' => 'Alexey Bobkov, Samuel Georges'
];
}
}

View File

@@ -0,0 +1,11 @@
1:
- Create blog post comments table
- create_comments_table.php
10.3: Bug fix update that uses no scripts
1.0.x: Another fix
junk:
- JUNK JUNK JUNK
- Some more comments that shouldn't be here
1.0.*:
- Create blog settings table
- create_blog_settings_table.php

View File

@@ -0,0 +1,74 @@
<?php namespace Winter\Tester;
use System\Classes\PluginBase;
class Plugin extends PluginBase
{
public function pluginDetails()
{
return [
'name' => 'Winter Test Plugin',
'description' => 'Test plugin used by unit tests.',
'author' => 'Alexey Bobkov, Samuel Georges'
];
}
public function registerComponents()
{
return [
'Winter\Tester\Components\Archive' => 'testArchive',
'Winter\Tester\Components\Post' => 'testPost',
'Winter\Tester\Components\MainMenu' => 'testMainMenu',
'Winter\Tester\Components\ContentBlock' => 'testContentBlock',
'Winter\Tester\Components\Comments' => 'testComments',
];
}
public function registerFormWidgets()
{
return [
'Winter\Tester\FormWidgets\Preview' => [
'label' => 'Preview',
'code' => 'preview'
]
];
}
public function registerNavigation()
{
return [
'blog' => [
'label' => 'Blog',
'url' => 'http://example.com/blog/posts',
'icon' => 'icon-pencil',
'permissions' => ['winter.blog.*'],
'order' => 500,
'sideMenu' => [
'posts' => [
'label' => 'Posts',
'icon' => 'icon-copy',
'url' => 'http://example.com/blog/posts',
'permissions' => ['winter.blog.access_posts']
],
'categories' => [
'label' => 'Categories',
'icon' => 'icon-list-ul',
'url' => 'http://example.com/blog/categories',
'permissions' => ['winter.blog.access_categories']
],
]
]
];
}
public function registerValidationRules()
{
return [
'uppercase' => function ($attribute, $value, $parameters, $validator) {
return strtoupper($value) === $value;
},
'be_like_bob' => \Winter\Tester\Rules\BeLikeBobRule::class,
];
}
}

View File

@@ -0,0 +1,12 @@
<?php namespace Winter\Tester\Classes;
class Users
{
public function getUsers()
{
return [
'Art Vandelay' => 'Arquitecht and Importer/Exporter',
'Carl' => 'where is he?',
];
}
}

View File

@@ -0,0 +1,41 @@
<?php namespace Winter\Tester\Components;
use Cms\Classes\ComponentBase;
class Archive extends ComponentBase
{
public function componentDetails()
{
return [
'name' => 'Blog Archive Dummy Component',
'description' => 'Displays an archive of blog posts.'
];
}
public function defineProperties()
{
return [
'posts-per-page' => [
'description' => 'This will set the posts to display per page',
'default' => 10
],
'page-number-param' => [
'description' => 'The router parameter for getting the pagination page number',
'default' => 'pageNum'
]
];
}
public function posts()
{
return [
['title' => 'Lorum ipsum', 'content' => 'Post Content #1'],
['title' => 'La Playa Nudista', 'content' => 'Second Post Content']
];
}
public function onTestAjax()
{
$this->page['var'] = 'page';
}
}

View File

@@ -0,0 +1,33 @@
<?php namespace Winter\Tester\Components;
use Cms\Classes\ComponentBase;
use Cms\Classes\CodeBase;
class Categories extends ComponentBase
{
public function __construct(?CodeBase $cmsObject = null, $properties = [])
{
parent::__construct($cmsObject, $properties);
}
public function componentDetails()
{
return [
'name' => 'Blog Categories Dummy Component',
'description' => 'Displays the list of categories in the blog.'
];
}
public function posts()
{
return [
['title' => 'Lorum ipsum', 'content' => 'Post Content #1'],
['title' => 'La Playa Nudista', 'content' => 'Second Post Content']
];
}
public function onTestAjax()
{
$this->page['var'] = 'page';
}
}

View File

@@ -0,0 +1,42 @@
<?php namespace Winter\Tester\Components;
use Cms\Classes\ComponentBase;
use Cms\Classes\CodeBase;
use Winter\Tester\Classes\Users;
class Comments extends ComponentBase
{
private $users;
public function __construct(?CodeBase $cmsObject = null, $properties = [], ?Users $users = null)
{
parent::__construct($cmsObject, $properties);
$this->users = $users;
}
public function componentDetails()
{
return [
'name' => 'Blog Comments Dummy Component',
'description' => 'Displays the list of comments on a post.'
];
}
public function posts()
{
return [
['title' => 'Lorum ipsum', 'content' => 'Post Content #1'],
['title' => 'La Playa Nudista', 'content' => 'Second Post Content']
];
}
public function onTestAjax()
{
$this->page['var'] = 'page';
}
public function getUsers()
{
return $this->users;
}
}

View File

@@ -0,0 +1,23 @@
<?php namespace Winter\Tester\Components;
use Cms\Classes\ComponentBase;
class ContentBlock extends ComponentBase
{
public function componentDetails()
{
return [
'name' => 'Content Block Dummy Component',
'description' => 'Displays a editable content block.'
];
}
public function onRender()
{
if ($output = $this->property('output')) {
return 'Custom output: '.$output;
}
return 'Pass';
}
}

View File

@@ -0,0 +1,19 @@
<?php namespace Winter\Tester\Components;
use Cms\Classes\ComponentBase;
class MainMenu extends ComponentBase
{
public function componentDetails()
{
return [
'name' => 'Menu Dummy Component',
'description' => 'Displays a really cool menu.'
];
}
public function menuItems()
{
return ['Home', 'Blog', 'About', 'Contact'];
}
}

View File

@@ -0,0 +1,24 @@
<?php namespace Winter\Tester\Components;
use Cms\Classes\ComponentBase;
class Post extends ComponentBase
{
public function componentDetails()
{
return [
'name' => 'Blog Post Dummy Component',
'description' => 'Displays a blog post.'
];
}
public function defineProperties()
{
return [
'show-featured' => [
'description' => 'Display the post featured image or not',
'default' => true
]
];
}
}

View File

@@ -0,0 +1,4 @@
<h4>DEFAULT MARKUP: Menu</h4>
<ul>
{% partial __SELF__ ~ "::items" items=__SELF__.menuItems %}
</ul>

View File

@@ -0,0 +1,3 @@
{% for item in items %}
<li>DEFAULT: {{ item }}</li>
{% endfor %}

View File

@@ -0,0 +1 @@
<p>DEFAULT MARKUP: I am a post yay</p>

View File

@@ -0,0 +1,7 @@
<?php namespace Winter\Tester\FormWidgets;
use Backend\Classes\FormWidgetBase;
class Preview extends FormWidgetBase
{
}

View File

@@ -0,0 +1,39 @@
<?php namespace Winter\Tester\Models;
use Model;
class TestModel extends Model
{
use \Winter\Storm\Database\Traits\Sortable;
public $table = 'winter_tester_test_model';
public $jsonable = [
'data',
];
public $belongsTo = [
'user' => TestUser::class
];
public $hasOne = [
'phone' => TestPhone::class
];
public $morphTo = [
'taggable' => []
];
public $rules = [
'uint' => 'required',
'range' => 'required|integer|between:1,10',
];
}
class TestUser extends Model
{
}
class TestPhone extends Model
{
}

View File

@@ -0,0 +1,57 @@
fields:
cb:
label: Checkbox
type: checkbox
switch:
label: Switch
type: switch
int:
label: Integer
type: number
step: 1
uint:
label: Unsigned Integer
type: number
step: 1
min: 0
double:
label: Double
type: number
range:
label: Range
type: range
min: 1
max: 10
datetime:
label: Datetime
type: datepicker
date:
label: Date
type: datepicker
mode: date
required: true
time:
label: Time
type: datepicker
mode: time
md:
label: Markdown
type: markdown
textarea:
label: Textarea
type: textarea
text:
label: Text
required: true

View File

@@ -0,0 +1,41 @@
<?php namespace Winter\Tester\Rules;
use Winter\Storm\Validation\Rule;
class BeLikeBobRule extends Rule
{
/**
* Determine if the validation rule passes.
*
* @param string $attribute
* @param mixed $value
* @return bool
*/
public function passes($attribute, $value)
{
return $value === 'bob';
}
/**
* Validation callback method.
*
* @param string $attribute
* @param mixed $value
* @param array $params
* @return bool
*/
public function validate($attribute, $value, $params)
{
return $this->passes($attribute, $value);
}
/**
* Get the validation error message.
*
* @return string
*/
public function message()
{
return 'You must be like bob';
}
}

View File

@@ -0,0 +1,32 @@
"1.5.1":
- Improved signature with the Test::method()
- Translation updates.
"1.5.0": "!!! Another major update to fix several issues"
"1.4.1": !!! Major update here.
1.3.2:
Added support for Translate plugin.
Added some new languages.
'1.3.1' :
- 'Minor bug fix
Please see changelog'
- 'fix_database.php'
"1.3.0" : !!! We've refactored major parts
of this plugin. Please see the
website for more information.
1.2.0:
- "!!! Security update - see: https://wintercms.com"
1.1.0 :
- "!!! Drop support for blog settings"
- drop_blog_settings_table.php
"1.0.5":
- Create blog settings table
- Another update message
- Yet one more update message
- create_blog_settings_table.php
"1.0.4": "Another fix"
"1.0.3": Bug fix update that uses no scripts
1.0.2: Added some stuff
1.0.1:
- Added some upgrade file and some "seeding"
- some_upgrade_file.php
- some_seeding_file.php