diff --git a/.dockerignore b/.dockerignore index 27af4077d7..59ead79ccf 100644 --- a/.dockerignore +++ b/.dockerignore @@ -7,4 +7,16 @@ db_dumps/ data/ var/ coverage/ +VERSION +rox_local.ini +config/reference.php +docker-compose.override.yml +docker/db/*.sql +!docker/db/word.sql +docker/db/*.zip +docker/db/*.txt public/build/ +public/bundles/ +public/main.js* +public/service-worker.js* +public/images/newsletters/ diff --git a/.editorconfig b/.editorconfig index 666b266e0c..4ff40a3324 100644 --- a/.editorconfig +++ b/.editorconfig @@ -1,21 +1,10 @@ # editorconfig.org root = true -# PHP should follow the PSR-2 standard (https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-2-coding-style-guide.md) - [*] indent_style = space -indent_size = 4 -end_of_line = lf charset = utf-8 -trim_trailing_whitespace = true -insert_final_newline = true - -[Makefile] -indent_style = tab - -[*.json] -indent_style = space +end_of_line = lf indent_size = 4 [*.scss] @@ -26,10 +15,17 @@ indent_size = 2 [docker-compose{,.*}.{yaml,yml}] indent_style = space -indent_size = 2 +insert_final_newline = true +trim_trailing_whitespace = true [.github/*/*.yml] indent_size = 2 -[*.feature] +[{compose.yaml,compose.*.yaml}] +indent_size = 2 + +[*.md] +trim_trailing_whitespace = false + +[*.twig] indent_size = 2 diff --git a/.env b/.env index fd05b43d6f..63facef601 100644 --- a/.env +++ b/.env @@ -1,3 +1,19 @@ +# In all environments, the following files are loaded if they exist, +# the latter taking precedence over the former: +# +# * .env contains default values for the environment variables needed by the app +# * .env.local uncommitted file with local overrides +# * .env.$APP_ENV committed environment-specific defaults +# * .env.$APP_ENV.local uncommitted environment-specific overrides +# +# Real environment variables win over .env files. +# +# DO NOT DEFINE PRODUCTION SECRETS IN THIS FILE NOR IN ANY OTHER COMMITTED FILES. +# https://symfony.com/doc/current/configuration/secrets.html +# +# Run "composer dump-env prod" to compile .env files for production use (requires symfony/flex >=1.2). +# https://symfony.com/doc/current/best_practices.html#use-environment-variables-for-infrastructure-configuration + DB_HOST=db DB_NAME=bewelcome DB_USER=bewelcome @@ -7,16 +23,17 @@ DB_PORT=3306 APP_REFRESH_TOKEN_TTL=600 MANTICORE_HOST=manticore -MANTICORE_PORT=9312 +MANTICORE_PORT=9308 ###> symfony/framework-bundle ### APP_ENV=dev -# Set secret in .env.local -APP_SECRET=7dfa1f3adbe7f25c8c085ee1f74f816a -#TRUSTED_PROXIES=127.0.0.1,127.0.0.2 -#TRUSTED_HOSTS=localhost,example.com +APP_SECRET= ###< symfony/framework-bundle ### +WEB_PUSH_VAPID_SUBJECT= +WEB_PUSH_VAPID_PUBLIC_KEY= +WEB_PUSH_VAPID_PRIVATE_KEY= + web_host=www.bewelcome.org new_members_messages_per_hour=5 new_members_messages_per_day=10 @@ -36,17 +53,32 @@ PaypalScrPixel=https://www.sandox.paypal.com/en_US/i/scr/pixel.gif ###> symfony/mailer ### MAILER_DSN=smtp://mailer:25 +MAILER_NO_REPLY_ADDRESS=noreply@bewelcome.org +MAILER_MESSAGE_ADDRESS=noreply@bewelcome.org +MAILER_GROUP_ADDRESS=noreply@bewelcome.org +MAILER_FORUM_ADDRESS=noreply@bewelcome.org +MAILER_PASSWORD_ADDRESS=password@bewelcome.org +MAILER_SIGNUP_ADDRESS=signup@bewelcome.org +MAILER_ACCOUNT_FEEDBACK_ADDRESS=account@bewelcome.org +MAILER_REMINDER_ADDRESS=reminder@bewelcome.org +MAILER_TERMS_OF_USE_ADDRESS=tou@bewelcome.org +MAILER_NEWSLETTER_ADDRESS=newsletter@bewelcome.org ###< symfony/mailer ### -LOCALES=ar,bg,ca,cs,da,de,el,en,eo,es,eu,fa,fi,fr,gl,hi,hr,hu,id,it,ja,lt,lv,nb,nl,no,pl,pt,pt-br,rm,ro,ru,sk,sl,sr,su,sw,tr,zh-hans,zh-hant +LOCALES=ar,bg,ca,cs,da,de,el,en,eo,es,eu,fa,fi,fr,gl,hi,hr,hu,id,it,ja,lt,lv,nb,nl,no,pl,pt,pt-br,rm,ro,ru,sk,sl,sr,su,sw,tr,zh-hans,zh-hant,hy DOCUMENT_LOCALES=en,fr,es ###> nelmio/cors-bundle ### CORS_ALLOW_ORIGIN=^https?://(localhost|127\.0\.0\.1)(:[0-9]+)?$ ###< nelmio/cors-bundle ### -###> lexik/jwt-authentication-bundle ### -JWT_SECRET_KEY=%kernel.project_dir%/config/jwt/private.pem -JWT_PUBLIC_KEY=%kernel.project_dir%/config/jwt/public.pem -JWT_PASSPHRASE=02567efd63a56b25644e9b52815ce880 -###< lexik/jwt-authentication-bundle ### +###> doctrine/doctrine-bundle ### +# Format described at https://www.doctrine-project.org/projects/doctrine-dbal/en/latest/reference/configuration.html#connecting-using-a-url +# IMPORTANT: You MUST configure your server version, either here or in config/packages/doctrine.yaml +# +# DATABASE_URL="sqlite:///%kernel.project_dir%/var/data_%kernel.environment%.db" +# DATABASE_URL="mysql://app:!ChangeMe!@127.0.0.1:3306/app?serverVersion=8.0.32&charset=utf8mb4" +# DATABASE_URL="mysql://app:!ChangeMe!@127.0.0.1:3306/app?serverVersion=10.11.2-MariaDB&charset=utf8mb4" +DATABASE_URL="mysql://${DB_USER}:${DB_PASS}@${DB_HOST}:${DB_PORT}/${DB_NAME}?serverVersion=12.0.2-MariaDB&charset=utf8mb4" +#DATABASE_URL="postgresql://app:!ChangeMe!@127.0.0.1:5432/app?serverVersion=16&charset=utf8" +###< doctrine/doctrine-bundle ### diff --git a/.env.dev b/.env.dev new file mode 100644 index 0000000000..e61e4f258f --- /dev/null +++ b/.env.dev @@ -0,0 +1,4 @@ + +###> symfony/framework-bundle ### +APP_SECRET=d6fcabe2cdf4bd6979dfdcc1277fe53d +###< symfony/framework-bundle ### diff --git a/.env.test b/.env.test index 1cd665efe5..3a6e184a20 100644 --- a/.env.test +++ b/.env.test @@ -1,7 +1,14 @@ -# define your env variables for the test env here KERNEL_CLASS='App\Kernel' APP_SECRET='$ecretf0rt3st' -DATABASE_URL=mysql://root:bewelcome_root_dev@db:3306/bewelcome-test -JWT_SECRET_KEY=%kernel.project_dir%/config/jwt/private-test.pem -JWT_PUBLIC_KEY=%kernel.project_dir%/config/jwt/public-test.pem -JWT_PASSPHRASE=A2706413B33785537E7421AC51D62C46 +MAILER_DSN="null://null" +WEB_PUSH_VAPID_SUBJECT="mailto:test@example.test" +WEB_PUSH_VAPID_PUBLIC_KEY="BJl6pftxKiM7GrkHX-q_b0Rtj3aDOct1LkDvo_9zFwPZAFaB6rMwAwVRYmTIBTBBsqQ-OaSdOwXEN-86oVV8bkg" +WEB_PUSH_VAPID_PRIVATE_KEY="2N9ejENMtuyDJe8fyBiIm-qcxdMqMHZBuXi36dob-Ow" +MANTICORE_HOST="127.0.0.1" +MANTICORE_PORT="9308" +DB_HOST="127.0.0.1" +DB_PORT="3306" +DB_USER="bewelcome" +DB_PASS="bewelcome" +DB_NAME="bewelcome" +DATABASE_URL="mysql://${DB_USER}:${DB_PASS}@${DB_HOST}:${DB_PORT}/${DB_NAME}?serverVersion=10.11.2-MariaDB&charset=utf8mb4" diff --git a/.github/workflows/build-image.yml b/.github/workflows/build-image.yml new file mode 100644 index 0000000000..7a64c0a630 --- /dev/null +++ b/.github/workflows/build-image.yml @@ -0,0 +1,294 @@ +name: Build and publish image + +# Builds the production (bewelcome_php) image once in CI for both linux/amd64 and +# linux/arm64, pushes a multi-arch manifest to GHCR with immutable tags, scans the +# image with Trivy, and — only when the parallel CI workflow also passes — notifies +# BeWelcome/sysadmins-infra to deploy. The deploy server then only runs +# `docker compose pull && up -d` — no on-server build. +# +# Each architecture is built on a native runner (no QEMU emulation) and pushed +# by digest; a final job stitches the per-arch digests into one manifest list so +# `docker pull` resolves the right arch automatically. + +on: + push: + branches: [develop] + # Only rebuild when something that ends up in the image actually changes. + paths: + - 'Dockerfile' + - '.dockerignore' + - 'docker/**' + - 'composer.json' + - 'composer.lock' + - 'symfony.lock' + - 'package.json' + - 'bun.lock' + - 'webpack.config.js' + - 'tailwind.config.js' + - 'postcss.config.js' + - 'src/**' + - 'assets/**' + - 'config/**' + - 'templates/**' + - 'public/**' + - 'bin/**' + - 'bootstrap/**' + - 'routes.php' + - '.github/workflows/build-image.yml' + tags: + - 'v*' + workflow_dispatch: {} + +permissions: + contents: read + packages: write + actions: read + +env: + IMAGE: ghcr.io/bewelcome/rox + +# Serialize per-ref so rapid develop pushes don't race two builds and fire two +# competing deploy dispatches; the newer push wins. +concurrency: + group: build-image-${{ github.ref }} + cancel-in-progress: true + +jobs: + build: + name: Build ${{ matrix.arch }} + runs-on: ${{ matrix.runner }} + strategy: + fail-fast: false + matrix: + include: + - arch: amd64 + platform: linux/amd64 + runner: ubuntu-latest + - arch: arm64 + platform: linux/arm64 + runner: ubuntu-24.04-arm + steps: + - name: Checkout + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # tag=v4.2.2 + + - name: Compute version metadata + id: version + run: | + echo "revision=$(git rev-parse --short HEAD)" >> "$GITHUB_OUTPUT" + echo "timestamp=$(git log -n 1 --format=%ct)" >> "$GITHUB_OUTPUT" + + - name: Log in to GitHub Container Registry + uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # tag=v3.4.0 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Extract image metadata + id: meta + uses: docker/metadata-action@369eb591f429131d6889c46b94e711f089e6ca96 # tag=v5.6.1 + with: + images: ${{ env.IMAGE }} + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@6524bf65af31da8d45b59e8c27de4bd072b392f5 # tag=v3.8.0 + + # Build the single-arch image and push it by digest only (no tags yet); + # the merge job assembles the tagged multi-arch manifest from these digests. + - name: Build and push by digest + id: build + uses: docker/build-push-action@4f58ea79222b3b9dc2c8bbdd6debcef730109a75 # tag=v6.9.0 + with: + context: . + target: bewelcome_php + platforms: ${{ matrix.platform }} + build-args: | + APP_VERSION=${{ steps.version.outputs.revision }} + APP_VERSION_TIMESTAMP=${{ steps.version.outputs.timestamp }} + labels: ${{ steps.meta.outputs.labels }} + cache-from: type=gha,scope=${{ matrix.arch }} + cache-to: type=gha,mode=max,scope=${{ matrix.arch }} + outputs: type=image,name=${{ env.IMAGE }},push-by-digest=true,name-canonical=true,push=true + + - name: Export digest + run: | + mkdir -p /tmp/digests + digest="${{ steps.build.outputs.digest }}" + touch "/tmp/digests/${digest#sha256:}" + + - name: Upload digest + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # tag=v4.6.2 + with: + name: digests-${{ matrix.arch }} + path: /tmp/digests/* + if-no-files-found: error + retention-days: 1 + + merge: + name: Push manifest + runs-on: ubuntu-latest + needs: [build] + outputs: + short_sha: ${{ steps.vars.outputs.short_sha }} + digest: ${{ steps.manifest.outputs.digest }} + steps: + - name: Download digests + uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # tag=v4.1.8 + with: + path: /tmp/digests + pattern: digests-* + merge-multiple: true + + - name: Log in to GitHub Container Registry + uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # tag=v3.4.0 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@6524bf65af31da8d45b59e8c27de4bd072b392f5 # tag=v3.8.0 + + - name: Extract image metadata + id: meta + uses: docker/metadata-action@369eb591f429131d6889c46b94e711f089e6ca96 # tag=v5.6.1 + with: + images: ${{ env.IMAGE }} + tags: | + type=sha,prefix=sha- + type=ref,event=branch + type=semver,pattern={{version}} + type=semver,pattern={{major}}.{{minor}} + type=semver,pattern={{major}} + + - name: Create and push multi-arch manifest + working-directory: /tmp/digests + run: | + docker buildx imagetools create \ + $(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \ + $(printf '${{ env.IMAGE }}@sha256:%s ' *) + + # The recomputed 7-char short sha MUST match docker/metadata-action's + # `type=sha` output (default short format = 7 chars). If anyone switches + # metadata-action to `format=long`, the `imagetools inspect :sha-` + # lookup below (and the deploy payload tag) will no longer match the pushed + # tag and must be updated accordingly. + - name: Compute short sha + id: vars + run: echo "short_sha=${GITHUB_SHA::7}" >> "$GITHUB_OUTPUT" + + # Resolve the immutable digest of the freshly pushed manifest list so the + # deploy payload (and rollback) pins an exact, arch-agnostic reference. + - name: Capture manifest digest + id: manifest + run: | + digest=$(docker buildx imagetools inspect "${{ env.IMAGE }}:sha-${{ steps.vars.outputs.short_sha }}" --format '{{json .Manifest.Digest}}' | tr -d '"') + echo "digest=$digest" >> "$GITHUB_OUTPUT" + + scan: + name: Scan image + runs-on: ubuntu-latest + needs: [merge] + steps: + - name: Log in to GitHub Container Registry + uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # tag=v3.4.0 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Run Trivy vulnerability scanner + uses: aquasecurity/trivy-action@ed142fd0673e97e23eac54620cfb913e5ce36c25 # tag=v0.36.0 + env: + TRIVY_DISABLE_VEX_NOTICE: '1' + with: + image-ref: ${{ env.IMAGE }}:sha-${{ needs.merge.outputs.short_sha }} + format: table + severity: CRITICAL,HIGH,MEDIUM + exit-code: '1' + ignore-unfixed: true + + deploy: + name: Deploy to stage + runs-on: ubuntu-latest + needs: [merge, scan] + if: > + github.event_name == 'push' && + github.ref == 'refs/heads/develop' && + needs.merge.result == 'success' && + needs.scan.result == 'success' + steps: + - name: Wait for CI workflow on this commit + # Poll ci.yml on this SHA only (not every GitHub check on the commit). + uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # tag=v7.0.1 + with: + script: | + const { owner, repo } = context.repo; + const sha = context.sha; + const pollIntervalMs = 15_000; + const maxAttempts = 40; + + const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms)); + + for (let attempt = 1; attempt <= maxAttempts; attempt++) { + const { data } = await github.rest.actions.listWorkflowRuns({ + owner, + repo, + workflow_id: 'ci.yml', + head_sha: sha, + per_page: 1, + }); + + const run = data.workflow_runs[0]; + if (!run) { + core.info(`CI workflow not started yet (attempt ${attempt}/${maxAttempts})`); + await sleep(pollIntervalMs); + continue; + } + + core.info(`CI workflow ${run.html_url} status=${run.status} conclusion=${run.conclusion ?? 'pending'}`); + + if (run.status !== 'completed') { + await sleep(pollIntervalMs); + continue; + } + + if (run.conclusion !== 'success') { + core.setFailed(`CI workflow finished with conclusion "${run.conclusion}" — stage deploy blocked`); + return; + } + + core.info('CI workflow passed'); + return; + } + + core.setFailed('Timed out waiting for CI workflow to complete'); + + # Mint a short-lived installation token for the bewelcome-platform-deployer + # GitHub App (installed on sysadmins-infra) to authenticate the cross-repo + # dispatch, scoped to just that repo. + - name: Mint cross-repo token + id: app-token + uses: actions/create-github-app-token@5d869da34e18e7287c1daad50e0b8ea0f506ce69 # tag=v1.11.0 + with: + app-id: ${{ secrets.DEPLOY_APP_ID }} + private-key: ${{ secrets.DEPLOY_APP_PRIVATE_KEY }} + owner: BeWelcome + repositories: sysadmins-infra + + # Trigger the stage deploy only for develop pushes. Tag (v*) builds publish + # SemVer images but are deployed manually/gated from sysadmins-infra. + - name: Notify sysadmins-infra to deploy stage + uses: peter-evans/repository-dispatch@ff45666b9427631e3450c54a1bcbee4d9ff4d7c0 # tag=v3.0.0 + with: + token: ${{ steps.app-token.outputs.token }} + repository: BeWelcome/sysadmins-infra + event-type: rox-image-pushed + client-payload: | + { + "image": "${{ env.IMAGE }}:sha-${{ needs.merge.outputs.short_sha }}@${{ needs.merge.outputs.digest }}", + "tag": "sha-${{ needs.merge.outputs.short_sha }}", + "sha": "${{ github.sha }}", + "ref": "${{ github.ref }}", + "environment": "stage" + } diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2d46163cd1..b920360d7c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,406 +1,394 @@ -name: CI - -on: - # Run CI every night at 2am - schedule: - - cron: 0 2 * * * - # Run CI on every Pull Request - pull_request: ~ - # Run CI only on push on bootstrap4 branch - push: - branches: - - bootstrap4 - - feature/trips - -jobs: - phpcpd: - name: PHPCPD - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v2 - - - name: Setup PHP - uses: shivammathur/setup-php@v2 - with: - php-version: 7.4 - extensions: curl, dom, gd, iconv, intl, json, libxml, mbstring, mysqli, pcntl, pdo_mysql, phar, tokenizer, xml, xmlwriter, xsl, zip - - - name: Get Composer Cache Directory - id: composer-cache - run: echo "::set-output name=dir::$(composer config cache-files-dir)" - - - name: Cache dependencies - uses: actions/cache@v1 - with: - path: ${{ steps.composer-cache.outputs.dir }} - key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }} - restore-keys: ${{ runner.os }}-composer- - - - name: Install project dependencies - run: composer install --prefer-dist --no-progress --no-suggest --no-interaction --no-scripts - - - name: Run phpcpd tests - run: vendor/bin/phpcpd src --exclude=src/Entity - - phpunit: - name: PHPUnit - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v2 - - - name: Setup PHP - uses: shivammathur/setup-php@v2 - with: - php-version: 7.4 - extensions: curl, dom, gd, iconv, intl, json, libxml, mbstring, mysqli, pcntl, pdo_mysql, phar, tokenizer, xdebug, xml, xmlwriter, xsl, zip - - - name: Get Composer Cache Directory - id: composer-cache - run: echo "::set-output name=dir::$(composer config cache-files-dir)" - - - name: Cache dependencies - uses: actions/cache@v1 - with: - path: ${{ steps.composer-cache.outputs.dir }} - key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }} - restore-keys: ${{ runner.os }}-composer- - - - name: Install project dependencies - run: composer install --prefer-dist --no-progress --no-suggest --no-interaction --no-scripts - - - name: Run phpunit tests - run: bin/phpunit - - - name: Run phpunit tests - run: phpdbg -qrr bin/phpunit --coverage-text --coverage-xml=build/logs/phpunit/coverage-xml --coverage-clover=build/logs/phpunit/clover.xml --log-junit=build/logs/phpunit/junit.xml --colors=never - - - name: Run Infection tests - run: vendor/bin/infection --only-covered --coverage=build/logs/phpunit --min-covered-msi=85 --threads=30 - - - uses: actions/upload-artifact@v2 - if: ${{ always() }} - with: - name: infection.log - path: infection.log - - behat: - name: Behat - runs-on: ubuntu-latest - env: - MAILER_DSN: 'smtp://localhost:1025' - DATABASE_URL: 'mysql://bewelcome:bewelcome@127.0.0.1:3306/bewelcome' - APP_ENV: 'test' - services: - mailcatcher: - image: tophfr/mailcatcher - ports: - - 1080:80 - - 1025:25 - db: - image: mariadb:10.1.41 - env: - MYSQL_ROOT_PASSWORD: bewelcome_root_dev - MYSQL_DATABASE: bewelcome - MYSQL_USER: bewelcome - MYSQL_PASSWORD: bewelcome - ports: - - 3306:3306 - steps: - - name: Checkout - uses: actions/checkout@v2 - - - name: Setup PHP - uses: shivammathur/setup-php@v2 - with: - php-version: 7.4 - extensions: curl, dom, gd, iconv, intl, json, libxml, mbstring, mysqli, pcntl, pdo_mysql, phar, tokenizer, xml, xmlwriter, xsl, zip - - - name: Setup NODE - uses: actions/setup-node@v2-beta - with: - node-version: '12' - - - name: Get Composer Cache Directory - id: composer-cache - run: echo "::set-output name=dir::$(composer config cache-files-dir)" - - - name: Cache dependencies - uses: actions/cache@v1 - with: - path: ${{ steps.composer-cache.outputs.dir }} - key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }} - restore-keys: ${{ runner.os }}-composer- - - - name: Install project dependencies - run: | - yarn install --frozen-lock - composer install --prefer-dist --no-progress --no-suggest --no-interaction --no-scripts - - - name: Prepare test database - run: | - yarn encore production - bin/console doctrine:database:create --env=test --if-not-exists - bin/console doctrine:schema:create --env=test - bin/console hautelook:fixtures:load --env=test --no-interaction - - - name: Run behat tests - run: vendor/bin/behat --profile localhost --colors --tags='~@wip' - - phploc: - name: PHPLoc - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v2 - - - name: Setup PHP - uses: shivammathur/setup-php@v2 - with: - php-version: 7.4 - extensions: curl, dom, gd, iconv, intl, json, libxml, mbstring, mysqli, pcntl, pdo_mysql, phar, tokenizer, xml, xmlwriter, xsl, zip - - - name: Get Composer Cache Directory - id: composer-cache - run: echo "::set-output name=dir::$(composer config cache-files-dir)" - - - name: Cache dependencies - uses: actions/cache@v1 - with: - path: ${{ steps.composer-cache.outputs.dir }} - key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }} - restore-keys: ${{ runner.os }}-composer- - - - name: Install project dependencies - run: composer install --prefer-dist --no-progress --no-suggest --no-interaction --no-scripts - - - name: Run phploc tests - run: vendor/bin/phploc --log-xml=phploc.xml src tests - - phpmd: - name: PHPMD - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v2 - - - name: Setup PHP - uses: shivammathur/setup-php@v2 - with: - php-version: 7.4 - extensions: curl, dom, gd, iconv, intl, json, libxml, mbstring, mysqli, pcntl, pdo_mysql, phar, tokenizer, xml, xmlwriter, xsl, zip - - - name: Get Composer Cache Directory - id: composer-cache - run: echo "::set-output name=dir::$(composer config cache-files-dir)" - - - name: Cache dependencies - uses: actions/cache@v1 - with: - path: ${{ steps.composer-cache.outputs.dir }} - key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }} - restore-keys: ${{ runner.os }}-composer- - - - name: Install project dependencies - run: composer install --prefer-dist --no-progress --no-suggest --no-interaction --no-scripts - - - name: Run phpmd tests - run: vendor/bin/phpmd src,tests text phpmd.xml - - php-cs-fixer: - name: PHP-CS-Fixer - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v2 - - - name: Setup PHP - uses: shivammathur/setup-php@v2 - with: - php-version: 7.4 - extensions: curl, dom, gd, iconv, intl, json, libxml, mbstring, mysqli, pcntl, pdo_mysql, phar, tokenizer, xml, xmlwriter, xsl, zip - - - name: Get Composer Cache Directory - id: composer-cache - run: echo "::set-output name=dir::$(composer config cache-files-dir)" - - - name: Cache dependencies - uses: actions/cache@v1 - with: - path: ${{ steps.composer-cache.outputs.dir }} - key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }} - restore-keys: ${{ runner.os }}-composer- - - - name: Install project dependencies - run: composer install --prefer-dist --no-progress --no-suggest --no-interaction --no-scripts - - - name: Run php-cs-fixer tests - run: vendor/bin/php-cs-fixer fix -v --diff --dry-run - - php-code-sniffer: - name: PHP-Code-Sniffer - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v2 - - - name: Setup PHP - uses: shivammathur/setup-php@v2 - with: - php-version: 7.4 - extensions: curl, dom, gd, iconv, intl, json, libxml, mbstring, mysqli, pcntl, pdo_mysql, phar, tokenizer, xml, xmlwriter, xsl, zip - - - name: Get Composer Cache Directory - id: composer-cache - run: echo "::set-output name=dir::$(composer config cache-files-dir)" - - - name: Cache dependencies - uses: actions/cache@v1 - with: - path: ${{ steps.composer-cache.outputs.dir }} - key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }} - restore-keys: ${{ runner.os }}-composer- - - - name: Install project dependencies - run: composer install --prefer-dist --no-progress --no-suggest --no-interaction --no-scripts - - - name: Run php-code-sniffer tests - run: vendor/bin/phpcs --colors --warning-severity=Error - - lint-yaml: - name: Lint YAML - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v2 - - - name: Setup PHP - uses: shivammathur/setup-php@v2 - with: - php-version: 7.4 - extensions: curl, dom, gd, iconv, intl, json, libxml, mbstring, mysqli, pcntl, pdo_mysql, phar, tokenizer, xml, xmlwriter, xsl, zip - - - name: Get Composer Cache Directory - id: composer-cache - run: echo "::set-output name=dir::$(composer config cache-files-dir)" - - - name: Cache dependencies - uses: actions/cache@v1 - with: - path: ${{ steps.composer-cache.outputs.dir }} - key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }} - restore-keys: ${{ runner.os }}-composer- - - - name: Install project dependencies - run: composer install --prefer-dist --no-progress --no-suggest --no-interaction --no-scripts - - - name: Run Linter - run: bin/console lint:yaml --parse-tags config fixtures - - doctrine-schema-validator: - name: Validate Doctrine schema - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v2 - - - name: Setup PHP - uses: shivammathur/setup-php@v2 - with: - php-version: 7.4 - extensions: curl, dom, gd, iconv, intl, json, libxml, mbstring, mysqli, pcntl, pdo_mysql, phar, tokenizer, xml, xmlwriter, xsl, zip - - - name: Get Composer Cache Directory - id: composer-cache - run: echo "::set-output name=dir::$(composer config cache-files-dir)" - - - name: Cache dependencies - uses: actions/cache@v1 - with: - path: ${{ steps.composer-cache.outputs.dir }} - key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }} - restore-keys: ${{ runner.os }}-composer- - - - name: Install project dependencies - run: composer install --prefer-dist --no-progress --no-suggest --no-interaction --no-scripts - - - name: Validate Doctrine schema - run: bin/console doctrine:schema:validate --skip-sync - - swagger: - name: Swagger validator - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v2 - - - name: Setup PHP - uses: shivammathur/setup-php@v2 - with: - php-version: 7.4 - extensions: curl, dom, gd, iconv, intl, json, libxml, mbstring, mysqli, pcntl, pdo_mysql, phar, tokenizer, xml, xmlwriter, xsl, zip - - - name: Setup NODE - uses: actions/setup-node@v2-beta - - - name: Get Composer Cache Directory - id: composer-cache - run: echo "::set-output name=dir::$(composer config cache-files-dir)" - - - name: Cache dependencies - uses: actions/cache@v1 - with: - path: ${{ steps.composer-cache.outputs.dir }} - key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }} - restore-keys: ${{ runner.os }}-composer- - - - name: Install project dependencies - run: | - composer install --prefer-dist --no-progress --no-suggest --no-interaction --no-scripts - yarn install --frozen-lock - - - name: Export Swagger documentation - run: bin/console api:swagger:export > swagger.json - - - name: Validate Swagger documentation - run: yarn swagger-cli validate swagger.json - - security: - name: Security checks - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v2 - - - name: Setup PHP - uses: shivammathur/setup-php@v2 - with: - php-version: 7.4 - extensions: curl, dom, gd, iconv, intl, json, libxml, mbstring, mysqli, pcntl, pdo_mysql, phar, tokenizer, xml, xmlwriter, xsl, zip - tools: symfony - - - name: Setup NODE - uses: actions/setup-node@v2-beta - - - name: Get Composer Cache Directory - id: composer-cache - run: echo "::set-output name=dir::$(composer config cache-files-dir)" - - - name: Cache dependencies - uses: actions/cache@v1 - with: - path: ${{ steps.composer-cache.outputs.dir }} - key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }} - restore-keys: ${{ runner.os }}-composer- - - - name: Install project dependencies - run: | - composer install --prefer-dist --no-progress --no-suggest --no-interaction --no-scripts - yarn install --frozen-lock - - - name: Run PHP security checker - run: symfony security:check - - - name: Run JS security checker - run: yarn audit +name: CI + +on: + # Run CI every night at 2am + schedule: + - cron: 0 2 * * * + # Run CI on every Pull Request + pull_request: ~ + # Run CI only on push on develop branch + push: + workflow_dispatch: + +env: + PHP_VERSION: 8.4 + +permissions: + contents: read + +jobs: + phpcpd: + name: PHPCPD + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # tag=v7.0.0 + + - name: Setup PHP + uses: shivammathur/setup-php@f3e473d116dcccaddc5834248c87452386958240 # tag=2.37.2 + with: + php-version: ${{ env.PHP_VERSION }} + extensions: curl, dom, gd, iconv, intl, json, libxml, mbstring, mysqli, pcntl, pdo_mysql, phar, tokenizer, xml, xmlwriter, xsl, zip + + - name: Get Composer Cache Directory + id: composer-cache + run: echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT + + - name: Cache dependencies + uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # tag=v5.0.5 + with: + path: ${{ steps.composer-cache.outputs.dir }} + key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }} + restore-keys: ${{ runner.os }}-composer- + + - name: Install project dependencies + run: composer install --prefer-dist --no-progress --no-suggest --no-interaction --no-scripts + + - name: Run phpcpd tests + run: vendor/bin/phpcpd src --exclude=src/Entity --exclude=src/Repository + + tests: + name: Tests + runs-on: ubuntu-latest + env: + DOCKER_API_VERSION: '1.44' + steps: + - name: Checkout + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # tag=v7.0.0 + + - name: Setup PHP + uses: shivammathur/setup-php@f3e473d116dcccaddc5834248c87452386958240 # tag=2.37.2 + with: + php-version: ${{ env.PHP_VERSION }} + extensions: curl, dom, gd, iconv, intl, json, libxml, mbstring, mysqli, pcntl, pdo_mysql, phar, tokenizer, xdebug, xml, xmlwriter, xsl, zip + coverage: xdebug + + - name: Get Composer Cache Directory + id: composer-cache + run: echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT + + - name: Cache dependencies + uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # tag=v5.0.5 + with: + path: ${{ steps.composer-cache.outputs.dir }} + key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }} + restore-keys: ${{ runner.os }}-composer- + + - name: Install project dependencies + run: composer install --prefer-dist --no-progress --no-suggest --no-interaction --no-scripts + + - name: Run phpunit tests + run: bin/phpunit --coverage-text --coverage-xml=build/logs/phpunit/coverage-xml --coverage-clover=build/logs/phpunit/clover.xml --log-junit=build/logs/phpunit/junit.xml --colors=never --order-by=random --exclude-group=integration + + - name: Run Infection tests + run: vendor/bin/infection --skip-initial-tests --coverage=build/logs/phpunit --min-covered-msi=80 --threads=30 + + - name: Install MariaDB + uses: getong/mariadb-action@v1.11 + with: + mysql database: 'bewelcome_test' + mysql user: 'bewelcome' + mysql password: 'bewelcome' + + - name: Create test database + run: bin/console test:database:create --env=test + + - name: Warmup cache + run: bin/console cache:clear --env=test + + - name: Setup Bun + uses: oven-sh/setup-bun@v2 + + - name: Install bun dependencies + uses: nick-fields/retry@ad984534de44a9489a53aefd81eb77f87c70dc60 # tag=v4.0.0 + with: + timeout_minutes: 10 + max_attempts: 5 + retry_wait_seconds: 15 + command: bun i --frozen-lockfile + + - name: Run webpack + run: bun encore dev + + - name: Run Integration tests + run: bin/phpunit --log-junit=build/logs/phpunit/integration.xml --colors=never --order-by=random --group=integration + + - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # tag=v7.0.1 + if: ${{ always() }} + with: + name: infection.log + path: infection.log + + phploc: + name: PHPLoc + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # tag=v7.0.0 + + - name: Setup PHP + uses: shivammathur/setup-php@f3e473d116dcccaddc5834248c87452386958240 # tag=2.37.2 + with: + php-version: ${{ env.PHP_VERSION }} + extensions: curl, dom, gd, iconv, intl, json, libxml, mbstring, mysqli, pcntl, pdo_mysql, phar, tokenizer, xml, xmlwriter, xsl, zip + + - name: Get Composer Cache Directory + id: composer-cache + run: echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT + + - name: Cache dependencies + uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # tag=v5.0.5 + with: + path: ${{ steps.composer-cache.outputs.dir }} + key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }} + restore-keys: ${{ runner.os }}-composer- + + - name: Install project dependencies + run: composer install --prefer-dist --no-progress --no-suggest --no-interaction --no-scripts + + - name: Run phploc + run: vendor/bin/phploc --log-xml=phploc.xml src tests + + + phpstan: + name: PHPStan (experimental) + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # tag=v7.0.0 + + - name: Setup PHP + uses: shivammathur/setup-php@f3e473d116dcccaddc5834248c87452386958240 # tag=2.37.2 + with: + php-version: ${{ env.PHP_VERSION }} + extensions: curl, dom, gd, iconv, intl, json, libxml, mbstring, mysqli, pcntl, pdo_mysql, phar, tokenizer, xml, xmlwriter, xsl, zip + + - name: Get Composer Cache Directory + id: composer-cache + run: echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT + + - name: Cache dependencies + uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # tag=v5.0.5 + with: + path: ${{ steps.composer-cache.outputs.dir }} + key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }} + restore-keys: ${{ runner.os }}-composer- + + - name: Install project dependencies + run: composer install --prefer-dist --no-progress --no-interaction --no-scripts + + - name: Install MariaDB + uses: getong/mariadb-action@v1.11 + with: + mysql database: 'bewelcome' + mysql user: 'bewelcome' + mysql password: 'bewelcome' + + - name: Create test database + run: bin/console test:database:create --env=dev + env: + DB_HOST: 127.0.0.1 + + - name: Warmup cache + run: bin/console cache:clear --env=dev + env: + DB_HOST: 127.0.0.1 + + - name: Run phpstan + continue-on-error: true + run: vendor/bin/phpstan + +# phpmd: +# name: PHPMD +# runs-on: ubuntu-latest +# steps: +# - name: Checkout +# uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # tag=v7.0.0 +# +# - name: Setup PHP +# uses: shivammathur/setup-php@f3e473d116dcccaddc5834248c87452386958240 # tag=2.37.2 +# with: +# php-version: ${{ env.PHP_VERSION }} +# extensions: curl, dom, gd, iconv, intl, json, libxml, mbstring, mysqli, pcntl, pdo_mysql, phar, tokenizer, xml, xmlwriter, xsl, zip +# +# - name: Get Composer Cache Directory +# id: composer-cache +# run: echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT +# +# - name: Cache dependencies +# uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # tag=v5.0.5 +# with: +# path: ${{ steps.composer-cache.outputs.dir }} +# key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }} +# restore-keys: ${{ runner.os }}-composer- +# +# - name: Install project dependencies +# run: composer install --prefer-dist --no-progress --no-suggest --no-interaction --no-scripts +# +# - name: Run phpmd tests +# run: vendor/bin/phpmd src,tests text phpmd.xml + + php-cs-fixer: + name: PHP-CS-Fixer + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # tag=v7.0.0 + + - name: Setup PHP + uses: shivammathur/setup-php@f3e473d116dcccaddc5834248c87452386958240 # tag=2.37.2 + with: + php-version: ${{ env.PHP_VERSION }} + extensions: curl, dom, gd, iconv, intl, json, libxml, mbstring, mysqli, pcntl, pdo_mysql, phar, tokenizer, xml, xmlwriter, xsl, zip + + - name: Get Composer Cache Directory + id: composer-cache + run: echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT + + - name: Cache dependencies + uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # tag=v5.0.5 + with: + path: ${{ steps.composer-cache.outputs.dir }} + key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }} + restore-keys: ${{ runner.os }}-composer- + + - name: Install project dependencies + run: composer install --prefer-dist --no-progress --no-suggest --no-interaction --no-scripts + + - name: Run php-cs-fixer tests + run: vendor/bin/php-cs-fixer fix -v --diff --dry-run + + php-code-sniffer: + name: PHP-Code-Sniffer + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # tag=v7.0.0 + + - name: Setup PHP + uses: shivammathur/setup-php@f3e473d116dcccaddc5834248c87452386958240 # tag=2.37.2 + with: + php-version: ${{ env.PHP_VERSION }} + extensions: curl, dom, gd, iconv, intl, json, libxml, mbstring, mysqli, pcntl, pdo_mysql, phar, tokenizer, xml, xmlwriter, xsl, zip + + - name: Get Composer Cache Directory + id: composer-cache + run: echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT + + - name: Cache dependencies + uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # tag=v5.0.5 + with: + path: ${{ steps.composer-cache.outputs.dir }} + key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }} + restore-keys: ${{ runner.os }}-composer- + + - name: Install project dependencies + run: composer install --prefer-dist --no-progress --no-suggest --no-interaction --no-scripts + + - name: Run php-code-sniffer tests + run: vendor/bin/phpcs --colors --warning-severity=Error + + lint-yaml: + name: Lint YAML + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # tag=v7.0.0 + + - name: Setup PHP + uses: shivammathur/setup-php@f3e473d116dcccaddc5834248c87452386958240 # tag=2.37.2 + with: + php-version: ${{ env.PHP_VERSION }} + extensions: curl, dom, gd, iconv, intl, json, libxml, mbstring, mysqli, pcntl, pdo_mysql, phar, tokenizer, xml, xmlwriter, xsl, zip + + - name: Get Composer Cache Directory + id: composer-cache + run: echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT + + - name: Cache dependencies + uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # tag=v5.0.5 + with: + path: ${{ steps.composer-cache.outputs.dir }} + key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }} + restore-keys: ${{ runner.os }}-composer- + + - name: Install project dependencies + run: composer install --prefer-dist --no-progress --no-suggest --no-interaction --no-scripts + + - name: Run Linter + run: bin/console lint:yaml --parse-tags config fixtures + + doctrine-schema-validator: + name: Validate Doctrine schema + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # tag=v7.0.0 + + - name: Setup PHP + uses: shivammathur/setup-php@f3e473d116dcccaddc5834248c87452386958240 # tag=2.37.2 + with: + php-version: ${{ env.PHP_VERSION }} + extensions: curl, dom, gd, iconv, intl, json, libxml, mbstring, mysqli, pcntl, pdo_mysql, phar, tokenizer, xml, xmlwriter, xsl, zip + + - name: Get Composer Cache Directory + id: composer-cache + run: echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT + + - name: Cache dependencies + uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # tag=v5.0.5 + with: + path: ${{ steps.composer-cache.outputs.dir }} + key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }} + restore-keys: ${{ runner.os }}-composer- + + - name: Install project dependencies + run: composer install --prefer-dist --no-progress --no-suggest --no-interaction --no-scripts + + - name: Validate Doctrine schema + run: bin/console doctrine:schema:validate --skip-sync + + security: + name: Security checks + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # tag=v7.0.0 + + - name: Setup PHP + uses: shivammathur/setup-php@f3e473d116dcccaddc5834248c87452386958240 # tag=2.37.2 + with: + php-version: ${{ env.PHP_VERSION }} + extensions: curl, dom, gd, iconv, intl, json, libxml, mbstring, mysqli, pcntl, pdo_mysql, phar, tokenizer, xml, xmlwriter, xsl, zip + tools: symfony + + - name: Setup Bun + uses: oven-sh/setup-bun@v2 + + - name: Get Composer Cache Directory + id: composer-cache + run: echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT + + - name: Cache dependencies + uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # tag=v5.0.5 + with: + path: ${{ steps.composer-cache.outputs.dir }} + key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }} + restore-keys: ${{ runner.os }}-composer- + + - name: Install project dependencies + run: composer install --prefer-dist --no-progress --no-suggest --no-interaction --no-scripts + + - name: Install bun dependencies + uses: nick-fields/retry@ad984534de44a9489a53aefd81eb77f87c70dc60 # tag=v4.0.0 + with: + timeout_minutes: 10 + max_attempts: 5 + retry_wait_seconds: 15 + command: bun i --frozen-lockfile + + - name: Run PHP security checker + run: symfony security:check + + - name: Run JS security checker + run: bun audit diff --git a/.github/workflows/gitlab-mirror.yml b/.github/workflows/gitlab-mirror.yml deleted file mode 100644 index f9d1129ae7..0000000000 --- a/.github/workflows/gitlab-mirror.yml +++ /dev/null @@ -1,15 +0,0 @@ -name: trigger mirror to gitlab - -on: [push] - -jobs: - trigger: - runs-on: "ubuntu-latest" - steps: - - name: trigger - uses: appleboy/gitlab-ci-action@v0.0.2 - with: - host: "https://gitlab.bewelcome.org" - token: ${{ secrets.TRIGGER_TOKEN }} - project_id: 17 - ref: master diff --git a/.gitignore b/.gitignore index a940fd07cc..e27b868558 100644 --- a/.gitignore +++ b/.gitignore @@ -2,12 +2,16 @@ # Here is a sample: https://gist.github.com/vincentchalamon/d5defad563ed49d9306a4aa57dfd4498 errors.log rox_local.ini +.php-version *.cache.ini .php_cs.cache +.php-cs-fixer.cache .phpunit.result.cache /data/* !data/user/avatars/.gitkeep !data/gallery/member/.gitkeep +/upload/* +!upload/images/.gitkeep google*.html tools/testenv/images/status.csv components/* @@ -16,6 +20,7 @@ revision.txt .sass-cache doc/ /docker/db/* +!docker/db/word.sql !docker/db/.gitkeep docker-compose.override.* !docker-compose.override.yml.dist @@ -41,6 +46,8 @@ phploc.xml /swagger.json /build/logs/ +.idea/ + # geonames files (created by geonames:update command) admin1CodesASCII.txt countryInfo.txt @@ -56,33 +63,20 @@ allCountries.zip /public/bundles/ /var/ /vendor/ +/config/reference.php ###< symfony/framework-bundle ### - -###> symfony/phpunit-bridge ### -.phpunit -/phpunit.xml -.phpunit.result.cache -###< symfony/phpunit-bridge ### - ###> symfony/webpack-encore-bundle ### /node_modules/ /public/build/ /public/main.js* /public/service-worker.js* npm-debug.log -yarn-error.log ###< symfony/webpack-encore-bundle ### ###> squizlabs/php_codesniffer ### /.phpcs-cache /phpcs.xml ###< squizlabs/php_codesniffer ### - -###> lexik/jwt-authentication-bundle ### -/config/jwt/*.pem -!/config/jwt/*-test.pem -###< lexik/jwt-authentication-bundle ### - ###> friends-of-behat/symfony-extension ### /behat.yml ###< friends-of-behat/symfony-extension ### @@ -93,3 +87,12 @@ yarn-error.log /.php-cs-fixer.php /.php-cs-fixer.cache ###< friendsofphp/php-cs-fixer ### + +###> phpunit/phpunit ### +/phpunit.xml +/.phpunit.cache/ +###< phpunit/phpunit ### + +###> phpstan/phpstan ### +phpstan.neon +###< phpstan/phpstan ### diff --git a/.php-cs-fixer.dist.php b/.php-cs-fixer.dist.php index fb75d7941a..95df42c376 100644 --- a/.php-cs-fixer.dist.php +++ b/.php-cs-fixer.dist.php @@ -1,44 +1,55 @@ exclude('src/Mike42') ->notName('*.twig') ->notName('*.yml') - ->in('src'); + ->in(['src/', 'tests/']) +; $config = new PhpCsFixer\Config(); $config + ->setParallelConfig(new PhpCsFixer\Runner\Parallel\ParallelConfig(4, 20)) ->setRiskyAllowed(true) ->setRules([ + '@PHP8x3Migration' => true, + '@PHP8x4Migration' => true, '@Symfony' => true, '@Symfony:risky' => true, 'array_syntax' => ['syntax' => 'short'], 'combine_consecutive_unsets' => true, // one should use PHPUnit methods to set up expected exception instead of annotations 'general_phpdoc_annotation_remove' => [ - 'expectedException', - 'expectedExceptionMessage', - 'expectedExceptionMessageRegExp' + 'annotations' => [ + 'expectedException', + 'expectedExceptionMessage', + 'expectedExceptionMessageRegExp', + ] + ], + 'global_namespace_import' => [ + 'import_classes' => true, ], 'heredoc_to_nowdoc' => true, - 'no_extra_consecutive_blank_lines' => [ - 'break', - 'continue', - 'extra', - 'return', - 'throw', - 'use', - 'parenthesis_brace_block', - 'square_brace_block', - 'curly_brace_block' + 'no_extra_blank_lines' => [ + 'tokens' => [ + 'break', + 'continue', + 'extra', + 'return', + 'throw', + 'use', + 'parenthesis_brace_block', + 'square_brace_block', + 'curly_brace_block', + ], ], - 'no_short_echo_tag' => true, 'no_unreachable_default_argument_value' => true, 'no_useless_else' => true, 'no_useless_return' => true, 'ordered_class_elements' => true, 'ordered_imports' => true, - 'php_unit_strict' => true, +// 'php_unit_strict' => true, +// Disabled as some tests fail after moving AssertEquals to AssertSame +// \todo enable again after determining why that assert fails. 'phpdoc_add_missing_param_annotation' => true, 'phpdoc_order' => true, 'semicolon_after_instruction' => true, @@ -46,7 +57,6 @@ 'strict_param' => true, 'concat_space' => ['spacing' => 'one'], ]) - ->setFinder($finder) -; + ->setFinder($finder); return $config; diff --git a/.travis.yml b/.travis.yml index 92084d23d7..ae2cb69f6d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -31,7 +31,7 @@ before_install: - sudo mysql -u root -e 'FLUSH PRIVILEGES;' install: - - yarn install --frozen-lock + - bun i --frozen-lockfile - composer install --no-interaction --ignore-platform-reqs --no-scripts script: diff --git a/Dockerfile b/Dockerfile index 87d90ff8fb..fb6d217bbe 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,112 +1,56 @@ # the different stages of this Dockerfile are meant to be built into separate images -# https://docs.docker.com/develop/develop-images/multistage-build/#stop-at-a-specific-build-stage -# https://docs.docker.com/compose/compose-file/#target - - # https://docs.docker.com/engine/reference/builder/#understand-how-arg-and-from-interact -ARG PHP_VERSION=7.4.28 -ARG NGINX_VERSION=1.17 +ARG PHP_VERSION=8.4 +ARG FRANKENPHP_VERSION=1.11 -# "php" stage -FROM php:${PHP_VERSION}-fpm-alpine3.15 AS bewelcome_php +# Shared PHP/FrankenPHP runtime base. +FROM dunglas/frankenphp:${FRANKENPHP_VERSION}-php${PHP_VERSION}-alpine AS bewelcome_php_base -# persistent / runtime deps RUN apk add --no-cache \ acl \ freetype \ libjpeg-turbo \ libpng \ fcgi \ - file \ gettext \ - git \ - openssh-client \ - python3 \ ; -ARG APCU_VERSION=5.1.18 RUN set -eux; \ - apk add --no-cache --virtual .build-deps \ - $PHPIZE_DEPS \ - freetype-dev \ - icu-dev \ - libjpeg-turbo-dev \ - libpng-dev \ - libxslt-dev \ - libzip-dev \ - zlib-dev \ - ; \ - \ - docker-php-ext-configure zip; \ - docker-php-ext-configure gd --with-freetype --with-jpeg=/usr/include/ --enable-gd; \ - docker-php-ext-install -j$(nproc) \ + install-php-extensions \ + apcu \ + curl \ + gmp \ intl \ gd \ mysqli \ pcntl \ pdo_mysql \ - xmlrpc \ xsl \ zip \ - exif \ - ; \ - pecl install \ - apcu-${APCU_VERSION} \ - ; \ - pecl clear-cache; \ - docker-php-ext-enable \ - apcu \ + exif \ opcache \ - ; \ - \ - runDeps="$( \ - scanelf --needed --nobanner --format '%n#p' --recursive /usr/local/lib/php/extensions \ - | tr ',' '\n' \ - | sort -u \ - | awk 'system("[ -e /usr/local/lib/" $1 " ]") == 0 { next } { print "so:" $1 }' \ - )"; \ - apk add --no-cache --virtual .phpexts-rundeps $runDeps; \ - \ - apk del .build-deps - -# https://github.com/nodejs/docker-node/issues/1126 -RUN set -eux; \ - echo "@edge http://nl.alpinelinux.org/alpine/edge/main" >> /etc/apk/repositories; \ - apk add --no-cache yarn@edge - -RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer -RUN export PATH="/usr/local/bin:$PATH" + ; -RUN ln -s $PHP_INI_DIR/php.ini-production $PHP_INI_DIR/php.ini COPY docker/php/conf.d/bewelcome.prod.ini $PHP_INI_DIR/conf.d/bewelcome.ini RUN set -eux; \ - { \ - echo '[www]'; \ - echo 'ping.path = /ping'; \ - } | tee /usr/local/etc/php-fpm.d/docker-healthcheck.conf - -# https://getcomposer.org/doc/03-cli.md#composer-allow-superuser -ENV COMPOSER_ALLOW_SUPERUSER=1 -# install Symfony Flex globally to speed up download of Composer packages (parallelized prefetching) -RUN set -eux; \ - composer global config --no-plugins allow-plugins.symfony/flex true; \ - composer global require "symfony/flex" --prefer-dist --no-progress --classmap-authoritative; \ - composer clear-cache -ENV PATH="${PATH}:/root/.composer/vendor/bin" + ln -sf "$PHP_INI_DIR/php.ini-production" "$PHP_INI_DIR/php.ini"; \ + sed -i -e "s/^ *memory_limit.*/memory_limit = 4G/g" "$PHP_INI_DIR/php.ini" WORKDIR /srv/bewelcome -# build for production -ARG APP_ENV=prod -# copy only specifically what we need for production +# Source snapshot reused by build and development stages. +FROM bewelcome_php_base AS bewelcome_source + COPY assets assets/ COPY bin bin/ COPY build build/ COPY config config/ +COPY docker docker/ COPY lib lib/ +COPY Migrations Migrations/ COPY Mike42 Mike42/ COPY modules modules/ COPY pthacks pthacks/ @@ -118,62 +62,143 @@ COPY tools tools/ COPY translations translations/ COPY routes.php ./ COPY rox_docker.ini /srv/bewelcome/rox_local.ini +COPY composer.json composer.lock symfony.lock ./ +COPY package.json bun.lock webpack.config.js postcss.config.js tailwind.config.js tsconfig.json ./ +COPY .env ./ + + +# Build PHP dependencies and optimized autoload outside the final runtime. +FROM bewelcome_php_base AS bewelcome_vendor_deps + +RUN set -eux; \ + apk add --no-cache curl; \ + curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer -# prevent the reinstallation of vendors at every changes in the source code COPY composer.json composer.lock symfony.lock ./ + RUN set -eux; \ - composer install --prefer-dist --no-dev --no-scripts --no-progress --no-suggest; \ + COMPOSER_ALLOW_SUPERUSER=1 composer install --prefer-dist --no-dev --no-scripts --no-progress --no-autoloader; \ composer clear-cache -# prevent the reinstallation of node_modules at every changes in the source code -COPY package.json yarn.lock webpack.config.js postcss.config.js tailwind.config.js ./ +FROM bewelcome_vendor_deps AS bewelcome_vendor + +COPY --from=bewelcome_source /srv/bewelcome ./ + RUN set -eux; \ - yarn install --frozen-lock; \ - yarn encore production --mode=production + COMPOSER_ALLOW_SUPERUSER=1 composer dump-autoload --classmap-authoritative --no-dev; \ + COMPOSER_ALLOW_SUPERUSER=1 composer dump-env prod; \ + composer clear-cache; \ + rm -rf /root/.composer /root/.cache/composer -# do not use .env files in production -COPY .env ./ -RUN composer dump-env prod; \ - rm .env + +# Build frontend assets outside the final runtime. +FROM bewelcome_php_base AS bewelcome_bun RUN set -eux; \ - mkdir -p var/cache var/log; \ - composer dump-autoload --classmap-authoritative --no-dev; \ - chmod +x bin/console; sync -VOLUME /srv/bewelcome/var -VOLUME /srv/bewelcome/data + apk add --no-cache bash curl git openssh-client unzip; \ + curl -fsSL https://bun.sh/install -o bun-install.sh; \ + bash bun-install.sh; \ + ln -s /root/.bun/bin/bun /usr/local/bin/bun; \ + rm bun-install.sh -COPY docker/php/docker-healthcheck.sh /usr/local/bin/docker-healthcheck -RUN chmod +x /usr/local/bin/docker-healthcheck +FROM bewelcome_bun AS bewelcome_assets -HEALTHCHECK --interval=10s --timeout=3s --retries=3 CMD ["docker-healthcheck"] +COPY package.json bun.lock ./ +COPY --from=bewelcome_vendor_deps /srv/bewelcome/vendor vendor/ -COPY docker/php/docker-entrypoint.sh /usr/local/bin/docker-entrypoint -RUN chmod +x /usr/local/bin/docker-entrypoint +RUN set -eux; \ + bun i --frozen-lockfile -ENTRYPOINT ["docker-entrypoint"] -CMD ["php-fpm"] +COPY --from=bewelcome_source /srv/bewelcome ./ +# Stub var/translations so encore can compile (entrypoint cache warmup fills real translations at runtime). +RUN mkdir -p var/translations && printf '%s\n' \ + '// auto-generated stub for image build' \ + 'export const localeFallbacks = {"en":"en"};' \ + 'export const messages = {};' \ + > var/translations/index.js -# "nginx" stage -# depends on the "php" stage above -FROM nginx:${NGINX_VERSION}-alpine AS bewelcome_nginx +RUN set -eux; \ + bun encore production --mode=production + + +# Self-contained production image. +FROM bewelcome_php_base AS bewelcome_php + +ARG APP_VERSION=unknown +ARG APP_VERSION_TIMESTAMP= + +ENV APP_ENV=prod + +COPY --from=bewelcome_source /srv/bewelcome/bin bin/ +COPY --from=bewelcome_source /srv/bewelcome/build build/ +COPY --from=bewelcome_source /srv/bewelcome/config config/ +COPY --from=bewelcome_source /srv/bewelcome/lib lib/ +COPY --from=bewelcome_source /srv/bewelcome/Migrations Migrations/ +COPY --from=bewelcome_source /srv/bewelcome/Mike42 Mike42/ +COPY --from=bewelcome_source /srv/bewelcome/modules modules/ +COPY --from=bewelcome_source /srv/bewelcome/pthacks pthacks/ +COPY --from=bewelcome_source /srv/bewelcome/public public/ +COPY --from=bewelcome_source /srv/bewelcome/roxlauncher roxlauncher/ +COPY --from=bewelcome_source /srv/bewelcome/src src/ +COPY --from=bewelcome_source /srv/bewelcome/templates templates/ +COPY --from=bewelcome_source /srv/bewelcome/tools tools/ +COPY --from=bewelcome_source /srv/bewelcome/translations translations/ +COPY --from=bewelcome_source /srv/bewelcome/routes.php ./ +COPY --from=bewelcome_source /srv/bewelcome/rox_local.ini ./ +COPY --from=bewelcome_source /srv/bewelcome/composer.json ./ +COPY --from=bewelcome_vendor /srv/bewelcome/vendor vendor/ +COPY --from=bewelcome_vendor /srv/bewelcome/.env.local.php ./ +COPY --from=bewelcome_assets /srv/bewelcome/public/build public/build/ +COPY --from=bewelcome_assets /srv/bewelcome/public/main.js /srv/bewelcome/public/service-worker.js public/ -COPY docker/nginx/conf.d/default.conf /etc/nginx/conf.d/default.conf +RUN set -eux; \ + printf '%s\n' "$APP_VERSION" > VERSION; \ + if [ -n "$APP_VERSION_TIMESTAMP" ]; then php -r 'touch("VERSION", (int) $argv[1]);' "$APP_VERSION_TIMESTAMP"; fi; \ + mkdir -p var/cache var/log data/user/avatars data/gallery/member upload/images public/bundles /config /data; \ + find public -name '*.map' -type f -delete; \ + chown -R www-data:www-data var data upload public/bundles /config /data; \ + chmod +x bin/console; \ + apk upgrade --no-cache; \ + sync +VOLUME /srv/bewelcome/var +VOLUME /srv/bewelcome/data -WORKDIR /srv/bewelcome/public +COPY docker/frankenphp/Caddyfile /etc/caddy/Caddyfile +COPY docker/php/docker-entrypoint.sh /usr/local/bin/docker-entrypoint +RUN chmod +x /usr/local/bin/docker-entrypoint + +USER www-data -COPY --from=bewelcome_php /srv/bewelcome/public ./ +HEALTHCHECK --interval=10s --timeout=3s --retries=3 CMD ["frankenphp", "php-cli", "-r", "echo 1;"] +ENTRYPOINT ["docker-entrypoint"] +CMD ["frankenphp", "run", "--config", "/etc/caddy/Caddyfile"] -# "php" dev stage -# depends on the "php" stage above -FROM bewelcome_php AS bewelcome_php_dev -# build for production -ARG NODE_ENV=production +# Local development image. The repository is bind-mounted over /srv/bewelcome. +FROM bewelcome_source AS bewelcome_php_dev + +ENV APP_ENV=dev +ENV COMPOSER_ALLOW_SUPERUSER=1 RUN set -eux; \ - apk add --no-cache \ - make \ - mysql-client + apk add --no-cache bash curl git make mariadb-client openssh-client python3 unzip; \ + curl -fsSL https://bun.sh/install -o bun-install.sh; \ + bash bun-install.sh; \ + ln -s /root/.bun/bin/bun /usr/local/bin/bun; \ + rm bun-install.sh; \ + curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer; \ + chmod a+w "$PHP_INI_DIR"; \ + mkdir -p vendor var/cache var/log; \ + chmod -R a+w vendor; \ + chmod -R 777 var + +COPY docker/frankenphp/Caddyfile /etc/caddy/Caddyfile +COPY docker/php/docker-entrypoint.sh /usr/local/bin/docker-entrypoint +RUN chmod +x /usr/local/bin/docker-entrypoint + +HEALTHCHECK --interval=10s --timeout=3s --retries=3 CMD ["frankenphp", "php-cli", "-r", "echo 1;"] + +ENTRYPOINT ["docker-entrypoint"] +CMD ["frankenphp", "run", "--config", "/etc/caddy/Caddyfile"] diff --git a/INSTALL.md b/INSTALL.md index 4fdcad6ef6..8d237c21c4 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -10,9 +10,7 @@ 2. You can choose to install using A) Docker and Docker Compose or B) Installation step by step of BW-Rox (GNU/Linux) (see below) -## A) Install using Docker and Docker Compose - -The docker configuration is still in-progress, and is currently missing the setup of the sphinx search functionality (essential for using all of the search functionality in the app). Until configuration is complete, local installation is recommended. +## Install using Docker and Docker Compose ### Requirements @@ -33,7 +31,7 @@ The docker configuration is still in-progress, and is currently missing the setu ```bash $ make install root=1 ``` - +
Troubleshooting @@ -61,6 +59,10 @@ Wait a few minutes for containers to build and start (it might take awhile). Pro Please read [Useful hints](#useful-hints) section below. +### Stage / production deployment + +Production images bake in Composer `vendor/` and Webpack `public/build/` at build time — no host-side `bun encore` step. See [docker/DEPLOYMENT.md](docker/DEPLOYMENT.md). + ## B) Installation step by step of BW-Rox (GNU/Linux) These steps have been tested on Debian/Ubuntu based systems. Commands, @@ -77,7 +79,7 @@ using a browser or use curl _url_ > _filename_. * [PHP GD lib enabled](https://www.php.net/manual/en/image.installation.php) * PHP extensions: mbstring, xml, fileinfo, intl, xsl, xmlrpc (see composer.json) * note that the xml extension does not need to be installed on Windows as it is [installed by default](https://www.php.net/manual/en/xml.installation.php) -* MariaDB >=10.1 +* MariaDB >=10.6 * [symfony command line interface](https://symfony.com/download) (download/setup) * SMTP server for email features * [Composer](https://www.getcomposer.org) Version 2 (installed globally) @@ -92,7 +94,7 @@ using a browser or use curl _url_ > _filename_. ```bash $ composer install - $ yarn install --frozen-lock + $ bun i --frozen-lockfile ``` 2. Initialize the database. diff --git a/Makefile b/Makefile index 89ebfeb9fc..90d02e6ce7 100644 --- a/Makefile +++ b/Makefile @@ -12,18 +12,17 @@ TIME_STAMP := $(shell git log -n 1 --format=%aI) all: phpci -phpci: phpcpd phploc phpmd php-code-sniffer phpunit infection behat version +phpci: phpcpd phploc phpstan php-code-sniffer php-cs-fixer phpunit infection int-test version yaml-lint doctrine twig install: git rev-parse --short HEAD > VERSION test -f docker-compose.override.yml || cp docker-compose.override.yml.dist docker-compose.override.yml - curl https://downloads.bewelcome.org/for_developers/rox_test_db/languages.sql.bz2 -o ./docker/db/languages.sql.bz2 - curl https://downloads.bewelcome.org/for_developers/rox_test_db/words.sql.bz2 -o ./docker/db/words.sql.bz2 - bunzip2 --force ./docker/db/languages.sql.bz2 ./docker/db/words.sql.bz2 + bzip2 -ckd docker/languages.sql.bz2 > docker/db/languages.sql + bzip2 -ckd docker/words.sql.bz2 > docker/db/words.sql ifdef root - sudo docker-compose up -d + sudo docker compose up -d else - docker-compose up -d + docker compose up -d endif install-geonames: @@ -34,31 +33,31 @@ install-geonames: unzip docker/db/alternateNames.zip -d docker/db/ rm docker/db/*.zip ifdef root - sudo docker-compose exec php sh -c "mysql bewelcome -u bewelcome -pbewelcome -h db < import.sql" + sudo docker compose exec php sh -c "mysql bewelcome -u bewelcome -pbewelcome -h db < import.sql" else - docker-compose exec php sh -c "mysql bewelcome -u bewelcome -pbewelcome -h db < import.sql" + docker compose exec php sh -c "mysql bewelcome -u bewelcome -pbewelcome -h db < import.sql" endif phpcsfix: "./vendor/bin/phpcbf" $(SRC_DIR) "./vendor/bin/php-cs-fixer" fix -v -deploy: composer yarn encore assets +deploy: composer bun encore assets composer: composer install --prefer-dist --no-progress --no-suggest --no-interaction --no-scripts -yarn: - yarn install +bun: + bun i encore: - yarn encore production + bun encore production assets: php bin/console assets:install --env=prod build: - yarn encore dev + bun encore dev php bin/console assets:install phpdox: phploc phpmd php-code-sniffer phpunit @@ -68,7 +67,7 @@ mkdocs: mkdocs build phpcpd: - "./vendor/bin/phpcpd" $(SRC_DIR_NO_TESTS) --exclude=src/Entity + "./vendor/bin/phpcpd" $(SRC_DIR_NO_TESTS) --exclude=src/Entity --exclude=src/Repository phploc: "./vendor/bin/phploc" --log-xml=phploc.xml $(SRC_DIR) @@ -76,6 +75,9 @@ phploc: phpmd: "./vendor/bin/phpmd" $(SRC_DIR_COMMA) text phpmd.xml +phpstan: + "./vendor/bin/phpstan" analyze + php-cs-fixer: "./vendor/bin/php-cs-fixer" fix -v --diff --dry-run @@ -83,16 +85,20 @@ php-code-sniffer: "./vendor/bin/phpcs" --colors --warning-severity=Error phpunit: - phpdbg -qrr bin/phpunit --coverage-xml=build/logs/phpunit/coverage-xml --coverage-clover=build/logs/phpunit/clover.xml --log-junit=build/logs/phpunit/junit.xml --colors=never + "./bin/phpunit" --coverage-xml=build/logs/phpunit/coverage-xml --coverage-clover=build/logs/phpunit/clover.xml --log-junit=build/logs/phpunit/junit.xml --colors=never --order-by=random --exclude-group=integration + +int-test: + "./bin/phpunit" --log-junit=build/logs/phpunit/junit.xml --colors=never --order-by=random --group=integration infection: phpunit - "./vendor/bin/infection" --only-covered --coverage=build/logs/phpunit --min-covered-msi=85 --threads=30 -behat: encore - bin/console doctrine:database:create --env=test --if-not-exists - bin/console doctrine:schema:create --env=test - bin/console hautelook:fixtures:load --env=test --no-interaction - vendor/bin/behat --colors --tags='~@wip' + "./vendor/bin/infection" --skip-initial-tests --coverage=build/logs/phpunit --min-covered-msi=80 --threads=2 + +#behat: encore +# bin/console doctrine:database:create --env=test --if-not-exists +# bin/console doctrine:schema:create --env=test +# bin/console hautelook:fixtures:load --env=test --no-interaction +# vendor/bin/behat --colors --tags='~@wip' phpmetrics: "./vendor/bin/phpmetrics" --exclude=src/App/Entity --report-violations=phpmetrics.xml $(SRC_DIR_COMMA) @@ -100,3 +106,12 @@ phpmetrics: version: git rev-parse --short HEAD > VERSION touch -d $(TIME_STAMP) VERSION + +yaml-lint: + bin/console lint:yaml --parse-tags config fixtures + +doctrine: + bin/console doctrine:schema:validate --skip-sync + +twig: + bin/console lint:twig diff --git a/src/Migrations/.gitignore b/Migrations/.gitignore similarity index 100% rename from src/Migrations/.gitignore rename to Migrations/.gitignore diff --git a/src/Migrations/Version20200307133359.php b/Migrations/Version20200307133359.php similarity index 97% rename from src/Migrations/Version20200307133359.php rename to Migrations/Version20200307133359.php index 67bd4e81dd..f9dd8765a7 100644 --- a/src/Migrations/Version20200307133359.php +++ b/Migrations/Version20200307133359.php @@ -2,18 +2,20 @@ declare(strict_types=1); -namespace App\Migrations; +namespace DoctrineMigrations; use Doctrine\DBAL\Schema\Schema; use Doctrine\Migrations\AbstractMigration; +use Override; /** * Auto-generated Migration: Please modify to your needs! * - * @SuppressWarnings(PHPMD) + * @SuppressWarnings("PHPMD") */ final class Version20200307133359 extends AbstractMigration { + #[Override] public function getDescription(): string { return 'Add the functions needed for message threads'; @@ -116,6 +118,7 @@ public function up(Schema $schema): void '); } + #[Override] public function down(Schema $schema): void { $this->addSql(' diff --git a/src/Migrations/Version20200522172912.php b/Migrations/Version20200522172912.php similarity index 89% rename from src/Migrations/Version20200522172912.php rename to Migrations/Version20200522172912.php index a3e4e010e2..cb80936775 100644 --- a/src/Migrations/Version20200522172912.php +++ b/Migrations/Version20200522172912.php @@ -2,18 +2,20 @@ declare(strict_types=1); -namespace App\Migrations; +namespace DoctrineMigrations; use Doctrine\DBAL\Schema\Schema; use Doctrine\Migrations\AbstractMigration; +use Override; /** * Auto-generated Migration: Please modify to your needs! * - * @SuppressWarnings(PHPMD) + * @SuppressWarnings("PHPMD") */ final class Version20200522172912 extends AbstractMigration { + #[Override] public function getDescription(): string { return 'Add forum_trads view'; @@ -28,7 +30,7 @@ public function up(Schema $schema): void VIEW `forum_trads` AS SELECT `translations`.`id` AS `id`, - `translations`.`IdLanguage` AS `IdLanguage`, + `translations`.`ShortCode` AS `ShortCode`, `translations`.`IdOwner` AS `IdOwner`, `translations`.`IdTrad` AS `IdTrad`, `translations`.`IdTranslator` AS `IdTranslator`, @@ -43,6 +45,7 @@ public function up(Schema $schema): void '); } + #[Override] public function down(Schema $schema): void { // this down() migration is auto-generated, please modify it to your needs diff --git a/Migrations/Version20260624120000.php b/Migrations/Version20260624120000.php new file mode 100644 index 0000000000..8ecec3b96a --- /dev/null +++ b/Migrations/Version20260624120000.php @@ -0,0 +1,118 @@ +addSql(' + CREATE TABLE IF NOT EXISTS browser_push_subscription ( + id INT AUTO_INCREMENT NOT NULL, + member_id INT NOT NULL, + endpoint_hash CHAR(64) NOT NULL, + endpoint LONGTEXT NOT NULL, + public_key LONGTEXT NOT NULL, + auth_token VARCHAR(255) NOT NULL, + content_encoding VARCHAR(32) DEFAULT NULL, + user_agent VARCHAR(255) DEFAULT NULL, + last_seen DATETIME DEFAULT NULL, + last_error VARCHAR(255) DEFAULT NULL, + created DATETIME NOT NULL, + updated DATETIME DEFAULT NULL, + UNIQUE INDEX uniq_browser_push_subscription_endpoint_hash (endpoint_hash), + INDEX idx_browser_push_subscription_member (member_id), + CONSTRAINT fk_browser_push_subscription_member + FOREIGN KEY (member_id) REFERENCES member (id) ON DELETE CASCADE, + PRIMARY KEY(id) + ) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB + '); + + $this->addSql(' + CREATE TABLE IF NOT EXISTS browser_push_notification ( + id INT AUTO_INCREMENT NOT NULL, + member_id INT NOT NULL, + status VARCHAR(32) NOT NULL, + type VARCHAR(32) NOT NULL, + sender_username VARCHAR(255) DEFAULT NULL, + url VARCHAR(2048) NOT NULL, + last_error VARCHAR(255) DEFAULT NULL, + attempts INT DEFAULT 0 NOT NULL, + created DATETIME NOT NULL, + updated DATETIME DEFAULT NULL, + INDEX idx_browser_push_notification_status_created (status, created, id), + INDEX idx_browser_push_notification_member_status (member_id, status, id), + CONSTRAINT fk_browser_push_notification_member + FOREIGN KEY (member_id) REFERENCES member (id) ON DELETE CASCADE, + PRIMARY KEY(id) + ) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB + '); + + $this->addSql(' + CREATE TABLE IF NOT EXISTS browser_push_notification_delivery ( + id INT AUTO_INCREMENT NOT NULL, + notification_id INT NOT NULL, + subscription_id INT DEFAULT NULL, + status VARCHAR(32) NOT NULL, + attempts INT DEFAULT 0 NOT NULL, + last_error VARCHAR(255) DEFAULT NULL, + created DATETIME NOT NULL, + updated DATETIME DEFAULT NULL, + INDEX idx_browser_push_notification_delivery_notification_status (notification_id, status), + INDEX idx_browser_push_notification_delivery_subscription (subscription_id), + CONSTRAINT fk_browser_push_notification_delivery_notification + FOREIGN KEY (notification_id) REFERENCES browser_push_notification (id) ON DELETE CASCADE, + CONSTRAINT fk_browser_push_notification_delivery_subscription + FOREIGN KEY (subscription_id) REFERENCES browser_push_subscription (id) ON DELETE SET NULL, + PRIMARY KEY(id) + ) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB + '); + + $this->addSql(" + INSERT INTO preferences ( + position, + codeName, + codeDescription, + Description, + created, + DefaultValue, + PossibleValues, + Status + ) VALUES ( + 56, + 'PreferenceBrowserNotifications', + 'BrowserNotificationsDesc', + 'This preference stores if the member wants browser push notifications.', + CURRENT_TIMESTAMP, + 'No', + 'No;OpenOnly;Always', + 'Normal' + ) + "); + } + + #[Override] + public function down(Schema $schema): void + { + $this->addSql(" + DELETE mp + FROM memberspreferences mp + INNER JOIN preferences p ON p.id = mp.IdPreference + WHERE p.codeName = 'PreferenceBrowserNotifications' + "); + $this->addSql("DELETE FROM preferences WHERE codeName = 'PreferenceBrowserNotifications'"); + $this->addSql('DROP TABLE browser_push_notification_delivery'); + $this->addSql('DROP TABLE browser_push_notification'); + $this->addSql('DROP TABLE browser_push_subscription'); + } +} diff --git a/Migrations/Version20260626100000.php b/Migrations/Version20260626100000.php new file mode 100644 index 0000000000..bead63affa --- /dev/null +++ b/Migrations/Version20260626100000.php @@ -0,0 +1,32 @@ +addSql('CREATE TABLE IF NOT EXISTS member_subtrip_hidden (id INT AUTO_INCREMENT NOT NULL, member_id INT NOT NULL, subtrip_id INT NOT NULL, created DATETIME NOT NULL, INDEX IDX_B1EC0277597D3FE (member_id), INDEX IDX_B1EC027F2BD7DD7 (subtrip_id), UNIQUE INDEX member_subtrip_hidden_unique (member_id, subtrip_id), CONSTRAINT FK_B1EC0277597D3FE FOREIGN KEY (member_id) REFERENCES member (id) ON DELETE CASCADE, CONSTRAINT FK_B1EC027F2BD7DD7 FOREIGN KEY (subtrip_id) REFERENCES sub_trips (id) ON DELETE CASCADE, PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB'); + $this->addSql('CREATE TABLE IF NOT EXISTS member_subtrip_notification_sent (id INT AUTO_INCREMENT NOT NULL, member_id INT NOT NULL, subtrip_id INT NOT NULL, created DATETIME NOT NULL, INDEX IDX_9D9311917597D3FE (member_id), INDEX IDX_9D931191F2BD7DD7 (subtrip_id), UNIQUE INDEX member_subtrip_notification_sent_unique (member_id, subtrip_id), CONSTRAINT FK_9D9311917597D3FE FOREIGN KEY (member_id) REFERENCES member (id) ON DELETE CASCADE, CONSTRAINT FK_9D931191F2BD7DD7 FOREIGN KEY (subtrip_id) REFERENCES sub_trips (id) ON DELETE CASCADE, PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB'); + $this->addSql("INSERT INTO preferences (position, codeName, codeDescription, Description, created, DefaultValue, PossibleValues, Status) SELECT 65, 'TripsNotifications', 'trips.notifications', 'How often the member wants notifications for trips in their area', NOW(), 'Never', 'Never;Immediately;Daily;Weekly;Monthly', 'Normal' WHERE NOT EXISTS (SELECT 1 FROM preferences WHERE codeName = 'TripsNotifications')"); + } + + #[Override] + public function down(Schema $schema): void + { + $this->addSql("DELETE mp FROM memberspreferences mp INNER JOIN preferences p ON p.id = mp.IdPreference WHERE p.codeName = 'TripsNotifications'"); + $this->addSql("DELETE FROM preferences WHERE codeName = 'TripsNotifications'"); + $this->addSql('DROP TABLE IF EXISTS member_subtrip_notification_sent'); + $this->addSql('DROP TABLE IF EXISTS member_subtrip_hidden'); + } +} diff --git a/Migrations/Version20260713152915.php b/Migrations/Version20260713152915.php new file mode 100644 index 0000000000..36b1001dc4 --- /dev/null +++ b/Migrations/Version20260713152915.php @@ -0,0 +1,29 @@ +addSql('DELETE mg FROM membersgroups mg LEFT JOIN `groups` g ON g.id = mg.IdGroup WHERE g.id IS NULL'); + } + + #[Override] + public function down(Schema $schema): void + { + $this->throwIrreversibleMigrationException('Deleted orphaned group memberships cannot be restored.'); + } +} diff --git a/Migrations/Version20260714110000.php b/Migrations/Version20260714110000.php new file mode 100644 index 0000000000..31d677fe29 --- /dev/null +++ b/Migrations/Version20260714110000.php @@ -0,0 +1,27 @@ +addSql('ALTER TABLE posts_notificationqueue ADD COLUMN IF NOT EXISTS MessageId VARCHAR(255) DEFAULT NULL, ADD UNIQUE INDEX IF NOT EXISTS posts_notificationqueue_message_id_unique (MessageId)'); + } + + #[Override] + public function down(Schema $schema): void + { + $this->addSql('ALTER TABLE posts_notificationqueue DROP INDEX posts_notificationqueue_message_id_unique, DROP MessageId'); + } +} diff --git a/Migrations/Version20260729120000.php b/Migrations/Version20260729120000.php new file mode 100644 index 0000000000..2d57c5eaa2 --- /dev/null +++ b/Migrations/Version20260729120000.php @@ -0,0 +1,36 @@ +addSql(' + CREATE TABLE IF NOT EXISTS rememberme_token ( + series VARCHAR(88) NOT NULL, + value VARCHAR(88) NOT NULL, + lastUsed DATETIME NOT NULL, + class VARCHAR(100) DEFAULT \'\' NOT NULL, + username VARCHAR(200) NOT NULL, + PRIMARY KEY(series) + ) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB + '); + } + + #[Override] + public function down(Schema $schema): void + { + $this->addSql('DROP TABLE IF EXISTS rememberme_token'); + } +} diff --git a/Migrations/Version20260801120000.php b/Migrations/Version20260801120000.php new file mode 100644 index 0000000000..ee8ee7a00a --- /dev/null +++ b/Migrations/Version20260801120000.php @@ -0,0 +1,40 @@ +addSql('ALTER TABLE comment MODIFY COLUMN relations VARCHAR(87) CHARACTER SET utf8mb4 COLLATE utf8mb4_uca1400_ai_ci NOT NULL'); + $this->addSql('ALTER TABLE comments MODIFY COLUMN Relations VARCHAR(87) CHARACTER SET utf8mb4 COLLATE utf8mb4_uca1400_ai_ci NOT NULL'); + $this->addSql('ALTER TABLE member MODIFY COLUMN StandardOffers VARCHAR(17) CHARACTER SET utf8mb4 COLLATE utf8mb4_uca1400_ai_ci DEFAULT NULL'); + $this->addSql('ALTER TABLE member MODIFY COLUMN Restrictions VARCHAR(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_uca1400_ai_ci DEFAULT NULL'); + $this->addSql('ALTER TABLE messages MODIFY COLUMN DeleteRequest VARCHAR(57) CHARACTER SET utf8mb4 COLLATE utf8mb4_uca1400_ai_ci DEFAULT NULL'); + $this->addSql('ALTER TABLE messages MODIFY COLUMN SpamInfo VARCHAR(71) CHARACTER SET utf8mb4 COLLATE utf8mb4_uca1400_ai_ci NOT NULL'); + $this->addSql('ALTER TABLE sub_trips MODIFY COLUMN options VARCHAR(34) CHARACTER SET utf8mb4 COLLATE utf8mb4_uca1400_ai_ci DEFAULT NULL'); + } + + #[Override] + public function down(Schema $schema): void + { + $this->addSql('ALTER TABLE comment MODIFY COLUMN relations SET(\'was_my_guest\', \'hosted_me\', \'only_once\', \'family\', \'close_friend\', \'travelled_Together\', \'friends\', \'chatted\') CHARACTER SET utf8mb4 COLLATE utf8mb4_uca1400_ai_ci NOT NULL'); + $this->addSql('ALTER TABLE comments MODIFY COLUMN Relations SET(\'was_my_guest\', \'hosted_me\', \'only_once\', \'family\', \'close_friend\', \'travelled_Together\', \'friends\', \'chatted\') CHARACTER SET utf8mb4 COLLATE utf8mb4_uca1400_ai_ci NOT NULL'); + $this->addSql('ALTER TABLE member MODIFY COLUMN StandardOffers SET(\'dinner\', \'guidedtour\') CHARACTER SET utf8mb4 COLLATE utf8mb4_uca1400_ai_ci DEFAULT NULL'); + $this->addSql('ALTER TABLE member MODIFY COLUMN Restrictions SET(\'no.alcohol\', \'no.drugs\', \'no.smoking\') CHARACTER SET utf8mb4 COLLATE utf8mb4_uca1400_ai_ci DEFAULT NULL'); + $this->addSql('ALTER TABLE messages MODIFY COLUMN DeleteRequest SET(\'senderdeleted\', \'receiverdeleted\', \'senderpurged\', \'receiverpurged\') CHARACTER SET utf8mb4 COLLATE utf8mb4_uca1400_ai_ci DEFAULT NULL'); + $this->addSql('ALTER TABLE messages MODIFY COLUMN SpamInfo SET(\'NotSpam\', \'SpamBlkWord\', \'SpamSayMember\', \'SpamSayChecker\', \'ProcessedBySpamManager\') CHARACTER SET utf8mb4 COLLATE utf8mb4_uca1400_ai_ci NOT NULL'); + $this->addSql('ALTER TABLE sub_trips MODIFY COLUMN options SET(\'Private\', \'MeetLocals\', \'LookingForHosts\') CHARACTER SET utf8mb4 COLLATE utf8mb4_uca1400_ai_ci DEFAULT NULL'); + } +} \ No newline at end of file diff --git a/Migrations/Version20260801130000.php b/Migrations/Version20260801130000.php new file mode 100644 index 0000000000..d8ccfaaaa4 --- /dev/null +++ b/Migrations/Version20260801130000.php @@ -0,0 +1,77 @@ +addSql('ALTER TABLE comment MODIFY COLUMN admin_action VARCHAR(21) CHARACTER SET utf8mb4 COLLATE utf8mb4_uca1400_ai_ci NOT NULL'); + $this->addSql('ALTER TABLE comment MODIFY COLUMN quality VARCHAR(8) CHARACTER SET utf8mb4 COLLATE utf8mb4_uca1400_ai_ci NOT NULL'); + $this->addSql('ALTER TABLE comments MODIFY COLUMN AdminAction VARCHAR(21) CHARACTER SET utf8mb4 COLLATE utf8mb4_uca1400_ai_ci NOT NULL'); + $this->addSql('ALTER TABLE comments MODIFY COLUMN Quality VARCHAR(8) CHARACTER SET utf8mb4 COLLATE utf8mb4_uca1400_ai_ci NOT NULL'); + $this->addSql('ALTER TABLE forum_post MODIFY COLUMN OwnerCanStillEdit VARCHAR(3) CHARACTER SET utf8mb4 COLLATE utf8mb4_uca1400_ai_ci NOT NULL'); + $this->addSql('ALTER TABLE forum_post MODIFY COLUMN PostDeleted VARCHAR(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_uca1400_ai_ci NOT NULL'); + $this->addSql('ALTER TABLE forum_post MODIFY COLUMN PostVisibility VARCHAR(13) CHARACTER SET utf8mb4 COLLATE utf8mb4_uca1400_ai_ci NOT NULL'); + $this->addSql('ALTER TABLE forum_thread MODIFY COLUMN ThreadDeleted VARCHAR(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_uca1400_ai_ci NOT NULL'); + $this->addSql('ALTER TABLE forum_thread MODIFY COLUMN ThreadVisibility VARCHAR(13) CHARACTER SET utf8mb4 COLLATE utf8mb4_uca1400_ai_ci NOT NULL'); + $this->addSql('ALTER TABLE forum_thread MODIFY COLUMN WhoCanReply VARCHAR(16) CHARACTER SET utf8mb4 COLLATE utf8mb4_uca1400_ai_ci NOT NULL'); + $this->addSql('ALTER TABLE groups MODIFY COLUMN Type VARCHAR(14) CHARACTER SET utf8mb4 COLLATE utf8mb4_uca1400_ai_ci NOT NULL'); + $this->addSql('ALTER TABLE member MODIFY COLUMN Accommodation VARCHAR(3) CHARACTER SET utf8mb4 COLLATE utf8mb4_uca1400_ai_ci DEFAULT NULL'); + $this->addSql('ALTER TABLE member MODIFY COLUMN Gender VARCHAR(6) CHARACTER SET utf8mb4 COLLATE utf8mb4_uca1400_ai_ci NOT NULL'); + $this->addSql('ALTER TABLE member MODIFY COLUMN Status VARCHAR(16) CHARACTER SET utf8mb4 COLLATE utf8mb4_uca1400_ai_ci NOT NULL'); + $this->addSql('ALTER TABLE membersgroups MODIFY COLUMN Status VARCHAR(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_uca1400_ai_ci NOT NULL'); + $this->addSql('ALTER TABLE members_threads_subscribed MODIFY COLUMN ActionToWatch VARCHAR(7) CHARACTER SET utf8mb4 COLLATE utf8mb4_uca1400_ai_ci NOT NULL'); + $this->addSql('ALTER TABLE member_language_level MODIFY COLUMN level VARCHAR(13) CHARACTER SET utf8mb4 COLLATE utf8mb4_uca1400_ai_ci NOT NULL'); + $this->addSql('ALTER TABLE messages MODIFY COLUMN InFolder VARCHAR(8) CHARACTER SET utf8mb4 COLLATE utf8mb4_uca1400_ai_ci NOT NULL'); + $this->addSql('ALTER TABLE messages MODIFY COLUMN Status VARCHAR(7) CHARACTER SET utf8mb4 COLLATE utf8mb4_uca1400_ai_ci NOT NULL'); + $this->addSql('ALTER TABLE reports_to_moderators MODIFY COLUMN LastWhoSpoke VARCHAR(9) CHARACTER SET utf8mb4 COLLATE utf8mb4_uca1400_ai_ci NOT NULL'); + $this->addSql('ALTER TABLE reports_to_moderators MODIFY COLUMN Status VARCHAR(12) CHARACTER SET utf8mb4 COLLATE utf8mb4_uca1400_ai_ci NOT NULL'); + $this->addSql('ALTER TABLE reports_to_moderators MODIFY COLUMN Type VARCHAR(13) CHARACTER SET utf8mb4 COLLATE utf8mb4_uca1400_ai_ci NOT NULL'); + $this->addSql('ALTER TABLE trips MODIFY COLUMN additionalInfo VARCHAR(13) CHARACTER SET utf8mb4 COLLATE utf8mb4_uca1400_ai_ci NOT NULL'); + $this->addSql('ALTER TABLE word MODIFY COLUMN domain VARCHAR(17) CHARACTER SET utf8mb4 COLLATE utf8mb4_uca1400_ai_ci NOT NULL'); + $this->addSql('ALTER TABLE word MODIFY COLUMN donottranslate VARCHAR(3) CHARACTER SET utf8mb4 COLLATE utf8mb4_uca1400_ai_ci NOT NULL'); + } + + #[Override] + public function down(Schema $schema): void + { + $this->addSql('ALTER TABLE comment MODIFY COLUMN admin_action ENUM(\'NothingNeeded\', \'AdminCommentMustCheck\', \'AdminAbuserMustCheck\', \'Checked\') CHARACTER SET utf8mb4 COLLATE utf8mb4_uca1400_ai_ci NOT NULL'); + $this->addSql('ALTER TABLE comment MODIFY COLUMN quality ENUM(\'positive\', \'neutral\', \'negative\') CHARACTER SET utf8mb4 COLLATE utf8mb4_uca1400_ai_ci NOT NULL'); + $this->addSql('ALTER TABLE comments MODIFY COLUMN AdminAction ENUM(\'NothingNeeded\', \'AdminCommentMustCheck\', \'AdminAbuserMustCheck\', \'Checked\') CHARACTER SET utf8mb4 COLLATE utf8mb4_uca1400_ai_ci NOT NULL'); + $this->addSql('ALTER TABLE comments MODIFY COLUMN Quality ENUM(\'positive\', \'neutral\', \'negative\') CHARACTER SET utf8mb4 COLLATE utf8mb4_uca1400_ai_ci NOT NULL'); + $this->addSql('ALTER TABLE forum_post MODIFY COLUMN OwnerCanStillEdit ENUM(\'Yes\', \'No\') CHARACTER SET utf8mb4 COLLATE utf8mb4_uca1400_ai_ci NOT NULL'); + $this->addSql('ALTER TABLE forum_post MODIFY COLUMN PostDeleted ENUM(\'NotDeleted\', \'Deleted\') CHARACTER SET utf8mb4 COLLATE utf8mb4_uca1400_ai_ci NOT NULL'); + $this->addSql('ALTER TABLE forum_post MODIFY COLUMN PostVisibility ENUM(\'NoRestriction\', \'MembersOnly\', \'GroupOnly\', \'Moderator\') CHARACTER SET utf8mb4 COLLATE utf8mb4_uca1400_ai_ci NOT NULL'); + $this->addSql('ALTER TABLE forum_thread MODIFY COLUMN ThreadDeleted ENUM(\'NotDeleted\', \'Deleted\') CHARACTER SET utf8mb4 COLLATE utf8mb4_uca1400_ai_ci NOT NULL'); + $this->addSql('ALTER TABLE forum_thread MODIFY COLUMN ThreadVisibility ENUM(\'NoRestriction\', \'MembersOnly\', \'GroupOnly\', \'Moderator\') CHARACTER SET utf8mb4 COLLATE utf8mb4_uca1400_ai_ci NOT NULL'); + $this->addSql('ALTER TABLE forum_thread MODIFY COLUMN WhoCanReply ENUM(\'MembersOnly\', \'GroupMembersOnly\', \'Moderators\') CHARACTER SET utf8mb4 COLLATE utf8mb4_uca1400_ai_ci NOT NULL'); + $this->addSql('ALTER TABLE groups MODIFY COLUMN Type ENUM(\'Public\', \'NeedAcceptance\', \'NeedInvitation\') CHARACTER SET utf8mb4 COLLATE utf8mb4_uca1400_ai_ci NOT NULL'); + $this->addSql('ALTER TABLE member MODIFY COLUMN Accommodation ENUM(\'yes\', \'no\', \'\') CHARACTER SET utf8mb4 COLLATE utf8mb4_uca1400_ai_ci DEFAULT NULL'); + $this->addSql('ALTER TABLE member MODIFY COLUMN Gender ENUM(\'male\', \'female\', \'other\') CHARACTER SET utf8mb4 COLLATE utf8mb4_uca1400_ai_ci NOT NULL'); + $this->addSql('ALTER TABLE member MODIFY COLUMN Status ENUM(\'MailToConfirm\', \'Pending\', \'DuplicateSigned\', \'NeedMore\', \'Rejected\', \'CompletedPending\', \'Active\', \'TakenOut\', \'Banned\', \'Sleeper\', \'ChoiceInactive\', \'OutOfRemind\', \'Renamed\', \'ActiveHidden\', \'SuspendedBeta\', \'AskToLeave\', \'StopBoringMe\', \'PassedAway\', \'Buggy\', \'Activated\', \'MailConfirmed\') CHARACTER SET utf8mb4 COLLATE utf8mb4_uca1400_ai_ci NOT NULL'); + $this->addSql('ALTER TABLE membersgroups MODIFY COLUMN Status ENUM(\'In\', \'WantToBeIn\', \'Kicked\', \'Invited\') CHARACTER SET utf8mb4 COLLATE utf8mb4_uca1400_ai_ci NOT NULL'); + $this->addSql('ALTER TABLE members_threads_subscribed MODIFY COLUMN ActionToWatch ENUM(\'replies\', \'updates\') CHARACTER SET utf8mb4 COLLATE utf8mb4_uca1400_ai_ci NOT NULL'); + $this->addSql('ALTER TABLE member_language_level MODIFY COLUMN level ENUM(\'mother.tongue\', \'expert\', \'fluent\', \'intermediate\', \'beginner\', \'hello.only\') CHARACTER SET utf8mb4 COLLATE utf8mb4_uca1400_ai_ci NOT NULL'); + $this->addSql('ALTER TABLE messages MODIFY COLUMN InFolder ENUM(\'Normal\', \'junk\', \'Spam\', \'Draft\', \'requests\') CHARACTER SET utf8mb4 COLLATE utf8mb4_uca1400_ai_ci NOT NULL'); + $this->addSql('ALTER TABLE messages MODIFY COLUMN Status ENUM(\'Draft\', \'ToCheck\', \'Checked\', \'ToSend\', \'Sent\', \'Freeze\') CHARACTER SET utf8mb4 COLLATE utf8mb4_uca1400_ai_ci NOT NULL'); + $this->addSql('ALTER TABLE reports_to_moderators MODIFY COLUMN LastWhoSpoke ENUM(\'Member\', \'Moderator\') CHARACTER SET utf8mb4 COLLATE utf8mb4_uca1400_ai_ci NOT NULL'); + $this->addSql('ALTER TABLE reports_to_moderators MODIFY COLUMN Status ENUM(\'Open\', \'OnDiscussion\', \'Closed\') CHARACTER SET utf8mb4 COLLATE utf8mb4_uca1400_ai_ci NOT NULL'); + $this->addSql('ALTER TABLE reports_to_moderators MODIFY COLUMN Type ENUM(\'SeeText\', \'AllowMeToEdit\', \'Insults\', \'RemoveMyPost\') CHARACTER SET utf8mb4 COLLATE utf8mb4_uca1400_ai_ci NOT NULL'); + $this->addSql('ALTER TABLE trips MODIFY COLUMN additionalInfo ENUM(\'none\', \'single\', \'couple\', \'friends_mixed\', \'friends_same\', \'family\') CHARACTER SET utf8mb4 COLLATE utf8mb4_uca1400_ai_ci NOT NULL'); + $this->addSql('ALTER TABLE word MODIFY COLUMN domain ENUM(\'messages\', \'messages+intl-icu\', \'validators\') CHARACTER SET utf8mb4 COLLATE utf8mb4_uca1400_ai_ci NOT NULL'); + $this->addSql('ALTER TABLE word MODIFY COLUMN donottranslate ENUM(\'yes\', \'no\') CHARACTER SET utf8mb4 COLLATE utf8mb4_uca1400_ai_ci NOT NULL'); + } +} diff --git a/Mike42/Wikitext/DefaultParserBackend.php b/Mike42/Wikitext/DefaultParserBackend.php index e29f06c54e..fb9a354d56 100644 --- a/Mike42/Wikitext/DefaultParserBackend.php +++ b/Mike42/Wikitext/DefaultParserBackend.php @@ -1,489 +1,30 @@ renderList($token, $list); - } - - public function renderUl($token, $list) - { - return $this->renderList($token, $list); - } - - public function renderDl($token, $list) - { - return $this->renderList($token, $list); - } - - public function renderH($token, $headings) - { - $outp = ''; - foreach ($headings as $heading) { - $tag = 'h'.$heading['depth']; - $outp .= "<$tag>".$heading['item']."\n"; - } - - return $outp; - } - - public function renderPre($token, $lines) - { - $outpline = []; - foreach ($lines as $line) { - $outpline[] = $line['item']; - } - - return '
'.implode("\n", $outpline).'
'; - } - - /** - * Render list and any sub-lists recursively. - * - * @param string $token The type of list (expect ul, ol, dl) - * @param mixed $list The hierachy representing this list - * @param mixed $expectedDepth - * - * @return string HTML markup for the list - */ - public function renderList($token, $list, $expectedDepth = 1) - { - $outp = ''; - $subtoken = 'li'; - $outp .= "<$token>\n"; - - foreach ($list as $item) { - if ('dl' === $token) { - $subtoken = ';' === $item['char'] ? 'dt' : 'dd'; - } - $outp .= "<$subtoken>"; - $diff = $item['depth'] - $expectedDepth; - /* Some items are undented unusually far .. */ - if ($diff > 0) { - $outp .= str_repeat("<$token><$subtoken>", $diff); - } - /* Caption of this item */ - $outp .= $item['item']; - if (\count($item['child']) > 0) { - /* Add children if applicable */ - $outp .= $this->renderList($token, $item['child'], $item['depth'] + 1); - } - if ($diff > 0) { - /* Close above extra encapsulation if applicable */ - $outp .= str_repeat("", $diff); - } - $outp .= "\n"; - } - $outp .= "\n"; - - return $outp; - } - - /** - * Default rendering of [[link]] or [[link|foo]]. - * - * @param string $destination page name we are linking to - * @param string $caption Caption of this link (can inlude parsed wikitext) - * @param mixed $arg - * - * @return string HTML markup for the link - */ - public function renderLinkInternal($arg) - { - /* Figure out properties based on arguments */ - if (isset($arg[0])) { - $destination = $arg[0]; - } - if (isset($arg[1])) { - $caption = $arg[1]; - } - - /* Compensate for missing values */ - if (isset($destination) && !isset($caption)) { - $caption = $destination; // Fill in caption = destination as default - } - if (!isset($destination)) { - if (isset($caption)) { - $destination = ''; // Empty link - } else { - return ''; // Empty link to nowhere (so skip it) - } - } - - $info = ['url' => $destination, /* You should override getInternalLinkInfo() to set this better according to your application. */ - 'title' => $destination, /* Eg [[foo:bar]] links to "foo:bar". */ - 'namespace' => '', /* Eg [[foo:bar]] is in namespace 'foo' */ - 'target' => $destination, /* Eg [[foo:bar]] has the target "bar" within the namespace. */ - 'namespaceignore' => false, /* eg [[:File:foo.png]], link to the image don't include it */ - 'caption' => $caption, /* The link caption eg [[foo:bar|baz]] has the caption 'baz' */ - 'exists' => true, /* Causes class="new" for making red-links */ - 'external' => false, ]; - - /* Attempt to deduce namespaces */ - if ('' === $destination) { - $split = false; - } else { - $split = strpos($destination, ':', 1); - } - - if (false === !$split) { - /* We have namespace */ - if (':' === substr($destination, 0, 1)) { /* Eg [[:category:foo]] */ - $info['namespaceignore'] = true; - $info['namespace'] = strtolower(substr($destination, 1, $split - 1)); - } else { - $info['namespace'] = strtolower(substr($destination, 0, $split)); - } - - ++$split; - $info['target'] = substr($destination, $split, \strlen($destination) - $split); - - /* Look up in default interwiki table */ - if (false === $this->interwiki) { - /* Load as needed */ - $this->loadInterwikiLinks(); - } - - if ('file' === $info['namespace']) { - /* Render an image instead of a link if requested */ - $info['url'] = $info['target']; - $info['caption'] = ''; - - return $this->renderFile($info, $arg); - } elseif (isset($this->interwiki[$info['namespace']])) { - /* We have a known namespace */ - $site = $this->interwiki[$info['namespace']]; - $info['url'] = str_replace('$1', $info['target'], $site); - } - } - - /* Allow the local app to contribute to link properties */ - $info = $this->getInternalLinkInfo($info); - - return ''.$info['caption'].''; - } - - public function renderFile($info, $arg) - { - $info['thumb'] = $info['url']; /* Default no no server-side thumbs */ - $info['class'] = ''; - $info['page'] = ''; - $info['caption'] = ''; - - $target = $info['target']; - $pos = strrpos($target, '.'); - if (false === $pos) { - $ext = ''; - } else { - ++$pos; - $ext = substr($target, $pos, \strlen($target) - $pos); - } - - switch ($ext) { - case 'jpg': - case 'jpeg': - case 'png': - case 'gif': - /* Image flags parsed. From: http://www.mediawiki.org/wiki/Help:Images */ - - /* Named arguments */ - if (isset($arg['link'])) { // |link= - $info['url'] = $arg['link']; - $info['link'] = $arg['link']; - unset($arg['link']); - } - if (isset($arg['class'])) { // |class= - $info['class'] = $arg['class']; - unset($arg['class']); - } - if (isset($arg['alt'])) { // |alt= - $info['title'] = $arg['alt']; - unset($arg['alt']); - } - if (isset($arg['page'])) { // |alt= - $info['page'] = $arg['page']; - unset($arg['page']); - } - - foreach ($arg as $key => $item) { - /* Figure out unnamed arguments */ - if (is_numeric($key)) { /* Any unsupported named arguments will be ignored */ - if ('px' === substr($item, 0, -2)) { - /* Size */ - // TODO - } else { - /* Load recognised switches */ - switch ($item) { - case 'frameless': - $info['frameless'] = true; - break; - case 'border': - $info['border'] = true; - break; - case 'frame': - $info['frame'] = true; - break; - case 'thumb': - $info['thumbnail'] = true; - break; - case 'thumbnail': - $info['thumbnail'] = true; - break; - case 'left': - $info['left'] = true; - break; - case 'right': - $info['right'] = true; - break; - case 'center': - $info['center'] = true; - break; - case 'none': - $info['none'] = true; - break; - default: - $info['caption'] = $item; - } - } - } - } - - $info = $this->getImageInfo($info); - - if ($info['namespaceignore'] || !$info['exists']) { - /* Only link to the image, do not display it */ - if ('' === $info['caption']) { - $info['caption'] = $info['target']; - } - /* Construct link */ - return ''.$info['caption'].''; - } - $dend = $dstart = ''; - if (isset($info['thumbnail']) || isset($info['frame'])) { - if (isset($info['right'])) { - $align = ' tright'; - } elseif (isset($info['left'])) { - $align = ' tleft'; - } else { - $align = ''; - } - $dstart = "
"; - if ('' !== $info['caption']) { - $dend .= '
'.htmlspecialchars($info['caption']).'
'; - } - $dend .= '
'; - } - /* Construct link */ - return "$dstart'.htmlspecialchars($info['title']).$dend"; - break; - default: - /* Something unsupported */ - return '(unsupported media file)'; - } - } - - /** - * Method to override when providing extra info about an image (basically external URL and thumbnail path). - * - * @param mixed $info - */ - public function getImageInfo($info) + public function getInternalLinkInfo($info): array { return $info; } - /** - * Method to override when providing extra info about a link. - * - * @param mixed $info - */ - public function getInternalLinkInfo($info) + public function getImageInfo($info): array { return $info; } - public function loadInterwikiLinks() - { - if (false !== $this->interwiki) { - /* Use loaded interwiki links if they exist */ - return; - } - - $this->interwiki = []; - $json = file_get_contents(__DIR__.'/interwiki.json'); - /* Unserialize data and load into associative array for easy lookup */ - $arr = json_decode($json); - foreach ($arr->query->interwikimap as $site) { - if (isset($site->prefix) && isset($site->url)) { - $this->interwiki[$site->prefix] = $site->url; - } - } - } - - /** - * Default rendering of [http://... link] or [http://foo]. - * - * @param string $destination page name we are linking to - * @param string $caption Caption of this link (can inlude parsed wikitext) - * @param mixed $arg - * - * @return string HTML markup for the link - */ - public function renderLinkExternal($arg) - { - $caption = $destination = $arg[0]; - if (isset($arg[1])) { - $caption = $arg[1]; - } - - return ''.$caption.''; - } - - /** - * Default encapsulation for '''bold'''. - * - * @param string $text Text to make bold - * - * @return string - */ - public function encapsulateBold($text) - { - return ''.$text.''; - } - - /** - * Default encapsulation for ''italic''. - * - * @param string $text Text to make bold - * - * @return string - */ - public function encapsulateItalic($text) - { - return ''.$text.''; - } - - public function encapsulateParagraph($text) - { - return '

'.$text."

\n"; - } - - /** - * Generate HTML for a table. - * - * @param mixed $table - */ - public function renderTable($table) - { - if ('' === $table['properties']) { - $outp = "\n"; - } else { - $outp = '
\n"; - } - - foreach ($table['row'] as $row) { - $outp .= $this->renderRow($row); - } - - return $outp."
\n"; - } - - /** - * Render a single row of a table. - * - * @param mixed $row - */ - public function renderRow($row) - { - /* Show row with or without attributes */ - if ('' === $row['properties']) { - $outp = "\n"; - } else { - $outp = '\n"; - } - - foreach ($row['col'] as $col) { - /* Show column with or without attributes */ - if (0 !== \count($col['arg'])) { - $outp .= '<'.$col['token'].' '.trim($col['arg'][0]).'>'; - } else { - $outp .= '<'.$col['token'].'>'; - } - $outp .= $col['content'].'\n"; - } - - return $outp."\n"; - } - - /** - * Function to over-ride if you want to provide a mechanism for getting templates. - * - * @param string $template - */ - public function getTemplateMarkup($template) - { - return "[[$template]]"; - } } diff --git a/Mike42/Wikitext/HtmlRenderer.php b/Mike42/Wikitext/HtmlRenderer.php new file mode 100644 index 0000000000..d5db13ca6b --- /dev/null +++ b/Mike42/Wikitext/HtmlRenderer.php @@ -0,0 +1,456 @@ +interwiki = $repo; + } + + /** + * Process an element which has arguments. Links, lists and templates fall under this category + * + * @param string $elementName + * @param string $arg + */ + public function renderWithArgs($elementName, $arg) + { + $fn = array($this, 'render' . ucfirst($elementName)); + + if (is_callable($fn)) { + /* If a function is defined to handle this, use it */ + return call_user_func_array($fn, array($arg)); + } else { + return $arg[0]; + } + } + + /** + * Encapsulate inline elements + * + * @param string $text parsed text contained within this element + * @param string $elementName the name of the element + * @return string Correct markup for this element + */ + public function encapsulateElement($elementName, $text) + { + $fn = array($this, 'encapsulate' . ucfirst($elementName)); + + if (is_callable($fn)) { + /* If a function is defined to encapsulate this, use it */ + return call_user_func_array($fn, array($text)); + } else { + return $text; + } + } + + public function renderLineBlock($elementName, $list) + { + $fn = array($this, 'render' . ucfirst($elementName)); + + if (is_callable($fn)) { + /* If a function is defined to encapsulate this, use it */ + return call_user_func_array($fn, array($elementName, $list)); + } else { + return $elementName; + } + } + + public function renderOl($token, $list) + { + return $this->renderList($token, $list); + } + + public function renderUl($token, $list) + { + return $this->renderList($token, $list); + } + + public function renderDl($token, $list) + { + return $this->renderList($token, $list); + } + + public function renderH($token, $headings) + { + $outp = ""; + foreach ($headings as $heading) { + $tag = "h" . $heading['depth']; + $outp .= "<$tag>" . $heading['item'] . "\n"; + } + return $outp; + } + + public function renderPre($token, $lines) + { + $outpline = array(); + foreach ($lines as $line) { + $outpline[] = $line['item']; + } + + return "
" . implode("\n", $outpline) . "
"; + } + + /** + * Render list and any sub-lists recursively + * + * @param string $token The type of list (expect ul, ol, dl) + * @param mixed $list The hierachy representing this list + * @return string HTML markup for the list + */ + public function renderList($token, $list, $expectedDepth = 1): string + { + $outp = ''; + $subtoken = "li"; + $outp .= "<$token>\n"; + + foreach ($list as $item) { + if ($token == 'dl') { + $subtoken = $item['char'] == ";" ? "dt" : "dd"; + } + $outp .= "<$subtoken>"; + $diff = $item['depth'] - $expectedDepth; + /* Some items are undented unusually far .. */ + if ($diff > 0) { + $outp .= str_repeat("<$token><$subtoken>", $diff); + } + /* Caption of this item */ + $outp .= $item['item']; + if (count($item['child']) > 0) { + /* Add children if applicable */ + $outp .= $this->renderList($token, $item['child'], $item['depth'] + 1); + } + if ($diff > 0) { + /* Close above extra encapsulation if applicable */ + $outp .= str_repeat("", $diff); + } + $outp .= "\n"; + } + $outp .= "\n"; + return $outp; + } + + /** + * Default rendering of [[link]] or [[link|foo]] + * + * @param string $destination page name we are linking to + * @param string $caption Caption of this link (can inlude parsed wikitext) + * @return string HTML markup for the link + */ + public function renderLinkInternal($arg): string + { + /* Figure out properties based on arguments */ + if (isset($arg[0])) { + $destination = $arg[0]; + } + if (isset($arg[1])) { + $caption = $arg[1]; + } + + /* Compensate for missing values */ + if (isset($destination) && !isset($caption)) { + $caption = $destination; // Fill in caption = destination as default + } + if (!isset($destination)) { + if (isset($caption)) { + $destination = ""; // Empty link + } else { + return ""; // Empty link to nowhere (so skip it) + } + } + + $info = array('url' => $destination, /* You should override getInternalLinkInfo() to set this better according to your application. */ + 'title' => $destination, /* Eg [[foo:bar]] links to "foo:bar". */ + 'namespace' => '', /* Eg [[foo:bar]] is in namespace 'foo' */ + 'target' => $destination, /* Eg [[foo:bar]] has the target "bar" within the namespace. */ + 'namespaceignore' => false, /* eg [[:File:foo.png]], link to the image don't include it */ + 'caption' => $caption, /* The link caption eg [[foo:bar|baz]] has the caption 'baz' */ + 'exists' => true, /* Causes class="new" for making red-links */ + 'external' => false); + + /* Attempt to deduce namespaces */ + if ($destination == '') { + $split = false; + } else { + $split = strpos($destination, ":", 1); + } + + if (!$split === false) { + /* We have namespace */ + if (substr($destination, 0, 1) == ":") { /* Eg [[:category:foo]] */ + $info['namespaceignore'] = true; + $info['namespace'] = strtolower(substr($destination, 1, $split - 1)); + } else { + $info['namespace'] = strtolower(substr($destination, 0, $split)); + } + + $split++; + $info['target'] = substr($destination, $split, strlen($destination) - $split); + + if ($info['namespace'] == 'file') { + /* Render an image instead of a link if requested */ + $info['url'] = $info['target']; + $info['caption'] = ''; + return $this->renderFile($info, $arg); + } else if ($this->interwiki->hasNamespace($info['namespace'])) { + /* We have a known namespace */ + $site = $this->interwiki->getTargetUrl($info['namespace']); + $info['url'] = str_replace("$1", $info['target'], $site); + $info['external'] = true; + } + } + + /* Allow the local app to contribute to link properties */ + $info = $this->getInternalLinkInfo($info); + + return "" . $info['caption'] . ""; + } + + public function renderFile($info, $arg) + { + $info['thumb'] = $info['url']; /* Default no no server-side thumbs */ + $info['class'] = ''; + $info['page'] = ''; + $info['caption'] = ''; + + $target = $info['target']; + $pos = strrpos($target, "."); + if ($pos === false) { + $ext = ''; + } else { + $pos++; + $ext = substr($target, $pos, strlen($target) - $pos); + } + + switch ($ext) { + case 'jpg': + case 'jpeg': + case 'png': + case 'gif': + case 'webp': + /* Image flags parsed. From: http://www.mediawiki.org/wiki/Help:Images */ + + /* Named arguments */ + if (isset($arg['link'])) { // |link= + $info['url'] = $arg['link']; + $info['link'] = $arg['link']; + unset($arg['link']); + } + if (isset($arg['class'])) { // |class= + $info['class'] = $arg['class']; + unset($arg['class']); + } + if (isset($arg['alt'])) { // |alt= + $info['title'] = $arg['alt']; + unset($arg['alt']); + } + if (isset($arg['page'])) { // |alt= + $info['page'] = $arg['page']; + unset($arg['page']); + } + + foreach ($arg as $key => $item) { + /* Figure out unnamed arguments */ + if (is_numeric($key)) { /* Any unsupported named arguments will be ignored */ + if (substr($item, 0, -2) == 'px') { + /* Size */ + // TODO + } else { + /* Load recognised switches */ + switch ($item) { + case "frameless": + $info['frameless'] = true; + break; + case "border": + $info['border'] = true; + break; + case "frame": + $info['frame'] = true; + break; + case "thumb": + $info['thumbnail'] = true; + break; + case "thumbnail": + $info['thumbnail'] = true; + break; + case "left": + $info['left'] = true; + break; + case "right": + $info['right'] = true; + break; + case "center": + $info['center'] = true; + break; + case "none": + $info['none'] = true; + break; + default: + $info['caption'] = $item; + } + } + } + } + + $info = $this->getImageInfo($info); + + if ($info['namespaceignore'] || !$info['exists']) { + /* Only link to the image, do not display it */ + if ($info['caption'] == '') { + $info['caption'] = $info['target']; + } + /* Construct link */ + return "" . $info['caption'] . ""; + } else { + $dend = $dstart = ""; + if (isset($info['thumbnail']) || isset($info['frame'])) { + if (isset($info['right'])) { + $align = " tright"; + } elseif (isset($info['left'])) { + $align = " tleft"; + } else { + $align = ""; + } + $dstart = "
"; + if ($info['caption'] != '') { + $dend .= "
" . htmlspecialchars($info['caption']) . "
"; + } + $dend .= "
"; + } + /* Construct link */ + return "$dstart\""$dend"; + } + + break; + default: + /* Something unsupported */ + return "(unsupported media file)"; + } + } + + /** + * Method to override when providing extra info about an image (basically external URL and thumbnail path) + */ + abstract public function getImageInfo($info): array; + + /** + * Method to override when providing extra info about a link + */ + abstract public function getInternalLinkInfo($info): array; + + /** + * Default rendering of [http://... link] or [http://foo] + * + * @param string $destination page name we are linking to + * @param string $caption Caption of this link (can inlude parsed wikitext) + * @return string HTML markup for the link + */ + public function renderLinkExternal($arg) + { + $caption = $destination = $arg[0]; + if (isset($arg[1])) { + $caption = $arg[1]; + } + return "" . $caption . ""; + } + + /** + * Default encapsulation for '''bold''' + * + * @param string $text Text to make bold + * @return string + */ + public function encapsulateBold($text) + { + return "" . $text . ""; + } + + /** + * Default encapsulation for ''italic'' + * + * @param string $text Text to make bold + * @return string + */ + public function encapsulateItalic($text) + { + return "" . $text . ""; + } + + public function encapsulateParagraph($text) + { + return "

" . $text . "

\n"; + } + + /** + * Generate HTML for a table + */ + public function renderTable($table) + { + if ($table['properties'] == '') { + $outp = "\n"; + } else { + $outp = "
\n"; + } + + foreach ($table['row'] as $row) { + $outp .= $this->renderRow($row); + } + + return $outp . "
\n"; + } + + /** + * Render a single row of a table + */ + public function renderRow($row) + { + /* Show row with or without attributes */ + if ($row['properties'] == '') { + $outp = "\n"; + } else { + $outp = "\n"; + } + + foreach ($row['col'] as $col) { + /* Show column with or without attributes */ + if (count($col['arg']) != 0) { + $outp .= "<" . $col['token'] . " " . trim($col['arg'][0]) . ">"; + } else { + $outp .= "<" . $col['token'] . ">"; + } + $outp .= $col['content'] . "\n"; + } + + return $outp . "\n"; + } + + /** + * Function to over-ride if you want to provide a mechanism for getting templates + * + * @param string $template + */ + public function getTemplateMarkup($template) + { + return "[[$template]]"; + } + +} diff --git a/Mike42/Wikitext/InterwikiRepository.php b/Mike42/Wikitext/InterwikiRepository.php new file mode 100644 index 0000000000..23c07ffe9e --- /dev/null +++ b/Mike42/Wikitext/InterwikiRepository.php @@ -0,0 +1,28 @@ +query->interwikimap as $site) { + if (isset($site->prefix) && isset($site->url)) { + $this->interwiki[$site->prefix] = $site->url; + } + } + } + + public function getTargetUrl(string $namespace): string + { + return $this->interwiki[$namespace]; + } + + public function hasNamespace(string $ns): bool + { + return array_key_exists($ns, $this->interwiki); + } + +} diff --git a/Mike42/Wikitext/NullInterwikiRepository.php b/Mike42/Wikitext/NullInterwikiRepository.php new file mode 100644 index 0000000000..353add14b4 --- /dev/null +++ b/Mike42/Wikitext/NullInterwikiRepository.php @@ -0,0 +1,25 @@ +startTag = str_split($startTag); - $this->endTag = str_split($endTag); - $this->argSep = str_split($argSep); - $this->argNameSep = str_split($argNameSep); - $this->argLimit = $argLimit; - $this->hasArgs = \count($this->argSep) > 0; + $this -> startTag = str_split($startTag); + $this -> endTag = str_split($endTag); + $this -> argSep = str_split($argSep); + $this -> argNameSep = str_split($argNameSep); + $this -> argLimit = $argLimit; + $this -> hasArgs = count($this -> argSep) > 0; } } diff --git a/Mike42/Wikitext/ParserLineBlockElement.php b/Mike42/Wikitext/ParserLineBlockElement.php index a1cc77266b..dc5d53e5b5 100644 --- a/Mike42/Wikitext/ParserLineBlockElement.php +++ b/Mike42/Wikitext/ParserLineBlockElement.php @@ -8,12 +8,12 @@ class ParserLineBlockElement public $endChar; /* End character */ public $limit; /* Max depth of the element */ public $nestTags; /* True if the tags for this element need to made hierachical for nesting */ - + public function __construct($startChar, $endChar, $limit = 0, $nestTags = true) { - $this->startChar = $startChar; - $this->endChar = $endChar; - $this->limit = $limit; - $this->nestTags = $nestTags; + $this -> startChar = $startChar; + $this -> endChar = $endChar; + $this -> limit = $limit; + $this -> nestTags = $nestTags; } } diff --git a/Mike42/Wikitext/ParserTableElement.php b/Mike42/Wikitext/ParserTableElement.php index 143eedf171..0605db6b89 100644 --- a/Mike42/Wikitext/ParserTableElement.php +++ b/Mike42/Wikitext/ParserTableElement.php @@ -11,9 +11,9 @@ class ParserTableElement public function __construct(string $lineStart, string $argsep, string $inlinesep, $limit) { - $this->lineStart = str_split($lineStart); - $this->argsep = str_split($argsep); - $this->inlinesep = str_split($inlinesep); - $this->limit = $limit; + $this -> lineStart = str_split($lineStart); + $this -> argsep = str_split($argsep); + $this -> inlinesep = str_split($inlinesep); + $this -> limit = $limit; } } diff --git a/Mike42/Wikitext/WikitextParser.php b/Mike42/Wikitext/WikitextParser.php index d067f54b41..55c3ddec4c 100644 --- a/Mike42/Wikitext/WikitextParser.php +++ b/Mike42/Wikitext/WikitextParser.php @@ -1,163 +1,121 @@ + Copyright (C) 2012 Michael Billington -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and -associated documentation files (the "Software"), to deal in the Software without restriction, -including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, -and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: + Permission is hereby granted, free of charge, to any person obtaining a copy of this software and + associated documentation files (the "Software"), to deal in the Software without restriction, + including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: -The above copyright notice and this permission notice shall be included in all copies or substantial -portions of the Software. + The above copyright notice and this permission notice shall be included in all copies or substantial + portions of the Software. -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, -INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A -PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF -CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -*/ + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, + INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ namespace Mike42\Wikitext; class WikitextParser { - const VERSION = '1.0'; + + const VERSION = "1.0"; const MAX_INCLUDE_DEPTH = 32; /* Depth of template includes to put up with. set to 0 to disallow inclusion, negative to remove the limit */ - public static $backend; + + private $inline; + private $lineBlock; + protected $backend; + private $tableBlock; + private $tableStart; + private $inlineLookup; + private $inlineChars; + private $preprocessor; + private $preprocessorChars; /* These are set as a result of parsing */ public $preprocessed; /* Wikitext after preprocessor had a go at it. */ public $result; /* Wikitext of result */ - private static $inline; - private static $lineBlock; - private static $tableBlock; - private static $tableStart; - private static $inlineLookup; - private static $inlineChars; - private static $preprocessor; - private static $preprocessorChars; - private static $initialised = false; - - /** - * Initialise a new parser object and parse a standalone document. - * If templates are included, each will processed by a different instance of this object. - * - * @param string $text The text to parse - */ - public function __construct(string $text, array $params = []) - { - if (false === self::$initialised) { - self::init(); - } - $this->params = $params; - $this->preprocessed = $this->preprocessText(self::explodeString($text)); - - /* Now divide into paragraphs */ - // TODO operate on arrays instead of strings here - $sections = explode("\n\n", str_replace("\r\n", "\n", $this->preprocessed)); - - $newtext = []; - foreach ($sections as $section) { - /* Newlines at the start/end have special meaning (compare to how this is called from parseLineBlock) */ - $sectionChars = self::explodeString("\n".$section); - $result = $this->parseInline($sectionChars, 'p'); - $newtext[] = $result['parsed']; - } - - $this->result = implode('', $newtext); - } - /** - * Definitions for tokens with special meaning to the parser. + * Definitions for tokens with special meaning to the parser */ - public static function init(array $sharedVars = []) + public function __construct(HtmlRenderer $render) { /* Table elements. These are parsed separately to the other elements */ - self::$tableStart = new ParserInlineElement('{|', '|}'); + $this->tableStart = new ParserInlineElement("{|", "|}"); - self::$tableBlock = [ - 'tr' => new ParserTableElement('|-', '', '', ''), - 'th' => new ParserTableElement('!', '|', '!!', 1), - 'td' => new ParserTableElement('|', '|', '||', 1), - 'caption' => new ParserTableElement('|+', '', '', 0), ]; + $this->tableBlock = array( + 'tr' => new ParserTableElement('|-', '', '', ''), + 'th' => new ParserTableElement('!', '|', '!!', 1), + 'td' => new ParserTableElement('|', '|', '||', 1), + 'caption' => new ParserTableElement('|+', '', '', 0)); /* Inline elemens. These are parsed recursively and can be nested as deeply as the system will allow. */ - self::$inline = [ - 'nothing' => new ParserInlineElement('', ''), - 'td' => new ParserInlineElement('', ''), // Just used as a marker - 'linkInternal' => new ParserInlineElement('[[', ']]', '|', '='), - 'linkExternal' => new ParserInlineElement('[', ']', ' ', '', 1), - 'bold' => new ParserInlineElement("'''", "'''"), - 'italic' => new ParserInlineElement("''", "''"), - 'switch' => new ParserInlineElement('__', '__'), ]; - self::$inlineChars = [ + $this->inline = array( + 'nothing' => new ParserInlineElement('', ''), + 'td' => new ParserInlineElement('', ''), // Just used as a marker + 'linkInternal' => new ParserInlineElement('[[', ']]', '|', '='), + 'linkExternal' => new ParserInlineElement('[', ']', ' ', '', 1), + 'bold' => new ParserInlineElement("'''", "'''"), + 'italic' => new ParserInlineElement("''", "''"), + 'switch' => new ParserInlineElement('__', '__')); + $this->inlineChars = [ '[' => true, '\'' => true, ']' => true, "\n" => true, - '=' => true, - '*' => true, - '#' => true, - ':' => true, - '|' => true, - '~' => true, - ' ' => true, - '_' => true, + "=" => true, + "*" => true, + "#" => true, + ":" => true, + "|" => true, + "~" => true, + " " => true, + '_' => true ]; /* Create lookup table for efficiency */ - self::$inlineLookup = self::elementLookupTable(self::$inline); - self::$backend = new DefaultParserBackend(); + $this->inlineLookup = $this->elementLookupTable($this->inline); + $this->backend = $render; /* Line-block elements. These are characters which have a special meaning at the start of lines, and use the next end-line as a close tag. */ - self::$lineBlock = [ - 'pre' => new ParserLineBlockElement([' '], [], 1, false), - 'ul' => new ParserLineBlockElement(['*'], [], 32, true), - 'ol' => new ParserLineBlockElement(['#'], [], 32, true), - 'dl' => new ParserLineBlockElement([':', ';'], [], 32, true), - 'h' => new ParserLineBlockElement(['='], ['='], 6, false), ]; - - self::$preprocessor = [ - 'noinclude' => new ParserInlineElement('', ''), - 'includeonly' => new ParserInlineElement('', ''), - 'arg' => new ParserInlineElement('{{{', '}}}', '|', '', 1), - 'template' => new ParserInlineElement('{{', '}}', '|', '='), - 'comment' => new ParserInlineElement(''), ]; - self::$preprocessorChars = [ + $this->lineBlock = array( + 'pre' => new ParserLineBlockElement(array(" "), [], 1, false), + 'ul' => new ParserLineBlockElement(array("*"), [], 32, true), + 'ol' => new ParserLineBlockElement(array("#"), [], 32, true), + 'dl' => new ParserLineBlockElement(array(":", ";"), [], 32, true), + 'h' => new ParserLineBlockElement(array("="), array("="), 6, false)); + + $this->preprocessor = array( + 'noinclude' => new ParserInlineElement('', ''), + 'includeonly' => new ParserInlineElement('', ''), + 'arg' => new ParserInlineElement('{{{', '}}}', '|', '', 1), + 'template' => new ParserInlineElement('{{', '}}', '|', '='), + 'comment' => new ParserInlineElement('')); + $this->preprocessorChars = [ '<' => true, '=' => true, '|' => true, - '{' => true, + '{' => true ]; - self::$initialised = true; - } - - /** - * Parse a given document/page of text (main entry point). - * - * @param string $text - * - * @return string - */ - public static function parse(string $text) - { - $parser = new self($text); - - return $parser->result; + $this->initialised = true; } - private static function elementLookupTable(array $elements) + private function elementLookupTable(array $elements): array { $lookup = []; foreach ($elements as $key => $token) { - if (0 !== \count($token->startTag)) { + if (count($token->startTag) != 0) { $c = $token->startTag[0]; if (!isset($lookup[$c])) { $lookup[$c] = []; @@ -165,54 +123,74 @@ private static function elementLookupTable(array $elements) $lookup[$c][$key] = $elements[$key]; } } - return $lookup; } - private static function explodeString(string $string) + /** + * Parse a given document/page of text (main entry point) + * + * @param string $text + */ + public function parse(string $text): string + { + $this->preprocessed = $this->preprocessText($this->explodeString($text)); + + /* Now divide into paragraphs */ + // TODO operate on arrays instead of strings here + $sections = explode("\n\n", str_replace("\r\n", "\n", $this->preprocessed)); + + $newtext = []; + foreach ($sections as $section) { + /* Newlines at the start/end have special meaning (compare to how this is called from parseLineBlock) */ + $sectionChars = $this->explodeString("\n" . $section); + $result = $this->parseInline($sectionChars, 'p'); + $newtext[] = $result['parsed']; + } + return $this->result = implode($newtext); + } + + private function explodeString(string $string) { return $chrArray = preg_split('//u', $string, -1, PREG_SPLIT_NO_EMPTY); } /** - * Handle template arguments and other oddities. This section of the parser is single-pass and linear, with the exception of the part which substitutes templates. - * - * @param string $text wikitext to handle - * @param mixed $arg Arguments (applies only to templates) - * @param bool $included true if the text is included, false otherwise - * + * Handle template arguments and other oddities. This section of the parser is single-pass and linear, with the exception of the part which substitutes templates + * @param string $text wikitext to handle + * @param mixed $arg Arguments (applies only to templates) + * @param boolean $included true if the text is included, false otherwise * @return string */ private function preprocessText(array $textChars, array $arg = [], bool $included = false, int $depth = 0) { $parsed = ''; - $len = \count($textChars); - for ($i = 0; $i < $len; ++$i) { + $len = count($textChars); + for ($i = 0; $i < $len; $i++) { $hit = false; $c = $textChars[$i]; - if (!isset(self::$preprocessorChars[$c])) { + if (!isset($this->preprocessorChars[$c])) { /* Fast exit for characters that do not start a tag. */ // TODO Could work faster if we didn't concatenate each character $parsed .= $c; continue; } - foreach (self::$preprocessor as $key => $child) { - if (self::tagIsAt($child->endTag, $textChars, $i)) { - if (('includeonly' === $key && $included) || ('noinclude' === $key && !$included)) { + foreach ($this->preprocessor as $key => $child) { + if ($this->tagIsAt($child->endTag, $textChars, $i)) { + if (($key == 'includeonly' && $included) || ($key == 'noinclude' && !$included)) { $hit = true; - $i += \count($child->endTag); + $i += count($child->endTag); /* Ignore expected end-tags */ break; } } - if (self::tagIsAt($child->startTag, $textChars, $i)) { + if ($this->tagIsAt($child->startTag, $textChars, $i)) { /* Hit a symbol. Parse it and keep going after the result */ $hit = true; - $i += \count($child->startTag); + $i += count($child->startTag); - if (('includeonly' === $key && $included) || ('noinclude' === $key && !$included)) { + if (($key == 'includeonly' && $included) || ($key == 'noinclude' && !$included)) { /* If this is a good tag, ignore it! */ break; } @@ -222,13 +200,13 @@ private function preprocessText(array $textChars, array $arg = [], bool $include $innerBuffer = ''; $innerCurKey = ''; - for ($i = $i; $i < $len; ++$i) { + for ($i = $i; $i < $len; $i++) { $innerHit = false; - if (self::tagIsAt($child->endTag, $textChars, $i)) { - $i += \count($child->endTag); + if ($this->tagIsAt($child->endTag, $textChars, $i)) { + $i += count($child->endTag); /* Clear buffers now */ - if ('' === $innerCurKey) { + if ($innerCurKey == '') { array_push($innerArg, $innerBuffer); } else { $innerArg[$innerCurKey] = $innerBuffer; @@ -236,20 +214,20 @@ private function preprocessText(array $textChars, array $arg = [], bool $include /* Figure out what to do with data */ $innerCurKey = array_shift($innerArg); - if ('arg' === $key) { + if ($key == 'arg') { if (is_numeric($innerCurKey)) { - --$innerCurKey; /* Because the associative array will be starting at 0 */ + $innerCurKey -= 1; /* Because the associative array will be starting at 0 */ } if (isset($arg[$innerCurKey])) { $parsed .= $arg[$innerCurKey]; // Use arg value if set - } elseif (\count($innerArg) > 0) { + } elseif (count($innerArg) > 0) { $parsed .= array_shift($innerArg); // Otherwise use embedded default if set } - } elseif ('template' === $key) { + } else if ($key == 'template') { /* Load wikitext of template, and preprocess it */ if (self::MAX_INCLUDE_DEPTH < 0 || $depth < self::MAX_INCLUDE_DEPTH) { - $markup = trim(self::$backend->getTemplateMarkup($innerCurKey)); - $parsed .= $this->preprocessText(self::explodeString($markup), $innerArg, true, $depth + 1); + $markup = trim($this->backend->getTemplateMarkup($innerCurKey)); + $parsed .= $this->preprocessText($this->explodeString($markup), $innerArg, true, $depth + 1); } } @@ -259,23 +237,23 @@ private function preprocessText(array $textChars, array $arg = [], bool $include } /* Argument splitting -- A dumber, non-recursiver version of what is used in ParseInline() */ - if ($child->hasArgs && (0 === $child->argLimit || $child->argLimit > \count($innerArg))) { - if (self::tagIsAt($child->argSep, $textChars, $i)) { + if ($child->hasArgs && ($child->argLimit == 0 || $child->argLimit > count($innerArg))) { + if ($this->tagIsAt($child->argSep, $textChars, $i)) { /* Hit argument separator */ - if ('' === $innerCurKey) { + if ($innerCurKey == '') { array_push($innerArg, $innerBuffer); } else { $innerArg[$innerCurKey] = $innerBuffer; } $innerCurKey = ''; // Reset key $innerBuffer = ''; // Reset parsed values - $i += \count($child->argSep) - 1; + $i += count($child->argSep) - 1; $innerHit = true; - } elseif ('' === $innerCurKey && self::tagIsAt($child->argNameSep, $textChars, $i)) { + } elseif ($innerCurKey == '' && $this->tagIsAt($child->argNameSep, $textChars, $i)) { /* Hit name/argument splitter */ $innerCurKey = $innerBuffer; // Set key $innerBuffer = ''; // Reset parsed values - $i += \count($child->argNameSep) - 1; + $i += count($child->argNameSep) - 1; $innerHit = true; } } @@ -292,54 +270,56 @@ private function preprocessText(array $textChars, array $arg = [], bool $include if (!$hit) { $parsed .= $c; } else { - --$i; + $i -= 1; } } - return $parsed; } - private static function tagIsAt(array $tag, array $textChars, int $position) + private function tagIsAt(array $tag, array $textChars, int $position) { - if ($textChars[$position] !== $tag[0]) { + if ($position >= count($textChars)) { + // Fast exit for common case + return false; + } + if (isset($tag[0]) && $textChars[$position] != $tag[0]) { // Fast exit for common case return false; } + // More detailed checks for other cases - $tagLen = \count($tag); - $strLen = \count($textChars); + $tagLen = count($tag); + $strLen = count($textChars); $match = $position + $tagLen <= $strLen && $tagLen > 0; - for ($i = 1; $i < $tagLen && $match; ++$i) { + for ($i = 1; $i < $tagLen && $match; $i++) { if ($textChars[$position + $i] !== $tag[$i]) { $match = false; break; } } - return $match; } /** * Parse a block of wikitext looking for inline tokens, indicating the start of an element. - * Calls itself recursively to search inside those elements when it finds them. + * Calls itself recursively to search inside those elements when it finds them * * @param string $text Text to parse - * @param $token the name of the current inline element, if inside one - * @param mixed $idxFrom + * @param $token The name of the current inline element, if inside one. */ private function parseInline(array $textChars, string $token = '', $idxFrom = 0) { /* Quick escape if we've run into a table */ $inParagraph = false; - if ('' === $token || !isset(self::$inline[$token])) { + if ($token == '' || !isset($this->inline[$token])) { /* Default to empty token if none is set (these have no end token, ensuring there will be no remainder after this runs) */ - if ('p' === $token) { + if ($token == 'p') { /* Blocks of text here need to be encapsualted in paragraph tags */ $inParagraph = true; } - $inlineElement = self::$inline['nothing']; + $inlineElement = $this->inline['nothing']; } else { - $inlineElement = self::$inline[$token]; + $inlineElement = $this->inline[$token]; } $parsed = ''; // For completely parsed text @@ -349,12 +329,12 @@ private function parseInline(array $textChars, string $token = '', $idxFrom = 0) $arg = []; $curKey = ''; - $len = \count($textChars); - for ($i = $idxFrom; $i < $len; ++$i) { + $len = count($textChars); + for ($i = $idxFrom; $i < $len; $i++) { /* Looping through each character */ $hit = false; // State so that the last part knows whether to simply append this as an unmatched character $c = $textChars[$i]; - if (!isset(self::$inlineChars[$c])) { + if (!isset($this->inlineChars[$c])) { // Fast exit for characters that do not start a tag. // TODO Could work faster if we didn't concatenate each character $buffer .= $c; @@ -362,30 +342,30 @@ private function parseInline(array $textChars, string $token = '', $idxFrom = 0) } /* Looking for this element's close-token */ - if (self::tagIsAt($inlineElement->endTag, $textChars, $i)) { + if ($this->tagIsAt($inlineElement->endTag, $textChars, $i)) { /* Hit a close tag: Stop parsing here, return the remainder, and let the parent continue */ - $start = $i + \count($inlineElement->endTag); + $start = $i + count($inlineElement->endTag); if ($inlineElement->hasArgs) { /* Handle arguments if needed */ - if ('' === $curKey) { + if ($curKey == '') { array_push($arg, $buffer); } else { $arg[$curKey] = $buffer; } - $buffer = self::$backend->renderWithArgs($token, $arg); + $buffer = $this->backend->renderWithArgs($token, $arg); } /* Clean up and quit */ $parsed .= $buffer; /* As far as I can tall $inPargraph should always be false here? */ - return ['parsed' => $parsed, 'remainderIdx' => $start]; + return array('parsed' => $parsed, 'remainderIdx' => $start); } /* Next priority is looking for this element's agument tokens if applicable */ - if ($inlineElement->hasArgs && (0 === $inlineElement->argLimit || $inlineElement->argLimit > \count($arg))) { - if (self::tagIsAt($inlineElement->argSep, $textChars, $i)) { + if ($inlineElement->hasArgs && ($inlineElement->argLimit == 0 || $inlineElement->argLimit > count($arg))) { + if ($this->tagIsAt($inlineElement->argSep, $textChars, $i)) { /* Hit argument separator */ - if ('' === $curKey) { + if ($curKey == '') { array_push($arg, $buffer); } else { $arg[$curKey] = $buffer; @@ -394,29 +374,29 @@ private function parseInline(array $textChars, string $token = '', $idxFrom = 0) $curKey = ''; // Reset key $buffer = ''; // Reset parsed values /* Handle position properly */ - $i += \count($inlineElement->argSep) - 1; + $i += count($inlineElement->argSep) - 1; $hit = true; - } elseif ('' === $curKey && self::tagIsAt($inlineElement->argNameSep, $textChars, $i)) { + } elseif ($curKey == '' && $this->tagIsAt($inlineElement->argNameSep, $textChars, $i)) { /* Hit name/argument splitter */ $curKey = $buffer; // Set key $buffer = ''; // Reset parsed values /* Handle position properly */ - $i += \count($inlineElement->argNameSep) - 1; + $i += count($inlineElement->argNameSep) - 1; $hit = true; } } /* Looking for new open-tokens */ - if (isset(self::$inlineLookup[$c])) { + if (isset($this->inlineLookup[$c])) { /* There are inline elements which start with this character. Check each one,.. */ - foreach (self::$inlineLookup[$c] as $key => $child) { - if (!$hit && self::tagIsAt($child->startTag, $textChars, $i)) { + foreach ($this->inlineLookup[$c] as $key => $child) { + if (!$hit && $this->tagIsAt($child->startTag, $textChars, $i)) { /* Hit a symbol. Parse it and keep going after the result */ - $start = $i + \count($child->startTag); + $start = $i + count($child->startTag); /* Regular, recursively-parsed element */ $result = $this->parseInline($textChars, $key, $start); - $buffer .= self::$backend->encapsulateElement($key, $result['parsed']); + $buffer .= $this->backend->encapsulateElement($key, $result['parsed']); $i = $result['remainderIdx'] - 1; $hit = true; } @@ -424,17 +404,17 @@ private function parseInline(array $textChars, string $token = '', $idxFrom = 0) } if (!$hit) { - if ("\n" === $c && $i < $len - 1) { - if (self::tagIsAt(self::$tableStart->startTag, $textChars, $i + 1)) { + if ($c == "\n" && $i < $len - 1) { + if ($this->tagIsAt($this->tableStart->startTag, $textChars, $i + 1)) { $hit = true; - $start = $i + 1 + \count(self::$tableStart->startTag); + $start = $i + 1 + count($this->tableStart->startTag); $key = 'table'; } else { /* Check for non-table line-based stuff coming up next, each time \n is found */ $next = $textChars[$i + 1]; - foreach (self::$lineBlock as $key => $block) { + foreach ($this->lineBlock as $key => $block) { foreach ($block->startChar as $char) { - if (!$hit && $next === $char) { + if (!$hit && $next == $char) { $hit = true; $start = $i + 1; break 2; @@ -445,27 +425,27 @@ private function parseInline(array $textChars, string $token = '', $idxFrom = 0) if ($hit) { /* Go over what's been found */ - if ('table' === $key) { + if ($key == 'table') { $result = $this->parseTable($textChars, $start); } else { /* Let parseLineBlock take care of this on a per-line basis */ $result = $this->parseLineBlock($textChars, $key, $start); } - if ('' !== $buffer) { + if ($buffer != '') { /* Something before this was part of a paragraph */ - $parsed .= self::$backend->encapsulateElement('paragraph', $buffer); - true === $inParagraph; + $parsed .= $this->backend->encapsulateElement('paragraph', $buffer); + $inParagraph == true; } - $buffer = ''; + $buffer = ""; /* Now append this non-paragraph element */ $parsed .= $result['parsed']; $i = $result['remainderIdx'] - 1; } /* Other \n-related things if it wasn't as exciting as above */ - if ('' !== $buffer && !$hit) { + if ($buffer != '' && !$hit) { /* Put in a space if it is not going to be the first thing added. */ - $buffer .= ' '; + $buffer .= " "; } } else { /* Append character to parsed output if it was not part of some token */ @@ -473,137 +453,132 @@ private function parseInline(array $textChars, string $token = '', $idxFrom = 0) } } - if ('td' === $token) { + if ($token == 'td') { /* We only get here from table syntax if something else was being parsed, so we can quit here */ $parsed = $buffer; - - return ['parsed' => $parsed, 'remainderIdx' => $i]; + return array('parsed' => $parsed, 'remainderIdx' => $i); } } /* Need to throw argument-driven items at the backend first here */ if ($inlineElement->hasArgs) { - if ('' === $curKey) { + if ($curKey == '') { array_push($arg, $buffer); } else { $arg[$curKey] = $buffer; } - $buffer = self::$backend->renderWithArgs($token, $arg); + $buffer = $this->backend->renderWithArgs($token, $arg); } - if ($inParagraph && '' !== $buffer) { + if ($inParagraph && $buffer != '') { /* Something before this was part of a paragraph */ - $parsed .= self::$backend->encapsulateElement('paragraph', $buffer); + $parsed .= $this->backend->encapsulateElement('paragraph', $buffer); } else { $parsed .= $buffer; } - return ['parsed' => $parsed, 'remainderIdx' => $i]; + return array('parsed' => $parsed, 'remainderIdx' => $i); } /** - * Parse block of wikitext known to be starting with a line-based token. + * Parse block of wikitext known to be starting with a line-based token * * @param $text Wikitext block to parse * @param $token name of the LineBlock token which we suspect - * @param mixed $fromIdx */ private function parseLineBlock(array $textChars, string $token, $fromIdx = 0) { /* Block element we are using */ - $lineBlockElement = self::$lineBlock[$token]; + $lineBlockElement = $this->lineBlock[$token]; // Loop through lines $lineStart = $fromIdx; $list = []; - while (false !== ($lineLen = self::getLineLen($textChars, $lineStart))) { - $startTokenLen = self::countChar($lineBlockElement->startChar, $textChars, $lineStart, $lineBlockElement->limit); - if (0 === $startTokenLen) { + while (($lineLen = $this->getLineLen($textChars, $lineStart)) !== false) { + $startTokenLen = $this->countChar($lineBlockElement->startChar, $textChars, $lineStart, $lineBlockElement->limit); + if ($startTokenLen === 0) { /* Wind back to include "\n" if the next line is not a list item. This is not expected * to trigger on the first iteration, since line-block tags were found for calling this method. */ - --$lineStart; + $lineStart -= 1; break; + } else { + $char = $textChars[$lineStart + $startTokenLen - 1]; + $endTokenLen = 0; + if (count($lineBlockElement->endChar) > 0) { + /* Also need to cut off end letters, such as in == Heading == */ + $endTokenLen = $this->countCharReverse($lineBlockElement->endChar, $textChars, $lineStart + $startTokenLen, $lineStart + $lineLen - 1); + } + /* Remainder of the line */ + $lineChars = array_slice($textChars, $lineStart + $startTokenLen, $lineLen - $startTokenLen - $endTokenLen); + $result = $this->parseInline($lineChars); + $list[] = array('depth' => $startTokenLen, 'item' => $result['parsed'], 'char' => $char); } - $char = $textChars[$lineStart + $startTokenLen - 1]; - $endTokenLen = 0; - if (\count($lineBlockElement->endChar) > 0) { - /* Also need to cut off end letters, such as in == Heading == */ - $endTokenLen = self::countCharReverse($lineBlockElement->endChar, $textChars, $lineStart + $startTokenLen, $lineStart + $lineLen - 1); - } - /* Remainder of the line */ - $lineChars = \array_slice($textChars, $lineStart + $startTokenLen, $lineLen - $startTokenLen - $endTokenLen); - $result = $this->parseInline($lineChars); - $list[] = ['depth' => $startTokenLen, 'item' => $result['parsed'], 'char' => $char]; - /* Move along to start of next line */ $lineStart += $lineLen + 1; } if ($lineBlockElement->nestTags) { /* Hierachy-ify nestable lists */ - $list = self::makeList($list); + $list = $this->makeList($list); } - $parsed = self::$backend->renderLineBlock($token, $list); - - return ['parsed' => $parsed, 'remainderIdx' => $lineStart]; + $parsed = $this->backend->renderLineBlock($token, $list); + return array('parsed' => $parsed, 'remainderIdx' => $lineStart); } /** - * Special handling for tables, uniquely containing both per-line and recursively parsed elements. - * - * @param string $text Text to parse - * @param mixed $fromIdx + * Special handling for tables, uniquely containing both per-line and recursively parsed elements * + * @param string $text Text to parse * @return multitype:string parsed and remaining text */ private function parseTable(array $textChars, $fromIdx = 0) { - $lineLen = self::getLineLen($textChars, $fromIdx); - $propertiesChars = \array_slice($textChars, $fromIdx, $lineLen); - $table['properties'] = implode('', $propertiesChars); + $lineLen = $this->getLineLen($textChars, $fromIdx); + $propertiesChars = array_slice($textChars, $fromIdx, $lineLen); + $table['properties'] = implode($propertiesChars); $table['row'] = []; $lineStart = $lineLen + 1; - while (false !== ($lineLen = self::getLineLen($textChars, $lineStart))) { - if (self::tagIsAt(self::$tableStart->endTag, $textChars, $lineStart)) { + while (($lineLen = $this->getLineLen($textChars, $lineStart)) !== false) { + if ($this->tagIsAt($this->tableStart->endTag, $textChars, $lineStart)) { $lineStart += $lineLen + 1; break; } $hit = false; - foreach (self::$tableBlock as $token => $block) { + foreach ($this->tableBlock as $token => $block) { /* Looking for matching per-line elements */ - if (!$hit && self::tagIsAt($block->lineStart, $textChars, $lineStart)) { + if (!$hit && $this->tagIsAt($block->lineStart, $textChars, $lineStart)) { $hit = true; break; } } if ($hit) { /* Move cursor along to skip the token */ - $tokenLen = \count($block->lineStart); + $tokenLen = count($block->lineStart); $contentStart = $lineStart + $tokenLen; $contentLen = $lineLen - $tokenLen; - if ('td' === $token || 'th' === $token) { + if ($token == 'td' || $token == 'th') { if (!isset($tmpRow)) { /* Been given a cell before a row. Make a row first */ - $tmpRow = ['properties' => '', 'col' => []]; + $tmpRow = array('properties' => '', 'col' => []); } /* Clobber the remaining text together and throw it to the cell parser */ $result = $this->parseTableCells($token, $textChars, $contentStart, $tmpRow['col']); $lineStart = $result['remainderIdx']; $lineLen = -1; $tmpRow['col'] = $result['col']; - } elseif ('tr' === $token) { - $contentChars = \array_slice($textChars, $contentStart, $contentLen); + } elseif ($token == 'tr') { + $contentChars = array_slice($textChars, $contentStart, $contentLen); if (isset($tmpRow)) { /* Append existing row to table (if one exists) */ $table['row'][] = $tmpRow; } /* Clearing current row and set properties */ - $tmpRow = [ - 'properties' => implode('', $contentChars), - 'col' => [], - ]; + $tmpRow = array( + 'properties' => implode($contentChars), + 'col' => [] + ); } } /* Move along to start of next line */ @@ -613,64 +588,61 @@ private function parseTable(array $textChars, $fromIdx = 0) /* Tack on the last row */ $table['row'][] = $tmpRow; } - $parsed = self::$backend->renderTable($table); - - return ['parsed' => $parsed, 'remainderIdx' => $lineStart]; + $parsed = $this->backend->renderTable($table); + return array('parsed' => $parsed, 'remainderIdx' => $lineStart); } - private static function getLineLen(array $textChars, int $position) + private function getLineLen(array $textChars, int $position) { /* Return number of characters in line, or FALSE if the string is depleted */ - for ($i = $position; $i < \count($textChars); ++$i) { - if ("\n" === $textChars[$i]) { + for ($i = $position; $i < count($textChars); $i++) { + if ($textChars[$i] == "\n") { return $i - $position; } } - - return $position < \count($textChars) ? \count($textChars) - $position : false; + return $position < count($textChars) ? count($textChars) - $position : false; } /** - * Retrieve columns started in this line of text. + * Retrieve columns started in this line of text * - * @param string $token Type of cells we are looking at (th or td) - * @param string $text Text to parse + * @param string $token Type of cells we are looking at (th or td) + * @param string $text Text to parse * @param string $colsSoFar Columns which have already been found in this row - * * @return multitype:string parsed and remaining text */ private function parseTableCells(string $token, array $textChars, int $from, array $colsSoFar) { - $tableElement = self::$tableBlock[$token]; - $len = \count($textChars); + $tableElement = $this->tableBlock[$token]; + $len = count($textChars); - $tmpCol = ['arg' => [], 'content' => '', 'token' => $token]; + $tmpCol = array('arg' => [], 'content' => '', 'token' => $token); $argCount = 0; $buffer = ''; /* Loop through each character */ - for ($i = $from; $i < $len; ++$i) { + for ($i = $from; $i < $len; $i++) { $hit = false; /* We basically detect the start of any inline/lineblock/table elements and, knowing that the inline parser knows how to handle them, throw then wayward */ $c = $textChars[$i]; - if (isset(self::$inlineLookup[$c])) { + if (isset($this->inlineLookup[$c])) { /* There are inline elements which start with this character. Check each one,.. */ - foreach (self::$inlineLookup[$c] as $key => $child) { - if (!$hit && self::tagIsAt($child->startTag, $textChars, $i)) { + foreach ($this->inlineLookup[$c] as $key => $child) { + if (!$hit && $this->tagIsAt($child->startTag, $textChars, $i)) { $hit = true; } } } - if ("\n" === $c) { - if (self::tagIsAt(self::$tableStart->startTag, $textChars, $i + 1)) { + if ($c == "\n") { + if ($this->tagIsAt($this->tableStart->startTag, $textChars, $i + 1)) { /* Table is coming up */ $hit = true; } else { - /* LineBlocks like lists and headings*/ + /* LineBlocks like lists and headings */ $next = $textChars[$i + 1]; - foreach (self::$lineBlock as $key => $block) { + foreach ($this->lineBlock as $key => $block) { foreach ($block->startChar as $char) { - if (!$hit && $next === $char) { + if (!$hit && $next == $char) { $hit = true; break 2; } @@ -688,34 +660,34 @@ private function parseTableCells(string $token, array $textChars, int $from, arr $i = $result['remainderIdx']; } - if (!$hit && self::tagIsAt($tableElement->inlinesep, $textChars, $i)) { + if (!$hit && $this->tagIsAt($tableElement->inlinesep, $textChars, $i)) { /* Got column separator, so this column is now finished */ $tmpCol['content'] = $buffer; $colsSoFar[] = $tmpCol; /* Reset for the next */ - $tmpCol = ['arg' => [], 'content' => '', 'token' => $token]; + $tmpCol = array('arg' => [], 'content' => '', 'token' => $token); $buffer = ''; $hit = true; - $i += \count($tableElement->inlinesep) - 1; + $i += count($tableElement->inlinesep) - 1; $argCount = 0; } - if (!$hit && $argCount < ($tableElement->limit) && self::tagIsAt($tableElement->argsep, $textChars, $i)) { + if (!$hit && $argCount < ($tableElement->limit) && $this->tagIsAt($tableElement->argsep, $textChars, $i)) { /* Got argument separator. Shift off the last argument */ $tmpCol['arg'][] = $buffer; $buffer = ''; $hit = true; - $i += \count($tableElement->argsep) - 1; - ++$argCount; + $i += count($tableElement->argsep) - 1; + $argCount++; } if (!$hit) { $c = $textChars[$i]; - if ("\n" === $c) { + if ($c == "\n") { /* Checking that the next line isn't starting a different element of the table */ - foreach (self::$tableBlock as $key => $block) { - if (self::tagIsAt($block->lineStart, $textChars, $i + 1)) { + foreach ($this->tableBlock as $key => $block) { + if ($this->tagIsAt($block->lineStart, $textChars, $i + 1)) { /* Next line is more table syntax. bail otu and let something else handle it */ break 2; } @@ -729,47 +701,40 @@ private function parseTableCells(string $token, array $textChars, int $from, arr $tmpCol['content'] = $buffer; $colsSoFar[] = $tmpCol; $start = $i + 1; - - return ['col' => $colsSoFar, 'remainderIdx' => $start]; + return array('col' => $colsSoFar, 'remainderIdx' => $start); } - private static function countChar(array $chars, array $text, int $position, int $max = 0) + private function countChar(array $chars, array $text, int $position, int $max = 0) { $i = 0; - while ($i < $max && false !== array_search($text[$position + $i], $chars, true)) { - ++$i; + while ($i < $max && array_search($text[$position + $i], $chars) !== false) { + $i++; } - return $i; } - private static function countCharReverse(array $chars, array $text, int $min, int $position) + private function countCharReverse(array $chars, array $text, int $min, int $position) { $i = 0; - while (($position - $i) > $min && false !== array_search($text[$position - $i], $chars, true)) { - ++$i; + while (($position - $i) > $min && array_search($text[$position - $i], $chars) !== false) { + $i++; } - return $i; } /** * Create a list from what we found in parseLineBlock(), returning all elements. */ - private static function makeList(array $lines) + private function makeList(array $lines) { - $list = self::findChildren($lines, 0, -1); - + $list = $this->findChildren($lines, 0, -1); return $list['child']; } /** - * Recursively nests list elements inside eachother, forming a hierachy to traverse when rendering. - * - * @param mixed $depth - * @param mixed $minKey + * Recursively nests list elements inside eachother, forming a hierachy to traverse when rendering */ - private static function findChildren(array $lines, $depth, $minKey) + private function findChildren(array $lines, $depth, $minKey) { $children = []; $not = []; @@ -789,7 +754,7 @@ private static function findChildren(array $lines, $depth, $minKey) /* For each child, list its children */ foreach ($children as $key => $child) { if (isset($children[$key])) { - $result = self::findChildren($children, $child['depth'], $key); + $result = $this->findChildren($children, $child['depth'], $key); $children[$key]['child'] = $result['child']; /* We know that all of this list's children are NOT children of this item (directly), so remove them from our records. */ @@ -806,6 +771,7 @@ private static function findChildren(array $lines, $depth, $minKey) } } - return ['child' => $children, 'not' => $not]; + return array('child' => $children, 'not' => $not); } + } diff --git a/README.md b/README.md index eff1502b41..eda1e434a6 100644 --- a/README.md +++ b/README.md @@ -33,7 +33,7 @@ You probably want to get started by checking out the code in `src/`. `build/` is deprecated and the code needs to be rewritten in `src/`. To make changes in **Javascript** bear in mind that the Webpack needs to process each change before it reflects on the site. -It is a good idea to run `yarn encore dev --watch` which will keep updating files as you keep saving them. +It is a good idea to run `bun encore dev --watch` which will keep updating files as you keep saving them. ## Documentation @@ -57,13 +57,88 @@ composer install --prefer-dist --no-progress --no-interaction --no-scripts Also run ```bash -yarn install --frozen-lock +bun i --frozen-lockfile ``` -everytime you see a change in either ```package.json``` or ```yarn.lock```. +everytime you see a change in either ```package.json``` or ```bun.lock```. If any ```.scss``` file or a file in ```assets/``` changed a ```make build``` is necessary. +## Production image & deployment :rocket: + +The production image is **built in CI, not on the deploy server**. The deploy host +only runs `docker compose pull && docker compose up -d` — there is no on-server +`docker compose ... --build` and no `composer install` on the server. + +### How the image is built + +The [`build-image`](.github/workflows/build-image.yml) workflow builds the +production `bewelcome_php` target from the [`Dockerfile`](Dockerfile) and pushes a +multi-arch (`linux/amd64` + `linux/arm64`) manifest to `ghcr.io/bewelcome/rox`. Each +architecture is built on a native runner (no QEMU) and pushed by digest, then a +merge job stitches the digests into one tagged manifest list so `docker pull` +resolves the right arch automatically. The image is self-contained: `vendor/` and +the compiled front-end assets (`public/build/`) are baked in at build time, so it +boots with no host checkout and no bind-mount of the source tree. + +It runs: + +* on every push to `develop` that touches image-affecting paths (`Dockerfile`, + `src/**`, `composer.lock`, `assets/**`, etc.), and +* on every `v*` tag push. + +Tags are produced by `docker/metadata-action`: + +| Tag | Meaning | +| --- | --- | +| `sha-` | Immutable per-commit pin — **use this to deploy and roll back** | +| `develop` | Moving pointer to the latest `develop` build (convenience only) | +| `vX.Y.Z`, `X.Y`, `X` | SemVer tags, published only for `v*` tag pushes | + +Every published image is scanned with [Trivy](https://trivy.dev/) (CRITICAL/HIGH/MEDIUM; +unfixed CVEs only). Results appear in the **Scan image** job log. + +After a successful push **on `develop`**, the workflow sends a `repository_dispatch` +(`event_type: rox-image-pushed`) to `BeWelcome/sysadmins-infra`, which deploys the +new `sha-` image to **stage** automatically — but **only if all three +gates pass**: + +1. the image build and push succeed, +2. the Trivy scan finds no CRITICAL/HIGH/MEDIUM unfixed vulnerabilities, and +3. the parallel [`CI`](.github/workflows/ci.yml) workflow on the same commit also + succeeds (phpunit, linters, security checks, etc.). + +If CI fails, the image may still be pushed to GHCR for inspection, but stage deploy +is blocked. The dispatch is *not* sent for `v*` tags — production releases are +triggered manually/gated from `sysadmins-infra`. + +### Cut a production release + +```bash +git tag vX.Y.Z +git push --tags +``` + +This publishes the SemVer image tags. Promote it to production from the +`sysadmins-infra` deploy workflow. + +### Roll back + +Redeploy a previous immutable tag from `sysadmins-infra` by pointing the deploy at +an earlier `ghcr.io/bewelcome/rox:sha-` (the digest is recorded in the +dispatch payload, so the rollback target is exact). + +### Required secrets + +The cross-repo dispatch authenticates as the `bewelcome-platform-deployer` GitHub +App (installed on `sysadmins-infra`). The workflow mints a short-lived installation +token at run time from two Actions secrets in this repo: + +* `DEPLOY_APP_ID` — the App's ID +* `DEPLOY_APP_PRIVATE_KEY` — the App's private key + +GHCR push itself uses the built-in `GITHUB_TOKEN` (`permissions: packages: write`). + ## Useful links * [Writing great Git commit messages](http://chris.beams.io/posts/git-commit/) * [Git crash course](http://git.or.cz/course/svn.html) diff --git a/Rox/Storage/Activities.php~ b/Rox/Storage/Activities.php~ deleted file mode 100644 index 2a8a3a9b34..0000000000 --- a/Rox/Storage/Activities.php~ +++ /dev/null @@ -1,89 +0,0 @@ -idmember = $idmember; - - return $this; - } - - /** - * Get idmember - * - * @return integer - */ - public function getIdmember() - { - return $this->idmember; - } - - /** - * Set housenumber - * - * @param integer $housenumber - * - * @return AddressesBeforeDataRetention - */ - public function setHousenumber($housenumber) - { - $this->housenumber = $housenumber; - - return $this; - } - - /** - * Get housenumber - * - * @return integer - */ - public function getHousenumber() - { - return $this->housenumber; - } - - /** - * Set streetname - * - * @param integer $streetname - * - * @return AddressesBeforeDataRetention - */ - public function setStreetname($streetname) - { - $this->streetname = $streetname; - - return $this; - } - - /** - * Get streetname - * - * @return integer - */ - public function getStreetname() - { - return $this->streetname; - } - - /** - * Set zip - * - * @param integer $zip - * - * @return AddressesBeforeDataRetention - */ - public function setZip($zip) - { - $this->zip = $zip; - - return $this; - } - - /** - * Get zip - * - * @return integer - */ - public function getZip() - { - return $this->zip; - } - - /** - * Set idcity - * - * @param integer $idcity - * - * @return AddressesBeforeDataRetention - */ - public function setIdcity($idcity) - { - $this->idcity = $idcity; - - return $this; - } - - /** - * Get idcity - * - * @return integer - */ - public function getIdcity() - { - return $this->idcity; - } - - /** - * Set explanation - * - * @param integer $explanation - * - * @return AddressesBeforeDataRetention - */ - public function setExplanation($explanation) - { - $this->explanation = $explanation; - - return $this; - } - - /** - * Get explanation - * - * @return integer - */ - public function getExplanation() - { - return $this->explanation; - } - - /** - * Set rank - * - * @param boolean $rank - * - * @return AddressesBeforeDataRetention - */ - public function setRank($rank) - { - $this->rank = $rank; - - return $this; - } - - /** - * Get rank - * - * @return boolean - */ - public function getRank() - { - return $this->rank; - } - - /** - * Set updated - * - * @param \DateTime $updated - * - * @return AddressesBeforeDataRetention - */ - public function setUpdated($updated) - { - $this->updated = $updated; - - return $this; - } - - /** - * Get updated - * - * @return \DateTime - */ - public function getUpdated() - { - return $this->updated; - } - - /** - * Set created - * - * @param \DateTime $created - * - * @return AddressesBeforeDataRetention - */ - public function setCreated($created) - { - $this->created = $created; - - return $this; - } - - /** - * Get created - * - * @return \DateTime - */ - public function getCreated() - { - return $this->created; - } - - /** - * Set idgettingthere - * - * @param integer $idgettingthere - * - * @return AddressesBeforeDataRetention - */ - public function setIdgettingthere($idgettingthere) - { - $this->idgettingthere = $idgettingthere; - - return $this; - } - - /** - * Get idgettingthere - * - * @return integer - */ - public function getIdgettingthere() - { - return $this->idgettingthere; - } - - /** - * Get id - * - * @return integer - */ - public function getId() - { - return $this->id; - } -} diff --git a/Rox/Storage/AddressesBeforeDataRetention.php~ b/Rox/Storage/AddressesBeforeDataRetention.php~ deleted file mode 100644 index a88eca20c4..0000000000 --- a/Rox/Storage/AddressesBeforeDataRetention.php~ +++ /dev/null @@ -1,96 +0,0 @@ -flags = $flags; - - return $this; - } - - /** - * Get flags - * - * @return string - */ - public function getFlags() - { - return $this->flags; - } - - /** - * Set blogCreated - * - * @param \DateTime $blogCreated - * - * @return Blog - */ - public function setBlogCreated($blogCreated) - { - $this->blogCreated = $blogCreated; - - return $this; - } - - /** - * Get blogCreated - * - * @return \DateTime - */ - public function getBlogCreated() - { - return $this->blogCreated; - } - - /** - * Set countryIdForeign - * - * @param integer $countryIdForeign - * - * @return Blog - */ - public function setCountryIdForeign($countryIdForeign) - { - $this->countryIdForeign = $countryIdForeign; - - return $this; - } - - /** - * Get countryIdForeign - * - * @return integer - */ - public function getCountryIdForeign() - { - return $this->countryIdForeign; - } - - /** - * Set tripIdForeign - * - * @param integer $tripIdForeign - * - * @return Blog - */ - public function setTripIdForeign($tripIdForeign) - { - $this->tripIdForeign = $tripIdForeign; - - return $this; - } - - /** - * Get tripIdForeign - * - * @return integer - */ - public function getTripIdForeign() - { - return $this->tripIdForeign; - } - - /** - * Set idmember - * - * @param integer $idmember - * - * @return Blog - */ - public function setIdmember($idmember) - { - $this->idmember = $idmember; - - return $this; - } - - /** - * Get idmember - * - * @return integer - */ - public function getIdmember() - { - return $this->idmember; - } - - /** - * Get blogId - * - * @return integer - */ - public function getBlogId() - { - return $this->blogId; - } -} diff --git a/Rox/Storage/Blog.php~ b/Rox/Storage/Blog.php~ deleted file mode 100644 index ccba12f047..0000000000 --- a/Rox/Storage/Blog.php~ +++ /dev/null @@ -1,61 +0,0 @@ -name = $name; - - return $this; - } - - /** - * Get name - * - * @return string - */ - public function getName() - { - return $this->name; - } - - /** - * Set idmember - * - * @param integer $idmember - * - * @return BlogCategories - */ - public function setIdmember($idmember) - { - $this->idmember = $idmember; - - return $this; - } - - /** - * Get idmember - * - * @return integer - */ - public function getIdmember() - { - return $this->idmember; - } - - /** - * Get blogCategoryId - * - * @return integer - */ - public function getBlogCategoryId() - { - return $this->blogCategoryId; - } -} diff --git a/Rox/Storage/BlogCategories.php~ b/Rox/Storage/BlogCategories.php~ deleted file mode 100644 index 49c073d428..0000000000 --- a/Rox/Storage/BlogCategories.php~ +++ /dev/null @@ -1,40 +0,0 @@ -id; - } -} diff --git a/Rox/Storage/BlogCategoriesSeq.php~ b/Rox/Storage/BlogCategoriesSeq.php~ deleted file mode 100644 index 9758ac21c7..0000000000 --- a/Rox/Storage/BlogCategoriesSeq.php~ +++ /dev/null @@ -1,26 +0,0 @@ -blogIdForeign = $blogIdForeign; - - return $this; - } - - /** - * Get blogIdForeign - * - * @return integer - */ - public function getBlogIdForeign() - { - return $this->blogIdForeign; - } - - /** - * Set created - * - * @param \DateTime $created - * - * @return BlogComments - */ - public function setCreated($created) - { - $this->created = $created; - - return $this; - } - - /** - * Get created - * - * @return \DateTime - */ - public function getCreated() - { - return $this->created; - } - - /** - * Set title - * - * @param string $title - * - * @return BlogComments - */ - public function setTitle($title) - { - $this->title = $title; - - return $this; - } - - /** - * Get title - * - * @return string - */ - public function getTitle() - { - return $this->title; - } - - /** - * Set text - * - * @param string $text - * - * @return BlogComments - */ - public function setText($text) - { - $this->text = $text; - - return $this; - } - - /** - * Get text - * - * @return string - */ - public function getText() - { - return $this->text; - } - - /** - * Set idmember - * - * @param integer $idmember - * - * @return BlogComments - */ - public function setIdmember($idmember) - { - $this->idmember = $idmember; - - return $this; - } - - /** - * Get idmember - * - * @return integer - */ - public function getIdmember() - { - return $this->idmember; - } - - /** - * Get id - * - * @return integer - */ - public function getId() - { - return $this->id; - } -} diff --git a/Rox/Storage/BlogComments.php~ b/Rox/Storage/BlogComments.php~ deleted file mode 100644 index 21fdb89d27..0000000000 --- a/Rox/Storage/BlogComments.php~ +++ /dev/null @@ -1,61 +0,0 @@ -id; - } -} diff --git a/Rox/Storage/BlogCommentsSeq.php~ b/Rox/Storage/BlogCommentsSeq.php~ deleted file mode 100644 index 1bb6ba74b4..0000000000 --- a/Rox/Storage/BlogCommentsSeq.php~ +++ /dev/null @@ -1,26 +0,0 @@ -edited = $edited; - - return $this; - } - - /** - * Get edited - * - * @return \DateTime - */ - public function getEdited() - { - return $this->edited; - } - - /** - * Set blogTitle - * - * @param string $blogTitle - * - * @return BlogData - */ - public function setBlogTitle($blogTitle) - { - $this->blogTitle = $blogTitle; - - return $this; - } - - /** - * Get blogTitle - * - * @return string - */ - public function getBlogTitle() - { - return $this->blogTitle; - } - - /** - * Set blogText - * - * @param string $blogText - * - * @return BlogData - */ - public function setBlogText($blogText) - { - $this->blogText = $blogText; - - return $this; - } - - /** - * Get blogText - * - * @return string - */ - public function getBlogText() - { - return $this->blogText; - } - - /** - * Set blogStart - * - * @param \DateTime $blogStart - * - * @return BlogData - */ - public function setBlogStart($blogStart) - { - $this->blogStart = $blogStart; - - return $this; - } - - /** - * Get blogStart - * - * @return \DateTime - */ - public function getBlogStart() - { - return $this->blogStart; - } - - /** - * Set blogEnd - * - * @param \DateTime $blogEnd - * - * @return BlogData - */ - public function setBlogEnd($blogEnd) - { - $this->blogEnd = $blogEnd; - - return $this; - } - - /** - * Get blogEnd - * - * @return \DateTime - */ - public function getBlogEnd() - { - return $this->blogEnd; - } - - /** - * Set blogLatitude - * - * @param float $blogLatitude - * - * @return BlogData - */ - public function setBlogLatitude($blogLatitude) - { - $this->blogLatitude = $blogLatitude; - - return $this; - } - - /** - * Get blogLatitude - * - * @return float - */ - public function getBlogLatitude() - { - return $this->blogLatitude; - } - - /** - * Set blogLongitude - * - * @param float $blogLongitude - * - * @return BlogData - */ - public function setBlogLongitude($blogLongitude) - { - $this->blogLongitude = $blogLongitude; - - return $this; - } - - /** - * Get blogLongitude - * - * @return float - */ - public function getBlogLongitude() - { - return $this->blogLongitude; - } - - /** - * Set blogGeonameid - * - * @param integer $blogGeonameid - * - * @return BlogData - */ - public function setBlogGeonameid($blogGeonameid) - { - $this->blogGeonameid = $blogGeonameid; - - return $this; - } - - /** - * Get blogGeonameid - * - * @return integer - */ - public function getBlogGeonameid() - { - return $this->blogGeonameid; - } - - /** - * Set blogDisplayOrder - * - * @param integer $blogDisplayOrder - * - * @return BlogData - */ - public function setBlogDisplayOrder($blogDisplayOrder) - { - $this->blogDisplayOrder = $blogDisplayOrder; - - return $this; - } - - /** - * Get blogDisplayOrder - * - * @return integer - */ - public function getBlogDisplayOrder() - { - return $this->blogDisplayOrder; - } - - /** - * Get blogId - * - * @return integer - */ - public function getBlogId() - { - return $this->blogId; - } -} diff --git a/Rox/Storage/BlogData.php~ b/Rox/Storage/BlogData.php~ deleted file mode 100644 index ff7b1afe09..0000000000 --- a/Rox/Storage/BlogData.php~ +++ /dev/null @@ -1,89 +0,0 @@ -id; - } -} diff --git a/Rox/Storage/BlogSeq.php~ b/Rox/Storage/BlogSeq.php~ deleted file mode 100644 index 7683f8e911..0000000000 --- a/Rox/Storage/BlogSeq.php~ +++ /dev/null @@ -1,26 +0,0 @@ -name = $name; - - return $this; - } - - /** - * Get name - * - * @return string - */ - public function getName() - { - return $this->name; - } - - /** - * Get blogTagId - * - * @return integer - */ - public function getBlogTagId() - { - return $this->blogTagId; - } -} diff --git a/Rox/Storage/BlogTags.php~ b/Rox/Storage/BlogTags.php~ deleted file mode 100644 index 3be35780f5..0000000000 --- a/Rox/Storage/BlogTags.php~ +++ /dev/null @@ -1,33 +0,0 @@ -id; - } -} diff --git a/Rox/Storage/BlogTagsSeq.php~ b/Rox/Storage/BlogTagsSeq.php~ deleted file mode 100644 index 899176bed6..0000000000 --- a/Rox/Storage/BlogTagsSeq.php~ +++ /dev/null @@ -1,26 +0,0 @@ -created = $created; - - return $this; - } - - /** - * Get created - * - * @return \DateTime - */ - public function getCreated() - { - return $this->created; - } - - /** - * Set blogCategoryIdForeign - * - * @param integer $blogCategoryIdForeign - * - * @return BlogToCategory - */ - public function setBlogCategoryIdForeign($blogCategoryIdForeign) - { - $this->blogCategoryIdForeign = $blogCategoryIdForeign; - - return $this; - } - - /** - * Get blogCategoryIdForeign - * - * @return integer - */ - public function getBlogCategoryIdForeign() - { - return $this->blogCategoryIdForeign; - } - - /** - * Set blogIdForeign - * - * @param integer $blogIdForeign - * - * @return BlogToCategory - */ - public function setBlogIdForeign($blogIdForeign) - { - $this->blogIdForeign = $blogIdForeign; - - return $this; - } - - /** - * Get blogIdForeign - * - * @return integer - */ - public function getBlogIdForeign() - { - return $this->blogIdForeign; - } - - /** - * Get id - * - * @return integer - */ - public function getId() - { - return $this->id; - } -} diff --git a/Rox/Storage/BlogToCategory.php~ b/Rox/Storage/BlogToCategory.php~ deleted file mode 100644 index 1075f70844..0000000000 --- a/Rox/Storage/BlogToCategory.php~ +++ /dev/null @@ -1,47 +0,0 @@ -blogIdForeign = $blogIdForeign; - - return $this; - } - - /** - * Get blogIdForeign - * - * @return integer - */ - public function getBlogIdForeign() - { - return $this->blogIdForeign; - } - - /** - * Set blogTagIdForeign - * - * @param integer $blogTagIdForeign - * - * @return BlogToTag - */ - public function setBlogTagIdForeign($blogTagIdForeign) - { - $this->blogTagIdForeign = $blogTagIdForeign; - - return $this; - } - - /** - * Get blogTagIdForeign - * - * @return integer - */ - public function getBlogTagIdForeign() - { - return $this->blogTagIdForeign; - } - - /** - * Get id - * - * @return integer - */ - public function getId() - { - return $this->id; - } -} diff --git a/Rox/Storage/BlogToTag.php~ b/Rox/Storage/BlogToTag.php~ deleted file mode 100644 index 54a313e897..0000000000 --- a/Rox/Storage/BlogToTag.php~ +++ /dev/null @@ -1,40 +0,0 @@ -nbcities = $nbcities; - - return $this; - } - - /** - * Get nbcities - * - * @return integer - */ - public function getNbcities() - { - return $this->nbcities; - } - - /** - * Get idregion - * - * @return integer - */ - public function getIdregion() - { - return $this->idregion; - } -} diff --git a/Rox/Storage/CountersRegionsNbcities.php~ b/Rox/Storage/CountersRegionsNbcities.php~ deleted file mode 100644 index 3efe406f5e..0000000000 --- a/Rox/Storage/CountersRegionsNbcities.php~ +++ /dev/null @@ -1,33 +0,0 @@ -created = $created; - - return $this; - } - - /** - * Get created - * - * @return \DateTime - */ - public function getCreated() - { - return $this->created; - } - - /** - * Set active - * - * @param integer $active - * - * @return Dbversion - */ - public function setActive($active) - { - $this->active = $active; - - return $this; - } - - /** - * Get active - * - * @return integer - */ - public function getActive() - { - return $this->active; - } - - /** - * Get version - * - * @return integer - */ - public function getVersion() - { - return $this->version; - } -} diff --git a/Rox/Storage/Dbversion.php~ b/Rox/Storage/Dbversion.php~ deleted file mode 100644 index 84d274bd7b..0000000000 --- a/Rox/Storage/Dbversion.php~ +++ /dev/null @@ -1,40 +0,0 @@ -idmember = $idmember; - - return $this; - } - - /** - * Get idmember - * - * @return integer - */ - public function getIdmember() - { - return $this->idmember; - } - - /** - * Set email - * - * @param string $email - * - * @return Donations - */ - public function setEmail($email) - { - $this->email = $email; - - return $this; - } - - /** - * Get email - * - * @return string - */ - public function getEmail() - { - return $this->email; - } - - /** - * Set statusprivate - * - * @param string $statusprivate - * - * @return Donations - */ - public function setStatusprivate($statusprivate) - { - $this->statusprivate = $statusprivate; - - return $this; - } - - /** - * Get statusprivate - * - * @return string - */ - public function getStatusprivate() - { - return $this->statusprivate; - } - - /** - * Set created - * - * @param \DateTime $created - * - * @return Donations - */ - public function setCreated($created) - { - $this->created = $created; - - return $this; - } - - /** - * Get created - * - * @return \DateTime - */ - public function getCreated() - { - return $this->created; - } - - /** - * Set amount - * - * @param string $amount - * - * @return Donations - */ - public function setAmount($amount) - { - $this->amount = $amount; - - return $this; - } - - /** - * Get amount - * - * @return string - */ - public function getAmount() - { - return $this->amount; - } - - /** - * Set money - * - * @param string $money - * - * @return Donations - */ - public function setMoney($money) - { - $this->money = $money; - - return $this; - } - - /** - * Get money - * - * @return string - */ - public function getMoney() - { - return $this->money; - } - - /** - * Set idcountry - * - * @param integer $idcountry - * - * @return Donations - */ - public function setIdcountry($idcountry) - { - $this->idcountry = $idcountry; - - return $this; - } - - /** - * Get idcountry - * - * @return integer - */ - public function getIdcountry() - { - return $this->idcountry; - } - - /** - * Set namegiven - * - * @param string $namegiven - * - * @return Donations - */ - public function setNamegiven($namegiven) - { - $this->namegiven = $namegiven; - - return $this; - } - - /** - * Get namegiven - * - * @return string - */ - public function getNamegiven() - { - return $this->namegiven; - } - - /** - * Set referencepaypal - * - * @param string $referencepaypal - * - * @return Donations - */ - public function setReferencepaypal($referencepaypal) - { - $this->referencepaypal = $referencepaypal; - - return $this; - } - - /** - * Get referencepaypal - * - * @return string - */ - public function getReferencepaypal() - { - return $this->referencepaypal; - } - - /** - * Set membercomment - * - * @param string $membercomment - * - * @return Donations - */ - public function setMembercomment($membercomment) - { - $this->membercomment = $membercomment; - - return $this; - } - - /** - * Get membercomment - * - * @return string - */ - public function getMembercomment() - { - return $this->membercomment; - } - - /** - * Set systemcomment - * - * @param string $systemcomment - * - * @return Donations - */ - public function setSystemcomment($systemcomment) - { - $this->systemcomment = $systemcomment; - - return $this; - } - - /** - * Get systemcomment - * - * @return string - */ - public function getSystemcomment() - { - return $this->systemcomment; - } - - /** - * Get id - * - * @return integer - */ - public function getId() - { - return $this->id; - } -} diff --git a/Rox/Storage/Donations.php~ b/Rox/Storage/Donations.php~ deleted file mode 100644 index 0139318f90..0000000000 --- a/Rox/Storage/Donations.php~ +++ /dev/null @@ -1,103 +0,0 @@ -choice = $choice; - - return $this; - } - - /** - * Get choice - * - * @return string - */ - public function getChoice() - { - return $this->choice; - } - - /** - * Set updated - * - * @param \DateTime $updated - * - * @return ForumsPostsVotes - */ - public function setUpdated($updated) - { - $this->updated = $updated; - - return $this; - } - - /** - * Get updated - * - * @return \DateTime - */ - public function getUpdated() - { - return $this->updated; - } - - /** - * Set created - * - * @param \DateTime $created - * - * @return ForumsPostsVotes - */ - public function setCreated($created) - { - $this->created = $created; - - return $this; - } - - /** - * Get created - * - * @return \DateTime - */ - public function getCreated() - { - return $this->created; - } - - /** - * Set nbupdates - * - * @param integer $nbupdates - * - * @return ForumsPostsVotes - */ - public function setNbupdates($nbupdates) - { - $this->nbupdates = $nbupdates; - - return $this; - } - - /** - * Get nbupdates - * - * @return integer - */ - public function getNbupdates() - { - return $this->nbupdates; - } - - /** - * Set idpost - * - * @param integer $idpost - * - * @return ForumsPostsVotes - */ - public function setIdpost($idpost) - { - $this->idpost = $idpost; - - return $this; - } - - /** - * Get idpost - * - * @return integer - */ - public function getIdpost() - { - return $this->idpost; - } - - /** - * Set idcontributor - * - * @param integer $idcontributor - * - * @return ForumsPostsVotes - */ - public function setIdcontributor($idcontributor) - { - $this->idcontributor = $idcontributor; - - return $this; - } - - /** - * Get idcontributor - * - * @return integer - */ - public function getIdcontributor() - { - return $this->idcontributor; - } -} diff --git a/Rox/Storage/ForumsPostsVotes.php~ b/Rox/Storage/ForumsPostsVotes.php~ deleted file mode 100644 index 797606afa5..0000000000 --- a/Rox/Storage/ForumsPostsVotes.php~ +++ /dev/null @@ -1,63 +0,0 @@ -id; - } -} diff --git a/Rox/Storage/GalleryCommentsSeq.php~ b/Rox/Storage/GalleryCommentsSeq.php~ deleted file mode 100644 index 260d8c420a..0000000000 --- a/Rox/Storage/GalleryCommentsSeq.php~ +++ /dev/null @@ -1,26 +0,0 @@ -id; - } -} diff --git a/Rox/Storage/GalleryItemsSeq.php~ b/Rox/Storage/GalleryItemsSeq.php~ deleted file mode 100644 index de3c31b90a..0000000000 --- a/Rox/Storage/GalleryItemsSeq.php~ +++ /dev/null @@ -1,26 +0,0 @@ -itemIdForeign = $itemIdForeign; - - return $this; - } - - /** - * Get itemIdForeign - * - * @return integer - */ - public function getItemIdForeign() - { - return $this->itemIdForeign; - } - - /** - * Set galleryIdForeign - * - * @param integer $galleryIdForeign - * - * @return GalleryItemsToGallery - */ - public function setGalleryIdForeign($galleryIdForeign) - { - $this->galleryIdForeign = $galleryIdForeign; - - return $this; - } - - /** - * Get galleryIdForeign - * - * @return integer - */ - public function getGalleryIdForeign() - { - return $this->galleryIdForeign; - } - - /** - * Get id - * - * @return integer - */ - public function getId() - { - return $this->id; - } -} diff --git a/Rox/Storage/GalleryItemsToGallery.php~ b/Rox/Storage/GalleryItemsToGallery.php~ deleted file mode 100644 index a0c0ef8967..0000000000 --- a/Rox/Storage/GalleryItemsToGallery.php~ +++ /dev/null @@ -1,40 +0,0 @@ -id; - } -} diff --git a/Rox/Storage/GallerySeq.php~ b/Rox/Storage/GallerySeq.php~ deleted file mode 100644 index d686b4d261..0000000000 --- a/Rox/Storage/GallerySeq.php~ +++ /dev/null @@ -1,26 +0,0 @@ -countryCode = $countryCode; - - return $this; - } - - /** - * Get countryCode - * - * @return string - */ - public function getCountryCode() - { - return $this->countryCode; - } - - /** - * Set adminCode - * - * @param string $adminCode - * - * @return GeonamesAdmincodes - */ - public function setAdminCode($adminCode) - { - $this->adminCode = $adminCode; - - return $this; - } - - /** - * Get adminCode - * - * @return string - */ - public function getAdminCode() - { - return $this->adminCode; - } - - /** - * Set name - * - * @param string $name - * - * @return GeonamesAdmincodes - */ - public function setName($name) - { - $this->name = $name; - - return $this; - } - - /** - * Get name - * - * @return string - */ - public function getName() - { - return $this->name; - } - - /** - * Get code - * - * @return string - */ - public function getCode() - { - return $this->code; - } -} diff --git a/Rox/Storage/GeonamesAdmincodes.php~ b/Rox/Storage/GeonamesAdmincodes.php~ deleted file mode 100644 index 41c2687e88..0000000000 --- a/Rox/Storage/GeonamesAdmincodes.php~ +++ /dev/null @@ -1,47 +0,0 @@ -latitude = $latitude; - - return $this; - } - - /** - * Get latitude - * - * @return float - */ - public function getLatitude() - { - return $this->latitude; - } - - /** - * Set longitude - * - * @param float $longitude - * - * @return GeonamesCache - */ - public function setLongitude($longitude) - { - $this->longitude = $longitude; - - return $this; - } - - /** - * Get longitude - * - * @return float - */ - public function getLongitude() - { - return $this->longitude; - } - - /** - * Set name - * - * @param string $name - * - * @return GeonamesCache - */ - public function setName($name) - { - $this->name = $name; - - return $this; - } - - /** - * Get name - * - * @return string - */ - public function getName() - { - return $this->name; - } - - /** - * Set population - * - * @param integer $population - * - * @return GeonamesCache - */ - public function setPopulation($population) - { - $this->population = $population; - - return $this; - } - - /** - * Get population - * - * @return integer - */ - public function getPopulation() - { - return $this->population; - } - - /** - * Set fkCountrycode - * - * @param string $fkCountrycode - * - * @return GeonamesCache - */ - public function setFkCountrycode($fkCountrycode) - { - $this->fkCountrycode = $fkCountrycode; - - return $this; - } - - /** - * Get fkCountrycode - * - * @return string - */ - public function getFkCountrycode() - { - return $this->fkCountrycode; - } - - /** - * Set fkAdmincode - * - * @param string $fkAdmincode - * - * @return GeonamesCache - */ - public function setFkAdmincode($fkAdmincode) - { - $this->fkAdmincode = $fkAdmincode; - - return $this; - } - - /** - * Get fkAdmincode - * - * @return string - */ - public function getFkAdmincode() - { - return $this->fkAdmincode; - } - - /** - * Set fclass - * - * @param string $fclass - * - * @return GeonamesCache - */ - public function setFclass($fclass) - { - $this->fclass = $fclass; - - return $this; - } - - /** - * Get fclass - * - * @return string - */ - public function getFclass() - { - return $this->fclass; - } - - /** - * Set fcode - * - * @param string $fcode - * - * @return GeonamesCache - */ - public function setFcode($fcode) - { - $this->fcode = $fcode; - - return $this; - } - - /** - * Get fcode - * - * @return string - */ - public function getFcode() - { - return $this->fcode; - } - - /** - * Set timezone - * - * @param integer $timezone - * - * @return GeonamesCache - */ - public function setTimezone($timezone) - { - $this->timezone = $timezone; - - return $this; - } - - /** - * Get timezone - * - * @return integer - */ - public function getTimezone() - { - return $this->timezone; - } - - /** - * Set parentadm1id - * - * @param integer $parentadm1id - * - * @return GeonamesCache - */ - public function setParentadm1id($parentadm1id) - { - $this->parentadm1id = $parentadm1id; - - return $this; - } - - /** - * Get parentadm1id - * - * @return integer - */ - public function getParentadm1id() - { - return $this->parentadm1id; - } - - /** - * Set parentcountryid - * - * @param integer $parentcountryid - * - * @return GeonamesCache - */ - public function setParentcountryid($parentcountryid) - { - $this->parentcountryid = $parentcountryid; - - return $this; - } - - /** - * Get parentcountryid - * - * @return integer - */ - public function getParentcountryid() - { - return $this->parentcountryid; - } - - /** - * Get geonameid - * - * @return integer - */ - public function getGeonameid() - { - return $this->geonameid; - } -} diff --git a/Rox/Storage/GeonamesCache.php~ b/Rox/Storage/GeonamesCache.php~ deleted file mode 100644 index fb7feb5e86..0000000000 --- a/Rox/Storage/GeonamesCache.php~ +++ /dev/null @@ -1,103 +0,0 @@ -geonameid = $geonameid; - - return $this; - } - - /** - * Get geonameid - * - * @return integer - */ - public function getGeonameid() - { - return $this->geonameid; - } - - /** - * Set latitude - * - * @param float $latitude - * - * @return GeonamesCacheBackup - */ - public function setLatitude($latitude) - { - $this->latitude = $latitude; - - return $this; - } - - /** - * Get latitude - * - * @return float - */ - public function getLatitude() - { - return $this->latitude; - } - - /** - * Set longitude - * - * @param float $longitude - * - * @return GeonamesCacheBackup - */ - public function setLongitude($longitude) - { - $this->longitude = $longitude; - - return $this; - } - - /** - * Get longitude - * - * @return float - */ - public function getLongitude() - { - return $this->longitude; - } - - /** - * Set name - * - * @param string $name - * - * @return GeonamesCacheBackup - */ - public function setName($name) - { - $this->name = $name; - - return $this; - } - - /** - * Get name - * - * @return string - */ - public function getName() - { - return $this->name; - } - - /** - * Set population - * - * @param integer $population - * - * @return GeonamesCacheBackup - */ - public function setPopulation($population) - { - $this->population = $population; - - return $this; - } - - /** - * Get population - * - * @return integer - */ - public function getPopulation() - { - return $this->population; - } - - /** - * Set fclass - * - * @param string $fclass - * - * @return GeonamesCacheBackup - */ - public function setFclass($fclass) - { - $this->fclass = $fclass; - - return $this; - } - - /** - * Get fclass - * - * @return string - */ - public function getFclass() - { - return $this->fclass; - } - - /** - * Set fcode - * - * @param string $fcode - * - * @return GeonamesCacheBackup - */ - public function setFcode($fcode) - { - $this->fcode = $fcode; - - return $this; - } - - /** - * Get fcode - * - * @return string - */ - public function getFcode() - { - return $this->fcode; - } - - /** - * Set fkCountrycode - * - * @param string $fkCountrycode - * - * @return GeonamesCacheBackup - */ - public function setFkCountrycode($fkCountrycode) - { - $this->fkCountrycode = $fkCountrycode; - - return $this; - } - - /** - * Get fkCountrycode - * - * @return string - */ - public function getFkCountrycode() - { - return $this->fkCountrycode; - } - - /** - * Set fkAdmincode - * - * @param string $fkAdmincode - * - * @return GeonamesCacheBackup - */ - public function setFkAdmincode($fkAdmincode) - { - $this->fkAdmincode = $fkAdmincode; - - return $this; - } - - /** - * Get fkAdmincode - * - * @return string - */ - public function getFkAdmincode() - { - return $this->fkAdmincode; - } - - /** - * Set timezone - * - * @param integer $timezone - * - * @return GeonamesCacheBackup - */ - public function setTimezone($timezone) - { - $this->timezone = $timezone; - - return $this; - } - - /** - * Get timezone - * - * @return integer - */ - public function getTimezone() - { - return $this->timezone; - } - - /** - * Set dateUpdated - * - * @param \DateTime $dateUpdated - * - * @return GeonamesCacheBackup - */ - public function setDateUpdated($dateUpdated) - { - $this->dateUpdated = $dateUpdated; - - return $this; - } - - /** - * Get dateUpdated - * - * @return \DateTime - */ - public function getDateUpdated() - { - return $this->dateUpdated; - } - - /** - * Set parentid - * - * @param integer $parentid - * - * @return GeonamesCacheBackup - */ - public function setParentid($parentid) - { - $this->parentid = $parentid; - - return $this; - } - - /** - * Get parentid - * - * @return integer - */ - public function getParentid() - { - return $this->parentid; - } - - /** - * Set parentadm1id - * - * @param integer $parentadm1id - * - * @return GeonamesCacheBackup - */ - public function setParentadm1id($parentadm1id) - { - $this->parentadm1id = $parentadm1id; - - return $this; - } - - /** - * Get parentadm1id - * - * @return integer - */ - public function getParentadm1id() - { - return $this->parentadm1id; - } - - /** - * Set parentcountryid - * - * @param integer $parentcountryid - * - * @return GeonamesCacheBackup - */ - public function setParentcountryid($parentcountryid) - { - $this->parentcountryid = $parentcountryid; - - return $this; - } - - /** - * Get parentcountryid - * - * @return integer - */ - public function getParentcountryid() - { - return $this->parentcountryid; - } - - /** - * Get id - * - * @return integer - */ - public function getId() - { - return $this->id; - } -} diff --git a/Rox/Storage/GeonamesCacheBackup.php~ b/Rox/Storage/GeonamesCacheBackup.php~ deleted file mode 100644 index 8a5375fc18..0000000000 --- a/Rox/Storage/GeonamesCacheBackup.php~ +++ /dev/null @@ -1,124 +0,0 @@ -geonameid = $geonameid; - - return $this; - } - - /** - * Get geonameid - * - * @return integer - */ - public function getGeonameid() - { - return $this->geonameid; - } - - /** - * Set name - * - * @param string $name - * - * @return GeonamesCountries - */ - public function setName($name) - { - $this->name = $name; - - return $this; - } - - /** - * Get name - * - * @return string - */ - public function getName() - { - return $this->name; - } - - /** - * Set continent - * - * @param string $continent - * - * @return GeonamesCountries - */ - public function setContinent($continent) - { - $this->continent = $continent; - - return $this; - } - - /** - * Get continent - * - * @return string - */ - public function getContinent() - { - return $this->continent; - } - - /** - * Get country - * - * @return string - */ - public function getCountry() - { - return $this->country; - } -} diff --git a/Rox/Storage/GeonamesCountries.php~ b/Rox/Storage/GeonamesCountries.php~ deleted file mode 100644 index c2ee9278ef..0000000000 --- a/Rox/Storage/GeonamesCountries.php~ +++ /dev/null @@ -1,47 +0,0 @@ -offsetjanuary = $offsetjanuary; - - return $this; - } - - /** - * Get offsetjanuary - * - * @return string - */ - public function getOffsetjanuary() - { - return $this->offsetjanuary; - } - - /** - * Set offsetjuly - * - * @param string $offsetjuly - * - * @return GeonamesTimezones - */ - public function setOffsetjuly($offsetjuly) - { - $this->offsetjuly = $offsetjuly; - - return $this; - } - - /** - * Get offsetjuly - * - * @return string - */ - public function getOffsetjuly() - { - return $this->offsetjuly; - } - - /** - * Get timezoneid - * - * @return integer - */ - public function getTimezoneid() - { - return $this->timezoneid; - } -} diff --git a/Rox/Storage/GeonamesTimezones.php~ b/Rox/Storage/GeonamesTimezones.php~ deleted file mode 100644 index a00934e738..0000000000 --- a/Rox/Storage/GeonamesTimezones.php~ +++ /dev/null @@ -1,40 +0,0 @@ -name = $name; - - return $this; - } - - /** - * Get name - * - * @return string - */ - public function getName() - { - return $this->name; - } - - /** - * Set fclass - * - * @param string $fclass - * - * @return Geonamesadminunits - */ - public function setFclass($fclass) - { - $this->fclass = $fclass; - - return $this; - } - - /** - * Get fclass - * - * @return string - */ - public function getFclass() - { - return $this->fclass; - } - - /** - * Set fcode - * - * @param string $fcode - * - * @return Geonamesadminunits - */ - public function setFcode($fcode) - { - $this->fcode = $fcode; - - return $this; - } - - /** - * Get fcode - * - * @return string - */ - public function getFcode() - { - return $this->fcode; - } - - /** - * Set country - * - * @param string $country - * - * @return Geonamesadminunits - */ - public function setCountry($country) - { - $this->country = $country; - - return $this; - } - - /** - * Get country - * - * @return string - */ - public function getCountry() - { - return $this->country; - } - - /** - * Set admin1 - * - * @param string $admin1 - * - * @return Geonamesadminunits - */ - public function setAdmin1($admin1) - { - $this->admin1 = $admin1; - - return $this; - } - - /** - * Get admin1 - * - * @return string - */ - public function getAdmin1() - { - return $this->admin1; - } - - /** - * Set moddate - * - * @param \DateTime $moddate - * - * @return Geonamesadminunits - */ - public function setModdate($moddate) - { - $this->moddate = $moddate; - - return $this; - } - - /** - * Get moddate - * - * @return \DateTime - */ - public function getModdate() - { - return $this->moddate; - } - - /** - * Get geonameid - * - * @return integer - */ - public function getGeonameid() - { - return $this->geonameid; - } -} diff --git a/Rox/Storage/Geonamesadminunits.php~ b/Rox/Storage/Geonamesadminunits.php~ deleted file mode 100644 index ce962af333..0000000000 --- a/Rox/Storage/Geonamesadminunits.php~ +++ /dev/null @@ -1,68 +0,0 @@ -isolanguage = $isolanguage; - - return $this; - } - - /** - * Get isolanguage - * - * @return string - */ - public function getIsolanguage() - { - return $this->isolanguage; - } - - /** - * Set alternatename - * - * @param string $alternatename - * - * @return Geonamesalternatenames - */ - public function setAlternatename($alternatename) - { - $this->alternatename = $alternatename; - - return $this; - } - - /** - * Get alternatename - * - * @return string - */ - public function getAlternatename() - { - return $this->alternatename; - } - - /** - * Set ispreferred - * - * @param boolean $ispreferred - * - * @return Geonamesalternatenames - */ - public function setIspreferred($ispreferred) - { - $this->ispreferred = $ispreferred; - - return $this; - } - - /** - * Get ispreferred - * - * @return boolean - */ - public function getIspreferred() - { - return $this->ispreferred; - } - - /** - * Set isshort - * - * @param boolean $isshort - * - * @return Geonamesalternatenames - */ - public function setIsshort($isshort) - { - $this->isshort = $isshort; - - return $this; - } - - /** - * Get isshort - * - * @return boolean - */ - public function getIsshort() - { - return $this->isshort; - } - - /** - * Set iscolloquial - * - * @param boolean $iscolloquial - * - * @return Geonamesalternatenames - */ - public function setIscolloquial($iscolloquial) - { - $this->iscolloquial = $iscolloquial; - - return $this; - } - - /** - * Get iscolloquial - * - * @return boolean - */ - public function getIscolloquial() - { - return $this->iscolloquial; - } - - /** - * Set ishistoric - * - * @param boolean $ishistoric - * - * @return Geonamesalternatenames - */ - public function setIshistoric($ishistoric) - { - $this->ishistoric = $ishistoric; - - return $this; - } - - /** - * Get ishistoric - * - * @return boolean - */ - public function getIshistoric() - { - return $this->ishistoric; - } - - /** - * Get alternatenameid - * - * @return integer - */ - public function getAlternatenameid() - { - return $this->alternatenameid; - } - - /** - * Set geonameid - * - * @param \App\Entity\Geonames $geonameid - * - * @return Geonamesalternatenames - */ - public function setGeonameid(\App\Entity\Geonames $geonameid = null) - { - $this->geonameid = $geonameid; - - return $this; - } - - /** - * Get geonameid - * - * @return \App\Entity\Geonames - */ - public function getGeonameid() - { - return $this->geonameid; - } -} diff --git a/Rox/Storage/Geonamesalternatenames.php~ b/Rox/Storage/Geonamesalternatenames.php~ deleted file mode 100644 index b7d4879d70..0000000000 --- a/Rox/Storage/Geonamesalternatenames.php~ +++ /dev/null @@ -1,78 +0,0 @@ -groupId = $groupId; - - return $this; - } - - /** - * Get groupId - * - * @return integer - */ - public function getGroupId() - { - return $this->groupId; - } - - /** - * Set relatedId - * - * @param integer $relatedId - * - * @return GroupsRelated - */ - public function setRelatedId($relatedId) - { - $this->relatedId = $relatedId; - - return $this; - } - - /** - * Get relatedId - * - * @return integer - */ - public function getRelatedId() - { - return $this->relatedId; - } - - /** - * Set addedby - * - * @param integer $addedby - * - * @return GroupsRelated - */ - public function setAddedby($addedby) - { - $this->addedby = $addedby; - - return $this; - } - - /** - * Get addedby - * - * @return integer - */ - public function getAddedby() - { - return $this->addedby; - } - - /** - * Set deletedby - * - * @param integer $deletedby - * - * @return GroupsRelated - */ - public function setDeletedby($deletedby) - { - $this->deletedby = $deletedby; - - return $this; - } - - /** - * Get deletedby - * - * @return integer - */ - public function getDeletedby() - { - return $this->deletedby; - } - - /** - * Set ts - * - * @param \DateTime $ts - * - * @return GroupsRelated - */ - public function setTs($ts) - { - $this->ts = $ts; - - return $this; - } - - /** - * Get ts - * - * @return \DateTime - */ - public function getTs() - { - return $this->ts; - } - - /** - * Get id - * - * @return integer - */ - public function getId() - { - return $this->id; - } -} diff --git a/Rox/Storage/GroupsRelated.php~ b/Rox/Storage/GroupsRelated.php~ deleted file mode 100644 index 36153c1e90..0000000000 --- a/Rox/Storage/GroupsRelated.php~ +++ /dev/null @@ -1,61 +0,0 @@ -created = $created; - - return $this; - } - - /** - * Get created - * - * @return \DateTime - */ - public function getCreated() - { - return $this->created; - } - - /** - * Set title - * - * @param string $title - * - * @return Groupsmessages - */ - public function setTitle($title) - { - $this->title = $title; - - return $this; - } - - /** - * Get title - * - * @return string - */ - public function getTitle() - { - return $this->title; - } - - /** - * Set message - * - * @param string $message - * - * @return Groupsmessages - */ - public function setMessage($message) - { - $this->message = $message; - - return $this; - } - - /** - * Get message - * - * @return string - */ - public function getMessage() - { - return $this->message; - } - - /** - * Set idsender - * - * @param integer $idsender - * - * @return Groupsmessages - */ - public function setIdsender($idsender) - { - $this->idsender = $idsender; - - return $this; - } - - /** - * Get idsender - * - * @return integer - */ - public function getIdsender() - { - return $this->idsender; - } - - /** - * Set idgroup - * - * @param integer $idgroup - * - * @return Groupsmessages - */ - public function setIdgroup($idgroup) - { - $this->idgroup = $idgroup; - - return $this; - } - - /** - * Get idgroup - * - * @return integer - */ - public function getIdgroup() - { - return $this->idgroup; - } - - /** - * Get id - * - * @return integer - */ - public function getId() - { - return $this->id; - } -} diff --git a/Rox/Storage/Groupsmessages.php~ b/Rox/Storage/Groupsmessages.php~ deleted file mode 100644 index 5d78aa9b32..0000000000 --- a/Rox/Storage/Groupsmessages.php~ +++ /dev/null @@ -1,61 +0,0 @@ -updated = $updated; - - return $this; - } - - /** - * Get updated - * - * @return \DateTime - */ - public function getUpdated() - { - return $this->updated; - } - - /** - * Set appearance - * - * @param string $appearance - * - * @return Guestsonline - */ - public function setAppearance($appearance) - { - $this->appearance = $appearance; - - return $this; - } - - /** - * Get appearance - * - * @return string - */ - public function getAppearance() - { - return $this->appearance; - } - - /** - * Set lastactivity - * - * @param string $lastactivity - * - * @return Guestsonline - */ - public function setLastactivity($lastactivity) - { - $this->lastactivity = $lastactivity; - - return $this; - } - - /** - * Get lastactivity - * - * @return string - */ - public function getLastactivity() - { - return $this->lastactivity; - } - - /** - * Set status - * - * @param string $status - * - * @return Guestsonline - */ - public function setStatus($status) - { - $this->status = $status; - - return $this; - } - - /** - * Get status - * - * @return string - */ - public function getStatus() - { - return $this->status; - } - - /** - * Get ipguest - * - * @return integer - */ - public function getIpguest() - { - return $this->ipguest; - } -} diff --git a/Rox/Storage/Guestsonline.php~ b/Rox/Storage/Guestsonline.php~ deleted file mode 100644 index fdb2516032..0000000000 --- a/Rox/Storage/Guestsonline.php~ +++ /dev/null @@ -1,54 +0,0 @@ -value = $value; - - return $this; - } - - /** - * Get value - * - * @return string - */ - public function getValue() - { - return $this->value; - } - - /** - * Set comment - * - * @param string $comment - * - * @return HcvolConfig - */ - public function setComment($comment) - { - $this->comment = $comment; - - return $this; - } - - /** - * Get comment - * - * @return string - */ - public function getComment() - { - return $this->comment; - } - - /** - * Set updated - * - * @param \DateTime $updated - * - * @return HcvolConfig - */ - public function setUpdated($updated) - { - $this->updated = $updated; - - return $this; - } - - /** - * Get updated - * - * @return \DateTime - */ - public function getUpdated() - { - return $this->updated; - } - - /** - * Get key - * - * @return string - */ - public function getKey() - { - return $this->key; - } -} diff --git a/Rox/Storage/HcvolConfig.php~ b/Rox/Storage/HcvolConfig.php~ deleted file mode 100644 index a8f207e671..0000000000 --- a/Rox/Storage/HcvolConfig.php~ +++ /dev/null @@ -1,47 +0,0 @@ -idtranslator = $idtranslator; - - return $this; - } - - /** - * Get idtranslator - * - * @return integer - */ - public function getIdtranslator() - { - return $this->idtranslator; - } - - /** - * Set idmember - * - * @param integer $idmember - * - * @return Intermembertranslations - */ - public function setIdmember($idmember) - { - $this->idmember = $idmember; - - return $this; - } - - /** - * Get idmember - * - * @return integer - */ - public function getIdmember() - { - return $this->idmember; - } - - /** - * Set updated - * - * @param \DateTime $updated - * - * @return Intermembertranslations - */ - public function setUpdated($updated) - { - $this->updated = $updated; - - return $this; - } - - /** - * Get updated - * - * @return \DateTime - */ - public function getUpdated() - { - return $this->updated; - } - - /** - * Set idlanguage - * - * @param integer $idlanguage - * - * @return Intermembertranslations - */ - public function setIdlanguage($idlanguage) - { - $this->idlanguage = $idlanguage; - - return $this; - } - - /** - * Get idlanguage - * - * @return integer - */ - public function getIdlanguage() - { - return $this->idlanguage; - } - - /** - * Get id - * - * @return integer - */ - public function getId() - { - return $this->id; - } -} diff --git a/Rox/Storage/Intermembertranslations.php~ b/Rox/Storage/Intermembertranslations.php~ deleted file mode 100644 index e896d6c991..0000000000 --- a/Rox/Storage/Intermembertranslations.php~ +++ /dev/null @@ -1,54 +0,0 @@ -fromid = $fromid; - - return $this; - } - - /** - * Get fromid - * - * @return integer - */ - public function getFromid() - { - return $this->fromid; - } - - /** - * Set toid - * - * @param integer $toid - * - * @return Linklist - */ - public function setToid($toid) - { - $this->toid = $toid; - - return $this; - } - - /** - * Get toid - * - * @return integer - */ - public function getToid() - { - return $this->toid; - } - - /** - * Set degree - * - * @param boolean $degree - * - * @return Linklist - */ - public function setDegree($degree) - { - $this->degree = $degree; - - return $this; - } - - /** - * Get degree - * - * @return boolean - */ - public function getDegree() - { - return $this->degree; - } - - /** - * Set rank - * - * @param boolean $rank - * - * @return Linklist - */ - public function setRank($rank) - { - $this->rank = $rank; - - return $this; - } - - /** - * Get rank - * - * @return boolean - */ - public function getRank() - { - return $this->rank; - } - - /** - * Set path - * - * @param string $path - * - * @return Linklist - */ - public function setPath($path) - { - $this->path = $path; - - return $this; - } - - /** - * Get path - * - * @return string - */ - public function getPath() - { - return $this->path; - } - - /** - * Set updated - * - * @param \DateTime $updated - * - * @return Linklist - */ - public function setUpdated($updated) - { - $this->updated = $updated; - - return $this; - } - - /** - * Get updated - * - * @return \DateTime - */ - public function getUpdated() - { - return $this->updated; - } - - /** - * Get id - * - * @return integer - */ - public function getId() - { - return $this->id; - } -} diff --git a/Rox/Storage/Linklist.php~ b/Rox/Storage/Linklist.php~ deleted file mode 100644 index fd9846ec5d..0000000000 --- a/Rox/Storage/Linklist.php~ +++ /dev/null @@ -1,68 +0,0 @@ -exUserId = $exUserId; - - return $this; - } - - /** - * Get exUserId - * - * @return integer - */ - public function getExUserId() - { - return $this->exUserId; - } - - /** - * Set username - * - * @param string $username - * - * @return Members - */ - public function setUsername($username) - { - $this->username = $username; - - return $this; - } - - /** - * Get username - * - * @return string - */ - public function getUsername() - { - return $this->username; - } - - /** - * Set status - * - * @param string $status - * - * @return Members - */ - public function setStatus($status) - { - $this->status = $status; - - return $this; - } - - /** - * Get status - * - * @return string - */ - public function getStatus() - { - return $this->status; - } - - /** - * Set changedid - * - * @param integer $changedid - * - * @return Members - */ - public function setChangedid($changedid) - { - $this->changedid = $changedid; - - return $this; - } - - /** - * Get changedid - * - * @return integer - */ - public function getChangedid() - { - return $this->changedid; - } - - /** - * Set email - * - * @param integer $email - * - * @return Members - */ - public function setEmail($email) - { - $this->email = $email; - - return $this; - } - - /** - * Get email - * - * @return integer - */ - public function getEmail() - { - return $this->email; - } - - /** - * Set idcity - * - * @param integer $idcity - * - * @return Members - */ - public function setIdcity($idcity) - { - $this->idcity = $idcity; - - return $this; - } - - /** - * Get idcity - * - * @return integer - */ - public function getIdcity() - { - return $this->idcity; - } - - /** - * Set latitude - * - * @param string $latitude - * - * @return Members - */ - public function setLatitude($latitude) - { - $this->latitude = $latitude; - - return $this; - } - - /** - * Get latitude - * - * @return string - */ - public function getLatitude() - { - return $this->latitude; - } - - /** - * Set longitude - * - * @param string $longitude - * - * @return Members - */ - public function setLongitude($longitude) - { - $this->longitude = $longitude; - - return $this; - } - - /** - * Get longitude - * - * @return string - */ - public function getLongitude() - { - return $this->longitude; - } - - /** - * Set nbremindwithoutlogingin - * - * @param integer $nbremindwithoutlogingin - * - * @return Members - */ - public function setNbremindwithoutlogingin($nbremindwithoutlogingin) - { - $this->nbremindwithoutlogingin = $nbremindwithoutlogingin; - - return $this; - } - - /** - * Get nbremindwithoutlogingin - * - * @return integer - */ - public function getNbremindwithoutlogingin() - { - return $this->nbremindwithoutlogingin; - } - - /** - * Set homephonenumber - * - * @param integer $homephonenumber - * - * @return Members - */ - public function setHomephonenumber($homephonenumber) - { - $this->homephonenumber = $homephonenumber; - - return $this; - } - - /** - * Get homephonenumber - * - * @return integer - */ - public function getHomephonenumber() - { - return $this->homephonenumber; - } - - /** - * Set cellphonenumber - * - * @param integer $cellphonenumber - * - * @return Members - */ - public function setCellphonenumber($cellphonenumber) - { - $this->cellphonenumber = $cellphonenumber; - - return $this; - } - - /** - * Get cellphonenumber - * - * @return integer - */ - public function getCellphonenumber() - { - return $this->cellphonenumber; - } - - /** - * Set workphonenumber - * - * @param integer $workphonenumber - * - * @return Members - */ - public function setWorkphonenumber($workphonenumber) - { - $this->workphonenumber = $workphonenumber; - - return $this; - } - - /** - * Get workphonenumber - * - * @return integer - */ - public function getWorkphonenumber() - { - return $this->workphonenumber; - } - - /** - * Set secemail - * - * @param integer $secemail - * - * @return Members - */ - public function setSecemail($secemail) - { - $this->secemail = $secemail; - - return $this; - } - - /** - * Get secemail - * - * @return integer - */ - public function getSecemail() - { - return $this->secemail; - } - - /** - * Set firstname - * - * @param integer $firstname - * - * @return Members - */ - public function setFirstname($firstname) - { - $this->firstname = $firstname; - - return $this; - } - - /** - * Get firstname - * - * @return integer - */ - public function getFirstname() - { - return $this->firstname; - } - - /** - * Set secondname - * - * @param integer $secondname - * - * @return Members - */ - public function setSecondname($secondname) - { - $this->secondname = $secondname; - - return $this; - } - - /** - * Get secondname - * - * @return integer - */ - public function getSecondname() - { - return $this->secondname; - } - - /** - * Set lastname - * - * @param integer $lastname - * - * @return Members - */ - public function setLastname($lastname) - { - $this->lastname = $lastname; - - return $this; - } - - /** - * Get lastname - * - * @return integer - */ - public function getLastname() - { - return $this->lastname; - } - - /** - * Set accomodation - * - * @param string $accomodation - * - * @return Members - */ - public function setAccomodation($accomodation) - { - $this->accomodation = $accomodation; - - return $this; - } - - /** - * Get accomodation - * - * @return string - */ - public function getAccomodation() - { - return $this->accomodation; - } - - /** - * Set additionalaccomodationinfo - * - * @param integer $additionalaccomodationinfo - * - * @return Members - */ - public function setAdditionalaccomodationinfo($additionalaccomodationinfo) - { - $this->additionalaccomodationinfo = $additionalaccomodationinfo; - - return $this; - } - - /** - * Get additionalaccomodationinfo - * - * @return integer - */ - public function getAdditionalaccomodationinfo() - { - return $this->additionalaccomodationinfo; - } - - /** - * Set ilivewith - * - * @param integer $ilivewith - * - * @return Members - */ - public function setIlivewith($ilivewith) - { - $this->ilivewith = $ilivewith; - - return $this; - } - - /** - * Get ilivewith - * - * @return integer - */ - public function getIlivewith() - { - return $this->ilivewith; - } - - /** - * Set identitychecklevel - * - * @param boolean $identitychecklevel - * - * @return Members - */ - public function setIdentitychecklevel($identitychecklevel) - { - $this->identitychecklevel = $identitychecklevel; - - return $this; - } - - /** - * Get identitychecklevel - * - * @return boolean - */ - public function getIdentitychecklevel() - { - return $this->identitychecklevel; - } - - /** - * Set informationtoguest - * - * @param integer $informationtoguest - * - * @return Members - */ - public function setInformationtoguest($informationtoguest) - { - $this->informationtoguest = $informationtoguest; - - return $this; - } - - /** - * Get informationtoguest - * - * @return integer - */ - public function getInformationtoguest() - { - return $this->informationtoguest; - } - - /** - * Set typicoffer - * - * @param string $typicoffer - * - * @return Members - */ - public function setTypicoffer($typicoffer) - { - $this->typicoffer = $typicoffer; - - return $this; - } - - /** - * Get typicoffer - * - * @return string - */ - public function getTypicoffer() - { - return $this->typicoffer; - } - - /** - * Set offer - * - * @param integer $offer - * - * @return Members - */ - public function setOffer($offer) - { - $this->offer = $offer; - - return $this; - } - - /** - * Get offer - * - * @return integer - */ - public function getOffer() - { - return $this->offer; - } - - /** - * Set maxguest - * - * @param integer $maxguest - * - * @return Members - */ - public function setMaxguest($maxguest) - { - $this->maxguest = $maxguest; - - return $this; - } - - /** - * Get maxguest - * - * @return integer - */ - public function getMaxguest() - { - return $this->maxguest; - } - - /** - * Set maxlenghtofstay - * - * @param integer $maxlenghtofstay - * - * @return Members - */ - public function setMaxlenghtofstay($maxlenghtofstay) - { - $this->maxlenghtofstay = $maxlenghtofstay; - - return $this; - } - - /** - * Get maxlenghtofstay - * - * @return integer - */ - public function getMaxlenghtofstay() - { - return $this->maxlenghtofstay; - } - - /** - * Set organizations - * - * @param integer $organizations - * - * @return Members - */ - public function setOrganizations($organizations) - { - $this->organizations = $organizations; - - return $this; - } - - /** - * Get organizations - * - * @return integer - */ - public function getOrganizations() - { - return $this->organizations; - } - - /** - * Set restrictions - * - * @param string $restrictions - * - * @return Members - */ - public function setRestrictions($restrictions) - { - $this->restrictions = $restrictions; - - return $this; - } - - /** - * Get restrictions - * - * @return string - */ - public function getRestrictions() - { - return $this->restrictions; - } - - /** - * Set otherrestrictions - * - * @param integer $otherrestrictions - * - * @return Members - */ - public function setOtherrestrictions($otherrestrictions) - { - $this->otherrestrictions = $otherrestrictions; - - return $this; - } - - /** - * Get otherrestrictions - * - * @return integer - */ - public function getOtherrestrictions() - { - return $this->otherrestrictions; - } - - /** - * Set bday - * - * @param integer $bday - * - * @return Members - */ - public function setBday($bday) - { - $this->bday = $bday; - - return $this; - } - - /** - * Get bday - * - * @return integer - */ - public function getBday() - { - return $this->bday; - } - - /** - * Set bmonth - * - * @param integer $bmonth - * - * @return Members - */ - public function setBmonth($bmonth) - { - $this->bmonth = $bmonth; - - return $this; - } - - /** - * Get bmonth - * - * @return integer - */ - public function getBmonth() - { - return $this->bmonth; - } - - /** - * Set byear - * - * @param integer $byear - * - * @return Members - */ - public function setByear($byear) - { - $this->byear = $byear; - - return $this; - } - - /** - * Get byear - * - * @return integer - */ - public function getByear() - { - return $this->byear; - } - - /** - * Set updated - * - * @param \DateTime $updated - * - * @return Members - */ - public function setUpdated($updated) - { - $this->updated = $updated; - - return $this; - } - - /** - * Get updated - * - * @return \DateTime - */ - public function getUpdated() - { - return $this->updated; - } - - /** - * Set created - * - * @param \DateTime $created - * - * @return Members - */ - public function setCreated($created) - { - $this->created = $created; - - return $this; - } - - /** - * Get created - * - * @return \DateTime - */ - public function getCreated() - { - return $this->created; - } - - /** - * Set lastlogin - * - * @param \DateTime $lastlogin - * - * @return Members - */ - public function setLastlogin($lastlogin) - { - $this->lastlogin = $lastlogin; - - return $this; - } - - /** - * Get lastlogin - * - * @return \DateTime - */ - public function getLastlogin() - { - return $this->lastlogin; - } - - /** - * Set securityflag - * - * @param integer $securityflag - * - * @return Members - */ - public function setSecurityflag($securityflag) - { - $this->securityflag = $securityflag; - - return $this; - } - - /** - * Get securityflag - * - * @return integer - */ - public function getSecurityflag() - { - return $this->securityflag; - } - - /** - * Set quality - * - * @param string $quality - * - * @return Members - */ - public function setQuality($quality) - { - $this->quality = $quality; - - return $this; - } - - /** - * Get quality - * - * @return string - */ - public function getQuality() - { - return $this->quality; - } - - /** - * Set profilesummary - * - * @param integer $profilesummary - * - * @return Members - */ - public function setProfilesummary($profilesummary) - { - $this->profilesummary = $profilesummary; - - return $this; - } - - /** - * Get profilesummary - * - * @return integer - */ - public function getProfilesummary() - { - return $this->profilesummary; - } - - /** - * Set occupation - * - * @param integer $occupation - * - * @return Members - */ - public function setOccupation($occupation) - { - $this->occupation = $occupation; - - return $this; - } - - /** - * Get occupation - * - * @return integer - */ - public function getOccupation() - { - return $this->occupation; - } - - /** - * Set counterguests - * - * @param integer $counterguests - * - * @return Members - */ - public function setCounterguests($counterguests) - { - $this->counterguests = $counterguests; - - return $this; - } - - /** - * Get counterguests - * - * @return integer - */ - public function getCounterguests() - { - return $this->counterguests; - } - - /** - * Set counterhosts - * - * @param integer $counterhosts - * - * @return Members - */ - public function setCounterhosts($counterhosts) - { - $this->counterhosts = $counterhosts; - - return $this; - } - - /** - * Get counterhosts - * - * @return integer - */ - public function getCounterhosts() - { - return $this->counterhosts; - } - - /** - * Set countertrusts - * - * @param integer $countertrusts - * - * @return Members - */ - public function setCountertrusts($countertrusts) - { - $this->countertrusts = $countertrusts; - - return $this; - } - - /** - * Get countertrusts - * - * @return integer - */ - public function getCountertrusts() - { - return $this->countertrusts; - } - - /** - * Set password - * - * @param string $password - * - * @return Members - */ - public function setPassword($password) - { - $this->password = $password; - - return $this; - } - - /** - * Get password - * - * @return string - */ - public function getPassword() - { - return $this->password; - } - - /** - * Set gender - * - * @param string $gender - * - * @return Members - */ - public function setGender($gender) - { - $this->gender = $gender; - - return $this; - } - - /** - * Get gender - * - * @return string - */ - public function getGender() - { - return $this->gender; - } - - /** - * Set hidegender - * - * @param string $hidegender - * - * @return Members - */ - public function setHidegender($hidegender) - { - $this->hidegender = $hidegender; - - return $this; - } - - /** - * Get hidegender - * - * @return string - */ - public function getHidegender() - { - return $this->hidegender; - } - - /** - * Set genderofguest - * - * @param string $genderofguest - * - * @return Members - */ - public function setGenderofguest($genderofguest) - { - $this->genderofguest = $genderofguest; - - return $this; - } - - /** - * Get genderofguest - * - * @return string - */ - public function getGenderofguest() - { - return $this->genderofguest; - } - - /** - * Set motivationforhospitality - * - * @param integer $motivationforhospitality - * - * @return Members - */ - public function setMotivationforhospitality($motivationforhospitality) - { - $this->motivationforhospitality = $motivationforhospitality; - - return $this; - } - - /** - * Get motivationforhospitality - * - * @return integer - */ - public function getMotivationforhospitality() - { - return $this->motivationforhospitality; - } - - /** - * Set hidebirthdate - * - * @param string $hidebirthdate - * - * @return Members - */ - public function setHidebirthdate($hidebirthdate) - { - $this->hidebirthdate = $hidebirthdate; - - return $this; - } - - /** - * Get hidebirthdate - * - * @return string - */ - public function getHidebirthdate() - { - return $this->hidebirthdate; - } - - /** - * Set birthdate - * - * @param \DateTime $birthdate - * - * @return Members - */ - public function setBirthdate($birthdate) - { - $this->birthdate = $birthdate; - - return $this; - } - - /** - * Get birthdate - * - * @return \DateTime - */ - public function getBirthdate() - { - return $this->birthdate; - } - - /** - * Set adresshidden - * - * @param string $adresshidden - * - * @return Members - */ - public function setAdresshidden($adresshidden) - { - $this->adresshidden = $adresshidden; - - return $this; - } - - /** - * Get adresshidden - * - * @return string - */ - public function getAdresshidden() - { - return $this->adresshidden; - } - - /** - * Set website - * - * @param string $website - * - * @return Members - */ - public function setWebsite($website) - { - $this->website = $website; - - return $this; - } - - /** - * Get website - * - * @return string - */ - public function getWebsite() - { - return $this->website; - } - - /** - * Set chatSkype - * - * @param string $chatSkype - * - * @return Members - */ - public function setChatSkype($chatSkype) - { - $this->chatSkype = $chatSkype; - - return $this; - } - - /** - * Get chatSkype - * - * @return string - */ - public function getChatSkype() - { - return $this->chatSkype; - } - - /** - * Set chatIcq - * - * @param string $chatIcq - * - * @return Members - */ - public function setChatIcq($chatIcq) - { - $this->chatIcq = $chatIcq; - - return $this; - } - - /** - * Get chatIcq - * - * @return string - */ - public function getChatIcq() - { - return $this->chatIcq; - } - - /** - * Set chatAol - * - * @param string $chatAol - * - * @return Members - */ - public function setChatAol($chatAol) - { - $this->chatAol = $chatAol; - - return $this; - } - - /** - * Get chatAol - * - * @return string - */ - public function getChatAol() - { - return $this->chatAol; - } - - /** - * Set chatMsn - * - * @param string $chatMsn - * - * @return Members - */ - public function setChatMsn($chatMsn) - { - $this->chatMsn = $chatMsn; - - return $this; - } - - /** - * Get chatMsn - * - * @return string - */ - public function getChatMsn() - { - return $this->chatMsn; - } - - /** - * Set chatYahoo - * - * @param string $chatYahoo - * - * @return Members - */ - public function setChatYahoo($chatYahoo) - { - $this->chatYahoo = $chatYahoo; - - return $this; - } - - /** - * Get chatYahoo - * - * @return string - */ - public function getChatYahoo() - { - return $this->chatYahoo; - } - - /** - * Set chatOthers - * - * @param string $chatOthers - * - * @return Members - */ - public function setChatOthers($chatOthers) - { - $this->chatOthers = $chatOthers; - - return $this; - } - - /** - * Get chatOthers - * - * @return string - */ - public function getChatOthers() - { - return $this->chatOthers; - } - - /** - * Set id4city - * - * @param integer $id4city - * - * @return Members - */ - public function setId4city($id4city) - { - $this->id4city = $id4city; - - return $this; - } - - /** - * Get id4city - * - * @return integer - */ - public function getId4city() - { - return $this->id4city; - } - - /** - * Set futuretrips - * - * @param integer $futuretrips - * - * @return Members - */ - public function setFuturetrips($futuretrips) - { - $this->futuretrips = $futuretrips; - - return $this; - } - - /** - * Get futuretrips - * - * @return integer - */ - public function getFuturetrips() - { - return $this->futuretrips; - } - - /** - * Set oldtrips - * - * @param integer $oldtrips - * - * @return Members - */ - public function setOldtrips($oldtrips) - { - $this->oldtrips = $oldtrips; - - return $this; - } - - /** - * Get oldtrips - * - * @return integer - */ - public function getOldtrips() - { - return $this->oldtrips; - } - - /** - * Set logcount - * - * @param integer $logcount - * - * @return Members - */ - public function setLogcount($logcount) - { - $this->logcount = $logcount; - - return $this; - } - - /** - * Get logcount - * - * @return integer - */ - public function getLogcount() - { - return $this->logcount; - } - - /** - * Set hobbies - * - * @param integer $hobbies - * - * @return Members - */ - public function setHobbies($hobbies) - { - $this->hobbies = $hobbies; - - return $this; - } - - /** - * Get hobbies - * - * @return integer - */ - public function getHobbies() - { - return $this->hobbies; - } - - /** - * Set books - * - * @param integer $books - * - * @return Members - */ - public function setBooks($books) - { - $this->books = $books; - - return $this; - } - - /** - * Get books - * - * @return integer - */ - public function getBooks() - { - return $this->books; - } - - /** - * Set music - * - * @param integer $music - * - * @return Members - */ - public function setMusic($music) - { - $this->music = $music; - - return $this; - } - - /** - * Get music - * - * @return integer - */ - public function getMusic() - { - return $this->music; - } - - /** - * Set pasttrips - * - * @param integer $pasttrips - * - * @return Members - */ - public function setPasttrips($pasttrips) - { - $this->pasttrips = $pasttrips; - - return $this; - } - - /** - * Get pasttrips - * - * @return integer - */ - public function getPasttrips() - { - return $this->pasttrips; - } - - /** - * Set plannedtrips - * - * @param integer $plannedtrips - * - * @return Members - */ - public function setPlannedtrips($plannedtrips) - { - $this->plannedtrips = $plannedtrips; - - return $this; - } - - /** - * Get plannedtrips - * - * @return integer - */ - public function getPlannedtrips() - { - return $this->plannedtrips; - } - - /** - * Set pleasebring - * - * @param integer $pleasebring - * - * @return Members - */ - public function setPleasebring($pleasebring) - { - $this->pleasebring = $pleasebring; - - return $this; - } - - /** - * Get pleasebring - * - * @return integer - */ - public function getPleasebring() - { - return $this->pleasebring; - } - - /** - * Set offerguests - * - * @param integer $offerguests - * - * @return Members - */ - public function setOfferguests($offerguests) - { - $this->offerguests = $offerguests; - - return $this; - } - - /** - * Get offerguests - * - * @return integer - */ - public function getOfferguests() - { - return $this->offerguests; - } - - /** - * Set offerhosts - * - * @param integer $offerhosts - * - * @return Members - */ - public function setOfferhosts($offerhosts) - { - $this->offerhosts = $offerhosts; - - return $this; - } - - /** - * Get offerhosts - * - * @return integer - */ - public function getOfferhosts() - { - return $this->offerhosts; - } - - /** - * Set publictransport - * - * @param integer $publictransport - * - * @return Members - */ - public function setPublictransport($publictransport) - { - $this->publictransport = $publictransport; - - return $this; - } - - /** - * Get publictransport - * - * @return integer - */ - public function getPublictransport() - { - return $this->publictransport; - } - - /** - * Set movies - * - * @param integer $movies - * - * @return Members - */ - public function setMovies($movies) - { - $this->movies = $movies; - - return $this; - } - - /** - * Get movies - * - * @return integer - */ - public function getMovies() - { - return $this->movies; - } - - /** - * Set chatGoogle - * - * @param integer $chatGoogle - * - * @return Members - */ - public function setChatGoogle($chatGoogle) - { - $this->chatGoogle = $chatGoogle; - - return $this; - } - - /** - * Get chatGoogle - * - * @return integer - */ - public function getChatGoogle() - { - return $this->chatGoogle; - } - - /** - * Set lastswitchtoactive - * - * @param \DateTime $lastswitchtoactive - * - * @return Members - */ - public function setLastswitchtoactive($lastswitchtoactive) - { - $this->lastswitchtoactive = $lastswitchtoactive; - - return $this; - } - - /** - * Get lastswitchtoactive - * - * @return \DateTime - */ - public function getLastswitchtoactive() - { - return $this->lastswitchtoactive; - } - - /** - * Set bewelcomed - * - * @param integer $bewelcomed - * - * @return Members - */ - public function setBewelcomed($bewelcomed) - { - $this->bewelcomed = $bewelcomed; - - return $this; - } - - /** - * Get bewelcomed - * - * @return integer - */ - public function getBewelcomed() - { - return $this->bewelcomed; - } - - /** - * Get id - * - * @return integer - */ - public function getId() - { - return $this->id; - } -} diff --git a/Rox/Storage/Members.php~ b/Rox/Storage/Members.php~ deleted file mode 100644 index ddda497a35..0000000000 --- a/Rox/Storage/Members.php~ +++ /dev/null @@ -1,537 +0,0 @@ -exUserId = $exUserId; - - return $this; - } - - /** - * Get exUserId - * - * @return integer - */ - public function getExUserId() - { - return $this->exUserId; - } - - /** - * Set username - * - * @param string $username - * - * @return MembersBeforeDataRetention - */ - public function setUsername($username) - { - $this->username = $username; - - return $this; - } - - /** - * Get username - * - * @return string - */ - public function getUsername() - { - return $this->username; - } - - /** - * Set status - * - * @param string $status - * - * @return MembersBeforeDataRetention - */ - public function setStatus($status) - { - $this->status = $status; - - return $this; - } - - /** - * Get status - * - * @return string - */ - public function getStatus() - { - return $this->status; - } - - /** - * Set changedid - * - * @param integer $changedid - * - * @return MembersBeforeDataRetention - */ - public function setChangedid($changedid) - { - $this->changedid = $changedid; - - return $this; - } - - /** - * Get changedid - * - * @return integer - */ - public function getChangedid() - { - return $this->changedid; - } - - /** - * Set email - * - * @param integer $email - * - * @return MembersBeforeDataRetention - */ - public function setEmail($email) - { - $this->email = $email; - - return $this; - } - - /** - * Get email - * - * @return integer - */ - public function getEmail() - { - return $this->email; - } - - /** - * Set idcity - * - * @param integer $idcity - * - * @return MembersBeforeDataRetention - */ - public function setIdcity($idcity) - { - $this->idcity = $idcity; - - return $this; - } - - /** - * Get idcity - * - * @return integer - */ - public function getIdcity() - { - return $this->idcity; - } - - /** - * Set nbremindwithoutlogingin - * - * @param integer $nbremindwithoutlogingin - * - * @return MembersBeforeDataRetention - */ - public function setNbremindwithoutlogingin($nbremindwithoutlogingin) - { - $this->nbremindwithoutlogingin = $nbremindwithoutlogingin; - - return $this; - } - - /** - * Get nbremindwithoutlogingin - * - * @return integer - */ - public function getNbremindwithoutlogingin() - { - return $this->nbremindwithoutlogingin; - } - - /** - * Set homephonenumber - * - * @param integer $homephonenumber - * - * @return MembersBeforeDataRetention - */ - public function setHomephonenumber($homephonenumber) - { - $this->homephonenumber = $homephonenumber; - - return $this; - } - - /** - * Get homephonenumber - * - * @return integer - */ - public function getHomephonenumber() - { - return $this->homephonenumber; - } - - /** - * Set cellphonenumber - * - * @param integer $cellphonenumber - * - * @return MembersBeforeDataRetention - */ - public function setCellphonenumber($cellphonenumber) - { - $this->cellphonenumber = $cellphonenumber; - - return $this; - } - - /** - * Get cellphonenumber - * - * @return integer - */ - public function getCellphonenumber() - { - return $this->cellphonenumber; - } - - /** - * Set workphonenumber - * - * @param integer $workphonenumber - * - * @return MembersBeforeDataRetention - */ - public function setWorkphonenumber($workphonenumber) - { - $this->workphonenumber = $workphonenumber; - - return $this; - } - - /** - * Get workphonenumber - * - * @return integer - */ - public function getWorkphonenumber() - { - return $this->workphonenumber; - } - - /** - * Set secemail - * - * @param integer $secemail - * - * @return MembersBeforeDataRetention - */ - public function setSecemail($secemail) - { - $this->secemail = $secemail; - - return $this; - } - - /** - * Get secemail - * - * @return integer - */ - public function getSecemail() - { - return $this->secemail; - } - - /** - * Set firstname - * - * @param integer $firstname - * - * @return MembersBeforeDataRetention - */ - public function setFirstname($firstname) - { - $this->firstname = $firstname; - - return $this; - } - - /** - * Get firstname - * - * @return integer - */ - public function getFirstname() - { - return $this->firstname; - } - - /** - * Set secondname - * - * @param integer $secondname - * - * @return MembersBeforeDataRetention - */ - public function setSecondname($secondname) - { - $this->secondname = $secondname; - - return $this; - } - - /** - * Get secondname - * - * @return integer - */ - public function getSecondname() - { - return $this->secondname; - } - - /** - * Set lastname - * - * @param integer $lastname - * - * @return MembersBeforeDataRetention - */ - public function setLastname($lastname) - { - $this->lastname = $lastname; - - return $this; - } - - /** - * Get lastname - * - * @return integer - */ - public function getLastname() - { - return $this->lastname; - } - - /** - * Set accomodation - * - * @param string $accomodation - * - * @return MembersBeforeDataRetention - */ - public function setAccomodation($accomodation) - { - $this->accomodation = $accomodation; - - return $this; - } - - /** - * Get accomodation - * - * @return string - */ - public function getAccomodation() - { - return $this->accomodation; - } - - /** - * Set additionalaccomodationinfo - * - * @param integer $additionalaccomodationinfo - * - * @return MembersBeforeDataRetention - */ - public function setAdditionalaccomodationinfo($additionalaccomodationinfo) - { - $this->additionalaccomodationinfo = $additionalaccomodationinfo; - - return $this; - } - - /** - * Get additionalaccomodationinfo - * - * @return integer - */ - public function getAdditionalaccomodationinfo() - { - return $this->additionalaccomodationinfo; - } - - /** - * Set ilivewith - * - * @param integer $ilivewith - * - * @return MembersBeforeDataRetention - */ - public function setIlivewith($ilivewith) - { - $this->ilivewith = $ilivewith; - - return $this; - } - - /** - * Get ilivewith - * - * @return integer - */ - public function getIlivewith() - { - return $this->ilivewith; - } - - /** - * Set identitychecklevel - * - * @param boolean $identitychecklevel - * - * @return MembersBeforeDataRetention - */ - public function setIdentitychecklevel($identitychecklevel) - { - $this->identitychecklevel = $identitychecklevel; - - return $this; - } - - /** - * Get identitychecklevel - * - * @return boolean - */ - public function getIdentitychecklevel() - { - return $this->identitychecklevel; - } - - /** - * Set informationtoguest - * - * @param integer $informationtoguest - * - * @return MembersBeforeDataRetention - */ - public function setInformationtoguest($informationtoguest) - { - $this->informationtoguest = $informationtoguest; - - return $this; - } - - /** - * Get informationtoguest - * - * @return integer - */ - public function getInformationtoguest() - { - return $this->informationtoguest; - } - - /** - * Set typicoffer - * - * @param string $typicoffer - * - * @return MembersBeforeDataRetention - */ - public function setTypicoffer($typicoffer) - { - $this->typicoffer = $typicoffer; - - return $this; - } - - /** - * Get typicoffer - * - * @return string - */ - public function getTypicoffer() - { - return $this->typicoffer; - } - - /** - * Set offer - * - * @param integer $offer - * - * @return MembersBeforeDataRetention - */ - public function setOffer($offer) - { - $this->offer = $offer; - - return $this; - } - - /** - * Get offer - * - * @return integer - */ - public function getOffer() - { - return $this->offer; - } - - /** - * Set maxguest - * - * @param integer $maxguest - * - * @return MembersBeforeDataRetention - */ - public function setMaxguest($maxguest) - { - $this->maxguest = $maxguest; - - return $this; - } - - /** - * Get maxguest - * - * @return integer - */ - public function getMaxguest() - { - return $this->maxguest; - } - - /** - * Set maxlenghtofstay - * - * @param integer $maxlenghtofstay - * - * @return MembersBeforeDataRetention - */ - public function setMaxlenghtofstay($maxlenghtofstay) - { - $this->maxlenghtofstay = $maxlenghtofstay; - - return $this; - } - - /** - * Get maxlenghtofstay - * - * @return integer - */ - public function getMaxlenghtofstay() - { - return $this->maxlenghtofstay; - } - - /** - * Set organizations - * - * @param integer $organizations - * - * @return MembersBeforeDataRetention - */ - public function setOrganizations($organizations) - { - $this->organizations = $organizations; - - return $this; - } - - /** - * Get organizations - * - * @return integer - */ - public function getOrganizations() - { - return $this->organizations; - } - - /** - * Set restrictions - * - * @param string $restrictions - * - * @return MembersBeforeDataRetention - */ - public function setRestrictions($restrictions) - { - $this->restrictions = $restrictions; - - return $this; - } - - /** - * Get restrictions - * - * @return string - */ - public function getRestrictions() - { - return $this->restrictions; - } - - /** - * Set otherrestrictions - * - * @param integer $otherrestrictions - * - * @return MembersBeforeDataRetention - */ - public function setOtherrestrictions($otherrestrictions) - { - $this->otherrestrictions = $otherrestrictions; - - return $this; - } - - /** - * Get otherrestrictions - * - * @return integer - */ - public function getOtherrestrictions() - { - return $this->otherrestrictions; - } - - /** - * Set bday - * - * @param integer $bday - * - * @return MembersBeforeDataRetention - */ - public function setBday($bday) - { - $this->bday = $bday; - - return $this; - } - - /** - * Get bday - * - * @return integer - */ - public function getBday() - { - return $this->bday; - } - - /** - * Set bmonth - * - * @param integer $bmonth - * - * @return MembersBeforeDataRetention - */ - public function setBmonth($bmonth) - { - $this->bmonth = $bmonth; - - return $this; - } - - /** - * Get bmonth - * - * @return integer - */ - public function getBmonth() - { - return $this->bmonth; - } - - /** - * Set byear - * - * @param integer $byear - * - * @return MembersBeforeDataRetention - */ - public function setByear($byear) - { - $this->byear = $byear; - - return $this; - } - - /** - * Get byear - * - * @return integer - */ - public function getByear() - { - return $this->byear; - } - - /** - * Set updated - * - * @param \DateTime $updated - * - * @return MembersBeforeDataRetention - */ - public function setUpdated($updated) - { - $this->updated = $updated; - - return $this; - } - - /** - * Get updated - * - * @return \DateTime - */ - public function getUpdated() - { - return $this->updated; - } - - /** - * Set created - * - * @param \DateTime $created - * - * @return MembersBeforeDataRetention - */ - public function setCreated($created) - { - $this->created = $created; - - return $this; - } - - /** - * Get created - * - * @return \DateTime - */ - public function getCreated() - { - return $this->created; - } - - /** - * Set lastlogin - * - * @param \DateTime $lastlogin - * - * @return MembersBeforeDataRetention - */ - public function setLastlogin($lastlogin) - { - $this->lastlogin = $lastlogin; - - return $this; - } - - /** - * Get lastlogin - * - * @return \DateTime - */ - public function getLastlogin() - { - return $this->lastlogin; - } - - /** - * Set securityflag - * - * @param integer $securityflag - * - * @return MembersBeforeDataRetention - */ - public function setSecurityflag($securityflag) - { - $this->securityflag = $securityflag; - - return $this; - } - - /** - * Get securityflag - * - * @return integer - */ - public function getSecurityflag() - { - return $this->securityflag; - } - - /** - * Set quality - * - * @param string $quality - * - * @return MembersBeforeDataRetention - */ - public function setQuality($quality) - { - $this->quality = $quality; - - return $this; - } - - /** - * Get quality - * - * @return string - */ - public function getQuality() - { - return $this->quality; - } - - /** - * Set profilesummary - * - * @param integer $profilesummary - * - * @return MembersBeforeDataRetention - */ - public function setProfilesummary($profilesummary) - { - $this->profilesummary = $profilesummary; - - return $this; - } - - /** - * Get profilesummary - * - * @return integer - */ - public function getProfilesummary() - { - return $this->profilesummary; - } - - /** - * Set occupation - * - * @param integer $occupation - * - * @return MembersBeforeDataRetention - */ - public function setOccupation($occupation) - { - $this->occupation = $occupation; - - return $this; - } - - /** - * Get occupation - * - * @return integer - */ - public function getOccupation() - { - return $this->occupation; - } - - /** - * Set counterguests - * - * @param integer $counterguests - * - * @return MembersBeforeDataRetention - */ - public function setCounterguests($counterguests) - { - $this->counterguests = $counterguests; - - return $this; - } - - /** - * Get counterguests - * - * @return integer - */ - public function getCounterguests() - { - return $this->counterguests; - } - - /** - * Set counterhosts - * - * @param integer $counterhosts - * - * @return MembersBeforeDataRetention - */ - public function setCounterhosts($counterhosts) - { - $this->counterhosts = $counterhosts; - - return $this; - } - - /** - * Get counterhosts - * - * @return integer - */ - public function getCounterhosts() - { - return $this->counterhosts; - } - - /** - * Set countertrusts - * - * @param integer $countertrusts - * - * @return MembersBeforeDataRetention - */ - public function setCountertrusts($countertrusts) - { - $this->countertrusts = $countertrusts; - - return $this; - } - - /** - * Get countertrusts - * - * @return integer - */ - public function getCountertrusts() - { - return $this->countertrusts; - } - - /** - * Set password - * - * @param string $password - * - * @return MembersBeforeDataRetention - */ - public function setPassword($password) - { - $this->password = $password; - - return $this; - } - - /** - * Get password - * - * @return string - */ - public function getPassword() - { - return $this->password; - } - - /** - * Set gender - * - * @param string $gender - * - * @return MembersBeforeDataRetention - */ - public function setGender($gender) - { - $this->gender = $gender; - - return $this; - } - - /** - * Get gender - * - * @return string - */ - public function getGender() - { - return $this->gender; - } - - /** - * Set hidegender - * - * @param string $hidegender - * - * @return MembersBeforeDataRetention - */ - public function setHidegender($hidegender) - { - $this->hidegender = $hidegender; - - return $this; - } - - /** - * Get hidegender - * - * @return string - */ - public function getHidegender() - { - return $this->hidegender; - } - - /** - * Set genderofguest - * - * @param string $genderofguest - * - * @return MembersBeforeDataRetention - */ - public function setGenderofguest($genderofguest) - { - $this->genderofguest = $genderofguest; - - return $this; - } - - /** - * Get genderofguest - * - * @return string - */ - public function getGenderofguest() - { - return $this->genderofguest; - } - - /** - * Set motivationforhospitality - * - * @param integer $motivationforhospitality - * - * @return MembersBeforeDataRetention - */ - public function setMotivationforhospitality($motivationforhospitality) - { - $this->motivationforhospitality = $motivationforhospitality; - - return $this; - } - - /** - * Get motivationforhospitality - * - * @return integer - */ - public function getMotivationforhospitality() - { - return $this->motivationforhospitality; - } - - /** - * Set hidebirthdate - * - * @param string $hidebirthdate - * - * @return MembersBeforeDataRetention - */ - public function setHidebirthdate($hidebirthdate) - { - $this->hidebirthdate = $hidebirthdate; - - return $this; - } - - /** - * Get hidebirthdate - * - * @return string - */ - public function getHidebirthdate() - { - return $this->hidebirthdate; - } - - /** - * Set birthdate - * - * @param \DateTime $birthdate - * - * @return MembersBeforeDataRetention - */ - public function setBirthdate($birthdate) - { - $this->birthdate = $birthdate; - - return $this; - } - - /** - * Get birthdate - * - * @return \DateTime - */ - public function getBirthdate() - { - return $this->birthdate; - } - - /** - * Set adresshidden - * - * @param string $adresshidden - * - * @return MembersBeforeDataRetention - */ - public function setAdresshidden($adresshidden) - { - $this->adresshidden = $adresshidden; - - return $this; - } - - /** - * Get adresshidden - * - * @return string - */ - public function getAdresshidden() - { - return $this->adresshidden; - } - - /** - * Set website - * - * @param string $website - * - * @return MembersBeforeDataRetention - */ - public function setWebsite($website) - { - $this->website = $website; - - return $this; - } - - /** - * Get website - * - * @return string - */ - public function getWebsite() - { - return $this->website; - } - - /** - * Set chatSkype - * - * @param string $chatSkype - * - * @return MembersBeforeDataRetention - */ - public function setChatSkype($chatSkype) - { - $this->chatSkype = $chatSkype; - - return $this; - } - - /** - * Get chatSkype - * - * @return string - */ - public function getChatSkype() - { - return $this->chatSkype; - } - - /** - * Set chatIcq - * - * @param string $chatIcq - * - * @return MembersBeforeDataRetention - */ - public function setChatIcq($chatIcq) - { - $this->chatIcq = $chatIcq; - - return $this; - } - - /** - * Get chatIcq - * - * @return string - */ - public function getChatIcq() - { - return $this->chatIcq; - } - - /** - * Set chatAol - * - * @param string $chatAol - * - * @return MembersBeforeDataRetention - */ - public function setChatAol($chatAol) - { - $this->chatAol = $chatAol; - - return $this; - } - - /** - * Get chatAol - * - * @return string - */ - public function getChatAol() - { - return $this->chatAol; - } - - /** - * Set chatMsn - * - * @param string $chatMsn - * - * @return MembersBeforeDataRetention - */ - public function setChatMsn($chatMsn) - { - $this->chatMsn = $chatMsn; - - return $this; - } - - /** - * Get chatMsn - * - * @return string - */ - public function getChatMsn() - { - return $this->chatMsn; - } - - /** - * Set chatYahoo - * - * @param string $chatYahoo - * - * @return MembersBeforeDataRetention - */ - public function setChatYahoo($chatYahoo) - { - $this->chatYahoo = $chatYahoo; - - return $this; - } - - /** - * Get chatYahoo - * - * @return string - */ - public function getChatYahoo() - { - return $this->chatYahoo; - } - - /** - * Set chatOthers - * - * @param string $chatOthers - * - * @return MembersBeforeDataRetention - */ - public function setChatOthers($chatOthers) - { - $this->chatOthers = $chatOthers; - - return $this; - } - - /** - * Get chatOthers - * - * @return string - */ - public function getChatOthers() - { - return $this->chatOthers; - } - - /** - * Set id4city - * - * @param integer $id4city - * - * @return MembersBeforeDataRetention - */ - public function setId4city($id4city) - { - $this->id4city = $id4city; - - return $this; - } - - /** - * Get id4city - * - * @return integer - */ - public function getId4city() - { - return $this->id4city; - } - - /** - * Set futuretrips - * - * @param integer $futuretrips - * - * @return MembersBeforeDataRetention - */ - public function setFuturetrips($futuretrips) - { - $this->futuretrips = $futuretrips; - - return $this; - } - - /** - * Get futuretrips - * - * @return integer - */ - public function getFuturetrips() - { - return $this->futuretrips; - } - - /** - * Set oldtrips - * - * @param integer $oldtrips - * - * @return MembersBeforeDataRetention - */ - public function setOldtrips($oldtrips) - { - $this->oldtrips = $oldtrips; - - return $this; - } - - /** - * Get oldtrips - * - * @return integer - */ - public function getOldtrips() - { - return $this->oldtrips; - } - - /** - * Set logcount - * - * @param integer $logcount - * - * @return MembersBeforeDataRetention - */ - public function setLogcount($logcount) - { - $this->logcount = $logcount; - - return $this; - } - - /** - * Get logcount - * - * @return integer - */ - public function getLogcount() - { - return $this->logcount; - } - - /** - * Set hobbies - * - * @param integer $hobbies - * - * @return MembersBeforeDataRetention - */ - public function setHobbies($hobbies) - { - $this->hobbies = $hobbies; - - return $this; - } - - /** - * Get hobbies - * - * @return integer - */ - public function getHobbies() - { - return $this->hobbies; - } - - /** - * Set books - * - * @param integer $books - * - * @return MembersBeforeDataRetention - */ - public function setBooks($books) - { - $this->books = $books; - - return $this; - } - - /** - * Get books - * - * @return integer - */ - public function getBooks() - { - return $this->books; - } - - /** - * Set music - * - * @param integer $music - * - * @return MembersBeforeDataRetention - */ - public function setMusic($music) - { - $this->music = $music; - - return $this; - } - - /** - * Get music - * - * @return integer - */ - public function getMusic() - { - return $this->music; - } - - /** - * Set pasttrips - * - * @param integer $pasttrips - * - * @return MembersBeforeDataRetention - */ - public function setPasttrips($pasttrips) - { - $this->pasttrips = $pasttrips; - - return $this; - } - - /** - * Get pasttrips - * - * @return integer - */ - public function getPasttrips() - { - return $this->pasttrips; - } - - /** - * Set plannedtrips - * - * @param integer $plannedtrips - * - * @return MembersBeforeDataRetention - */ - public function setPlannedtrips($plannedtrips) - { - $this->plannedtrips = $plannedtrips; - - return $this; - } - - /** - * Get plannedtrips - * - * @return integer - */ - public function getPlannedtrips() - { - return $this->plannedtrips; - } - - /** - * Set pleasebring - * - * @param integer $pleasebring - * - * @return MembersBeforeDataRetention - */ - public function setPleasebring($pleasebring) - { - $this->pleasebring = $pleasebring; - - return $this; - } - - /** - * Get pleasebring - * - * @return integer - */ - public function getPleasebring() - { - return $this->pleasebring; - } - - /** - * Set offerguests - * - * @param integer $offerguests - * - * @return MembersBeforeDataRetention - */ - public function setOfferguests($offerguests) - { - $this->offerguests = $offerguests; - - return $this; - } - - /** - * Get offerguests - * - * @return integer - */ - public function getOfferguests() - { - return $this->offerguests; - } - - /** - * Set offerhosts - * - * @param integer $offerhosts - * - * @return MembersBeforeDataRetention - */ - public function setOfferhosts($offerhosts) - { - $this->offerhosts = $offerhosts; - - return $this; - } - - /** - * Get offerhosts - * - * @return integer - */ - public function getOfferhosts() - { - return $this->offerhosts; - } - - /** - * Set publictransport - * - * @param integer $publictransport - * - * @return MembersBeforeDataRetention - */ - public function setPublictransport($publictransport) - { - $this->publictransport = $publictransport; - - return $this; - } - - /** - * Get publictransport - * - * @return integer - */ - public function getPublictransport() - { - return $this->publictransport; - } - - /** - * Set movies - * - * @param integer $movies - * - * @return MembersBeforeDataRetention - */ - public function setMovies($movies) - { - $this->movies = $movies; - - return $this; - } - - /** - * Get movies - * - * @return integer - */ - public function getMovies() - { - return $this->movies; - } - - /** - * Set chatGoogle - * - * @param integer $chatGoogle - * - * @return MembersBeforeDataRetention - */ - public function setChatGoogle($chatGoogle) - { - $this->chatGoogle = $chatGoogle; - - return $this; - } - - /** - * Get chatGoogle - * - * @return integer - */ - public function getChatGoogle() - { - return $this->chatGoogle; - } - - /** - * Set lastswitchtoactive - * - * @param \DateTime $lastswitchtoactive - * - * @return MembersBeforeDataRetention - */ - public function setLastswitchtoactive($lastswitchtoactive) - { - $this->lastswitchtoactive = $lastswitchtoactive; - - return $this; - } - - /** - * Get lastswitchtoactive - * - * @return \DateTime - */ - public function getLastswitchtoactive() - { - return $this->lastswitchtoactive; - } - - /** - * Set bewelcomed - * - * @param integer $bewelcomed - * - * @return MembersBeforeDataRetention - */ - public function setBewelcomed($bewelcomed) - { - $this->bewelcomed = $bewelcomed; - - return $this; - } - - /** - * Get bewelcomed - * - * @return integer - */ - public function getBewelcomed() - { - return $this->bewelcomed; - } - - /** - * Get id - * - * @return integer - */ - public function getId() - { - return $this->id; - } -} diff --git a/Rox/Storage/MembersBeforeDataRetention.php~ b/Rox/Storage/MembersBeforeDataRetention.php~ deleted file mode 100644 index 80b4e0ad15..0000000000 --- a/Rox/Storage/MembersBeforeDataRetention.php~ +++ /dev/null @@ -1,523 +0,0 @@ -idsubscriber = $idsubscriber; - - return $this; - } - - /** - * Get idsubscriber - * - * @return integer - */ - public function getIdsubscriber() - { - return $this->idsubscriber; - } - - /** - * Set idgroup - * - * @param integer $idgroup - * - * @return MembersGroupsSubscribed - */ - public function setIdgroup($idgroup) - { - $this->idgroup = $idgroup; - - return $this; - } - - /** - * Get idgroup - * - * @return integer - */ - public function getIdgroup() - { - return $this->idgroup; - } - - /** - * Set actiontowatch - * - * @param string $actiontowatch - * - * @return MembersGroupsSubscribed - */ - public function setActiontowatch($actiontowatch) - { - $this->actiontowatch = $actiontowatch; - - return $this; - } - - /** - * Get actiontowatch - * - * @return string - */ - public function getActiontowatch() - { - return $this->actiontowatch; - } - - /** - * Set unsubscribekey - * - * @param string $unsubscribekey - * - * @return MembersGroupsSubscribed - */ - public function setUnsubscribekey($unsubscribekey) - { - $this->unsubscribekey = $unsubscribekey; - - return $this; - } - - /** - * Get unsubscribekey - * - * @return string - */ - public function getUnsubscribekey() - { - return $this->unsubscribekey; - } - - /** - * Set created - * - * @param \DateTime $created - * - * @return MembersGroupsSubscribed - */ - public function setCreated($created) - { - $this->created = $created; - - return $this; - } - - /** - * Get created - * - * @return \DateTime - */ - public function getCreated() - { - return $this->created; - } - - /** - * Get id - * - * @return integer - */ - public function getId() - { - return $this->id; - } -} diff --git a/Rox/Storage/MembersGroupsSubscribed.php~ b/Rox/Storage/MembersGroupsSubscribed.php~ deleted file mode 100644 index b563990c98..0000000000 --- a/Rox/Storage/MembersGroupsSubscribed.php~ +++ /dev/null @@ -1,61 +0,0 @@ -updated = $updated; - - return $this; - } - - /** - * Get updated - * - * @return \DateTime - */ - public function getUpdated() - { - return $this->updated; - } - - /** - * Set idmember - * - * @param integer $idmember - * - * @return MembersRoles - */ - public function setIdmember($idmember) - { - $this->idmember = $idmember; - - return $this; - } - - /** - * Get idmember - * - * @return integer - */ - public function getIdmember() - { - return $this->idmember; - } - - /** - * Set idrole - * - * @param integer $idrole - * - * @return MembersRoles - */ - public function setIdrole($idrole) - { - $this->idrole = $idrole; - - return $this; - } - - /** - * Get idrole - * - * @return integer - */ - public function getIdrole() - { - return $this->idrole; - } -} diff --git a/Rox/Storage/MembersRoles.php~ b/Rox/Storage/MembersRoles.php~ deleted file mode 100644 index f8167745bf..0000000000 --- a/Rox/Storage/MembersRoles.php~ +++ /dev/null @@ -1,42 +0,0 @@ -seriestoken = $seriestoken; - - return $this; - } - - /** - * Get seriestoken - * - * @return string - */ - public function getSeriestoken() - { - return $this->seriestoken; - } - - /** - * Set authtoken - * - * @param string $authtoken - * - * @return MembersSessions - */ - public function setAuthtoken($authtoken) - { - $this->authtoken = $authtoken; - - return $this; - } - - /** - * Get authtoken - * - * @return string - */ - public function getAuthtoken() - { - return $this->authtoken; - } - - /** - * Set modified - * - * @param \DateTime $modified - * - * @return MembersSessions - */ - public function setModified($modified) - { - $this->modified = $modified; - - return $this; - } - - /** - * Get modified - * - * @return \DateTime - */ - public function getModified() - { - return $this->modified; - } - - /** - * Get idmember - * - * @return integer - */ - public function getIdmember() - { - return $this->idmember; - } -} diff --git a/Rox/Storage/MembersSessions.php~ b/Rox/Storage/MembersSessions.php~ deleted file mode 100644 index 1b770241e2..0000000000 --- a/Rox/Storage/MembersSessions.php~ +++ /dev/null @@ -1,47 +0,0 @@ -idsubscriber = $idsubscriber; - - return $this; - } - - /** - * Get idsubscriber - * - * @return integer - */ - public function getIdsubscriber() - { - return $this->idsubscriber; - } - - /** - * Set idtag - * - * @param integer $idtag - * - * @return MembersTagsSubscribed - */ - public function setIdtag($idtag) - { - $this->idtag = $idtag; - - return $this; - } - - /** - * Get idtag - * - * @return integer - */ - public function getIdtag() - { - return $this->idtag; - } - - /** - * Set actiontowatch - * - * @param string $actiontowatch - * - * @return MembersTagsSubscribed - */ - public function setActiontowatch($actiontowatch) - { - $this->actiontowatch = $actiontowatch; - - return $this; - } - - /** - * Get actiontowatch - * - * @return string - */ - public function getActiontowatch() - { - return $this->actiontowatch; - } - - /** - * Set unsubscribekey - * - * @param string $unsubscribekey - * - * @return MembersTagsSubscribed - */ - public function setUnsubscribekey($unsubscribekey) - { - $this->unsubscribekey = $unsubscribekey; - - return $this; - } - - /** - * Get unsubscribekey - * - * @return string - */ - public function getUnsubscribekey() - { - return $this->unsubscribekey; - } - - /** - * Set created - * - * @param \DateTime $created - * - * @return MembersTagsSubscribed - */ - public function setCreated($created) - { - $this->created = $created; - - return $this; - } - - /** - * Get created - * - * @return \DateTime - */ - public function getCreated() - { - return $this->created; - } - - /** - * Set notificationsenabled - * - * @param boolean $notificationsenabled - * - * @return MembersTagsSubscribed - */ - public function setNotificationsenabled($notificationsenabled) - { - $this->notificationsenabled = $notificationsenabled; - - return $this; - } - - /** - * Get notificationsenabled - * - * @return boolean - */ - public function getNotificationsenabled() - { - return $this->notificationsenabled; - } - - /** - * Get id - * - * @return integer - */ - public function getId() - { - return $this->id; - } -} diff --git a/Rox/Storage/MembersTagsSubscribed.php~ b/Rox/Storage/MembersTagsSubscribed.php~ deleted file mode 100644 index 9a79dccf22..0000000000 --- a/Rox/Storage/MembersTagsSubscribed.php~ +++ /dev/null @@ -1,68 +0,0 @@ -updated = $updated; - - return $this; - } - - /** - * Get updated - * - * @return \DateTime - */ - public function getUpdated() - { - return $this->updated; - } - - /** - * Set created - * - * @param \DateTime $created - * - * @return MemberslanguageslevelBeforeDataRetention - */ - public function setCreated($created) - { - $this->created = $created; - - return $this; - } - - /** - * Get created - * - * @return \DateTime - */ - public function getCreated() - { - return $this->created; - } - - /** - * Set idmember - * - * @param integer $idmember - * - * @return MemberslanguageslevelBeforeDataRetention - */ - public function setIdmember($idmember) - { - $this->idmember = $idmember; - - return $this; - } - - /** - * Get idmember - * - * @return integer - */ - public function getIdmember() - { - return $this->idmember; - } - - /** - * Set idlanguage - * - * @param integer $idlanguage - * - * @return MemberslanguageslevelBeforeDataRetention - */ - public function setIdlanguage($idlanguage) - { - $this->idlanguage = $idlanguage; - - return $this; - } - - /** - * Get idlanguage - * - * @return integer - */ - public function getIdlanguage() - { - return $this->idlanguage; - } - - /** - * Set level - * - * @param string $level - * - * @return MemberslanguageslevelBeforeDataRetention - */ - public function setLevel($level) - { - $this->level = $level; - - return $this; - } - - /** - * Get level - * - * @return string - */ - public function getLevel() - { - return $this->level; - } - - /** - * Get id - * - * @return integer - */ - public function getId() - { - return $this->id; - } -} diff --git a/Rox/Storage/MemberslanguageslevelBeforeDataRetention.php~ b/Rox/Storage/MemberslanguageslevelBeforeDataRetention.php~ deleted file mode 100644 index 142ee6d743..0000000000 --- a/Rox/Storage/MemberslanguageslevelBeforeDataRetention.php~ +++ /dev/null @@ -1,61 +0,0 @@ -idlanguage = $idlanguage; - - return $this; - } - - /** - * Get idlanguage - * - * @return integer - */ - public function getIdlanguage() - { - return $this->idlanguage; - } - - /** - * Set idowner - * - * @param integer $idowner - * - * @return MemberstradsBeforeDataRetention - */ - public function setIdowner($idowner) - { - $this->idowner = $idowner; - - return $this; - } - - /** - * Get idowner - * - * @return integer - */ - public function getIdowner() - { - return $this->idowner; - } - - /** - * Set idtrad - * - * @param integer $idtrad - * - * @return MemberstradsBeforeDataRetention - */ - public function setIdtrad($idtrad) - { - $this->idtrad = $idtrad; - - return $this; - } - - /** - * Get idtrad - * - * @return integer - */ - public function getIdtrad() - { - return $this->idtrad; - } - - /** - * Set idtranslator - * - * @param integer $idtranslator - * - * @return MemberstradsBeforeDataRetention - */ - public function setIdtranslator($idtranslator) - { - $this->idtranslator = $idtranslator; - - return $this; - } - - /** - * Get idtranslator - * - * @return integer - */ - public function getIdtranslator() - { - return $this->idtranslator; - } - - /** - * Set updated - * - * @param \DateTime $updated - * - * @return MemberstradsBeforeDataRetention - */ - public function setUpdated($updated) - { - $this->updated = $updated; - - return $this; - } - - /** - * Get updated - * - * @return \DateTime - */ - public function getUpdated() - { - return $this->updated; - } - - /** - * Set created - * - * @param \DateTime $created - * - * @return MemberstradsBeforeDataRetention - */ - public function setCreated($created) - { - $this->created = $created; - - return $this; - } - - /** - * Get created - * - * @return \DateTime - */ - public function getCreated() - { - return $this->created; - } - - /** - * Set type - * - * @param string $type - * - * @return MemberstradsBeforeDataRetention - */ - public function setType($type) - { - $this->type = $type; - - return $this; - } - - /** - * Get type - * - * @return string - */ - public function getType() - { - return $this->type; - } - - /** - * Set sentence - * - * @param string $sentence - * - * @return MemberstradsBeforeDataRetention - */ - public function setSentence($sentence) - { - $this->sentence = $sentence; - - return $this; - } - - /** - * Get sentence - * - * @return string - */ - public function getSentence() - { - return $this->sentence; - } - - /** - * Set idrecord - * - * @param integer $idrecord - * - * @return MemberstradsBeforeDataRetention - */ - public function setIdrecord($idrecord) - { - $this->idrecord = $idrecord; - - return $this; - } - - /** - * Get idrecord - * - * @return integer - */ - public function getIdrecord() - { - return $this->idrecord; - } - - /** - * Set tablecolumn - * - * @param string $tablecolumn - * - * @return MemberstradsBeforeDataRetention - */ - public function setTablecolumn($tablecolumn) - { - $this->tablecolumn = $tablecolumn; - - return $this; - } - - /** - * Get tablecolumn - * - * @return string - */ - public function getTablecolumn() - { - return $this->tablecolumn; - } - - /** - * Get id - * - * @return integer - */ - public function getId() - { - return $this->id; - } -} diff --git a/Rox/Storage/MemberstradsBeforeDataRetention.php~ b/Rox/Storage/MemberstradsBeforeDataRetention.php~ deleted file mode 100644 index 4c0f12d84b..0000000000 --- a/Rox/Storage/MemberstradsBeforeDataRetention.php~ +++ /dev/null @@ -1,96 +0,0 @@ -messagetype = $messagetype; - - return $this; - } - - /** - * Get messagetype - * - * @return string - */ - public function getMessagetype() - { - return $this->messagetype; - } - - /** - * Set idmessagefromlocalvol - * - * @param integer $idmessagefromlocalvol - * - * @return Messages - */ - public function setIdmessagefromlocalvol($idmessagefromlocalvol) - { - $this->idmessagefromlocalvol = $idmessagefromlocalvol; - - return $this; - } - - /** - * Get idmessagefromlocalvol - * - * @return integer - */ - public function getIdmessagefromlocalvol() - { - return $this->idmessagefromlocalvol; - } - - /** - * Set updated - * - * @param \DateTime $updated - * - * @return Messages - */ - public function setUpdated($updated) - { - $this->updated = $updated; - - return $this; - } - - /** - * Get updated - * - * @return \DateTime - */ - public function getUpdated() - { - return $this->updated; - } - - /** - * Set created - * - * @param \DateTime $created - * - * @return Messages - */ - public function setCreated($created) - { - $this->created = $created; - - return $this; - } - - /** - * Get created - * - * @return \DateTime - */ - public function getCreated() - { - return $this->created; - } - - /** - * Set datesent - * - * @param \DateTime $datesent - * - * @return Messages - */ - public function setDatesent($datesent) - { - $this->datesent = $datesent; - - return $this; - } - - /** - * Get datesent - * - * @return \DateTime - */ - public function getDatesent() - { - return $this->datesent; - } - - /** - * Set deleterequest - * - * @param string $deleterequest - * - * @return Messages - */ - public function setDeleterequest($deleterequest) - { - $this->deleterequest = $deleterequest; - - return $this; - } - - /** - * Get deleterequest - * - * @return string - */ - public function getDeleterequest() - { - return $this->deleterequest; - } - - /** - * Set idparent - * - * @param integer $idparent - * - * @return Messages - */ - public function setIdparent($idparent) - { - $this->idparent = $idparent; - - return $this; - } - - /** - * Get idparent - * - * @return integer - */ - public function getIdparent() - { - return $this->idparent; - } - - /** - * Set idreceiver - * - * @param integer $idreceiver - * - * @return Messages - */ - public function setIdreceiver($idreceiver) - { - $this->idreceiver = $idreceiver; - - return $this; - } - - /** - * Get idreceiver - * - * @return integer - */ - public function getIdreceiver() - { - return $this->idreceiver; - } - - /** - * Set idsender - * - * @param integer $idsender - * - * @return Messages - */ - public function setIdsender($idsender) - { - $this->idsender = $idsender; - - return $this; - } - - /** - * Get idsender - * - * @return integer - */ - public function getIdsender() - { - return $this->idsender; - } - - /** - * Set identityinformation - * - * @param string $identityinformation - * - * @return Messages - */ - public function setIdentityinformation($identityinformation) - { - $this->identityinformation = $identityinformation; - - return $this; - } - - /** - * Get identityinformation - * - * @return string - */ - public function getIdentityinformation() - { - return $this->identityinformation; - } - - /** - * Set sendconfirmation - * - * @param string $sendconfirmation - * - * @return Messages - */ - public function setSendconfirmation($sendconfirmation) - { - $this->sendconfirmation = $sendconfirmation; - - return $this; - } - - /** - * Get sendconfirmation - * - * @return string - */ - public function getSendconfirmation() - { - return $this->sendconfirmation; - } - - /** - * Set spaminfo - * - * @param string $spaminfo - * - * @return Messages - */ - public function setSpaminfo($spaminfo) - { - $this->spaminfo = $spaminfo; - - return $this; - } - - /** - * Get spaminfo - * - * @return string - */ - public function getSpaminfo() - { - return $this->spaminfo; - } - - /** - * Set status - * - * @param string $status - * - * @return Messages - */ - public function setStatus($status) - { - $this->status = $status; - - return $this; - } - - /** - * Get status - * - * @return string - */ - public function getStatus() - { - return $this->status; - } - - /** - * Set message - * - * @param string $message - * - * @return Messages - */ - public function setMessage($message) - { - $this->message = $message; - - return $this; - } - - /** - * Get message - * - * @return string - */ - public function getMessage() - { - return $this->message; - } - - /** - * Set infolder - * - * @param string $infolder - * - * @return Messages - */ - public function setInfolder($infolder) - { - $this->infolder = $infolder; - - return $this; - } - - /** - * Get infolder - * - * @return string - */ - public function getInfolder() - { - return $this->infolder; - } - - /** - * Set whenfirstread - * - * @param \DateTime $whenfirstread - * - * @return Messages - */ - public function setWhenfirstread($whenfirstread) - { - $this->whenfirstread = $whenfirstread; - - return $this; - } - - /** - * Get whenfirstread - * - * @return \DateTime - */ - public function getWhenfirstread() - { - return $this->whenfirstread; - } - - /** - * Set idchecker - * - * @param integer $idchecker - * - * @return Messages - */ - public function setIdchecker($idchecker) - { - $this->idchecker = $idchecker; - - return $this; - } - - /** - * Get idchecker - * - * @return integer - */ - public function getIdchecker() - { - return $this->idchecker; - } - - /** - * Set idtriggerer - * - * @param integer $idtriggerer - * - * @return Messages - */ - public function setIdtriggerer($idtriggerer) - { - $this->idtriggerer = $idtriggerer; - - return $this; - } - - /** - * Get idtriggerer - * - * @return integer - */ - public function getIdtriggerer() - { - return $this->idtriggerer; - } - - /** - * Set joinmemberpict - * - * @param string $joinmemberpict - * - * @return Messages - */ - public function setJoinmemberpict($joinmemberpict) - { - $this->joinmemberpict = $joinmemberpict; - - return $this; - } - - /** - * Get joinmemberpict - * - * @return string - */ - public function getJoinmemberpict() - { - return $this->joinmemberpict; - } - - /** - * Set checkercomment - * - * @param string $checkercomment - * - * @return Messages - */ - public function setCheckercomment($checkercomment) - { - $this->checkercomment = $checkercomment; - - return $this; - } - - /** - * Get checkercomment - * - * @return string - */ - public function getCheckercomment() - { - return $this->checkercomment; - } - - /** - * Get id - * - * @return integer - */ - public function getId() - { - return $this->id; - } -} diff --git a/Rox/Storage/Messages.php~ b/Rox/Storage/Messages.php~ deleted file mode 100644 index ee2b6d939e..0000000000 --- a/Rox/Storage/Messages.php~ +++ /dev/null @@ -1,166 +0,0 @@ -name = $name; - - return $this; - } - - /** - * Get name - * - * @return string - */ - public function getName() - { - return $this->name; - } - - /** - * Get id - * - * @return integer - */ - public function getId() - { - return $this->id; - } -} diff --git a/Rox/Storage/ModUserApps.php~ b/Rox/Storage/ModUserApps.php~ deleted file mode 100644 index c3ac0b848d..0000000000 --- a/Rox/Storage/ModUserApps.php~ +++ /dev/null @@ -1,33 +0,0 @@ -id; - } -} diff --git a/Rox/Storage/ModUserAppsSeq.php~ b/Rox/Storage/ModUserAppsSeq.php~ deleted file mode 100644 index d7023cfbe8..0000000000 --- a/Rox/Storage/ModUserAppsSeq.php~ +++ /dev/null @@ -1,26 +0,0 @@ -name = $name; - - return $this; - } - - /** - * Get name - * - * @return string - */ - public function getName() - { - return $this->name; - } - - /** - * Get id - * - * @return integer - */ - public function getId() - { - return $this->id; - } -} diff --git a/Rox/Storage/ModUserAuth.php~ b/Rox/Storage/ModUserAuth.php~ deleted file mode 100644 index a0a1828b24..0000000000 --- a/Rox/Storage/ModUserAuth.php~ +++ /dev/null @@ -1,33 +0,0 @@ -id; - } -} diff --git a/Rox/Storage/ModUserAuthSeq.php~ b/Rox/Storage/ModUserAuthSeq.php~ deleted file mode 100644 index f10f06a278..0000000000 --- a/Rox/Storage/ModUserAuthSeq.php~ +++ /dev/null @@ -1,26 +0,0 @@ -appId = $appId; - - return $this; - } - - /** - * Get appId - * - * @return integer - */ - public function getAppId() - { - return $this->appId; - } - - /** - * Set name - * - * @param string $name - * - * @return ModUserRights - */ - public function setName($name) - { - $this->name = $name; - - return $this; - } - - /** - * Get name - * - * @return string - */ - public function getName() - { - return $this->name; - } - - /** - * Set hasImplied - * - * @param integer $hasImplied - * - * @return ModUserRights - */ - public function setHasImplied($hasImplied) - { - $this->hasImplied = $hasImplied; - - return $this; - } - - /** - * Get hasImplied - * - * @return integer - */ - public function getHasImplied() - { - return $this->hasImplied; - } - - /** - * Set level - * - * @param integer $level - * - * @return ModUserRights - */ - public function setLevel($level) - { - $this->level = $level; - - return $this; - } - - /** - * Get level - * - * @return integer - */ - public function getLevel() - { - return $this->level; - } - - /** - * Get id - * - * @return integer - */ - public function getId() - { - return $this->id; - } -} diff --git a/Rox/Storage/ModUserRights.php~ b/Rox/Storage/ModUserRights.php~ deleted file mode 100644 index 9c4145e78f..0000000000 --- a/Rox/Storage/ModUserRights.php~ +++ /dev/null @@ -1,54 +0,0 @@ -id; - } -} diff --git a/Rox/Storage/ModUserRightsSeq.php~ b/Rox/Storage/ModUserRightsSeq.php~ deleted file mode 100644 index 8f88f3effe..0000000000 --- a/Rox/Storage/ModUserRightsSeq.php~ +++ /dev/null @@ -1,26 +0,0 @@ -updated = $updated; - - return $this; - } - - /** - * Get updated - * - * @return \DateTime - */ - public function getUpdated() - { - return $this->updated; - } - - /** - * Set appearance - * - * @param string $appearance - * - * @return Online - */ - public function setAppearance($appearance) - { - $this->appearance = $appearance; - - return $this; - } - - /** - * Get appearance - * - * @return string - */ - public function getAppearance() - { - return $this->appearance; - } - - /** - * Set lastactivity - * - * @param string $lastactivity - * - * @return Online - */ - public function setLastactivity($lastactivity) - { - $this->lastactivity = $lastactivity; - - return $this; - } - - /** - * Get lastactivity - * - * @return string - */ - public function getLastactivity() - { - return $this->lastactivity; - } - - /** - * Set status - * - * @param string $status - * - * @return Online - */ - public function setStatus($status) - { - $this->status = $status; - - return $this; - } - - /** - * Get status - * - * @return string - */ - public function getStatus() - { - return $this->status; - } - - /** - * Get idmember - * - * @return integer - */ - public function getIdmember() - { - return $this->idmember; - } -} diff --git a/Rox/Storage/Online.php~ b/Rox/Storage/Online.php~ deleted file mode 100644 index 4bd3b3185c..0000000000 --- a/Rox/Storage/Online.php~ +++ /dev/null @@ -1,54 +0,0 @@ -updated = $updated; - - return $this; - } - - /** - * Get updated - * - * @return \DateTime - */ - public function getUpdated() - { - return $this->updated; - } - - /** - * Set isrealproductiondatabase - * - * @param string $isrealproductiondatabase - * - * @return Params - */ - public function setIsrealproductiondatabase($isrealproductiondatabase) - { - $this->isrealproductiondatabase = $isrealproductiondatabase; - - return $this; - } - - /** - * Get isrealproductiondatabase - * - * @return string - */ - public function getIsrealproductiondatabase() - { - return $this->isrealproductiondatabase; - } - - /** - * Set recordonline - * - * @param integer $recordonline - * - * @return Params - */ - public function setRecordonline($recordonline) - { - $this->recordonline = $recordonline; - - return $this; - } - - /** - * Get recordonline - * - * @return integer - */ - public function getRecordonline() - { - return $this->recordonline; - } - - /** - * Set toggledonatebar - * - * @param integer $toggledonatebar - * - * @return Params - */ - public function setToggledonatebar($toggledonatebar) - { - $this->toggledonatebar = $toggledonatebar; - - return $this; - } - - /** - * Get toggledonatebar - * - * @return integer - */ - public function getToggledonatebar() - { - return $this->toggledonatebar; - } - - /** - * Set neededperyear - * - * @param integer $neededperyear - * - * @return Params - */ - public function setNeededperyear($neededperyear) - { - $this->neededperyear = $neededperyear; - - return $this; - } - - /** - * Get neededperyear - * - * @return integer - */ - public function getNeededperyear() - { - return $this->neededperyear; - } - - /** - * Set campaignstartdate - * - * @param \DateTime $campaignstartdate - * - * @return Params - */ - public function setCampaignstartdate($campaignstartdate) - { - $this->campaignstartdate = $campaignstartdate; - - return $this; - } - - /** - * Get campaignstartdate - * - * @return \DateTime - */ - public function getCampaignstartdate() - { - return $this->campaignstartdate; - } - - /** - * Set mailtonotifywhennewmembersignup - * - * @param string $mailtonotifywhennewmembersignup - * - * @return Params - */ - public function setMailtonotifywhennewmembersignup($mailtonotifywhennewmembersignup) - { - $this->mailtonotifywhennewmembersignup = $mailtonotifywhennewmembersignup; - - return $this; - } - - /** - * Get mailtonotifywhennewmembersignup - * - * @return string - */ - public function getMailtonotifywhennewmembersignup() - { - return $this->mailtonotifywhennewmembersignup; - } - - /** - * Set featureforumclosed - * - * @param string $featureforumclosed - * - * @return Params - */ - public function setFeatureforumclosed($featureforumclosed) - { - $this->featureforumclosed = $featureforumclosed; - - return $this; - } - - /** - * Get featureforumclosed - * - * @return string - */ - public function getFeatureforumclosed() - { - return $this->featureforumclosed; - } - - /** - * Set featureajaxchatclosed - * - * @param string $featureajaxchatclosed - * - * @return Params - */ - public function setFeatureajaxchatclosed($featureajaxchatclosed) - { - $this->featureajaxchatclosed = $featureajaxchatclosed; - - return $this; - } - - /** - * Get featureajaxchatclosed - * - * @return string - */ - public function getFeatureajaxchatclosed() - { - return $this->featureajaxchatclosed; - } - - /** - * Set featuresignupclose - * - * @param string $featuresignupclose - * - * @return Params - */ - public function setFeaturesignupclose($featuresignupclose) - { - $this->featuresignupclose = $featuresignupclose; - - return $this; - } - - /** - * Get featuresignupclose - * - * @return string - */ - public function getFeaturesignupclose() - { - return $this->featuresignupclose; - } - - /** - * Set featuresearchpageisclosed - * - * @param string $featuresearchpageisclosed - * - * @return Params - */ - public function setFeaturesearchpageisclosed($featuresearchpageisclosed) - { - $this->featuresearchpageisclosed = $featuresearchpageisclosed; - - return $this; - } - - /** - * Get featuresearchpageisclosed - * - * @return string - */ - public function getFeaturesearchpageisclosed() - { - return $this->featuresearchpageisclosed; - } - - /** - * Set featurequicksearchisclosed - * - * @param string $featurequicksearchisclosed - * - * @return Params - */ - public function setFeaturequicksearchisclosed($featurequicksearchisclosed) - { - $this->featurequicksearchisclosed = $featurequicksearchisclosed; - - return $this; - } - - /** - * Get featurequicksearchisclosed - * - * @return string - */ - public function getFeaturequicksearchisclosed() - { - return $this->featurequicksearchisclosed; - } - - /** - * Set rssfeedisclosed - * - * @param string $rssfeedisclosed - * - * @return Params - */ - public function setRssfeedisclosed($rssfeedisclosed) - { - $this->rssfeedisclosed = $rssfeedisclosed; - - return $this; - } - - /** - * Get rssfeedisclosed - * - * @return string - */ - public function getRssfeedisclosed() - { - return $this->rssfeedisclosed; - } - - /** - * Set ajaxchatspecialallowedlist - * - * @param string $ajaxchatspecialallowedlist - * - * @return Params - */ - public function setAjaxchatspecialallowedlist($ajaxchatspecialallowedlist) - { - $this->ajaxchatspecialallowedlist = $ajaxchatspecialallowedlist; - - return $this; - } - - /** - * Get ajaxchatspecialallowedlist - * - * @return string - */ - public function getAjaxchatspecialallowedlist() - { - return $this->ajaxchatspecialallowedlist; - } - - /** - * Set ajaxchatdebulevel - * - * @param integer $ajaxchatdebulevel - * - * @return Params - */ - public function setAjaxchatdebulevel($ajaxchatdebulevel) - { - $this->ajaxchatdebulevel = $ajaxchatdebulevel; - - return $this; - } - - /** - * Get ajaxchatdebulevel - * - * @return integer - */ - public function getAjaxchatdebulevel() - { - return $this->ajaxchatdebulevel; - } - - /** - * Set reloadrightsandflags - * - * @param string $reloadrightsandflags - * - * @return Params - */ - public function setReloadrightsandflags($reloadrightsandflags) - { - $this->reloadrightsandflags = $reloadrightsandflags; - - return $this; - } - - /** - * Get reloadrightsandflags - * - * @return string - */ - public function getReloadrightsandflags() - { - return $this->reloadrightsandflags; - } - - /** - * Set logsIdMidnight - * - * @param integer $logsIdMidnight - * - * @return Params - */ - public function setLogsIdMidnight($logsIdMidnight) - { - $this->logsIdMidnight = $logsIdMidnight; - - return $this; - } - - /** - * Get logsIdMidnight - * - * @return integer - */ - public function getLogsIdMidnight() - { - return $this->logsIdMidnight; - } - - /** - * Set previousLogsIdMidnight - * - * @param integer $previousLogsIdMidnight - * - * @return Params - */ - public function setPreviousLogsIdMidnight($previousLogsIdMidnight) - { - $this->previousLogsIdMidnight = $previousLogsIdMidnight; - - return $this; - } - - /** - * Get previousLogsIdMidnight - * - * @return integer - */ - public function getPreviousLogsIdMidnight() - { - return $this->previousLogsIdMidnight; - } - - /** - * Set memcache - * - * @param string $memcache - * - * @return Params - */ - public function setMemcache($memcache) - { - $this->memcache = $memcache; - - return $this; - } - - /** - * Get memcache - * - * @return string - */ - public function getMemcache() - { - return $this->memcache; - } - - /** - * Set daylightoffset - * - * @param integer $daylightoffset - * - * @return Params - */ - public function setDaylightoffset($daylightoffset) - { - $this->daylightoffset = $daylightoffset; - - return $this; - } - - /** - * Get daylightoffset - * - * @return integer - */ - public function getDaylightoffset() - { - return $this->daylightoffset; - } - - /** - * Set nbcommentsinlastcomments - * - * @param integer $nbcommentsinlastcomments - * - * @return Params - */ - public function setNbcommentsinlastcomments($nbcommentsinlastcomments) - { - $this->nbcommentsinlastcomments = $nbcommentsinlastcomments; - - return $this; - } - - /** - * Get nbcommentsinlastcomments - * - * @return integer - */ - public function getNbcommentsinlastcomments() - { - return $this->nbcommentsinlastcomments; - } - - /** - * Set idcommentofthemoment - * - * @param integer $idcommentofthemoment - * - * @return Params - */ - public function setIdcommentofthemoment($idcommentofthemoment) - { - $this->idcommentofthemoment = $idcommentofthemoment; - - return $this; - } - - /** - * Get idcommentofthemoment - * - * @return integer - */ - public function getIdcommentofthemoment() - { - return $this->idcommentofthemoment; - } - - /** - * Set mailbotmode - * - * @param string $mailbotmode - * - * @return Params - */ - public function setMailbotmode($mailbotmode) - { - $this->mailbotmode = $mailbotmode; - - return $this; - } - - /** - * Get mailbotmode - * - * @return string - */ - public function getMailbotmode() - { - return $this->mailbotmode; - } - - /** - * Set togglestatsforwordsusage - * - * @param string $togglestatsforwordsusage - * - * @return Params - */ - public function setTogglestatsforwordsusage($togglestatsforwordsusage) - { - $this->togglestatsforwordsusage = $togglestatsforwordsusage; - - return $this; - } - - /** - * Get togglestatsforwordsusage - * - * @return string - */ - public function getTogglestatsforwordsusage() - { - return $this->togglestatsforwordsusage; - } - - /** - * Get id - * - * @return integer - */ - public function getId() - { - return $this->id; - } -} diff --git a/Rox/Storage/Params.php~ b/Rox/Storage/Params.php~ deleted file mode 100644 index 51b1ca5ddb..0000000000 --- a/Rox/Storage/Params.php~ +++ /dev/null @@ -1,194 +0,0 @@ -idmember = $idmember; - - return $this; - } - - /** - * Get idmember - * - * @return integer - */ - public function getIdmember() - { - return $this->idmember; - } - - /** - * Set created - * - * @param \DateTime $created - * - * @return Pendingmandatory - */ - public function setCreated($created) - { - $this->created = $created; - - return $this; - } - - /** - * Get created - * - * @return \DateTime - */ - public function getCreated() - { - return $this->created; - } - - /** - * Set firstname - * - * @param string $firstname - * - * @return Pendingmandatory - */ - public function setFirstname($firstname) - { - $this->firstname = $firstname; - - return $this; - } - - /** - * Get firstname - * - * @return string - */ - public function getFirstname() - { - return $this->firstname; - } - - /** - * Set secondname - * - * @param string $secondname - * - * @return Pendingmandatory - */ - public function setSecondname($secondname) - { - $this->secondname = $secondname; - - return $this; - } - - /** - * Get secondname - * - * @return string - */ - public function getSecondname() - { - return $this->secondname; - } - - /** - * Set lastname - * - * @param string $lastname - * - * @return Pendingmandatory - */ - public function setLastname($lastname) - { - $this->lastname = $lastname; - - return $this; - } - - /** - * Get lastname - * - * @return string - */ - public function getLastname() - { - return $this->lastname; - } - - /** - * Set housenumber - * - * @param string $housenumber - * - * @return Pendingmandatory - */ - public function setHousenumber($housenumber) - { - $this->housenumber = $housenumber; - - return $this; - } - - /** - * Get housenumber - * - * @return string - */ - public function getHousenumber() - { - return $this->housenumber; - } - - /** - * Set streetname - * - * @param string $streetname - * - * @return Pendingmandatory - */ - public function setStreetname($streetname) - { - $this->streetname = $streetname; - - return $this; - } - - /** - * Get streetname - * - * @return string - */ - public function getStreetname() - { - return $this->streetname; - } - - /** - * Set zip - * - * @param string $zip - * - * @return Pendingmandatory - */ - public function setZip($zip) - { - $this->zip = $zip; - - return $this; - } - - /** - * Get zip - * - * @return string - */ - public function getZip() - { - return $this->zip; - } - - /** - * Set idcity - * - * @param integer $idcity - * - * @return Pendingmandatory - */ - public function setIdcity($idcity) - { - $this->idcity = $idcity; - - return $this; - } - - /** - * Get idcity - * - * @return integer - */ - public function getIdcity() - { - return $this->idcity; - } - - /** - * Set comment - * - * @param string $comment - * - * @return Pendingmandatory - */ - public function setComment($comment) - { - $this->comment = $comment; - - return $this; - } - - /** - * Get comment - * - * @return string - */ - public function getComment() - { - return $this->comment; - } - - /** - * Set status - * - * @param string $status - * - * @return Pendingmandatory - */ - public function setStatus($status) - { - $this->status = $status; - - return $this; - } - - /** - * Get status - * - * @return string - */ - public function getStatus() - { - return $this->status; - } - - /** - * Set idaddress - * - * @param integer $idaddress - * - * @return Pendingmandatory - */ - public function setIdaddress($idaddress) - { - $this->idaddress = $idaddress; - - return $this; - } - - /** - * Get idaddress - * - * @return integer - */ - public function getIdaddress() - { - return $this->idaddress; - } - - /** - * Get id - * - * @return integer - */ - public function getId() - { - return $this->id; - } -} diff --git a/Rox/Storage/Pendingmandatory.php~ b/Rox/Storage/Pendingmandatory.php~ deleted file mode 100644 index 65dd4df20f..0000000000 --- a/Rox/Storage/Pendingmandatory.php~ +++ /dev/null @@ -1,110 +0,0 @@ -migrationName = $migrationName; - - return $this; - } - - /** - * Get migrationName - * - * @return string - */ - public function getMigrationName() - { - return $this->migrationName; - } - - /** - * Set startTime - * - * @param \DateTime $startTime - * - * @return Phinxlog - */ - public function setStartTime($startTime) - { - $this->startTime = $startTime; - - return $this; - } - - /** - * Get startTime - * - * @return \DateTime - */ - public function getStartTime() - { - return $this->startTime; - } - - /** - * Set endTime - * - * @param \DateTime $endTime - * - * @return Phinxlog - */ - public function setEndTime($endTime) - { - $this->endTime = $endTime; - - return $this; - } - - /** - * Get endTime - * - * @return \DateTime - */ - public function getEndTime() - { - return $this->endTime; - } - - /** - * Set breakpoint - * - * @param boolean $breakpoint - * - * @return Phinxlog - */ - public function setBreakpoint($breakpoint) - { - $this->breakpoint = $breakpoint; - - return $this; - } - - /** - * Get breakpoint - * - * @return boolean - */ - public function getBreakpoint() - { - return $this->breakpoint; - } - - /** - * Get version - * - * @return integer - */ - public function getVersion() - { - return $this->version; - } -} diff --git a/Rox/Storage/Phinxlog.php~ b/Rox/Storage/Phinxlog.php~ deleted file mode 100644 index 9166ec7d51..0000000000 --- a/Rox/Storage/Phinxlog.php~ +++ /dev/null @@ -1,54 +0,0 @@ -idmember = $idmember; - - return $this; - } - - /** - * Get idmember - * - * @return integer - */ - public function getIdmember() - { - return $this->idmember; - } - - /** - * Set tablename - * - * @param string $tablename - * - * @return Previousversion - */ - public function setTablename($tablename) - { - $this->tablename = $tablename; - - return $this; - } - - /** - * Get tablename - * - * @return string - */ - public function getTablename() - { - return $this->tablename; - } - - /** - * Set idintable - * - * @param integer $idintable - * - * @return Previousversion - */ - public function setIdintable($idintable) - { - $this->idintable = $idintable; - - return $this; - } - - /** - * Get idintable - * - * @return integer - */ - public function getIdintable() - { - return $this->idintable; - } - - /** - * Set type - * - * @param string $type - * - * @return Previousversion - */ - public function setType($type) - { - $this->type = $type; - - return $this; - } - - /** - * Get type - * - * @return string - */ - public function getType() - { - return $this->type; - } - - /** - * Set xmloldversion - * - * @param string $xmloldversion - * - * @return Previousversion - */ - public function setXmloldversion($xmloldversion) - { - $this->xmloldversion = $xmloldversion; - - return $this; - } - - /** - * Get xmloldversion - * - * @return string - */ - public function getXmloldversion() - { - return $this->xmloldversion; - } - - /** - * Set created - * - * @param \DateTime $created - * - * @return Previousversion - */ - public function setCreated($created) - { - $this->created = $created; - - return $this; - } - - /** - * Get created - * - * @return \DateTime - */ - public function getCreated() - { - return $this->created; - } - - /** - * Get id - * - * @return integer - */ - public function getId() - { - return $this->id; - } -} diff --git a/Rox/Storage/Previousversion.php~ b/Rox/Storage/Previousversion.php~ deleted file mode 100644 index f4cc9a56dd..0000000000 --- a/Rox/Storage/Previousversion.php~ +++ /dev/null @@ -1,68 +0,0 @@ -idmember = $idmember; - - return $this; - } - - /** - * Get idmember - * - * @return integer - */ - public function getIdmember() - { - return $this->idmember; - } - - /** - * Set idvisitor - * - * @param integer $idvisitor - * - * @return Recentvisits - */ - public function setIdvisitor($idvisitor) - { - $this->idvisitor = $idvisitor; - - return $this; - } - - /** - * Get idvisitor - * - * @return integer - */ - public function getIdvisitor() - { - return $this->idvisitor; - } - - /** - * Set created - * - * @param \DateTime $created - * - * @return Recentvisits - */ - public function setCreated($created) - { - $this->created = $created; - - return $this; - } - - /** - * Get created - * - * @return \DateTime - */ - public function getCreated() - { - return $this->created; - } - - /** - * Get id - * - * @return integer - */ - public function getId() - { - return $this->id; - } -} diff --git a/Rox/Storage/Recentvisits.php~ b/Rox/Storage/Recentvisits.php~ deleted file mode 100644 index d90d9872ac..0000000000 --- a/Rox/Storage/Recentvisits.php~ +++ /dev/null @@ -1,47 +0,0 @@ -usernamenottouse; - } -} diff --git a/Rox/Storage/RecordedUsernamesOfLeftMembers.php~ b/Rox/Storage/RecordedUsernamesOfLeftMembers.php~ deleted file mode 100644 index 7d94440dd0..0000000000 --- a/Rox/Storage/RecordedUsernamesOfLeftMembers.php~ +++ /dev/null @@ -1,26 +0,0 @@ -updated = $updated; - - return $this; - } - - /** - * Get updated - * - * @return \DateTime - */ - public function getUpdated() - { - return $this->updated; - } - - /** - * Set idrole - * - * @param integer $idrole - * - * @return RolesPrivileges - */ - public function setIdrole($idrole) - { - $this->idrole = $idrole; - - return $this; - } - - /** - * Get idrole - * - * @return integer - */ - public function getIdrole() - { - return $this->idrole; - } - - /** - * Set idprivilege - * - * @param integer $idprivilege - * - * @return RolesPrivileges - */ - public function setIdprivilege($idprivilege) - { - $this->idprivilege = $idprivilege; - - return $this; - } - - /** - * Get idprivilege - * - * @return integer - */ - public function getIdprivilege() - { - return $this->idprivilege; - } -} diff --git a/Rox/Storage/RolesPrivileges.php~ b/Rox/Storage/RolesPrivileges.php~ deleted file mode 100644 index aea7207054..0000000000 --- a/Rox/Storage/RolesPrivileges.php~ +++ /dev/null @@ -1,42 +0,0 @@ -id; - } -} diff --git a/Rox/Storage/ShoutsSeq.php~ b/Rox/Storage/ShoutsSeq.php~ deleted file mode 100644 index a1f5897d4a..0000000000 --- a/Rox/Storage/ShoutsSeq.php~ +++ /dev/null @@ -1,26 +0,0 @@ -name = $name; - - return $this; - } - - /** - * Get name - * - * @return string - */ - public function getName() - { - return $this->name; - } - - /** - * Set query - * - * @param string $query - * - * @return Sqlforvolunteers - */ - public function setQuery($query) - { - $this->query = $query; - - return $this; - } - - /** - * Get query - * - * @return string - */ - public function getQuery() - { - return $this->query; - } - - /** - * Set updated - * - * @param \DateTime $updated - * - * @return Sqlforvolunteers - */ - public function setUpdated($updated) - { - $this->updated = $updated; - - return $this; - } - - /** - * Get updated - * - * @return \DateTime - */ - public function getUpdated() - { - return $this->updated; - } - - /** - * Set param1 - * - * @param string $param1 - * - * @return Sqlforvolunteers - */ - public function setParam1($param1) - { - $this->param1 = $param1; - - return $this; - } - - /** - * Get param1 - * - * @return string - */ - public function getParam1() - { - return $this->param1; - } - - /** - * Set param2 - * - * @param string $param2 - * - * @return Sqlforvolunteers - */ - public function setParam2($param2) - { - $this->param2 = $param2; - - return $this; - } - - /** - * Get param2 - * - * @return string - */ - public function getParam2() - { - return $this->param2; - } - - /** - * Set logme - * - * @param string $logme - * - * @return Sqlforvolunteers - */ - public function setLogme($logme) - { - $this->logme = $logme; - - return $this; - } - - /** - * Get logme - * - * @return string - */ - public function getLogme() - { - return $this->logme; - } - - /** - * Set defvalueparam1 - * - * @param string $defvalueparam1 - * - * @return Sqlforvolunteers - */ - public function setDefvalueparam1($defvalueparam1) - { - $this->defvalueparam1 = $defvalueparam1; - - return $this; - } - - /** - * Get defvalueparam1 - * - * @return string - */ - public function getDefvalueparam1() - { - return $this->defvalueparam1; - } - - /** - * Set defvalueparam2 - * - * @param string $defvalueparam2 - * - * @return Sqlforvolunteers - */ - public function setDefvalueparam2($defvalueparam2) - { - $this->defvalueparam2 = $defvalueparam2; - - return $this; - } - - /** - * Get defvalueparam2 - * - * @return string - */ - public function getDefvalueparam2() - { - return $this->defvalueparam2; - } - - /** - * Set param1type - * - * @param string $param1type - * - * @return Sqlforvolunteers - */ - public function setParam1type($param1type) - { - $this->param1type = $param1type; - - return $this; - } - - /** - * Get param1type - * - * @return string - */ - public function getParam1type() - { - return $this->param1type; - } - - /** - * Set param2type - * - * @param string $param2type - * - * @return Sqlforvolunteers - */ - public function setParam2type($param2type) - { - $this->param2type = $param2type; - - return $this; - } - - /** - * Get param2type - * - * @return string - */ - public function getParam2type() - { - return $this->param2type; - } - - /** - * Set param3 - * - * @param string $param3 - * - * @return Sqlforvolunteers - */ - public function setParam3($param3) - { - $this->param3 = $param3; - - return $this; - } - - /** - * Get param3 - * - * @return string - */ - public function getParam3() - { - return $this->param3; - } - - /** - * Set defvalueparam3 - * - * @param string $defvalueparam3 - * - * @return Sqlforvolunteers - */ - public function setDefvalueparam3($defvalueparam3) - { - $this->defvalueparam3 = $defvalueparam3; - - return $this; - } - - /** - * Get defvalueparam3 - * - * @return string - */ - public function getDefvalueparam3() - { - return $this->defvalueparam3; - } - - /** - * Set param3type - * - * @param string $param3type - * - * @return Sqlforvolunteers - */ - public function setParam3type($param3type) - { - $this->param3type = $param3type; - - return $this; - } - - /** - * Get param3type - * - * @return string - */ - public function getParam3type() - { - return $this->param3type; - } - - /** - * Set param4 - * - * @param string $param4 - * - * @return Sqlforvolunteers - */ - public function setParam4($param4) - { - $this->param4 = $param4; - - return $this; - } - - /** - * Get param4 - * - * @return string - */ - public function getParam4() - { - return $this->param4; - } - - /** - * Set defvalueparam4 - * - * @param string $defvalueparam4 - * - * @return Sqlforvolunteers - */ - public function setDefvalueparam4($defvalueparam4) - { - $this->defvalueparam4 = $defvalueparam4; - - return $this; - } - - /** - * Get defvalueparam4 - * - * @return string - */ - public function getDefvalueparam4() - { - return $this->defvalueparam4; - } - - /** - * Set param4type - * - * @param string $param4type - * - * @return Sqlforvolunteers - */ - public function setParam4type($param4type) - { - $this->param4type = $param4type; - - return $this; - } - - /** - * Get param4type - * - * @return string - */ - public function getParam4type() - { - return $this->param4type; - } - - /** - * Set param5 - * - * @param string $param5 - * - * @return Sqlforvolunteers - */ - public function setParam5($param5) - { - $this->param5 = $param5; - - return $this; - } - - /** - * Get param5 - * - * @return string - */ - public function getParam5() - { - return $this->param5; - } - - /** - * Set defvalueparam5 - * - * @param string $defvalueparam5 - * - * @return Sqlforvolunteers - */ - public function setDefvalueparam5($defvalueparam5) - { - $this->defvalueparam5 = $defvalueparam5; - - return $this; - } - - /** - * Get defvalueparam5 - * - * @return string - */ - public function getDefvalueparam5() - { - return $this->defvalueparam5; - } - - /** - * Set param5type - * - * @param string $param5type - * - * @return Sqlforvolunteers - */ - public function setParam5type($param5type) - { - $this->param5type = $param5type; - - return $this; - } - - /** - * Get param5type - * - * @return string - */ - public function getParam5type() - { - return $this->param5type; - } - - /** - * Get id - * - * @return integer - */ - public function getId() - { - return $this->id; - } -} diff --git a/Rox/Storage/Sqlforvolunteers.php~ b/Rox/Storage/Sqlforvolunteers.php~ deleted file mode 100644 index 1fdf41b00f..0000000000 --- a/Rox/Storage/Sqlforvolunteers.php~ +++ /dev/null @@ -1,159 +0,0 @@ -geonameid = $geonameid; - - return $this; - } - - /** - * Get geonameid - * - * @return integer - */ - public function getGeonameid() - { - return $this->geonameid; - } - - /** - * Set arrival - * - * @param \DateTime $arrival - * - * @return SubTrips - */ - public function setArrival($arrival) - { - $this->arrival = $arrival; - - return $this; - } - - /** - * Get arrival - * - * @return \DateTime - */ - public function getArrival() - { - return $this->arrival; - } - - /** - * Set departure - * - * @param \DateTime $departure - * - * @return SubTrips - */ - public function setDeparture($departure) - { - $this->departure = $departure; - - return $this; - } - - /** - * Get departure - * - * @return \DateTime - */ - public function getDeparture() - { - return $this->departure; - } - - /** - * Set options - * - * @param integer $options - * - * @return SubTrips - */ - public function setOptions($options) - { - $this->options = $options; - - return $this; - } - - /** - * Get options - * - * @return integer - */ - public function getOptions() - { - return $this->options; - } - - /** - * Get id - * - * @return integer - */ - public function getId() - { - return $this->id; - } - - /** - * Set trip - * - * @param \App\Entity\Trips $trip - * - * @return SubTrips - */ - public function setTrip(\App\Entity\Trips $trip = null) - { - $this->trip = $trip; - - return $this; - } - - /** - * Get trip - * - * @return \App\Entity\Trips - */ - public function getTrip() - { - return $this->trip; - } -} diff --git a/Rox/Storage/SubTrips.php~ b/Rox/Storage/SubTrips.php~ deleted file mode 100644 index 382c5320a5..0000000000 --- a/Rox/Storage/SubTrips.php~ +++ /dev/null @@ -1,64 +0,0 @@ -summary = $summary; - - return $this; - } - - /** - * Get summary - * - * @return string - */ - public function getSummary() - { - return $this->summary; - } - - /** - * Set description - * - * @param string $description - * - * @return Suggestions - */ - public function setDescription($description) - { - $this->description = $description; - - return $this; - } - - /** - * Get description - * - * @return string - */ - public function getDescription() - { - return $this->description; - } - - /** - * Set salt - * - * @param string $salt - * - * @return Suggestions - */ - public function setSalt($salt) - { - $this->salt = $salt; - - return $this; - } - - /** - * Get salt - * - * @return string - */ - public function getSalt() - { - return $this->salt; - } - - /** - * Set state - * - * @param integer $state - * - * @return Suggestions - */ - public function setState($state) - { - $this->state = $state; - - return $this; - } - - /** - * Get state - * - * @return integer - */ - public function getState() - { - return $this->state; - } - - /** - * Set flags - * - * @param integer $flags - * - * @return Suggestions - */ - public function setFlags($flags) - { - $this->flags = $flags; - - return $this; - } - - /** - * Get flags - * - * @return integer - */ - public function getFlags() - { - return $this->flags; - } - - /** - * Set threadid - * - * @param integer $threadid - * - * @return Suggestions - */ - public function setThreadid($threadid) - { - $this->threadid = $threadid; - - return $this; - } - - /** - * Get threadid - * - * @return integer - */ - public function getThreadid() - { - return $this->threadid; - } - - /** - * Set created - * - * @param \DateTime $created - * - * @return Suggestions - */ - public function setCreated($created) - { - $this->created = $created; - - return $this; - } - - /** - * Get created - * - * @return \DateTime - */ - public function getCreated() - { - return $this->created; - } - - /** - * Set createdby - * - * @param integer $createdby - * - * @return Suggestions - */ - public function setCreatedby($createdby) - { - $this->createdby = $createdby; - - return $this; - } - - /** - * Get createdby - * - * @return integer - */ - public function getCreatedby() - { - return $this->createdby; - } - - /** - * Set modified - * - * @param \DateTime $modified - * - * @return Suggestions - */ - public function setModified($modified) - { - $this->modified = $modified; - - return $this; - } - - /** - * Get modified - * - * @return \DateTime - */ - public function getModified() - { - return $this->modified; - } - - /** - * Set modifiedby - * - * @param integer $modifiedby - * - * @return Suggestions - */ - public function setModifiedby($modifiedby) - { - $this->modifiedby = $modifiedby; - - return $this; - } - - /** - * Get modifiedby - * - * @return integer - */ - public function getModifiedby() - { - return $this->modifiedby; - } - - /** - * Set laststatechanged - * - * @param \DateTime $laststatechanged - * - * @return Suggestions - */ - public function setLaststatechanged($laststatechanged) - { - $this->laststatechanged = $laststatechanged; - - return $this; - } - - /** - * Get laststatechanged - * - * @return \DateTime - */ - public function getLaststatechanged() - { - return $this->laststatechanged; - } - - /** - * Set votingend - * - * @param \DateTime $votingend - * - * @return Suggestions - */ - public function setVotingend($votingend) - { - $this->votingend = $votingend; - - return $this; - } - - /** - * Get votingend - * - * @return \DateTime - */ - public function getVotingend() - { - return $this->votingend; - } - - /** - * Get id - * - * @return integer - */ - public function getId() - { - return $this->id; - } -} diff --git a/Rox/Storage/Suggestions.php~ b/Rox/Storage/Suggestions.php~ deleted file mode 100644 index 5682686933..0000000000 --- a/Rox/Storage/Suggestions.php~ +++ /dev/null @@ -1,110 +0,0 @@ -vote = $vote; - - return $this; - } - - /** - * Get vote - * - * @return integer - */ - public function getVote() - { - return $this->vote; - } - - /** - * Set optionid - * - * @param integer $optionid - * - * @return SuggestionsOptionRanks - */ - public function setOptionid($optionid) - { - $this->optionid = $optionid; - - return $this; - } - - /** - * Get optionid - * - * @return integer - */ - public function getOptionid() - { - return $this->optionid; - } - - /** - * Set memberhash - * - * @param string $memberhash - * - * @return SuggestionsOptionRanks - */ - public function setMemberhash($memberhash) - { - $this->memberhash = $memberhash; - - return $this; - } - - /** - * Get memberhash - * - * @return string - */ - public function getMemberhash() - { - return $this->memberhash; - } -} diff --git a/Rox/Storage/SuggestionsOptionRanks.php~ b/Rox/Storage/SuggestionsOptionRanks.php~ deleted file mode 100644 index 73a2c812d4..0000000000 --- a/Rox/Storage/SuggestionsOptionRanks.php~ +++ /dev/null @@ -1,42 +0,0 @@ -suggestionid = $suggestionid; - - return $this; - } - - /** - * Get suggestionid - * - * @return integer - */ - public function getSuggestionid() - { - return $this->suggestionid; - } - - /** - * Set state - * - * @param integer $state - * - * @return SuggestionsOptions - */ - public function setState($state) - { - $this->state = $state; - - return $this; - } - - /** - * Get state - * - * @return integer - */ - public function getState() - { - return $this->state; - } - - /** - * Set summary - * - * @param string $summary - * - * @return SuggestionsOptions - */ - public function setSummary($summary) - { - $this->summary = $summary; - - return $this; - } - - /** - * Get summary - * - * @return string - */ - public function getSummary() - { - return $this->summary; - } - - /** - * Set description - * - * @param string $description - * - * @return SuggestionsOptions - */ - public function setDescription($description) - { - $this->description = $description; - - return $this; - } - - /** - * Get description - * - * @return string - */ - public function getDescription() - { - return $this->description; - } - - /** - * Set created - * - * @param \DateTime $created - * - * @return SuggestionsOptions - */ - public function setCreated($created) - { - $this->created = $created; - - return $this; - } - - /** - * Get created - * - * @return \DateTime - */ - public function getCreated() - { - return $this->created; - } - - /** - * Set createdby - * - * @param integer $createdby - * - * @return SuggestionsOptions - */ - public function setCreatedby($createdby) - { - $this->createdby = $createdby; - - return $this; - } - - /** - * Get createdby - * - * @return integer - */ - public function getCreatedby() - { - return $this->createdby; - } - - /** - * Set modified - * - * @param \DateTime $modified - * - * @return SuggestionsOptions - */ - public function setModified($modified) - { - $this->modified = $modified; - - return $this; - } - - /** - * Get modified - * - * @return \DateTime - */ - public function getModified() - { - return $this->modified; - } - - /** - * Set modifiedby - * - * @param integer $modifiedby - * - * @return SuggestionsOptions - */ - public function setModifiedby($modifiedby) - { - $this->modifiedby = $modifiedby; - - return $this; - } - - /** - * Get modifiedby - * - * @return integer - */ - public function getModifiedby() - { - return $this->modifiedby; - } - - /** - * Set deleted - * - * @param \DateTime $deleted - * - * @return SuggestionsOptions - */ - public function setDeleted($deleted) - { - $this->deleted = $deleted; - - return $this; - } - - /** - * Get deleted - * - * @return \DateTime - */ - public function getDeleted() - { - return $this->deleted; - } - - /** - * Set deletedby - * - * @param integer $deletedby - * - * @return SuggestionsOptions - */ - public function setDeletedby($deletedby) - { - $this->deletedby = $deletedby; - - return $this; - } - - /** - * Get deletedby - * - * @return integer - */ - public function getDeletedby() - { - return $this->deletedby; - } - - /** - * Set mutuallyexclusivewith - * - * @param string $mutuallyexclusivewith - * - * @return SuggestionsOptions - */ - public function setMutuallyexclusivewith($mutuallyexclusivewith) - { - $this->mutuallyexclusivewith = $mutuallyexclusivewith; - - return $this; - } - - /** - * Get mutuallyexclusivewith - * - * @return string - */ - public function getMutuallyexclusivewith() - { - return $this->mutuallyexclusivewith; - } - - /** - * Set rank - * - * @param boolean $rank - * - * @return SuggestionsOptions - */ - public function setRank($rank) - { - $this->rank = $rank; - - return $this; - } - - /** - * Get rank - * - * @return boolean - */ - public function getRank() - { - return $this->rank; - } - - /** - * Set orderhint - * - * @param integer $orderhint - * - * @return SuggestionsOptions - */ - public function setOrderhint($orderhint) - { - $this->orderhint = $orderhint; - - return $this; - } - - /** - * Get orderhint - * - * @return integer - */ - public function getOrderhint() - { - return $this->orderhint; - } - - /** - * Get id - * - * @return integer - */ - public function getId() - { - return $this->id; - } -} diff --git a/Rox/Storage/SuggestionsOptions.php~ b/Rox/Storage/SuggestionsOptions.php~ deleted file mode 100644 index ef32478bf7..0000000000 --- a/Rox/Storage/SuggestionsOptions.php~ +++ /dev/null @@ -1,117 +0,0 @@ -suggestionid = $suggestionid; - - return $this; - } - - /** - * Get suggestionid - * - * @return integer - */ - public function getSuggestionid() - { - return $this->suggestionid; - } - - /** - * Set optionid - * - * @param integer $optionid - * - * @return SuggestionsVotes - */ - public function setOptionid($optionid) - { - $this->optionid = $optionid; - - return $this; - } - - /** - * Get optionid - * - * @return integer - */ - public function getOptionid() - { - return $this->optionid; - } - - /** - * Set rank - * - * @param integer $rank - * - * @return SuggestionsVotes - */ - public function setRank($rank) - { - $this->rank = $rank; - - return $this; - } - - /** - * Get rank - * - * @return integer - */ - public function getRank() - { - return $this->rank; - } - - /** - * Set memberhash - * - * @param string $memberhash - * - * @return SuggestionsVotes - */ - public function setMemberhash($memberhash) - { - $this->memberhash = $memberhash; - - return $this; - } - - /** - * Get memberhash - * - * @return string - */ - public function getMemberhash() - { - return $this->memberhash; - } - - /** - * Get id - * - * @return integer - */ - public function getId() - { - return $this->id; - } -} diff --git a/Rox/Storage/SuggestionsVotes.php~ b/Rox/Storage/SuggestionsVotes.php~ deleted file mode 100644 index 8b9030d2c0..0000000000 --- a/Rox/Storage/SuggestionsVotes.php~ +++ /dev/null @@ -1,54 +0,0 @@ -name = $name; - - return $this; - } - - /** - * Get name - * - * @return integer - */ - public function getName() - { - return $this->name; - } - - /** - * Set description - * - * @param integer $description - * - * @return Tags - */ - public function setDescription($description) - { - $this->description = $description; - - return $this; - } - - /** - * Get description - * - * @return integer - */ - public function getDescription() - { - return $this->description; - } - - /** - * Set type - * - * @param string $type - * - * @return Tags - */ - public function setType($type) - { - $this->type = $type; - - return $this; - } - - /** - * Get type - * - * @return string - */ - public function getType() - { - return $this->type; - } - - /** - * Set position - * - * @param integer $position - * - * @return Tags - */ - public function setPosition($position) - { - $this->position = $position; - - return $this; - } - - /** - * Get position - * - * @return integer - */ - public function getPosition() - { - return $this->position; - } - - /** - * Set created - * - * @param \DateTime $created - * - * @return Tags - */ - public function setCreated($created) - { - $this->created = $created; - - return $this; - } - - /** - * Get created - * - * @return \DateTime - */ - public function getCreated() - { - return $this->created; - } - - /** - * Get id - * - * @return integer - */ - public function getId() - { - return $this->id; - } -} diff --git a/Rox/Storage/Tags.php~ b/Rox/Storage/Tags.php~ deleted file mode 100644 index c612fcf138..0000000000 --- a/Rox/Storage/Tags.php~ +++ /dev/null @@ -1,61 +0,0 @@ -edited = $edited; - - return $this; - } - - /** - * Get edited - * - * @return \DateTime - */ - public function getEdited() - { - return $this->edited; - } - - /** - * Set tripName - * - * @param string $tripName - * - * @return TripData - */ - public function setTripName($tripName) - { - $this->tripName = $tripName; - - return $this; - } - - /** - * Get tripName - * - * @return string - */ - public function getTripName() - { - return $this->tripName; - } - - /** - * Set tripText - * - * @param string $tripText - * - * @return TripData - */ - public function setTripText($tripText) - { - $this->tripText = $tripText; - - return $this; - } - - /** - * Get tripText - * - * @return string - */ - public function getTripText() - { - return $this->tripText; - } - - /** - * Set tripDescr - * - * @param string $tripDescr - * - * @return TripData - */ - public function setTripDescr($tripDescr) - { - $this->tripDescr = $tripDescr; - - return $this; - } - - /** - * Get tripDescr - * - * @return string - */ - public function getTripDescr() - { - return $this->tripDescr; - } - - /** - * Get tripId - * - * @return integer - */ - public function getTripId() - { - return $this->tripId; - } -} diff --git a/Rox/Storage/TripData.php~ b/Rox/Storage/TripData.php~ deleted file mode 100644 index 970e148db5..0000000000 --- a/Rox/Storage/TripData.php~ +++ /dev/null @@ -1,54 +0,0 @@ -tripOptions = $tripOptions; - - return $this; - } - - /** - * Get tripOptions - * - * @return string - */ - public function getTripOptions() - { - return $this->tripOptions; - } - - /** - * Set tripTouched - * - * @param \DateTime $tripTouched - * - * @return TripOld - */ - public function setTripTouched($tripTouched) - { - $this->tripTouched = $tripTouched; - - return $this; - } - - /** - * Get tripTouched - * - * @return \DateTime - */ - public function getTripTouched() - { - return $this->tripTouched; - } - - /** - * Set idmember - * - * @param integer $idmember - * - * @return TripOld - */ - public function setIdmember($idmember) - { - $this->idmember = $idmember; - - return $this; - } - - /** - * Get idmember - * - * @return integer - */ - public function getIdmember() - { - return $this->idmember; - } - - /** - * Get tripId - * - * @return integer - */ - public function getTripId() - { - return $this->tripId; - } -} diff --git a/Rox/Storage/TripOld.php~ b/Rox/Storage/TripOld.php~ deleted file mode 100644 index 9a7ccc8aca..0000000000 --- a/Rox/Storage/TripOld.php~ +++ /dev/null @@ -1,47 +0,0 @@ -id; - } -} diff --git a/Rox/Storage/TripSeq.php~ b/Rox/Storage/TripSeq.php~ deleted file mode 100644 index 6d71c4fa99..0000000000 --- a/Rox/Storage/TripSeq.php~ +++ /dev/null @@ -1,26 +0,0 @@ -tripIdForeign = $tripIdForeign; - - return $this; - } - - /** - * Get tripIdForeign - * - * @return integer - */ - public function getTripIdForeign() - { - return $this->tripIdForeign; - } - - /** - * Set galleryIdForeign - * - * @param integer $galleryIdForeign - * - * @return TripToGallery - */ - public function setGalleryIdForeign($galleryIdForeign) - { - $this->galleryIdForeign = $galleryIdForeign; - - return $this; - } - - /** - * Get galleryIdForeign - * - * @return integer - */ - public function getGalleryIdForeign() - { - return $this->galleryIdForeign; - } - - /** - * Get id - * - * @return integer - */ - public function getId() - { - return $this->id; - } -} diff --git a/Rox/Storage/TripToGallery.php~ b/Rox/Storage/TripToGallery.php~ deleted file mode 100644 index 15fce8b99b..0000000000 --- a/Rox/Storage/TripToGallery.php~ +++ /dev/null @@ -1,40 +0,0 @@ -summary = $summary; - - return $this; - } - - /** - * Get summary - * - * @return string - */ - public function getSummary() - { - return $this->summary; - } - - /** - * Set description - * - * @param string $description - * - * @return Trips - */ - public function setDescription($description) - { - $this->description = $description; - - return $this; - } - - /** - * Get description - * - * @return string - */ - public function getDescription() - { - return $this->description; - } - - /** - * Set countoftravellers - * - * @param integer $countoftravellers - * - * @return Trips - */ - public function setCountoftravellers($countoftravellers) - { - $this->countoftravellers = $countoftravellers; - - return $this; - } - - /** - * Get countoftravellers - * - * @return integer - */ - public function getCountoftravellers() - { - return $this->countoftravellers; - } - - /** - * Set createdAt - * - * @param \DateTime $createdAt - * - * @return Trips - */ - public function setCreatedAt($createdAt) - { - $this->createdAt = $createdAt; - - return $this; - } - - /** - * Get createdAt - * - * @return \DateTime - */ - public function getCreatedAt() - { - return $this->createdAt; - } - - /** - * Set updatedAt - * - * @param \DateTime $updatedAt - * - * @return Trips - */ - public function setUpdatedAt($updatedAt) - { - $this->updatedAt = $updatedAt; - - return $this; - } - - /** - * Get updatedAt - * - * @return \DateTime - */ - public function getUpdatedAt() - { - return $this->updatedAt; - } - - /** - * Set deletedAt - * - * @param \DateTime $deletedAt - * - * @return Trips - */ - public function setDeletedAt($deletedAt) - { - $this->deletedAt = $deletedAt; - - return $this; - } - - /** - * Get deletedAt - * - * @return \DateTime - */ - public function getDeletedAt() - { - return $this->deletedAt; - } - - /** - * Set additionalinfo - * - * @param integer $additionalinfo - * - * @return Trips - */ - public function setAdditionalinfo($additionalinfo) - { - $this->additionalinfo = $additionalinfo; - - return $this; - } - - /** - * Get additionalinfo - * - * @return integer - */ - public function getAdditionalinfo() - { - return $this->additionalinfo; - } - - /** - * Get id - * - * @return integer - */ - public function getId() - { - return $this->id; - } - - /** - * Set createdBy - * - * @param \App\Entity\Members $createdBy - * - * @return Trips - */ - public function setCreatedBy(\App\Entity\Members $createdBy = null) - { - $this->createdBy = $createdBy; - - return $this; - } - - /** - * Get createdBy - * - * @return \App\Entity\Members - */ - public function getCreatedBy() - { - return $this->createdBy; - } -} diff --git a/Rox/Storage/Trips.php~ b/Rox/Storage/Trips.php~ deleted file mode 100644 index 1b91e35907..0000000000 --- a/Rox/Storage/Trips.php~ +++ /dev/null @@ -1,85 +0,0 @@ -authId = $authId; - - return $this; - } - - /** - * Get authId - * - * @return integer - */ - public function getAuthId() - { - return $this->authId; - } - - /** - * Set handle - * - * @param string $handle - * - * @return UserBeforeDataRetention - */ - public function setHandle($handle) - { - $this->handle = $handle; - - return $this; - } - - /** - * Get handle - * - * @return string - */ - public function getHandle() - { - return $this->handle; - } - - /** - * Set email - * - * @param string $email - * - * @return UserBeforeDataRetention - */ - public function setEmail($email) - { - $this->email = $email; - - return $this; - } - - /** - * Get email - * - * @return string - */ - public function getEmail() - { - return $this->email; - } - - /** - * Set pw - * - * @param string $pw - * - * @return UserBeforeDataRetention - */ - public function setPw($pw) - { - $this->pw = $pw; - - return $this; - } - - /** - * Get pw - * - * @return string - */ - public function getPw() - { - return $this->pw; - } - - /** - * Set active - * - * @param integer $active - * - * @return UserBeforeDataRetention - */ - public function setActive($active) - { - $this->active = $active; - - return $this; - } - - /** - * Get active - * - * @return integer - */ - public function getActive() - { - return $this->active; - } - - /** - * Set lastlogin - * - * @param \DateTime $lastlogin - * - * @return UserBeforeDataRetention - */ - public function setLastlogin($lastlogin) - { - $this->lastlogin = $lastlogin; - - return $this; - } - - /** - * Get lastlogin - * - * @return \DateTime - */ - public function getLastlogin() - { - return $this->lastlogin; - } - - /** - * Set location - * - * @param integer $location - * - * @return UserBeforeDataRetention - */ - public function setLocation($location) - { - $this->location = $location; - - return $this; - } - - /** - * Get location - * - * @return integer - */ - public function getLocation() - { - return $this->location; - } - - /** - * Get id - * - * @return integer - */ - public function getId() - { - return $this->id; - } -} diff --git a/Rox/Storage/UserBeforeDataRetention.php~ b/Rox/Storage/UserBeforeDataRetention.php~ deleted file mode 100644 index 70f1705ab9..0000000000 --- a/Rox/Storage/UserBeforeDataRetention.php~ +++ /dev/null @@ -1,75 +0,0 @@ -name = $name; - - return $this; - } - - /** - * Get name - * - * @return string - */ - public function getName() - { - return $this->name; - } - - /** - * Set updated - * - * @param \DateTime $updated - * - * @return VolunteerBoards - */ - public function setUpdated($updated) - { - $this->updated = $updated; - - return $this; - } - - /** - * Get updated - * - * @return \DateTime - */ - public function getUpdated() - { - return $this->updated; - } - - /** - * Set purposecomment - * - * @param string $purposecomment - * - * @return VolunteerBoards - */ - public function setPurposecomment($purposecomment) - { - $this->purposecomment = $purposecomment; - - return $this; - } - - /** - * Get purposecomment - * - * @return string - */ - public function getPurposecomment() - { - return $this->purposecomment; - } - - /** - * Set textcontent - * - * @param string $textcontent - * - * @return VolunteerBoards - */ - public function setTextcontent($textcontent) - { - $this->textcontent = $textcontent; - - return $this; - } - - /** - * Get textcontent - * - * @return string - */ - public function getTextcontent() - { - return $this->textcontent; - } - - /** - * Set created - * - * @param \DateTime $created - * - * @return VolunteerBoards - */ - public function setCreated($created) - { - $this->created = $created; - - return $this; - } - - /** - * Get created - * - * @return \DateTime - */ - public function getCreated() - { - return $this->created; - } - - /** - * Get id - * - * @return integer - */ - public function getId() - { - return $this->id; - } -} diff --git a/Rox/Storage/VolunteerBoards.php~ b/Rox/Storage/VolunteerBoards.php~ deleted file mode 100644 index ac373ac633..0000000000 --- a/Rox/Storage/VolunteerBoards.php~ +++ /dev/null @@ -1,61 +0,0 @@ -nbuse = $nbuse; - - return $this; - } - - /** - * Get nbuse - * - * @return integer - */ - public function getNbuse() - { - return $this->nbuse; - } - - /** - * Get code - * - * @return string - */ - public function getCode() - { - return $this->code; - } -} diff --git a/Rox/Storage/WordsUse.php~ b/Rox/Storage/WordsUse.php~ deleted file mode 100644 index b5090aa049..0000000000 --- a/Rox/Storage/WordsUse.php~ +++ /dev/null @@ -1,33 +0,0 @@ - { + if (event.target.type === 'radio') { + if (event.target.value === 'no') { + hostingInterest.classList.remove('u:block'); + hostingInterest.classList.add('u:hidden'); + } else { + hostingInterest.classList.remove('u:hidden'); + hostingInterest.classList.add('u:block'); + } + accommodationRadiobuttons.forEach( (radio) => { + radio.parentElement.classList.remove('u:bg-gray-400') + }) + event.target.parentElement.classList.add('u:bg-gray-400'); + } +} + +const markers = [ + trans('hosting_interest.select'), + trans('hosting_interest.very_low'), + trans('hosting_interest.low'), + trans('hosting_interest.lower'), + trans('hosting_interest.low_to_medium'), + trans('hosting_interest.medium'), + trans('hosting_interest.medium_to_high'), + trans('hosting_interest.high'), + trans('hosting_interest.higher'), + trans('hosting_interest.very_high'), + trans('hosting_interest.cant_wait') +] + +const slider = document.querySelectorAll('input[type="range"]'); + +function updateValueOutput(value) { + const valueOutput = document.getElementsByClassName('rangeSlider__value-output'); + if (valueOutput.length) { + valueOutput[0].innerHTML = markers[value]; + } +} + +const initializeHostingInterestSlider = () => { + return rangeSlider.create(slider, { + onInit: function () { + updateValueOutput(0); + }, + onSlide: function (value, percent, position) { + updateValueOutput(value); + } + }); +}; + +const initializeAccommodationRadioButtons = () => { + accommodationRadiobuttons.forEach( (radio) => { + radio.addEventListener("click", radioHandler) + }) +} + +const initializeAccommodationWidget = () => { + initializeAccommodationRadioButtons() + initializeHostingInterestSlider() +} diff --git a/assets/js/admin/faqs.js b/assets/js/admin/faqs.js index bfcefcd0fd..7db9d6c4c5 100644 --- a/assets/js/admin/faqs.js +++ b/assets/js/admin/faqs.js @@ -1,9 +1,15 @@ -$( function() { - $( "#faqs" ).sortable({ - axis: 'y', - update: function (event, ui) { - var data = $(this).sortable( "serialize", { key : "faq" } ); - $("#form_sortOrder").val(data); - } - }); +import Sortable from 'sortablejs'; + +document.addEventListener('DOMContentLoaded', function () { + const faqsContainer = document.getElementById('faqs'); + if (faqsContainer) { + new Sortable(faqsContainer, { + animation: 150, + onUpdate: function (evt) { + const itemEls = faqsContainer.querySelectorAll('.card'); + const data = Array.from(itemEls).map(el => 'faq[]=' + el.id.replace('faq_', '')).join('&'); + document.getElementById('form_sortOrder').value = data; + } + }); + } }); \ No newline at end of file diff --git a/assets/js/admin/tools/login_message.ts b/assets/js/admin/tools/login_message.ts index 5deab5d19a..555a25b0f0 100644 --- a/assets/js/admin/tools/login_message.ts +++ b/assets/js/admin/tools/login_message.ts @@ -1,33 +1,25 @@ -import VanillaCalendar, { Options } from 'vanilla-calendar-pro'; -import 'vanilla-calendar-pro/build/vanilla-calendar.min.css'; +// @ts-ignore +import { Calendar, type Options } from 'vanilla-calendar-pro'; +import 'vanilla-calendar-pro/styles/index.css'; const options: Options = { - input: true, + inputMode: true, type: 'default', - actions: { - changeToInput(e, calendar, self) { - if (!self.HTMLInputElement) return; - if (self.selectedDates[0]) { - self.HTMLInputElement.value = self.selectedDates[0] + " " + self.selectedTime; - } else { - self.HTMLInputElement.value = ''; - } - }, - }, - settings: { - range: { - disablePast: true, - }, - selection: { - time: 24, - }, - visibility: { - positionToInput: 'center', - theme: 'light', - }, + onChangeToInput(self) { + if (!self.context.inputElement) return; + if (self.context.selectedDates[0]) { + self.context.inputElement.value = self.context.selectedDates[0] + " " + self.context.selectedTime; + self.hide(); + } else { + self.context.inputElement.value = ''; + } }, + disableDatesPast: true, + selectionTimeMode: 24, + positionToInput: 'auto', + selectedTheme: 'light', }; const expires = document.getElementById('login_message_expires'); -const calendar = new VanillaCalendar(expires, options); +const calendar = new Calendar(expires, options); calendar.init(); diff --git a/assets/js/app.js b/assets/js/app.js index 08a8122ca5..8c0acc175e 100644 --- a/assets/js/app.js +++ b/assets/js/app.js @@ -1,12 +1,6 @@ // assets/js/main.js -const $ = require('jquery'); - -global.$ = global.jQuery = $; - -require('popper.js'); - -require('bootstrap'); - -require('/scss/bewelcome.scss'); +import * as bootstrap from 'bootstrap'; +window.bootstrap = bootstrap; +import '/scss/bewelcome.scss'; diff --git a/assets/js/bewelcome.js b/assets/js/bewelcome.js index d7844c5005..a2047deddd 100644 --- a/assets/js/bewelcome.js +++ b/assets/js/bewelcome.js @@ -1,27 +1,27 @@ -import 'jquery'; -import 'popper.js'; +import * as bootstrap from 'bootstrap' -import 'bootstrap'; -import 'bootstrap-dropdown-hover'; import '../../public/script/common/common.js'; -import '../scss/bewelcome.scss'; import 'cookieconsent/src/cookieconsent.js'; + +import '../scss/bewelcome.scss'; import 'cookieconsent/src/styles/animation.css'; import 'cookieconsent/src/styles/base.css'; import 'cookieconsent/src/styles/layout.css'; import 'cookieconsent/src/styles/media.css'; import 'cookieconsent/src/styles/themes/classic.css'; import 'cookieconsent/src/styles/themes/edgeless.css'; -import 'select2/dist/js/select2.full.js'; -import './loginmessages.js'; +import '../scss/cookie-consent.scss'; import '@fortawesome/fontawesome-free/js/all.js'; import './collapsemenu.js'; +import './member-menu-dropdown.js'; import './tom-select.js'; -$(".select2").select2({ - theme: 'bootstrap4', - width: 'auto', - dropdownAutoWidth: true -}); +window.bootstrap = bootstrap; + -$(".toast").toast('show'); +document.addEventListener('DOMContentLoaded', () => { + document.querySelectorAll('.toast').forEach(toastNode => { + const toast = new window.bootstrap.Toast(toastNode); + toast.show(); + }); +}); \ No newline at end of file diff --git a/assets/js/browserPushPreference.js b/assets/js/browserPushPreference.js new file mode 100644 index 0000000000..1ef8c304aa --- /dev/null +++ b/assets/js/browserPushPreference.js @@ -0,0 +1,412 @@ +const BROWSER_PUSH_TIMEOUT_MS = 5000 +const BROWSER_PUSH_RECONCILED_KEY_PREFIX = 'bewelcomeBrowserPushReconciled:' + +export async function requestBrowserPushPermission(element) { + if (!isBrowserPushAvailable(element)) { + return false + } + + return await requestBrowserNotificationPermission(element) +} + +export async function requestBrowserNotificationPermission(element) { + if (!isBrowserNotificationAvailable(element)) { + return false + } + if (Notification.permission === 'denied') { + return false + } + if (Notification.permission === 'granted') { + return true + } + + return await requestNotificationPermission() === 'granted' +} + +export async function handleBrowserPushPreferenceChange(element, permissionPromise = null) { + const value = getBrowserPushPreferenceValue(element) + element.dataset.browserPushPreferenceValue = value + removeSessionValue(BROWSER_PUSH_RECONCILED_KEY_PREFIX + (element.dataset.memberId || '')) + if (value !== 'Always') { + await removeCurrentBrowserSubscription(element, true) + const permissionGranted = value !== 'OpenOnly' + || await (permissionPromise || requestBrowserNotificationPermission(element)) + dispatchPreferenceChange(value) + + return permissionGranted + } + + const enabled = await enableBrowserPushForCurrentBrowser(element, permissionPromise) + dispatchPreferenceChange(value) + + return enabled +} + +export async function enableBrowserPushForCurrentBrowser(element, permissionPromise = null) { + const enabled = null !== await maybeSubscribeCurrentBrowser(element, permissionPromise) + if (enabled) { + markBrowserPushReconciled(element) + } + + return enabled +} + +export async function getBrowserPushDeviceState(element) { + const value = getBrowserPushPreferenceValue(element) + if (value === 'No') { + return 'off' + } + if (!isBrowserNotificationAvailable(element)) { + return 'unsupported' + } + if (Notification.permission === 'denied') { + return 'denied' + } + if (value === 'OpenOnly') { + return Notification.permission === 'granted' ? 'open_only' : 'inactive' + } + if (!supportsBrowserPush()) { + return 'unsupported' + } + if (Notification.permission !== 'granted') { + return 'inactive' + } + + try { + const registration = await getServiceWorkerRegistration() + if (!registration) { + return 'error' + } + const subscription = await registration.pushManager.getSubscription() + if (!subscription) { + return 'inactive' + } + const applicationServerKey = urlBase64ToUint8Array(element.dataset.publicKey) + + return applicationServerKeyMatches(subscription, applicationServerKey) ? 'active' : 'inactive' + } catch (error) { + return 'error' + } +} + +export function initBrowserPushSession() { + const element = document.querySelector('[data-browser-push-session]') + if (!element) { + return + } + + element.addEventListener('click', (event) => { + if (event.defaultPrevented || event.button > 0 || event.metaKey || event.ctrlKey || event.shiftKey || event.altKey) { + return + } + + event.preventDefault() + const memberId = element.dataset.memberId || '' + removeSessionValue(BROWSER_PUSH_RECONCILED_KEY_PREFIX + memberId) + window.dispatchEvent(new CustomEvent('browser-push-session-ending', { + detail: { memberId }, + })) + withTimeout(removeCurrentBrowserSubscription(element, true), BROWSER_PUSH_TIMEOUT_MS).finally(() => { + window.location.assign(element.href) + }) + }) + + reconcileCurrentBrowserSubscription(element) +} + +async function reconcileCurrentBrowserSubscription(element) { + const memberId = element.dataset.memberId || '' + const reconciliationState = getBrowserPushReconciliationState(element) + if (!memberId) { + return + } + + try { + const registration = await getServiceWorkerRegistration() + if (!registration) { + return + } + + const subscription = await registration.pushManager.getSubscription() + const shouldHaveSubscription = + element.dataset.browserPushPreferenceValue === 'Always' + && isBrowserPushAvailable(element) + && Notification.permission === 'granted' + if ( + getSessionValue(BROWSER_PUSH_RECONCILED_KEY_PREFIX + memberId) === reconciliationState + && browserPushSubscriptionMatchesExpectedState(element, subscription, shouldHaveSubscription) + ) { + return + } + + if (shouldHaveSubscription) { + await createOrUpdateBrowserPushSubscription(element, registration) + } else if (subscription) { + await removeSubscription(element, subscription) + } + setSessionValue(BROWSER_PUSH_RECONCILED_KEY_PREFIX + memberId, reconciliationState) + } catch (error) { + // The explicit preference control remains available for retry. + } +} + +function browserPushSubscriptionMatchesExpectedState(element, subscription, shouldHaveSubscription) { + if (!shouldHaveSubscription) { + return !subscription + } + if (!subscription) { + return false + } + + return applicationServerKeyMatches(subscription, urlBase64ToUint8Array(element.dataset.publicKey)) +} + +function markBrowserPushReconciled(element) { + const memberId = element.dataset.memberId || '' + if (memberId) { + setSessionValue( + BROWSER_PUSH_RECONCILED_KEY_PREFIX + memberId, + getBrowserPushReconciliationState(element), + ) + } +} + +function getBrowserPushReconciliationState(element) { + return `${element.dataset.browserPushPreferenceValue || 'No'}:${element.dataset.publicKey || ''}` +} + +async function maybeSubscribeCurrentBrowser(element, permissionPromise = null) { + if (!shouldTryBrowserPush(element)) { + return null + } + + try { + const hasPermission = permissionPromise ? await permissionPromise : await requestBrowserPushPermission(element) + if (!hasPermission) { + return null + } + + const registration = await getServiceWorkerRegistration() + if (!registration) { + return null + } + + return await createOrUpdateBrowserPushSubscription(element, registration) + } catch (error) { + return null + } +} + +async function removeCurrentBrowserSubscription(element, removeFromServer = false) { + if (!supportsBrowserPush()) { + return + } + + try { + const registration = await getServiceWorkerRegistration() + if (!registration) { + return + } + const subscription = await registration.pushManager.getSubscription() + if (!subscription) { + return + } + + if (removeFromServer) { + await removeSubscription(element, subscription) + } else { + await subscription.unsubscribe() + } + } catch (error) { + // Server-side preference cleanup still prevents future sends for this account. + } +} + +async function removeSubscription(element, subscription) { + const results = await Promise.allSettled([ + deleteBrowserPushSubscription(element, subscription), + unsubscribeBrowserPushSubscription(subscription), + ]) + if (results.every(result => result.status === 'rejected')) { + throw results[0].reason + } +} + +async function unsubscribeBrowserPushSubscription(subscription) { + if (!await subscription.unsubscribe()) { + throw new Error('Browser push subscription could not be removed') + } +} + +function shouldTryBrowserPush(element) { + return isBrowserPushAvailable(element) + && element.dataset.browserPushPreferenceValue === 'Always' + && Notification.permission !== 'denied' +} + +function isBrowserPushAvailable(element) { + return isBrowserNotificationAvailable(element) && supportsBrowserPush() +} + +function supportsBrowserPush() { + return 'serviceWorker' in navigator && 'PushManager' in window +} + +function isBrowserNotificationAvailable(element) { + return element + && element.dataset.browserPushConfigured === '1' + && 'Notification' in window + && window.isSecureContext +} + +function getBrowserPushPreferenceValue(element) { + if (element.type === 'checkbox') { + return element.checked ? 'Always' : 'No' + } + + return element.value || element.dataset.browserPushPreferenceValue || 'No' +} + +async function createOrUpdateBrowserPushSubscription(element, registration) { + const applicationServerKey = urlBase64ToUint8Array(element.dataset.publicKey) + let subscription = await registration.pushManager.getSubscription() + if (subscription && !applicationServerKeyMatches(subscription, applicationServerKey)) { + await removeSubscription(element, subscription) + subscription = null + } + if (!subscription) { + subscription = await registration.pushManager.subscribe({ + userVisibleOnly: true, + applicationServerKey, + }) + } + await requestJson(element.dataset.subscribeUrl, 'POST', { + ...subscription.toJSON(), + contentEncoding: 'aes128gcm', + }, element.dataset.csrfToken) + + return subscription +} + +async function deleteBrowserPushSubscription(element, subscription) { + if (!element.dataset.unsubscribeUrl) { + throw new Error('Browser push unsubscribe URL is missing') + } + + await requestJson( + element.dataset.unsubscribeUrl, + 'DELETE', + subscription.toJSON(), + element.dataset.csrfToken, + true, + ) +} + +async function requestJson(url, method, payload, csrfToken, keepalive = false) { + const response = await fetch(url, { + method, + credentials: 'same-origin', + keepalive, + headers: { + 'Accept': 'application/json', + 'Content-Type': 'application/json', + 'X-CSRF-Token': csrfToken, + }, + body: JSON.stringify(payload), + }) + + if (!response.ok) { + throw new Error(`Browser push request failed with ${response.status}`) + } + + const contentType = response.headers.get('Content-Type') || '' + if (!contentType.includes('application/json')) { + return null + } + + return response.json() +} + +function requestNotificationPermission() { + return new Promise((resolve) => { + const result = Notification.requestPermission(resolve) + if (result && 'function' === typeof result.then) { + result.then(resolve) + } + }) +} + +function getServiceWorkerRegistration() { + return withTimeout(navigator.serviceWorker.ready, BROWSER_PUSH_TIMEOUT_MS) +} + +function urlBase64ToUint8Array(base64String) { + const padding = '='.repeat((4 - base64String.length % 4) % 4) + const base64 = (base64String + padding).replace(/-/g, '+').replace(/_/g, '/') + const rawData = window.atob(base64) + const outputArray = new Uint8Array(rawData.length) + + for (let i = 0; i < rawData.length; ++i) { + outputArray[i] = rawData.charCodeAt(i) + } + + return outputArray +} + +function applicationServerKeyMatches(subscription, applicationServerKey) { + const currentKey = subscription.options && subscription.options.applicationServerKey + if (!currentKey) { + return false + } + const currentKeyBytes = new Uint8Array(currentKey) + if (currentKeyBytes.byteLength !== applicationServerKey.byteLength) { + return false + } + + for (let i = 0; i < currentKeyBytes.byteLength; i++) { + if (currentKeyBytes[i] !== applicationServerKey[i]) { + return false + } + } + + return true +} + +function dispatchPreferenceChange(value) { + window.dispatchEvent(new CustomEvent('browser-push-preference-changed', { + detail: { value }, + })) +} + +function getSessionValue(key) { + try { + return window.sessionStorage.getItem(key) + } catch (error) { + return null + } +} + +function setSessionValue(key, value) { + try { + window.sessionStorage.setItem(key, value) + } catch (error) { + // Reconciliation will run again on the next page when storage is unavailable. + } +} + +function removeSessionValue(key) { + try { + window.sessionStorage.removeItem(key) + } catch (error) { + // Reconciliation will run after the next full browser session. + } +} + +function withTimeout(promise, timeoutMs) { + return Promise.race([ + promise, + new Promise((resolve) => { + window.setTimeout(() => resolve(null), timeoutMs) + }), + ]) +} diff --git a/assets/js/bsfileselect.js b/assets/js/bsfileselect.js index 0f121fd0e0..9a475b4d99 100644 --- a/assets/js/bsfileselect.js +++ b/assets/js/bsfileselect.js @@ -1,7 +1,5 @@ import bsCustomFileInput from 'bs-custom-file-input'; -$(function () { - $(document).ready(function () { - bsCustomFileInput.init(); - }); +document.addEventListener('DOMContentLoaded', function () { + bsCustomFileInput.init(); }); diff --git a/assets/js/calendar.js b/assets/js/calendar.js new file mode 100644 index 0000000000..5c2356d4a1 --- /dev/null +++ b/assets/js/calendar.js @@ -0,0 +1,39 @@ +import { Calendar } from 'vanilla-calendar-pro'; +import 'vanilla-calendar-pro/styles/index.css'; +import * as dayjs from 'dayjs' + +export { initializeCalendar } + +const htmlTag = document.getElementsByTagName('html')[0]; +const lang = htmlTag.attributes['lang'].value; + +const now = dayjs() +const minimumAge = now.subtract(18, 'year'); +const maximumAge = now.subtract(120, 'year'); + +const options = { + inputMode: true, + type: 'default', + onChangeToInput(self) { + if (!self.context.inputElement) return; + if (self.context.selectedDates[0]) { + self.context.inputElement.value = self.context.selectedDates[0]; + self.hide(); + } else { + self.context.inputElement.value = ''; + } + }, + lang: lang, + dateMin: maximumAge.format('YYYY-MM-DD'), + dateMax: minimumAge.format('YYYY-MM-DD'), + positionToInput: 'auto', + selectedTheme: 'light', + disabledDates: [], + dateToday: minimumAge.toDate(), +}; + +const initializeCalendar = (id) => { + const calendarAnchor = document.getElementById(id); + const calendar = new Calendar(calendarAnchor, options); + calendar.init(); +} \ No newline at end of file diff --git a/assets/js/collapsemenu.js b/assets/js/collapsemenu.js index 3cd5d77c65..e69de29bb2 100644 --- a/assets/js/collapsemenu.js +++ b/assets/js/collapsemenu.js @@ -1,116 +0,0 @@ -$('[data-toggle="dropdown"]').bootstrapDropdownHover({ - clickBehavior: 'sticky', - hideTimeout: 1000 -}); - -$(function () { - registerOnClickEvent(); -}); - -// ------------------------------------------------------- // -// Multi Level dropdowns -// ------------------------------------------------------ // -function registerOnClickEvent() { - $("ul.dropdown-menu [data-toggle='dropdown']").on("click", function (event) { - - $(this).siblings().toggleClass("show"); - - if (!$(this).next().hasClass('show')) { - $(this).parents('.dropdown-menu').first().find('.show').removeClass("show"); - } - $(this).parents('li.nav-item.dropdown.show').on('hidden.bs.dropdown', function (e) { - $('.dropdown-submenu .show').removeClass("show"); - }); - - }); - -} - -const gapSize = 4; - -var autocollapse_menu = function (resizing) { - const hamburger = document.getElementById('hamburger'); - const hamburgerMenu = document.getElementById('hamburger_menu'); - const staticMenu = document.getElementById('static_menu'); - const collapsingMenu = document.getElementById('collapsing_menu'); - - if (hamburgerMenu != null) { - // if resizing move all menu items back into the collapsing menu and start from there - // This also takes care of vanishing elements due to smaller viewports (like username and text on logo) - let hiddenItems = hamburgerMenu.childNodes; - if (hiddenItems.length !== 0) { - while(hamburgerMenu.childNodes.length !== 0) { - const menuItemToMove = hamburgerMenu.childNodes[0]; - collapsingMenu.appendChild(menuItemToMove); - menuItemToMove.classList.remove('dropdown-submenu'); - menuItemToMove.classList.add('dropdown'); - } - } - - let dimensionsStatic = staticMenu.getBoundingClientRect(); - let dimensionsCollapse = collapsingMenu.getBoundingClientRect(); - - if (dimensionsStatic.left - dimensionsCollapse.right < gapSize) { - hamburger.classList.remove('d-none'); - - while (dimensionsStatic.left - dimensionsCollapse.right < gapSize) { - // add child to dropdown - const menuItems = document.querySelectorAll('#collapsing_menu > li:not(:first-child)'); - const count = menuItems.length; - const menuItemToMove = menuItems[count - 1]; - menuItemToMove.classList.remove('dropdown'); - menuItemToMove.classList.add('dropdown-submenu'); - menuItemToMove.classList.add('dropdown-menu-right'); - - // insert in front of the first item in the hamburger menu - hamburgerMenu.insertBefore(menuItemToMove, hamburgerMenu.firstChild); - - dimensionsStatic = staticMenu.getBoundingClientRect(); - dimensionsCollapse = collapsingMenu.getBoundingClientRect(); - } - let visible = true; - for (let i = 0; i < hiddenItems.length; i++) { - visible = visible && (hiddenItems[i].id !== 'login_signup'); - } - if (!visible) { - hamburger.classList.add('d-none'); - } - } else { - hiddenItems = hamburgerMenu.childNodes; - - if (hiddenItems.length === 0) { - hamburger.classList.add('d-none'); - } - while (dimensionsStatic.left - dimensionsCollapse.right >= gapSize && hiddenItems.length !== 0) { - const menuItems = hamburgerMenu.childNodes; - const menuItemToMove = menuItems[0]; - menuItemToMove.classList.remove('dropdown-submenu'); - menuItemToMove.classList.remove('dropdown-menu-right'); - menuItemToMove.classList.add('dropdown'); - - collapsingMenu.appendChild(menuItemToMove); - - dimensionsStatic = staticMenu.getBoundingClientRect(); - dimensionsCollapse = collapsingMenu.getBoundingClientRect(); - - hiddenItems = document.querySelectorAll('#hamburger_menu > li'); - } - - if (dimensionsStatic.left - dimensionsCollapse.right < gapSize) { - autocollapse_menu(); - } - } - } - - registerOnClickEvent(); -} - -$(document).ready(function () { - // when the page has loaded - autocollapse_menu(false); - - // when the window is resized - $(window).on('resize', function () { - autocollapse_menu(true); - }); -}); diff --git a/assets/js/faq.js b/assets/js/faq.js index 23e6021cdf..1e19ef368d 100644 --- a/assets/js/faq.js +++ b/assets/js/faq.js @@ -1,33 +1,45 @@ import '../scss/faq.scss'; -var faqs = jQuery('#faqs'); -faqs.find("dd").hide(); -faqs.find("dt").click(function (e) { - e.preventDefault(); - jQuery(this).next("#faqs dd").slideToggle(500); +document.addEventListener('DOMContentLoaded', function () { + const faqs = document.getElementById('faqs'); + if (faqs) { + const dds = faqs.querySelectorAll('dd'); + dds.forEach(dd => dd.style.display = 'none'); + const dts = faqs.querySelectorAll('dt'); + dts.forEach(dt => { + dt.addEventListener('click', function (e) { + e.preventDefault(); + const nextDd = this.nextElementSibling; + if (nextDd && nextDd.tagName === 'DD') { + if (nextDd.style.display === 'none') { + nextDd.style.display = 'block'; + } else { + nextDd.style.display = 'none'; + } + } + + const icon = this.querySelector('[data-fa-i2svg]'); + if (icon) { + icon.classList.toggle('fa-plus-circle'); + icon.classList.toggle('fa-minus-circle'); + } + }); + }); + } + + openHash(); }); -document.addEventListener('DOMContentLoaded', function () { - jQuery('dt').on('click', function () { - jQuery(this) - .find('[data-fa-i2svg]') - .toggleClass('fa-plus-circle') - .toggleClass('fa-minus-circle'); - }); - }); - window.addEventListener('hashchange', openHash); -function openHash() -{ - // Alerts every time the hash changes! +function openHash() { let hash = location.hash; - $(hash).click(); - $(document).scrollTop($(hash).offset().top); + if (hash) { + const element = document.querySelector(hash); + if (element) { + element.click(); + element.scrollIntoView(); + } + } } - -$(function () { - // Trigger the event (useful on page load). - openHash(); -}); diff --git a/assets/js/gallery.js b/assets/js/gallery.js index c0f24300c8..e50c87e428 100644 --- a/assets/js/gallery.js +++ b/assets/js/gallery.js @@ -1,7 +1,7 @@ let Masonry = require('masonry-layout'); let imagesLoaded = require('imagesloaded'); -$(function () { +document.addEventListener('DOMContentLoaded', function () { // init Masonry let grid = document.getElementById('masonry-grid'); diff --git a/assets/js/home.js b/assets/js/home.js index 5b34dee1c9..6277c5ab83 100644 --- a/assets/js/home.js +++ b/assets/js/home.js @@ -1,9 +1,8 @@ import 'jquery'; -import 'popper.js'; +import '@popperjs/core'; + +import * as bootstrap from 'bootstrap' -import 'bootstrap'; -import 'bootstrap-dropdown-hover'; -import '../scss/home.scss'; import 'cookieconsent/src/cookieconsent.js'; import 'cookieconsent/src/styles/animation.css'; import 'cookieconsent/src/styles/base.css'; @@ -11,22 +10,98 @@ import 'cookieconsent/src/styles/layout.css'; import 'cookieconsent/src/styles/media.css'; import 'cookieconsent/src/styles/themes/classic.css'; import 'cookieconsent/src/styles/themes/edgeless.css'; -import 'select2/dist/js/select2.full.js'; +import '../scss/cookie-consent.scss'; +// import 'select2/dist/js/select2.full.js'; import '@fortawesome/fontawesome-free/js/all.js'; -import './scrollmagic.js'; import './collapsemenu.js'; -import {initializeSingleAutoComplete} from './suggest/locations'; - -function onChange(element, result) { - const fullName = element; - const baseId = element.id + "_"; - const geonameId = document.getElementById(baseId + "geoname_id"); - const latitude = document.getElementById(baseId + "latitude"); - const longitude = document.getElementById(baseId + "longitude"); - fullName.value = result.name.replaceAll("#", ", "); - geonameId.value = result.id; - latitude.value = result.latitude; - longitude.value = result.longitude; -} - -initializeSingleAutoComplete("/suggest/locations/all", 'js-location-picker', onChange); +import '../scss/home.scss'; + +window.bootstrap = bootstrap; + +/* $(".select2").select2({ + theme: 'bootstrap4', + width: 'auto', + dropdownAutoWidth: true, +}); +*/ + +// ── Home login bottom sheet (mobile only) ────────────────────────── +(function () { + const aside = document.querySelector('.js-home-login-aside'); + const backdrop = document.querySelector('.js-home-login-backdrop'); + const triggers = document.querySelectorAll('.js-home-login-open'); + const root = document.documentElement; + let lockedScrollY = 0; + if (!aside || !backdrop) return; + + function setExpandedState(isExpanded) { + triggers.forEach(function (btn) { + btn.setAttribute('aria-expanded', isExpanded ? 'true' : 'false'); + }); + } + + function lockBodyScroll() { + lockedScrollY = window.scrollY || window.pageYOffset || 0; + document.body.classList.add('home-sheet-open'); + document.body.style.position = 'fixed'; + document.body.style.top = `-${lockedScrollY}px`; + document.body.style.left = '0'; + document.body.style.right = '0'; + document.body.style.width = '100%'; + root.style.overflow = 'hidden'; + } + + function unlockBodyScroll() { + document.body.classList.remove('home-sheet-open'); + document.body.style.position = ''; + document.body.style.top = ''; + document.body.style.left = ''; + document.body.style.right = ''; + document.body.style.width = ''; + root.style.overflow = ''; + window.scrollTo(0, lockedScrollY); + } + + function openSheet() { + if (aside.classList.contains('is-open')) return; + aside.classList.add('is-open'); + setExpandedState(true); + // Trigger reflow so CSS transition plays on backdrop + backdrop.style.display = 'block'; + requestAnimationFrame(function () { + backdrop.classList.add('is-visible'); + }); + lockBodyScroll(); + const closeBtn = aside.querySelector('.js-home-login-close'); + if (closeBtn) closeBtn.focus(); + } + + function closeSheet() { + if (!aside.classList.contains('is-open')) return; + aside.classList.remove('is-open'); + backdrop.classList.remove('is-visible'); + unlockBodyScroll(); + setExpandedState(false); + // Hide backdrop after transition + backdrop.addEventListener('transitionend', function onEnd() { + backdrop.style.display = ''; + backdrop.removeEventListener('transitionend', onEnd); + }, {once: true}); + } + + triggers.forEach(function (btn) { + btn.addEventListener('click', openSheet); + }); + + document.querySelectorAll('.js-home-login-close').forEach(function (btn) { + btn.addEventListener('click', closeSheet); + }); + + backdrop.addEventListener('click', closeSheet); + + document.addEventListener('keydown', function (e) { + if (e.key === 'Escape' && aside.classList.contains('is-open')) { + closeSheet(); + } + }); +}()); diff --git a/assets/js/jquery-validation.js b/assets/js/jquery-validation.js index fc98a56cca..f1dad74f77 100644 --- a/assets/js/jquery-validation.js +++ b/assets/js/jquery-validation.js @@ -1,7 +1 @@ -// assets/js/main.js - -const $ = require('jquery'); - -global.$ = global.jQuery = $; - -require('jquery-validation'); +import 'jquery-validation'; \ No newline at end of file diff --git a/assets/js/landing/landing.js b/assets/js/landing/landing.js index c31f6ae5fd..d4f2aee1d8 100644 --- a/assets/js/landing/landing.js +++ b/assets/js/landing/landing.js @@ -15,8 +15,8 @@ function onChange(element, result) { initializeSingleAutoComplete("/suggest/locations/all", 'js-location-picker', onChange); -$(document).ready(function() { - if (!$('#conversationsdisplay').length) { +document.addEventListener('DOMContentLoaded', function() { + if (!document.getElementById('conversationsdisplay')) { return; } @@ -24,30 +24,94 @@ $(document).ready(function() { Home.updateThreads(); Home.updateTripLegs(); - $('a[data-toggle="tab"]').on('show.bs.tab', Home.onTabChange); - - $('#all, #unread').change(function() { - setTimeout(Home.updateMessages, 500); + const tabElements = document.querySelectorAll('a[data-bs-toggle="tab"]'); + tabElements.forEach(tab => { + tab.addEventListener('show.bs.tab', Home.onTabChange); }); + const tabFromHash = Array.from(tabElements).find(tab => tab.getAttribute('href') === window.location.hash); + if (tabFromHash) { + window.bootstrap.Tab.getOrCreateInstance(tabFromHash).show(); + } - $('#groupsButton, #forumButton, #followingButton').change(function() { - setTimeout(Home.updateThreads, 500); - }); + const allRadio = document.getElementById('all'); + if (allRadio) { + allRadio.addEventListener('change', function() { + setTimeout(Home.updateMessages, 500); + }); + } + + const unreadRadio = document.getElementById('unread'); + if (unreadRadio) { + unreadRadio.addEventListener('change', function() { + setTimeout(Home.updateMessages, 500); + }); + } - $('.hosting').click(Home.setHostingStatus); + const groupsButton = document.getElementById('groupsButton'); + if (groupsButton) { + groupsButton.addEventListener('change', function() { + setTimeout(Home.updateThreads, 500); + }); + } - $('#show_online').change(function() { - setTimeout(Home.updateActivities, 500); + const forumButton = document.getElementById('forumButton'); + if (forumButton) { + forumButton.addEventListener('change', function() { + setTimeout(Home.updateThreads, 500); + }); + } + + const followingButton = document.getElementById('followingButton'); + if (followingButton) { + followingButton.addEventListener('change', function() { + setTimeout(Home.updateThreads, 500); + }); + } + + const hostingElements = document.querySelectorAll('.hosting'); + hostingElements.forEach(el => { + el.addEventListener('click', Home.setHostingStatus); }); - $('#trips_radius').change(function() { - setTimeout(Home.updateTripLegs, 500); + const showOnline = document.getElementById('show_online'); + if (showOnline) { + showOnline.addEventListener('change', function() { + setTimeout(Home.updateActivities, 500); + }); + } + + const tripsRadius = document.getElementById('trips_radius'); + if (tripsRadius) { + tripsRadius.addEventListener('change', function() { + setTimeout(Home.updateTripLegs, 500); + }); + } +}); + +document.addEventListener('submit', function(event) { + const form = event.target.closest('.js-hide-leg'); + if (!form) { + return; + } + + event.preventDefault(); + + fetch(form.action, { + method: 'POST', + body: new FormData(form), + headers: { + 'X-Requested-With': 'XMLHttpRequest' + } + }).then(function(response) { + if (response.ok) { + form.closest('.c-dashboard__item').remove(); + } }); }); var Home = { onTabChange: function (e) { - switch($(e.target).attr('aria-controls')) { + switch(e.target.getAttribute('aria-controls')) { case 'messages': return Home.updateMessages(); @@ -62,112 +126,142 @@ var Home = { } }, updateMessages: function () { - var all = $('#all').hasClass('active') ? 1 : 0; - var unread = $('#unread').hasClass('active') ? 1 : 0; - - $.ajax({ - type: 'GET', - url: '/widget/conversations', - data: { - all: all, - unread: unread - }, - success: function(messages) { - $('#conversationsdisplay').replaceWith(messages); - } + const allRadio = document.getElementById('all'); + const all = allRadio && allRadio.classList.contains('active') ? 1 : 0; + + const unreadRadio = document.getElementById('unread'); + const unread = unreadRadio && unreadRadio.classList.contains('active') ? 1 : 0; + + const params = new URLSearchParams({ + all: all, + unread: unread }); + + fetch('/widget/conversations?' + params.toString()) + .then(response => response.text()) + .then(messages => { + const display = document.getElementById('conversationsdisplay'); + if (display) { + display.outerHTML = messages; + } + }); }, updateNotifications: function() { - $.ajax({ - type: 'GET', - url: '/widget/notifications', - success: function (notifications) { - $('#notificationsdisplay').replaceWith(notifications); + fetch('/widget/notifications') + .then(response => response.text()) + .then(notifications => { + const display = document.getElementById('notificationsdisplay'); + if (display) { + display.outerHTML = notifications; + } // Set click event - $('.notify').click(function (e) { - e.preventDefault(); - - var that = $(this); - var id = $(this).attr('id'); - - $.ajax({ - type: 'GET', - url: '/notify/' + id.replace('notify-', '') + '/check', - success: function() { - // update the notifications - Home.updateNotifications(); - } + const notifies = document.querySelectorAll('.notify'); + notifies.forEach(notify => { + notify.addEventListener('click', function (e) { + e.preventDefault(); + const id = this.getAttribute('id'); + + fetch('/notify/' + id.replace('notify-', '') + '/check') + .then(() => { + // update the notifications + Home.updateNotifications(); + }); }); }); - } - }); + }); }, updateThreads: function () { // Get parameters - var groups = $('#groupsButton').hasClass('active') ? 1 : 0; - var forum = $('#forumButton').hasClass('active') ? 1 : 0; - var following = $('#following').hasClass('active') ? 1 : 0; - - $.ajax({ - type: 'GET', - url: '/widget/threads', - data: { - groups: groups, - forum: forum, - following: following - }, - success: function (threads) { - $('#threadsdisplay').replaceWith(threads); - } + const groupsButton = document.getElementById('groupsButton'); + const groups = groupsButton && groupsButton.classList.contains('active') ? 1 : 0; + + const forumButton = document.getElementById('forumButton'); + const forum = forumButton && forumButton.classList.contains('active') ? 1 : 0; + + const followingEl = document.getElementById('following'); + const following = followingEl && followingEl.classList.contains('active') ? 1 : 0; + + const params = new URLSearchParams({ + groups: groups, + forum: forum, + following: following }); + + fetch('/widget/threads?' + params.toString()) + .then(response => response.text()) + .then(threads => { + const display = document.getElementById('threadsdisplay'); + if (display) { + display.outerHTML = threads; + } + }); }, updateActivities: function () { - var online = $('#show_online').prop('checked') ? 1 : 0; - // Get parameters - $.ajax({ - type: 'GET', - url: '/widget/activities', - data: { - online: online - }, - success: function (activities) { - $('#activitiesdisplay').replaceWith(activities); - } + const showOnline = document.getElementById('show_online'); + const online = showOnline && showOnline.checked ? 1 : 0; + + const params = new URLSearchParams({ + online: online }); + + fetch('/widget/activities?' + params.toString()) + .then(response => response.text()) + .then(activities => { + const display = document.getElementById('activitiesdisplay'); + if (display) { + display.outerHTML = activities; + } + }); }, updateTripLegs: function () { - const tripsRadius = $('#trips_radius'); - let radius = tripsRadius.val(); - - $.ajax({ - type: 'GET', - url: '/widget/visitors', - data: { - radius: radius - }, - success: function(legs) { - $('#legsdisplay').replaceWith(legs); - }, + const tripsRadius = document.getElementById('trips_radius'); + const radius = tripsRadius ? tripsRadius.value : ''; + + const params = new URLSearchParams({ + radius: radius }); + + fetch('/widget/visitors?' + params.toString()) + .then(response => response.text()) + .then(legs => { + const display = document.getElementById('legsdisplay'); + if (display) { + display.outerHTML = legs; + } + }); }, setHostingStatus: function (e) { e.preventDefault(); - // Get parameters - var accommodation = this.id; - $.ajax({ - type: 'POST', - url: '/widget/accommodation', - data: { - accommodation: accommodation - }, - dataType: 'json', - success: function (data) { - $('#welcomeavatar').replaceWith(data.profilePictureWithAccommodation); - $('#accommodation').replaceWith(data.accommodationHtml); - $('.hosting').click(Home.setHostingStatus); + const accommodation = this.id; + + const formData = new FormData(); + formData.append('accommodation', accommodation); + + fetch('/widget/accommodation', { + method: 'POST', + body: formData, + headers: { + 'X-Requested-With': 'XMLHttpRequest' + } + }) + .then(response => response.json()) + .then(data => { + const welcomeAvatar = document.getElementById('welcomeavatar'); + if (welcomeAvatar) { + welcomeAvatar.outerHTML = data.profilePictureWithAccommodation; + } + + const accommodationDisplay = document.getElementById('accommodation'); + if (accommodationDisplay) { + accommodationDisplay.outerHTML = data.accommodationHtml; } + + const hostingElements = document.querySelectorAll('.hosting'); + hostingElements.forEach(el => { + el.addEventListener('click', Home.setHostingStatus); + }); }); } }; diff --git a/assets/js/lightbox.js b/assets/js/lightbox.js index e7e1ffa562..aba8d9dbce 100644 --- a/assets/js/lightbox.js +++ b/assets/js/lightbox.js @@ -1,11 +1,6 @@ -require('ekko-lightbox'); -require('ekko-lightbox/dist/ekko-lightbox.css'); +import Lightbox from 'bs5-lightbox'; -$(function () { -$(document).on('click', '[data-toggle="lightbox"]', function(event) { - event.preventDefault(); - $(this).ekkoLightbox({ - alwaysShowClose: true, - }); - }); -}); +document.querySelectorAll('[data-toggle="lightbox"]') + .forEach( + el => el.addEventListener('click', Lightbox.initialize) + ); diff --git a/assets/js/loginmessages.js b/assets/js/loginmessages.js index 464de4c3ff..e69de29bb2 100644 --- a/assets/js/loginmessages.js +++ b/assets/js/loginmessages.js @@ -1,9 +0,0 @@ -import 'jquery'; - -$('.close').on('click', function() { - const id = $(this).data('alert'); - $.ajax({ - url: '/loginmessage/acknowledge/' + id, - type: 'POST' - }); -}); diff --git a/assets/js/member-menu-dropdown.js b/assets/js/member-menu-dropdown.js new file mode 100644 index 0000000000..25c6e14482 --- /dev/null +++ b/assets/js/member-menu-dropdown.js @@ -0,0 +1,43 @@ +import $ from 'jquery'; + +const wideQuery = window.matchMedia('(min-width: 1200px)'); + +function syncTopbarSheetScrollLock() { + const shouldLock = !wideQuery.matches && document.querySelector('#main_menu .dropdown-menu.show'); + document.body.classList.toggle('topbar-sheet-open', Boolean(shouldLock)); +} + +/** Close the top-bar dropdown whose menu contains this close control (profile, search, community full sheets). */ +function hideDropdownFromCloseButton(closeButton) { + const $toggle = $(closeButton).closest('ul.dropdown-menu').prev('.dropdown-toggle'); + if ($toggle.length) { + $toggle.dropdown('hide'); + } +} + +$(document).on('click', '.member-menu__close', function (e) { + e.preventDefault(); + e.stopPropagation(); + hideDropdownFromCloseButton(this); +}); + +/** Close any open #main_menu dropdown when crossing to xl (sheets → compact popovers). */ +function closeMainMenuDropdownsIfWide() { + if (!wideQuery.matches) { + return; + } + document.querySelectorAll('#main_menu .nav-item.dropdown.show > .dropdown-toggle').forEach((el) => { + $(el).dropdown('hide'); + }); + syncTopbarSheetScrollLock(); +} + +$(document).on('shown.bs.dropdown hidden.bs.dropdown', '#main_menu .nav-item.dropdown', function () { + syncTopbarSheetScrollLock(); +}); + +if (typeof wideQuery.addEventListener === 'function') { + wideQuery.addEventListener('change', closeMainMenuDropdownsIfWide); +} else if (typeof wideQuery.addListener === 'function') { + wideQuery.addListener(closeMainMenuDropdownsIfWide); +} diff --git a/assets/js/member/autocomplete.js b/assets/js/member/autocomplete.js index 5f72c6b8cd..5197a2ee27 100644 --- a/assets/js/member/autocomplete.js +++ b/assets/js/member/autocomplete.js @@ -1,46 +1,21 @@ -$( function() { - function log( message ) { - $( "
" ).text( message ).prependTo( "#log" ); - $( "#log" ).scrollTop( 0 ); - } +import TomSelect from 'tom-select'; +import 'tom-select/dist/css/tom-select.min.css'; - $( ".member-autocomplete-start" ).autocomplete({ - source: function( request, response ) { - $.ajax( { - url: "/member/autocomplete/start", - dataType: "jsonp", - data: { - term: request.term - }, - success: function( data ) { - response( data ); - } - } ); - }, - minLength: 2, - select: function( event, ui ) { - log( "Selected: " + ui.item.value + " aka " + ui.item.id ); - $(this).val(ui.item.value); - } - } ); - - $( ".member-autocomplete" ).autocomplete({ - source: function( request, response ) { - $.ajax( { - url: "/member/autocomplete", - dataType: "jsonp", - data: { - term: request.term - }, - success: function( data ) { - response( data ); - } - } ); - }, - minLength: 2, - select: function( event, ui ) { - log( "Selected: " + ui.item.value + " aka " + ui.item.id ); - $(this).val(ui.item.value); - } - } ); -}); \ No newline at end of file +new TomSelect('.member-autocomplete-start', { + load: function(query, callback) { + const url = '/member/autocomplete/start?term=' + encodeURIComponent(query); + fetch(url) + .then(response => response.json()) + .then(json => { + callback(json.items); + }).catch(()=>{ + callback(); + }); + }, + maxItems: 1, + create: true, + createOnBlur: true, + valueField: 'id', + labelField: 'id', + searchField: 'id', +}); diff --git a/assets/js/offcanvas.js b/assets/js/offcanvas.js index e72360e452..6df9258c27 100644 --- a/assets/js/offcanvas.js +++ b/assets/js/offcanvas.js @@ -1,7 +1,9 @@ -$(document).ready(function () { +document.addEventListener('DOMContentLoaded', function () { 'use strict'; - $('[data-toggle="offcanvas"]').on('click', function () { - $('.offcanvas-collapse').toggleClass('open'); + document.querySelectorAll('[data-bs-toggle="offcanvas"]').forEach(function(element) { + element.addEventListener('click', function () { + document.querySelector('.offcanvas-collapse').classList.toggle('open'); + }); }); -}); \ No newline at end of file +}); diff --git a/assets/js/password/check.js b/assets/js/password/check.js new file mode 100644 index 0000000000..8e70138f8a --- /dev/null +++ b/assets/js/password/check.js @@ -0,0 +1,72 @@ +const passwordField = document.querySelector('.js-password-input'); +const passwordStrength = document.querySelector('.js-password-strength'); +const username = document.querySelector('.js-username'); +const email = document.querySelector('.js-email-address'); + +function resetBackgroundColor() { + for (let i = 0; i < 5; i++) { + passwordStrength.children.item(i).classList.add('u:bg-gray-300'); + passwordStrength.children.item(i).classList.remove('u:bg-red-700'); + passwordStrength.children.item(i).classList.remove('u:bg-bewelcome'); + passwordStrength.children.item(i).classList.remove('u:bg-bewelcome-dark'); + passwordStrength.children.item(i).classList.remove('u:bg-green-600'); + passwordStrength.children.item(i).classList.remove('u:bg-green-800'); + } +} + +async function getPasswordScore() { + // Collect form data (username, email address and password) + // Send to server to calculate score + // Change colors + const formData = new FormData(); + formData.append('username', username.value); + formData.append('email', email.value); + formData.append('password', passwordField.value); + + let score = 0; + try { + const response = await fetch("/password/check/", { + method: "POST", + // Set the FormData instance as the request body + body: formData, + }); + const json = await response.json(); + score = json.score; + } catch (e) { + console.error(e); + } + + let backgroundColor; + switch(score) { + case 0: backgroundColor = 'u:bg-red-700'; break; + case 1: backgroundColor = 'u:bg-bewelcome-dark'; break; + case 2: backgroundColor = 'u:bg-bewelcome'; break; + case 3: backgroundColor = 'u:bg-green-600'; break; + case 4: backgroundColor = 'u:bg-green-800'; break; + } + + resetBackgroundColor(); + for (let i = 0; i < 5; i++) { + if (i <= score) { + passwordStrength.children.item(i).classList.remove('u:bg-gray-300'); + passwordStrength.children.item(i).classList.add(backgroundColor); + } + } +} + +let timeout; + +passwordField.addEventListener('keyup', () => { + clearTimeout(timeout); + if (passwordField.value == '') { + for (let i = 0; i < 5; i++) { + resetBackgroundColor(); + } + } else { + timeout = setTimeout(() => { getPasswordScore(); }, 500); + } +}); + +if (passwordField.value != '') { + g +} diff --git a/assets/js/password/showhide.js b/assets/js/password/showhide.js new file mode 100644 index 0000000000..77a3519706 --- /dev/null +++ b/assets/js/password/showhide.js @@ -0,0 +1,26 @@ +const showHidePasswordButtons = document.querySelectorAll('.js-password-show-hide'); + +const showHidePassword = (event) => { + const showHidePasswordButton = event.target.closest('button'); + const passwordField = showHidePasswordButton.parentNode.querySelector('input'); + + if (passwordField.type === 'text') { + passwordField.type = 'password'; + showHidePasswordButton.innerHTML="\n" + + " \n" + + " \n" + + " "; + } else { + passwordField.type = 'text'; + showHidePasswordButton.innerHTML="\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " "; + } +} + +showHidePasswordButtons.forEach((element) => { + element.addEventListener("click", showHidePassword); +}) diff --git a/assets/js/profile/account.js b/assets/js/profile/account.js new file mode 100644 index 0000000000..1e7886fc33 --- /dev/null +++ b/assets/js/profile/account.js @@ -0,0 +1,3 @@ +import { initializeCalendar} from "../calendar"; + +initializeCalendar('account_edit_form_birthdate') diff --git a/assets/js/profile/avatar.js b/assets/js/profile/avatar.js new file mode 100644 index 0000000000..fe4f74f0c7 --- /dev/null +++ b/assets/js/profile/avatar.js @@ -0,0 +1,72 @@ +import Croppie from 'croppie'; +import 'croppie/croppie.css'; + +const member = document.getElementById('member').value +const avatarContainer = document.getElementById('avatar_container') + +const croppie = new Croppie(avatarContainer, { + url: '/members/avatar/' + member + '/original', + viewport: { + width: avatarContainer.clientWidth, + height: avatarContainer.clientHeight, + type: 'circle' + }, +}) + +const images = document.querySelectorAll('[data-image-id]'); + +images.forEach(image => { + image.addEventListener('click', function() { + updateCroppieImage(this.dataset.imageId) + }) +}) + +function updateCroppieImage(image) { + croppie.bind({url: 'gallery/img?id=' + image}) +} + +const avatarFile = document.getElementById('avatar-file') +const avatarUpdate = document.getElementById('avatar-update') + +avatarFile.addEventListener('change', function(e) { + const input = e.target; + if (input.files && input.files[0]) { + const reader = new FileReader(); + + reader.onload = function (e) { + // document.querySelector('.upload-demo').classList.add('ready'); + croppie.bind({ + url: e.target.result + }).then(function(){ + console.log('bound'); + }); + + } + + reader.readAsDataURL(input.files[0]); + } +}) + +avatarUpdate.addEventListener('click', function() { + croppie.result({ + type: 'rawcanvas', + circle: false, + size: { width: 500, height: 500 }, + format: 'png' + }).then(function (canvas) { + const formData = new FormData(); + formData.append('avatar', canvas.toDataURL()); + + fetch('/members/uploadavatar', { + method: 'POST', + body: formData, + }).then((response) => { + // Update local instances as well. + if (response.status === 200) { + location.href = '/members/' + member + '/edit'; + } else { + console.log('something went wrong: ' + response.status + ' ' + response.statusText + '') + } + }) + }) +}) diff --git a/assets/js/profile/edit.js b/assets/js/profile/edit.js new file mode 100644 index 0000000000..7a922fdbfb --- /dev/null +++ b/assets/js/profile/edit.js @@ -0,0 +1,34 @@ +import MicroModal from 'micromodal'; + +const editLanguages = document.querySelectorAll("[data-edit-language]"); + +editLanguages.forEach(editLanguage => { + editLanguage.addEventListener("click", e => { + editLanguages.forEach(editLanguage => { + editLanguage.classList.add('btn-outline-primary') + editLanguage.classList.remove('btn-primary') + }) + + const languages = document.querySelectorAll('[id^=profile-language-]') + languages.forEach(language => { + language.classList.add('u:hidden!') + }) + + const language = e.target.dataset.editLanguage + const activeLanguage = document.getElementById("profile-language-" + language) + const editLanguageButton = document.querySelector("[data-edit-language=" + language + "]") + + activeLanguage.classList.remove('u:hidden!') + editLanguageButton.classList.add("btn-primary") + editLanguageButton.classList.remove("btn-outline-primary") + }) +}) + +const deleteLanguages = document.querySelectorAll("[data-delete-language]") + +deleteLanguages.forEach( deleteLanguage => { + deleteLanguage.addEventListener('click', (e) => { + const modalId = 'delete-' + e.target.dataset.deleteLanguage; + MicroModal.show(modalId); + }) +}) diff --git a/assets/js/profile/edit_accommodation.js b/assets/js/profile/edit_accommodation.js new file mode 100644 index 0000000000..d042fba961 --- /dev/null +++ b/assets/js/profile/edit_accommodation.js @@ -0,0 +1,97 @@ +import { initializeAccommodationWidget } from "../accommodation_widget"; + +const hostingInterest = document.getElementById('accommodation_form_hosting_interest') + +initializeAccommodationWidget() + +// now register on change handler for the radio buttons to change state when the user clicks + +const updateAccommodation = async (e) => { + const accommodation = document.querySelector('input[name="accommodation_form[accommodation]"]:checked').value; + const newAccommodationValue = { + accommodation: accommodation, + hostingInterest: +hostingInterest.value + } + + await fetch('/members/update/accommodation', { + method: 'POST', + headers: { + 'Accept': 'application/json', + 'Content-Type': 'application/json' + }, + body: JSON.stringify(newAccommodationValue) + }).then((response) => { + }) +} + +const updateOffers = async (e) => { + const newOffers = { + dinner: offers[0].checked, + tour: offers[1].checked, + accessible: offers[2].checked + } + + await fetch('/members/update/offers', { + method: 'POST', + headers: { + 'Accept': 'application/json', + 'Content-Type': 'application/json' + }, + body: JSON.stringify(newOffers) + }).then((response) => { + }) +} + +const updateRestrictions = async (e) => { + const newRestrictions = { + noAlcohol: restrictions[0].checked, + noSmoking: restrictions[1].checked, + noDrugs: restrictions[2].checked + } + + await fetch('/members/update/restrictions', { + method: 'POST', + headers: { + 'Accept': 'application/json', + 'Content-Type': 'application/json' + }, + body: JSON.stringify(newRestrictions) + }).then((response) => { + }) +} + +const accommodationRadiobuttons = document.querySelectorAll(('.js-accommodation')) +accommodationRadiobuttons.forEach( (radio) => { + radio.addEventListener("change", updateAccommodation) +}) + +hostingInterest.addEventListener("change", updateAccommodation) + +const offers = document.querySelectorAll('[data-offer]') +offers.forEach( (offer) => { + offer.addEventListener("change", updateOffers) +}) + +const restrictions = document.querySelectorAll('[data-restrictions]') +restrictions.forEach( (restriction) => { + restriction.addEventListener("change", updateRestrictions) +}) + +const updateMaxGuests = async (e) => { + const newMaxGuests = { + maxGuests: +e.target.value + } + + await fetch('/members/update/maxguests', { + method: 'POST', + headers: { + 'Accept': 'application/json', + 'Content-Type': 'application/json' + }, + body: JSON.stringify(newMaxGuests) + }).then((response) => { + }) +} + +const maxGuests = document.getElementById('accommodation_form_max_guests') +maxGuests.addEventListener("change", updateMaxGuests) diff --git a/assets/js/profile/edit_languages.js b/assets/js/profile/edit_languages.js new file mode 100644 index 0000000000..02d5a22b09 --- /dev/null +++ b/assets/js/profile/edit_languages.js @@ -0,0 +1,47 @@ +import {initializeTomSelects, destroyTomSelects} from "../tom-select"; + +document + .querySelectorAll('.js-add-language') + .forEach(btn => { + btn.addEventListener("click", addFormToCollection) + }); + +addDeleteLanguageEventListener() + +function addFormToCollection(e) { + const collectionHolder = document.querySelector('.' + e.currentTarget.dataset.collectionHolderClass); + + const html = collectionHolder + .dataset + .prototype + .replace( + /__name__/g, + collectionHolder.dataset.index + ); + + collectionHolder.insertAdjacentHTML('beforeend', html) + collectionHolder.insertAdjacentHTML('beforeend', '
') + collectionHolder.dataset.index++ + + addDeleteLanguageEventListener() + initializeTomSelects() +} + +function deleteFormFromCollection(e) { + const current = document.getElementById(e.currentTarget.dataset.related); + console.log(current) + current.remove() + + const collectionHolder = document.querySelector('.' + e.currentTarget.dataset.collectionHolderClass); + collectionHolder.dataset.index-- + + initializeTomSelects() +} + +function addDeleteLanguageEventListener() { + document + .querySelectorAll('.js-delete-language') + .forEach(btn => { + btn.addEventListener("click", deleteFormFromCollection) + }); +} diff --git a/assets/js/profile/preference.js b/assets/js/profile/preference.js new file mode 100644 index 0000000000..5cfb572f99 --- /dev/null +++ b/assets/js/profile/preference.js @@ -0,0 +1,121 @@ +import { + enableBrowserPushForCurrentBrowser, + getBrowserPushDeviceState, + handleBrowserPushPreferenceChange, + requestBrowserNotificationPermission, + requestBrowserPushPermission, +} from '../browserPushPreference'; + +const memberElement = document.getElementById('member') +const member = memberElement.value +const preferences = document.querySelectorAll('.preference') +const browserPushPreference = document.querySelector('[data-browser-push-preference]') +const browserPushControls = document.querySelector('[data-browser-push-device-controls]') + +preferences.forEach(preference => { + preference.addEventListener('change', event => updatePreference(preference, event)) +}) + +if (browserPushPreference && browserPushControls) { + const enableButton = browserPushControls.querySelector('[data-browser-push-enable]') + enableButton.addEventListener('click', async () => { + enableButton.disabled = true + if (getPreferenceValue(browserPushPreference) === 'OpenOnly') { + await requestBrowserNotificationPermission(browserPushPreference) + await renderBrowserPushState() + } else { + await renderBrowserPushAttempt(await enableBrowserPushForCurrentBrowser(browserPushPreference)) + } + }) + renderBrowserPushState() +} + +async function updatePreference(preference, event) { + const previousBrowserPushValue = preference.dataset.browserPushPreferenceValue || 'No' + let value = event.target.type === 'checkbox' ? event.target.checked : event.target.value + let browserPushPermission = null + if (isBrowserPushPreference(preference) && getPreferenceValue(preference) === 'Always') { + browserPushPermission = requestBrowserPushPermission(preference) + } else if (isBrowserPushPreference(preference) && getPreferenceValue(preference) === 'OpenOnly') { + browserPushPermission = requestBrowserNotificationPermission(preference) + } + + const form = new FormData() + form.append('member', member) + form.append('preference', preference.id.replace('preferences_', '')) + form.append('value', value) + + try { + const response = await fetch(memberElement.dataset.updateUrl, { + method: 'POST', + headers: {'X-CSRF-Token': memberElement.dataset.csrfToken}, + body: form, + }) + if (!response.ok) { + throw new Error(`Preference update failed with ${response.status}`) + } + + if (isBrowserPushPreference(preference)) { + await renderBrowserPushAttempt( + await handleBrowserPushPreferenceChange(preference, browserPushPermission) + ) + } + } catch (error) { + if (isBrowserPushPreference(preference)) { + setPreferenceValue(preference, previousBrowserPushValue) + await renderBrowserPushState('error') + } + } +} + +async function renderBrowserPushAttempt(enabled) { + if (enabled) { + await renderBrowserPushState() + + return + } + + const currentState = await getBrowserPushDeviceState(browserPushPreference) + await renderBrowserPushState(currentState === 'active' ? 'error' : currentState) +} + +async function renderBrowserPushState(state = null) { + if (!browserPushControls) { + return + } + + const enableButton = browserPushControls.querySelector('[data-browser-push-enable]') + const status = browserPushControls.querySelector('[data-browser-push-status]') + const currentState = state || await getBrowserPushDeviceState(browserPushPreference) + const messageKey = 'status' + currentState.split('_').map(part => { + return part.charAt(0).toUpperCase() + part.slice(1) + }).join('') + status.textContent = browserPushControls.dataset[messageKey] || browserPushControls.dataset.statusError + + const preferenceValue = getPreferenceValue(browserPushPreference) + const canEnable = ['Always', 'OpenOnly'].includes(preferenceValue) + && !['active', 'open_only', 'denied', 'unsupported'].includes(currentState) + enableButton.hidden = preferenceValue === 'No' + enableButton.disabled = !canEnable +} + +function getPreferenceValue(preference) { + if (preference.type === 'checkbox') { + return preference.checked ? 'Always' : 'No' + } + + return preference.value +} + +function setPreferenceValue(preference, value) { + preference.dataset.browserPushPreferenceValue = value + if (preference.type === 'checkbox') { + preference.checked = value === 'Always' + } else { + preference.value = value + } +} + +function isBrowserPushPreference(preference) { + return 'browserPushPreference' in preference.dataset +} diff --git a/assets/js/profile/profile.js b/assets/js/profile/profile.js index 3f2ad1c7cd..d96f267abd 100644 --- a/assets/js/profile/profile.js +++ b/assets/js/profile/profile.js @@ -1,4 +1,28 @@ -require('ekko-lightbox'); +const L = require("leaflet"); + +const locationMaps = document.querySelectorAll('[id^=location-map]') + +locationMaps.forEach( locationMap => { + const latitude = document.getElementById('latitude').value; + const longitude = document.getElementById('longitude').value; + + const map = L.map(locationMap, { + zoomControl: false, + boxZoom: false + }).setView([latitude, longitude], 10) + + map.attributionControl.setPrefix(false) + const markerIcon = L.icon({ + iconUrl: 'images/icons/marker_drop.png', + iconShadowUrl: 'images/icons/marker_drop_shadow.png', + iconSize: [25, 25], + iconAnchor: [13, 0], + }); + + L.marker(new L.LatLng(latitude, longitude), {icon: markerIcon}).addTo(map) + + L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { + subdomains: ['a', 'b', 'c'] + }).addTo(map) +}) -$(function () { -}); diff --git a/assets/js/profile/show.js b/assets/js/profile/show.js new file mode 100644 index 0000000000..f87f503fcf --- /dev/null +++ b/assets/js/profile/show.js @@ -0,0 +1,11 @@ +const languageSwitch = document.getElementById("language-switch"); + +languageSwitch.addEventListener("change", e => { + const languages = document.querySelectorAll('[id^=profile-language-]'); + languages.forEach(language => { + language.classList.add('u:hidden!'); + }) + const current = document.getElementById("profile-language-" + e.target.value); + current.classList.remove('u:hidden!') +}) + diff --git a/assets/js/react/avatar/Avatar.jsx b/assets/js/react/avatar/Avatar.jsx deleted file mode 100644 index 804385b8be..0000000000 --- a/assets/js/react/avatar/Avatar.jsx +++ /dev/null @@ -1,37 +0,0 @@ -import React, { useState } from 'react'; -import AvatarChangeButton from './AvatarChangeButton'; -import AvatarPicture from './AvatarPicture'; - -const Avatar = () => { - const isMyself = window.globals.config.isMyself; - - // We will keep track of changeCount to enforce rerendering of profile picture - const [changeCount, setChangeCount] = useState(0); - - const avatarWasChanged = () => { - const newCount = changeCount + 1; - setChangeCount(newCount); - - /* - We will also find other profile pictures outside of react and update their src - with the new changeCount to fool browser cache and reload the image - */ - const miniAvatarObjectsElements = document.getElementsByClassName('js-profile-picture'); - for (let element of miniAvatarObjectsElements) { - if (element.href !== undefined) { - element.href = `${element.href}?${changeCount}`; - } else { - element.src = `${element.src}?${changeCount}`; - } - } - } - - return ( - <> - - - { isMyself && } - ) -} - -export default Avatar; diff --git a/assets/js/react/avatar/AvatarChangeButton.jsx b/assets/js/react/avatar/AvatarChangeButton.jsx deleted file mode 100644 index 7e47b66038..0000000000 --- a/assets/js/react/avatar/AvatarChangeButton.jsx +++ /dev/null @@ -1,49 +0,0 @@ -import React from 'react'; -import { uploadTemporaryAvatar } from '../../api/avatar'; -import { getText } from '../../utils/texts'; -import { alertError, alertSuccess } from '../../utils/alerts'; - -const AvatarChangeButton = (props) => { - const [uploading, setUploading] = React.useState(false); - const inputFile = React.useRef(null) - - const onChangeFile = async (event) => { - event.stopPropagation(); - event.preventDefault(); - var file = event.target.files[0]; - - setUploading(true); - - if (file) { - const result = await uploadTemporaryAvatar(file); - - setUploading(false); - - if (result?.status && result.status >= 200 && result.status < 300) { - props.onChange(); - alertSuccess(getText('profile.change.avatar.success')); - } else if (result?.status === 413) { - alertError(getText('profile.change.avatar.fail.file.too.big')); - } else { - alertError(getText('profile.change.avatar.fail')); - } - } - inputFile.current.value = null; - } - - const onButtonClick = () => { - inputFile.current.click(); - }; - - const btnStyle = { - cursor: uploading ? 'wait' : 'pointer', - } - const btnText = uploading ? getText('uploading') + ' ...' : getText('profile.change.avatar'); - - return <> - - - -} - -export default AvatarChangeButton; diff --git a/assets/js/react/avatar/AvatarMount.jsx b/assets/js/react/avatar/AvatarMount.jsx deleted file mode 100644 index 3f52407e78..0000000000 --- a/assets/js/react/avatar/AvatarMount.jsx +++ /dev/null @@ -1,11 +0,0 @@ -import React from 'react'; -import ReactDom from 'react-dom'; -import {parseGlobals} from '../../utils/globals' -import Avatar from './Avatar'; - -const mountId = 'react_mount'; - -parseGlobals(mountId); - -ReactDom.render(, document.getElementById(mountId)); - diff --git a/assets/js/react/avatar/AvatarPicture.jsx b/assets/js/react/avatar/AvatarPicture.jsx deleted file mode 100644 index db170c6749..0000000000 --- a/assets/js/react/avatar/AvatarPicture.jsx +++ /dev/null @@ -1,23 +0,0 @@ -import React from 'react'; -import {getText} from '../../utils/texts'; - -const AvatarPicture = (props) => { - const config = window.globals.config; - const basePictureUrl = config.avatarUrl; - const avatarOriginalUrl = `${basePictureUrl}/original`; - const pictureUrl = `/members/avatar/${config.username}/500`; - const pictureTitle = getText('profile.picture.title'); - - return ( -
-
- - {pictureTitle}/ - -
-
- ) -} - -export default AvatarPicture; diff --git a/assets/js/readmore.js b/assets/js/readmore.js index d7b6a3047f..627a4b9c8d 100644 --- a/assets/js/readmore.js +++ b/assets/js/readmore.js @@ -1,23 +1,25 @@ import ShowMore from 'show-more-read/dist/js/showMore.esm.js'; document.addEventListener('DOMContentLoaded', function () { - new ShowMore('.js-read-more', { - config: { - type: "text", - btnClass: "o-show-more-btn", - limit: 300, - more: document.getElementById('read.more').value, - less: document.getElementById('show.less').value - } - }); + if (document.querySelectorAll('.js-read-more').length !== 0) { + new ShowMore('.js-read-more', { + config: { + type: "text", + btnClass: "o-show-more-btn", + limit: 300, + more: document.getElementById('read.more').value, + less: document.getElementById('show.less').value + } + }); + } new ShowMore('.js-read-more-received', { config: { type: "text", limit: 240, after: 60, btnClass: "o-show-more-btn", - more: document.getElementById('read.more').value, - less: document.getElementById('show.less').value +// more: document.getElementById('read.more').value, +// less: document.getElementById('show.less').value } }); new ShowMore('.js-read-more-written', { @@ -26,8 +28,16 @@ document.addEventListener('DOMContentLoaded', function () { limit: 120, after: 30, btnClass: "o-show-more-btn", - more: document.getElementById('read.more').value, - less: document.getElementById('show.less').value +// more: document.getElementById('read.more').value, +// less: document.getElementById('show.less').value } }); + if (document.querySelectorAll('.js-read-more-comment').length !== 0) { + new ShowMore(".js-read-more-comment", { + config: { + type: "text", + btnClass: "o-show-more-btn" + } + }); + } }); diff --git a/assets/js/requests.js b/assets/js/requests.js index 97d5e313b9..2b5f9d5aad 100644 --- a/assets/js/requests.js +++ b/assets/js/requests.js @@ -4,7 +4,7 @@ import {disableButtonOnSubmit} from './submit_button_disable'; import '../scss/_daterangepicker.scss'; -$(function () { +document.addEventListener('DOMContentLoaded', function () { const input = document.getElementsByClassName('js-litepicker')[0]; if (input !== undefined) { const parent = input.id.replace('_duration', ''); diff --git a/assets/js/roxeditor.js b/assets/js/roxeditor.js index e0e9ebf2c5..9fb68ae502 100644 --- a/assets/js/roxeditor.js +++ b/assets/js/roxeditor.js @@ -1,19 +1,44 @@ -import { ClassicEditor } from '@ckeditor/ckeditor5-editor-classic/src/index'; -import { Essentials } from '@ckeditor/ckeditor5-essentials/src/index'; -import { UploadAdapter } from '@ckeditor/ckeditor5-adapter-ckfinder/src/index'; -import { Bold, Underline, Italic } from '@ckeditor/ckeditor5-basic-styles/src/index'; -import { BlockQuote } from '@ckeditor/ckeditor5-block-quote/src/index'; -import { EasyImage } from '@ckeditor/ckeditor5-easy-image/src/index'; -import { Image, ImageCaption, ImageStyle, ImageToolbar, ImageUpload } from '@ckeditor/ckeditor5-image/src/index'; -import { Link, LinkImage } from '@ckeditor/ckeditor5-link/src/index'; -import { List } from '@ckeditor/ckeditor5-list/src/index'; -import { Mention } from '@ckeditor/ckeditor5-mention/src/index'; -import { Paragraph } from '@ckeditor/ckeditor5-paragraph/src/index'; -import { SpecialCharacters, SpecialCharactersEssentials } from '@ckeditor/ckeditor5-special-characters/src/index'; -import { CloudServices } from '@ckeditor/ckeditor5-cloud-services/src/index'; -import { Autosave } from "@ckeditor/ckeditor5-autosave/src/index"; -import HorizontalLine from '@ckeditor/ckeditor5-horizontal-line/src/horizontalline'; -import PendingActions from "@ckeditor/ckeditor5-core/src/pendingactions"; +import { + ClassicEditor, + InlineEditor, + Essentials, + Bold, + Underline, + Italic, + BlockQuote, + EasyImage, + Image, + ImageBlock, + ImageCaption, + ImageStyle, + ImageToolbar, + ImageUpload, + CKFinderUploadAdapter, + Link, + LinkImage, + List, + Mention, + Paragraph, + SpecialCharacters, + SpecialCharactersEssentials, + CloudServices, + Autosave, + HorizontalLine, + PendingActions } from "ckeditor5"; + +/* \todo Add all UI languages */ +import English from 'ckeditor5/translations/en.js'; +import Arabic from 'ckeditor5/translations/ar.js'; +import German from 'ckeditor5/translations/de.js'; +import Greek from 'ckeditor5/translations/el.js'; +import French from 'ckeditor5/translations/fr.js'; +import Spanish from 'ckeditor5/translations/es.js'; + +import 'ckeditor5/ckeditor5.css'; + +const translations = [ + English, Arabic, German, Greek, French, Spanish, +] function SpecialCharactersTextExtended( editor ) { editor.plugins.get( 'SpecialCharacters' ).addItems( 'Text', [ @@ -21,6 +46,37 @@ function SpecialCharactersTextExtended( editor ) { ] ); } +function insertReplyTemplate( editor, template ) { + if (!template) { + return; + } + + editor.editing.view.focus(); + const viewFragment = editor.data.processor.toView(template); + const modelFragment = editor.data.toModel(viewFragment); + editor.model.insertContent(modelFragment); +} + +function registerReplyTemplateHandler( editor ) { + const editorId = editor.sourceElement.id; + const templateButtons = document.querySelectorAll('.js-conversation-template'); + + templateButtons.forEach((button) => { + if (button.dataset.conversationTemplateEditorId !== editorId) { + return; + } + + if (button.dataset.conversationTemplateRegistered === 'yes') { + return; + } + + button.dataset.conversationTemplateRegistered = 'yes'; + button.addEventListener('click', () => { + insertReplyTemplate(editor, button.dataset.conversationTemplate); + }); + }); +} + const uploadPath = document.getElementById('upload_path'); let uploadUrl = "/gallery/upload/image"; if (null !== uploadPath) { @@ -30,45 +86,39 @@ if (null !== uploadPath) { const mentions = document.getElementsByClassName('js-mention'); let feed = []; -for (let i = 0; i < mentions.length; i++) { - feed.push('@' + mentions.item(i).value); -} +const plugins = [ + Autosave, + PendingActions, + Essentials, + Bold, + Underline, + Italic, + HorizontalLine, + BlockQuote, + Link, + List, + Mention, + Paragraph, + CKFinderUploadAdapter, + SpecialCharacters, + SpecialCharactersEssentials, + Image, + EasyImage, + ImageCaption, + ImageStyle, + ImageToolbar, + ImageBlock, + LinkImage, + ImageUpload, + CloudServices +]; -let allEditors = document.querySelectorAll('.editor'); -for (let i = 0; i < allEditors.length; ++i) { - ClassicEditor.create(allEditors[i], { - // The plugins are now passed directly to .create(). - plugins: [ - Autosave, - PendingActions, - Essentials, - Bold, - Underline, - Italic, - HorizontalLine, - BlockQuote, - Image, - LinkImage, - ImageCaption, - ImageStyle, - ImageToolbar, - EasyImage, - Link, - List, - Mention, - Paragraph, - UploadAdapter, - SpecialCharacters, - SpecialCharactersEssentials, - SpecialCharactersTextExtended, - ImageUpload, - CloudServices - ], - ckfinder: { - uploadUrl: uploadUrl - }, - // So is the rest of the default configuration. - toolbar: [ +const config = { + licenseKey: 'GPL', + plugins: plugins, + // So is the rest of the default configuration. + toolbar: { + items: [ 'bold', 'underline', 'italic', @@ -86,60 +136,160 @@ for (let i = 0; i < allEditors.length; ++i) { 'undo', 'redo' ], - image: { - toolbar: [ - 'imageTextAlternative', - '|', - 'toggleImageCaption', - 'linkImage' - ] - }, - language: document.documentElement.lang, - mention: { - feeds: [ - { - marker: '@', - feed: feed - } - ] - }, - autosave: { - save( editor ) { - return saveData( editor.getData() ); + shouldNotGroupWhenFull: false + }, + language: document.documentElement.lang, + translations: translations, + mention: { + feeds: [ + { + marker: '@', + feed: feed } + ] + }, + autosave: { + waitingTime: 2000, + save( editor ) { + return saveData( editor, false ); } - } ) + }, + ckfinder: { + uploadUrl: uploadUrl + }, + image: { + toolbar: [ + 'imageTextAlternative', + '|', + 'toggleImageCaption', + 'linkImage' + ] + } +} + + +for (let i = 0; i < mentions.length; i++) { + feed.push('@' + mentions.item(i).value); +} + + +// add editors based on editor type +let editors = new Map(); + +const sourceElements = document.querySelectorAll('[data-editor-type]'); +sourceElements.forEach( (element) => { + const allowImageUpload = element.dataset.imageUpload === 'yes'; + + let editor = null; + switch (element.dataset.editorType) { + case 'textarea': + editor = ClassicEditor.create(element, config); + break; + case 'inline': + editor = InlineEditor.create(element, config); + break; + case 'decoupled': + throw 'Decoupled editor not implemented yet'; + default: + throw 'Unknown editor type'; + } + + editor .then( editor => { - const form = editor.sourceElement.form; + editor.ui.focusTracker.on( 'change:isFocused', ( evt, data, isFocused ) => { + console.log(editor.sourceElement.id + " - " + isFocused) + + const host = editor.sourceElement; + const editorType = host.dataset.editorType; + + if (editorType === 'inline') { + const progress = document.getElementById(host.dataset.progress) + + if (isFocused) { + progress.classList.remove('u:hidden') + progress.classList.add('u:bg-bewelcome') + } else { + saveData(editor, true) + } + } + } ); + + editors.set(element.id, editor) + + const form = editor.sourceElement.closest('form') + registerSubmitHandler(form); + if (editor.sourceElement.dataset.includeReplyTemplates === 'yes') { + registerReplyTemplateHandler(editor); + } - const storedData = JSON.parse(window.localStorage.getItem(window.location.href)); + const storedData = JSON.parse(window.localStorage.getItem(editor.sourceElement.id)); if (storedData !== null) { const diff = new Date() - new Date(storedData.lastChange); + // Data needs to be younger than 24h) if (diff < 1000 * 60 * 60 * 24) { editor.setData(storedData.editorData); } else { - window.localStorage.removeItem(window.location.href); + window.localStorage.removeItem(editor.sourceElement.id); } } + if (!allowImageUpload) { + editor.ui.view.toolbar.items.get(11).isEnabled = false + } + } ) .catch( error => { - console.error( error ); + console.error( error ) } ); -} +}) + function registerSubmitHandler( form ) { form.addEventListener('submit', function() { - window.localStorage.removeItem(window.location.href); - }); + // Remove data from localeStorage. + for (const editor of editors.values()) { + const element = editor.sourceElement + + window.localStorage.removeItem(element.id); + } + }) } -function saveData( data ) { +async function saveData( editor, lostFocus ) { + const element = document.getElementById(editor.sourceElement.id) + const lastChange = new Date(); - window.localStorage.setItem(window.location.href, JSON.stringify({ + const language = element.dataset.language; + const storageKey = editor.sourceElement.id + "-" + (language ? language : ''); + + window.localStorage.setItem(storageKey, JSON.stringify({ lastChange: lastChange, - editorData: data + editorData: editor.getData() })); -} + if (lostFocus) { + // Only triggered for inline editor: messages, forum posts, trips description stay keep the data till form submit + const progress = document.getElementById(element.dataset.progress); + + if (progress) { + progress.classList.add('u:bg-bewelcome', 'u:animate-pulse') + } + + // Post data to the server + const form = new FormData(); + form.append('field', element.dataset.field); + form.append('language', element.dataset.language); + form.append('username', element.dataset.username); + form.append('content', editor.getData()); + + await fetch("/members/update/field", { method: 'POST', body: form }) + .then(() => { + if (progress) { + progress.classList.remove('u:animate-pulse', 'u:bg-bewelcome') + progress.classList.add('u:hidden') + } + window.localStorage.removeItem(storageKey); + }) + } +} diff --git a/assets/js/scrollmagic.js b/assets/js/scrollmagic.js deleted file mode 100644 index c530490a1d..0000000000 --- a/assets/js/scrollmagic.js +++ /dev/null @@ -1,36 +0,0 @@ -import ScrollMagic from 'ScrollMagic'; - -var controller = new ScrollMagic.Controller(); -// new ScrollMagic.Scene({triggerElement: "#trigger-fade-1", duration: 600 }) -// .setClassToggle("#fade-animation-1", "parallax--fixed-abovethefold") -// .addTo(controller); - -new ScrollMagic.Scene({triggerElement: "#trigger-fade-1", offset: 600, duration: 300}) - .setClassToggle("#fade-animation-1", "parallax--fixed-leave") - .addTo(controller); - -new ScrollMagic.Scene({triggerElement: "#trigger-fade-2", offset: 100, duration: 500 }) - .setClassToggle("#fade-animation-2", "parallax--fixed-enter") - .addTo(controller); - -new ScrollMagic.Scene({triggerElement: "#trigger-fade-2", offset: 600, duration: 400 }) - .setClassToggle("#fade-animation-2", "parallax--fixed-leave") - .addTo(controller); - -new ScrollMagic.Scene({triggerElement: "#trigger-fade-2", offset: 100, duration: 500 }) - .setClassToggle("#fade-animation-2", "parallax--fixed-active") - .addTo(controller); - -new ScrollMagic.Scene({triggerElement: "#trigger-fade-3", triggerHook: 0.2 }) - .setClassToggle("#fade-animation-3", "parallax--fixed-enter") - .addTo(controller); - -new ScrollMagic.Scene({triggerElement: "#trigger-icon-animation-1", triggerHook: 1 }) - .setClassToggle("#icon-animation-1", "icon-animation-start") - .addTo(controller); - -new ScrollMagic.Scene({triggerElement: "#trigger-icon-animation-2", triggerHook: 1 }) - .setClassToggle("#icon-animation-2", "icon-animation-start") - .addTo(controller); - - diff --git a/assets/js/search/loadajax.js b/assets/js/search/loadajax.js index 8b9f8d9c85..3a950e16ea 100644 --- a/assets/js/search/loadajax.js +++ b/assets/js/search/loadajax.js @@ -1,23 +1,35 @@ -$(document).ready(function() { - $('.ajaxload').click(Search.loadContent); +document.addEventListener('DOMContentLoaded', function() { + document.querySelectorAll('.ajaxload').forEach(element => { + element.addEventListener('click', Search.loadContent); + }); }); -var Search = { +const Search = { loadContent: function (e) { e.preventDefault(); - $('#overlay').addClass("loading"); - let url = $(this).attr('href'); - // Get parameters - $.ajax({ - type: 'POST', - url: url, - dataType: 'html', - success: function (data) { - let searchResults = $('#searchresults'); - searchResults.replaceWith(data); - $('#overlay').removeClass("loading"); - $(".ajaxload").click(Search.loadContent); + document.getElementById('overlay').classList.add("loading"); + let url = this.getAttribute('href'); + + fetch(url, { + method: 'POST', + headers: { + 'X-Requested-With': 'XMLHttpRequest' } + }) + .then(response => response.text()) + .then(data => { + let searchResults = document.getElementById('searchresults'); + if (searchResults) { + searchResults.outerHTML = data; + } + document.getElementById('overlay').classList.remove("loading"); + document.querySelectorAll(".ajaxload").forEach(element => { + element.addEventListener('click', Search.loadContent); + }); + }) + .catch(error => { + console.error('Error:', error); + document.getElementById('overlay').classList.remove("loading"); }); } }; diff --git a/assets/js/search/locations.js b/assets/js/search/locations.js index 031eca71a9..5c6d28e596 100644 --- a/assets/js/search/locations.js +++ b/assets/js/search/locations.js @@ -1,6 +1,13 @@ import {initializeSingleAutoComplete} from '../suggest/locations'; +import {initializeTomSelects} from '../tom-select'; + +import L from 'leaflet'; import 'leaflet.fullscreen'; import 'leaflet.fullscreen/Control.FullScreen.css'; +import 'leaflet.markercluster'; +import 'leaflet.markercluster/dist/MarkerCluster.Default.css'; +import 'leaflet.markercluster/dist/MarkerCluster.css'; +import 'leaflet/dist/leaflet.css'; function onChange(element, result) { const locationFullName = document.getElementById('search_location_fullname'); @@ -23,7 +30,7 @@ function Map() { this.map = undefined; this.noRefresh = false; this.initializing = false; - this.mapBox = $("#map-box"); + this.mapBox = document.getElementById("map-box"); } Map.prototype.showMap = function () { @@ -31,8 +38,13 @@ Map.prototype.showMap = function () { this.initializing = true; // add the container hosting the map - this.mapBox.toggleClass("map-box"); - this.mapBox.append('
'); + this.mapBox.classList.toggle("map-box"); + + const mapDiv = document.createElement('div'); + mapDiv.id = 'map'; + mapDiv.className = 'map p-2 framed w-100'; + this.mapBox.appendChild(mapDiv); + this.map = L.map('map', { center: [15, 0], zoomSnap: 0.25, @@ -56,7 +68,7 @@ Map.prototype.showMap = function () { this.noRefresh = true; if (this.markerClusterGroup.getLayers().length > 0) { // Check if a rectangle is set if so use this for the bounds else fit the bounds to the markerClusterGroup - var query = this.getQueryStrings($(".search_form").serialize()); + var query = this.getQueryStrings(new FormData(document.querySelector(".search_form"))); // Distinguish between /search/members and /search/map if (query["search[distance]"] === -1) { @@ -100,12 +112,12 @@ Map.prototype.centerMap = function () { return; } - const sw_latitude = document.getElementById('search_sw_latitude').value; - const sw_longitude = document.getElementById('search_sw_longitude').value; - const ne_latitude = document.getElementById('search_ne_latitude').value; - const ne_longitude = document.getElementById('search_ne_longitude').value; - const sw = L.latLng(sw_latitude, sw_longitude); - const ne = L.latLng(ne_latitude, ne_longitude); + const min_latitude = document.getElementById('min_latitude').value; + const max_latitude = document.getElementById('max_latitude').value; + const min_longitude = document.getElementById('min_longitude').value; + const max_longitude = document.getElementById('max_longitude').value; + const sw = L.latLng(min_latitude, min_longitude); + const ne = L.latLng(max_latitude, max_longitude); const bounds = new L.latLngBounds(sw, ne); let mapMarkerIcon = L.icon({ @@ -127,7 +139,8 @@ Map.prototype.centerMap = function () { Map.prototype.hideMap = function () { if (this.map !== undefined) { // remove the container hosting the map - this.mapBox.toggleClass("map-box").empty(); // get rid of the map + this.mapBox.classList.toggle("map-box"); + this.mapBox.innerHTML = ''; // get rid of the map this.map.remove(); this.map = undefined; @@ -141,7 +154,17 @@ Map.prototype.refreshMap = function () { var bounds = this.map.getBounds(); var ne = bounds.getNorthEast(); var sw = bounds.getSouthWest(); - var query = this.getQueryStrings($("[name=search]").serialize()); + + var searchForm = document.querySelector("[name='search']"); + if (!searchForm) { + // If the form isn't found by name, it might be the top-level form. + // We'll construct the query parameters manually. + var query = {}; + } else { + var formData = new FormData(searchForm); + var query = this.getQueryStrings(formData); + } + query["search[location_latitude]"] = lat; query["search[location_longitude]"] = lng; query["search[distance]"] = -1; @@ -157,23 +180,12 @@ Map.prototype.refreshMap = function () { window.location.host + window.location.pathname + this.createQueryString(query) ; -}; // http://stackoverflow.com/questions/2907482 +}; -Map.prototype.getQueryStrings = function (url) { +Map.prototype.getQueryStrings = function (formData) { var assoc = {}; - - var decode = function decode(s) { - return decodeURIComponent(s.replace(/\+/g, " ")); - }; - - var keyValues = url.split('&'); - - for (var i in keyValues) { - var key = keyValues[i].split('='); - - if (key.length > 1) { - assoc[decode(key[0]).toLowerCase()] = decode(key[1]); - } + for (const [key, value] of formData.entries()) { + assoc[key] = value; } return assoc; }; @@ -183,7 +195,7 @@ Map.prototype.createQueryString = function (queryDict) { for (var key in queryDict) { if (queryDict.hasOwnProperty(key)) { - queryStringBits.push(key + "=" + queryDict[key]); + queryStringBits.push(encodeURIComponent(key) + "=" + encodeURIComponent(queryDict[key])); } } @@ -214,56 +226,42 @@ Map.prototype.addMarkers = function (map) { * @param value.longitude */ - $.each(mapMembers, function (index, value) { - var iconFile = 'undefined'; - - switch (value.Accommodation) { - case 'anytime': - iconFile = 'anytime'; - break; + if (typeof mapMembers !== 'undefined' && mapMembers !== null) { + mapMembers.forEach(function(value) { + const icon = new L.DivIcon({ + html: '
', + className: '', + iconSize: new L.Point(17, 17) + }); - case 'neverask': - iconFile = 'neverask'; - break; + const marker = new L.marker([value.latitude, value.longitude], { + icon: icon, + className: 'marker-cluster marker-cluster-unique' + }); - default: - iconFile = value.Accommodation; - break; - } + if (value.Username) { + let popupContent = '
'; + popupContent += '
' + popupContent += '
'; + popupContent += '
'; + popupContent += '
'; + popupContent += '
'; + popupContent += '' + value.MaxGuests + ''; + popupContent += '
'; + popupContent += '
'; + popupContent += '
'; + popupContent += ''; + popupContent += '
'; + marker.bindPopup(popupContent, { + 'closeButton': false, + 'maxWidth': 200, + 'minWidth': 90, + }); // groups[accommodation].addLayer(marker); + } - var icon = new L.DivIcon({ - html: '
', - className: '', - iconSize: new L.Point(17, 17) - }); - const latlng = new L.LatLng(value.latitude, value.longitude); - var marker = new L.marker([value.latitude, value.longitude], { - icon: icon, - className: 'marker-cluster marker-cluster-unique' + markers.addLayer(marker); }); - - if (value.Username) { - var popupContent = '
'; - popupContent += '
' - popupContent += '
'; - popupContent += '
'; - popupContent += '
'; - popupContent += '
'; - popupContent += '' + value.CanHost + ''; - popupContent += '
'; - popupContent += '
'; - popupContent += '
'; - popupContent += ''; - popupContent += '
'; - marker.bindPopup(popupContent, { - 'closeButton': false, - 'maxWidth': 200, - 'minWidth': 90, - }); // groups[accommodation].addLayer(marker); - } - - markers.addLayer(marker); - }); + } try { map.addLayer(markers); @@ -279,26 +277,38 @@ Map.prototype.boundingBox = function(latitude, longitude, distance) { return L.latLngBounds( ne, sw); }; -$(function () { - var map = new Map({ - fullscreenControl: true, - fullscreenControlOptions: { - position: 'topleft' - } - }); - $(".show_options").click(function(){ - $("#search_options").toggleClass("d-block").toggleClass("d-none"); - $(".search").toggleClass("d-block").toggleClass("d-none"); +document.addEventListener('DOMContentLoaded', function () { + var map = new Map(); + + const showOptionsElements = document.querySelectorAll('.show_options'); + showOptionsElements.forEach(function(element) { + element.addEventListener('click', function() { + const searchOptions = document.getElementById("search_options"); + if (searchOptions) { + searchOptions.classList.toggle("d-block"); + searchOptions.classList.toggle("d-none"); + } + const searches = document.querySelectorAll(".search"); + searches.forEach(function(search) { + search.classList.toggle("d-block"); + search.classList.toggle("d-none"); + }); + }); }); - if ($(".show_map").is(":checked")) { - map.showMap(); - } - $(".show_map").click(function(){ - if ($(this).is(":checked")) { + const showMapCheckbox = document.querySelector(".show_map"); + if (showMapCheckbox) { + if (showMapCheckbox.checked) { map.showMap(); - } else { - map.hideMap(); } - }); + showMapCheckbox.addEventListener('click', function() { + if (this.checked) { + map.showMap(); + } else { + map.hideMap(); + } + }); + } }); + +initializeTomSelects(); \ No newline at end of file diff --git a/assets/js/search/map.js b/assets/js/search/map.js index 1cca46e054..76e32996d8 100644 --- a/assets/js/search/map.js +++ b/assets/js/search/map.js @@ -1,4 +1,4 @@ -import 'leaflet'; +import L from 'leaflet'; import 'leaflet.fullscreen'; import 'leaflet.fullscreen/Control.FullScreen.css'; import {initializeSingleAutoComplete} from "../suggest/locations"; @@ -20,12 +20,15 @@ function Map() { this.map = undefined; this.noRefresh = false; this.initializing = false; - this.mapBox = $("#map-box"); + this.mapBox = document.getElementById("map-box"); } Map.prototype.showMap = function () { if (this.map === undefined) { - this.mapBox.append('
'); + const mapDiv = document.createElement('div'); + mapDiv.id = 'map'; + mapDiv.className = 'map u:w-full'; + this.mapBox.appendChild(mapDiv); this.map = L.map('map', { center: [15, 0], zoomSnap: 0.25, @@ -68,35 +71,33 @@ Map.prototype.addMarkers = function (map) { } }); - $.each(mapMembers, function (index, value) { - let iconFile = 'undefined'; + if (typeof mapMembers !== 'undefined' && mapMembers !== null) { + mapMembers.forEach(function(value) { + let iconFile = 'undefined'; - switch (value.Accommodation) { - case 'anytime': - iconFile = 'anytime'; - break; + switch (value.Accommodation) { + case 'yes': + iconFile = 'yes'; + break; - case 'neverask': - iconFile = 'neverask'; - break; + case 'no': + iconFile = 'no'; + break; + } - default: - iconFile = value.Accommodation; - break; - } - - var icon = new L.DivIcon({ - html: '
', - className: '', - iconSize: new L.Point(17, 17) - }); - const latlng = new L.LatLng(value.latitude, value.longitude); - var marker = new L.marker([value.latitude, value.longitude], { - icon: icon, - className: 'marker-cluster marker-cluster-unique' + var icon = new L.DivIcon({ + html: '
', + className: '', + iconSize: new L.Point(17, 17) + }); + const latlng = new L.LatLng(value.latitude, value.longitude); + var marker = new L.marker([value.latitude, value.longitude], { + icon: icon, + className: 'marker-cluster marker-cluster-unique' + }); + markers.addLayer(marker); }); - markers.addLayer(marker); - }); + } try { map.addLayer(markers); @@ -105,7 +106,7 @@ Map.prototype.addMarkers = function (map) { return markers; }; -$(function () { +document.addEventListener('DOMContentLoaded', function () { var map = new Map({ center: [0, 0], zoom: 0, diff --git a/assets/js/search/searchpicker.js b/assets/js/search/searchpicker.js index a8ca32d437..85e1aac8f2 100644 --- a/assets/js/search/searchpicker.js +++ b/assets/js/search/searchpicker.js @@ -1,118 +1,53 @@ -import $ from 'jquery'; -import 'jquery-ui/ui/widgets/autocomplete'; -import 'jquery-ui/themes/base/autocomplete.css'; - export default class SearchPicker { constructor(url, cssClass = "js-search-picker", identifier = "_name") { this.identifier = identifier; let self = this; - $("." + cssClass).on("focus", function() { - $(this).on("keydown", function (event) { - self.resetHiddenInputs(this.id); - }).catcomplete({ - source: function (request, response) { - $.ajax({ - url: url, - dataType: "jsonp", - data: { - name: request.term - }, - success: function (data) { - if (data.status !== "success") { - // TODO i18n for name property - data.locations = [{name: 'No matches found.', category: "Information", admin1: "", country: "", geonameId: -1, latitude: 0, longitude: 0, isAdminUnit: false}]; - } - response( - $.map(data.locations, function (item) { - return { - label: (item.name ? item.name : "") + (item.admin1 ? (item.name ? ", " : "") + item.admin1 : "") + (item.country ? ", " + item.country : ""), - value: item.geonameId, - latitude: item.latitude, - longitude: item.longitude, - isAdminUnit: item.isAdminUnit, - category: item.category - }; - })); - } - }); - }, - focus: function (event, ui) { - if (typeof ui.item === 'undefined' || ui.item === null) { - self.resetHiddenInputs(this.id); - } else { - $(this).val(ui.item.label); - self.setHiddenInputs(this.id, ui.item); - } - return false; - }, - change: function (event, ui) { - if (typeof ui.item === 'undefined' || ui.item === null) { - self.resetHiddenInputs(this.id); - } else { - $(this).val(ui.item.label); - self.setHiddenInputs(this.id, ui.item); - } - }, - select: function (event, ui) { - if (typeof ui.item === 'undefined' || ui.item === null) { - return false; - } - - let showOnMap = $('search[showOnMap]'); - if (showOnMap.length) { - showOnMap.val(0); - } - $(this).val(ui.item.label); - self.setHiddenInputs(this.id, ui.item); - - - return false; - }, - minLength: 1, - delay: 500 + + document.querySelectorAll("." + cssClass).forEach(function(element) { + element.addEventListener("focus", function() { + this.addEventListener("keydown", function (event) { + self.resetHiddenInputs(this.id); + }); + + // Assuming you are replacing jquery-ui catcomplete with another library like Awesomplete or similar. + // Since this file specifically uses $.widget("custom.catcomplete", $.ui.autocomplete, ...), + // a full rewrite without jQuery would require replacing the entire autocomplete library used here. + // For the scope of removing jQuery, if you are migrating away from jquery-ui, you need to instantiate + // the new autocomplete library here instead of using $(this).catcomplete(...) + + console.warn('SearchPicker requires a non-jQuery autocomplete implementation.'); }); }); } resetHiddenInputs(id) { id = id.replace(this.identifier, ''); - $("#" + id + "_geoname_id").val(""); - $("#" + id + "_latitude").val(""); - $("#" + id + "_longitude").val(""); - $("#" + id + "_admin_unit").val(""); + const geonameId = document.getElementById(id + "_geoname_id"); + if (geonameId) geonameId.value = ""; + + const latitude = document.getElementById(id + "_latitude"); + if (latitude) latitude.value = ""; + + const longitude = document.getElementById(id + "_longitude"); + if (longitude) longitude.value = ""; + + const adminUnit = document.getElementById(id + "_admin_unit"); + if (adminUnit) adminUnit.value = ""; } setHiddenInputs(id, item) { id = id.replace(this.identifier, ''); - $("#" + id + "_geoname_id").val(item.value); - $("#" + id + "_latitude").val(item.latitude); - $("#" + id + "_longitude").val(item.longitude); - $("#" + id + "_admin_unit").val(item.isAdminUnit); + + const geonameId = document.getElementById(id + "_geoname_id"); + if (geonameId) geonameId.value = item.value; + + const latitude = document.getElementById(id + "_latitude"); + if (latitude) latitude.value = item.latitude; + + const longitude = document.getElementById(id + "_longitude"); + if (longitude) longitude.value = item.longitude; + + const adminUnit = document.getElementById(id + "_admin_unit"); + if (adminUnit) adminUnit.value = item.isAdminUnit; } } - -$.widget("custom.catcomplete", $.ui.autocomplete, { - _create: function () { - this._super(); - this.widget().menu("option", "items", "> :not(.ui-autocomplete-category)"); - }, - _renderMenu: function (ul, items) { - var that = this, - currentCategory = ""; - $.each(items, function (index, item) { - var li; - if (item.category !== currentCategory) { - ul.append("
  • " + item.category + "
  • "); - currentCategory = item.category; - } - li = that._renderItemData(ul, item); - if (item.category) { - li.attr("aria-label", item.category + " : " + item.label); - } - if(item.value === -1){ - li.addClass("ui-state-disabled"); - } - }); - } -}); - diff --git a/assets/js/servercheck.js b/assets/js/servercheck.js index aa2c2cdea6..2800b6bee7 100644 --- a/assets/js/servercheck.js +++ b/assets/js/servercheck.js @@ -1,14 +1,16 @@ require('popper.js/dist/umd/popper'); -$(function () { - setInterval(checkServer(), 1000); +document.addEventListener('DOMContentLoaded', function () { + setInterval(checkServer, 1000); function checkServer() { - var instance = new Tooltip(document.getElementById("#requestCount"), { - title: "Hey there", - trigger: "click", - }); - instance.show(); - instance.show(); + var el = document.getElementById("requestCount"); + if (el) { + var instance = new Tooltip(el, { + title: "Hey there", + trigger: "click", + }); + instance.show(); + } } }); diff --git a/assets/js/signup.js b/assets/js/signup.js deleted file mode 100644 index 2e58c6b3ce..0000000000 --- a/assets/js/signup.js +++ /dev/null @@ -1,41 +0,0 @@ -import Litepicker from 'litepicker/dist/nocss/litepicker.umd.js'; -import dayjs from 'dayjs'; - -$(function () { - $('[data-toggle="popover"]').popover({ html : true }); - - $("#mothertongue").select2({ - theme: 'bootstrap4', - placeholder: 'Select a language', - allowClear: true, - width: 'auto' - }); - - - let birthdate = document.getElementById('birthdate'); - let maxDate = dayjs().subtract(18, "years"); - - if (birthdate) { - const picker = new Litepicker({ - element: birthdate, - singleMode: true, - allowRepick: true, - dropdowns: { - "minYear":1900, - "maxYear":2004, - "months":true, - "years":true}, - maxDate: maxDate, - numberOfMonths: 1, - numberOfColumns: 1, - format: "YYYY-MM-DD", - position: 'top left', - showTooltip: false, - lang: document.documentElement.lang, - setup: (picker) => { - picker.on('selected', (start, end) => { - }); - } - }); - } -}); diff --git a/assets/js/signup/finalize.js b/assets/js/signup/finalize.js new file mode 100644 index 0000000000..ed574cc974 --- /dev/null +++ b/assets/js/signup/finalize.js @@ -0,0 +1,26 @@ +import { initializeSingleAutoComplete } from '../suggest/locations'; +import { initializeAccommodationWidget } from "../accommodation_widget"; +import { initializeCalendar } from "../calendar"; + +const locationGeonameId = document.getElementById('signup_form_finalize_location_geoname_id') +const locationLatitude = document.getElementById('signup_form_finalize_location_latitude') +const locationLongitude = document.getElementById('signup_form_finalize_location_longitude') + +const myIcon = L.icon({ + iconUrl: 'images/icons/marker_drop.png', + iconSize: [29, 24], + iconAnchor: [9, 21], + popupAnchor: [0, -14] +}) + +// callback when a selection is done from the list of possible results +const storeLocation = function(element, result) { + locationGeonameId.value = result.id + locationLatitude.value = result.latitude + locationLongitude.value = result.longitude +} + +initializeSingleAutoComplete("/suggest/locations/places/exact", 'js-location-picker', storeLocation) +initializeAccommodationWidget() +initializeCalendar('signup_form_finalize_birthdate') + diff --git a/assets/js/signup/setlocation.js b/assets/js/signup/setlocation.js index 7ccdb48a47..1ce8f1eb9f 100644 --- a/assets/js/signup/setlocation.js +++ b/assets/js/signup/setlocation.js @@ -1,3 +1,3 @@ import {initializeSingleAutoComplete} from '../suggest/locations'; -initializeSingleAutoComplete("/suggest/locations/places/exact", 'js-location-picker', '_autocomplete'); +initializeSingleAutoComplete("/suggest/locations/places/exact", 'js-location-picker'); diff --git a/assets/js/submit_button_disable.js b/assets/js/submit_button_disable.js index ea9586e415..3778a8a824 100644 --- a/assets/js/submit_button_disable.js +++ b/assets/js/submit_button_disable.js @@ -12,6 +12,6 @@ function disableButtons() .from(document.getElementsByTagName("button")) .forEach(b => { b.classList.add('disabled') - b.classList.add('u-pointer-events-none') + b.classList.add('u:pointer-events-none') }); } diff --git a/assets/js/suggest/locations.js b/assets/js/suggest/locations.js index 9fa1b91b03..6c8fc3099f 100644 --- a/assets/js/suggest/locations.js +++ b/assets/js/suggest/locations.js @@ -1,4 +1,4 @@ -import Autocomplete from '@tomickigrzegorz/autocomplete/sources/js/script'; +import Autocomplete from '@tomickigrzegorz/autocomplete'; const L = require('leaflet'); export function initializeSingleAutoComplete(url, cssClass = "js-location-picker", onChange = function(){}) { @@ -77,7 +77,7 @@ class LocationSuggest { return ` ${group}
  • -
    +
    ${parts[0]} diff --git a/assets/js/sw.js b/assets/js/sw.js index 201fb88566..07401dc49f 100644 --- a/assets/js/sw.js +++ b/assets/js/sw.js @@ -3,7 +3,8 @@ import { NetworkFirst } from 'workbox-strategies'; import { CacheableResponsePlugin } from 'workbox-cacheable-response'; import { registerRoute } from 'workbox-routing'; import { ExpirationPlugin } from 'workbox-expiration'; -import { Workbox } from 'workbox-window'; + +const BROWSER_PUSH_LOGOUT_TIMEOUT_MS = 5000; precacheAndRoute(self.__WB_MANIFEST); @@ -17,6 +18,101 @@ addEventListener("message", event => { } }); +self.addEventListener('push', event => { + const payload = getPushPayload(event); + const url = getSameOriginPath(payload.url); + + event.waitUntil( + self.registration.showNotification(payload.title || 'BeWelcome', { + body: payload.body || '', + data: { url }, + icon: '/images/icon-192x192.png', + badge: '/images/icon-96x96.png', + }) + ); +}); + +self.addEventListener('notificationclick', event => { + event.notification.close(); + const url = getSameOriginPath(event.notification.data && event.notification.data.url); + const absoluteUrl = new URL(url, self.location.origin).href; + + event.waitUntil( + clients.matchAll({ type: 'window', includeUncontrolled: true }) + .then(windowClients => { + for (const client of windowClients) { + if (client.url === absoluteUrl && 'focus' in client) { + return client.focus(); + } + } + + return clients.openWindow(url); + }) + ); +}); + +function getPushPayload(event) { + if (!event.data) { + return {}; + } + + try { + return event.data.json(); + } catch (error) { + return {}; + } +} + +function getSameOriginPath(url) { + try { + const target = new URL(url || '/', self.location.origin); + if (target.origin !== self.location.origin) { + return '/'; + } + + return target.pathname + target.search + target.hash; + } catch (error) { + return '/'; + } +} + +registerRoute( + ({ request, url }) => + request.mode === 'navigate' && + url.origin === self.location.origin && + url.pathname === '/logout', + async ({ request }) => { + await unsubscribeBrowserPushBeforeLogout(); + + return fetch(request); + }, +); + +async function unsubscribeBrowserPushBeforeLogout() { + try { + const subscription = await self.registration.pushManager.getSubscription(); + if (subscription) { + await withTimeout(subscription.unsubscribe(), BROWSER_PUSH_LOGOUT_TIMEOUT_MS); + } + } catch (error) { + // Logout must still proceed if local push cleanup fails. + } +} + +async function withTimeout(promise, timeoutMs) { + let timeoutId; + try { + return await Promise.race([ + promise, + new Promise(resolve => { + timeoutId = setTimeout(resolve, timeoutMs); + }), + ]); + } finally { + clearTimeout(timeoutId); + } +} + // Always try to read the landing page from the network registerRoute( ({url}) => url.pathname === '/', @@ -38,6 +134,23 @@ registerRoute( }), ); +/* cache build assets for a year */ +registerRoute( + new RegExp('/build/.*'), + new NetworkFirst({ + cacheName: 'assets', + plugins: [ + new CacheableResponsePlugin({ + statuses: [200], + }), + new ExpirationPlugin({ + maxEntries: 100, + maxAgeSeconds: 60 * 60 * 24 * 365, + }), + ], + }), +); + registerRoute( new RegExp('/conversation/.*'), new NetworkFirst({ diff --git a/assets/js/tempusdominus.js b/assets/js/tempusdominus.js index d740386192..b2257aaa62 100644 --- a/assets/js/tempusdominus.js +++ b/assets/js/tempusdominus.js @@ -1,20 +1,15 @@ -global.moment = require('moment'); +import moment from 'moment'; +import 'tempusdominus-bootstrap'; -require('tempusdominus-bootstrap'); - -$.fn.datetimepicker.Constructor.Default = $.extend({}, $.fn.datetimepicker.Constructor.Default, { - locale: document.getElementsByTagName('html')[0].getAttribute('lang'), -// allowInputToggle: true, - icons: { - time: 'fas fa-clock', - date: 'fas fa-calendar', - up: 'fas fa-arrow-up', - down: 'fas fa-arrow-down', - previous: 'fas fa-chevron-left', - next: 'fas fa-chevron-right', - today: 'fas fa-calendar-check-o', - clear: 'fas fa-trash', - close: 'fas fa-times' - } -}); +global.moment = moment; +// Assuming tempusdominus relies on jQuery internally. +// If tempusdominus is tightly coupled to jQuery (e.g. $.fn.datetimepicker), +// and the goal is to remove jQuery completely, a modern alternative like flatpickr +// or vanilla-calendar-pro (which is in package.json) should be used instead. +// For the scope of this file rewrite, if we MUST keep tempusdominus for now, +// it still requires jQuery. If we are completely removing jQuery, this whole +// script needs to be replaced with a different library's initialization. +// Since 'vanilla-calendar-pro' is in package.json, let's assume we want to use that +// or native date inputs eventually. For now, we leave a warning. +console.warn('tempusdominus-bootstrap requires jQuery. Consider replacing with vanilla-calendar-pro or native inputs.'); diff --git a/assets/js/tom-select.js b/assets/js/tom-select.js index ed4d7f1a6e..d49cab1115 100644 --- a/assets/js/tom-select.js +++ b/assets/js/tom-select.js @@ -1,52 +1,68 @@ import TomSelect from 'tom-select'; import 'tom-select/dist/esm/plugins/remove_button/plugin'; -import '../scss/tom-select/tom-select.scss'; +import 'tom-select/dist/css/tom-select.bootstrap5.min.css'; -document - .querySelectorAll('.js-tom-select') - .forEach((element) => { - const tomSelectOptions = element.dataset; +let tomSelects = []; - const autocompleteChoices = tomSelectOptions.autocompleteChoices !== undefined; - let settings = { - render: { - option_create: function (data, escape) { - return '
    ' + tomSelectOptions.createOptionText + ' ' + escape(data.input) + '…
    '; - }, - no_results: function (data, escape) { - return '
    ' + tomSelectOptions.noResultsText + '
    '; - }, - }, - } - if (tomSelectOptions.create !== undefined) { - settings.create = true; - } - if (tomSelectOptions.createOnBlur !== undefined) { - settings.createOnBlur = true; - } - if (tomSelectOptions.closeAfterSelect !== undefined) { - settings.closeAfterSelect = true; - } - if (tomSelectOptions.maxItems !== undefined) { - settings.maxItems = tomSelectOptions.maxItems; - } - if (tomSelectOptions.maxOptions !== undefined) { - settings.maxOptions = tomSelectOptions.maxOptions; - } - if (tomSelectOptions.preload !== undefined) { - settings.preload = tomSelectOptions.preload; - } - if (tomSelectOptions.plugins !== undefined) { - settings.plugins = tomSelectOptions.plugins.split(","); - settings.sortField = { field: 'text' }; - } - if (autocompleteChoices) { - settings.valueField = 'title'; - settings.labelField = 'title'; - settings.searchField = 'title'; - settings.options = JSON.parse(tomSelectOptions.autocompleteChoices); - } +export function initializeTomSelects(cssClass = ".js-tom-select") { + document + .querySelectorAll(cssClass) + .forEach((element) => { + try { + const tomSelectOptions = element.dataset; - new TomSelect(element, settings); + const autocompleteChoices = tomSelectOptions.autocompleteChoices !== undefined; + let settings = { + render: { + option_create: function (data, escape) { + return '
    ' + tomSelectOptions.createOptionText + ' ' + escape(data.input) + '…
    '; + }, + no_results: function (data, escape) { + return '
    ' + tomSelectOptions.noResultsText + '
    '; + }, + }, + } + if (tomSelectOptions.create !== undefined) { + settings.create = true; + } + if (tomSelectOptions.createOnBlur !== undefined) { + settings.createOnBlur = true; + } + if (tomSelectOptions.closeAfterSelect !== undefined) { + settings.closeAfterSelect = true; + } + if (tomSelectOptions.maxItems !== undefined) { + settings.maxItems = tomSelectOptions.maxItems; + } + if (tomSelectOptions.maxOptions !== undefined) { + settings.maxOptions = tomSelectOptions.maxOptions; + } + if (tomSelectOptions.preload !== undefined) { + settings.preload = tomSelectOptions.preload; + } + if (tomSelectOptions.plugins !== undefined) { + settings.plugins = tomSelectOptions.plugins.split(","); + } + if (autocompleteChoices) { + settings.valueField = 'title'; + settings.labelField = 'title'; + settings.searchField = 'title'; + settings.options = JSON.parse(tomSelectOptions.autocompleteChoices); + } + settings.maxOptions = null; + settings.sortField = [{field:'$order'},{field:'$score'}]; + tomSelects.push(new TomSelect(element, settings)); + } catch(e) { } + + }) + ; +} + +export function destroyTomSelects(cssClass = "js-tom-select") { + tomSelects.forEach( (tomSelect) => { + tomSelect.sync() + tomSelect.destroy() }) -; +} + +initializeTomSelects(); diff --git a/assets/js/translator.js b/assets/js/translator.js new file mode 100644 index 0000000000..4e9943f084 --- /dev/null +++ b/assets/js/translator.js @@ -0,0 +1,18 @@ +import { createTranslator } from '@symfony/ux-translator'; +import { messages, localeFallbacks } from '../../var/translations'; + +/* + * This file is part of the Symfony UX Translator package. + * + * If folder "../var/translations" does not exist, or some translations are missing, + * you must warmup your Symfony cache to refresh JavaScript translations. + * + * If you use TypeScript, you can rename this file to "translator.ts" to take advantage of types checking. + */ + +const translator = createTranslator({ + messages, + localeFallbacks, +}); + +export const { trans } = translator; diff --git a/assets/js/treasurer.js b/assets/js/treasurer.js index cbf70c33e9..e69de29bb2 100644 --- a/assets/js/treasurer.js +++ b/assets/js/treasurer.js @@ -1,10 +0,0 @@ -require('./tempusdominus.js'); - -$(function () { - let donationDate = $('#donate-date'); - donationDate.datetimepicker({ - locale: 'en', - keepInvalid: true, - format: 'DD-MM-YYYY' - }); -}); diff --git a/assets/js/trips.js b/assets/js/trips.js index 7345029e3e..31e299de42 100644 --- a/assets/js/trips.js +++ b/assets/js/trips.js @@ -65,137 +65,144 @@ function initializePicker(value) { } } -$(document).on('click', '.js-btn-add[data-target]', function (event) { - let collectionHolder = $('#' + $(this).attr('data-target')); +document.addEventListener('click', function(event) { + const addBtn = event.target.closest('.js-btn-add[data-target]'); + if (addBtn) { + event.preventDefault(); - if (!collectionHolder.attr('data-counter')) { - collectionHolder.attr('data-counter', collectionHolder.children().length); - } + const targetId = addBtn.getAttribute('data-target'); + let collectionHolder = document.getElementById(targetId); - let prototype = collectionHolder.attr('data-prototype'); - let form = prototype.replace(/__name__/g, collectionHolder.attr('data-counter')); + if (!collectionHolder.hasAttribute('data-counter')) { + collectionHolder.setAttribute('data-counter', collectionHolder.children.length); + } - let counter = Number(collectionHolder.attr('data-counter')); + let prototype = collectionHolder.getAttribute('data-prototype'); + let formHTML = prototype.replace(/__name__/g, collectionHolder.getAttribute('data-counter')); - collectionHolder.attr('data-counter', counter + 1); - collectionHolder.append(form); + let counter = Number(collectionHolder.getAttribute('data-counter')); - /* enable a search picker on all location fields (including the newly added one */ - initializeMultipleAutoCompletes( "/suggest/locations/places", 'js-location-picker', onChange); + collectionHolder.setAttribute('data-counter', counter + 1); + collectionHolder.insertAdjacentHTML('beforeend', formHTML); - const duration = document.getElementById('trip_subtrips_' + counter + '_duration'); - if (lastEndDateSet != null) { - const arrival = document.getElementById('trip_subtrips_' + counter + '_arrival'); - arrival.value = lastEndDateSet; - const nextDay = dayjs(lastEndDateSet).add(1, 'day'); - const departure = document.getElementById('trip_subtrips_' + counter + '_departure'); - departure.value = nextDay.format('YYYY-MM-DD'); - } + /* enable a search picker on all location fields (including the newly added one */ + initializeMultipleAutoCompletes("/suggest/locations/places", 'js-location-picker', onChange); - initializePicker(duration); + const duration = document.getElementById('trip_legs_' + counter + '_duration'); + if (lastEndDateSet != null) { + const arrival = document.getElementById('trip_legs_' + counter + '_arrival'); + arrival.value = lastEndDateSet; + const nextDay = dayjs(lastEndDateSet).add(1, 'day'); + const departure = document.getElementById('trip_legs_' + counter + '_departure'); + departure.value = nextDay.format('YYYY-MM-DD'); + } - event && event.preventDefault(); + initializePicker(duration); + } + + const removeBtn = event.target.closest('.js-btn-remove[data-related]'); + if (removeBtn) { + event.preventDefault(); + + const relatedName = removeBtn.getAttribute('data-related'); + const elementsToRemove = document.querySelectorAll('*[data-content="' + relatedName + '"]'); + elementsToRemove.forEach(el => el.remove()); + } }); -$(document).on('click', '.js-btn-remove[data-related]', function (event) { - let name = $(this).attr('data-related'); - $('*[data-content="' + name + '"]').remove(); +document.addEventListener('DOMContentLoaded', function () { + const mapElement = document.getElementById('map'); + if (mapElement) { + var map = L.map('map', { + center: [0, 0], + zoom: 0, + zoomSnap: 0.1, + fullscreenControl: true, + fullscreenControlOptions: { + position: 'topleft' + } + }); - event && event.preventDefault(); -}); + const dataElements = document.querySelectorAll('.js-data'); + let allData = Array.from(dataElements).map(el => el.value.split(',')); + let circlesArray = []; + let locationsArray = []; -$( function() { -if ($('#map').length) { + const tripIcon = L.icon({ + iconUrl: '../images/marker.png', + iconRetinaUrl: "../images/marker-2x.png", + iconSize: [25, 41], + iconAnchor: [12, 41], + popupAnchor: [1, -34], + }); - var map = L.map('map', { - center: [0, 0], - zoom: 0, - zoomSnap: 0.1, - fullscreenControl: true, - fullscreenControlOptions: { - position: 'topleft' - } - }); + for (let i = 0; i < allData.length; i++) { + let location = allData[i][0]; + let latitude = parseFloat(allData[i][1]); + let longitude = parseFloat(allData[i][2]); - let allData = $('.js-data').map((_, el) => [el.value.split(',')]).get() - let circlesArray = [] + locationsArray.push([latitude, longitude]); - let locationsArray = [] + let countryName = allData[i][3]; + let tripDate = allData[i][4]; - const tripIcon = L.icon({ - iconUrl: '../images/marker.png', - iconRetinaUrl: "../images/marker-2x.png", - iconSize: [25, 41], - iconAnchor: [12, 41], - popupAnchor: [1, -34], - }); - for (let i = 0; i < allData.length; i++) { + let marker = L.marker([latitude, longitude], { icon: tripIcon }).addTo(map); + marker.bindPopup("" + location + " (" + countryName + ")
    " + tripDate); - let location = allData[i][0] - let latitude = allData[i][1] - let longitude = allData[i][2] + let circle = L.circle([latitude, longitude], { + color: 'rgb(112,0,243)', + fillColor: 'rgba(112, 0, 243, 0.1)', + fillOpacity: 1, + radius: trip.radius + .1 + }).addTo(map); + circlesArray.push(circle); + } - locationsArray.push([latitude, longitude]); + // if not own trip add circle with search radius of current member + if (trip.own === false) { + const ownIcon = L.icon({ + iconUrl: '../images/trip_marker.png', + iconRetinaUrl: "../images/trip_marker-2x.png", + iconSize: [25, 41], + iconAnchor: [12, 41], + popupAnchor: [1, -34], + }); + const marker = L.marker([memberInfo.latitude, memberInfo.longitude], { icon: ownIcon }).addTo(map); + marker.bindPopup("Your location
    ...and search radius"); + + L.circle([memberInfo.latitude, memberInfo.longitude], { + color: 'rgb(0, 184, 85)', + fillColor: 'rgba(0, 184, 85, 0.1)', + fillOpacity: 1, + radius: memberInfo.searchRadius * 1000 + }).addTo(map); + } - let countryName = allData[i][3] - let tripDate = allData[i][4] + let group = new L.featureGroup(circlesArray); + if (circlesArray.length > 1) { + map.fitBounds(group.getBounds()); + } else if (allData.length > 0) { + map.setView([parseFloat(allData[0][1]), parseFloat(allData[0][2])], 12); + } - let marker = L.marker([latitude, longitude], { icon: tripIcon}).addTo(map); - marker.bindPopup("" + location + " (" + countryName + ")
    " + tripDate); + let journey = L.polyline(locationsArray).addTo(map); + var arrows = L.polylineDecorator(journey, { + patterns: [ + { offset: 25, repeat: 50, symbol: L.Symbol.arrowHead({ pixelSize: 15, pathOptions: { fillOpacity: 1, weight: 0 } }) } + ] + }).addTo(map); - let circle = null; - circle = L.circle([latitude, longitude], { - color: 'rgb(112,0,243)', - fillColor: 'rgba(112, 0, 243, 0.1)', - fillOpacity: 1, - radius: trip.radius +.1 + L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { + attribution: '© OpenStreetMap contributors', + subdomains: ['a', 'b', 'c'] }).addTo(map); - circlesArray.push(circle) - } - // if not own trip add circle with search radius of current member - if (trip.own === false) { - const ownIcon = L.icon({ - iconUrl: '../images/trip_marker.png', - iconRetinaUrl: "../images/trip_marker-2x.png", - iconSize: [25, 41], - iconAnchor: [12, 41], - popupAnchor: [1, -34], + // detect fullscreen toggling + map.on('enterFullscreen', function () { + map.fitBounds(group.getBounds()); + }); + map.on('exitFullscreen', function () { + map.fitBounds(group.getBounds()); }); - const marker = L.marker([memberInfo.latitude, memberInfo.longitude], { icon: ownIcon}).addTo(map); - marker.bindPopup("Your location
    ...and search radius"); - - L.circle([memberInfo.latitude, memberInfo.longitude], { - color: 'rgb(0, 184, 85)', - fillColor: 'rgba(0, 184, 85, 0.1)', - fillOpacity: 1, - radius: memberInfo.searchRadius * 1000 - }).addTo(map); - } - let group = new L.featureGroup(circlesArray); - if (circlesArray.length > 1) { - map.fitBounds(group.getBounds()); - } else { - map.setView([allData[0][1], allData[0][2]], 12) } - - let journey = L.polyline(locationsArray).addTo(map); - var arrows = L.polylineDecorator(journey, { - patterns: [ - {offset: 25, repeat: 50, symbol: L.Symbol.arrowHead({pixelSize: 15, pathOptions: {fillOpacity: 1, weight: 0}})} - ] - }).addTo(map); - - L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { - attribution: '© OpenStreetMap contributors', - subdomains: ['a', 'b', 'c'] - }).addTo(map); - - // detect fullscreen toggling - map.on('enterFullscreen', function(){ - map.fitBounds(group.getBounds()); - }); - map.on('exitFullscreen', function(){ - map.fitBounds(group.getBounds()); - }); -}}); +}); diff --git a/assets/js/updateCounters.js b/assets/js/updateCounters.js index f2806a1fcb..ac7d8fdb18 100644 --- a/assets/js/updateCounters.js +++ b/assets/js/updateCounters.js @@ -1,16 +1,202 @@ +import {initBrowserPushSession} from './browserPushPreference'; + +const browserNotificationLastIdKeyPrefix = 'bewelcomeBrowserNotificationLastId:'; +const browserNotificationDefaultInterval = 600000; +const browserNotificationOpenOnlyInterval = 120000; +const browserNotificationMemoryLastIds = {}; +let browserNotificationIntervalId = null; +let browserNotificationCurrentInterval = browserNotificationDefaultInterval; + function updateCount() { - $.ajax({ - type: 'POST', - url: '/count/conversations/unread', - dataType: 'json', - success: function (data) { - $('#conversationCount').replaceWith(data.html); - if (typeof autocollapse_menu === "function") { - autocollapse_menu(true); + const memberId = getBrowserNotificationMemberId(); + const browserNotificationLastId = getBrowserNotificationLastId(memberId); + const browserNotificationQuery = browserNotificationLastId === null + ? '' + : '?browserNotificationSince=' + encodeURIComponent(browserNotificationLastId); + fetch('/count/conversations/unread' + browserNotificationQuery, { + method: 'POST', + headers: { + 'X-Requested-With': 'XMLHttpRequest', + 'Accept': 'application/json' + } + }) + .then(response => { + if (!response.ok) { + throw new Error('Network response was not ok'); + } + return response.json(); + }) + .then(async data => { + const conversationCount = document.getElementById('conversationCount'); + if (conversationCount && data && data.html !== undefined) { + conversationCount.outerHTML = data.html; + if (typeof window.autocollapse_menu === "function") { + window.autocollapse_menu(true); } - }}); + } + await showBrowserNotifications(data); + updateBrowserNotificationInterval(data && data.browserNotification ? browserNotificationOpenOnlyInterval : browserNotificationDefaultInterval); + }) + .catch(error => { + console.error('Error fetching unread count:', error); + }); +} + +async function showBrowserNotifications(data) { + if (!data || !data.browserNotification) { + return; + } + + const latestId = data.browserNotification.latestId || 0; + const memberId = data.browserNotification.memberId || getBrowserNotificationMemberId(); + const previousLastId = getBrowserNotificationLastId(memberId); + if (previousLastId === null) { + setBrowserNotificationLastId(memberId, latestId); + return; + } + + if (!('Notification' in window) || Notification.permission !== 'granted') { + setBrowserNotificationLastId(memberId, latestId); + return; + } + + let displayedThroughId = previousLastId; + for (const notification of data.browserNotification.notifications) { + if (notification.id <= previousLastId) { + continue; + } + try { + await showBrowserNotification(notification); + displayedThroughId = notification.id; + } catch (error) { + break; + } + } + + setBrowserNotificationLastId(memberId, displayedThroughId); +} + +async function showBrowserNotification(notification) { + const options = { + body: notification.body, + tag: 'bewelcome-open-' + notification.id, + data: {url: notification.url}, + icon: '/images/icon-192x192.png', + badge: '/images/icon-96x96.png', + }; + if ('serviceWorker' in navigator) { + const registration = await withTimeout(navigator.serviceWorker.ready, 5000); + if (registration && 'function' === typeof registration.showNotification) { + await registration.showNotification(notification.title, options); + return; + } + } + + const browserNotification = new Notification(notification.title, options); + browserNotification.onclick = function () { + const url = new URL(notification.url, window.location.origin); + if (url.origin === window.location.origin) { + window.focus(); + window.location.href = url.href; + } + }; +} + +function getBrowserNotificationMemberId() { + const conversationCount = document.getElementById('conversationCount'); + + return conversationCount ? conversationCount.dataset.memberId || '' : ''; +} + +function getBrowserNotificationLastId(memberId) { + if (!memberId) { + return null; + } + + const value = getBrowserNotificationStoredValue(browserNotificationLastIdKeyPrefix + memberId); + if (value === null) { + return null; + } + + const lastId = Number(value); + return Number.isFinite(lastId) ? lastId : 0; } -let interval = setInterval(function () { updateCount(); }, 60000 * 1000); +function setBrowserNotificationLastId(memberId, lastId) { + if (!memberId) { + return; + } -updateCount(); + setBrowserNotificationStoredValue(browserNotificationLastIdKeyPrefix + memberId, lastId); +} + +function getBrowserNotificationStoredValue(key) { + try { + return window.sessionStorage.getItem(key) ?? browserNotificationMemoryLastIds[key] ?? null; + } catch (error) { + return browserNotificationMemoryLastIds[key] ?? null; + } +} + +function setBrowserNotificationStoredValue(key, value) { + browserNotificationMemoryLastIds[key] = String(value); + try { + window.sessionStorage.setItem(key, value); + } catch (error) { + // Storage can be blocked; the in-memory marker still prevents duplicates in this tab. + } +} + +function clearBrowserNotificationLastId(memberId) { + if (!memberId) { + return; + } + + const key = browserNotificationLastIdKeyPrefix + memberId; + delete browserNotificationMemoryLastIds[key]; + try { + window.sessionStorage.removeItem(key); + } catch (error) { + // The next request still initializes from the in-memory marker. + } +} + +function updateBrowserNotificationInterval(interval) { + if (interval === browserNotificationCurrentInterval && browserNotificationIntervalId) { + return; + } + + window.clearInterval(browserNotificationIntervalId); + browserNotificationCurrentInterval = interval; + browserNotificationIntervalId = window.setInterval(function () { updateCount(); }, interval); +} + +function withTimeout(promise, timeoutMs) { + return Promise.race([ + promise, + new Promise((resolve) => { + window.setTimeout(() => resolve(null), timeoutMs); + }), + ]); +} + +window.addEventListener('browser-push-preference-changed', (event) => { + const memberId = getBrowserNotificationMemberId(); + clearBrowserNotificationLastId(memberId); + const interval = event.detail && event.detail.value === 'OpenOnly' + ? browserNotificationOpenOnlyInterval + : browserNotificationDefaultInterval; + updateBrowserNotificationInterval(interval); + updateCount(); +}); + +window.addEventListener('browser-push-session-ending', (event) => { + clearBrowserNotificationLastId(event.detail && event.detail.memberId); +}); + +initBrowserPushSession(); + +if (getBrowserNotificationMemberId()) { + updateBrowserNotificationInterval(browserNotificationDefaultInterval); + updateCount(); +} diff --git a/assets/public/js/confighelper/plugin.js b/assets/public/js/confighelper/plugin.js index c12d664a3d..a4619c0d67 100644 --- a/assets/public/js/confighelper/plugin.js +++ b/assets/public/js/confighelper/plugin.js @@ -1,6 +1,6 @@ /** * @file Configuration helper plugin for CKEditor - * Copyright (C) 2012 Alfonso Martnez de Lizarrondo + * Copyright (C) 2012 Alfonso Mart�nez de Lizarrondo * */ (function() { diff --git a/assets/public/js/search/createmap.js b/assets/public/js/search/createmap.js index e13881c447..fbbd5c6c9b 100644 --- a/assets/public/js/search/createmap.js +++ b/assets/public/js/search/createmap.js @@ -132,22 +132,8 @@ function addMarkers(map) { $.each(mapMembers, function (index, value) { var iconFile; - switch (value.Accommodation) { - case 'anytime': - iconFile = 'anytime'; - break; - - case 'dependonrequest': - iconFile = 'dependonrequest'; - break; - - case 'dontask': - iconFile = 'neverask'; - break; - } - var icon = new L.DivIcon({ - html: '
    ', + html: '
    ', className: '', iconSize: new L.Point(17, 17) }); diff --git a/assets/scss/_custom.scss b/assets/scss/_custom.scss index b8ceb2c931..3ef1e9c665 100644 --- a/assets/scss/_custom.scss +++ b/assets/scss/_custom.scss @@ -2,12 +2,19 @@ $enable-responsive-font-sizes: true; $brand-primary: #f37000; $primary: $brand-primary; $info: #0083f3; +$topbar-unread-badge-bg: #3781eb; -$link-color: #4c6c9b; // Use original bootstrap primary for links instead of BW orange -$link-hover-decoration: none; +// BeWelcome accent used in the landing page cards +$bw-blue-dark: #153B74; + +$link-color: #1f4f9a; +$link-decoration: none !important; +$link-hover-decoration: none !important; $grid-gutter-width: 1.875rem; // 30px -$font-family-sans-serif: 'Lato', 'Lato Light'; +$font-family-sans-serif: 'Noto Sans'; +$font-family-bold: 'Signika'; + $line-height: 1.5; $headings-font-family: "Signika"; @@ -20,6 +27,13 @@ $input-btn-padding-x-sm: .75rem; $input-btn-padding-x-lg: 1.25rem; $btn-block-spacing-y: 5px; $btn-toolbar-margin: 5px; +$color-contrast-dark: #000; +$color-contrast-light: #fff; +$min-contrast-ratio: 2.1; + +$btn-color: #fff; +$btn-font-weight: 400; + $input-padding-x: .375rem; $input-padding-y: .375rem; $input-border-color: #ccc; @@ -27,7 +41,7 @@ $input-padding-x-sm: .75rem; $input-padding-y-sm: .275rem; $input-padding-x-lg: 1.25rem; -$dropdown-bg: transparentize(#000, 0.2); +$dropdown-bg: rgba(0, 0, 0, 0.8); $dropdown-border-color: rgba(255,255,255,.15); $dropdown-link-color: #fff; diff --git a/assets/scss/_footer.scss b/assets/scss/_footer.scss index d2d371ca9e..9257bd13db 100644 --- a/assets/scss/_footer.scss +++ b/assets/scss/_footer.scss @@ -6,30 +6,68 @@ footer { order: 2; } + $stickyfooter-bg: #35353a; + $stickyfooter-main-padding-top: 3.25rem; + $stickyfooter-main-padding-bottom: 2.75rem; + /* Darker strip: copyright + language */ + $footer-legal-band-bg: #2a2a2f; + $footer-legal-band-padding-y: 1rem; + /* Four footer columns + bottom band: narrower block, more centered on wide viewports */ + $footer-columns-max-width: 1080px; + .stickyfooter { + display: flex; + flex-direction: column; height: auto; font-size: $font-size-sm; - line-height: 1.1; + line-height: 1.45; width: 100%; - margin-top: 1rem; - padding: $spacer $spacer; - background-color: #555; - color: #999; + max-width: 100%; + margin-top: 0; + padding: 0; + color: #b0b0b5; a { - color: #aaa; - white-space: nowrap; + color: #c8c8c8; + white-space: normal; &:hover { color: #fff; + text-decoration: none; } &:focus { color: #fff; } } - & > .container { - padding: 1rem $spacer; + .stickyfooter__main { + flex: 0 1 auto; + width: 100%; + padding-top: $stickyfooter-main-padding-top; + padding-right: $spacer; + padding-bottom: $stickyfooter-main-padding-bottom; + padding-left: $spacer; + font-size: 1rem; + line-height: 1.5; + background-color: $stickyfooter-bg; + background-image: linear-gradient(180deg, rgba(255, 255, 255, 0.04) 0%, transparent 0.75rem); + } + + .stickyfooter-container { + width: 100%; + max-width: $footer-columns-max-width; + margin-right: auto; + margin-left: auto; + } + + .stickyfooter__main > .stickyfooter-container { + padding-top: 0; + padding-bottom: 0; + } + + .footer-bottom-band > .stickyfooter-container { + padding-right: $spacer; + padding-left: $spacer; } .footnav:before{ @@ -37,6 +75,347 @@ footer { margin-left: 0.3rem; } + .stickyfooter__heading { + display: flex; + align-items: center; + gap: 0.45rem; + margin: 0 0 0.6rem; + font-size: 0.875rem; + font-weight: 700; + letter-spacing: 0.045em; + text-transform: uppercase; + color: #fff; + text-shadow: 0 1px 2px rgba(0, 0, 0, 0.35); + + .stickyfooter__heading-icon { + flex-shrink: 0; + font-size: 1.1rem; + opacity: 1; + color: #fff; + filter: drop-shadow(0 1px 1px rgba(0, 0, 0, 0.35)); + } + + .stickyfooter__heading-link { + display: flex; + align-items: center; + gap: inherit; + color: inherit; + text-decoration: none; + + &:hover, + &:focus { + color: #fff; + + .stickyfooter__heading-icon { + color: #fff; + } + } + } + } + + .stickyfooter__heading--stacked { + margin-top: 1.15rem; + } + + .footer-bottom-band { + flex: 0 0 auto; + width: 100%; + max-width: 100%; + margin: 0; + padding-top: $footer-legal-band-padding-y; + padding-bottom: $footer-legal-band-padding-y; + background-color: $footer-legal-band-bg; + background-image: none; + border: none; + border-radius: 0; + box-shadow: none; + border-top: 1px solid rgba(255, 255, 255, 0.06); + + .footer-bottom-band__row { + min-height: 0; + } + + .footer-bottom-band__legal { + display: flex; + align-items: center; + + @media (max-width: 767.98px) { + margin-bottom: 1rem; + } + } + + .footer-bottom-band__lang { + display: flex; + align-items: center; + + .footer-bottom-band__lang-form { + width: 100%; + } + + @media (max-width: 767.98px) { + padding-top: $footer-legal-band-padding-y; + border-top: 1px solid rgba(255, 255, 255, 0.08); + + .footer-bottom-band__lang-form .form-row { + justify-content: flex-start; + } + + .footer-bottom-band__lang-select-wrap { + flex: 0 0 auto; + width: auto; + max-width: 100%; + } + } + + @media (min-width: 768px) { + text-align: right; + + .form-row { + justify-content: flex-end; + flex-wrap: nowrap; + } + + .footer-bottom-band__lang-form .col-md-auto { + text-align: left; + } + + /* Keep label + select adjacent; avoid a stretched middle column */ + .footer-bottom-band__lang-form .form-row > .col-md-auto:first-of-type { + padding-right: 0.25rem; + } + + .footer-bottom-band__lang-select-wrap.col-md-auto { + flex: 0 0 auto; + padding-left: 0.25rem; + } + } + + .col-form-label { + color: rgba(255, 255, 255, 0.88); + font-size: 0.875rem; + } + + .footer-bottom-band__lang-label { + @media (max-width: 767.98px) { + margin-bottom: 0.35rem; + } + } + } + + .footer-bottom-band__meta { + display: block; + width: 100%; + margin-top: 0; + margin-left: 0; + margin-right: 0; + padding-top: 0; + max-width: none; + text-align: left; + border-top: none; + } + + .footer-site-language + .select2-container--bootstrap4 { + flex: 0 1 auto; + min-width: 0; + width: 100% !important; + max-width: 100%; + + @media (max-width: 767.98px) { + width: auto !important; + max-width: min(100%, 20rem); + } + + @media (min-width: 768px) { + max-width: 16rem; + } + + .select2-selection--single { + display: flex; + align-items: center; + min-height: 1.85rem; + height: auto; + padding: 0.2rem 1.75rem 0.2rem 0.35rem; + font-size: 0.8125rem; + line-height: 1.25; + } + + .select2-selection__rendered { + display: block; + padding: 0 0.25rem 0 0; + line-height: 1.3; + } + + .select2-selection__arrow { + top: 50%; + bottom: auto; + height: 1.25rem; + margin-top: 0; + transform: translateY(-50%); + right: 0.35rem; + } + } + } + + .stickyfooter__columns > [class*='col-'] { + display: flex; + flex-direction: column; + align-items: stretch; + } + + .stickyfooter__link-list li { + margin-bottom: 0.35rem; + + &:last-child { + margin-bottom: 0; + } + } + + .stickyfooter__link-list--legal { + font-size: 1em; + } + + .footer-help-translate { + align-self: flex-start; + width: fit-content; + max-width: 100%; + display: inline-flex; + align-items: center; + gap: 0.45rem; + padding: 0.4rem 0.75rem; + font-size: 0.8125rem; + font-weight: 500; + line-height: 1.35; + color: #c9c9ce; + text-decoration: none; + cursor: pointer; + background: rgba(255, 255, 255, 0.05); + border: 1px solid rgba(255, 255, 255, 0.12); + border-radius: 0.3rem; + box-shadow: none; + transition: + background 0.15s ease, + border-color 0.15s ease, + color 0.15s ease; + + .footer-help-translate__icon { + display: inline-flex; + flex-shrink: 0; + align-items: center; + font-size: 0.95rem; + line-height: 1; + color: #8aa4c0; + opacity: 0.9; + } + + .footer-help-translate__text { + white-space: normal; + } + + &:hover, + &:focus { + color: #f0f0f2; + text-decoration: none; + background: rgba(255, 255, 255, 0.09); + border-color: rgba(255, 255, 255, 0.2); + } + + &:focus-visible { + outline: 2px solid rgba(130, 180, 255, 0.45); + outline-offset: 2px; + } + + &--embed { + width: max-content; + max-width: 100%; + cursor: default; + flex-wrap: wrap; + align-items: center; + row-gap: 0.35rem; + + select.footer-help-translate__control { + width: auto !important; + max-width: 100%; + } + + .footer-help-translate__text { + flex: 0 0 auto; + min-width: 0; + line-height: 1.35; + } + + .footer-help-translate__control + .select2-container--bootstrap4 { + flex: 0 0 auto; + width: auto !important; + min-width: 0; + margin-top: 0; + + .select2-selection--single { + display: flex; + align-items: center; + min-height: 0; + height: auto; + padding: 0; + background: transparent !important; + border: none !important; + box-shadow: none !important; + } + + &.select2-container--focus:not(.select2-container--open) .select2-selection--single, + &.select2-container--open .select2-selection--single { + border: none !important; + box-shadow: none !important; + } + + .select2-selection__rendered { + padding-right: 1.125rem; + padding-left: 0.15rem; + line-height: 1.35; + font-weight: 500; + color: #8aa4c0; + } + + .select2-selection__arrow { + top: 50%; + right: 0; + width: 0.65rem; + height: 1rem; + margin-top: 0; + transform: translateY(-50%); + } + + .select2-selection__arrow b { + border-color: #8aa4c0 transparent transparent transparent; + } + } + + &:hover .footer-help-translate__control + .select2-container--bootstrap4 .select2-selection__rendered { + color: #f0f0f2; + } + + &:hover .footer-help-translate__control + .select2-container--bootstrap4 .select2-selection__arrow b { + border-color: #f0f0f2 transparent transparent transparent; + } + } + } + + .footer-bottom-band__meta { + font-size: 0.85em; + line-height: 1.45; + color: #8f8f95; + + a { + color: #bababf; + + &:hover, + &:focus { + color: #fff; + } + } + } + + .font-weight-semibold { + font-weight: 600; + } } } @@ -46,4 +425,12 @@ footer { order: 1; margin-top: 1em; +} + +/* Translation mode (footer admin): Select2 dropdown is attached to body — compact option rows */ +#select2-footer_embed_select-results { + .select2-results__option { + padding: 0.2rem 0.5rem; + line-height: 1.25; + } } \ No newline at end of file diff --git a/assets/scss/_forums.scss b/assets/scss/_forums.scss index 69bce3408e..5005e25a46 100644 --- a/assets/scss/_forums.scss +++ b/assets/scss/_forums.scss @@ -98,6 +98,7 @@ .l-forum-single-post img, .l-search-post img { max-width: 100%; + height: auto; } .c-single-post-post_info, diff --git a/assets/scss/_general.scss b/assets/scss/_general.scss index e41298934b..79de87650c 100644 --- a/assets/scss/_general.scss +++ b/assets/scss/_general.scss @@ -1,3 +1,5 @@ +@use "sass:math"; + /* Sticky footer styles -------------------------------------------------- */ html { @@ -44,9 +46,17 @@ main { } .ui-autocomplete-loading { + margin-right: 8px; background: white url("../images/ui-anim_basic_16x16.gif") right center no-repeat; } +.ui-autocomplete { + max-height: 200px; + overflow-y: auto; + /* prevent horizontal scrollbar */ + overflow-x: hidden; +} + .button { display: inline-block; font-weight: $btn-font-weight; @@ -57,7 +67,7 @@ main { user-select: none; border: $input-btn-border-width solid transparent; margin-right: 1rem; - @include button-size($input-btn-padding-y, $input-btn-padding-x, $font-size-base, $line-height-base, $btn-border-radius); + @include button-size($input-btn-padding-y, $input-btn-padding-x, $font-size-base, $btn-border-radius); @include transition(all .2s ease-in-out); &.focus { @@ -247,7 +257,7 @@ a { cursor: pointer; } -input.noradio{ +input.noradio { display:none; } diff --git a/assets/scss/_home-landing.scss b/assets/scss/_home-landing.scss new file mode 100644 index 0000000000..20feea2ac5 --- /dev/null +++ b/assets/scss/_home-landing.scss @@ -0,0 +1,1118 @@ +.home-landing { + .home-hero, + .home-strip { + position: relative; + overflow: hidden; + color: #fff; + } + + .home-hero__media, + .home-strip__media { + position: absolute; + inset: 0; + z-index: 0; + } + + .home-hero__img, + .home-hero__video, + .home-strip__img { + width: 100%; + height: 100%; + object-fit: cover; + } + + .home-hero__video { + display: block; + position: absolute; + inset: 0; + object-position: center; + } + + .home-hero::after, + .home-strip::after { + content: ''; + position: absolute; + inset: 0; + z-index: 1; + background: rgba(0, 0, 0, 0.38); + } + + .home-hero::after { + background: linear-gradient( + to bottom, + rgba(0, 0, 0, 0.58) 0%, + rgba(0, 0, 0, 0.44) 45%, + rgba(0, 0, 0, 0.5) 100% + ); + } + + .home-hero__body, + .home-strip__body { + position: relative; + z-index: 2; + } + + .home-hero { + min-height: calc(100vh - var(--bw-topbar-offset, 64px)); + min-height: calc(100dvh - var(--bw-topbar-offset, 64px)); + display: flex; + align-items: center; + } + + .home-hero__body { + width: 100%; + padding-top: 2.75rem; + padding-bottom: 3rem; + } + + .home-hero__container { + max-width: 1140px; + } + + .home-hero__copy { + text-shadow: none; + } + + .home-hero__row { + row-gap: 1.5rem; + + @include media-breakpoint-up(md) { + row-gap: 1.75rem; + } + + @include media-breakpoint-up(xl) { + row-gap: 2.5rem; + } + } + + .home-heading { + display: inline-flex; + flex-direction: column; + align-items: center; + font-size: clamp(1.85rem, 4.2vw, 3.15rem); + font-weight: 700; + line-height: 1.15; + letter-spacing: 0.02em; + font-family: Signika, sans-serif; + margin-bottom: 0.875rem; + + @include media-breakpoint-up(lg) { + align-items: flex-start; + margin-bottom: 1rem; + } + } + + .home-heading__brand { + display: inline-flex; + align-items: center; + gap: 0.55rem; + margin-bottom: 0.55rem; + } + + .home-heading__logo-full { + width: clamp(13.6rem, 34vw, 20.5rem); + height: auto; + flex: 0 0 auto; + } + + .home-heading__subtitle { + display: block; + font-size: 1.9rem; + font-weight: 700; + line-height: 1.15; + letter-spacing: 0.04em; + text-transform: uppercase; + text-wrap: balance; + } + + .home-hero__abstract { + font-size: clamp(1.05rem, 2vw, 1.2rem); + line-height: 1.5; + font-weight: 500; + opacity: 0.96; + margin-bottom: 0.45rem; + + @include media-breakpoint-up(md) { + margin-bottom: 0.55rem; + } + } + + .home-hero__lead { + font-size: clamp(1rem, 1.85vw, 1.125rem); + line-height: 1.6; + font-weight: 300; + opacity: 0.92; + max-width: 38rem; + margin-left: auto; + margin-right: auto; + margin-bottom: 1.5rem; + + @include media-breakpoint-up(lg) { + margin-left: 0; + margin-bottom: 2.25rem; + } + + @include media-breakpoint-up(xl) { + margin-bottom: 2.75rem; + } + } + + .home-hero__link { + color: #ffb366; + font-weight: 600; + text-decoration: underline; + text-underline-offset: 0.15em; + + &:hover, + &:focus { + color: #ffd4a8; + } + } + + .home-hero__cta { + display: inline-flex; + align-items: center; + justify-content: center; + padding: 0.85rem 1.75rem; + font-size: 1.05rem; + font-weight: 700; + letter-spacing: 0.02em; + border-radius: 999px; + border: none; + color: #fff; + background: linear-gradient(135deg, #ff9a2e 0%, #f37000 60%, #e06000 100%); + box-shadow: none; + transition: filter 0.15s ease; + + &:hover, + &:focus { + color: #fff; + filter: brightness(1.07); + } + } + + /* ── Mobile: hero copy full-viewport, aside becomes bottom sheet ── */ + @include media-breakpoint-down(lg) { + .home-hero { + min-height: calc(100vh - var(--bw-topbar-offset, 64px)); + min-height: calc(100dvh - var(--bw-topbar-offset, 64px)); + align-items: center; + } + + .home-hero__body { + padding-top: 1.5rem; + padding-bottom: 2rem; + } + + .home-hero__copy { + margin-bottom: 0 !important; + transform: none; + max-width: min(92vw, 30rem); + margin-left: auto; + margin-right: auto; + } + + .home-heading { + align-items: center; + font-size: clamp(1.55rem, 6vw, 2rem); + line-height: 1.16; + letter-spacing: 0.01em; + margin-bottom: 0.65rem; + } + + .home-heading__brand { + gap: 0.4rem; + margin-bottom: 0.4rem; + } + + .home-heading__logo-mark { + width: clamp(1.85rem, 9vw, 2.3rem); + } + + .home-heading__logo-text { + width: clamp(9.2rem, 46vw, 12.8rem); + transform: translateY(0.06rem); + } + + .home-heading__subtitle { + max-width: none; + font-size: clamp(1.08rem, 5.2vw, 1.4rem); + line-height: 1.18; + letter-spacing: 0.02em; + } + + .home-hero__abstract { + font-size: 1.06rem; + line-height: 1.48; + max-width: 34ch; + margin-left: auto; + margin-right: auto; + margin-bottom: 0.3rem; + } + + .home-hero__lead { + font-size: 1rem; + line-height: 1.52; + max-width: 36ch; + margin-left: auto; + margin-right: auto; + margin-bottom: 1.05rem; + } + + /* Actions row: join and login side by side */ + .home-hero__actions { + display: flex; + flex-wrap: wrap; + gap: 0.6rem; + justify-content: center; + } + + .home-hero__cta { + width: auto; + min-height: 2.75rem; + padding: 0.7rem 1.4rem; + font-size: 0.95rem; + } + + /* Login trigger: ghost pill */ + .home-hero__login-btn { + min-height: 2.75rem; + padding: 0.7rem 1.4rem; + font-size: 0.95rem; + font-weight: 600; + border-radius: 999px; + color: #fff; + border: 1.5px solid rgba(255, 255, 255, 0.65); + background: rgba(255, 255, 255, 0.22); + letter-spacing: 0.01em; + gap: 0.45rem; + box-shadow: none; + transition: + background-color 0.18s ease, + border-color 0.18s ease; + + &:hover, + &:focus { + color: #fff; + background: rgba(255, 255, 255, 0.32); + border-color: rgba(255, 255, 255, 0.85); + } + } + + /* Aside: taken out of flex flow and positioned as bottom sheet */ + .home-hero__aside { + position: fixed !important; + bottom: 0; + left: 0; + right: 0; + width: 100% !important; + max-width: 100% !important; + padding: 0 !important; + margin: 0 !important; + flex: none !important; + display: flex; + align-items: flex-end; + max-height: calc(100dvh - var(--bw-topbar-offset, 64px)); + /* Above topbar and cookie banner */ + z-index: 12010; + transform: translateY(calc(100% + 2px)); + transition: transform 0.38s cubic-bezier(0.32, 0.72, 0, 1); + /* Visibility is more reliable than pointer-events on Android */ + visibility: hidden; + + &.is-open { + transform: translateY(0); + visibility: visible; + } + + @include media-breakpoint-up(sm) { + left: 50%; + right: auto; + width: calc(100% - 2rem) !important; + max-width: 38rem !important; + transform: translate(-50%, calc(100% + 2px)); + + &.is-open { + transform: translate(-50%, 0); + } + } + } + + /* Panel: rounded top, full width, no max-width limit on mobile */ + .home-login-panel { + width: 100%; + max-width: 100%; + margin: 0; + padding: 1.35rem 1.25rem 2rem; + border-radius: 1.5rem 1.5rem 0 0; + border-bottom: none; + position: relative; + max-height: calc(100dvh - var(--bw-topbar-offset, 64px) - 0.5rem); + overflow-y: auto; + overscroll-behavior: contain; + -webkit-overflow-scrolling: touch; + padding-bottom: max(2rem, calc(1.35rem + env(safe-area-inset-bottom, 0px))); + backdrop-filter: none !important; + -webkit-backdrop-filter: none !important; + background: #fff; + } + + @include media-breakpoint-up(sm) { + .home-login-panel { + max-width: 38rem; + margin-left: auto; + margin-right: auto; + } + } + + /* Close button inside panel */ + .home-login-panel__close { + position: absolute; + top: 0.85rem; + right: 0.85rem; + display: flex; + align-items: center; + justify-content: center; + width: 2.1rem; + height: 2.1rem; + padding: 0; + border: none; + border-radius: 999px; + background: rgba(15, 23, 42, 0.07); + color: #475569; + cursor: pointer; + transition: background-color 0.15s ease; + + &:hover, + &:focus { + background: rgba(15, 23, 42, 0.12); + color: #0f172a; + } + } + + .home-login-panel__title { + font-size: 1.05rem; + margin-bottom: 0.9rem; + padding-right: 2rem; + } + + .home-login-field { + margin-bottom: 0.7rem; + } + + .home-login-field--row { + margin-bottom: 0.7rem; + } + + .home-login-field__label { + font-size: 0.73rem; + margin-bottom: 0.3rem; + } + + .home-login-field__input { + padding: 0.65rem 0.9rem; + font-size: 0.95rem; + border-radius: 0.75rem; + } + + .home-login-field--password .home-login-field__input { + padding-right: 2.75rem; + } + + .home-login-field__toggle { + right: 0.3rem; + width: 2rem; + height: 2rem; + } + + .home-login-field__remember { + font-size: 0.8rem; + } + + .home-login-form__submit { + margin-top: 0.3rem; + padding: 0.75rem 1rem; + font-size: 0.95rem; + } + + .home-login-panel__signup { + margin-top: 0.8rem; + padding-top: 0.7rem; + font-size: 0.75rem; + } + } + + /* ── Backdrop overlay ──────────────────────────────────────────── */ + .home-login-backdrop { + display: none; + position: fixed; + inset: 0; + z-index: 12009; + background: rgba(5, 14, 28, 0.55); + backdrop-filter: blur(3px); + -webkit-backdrop-filter: blur(3px); + opacity: 0; + transition: opacity 0.3s ease; + + &.is-visible { + display: block; + opacity: 1; + } + } + + /* ── iOS layering fix when sheet is open ───────────────────────── */ + body.home-sheet-open & { + .home-hero { + overflow: visible; + } + } + + /* ── Login card ───────────────────────────────────────────────── */ + .home-login-panel { + width: 100%; + margin-left: auto; + margin-right: auto; + max-width: 100%; + padding: 1.75rem 1.65rem 1.5rem; + border-radius: 1.75rem; + background: rgba(255, 255, 255, 0.97); + border: 1px solid rgba(255, 255, 255, 0.75); + box-shadow: + 0 2px 4px rgba(15, 23, 42, 0.04), + 0 24px 64px -8px rgba(15, 23, 42, 0.22); + backdrop-filter: blur(20px) saturate(160%); + + @supports not (backdrop-filter: blur(1px)) { + background: #fff; + } + } + + .home-login-panel__title { + display: block; + font-size: 1.3rem; + font-weight: 500; + letter-spacing: -0.01em; + color: #d97a2e; + margin-bottom: 1.15rem; + text-align: left; + } + + /* ── Fields ────────────────────────────────────────────────────── */ + .home-login-field { + margin-bottom: 0.85rem; + } + + .home-login-field__label { + display: block; + font-size: 0.78rem; + font-weight: 700; + letter-spacing: 0.01em; + color: #475569; + margin-bottom: 0.4rem; + } + + .home-login-field__input { + display: block; + width: 100%; + padding: 0.7rem 1rem; + font-size: 1rem; + line-height: 1.4; + color: #0f172a; + background: #f1f5f9; + border: 1.5px solid transparent; + border-radius: 0.875rem; + transition: + background-color 0.18s ease, + border-color 0.18s ease, + box-shadow 0.18s ease; + + &::placeholder { + color: #94a3b8; + } + + &:focus { + outline: none; + background: #fff; + border-color: #f37000; + box-shadow: 0 0 0 4px rgba(243, 112, 0, 0.13); + } + } + + .home-login-field__password-wrap { + position: relative; + } + + .home-login-field--password .home-login-field__input { + padding-right: 3rem; + } + + .home-login-field__toggle { + position: absolute; + top: 50%; + right: 0.45rem; + transform: translateY(-50%); + display: flex; + align-items: center; + justify-content: center; + width: 2.1rem; + height: 2.1rem; + padding: 0; + border: none; + border-radius: 0.65rem; + background: transparent; + color: #94a3b8; + transition: color 0.15s ease; + + &:hover, + &:focus { + color: #475569; + background: rgba(15, 23, 42, 0.04); + } + } + + /* ── Remember me ───────────────────────────────────────────────── */ + .home-login-field--row { + margin-bottom: 0.85rem; + } + + .home-login-field__checkbox { + width: 1rem; + height: 1rem; + flex-shrink: 0; + accent-color: #f37000; + cursor: pointer; + border-radius: 0.25rem; + } + + .home-login-field__remember { + color: #475569; + font-size: 0.85rem; + cursor: pointer; + } + + /* ── Submit ────────────────────────────────────────────────────── */ + .home-login-form__submit { + width: 100%; + margin-top: 0.5rem; + padding: 0.85rem 1rem; + font-size: 1rem; + font-weight: 700; + letter-spacing: 0.01em; + border: none; + border-radius: 999px; + color: #fff; + background: linear-gradient(135deg, #ff9a2e 0%, #f37000 60%, #e06000 100%); + box-shadow: + 0 4px 14px rgba(243, 112, 0, 0.32), + 0 1px 3px rgba(243, 112, 0, 0.15); + transition: + filter 0.18s ease, + box-shadow 0.18s ease, + transform 0.18s ease; + + &:hover, + &:focus { + color: #fff; + filter: brightness(1.07); + box-shadow: + 0 6px 20px rgba(243, 112, 0, 0.38), + 0 2px 6px rgba(243, 112, 0, 0.18); + transform: translateY(-1px); + } + + &:active { + transform: translateY(0); + filter: brightness(0.97); + } + } + + /* ── Signup hint ───────────────────────────────────────────────── */ + .home-login-panel__signup { + margin-top: 1.1rem; + margin-bottom: 0; + padding-top: 0.9rem; + border-top: 1px solid rgba(15, 23, 42, 0.07); + font-size: 0.8125rem; + line-height: 1.5; + text-align: center; + color: #64748b; + + a { + color: #ea6d00; + font-weight: 700; + text-decoration: none; + + &:hover, + &:focus { + text-decoration: underline; + text-underline-offset: 0.12em; + } + } + } + + @include media-breakpoint-down(lg) { + .home-login-panel { + padding: 1.35rem 1.2rem 1.15rem; + } + + .home-login-panel__title { + font-size: 1.1rem; + margin-bottom: 0.9rem; + } + + .home-login-field { + margin-bottom: 0.7rem; + } + + .home-login-field--row { + margin-bottom: 0.7rem; + } + + .home-login-field__label { + font-size: 0.73rem; + margin-bottom: 0.3rem; + } + + .home-login-field__input { + padding: 0.65rem 0.9rem; + font-size: 0.95rem; + border-radius: 0.75rem; + } + + .home-login-field--password .home-login-field__input { + padding-right: 2.75rem; + } + + .home-login-field__toggle { + right: 0.3rem; + width: 2rem; + height: 2rem; + } + + .home-login-field__remember { + font-size: 0.8rem; + } + + .home-login-form__submit { + margin-top: 0.3rem; + padding: 0.75rem 1rem; + font-size: 0.95rem; + } + + .home-login-panel__signup { + margin-top: 0.8rem; + padding-top: 0.7rem; + font-size: 0.75rem; + } + + .home-section-title { + line-height: 1.25; + padding-left: 0.25rem; + padding-right: 0.25rem; + } + + .home-icon-title { + line-height: 1.35; + font-size: 1.2rem; + } + + .home-subheading { + line-height: 1.65; + padding-left: 0.25rem; + padding-right: 0.25rem; + } + } + + /* ── Shared section title ──────────────────────────────────────── */ + .home-section-title { + font-size: clamp(1.65rem, 3vw, 2.5rem); + font-weight: 800; + font-family: Signika, sans-serif; + color: #0f172a; + letter-spacing: -0.02em; + } + + /* ── About / features ──────────────────────────────────────────── */ + #about { + background: #fff; + } + + .home-about__container { + padding-top: 4rem; + padding-bottom: 4rem; + } + + .home-features__row { + display: flex; + flex-wrap: wrap; + gap: 1.25rem; + justify-content: center; + } + + .home-feature-card { + flex: 1 1 220px; + max-width: 260px; + background: #fff; + border: 1px solid rgba($bw-blue-dark, 0.07); + border-radius: 1.25rem; + padding: 1.75rem 1.5rem; + text-align: center; + transition: + box-shadow 0.2s ease, + transform 0.2s ease; + + &:hover { + box-shadow: 0 12px 32px rgba($bw-blue-dark, 0.1); + transform: translateY(-3px); + } + } + + .home-feature-card__icon { + display: inline-flex; + align-items: center; + justify-content: center; + width: 3.25rem; + height: 3.25rem; + border-radius: 999px; + background: linear-gradient(135deg, #ff9a2e 0%, #f37000 100%); + color: #fff; + font-size: 1.35rem; + margin-bottom: 1rem; + box-shadow: none; + } + + .home-feature-card__title { + font-size: 1.05rem; + font-weight: 700; + color: #0f172a; + margin-bottom: 0.5rem; + } + + .home-feature-card__text { + font-size: 0.9rem; + line-height: 1.6; + color: #64748b; + margin-bottom: 0; + } + + /* ── Statistics ────────────────────────────────────────────────── */ + #statistics { + background: #f8fafc; + border-top: 1px solid #eef0f3; + border-bottom: 1px solid #eef0f3; + } + + .home-stats__container { + padding-top: 4rem; + padding-bottom: 4rem; + text-align: center; + } + + .home-stats__eyebrow { + font-size: 0.7rem; + font-weight: 700; + letter-spacing: 0.18em; + text-transform: uppercase; + color: #94a3b8; + margin-bottom: 2.5rem; + } + + .home-stats__row { + margin-left: -0.5rem; + margin-right: -0.5rem; + } + + .home-stat-item { + padding: 1.75rem 0.5rem; + text-align: center; + + @include media-breakpoint-up(lg) { + border-right: 1px solid #e2e8f0; + + &:last-child { + border-right: none; + } + } + } + + .home-stat-item__icon { + display: none; + } + + .home-stat-value { + font-size: clamp(2rem, 5vw, 3rem); + font-weight: 800; + line-height: 1; + color: #0f172a; + margin-bottom: 0.4rem; + font-family: Signika, sans-serif; + letter-spacing: -0.03em; + } + + .home-stat-label { + font-size: 0.7rem; + font-weight: 600; + color: #64748b; + text-transform: uppercase; + letter-spacing: 0.1em; + } + + /* ── Photo strips ──────────────────────────────────────────────── */ + .home-strip { + min-height: 70vh; + display: flex; + align-items: center; + + &::after { + background: linear-gradient( + to bottom, + rgba(0, 0, 0, 0.3) 0%, + rgba(0, 0, 0, 0.5) 100% + ); + } + } + + .home-strip__body { + text-align: center; + padding-top: 5rem; + padding-bottom: 5rem; + } + + /* ── CTA section ───────────────────────────────────────────────── */ + .home-strip--cta { + min-height: auto; + + &::after { + background: rgba(0, 0, 0, 0.55); + } + } + + .home-strip--cta .home-strip__body { + padding-top: 4rem; + padding-bottom: 4rem; + } + + .home-cta-heading { + font-size: clamp(1.75rem, 4vw, 2.75rem); + font-weight: 800; + font-family: Signika, sans-serif; + letter-spacing: -0.02em; + line-height: 1.15; + color: #fff; + margin-bottom: 0.6rem; + } + + .home-subheading { + font-size: clamp(0.9rem, 1.8vw, 1.05rem); + line-height: 1.6; + font-weight: 400; + color: rgba(255, 255, 255, 0.75); + margin-bottom: 2.25rem; + } + + .home-cta__button { + display: inline-flex; + align-items: center; + justify-content: center; + min-height: 2.95rem; + padding: 0.8rem 1.85rem; + border: none; + border-radius: 999px; + color: #fff; + font-size: 1rem; + font-weight: 700; + letter-spacing: 0.01em; + background: linear-gradient(135deg, #ff9a2e 0%, #f37000 60%, #e06000 100%); + transition: filter 0.18s ease; + + &:hover, + &:focus { + color: #fff; + filter: brightness(1.06); + } + } + + .home-cta-label { + font-size: 0.68rem; + font-weight: 700; + letter-spacing: 0.12em; + text-transform: uppercase; + color: #94a3b8; + margin-bottom: 0.55rem; + text-align: left; + } + + .home-cta-hint { + font-size: 0.78rem; + color: #94a3b8; + margin-top: 0.6rem; + margin-bottom: 0; + text-align: left; + } + + .home-cta-field { + display: flex; + align-items: center; + background: #f8fafc; + border: 1.5px solid #e2e8f0; + border-radius: 0.85rem; + overflow: hidden; + transition: border-color 0.2s ease, box-shadow 0.2s ease; + + &:focus-within { + border-color: #cbd5e1; + box-shadow: 0 0 0 3px rgba(15, 23, 42, 0.06); + } + + &__icon { + flex-shrink: 0; + padding: 0 0.9rem; + color: #94a3b8; + font-size: 0.9rem; + } + + &__auto-wrapper { + flex: 1; + min-width: 0; + display: flex; + align-items: center; + + /* Neutralize the global auto-search-wrapper styles */ + &::before { + display: none !important; + } + + input { + border: none !important; + border-radius: 0 !important; + background: transparent !important; + box-shadow: none !important; + padding-left: 0 !important; + height: 3rem !important; + width: 100%; + color: #0f172a; + font-size: 0.95rem; + + &::placeholder { + color: #94a3b8; + } + + &:focus { + outline: none; + border: none !important; + box-shadow: none !important; + } + } + } + + &__input { + flex: 1; + min-width: 0; + height: 3rem; + background: transparent; + border: none; + color: #0f172a; + font-size: 0.95rem; + font-weight: 400; + padding: 0; + box-shadow: none; + + &::placeholder { + color: #94a3b8; + } + + &:focus { + outline: none; + box-shadow: none; + background: transparent; + } + } + + &__btn { + flex-shrink: 0; + margin: 0.3rem; + width: 2.4rem; + height: 2.4rem; + border: none; + border-radius: 0.6rem; + background: #f37000; + color: #fff; + font-size: 0.85rem; + display: flex; + align-items: center; + justify-content: center; + transition: background 0.18s ease; + + &:hover, + &:focus { + background: darken(#f37000, 8%); + outline: none; + } + } + } +} + +.loginbar--slim { + .loginbar-slim__cta { + line-height: 1.35; + + a { + &:hover, + &:focus { + color: #fff; + text-decoration: underline; + } + } + } + + .loginbar-slim__sep { + font-weight: 300; + user-select: none; + } + + .loginbar-slim__lang-toggle { + &:hover, + &:focus, + &:active { + color: #fff !important; + background: transparent !important; + border: none !important; + box-shadow: none !important; + text-decoration: none; + } + + &:focus-visible { + outline: 2px solid rgba(255, 255, 255, 0.45); + outline-offset: 2px; + } + } +} + +/* Cookie consent: bottom full-width banner */ +.cc-window.cc-banner { + left: 0; + right: 0; + bottom: 0; + width: 100%; + max-width: none; + border-radius: 0; + border-top: 1px solid rgba(15, 23, 42, 0.1); + box-shadow: 0 -8px 28px rgba(15, 23, 42, 0.1); + padding: 0.85rem 1rem; +} + +.cc-window .cc-message { + font-size: 0.9rem; + line-height: 1.45; +} + +.cc-window .cc-link { + color: #f37000; +} + +.cc-window .cc-btn { + border: none; + border-radius: 999px; + padding: 0.45rem 1rem; + font-weight: 700; +} diff --git a/assets/scss/_home.scss b/assets/scss/_home.scss index 6035b2265a..9d37c30298 100644 --- a/assets/scss/_home.scss +++ b/assets/scss/_home.scss @@ -1,5 +1,5 @@ .welcomeback{ - background-color: theme('colors.gray-15'); + background-color: theme('colors.gray-150'); border-radius: 16px; position: relative; padding: 16px; diff --git a/assets/scss/_mixins.scss b/assets/scss/_mixins.scss index ececa08d4a..4a60df3aa1 100644 --- a/assets/scss/_mixins.scss +++ b/assets/scss/_mixins.scss @@ -30,8 +30,14 @@ ); @each $ext in $exts { - $extmod: if(map-has-key($extmods, $ext), $ext + map-get($extmods, $ext), $ext); - $format: if(map-has-key($formats, $ext), map-get($formats, $ext), $ext); + $extmod: $ext; + @if map-has-key($extmods, $ext) { + $extmod: $ext + map-get($extmods, $ext); + } + $format: $ext; + @if map-has-key($formats, $ext) { + $format: map-get($formats, $ext); + } $src: append($src, url(quote($path + "." + $extmod)) format(quote($format)), comma); } diff --git a/assets/scss/_navbar.scss b/assets/scss/_navbar.scss index 7252ae08fe..1cd86ff6a6 100644 --- a/assets/scss/_navbar.scss +++ b/assets/scss/_navbar.scss @@ -1,5 +1,59 @@ -.navbar { +/* Logo: icon SVG has a tall viewBox — without explicit size it blows up; wordmark must not flex-shrink to 0. */ +#main_menu .bw-header-logo { + display: inline-flex; + flex-direction: row; + align-items: center; + gap: 0.4rem; + height: 44px; + max-height: 44px; + min-width: 0; +} + +#main_menu .bw-header-logo__icon { + display: block; + width: 40px; + height: 40px; + flex: 0 0 40px; + object-fit: contain; +} + +#main_menu .bw-header-logo__text { + display: block; + flex: 0 0 auto; + width: auto; + height: 30px; + object-fit: contain; + object-position: left center; +} + +@include media-breakpoint-down(md) { + #main_menu .bw-header-logo__text { + display: none; + } + + #main_menu.loginbar--slim .bw-header-logo { + width: auto; + max-width: 100%; + } + + #main_menu.loginbar--slim .bw-header-logo__text { + display: block; + height: 24px; + } +} + +@include media-breakpoint-up(md) { + #main_menu .bw-header-logo__text { + height: 38px; + } + + #main_menu .bw-header-logo { + width: 260px; + max-width: 260px; + } +} +.navbar { .navbar-brand { padding-right: $spacer; } @@ -10,14 +64,280 @@ padding-top: 0.75rem; } - .nav-link:hover { - background-color: rgba($navbar-dark-color, 0.2); - color: $navbar-dark-hover-color; - text-shadow: 0 0 0.1rem white; - border-radius: $border-radius; + z-index: 2000; +} + +/* Standard app-bar height (64px); keep offsets (sticky, offcanvas, layouts) in sync. */ +:root { + --bw-topbar-offset: 64px; +} + +#main_menu.navbar { + height: 64px; + min-height: 64px; + max-height: 64px; + box-sizing: border-box; + padding-top: 0; + padding-bottom: 0; + box-shadow: 0 2px 10px rgba(15, 23, 42, 0.12); +} + +#main_menu #brand_image.navbar-brand { + display: inline-flex; + align-items: center; + margin-top: 0; + margin-bottom: 0; + padding-top: 0; + padding-bottom: 0; + line-height: 1; +} + +@include media-breakpoint-down(lg) { + #main_menu.navbar > .bw-topbar__container { + padding-left: max(0.7rem, env(safe-area-inset-left, 0px)) !important; + padding-right: max(0.7rem, env(safe-area-inset-right, 0px)) !important; } - z-index: 2000; + #main_menu #collapsing_menu.navbar-nav, + #main_menu #static_menu.navbar-nav { + margin-left: 0 !important; + margin-right: 0 !important; + } +} + +/* Right cluster: search + community icons + messages + profile. */ +#main_menu #static_menu.navbar-nav { + flex-wrap: nowrap; + column-gap: 0.2rem; +} + +@include media-breakpoint-up(xl) { + #main_menu #static_menu.navbar-nav { + column-gap: 0.5rem; + } +} + +#main_menu #conversationCount.topbar-counter.nav-link { + margin: 0 !important; + padding-left: 0 !important; + padding-right: 0 !important; +} + +#main_menu.navbar .navbar-nav .nav-link { + padding-top: 0.625rem; + padding-bottom: 0.625rem; +} + +/* + * Main header nav: kill the light “box” around items on hover/open dropdown. + * Browsers often paint this as :focus/:focus-visible outline or box-shadow on the + * .dropdown-toggle ; previous rules lost specificity to Bootstrap / UA styles. + */ +#main_menu.navbar-dark { + -webkit-tap-highlight-color: transparent; + + .topbar-counter__link, + .topbar-member-toggle, + .topbar-icon-dropdown { + display: inline-flex; + align-items: center; + gap: 0.45rem; + box-sizing: border-box; + /* Same pill box as messages (44px); lock height so profile name/avatar cannot stretch it. */ + height: 2.75rem; + min-height: 2.75rem; + max-height: 2.75rem; + padding-left: 0.65rem !important; + padding-right: 0.85rem !important; + border-radius: 999px; + transition: background-color 0.15s ease; + /* Visible chip at rest (same spirit as former hover-only state). */ + background-color: rgba(255, 255, 255, 0.12) !important; + text-decoration: none; + } + + .topbar-icon-dropdown { + justify-content: center; + width: 2.75rem; + min-width: 2.75rem; + max-width: 2.75rem; + padding-left: 0 !important; + padding-right: 0 !important; + gap: 0; + } + + .topbar-icon-dropdown::after { + display: none !important; + } + + .topbar-icon-dropdown__icon { + display: inline-flex; + align-items: center; + justify-content: center; + width: 1.3rem; + font-size: 1.15rem; + line-height: 1; + } + + .topbar-counter__link:hover, + .topbar-counter__link:focus, + .topbar-member-toggle:hover, + .topbar-member-toggle:focus, + .nav-item.dropdown.show > .topbar-member-toggle, + .topbar-icon-dropdown:hover, + .topbar-icon-dropdown:focus, + .nav-item.dropdown.show > .topbar-icon-dropdown { + background-color: rgba(255, 255, 255, 0.2) !important; + text-decoration: none; + } + + /* Keep name + caret same white as at rest (Bootstrap hover uses $navbar-dark-hover-color otherwise). */ + .topbar-member-toggle, + .topbar-member-toggle:hover, + .topbar-member-toggle:focus, + .topbar-member-toggle:focus-visible, + .nav-item.dropdown.show > .topbar-member-toggle, + .topbar-icon-dropdown, + .topbar-icon-dropdown:hover, + .topbar-icon-dropdown:focus, + .topbar-icon-dropdown:focus-visible, + .nav-item.dropdown.show > .topbar-icon-dropdown { + color: $navbar-dark-color !important; + } + + .topbar-counter__link { + position: relative; + } + + .topbar-counter__icon { + display: inline-flex; + align-items: center; + justify-content: center; + width: 1.3rem; + font-size: 1.15rem; + line-height: 1; + opacity: 1; + } + + .topbar-counter__badge.badge { + position: absolute; + top: -0.08rem; + right: -0.05rem; + min-width: 1rem; + height: 1rem; + padding: 0 0.2rem; + display: inline-flex; + align-items: center; + justify-content: center; + font-size: 0.65rem; + font-weight: 700; + line-height: 1; + border-radius: 999px; + color: rgba(255, 255, 255, 0.95); + background-color: rgba(255, 255, 255, 0.22); + border: 1px solid rgba(255, 255, 255, 0.78); + box-shadow: 0 1px 3px rgba(0, 0, 0, 0.18); + + i { + margin: 0 !important; + font-size: 0.55rem; + line-height: 1; + } + } + + /* No unread: hide badge entirely (loading uses data-count="-1" and keeps spinner visible). */ + #conversationCount[data-count="0"] .topbar-counter__badge.badge { + display: none !important; + } + + /* Unread ≥ 1: clear blue chip on orange bar. */ + #conversationCount[data-count]:not([data-count="0"]):not([data-count="-1"]) .topbar-counter__badge.badge { + top: -0.12rem; + right: -0.08rem; + min-width: 1.15rem; + height: 1.15rem; + padding: 0 0.28rem; + font-size: 0.72rem; + font-weight: 800; + color: #fff; + background-color: $topbar-unread-badge-bg; + border: 1px solid rgba(255, 255, 255, 0.95); + box-shadow: + 0 0 0 1px rgba(0, 0, 0, 0.1), + 0 2px 6px rgba(0, 80, 160, 0.35); + } + + .topbar-member__name { + max-width: 10.5rem; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + line-height: 1.2; + font-size: $font-size-base; + } + + .topbar-member-toggle .js-profile-picture { + width: 32px; + height: 32px; + flex: 0 0 32px; + border: 0 !important; + box-shadow: none !important; + } + + @include media-breakpoint-down(md) { + .topbar-member-toggle { + gap: 0.1rem; + padding-left: 0.4rem !important; + padding-right: 0.45rem !important; + } + + .topbar-member-toggle::after { + margin-left: 0.08rem; + } + } + + .navbar-nav .nav-link { + border: 0; + text-shadow: none; + } + + /* Exclude profile chip + top-bar icon chips: they keep a subtle pill background. */ + .navbar-nav .nav-link:not(.topbar-member-toggle):not(.topbar-icon-dropdown), + .navbar-nav .nav-link.dropdown-toggle:not(.topbar-member-toggle):not(.topbar-icon-dropdown) { + &, + &:hover, + &:focus, + &:focus-visible, + &:active { + background-color: transparent !important; + color: $navbar-dark-color !important; + border: 0 !important; + border-color: transparent !important; + outline: none !important; + outline-offset: 0 !important; + box-shadow: none !important; + } + } + + .navbar-nav .nav-item.show > .nav-link, + .navbar-nav .nav-item.dropdown.show > .nav-link { + outline: none !important; + box-shadow: none !important; + border: 0 !important; + } + + /* Inner (e.g. envelope) can still get the UA focus ring */ + .navbar-nav .nav-link a, + .navbar-nav .nav-item a.nav-link { + &, + &:hover, + &:focus, + &:focus-visible, + &:active { + outline: none !important; + box-shadow: none !important; + } + } } .navbar-shadow{ @@ -26,7 +346,7 @@ .subnav{ position: fixed !important; - top: 42px; + top: var(--bw-topbar-offset, 56px); left: 0; right: 0; background-color: rgba($brand-primary,0.95); @@ -96,6 +416,21 @@ } @include media-breakpoint-up(lg) { + /* + * Default .navbar > .container uses align-items: center, so the left and right
    comment) { ?> -
    comment); ?>
    +
    comment); ?>
    diff --git a/build/admin/adminbase.ctrl.php b/build/admin/adminbase.ctrl.php index ccd96c5e13..0305691826 100644 --- a/build/admin/adminbase.ctrl.php +++ b/build/admin/adminbase.ctrl.php @@ -12,6 +12,7 @@ public function __construct($model = false) } } + #[\Override] public function __destruct() { unset($this->_model); @@ -35,7 +36,7 @@ protected function checkRights($right = '') $this->redirectAbsolute($this->router->url('admin_norights')); exit(0); } - return array($member, $rights); + return [$member, $rights]; } /** diff --git a/build/admin/autoload.ini b/build/admin/autoload.ini index c151a69de8..070e460cd8 100644 --- a/build/admin/autoload.ini +++ b/build/admin/autoload.ini @@ -18,9 +18,3 @@ adminnewmembers.model.php = AdminNewMembersModel [newmembers/pages] adminnewmembersbase.page.php = AdminNewMembersBasePage adminnewmemberslistmembers.page.php = AdminNewMembersListMembersPage - -[rights] -adminrights.entity.php = Right - -[flags] -adminflags.entity.php = Flag diff --git a/build/admin/comments/admincomments.ctrl.php b/build/admin/comments/admincomments.ctrl.php index dbd12140cf..6b39d2ab17 100644 --- a/build/admin/comments/admincomments.ctrl.php +++ b/build/admin/comments/admincomments.ctrl.php @@ -44,6 +44,7 @@ public function __construct() { $this->model = new AdminCommentsModel(); } + #[\Override] public function __destruct() { unset($this->model); } @@ -94,7 +95,7 @@ public function updateCallback(StdClass $args, ReadOnlyObject $action, $this->setFlashNotice("Updated comment of " . $args->post['nameFrom'] . " about " . $args->post['nameTo'] . "."); - return $this->router->url('admin_comments_list_single', array('id' => $args->post['id']), false); + return $this->router->url('admin_comments_list_single', ['id' => $args->post['id']], false); } /** @@ -104,7 +105,7 @@ public function updateCallback(StdClass $args, ReadOnlyObject $action, */ public function subset() { - list($member, $rights) = $this->checkRights('Comments'); + [$member, $rights] = $this->checkRights('Comments'); $page = new AdminCommentsPage($this->model); $page->setSubset($this->route_vars['subset']); $page->comments = $this->model->getSubset($this->route_vars['subset']); @@ -118,7 +119,7 @@ public function subset() */ public function from() { - list($member, $rights) = $this->checkRights('Comments'); + [$member, $rights] = $this->checkRights('Comments'); $page = new AdminCommentsPage($this->model); $page->setSubset("from"); $page->comments = $this->model->getFrom($this->route_vars['id']); @@ -132,7 +133,7 @@ public function from() */ public function to() { - list($member, $rights) = $this->checkRights('Comments'); + [$member, $rights] = $this->checkRights('Comments'); $page = new AdminCommentsPage($this->model); $page->setSubset("to"); $page->comments = $this->model->getTo($this->route_vars['id']); @@ -146,7 +147,7 @@ public function to() */ public function single() { - list($member, $rights) = $this->checkRights('Comments'); + [$member, $rights] = $this->checkRights('Comments'); $this->_processGet(); $page = new AdminCommentsPage($this->model); $page->setSubset("single"); diff --git a/build/admin/comments/admincomments.model.php b/build/admin/comments/admincomments.model.php index a086d779e2..9b7a4c913e 100644 --- a/build/admin/comments/admincomments.model.php +++ b/build/admin/comments/admincomments.model.php @@ -67,7 +67,7 @@ public function getTo($id) public function getSingle($id) { $result = $this->createEntity('Comment')->findById($id); - $a = array(); + $a = []; $a[] = $result; return $a; } @@ -76,7 +76,7 @@ public function getSingle($id) // @see MembersModel.checkCommentForm() public function checkUpdate(&$vars) { - $errors = array(); + $errors = []; // if (!isset($vars['TextFree'])) { // $errors[] = 'Comment_NoCommentLengthSelected'; // } diff --git a/build/admin/comments/pages/admincomments.page.php b/build/admin/comments/pages/admincomments.page.php index 59402683d5..6a2103b59e 100755 --- a/build/admin/comments/pages/admincomments.page.php +++ b/build/admin/comments/pages/admincomments.page.php @@ -32,14 +32,14 @@ class AdminCommentsPage extends AdminBasePage { - private $_subset2Teaser = array( + private $_subset2Teaser = [ "all" => "All Comments", "abusive" => "Abusive Comments", "negative" => "Negative Comments", "from" => "User Comments", "to" => "User Comments", "single" => "Edit Comment" - ); + ]; private $teaser = ""; @@ -69,6 +69,7 @@ public function setSubset($subset) $this->subset = $subset; } + #[\Override] public function teaserHeadline() { return "{$this->words->get('AdminTools')} » {$this->teaser}"; @@ -86,7 +87,7 @@ protected function allowEdit($f) protected function getProximityBlock($sel) { - $selected = explode(",", $sel); + $selected = explode(",", (string) $sel); $proximityBlock = ""; $syshcvol = PVars::getObj('syshcvol'); foreach ($syshcvol->LenghtComments as $proximity) diff --git a/build/admin/comments/templates/admincomments.column_col3.php b/build/admin/comments/templates/admincomments.column_col3.php index 80a9c56623..0b61e4cbf9 100755 --- a/build/admin/comments/templates/admincomments.column_col3.php +++ b/build/admin/comments/templates/admincomments.column_col3.php @@ -64,7 +64,7 @@ Profile
    - my comments
    + my comments
    contact me
  • @@ -73,7 +73,7 @@ Profile
    - comments about me
    + comments about me
    contact me @@ -104,7 +104,7 @@ HTML; if($comment->AdminAction != "Checked" && $comment->AdminAction != "NothingNeeded") { - $url = $this->router->url('admin_comments_list_single', array('id' => $comment->id)); + $url = $this->router->url('admin_comments_list_single', ['id' => $comment->id]); ?> diff --git a/build/admin/comments/templates/admincomments.leftsidebar.php b/build/admin/comments/templates/admincomments.leftsidebar.php index 1613af59b4..f5404ded9c 100644 --- a/build/admin/comments/templates/admincomments.leftsidebar.php +++ b/build/admin/comments/templates/admincomments.leftsidebar.php @@ -32,12 +32,12 @@

    get('Action'); ?>

    diff --git a/build/admin/flags/adminflags.ctrl.php b/build/admin/flags/adminflags.ctrl.php deleted file mode 100644 index 1f5cda428f..0000000000 --- a/build/admin/flags/adminflags.ctrl.php +++ /dev/null @@ -1,339 +0,0 @@ - or -write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. - -*/ - -/** - * @author shevek - */ - -/** - * adminFlags controller - * deals with actions that are available exclusively for Flags managers - * - * @package apps - * @subpackage Admin - */ -class AdminFlagsController extends AdminBaseController -{ - private $model; - - public function __construct() { - parent::__construct(); - $this->model = new AdminFlagsModel(); - } - - public function __destruct() { - unset($this->model); - } - - public function assignCallback(StdClass $args, ReadOnlyObject $action, - ReadWriteObject $mem_redirect, ReadWriteObject $mem_resend) - { - $vars = $args->post; - $errors = $this->model->checkAssignVarsOk($vars); - if (count($errors) > 0) { - $mem_redirect->errors = $errors; - $mem_redirect->vars = $args->post; - return false; - } - $this->model->assignFlag($vars); - $Flags = $this->model->getFlags(); - $flag = $Flags[$vars['flagid']]; - $this->setFlashNotice($this->getWords()->get('AdminFlagsFlagAssigned', $vars['username'], $flag->Name)); - - return $this->router->url('admin_flags_member', array("username" => $vars['username']), false); - } - - public function assign() { - $this->checkRights('Flags'); - $member = false; - if (isset($this->route_vars['username'])) { - $temp = new Member(); - $member = $temp->findByUsername($this->route_vars['username']); - }; - $page = new AdminFlagsAssignPage(); - $page->member = $member; - $page->vars = array( - 'username' => ($member ? $member->Username : ''), - 'flagid' => 0, - 'level' => 0, - 'scope' => '', - 'comment' => ''); - $page->flags = $this->model->getFlags(true, $member); - return $page; - } - - public function listMembersCallback(StdClass $args, ReadOnlyObject $action, - ReadWriteObject $mem_redirect, ReadWriteObject $mem_resend) - { - $vars = $args->post; - $member = false; - if (isset($vars['member']) && $vars['member'] <> '0') { - $temp = new Member(); - $member = $temp->findById($vars['member']); - } - $history = false; - if (isset($vars['history']) && $vars['history'] <> '0') { - $history= true; - } - $mem_redirect->vars = $vars; - $mem_redirect->members = $this->model->getMembersWithFlags(false, $history); - // get list of members with Flags (as assigned, filter by $member if set) - $mem_redirect->membersWithFlags = $this->model->getMembersWithFlags($member, $history); - } - - public function listMembers() - { - $this->checkRights('Flags'); - $member = false; - if (isset($this->route_vars['username'])) { - $temp = new Member(); - $member = $temp->findByUsername($this->route_vars['username']); - }; - $page = new AdminFlagsListMembersPage(); - $page->vars = array( - 'member' => ($member ? $member->id : 0) - ); - $page->current = 'AdminFlagsListMembers'; - $page->flags = $this->model->getFlags(); - // get list of members (with assigned Flags) - $page->members = $this->model->getMembersWithFlags(); - // get list of members with Flags (as assigned, filter by $member if set) - $page->membersWithFlags = $this->model->getMembersWithFlags($member); - if (($member) && (count($page->membersWithFlags) == 0)) { - $this->redirectAbsolute('/admin/flags/assign/' . $this->route_vars['username']); - } - return $page; - } - - public function listFlagsCallback(StdClass $args, ReadOnlyObject $action, - ReadWriteObject $mem_redirect, ReadWriteObject $mem_resend) - { - $vars = $args->post; - $flagId = false; - if (isset($vars['flagid']) && $vars['flagid'] <> '0') { - $flagId = $vars['flagid']; - } - $history = false; - if (isset($vars['history']) && $vars['history'] <> '0') { - $history = true; - } - $mem_redirect->vars = $vars; - $mem_redirect->FlagsWithMembers = $this->model->getFlagsWithMembers($flagId, $history); - return true; - } - - public function listFlags() - { - $this->checkRights('Flags'); - $flagId = false; - if (isset($this->route_vars['id']) && is_numeric($this->route_vars['id'])) { - $flagId = $this->route_vars['id']; - }; - $page = new AdminFlagsListFlagsPage(); - $page->flags = $this->model->getFlags(); - $page->vars = array( - 'flagid' => $flagId - ); - $page->flagsWithMembers = $this->model->getFlagsWithMembers($flagId); - return $page; - } - - public function overview() { - $this->checkRights('Flags'); - $page = new AdminFlagsOverviewPage(); - $page->current = 'AdminFlagsOverview'; - $page->flags = $this->model->getFlags(); - return $page; - } - - public function tooltip() { - $id = $this->args_vars->get['tooltip']; - header('Content-type: text/html, charset=utf-8'); - $javascript = $this->model->getWords()->get($id); - echo $javascript . "\n"; - exit; - } - - public function editCallback(StdClass $args, ReadOnlyObject $action, - ReadWriteObject $mem_redirect, ReadWriteObject $mem_resend) - { - $vars = $args->post; - $errors = $this->model->checkEditVarsOk($vars); - if (count($errors) > 0) { - $mem_redirect->errors = $errors; - - // Set variables (necessary due to disabled flag) - $vars['flag'] = $vars['flagid']; - - $mem_redirect->vars = $vars; - return false; - } - $this->model->edit($vars); - $this->setFlashNotice($this->getWords()->get('AdminFlagsFlagEdited')); - return true; - } - - public function edit() - { - $this->checkRights('Flags'); - - $flagId = $this->route_vars['id']; - $username = $this->route_vars['username']; - // Check if flag and user exist and if flag is assigned to user at all; redirect if not - $flag = new Flag($flagId); - if (!$flag) { - $this->redirectAbsolute($this->router->url('admin_flags_overview')); - } - $temp = new Member(); - $member = $temp->findByUsername($username); - if (!$member) { - $this->redirectAbsolute($this->router->url('admin_flags_overview')); - } - $assigned = $flag->getFlagForMember($member); - if (!$assigned) { - $this->redirectAbsolute($this->router->url('admin_flags_overview')); - } - - $page = new AdminFlagsEditPage(); - $page->flags = $this->model->getFlags(true); - $vars = array( - 'username' => $username, - 'flag' => $flagId, - 'level' => $assigned->Level, - 'scope' => $assigned->Scope, - 'comment' => $assigned->Comment - ); - $page->vars = $vars; - return $page; - } - - public function removeCallback(StdClass $args, ReadOnlyObject $action, - ReadWriteObject $mem_redirect, ReadWriteObject $mem_resend) - { - $vars = $args->post; - $flags = $this->model->getFlags(); - $flag = $flags[$vars['flagid']]; - $this->setFlashNotice($this->getWords()->get('AdminFlagsFlagRemoved', $vars['username'], $flag->Name )); - switch ($vars['redirect']) { - case 'members': - $url = $this->router->url('admin_flags_members', array(), false); - break; - case 'member': - $url = $this->router->url('admin_flags_member', array("username" => $vars['username']), false); - break; - case 'Flags': - $url = $this->router->url('admin_flags_Flags', array(), false); - break; - case 'flag': - $url = $this->router->url('admin_flags_flag', array("id" => $vars['flag']), false); - break; - default: - $url = $this->router->url('admin_Flags', array(), false); - } - $this->model->remove($vars); - return $url; - } - - public function remove() - { - $this->checkRights('Flags'); - $flagId = $this->route_vars['id']; - $username = $this->route_vars['username']; - // Check if flag and user exist and if flag is assigned to user at all; redirect if not - $flag = new Flag($flagId); - if (!$flag) { - $this->redirectAbsolute($this->router->url('admin_flags_overview')); - } - $temp = new Member(); - $member = $temp->findByUsername($username); - if (!$member) { - $this->redirectAbsolute($this->router->url('admin_flags_overview')); - } - $assigned = $flag->getFlagForMember($member); - if (!$assigned) { - $this->redirectAbsolute($this->router->url('admin_flags_overview')); - } - $page = new AdminFlagsRemovePage(); - - $flags = $this->model->getFlags(true); - $page->flags = $flags; - $redirectTo = ''; - if (isset($_SERVER['HTTP_REFERER'])) { - if (strpos($_SERVER['HTTP_REFERER'], "/list/members") !== false) { - $redirectTo = 'members'; - } - if (strpos($_SERVER['HTTP_REFERER'], "/list/member/") !== false) { - $redirectTo = 'member'; - } - if (strpos($_SERVER['HTTP_REFERER'], "/list/Flags") !== false) { - $redirectTo = 'Flags'; - } - if (strpos($_SERVER['HTTP_REFERER'], "/list/flag/") !== false) { - $redirectTo = 'flag'; - } - } - $vars = array( - 'username' => $username, - 'flag' => $flagId, - 'level' => $assigned->Level, - 'scope' => $assigned->Scope, - 'comment' => $assigned->Comment, - 'redirect' => $redirectTo - ); - $page->vars = $vars; - return $page; - } - - public function createCallback(StdClass $args, ReadOnlyObject $action, - ReadWriteObject $mem_redirect, ReadWriteObject $mem_resend) - { - $vars = $args->post; - $errors = $this->model->checkCreateVarsOk($vars); - if (count($errors) > 0) { - $mem_redirect->errors = $errors; - $mem_redirect->vars = $args->post; - return false; - } - $this->model->createFlag($vars); - $this->setFlashNotice($this->getWords()->get('AdminFlagsFlagCreate', $vars['name'])); - return $this->router->url('admin_flags_overview', array(), false); - } - - public function create() - { - list($loggedInMember, $Rights) = $this->checkRights('Flags'); - // Check if member has create flag if not redirect to overview - if ((stripos($Rights['Flags']['Scope'], 'create') === false - && stripos($Rights['Flags']['Scope'], 'all') === false)) { - $this->redirectAbsolute($this->router->url('admin_flags_overview')); - } - $page = new AdminFlagsCreatePage(); - $vars = array( - 'name' => '', - 'description' => '' - ); - $page->vars = $vars; - return $page; - } -} \ No newline at end of file diff --git a/build/admin/flags/adminflags.entity.php b/build/admin/flags/adminflags.entity.php deleted file mode 100644 index 5c6abf84bd..0000000000 --- a/build/admin/flags/adminflags.entity.php +++ /dev/null @@ -1,49 +0,0 @@ -findById($flagId); - } - } - - /** - * overloads RoxEntityBase::loadEntity to load related data - * - * @param array $data - * - * @access protected - * @return bool - */ - protected function loadEntity(array $data) - { - if ($status = parent::loadEntity($data)) - { - } - return $status; - } - - public function getFlagForMember(Member $member) { - $query = " - SELECT - * - FROM - flagsmembers fm - WHERE - fm.IdFlag = " . $this->id . " - AND fm.IdMember = " . $member->id . " - AND fm.Level <> 0 - "; - return $this->singleLookup($query); - } -} \ No newline at end of file diff --git a/build/admin/flags/adminflags.model.php b/build/admin/flags/adminflags.model.php deleted file mode 100644 index d3908a5bdb..0000000000 --- a/build/admin/flags/adminflags.model.php +++ /dev/null @@ -1,348 +0,0 @@ - 2 && $countSemiColons <> ($countQuotes / 2)) { - return false; - } - return true; - } - - /** - * @param $vars - * @return array - */ - public function checkAssignVarsOk($vars) { - $errors = array(); - if (empty($vars['username'])) { - $errors[] = 'AdminFlagsUsernameEmpty'; - } else { - // check if user name exists - $member = new Member(); - $member = $member->findByUsername($vars['username']); - if (!$member) { - $errors[] = 'AdminFlagsUsernameNotExisting'; - } - } - if ($vars['flagid'] == 0) { - $errors[] = 'AdminFlagsNoFlagSelected'; - } else { - // check if flag is already assigned - if (isset($member)) { - $flag = new Flag($vars['flagid']); - $assigned = $flag->getFlagForMember($member); - if ($assigned) { - $errors[] = 'AdminFlagsAlreadyAssigned'; - } - } - } - if ($vars['level'] == 0) { - $errors[] = 'AdminFlagsNoLevelSelected'; - } - if (empty($vars['comment'])) { - $errors[] = 'AdminFlagsCommentEmpty'; - } - return $errors; - } - - /** - * @param $vars - */ - public function assignFlag($vars) { - $member = new Member(); - $member = $member->findByUsername($vars['username']); - $query = " - INSERT INTO - flagsmembers - SET - IdFlag = '" . $this->dao->escape($vars['flagid']) . "', - IdMember = '" . $member->id . "', - Scope = '" . $this->dao->escape($vars['scope']) . "', - Level = '" . $this->dao->escape($vars['level']) . "', - Comment = '" . $this->dao->escape($vars['comment']) . "', - created = NOW()"; - $this->dao->query($query); - } - - /** - * get list of members with all assigned flags - * - * @access public - * @return array of members with flags - */ - public function getMembersWithFlags($member = false, $includeLevelZero = false) - { - $query = ' - SELECT - m.Username, - m.id as id, - m.status, - m.LastLogin, - g.Name as PlaceName, - gc.Name as CountryName, - f.id flagId, - fm.Level, - fm.Scope, - fm.Comment - FROM - flags f, - flagsmembers fm, - members m, - geonames g, - geonamescountries gc - WHERE - m.Status in (' . MemberStatusType::ACTIVE_ALL . ')'; - if ($member) { - $query .= ' AND m.id = ' . $member->id; - } - $query .= ' - AND fm.IdMember = m.id - AND fm.IdFlag = f.id - AND f.Relevance <> 0 - AND m.IdCity = g.geonameId - AND g.country = gc.country '; - if (!$includeLevelZero) { - $query .= ' AND fm.Level <> 0'; - } - $query .= ' - ORDER BY - f.Relevance DESC, - m.Username, - f.Name - '; - $result = $this->bulkLookup($query); - - $membersWithFlags = array(); - foreach ($result as $mwr) { - if (!isset($membersWithFlags[$mwr->Username])) { - $memberDetails = new stdClass(); - $memberDetails->id = $mwr->id; - $memberDetails->Status = $mwr->status; - $memberDetails->LastLogin = date('Y-m-d', strtotime($mwr->LastLogin)); - $memberDetails->PlaceName = $mwr->PlaceName; - $memberDetails->CountryName = $mwr->CountryName; - $memberDetails->Flags = array(); - $membersWithFlags[$mwr->Username] = $memberDetails; - } - $flagDetails = new stdClass(); - $flagDetails->level = $mwr->Level; - $flagDetails->scope = $mwr->Scope; - $flagDetails->comment = $mwr->Comment; - $membersWithFlags[$mwr->Username]->Flags[$mwr->flagId] = $flagDetails; - } - return $membersWithFlags; - } - - /** - * get list of flags with members with that flag - * - * @access public - * @return list of flags with members - */ - public function getFlagsWithMembers($flagId = false, $includeLevelZero = false) - { - $query = ' - SELECT - f.id flagId, - fm.Level, - fm.Scope, - fm.Comment, - m.Username, - m.id as id, - m.status, - m.LastLogin, - g.Name as PlaceName, - gc.Name as CountryName - FROM - flags f, - flagsmembers fm, - members m, - geonames g, - geonamescountries gc - WHERE - m.Status in (' . MemberStatusType::ACTIVE_ALL . ') - AND fm.IdMember = m.id - AND fm.IdFlag = f.id - AND f.Relevance <> 0'; - if ($flagId) { - $query .= ' AND f.id = ' . $flagId; - } - $query .= ' - AND m.IdCity = g.geonameId - AND g.country = gc.country - '; - if (!$includeLevelZero) { - $query .= ' AND fm.Level <> 0'; - } - $query .= ' - ORDER BY - f.Relevance DESC, - f.Name, - m.Username - '; - $result = $this->bulkLookup($query); - - $flagsWithMembers = array(); - foreach ($result as $rwm) { - if (!isset($flagsWithMembers[$rwm->flagId])) { - $flagDetails = new StdClass(); - $flagDetails->Members = array(); - $flagsWithMembers[$rwm->flagId] = $flagDetails; - } - $memberDetails = new StdClass(); - $memberDetails->Status = $rwm->status; - $memberDetails->LastLogin = date('Y-m-d', strtotime($rwm->LastLogin)); - $memberDetails->Username = $rwm->Username; - $memberDetails->PlaceName = $rwm->PlaceName; - $memberDetails->CountryName = $rwm->CountryName; - $memberDetails->level = $rwm->Level; - $memberDetails->scope = $rwm->Scope; - $memberDetails->comment = $rwm->Comment; - $flagsWithMembers[$rwm->flagId]->Members[$rwm->id] = $memberDetails; - } - return $flagsWithMembers; - } - - /** - * get all flags defined or flags allowed for member - * - * @access public - * @return array list of flags - */ - public function getFlags($memberFlagsOnly = false, $member = false) { - $query = " - SELECT - * - FROM - flags f - WHERE - f.Relevance <> 0"; - if ($memberFlagsOnly) { - } - $query .= " - ORDER BY - f.Relevance DESC, - f.Name - "; - $memberFlags = array(); - if ($member) { - $memberFlags = $member->getOldFlags(); - } - $result = $this->bulkLookup($query, array('id')); - - foreach($memberFlags as $flag) { - if (isset($result[$flag['id']])) { - unset($result[$flag['id']]); - } - } - return $result; - } - - public function checkEditVarsOk($vars) { - $errors = array(); - if (empty($vars['comment'])) { - $errors[] = 'AdminFlagsCommentEmpty'; - } - return $errors; - } - - public function edit($vars) { - $temp = new Member(); - $member = $temp->findByUsername($vars['username']); - $query = " - UPDATE - flagsmembers fm - SET - fm.Level = '" . $this->dao->escape($vars['level']) . "', - fm.Scope = '" . $this->dao->escape($vars['scope']) . "', - fm.Comment = '" . $this->dao->escape($vars['comment']) . "', - fm.Updated = NOW() - WHERE - fm.IdMember = " . $member->id . " - AND fm.IdFlag = " . $this->dao->escape($vars['flagid']) . " - "; - $this->dao->query($query); - return true; - } - - /** - * Removes a flag from a member - * Keeps the history by setting the level to 0 and updating the comment - * with a note when the removal happened and by whom - * - * @param $vars - * @return bool - */ - public function remove($vars) { - $temp = new Member(); - $member = $temp->findByUsername($vars['username']); - $loggedInMember = $this->getLoggedInMember(); - $comment = $vars['comment'] . "\n\nRemoved by " .$loggedInMember->Username . " on " - . date('Y-m-d'); - $query = " - UPDATE - flagsmembers fm - SET - fm.Level = '0', - fm.Scope = '" . $this->dao->escape($vars['scope']) . "', - fm.Comment = '" . $this->dao->escape( $comment ) . "', - fm.Updated = NOW() - WHERE - fm.IdMember = " . $member->id . " - AND fm.IdFlag = " . $this->dao->escape($vars['flagid']) . " - "; - $this->dao->query($query); - return true; - } - - public function checkCreateVarsOk($vars) { - $errors = array(); - if (empty($vars['name'])) { - $errors[] = 'AdminFlagsNameEmpty'; - } else { - $query = " - SELECT - * - FROM - flags f - WHERE - f.Name LIKE '" . $this->dao->escape($vars['name']) . "'"; - $name = $this->singleLookup($query); - if ($name) { - $errors[] = 'AdminFlagsFlagExists'; - } - } - if (empty($vars['description'])) { - $errors[] = 'AdminFlagsDescriptionEmpty'; - } - if (empty($vars['relevance'])) { - $errors[] = 'AdminFlagsRelevance'; - } - return $errors; - } - - public function createFlag($vars) { - $query = " - INSERT INTO - flags - SET - `Name` = '" . $this->dao->escape($vars['name']) . "', - `Description` = '" . $this->dao->escape($vars['description']) . "', - `Relevance` = '100' - "; - $this->dao->query($query); - - return true; - } -} diff --git a/build/admin/flags/pages/adminflagsassign.page.php b/build/admin/flags/pages/adminflagsassign.page.php deleted file mode 100644 index 2f430175b0..0000000000 --- a/build/admin/flags/pages/adminflagsassign.page.php +++ /dev/null @@ -1,30 +0,0 @@ -setCurrent('AdminFlagsAssign'); - $this->addLateLoadScriptFile('build/jquery_ui.js'); - $this->addLateLoadScriptFile('build/member/autocomplete.js'); - } - - public function teaserHeadline() - { - $headline = parent::teaserHeadline(); - return $headline . "» {$this->words->get('AdminFlags')}"; - } - - protected function getStylesheets() - { - $stylesheets = parent::getStylesheets(); - $stylesheets[] = 'build/jquery_ui.css'; - return $stylesheets; - } -} diff --git a/build/admin/flags/pages/adminflagsbase.page.php b/build/admin/flags/pages/adminflagsbase.page.php deleted file mode 100644 index 481a708215..0000000000 --- a/build/admin/flags/pages/adminflagsbase.page.php +++ /dev/null @@ -1,102 +0,0 @@ - 'admin/flags/assign', - 'AdminFlagsOverview' => 'admin/flags/overview', - 'AdminFlagsListMembers' => 'admin/flags/list/members', - 'AdminFlagsListFlags' => 'admin/flags/list/flags', - 'AdminFlagsCreate' => 'admin/flags/create', - ); - - protected $current = false; - protected $flags = false; - protected $create = false; - - public function __construct() { - parent::__construct(new AdminFlagsModel()); - $member = $this->model->getLoggedInMember(); - $flags = $member->getOldFlags(); - $scope = $flags['Flags']['Scope'] ?? null; - $this->create = stripos($scope, '"create"') !== false; - $this->create |= stripos($scope, '"all"') !== false; - } - - public function teaserHeadline() - { - $headline = parent::teaserHeadline(); - return $headline . " » {$this->words->get('AdminFlags')}"; - } - - /** - * @param string $current current item in the side bar - */ - protected function setCurrent($current) { - $this->current = $current; - } - - protected function getStylesheets() - { - $stylesheets = parent::getStylesheets(); - $stylesheets[] = 'styles/css/minimal/screen/custom/admin.css?2'; - return $stylesheets; - } - - protected function getSubmenuItems() - { - $items = []; - foreach($this->sidebar as $key => $item) { - if (!$this->create && $key == 'AdminRightsCreate') continue; - $items[] = [ - $key, - $item, - $this->words->get($key), - ]; - } - return $items; - } - - protected function getSubmenuActiveItem() - { - return $this->current; - } - - protected function flagsSelect($flags, $current, $disabled = false) - { - $select = '' . $this->getWords()->FlushBuffer(); - return $select; - } - - function levelSelect($current, $disabled = false, $showEmpty = true) - { - $select = ''; - return $select; - } -} diff --git a/build/admin/flags/pages/adminflagscreate.page.php b/build/admin/flags/pages/adminflagscreate.page.php deleted file mode 100644 index 20bbb0466b..0000000000 --- a/build/admin/flags/pages/adminflagscreate.page.php +++ /dev/null @@ -1,21 +0,0 @@ -setCurrent('AdminFlagsAssign'); - } - - public function teaserHeadline() - { - $headline = parent::teaserHeadline(); - return $headline . "» {$this->words->get('AdminFlags')}"; - } -} diff --git a/build/admin/flags/pages/adminflagsedit.page.php b/build/admin/flags/pages/adminflagsedit.page.php deleted file mode 100644 index 9336ad9376..0000000000 --- a/build/admin/flags/pages/adminflagsedit.page.php +++ /dev/null @@ -1,16 +0,0 @@ -{$this->words->get('AdminFlags')}"; - } -} diff --git a/build/admin/flags/pages/adminflagslistflags.page.php b/build/admin/flags/pages/adminflagslistflags.page.php deleted file mode 100644 index 09a856df8c..0000000000 --- a/build/admin/flags/pages/adminflagslistflags.page.php +++ /dev/null @@ -1,27 +0,0 @@ -setCurrent('AdminFlagsListFlags'); - } - - public function teaserHeadline() - { - $headline = parent::teaserHeadline(); - return $headline . "» {$this->words->get('AdminFlagsListFlags')}"; - } - - public function getLateLoadScriptFiles() { - $scripts = parent::getLateLoadScriptfiles(); - // $scripts[] = 'adminflagstooltip.js'; - return $scripts; - } -} diff --git a/build/admin/flags/pages/adminflagslistmembers.page.php b/build/admin/flags/pages/adminflagslistmembers.page.php deleted file mode 100644 index 471274a202..0000000000 --- a/build/admin/flags/pages/adminflagslistmembers.page.php +++ /dev/null @@ -1,27 +0,0 @@ -setCurrent('AdminFlagsListMembers'); - } - - public function teaserHeadline() - { - $headline = parent::teaserHeadline(); - return $headline . "» {$this->words->get('AdminFlagsListMembers')}"; - } - - public function getLateLoadScriptFiles() { - $scripts = parent::getLateLoadScriptfiles(); -// $scripts[] = 'adminflagstooltip.js'; - return $scripts; - } -} diff --git a/build/admin/flags/pages/adminflagsoverview.page.php b/build/admin/flags/pages/adminflagsoverview.page.php deleted file mode 100644 index 2da4cac504..0000000000 --- a/build/admin/flags/pages/adminflagsoverview.page.php +++ /dev/null @@ -1,21 +0,0 @@ -setCurrent('AdminFlagsOverview'); - } - - public function teaserHeadline() - { - $headline = parent::teaserHeadline(); - return $headline . "» {$this->words->get('AdminFlagsOverview')}"; - } -} diff --git a/build/admin/flags/pages/adminflagsremove.page.php b/build/admin/flags/pages/adminflagsremove.page.php deleted file mode 100644 index 2e320bfd7c..0000000000 --- a/build/admin/flags/pages/adminflagsremove.page.php +++ /dev/null @@ -1,16 +0,0 @@ -{$this->words->get('AdminFlags')}"; - } -} diff --git a/build/admin/flags/templates/adminflags.leftsidebar.php b/build/admin/flags/templates/adminflags.leftsidebar.php deleted file mode 100644 index 7241d14ed6..0000000000 --- a/build/admin/flags/templates/adminflags.leftsidebar.php +++ /dev/null @@ -1,42 +0,0 @@ - or -write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. - -*/ -/** - * @author shevek - */ -?> -

    words->get('AdminFlagsSideBarTitle'); ?>

    - \ No newline at end of file diff --git a/build/admin/flags/templates/adminflagsassign.column_col3.php b/build/admin/flags/templates/adminflagsassign.column_col3.php deleted file mode 100644 index 596e8b282b..0000000000 --- a/build/admin/flags/templates/adminflagsassign.column_col3.php +++ /dev/null @@ -1,57 +0,0 @@ - or -write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. - -*/ -$vars = $this->getRedirectedMem('vars'); -if ($vars) { - // overwrite the vars - $this->vars = $vars; -} - -include 'adminflagserrors.php'; - -$callbackTags = $this->layoutkit->formkit->setPostCallback('AdminFlagsController', 'assignCallback'); -?> -
    - - - - -
    - - member ? 'readonly="readonly"' : '') ?> - /> -
    -
    - - flagsSelect($this->flags, $this->vars['flagid']) ?> -
    -
    - - -
    -
    - " />flushBuffer(); ?> -
    -
    diff --git a/build/admin/flags/templates/adminflagscreate.column_col3.php b/build/admin/flags/templates/adminflagscreate.column_col3.php deleted file mode 100644 index 7f742519ad..0000000000 --- a/build/admin/flags/templates/adminflagscreate.column_col3.php +++ /dev/null @@ -1,47 +0,0 @@ - or -write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. - -*/ -$vars = $this->getRedirectedMem('vars'); -if ($vars) { - // overwrite the vars - $this->vars = $vars; -} - -include 'adminflagserrors.php'; - -$callbackTags = $this->layoutkit->formkit->setPostCallback('AdminFlagsController', 'createCallback'); -?> -
    - -
    - - -
    -
    - - -
    -
    - " />flushBuffer(); ?> -
    -
    \ No newline at end of file diff --git a/build/admin/flags/templates/adminflagsedit.column_col3.php b/build/admin/flags/templates/adminflagsedit.column_col3.php deleted file mode 100644 index bf6c9574be..0000000000 --- a/build/admin/flags/templates/adminflagsedit.column_col3.php +++ /dev/null @@ -1,55 +0,0 @@ - or -write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. - -*/ -$vars = $this->getRedirectedMem('vars'); -if ($vars) { - // overwrite the vars - $this->vars = $vars; -} - -include 'adminflagserrors.php'; - -$callbackTags = $this->layoutkit->formkit->setPostCallback('AdminFlagsController', 'editCallback'); -?> -
    - - - - - -
    - - -
    -
    - - flagsSelect($this->flags, $this->vars['flag'], true) ?> -
    -
    - - -
    -
    - " />flushBuffer(); ?> -
    -
    \ No newline at end of file diff --git a/build/admin/flags/templates/adminflagserrors.php b/build/admin/flags/templates/adminflagserrors.php deleted file mode 100644 index aacacf277a..0000000000 --- a/build/admin/flags/templates/adminflagserrors.php +++ /dev/null @@ -1,15 +0,0 @@ -getRedirectedMem('errors'); -if ($errors) { - echo '
    '; - foreach($errors as $error) { - echo '

    ' . $this->words->get($error) . '

    '; - } - echo '
    '; -} \ No newline at end of file diff --git a/build/admin/flags/templates/adminflagslistflags.column_col3.php b/build/admin/flags/templates/adminflagslistflags.column_col3.php deleted file mode 100644 index f94271b762..0000000000 --- a/build/admin/flags/templates/adminflagslistflags.column_col3.php +++ /dev/null @@ -1,70 +0,0 @@ -getRedirectedMem('vars'); -if ($vars) { - // overwrite the vars - $this->vars = $vars; - $this->flagsWithMembers = $this->getRedirectedMem('flagsWithMembers'); -} - -$callbackTags = $this->layoutkit->formkit->setPostCallback('AdminFlagsController', 'listFlagsCallback'); -$layoutbits = new MOD_layoutbits(); -?> -
    -
    - - - - flagsSelect($this->flags, $this->vars['flagid']) ?> - - vars['history'])) ? 'checked="checked' : '' ?> /> - - - "/>flushBuffer(); ?> - -
    - - - - - - - - -flagsWithMembers as $flagId => $details) { - ?> - - - Members as $id => $memberDetails) { - $ss = ($memberDetails->level == 0) ? '' : ''; - $se = ($memberDetails->level == 0) ? '' : ''; - ?> - - - - - - - - - -
    get('AdminFlagsFlag') ?>get('AdminFlagsUsername') ?>get('AdminFlagsLevel') ?>get('AdminFlagsComment') ?>
    flags[$flagId]->Name ?> - PIC_30_30($memberDetails->Username) ?>
    - Username ?>
    - Status ?> - Last login: LastLogin ?> -
    level . $se ?>comment . $se ?> - level <> 0) { ?> - - - -
    -
    \ No newline at end of file diff --git a/build/admin/flags/templates/adminflagslistmembers.column_col3.helper.php b/build/admin/flags/templates/adminflagslistmembers.column_col3.helper.php deleted file mode 100644 index 788a503fd2..0000000000 --- a/build/admin/flags/templates/adminflagslistmembers.column_col3.helper.php +++ /dev/null @@ -1,15 +0,0 @@ -'; - $select .= ''; - foreach($members as $username => $member) { - $select .= ''; - } - $select .= ''; - return $select; -} \ No newline at end of file diff --git a/build/admin/flags/templates/adminflagslistmembers.column_col3.php b/build/admin/flags/templates/adminflagslistmembers.column_col3.php deleted file mode 100644 index 03dd28d6ce..0000000000 --- a/build/admin/flags/templates/adminflagslistmembers.column_col3.php +++ /dev/null @@ -1,73 +0,0 @@ -getRedirectedMem('vars'); -if ($vars) { - // overwrite the vars - $this->vars = $vars; - $this->members = $this->getRedirectedMem('members'); - $this->membersWithFlags = $this->getRedirectedMem('membersWithFlags'); -} - -$callbackTags = $this->layoutkit->formkit->setPostCallback('AdminFlagsController', 'listMembersCallback'); -$layoutbits = new MOD_layoutbits(); - -?> -
    -
    - - - - members, $this->vars['member']) ?> - - vars['history'])) ? 'checked="checked' : '' ?> /> - - - "/>flushBuffer(); ?> -
    -
    -
    - - - - - - - -membersWithFlags as $username => $details){ - ?> - - Flags as $id => $flag) { - $ss = ($flag->level == 0) ? '' : ''; - $se = ($flag->level == 0) ? '' : ''; - ?> - - - - - - - -
    get('AdminFlagsUsername') ?>get('AdminFlagsFlag') ?>get('AdminFlagsLevel') ?>get('AdminFlagsComment') ?>
    PIC_50_50($username, 'class="profileimg"'); ?>
    -
    - Status ?>
    - Last login: LastLogin ?>
    - - - getSilent('AdminFlagsAssignFlag') ?>flushBuffer() ?>
    flags[$id]->Name . $se ?>level . $se ?>comment ?> - level <> 0) : ?> - - -
    -
    diff --git a/build/admin/flags/templates/adminflagsoverview.column_col3.php b/build/admin/flags/templates/adminflagsoverview.column_col3.php deleted file mode 100644 index 6880250cf9..0000000000 --- a/build/admin/flags/templates/adminflagsoverview.column_col3.php +++ /dev/null @@ -1,16 +0,0 @@ - -
    -
    -flags as $flag) : ?> -
    Name ?>
    -
    Description ?>
    - -
    -
    \ No newline at end of file diff --git a/build/admin/flags/templates/adminflagsremove.column_col3.php b/build/admin/flags/templates/adminflagsremove.column_col3.php deleted file mode 100644 index 9faaf09608..0000000000 --- a/build/admin/flags/templates/adminflagsremove.column_col3.php +++ /dev/null @@ -1,61 +0,0 @@ - or -write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. - -*/ -$vars = $this->getRedirectedMem('vars'); -if ($vars) { - // overwrite the vars - $this->vars = $vars; -} - -include 'adminflagserrors.php'; - -$callbackTags = $this->layoutkit->formkit->setPostCallback('AdminFlagsController', 'removeCallback'); -?> -
    - - - -
    - - -
    -
    - - flagsSelect($this->flags, $this->vars['flag'], true) ?> -
    -
    - - levelSelect($this->vars['level'], true) ?> -
    -
    - - -
    -
    - - -
    -
    - " />flushBuffer(); ?> -
    -
    diff --git a/build/admin/massmail/adminmassmail.ctrl.php b/build/admin/massmail/adminmassmail.ctrl.php index 2f9b031fd2..7eb69cc2a1 100644 --- a/build/admin/massmail/adminmassmail.ctrl.php +++ b/build/admin/massmail/adminmassmail.ctrl.php @@ -52,7 +52,7 @@ public function __construct() * */ public function massmail() { - list($member, $rights) = $this->checkRights('MassMail', self::MASSMAILEDIT); + [$member, $rights] = $this->checkRights('MassMail'); $page = new AdminMassmailPage($this->model); return $page; } @@ -76,11 +76,11 @@ public function massmailEditCreateCallback(StdClass $args, ReadOnlyObject $actio if ($args->post['Id'] == 0) { $this->model->createMassmail($args->post['Name'], $args->post['Type'], $args->post['Subject'], $args->post['Body'], $args->post['Description']); - $this->session->set( 'AdminMassMailStatus', array( 'Create', $args->post['Name']) ); + $this->session->set( 'AdminMassMailStatus', [ 'Create', $args->post['Name']] ); } else { $this->model->updateMassmail($args->post['Id'], $args->post['Name'], $args->post['Type'], $args->post['Subject'], $args->post['Body']); - $this->session->set( 'AdminMassMailStatus', array( 'Edit', $args->post['Name']) ); + $this->session->set( 'AdminMassMailStatus', [ 'Edit', $args->post['Name']] ); } return 'admin/massmail/create/finish'; } @@ -90,7 +90,7 @@ public function massmailEditCreateCallback(StdClass $args, ReadOnlyObject $actio * */ public function massmailCreate() { - list($member, $rights) = $this->checkRights('MassMail', self::MASSMAILEDIT); + [$member, $rights] = $this->checkRights('MassMail'); $page = new AdminMassmailEditCreatePage($this->model); $page->member = $member; return $page; @@ -101,7 +101,7 @@ public function massmailCreate() { * */ public function massmailDetails() { - list($member, $rights) = $this->checkRights('MassMail', self::MASSMAILEDIT); + [$member, $rights] = $this->checkRights('MassMail'); $id = $this->route_vars['id']; $page = new AdminMassmailDetailsPage($this->model, $id); $page->member = $member; @@ -113,7 +113,7 @@ public function massmailDetails() { * */ public function massmailDetailsMailing() { - list($member, $rights) = $this->checkRights('MassMail', self::MASSMAILEDIT); + [$member, $rights] = $this->checkRights('MassMail'); $id = $this->route_vars['id']; $type = $this->route_vars['type']; $pageno = 1; @@ -130,7 +130,7 @@ public function massmailDetailsMailing() { * */ public function massmailEdit() { - list($member, $rights) = $this->checkRights('MassMail', self::MASSMAILEDIT); + [$member, $rights] = $this->checkRights('MassMail'); $id = $this->route_vars['id']; $page = new AdminMassmailEditCreatePage($this->model, $id); $page->member = $member; @@ -142,7 +142,7 @@ public function massmailEdit() { * * @return string json encoded list of admin units */ - public function getAdminUnits() { + public function getAdminUnits(): never { $countrycode = $this->route_vars['countrycode']; $adminunits = $this->model->getAdminUnits($countrycode); header('Content-type: application/json'); @@ -155,7 +155,7 @@ public function getAdminUnits() { * * @return string json encoded list of places */ - public function getPlaces() { + public function getPlaces(): never { $countrycode = $this->route_vars['countrycode']; $adminunit = $this->route_vars['adminunit']; $places = $this->model->getPlaces($countrycode, $adminunit); @@ -184,8 +184,8 @@ public function massmailEnqueueCallback(StdClass $args, ReadOnlyObject $action, } $count = $this->model->enqueueMassMail($args->post); $massmail = $this->model->getMassMail($args->post['id']); - $this->session->set( 'AdminMassMailStatus', array( 'Enqueue', $massmail->Name, $count) ); - return $this->router->url('admin_massmail', array(), false); + $this->session->set( 'AdminMassMailStatus', [ 'Enqueue', $massmail->Name, $count] ); + return $this->router->url('admin_massmail', [], false); } /** @@ -193,7 +193,7 @@ public function massmailEnqueueCallback(StdClass $args, ReadOnlyObject $action, * */ public function massmailEnqueue() { - list($member, $rights) = $this->checkRights('MassMail', self::MASSMAILENQUEUE); + [$member, $rights] = $this->checkRights('MassMail'); $id = $this->route_vars['id']; $massmail = $this->model->getMassmail($id); $page = new AdminMassmailEnqueuePage($this->model, $massmail); @@ -208,11 +208,11 @@ public function massmailEnqueue() { * */ public function massmailUnqueue() { - list($member, $rights) = $this->checkRights('MassMail', self::MASSMAILENQUEUE); + [$member, $rights] = $this->checkRights('MassMail'); $id = $this->route_vars['id']; $count = $this->model->unqueueMassMail($id); $massmail = $this->model->getMassMail($id); - $this->session->set( 'AdminMassMailStatus', array( 'Unqueue', $massmail->Name, $count) ); + $this->session->set( 'AdminMassMailStatus', [ 'Unqueue', $massmail->Name, $count] ); $this->redirectAbsolute($this->router->url('admin_massmail')); } @@ -221,11 +221,11 @@ public function massmailUnqueue() { * */ public function massmailTrigger() { - list($member, $rights) = $this->checkRights('MassMail', self::MASSMAILTRIGGER); + [$member, $rights] = $this->checkRights('MassMail'); $id = $this->route_vars['id']; $count = $this->model->triggerMassMail($id); $massmail = $this->model->getMassMail($id); - $this->session->set( 'AdminMassMailStatus', array( 'Trigger', $massmail->Name, $count) ); + $this->session->set( 'AdminMassMailStatus', [ 'Trigger', $massmail->Name, $count] ); $this->redirectAbsolute($this->router->url('admin_massmail')); } @@ -234,11 +234,11 @@ public function massmailTrigger() { * */ public function massmailUntrigger() { - list($member, $rights) = $this->checkRights('MassMail', self::MASSMAILTRIGGER); + [$member, $rights] = $this->checkRights('MassMail'); $id = $this->route_vars['id']; $count = $this->model->untriggerMassMail($id); $massmail = $this->model->getMassMail($id); - $this->session->set( 'AdminMassMailStatus', array( 'Untrigger', $massmail->Name, $count) ); + $this->session->set( 'AdminMassMailStatus', [ 'Untrigger', $massmail->Name, $count] ); $this->redirectAbsolute($this->router->url('admin_massmail')); } } diff --git a/build/admin/massmail/adminmassmail.model.php b/build/admin/massmail/adminmassmail.model.php index ad89fa5e68..409a266664 100644 --- a/build/admin/massmail/adminmassmail.model.php +++ b/build/admin/massmail/adminmassmail.model.php @@ -207,8 +207,8 @@ public function getMassmailRecipientsInfo($id, $type, $start, $limit) { } // get language names from DB - $languages = array(); - $languagesnames = array(); + $languages = []; + $languagesnames = []; foreach($mmris as $mm) { $languages[] = $mm->LanguageId; } @@ -255,7 +255,7 @@ public function getMassmailRecipientsCount($id, $type) { } public function createMassmail($name, $type, $subject, $body, $description) { - $name = $this->dao->escape(strtolower($name)); + $name = $this->dao->escape(strtolower((string) $name)); // first create entry in the broadcast table $query = " INSERT INTO @@ -346,12 +346,12 @@ public function updateMassmail($id, $name, $type, $subject, $body) { public function massmailEditCreateVarsOk(&$vars) { $id = $vars['Id']; - $name = strtolower($vars['Name']); + $name = strtolower((string) $vars['Name']); $subject = $vars['Subject']; $body = $vars['Body']; $description = $vars['Description']; $type = $vars['Type']; - $errors = array(); + $errors = []; if (empty($name)) { $errors[] = 'AdminMassMailNameEmpty'; } @@ -436,7 +436,7 @@ public function getEnqueueAction($vars) { } public function massmailEnqueueVarsOk(&$vars) { - $errors = array(); + $errors = []; $action = $this->getEnqueueAction($vars); switch($action) { case 'enqueueMembers': @@ -711,9 +711,9 @@ public function enqueueMassmail($vars) { $action = $this->getEnqueueAction($vars); switch($action) { case 'enqueueMembers': - $usernames = array(); + $usernames = []; if ($vars['members-type'] == 'usernames') { - $usernames = explode(";", $vars['usernames']); + $usernames = explode(";", (string) $vars['usernames']); } if (empty($vars['max-messages'])) { $maxmessages = 0; diff --git a/build/admin/massmail/pages/adminmassmail.page.php b/build/admin/massmail/pages/adminmassmail.page.php index 82e2f04c9f..ca7b2c7278 100644 --- a/build/admin/massmail/pages/adminmassmail.page.php +++ b/build/admin/massmail/pages/adminmassmail.page.php @@ -43,6 +43,7 @@ public function __construct($model) { $this->setCurrent('AdminMassMail'); } + #[\Override] public function teaserHeadline() { return "{$this->words->get('AdminTools')} » {$this->words->get('AdminMassMail')}"; diff --git a/build/admin/massmail/pages/adminmassmailbase.page.php b/build/admin/massmail/pages/adminmassmailbase.page.php index 3f928769a8..79b66ff6b0 100644 --- a/build/admin/massmail/pages/adminmassmailbase.page.php +++ b/build/admin/massmail/pages/adminmassmailbase.page.php @@ -32,10 +32,10 @@ class AdminMassmailBasePage extends AdminBasePage { - protected $sidebar = array( + protected $sidebar = [ 'AdminMassMail' => 'admin/massmail', 'AdminMassMailCreate' => 'admin/massmail/create', - ); + ]; protected $current = ''; @@ -53,16 +53,16 @@ public function __construct($model) { $this->member = $this->model->getLoggedInMember(); $this->rights = $this->member->getOldRights(); $scope = $this->rights["MassMail"]["Scope"]; - $this->canChangeType = (stripos($scope, '"changetype"') !== false); + $this->canChangeType = (stripos((string) $scope, '"changetype"') !== false); // newsletter types - $this->newsletterSpecific = (stripos($scope, '"specific"') !== false); - $this->newsletterGeneral = (stripos($scope, '"general"') !== false); - $this->loginReminder = (stripos($scope, '"remindtologin"') !== false); - $this->mailToConfirmReminder = (stripos($scope, '"mailtoconfirmreminder"') !== false); - $this->correctBirthDate = (stripos($scope, '"correctbirthdate"') !== false); - $this->termsOfUse = (stripos($scope, '"termsofuse"') !== false); - $this->suspendAfter5Reminders = (stripos($scope, '"suspendafter5reminders"') !== false); + $this->newsletterSpecific = (stripos((string) $scope, '"specific"') !== false); + $this->newsletterGeneral = (stripos((string) $scope, '"general"') !== false); + $this->loginReminder = (stripos((string) $scope, '"remindtologin"') !== false); + $this->mailToConfirmReminder = (stripos((string) $scope, '"mailtoconfirmreminder"') !== false); + $this->correctBirthDate = (stripos((string) $scope, '"correctbirthdate"') !== false); + $this->termsOfUse = (stripos((string) $scope, '"termsofuse"') !== false); + $this->suspendAfter5Reminders = (stripos((string) $scope, '"suspendafter5reminders"') !== false); // if no type is set assume all if (!($this->newsletterSpecific || $this->newsletterGeneral || $this->loginReminder @@ -76,38 +76,38 @@ public function __construct($model) { $this->termsOfUse = true; $this->suspendAfter5Reminders = true; } - $this->enqueueGroups = array(); - $this->enqueueCountries = array(); - $this->canEnqueueMembers = (stripos($scope, '"members"') !== false); - $this->canEnqueueLocation = (stripos($scope, '"location"') !== false) - || (stripos($scope, '"location:') !== false); + $this->enqueueGroups = []; + $this->enqueueCountries = []; + $this->canEnqueueMembers = (stripos((string) $scope, '"members"') !== false); + $this->canEnqueueLocation = (stripos((string) $scope, '"location"') !== false) + || (stripos((string) $scope, '"location:') !== false); if ($this->canEnqueueLocation) { - $startpos = stripos($scope, '"location:') + 10; + $startpos = stripos((string) $scope, '"location:') + 10; if ($startpos !== false) { - $endpos = strpos($scope, '"', $startpos); + $endpos = strpos((string) $scope, '"', $startpos); if ($endpos === false) { - $endpos = strlen($scope); + $endpos = strlen((string) $scope); } - $countries = substr($scope, $startpos, $endpos - $startpos); + $countries = substr((string) $scope, $startpos, $endpos - $startpos); $this->enqueueCountries = explode(",", trim($countries)); } } - $this->canEnqueueGroup = (stripos($scope, "group") !== false) - || (stripos($scope, "group:") !== false); + $this->canEnqueueGroup = (stripos((string) $scope, "group") !== false) + || (stripos((string) $scope, "group:") !== false); if ($this->canEnqueueGroup) { - $startpos = stripos($scope, '"group:') + 7; + $startpos = stripos((string) $scope, '"group:') + 7; if ($startpos !== false) { - $endpos = strpos($scope, '"', $startpos); + $endpos = strpos((string) $scope, '"', $startpos); if ($endpos === false) { - $endpos = strlen($scope); + $endpos = strlen((string) $scope); } - $groups = substr($scope, $startpos, $endpos - $startpos); + $groups = substr((string) $scope, $startpos, $endpos - $startpos); $this->enqueueGroups = explode(",", trim($groups)); } } - $this->canEnqueueReminder = (stripos($scope, "reminder") !== false); - $this->canEnqueueMailToConfirmReminder = (stripos($scope, "mailtoconfirmreminder") !== false); - $this->canEnqueueTermsOfUse = (stripos($scope, "termsofuse") !== false); + $this->canEnqueueReminder = (stripos((string) $scope, "reminder") !== false); + $this->canEnqueueMailToConfirmReminder = (stripos((string) $scope, "mailtoconfirmreminder") !== false); + $this->canEnqueueTermsOfUse = (stripos((string) $scope, "termsofuse") !== false); // if no scope was given for enqueueing assume full scope $enqueueAny = $this->canEnqueueMembers || $this->canEnqueueLocation || $this->canEnqueueGroup @@ -133,7 +133,7 @@ public function __construct($model) { $this->canTrigger = true; } - if ((stripos($scope, "All") !== false)) { + if ((stripos((string) $scope, "All") !== false)) { $this->canEnqueueMembers = true; $this->canEnqueueLocation = true; $this->canEnqueueGroup = true; @@ -153,6 +153,7 @@ public function __construct($model) { } } + #[\Override] protected function getSubmenuItems() { $items = []; diff --git a/build/admin/massmail/pages/adminmassmaildetails.page.php b/build/admin/massmail/pages/adminmassmaildetails.page.php index a38293e558..7e88f9f716 100644 --- a/build/admin/massmail/pages/adminmassmaildetails.page.php +++ b/build/admin/massmail/pages/adminmassmaildetails.page.php @@ -33,7 +33,6 @@ class AdminMassmailDetailsPage extends AdminMassmailBasePage { protected $ROWSPERPAGE = 20; - protected $id; protected $model; protected $massmail; protected $type; @@ -41,20 +40,20 @@ class AdminMassmailDetailsPage extends AdminMassmailBasePage protected $count; protected $details; - public function __construct($model, $id, $detail = false, $pageno = false) { + public function __construct($model, protected $id, $detail = false, $pageno = false) { parent::__construct($model); - $this->id = $id; $this->model = $model; - $this->massmail = $model->getMassMail($id); + $this->massmail = $model->getMassMail($this->id); $this->detail = $detail; if ($detail) { - $this->count = $this->model->getMassmailRecipientsCount( $id, $detail); - $this->details = $this->model->getMassmailRecipientsInfo( $id, $detail, + $this->count = $this->model->getMassmailRecipientsCount( $this->id, $detail); + $this->details = $this->model->getMassmailRecipientsInfo( $this->id, $detail, ($pageno -1 ) * $this->ROWSPERPAGE, $this->ROWSPERPAGE); } $this->setCurrent('AdminMassMailDetails'); } + #[\Override] public function teaserHeadline() { return '' . $this->words->get('AdminTools') . " " . ' » ' . $this->words->get('AdminMassMail') . "" diff --git a/build/admin/massmail/pages/adminmassmaileditcreate.page.php b/build/admin/massmail/pages/adminmassmaileditcreate.page.php index e3562651c7..03f48c6a3b 100644 --- a/build/admin/massmail/pages/adminmassmaileditcreate.page.php +++ b/build/admin/massmail/pages/adminmassmaileditcreate.page.php @@ -64,6 +64,7 @@ public function __construct($model, $id = 0) { $this->addStylesheet('build/roxeditor.css'); } + #[\Override] public function teaserHeadline() { if ($this->id == 0) { $editcreate = 'create'; diff --git a/build/admin/massmail/pages/adminmassmailenqueue.page.php b/build/admin/massmail/pages/adminmassmailenqueue.page.php index 48b78c348d..7390fd3c2a 100644 --- a/build/admin/massmail/pages/adminmassmailenqueue.page.php +++ b/build/admin/massmail/pages/adminmassmailenqueue.page.php @@ -41,6 +41,7 @@ public function __construct($model, $massmail) { $this->setCurrent('AdminMassMailEnqueue'); } + #[\Override] public function teaserHeadline() { return '' . $this->words->get('AdminTools') . " " . ' » ' . $this->words->get('AdminMassMail') . "" diff --git a/build/admin/massmail/templates/adminmassmaileditcreate.column_col3.php b/build/admin/massmail/templates/adminmassmaileditcreate.column_col3.php index 92ce35aa4d..dddfa0f083 100644 --- a/build/admin/massmail/templates/adminmassmaileditcreate.column_col3.php +++ b/build/admin/massmail/templates/adminmassmaileditcreate.column_col3.php @@ -43,9 +43,9 @@ $this->words->getSilent('AdminMassMailEditSelectType') - ); + ]; if ($this->newsletterSpecific) { $options["Specific"] = $this->words->getSilent('AdminMassMailEditTypeSpecific'); } diff --git a/build/admin/newmembers/adminnewmembers.ctrl.php b/build/admin/newmembers/adminnewmembers.ctrl.php index 867eb07f5f..72d0e4e263 100644 --- a/build/admin/newmembers/adminnewmembers.ctrl.php +++ b/build/admin/newmembers/adminnewmembers.ctrl.php @@ -44,6 +44,7 @@ public function __construct() { $this->model = new AdminNewMembersModel(); } + #[\Override] public function __destruct() { unset($this->model); } @@ -65,7 +66,7 @@ public function listMembersCallback(StdClass $args, ReadOnlyObject $action, public function listMembers() { - list($loggedInMember, $rights) = $this->CheckRights(); + [$loggedInMember, $rights] = $this->CheckRights(); $safetyTeamOrAdmin = false; if (isset($rights['SafetyTeam']) || isset($rights['Checker'])) { $safetyTeamOrAdmin = true; diff --git a/build/admin/newmembers/adminnewmembers.model.php b/build/admin/newmembers/adminnewmembers.model.php index bdf25261ab..1bd0f73b4e 100644 --- a/build/admin/newmembers/adminnewmembers.model.php +++ b/build/admin/newmembers/adminnewmembers.model.php @@ -41,7 +41,7 @@ private function FindTrad($IdTrad,$ReplaceWithBr=false) { if (isset ($row->Sentence) == "") { //LogStr("Blank Sentence for language " . $IdLanguage . " with MembersTrads.IdTrad=" . $IdTrad, "Bug"); } else { - return (strip_tags($this->ReplaceWithBr($row->Sentence,$ReplaceWithBr), $AllowedTags)); + return (strip_tags((string) $this->ReplaceWithBr($row->Sentence,$ReplaceWithBr), $AllowedTags)); } } // Try default eng @@ -61,7 +61,7 @@ private function FindTrad($IdTrad,$ReplaceWithBr=false) { if (isset ($row->Sentence) == "") { //LogStr("Blank Sentence for language 1 (eng) with memberstrads.IdTrad=" . $IdTrad, "Bug"); } else { - return (strip_tags($this->ReplaceWithBr($row->Sentence,$ReplaceWithBr), $AllowedTags)); + return (strip_tags((string) $this->ReplaceWithBr($row->Sentence,$ReplaceWithBr), $AllowedTags)); } } // Try first language available @@ -82,7 +82,7 @@ private function FindTrad($IdTrad,$ReplaceWithBr=false) { if (isset ($row->Sentence) == "") { //LogStr("Blank Sentence (any language) memberstrads.IdTrad=" . $IdTrad, "Bug"); } else { - return (strip_tags($this->ReplaceWithBr($row->Sentence,$ReplaceWithBr), $AllowedTags)); + return (strip_tags((string) $this->ReplaceWithBr($row->Sentence,$ReplaceWithBr), $AllowedTags)); } } return (""); @@ -132,7 +132,7 @@ public function getMembersCount($safetyTeamOrAdmin) { * @throws PException */ public function getMembers($first, $count, $safetyTeamOrAdmin) { - $langarr = explode('-', $this->session->get('lang')); + $langarr = explode('-', (string) $this->session->get('lang')); $lang = $langarr[0]; // First get current page and limits @@ -186,9 +186,9 @@ public function getMembers($first, $count, $safetyTeamOrAdmin) { $loggedInMember = $this->getLoggedInMember(); - $members = array(); - $geonameIds = array(); - $countryIds = array(); + $members = []; + $geonameIds = []; + $countryIds = []; $layoutBits = new MOD_layoutbits(); foreach($rawMembers as $member) { $geonameIds[$member->geonameId] = $member->geonameId; @@ -249,7 +249,7 @@ public function getMembers($first, $count, $safetyTeamOrAdmin) { ORDER BY geonameId, source, ispreferred DESC, isshort DESC"; $rawNames = $this->bulkLookup($query); - $names = array(); + $names = []; foreach($rawNames as $rawName) { if (!isset($names[$rawName->geonameId])) { $names[$rawName->geonameId] = $rawName->name; @@ -273,7 +273,7 @@ public function getMembers($first, $count, $safetyTeamOrAdmin) { ORDER BY geonameId, source, ispreferred DESC, isshort DESC"; $countryRawNames = $this->bulkLookup($query); - $countryNames = array(); + $countryNames = []; foreach($countryRawNames as $countryRawName) { if (!isset($countryNames[$countryRawName->countryCode])) { $countryNames[$countryRawName->countryCode] = $countryRawName->country; diff --git a/build/admin/newmembers/pages/adminnewmembersbase.page.php b/build/admin/newmembers/pages/adminnewmembersbase.page.php index a04a73a532..856779fb29 100644 --- a/build/admin/newmembers/pages/adminnewmembersbase.page.php +++ b/build/admin/newmembers/pages/adminnewmembersbase.page.php @@ -17,6 +17,7 @@ public function __construct() { $this->_statuses = $this->model->getStatuses(); } + #[\Override] public function teaserHeadline() { $headline = parent::teaserHeadline(); @@ -30,6 +31,7 @@ protected function setCurrent($current) { $this->_current = $current; } + #[\Override] protected function getStylesheets() { $stylesheets = parent::getStylesheets(); diff --git a/build/admin/newmembers/pages/adminnewmemberslistmembers.page.php b/build/admin/newmembers/pages/adminnewmemberslistmembers.page.php index 950b972b14..91e47aa212 100644 --- a/build/admin/newmembers/pages/adminnewmemberslistmembers.page.php +++ b/build/admin/newmembers/pages/adminnewmemberslistmembers.page.php @@ -13,12 +13,14 @@ public function __construct($model = false) { $this->setCurrent('AdminFlagsListMembers'); } + #[\Override] public function getLateLoadScriptFiles() { $scripts = parent::getLateLoadScriptfiles(); // $scripts[] = 'adminflagstooltip.js'; return $scripts; } + #[\Override] protected function getStylesheets() { $stylesheets = parent::getStylesheets(); $stylesheets[] = 'styles/css/minimal/screen/basemod_minimal_col3.css'; @@ -36,7 +38,7 @@ public function statusForm($memberId, $memberStatus) $layoutkit = $this->layoutkit; $formkit = $layoutkit->formkit; $callbackTags = $formkit->setPostCallback('AdminNewMembersController', 'setStatusCallback'); - if (($logged_member = $this->model->getLoggedInMember()) && $logged_member->hasOldRight(array('Admin' => '', 'SafetyTeam' => '', 'Accepter' => '', 'Profile' => ''))) { + if (($logged_member = $this->model->getLoggedInMember()) && $logged_member->hasOldRight(['Admin' => '', 'SafetyTeam' => '', 'Accepter' => '', 'Profile' => ''])) { $form .= '
    ' . $callbackTags; $form .= ''; $form .= ''; return $select; diff --git a/build/admin/pages/adminbase.page.php b/build/admin/pages/adminbase.page.php index 4f0fcf6e6e..9d7dc16913 100644 --- a/build/admin/pages/adminbase.page.php +++ b/build/admin/pages/adminbase.page.php @@ -46,6 +46,7 @@ public function __construct($model = false) { } } + #[\Override] protected function getPageTitle() { return 'Volunteer Pages - BeWelcome'; @@ -56,14 +57,16 @@ public function teaserHeadline() return "{$this->words->get('AdminTools')}"; } + #[\Override] protected function getStylesheets() { $stylesheets = parent::getStylesheets(); $stylesheets[] = 'styles/css/minimal/screen/custom/admin.css?2'; return $stylesheets; } + #[\Override] protected function getColumnNames() { - return array('col1', 'col3'); + return ['col1', 'col3']; } } diff --git a/build/admin/pages/adminlogs.page.php b/build/admin/pages/adminlogs.page.php index 42f149febe..7c0f520ae7 100644 --- a/build/admin/pages/adminlogs.page.php +++ b/build/admin/pages/adminlogs.page.php @@ -32,21 +32,11 @@ class AdminLogsPage extends AdminBasePage { + #[\Override] public function teaserHeadline() { return "{$this->words->get('AdminTools')} » {$this->words->get('AdminLogs')}"; } - - /** - * determines the output displayed on the page - * errors = php error log - * exceptions = exception log - * mysql = mysql log - * apache = apache error log - * - * @var string - */ - private $type; /** * name of log file to read from @@ -69,28 +59,23 @@ public function teaserHeadline() * @access public * @throws Exception */ - public function __construct($type) + public function __construct(/** + * determines the output displayed on the page + * errors = php error log + * exceptions = exception log + * mysql = mysql log + * apache = apache error log + */ + private $type) { parent::__construct(); - $this->type = $type; - - switch (strtolower($type)) - { - case 'php': - $this->logfile = '../../logs/php_errors.log'; - break; - case 'exception': - $this->logfile = '../../logs/exception.log'; - break; - case 'mysql': - $this->logfile = '../../logs/mysql/mysql-slow.log'; - break; - case 'apache': - $this->logfile = '../../logs/www.bewelcome.org-error.log'; - break; - default: - throw new Exception('Bad type specified for log in AdminLogsPage'); - } + $this->logfile = match (strtolower($this->type)) { + 'php' => '../../logs/php_errors.log', + 'exception' => '../../logs/exception.log', + 'mysql' => '../../logs/mysql/mysql-slow.log', + 'apache' => '../../logs/www.bewelcome.org-error.log', + default => throw new Exception('Bad type specified for log in AdminLogsPage'), + }; $this->logname = basename($this->logfile); } diff --git a/build/admin/pages/adminspam.page.php b/build/admin/pages/adminspam.page.php index 589847f6d5..030658fd44 100755 --- a/build/admin/pages/adminspam.page.php +++ b/build/admin/pages/adminspam.page.php @@ -33,6 +33,7 @@ class AdminSpamPage extends AdminBasePage { + #[\Override] public function teaserHeadline() { return "{$this->words->get('AdminTools')} » {$this->words->get('AdminSpam')}"; diff --git a/build/admin/pages/tempvolstart.page.php b/build/admin/pages/tempvolstart.page.php index 0ca8d3eff5..bf6773917d 100644 --- a/build/admin/pages/tempvolstart.page.php +++ b/build/admin/pages/tempvolstart.page.php @@ -32,20 +32,23 @@ class TempVolStartPage extends AdminBasePage { + #[\Override] protected function getPageTitle() { return 'Volunteer Pages - BeWelcome'; } + #[\Override] public function teaserHeadline() { return "{$this->words->get('VolunteerPage')}"; } + #[\Override] protected function getColumnNames() { // we don't need the other columns - return array('col3'); + return ['col3']; } protected function column_col3() { diff --git a/build/admin/rights/adminrights.ctrl.php b/build/admin/rights/adminrights.ctrl.php deleted file mode 100644 index fb4a40b05a..0000000000 --- a/build/admin/rights/adminrights.ctrl.php +++ /dev/null @@ -1,339 +0,0 @@ - or -write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. - -*/ - -/** - * @author shevek - */ - -/** - * adminrights controller - * deals with actions that are available exclusively for rights managers - * - * @package apps - * @subpackage Admin - */ -class AdminRightsController extends AdminBaseController -{ - private $model; - - public function __construct() { - parent::__construct(); - $this->model = new AdminRightsModel(); - } - - public function __destruct() { - unset($this->model); - } - - public function assignCallback(StdClass $args, ReadOnlyObject $action, - ReadWriteObject $mem_redirect, ReadWriteObject $mem_resend) - { - $vars = $args->post; - $errors = $this->model->checkAssignVarsOk($vars); - if (count($errors) > 0) { - $mem_redirect->errors = $errors; - $mem_redirect->vars = $args->post; - return false; - } - $this->model->assignRight($vars); - $rights = $this->model->getRights(); - $right = $rights[$vars['rightid']]; - $this->setFlashNotice($this->getWords()->get('AdminRightsRightAssigned', $vars['username'], $right->Name)); - - return $this->router->url('admin_rights_member', array("username" => $vars['username']), false); - } - - public function assign() { - $this->checkRights('Rights'); - $member = false; - if (isset($this->route_vars['username'])) { - $temp = new Member(); - $member = $temp->findByUsername($this->route_vars['username']); - }; - $page = new AdminRightsAssignPage(); - $page->member = $member; - $page->vars = array( - 'username' => ($member ? $member->Username : ''), - 'rightid' => 0, - 'level' => 0, - 'scope' => '', - 'comment' => ''); - $page->rights = $this->model->getRights(true, $member); - return $page; - } - - public function listMembersCallback(StdClass $args, ReadOnlyObject $action, - ReadWriteObject $mem_redirect, ReadWriteObject $mem_resend) - { - $vars = $args->post; - $member = false; - if (isset($vars['member']) && $vars['member'] <> '0') { - $temp = new Member(); - $member = $temp->findById($vars['member']); - } - $history = false; - if (isset($vars['history']) && $vars['history'] <> '0') { - $history= true; - } - $mem_redirect->vars = $vars; - $mem_redirect->members = $this->model->getMembersWithRights(false, $history); - // get list of members with rights (as assigned, filter by $member if set) - $mem_redirect->membersWithRights = $this->model->getMembersWithRights($member, $history); - } - - public function listMembers() - { - $this->checkRights('Rights'); - $member = false; - if (isset($this->route_vars['username'])) { - $temp = new Member(); - $member = $temp->findByUsername($this->route_vars['username']); - }; - $page = new AdminRightsListMembersPage(); - $page->vars = array( - 'member' => ($member ? $member->id : 0) - ); - $page->current = 'AdminRightsListMembers'; - $page->rights = $this->model->getRights(); - // get list of members (with assigned rights) - $page->members = $this->model->getMembersWithRights(); - // get list of members with rights (as assigned, filter by $member if set) - $page->membersWithRights = $this->model->getMembersWithRights($member); - if (($member) && (count($page->membersWithRights) == 0)) { - $this->redirectAbsolute('/admin/rights/assign/' . $this->route_vars['username']); - } - return $page; - } - - public function listRightsCallback(StdClass $args, ReadOnlyObject $action, - ReadWriteObject $mem_redirect, ReadWriteObject $mem_resend) - { - $vars = $args->post; - $rightId = false; - if (isset($vars['rightid']) && $vars['rightid'] <> '0') { - $rightId = $vars['rightid']; - } - $history = false; - if (isset($vars['history']) && $vars['history'] <> '0') { - $history = true; - } - $mem_redirect->vars = $vars; - $mem_redirect->rightsWithMembers = $this->model->getRightsWithMembers($rightId, $history); - return true; - } - - public function listRights() - { - $this->checkRights('Rights'); - $rightId = false; - if (isset($this->route_vars['id']) && is_numeric($this->route_vars['id'])) { - $rightId = $this->route_vars['id']; - }; - $page = new AdminRightsListRightsPage(); - $page->rights = $this->model->getRights(); - $page->vars = array( - 'rightid' => $rightId - ); - $page->rightsWithMembers = $this->model->getRightsWithMembers($rightId); - return $page; - } - - public function overview() { - $this->checkRights('Rights'); - $page = new AdminRightsOverviewPage(); - $page->current = 'AdminRightsOverview'; - $page->rights = $this->model->getRights(); - return $page; - } - - public function tooltip() { - $id = $this->args_vars->get['tooltip']; - header('Content-type: text/html, charset=utf-8'); - $javascript = $this->model->getWords()->get($id); - echo $javascript . "\n"; - exit; - } - - public function editCallback(StdClass $args, ReadOnlyObject $action, - ReadWriteObject $mem_redirect, ReadWriteObject $mem_resend) - { - $vars = $args->post; - $errors = $this->model->checkEditVarsOk($vars); - if (count($errors) > 0) { - $mem_redirect->errors = $errors; - - // Set variables (necessary due to disabled flag) - $vars['right'] = $vars['rightid']; - - $mem_redirect->vars = $vars; - return false; - } - $this->model->edit($vars); - $this->setFlashNotice($this->getWords()->get('AdminRightsRightEdited')); - return true; - } - - public function edit() - { - $this->checkRights('Rights'); - - $rightId = $this->route_vars['id']; - $username = $this->route_vars['username']; - // Check if right and user exist and if right is assigned to user at all; redirect if not - $right = new Right($rightId); - if (!$right) { - $this->redirectAbsolute($this->router->url('admin_rights_overview')); - } - $temp = new Member(); - $member = $temp->findByUsername($username); - if (!$member) { - $this->redirectAbsolute($this->router->url('admin_rights_overview')); - } - $assigned = $right->getRightForMember($member); - if (!$assigned) { - $this->redirectAbsolute($this->router->url('admin_rights_overview')); - } - - $page = new AdminRightsEditPage(); - $page->rights = $this->model->getRights(true); - $vars = array( - 'username' => $username, - 'right' => $rightId, - 'level' => $assigned->Level, - 'scope' => $assigned->Scope, - 'comment' => $assigned->Comment - ); - $page->vars = $vars; - return $page; - } - - public function removeCallback(StdClass $args, ReadOnlyObject $action, - ReadWriteObject $mem_redirect, ReadWriteObject $mem_resend) - { - $vars = $args->post; - $rights = $this->model->getRights(); - $right = $rights[$vars['rightid']]; - $this->setFlashNotice($this->getWords()->get('AdminRightsRightRemoved', $vars['username'], $right->Name )); - switch ($vars['redirect']) { - case 'members': - $url = $this->router->url('admin_rights_members', array(), false); - break; - case 'member': - $url = $this->router->url('admin_rights_member', array("username" => $vars['username']), false); - break; - case 'rights': - $url = $this->router->url('admin_rights_rights', array(), false); - break; - case 'right': - $url = $this->router->url('admin_rights_right', array("id" => $vars['right']), false); - break; - default: - $url = $this->router->url('admin_rights', array(), false); - } - $this->model->remove($vars); - return $url; - } - - public function remove() - { - $this->checkRights('Rights'); - $rightId = $this->route_vars['id']; - $username = $this->route_vars['username']; - // Check if right and user exist and if right is assigned to user at all; redirect if not - $right = new Right($rightId); - if (!$right) { - $this->redirectAbsolute($this->router->url('admin_rights_overview')); - } - $temp = new Member(); - $member = $temp->findByUsername($username); - if (!$member) { - $this->redirectAbsolute($this->router->url('admin_rights_overview')); - } - $assigned = $right->getRightForMember($member); - if (!$assigned) { - $this->redirectAbsolute($this->router->url('admin_rights_overview')); - } - $page = new AdminRightsRemovePage(); - - $rights = $this->model->getRights(true); - $page->rights = $rights; - $redirectTo = ''; - if (isset($_SERVER['HTTP_REFERER'])) { - if (strpos($_SERVER['HTTP_REFERER'], "/list/members") !== false) { - $redirectTo = 'members'; - } - if (strpos($_SERVER['HTTP_REFERER'], "/list/member/") !== false) { - $redirectTo = 'member'; - } - if (strpos($_SERVER['HTTP_REFERER'], "/list/rights") !== false) { - $redirectTo = 'rights'; - } - if (strpos($_SERVER['HTTP_REFERER'], "/list/right/") !== false) { - $redirectTo = 'right'; - } - } - $vars = array( - 'username' => $username, - 'right' => $rightId, - 'level' => $assigned->Level, - 'scope' => $assigned->Scope, - 'comment' => $assigned->Comment, - 'redirect' => $redirectTo - ); - $page->vars = $vars; - return $page; - } - - public function createCallback(StdClass $args, ReadOnlyObject $action, - ReadWriteObject $mem_redirect, ReadWriteObject $mem_resend) - { - $vars = $args->post; - $errors = $this->model->checkCreateVarsOk($vars); - if (count($errors) > 0) { - $mem_redirect->errors = $errors; - $mem_redirect->vars = $args->post; - return false; - } - $this->model->createRight($vars); - $this->setFlashNotice($this->getWords()->get('AdminRightsRightCreate', $vars['name'])); - return $this->router->url('admin_rights_overview', array(), false); - } - - public function create() - { - list($loggedInMember, $rights) = $this->checkRights('Rights'); - // Check if member has create right if not redirect to overview - if ((stripos($rights['Rights']['Scope'], 'create') === false - && stripos($rights['Rights']['Scope'], 'all') === false)) { - $this->redirectAbsolute($this->router->url('admin_rights_overview')); - } - $page = new AdminRightsCreatePage(); - $vars = array( - 'name' => '', - 'description' => '' - ); - $page->vars = $vars; - return $page; - } -} \ No newline at end of file diff --git a/build/admin/rights/adminrights.entity.php b/build/admin/rights/adminrights.entity.php deleted file mode 100644 index 5fb72efcc5..0000000000 --- a/build/admin/rights/adminrights.entity.php +++ /dev/null @@ -1,48 +0,0 @@ -findById($rightId); - } - } - - /** - * overloads RoxEntityBase::loadEntity to load related data - * - * @param array $data - * - * @access protected - * @return bool - */ - protected function loadEntity(array $data) - { - if ($status = parent::loadEntity($data)) - { - } - return $status; - } - - public function getRightForMember(Member $member) { - $query = " - SELECT - * - FROM - rightsvolunteers rv - WHERE - rv.IdRight = " . $this->id . " - AND rv.IdMember = " . $member->id . " - "; - return $this->singleLookup($query); - } -} \ No newline at end of file diff --git a/build/admin/rights/adminrights.model.php b/build/admin/rights/adminrights.model.php deleted file mode 100644 index d1f5e3fa32..0000000000 --- a/build/admin/rights/adminrights.model.php +++ /dev/null @@ -1,380 +0,0 @@ - 2 && $countSemiColons <> ($countQuotes / 2)) { - return false; - } - return true; - } - - /** - * @param $vars - * @return array - */ - public function checkAssignVarsOk($vars) { - $errors = array(); - if (empty($vars['username'])) { - $errors[] = 'AdminRightsUsernameEmpty'; - } else { - // check if user name exists - $member = new Member(); - $member = $member->findByUsername($vars['username']); - if (!$member) { - $errors[] = 'AdminRightsUsernameNotExisting'; - } - } - if ($vars['rightid'] == 0) { - $errors[] = 'AdminRightsNoRightSelected'; - } else { - // check if right is already assigned - if ($member) { - $right = new Right($vars['rightid']); - $assigned = $right->getRightForMember($member); - if ($assigned) { - $errors[] = 'AdminRightsAlreadyAssigned'; - } - } - } - if ($vars['level'] == 0) { - $errors[] = 'AdminRightsNoLevelSelected'; - } - if (empty($vars['scope'])) { - $errors[] = 'AdminRightsScopeEmpty'; - } else { - // check if scope is well formed - if (!$this->checkScopeWellFormed($vars['scope'])) { - $errors[] = 'AdminRightsScopeNotWellFormed'; - } - } - if (empty($vars['comment'])) { - $errors[] = 'AdminRightsCommentEmpty'; - } - return $errors; - } - - /** - * @param $vars - */ - public function assignRight($vars) { - $member = new Member(); - $member = $member->findByUsername($vars['username']); - $query = " - INSERT INTO - rightsvolunteers - SET - IdRight = '" . $this->dao->escape($vars['rightid']) . "', - IdMember = '" . $member->id . "', - Scope = '" . $this->dao->escape($vars['scope']) . "', - Level = '" . $this->dao->escape($vars['level']) . "', - Comment = '" . $this->dao->escape($vars['comment']) . "', - created = NOW()"; - $this->dao->query($query); - } - - /** - * get list of members with all assigned rights - * - * @access public - * @return array of members with rights - */ - public function getMembersWithRights($member = false) - { - $query = ' - SELECT - m.Username, - m.id as id, - m.status, - m.LastLogin, - g.Name as PlaceName, - gc.Name as CountryName, - r.id rightId, - rv.Level, - rv.Scope, - rv.Comment - FROM - rights r, - rightsvolunteers rv, - members m, - geonames g, - geonamescountries gc - WHERE - m.Status in (' . MemberStatusType::ACTIVE_ALL . ')'; - if ($member) { - $query .= ' AND m.id = ' . $member->id; - } - $rights = implode("','", $this->getAllowedRights()); - if (!empty($rights)) { - $query .= " - AND - r.Name IN ('" . $rights . "') "; - } - $query .= ' - AND rv.IdMember = m.id - AND rv.IdRight = r.id - AND m.IdCity = g.geonameId - AND g.country = gc.country '; - $query .= ' - ORDER BY - m.Username, - r.Name - '; - $result = $this->bulkLookup($query); - - $membersWithRights = array(); - foreach ($result as $mwr) { - if (!isset($membersWithRights[$mwr->Username])) { - $memberDetails = new stdClass(); - $memberDetails->id = $mwr->id; - $memberDetails->Status = $mwr->status; - $memberDetails->LastLogin = date('Y-m-d', strtotime($mwr->LastLogin)); - $memberDetails->PlaceName = $mwr->PlaceName; - $memberDetails->CountryName = $mwr->CountryName; - $memberDetails->Rights = array(); - $membersWithRights[$mwr->Username] = $memberDetails; - } - $rightDetails = new stdClass(); - $rightDetails->level = $mwr->Level; - $rightDetails->scope = $mwr->Scope; - $rightDetails->comment = $mwr->Comment; - $membersWithRights[$mwr->Username]->Rights[$mwr->rightId] = $rightDetails; - } - return $membersWithRights; - } - - /** - * get list of rights with members with that right - * - * @access public - * @return list of rights with members - */ - public function getRightsWithMembers($rightId = false, $includeLevelZero = false) - { - $query = ' - SELECT - r.id rightId, - rv.Level, - rv.Scope, - rv.Comment, - m.Username, - m.id as id, - m.status, - m.LastLogin, - g.Name as PlaceName, - gc.Name as CountryName - FROM - rights r, - rightsvolunteers rv, - members m, - geonames g, - geonamescountries gc - WHERE - m.Status in (' . MemberStatusType::ACTIVE_ALL . ') - AND rv.IdMember = m.id - AND rv.IdRight = r.id'; - if ($rightId) { - $query .= ' AND r.id = ' . $rightId; - } - $rights = implode("','", $this->getAllowedRights()); - if (!empty($rights)) { - $query .= " - AND - r.Name IN ('" . $rights . "') "; - } - $query .= ' - AND m.IdCity = g.geonameId - AND g.country = gc.country '; - if (!$includeLevelZero) { - $query .= ' AND rv.Level <> 0'; - } - $query .= ' - ORDER BY - r.Name, - m.Username - '; - $result = $this->bulkLookup($query); - - $rightsWithMembers = array(); - foreach ($result as $rwm) { - if (!isset($rightsWithMembers[$rwm->rightId])) { - $rightDetails = new StdClass(); - $rightDetails->Members = array(); - $rightsWithMembers[$rwm->rightId] = $rightDetails; - } - $memberDetails = new StdClass(); - $memberDetails->Status = $rwm->status; - $memberDetails->LastLogin = date('Y-m-d', strtotime($rwm->LastLogin)); - $memberDetails->Username = $rwm->Username; - $memberDetails->PlaceName = $rwm->PlaceName; - $memberDetails->CountryName = $rwm->CountryName; - $memberDetails->level = $rwm->Level; - $memberDetails->scope = $rwm->Scope; - $memberDetails->comment = $rwm->Comment; - $rightsWithMembers[$rwm->rightId]->Members[$rwm->id] = $memberDetails; - } - return $rightsWithMembers; - } - - private function getAllowedRights() { - $member = $this->getLoggedInMember(); - if (!$member) { - return array('None'); - } - $memberRights = $member->getOldRights(); - $scope= str_replace('"', '', $memberRights['Rights']['Scope']); - $rights = array(); - if (stripos($scope, 'All') === false) { - $rights = explode(',', $scope); - } - - return $rights; - } - - /** - * get all rights defined or rights allowed for member - * - * @access public - * @return array list of rights - */ - public function getRights($memberRightsOnly = false, $member = false) { - $query = " - SELECT - * - FROM - rights"; - if ($memberRightsOnly) { - $rights = $this->getAllowedRights(); - if (count($rights) > 0) { - $query .= " WHERE - Name IN ('" . implode("','", $rights) . "') "; - } - } - $query .= " - ORDER BY - Name - "; - $memberRights = array(); - if ($member) { - $memberRights = $member->getOldRights(); - } - $result = $this->bulkLookup($query, array('id')); - - foreach($memberRights as $right) { - if (isset($result[$right['id']])) { - unset($result[$right['id']]); - } - } - return $result; - } - - public function checkEditVarsOk($vars) { - $errors = array(); - if (empty($vars['scope'])) { - $errors[] = 'AdminRightsScopeEmpty'; - } else { - // check if scope is well formed - if (!$this->checkScopeWellFormed($vars['scope'])) { - $errors[] = 'AdminRightsScopeNotWellFormed'; - } - } - if (empty($vars['comment'])) { - $errors[] = 'AdminRightsCommentEmpty'; - } - return $errors; - } - - public function edit($vars) { - $temp = new Member(); - $member = $temp->findByUsername($vars['username']); - $query = " - UPDATE - rightsvolunteers - SET - Level = '" . $this->dao->escape($vars['level']) . "', - Scope = '" . $this->dao->escape($vars['scope']) . "', - Comment = '" . $this->dao->escape($vars['comment']) . "', - Updated = NOW() - WHERE - IdMember = " . $member->id . " - AND IdRight = " . $this->dao->escape($vars['rightid']) . " - "; - $this->dao->query($query); - return true; - } - - /** - * Removes a right from a member - * Keeps the history by setting the level to 0 and updating the comment - * with a note when the removal happened and by whom - * - * @param $vars - * @return bool - */ - public function remove($vars) { - $temp = new Member(); - $member = $temp->findByUsername($vars['username']); - $loggedInMember = $this->getLoggedInMember(); - $comment = $vars['comment'] . "\n\nRemoved by " .$loggedInMember->Username . " on " - . date('Y-m-d'); - $query = " - UPDATE - rightsvolunteers - SET - Level = '0', - Scope = '" . $this->dao->escape($vars['scope']) . "', - Comment = '" . $this->dao->escape( $comment ) . "', - Updated = NOW() - WHERE - IdMember = " . $member->id . " - AND IdRight = " . $this->dao->escape($vars['rightid']) . " - "; - $this->dao->query($query); - return true; - } - - public function checkCreateVarsOk($vars) { - $errors = array(); - if (empty($vars['name'])) { - $errors[] = 'AdminRightsNameEmpty'; - } else { - $query = " - SELECT - * - FROM - rights r - WHERE - r.Name LIKE '" . $this->dao->escape($vars['name']) . "'"; - $name = $this->singleLookup($query); - if ($name) { - $errors[] = 'AdminRightsRightExists'; - } - } - if (empty($vars['description'])) { - $errors[] = 'AdminRightsDescriptionEmpty'; - } - return $errors; - } - - public function createRight($vars) { - $query = " - INSERT INTO - rights - SET - `Name` = '" . $this->dao->escape($vars['name']) . "', - `Description` = '" . $this->dao->escape($vars['description']) . "'"; - $this->dao->query($query); - - return true; - } -} diff --git a/build/admin/rights/pages/adminrightsassign.page.php b/build/admin/rights/pages/adminrightsassign.page.php deleted file mode 100644 index 41ebc24ba9..0000000000 --- a/build/admin/rights/pages/adminrightsassign.page.php +++ /dev/null @@ -1,30 +0,0 @@ -setCurrent('AdminRightsAssign'); - $this->addLateLoadScriptFile('build/jquery_ui.js'); - $this->addLateLoadScriptFile('build/member/autocomplete.js'); - } - - public function teaserHeadline() - { - $headline = parent::teaserHeadline(); - return $headline . " » {$this->words->get('AdminRights')}"; - } - - protected function getStylesheets() - { - $stylesheets = parent::getStylesheets(); - $stylesheets[] = 'build/jquery_ui.css'; - return $stylesheets; - } -} diff --git a/build/admin/rights/pages/adminrightsbase.page.php b/build/admin/rights/pages/adminrightsbase.page.php deleted file mode 100644 index 0ef2124e98..0000000000 --- a/build/admin/rights/pages/adminrightsbase.page.php +++ /dev/null @@ -1,101 +0,0 @@ - 'admin/rights', - 'AdminRightsOverview' => 'admin/rights/overview', - 'AdminRightsListMembers' => 'admin/rights/list/members', - 'AdminRightsListRights' => 'admin/rights/list/rights', - 'AdminRightsCreate' => 'admin/rights/create', - ); - - protected $current = false; - protected $rights = false; - protected $create = false; - - public function __construct() { - parent::__construct(new AdminRightsModel()); - $member = $this->model->getLoggedInMember(); - $rights = $member->getOldRights(); - $scope = $rights['Rights']['Scope']; - $this->create = stripos($scope, '"create"') !== false; - $this->create |= stripos($scope, '"all"') !== false; - } - - public function teaserHeadline() - { - $headline = parent::teaserHeadline(); - return $headline . " » {$this->words->get('AdminRights')}"; - } - - /** - * @param string $current current item in the side bar - */ - protected function setCurrent($current) { - $this->current = $current; - } - - protected function getStylesheets() - { - $stylesheets = parent::getStylesheets(); - $stylesheets[] = 'styles/css/minimal/screen/custom/admin.css?2'; - return $stylesheets; - } - - protected function getSubmenuItems() - { - $items = []; - foreach($this->sidebar as $key => $item) { - if (!$this->create && $key == 'AdminRightsCreate') continue; - $items[] = [ - $key, - $item, - $this->words->get($key), - ]; - } - return $items; - } - - protected function getSubmenuActiveItem() - { - return $this->current; - } - - protected function rightsSelect($rights, $current, $disabled = false) - { - $select = ''; - return $select; - } - - function levelSelect($current, $disabled = false, $showEmpty = true) - { - $select = ''; - return $select; - } -} diff --git a/build/admin/rights/pages/adminrightscreate.page.php b/build/admin/rights/pages/adminrightscreate.page.php deleted file mode 100644 index 264d052ec1..0000000000 --- a/build/admin/rights/pages/adminrightscreate.page.php +++ /dev/null @@ -1,21 +0,0 @@ -setCurrent('AdminRightsAssign'); - } - - public function teaserHeadline() - { - $headline = parent::teaserHeadline(); - return $headline . " » {$this->words->get('AdminRights')}"; - } -} diff --git a/build/admin/rights/pages/adminrightsedit.page.php b/build/admin/rights/pages/adminrightsedit.page.php deleted file mode 100644 index 544e29623e..0000000000 --- a/build/admin/rights/pages/adminrightsedit.page.php +++ /dev/null @@ -1,16 +0,0 @@ -{$this->words->get('AdminRights')}"; - } -} diff --git a/build/admin/rights/pages/adminrightslistmembers.page.php b/build/admin/rights/pages/adminrightslistmembers.page.php deleted file mode 100644 index 6445e10fa7..0000000000 --- a/build/admin/rights/pages/adminrightslistmembers.page.php +++ /dev/null @@ -1,27 +0,0 @@ -setCurrent('AdminRightsListMembers'); - } - - public function teaserHeadline() - { - $headline = parent::teaserHeadline(); - return $headline . " » {$this->words->get('AdminRightsListMembers')}"; - } - - public function getLateLoadScriptFiles() { - $scripts = parent::getLateLoadScriptfiles(); -// $scripts[] = 'adminrightstooltip.js'; - return $scripts; - } -} diff --git a/build/admin/rights/pages/adminrightslistrights.page.php b/build/admin/rights/pages/adminrightslistrights.page.php deleted file mode 100644 index 8a38754e9e..0000000000 --- a/build/admin/rights/pages/adminrightslistrights.page.php +++ /dev/null @@ -1,27 +0,0 @@ -setCurrent('AdminRightsListRights'); - } - - public function teaserHeadline() - { - $headline = parent::teaserHeadline(); - return $headline . " » {$this->words->get('AdminRightsListRights')}"; - } - - public function getLateLoadScriptFiles() { - $scripts = parent::getLateLoadScriptfiles(); - // $scripts[] = 'adminrightstooltip.js'; - return $scripts; - } -} diff --git a/build/admin/rights/pages/adminrightsoverview.page.php b/build/admin/rights/pages/adminrightsoverview.page.php deleted file mode 100644 index 72847da2a0..0000000000 --- a/build/admin/rights/pages/adminrightsoverview.page.php +++ /dev/null @@ -1,21 +0,0 @@ -setCurrent('AdminRightsOverview'); - } - - public function teaserHeadline() - { - $headline = parent::teaserHeadline(); - return $headline . " » {$this->words->get('AdminRightsOverview')}"; - } -} diff --git a/build/admin/rights/pages/adminrightsremove.page.php b/build/admin/rights/pages/adminrightsremove.page.php deleted file mode 100644 index 9fc2eab357..0000000000 --- a/build/admin/rights/pages/adminrightsremove.page.php +++ /dev/null @@ -1,16 +0,0 @@ -{$this->words->get('AdminRights')}"; - } -} diff --git a/build/admin/rights/templates/adminrights.leftsidebar.php b/build/admin/rights/templates/adminrights.leftsidebar.php deleted file mode 100644 index 7871a685f2..0000000000 --- a/build/admin/rights/templates/adminrights.leftsidebar.php +++ /dev/null @@ -1,42 +0,0 @@ - or -write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. - -*/ -/** - * @author shevek - */ -?> -

    words->get('AdminRightsSideBarTitle'); ?>

    - \ No newline at end of file diff --git a/build/admin/rights/templates/adminrightsassign.column_col3.php b/build/admin/rights/templates/adminrightsassign.column_col3.php deleted file mode 100644 index 681da793c5..0000000000 --- a/build/admin/rights/templates/adminrightsassign.column_col3.php +++ /dev/null @@ -1,68 +0,0 @@ - or -write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. - -*/ -$vars = $this->getRedirectedMem('vars'); -if ($vars) { - // overwrite the vars - $this->vars = $vars; -} - -include 'adminrightserrors.php'; - -$callbackTags = $this->layoutkit->formkit->setPostCallback('AdminRightsController', 'assignCallback'); -?> - - - -
    -
    - - member ? 'readonly="readonly"' : '') ?> - /> -
    -
    - - rightsSelect($this->rights, $this->vars['rightid']) ?> -
    -
    - - levelSelect($this->vars['level'], false, true) ?> -
    -
    -
    -
    - - - Enter the scope. Use ';' as delimiter and " around blocks -
    -
    - - -
    -
    -
    - " />flushBuffer(); ?> -
    -
    diff --git a/build/admin/rights/templates/adminrightscreate.column_col3.php b/build/admin/rights/templates/adminrightscreate.column_col3.php deleted file mode 100644 index 658e888c20..0000000000 --- a/build/admin/rights/templates/adminrightscreate.column_col3.php +++ /dev/null @@ -1,47 +0,0 @@ - or -write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. - -*/ -$vars = $this->getRedirectedMem('vars'); -if ($vars) { - // overwrite the vars - $this->vars = $vars; -} - -include 'adminrightserrors.php'; - -$callbackTags = $this->layoutkit->formkit->setPostCallback('AdminRightsController', 'createCallback'); -?> -
    - -
    - - -
    -
    - - -
    -
    - " />flushBuffer(); ?> -
    -
    \ No newline at end of file diff --git a/build/admin/rights/templates/adminrightsedit.column_col3.php b/build/admin/rights/templates/adminrightsedit.column_col3.php deleted file mode 100644 index de1a99d5d8..0000000000 --- a/build/admin/rights/templates/adminrightsedit.column_col3.php +++ /dev/null @@ -1,58 +0,0 @@ - or -write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. - -*/ -$vars = $this->getRedirectedMem('vars'); -if ($vars) { - // overwrite the vars - $this->vars = $vars; -} - -include 'adminrightserrors.php'; - -$callbackTags = $this->layoutkit->formkit->setPostCallback('AdminRightsController', 'editCallback'); -?> -
    - - -
    - - -
    -
    - - rightsSelect($this->rights, $this->vars['right'], true) ?> -
    -
    - - levelSelect($this->vars['level'], false, false) ?> -
    -
    - - -
    -
    - - -
    - " />flushBuffer(); ?> -
    diff --git a/build/admin/rights/templates/adminrightserrors.php b/build/admin/rights/templates/adminrightserrors.php deleted file mode 100644 index 9682079f20..0000000000 --- a/build/admin/rights/templates/adminrightserrors.php +++ /dev/null @@ -1,15 +0,0 @@ -getRedirectedMem('errors'); -if ($errors) { - echo '
    '; - foreach($errors as $error) { - echo '

    ' . $this->words->get($error) . '

    '; - } - echo '
    '; -} \ No newline at end of file diff --git a/build/admin/rights/templates/adminrightslistmembers.column_col3.helper.php b/build/admin/rights/templates/adminrightslistmembers.column_col3.helper.php deleted file mode 100644 index c8ce8be0eb..0000000000 --- a/build/admin/rights/templates/adminrightslistmembers.column_col3.helper.php +++ /dev/null @@ -1,15 +0,0 @@ -'; - $select .= ''; - foreach($members as $username => $member) { - $select .= ''; - } - $select .= ''; - return $select; -} diff --git a/build/admin/rights/templates/adminrightslistmembers.column_col3.php b/build/admin/rights/templates/adminrightslistmembers.column_col3.php deleted file mode 100644 index c750615bc3..0000000000 --- a/build/admin/rights/templates/adminrightslistmembers.column_col3.php +++ /dev/null @@ -1,78 +0,0 @@ -getRedirectedMem('vars'); -if ($vars) { - // overwrite the vars - $this->vars = $vars; - $this->members = $this->getRedirectedMem('members'); - $this->membersWithRights = $this->getRedirectedMem('membersWithRights'); -} - -$callbackTags = $this->layoutkit->formkit->setPostCallback('AdminRightsController', 'listMembersCallback'); -$layoutbits = new MOD_layoutbits(); - -?> -
    -
    - - - - - members, $this->vars['member']) ?> - - "/>flushBuffer(); ?> -
    -
    -
    - - - - - - - - -membersWithRights as $username => $details) : - $firstRow = true; - ?> - - - Rights as $id => $right) : - if ($firstRow) : - $firstRow = false; - else : - echo ''; - endif; - $ss = ($right->level == 0) ? '' : ''; - $se = ($right->level == 0) ? '' : ''; - ?> - - - - - - - - -
    get('AdminRightsUsername') ?>get('AdminRightsRight') ?>get('AdminRightsLevel') ?>get('AdminRightsScope') ?>get('AdminRightsComment') ?>
    PIC_50_50($username, 'class="profileimg"') . '
    '; - echo $username; ?>
    - Status ?>
    - Last login: LastLogin ?>
    - - - getSilent('AdminRightsAssignRight') ?>flushBuffer() ?>
    rights[$id]->Name . $se ?>level . $se ?>scope . $se ?>comment ?> - level <> 0) : ?> - - -
    -
    diff --git a/build/admin/rights/templates/adminrightslistrights.column_col3.php b/build/admin/rights/templates/adminrightslistrights.column_col3.php deleted file mode 100644 index 87e9a17c5f..0000000000 --- a/build/admin/rights/templates/adminrightslistrights.column_col3.php +++ /dev/null @@ -1,75 +0,0 @@ -getRedirectedMem('vars'); -if ($vars) { - // overwrite the vars - $this->vars = $vars; - $this->rightsWithMembers = $this->getRedirectedMem('rightsWithMembers'); -} - -$callbackTags = $this->layoutkit->formkit->setPostCallback('AdminRightsController', 'listRightsCallback'); -$layoutbits = new MOD_layoutbits(); -?> -
    -
    - - - rightsSelect($this->rights, $this->vars['rightid']) ?> - - vars['history'])) ? 'checked="checked' : '' ?> /> - - - "/>flushBuffer(); ?> - -
    -
    -
    - - - - - - - - -rightsWithMembers as $rightId => $details) : - $firstRow = true; - ?> - - Members as $id => $memberDetails) : - if ($firstRow) : - $firstRow = false; - else : - echo ''; - endif; - $ss = ($memberDetails->level == 0) ? '' : ''; - $se = ($memberDetails->level == 0) ? '' : ''; - ?> - - - - - - - - -
    get('AdminRightsRight') ?>get('AdminRightsUsername') ?>get('AdminRightsLevel') ?>get('AdminRightsScope') ?>get('AdminRightsComment') ?>
    rights[$rightId]->Name ?>
    - PIC_30_30($memberDetails->Username) ?>
    - Username ?>
    - Status ?>
    - Last login: LastLogin ?> -
    level . $se ?>scope . $se ?>comment . $se ?> - level <> 0) : ?> - - -
    -
    \ No newline at end of file diff --git a/build/admin/rights/templates/adminrightsoverview.column_col3.php b/build/admin/rights/templates/adminrightsoverview.column_col3.php deleted file mode 100644 index 6b25b08d58..0000000000 --- a/build/admin/rights/templates/adminrightsoverview.column_col3.php +++ /dev/null @@ -1,17 +0,0 @@ - -
    -rights as $right) : ?> -
    -

    Name ?>

    -

    Description ?>

    -
    - -
    - diff --git a/build/admin/rights/templates/adminrightsremove.column_col3.php b/build/admin/rights/templates/adminrightsremove.column_col3.php deleted file mode 100644 index 742fd10ffa..0000000000 --- a/build/admin/rights/templates/adminrightsremove.column_col3.php +++ /dev/null @@ -1,59 +0,0 @@ - or -write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. - -*/ -$vars = $this->getRedirectedMem('vars'); -if ($vars) { - // overwrite the vars - $this->vars = $vars; -} - -include 'adminrightserrors.php'; - -$callbackTags = $this->layoutkit->formkit->setPostCallback('AdminRightsController', 'removeCallback'); -?> -
    - - - -
    - - -
    -
    - - rightsSelect($this->rights, $this->vars['right'], true) ?> -
    -
    - - levelSelect($this->vars['level'], true) ?> -
    -
    - - -
    -
    - - -
    - " />flushBuffer(); ?> -
    diff --git a/build/admin/subscriptions/adminsubscriptions.ctrl.php b/build/admin/subscriptions/adminsubscriptions.ctrl.php index f6e54b8b72..c8468dbb63 100644 --- a/build/admin/subscriptions/adminsubscriptions.ctrl.php +++ b/build/admin/subscriptions/adminsubscriptions.ctrl.php @@ -42,6 +42,7 @@ public function __construct() { $this->model = new AdminSubscriptionsModel(); } + #[\Override] public function __destruct() { unset($this->model); } @@ -71,9 +72,9 @@ public function manageCallback(StdClass $args, ReadOnlyObject $action, public function manage() { $this->checkRights('ManageSubscriptions'); $page = new AdminSubscriptionsManagePage(); - $page->vars = array( + $page->vars = [ 'username' => '' - ); + ]; return $page; } } \ No newline at end of file diff --git a/build/admin/subscriptions/adminsubscriptions.model.php b/build/admin/subscriptions/adminsubscriptions.model.php index df768ff06d..8b0d521e55 100644 --- a/build/admin/subscriptions/adminsubscriptions.model.php +++ b/build/admin/subscriptions/adminsubscriptions.model.php @@ -6,7 +6,7 @@ class AdminSubscriptionsModel extends RoxModelBase { public function checkManageVarsOk($vars) { - $errors = array(); + $errors = []; if (empty($vars['username'])) { $errors[] = 'AdminManageSubscriptionsNameEmpty'; } else { diff --git a/build/admin/subscriptions/pages/adminsubscriptionsmanage.page.php b/build/admin/subscriptions/pages/adminsubscriptionsmanage.page.php index 7b44e6b7a8..1199db7ce5 100644 --- a/build/admin/subscriptions/pages/adminsubscriptionsmanage.page.php +++ b/build/admin/subscriptions/pages/adminsubscriptionsmanage.page.php @@ -8,13 +8,13 @@ class AdminSubscriptionsManagePage extends AdminBasePage { - protected $sidebar = array( + protected $sidebar = [ 'AdminFlagsAssign' => 'admin/flags/assign', 'AdminFlagsOverview' => 'admin/flags/overview', 'AdminFlagsListMembers' => 'admin/flags/list/members', 'AdminFlagsListFlags' => 'admin/flags/list/flags', 'AdminFlagsCreate' => 'admin/flags/create', - ); + ]; protected $current = false; protected $flags = false; @@ -25,12 +25,14 @@ public function __construct() { $member = $this->model->getLoggedInMember(); } + #[\Override] public function teaserHeadline() { $headline = parent::teaserHeadline(); return $headline . "» {$this->words->get('AdminManageSubscriptions')}"; } + #[\Override] protected function getStylesheets() { $stylesheets = parent::getStylesheets(); @@ -38,6 +40,7 @@ protected function getStylesheets() return $stylesheets; } + #[\Override] public function getLateLoadScriptFiles() { $scripts = parent::getLateLoadScriptfiles(); diff --git a/build/admin/treasurer/admintreasurer.ctrl.php b/build/admin/treasurer/admintreasurer.ctrl.php index c61554b642..4d9be06420 100644 --- a/build/admin/treasurer/admintreasurer.ctrl.php +++ b/build/admin/treasurer/admintreasurer.ctrl.php @@ -40,6 +40,7 @@ public function __construct() { $this->model = new AdminTreasurerModel(); } + #[\Override] public function __destruct() { unset($this->model); } @@ -52,7 +53,7 @@ public function __destruct() { */ public function treasurerOverview() { - list($member, $rights) = $this->checkRights('Treasurer'); + [$member, $rights] = $this->checkRights('Treasurer'); $page = new AdminTreasurerPage($this->model); return $page; } @@ -78,7 +79,7 @@ public function treasurerEditCreateDonationCallback(StdClass $args, ReadOnlyObje $id = $vars['id']; if ($id == 0) { $memberId = $vars['IdMember'] != 0 ? $vars['IdMember'] : null; - $success = $this->model->createDonation($vars['IdMember'], $vars['DonatedOn'], + $success = $this->model->createDonation($memberId, $vars['DonatedOn'], $vars['donate-amount'], $vars['donate-comment'], $countryid); } else { $success = $this->model->updateDonation($id, $vars['IdMember'], $vars['DonatedOn'], @@ -86,10 +87,10 @@ public function treasurerEditCreateDonationCallback(StdClass $args, ReadOnlyObje } if (!$success) { $mem_redirect->vars = $vars; - $mem_redirect->errors = array('AdminTreasurerDbUpdateFailed'); + $mem_redirect->errors = ['AdminTreasurerDbUpdateFailed']; return false; } - return $this->router->url('admin_treasurer_overview', array(), false); + return $this->router->url('admin_treasurer_overview', [], false); } /** @@ -100,7 +101,7 @@ public function treasurerEditCreateDonationCallback(StdClass $args, ReadOnlyObje */ public function treasurerEditCreateDonation() { - list($member, $rights) = $this->checkRights('Treasurer'); + [$member, $rights] = $this->checkRights('Treasurer'); $id = 0; if (isset($this->route_vars['id'])) { $id = $this->route_vars['id']; @@ -129,11 +130,11 @@ public function treasurerStartDonationCampaignCallback(StdClass $args, $success = $this->model->startDonationCampaign($vars); if (!$success) { $mem_redirect->vars = $vars; - $mem_redirect->errors = array('AdminTreasurerDbUpdateFailed'); + $mem_redirect->errors = ['AdminTreasurerDbUpdateFailed']; return false; } $this->session->set( 'AdminTreasurerStatus', 'StartSuccess' ); - return $this->router->url('admin_treasurer_overview', array(), false); + return $this->router->url('admin_treasurer_overview', [], false); } /** @@ -144,7 +145,7 @@ public function treasurerStartDonationCampaignCallback(StdClass $args, */ public function treasurerStartDonationCampaign() { - list($member, $rights) = $this->checkRights('Treasurer'); + [$member, $rights] = $this->checkRights('Treasurer'); $page = new AdminTreasurerStartDonationCampaignPage($this->model); return $page; } @@ -157,7 +158,7 @@ public function treasurerStartDonationCampaign() */ public function treasurerStopDonationCampaign() { - list($member, $rights) = $this->checkRights('Treasurer'); + [$member, $rights] = $this->checkRights('Treasurer'); $success = $this->model->stopDonationCampaign(); if ($success) { $this->session->set( 'AdminTreasurerStatus', 'StopSuccess' ); diff --git a/build/admin/treasurer/admintreasurer.model.php b/build/admin/treasurer/admintreasurer.model.php index bf91f3d2ce..00cfd9915e 100644 --- a/build/admin/treasurer/admintreasurer.model.php +++ b/build/admin/treasurer/admintreasurer.model.php @@ -6,7 +6,7 @@ class AdminTreasurerModel extends RoxModelBase { public function treasurerEditCreateDonationVarsOk(&$vars) { - $errors = array(); + $errors = []; if (empty($vars['donate-username'])) { $errors[] = 'AdminTreasurerDonorEmpty'; } else { @@ -28,12 +28,12 @@ public function treasurerEditCreateDonationVarsOk(&$vars) { $errors[] = 'AdminTreasurerDonatedOnEmpty'; } else { $date = $vars['donate-date']; - if ((strlen($date) < 8) || (strlen($date) > 10)) { + if ((strlen((string) $date) < 8) || (strlen((string) $date) > 10)) { $errors[] = 'AdminTreasurerDonatedOnInvalid'; } else { - list($day, $month, $year) = preg_split('/[\/.-]/', $date); - if (substr($month,0,1) == '0') $month = substr($month,1,2); - if (substr($day,0,1) == '0') $day = substr($day,1,2); + [$day, $month, $year] = preg_split('/[\/.-]/', (string) $date); + if (str_starts_with($month, '0')) $month = substr($month,1,2); + if (str_starts_with($day, '0')) $day = substr($day,1,2); $start = mktime(0, 0, 0, (int)$month, (int)$day, (int)$year); $vars['DonatedOn'] = date('YmdHis', $start); } @@ -73,25 +73,29 @@ public function getCountryCodeForGeonameId($geonameid) { } public function createDonation($memberid, $donatedon, $amount, $comment, $countryid) { - $query = " + $statement = $this->dao->prepare(" INSERT INTO donations SET - IdMember = " . $memberid . ", + IdMember = ?, Email = '', StatusPrivate = 'showamountonly', - created = '" . $donatedon . "', - Amount = " . $amount . ", + created = ?, + Amount = ?, Money = '', - IdCountry = " . $countryid . ", + IdCountry = ?, namegiven = '', referencepaypal = '', membercomment = '', - SystemComment = '" . $this->dao->escape($comment) . "'"; - $affected = $this->dao->exec($query); - if ($affected != 1) { - return false; - } + SystemComment = ? + "); + $statement->bindParam(1, $memberid); + $statement->bindParam(2, $donatedon); + $statement->bindParam(3, $amount); + $statement->bindParam(4, $countryid); + $statement->bindParam(5, $comment); + $statement->execute(); + return true; } @@ -160,7 +164,7 @@ public function getDonationCampaignStatus() { } public function treasurerStartDonationCampaignVarsOk(&$vars) { - $errors = array(); + $errors = []; if (!is_numeric($vars['donate-needed-per-year'])) { $errors[] = 'AdminTreasurerNeededAmountInvalid'; } @@ -168,12 +172,12 @@ public function treasurerStartDonationCampaignVarsOk(&$vars) { $errors[] = 'AdminTreasurerStartDateEmpty'; } else { $date = $vars['donate-start-date']; - if ((strlen($date) < 8) || (strlen($date) > 10)) { + if ((strlen((string) $date) < 8) || (strlen((string) $date) > 10)) { $errors[] = 'AdminTreasurerStartDateInvalid'; } else { - list($day, $month, $year) = preg_split('/[\/.-]/', $date); - if (substr($month,0,1) == '0') $month = substr($month,1,2); - if (substr($day,0,1) == '0') $day = substr($day,1,2); + [$day, $month, $year] = preg_split('/[\/.-]/', (string) $date); + if (str_starts_with($month, '0')) $month = substr($month,1,2); + if (str_starts_with($day, '0')) $day = substr($day,1,2); $start = mktime(0, 0, 0, (int)$month, (int)$day, (int)$year); $vars['StartDate'] = date('Y-m-d', $start); } diff --git a/build/admin/treasurer/pages/admintreasurer.page.php b/build/admin/treasurer/pages/admintreasurer.page.php index f4325a37cf..8d2b0dcfcf 100644 --- a/build/admin/treasurer/pages/admintreasurer.page.php +++ b/build/admin/treasurer/pages/admintreasurer.page.php @@ -44,11 +44,12 @@ public function __construct(AdminTreasurerModel $model) { } // Check if a donation campaign is currently running $this->campaign = ($model->getDonationCampaignStatus() == 1); - list($amount, $date) = $this->model->getDonationCampaignValues(); + [$amount, $date] = $this->model->getDonationCampaignValues(); $this->neededPerYear = $amount; $this->campaignStartDate = $date; } + #[\Override] public function teaserHeadline() { return "{$this->words->get('AdminTools')} » {$this->words->get('AdminTreasurer')}"; diff --git a/build/admin/treasurer/pages/admintreasurerbase.page.php b/build/admin/treasurer/pages/admintreasurerbase.page.php index f70e00ab92..6b5b444ab9 100644 --- a/build/admin/treasurer/pages/admintreasurerbase.page.php +++ b/build/admin/treasurer/pages/admintreasurerbase.page.php @@ -4,6 +4,7 @@ class AdminTreasurerBasePage extends AdminBasePage { protected $campaign = false; + #[\Override] protected function getSubmenuItems() { $words = $this->getWords(); diff --git a/build/admin/treasurer/pages/admintreasurereditcreatedonation.page.php b/build/admin/treasurer/pages/admintreasurereditcreatedonation.page.php index 6c37e01ea6..92db579be0 100644 --- a/build/admin/treasurer/pages/admintreasurereditcreatedonation.page.php +++ b/build/admin/treasurer/pages/admintreasurereditcreatedonation.page.php @@ -48,13 +48,14 @@ public function __construct(AdminTreasurerModel $model, $id) { $m = new Member($donation->IdMember); $this->username = $m->Username; $this->amount = $donation->Amount; - $this->date = date('d.m.Y', strtotime($donation->created)); + $this->date = date('d.m.Y', strtotime((string) $donation->created)); $this->comment = $donation->SystemComment; $this->countrycode = $this->model->getCountryCodeForGeonameId($donation->IdCountry); } $this->addLateLoadScriptFile('build/treasurer.js'); } + #[\Override] public function teaserHeadline() { $str = "{$this->words->get('AdminTools')} » {$this->words->get('AdminTreasurer')} » "; diff --git a/build/admin/treasurer/pages/admintreasurerstartdonationcampaign.page.php b/build/admin/treasurer/pages/admintreasurerstartdonationcampaign.page.php index 6da374d040..21a5dbd825 100644 --- a/build/admin/treasurer/pages/admintreasurerstartdonationcampaign.page.php +++ b/build/admin/treasurer/pages/admintreasurerstartdonationcampaign.page.php @@ -36,12 +36,13 @@ public function __construct(AdminTreasurerModel $model) { parent::__construct(); $this->model = $model; $this->member = $model->getLoggedInMember(); - list($amount, $date) = $this->model->getDonationCampaignValues(); + [$amount, $date] = $this->model->getDonationCampaignValues(); $this->amount = $amount; - list($year, $month, $day) = preg_split('/[\/.-]/', $date); + [$year, $month, $day] = preg_split('/[\/.-]/', (string) $date); $this->date = $day . "." . $month . "." . $year; } + #[\Override] public function teaserHeadline() { return "{$this->words->get('AdminTools')} » {$this->words->get('AdminTreasurer')} » {$this->words->get('AdminTreasurerStartDonationCampaign')}"; diff --git a/build/admin/treasurer/templates/admintreasurer.column_col3.php b/build/admin/treasurer/templates/admintreasurer.column_col3.php index 4c3707f101..04b496e69a 100644 --- a/build/admin/treasurer/templates/admintreasurer.column_col3.php +++ b/build/admin/treasurer/templates/admintreasurer.column_col3.php @@ -86,7 +86,7 @@ echo ''; } ?> -created)); ?> +created)); ?> € Amount); ?> SystemComment; ?> CountryName; ?> diff --git a/build/admin/word/adminword.ctrl.php b/build/admin/word/adminword.ctrl.php index 376a1758ed..fa324678ed 100644 --- a/build/admin/word/adminword.ctrl.php +++ b/build/admin/word/adminword.ctrl.php @@ -69,7 +69,7 @@ private function checkRights($right = '') { $this->redirectAbsolute($this->router->url('admin_norights')); exit(0); } - return array($member, $rights); + return [$member, $rights]; } /** @@ -102,11 +102,11 @@ public function createCode(){ if (isset($this->route_vars['wordcode'])){ $page->data = $this->model->getTranslationData('create','long','en',$this->route_vars['wordcode']); if (!isset($page->data[0])) { - $page->data = array(array('EngCode' => $this->route_vars['wordcode'])); + $page->data = [['EngCode' => $this->route_vars['wordcode']]]; } } - $page->formdata = $this->getFormData(array('EngCode','Sentence','EngDesc','EngDnt', - 'isarchived','EngPrio','lang'),(array)$page->data[0]); + $page->formdata = $this->getFormData(['EngCode','Sentence','EngDesc','EngDnt', + 'isarchived','EngPrio','lang'],(array)$page->data[0]); return $page; } @@ -122,13 +122,13 @@ public function createCode(){ */ public function createCodeCallback(StdClass $args, ReadOnlyObject $action, ReadWriteObject $mem_redirect, ReadWriteObject $mem_resend){ if (!$nav = $this->baseCallback($args,$mem_redirect,'createCode')){return false;} - list($id,$res) = $this->model->UpdateSingleTranslation($args->post); + [$id, $res] = $this->model->UpdateSingleTranslation($args->post); if ($res == 2) {$this->words->MakeRevision($id,'words');} // get the flash notice/error - list($type,$msg) = $this->getResultMsg($res,$args->post['EngCode'],$args->post['lang']); + [$type, $msg] = $this->getResultMsg($res,$args->post['EngCode'],$args->post['lang']); $this->$type($msg); $this->session->remove('form'); - return $this->router->url('admin_word_create', array(), false); + return $this->router->url('admin_word_create', [], false); } @@ -149,8 +149,8 @@ public function editCode(){ $page->status = 'AdminWordUpdateCodeParsMsg'; } - $page->formdata = $this->getFormData(array('EngCode','EngSent','EngDesc','EngDnt', - 'Sentence','lang','isarchived','EngPrio'),$page->nav); + $page->formdata = $this->getFormData(['EngCode','EngSent','EngDesc','EngDnt', + 'Sentence','lang','isarchived','EngPrio'],$page->nav); return $page; } @@ -168,10 +168,10 @@ public function editCodeCallback(StdClass $args, ReadOnlyObject $action, ReadWri if (!$nav = $this->baseCallback($args,$mem_redirect,'editCode')){return false;} switch($args->post['DOACTION']){ case 'Submit' : - list($id,$res) = $this->model->UpdateSingleTranslation($args->post); + [$id, $res] = $this->model->UpdateSingleTranslation($args->post); if ($res != 1) {$this->words->MakeRevision($id,'words');} // get the flash notice/error - list($type,$msg) = $this->getResultMsg($res,$args->post['EngCode'],$args->post['lang']); + [$type, $msg] = $this->getResultMsg($res,$args->post['EngCode'],$args->post['lang']); $this->$type($msg); break; case 'Back' : @@ -179,8 +179,8 @@ public function editCodeCallback(StdClass $args, ReadOnlyObject $action, ReadWri break; } return $this->router->url('admin_word_editlang', - array('wordcode'=>$args->post['EngCode'], - 'shortcode'=>'en') + ['wordcode'=>$args->post['EngCode'], + 'shortcode'=>'en'] , false); } /** @@ -193,7 +193,7 @@ public function findTranslations(){ $page = new AdminWordFindTranslationsPage(); $page->nav = $this->getNavigationData(); $page->langarr = $this->model->getLangarr($page->nav['scope']); - $page->formdata = $this->getFormData(array('EngCode','EngDesc','Sentence','lang'),$page->nav); + $page->formdata = $this->getFormData(['EngCode','EngDesc','Sentence','lang'],$page->nav); return $page; } @@ -209,8 +209,8 @@ public function findTranslations(){ */ public function findTranslationsCallback(StdClass $args, ReadOnlyObject $action, ReadWriteObject $mem_redirect, ReadWriteObject $mem_resend){ if (!$nav = $this->baseCallback($args,$mem_redirect,'findTranslations')){return false;} - $searchparams = array(); - foreach (array('EngCode','EngDesc','Sentence','lang') as $item){ + $searchparams = []; + foreach (['EngCode','EngDesc','Sentence','lang'] as $item){ if (isset($args->post[$item])){ if (strlen($args->post[$item])>0){ $searchparams[$item] = $args->post[$item]; @@ -261,8 +261,8 @@ public function editTranslation(){ $wordcode = false; $this->data = null; } - $page->formdata = $this->getFormData(array('EngCode','Sentence','EngDesc', - 'EngDnt','EngSent','lang') + $page->formdata = $this->getFormData(['EngCode','Sentence','EngDesc', + 'EngDnt','EngSent','lang'] ,$nav); return $page; } @@ -287,16 +287,16 @@ public function editTranslationCallback(StdClass $args, ReadOnlyObject $action, // dont do this if translation is equal to db and no admin rights // and continue with the second page - return $this->router->url('admin_word_code', array(), false); + return $this->router->url('admin_word_code', [], false); } // check if the wordcode exists in English $wcexist = $this->model->wordcodeExist($args->post['EngCode'],'en'); if ($wcexist->cnt > 0){ - list($id,$res) = $this->model->UpdateSingleTranslation($args->post); + [$id, $res] = $this->model->UpdateSingleTranslation($args->post); // write the old translation to the previousversion table if ($res == 2) {$this->words->MakeRevision($id,'words');} // get the flash notice/error - list($type,$msg) = $this->getResultMsg($res,$args->post['EngCode'],$args->post['lang']); + [$type, $msg] = $this->getResultMsg($res,$args->post['EngCode'],$args->post['lang']); } else { $type = 'setFlashError'; @@ -307,8 +307,8 @@ public function editTranslationCallback(StdClass $args, ReadOnlyObject $action, if (isset($args->post['findBtn'])){ $this->session->remove('form'); return $this->router->url('admin_word_editlang', - array('wordcode'=>$args->post['EngCode'], - 'shortcode'=>$args->post['lang']), false); + ['wordcode'=>$args->post['EngCode'], + 'shortcode'=>$args->post['lang']], false); } // case 'Delete' : // $res = $this->model->removeSingleTranslation($args->post); @@ -357,7 +357,7 @@ public function showListCallback(StdClass $args, ReadOnlyObject $action, ReadWri foreach(array_keys($args->post) as $key){ if (preg_match('#^Edit_(\d+)$#',$key,$id)){ $wordcode = $this->model->getWordcodeById($id[1]); - return $this->router->url('admin_word_editone', array('wordcode'=>$wordcode->code), false); + return $this->router->url('admin_word_editone', ['wordcode'=>$wordcode->code], false); } if (preg_match('#^ThisIsOk_(\d+)$#',$key,$id)){ $this->model->updateNoChanges($id[1]); @@ -396,7 +396,7 @@ public function showStatistics(){ * @return array Array with data to prefill the form with */ private function getFormData($fields,$vars = null){ - $formdata = array(); + $formdata = []; foreach ($fields as $field) { if (isset($vars[$field])){ $formdata[$field] = $vars[$field]; @@ -443,7 +443,7 @@ private function getResultMsg($res,$code,$shortcode){ MOD_log::get()->write('updating '.$code.' in '.$shortcode, 'AdminWord'); break; } - return array($type,$msg); + return [$type,$msg]; } /** * calculates translation statistics for all languages or single language @@ -483,9 +483,9 @@ private function checkScope($scope,$shortcode){ private function getNavigationData(){ // collect volunteerrights for this member; - list($this->member, $this->wordrights) = $this->checkRights('Words'); + [$this->member, $this->wordrights] = $this->checkRights('Words'); $rights = MOD_right::get(); - $nav = array(); + $nav = []; // get the base language from the session $nav['idLanguage'] = $this->session->get( 'IdLanguage', 0); $nav['shortcode'] = $this->session->get( 'lang', 'en'); @@ -494,7 +494,7 @@ private function getNavigationData(){ // array of objects with scope languages $nav['scope'] = $this->wordrights['Words']['Scope']; if ($nav['scope']=='"All"'){ - $this->langarr = array('All'); + $this->langarr = ['All']; //$nav['scopetext'] = 'All'; } else { $sc_arr = preg_split('#[,; ]+#',str_replace('"','',$nav['scope'])); diff --git a/build/admin/word/adminword.model.php b/build/admin/word/adminword.model.php index 95b88a7c52..8a32bb4505 100644 --- a/build/admin/word/adminword.model.php +++ b/build/admin/word/adminword.model.php @@ -212,7 +212,7 @@ public function getTranslationData($type,$limit,$shortcode,$wordcode = false){ ORDER BY EngUpdated DESC '; $listing = $this->BulkLookup($sql); - $data = array(); + $data = []; // some postprocessing if ($type == 'edit'){ @@ -283,7 +283,7 @@ public function wordcodeExist($code,$shortcode){ */ public function getLangarr($scope){ $sql = "SELECT * FROM languages WHERE "; - if (strpos($scope, "All") === false) { + if (!str_contains((string) $scope, "All")) { $scope = str_replace('"', '', $scope); $scope = str_replace(';', ',', $scope); $langs = explode(",", $scope); @@ -295,7 +295,7 @@ public function getLangarr($scope){ $sql .= " AND IsWrittenLanguage = 1 ORDER BY EnglishName"; $res = $this->BulkLookup($sql); - $langarr = array(); + $langarr = []; foreach ($res as $rec) { $langarr[] = $rec; } @@ -331,16 +331,11 @@ public function updateSingleTranslation($form){ $eng_ins = 'majorupdate = now(),'; $eng_upd = 'updated = updated,'; if (isset($form['changetype'])){ - switch ($form['changetype']){ - case 'major': - $eng_upd = 'majorupdate = now(), IdMember = '.(int)$this->session->get("IdMember").','; - break; - case 'none': - $eng_upd = 'updated = updated,'; - break; - default: - $eng_upd = 'IdMember = '.(int)$this->session->get("IdMember").','; - }} + $eng_upd = match ($form['changetype']) { + 'major' => 'majorupdate = now(), IdMember = '.(int)$this->session->get("IdMember").',', + 'none' => 'updated = updated,', + default => 'IdMember = '.(int)$this->session->get("IdMember").',', + };} if (isset($form['EngDesc'])){ $desc = 'description = "'.$this->dao->escape($form['EngDesc']).'", '; } @@ -369,7 +364,7 @@ public function updateSingleTranslation($form){ '.$eng_upd.$desc.' Sentence = "'.$this->dao->escape($form["Sentence"]).'"'; $this->dao->query($sql); - $returnval = array(mysql_insert_id(),mysql_affected_rows()); + $returnval = [mysql_insert_id(),mysql_affected_rows()]; // update dnt,isarchived and TP for all translations, // but do not change the update moment for the other languages if (count($changeInAll)>0){ @@ -391,7 +386,7 @@ public function updateSingleTranslation($form){ * @return array Array of wordcodes of the error messages that need to be thrown */ public function createCodeFormCheck($form){ - $errors = array(); + $errors = []; if (empty($form['EngCode'])){ $errors[] = 'AdminWordErrorCodeEmpty'; } else { @@ -404,7 +399,7 @@ public function createCodeFormCheck($form){ if ($form['EngDesc'] == $form['EngCode'] || $form['EngDesc'] == $form['Sentence']) { $errors[] = 'AdminWordErrorDescIsCodeSent'; } - if (strlen($form['EngDesc'])<15){ + if (strlen((string) $form['EngDesc'])<15){ $errors[] = 'AdminWordErrorDescriptionTooShort'; } } @@ -422,7 +417,7 @@ public function createCodeFormCheck($form){ * @return array Array of wordcodes of the error messages that need to be thrown */ public function editCodeFormCheck($form){ - $errors = array(); + $errors = []; $rights = MOD_right::get(); $wordLevel = $rights->hasRight('Words'); @@ -447,7 +442,7 @@ public function editCodeFormCheck($form){ * @return array Array of wordcodes of the error messages that need to be thrown */ public function editTranslationFormCheck($form){ - $errors = array(); + $errors = []; if (empty($form['EngCode'])){ $errors[] = 'AdminWordErrorCodeEmpty'; } elseif (isset($form['submitBtn'])) { @@ -482,10 +477,10 @@ public function editTranslationFormCheck($form){ * @return array Array of wordcodes of the error messages that need to be thrown */ public function findTranslationsFormCheck($form){ - $errors = array(); - if (!preg_match('#(?![_])[\w]#u',$form['EngCode']) - && !preg_match('#(?![_])[\w]#u',$form['EngDesc']) - && !preg_match('#(?![_])[\w]#u',$form['Sentence'])){ + $errors = []; + if (!preg_match('#(?![_])[\w]#u',(string) $form['EngCode']) + && !preg_match('#(?![_])[\w]#u',(string) $form['EngDesc']) + && !preg_match('#(?![_])[\w]#u',(string) $form['Sentence'])){ $errors[] = 'AdminWordErrorNeedOneSearchTerm'; } return $errors; @@ -499,13 +494,13 @@ public function findTranslationsFormCheck($form){ * @param array $errors Array of already collected error messages */ private function checkWordcodeFormat($code,&$errors){ - if (!preg_match('#^[a-z][-a-z0-9\._]+[a-z0-9]$#i',$code)){ + if (!preg_match('#^[a-z][-a-z0-9\._]+[a-z0-9]$#i',(string) $code)){ $errors[] = 'AdminWordErrorBadCodeFormat'; } } public function setNoUpdateNeeded($id) { - $result = array(); + $result = []; $result['status'] = 'success'; // check if id exists $this->updateNoChanges($id); diff --git a/build/admin/word/pages/adminwordbase.page.php b/build/admin/word/pages/adminwordbase.page.php index 6f039f6817..0470132ec1 100644 --- a/build/admin/word/pages/adminwordbase.page.php +++ b/build/admin/word/pages/adminwordbase.page.php @@ -15,17 +15,17 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License -along with this program; if not, see or -write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, +along with this program; if not, see or +write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - /** + /** * @author Tsjoek */ - /** + /** * words management base page - * + * * @package Apps * @subpackage Admin */ @@ -33,19 +33,20 @@ class AdminWordBasePage extends PageWithActiveSkin { protected $purifier; // instance of html-purifier - public $formdata = array(); // data collected from the form - + public $formdata = []; // data collected from the form + public function __construct($model = false) { parent::__construct(); - $this->purifier = MOD_htmlpure::getSuggestionsHtmlPurifier(); + $this->purifier = (new MOD_htmlpure())->getSuggestionsHtmlPurifier(); } - + /* * default browsertab title * * @access protected * @return string */ + #[\Override] protected function getPageTitle() { return 'Words management | BeWelcome'; } @@ -64,8 +65,9 @@ public function teaserHeadline(){ protected function leftSidebar() { include '../build/admin/word/templates/adminword.leftsidebar.php'; } - - protected function getStylesheets() + + #[\Override] + protected function getStylesheets() { $stylesheets = parent::getStylesheets(); $stylesheets[] = 'styles/css/minimal/screen/custom/adminword.css'; @@ -85,7 +87,7 @@ protected function showScope(){ $tot = ''; foreach ($this->langarr as $item){ if (strlen($tot)>0) {$tot.=', ';} - $tot .= trim($this->words->get('lang_'.$item->ShortCode)); + $tot .= trim((string) $this->words->get('lang_'.$item->ShortCode)); } return $tot; } diff --git a/build/admin/word/pages/adminwordcreatecode.page.php b/build/admin/word/pages/adminwordcreatecode.page.php index 48ff561619..f988240ff5 100644 --- a/build/admin/word/pages/adminwordcreatecode.page.php +++ b/build/admin/word/pages/adminwordcreatecode.page.php @@ -37,6 +37,7 @@ class AdminWordCreateCodePage extends AdminWordBasePage * @access public * @return string */ + #[\Override] public function teaserHeadline(){ $string = 'AdminWord'; $string .= ' » Create WordCode'; diff --git a/build/admin/word/pages/adminwordeditcode.page.php b/build/admin/word/pages/adminwordeditcode.page.php index 6677f55963..a1879fa655 100644 --- a/build/admin/word/pages/adminwordeditcode.page.php +++ b/build/admin/word/pages/adminwordeditcode.page.php @@ -37,6 +37,7 @@ class AdminWordEditCodePage extends AdminWordBasePage * @access public * @return string */ + #[\Override] public function teaserHeadline(){ $string = 'AdminWord'; $string .= ' » '.$this->nav['currentLanguage']; diff --git a/build/admin/word/pages/adminwordedittranslation.page.php b/build/admin/word/pages/adminwordedittranslation.page.php index 02130e4422..83138ee9c3 100644 --- a/build/admin/word/pages/adminwordedittranslation.page.php +++ b/build/admin/word/pages/adminwordedittranslation.page.php @@ -37,6 +37,7 @@ class AdminWordEditTranslationPage extends AdminWordBasePage * @access public * @return string */ + #[\Override] public function teaserHeadline() { $string = 'AdminWord'; diff --git a/build/admin/word/pages/adminwordfindtranslations.page.php b/build/admin/word/pages/adminwordfindtranslations.page.php index 38d18af5be..285b3ddd45 100644 --- a/build/admin/word/pages/adminwordfindtranslations.page.php +++ b/build/admin/word/pages/adminwordfindtranslations.page.php @@ -37,6 +37,7 @@ class AdminWordFindTranslationsPage extends AdminWordBasePage * @access public * @return string */ + #[\Override] public function teaserHeadline() { $string = 'AdminWord'; diff --git a/build/admin/word/pages/adminwordshowlist.page.php b/build/admin/word/pages/adminwordshowlist.page.php index c5c1a37c2b..639853a771 100644 --- a/build/admin/word/pages/adminwordshowlist.page.php +++ b/build/admin/word/pages/adminwordshowlist.page.php @@ -37,24 +37,21 @@ class AdminWordShowListPage extends AdminWordBasePage * @access public * @return string */ + #[\Override] public function teaserHeadline() { $string = 'AdminWord'; $string .= ' » '.$this->nav['currentLanguage']; - switch ($this->type){ - case 'all' : - $string .= ' » All words'; - break; - case 'missing' : - $string .= ' » Missing'; - break; - case 'update' : - $string .= ' » Update needed'; - break; - } + match ($this->type) { + 'all' => $string .= ' » All words', + 'missing' => $string .= ' » Missing', + 'update' => $string .= ' » Update needed', + default => $string, + }; return $string; } + #[\Override] public function getLateLoadScriptfiles() { $scriptFiles = parent::getLateLoadScriptfiles(); if ($this->type == 'update') { diff --git a/build/admin/word/pages/adminwordshowstatistics.page.php b/build/admin/word/pages/adminwordshowstatistics.page.php index 34b6a91b02..5a8a7342ff 100644 --- a/build/admin/word/pages/adminwordshowstatistics.page.php +++ b/build/admin/word/pages/adminwordshowstatistics.page.php @@ -37,6 +37,7 @@ class AdminWordShowStatisticsPage extends AdminWordBasePage * @access public * @return string */ + #[\Override] public function teaserHeadline() { $string = 'AdminWord'; diff --git a/build/admin/word/templates/adminwordcreatecode.column_col3.php b/build/admin/word/templates/adminwordcreatecode.column_col3.php index f774581dac..2614a434d1 100644 --- a/build/admin/word/templates/adminwordcreatecode.column_col3.php +++ b/build/admin/word/templates/adminwordcreatecode.column_col3.php @@ -54,7 +54,7 @@ - @@ -63,7 +63,7 @@ ?> - + diff --git a/build/admin/word/templates/adminwordeditcode.column_col3.php b/build/admin/word/templates/adminwordeditcode.column_col3.php index fd88e36c30..c32b1eafca 100644 --- a/build/admin/word/templates/adminwordeditcode.column_col3.php +++ b/build/admin/word/templates/adminwordeditcode.column_col3.php @@ -59,15 +59,15 @@ if (empty($this->formdata['EngCode'])){ ?> - + getformatted(($this->status),htmlspecialchars($this->formdata['EngCode'])); +echo $words->getformatted(($this->status),htmlspecialchars((string) $this->formdata['EngCode'])); ?> - - - - + + + + - - + + - <", ">"); +$tagold = ["<", ">"]; +$tagnew = ["<", ">"]; echo ''; + htmlentities((string) $this->formdata['EngSent'], ENT_COMPAT, 'UTF-8'))).''; ?> '; +$NbRows = ceil(3 + strlen((string) $this->formdata['Sentence'])/75); +echo ' rows="'.$NbRows.'">'. htmlspecialchars((string) $this->formdata['Sentence']) .''; ?> @@ -94,17 +94,17 @@ - +
    +
    English text:
    + formdata['EngDnt'] == "yes") { echo 'Do not translate'; @@ -67,24 +67,24 @@ ?>
    Description: -formdata['EngDesc']) ?> +formdata['EngDesc']) ?>
    English source: '. str_replace("\n","
    ", str_replace($tagold,$tagnew, - htmlentities($this->formdata['EngSent'], ENT_COMPAT, 'UTF-8'))).'
    - - + +      diff --git a/build/admin/word/templates/adminwordfindtranslations.column_col3.php b/build/admin/word/templates/adminwordfindtranslations.column_col3.php index 3f34510d5b..b66485b356 100644 --- a/build/admin/word/templates/adminwordfindtranslations.column_col3.php +++ b/build/admin/word/templates/adminwordfindtranslations.column_col3.php @@ -25,15 +25,15 @@ - - - @@ -42,11 +42,11 @@ diff --git a/build/admin/word/templates/adminwordshowlist.column_col3.php b/build/admin/word/templates/adminwordshowlist.column_col3.php index fc403c9d3e..399c2d3c75 100644 --- a/build/admin/word/templates/adminwordshowlist.column_col3.php +++ b/build/admin/word/templates/adminwordshowlist.column_col3.php @@ -54,7 +54,7 @@ if ($this->filter == 'short'){ ?> This list only contains items created at least 7 days ago and updated at most 6 months ago. -Remove this limitation +Remove this limitation

    @@ -68,25 +68,25 @@ data as $dat){ - echo ''; if ($this->nav['shortcode'] != 'en'){ echo ''; } if ($dat->missing){ // missing translation echo ''; echo "\r\n"; diff --git a/build/admin/word/templates/adminwordshowstatistics.column_col3.php b/build/admin/word/templates/adminwordshowstatistics.column_col3.php index 847e403dd6..91e599e433 100644 --- a/build/admin/word/templates/adminwordshowstatistics.column_col3.php +++ b/build/admin/word/templates/adminwordshowstatistics.column_col3.php @@ -39,7 +39,7 @@ echo ''; $cnt++; diff --git a/build/donate/donate.ctrl.php b/build/donate/donate.ctrl.php index 675cadf323..9620a02d61 100644 --- a/build/donate/donate.ctrl.php +++ b/build/donate/donate.ctrl.php @@ -10,6 +10,7 @@ public function __construct() $this->_view = new DonateView($this->_model); } + #[\Override] public function __destruct() { unset($this->_model); diff --git a/build/donate/donate.model.php b/build/donate/donate.model.php index 8a708dfde1..6f4d683c7d 100644 --- a/build/donate/donate.model.php +++ b/build/donate/donate.model.php @@ -17,7 +17,7 @@ class DonateModel extends RoxModelBase */ public function getStatForDonations() { // check if donate.ini exists and get values - list($requiredPerYear, $campaignStart) = $this->getCampaignValues(); + [$requiredPerYear, $campaignStart] = $this->getCampaignValues(); $requiredPerMonth = floor($requiredPerYear / 12); // Calculate donations received for current year @@ -87,7 +87,7 @@ public function getStatForDonations() { public function getDonations($recent = false) { $rights = MOD_right::get(); $where = ""; - list($dummy, $campaignStart) = $this->getCampaignValues(); + [$dummy, $campaignStart] = $this->getCampaignValues(); if ($rights->hasRight('Treasurer')) { $limitClause = ""; if ($recent) { @@ -107,7 +107,7 @@ public function getDonations($recent = false) { $limitClause "; $result = $this->dao->query($query); - $donations = array(); + $donations = []; while ($row = $result->fetch(PDB::FETCH_OBJ)) { if ($row->IdCountry == 0) { $countryName = "Unknown country"; @@ -149,7 +149,7 @@ public function processIpnNotificationFromPayPal() }// Reply with an empty 200 response to indicate to paypal the IPN was received correctly. header("HTTP/1.1 200 OK"); PPHP::PExit(); - } catch (Exception $e) { + } catch (Exception) { } } @@ -204,11 +204,11 @@ public function returnFromPayPal() // parse the data to read the return variables by paypal $lines = explode("\n", $res); - $keyarray = array(); + $keyarray = []; if (strcmp ($lines[0], "SUCCESS") == 0) { for ($i=1; $isingleLookup($query); if (!$r) { // failed return defaults (might miss a DB update) - return array(1260, '2012-10-11'); + return [1260, '2012-10-11']; } else { - return array($r->neededperyear, $r->campaignstartdate); + return [$r->neededperyear, $r->campaignstartdate]; } } diff --git a/build/donate/donate.view.php b/build/donate/donate.view.php index 6606c4e8bf..95d5eaf18a 100644 --- a/build/donate/donate.view.php +++ b/build/donate/donate.view.php @@ -8,7 +8,7 @@ class DonateView extends PAppView * @param void */ private $_model; - + public function __construct(DonateModel &$model) { $this->_model =& $model; } @@ -27,7 +27,7 @@ public function donate($sub = false,$TDonationArray = false, $error = false) require 'templates/donate_list.php'; } else require 'templates/donate.php'; } - + public function donateBar($TDonationArray = false) { $Stat=$this->_model->getStatForDonations() ; @@ -37,6 +37,11 @@ public function donateBar($TDonationArray = false) public function submenu($sub) { require 'templates/submenu_donate.php'; } + + protected function addStyles() + { + return []; + } } ?> diff --git a/build/donate/templates/donate.php b/build/donate/templates/donate.php index dfab7f4330..a44ccfd51e 100644 --- a/build/donate/templates/donate.php +++ b/build/donate/templates/donate.php @@ -1,5 +1,9 @@ +
    session->get('lang') ? 'fr' : 'en'; +$helloAssoLink = 'https://www.helloasso.com/associations/bevolunteer/formulaires/1/' . $lang; ?>
    @@ -41,13 +47,11 @@

    get('Donate_Account2')?>

    get('Donate_Account')?>

    - +
    +

    get('donate.hello.asso');?>

    + get('donate.hello.asso');?> +

    get('donate.hello.asso.text');?>

    +

    get('Donate_Paypal_Legend')?>

    @@ -144,3 +148,5 @@ function clearForm (Element) { document.getElementById(Element).value = ''; } + + diff --git a/build/donate/templates/donate_list.php b/build/donate/templates/donate_list.php index 0c473f6a44..03a4542425 100644 --- a/build/donate/templates/donate_list.php +++ b/build/donate/templates/donate_list.php @@ -33,27 +33,27 @@ $max=count($TDonationArray) ; for ($ii=0;$ii<$max;$ii++) { - $info_styles = array(0 => "class=\"blank\"", 1 => "class=\"highlight\""); + $info_styles = [0 => "class=\"blank\"", 1 => "class=\"highlight\""]; static $iii = 0; $T=$TDonationArray[$ii] ; $string = $info_styles[($iii++%2)]; // this displays the
    if ($this->session->has( "IdMember" ) and ($T->IdMember==$this->session->get("IdMember"))) { $string .= "bgcolor=\"yellow\""; } - echo "" ; + echo "" ; echo "" ; echo "" ; echo "" ; - echo "" ; + echo "" ; + echo $m->getUsername()," ",$T->referencepaypal ; } } - echo "\n" ; + echo "\n" ; } echo "
    +
    +
    +

    '.htmlspecialchars($dat->EngCode).'

    '; + echo '

    '.htmlspecialchars((string) $dat->EngCode).'

    '; if ($dat->EngDnt=='yes'){echo 'Do not translate';} if ($this->nav['grep']>0) { echo 'grep'; + echo htmlspecialchars((string) $dat->EngCode) . '&scope=layout/*;*;lib/*">grep'; } - echo '

    ' . htmlspecialchars($dat->EngDesc) . '

    '; + echo '

    ' . htmlspecialchars((string) $dat->EngDesc) . '

    '; echo '
    '.$this->purifier->purify($dat->EngSent); - echo '

    Last update '.$layoutbits->ago(strtotime($dat->EngUpdated)).' '.htmlspecialchars($dat->EngMember).'

    '; + echo '

    Last update '.$layoutbits->ago(strtotime((string) $dat->EngUpdated)).' '.htmlspecialchars((string) $dat->EngMember).'

    '; echo '
    '; - echo '
    ADD'; + echo '
    ADD'; } else { if ($dat->update){ // update needed @@ -99,9 +99,9 @@ } else { // up-to-date translation echo '
    '.$this->purifier->purify($dat->Sentence); - echo '

    edit

    '; + echo '

    edit

    '; } - echo '

    Last update '.$layoutbits->ago(strtotime($dat->TrUpdated)).' '.htmlspecialchars($dat->TrMember).'

    '; + echo '

    Last update '.$layoutbits->ago(strtotime((string) $dat->TrUpdated)).' '.htmlspecialchars((string) $dat->TrMember).'

    '; } echo '
    '.htmlspecialchars($dat['name']).''; + echo '">'.htmlspecialchars((string) $dat['name']).''; printf("%01.1f", (float)$dat['perc']); echo '% done
    ",date("y/m/d",strtotime($T->created)),"
    ",date("y/m/d",strtotime((string) $T->created)),"" ; printf ("%s %3.2f",$T->Money,$T->Amount) ; echo "",$T->SystemComment,"",$T->CountryName,"" ; if ($hasRight) { $m = MOD_member::getMember_userId($T->IdMember); if ($m) { - echo "",$m->getUsername()," ",$T->referencepaypal,"
    " ; diff --git a/build/donate/templates/userbar_donate.php b/build/donate/templates/userbar_donate.php index 59f70d4ca1..8db90fc081 100644 --- a/build/donate/templates/userbar_donate.php +++ b/build/donate/templates/userbar_donate.php @@ -1,5 +1,5 @@ _model->forums_uri = $this->forums_uri; } + #[\Override] public function __destruct() { unset($this->_model); unset($this->_view); @@ -42,7 +43,7 @@ public function topMenu($currentTab) { public function get_forums_uri() { $request = PRequest::get()->request; - $uri = array(); + $uri = []; foreach ($request as $r) { array_push($uri,$r); if ($r == 'forums' or $r == 'forum') break; @@ -77,7 +78,7 @@ public function index($subforum = false) { if (($request[0] == "group") && (isset($request[1]))) { $IdGroup = intval($request[1]); } - $new_request = array(); + $new_request = []; $push = false; foreach ($request as $r) { if ($r == 'forums' or $r == 'forum') $push = true; @@ -189,7 +190,7 @@ public function index($subforum = false) { else if ($this->action == self::ACTION_VIEW_FORUM) { $groupsCallback = false; $member = $this->_model->getLoggedInMember(); - if ($member && $member->Status != 'ChoiceInactive') { + if ($member && !($member->Status == 'ChoiceInactive' || $member->Status == 'Activated')) { $noForumNewTopicButton = false; } else { // Don't offer the new topic button to 'silent' members @@ -574,11 +575,11 @@ private function searchUserposts($user) { if ($membersForumPostsPagePublic || ($profileVisitor->getPKValue() == $userId) || $this->BW_Right->HasRight("Admin") || $this->BW_Right->HasRight("ForumModerator") || $this->BW_Right->HasRight("SafetyTeam") ) { $posts = $this->_model->searchUserposts($user); } else { - $posts = array(); //TODO: post something that says that the user has not enabled that page + $posts = []; //TODO: post something that says that the user has not enabled that page } } else { - $posts = array() ; + $posts = [] ; } $this->_view->displaySearchResultPosts($posts); // TODO: post something suggesting to LogIn or to register to maybe see posts by this user } @@ -646,7 +647,7 @@ public function showExternalLatest($showGroups = false) { $request = $this->request; $member = $this->_model->getLoggedInMember(); $showForumNewTopicButton = true; - if ($member->Status == 'ChoiceInactive') { + if ($member->Status == 'ChoiceInactive' || $member->Status == 'Activated') { $showForumNewTopicButton = false; } $this->parseRequest(); @@ -663,7 +664,7 @@ public function editProcess() { $this->parseRequest(); return $this->_model->editProcess(); } else { - PPostHandler::setCallback($callbackId, __CLASS__, __METHOD__); + PPostHandler::setCallback($callbackId, self::class, __METHOD__); return $callbackId; } } @@ -675,7 +676,7 @@ public function createProcess() { $this->parseRequest(); return $this->_model->createProcess(); } else { - PPostHandler::setCallback($callbackId, __CLASS__, __METHOD__); + PPostHandler::setCallback($callbackId, self::class, __METHOD__); return $callbackId; } } @@ -687,7 +688,7 @@ public function replyProcess() { $this->parseRequest(); return $this->_model->replyProcess(); } else { - PPostHandler::setCallback($callbackId, __CLASS__, __METHOD__); + PPostHandler::setCallback($callbackId, self::class, __METHOD__); return $callbackId; } } @@ -699,7 +700,7 @@ public function reportpostProcess() { $this->parseRequest(); return $this->_model->reportpostProcess(); } else { - PPostHandler::setCallback($callbackId, __CLASS__, __METHOD__); + PPostHandler::setCallback($callbackId, self::class, __METHOD__); return $callbackId; } } @@ -712,7 +713,7 @@ public function ModeratorEditPostProcess() { // echo ("here") ; return $this->_model->ModeratorEditPostProcess(); } else { - PPostHandler::setCallback($callbackId, __CLASS__, __METHOD__); + PPostHandler::setCallback($callbackId, self::class, __METHOD__); return $callbackId; } } @@ -725,7 +726,7 @@ public function ModeratorEditTagProcess() { // echo ("here") ; return $this->_model->ModeratorEditTagProcess(); } else { - PPostHandler::setCallback($callbackId, __CLASS__, __METHOD__); + PPostHandler::setCallback($callbackId, self::class, __METHOD__); return $callbackId; } } @@ -741,7 +742,7 @@ public function mygroupsonlyProcess() { if (PPostHandler::isHandling()) { return $this->_model->switchShowMyGroupsTopicsOnly(); } else { - PPostHandler::setCallback($callbackId, __CLASS__, __METHOD__); + PPostHandler::setCallback($callbackId, self::class, __METHOD__); return $callbackId; } } @@ -752,7 +753,7 @@ public function morelessthreadsProcess() { if (PPostHandler::isHandling()) { return $this->_model->adjustThreadsCountToShow($step = 3); } else { - PPostHandler::setCallback($callbackId, __CLASS__, __METHOD__); + PPostHandler::setCallback($callbackId, self::class, __METHOD__); return $callbackId; } } @@ -877,39 +878,39 @@ private function parseRequest() { $this->action = self::ACTION_REVERSE; } else if ($r == 'delete') { $this->action = self::ACTION_DELETE; - } else if (preg_match_all('/page([0-9]+)/i', $r, $regs)) { + } else if (preg_match_all('/page([0-9]+)/i', (string) $r, $regs)) { $this->_model->setPage($regs[1][0]); $this->_model->pushToPageArray($regs[1][0]); } else if ($r == 'locationDropdowns') { $this->action = self::ACTION_LOCATIONDROPDOWNS; } else { $char = $r[0]; - $dashpos = strpos($r, '-'); + $dashpos = strpos((string) $r, '-'); if ($dashpos === false) { - $dashpos = strlen($r) - 1; + $dashpos = strlen((string) $r) - 1; } else { $dashpos--; } if ($char == 'g') { // Geoname-ID - $this->_model->setGeonameid((int) substr($r, 1, $dashpos)); + $this->_model->setGeonameid((int) substr((string) $r, 1, $dashpos)); $this->isTopLevel = false; } else if ($char == 'c') { // Countrycode - $this->_model->setCountryCode(substr($r, 1, $dashpos)); + $this->_model->setCountryCode(substr((string) $r, 1, $dashpos)); $this->isTopLevel = false; } else if ($char == 'a') { // Admincode - $this->_model->setAdminCode(substr($r, 1, $dashpos)); + $this->_model->setAdminCode(substr((string) $r, 1, $dashpos)); $this->isTopLevel = false; } else if ($char == 't') { // Tagid - $this->_model->addTag((int) substr($r, 1, $dashpos)); + $this->_model->addTag((int) substr((string) $r, 1, $dashpos)); $this->isTopLevel = false; } else if ($char == 's') { // Subject-ID (Thread-ID) - $this->_model->setThreadId((int) substr($r, 1, $dashpos)); + $this->_model->setThreadId((int) substr((string) $r, 1, $dashpos)); $this->isTopLevel = false; } else if ($char == 'u') { // Group ID (This is a dedicated group) - $this->_model->setGroupId((int) substr($r, 1, $dashpos)); + $this->_model->setGroupId((int) substr((string) $r, 1, $dashpos)); $this->isTopLevel = false; } else if ($char == 'm' && $r != "mygroupsonly") { // Message-ID (Single Post) - $this->_model->setMessageId(substr($r, 1, $dashpos)); + $this->_model->setMessageId(substr((string) $r, 1, $dashpos)); $this->isTopLevel = false; } } @@ -927,7 +928,7 @@ public function searchProcess() { $this->parseRequest(); return $this->_model->searchProcess(); } else { - PPostHandler::setCallback($callbackId, __CLASS__, __METHOD__); + PPostHandler::setCallback($callbackId, self::class, __METHOD__); return $callbackId; } } diff --git a/build/forums/forums.model.php b/build/forums/forums.model.php index 655359cedd..5029627606 100644 --- a/build/forums/forums.model.php +++ b/build/forums/forums.model.php @@ -24,7 +24,7 @@ function cmpForumLang($a, $b) if ($a == $b) { return 0; } - return (strtolower($a->Name) < strToLower($b->Name)) ? -1 : 1; + return (strtolower((string) $a->Name) < strToLower((string) $b->Name)) ? -1 : 1; } class Forums extends RoxModelBase { @@ -159,11 +159,8 @@ function FindAppropriatedLanguage($IdPost=0) { $query ="SELECT `IdLanguage` FROM `forum_trads` WHERE `IdTrad`=".$IdTrad." order by id asc limit 1" ; $q = $this->dao->query($query); $row = $q->fetch(PDB::FETCH_OBJ); - if (isset ($row->IdLanguage)) { - return($row->IdLanguage) ; - } - return(0) ; // By default we will return english + return($row->IdLanguage ?? 0) ; // By default we will return english } // end of FindAppropriatedLanguage @@ -181,17 +178,11 @@ public function __construct() { if ($this->session->has('IdMember')) { $member = $this->getLoggedInMember(); - switch($member->getPreference("PreferenceForumFirstPage")) { - case "Pref_ForumFirstPageLastPost": - $this->setTopMode(Forums::CV_TOPMODE_FORUM) ; - break ; - case "Pref_ForumFirstPageCategory": - $this->setTopMode(Forums::CV_TOPMODE_CATEGORY) ; - break ; - default: - $this->setTopMode(Forums::CV_TOPMODE_LANDING) ; - break ; - } + match ($member->getPreference("PreferenceForumFirstPage")) { + "Pref_ForumFirstPageLastPost" => $this->setTopMode(Forums::CV_TOPMODE_FORUM), + "Pref_ForumFirstPageCategory" => $this->setTopMode(Forums::CV_TOPMODE_CATEGORY), + default => $this->setTopMode(Forums::CV_TOPMODE_LANDING), + }; $layoutbits = new MOD_layoutbits(); $this->ForumOrderList = $layoutbits->GetPreference("PreferenceForumOrderListAsc", $member->id); } else { @@ -203,7 +194,7 @@ public function __construct() { $this->POSTS_PER_PAGE = self::CV_POSTS_PER_PAGE; // Variable because it can change wether the user is logged or no } - $MyGroups = array(); + $MyGroups = []; $this->words = new MOD_words(); @@ -346,20 +337,13 @@ public function adjustThreadsCountToShow($step = 1) { . ' preference not found in "preferences" table'); } - switch ($command) { - case "moreagora": - $membersmodel->set_preference($member->id, $forumpref->id, min($forumthreads + $step, $MAX_THREADS)); - break; - case "lessagora": - $membersmodel->set_preference($member->id, $forumpref->id, max($forumthreads - $step, 1)); - break; - case "moregroups": - $membersmodel->set_preference($member->id, $groupspref->id, min($groupsthreads + $step, $MAX_THREADS)); - break; - case "lessgroups": - $membersmodel->set_preference($member->id, $groupspref->id, max($groupsthreads - $step, 1)); - break; - } + match ($command) { + "moreagora" => $membersmodel->set_preference($member->id, $forumpref->id, min($forumthreads + $step, $MAX_THREADS)), + "lessagora" => $membersmodel->set_preference($member->id, $forumpref->id, max($forumthreads - $step, 1)), + "moregroups" => $membersmodel->set_preference($member->id, $groupspref->id, min($groupsthreads + $step, $MAX_THREADS)), + "lessgroups" => $membersmodel->set_preference($member->id, $groupspref->id, max($groupsthreads - $step, 1)), + default => false, + }; return false; } @@ -524,7 +508,7 @@ private function boardGroup($showsticky = true) { } $group = $gr->fetch(PDB::FETCH_OBJ); - $subboards = array(); + $subboards = []; $gtitle= $this->words->getSilent("ForumGroupTitle", $this->getGroupName($group->Name)) ; $this->board = new Board($this->dao, "", ".", $this->getSession(), $subboards, $this->IdGroup); $this->board->initThreads($this->getPage(), $showsticky); @@ -721,8 +705,8 @@ public function DofTradUpdate($IdForumTrads,$P_Sentence,$P_IdLanguage=0) { $IdLanguage=(int)$P_IdLanguage ; $Sentence= $this->dao->escape($P_Sentence); - MOD_log::get()->write("Updating data for IdForumTrads=#".$id." Before [".addslashes($rBefore->Sentence)."] IdLanguage=".$rBefore->IdLanguage."
    \nAfter [".$Sentence."] IdLanguage=".$IdLanguage, "ForumModerator"); - $sUpdate="update forum_trads set Sentence='".$Sentence."',IdLanguage=".$IdLanguage.",IdTranslator=".$this->session->get("IdMember")." where id=".$id ; + MOD_log::get()->write("Updating data for IdForumTrads=#".$id." Before [".addslashes((string) $rBefore->Sentence)."] IdLanguage=".$rBefore->IdLanguage."
    \nAfter [".$Sentence."] IdLanguage=".$IdLanguage, "ForumModerator"); + $sUpdate="update forum_trads set Sentence='".$Sentence."',IdLanguage=".$IdLanguage.",IdTranslator=".$this->session->get("IdMember").", updated=NOW() where id=".$id ; $s=$this->dao->query($sUpdate); if (!$s) { throw new PException('Failed for Update forum_trads.id=#'.$id); @@ -769,7 +753,7 @@ private function editPost($vars, $editorid) { $this->ReplaceInFTrad($this->dao->escape($this->cleanupText($vars['topic_title'])), "forums_threads.IdTitle", $rBefore->threadid, $rBefore->IdTitle, $rBefore->IdWriter) ; // case the update concerns the reference language of the threads if ($rBefore->thread_IdFirstLanguageUsed==$this->GetLanguageChoosen()) { - $groupId = (isset($vars['IdGroup']))?$vars['IdGroup']:'NULL'; + $groupId = $vars['IdGroup'] ?? 'NULL'; $query="update forums_threads set IdGroup=". $groupId.",title='".$this->dao->escape($this->cleanupText($vars['topic_title']))."' where forums_threads.id=".$rBefore->threadid ; $s=$this->dao->query($query); } @@ -789,7 +773,7 @@ private function editPost($vars, $editorid) { } $this->prepare_notification($this->messageId,"useredit") ; // Prepare a notification - MOD_log::get()->write("Editing Post=#".$this->messageId." Text Before=".addslashes($rBefore->message)."
    NotifyMe=[".$vars['NotifyMe']."]", "Forum"); + MOD_log::get()->write("Editing Post=#".$this->messageId." Text Before=".addslashes((string) $rBefore->message)."
    NotifyMe=[".$vars['NotifyMe']."]", "Forum"); } // editPost /** @@ -804,7 +788,7 @@ private function editTopic($vars, $threadid) { UPDATE `forums_threads` SET `title` = '%s' WHERE `id` = '%d' ", - $this->dao->escape(strip_tags($vars['topic_title'])), + $this->dao->escape(strip_tags((string) $vars['topic_title'])), $threadid ); @@ -818,7 +802,7 @@ private function editTopic($vars, $threadid) { } $rBefore = $s->fetch(PDB::FETCH_OBJ); - $this->ReplaceInFTrad($this->dao->escape(strip_tags($vars['topic_title'])), "forums_threads.IdTitle", $rBefore->IdThread, $rBefore->IdTitle, $rBefore->IdWriter) ; + $this->ReplaceInFTrad($this->dao->escape(strip_tags((string) $vars['topic_title'])), "forums_threads.IdTitle", $rBefore->IdThread, $rBefore->IdTitle, $rBefore->IdWriter) ; // case the update concerns the reference language of the posts if ($rBefore->thread_IdFirstLanguageUsed==$this->GetLanguageChoosen()) { @@ -916,9 +900,9 @@ public function reportpostProcess() { * in other case an array of reports is returned */ public function GetReports($IdPost,$IdReporter=0) { - $tt=array() ; + $tt=[] ; if (empty($IdReporter)) { - $ss = "select reports_to_moderators.*,Username from reports_to_moderators,members where IdPost=".$IdPost." and members.id=IdReporter" ; + $ss = "select reports_to_moderators.*,Username from reports_to_moderators,member where IdPost=".$IdPost." and member.id=IdReporter" ; $s = $this->dao->query($ss); while ($rr = $s->fetch(PDB::FETCH_OBJ)) { array_push($tt,$rr) ; @@ -953,12 +937,12 @@ public function prepareReportPost($IdPost,$IdWriter) { */ public function prepareReportList($IdMember,$StatusList) { // This retrieve all the reports for the a member or all members - $ss = "select reports_to_moderators.*,Username from reports_to_moderators,members where members.id=IdReporter " ; + $ss = "select reports_to_moderators.*,Username from reports_to_moderators,member where member.id=IdReporter " ; if (!empty($StatusList)) { $ss=$ss." and reports_to_moderators.Status in ".$StatusList ; } - $tt=array() ; + $tt=[] ; if (!empty($IdMember)) { $ss=$ss." and reports_to_moderators.IdModerator=".$IdMember ; } @@ -977,7 +961,7 @@ public function prepareReportList($IdMember,$StatusList) { // This retrieve all returns and integer */ public function countReportList($IdMember,$StatusList) { // This count all the reports for and optional members or all members according to their styatus - $ss = "select count(*) as cnt from reports_to_moderators,members where members.id=IdReporter " ; + $ss = "select count(*) as cnt from reports_to_moderators,member where member.id=IdReporter " ; if (!empty($StatusList)) { $ss=$ss." and reports_to_moderators.Status in ".$StatusList ; } @@ -999,7 +983,7 @@ public function prepareModeratorEditPost($IdPost, $moderator = false) { $DataPost->IdPost=$IdPost ; $DataPost->Error="" ; // This will receive the error sentence if any - $query = "select forums_posts.*,members.Status as memberstatus,members.UserName as UserNamePoster from forums_posts,members where forums_posts.id=".$IdPost." and IdWriter=members.id" ; + $query = "select forums_posts.*,member.Status as memberstatus,member.UserName as UserNamePoster from forums_posts,member where forums_posts.id=".$IdPost." and IdWriter=member.id" ; $s = $this->dao->query($query); $DataPost->Post = $s->fetch(PDB::FETCH_OBJ) ; @@ -1035,9 +1019,9 @@ public function prepareModeratorEditPost($IdPost, $moderator = false) { } // retrieve all trads for content - $query = "select forum_trads.*,EnglishName,ShortCode,forum_trads.id as IdForumTrads from forum_trads,languages where IdLanguage=languages.id and IdTrad=".$DataPost->Post->IdContent." order by forum_trads.created asc" ; + $query = "select forum_trads.*,Name,ShortCode,forum_trads.id as IdForumTrads from forum_trads,language where ShortCode=language.ShortCode and IdTrad=".$DataPost->Post->IdContent." order by forum_trads.created asc" ; $s = $this->dao->query($query); - $DataPost->Post->Content=array() ; + $DataPost->Post->Content=[] ; while ($row=$s->fetch(PDB::FETCH_OBJ)) { $DataPost->Post->Content[]=$row ; } @@ -1053,9 +1037,9 @@ public function prepareModeratorEditPost($IdPost, $moderator = false) { // retrieve all trads for Title - $query = "select forum_trads.*,EnglishName,ShortCode,forum_trads.id as IdForumTrads from forum_trads,languages where IdLanguage=languages.id and IdTrad=".$DataPost->Thread->IdTitle." order by forum_trads.created asc" ; + $query = "select forum_trads.*,Name,ShortCode,forum_trads.id as IdForumTrads from forum_trads,languages where IdLanguage=languages.id and IdTrad=".$DataPost->Thread->IdTitle." order by forum_trads.created asc" ; $s = $this->dao->query($query); - $DataPost->Thread->Title=array() ; + $DataPost->Thread->Title=[] ; while ($row=$s->fetch(PDB::FETCH_OBJ)) { array_push($DataPost->Thread->Title,$row) ; } @@ -1312,7 +1296,7 @@ public function delProcess() { private function checkVarsReply(&$vars) { - $errors = array(); + $errors = []; if (!isset($vars['topic_text']) || empty($vars['topic_text'])) { $errors[] = 'text'; @@ -1326,7 +1310,7 @@ private function checkVarsReply(&$vars) { } public function checkVarsTopic(&$vars) { - $errors = array(); + $errors = []; if (!isset($vars['topic_title']) || empty($vars['topic_title'])) { $errors[] = 'title'; @@ -1361,8 +1345,8 @@ private function replyTopic(&$vars) { $this->dao->query("START TRANSACTION"); $query = sprintf( " -INSERT INTO `forums_posts` ( `threadid`, `create_time`, `message`,`IdWriter`,`IdFirstLanguageUsed`,`PostVisibility`) -VALUES ('%d', NOW(), '%s','%d',%d,'%s') +INSERT INTO `forums_posts` ( `threadid`, `create_time`, `message`,`IdWriter`,`IdFirstLanguageUsed`,`PostVisibility`, `IdContent`,`edit_count`) +VALUES ('%d', NOW(), '%s','%d',%d,'%s',0, 0) ", $this->threadid, $this->dao->escape($this->cleanupText($vars['topic_text'])), @@ -1437,12 +1421,20 @@ public function newTopic(&$vars) { /** @var PDBStatement_mysqli $statement */ $statement = $this->dao->prepare(" - INSERT INTO `forums_posts` ( - `create_time`, `message`,`IdWriter`,`IdFirstLanguageUsed`,`PostVisibility`) - VALUES (NOW(), ?, ?, ?, ?) + INSERT INTO `forums_posts` + ( + `create_time`, + `message`, + `IdWriter`, + `IdFirstLanguageUsed`, + `PostVisibility`, + `PostDeleted`, + `IdContent`, + `edit_count` + ) + VALUES (NOW(), ?, ?, ?, ?, 'NotDeleted', 0, 0) "); $text = $this->cleanupText($vars['topic_text']); - $userId = $User->getId(); $memberId = $this->session->get("IdMember"); $language = $this->GetLanguageChoosen(); $statement->bindParam(1, $text); @@ -1464,11 +1456,11 @@ public function newTopic(&$vars) { $statement = $this->dao->prepare(" INSERT INTO `forums_threads` ( `title`, `first_postid`, `last_postid`, - `IdFirstLanguageUsed`,`IdGroup`,`ThreadVisibility`) - VALUES (?, ?, ?, ?, ?, ?) + `IdFirstLanguageUsed`,`IdGroup`,`ThreadVisibility`, `IdTitle`, `replies`, `views`, `stickyvalue`) + VALUES (?, ?, ?, ?, ?, ?, 0, 0, 0, 0) "); - $title = strip_tags($vars['topic_title']); + $title = strip_tags((string) $vars['topic_title']); $statement->bindParam(1, $title); $statement->bindParam(2, $postId); $statement->bindParam(3, $postId); @@ -1479,7 +1471,7 @@ public function newTopic(&$vars) { $result = $statement->execute(); $threadId = $statement->insertId(); - $ss=$this->dao->escape(strip_tags(($vars['topic_title']))) ; + $ss=$this->dao->escape(strip_tags(((string) $vars['topic_title']))) ; $this->InsertInFTrad($ss,"forums_threads.IdTitle",$threadId) ; $statement = $this->dao->prepare("UPDATE `forums_posts` SET `threadId` = ? WHERE `Id` = ?"); @@ -1551,11 +1543,11 @@ public function prepareTopic($WithDetail=false) { } if (isset($topicinfo->WhoCanReply)) { if ($topicinfo->WhoCanReply=="MembersOnly") { - $topicinfo->CanReply=true ; + $topicinfo->CanReply=$this->getLoggedInMember()->Status !== \App\Doctrine\MemberStatusType::ACCOUNT_ACTIVATED; } else if ($topicinfo->WhoCanReply=="GroupsMembersOnly") { if ($topicinfo->IdGroup==0) { - $topicinfo->CanReply=true ; + $topicinfo->CanReply=$this->getLoggedInMember()->Status !== \App\Doctrine\MemberStatusType::ACCOUNT_ACTIVATED ; } else { $topicinfo->CanReply=in_array($topicinfo->IdGroup,$this->MyGroups) ; // Set to true only if current member is member of the group @@ -1588,11 +1580,11 @@ public function prepareTopic($WithDetail=false) { message, IdContent, IdWriter, - geonames.name AS city, - geonamescountries.name AS country, + g.name AS city, + c.name AS country, forums_posts.threadid, OwnerCanStillEdit, - members.Username as OwnerUsername, + member.Username as OwnerUsername, PostVisibility, PostDeleted, forums_threads.IdGroup @@ -1600,13 +1592,13 @@ public function prepareTopic($WithDetail=false) { forums_threads, forums_posts LEFT - JOIN members ON forums_posts.IdWriter = members.id + JOIN member ON forums_posts.IdWriter = member.id LEFT JOIN - addresses AS a ON a.IdMember = members.id AND a.rank = 0 + address AS a ON a.member_id = member.id AND a.active = 1 LEFT JOIN - geonames ON a.IdCity = geonames.geonameId + geo__names g ON a.location = g.geoname_id LEFT JOIN - geonamescountries ON geonames.country = geonamescountries.country + geo__names c ON g.country = c.geoname_id WHERE forums_posts.threadid = '%d' AND forums_posts.threadid=forums_threads.id @@ -1624,8 +1616,8 @@ public function prepareTopic($WithDetail=false) { } while ($row = $s->fetch(PDB::FETCH_OBJ)) { if ($WithDetail) { // if details are required retrieve all the translated text for posts (sentence, owner, modification time and translator name) of this thread - $sw = $this->dao->query("select forum_trads.IdLanguage,UNIX_TIMESTAMP(forum_trads.created) as trad_created, UNIX_TIMESTAMP(forum_trads.updated) as trad_updated, forum_trads.Sentence,IdOwner,IdTranslator,languages.ShortCode,languages.EnglishName,mTranslator.Username as TranslatorUsername ,mOwner.Username as OwnerUsername - from forum_trads,languages,members as mOwner, members as mTranslator + $sw = $this->dao->query("select forum_trads.IdLanguage,UNIX_TIMESTAMP(forum_trads.created) as trad_created, UNIX_TIMESTAMP(forum_trads.updated) as trad_updated, forum_trads.Sentence,IdOwner,IdTranslator,languages.ShortCode,languages.Name,mTranslator.Username as TranslatorUsername ,mOwner.Username as OwnerUsername + from forum_trads,languages,member as mOwner, member as mTranslator where languages.id=forum_trads.IdLanguage and forum_trads.IdTrad=".$row->IdContent." and mOwner.id=IdOwner and mTranslator.id=IdTranslator order by forum_trads.id asc"); while ($roww = $sw->fetch(PDB::FETCH_OBJ)) { $row->Trad[]=$roww ; @@ -1686,21 +1678,21 @@ public function initLastPosts() { UNIX_TIMESTAMP(`create_time`) AS `posttime`, `message`, `IdContent`, - `members`.`Username` AS `OwnerUsername`, + `member`.`username` AS `OwnerUsername`, `IdWriter`, forums_threads.`id` as `threadid`, `PostVisibility`, `PostDeleted`, `ThreadDeleted`, `OwnerCanStillEdit`, - `geonames`.`name` as `city`, + `geo__names`.`name` as `city`, `geonamescountries`.`name` as `country`, `IdGroup` -FROM forums_posts, forums_threads, members, addresses -LEFT JOIN `geonames` ON (addresses.IdCity = `geonames`.`geonameId`) -LEFT JOIN `geonamescountries` ON (geonames.country = `geonamescountries`.`country`) -WHERE `forums_posts`.`threadid` = '%d' AND `forums_posts`.`IdWriter` = `members`.`id` -AND addresses.IdMember = members.id AND addresses.rank = 0 +FROM forums_posts, forums_threads, member, address +LEFT JOIN `geo__names` ON (address.location = `geo__names`.`geoname_id`) +LEFT JOIN `geonamescountries` ON (geo__names.country = `geonamescountries`.`country`) +WHERE `forums_posts`.`threadid` = '%d' AND `forums_posts`.`IdWriter` = `member`.`id` +AND address.member_id = member.id AND address.active = 1 AND `forums_posts`.`threadid`=`forums_threads`.`id` and ({$this->PublicPostVisibility}) and ({$this->PublicThreadVisibility}) @@ -1717,9 +1709,9 @@ public function initLastPosts() { if (!$s) { throw new PException('Could not retrieve Posts!'); } - $this->topic->posts = array(); + $this->topic->posts = []; while ($row = $s->fetch(PDB::FETCH_OBJ)) { - $sw = $this->dao->query("select forum_trads.IdLanguage,UNIX_TIMESTAMP(forum_trads.created) as trad_created, UNIX_TIMESTAMP(forum_trads.updated) as trad_updated, forum_trads.Sentence,IdOwner,IdTranslator,languages.ShortCode,languages.EnglishName,mTranslator.Username as TranslatorUsername ,mOwner.Username as OwnerUsername from forum_trads,languages,members as mOwner, members as mTranslator + $sw = $this->dao->query("select forum_trads.IdLanguage,UNIX_TIMESTAMP(forum_trads.created) as trad_created, UNIX_TIMESTAMP(forum_trads.updated) as trad_updated, forum_trads.Sentence,IdOwner,IdTranslator,languages.ShortCode,languages.Name,mTranslator.Username as TranslatorUsername ,mOwner.Username as OwnerUsername from forum_trads,languages,member as mOwner, member as mTranslator where languages.id=forum_trads.IdLanguage and forum_trads.IdTrad=".$row->IdContent." and mOwner.id=IdOwner and mTranslator.id=IdTranslator order by forum_trads.id asc"); while ($roww = $sw->fetch(PDB::FETCH_OBJ)) { $row->Trad[]=$roww ; @@ -1838,7 +1830,7 @@ public function unsubscribeGroup($IdGroup) { public function searchSubscriptions() { $member= $this->getLoggedInMember(); if (!$member) { - return array(); + return []; } $TResults = new StdClass(); $query = " @@ -1863,7 +1855,7 @@ public function searchSubscriptions() { throw new PException('Could not retrieve members_threads_subscribed sts via searchSubscription !'); } - $TResults->TData = array(); + $TResults->TData = []; while ($row = $s->fetch(PDB::FETCH_OBJ)) { $TResults->TData[] = $row; } @@ -1884,7 +1876,7 @@ public function searchSubscriptions() { if (!$s) { throw new PException('Could load group memberships'); } - $TResults->Groups = array(); + $TResults->Groups = []; while ($row = $s->fetch(PDB::FETCH_OBJ)) { $TResults->Groups[] = $row; } @@ -1905,9 +1897,9 @@ public function UnsubscribeThread($IdSubscribe=0,$Key="") { members_threads_subscribed.id AS IdSubscribe, IdThread, IdSubscriber, - Username from members, + Username from member, members_threads_subscribed -WHERE members.id=members_threads_subscribed.IdSubscriber +WHERE member.id=members_threads_subscribed.IdSubscriber AND members_threads_subscribed.id=%d AND UnSubscribeKey='%s' ", @@ -2002,10 +1994,10 @@ public function SubscribeThread($IdThread,$ParamIdMember=0) { MOD_log::get()->write("Allready subscribed to Thread=#".$IdThread, "Forum"); return(false) ; } - $key=MD5(rand(100000,900000)) ; + $key=MD5(random_int(100000,900000)) ; $query = "INSERT INTO - members_threads_subscribed(IdThread,IdSubscriber,UnSubscribeKey,notificationsEnabled) - VALUES(".$IdThread.",".$this->session->get("IdMember").",'".$this->dao->escape($key)."', 1)" ; + members_threads_subscribed(IdThread,IdSubscriber,UnSubscribeKey,notificationsEnabled,created) + VALUES(".$IdThread.",".$this->session->get("IdMember").",'".$this->dao->escape($key)."', 1,NOW())" ; $s = $this->dao->query($query); if (!$s) { throw new PException('Forum->SubscribeThread failed !'); @@ -2093,13 +2085,13 @@ public function searchUserposts($cid=0) { `PostVisibility`, `PostDeleted`, `ThreadDeleted`, - `forums_threads`.`IdTitle`,`forums_threads`.`IdGroup`, `IdWriter`, `members`.`Username` AS `OwnerUsername`, `groups`.`Name` AS `GroupName`, `geonames`.`country` - FROM (forums_posts, members, forums_threads, addresses) + `forums_threads`.`IdTitle`,`forums_threads`.`IdGroup`, `IdWriter`, `member`.`Username` AS `OwnerUsername`, `groups`.`Name` AS `GroupName`, `geo__names`.`country` + FROM (forums_posts, member, forums_threads, address) LEFT JOIN `groups` ON (`forums_threads`.`IdGroup` = `groups`.`id`) -LEFT JOIN `geonames` ON (addresses.IdCity = geonames.geonameId) -WHERE `forums_posts`.`IdWriter` = %d AND `forums_posts`.`IdWriter` = `members`.`id` +LEFT JOIN `geo__names` ON (address.location = geo__names.geoname_id) +WHERE `forums_posts`.`IdWriter` = %d AND `forums_posts`.`IdWriter` = `member`.`id` AND `forums_posts`.`threadid` = `forums_threads`.`id` -AND addresses.IdMember = members.id AND addresses.rank = 0 +AND address.member_id = member.id AND address.active = 1 AND ($this->PublicThreadVisibility) AND ($this->PublicPostVisibility) AND ($this->PostGroupsRestriction) @@ -2108,9 +2100,9 @@ public function searchUserposts($cid=0) { if (!$s) { throw new PException('Could not retrieve Posts via searchUserposts !'); } - $posts = array(); + $posts = []; while ($row = $s->fetch(PDB::FETCH_OBJ)) { - $sw = $this->dao->query("select forum_trads.IdLanguage,UNIX_TIMESTAMP(forum_trads.created) as trad_created, UNIX_TIMESTAMP(forum_trads.updated) as trad_updated, forum_trads.Sentence,IdOwner,IdTranslator,languages.ShortCode,languages.EnglishName,mTranslator.Username as TranslatorUsername ,mOwner.Username as OwnerUsername from forum_trads,languages,members as mOwner,members as mTranslator where languages.id=forum_trads.IdLanguage and forum_trads.IdTrad=".$row->IdContent." and mTranslator.id=IdTranslator and mOwner.id=IdOwner order by forum_trads.id asc"); + $sw = $this->dao->query("select forum_trads.IdLanguage,UNIX_TIMESTAMP(forum_trads.created) as trad_created, UNIX_TIMESTAMP(forum_trads.updated) as trad_updated, forum_trads.Sentence,IdOwner,IdTranslator,languages.ShortCode,languages.Name,mTranslator.Username as TranslatorUsername ,mOwner.Username as OwnerUsername from forum_trads,languages,member as mOwner,member as mTranslator where languages.id=forum_trads.IdLanguage and forum_trads.IdTrad=".$row->IdContent." and mTranslator.id=IdTranslator and mOwner.id=IdOwner order by forum_trads.id asc"); while ($roww = $sw->fetch(PDB::FETCH_OBJ)) { $row->Trad[]=$roww ; } @@ -2136,7 +2128,7 @@ public function isTopic() { private $threadid = 0; private $page = 1; - private $page_array = array(); + private $page_array = []; private $messageId = 0; private $TopMode=Forums::CV_TOPMODE_LANDING; // define that we use the landing page for top mode @@ -2209,14 +2201,14 @@ private function cleanupText($txt) } // end of cleanupText function GetLanguageName($IdLanguage) { - $query="select id as IdLanguage,Name,EnglishName,ShortCode,WordCode from languages where id=".($IdLanguage) + $query="select id as IdLanguage,Name,Name,ShortCode from languages where id=".($IdLanguage) . " AND IsWrittenLanguage = 1"; $s = $this->dao->query($query); if (!$s) { throw new PException('Could not retrieve IdLanguage in GetLanguageName entries'); } else { $row = $s->fetch(PDB::FETCH_OBJ) ; - $row->Name = $this->getWords()->getSilent($row->WordCode) . " (" . $row->Name . ")"; + $row->Name = $this->getWords()->getSilent('lang' . $row->ShortCode) . " (" . $row->Name . ")"; return($row) ; } return("not Found") ; @@ -2229,8 +2221,8 @@ function GetLanguageName($IdLanguage) { public function LanguageChoices($DefIdLanguage=-1) { - $tt=array() ; - $allreadyin=array() ; + $tt=[] ; + $allreadyin=[] ; $ii=0 ; // First proposed will deflanguage @@ -2258,14 +2250,14 @@ public function LanguageChoices($DefIdLanguage=-1) { array_push($tt, "AllLanguages"); // then now all available languages - $query="select id as IdLanguage,Name,EnglishName,ShortCode,WordCode from languages where id>0" + $query="select id as IdLanguage,Name,Name,ShortCode from languages where id>0" . " AND IsWrittenLanguage = 1"; $s = $this->dao->query($query); - $langarr = array(); + $langarr = []; while ($row = $s->fetch(PDB::FETCH_OBJ)) { if (!in_array($row->IdLanguage,$allreadyin)) { array_push($allreadyin,$row->IdLanguage) ; - $row->Name = $this->getWords()->getSilent($row->WordCode) . " (" . trim($row->Name) . ")"; + $row->Name = $this->getWords()->getSilent('lang_' . $row->ShortCode) . " (" . trim((string) $row->Name) . ")"; $langarr[] = $row; } } @@ -2276,7 +2268,7 @@ public function LanguageChoices($DefIdLanguage=-1) { // This fonction will prepare a list of group in an array that the moderator can use public function ModeratorGroupChoice() { - $tt=array() ; + $tt=[] ; $query="select groups.id as IdGroup,Name,count(*) as cnt from groups,membersgroups WHERE membersgroups.IdGroup=groups.id group by groups.id order by Name "; @@ -2292,11 +2284,11 @@ public function ModeratorGroupChoice() { // This fonction will prepare a list of group in an array that the user can use // (according to his member ship) public function GroupChoice() { - $tt=array() ; + $tt=[] ; - $query="select groups.id as IdGroup,Name,count(*) as cnt from groups,membersgroups,members - WHERE membersgroups.IdGroup=groups.id and members.id=membersgroups.IdMember and - members.Status in ('Active','ActiveHidden') and members.id=".$this->session->get('IdMember')." and membersgroups.Status='In' group by groups.id order by groups.id "; + $query="select groups.id as IdGroup,groups.Name,count(*) as cnt from groups,membersgroups,member + WHERE membersgroups.IdGroup=groups.id and member.id=membersgroups.IdMember and + member.Status in ('Active','ActiveHidden') and member.id=".$this->session->get('IdMember')." and membersgroups.Status='In' group by groups.id order by groups.id "; $s = $this->dao->query($query); while ($row = $s->fetch(PDB::FETCH_OBJ)) { $row->GroupName=$this->getGroupName($row->Name); @@ -2379,7 +2371,7 @@ private function prepare_notification($postId, $type) { return; } - $members = array(); // collects all members that get a notification (to avoid several notifications for the same post) + $members = []; // collects all members that get a notification (to avoid several notifications for the same post) // first we get all open (ToSend) post notifications from the database and build // a list of members that don't need another reminder @@ -2403,7 +2395,7 @@ private function prepare_notification($postId, $type) { // get group members in case of a group post to limit subscriptions to tags and threads $group = false; - $groupMembers = array(); + $groupMembers = []; if ($post->groupId != 0) { $group = $this->createEntity('Group')->findById($post->groupId); $memberEntities = $group->getMembers(); @@ -2416,7 +2408,7 @@ private function prepare_notification($postId, $type) { // We reuse the $group entity from above $subscriberEntities = $group->getEmailAcceptingMembers(); - $membersTemp = array(); + $membersTemp = []; foreach($subscriberEntities as $subscriber) { $memberId = $subscriber->getPKValue(); if ($memberId == 0) continue; @@ -2465,7 +2457,7 @@ private function prepare_notification($postId, $type) { return; } - $membersTemp = array(); + $membersTemp = []; while ($row = $res->fetch(PDB::FETCH_OBJ)) { if ($row->subscriber > 0) { // did member disable notifications for this thread? @@ -2613,7 +2605,7 @@ public function searchForums($keywords, $currentPage, $items = 30) { $client = new Client($config); $query = new Search($client); $query - ->setIndex('forum_rt') + ->setTable('forum_rt') ->limit(1000) ->sort(['post_id' => 'DESC']) ; @@ -2680,7 +2672,7 @@ public function searchForums($keywords, $currentPage, $items = 30) { $query = " SELECT SQL_CALC_FOUND_ROWS `forums_posts`.`id`, - `members`.`Username`, + `member`.`Username`, `forums_posts`.`message`, `forum_trads`.`Sentence`, `forums_threads`.`id` AS `IdThread`, @@ -2691,7 +2683,7 @@ public function searchForums($keywords, $currentPage, $items = 30) { `forums_threads`.`ThreadVisibility`, `forums_threads`.`ThreadDeleted`, UNIX_TIMESTAMP(`forums_posts`.`create_time`) AS `created`, - geonames.name AS city, + geo__names.name AS city, geonamescountries.name AS country FROM `forums_posts` @@ -2702,13 +2694,13 @@ public function searchForums($keywords, $currentPage, $items = 30) { LEFT JOIN `forum_trads` ON (`forum_trads`.`IdTrad` = `forums_posts`.`IdContent` AND `forum_trads`.`IdLanguage` = {$languageId}) LEFT JOIN - `members` ON (`forums_posts`.`IdWriter` = `members`.`id`) + `member` ON (`forums_posts`.`IdWriter` = `member`.`id`) LEFT JOIN - `addresses` ON `members`.`id` = `addresses`.`IdMember` + `address` ON `member`.`id` = `address`.`member_id` and `address`.`active` = 1 LEFT JOIN - `geonames` ON `addresses`.IdCity = `geonames`.`geonameId` + `geo__names` ON `address`.location = `geo__names`.`geoname_id` LEFT JOIN - `geonamescountries` ON `geonames`.`country` = `geonamescountries`.`country` + `geonamescountries` ON `geo__names`.`country` = `geonamescountries`.`country` WHERE `forums_posts`.`id` IN ({$separatedPostIds}) AND (`forums_threads`.`IdGroup` IN ({$separatedGroupIds}) OR `forums_threads`.`IdGroup` IS NULL) @@ -2762,7 +2754,7 @@ public function searchProcess() { $vars_ok = $this->_checkVarsSearch($vars); if ($vars_ok) { - $keyword = htmlspecialchars($vars['fs-keyword']); + $keyword = htmlspecialchars((string) $vars['fs-keyword']); PPostHandler::clearVars(); return PVars::getObj('env')->baseuri.$this->forums_uri.'search/'. $keyword; } @@ -2776,7 +2768,7 @@ private function addPostToManticoreIndex($vars, $postId, $threadId, $memberId, $ $port = PVars::getObj('env')->manticore_port; $config = ['host' => $host, 'port' => $port]; $client = new Client($config); - $index = $client->index('forum_rt'); + $index = $client->table('forum_rt'); $index->addDocument([ 'post_id' => $postId, 'post_deleted' => 'NotDeleted', @@ -2802,7 +2794,7 @@ private function updatePostInManticoreIndex($vars) // Find document in index $query = new Search($client); $query - ->setIndex('forum_rt') + ->setTable('forum_rt') ->filter('post_id', 'equals', $postId) ->filter('thread_id', 'equals', $threadId) ; @@ -2814,7 +2806,7 @@ private function updatePostInManticoreIndex($vars) $data['content'] = $vars['Sentence']; // Then replace with new content - $index = $client->index('forum_rt'); + $index = $client->table('forum_rt'); $index->replaceDocument($data, $hit->getId()); } } // end of class Forums @@ -2822,14 +2814,14 @@ private function updatePostInManticoreIndex($vars) class Topic { public $topicinfo; - public $posts = array(); + public $posts = []; } class Board implements Iterator { public $THREADS_PER_PAGE ; //Variable because it can change wether the user is logged or no public $POSTS_PER_PAGE ; //Variable because it can change wether the user is logged or no - public function __construct(&$dao, $boardname, $link, $session, $board_description=false, $IdGroup=false, $no_forumsgroup=false) { + public function __construct(&$dao, private $boardname, private $link, $session, private $board_description=false, $IdGroup=false, $no_forumsgroup=false) { $this->THREADS_PER_PAGE=Forums::CV_THREADS_PER_PAGE ; //Variable because it can change wether the user is logged or no $this->POSTS_PER_PAGE=Forums::CV_POSTS_PER_PAGE ; //Variable because it can change wether the user is logged or no @@ -2842,10 +2834,6 @@ public function __construct(&$dao, $boardname, $link, $session, $board_descripti } $this->dao =& $dao; - - $this->boardname = $boardname; - $this->board_description = $board_description; - $this->link = $link; $this->IdGroup = $IdGroup; $this->PublicThreadVisibility = "(ThreadVisibility!='ModeratorOnly') and (ThreadDeleted!='Deleted')"; @@ -2918,7 +2906,7 @@ public function __construct(&$dao, $boardname, $link, $session, $board_descripti this filtres the list of thread results according to the presence of : $this->IdGroup ; */ - public function FilterThreadListResultsWithIdCriteria($ids = array()) { + public function FilterThreadListResultsWithIdCriteria($ids = []) { $wherethread="" ; if (count($ids) <> 0) { @@ -2948,9 +2936,9 @@ public function FilterThreadListResultsWithIdCriteria($ids = array()) { * @param array $ids * @throws PException */ - public function initThreads($page = 1, $showsticky = true, $ids = array()) { + public function initThreads($page = 1, $showsticky = true, $ids = []) { - $this->threads = array(); + $this->threads = []; $wherethread=$this->FilterThreadListResultsWithIdCriteria($ids) ; if ($showsticky) { @@ -2999,8 +2987,8 @@ public function initThreads($page = 1, $showsticky = true, $ids = array()) { WHERE fp.threadid = `forums_threads`.`id` AND fp.PostDeleted = 'NotDeleted' ) "; - $query .= "LEFT JOIN `members` AS `first_member` ON (`first`.`IdWriter` = `first_member`.`id`)" ; - $query .= "LEFT JOIN `members` AS `last_member` ON (`last`.`IdWriter` = `last_member`.`id`)" ; + $query .= "LEFT JOIN `member` AS `first_member` ON (`first`.`IdWriter` = `first_member`.`id`)" ; + $query .= "LEFT JOIN `member` AS `last_member` ON (`last`.`IdWriter` = `last_member`.`id`)" ; $query .= " WHERE 1 ".$wherethread . $orderby . " LIMIT ".$from.", ".$this->THREADS_PER_PAGE ; @@ -3021,20 +3009,14 @@ public function initThreads($page = 1, $showsticky = true, $ids = array()) { } // end of initThreads - private $threads = array(); + private $threads = []; public function getThreads() { return $this->threads; } - - private $boardname; public function getBoardName() { return $this->boardname; } - private $board_description; - - private $link; - public function getNumberOfThreads() { return $this->numberOfThreads; } @@ -3043,7 +3025,7 @@ public function getTotalThreads() { return $this->totalThreads; } - private $subboards = array(); + private $subboards = []; // Add a subboard public function add(Board $board) { diff --git a/build/forums/forums.view.php b/build/forums/forums.view.php index 0c4d0579dc..a3bed3f255 100644 --- a/build/forums/forums.view.php +++ b/build/forums/forums.view.php @@ -96,7 +96,7 @@ public function threadURL($thread, $baseurl = false) if ($baseurl === false) { $baseurl = $this->uri; } - return $baseurl.'s'.$thread->id.'-'.preg_replace('/[^A-Za-z0-9]/', '_',$this->words->fTrad($thread->IdTitle) ) ; + return $baseurl.'s'.$thread->id.'-'.preg_replace('/[^A-Za-z0-9]/', '_',(string) $this->words->fTrad($thread->IdTitle) ) ; } public function postURL($post, $baseurl = false) @@ -108,7 +108,7 @@ public function postURL($post, $baseurl = false) { $baseurl = 'group/' . $post->IdGroup . '/forum/'; } - return $baseurl.'s'.$post->threadid.'-'.preg_replace('/[^A-Za-z0-9]/', '_',$this->words->fTrad($post->IdTitle) ) ; + return $baseurl.'s'.$post->threadid.'-'.preg_replace('/[^A-Za-z0-9]/', '_',(string) $this->words->fTrad($post->IdTitle) ) ; } public function groupURL($post, $baseurl = false) @@ -230,6 +230,9 @@ public function ModeditPost(&$callbackId) { * Display a topic */ public function showTopic() { + $this->page->addStyleSheet('build/lightbox.css'); + $this->page->addLateLoadScriptFile('build/lightbox.js'); + $topic = $this->_model->getTopic(); $request = PRequest::get()->request; @@ -246,7 +249,7 @@ public function showTopic() { } if (empty($this->session->get('IdMember'))) { if (isset($topic->posts[0])) { - $this->page->SetMetaDescription(strip_tags($this->_model->words->fTrad(($topic->posts[0]->IdContent)))) ; ; + $this->page->SetMetaDescription(strip_tags((string) $this->_model->words->fTrad(($topic->posts[0]->IdContent)))) ; ; } } @@ -518,7 +521,7 @@ private function getPageLinks($currentPage, $itemsPerPage, $max) { } $offs = ($currentPage - 1) * $itemsPerPage; - $pages = array(); + $pages = []; $j = 0; for ($i = 1; $i <= $maxPage; $i++) { if ($i <= ($currentPage - 3) && $i != 1 && $i != 2) { @@ -531,7 +534,7 @@ private function getPageLinks($currentPage, $itemsPerPage, $max) { $pages[] = 'separator'; } $j = $i; - $p = array('pageno' => $i); + $p = ['pageno' => $i]; if ($i == $currentPage) { $p['current'] = true; } diff --git a/build/forums/templates/boardonecategory.php b/build/forums/templates/boardonecategory.php index b8bbd6f855..9cc7f058ba 100644 --- a/build/forums/templates/boardonecategory.php +++ b/build/forums/templates/boardonecategory.php @@ -21,7 +21,7 @@ Boston, MA 02111-1307, USA. */ - $styles = array( 'highlight', 'blank' ); + $styles = [ 'highlight', 'blank' ]; $words = new MOD_words(); ?> diff --git a/build/forums/templates/categories_continents_tagcloud.php b/build/forums/templates/categories_continents_tagcloud.php index 8c8cd6ef75..300515d876 100644 --- a/build/forums/templates/categories_continents_tagcloud.php +++ b/build/forums/templates/categories_continents_tagcloud.php @@ -65,7 +65,7 @@ $TagName=$this->words->fTrad($tag->IdName) ; $TagDescription=$this->words->fTrad($tag->IdDescription) ; - $tagcloudlist .= ''; + $tagcloudlist .= ''; } $tagcloudlist = rtrim($tagcloudlist, ': '); diff --git a/build/forums/templates/editcreateform.php b/build/forums/templates/editcreateform.php index 8cc60f7c1f..894385b784 100644 --- a/build/forums/templates/editcreateform.php +++ b/build/forums/templates/editcreateform.php @@ -57,7 +57,7 @@ echo $words->getFormatted("forum_edit_post"); } else { $backUrl = str_replace('/reply', '', $uri); - echo $words->getFormatted("forum_reply_title") . ' "' . strip_tags($topic->topicinfo->title) . '"'; + echo $words->getFormatted("forum_reply_title") . ' "' . strip_tags((string) $topic->topicinfo->title) . '"'; } } echo ''; @@ -109,7 +109,7 @@ ?> + value="" aria-describedby="forumaddtitle"> @@ -118,11 +118,11 @@
    - diff --git a/build/forums/templates/landing.php b/build/forums/templates/landing.php index dea34049c8..9e33fd01aa 100644 --- a/build/forums/templates/landing.php +++ b/build/forums/templates/landing.php @@ -95,7 +95,7 @@
    flushBuffer(); } - $multipages = array($forumpages, $currentGroupsPage); + $multipages = [$forumpages, $currentGroupsPage]; $currentPage = $currentForumPage; $maxPage = $forumMaxPage; diff --git a/build/forums/templates/modtagform.php b/build/forums/templates/modtagform.php index 64ca9476ff..6386c62b8e 100644 --- a/build/forums/templates/modtagform.php +++ b/build/forums/templates/modtagform.php @@ -1,145 +1,145 @@ - or -write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. - -*/ - -$words = new MOD_words(); - -?> -

    Editing Tag # -IdTag ; -if (isset($DataTag->Tag->tag)) echo " [".$DataTag->Tag->tag."]" ; -?> -

    -

    -Error)) { - echo "

    ",$DataTag->Error,"

    " ; -} - -$request = PRequest::get()->request; -$uri = implode('/', $request); - - -echo "" ; -echo "" ; - -// print_r($DataTag) ; -// Display the various content for this tag in various languages -$max=count($DataTag->Names) ; -echo "" ; -if (isset($DataTag->Tag->description)) echo "" ; -echo "" ; -foreach ($DataTag->Names as $Content) { - - echo "id."\" id=\"modtagforum\">" ; - echo "" ; - echo "IdTag."\"/>" ; - $ArrayLanguage=$this->_model->LanguageChoices($Content->IdLanguage) ; - echo "" ; - echo "" ; - echo "\n" ; -} -// Display the various description for this tag in various languages -$max=count($DataTag->Descriptions) ; -echo "" ; -echo "" ; -foreach ($DataTag->Descriptions as $Content) { - if (empty($Content->IdLanguage)) { - $Content->IdLanguage=0 ; // force to english - } - echo "id."\" id=\"modtagforum\">" ; - echo "" ; - echo "IdTag."\"/>" ; - $ArrayLanguage=$this->_model->LanguageChoices($Content->IdLanguage) ; - echo "" ; - echo "\n" ; -} - -// Now propose the to add a translation -echo "" ; -echo "id."\" id=\"modtagforum\">" ; -echo "" ; -echo "IdTag."\"/>" ; -echo "Tag->IdName."\"/>" ; -echo "Tag->IdDescription."\"/>" ; -if (!isset($Content->IdLanguage)) { - die ("Bug in modtagform.php \$Content->IdLanguage is not set !") ; -} -$ArrayLanguage=$this->_model->LanguageChoices($Content->IdLanguage) ; -echo "" ; -echo "\n" ; - -// Now propose to replace another tag with this one -echo "" ; -echo "id."\" id=\"modtagforum\">" ; -echo "" ; -echo "IdTag."\"/>" ; -echo "" ; -echo "\n" ; - -echo "
    Tag->id."\">go to tag     forum main page " ; -echo " This tag is used by ",$DataTag->NbThread," thread(s)
    tag (old TB way)" ,$DataTag->Tag->description,"
    Content of tag ($max translations)
    " ; - echo "\n" ; - - - echo "\n" ; - echo "IdForumTrads."\">
    Content of descriptions ($max translations)
    " ; - echo "\n" ; - - - echo "\n" ; - echo "IdForumTrads."\">" ; - echo "
    " ; -echo "\n" ; - - -echo "Name
    Description\n
    " ; -echo "USE CAREFULLY !
    here you can enter the #id of a tag which will be deleted and will have all its entries in forum treads replaced by the current tag (".$words->fTrad($DataTag->Tag->IdName).")" ; -echo "
    numeric Id of the tag to delete and replace
    " ; -?> -

    + or +write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, +Boston, MA 02111-1307, USA. + +*/ + +$words = new MOD_words(); + +?> +

    Editing Tag # +IdTag ; +if (isset($DataTag->Tag->tag)) echo " [".$DataTag->Tag->tag."]" ; +?> +

    +

    +Error)) { + echo "

    ",$DataTag->Error,"

    " ; +} + +$request = PRequest::get()->request; +$uri = implode('/', $request); + + +echo "" ; +echo "" ; + +// print_r($DataTag) ; +// Display the various content for this tag in various languages +$max=count($DataTag->Names) ; +echo "" ; +if (isset($DataTag->Tag->description)) echo "" ; +echo "" ; +foreach ($DataTag->Names as $Content) { + + echo "id."\" id=\"modtagforum\">" ; + echo "" ; + echo "IdTag."\"/>" ; + $ArrayLanguage=$this->_model->LanguageChoices($Content->IdLanguage) ; + echo "" ; + echo "" ; + echo "\n" ; +} +// Display the various description for this tag in various languages +$max=count($DataTag->Descriptions) ; +echo "" ; +echo "" ; +foreach ($DataTag->Descriptions as $Content) { + if (empty($Content->IdLanguage)) { + $Content->IdLanguage=0 ; // force to english + } + echo "id."\" id=\"modtagforum\">" ; + echo "" ; + echo "IdTag."\"/>" ; + $ArrayLanguage=$this->_model->LanguageChoices($Content->IdLanguage) ; + echo "" ; + echo "\n" ; +} + +// Now propose the to add a translation +echo "" ; +echo "id."\" id=\"modtagforum\">" ; +echo "" ; +echo "IdTag."\"/>" ; +echo "Tag->IdName."\"/>" ; +echo "Tag->IdDescription."\"/>" ; +if (!isset($Content->IdLanguage)) { + die ("Bug in modtagform.php \$Content->IdLanguage is not set !") ; +} +$ArrayLanguage=$this->_model->LanguageChoices($Content->IdLanguage) ; +echo "" ; +echo "\n" ; + +// Now propose to replace another tag with this one +echo "" ; +echo "id."\" id=\"modtagforum\">" ; +echo "" ; +echo "IdTag."\"/>" ; +echo "" ; +echo "\n" ; + +echo "
    Tag->id."\">go to tag     forum main page " ; +echo " This tag is used by ",$DataTag->NbThread," thread(s)
    tag (old TB way)" ,$DataTag->Tag->description,"
    Content of tag ($max translations)
    " ; + echo "\n" ; + + + echo "\n" ; + echo "IdForumTrads."\">
    Content of descriptions ($max translations)
    " ; + echo "\n" ; + + + echo "\n" ; + echo "IdForumTrads."\">" ; + echo "
    " ; +echo "\n" ; + + +echo "Name
    Description\n
    " ; +echo "USE CAREFULLY !
    here you can enter the #id of a tag which will be deleted and will have all its entries in forum treads replaced by the current tag (".$words->fTrad($DataTag->Tag->IdName).")" ; +echo "
    numeric Id of the tag to delete and replace
    " ; +?> +

    diff --git a/build/forums/templates/replyLastPosts.php b/build/forums/templates/replyLastPosts.php index 58a5e6971a..98377e4f35 100644 --- a/build/forums/templates/replyLastPosts.php +++ b/build/forums/templates/replyLastPosts.php @@ -47,7 +47,7 @@ $postAuthor = $post->OwnerUsername; if ($postAuthor !== $username && !in_array($postAuthor, $authors)) { $authors[] = $postAuthor; - echo ''; + echo ''; } require 'singlepost.php'; $cntx = $cnt; diff --git a/build/forums/templates/reportslist.php b/build/forums/templates/reportslist.php index 4fbb4c2763..5f90ed3436 100644 --- a/build/forums/templates/reportslist.php +++ b/build/forums/templates/reportslist.php @@ -27,13 +27,13 @@ $request = PRequest::get()->request; if (!isset($vars['errors']) || !is_array($vars['errors'])) { - $vars['errors'] = array(); + $vars['errors'] = []; } $list=$DataPost ; // Retrieve the data to display (set by the controller) $words = new MOD_words(); -$styles = array( 'highlight', 'blank' ); // alternating background for table rows +$styles = [ 'highlight', 'blank' ]; // alternating background for table rows $iiMax = count($list) ; // This retrieve the number of polls ?> diff --git a/build/forums/templates/searchresultposts.php b/build/forums/templates/searchresultposts.php index 77c54da648..b63ee37278 100644 --- a/build/forums/templates/searchresultposts.php +++ b/build/forums/templates/searchresultposts.php @@ -39,21 +39,21 @@ ?> - +
    -

    get('GroupsSearchDiscussionsGroup', htmlspecialchars($keyword, ENT_QUOTES)); ?>

    +

    get('GroupsSearchDiscussionsGroup', htmlspecialchars((string) $keyword, ENT_QUOTES)); ?>

    render(); $words = new MOD_words(); - $styles = array('l-search-post--dark', ''); + $styles = ['l-search-post--dark', '']; $cnt = 0; foreach ($posts as $post) { ?> -
    +
    Name); ?>Name); ?>
    AcceptMails == 'yes') { ?> diff --git a/build/forums/templates/singlepost.php b/build/forums/templates/singlepost.php index 29b17b013b..abddd27086 100644 --- a/build/forums/templates/singlepost.php +++ b/build/forums/templates/singlepost.php @@ -30,7 +30,7 @@ use App\Utilities\ForumUtilities; $words = new MOD_words(); -$styles = array('l-forum-single-post--dark', ''); +$styles = ['l-forum-single-post--dark', '']; if (!isset($topic)) { $topic = new stdClass(); $topic->WithDetail = false; @@ -69,7 +69,9 @@ for ($jj = 0; (($jj < $max) and ($topic->WithDetail)); $jj++) { // Not optimized, it is a bit stupid to look in all the trads here if (($post->Trad[$jj]->trad_created != $post->Trad[$jj]->trad_updated)) { // If one of the trads have been updated if ($post->Trad[$jj]->IdLanguage == $this->session->get("IdLanguage")) { - echo '
    ' . date($words->getFormatted('DateHHMMShortFormat'), ServerToLocalDateTime($post->Trad[$jj]->trad_updated, $this->getSession())), ' by ', $post->Trad[$jj]->TranslatorUsername . '
    '; + if (null !== $post->Trad[$jj]->trad_updated) { + echo '
    ' . date($words->getFormatted('DateHHMMShortFormat'), ServerToLocalDateTime($post->Trad[$jj]->trad_updated, $this->getSession())), ' by ', $post->Trad[$jj]->TranslatorUsername . '
    '; + } } } } @@ -121,7 +123,7 @@ // Todo : the title for translations pops up when the mouse goes on the link but the html inside it is strips, the todo is to popup something which also displays the html result - $ssSentence = str_replace("\"", """, addslashes(strip_tags($Trad->Sentence, "



    • "))); + $ssSentence = str_replace("\"", """, addslashes(strip_tags((string) $Trad->Sentence, "



      • "))); $ssSentence = str_replace("\n", "", $ssSentence); // If we dont remove teh extraline breaks, javascript with on mosover for translation doesn't work // $ssTitle=addslashes(strip_tags(str_replace("

        "," ",$Trad->Sentence))) ; if ($jj == 0) { @@ -141,7 +143,8 @@ RemoveFQDN($words->fTrad($post->IdContent)); + $postContent = $forumUtilities->removeFqdn($words->fTrad($post->IdContent)); + $postContent = ForumUtilities::addLightboxToFigures($postContent); if (($post->PostDeleted == "Deleted")&&($this->BW_Right->HasRight("ForumModerator"))) { diff --git a/build/forums/templates/tagcloud_and_toptags.php b/build/forums/templates/tagcloud_and_toptags.php index 6dd44ae935..f9743d35eb 100644 --- a/build/forums/templates/tagcloud_and_toptags.php +++ b/build/forums/templates/tagcloud_and_toptags.php @@ -28,7 +28,7 @@ $TagCategory=$this->words->fTrad($tag->IdName) ; $TagDescription=$this->words->fTrad($tag->IdDescription) ; // echo '

      • '.$TagCategory.'
      • ' ; - echo '
      • '.$TagCategory.'
        ' ; + echo '
      • '.$TagCategory.'
        ' ; echo ' '.$TagDescription.'
      • '; } ?> diff --git a/build/forums/templates/topcategories.php b/build/forums/templates/topcategories.php index 140ef7ede4..dd34cda9e7 100644 --- a/build/forums/templates/topcategories.php +++ b/build/forums/templates/topcategories.php @@ -52,7 +52,7 @@ if (isset($list->IdName)) { $TagName=$this->words->fTrad($list->IdName) ; $tag_description=$this->words->fTrad($list->IdDescription) ; - echo ''.$TagName.'' ; + echo ''.$TagName.'' ; } else { $TagName=$this->words->getFormatted('ForumNoSpecificCategories') ; $tag_description="here goes the unclassfied forums post" ; diff --git a/build/forums/templates/topic.php b/build/forums/templates/topic.php index ff0c2ca74d..5b5c5156d1 100644 --- a/build/forums/templates/topic.php +++ b/build/forums/templates/topic.php @@ -147,7 +147,7 @@ } if ($User) { - if (!$topic->topicinfo->IsClosed) { + if (!$topic->topicinfo->IsClosed && $topic->topicinfo->CanReply) { ?>
        diff --git a/build/forums/templates/unsubscriberesult.php b/build/forums/templates/unsubscriberesult.php index d14952db8e..0bd1958392 100644 --- a/build/forums/templates/unsubscriberesult.php +++ b/build/forums/templates/unsubscriberesult.php @@ -34,7 +34,10 @@ } echo "


        \n" ; - if ($this->session->has( "IdMember" ) { - echo "

        ",$words->getFormatted("forum_ToSeeYourSubscription"),"

        " ; + if ($this->session->has( "IdMember" )) { + echo "

        " + . $words->getFormatted("forum_ToSeeYourSubscription") + . "

        " + ; } -?> + diff --git a/build/forums/templates/userbar.php b/build/forums/templates/userbar.php index 0638e212ef..9ce544e374 100755 --- a/build/forums/templates/userbar.php +++ b/build/forums/templates/userbar.php @@ -38,7 +38,7 @@

        Moderation actions

        BW_Right->HasRight("ForumModerator")) { ?> diff --git a/build/forums/thread.entity.php b/build/forums/thread.entity.php index 7288312825..27842149ae 100644 --- a/build/forums/thread.entity.php +++ b/build/forums/thread.entity.php @@ -12,7 +12,6 @@ class Thread extends RoxEntityBase public function __construct($thread_id = false) { - parent::__construct(); if (intval($thread_id)) { $this->findByThreadId(intval($thread_id)); diff --git a/build/gallery/gallery.ctrl.php b/build/gallery/gallery.ctrl.php index dfc73ca826..ccefbd26b5 100644 --- a/build/gallery/gallery.ctrl.php +++ b/build/gallery/gallery.ctrl.php @@ -87,7 +87,7 @@ public function index() break; case 'uploaded_done': - $galleryId = (isset($_GET['id'])) ? $_GET['id'] : false; + $galleryId = $_GET['id'] ?? false; $this->ajaxlatestimages($galleryId, true); PPHP::PExit(); break; @@ -106,7 +106,7 @@ public function index() if (isset($request[2])) { $vars['gallery'] = $this->_model->updateGalleryProcess(); } - $insertId = isset($vars['gallery']) ? $vars['gallery'] : mysqli_insert_id(); + $insertId = $vars['gallery'] ?? mysqli_insert_id(); $loc_rel = 'gallery/show/sets/'.$insertId; header('Location: ' . PVars::getObj('env')->baseuri . $loc_rel); PVars::getObj('page')->output_done = true; @@ -133,12 +133,10 @@ public function index() !$this->imageIsPublic($image)) { $this->redirectToLogin(implode('/', $request)); } - switch (isset($request[4]) ? $request[4] : '') { - case 'delete': - return $this->deleteImage($image); - default: - return $this->image($image); - } + return match ($request[4] ?? '') { + 'delete' => $this->deleteImage($image), + default => $this->image($image), + }; break; case 'galleries': @@ -186,19 +184,12 @@ public function index() ); } if (isset($request[4]) - && (substr( - $request[4], 0, 5 - ) != '=page') + && (!str_starts_with($request[4], '=page')) ) { - switch ($request[4]) { - case 'galleries': - case 'sets': - return $this->user($userId); - case 'pictures': - case 'images': - default: - return $this->userimages($userId); - } + return match ($request[4]) { + 'galleries', 'sets' => $this->user($userId), + default => $this->userimages($userId), + }; } return $this->user($userId); } @@ -489,14 +480,14 @@ private function ajaxImageGallery($type) { echo $words->get('GalleryCannotBeEmpty'); } else { $this->_model->ajaxModImageGallery($type,$id,$str,''); - $str = utf8_decode(addslashes(preg_replace("/\r|\n/s", "",nl2br($str)))); + $str = mb_convert_encoding(addslashes((string) preg_replace("/\r|\n/s", "",nl2br($str))), 'ISO-8859-1'); echo $str; } } if( isset($_GET['text']) ) { $str = htmlentities($_GET['text'], ENT_QUOTES, "UTF-8"); $this->_model->ajaxModImageGallery($type, $id,'',$str); - $str = utf8_decode(addslashes(preg_replace("/\r|\n/s", "",nl2br($str)))); + $str = mb_convert_encoding(addslashes((string) preg_replace("/\r|\n/s", "",nl2br($str))), 'ISO-8859-1'); if ($str === '') { echo $words->get('GalleryAddDescription'); } else { @@ -526,8 +517,8 @@ public function createGalleryCallback($args, $action, $mem_redirect, $mem_resend //$errors = $this->model->checkCreateGalleryForm($vars); // Not a lot to check at this point: - $errors = array(); - $desc = (isset($vars['g-description'])) ? $vars['g-description'] : false; + $errors = []; + $desc = $vars['g-description'] ?? false; if (!isset($vars['g-title']) || $vars['g-title'] == "") $errors[] = 'ErrorGalleryNoTitleSet'; if (count($errors) > 0) { @@ -564,7 +555,7 @@ public function editProcess() } else { - PPostHandler::setCallback($callbackId, __CLASS__, __FUNCTION__); + PPostHandler::setCallback($callbackId, self::class, __FUNCTION__); return $callbackId; } } @@ -589,7 +580,7 @@ public function editGalleryProcess() } else { - PPostHandler::setCallback($callbackId, __CLASS__, __FUNCTION__); + PPostHandler::setCallback($callbackId, self::class, __FUNCTION__); return $callbackId; } } @@ -631,7 +622,7 @@ public function commentProcess($image = false) } else { - PPostHandler::setCallback($callbackId, __CLASS__, __FUNCTION__); + PPostHandler::setCallback($callbackId, self::class, __FUNCTION__); return $callbackId; } } @@ -646,7 +637,7 @@ public function uploadProcess() } else { - PPostHandler::setCallback($callbackId, __CLASS__, __FUNCTION__); + PPostHandler::setCallback($callbackId, self::class, __FUNCTION__); return $callbackId; } } @@ -672,6 +663,7 @@ public function thumbImg($id) $thumbFile = 'nopic.gif'; $d->mimetype = 'image/gif'; } + header('Cache-Control: max-age=604800'); header('Content-type: '.$d->mimetype); $tmpDir->readFile($thumbFile); PPHP::PExit(); diff --git a/build/gallery/gallery.model.php b/build/gallery/gallery.model.php index d2daf817d6..56a594e8ea 100644 --- a/build/gallery/gallery.model.php +++ b/build/gallery/gallery.model.php @@ -368,7 +368,7 @@ public function getLatestItems($userId = false, $galleryId = false, $numRows = f a.`title` AS album, a.`id` AS albumId FROM `gallery_items` AS i -LEFT JOIN `members` AS `m` ON +LEFT JOIN `member` AS `m` ON m.`id` = i.`user_id_foreign` LEFT JOIN `gallery_items_to_gallery` AS `g` ON g.`item_id_foreign` = i.`id` @@ -414,7 +414,7 @@ public function getNextItems($imageId,$limit = 1,$userId = false,$galleryId = fa i.`title`, i.`created` FROM `gallery_items` AS i -LEFT JOIN `members` AS `m` ON +LEFT JOIN `member` AS `m` ON m.`id` = i.`user_id_foreign` WHERE i.`id` > '.(int)$imageId.' '; @@ -448,7 +448,7 @@ public function getPreviousItems($imageId,$limit = 1,$userId = false,$galleryId i.`title`, i.`created` FROM `gallery_items` AS i -LEFT JOIN `members` AS `m` ON +LEFT JOIN `member` AS `m` ON m.`id` = i.`user_id_foreign` WHERE i.`id` < '.(int)$imageId.' '; @@ -517,7 +517,7 @@ public function imageData($itemId) i.`description`, i.`created` FROM `gallery_items` AS i, -members as m +member as m WHERE i.`id` = ". (int)$itemId . " AND m.id = i.user_id_foreign AND m.Status IN ('Active', 'ChoiceInactive', 'Pending', 'OutOfRemind') @@ -596,15 +596,10 @@ public function uploadProcess(&$vars) // if upload failed, set error message if (!empty($fileName) && $error != UPLOAD_ERR_OK) { $noError = false; - switch ($error) { - case UPLOAD_ERR_INI_SIZE: - case UPLOAD_ERR_FORM_SIZE: - $vars['fileErrors'][$fileName] = 'Gallery_UploadFileTooLarge'; - break; - default: - $vars['fileErrors'][$fileName] = 'Gallery_UploadError'; - break; - } + $vars['fileErrors'][$fileName] = match ($error) { + UPLOAD_ERR_INI_SIZE, UPLOAD_ERR_FORM_SIZE => 'Gallery_UploadFileTooLarge', + default => 'Gallery_UploadError', + }; } elseif (!empty($fileName)) { // upload succeeded -> check if image $img = new MOD_images_Image($_FILES['gallery-file']['tmp_name'][$key]); if (!$img->isImage()) { @@ -615,8 +610,8 @@ public function uploadProcess(&$vars) $size = $img->getImageSize(); $original_x = min($size[0],PVars::getObj('images')->max_width); $original_y = min($size[1],PVars::getObj('images')->max_height); - $tempDir = dirname($_FILES['gallery-file']['tmp_name'][$key]); - $resizedName = md5($_FILES['gallery-file']['tmp_name'][$key]) . md5(date('now')) . '_resized'; + $tempDir = dirname((string) $_FILES['gallery-file']['tmp_name'][$key]); + $resizedName = md5((string) $_FILES['gallery-file']['tmp_name'][$key]) . md5(date('now')) . '_resized'; $img->createThumb($tempDir,$resizedName, $original_x, $original_y, true, 'ratio'); $tempFile = $tempDir . '/' . $resizedName ; diff --git a/build/gallery/gallery.view.php b/build/gallery/gallery.view.php index 695a1af0c0..79dc2b774b 100644 --- a/build/gallery/gallery.view.php +++ b/build/gallery/gallery.view.php @@ -9,12 +9,8 @@ * @version $Id$ */ class GalleryView extends PAppView { - private $_model; - - - public function __construct(GalleryModel $model) + public function __construct(private readonly GalleryModel $_model) { - $this->_model = $model; } public function loginWidget() { @@ -42,7 +38,7 @@ public function userOverviewSimple($statement, $userHandle, $galleries = false) $callbackId = $Gallery->updateGalleryProcess(); $vars =& PPostHandler::getVars($callbackId); if (!isset($vars['errors'])) - $vars['errors'] = array(); + $vars['errors'] = []; $type = 'images'; $galleries = $this->_model->getUserGalleries(); echo ' diff --git a/build/gallery/pages/galleries.page.php b/build/gallery/pages/galleries.page.php index 44b7936a80..c7f23cd965 100644 --- a/build/gallery/pages/galleries.page.php +++ b/build/gallery/pages/galleries.page.php @@ -11,11 +11,13 @@ class GalleryGalleriesPage extends GalleryBasePage { + #[\Override] protected function getSubmenuActiveItem() { return 'overview'; } + #[\Override] protected function teaserHeadline() { return ''; diff --git a/build/gallery/pages/gallery.page.php b/build/gallery/pages/gallery.page.php index 041cb62d17..eda7151a85 100644 --- a/build/gallery/pages/gallery.page.php +++ b/build/gallery/pages/gallery.page.php @@ -11,16 +11,19 @@ class GalleryPage extends GalleryBasePage { + #[\Override] protected function teaserHeadline() { $words = $this->words; return ''.$words->get('Gallery').''; } + #[\Override] protected function getTopmenuActiveItem() { return 'gallery'; } + #[\Override] protected function getSubmenuActiveItem() { return 'overview'; @@ -33,7 +36,7 @@ protected function column_col3() { $gallery = $this->gallery; $d = $this->d; $num_rows = $this->num_rows; - echo '

        '.htmlspecialchars($gallery->title).'

        '; + echo '

        '.htmlspecialchars((string) $gallery->title).'

        '; if ($this->myself && $this->upload) { // Display the upload form require SCRIPT_BASE . 'build/gallery/templates/uploadform.php'; diff --git a/build/gallery/pages/galleryavatars.page.php b/build/gallery/pages/galleryavatars.page.php index 3a32af30c6..b2af5aa00d 100644 --- a/build/gallery/pages/galleryavatars.page.php +++ b/build/gallery/pages/galleryavatars.page.php @@ -11,11 +11,13 @@ class GalleryAvatarsPage extends GalleryBasePage { + #[\Override] protected function getSubmenuActiveItem() { return 'overview'; } + #[\Override] protected function teaserHeadline() { return ''.parent::teaserHeadline() . ' » '. $this->getWords()->getBuffered('GalleryAvatars').''; } diff --git a/build/gallery/pages/gallerybase.page.php b/build/gallery/pages/gallerybase.page.php index b07c98b235..7abd558430 100644 --- a/build/gallery/pages/gallerybase.page.php +++ b/build/gallery/pages/gallerybase.page.php @@ -10,6 +10,7 @@ class GalleryBasePage extends PageWithActiveSkin { + #[\Override] protected function init() { $this->page_title = 'Gallery | BeWelcome'; @@ -17,6 +18,7 @@ protected function init() $this->addLateLoadScriptFile('build/lightbox.js'); } + #[\Override] protected function teaser() { ?>
        @@ -47,6 +49,7 @@ protected function getSubmenuActiveItem() return 'overview'; } + #[\Override] protected function getStylesheets() { $stylesheets = parent::getStylesheets(); $stylesheets[] = 'build/lightbox.css'; @@ -63,11 +66,13 @@ protected function getMessage() * */ + #[\Override] protected function getSubmenuItems() { - return array(); + return []; } + #[\Override] protected function submenu() { $active_menu_item = $this->getSubmenuActiveItem(); echo '
    -
    +
    {% if reported.haveToPaginate %} -
    +
    {{ pagerfanta( reported, 'rox_default') }}
    {% endif %} diff --git a/templates/admin/checker/communitynews.html.twig b/templates/admin/checker/communitynews.html.twig index 90c11a2be3..de08600386 100644 --- a/templates/admin/checker/communitynews.html.twig +++ b/templates/admin/checker/communitynews.html.twig @@ -7,9 +7,11 @@ {% block javascripts %} @@ -22,7 +24,7 @@ {{ form_start(form) }} {{ form_errors(form) }} {% if reported.haveToPaginate %} -
    +
    {{ pagerfanta( reported, 'rox_default') }}
    {% endif %} @@ -41,19 +43,19 @@ {% for comment in reported.currentPageResults %} {{ comment.title|purify }}
    {{ comment.text|truncate(50) }} - {{ macros.roundedavatarstack(comment.author.username) }} + {{ macros.roundedavatarstack(comment.author.username) }} {{ comment.created | format_datetime('short', 'short') }} {{ form_widget(form.spamComments[loop.index0], {'attr': {'class': 'checkableDelete'}}) }} {% endfor %}
    -
    +
    {% if reported.haveToPaginate %} -
    +
    {{ pagerfanta( reported, 'rox_default') }}
    {% endif %} diff --git a/templates/admin/checker/messages.html.twig b/templates/admin/checker/messages.html.twig index 8f30e79969..5b1a04a897 100644 --- a/templates/admin/checker/messages.html.twig +++ b/templates/admin/checker/messages.html.twig @@ -3,12 +3,27 @@ {% block javascripts %} @@ -21,9 +36,14 @@ {{ form_start(form) }} {{ form_errors(form) }} {% if reported.haveToPaginate %} -
    +
    {{ pagerfanta( reported, 'rox_default') }}
    +
    +
    + +
    +
    {% endif %} @@ -33,19 +53,19 @@ - - + + - - - + + + {% for message in reported.currentPageResults %} - @@ -58,12 +78,12 @@ {% endfor %}
    Receiver Created Comment{{ 'ok' | trans }}{{ 'spam' | trans }}okspam
     
    {{ macros.avatarstack(message.Sender.Username, 30) }}
    {{ ('memberstatus' ~ message.Sender.Status)|lower|trans }}
    {{ message.subject.subject }}
    +
    {{ message.subject.subject }} {% if message.request is null %}{% else %}{% endif %}
    {{ message.Message|purify }}
    {{ macros.avatarstack(message.Receiver.Username, 30) }}
    {{ ('memberstatus' ~ message.Receiver.Status)|lower|trans }}
    -
    +
    {% if reported.haveToPaginate %} -
    +
    {{ pagerfanta( reported, 'rox_default') }}
    {% endif %} diff --git a/templates/admin/comment/comment.html.twig b/templates/admin/comment/comment.html.twig index e47e84deb8..4b4d0d5f3b 100644 --- a/templates/admin/comment/comment.html.twig +++ b/templates/admin/comment/comment.html.twig @@ -3,9 +3,9 @@ {% block content %}

    {{ 'admin.comment.headline' | trans }}

    -
    +
    - {% if comment.displayinpublic %}{{ 'Comment is visible to everyone.' }}{% else %}{{ 'Comment is currently hidden.' }}{% endif %} + {% if comment.showToOtherMembers %}{{ 'Comment is visible to everyone.' }}{% else %}{{ 'Comment is currently hidden.' }}{% endif %}
    {% if comment.editingAllowed %}{{ 'Comment can be edited.' }}{% else %}{{ 'Comment is currently locked.' }}{% endif %} @@ -17,13 +17,13 @@ {% include 'member/comment.html.twig' with { 'comment': reply, 'mute': true } %} {% endif %}
    - {{ form_start(form, { 'attr': { 'class': 'form-inline'}}) }} + {{ form_start(form, { 'attr': { 'class': 'd-flex flex-wrap gap-2'}}) }} {% if form.showComment is defined %}{{ form_widget(form.showComment) }}{% else %}{{ form_widget(form.hideComment) }}{% endif %} {% if form.disableEditing is defined %}{{ form_widget(form.disableEditing) }}{% else %}{{ form_widget(form.allowEditing) }}{% endif %} {{ form_widget(form.markAsChecked) }} {#{{ form_widget(form.markAsChecked) }}#} {{ form_widget(form.markAsAbuse) }} {{ form_widget(form.moveToNegative) }} {{ form_widget(form.deleteComment) }} - {% trans with {'%username%': comment.toMember.username} %}admin.comments.to.all{% endtrans %} - {% trans with {'%username%': comment.fromMember.username} %}admin.comments.from.all{% endtrans %} + {% trans with {'%username%': comment.toMember.username} %}admin.comments.to.all{% endtrans %} + {% trans with {'%username%': comment.fromMember.username} %}admin.comments.from.all{% endtrans %} {{ form_end(form) }}
    diff --git a/templates/admin/comment/overview.html.twig b/templates/admin/comment/overview.html.twig index 1ffd25f8eb..5044cc7cc2 100644 --- a/templates/admin/comment/overview.html.twig +++ b/templates/admin/comment/overview.html.twig @@ -33,9 +33,9 @@ {{ macros.avatarstack(comment.fromMember.Username, 50) }} {{ 'comment.quality' | trans }}
    - {{ ('CommentQuality_' ~ comment.Quality) | lower | trans }} ({{ 'written' | trans }} {{ comment.created }}{% if comment.created != comment.updated %} — {{ 'updated' | trans }} {{ comment.updated }}{% endif %})
    + {{ ('comment.quality.' ~ comment.Quality) | lower | trans }} ({{ 'written' | trans }} {{ comment.created }}{% if not comment.updated is null and comment.created != comment.updated %} — {{ 'updated' | trans }} {{ comment.updated }}{% endif %})
    {{ 'comment.text' | trans }}
    - {{ comment.TextFree | nl2br }}
    + {{ comment.comment | nl2br }}
    {{ 'comment.know' | trans }}
    {% set relations = comment.relations | split(',') %} {% for relation in relations %}{{ ('profile.comment.relation.' ~ relation) | lower | trans({'username': comment.toMember.Username}) }} {% endfor %} @@ -44,7 +44,7 @@ {{ macros.avatarstack(comment.toMember.Username, 50) }}
    - {% if comment.displayinpublic %} + {% if comment.showToOtherMembers %} {% else %} diff --git a/templates/admin/communitynews/list.html.twig b/templates/admin/communitynews/list.html.twig index c8aa977c4d..6a32b1bf15 100644 --- a/templates/admin/communitynews/list.html.twig +++ b/templates/admin/communitynews/list.html.twig @@ -8,46 +8,46 @@ {% block content %}

    {{ 'bewelcome_news.header' | trans }}

    -
    + {% if communityNews.haveToPaginate %} -
    +
    {{ pagerfanta( communityNews, 'rounded_pagination', { routeName: 'admin_communitynews_overview' }) }}
    {% endif %} {% for news in communityNews %} -
    +
    -
    -
    +
    +
    {{ macros.roundedavatarstack( news.createdBy.Username, 72) }}
    -
    -

    {{ news.title }}

    - - +
    +

    {{ news.title }}

    + + {{ news.createdAt.DiffForHumans }} {% if news.updatedBy and news.updatedBy.Username != news.createdBy.Username %} -
    {{ 'bewelcome_news.lastupdater' | trans}} +
    {{ 'bewelcome_news.lastupdater' | trans}} {{ macros.profilelink( news.updatedBy.Username ) }} {{ news.updatedAt.DiffForHumans }} {% endif %}
    -
    +
    {{ news.text | truncate(50) | raw }}
    -

    {{ 'label.read.more' | trans }} ({% trans with {'%commentsCount%': news.comments|length} %}bewelcome_news.nrcomments{% endtrans %}) +

    {{ 'label.read.more' | trans }} ({% trans with {'%commentsCount%': news.comments|length} %}bewelcome_news.nrcomments{% endtrans %})

    -
    - +
    + {%- if news.public == true -%} @@ -62,7 +62,7 @@ {% endfor %} {% if communityNews.haveToPaginate %} -
    +
    {{ pagerfanta( communityNews, 'rounded_pagination', { routeName: 'admin_communitynews_overview' }) }}
    {% endif %} diff --git a/templates/admin/faqs/editcreate.category.html.twig b/templates/admin/faqs/editcreate.category.html.twig index 609751fd74..48f616fc33 100644 --- a/templates/admin/faqs/editcreate.category.html.twig +++ b/templates/admin/faqs/editcreate.category.html.twig @@ -15,10 +15,10 @@

    {{ 'admin.faq.create.category' | trans }}

    {% endif %} {{ form_start(form) }} -
    +
    {{ form_row(form.wordCode) }}
    -
    +
    {{ form_row(form.description) }}
    {{ form_end(form) }} diff --git a/templates/admin/faqs/editcreate.faq.html.twig b/templates/admin/faqs/editcreate.faq.html.twig index ed45169822..c4907b6f76 100644 --- a/templates/admin/faqs/editcreate.faq.html.twig +++ b/templates/admin/faqs/editcreate.faq.html.twig @@ -16,27 +16,27 @@ {% endif %} {{ form_start(form, {"attr": {"novalidate":"novalidate"}}) }} {{ form_errors(form) }} -
    +
    {{ form_label(form.faqCategory) }} {{ form_widget(form.faqCategory) }} The category the FAQ will be added to (read-only).
    -
    +
    {{ form_label(form.wordCode) }} {{ form_widget(form.wordCode) }} The word code to be used for the FAQ.
    -
    +
    {{ form_label(form.question) }} {{ form_widget(form.question) }} The question to be answered (English only).
    -
    +
    {{ form_label(form.answer) }} {{ form_widget(form.answer) }} The answer to the question (English only).
    -
    {% endfor %} diff --git a/templates/admin/faqs/sort.categories.html.twig b/templates/admin/faqs/sort.categories.html.twig index ae439934ab..0becd3c3f8 100644 --- a/templates/admin/faqs/sort.categories.html.twig +++ b/templates/admin/faqs/sort.categories.html.twig @@ -14,7 +14,7 @@

    {{ 'admin.faqs.sort_categories' | trans }}

    {% if faqCategories|length == 0 %}

    {{ 'faqs.none' | trans }}

    -

    {{ 'faqs.none.create' | trans }}

    +

    {{ 'faqs.none.create' | trans }}

    {% else %} {{ form_start(form) }} {{ form_row(form.sortOrder) }} @@ -22,7 +22,7 @@
    {{ 'faq' | trans }}

    {{ 'admin.faq.abstract' | trans }}

    -

    +

    diff --git a/templates/admin/flags/form.html.twig b/templates/admin/flags/form.html.twig new file mode 100644 index 0000000000..4ba13e5b18 --- /dev/null +++ b/templates/admin/flags/form.html.twig @@ -0,0 +1,29 @@ +{% extends 'base.html.twig' %} + +{% block javascripts %} + {% if autocomplete|default(false) %} + {{ encore_entry_script_tags('member/autocomplete') }} + {% endif %} +{% endblock javascripts %} + +{% block content %} +

    {{ headline|trans }}

    +
    +
    + {{ form_start(form) }} + {{ form_errors(form) }} + {% if form.username is defined %} + {{ form_row(form.username) }} + {{ form_row(form.flag) }} + {{ form_row(form.level) }} + {{ form_row(form.scope) }} + {{ form_row(form.comment) }} + {% else %} + {{ form_row(form.name) }} + {{ form_row(form.description) }} + {% endif %} + {{ form_row(form.submit) }} + {{ form_end(form) }} +
    +
    +{% endblock content %} diff --git a/templates/admin/flags/list.html.twig b/templates/admin/flags/list.html.twig new file mode 100644 index 0000000000..c8d5e31aa1 --- /dev/null +++ b/templates/admin/flags/list.html.twig @@ -0,0 +1,119 @@ +{% extends 'base.html.twig' %} +{% import 'macros.twig' as macros %} + +{% block javascripts %} + {{ encore_entry_script_tags('member/autocomplete') }} +{% endblock javascripts %} + +{% block content %} +

    + {{ (member_first ? 'admin.flags.list.members' : 'admin.flags.list.flags')|trans }} +

    + + +
    + + +
    +
    + + +
    +
    + + + +
    +
    + +
    + + + {% if assignments.nbResults > 0 %} +
    {{ pagerfanta(assignments, 'rox_default') }}
    + {% endif %} + +
    + + + + + + + + + + + + + + + {% for assignment in assignments %} + + + + + + + + + + + {% else %} + + + + {% endfor %} + +
    {{ 'admin.flags.member'|trans }}{{ 'admin.flags.flag'|trans }}{{ 'admin.flags.level'|trans }}{{ 'admin.flags.scope'|trans }}{{ 'admin.flags.comment'|trans }}{{ 'admin.assignments.created'|trans }}{{ 'admin.assignments.updated'|trans }}{{ 'admin.assignments.actions'|trans }}
    +
    + {{ macros.avatar(assignment.username, 50, true) }} +
    + + {{ assignment.username }} + +
    {{ assignment.status }}
    +
    + {{ assignment.last_active ? assignment.last_active|date('Y-m-d') : '—' }} +
    +
    + {{ assignment.place_name|default('—') }}{% if assignment.country_name %}, {{ assignment.country_name }}{% endif %} +
    +
    +
    +
    + + {{ assignment.definition_name }} + + {% if assignment.superseded %} + {{ 'admin.flags.superseded'|trans }} + {% endif %} + {{ assignment.level }}{{ assignment.scope }}{{ assignment.comment|nl2br }}{{ assignment.created_at|date('Y-m-d H:i') }}{{ assignment.updated_at ? assignment.updated_at|date('Y-m-d H:i') : '—' }} + {% if not assignment.superseded and assignment.level != 0 %} + + + + + + + {% endif %} +
    {{ 'admin.assignments.none'|trans }}
    +
    + + {% if assignments.nbResults > 0 %} +
    {{ pagerfanta(assignments, 'rox_default') }}
    + {% endif %} +{% endblock content %} diff --git a/templates/admin/flags/overview.html.twig b/templates/admin/flags/overview.html.twig new file mode 100644 index 0000000000..620cd30dca --- /dev/null +++ b/templates/admin/flags/overview.html.twig @@ -0,0 +1,29 @@ +{% extends 'base.html.twig' %} + +{% block content %} +

    {{ 'admin.flags.overview'|trans }}

    +
    + + + + + + + + + + {% for flag in flags %} + + + + + + {% else %} + + + + {% endfor %} + +
    {{ 'admin.flags.name'|trans }}{{ 'admin.flags.description'|trans }}{{ 'admin.flags.relevance'|trans }}
    {{ flag.name }}{{ flag.description }}{{ flag.relevance }}
    {{ 'admin.assignments.none'|trans }}
    +
    +{% endblock content %} diff --git a/templates/admin/flags/remove.html.twig b/templates/admin/flags/remove.html.twig new file mode 100644 index 0000000000..462ead9939 --- /dev/null +++ b/templates/admin/flags/remove.html.twig @@ -0,0 +1,18 @@ +{% extends 'base.html.twig' %} + +{% block content %} +

    {{ 'admin.flags.remove'|trans }}

    +

    {{ 'admin.flags.remove.confirm'|trans({ + '%flag%': assignment.flag.name, + '%username%': assignment.member.username + }) }}

    +
    +
    {{ 'admin.flags.level'|trans }}
    +
    {{ assignment.level }}
    +
    {{ 'admin.flags.scope'|trans }}
    +
    {{ assignment.scope }}
    +
    {{ 'admin.flags.comment'|trans }}
    +
    {{ assignment.comment|nl2br }}
    +
    + {{ form(form) }} +{% endblock content %} diff --git a/templates/admin/logs/index.html.twig b/templates/admin/logs/index.html.twig index b15b8e9c3f..49d77cb19b 100644 --- a/templates/admin/logs/index.html.twig +++ b/templates/admin/logs/index.html.twig @@ -19,7 +19,7 @@ {% block content %} {% if form is defined %} - {% form_theme form 'bootstrap_4_horizontal_layout.html.twig' %} + {% form_theme form 'bootstrap_5_horizontal_layout.html.twig' %} {{ form_start(form) }} {{ form_rest(form) }} @@ -30,7 +30,7 @@
    {{ 'admin.logs.no.logs' | trans }}
    {% else %} {% if logs.haveToPaginate %} -
    +
    {{ pagerfanta( logs, 'rox_default' ) }}
    {% endif %} @@ -52,7 +52,7 @@ {% endfor %} {% if logs.haveToPaginate %} -
    +
    {{ pagerfanta( logs, 'rox_default') }}
    {% endif %} diff --git a/templates/admin/massmail/test.sending.html.twig b/templates/admin/massmail/test.sending.html.twig index 2df0becb23..d5bcef2475 100644 --- a/templates/admin/massmail/test.sending.html.twig +++ b/templates/admin/massmail/test.sending.html.twig @@ -2,17 +2,17 @@ {% block content %}

    Massmail - Test mailing

    -
    -
    +
    +
    {{ form_start(form) }} {{ form_row(form.members) }} {{ form_end(form) }}
    -
    -

    Newsletter (translated into current locale)

    -
    +
    +

    Newsletter (translated into current locale)

    +
    {{ ('broadcast_body_' ~ newsletter.name)|lower|trans({'username': app.user.username}, null, app.request.locale)|prepare_newsletter(true) }}
    diff --git a/templates/admin/rights/form.html.twig b/templates/admin/rights/form.html.twig new file mode 100644 index 0000000000..7d263ef1b4 --- /dev/null +++ b/templates/admin/rights/form.html.twig @@ -0,0 +1,29 @@ +{% extends 'base.html.twig' %} + +{% block javascripts %} + {% if autocomplete|default(false) %} + {{ encore_entry_script_tags('member/autocomplete') }} + {% endif %} +{% endblock javascripts %} + +{% block content %} +

    {{ headline|trans }}

    +
    +
    + {{ form_start(form) }} + {{ form_errors(form) }} + {% if form.username is defined %} + {{ form_row(form.username) }} + {{ form_row(form.right) }} + {{ form_row(form.level) }} + {{ form_row(form.scope) }} + {{ form_row(form.comment) }} + {% else %} + {{ form_row(form.name) }} + {{ form_row(form.description) }} + {% endif %} + {{ form_row(form.submit) }} + {{ form_end(form) }} +
    +
    +{% endblock content %} diff --git a/templates/admin/rights/list.html.twig b/templates/admin/rights/list.html.twig new file mode 100644 index 0000000000..0d66169b0a --- /dev/null +++ b/templates/admin/rights/list.html.twig @@ -0,0 +1,120 @@ +{% extends 'base.html.twig' %} +{% import 'macros.twig' as macros %} + +{% block javascripts %} + {{ encore_entry_script_tags('member/autocomplete') }} +{% endblock javascripts %} + +{% block content %} +

    + {{ (member_first ? 'admin.rights.list.members' : 'admin.rights.list.rights')|trans }} +

    + +
    +
    + + +
    +
    + + +
    + {% if member_first %} + + {% else %} +
    + + + +
    + {% endif %} +
    + +
    +
    + + {% if assignments.nbResults > 0 %} +
    {{ pagerfanta(assignments, 'rox_default') }}
    + {% endif %} + +
    + + + + + + + + + + + + + + + {% for assignment in assignments %} + + + + + + + + + + + {% else %} + + + + {% endfor %} + +
    {{ 'admin.rights.member'|trans }}{{ 'admin.rights.right'|trans }}{{ 'admin.rights.level'|trans }}{{ 'admin.rights.scope'|trans }}{{ 'admin.rights.comment'|trans }}{{ 'admin.assignments.created'|trans }}{{ 'admin.assignments.updated'|trans }}{{ 'admin.assignments.actions'|trans }}
    +
    + {{ macros.avatar(assignment.username, 50, true) }} +
    + + {{ assignment.username }} + +
    {{ assignment.status }}
    +
    + {{ assignment.last_active ? assignment.last_active|date('Y-m-d') : '—' }} +
    +
    + {{ assignment.place_name|default('—') }}{% if assignment.country_name %}, {{ assignment.country_name }}{% endif %} +
    +
    +
    +
    + + {{ assignment.definition_name }} + + {{ assignment.level }}{{ assignment.scope }}{{ assignment.comment|nl2br }}{{ assignment.created_at|date('Y-m-d H:i') }}{{ assignment.updated_at ? assignment.updated_at|date('Y-m-d H:i') : '—' }} + + + + {% if assignment.level != 0 %} + + + + {% endif %} +
    {{ 'admin.assignments.none'|trans }}
    +
    + + {% if assignments.nbResults > 0 %} +
    {{ pagerfanta(assignments, 'rox_default') }}
    + {% endif %} +{% endblock content %} diff --git a/templates/admin/rights/overview.html.twig b/templates/admin/rights/overview.html.twig new file mode 100644 index 0000000000..9e1cf92ffe --- /dev/null +++ b/templates/admin/rights/overview.html.twig @@ -0,0 +1,29 @@ +{% extends 'base.html.twig' %} + +{% block content %} +

    {{ 'admin.rights.overview'|trans }}

    +
    + + + + + + + + + {% for right in rights %} + + + + + {% else %} + + + + {% endfor %} + +
    {{ 'admin.rights.name'|trans }}{{ 'admin.rights.description'|trans }}
    + {{ right.name }} + {{ right.description }}
    {{ 'admin.assignments.none'|trans }}
    +
    +{% endblock content %} diff --git a/templates/admin/rights/remove.html.twig b/templates/admin/rights/remove.html.twig new file mode 100644 index 0000000000..ffa2c63975 --- /dev/null +++ b/templates/admin/rights/remove.html.twig @@ -0,0 +1,18 @@ +{% extends 'base.html.twig' %} + +{% block content %} +

    {{ 'admin.rights.remove'|trans }}

    +

    {{ 'admin.rights.remove.confirm'|trans({ + '%right%': assignment.right.name, + '%username%': assignment.member.username + }) }}

    +
    +
    {{ 'admin.rights.level'|trans }}
    +
    {{ assignment.level }}
    +
    {{ 'admin.rights.scope'|trans }}
    +
    {{ assignment.scope }}
    +
    {{ 'admin.rights.comment'|trans }}
    +
    {{ assignment.comment|nl2br }}
    +
    + {{ form(form) }} +{% endblock content %} diff --git a/templates/admin/tools/check.feedback.html.twig b/templates/admin/tools/check.feedback.html.twig index ea1a7929bd..b44b416329 100644 --- a/templates/admin/tools/check.feedback.html.twig +++ b/templates/admin/tools/check.feedback.html.twig @@ -18,7 +18,7 @@

    {{ 'admin.tools.headline' | trans }}

    {{ 'admin.tools.check_feedback' | trans }}

    - {% form_theme form 'bootstrap_4_horizontal_layout.html.twig' %} + {% form_theme form 'bootstrap_5_horizontal_layout.html.twig' %} {{ form_start(form) }} {{ form_rest(form) }} @@ -27,7 +27,7 @@
    {{ 'admin.feedback.no.feedback' | trans }}
    {% else %} {% if feedbacks.haveToPaginate %} -
    +
    {{ pagerfanta( feedbacks, 'rox_default') }}
    {% endif %} @@ -50,7 +50,7 @@
    {% if feedbacks.haveToPaginate %} -
    +
    {{ pagerfanta( feedbacks, 'rox_default') }}
    {% endif %} diff --git a/templates/admin/tools/login.messages.show.html.twig b/templates/admin/tools/login.messages.show.html.twig index 47a8770e77..5043b0e418 100644 --- a/templates/admin/tools/login.messages.show.html.twig +++ b/templates/admin/tools/login.messages.show.html.twig @@ -17,8 +17,8 @@ {% for login_message in login_messages %} - {{ login_message.message|purify }} - {% if login_message.expires|date("U") > "now"|date("U") %}{% endif %} + {{ login_message.message|purify }} + {% if login_message.expires|date("U") > "now"|date("U") %}{% endif %} {% endfor %} diff --git a/templates/admin/tools/uploaded.images.html.twig b/templates/admin/tools/uploaded.images.html.twig index 9657386427..af63e564b9 100644 --- a/templates/admin/tools/uploaded.images.html.twig +++ b/templates/admin/tools/uploaded.images.html.twig @@ -10,7 +10,7 @@

    {{ 'admin.tools.uploaded_images' | trans }}

    {% if results.haveToPaginate %} -
    +
    {{ pagerfanta( results, 'rounded_pagination') }}
    @@ -27,7 +27,7 @@ {% endfor %}
    -
    +
    {{ pagerfanta( results, 'rounded_pagination') }}
    {% else %} diff --git a/templates/admin/translations/edit.html.twig b/templates/admin/translations/edit.html.twig index 49ffd9ef16..253d9334ec 100644 --- a/templates/admin/translations/edit.html.twig +++ b/templates/admin/translations/edit.html.twig @@ -18,7 +18,7 @@ {{ form_row(form.description) }} {{ form_row(form.englishText) }} -
    +
    {% if richtext %} {% endfor %} {% endfor %} -
    {% if not loop.last %}
    {% endif %}
    +
    {% if not loop.last %}
    {% endif %}
    {% else %} - + {{ icon }} {{ name|capitalize }} {% endif %} {% endfor %}
    - + {% endblock content %} diff --git a/templates/admin/translations/list.html.twig b/templates/admin/translations/list.html.twig index ab83d84c2e..0d3fb16567 100644 --- a/templates/admin/translations/list.html.twig +++ b/templates/admin/translations/list.html.twig @@ -62,7 +62,7 @@

    {{ translation.domain }}

    -

    {% if translation.shortcode == locale %} +

    {% if translation.shortCode == locale %} {% if translation.majorUpdate is defined %}{% endif %} {{ translation.sentence | striptags | truncate(50) }} {% else %} @@ -70,10 +70,10 @@ {% endif %}

    - +

    {{ translation.created|format_date('medium') }}

    - {% if translation.shortcode == locale %} + {% if translation.shortCode == locale %} {% else %} diff --git a/templates/admin/translations/mockup.email.html.twig b/templates/admin/translations/mockup.email.html.twig index f2f9bb6b1f..32ea76dcf8 100644 --- a/templates/admin/translations/mockup.email.html.twig +++ b/templates/admin/translations/mockup.email.html.twig @@ -9,5 +9,5 @@

    {{ 'translation.mockup.abstract'|trans }}

    {{ 'translations.mockup.template'|trans }}: {{ html_template }}
    {% if description != '' %}{{ description }}{% endif %}

    -
    {{ block("content", html_template)|raw }}
    +
    {{ block("content", html_template)|raw }}
    {% endblock content %} diff --git a/templates/admin/translations/mockup.page.html.twig b/templates/admin/translations/mockup.page.html.twig index bb2b0fe2c9..4578b18a71 100644 --- a/templates/admin/translations/mockup.page.html.twig +++ b/templates/admin/translations/mockup.page.html.twig @@ -14,7 +14,7 @@ {% if url != '' %}

    {{ 'translations.mockup.url'|trans }}: {{ url }}

    {% endif %}

    {{ 'translations.mockup.template'|trans }}: {{ template}}

    {% if description != '' %}

    {{ description }}

    {% endif %} -

    {{ name }}

    -
    {{ block("content", html_template)|raw }}
    - +

    {{ name }}

    +
    {{ block("content", html_template)|raw }}
    + {% endblock content %} diff --git a/templates/admin/translations/mockup.page_with_parameters.html.twig b/templates/admin/translations/mockup.page_with_parameters.html.twig index b7ebf6f3e4..d0a620d96d 100644 --- a/templates/admin/translations/mockup.page_with_parameters.html.twig +++ b/templates/admin/translations/mockup.page_with_parameters.html.twig @@ -10,11 +10,11 @@ {% block content %}

    {{ 'translations.headline' | trans }}

    -

    {{ 'translation.mockup.abstract'|trans }}

    -

    {{ name }}

    - {% if url != '' %}

    {{ 'translations.mockup.url'|trans }}: {{ url }}

    {% endif %} -

    {{ 'translations.mockup.template'|trans }}: {{ template}}

    - {% if description != '' %}

    {{ description }}

    {% endif %} -
    {{ block("content", html_template)|raw }}
    - +

    {{ 'translation.mockup.abstract'|trans }}

    +

    {{ name }}

    + {% if url != '' %}

    {{ 'translations.mockup.url'|trans }}: {{ url }}

    {% endif %} +

    {{ 'translations.mockup.template'|trans }}: {{ template}}

    + {% if description != '' %}

    {{ description }}

    {% endif %} +
    {{ block("content", html_template)|raw }}
    + {% endblock content %} diff --git a/templates/admin/translations/mockup.template.html.twig b/templates/admin/translations/mockup.template.html.twig index a7dcff4954..f136066335 100644 --- a/templates/admin/translations/mockup.template.html.twig +++ b/templates/admin/translations/mockup.template.html.twig @@ -14,7 +14,7 @@

    {{ 'translations.mockup.url'|trans }}: {{ url }}

    {{ 'translations.mockup.template'|trans }}: {{ template}}

    {% if description != '' %}

    {{ description }}

    {% endif %} -
    {{ block("content", html_template)|raw }}
    - +
    {{ block("content", html_template)|raw }}
    + {% endblock content %} diff --git a/templates/admin/translations/mockups.html.twig b/templates/admin/translations/mockups.html.twig index cd35997336..c210887f27 100644 --- a/templates/admin/translations/mockups.html.twig +++ b/templates/admin/translations/mockups.html.twig @@ -10,7 +10,7 @@ {% block content %}

    {{ 'translations.headline.mockups' | trans }}

    -
    +
    {% for feature in features %}  {{ feature|humanize }} {% endfor %} diff --git a/templates/admin/translations/no.right.html.twig b/templates/admin/translations/no.right.html.twig index b2b9ebc229..f8dbf46f02 100644 --- a/templates/admin/translations/no.right.html.twig +++ b/templates/admin/translations/no.right.html.twig @@ -10,7 +10,7 @@

    {{ 'admin.translations.select.locale' | trans }}

    {%- for locale in locales -%} - {{ ('lang_' ~ locale) | trans }} ({{ locale }})  + {{ ('lang_' ~ locale) | trans }} ({{ locale }})  {%- endfor -%}

    {% endblock content %} diff --git a/templates/admin/treasurer/edit_donation.html.twig b/templates/admin/treasurer/edit_donation.html.twig new file mode 100644 index 0000000000..aab0b29da0 --- /dev/null +++ b/templates/admin/treasurer/edit_donation.html.twig @@ -0,0 +1,11 @@ +{% extends 'base.html.twig' %} + +{% block content %} +

    {% if donation.id %}{{ 'admin.treasurer.donation.edit' | trans }}{% else %}{{ 'admin.treasurer.donation.create' | trans }}{% endif %}

    + + {{ form_start(form) }} + {{ form_widget(form) }} + + {{ 'button.cancel' | trans }} + {{ form_end(form) }} +{% endblock %} diff --git a/templates/admin/treasurer/index.html.twig b/templates/admin/treasurer/index.html.twig new file mode 100644 index 0000000000..98fccea8d3 --- /dev/null +++ b/templates/admin/treasurer/index.html.twig @@ -0,0 +1,88 @@ +{% extends 'base.html.twig' %} + +{% block content %} +

    {{ 'admin.treasurer.overview' | trans }}

    + +
    +
    +
    +
    + {{ 'admin.treasurer.campaign.status' | trans }} +
    +
    + {% if params.toggledonatebar %} +

    {{ 'admin.treasurer.campaign.active' | trans }}

    + {{ 'admin.treasurer.campaign.stop' | trans }} + {% else %} +

    {{ 'admin.treasurer.campaign.inactive' | trans }}

    + {{ 'admin.treasurer.campaign.start' | trans }} + {% endif %} +
    +
    +
    +
    +
    +
    + {{ 'admin.treasurer.stats' | trans }} +
    +
    +

    {{ 'admin.treasurer.stats.year_needed' | trans }}: {{ stats.YearNeededAmount }}

    +

    {{ 'admin.treasurer.stats.year_donation' | trans }}: {{ stats.YearDonation }}

    +

    {{ 'admin.treasurer.stats.quarter_needed' | trans }}: {{ stats.QuarterNeededAmount }}

    +

    {{ 'admin.treasurer.stats.quarter_donation' | trans }}: {{ stats.QuarterDonation }}

    +
    +
    +
    +
    + + + + {% if donations.nbResults == 0 %} +
    {{ 'admin.treasurer.no.donations' | trans }}
    + {% else %} + {% if donations.haveToPaginate %} +
    + {{ pagerfanta( donations, 'rox_default' ) }} +
    + {% endif %} + + + + + + + + + + + + + {% for donation in donations.currentPageResults %} + + + + + + + + + {% endfor %} + +
    {{ 'admin.treasurer.donation.date' | trans }}{{ 'admin.treasurer.donation.donor' | trans }}{{ 'admin.treasurer.donation.amount' | trans }}{{ 'admin.treasurer.donation.country' | trans }}{{ 'admin.treasurer.donation.comment' | trans }}{{ 'admin.treasurer.donation.actions' | trans }}
    {{ donation.created | date('Y-m-d') }} + {% if donation.donor %} + {{ donation.donor.username }} + {% else %} + {{ donation.nameGiven }} + {% endif %} + {{ donation.amount }} {{ donation.money }}{{ donation.country ? donation.country.name : '' }}{{ donation.systemComment }} + {{ 'button.edit' | trans }} +
    + {% if donations.haveToPaginate %} +
    + {{ pagerfanta( donations, 'rox_default') }} +
    + {% endif %} + {% endif %} +{% endblock %} diff --git a/templates/admin/treasurer/start_campaign.html.twig b/templates/admin/treasurer/start_campaign.html.twig new file mode 100644 index 0000000000..bb277138a9 --- /dev/null +++ b/templates/admin/treasurer/start_campaign.html.twig @@ -0,0 +1,11 @@ +{% extends 'base.html.twig' %} + +{% block content %} +

    {{ 'admin.treasurer.campaign.start' | trans }}

    + + {{ form_start(form) }} + {{ form_widget(form) }} + + {{ 'button.cancel' | trans }} + {{ form_end(form) }} +{% endblock %} diff --git a/templates/base-lite.html.twig b/templates/base-lite.html.twig index d3f05816b1..929e14357b 100644 --- a/templates/base-lite.html.twig +++ b/templates/base-lite.html.twig @@ -1,20 +1,20 @@ {% import 'macros.twig' as macros %} - + - - + + + + - {% apply spaceless %} - {% if block('title') is defined %} - {{ block('title') | trim }} | - {% endif %} BeWelcome - {% endapply %} + {%- if block('title') is defined -%} + {{ block('title') | trim }} | + {%- endif -%} BeWelcome @@ -26,12 +26,18 @@ {{ encore_entry_link_tags('bewelcome') }} {{ encore_entry_link_tags('tailwind') }} - + {% block stylesheets %}{% endblock %} +
    @@ -55,12 +61,6 @@
    {% include 'footer.html.twig' %} {{ encore_entry_script_tags('bewelcome') }} - {% block javascripts %}{% endblock javascripts %} diff --git a/templates/base.html.twig b/templates/base.html.twig index 755c62d58d..6bdb314959 100644 --- a/templates/base.html.twig +++ b/templates/base.html.twig @@ -1,105 +1,158 @@ {% import 'macros.twig' as macros %} - - - - - - - + + + + + + + + + - - {% apply spaceless %} - {% if block('title') is defined %} - {{ block('title') | trim }} | - {% endif %} BeWelcome - {% endapply %} - + {%- if block('title') is defined %}{{ block('title') | trim }} | {% endif -%} BeWelcome - - - - {% block redirect %}{% endblock %} + + + + {% block redirect %}{% endblock %} - {{ encore_entry_link_tags('bewelcome') }} - {{ encore_entry_link_tags('tailwind') }} + {{ encore_entry_link_tags('bewelcome') }} + {{ encore_entry_link_tags('tailwind') }} - {% block stylesheets %}{% endblock %} - - {% block matomo %}{% endblock %} - + {% block stylesheets %}{% endblock %} - - - - - {% set sidebar = (submenu is defined) %} - {% include 'menu.html.twig' %} - {% block main %} -
    -
    -
    - {% set contentBlock %} - {% for label, messages in app.flashes %} -
    - {% for message in messages %} -
    -
    - {{ message | raw }} -
    + {% block matomo %}{% endblock %} + + + + + + +{% set sidebar = (submenu is defined) %} +{% include 'menu.html.twig' %} +{% block main %} +
    +
    +
    + {% set contentBlock %} + {% set loggedInMember = app.user %} + {% if not loggedInMember is null %} + {% if not hide_finish_setup is defined %} + {% if loggedInMember.status == constant('App\\Doctrine\\MemberStatusType::MAIL_CONFIRMED') or + loggedInMember.status == constant('App\\Doctrine\\MemberStatusType::AWAITING_MAIL_CONFIRMATION') %} +
    +
    {% set deletionDate = app.user.created|date_modify("+7 days")|format_date('long') %} + {{ 'profile.finish.setup'|trans({deletion_date: deletionDate})|raw }}
    + - {% endfor %} -
    - {% endfor %} - {% block content %}{% endblock %} - {% endset %} -
    - {% if sidebar %} -
    -
    -

    - -

    - {{ contentBlock | raw }}
    -
    - {% endblock main %} - {% include 'footer.html.twig' %} - {{ encore_entry_script_tags('bewelcome') }} - {{ encore_entry_script_tags('updatecounters') }} + {% endif %} + {% for label, messages in app.flashes %} +
    + {% for message in messages %} +
    +
    + {{ message | raw }} +
    +
    + {% endfor %} +
    + {% endfor %} + {% block content %}{% endblock %} + {% endset %} +
    {% if sidebar %} - {{ encore_entry_script_tags('offcanvas') }} +
    +
    +

    + +

    + {{ contentBlock | raw }} +
    + +
    + {% else %} + {{ contentBlock | raw }} {% endif %} - {% block javascripts %}{% endblock javascripts %} - +
    +
    +{% endblock main %} +{% include 'footer.html.twig' %} +{{ encore_entry_script_tags('bewelcome') }} +{{ encore_entry_script_tags('updatecounters') }} +{% if sidebar %} + {{ encore_entry_script_tags('offcanvas') }} +{% endif %} +{% block javascripts %}{% endblock javascripts %} + diff --git a/templates/bundles/TwigBundle/Exception/error403.html.twig b/templates/bundles/TwigBundle/Exception/error403.html.twig index cf836ef384..b563655522 100644 --- a/templates/bundles/TwigBundle/Exception/error403.html.twig +++ b/templates/bundles/TwigBundle/Exception/error403.html.twig @@ -5,7 +5,7 @@

    {{ 'error.page.access.denied'|trans }}

    {% if app.user %} -

    {{ 'error.greeting'|trans(app.user.Username) }}

    +

    {{ 'error.greeting'|trans({username: app.user.Username}) }}

    {{ 'error.403'|trans }}

    {% else %}

    {{ 'error.403'|trans }}

    diff --git a/templates/bundles/TwigBundle/Exception/error404.html.twig b/templates/bundles/TwigBundle/Exception/error404.html.twig index 1058142871..c2decf6b26 100644 --- a/templates/bundles/TwigBundle/Exception/error404.html.twig +++ b/templates/bundles/TwigBundle/Exception/error404.html.twig @@ -5,7 +5,7 @@

    {{ 'error.page.not.found'|trans }}

    {% if app.user %} -

    {{ 'error.greeting'|trans(app.user.Username) }}

    +

    {{ 'error.greeting'|trans({username: app.user.Username}) }}

    {{ 'error.404'|trans({'url': app.request.pathInfo }) }}

    {% else %}

    {{ 'error.404'|trans({'url': app.request.pathInfo }) }}

    diff --git a/templates/bundles/TwigBundle/Exception/error500.html.twig b/templates/bundles/TwigBundle/Exception/error500.html.twig index f7b2c5d0a1..9424e1c1fd 100644 --- a/templates/bundles/TwigBundle/Exception/error500.html.twig +++ b/templates/bundles/TwigBundle/Exception/error500.html.twig @@ -5,7 +5,7 @@

    {{ 'error.page.server.error'|trans }}

    {% if app.user %} -

    {{ 'error.greeting'|trans(app.user.Username) }}

    +

    {{ 'error.greeting'|trans({username: app.user.Username}) }}

    {{ 'error.500'|trans }}

    {% else %}

    {{ 'error.500'|trans }}

    diff --git a/templates/ckeditor/ckeditor.html.twig b/templates/ckeditor/ckeditor.html.twig index 9b1aea4d42..d8e801d2d9 100644 --- a/templates/ckeditor/ckeditor.html.twig +++ b/templates/ckeditor/ckeditor.html.twig @@ -1,22 +1,45 @@ {% block ckeditor_widget %} - + {% set attr = attr|merge({}) %} + {% set include_reply_templates = include_reply_templates|default(false) %} + {% if editor_type == constant('App\\Form\\CkEditorType::EDITOR_TYPE_INLINE') or + editor_type == constant('App\\Form\\CkEditorType::EDITOR_TYPE_DECOUPLED') + %} +
    + {% if editor_type == constant('App\\Form\\CkEditorType::EDITOR_TYPE_DECOUPLED') %} +
    + {% endif %} +
    + {{ value|raw }} +
    + {% if editor_type == constant('App\\Form\\CkEditorType::EDITOR_TYPE_INLINE') %} +
    {{ 'profile.edit'|trans() }}
    + {% endif %} +
    +
    + {% else %} + {% set attr = attr|merge({'data-editor-type': editor_type}) %} + {% set attr = attr|merge({'data-image-upload': image_upload ? 'yes' : 'no'}) %} + {% set attr = attr|merge({'data-include-reply-templates': include_reply_templates ? 'yes' : 'no'}) %} + + {% endif %} + {% if include_reply_templates %} + {% include 'conversations/_reply_templates.html.twig' with {'editor_id': form.vars.id} only %} + {% endif %} {% if not async %} - {{ block( '_ckeditor_javascript' ) }} - {{ block( '_ckeditor_stylesheet' ) }} + {{ block( '_ckeditor_javascript' ) }} + {{ block( '_ckeditor_stylesheet' ) }} {% endif %} {% endblock %} {% block _ckeditor_javascript %} - - {{ encore_entry_script_tags('roxeditor') }} + {{ encore_entry_script_tags('roxeditor') }} {% endblock %} {% block _ckeditor_stylesheet %} - {{ encore_entry_link_tags('roxeditor') }} - + {{ encore_entry_link_tags('roxeditor') }} + {% endblock %} - diff --git a/templates/community/community.html.twig b/templates/community/community.html.twig index aadc41218c..a70b39090f 100644 --- a/templates/community/community.html.twig +++ b/templates/community/community.html.twig @@ -15,31 +15,31 @@
    diff --git a/templates/communitynews/list.html.twig b/templates/communitynews/list.html.twig index a7579462f7..3e05359bb0 100644 --- a/templates/communitynews/list.html.twig +++ b/templates/communitynews/list.html.twig @@ -1,5 +1,5 @@ -{% import 'macros.twig' as macros %} {% extends 'base.html.twig' %} +{% import 'macros.twig' as macros %} {% block stylesheets %} {{ encore_entry_link_tags('tailwind') }} @@ -12,38 +12,38 @@ {% block content %}

    {{ 'bewelcome_news.header' | trans }}

    {% if communityNews.haveToPaginate %} -
    +
    {{ pagerfanta( communityNews, 'rounded_pagination', { routeName: 'communitynews' }) }}
    {% endif %} {% for news in communityNews %} -
    -
    -
    +
    +
    +
    {{ macros.roundedavatarstack( news.createdBy.Username, 72) }}
    -
    -

    {{ news.title }}

    - - +
    +

    {{ news.title }}

    + + {{ news.createdAt.DiffForHumans }} {% if news.updatedBy and news.updatedBy.Username != news.createdBy.Username %} -
    {{ 'bewelcome_news.lastupdater' | trans}} +
    {{ 'bewelcome_news.lastupdater' | trans}} {{ macros.profilelink( news.updatedBy.Username ) }} {{ news.updatedAt.DiffForHumans }} {% endif %}
    -
    +
    {{ news.text | truncate(500) | raw }}
    -

    {{ 'label.read.more' | trans }} ({% trans with {'%commentsCount%': news.comments|length} %}bewelcome_news.nrcomments{% endtrans %}) +

    {{ 'label.read.more' | trans }} ({% trans with {'%commentsCount%': news.comments|length} %}bewelcome_news.nrcomments{% endtrans %})

    {% endfor %} {% if communityNews.haveToPaginate %} -
    +
    {{ pagerfanta( communityNews, 'rounded_pagination', { routeName: 'communitynews' }) }}
    {% endif %} diff --git a/templates/communitynews/show.html.twig b/templates/communitynews/show.html.twig index 91ffa58e5d..d61d8ca012 100644 --- a/templates/communitynews/show.html.twig +++ b/templates/communitynews/show.html.twig @@ -1,5 +1,5 @@ -{% import 'macros.twig' as macros %} {% extends 'base.html.twig' %} +{% import 'macros.twig' as macros %} {% block stylesheets %} {{ encore_entry_link_tags('tailwind') }} @@ -10,24 +10,24 @@ {% endblock %} {% block content %} -
    -
    -
    +
    +
    + -
    +
    {{ macros.roundedavatarstack( communityNews.createdBy.Username, 72) }}
    -
    -

    {{ communityNews.title }}

    - - +
    +

    {{ communityNews.title }}

    + + {{ communityNews.createdAt.DiffForHumans }} {% if communityNews.updatedBy and communityNews.updatedBy.Username != communityNews.createdBy.Username %}
    - + {{ 'bewelcome_news.lastupdater' | trans}} {{ macros.profilelink( communityNews.updatedBy.Username ) }} {{ communityNews.updatedAt.DiffForHumans }} @@ -36,10 +36,10 @@
    -
    +
    {{ communityNews.text| raw }}
    -
    +

    {% set commentsCount = communityNews.comments | length %}{% trans %}%commentsCount% comments{% endtrans %}

    @@ -48,52 +48,50 @@ {% if is_granted('IS_AUTHENTICATED_REMEMBERED') %}
    {{ form_start(form, {'attr': {'novalidate': 'novalidate'}}) }} -
    +
    {{ form_widget(form.title) }} -
    {{ form_errors(form.title) }}
    +
    {{ form_errors(form.title) }}
    -
    +
    {{ form_widget(form.text) }} -
    {{ form_errors(form.text) }}
    +
    {{ form_errors(form.text) }}
    {{ form_end(form) }}
    {% if comments.haveToPaginate %} -
    +
    {{ pagerfanta( comments, 'rounded_pagination') }}
    {% endif %} {% for comment in comments.currentPageResults %} -
    -
    -
    +
    +
    +
    {{ macros.roundedavatarstack( comment.author.Username, 50) }}
    -
    -

    {{ comment.title }}

    - +
    +

    {{ comment.title }}

    + {{ macros.profilelink( comment.author.Username ) }} - + {{ comment.created.DiffForHumans | trans }}
    -
    +
    {{ comment.text | raw }}
    {% endfor %} {% if comments.haveToPaginate %} -
    +
    {{ pagerfanta( comments, 'rounded_pagination') }}
    {% endif %} {% endif %} {% endblock content %} - - diff --git a/templates/conversations/_reply_templates.html.twig b/templates/conversations/_reply_templates.html.twig new file mode 100644 index 0000000000..d061250a1f --- /dev/null +++ b/templates/conversations/_reply_templates.html.twig @@ -0,0 +1,36 @@ +{% set conversation_templates = [ + { + label: 'conversation.reply.template.interested.label', + body: 'conversation.reply.template.interested.body' + }, + { + label: 'conversation.reply.template.need_details.label', + body: 'conversation.reply.template.need_details.body' + }, + { + label: 'conversation.reply.template.not_available.label', + body: 'conversation.reply.template.not_available.body' + } +] %} + +
    +
    + + +
    +
    diff --git a/templates/conversations/between.html.twig b/templates/conversations/between.html.twig index a7567efc70..c6d8eecfd5 100644 --- a/templates/conversations/between.html.twig +++ b/templates/conversations/between.html.twig @@ -5,15 +5,19 @@ {{ encore_entry_link_tags('tailwind') }} {% endblock %} +{% block title %} + {{ 'conversations' | trans }} +{% endblock title %} + {% block content %} - {% set member = app.user %} + {% set loggedInMember = app.user %} {{ macros.new_conversation_header(otherMember, 'messages.with.member.headline', false) }} {% if items.nbResults == 0 %}

    {{ 'messages.none' | trans }}

    {% else %} {% if items.haveToPaginate %} -
    +
    {{ pagerfanta( items, 'rounded_pagination') }}
    {% endif %} @@ -21,7 +25,7 @@ {% include 'conversations/message.html.twig' with { 'message': message, 'between': false, 'folder': 'none' } %} {% endfor %} {% if items.haveToPaginate %} -
    +
    {{ pagerfanta( items, 'rounded_pagination') }}
    {% endif %} diff --git a/templates/conversations/conversations.html.twig b/templates/conversations/conversations.html.twig index ac6fd895e8..09f7ed60d2 100644 --- a/templates/conversations/conversations.html.twig +++ b/templates/conversations/conversations.html.twig @@ -9,22 +9,26 @@ {{ encore_entry_script_tags('conversations') }} {% endblock %} +{% block title %} + {{ 'conversations' | trans }} +{% endblock title %} + {% block content %} -{% set member = app.user %} -
    +{% set loggedInMember = app.user %} +

    {{ submenu.active | trans }}

    -
    +
    {% if submenu.active != 'spam' and submenu.active != 'deleted' %} -
    -