diff --git a/tests/.env.test b/.ci/.env.ci similarity index 92% rename from tests/.env.test rename to .ci/.env.ci index c2f7250d..8d9ee1bf 100644 --- a/tests/.env.test +++ b/.ci/.env.ci @@ -10,7 +10,7 @@ DB_ADAPTER=mysql DB_HOST=127.0.0.1 DB_PORT=3306 DB_USERNAME=root -DB_PASSWORD= +DB_PASSWORD=secret DB_NAME=vokuro MAIL_FROM_NAME=Vokuro @@ -22,4 +22,4 @@ MAIL_SMTP_USERNAME= MAIL_SMTP_PASSWORD= CODECEPTION_URL=127.0.0.1 -CODECEPTION_PORT=8888 +CODECEPTION_PORT=80 diff --git a/.env.example b/.ci/.env.example similarity index 88% rename from .env.example rename to .ci/.env.example index c2f7250d..becff2ac 100644 --- a/.env.example +++ b/.ci/.env.example @@ -7,11 +7,11 @@ APP_PUBLIC_URL=dev.vokuro.phalcon.io # - sqlite # - pgsql DB_ADAPTER=mysql -DB_HOST=127.0.0.1 +DB_HOST=vokuro-mysql DB_PORT=3306 DB_USERNAME=root -DB_PASSWORD= -DB_NAME=vokuro +DB_PASSWORD=secret +DB_NAME=phalcon_vokuro MAIL_FROM_NAME=Vokuro MAIL_FROM_EMAIL=mail@dev.vokuro.phalcon.io diff --git a/.ci/create-db.sh b/.ci/create-db.sh index 907ff226..08b2199f 100755 --- a/.ci/create-db.sh +++ b/.ci/create-db.sh @@ -9,7 +9,7 @@ set -e -: "${DB_NAME:=vokuro}" +: "${DB_NAME:=phalcon_vokuro}" case "$DB_ADAPTER" in "mysql") diff --git a/.ci/install-phalcon.sh b/.ci/install-phalcon.sh deleted file mode 100755 index 1d87f3f1..00000000 --- a/.ci/install-phalcon.sh +++ /dev/null @@ -1,34 +0,0 @@ -#!/usr/bin/env bash -# -# This file is part of the Phalcon Framework. -# -# (c) Phalcon Team -# -# For the full copyright and license information, please view the -# LICENSE.txt file that was distributed with this source code. - -set -e - -: "${PHALCON_VERSION:=master}" - -EXT_DIR="$(php-config --extension-dir)" -LOCAL_PATH="phalcon-$PHALCON_VERSION/php-$(php-config --vernum)/$TRAVIS_ARCH" - -# Using cache only for tagged Phalcon versions -if [ "$PHALCON_VERSION" != "master" ] && - [ "$PHALCON_VERSION" != "4.0.x" ] && - [ -f "$HOME/assets/$LOCAL_PATH/phalcon.so" ] -then - cp "$HOME/assets/$LOCAL_PATH/phalcon.so" "$EXT_DIR/phalcon.so" -else - git clone --depth=1 -v https://github.com/phalcon/cphalcon.git -b "$PHALCON_VERSION" /tmp/phalcon - cd /tmp/phalcon/build || exit 1 - ./install --phpize "$(phpenv which phpize)" --php-config "$(phpenv which php-config)" 1> /dev/null - - mkdir -p "$HOME/assets/$LOCAL_PATH" - cp "$EXT_DIR/phalcon.so" "$HOME/assets/$LOCAL_PATH/phalcon.so" -fi - -echo extension=phalcon.so >> "$(phpenv prefix)/etc/php.ini" - -"$(phpenv which php)" -m | grep -q phalcon diff --git a/.github/workflows/docker-build.yml b/.github/workflows/docker-build.yml deleted file mode 100644 index 4d5d2479..00000000 --- a/.github/workflows/docker-build.yml +++ /dev/null @@ -1,12 +0,0 @@ -name: CI - -on: [push, pull_request] - -jobs: - build: - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v1 - - name: Build Vokuro image - run: docker build -t phalconphp/vokuro:4.1.2 -f docker/Dockerfile . diff --git a/.github/workflows/docker-build.yml.bak b/.github/workflows/docker-build.yml.bak new file mode 100644 index 00000000..34fbedf8 --- /dev/null +++ b/.github/workflows/docker-build.yml.bak @@ -0,0 +1,14 @@ +name: CI + +on: [push, pull_request] + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v1 + - name: Build Vokuro image 8.0 + run: docker build -t phalconphp/vokuro:5.0.0-8.0 -f docker/8.0/Dockerfile . + + - name: Build Vokuro image 8.1 + run: docker build -t phalconphp/vokuro:5.0.0-8.1 -f docker/8.1/Dockerfile . diff --git a/.github/workflows/validations.yml b/.github/workflows/validations.yml index 69ad839f..bb7b3271 100644 --- a/.github/workflows/validations.yml +++ b/.github/workflows/validations.yml @@ -1,88 +1,99 @@ -name: "Validations" -on: [push, pull_request] -jobs: - validate-code-style: - name: PSR-12 Code style - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v1 - - - name: Validate composer.json and composer.lock - run: composer validate +name: Testing Suite - - name: Get Composer Cache Directory - id: composer-cache - run: echo "::set-output name=dir::$(composer config cache-files-dir)" +on: [push, pull_request] - - name: Cache composer dependencies - uses: actions/cache@v1 - with: - path: ${{ steps.composer-cache.outputs.dir }} - key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }} - restore-keys: ${{ runner.os }}-composer- +env: + DB_HOST: '127.0.0.1' - - name: Install PHP_CodeSniffer composer package - run: composer global require "squizlabs/php_codesniffer=*" +jobs: + run: + runs-on: ubuntu-latest + name: Workflow - PHP-${{ matrix.php }} - - name: Validate PSR-12 Code Style - run: ~/.composer/vendor/bin/phpcs + services: + mysql: + image: mysql:5.7 + ports: + - "3306:3306" + env: + MYSQL_ROOT_PASSWORD: secret + MYSQL_USER: phalcon + MYSQL_DATABASE: vokuro + MYSQL_PASSWORD: secret - validate-code-static: - name: Static Code with PHP ${{ matrix.php-versions }} - runs-on: ubuntu-latest - env: - extensions: mbstring, intl, json, psr, phalcon-4.0.5 - key: cache-v2.0~14.05.2020 - needs: validate-code-style strategy: fail-fast: false matrix: - php-versions: ['7.2', '7.3', '7.4'] + php: ['8.0', '8.1'] steps: - - name: Checkout the code - uses: actions/checkout@v1 - - - name: Setup cache environment - id: cache-env - uses: shivammathur/cache-extensions@v1 - with: - php-version: ${{ matrix.php-versions }} - extensions: ${{ env.extensions }} - key: ${{ env.key }} - - - name: Cache extensions - uses: actions/cache@v1 - with: - path: ${{ steps.cache-env.outputs.dir }} - key: ${{ steps.cache-env.outputs.key }} - restore-keys: ${{ steps.cache-env.outputs.key }} - + - uses: actions/checkout@v1 - name: Setup PHP uses: shivammathur/setup-php@v2 with: - php-version: ${{ matrix.php-versions }} - extensions: ${{ env.extensions }} + php-version: ${{ matrix.php }} tools: pecl + extensions: mbstring, intl, json, phalcon-5.0.1 + coverage: xdebug + + - name: Init Database + run: | + mysql -uroot -h127.0.0.1 -psecret -e 'CREATE DATABASE IF NOT EXISTS `vokuro`;' + + - name: Validate composer.json and composer.lock + run: composer validate - - name: Get Composer Cache Directory + - name: Get composer cache directory id: composer-cache run: echo "::set-output name=dir::$(composer config cache-files-dir)" - - name: Cache composer dependencies - uses: actions/cache@v1 + - name: Cache dependencies + uses: actions/cache@v2 with: path: ${{ steps.composer-cache.outputs.dir }} - key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }} - restore-keys: ${{ runner.os }}-composer- + key: ${{ matrix.php }}-composer-${{ hashFiles('**/composer.lock') }} + restore-keys: ${{ matrix.php }}-composer- - - name: Install Composer dependencies with PHPStan - run: composer require --prefer-dist --no-progress --no-suggest --dev phpstan/phpstan + - name: Install Composer dependencies + run: composer install --prefer-dist --no-progress --no-suggest + + - name: Run PHPCS + if: always() + run: vendor/bin/phpcs - name: Run Psalm if: always() run: vendor/bin/psalm --show-info=false - - name: Run PHPStan + - name: Env file if: always() - run: vendor/bin/phpstan analyse -l 5 src + run: cp -v ./.ci/.env.ci ./.env + +# - name: Run migrations +# if: always() +# run: | +# vendor/bin/phinx migrate +# +# - name: Run seeds +# if: always() +# run: | +# vendor/bin/phinx seed:run + + - name: Run tests + if: always() + run: | + sudo php -S 0.0.0.0 -t ./.htrouter.php & + vendor/bin/codecept build + vendor/bin/codecept run unit --coverage-xml=unit-coverage.xml +# vendor/bin/codecept run functional --coverage-xml=functional-coverage.xml +# vendor/bin/codecept run acceptance --coverage-xml=acceptance-coverage.xml + +# - name: Upload to codecov +# uses: codecov/codecov-action@v3 +# with: +# token: ${{ secrets.CODECOV_TOKEN }} # not required for public repos +# directory: ./tests/_output/ +# files: unit-coverage.xml,functional-coverage.xml,acceptance-coverage.xml +# name: codecov-umbrella # optional +# fail_ci_if_error: false +# verbose: true # optional (default = false) diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index e0bb8bf5..00000000 --- a/.travis.yml +++ /dev/null @@ -1,66 +0,0 @@ -language: php - -php: - - '7.3' - - '7.2' - -dist: bionic - -services: - - mysql - - postgresql - -addons: - postgresql: "11.2" - hosts: - - dev.vokuro.phalcon.io - -env: - global: - - PHALCON_VERSION=v4.0.0 - matrix: - - DB=mysql DB_ADAPTER=mysql DB_PORT=3306 DB_USERNAME=root - - DB=postgres DB_ADAPTER=pgsql DB_PORT=5432 DB_USERNAME=postgres - - DB=sqlite DB_ADAPTER=sqlite - -matrix: - fast_finish: true - -cache: - timeout: 604800 - directories: - - "$HOME/.composer/cache" - - "$HOME/assets" - -before_install: - - git config --global advice.detachedHead false - - if [ "$DB" = "postgres" ]; then .ci/install-postgres.sh; fi - - if [ -n "$GITHUB_TOKEN" ]; then composer config github-oauth.github.com "$GITHUB_TOKEN"; fi - -install: - - pecl install --force psr - - .ci/create-db.sh - - .ci/install-phalcon.sh - -before_script: - - travis_retry composer install --no-interaction --no-ansi --no-progress --no-suggest - - cp tests/.env.test .env - - vendor/bin/phinx migrate -e development - - vendor/bin/phinx seed:run -e development - - php -S 127.0.0.1:8888 -t public/ .htrouter.php & - -script: - - vendor/bin/codecept build --quiet - - vendor/bin/codecept run - - vendor/bin/psalm --show-info=false - - | - if [ "$TRAVIS_PHP_VERSION" = "7.2" ]; then - phpenv config-rm xdebug.ini || true - vendor/bin/phpcs - fi - -#after_success: -# - bash <(curl -s https://codecov.io/bash) - -notifications: - email: false diff --git a/README.md b/README.md index e6b58465..7cd007eb 100644 --- a/README.md +++ b/README.md @@ -19,8 +19,8 @@ Thanks. To run this application on your machine, you need at least: -* PHP >= 7.2 -* Phalcon >= 4.0 +* PHP >= 7.4 +* Phalcon >= 5.0 * MySQL >= 5.5 * Apache Web Server with `mod_rewrite enabled`, and `AllowOverride Options` (or `All`) in your `httpd.conf` or Nginx Web Server * Latest [Phalcon Framework](https://github.com/phalcon/cphalcon) extension installed/enabled @@ -28,7 +28,7 @@ To run this application on your machine, you need at least: ### Install Vökuró via composer create-project ```bash -composer create-project phalcon/vokuro /path/to/vokuro-folder "4.1.2" --prefer-dist +composer create-project phalcon/vokuro /path/to/vokuro-folder "5.0.0" --prefer-dist ``` ### Installing Dependencies via Composer @@ -44,7 +44,7 @@ Run the composer installer: ```bash cd vokuro composer install -cp .env.example .env +cp ./.ci/.env.example .env vendor/bin/phinx migrate vendor/bin/phinx seed:run ``` @@ -64,11 +64,11 @@ If you wish to check older versions or newer ones currently under development, p Phalcon is an open source project and a volunteer effort. Vökuró does not have human resources fully dedicated to the maintenance of this software. -If you want something to be improved or you want a new feature please submit a Pull Request. +If you want something to be improved, or you want a new feature please submit a Pull Request. ## Sponsors -Become a sponsor and get your logo on our README on Github with a link to your site. [[Become a sponsor](https://opencollective.com/phalcon#sponsor)] +Become a sponsor and get your logo on our README on GitHub with a link to your site. [[Become a sponsor](https://opencollective.com/phalcon#sponsor)] sponsors diff --git a/codeception.yml b/codeception.yml index e6cc38eb..66f5e65e 100644 --- a/codeception.yml +++ b/codeception.yml @@ -29,7 +29,7 @@ extensions: # Get params from .env file params: - - tests/.env.test + - .env error_level: "E_ALL" diff --git a/composer.json b/composer.json index 92e63bf4..02094539 100644 --- a/composer.json +++ b/composer.json @@ -25,21 +25,21 @@ } ], "require": { - "php": ">=7.2", + "php": ">=7.4", "ext-openssl": "*", - "ext-phalcon": "~4.0.0", - "robmorgan/phinx": "^0.11.1", - "swiftmailer/swiftmailer": "^6.2", - "vlucas/phpdotenv": "^3.6" + "ext-phalcon": "~5.0.0", + "robmorgan/phinx": "^0.12.12", + "symfony/mailer": "^6.0", + "vlucas/phpdotenv": "^5.4" }, "require-dev": { - "codeception/codeception": "^4.1.6", - "phalcon/ide-stubs": "4.0.6", - "phpunit/phpunit": "^8.4", - "squizlabs/php_codesniffer": "3.5.5", - "vimeo/psalm": "^3.7", - "codeception/module-phpbrowser": "^1.0", - "codeception/module-asserts": "^1.2" + "codeception/codeception": "^5.0", + "codeception/module-asserts": "^3.0", + "codeception/module-phpbrowser": "^3.0", + "phalcon/ide-stubs": "^v5.0.1", + "squizlabs/php_codesniffer": "^3.7", + "vimeo/psalm": "^4.27", + "phpstan/phpstan": "^1.8" }, "suggest": { "ext-apc": "Needed to support caching ACL" @@ -56,7 +56,6 @@ "exclude": [ "/.ci", ".dockerignore", - ".travis.yml", "CODE_OF_CONDUCT.md", "CONTRIBUTING.md" ] diff --git a/config/acl.php b/config/acl.php index 3751a2a1..67c5f8eb 100644 --- a/config/acl.php +++ b/config/acl.php @@ -1,5 +1,4 @@ [ 'users' => [ diff --git a/config/config.php b/config/config.php index b834ef7d..3f3ba257 100644 --- a/config/config.php +++ b/config/config.php @@ -1,5 +1,4 @@ [ - 'adapter' => getenv('DB_ADAPTER'), - 'host' => getenv('DB_HOST'), - 'port' => getenv('DB_PORT'), - 'username' => getenv('DB_USERNAME'), - 'password' => getenv('DB_PASSWORD'), - 'dbname' => getenv('DB_NAME'), + 'adapter' => $_ENV['DB_ADAPTER'] ?? 'mysql', + 'host' => $_ENV['DB_HOST'] ?? '127.0.0.1', + 'port' => $_ENV['DB_PORT'] ?? 3306, + 'username' => $_ENV['DB_USERNAME'] ?? 'root', + 'password' => $_ENV['DB_PASSWORD'] ?? 'secret', + 'dbname' => $_ENV['DB_NAME'] ?? 'phalcon_vokuro', ], 'application' => [ - 'baseUri' => getenv('APP_BASE_URI'), - 'publicUrl' => getenv('APP_PUBLIC_URL'), - 'cryptSalt' => getenv('APP_CRYPT_SALT'), + 'baseUri' => $_ENV['APP_BASE_URI'] ?? '/', + 'publicUrl' => $_ENV['APP_PUBLIC_URL'] ?? 'https://vokuro.phalcon.ld', + 'cryptSalt' => $_ENV['APP_CRYPT_SALT'] ?? '', 'viewsDir' => root_path('themes/vokuro/'), 'cacheDir' => root_path('var/cache/'), 'sessionSavePath' => root_path('var/cache/session/'), ], 'mail' => [ - 'fromName' => getenv('MAIL_FROM_NAME'), - 'fromEmail' => getenv('MAIL_FROM_EMAIL'), + 'fromName' => $_ENV['MAIL_FROM_NAME'] ?? 'Vokuro Mailer', + 'fromEmail' => $_ENV['MAIL_FROM_EMAIL'] ?? 'vokuro@localhost', 'smtp' => [ - 'server' => getenv('MAIL_SMTP_SERVER'), - 'port' => getenv('MAIL_SMTP_PORT'), - 'security' => getenv('MAIL_SMTP_SECURITY'), - 'username' => getenv('MAIL_SMTP_USERNAME'), - 'password' => getenv('MAIL_SMTP_PASSWORD'), + 'server' => $_ENV['MAIL_SMTP_SERVER'] ?? 'localhost', + 'port' => $_ENV['MAIL_SMTP_PORT'] ?? 25, + 'security' => $_ENV['MAIL_SMTP_SECURITY'] ?? '', + 'username' => $_ENV['MAIL_SMTP_USERNAME'] ?? '', + 'password' => $_ENV['MAIL_SMTP_PASSWORD'] ?? '', ], ], 'logger' => [ 'path' => root_path('var/logs/'), 'format' => '%date% [%type%] %message%', 'date' => 'D j H:i:s', - 'logLevel' => Logger::DEBUG, + 'logLevel' => Enum::DEBUG, 'filename' => 'application.log', ], - // Set to false to disable sending emails (for use in test environment) + // Set to false, to disable sending emails (for use in test environment) 'useMail' => true, ]; diff --git a/config/providers.php b/config/providers.php index 38ed0cd4..6cc4c88d 100644 --- a/config/providers.php +++ b/config/providers.php @@ -1,5 +1,4 @@ " \ + description="The PHP image to test the Vökuró example concepts" + +ENV PHALCON_VERSION="5.0.1" \ + PHP_VERSION="8.0" + +# Update +RUN apt update -y && \ + apt install -y \ + apt-utils \ + gettext \ + git \ + libzip-dev \ + nano \ + sudo \ + wget \ + zip + +# PECL Packages +RUN pecl install -o -f redis && \ + pecl install phalcon-${PHALCON_VERSION} \ + xdebug + +# Install PHP extensions +RUN docker-php-ext-install \ + gettext \ + pdo_mysql \ + zip + +# Install PHP extensions +RUN docker-php-ext-enable \ + opcache \ + phalcon \ + redis \ + xdebug + +# Clear cache +RUN apt-get clean && rm -rf /var/lib/apt/lists/* + +# Add user +RUN groupadd -g 1000 phalcon +RUN useradd -u 1000 -ms /bin/bash -g phalcon phalcon + +# Composer +COPY --from=composer /usr/bin/composer /usr/local/bin/composer + +# Copy existing application directory contents +COPY . /code + +# Bash script with helper aliases +COPY ./config/.bashrc /root/.bashrc +COPY ./config/.bashrc /home/phalcon/.bashrc + +# Copy existing application directory permissions +COPY --chown=phalcon:phalcon . /code + +# Change current user to phalcon +USER phalcon + +EXPOSE 80 + +CMD ["php", "-S", "0.0.0.0:80", "-t", "public/", ".htrouter.php"] diff --git a/docker/8.0/config/.bashrc b/docker/8.0/config/.bashrc new file mode 100644 index 00000000..e106a759 --- /dev/null +++ b/docker/8.0/config/.bashrc @@ -0,0 +1,75 @@ +#!/bin/bash + +# Easier navigation: .., ..., ...., ....., ~ and - +alias ..="cd .." +alias ...="cd ../.." +alias ....="cd ../../.." +alias .....="cd ../../../.." +alias ~="cd ~" # `cd` is probably faster to type though +alias -- -="cd -" + +# Shortcuts +alias g="git" +alias h="history" + +# Detect which `ls` flavor is in use +if ls --color > /dev/null 2>&1; then # GNU `ls` + colorflag="--color" +else # OS X `ls` + colorflag="-G" +fi + +# List all files colorized in long format +# shellcheck disable=SC2139 +alias l="ls -lF ${colorflag}" + +# List all files colorized in long format, including dot files +# shellcheck disable=SC2139 +alias la="ls -laF ${colorflag}" + +# List only directories +# shellcheck disable=SC2139 +alias lsd="ls -lF ${colorflag} | grep --color=never '^d'" + +# See: https://superuser.com/a/656746/280737 +alias ll='LC_ALL="C.UTF-8" ls -alF' + +# Always use color output for `ls` +# shellcheck disable=SC2139 +alias ls="command ls ${colorflag}" +export LS_COLORS='no=00:fi=00:di=01;34:ln=01;36:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arj=01;31:*.taz=01;31:*.lzh=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.gz=01;31:*.bz2=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.jpg=01;35:*.jpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.avi=01;35:*.fli=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.ogg=01;35:*.mp3=01;35:*.wav=01;35:' + +# Always enable colored `grep` output +alias grep='grep --color=auto ' + +# Enable aliases to be sudo’ed +alias sudo='sudo ' + +# Get week number +alias week='date +%V' + +# Stopwatch +alias timer='echo "Timer started. Stop with Ctrl-D." && date && time cat && date' + +# Canonical hex dump; some systems have this symlinked +command -v hd > /dev/null || alias hd="hexdump -C" + +# vhosts +alias hosts='sudo nano /etc/hosts' + +# copy working directory +alias cwd='pwd | tr -d "\r\n" | xclip -selection clipboard' + +# copy file interactive +alias cp='cp -i' + +# move file interactive +alias mv='mv -i' + +# untar +alias untar='tar xvf' + +# Zephir related +alias untar='tar xvf' + +PATH=$PATH:./vendor/bin diff --git a/docker/8.0/config/extra.ini b/docker/8.0/config/extra.ini new file mode 100644 index 00000000..ec632f51 --- /dev/null +++ b/docker/8.0/config/extra.ini @@ -0,0 +1,8 @@ +error_reporting = E_ALL +display_errors = "On" +display_startup_errors = "On" +log_errors = "On" +error_log = /srv/storage/logs/php_errors.log +memory_limit = 512M +apc.enable_cli = "On" +session.save_path = "/tmp" diff --git a/docker/8.1/Dockerfile b/docker/8.1/Dockerfile new file mode 100644 index 00000000..5d6c557b --- /dev/null +++ b/docker/8.1/Dockerfile @@ -0,0 +1,69 @@ +FROM composer:latest as composer +FROM php:8.1-fpm + +# Set working directory +WORKDIR /code + +LABEL vendor="Phalcon" \ + maintainer="Phalcon Team " \ + description="The PHP image to test the Vökuró example concepts" + +ENV PHALCON_VERSION="5.0.1" \ + PHP_VERSION="8.1" + +# Update +RUN apt update -y && \ + apt install -y \ + apt-utils \ + gettext \ + git \ + libzip-dev \ + nano \ + sudo \ + wget \ + zip + +# PECL Packages +RUN pecl install -o -f redis && \ + pecl install phalcon-${PHALCON_VERSION} \ + xdebug + +# Install PHP extensions +RUN docker-php-ext-install \ + gettext \ + pdo_mysql \ + zip + +# Install PHP extensions +RUN docker-php-ext-enable \ + opcache \ + phalcon \ + redis \ + xdebug + +# Clear cache +RUN apt-get clean && rm -rf /var/lib/apt/lists/* + +# Add user +RUN groupadd -g 1000 phalcon +RUN useradd -u 1000 -ms /bin/bash -g phalcon phalcon + +# Composer +COPY --from=composer /usr/bin/composer /usr/local/bin/composer + +# Copy existing application directory contents +COPY . /code + +# Bash script with helper aliases +COPY config/.bashrc /root/.bashrc +COPY config/.bashrc /home/phalcon/.bashrc + +# Copy existing application directory permissions +COPY --chown=phalcon:phalcon . /code + +# Change current user to phalcon +USER phalcon + +EXPOSE 80 + +CMD ["php", "-S", "0.0.0.0:80", "-t", "public/", ".htrouter.php"] diff --git a/docker/8.1/config/.bashrc b/docker/8.1/config/.bashrc new file mode 100644 index 00000000..e106a759 --- /dev/null +++ b/docker/8.1/config/.bashrc @@ -0,0 +1,75 @@ +#!/bin/bash + +# Easier navigation: .., ..., ...., ....., ~ and - +alias ..="cd .." +alias ...="cd ../.." +alias ....="cd ../../.." +alias .....="cd ../../../.." +alias ~="cd ~" # `cd` is probably faster to type though +alias -- -="cd -" + +# Shortcuts +alias g="git" +alias h="history" + +# Detect which `ls` flavor is in use +if ls --color > /dev/null 2>&1; then # GNU `ls` + colorflag="--color" +else # OS X `ls` + colorflag="-G" +fi + +# List all files colorized in long format +# shellcheck disable=SC2139 +alias l="ls -lF ${colorflag}" + +# List all files colorized in long format, including dot files +# shellcheck disable=SC2139 +alias la="ls -laF ${colorflag}" + +# List only directories +# shellcheck disable=SC2139 +alias lsd="ls -lF ${colorflag} | grep --color=never '^d'" + +# See: https://superuser.com/a/656746/280737 +alias ll='LC_ALL="C.UTF-8" ls -alF' + +# Always use color output for `ls` +# shellcheck disable=SC2139 +alias ls="command ls ${colorflag}" +export LS_COLORS='no=00:fi=00:di=01;34:ln=01;36:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arj=01;31:*.taz=01;31:*.lzh=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.gz=01;31:*.bz2=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.jpg=01;35:*.jpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.avi=01;35:*.fli=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.ogg=01;35:*.mp3=01;35:*.wav=01;35:' + +# Always enable colored `grep` output +alias grep='grep --color=auto ' + +# Enable aliases to be sudo’ed +alias sudo='sudo ' + +# Get week number +alias week='date +%V' + +# Stopwatch +alias timer='echo "Timer started. Stop with Ctrl-D." && date && time cat && date' + +# Canonical hex dump; some systems have this symlinked +command -v hd > /dev/null || alias hd="hexdump -C" + +# vhosts +alias hosts='sudo nano /etc/hosts' + +# copy working directory +alias cwd='pwd | tr -d "\r\n" | xclip -selection clipboard' + +# copy file interactive +alias cp='cp -i' + +# move file interactive +alias mv='mv -i' + +# untar +alias untar='tar xvf' + +# Zephir related +alias untar='tar xvf' + +PATH=$PATH:./vendor/bin diff --git a/docker/8.1/config/extra.ini b/docker/8.1/config/extra.ini new file mode 100644 index 00000000..ec632f51 --- /dev/null +++ b/docker/8.1/config/extra.ini @@ -0,0 +1,8 @@ +error_reporting = E_ALL +display_errors = "On" +display_startup_errors = "On" +log_errors = "On" +error_log = /srv/storage/logs/php_errors.log +memory_limit = 512M +apc.enable_cli = "On" +session.save_path = "/tmp" diff --git a/docker/Dockerfile b/docker/Dockerfile deleted file mode 100644 index bdc5e6a7..00000000 --- a/docker/Dockerfile +++ /dev/null @@ -1,40 +0,0 @@ -# docker build -t phalconphp/vokuro:4.1.2 -f docker/Dockerfile . - -# debian/buster -FROM php:7.4-cli - -ENV VERSION=4.1.2 - -LABEL version="$VERSION" \ - vendor="Phalcon" \ - maintainer="Phalcon Team " \ - description="The PHP image to test Vökuró example concepts" - -ADD . /code - -WORKDIR /code - -RUN apt update \ - && curl -s https://packagecloud.io/install/repositories/phalcon/stable/script.deb.sh | bash \ - && apt update -y \ - && apt install php7.4-phalcon \ - && docker-php-ext-install opcache pdo_mysql mysqli 1> /dev/null \ - && printf "\\n" | pecl install --force psr 1> /dev/null \ - && docker-php-ext-enable psr \ - && docker-php-ext-enable phalcon \ - && php -m | grep -i "opcache\|mysql\|phalcon\|psr\|pdo\|mbstring" \ - && mv /code/.env.example /code/.env \ - && apt-get autoremove -y \ - && apt-get autoclean -y \ - && apt-get clean -y \ - && rm -rf /tmp/* /var/tmp/* \ - && find /var/cache/apt/archives /var/lib/apt/lists /var/cache \ - -not -name lock \ - -type f \ - -delete \ - && find /var/log -type f | while read f; do echo -n '' > ${f}; done - -EXPOSE 80 - -# docker run -p 80:80 phalconphp/vokuro:4.1.2 -CMD ["php", "-S", "0.0.0.0:80", "-t", "public/", ".htrouter.php"] diff --git a/phinx.php b/phinx.php index 0cbf3e62..bf727490 100644 --- a/phinx.php +++ b/phinx.php @@ -2,32 +2,39 @@ use Dotenv\Dotenv; -$dotenv = Dotenv::create(__DIR__); -$dotenv->load(); +(Dotenv::createImmutable(__DIR__))->load(); -return -[ - 'paths' => [ +$adapter = strtolower($_ENV['DB_ADAPTER'] ?? 'mysql'); +$host = $_ENV['DB_HOST'] ?? 'localhost'; +$user = $_ENV['DB_USERNAME'] ?? 'root'; +$pass = $_ENV['DB_PASSWORD'] ?? ''; +$port = $_ENV['DB_PORT'] ?? 3306; +$name = $_ENV['DB_NAME'] ?? 'phalcon_vokuro'; + +if ('sqlite' === $adapter) { + $name = '%%PHINX_CONFIG_DIR%%/db/' . $name; +} + +return [ + 'paths' => [ 'migrations' => [ 'Vokuro\\Migrations' => '%%PHINX_CONFIG_DIR%%/db/migrations' ], - 'seeds' => [ + 'seeds' => [ 'Vokuro\\Seeds' => '%%PHINX_CONFIG_DIR%%/db/seeds', ], ], - 'environments' => [ + 'environments' => [ 'default_migration_table' => 'phinxlog', - 'default_database' => 'development', - 'development' => [ - 'adapter' => strtolower(getenv('DB_ADAPTER')), - 'host' => getenv('DB_HOST'), - 'name' => strtolower(getenv('DB_ADAPTER')) === 'sqlite' ? - '%%PHINX_CONFIG_DIR%%/db/' . getenv('DB_NAME') : - getenv('DB_NAME'), - 'user' => getenv('DB_USERNAME'), - 'pass' => getenv('DB_PASSWORD'), - 'port' => getenv('DB_PORT'), - 'charset' => 'utf8', + 'default_database' => 'development', + 'development' => [ + 'adapter' => $adapter, + 'host' => $host, + 'name' => $name, + 'user' => $user, + 'pass' => $pass, + 'port' => $port, + 'charset' => 'utf8', 'collation' => 'utf8_unicode_ci', ], ], diff --git a/phpcs.xml.dist b/phpcs.xml.dist index c893a954..16dce352 100644 --- a/phpcs.xml.dist +++ b/phpcs.xml.dist @@ -2,8 +2,9 @@ Phalcon Coding Standards + - + diff --git a/phpstan.neon.dist b/phpstan.neon.dist index f6c3a616..69e04b8e 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -1,6 +1,9 @@ parameters: - bootstrap: %rootDir%/../../../vendor/autoload.php - + level: 5 + paths: + - src + bootstrapFiles: + - %rootDir%/../../../vendor/autoload.php ignoreErrors: - '#Parameter \#1 \$eventsManager of method Phalcon#' reportUnmatchedIgnoredErrors: false diff --git a/psalm.xml.dist b/psalm.xml.dist index e45c0a31..57dab7d0 100644 --- a/psalm.xml.dist +++ b/psalm.xml.dist @@ -1,6 +1,5 @@ load(); + (Dotenv::createImmutable($rootPath))->load(); /** * Run Vökuró! diff --git a/src/Application.php b/src/Application.php index 2db8959a..4a060d5f 100644 --- a/src/Application.php +++ b/src/Application.php @@ -1,5 +1,4 @@ di = new FactoryDefault(); - $this->app = $this->createApplication(); + $this->di = new FactoryDefault(); + $this->app = $this->createApplication(); $this->rootPath = $rootPath; $this->di->setShared(self::APPLICATION_PROVIDER, $this); @@ -67,14 +68,17 @@ public function __construct(string $rootPath) */ public function run(): string { - $baseUri = $this->di->getShared('url')->getBaseUri(); - $position = strpos($_SERVER['REQUEST_URI'], $baseUri) + strlen($baseUri); - $uri = '/' . substr($_SERVER['REQUEST_URI'], $position); + $baseUri = $this->di->getShared('url') + ->getBaseUri() + ; + $uri = $_SERVER['REQUEST_URI'] ?? '/'; + $position = (int) strpos($uri, $baseUri) + strlen($baseUri); + $uri = '/' . substr($uri, $position); /** @var ResponseInterface $response */ $response = $this->app->handle($uri); - return (string)$response->getContent(); + return (string) $response->getContent(); } /** @@ -108,7 +112,7 @@ protected function initializeProviders(): void $providers = include_once $filename; foreach ($providers as $providerClass) { /** @var ServiceProviderInterface $provider */ - $provider = new $providerClass; + $provider = new $providerClass(); $provider->register($this->di); } } diff --git a/src/Controllers/AboutController.php b/src/Controllers/AboutController.php index 59914d24..eb4ab2c6 100644 --- a/src/Controllers/AboutController.php +++ b/src/Controllers/AboutController.php @@ -1,5 +1,4 @@ request->hasPost('permissions') && $this->request->hasPost('submit')) { // Deletes the current permissions - $profile->getPermissions()->delete(); + $profile->getPermissions() + ->delete() + ; // Save the new permissions foreach ($this->request->getPost('permissions') as $permission) { @@ -67,19 +72,17 @@ public function indexAction(): void ], ]); - $profilesSelect = $this->tag->select([ - 'profileId', - $profiles, - 'using' => [ - 'id', - 'name', - ], - 'useEmpty' => true, - 'emptyText' => '...', - 'emptyValue' => '', - 'class' => 'form-control mr-sm-2', - ]); + $options = ['class' => 'form-control mr-sm-2']; + $select = $this + ->tag + ->inputSelect(' ', PHP_EOL, $options) + ->addPlaceholder('...', '', [], true) + ; + + foreach ($profiles as $profile) { + $select->add($profile->name, (string) $profile->id); + } - $this->view->setVar('profilesSelect', $profilesSelect); + $this->view->setVar('profilesSelect', $select); } } diff --git a/src/Controllers/PrivacyController.php b/src/Controllers/PrivacyController.php index 674353cf..6e08d79e 100644 --- a/src/Controllers/PrivacyController.php +++ b/src/Controllers/PrivacyController.php @@ -1,5 +1,4 @@ request->isPost()) { - $query = Criteria::fromInput($this->di, Profiles::class, $this->request->getPost()); + $query = Criteria::fromInput($this->di, Profiles::class, $this->request->getPost()); $searchparams = $query->getParams(); unset($searchparams['di']); $this->persistent->searchParams = $searchparams; @@ -68,10 +69,10 @@ public function searchAction() } $paginator = new Paginator([ - 'model' => Profiles::class, + 'model' => Profiles::class, 'parameters' => $parameters, - 'limit' => 10, - 'page' => $this->request->getQuery('page', 'int', 1), + 'limit' => 10, + 'page' => $this->request->getQuery('page', 'int', 1), ]); $this->view->setVar('page', $paginator->paginate()); @@ -84,13 +85,13 @@ public function createAction(): void { if ($this->request->isPost()) { $profile = new Profiles([ - 'name' => $this->request->getPost('name', 'striptags'), + 'name' => $this->request->getPost('name', 'striptags'), 'active' => $this->request->getPost('active'), ]); if (!$profile->save()) { foreach ($profile->getMessages() as $message) { - $this->flash->error((string)$message); + $this->flash->error((string) $message); } } else { $this->flash->success("Profile was created successfully"); @@ -117,13 +118,13 @@ public function editAction($id) if ($this->request->isPost()) { $profile->assign([ - 'name' => $this->request->getPost('name', 'striptags'), + 'name' => $this->request->getPost('name', 'striptags'), 'active' => $this->request->getPost('active'), ]); if (!$profile->save()) { foreach ($profile->getMessages() as $message) { - $this->flash->error((string)$message); + $this->flash->error((string) $message); } } else { $this->flash->success("Profile was updated successfully"); @@ -131,7 +132,7 @@ public function editAction($id) } $this->view->setVars([ - 'form' => new ProfilesForm(null, ['edit' => true]), + 'form' => new ProfilesForm(null, ['edit' => true]), 'profile' => $profile, ]); } @@ -154,7 +155,7 @@ public function deleteAction($id) if (!$profile->delete()) { foreach ($profile->getMessages() as $message) { - $this->flash->error((string)$message); + $this->flash->error((string) $message); } } else { $this->flash->success("Profile was deleted"); diff --git a/src/Controllers/SessionController.php b/src/Controllers/SessionController.php index 09a08c12..c27c04e7 100644 --- a/src/Controllers/SessionController.php +++ b/src/Controllers/SessionController.php @@ -1,5 +1,4 @@ request->isPost()) { // Send emails only is config value is set to true - if ($this->getDI()->get('config')->useMail) { + if ( + $this->getDI() + ->get('config')->useMail + ) { if ($form->isValid($this->request->getPost()) == false) { foreach ($form->getMessages() as $message) { $this->flash->error($message); diff --git a/src/Controllers/TermsController.php b/src/Controllers/TermsController.php index e4a9dba7..9d31d6a1 100644 --- a/src/Controllers/TermsController.php +++ b/src/Controllers/TermsController.php @@ -1,5 +1,4 @@ user->id); + $user = Users::findFirst($confirmation->user->id); $user->active = 'Y'; if (!$user->save()) { foreach ($confirmation->user->getMessages() as $message) { diff --git a/src/Controllers/UsersController.php b/src/Controllers/UsersController.php index 69c49e2c..7ba620ae 100644 --- a/src/Controllers/UsersController.php +++ b/src/Controllers/UsersController.php @@ -1,5 +1,4 @@ view->setVar('form', new UsersForm()); - $this->assets->collection("js")->addJs("/js/privateUsers.js", true, true); + $this->assets->collection("js") + ->addJs("/js/privateUsers.js", true, true) + ; } /** @@ -57,9 +60,9 @@ public function searchAction(): void } $paginator = new Paginator([ - 'builder' => $builder->createBuilder(), - 'limit' => 10, - 'page' => $this->request->getQuery('page', 'int', 1), + 'builder' => $builder->createBuilder(), + 'limit' => 10, + 'page' => $this->request->getQuery('page', 'int', 1), ]); $this->view->setVar('page', $paginator->paginate()); diff --git a/src/Forms/ChangePasswordForm.php b/src/Forms/ChangePasswordForm.php index 6ed94f6d..9e6034c6 100644 --- a/src/Forms/ChangePasswordForm.php +++ b/src/Forms/ChangePasswordForm.php @@ -1,5 +1,4 @@ getRootPath(), ltrim($prefix, DIRECTORY_SEPARATOR)]); + return join( + DIRECTORY_SEPARATOR, + [ + $application->getRootPath(), + ltrim($prefix, DIRECTORY_SEPARATOR) + ] + ); } diff --git a/src/Models/EmailConfirmations.php b/src/Models/EmailConfirmations.php index 6b29a789..3e8447d5 100644 --- a/src/Models/EmailConfirmations.php +++ b/src/Models/EmailConfirmations.php @@ -1,5 +1,4 @@ mustChangePassword = 'Y'; /** @var Security $security */ - $security = $this->getDI()->getShared('security'); + $security = $this->getDI() + ->getShared('security') + ; // Use this password as default $this->password = $security->hash($tempPassword); } else { @@ -119,7 +122,10 @@ public function beforeValidationOnCreate() // The account must be confirmed via e-mail // Only require this if emails are turned on in the config, otherwise account is automatically active - if ($this->getDI()->get('config')->useMail) { + if ( + $this->getDI() + ->get('config')->useMail + ) { $this->active = 'N'; } else { $this->active = 'Y'; @@ -138,14 +144,18 @@ public function beforeValidationOnCreate() public function afterCreate() { // Only send the confirmation email if emails are turned on in the config - if ($this->getDI()->get('config')->useMail && $this->active == 'N') { + if ( + $this->getDI() + ->get('config')->useMail && $this->active == 'N' + ) { $emailConfirmation = new EmailConfirmations(); $emailConfirmation->usersId = $this->id; if ($emailConfirmation->save()) { $this->getDI() - ->getFlash() - ->notice('A confirmation mail has been sent to ' . $this->email); + ->getFlash() + ->notice('A confirmation mail has been sent to ' . $this->email) + ; } } } diff --git a/src/Plugins/Acl/Acl.php b/src/Plugins/Acl/Acl.php index 1a27912d..90ba9e7f 100644 --- a/src/Plugins/Acl/Acl.php +++ b/src/Plugins/Acl/Acl.php @@ -1,5 +1,4 @@ @@ -88,7 +89,9 @@ public function isPrivate($controllerName): bool */ public function isAllowed($profile, $controller, $action): bool { - return $this->getAcl()->isAllowed($profile, $controller, $action); + return $this->getAcl() + ->isAllowed($profile, $controller, $action) + ; } /** @@ -230,7 +233,7 @@ public function rebuild(): AclMemory */ protected function getFilePath() { - if (!isset($this->filePath)) { + if (true === empty($this->filePath)) { $this->filePath = rtrim($this->config->application->cacheDir, '\\/') . '/acl/data.txt'; } diff --git a/src/Plugins/Auth/Auth.php b/src/Plugins/Auth/Auth.php index 53bea6c6..e2823424 100644 --- a/src/Plugins/Auth/Auth.php +++ b/src/Plugins/Auth/Auth.php @@ -1,5 +1,4 @@ cookies->get('RMU')->getValue(); - $cookieToken = $this->cookies->get('RMT')->getValue(); + $userId = $this->cookies->get('RMU') + ->getValue() + ; + $cookieToken = $this->cookies->get('RMT') + ->getValue() + ; $user = Users::findFirstById($userId); if ($user) { @@ -201,8 +206,12 @@ public function loginWithRememberMe() } } - $this->cookies->get('RMU')->delete(); - $this->cookies->get('RMT')->delete(); + $this->cookies->get('RMU') + ->delete() + ; + $this->cookies->get('RMT') + ->delete() + ; return $this->response->redirect('session/login'); } @@ -256,17 +265,23 @@ public function getName() public function remove() { if ($this->cookies->has('RMU')) { - $this->cookies->get('RMU')->delete(); + $this->cookies->get('RMU') + ->delete() + ; } if ($this->cookies->has('RMT')) { - $token = $this->cookies->get('RMT')->getValue(); + $token = $this->cookies->get('RMT') + ->getValue() + ; $userId = $this->findFirstByToken($token); if ($userId) { $this->deleteToken($userId); } - $this->cookies->get('RMT')->delete(); + $this->cookies->get('RMT') + ->delete() + ; } $this->session->remove('auth-identity'); diff --git a/src/Plugins/Mail/Mail.php b/src/Plugins/Mail/Mail.php index 02901292..f6bc9ff7 100644 --- a/src/Plugins/Mail/Mail.php +++ b/src/Plugins/Mail/Mail.php @@ -1,5 +1,4 @@ config->mail; $template = $this->getTemplate($name, $params); + $mailUsername = $mailSettings->smtp->username; + if (true !== empty($mailUsername)) { + $mailUsername .= ':' . $mailSettings->smtp->password; + } + // Create the message - $message = new Message(); + $message = new Email(); $message - ->setSubject($subject) - ->setTo($to) - ->setFrom([$mailSettings->fromEmail => $mailSettings->fromName]) - ->setBody($template, 'text/html'); + ->subject($subject) + ->from(new Address($mailSettings->fromEmail, $mailSettings->fromName)) + ->to(...$to) + ->text($template) + ; - $transport = new Smtp($mailSettings->smtp->server, $mailSettings->smtp->port, $mailSettings->smtp->security); - $transport - ->setUsername($mailSettings->smtp->username) - ->setPassword($mailSettings->smtp->password); + $dsn = sprintf( + 'smtp://%s@%s:%s', + $mailUsername, + $mailSettings->smtp->server, + $mailSettings->smtp->port + ); + $transport = Transport::fromDsn($dsn); - return (new Swift_Mailer($transport))->send($message); + (new Mailer($transport))->send($message); } /** diff --git a/src/Providers/AclProvider.php b/src/Providers/AclProvider.php index f4bbcf65..cc4431bf 100644 --- a/src/Providers/AclProvider.php +++ b/src/Providers/AclProvider.php @@ -1,5 +1,4 @@ getRootPath(); - $di->setShared($this->providerName, function () use ($rootPath) { - $filename = $rootPath . '/config/acl.php'; - $privateResources = []; - if (is_readable($filename)) { - $privateResources = include $filename; - if (!empty($privateResources['private'])) { - $privateResources = $privateResources['private']; + $di->setShared( + $this->providerName, + function () use ($rootPath) { + $filename = $rootPath . '/config/acl.php'; + $privateResources = []; + if (is_readable($filename)) { + $privateResources = include $filename; + if (!empty($privateResources['private'])) { + $privateResources = $privateResources['private']; + } } - } - $acl = new Acl(); - $acl->addPrivateResources($privateResources); + $acl = new Acl(); + $acl->addPrivateResources($privateResources); - return $acl; - }); + return $acl; + } + ); } } diff --git a/src/Providers/AssetsProvider.php b/src/Providers/AssetsProvider.php index f0fb325d..11e387e9 100644 --- a/src/Providers/AssetsProvider.php +++ b/src/Providers/AssetsProvider.php @@ -1,5 +1,4 @@ setShared($this->providerName, function () use ($assetManager) { + /** @var TagFactory $tagFactory */ + $tagFactory = $di->getShared('tag'); - $assetManager->collection('css') - ->addCss( - '//stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css?dc=' . self::VERSION, - false, - false, - [ - "media" => "screen,projection", - "integrity" => "sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T", - "crossorigin" => "anonymous" - ] - ) - ->addCss('/css/style.css?dc=' . self::VERSION, true, true, [ - "media" => "screen,projection" - ]); + $di->setShared( + $this->providerName, + function () use ($tagFactory) { + $assetManager = new Manager($tagFactory); + $assetManager->collection('css') + ->addCss( + '//cdn.jsdelivr.net/npm/bootstrap@4.6.2/dist/css/bootstrap.min.css?dc=' . self::VERSION, + false, + false, + [ + 'media' => 'screen,projection', + 'integrity' => 'sha384-xOolHFLEh07PJGoPkLv1IbcEPTNtaed2xpHsD9ESMhqIYd0nLMwNLD69Npy4HI+N', + 'crossorigin' => 'anonymous' + ] + ) + ->addCss('/css/style.css?dc=' . self::VERSION, true, true, [ + 'media' => 'screen,projection' + ]) + ; - $assetManager->collection('js') - ->addJs('//code.jquery.com/jquery-3.3.1.slim.min.js?dc=' . self::VERSION, false, true, [ - "integrity" => "sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo", - "crossorigin" => "anonymous" - ]) - ->addJs( - '//stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js?dc=' . self::VERSION, - false, - true, - [ - "integrity" => "sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM", - "crossorigin" => "anonymous" - ] - ); + $assetManager->collection('js') + ->addJs( + '//code.jquery.com/jquery-3.6.1.slim.min.js?dc=' . self::VERSION, + false, + true, + [ + 'integrity' => 'sha256-w8CvhFs7iHNVUtnSP0YKEg00p9Ih13rlL9zGqvLdePA=', + 'crossorigin' => 'anonymous' + ] + ) + ->addJs( + '//cdn.jsdelivr.net/npm/bootstrap@4.6.2/dist/js/bootstrap.min.js?dc=' . self::VERSION, + false, + true, + [ + 'integrity' => 'sha384-+sLIOodYLS7CIrQpBjl+C7nPvqq+FbNUBDunl/OZv93DB7Ln/533i8e/mZXLi/P+', + 'crossorigin' => 'anonymous' + ] + ) + ; - return $assetManager; - }); + return $assetManager; + } + ); } } diff --git a/src/Providers/AuthProvider.php b/src/Providers/AuthProvider.php index 1005e44b..fc7567f7 100644 --- a/src/Providers/AuthProvider.php +++ b/src/Providers/AuthProvider.php @@ -1,5 +1,4 @@ getRootPath(); - $di->setShared($this->providerName, function () use ($rootPath) { - $config = include $rootPath . '/config/config.php'; + $di->setShared( + $this->providerName, + function () use ($rootPath) { + $config = include $rootPath . '/config/config.php'; - return new Config($config); - }); + return new Config($config); + } + ); } } diff --git a/src/Providers/CryptProvider.php b/src/Providers/CryptProvider.php index 7af441b7..cf6003c2 100644 --- a/src/Providers/CryptProvider.php +++ b/src/Providers/CryptProvider.php @@ -1,5 +1,4 @@ getShared('config')->path('application.cryptSalt'); + $cryptSalt = $di->getShared('config') + ->path('application.cryptSalt') + ; - $di->set($this->providerName, function () use ($cryptSalt) { - $crypt = new Crypt(); - $crypt->setKey($cryptSalt); + $di->set( + $this->providerName, + function () use ($cryptSalt) { + $crypt = new Crypt(); + $crypt->setKey($cryptSalt); - return $crypt; - }); + return $crypt; + } + ); } } diff --git a/src/Providers/DbProvider.php b/src/Providers/DbProvider.php index ecae3b0f..ede94768 100644 --- a/src/Providers/DbProvider.php +++ b/src/Providers/DbProvider.php @@ -1,5 +1,4 @@ Pdo\Mysql::class, 'pgsql' => Pdo\Postgresql::class, 'sqlite' => Pdo\Sqlite::class, @@ -47,13 +49,18 @@ class DbProvider implements ServiceProviderInterface public function register(DiInterface $di): void { /** @var Config $config */ - $config = $di->getShared('config')->get('database'); + $config = $di->getShared('config') + ->get('database') + ; $class = $this->getClass($config); $config = $this->createConfig($config); - $di->set($this->providerName, function () use ($class, $config) { - return new $class($config); - }); + $di->set( + $this->providerName, + function () use ($class, $config) { + return new $class($config); + } + ); } /** diff --git a/src/Providers/DispatcherProvider.php b/src/Providers/DispatcherProvider.php index 1a22b91b..c94d4965 100644 --- a/src/Providers/DispatcherProvider.php +++ b/src/Providers/DispatcherProvider.php @@ -1,5 +1,4 @@ set($this->providerName, function () { - $dispatcher = new Dispatcher(); - $dispatcher->setDefaultNamespace('Vokuro\Controllers'); + $di->set( + $this->providerName, + function () { + $dispatcher = new Dispatcher(); + $dispatcher->setDefaultNamespace('Vokuro\Controllers'); - return $dispatcher; - }); + return $dispatcher; + } + ); } } diff --git a/src/Providers/FlashProvider.php b/src/Providers/FlashProvider.php index 7d65115e..3e740781 100644 --- a/src/Providers/FlashProvider.php +++ b/src/Providers/FlashProvider.php @@ -1,5 +1,4 @@ set($this->providerName, function () { - $escaper = new Escaper(); - $flash = new Flash($escaper); - $flash->setImplicitFlush(false); - $flash->setCssClasses([ - 'error' => 'alert alert-danger', - 'success' => 'alert alert-success', - 'notice' => 'alert alert-info', - 'warning' => 'alert alert-warning', - ]); + $escaper = $di->getShared('escaper'); + $di->set( + $this->providerName, + function () use ($escaper) { + $flash = new Flash($escaper); + $flash->setImplicitFlush(false); + $flash->setCssClasses( + [ + 'error' => 'alert alert-danger', + 'success' => 'alert alert-success', + 'notice' => 'alert alert-info', + 'warning' => 'alert alert-warning', + ] + ); - return $flash; - }); + return $flash; + } + ); } } diff --git a/src/Providers/LoggerProvider.php b/src/Providers/LoggerProvider.php index 0eadca08..0ea91476 100644 --- a/src/Providers/LoggerProvider.php +++ b/src/Providers/LoggerProvider.php @@ -1,5 +1,4 @@ getShared('config')->get('logger'); - - $di->set($this->providerName, function () use ($loggerConfigs) { - $filename = trim($loggerConfigs->get('filename'), '\\/'); - $path = rtrim($loggerConfigs->get('path'), '\\/') . DIRECTORY_SEPARATOR; - - $formatter = new FormatterLine($loggerConfigs->get('format'), $loggerConfigs->get('date')); - $logger = new FileLogger($path . $filename); - - $logger->setFormatter($formatter); - - return $logger; - }); + $loggerConfigs = $di->getShared('config') + ->get('logger') + ; + + $di->set( + $this->providerName, + function () use ($loggerConfigs) { + $filename = trim($loggerConfigs->get('filename'), '\\/'); + $path = rtrim($loggerConfigs->get('path'), '\\/') . DIRECTORY_SEPARATOR; + $adapter = new Stream($path . $filename); + $formatter = new Line( + $loggerConfigs->get('format'), + $loggerConfigs->get('date') + ); + $adapter->setFormatter($formatter); + + return new Logger('vokuro-logger', ['main' => $adapter]); + } + ); } } diff --git a/src/Providers/MailProvider.php b/src/Providers/MailProvider.php index 84306e96..4dc6322d 100644 --- a/src/Providers/MailProvider.php +++ b/src/Providers/MailProvider.php @@ -1,5 +1,4 @@ getShared('config')->path('application.cacheDir'); - $di->set($this->providerName, function () use ($cacheDir) { - return new MetaDataAdapter([ - 'metaDataDir' => $cacheDir . 'metaData/', - ]); - }); + $cacheDir = $di->getShared('config') + ->path('application.cacheDir') + ; + $di->set( + $this->providerName, + function () use ($cacheDir) { + return new MetaDataAdapter( + [ + 'metaDataDir' => $cacheDir . 'metaData/', + ] + ); + } + ); } } diff --git a/src/Providers/RouterProvider.php b/src/Providers/RouterProvider.php index d8d52b5e..fd33ba3b 100644 --- a/src/Providers/RouterProvider.php +++ b/src/Providers/RouterProvider.php @@ -1,5 +1,4 @@ getRootPath(); - $di->set($this->providerName, function () use ($basePath) { - $router = new Router(); + $di->set( + $this->providerName, + function () use ($basePath) { + $router = new Router(); - $routes = $basePath . '/config/routes.php'; - if (!file_exists($routes) || !is_readable($routes)) { - throw new Exception($routes . ' file does not exist or is not readable.'); - } + $routes = $basePath . '/config/routes.php'; + if (!file_exists($routes) || !is_readable($routes)) { + throw new Exception($routes . ' file does not exist or is not readable.'); + } - require_once $routes; + require_once $routes; - return $router; - }); + return $router; + } + ); } } diff --git a/src/Providers/SecurityProvider.php b/src/Providers/SecurityProvider.php index bb9462d3..bbeccbf0 100644 --- a/src/Providers/SecurityProvider.php +++ b/src/Providers/SecurityProvider.php @@ -1,5 +1,4 @@ set($this->providerName, function () use ($di) { - $security = new Security(); - $security->setDI($di); + $di->set( + $this->providerName, + function () use ($di) { + $security = new Security(); + $security->setDI($di); - return $security; - }); + return $security; + } + ); } } diff --git a/src/Providers/SessionBagProvider.php b/src/Providers/SessionBagProvider.php index 76291835..58b48e23 100644 --- a/src/Providers/SessionBagProvider.php +++ b/src/Providers/SessionBagProvider.php @@ -1,5 +1,4 @@ set($this->providerName, function () { - return new Bag('conditions'); - }); + $session = $di->get('session'); + $di->set( + $this->providerName, + function () use ($session) { + return new Bag($session, 'conditions'); + } + ); } } diff --git a/src/Providers/SessionProvider.php b/src/Providers/SessionProvider.php index a82d5744..da2535bf 100644 --- a/src/Providers/SessionProvider.php +++ b/src/Providers/SessionProvider.php @@ -1,5 +1,4 @@ getShared('config')->path('application.sessionSavePath'); - $handler = new SessionAdapter([ - 'savePath' => $savePath, - ]); - - $di->set($this->providerName, function () use ($handler) { - $session = new SessionManager(); - $session->setAdapter($handler); - $session->start(); - - return $session; - }); + $savePath = $di->getShared('config') + ->path('application.sessionSavePath') + ; + $handler = new SessionAdapter( + [ + 'savePath' => $savePath, + ] + ); + + $di->set( + $this->providerName, + function () use ($handler) { + $session = new SessionManager(); + $session->setAdapter($handler); + $session->start(); + + return $session; + } + ); } } diff --git a/src/Providers/UrlProvider.php b/src/Providers/UrlProvider.php index baa88023..c7672bb7 100644 --- a/src/Providers/UrlProvider.php +++ b/src/Providers/UrlProvider.php @@ -1,5 +1,4 @@ getShared('config')->path('application.baseUri'); + $baseUri = $di->getShared('config') + ->path('application.baseUri') + ; - $di->setShared($this->providerName, function () use ($baseUri) { - $url = new UrlResolver(); - $url->setBaseUri($baseUri); + $di->setShared( + $this->providerName, + function () use ($baseUri) { + $url = new UrlResolver(); + $url->setBaseUri($baseUri); - return $url; - }); + return $url; + } + ); } } diff --git a/src/Providers/ViewProvider.php b/src/Providers/ViewProvider.php index 3d3cc5b8..90868ff9 100644 --- a/src/Providers/ViewProvider.php +++ b/src/Providers/ViewProvider.php @@ -1,5 +1,4 @@ path('application.cacheDir'); - $di->setShared($this->providerName, function () use ($viewsDir, $cacheDir, $di) { - $view = new View(); - $view->setViewsDir($viewsDir); - $view->registerEngines([ - '.volt' => function (View $view) use ($cacheDir, $di) { - $volt = new Volt($view, $di); - $volt->setOptions([ - 'path' => $cacheDir . 'volt/', - 'separator' => '_', - ]); - - return $volt; - }, - ]); - - return $view; - }); + $di->setShared( + $this->providerName, + function () use ($viewsDir, $cacheDir, $di) { + $view = new View(); + $view->setViewsDir($viewsDir); + $view->registerEngines( + [ + '.volt' => function (View $view) use ($cacheDir, $di) { + $volt = new Volt($view, $di); + $volt->setOptions( + [ + 'path' => $cacheDir . 'volt/', + 'separator' => '_', + ] + ); + + return $volt; + }, + ] + ); + + return $view; + } + ); } } diff --git a/tests/acceptance/controllers/AboutControllerCest.php b/tests/acceptance/controllers/AboutControllerCest.php index 64f956fc..9cfc15ab 100644 --- a/tests/acceptance/controllers/AboutControllerCest.php +++ b/tests/acceptance/controllers/AboutControllerCest.php @@ -1,4 +1,5 @@ '', + $emptyData = []; + $emptyPasswordData = [ + self::PASS_KEY => '', self::CONFIRM_PASS_KEY => '', ]; - $shortPasswordData = [ - self::PASS_KEY => '123', + $shortPasswordData = [ + self::PASS_KEY => '123', self::CONFIRM_PASS_KEY => '123', ]; - $emptyConfirmPasswordData = [ + $emptyConfirmPasswordData = [ self::PASS_KEY => 'valid password empty config', ]; $missMatchConfigPasswordData = [ - self::PASS_KEY => '123456780', + self::PASS_KEY => '123456780', self::CONFIRM_PASS_KEY => '123456789', ]; - $correctData1 = [ - self::PASS_KEY => '12345678', + $correctData1 = [ + self::PASS_KEY => '12345678', self::CONFIRM_PASS_KEY => '12345678', ]; - $correctData2 = [ - self::PASS_KEY => 'valid password', + $correctData2 = [ + self::PASS_KEY => 'valid password', self::CONFIRM_PASS_KEY => 'valid password' ]; - $correctData3 = [ - self::PASS_KEY => '(*%^%$#@#$%^', + $correctData3 = [ + self::PASS_KEY => '(*%^%$#@#$%^', self::CONFIRM_PASS_KEY => '(*%^%$#@#$%^', ]; @@ -61,13 +62,13 @@ public function dataProvider(): array * @dataProvider dataProvider * * @param array $data - * @param int $errorsCount - * @param bool $expected + * @param int $errorsCount + * @param bool $expected */ public function testValidations(array $data, int $errorsCount, bool $expected): void { - $form = new ChangePasswordForm(); - $isValid = $form->isValid($data); + $form = new ChangePasswordForm(); + $isValid = $form->isValid($data); $messages = $form->getMessages(); $this->assertEquals($expected, $isValid); diff --git a/tests/functional/forms/ForgotPasswordFormTest.php b/tests/functional/forms/ForgotPasswordFormTest.php index 9533f2f7..1a0c21e0 100644 --- a/tests/functional/forms/ForgotPasswordFormTest.php +++ b/tests/functional/forms/ForgotPasswordFormTest.php @@ -1,4 +1,5 @@ isValid($data); + $form = new ForgotPasswordForm(); + $isValid = $form->isValid($data); $messages = $form->getMessages(); $this->assertEquals($expected, $isValid); diff --git a/tests/functional/forms/LoginFormTest.php b/tests/functional/forms/LoginFormTest.php index dc88c37c..d526e196 100644 --- a/tests/functional/forms/LoginFormTest.php +++ b/tests/functional/forms/LoginFormTest.php @@ -1,35 +1,34 @@ register($di); - $emptyData = []; + $emptyData = []; $incorrectCsrfData = [ self::EMAIL_KEY => 'bob@phalcon.io', - self::PASS_KEY => 'password1', - self::CSRF_KEY => 'invalid', + self::PASS_KEY => 'password1', + self::CSRF_KEY => 'invalid', ]; return [ @@ -42,13 +41,13 @@ public function dataProvider(): array * @dataProvider dataProvider * * @param array $data - * @param int $errorsCount - * @param bool $expected + * @param int $errorsCount + * @param bool $expected */ public function testValidations(array $data, int $errorsCount, bool $expected): void { - $form = new LoginForm(); - $isValid = $form->isValid($data); + $form = new LoginForm(); + $isValid = $form->isValid($data); $messages = $form->getMessages(); $this->assertEquals($expected, $isValid); diff --git a/tests/functional/forms/ProfilesFormTest.php b/tests/functional/forms/ProfilesFormTest.php index 2df5ad8a..801ff55c 100644 --- a/tests/functional/forms/ProfilesFormTest.php +++ b/tests/functional/forms/ProfilesFormTest.php @@ -1,4 +1,5 @@ isValid($data); + $form = new ProfilesForm(); + $isValid = $form->isValid($data); $messages = $form->getMessages(); $this->assertEquals($expected, $isValid); diff --git a/tests/unit/ApplicationTest.php b/tests/unit/ApplicationTest.php index 924d20c2..46296dd3 100644 --- a/tests/unit/ApplicationTest.php +++ b/tests/unit/ApplicationTest.php @@ -1,4 +1,5 @@ constructEmptyExcept(Application::class, 'getRootPath', ['rootPath' => $rootPath]); + $class = $this->constructEmptyExcept(Application::class, 'getRootPath', ['rootPath' => $rootPath]); $this->assertEquals($rootPath, $class->getRootPath()); } diff --git a/tests/unit/controllers/AboutControllerTest.php b/tests/unit/controllers/AboutControllerTest.php index 69adbc7b..1f4accb1 100644 --- a/tests/unit/controllers/AboutControllerTest.php +++ b/tests/unit/controllers/AboutControllerTest.php @@ -1,4 +1,5 @@ About this Demo
- This is a sample application for the Phalcon Framework. We expect to implement as many features - as possible to show how the framework works and its potential. Please write us if you have any - feedback or comments. Feel free to clone the code of this application here. + This is a sample application for the {{ tag.a('https://phalcon.io', 'Phalcon Framework') }}. + We expect to implement as many features as possible to show how the framework works and + its potential. Please write us if you have any feedback or comments. Feel free to + clone the code of this application {{ tag.a('https://github.com/phalcon/vokuro', 'here') }}. The purpose of this application is merely academic. Thanks!
diff --git a/themes/vokuro/emailTemplates/confirmation.volt b/themes/vokuro/emailTemplates/confirmation.volt index a4b7d27b..465df9c3 100644 --- a/themes/vokuro/emailTemplates/confirmation.volt +++ b/themes/vokuro/emailTemplates/confirmation.volt @@ -1,25 +1,28 @@ - - -

