Compare commits

..

1 Commits

Author SHA1 Message Date
Luca ee002b9609 Fix deprecation error 2023-06-25 14:21:00 +02:00
819 changed files with 25554 additions and 40066 deletions

View File

@ -13,7 +13,7 @@ insert_final_newline = true
trim_trailing_whitespace = true
max_line_length = 120
[{.babelrc,package.json,.eslintrc.json,.prettierrc.json}]
[{.babelrc,package.json}]
indent_size = 2
[docker/**.conf]
@ -27,8 +27,6 @@ max_line_length = unset
indent_size = 2
[*.js]
indent_size = 2
max_line_length = unset
quote_type = single
[{LICENSE,db/*.sql}]

View File

@ -1,3 +0,0 @@
/public
/node_modules
/vendor

View File

@ -1,10 +0,0 @@
{
"parser": "@babel/eslint-parser",
"extends": ["plugin:editorconfig/all", "prettier"],
"plugins": ["editorconfig"],
"rules": {
"prefer-arrow-callback": "error",
"prefer-template": "error",
"no-var": "error"
}
}

5
.gitignore vendored
View File

@ -26,10 +26,8 @@ _vimrc_local.vim
# Project files
/config/config.php
/config/lang/
/public/*.xml
/public/coverage
/test/coverage
/public/coverage
/coverage
/unittests.xml
/resources/lang/*/*.mo
@ -42,4 +40,3 @@ _vimrc_local.vim
/public/assets
/package-lock.json
/yarn-error.log
/.yarn-cache

View File

@ -12,7 +12,6 @@ variables:
DOCROOT: /var/www/
stages:
- prepare
- validate
- build
- test
@ -21,90 +20,44 @@ stages:
- deploy-production
- stop
.use_cache: &use_cache
cache:
key: "$CI_JOB_NAME-$CI_COMMIT_REF_SLUG"
paths:
- .yarn-cache/
- vendor/
# for jobs that depend on composer
.use_composer: &use_composer
<<: *use_cache
needs:
- composer install
before_script:
- composer install --no-ansi --no-progress
# for jobs that depend on yarn
.use_yarn: &use_yarn
<<: *use_cache
needs:
- yarn install
before_script:
- yarn install --check-frontend --cache-folder .yarn-cache
#
# Preparation
# Validation
#
composer validate:
check-style:
image: composer:latest
stage: prepare
stage: validate
before_script:
- composer --no-ansi global config --no-plugins allow-plugins.dealerdirect/phpcodesniffer-composer-installer true
- composer --no-ansi global require slevomat/coding-standard squizlabs/php_codesniffer
- export PATH=$PATH:$COMPOSER_HOME/vendor/bin
script:
- phpcs -p --no-colors --basepath="$PWD"
check-editorconfig:
image: mstruebing/editorconfig-checker
stage: validate
script:
- ec -v
validate-composer:
image: composer:latest
stage: validate
script:
- composer --no-ansi validate --strict
composer install:
<<: *use_cache
image: composer:latest
stage: prepare
needs:
- composer audit
- composer validate
script:
- composer install --no-ansi --no-progress
composer audit:
image: php:latest
stage: prepare
needs:
- composer validate
before_script:
- curl -Ls https://github.com/symfony/cli/releases/latest/download/symfony_linux_amd64.gz | gzip -d > /bin/symfony
- chmod +x /bin/symfony
script:
- symfony check:security --no-ansi
yarn-validate:
validate-yarn:
image: node:alpine
stage: prepare
stage: validate
before_script:
- yarn global add package-json-validator
- export PATH=$PATH:~/.yarn/bin
script:
- pjv
yarn install:
<<: *use_cache
image: node:alpine
stage: prepare
needs:
- yarn-validate
- yarn audit
script:
- yarn install --check-frontend --cache-folder .yarn-cache
yarn audit:
image: node:alpine
stage: prepare
needs:
- yarn-validate
script:
- yarn audit
generate-version:
image: alpine
stage: prepare
stage: validate
artifacts:
name: "${CI_JOB_NAME}_${CI_JOB_ID}_version"
expire_in: 1 day
@ -113,64 +66,10 @@ generate-version:
before_script:
- apk add -q git
script:
- >
VERSION="$(\
git describe --exact-match --tags HEAD 2> /dev/null\
|| (\
(git describe --abbrev=0 --tags | tr -d '\n')\
&& echo "-${CI_COMMIT_REF_NAME}+${CI_PIPELINE_ID}.${CI_COMMIT_SHORT_SHA}"\
)\
)"
- VERSION="$(git describe --abbrev=0 --tags)-${CI_COMMIT_REF_NAME}+${CI_PIPELINE_ID}.${CI_COMMIT_SHORT_SHA}"
- echo "${VERSION}"
- echo -n "${VERSION}" > storage/app/VERSION
#
# Validation
#
phpcs:
<<: *use_composer
image: composer:latest
stage: validate
script:
# tell phpcs the PHP version to check against
# we are using the min suppported version here
- ./vendor/bin/phpcs --config-set php_version 80100
- ./vendor/bin/phpcs -p --no-colors --basepath="$PWD"
phpstan:
<<: *use_composer
image: composer:latest
stage: validate
script:
- ./vendor/bin/phpstan --no-progress
yarn check:
<<: *use_yarn
image: node:alpine
stage: validate
script:
- yarn check
yarn lint:
<<: *use_yarn
image: node:alpine
stage: validate
script:
# Install git, so that tools can use .gitignore.
# Not done in before_script because of <<: *use_yarn.
- apk add --no-cache git
- yarn lint
translations lint:
image: alpine
stage: prepare
before_script:
- apk add gettext
script:
- find resources/lang -type f -name '*.po' -exec sh -c 'msgfmt "${1%.*}.po" -o"${1%.*}.mo"' shell {} \;
- '[[ $(find resources/lang -type f -name "*.po" | wc -l) == $(find resources/lang -type f -name "*.mo" | wc -l) ]]'
#
# Build
#
@ -188,25 +87,39 @@ build-image:
<<: *container_definition
stage: build
needs:
- phpcs
- phpstan
- composer validate
- yarn check
- yarn lint
- translations lint
- check-editorconfig
- check-style
- generate-version
- validate-composer
- validate-yarn
dependencies:
- generate-version
script:
- /kaniko/executor --context ${CI_PROJECT_DIR}
--dockerfile ${CI_PROJECT_DIR}/docker/Dockerfile
--destination "${TEST_IMAGE}"
--cache=true
#
# Test
#
audit-composer:
image: php:latest
stage: test
needs: [ ]
before_script:
- curl -Ls https://github.com/symfony/cli/releases/latest/download/symfony_linux_amd64.gz | gzip -d > /bin/symfony
- chmod +x /bin/symfony
script:
- symfony check:security --no-ansi
audit-yarn:
image: node:alpine
stage: test
needs: [ ]
script:
- yarn audit
test:
image:
name: ${TEST_IMAGE}
@ -235,11 +148,10 @@ test:
- ./bin/migrate
script:
- >-
php -d memory_limit=1024M -d pcov.enabled=1 -d pcov.directory=. vendor/bin/phpunit -vvv --colors=never
php -d pcov.enabled=1 -d pcov.directory=. vendor/bin/phpunit -vvv --colors=never
--coverage-text --coverage-html "${HOMEDIR}/coverage/"
--log-junit "${HOMEDIR}/unittests.xml"
after_script:
- sed -i 's~/var/www/~~' unittests.xml
- '"${DOCROOT}/bin/migrate" down'
dump-database:
@ -260,9 +172,6 @@ dump-database:
- cd "${DOCROOT}"
- ./bin/migrate
script:
- >-
mysql -h "${MYSQL_HOST}" -u "${MYSQL_USER}" -p"${MYSQL_PASSWORD}" "${MYSQL_DATABASE}"
-e 'UPDATE users SET api_key="" WHERE name="admin"'
- >-
mysqldump -h "${MYSQL_HOST}" -u "${MYSQL_USER}" -p"${MYSQL_PASSWORD}" "${MYSQL_DATABASE}"
> "${HOMEDIR}/initial-install.sql"
@ -292,11 +201,7 @@ release-image:
- test
dependencies: [ ]
script:
- echo -e "FROM ${TEST_IMAGE}"
| /kaniko/executor
--dockerfile /dev/stdin
--destination "${RELEASE_IMAGE}"
--cache=true
- echo -e "FROM ${TEST_IMAGE}" | /kaniko/executor --dockerfile /dev/stdin --destination "${RELEASE_IMAGE}"
only:
- main
@ -313,8 +218,8 @@ build-release-file:
stage: release
needs:
- build-image
- yarn audit
- composer audit
- audit-yarn
- audit-composer
- test
- dump-database
- generate-assets
@ -369,7 +274,6 @@ deploy:
dependencies: *deploy_needs
environment:
name: rsync-staging
deployment_tier: development
only:
- main
script:
@ -392,10 +296,7 @@ deploy:
- test
- build-image
before_script:
- &kubectl_deployment_script |-
if [[ -z "${KUBE_INGRESS_BASE_DOMAIN}" ]]; then echo "Skipping deployment"; exit; fi
if [[ -n "${KUBE_CONTEXT}" ]]; then kubectl config use-context "${KUBE_CONTEXT}"; fi
if [[ -z "${KUBE_NAMESPACE}" ]]; then export KUBE_NAMESPACE=${CI_PROJECT_PATH_SLUG}-${CI_ENVIRONMENT_SLUG}; fi
- &kubectl_deployment_script if [[ -z "${KUBE_INGRESS_BASE_DOMAIN}" ]]; then echo "Skipping deployment"; exit; fi
.deploy_k8s: &deploy_k8s
<<: *kubectl_deployment
@ -410,12 +311,8 @@ deploy:
# CI_ENVIRONMENT_URL is the URL configured in the GitLab environment
- export CI_ENVIRONMENT_URL="${CI_ENVIRONMENT_URL:-https://${CI_PROJECT_PATH_SLUG}.${KUBE_INGRESS_BASE_DOMAIN}/}"
- export CI_IMAGE=$RELEASE_IMAGE
- export CI_INGRESS_CLASS=${CI_INGRESS_CLASS:-traefik}
- export CI_INGRESS_MATCH=${CI_INGRESS_MATCH:-$( if [[ "$CI_INGRESS_CLASS" == "nginx" ]]; then echo '/?(.*)'; fi )}
- export CI_INGRESS_TRAEFIK_ENTRYPOINT=${CI_INGRESS_TRAEFIK_ENTRYPOINT:-websecure}
- export CI_INGRESS_DOMAIN=$(echo "$CI_ENVIRONMENT_URL" | grep -oP '(?:https?://)?\K([^/]+)' | head -n1)
- export CI_INGRESS_PATH=$(echo "$CI_ENVIRONMENT_URL" | grep -oP '(?:https?://)?(?:[^/])+\K(.*)')
- '[[ "${CI_INGRESS_PATH}" == /* ]] || export CI_INGRESS_PATH="/${CI_INGRESS_PATH}"'
- export CI_KUBE_NAMESPACE=$KUBE_NAMESPACE
# Any available storage class like default, local-path (if you know what you are doing ;), longhorn etc.
- export CI_PVC_SC=${CI_PVC_SC:-"${CI_PVC_SC_LOCAL:-local-path}"}
@ -424,24 +321,19 @@ deploy:
- export CI_CLUSTER_ISSUER=${CI_CLUSTER_ISSUER:-letsencrypt}
- export CI_SETUP_ADMIN_PASSWORD=${CI_SETUP_ADMIN_PASSWORD}
- echo "Generating config"
- cp deployment.tpl.yaml deployment.yaml
- >-
for env in ${!CI_*}; do
sed -i "s#<${env}>#$( echo "${!env}" | head -n1 | sed -e 's~\\~\\\\~' -e 's~#~\\#~' )#g" deployment.yaml;
done
- echo "Checking namespace ${CI_KUBE_NAMESPACE}"
- kubectl get namespace "${CI_KUBE_NAMESPACE}" > /dev/null 2>&1 || kubectl create namespace "${CI_KUBE_NAMESPACE}"
- echo "Deploying to ${CI_ENVIRONMENT_URL}"
- kubectl -n "${CI_KUBE_NAMESPACE}" diff -f deployment.yaml || true
- kubectl -n "${CI_KUBE_NAMESPACE}" apply -f deployment.yaml
- kubectl apply -f deployment.yaml
- >-
kubectl -n "${CI_KUBE_NAMESPACE}" wait --for=condition=Ready pods --timeout=${CI_WAIT_TIMEOUT:-5}m
kubectl -n $CI_KUBE_NAMESPACE wait --for=condition=Ready pods --timeout=${CI_WAIT_TIMEOUT:-5}m
-l app=$CI_PROJECT_PATH_SLUG -l tier=database
- >-
kubectl -n "${CI_KUBE_NAMESPACE}" wait --for=condition=Ready pods --timeout=${CI_WAIT_TIMEOUT:-5}m
kubectl -n $CI_KUBE_NAMESPACE wait --for=condition=Ready pods --timeout=${CI_WAIT_TIMEOUT:-5}m
-l app=$CI_PROJECT_PATH_SLUG -l tier=application -l commit=$CI_COMMIT_SHORT_SHA
.deploy_k8s_stop: &deploy_k8s_stop
@ -452,8 +344,7 @@ deploy:
GIT_STRATEGY: none
when: manual
script:
- TARGETS=all,ingress,pvc,certificate
- kubectl -n "${KUBE_NAMESPACE}" delete $TARGETS -l app=$CI_PROJECT_PATH_SLUG -l environment=$CI_ENVIRONMENT_SLUG
- kubectl delete all,ingress,pvc -l app=$CI_PROJECT_PATH_SLUG -l environment=$CI_ENVIRONMENT_SLUG
deploy-k8s-review:
<<: *deploy_k8s
@ -462,7 +353,6 @@ deploy-k8s-review:
on_stop: stop-k8s-review
auto_stop_in: 1 week
url: https://${CI_PROJECT_PATH_SLUG}-review.${KUBE_INGRESS_BASE_DOMAIN}/${CI_COMMIT_REF_SLUG}
deployment_tier: development
variables:
CI_REPLICAS_REVIEW: 1
CI_APP_NAME: review/${CI_COMMIT_REF_NAME}
@ -476,7 +366,6 @@ stop-k8s-review:
environment:
name: review/${CI_COMMIT_REF_NAME}
action: stop
deployment_tier: development
#
# Deploy production
@ -487,8 +376,8 @@ deploy-production:
stage: deploy-production
needs:
- test
- yarn audit
- composer audit
- audit-yarn
- audit-composer
- build-image
- generate-assets
dependencies:
@ -496,7 +385,6 @@ deploy-production:
- generate-assets
environment:
name: rsync-production
deployment_tier: production
when: manual
only:
- main
@ -516,8 +404,8 @@ deploy-k8s-production:
stage: deploy-production
needs:
- release-image
- yarn audit
- composer audit
- audit-yarn
- audit-composer
environment:
name: production
on_stop: stop-k8s-production

View File

@ -4,11 +4,9 @@
<file>config</file>
<file>db</file>
<file>includes</file>
<file>public/index.php</file>
<file>src</file>
<file>tests</file>
<exclude-pattern>/config/config.php</exclude-pattern>
<rule ref="PSR12" />
<rule ref="SlevomatCodingStandard.Namespaces.UnusedUses">
@ -21,32 +19,4 @@
<property name="ignoreUnusedValuesWhenOnlyKeysAreUsedInForeach" value="true" />
</properties>
</rule>
<rule ref="Generic.Files.LineLength.TooLong">
<exclude-pattern>/includes</exclude-pattern>
</rule>
<rule ref="SlevomatCodingStandard.TypeHints.ParameterTypeHint">
<exclude-pattern>/includes</exclude-pattern>
<exclude name="SlevomatCodingStandard.TypeHints.ParameterTypeHint.MissingTraversableTypeHintSpecification" />
</rule>
<rule ref="SlevomatCodingStandard.TypeHints.ReturnTypeHint">
<exclude-pattern>/includes</exclude-pattern>
<exclude name="SlevomatCodingStandard.TypeHints.ReturnTypeHint.MissingTraversableTypeHintSpecification" />
</rule>
<rule ref="SlevomatCodingStandard.TypeHints.PropertyTypeHint">
<exclude-pattern>/includes</exclude-pattern>
<exclude name="SlevomatCodingStandard.TypeHints.PropertyTypeHint.MissingTraversableTypeHintSpecification" />
</rule>
<rule ref="SlevomatCodingStandard.Classes.RequireConstructorPropertyPromotion" />
<rule ref="SlevomatCodingStandard.Commenting.EmptyComment" />
<rule ref="SlevomatCodingStandard.Commenting.UselessFunctionDocComment" />
<rule ref="Generic.Formatting.SpaceAfterCast" />
<rule ref="SlevomatCodingStandard.Arrays.TrailingArrayComma"/>
<rule ref="SlevomatCodingStandard.Arrays.SingleLineArrayWhitespace"/>
<rule ref="Squiz.Strings.DoubleQuoteUsage" />
<rule ref="SlevomatCodingStandard.TypeHints.DeclareStrictTypes">
<exclude-pattern>/includes</exclude-pattern>
<properties>
<property name="spacesCountAroundEqualsSign" value="0" />
</properties>
</rule>
</ruleset>

View File

@ -1,5 +0,0 @@
{
"printWidth": 120,
"tabWidth": 2,
"singleQuote": true
}

View File

@ -2,30 +2,12 @@
## Coding guide lines
* Make sure your code follows the [PSR-12](https://www.php-fig.org/psr/psr-12/) code style and is [.editorconfig](.editorconfig) valid.
You may use `composer run phpcs` and [Editorconfig-Checker](https://editorconfig-checker.github.io) to verify that.
* You should use an [editorconfig plugin for your editor](https://editorconfig.org/#pre-installed) for automatic basic code formatting.
* Use `use` statements wherever possible instead of writing the fully qualified name.
* Code must pass PHPStan checks (`composer phpstan`)
* Order the composer/npm dependencies alphabetically.
* Do not use code from the [includes](includes) directory anywhere else.
* Don't refactor [includes](includes) code just for the sake of change, it is legacy code that must only be replaced.
* Please cover your code by unit tests, our goal is to stay at 100% line coverage.
Code under `includes` does not require tests as it's mostly not testable and needs to be rewritten.
* Do not use code from the [includes](./includes) directory anywhere else.
* Please cover your code by unit tests. Code under `includes` does not require tests.
* Do not use vendor prefixes like `-webkit` in styles.
This is done by PostCSS + Autoprefixer according to the [`.browserslistrc`](.browserslistrc).
* Translations must be abbreviated, for example `form.save`.
The `default.po` files contain translations that can be auto-detected using Poedit, `additional.po` contains generated messages like validations.
* JavaScript code must pass the checks `yarn lint`.
Auto-fixing is supported via `yarn lint:fix`.
* Don't put function calls in a template-literal (template-strings).
This is done by PostCSS + Autoprefixer according to the [`.browserslistrc`](./.browserslistrc).
## Pull requests
* The PR should contain a short overview of the changes.
* Before implementing bigger changes, please open an issue to discuss the feature and possible implementation options.
* Please create single pull requests for every feature instead of creating one big monster of pull request containing a complete rewrite.
* Squash similar commits to make the review easier.
* For visual changes, include both before and after screenshots to easily compare and discuss changes.
## Commits
* The commit message must be meaningful. It should serve as a short overview of the changes.
If needed, an additional description can be provided.
* A commit should be self-contained and result in a working Engelsystem.
Please create single pull requests for every feature instead of creating one big monster of pull request containing a complete rewrite.

View File

@ -8,95 +8,7 @@ Please also read the [CONTRIBUTING.md](CONTRIBUTING.md).
* Yarn (Development/Building only)
* PHP Composer (Development/Building only)
## Code style
Please ensure that your pull requests follow the [PSR-12](https://www.php-fig.org/psr/psr-12/) coding style guide.
You can check that by running
```bash
composer run phpcs
# with docker
docker exec engelsystem_dev-es_workspace-1 composer run phpcs
```
You may auto fix reported issues by running
```bash
composer run phpcbf
# with docker
docker exec engelsystem_dev-es_workspace-1 composer run phpcbf
```
## Pre-commit hooks
You should set up the pre-commit hook to check the code style and run tests on commit:
Docker (recommended):
```sh
echo "docker exec engelsystem_dev-es_workspace-1 bin/pre-commit" > .git/hooks/pre-commit
chmod u+x .git/hooks/pre-commit
```
Host machine:
```sh
ln -s ../../bin/pre-commit .git/hooks/pre-commit
```
## Docker
We suggest using Docker for the Development local build.
If unspecific issues appear try using Docker version >= 20.10.14.
This repo [ships a docker setup](docker/dev) for a quick development start.
If you use another uid/gid than 1000 on your machine you have to adjust it in [docker/dev/.env](docker/dev/.env).
Run this once
```bash
cd docker/dev
docker compose up
```
Run these commands once initially and then as required after changes
```bash
# Install composer dependencies
docker compose exec es_workspace composer i
# Install node packages
docker compose exec es_workspace yarn install
# Run a full front-end build
docker compose exec es_workspace yarn build
# Or run a front-end build for specific themes only, e.g.
docker compose exec -e THEMES=0,1 es_workspace yarn build
# Update the translation files
docker compose exec es_workspace find /var/www/resources/lang -type f -name '*.po' -exec sh -c 'msgfmt "${1%.*}.po" -o"${1%.*}.mo"' shell {} \;
# Run the migrations
docker compose exec es_workspace bin/migrate
```
While developing you may use the watch mode to rebuild the system on changes
```bash
# Run a front-end build and update on change
docker compose exec es_workspace yarn build:watch
# Or run a front-end build and update on change for specific themes only, e.g.
docker compose exec -e THEMES=0,1 es_workspace yarn build:watch
```
It might also be useful to have an interactive database interface for which a phpMyAdmin instance can be startet at [http://localhost:8888](http://localhost:8888).
```bash
docker compose --profile dev up
```
## Localhost
You can find your local Engelsystem on [http://localhost:5080](http://localhost:5080).
## Local build without Docker
## Local build
The following instructions explain how to get, build and run the latest Engelsystem version directly from the git main branch (may be unstable!).
* Clone the main branch: `git clone https://github.com/engelsystem/engelsystem.git`
@ -123,51 +35,36 @@ The following instructions explain how to get, build and run the latest Engelsys
```
* Generate translation files
```bash
find resources/lang/ -type f -name '*.po' -exec sh -c 'msgfmt "${1%.*}.po" -o"${1%.*}.mo"' shell {} \;
find resources/lang/ -type f -name '*.po' -exec sh -c 'file="{}"; msgfmt "${file%.*}.po" -o "${file%.*}.mo"' \;
```
## Testing
To run only unit tests (tests that should not change the Engelsystem state) use
To run the unit tests use
```bash
vendor/bin/phpunit --testsuite Unit
```
```
If a database is configured and the Engelsystem is allowed to mess around with some files, you can run feature tests.
The tests can potentially delete some database entries, so they should never be run on a production system!
```bash
vendor/bin/phpunit --testsuite Feature
```
When you want to run unit and feature tests at once:
```bash
# or for unit- and feature tests:
vendor/bin/phpunit
```
```
To generate code coverage reports it's highly recommended to use [`pcov`](https://github.com/krakjoe/pcov) or
To run code coverage reports its highly recommended to use [`pcov`](https://github.com/krakjoe/pcov) or
at least `phpdbg -qrr`(which has problems with switch case statements) as using Xdebug slows down execution.
```bash
php -d pcov.enabled=1 -d pcov.directory=. vendor/bin/phpunit --coverage-text
php -d pcov.enabled=1 -d pcov.directory=. vendor/bin/phpunit --testsuite Unit --coverage-text
```
For better debug output, adding `-vvv` might be helpful.
Adding `--coverage-html public/coverage/` exports the coverage reports to the `public/` dir which then can be viewed at [localhost:5080/coverage/index.html](http://localhost:5080/coverage/index.html).
### Docker
If using the Docker-based development environment you can run the following script to retrieve a coverage report.
```sh
docker compose exec es_workspace composer phpunit:coverage
```
A browsable HTML version is available at http://localhost:5080/coverage/index.html .
### Var Dump server
Symfony Var Dump server is configured to allow for easier debugging. It is not meant as a replacement for xdebug but can actually be used together with xdebug.
The Var Dump Server is especially useful if you want to debug a request without messing up the output e.g. of API calls or the HTML layout.
This Var Dump Server is especially useful for when you want to debug a request without messing up the output e.g API calls ot HTML layout.
To use simply call the method `dump` and pass the arguments in exactly the same way you would when using `var_dump`.
This will send the output to the Var Dump server which can be viewed in the terminal.
This will send the output to the Var Dump server which can be viewed in the terminal.
This does however require that you start the var-dump-server otherwise the output will be printed in your browser
You can also `dump` and `die` if you wish to not let your code continue any further by calling the `dd` method
@ -177,7 +74,7 @@ To view the output of `dump` call the following commands:
```bash
vendor/bin/var-dump-server
# or for running in docker
docker compose exec es_server vendor/bin/var-dump-server
docker-compose exec es_server vendor/bin/var-dump-server
```
For more information check out the Var Dump Server documentation: [Symfony VarDumper](https://symfony.com/components/VarDumper)
@ -186,6 +83,16 @@ For more information check out the Var Dump Server documentation: [Symfony VarDu
We use gettext. You may use POEdit to extract new texts from the sourcecode.
Please config POEdit to extract also the twig template files using the following settings: https://gist.github.com/jlambe/a868d9b63d70902a12254ce47069d0e6
## Code style
Please ensure that your pull requests follow the [PSR-12](https://www.php-fig.org/psr/psr-12/) coding style guide.
You can check that by running
```bash
composer run phpcs
```
You may auto fix reported issues by running
```bash
composer run phpcbf
```
## CI & Build Pipeline
@ -201,12 +108,51 @@ PRODUCTION_REMOTE # Same as STAGING_REMOTE but for the production environm
PRODUCTION_REMOTE_PATH # Same as STAGING_REMOTE_PATH but for the production environment
```
## Static code analysis
## Docker
You can run a static code analysis with this command:
If unspecific issues appear try using Docker version >= 20.10.14.
This repo [ships a docker setup](docker/dev) for a quick development start.
If you use another uid/gid than 1000 on your machine you have to adjust it in [docker/dev/.env](docker/dev/.env).
Run this once
```bash
composer phpstan
cd docker/dev
docker-compose up
```
Run these commands once initially and then as required after changes
```bash
# Install composer dependencies
docker-compose exec es_workspace composer i
# Install node packages
docker-compose exec es_workspace yarn install
# Run a full front-end build
docker-compose exec es_workspace yarn build
# Or run a front-end build for specific themes only, e.g.
docker-compose exec -e THEMES=0,1 es_workspace yarn build
# Update the translation files
docker-compose exec es_workspace find /var/www/resources/lang -type f -name '*.po' -exec sh -c 'file="{}"; msgfmt "${file%.*}.po" -o "${file%.*}.mo"' \;
# Run the migrations
docker-compose exec es_workspace bin/migrate
```
While developing you may use the watch mode to rebuild the system on changes
```bash
# Run a front-end build and update on change
docker-compose exec es_workspace yarn build:watch
# Or run a front-end build and update on change for specific themes only, e.g.
docker-compose exec -e THEMES=0,1 es_workspace yarn build:watch
```
**Hint for using Xdebug with *PhpStorm***

View File

@ -15,7 +15,7 @@ Please read the [CONTRIBUTING.md](CONTRIBUTING.md) and [DEVELOPMENT.md](DEVELOPM
The Engelsystem may be installed manually or by using the provided [docker setup](#docker).
### Requirements
* PHP >= 8.1
* PHP >= 7.4
* Required modules:
* dom
* json
@ -28,30 +28,21 @@ The Engelsystem may be installed manually or by using the provided [docker setup
* MySQL-Server >= 5.7.8 or MariaDB-Server >= 10.2.2
* Webserver, i.e. lighttpd, nginx, or Apache
From previous experience, 2 cores and 2GB ram are roughly enough for up to 1000 Angels (~700 arrived + 500 arrived but not working) during an event.
### Download
* Go to the [Releases](https://github.com/engelsystem/engelsystem/releases) page and download the latest stable release file.
* Extract the files to your webroot and continue with the directions for configurations and setup.
### Configuration and Setup
* The webserver must have write access to the `storage` directory and read access for all other directories
* The webserver must point to the `public` directory.
* The webserver must read the `.htaccess` file and `mod_rewrite` must be enabled
* The webserver must have write access to the ```storage``` directory and read access for all other directories
* The webserver must point to the ```public``` directory.
* The webserver must read the ```.htaccess``` file and ```mod_rewrite``` must be enabled
* Recommended: Directory Listing should be disabled.
* There must be a MySQL database set up with a user who has full rights to that database.
* If necessary, create a `config/config.php` to override values from `config/config.default.php`.
* To disable/remove values from the following lists, set the value of the entry to `null`:
* `themes`
* `tshirt_sizes`
* `headers`
* `header_items`
* `footer_items`
* `locales`
* `contact_options`
* To import the database, the `bin/migrate` script has to be run. If you can't execute scripts, you can use the `initial-install.sql` file from the release zip.
* In the browser, login with credentials `admin` : `asdfasdf` and change the password.
* If necessary, create a ```config/config.php``` to override values from ```config/config.default.php```.
* To edit values from the `footer_items`, `themes`, `locales`, `tshirt_sizes` or `headers` lists, directly modify the ```config/config.default.php``` file or rename it to ```config/config.php```.
* To import the database, the ```bin/migrate``` script has to be run. If you can't execute scripts, you can use the `initial-install.sql` file from the release zip.
* In the browser, login with credentials ```admin``` : ```asdfasdf``` and change the password.
The Engelsystem can now be used.
@ -64,7 +55,7 @@ The Engelsystem can now be used.
To build the `es_server` container:
```bash
cd docker
docker compose build
docker-compose build
```
or to build the container by its own:
@ -76,14 +67,14 @@ docker build -f docker/Dockerfile . -t es_server
Start the Engelsystem
```bash
cd docker
docker compose up -d
docker-compose up -d
```
#### Set Up / Migrate Database
Create the Database Schema (on a fresh install) or import database changes to migrate it to the newest version
#### Migrate
Import database changes to migrate it to the newest version
```bash
cd docker
docker compose exec es_server bin/migrate
docker-compose exec es_server bin/migrate
```
### Scripts

View File

@ -1,16 +0,0 @@
# Security Policy
## Reporting a Vulnerability
If you want to contact us directly regarding a security concern, please write an e-mail to contact@engelsystem.de and explain your findings.
Thank you!
## Use of external reporting / bug bounty services
We kindly ask you to not use any external reporting / bug bounty service. We do not collaborate with any external service and experiences in the past showed that these services usually add a lot of unnecessary overhead.
Please send security critical bug reports to contact@engelsystem.de.
If you feel like we are not reacting fast enough (generally no more than 14 days should go by until an initial response; This is a volunteer project mostly used internally after all), please feel free to go for full disclosure via our github issue tracker, and tag the issue there by creating a title prefixed with [SECURITY].
If you find a critical vulnerability that warrants a CVE, we will also take care of issuing a CVE without any bug bounty platform having to be involved.

View File

@ -4,9 +4,7 @@
use Composer\Autoload\ClassLoader;
use Engelsystem\Application;
use Engelsystem\Database\Migration\Migrate;
use Engelsystem\Database\Migration\Direction;
use Engelsystem\Database\Migration\MigrationServiceProvider;
use Engelsystem\Environment;
use Engelsystem\Exceptions\Handler;
use Engelsystem\Exceptions\Handlers\NullHandler;
@ -21,7 +19,7 @@ $app->register(MigrationServiceProvider::class);
/** @var Handler $errorHandler */
$errorHandler = $app->get(Handler::class);
$errorHandler->setHandler(Environment::PRODUCTION, new NullHandler());
$errorHandler->setHandler(Handler::ENV_PRODUCTION, new NullHandler());
/** @var Migrate $migration */
$migration = $app->get('db.migration');
@ -34,10 +32,10 @@ if (in_array('help', $argv) || in_array('--help', $argv) || in_array('-h', $argv
exit;
}
$direction = Direction::UP;
$method = Migrate::UP;
if (in_array('down', $argv)) {
$argv = array_values($argv);
$direction = Direction::DOWN;
$method = Migrate::DOWN;
}
$oneStep = false;
@ -50,4 +48,4 @@ if (in_array('force', $argv) || in_array('--force', $argv) || in_array('-f', $ar
$force = true;
}
$migration->run($baseDir, $direction, $oneStep, $force);
$migration->run($baseDir, $method, $oneStep, $force);

View File

@ -1,26 +0,0 @@
#!/usr/bin/env sh
# immediate exit after an error
set -e
testing() {
echo
echo "🔎 Checking ${1}"
}
testing 'JS & CSS 🎨'
yarn check
yarn lint
testing 'PHP ⚙️'
composer validate
composer phpcs
composer phpstan
./vendor/bin/phpunit
testing 'translations 🗺️'
find resources/lang -type f -name '*.po' -exec sh -c 'msgfmt "${1%.*}.po" -o"${1%.*}.mo"' shell {} \;
[ "$(find resources/lang -type f -name '*.po' | wc -l)" -eq "$(find resources/lang -type f -name '*.mo' | wc -l)" ]
find resources/lang -type f -name '*.mo' -exec rm {} \;
echo '✅ Done 🎉'

View File

@ -14,61 +14,47 @@
}
],
"scripts": {
"phpcs:setup": "phpcs --config-set php_version 80100",
"phpcs": [
"composer phpcs:setup",
"phpcs -p --cache"
],
"phpcbf": [
"composer phpcs:setup",
"phpcbf -p"
],
"phpstan": "phpstan",
"phpunit": "phpunit",
"phpunit:coverage": "phpunit --coverage-text --coverage-html ./public/coverage/"
"phpcs": "phpcs -p",
"phpcbf": "phpcbf -p"
},
"require": {
"php": ">=8.1.0",
"php": ">=7.4.0",
"ext-json": "*",
"ext-libxml": "*",
"ext-mbstring": "*",
"ext-pdo": "*",
"ext-simplexml": "*",
"ext-xml": "*",
"doctrine/dbal": "^3.7",
"doctrine/dbal": "^3.2",
"erusev/parsedown": "^1.7",
"gettext/gettext": "^5.7",
"gettext/translator": "^1.2",
"guzzlehttp/guzzle": "^7.8",
"illuminate/container": "^10.38",
"illuminate/database": "^10.38",
"illuminate/support": "^10.38",
"league/oauth2-client": "^2.7",
"league/openapi-psr7-validator": "^0.21",
"gettext/gettext": "^5.6",
"gettext/translator": "^1.0",
"guzzlehttp/guzzle": "^7.4",
"illuminate/container": "^8.76",
"illuminate/database": "^8.76",
"illuminate/support": "^8.76",
"league/oauth2-client": "^2.6",
"nikic/fast-route": "^1.3",
"nyholm/psr7": "^1.8",
"psr/container": "^2.0",
"psr/http-message": "^1.1",
"nyholm/psr7": "^1.4",
"psr/container": "^1.1",
"psr/http-server-middleware": "^1.0",
"psr/log": "^3.0",
"rcrowe/twigbridge": "^0.14.1",
"psr/log": "^1.1",
"rcrowe/twigbridge": "^0.14.0",
"respect/validation": "^1.1",
"symfony/http-foundation": "^6.4",
"symfony/mailer": "^6.4",
"symfony/psr-http-message-bridge": "^2.3",
"twig/twig": "^3.8",
"vlucas/phpdotenv": "^5.6"
"symfony/http-foundation": "^5.4",
"symfony/mailer": "^5.4",
"symfony/psr-http-message-bridge": "^2.1",
"twig/twig": "^3.3",
"vlucas/phpdotenv": "^5.4"
},
"require-dev": {
"dms/phpunit-arraysubset-asserts": "^0.5",
"fakerphp/faker": "^1.23",
"fig/log-test": "^1.1",
"filp/whoops": "^2.15",
"phpstan/phpstan": "^1.10",
"phpunit/phpunit": "^9.6",
"slevomat/coding-standard": "^8.14",
"squizlabs/php_codesniffer": "^3.8",
"symfony/var-dumper": "^6.4"
"dms/phpunit-arraysubset-asserts": "^0.3.1",
"fakerphp/faker": "^1.17",
"filp/whoops": "^2.14",
"phpunit/phpunit": "^9.5",
"slevomat/coding-standard": "^7.1",
"squizlabs/php_codesniffer": "^3.6",
"symfony/var-dumper": "^5.4"
},
"autoload": {
"psr-4": {

3580
composer.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -1,7 +1,5 @@
<?php
declare(strict_types=1);
// Application config
return [
@ -28,6 +26,7 @@ return [
\Engelsystem\Renderer\TwigServiceProvider::class,
\Engelsystem\Middleware\RouteDispatcherServiceProvider::class,
\Engelsystem\Middleware\RequestHandlerServiceProvider::class,
\Engelsystem\Middleware\SessionHandlerServiceProvider::class,
\Engelsystem\Http\Validation\ValidationServiceProvider::class,
\Engelsystem\Http\RedirectServiceProvider::class,
@ -37,7 +36,6 @@ return [
\Engelsystem\Http\HttpClientServiceProvider::class,
\Engelsystem\Helpers\DumpServerServiceProvider::class,
\Engelsystem\Helpers\UuidServiceProvider::class,
\Engelsystem\Controllers\Api\UsesAuthServiceProvider::class,
],
// Application middleware
@ -48,13 +46,10 @@ return [
// Changes of request/response parameters
\Engelsystem\Middleware\SetLocale::class,
\Engelsystem\Middleware\ETagHandler::class,
\Engelsystem\Middleware\AddHeaders::class,
\Engelsystem\Middleware\TrimInput::class,
// The application code
\Engelsystem\Middleware\ErrorHandler::class,
\Engelsystem\Middleware\ApiRouteHandler::class,
\Engelsystem\Middleware\VerifyCsrfToken::class,
\Engelsystem\Middleware\RouteDispatcher::class,
\Engelsystem\Middleware\SessionHandler::class,
@ -69,22 +64,11 @@ return [
// a list of
// 'Class@method' or 'Class' (which uses @handle),
// ['Class', 'method'],
// callable like [$instance, 'method'] or 'function'
// callable like [$instance, 'method] or 'function'
// or $function
// ]
'message.created' => \Engelsystem\Events\Listener\Messages::class . '@created',
'news.created' => \Engelsystem\Events\Listener\News::class . '@created',
'news.updated' => \Engelsystem\Events\Listener\News::class . '@updated',
'oauth2.login' => \Engelsystem\Events\Listener\OAuth2::class . '@login',
'shift.deleting' => [
\Engelsystem\Events\Listener\Shifts::class . '@deletingCreateWorklogs',
\Engelsystem\Events\Listener\Shifts::class . '@deletingSendEmails',
],
'shift.updating' => \Engelsystem\Events\Listener\Shifts::class . '@updatedSendEmail',
],
];

View File

@ -1,7 +1,5 @@
<?php
declare(strict_types=1);
// To change settings create a config.php
return [
@ -13,58 +11,41 @@ return [
'password' => env('MYSQL_PASSWORD', ''),
],
// For accessing /metrics (and /stats)
'api_key' => env('API_KEY', ''),
// For accessing stats
'api_key' => '',
// Enable maintenance mode (show a static page)
'maintenance' => (bool) env('MAINTENANCE', false),
'maintenance' => (bool)env('MAINTENANCE', false),
// Application name (not the event name)
// Application name (not the event name!)
'app_name' => env('APP_NAME', 'Engelsystem'),
// Set to development to enable debugging messages
'environment' => env('ENVIRONMENT', 'production'),
// Application URL and base path to use instead of the auto-detected one
'url' => env('APP_URL'),
// Application URL and base path to use instead of the auto detected one
'url' => env('APP_URL', null),
// Header links
// Available link placeholders: %lang%
// To disable a header_item in the config.php, you can set its value to null
'header_items' => [
// Name can be a translation string, permission is a engelsystem privilege
// 'Name' => 'URL',
// 'Name' => ['URL', 'permission'],
//'Foo' => ['https://foo.bar/batz-%lang%.html', 'logout'], // Permission: for logged-in users
//'Foo' => 'https://foo.bar/batz-%lang%.html',
],
// Footer links
// To disable a footer item in the config.php, you can set its value to null
'footer_items' => [
// Name can be a translation string, permission is a engelsystem privilege
// 'Name' => 'URL',
// 'Name' => ['URL', 'permission'],
// URL to the angel faq and job description
'faq.faq' => [env('FAQ_URL', '/faq'), 'faq.view'],
'FAQ' => env('FAQ_URL', '/faq'),
// Contact email address, linked on every page
'Contact' => env('CONTACT_EMAIL', 'mailto:ticket@c3heaven.de'),
],
// Other ways to ask the heaven
// Multiple contact options / links are possible, analogue to footer_items
'contact_options' => [
// E-mail address
'general.email' => env('CONTACT_EMAIL', 'mailto:ticket@c3heaven.de'),
],
// Text displayed on the FAQ page, rendered as markdown
'faq_text' => env('FAQ_TEXT'),
'faq_text' => env('FAQ_TEXT', null),
// Link to documentation/help
'documentation_url' => env('DOCUMENTATION_URL', 'https://engelsystem.de/doc/'),
'documentation_url' => 'https://engelsystem.de/doc/',
// Email config
'email' => [
@ -79,20 +60,17 @@ return [
'host' => env('MAIL_HOST', 'localhost'),
'port' => env('MAIL_PORT', 587),
// If tls transport encryption should be used
'tls' => env('MAIL_TLS'),
'tls' => env('MAIL_TLS', null),
'username' => env('MAIL_USERNAME'),
'password' => env('MAIL_PASSWORD'),
'sendmail' => env('MAIL_SENDMAIL', '/usr/sbin/sendmail -bs'),
],
// Your privacy@ contact address
'privacy_email' => env('PRIVACY_EMAIL'),
// Show opt in to save some personal data after the event on user profile and registration pages
'enable_email_goodie' => (bool) env('ENABLE_EMAIL_GOODIE', true),
# Your privacy@ contact address
'privacy_email' => '',
// Initial admin password
'setup_admin_password' => env('SETUP_ADMIN_PASSWORD'),
'setup_admin_password' => env('SETUP_ADMIN_PASSWORD', null),
'oauth' => [
// '[name]' => [config]
@ -110,8 +88,6 @@ return [
'url_token' => '[generated by provider]',
// User info URL which provides userdata
'url_info' => '[generated by provider]',
// OAuth Scopes
// 'scope' => ['openid'],
// Info unique user id field
'id' => 'uuid',
// The following fields are used for registration
@ -151,19 +127,7 @@ return [
// Default theme, 1=style1.css
'theme' => env('THEME', 1),
// Supported themes
// To disable a theme in the config.php, you can set its value to null
'themes' => [
17 => [
'name' => 'Engelsystem 37c3 (2023)',
'type' => 'dark',
'navbar_classes' => 'navbar-dark',
],
16 => [
'name' => 'Engelsystem cccamp23 (2023)',
'type' => 'dark',
'navbar_classes' => 'navbar-dark',
],
15 => [
'name' => 'Engelsystem rC3 (2021)',
'type' => 'dark',
@ -250,33 +214,17 @@ return [
// Must be one of news, meetings, user_shifts, angeltypes, questions
'home_site' => env('HOME_SITE', 'news'),
// Number of News shown on one site and for feed readers (minimum 1)
// Number of News shown on one site
'display_news' => env('DISPLAY_NEWS', 10),
// Users are able to sign up
'registration_enabled' => (bool) env('REGISTRATION_ENABLED', true),
// URL to external registration page, used on login page
'external_registration_url' => env('EXTERNAL_REGISTRATION_URL'),
// Required user fields
'required_user_fields' => [
'pronoun' => (bool) env('PRONOUN_REQUIRED', false),
'firstname' => (bool) env('FIRSTNAME_REQUIRED', false),
'lastname' => (bool) env('LASTNAME_REQUIRED', false),
'tshirt_size' => (bool) env('TSHIRT_SIZE_REQUIRED', true),
'mobile' => (bool) env('MOBILE_REQUIRED', false),
'dect' => (bool) env('DECT_REQUIRED', false),
],
'registration_enabled' => (bool)env('REGISTRATION_ENABLED', true),
// Only arrived angels can sign up for shifts
'signup_requires_arrival' => (bool) env('SIGNUP_REQUIRES_ARRIVAL', false),
'signup_requires_arrival' => (bool)env('SIGNUP_REQUIRES_ARRIVAL', false),
// Whether newly-registered user should automatically be marked as arrived
'autoarrive' => (bool) env('ANGEL_AUTOARRIVE', false),
// Supporters of an angeltype can promote other angels of the angeltype to supporter
'supporters_can_promote' => (bool) env('SUPPORTERS_CAN_PROMOTE', false),
'autoarrive' => (bool)env('ANGEL_AUTOARRIVE', false),
// Only allow shift signup this number of hours in advance
// Setting this to 0 disables the feature
@ -298,65 +246,48 @@ return [
// Define the algorithm to use for `password_verify()`
// If the user uses an old algorithm the password will be converted to the new format
// See https://secure.php.net/manual/en/password.constants.php for a complete list
'password_algorithm' => env('PASSWORD_ALGORITHM', PASSWORD_DEFAULT),
'password_algorithm' => PASSWORD_DEFAULT,
// The minimum length for passwords
'min_password_length' => env('PASSWORD_MINIMUM_LENGTH', 8),
// Whether the login and registration via password should be enabled (login will be hidden)
// This is useful when using oauth, disabling it also disables normal registration without oauth
'enable_password' => (bool) env('ENABLE_PASSWORD', true),
// Whether the Password field should be enabled on registration.
// This is useful when using oauth, disabling it also disables normal
// registration without oauth.
'enable_password' => (bool)env('ENABLE_PASSWORD', true),
// Whether the DECT field should be enabled
'enable_dect' => (bool) env('ENABLE_DECT', true),
'enable_dect' => (bool)env('ENABLE_DECT', true),
// Whether the mobile number can be shown to other users
'enable_mobile_show' => (bool) env('ENABLE_MOBILE_SHOW', false),
// Regular expression describing a FALSE username.
// Per default usernames must only contain alphanumeric chars, "-", "_" or ".".
'username_regex' => (string) env('USERNAME_REGEX', '/([^\p{L}\p{N}_.-]+)/ui'),
// Enables first name and last name
'enable_user_name' => (bool) env('ENABLE_USER_NAME', false),
// Show a users first name and last name instead of username
'display_full_name' => env('DISPLAY_FULL_NAME', false)
&& env('ENABLE_USER_NAME', false),
// Enables prename and lastname
'enable_user_name' => (bool)env('ENABLE_USER_NAME', false),
// Enable displaying the pronoun fields
'enable_pronoun' => (bool) env('ENABLE_PRONOUN', true),
'enable_pronoun' => (bool)env('ENABLE_PRONOUN', true),
// Enables the planned arrival/leave date
'enable_planned_arrival' => (bool) env('ENABLE_PLANNED_ARRIVAL', true),
'enable_planned_arrival' => (bool)env('ENABLE_PLANNED_ARRIVAL', true),
// Whether force active should be enabled
'enable_force_active' => (bool) env('ENABLE_FORCE_ACTIVE', true),
// Enables the T-Shirt configuration on signup and profile
'enable_tshirt_size' => (bool)env('ENABLE_TSHIRT_SIZE', true),
// Resembles the Goodie Type. There are three options:
// 'none' => no goodie at all
// 'goodie' => a goodie which has no sizing options
// 'tshirt' => goodie that is called tshirt and has sizing options
'goodie_type' => env('GOODIE_TYPE', 'goodie'),
// Enables the goody configuration on signup and profile
'enable_goody' => (bool)env('ENABLE_GOODY', false),
// Enables the food voucher in the user profile
'enable_voucher' => (bool) env('ENABLE_VOUCHER', true),
'enable_voucher' => (bool)env('ENABLE_VOUCHER', true),
// Number of shifts to freeload until angel is locked for shift signup.
'max_freeloadable_shifts' => env('MAX_FREELOADABLE_SHIFTS', 2),
// Hide columns in backend user view. Possible values are any sortable parameters of the table.
'disabled_user_view_columns' => [],
// Local timezone
'timezone' => env('TIMEZONE', 'Europe/Berlin'),
'timezone' => env('TIMEZONE', ini_get('date.timezone') ?: 'Europe/Berlin'),
// Multiply 'night shifts' and freeloaded shifts (start or end between 2 and 8 exclusive) by 2 in goodie score
// Goodies must be enabled to use this feature
// Multiply 'night shifts' and freeloaded shifts (start or end between 2 and 6 exclusive) by 2
'night_shifts' => [
'enabled' => (bool) env('NIGHT_SHIFTS', true), // Disable to weigh every shift the same
'start' => env('NIGHT_SHIFTS_START', 2), // Starting from hour
'end' => env('NIGHT_SHIFTS_END', 8), // Ends at (without including) hour
'enabled' => (bool)env('NIGHT_SHIFTS', true), // Disable to weigh every shift the same
'start' => env('NIGHT_SHIFTS_START', 2),
'end' => env('NIGHT_SHIFTS_END', 6),
'multiplier' => env('NIGHT_SHIFTS_MULTIPLIER', 2),
],
@ -366,20 +297,10 @@ return [
'shifts_per_voucher' => env('SHIFTS_PER_VOUCHER', 0),
'hours_per_voucher' => env('HOURS_PER_VOUCHER', 2),
// 'Y-m-d' formatted
'voucher_start' => env('VOUCHER_START') ?: null,
'voucher_start' => env('VOUCHER_START', null) ?: null,
],
// Enables Driving License
'driving_license_enabled' => (bool) env('DRIVING_LICENSE_ENABLED', true),
# Instruction in accordance with § 43 Para. 1 of the German Infection Protection Act (IfSG)
'ifsg_enabled' => (bool) env('IFSG_ENABLED', false),
# Instruction only onsite in accordance with § 43 Para. 1 of the German Infection Protection Act (IfSG)
'ifsg_light_enabled' => env('IFSG_LIGHT_ENABLED', false) && env('IFSG_ENABLED', false),
// Available locales in /resources/lang/
// To disable a locale in the config.php, you can set its value to null
'locales' => [
'de_DE' => 'Deutsch',
'en_US' => 'English',
@ -388,31 +309,21 @@ return [
// The default locale to use
'default_locale' => env('DEFAULT_LOCALE', 'en_US'),
// Available T-Shirt sizes
// To disable a t-shirt size in the config.php, you can set its value to null
// Available T-Shirt sizes, set value to null if not available
'tshirt_sizes' => [
'S' => 'Small Straight-Cut',
'S-F' => 'Small Fitted-Cut',
'S-G' => 'Small Fitted-Cut',
'M' => 'Medium Straight-Cut',
'M-F' => 'Medium Fitted-Cut',
'M-G' => 'Medium Fitted-Cut',
'L' => 'Large Straight-Cut',
'L-F' => 'Large Fitted-Cut',
'L-G' => 'Large Fitted-Cut',
'XL' => 'XLarge Straight-Cut',
'XL-F' => 'XLarge Fitted-Cut',
'XL-G' => 'XLarge Fitted-Cut',
'2XL' => '2XLarge Straight-Cut',
'3XL' => '3XLarge Straight-Cut',
'4XL' => '4XLarge Straight-Cut',
],
// T-shirt Size-Guide link
'tshirt_link' => env('TSHIRT_LINK'),
// Whether to show the current day of the event (-2, -1, 0, 1, 2…) in footer and on the dashboard.
// The event start date has to be set for it to appear.
'enable_show_day_of_event' => (bool) env('ENABLE_SHOW_DAY_OF_EVENT', false),
// If true there will be a day 0 (-1, 0, 1…). If false there won't (-1, 1…)
'event_has_day0' => (bool) env('EVENT_HAS_DAY0', true),
'metrics' => [
// User work buckets in seconds
'work' => [1 * 60 * 60, 1.5 * 60 * 60, 2 * 60 * 60, 3 * 60 * 60, 5 * 60 * 60, 10 * 60 * 60, 20 * 60 * 60],
@ -431,26 +342,18 @@ return [
// Cookie name
'name' => env('SESSION_NAME', 'session'),
// Lifetime in days
'lifetime' => env('SESSION_LIFETIME', 30),
],
// IP addresses of reverse proxies that are trusted, can be an array or a comma separated list
'trusted_proxies' => env('TRUSTED_PROXIES', ['127.0.0.0/8', '::ffff:127.0.0.0/8', '::1/128']),
// Add additional headers
'add_headers' => (bool) env('ADD_HEADERS', true),
// Predefined headers
// To disable a header in the config.php, you can set its value to null
'add_headers' => (bool)env('ADD_HEADERS', true),
'headers' => [
'X-Content-Type-Options' => 'nosniff',
'X-Frame-Options' => 'sameorigin',
'Referrer-Policy' => 'strict-origin-when-cross-origin',
'Content-Security-Policy' =>
'default-src \'self\'; '
. ' style-src \'self\' \'unsafe-inline\'; '
. 'img-src \'self\' data:;',
'Content-Security-Policy' => 'default-src \'self\' \'unsafe-inline\' \'unsafe-eval\'; img-src \'self\' data:;',
'X-XSS-Protection' => '1; mode=block',
'Feature-Policy' => 'autoplay \'none\'',
//'Strict-Transport-Security' => 'max-age=7776000',
@ -461,7 +364,7 @@ return [
'credits' => [
'Contribution' => 'Please visit [engelsystem/engelsystem](https://github.com/engelsystem/engelsystem) if '
. 'you want to contribute, have found any [bugs](https://github.com/engelsystem/engelsystem/issues) '
. 'or need help.',
. 'or need help.'
],
// var dump server

View File

@ -1,15 +1,11 @@
<?php
declare(strict_types=1);
use FastRoute\RouteCollector;
/** @var RouteCollector $route */
// Pages
$route->get('/', 'HomeController@index');
$route->get('/register', 'RegistrationController@view');
$route->post('/register', 'RegistrationController@save');
$route->get('/credits', 'CreditsController@index');
$route->get('/health', 'HealthController@index');
@ -19,154 +15,54 @@ $route->post('/login', 'AuthController@postLogin');
$route->get('/logout', 'AuthController@logout');
// OAuth
$route->addGroup(
'/oauth/{provider}',
function (RouteCollector $route): void {
$route->get('', 'OAuthController@index');
$route->post('/connect', 'OAuthController@connect');
$route->post('/disconnect', 'OAuthController@disconnect');
}
);
$route->get('/oauth/{provider}', 'OAuthController@index');
$route->post('/oauth/{provider}/connect', 'OAuthController@connect');
$route->post('/oauth/{provider}/disconnect', 'OAuthController@disconnect');
// User settings
$route->addGroup(
'/settings',
function (RouteCollector $route): void {
$route->get('/profile', 'SettingsController@profile');
$route->post('/profile', 'SettingsController@saveProfile');
$route->get('/password', 'SettingsController@password');
$route->post('/password', 'SettingsController@savePassword');
$route->get('/theme', 'SettingsController@theme');
$route->post('/theme', 'SettingsController@saveTheme');
$route->get('/language', 'SettingsController@language');
$route->post('/language', 'SettingsController@saveLanguage');
$route->get('/certificates', 'SettingsController@certificate');
$route->post('/certificates/ifsg', 'SettingsController@saveIfsgCertificate');
$route->post('/certificates/driving', 'SettingsController@saveDrivingLicense');
$route->get('/api', 'SettingsController@api');
$route->post('/api', 'SettingsController@apiKeyReset');
$route->get('/oauth', 'SettingsController@oauth');
$route->get('/sessions', 'SettingsController@sessions');
$route->post('/sessions', 'SettingsController@sessionsDelete');
}
);
// User admin settings
$route->addGroup(
'/users/{user_id:\d+}',
function (RouteCollector $route): void {
$route->get('/certificates', 'Admin\\UserSettingsController@certificate');
$route->post('/certificates/ifsg', 'Admin\\UserSettingsController@saveIfsgCertificate');
$route->post('/certificates/driving', 'Admin\\UserSettingsController@saveDrivingLicense');
}
);
$route->get('/settings/password', 'SettingsController@password');
$route->post('/settings/password', 'SettingsController@savePassword');
$route->get('/settings/theme', 'SettingsController@theme');
$route->post('/settings/theme', 'SettingsController@saveTheme');
$route->get('/settings/language', 'SettingsController@language');
$route->post('/settings/language', 'SettingsController@saveLanguage');
$route->get('/settings/oauth', 'SettingsController@oauth');
// Password recovery
$route->addGroup(
'/password/reset',
function (RouteCollector $route): void {
$route->get('', 'PasswordResetController@reset');
$route->post('', 'PasswordResetController@postReset');
$route->get('/{token:.+}', 'PasswordResetController@resetPassword');
$route->post('/{token:.+}', 'PasswordResetController@postResetPassword');
}
);
$route->get('/password/reset', 'PasswordResetController@reset');
$route->post('/password/reset', 'PasswordResetController@postReset');
$route->get('/password/reset/{token:.+}', 'PasswordResetController@resetPassword');
$route->post('/password/reset/{token:.+}', 'PasswordResetController@postResetPassword');
// Stats
$route->get('/metrics', 'Metrics\\Controller@metrics');
$route->get('/stats', 'Metrics\\Controller@stats');
// Angeltypes
$route->addGroup('/angeltypes', function (RouteCollector $route): void {
$route->get('/about', 'AngelTypesController@about');
});
// Shifts
$route->addGroup('/shifts', function (RouteCollector $route): void {
$route->get('/random', 'ShiftsController@random');
});
// News
$route->get('/news', 'NewsController@index');
$route->get('/meetings', 'NewsController@meetings');
$route->addGroup(
'/news',
function (RouteCollector $route): void {
$route->get('', 'NewsController@index');
$route->get('/{news_id:\d+}', 'NewsController@show');
$route->post('/{news_id:\d+}', 'NewsController@comment');
$route->post('/comment/{comment_id:\d+}', 'NewsController@deleteComment');
}
);
$route->get('/news/{id:\d+}', 'NewsController@show');
$route->post('/news/{id:\d+}', 'NewsController@comment');
$route->post('/news/comment/{id:\d+}', 'NewsController@deleteComment');
// FAQ
$route->get('/faq', 'FaqController@index');
// Questions
$route->addGroup(
'/questions',
function (RouteCollector $route): void {
$route->get('', 'QuestionsController@index');
$route->post('', 'QuestionsController@delete');
$route->get('/new', 'QuestionsController@add');
$route->post('/new', 'QuestionsController@save');
}
);
$route->get('/questions', 'QuestionsController@index');
$route->post('/questions', 'QuestionsController@delete');
$route->get('/questions/new', 'QuestionsController@add');
$route->post('/questions/new', 'QuestionsController@save');
// Messages
$route->addGroup(
'/messages',
function (RouteCollector $route): void {
$route->get('', 'MessagesController@index');
$route->post('', 'MessagesController@redirectToConversation');
$route->get('/{user_id:\d+}', 'MessagesController@messagesOfConversation');
$route->post('/{user_id:\d+}', 'MessagesController@send');
$route->post('/{user_id:\d+}/{msg_id:\d+}', 'MessagesController@delete');
}
);
$route->get('/messages', 'MessagesController@index');
$route->post('/messages', 'MessagesController@redirectToConversation');
$route->get('/messages/{user_id:\d+}', 'MessagesController@messagesOfConversation');
$route->post('/messages/{user_id:\d+}', 'MessagesController@send');
$route->post('/messages/{user_id:\d+}/{msg_id:\d+}', 'MessagesController@delete');
// API
$route->addGroup(
'/api',
function (RouteCollector $route): void {
$route->get('', 'Api\IndexController@index');
$route->addGroup(
'/v0-beta',
function (RouteCollector $route): void {
$route->addRoute(['OPTIONS'], '[/{resource:.+}]', 'Api\IndexController@options');
$route->get('', 'Api\IndexController@indexV0');
$route->get('/openapi', 'Api\IndexController@openApiV0');
$route->get('/info', 'Api\IndexController@info');
$route->get('/angeltypes', 'Api\AngelTypeController@index');
$route->get('/angeltypes/{angeltype_id:\d+}/shifts', 'Api\ShiftsController@entriesByAngeltype');
$route->get('/locations', 'Api\LocationsController@index');
$route->get('/locations/{location_id:\d+}/shifts', 'Api\ShiftsController@entriesByLocation');
$route->get('/news', 'Api\NewsController@index');
$route->get('/users/{user_id:(?:\d+|self)}', 'Api\UsersController@user');
$route->get('/users/{user_id:(?:\d+|self)}/angeltypes', 'Api\AngelTypeController@ofUser');
$route->get('/users/{user_id:(?:\d+|self)}/shifts', 'Api\ShiftsController@entriesByUser');
$route->addRoute(
['POST', 'PUT', 'DELETE', 'PATCH'],
'/[{resource:.+}]',
'Api\IndexController@notImplemented'
);
$route->get('/[{resource:.+}]', 'Api\IndexController@notFound');
}
);
$route->get('/[{resource:.+}]', 'Api\IndexController@notFound');
}
);
// Feeds
$route->get('/atom', 'FeedController@atom');
$route->get('/ical', 'FeedController@ical');
$route->get('/rss', 'FeedController@rss');
$route->get('/shifts-json-export', 'FeedController@shifts');
$route->get('/api[/{resource:.+}]', 'ApiController@index');
// Design
$route->get('/design', 'DesignController@index');
@ -174,118 +70,59 @@ $route->get('/design', 'DesignController@index');
// Administration
$route->addGroup(
'/admin',
function (RouteCollector $route): void {
function (RouteCollector $route) {
// FAQ
$route->addGroup(
'/faq',
function (RouteCollector $route): void {
$route->get('[/{faq_id:\d+}]', 'Admin\\FaqController@edit');
$route->post('[/{faq_id:\d+}]', 'Admin\\FaqController@save');
function (RouteCollector $route) {
$route->get('[/{id:\d+}]', 'Admin\\FaqController@edit');
$route->post('[/{id:\d+}]', 'Admin\\FaqController@save');
}
);
// Log
$route->addGroup(
'/logs',
function (RouteCollector $route): void {
$route->get('', 'Admin\\LogsController@index');
$route->post('', 'Admin\\LogsController@index');
}
);
$route->get('/logs', 'Admin\\LogsController@index');
$route->post('/logs', 'Admin\\LogsController@index');
// Schedule
$route->addGroup(
'/schedule',
function (RouteCollector $route): void {
$route->get('', 'Admin\\ScheduleController@index');
$route->get('/edit[/{schedule_id:\d+}]', 'Admin\\ScheduleController@edit');
$route->post('/edit[/{schedule_id:\d+}]', 'Admin\\ScheduleController@save');
$route->get('/load/{schedule_id:\d+}', 'Admin\\ScheduleController@loadSchedule');
$route->post('/import/{schedule_id:\d+}', 'Admin\\ScheduleController@importSchedule');
}
);
// Shifts
$route->addGroup(
'/shifts',
function (RouteCollector $route): void {
$route->get('/history', 'Admin\\ShiftsController@history');
$route->post('/history', 'Admin\\ShiftsController@deleteTransaction');
}
);
// Shift types
$route->addGroup(
'/shifttypes',
function (RouteCollector $route): void {
$route->get('', 'Admin\\ShiftTypesController@index');
$route->post('', 'Admin\\ShiftTypesController@delete');
$route->get('/{shift_type_id:\d+}', 'Admin\\ShiftTypesController@view');
$route->get('/edit[/{shift_type_id:\d+}]', 'Admin\\ShiftTypesController@edit');
$route->post('/edit[/{shift_type_id:\d+}]', 'Admin\\ShiftTypesController@save');
function (RouteCollector $route) {
$route->get('', 'Admin\\Schedule\\ImportSchedule@index');
$route->get('/edit[/{id:\d+}]', 'Admin\\Schedule\\ImportSchedule@edit');
$route->post('/edit[/{id:\d+}]', 'Admin\\Schedule\\ImportSchedule@save');
$route->get('/load/{id:\d+}', 'Admin\\Schedule\\ImportSchedule@loadSchedule');
$route->post('/import/{id:\d+}', 'Admin\\Schedule\\ImportSchedule@importSchedule');
}
);
// Questions
$route->addGroup(
'/questions',
function (RouteCollector $route): void {
function (RouteCollector $route) {
$route->get('', 'Admin\\QuestionsController@index');
$route->post('', 'Admin\\QuestionsController@delete');
$route->get('/{question_id:\d+}', 'Admin\\QuestionsController@edit');
$route->post('/{question_id:\d+}', 'Admin\\QuestionsController@save');
}
);
// Locations
$route->addGroup(
'/locations',
function (RouteCollector $route): void {
$route->get('', 'Admin\\LocationsController@index');
$route->post('', 'Admin\\LocationsController@delete');
$route->get('/edit[/{location_id:\d+}]', 'Admin\\LocationsController@edit');
$route->post('/edit[/{location_id:\d+}]', 'Admin\\LocationsController@save');
$route->get('/{id:\d+}', 'Admin\\QuestionsController@edit');
$route->post('/{id:\d+}', 'Admin\\QuestionsController@save');
}
);
// User
$route->addGroup(
'/user/{user_id:\d+}',
function (RouteCollector $route): void {
// Goodies
$route->addGroup(
'/goodie',
function (RouteCollector $route): void {
$route->get('', 'Admin\\UserGoodieController@editGoodie');
$route->post('', 'Admin\\UserGoodieController@saveGoodie');
}
);
// Worklogs
$route->addGroup(
'/worklog',
function (RouteCollector $route): void {
$route->get('[/{worklog_id:\d+}]', 'Admin\\UserWorkLogController@editWorklog');
$route->post('[/{worklog_id:\d+}]', 'Admin\\UserWorkLogController@saveWorklog');
$route->get(
'/{worklog_id:\d+}/delete',
'Admin\\UserWorkLogController@showDeleteWorklog'
);
$route->post(
'/{worklog_id:\d+}/delete',
'Admin\\UserWorkLogController@deleteWorklog'
);
}
);
'/user/{id:\d+}',
// Shirts
function (RouteCollector $route) {
$route->get('/shirt', 'Admin\\UserShirtController@editShirt');
$route->post('/shirt', 'Admin\\UserShirtController@saveShirt');
}
);
// News
$route->addGroup(
'/news',
function (RouteCollector $route): void {
$route->get('[/{news_id:\d+}]', 'Admin\\NewsController@edit');
$route->post('[/{news_id:\d+}]', 'Admin\\NewsController@save');
function (RouteCollector $route) {
$route->get('[/{id:\d+}]', 'Admin\\NewsController@edit');
$route->post('[/{id:\d+}]', 'Admin\\NewsController@save');
}
);
}

View File

@ -1,34 +0,0 @@
<?php
declare(strict_types=1);
namespace Database\Factories\Engelsystem\Models;
use Engelsystem\Models\AngelType;
use Illuminate\Database\Eloquent\Factories\Factory;
class AngelTypeFactory extends Factory
{
/** @var string */
protected $model = AngelType::class; // phpcs:ignore
public function definition(): array
{
return [
'name' => $this->faker->unique()->firstName(),
'description' => $this->faker->text(),
'contact_name' => $this->faker->firstName(),
'contact_dect' => $this->faker->randomNumber(4),
'contact_email' => $this->faker->email(),
'restricted' => $this->faker->boolean(),
'requires_driver_license' => $this->faker->boolean(),
'requires_ifsg_certificate' => $this->faker->boolean(),
'shift_self_signup' => $this->faker->boolean(),
'show_on_dashboard' => $this->faker->boolean(),
'hide_register' => $this->faker->boolean(),
'hide_on_shift_view' => $this->faker->boolean(),
];
}
}

View File

@ -1,7 +1,5 @@
<?php
declare(strict_types=1);
namespace Database\Factories\Engelsystem\Models;
use Engelsystem\Models\Faq;
@ -10,9 +8,12 @@ use Illuminate\Database\Eloquent\Factories\Factory;
class FaqFactory extends Factory
{
/** @var string */
protected $model = Faq::class; // phpcs:ignore
protected $model = Faq::class;
public function definition(): array
/**
* @return array
*/
public function definition()
{
return [
'question' => $this->faker->text(100),

View File

@ -1,21 +0,0 @@
<?php
declare(strict_types=1);
namespace Database\Factories\Engelsystem\Models;
use Engelsystem\Models\Group;
use Illuminate\Database\Eloquent\Factories\Factory;
class GroupFactory extends Factory
{
/** @var string */
protected $model = Group::class; // phpcs:ignore
public function definition(): array
{
return [
'name' => $this->faker->unique()->word(),
];
}
}

View File

@ -1,7 +1,5 @@
<?php
declare(strict_types=1);
namespace Database\Factories\Engelsystem\Models;
use Engelsystem\Models\Message;
@ -11,9 +9,12 @@ use Illuminate\Database\Eloquent\Factories\Factory;
class MessageFactory extends Factory
{
/** @var string */
protected $model = Message::class; // phpcs:ignore
protected $model = Message::class;
public function definition(): array
/**
* @return array
*/
public function definition()
{
return [
'user_id' => User::factory(),

View File

@ -1,7 +1,5 @@
<?php
declare(strict_types=1);
namespace Database\Factories\Engelsystem\Models;
use Engelsystem\Models\News;
@ -12,9 +10,12 @@ use Illuminate\Database\Eloquent\Factories\Factory;
class NewsCommentFactory extends Factory
{
/** @var string */
protected $model = NewsComment::class; // phpcs:ignore
protected $model = NewsComment::class;
public function definition(): array
/**
* @return array
*/
public function definition()
{
return [
'news_id' => News::factory(),

View File

@ -1,7 +1,5 @@
<?php
declare(strict_types=1);
namespace Database\Factories\Engelsystem\Models;
use Engelsystem\Models\News;
@ -11,17 +9,19 @@ use Illuminate\Database\Eloquent\Factories\Factory;
class NewsFactory extends Factory
{
/** @var string */
protected $model = News::class; // phpcs:ignore
protected $model = News::class;
public function definition(): array
/**
* @return array
*/
public function definition()
{
return [
'title' => $this->faker->text(50),
'text' => $this->faker->realText(),
'is_meeting' => $this->faker->boolean(),
'is_pinned' => $this->faker->boolean(.1),
'is_highlighted' => $this->faker->boolean(.1),
'user_id' => User::factory(),
'title' => $this->faker->text(50),
'text' => $this->faker->realText(),
'is_meeting' => $this->faker->boolean(),
'is_pinned' => $this->faker->boolean(.1),
'user_id' => User::factory(),
];
}
}

View File

@ -1,30 +0,0 @@
<?php
declare(strict_types=1);
namespace Database\Factories\Engelsystem\Models;
use Engelsystem\Models\OAuth;
use Engelsystem\Models\User\User;
use Illuminate\Database\Eloquent\Factories\Factory;
class OAuthFactory extends Factory
{
/** @var class-string */
protected $model = OAuth::class; // phpcs:ignore
/**
* @return array<string, mixed>
*/
public function definition(): array
{
return [
'user_id' => User::factory(),
'provider' => $this->faker->unique()->word(),
'identifier' => $this->faker->unique()->word(),
'access_token' => $this->faker->unique()->word(),
'refresh_token' => $this->faker->unique()->word(),
'expires_at' => $this->faker->dateTimeInInterval('+5 days', '+3 months')->format('Y-m-d'),
];
}
}

View File

@ -1,22 +0,0 @@
<?php
declare(strict_types=1);
namespace Database\Factories\Engelsystem\Models;
use Engelsystem\Models\Privilege;
use Illuminate\Database\Eloquent\Factories\Factory;
class PrivilegeFactory extends Factory
{
/** @var string */
protected $model = Privilege::class; // phpcs:ignore
public function definition(): array
{
return [
'name' => $this->faker->unique()->word(),
'description' => $this->faker->text(),
];
}
}

View File

@ -1,7 +1,5 @@
<?php
declare(strict_types=1);
namespace Database\Factories\Engelsystem\Models;
use Carbon\Carbon;
@ -12,9 +10,12 @@ use Illuminate\Database\Eloquent\Factories\Factory;
class QuestionFactory extends Factory
{
/** @var string */
protected $model = Question::class; // phpcs:ignore
protected $model = Question::class;
public function definition(): array
/**
* @return array
*/
public function definition()
{
return [
'user_id' => User::factory(),

View File

@ -1,24 +1,24 @@
<?php
declare(strict_types=1);
namespace Database\Factories\Engelsystem\Models;
use Engelsystem\Models\Location;
use Engelsystem\Models\Room;
use Illuminate\Database\Eloquent\Factories\Factory;
class LocationFactory extends Factory
class RoomFactory extends Factory
{
/** @var string */
protected $model = Location::class; // phpcs:ignore
protected $model = Room::class;
public function definition(): array
/**
* @return array
*/
public function definition()
{
return [
'name' => $this->faker->unique()->firstName(),
'map_url' => $this->faker->url(),
'description' => $this->faker->text(),
'dect' => $this->faker->optional()->numberBetween(1000, 9999),
];
}
}

View File

@ -1,24 +0,0 @@
<?php
declare(strict_types=1);
namespace Database\Factories\Engelsystem\Models;
use Engelsystem\Models\Session;
use Engelsystem\Models\User\User;
use Illuminate\Database\Eloquent\Factories\Factory;
class SessionFactory extends Factory
{
/** @var string */
protected $model = Session::class; // phpcs:ignore
public function definition(): array
{
return [
'id' => $this->faker->lexify('????????????????????????????????'),
'payload' => $this->faker->text(100),
'user_id' => $this->faker->optional()->passthrough(User::factory()),
];
}
}

View File

@ -1,30 +0,0 @@
<?php
declare(strict_types=1);
namespace Database\Factories\Engelsystem\Models\Shifts;
use Engelsystem\Models\AngelType;
use Engelsystem\Models\Location;
use Engelsystem\Models\Shifts\NeededAngelType;
use Engelsystem\Models\Shifts\Shift;
use Illuminate\Database\Eloquent\Factories\Factory;
class NeededAngelTypeFactory extends Factory
{
/** @var string */
protected $model = NeededAngelType::class; // phpcs:ignore
public function definition(): array
{
$type = $this->faker->numberBetween(0, 2);
return [
'location_id' => $type == 0 ? Location::factory() : null,
'shift_id' => $type == 1 ? null : Shift::factory(),
'shift_type_id' => $type == 2 ? null : Shift::factory(),
'angel_type_id' => AngelType::factory(),
'count' => $this->faker->numberBetween(1, 5),
];
}
}

View File

@ -1,7 +1,5 @@
<?php
declare(strict_types=1);
namespace Database\Factories\Engelsystem\Models\Shifts;
use Engelsystem\Models\Shifts\Schedule;
@ -10,15 +8,17 @@ use Illuminate\Database\Eloquent\Factories\Factory;
class ScheduleFactory extends Factory
{
/** @var string */
protected $model = Schedule::class; // phpcs:ignore
protected $model = Schedule::class;
public function definition(): array
/**
* @return array
*/
public function definition()
{
return [
'name' => $this->faker->unique()->words(4, true),
'name' => $this->faker->words(4, true),
'url' => $this->faker->parse('https://{{safeEmailDomain}}/{{slug}}.xml'),
'shift_type' => $this->faker->numberBetween(1, 5),
'needed_from_shift_type' => $this->faker->boolean(.2),
'minutes_before' => 15,
'minutes_after' => 15,
];

View File

@ -1,31 +0,0 @@
<?php
declare(strict_types=1);
namespace Database\Factories\Engelsystem\Models\Shifts;
use Engelsystem\Models\AngelType;
use Engelsystem\Models\Shifts\Shift;
use Engelsystem\Models\Shifts\ShiftEntry;
use Engelsystem\Models\User\User;
use Illuminate\Database\Eloquent\Factories\Factory;
class ShiftEntryFactory extends Factory
{
/** @var string */
protected $model = ShiftEntry::class; // phpcs:ignore
public function definition(): array
{
$freeloaded = $this->faker->optional(.01, false)->boolean();
return [
'shift_id' => Shift::factory(),
'angel_type_id' => AngelType::factory(),
'user_id' => User::factory(),
'user_comment' => $this->faker->optional(.05, '')->text(),
'freeloaded' => $freeloaded,
'freeloaded_comment' => $freeloaded ? $this->faker->text() : '',
];
}
}

View File

@ -1,34 +0,0 @@
<?php
declare(strict_types=1);
namespace Database\Factories\Engelsystem\Models\Shifts;
use Engelsystem\Models\Location;
use Engelsystem\Models\Shifts\Shift;
use Engelsystem\Models\Shifts\ShiftType;
use Engelsystem\Models\User\User;
use Illuminate\Database\Eloquent\Factories\Factory;
class ShiftFactory extends Factory
{
/** @var string */
protected $model = Shift::class; // phpcs:ignore
public function definition(): array
{
$start = $this->faker->dateTimeThisMonth('2 weeks');
return [
'title' => $this->faker->unique()->text(15),
'description' => $this->faker->text(),
'url' => $this->faker->url(),
'start' => $start,
'end' => $this->faker->dateTimeInInterval($start, '+3 hours'),
'shift_type_id' => ShiftType::factory(),
'location_id' => Location::factory(),
'transaction_id' => $this->faker->optional()->uuid(),
'created_by' => User::factory(),
'updated_by' => $this->faker->optional(.3)->boolean() ? User::factory() : null,
];
}
}

View File

@ -1,22 +0,0 @@
<?php
declare(strict_types=1);
namespace Database\Factories\Engelsystem\Models\Shifts;
use Engelsystem\Models\Shifts\ShiftType;
use Illuminate\Database\Eloquent\Factories\Factory;
class ShiftTypeFactory extends Factory
{
/** @var string */
protected $model = ShiftType::class; // phpcs:ignore
public function definition(): array
{
return [
'name' => $this->faker->unique()->firstName(),
'description' => $this->faker->text(),
];
}
}

View File

@ -1,22 +1,21 @@
<?php
declare(strict_types=1);
namespace Database\Factories\Engelsystem\Models\User;
use Engelsystem\Models\User\Contact;
use Engelsystem\Models\User\User;
use Illuminate\Database\Eloquent\Factories\Factory;
class ContactFactory extends Factory
{
/** @var string */
protected $model = Contact::class; // phpcs:ignore
protected $model = Contact::class;
public function definition(): array
/**
* @return array
*/
public function definition()
{
return [
'user_id' => User::factory(),
'dect' => $this->faker->optional()->numberBetween(1000, 9999),
'email' => $this->faker->unique()->optional()->safeEmail(),
'mobile' => $this->faker->optional(.2)->phoneNumber(),

View File

@ -1,19 +1,19 @@
<?php
declare(strict_types=1);
namespace Database\Factories\Engelsystem\Models\User;
use Engelsystem\Models\User\License;
use Engelsystem\Models\User\User;
use Illuminate\Database\Eloquent\Factories\Factory;
class LicenseFactory extends Factory
{
/** @var string */
protected $model = License::class; // phpcs:ignore
protected $model = License::class;
public function definition(): array
/**
* @return array
*/
public function definition()
{
$drive_car = $this->faker->boolean(.8);
$drive_3_5t = $drive_car && $this->faker->boolean(.7);
@ -21,30 +21,14 @@ class LicenseFactory extends Factory
$drive_12t = $drive_7_5t && $this->faker->boolean(.3);
$drive_forklift = ($drive_car && $this->faker->boolean(.1))
|| ($drive_12t && $this->faker->boolean(.7));
$drive_confirmed = $this->faker->boolean(0.5) && (
$drive_car
|| $drive_3_5t
|| $drive_7_5t
|| $drive_12t
|| $drive_forklift
);
$ifsg_certificate = $this->faker->boolean(0.1);
$ifsg_certificate_light = $this->faker->boolean(0.5) && !$ifsg_certificate;
$ifsg_confirmed = $this->faker->boolean(0.5) && ($ifsg_certificate || $ifsg_certificate_light);
return [
'user_id' => User::factory(),
'has_car' => $drive_car && $this->faker->boolean(.7),
'drive_forklift' => $drive_forklift,
'drive_car' => $drive_car,
'drive_3_5t' => $drive_3_5t,
'drive_7_5t' => $drive_7_5t,
'drive_12t' => $drive_12t,
'drive_confirmed' => $drive_confirmed,
'ifsg_certificate' => $ifsg_certificate,
'ifsg_certificate_light' => $ifsg_certificate_light,
'ifsg_confirmed' => $ifsg_confirmed,
'has_car' => $drive_car && $this->faker->boolean(.7),
'drive_forklift' => $drive_forklift,
'drive_car' => $drive_car,
'drive_3_5t' => $drive_3_5t,
'drive_7_5t' => $drive_7_5t,
'drive_12t' => $drive_12t,
];
}
}

View File

@ -1,23 +1,22 @@
<?php
declare(strict_types=1);
namespace Database\Factories\Engelsystem\Models\User;
use Engelsystem\Models\User\PasswordReset;
use Engelsystem\Models\User\User;
use Illuminate\Database\Eloquent\Factories\Factory;
class PasswordResetFactory extends Factory
{
/** @var string */
protected $model = PasswordReset::class; // phpcs:ignore
protected $model = PasswordReset::class;
public function definition(): array
/**
* @return array
*/
public function definition()
{
return [
'user_id' => User::factory(),
'token' => bin2hex(random_bytes(16)),
'token' => md5($this->faker->unique()->password()),
];
}
}

View File

@ -1,26 +1,25 @@
<?php
declare(strict_types=1);
namespace Database\Factories\Engelsystem\Models\User;
use Carbon\Carbon;
use Engelsystem\Models\User\PersonalData;
use Engelsystem\Models\User\User;
use Illuminate\Database\Eloquent\Factories\Factory;
class PersonalDataFactory extends Factory
{
/** @var string */
protected $model = PersonalData::class; // phpcs:ignore
protected $model = PersonalData::class;
public function definition(): array
/**
* @return array
*/
public function definition()
{
$arrival = $this->faker->optional()->dateTimeThisMonth('2 weeks');
$departure = $this->faker->optional()->dateTimeThisMonth('2 weeks');
return [
'user_id' => User::factory(),
'first_name' => $this->faker->optional(.7)->firstName(),
'last_name' => $this->faker->optional()->lastName(),
'pronoun' => $this->faker->optional(.3)->pronoun(),

View File

@ -1,30 +1,27 @@
<?php
declare(strict_types=1);
namespace Database\Factories\Engelsystem\Models\User;
use Engelsystem\Models\User\Settings;
use Engelsystem\Models\User\User;
use Illuminate\Database\Eloquent\Factories\Factory;
class SettingsFactory extends Factory
{
/** @var string */
protected $model = Settings::class; // phpcs:ignore
protected $model = Settings::class;
public function definition(): array
/**
* @return array
*/
public function definition()
{
return [
'user_id' => User::factory(),
'language' => $this->faker->locale(),
'theme' => $this->faker->numberBetween(1, 20),
'email_human' => $this->faker->boolean(),
'email_messages' => $this->faker->boolean(),
'email_goodie' => $this->faker->boolean(),
'email_goody' => $this->faker->boolean(),
'email_shiftinfo' => $this->faker->boolean(),
'email_news' => $this->faker->boolean(),
'mobile_show' => $this->faker->boolean(),
];
}
}

View File

@ -1,39 +1,39 @@
<?php
declare(strict_types=1);
namespace Database\Factories\Engelsystem\Models\User;
use Carbon\Carbon;
use Engelsystem\Models\User\State;
use Engelsystem\Models\User\User;
use Illuminate\Database\Eloquent\Factories\Factory;
class StateFactory extends Factory
{
/** @var string */
protected $model = State::class; // phpcs:ignore
protected $model = State::class;
public function definition(): array
/**
* @return array
*/
public function definition()
{
$arrival = $this->faker->optional()->dateTimeThisMonth();
return [
'user_id' => User::factory(),
'arrived' => (bool) $arrival,
'arrived' => (bool)$arrival,
'arrival_date' => $arrival ? Carbon::instance($arrival) : null,
'user_info' => $this->faker->optional(.1)->text(),
'active' => $this->faker->boolean(.3),
'force_active' => $this->faker->boolean(.1),
'got_goodie' => $this->faker->boolean(),
'got_shirt' => $this->faker->boolean(),
'got_voucher' => $this->faker->numberBetween(0, 10),
];
}
/**
* Indicate that the user is arrived
*
* @return self
*/
public function arrived(): self
public function arrived()
{
return $this->state(
function (array $attributes) {

View File

@ -1,7 +1,5 @@
<?php
declare(strict_types=1);
namespace Database\Factories\Engelsystem\Models\User;
use Engelsystem\Models\User\User;
@ -10,16 +8,18 @@ use Illuminate\Database\Eloquent\Factories\Factory;
class UserFactory extends Factory
{
/** @var string */
protected $model = User::class; // phpcs:ignore
protected $model = User::class;
public function definition(): array
/**
* @return array
*/
public function definition()
{
return [
'name' => $this->faker->unique()->userName(),
'password' => crypt(random_bytes(16), '$1$salt$'),
'password' => password_hash($this->faker->password(), PASSWORD_DEFAULT),
'email' => $this->faker->unique()->safeEmail(),
'api_key' => bin2hex(random_bytes(32)),
'updated_at' => $this->faker->dateTimeInInterval('-3 months', 'now'),
'api_key' => md5($this->faker->unique()->password()),
];
}
}

View File

@ -1,26 +0,0 @@
<?php
declare(strict_types=1);
namespace Database\Factories\Engelsystem\Models;
use Engelsystem\Models\AngelType;
use Engelsystem\Models\User\User;
use Engelsystem\Models\UserAngelType;
use Illuminate\Database\Eloquent\Factories\Factory;
class UserAngelTypeFactory extends Factory
{
/** @var string */
protected $model = UserAngelType::class; // phpcs:ignore
public function definition(): array
{
return [
'user_id' => User::factory(),
'angel_type_id' => AngelType::factory(),
'confirm_user_id' => $this->faker->optional()->passthrough(User::factory()),
'supporter' => $this->faker->boolean(),
];
}
}

View File

@ -1,7 +1,5 @@
<?php
declare(strict_types=1);
namespace Database\Factories\Engelsystem\Models;
use Engelsystem\Models\User\User;
@ -11,9 +9,12 @@ use Illuminate\Database\Eloquent\Factories\Factory;
class WorklogFactory extends Factory
{
/** @var string */
protected $model = Worklog::class; // phpcs:ignore
protected $model = Worklog::class;
public function definition(): array
/**
* @return array
*/
public function definition()
{
return [
'user_id' => User::factory(),

802
db/install.sql Normal file
View File

@ -0,0 +1,802 @@
-- phpMyAdmin SQL Dump
-- version 4.5.2
-- http://www.phpmyadmin.net
--
-- Host: localhost
-- Erstellungszeit: 27. Sep 2016 um 17:48
-- Server-Version: 10.1.10-MariaDB
-- PHP-Version: 7.0.4
SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
SET time_zone = "+00:00";
--
-- Datenbank: `engelsystem`
--
-- --------------------------------------------------------
--
-- Tabellenstruktur für Tabelle `AngelTypes`
--
DROP TABLE IF EXISTS `AngelTypes`;
CREATE TABLE `AngelTypes` (
`id` int(11) NOT NULL,
`name` varchar(50) NOT NULL DEFAULT '',
`restricted` int(1) NOT NULL,
`description` text NOT NULL,
`requires_driver_license` tinyint(1) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- --------------------------------------------------------
--
-- Tabellenstruktur für Tabelle `EventConfig`
--
DROP TABLE IF EXISTS `EventConfig`;
CREATE TABLE `EventConfig` (
`event_name` varchar(255) DEFAULT NULL,
`buildup_start_date` int(11) DEFAULT NULL,
`event_start_date` int(11) DEFAULT NULL,
`event_end_date` int(11) DEFAULT NULL,
`teardown_end_date` int(11) DEFAULT NULL,
`event_welcome_msg` varchar(255) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- --------------------------------------------------------
--
-- Tabellenstruktur für Tabelle `GroupPrivileges`
--
DROP TABLE IF EXISTS `GroupPrivileges`;
CREATE TABLE `GroupPrivileges` (
`id` int(11) NOT NULL,
`group_id` int(11) NOT NULL,
`privilege_id` int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
--
-- Daten für Tabelle `GroupPrivileges`
--
INSERT INTO `GroupPrivileges` (`id`, `group_id`, `privilege_id`) VALUES
(85, -7, 10),
(87, -7, 18),
(86, -7, 21),
(216, -6, 5),
(212, -6, 6),
(207, -6, 7),
(211, -6, 12),
(208, -6, 13),
(210, -6, 14),
(214, -6, 16),
(209, -6, 21),
(213, -6, 28),
(206, -6, 31),
(215, -6, 33),
(257, -6, 38),
(219, -5, 14),
(221, -5, 25),
(220, -5, 33),
(241, -4, 5),
(238, -4, 14),
(240, -4, 16),
(237, -4, 19),
(242, -4, 25),
(235, -4, 27),
(239, -4, 28),
(236, -4, 32),
(218, -4, 39),
(258, -3, 31),
(247, -2, 3),
(246, -2, 4),
(255, -2, 8),
(252, -2, 9),
(254, -2, 11),
(248, -2, 15),
(251, -2, 17),
(256, -2, 24),
(253, -2, 26),
(245, -2, 30),
(244, -2, 34),
(249, -2, 35),
(243, -2, 36),
(250, -2, 37),
(88, -1, 1),
(23, -1, 2),
(24, -1, 5);
-- --------------------------------------------------------
--
-- Tabellenstruktur für Tabelle `Groups`
--
DROP TABLE IF EXISTS `Groups`;
CREATE TABLE `Groups` (
`Name` varchar(35) NOT NULL,
`UID` int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
--
-- Daten für Tabelle `Groups`
--
INSERT INTO `Groups` (`Name`, `UID`) VALUES
('6-Developer', -7),
('5-Bürokrat', -6),
('4-Team Coordinator', -5),
('3-Shift Coordinator', -4),
('Shirt-Manager', -3),
('2-Engel', -2),
('1-Gast', -1);
-- --------------------------------------------------------
--
-- Tabellenstruktur für Tabelle `LogEntries`
--
DROP TABLE IF EXISTS `LogEntries`;
CREATE TABLE `LogEntries` (
`id` int(11) NOT NULL,
`timestamp` int(11) NOT NULL,
`nick` text NOT NULL,
`message` text NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- --------------------------------------------------------
--
-- Tabellenstruktur für Tabelle `Messages`
--
DROP TABLE IF EXISTS `Messages`;
CREATE TABLE `Messages` (
`id` int(11) NOT NULL,
`Datum` int(11) NOT NULL,
`SUID` int(11) NOT NULL DEFAULT '0',
`RUID` int(11) NOT NULL DEFAULT '0',
`isRead` char(1) NOT NULL DEFAULT 'N',
`Text` text NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Fuers interen Communikationssystem';
-- --------------------------------------------------------
--
-- Tabellenstruktur für Tabelle `NeededAngelTypes`
--
DROP TABLE IF EXISTS `NeededAngelTypes`;
CREATE TABLE `NeededAngelTypes` (
`id` int(11) NOT NULL,
`room_id` int(11) DEFAULT NULL,
`shift_id` int(11) DEFAULT NULL,
`angel_type_id` int(11) NOT NULL,
`count` int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- --------------------------------------------------------
--
-- Tabellenstruktur für Tabelle `News`
--
DROP TABLE IF EXISTS `News`;
CREATE TABLE `News` (
`ID` int(11) NOT NULL,
`Datum` int(11) NOT NULL,
`Betreff` varchar(150) NOT NULL DEFAULT '',
`Text` text NOT NULL,
`UID` int(11) NOT NULL DEFAULT '0',
`Treffen` tinyint(4) NOT NULL DEFAULT '0'
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- --------------------------------------------------------
--
-- Tabellenstruktur für Tabelle `NewsComments`
--
DROP TABLE IF EXISTS `NewsComments`;
CREATE TABLE `NewsComments` (
`ID` bigint(11) NOT NULL,
`Refid` int(11) NOT NULL DEFAULT '0',
`Datum` datetime NOT NULL DEFAULT '0001-01-01 00:00:00',
`Text` text NOT NULL,
`UID` int(11) NOT NULL DEFAULT '0'
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- --------------------------------------------------------
--
-- Tabellenstruktur für Tabelle `Privileges`
--
DROP TABLE IF EXISTS `Privileges`;
CREATE TABLE `Privileges` (
`id` int(11) NOT NULL,
`name` varchar(128) NOT NULL,
`desc` varchar(1024) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
--
-- Daten für Tabelle `Privileges`
--
INSERT INTO `Privileges` (`id`, `name`, `desc`) VALUES
(1, 'start', 'Startseite für Gäste/Nicht eingeloggte User'),
(2, 'login', 'Logindialog'),
(3, 'news', 'Anzeigen der News-Seite'),
(4, 'logout', 'User darf sich ausloggen'),
(5, 'register', 'Einen neuen Engel registerieren'),
(6, 'admin_rooms', 'Räume administrieren'),
(7, 'admin_angel_types', 'Engel Typen administrieren'),
(8, 'user_settings', 'User profile settings'),
(9, 'user_messages', 'Writing and reading messages from user to user'),
(10, 'admin_groups', 'Manage usergroups and their rights'),
(11, 'user_questions', 'Let users ask questions'),
(12, 'admin_questions', 'Answer user''s questions'),
(13, 'admin_faq', 'Edit FAQs'),
(14, 'admin_news', 'Administrate the news section'),
(15, 'news_comments', 'User can comment news'),
(16, 'admin_user', 'Administrate the angels'),
(17, 'user_meetings', 'Lists meetings (news)'),
(18, 'admin_language', 'Translate the system'),
(19, 'admin_log', 'Display recent changes'),
(20, 'user_wakeup', 'User wakeup-service organization'),
(21, 'admin_import', 'Import rooms and shifts from pentabarf'),
(22, 'credits', 'View credits'),
(23, 'faq', 'View FAQ'),
(24, 'user_shifts', 'Signup for shifts'),
(25, 'user_shifts_admin', 'Signup other angels for shifts.'),
(26, 'user_myshifts', 'Allow angels to view their own shifts and cancel them.'),
(27, 'admin_arrive', 'Mark angels when they arrive.'),
(28, 'admin_shifts', 'Create shifts'),
(30, 'ical', 'iCal shift export'),
(31, 'admin_active', 'Mark angels as active and if they got a t-shirt.'),
(32, 'admin_free', 'Show a list of free/unemployed angels.'),
(33, 'admin_user_angeltypes', 'Confirm restricted angel types'),
(34, 'atom', ' Atom news export'),
(35, 'shifts_json_export', 'Export shifts in JSON format'),
(36, 'angeltypes', 'View angeltypes'),
(37, 'user_angeltypes', 'Join angeltypes.'),
(38, 'shifttypes', 'Administrate shift types'),
(39, 'admin_event_config', 'Allow editing event config');
-- --------------------------------------------------------
--
-- Tabellenstruktur für Tabelle `Questions`
--
DROP TABLE IF EXISTS `Questions`;
CREATE TABLE `Questions` (
`QID` bigint(20) NOT NULL,
`UID` int(11) NOT NULL DEFAULT '0',
`Question` text NOT NULL,
`AID` int(11) DEFAULT NULL,
`Answer` text
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Fragen und Antworten';
-- --------------------------------------------------------
--
-- Tabellenstruktur für Tabelle `Room`
--
DROP TABLE IF EXISTS `Room`;
CREATE TABLE `Room` (
`RID` int(11) NOT NULL,
`Name` varchar(35) NOT NULL DEFAULT '',
`Man` text,
`FromPentabarf` char(1) NOT NULL DEFAULT 'N',
`show` char(1) NOT NULL DEFAULT 'Y',
`Number` int(11) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
--
-- Daten für Tabelle `Room`
--
INSERT INTO `Room` (`RID`, `Name`, `Man`, `FromPentabarf`, `show`, `Number`) VALUES
(1, 'Testraum', NULL, '', 'Y', 0);
-- --------------------------------------------------------
--
-- Tabellenstruktur für Tabelle `ShiftEntry`
--
DROP TABLE IF EXISTS `ShiftEntry`;
CREATE TABLE `ShiftEntry` (
`id` int(11) NOT NULL,
`SID` int(11) NOT NULL DEFAULT '0',
`TID` int(11) NOT NULL DEFAULT '0',
`UID` int(11) NOT NULL DEFAULT '0',
`Comment` text,
`freeload_comment` text,
`freeloaded` tinyint(1) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- --------------------------------------------------------
--
-- Tabellenstruktur für Tabelle `Shifts`
--
DROP TABLE IF EXISTS `Shifts`;
CREATE TABLE `Shifts` (
`SID` int(11) NOT NULL,
`title` text,
`shifttype_id` int(11) NOT NULL,
`start` int(11) NOT NULL,
`end` int(11) NOT NULL,
`RID` int(11) NOT NULL DEFAULT '0',
`URL` text,
`PSID` int(11) DEFAULT NULL,
`created_by_user_id` int(11) DEFAULT NULL,
`created_at_timestamp` int(11) NOT NULL,
`edited_by_user_id` int(11) DEFAULT NULL,
`edited_at_timestamp` int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- --------------------------------------------------------
--
-- Tabellenstruktur für Tabelle `ShiftTypes`
--
DROP TABLE IF EXISTS `ShiftTypes`;
CREATE TABLE `ShiftTypes` (
`id` int(11) NOT NULL,
`name` varchar(255) NOT NULL,
`angeltype_id` int(11) DEFAULT NULL,
`description` text NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
--
-- Daten für Tabelle `ShiftTypes`
--
INSERT INTO `ShiftTypes` (`id`, `name`, `angeltype_id`, `description`) VALUES
(4, 'Schichttyp1', NULL, '');
-- --------------------------------------------------------
--
-- Tabellenstruktur für Tabelle `User`
--
DROP TABLE IF EXISTS `User`;
CREATE TABLE `User` (
`UID` int(11) NOT NULL,
`Nick` varchar(23) NOT NULL DEFAULT '',
`Name` varchar(23) DEFAULT NULL,
`Vorname` varchar(23) DEFAULT NULL,
`Alter` int(4) DEFAULT NULL,
`Telefon` varchar(40) DEFAULT NULL,
`DECT` varchar(5) DEFAULT NULL,
`Handy` varchar(40) DEFAULT NULL,
`email` varchar(123) DEFAULT NULL,
`email_shiftinfo` tinyint(1) NOT NULL DEFAULT '0' COMMENT 'User wants to be informed by mail about changes in his shifts',
`jabber` varchar(200) DEFAULT NULL,
`Size` varchar(4) DEFAULT NULL,
`Passwort` varchar(128) DEFAULT NULL,
`password_recovery_token` varchar(32) DEFAULT NULL,
`Gekommen` tinyint(4) NOT NULL DEFAULT '0',
`Aktiv` tinyint(4) NOT NULL DEFAULT '0',
`force_active` tinyint(1) NOT NULL,
`Tshirt` tinyint(4) DEFAULT '0',
`color` tinyint(4) DEFAULT '10',
`Sprache` char(64) NOT NULL,
`Menu` char(1) NOT NULL DEFAULT 'L',
`lastLogIn` int(11) NOT NULL,
`CreateDate` datetime NOT NULL DEFAULT '0001-01-01 00:00:00',
`Art` varchar(30) DEFAULT NULL,
`kommentar` text,
`Hometown` varchar(255) NOT NULL DEFAULT '',
`api_key` varchar(32) NOT NULL,
`got_voucher` int(11) NOT NULL,
`arrival_date` int(11) DEFAULT NULL,
`planned_arrival_date` int(11) NOT NULL,
`planned_departure_date` int(11) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
--
-- Daten für Tabelle `User`
--
INSERT INTO `User` (`UID`, `Nick`, `Name`, `Vorname`, `Alter`, `Telefon`, `DECT`, `Handy`, `email`, `email_shiftinfo`, `jabber`, `Size`, `Passwort`, `password_recovery_token`, `Gekommen`, `Aktiv`, `force_active`, `Tshirt`, `color`, `Sprache`, `Menu`, `lastLogIn`, `CreateDate`, `Art`, `kommentar`, `Hometown`, `api_key`, `got_voucher`, `arrival_date`, `planned_arrival_date`, `planned_departure_date`) VALUES
(1, 'admin', 'Gates', 'Bill', 42, '', '-', '', 'admin@example.com', 1, '', 'XL', '$6$rounds=5000$hjXbIhoRTH3vKiRa$Wl2P2iI5T9iRR.HHu/YFHswBW0WVn0yxCfCiX0Keco9OdIoDK6bIAADswP6KvMCJSwTGdV8PgA8g8Xfw5l8BD1', NULL, 1, 1, 0, 1, 0, 'de_DE.UTF-8', 'L', 1474990948, '0001-01-01 00:00:00', '', '', '', '038850abdd1feb264406be3ffa746235', 0, 1439490478, 1436964455, 1440161255);
-- --------------------------------------------------------
--
-- Tabellenstruktur für Tabelle `UserAngelTypes`
--
DROP TABLE IF EXISTS `UserAngelTypes`;
CREATE TABLE `UserAngelTypes` (
`id` int(11) NOT NULL,
`user_id` int(11) NOT NULL,
`angeltype_id` int(11) NOT NULL,
`confirm_user_id` int(11) DEFAULT NULL,
`coordinator` tinyint(1) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- --------------------------------------------------------
--
-- Tabellenstruktur für Tabelle `UserDriverLicenses`
--
DROP TABLE IF EXISTS `UserDriverLicenses`;
CREATE TABLE `UserDriverLicenses` (
`user_id` int(11) NOT NULL,
`has_car` tinyint(1) NOT NULL,
`has_license_car` tinyint(1) NOT NULL,
`has_license_3_5t_transporter` tinyint(1) NOT NULL,
`has_license_7_5t_truck` tinyint(1) NOT NULL,
`has_license_12_5t_truck` tinyint(1) NOT NULL,
`has_license_forklift` tinyint(1) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
--
-- Daten für Tabelle `UserDriverLicenses`
--
INSERT INTO `UserDriverLicenses` (`user_id`, `has_car`, `has_license_car`, `has_license_3_5t_transporter`, `has_license_7_5t_truck`, `has_license_12_5t_truck`, `has_license_forklift`) VALUES
(1, 1, 1, 1, 1, 1, 1);
-- --------------------------------------------------------
--
-- Tabellenstruktur für Tabelle `UserGroups`
--
DROP TABLE IF EXISTS `UserGroups`;
CREATE TABLE `UserGroups` (
`id` int(11) NOT NULL,
`uid` int(11) NOT NULL,
`group_id` int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
--
-- Daten für Tabelle `UserGroups`
--
INSERT INTO `UserGroups` (`id`, `uid`, `group_id`) VALUES
(3, 1, -7),
(4, 1, -6),
(12, 1, -5),
(2, 1, -4),
(1, 1, -2);
--
-- Indizes der exportierten Tabellen
--
--
-- Indizes für die Tabelle `AngelTypes`
--
ALTER TABLE `AngelTypes`
ADD PRIMARY KEY (`id`),
ADD UNIQUE KEY `Name` (`name`);
--
-- Indizes für die Tabelle `GroupPrivileges`
--
ALTER TABLE `GroupPrivileges`
ADD PRIMARY KEY (`id`),
ADD KEY `group_id` (`group_id`,`privilege_id`),
ADD KEY `privilege_id` (`privilege_id`);
--
-- Indizes für die Tabelle `Groups`
--
ALTER TABLE `Groups`
ADD PRIMARY KEY (`UID`);
--
-- Indizes für die Tabelle `LogEntries`
--
ALTER TABLE `LogEntries`
ADD PRIMARY KEY (`id`),
ADD KEY `timestamp` (`timestamp`);
--
-- Indizes für die Tabelle `Messages`
--
ALTER TABLE `Messages`
ADD PRIMARY KEY (`id`),
ADD KEY `Datum` (`Datum`),
ADD KEY `SUID` (`SUID`),
ADD KEY `RUID` (`RUID`);
--
-- Indizes für die Tabelle `NeededAngelTypes`
--
ALTER TABLE `NeededAngelTypes`
ADD PRIMARY KEY (`id`),
ADD KEY `room_id` (`room_id`,`angel_type_id`),
ADD KEY `shift_id` (`shift_id`),
ADD KEY `angel_type_id` (`angel_type_id`);
--
-- Indizes für die Tabelle `News`
--
ALTER TABLE `News`
ADD PRIMARY KEY (`ID`),
ADD KEY `UID` (`UID`);
--
-- Indizes für die Tabelle `NewsComments`
--
ALTER TABLE `NewsComments`
ADD PRIMARY KEY (`ID`),
ADD KEY `Refid` (`Refid`),
ADD KEY `UID` (`UID`);
--
-- Indizes für die Tabelle `Privileges`
--
ALTER TABLE `Privileges`
ADD PRIMARY KEY (`id`),
ADD UNIQUE KEY `name` (`name`);
--
-- Indizes für die Tabelle `Questions`
--
ALTER TABLE `Questions`
ADD PRIMARY KEY (`QID`),
ADD KEY `UID` (`UID`),
ADD KEY `AID` (`AID`);
--
-- Indizes für die Tabelle `Room`
--
ALTER TABLE `Room`
ADD PRIMARY KEY (`RID`),
ADD UNIQUE KEY `Name` (`Name`);
--
-- Indizes für die Tabelle `ShiftEntry`
--
ALTER TABLE `ShiftEntry`
ADD PRIMARY KEY (`id`),
ADD KEY `TID` (`TID`),
ADD KEY `UID` (`UID`),
ADD KEY `SID` (`SID`,`TID`),
ADD KEY `freeloaded` (`freeloaded`);
--
-- Indizes für die Tabelle `Shifts`
--
ALTER TABLE `Shifts`
ADD PRIMARY KEY (`SID`),
ADD UNIQUE KEY `PSID` (`PSID`),
ADD KEY `RID` (`RID`),
ADD KEY `shifttype_id` (`shifttype_id`),
ADD KEY `created_by_user_id` (`created_by_user_id`),
ADD KEY `edited_by_user_id` (`edited_by_user_id`);
--
-- Indizes für die Tabelle `ShiftTypes`
--
ALTER TABLE `ShiftTypes`
ADD PRIMARY KEY (`id`),
ADD KEY `angeltype_id` (`angeltype_id`);
--
-- Indizes für die Tabelle `User`
--
ALTER TABLE `User`
ADD PRIMARY KEY (`UID`),
ADD UNIQUE KEY `Nick` (`Nick`),
ADD KEY `api_key` (`api_key`),
ADD KEY `password_recovery_token` (`password_recovery_token`),
ADD KEY `force_active` (`force_active`),
ADD KEY `arrival_date` (`arrival_date`,`planned_arrival_date`),
ADD KEY `planned_departure_date` (`planned_departure_date`);
--
-- Indizes für die Tabelle `UserAngelTypes`
--
ALTER TABLE `UserAngelTypes`
ADD PRIMARY KEY (`id`),
ADD KEY `user_id` (`user_id`,`angeltype_id`,`confirm_user_id`),
ADD KEY `angeltype_id` (`angeltype_id`),
ADD KEY `confirm_user_id` (`confirm_user_id`),
ADD KEY `coordinator` (`coordinator`);
--
-- Indizes für die Tabelle `UserDriverLicenses`
--
ALTER TABLE `UserDriverLicenses`
ADD PRIMARY KEY (`user_id`);
--
-- Indizes für die Tabelle `UserGroups`
--
ALTER TABLE `UserGroups`
ADD PRIMARY KEY (`id`),
ADD KEY `uid` (`uid`,`group_id`),
ADD KEY `group_id` (`group_id`);
--
-- AUTO_INCREMENT für exportierte Tabellen
--
--
-- AUTO_INCREMENT für Tabelle `AngelTypes`
--
ALTER TABLE `AngelTypes`
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=4;
--
-- AUTO_INCREMENT für Tabelle `GroupPrivileges`
--
ALTER TABLE `GroupPrivileges`
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=259;
--
-- AUTO_INCREMENT für Tabelle `LogEntries`
--
ALTER TABLE `LogEntries`
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT;
--
-- AUTO_INCREMENT für Tabelle `Messages`
--
ALTER TABLE `Messages`
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT;
--
-- AUTO_INCREMENT für Tabelle `NeededAngelTypes`
--
ALTER TABLE `NeededAngelTypes`
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT;
--
-- AUTO_INCREMENT für Tabelle `News`
--
ALTER TABLE `News`
MODIFY `ID` int(11) NOT NULL AUTO_INCREMENT;
--
-- AUTO_INCREMENT für Tabelle `NewsComments`
--
ALTER TABLE `NewsComments`
MODIFY `ID` bigint(11) NOT NULL AUTO_INCREMENT;
--
-- AUTO_INCREMENT für Tabelle `Privileges`
--
ALTER TABLE `Privileges`
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=40;
--
-- AUTO_INCREMENT für Tabelle `Questions`
--
ALTER TABLE `Questions`
MODIFY `QID` bigint(20) NOT NULL AUTO_INCREMENT;
--
-- AUTO_INCREMENT für Tabelle `Room`
--
ALTER TABLE `Room`
MODIFY `RID` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=2;
--
-- AUTO_INCREMENT für Tabelle `ShiftEntry`
--
ALTER TABLE `ShiftEntry`
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=2;
--
-- AUTO_INCREMENT für Tabelle `Shifts`
--
ALTER TABLE `Shifts`
MODIFY `SID` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=13;
--
-- AUTO_INCREMENT für Tabelle `ShiftTypes`
--
ALTER TABLE `ShiftTypes`
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=5;
--
-- AUTO_INCREMENT für Tabelle `User`
--
ALTER TABLE `User`
MODIFY `UID` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=2;
--
-- AUTO_INCREMENT für Tabelle `UserAngelTypes`
--
ALTER TABLE `UserAngelTypes`
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=2;
--
-- AUTO_INCREMENT für Tabelle `UserGroups`
--
ALTER TABLE `UserGroups`
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=13;
--
-- Constraints der exportierten Tabellen
--
--
-- Constraints der Tabelle `GroupPrivileges`
--
ALTER TABLE `GroupPrivileges`
ADD CONSTRAINT `groupprivileges_ibfk_1` FOREIGN KEY (`group_id`) REFERENCES `Groups` (`UID`) ON DELETE CASCADE ON UPDATE CASCADE,
ADD CONSTRAINT `groupprivileges_ibfk_2` FOREIGN KEY (`privilege_id`) REFERENCES `Privileges` (`id`) ON DELETE CASCADE ON UPDATE CASCADE;
--
-- Constraints der Tabelle `Messages`
--
ALTER TABLE `Messages`
ADD CONSTRAINT `messages_ibfk_1` FOREIGN KEY (`SUID`) REFERENCES `User` (`UID`) ON DELETE CASCADE ON UPDATE CASCADE,
ADD CONSTRAINT `messages_ibfk_2` FOREIGN KEY (`RUID`) REFERENCES `User` (`UID`) ON DELETE CASCADE ON UPDATE CASCADE;
--
-- Constraints der Tabelle `NeededAngelTypes`
--
ALTER TABLE `NeededAngelTypes`
ADD CONSTRAINT `neededangeltypes_ibfk_1` FOREIGN KEY (`room_id`) REFERENCES `Room` (`RID`) ON DELETE CASCADE ON UPDATE CASCADE,
ADD CONSTRAINT `neededangeltypes_ibfk_2` FOREIGN KEY (`shift_id`) REFERENCES `Shifts` (`SID`) ON DELETE CASCADE ON UPDATE CASCADE,
ADD CONSTRAINT `neededangeltypes_ibfk_3` FOREIGN KEY (`angel_type_id`) REFERENCES `AngelTypes` (`id`) ON DELETE CASCADE ON UPDATE CASCADE;
--
-- Constraints der Tabelle `News`
--
ALTER TABLE `News`
ADD CONSTRAINT `news_ibfk_1` FOREIGN KEY (`UID`) REFERENCES `User` (`UID`) ON DELETE CASCADE ON UPDATE CASCADE;
--
-- Constraints der Tabelle `NewsComments`
--
ALTER TABLE `NewsComments`
ADD CONSTRAINT `newscomments_ibfk_1` FOREIGN KEY (`Refid`) REFERENCES `News` (`ID`) ON DELETE CASCADE ON UPDATE CASCADE,
ADD CONSTRAINT `newscomments_ibfk_2` FOREIGN KEY (`UID`) REFERENCES `User` (`UID`) ON DELETE CASCADE ON UPDATE CASCADE;
--
-- Constraints der Tabelle `Questions`
--
ALTER TABLE `Questions`
ADD CONSTRAINT `questions_ibfk_1` FOREIGN KEY (`UID`) REFERENCES `User` (`UID`) ON DELETE CASCADE ON UPDATE CASCADE,
ADD CONSTRAINT `questions_ibfk_2` FOREIGN KEY (`AID`) REFERENCES `User` (`UID`) ON DELETE CASCADE ON UPDATE CASCADE;
--
-- Constraints der Tabelle `ShiftEntry`
--
ALTER TABLE `ShiftEntry`
ADD CONSTRAINT `shiftentry_ibfk_1` FOREIGN KEY (`SID`) REFERENCES `Shifts` (`SID`) ON DELETE CASCADE ON UPDATE CASCADE,
ADD CONSTRAINT `shiftentry_ibfk_2` FOREIGN KEY (`UID`) REFERENCES `User` (`UID`) ON DELETE CASCADE ON UPDATE CASCADE,
ADD CONSTRAINT `shiftentry_ibfk_3` FOREIGN KEY (`TID`) REFERENCES `AngelTypes` (`id`) ON DELETE CASCADE ON UPDATE CASCADE;
--
-- Constraints der Tabelle `Shifts`
--
ALTER TABLE `Shifts`
ADD CONSTRAINT `shifts_ibfk_1` FOREIGN KEY (`RID`) REFERENCES `Room` (`RID`) ON DELETE CASCADE ON UPDATE CASCADE,
ADD CONSTRAINT `shifts_ibfk_2` FOREIGN KEY (`shifttype_id`) REFERENCES `ShiftTypes` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
ADD CONSTRAINT `shifts_ibfk_3` FOREIGN KEY (`created_by_user_id`) REFERENCES `User` (`UID`) ON DELETE SET NULL ON UPDATE CASCADE,
ADD CONSTRAINT `shifts_ibfk_4` FOREIGN KEY (`edited_by_user_id`) REFERENCES `User` (`UID`) ON DELETE SET NULL ON UPDATE CASCADE;
--
-- Constraints der Tabelle `ShiftTypes`
--
ALTER TABLE `ShiftTypes`
ADD CONSTRAINT `shifttypes_ibfk_1` FOREIGN KEY (`angeltype_id`) REFERENCES `AngelTypes` (`id`) ON DELETE CASCADE ON UPDATE CASCADE;
--
-- Constraints der Tabelle `UserAngelTypes`
--
ALTER TABLE `UserAngelTypes`
ADD CONSTRAINT `userangeltypes_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `User` (`UID`) ON DELETE CASCADE ON UPDATE CASCADE,
ADD CONSTRAINT `userangeltypes_ibfk_2` FOREIGN KEY (`angeltype_id`) REFERENCES `AngelTypes` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
ADD CONSTRAINT `userangeltypes_ibfk_3` FOREIGN KEY (`confirm_user_id`) REFERENCES `User` (`UID`) ON DELETE SET NULL ON UPDATE CASCADE;
--
-- Constraints der Tabelle `UserDriverLicenses`
--
ALTER TABLE `UserDriverLicenses`
ADD CONSTRAINT `userdriverlicenses_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `User` (`UID`) ON DELETE CASCADE ON UPDATE CASCADE;
--
-- Constraints der Tabelle `UserGroups`
--
ALTER TABLE `UserGroups`
ADD CONSTRAINT `usergroups_ibfk_1` FOREIGN KEY (`group_id`) REFERENCES `Groups` (`UID`) ON DELETE CASCADE ON UPDATE CASCADE,
ADD CONSTRAINT `usergroups_ibfk_2` FOREIGN KEY (`uid`) REFERENCES `User` (`UID`) ON DELETE CASCADE ON UPDATE CASCADE;

View File

@ -1,15 +1,12 @@
<?php
declare(strict_types=1);
namespace Engelsystem\Migrations;
use Engelsystem\Database\Migration\Migration;
class ImportInstallSql extends Migration
{
/** @var array<string> */
protected array $oldTables = [
protected $oldTables = [
'AngelTypes',
'EventConfig',
'GroupPrivileges',
@ -29,17 +26,31 @@ class ImportInstallSql extends Migration
'UserAngelTypes',
'UserDriverLicenses',
'UserGroups',
'UserWorkLog',
];
/**
* Run the migration
*/
public function up()
{
foreach ($this->oldTables as $table) {
if ($this->schema->hasTable($table)) {
return;
}
}
$sql = file_get_contents(__DIR__ . '/../install.sql');
$this->schema->getConnection()->unprepared($sql);
}
/**
* Reverse the migration
*/
public function down(): void
public function down()
{
$this->schema->getConnection()->statement('SET FOREIGN_KEY_CHECKS=0;');
// Delete all remaining tables
foreach ($this->oldTables as $table) {
if ($this->schema->hasTable($table)) {
$this->schema->dropIfExists($table);

View File

@ -1,12 +1,29 @@
<?php
declare(strict_types=1);
namespace Engelsystem\Migrations;
use Engelsystem\Database\Migration\Migration;
class ImportUpdateSql extends Migration
{
// Do nothing as the tables will be created by later migrations and deleted by ImportInstall
/**
* Run the migration
*/
public function up()
{
if ($this->schema->hasTable('UserWorkLog')) {
return;
}
$sql = file_get_contents(__DIR__ . '/../update.sql');
$this->schema->getConnection()->unprepared($sql);
}
/**
* Reverse the migration
*/
public function down()
{
$this->schema->dropIfExists('UserWorkLog');
}
}

View File

@ -1,7 +1,5 @@
<?php
declare(strict_types=1);
namespace Engelsystem\Migrations;
use Engelsystem\Database\Migration\Migration;
@ -12,7 +10,7 @@ class FixOldTables extends Migration
/**
* Run the migration
*/
public function up(): void
public function up()
{
$connection = $this->schema->getConnection();
@ -31,9 +29,16 @@ class FixOldTables extends Migration
->where($column, '<', '0001-01-01 00:00:00')
->update([$column => '0001-01-01 00:00:00']);
$this->schema->table($table, function (Blueprint $table) use ($column): void {
$this->schema->table($table, function (Blueprint $table) use ($column) {
$table->dateTime($column)->default('0001-01-01 00:00:00')->change();
});
}
}
/**
* Reverse the migration
*/
public function down()
{
}
}

View File

@ -1,7 +1,5 @@
<?php
declare(strict_types=1);
namespace Engelsystem\Migrations;
use Engelsystem\Database\Migration\Migration;
@ -11,7 +9,7 @@ class CleanupGroupPrivileges extends Migration
/**
* Run the migration
*/
public function up(): void
public function up()
{
if (!$this->schema->hasTable('GroupPrivileges')) {
return;
@ -45,7 +43,7 @@ class CleanupGroupPrivileges extends Migration
/**
* Reverse the migration
*/
public function down(): void
public function down()
{
if (!$this->schema->hasTable('GroupPrivileges')) {
return;

View File

@ -1,7 +1,5 @@
<?php
declare(strict_types=1);
namespace Engelsystem\Migrations;
use Engelsystem\Database\Migration\Migration;
@ -9,7 +7,7 @@ use Engelsystem\Database\Migration\Migration;
class AddAngelSupporterPermissions extends Migration
{
/** @var string[] */
protected array $data = [
protected $data = [
'2-Engel',
'shiftentry_edit_angeltype_supporter',
];
@ -17,7 +15,7 @@ class AddAngelSupporterPermissions extends Migration
/**
* Run the migration
*/
public function up(): void
public function up()
{
if (!$this->schema->hasTable('GroupPrivileges')) {
return;
@ -41,7 +39,7 @@ class AddAngelSupporterPermissions extends Migration
/**
* Reverse the migration
*/
public function down(): void
public function down()
{
if (!$this->schema->hasTable('GroupPrivileges')) {
return;
@ -54,7 +52,11 @@ class AddAngelSupporterPermissions extends Migration
);
}
private function getQuery(string $type): string
/**
* @param string $type
* @return string
*/
protected function getQuery($type)
{
return sprintf('
%s FROM GroupPrivileges

View File

@ -1,7 +1,5 @@
<?php
declare(strict_types=1);
namespace Engelsystem\Migrations;
use Engelsystem\Database\Migration\Migration;
@ -12,9 +10,9 @@ class CreateLogEntriesTable extends Migration
/**
* Run the migration
*/
public function up(): void
public function up()
{
$this->schema->create('log_entries', function (Blueprint $table): void {
$this->schema->create('log_entries', function (Blueprint $table) {
$table->increments('id');
$table->string('level', 20);
$table->text('message');
@ -34,9 +32,9 @@ class CreateLogEntriesTable extends Migration
/**
* Reverse the migration
*/
public function down(): void
public function down()
{
$this->schema->create('LogEntries', function (Blueprint $table): void {
$this->schema->create('LogEntries', function (Blueprint $table) {
$table->increments('id');
$table->string('level', 20);
$table->text('message');

View File

@ -1,7 +1,5 @@
<?php
declare(strict_types=1);
namespace Engelsystem\Migrations;
use Engelsystem\Database\Migration\Migration;
@ -12,9 +10,9 @@ class CreateSessionsTable extends Migration
/**
* Run the migration
*/
public function up(): void
public function up()
{
$this->schema->create('sessions', function (Blueprint $table): void {
$this->schema->create('sessions', function (Blueprint $table) {
$table->string('id')->unique();
$table->text('payload');
$table->dateTime('last_activity')->useCurrent();
@ -24,7 +22,7 @@ class CreateSessionsTable extends Migration
/**
* Reverse the migration
*/
public function down(): void
public function down()
{
$this->schema->dropIfExists('sessions');
}

View File

@ -1,18 +1,16 @@
<?php
declare(strict_types=1);
namespace Engelsystem\Migrations;
use Carbon\Carbon;
use Engelsystem\Database\Migration\Migration;
use Engelsystem\Models\EventConfig;
use Illuminate\Database\QueryException;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Collection;
class CreateEventConfigTable extends Migration
{
protected array $mapping = [
protected $mapping = [
'buildup_start_date' => 'buildup_start',
'event_start_date' => 'event_start',
'event_end_date' => 'event_end',
@ -22,11 +20,11 @@ class CreateEventConfigTable extends Migration
/**
* Run the migration
*/
public function up(): void
public function up()
{
foreach (['json', 'text'] as $type) {
try {
$this->schema->create('event_config', function (Blueprint $table) use ($type): void {
$this->schema->create('event_config', function (Blueprint $table) use ($type) {
$table->string('name')->index()->unique();
$table->{$type}('value');
$table->timestamps();
@ -43,24 +41,26 @@ class CreateEventConfigTable extends Migration
}
if ($this->schema->hasTable('EventConfig')) {
$connection = $this->schema->getConnection();
$config = $connection
$config = $this->schema->getConnection()
->table('EventConfig')
->first();
if (!empty($config)) {
$connection->table('event_config')
->insert([
['name' => 'name', 'value' => $config->event_name],
['name' => 'welcome_msg', 'value' => $config->event_welcome_msg],
]);
(new EventConfig([
'name' => 'name',
'value' => $config->event_name,
]))->save();
(new EventConfig([
'name' => 'welcome_msg',
'value' => $config->event_welcome_msg,
]))->save();
foreach ($this->mapping as $old => $new) {
$connection->table('event_config')
->insert([
'name' => $new,
'value' => (new Carbon())->setTimestamp($config->{$old}),
]);
(new EventConfig([
'name' => $new,
'value' => (new Carbon())->setTimestamp($config->{$old}),
]))->save();
}
}
@ -71,11 +71,9 @@ class CreateEventConfigTable extends Migration
/**
* Reverse the migration
*/
public function down(): void
public function down()
{
$connection = $this->schema->getConnection();
$this->schema->create('EventConfig', function (Blueprint $table): void {
$this->schema->create('EventConfig', function (Blueprint $table) {
$table->string('event_name')->nullable();
$table->integer('buildup_start_date')->nullable();
$table->integer('event_start_date')->nullable();
@ -84,19 +82,19 @@ class CreateEventConfigTable extends Migration
$table->string('event_welcome_msg')->nullable();
});
$config = $connection->table('event_config')->get();
$config = new EventConfig();
$data = [
'event_name' => $this->getConfigValue($config, 'name'),
'event_welcome_msg' => $this->getConfigValue($config, 'welcome_msg'),
'event_name' => $config->findOrNew('name')->value,
'event_welcome_msg' => $config->findOrNew('welcome_msg')->value,
];
foreach ($this->mapping as $new => $old) {
$value = $this->getConfigValue($config, $old);
/** @var Carbon $value */
$value = $config->findOrNew($old)->value;
if (!$value) {
continue;
}
$value = Carbon::make($value);
$data[$new] = $value->getTimestamp();
}
@ -113,11 +111,4 @@ class CreateEventConfigTable extends Migration
$this->schema->dropIfExists('event_config');
}
private function getConfigValue(Collection $config, string $name): mixed
{
$value = $config->where('name', $name)->first('value', (object) ['value' => null])->value;
return $value ? json_decode($value, true) : null;
}
}

View File

@ -1,11 +1,15 @@
<?php
declare(strict_types=1);
namespace Engelsystem\Migrations;
use Carbon\Carbon;
use Engelsystem\Database\Migration\Migration;
use Engelsystem\Models\User\Contact;
use Engelsystem\Models\User\PasswordReset;
use Engelsystem\Models\User\PersonalData;
use Engelsystem\Models\User\Settings;
use Engelsystem\Models\User\State;
use Engelsystem\Models\User\User;
use Illuminate\Database\Schema\Blueprint;
use stdClass;
@ -17,9 +21,9 @@ class CreateUsersTables extends Migration
/**
* Run the migration
*/
public function up(): void
public function up()
{
$this->schema->create('users', function (Blueprint $table): void {
$this->schema->create('users', function (Blueprint $table) {
$table->increments('id');
$table->string('name', 24)->unique();
@ -31,7 +35,7 @@ class CreateUsersTables extends Migration
$table->timestamps();
});
$this->schema->create('users_personal_data', function (Blueprint $table): void {
$this->schema->create('users_personal_data', function (Blueprint $table) {
$this->referencesUser($table, true);
$table->string('first_name', 64)->nullable();
@ -42,7 +46,7 @@ class CreateUsersTables extends Migration
$table->date('planned_departure_date')->nullable();
});
$this->schema->create('users_contact', function (Blueprint $table): void {
$this->schema->create('users_contact', function (Blueprint $table) {
$this->referencesUser($table, true);
$table->string('dect', 5)->nullable();
@ -50,7 +54,7 @@ class CreateUsersTables extends Migration
$table->string('email', 254)->nullable();
});
$this->schema->create('users_settings', function (Blueprint $table): void {
$this->schema->create('users_settings', function (Blueprint $table) {
$this->referencesUser($table, true);
$table->string('language', 64);
@ -59,7 +63,7 @@ class CreateUsersTables extends Migration
$table->boolean('email_shiftinfo')->default(false);
});
$this->schema->create('users_state', function (Blueprint $table): void {
$this->schema->create('users_state', function (Blueprint $table) {
$this->referencesUser($table, true);
$table->boolean('arrived')->default(false);
@ -70,7 +74,7 @@ class CreateUsersTables extends Migration
$table->integer('got_voucher')->default(0);
});
$this->schema->create('password_resets', function (Blueprint $table): void {
$this->schema->create('password_resets', function (Blueprint $table) {
$this->referencesUser($table, true);
$table->text('token');
@ -79,33 +83,33 @@ class CreateUsersTables extends Migration
});
if ($this->schema->hasTable('User')) {
$connection = $this->schema->getConnection();
$emptyDates = ['0000-00-00 00:00:00', '0001-01-01 00:00:00', '1000-01-01 00:00:00'];
/** @var stdClass[] $users */
$users = $connection->table('User')->get();
$users = $this->schema->getConnection()->table('User')->get();
foreach ($users as $data) {
$user = [
'id' => $data->UID,
$user = new User([
'name' => $data->Nick,
'password' => $data->Passwort,
'email' => $data->email,
'api_key' => $data->api_key,
'last_login_at' => $data->lastLogIn ? Carbon::createFromTimestamp($data->lastLogIn) : null,
];
if (!in_array($data->CreateDate, $emptyDates)) {
$user['created_at'] = new Carbon($data->CreateDate);
}
$connection->table('users')->insert($user);
$connection->table('users_contact')->insert([
'user_id' => $data->UID,
'dect' => $data->DECT ?: null,
'mobile' => $data->Handy ?: ($data->Telefon ?: null),
]);
$user->setAttribute('id', $data->UID);
if (!in_array($data->CreateDate, $emptyDates)) {
$user->setAttribute('created_at', new Carbon($data->CreateDate));
}
$user->save();
$connection->table('users_personal_data')->insert([
'user_id' => $data->UID,
$contact = new Contact([
'dect' => $data->DECT ? $data->DECT : null,
'mobile' => $data->Handy ?: ($data->Telefon ?: null),
]);
$contact->user()
->associate($user)
->save();
$personalData = new PersonalData([
'first_name' => $data->Vorname ?: null,
'last_name' => $data->Name ?: null,
'shirt_size' => $data->Size ?: null,
@ -116,17 +120,24 @@ class CreateUsersTables extends Migration
? Carbon::createFromTimestamp($data->planned_departure_date)
: null,
]);
$personalData->user()
->associate($user)
->save();
$connection->table('users_settings')->insert([
'user_id' => $data->UID,
$settings = new Settings([
'language' => $data->Sprache,
'theme' => $data->color,
'email_human' => $data->email_by_human_allowed,
'email_shiftinfo' => $data->email_shiftinfo,
]);
unset($settings->email_news);
unset($settings->email_goody);
$connection->table('users_state')->insert([
'user_id' => $data->UID,
$settings->user()
->associate($user)
->save();
$state = new State([
'arrived' => $data->Gekommen,
'arrival_date' => $data->arrival_date ? Carbon::createFromTimestamp($data->arrival_date) : null,
'active' => $data->Aktiv,
@ -134,12 +145,17 @@ class CreateUsersTables extends Migration
'got_shirt' => $data->Tshirt,
'got_voucher' => $data->got_voucher,
]);
$state->user()
->associate($user)
->save();
if ($data->password_recovery_token) {
$connection->table('password_resets')->insert([
'user_id' => $data->UID,
'token' => $data->password_recovery_token,
$passwordReset = new PasswordReset([
'token' => $data->password_recovery_token,
]);
$passwordReset->user()
->associate($user)
->save();
}
}
@ -157,12 +173,10 @@ class CreateUsersTables extends Migration
/**
* Reverse the migration
*/
public function down(): void
public function down()
{
$connection = $this->schema->getConnection();
$this->schema->create('User', function (Blueprint $table): void {
$table->integer('UID', true);
$this->schema->create('User', function (Blueprint $table) {
$table->integer('UID', true, false);
$table->string('Nick', 23)->unique()->default('');
$table->string('Name', 23)->nullable();
@ -203,16 +217,12 @@ class CreateUsersTables extends Migration
$table->index('planned_departure_date', 'planned_departure_date');
});
foreach ($connection->table('users')->get() as $user) {
/** @var stdClass $user */
/** @var stdClass $contact */
$contact = $connection->table('users_contact')->where('user_id', $user->id)->first();
/** @var stdClass $personal */
$personal = $connection->table('users_personal_data')->where('user_id', $user->id)->first();
/** @var stdClass $settings */
$settings = $connection->table('users_settings')->where('user_id', $user->id)->first();
/** @var stdClass $state */
$state = $connection->table('users_state')->where('user_id', $user->id)->first();
foreach (User::all() as $user) {
/** @var User $user */
$contact = $user->contact;
$personal = $user->personalData;
$settings = $user->settings;
$state = $user->state;
$this->schema
->getConnection()
@ -234,28 +244,23 @@ class CreateUsersTables extends Migration
'Tshirt' => $state->got_shirt,
'color' => $settings->theme,
'Sprache' => $settings->language,
'lastLogIn' => $user->last_login_at
? Carbon::make($user->last_login_at)->getTimestamp()
: null,
'CreateDate' => $user->created_at
? Carbon::make($user->created_at)->toDateTimeString()
: '0001-01-01 00:00:00',
'lastLogIn' => $user->last_login_at ? $user->last_login_at->getTimestamp() : null,
'CreateDate' => $user->created_at ? $user->created_at->toDateTimeString() : null,
'api_key' => $user->api_key,
'got_voucher' => $state->got_voucher,
'arrival_date' => $state->arrival_date
? Carbon::make($state->arrival_date)->getTimestamp()
: null,
'arrival_date' => $state->arrival_date ? $state->arrival_date->getTimestamp() : null,
'planned_arrival_date' => $personal->planned_arrival_date
? Carbon::make($personal->planned_arrival_date)->getTimestamp()
: 0,
? $personal->planned_arrival_date->getTimestamp()
: null,
'planned_departure_date' => $personal->planned_departure_date
? Carbon::make($personal->planned_departure_date)->getTimestamp()
? $personal->planned_departure_date->getTimestamp()
: null,
'email_by_human_allowed' => $settings->email_human,
]);
}
foreach ($connection->table('password_resets')->get() as $passwordReset) {
foreach (PasswordReset::all() as $passwordReset) {
/** @var PasswordReset $passwordReset */
$this->schema->getConnection()
->table('User')
->where('UID', '=', $passwordReset->user_id)

View File

@ -1,7 +1,5 @@
<?php
declare(strict_types=1);
namespace Engelsystem\Migrations;
use Engelsystem\Database\Migration\Migration;
@ -9,7 +7,8 @@ use Illuminate\Database\Schema\Blueprint;
class ChangeUsersContactDectFieldSize extends Migration
{
protected array $tables = [
/** @var array */
protected $tables = [
'AngelTypes' => 'contact_dect',
'users_contact' => 'dect',
];
@ -17,7 +16,7 @@ class ChangeUsersContactDectFieldSize extends Migration
/**
* Run the migration
*/
public function up(): void
public function up()
{
$this->changeDectTo(40);
}
@ -25,19 +24,22 @@ class ChangeUsersContactDectFieldSize extends Migration
/**
* Reverse the migration
*/
public function down(): void
public function down()
{
$this->changeDectTo(5);
}
private function changeDectTo(int $length): void
/**
* @param int $length
*/
protected function changeDectTo(int $length)
{
foreach ($this->tables as $table => $column) {
if (!$this->schema->hasTable($table)) {
continue;
}
$this->schema->table($table, function (Blueprint $table) use ($column, $length): void {
$this->schema->table($table, function (Blueprint $table) use ($column, $length) {
$table->string($column, $length)->change();
});
}

View File

@ -1,37 +1,28 @@
<?php
declare(strict_types=1);
namespace Engelsystem\Migrations;
use Engelsystem\Database\Migration\Migration;
use stdClass;
use Engelsystem\Models\User\State;
class FixMissingArrivalDates extends Migration
{
/**
* Run the migration
*/
public function up(): void
public function up()
{
$connection = $this->schema->getConnection();
/** @var stdClass[] $states */
$states = $connection
->table('users_state')
->where('arrived', true)
->where('arrival_date', null)
->get();
$states = State::whereArrived(true)->whereArrivalDate(null)->get();
foreach ($states as $state) {
/** @var stdClass $personalData */
$personalData = $connection
->table('users_personal_data')
->where('user_id', $state->user_id)
->first();
$state->arrival_date = $personalData->planned_arrival_date;
$connection->table('users_state')
->update((array) $state);
$state->arrival_date = $state->user->personalData->planned_arrival_date;
$state->save();
}
}
/**
* Down is not possible and not needed since this is a bugfix.
*/
public function down()
{
}
}

View File

@ -1,7 +1,5 @@
<?php
declare(strict_types=1);
namespace Engelsystem\Migrations;
use Engelsystem\Database\Migration\Migration;
@ -11,26 +9,26 @@ class FixUserLanguages extends Migration
/**
* Run the migration
*/
public function up(): void
public function up()
{
$connection = $this->schema->getConnection();
$connection
->table('users_settings')
->update([
'language' => $connection->raw('REPLACE(language, ".UTF-8", "")'),
'language' => $connection->raw('REPLACE(language, ".UTF-8", "")')
]);
}
/**
* Reverse the migration
*/
public function down(): void
public function down()
{
$connection = $this->schema->getConnection();
$connection
->table('users_settings')
->update([
'language' => $connection->raw('CONCAT(language, ".UTF-8")'),
'language' => $connection->raw('CONCAT(language, ".UTF-8")')
]);
}
}

View File

@ -1,7 +1,5 @@
<?php
declare(strict_types=1);
namespace Engelsystem\Migrations;
use Engelsystem\Database\Migration\Migration;
@ -11,7 +9,7 @@ class MigrateAdminSchedulePermissions extends Migration
/**
* Run the migration
*/
public function up(): void
public function up()
{
if (!$this->schema->hasTable('Privileges')) {
return;
@ -31,7 +29,7 @@ class MigrateAdminSchedulePermissions extends Migration
/**
* Reverse the migration
*/
public function down(): void
public function down()
{
if (!$this->schema->hasTable('Privileges')) {
return;

View File

@ -1,7 +1,5 @@
<?php
declare(strict_types=1);
namespace Engelsystem\Migrations;
use Engelsystem\Database\Migration\Migration;
@ -14,55 +12,76 @@ class CreateScheduleShiftTable extends Migration
/**
* Run the migration
*/
public function up(): void
public function up()
{
$this->schema->create('schedules', function (Blueprint $table): void {
$table->increments('id');
$table->string('url');
});
$this->schema->create('schedule_shift', function (Blueprint $table): void {
$table->integer('shift_id')->index()->unique();
if ($this->schema->hasTable('Shifts')) {
// Legacy table access
$table->foreign('shift_id')
->references('SID')->on('Shifts')
->onUpdate('cascade')
->onDelete('cascade');
$this->schema->create(
'schedules',
function (Blueprint $table) {
$table->increments('id');
$table->string('url');
}
);
$this->references($table, 'schedules');
$table->uuid('guid');
});
$this->schema->create(
'schedule_shift',
function (Blueprint $table) {
$table->integer('shift_id')->index()->unique();
if ($this->schema->hasTable('Shifts')) {
// Legacy table access
$table->foreign('shift_id')
->references('SID')->on('Shifts')
->onUpdate('cascade')
->onDelete('cascade');
}
$this->references($table, 'schedules');
$table->uuid('guid');
}
);
if ($this->schema->hasTable('Shifts')) {
$this->schema->table('Shifts', function (Blueprint $table): void {
$table->dropColumn('PSID');
});
$this->schema->table(
'Shifts',
function (Blueprint $table) {
$table->dropColumn('PSID');
}
);
}
if ($this->schema->hasTable('Room')) {
$this->schema->table('Room', function (Blueprint $table): void {
$table->dropColumn('from_frab');
});
$this->schema->table(
'Room',
function (Blueprint $table) {
$table->dropColumn('from_frab');
}
);
}
}
/**
* Reverse the migration
*/
public function down(): void
public function down()
{
if ($this->schema->hasTable('Room')) {
$this->schema->table('Room', function (Blueprint $table): void {
$table->boolean('from_frab')->default(false);
});
$this->schema->table(
'Room',
function (Blueprint $table) {
$table->boolean('from_frab')
->default(false);
}
);
}
if ($this->schema->hasTable('Shifts')) {
$this->schema->table('Shifts', function (Blueprint $table): void {
$table->integer('PSID')->nullable()->default(null)->unique();
});
$this->schema->table(
'Shifts',
function (Blueprint $table) {
$table->integer('PSID')
->nullable()->default(null)
->unique();
}
);
}
$this->schema->drop('schedule_shift');

View File

@ -64,9 +64,12 @@ class CreateNewsTable extends Migration
$this->schema->drop('new_news');
}
/**
* @return void
*/
private function createNewNewsTable(): void
{
$this->schema->create('news', function (Blueprint $table): void {
$this->schema->create('news', function (Blueprint $table) {
$table->increments('id');
$table->string('title', 150);
$table->text('text');
@ -76,6 +79,9 @@ class CreateNewsTable extends Migration
});
}
/**
* @return void
*/
private function copyPreviousToNewNewsTable(): void
{
$connection = $this->schema->getConnection();
@ -98,18 +104,25 @@ class CreateNewsTable extends Migration
}
}
/**
* @return void
*/
private function createPreviousNewsTable(): void
{
$this->schema->create('News', function (Blueprint $table): void {
$this->schema->create('News', function (Blueprint $table) {
$table->increments('ID');
$table->integer('Datum');
$table->string('Betreff', 150)->default('');
$table->string('Betreff', 150)
->default('');
$table->text('Text');
$this->references($table, 'users', 'UID');
$table->boolean('Treffen')->default(false);
});
}
/**
* @return void
*/
private function copyNewToPreviousNewsTable(): void
{
$connection = $this->schema->getConnection();

View File

@ -53,9 +53,12 @@ class CreateNewsCommentsTable extends Migration
$this->schema->drop('news_comments');
}
/**
* @return void
*/
private function createNewNewsCommentsTable(): void
{
$this->schema->create('news_comments', function (Blueprint $table): void {
$this->schema->create('news_comments', function (Blueprint $table) {
$table->increments('id');
$this->references($table, 'news', 'news_id');
$table->text('text');
@ -64,6 +67,9 @@ class CreateNewsCommentsTable extends Migration
});
}
/**
* @return void
*/
private function copyPreviousToNewNewsCommentsTable(): void
{
$connection = $this->schema->getConnection();
@ -84,9 +90,12 @@ class CreateNewsCommentsTable extends Migration
}
}
/**
* @return void
*/
private function createPreviousNewsCommentsTable(): void
{
$this->schema->create('NewsComments', function (Blueprint $table): void {
$this->schema->create('NewsComments', function (Blueprint $table) {
$table->increments('ID');
$this->references($table, 'news', 'Refid');
$table->dateTime('Datum');
@ -95,6 +104,9 @@ class CreateNewsCommentsTable extends Migration
});
}
/**
* @return void
*/
private function copyNewToPreviousNewsCommentsTable(): void
{
$connection = $this->schema->getConnection();

View File

@ -64,18 +64,27 @@ class CreateMessagesTable extends Migration
$this->schema->drop('new_messages');
}
/**
* @return void
*/
private function createNewMessagesTable(): void
{
$this->schema->create('messages', function (Blueprint $table): void {
$table->increments('id');
$this->referencesUser($table);
$this->references($table, 'users', 'receiver_id');
$table->boolean('read')->default(0);
$table->text('text');
$table->timestamps();
});
$this->schema->create(
'messages',
function (Blueprint $table) {
$table->increments('id');
$this->referencesUser($table);
$this->references($table, 'users', 'receiver_id');
$table->boolean('read')->default(0);
$table->text('text');
$table->timestamps();
}
);
}
/**
* @return void
*/
private function copyPreviousToNewMessagesTable(): void
{
$connection = $this->schema->getConnection();
@ -100,18 +109,28 @@ class CreateMessagesTable extends Migration
}
}
/**
* @return void
*/
private function createPreviousMessagesTable(): void
{
$this->schema->create('Messages', function (Blueprint $table): void {
$table->increments('id');
$table->integer('Datum');
$this->references($table, 'users', 'SUID');
$this->references($table, 'users', 'RUID');
$table->char('isRead')->default('N');
$table->text('Text');
});
$this->schema->create(
'Messages',
function (Blueprint $table) {
$table->increments('id');
$table->integer('Datum');
$this->references($table, 'users', 'SUID');
$this->references($table, 'users', 'RUID');
$table->char('isRead')
->default('N');
$table->text('Text');
}
);
}
/**
* @return void
*/
private function copyNewToPreviousMessagesTable(): void
{
$connection = $this->schema->getConnection();

View File

@ -17,6 +17,9 @@ class CreateQuestionsTable extends Migration
use ChangesReferences;
use Reference;
/**
* @return void
*/
public function up(): void
{
$hasPreviousQuestionsTable = $this->schema->hasTable('Questions');
@ -40,6 +43,9 @@ class CreateQuestionsTable extends Migration
}
}
/**
* @return void
*/
public function down(): void
{
// Rename as some SQL DBMS handle identifiers case insensitive
@ -57,17 +63,28 @@ class CreateQuestionsTable extends Migration
$this->schema->drop('new_questions');
}
/**
* @return void
*/
private function createNewQuestionsTable(): void
{
$this->schema->create('questions', function (Blueprint $table): void {
$table->increments('id');
$this->referencesUser($table);
$table->text('text');
$table->text('answer')->nullable();
$this->references($table, 'users', 'answerer_id')->nullable();
});
$this->schema->create(
'questions',
function (Blueprint $table) {
$table->increments('id');
$this->referencesUser($table);
$table->text('text');
$table->text('answer')
->nullable();
$this->references($table, 'users', 'answerer_id')
->nullable();
}
);
}
/**
* @return void
*/
private function copyPreviousToNewQuestionsTable(): void
{
$connection = $this->schema->getConnection();
@ -87,17 +104,28 @@ class CreateQuestionsTable extends Migration
}
}
/**
* @return void
*/
private function createPreviousQuestionsTable(): void
{
$this->schema->create('Questions', function (Blueprint $table): void {
$table->increments('QID');
$this->references($table, 'users', 'UID');
$table->text('Question');
$this->references($table, 'users', 'AID')->nullable();
$table->text('Answer')->nullable();
});
$this->schema->create(
'Questions',
function (Blueprint $table) {
$table->increments('QID');
$this->references($table, 'users', 'UID');
$table->text('Question');
$this->references($table, 'users', 'AID')
->nullable();
$table->text('Answer')
->nullable();
}
);
}
/**
* @return void
*/
private function copyNewToPreviousQuestionsTable(): void
{
$connection = $this->schema->getConnection();

View File

@ -14,8 +14,11 @@ class UserPersonalDataAddPronounField extends Migration
*/
public function up(): void
{
$this->schema->table('users_personal_data', function (Blueprint $table): void {
$table->string('pronoun', 15)->nullable()->default(null)->after('last_name');
$this->schema->table('users_personal_data', function (Blueprint $table) {
$table->string('pronoun', 15)
->nullable()
->default(null)
->after('last_name');
});
}
@ -24,7 +27,7 @@ class UserPersonalDataAddPronounField extends Migration
*/
public function down(): void
{
$this->schema->table('users_personal_data', function (Blueprint $table): void {
$this->schema->table('users_personal_data', function (Blueprint $table) {
$table->dropColumn('pronoun');
});
}

View File

@ -28,5 +28,11 @@ class ChangeMysqlDatabaseEncodingToUtf8mb4 extends Migration
}
}
// As utf8mb4 is a superset of utf8, there is nothing to do in the downgrade
/**
* Reverse the migration
*/
public function down(): void
{
// As utf8mb4 is a superset of utf8, there is nothing to do here
}
}

View File

@ -5,19 +5,21 @@ declare(strict_types=1);
namespace Engelsystem\Migrations;
use Engelsystem\Database\Migration\Migration;
use Engelsystem\Models\Room;
use Illuminate\Database\Schema\Blueprint;
use stdClass;
class CreateRoomsTable extends Migration
{
use ChangesReferences;
use Reference;
/**
* Run the migration
*/
public function up(): void
{
$this->schema->create('rooms', function (Blueprint $table): void {
$this->schema->create('rooms', function (Blueprint $table) {
$table->increments('id');
$table->string('name', 35)->unique();
$table->string('map_url', 300)->nullable();
@ -33,13 +35,13 @@ class CreateRoomsTable extends Migration
->get();
foreach ($previousRecords as $previousRecord) {
$connection->table('rooms')
->insert([
'id' => $previousRecord->RID,
'name' => $previousRecord->Name,
'map_url' => $previousRecord->map_url ?: null,
'description' => $previousRecord->description ?: null,
]);
$room = new Room([
'name' => $previousRecord->Name,
'map_url' => $previousRecord->map_url ?: null,
'description' => $previousRecord->description ?: null,
]);
$room->setAttribute('id', $previousRecord->RID);
$room->save();
}
$this->changeReferences(
@ -58,18 +60,16 @@ class CreateRoomsTable extends Migration
*/
public function down(): void
{
$connection = $this->schema->getConnection();
$this->schema->create('Room', function (Blueprint $table): void {
$this->schema->create('Room', function (Blueprint $table) {
$table->increments('RID');
$table->string('Name', 35)->unique();
$table->string('map_url', 300)->nullable();
$table->mediumText('description')->nullable();
});
foreach ($connection->table('rooms')->get() as $room) {
/** @var stdClass $room */
$connection
foreach (Room::all() as $room) {
$this->schema
->getConnection()
->table('Room')
->insert([
'RID' => $room->id,

View File

@ -6,6 +6,7 @@ namespace Engelsystem\Migrations;
use Carbon\Carbon;
use Engelsystem\Database\Migration\Migration;
use Engelsystem\Models\Worklog;
use Illuminate\Database\Schema\Blueprint;
use stdClass;
@ -19,7 +20,7 @@ class CreateWorklogsTable extends Migration
*/
public function up(): void
{
$this->schema->create('worklogs', function (Blueprint $table): void {
$this->schema->create('worklogs', function (Blueprint $table) {
$table->increments('id');
$this->referencesUser($table);
$this->references($table, 'users', 'creator_id');
@ -37,20 +38,18 @@ class CreateWorklogsTable extends Migration
->get();
foreach ($previousRecords as $previousRecord) {
$worked_at = Carbon::createFromTimestamp($previousRecord->work_timestamp);
$room = new Worklog([
'user_id' => $previousRecord->user_id,
'creator_id' => $previousRecord->created_user_id,
'worked_at' => $previousRecord->work_timestamp,
'hours' => $previousRecord->work_hours,
'comment' => $previousRecord->comment,
]);
$created_at = Carbon::createFromTimestamp($previousRecord->created_timestamp);
$this->schema->getConnection()
->table('worklogs')
->insert([
'id' => $previousRecord->id,
'user_id' => $previousRecord->user_id,
'creator_id' => $previousRecord->created_user_id,
'worked_at' => $worked_at,
'hours' => $previousRecord->work_hours,
'comment' => $previousRecord->comment,
'created_at' => $created_at,
'updated_at' => $created_at,
]);
$room->setAttribute('id', $previousRecord->id);
$room->setAttribute('created_at', $created_at);
$room->setAttribute('updated_at', $created_at);
$room->save();
}
$this->changeReferences(
@ -69,9 +68,7 @@ class CreateWorklogsTable extends Migration
*/
public function down(): void
{
$connection = $this->schema->getConnection();
$this->schema->create('UserWorkLog', function (Blueprint $table): void {
$this->schema->create('UserWorkLog', function (Blueprint $table) {
$table->increments('id');
$this->referencesUser($table);
$table->integer('work_timestamp');
@ -81,18 +78,19 @@ class CreateWorklogsTable extends Migration
$table->integer('created_timestamp')->index();
});
foreach ($connection->table('worklogs')->get() as $record) {
/** @var stdClass $record */
$connection
foreach (Worklog::all() as $record) {
/** @var Worklog $record */
$this->schema
->getConnection()
->table('UserWorkLog')
->insert([
'id' => $record->id,
'user_id' => $record->user_id,
'work_timestamp' => Carbon::createFromFormat('Y-m-d', $record->worked_at)->timestamp,
'work_timestamp' => $record->worked_at->timestamp,
'work_hours' => $record->hours,
'comment' => $record->comment,
'created_user_id' => $record->creator_id,
'created_timestamp' => Carbon::createFromFormat('Y-m-d H:i:s', $record->created_at)->timestamp,
'created_timestamp' => $record->created_at->timestamp,
]);
}

View File

@ -1,7 +1,5 @@
<?php
declare(strict_types=1);
namespace Engelsystem\Migrations;
use Engelsystem\Database\Migration\Migration;
@ -11,7 +9,7 @@ class CreateWelcomeAngelPermissionsGroup extends Migration
/**
* Run the migration
*/
public function up(): void
public function up()
{
if (!$this->schema->hasTable('Groups')) {
return;
@ -40,7 +38,7 @@ class CreateWelcomeAngelPermissionsGroup extends Migration
/**
* Reverse the migration
*/
public function down(): void
public function down()
{
if (!$this->schema->hasTable('Groups')) {
return;

View File

@ -1,34 +1,32 @@
<?php
declare(strict_types=1);
namespace Engelsystem\Migrations;
use Carbon\Carbon;
use Engelsystem\Database\Migration\Migration;
use Engelsystem\Models\Question;
use Illuminate\Database\Schema\Blueprint;
class AddTimestampsToQuestions extends Migration
{
use ChangesReferences;
/**
* Run the migration
*/
public function up(): void
{
$connection = $this->schema->getConnection();
$now = Carbon::now();
$this->schema->table('questions', function (Blueprint $table): void {
$this->schema->table('questions', function (Blueprint $table) {
$table->timestamp('answered_at')->after('answerer_id')->nullable();
$table->timestamps();
});
$connection->table('questions')
->update([
'created_at' => $now,
'updated_at' => $now,
]);
$connection->table('questions')
$now = Carbon::now();
Question::query()->update([
'created_at' => $now,
'updated_at' => $now,
]);
Question::query()
->whereNotNull('answerer_id')
->update([
'answered_at' => $now,
@ -40,7 +38,7 @@ class AddTimestampsToQuestions extends Migration
*/
public function down(): void
{
$this->schema->table('questions', function (Blueprint $table): void {
$this->schema->table('questions', function (Blueprint $table) {
$table->dropColumn('answered_at');
$table->dropTimestamps();
});

View File

@ -1,7 +1,5 @@
<?php
declare(strict_types=1);
namespace Engelsystem\Migrations;
use Engelsystem\Database\Migration\Migration;
@ -12,9 +10,9 @@ class CreateFaqTableAndPermissions extends Migration
/**
* Run the migration
*/
public function up(): void
public function up()
{
$this->schema->create('faq', function (Blueprint $table): void {
$this->schema->create('faq', function (Blueprint $table) {
$table->increments('id');
$table->string('question');
$table->text('text');
@ -48,7 +46,7 @@ class CreateFaqTableAndPermissions extends Migration
/**
* Reverse the migration
*/
public function down(): void
public function down()
{
$this->schema->drop('faq');

View File

@ -1,7 +1,5 @@
<?php
declare(strict_types=1);
namespace Engelsystem\Migrations;
use Engelsystem\Database\Migration\Migration;
@ -11,7 +9,7 @@ class CreateQuestionsPermissions extends Migration
/**
* Run the migration
*/
public function up(): void
public function up()
{
if ($this->schema->hasTable('Privileges')) {
$db = $this->schema->getConnection();
@ -38,7 +36,7 @@ class CreateQuestionsPermissions extends Migration
/**
* Reverse the migration
*/
public function down(): void
public function down()
{
if (!$this->schema->hasTable('Privileges')) {
return;

View File

@ -16,7 +16,7 @@ class CreateOauthTable extends Migration
*/
public function up(): void
{
$this->schema->create('oauth', function (Blueprint $table): void {
$this->schema->create('oauth', function (Blueprint $table) {
$table->increments('id');
$this->referencesUser($table);
$table->string('provider');

View File

@ -1,11 +1,10 @@
<?php
declare(strict_types=1);
namespace Engelsystem\Migrations;
use Carbon\Carbon;
use Engelsystem\Database\Migration\Migration;
use Engelsystem\Models\Shifts\Schedule;
use Illuminate\Database\Schema\Blueprint;
class AddNameMinutesAndTimestampsToSchedules extends Migration
@ -15,34 +14,39 @@ class AddNameMinutesAndTimestampsToSchedules extends Migration
/**
* Run the migration
*/
public function up(): void
public function up()
{
$connection = $this->schema->getConnection();
$this->schema->table(
'schedules',
function (Blueprint $table) {
$table->string('name')->default('')->after('id');
$table->integer('shift_type')->default(0)->after('name');
$table->integer('minutes_before')->default(0)->after('shift_type');
$table->integer('minutes_after')->default(0)->after('minutes_before');
$table->timestamps();
}
);
$this->schema->table('schedules', function (Blueprint $table): void {
$table->string('name')->default('')->after('id');
$table->unsignedInteger('shift_type')->default(0)->after('name');
$table->integer('minutes_before')->default(0)->after('shift_type');
$table->integer('minutes_after')->default(0)->after('minutes_before');
$table->timestamps();
});
$connection->table('schedules')
Schedule::query()
->update([
'created_at' => Carbon::now(),
'minutes_before' => 15,
'minutes_after' => 15,
]);
$this->schema->table('schedules', function (Blueprint $table): void {
$table->string('name')->default(null)->change();
$table->unsignedInteger('shift_type')->default(null)->change();
$table->integer('minutes_before')->default(null)->change();
$table->integer('minutes_after')->default(null)->change();
});
$this->schema->table(
'schedules',
function (Blueprint $table) {
$table->string('name')->default(null)->change();
$table->integer('shift_type')->default(null)->change();
$table->integer('minutes_before')->default(null)->change();
$table->integer('minutes_after')->default(null)->change();
}
);
// Add legacy reference
if ($this->schema->hasTable('ShiftTypes')) {
$connection = $this->schema->getConnection();
$query = $connection
->table('Shifts')
->select('Shifts.shifttype_id')
@ -50,29 +54,33 @@ class AddNameMinutesAndTimestampsToSchedules extends Migration
->where('schedule_shift.schedule_id', $connection->raw('schedules.id'))
->limit(1);
$connection->table('schedules')
->update([
'shift_type' => $connection->raw('(' . $query->toSql() . ')'),
]);
Schedule::query()
->update(['shift_type' => $connection->raw('(' . $query->toSql() . ')')]);
$this->schema->table('schedules', function (Blueprint $table): void {
$this->addReference($table, 'shift_type', 'ShiftTypes');
});
$this->schema->table(
'schedules',
function (Blueprint $table) {
$this->addReference($table, 'shift_type', 'ShiftTypes');
}
);
}
}
/**
* Reverse the migration
*/
public function down(): void
public function down()
{
$this->schema->table('schedules', function (Blueprint $table): void {
$table->dropForeign('schedules_shift_type_foreign');
$table->dropColumn('name');
$table->dropColumn('shift_type');
$table->dropColumn('minutes_before');
$table->dropColumn('minutes_after');
$table->dropTimestamps();
});
$this->schema->table(
'schedules',
function (Blueprint $table) {
$table->dropForeign('schedules_shift_type_foreign');
$table->dropColumn('name');
$table->dropColumn('shift_type');
$table->dropColumn('minutes_before');
$table->dropColumn('minutes_after');
$table->dropTimestamps();
}
);
}
}

View File

@ -1,7 +1,5 @@
<?php
declare(strict_types=1);
namespace Engelsystem\Migrations;
use Engelsystem\Database\Migration\Migration;
@ -9,23 +7,31 @@ use Illuminate\Database\Schema\Blueprint;
class AddEmailNewsToUsersSettings extends Migration
{
use Reference;
/**
* Run the migration
*/
public function up(): void
public function up()
{
$this->schema->table('users_settings', function (Blueprint $table): void {
$table->boolean('email_news')->default(false)->after('email_shiftinfo');
});
$this->schema->table(
'users_settings',
function (Blueprint $table) {
$table->boolean('email_news')->default(false)->after('email_shiftinfo');
}
);
}
/**
* Reverse the migration
*/
public function down(): void
public function down()
{
$this->schema->table('users_settings', function (Blueprint $table): void {
$table->dropColumn('email_news');
});
$this->schema->table(
'users_settings',
function (Blueprint $table) {
$table->dropColumn('email_news');
}
);
}
}

View File

@ -1,7 +1,5 @@
<?php
declare(strict_types=1);
namespace Engelsystem\Migrations;
use Engelsystem\Database\Migration\Migration;
@ -9,27 +7,35 @@ use Illuminate\Database\Schema\Blueprint;
class OauthAddTokens extends Migration
{
use Reference;
/**
* Run the migration
*/
public function up(): void
public function up()
{
$this->schema->table('oauth', function (Blueprint $table): void {
$table->string('access_token')->nullable()->default(null)->after('identifier');
$table->string('refresh_token')->nullable()->default(null)->after('access_token');
$table->dateTime('expires_at')->nullable()->default(null)->after('refresh_token');
});
$this->schema->table(
'oauth',
function (Blueprint $table) {
$table->string('access_token')->nullable()->default(null)->after('identifier');
$table->string('refresh_token')->nullable()->default(null)->after('access_token');
$table->dateTime('expires_at')->nullable()->default(null)->after('refresh_token');
}
);
}
/**
* Reverse the migration
*/
public function down(): void
public function down()
{
$this->schema->table('oauth', function (Blueprint $table): void {
$table->dropColumn('access_token');
$table->dropColumn('refresh_token');
$table->dropColumn('expires_at');
});
$this->schema->table(
'oauth',
function (Blueprint $table) {
$table->dropColumn('access_token');
$table->dropColumn('refresh_token');
$table->dropColumn('expires_at');
}
);
}
}

View File

@ -1,7 +1,5 @@
<?php
declare(strict_types=1);
namespace Engelsystem\Migrations;
use Engelsystem\Database\Migration\Migration;
@ -9,23 +7,31 @@ use Illuminate\Database\Schema\Blueprint;
class NewsAddIsPinned extends Migration
{
use Reference;
/**
* Run the migration
*/
public function up(): void
public function up()
{
$this->schema->table('news', function (Blueprint $table): void {
$table->boolean('is_pinned')->default(false)->after('is_meeting');
});
$this->schema->table(
'news',
function (Blueprint $table) {
$table->boolean('is_pinned')->default(false)->after('is_meeting');
}
);
}
/**
* Reverse the migration
*/
public function down(): void
public function down()
{
$this->schema->table('news', function (Blueprint $table): void {
$table->dropColumn('is_pinned');
});
$this->schema->table(
'news',
function (Blueprint $table) {
$table->dropColumn('is_pinned');
}
);
}
}

View File

@ -1,7 +1,5 @@
<?php
declare(strict_types=1);
namespace Engelsystem\Migrations;
use Engelsystem\Database\Migration\Migration;
@ -9,25 +7,33 @@ use Illuminate\Database\Schema\Blueprint;
class OauthChangeTokensToText extends Migration
{
use Reference;
/**
* Run the migration
*/
public function up(): void
public function up()
{
$this->schema->table('oauth', function (Blueprint $table): void {
$table->text('access_token')->change();
$table->text('refresh_token')->change();
});
$this->schema->table(
'oauth',
function (Blueprint $table) {
$table->text('access_token')->change();
$table->text('refresh_token')->change();
}
);
}
/**
* Reverse the migration
*/
public function down(): void
public function down()
{
$this->schema->table('oauth', function (Blueprint $table): void {
$table->string('access_token')->change();
$table->string('refresh_token')->change();
});
$this->schema->table(
'oauth',
function (Blueprint $table) {
$table->string('access_token')->change();
$table->string('refresh_token')->change();
}
);
}
}

View File

@ -1,45 +0,0 @@
<?php
declare(strict_types=1);
namespace Engelsystem\Migrations;
use Engelsystem\Config\Config;
use Engelsystem\Database\Migration\Migration;
use Engelsystem\Helpers\Carbon;
use Illuminate\Database\Schema\Builder as SchemaBuilder;
use stdClass;
class CreateFirstUser extends Migration
{
public function __construct(SchemaBuilder $schemaBuilder, protected Config $config)
{
parent::__construct($schemaBuilder);
}
/**
* Run the migration
*/
public function up(): void
{
$db = $this->schema->getConnection();
if ($db->table('users')->count() > 0) {
return;
}
$db->table('users')->insert([
'name' => 'admin',
'email' => 'admin@localhost',
'password' => password_hash('asdfasdf', PASSWORD_DEFAULT),
'api_key' => bin2hex(random_bytes(16)),
'created_at' => Carbon::now(),
]);
/** @var stdClass $admin */
$admin = $db->table('users')->where('name', 'admin')->first();
foreach (['users_contact', 'users_personal_data', 'users_state'] as $table) {
$db->table($table)->insert(['user_id' => $admin->id]);
}
$db->table('users_settings')->insert(['user_id' => $admin->id, 'language' => 'en_US', 'theme' => 0]);
}
}

View File

@ -1,41 +1,48 @@
<?php
declare(strict_types=1);
namespace Engelsystem\Migrations;
use Engelsystem\Config\Config;
use Engelsystem\Database\Migration\Migration;
use Engelsystem\Helpers\Authenticator;
use Engelsystem\Models\User\User;
use Illuminate\Database\Schema\Builder as SchemaBuilder;
use stdClass;
class SetAdminPassword extends Migration
{
public function __construct(SchemaBuilder $schemaBuilder, protected Config $config)
use Reference;
/** @var Authenticator */
protected $auth;
/** @var Config */
protected $config;
/**
* @param SchemaBuilder $schemaBuilder
* @param Authenticator $auth
* @param Config $config
*/
public function __construct(SchemaBuilder $schemaBuilder, Authenticator $auth, Config $config)
{
parent::__construct($schemaBuilder);
$this->auth = $auth;
$this->config = $config;
}
/**
* Run the migration
*/
public function up(): void
public function up()
{
$db = $this->schema->getConnection();
/** @var stdClass $admin */
$admin = $db->table('users')->where('name', 'admin')->first();
/** @var User $admin */
$admin = $this->auth->authenticate('admin', 'asdfasdf');
$setupPassword = $this->config->get('setup_admin_password');
if (
!$admin
|| !password_verify('asdfasdf', $admin->password)
|| !$setupPassword
) {
if (!$admin || !$setupPassword) {
return;
}
$db->table('users')
->where('id', $admin->id)
->update(['password' => password_hash($setupPassword, PASSWORD_DEFAULT)]);
$this->auth->setPassword($admin, $setupPassword);
}
}

View File

@ -1,7 +1,5 @@
<?php
declare(strict_types=1);
namespace Engelsystem\Migrations;
use Engelsystem\Database\Migration\Migration;
@ -11,7 +9,7 @@ class AddShirtEditPermissions extends Migration
/**
* Run the migration
*/
public function up(): void
public function up()
{
if (!$this->schema->hasTable('GroupPrivileges')) {
return;
@ -42,7 +40,7 @@ class AddShirtEditPermissions extends Migration
/**
* Reverse the migration
*/
public function down(): void
public function down()
{
if (!$this->schema->hasTable('GroupPrivileges')) {
return;

View File

@ -1,7 +1,5 @@
<?php
declare(strict_types=1);
namespace Engelsystem\Migrations;
use Engelsystem\Database\Migration\Migration;
@ -9,31 +7,39 @@ use Illuminate\Database\Schema\Blueprint;
class AddShiftsDescription extends Migration
{
use Reference;
/**
* Run the migration
*/
public function up(): void
public function up()
{
if (!$this->schema->hasTable('Shifts')) {
return;
}
$this->schema->table('Shifts', function (Blueprint $table): void {
$table->text('description')->nullable()->after('shifttype_id');
});
$this->schema->table(
'Shifts',
function (Blueprint $table) {
$table->text('description')->nullable()->after('shifttype_id');
}
);
}
/**
* Reverse the migration
*/
public function down(): void
public function down()
{
if (!$this->schema->hasTable('Shifts')) {
return;
}
$this->schema->table('Shifts', function (Blueprint $table): void {
$table->dropColumn('description');
});
$this->schema->table(
'Shifts',
function (Blueprint $table) {
$table->dropColumn('description');
}
);
}
}

View File

@ -16,7 +16,7 @@ class CreateUserLicensesTable extends Migration
*/
public function up(): void
{
$this->schema->create('users_licenses', function (Blueprint $table): void {
$this->schema->create('users_licenses', function (Blueprint $table) {
$this->referencesUser($table, true);
$table->boolean('has_car')->default(false);
$table->boolean('drive_forklift')->default(false);
@ -54,7 +54,7 @@ class CreateUserLicensesTable extends Migration
*/
public function down(): void
{
$this->schema->create('UserDriverLicenses', function (Blueprint $table): void {
$this->schema->create('UserDriverLicenses', function (Blueprint $table) {
$this->referencesUser($table, true);
$table->boolean('has_car');
$table->boolean('has_license_car');

View File

@ -1,7 +1,5 @@
<?php
declare(strict_types=1);
namespace Engelsystem\Migrations;
use Engelsystem\Database\Migration\Migration;
@ -12,9 +10,9 @@ class IncreaseSessionsTablePayloadSize extends Migration
/**
* Run the migration
*/
public function up(): void
public function up()
{
$this->schema->table('sessions', function (Blueprint $table): void {
$this->schema->table('sessions', function (Blueprint $table) {
$table->mediumText('payload')->change();
});
}
@ -22,9 +20,9 @@ class IncreaseSessionsTablePayloadSize extends Migration
/**
* Reverse the migration
*/
public function down(): void
public function down()
{
$this->schema->table('sessions', function (Blueprint $table): void {
$this->schema->table('sessions', function (Blueprint $table) {
$table->text('payload')->change();
});
}

View File

@ -1,7 +1,5 @@
<?php
declare(strict_types=1);
namespace Engelsystem\Migrations;
use Engelsystem\Database\Migration\Migration;
@ -9,17 +7,21 @@ use Illuminate\Database\Schema\Blueprint;
class UsersSettingsAddEmailGoody extends Migration
{
use Reference;
/**
* Run the migration
*/
public function up(): void
public function up()
{
$this->schema->table(
'users_settings',
function (Blueprint $table) {
$table->boolean('email_goody')->default(false)->after('email_human');
}
);
$connection = $this->schema->getConnection();
$this->schema->table('users_settings', function (Blueprint $table): void {
$table->boolean('email_goody')->default(false)->after('email_human');
});
$connection
->table('users_settings')
->update(['email_goody' => $connection->raw('email_human')]);
@ -28,10 +30,13 @@ class UsersSettingsAddEmailGoody extends Migration
/**
* Reverse the migration
*/
public function down(): void
public function down()
{
$this->schema->table('users_settings', function (Blueprint $table): void {
$table->dropColumn('email_goody');
});
$this->schema->table(
'users_settings',
function (Blueprint $table) {
$table->dropColumn('email_goody');
}
);
}
}

View File

@ -1,7 +1,5 @@
<?php
declare(strict_types=1);
namespace Engelsystem\Migrations;
use Engelsystem\Database\Migration\Migration;
@ -11,7 +9,7 @@ class RemoveAdminNewsHtmlPrivilege extends Migration
/**
* Run the migration
*/
public function up(): void
public function up()
{
if (!$this->schema->hasTable('GroupPrivileges')) {
return;
@ -29,7 +27,7 @@ class RemoveAdminNewsHtmlPrivilege extends Migration
/**
* Reverse the migration
*/
public function down(): void
public function down()
{
if (!$this->schema->hasTable('GroupPrivileges')) {
return;

View File

@ -1,7 +1,5 @@
<?php
declare(strict_types=1);
namespace Engelsystem\Migrations;
use Engelsystem\Database\Migration\Migration;
@ -15,9 +13,9 @@ class IncreaseTshirtFieldWidth extends Migration
/**
* Run the migration
*/
public function up(): void
public function up()
{
$this->schema->table('users_personal_data', function (Blueprint $table): void {
$this->schema->table('users_personal_data', function (Blueprint $table) {
$table->string('shirt_size', 10)->change();
});
}
@ -25,9 +23,9 @@ class IncreaseTshirtFieldWidth extends Migration
/**
* Reverse the migration
*/
public function down(): void
public function down()
{
$this->schema->table('users_personal_data', function (Blueprint $table): void {
$this->schema->table('users_personal_data', function (Blueprint $table) {
$table->string('shirt_size', 4)->change();
});
}

View File

@ -1,7 +1,5 @@
<?php
declare(strict_types=1);
namespace Engelsystem\Migrations;
use Engelsystem\Database\Migration\Migration;
@ -11,7 +9,7 @@ class CreateVoucherEditPermission extends Migration
/**
* Run the migration
*/
public function up(): void
public function up()
{
if (!$this->schema->hasTable('Privileges')) {
return;
@ -38,7 +36,7 @@ class CreateVoucherEditPermission extends Migration
/**
* Reverse the migration
*/
public function down(): void
public function down()
{
if (!$this->schema->hasTable('Privileges')) {
return;

View File

@ -18,7 +18,7 @@ class ShiftsAddTransactionId extends Migration
return;
}
$this->schema->table('Shifts', function (Blueprint $table): void {
$this->schema->table('Shifts', function (Blueprint $table) {
$table->uuid('transaction_id')->index()->nullable()->default(null);
});
}
@ -32,7 +32,7 @@ class ShiftsAddTransactionId extends Migration
return;
}
$this->schema->table('Shifts', function (Blueprint $table): void {
$this->schema->table('Shifts', function (Blueprint $table) {
$table->dropColumn('transaction_id');
});
}

View File

@ -1,82 +0,0 @@
<?php
declare(strict_types=1);
namespace Engelsystem\Migrations;
use Engelsystem\Database\Migration\Migration;
class FixOldGroupsTableIdAndName extends Migration
{
/** @var string[] */
protected array $naming = [
'1-Gast' => 'Guest',
'2-Engel' => 'Angel',
'Shirt-Manager' => 'Shirt Manager',
'3-Shift Coordinator' => 'Shift Coordinator',
'4-Team Coordinator' => 'Team Coordinator',
'5-Bürokrat' => 'Bureaucrat',
'6-Developer' => 'Developer',
];
/** @var int[] */
protected array $ids = [
-25 => -30,
-26 => -35,
-30 => -50,
-40 => -60,
-50 => -65,
-60 => -80,
-65 => -85,
-70 => -90,
];
/**
* Run the migration
*/
public function up(): void
{
$this->migrate($this->naming, $this->ids);
}
/**
* Reverse the migration
*/
public function down(): void
{
$this->migrate(array_flip($this->naming), array_flip($this->ids));
}
/**
* @param string[] $naming
* @param int[] $ids
*/
private function migrate(array $naming, array $ids): void
{
if (!$this->schema->hasTable('Groups')) {
return;
}
$connection = $this->schema->getConnection();
foreach ($connection->table('Groups')->orderByDesc('UID')->get() as $data) {
if (isset($naming[$data->Name])) {
$data->Name = $naming[$data->Name];
}
$data->oldId = $data->UID;
if (isset($ids[$data->oldId])) {
$data->UID = $ids[$data->oldId];
} elseif (isset($ids[$data->oldId * -1])) {
$data->UID = $ids[$data->oldId * -1] * -1;
}
$connection
->table('Groups')
->where('UID', $data->oldId)
->update([
'UID' => $data->UID * -1,
'Name' => $data->Name,
]);
}
}
}

View File

@ -1,31 +0,0 @@
<?php
declare(strict_types=1);
namespace Engelsystem\Migrations;
use Engelsystem\Database\Migration\Migration;
use Illuminate\Database\Schema\Blueprint;
class AddMobileShowToUsersSettings extends Migration
{
/**
* Run the migration
*/
public function up(): void
{
$this->schema->table('users_settings', function (Blueprint $table): void {
$table->boolean('mobile_show')->default(false)->after('email_news');
});
}
/**
* Reverse the migration
*/
public function down(): void
{
$this->schema->table('users_settings', function (Blueprint $table): void {
$table->dropColumn('mobile_show');
});
}
}

View File

@ -1,31 +0,0 @@
<?php
declare(strict_types=1);
namespace Engelsystem\Migrations;
use Engelsystem\Database\Migration\Migration;
use Illuminate\Database\Schema\Blueprint;
class AddDectToRooms extends Migration
{
/**
* Run the migration
*/
public function up(): void
{
$this->schema->table('rooms', function (Blueprint $table): void {
$table->text('dect')->nullable()->after('description');
});
}
/**
* Reverse the migration
*/
public function down(): void
{
$this->schema->table('rooms', function (Blueprint $table): void {
$table->dropColumn('dect');
});
}
}

View File

@ -1,39 +0,0 @@
<?php
declare(strict_types=1);
namespace Engelsystem\Migrations;
use Engelsystem\Database\Migration\Migration;
use Illuminate\Database\Schema\Blueprint;
class AddHideRegisterToAngeltypes extends Migration
{
/**
* Run the migration
*/
public function up(): void
{
if (!$this->schema->hasTable('AngelTypes')) {
return;
}
$this->schema->table('AngelTypes', function (Blueprint $table): void {
$table->boolean('hide_register')->default(false)->after('show_on_dashboard');
});
}
/**
* Reverse the migration
*/
public function down(): void
{
if (!$this->schema->hasTable('AngelTypes')) {
return;
}
$this->schema->table('AngelTypes', function (Blueprint $table): void {
$table->dropColumn('hide_register');
});
}
}

View File

@ -1,262 +0,0 @@
<?php
declare(strict_types=1);
namespace Engelsystem\Migrations;
use Engelsystem\Database\Migration\Migration;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Database\Schema\Blueprint;
use stdClass;
class CreatePrivilegesAndGroupsRelatedTables extends Migration
{
use ChangesReferences;
use Reference;
/**
* Creates the new table, copies the data and drops the old one.
*/
public function up(): void
{
$hasPrevious = $this->schema->hasTable('Privileges');
if ($hasPrevious) {
// Rename because some DBMS handle identifiers case-insensitive
$this->schema->rename('Groups', 'groups_old');
$this->schema->rename('Privileges', 'privileges_old');
}
$this->createNew();
if ($hasPrevious) {
$this->copyOldToNew();
$this->changeReferences(
'groups_old',
'UID',
'groups',
'id'
);
$this->changeReferences(
'privileges_old',
'id',
'privileges',
'id'
);
$this->changeReferences(
'UserGroups',
'id',
'users_groups',
'id'
);
$this->changeReferences(
'GroupPrivileges',
'id',
'group_privileges',
'id'
);
$this->schema->drop('UserGroups');
$this->schema->drop('GroupPrivileges');
$this->schema->drop('groups_old');
$this->schema->drop('privileges_old');
}
}
/**
* Recreates the previous table, copies the data and drops the new one.
*/
public function down(): void
{
// Rename because some DBMS handle identifiers case-insensitive
$this->schema->rename('groups', 'groups_new');
$this->schema->rename('privileges', 'privileges_new');
$this->createOldTable();
$this->copyNewToOld();
$this->changeReferences(
'groups_new',
'id',
'Groups',
'UID',
'integer'
);
$this->changeReferences(
'privileges_new',
'id',
'Privileges',
'id'
);
$this->changeReferences(
'users_groups',
'id',
'UserGroups',
'id'
);
$this->changeReferences(
'group_privileges',
'id',
'GroupPrivileges',
'id'
);
$this->schema->drop('users_groups');
$this->schema->drop('group_privileges');
$this->schema->drop('groups_new');
$this->schema->drop('privileges_new');
}
private function createNew(): void
{
$this->schema->create('groups', function (Blueprint $table): void {
$table->increments('id');
$table->string('name', 35)->unique();
});
$this->schema->create('privileges', function (Blueprint $table): void {
$table->increments('id');
$table->string('name', 128)->unique();
$table->string('description', 1024);
});
$this->schema->create('users_groups', function (Blueprint $table): void {
$table->increments('id');
$this->referencesUser($table)->index();
$this->references($table, 'groups')->index();
});
$this->schema->create('group_privileges', function (Blueprint $table): void {
$table->increments('id');
$this->references($table, 'groups')->index();
$this->references($table, 'privileges')->index();
});
}
private function createOldTable(): void
{
$this->schema->create('Groups', function (Blueprint $table): void {
$table->string('Name', 35);
$table->integer('UID')->primary();
});
$this->schema->create('Privileges', function (Blueprint $table): void {
$table->increments('id');
$table->string('name', 128)->unique();
$table->string('desc', 1024);
});
$this->schema->create('UserGroups', function (Blueprint $table): void {
$table->increments('id');
$this->references($table, 'users', 'uid');
$this->references($table, 'Groups', 'group_id', 'UID', false, 'integer')->index();
$table->index(['uid', 'group_id']);
});
$this->schema->create('GroupPrivileges', function (Blueprint $table): void {
$table->increments('id');
$this->references($table, 'Groups', 'group_id', 'UID', false, 'integer');
$this->references($table, 'Privileges', 'privilege_id')->index();
$table->index(['group_id', 'privilege_id']);
});
}
private function copyOldToNew(): void
{
$connection = $this->schema->getConnection();
/** @var stdClass[] $records */
$records = $connection
->table('groups_old')
->get();
foreach ($records as $record) {
$connection->table('groups')->insert([
'id' => $record->UID,
'name' => $record->Name,
]);
}
$records = $connection
->table('privileges_old')
->get();
foreach ($records as $record) {
$connection->table('privileges')->insert([
'id' => $record->id,
'name' => $record->name,
'description' => $record->desc,
]);
}
$records = $connection
->table('UserGroups')
->get();
foreach ($records as $record) {
$connection->table('users_groups')->insert([
'id' => $record->id,
'user_id' => $record->uid,
'group_id' => $record->group_id,
]);
}
$records = $connection
->table('GroupPrivileges')
->get();
foreach ($records as $record) {
$connection->table('group_privileges')->insert([
'id' => $record->id,
'group_id' => $record->group_id,
'privilege_id' => $record->privilege_id,
]);
}
}
private function copyNewToOld(): void
{
$connection = $this->schema->getConnection();
/** @var Collection|stdClass[] $records */
$records = $connection
->table('groups_new')
->get();
foreach ($records as $record) {
$connection->table('Groups')->insert([
'Name' => $record->name,
'UID' => $record->id,
]);
}
$records = $connection
->table('privileges_new')
->get();
foreach ($records as $record) {
$connection->table('Privileges')->insert([
'id' => $record->id,
'name' => $record->name,
'desc' => $record->description,
]);
}
$records = $connection
->table('users_groups')
->get();
foreach ($records as $record) {
$connection->table('UserGroups')->insert([
'id' => $record->id,
'uid' => $record->user_id,
'group_id' => $record->group_id,
]);
}
$records = $connection
->table('group_privileges')
->get();
foreach ($records as $record) {
$connection->table('GroupPrivileges')->insert([
'id' => $record->id,
'group_id' => $record->group_id,
'privilege_id' => $record->privilege_id,
]);
}
}
}

View File

@ -1,158 +0,0 @@
<?php
declare(strict_types=1);
namespace Engelsystem\Migrations;
use Engelsystem\Database\Migration\Migration;
use stdClass;
class FillPrivilegesAndGroupsRelatedTables extends Migration
{
/**
* Inserts missing data into permissions & groups related tables
*/
public function up(): void
{
$db = $this->schema->getConnection();
if ($db->table('privileges')->count() > 0) {
return;
}
$db->table('groups')
->insert([
['id' => 10, 'name' => 'Guest'],
['id' => 20, 'name' => 'Angel'],
['id' => 30, 'name' => 'Welcome Angel'],
['id' => 35, 'name' => 'Voucher Angel'],
['id' => 50, 'name' => 'Shirt Manager'],
['id' => 60, 'name' => 'Shift Coordinator'],
['id' => 65, 'name' => 'Team Coordinator'],
['id' => 80, 'name' => 'Bureaucrat'],
['id' => 85, 'name' => 'News Admin'],
['id' => 90, 'name' => 'Developer'],
]);
$db->table('privileges')
->insert([
['id' => 1, 'name' => 'start', 'description' => 'Startseite für Gäste/Nicht eingeloggte User'],
['id' => 2, 'name' => 'login', 'description' => 'Logindialog'],
['id' => 3, 'name' => 'news', 'description' => 'Anzeigen der News-Seite'],
['id' => 4, 'name' => 'logout', 'description' => 'User darf sich ausloggen'],
['id' => 5, 'name' => 'register', 'description' => 'Einen neuen Engel registerieren'],
['id' => 6, 'name' => 'admin_rooms', 'description' => 'Räume administrieren'],
['id' => 7, 'name' => 'admin_angel_types', 'description' => 'Engel Typen administrieren'],
['id' => 8, 'name' => 'user_settings', 'description' => 'User profile settings'],
['id' => 9, 'name' => 'user_messages',
'description' => 'Writing and reading messages from user to user'],
['id' => 10, 'name' => 'admin_groups', 'description' => 'Manage usergroups and their rights'],
['id' => 14, 'name' => 'admin_news', 'description' => 'Administrate the news section'],
['id' => 15, 'name' => 'news_comments', 'description' => 'User can comment news'],
['id' => 16, 'name' => 'admin_user', 'description' => 'Administrate the angels'],
['id' => 17, 'name' => 'user_meetings', 'description' => 'Lists meetings (news)'],
['id' => 18, 'name' => 'admin_language', 'description' => 'Translate the system'],
['id' => 19, 'name' => 'admin_log', 'description' => 'Display recent changes'],
['id' => 21, 'name' => 'schedule.import', 'description' => 'Import rooms and shifts from schedule.xml'],
['id' => 24, 'name' => 'user_shifts', 'description' => 'Signup for shifts'],
['id' => 25, 'name' => 'user_shifts_admin', 'description' => 'Signup other angels for shifts.'],
['id' => 26, 'name' => 'user_myshifts',
'description' => 'Allow angels to view their own shifts and cancel them.'],
['id' => 27, 'name' => 'admin_arrive', 'description' => 'Mark angels when they arrive.'],
['id' => 28, 'name' => 'admin_shifts', 'description' => 'Create shifts'],
['id' => 30, 'name' => 'ical', 'description' => 'iCal shift export'],
['id' => 31, 'name' => 'admin_active',
'description' => 'Mark angels as active and if they got a t-shirt.'],
['id' => 32, 'name' => 'admin_free', 'description' => 'Show a list of free/unemployed angels.'],
['id' => 33, 'name' => 'admin_user_angeltypes', 'description' => 'Confirm restricted angel types'],
['id' => 34, 'name' => 'atom', 'description' => ' Atom news export'],
['id' => 35, 'name' => 'shifts_json_export', 'description' => 'Export shifts in JSON format'],
['id' => 36, 'name' => 'angeltypes', 'description' => 'View angeltypes'],
['id' => 37, 'name' => 'user_angeltypes', 'description' => 'Join angeltypes.'],
['id' => 38, 'name' => 'shifttypes', 'description' => 'Administrate shift types'],
['id' => 39, 'name' => 'admin_event_config', 'description' => 'Allow editing event config'],
['id' => 40, 'name' => 'view_rooms', 'description' => 'User can view rooms'],
['id' => 41, 'name' => 'shiftentry_edit_angeltype_supporter',
'description' => 'If user with this privilege is angeltype supporter, '
. 'he can put users in shifts for their angeltype'],
['id' => 43, 'name' => 'admin_user_worklog', 'description' => 'Manage user work log entries.'],
['id' => 44, 'name' => 'faq.view', 'description' => 'View FAQ entries'],
['id' => 45, 'name' => 'faq.edit', 'description' => 'Edit FAQ entries'],
['id' => 46, 'name' => 'question.add', 'description' => 'Ask questions'],
['id' => 47, 'name' => 'question.edit', 'description' => 'Answer questions'],
['id' => 48, 'name' => 'user.edit.shirt', 'description' => 'Edit user shirts'],
['id' => 49, 'name' => 'voucher.edit', 'description' => 'Edit vouchers'],
]);
$db->table('group_privileges')->insert([
['id' => 23, 'group_id' => 10, 'privilege_id' => 2],
['id' => 24, 'group_id' => 10, 'privilege_id' => 5],
['id' => 85, 'group_id' => 90, 'privilege_id' => 10],
['id' => 86, 'group_id' => 90, 'privilege_id' => 21],
['id' => 87, 'group_id' => 90, 'privilege_id' => 18],
['id' => 88, 'group_id' => 10, 'privilege_id' => 1],
['id' => 206, 'group_id' => 80, 'privilege_id' => 31],
['id' => 207, 'group_id' => 80, 'privilege_id' => 7],
['id' => 209, 'group_id' => 80, 'privilege_id' => 21],
['id' => 210, 'group_id' => 80, 'privilege_id' => 14],
['id' => 212, 'group_id' => 80, 'privilege_id' => 6],
['id' => 213, 'group_id' => 80, 'privilege_id' => 28],
['id' => 214, 'group_id' => 80, 'privilege_id' => 16],
['id' => 215, 'group_id' => 80, 'privilege_id' => 33],
['id' => 216, 'group_id' => 80, 'privilege_id' => 5],
['id' => 218, 'group_id' => 60, 'privilege_id' => 39],
['id' => 219, 'group_id' => 65, 'privilege_id' => 14],
['id' => 220, 'group_id' => 65, 'privilege_id' => 33],
['id' => 221, 'group_id' => 65, 'privilege_id' => 25],
['id' => 235, 'group_id' => 60, 'privilege_id' => 27],
['id' => 236, 'group_id' => 60, 'privilege_id' => 32],
['id' => 237, 'group_id' => 60, 'privilege_id' => 19],
['id' => 238, 'group_id' => 60, 'privilege_id' => 14],
['id' => 239, 'group_id' => 60, 'privilege_id' => 28],
['id' => 240, 'group_id' => 60, 'privilege_id' => 16],
['id' => 241, 'group_id' => 60, 'privilege_id' => 5],
['id' => 242, 'group_id' => 60, 'privilege_id' => 25],
['id' => 243, 'group_id' => 20, 'privilege_id' => 36],
['id' => 244, 'group_id' => 20, 'privilege_id' => 34],
['id' => 245, 'group_id' => 20, 'privilege_id' => 30],
['id' => 246, 'group_id' => 20, 'privilege_id' => 4],
['id' => 247, 'group_id' => 20, 'privilege_id' => 3],
['id' => 248, 'group_id' => 20, 'privilege_id' => 15],
['id' => 249, 'group_id' => 20, 'privilege_id' => 35],
['id' => 250, 'group_id' => 20, 'privilege_id' => 37],
['id' => 251, 'group_id' => 20, 'privilege_id' => 17],
['id' => 252, 'group_id' => 20, 'privilege_id' => 9],
['id' => 253, 'group_id' => 20, 'privilege_id' => 26],
['id' => 255, 'group_id' => 20, 'privilege_id' => 8],
['id' => 256, 'group_id' => 20, 'privilege_id' => 24],
['id' => 257, 'group_id' => 80, 'privilege_id' => 38],
['id' => 258, 'group_id' => 50, 'privilege_id' => 31],
['id' => 259, 'group_id' => 20, 'privilege_id' => 40],
['id' => 260, 'group_id' => 85, 'privilege_id' => 14],
['id' => 262, 'group_id' => 60, 'privilege_id' => 43],
['id' => 263, 'group_id' => 20, 'privilege_id' => 41],
['id' => 264, 'group_id' => 30, 'privilege_id' => 27],
['id' => 265, 'group_id' => 10, 'privilege_id' => 44],
['id' => 266, 'group_id' => 20, 'privilege_id' => 44],
['id' => 267, 'group_id' => 60, 'privilege_id' => 45],
['id' => 268, 'group_id' => 20, 'privilege_id' => 46],
['id' => 269, 'group_id' => 60, 'privilege_id' => 47],
['id' => 270, 'group_id' => 60, 'privilege_id' => 48],
['id' => 271, 'group_id' => 50, 'privilege_id' => 48],
['id' => 272, 'group_id' => 50, 'privilege_id' => 27],
['id' => 273, 'group_id' => 60, 'privilege_id' => 49],
['id' => 274, 'group_id' => 35, 'privilege_id' => 49],
['id' => 275, 'group_id' => 35, 'privilege_id' => 27],
]);
/** @var stdClass $admin */
$admin = $db->table('users')->where('name', 'admin')->first();
if (!$admin) {
return;
}
// Angel, ShiCo, Team coordinator, Bureaucrat, Dev
foreach ([20, 60, 65, 80, 90] as $group) {
$db->table('users_groups')->insert(['user_id' => $admin->id, 'group_id' => $group]);
}
}
}

View File

@ -1,43 +0,0 @@
<?php
declare(strict_types=1);
namespace Engelsystem\Migrations;
use Engelsystem\Database\Migration\Migration;
use Illuminate\Database\Schema\Blueprint;
class ShifttypeRemoveAngeltype extends Migration
{
use Reference;
/**
* Run the migration
*/
public function up(): void
{
if (!$this->schema->hasTable('ShiftTypes')) {
return;
}
$this->schema->table('ShiftTypes', function (Blueprint $table): void {
$table->dropForeign('shifttypes_ibfk_1');
$table->dropColumn('angeltype_id');
});
}
/**
* Reverse the migration
*/
public function down(): void
{
if (!$this->schema->hasTable('ShiftTypes')) {
return;
}
$this->schema->table('ShiftTypes', function (Blueprint $table): void {
$table->integer('angeltype_id')->after('name')->index()->nullable();
$this->addReference($table, 'angeltype_id', 'AngelTypes', null, 'shifttypes_ibfk_1');
});
}
}

View File

@ -1,86 +0,0 @@
<?php
declare(strict_types=1);
namespace Engelsystem\Migrations;
use Engelsystem\Database\Migration\Migration;
use Illuminate\Database\Schema\Blueprint;
use stdClass;
class CreateShiftTypesTable extends Migration
{
use ChangesReferences;
/**
* Creates the new table, copies the data and drops the old one
*/
public function up(): void
{
$connection = $this->schema->getConnection();
$this->schema->create('shift_types', function (Blueprint $table): void {
$table->increments('id');
$table->string('name')->unique();
$table->text('description');
});
if (!$this->schema->hasTable('ShiftTypes')) {
return;
}
/** @var stdClass[] $records */
$records = $connection
->table('ShiftTypes')
->get();
foreach ($records as $record) {
$connection->table('shift_types')->insert([
'id' => $record->id,
'name' => $record->name,
'description' => $record->description,
]);
}
$this->changeReferences(
'ShiftTypes',
'id',
'shift_types',
'id'
);
$this->schema->drop('ShiftTypes');
}
/**
* Recreates the previous table, copies the data and drops the new one
*/
public function down(): void
{
$connection = $this->schema->getConnection();
$this->schema->create('ShiftTypes', function (Blueprint $table): void {
$table->increments('id');
$table->string('name', 255);
$table->mediumText('description');
});
/** @var stdClass[] $records */
$records = $connection
->table('shift_types')
->get();
foreach ($records as $record) {
$connection->table('ShiftTypes')->insert([
'id' => $record->id,
'name' => $record->name,
'description' => $record->description,
]);
}
$this->changeReferences(
'shift_types',
'id',
'ShiftTypes',
'id'
);
$this->schema->drop('shift_types');
}
}

View File

@ -1,126 +0,0 @@
<?php
declare(strict_types=1);
namespace Engelsystem\Migrations;
use Engelsystem\Database\Migration\Migration;
use Illuminate\Support\Collection;
use Illuminate\Database\Schema\Blueprint;
use stdClass;
class CreateAngelTypesTable extends Migration
{
use ChangesReferences;
/**
* Creates the new table, copies the data and drops the old one
*/
public function up(): void
{
$connection = $this->schema->getConnection();
$this->schema->create('angel_types', function (Blueprint $table): void {
$table->increments('id');
$table->string('name')->unique();
$table->text('description')->default('');
$table->string('contact_name')->default('');
$table->string('contact_dect')->default('');
$table->string('contact_email')->default('');
$table->boolean('restricted')->default(false);
$table->boolean('requires_driver_license')->default(false);
$table->boolean('no_self_signup')->default(false);
$table->boolean('show_on_dashboard')->default(true);
$table->boolean('hide_register')->default(false);
});
if (!$this->schema->hasTable('AngelTypes')) {
return;
}
/** @var Collection|stdClass[] $records */
$records = $connection
->table('AngelTypes')
->get();
foreach ($records as $record) {
$connection->table('angel_types')->insert([
'id' => $record->id,
'name' => $record->name,
'description' => $record->description,
'contact_name' => (string) $record->contact_name,
'contact_dect' => (string) $record->contact_dect,
'contact_email' => (string) $record->contact_email,
'restricted' => $record->restricted,
'requires_driver_license' => $record->requires_driver_license,
'no_self_signup' => $record->no_self_signup,
'show_on_dashboard' => $record->show_on_dashboard,
'hide_register' => $record->hide_register,
]);
}
$this->changeReferences(
'AngelTypes',
'id',
'angel_types',
'id'
);
$this->schema->drop('AngelTypes');
}
/**
* Recreates the previous table, copies the data and drops the new one
*/
public function down(): void
{
$connection = $this->schema->getConnection();
$this->schema->create('AngelTypes', function (Blueprint $table): void {
$table->integer('id', true);
$table->string('name', 50)->default('')->unique();
$table->boolean('restricted');
$table->mediumText('description');
$table->boolean('requires_driver_license');
$table->boolean('no_self_signup');
$table->string('contact_name', 250)->nullable();
$table->string('contact_dect', 40)->nullable();
$table->string('contact_email', 250)->nullable();
$table->boolean('show_on_dashboard');
$table->boolean('hide_register')->default(false);
});
/** @var Collection|stdClass[] $records */
$records = $connection
->table('angel_types')
->get();
foreach ($records as $record) {
$connection->table('AngelTypes')->insert([
'id' => $record->id,
'name' => $record->name,
'description' => $record->description,
'contact_name' => $record->contact_name ?: null,
'contact_dect' => $record->contact_dect ?: null,
'contact_email' => $record->contact_email ?: null,
'restricted' => $record->restricted,
'requires_driver_license' => $record->requires_driver_license,
'no_self_signup' => $record->no_self_signup,
'show_on_dashboard' => $record->show_on_dashboard,
'hide_register' => $record->hide_register,
]);
}
$this->changeReferences(
'angel_types',
'id',
'AngelTypes',
'id',
'integer'
);
$this->schema->drop('angel_types');
}
}

View File

@ -1,101 +0,0 @@
<?php
declare(strict_types=1);
namespace Engelsystem\Migrations;
use Engelsystem\Database\Migration\Migration;
use Illuminate\Database\Schema\Blueprint;
use stdClass;
class CreateUserAngelTypesTable extends Migration
{
use ChangesReferences;
use Reference;
/**
* Creates the new table, copies the data and drops the old one
*/
public function up(): void
{
$connection = $this->schema->getConnection();
$this->schema->create('user_angel_type', function (Blueprint $table): void {
$table->increments('id');
$this->referencesUser($table);
$this->references($table, 'angel_types')->index();
$this->references($table, 'users', 'confirm_user_id')->nullable()->default(null)->index();
$table->boolean('supporter')->default(false)->index();
$table->index(['user_id', 'angel_type_id', 'confirm_user_id']);
$table->unique(['user_id', 'angel_type_id']);
});
if (!$this->schema->hasTable('UserAngelTypes')) {
return;
}
/** @var stdClass[] $records */
$records = $connection
->table('UserAngelTypes')
->get();
foreach ($records as $record) {
$connection->table('user_angel_type')->insert([
'id' => $record->id,
'user_id' => $record->user_id,
'angel_type_id' => $record->angeltype_id,
'confirm_user_id' => $record->confirm_user_id ?: null,
'supporter' => (bool) $record->supporter,
]);
}
$this->changeReferences(
'UserAngelTypes',
'id',
'user_angel_type',
'id'
);
$this->schema->drop('UserAngelTypes');
}
/**
* Recreates the previous table, copies the data and drops the new one
*/
public function down(): void
{
$connection = $this->schema->getConnection();
$this->schema->create('UserAngelTypes', function (Blueprint $table): void {
$table->increments('id');
$this->referencesUser($table);
$this->references($table, 'angel_types', 'angeltype_id')->index('angeltype_id');
$this->references($table, 'users', 'confirm_user_id')->nullable()->index('confirm_user_id');
$table->boolean('supporter')->nullable()->index('coordinator');
$table->index(['user_id', 'angeltype_id', 'confirm_user_id'], 'user_id');
});
/** @var stdClass[] $records */
$records = $connection
->table('user_angel_type')
->get();
foreach ($records as $record) {
$connection->table('UserAngelTypes')->insert([
'id' => $record->id,
'user_id' => $record->user_id,
'angeltype_id' => $record->angel_type_id,
'confirm_user_id' => $record->confirm_user_id ?: null,
'supporter' => (bool) $record->supporter,
]);
}
$this->changeReferences(
'user_angel_type',
'id',
'UserAngelTypes',
'id',
'integer'
);
$this->schema->drop('user_angel_type');
}
}

View File

@ -1,45 +0,0 @@
<?php
declare(strict_types=1);
namespace Engelsystem\Migrations;
use Engelsystem\Database\Migration\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Str;
class ChangeApiKeyLength extends Migration
{
/**
* Run the migration
*/
public function up(): void
{
$this->schema->table('users', function (Blueprint $table): void {
$table->string('api_key', 64)->change();
});
}
/**
* Reverse the migration
*/
public function down(): void
{
$connection = $this->schema->getConnection();
$data = $connection->table('users')->get(['id', 'api_key']);
foreach ($data as $user) {
if (Str::length($user->api_key) <= 32) {
continue;
}
$key = Str::substr($user->api_key, 0, 32);
$connection->table('users')
->where('id', $user->id)
->update(['api_key' => $key]);
}
$this->schema->table('users', function (Blueprint $table): void {
$table->string('api_key', 32)->change();
});
}
}

View File

@ -1,149 +0,0 @@
<?php
declare(strict_types=1);
namespace Engelsystem\Migrations;
use Engelsystem\Database\Migration\Migration;
use Engelsystem\Helpers\Carbon;
use Illuminate\Database\Schema\Blueprint;
use stdClass;
class CreateShiftsTable extends Migration
{
use ChangesReferences;
use Reference;
/**
* Creates the new table, copies the data and drops the old one
*/
public function up(): void
{
$connection = $this->schema->getConnection();
$previous = $this->schema->hasTable('Shifts');
if ($previous) {
$this->schema->rename('Shifts', 'shifts_old');
}
$this->schema->create('shifts', function (Blueprint $table): void {
$table->increments('id');
$table->string('title');
$table->text('description')->default('');
$table->string('url')->default('');
$table->dateTime('start')->index();
$table->dateTime('end');
$this->references($table, 'shift_types');
$this->references($table, 'rooms');
$table->uuid('transaction_id')->nullable()->default(null)->index();
$this->references($table, 'users', 'created_by');
$this->references($table, 'users', 'updated_by')->nullable()->default(null);
$table->timestamps();
});
if (!$previous) {
return;
}
/** @var stdClass[] $records */
$records = $connection
->table('shifts_old')
->get();
foreach ($records as $record) {
$isUpdated = !empty($record->edited_at_timestamp)
&& $record->edited_at_timestamp != $record->created_at_timestamp;
$connection->table('shifts')->insert([
'id' => $record->SID,
'title' => (string) $record->title,
'description' => (string) $record->description,
'url' => (string) $record->URL,
'start' => Carbon::createFromTimestamp($record->start),
'end' => Carbon::createFromTimestamp($record->end),
'shift_type_id' => $record->shifttype_id,
'room_id' => $record->RID,
'transaction_id' => $record->transaction_id,
'created_by' => $record->created_by_user_id,
'updated_by' => $isUpdated ? $record->edited_by_user_id : null,
'created_at' => Carbon::createFromTimestamp($record->created_at_timestamp),
'updated_at' => $isUpdated ? Carbon::createFromTimestamp($record->edited_at_timestamp) : null,
]);
}
$this->changeReferences(
'shifts_old',
'SID',
'shifts',
'id'
);
$this->schema->drop('shifts_old');
}
/**
* Recreates the previous table, copies the data and drops the new one
*/
public function down(): void
{
$connection = $this->schema->getConnection();
$this->schema->rename('shifts', 'shifts_old');
$this->schema->create('Shifts', function (Blueprint $table): void {
$table->increments('SID');
$table->mediumText('title')->nullable()->default(null);
$this->references($table, 'shift_types', 'shifttype_id');
$table->text('description')->nullable()->default(null);
$table->integer('start')->index();
$table->integer('end');
$this->references($table, 'rooms', 'RID')->default(0);
$table->mediumText('URL')->nullable()->default(null);
$this->references($table, 'users', 'created_by_user_id')->nullable()->default(null);
$table->integer('created_at_timestamp');
$this->references($table, 'users', 'edited_by_user_id')->nullable()->default(null);
$table->integer('edited_at_timestamp');
$table->uuid('transaction_id')->nullable()->default(null)->index();
});
/** @var stdClass[] $records */
$records = $connection
->table('shifts_old')
->get();
$now = Carbon::now()->getTimestamp();
foreach ($records as $record) {
$createdAt = $record->created_at ? Carbon::make($record->created_at)->getTimestamp() : $now;
$updatedAt = $record->updated_at ? Carbon::make($record->updated_at)->getTimestamp() : $createdAt;
$connection->table('Shifts')->insert([
'SID' => $record->id,
'title' => $record->title,
'shifttype_id' => $record->shift_type_id,
'description' => $record->description ?: null,
'start' => Carbon::make($record->start)->getTimestamp(),
'end' => Carbon::make($record->end)->getTimestamp(),
'RID' => $record->room_id,
'URL' => $record->url ?: null,
'created_by_user_id' => $record->created_by,
'created_at_timestamp' => $createdAt,
'edited_by_user_id' => $record->updated_by,
'edited_at_timestamp' => $updatedAt,
'transaction_id' => $record->transaction_id,
]);
}
$this->changeReferences(
'shifts_old',
'id',
'Shifts',
'SID'
);
$this->schema->drop('shifts_old');
}
}

View File

@ -1,114 +0,0 @@
<?php
declare(strict_types=1);
namespace Engelsystem\Migrations;
use Engelsystem\Database\Migration\Migration;
use Illuminate\Database\Schema\Blueprint;
use stdClass;
class CreateShiftEntriesTable extends Migration
{
use ChangesReferences;
use Reference;
/**
* Creates the new table, copies the data and drops the old one
*/
public function up(): void
{
$connection = $this->schema->getConnection();
$previous = $this->schema->hasTable('ShiftEntry');
$this->schema->create('shift_entries', function (Blueprint $table): void {
$table->increments('id');
$this->references($table, 'shifts');
$this->references($table, 'angel_types');
$this->referencesUser($table);
$table->mediumText('user_comment')->default('');
$table->boolean('freeloaded')->default(false)->index();
$table->mediumText('freeloaded_comment')->default('');
$table->index(['angel_type_id', 'shift_id']);
});
if (!$previous) {
return;
}
/** @var stdClass[] $records */
$records = $connection
->table('ShiftEntry')
->get();
foreach ($records as $record) {
$connection->table('shift_entries')->insert([
'id' => $record->id,
'shift_id' => $record->SID,
'angel_type_id' => $record->TID,
'user_id' => $record->UID,
'user_comment' => $record->Comment,
'freeloaded' => (bool) $record->freeloaded,
'freeloaded_comment' => $record->freeload_comment,
]);
}
$this->changeReferences(
'ShiftEntry',
'id',
'shift_entries',
'id'
);
$this->schema->drop('ShiftEntry');
}
/**
* Recreates the previous table, copies the data and drops the new one
*/
public function down(): void
{
$connection = $this->schema->getConnection();
$this->schema->create('ShiftEntry', function (Blueprint $table): void {
$table->increments('id');
$this->references($table, 'shifts', 'SID')->default(0);
$this->references($table, 'angel_types', 'TID')->default(0);
$this->references($table, 'users', 'UID')->default(0);
$table->mediumText('Comment')->nullable();
$table->mediumText('freeload_comment')->nullable()->default(null);
$table->boolean('freeloaded')->index();
$table->index(['SID', 'TID']);
});
/** @var stdClass[] $records */
$records = $connection
->table('shift_entries')
->get();
foreach ($records as $record) {
$connection->table('ShiftEntry')->insert([
'id' => $record->id,
'SID' => $record->shift_id,
'TID' => $record->angel_type_id,
'UID' => $record->user_id,
'Comment' => $record->user_comment,
'freeloaded' => (bool) $record->freeloaded,
'freeload_comment' => $record->freeloaded_comment,
]);
}
$this->changeReferences(
'shift_entries',
'id',
'ShiftEntry',
'id'
);
$this->schema->drop('shift_entries');
}
}

Some files were not shown because too many files have changed in this diff Show More