Add migrations system and remove Illuminate dependencies.

This commit is contained in:
flash 2018-05-16 20:18:30 +02:00
parent 966301c21e
commit 26ed87ce02
19 changed files with 478 additions and 1535 deletions

View file

@ -12,9 +12,6 @@
"ext-mbstring": "*", "ext-mbstring": "*",
"twig/twig": "~2.4", "twig/twig": "~2.4",
"nesbot/carbon": "~1.22", "nesbot/carbon": "~1.22",
"illuminate/database": "~5.5",
"illuminate/filesystem": "~5.5",
"doctrine/dbal": "~2.6",
"swiftmailer/swiftmailer": "~6.0", "swiftmailer/swiftmailer": "~6.0",
"erusev/parsedown": "~1.6", "erusev/parsedown": "~1.6",
"geoip2/geoip2": "~2.0" "geoip2/geoip2": "~2.0"

828
composer.lock generated
View file

@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically" "This file is @generated automatically"
], ],
"content-hash": "640791cee4f0e5a55e8fe6829d68c99b", "content-hash": "f30e0f8bcfb4eb650250a7e4efb17058",
"packages": [ "packages": [
{ {
"name": "composer/ca-bundle", "name": "composer/ca-bundle",
@ -62,430 +62,6 @@
], ],
"time": "2018-03-29T19:57:20+00:00" "time": "2018-03-29T19:57:20+00:00"
}, },
{
"name": "doctrine/annotations",
"version": "v1.6.0",
"source": {
"type": "git",
"url": "https://github.com/doctrine/annotations.git",
"reference": "c7f2050c68a9ab0bdb0f98567ec08d80ea7d24d5"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/doctrine/annotations/zipball/c7f2050c68a9ab0bdb0f98567ec08d80ea7d24d5",
"reference": "c7f2050c68a9ab0bdb0f98567ec08d80ea7d24d5",
"shasum": ""
},
"require": {
"doctrine/lexer": "1.*",
"php": "^7.1"
},
"require-dev": {
"doctrine/cache": "1.*",
"phpunit/phpunit": "^6.4"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.6.x-dev"
}
},
"autoload": {
"psr-4": {
"Doctrine\\Common\\Annotations\\": "lib/Doctrine/Common/Annotations"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Roman Borschel",
"email": "roman@code-factory.org"
},
{
"name": "Benjamin Eberlei",
"email": "kontakt@beberlei.de"
},
{
"name": "Guilherme Blanco",
"email": "guilhermeblanco@gmail.com"
},
{
"name": "Jonathan Wage",
"email": "jonwage@gmail.com"
},
{
"name": "Johannes Schmitt",
"email": "schmittjoh@gmail.com"
}
],
"description": "Docblock Annotations Parser",
"homepage": "http://www.doctrine-project.org",
"keywords": [
"annotations",
"docblock",
"parser"
],
"time": "2017-12-06T07:11:42+00:00"
},
{
"name": "doctrine/cache",
"version": "v1.7.1",
"source": {
"type": "git",
"url": "https://github.com/doctrine/cache.git",
"reference": "b3217d58609e9c8e661cd41357a54d926c4a2a1a"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/doctrine/cache/zipball/b3217d58609e9c8e661cd41357a54d926c4a2a1a",
"reference": "b3217d58609e9c8e661cd41357a54d926c4a2a1a",
"shasum": ""
},
"require": {
"php": "~7.1"
},
"conflict": {
"doctrine/common": ">2.2,<2.4"
},
"require-dev": {
"alcaeus/mongo-php-adapter": "^1.1",
"mongodb/mongodb": "^1.1",
"phpunit/phpunit": "^5.7",
"predis/predis": "~1.0"
},
"suggest": {
"alcaeus/mongo-php-adapter": "Required to use legacy MongoDB driver"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.7.x-dev"
}
},
"autoload": {
"psr-4": {
"Doctrine\\Common\\Cache\\": "lib/Doctrine/Common/Cache"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Roman Borschel",
"email": "roman@code-factory.org"
},
{
"name": "Benjamin Eberlei",
"email": "kontakt@beberlei.de"
},
{
"name": "Guilherme Blanco",
"email": "guilhermeblanco@gmail.com"
},
{
"name": "Jonathan Wage",
"email": "jonwage@gmail.com"
},
{
"name": "Johannes Schmitt",
"email": "schmittjoh@gmail.com"
}
],
"description": "Caching library offering an object-oriented API for many cache backends",
"homepage": "http://www.doctrine-project.org",
"keywords": [
"cache",
"caching"
],
"time": "2017-08-25T07:02:50+00:00"
},
{
"name": "doctrine/collections",
"version": "v1.5.0",
"source": {
"type": "git",
"url": "https://github.com/doctrine/collections.git",
"reference": "a01ee38fcd999f34d9bfbcee59dbda5105449cbf"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/doctrine/collections/zipball/a01ee38fcd999f34d9bfbcee59dbda5105449cbf",
"reference": "a01ee38fcd999f34d9bfbcee59dbda5105449cbf",
"shasum": ""
},
"require": {
"php": "^7.1"
},
"require-dev": {
"doctrine/coding-standard": "~0.1@dev",
"phpunit/phpunit": "^5.7"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.3.x-dev"
}
},
"autoload": {
"psr-0": {
"Doctrine\\Common\\Collections\\": "lib/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Roman Borschel",
"email": "roman@code-factory.org"
},
{
"name": "Benjamin Eberlei",
"email": "kontakt@beberlei.de"
},
{
"name": "Guilherme Blanco",
"email": "guilhermeblanco@gmail.com"
},
{
"name": "Jonathan Wage",
"email": "jonwage@gmail.com"
},
{
"name": "Johannes Schmitt",
"email": "schmittjoh@gmail.com"
}
],
"description": "Collections Abstraction library",
"homepage": "http://www.doctrine-project.org",
"keywords": [
"array",
"collections",
"iterator"
],
"time": "2017-07-22T10:37:32+00:00"
},
{
"name": "doctrine/common",
"version": "v2.8.1",
"source": {
"type": "git",
"url": "https://github.com/doctrine/common.git",
"reference": "f68c297ce6455e8fd794aa8ffaf9fa458f6ade66"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/doctrine/common/zipball/f68c297ce6455e8fd794aa8ffaf9fa458f6ade66",
"reference": "f68c297ce6455e8fd794aa8ffaf9fa458f6ade66",
"shasum": ""
},
"require": {
"doctrine/annotations": "1.*",
"doctrine/cache": "1.*",
"doctrine/collections": "1.*",
"doctrine/inflector": "1.*",
"doctrine/lexer": "1.*",
"php": "~7.1"
},
"require-dev": {
"phpunit/phpunit": "^5.7"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.8.x-dev"
}
},
"autoload": {
"psr-4": {
"Doctrine\\Common\\": "lib/Doctrine/Common"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Roman Borschel",
"email": "roman@code-factory.org"
},
{
"name": "Benjamin Eberlei",
"email": "kontakt@beberlei.de"
},
{
"name": "Guilherme Blanco",
"email": "guilhermeblanco@gmail.com"
},
{
"name": "Jonathan Wage",
"email": "jonwage@gmail.com"
},
{
"name": "Johannes Schmitt",
"email": "schmittjoh@gmail.com"
}
],
"description": "Common Library for Doctrine projects",
"homepage": "http://www.doctrine-project.org",
"keywords": [
"annotations",
"collections",
"eventmanager",
"persistence",
"spl"
],
"time": "2017-08-31T08:43:38+00:00"
},
{
"name": "doctrine/dbal",
"version": "v2.7.1",
"source": {
"type": "git",
"url": "https://github.com/doctrine/dbal.git",
"reference": "11037b4352c008373561dc6fc836834eed80c3b5"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/doctrine/dbal/zipball/11037b4352c008373561dc6fc836834eed80c3b5",
"reference": "11037b4352c008373561dc6fc836834eed80c3b5",
"shasum": ""
},
"require": {
"doctrine/common": "^2.7.1",
"ext-pdo": "*",
"php": "^7.1"
},
"require-dev": {
"doctrine/coding-standard": "^4.0",
"phpunit/phpunit": "^7.0",
"phpunit/phpunit-mock-objects": "!=3.2.4,!=3.2.5",
"symfony/console": "^2.0.5||^3.0",
"symfony/phpunit-bridge": "^3.4.5|^4.0.5"
},
"suggest": {
"symfony/console": "For helpful console commands such as SQL execution and import of files."
},
"bin": [
"bin/doctrine-dbal"
],
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.7.x-dev"
}
},
"autoload": {
"psr-0": {
"Doctrine\\DBAL\\": "lib/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Roman Borschel",
"email": "roman@code-factory.org"
},
{
"name": "Benjamin Eberlei",
"email": "kontakt@beberlei.de"
},
{
"name": "Guilherme Blanco",
"email": "guilhermeblanco@gmail.com"
},
{
"name": "Jonathan Wage",
"email": "jonwage@gmail.com"
}
],
"description": "Database Abstraction Layer",
"homepage": "http://www.doctrine-project.org",
"keywords": [
"database",
"dbal",
"persistence",
"queryobject"
],
"time": "2018-04-07T18:44:18+00:00"
},
{
"name": "doctrine/inflector",
"version": "v1.3.0",
"source": {
"type": "git",
"url": "https://github.com/doctrine/inflector.git",
"reference": "5527a48b7313d15261292c149e55e26eae771b0a"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/doctrine/inflector/zipball/5527a48b7313d15261292c149e55e26eae771b0a",
"reference": "5527a48b7313d15261292c149e55e26eae771b0a",
"shasum": ""
},
"require": {
"php": "^7.1"
},
"require-dev": {
"phpunit/phpunit": "^6.2"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.3.x-dev"
}
},
"autoload": {
"psr-4": {
"Doctrine\\Common\\Inflector\\": "lib/Doctrine/Common/Inflector"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Roman Borschel",
"email": "roman@code-factory.org"
},
{
"name": "Benjamin Eberlei",
"email": "kontakt@beberlei.de"
},
{
"name": "Guilherme Blanco",
"email": "guilhermeblanco@gmail.com"
},
{
"name": "Jonathan Wage",
"email": "jonwage@gmail.com"
},
{
"name": "Johannes Schmitt",
"email": "schmittjoh@gmail.com"
}
],
"description": "Common String Manipulations with regard to casing and singular/plural rules.",
"homepage": "http://www.doctrine-project.org",
"keywords": [
"inflection",
"pluralize",
"singularize",
"string"
],
"time": "2018-01-09T20:05:19+00:00"
},
{ {
"name": "doctrine/lexer", "name": "doctrine/lexer",
"version": "v1.0.1", "version": "v1.0.1",
@ -695,262 +271,6 @@
], ],
"time": "2018-04-10T15:32:59+00:00" "time": "2018-04-10T15:32:59+00:00"
}, },
{
"name": "illuminate/container",
"version": "v5.6.22",
"source": {
"type": "git",
"url": "https://github.com/illuminate/container.git",
"reference": "1a29b314dd5c7a5a5bce3dd7b9da924cc1ec22ec"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/illuminate/container/zipball/1a29b314dd5c7a5a5bce3dd7b9da924cc1ec22ec",
"reference": "1a29b314dd5c7a5a5bce3dd7b9da924cc1ec22ec",
"shasum": ""
},
"require": {
"illuminate/contracts": "5.6.*",
"php": "^7.1.3",
"psr/container": "~1.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "5.6-dev"
}
},
"autoload": {
"psr-4": {
"Illuminate\\Container\\": ""
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Taylor Otwell",
"email": "taylor@laravel.com"
}
],
"description": "The Illuminate Container package.",
"homepage": "https://laravel.com",
"time": "2018-05-14T12:49:42+00:00"
},
{
"name": "illuminate/contracts",
"version": "v5.6.22",
"source": {
"type": "git",
"url": "https://github.com/illuminate/contracts.git",
"reference": "3dc639feabe0f302f574157a782ede323881a944"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/illuminate/contracts/zipball/3dc639feabe0f302f574157a782ede323881a944",
"reference": "3dc639feabe0f302f574157a782ede323881a944",
"shasum": ""
},
"require": {
"php": "^7.1.3",
"psr/container": "~1.0",
"psr/simple-cache": "~1.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "5.6-dev"
}
},
"autoload": {
"psr-4": {
"Illuminate\\Contracts\\": ""
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Taylor Otwell",
"email": "taylor@laravel.com"
}
],
"description": "The Illuminate Contracts package.",
"homepage": "https://laravel.com",
"time": "2018-05-11T23:38:58+00:00"
},
{
"name": "illuminate/database",
"version": "v5.6.22",
"source": {
"type": "git",
"url": "https://github.com/illuminate/database.git",
"reference": "713d376a2e2b9c7cded8916125c24b7b3adb4984"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/illuminate/database/zipball/713d376a2e2b9c7cded8916125c24b7b3adb4984",
"reference": "713d376a2e2b9c7cded8916125c24b7b3adb4984",
"shasum": ""
},
"require": {
"illuminate/container": "5.6.*",
"illuminate/contracts": "5.6.*",
"illuminate/support": "5.6.*",
"php": "^7.1.3"
},
"suggest": {
"doctrine/dbal": "Required to rename columns and drop SQLite columns (~2.6).",
"fzaninotto/faker": "Required to use the eloquent factory builder (~1.4).",
"illuminate/console": "Required to use the database commands (5.6.*).",
"illuminate/events": "Required to use the observers with Eloquent (5.6.*).",
"illuminate/filesystem": "Required to use the migrations (5.6.*).",
"illuminate/pagination": "Required to paginate the result set (5.6.*)."
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "5.6-dev"
}
},
"autoload": {
"psr-4": {
"Illuminate\\Database\\": ""
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Taylor Otwell",
"email": "taylor@laravel.com"
}
],
"description": "The Illuminate Database package.",
"homepage": "https://laravel.com",
"keywords": [
"database",
"laravel",
"orm",
"sql"
],
"time": "2018-05-14T22:33:47+00:00"
},
{
"name": "illuminate/filesystem",
"version": "v5.6.22",
"source": {
"type": "git",
"url": "https://github.com/illuminate/filesystem.git",
"reference": "a4ca4a9c2f969ec227748ab334693144995ba0ce"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/illuminate/filesystem/zipball/a4ca4a9c2f969ec227748ab334693144995ba0ce",
"reference": "a4ca4a9c2f969ec227748ab334693144995ba0ce",
"shasum": ""
},
"require": {
"illuminate/contracts": "5.6.*",
"illuminate/support": "5.6.*",
"php": "^7.1.3",
"symfony/finder": "~4.0"
},
"suggest": {
"league/flysystem": "Required to use the Flysystem local and FTP drivers (~1.0).",
"league/flysystem-aws-s3-v3": "Required to use the Flysystem S3 driver (~1.0).",
"league/flysystem-cached-adapter": "Required to use the Flysystem cache (~1.0).",
"league/flysystem-rackspace": "Required to use the Flysystem Rackspace driver (~1.0).",
"league/flysystem-sftp": "Required to use the Flysystem SFTP driver (~1.0)."
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "5.6-dev"
}
},
"autoload": {
"psr-4": {
"Illuminate\\Filesystem\\": ""
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Taylor Otwell",
"email": "taylor@laravel.com"
}
],
"description": "The Illuminate Filesystem package.",
"homepage": "https://laravel.com",
"time": "2018-05-02T16:10:37+00:00"
},
{
"name": "illuminate/support",
"version": "v5.6.22",
"source": {
"type": "git",
"url": "https://github.com/illuminate/support.git",
"reference": "2ef559ad8840481d5247bd7ebfd04eb37d3f6889"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/illuminate/support/zipball/2ef559ad8840481d5247bd7ebfd04eb37d3f6889",
"reference": "2ef559ad8840481d5247bd7ebfd04eb37d3f6889",
"shasum": ""
},
"require": {
"doctrine/inflector": "~1.1",
"ext-mbstring": "*",
"illuminate/contracts": "5.6.*",
"nesbot/carbon": "^1.24.1",
"php": "^7.1.3"
},
"conflict": {
"tightenco/collect": "<5.5.33"
},
"suggest": {
"illuminate/filesystem": "Required to use the composer class (5.6.*).",
"symfony/process": "Required to use the composer class (~4.0).",
"symfony/var-dumper": "Required to use the dd function (~4.0)."
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "5.6-dev"
}
},
"autoload": {
"psr-4": {
"Illuminate\\Support\\": ""
},
"files": [
"helpers.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Taylor Otwell",
"email": "taylor@laravel.com"
}
],
"description": "The Illuminate Support package.",
"homepage": "https://laravel.com",
"time": "2018-05-12T17:43:47+00:00"
},
{ {
"name": "maxmind-db/reader", "name": "maxmind-db/reader",
"version": "v1.3.0", "version": "v1.3.0",
@ -1101,103 +421,6 @@
], ],
"time": "2018-04-23T09:02:57+00:00" "time": "2018-04-23T09:02:57+00:00"
}, },
{
"name": "psr/container",
"version": "1.0.0",
"source": {
"type": "git",
"url": "https://github.com/php-fig/container.git",
"reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/php-fig/container/zipball/b7ce3b176482dbbc1245ebf52b181af44c2cf55f",
"reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f",
"shasum": ""
},
"require": {
"php": ">=5.3.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.0.x-dev"
}
},
"autoload": {
"psr-4": {
"Psr\\Container\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "PHP-FIG",
"homepage": "http://www.php-fig.org/"
}
],
"description": "Common Container Interface (PHP FIG PSR-11)",
"homepage": "https://github.com/php-fig/container",
"keywords": [
"PSR-11",
"container",
"container-interface",
"container-interop",
"psr"
],
"time": "2017-02-14T16:28:37+00:00"
},
{
"name": "psr/simple-cache",
"version": "1.0.1",
"source": {
"type": "git",
"url": "https://github.com/php-fig/simple-cache.git",
"reference": "408d5eafb83c57f6365a3ca330ff23aa4a5fa39b"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/php-fig/simple-cache/zipball/408d5eafb83c57f6365a3ca330ff23aa4a5fa39b",
"reference": "408d5eafb83c57f6365a3ca330ff23aa4a5fa39b",
"shasum": ""
},
"require": {
"php": ">=5.3.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.0.x-dev"
}
},
"autoload": {
"psr-4": {
"Psr\\SimpleCache\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "PHP-FIG",
"homepage": "http://www.php-fig.org/"
}
],
"description": "Common interfaces for simple caching",
"keywords": [
"cache",
"caching",
"psr",
"psr-16",
"simple-cache"
],
"time": "2017-10-23T01:57:42+00:00"
},
{ {
"name": "swiftmailer/swiftmailer", "name": "swiftmailer/swiftmailer",
"version": "v6.0.2", "version": "v6.0.2",
@ -1253,55 +476,6 @@
], ],
"time": "2017-09-30T22:39:41+00:00" "time": "2017-09-30T22:39:41+00:00"
}, },
{
"name": "symfony/finder",
"version": "v4.0.9",
"source": {
"type": "git",
"url": "https://github.com/symfony/finder.git",
"reference": "ca27c02b7a3fef4828c998c2ff9ba7aae1641c49"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/finder/zipball/ca27c02b7a3fef4828c998c2ff9ba7aae1641c49",
"reference": "ca27c02b7a3fef4828c998c2ff9ba7aae1641c49",
"shasum": ""
},
"require": {
"php": "^7.1.3"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "4.0-dev"
}
},
"autoload": {
"psr-4": {
"Symfony\\Component\\Finder\\": ""
},
"exclude-from-classmap": [
"/Tests/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Fabien Potencier",
"email": "fabien@symfony.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony Finder Component",
"homepage": "https://symfony.com",
"time": "2018-04-04T05:10:37+00:00"
},
{ {
"name": "symfony/polyfill-mbstring", "name": "symfony/polyfill-mbstring",
"version": "v1.8.0", "version": "v1.8.0",

View file

@ -1,52 +0,0 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Misuzu\DatabaseV1;
// phpcs:disable
class InitialUsersTable extends Migration
{
/**
* @SuppressWarnings(PHPMD)
*/
public function up()
{
$schema = DatabaseV1::connection()->getSchemaBuilder();
$schema->create('users', function (Blueprint $table) {
$table->increments('user_id');
$table->string('username', 255)
->unique();
$table->string('password', 255)
->nullable()
->default(null);
$table->string('email', 255)
->unique();
$table->binary('register_ip');
$table->binary('last_ip');
$table->char('user_country', 2)
->default('XX');
$table->integer('user_registered')
->unsigned()
->default(0);
$table->string('user_chat_key', 32)
->nullable()
->default(null);
});
}
/**
* @SuppressWarnings(PHPMD)
*/
public function down()
{
$schema = DatabaseV1::connection()->getSchemaBuilder();
$schema->drop('users');
}
}

View file

@ -1,66 +0,0 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Misuzu\DatabaseV1;
// phpcs:disable
class CreateSessionsTable extends Migration
{
/**
* @SuppressWarnings(PHPMD)
*/
public function up()
{
$schema = DatabaseV1::connection()->getSchemaBuilder();
$schema->create('sessions', function (Blueprint $table) {
$table->increments('session_id');
$table->integer('user_id')
->unsigned();
$table->string('session_key', 255);
$table->binary('session_ip');
$table->string('user_agent', 255)
->nullable()
->default(null);
$table->timestamp('expires_on')
->nullable();
$table->timestamps();
$table->foreign('user_id')
->references('user_id')
->on('users')
->onUpdate('cascade')
->onDelete('cascade');
});
$schema->table('users', function (Blueprint $table) {
$table->dropColumn('user_registered');
$table->timestamps();
$table->softDeletes();
});
}
/**
* @SuppressWarnings(PHPMD)
*/
public function down()
{
$schema = DatabaseV1::connection()->getSchemaBuilder();
$schema->table('users', function (Blueprint $table) {
$table->integer('user_registered')
->unsigned()
->default(0);
$table->dropSoftDeletes();
$table->dropTimestamps();
});
$schema->drop('sessions');
}
}

View file

@ -1,90 +0,0 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Misuzu\DatabaseV1;
// phpcs:disable
class CreateRolesTables extends Migration
{
/**
* @SuppressWarnings(PHPMD)
*/
public function up()
{
$schema = DatabaseV1::connection()->getSchemaBuilder();
$schema->create('roles', function (Blueprint $table) {
$table->increments('role_id');
$table->integer('role_hierarchy')
->default(1);
$table->string('role_name', 255);
$table->string('role_title', 64)
->nullable();
$table->text('role_description')
->nullable();
$table->boolean('role_secret')
->default(false);
$table->integer('role_colour')
->nullable()
->default(null);
$table->timestamps();
});
$schema->create('user_roles', function (Blueprint $table) {
$table->integer('user_id')
->unsigned();
$table->integer('role_id')
->unsigned();
$table->primary(['user_id', 'role_id']);
$table->foreign('user_id')
->references('user_id')
->on('users')
->onUpdate('cascade')
->onDelete('cascade');
$table->foreign('role_id')
->references('role_id')
->on('roles')
->onUpdate('cascade')
->onDelete('cascade');
});
$schema->table('users', function (Blueprint $table) {
$table->integer('display_role')
->unsigned()
->nullable()
->default(null);
$table->foreign('display_role')
->references('role_id')
->on('roles')
->onUpdate('cascade')
->onDelete('set null');
});
}
/**
* @SuppressWarnings(PHPMD)
*/
public function down()
{
$schema = DatabaseV1::connection()->getSchemaBuilder();
$schema->table('users', function (Blueprint $table) {
$table->dropForeign(['display_role']);
$table->dropColumn('display_role');
});
$schema->drop('user_roles');
$schema->drop('roles');
}
}

View file

@ -1,48 +0,0 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Misuzu\DatabaseV1;
// phpcs:disable
class CreateLoginAttemptsTable extends Migration
{
/**
* @SuppressWarnings(PHPMD)
*/
public function up()
{
$schema = DatabaseV1::connection()->getSchemaBuilder();
$schema->create('login_attempts', function (Blueprint $table) {
$table->increments('attempt_id');
$table->boolean('was_successful');
$table->binary('attempt_ip');
$table->char('attempt_country', 2)
->default('XX');
$table->integer('user_id')
->nullable()
->default(null)
->unsigned();
$table->timestamps();
$table->foreign('user_id')
->references('user_id')
->on('users')
->onUpdate('cascade')
->onDelete('set null');
});
}
/**
* @SuppressWarnings(PHPMD)
*/
public function down()
{
$schema = DatabaseV1::connection()->getSchemaBuilder();
$schema->drop('login_attempts');
}
}

View file

@ -1,38 +0,0 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Misuzu\DatabaseV1;
// phpcs:disable
class AddSessionCountryAndLoginUserAgent extends Migration
{
/**
* @SuppressWarnings(PHPMD)
*/
public function up()
{
$schema = DatabaseV1::connection()->getSchemaBuilder();
$schema->table('sessions', function (Blueprint $table) {
$table->char('session_country', 2)
->default('XX');
});
$schema->table('login_attempts', function (Blueprint $table) {
$table->string('user_agent', 255)
->default('');
});
}
/**
* @SuppressWarnings(PHPMD)
*/
public function down()
{
$schema = DatabaseV1::connection()->getSchemaBuilder();
$schema->table('sessions', function (Blueprint $table) {
$table->dropColumn('session_country');
});
$schema->table('login_attempts', function (Blueprint $table) {
$table->dropColumn('user_agent');
});
}
}

View file

@ -1,69 +0,0 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Misuzu\DatabaseV1;
// phpcs:disable
class AddProfileFieldsToUsers extends Migration
{
/**
* @SuppressWarnings(PHPMD)
*/
public function up()
{
$schema = DatabaseV1::connection()->getSchemaBuilder();
$schema->table('users', function (Blueprint $table) {
$table->string('user_website', 255)
->default('');
$table->string('user_twitter', 20)
->default('');
$table->string('user_github', 40)
->default('');
$table->string('user_skype', 60)
->default('');
$table->string('user_discord', 40)
->default('');
$table->string('user_youtube', 255)
->default('');
$table->string('user_steam', 255)
->default('');
$table->string('user_twitchtv', 30)
->default('');
$table->string('user_osu', 20)
->default('');
$table->string('user_lastfm', 20)
->default('');
});
}
/**
* @SuppressWarnings(PHPMD)
*/
public function down()
{
$schema = DatabaseV1::connection()->getSchemaBuilder();
$schema->table('users', function (Blueprint $table) {
$table->dropColumn([
'user_website',
'user_twitter',
'user_github',
'user_skype',
'user_discord',
'user_youtube',
'user_steam',
'user_twitchtv',
'user_osu',
'user_lastfm',
]);
});
}
}

View file

@ -1,59 +0,0 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Misuzu\DatabaseV1;
// phpcs:disable
class CreateNewsTables extends Migration
{
/**
* @SuppressWarnings(PHPMD)
*/
public function up()
{
$schema = DatabaseV1::connection()->getSchemaBuilder();
$schema->create('news_categories', function (Blueprint $table) {
$table->increments('category_id');
$table->string('category_name');
$table->text('category_description');
$table->boolean('is_hidden')->default(false);
$table->timestamps();
});
$schema->create('news_posts', function (Blueprint $table) {
$table->increments('post_id');
$table->integer('category_id')->unsigned();
$table->boolean('is_featured')->default(false);
$table->integer('user_id')->unsigned()->nullable();
$table->string('post_title');
$table->text('post_text');
$table->timestamp('scheduled_for')->useCurrent();
$table->timestamps();
$table->softDeletes();
$table->foreign('category_id')
->references('category_id')
->on('news_categories')
->onUpdate('cascade')
->onDelete('cascade');
$table->foreign('user_id')
->references('user_id')
->on('users')
->onUpdate('cascade')
->onDelete('set null');
});
}
/**
* @SuppressWarnings(PHPMD)
*/
public function down()
{
$schema = DatabaseV1::connection()->getSchemaBuilder();
$schema->drop('news_posts');
$schema->drop('news_categories');
}
}

View file

@ -1,39 +0,0 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Misuzu\DatabaseV1;
// phpcs:disable
class AddLastSeenAndUserTitle extends Migration
{
/**
* @SuppressWarnings(PHPMD)
*/
public function up()
{
$schema = DatabaseV1::connection()->getSchemaBuilder();
$schema->table('users', function (Blueprint $table) {
$table->string('user_title', 64)
->nullable()
->default(null);
$table->timestamp('last_seen')
->nullable()
->default(null);
});
}
/**
* @SuppressWarnings(PHPMD)
*/
public function down()
{
$schema = DatabaseV1::connection()->getSchemaBuilder();
$schema->table('users', function (Blueprint $table) {
$table->dropColumn([
'user_title',
'last_seen',
]);
});
}
}

View file

@ -0,0 +1,172 @@
<?php
namespace Misuzu\DatabaseMigrations\InitialStructure;
use PDO;
use Misuzu\Database;
function migrate_up(PDO $conn): void
{
$conn->exec("
CREATE TABLE `msz_roles` (
`role_id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
`role_hierarchy` INT(11) NOT NULL DEFAULT '1',
`role_name` VARCHAR(255) NOT NULL,
`role_title` VARCHAR(64) NULL DEFAULT NULL,
`role_description` TEXT NULL,
`role_secret` TINYINT(1) NOT NULL DEFAULT '0',
`role_colour` INT(11) NOT NULL DEFAULT '0',
`created_at` TIMESTAMP NULL DEFAULT NULL,
`updated_at` TIMESTAMP NULL DEFAULT NULL,
PRIMARY KEY (`role_id`)
)
");
$conn->exec("
CREATE TABLE `msz_users` (
`user_id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
`username` VARCHAR(255) NOT NULL,
`password` VARCHAR(255) NULL DEFAULT NULL,
`email` VARCHAR(255) NOT NULL,
`register_ip` BLOB NOT NULL,
`last_ip` BLOB NOT NULL,
`user_country` CHAR(2) NOT NULL DEFAULT 'XX',
`user_chat_key` VARCHAR(32) NULL DEFAULT NULL,
`created_at` TIMESTAMP NULL DEFAULT NULL,
`updated_at` TIMESTAMP NULL DEFAULT NULL,
`deleted_at` TIMESTAMP NULL DEFAULT NULL,
`display_role` INT(10) UNSIGNED NULL DEFAULT NULL,
`user_website` VARCHAR(255) NOT NULL DEFAULT '',
`user_twitter` VARCHAR(20) NOT NULL DEFAULT '',
`user_github` VARCHAR(40) NOT NULL DEFAULT '',
`user_skype` VARCHAR(60) NOT NULL DEFAULT '',
`user_discord` VARCHAR(40) NOT NULL DEFAULT '',
`user_youtube` VARCHAR(255) NOT NULL DEFAULT '',
`user_steam` VARCHAR(255) NOT NULL DEFAULT '',
`user_twitchtv` VARCHAR(30) NOT NULL DEFAULT '',
`user_osu` VARCHAR(20) NOT NULL DEFAULT '',
`user_lastfm` VARCHAR(20) NOT NULL DEFAULT '',
`user_title` VARCHAR(64) NOT NULL DEFAULT '',
`last_seen` TIMESTAMP NULL DEFAULT NULL,
PRIMARY KEY (`user_id`),
UNIQUE INDEX `users_username_unique` (`username`),
UNIQUE INDEX `users_email_unique` (`email`),
INDEX `users_display_role_foreign` (`display_role`),
CONSTRAINT `users_display_role_foreign`
FOREIGN KEY (`display_role`)
REFERENCES `msz_roles` (`role_id`)
ON UPDATE CASCADE
ON DELETE SET NULL
)
");
$conn->exec("
CREATE TABLE `msz_user_roles` (
`user_id` INT(10) UNSIGNED NOT NULL,
`role_id` INT(10) UNSIGNED NOT NULL,
UNIQUE INDEX `user_roles_unique` (`user_id`, `role_id`),
INDEX `user_roles_role_id_foreign` (`role_id`),
CONSTRAINT `user_roles_role_id_foreign`
FOREIGN KEY (`role_id`)
REFERENCES `msz_roles` (`role_id`)
ON UPDATE CASCADE
ON DELETE CASCADE,
CONSTRAINT `user_roles_user_id_foreign`
FOREIGN KEY (`user_id`)
REFERENCES `msz_users` (`user_id`)
ON UPDATE CASCADE
ON DELETE CASCADE
)
");
$conn->exec("
CREATE TABLE `msz_sessions` (
`session_id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
`user_id` INT(10) UNSIGNED NOT NULL,
`session_key` VARCHAR(255) NOT NULL,
`session_ip` BLOB NOT NULL,
`user_agent` VARCHAR(255) NULL DEFAULT NULL,
`expires_on` TIMESTAMP NULL DEFAULT NULL,
`created_at` TIMESTAMP NULL DEFAULT NULL,
`updated_at` TIMESTAMP NULL DEFAULT NULL,
`session_country` CHAR(2) NOT NULL DEFAULT 'XX',
PRIMARY KEY (`session_id`),
INDEX `sessions_user_id_foreign` (`user_id`),
CONSTRAINT `sessions_user_id_foreign`
FOREIGN KEY (`user_id`)
REFERENCES `msz_users` (`user_id`)
ON UPDATE CASCADE
ON DELETE CASCADE
)
");
$conn->exec("
CREATE TABLE `msz_login_attempts` (
`attempt_id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
`was_successful` TINYINT(1) NOT NULL,
`attempt_ip` BLOB NOT NULL,
`attempt_country` CHAR(2) NOT NULL DEFAULT 'XX',
`user_id` INT(10) UNSIGNED NULL DEFAULT NULL,
`created_at` TIMESTAMP NULL DEFAULT NULL,
`updated_at` TIMESTAMP NULL DEFAULT NULL,
`user_agent` VARCHAR(255) NOT NULL DEFAULT '',
PRIMARY KEY (`attempt_id`),
INDEX `login_attempts_user_id_foreign` (`user_id`),
CONSTRAINT `login_attempts_user_id_foreign`
FOREIGN KEY (`user_id`)
REFERENCES `msz_users` (`user_id`)
ON UPDATE CASCADE
ON DELETE SET NULL
)
");
$conn->exec("
CREATE TABLE `msz_news_categories` (
`category_id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
`category_name` VARCHAR(255) NOT NULL,
`category_description` TEXT NOT NULL,
`is_hidden` TINYINT(1) NOT NULL DEFAULT '0',
`created_at` TIMESTAMP NULL DEFAULT NULL,
`updated_at` TIMESTAMP NULL DEFAULT NULL,
PRIMARY KEY (`category_id`)
)
");
$conn->exec("
CREATE TABLE `msz_news_posts` (
`post_id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
`category_id` INT(10) UNSIGNED NOT NULL,
`is_featured` TINYINT(1) NOT NULL DEFAULT '0',
`user_id` INT(10) UNSIGNED NULL DEFAULT NULL,
`post_title` VARCHAR(255) NOT NULL,
`post_text` TEXT NOT NULL,
`scheduled_for` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
`created_at` TIMESTAMP NULL DEFAULT NULL,
`updated_at` TIMESTAMP NULL DEFAULT NULL,
`deleted_at` TIMESTAMP NULL DEFAULT NULL,
PRIMARY KEY (`post_id`),
INDEX `news_posts_category_id_foreign` (`category_id`),
INDEX `news_posts_user_id_foreign` (`user_id`),
CONSTRAINT `news_posts_category_id_foreign`
FOREIGN KEY (`category_id`)
REFERENCES `msz_news_categories` (`category_id`)
ON UPDATE CASCADE
ON DELETE CASCADE,
CONSTRAINT `news_posts_user_id_foreign`
FOREIGN KEY (`user_id`)
REFERENCES `msz_users` (`user_id`)
ON UPDATE CASCADE
ON DELETE SET NULL
)
");
}
function migrate_down(PDO $conn): void
{
$conn->exec('DROP TABLE `msz_news_posts`');
$conn->exec('DROP TABLE `msz_news_categories`');
$conn->exec('DROP TABLE `msz_login_attempts`');
$conn->exec('DROP TABLE `msz_sessions`');
$conn->exec('DROP TABLE `msz_user_roles`');
$conn->exec('DROP TABLE `msz_users`');
$conn->exec('DROP TABLE `msz_roles`');
}

View file

@ -1,28 +1,65 @@
<?php <?php
/** /**
* Migration script * Migration script
* @todo Move this into a CLI commands system.
*/ */
namespace Misuzu; use Misuzu\Database;
use Misuzu\DatabaseMigrationManager;
exit;
use Illuminate\Database\Migrations\DatabaseMigrationRepository;
use Illuminate\Database\Migrations\Migrator;
use Illuminate\Filesystem\Filesystem;
require_once __DIR__ . '/misuzu.php'; require_once __DIR__ . '/misuzu.php';
$repository = new DatabaseMigrationRepository(Application::getInstance()->getDatabase()->getDatabaseManager(), 'migrations'); define('MSZ_MIGRATABLE_DATABASES', [
$migrator = new Migrator($repository, $repository->getConnectionResolver(), new Filesystem); 'mysql-test' => __DIR__ . '/database',
]);
if (!$migrator->repositoryExists()) { function migrate_log($log): void
$repository->createRepository(); {
echo $log . PHP_EOL;
} }
$migrator->run(__DIR__ . '/database'); if (PHP_SAPI !== 'cli') {
//$migrator->rollback(__DIR__ . '/database'); migrate_log('This can only be run from a CLI, if you can access this from a web browser your configuration is bad.');
exit;
foreach ($migrator->getNotes() as $note) { }
echo strip_tags($note) . PHP_EOL;
$migrateTargets = MSZ_MIGRATABLE_DATABASES;
$doRollback = isset($argv[1]) && $argv[1] === 'rollback';
$targetDb = isset($argv[$doRollback ? 2 : 1]) ? $argv[$doRollback ? 2 : 1] : null;
if ($targetDb !== null) {
if (array_key_exists($targetDb, $migrateTargets)) {
$migrateTargets = [$targetDb => $migrateTargets[$targetDb]];
} else {
migrate_log('Invalid target database connection.');
exit;
}
}
foreach ($migrateTargets as $db => $path) {
migrate_log("Creating migration manager for '{$db}'...");
$migrationManager = new DatabaseMigrationManager(Database::connection($db), $path);
$migrationManager->setLogger('migrate_log');
if ($doRollback) {
migrate_log("Rolling back last migrations for '{$db}'...");
$migrationManager->rollback();
} else {
migrate_log("Running migrations for '{$db}'...");
$migrationManager->migrate();
}
$errors = $migrationManager->getErrors();
$errorCount = count($errors);
if ($errorCount < 1) {
migrate_log('Completed with no errors!');
} else {
migrate_log(PHP_EOL . "There were {$errorCount} errors during the migrations...");
foreach ($errors as $error) {
migrate_log($error);
}
}
} }

View file

@ -1,11 +1,15 @@
<?php <?php
/** /**
* Setup script * Setup script
* @todo Move this into a CLI commands system.
*/ */
namespace Misuzu; namespace Misuzu;
if (PHP_SAPI !== 'cli') {
echo 'This can only be run from a CLI, if you can access this from a web browser your configuration is bad.';
exit;
}
use Misuzu\Database; use Misuzu\Database;
require_once __DIR__ . '/misuzu.php'; require_once __DIR__ . '/misuzu.php';

View file

@ -1,5 +1,6 @@
<?php <?php
use Misuzu\Database; use Misuzu\Database;
use Misuzu\DatabaseMigrationManager;
require_once __DIR__ . '/../misuzu.php'; require_once __DIR__ . '/../misuzu.php';
@ -19,6 +20,6 @@ $featuredNews = Database::connection()
LIMIT 3 LIMIT 3
')->fetchAll(); ')->fetchAll();
//var_dump(Database::connection()->query('SHOW SESSION STATUS LIKE "Questions"')->fetch()); //var_dump(Database::connection()->query('SHOW SESSION STATUS LIKE "Questions"')->fetch()['Value']);
echo $app->getTemplating()->render('home.landing', compact('featuredNews')); echo $app->getTemplating()->render('home.landing', compact('featuredNews'));

View file

@ -26,6 +26,7 @@ class Application extends ApplicationBase
*/ */
private const DATABASE_CONNECTIONS = [ private const DATABASE_CONNECTIONS = [
'mysql-main', 'mysql-main',
'mysql-test',
]; ];
/** /**
@ -40,12 +41,6 @@ class Application extends ApplicationBase
*/ */
private $currentUserId = 0; private $currentUserId = 0;
/**
* Database instance.
* @var \Misuzu\DatabaseV1
*/
private $databaseInstance = null;
/** /**
* ConfigManager instance. * ConfigManager instance.
* @var \Misuzu\Config\ConfigManager * @var \Misuzu\Config\ConfigManager
@ -216,45 +211,11 @@ class Application extends ApplicationBase
*/ */
public function startDatabase(): void public function startDatabase(): void
{ {
if (!is_null($this->databaseInstance)) { if (Database::hasInstance()) {
throw new UnexpectedValueException('Database module has already been started.'); throw new UnexpectedValueException('Database module has already been started.');
} }
new Database($this->configInstance, self::DATABASE_CONNECTIONS[0]); new Database($this->configInstance, self::DATABASE_CONNECTIONS[0]);
$this->databaseInstance = new DatabaseV1($this->configInstance, self::DATABASE_CONNECTIONS[0]);
$this->loadDatabaseConnections();
}
/**
* Gets the active database instance.
* @return DatabaseV1
*/
public function getDatabase(): DatabaseV1
{
if (is_null($this->databaseInstance)) {
throw new UnexpectedValueException('Internal database instance is null, did you run startDatabase yet?');
}
return $this->databaseInstance;
}
/**
* Sets up the required database connections defined in the DATABASE_CONNECTIONS constant.
*/
private function loadDatabaseConnections(): void
{
$config = $this->getConfig();
$database = $this->getDatabase();
foreach (self::DATABASE_CONNECTIONS as $name) {
$section = "Database.{$name}";
if (!$config->contains($section)) {
throw new InvalidArgumentException("Database {$name} is not configured.");
}
$database->addConnectionFromConfig($section, $name);
}
} }
/** /**

View file

@ -47,13 +47,18 @@ final class Database
public static function getInstance(): Database public static function getInstance(): Database
{ {
if (!(self::$instance instanceof static)) { if (!self::hasInstance()) {
throw new \UnexpectedValueException('No instance of Database exists yet.'); throw new \UnexpectedValueException('No instance of Database exists yet.');
} }
return self::$instance; return self::$instance;
} }
public static function hasInstance(): bool
{
return self::$instance instanceof static;
}
public function __construct( public function __construct(
ConfigManager $config, ConfigManager $config,
string $default = 'default' string $default = 'default'

View file

@ -0,0 +1,237 @@
<?php
namespace Misuzu;
use Exception;
use PDO;
use PDOException;
final class DatabaseMigrationManager
{
private $targetConnection;
private $migrationStorage;
private const MIGRATION_NAMESPACE = '\\Misuzu\\DatabaseMigrations\\%s\\%s';
private $errors = [];
private $logFunction;
public function __construct(PDO $conn, string $path)
{
$this->targetConnection = $conn;
$this->migrationStorage = realpath($path);
}
private function addError(Exception $exception): void
{
$this->errors[] = $exception;
$this->writeLog($exception->getMessage());
}
public function setLogger(callable $logger): void
{
$this->logFunction = $logger;
}
private function writeLog(string $log): void
{
if (!is_callable($this->logFunction)) {
return;
}
call_user_func($this->logFunction, $log);
}
public function getErrors(): array
{
return $this->errors;
}
private function getMigrationScripts(): array
{
if (!file_exists($this->migrationStorage) || !is_dir($this->migrationStorage)) {
$this->addError(new Exception('Migrations script directory does not exist.'));
return [];
}
$files = glob(rtrim($this->migrationStorage, '/\\') . '/*.php');
return $files;
}
private function createMigrationRepository(): bool
{
try {
$this->targetConnection->exec('
CREATE TABLE IF NOT EXISTS `msz_migrations` (
`migration_id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
`migration_name` VARCHAR(255) NOT NULL,
`migration_batch` INT(11) UNSIGNED NOT NULL,
PRIMARY KEY (`migration_id`),
UNIQUE INDEX (`migration_id`)
)
');
} catch (PDOException $ex) {
$this->addError($ex);
return false;
}
return true;
}
public function migrate(): bool
{
$this->writeLog('Running migrations...');
if (!$this->createMigrationRepository()) {
return false;
}
$migrationScripts = $this->getMigrationScripts();
if (count($migrationScripts) < 1) {
if (count($this->errors) > 0) {
return false;
}
$this->writeLog('Nothing to migrate!');
return true;
}
try {
$this->writeLog('Fetching completed migration...');
$fetchStatus = $this->targetConnection->prepare("
SELECT *, CONCAT(:basepath, '/', `migration_name`, '.php') as `migration_path`
FROM `msz_migrations`
");
$fetchStatus->bindValue('basepath', $this->migrationStorage);
$migrationStatus = $fetchStatus->execute() ? $fetchStatus->fetchAll() : [];
} catch (PDOException $ex) {
$this->addError($ex);
return false;
}
if (count($migrationStatus) < 1 && count($this->errors) > 0) {
return false;
}
$remainingMigrations = array_diff($migrationScripts, array_column($migrationStatus, 'migration_path'));
if (count($remainingMigrations) < 1) {
$this->writeLog('Nothing to migrate!');
return true;
}
$batchNumber = $this->targetConnection->query('
SELECT COALESCE(MAX(`migration_batch`), 0) + 1
FROM `msz_migrations`
')->fetchColumn();
$recordMigration = $this->targetConnection->prepare('
INSERT INTO `msz_migrations`
(`migration_name`, `migration_batch`)
VALUES
(:name, :batch)
');
$recordMigration->bindValue('batch', $batchNumber);
foreach ($remainingMigrations as $migration) {
$filename = pathinfo($migration, PATHINFO_FILENAME);
$filenameSplit = explode('_', $filename);
$recordMigration->bindValue('name', $filename);
$migrationName = '';
if (count($filenameSplit) < 5) {
$this->addError(new Exception("Invalid migration name: '{$filename}'"));
return false;
}
for ($i = 4; $i < count($filenameSplit); $i++) {
$migrationName .= ucfirst(strtolower($filenameSplit[$i]));
}
include_once $migration;
$this->writeLog("Running migration '{$filename}'...");
$migrationFunction = sprintf(self::MIGRATION_NAMESPACE, $migrationName, 'migrate_up');
$migrationFunction($this->targetConnection);
$recordMigration->execute();
}
$this->writeLog('Successfully completed all migrations!');
return true;
}
public function rollback(): bool
{
$this->writeLog('Rolling back last migration batch...');
if (!$this->createMigrationRepository()) {
return false;
}
try {
$fetchStatus = $this->targetConnection->prepare("
SELECT *, CONCAT(:basepath, '/', `migration_name`, '.php') as `migration_path`
FROM `msz_migrations`
WHERE `migration_batch` = (
SELECT MAX(`migration_batch`)
FROM `msz_migrations`
)
");
$fetchStatus->bindValue('basepath', $this->migrationStorage);
$migrations = $fetchStatus->execute() ? $fetchStatus->fetchAll() : [];
} catch (PDOException $ex) {
$this->addError($ex);
return false;
}
if (count($migrations) < 1) {
if (count($this->errors) > 0) {
return false;
}
$this->writeLog('Nothing to roll back!');
return true;
}
$migrationScripts = $this->getMigrationScripts();
if (count($migrationScripts) < count($migrations)) {
$this->addError(new Exception('There are missing migration scripts!'));
return false;
}
$removeRecord = $this->targetConnection->prepare('
DELETE FROM `msz_migrations`
WHERE `migration_id` = :id
');
foreach ($migrations as $migration) {
if (!file_exists($migration['migration_path'])) {
$this->addError(new Exception("Migration '{$migration['migration_name']}' does not exist."));
return false;
}
$nameSplit = explode('_', $migration['migration_name']);
$migrationName = '';
for ($i = 4; $i < count($nameSplit); $i++) {
$migrationName .= ucfirst(strtolower($nameSplit[$i]));
}
include_once $migration['migration_path'];
$this->writeLog("Rolling '{$migration['migration_name']}' back...");
$migrationFunction = sprintf(self::MIGRATION_NAMESPACE, $migrationName, 'migrate_down');
$migrationFunction($this->targetConnection);
$removeRecord->bindValue('id', $migration['migration_id']);
$removeRecord->execute();
}
$this->writeLog('Successfully completed all rollbacks');
return true;
}
}

View file

@ -1,174 +0,0 @@
<?php
namespace Misuzu;
use Illuminate\Database\Capsule\Manager as LaravelDatabaseManager;
use Misuzu\Config\ConfigManager;
use InvalidArgumentException;
/**
* Class Database
* @package Misuzu
*/
class DatabaseV1 extends LaravelDatabaseManager
{
/**
* @var ConfigManager
*/
private $configManager;
/**
* Array of supported abstraction layers, primarily depends on what Illuminate\Database supports in reality.
*/
private const SUPPORTED_DB_ALS = [
'mysql',
'sqlite',
'pgsql',
'sqlsrv',
];
/**
* The default port for MySQL.
*/
private const DEFAULT_PORT_MYSQL = 3306;
/**
* The default port for PostgreSQL.
*/
private const DEFAULT_PORT_PGSQL = 5432;
/**
* Default port for Microsoft SQL Server.
*/
private const DEFAULT_PORT_MSSQL = 1433;
/**
* Default hostname.
*/
private const DEFAULT_HOST = '127.0.0.1';
/**
* Database constructor.
* @param ConfigManager $config
* @param string $default
* @param bool $startEloquent
* @param bool $setAsGlobal
*/
public function __construct(
ConfigManager $config,
string $default = 'default',
bool $startEloquent = true,
bool $setAsGlobal = true
) {
$this->configManager = $config;
parent::__construct();
$this->container['config']['database.default'] = $default;
if ($startEloquent) {
$this->bootEloquent();
}
if ($setAsGlobal) {
$this->setAsGlobal();
}
}
/**
* Creates a new connection using a ConfigManager instance.
* @param string $section
* @param string $name
*/
public function addConnectionFromConfig(string $section, string $name = 'default'): void
{
if (!$this->configManager->contains($section, 'driver')) {
throw new InvalidArgumentException('Config section not found!');
}
$driver = $this->configManager->get($section, 'driver');
if (!in_array($driver, self::SUPPORTED_DB_ALS)) {
throw new InvalidArgumentException('Unsupported driver.');
}
$args = [
'driver' => $driver,
'database' => $this->configManager->get($section, 'database', 'string', 'misuzu'),
'prefix' => $this->configManager->contains($section, 'prefix')
? $this->configManager->get($section, 'prefix', 'string')
: '',
];
switch ($driver) {
case 'mysql':
$is_unix_socket = $this->configManager->contains($section, 'unix_socket');
$args['host'] = $is_unix_socket
? ''
: $this->configManager->get($section, 'host', 'string', self::DEFAULT_HOST);
$args['port'] = $is_unix_socket
? self::DEFAULT_PORT_MYSQL
: $this->configManager->get($section, 'port', 'int', self::DEFAULT_PORT_MYSQL);
$args['username'] = $this->configManager->get($section, 'username', 'string');
$args['password'] = $this->configManager->get($section, 'password', 'string');
$args['unix_socket'] = $is_unix_socket
? $this->configManager->get($section, 'unix_socket', 'string')
: '';
// these should probably be locked to these types
$args['charset'] = $this->configManager->contains($section, 'charset')
? $this->configManager->get($section, 'charset', 'string')
: 'utf8mb4';
$args['collation'] = $this->configManager->contains($section, 'collation')
? $this->configManager->get($section, 'collation', 'string')
: 'utf8mb4_bin';
$args['strict'] = false; // breaks mysql 8
$args['engine'] = null;
break;
case 'pgsql':
$is_unix_socket = $this->configManager->contains($section, 'unix_socket');
$args['host'] = $is_unix_socket
? ''
: $this->configManager->get($section, 'host', 'string', self::DEFAULT_HOST);
$args['port'] = $is_unix_socket
? self::DEFAULT_PORT_PGSQL
: $this->configManager->get($section, 'port', 'int', self::DEFAULT_PORT_PGSQL);
$args['username'] = $this->configManager->get($section, 'username', 'string');
$args['password'] = $this->configManager->get($section, 'password', 'string');
$args['unix_socket'] = $is_unix_socket
? $this->configManager->get($section, 'unix_socket', 'string')
: '';
// these should probably be locked to these types
$args['charset'] = $this->configManager->contains($section, 'charset')
? $this->configManager->get($section, 'charset', 'string')
: 'utf8';
$args['schema'] = 'public';
$args['sslmode'] = 'prefer';
break;
case 'sqlsrv':
$args['host'] = $this->configManager->get($section, 'host', 'string', self::DEFAULT_HOST);
$args['port'] = $this->configManager->get($section, 'port', 'int', self::DEFAULT_PORT_MSSQL);
$args['username'] = $this->configManager->get($section, 'username', 'string');
$args['password'] = $this->configManager->get($section, 'password', 'string');
// these should probably be locked to these types
$args['charset'] = $this->configManager->contains($section, 'charset')
? $this->configManager->get($section, 'charset', 'string')
: 'utf8';
break;
}
$this->addConnection($args, $name);
}
}

View file

@ -190,11 +190,6 @@ function crop_image_centred(Imagick $image, int $target_width, int $target_heigh
return $image->deconstructImages(); return $image->deconstructImages();
} }
function create_pagination($paginator)
{
return \Illuminate\Pagination\UrlWindow::make($paginator);
}
function running_on_windows(): bool function running_on_windows(): bool
{ {
return starts_with(strtolower(PHP_OS), 'win'); return starts_with(strtolower(PHP_OS), 'win');
@ -206,11 +201,6 @@ function first_paragraph(string $text, string $delimiter = "\n"): string
return $index === false ? $text : mb_substr($text, 0, $index); return $index === false ? $text : mb_substr($text, 0, $index);
} }
function is_valid_page(\Illuminate\Pagination\LengthAwarePaginator $paginator, int $attemptedPage): bool
{
return $attemptedPage >= 1 && $attemptedPage <= $paginator->lastPage();
}
function pdo_prepare_array_update(array $keys, bool $useKeys = false, string $format = '%s'): string function pdo_prepare_array_update(array $keys, bool $useKeys = false, string $format = '%s'): string
{ {
return pdo_prepare_array($keys, $useKeys, sprintf($format, '`%1$s` = :%1$s')); return pdo_prepare_array($keys, $useKeys, sprintf($format, '`%1$s` = :%1$s'));