+ + +

-

You're - Almost There! Just Confirm Your Email

+

You're + Almost There! Just Confirm Your Email

-

- You've successfully created a Vökuró account. To activate it, please click below to verify your email - address. +

+ You've successfully created a Vökuró account. To activate it, + please click below to verify your email address. -
-
- Confirm +
+
+ {{ tag.a( + 'http://' ~ publicUrl ~ confirmUrl, + 'Confirm', + ['style' : 'background:#E86537;color:#fff;padding:10px'] + ) }} -
-
- Vökuró. Enjoy! -
-

- - +
+
+ Vökuró. Enjoy! +
+

+ + diff --git a/themes/vokuro/emailTemplates/reset.volt b/themes/vokuro/emailTemplates/reset.volt index bd31a8f6..efb30a0e 100644 --- a/themes/vokuro/emailTemplates/reset.volt +++ b/themes/vokuro/emailTemplates/reset.volt @@ -1,24 +1,30 @@ - - -

+ + +

-

Reset Your - Password

+

+ Reset Your Password +

-

- To reset the password for the Vökuró account associated with your email, click on the button below. If you - don't want to reset your password, please disregard this email. +

+ To reset the password for the Vökuró account associated with + your email, click on the button below. If you don't want to + reset your password, please disregard this email. -
-
- Reset +
+
+ {{ tag.a( + 'http://' ~ publicUrl ~ resetUrl, + 'Reset', + ['style' : 'background:#E86537;color:#fff;padding:10px'] + ) }} -
-
- Vökuró. Enjoy! -
-

