Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • alexander.vorwerk/studip
  • hochschule-wismar/stud-ip
  • tleilax/studip
  • marcus/studip
  • manschwa/studip
  • eberhardt/studip
  • uol/studip
  • pluta/studip
  • thienel/extern-uni-b
  • studip/studip
  • strohm/studip
  • uni-osnabrueck/studip
  • FloB/studip
  • universit-t-rostock/studip
  • Robinyyy/studip
  • jakob.diel/studip
  • HyperSpeeed/studip
  • ann/studip
  • nod3zer0/stud-ip-siple-saml-php-plugin
19 results
Show changes
Commits on Source (2608)
Showing
with 3256 additions and 227 deletions
......@@ -20,3 +20,6 @@ block_comment_start = /*
block_comment_end = */
line_comment = //
quote_type = single
[*.yml]
indent_size = 2
\ No newline at end of file
# MYSQL_HOST=""
# MYSQL_USER=""
# MYSQL_PASSWORD=""
# MYSQL_DATABASE=""
# Enable the next line to display the debug bar in development mode
# DEBUG_BAR=1
# Enable the following to allow opening files from exception displays in your
# editor. Beware: You need to provide a full path for prefix your files since
# the exception only displays the relative path.
#
# Variables being substituted: %{file} and %{line}
#
# EDITOR_URL="phpstorm://open?file=<path-to-your-studip>/%{file}&line=%{line}"
# EDITOR_URL="vscode://file/<path-to-your-studip>/%{file}:%{line}:0
# STUDIP_CACHING_ENABLE=""
# STUDIP_CACHE_IS_SESSION_STORAGE=""
# STUDIP_ENV=""
# STUDIP_MAIL_TRANSPORT=""
# STUDIP_PLUGINS_UPLOAD_ENABLE=""
## You may also change configuration settings from the environment. To do so, prefix the configuration name with
## "STUDIP_CONFIG_". Example for changing the site name:
#
# STUDIP_CONFIG_UNI_NAME_CLEAN="new uni name"
{
"parserOptions": {
"parser": "@babel/eslint-parser",
"sourceType": "module"
},
"env": {
"browser": true,
"es6": true
},
"extends": [
"eslint:recommended",
"plugin:vue/essential"
],
"globals": {
"STUDIP": "writable",
"CKEDITOR": "writable",
"$": "writable",
"_": "writable",
"jQuery": "writable"
},
"plugins": [
"vue"
],
"rules": {
"no-unused-vars": "off",
"no-async-promise-executor": "error",
"no-await-in-loop": "error",
"no-promise-executor-return": "error",
"require-atomic-updates": "error",
"max-nested-callbacks": ["error", 4],
"no-return-await": "error",
"prefer-promise-reject-errors": "error"
}
}
*~
.env
.webpack.*
composer
node_modules
......@@ -21,6 +23,7 @@ data/oer_logos/*
data/upload_doc/*
public/.htaccess
public/.rnd
public/assets/javascripts/*.js
public/assets/javascripts/*.js.map
public/assets/stylesheets/*.css
......@@ -29,13 +32,10 @@ public/pictures/banner/*.gif
public/pictures/banner/*.jpeg
public/pictures/banner/*.jpg
public/pictures/banner/*.png
public/pictures/course/[0-9a-f]*.png
public/pictures/institute/[0-9a-f]*.png
public/pictures/smile/*.gif
public/pictures/smile/*.jpeg
public/pictures/smile/*.jpg
public/pictures/smile/*.png
public/pictures/user/[0-9a-f]*.png
public/pictures/stock-images/*
public/pictures/course/*/*.webp
public/pictures/institute/*/*.webp
public/pictures/user/*/*.webp
public/plugins_packages/*
tests/_log
......@@ -44,6 +44,9 @@ tests/_helpers/TestGuy.php
tests/_helpers/WebGuy.php
tests/_helpers/_generated
tests/_output/
tests/e2e/.auth
tests/e2e/test-results/*
playwright-report/*
.idea
/config/oauth2/*.key
......
image: studip/studip:tests-php7.2
image: studip/studip:tests-php8.1
variables:
FF_NETWORK_PER_BUILD: 1
GIT_DEPTH: 1
MYSQL_RANDOM_ROOT_PASSWORD: "true"
MYSQL_DATABASE: studip_db
MYSQL_USER: studip_user
......@@ -12,199 +14,371 @@ variables:
# Optimize caching
FF_USE_FASTZIP: "true"
CACHE_COMPRESSION_LEVEL: "fast"
# User faster docker driver
# Use faster docker driver
DOCKER_DRIVER: overlay2
# Images
NODE_IMAGE: node:18-slim
# Directories
CACHE_DIR: .caches
REPORT_DIR: .reports
# Set npm cache directory
npm_config_cache: $CI_PROJECT_DIR/.npm
stages:
- build
- checks
- analyse
- tests
- test
- cache
- packaging
- release
- build
.scripts:
install-composer:
mkdir-caches: &mkdir-caches
- mkdir -p $CACHE_DIR
mkdir-reports: &mkdir-reports
- mkdir -p $REPORT_DIR
install-composer: &install-composer
- make composer-dev
configure-studip:
- !reference [.scripts, install-composer]
configure-studip: &configure-studip
- *install-composer
- cp docker/studip/config_local.php config/config_local.inc.php
- cp config/config.inc.php.dist config/config.inc.php
initialize-studip-database:
- !reference [.scripts, configure-studip]
initialize-studip-database: &initialize-studip-database
- *configure-studip
- chmod +x .gitlab/scripts/install_db.sh
- .gitlab/scripts/install_db.sh
- cli/studip migrate
remove-absolute-path-in-report:
- sed -i "s%$PWD/%%" tests/_output/report.xml
.artifacts:
common: &common-artifacts
when: always
expire_in: 1 week
tests: &test-artifacts
<<: *common-artifacts
paths:
- tests/_output
reports:
junit: tests/_output/report.xml
.caches:
php: &composer-cache
key: "php-$CI_COMMIT_REF_SLUG"
composer: &composer-cache
key:
files:
- composer.lock
paths:
- composer/
- .caches/phplint-cache
- .caches/resultCache.php
- .caches/cache/*
- .caches/resultCaches/*
js: &npm-cache
key: "js-$CI_COMMIT_REF_SLUG"
policy: pull
npm: &npm-cache
key:
files:
- package-lock.json
paths:
- node_modules/
- .caches/eslint-cache
- .caches/stylelint-cache
- .npm
.definitions:
mariadb-service: &mariadb-service
- name: mariadb
command: [ "--sql_mode=","--character-set-client=utf8","--character-set-server=utf8","--collation-server=utf8_unicode_ci"]
build-composer:
stage: build
needs: []
interruptible: true
variables:
COMPOSER_CACHE: $CACHE_DIR/composer-cache
before_script:
- mkdir -p $COMPOSER_CACHE
script:
- composer install
cache:
- *composer-cache
- key: composer-package-cache
paths:
- $COMPOSER_CACHE
policy: pull-push
lint-php:
stage: checks
needs: []
cache: *composer-cache
allow_failure: false
needs: [build-composer]
variables:
CACHE_LOCATION: $CACHE_DIR/phplint-cache
PHPLINT_JSON_REPORT: $REPORT_DIR/phplint-report.json
PHPLINT_CODE_QUALITY_REPORT: $REPORT_DIR/phplint-codequality.json
interruptible: true
cache:
- *composer-cache
- key: "$CI_JOB_NAME_SLUG:$CI_COMMIT_REF_SLUG"
paths:
- $CACHE_LOCATION
before_script:
- !reference [.scripts, install-composer]
- mkdir -p .reports
- *mkdir-caches
- *mkdir-reports
- *install-composer
script:
- php -d memory_limit=-1 composer/bin/phplint --xml .reports/phplint-report.xml --cache=.caches/phplint-cache
- COMPOSER_MEMORY_LIMIT=-1
composer exec phplint
--
--log-json=$PHPLINT_JSON_REPORT
--cache=$CACHE_LOCATION
after_script:
- ./.gitlab/scripts/convert-phplint-report $PHPLINT_JSON_REPORT > $PHPLINT_CODE_QUALITY_REPORT
artifacts:
<<: *common-artifacts
paths:
- .reports/phplint-report.xml
reports:
junit: .reports/phplint-report.xml
codequality: $PHPLINT_CODE_QUALITY_REPORT
lint-php-8.3:
image: studip/studip:tests-php8.3
stage: checks
needs: [build-composer]
variables:
CACHE_LOCATION: $CACHE_DIR/phplint-cache
PHPLINT_JSON_REPORT: $REPORT_DIR/phplint-report-8.3.json
PHPLINT_CODE_QUALITY_REPORT: $REPORT_DIR/phplint-codequality-8.3.json
interruptible: true
cache:
- *composer-cache
- key: "$CI_JOB_NAME_SLUG:$CI_COMMIT_REF_SLUG"
paths:
- $CACHE_LOCATION
before_script:
- *mkdir-caches
- *mkdir-reports
- *install-composer
script:
- COMPOSER_MEMORY_LIMIT=-1
composer exec phplint
--
--log-json=$PHPLINT_JSON_REPORT
--cache=$CACHE_LOCATION
after_script:
- ./.gitlab/scripts/convert-phplint-report $PHPLINT_JSON_REPORT > $PHPLINT_CODE_QUALITY_REPORT
artifacts:
reports:
codequality: $PHPLINT_CODE_QUALITY_REPORT
lint-js:
stage: checks
needs: []
cache: *npm-cache
allow_failure: false
image: $NODE_IMAGE
variables:
CACHE_LOCATION: $CACHE_DIR/eslint-cache
ESLINT_CODE_QUALITY_REPORT: $REPORT_DIR/eslint-codequality.json
cache:
- key: "$CI_JOB_NAME_SLUG:$CI_COMMIT_REF_SLUG"
paths:
- $CACHE_LOCATION
interruptible: true
before_script:
- make npm
- *mkdir-reports
- npm ci --prefer--offline
script:
- npm run lint -- --cache --cache-location .caches/eslint-cache --format ./node_modules/eslint-junit/index.js
- npm run lint-js --
--cache --cache-location $CACHE_LOCATION
--format gitlab
artifacts:
<<: *common-artifacts
paths:
- .reports/eslint-report.xml
reports:
junit: .reports/eslint-report.xml
codequality: $ESLINT_CODE_QUALITY_REPORT
lint-css:
stage: checks
needs: []
cache: *npm-cache
allow_failure: false
image: $NODE_IMAGE
variables:
CACHE_LOCATION: $CACHE_DIR/stylelint-cache
STYLELINT_CODE_QUALITY_REPORT: $REPORT_DIR/stylelint-codequality.json
interruptible: true
cache:
- key: "CI_COMMIT_REF_SLUG-lint-css"
paths:
- $CACHE_LOCATION
policy: pull-push
when: always
before_script:
- make npm
- *mkdir-caches
- *mkdir-reports
- npm install
script:
- npm run css-lint -s -- --cache --cache-location .caches/stylelint-cache --custom-formatter node_modules/stylelint-junit-formatter --output-file .reports/stylelint-report.xml
- npm run lint-css --
--cache --cache-location $CACHE_LOCATION
--custom-formatter=node_modules/stylelint-formatter-gitlab
--output-file $STYLELINT_CODE_QUALITY_REPORT
artifacts:
<<: *common-artifacts
paths:
- .reports/stylelint-report.xml
reports:
junit: .reports/stylelint-report.xml
codequality: $STYLELINT_CODE_QUALITY_REPORT
phpstan:
stage: analyse
needs: [lint-php]
allow_failure: true
needs: [build-composer]
variables:
CACHE_LOCATION: $CACHE_DIR/phpstan
PHPSTAN_CODE_QUALITY_REPORT: $REPORT_DIR/phpstan-codequality.json
interruptible: true
when: manual
cache: *composer-cache
cache:
- *composer-cache
- key: "$CO_JOB_NAME_SLUG:$CI_COMMIT_REF_SLUG"
paths:
- $CACHE_LOCATION
before_script:
- make composer-dev
- mkdir .reports -p
- *mkdir-caches
- *mkdir-reports
- *install-composer
- 'echo -e "includes:\n - phpstan.neon.dist\n\nparameters:\n tmpDir: $PHPSTAN_CACHE_PATH" > phpstan.neon'
script:
- php composer/bin/phpstan analyse --memory-limit=1G --no-progress --level=$PHPSTAN_LEVEL --error-format=gitlab > .reports/report-phpstan.json
- php
composer/bin/phpstan analyse
--memory-limit=1G
--no-progress
--level=$PHPSTAN_LEVEL
--error-format=gitlab > $PHPSTAN_CODE_QUALITY_REPORT
after_script:
- rm phpstan.neon
artifacts:
paths:
- .reports/report-phpstan.json
expire_in: 14 days
when: always
reports:
codequality: .reports/report-phpstan.json
codequality: $PHPSTAN_CODE_QUALITY_REPORT
test-unit:
stage: tests
stage: test
needs: [lint-php]
variables:
PHPUNIT_XML_REPORT: $REPORT_DIR/phpunit-report.xml
cache:
<<: *composer-cache
policy: pull
allow_failure: false
interruptible: true
before_script:
- !reference [.scripts, configure-studip]
- *mkdir-reports
- *configure-studip
script:
- 'composer/bin/codecept
run unit
--xml=$PHPUNIT_XML_REPORT
-o "paths: output: ."'
after_script:
- sed -i "s%$PWD/%%" $PHPUNIT_XML_REPORT
artifacts:
reports:
junit: $PHPUNIT_XML_REPORT
test-jest:
stage: test
needs: [lint-js]
image: $NODE_IMAGE
variables:
JS_TEST_REPORT: $REPORT_DIR/jest.xml
cache: *npm-cache
interruptible: true
before_script:
- *mkdir-reports
- npm install
script:
- composer/bin/codecept run unit --xml
- !reference [.scripts, remove-absolute-path-in-report]
- JEST_JUNIT_OUTPUT_FILE="$JS_TEST_REPORT" npx jest tests/jest/ --ci --reporters=default --reporters=jest-junit
artifacts:
<<: *test-artifacts
reports:
junit: $JS_TEST_REPORT
test-functional:
stage: tests
stage: test
needs: [lint-php]
variables:
FUNCTIONAL_XML_REPORT: $REPORT_DIR/functional-report.xml
FUNCTIONAL_CODE_QUALITY_REPORT: $REPORT_DIR/functional-codequality.json
cache:
<<: *composer-cache
policy: pull
services:
- mariadb
- *mariadb-service
allow_failure: false
interruptible: true
before_script:
- !reference [.scripts, initialize-studip-database]
- *mkdir-reports
- *initialize-studip-database
script:
- composer/bin/codecept run functional --xml
- !reference [.scripts, remove-absolute-path-in-report]
- 'composer/bin/codecept
run functional
--xml=$FUNCTIONAL_XML_REPORT
-o "paths: output: ."'
after_script:
- sed -i "s%$PWD/%%" $FUNCTIONAL_XML_REPORT
artifacts:
<<: *test-artifacts
reports:
junit: $FUNCTIONAL_XML_REPORT
test-jsonapi:
stage: tests
stage: test
needs: [lint-php]
cache:
<<: *composer-cache
policy: pull
services:
- mariadb
allow_failure: false
- *mariadb-service
variables:
JSONAPI_XML_REPORT: $REPORT_DIR/jsonapi-report.xml
interruptible: true
before_script:
- !reference [.scripts, initialize-studip-database]
- *mkdir-reports
- *initialize-studip-database
script:
- composer/bin/codecept run jsonapi --xml
- !reference [.scripts, remove-absolute-path-in-report]
- 'composer/bin/codecept
run jsonapi
--xml=$JSONAPI_XML_REPORT
-o "paths: output: ."'
after_script:
- sed -i "s%$PWD/%%" $JSONAPI_XML_REPORT
artifacts:
<<: *test-artifacts
when: always
expire_in: 1 week
paths:
- tests/_output
reports:
junit: tests/_output/report.xml
junit: $JSONAPI_XML_REPORT
test-assets:
stage: tests
stage: test
needs: []
image: $NODE_IMAGE
cache: *npm-cache
allow_failure: false
interruptible: true
before_script:
- make npm
- npm install
script:
- make webpack-dev
- npm run webpack-dev
test-e2e:
stage: test
# needs: [lint-css, lint-js, lint-php]
image: mcr.microsoft.com/playwright:v1.33.0-jammy
services:
- name: mariadb
command: ["--sql_mode="]
variables:
PHP_WEBSERVER_URL: localhost:65432
E2E_REPORT: $REPORT_DIR/e2e.xml
interruptible: true
when: manual
cache:
- *composer-cache
- *npm-cache
before_script:
- mkdir ./bin
- apt-get update
- apt -y install software-properties-common
- add-apt-repository ppa:ondrej/php
- apt-get update
- DEBIAN_FRONTEND=noninteractive
apt-get -yq install
make zip unzip mariadb-client
php7.4 libapache2-mod-php7.4 php7.4-common php7.4-curl php7.4-mbstring
php7.4-xmlrpc php7.4-mysql php7.4-gd php7.4-xml php7.4-intl php7.4-ldap
php7.4-imagick php7.4-json php7.4-cli
- echo "short_open_tag=On" >> /etc/php/7.4/php.ini
- echo "short_open_tag=On" >> /etc/php/7.4/cli/php.ini
- php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
- php composer-setup.php --install-dir=./bin --filename=composer
- export PATH="./bin:$PATH"
- php -r "unlink('composer-setup.php');"
- *mkdir-reports
- *initialize-studip-database
- ./cli/studip config:set SHOW_TERMS_ON_FIRST_LOGIN 0
- npm install playwright
- npm ci
- npx playwright install --with-deps
script:
- php -S $PHP_WEBSERVER_URL -t public -q &
- PHP_SERVER_PID=$!
- PLAYWRIGHT_JUNIT_OUTPUT_NAME="$E2E_REPORT"
PLAYWRIGHT_BASE_URL="http://$PHP_WEBSERVER_URL"
npx playwright test --reporter=junit --grep-invert a11y
- kill -3 $PHP_SERVER_PID
artifacts:
reports:
junit: $E2E_REPORT
packaging:
stage: packaging
......@@ -228,6 +402,18 @@ packaging:
dotenv: .packaging.env
expire_in: never
build_image:
image:
name: gcr.io/kaniko-project/executor:debug
entrypoint: [""]
stage: build
when: manual
interruptible: true
variables:
IMAGE_TAG: $CI_REGISTRY_IMAGE:$CI_COMMIT_REF_NAME
script:
- /kaniko/executor --context=dir://${CI_PROJECT_DIR} --dockerfile ${CI_PROJECT_DIR}/docker/studip/Dockerfile --destination ${IMAGE_TAG} --cache=true
release:
stage: release
image: studip/release-cli
......
version: 2
updates:
- package-ecosystem: composer
directory: /
schedule:
interval: weekly
labels: []
versioning-strategy: lockfile-only
open-pull-requests-limit: -1
open-security-pull-requests-limit: -1
- package-ecosystem: npm
directory: /
schedule:
interval: weekly
labels: []
versioning-strategy: lockfile-only
open-pull-requests-limit: -1
open-security-pull-requests-limit: -1
......@@ -6,4 +6,4 @@ Welches Problem ist aufgetreten und wie ist es dazu gekommen? (Hilfreich: vorher
Ist der Fehler reproduzierbar? Falls ja, wie.
/label ~BIEST ~"Version::5.3"
/label ~BIEST ~"Version::5.4"
## Barrierefreiheits-Review
### Prüfung auf ausreichenden Kontrast und Kenntlichmachung bei GUI-Elementen
- [ ] Vordergrund- und Hintergrundfarbe haben einen ausreichenden Kontrast.
- Mindestens 4,5:1 bei Text und 3:1 bei Icons, idealerweise 7:1.
- [ ] Links werden passend hervorgehoben.
- Kontrast mindestens 3:1 und mit einer weiteren Hervorhebung.
- Wegen GUI-Richtlinien nur im Fließtext umsetzbar.
- [ ] Die angezeigten Informationen sind auch ohne Farbsehen erkennbar.
### Prüfung auf Tastaturbedienbarkeit von Seitenelementen
- [ ] Interaktive Elemente (Link, Button) sind per TAB erreichbar.
- [ ] Elemente verwenden übliche Tasten zur Bedienung
- Eingabetaste für Links und Buttons.
- Pfeiltasten für Select-Felder und Radio-Buttons.
- Leertaste zum Aktivieren von Checkboxen, Radio-Buttons und zum Öffnen von Select-Feldern.
- [ ] Fokusfallen sind nicht vorhanden
- [ ] Die „natürliche“ Reihenfolge der Fokussierung bleibt erhalten.
- tabindex > 0 wird nicht verwendet.
- [ ] Die Fokussierung wird beim Aufruf von Aktionen nicht zurückgesetzt.
### Prüfung auf Nutzbarkeit von Seitenelementen mit Screenreadern
- [ ] Elemente werden korrekt vorgelesen.
- Button: „Schalter“
- Link: „Link“
- Select-Feld: „Auswahlfeld“/„Auswahlschalter“
- [ ] Icons, die nur Schmuckelemente sind, sind für Screenreader unsichtbar.
- [ ] Icons und Bilder, die eine Information liefern, haben einen Alternativtext, der vorgelesen wird.
- [ ] Vorgelesene Texte referenzieren andere Elemente der Seite ohne Positionsangaben.
- [ ] Anhand des vorgelesenen Textes ist die Struktur der Seite erkennbar.
- [ ] Dopplungen von Text (durch ein Icon neben einem Text) tauchen nicht auf.
## Mängel
- (Hier Mängel auflisten)
/label ~BIEST ~Accessibility ~"Version::5.4"
# Releasearbeiten zur Version x.y
## Vorbereitend
* [ ] Release-Notes leeren
* [ ] Version anpassen
## Zum Release
* [ ] Übersetzung vervollständigen
* [ ] Demo-Daten
* [ ] const DEFAULT_ENV = 'production';
* [ ] history.txt
* [ ] Release-Notes
* [ ] Changelog aktualisieren
#!/usr/bin/env php
<?php
function error(string $error, int $status = 1): void
{
echo trim($error) . "\n";
exit($status);
}
$self = basename($argv[0]);
if ($argc !== 2) {
error("Missing report file, use {$self} <filename>");
}
$report_file = $argv[1];
if (!file_exists($report_file)) {
error("Report file {$report_file} does not exist");
}
if (!is_readable($report_file)) {
error("Report file {$report_file} is not readable");
}
$json = json_decode(file_get_contents($report_file), true);
if ($json === false) {
error("Could not read json contents of {$report_file}");
}
$errors = [];
foreach ($json['errors'] as $error) {
$errors[] = [
'description' => $error['error'],
'fingerprint' => md5("{$error['file_name']}:{$error['line']}"),
'severity' => 'major',
'location' => [
'path' => $error['file_name'],
'lines' => [
'begin' => $error['line'],
],
],
];
}
echo json_encode($errors);
#!/bin/bash
set -e
if [ $(mysql -f -u $MYSQL_USER -h $MYSQL_HOST -p$MYSQL_PASSWORD $MYSQL_DATABASE -e "show tables;" --batch | wc -l) -eq 0 ]; then
importSQLFile() {
mysql --default-character-set=utf8mb4\
--init-command="SET NAMES UTF8;"\
-u $MYSQL_USER\
-h $MYSQL_HOST\
-p$MYSQL_PASSWORD\
$MYSQL_DATABASE\
< $1
}
if [ $(mysql -u $MYSQL_USER -h $MYSQL_HOST -p$MYSQL_PASSWORD $MYSQL_DATABASE -e "show tables;" --batch | wc -l) -eq 0 ]; then
# Setup mysql database
echo "INSTALL DB"
mysql -f -u $MYSQL_USER -h $MYSQL_HOST -p$MYSQL_PASSWORD $MYSQL_DATABASE < ./db/studip.sql
importSQLFile ./db/studip.sql
echo "INSTALL DEFAULT DATA"
mysql -f -u $MYSQL_USER -h $MYSQL_HOST -p$MYSQL_PASSWORD $MYSQL_DATABASE < ./db/studip_default_data.sql
mysql -f -u $MYSQL_USER -h $MYSQL_HOST -p$MYSQL_PASSWORD $MYSQL_DATABASE < ./db/studip_resources_default_data.sql
importSQLFile ./db/studip_default_data.sql
importSQLFile ./db/studip_resources_default_data.sql
echo "INSTALL ROOTUSER"
mysql -f -u $MYSQL_USER -h $MYSQL_HOST -p$MYSQL_PASSWORD $MYSQL_DATABASE < ./db/studip_root_user.sql
importSQLFile ./db/studip_root_user.sql
# Check if demodata is required
if [ ! -z $DEMO_DATA ]; then
echo "INSTALL DEMODATA"
mysql -f -u $MYSQL_USER -h $MYSQL_HOST -p$MYSQL_PASSWORD $MYSQL_DATABASE < ./db/studip_demo_data.sql
importSQLFile ./db/studip_demo_data.sql
echo "INSTALL MVV_DEMODATA"
mysql -f -u $MYSQL_USER -h $MYSQL_HOST -p$MYSQL_PASSWORD $MYSQL_DATABASE < ./db/studip_mvv_demo_data.sql
importSQLFile ./db/studip_mvv_demo_data.sql
echo "INSTALL RESOURCES-DEMODATA"
mysql -f -u $MYSQL_USER -h $MYSQL_HOST -p$MYSQL_PASSWORD $MYSQL_DATABASE < ./db/studip_resources_demo_data.sql
importSQLFile ./db/studip_resources_demo_data.sql
fi
echo "INSTALLATION FINISHED"
......
{
"extends": "stylelint-config-standard",
"extends": "stylelint-config-standard-scss",
"rules": {
"alpha-value-notation": null,
"at-rule-empty-line-before": null,
"at-rule-no-vendor-prefix": null,
"block-closing-brace-empty-line-before": null,
"block-closing-brace-newline-after": null,
"block-closing-brace-newline-before": null,
"block-closing-brace-space-before": null,
"block-no-empty": null,
"block-opening-brace-newline-after": null,
"block-opening-brace-space-after": null,
"block-opening-brace-space-before": null,
"color-function-notation": null,
"color-hex-case": null,
"color-hex-length": null,
"color-no-invalid-hex": null,
"comment-empty-line-before": null,
"comment-whitespace-inside": null,
"declaration-bang-space-after": null,
"declaration-bang-space-before": null,
"custom-property-empty-line-before": null,
"declaration-block-no-duplicate-properties": null,
"declaration-block-no-redundant-longhand-properties": null,
"declaration-block-no-shorthand-property-overrides": null,
"declaration-block-semicolon-newline-after": null,
"declaration-block-semicolon-space-before": null,
"declaration-block-single-line-max-declarations": null,
"declaration-block-trailing-semicolon": null,
"declaration-colon-newline-after": null,
"declaration-colon-space-after": null,
"declaration-colon-space-before": null,
"declaration-empty-line-before": null,
"font-family-name-quotes": null,
"font-family-no-missing-generic-family-keyword": null,
"function-comma-space-after": null,
"function-comma-space-before": null,
"function-name-case": null,
"function-no-unknown": null,
"function-parentheses-newline-inside": null,
"function-parentheses-space-inside": null,
"function-url-quotes": null,
"hue-degree-notation": null,
"indentation": null,
"import-notation": "string",
"keyframes-name-pattern": null,
"length-zero-no-unit": null,
"max-empty-lines": null,
"max-line-length": null,
"media-feature-range-notation": "prefix",
"media-feature-name-no-vendor-prefix": null,
"no-descending-specificity": null,
"no-duplicate-selectors": null,
"no-empty-first-line": null,
"no-empty-source": null,
"no-eol-whitespace": null,
"no-extra-semicolons": null,
"no-invalid-position-at-import-rule": null,
"no-irregular-whitespace": null,
"no-missing-end-of-source-newline": null,
"number-leading-zero": null,
"number-max-precision": null,
"number-no-trailing-zeros": null,
"property-no-vendor-prefix": null,
"rule-empty-line-before": null,
"selector-attribute-quotes": null,
"selector-class-pattern": null,
"selector-combinator-space-after": null,
"selector-combinator-space-before": null,
"selector-descendant-combinator-no-non-space": null,
"selector-id-pattern": null,
"selector-list-comma-newline-after": null,
"selector-no-vendor-prefix": null,
"selector-not-notation": null,
"selector-pseudo-element-colon-notation": null,
"shorthand-property-no-redundant-values": null,
"string-quotes": null,
"value-keyword-case": null,
"value-list-max-empty-lines": null,
"value-no-vendor-prefix": null
"value-no-vendor-prefix": null,
"custom-property-pattern": [
"^([a-z][a-z0-9]*-+)*[a-z0-9]+$",
{"message": "Expected custom property name to be kebab-case-ish (multiple dashes are allowed"}
],
"scss/at-extend-no-missing-placeholder": null,
"scss/at-mixin-pattern": null,
"scss/dollar-variable-empty-line-before": null,
"scss/dollar-variable-pattern": null,
"scss/double-slash-comment-empty-line-before": null,
"scss/function-unquote-no-unquoted-strings-inside": null,
"scss/no-global-function-names": null
},
"overrides": [
{
"files": ["**/*.scss"],
"customSyntax": "postcss-scss",
"rules": {
"at-rule-no-unknown": null
}
},
{
"files": ["**/*.less"],
"customSyntax": "postcss-less"
}
],
"ignoreFiles": [
"resource/assets/stylesheets/jquery-ui.structure.css",
"resources/assets/stylesheets/less/jquery-ui/*",
"resources/assets/stylesheets/vendor/*"
]
}
This diff is collapsed.
......@@ -38,7 +38,7 @@ PROJECT_NAME = Stud.IP
# could be handy for archiving the generated documentation or if some version
# control system is used.
PROJECT_NUMBER = 4.0
PROJECT_NUMBER = 6.0
# Using the PROJECT_BRIEF tag one can provide an optional one line description
# for a project that appears at the top of each page and should give viewer a
......
......@@ -2,7 +2,7 @@ Die Installation von Stud.IP ist halb so schlimm:
es müssen lediglich ein paar Dateien kopiert werden und ein paar
Programme laufen ;-)
Vorausgesetzt wird ein Webserver wie Apache2 oder nginx mit PHP-7.2 Modulen und
Vorausgesetzt wird ein Webserver wie Apache2 oder nginx mit PHP-7.4 Modulen und
eine MySQL 5.7.6 Datenbank.
Was genau zu tun ist, steht in
......
......@@ -72,13 +72,27 @@ test-functional: $(CODECEPT)
test-jsonapi: $(CODECEPT)
$(CODECEPT) run jsonapi
test-e2e: npm
npx playwright test
test-unit: $(CODECEPT)
$(CODECEPT) run unit
catalogs: npm $(CATALOGS)
clean-icons:
find public/assets/images/icons -type f -not -path '*blue*' -delete
optimize-icons: npm
find public/assets/images/icons -type f | xargs -P0 npx svgo -q --config=config/svgo.config.js
find public/assets/images/icons/blue -type f | xargs -P0 npx svgo -q --config=config/svgo.config.js
icons: optimize-icons
find public/assets/images/icons/blue -type f -print0 | xargs -0 -n1 -I{} echo 'sed "s/#28497c/#000000/g" {} > {}' | sed 's#icons/blue#icons/black#2' | sh
find public/assets/images/icons/blue -type f -print0 | xargs -0 -n1 -I{} echo 'sed "s/#28497c/#00962d/g" {} > {}' | sed 's#icons/blue#icons/green#2' | sh
find public/assets/images/icons/blue -type f -print0 | xargs -0 -n1 -I{} echo 'sed "s/#28497c/#6e6e6e/g" {} > {}' | sed 's#icons/blue#icons/grey#2' | sh
find public/assets/images/icons/blue -type f -print0 | xargs -0 -n1 -I{} echo 'sed "s/#28497c/#cb1800/g" {} > {}' | sed 's#icons/blue#icons/red#2' | sh
find public/assets/images/icons/blue -type f -print0 | xargs -0 -n1 -I{} echo 'sed "s/#28497c/#ffffff/g" {} > {}' | sed 's#icons/blue#icons/white#2' | sh
find public/assets/images/icons/blue -type f -print0 | xargs -0 -n1 -I{} echo 'sed "s/#28497c/#ffad00/g" {} > {}' | sed 's#icons/blue#icons/yellow#2' | sh
# default rules for gettext handling
js-%.pot: $(VUE_SOURCES)
......
# Stud.IP v *version*
# Stud.IP v6.0
*Datum*
**15.03.2024**
## Neue Features
- ...
### System
- Der Stud.IP-Cache ist nun kompatibel zu PSR-6. ([TIC #3701](https://gitlab.studip.de/studip/studip/-/issues/3701))
- Das `User`-Model hat die Methode `hasPermissionLevel()` erhalten, um einfach abfragen zu können, ob eine Person einen bestimmten Berechtigungsstatus hat. ([Issue #3453](https://gitlab.studip.de/studip/studip/-/issues/3453))
- In der Standort-Verwaltung können nun nicht nur Ferien sondern auch Feiertage konfiguriert werden. Dies erlaubt das Markieren von Feiertagen als gesetzliche Feiertage, da diese je nach Bundesland variieren können. ([Issue #2795](https://gitlab.studip.de/studip/studip/-/issues/2795))
- Die Nutzungsbedingungen sind nun nicht mehr als statische HTML-Dateien hinterlegt, sondern können analog zu Impressum, Datenschutz- und Barrierefreiheitserklärung direkt über die Oberfläche bearbeitet werden. Initial ist diese Seite aber im Entwurfsmodus und daher für Nicht-Roots unsichtbar. Damit andere Personen beim ersten Login diese Nutzungsbedingungen sehen und ihnen zustimmen können, muss der Entwurfsmodus für diese Seite abgeschaltet werden. ([TIC #4433](https://gitlab.studip.de/studip/studip/-/issues/4433))
### Layout
- Die Login-Seite wurde überarbeitet
- Das Design von Stud.IP wurde modernisiert
- Neue Avatarbilder
### Courseware
- Rechte und Sichtbarkeit überarbeitet
- Verbesserter Übersichtsdialog
- Rechte und Sichtbarkeit können für ein ganzes Lernmaterial gesetzt werden
- [Issue #3442](https://gitlab.studip.de/studip/studip/-/issues/3442)
- Peer-Review für Aufgaben
- Lehrende können Peer-Review-Prozess für Aufgaben einstellen
- Lernende sehen Aufgabenlösungen ein, geben Feedback und Bewertung dazu ab
- [Issue #2484](https://gitlab.studip.de/studip/studip/-/issues/2484)
- Blubber-Block
- Blubber Diskussionen können jetzt als Block eingebunden werden
- Lernmaterialübersicht im Inhaltsverzeichnis
- Schafft einen Überblick über weitere Lernmaterialien in der Veranstaltungen ohne den Kontext verlassen zu müssen
- Neues Layout für den Merksatz-Block
### Vips Plugin wird als Aufgaben-Werkzeug in Kern integriert
- Mit Vips lassen sich Selbsttests, Übungen und Klausuren erstellen
- Lernende können Vips Aufgabenblätter in Stud.IP bearbeiten und erhalten dort auch ihre Ergebnisse
- Für eine Vielzahl von Aufgabentypen besteht die Möglichkeit einer Autokorrektur
- [Issue #4258](https://gitlab.studip.de/studip/studip/-/issues/4258)
- [Plugin](https://develop.studip.de/studip/plugins.php/pluginmarket/presenting/details/81097da5ef66a002998b75d5eeece1f0)
### Neues Benachrichtigungssystem
- Vereinheitlichung wie Stud.IP mit Nutzenden kommuniziert
- Messageboxen, Companionmeldungen und Notifications werden vereinheitlicht
- [Issue #660](https://gitlab.studip.de/studip/studip/-/issues/660)
### Garuda Plugin in Kern integriert
- Mit Garuda können Zielgruppen definiert werden, um diesen Sammelnachrichten zukommen zu lassen
- [Issue #3326](https://gitlab.studip.de/studip/studip/-/issues/3326)
- [Plugin](https://develop.studip.de/studip/plugins.php/pluginmarket/presenting/details/d24cb47ee246033c325496b832e64147)
### Bilderpool
- Neuer Archiv Upload
- Ermöglicht das Einpflegen von einer Vielzahl von Bilder mit nur einem Upload
- Metadaten werden in dem Archiv als CSV-Datei mitgegeben und müssen nicht mehr einzeln eingegeben werden
- Stud.IP Bildersammlung kann mit nur einem Upload integriert werden
- Die Stud.IP Bildersammlung finden Sie [hier](https://gitlab.studip.de/studip/bilderpool)
### Anzeige von ILIAS-Kursen auf "Mein Arbeitsplatz"
- Bei aktivierter ILIAS-Schnittstelle können Lehrende ihre Stud.IP Veranstaltungen mit ILIAS-Kursen verknüpfen
- Lernende erhalten eine Übersicht über ihre ILIAS-Kurse im Stud.IP Arbeitsplatz
### Assistent für Roots nach Updates
- Nach einem Update auf eine neue Stud.IP Version werden Nutzenden mit Root-Rechten die neuen Features der Version präsentiert
### Studiengruppen
- Um Studiengruppen sichtbarer und interessanter zu machen wurde eine Reihe von Verbesserungen vorgenommen
- Neues Widget für die Startseite
- Möglichkeit Studiengruppen für eine Veranstaltungen vorzuschlagen
- [Issue #3616](https://gitlab.studip.de/studip/studip/-/issues/3616)
## Breaking changes
- ...
- Mindestanforderung an PHP auf 8.1 angehoben ([TIC #3805](https://gitlab.studip.de/studip/studip/issues/3805))
- Im Rahmen von [Issue #3788](https://gitlab.studip.de/studip/studip/-/issues/3788) wurden die Zusätze an allen Icons entfernt. Dadurch kann es sein, dass manche Plugins nicht mehr erscheinen. Diese müssen dann auf eine Variante ohne Zusätze umgestellt werden.
- Die Funktion `get_config()` wurde entfernt. Stattdessen muss die Methode `Config::get()->getValue('CONFIG_KEY')` bzw. der Shortcut `Config::get()->CONFIG_KEY` verwendet werden. ([Issue #2797](https://gitlab.studip.de/studip/studip/-/issues/2797))
- Die Funktion `smile()` wurde entfernt. Sie kann ersatzlos entfernt werden. ([Issue #3158](https://gitlab.studip.de/studip/studip/-/issues/3158))
- Die Funktion `transformBeforeSave()` wurde entfernt. Sie kann ersatzlos entfernt werden. ([Issue #3159](https://gitlab.studip.de/studip/studip/-/issues/3159))
- Die schon lange nicht mehr genutzten Methoden zum Setzen, Auslesen und Enfernen von Schmuckgrafiken von Bildern für die Sidebar wurde entfernt. Die Methoden `Sidebar::setImage()`, `Sidebar::getImage()` sowie `Sidebar::removeImage()` müssen ersatzlos entfernt werden. ([Issue #3157](https://gitlab.studip.de/studip/studip/-/issues/3157))
- Der zweite Parameter für die Methode `Navigation::setImage()` wurde entfernt. Der Parameter schien sich auf das Bild zu beziehen, hat aber Attribute an dem Link gesetzt. Stattdessen muss die Methode `Navigation::setLinkAttributes()` verwendet werden. ([Issue #3578](https://gitlab.studip.de/studip/studip/-/issues/3578))
- Die Unterstützung für LESS-Stylsheets in Plugins wurde entfernt. Als Alternative wird SCSS unterstützt. ([Issue #2720](https://gitlab.studip.de/studip/studip/-/issues/2720))
- Die Funktionen `studip_json_encode()` und `studip_json_decode()` wurden entfernt. Stattdessen müssen die Methode `json_encode()` und `json_decode()` verwendet werden. ([Issue #3814](https://gitlab.studip.de/studip/studip/-/issues/3814))
- Die `MembersModel.php` wurde entfernt ([Issue #3811](https://gitlab.studip.de/studip/studip/-/issues/3811))
- Die `admission.inc.php` wurde entfernt. ([Issue #3812](https://gitlab.studip.de/studip/studip/-/issues/3812))
- Die folgenden Funktionen wurden aus der Datei `lib/functions.php` entfernt: `re_sort_dozenten()`, `re_sort_tutoren()` und `get_next_position()` ([Issue #4002](https://gitlab.studip.de/studip/studip/-/issues/4002))
- Die Methoden `CronjobScheduler::scheduleOnce()` sowie `CronjobTask::scheduleOnce()` wurden ersatzlos entfernt. ([Issue #4078](https://gitlab.studip.de/studip/studip/-/issues/4078))
- Die folgenden Klassen wurden innerhalb von Stud.IP verschoben. Da sie über den Autoloader geladen werden, kann jedes manuelle Einbinden ersatzlos entfernt werden. ([Issue #4105](https://gitlab.studip.de/studip/studip/-/issues/4105))
- `AuthenticatedController`
- `PluginController`
- `StudipController`
- `StudipControllerPropertiesTrait`
- `StudipResponse`
- Im Rahmen von [Issue #4118](https://gitlab.studip.de/studip/studip/-/issues/4118) wurde `write_excel` ausgebaut. Als Alternative kann `phpoffice/phpspreadsheet` verwendet werden.
- Im Rahmen von [TIC #3701](https://gitlab.studip.de/studip/studip/-/issues/3701) wurden die Klassen für den Cache umbenannt. Alle Vorkommnisse sollten ersetzt werden:
- `StudipCacheFactory` -> `Studip\Cache\Factory`
- Die Bibliothek `opis/json-schema` wurde auf Version 2.3.0 aktualisiert ([Issue #4173](https://gitlab.studip.de/studip/studip/-/issues/4173)). Dadurch ergeben sich die folgenden Änderungen für Komponenten aus Courseware (siehe auch [Migration Guide](https://opis.io/json-schema/2.x/php-migration.html#validator)):
- Instanzen von `Courseware\ContainerTypes\BlockType` müssen die Methode `getJsonSchema` anpassen. Der Return Type ist nun `string` und es muss der Inhalt der Schema-Datei zurückgegeben werden ohne Aufruf von `Schema::fromJsonString()`.
- Instanzen von `Courseware\ContainerTypes\ContainerType` müssen die Methode `getJsonSchema` anpassen. Der Return Type ist nun `string` und es muss der Inhalt der Schema-Datei zurückgegeben werden ohne Aufruf von `Schema::fromJsonString()`.
- Die von Stud.IP verwendete Template-Bibliothek "Flexi Templates" wurde vollständig in den Kern integriert.
Obwohl die Umstellung abwärtskompatibel sein sollte, sollten die Klassen folgendermassen ersetzt werden:
- `Flexi_TemplateFactory` > `Flexi\Factory`
- `Flexi_Template` > `Flexi\Template`
- `Flexi_PhpTemplate` > `Flexi\PhpTemplate`
- `Flexi_TemplateNotFoundException` > `Flexi\TemplateNotFoundException`
Sollte ein Plugin manuell Flexi einbinden, so wird dies zu einem Fehler führen. Jegliches Einbinden von Dateien
unterhalb von `vendor/flexi` muss ersatzlos entfernt werden.
- Die folgenden Funktionen wurden entfernt ([Issue #4179](https://gitlab.studip.de/studip/studip/-/issues/4179))
- `getWeekdays($short = true)`
- `veranstaltung_beginn($seminar_id = '', $return_mode = '')`
- `veranstaltung_beginn_from_metadata($reg_irreg, $sem_begin, $start_woche, $start_termin,$turnus_data, $return_mode='int')`
- `get_sem_name ($time)`
- `get_sem_num ($time)`
- `get_sem_num_sem_browse ()`
- `get_semester($seminar_id)`
- `delete_date($termin_id, $topic_delete = TRUE, $folder_move = TRUE, $sem_id=0)`
- `delete_range_of_dates($range_id, $topics = FALSE)`
- `isSchedule ($sem_id, $presence_dates_only = TRUE, $clearcache = FALSE)`
- `isMetadateCorrespondingDate ($termin_id, $begin = '', $end = '', $seminar_id='')`
- `getPresenceTypes()`
- Die Klasse `AuxLockRules` wurde ausgebaut. ([Issue #4187](https://gitlab.studip.de/studip/studip/-/issues/4187))
- Die Klasse `ProfileModel` wurde gelöscht. Die darin enthaltenen Methoden wurden in den `Profile_Controller` verschoben. ([Issue #4185]https://gitlab.studip.de/studip/studip/-/issues/4185))
- Die Klasse `StudipTransformFormat` wurde ausgebaut ([Issue #4188](https://gitlab.studip.de/studip/studip/-/issues/4188))
- Die REST-API (`public/api.php`) wurde zu Stud.IP 5.0 deprecated und nun mit Stud.IP 6.0 entfernt. Als Ersatz steht die JSONAPI zur Verfügung. ([Issue #2798](https://gitlab.studip.de/studip/studip/-/issues/2798))
- Die Klassen `CalendarView`, `CalendarScheduleModel` sowie alle davon abhängigen Klassen wurden entfernt. ([Issue #4421](https://gitlab.studip.de/studip/studip/-/issues/4421))
- Anstelle von `CalendarView` sollte `\Studip\Fullcalendar` verwendet werden.
- Das Datenbankschema des Stundenplans wurde geändert. ([Issue #4421](https://gitlab.studip.de/studip/studip/-/issues/4421))
- Die Evaluationen wurden ausgebaut. Stattdessen sollte man nun die neuen Fragebögen verwenden ([Issue #3787]https://gitlab.studip.de/studip/studip/-/issues/3787)
- Die Klassen `DbView`, `DbSnapshot` und die zugehörigen Dateien in `lib/dbviews` wurden ausgebaut. ([Issue #4390](https://gitlab.studip.de/studip/studip/-/issues/4390))
- Als Ersatz dienen Datenbankabfragen mittels der `DBManager`-Klasse oder mittels `SimpleORMap`-Modellen.
- Es wurden zwei neue CLI-Kommandos hinzugefügt, womit man Klassenrümpfe für SORM-Models und Migrationen erstellen kann. Bei den Migrationen wird die Versionsnummer für die jeweilige `domain` automatisch ermittelt.
- `cli/studip make:model` und `cli/studip make:migration`.
- Es wurde ein neues CLI-Kommando hinzugefügt, womit man auf einfache Weise ein Plugin-Grundgerüst erstellen kann.
- `cli/studip make:plugin`
- Die Klasse `Seminar`, sowie die Klassen in `lib/raumzeit` wurden ausgebaut. ([Issue #3209](https://gitlab.studip.de/studip/studip/-/issues/3209))
- Als Ersatz für viele Methoden der Seminar-Klasse dienen die Klassen `Course`, `CourseDate` und `SeminarCycleDate`, sowie die neue `CourseDateList`-Klasse.
- Die Klassen `TreeAbstract`, `TreeView` und `SemBrowse` wurden ausgebaut. ([Issue #4392](https://gitlab.studip.de/studip/studip/-/issues/4392))
- Zur Anzeige von Baumstrukturen können als Ersatz die Implementierungen des `StudipTreeNode`-Interfaces genutzt werden.
- Die Zuordnung von Veranstaltungen zu Semestern anhand von Timestamps wurde entfernt. In der Datenbank wurden die Spalten `start_time` und `duration_time` der Tabelle `seminare` entfernt. ([Issue #4391]https://gitlab.studip.de/studip/studip/-/issues/4391))
- Plugins, die Veranstaltungen anhand von Timestamps laden oder anderweitig verwenden, müssen angepasst werden!
- Das Mapping von Veranstaltungen zu Semestern findet nun ausschließlich anhand der Semester-ID über die Verknüpfungstabelle `semester_courses` statt.
- Die ELearning-Schnittstelle wurde ausgebaut. In diesem Rahmen wurden auch die Methoden `printhead()` und `printcontent()` ersatzlos entfernt. ([Issue #4109](https://gitlab.studip.de/studip/studip/-/issues/4109))
## Security related issues
-
## Bugfixes
## Deprecated Features
- ...
-
## Veraltete Features
## Known Issues
- ...
-
RELEASE 5.3.alpha-svn
RELEASE 6.0.alpha
......@@ -3,6 +3,21 @@ class Accessibility_FormsController extends StudipController
{
protected $with_session = true;
public function before_filter(&$action, &$args)
{
parent::before_filter($action, $args);
if (
Config::get()->REPORT_BARRIER_MODE === 'off'
|| (
Config::get()->REPORT_BARRIER_MODE === 'logged-in'
&& !User::findCurrent()
)
) {
throw new AccessDeniedException();
}
}
public function report_barrier_action()
{
PageLayout::setTitle(_('Barriere melden'));
......@@ -53,7 +68,7 @@ class Accessibility_FormsController extends StudipController
)->setRequired();
$this->form->addPart($details_part);
$personal_data_part = new \Studip\Forms\Fieldset(_('Ihre persönlichen Daten'));
$personal_data_part->addText(sprintf('<p>%s</p>', _('Geben Sie bitte Ihren Namen und Ihre E-Mail-Adresse an. Optional können Sie auch Ihre Telefonnummer angeben.')));
$personal_data_part->addText(sprintf('<p>%s</p>', _('Freiwillige Angaben Ihrer Kontaktdaten für etwaige Rückfragen.')));
$personal_data_part->addInput(
new \Studip\Forms\SelectInput(
'salutation',
......@@ -75,7 +90,7 @@ class Accessibility_FormsController extends StudipController
_('Vorname und Nachname'),
$user ? sprintf('%s %s', $user->vorname, $user->nachname) : ''
)
)->setRequired();
);
$personal_data_part->addInput(
new \Studip\Forms\TextInput(
'phone_number',
......@@ -89,7 +104,29 @@ class Accessibility_FormsController extends StudipController
_('E-Mail-Adresse'),
$user ? $user->email : ''
)
)->setRequired();
);
// Add a honeypot value and timestamp
$personal_data_part->addInput(
new \Studip\Forms\TextInput(
'homepage',
_('Homepage'),
'',
[
'aria-hidden' => 'true',
'class' => 'sr-only',
'placeholder' => _('Dieses Feld nicht ausfüllen'),
'title' => _('Dieses Feld nicht ausfüllen'),
]
)
);
$this->form->addInput(
new \Studip\Forms\HiddenInput('time', '', time())
);
$personal_data_part->addText(sprintf('<p>%s</p>',
_('Informationen zum Datenschutz dieses Formulars finden Sie in der Datenschutzerklärung.')));
$privacy_url = Config::get()->PRIVACY_URL;
if (is_internal_url($privacy_url)) {
......@@ -107,19 +144,23 @@ class Accessibility_FormsController extends StudipController
['target' => '_blank']
);
}
$personal_data_part->addInput(
new \Studip\Forms\CheckboxInput(
'confirm_privacy',
_('Ich habe die Datenschutzerklärung gelesen und akzeptiere sie.'),
''
)
)->setRequired();
$this->form->addPart($personal_data_part);
$this->form->addPart(new \Studip\Forms\Captcha());
$this->form->setSaveButtonText(_('Barriere melden'));
$this->form->setSaveButtonName('report');
$this->form->setURL($this->report_barrierURL());
$this->form->addStoreCallback(
function ($form, $form_values) {
if (
$form_values['time'] >= time() - 2
|| !empty($form_values['homepage'])
) {
return 0;
}
$recipients = Config::get()->ACCESSIBILITY_RECEIVER_EMAIL;
if (empty($recipients)) {
//Fallback: Use the UNI_CONTACT mail address:
......@@ -128,7 +169,7 @@ class Accessibility_FormsController extends StudipController
//Get the sender and their language:
$sender = User::findCurrent();
//Default to the system default language:
$lang = explode('_', $GLOBALS['DEFAULT_LANGUAGE'])[0];
$lang = explode('_', Config::get()->DEFAULT_LANGUAGE ?? 'de_DE')[0];
if ($sender) {
//Use the senders language since the choices in the form
//are in their language as well.
......
......@@ -16,7 +16,7 @@ class ActivityfeedController extends AuthenticatedController
$provider = Request::getArray('provider');
WidgetHelper::addWidgetUserConfig($GLOBALS['user']->id, 'ACTIVITY_FEED', $provider);
UserConfig::get($GLOBALS['user']->id)->store('ACTIVITY_FEED', $provider);
$this->response->add_header('X-Dialog-Close', 1);
$this->response->add_header('X-Dialog-Execute', 'STUDIP.ActivityFeed.updateFilter');
......@@ -53,7 +53,7 @@ class ActivityfeedController extends AuthenticatedController
unset($modules[Context::INSTITUTE]['participants']);
unset($modules[Context::INSTITUTE]['schedule']);
$standard_plugins = PluginManager::getInstance()->getPlugins("StandardPlugin");
$standard_plugins = PluginManager::getInstance()->getPlugins(StandardPlugin::class);
foreach ($standard_plugins as $plugin) {
if ($plugin instanceof ActivityProvider) {
$modules[Context::COURSE][$plugin->getPluginName()] = $plugin->getPluginName();
......@@ -67,7 +67,7 @@ class ActivityfeedController extends AuthenticatedController
'blubber' => _('Blubber'),
];
$homepage_plugins = PluginEngine::getPlugins('HomepagePlugin');
$homepage_plugins = PluginEngine::getPlugins(HomepagePlugin::class);
foreach ($homepage_plugins as $plugin) {
if ($plugin->isActivated($GLOBALS['user']->id, 'user')) {
if ($plugin instanceof ActivityProvider) {
......@@ -81,7 +81,7 @@ class ActivityfeedController extends AuthenticatedController
public function configuration_action()
{
$this->config = WidgetHelper::getWidgetUserConfig($GLOBALS['user']->id, 'ACTIVITY_FEED');
$this->config = UserConfig::get($GLOBALS['user']->id)->getValue('ACTIVITY_FEED');
$this->modules = $this->getAllModules();
$this->context_translations = [
Context::COURSE => _('Veranstaltungen'),
......@@ -92,4 +92,193 @@ class ActivityfeedController extends AuthenticatedController
PageLayout::setTitle(_('Aktivitäten konfigurieren'));
}
public function load_action(): void
{
$user = User::findCurrent();
// failsafe einbauen - falls es keine älteren Aktivitäten mehr im System gibt, Abbruch!
$oldest_activity = \Studip\Activity\Activity::getOldestActivity();
$max_age = $oldest_activity ? $oldest_activity->mkdate : time();
$contexts = [];
// create system context
$system_context = new \Studip\Activity\SystemContext($user);
$contexts[] = $system_context;
$contexts[] = new \Studip\Activity\UserContext($user, $user);
$user->contacts->each(function ($another_user) use (&$contexts, $user) {
$contexts[] = new \Studip\Activity\UserContext($another_user, $user);
});
if (!in_array($user->perms, ['admin','root'])) {
// create courses and institutes context
foreach (\Course::findMany($user->course_memberships->pluck('seminar_id')) as $course) {
$contexts[] = new \Studip\Activity\CourseContext($course, $user);
}
foreach (\Institute::findMany($user->institute_memberships->pluck('institut_id')) as $institute) {
$contexts[] = new \Studip\Activity\InstituteContext($institute, $user);
}
}
// add filters
$filter = new \Studip\Activity\Filter();
$start = Request::int('start', strtotime('yesterday'));
$end = Request::int('end', time());
$scrollfrom = Request::int('scrollfrom', false);
$filtertype = Request::get('filtertype', '');
$objectType = Request::get('object_type');
$filter->setObjectType($objectType);
$objectId = Request::get('object_id');
$filter->setObjectId($objectId);
$context = Request::get('context_type');
$filter->setContext($context);
$contextId = Request::get('context_id');
$filter->setContextId($contextId);
if (!empty($filtertype)) {
$filter->setType(json_decode($filtertype));
}
if ($scrollfrom) {
// shorten "watch-window" by one second to prevent duplication of activities
$scrollfrom -= 1;
if ($scrollfrom > $max_age){
$end = $scrollfrom;
$start = strtotime('yesterday', $end);
$data = [];
$backtrack = 1;
while (empty($data)) {
$filter->setStartDate($start);
$filter->setEndDate($end);
$data = $this->getStreamData($contexts, $filter);
if ($start < $max_age) {
break;
}
// move "watch-window" back one day at a time
$end = $start - 1;
$start = strtotime("-{$backtrack} days", $start);
// enforce maximum "watch-window", currently 2 weeks
$backtrack = min(14, $backtrack + 1);
}
} else {
$data = false;
}
} else {
$filter->setStartDate($start);
$filter->setEndDate($end);
$data = $this->getStreamData($contexts, $filter);
}
// set etag for preventing resending the same stuff over and over again
$etag = md5(serialize($data));
$this->response->add_header('ETag', '"' . $etag . '"');
if (isset($_SERVER['HTTP_IF_NONE_MATCH']) && $this->etagMatches($etag, $_SERVER['HTTP_IF_NONE_MATCH'])) {
$this->set_status(304);
$this->render_nothing();
return;
}
if (isset($_SERVER['HTTP_IF_MATCH']) && !$this->etagMatches($etag, $_SERVER['HTTP_IF_MATCH'])) {
$this->set_status(412);
$this->render_nothing();
return;
}
$this->render_json($data);
}
/**
* private helper function to get stream data for given contexts and filter
*
* @param $contexts
* @param $filter
* @return array
*/
private function getStreamData($contexts, $filter): array
{
$stream = new Studip\Activity\Stream($contexts, $filter);
$data = $stream->toArray();
foreach ($data as $key => $act) {
$actor = [
'type' => $act['actor_type'],
'id' => $act['actor_id'],
];
if ($act['actor_type'] == 'user') {
$a_user = \User::findFull($act['actor_id']);
$actor['details'] = $this->getMiniUser($a_user ?: new \User());
} elseif ($act['actor_type'] === 'anonymous') {
$actor['details'] = [
'name' => _('Anonym'),
];
}
unset($data[$key]['actor_type']);
unset($data[$key]['actor_id']);
$data[$key]['actor'] = $actor;
}
return $data;
}
private function getMiniUser(User $user): array
{
$avatar = \Avatar::getAvatar($user->id);
return [
'id' => $user->id,
'name' => $this->getNamesOfUser($user),
'avatar_small' => $avatar->getURL(\Avatar::SMALL),
'avatar_medium' => $avatar->getURL(\Avatar::MEDIUM),
'avatar_normal' => $avatar->getURL(\Avatar::NORMAL),
'avatar_original' => $avatar->getURL(\Avatar::NORMAL)
];
}
private function getNamesOfUser(User $user): array
{
return [
'username' => $user->username,
'formatted' => $user->getFullName(),
'family' => $user->nachname,
'given' => $user->vorname,
'prefix' => $user->title_front,
'suffix' => $user->title_rear,
];
}
// Helper method checking if a ETag value list includes the current ETag.
private function etagMatches(string $etag, string $list)
{
if ($list === '*') {
return true;
}
return in_array(
$etag,
preg_split('/\s*,\s*/', $list)
);
}
}