- - +
+
+ Vökuró. Enjoy! +
+

+ + diff --git a/themes/vokuro/index.volt b/themes/vokuro/index.volt index fd07ae6d..6b895973 100644 --- a/themes/vokuro/index.volt +++ b/themes/vokuro/index.volt @@ -6,8 +6,8 @@ {{ assets.outputCss('css') }} - {{ content() }} +{{ content() }} - {{ assets.outputJs('js') }} +{{ assets.outputJs('js') }} diff --git a/themes/vokuro/index/index.volt b/themes/vokuro/index/index.volt index cd0067a3..17831add 100644 --- a/themes/vokuro/index/index.volt +++ b/themes/vokuro/index/index.volt @@ -4,7 +4,12 @@

Welcome!

This is a website secured by Phalcon Framework


- {{ link_to('session/signup', ' Create an Account', 'class': 'btn btn-primary btn-large') }} + {{ tag.a( + 'session/signup', + " Create an Account", + ['class': 'btn btn-primary btn-large'], + true + ) }}
@@ -12,16 +17,21 @@

Awesome Section

-

Nullam quis risus eget urna mollis ornare vel eu leo. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nullam id dolor id nibh ultricies vehicula ut id elit.

-

Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Duis mollis, est non commodo luctus, nisi erat porttitor ligula, eget lacinia odio sem nec elit. Donec sed odio dui.

+

Nullam quis risus eget urna mollis ornare vel eu leo. Cum sociis natoque penatibus et magnis dis + parturient montes, nascetur ridiculus mus. Nullam id dolor id nibh ultricies vehicula ut id + elit.

+

Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Duis mollis, est non commodo + luctus, nisi erat porttitor ligula, eget lacinia odio sem nec elit. Donec sed odio dui.

Important Stuff

-

Nullam quis risus eget urna mollis ornare vel eu leo. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nullam id dolor id nibh ultricies vehicula ut id elit.

-

Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Duis mollis, est non commodo luctus, nisi erat porttitor ligula, eget lacinia odio sem nec elit. Donec sed odio dui.

+

Nullam quis risus eget urna mollis ornare vel eu leo. Cum sociis natoque penatibus et magnis dis parturient + montes, nascetur ridiculus mus. Nullam id dolor id nibh ultricies vehicula ut id elit.

+

Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Duis mollis, est non commodo luctus, + nisi erat porttitor ligula, eget lacinia odio sem nec elit. Donec sed odio dui.

@@ -29,11 +39,20 @@
Vökuró, Inc.
456 Infinite Loop, Suite 101
- P: (123) 456-7890 + P:  + {{ tag.a( + 'tel:+11234567890', + '(123) 456-7890', + ['title' : 'Call us'] + ) }}
Contacts
- team@phalcon.io + {{ tag.a( + 'mailto:team@phalcon.io?subject=Vökuró feedback', + 'team@phalcon.io', + ['title' : 'Send feedback'] + ) }}
diff --git a/themes/vokuro/layouts/emailTemplates.volt b/themes/vokuro/layouts/emailTemplates.volt index 673273ce..81cd52f9 100644 --- a/themes/vokuro/layouts/emailTemplates.volt +++ b/themes/vokuro/layouts/emailTemplates.volt @@ -1,12 +1,14 @@ - +
diff --git a/themes/vokuro/layouts/private.volt b/themes/vokuro/layouts/private.volt index 8f884334..c188d3b0 100644 --- a/themes/vokuro/layouts/private.volt +++ b/themes/vokuro/layouts/private.volt @@ -6,9 +6,15 @@ ] -%} diff --git a/themes/vokuro/layouts/public.volt b/themes/vokuro/layouts/public.volt index 8f828725..16685590 100644 --- a/themes/vokuro/layouts/public.volt +++ b/themes/vokuro/layouts/public.volt @@ -4,9 +4,10 @@ ] -%} diff --git a/themes/vokuro/permissions/index.volt b/themes/vokuro/permissions/index.volt index 7a7366aa..ffaee01e 100644 --- a/themes/vokuro/permissions/index.volt +++ b/themes/vokuro/permissions/index.volt @@ -6,35 +6,37 @@ {{ profilesSelect }} - {{ submit_button('Search', 'class': 'btn btn-primary', 'name' : 'search') }} + {{ tag.inputSubmit('search', 'Search', ['class': 'btn btn-primary']) }} {% if request.isPost() and profile %} -
-
- {% for resource, actions in acl.getResources() %} -

{{ resource }}

+
+
+ {% for resource, actions in acl.getResources() %} +

{{ resource }}

-
- +

Vökuró

- - - - - - - - {% for action in actions %} +
Description
+ - - + + - {% endfor %} - -
- - {{ acl.getActionDescription(action) ~ ' ' ~ resource }}Description
- {% endfor %} + + + {% for action in actions %} + + + + + {{ acl.getActionDescription(action) ~ ' ' ~ resource }} + + {% endfor %} + + + {% endfor %} - {{ submit_button('Submit', 'class': 'btn btn-primary', 'name':'submit') }} - + {{ tag.inputSubmit('Submit', 'submit', ['class': 'btn btn-primary']) }} + {% endif %} diff --git a/themes/vokuro/privacy/index.volt b/themes/vokuro/privacy/index.volt index e46c19a8..b4fda16e 100644 --- a/themes/vokuro/privacy/index.volt +++ b/themes/vokuro/privacy/index.volt @@ -1,6 +1,8 @@

Privacy

-

Nullam quis risus eget urna mollis ornare vel eu leo. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nullam id dolor id nibh ultricies vehicula ut id elit.

-

Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Duis mollis, est non commodo luctus, nisi erat porttitor ligula, eget lacinia odio sem nec elit. Donec sed odio dui.

+

Nullam quis risus eget urna mollis ornare vel eu leo. Cum sociis natoque penatibus et magnis dis parturient + montes, nascetur ridiculus mus. Nullam id dolor id nibh ultricies vehicula ut id elit.

+

Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Duis mollis, est non commodo luctus, nisi + erat porttitor ligula, eget lacinia odio sem nec elit. Donec sed odio dui.

diff --git a/themes/vokuro/profiles/create.volt b/themes/vokuro/profiles/create.volt index 8395b731..bdfbd4cb 100644 --- a/themes/vokuro/profiles/create.volt +++ b/themes/vokuro/profiles/create.volt @@ -3,7 +3,7 @@ {{ flash.output() }}
- {{ link_to("profiles", 'class': 'btn btn-primary', "← Go Back") }} + {{ tag.a("profiles", "← Go Back", ['class': 'btn btn-primary']) }}
@@ -23,7 +23,7 @@
- {{ submit_button("Save", "class": "btn btn-success") }} + {{ tag.inputSubmit("Save", "Save", ["class": "btn btn-success"]) }}
diff --git a/themes/vokuro/profiles/edit.volt b/themes/vokuro/profiles/edit.volt index 85cba66c..164d8597 100644 --- a/themes/vokuro/profiles/edit.volt +++ b/themes/vokuro/profiles/edit.volt @@ -3,16 +3,32 @@ {{ flash.output() }}
- {{ link_to("profiles/index", "← Go Back", "class": "btn btn-warning") }} + {{ tag.a("profiles/index", "← Go Back", ["class": "btn btn-warning"], true) }}
-
+{{ tag.form(["method" :"post"]) }} @@ -52,12 +68,32 @@ {{ user.banned == 'Y' ? 'Yes' : 'No' }} {{ user.suspended == 'Y' ? 'Yes' : 'No' }} {{ user.active == 'Y' ? 'Yes' : 'No' }} - {{ link_to("users/edit/" ~ user.id, ' Edit', "class": "btn btn-sm btn-outline-warning") }} - {{ link_to("users/delete/" ~ user.id, ' Delete', "class": "btn btn-sm btn-outline-danger") }} + + {{ + tag.a( + "users/edit/" ~ user.id, + " Edit", + ["class": "btn btn-sm btn-outline-warning"], + true + ) + }} + + + {{ + tag.a( + "users/delete/" ~ user.id, + " Delete", + ["class": "btn btn-sm btn-outline-danger"], + true + ) + }} + {% else %} - There are no users assigned to this profile + + There are no users assigned to this profile + {% endfor %} @@ -66,5 +102,5 @@ {{ form.render("id") }} - {{ submit_button("Save", "class": "btn btn-success") }} -
+ {{ tag.inputSubmit("Save", "Save", ["class": "btn btn-success"]) }} +{{ tag.close("form") }} diff --git a/themes/vokuro/profiles/search.volt b/themes/vokuro/profiles/search.volt index a08967e4..3bd76811 100644 --- a/themes/vokuro/profiles/search.volt +++ b/themes/vokuro/profiles/search.volt @@ -3,8 +3,8 @@ {{ flash.output() }}
- {{ link_to("profiles/index", "← Go Back", "class": "btn btn-warning") }} - {{ link_to("profiles/create", "Create profiles", "class": "btn btn-primary") }} + {{ tag.a("profiles/index", "← Go Back", ["class": "btn btn-warning"]) }} + {{ tag.a("profiles/create", "Create profiles", ["class": "btn btn-primary"]) }}
@@ -18,14 +18,14 @@ {% for profile in page.items %} - - - + + + {% else %} diff --git a/themes/vokuro/session/forgotPassword.volt b/themes/vokuro/session/forgotPassword.volt index 418b83a6..7633e1cb 100644 --- a/themes/vokuro/session/forgotPassword.volt +++ b/themes/vokuro/session/forgotPassword.volt @@ -11,6 +11,6 @@ {{ form.render('Send') }} -
+
{{ link_to('session/login', "← Back to Login") }} diff --git a/themes/vokuro/terms/index.volt b/themes/vokuro/terms/index.volt index f890d59e..cfdfead0 100644 --- a/themes/vokuro/terms/index.volt +++ b/themes/vokuro/terms/index.volt @@ -1,6 +1,8 @@

Terms

-

Nullam quis risus eget urna mollis ornare vel eu leo. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nullam id dolor id nibh ultricies vehicula ut id elit.

-

Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Duis mollis, est non commodo luctus, nisi erat porttitor ligula, eget lacinia odio sem nec elit. Donec sed odio dui.

+

Nullam quis risus eget urna mollis ornare vel eu leo. Cum sociis natoque penatibus et magnis dis parturient + montes, nascetur ridiculus mus. Nullam id dolor id nibh ultricies vehicula ut id elit.

+

Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Duis mollis, est non commodo luctus, nisi + erat porttitor ligula, eget lacinia odio sem nec elit. Donec sed odio dui.

diff --git a/themes/vokuro/users/edit.volt b/themes/vokuro/users/edit.volt index 33b71c42..d84df670 100644 --- a/themes/vokuro/users/edit.volt +++ b/themes/vokuro/users/edit.volt @@ -9,16 +9,20 @@
{{ profile['id'] }}{{ profile['name'] }}{{ profile['active'] == 'Y' ? 'Yes' : 'No' }}{{ profile.id }}{{ profile.name }}{{ profile.active == 'Y' ? 'Yes' : 'No' }} - {{ link_to("profiles/edit/" ~ profile['id'], ' Edit', "class": "btn btn-sm btn-outline-warning") }} + {{ link_to("profiles/edit/" ~ profile.id, ' Edit', "class": "btn btn-sm btn-outline-warning") }} - {{ link_to("profiles/delete/" ~ profile['id'], ' Delete', "class": "btn btn-sm btn-outline-danger") }} + {{ link_to("profiles/delete/" ~ profile.id, ' Delete', "class": "btn btn-sm btn-outline-danger") }}