diff --git a/.DS_Store b/.DS_Store index de280936a..3cf011a6d 100644 Binary files a/.DS_Store and b/.DS_Store differ diff --git a/.circleci/build.sh b/.circleci/build.sh new file mode 100755 index 000000000..106b5d144 --- /dev/null +++ b/.circleci/build.sh @@ -0,0 +1,20 @@ +#!/usr/bin/env bash +work_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +usage=("" \ +"Usage: $0" \ +" CircleCI needs a primary image with docker-in-docker backend." \ +" To build it use deployment/build.sh script to push to image registry and tag it:" \ +" deployment/images/build.sh secondary betothreeprod/cci-mariadb arm64v8-latest" \ +"Then you can run composition process: sudo docker-compose up --build" \ +"") +[ ! "$(command -v circleci)" ] && curl -fLSs https://circle.ci/cli | bash +# https://github.com/koalaman/shellcheck/wiki/SC2207 +# shellcheck source=../deploy.sh +mapfile -t dock < <(find "${work_dir}/../deployment/images" -name "Dockerfile.x86_64") +[ "$#" -lt 1 ] && printf "Usage: %s " "$0" && exit 0 +for d in "${dock[@]}"; do + dir=$(dirname "$d") + docker_build "$dir" "." "$1/$(basename "$dir")" "$(arch)" +done +sed -e "/custom_checkout:/s/\"\"/\"\/tmp\/_circleci_local_build_repo\"/g" "${work_dir}/config.yml" | circleci config process - > "${work_dir}/config-compat.yml" +circleci local execute -c "${work_dir}/config-compat.yml" || echo -e "${usage[0]}" diff --git a/.circleci/config.yml b/.circleci/config.yml index bbe1ccea4..864df20df 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1,94 +1,128 @@ -# PHP CircleCI 2.0 configuration file -# -# Check https://circleci.com/docs/2.0/language-php/ for more details -# -version: 2 +version: 2.1 +aliases: + - &deps + run: + name: Install dependencies + command: | + git submodule sync + git submodule update --init --recursive + apk update \ + && apk add \ + npm \ + php7-session \ + && apk del build-base \ + && rm -rf /var/cache/apk/* + npm ci + npm link balena-cloud-apps +orbs: + shellcheck: circleci/shellcheck@1.3.16 jobs: build: + docker: + - image: betothreeprod/intel-nuc-node-php7 + - image: betothreeprod/mariadb-intel-nuc + environment: + PUID: 0 + PGID: 0 + TZ: Europe/Paris + MYSQL_ROOT_PASSWORD: mariadb + MYSQL_HOST: localhost + MYSQL_DATABASE: aria_db + MYSQL_USER: maria + MYSQL_PASSWORD: maria-abc + shell: /bin/bash -leo pipefail environment: - DB: Mysql - # a host alias or IP address - MYSQL_SERVICE_HOST: 192.168.99.100 - MYSQL_SERVICE_PORT: 3306 - TEST_MYSQL_SERVICE_HOST: 192.168.99.100 - TEST_MYSQL_SERVICE_PORT: 3306 - DATABASE_NAME: phpcms - DATABASE_SERVICE_NAME: MYSQL - #(optional) - #WEBHOOK_URL: - # Persistent connection credentials - DATABASE_USER: root - # overrides docker-compose-alias.sh -p= - DATABASE_PASSWORD: pdocker - # Just add TEST_DATABASE_USER and TEST_DATABASE_PASSWORD - TEST_DATABASE_USER: ubuntu - # overrides docker-compose-alias.sh -t= - TEST_DATABASE_PASSWORD: ptest - # CakePHP generated - #CAKEPHP_SECRET_TOKEN: - #CAKEPHP_SECRET_SALT: - #CAKEPHP_SECURITY_CIPHER_SEED: - # Generated by ./configure.sh -h - GET_HASH_PASSWORD: ${GET_HASH_PASSWORD} + - BASH_ENV: /etc/profile + - DKR_ARCH: x86_64 + - MYSQL_HOST: 127.0.0.1 + - MYSQL_TCP_PORT: 3306 + working_directory: /var/www/html/ + steps: + - checkout + - restore_cache: + keys: + - v1-dependencies-{{ checksum "package-lock.json" }} + - v1-dependencies-{{ checksum "composer.lock" }} + - setup_remote_docker: + docker_layer_caching: false + - *deps + - save_cache: + key: v1-dependencies-{{ checksum "composer.lock" }} + paths: + - app/Vendor + - webroot/php-cms + - save_cache: + key: v1-dependencies-{{ checksum "package-lock.json" }} + paths: + - $HOME/.npm + - run: + name: Set architecture and Setup Environment Variables + command: | + balena_deploy . $DKR_ARCH --nobuild --exit + - run: + name: Waiting for Mysql to be ready + command: | + set -x + for i in `seq 1 10`; + do + nc -z $MYSQL_HOST $MYSQL_TCP_PORT && echo Success && exit 0 + echo -n . + sleep 1 + done + echo 'Failed waiting for Mysql' && exit 1 + - run: + command: | + set -u + mkdir -p ./app/build/logs + mkdir -p ~/phpunit + ./test-cake.sh --circle + . common.env && cat $MYPHPCMS_DIR/e13/etc/constantes.properties | grep PASSWORD_ADMIN | head -c 18 + when: always + - persist_to_workspace: + root: app/ + paths: + - Config + compose: docker: - # Specify the version you desire here - - image: circleci/php:7.1-node-browsers - environment: - DOCKER_OS_NAME: linux - DOCKER_PHP_VERSION: 7.1 - - # Specify service dependencies here if necessary - # CircleCI maintains a library of pre-built images - # documented at https://circleci.com/docs/2.0/circleci-images/ - # Using the RAM variation mitigates I/O contention - # for database intensive operations. - # - image: circleci/mysql:5.7-ram - - image: circleci/mysql:5.7 - container_name: mysql - environment: - MYSQL_ALLOW_EMPTY_PASSWORD: yes - MYSQL_ROOT_PASSWORD: 'pdocker' - MYSQL_DATABASE: phpcms - + - image: betothreeprod/dind-php7 + shell: /bin/bash -leo pipefail + environment: + - BASH_ENV: /etc/profile + - DKR_ARCH: x86_64 steps: - - checkout - - run: git submodule update --init --recursive - - - run: sudo apt update # PHP CircleCI 2.0 Configuration File# PHP CircleCI 2.0 Configuration File sudo apt install zlib1g-dev libsqlite3-dev - - run: sudo docker-php-ext-install zip - - run: sudo apt-get install mariadb-client - - # Download and cache dependencies - - restore_cache: - keys: - # "composer.lock" can be used if it is committed to the repo - - v1-dependencies-{{ checksum "composer.lock" }} - # fallback to using the latest cache if no exact match is found - - v1-dependencies- - - - run: composer install -n --prefer-dist - - - save_cache: - key: v1-dependencies-{{ checksum "composer.lock" }} - paths: - - ./app/Vendor/ - - - run: ./test-cake.sh -v --docker -p=$DATABASE_PASSWORD -t=$TEST_DATABASE_PASSWORD #| grep Test - # Installing and Using docker-compose - - run: - name: Install Docker Compose - command: | - curl -L https://github.com/docker/compose/releases/download/1.19.0/docker-compose-`uname -s`-`uname -m` > ~/docker-compose - chmod +x ~/docker-compose - sudo mv ~/docker-compose /usr/local/bin/docker-compose - - setup_remote_docker: # (2) - docker_layer_caching: true # (3) - - # use a primary image that already has Docker (recommended) - # build and push Docker image - # (4) - - run: | + - checkout + - attach_workspace: + at: app + - restore_cache: + keys: + - v1-dependencies-{{ checksum "package-lock.json" }} + - v1-dependencies-{{ checksum "composer.lock" }} + - setup_remote_docker: + docker_layer_caching: false + - *deps + - run: + name: Set architecture and Setup Environment Variables + command: | + balena_deploy . $DKR_ARCH --nobuild --exit + - run: + command: | + set -u TAG=0.1.$CIRCLE_BUILD_NUM - ./docker-compose-alias.sh -dns=b23prodtm.info -p=$DATABASE_PASSWORD -t=$TEST_DATABASE_PASSWORD up -d --build - docker login -u $DOCKER_USER -p $DOCKER_PASS - docker push b23dkr/myphpcms:$TAG + docker-compose -f docker-compose.$DKR_ARCH build + - store_test_results: + path: ~/phpunit + - store_artifacts: + path: ~/phpunit +workflows: + cleanup: + jobs: + - shellcheck/check: + ignore: 'SC1091,SC2034,SC2096,SC2038' + build-and-compose: + jobs: + - build + - compose: + requires: + - build + context: Info-b23prodtm + version: 2 diff --git a/.gitignore b/.gitignore index 19e662215..cfd35212d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,8 +1,25 @@ # User specific & automatically generated files # ################################################# -myphpcms*.zip +.env +*.old +*.armhf +*.aarch64 +*.x86_64 +Dockerfile.* +!Dockerfile.template +!Dockerfile.armhf +!Dockerfile.x86_64 +docker-compose.* +!docker-compose.yml +!docker-compose.x86_64 +!docker-compose.armhf +.circleci/config-compat.yml +acake2php*.zip /app/Config/database.php* +!/app/Config/database.php /app/Config/database.sql* +/app/Config/Schema/schema.php* +!/app/Config/Schema/schema.php /app/tmp /app/Vendor/ !/app/Vendor/autoload.php @@ -20,7 +37,13 @@ myphpcms*.zip /dist /tags *.mo -/bin/composer.phar +**/composer*.phar +mysqldb/config/ +mysqldb/conf.d/custom.cnf +node_modules +*.log +etc/apache2/conf.d/site.conf +etc/apache2/conf.d/ssl_site.conf # IDE and editor specific files # ################################# @@ -40,3 +63,5 @@ Icon? ehthumbs.db Thumbs.db /nbproject/private/ +mysqldb/mysqld/ +mysqld/conf.d/custom.cnf diff --git a/.gitmodules b/.gitmodules index 03943ab24..ded62e7ca 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,9 +1,19 @@ +[submodule "app/webroot/php-cms"] + path = app/webroot/php-cms + url = https://bitbucket.org/b23prodtm/php-cms.git +[submodule "python-wifi-connect"] + path = python-wifi-connect + url = https://github.com/b23prodtm/python-wifi-connect.git +[submodule "cakephp"] + path = cakephp + url = git://github.com/cakephp/cakephp.git + branch = 2.x +[submodule "app/Plugin/Datasources"] + path = app/Plugin/Datasources + url = https://github.com/cakephp/datasources.git +[submodule "app/Plugin/UpdateShell"] + path = app/Plugin/UpdateShell + url = https://github.com/b23prodtm/update.git [submodule "app/Plugin/Markdown"] path = app/Plugin/Markdown url = https://github.com/b23prodtm/markdown-plugin.git -[submodule "app/webroot/php_cms"] - path = app/webroot/php_cms - url = https://bitbucket.org/b23prodtm/php-cms.git -[submodule ".travis/TravisCI-OSX-PHP"] - path = .travis/TravisCI-OSX-PHP - url = https://github.com/b23prodtm/TravisCI-OSX-PHP.git diff --git a/.htaccess b/.htaccess deleted file mode 100644 index f13591f2c..000000000 --- a/.htaccess +++ /dev/null @@ -1,8 +0,0 @@ - - RewriteEngine on - # Uncomment if you have a .well-known directory in the root folder, e.g. for the Let's Encrypt challenge - # https://tools.ietf.org/html/rfc5785 - #RewriteRule ^(\.well-known/.*)$ $1 [L] - RewriteRule ^$ app/webroot/ [L] - RewriteRule (.*) app/webroot/$1 [L] - \ No newline at end of file diff --git a/.htaccess b/.htaccess new file mode 120000 index 000000000..f2d12d0b6 --- /dev/null +++ b/.htaccess @@ -0,0 +1 @@ +app/webroot/.htaccess \ No newline at end of file diff --git a/.openshift/cron/weekly/chronograph b/.openshift/cron/weekly/chronograph index 61de949f4..18cf54a42 100755 --- a/.openshift/cron/weekly/chronograph +++ b/.openshift/cron/weekly/chronograph @@ -1,3 +1,3 @@ -#!/bin/bash +#!/usr/bin/env bash echo "`date`: `cat $(dirname \"$0\")/chrono.dat`" diff --git a/.travis.yml b/.travis.yml index e8a8ebc5d..3bc981aa9 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,116 +4,99 @@ cache: - ".autoconf" - "$HOME/.composer/cache/files" # language: php # linux only -language: bash # cross-platform +language: node_js # cross-platform +node_js: + - "14.5" os: - linux - osx - windows -dist: xenial +arch: + - amd64 + - arm64 + +dist: bionic +addons: + mariadb: '10.3' + apt: + sources: + - sourceline: ppa:ondrej/php env: matrix: - - _PHP=latest _PKG=hhvm - - _PHP=7.1 _PKG=php - - _PHP=7.2 _PKG=php - - _PHP=7.3 _PKG=php + - _PHP=7.2 _PKG=php PHPENV_ROOT=~/.phpenv + - _PHP=7.3 _PKG=php PHPENV_ROOT=~/.phpenv + global: - - _SSL=openssl - - DB=Mysql - - PHPUNIT=4 - - PHPCS=3 - - COLLECT_COVERAGE=false - - PHPENV_ROOT=/usr/local/bin/phpenv - - WEBHOOK_URL=https://discordapp.com/api/webhooks/479745392880386058/YOO7Nnn1IFWUtXX0n0qAZYeMDeV-SLa0lSzjGpNnKGTzG-xA0T3dplVGzSM4ObKLeMWg - - secure: C39DQ1zYpSAOy33Sb8NP89o6k4HUnjHnQ+bQkgbo3WH7WtiN76dGeO9jm1DjMn5np6oKbDi41/fxonaTUIjb9YMksG2YB+NBDYXHyV1H7/xAeC6uTxwUObrLXh8aOUwiiuLPllMdtOLX8JSPxl1Ixc6KyeFywPiMvwuOe4QZW6sVG4sqhZC/UUycYKRSMaOthtuTDPYKjBLaDPiEzkUmdBIo9IhAsidEFAHj4jEmw9gBtac0B2x7GbvvoDivdH3KdNSoPt2SkD0RLX51Qf7AYeAV4fw65cuCp/Aat/uk55x3lN5g18Ww9khY/cFSwPC0JXGQnnJvdcDP2diZNkqE41Yc/Mw3xwfrvp3/v8js3VIBzsGINKiSdXZ/yXqI9iRzvzlfmXRHvd4sFXRzUpi8ZB4PXaboMndbNRoh4PcoRNFtXhyebQCEgZv2x3oiKXw38WT5cga03uMH4E5z5afS3n7NP1tsuiNWd499dJzAkW8OPeLDPqY3a/b5qLeZIK1bo23mvCjPtbm+B2g2QocKcd1oQ+XANCyuT3M/+AIypdMabGOSon2fDKrUUN+SqIX4FcYaHi1sG3qUp23870u9YcT4hK2LCKBcBPkFpxqEZLwdHbJmjHPo6uRyAKOD7r/k1DtIRqkcJ+5BpU4emo6rM9rdh5mWjLtK7vdY8Y/tvP8= + - DEBIAN_FRONTEND=noninteractive + - PHPENV_ROOT=/usr/local/bin/phpenv + - _SSL=openssl + - MYPHPCMS_LOG=app/tmp/logs + - WEBHOOK_URL=https://discordapp.com/api/webhooks/479745392880386058/YOO7Nnn1IFWUtXX0n0qAZYeMDeV-SLa0lSzjGpNnKGTzG-xA0T3dplVGzSM4ObKLeMWg + - secure: C39DQ1zYpSAOy33Sb8NP89o6k4HUnjHnQ+bQkgbo3WH7WtiN76dGeO9jm1DjMn5np6oKbDi41/fxonaTUIjb9YMksG2YB+NBDYXHyV1H7/xAeC6uTxwUObrLXh8aOUwiiuLPllMdtOLX8JSPxl1Ixc6KyeFywPiMvwuOe4QZW6sVG4sqhZC/UUycYKRSMaOthtuTDPYKjBLaDPiEzkUmdBIo9IhAsidEFAHj4jEmw9gBtac0B2x7GbvvoDivdH3KdNSoPt2SkD0RLX51Qf7AYeAV4fw65cuCp/Aat/uk55x3lN5g18Ww9khY/cFSwPC0JXGQnnJvdcDP2diZNkqE41Yc/Mw3xwfrvp3/v8js3VIBzsGINKiSdXZ/yXqI9iRzvzlfmXRHvd4sFXRzUpi8ZB4PXaboMndbNRoh4PcoRNFtXhyebQCEgZv2x3oiKXw38WT5cga03uMH4E5z5afS3n7NP1tsuiNWd499dJzAkW8OPeLDPqY3a/b5qLeZIK1bo23mvCjPtbm+B2g2QocKcd1oQ+XANCyuT3M/+AIypdMabGOSon2fDKrUUN+SqIX4FcYaHi1sG3qUp23870u9YcT4hK2LCKBcBPkFpxqEZLwdHbJmjHPo6uRyAKOD7r/k1DtIRqkcJ+5BpU4emo6rM9rdh5mWjLtK7vdY8Y/tvP8= matrix: - fast_finish: true - exclude: - - os: windows - - os: linux + #fast_finish: true include: - os: linux - language: php - php: 7.1 - env: _PHP=7.1 _PKG=php PHPENV_ROOT=~/.phpenv - - os: linux - language: php - php: 'hhvm' - env: _PHP=latest _PKG=hhvm PHPENV_ROOT=~/.phpenv + arch: arm64 - os: osx + arch: amd64 - os: windows - env: _PHP=7.3 _PKG=php _SSL=openssl.light - - os: windows - env: _PHP=latest _PKG=hhvm _SSL=openssl.light + arch: amd64 allow_failures: - - php: 'hhvm' - - env: _PHP=latest _PKG=hhvm - - env: _PHP=7.3 _PKG=php + - os: linux + arch: arm64 + - os: osx - os: windows -addons: - coverity_scan: - project: - name: b23prodtm/myphpcms - description: 'This PHP CMS is featuring well-known functionalities as cool as - posting some web contents with pictures stored in a database. Developer Note - : This is the Cake PHP cartridge repository. A submodule is included in app/webroot.' - notification_email: b23prodtm@users.sourceforge.net - build_command_prepend: ./configure.sh "-c" "-h" "-p" "pass" "-s" "word" "--mig-database" - "-y" && .travis/configure.sh - build_command: "./test-cake.sh --cov | grep Test" - branch_pattern: coverity_scan - apt: - packages: - - php7.0 - - php7.0-xml - - hhvm - update: true - services: +- mysql +- docker - memcached before_install: - cd .travis/TravisCI-OSX-PHP - source build/phpenv_install.sh - source build/prepare_${TRAVIS_OS_NAME}_env.sh #; source exports - - if [[ "${TRAVIS_OS_NAME}" == "linux" && "${_PHP}" == 7* ]]; then COLLECT_COVERAGE=true ; fi - - if [[ "${TRAVIS_OS_NAME}" == "linux" && "${COLLECT_COVERAGE}" != "true" ]]; then phpenv config-rm xdebug.ini || true ; fi - - if [ ! -z "${ADDITIONAL_PHP_INI}" ]; then source build/custom_php_ini.sh; fi - - if [[ "${TRAVIS_OS_NAME}" == "linux" && "${COLLECT_COVERAGE}" != "true" ]]; then echo -n | openssl s_client -connect https://scan.coverity.com:443 | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' | sudo tee -a /etc/ssl/certs/ca-; fi + - if [[ "${TRAVIS_OS_NAME}" = "linux" && "${_PHP}" = 7* ]]; then COLLECT_COVERAGE=true ; fi + - if [[ "${TRAVIS_OS_NAME}" = "linux" && "${COLLECT_COVERAGE}" != "true" ]]; then phpenv config-rm xdebug.ini || true ; fi + - if [ ! -z "${ADDITIONAL_PHP_INI}" ]; then build/custom_php_ini.sh; fi + - build/handle_${TRAVIS_OS_NAME}_pkg.sh "${_SSL}" "latest"; + - if [[ "${TRAVIS_OS_NAME}" != "windows" ]]; then [ $(which c_rehash) > /dev/null ] && sudo c_rehash; fi + - build/handle_${TRAVIS_OS_NAME}_pkg.sh "curl" "latest" "--with-openssl" | tail + - build/handle_${TRAVIS_OS_NAME}_pkg.sh "${_PKG}" "${_PHP}" "--with-homebrew-curl" + - build/handle_${TRAVIS_OS_NAME}_pkg.sh "${_PKG}" "${_PHP}-xml" | tail + - build/handle_${TRAVIS_OS_NAME}_pkg.sh "${_PKG}" "${_PHP}-fpm" | tail + - php -i | grep "SSL Version" + - build/handle_${TRAVIS_OS_NAME}_pkg.sh "composer" "latest" | tail - cd ../.. - - source ./Scripts/configure_tmp.sh + #- docker login -u $DOCKER_USER -p $DOCKER_PASS + - sudo mkdir -p /etc/mysql/conf.d/ && sudo cp -f mysqldb/conf.d/my.cnf /etc/mysql/conf.d/my.cnf + - sudo sed -i.bind "/bind-address/s/=.*$/= ${MYSQL_BIND_ADDRESS:-127.0.0.1}/" /etc/mysql/conf.d/my.cnf + - if [[ "${TRAVIS_OS_NAME}" = "linux" ]]; then sudo systemctl restart mysql; fi + - npm install --no-optional + - npm link balena-cloud install: - - cd .travis/TravisCI-OSX-PHP - - if [[ "${TRAVIS_OS_NAME}" != "linux" ]]; then build/handle_${TRAVIS_OS_NAME}_pkg.sh "${_SSL}"; /usr/local/opt/openssl/bin/c_rehash; fi - - if [[ "${TRAVIS_OS_NAME}" != "linux" ]]; then build/handle_${TRAVIS_OS_NAME}_pkg.sh "${_PKG}" "${_PHP}" "--with-openssl"; fi - - if [[ "${TRAVIS_OS_NAME}" != "linux" ]]; then build/handle_${TRAVIS_OS_NAME}_pkg.sh "composer"; bash -c 'composer install --dev --no-interaction'; fi - - cd ../.. - - if [[ "${TRAVIS_OS_NAME}" == "linux" ]]; then curl -s http://getcomposer.org/installer | php && php composer.phar install --dev --no-interaction; fi + - ./deploy.sh "$(arch)" --nobuild --exit before_script: -- if [[ "${TRAVIS_OS_NAME}" == "linux" && "${_PHP}" == "hhvm" ]]; then curl -sSfL -o ~/.phpenv/versions/hhvm/bin/phpunit https://phar.phpunit.de/phpunit-5.7.phar; fi -- mkdir -p build/logs - + - mkdir -p ${MYPHPCMS_LOG} script: -- if [ "${COVERITY_SCAN_BRANCH}" != 1 ]; then ./test-cake.sh --travis | grep Test; fi -after_script: -- if [[ ("${COLLECT_COVERAGE}" == "true") && ("${COVERITY_SCAN_BRANCH}" != 1) ]]; - then travis_retry php app/vendor/bin/php-coveralls -v -r ./app/; fi + - if [[ "${TRAVIS_OS_NAME}" != "linux" ]]; then ./test-cake.sh --travis --phpcs || true; fi + - if [[ "${TRAVIS_OS_NAME}" = "linux" ]]; then ./test-cake.sh --travis; fi + - cat "${MYPHPCMS_LOG}/travis.${TRAVIS_BUILD_NUMBER}.log" || true after_success: -- wget https://raw.githubusercontent.com/k3rn31p4nic/travis-ci-discord-webhook/master/send.sh -- chmod +x send.sh -- "./send.sh success $WEBHOOK_URL" -- zip -r myphpcms.zip * -- git tag --force "v${GIT_RELEASE_VERSION}.${TRAVIS_BUILD_NUMBER}" + - ./discord.sh success "$WEBHOOK_URL" + - zip -r acake2php.zip * > /dev/null + - git tag --force "${GIT_RELEASE_VERSION}.${TRAVIS_BUILD_NUMBER}" deploy: provider: releases api_key: secure: UmXoq0sFQQixpMH12MG1Q3+pQhw05SuN919FgnKCru3X3RTCpXnZB8hgXvQHZn5Hhunq5eBPZ7C/bvk5wkzPXrwpAXyA7wj7PhGn6QbksU6xtkNOQVera/pMoTJW2VtNA2GcWvUvCnht3m73Tp2lguaI3Q6Yt8qq1vHJlDO5hbgvC0LdDrRFLIAA95jA9DWZRCWanHV5aepVNkX0qjQm25BIAwvQtfxkj/DipDYy2eIMh8brh6aZamE3cBv8sXP8b2b89GB670E35Otfseu58a6HxqmLD4dI5kIEzhSFjuelPJne0tmebFKww+mPn7v2SKJZR9xVfQM+mZHAp7SiozEvi1nqhUN31Z64mpDQDPnAB6eO36rGSdxDyYN7Ab24lJuLTcNkRbNOaJzn88q9d5DqGGQRJl6875cJmPFOjUwNteJIvLhDmPX3oHSPvWx3AtpEUtWeCrVt1yc7tyG0kdW8MmzoWvgDhbyvqAefKO3bEzVZeQQy/7LKy1i42+B/7N57oR6sgFX2N/zvdckFKjwHNiydds67Wj++EuJRXr2AhxdraW3iwDBTmkrZ3TjOsxcySbMBJHCOwHF9yAmLklbk4h1haCohkQrQxBp6Rhm3vKJGDOR3rOkjqIzqgHgo3pcXDdBULMpfB3/IbDeh3/RMuTEOXvv7FUNRjb4JIdI= - file: myphpcms.zip + file: acake2php.zip on: - repo: b23prodtm/myphpcms + repo: b23prodtm/acake2php branch: feature/gh-releases diff --git a/.travis/TravisCI-OSX-PHP b/.travis/TravisCI-OSX-PHP deleted file mode 160000 index 94c5f2272..000000000 --- a/.travis/TravisCI-OSX-PHP +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 94c5f2272a56c81152c8a7c02d0ff18690eb16cb diff --git a/.travis/configure.sh b/.travis/configure.sh deleted file mode 100755 index 28d73c93f..000000000 --- a/.travis/configure.sh +++ /dev/null @@ -1,135 +0,0 @@ -#!/usr/bin/env bash -echo -e " -Set of default environment -========================== - Find exports for local development phase (testing) only in './Scripts/bootargs.sh') - "; -echo -e " -Documented VARIABLES in .travis.yml - TRAVIS_OS_NAME: os: ['osx','linux'] - TRAVIS_PHP_VERSION : php: - DB=['Mysql', 'Pgsql', 'Sqlite'] - -Required VARIABLES in .travis.yml or Pod environment - DATABASE_USER: - DATABASE_PASSWORD: - TEST_DATABASE_USER: - TEST_DATABASE_PASSWORD: - if [ DB='Mysql' ]; then - TEST_MYSQL_SERVICE_HOST: - else if [ DB='Postgres' ]; then - TEST_POSTGRES_SERVICE_HOST: - fi -optional environment VARIABLES in .travis.yml - ADDITIONAL_PHP_INI='path to a php.ini settings file' -========================== -"; -[ ! -z $TEST_DATABASE_USER ] && [ ! -z $TEST_DATABASE_PASSWORD ] && [[ (! -z $TEST_MYSQL_SERVICE_HOST) || (! -z $TEST_PGSQL_SERVICE_HOST) ]] || echo "Missing VARIABLES. Please review your settings !" -if [ ! -z "${ADDITIONAL_PHP_INI}" ]; then /usr/bin/env bash .travis/TravisCI-OSX-PHP/build/custom_php_ini.sh; fi -mkdir -p build/logs -echo -e "Database Unit Tests... DB=${DB}" -if [[ "${TRAVIS_OS_NAME}" == "linux" ]]; then - if [[ ${TRAVIS_PHP_VERSION:0:3} == "7.2" ]]; then - pear config-set preferred_state snapshot && yes "" | pecl install mcrypt ; - fi - sudo locale-gen de_DE - sudo locale-gen es_ES -fi -if [[ ${DB} == 'Mysql' ]]; then mysql -v -e 'CREATE DATABASE IF NOT EXISTS cakephp_test;' -u ${DATABASE_USER} --password=${DATABASE_PASSWORD}; fi -if [[ ${DB} == 'Mysql' ]]; then mysql -v -e 'CREATE DATABASE IF NOT EXISTS cakephp_test2;' -u ${DATABASE_USER} --password=${DATABASE_PASSWORD}; fi -if [[ ${DB} == 'Mysql' ]]; then mysql -v -e 'CREATE DATABASE IF NOT EXISTS cakephp_test3;' -u ${DATABASE_USER} --password=${DATABASE_PASSWORD}; fi -if [[ ${DB} == 'Pgsql' ]]; then psql -c 'CREATE DATABASE cakephp_test;' -U postgres; fi -if [[ ${DB} == 'Pgsql' ]]; then psql -c 'CREATE SCHEMA test2;' -U postgres -d cakephp_test; fi -if [[ ${DB} == 'Pgsql' ]]; then psql -c 'CREATE SCHEMA test3;' -U postgres -d cakephp_test; fi -chmod -R 777 ./app/tmp -if [[ ("${TRAVIS_OS_NAME}" == "linux") && (${TRAVIS_PHP_VERSION:0:3} == "5.3") ]] ; then pecl install timezonedb ; fi -if [[ "${TRAVIS_OS_NAME}" == "linux" ]]; then - echo "extension = memcached.so" >> ~/.phpenv/versions/$(phpenv version-name)/etc/php.ini - if [[ ${TRAVIS_PHP_VERSION:0:1} == "7" ]] ; then echo "yes" | pecl install apcu-5.1.3 || true; fi - if [[ ${TRAVIS_PHP_VERSION:0:1} == "5" ]] ; then echo "yes" | pecl install apcu-4.0.11 || true; fi - echo -e "extension = apcu.so\napc.enable_cli=1" >> ~/.phpenv/versions/$(phpenv version-name)/etc/php.ini - phpenv rehash -fi -set +H -echo " array( - 'datasource' => 'Database/MysqlCms', - 'host' => '${TEST_MYSQL_SERVICE_HOST}', - 'login' => '${TEST_DATABASE_USER}', - 'password' => '${TEST_DATABASE_PASSWORD}' - ), - 'Pgsql' => array( - 'datasource' => 'Database/PostgresCms', - 'host' => '${TEST_PGSQL_SERVICE_HOST}', - 'login' => '${TEST_DATABASE_USER}', - 'database' => 'cakephp_test', - 'schema' => array( - 'default' => 'public', - 'test' => 'public', - 'test2' => 'test2', - 'test_database_three' => 'test3' - ) - ), - 'Sqlite' => array( - 'datasource' => 'Database/SqliteCms', - 'database' => array( - 'default' => ':memory:', - 'test' => ':memory:', - 'test2' => '/tmp/cakephp_test2.db', - 'test_database_three' => '/tmp/cakephp_test3.db' - ), - ) - ); - public \$default = array( - 'persistent' => false, - 'host' => '', - 'login' => '', - 'password' => '', - 'database' => 'cakephp_test', - 'prefix' => '' - ); - public \$test = array( - 'persistent' => false, - 'host' => '', - 'login' => '', - 'password' => '', - 'database' => 'cakephp_test', - 'prefix' => '' - ); - public \$test2 = array( - 'persistent' => false, - 'host' => '', - 'login' => '', - 'password' => '', - 'database' => 'cakephp_test2', - 'prefix' => '' - ); - public \$test_database_three = array( - 'persistent' => false, - 'host' => '', - 'login' => '', - 'password' => '', - 'database' => 'cakephp_test3', - 'prefix' => '' - ); - public function __construct() { - \$db = 'Mysql'; - if (!empty(\$_SERVER['DB'])) { - \$db = \$_SERVER['DB']; - } - foreach (array('default', 'test', 'test2', 'test_database_three') as \$source) { - \$config = array_merge(\$this->{\$source}, \$this->identities[\$db]); - if (is_array(\$config['database'])) { - \$config['database'] = \$config['database'][\$source]; - } - if (!empty(\$config['schema']) && is_array(\$config['schema'])) { - \$config['schema'] = \$config['schema'][\$source]; - } - \$this->{\$source} = \$config; - } - } - }" > app/Config/database.php - echo -e "${green}Unit Test was set up in app/Config/database.php${nc}" diff --git a/Dockerfile.armhf b/Dockerfile.armhf new file mode 100644 index 000000000..67a1d36c1 --- /dev/null +++ b/Dockerfile.armhf @@ -0,0 +1,137 @@ +# THIS file was generated for $DKR_ARCH raspberrypi3 +# Make changes to the Dockefile.template +# Docker architecture (x86_64, armhf, aarch64 ) +ARG IMG_TAG +ARG DKR_ARCH +ARG PRIMARY_HUB +# Primary image is a Linux PHP with Apache 2 server pre-installed +FROM ${PRIMARY_HUB:-betothreeprod/apache-php7}:${IMG_TAG:-latest}-${DKR_ARCH:-armhf} + +ENV INITSYSTEM off +ENV UDEV off +# ---------------------- +# About Dockerfile ARGS: +# ALL the following ARGS are DUPLICATED in common.env and $DKR_ARCH.env +# and Scripts/fooargs.sh for development phase. +# If not set in common.env, it must be set in the host machine environment +# when ./start.sh or ./test.sh or in development phase. +# ---------------------- +# Values in default (no-arg) production mode +# May be overriden in docker-compose.yml +#----------------------- +ARG CAKEPHP_DEBUG_LEVEL +ENV CAKEPHP_DEBUG_LEVEL ${CAKEPHP_DEBUG_LEVEL:-2} +ENV BALENA_MACHINE_NAME ${BALENA_MACHINE_NAME:-raspberrypi3} +ARG SECONDARY_HUB +ENV SECONDARY_HUB ${SECONDARY_HUB:-betothreeprod/mariadb-raspberrypi3} +ENV DKR_ARCH ${DKR_ARCH:-armhf} +ARG COLLECT_COVERAGE +ENV COLLECT_COVERAGE ${COLLECT_COVERAGE:-'False'} +ARG DB +ENV DB ${DB:-Mysql} +ARG MYSQL_HOST +ENV MYSQL_HOST ${MYSQL_HOST:-db} +ARG MYSQL_TCP_PORT +ENV MYSQL_TCP_PORT ${MYSQL_TCP_PORT:-3306} +ARG MYPHPCMS_DIR +ENV MYPHPCMS_DIR ${MYPHPCMS_DIR:-'app/webroot/php-cms'} +ARG MYPHPCMS_LOG +ENV MYPHPCMS_LOG ${MYPHPCMS_LOG:-'app/tmp/logs'} +ARG DATABASE_USER +ENV DATABASE_USER ${DATABASE_USER:-'root'} +ARG MYSQL_DATABASE +ENV MYSQL_DATABASE ${MYSQL_DATABASE:-'aria_db'} +ARG MYSQL_ROOT_PASSWORD +ENV MYSQL_ROOT_PASSWORD ${MYSQL_ROOT_PASSWORD:-'mariadb'} +ARG TEST_DATABASE_NAME +ENV TEST_DATABASE_NAME ${TEST_DATABASE_NAME:-'test'} +ARG MYSQL_USER +ENV MYSQL_USER ${MYSQL_USER:-'maria'} +ARG MYSQL_PASSWORD +ENV MYSQL_PASSWORD ${MYSQL_PASSWORD:-'maria-abc'} +ARG SERVER_NAME +ENV SERVER_NAME ${SERVER_NAME:-'acake2php.local'} +# Change uid and gid of apache to docker user uid/gid +ARG PUID +ENV PUID ${PUID:-0} +ARG PGID +ENV PGID ${PGID:-0} +# Must own the ip address +ARG HTTPD_LISTEN +ENV HTTPD_LISTEN ${HTTPD_LISTEN:-'*:80'} +ARG SSL_PORT +ENV SSL_PORT ${SSL_PORT:-'443'} +ARG HTTPD_LISTEN_SSL +ENV HTTPD_LISTEN_SSL ${HTTPD_LISTEN_SSL:-'*:443'} +# Enable migrate-database.sh options +ARG MIGRATE_OPTION +ENV MIGRATE_OPTION ${MIGRATE_OPTION:-'-v'} + +# Use the default production configuration +#COPY $PHP_INI_DIR/php.ini-production $PHP_INI_DIR/php.ini +RUN [ "cross-build-start" ] +RUN install_packages \ + git \ + openssh-client \ + tar \ + gzip \ + ca-certificates \ + zip \ + unzip \ + mariadb-client + +RUN install_packages \ + memcached \ + libmemcached-dev \ + php7-pecl-xdebug \ + gettext + # libicu libicu-dev + +WORKDIR /usr/src/ + +COPY vagrant-shell.sh . +RUN chmod 0755 vagrant-shell.sh +RUN ./vagrant-shell.sh php-settings-update extension memcached.so \ + && ./vagrant-shell.sh php-settings-update session.save_handler memcached \ + && ./vagrant-shell.sh php-settings-update session.save_path '127.0.0.1:11211,127.0.0.1:11212' + +WORKDIR /var/www/localhost/htdocs/ + +# Copy the app source code inside the image +COPY app app + +COPY package.json . +COPY package-lock.json . + +# Helper packages (just a long node process...) +RUN npm install --no-optional && npm link balena-cloud + +# Add cake and composer command to system path +COPY composer.json . +COPY composer.lock . +ENV PATH "${PATH}:/var/www/localhost/htdocs/app/Console" +ENV PATH "${PATH}:/var/www/localhost/htdocs/app/Vendor/bin" + +# Configure the application +WORKDIR /var/www/localhost/htdocs/ + +# Copy the scripts code inside the image +COPY . . + +# Change mode of bash Scripts +RUN chmod -R gu+xs deploy.sh configure.sh migrate-database.sh Scripts/ + +# Password Hash Verbose +# RUN cat app/webroot/php-cms/e13/etc/export_hash_password.sh | awk -F= '{print $2}' | tail -n 1 + +# just containers configuration +COPY etc /etc +RUN chmod 0755 *.sh +RUN ./deploy.sh ${DKR_ARCH} --nobuild --exit \ + && ./configure.sh --openshift -a -m -c -h -p pass -s word --development + +RUN [ "cross-build-end" ] + +ENTRYPOINT ./migrate-database.sh -o -u -i ${MIGRATE_OPTION} \ + && ./migrate-database.sh -o -u ${MIGRATE_OPTION} --connection=test && /init +EXPOSE 80 443 diff --git a/Dockerfile.template b/Dockerfile.template new file mode 100644 index 000000000..bb4feec38 --- /dev/null +++ b/Dockerfile.template @@ -0,0 +1,137 @@ +# THIS file was generated for $DKR_ARCH %%BALENA_MACHINE_NAME%% +# Make changes to the Dockefile.template +# Docker architecture (x86_64, armhf, aarch64 ) +ARG IMG_TAG +ARG DKR_ARCH +ARG PRIMARY_HUB +# Primary image is a Linux PHP with Apache 2 server pre-installed +FROM ${PRIMARY_HUB:-betothreeprod/apache-php7}:${IMG_TAG:-latest}-${DKR_ARCH:-%%BALENA_ARCH%%} + +ENV INITSYSTEM off +ENV UDEV off +# ---------------------- +# About Dockerfile ARGS: +# ALL the following ARGS are DUPLICATED in common.env and $DKR_ARCH.env +# and Scripts/fooargs.sh for development phase. +# If not set in common.env, it must be set in the host machine environment +# when ./start.sh or ./test.sh or in development phase. +# ---------------------- +# Values in default (no-arg) production mode +# May be overriden in docker-compose.yml +#----------------------- +ARG CAKEPHP_DEBUG_LEVEL +ENV CAKEPHP_DEBUG_LEVEL ${CAKEPHP_DEBUG_LEVEL:-2} +ENV BALENA_MACHINE_NAME ${BALENA_MACHINE_NAME:-%%BALENA_MACHINE_NAME%%} +ARG SECONDARY_HUB +ENV SECONDARY_HUB ${SECONDARY_HUB:-'linuxserver/mariadb'} +ENV DKR_ARCH ${DKR_ARCH:-%%BALENA_ARCH%%} +ARG COLLECT_COVERAGE +ENV COLLECT_COVERAGE ${COLLECT_COVERAGE:-'False'} +ARG DB +ENV DB ${DB:-Mysql} +ARG MYSQL_HOST +ENV MYSQL_HOST ${MYSQL_HOST:-db} +ARG MYSQL_TCP_PORT +ENV MYSQL_TCP_PORT ${MYSQL_TCP_PORT:-3306} +ARG MYPHPCMS_DIR +ENV MYPHPCMS_DIR ${MYPHPCMS_DIR:-'app/webroot/php-cms'} +ARG MYPHPCMS_LOG +ENV MYPHPCMS_LOG ${MYPHPCMS_LOG:-'app/tmp/logs'} +ARG DATABASE_USER +ENV DATABASE_USER ${DATABASE_USER:-'root'} +ARG MYSQL_DATABASE +ENV MYSQL_DATABASE ${MYSQL_DATABASE:-'aria_db'} +ARG MYSQL_ROOT_PASSWORD +ENV MYSQL_ROOT_PASSWORD ${MYSQL_ROOT_PASSWORD:-'mariadb'} +ARG TEST_DATABASE_NAME +ENV TEST_DATABASE_NAME ${TEST_DATABASE_NAME:-'test'} +ARG MYSQL_USER +ENV MYSQL_USER ${MYSQL_USER:-'maria'} +ARG MYSQL_PASSWORD +ENV MYSQL_PASSWORD ${MYSQL_PASSWORD:-'maria-abc'} +ARG SERVER_NAME +ENV SERVER_NAME ${SERVER_NAME:-'acake2php.local'} +# Change uid and gid of apache to docker user uid/gid +ARG PUID +ENV PUID ${PUID:-0} +ARG PGID +ENV PGID ${PGID:-0} +# Must own the ip address +ARG HTTPD_LISTEN +ENV HTTPD_LISTEN ${HTTPD_LISTEN:-'*:80'} +ARG SSL_PORT +ENV SSL_PORT ${SSL_PORT:-'443'} +ARG HTTPD_LISTEN_SSL +ENV HTTPD_LISTEN_SSL ${HTTPD_LISTEN_SSL:-'*:443'} +# Enable migrate-database.sh options +ARG MIGRATE_OPTION +ENV MIGRATE_OPTION ${MIGRATE_OPTION:-'-v'} + +# Use the default production configuration +#COPY $PHP_INI_DIR/php.ini-production $PHP_INI_DIR/php.ini +# RUN [ "cross-build-start" ] +RUN install_packages \ + git \ + openssh-client \ + tar \ + gzip \ + ca-certificates \ + zip \ + unzip \ + mariadb-client + +RUN install_packages \ + memcached \ + libmemcached-dev \ + php7-pecl-xdebug \ + gettext + # libicu libicu-dev + +WORKDIR /usr/src/ + +COPY vagrant-shell.sh . +RUN chmod 0755 vagrant-shell.sh +RUN ./vagrant-shell.sh php-settings-update extension memcached.so \ + && ./vagrant-shell.sh php-settings-update session.save_handler memcached \ + && ./vagrant-shell.sh php-settings-update session.save_path '127.0.0.1:11211,127.0.0.1:11212' + +WORKDIR /var/www/localhost/htdocs/ + +# Copy the app source code inside the image +COPY app app + +COPY package.json . +COPY package-lock.json . + +# Helper packages (just a long node process...) +RUN npm install --no-optional && npm link balena-cloud + +# Add cake and composer command to system path +COPY composer.json . +COPY composer.lock . +ENV PATH "${PATH}:/var/www/localhost/htdocs/app/Console" +ENV PATH "${PATH}:/var/www/localhost/htdocs/app/Vendor/bin" + +# Configure the application +WORKDIR /var/www/localhost/htdocs/ + +# Copy the scripts code inside the image +COPY . . + +# Change mode of bash Scripts +RUN chmod -R gu+xs deploy.sh configure.sh migrate-database.sh Scripts/ + +# Password Hash Verbose +# RUN cat app/webroot/php-cms/e13/etc/export_hash_password.sh | awk -F= '{print $2}' | tail -n 1 + +# just containers configuration +COPY etc /etc +RUN chmod 0755 *.sh +RUN ./deploy.sh ${DKR_ARCH} --nobuild --exit \ + && ./configure.sh --openshift -a -m -c -h -p pass -s word --development + +# RUN [ "cross-build-end" ] + +ENTRYPOINT ./migrate-database.sh -o -u -i ${MIGRATE_OPTION} \ + && ./migrate-database.sh -o -u ${MIGRATE_OPTION} --connection=test && /init +EXPOSE 80 443 diff --git a/Dockerfile.x86_64 b/Dockerfile.x86_64 new file mode 100644 index 000000000..12a7e9909 --- /dev/null +++ b/Dockerfile.x86_64 @@ -0,0 +1,137 @@ +# THIS file was generated for $DKR_ARCH intel-nuc +# Make changes to the Dockefile.template +# Docker architecture (x86_64, armhf, aarch64 ) +ARG IMG_TAG +ARG DKR_ARCH +ARG PRIMARY_HUB +# Primary image is a Linux PHP with Apache 2 server pre-installed +FROM ${PRIMARY_HUB:-betothreeprod/apache-php7}:${IMG_TAG:-latest}-${DKR_ARCH:-x86_64} + +ENV INITSYSTEM off +ENV UDEV off +# ---------------------- +# About Dockerfile ARGS: +# ALL the following ARGS are DUPLICATED in common.env and $DKR_ARCH.env +# and Scripts/fooargs.sh for development phase. +# If not set in common.env, it must be set in the host machine environment +# when ./start.sh or ./test.sh or in development phase. +# ---------------------- +# Values in default (no-arg) production mode +# May be overriden in docker-compose.yml +#----------------------- +ARG CAKEPHP_DEBUG_LEVEL +ENV CAKEPHP_DEBUG_LEVEL ${CAKEPHP_DEBUG_LEVEL:-2} +ENV BALENA_MACHINE_NAME ${BALENA_MACHINE_NAME:-intel-nuc} +ARG SECONDARY_HUB +ENV SECONDARY_HUB ${SECONDARY_HUB:-betothreeprod/mariadb-intel-nuc} +ENV DKR_ARCH ${DKR_ARCH:-x86_64} +ARG COLLECT_COVERAGE +ENV COLLECT_COVERAGE ${COLLECT_COVERAGE:-'False'} +ARG DB +ENV DB ${DB:-Mysql} +ARG MYSQL_HOST +ENV MYSQL_HOST ${MYSQL_HOST:-db} +ARG MYSQL_TCP_PORT +ENV MYSQL_TCP_PORT ${MYSQL_TCP_PORT:-3306} +ARG MYPHPCMS_DIR +ENV MYPHPCMS_DIR ${MYPHPCMS_DIR:-'app/webroot/php-cms'} +ARG MYPHPCMS_LOG +ENV MYPHPCMS_LOG ${MYPHPCMS_LOG:-'app/tmp/logs'} +ARG DATABASE_USER +ENV DATABASE_USER ${DATABASE_USER:-'root'} +ARG MYSQL_DATABASE +ENV MYSQL_DATABASE ${MYSQL_DATABASE:-'aria_db'} +ARG MYSQL_ROOT_PASSWORD +ENV MYSQL_ROOT_PASSWORD ${MYSQL_ROOT_PASSWORD:-'mariadb'} +ARG TEST_DATABASE_NAME +ENV TEST_DATABASE_NAME ${TEST_DATABASE_NAME:-'test'} +ARG MYSQL_USER +ENV MYSQL_USER ${MYSQL_USER:-'maria'} +ARG MYSQL_PASSWORD +ENV MYSQL_PASSWORD ${MYSQL_PASSWORD:-'maria-abc'} +ARG SERVER_NAME +ENV SERVER_NAME ${SERVER_NAME:-'acake2php.local'} +# Change uid and gid of apache to docker user uid/gid +ARG PUID +ENV PUID ${PUID:-0} +ARG PGID +ENV PGID ${PGID:-0} +# Must own the ip address +ARG HTTPD_LISTEN +ENV HTTPD_LISTEN ${HTTPD_LISTEN:-'*:80'} +ARG SSL_PORT +ENV SSL_PORT ${SSL_PORT:-'443'} +ARG HTTPD_LISTEN_SSL +ENV HTTPD_LISTEN_SSL ${HTTPD_LISTEN_SSL:-'*:443'} +# Enable migrate-database.sh options +ARG MIGRATE_OPTION +ENV MIGRATE_OPTION ${MIGRATE_OPTION:-'-v'} + +# Use the default production configuration +#COPY $PHP_INI_DIR/php.ini-production $PHP_INI_DIR/php.ini +# RUN [ "cross-build-start" ] +RUN install_packages \ + git \ + openssh-client \ + tar \ + gzip \ + ca-certificates \ + zip \ + unzip \ + mariadb-client + +RUN install_packages \ + memcached \ + libmemcached-dev \ + php7-pecl-xdebug \ + gettext + # libicu libicu-dev + +WORKDIR /usr/src/ + +COPY vagrant-shell.sh . +RUN chmod 0755 vagrant-shell.sh +RUN ./vagrant-shell.sh php-settings-update extension memcached.so \ + && ./vagrant-shell.sh php-settings-update session.save_handler memcached \ + && ./vagrant-shell.sh php-settings-update session.save_path '127.0.0.1:11211,127.0.0.1:11212' + +WORKDIR /var/www/localhost/htdocs/ + +# Copy the app source code inside the image +COPY app app + +COPY package.json . +COPY package-lock.json . + +# Helper packages (just a long node process...) +RUN npm install --no-optional && npm link balena-cloud + +# Add cake and composer command to system path +COPY composer.json . +COPY composer.lock . +ENV PATH "${PATH}:/var/www/localhost/htdocs/app/Console" +ENV PATH "${PATH}:/var/www/localhost/htdocs/app/Vendor/bin" + +# Configure the application +WORKDIR /var/www/localhost/htdocs/ + +# Copy the scripts code inside the image +COPY . . + +# Change mode of bash Scripts +RUN chmod -R gu+xs deploy.sh configure.sh migrate-database.sh Scripts/ + +# Password Hash Verbose +# RUN cat app/webroot/php-cms/e13/etc/export_hash_password.sh | awk -F= '{print $2}' | tail -n 1 + +# just containers configuration +COPY etc /etc +RUN chmod 0755 *.sh +RUN ./deploy.sh ${DKR_ARCH} --nobuild --exit \ + && ./configure.sh --openshift -a -m -c -h -p pass -s word --development + +# RUN [ "cross-build-end" ] + +ENTRYPOINT ./migrate-database.sh -o -u -i ${MIGRATE_OPTION} \ + && ./migrate-database.sh -o -u ${MIGRATE_OPTION} --connection=test && /init +EXPOSE 80 443 diff --git a/INSTALL.md b/INSTALL.md index 91816be75..18e698fc9 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -1,46 +1,108 @@ -# INSTALLATION -Docker :whale: is able to use web server containers in local (VM/Vbox) or remote (Cloud) machine cluster (Kubernetes). +## Build the virtual machine (VM) +Docker :whale: is able to use web server containers in local VM or a remote cluster. A typical install script could look like the following script, for instance edit a file : - #!/usr/bin/env bash + #!/usr/bin/env bash + set -u + export PATH="node_modules/.bin:$PATH" + cd acake2php + git clone https://github.com/b23prodtm/acake2php.git + git submodule sync && git submodule update --init --recursive + npm install --no-optional + # reset architecture flags + ./deploy.sh x86_64 --nobuild 0 + ./deploy.sh x86_64 --build-deps --docker - cd myphpcms - git pull - git submodule update --init --recursive - ./docker-compose-alias.sh -dns=domain.com -S -p=sqlrootpassword -t=testpassword -v $* - cd .. - -If you saved the file as _startup.sh_ In bash follows : ```startup.sh --build -d up``` You can add more docker-compose parameters as arguments. Docker builds up a new container and pushes it in registry. It will eventually run the container as the startup script succeeds. -## Circle CI, Docker Local testing +## Quick VM Startup +Everyting is ready to launch a container in real cluster environment. The process is described further. +We have provided 3 ways to make use of this project. It supports: + - [Docker CE](https://docs.docker.com/machine/get-started/) + `docker-compose up` may be enough to run and test the configuration + - [Balena Cloud](https://www.balena.io/docs/learn/getting-started/raspberrypi3/nodejs/) + `./deploy.sh armhf --balena` + - [Kubernetes](https://kubernetes.io//docs/concepts/overview/what-is-kubernetes/) + `./kompose.sh up` may be run if your shell run on a valid working cluster environment + +Please read README.md file to get more information on how to setup the cluster and handle common issues. + +## VM Requirements +- Broadband Internet access to the Worldwide Web, to download the packages and container images dependencies from the remote Docker registries. +- The Docker CE described with the Dockerfile. >:whale: [Get Started](https://docs.docker.com/machine/get-started/) application. +- NodeJS command line package manager interface, [npmjs](https://www.npmjs.com/get-npm) +- A BASH Terminal (Linux or Darwin OS are known to work) +- A virtualization system like [VBoxmanager](https://www.virtualbox.org/wiki/Downloads) must be installed for your OS. + +Once everything is installed, please reboot your system. + +## Webserver configuration +A few variables are defined in containers environment provides client-server communication. + + # Persistent ROOT connection credentials + MYSQL_HOST: localhost + DATABASE_USER: root + MYSQL_ROOT_PASSWORD: mariadb + # CakePHP secrets + CAKEPHP_SECRET_TOKEN: + CAKEPHP_SECRET_SALT: + CAKEPHP_SECURITY_CIPHER_SEED: + +Some configuration changes may broke the installation with Docker and on file permissions. The following default variables may be setup as your server preferences, set in open source: + + # The following values are options to change if needed + # Binding a mysql container to a specific (public) IP address or all (0.0.0.0) + MYSQL_BIND_ADDRESS=0.0.0.0 + + # Run as a different user space ($ id -u $USER) + PUID=0 + # Run as a different user-group space ($ id -g $USER) + PGID=0 + + # MariaDB Timezone + TZ=Europe/Paris + + # Persistent USER connection credentials + MYSQL_USER=maria + MYSQL_PASSWORD=maria-abc + + # staff credentials (url=/admin/index.php) given $ ./configure.sh -h -p pass -s salt + GET_HASH_PASSWORD= + + # Apache 2 httpd, or DNS CNAME of the host machine ($ hostname) + SERVER_NAME=www-machine.local + +## Validate the configuration + + ./configure.sh --docker --mig-database -u -i + + This should pass until it updates the database. This can succeed only if the [Webserver](#Webserver-configuration) initialization did well with your settings. The webserver must be ready to use. + +## Circle CI The current project is a full php with mariadb container for the Docker Virtual Machine (VM) manager, or Docker-CE, or even a ```Dockerfile``` compatible container interface. We choose Circle CI because it's able to achieve full remote tests with docker :whale: before we deploy to a Cloud Provider, Kubernetes Cluster, OpenShift, etc. +### Make local tests with CircleCI CLI A local test may only run with a complete local Virtual Host (Vbox) configuration. See the requirements below. +Get started a Docker shell, and build through local Circle CLI: -### Simple Docker compose tests -To use the built-in CakePHP 2 interface to test with Docker Compose YAML run the test script as follows : + .circleci/build.sh - test-cake.sh --docker +* **circleci cli** -### Requirements -- Broadband Internet access to the Worldwide Web, to download the packages and container images dependencies from the remote Docker registries. -- The [VBoxmanager](https://www.virtualbox.org/wiki/Downloads) package. -- The Docker VM described with the Dockerfile. >:whale: [Get Started](https://docs.docker.com/machine/get-started/) application. -- The docker:docker user SSH remote access enabled (Ask the system administrator to enable Remote Session Accounts with Password authentification in /etc/ssh/sshd_config) - The CircleCI Client installed in ```$PATH```. [CLI Configuration](https://circleci.com/docs/2.0/local-cli/#section=configuration) shell command line : - curl -fLSs https://circle.ci/cli | bash + curl -fLSs https://circle.ci/cli | bash -Once everything is installed, please reboot your system. -### Make local tests with CircleCI CLI -- Enable Docker VM on your system (a virtual Host is instancied) -- Shell command line : ```circleci local execute``` +### [developers] Update the Docker deployment image +Rebuild image registry from deployment folder if you make change to the primary. E.g. change of Linux distribution. Edit the file deployment/images/primary/Dockerfile.template to your needs and perform a build from the a Docker client machine. If you make use of [Balena OS base image list](https://www.balena.io/docs/reference/base-images/base-images-ref/) repository you can use blocks to cross build for ARM ```# [ "cross-build-start" ] # [ "cross-build-end" ]``` command lines in the Dockerfile.template files. For instance, in a Terminal with Docker installed, at first dependencies may be built : + + ./deploy.sh armhf --nobuild --build-deps + +To deploy a Raspberry Pi with Docker or Balena Cloud. -### Startup -Everyting is ready to launch a container in real cluster environment. The process is described further. [Kubespray with Ansible and Kubernetes cluster](https://github.com/b23prodtm/kubesrpay). + ./deploy.sh armhf --balena ### License Copyright 2016 www.b23prodtm.info diff --git a/README.md b/README.md index 65a6dcd46..dedfb5081 100644 --- a/README.md +++ b/README.md @@ -1,51 +1,58 @@ - - -- [CakePHP Sample App on OpenShift](#cakephp-sample-app-on-openshift) - + [Source repository layout](#source-repository-layout) +- [A CakePHP 2.x application ](#a-cakephp-2.x-application) + + [Quickstart](#quickstart) + - [Plugins](#plugins) + + [CakePHP Plugins](#cakephp-plugins) + + [NodeJs dependencies](#nodejs-dependencies) + [Compatibility](#compatibility) - + [Local Built-in Server](#local-built-in-server) - + [PHP Unit Test](#php-unit-test) - + [Server-side environment](#server-side-environment) - + [Database configuration](#database-configuration) + + [PHPUnit Test](#phpunit-test) + + [Device pod environment](#device-pod-environment) + - [Database terminal](#database-terminal) + + [More Database Configuration](#more-database-configuration) + + [Generate new administrator password](#generate-new-administrator-password) + [Common Issues](#common-issues) + [License](#license) +> We are moving to Kubernetes to host our website... See more about that project in [Kubespray](http://www.github.com/b23prodtm/kubespray). -CakePHP for [PHP-CMS Pohse](https://sourceforge.net/projects/pohse/) on OpenShift [![Build Status](https://travis-ci.org/b23prodtm/myphpcms.svg?branch=development)](https://travis-ci.org/b23prodtm/myphpcms) -=============================== - -This is a quickstart CakePHP application for OpenShift v3 that you ''can'' use as a starting point to develop your own application and deploy it on an [OpenShift](https://github.com/openshift/origin) cluster. - -If you'd like to install it, follow [these directions](https://github.com/openshift/cakephp-ex/blob/master/README.md#installation). +A CakePHP 2.x application +========================= +[![TravisCI Status](https://travis-ci.com/b23prodtm/acake2php.svg?branch=development)](https://travis-ci.com/b23prodtm/acake2php) +[![CircleCI Status](https://circleci.com/gh/b23prodtm/acake2php.svg?style=svg)](https://app.circleci.com/pipelines/github/b23prodtm/acake2php) -It includes a link to [PHP-CMS Pohse](https://sourceforge.net/projects/pohse/) and its [GIT cake-php release](https://bitbucket.org/b23prodtm/php-cms/branch/cake-php). The latter PHP CMS is featuring well-known functionalities as cool as posting some web contents with pictures stored in a database. More features do come thank to the powerful [Cake PHP framework](http://www.cakephp.org). +> [Including PHP-CMS ex-Pohse](https://sourceforge.net/projects/pohse/) -### Source repository layout +Quickstart +---------- +Using the basic container orchestrator or engine to deploy and test, is straitforward. +Currently the deployment script +```. deploy.sh``` +Based on [Balena engine](http://www.balena.io). See more about [NodeJs dependencies](#nodejs-dependencies) +Plugins +------- You do not need to change anything in your existing PHP project's repository. However, if these files exist they will affect the behavior of the build process: -* **download from git** +* Git **submodules** - Use a git client to download the project. It will stay in the myphpcms/ folder : - ```git checkout https://github.com/b23prodtm/myphpcms.git``` +  The acake2php folder includes modules that need to be pulled in order to install locally. + After the first checkout browse to acake2php folder and do + ```git submodule sync && git submodule update --init --recursive``` + You'll see modules populating the subfolder app/webroot/... If something goes wrong, erase the acake2php folder and start over. + > After a sucessful ```git checkout```each time, run once ```git submodule update --init --recursive``` to ensure submodules are downloaded from git. Otherwise your build may fail. + > _DEVELOPER TIP:_ To push tags : ```git tag` && git push --tags```. -* **submodules** +* Packagist **composer.json** -  The myphpcms folder includes modules that need to be pulled in order to install locally. - After the first checkout browse to myphpcms folder and do - ```git submodule update --init --recursive``` - You'll see modules populating the subfolder app/webroot/... If something goes wrong, erase the myphpcms folder and start over. + List of dependencies to be installed with `composer`[here](https://packagist.org). -* **composer.json** +#### CakePHP Plugins - List of dependencies to be installed with `composer`. The format is documented - [here](https://getcomposer.org/doc/04-schema.md). - Plugins are registered in both _git submodule_ and _composer.json_. To allow a plugin to accept ```composer update```, edit _composer.json_ according to the available released tags. In the plugin's home repository (app/Plugin//), call```git tag``` or ``git log``` for more information. - >_DEVELOPER TIP:_ To push tags : ```git tag` && git push --tags```. + Plugins are registered in both _git submodule_ and _composer.json_. To allow a plugin to accept ```composer update```, edit _composer.json_ according to the available released tags. + In the plugin's home repository (`app/Vendor/` or `app/Plugin//`) * **.htaccess** @@ -71,46 +78,67 @@ However, if these files exist they will affect the behavior of the build process RewriteRule (.*) webroot/$1 [L] -### Compatibility +#### NodeJs dependencies + + This project depends on npmjs [balena-cloud](https://www.npmjs.com/package/balena-cloud). Please call + `npm update` + whenever the system complains about `balena_deploy` not found. + +* **.env files** + + Set environment variables as the following arguments, for instance on MacOS X: -This repository is compatible with PHP 5.6 and higher, excluding any alpha or beta versions. + ./deploy.sh amd64 --nobuild -### Local built-in server ->for local test only + Use a .env file in shell to configure up with RaspberryPI3 hosts : + ./deploy.sh arm32 --nobuild + + .env -> arm32v7.env + + ./deploy.sh arm32 --balena + +Compatibility +------------- +* CakePHP 2.X application also supports Docker CE 18.03 and later +* MariaDB 10.1 and later + +CAKE includes a server application that´s only made for local tests on port 9000. Open a Terminal window: - ./start-cake.sh -p= + DB=Mysql ./configure.sh --mig-database -u + ./start-cake.sh --docker -c server -p 9000 ->Ctrl-click the URLs to open them in the browser. To get more help about the command line interface : +> Ctrl-click the URLs to open them in the browser. To get more help about the command line interface : ./start-cake.sh --help -### PHP Unit Test - +### PHPUnit Test +JUNIT tests are available with the following call to CAKE server: Open a Terminal window: - ./test-cake.sh -p= -t= + ./test-cake.sh -See [below](#common-issues) to allow access on the built-in local server. +There are options (--travis, --openshift, --circle) dedicated to continuous integration build environments. Use --help to see more about options. -### Server-side environment +See [below](#common-issues) to allow access on the built-in local server. -When deployment happens on server-side or is triggered by a git push event, 'source-to-image (s2i)', the httpd-server or pod needs proper environment variables to be set ready. Otherwise the scripts will fail with an error state, unable to connect to the database +Device pod environment +---------------------- +When deployment happens on device or is triggered by a git push event, 'source-to-image (s2i)', the httpd-server or pod needs proper environment variables to be set ready. Otherwise the scripts will fail with an error state, unable to connect to the database The following variables must be set up as server environment, provided by your **database administrator**: - # SqliteCms, PostgresCms - DATABASE_ENGINE:MysqlCms + # Sqlite, Postgres + DB:Mysql ->Note: DB Engine selects CakePhp Model/Datasource/Database DBOSource class to configure SQL connections. +> Note: DB selects CakePhp Model/Datasource/Database DBOSource class to configure SQL connections. - DATABASE_NAME:default - DATABASE_SERVICE_NAME:MYSQL - # a host alias or IP address - MYSQL_SERVICE_HOST:mysql + MYSQL_DATABASE:default + # a hostname or IP address + MYSQL_HOST:mysql ->Note: Prefixed with *TEST_* they are used by the index.php?test=1 URLs and ./test-cake.sh (--travis) +> Note: Prefixed with *TEST_* they are used by the index.php?test=1 URLs and ./test-cake.sh (--travis) The following additional variables must be set up as server secrets environment, provided by your database administrator: @@ -118,10 +146,10 @@ The following additional variables must be set up as server secrets environment, WEBHOOK_URL: # Persistent connection credentials DATABASE_USER: - DATABASE_PASSWORD: - # Just add TEST_DATABASE_USER and TEST_DATABASE_PASSWORD - TEST_DATABASE_USER: - TEST_DATABASE_PASSWORD: + MYSQL_ROOT_PASSWORD: + # Just add MYSQL_USER and MYSQL_PASSWORD + MYSQL_USER: + MYSQL_PASSWORD: # CakePHP generated CAKEPHP_SECRET_TOKEN: CAKEPHP_SECRET_SALT: @@ -129,151 +157,224 @@ The following additional variables must be set up as server secrets environment, # Generated by ./configure.sh -h GET_HASH_PASSWORD: -### Database Configuration + MYSQL_DATABASE + aria_db + + MYSQL_HOST + db + + MYSQL_PASSWORD + maria-abc + + MYSQL_ROOT_PASSWORD + mariadb + + MYSQL_TCP_PORT + 3306 + + MYSQL_USER + maria + + SERVER_NAME + + + +Database terminal +----------------- +Container engines provides provide a confined environment, with persistent storage. Check that last database deployment was successful, open a pod shell : + +Inside **db** pod: + +```mysql -uroot --password=${MYSQL_ROOT_PASSWORD}``` + +Issue some SQL statements, for instance : + +```ùse aria_db; show tables;``` should list tables + +Inside **acake2php** pod: + +```cake schema update --connection=default``` should build the databases + +```cake schema update --connection=test``` should build the test databases + +#### More Database Configuration An SQL server (must match remote server version) must be reachable by hostname or via its socket. If it's the 1st time you use this connection, Configure it as a service and configure the login ACL with the user shell. -* __Mysql__ mysql installation: +* __Optional__ database automatic configuration: - mysql_secure_installation +```acake2php +./configure.sh -d -u -i +``` + +* __Optional__ To Setup MYSQL_ROOT_PASSWORD at prompt: + +```db +mysql_secure_installation +``` -* __Optional__ Edit `./app/Config/database.cms.php` if you wish to modify the DATABASE_CONFIG class. +* __Optional__ Edit `./app/Config/database.php` if you wish to modify the DATABASE_CONFIG class. * __Optional__ Edit `./app/Model/Datasources/Database` if you wish to modify the DBOSource driver. -* Edit `./Scripts/bootargs.sh` to change default environment settings (host, port, login, database name) +* Edit `./Scripts/fooargs.sh` to change default *test* environment settings (host, port, login, database name) * Run the configuration script: - ./configure.sh -d -p= -u +```acake2php +./configure.sh -d -p -i --sql-password= +``` * More about configuration: - ./configure.sh --help && ./migrate-database.sh --help +```acake2php +./configure.sh --help && ./migrate-database.sh --help +``` * More [common issues](#common-issues) -* The following command resets SQL users `${DATABASE_USER}` and `${TEST_DATABASE_USER}` password : +* The following command resets SQL users `${DATABASE_USER}` and `${MYSQL_USER}` password : ./migrate-database.sh -p -i -p --test-sql-password +#### Generate new administrator password +To sign in with staff rights, at http://localhost/admin/index.php, somebody needs a unique password stored in `GET_HASH_PASSWORD`. One way to generate this hashed password with "salted“ encryption and setup: -### Common Issues + ./configure.sh -h -p -w -1. How to fix the following error? +To regenerate or read the current password hash again, simply browse to http://localhost/php-cms/e13/etc/getHashPassword.php -Index page displays: +`GET_HASH_PASSWORD=` must be stored in the local server environment as a system readable variable. +Common Issues +------------- +1. How to fix the following error? + + Index page displays: +``` errno : 1146 sqlstate : 42S02 error : Table 'phpcms.info' doesn't exist - -Try the following to migrate (update) all database tables, answer 'y' when prompted: - +``` + Try the following to migrate (update) all database tables, answer 'y' when prompted: +```acake2php ./migrate-database.sh -u - +``` 2. ACCESS DENIED appears with other information complaining about database connection, what does that mean ? -You probably have modified user privileges on your server: - + You probably have modified user privileges on your server: +```db mysql -u root use mysql; - grant all on $TEST_DATABASE_NAME.* to '$TEST_DATABASE_USER'@'$TEST_MYSQL_SERVICE_HOST'; + grant all PRIVILEGES on $TEST_DATABASE_NAME.* to '$MYSQL_USER'@'$MYSQL_HOST'; exit +```acake2php ./configure.sh -c +``` + This will reset the connection profile in ..etc/ properties file with the template. + More about environment variables are located in the remote pod (OpenShift) settings and locally in ./Scripts/fooargs.sh. -This will reset the connection profile in ..etc/ properties file with the template. -More about environment variables are located in the remote pod (OpenShift) settings and locally in ./Scripts/bootargs.sh. - ->Note: - - ./configure.sh --mig-database -p -i -p -t - -to do a reset with environment root and user password. + > Note: +```acake2php + ./configure.sh --mig-database -p -i --sql-password +``` + to do a reset with environment root and user password. 3. ACCESS DENIED for root@'127.0.0.1' or root@'localhost' appears with other information complaining about database connection, what does that mean ? -This looks like a first installation of mysql. You have to secure or reset your mysql root access: - + (automatic) This looks like a first installation of mysql. You have to secure or reset your mysql root access: +```acake2php + MYSQL_ROOT_PASSWORD= sudo bash mysqldb/mysql_secure_shell +``` + (manual) The Linux shell way to reinitialize sql root password: +```db sudo rm -rf /usr/local/var/mysql mysqld --initialize | grep "temporary password" | cut -f4 -d ":" | cut -c 2- > app/tmp/nupwd - ->Note: A temporary password is generated for root@localhost. Now import identities. - +``` + > Note: A temporary password is generated for root@localhost. Now import identities. +```acake2php brew services restart mysql@5.7 - ./configure.sh --mig-database -p=$(cat app/tmp/nupwd) -i -p -t ->You have now configured a new SQL root password and a test password. Local SQL access and server is ready to run tests: - - ./test-cake.sh -p -t= - -Go on to development phase with the [Local Built-in server](#local-built-in-server). - -4. My mysql server's upgraded to another version, what should I do ? - -Upgrade your phpcms database within a (secure)shell: - - mysql_upgrade -u root --password= - -4. I've made changes to mysql database tables, I've made changes to Config/Schema/myschema.php, as Config/database.php defines it, what should I do ? + ./configure.sh --mig-database -p $(cat app/tmp/nupwd) -i --sql-password +``` + > You have now configured a new SQL root password and a test password. Local SQL access and server is ready to run tests: +```acake2php + ./test-cake.sh -p -t +``` + Go on to development phase with the [Local Built-in server](#local-built-in-server). -Migrate all your tables: +4. I've made changes to mysql database tables, I've made changes to Config/Schema/schema.php, as Config/database.php defines it, what should I do ? + Migrate all your tables: +```acake2php ./migrate-database.sh -u +``` + Answer 'y' when prompted. -Answer 'y' when prompted. - -5. How to fix up 'Database connection "Mysql" or "Pgsql" is missing, or could not be created' ? - -Log in with root privileges should work: - - mysql -u root --password= cakephp_test - -Postgres has its own command: - - pgsql -U root --password= -d cakephp_test - -If not, retry the [secure_installation](#database-configuration). - -Check your environment variables (`./Scripts/bootargs.sh` or Docker/Pod settings). Use one or the other, and see which works for you: - - MYSQL_SERVICE_HOST=localhost (Unix/OSX platforms) - or - MYSQL_SERVICE_HOST=127.0.0.1 - .. - - MYSQL_SERVICE_PORT=3306 - -Debug the local configuration with verbosity level information (add `-o` if you are in a remote shell): - +5. How to fix up 'Database connection "Mysql" or could not be created ? + PHP mysql extensions must be installed. +```acake2php + php -i | grep Extensions +``` + Log in with root privileges should work: +```db + mysql -u root --password=${MYSQL_ROOT_PASSWORD} +``` + If not, do a reset of your passwords: +```db + mysqladmin -uroot password +``` + If it isn't possible to login: + + Check your environment variables (common.env and docker-compose.yml) settings). Use one or the other, and see which works for you: +``` + MYSQL_HOST=$(hostname) +```(Unix/OSX platforms) + or if docker-compose services are the following name: +``` + MYSQL_HOST=db + MYSQL_TCP_PORT=3306 +``` + + Debug the local configuration, look for unbound VARIABLES, add verbosity level information (add `-o` if you are in a remote shell): +```acake2php + set -u ./configure.sh --verbose -d -u +``` + + Try resetting privileges +```acake2php + ./configure.sh --mig-database -p ${MYSQL_ROOT_PASSWORD} -t ${MYSQL_PASSWORD} -i +``` + Don't miss the parameter to startup a local container database : +```acake2php + ./migrate-database.sh -u --docker -i or ./configure.sh --mig-database -u --docker -i +``` + + Note that localhost is a special value. Using 127.0.0.1 is not the same thing. The latter will connect to the mysqld server through tcpip. + + Try the [secure_installation](#database-configuration). +6. How to fix up ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/run/mysqld/mysql.sock' (2) ? -6. How to fix up ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/mysql/mysql.sock' (2) ? - -Run the socket fixup script with arguments: - - ./migrate-database.sh -y + Run the socket fixup script with arguments: +```acake2php + ./migrate-database.sh /tmp/mysqld.sock brew services restart mysql@5.7 - +``` 7. I'm testing with ./start_cake.sh and I cannot add any new post on Updates section, what should I do ? -With the CLI, you may ctrl-X ctrl-C to exit server and migrate your database: - + With the CLI, you may ctrl-X ctrl-C to exit server and migrate your database: +```acake2php ./migrate-database.sh -u ./start_cake.sh - -Answer 'y' when prompted. +``` + Answer 'y' when prompted. 8. I cannot upload any picture, why ? -The Mysql.php Datasource must define binary and mediumbinary storage types. Please look at the file __app/Model/Datasource/Mysql_cms.php__ if it exists and if you experienced the following error: - + The Mysql.php Datasource must define binary and mediumbinary storage types. Please look at the file __app/Model/Datasource/Mysql_cms.php__ if it exists and if you experienced the following error: +``` errno : 1054 sqlstate : 42S22 error : Unknown column 'image' in 'field list' - -Add the *__mediumbinary__* storage, extending the original Datasource class: +``` + Add the *__mediumbinary__* storage, extending the original Datasource class: ``` ``` -Ensure it is set as DATABASE_ENGINE in `app/Config/database.cms.php`,`./Scripts/bootargs.sh`, `.travis.yml` and update the database schema: - + Ensure it is set as $identities[DB]['datasource'] in `app/Config/database.php`,`./Scripts/fooargs.sh`, `.travis.yml` and update the database schema: +```acake2php ./migrate-database.sh -u - +``` 9. It looks like submodule folders have disappeared, why ? -A recent `git checkout ` made the submodule disappear from disk, that can happen on master/development branch. Recall or add the shell configure script to your workflow: - + A recent `git checkout ` made the submodule disappear from disk, that can happen on master/development branch. Recall or add the shell configure script to your workflow: +```acake2php ./configure.sh -m +``` +10. Error: Please install PHPUnit framework v3.7 (http://www.phpunit.de) -10. SHA1 signature couldn't be verified with the file composer.phar, how is that possible ? - -The composer binary hasn't been downloaded on this machine, and must be downloaded again. By default, git shouldn't keep track on this file. Delete it and launch composer installer again. + You need to configure development environment from Composer dependencies. +```acake2php + ./configure.sh --development +``` +11. Undefined functins balena_deploy or init_functions: No such file or directory - rm bin/composer.phar - ./composer.sh + You need to export the `node_modules/.bin` for this shell to find npmjs installed binaries. -If you are working on a git remote tracked branch, it is recommended to remove from file tracking and add to `.gitignore`. +``` + export PATH="`pwd`/node_modules/.bin:\$PATH" +``` - git rm bin/composer.phar - echo "/bin/composer.phar" >> .gitignore +12. Any message "saved[@]: unbound variable" on Darwin (OSX) -### License - Copyright 2016 www.b23prodtm.info + Your BASH doesn't handle array in scripts and uses version 3. Please upgrade to v.4 or later. + Check your bash version and upgrade OpenSSL Cacert as well: +``` + .travis/TravisCI-OSX-PHP/build/prepare_osx_env.sh +``` +License +------- + Copyright 2016 www.b23prodtm.info Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/Scripts/app/Config/core.php.sed b/Scripts/app/Config/core.php.sed new file mode 100644 index 000000000..e4bd1c01f --- /dev/null +++ b/Scripts/app/Config/core.php.sed @@ -0,0 +1 @@ +s/srand\(([a-z|A-Z|_].+)\)/srand\(\(int\)\(float\)\1\)/g diff --git a/Scripts/bootargs.sh b/Scripts/bootargs.sh old mode 100755 new mode 100644 index b0b17980c..5ee4107ad --- a/Scripts/bootargs.sh +++ b/Scripts/bootargs.sh @@ -1,50 +1,8 @@ -#!/bin/bash -source ./Scripts/lib/parsing.sh -set -e -#; colorize shell script -nc="\033[0m" -red="\033[0;31m" -green="\033[0;32m" -orange="\033[0;33m" -cyan="\033[0;36m" -echo -e "Loading ${orange}Test environment${nc} : $0..." -#; To change Model/Datasource/Database -[[ ("${DB}" == "Mysql") || -z $DB ]] && export DB="Mysql" && export DATABASE_ENGINE="MysqlCms" && export DATABASE_SERVICE_NAME="MYSQL" -[ "${DB}" == "Pgsql" ] && export DATABASE_ENGINE="PostgresCms" && export DATABASE_SERVICE_NAME="PGSQL" -[ "${DB}" == "Sqlite" ] && export DATABASE_ENGINE="SqliteCms" && export DATABASE_SERVICE_NAME="SQLITE" -echo -e "DB : ${green}${DB}${nc}" -#; Host name (unix) 'localhost' generally replaces '127.0.0.1' (macOS). -export PGSQL_SERVICE_HOST="localhost" -#;export MYSQL_SERVICE_HOST="127.0.0.1" -export MYSQL_SERVICE_HOST="localhost" -export MYSQL_SERVICE_PORT="3306" -#; To override, use shell parameter -dbase= instead -export DATABASE_NAME="phpcms" -export DATABASE_USER="root" -#; To override, shell parameter -p= instead -#;export DATABASE_PASSWORD="" -#. Test configuration ?test=1, ./test_cake.sh -export TEST_PGSQL_SERVICE_HOST="localhost" -#;export TEST_MYSQL_SERVICE_HOST="127.0.0.1" -export TEST_MYSQL_SERVICE_HOST="localhost" -export TEST_MYSQL_SERVICE_PORT="3306" -#; To override, use shell parameter -tbase= instead -export TEST_DATABASE_NAME="cakephp_test" -export TEST_DATABASE_USER="test" -#; To override, use shell parameter -t= instead -#;export TEST_DATABASE_PASSWORD="" -export FTP_SERVICE_HOST="localhost" -export FTP_SERVICE_USER="test" -export FTP_SERVICE_PASSWORD="mypassword" -#; More about default environment app/Config/core.php -#; Openshift Online secure keys (default_keys) -export CAKEPHP_SECURITY_SALT="Word" -export CAKEPHP_SECURITY_CIPHER_SEED="01234" -#; 0, 1, 2 the higher the more debug data -export CAKEPHP_DEBUG_LEVEL=2 -#; Read -p pass -s word <- bootstrap.sh exports -#; export GET_HASH_PASSWORD=wokUd0mccQD2s -if [[ $(parse_arg_exists "-[vV]*|--verbose" $*) ]]; then - echo "DATABASE_PASSWORD=${DATABASE_PASSWORD}" - echo "TEST_DATABASE_PASSWORD=${TEST_DATABASE_PASSWORD}" -fi; +#!/usr/bin/env bash +TOPDIR=$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd) +incBOOT_ARGS=${incBOOT_ARGS:-0}; if [ "$incBOOT_ARGS" -eq 0 ]; then + export incBOOT_ARGS=1 + [[ ! -e "$TOPDIR/.env" || ! -e "$TOPDIR/common.env" ]] \ + && printf "Missing environment configuration, please run ./deploy.sh %s --nobuild first.\n" "$(arch)" && exit 1 + eval "$(cat "$TOPDIR/.env" "$TOPDIR/common.env" | awk 'BEGIN{ FS="\n" }{ print "export " $1 }')" +fi diff --git a/Scripts/bootstrap.sh b/Scripts/bootstrap.sh index 55b2433e0..058565a3d 100755 --- a/Scripts/bootstrap.sh +++ b/Scripts/bootstrap.sh @@ -1,42 +1,53 @@ -#!/bin/bash +#!/usr/bin/env bash set -e -source ./Scripts/lib/shell_prompt.sh -source ./Scripts/lib/parsing.sh -openshift=$(parse_arg_exists "-[oO]*|--openshift" $*) -if [ -z ${PHP_CMS_DIR} ]; then export PHP_CMS_DIR=app/webroot/php_cms; fi -if [ $openshift 2> /dev/null ]; then - echo "Real environment bootargs..." +TOPDIR=$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd) +# shellcheck source=lib/logging.sh +. "${TOPDIR}/Scripts/lib/logging.sh" +# shellcheck source=lib/shell_prompt.sh +. "${TOPDIR}/Scripts/lib/shell_prompt.sh" +# shellcheck source=lib/parsing.sh +. "${TOPDIR}/Scripts/lib/parsing.sh" +openshift=$(parse_arg "-[oO]+|--openshift" "$@") +pargs=$(parse_arg_trim "-[oO]+|--openshift" "$@") +if [ -n "$openshift" ]; then + slogger -st "$0" "Bootargs...: ${pargs}" export CAKEPHP_DEBUG_LEVEL=1 + # shellcheck source=bootargs.sh + . "${TOPDIR}/Scripts/bootargs.sh" "$@" else - echo "Provided local/test bootargs..." + slogger -st "$0" "Locally Testing values, bootargs...: ${pargs}" export CAKEPHP_DEBUG_LEVEL=2 - source ./Scripts/bootargs.sh $* + # shellcheck source=fooargs.sh + . "${TOPDIR}/Scripts/fooargs.sh" "$@" fi #; #; check if file etc/constantes_local.properties exist (~ ./configure.sh was run once) #; -if [ ! -f ${PHP_CMS_DIR}/e13/etc/constantes.properties ]; then - shell_prompt "./configure.sh -c" "configuration" +if [ ! -f "$TOPDIR/$MYPHPCMS_DIR/e13/etc/constantes.properties" ] && [ -z "$openshift" ]; then + shell_prompt "$TOPDIR/configure.sh -c" "missing file creation constantes.properties" "${DEBIAN_FRONTEND:-}" fi -echo "Configuration begins automatically..." +slogger -st "$0" "Auto configuration..." #; hash file that is stored in webroot to allow administrator privileges -if [[ ! $GET_HASH_PASSWORD ]]; then - hash="${PHP_CMS_DIR}/e13/etc/export_hash_password.sh" - if [ ! -f $hash ]; then - shell_prompt "./configure.sh -c -h" "configuration" +if [ -z "${GET_HASH_PASSWORD:-}" ] && [ -z "$openshift" ]; then + hash="$TOPDIR/${MYPHPCMS_DIR}/e13/etc/export_hash_password.sh" + if [ ! -f "$hash" ]; then + shell_prompt "$TOPDIR/configure.sh -h " "define a value for missing GET_HASH_PASSWORD" "${DEBIAN_FRONTEND:-}" fi - source $hash + # shellcheck source=app/webroot/php-cms/e13/etc/export_hash_password.sh + . "$hash" fi +# shellcheck disable=SC2154 echo -e "${nc}Password ${green}${GET_HASH_PASSWORD}${nc}" #; Install PHPUnit, performs unit tests #; The website must pass health checks in order to be deployed -if [ $openshift 2> /dev/null ]; then - phpunit="./app/Vendor/bin/phpunit" - if [ ! -f $phpunit ]; then - source ./Scripts/composer.sh -o phpunit/phpunit cakephp/cakephp-codesniffer - else - echo -e "PHPUnit ${green}[OK]${nc}" - fi - echo `$phpunit --version` +if [ -n "$openshift" ]; then + phpunit="$TOPDIR/app/Vendor/bin/phpunit" + if [ ! -f "$phpunit" ]; then + # shellcheck source=composer.sh + "${TOPDIR}/Scripts/composer.sh" install --dev --no-interaction --ignore-platform-reqs + else + slogger -st "$0" "PHPUnit ${green}[OK]${nc}" + fi + printf "%s\n" "$($phpunit --version)" fi -source ./Scripts/config_app_database.sh +bash -c "$TOPDIR/Scripts/start_daemon.sh ${pargs}" diff --git a/Scripts/composer.sh b/Scripts/composer.sh index 2a9c0a410..876bfd319 100755 --- a/Scripts/composer.sh +++ b/Scripts/composer.sh @@ -1,27 +1,26 @@ -#!/bin/bash +#!/usr/bin/env bash #; #; #; Composer simplifies the process to add features like plugins #; #; -#; colorful shell -source ./Scripts/lib/parsing.sh -nc='\033[0m' -red="\033[0;31m" -green="\033[0;32m" -orange="\033[0;33m" -cyan="\033[0;36m" +TOPDIR=$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd) +# shellcheck source=lib/logging.sh +. "${TOPDIR}/Scripts/lib/logging.sh" +# shellcheck source=lib/parsing.sh +. "${TOPDIR}/Scripts/lib/parsing.sh" composer="bin/composer.phar" -if [ $(which composer) 2> /dev/null ]; then +if [ -n "$(command -v composer)" ]; then composer="composer" -else if [ ! -f $composer ]; then - echo -e "Composer setup...\n" +elif [ ! -f $composer ]; then + slogger -st "$0" "Composer setup...\n" mkdir -p bin - cd bin + cd bin || exit 1 curl -sS https://getcomposer.org/installer | php cd .. -fi;fi -echo -e "Composer ${green}[OK]${nc}" +fi +# shellcheck disable=SC2154 +slogger -st "$0" "Composer ${green}[OK]${nc}" bash -c "${composer} --version" #; update plugins and dependencies (composer install is good enough to check for updates) -bash -c "${composer} install $*" +bash -c "${composer} $*" diff --git a/Scripts/config_a2ensite.sh b/Scripts/config_a2ensite.sh new file mode 100755 index 000000000..e8958db57 --- /dev/null +++ b/Scripts/config_a2ensite.sh @@ -0,0 +1,27 @@ +#!/usr/bin/env bash +set -eu +TOPDIR=$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd) +. init_functions . +export WWW="${1:-$TOPDIR/app/webroot}" +export CNF="${2:-/etc/apache2}" +log_daemon_msg "Add VirtualHost $HTTPD_LISTEN ${WWW} to ${CNF}/conf.d/site.conf, ${BASH_SOURCE[0]} [www_directory:app/webroot] [site.conf_directory:/etc/apache2]" +mkdir -p "$CNF/conf.d" +mkdir -p "$WWW" +envsubst < "${CNF}/site.tpl" > "${CNF}/conf.d/site.conf" +log_daemon_msg "SSL VirtualHost" +envsubst < "${CNF}/ssl_site.tpl" > "${CNF}/conf.d/ssl_site.conf" +log_daemon_msg "Enable mod_rewrite" +if [ -f "${CNF}/httpd.conf" ]; then + sed -i.old -E -e "/mod_rewrite.so/s/^#+//g" "${CNF}/httpd.conf" + grep mod_rewrite.so < "${CNF}/httpd.conf" +else + log_warning_msg "${CNF}/httpd.conf file not found" +fi +log_daemon_msg "Add /etc/hosts $SERVER_NAME" +if [ -w "/etc/hosts" ]; then + tmpfile=$(mktemp) + sed -E -e "/127.0.0.1/s/(localhost)/\\1 ${SERVER_NAME} www.${SERVER_NAME}/" /etc/hosts > "$tmpfile" + cat "$tmpfile" > /etc/hosts +else + log_warning_msg "/etc/hosts file not found" +fi diff --git a/Scripts/config_app_database.sh b/Scripts/config_app_database.sh index 9d102f21c..407a2b5b4 100755 --- a/Scripts/config_app_database.sh +++ b/Scripts/config_app_database.sh @@ -1,39 +1,58 @@ -#!/bin/bash +#!/usr/bin/env bash +TOPDIR=$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd) sqlversion="5.7" -if [ ! $(which brew) 2> /dev/null ]; then echo "Missing homebrew... aborted mysql check."; else if [ ! $(which mysql) 2> /dev/null ]; then - echo -e "Missing MySQL ${sqlversion} database service." - brew outdated mysql@${sqlversion} | brew upgrade - echo -e "Installing with Homebrew..." - brew install mysql@${sqlversion} - echo -e "Starting the service thread..." - brew services start mysql@${sqlversion} - echo -e "Performing some checks..." - mysql_upgrade -u root & +# shellcheck source=lib/logging.sh +. "${TOPDIR}/Scripts/lib/logging.sh" +# shellcheck source=lib/parsing.sh +. "${TOPDIR}/Scripts/lib/parsing.sh" +docker=$(parse_arg "--docker" "$@") +if [ -n "$docker" ]; then + bash -c "./Scripts/start_daemon.sh ${docker}" else - mysql --version -fi; fi -while [[ "$#" > 0 ]]; do case $1 in + if [ -z "$(command -v brew)" ]; then + echo "Missing homebrew... aborted mysql check."; + elif [ -z "$(command -v mysql)" ]; then + slogger -st "$0" "Missing MySQL ${sqlversion} database service." + brew outdated mysql@${sqlversion} | brew upgrade + slogger -st "$0" "Installing with Homebrew..." + brew install mysql@${sqlversion} + slogger -st "$0" "Starting the service thread..." + brew services start mysql@${sqlversion} + slogger -st "$0" "Performing some checks..." + mysql_upgrade -u root & + fi +fi +sockdir=/var/run/mysqld +wd="$TOPDIR/app/Config" +while [[ "$#" -gt 0 ]]; do case $1 in *.php) dbfile=$1 - wd="app/Config" - source ./Scripts/cp_bkp_old.sh $wd $dbfile "database.php" + file=$(echo "$dbfile" | cut -d . -f 1) + # shellcheck source=cp_bkp_old.sh + . "${TOPDIR}/Scripts/cp_bkp_old.sh" "$wd" "$dbfile" "${file}.php" ;; - -[yY]*) - #; symlink mysql socket with php - echo "Please allow the super-user to link mysql socket to php ..." - sudo mkdir -p /var/mysql - if [ -h /var/mysql/mysql.sock ]; then - ls -al /var/mysql/mysql.sock + *.sock ) + if [ -n "$(command -v mysql)" ]; then + mysql --version + fi + sockh=$sockdir/mysqld.sock + #; symlink mysql socket + # shellcheck disable=SC2154 + slogger -st "$0" "${orange}Please allow the super-user to link mysql socket to $1 ...${nc}" + if [ -e $sockh ]; then + ls -al $sockh else - sudo ln -vs /tmp/mysql.sock /var/mysql/mysql.sock + [ ! -d $sockdir ] && sudo mkdir -p $sockdir + sudo ln -vsf "$1" $sockh fi;; *) ;; esac; shift; done -if [ ! -h /var/mysql/mysql.sock ]; then - echo -e "${orange}Warning:${nc}/var/mysql/mysql.sock symlink not found." -else - echo -e "${green}Notice: mysql.sock symlink was found.${nc}" - #export MYSQL_SERVICE_HOST="127.0.0.1" - #export TEST_MYSQL_SERVICE_HOST="127.0.0.1" +if [ -z "$docker" ]; then + if [ -n "$(command -v mysql)" ] && [ ! -e $sockdir/mysqld.sock ]; then + slogger -st "$0" "${orange}Warning:${nc}$sockdir/mysqld.sock not found." + else + # shellcheck disable=SC2154 + slogger -st "$0" "${green}Notice: mysqld.sock was found.${nc}" + fi fi diff --git a/Scripts/config_etc_const.sh b/Scripts/config_etc_const.sh index 34e03098c..f2ba84aa4 100755 --- a/Scripts/config_etc_const.sh +++ b/Scripts/config_etc_const.sh @@ -1,6 +1,9 @@ -#!/bin/bash +#!/usr/bin/env bash set -e -wd="app/webroot/php_cms/e13/etc/" +TOPDIR=$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd) +MYPHPCMS_DIR=${MYPHPCMS_DIR:-'app/webroot/php-cms'} +wd="${TOPDIR}/${MYPHPCMS_DIR}/e13/etc/" src="constantes_template.properties" dst="constantes.properties" -source ./Scripts/cp_bkp_old.sh $wd $src $dst +# shellcheck source=cp_bkp_old.sh +. "${TOPDIR}/Scripts/cp_bkp_old.sh" "$wd" "$src" "$dst" diff --git a/Scripts/config_etc_pass.sh b/Scripts/config_etc_pass.sh index 7d24c4fa5..9c68ebe6d 100755 --- a/Scripts/config_etc_pass.sh +++ b/Scripts/config_etc_pass.sh @@ -1,45 +1,53 @@ -#!/bin/bash -pwd=`pwd` +#!/usr/bin/env bash +[ $# -lt 1 ] && echo "Usage: $0 -p= -s= [-f=]" && exit 1 +TOPDIR=$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd) +# shellcheck source=lib/logging.sh +. "$TOPDIR/Scripts/lib/logging.sh" +# shellcheck source=lib/parsing.sh +. "$TOPDIR/Scripts/lib/parsing.sh" +pwd=$(pwd) pass="" salt="" hash_file="" -cd app/webroot/php_cms/e13/etc/ +MYPHPCMS_DIR=${MYPHPCMS_DIR:-'app/webroot/php-cms'} +dir="$TOPDIR/$MYPHPCMS_DIR/e13/etc/" +cd "$dir" || log_failure_msg "No such directory %s\n" "$dir" # passed args from shell_prompt -while [[ "$#" > 0 ]]; do case $1 in +while [ "$#" -gt 0 ]; do case $1 in -[pP]* ) - pass=$2 - shift;; + parse_arg_export "pass" "a password" "$@";; -[sS]* ) - salt=$2 - shift;; + parse_arg_export "salt" "a salt word" "$@";; -[fF]* ) - hash_file=$2 - shift;; - *) ;; + parse_arg_export "hash_file" "a filename.sh" "$@";; + *);; esac; shift; done #; read password if not set -if [ -z $pass ]; then while true; do - read -sp "Please enter a password :" pass +if [ -z "$pass" ]; then while true; do + read -sp -r "Please enter a password :" pass echo -e "\n" - read -sp "Please re-enter the password :" confirmpass + read -sp -r "Please re-enter the password :" confirmpass echo -e "\n" - if [ "$pass" == "$confirmpass" ]; then - break + if [ "$pass" = "$confirmpass" ]; then + break else - echo -e "${red}Passwords don't match.\n${nc}" + # shellcheck disable=SC2154 + echo -e "${red}Passwords don't match.\n${nc}" fi done; fi # read salt if not set -if [ -z $salt ]; then while [ "$salt" == "" ]; do - read -p "Please enter the salt word :" salt +if [ -z "$salt" ]; then while [ "$salt" = "" ]; do + read -p -r "Please enter the salt word :" salt done; fi # read filename if not set -if [ -z $hash_file ]; then +if [ -z "$hash_file" ]; then hash_file="export_hash_password.sh" fi -php -f getHashPassword.php -- -p $pass -s $salt -f $hash_file +php -f getHashPassword.php -- -p "$pass" -s "$salt" -f "$hash_file" #; so that the shell can execute export file chmod 777 $hash_file -echo -e "Saved in $hash_file .\n" -cd $pwd +# shellcheck source=../app/webroot/php-cms/e13/etc/getHashPassword.php +. "$hash_file" +slogger -st "$0" "Saved in $hash_file .\n" +cd "$pwd" || log_failure_msg "No such directory %s\n" "$dir" diff --git a/Scripts/configure_tmp.sh b/Scripts/configure_tmp.sh index c2705906f..107397d02 100755 --- a/Scripts/configure_tmp.sh +++ b/Scripts/configure_tmp.sh @@ -1,7 +1,9 @@ -#!/bin/bash -mkdir -p app/tmp/cache/persistent -mkdir -p app/tmp/cache/models -mkdir -p app/tmp/tests -mkdir -p app/tmp/logs -touch app/tmp/logs/error.log -chmod -Rv 770 app/tmp +#!/usr/bin/env bash +TOPDIR=$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd) +mkdir -p "$TOPDIR/app/tmp/cache/long" +mkdir -p "$TOPDIR/app/tmp/cache/persistent" +mkdir -p "$TOPDIR/app/tmp/cache/models" +mkdir -p "$TOPDIR/app/tmp/tests" +mkdir -p "$TOPDIR/app/tmp/logs" +touch "$TOPDIR/app/tmp/logs/error.log" +chmod -Rv 1776 "$TOPDIR/app/tmp" diff --git a/Scripts/cp_bkp_old.sh b/Scripts/cp_bkp_old.sh index 4902ddb01..89ec5548e 100755 --- a/Scripts/cp_bkp_old.sh +++ b/Scripts/cp_bkp_old.sh @@ -1,22 +1,27 @@ -#!/bin/bash +#!/usr/bin/env bash set -e [ $# -lt 3 ] && echo "Usage : $0 " && exit 1 +TOPDIR=$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd) +# shellcheck source=lib/logging.sh +. "${TOPDIR}/Scripts/lib/logging.sh" wd=$1 src=$2 dst=$3 -pwd=`pwd` -cd $wd -if [[ ( -f $dst ) && ( -f $src ) && ( $(which md5) > /dev/null ) ]]; then +pwd=$(pwd) +cd "$wd" +if [[ -f $dst && -f $src && -n $(command -v md5) ]]; then # read or operation to define $file1 & $file2 here ... - val1=`md5 -q $src` - val2=`md5 -q $dst` + val1=$(md5 -q "$src") + val2=$(md5 -q "$dst") tmpval="Z${val1}" ; val1="${tmpval}" tmpval="Z${val2}" ; val2="${tmpval}" - if [ $val1 != $val2 ]; then - # files are not the same, do operation here .. - cp -v $dst "${dst}.old" + if [ "$val1" != "$val2" ]; then + # files are not the same, backup + cp -v "$dst" "${dst}.old" + else + echo "${dst} file's already there.." fi fi -cp -v $src $dst -cd $pwd -echo -e "${src} copied. Please, review the files.\n" +cp -v "$src" "$dst" +cd "$pwd" +slogger -st "$0" "${src} copied. Please, review the files.\n" diff --git a/Scripts/fooargs.sh b/Scripts/fooargs.sh new file mode 100755 index 000000000..e7bef353f --- /dev/null +++ b/Scripts/fooargs.sh @@ -0,0 +1,56 @@ +#!/usr/bin/env bash +incFOO_ARGS=${incFOO_ARGS:-0}; if [ "$incFOO_ARGS" -eq 0 ]; then + export incFOO_ARGS=1 + # shellcheck source=lib/logging.sh + . ./Scripts/lib/logging.sh + # shellcheck source=lib/parsing.sh + . ./Scripts/lib/parsing.sh + set -eu + docker=$(parse_arg "--docker" "$@") + travis=$(parse_arg "--travis" "$@") + # shellcheck disable=SC2154 + slogger -st "$0" "Loading ${orange}Test environment${nc} : $0..." + #; Common Environment profile + [[ ! -e .env || ! -e common.env ]] \ + && printf "Missing environment configuration, please run ./deploy.sh %s --nobuild first." "$(arch)" \ + && exit 1 + eval "$(cat .env common.env | awk 'BEGIN{ FS="\n" }{ print "export " $1 }')" + #; To change Model/Datasource/Database + export DB=${DB:-Mysql} + # shellcheck disable=SC2154 + slogger -st "$0" "DB : ${green}${DB}${nc}" + # Test units : + # - Web interface: + # URL: http://localhost:8000/index.php?test=1 + # - Built-in cake Console + # $ ./test_cake.sh + # - Continuous Integration + # $ .circleci/build.sh + # + if [ -n "$docker" ] || [ -n "$travis" ]; then + export MYSQL_HOST=${MYSQL_HOST:-$(hostname)} + export PGSQL_HOST=${MYSQL_HOST:-$(hostname)} + fi + export MYSQL_HOST=${MYSQL_HOST:-'localhost'} + export PGSQL_HOST=${PGSQL_HOST:-'localhost'} + export MYSQL_TCP_PORT=${MYSQL_TCP_PORT:-'3306'} + export MYSQL_USER=${MYSQL_USER:-'maria'} + #; To override, use shell parameter -t instead + [ ! "$travis" ] && export MYSQL_PASSWORD=${MYSQL_PASSWORD:-'maria-abc'} + export MYSQL_DATABASE=${MYSQL_DATABASE:-'aria_db'} + #; To override, use shell parameter -dbase= instead + export DATABASE_USER=${DATABASE_USER:-'root'} + #; To override, shell parameter -p= instead + [ ! "$travis" ] && export MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD:-'mariadb'} + #; To override, use shell parameter -tbase= instead + export TEST_DATABASE_NAME=${TEST_DATABASE_NAME:-'test'} + export FTP_SERVICE_HOST=localhost + export FTP_SERVICE_USER=test + export FTP_SERVICE_PASSWORD=mypassword + #; export GET_HASH_PASSWORD=wokUd0mcc + if [ -n "$(parse_arg "-[vV]+|--verbose" "$@")" ]; then + echo "MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD}" + echo "MYSQL_PASSWORD=${MYSQL_PASSWORD}" + fi + export SERVER_NAME=${SERVER_NAME:-$(hostname)} +fi diff --git a/Scripts/lib/Cake/Console/ConsoleOutput.php.sed b/Scripts/lib/Cake/Console/ConsoleOutput.php.sed new file mode 100644 index 000000000..ad786b4fb --- /dev/null +++ b/Scripts/lib/Cake/Console/ConsoleOutput.php.sed @@ -0,0 +1 @@ +s/implode\((\$styleInfo),(.*)\)/implode\(\2,\1\)/g diff --git a/Scripts/lib/Cake/Console/ShellDispatcher.php.sed b/Scripts/lib/Cake/Console/ShellDispatcher.php.sed new file mode 100644 index 000000000..208a59a53 --- /dev/null +++ b/Scripts/lib/Cake/Console/ShellDispatcher.php.sed @@ -0,0 +1 @@ +s/\$dispatcher->_stop(\(.*\));/\1;/g diff --git a/Scripts/lib/locate.sh b/Scripts/lib/locate.sh index 05636a5e2..a4d089725 100644 --- a/Scripts/lib/locate.sh +++ b/Scripts/lib/locate.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash _locate() { - [ $# -lt 1 ] && echo "Usage: $0 " && return $FALSE - find /usr -name $1 | grep -m 1 $1 + [ $# -lt 1 ] && echo "Usage: $0 " && return "$FALSE" + find /usr -name "$1" | grep -m 1 "$1" } # export -f _locate diff --git a/Scripts/lib/logging.sh b/Scripts/lib/logging.sh new file mode 100644 index 000000000..7e4ef4cfc --- /dev/null +++ b/Scripts/lib/logging.sh @@ -0,0 +1,24 @@ +#!/usr/bin/env bash +TOPDIR=$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd) +. init_functions . +function new_cake_log_long() { + while [ "$#" -gt 0 ]; do case $1 in + --travis) + new_log "$TOPDIR/${MYPHPCMS_LOG}" "travis.${TRAVIS_BUILD_NUMBER:-'TRAVIS_BUILD_NUMBER'}.log" + return;; + --docker) + new_log "$TOPDIR/${MYPHPCMS_LOG}" "docker.log" + return;; + -[oO]+|--openshift) + new_log "$TOPDIR/${MYPHPCMS_LOG}" "openshift.log" + return;; + *) + ;; + esac; shift; done + new_log "$TOPDIR/${MYPHPCMS_LOG}" "acake2php.log" +} +function new_cake_log() { + a="$(new_cake_log_long "$@")" + ln -sf "$a" "$(basename "$a")" + basename "$a" +} diff --git a/Scripts/lib/parsing.sh b/Scripts/lib/parsing.sh index ae6b109d4..42686896d 100755 --- a/Scripts/lib/parsing.sh +++ b/Scripts/lib/parsing.sh @@ -1,52 +1,151 @@ -#!/bin/bash +#!/usr/bin/env bash set -e +TOPDIR=$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd) +banner=("" "[$0] BASH ${BASH_SOURCE[0]}" ""); printf "%s\n" "${banner[@]}" +#; colorize shell script +nc="\033[0m" +red="\033[0;31m" +green="\033[0;32m" +orange="\033[0;33m" +cyan="\033[0;36m" parse_sql_password() { - [ $# -lt 2 ] && echo "Usage: $0 -p|-t|--*sql-password*|*= " && return $FALSE - pass=$(echo $1 | cut -f 2 -d '=') - while true; do case "$pass" in - *sql-password*|-[pPtT]*) - read -sp " -Please, enter the $3 SQL password now: -" pass;; - "") - echo "WARNING: using blank password is unsafe !" - pass="" - break;; - *) - break;; - esac; done - #;echo $pass - export $2=$pass + [ $# -lt 3 ] && printf "Usage: %s -|--\n" \ + "${FUNCNAME[0]}" \ + && exit 1 + evar=$1 + desc=$2 + shift 2 + # Transform long options to short ones + while [ "$#" -gt 0 ]; do + # shellcheck disable=SC2046 + case "$1" in + -[pP]*|-[tT]*) + parse_and_export "$1" "$evar" "$desc" "${@}" + shift + ;; + --sql-password*) set -- $(echo "$1" \ + | awk 'BEGIN{ FS="[ =]+" }{ print "-p " $2 }') "${@:2}" + parse_and_export "-p" "$evar" "$desc" "${@}" + shift + ;; + --test-sql-password*) set -- $(echo "$1" \ + | awk 'BEGIN{ FS="[ =]+" }{ print "-t " $2 }') "${@:2}" + parse_and_export "-t" "$evar" "$desc" "${@}" + shift + ;; + *);; + esac;shift + done } #; export -f parse_sql_password parse_arg_export() { - [ $# -lt 3 ] && echo "Usage: $0 -= <-pattern*|-PATTERN*> " && return $FALSE - zval=$(echo $1 | cut -f 2 -d '=') + [ $# -lt 3 ] && printf "%s\n" \ + "Usage: ${FUNCNAME[0]} - " \ + && exit 1 + evar="$1" + desc="$2" + shift 2 + zval=$(echo "$@" | awk 'BEGIN{ FS="[ =]+" }{ print $2 }') while true; do case "$zval" in - $2|"") - read -sp " -Please, enter the $4 value now: -" zval;; + "") + read -r -s -p " +Please, enter the $desc value now: +" zval + ;; *) break;; esac; done - export $3=$zval + eval "export ${evar}=${zval}" } #; export -f parse_arg_export parse_arg_exists() { - [ $# -lt 2 ] && echo "Usage: $0 list-or-\$*" - arg1=$(echo $1 | cut -f 1 -d '|') - arg2=$(echo $1 | cut -f 2 -d '|') + [ $# -eq 1 ] && return + [ $# -lt 2 ] && printf "%s\n" \ + "Usage: ${FUNCNAME[0]} list-or-\$*" \ + "Prints the argument index that's matched in the regex-arg-case (~ patn|patn2)" \ + && exit 1 + # add mask case |---- to avoid unknown state in split when $# = 1 + export arg_case="$1|----" shift - count=1 - while [[ "$#" > 0 ]]; do case $1 in - $arg1|$arg2 ) echo $count; break;; - *) ;; - esac; ((count++)); shift; done + echo "$@" | awk 'BEGIN{FS=" "; ORS=" "; split(ENVIRON["arg_case"], a, "|")} { + n=-1 + for(i in a) { + for(f=1; f<=NF; f++) { + if($f ~ a[i]) { + n=f + break + } + if(n != -1) break + } + } + } + END { + if(n >= 0) print n + }' + unset arg_case } #; export -f parse_arg_exists() -parse_dns_host() { - [ $# -lt 3 ] && echo "Usage: $0 " - parse_arg_export $1 "-dns*|-DNS*" $2 $3 +parse_arg_trim() { + [ $# -eq 1 ] && return + [ $# -lt 2 ] && printf "%s\n" \ + "Usage: ${FUNCNAME[0]} list-or-\$*" \ + "Prints the argument list that's not matched in the regex-arg-case (~ patn|patn2)" \ + && exit 1 + export arg_case=$1 + shift + echo "$@" | awk 'BEGIN{FS=" "; ORS=" "; split(ENVIRON["arg_case"], a, "|"); n[0]=""} { + for(f=1;f<=NF;f++) { + n[f]=$f + for(i in a) { + if($f ~ a[i]) n[f]="" + } + } + } END{ + for(f in n) { + if(n[f] != "") print n[f] + } + }' +} + +#; export -f parse_dom_host() +### ------------------------- +# Only short options (e.g. -a -f) are supported. +# Long options must be transformed into short ones before. +# When an argument --name=Bob passes, transform into -n Bob: +# +# set -- $(echo "$1" \ +# | awk 'BEGIN{ FS="[ =]+" }{ print "-n " $2 }') "${@:2}" +# parse_and_export -n NAME "Set user name" "${@:2}" +# +# To continue arguments processing after a call to this function : +# +# shift +# +parse_and_export() { + [ $# -lt 4 ] && printf "%s\n" \ + "Usage: ${FUNCNAME[0]} <-arg list> " \ + && exit 1 + optstr=$1 + evar=$2 + desc=$3 + shift 3 + unset OPTIND + while [ "$#" -gt 0 ]; do + OPTIND=$(("$(parse_arg_exists "$optstr" "$@")" +1)) + if [ "$OPTIND" -gt 0 ]; then + shift $((OPTIND -1)) + parse_arg_export "$evar" "${desc}" "-${optstr}" "${1:-}" + [ -n "${1:-}" ] && OPTIND=$((OPTIND +1)) + break + fi + shift + done + export OPTIND +} +#; export -f parse_and_export() +parse_arg() { + ret=$(parse_arg_exists "$@") + # shellcheck disable=SC2015 + [ -n "$ret" ] && shift 1 && echo "${*:$ret:1}" || true } -#; export -f parse_dns_host() +#; export -f parse_arg() diff --git a/Scripts/lib/shell_prompt.sh b/Scripts/lib/shell_prompt.sh index 4fbb33cf9..2ede9ba29 100755 --- a/Scripts/lib/shell_prompt.sh +++ b/Scripts/lib/shell_prompt.sh @@ -1,37 +1,60 @@ -#!/bin/bash +#!/usr/bin/env bash set -e +TOPDIR=$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd) +. init_functions . shell_prompt() { - [ $# -lt 2 ] && echo "Usage: $0 [-y|n]" && return $FALSE - script=$1 - title=$2 + [ $# -lt 2 ] && printf "Usage: %s [-y|n]" "${FUNCNAME[0]}" && exit 1 + script="$1" + title="$2" while true; do - # (1) prompt user, and read command line argument if no 3rd arg - echo -e "${cyan}Run ${title} ?...\n${nc}" - answer=$3 - case $answer in - -[yY]* ) answer="Y";; - - -[nN]* ) answer="N";; - - * ) - read -p "Do ${script} now (Y/N) ? " answer;; - esac - # (2) run a script if the user answered Y (yes) or N (no) quit the script - case $answer in - [yY]* ) echo -e "Yes.\n" - source $script - break;; - - [nN]* ) echo -e "No.\n" - break;; - - * ) echo -e "${red}Dude, just enter Y or N, please.\n${nc}";; - esac + # (1) prompt user, and read command line argument if no 3rd arg + # shellcheck disable=SC2154 + log_daemon_msg "Run ${title} ?..." + answer=$3 + case $answer in + -[yY]*|noninteractive ) answer="Y" + ;; + -[nN]* ) answer="N" + ;; + * ) read -r -p "Do ${script} now (Y/N) ? " answer + ;; + esac + # (2) run a script if the user answered Y (yes) or N (no) quit the script + case $answer in + [yY]* ) echo -e "Yes." + # FIXME: bash -c might mask shell syntax errors (e.g. long filenames) + # shellcheck disable=SC1090 + bash -c "$script || log_failure_msg \"FAILED\"" + break;; + [nN]* ) echo -e "No.\n" + break;; + * ) log_failure_msg "Dude, just enter Y or N, please." + ;; + esac done } #; export -f shell_prompt show_password_status() { - [ "$#" -lt 3 ] && echo "Usage: $0 '' '' " - echo -e "User ${green}${1}${nc} (using password:${orange} $([ -z $2 ] && echo 'NO' || echo 'YES')${nc}) $3...\n" + [ "$#" -lt 3 ] && echo "Usage: ${FUNCNAME[0]} '' '' " && exit 1 + slogger -st "${FUNCNAME[0]}" "User ${1} (using password: $([ -z "$2" ] && echo "NO" || echo "YES")) $3..." } #; export -f show_password_status +patches() { + for f in "$@"; do + file="$(basename "${f}")" + dir="$(dirname "${f}")" + [ ! -f "$dir/$file" ] && file="${file,,}" + [ ! -f "$dir/$file" ] && dir="${dir,,}" + sed -i.old -E -f "$(dirname "${BASH_SOURCE[0]}")/../${f}.sed" "$dir/$file" + done +} +#; export -f patches +cakephp() { + "${TOPDIR}/app/Console/cake.php" "$@" +} +#; export -f cakephp +docker_name() { + [ "$#" -lt 1 ] && echo "Usage: ${FUNCNAME[0]} 'DOCKER_HUB_NAME'" && exit 1 + echo "$1" | awk -F/ '{ print $2 }' | awk -F: '{ print $1 }' +} +#; export -f docker_name diff --git a/Scripts/lib/test/parsing.sh b/Scripts/lib/test/parsing.sh new file mode 100644 index 000000000..24c55693e --- /dev/null +++ b/Scripts/lib/test/parsing.sh @@ -0,0 +1,92 @@ +#!/usr/bin/env bash +set -e +TOPDIR=$(cd "$(dirname "${BASH_SOURCE[0]}")/../../.." && pwd) +# shellcheck source=lib/parsing.sh +. "${TOPDIR}/Scripts/lib/parsing.sh" +Z=("[%s] %s %s(OPTIND=%s)\n") +# During the test build, arguments were passed "inline" or "dollar-star" $* +# It turns out that bash shells passes arguments array or "dollar-array" $@. +# The difference's in layouts by printing list inline "$*" or column style "$@". +function test_parse_and_export() { + args=(-t T "1st password" -t "pass_one") + parse_and_export "${args[@]}" + # shellcheck disable=SC2059 + [ "$T" = "pass_one" ] \ + && printf "${Z[*]}" "OK" "1° export" "$T" $OPTIND \ + || printf "${Z[*]}" "FAILED" "1° export" "$T" $OPTIND + + args=(-p P "2nd password" -t "-p" "pass_two") + parse_and_export "${args[@]}" + # shellcheck disable=SC2059 + [ "$P" = "pass_two" ] \ + && printf "${Z[*]}" "OK" "2° export" "$P" $OPTIND \ + || printf "${Z[*]}" "FAILED" "2° export" "$P" $OPTIND + unset P T +} + +function test_parse_sql_password() { + args=(P "password one" "-p" "pass_one" "--foo=arg") + parse_sql_password "${args[@]}" + # shellcheck disable=SC2059 + [ "$P" = "pass_one" ] \ + && printf "${Z[*]}" "OK" "1° password" "$P" $OPTIND \ + || printf "${Z[*]}" "FAILED" "1° password" "$P" $OPTIND + + args=("S" "password two" "-f" "arg" "--test-sql-password=pass_two") + parse_sql_password "${args[@]}" + # shellcheck disable=SC2059 + [ "$S" = "pass_two" ] \ + && printf "${Z[*]}" "OK" "2° password" "$S" $OPTIND \ + || printf "${Z[*]}" "FAILED" "2° password" "$S" $OPTIND + unset P S +} + +function test_arg_exists() { + args=(-d me "--open=9" --data) + T=$(parse_arg_exists "-d" "${args[@]}") + # shellcheck disable=SC2059 + [ -n "$T" ] \ + && printf "${Z[*]}" "OK" "1° match" "$T" $OPTIND \ + || printf "${Z[*]}" "FAILED" "1° match" "$T" $OPTIND + + P=$(parse_arg_exists "-d|--data" "${args[@]}") + # shellcheck disable=SC2059 + [ -n "$P" ] \ + && printf "${Z[*]}" "OK" "2° match" "$P" $OPTIND \ + || printf "${Z[*]}" "FAILED" "2° match" "$P" $OPTIND +} + +function test_arg() { + args=(-d me --open --data) + T=$(parse_arg "-d|--data" "${args[@]}") + # shellcheck disable=SC2059 + [ "$T" = "-d" ] \ + && printf "${Z[*]}" "OK" "1° parse" "$T" $OPTIND \ + || printf "${Z[*]}" "FAILED" "1° parse" "$T" $OPTIND + + P=$(parse_arg "--open" "${args[@]}") + # shellcheck disable=SC2059 + [ "$P" = "--open" ] \ + && printf "${Z[*]}" "OK" "2° parse" "$P" $OPTIND \ + || printf "${Z[*]}" "FAILED" "2° parse" "$P" $OPTIND +} + +function test_arg_trim() { + args=(-d me --open --data) + T=$(parse_arg_trim "-d|--data" "${args[@]}") + # shellcheck disable=SC2059 + [[ $(echo "$T" | wc -w) -eq $(echo "me --open" | wc -w) ]] \ + && printf "${Z[*]}" "OK" "1° trim" "$T" $OPTIND \ + || printf "${Z[*]}" "FAILED" "1° trim" "$T" $OPTIND + + P=$(parse_arg_trim "--open" "${args[@]}") + # shellcheck disable=SC2059 + [[ $(echo "$P" | wc -w) -eq $(echo "-d me --data" | wc -w) ]] \ + && printf "${Z[*]}" "OK" "2° trim" "$P" $OPTIND \ + || printf "${Z[*]}" "FAILED" "2° trim" "$P" $OPTIND +} +test=("test_arg_exists" "test_arg" "test_arg_trim" "test_parse_and_export" "test_parse_sql_password") +for t in "${test[@]}"; do + printf "TEST CASES : %s\n" "$t" && eval "$t" +done +sleep 2 diff --git a/Scripts/linter-shellcheck.sh b/Scripts/linter-shellcheck.sh new file mode 100755 index 000000000..4b5e13b33 --- /dev/null +++ b/Scripts/linter-shellcheck.sh @@ -0,0 +1,13 @@ +#!/bin/bash -eo pipefail +IGNORE_STRING=SC1091,SC2034,SC2096,SC2155,SC1090,SC2096,SC2038 +SHELLCHECK_OPTS=$(echo "-e ${IGNORE_STRING//,/ -e }") + +export SHELLCHECK_OPTS="$SHELLCHECK_OPTS" + +echo "Running shellcheck with the following SHELLCHECK_OPTS value..." +echo "SHELLCHECK_OPTS=$SHELLCHECK_OPTS" + +find '.' -not -path '' \ + -type f -name '*.sh' | \ + xargs shellcheck --external-sources | \ + tee -a 'shellcheck.log' diff --git a/Scripts/start_daemon.sh b/Scripts/start_daemon.sh new file mode 100755 index 000000000..72bd5659a --- /dev/null +++ b/Scripts/start_daemon.sh @@ -0,0 +1,113 @@ +#!/usr/bin/env bash +TOPDIR=$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd) +# shellcheck source=lib/logging.sh +. "$TOPDIR/Scripts/lib/logging.sh" +# shellcheck source=lib/shell_prompt.sh +. "$TOPDIR/Scripts/lib/shell_prompt.sh" +# shellcheck source=lib/parsing.sh +. "$TOPDIR/Scripts/lib/parsing.sh" +openshift=$(parse_arg "-[oO]+|--openshift" "$@") +docker=$(parse_arg "--docker" "$@") +travis=$(parse_arg "--travis" "$@") +ck_args=$(parse_arg_trim "-[oO]+|--openshift|--docker|--travis" "$@") +LOG=$(new_cake_log "$travis" "$docker" "$openshift") && slogger -st "$0" "$LOG" +MARIADB_SHORT_NAME=$(docker_name "$SECONDARY_HUB") +function wait_for_host() { + [ "$#" -lt 2 ] && printf "Usage: %s " "${FUNCNAME[0]}" && exit 1 + for i in $(seq 1 10); do + # shellcheck disable=SC2154 + nc -z "$1" "$2" && slogger -st "${FUNCNAME[0]}" "${green}Success${nc}" && sleep 2 && return 0 + echo -n . + sleep 1 + done + # shellcheck disable=SC2154 + slogger -st "${FUNCNAME[0]}" "${red}Failed: Host's unavailable${nc}" + return 1 +} +function run_ps() { + if "$@" >> "$LOG" 2>&1; then + log_success_msg "SUCCESS" + else + log_failure_msg "FAILED" + fi +} +if [ -n "$docker" ]; then + slogger -st "$0" "Docker list ${MARIADB_SHORT_NAME} containers ($SECONDARY_HUB)" + #docker shows only running cid (not -q -a -f) + maria=$(docker ps -q -f "name=${MARIADB_SHORT_NAME}") + if [ -z "$maria" ]; then + docker pull "${SECONDARY_HUB}" + fi + CID="$TOPDIR/mysqldb/mysqld/mysqld.cid" + if [ -f "$CID" ] && [ "$(cat "$CID")" = "$maria" ]; then + slogger -st "$0" "Container $MARIADB_SHORT_NAME running." + else + slogger -st "$0" "Container $MARIADB_SHORT_NAME already maybe running, was stopped." + maria_hub=$(docker ps -q -a -f "ancestor=${SECONDARY_HUB}") + docker stop "$maria" "$maria_hub" >> "$LOG" 2>&1 || true + docker rm -f "$maria" "$maria_hub" >> "$LOG" 2>&1 || true + slogger -st "$0" "Container $MARIADB_SHORT_NAME 's started up..." + mysql_credentials=("-e MYSQL_DATABASE=${MYSQL_DATABASE} -e MYSQL_USER=${MYSQL_USER}" "-e MYSQL_PASSWORD=${MYSQL_PASSWORD}" \ + "-e DATABASE_USER=${DATABASE_USER}" "-e MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD}") + [ -z "$(docker network ls -q -f 'name=cake')" ] && docker network create cake + if docker run --name "$MARIADB_SHORT_NAME" -id \ + --env-file .env -e PUID="$(id -u "$USER")" -e PGID="$(id -g "$USER")" \ + --network cake -e MYSQL_HOST="${MYSQL_HOST}" -e MYSQL_BIND_ADDRESS="${MYSQL_BIND_ADDRESS:-'0.0.0.0'}" \ + "${mysql_credentials[@]}" --publish "$MYSQL_TCP_PORT:$MYSQL_TCP_PORT" \ + -v "$TOPDIR/mysqldb/conf.d:/etc/mysql/conf.d" -v "$TOPDIR/mysqldb/config:/config" \ + -v "$TOPDIR/mysqldb/mysqld:/var/run/mysqld/" \ + "${SECONDARY_HUB}" >> "$LOG" 2>&1; then + slogger -st "$0" "Started docker --name=${MARIADB_SHORT_NAME} ref: $(docker ps -q -a -f "name=maria") host: $MYSQL_HOST}" + fi + fi + if ! wait_for_host "$MYSQL_HOST" "${MYSQL_TCP_PORT:-3306}"; then + slogger -st "$0" "${red}Failed waiting for Mysql${nc}" + fi + docker ps -q -f "name=${MARIADB_SHORT_NAME}" > "$CID" + check_log "$LOG" +fi +# shellcheck disable=SC2086 +if [ -n "$(parse_arg "server" $ck_args)" ]; then + show_password_status "${DATABASE_USER}" "${MYSQL_ROOT_PASSWORD}" "is running development server" + url="http://${SERVER_NAME}:${CAKE_TCP_PORT:-8000}" + # shellcheck disable=SC2154 + slogger -st "$0" "Welcome homepage ${cyan}${url}${nc}" + slogger -st "$0" "Administrator login ${cyan}${url}/admin/index${nc}" + # shellcheck disable=SC2154 + slogger -st "$0" "Debugging echoes ${cyan}${url}${orange}?debug=1&verbose=1${nc}" + slogger -st "$0" "Another Test configuration ${cyan}${url}/admin/index.php${orange}?test=1${nc}" + slogger -st "$0" "Unit tests ${cyan}${url}/test.php${nc}" + slogger -st "$0" "Turnoff flags (fix captcha)${cyan}${url}/admin/logoff.php${nc}" + slogger -st "$0" "===============================================" + # shellcheck disable=SC2086 + run_ps cakephp $ck_args +elif [ -n "$(parse_arg "test" "$(parse_arg_trim "--connection*" $ck_args)")" ]; then + slogger -st "$0" "$(printf "Passed Cake Args: %s" "$ck_args")" + if [ "${COLLECT_COVERAGE}" = "true" ]; then + run_ps "$TOPDIR/app/Vendor/bin/phpunit" --log-junit ~/phpunit/junit.xml --coverage-clover \ + app/build/logs/clover.xml --stop-on-failure -c app/phpunit.xml.dist \ + app/Test/Case/AllTestsTest.php + elif [ "${PHPCS}" = 1 ]; then + run_ps "$TOPDIR/app/Vendor/bin/phpcs" --colors -p -s --extensions=php --cache "$TOPDIR/app" + else + # shellcheck disable=SC2086 + run_ps cakephp $ck_args --coverage-clover app/build/logs/clover.xml + fi +elif [ -n "$(parse_arg "update" $ck_args)" ]; then + #; cakephp shell + slogger -st "$0" "Migrating database 'cake schema update' ..." + # shellcheck disable=SC2086 + p=$(parse_arg_trim "update" $ck_args) + slogger -st "$0" "$(printf "Passed Cake Args:(%s) -> %s" "$ck_args" "$p")" + # shellcheck disable=SC2086 + run_ps cakephp schema update $p -y + if [ -f app/Config/Schema/sessions.php ]; then + slogger -st "$0" "Generating default Sessions table" + # shellcheck disable=SC2086 + run_ps cakephp schema create Sessions $p -y + fi + slogger -st "$0" "Generating database schema 'cake schema generate'" + # shellcheck disable=SC2086 + run_ps cakephp schema generate $p -f snapshot +fi +check_log "$LOG" diff --git a/aarch64.env b/aarch64.env new file mode 100644 index 000000000..40acdecea --- /dev/null +++ b/aarch64.env @@ -0,0 +1,5 @@ +DKR_ARCH=aarch64 +BALENA_MACHINE_NAME=generic-aarch64 +IMG_TAG=latest +PRIMARY_HUB=betothreeprod/apache-php7 +SECONDARY_HUB=betothreeprod/mariadb-generic-aarch64 diff --git a/app/.htaccess b/app/.htaccess deleted file mode 100644 index 076135aea..000000000 --- a/app/.htaccess +++ /dev/null @@ -1,6 +0,0 @@ - - RewriteEngine on - RewriteBase /app/ - RewriteRule ^$ webroot/ [L] - RewriteRule (.*) webroot/$1 [L] - diff --git a/app/Config/Schema/myschema.php b/app/Config/Schema/myschema.php deleted file mode 100644 index 91fbe74b3..000000000 --- a/app/Config/Schema/myschema.php +++ /dev/null @@ -1,226 +0,0 @@ - array('type' => 'integer', 'null' => false, 'default' => '0', 'unsigned' => false, 'key' => 'primary'), - 'fk_reference_facture' => array('type' => 'string', 'null' => false, 'length' => 32, 'key' => 'primary', 'collate' => 'utf8_general_ci', 'charset' => 'utf8'), - 'fk_reference_magasin' => array('type' => 'string', 'null' => false, 'length' => 4, 'key' => 'primary', 'collate' => 'utf8_general_ci', 'charset' => 'utf8'), - 'indexes' => array( - 'PRIMARY' => array('column' => array('fk_reference_commande', 'fk_reference_facture', 'fk_reference_magasin'), 'unique' => 1) - ), - 'tableParameters' => array('charset' => 'utf8', 'collate' => 'utf8_general_ci', 'engine' => 'InnoDB') - ); - - public $cake_sessions = array( - 'id' => array('type' => 'string', 'null' => false, 'default' => null, 'key' => 'primary', 'collate' => 'utf8_general_ci', 'charset' => 'utf8'), - 'data' => array('type' => 'text', 'null' => true, 'default' => null, 'collate' => 'utf8_general_ci', 'charset' => 'utf8'), - 'expires' => array('type' => 'integer', 'null' => true, 'default' => null, 'unsigned' => false), - 'indexes' => array( - 'PRIMARY' => array('column' => 'id', 'unique' => 1) - ), - 'tableParameters' => array('charset' => 'utf8', 'collate' => 'utf8_general_ci', 'engine' => 'InnoDB') - ); - - public $categorie = array( - 'id' => array('type' => 'integer', 'null' => false, 'default' => null, 'unsigned' => false, 'key' => 'primary', 'autoIncrement' => true), - 'nom' => array('type' => 'string', 'null' => false, 'length' => 50, 'key' => 'primary', 'collate' => 'utf8_general_ci', 'charset' => 'utf8'), - 'parent' => array('type' => 'integer', 'null' => true, 'default' => null, 'length' => 3, 'unsigned' => false, 'key' => 'index'), - 'image' => array('type' => 'integer', 'null' => true, 'default' => null, 'unsigned' => false), - 'indexes' => array( - 'PRIMARY' => array('column' => array('id', 'nom'), 'unique' => 1), - 'parent' => array('column' => 'parent', 'unique' => 0) - ), - 'tableParameters' => array('charset' => 'utf8', 'collate' => 'utf8_general_ci', 'engine' => 'InnoDB') - ); - - public $classification = array( - 'reference_classe' => array('type' => 'string', 'null' => false, 'length' => 4, 'key' => 'primary', 'collate' => 'utf8_general_ci', 'charset' => 'utf8'), - 'nom' => array('type' => 'string', 'null' => false, 'length' => 30, 'collate' => 'utf8_general_ci', 'charset' => 'utf8'), - 'fk_reference_categorie' => array('type' => 'integer', 'null' => false, 'default' => '0', 'unsigned' => false), - 'indexes' => array( - 'PRIMARY' => array('column' => 'reference_classe', 'unique' => 1) - ), - 'tableParameters' => array('charset' => 'utf8', 'collate' => 'utf8_general_ci', 'engine' => 'InnoDB') - ); - - public $clients = array( - 'identifiant' => array('type' => 'string', 'null' => false, 'length' => 20, 'key' => 'primary', 'collate' => 'utf8_general_ci', 'charset' => 'utf8'), - 'email' => array('type' => 'string', 'null' => false, 'length' => 60, 'collate' => 'utf8_general_ci', 'charset' => 'utf8'), - 'fk_id_mdp' => array('type' => 'string', 'null' => true, 'default' => null, 'length' => 32, 'key' => 'unique', 'collate' => 'utf8_general_ci', 'charset' => 'utf8'), - 'nom' => array('type' => 'string', 'null' => false, 'length' => 30, 'collate' => 'utf8_general_ci', 'charset' => 'utf8'), - 'prenom' => array('type' => 'string', 'null' => false, 'length' => 30, 'collate' => 'utf8_general_ci', 'charset' => 'utf8'), - 'annee_de_naissance' => array('type' => 'text', 'null' => false, 'length' => 4), - 'adresse' => array('type' => 'string', 'null' => true, 'default' => null, 'length' => 30, 'collate' => 'utf8_general_ci', 'charset' => 'utf8'), - 'ville' => array('type' => 'string', 'null' => false, 'length' => 20, 'collate' => 'utf8_general_ci', 'charset' => 'utf8'), - 'pays' => array('type' => 'string', 'null' => false, 'length' => 20, 'collate' => 'utf8_general_ci', 'charset' => 'utf8'), - 'telephone' => array('type' => 'integer', 'null' => true, 'default' => null, 'length' => 20, 'unsigned' => false), - 'indexes' => array( - 'PRIMARY' => array('column' => 'identifiant', 'unique' => 1) - ), - 'tableParameters' => array('charset' => 'utf8', 'collate' => 'utf8_general_ci', 'engine' => 'InnoDB') - ); - - public $commande = array( - 'reference' => array('type' => 'integer', 'null' => false, 'default' => null, 'unsigned' => false, 'key' => 'primary'), - 'date_de_commande' => array('type' => 'date', 'null' => false, 'key' => 'index'), - 'fk_reference_produit' => array('type' => 'string', 'null' => false, 'length' => 20, 'collate' => 'utf8_general_ci', 'charset' => 'utf8'), - 'fk_reference_promotion' => array('type' => 'integer', 'null' => false, 'default' => '0', 'unsigned' => false), - 'indexes' => array( - 'PRIMARY' => array('column' => 'reference', 'unique' => 1), - 'date_de_commande' => array('column' => 'date_de_commande', 'unique' => 0) - ), - 'tableParameters' => array('charset' => 'utf8', 'collate' => 'utf8_general_ci', 'engine' => 'InnoDB') - ); - - public $compte = array( - 'fk_identifiant' => array('type' => 'string', 'null' => false, 'length' => 20, 'key' => 'primary', 'collate' => 'utf8_general_ci', 'charset' => 'utf8'), - 'nb_de_produits_achetes' => array('type' => 'integer', 'null' => true, 'default' => null, 'unsigned' => false, 'key' => 'index'), - 'montant_d_achat_total' => array('type' => 'decimal', 'null' => false, 'default' => '0.0', 'length' => '6,1', 'unsigned' => false), - 'date_ouverture_du_compte' => array('type' => 'date', 'null' => false), - 'indexes' => array( - 'PRIMARY' => array('column' => 'fk_identifiant', 'unique' => 1), - 'nb_de_produits_achetes' => array('column' => array('nb_de_produits_achetes', 'montant_d_achat_total', 'date_ouverture_du_compte'), 'unique' => 0) - ), - 'tableParameters' => array('charset' => 'utf8', 'collate' => 'utf8_general_ci', 'engine' => 'InnoDB') - ); - - public $articles = array( - 'id' => array('type' => 'integer', 'null' => false, 'default' => null, 'unsigned' => false, 'key' => 'primary'), - 'entete' => array('type' => 'string', 'null' => false, 'length' => 250, 'collate' => 'utf8_general_ci', 'charset' => 'utf8'), - 'fk_reference_categorie' => array('type' => 'integer', 'null' => true, 'default' => null, 'unsigned' => false), - 'corps' => array('type' => 'text', 'null' => false, 'length' => 4, 'collate' => 'utf8_general_ci', 'charset' => 'utf8'), - 'date' => array('type' => 'date', 'null' => false), - 'published' => array('type' => 'date', 'null' => false), - 'indexes' => array( - 'PRIMARY' => array('column' => 'id', 'unique' => 1) - ), - 'tableParameters' => array('charset' => 'utf8', 'collate' => 'utf8_general_ci', 'engine' => 'InnoDB') - ); - - public $disponibilite = array( - 'fk_id_produit' => array('type' => 'integer', 'null' => false, 'default' => '0', 'length' => 5, 'unsigned' => false, 'key' => 'primary'), - 'fk_reference_exemplaire' => array('type' => 'string', 'null' => false, 'length' => 20, 'key' => 'primary', 'collate' => 'utf8_general_ci', 'charset' => 'utf8'), - 'indexes' => array( - 'PRIMARY' => array('column' => array('fk_id_produit', 'fk_reference_exemplaire'), 'unique' => 1) - ), - 'tableParameters' => array('charset' => 'utf8', 'collate' => 'utf8_general_ci', 'engine' => 'InnoDB') - ); - - public $editeur = array( - 'code_editeur' => array('type' => 'string', 'null' => false, 'length' => 4, 'key' => 'primary', 'collate' => 'utf8_general_ci', 'charset' => 'utf8'), - 'image' => array('type' => 'integer', 'null' => true, 'default' => null, 'length' => 5, 'unsigned' => false), - 'nom' => array('type' => 'string', 'null' => false, 'length' => 20, 'collate' => 'utf8_general_ci', 'charset' => 'utf8'), - 'indexes' => array( - 'PRIMARY' => array('column' => 'code_editeur', 'unique' => 1) - ), - 'tableParameters' => array('charset' => 'utf8', 'collate' => 'utf8_general_ci', 'engine' => 'InnoDB') - ); - - public $exemplaire = array( - 'code_reference' => array('type' => 'string', 'null' => false, 'length' => 20, 'key' => 'primary', 'collate' => 'utf8_general_ci', 'charset' => 'utf8'), - 'date_de_livraison' => array('type' => 'date', 'null' => false), - 'fk_id_produit' => array('type' => 'integer', 'null' => false, 'default' => '0', 'length' => 5, 'unsigned' => false), - 'indexes' => array( - 'PRIMARY' => array('column' => 'code_reference', 'unique' => 1) - ), - 'tableParameters' => array('charset' => 'utf8', 'collate' => 'utf8_general_ci', 'engine' => 'InnoDB') - ); - - public $facture = array( - 'reference' => array('type' => 'string', 'null' => false, 'length' => 32, 'key' => 'primary', 'collate' => 'utf8_general_ci', 'charset' => 'utf8'), - 'montant_facture' => array('type' => 'decimal', 'null' => true, 'default' => null, 'length' => '6,1', 'unsigned' => false), - 'date_de_facturation' => array('type' => 'date', 'null' => false), - 'mode_de_paiement' => array('type' => 'string', 'null' => false, 'length' => 4, 'key' => 'index', 'collate' => 'utf8_general_ci', 'charset' => 'utf8'), - 'fk_identifiant' => array('type' => 'string', 'null' => false, 'length' => 20, 'collate' => 'utf8_general_ci', 'charset' => 'utf8'), - 'indexes' => array( - 'PRIMARY' => array('column' => 'reference', 'unique' => 1), - 'mode_de_paiement' => array('column' => array('mode_de_paiement', 'fk_identifiant'), 'unique' => 0) - ), - 'tableParameters' => array('charset' => 'utf8', 'collate' => 'utf8_general_ci', 'engine' => 'InnoDB') - ); - - public $fournisseur = array( - 'code_fournisseur' => array('type' => 'string', 'null' => false, 'length' => 4, 'key' => 'primary', 'collate' => 'utf8_general_ci', 'charset' => 'utf8'), - 'nom' => array('type' => 'string', 'null' => false, 'length' => 30, 'key' => 'index', 'collate' => 'utf8_general_ci', 'charset' => 'utf8'), - 'adresse' => array('type' => 'string', 'null' => false, 'length' => 40, 'collate' => 'utf8_general_ci', 'charset' => 'utf8'), - 'numero_tel' => array('type' => 'integer', 'null' => false, 'default' => '0', 'length' => 20, 'unsigned' => false), - 'ville' => array('type' => 'string', 'null' => false, 'length' => 15, 'collate' => 'utf8_general_ci', 'charset' => 'utf8'), - 'pays' => array('type' => 'string', 'null' => false, 'length' => 15, 'collate' => 'utf8_general_ci', 'charset' => 'utf8'), - 'indexes' => array( - 'PRIMARY' => array('column' => 'code_fournisseur', 'unique' => 1), - 'nom' => array('column' => array('nom', 'ville', 'pays'), 'unique' => 0) - ), - 'tableParameters' => array('charset' => 'utf8', 'collate' => 'utf8_general_ci', 'engine' => 'InnoDB', 'comment' => 'Fournisseurs des produits') - ); - - public $image = array( - 'id' => array('type' => 'integer', 'null' => false, 'default' => null, 'unsigned' => false, 'key' => 'primary'), - 'nom' => array('type' => 'string', 'null' => true, 'default' => null, 'length' => 250, 'collate' => 'utf8_general_ci', 'charset' => 'utf8'), - 'image' => array('type' => 'mediumbinary', 'null' => false, 'default' => null), - 'mime' => array('type' => 'string', 'null' => false, 'default' => 'image/png', 'length' => 250, 'collate' => 'utf8_general_ci', 'charset' => 'utf8'), - 'description' => array('type' => 'text', 'null' => true, 'default' => null, 'collate' => 'utf8_general_ci', 'charset' => 'utf8'), - 'indexes' => array( - 'PRIMARY' => array('column' => 'id', 'unique' => 1) - ), - 'tableParameters' => array('charset' => 'utf8', 'collate' => 'utf8_general_ci', 'engine' => 'InnoDB') - ); - - public $info = array( - 'id' => array('type' => 'integer', 'null' => false, 'default' => null, 'unsigned' => false, 'key' => 'primary'), - 'categorie' => array('type' => 'integer', 'null' => true, 'default' => null, 'unsigned' => false), - 'titre' => array('type' => 'text', 'null' => false, 'default' => null, 'collate' => 'utf8_general_ci', 'charset' => 'utf8'), - 'auteur' => array('type' => 'string', 'null' => false, 'length' => 250, 'collate' => 'utf8_general_ci', 'charset' => 'utf8'), - 'contenu' => array('type' => 'text', 'null' => false, 'default' => null, 'collate' => 'utf8_general_ci', 'charset' => 'utf8'), - 'langue' => array('type' => 'string', 'null' => false, 'length' => 32, 'collate' => 'utf8_general_ci', 'charset' => 'utf8'), - 'date' => array('type' => 'date', 'null' => false), - 'published' => array('type' => 'date', 'null' => false), - 'images' => array('type' => 'string', 'null' => true, 'default' => null, 'length' => 35, 'collate' => 'utf8_general_ci', 'charset' => 'utf8'), - 'indexes' => array( - 'PRIMARY' => array('column' => 'id', 'unique' => 1) - ), - 'tableParameters' => array('charset' => 'utf8', 'collate' => 'utf8_general_ci', 'engine' => 'InnoDB') - ); - - public $messages = array( - 'id' => array('type' => 'integer', 'null' => false, 'default' => null, 'unsigned' => false, 'key' => 'primary'), - 'titre' => array('type' => 'string', 'null' => false, 'length' => 250, 'collate' => 'utf8_general_ci', 'charset' => 'utf8'), - 'texte' => array('type' => 'text', 'null' => false, 'default' => null, 'collate' => 'utf8_general_ci', 'charset' => 'utf8'), - 'fk_identifiant' => array('type' => 'string', 'null' => false, 'length' => 250, 'collate' => 'utf8_general_ci', 'charset' => 'utf8'), - 'date' => array('type' => 'date', 'null' => false), - 'indexes' => array( - 'PRIMARY' => array('column' => 'id', 'unique' => 1) - ), - 'tableParameters' => array('charset' => 'utf8', 'collate' => 'utf8_general_ci', 'engine' => 'InnoDB') - ); - - public $motdepasses = array( - 'id_mdp' => array('type' => 'string', 'null' => false, 'length' => 32, 'key' => 'primary', 'collate' => 'utf8_general_ci', 'charset' => 'utf8'), - 'password' => array('type' => 'string', 'null' => false, 'length' => 8, 'collate' => 'utf8_general_ci', 'charset' => 'utf8'), - 'indexes' => array( - 'PRIMARY' => array('column' => 'id_mdp', 'unique' => 1) - ), - 'tableParameters' => array('charset' => 'utf8', 'collate' => 'utf8_general_ci', 'engine' => 'InnoDB') - ); - - public $php4u_bookmarks = array( - 'id' => array('type' => 'integer', 'null' => false, 'default' => null, 'length' => 10, 'unsigned' => true, 'key' => 'primary'), - 'dbase' => array('type' => 'string', 'null' => false, 'length' => 128, 'collate' => 'utf8_general_ci', 'charset' => 'utf8'), - 'user' => array('type' => 'string', 'null' => false, 'length' => 128, 'collate' => 'utf8_general_ci', 'charset' => 'utf8'), - 'label' => array('type' => 'string', 'null' => false, 'length' => 128, 'collate' => 'utf8_general_ci', 'charset' => 'utf8'), - 'query' => array('type' => 'text', 'null' => false, 'default' => null, 'collate' => 'utf8_general_ci', 'charset' => 'utf8'), - 'indexes' => array( - 'PRIMARY' => array('column' => 'id', 'unique' => 1) - ), - 'tableParameters' => array('charset' => 'utf8', 'collate' => 'utf8_general_ci', 'engine' => 'InnoDB') - ); - -} diff --git a/app/Config/Schema/schema.php b/app/Config/Schema/schema.php index 2cc9ff849..f07cb9f06 100644 --- a/app/Config/Schema/schema.php +++ b/app/Config/Schema/schema.php @@ -1,4 +1,11 @@ - -u +* pour mettre à jour la base données */ class AppSchema extends CakeSchema { public $file = 'schema.php'; @@ -11,18 +18,18 @@ public function after($event = array()) { } public $achat = array( - 'fk_reference_commande' => array('type' => 'integer', 'null' => false, 'default' => '0', 'unsigned' => false, 'key' => 'primary'), - 'fk_reference_facture' => array('type' => 'string', 'null' => false, 'length' => 32, 'key' => 'primary', 'collate' => 'utf8_general_ci', 'charset' => 'utf8'), - 'fk_reference_magasin' => array('type' => 'string', 'null' => false, 'length' => 4, 'key' => 'primary', 'collate' => 'utf8_general_ci', 'charset' => 'utf8'), + 'id_commande' => array('type' => 'integer', 'null' => false, 'default' => '0', 'unsigned' => false, 'key' => 'primary'), + 'id_facture' => array('type' => 'string', 'null' => false, 'length' => 32, 'key' => 'primary'), + 'id_magasin' => array('type' => 'string', 'null' => false, 'length' => 4, 'key' => 'primary'), 'indexes' => array( - 'PRIMARY' => array('column' => array('fk_reference_commande', 'fk_reference_facture', 'fk_reference_magasin'), 'unique' => 1) + 'PRIMARY' => array('column' => array('id_commande', 'id_facture', 'id_magasin'), 'unique' => 1) ), 'tableParameters' => array('charset' => 'utf8', 'collate' => 'utf8_general_ci', 'engine' => 'InnoDB') ); public $cake_sessions = array( - 'id' => array('type' => 'string', 'null' => false, 'default' => null, 'key' => 'primary', 'collate' => 'utf8_general_ci', 'charset' => 'utf8'), - 'data' => array('type' => 'text', 'null' => true, 'default' => null, 'collate' => 'utf8_general_ci', 'charset' => 'utf8'), + 'id' => array('type' => 'string', 'null' => false, 'default' => null, 'key' => 'primary'), + 'data' => array('type' => 'text', 'null' => true, 'default' => null), 'expires' => array('type' => 'integer', 'null' => true, 'default' => null, 'unsigned' => false), 'indexes' => array( 'PRIMARY' => array('column' => 'id', 'unique' => 1) @@ -32,7 +39,7 @@ public function after($event = array()) { public $categorie = array( 'id' => array('type' => 'integer', 'null' => false, 'default' => null, 'unsigned' => false, 'key' => 'primary', 'autoIncrement' => true), - 'nom' => array('type' => 'string', 'null' => false, 'length' => 50, 'key' => 'primary', 'collate' => 'utf8_general_ci', 'charset' => 'utf8'), + 'nom' => array('type' => 'string', 'null' => false, 'length' => 50, 'key' => 'primary'), 'parent' => array('type' => 'integer', 'null' => true, 'default' => null, 'length' => 3, 'unsigned' => false, 'key' => 'index'), 'image' => array('type' => 'integer', 'null' => true, 'default' => null, 'unsigned' => false), 'indexes' => array( @@ -43,53 +50,55 @@ public function after($event = array()) { ); public $classification = array( - 'reference_classe' => array('type' => 'string', 'null' => false, 'length' => 4, 'key' => 'primary', 'collate' => 'utf8_general_ci', 'charset' => 'utf8'), - 'nom' => array('type' => 'string', 'null' => false, 'length' => 30, 'collate' => 'utf8_general_ci', 'charset' => 'utf8'), - 'fk_reference_categorie' => array('type' => 'integer', 'null' => false, 'default' => '0', 'unsigned' => false), + 'id' => array('type' => 'string', 'null' => false, 'length' => 4, 'key' => 'primary'), + 'nom' => array('type' => 'string', 'null' => false, 'length' => 30), + 'id_categorie' => array('type' => 'integer', 'null' => false, 'default' => '0', 'unsigned' => false), 'indexes' => array( - 'PRIMARY' => array('column' => 'reference_classe', 'unique' => 1) + 'PRIMARY' => array('column' => 'id', 'unique' => 1) ), 'tableParameters' => array('charset' => 'utf8', 'collate' => 'utf8_general_ci', 'engine' => 'InnoDB') ); - public $client = array( - 'identifiant' => array('type' => 'string', 'null' => false, 'length' => 20, 'key' => 'primary', 'collate' => 'utf8_general_ci', 'charset' => 'utf8'), - 'email' => array('type' => 'string', 'null' => false, 'length' => 60, 'collate' => 'utf8_general_ci', 'charset' => 'utf8'), - 'fk_id_mdp' => array('type' => 'string', 'null' => true, 'default' => null, 'length' => 32, 'key' => 'unique', 'collate' => 'utf8_general_ci', 'charset' => 'utf8'), - 'nom' => array('type' => 'string', 'null' => false, 'length' => 30, 'collate' => 'utf8_general_ci', 'charset' => 'utf8'), - 'prenom' => array('type' => 'string', 'null' => false, 'length' => 30, 'collate' => 'utf8_general_ci', 'charset' => 'utf8'), + public $clients = array( + 'id' => array('type' => 'string', 'null' => false, 'length' => 50, 'key' => 'primary'), + 'email' => array('type' => 'string', 'null' => false, 'length' => 255), + 'id_motdepasse' => array('type' => 'string', 'null' => true, 'length' => 255), + 'nom' => array('type' => 'string', 'null' => false, 'length' => 30), + 'prenom' => array('type' => 'string', 'null' => false, 'length' => 30), 'annee_de_naissance' => array('type' => 'text', 'null' => false, 'length' => 4), - 'adresse' => array('type' => 'string', 'null' => true, 'default' => null, 'length' => 30, 'collate' => 'utf8_general_ci', 'charset' => 'utf8'), - 'ville' => array('type' => 'string', 'null' => false, 'length' => 20, 'collate' => 'utf8_general_ci', 'charset' => 'utf8'), - 'pays' => array('type' => 'string', 'null' => false, 'length' => 20, 'collate' => 'utf8_general_ci', 'charset' => 'utf8'), - 'numero_tel' => array('type' => 'integer', 'null' => true, 'default' => null, 'length' => 20, 'unsigned' => false), + 'adresse' => array('type' => 'string', 'null' => true, 'default' => null, 'length' => 30), + 'codepostal' => array('type' => 'integer', 'null' => true, 'default' => null, 'length' => 10, 'unsigned' => false), + 'ville' => array('type' => 'string', 'null' => false, 'length' => 40), + 'pays' => array('type' => 'string', 'null' => false, 'length' => 20), + 'telephone' => array('type' => 'integer', 'null' => true, 'default' => null, 'length' => 20, 'unsigned' => false), + 'role' => array('type' => 'string', 'null' => false, 'length' => 20), + 'cree' => array('type' => 'date', 'null' => false), + 'modifie' => array('type' => 'date', 'null' => false), 'indexes' => array( - 'PRIMARY' => array('column' => 'identifiant', 'unique' => 1), - 'fk_id_mdp' => array('column' => 'fk_id_mdp', 'unique' => 1), - 'fk_id_mdp_2' => array('column' => 'fk_id_mdp', 'unique' => 1) + 'PRIMARY' => array('column' => 'id', 'unique' => 1) ), 'tableParameters' => array('charset' => 'utf8', 'collate' => 'utf8_general_ci', 'engine' => 'InnoDB') ); public $commande = array( - 'reference' => array('type' => 'integer', 'null' => false, 'default' => null, 'unsigned' => false, 'key' => 'primary'), + 'id' => array('type' => 'integer', 'null' => false, 'default' => null, 'unsigned' => false, 'key' => 'primary'), 'date_de_commande' => array('type' => 'date', 'null' => false, 'key' => 'index'), - 'fk_reference_produit' => array('type' => 'string', 'null' => false, 'length' => 20, 'collate' => 'utf8_general_ci', 'charset' => 'utf8'), - 'fk_reference_promotion' => array('type' => 'integer', 'null' => false, 'default' => '0', 'unsigned' => false), + 'id_produit' => array('type' => 'string', 'null' => false, 'length' => 20), + 'id_promotion' => array('type' => 'integer', 'null' => false, 'default' => '0', 'unsigned' => false), 'indexes' => array( - 'PRIMARY' => array('column' => 'reference', 'unique' => 1), + 'PRIMARY' => array('column' => 'id', 'unique' => 1), 'date_de_commande' => array('column' => 'date_de_commande', 'unique' => 0) ), 'tableParameters' => array('charset' => 'utf8', 'collate' => 'utf8_general_ci', 'engine' => 'InnoDB') ); public $compte = array( - 'fk_identifiant' => array('type' => 'string', 'null' => false, 'length' => 20, 'key' => 'primary', 'collate' => 'utf8_general_ci', 'charset' => 'utf8'), + 'id' => array('type' => 'string', 'null' => false, 'length' => 20, 'key' => 'primary'), 'nb_de_produits_achetes' => array('type' => 'integer', 'null' => true, 'default' => null, 'unsigned' => false, 'key' => 'index'), 'montant_d_achat_total' => array('type' => 'decimal', 'null' => false, 'default' => '0.0', 'length' => '6,1', 'unsigned' => false), 'date_ouverture_du_compte' => array('type' => 'date', 'null' => false), 'indexes' => array( - 'PRIMARY' => array('column' => 'fk_identifiant', 'unique' => 1), + 'PRIMARY' => array('column' => 'id', 'unique' => 1), 'nb_de_produits_achetes' => array('column' => array('nb_de_produits_achetes', 'montant_d_achat_total', 'date_ouverture_du_compte'), 'unique' => 0) ), 'tableParameters' => array('charset' => 'utf8', 'collate' => 'utf8_general_ci', 'engine' => 'InnoDB') @@ -97,30 +106,30 @@ public function after($event = array()) { public $articles = array( 'id' => array('type' => 'integer', 'null' => false, 'default' => null, 'unsigned' => false, 'key' => 'primary'), - 'entete' => array('type' => 'string', 'null' => false, 'length' => 250, 'collate' => 'utf8_general_ci', 'charset' => 'utf8'), - 'fk_reference_categorie' => array('type' => 'integer', 'null' => true, 'default' => null, 'unsigned' => false), - 'corps' => array('type' => 'text', 'null' => false, 'length' => 4, 'collate' => 'utf8_general_ci', 'charset' => 'utf8'), + 'entete' => array('type' => 'string', 'null' => false, 'length' => 250), + 'id_categorie' => array('type' => 'integer', 'null' => true, 'default' => null, 'unsigned' => false), + 'corps' => array('type' => 'text', 'null' => false, 'length' => 4), 'date' => array('type' => 'date', 'null' => false), - 'published' => array('type' => 'date', 'null' => false), - 'indexes' => array( + 'published' => array('type' => 'date', 'null' => false), + 'indexes' => array( 'PRIMARY' => array('column' => 'id', 'unique' => 1) ), 'tableParameters' => array('charset' => 'utf8', 'collate' => 'utf8_general_ci', 'engine' => 'InnoDB') ); public $disponibilite = array( - 'fk_id_produit' => array('type' => 'integer', 'null' => false, 'default' => '0', 'length' => 5, 'unsigned' => false, 'key' => 'primary'), - 'fk_reference_exemplaire' => array('type' => 'string', 'null' => false, 'length' => 20, 'key' => 'primary', 'collate' => 'utf8_general_ci', 'charset' => 'utf8'), + 'id' => array('type' => 'integer', 'null' => false, 'default' => '0', 'length' => 5, 'unsigned' => false, 'key' => 'primary'), + 'id_exemplaire' => array('type' => 'string', 'null' => false, 'length' => 20, 'key' => 'primary'), 'indexes' => array( - 'PRIMARY' => array('column' => array('fk_id_produit', 'fk_reference_exemplaire'), 'unique' => 1) + 'PRIMARY' => array('column' => array('id', 'id_exemplaire'), 'unique' => 1) ), 'tableParameters' => array('charset' => 'utf8', 'collate' => 'utf8_general_ci', 'engine' => 'InnoDB') ); public $editeur = array( - 'code_editeur' => array('type' => 'string', 'null' => false, 'length' => 4, 'key' => 'primary', 'collate' => 'utf8_general_ci', 'charset' => 'utf8'), + 'code_editeur' => array('type' => 'string', 'null' => false, 'length' => 4, 'key' => 'primary'), 'image' => array('type' => 'integer', 'null' => true, 'default' => null, 'length' => 5, 'unsigned' => false), - 'nom' => array('type' => 'string', 'null' => false, 'length' => 20, 'collate' => 'utf8_general_ci', 'charset' => 'utf8'), + 'nom' => array('type' => 'string', 'null' => false, 'length' => 20), 'indexes' => array( 'PRIMARY' => array('column' => 'code_editeur', 'unique' => 1) ), @@ -128,9 +137,9 @@ public function after($event = array()) { ); public $exemplaire = array( - 'code_reference' => array('type' => 'string', 'null' => false, 'length' => 20, 'key' => 'primary', 'collate' => 'utf8_general_ci', 'charset' => 'utf8'), + 'code_reference' => array('type' => 'string', 'null' => false, 'length' => 20, 'key' => 'primary'), 'date_de_livraison' => array('type' => 'date', 'null' => false), - 'fk_id_produit' => array('type' => 'integer', 'null' => false, 'default' => '0', 'length' => 5, 'unsigned' => false), + 'id' => array('type' => 'integer', 'null' => false, 'default' => '0', 'length' => 5, 'unsigned' => false), 'indexes' => array( 'PRIMARY' => array('column' => 'code_reference', 'unique' => 1) ), @@ -138,25 +147,25 @@ public function after($event = array()) { ); public $facture = array( - 'reference' => array('type' => 'string', 'null' => false, 'length' => 32, 'key' => 'primary', 'collate' => 'utf8_general_ci', 'charset' => 'utf8'), + 'reference' => array('type' => 'string', 'null' => false, 'length' => 32, 'key' => 'primary'), 'montant_facture' => array('type' => 'decimal', 'null' => true, 'default' => null, 'length' => '6,1', 'unsigned' => false), 'date_de_facturation' => array('type' => 'date', 'null' => false), - 'mode_de_paiement' => array('type' => 'string', 'null' => false, 'length' => 4, 'key' => 'index', 'collate' => 'utf8_general_ci', 'charset' => 'utf8'), - 'fk_identifiant' => array('type' => 'string', 'null' => false, 'length' => 20, 'collate' => 'utf8_general_ci', 'charset' => 'utf8'), + 'mode_de_paiement' => array('type' => 'string', 'null' => false, 'length' => 4, 'key' => 'index'), + 'id' => array('type' => 'string', 'null' => false, 'length' => 20), 'indexes' => array( 'PRIMARY' => array('column' => 'reference', 'unique' => 1), - 'mode_de_paiement' => array('column' => array('mode_de_paiement', 'fk_identifiant'), 'unique' => 0) + 'mode_de_paiement' => array('column' => array('mode_de_paiement', 'id'), 'unique' => 0) ), 'tableParameters' => array('charset' => 'utf8', 'collate' => 'utf8_general_ci', 'engine' => 'InnoDB') ); public $fournisseur = array( - 'code_fournisseur' => array('type' => 'string', 'null' => false, 'length' => 4, 'key' => 'primary', 'collate' => 'utf8_general_ci', 'charset' => 'utf8'), - 'nom' => array('type' => 'string', 'null' => false, 'length' => 30, 'key' => 'index', 'collate' => 'utf8_general_ci', 'charset' => 'utf8'), - 'adresse' => array('type' => 'string', 'null' => false, 'length' => 40, 'collate' => 'utf8_general_ci', 'charset' => 'utf8'), + 'code_fournisseur' => array('type' => 'string', 'null' => false, 'length' => 4, 'key' => 'primary'), + 'nom' => array('type' => 'string', 'null' => false, 'length' => 30, 'key' => 'index'), + 'adresse' => array('type' => 'string', 'null' => false, 'length' => 40), 'numero_tel' => array('type' => 'integer', 'null' => false, 'default' => '0', 'length' => 20, 'unsigned' => false), - 'ville' => array('type' => 'string', 'null' => false, 'length' => 15, 'collate' => 'utf8_general_ci', 'charset' => 'utf8'), - 'pays' => array('type' => 'string', 'null' => false, 'length' => 15, 'collate' => 'utf8_general_ci', 'charset' => 'utf8'), + 'ville' => array('type' => 'string', 'null' => false, 'length' => 15), + 'pays' => array('type' => 'string', 'null' => false, 'length' => 15), 'indexes' => array( 'PRIMARY' => array('column' => 'code_fournisseur', 'unique' => 1), 'nom' => array('column' => array('nom', 'ville', 'pays'), 'unique' => 0) @@ -166,10 +175,10 @@ public function after($event = array()) { public $image = array( 'id' => array('type' => 'integer', 'null' => false, 'default' => null, 'unsigned' => false, 'key' => 'primary'), - 'nom' => array('type' => 'string', 'null' => true, 'default' => null, 'length' => 250, 'collate' => 'utf8_general_ci', 'charset' => 'utf8'), + 'nom' => array('type' => 'string', 'null' => true, 'default' => null, 'length' => 250), 'image' => array('type' => 'mediumbinary', 'null' => false, 'default' => null), - 'mime' => array('type' => 'string', 'null' => false, 'default' => 'image/png', 'length' => 250, 'collate' => 'utf8_general_ci', 'charset' => 'utf8'), - 'description' => array('type' => 'text', 'null' => true, 'default' => null, 'collate' => 'utf8_general_ci', 'charset' => 'utf8'), + 'mime' => array('type' => 'string', 'null' => false, 'default' => 'image/png', 'length' => 250), + 'description' => array('type' => 'text', 'null' => true, 'default' => null), 'indexes' => array( 'PRIMARY' => array('column' => 'id', 'unique' => 1) ), @@ -179,13 +188,13 @@ public function after($event = array()) { public $info = array( 'id' => array('type' => 'integer', 'null' => false, 'default' => null, 'unsigned' => false, 'key' => 'primary'), 'categorie' => array('type' => 'integer', 'null' => true, 'default' => null, 'unsigned' => false), - 'titre' => array('type' => 'text', 'null' => false, 'default' => null, 'collate' => 'utf8_general_ci', 'charset' => 'utf8'), - 'auteur' => array('type' => 'string', 'null' => false, 'length' => 250, 'collate' => 'utf8_general_ci', 'charset' => 'utf8'), - 'contenu' => array('type' => 'text', 'null' => false, 'default' => null, 'collate' => 'utf8_general_ci', 'charset' => 'utf8'), - 'langue' => array('type' => 'string', 'null' => false, 'length' => 32, 'collate' => 'utf8_general_ci', 'charset' => 'utf8'), + 'titre' => array('type' => 'text', 'null' => false, 'default' => null), + 'auteur' => array('type' => 'string', 'null' => false, 'length' => 250), + 'contenu' => array('type' => 'text', 'null' => false, 'default' => null), + 'langue' => array('type' => 'string', 'null' => false, 'length' => 32), 'date' => array('type' => 'date', 'null' => false), 'published' => array('type' => 'date', 'null' => false), - 'images' => array('type' => 'string', 'null' => true, 'default' => null, 'length' => 35, 'collate' => 'utf8_general_ci', 'charset' => 'utf8'), + 'images' => array('type' => 'string', 'null' => true, 'default' => null, 'length' => 35), 'indexes' => array( 'PRIMARY' => array('column' => 'id', 'unique' => 1) ), @@ -194,9 +203,9 @@ public function after($event = array()) { public $messages = array( 'id' => array('type' => 'integer', 'null' => false, 'default' => null, 'unsigned' => false, 'key' => 'primary'), - 'titre' => array('type' => 'string', 'null' => false, 'length' => 250, 'collate' => 'utf8_general_ci', 'charset' => 'utf8'), - 'texte' => array('type' => 'text', 'null' => false, 'default' => null, 'collate' => 'utf8_general_ci', 'charset' => 'utf8'), - 'pseudo' => array('type' => 'string', 'null' => false, 'length' => 250, 'collate' => 'utf8_general_ci', 'charset' => 'utf8'), + 'titre' => array('type' => 'string', 'null' => false, 'length' => 250), + 'texte' => array('type' => 'text', 'null' => false, 'default' => null), + 'id_client' => array('type' => 'string', 'null' => false, 'length' => 255), 'date' => array('type' => 'date', 'null' => false), 'indexes' => array( 'PRIMARY' => array('column' => 'id', 'unique' => 1), @@ -205,21 +214,24 @@ public function after($event = array()) { 'tableParameters' => array('charset' => 'utf8', 'collate' => 'utf8_general_ci', 'engine' => 'InnoDB') ); - public $motdepasse = array( - 'id_unique' => array('type' => 'string', 'null' => false, 'length' => 32, 'key' => 'primary', 'collate' => 'utf8_general_ci', 'charset' => 'utf8'), - 'motdepasse' => array('type' => 'string', 'null' => false, 'length' => 8, 'collate' => 'utf8_general_ci', 'charset' => 'utf8'), + public $motdepasses = array( + 'id' => array('type' => 'integer', 'null' => false, 'default' => null, 'unsigned' => false, 'key' => 'primary', 'autoIncrement' => true), + 'password' => array('type' => 'string', 'null' => false, 'length' => 255), + 'password_confirm' => array('type' => 'string', 'null' => false, 'length' => 255), + 'cree' => array('type' => 'date', 'null' => false), + 'modifie' => array('type' => 'date', 'null' => false), 'indexes' => array( - 'PRIMARY' => array('column' => 'id_unique', 'unique' => 1) + 'PRIMARY' => array('column' => 'id', 'unique' => 1) ), 'tableParameters' => array('charset' => 'utf8', 'collate' => 'utf8_general_ci', 'engine' => 'InnoDB') ); public $php4u_bookmarks = array( 'id' => array('type' => 'integer', 'null' => false, 'default' => null, 'length' => 10, 'unsigned' => true, 'key' => 'primary'), - 'dbase' => array('type' => 'string', 'null' => false, 'length' => 128, 'collate' => 'utf8_general_ci', 'charset' => 'utf8'), - 'user' => array('type' => 'string', 'null' => false, 'length' => 128, 'collate' => 'utf8_general_ci', 'charset' => 'utf8'), - 'label' => array('type' => 'string', 'null' => false, 'length' => 128, 'collate' => 'utf8_general_ci', 'charset' => 'utf8'), - 'query' => array('type' => 'text', 'null' => false, 'default' => null, 'collate' => 'utf8_general_ci', 'charset' => 'utf8'), + 'dbase' => array('type' => 'string', 'null' => false, 'length' => 128), + 'user' => array('type' => 'string', 'null' => false, 'length' => 128), + 'label' => array('type' => 'string', 'null' => false, 'length' => 128), + 'query' => array('type' => 'text', 'null' => false, 'default' => null), 'indexes' => array( 'PRIMARY' => array('column' => 'id', 'unique' => 1) ), diff --git a/app/Config/boot_profile.cms.php b/app/Config/boot_profile.cms.php index a059a8c05..ec2a18af8 100644 --- a/app/Config/boot_profile.cms.php +++ b/app/Config/boot_profile.cms.php @@ -2,7 +2,7 @@ /*var_dump(App::path('Cms'));*/ /* -- PHP AUTOLOAD Load Composer autoload.*/ -require APP . 'Vendor' . DS . 'autoload.php'; +include APP . 'Vendor' . DS . 'autoload.php'; /* Remove and re-prepend CakePHP's autoloader as Composer thinks it is the most important. See: http://goo.gl/kKVJO7 */ @@ -14,7 +14,7 @@ and is even quicker than a semantically equal self-defined autoload function like this one */ App::build(array( - 'Cms' => array(WWW_ROOT . 'php_cms' . DS . 'e13' . DS . 'include' . DS) + 'Cms' => array(WWW_ROOT . 'php-cms' . DS . 'e13' . DS . 'include' . DS) ), App::REGISTER); /** * Load DebugKit plugin @@ -24,4 +24,13 @@ /** * Load Markdown Plugin */ + CakePlugin::load(array('Markdown' => array('bootstrap' => true))); +/** + * Load UpdateShell Plugin + */ +CakePlugin::load('UpdateShell'); +/** + * Load DataSources Plugin + */ +CakePlugin::load('Datasources'); diff --git a/app/Config/core.php b/app/Config/core.php index 3704abc0d..4bdf9ff85 100755 --- a/app/Config/core.php +++ b/app/Config/core.php @@ -47,7 +47,7 @@ function make_secure_key($args) { } // Convert the hash to an int to seed the RNG - srand(hexdec(substr($hash,0,8))); + srand((int)(float)hexdec(substr($hash,0,8))); // Create a random string the same length as the default $val = ''; for($i = 1; $i <= strlen($original); $i++){ diff --git a/app/Config/database.cms.php b/app/Config/database.php similarity index 100% rename from app/Config/database.cms.php rename to app/Config/database.php diff --git a/app/Config/email.php b/app/Config/email.php new file mode 100644 index 000000000..132c32b0f --- /dev/null +++ b/app/Config/email.php @@ -0,0 +1,28 @@ + 'Mail', + 'from' => 'webmaster@localhost', + //'charset' => 'utf-8', + //'headerCharset' => 'utf-8', + ); + public $gmail = array( + 'host' => 'smtp.gmail.com', + 'port' => 465, + 'username' => 'my@gmail.com', + 'password' => 'secret', + 'transport' => 'Smtp', + 'tls' => true + ); + public function __construct() { + $this->default['from'] = getenv('SERVER_NAME') ? 'no-reply@' . getenv('SERVER_NAME') : $this->default['from']; + } +} + ?> diff --git a/app/Config/routes.php b/app/Config/routes.php index fc2215d62..14b15f3f3 100755 --- a/app/Config/routes.php +++ b/app/Config/routes.php @@ -29,6 +29,30 @@ * views are prefixed with "admin/" => admin_action() */ Router::connect('/admin/e14/:action/*', array('controller' => 'e14', 'admin' => true)); +/** + *************************************************** ArticleController routing + * the one star(*) wildcard is for one-to-one passed arguments separated by the slash '/' + */ +Router::connect('/users/psd/:action/*', array('controller' => 'MotDePasse')); +/** + * the two stars(**) wildcard is for many-to-one argument passed as a whole string + */ +Router::connect('/users/psd/**', array('controller' => 'MotDePasse', 'action' => 'index')); +/** + */ +Router::connect('/admin/users/psd/:action/*', array('controller' => 'MotDePasse', 'admin' => true)); +/** + *************************************************** ArticleController routing + * the one star(*) wildcard is for one-to-one passed arguments separated by the slash '/' + */ +Router::connect('/users/:action/*', array('controller' => 'client')); +/** + * the two stars(**) wildcard is for many-to-one argument passed as a whole string + */ +Router::connect('/users/**', array('controller' => 'client', 'action' => 'index')); +/** + */ +Router::connect('/admin/users/:action/*', array('controller' => 'client', 'admin' => true)); /** *************************************************** ArticleController routing * the one star(*) wildcard is for one-to-one passed arguments separated by the slash '/' @@ -54,7 +78,7 @@ */ Router::connect('/admin/contactus/:action/*', array('controller' => 'message', 'admin' => true)); /** - *************************************************** default routing + *************************************************** default routing */ Router::connect('/admin/*', array('controller' => 'e14', 'action' => 'index', 'admin' => true)); /** @@ -67,7 +91,7 @@ Router::connect('/', array('controller' => 'e14', 'action' => 'index')); -/* all URLs /(somename).php parsed to (somename) as :action or passed argument e.g. index/image.php => e14/index/_image => _image.php as included script */ +/* all URLs /(somename).php parsed to (somename) as :action or passed argument e.g. index/_image.php => e14/index/_image => _image.php as included script */ Router::parseExtensions('php'); /** * Load all plugin routes. See the CakePlugin documentation on @@ -79,5 +103,4 @@ * Load the CakePHP default routes. Only remove this if you do not want to use * the built-in default routes. * */ -require CAKE . 'Config' . DS . 'routes.php'; - +include CAKE . 'Config' . DS . 'routes.php'; diff --git a/app/Controller/AppController.php b/app/Controller/AppController.php index 00d8e8f36..49e4da5a4 100755 --- a/app/Controller/AppController.php +++ b/app/Controller/AppController.php @@ -21,7 +21,7 @@ */ App::uses('Controller', 'Controller'); App::uses('Index', 'Cms'); - +App::uses('AuthComponent', 'Controller/Component/'); /** * Application Controller * @@ -38,25 +38,62 @@ class AppController extends Controller { */ public $components = array('DebugKit.Toolbar', 'Flash' => array( - 'className' => 'MyFlash')); + 'className' => 'MyFlash' + ), + 'Auth' => array( + 'loginRedirect' => array('controller' => 'clients', 'action' => 'index'), + 'logoutRedirect' => array('controller' => 'e14', 'action' => 'index'), + 'authError' => "Veuillez vous authentifier, s'il-vous-plaît.", + 'authenticate' => array( + AuthComponent::ALL => array( + 'userModel' => 'Client', + 'fields' => array( + 'username' => 'id', // 'username' par défaut + 'password' => 'id_motdepasse' // 'password' par défaut + ) + ), + 'Basic', + 'Form' + ), + 'authorize' => array('Controller') + ) + ); + + /** Gestion simple des acces controlés par role. Un 'controller' dépendant de cette méthode pour + * définir l'autorisation Client pour une action donnée + */ + public function isAuthorized($user) { + /* Admin peut accéder à toute action */ + if (isset($user['role']) && $user['role'] === 'admin') { + return true; + } + + /* Refus par défaut */ + return false; + } public $helpers = array('Info' => array( 'index' => null, 'countPerPage' => '10', 'md' => true - ), 'Markdown.Markdown' => true, 'Form', 'Html', 'Js', 'Time', 'Flash'); + ), 'Markdown.Markdown' => true, 'Text', 'Form', 'Html', 'Js', 'Time', 'Flash'); protected $_r; public function __construct($request = null, $response = null) { parent::__construct($request, $response); /* initialise les $GLOBALS et le sitemap */ - $this->_r = new Index($this->View, APP . 'index.php', true, WWW_ROOT . 'php_cms'); + $this->_r = new Index($this->View, APP . 'index.php', true, WWW_ROOT . 'php-cms'); $this->helpers['Info']['index'] = $this->_r; $this->set("r", $this->_r); } public function beforeFilter() { + parent::beforeFilter(); /* internationalisation (i18n) */ Configure::write('Config.language', $this->_r->getLanguage()); + /* AuthComponent de ne pas exiger un login pour toutes les actions index et view*/ + $this->Auth->allow( + 'index', + 'view'); } /** diff --git a/app/Controller/ArticleController.php b/app/Controller/ArticleController.php index 8e29bb290..c8a9fab30 100644 --- a/app/Controller/ArticleController.php +++ b/app/Controller/ArticleController.php @@ -40,11 +40,11 @@ function publierImages() { ) ); - public function index($fk_reference_categorie = null) { - if ($fk_reference_categorie === null) { + public function index($id__categorie = null) { + if ($id__categorie === null) { $this->set('articles', $this->Article->find('all')); } else { - $this->set('articles', $this->Article->find($fk_reference_categorie)); + $this->set('articles', $this->Article->find($id__categorie)); } $this->set("pIndex", "activites__index"); $this->render(null, "default-e14"); diff --git a/app/Controller/ClientController.php b/app/Controller/ClientController.php new file mode 100644 index 000000000..3fea9ee28 --- /dev/null +++ b/app/Controller/ClientController.php @@ -0,0 +1,159 @@ +Auth->allow('add', 'logout'); + } + + public function admin_login() { + $this->Auth->redirectUrl(array('action' => 'index', 'admin' => true)); + return $this->redirect(array('action' => 'login', 'admin' => false)); + } + public function login() { + if ($this->request->is('post')) { + if ($this->Auth->login()) { + return $this->redirect($this->Auth->redirectUrl()); + } else { + $this->Flash->error(__("Invalid username or password")); + } + } + $this->set('pIndex', 'users__login'); + $this->render(null, 'default-e14'); + } + + public function admin_logout() { + return $this->redirect(array('action' => 'logout', 'admin' => false)); + } + public function logout() { + return $this->redirect($this->Auth->logout()); + } + + public function index() { + $this->set('pIndex', 'users__index'); + $this->render(null, 'default-e14'); + } + + public function admin_index() { + $this->Client->recursive = 0; + $this->set('clients', $this->paginate()); + $this->set('pIndex', 'users__adminindex'); + $this->render(null, 'admin_default-e14'); + } + + public function admin_view($id = 0) { + return $this->redirect(array('action' => 'view', 'admin' => false, $id)); + } + public function view($id = 0) { + if (!$id) { + return $this->redirect(array("action" => "index")); + } + if (!$this->Client->exists($id)) { + throw new NotFoundException(__('Invalid username')); + } + $this->set('client', $this->Client->findById($id)); + $this->set('pIndex', 'users__view'); + $this->render(null, 'default-e14'); + } + public function admin_add() { + return $this->redirect(array('action' => 'add', 'admin' => false)); + } + public function add() { + if ($this->request->is('post')) { + $this->Client->create(); + if ($this->Client->save($this->request->data)) { + $this->Flash->success(__('Subscription success')); + $id = $this->Client->id; + $this->request->data['Client'] = array_merge( + $this->request->data['Client'], + array('id' => $id) + ); + /* Desaffectaction du 'password' en requete, + pour éviter la sauvegarde en session en clair du mot de passe en appelant login. + unset($this->request->data['Client']['id_motdepasse']);*/ + $this->Auth->login($this->request->data['Client']); + /* Le mot de passe sera cree ensuite */ + return $this->redirect(array('controller' => 'MotDePasse', 'action' => 'add', $id)); + } else { + $this->Flash->error(__('Failed to subscribe. Please try again')); + } + } + $this->set('pIndex', 'users__add'); + $this->render(null, 'default-e14'); + } + public function admin_edit($id = null, $id_motdepasse = null) { + return $this->redirect(array('action' => 'edit', 'admin' => false, $id, $id_motdepasse)); + } + public function edit($id = null, $id_motdepasse = null) { + $this->Client->id = $id; + if (!$this->Client->exists()) { + throw new NotFoundException(__('Invalid username')); + } + if(isset($id_motdepasse)) { + $this->Client->id_motdepasse = $id_motdepasse; + } + if ($this->request->is('post') || $this->request->is('put')) { + if ($this->Client->save($this->request->data)) { + $this->Flash->success(__('Saved changes success!')); + return $this->redirect(array('action' => 'index')); + } else { + $this->Flash->error(__('Failed to save changes. Please try again')); + } + } else { + $this->request->data = $this->Client->findById($id); + /* Desaffectaction du 'password' en requete, + pour éviter la sauvegarde en session en clair du mot de passe en appelant login. */ + unset($this->request->data['Client']['id_motdepasse']); + } + $this->set('pIndex', 'users__edit'); + $this->render(null, 'default-e14'); + } + public function admin_delete($id = null) { + return $this->redirect(array('action' => 'delete', 'admin' => false)); + } + + public function delete($id = null) { + // Avant 2.5, utilisez + // $this->request->onlyAllow('post'); + + $this->request->allowMethod('post'); + + $this->Client->id = $id; + if (!$this->Client->exists()) { + throw new NotFoundException(__('Invalid username')); + } + if ($this->Client->delete()) { + $this->Flash->success(__('Subscription was removed')); + return $this->redirect(array('action' => 'index')); + } + $this->Flash->error(__('Subscription could NOT be removed')); + return $this->redirect(array('action' => 'index')); + } + + public function admin_recovery() { + return $this->redirect(array('action' => 'recovery', 'admin' => false)); + } + public function recovery() { + $this->set('client', $this->Client); + $Email = new CakeEmail(); + $Email->helpers(array('Html', 'Text')); + /* app/view/Emails*/ + $Email->template('recovery', 'default') + ->emailFormat('html') + ->to($this->Client->email) + ->send(); + } + +} +?> diff --git a/app/Controller/Component/MyFlashComponent.php b/app/Controller/Component/MyFlashComponent.php index d02e30b14..bf6f59750 100644 --- a/app/Controller/Component/MyFlashComponent.php +++ b/app/Controller/Component/MyFlashComponent.php @@ -31,18 +31,23 @@ public function beforeRender(Controller $controller) { public function shutDown(Controller $controller) { parent::shutdown($controller); - + } public function beforeRedirect(Controller $controller, $url, $status = null, $exit = true) { parent::beforeRedirect($controller, $url, $status, $exit); } - - public function success($message) { + + public function success($message) { $this->set($message, array('params' => array('class' => 'success'))); } - + public function error($message) { $this->set($message, array('params' => array('class' => 'error'))); } + + public function notice($message) { + $this->set($message, array('params' => array('class' => 'notice'))); + } + } diff --git a/app/Controller/E14Controller.php b/app/Controller/E14Controller.php index b76c4e223..4da7d1f39 100644 --- a/app/Controller/E14Controller.php +++ b/app/Controller/E14Controller.php @@ -19,6 +19,11 @@ class E14Controller extends AppController { public function __construct($request = null, $response = null) { parent::__construct($request, $response); + $route = Router::currentRoute(); + i_debug($route); + } + public function beforeFilter() { + $this->Auth->allow(); } /** @param string $p page filename.php (optional) */ diff --git a/app/Controller/EmailsController.php b/app/Controller/EmailsController.php index 975a2f279..9f7981db0 100644 --- a/app/Controller/EmailsController.php +++ b/app/Controller/EmailsController.php @@ -22,7 +22,7 @@ public function index($id) { } public function send() { - if (empty($this->request->data) || $this->params['requested']) { + if (empty($this->request->data) || $this->request->params['requested']) { $post_email = $this->request->data('Email'); if (!$post_email) { $post_email = array( @@ -33,11 +33,11 @@ public function send() { }; $this->set($post_email); /** continues to render send.ctp ... */ - if ($this->params['requested']) { + if ($this->request->params['requested']) { return $this->render()->body(); } } else { - if ($this->params['requested']) { + if ($this->request->params['requested']) { trigger_error("Illegal request"); } else { $post_email = $this->request->data('Email'); diff --git a/app/Controller/MessageController.php b/app/Controller/MessageController.php index b41e5e72f..9f4ef0c92 100644 --- a/app/Controller/MessageController.php +++ b/app/Controller/MessageController.php @@ -11,11 +11,15 @@ */ class MessageController extends AppController { - public function index($fk_identifiant = null) { - if ($fk_identifiant === null) { + public function __construct($request = null, $response = null) { + parent::__construct($request, $response); + } + + public function index($id = null) { + if ($id === null) { $this->set('messages', $this->Message->find('all')); } else { - $this->set('messages', $this->Message->find($fk_identifiant)); + $this->set('messages', $this->Message->find($id)); } $this->set("pIndex","contactus__index"); $this->render(null, "default-e14"); @@ -25,8 +29,6 @@ public function index($fk_identifiant = null) { * @param String $p method name */ public function admin_index($p = null) { - //debug($this->request->params); - //debug($GLOBALS); $this->set('pIndex', 'admin__contactus'); $this->set('pMethod', $p); $this->render(null, "default-e14"); @@ -49,15 +51,80 @@ public function view($id) { public function add($id = null) { if (empty($this->request->data)) { $this->request->data = $this->Message->findById($id); - } else { - /* sauvegarde du message */ - require APP . $r->r['include__php_constantes.inc']; - /* ajouter dans la base de donnees */ - $sql = new SQL(SERVEUR, BASE, CLIENT, CLIENT_MDP); - } + } else if ($this->request->is('post')) { + $this->Message->create(); + $this->request->data['Message']['id'] = $this->Auth->user('id'); + if ($this->Message->save($this->request->data)) { + $this->Flash->success(__('Message posted')); + return $this->redirect(array('action' => 'index')); + } + $this->Flash->error(__('Unable to post the message')); + } $this->set("pIndex","contactus__write"); $this->render(null, "default-e14"); } + + public function edit($id = null) { + if (!$id) { +/* throw new NotFoundException(__('Invalid message'));*/ + return $this->redirect(array('action' => 'add')); + } + + $post = $this->Message->findById($id); + if (!$post) { + throw new NotFoundException(__('Invalid message')); + } + + if ($this->request->is(array('post', 'put'))) { + $this->Message->id = $id; + if ($this->Message->save($this->request->data)) { + $this->Flash->success(__('Message was successfully updated')); + return $this->redirect(array('action' => 'index')); + } + $this->Flash->error(__('Impossible to modify the message')); + } + + if (!$this->request->data) { + $this->request->data = $post; + } + $this->set("pIndex","contactus__edit"); + $this->render(null, "default-e14"); +} + public function delete($id) { + /* devier les requetes delete?id= */ + if ($this->request->is('get')) { + throw new MethodNotAllowedException(); + } + + if ($this->Message->delete($id)) { + $this->Flash->success( + __('Message %s was successfully removed.', h($id)) + ); + } else { + $this->Flash->error( + __('Message %s could NOT be removed', h($id)) + ); + } + + return $this->redirect(array('action' => 'index')); + } + + public function isAuthorized($client) { + /* Tous les users inscrits peuvent ajouter les posts */ + if ($this->action === 'add') { + return true; + } + + /* Le propriétaire du post peut l'éditer et le supprimer */ + if (in_array($this->action, array('edit', 'delete'))) { + $messageId = (int) $this->request->params['pass'][0]; + if ($this->Message->isOwnedBy($messageId, $client['id'])) { + return true; + } + } + + return parent::isAuthorized($client); + } } ?> diff --git a/app/Controller/MotDePasseController.php b/app/Controller/MotDePasseController.php new file mode 100644 index 000000000..6504e03c9 --- /dev/null +++ b/app/Controller/MotDePasseController.php @@ -0,0 +1,107 @@ +Auth->allow('add', 'delete'); + } + + public function index() { + $this->set('pIndex', 'users__index'); + $this->render(null, 'default-e14'); + } + public function add($id = null) { + if ($this->request->is('post')) { + $this->MotDePasse->create(); + if ($this->MotDePasse->save($this->request->data)) { + $this->Flash->success(__('Password was NOT saved')); + if(!isset($id)) { + $id = $this->Auth->user('id'); + } + $client = Client::findById($id); + $this->Flash->message(__('Subscription saving %s...', $client)); + /* Desaffectaction du 'password' en requete, + pour éviter la sauvegarde en session en clair du mot de passe en appelant login. */ + unset($this->request->data['MotDePasse']['password']); + unset($this->request->data['MotDePasse']['password_confirm']); + if($client !== false) { + return $this->redirect(array('controller' => 'Client', 'action' => 'edit', $id, $this->MotDePasse->id)); + } else { + return $this->redirect(array('controller' => 'MotDePasse', 'action' => 'index')); + } + } else { + $this->Flash->error(__('Password could NOT be saved. Please try again')); + } + } + $this->set('pIndex', 'users__add'); + $this->render(null, 'default-e14'); + } + + public function edit($id = null, $id = null) { + $this->MotDePasse->id = $id; + if (!$this->MotDePasse->exists()) { + throw new NotFoundException(__('Invalid password')); + } + if ($this->request->is('post') || $this->request->is('put')) { + if(!isset($id)) { + $id = $this->Auth->user('id'); + } + $client = Client::findById($id); + if ($client !== false && $client->isOwnedBy($this->MotDePasse->id, $id) && $this->MotDePasse->save($this->request->data)) { + $this->Flash->success(__('Password was saved')); + return $this->redirect(array('action' => 'index')); + } else { + $this->Flash->error(__('Password could NOT be saved. Please try again')); + } + } else { + $this->request->data = $this->MotDePasse->findById($id); + unset($this->request->data['MotDePasse']['password']); + unset($this->request->data['MotDePasse']['password_confirm']); + } + $this->set('pIndex', 'users__edit'); + $this->render(null, 'default-e14'); + } + + public function delete($id = null, $id = null) { + // Avant 2.5, utilisez + // $this->request->onlyAllow('post'); + + $this->request->allowMethod('post', 'put'); + + $this->MotDePasse->id = $id; + if (!$this->MotDePasse->exists()) { + throw new NotFoundException(__('Invalid password')); + } + if(!isset($id)) { + $id = $this->Auth->user('id'); + } + $client = Client::findById($id); + if ($client !== false && $client->isOwnedBy($this->MotDePasse->id, $id) && $this->MotDePasse->delete()) { + $this->Flash->success(__('Password was removed')); + return $this->redirect(array('action' => 'add', $id)); + } + if(!$client) { + $this->Flash->error(__("Invalid '%s' subscription", $id)); + } else { + $this->Flash->error(__("Subscription '%s' doesn\'t match the password", $id)); + } + $this->Flash->error(__('Password could NOT be removed')); + return $this->redirect(array('action' => 'index')); + } +} diff --git a/app/Locale/article.pot b/app/Locale/article.pot index 6195f8242..a578450bf 100644 --- a/app/Locale/article.pot +++ b/app/Locale/article.pot @@ -13,28 +13,104 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n" -#: View/Article/add.ctp:3 +#: Controller/ArticleController.php:70;97;102 +msgid "Invalid article" +msgstr "" + +#: Controller/ArticleController.php:85 +msgid "Your article has been saved." +msgstr "" + +#: Controller/ArticleController.php:89 +msgid "Unable to add your article." +msgstr "" + +#: Controller/ArticleController.php:109 +msgid "Your article has been updated." +msgstr "" + +#: Controller/ArticleController.php:113 +msgid "Unable to update your article." +msgstr "" + +#: Controller/ArticleController.php:130 +msgid "Article with id : %s was deleted." +msgstr "" + +#: Controller/ArticleController.php:134 +msgid "Article with id: %s couldn't be deleted." +msgstr "" + +#: View/Article/add.ctp:9 +msgid "Upload some images" +msgstr "" + +#: View/Article/add.ctp:15;20 +#: View/Article/edit.ctp:11;16 +msgid "Upload" +msgstr "" + +#: View/Article/add.ctp:17 +#: View/Article/edit.ctp:13 +msgid "file format image/%s" +msgstr "" + +#: View/Article/add.ctp:24 #: View/Article/index.ctp:22 msgid "Add an article" msgstr "" -#: View/Article/add.ctp:6 +#: View/Article/add.ctp:26 +#: View/Article/edit.ctp:22 msgid "Header" msgstr "" -#: View/Article/add.ctp:7 +#: View/Article/add.ctp:27 +#: View/Article/edit.ctp:23 msgid "Published" msgstr "" -#: View/Article/add.ctp:8 +#: View/Article/add.ctp:28 +#: View/Article/edit.ctp:24 msgid "Body" msgstr "" -#: View/Article/add.ctp:9 -msgid "Created" +#: View/Article/add.ctp:30 +msgid "Save and continue with images" +msgstr "" + +#: View/Article/add.ctp:15 +#: View/Article/edit.ctp:11 +msgid "%s image" +msgid_plural "images" +msgstr[0] "" +msgstr[1] "" + +#: View/Article/edit.ctp:8 +msgid "Upload more images" +msgstr "" + +#: View/Article/edit.ctp:20 +msgid "Edit an article" +msgstr "" + +#: View/Article/edit.ctp:26 +msgid "Save this article" +msgstr "" + +#: View/Article/index.ctp:4 +msgid "db_articles" +msgstr "" + +#: View/Article/index.ctp:5 +msgid "categorie" +msgstr "" + +#: View/Article/index.ctp:5 +msgid "article" msgstr "" -#: View/Article/add.ctp:10 -msgid "Save an article" +#: View/Article/index.ctp:5 +msgid "published" msgstr "" diff --git a/app/Locale/cake.pot b/app/Locale/cake.pot index 0d4558b14..9579672fc 100644 --- a/app/Locale/cake.pot +++ b/app/Locale/cake.pot @@ -15,6 +15,8 @@ msgstr "" #: View/Errors/error400.ctp:10 #: View/Errors/error500.ctp:10 +#: View/Errors/missing_connection.ctp:2 +#: View/Errors/missing_datasource_config.ctp:2 msgid "Error" msgstr "" diff --git a/app/Locale/cake_dev.pot b/app/Locale/cake_dev.pot index 4a7ee1225..d153a679b 100644 --- a/app/Locale/cake_dev.pot +++ b/app/Locale/cake_dev.pot @@ -19,6 +19,7 @@ msgstr "" #: Plugin/Markdown/View/Errors/missing_markdown.ctp:3;7 #: View/Errors/fatal_error.ctp:19 +#: View/Errors/pdo_error.ctp:19 msgid "Error" msgstr "" @@ -50,6 +51,18 @@ msgstr "" msgid "Line" msgstr "" +#: View/Errors/pdo_error.ctp:17 +msgid "Database Error" +msgstr "" + +#: View/Errors/pdo_error.ctp:24 +msgid "SQL Query" +msgstr "" + +#: View/Errors/pdo_error.ctp:29 +msgid "SQL Query Params" +msgstr "" + #: View/Layouts/default.ctp:8 #: View/Layouts/error.ctp:8 msgid "CakePHP: the rapid development php framework" diff --git a/app/Locale/cms.pot b/app/Locale/cms.pot new file mode 100644 index 000000000..cc8133990 --- /dev/null +++ b/app/Locale/cms.pot @@ -0,0 +1,30 @@ +# LANGUAGE translation of CakePHP Application +# Copyright YEAR NAME +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PROJECT VERSION\n" +"PO-Revision-Date: YYYY-mm-DD HH:MM+ZZZZ\n" +"Last-Translator: NAME \n" +"Language-Team: LANGUAGE \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n" + +#: View/Errors/missing_connection.ctp:5 +#: View/Errors/missing_datasource_config.ctp:5 +msgid "Please review your configuration file " +msgstr "" + +#: View/Errors/missing_connection.ctp:6 +#: View/Errors/missing_datasource_config.ctp:6 +#: View/Errors/pdo_error.ctp:33 +msgid "In a server shell prompt" +msgstr "" + +#: View/Errors/pdo_error.ctp:32 +msgid "Please review your configuration (" +msgstr "" + diff --git a/app/Locale/debug_kit.pot b/app/Locale/debug_kit.pot index 8f5b6f066..a845d6b01 100644 --- a/app/Locale/debug_kit.pot +++ b/app/Locale/debug_kit.pot @@ -13,31 +13,31 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n" -#: Plugin/DebugKit/Console/Command/BenchmarkShell.php:41 +#: Plugin/DebugKit/Console/Command/BenchmarkShell.php:38 msgid "-> Testing :url" msgstr "" -#: Plugin/DebugKit/Console/Command/BenchmarkShell.php:67 +#: Plugin/DebugKit/Console/Command/BenchmarkShell.php:64 msgid "Total Requests made: :requests" msgstr "" -#: Plugin/DebugKit/Console/Command/BenchmarkShell.php:68 +#: Plugin/DebugKit/Console/Command/BenchmarkShell.php:65 msgid "Total Time elapsed: :duration (seconds)" msgstr "" -#: Plugin/DebugKit/Console/Command/BenchmarkShell.php:72 +#: Plugin/DebugKit/Console/Command/BenchmarkShell.php:69 msgid "Requests/Second: :rps req/sec" msgstr "" -#: Plugin/DebugKit/Console/Command/BenchmarkShell.php:76 +#: Plugin/DebugKit/Console/Command/BenchmarkShell.php:73 msgid "Average request time: :average-time seconds" msgstr "" -#: Plugin/DebugKit/Console/Command/BenchmarkShell.php:80 +#: Plugin/DebugKit/Console/Command/BenchmarkShell.php:77 msgid "Standard deviation of average request time: :std-dev" msgstr "" -#: Plugin/DebugKit/Console/Command/BenchmarkShell.php:84 +#: Plugin/DebugKit/Console/Command/BenchmarkShell.php:81 msgid "Longest/shortest request: :longest sec/:shortest sec" msgstr "" @@ -54,7 +54,7 @@ msgid "Number of iterations to perform." msgstr "" #: Plugin/DebugKit/Console/Command/BenchmarkShell.php:148 -msgid "Maximum total time for all iterations, in seconds.If a single iteration takes more than the tiemout, only one request will be made" +msgid "Maximum total time for all iterations, in seconds.If a single iteration takes more than the timeout, only one request will be made" msgstr "" #: Plugin/DebugKit/Console/Command/BenchmarkShell.php:152 @@ -89,19 +89,19 @@ msgstr "" msgid "Could not load DebugToolbar panel %s" msgstr "" -#: Plugin/DebugKit/Lib/DebugTimer.php:133 +#: Plugin/DebugKit/Lib/DebugTimer.php:127 msgid "Core Processing (Derived from $_SERVER[\"REQUEST_TIME\"])" msgstr "" -#: Plugin/DebugKit/Lib/FireCake.php:315 +#: Plugin/DebugKit/Lib/FireCake.php:309 msgid "Headers already sent in %s on line %s. Cannot send log data to FirePHP." msgstr "" -#: Plugin/DebugKit/Lib/FireCake.php:336 +#: Plugin/DebugKit/Lib/FireCake.php:330 msgid "Incorrect parameter count for FireCake::fb()" msgstr "" -#: Plugin/DebugKit/Lib/FireCake.php:415 +#: Plugin/DebugKit/Lib/FireCake.php:409 msgid "Maximum number (99,999) of messages reached!" msgstr "" @@ -109,19 +109,19 @@ msgstr "" msgid "There are no active panels. You must enable a panel to see its output." msgstr "" -#: Plugin/DebugKit/View/Elements/environment_panel.ctp:20 +#: Plugin/DebugKit/View/Elements/environment_panel.ctp:21 msgid "App Constants" msgstr "" -#: Plugin/DebugKit/View/Elements/environment_panel.ctp:36 +#: Plugin/DebugKit/View/Elements/environment_panel.ctp:37 msgid "CakePHP Constants" msgstr "" -#: Plugin/DebugKit/View/Elements/environment_panel.ctp:52 +#: Plugin/DebugKit/View/Elements/environment_panel.ctp:53 msgid "PHP Environment" msgstr "" -#: Plugin/DebugKit/View/Elements/environment_panel.ctp:70 +#: Plugin/DebugKit/View/Elements/environment_panel.ctp:71 msgid "Hidef Environment" msgstr "" @@ -186,19 +186,31 @@ msgstr "" msgid "Sql Logs" msgstr "" -#: Plugin/DebugKit/View/Elements/sql_log_panel.ctp:38 +#: Plugin/DebugKit/View/Elements/sql_log_panel.ctp:39 +msgid "No query logs when debug < 2." +msgstr "" + +#: Plugin/DebugKit/View/Elements/sql_log_panel.ctp:41 +msgid "No query logs." +msgstr "" + +#: Plugin/DebugKit/View/Elements/sql_log_panel.ctp:58 msgid "Total Time: %s ms
Total Queries: %s queries" msgstr "" -#: Plugin/DebugKit/View/Elements/sql_log_panel.ctp:47 +#: Plugin/DebugKit/View/Elements/sql_log_panel.ctp:67 +msgid "%s duplicate queries run." +msgstr "" + +#: Plugin/DebugKit/View/Elements/sql_log_panel.ctp:70 msgid "Query Explain:" msgstr "" -#: Plugin/DebugKit/View/Elements/sql_log_panel.ctp:50 +#: Plugin/DebugKit/View/Elements/sql_log_panel.ctp:73 msgid "Click an \"Explain\" link above, to see the query explanation." msgstr "" -#: Plugin/DebugKit/View/Elements/sql_log_panel.ctp:55 +#: Plugin/DebugKit/View/Elements/sql_log_panel.ctp:79 msgid "No active database connections" msgstr "" @@ -238,7 +250,7 @@ msgstr "" msgid "View Variables" msgstr "" -#: Plugin/DebugKit/View/Helper/DebugTimerHelper.php:45 +#: Plugin/DebugKit/View/Helper/DebugTimerHelper.php:44 msgid "Rendering View" msgstr "" @@ -246,11 +258,11 @@ msgstr "" msgid "Rendering %s" msgstr "" -#: Plugin/DebugKit/View/Helper/DebugTimerHelper.php:86 +#: Plugin/DebugKit/View/Helper/DebugTimerHelper.php:88 msgid "View render complete" msgstr "" -#: Plugin/DebugKit/View/Helper/HtmlToolbarHelper.php:205 +#: Plugin/DebugKit/View/Helper/HtmlToolbarHelper.php:231 msgid "Explain" msgstr "" @@ -262,7 +274,7 @@ msgstr "" msgid "No markup errors found" msgstr "" -#: Plugin/DebugKit/View/Helper/ToolbarHelper.php:189 +#: Plugin/DebugKit/View/Helper/ToolbarHelper.php:190 msgid "maybe slow" msgstr "" diff --git a/app/Locale/default.pot b/app/Locale/default.pot index 016f6fa4c..d81f7919b 100644 --- a/app/Locale/default.pot +++ b/app/Locale/default.pot @@ -13,15 +13,457 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n" -#: Controller/ArticleController.php:52 -msgid "Invalid article" +#: Controller/ClientController.php:29 +msgid "Invalid username or password" msgstr "" -#: Controller/ArticleController.php:62 -msgid "Your article has been saved." +#: Controller/ClientController.php:63;101;134 +msgid "Invalid username" msgstr "" -#: Controller/ArticleController.php:65 -msgid "Unable to add your article." +#: Controller/ClientController.php:76 +msgid "Subscription success" +msgstr "" + +#: Controller/ClientController.php:89 +msgid "Failed to subscribe. Please try again" +msgstr "" + +#: Controller/ClientController.php:108 +msgid "Saved changes success!" +msgstr "" + +#: Controller/ClientController.php:111 +msgid "Failed to save changes. Please try again" +msgstr "" + +#: Controller/ClientController.php:137 +msgid "Subscription was removed" +msgstr "" + +#: Controller/ClientController.php:140 +msgid "Subscription could NOT be removed" +msgstr "" + +#: Controller/MessageController.php:39;44;76 +msgid "Invalid message" +msgstr "" + +#: Controller/MessageController.php:58 +msgid "Message posted" +msgstr "" + +#: Controller/MessageController.php:61 +msgid "Unable to post the message" +msgstr "" + +#: Controller/MessageController.php:82 +msgid "Message was successfully updated" +msgstr "" + +#: Controller/MessageController.php:85 +msgid "Impossible to modify the message" +msgstr "" + +#: Controller/MessageController.php:102 +msgid "Message %s was successfully removed." +msgstr "" + +#: Controller/MessageController.php:106 +msgid "Message %s could NOT be removed" +msgstr "" + +#: Controller/MotDePasseController.php:33 +msgid "Password was NOT saved" +msgstr "" + +#: Controller/MotDePasseController.php:38 +msgid "Subscription saving %s..." +msgstr "" + +#: Controller/MotDePasseController.php:49;70 +msgid "Password could NOT be saved. Please try again" +msgstr "" + +#: Controller/MotDePasseController.php:59;89 +msgid "Invalid password" +msgstr "" + +#: Controller/MotDePasseController.php:67 +msgid "Password was saved" +msgstr "" + +#: Controller/MotDePasseController.php:96 +msgid "Password was removed" +msgstr "" + +#: Controller/MotDePasseController.php:100 +msgid "Invalid '%s' subscription" +msgstr "" + +#: Controller/MotDePasseController.php:102 +msgid "Subscription '%s' doesn't match the password" +msgstr "" + +#: Controller/MotDePasseController.php:104 +msgid "Password could NOT be removed" +msgstr "" + +#: Plugin/Datasources/Model/Datasource/ArraySource.php:125 +msgid "No records found in model." +msgstr "" + +#: Plugin/Datasources/Model/Datasource/CouchdbSource.php:80 +msgid "CouchDB Error: connection failed" +msgstr "" + +#: Plugin/Datasources/Model/Datasource/XmlrpcSource.php:133 +msgid "Transport error - could not open socket" +msgstr "" + +#: Plugin/Datasources/Model/Datasource/XmlrpcSource.php:136 +msgid "Transport error - HTTP status code was not 200" +msgstr "" + +#: Plugin/Datasources/Model/Datasource/XmlrpcSource.php:180 +msgid "Parse error. Not well formed" +msgstr "" + +#: View/Client/add.ctp:4 +msgid "Add a new subscription" +msgstr "" + +#: View/Client/add.ctp:6 +#: View/Client/edit.ctp:6 +#: View/Client/view.ctp:4 +msgid "My username" +msgstr "" + +#: View/Client/add.ctp:7 +#: View/Client/edit.ctp:7 +#: View/Client/view.ctp:9 +msgid "My email address" +msgstr "" + +#: View/Client/add.ctp:9 +#: View/Client/edit.ctp:9 +#: View/Client/view.ctp:14 +msgid "My first name" +msgstr "" + +#: View/Client/add.ctp:10 +#: View/Client/edit.ctp:10 +#: View/Client/view.ctp:19 +msgid "My name" +msgstr "" + +#: View/Client/add.ctp:11 +#: View/Client/edit.ctp:11 +#: View/Client/view.ctp:24 +msgid "My birthday" +msgstr "" + +#: View/Client/add.ctp:12 +#: View/Client/edit.ctp:12 +#: View/Client/view.ctp:29 +msgid "My street address" +msgstr "" + +#: View/Client/add.ctp:13 +#: View/Client/edit.ctp:13 +#: View/Client/view.ctp:34 +msgid "My city code" +msgstr "" + +#: View/Client/add.ctp:14 +#: View/Client/edit.ctp:14 +#: View/Client/view.ctp:39 +msgid "My city" +msgstr "" + +#: View/Client/add.ctp:15 +#: View/Client/edit.ctp:15 +#: View/Client/view.ctp:44 +msgid "My country" +msgstr "" + +#: View/Client/add.ctp:26 +#: View/Client/edit.ctp:26 +msgid "Continue" +msgstr "" + +#: View/Client/add.ctp:29 +#: View/Client/admin_index.ctp:20;70 +#: View/Client/edit.ctp:29 +#: View/Client/index.ctp:5 +#: View/Client/login.ctp:14 +#: View/Client/view.ctp:72 +#: View/Emails/html/recovery.ctp:5 +#: View/Emails/text/recovery.ctp:5 +#: View/MotDePasse/add.ctp:19 +#: View/MotDePasse/edit.ctp:19 +#: View/MotDePasse/index.ctp:4 +#: View/MotDePasse/view.ctp:32 +msgid "Actions" +msgstr "" + +#: View/Client/add.ctp:31 +msgid "My subscription" +msgstr "" + +#: View/Client/admin_index.ctp:2 +msgid "Profils clients" +msgstr "" + +#: View/Client/admin_index.ctp:45 +msgid "View" +msgstr "" + +#: View/Client/admin_index.ctp:46 +msgid "Modify" +msgstr "" + +#: View/Client/admin_index.ctp:47 +#: View/Client/edit.ctp:32 +msgid "Unsubscribe" +msgstr "" + +#: View/Client/admin_index.ctp:49 +#: View/Client/view.ctp:78 +msgid "Are you sure to unsubscribe # %s?" +msgstr "" + +#: View/Client/admin_index.ctp:58 +msgid "Page {:page} of {:pages}, display from {:current} records out of {:count}, starting from record {:start}, until {:end}" +msgstr "" + +#: View/Client/admin_index.ctp:63 +msgid "previous" +msgstr "" + +#: View/Client/admin_index.ctp:65 +msgid "next" +msgstr "" + +#: View/Client/admin_index.ctp:72 +msgid "Subscribe" +msgstr "" + +#: View/Client/edit.ctp:4 +msgid "Modify my profile information" +msgstr "" + +#: View/Client/edit.ctp:31 +#: View/Client/view.ctp:81 +msgid "Change my password" +msgstr "" + +#: View/Client/edit.ctp:32 +msgid "Are you sure you want to remove # %s?" +msgstr "" + +#: View/Client/edit.ctp:33 +msgid "Member list" +msgstr "" + +#: View/Client/index.ctp:2 +msgid "Dashboard" +msgstr "" + +#: View/Client/index.ctp:7 +msgid "Connect" +msgstr "" + +#: View/Client/index.ctp:8 +#: View/Client/login.ctp:15 +msgid "New subscription" +msgstr "" + +#: View/Client/login.ctp:6 +msgid "Please enter an username" +msgstr "" + +#: View/Client/login.ctp:12 +msgid "Sign in" +msgstr "" + +#: View/Client/login.ctp:16 +msgid "Forgot my password ?" +msgstr "" + +#: View/Client/view.ctp:2 +msgid "Client" +msgstr "" + +#: View/Client/view.ctp:49 +msgid "My phone number" +msgstr "" + +#: View/Client/view.ctp:54 +msgid "My role" +msgstr "" + +#: View/Client/view.ctp:59 +msgid "Created on" +msgstr "" + +#: View/Client/view.ctp:64 +msgid "Modified on" +msgstr "" + +#: View/Client/view.ctp:74 +msgid "Modify subscription" +msgstr "" + +#: View/Client/view.ctp:75 +msgid "Remove subscription" +msgstr "" + +#: View/Emails/html/recovery.ctp:1 +#: View/Emails/text/recovery.ctp:1 +msgid "Cher utilisateur %s" +msgstr "" + +#: View/Emails/html/recovery.ctp:2 +#: View/Emails/text/recovery.ctp:2 +msgid "Vous avez demandé la récupération de votre mot de passe. Par sécurité, nous vous recommandons de réinitialiser celui-ci." +msgstr "" + +#: View/Emails/html/recovery.ctp:3 +#: View/Emails/text/recovery.ctp:3 +msgid "Si vous n'êtes pas l'auteur de cette demande, vous pouvez ignorer ce message." +msgstr "" + +#: View/Emails/html/recovery.ctp:7 +#: View/Emails/text/recovery.ctp:6 +msgid "Réinitialiser le mot de passe" +msgstr "" + +#: View/Emails/html/recovery.ctp:12 +#: View/Emails/text/recovery.ctp:9 +msgid "Ce message est généré à la demande de l'utilisateur." +msgstr "" + +#: View/Message/add.ctp:4 +#: View/Message/edit.ctp:4 +msgid "Sujet de votre message" +msgstr "" + +#: View/Message/add.ctp:7 +#: View/Message/edit.ctp:7 +msgid "Contenu du message" +msgstr "" + +#: View/Message/add.ctp:9 +msgid "Auteur" +msgstr "" + +#: View/Message/add.ctp:11 +#: View/Message/edit.ctp:11 +msgid "Date" +msgstr "" + +#: View/Message/add.ctp:13 +msgid "Poster un ticket" +msgstr "" + +#: View/Message/edit.ctp:2 +#: View/Message/index.ctp:20 +msgid "Modifier un message" +msgstr "" + +#: View/Message/edit.ctp:9 +msgid "Pseudonyme" +msgstr "" + +#: View/Message/edit.ctp:14 +msgid "Sauvegarder" +msgstr "" + +#: View/Message/index.ctp:5 +msgid "Poster un message" +msgstr "" + +#: View/Message/index.ctp:8 +msgid "Tableau de bord" +msgstr "" + +#: View/Message/index.ctp:9 +#: View/Message/view.ctp:5 +msgid "date" +msgstr "" + +#: View/Message/index.ctp:9 +#: View/Message/view.ctp:5 +msgid "titre" +msgstr "" + +#: View/Message/index.ctp:9 +msgid "id" +msgstr "" + +#: View/Message/index.ctp:24 +msgid "Supprimer" +msgstr "" + +#: View/Message/view.ctp:4 +msgid "Ticket view" +msgstr "" + +#: View/MotDePasse/add.ctp:4 +msgid "Créer mon mot de passe" +msgstr "" + +#: View/MotDePasse/add.ctp:16 +#: View/MotDePasse/edit.ctp:16 +msgid "Soumettre" +msgstr "" + +#: View/MotDePasse/add.ctp:21 +#: View/MotDePasse/edit.ctp:28 +msgid "Mon profil" +msgstr "" + +#: View/MotDePasse/edit.ctp:4 +#: View/MotDePasse/index.ctp:6 +#: View/MotDePasse/view.ctp:34 +msgid "Modifier mon mot de passe" +msgstr "" + +#: View/MotDePasse/edit.ctp:22 +#: View/MotDePasse/index.ctp:7 +#: View/MotDePasse/view.ctp:35 +msgid "Réinitialiser mon mot de passe" +msgstr "" + +#: View/MotDePasse/edit.ctp:26 +#: View/MotDePasse/index.ctp:11 +#: View/MotDePasse/view.ctp:39 +msgid "Êtes-vous certain de réinitialiser votre mot de passe ?" +msgstr "" + +#: View/MotDePasse/index.ctp:2 +#: View/MotDePasse/view.ctp:2;9 +msgid "Mot de passe" +msgstr "" + +#: View/MotDePasse/index.ctp:13 +msgid "Modifier le profil" +msgstr "" + +#: View/MotDePasse/view.ctp:4 +msgid "Id" +msgstr "" + +#: View/MotDePasse/view.ctp:14 +msgid "Confirmation du mot de passe" +msgstr "" + +#: View/MotDePasse/view.ctp:19 +msgid "Créé le" +msgstr "" + +#: View/MotDePasse/view.ctp:24 +msgid "Modifié le" msgstr "" diff --git a/app/Locale/formulaire.pot b/app/Locale/formulaire.pot new file mode 100644 index 000000000..8a19a53e3 --- /dev/null +++ b/app/Locale/formulaire.pot @@ -0,0 +1,71 @@ +# LANGUAGE translation of CakePHP Application +# Copyright YEAR NAME +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PROJECT VERSION\n" +"PO-Revision-Date: YYYY-mm-DD HH:MM+ZZZZ\n" +"Last-Translator: NAME \n" +"Language-Team: LANGUAGE \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n" + +#: Model/Client.php:validation for field id +msgid "Username required" +msgstr "" + +#: Model/Client.php:validation for field id +msgid "Name already exists" +msgstr "" + +#: Model/Client.php:validation for field nom +msgid "Last name required" +msgstr "" + +#: Model/Client.php:validation for field prenom +msgid "First name required" +msgstr "" + +#: Model/Client.php:validation for field ville +msgid "City required" +msgstr "" + +#: Model/Client.php:validation for field codepostal +msgid "City code required" +msgstr "" + +#: Model/Client.php:validation for field role +msgid "Please choose a valid role" +msgstr "" + +#: Model/Client.php:validation for field telephone +msgid "e.g. +999 8811 2022" +msgstr "" + +#: Model/Message.php:validation for field titre;validation for field texte +msgid "No HTML tags" +msgstr "" + +#: Model/Message.php:validation for field titre;validation for field texte +msgid "Requis" +msgstr "" + +#: Model/Message.php:validation for field id_client +msgid "Only alphabetic or numerical characters or dash or underscores." +msgstr "" + +#: Model/Motdepasse.php:validation for field password +msgid "Pasword required" +msgstr "" + +#: Model/Motdepasse.php:validation for field password_confirm +msgid "Confirm password" +msgstr "" + +#: Model/Motdepasse.php:validation for field cree;validation for field modifie +msgid "date" +msgstr "" + diff --git a/app/Model/Client.php b/app/Model/Client.php new file mode 100644 index 000000000..e46533661 --- /dev/null +++ b/app/Model/Client.php @@ -0,0 +1,89 @@ + array( + 'foreignKey' => 'id_motdepasse' + ) + ); + public $displayField = 'email'; + public $validate = array( + 'id' => array( + 'required' => array( + 'rule' => 'alphaNumericDashUnderscore', + 'message' => 'Username required', + 'allowEmpty' => false + ), + 'unique' => array( + 'rule' => 'isUnique', + 'message' => 'Name already exists' + ) + ), + 'nom' => array( + 'required' => array( + 'rule' => 'alphaDash', + 'message' => 'Last name required', + 'allowEmpty' => false + ) + ), + 'prenom' => array( + 'required' => array( + 'rule' => 'alphaDash', + 'message' => 'First name required', + 'allowEmpty' => false + ) + ), + 'ville' => array( + 'required' => array( + 'rule' => 'alphaDash', + 'message' => 'City required', + 'allowEmpty' => false + ) + ), + 'codepostal' => array( + 'required' => array( + 'rule' => array('postal', '/^[0-9]+$/', 'eu'), + 'message' => 'City code required', + 'allowEmpty' => false + ) + ), + 'role' => array( + 'valid' => array( + 'rule' => array('inList', array('admin', 'visiteur')), + 'message' => 'Please choose a valid role', + 'allowEmpty' => false + ) + ), + 'telephone' => array( + 'valid' => array( + 'rule' => 'numeric', + 'message' => 'e.g. +999 8811 2022' + ) + ) + ); + public function alphaNumericDashUnderscore($check) { + $valeur = array_values($check); + return !preg_match('/^[0-9a-zA-Z_-\@\.]*$/', $valeur[0]); + } + public function alphaDash($check) { + $valeur = array_values($check); + return !preg_match('/^[a-zA-Z-\',\s]*$/', $valeur[0]); + } + + public function numeric($check) { + $valeur = array_values($check); + return !preg_match('/^[0-9\+\(\)\s]*$/', $valeur[0]); + } + + public function isOwnedBy($client, $motdepasse) { + return $this->field('id', array('id' => $client, 'id_motdepasse' => $motdepasse)) !== false; + } +} +?> diff --git a/app/Model/Datasource/Database/MysqlCms.php b/app/Model/Datasource/Database/MysqlCms.php index ce57d9990..238c59e82 100644 --- a/app/Model/Datasource/Database/MysqlCms.php +++ b/app/Model/Datasource/Database/MysqlCms.php @@ -1,8 +1,15 @@ columns['mediumbinary'] = array('name' => 'mediumblob'); @@ -45,10 +52,29 @@ public function column($real) { * @throws MissingConnectionException */ public function connect() { - if (Configure::read('debug') > 1) { - var_dump($this->config); + if (Configure::read('debug') > 2) { + debug($this->config); + } + try { + parent::connect(); + } catch(MissingConnectionException $e) { + if (getenv('TRAVIS_BUILD_NUMBER')) { + $this->showError(getenv('MYPHPCMS_LOG').'/migrate-getenv'.('TRAVIS_BUILD_NUMBER').'.log'); + } + $this->showError($e->getAttributes()); + throw $e; } - parent::connect(); } + /** + * Shows an error message and outputs the MYSQL result if CAKEPHP_DEBUG_LEVEL > 0 + * + * @param string $result A MYSQL result + */ + public function showError($error = null) { + if (Configure::read('debug') > 0) { + trigger_error('MYSQL Error: ' + . print_r($error, TRUE) . '', E_USER_WARNING); + } + } } ?> diff --git a/app/Model/Datasource/Database/PostgresCms.php b/app/Model/Datasource/Database/PostgresCms.php index 3bf62640c..8381eed81 100644 --- a/app/Model/Datasource/Database/PostgresCms.php +++ b/app/Model/Datasource/Database/PostgresCms.php @@ -11,7 +11,12 @@ public function connect() { if (Configure::read('debug') > 1) { var_dump($this->config); } - parent::connect(); + try { + parent::connect(); + } catch(MissingConnectionException $e) { + print_r($e->getAttributes()); + throw $e; + } } } ?> diff --git a/app/Model/Datasource/Database/SqliteCms.php b/app/Model/Datasource/Database/SqliteCms.php index f7ba6c2ba..42ca3d396 100644 --- a/app/Model/Datasource/Database/SqliteCms.php +++ b/app/Model/Datasource/Database/SqliteCms.php @@ -33,7 +33,12 @@ public function connect() { if (Configure::read('debug') > 1) { var_dump($this->config); } - parent::connect(); + try { + parent::connect(); + } catch(MissingConnectionException $e) { + print_r($e->getAttributes()); + throw $e; + } } } ?> diff --git a/app/Model/Message.php b/app/Model/Message.php new file mode 100644 index 000000000..b8518ac12 --- /dev/null +++ b/app/Model/Message.php @@ -0,0 +1,55 @@ + + */ +class Message extends AppModel { + public $validationDomain = 'formulaire'; + public $belongsTo = array( + 'Client' => array( + 'foreignKey' => 'id_client' + ) + ); + public $validate = array( + 'titre' => array( + 'rule2' => array( + 'rule' => 'notags', + 'message' => 'No HTML tags', + 'last' => true), + 'Requis' => array('rule' => 'notBlank') + ), + 'texte' => array( + 'rule3' => array( + 'rule' => 'notags', + 'message'=>'No HTML tags', + 'last' => true), + 'Requis' => array('rule' => 'notBlank') + ), + 'id_client' => array( + 'rule' => 'alphaNumericDashUnderscore', + 'message' => "Only alphabetic or numerical characters or dash or underscores." + ) + ); + + public function alphaNumericDashUnderscore($check) { + $valeur = array_values($check); + return !preg_match('/^[0-9a-zA-Z_-\@\.]*$/', $valeur[0]); + } + + public function notags($check) { + $texte = array_values($check); + return !preg_match('/<[^>]+>?(.*)/', $texte[0]); + } + + public function isOwnedBy($message, $client) { + return $this->field('id', array('id' => $message, 'id_client' => $client)) !== false; + } +} diff --git a/app/Model/Motdepasse.php b/app/Model/Motdepasse.php new file mode 100644 index 000000000..acdd8a474 --- /dev/null +++ b/app/Model/Motdepasse.php @@ -0,0 +1,76 @@ + array( + 'foreignKey' => 'id_motdepasse' + )); +/** + * Validation rules + * + * @var array + */ + public $validate = array( + 'password' => array( + 'required' => array( + 'rule' => 'alphaNumericDashUnderscore', + 'message' => 'Pasword required', + 'allowEmpty' => false + ) + ), + 'password_confirm' => array( + 'confirme' => array( + 'rule' => 'fieldIsConfirmed', + 'message' => 'Confirm password' + ) + ), + 'cree' => array( + 'date' => array( + 'rule' => array('date'), + //'message' => 'Your custom message here', + //'allowEmpty' => false, + //'required' => false, + //'last' => false, // Stop validation after this rule + //'on' => 'create', // Limit validation to 'create' or 'update' operations + ), + ), + 'modifie' => array( + 'date' => array( + 'rule' => array('date'), + //'message' => 'Your custom message here', + //'allowEmpty' => false, + //'required' => false, + //'last' => false, // Stop validation after this rule + //'on' => 'create', // Limit validation to 'create' or 'update' operations + ), + ), + ); + public function alphaNumericDashUnderscore($check) { + $valeur = array_values($check); + return !preg_match('/^[0-9a-zA-Z_-\@\.]*$/', $valeur[0]); + } + + public function fieldIsConfirmed($check) { + $valeur = array_values($check); + return $this->data[$this->alias]['password'] === $valeur[0]; + } + + public function beforeSave($options = array()) { + foreach (array_keys($this->data[$this->alias]) as $key) { + if (preg_match('/^password.*/', $key) && !empty($this->data[$this->alias][$key])) { + $passwordHasher = new BlowfishPasswordHasher(); + $this->data[$this->alias][$key] = $passwordHasher->hash( + $this->data[$this->alias][$key] + ); + } + } + return true; + } + +} diff --git a/app/Plugin/Datasources b/app/Plugin/Datasources new file mode 160000 index 000000000..b741921fa --- /dev/null +++ b/app/Plugin/Datasources @@ -0,0 +1 @@ +Subproject commit b741921fa414ed7591494a6fbd12dbb6704dfc31 diff --git a/app/Plugin/Markdown b/app/Plugin/Markdown index f15c7f347..20d178a9e 160000 --- a/app/Plugin/Markdown +++ b/app/Plugin/Markdown @@ -1 +1 @@ -Subproject commit f15c7f3479577808b751d0fe39c216d7e3ec0f58 +Subproject commit 20d178a9e2f76858d1e4349e480d43529d510426 diff --git a/app/Plugin/UpdateShell b/app/Plugin/UpdateShell new file mode 160000 index 000000000..259b6e50e --- /dev/null +++ b/app/Plugin/UpdateShell @@ -0,0 +1 @@ +Subproject commit 259b6e50e1b7c8c3b3a45ccfc384a5f55d428a23 diff --git a/app/Test/Case/Controller/ClientsControllerTest.php b/app/Test/Case/Controller/ClientsControllerTest.php new file mode 100644 index 000000000..7b5ae6c11 --- /dev/null +++ b/app/Test/Case/Controller/ClientsControllerTest.php @@ -0,0 +1,19 @@ +MotDePasse = ClassRegistry::init('MotDePasse'); + } + +/** + * tearDown method + * + * @return void + */ + public function tearDown() { + unset($this->MotDePasse); + + parent::tearDown(); + } + +} diff --git a/app/Test/Fixture/ClientFixture.php b/app/Test/Fixture/ClientFixture.php new file mode 100644 index 000000000..ec0848f91 --- /dev/null +++ b/app/Test/Fixture/ClientFixture.php @@ -0,0 +1,57 @@ + array('type' => 'string', 'null' => false, 'default' => null, 'length' => 50, 'key' => 'primary', 'collate' => 'utf8_general_ci', 'charset' => 'utf8'), + 'email' => array('type' => 'string', 'null' => false, 'default' => null, 'collate' => 'utf8_general_ci', 'charset' => 'utf8'), + 'id_motdepasse' => array('type' => 'string', 'null' => false, 'default' => null, 'collate' => 'utf8_general_ci', 'charset' => 'utf8'), + 'nom' => array('type' => 'string', 'null' => false, 'default' => null, 'length' => 30, 'collate' => 'utf8_general_ci', 'charset' => 'utf8'), + 'prenom' => array('type' => 'string', 'null' => false, 'default' => null, 'length' => 30, 'collate' => 'utf8_general_ci', 'charset' => 'utf8'), + 'annee_de_naissance' => array('type' => 'string', 'null' => false, 'default' => null, 'collate' => 'utf8_general_ci', 'charset' => 'utf8'), + 'adresse' => array('type' => 'string', 'null' => true, 'default' => null, 'length' => 30, 'collate' => 'utf8_general_ci', 'charset' => 'utf8'), + 'codepostal' => array('type' => 'integer', 'null' => true, 'default' => null, 'length' => 10, 'unsigned' => false), + 'ville' => array('type' => 'string', 'null' => false, 'default' => null, 'length' => 20, 'collate' => 'utf8_general_ci', 'charset' => 'utf8'), + 'pays' => array('type' => 'string', 'null' => false, 'default' => null, 'length' => 20, 'collate' => 'utf8_general_ci', 'charset' => 'utf8'), + 'telephone' => array('type' => 'integer', 'null' => true, 'default' => null, 'length' => 20, 'unsigned' => false), + 'role' => array('type' => 'string', 'null' => false, 'default' => null, 'length' => 20, 'collate' => 'utf8_general_ci', 'charset' => 'utf8'), + 'cree' => array('type' => 'date', 'null' => false, 'default' => null), + 'modifie' => array('type' => 'date', 'null' => false, 'default' => null), + 'indexes' => array( + 'PRIMARY' => array('column' => 'id', 'unique' => 1) + ), + 'tableParameters' => array('charset' => 'utf8', 'collate' => 'utf8_general_ci', 'engine' => 'InnoDB') + ); + +/** + * Records + * + * @var array + */ + public $records = array( + array( + 'id' => 'Lorem ipsum dolor sit amet', + 'email' => 'Lorem ipsum dolor sit amet', + 'id_motdepasse' => 'Lorem ipsum dolor sit amet', + 'nom' => 'Lorem ipsum dolor sit amet', + 'prenom' => 'Lorem ipsum dolor sit amet', + 'annee_de_naissance' => 'Lorem ipsum dolor sit amet', + 'adresse' => 'Lorem ipsum dolor sit amet', + 'codepostal' => 1, + 'ville' => 'Lorem ipsum dolor ', + 'pays' => 'Lorem ipsum dolor ', + 'telephone' => 1, + 'role' => 'Lorem ipsum dolor ', + 'cree' => '2018-12-30', + 'modifie' => '2018-12-30' + ), + ); + +} diff --git a/app/Test/Fixture/MotdepasseFixture.php b/app/Test/Fixture/MotdepasseFixture.php new file mode 100644 index 000000000..223826d3c --- /dev/null +++ b/app/Test/Fixture/MotdepasseFixture.php @@ -0,0 +1,39 @@ + array('type' => 'integer', 'null' => false, 'default' => null, 'unsigned' => false, 'key' => 'primary'), + 'password' => array('type' => 'string', 'null' => false, 'default' => null, 'collate' => 'utf8_general_ci', 'charset' => 'utf8'), + 'password_confirm' => array('type' => 'string', 'null' => false, 'default' => null, 'collate' => 'utf8_general_ci', 'charset' => 'utf8'), + 'cree' => array('type' => 'date', 'null' => false, 'default' => null), + 'modifie' => array('type' => 'date', 'null' => false, 'default' => null), + 'indexes' => array( + 'PRIMARY' => array('column' => 'id_mdp', 'unique' => 1) + ), + 'tableParameters' => array('charset' => 'utf8', 'collate' => 'utf8_general_ci', 'engine' => 'InnoDB') + ); + +/** + * Records + * + * @var array + */ + public $records = array( + array( + 'id' => 1, + 'password' => 'Lorem ipsum dolor sit amet', + 'password_confirm' => 'Lorem ipsum dolor sit amet', + 'cree' => '2018-12-29', + 'modifie' => '2018-12-29' + ), + ); + +} diff --git a/app/View/Article/index.ctp b/app/View/Article/index.ctp index 99017892e..c3f44ca9e 100644 --- a/app/View/Article/index.ctp +++ b/app/View/Article/index.ctp @@ -1,6 +1,6 @@ setContenu_Ligne(0, array(__d('article', "categorie"), __d('article', "article"), __d('article', "published"))); @@ -8,7 +8,7 @@ $t->setContenu_Ligne(0, array(__d('article', "categorie"), __d('article', "artic for ($i = 1; $i < count($articles) + 1; $i++) { $article = $articles[$i - 1]; - $t->setContenu_Cellule($i, 0, $article['Article']['fk_reference_categorie']); + $t->setContenu_Cellule($i, 0, $article['Article']['id__categorie']); $t->setContenu_Cellule($i, 1, $this->Html->link($article['Article']['id'], array('controller' => 'article', 'action' => 'view', array($article['Article']['id']))) diff --git a/app/View/Client/add.ctp b/app/View/Client/add.ctp new file mode 100644 index 000000000..ca106a4e7 --- /dev/null +++ b/app/View/Client/add.ctp @@ -0,0 +1,33 @@ +
+Form->create('Client'); ?> +
+ + Form->input('id', array('label' => __('My username'))); + echo $this->Form->input('email', array('label' => __('My email address'))); + echo $this->Form->hidden('id_motdepasse'); + echo $this->Form->input('prenom', array('label' => __('My first name'))); + echo $this->Form->input('nom', array('label' => __('My name'))); + echo $this->Form->input('annee_de_naissance', array('label' => __('My birthday'))); + echo $this->Form->input('adresse', array('label' => __('My street address'))); + echo $this->Form->input('codepostal', array('label' => __('My city code'))); + echo $this->Form->input('ville', array('label' => __('My city'))); + echo $this->Form->input('pays', array('label' => __('My country'))); + echo $this->Form->input('telephone', array('label' => 'My phone number')); + echo $this->Form->input('role', array( + 'label' => 'Choose a role', + 'options' => array('admin' => 'Member', 'visiteur' => 'Free') + ) + ); + echo $this->Form->input('cree', array('label' => 'Profile creation date')); + echo $this->Form->input('modifie', array('label' => 'Profile modification date')); + ?> +
+Form->end(__('Continue')); ?> +
+
+

+
    +
  • Html->link(__('My subscription'), array('action' => 'index')); ?>
  • +
+
diff --git a/app/View/Client/admin_index.ctp b/app/View/Client/admin_index.ctp new file mode 100644 index 000000000..d99fe7f6c --- /dev/null +++ b/app/View/Client/admin_index.ctp @@ -0,0 +1,74 @@ +
+

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Paginator->sort('id'); ?>Paginator->sort('email'); ?>Paginator->sort('id_motdepasse'); ?>Paginator->sort('nom'); ?>Paginator->sort('prenom'); ?>Paginator->sort('annee_de_naissance'); ?>Paginator->sort('adresse'); ?>Paginator->sort('codepostal'); ?>Paginator->sort('ville'); ?>Paginator->sort('pays'); ?>Paginator->sort('telephone'); ?>Paginator->sort('role'); ?>Paginator->sort('cree'); ?>Paginator->sort('modifie'); ?>
   + Html->link(strlen($client['MotDePasse']['password']), array( + 'controller' => 'Motdepasse', 'action' => 'view', $client['MotDePasse']['id'] + )); ?> +             + Html->link(__('View'), array('action' => 'view', $client['Client']['id'])); ?> + Html->link(__('Modify'), array('action' => 'edit', $client['Client']['id'])); ?> + Form->postLink(__('Unsubscribe'), array( + 'action' => 'delete', $client['Client']['id']), array( + 'confirm' => __('Are you sure to unsubscribe # %s?', $client['Client']['id']))); ?> +
+

+ Paginator->counter(array( + 'format' => __('Page {:page} of {:pages}, display from {:current} records out of {:count}, starting from record {:start}, until {:end}') + )); + ?>

+
+ Paginator->prev('< ' . __('previous'), array(), null, array('class' => 'prev disabled')); + echo $this->Paginator->numbers(array('separator' => '')); + echo $this->Paginator->next(__('next') . ' >', array(), null, array('class' => 'next disabled')); + ?> +
+
+
+

+
    +
  • Html->link(__('Subscribe'), array('action' => 'add')); ?>
  • +
+
diff --git a/app/View/Client/edit.ctp b/app/View/Client/edit.ctp new file mode 100644 index 000000000..39f081af5 --- /dev/null +++ b/app/View/Client/edit.ctp @@ -0,0 +1,35 @@ +
+Form->create('Client'); ?> +
+ + Form->input('id', array('label' => __('My username'))); + echo $this->Form->input('email', array('label' => __('My email address'))); + echo $this->Form->hidden('id_motdepasse'); + echo $this->Form->input('prenom', array('label' => __('My first name'))); + echo $this->Form->input('nom', array('label' => __('My name'))); + echo $this->Form->input('annee_de_naissance', array('label' => __('My birthday'))); + echo $this->Form->input('adresse', array('label' => __('My street address'))); + echo $this->Form->input('codepostal', array('label' => __('My city code'))); + echo $this->Form->input('ville', array('label' => __('My city'))); + echo $this->Form->input('pays', array('label' => __('My country'))); + echo $this->Form->input('telephone', array('label' => 'My phone number')); + echo $this->Form->input('role', array( + 'label' => 'Choose a role', + 'options' => array('admin' => 'Member', 'visiteur' => 'Free') + ) + ); + echo $this->Form->input('cree', array('label' => 'Profile creation date')); + echo $this->Form->input('modifie', array('label' => 'Profile modification date')); + ?> +
+Form->end(__('Continue')); ?> +
+
+

+
    +
  • Html->link(__('Change my password'), array('controller' = > 'Motdepasse', 'action' => 'edit', $client['Motdepasse']['id'])); ?>
  • +
  • Form->postLink(__('Unsubscribe'), array('action' => 'delete', $this->Form->value('Client.id')), array('confirm' => __('Are you sure you want to remove # %s?', $this->Form->value('Client.id')))); ?>
  • +
  • Html->link(__('Member list'), array('action' => 'index')); ?>
  • +
+
diff --git a/app/View/Client/index.ctp b/app/View/Client/index.ctp new file mode 100644 index 000000000..27a3e0b31 --- /dev/null +++ b/app/View/Client/index.ctp @@ -0,0 +1,10 @@ +
+

+
+
+

+
    +
  • Html->link(__('Connect'), array('action' => 'login')); ?>
  • +
  • Html->link(__('New subscription'), array('action' => 'add')); ?>
  • +
+
diff --git a/app/View/Client/login.ctp b/app/View/Client/login.ctp new file mode 100644 index 000000000..99369551e --- /dev/null +++ b/app/View/Client/login.ctp @@ -0,0 +1,20 @@ +
+Flash->render('auth'); ?> +Form->create('Client'); ?> +
+ + + + Form->input('id'); + echo $this->Form->input('motdepasse', array('type' => 'password')); + ?> +
+ Form->end(__('Sign in')); ?> +
+

+
  • Html->link(__('New subscription'), array('action' => 'add')); ?>
  • +
  • Form->postLink(__('Forgot my password ?'), array( + 'action' => 'recovery' + )); ?>
  • +
+ diff --git a/app/View/Client/view.ctp b/app/View/Client/view.ctp new file mode 100644 index 000000000..3dc6a6ad2 --- /dev/null +++ b/app/View/Client/view.ctp @@ -0,0 +1,83 @@ +
+

+
+
+
+ +   +
+
+
+ +   +
+
+
+ +   +
+
+
+ +   +
+
+
+ +   +
+
+
+ +   +
+
+
+ +   +
+
+
+ +   +
+
+
+ +   +
+
+
+ +   +
+
+
+ +   +
+
+
+ +   +
+
+
+ +   +
+
+
+
+

+
    +
  • Html->link(__('Modify subscription'), array('action' => 'edit', $client['Client']['id'])); ?>
  • +
  • Form->postLink(__('Remove subscription'), array( + 'action' => 'delete', $client['Client']['id']), + array( + 'confirm' => __('Are you sure to unsubscribe # %s?', $client['Client']['id']) + ) + ); ?>
  • +
  • Html->link(__('Change my password'), array('controller' => 'motdepasse', 'action' => 'index')); ?>
  • +
+
diff --git a/app/View/E14/admin_cat.ctp b/app/View/E14/admin_cat.ctp index e8db00ea3..593406fa4 100644 --- a/app/View/E14/admin_cat.ctp +++ b/app/View/E14/admin_cat.ctp @@ -1,8 +1,8 @@ r['include__php_constantes.inc']; -require APP . $r->r['include__php_module_html.inc']; -require APP . $r->r['include__php_module_cat.inc']; +include_once APP . $r->r['include__php_constantes.inc']; +include_once APP . $r->r['include__php_module_html.inc']; +include_once APP . $r->r['include__php_module_cat.inc']; $sql = new SQL(SERVEUR, BASE, CLIENT, CLIENT_MDP); diff --git a/app/View/E14/admin_dvd.ctp b/app/View/E14/admin_dvd.ctp index 1db97c0bf..e70eded76 100644 --- a/app/View/E14/admin_dvd.ctp +++ b/app/View/E14/admin_dvd.ctp @@ -1,8 +1,8 @@ r["include__php_module_html.inc"]; -require APP . $r->r["include__php_module_DVD.inc"]; +include_once APP . $r->r["include__php_module_html.inc"]; +include_once APP . $r->r["include__php_module_DVD.inc"]; $clefPage = "admin__"; $ajouter = $r->sitemap[$clefPage . 'ajouter']; diff --git a/app/View/E14/admin_infos.ctp b/app/View/E14/admin_infos.ctp index 89a75af1e..dfbda23e9 100644 --- a/app/View/E14/admin_infos.ctp +++ b/app/View/E14/admin_infos.ctp @@ -1,6 +1,6 @@ r['include__php_constantes.inc']; +include_once APP . $r->r['include__php_constantes.inc']; echo "
" . $r->lang("admininfos") . "

"; $liste = HTML_listeDebut(); diff --git a/app/View/E14/cat.ctp b/app/View/E14/cat.ctp index 5169c32e5..1b53aad97 100644 --- a/app/View/E14/cat.ctp +++ b/app/View/E14/cat.ctp @@ -1,8 +1,8 @@ r['include__php_constantes.inc']; -require APP . $r->r['include__php_module_cat.inc']; +include_once APP . $r->r['include__php_constantes.inc']; +include_once APP . $r->r['include__php_module_cat.inc']; $sql = new SQL(SERVEUR, BASE, CLIENT, CLIENT_MDP); diff --git a/app/View/E14/dvd.ctp b/app/View/E14/dvd.ctp index 824e0fc66..d74840087 100644 --- a/app/View/E14/dvd.ctp +++ b/app/View/E14/dvd.ctp @@ -1,6 +1,6 @@ r["include__php_module_DVD.inc"]; +include_once APP . $r->r["include__php_module_DVD.inc"]; $pageUrl = $r->sitemap[$pIndex]; if ($nom && $base) { diff --git a/app/View/E14/etc.ctp b/app/View/E14/etc.ctp index 3397b4a97..acb6c3546 100644 --- a/app/View/E14/etc.ctp +++ b/app/View/E14/etc.ctp @@ -1,9 +1,2 @@ r['etc'] . DS . $p; -} else if (isset($r)){ - require APP . $r->r['etc__index']; -} else { - // code... -} ?> diff --git a/app/View/E14/images.ctp b/app/View/E14/images.ctp new file mode 100644 index 000000000..acb6c3546 --- /dev/null +++ b/app/View/E14/images.ctp @@ -0,0 +1,2 @@ + diff --git a/app/View/E14/index.ctp b/app/View/E14/index.ctp index c076d9b2f..a7318da7f 100644 --- a/app/View/E14/index.ctp +++ b/app/View/E14/index.ctp @@ -1,8 +1,8 @@ r)){ - include APP . $r->r["e13__" . $p]; + include_once APP . $r->r["e13__" . $p]; } else if (isset($r) && isset($offset)) { - require APP . $r->r["include__php_constantes.inc"]; + include_once APP . $r->r["include__php_constantes.inc"]; App::uses('HTMLHelper', 'Helper'); $sql = new SQL(SERVEUR, BASE, CLIENT, CLIENT_MDP); /** test de la connexion */ diff --git a/app/View/E14/infos.ctp b/app/View/E14/infos.ctp index 5ac5a89b5..4a8af2d07 100644 --- a/app/View/E14/infos.ctp +++ b/app/View/E14/infos.ctp @@ -1,6 +1,6 @@ lang("contents", "infos"); -require APP . $r->r["include__php_constantes.inc"]; +include_once APP . $r->r["include__php_constantes.inc"]; // info SQL $sql = new SQL(SERVEUR, BASE, CLIENT, CLIENT_MDP); if ($sql->connect_succes()) { diff --git a/app/View/Emails/html/recovery.ctp b/app/View/Emails/html/recovery.ctp new file mode 100644 index 000000000..0bc7a5425 --- /dev/null +++ b/app/View/Emails/html/recovery.ctp @@ -0,0 +1,12 @@ +

,
+

+

+
+

+
    +
  • Html->link(__('Réinitialiser le mot de passe'), array( + 'controller' => 'MotDePasse', 'action' => 'delete', $client['MotDePasse']['id']) + );?>
  • +
+
+

diff --git a/app/View/Emails/send.ctp b/app/View/Emails/send.ctp index b02dd337d..6375ff5f4 100644 --- a/app/View/Emails/send.ctp +++ b/app/View/Emails/send.ctp @@ -4,7 +4,7 @@
request->data)) { - $this->Html->link('Continue...', array("Controller" => 'E13', 'action' => 'index')); + $this->Html->link('Continue...', array("Controller" => 'e14', 'action' => 'index')); echo $this->Form->create('Email', array('type' => 'post', 'url' => '/emails/send')); } else { echo $this->Form->input('email', array('class' => 'email_form', 'label' => 'To: ', 'value' => $email)); @@ -16,4 +16,3 @@
- diff --git a/app/View/Emails/text/recovery.ctp b/app/View/Emails/text/recovery.ctp new file mode 100644 index 000000000..02af5b705 --- /dev/null +++ b/app/View/Emails/text/recovery.ctp @@ -0,0 +1,9 @@ +, +

+ +- - - - - - - - - - - - - - - - - - - - - - - + + * Html->link(__('Réinitialiser le mot de passe'), array( + 'controller' => 'MotDePasse', 'action' => 'delete', $client['MotDePasse']['id']) + );?> + diff --git a/app/View/Errors/missing_connection.ctp b/app/View/Errors/missing_connection.ctp index 98c4bf371..d29f3036d 100644 --- a/app/View/Errors/missing_connection.ctp +++ b/app/View/Errors/missing_connection.ctp @@ -2,8 +2,8 @@ :

-

: database.cms.php, (./start_cake.sh) bootargs.sh -:

./migrate-database.sh -Y -i
+

: database.php, (./start_cake.sh) fooargs.sh +:

./migrate-database.sh -i

0): diff --git a/app/View/Errors/missing_datasource_config.ctp b/app/View/Errors/missing_datasource_config.ctp index 8f7e80be6..ad9213363 100644 --- a/app/View/Errors/missing_datasource_config.ctp +++ b/app/View/Errors/missing_datasource_config.ctp @@ -2,8 +2,8 @@ :

-

: database.cms.php -:

./configure.sh -d -Y
+

: database.php +:

./configure.sh

0): diff --git a/app/View/Errors/pdo_error.ctp b/app/View/Errors/pdo_error.ctp new file mode 100644 index 000000000..0a3072707 --- /dev/null +++ b/app/View/Errors/pdo_error.ctp @@ -0,0 +1,37 @@ + +

+

+ : + +

+queryString)) : ?> +

+ : + queryString); ?> +

+ +params)) : ?> + : + params); ?> + +

: Schema/schema.php +:

./configure.sh -d -u -p<sql-root-password>
+

+element('exception_stack_trace'); +?> diff --git a/app/View/Layouts/default-cake29.ctp b/app/View/Layouts/default-cake29.ctp index 5a4bb7ae5..72e5706df 100644 --- a/app/View/Layouts/default-cake29.ctp +++ b/app/View/Layouts/default-cake29.ctp @@ -264,11 +264,10 @@ $ git push Note: the cakephp-mysql.json template creates the DB service and environment variables for you.
-oc env dc/cakephp-mysql-example DATABASE_SERVICE_NAME=<database service name>
-oc env dc/cakephp-mysql-example DATABASE_ENGINE=mysql
-oc env dc/cakephp-mysql-example DATABASE_NAME=<your created database>
+oc env dc/cakephp-mysql-example DB=Mysql
+oc env dc/cakephp-mysql-example MYSQL_DATABASE=<your created database>
 oc env dc/cakephp-mysql-example DATABASE_USER=<your database user>
-oc env dc/cakephp-mysql-example DATABASE_PASSWORD=<your database user's password>
+oc env dc/cakephp-mysql-example MYSQL_ROOT_PASSWORD=<your database user's password>
                                                 

diff --git a/app/View/Message/add.ctp b/app/View/Message/add.ctp index 3017dc18d..84ffba8b5 100644 --- a/app/View/Message/add.ctp +++ b/app/View/Message/add.ctp @@ -1,14 +1,14 @@ Form->create('Message'); - echo $this->Form->input('titre', array('label' => $r->lang('titre', 'contactus'), + echo $this->Form->create('Message'); + echo $this->Form->input('titre', array('label' => __('Sujet de votre message'), 'required' => true)); - echo $this->Form->input('texte', array('label' => $r->lang('texte', 'contactus'), + echo $this->Form->input('texte', array( + 'label' => __('Contenu du message'), 'required' => true)); - echo $this->Form->input('fk_identifiant', array('label' => $r->lang('identifiant', 'contactus'), + echo $this->Form->input('id', array('label' => __('Auteur'), 'required' => true)); - echo $this->Form->input('date', array('label' => $r->lang('date', 'contactus'), + echo $this->Form->input('date', array('label' => __('Date'), 'required' => true)); - echo $this->Form->end($r->lang('write', 'contactus')); -?> \ No newline at end of file + echo $this->Form->end(__('Poster un ticket')); +?> diff --git a/app/View/Message/edit.ctp b/app/View/Message/edit.ctp new file mode 100644 index 000000000..c63505d67 --- /dev/null +++ b/app/View/Message/edit.ctp @@ -0,0 +1,15 @@ +Form->create('Message'); +echo $this->Form->input('titre', array('label' => __('Sujet de votre message'), + 'required' => true)); +echo $this->Form->input('texte', array( + 'label' => __('Contenu du message'), + 'required' => true)); +echo $this->Form->input('id', array('label' => __('Pseudonyme'), + 'required' => true)); +echo $this->Form->input('date', array('label' => __('Date'), + 'required' => true)); +echo $this->Form->input('id', array('hidden' => true)); +echo $this->Form->end(__('Sauvegarder')); +?> diff --git a/app/View/Message/index.ctp b/app/View/Message/index.ctp index ba7f6f772..1c809ed88 100644 --- a/app/View/Message/index.ctp +++ b/app/View/Message/index.ctp @@ -1,20 +1,30 @@ lang("contactus")); -$t->setContenu_Ligne(0, $r->lang(array("date", "titre", "identifiant"), "contactus")); +require APP . $r->r['include__php_tbl.class.inc']; +echo $this->Html->link( + __('Poster un message'), + array('controller' => 'message', 'action' => 'add') +); +$t = new Tableau(count($messages) + 1, 5, __('Tableau de bord')); +$t->setContenu_Ligne(0, array(__('date'), __('titre'), __('id'))); /* On fait un tour des $messages array */ for ($i = 1; $i < count($messages) + 1; $i++) { $message = $messages[$i - 1]; - $t->setContenu_Cellule($i, 0, $message['Message']['fk_identifiant']); - $t->setContenu_Cellule($i, 1, $this->Html->link($message['Message']['id'], array('controller' => 'message', - 'action' => 'view', - array($message['Message']['id']))) + $t->setContenu_Cellule($i, 0, $message['Message']['date']); + $t->setContenu_Cellule($i, 1, $this->Html->link($message['Message']['titre'], array( + 'action' => 'view', $message['Message']['id'])) + ); + $t->setContenu_Cellule($i, 2, $this->Text->autoLinkEmails($message['Message']['id'])); + $t->setContenu_Cellule($i, 3, $this->Html->link(__('Modifier un message'), array( + 'action' => 'edit', $message['Message']['id'])) + ); + $t->setContenu_Cellule($i, 4, $this->Form->postLink( + __('Supprimer'), + array('action' => 'delete', $message['Message']['id']), + array('confirm' => 'Êtes-vous sûr ?')) ); - $t->setContenu_Cellule($i, 2, $message['Message']['published']); } -echo $t->fin(); -?> \ No newline at end of file +echo $t->fin(4); +?> diff --git a/app/View/Message/view.ctp b/app/View/Message/view.ctp index 27dda458c..cf939920f 100644 --- a/app/View/Message/view.ctp +++ b/app/View/Message/view.ctp @@ -1,12 +1,12 @@ lang("view", "contactus")); - $t->setContenu_Colonne(0, $r->lang(array("date", "titre", "texte"), "contactus")); + require APP . $r->r['include__php_tbl.class.inc']; + $t = new Tableau(3, 2, __('Ticket view')); + $t->setContenu_Colonne(0, array(__('date'), __('titre'), + $this->Text->autoLinkEmails($message['id']) + )); $t->setContenu_Cellule(0, 1, $message['Message']['date']); $t->setContenu_Cellule(1, 1, $message['Message']['titre']); - $t->setContenu_Cellule(2, 2, $message['Message']['texte']); - $t->fin(1); - -?> \ No newline at end of file + $t->setContenu_Cellule(2, 1, $this->Markdown->transform($this->Text->autoLink($message['Message']['texte']))); + echo $t->fin(4); +?> diff --git a/app/View/MotDePasse/add.ctp b/app/View/MotDePasse/add.ctp new file mode 100644 index 000000000..ec5d1e03b --- /dev/null +++ b/app/View/MotDePasse/add.ctp @@ -0,0 +1,23 @@ +

+Form->create('MotDePasse'); ?> +
+ + Form->input('id'); + echo $this->Form->input('password', array('label' => 'Entrez un mot de passe')); + echo $this->Form->input('password_confirm', array( + 'type' => 'password', + 'label' => 'Confirmez le mot de passe') + ); + echo $this->Form->input('cree'); + echo $this->Form->input('modifie'); + ?> +
+Form->end(__('Soumettre')); ?> +
+
+

+
    +
  • Html->link(__('Mon profil'), array('controller' => 'Client', 'action' => 'index')); ?>
  • +
+
diff --git a/app/View/MotDePasse/edit.ctp b/app/View/MotDePasse/edit.ctp new file mode 100644 index 000000000..c83dedc88 --- /dev/null +++ b/app/View/MotDePasse/edit.ctp @@ -0,0 +1,30 @@ +
+Form->create('MotDePasse'); ?> +
+ + Form->input('id'); + echo $this->Form->input('password', array('label' => 'Entrez un mot de passe')); + echo $this->Form->input('password_confirm', array( + 'type' => 'password', + 'label' => 'Confirmez le mot de passe') + ); + echo $this->Form->input('cree'); + echo $this->Form->input('modifie'); + ?> +
+Form->end(__('Soumettre')); ?> +
+
+

+
    + +
  • Form->postLink(__('Réinitialiser mon mot de passe'), array( + 'action' => 'delete', + $this->Form->value('MotDePasse.id') + ), array( + 'confirm' => __('Êtes-vous certain de réinitialiser votre mot de passe ?') + )); ?>
  • +
  • Html->link(__('Mon profil'), array('controller' => 'Client', 'action' => 'index')); ?>
  • +
+
diff --git a/app/View/MotDePasse/index.ctp b/app/View/MotDePasse/index.ctp new file mode 100644 index 000000000..f4b08dba6 --- /dev/null +++ b/app/View/MotDePasse/index.ctp @@ -0,0 +1,18 @@ +
+

+
+

+
    +
  • Html->link(__('Modifier mon mot de passe'), array('action' => 'edit', $motdepasse['Motdepasse']['id'])); ?>
  • +
  • Form->postLink(__('Réinitialiser mon mot de passe'), array( + 'action' => 'delete', + $this->Form->value('Motdepasse.id') + ), array( + 'confirm' => __('Êtes-vous certain de réinitialiser votre mot de passe ?') + )); ?>
  • +
  • Html->link(__('Modifier le profil'), + array( + 'action' => 'edit', AuthComponent::user('id') + )); ?>
  • +
+
diff --git a/app/View/MotDePasse/view.ctp b/app/View/MotDePasse/view.ctp new file mode 100644 index 000000000..fbffb20eb --- /dev/null +++ b/app/View/MotDePasse/view.ctp @@ -0,0 +1,42 @@ +
+

+
+
+
+ +   +
+
+
+ +   +
+
+
+ +   +
+
+
+ +   +
+
+
+ +   +
+
+
+
+

+
    +
  • Html->link(__('Modifier mon mot de passe'), array('action' => 'edit', $motdepasse['Motdepasse']['id'])); ?>
  • +
  • Form->postLink(__('Réinitialiser mon mot de passe'), array( + 'action' => 'delete', + $this->Form->value('Motdepasse.id') + ), array( + 'confirm' => __('Êtes-vous certain de réinitialiser votre mot de passe ?') + )); ?>
  • +
+
diff --git a/app/index.php b/app/index.php index 2a3902ccf..fdc5cf98d 100755 --- a/app/index.php +++ b/app/index.php @@ -14,4 +14,4 @@ * @license https://opensource.org/licenses/mit-license.php MIT License */ -require 'webroot' . DIRECTORY_SEPARATOR . 'index.php'; +include 'webroot' . DIRECTORY_SEPARATOR . 'index.php'; diff --git a/app/webroot/.DS_Store b/app/webroot/.DS_Store index 84ff4872e..5008ddfcf 100644 Binary files a/app/webroot/.DS_Store and b/app/webroot/.DS_Store differ diff --git a/app/webroot/.htaccess b/app/webroot/.htaccess index c164adc5c..0a9c19f72 100644 --- a/app/webroot/.htaccess +++ b/app/webroot/.htaccess @@ -6,11 +6,10 @@ RewriteEngine On - RewriteBase /app/webroot/ RewriteCond %{REQUEST_FILENAME} !-d RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_URI} !^(img|css|js)/(.*)$ - RewriteCond %{REQUEST_URI} !^(php-cms/)/(tempcache)/(.*)$ + RewriteCond %{REQUEST_URI} !^(tmp)/(.*)$ RewriteCond %{REQUEST_URI} !^(php-cms/e13)/(etc|images)/(.*)$ RewriteRule ^(.*)$ index.php [QSA,L] diff --git a/app/webroot/health.php b/app/webroot/health.php index 8db455569..307937c72 100644 --- a/app/webroot/health.php +++ b/app/webroot/health.php @@ -1,8 +1,8 @@ =5.3.0" }, + "default-branch": true, "type": "cakephp-plugin", "extra": { "installer-name": "MarkdownExtra" @@ -50,7 +51,105 @@ "markdown", "plugin" ], - "time": "2018-11-15T23:11:19+00:00" + "support": { + "issues": "https://github.com/b23prodtm/markdown-plugin/issues", + "source": "https://github.com/b23prodtm/markdown-plugin" + }, + "time": "2020-06-28T12:50:12+00:00" + }, + { + "name": "betothreeprod/updateshell", + "version": "dev-development", + "source": { + "type": "git", + "url": "https://github.com/b23prodtm/update.git", + "reference": "259b6e50e1b7c8c3b3a45ccfc384a5f55d428a23" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/b23prodtm/update/zipball/259b6e50e1b7c8c3b3a45ccfc384a5f55d428a23", + "reference": "259b6e50e1b7c8c3b3a45ccfc384a5f55d428a23", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8" + }, + "default-branch": true, + "type": "cakephp-plugin", + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-2-Clause" + ], + "description": "A CakePHP Plugin: UpdateShell", + "homepage": "https://github.com/b23prodtm/update", + "keywords": [ + "cakephp", + "plugin", + "update" + ], + "support": { + "source": "https://github.com/b23prodtm/update/tree/development" + }, + "time": "2021-02-08T16:03:01+00:00" + }, + { + "name": "cakephp/datasources", + "version": "dev-master", + "source": { + "type": "git", + "url": "https://github.com/cakephp/datasources.git", + "reference": "b741921fa414ed7591494a6fbd12dbb6704dfc31" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/cakephp/datasources/zipball/b741921fa414ed7591494a6fbd12dbb6704dfc31", + "reference": "b741921fa414ed7591494a6fbd12dbb6704dfc31", + "shasum": "" + }, + "require": { + "composer/installers": "*", + "php": ">=5.2.8" + }, + "default-branch": true, + "type": "cakephp-plugin", + "extra": { + "branch-alias": { + "dev-master": "2.3.x-dev" + }, + "installer-name": "Datasources" + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "CakePHP Community", + "homepage": "https://github.com/cakephp/datasources/graphs/contributors" + } + ], + "description": "CakePHP Datasources Plugin", + "homepage": "https://github.com/cakephp/datasources", + "keywords": [ + "adodb", + "cakephp", + "couchdb", + "datasources", + "db2", + "firebird", + "ldap", + "odbc", + "sqlite", + "sqlserver", + "sybase" + ], + "support": { + "forum": "http://stackoverflow.com/tags/cakephp", + "irc": "irc://irc.freenode.org/cakephp", + "issues": "https://github.com/cakephp/datasources/issues", + "source": "https://github.com/cakephp/datasources" + }, + "time": "2017-11-13T12:04:37+00:00" }, { "name": "cakephp/debug_kit", @@ -102,38 +201,48 @@ "debug", "kit" ], + "support": { + "forum": "http://stackoverflow.com/tags/cakephp", + "irc": "irc://irc.freenode.org/cakephp", + "issues": "https://github.com/cakephp/debug_kit/issues", + "source": "https://github.com/cakephp/debug_kit" + }, "time": "2018-09-18T01:48:48+00:00" }, { "name": "composer/installers", - "version": "v1.6.0", + "version": "v1.10.0", "source": { "type": "git", "url": "https://github.com/composer/installers.git", - "reference": "cfcca6b1b60bc4974324efb5783c13dca6932b5b" + "reference": "1a0357fccad9d1cc1ea0c9a05b8847fbccccb78d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/installers/zipball/cfcca6b1b60bc4974324efb5783c13dca6932b5b", - "reference": "cfcca6b1b60bc4974324efb5783c13dca6932b5b", + "url": "https://api.github.com/repos/composer/installers/zipball/1a0357fccad9d1cc1ea0c9a05b8847fbccccb78d", + "reference": "1a0357fccad9d1cc1ea0c9a05b8847fbccccb78d", "shasum": "" }, "require": { - "composer-plugin-api": "^1.0" + "composer-plugin-api": "^1.0 || ^2.0" }, "replace": { "roundcube/plugin-installer": "*", "shama/baton": "*" }, "require-dev": { - "composer/composer": "1.0.*@dev", - "phpunit/phpunit": "^4.8.36" + "composer/composer": "1.6.* || ^2.0", + "composer/semver": "^1 || ^3", + "phpstan/phpstan": "^0.12.55", + "phpstan/phpstan-phpunit": "^0.12.16", + "symfony/phpunit-bridge": "^4.2 || ^5", + "symfony/process": "^2.3" }, "type": "composer-plugin", "extra": { "class": "Composer\\Installers\\Plugin", "branch-alias": { - "dev-master": "1.0-dev" + "dev-main": "1.x-dev" } }, "autoload": { @@ -163,6 +272,7 @@ "Kanboard", "Lan Management System", "MODX Evo", + "MantisBT", "Mautic", "Maya", "OXID", @@ -170,7 +280,9 @@ "Porto", "RadPHP", "SMF", + "Starbug", "Thelia", + "Whmcs", "WolfCMS", "agl", "aimeos", @@ -193,6 +305,7 @@ "installer", "itop", "joomla", + "known", "kohana", "laravel", "lavalite", @@ -208,6 +321,7 @@ "phpbb", "piwik", "ppi", + "processwire", "puppet", "pxcms", "reindex", @@ -215,6 +329,7 @@ "shopware", "silverstripe", "sydes", + "sylius", "symfony", "typo3", "wordpress", @@ -222,25 +337,46 @@ "zend", "zikula" ], - "time": "2018-08-27T06:10:37+00:00" + "support": { + "issues": "https://github.com/composer/installers/issues", + "source": "https://github.com/composer/installers/tree/v1.10.0" + }, + "funding": [ + { + "url": "https://packagist.com", + "type": "custom" + }, + { + "url": "https://github.com/composer", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/composer/composer", + "type": "tidelift" + } + ], + "time": "2021-01-14T11:07:16+00:00" }, { "name": "michelf/php-markdown", - "version": "1.8.0", + "version": "1.9.0", "source": { "type": "git", "url": "https://github.com/michelf/php-markdown.git", - "reference": "01ab082b355bf188d907b9929cd99b2923053495" + "reference": "c83178d49e372ca967d1a8c77ae4e051b3a3c75c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/michelf/php-markdown/zipball/01ab082b355bf188d907b9929cd99b2923053495", - "reference": "01ab082b355bf188d907b9929cd99b2923053495", + "url": "https://api.github.com/repos/michelf/php-markdown/zipball/c83178d49e372ca967d1a8c77ae4e051b3a3c75c", + "reference": "c83178d49e372ca967d1a8c77ae4e051b3a3c75c", "shasum": "" }, "require": { "php": ">=5.3.0" }, + "require-dev": { + "phpunit/phpunit": ">=4.3 <5.8" + }, "type": "library", "autoload": { "psr-4": { @@ -268,35 +404,40 @@ "keywords": [ "markdown" ], - "time": "2018-01-15T00:49:33+00:00" + "support": { + "issues": "https://github.com/michelf/php-markdown/issues", + "source": "https://github.com/michelf/php-markdown/tree/1.9.0" + }, + "time": "2019-12-02T02:32:27+00:00" } ], "packages-dev": [ { "name": "cakephp/cakephp-codesniffer", - "version": "3.1.1", + "version": "4.2.4", "source": { "type": "git", "url": "https://github.com/cakephp/cakephp-codesniffer.git", - "reference": "682e79fda294c4383e094a2a881e16dcf1130750" + "reference": "c5bb1faeebf09cd4a3604bdb0c84f7bc92dc5475" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/cakephp/cakephp-codesniffer/zipball/682e79fda294c4383e094a2a881e16dcf1130750", - "reference": "682e79fda294c4383e094a2a881e16dcf1130750", + "url": "https://api.github.com/repos/cakephp/cakephp-codesniffer/zipball/c5bb1faeebf09cd4a3604bdb0c84f7bc92dc5475", + "reference": "c5bb1faeebf09cd4a3604bdb0c84f7bc92dc5475", "shasum": "" }, "require": { - "php": ">=5.6", - "squizlabs/php_codesniffer": "^3.0.0" + "php": ">=7.2.0", + "slevomat/coding-standard": "^6.3.6", + "squizlabs/php_codesniffer": "~3.5.5" }, "require-dev": { - "phpunit/phpunit": "<6.0" + "phpunit/phpunit": "^7.1" }, "type": "phpcodesniffer-standard", "autoload": { "psr-4": { - "CakePHP\\": "CakePHP" + "CakePHP\\": "CakePHP/" } }, "notification-url": "https://packagist.org/downloads/", @@ -310,43 +451,116 @@ } ], "description": "CakePHP CodeSniffer Standards", - "homepage": "http://cakephp.org", + "homepage": "https://cakephp.org", "keywords": [ "codesniffer", "framework" ], - "time": "2018-11-30T16:04:05+00:00" + "support": { + "forum": "https://stackoverflow.com/tags/cakephp", + "irc": "irc://irc.freenode.org/cakephp", + "issues": "https://github.com/cakephp/cakephp-codesniffer/issues", + "source": "https://github.com/cakephp/cakephp-codesniffer" + }, + "time": "2020-12-03T20:39:38+00:00" + }, + { + "name": "dealerdirect/phpcodesniffer-composer-installer", + "version": "v0.7.1", + "source": { + "type": "git", + "url": "https://github.com/Dealerdirect/phpcodesniffer-composer-installer.git", + "reference": "fe390591e0241955f22eb9ba327d137e501c771c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Dealerdirect/phpcodesniffer-composer-installer/zipball/fe390591e0241955f22eb9ba327d137e501c771c", + "reference": "fe390591e0241955f22eb9ba327d137e501c771c", + "shasum": "" + }, + "require": { + "composer-plugin-api": "^1.0 || ^2.0", + "php": ">=5.3", + "squizlabs/php_codesniffer": "^2.0 || ^3.0 || ^4.0" + }, + "require-dev": { + "composer/composer": "*", + "phpcompatibility/php-compatibility": "^9.0", + "sensiolabs/security-checker": "^4.1.0" + }, + "type": "composer-plugin", + "extra": { + "class": "Dealerdirect\\Composer\\Plugin\\Installers\\PHPCodeSniffer\\Plugin" + }, + "autoload": { + "psr-4": { + "Dealerdirect\\Composer\\Plugin\\Installers\\PHPCodeSniffer\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Franck Nijhof", + "email": "franck.nijhof@dealerdirect.com", + "homepage": "http://www.frenck.nl", + "role": "Developer / IT Manager" + } + ], + "description": "PHP_CodeSniffer Standards Composer Installer Plugin", + "homepage": "http://www.dealerdirect.com", + "keywords": [ + "PHPCodeSniffer", + "PHP_CodeSniffer", + "code quality", + "codesniffer", + "composer", + "installer", + "phpcs", + "plugin", + "qa", + "quality", + "standard", + "standards", + "style guide", + "stylecheck", + "tests" + ], + "support": { + "issues": "https://github.com/dealerdirect/phpcodesniffer-composer-installer/issues", + "source": "https://github.com/dealerdirect/phpcodesniffer-composer-installer" + }, + "time": "2020-12-07T18:04:37+00:00" }, { "name": "doctrine/instantiator", - "version": "1.1.0", + "version": "1.4.0", "source": { "type": "git", "url": "https://github.com/doctrine/instantiator.git", - "reference": "185b8868aa9bf7159f5f953ed5afb2d7fcdc3bda" + "reference": "d56bf6102915de5702778fe20f2de3b2fe570b5b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/instantiator/zipball/185b8868aa9bf7159f5f953ed5afb2d7fcdc3bda", - "reference": "185b8868aa9bf7159f5f953ed5afb2d7fcdc3bda", + "url": "https://api.github.com/repos/doctrine/instantiator/zipball/d56bf6102915de5702778fe20f2de3b2fe570b5b", + "reference": "d56bf6102915de5702778fe20f2de3b2fe570b5b", "shasum": "" }, "require": { - "php": "^7.1" + "php": "^7.1 || ^8.0" }, "require-dev": { - "athletic/athletic": "~0.1.8", + "doctrine/coding-standard": "^8.0", "ext-pdo": "*", "ext-phar": "*", - "phpunit/phpunit": "^6.2.3", - "squizlabs/php_codesniffer": "^3.0.2" + "phpbench/phpbench": "^0.13 || 1.0.0-alpha2", + "phpstan/phpstan": "^0.12", + "phpstan/phpstan-phpunit": "^0.12", + "phpunit/phpunit": "^7.0 || ^8.0 || ^9.0" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.2.x-dev" - } - }, "autoload": { "psr-4": { "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/" @@ -360,57 +574,83 @@ { "name": "Marco Pivetta", "email": "ocramius@gmail.com", - "homepage": "http://ocramius.github.com/" + "homepage": "https://ocramius.github.io/" } ], "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", - "homepage": "https://github.com/doctrine/instantiator", + "homepage": "https://www.doctrine-project.org/projects/instantiator.html", "keywords": [ "constructor", "instantiate" ], - "time": "2017-07-22T11:58:36+00:00" + "support": { + "issues": "https://github.com/doctrine/instantiator/issues", + "source": "https://github.com/doctrine/instantiator/tree/1.4.0" + }, + "funding": [ + { + "url": "https://www.doctrine-project.org/sponsorship.html", + "type": "custom" + }, + { + "url": "https://www.patreon.com/phpdoctrine", + "type": "patreon" + }, + { + "url": "https://tidelift.com/funding/github/packagist/doctrine%2Finstantiator", + "type": "tidelift" + } + ], + "time": "2020-11-10T18:47:58+00:00" }, { "name": "guzzlehttp/guzzle", - "version": "6.3.3", + "version": "7.2.0", "source": { "type": "git", "url": "https://github.com/guzzle/guzzle.git", - "reference": "407b0cb880ace85c9b63c5f9551db498cb2d50ba" + "reference": "0aa74dfb41ae110835923ef10a9d803a22d50e79" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/guzzle/zipball/407b0cb880ace85c9b63c5f9551db498cb2d50ba", - "reference": "407b0cb880ace85c9b63c5f9551db498cb2d50ba", + "url": "https://api.github.com/repos/guzzle/guzzle/zipball/0aa74dfb41ae110835923ef10a9d803a22d50e79", + "reference": "0aa74dfb41ae110835923ef10a9d803a22d50e79", "shasum": "" }, "require": { - "guzzlehttp/promises": "^1.0", - "guzzlehttp/psr7": "^1.4", - "php": ">=5.5" + "ext-json": "*", + "guzzlehttp/promises": "^1.4", + "guzzlehttp/psr7": "^1.7", + "php": "^7.2.5 || ^8.0", + "psr/http-client": "^1.0" + }, + "provide": { + "psr/http-client-implementation": "1.0" }, "require-dev": { "ext-curl": "*", - "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.4 || ^7.0", - "psr/log": "^1.0" + "php-http/client-integration-tests": "^3.0", + "phpunit/phpunit": "^8.5.5 || ^9.3.5", + "psr/log": "^1.1" }, "suggest": { + "ext-curl": "Required for CURL handler support", + "ext-intl": "Required for Internationalized Domain Name (IDN) support", "psr/log": "Required for using the Log middleware" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "6.3-dev" + "dev-master": "7.1-dev" } }, "autoload": { - "files": [ - "src/functions_include.php" - ], "psr-4": { "GuzzleHttp\\": "src/" - } + }, + "files": [ + "src/functions_include.php" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -421,6 +661,11 @@ "name": "Michael Dowling", "email": "mtdowling@gmail.com", "homepage": "https://github.com/mtdowling" + }, + { + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com", + "homepage": "https://sagikazarmark.hu" } ], "description": "Guzzle is a PHP HTTP client library", @@ -431,30 +676,54 @@ "framework", "http", "http client", + "psr-18", + "psr-7", "rest", "web service" ], - "time": "2018-04-22T15:46:56+00:00" + "support": { + "issues": "https://github.com/guzzle/guzzle/issues", + "source": "https://github.com/guzzle/guzzle/tree/7.2.0" + }, + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://github.com/Nyholm", + "type": "github" + }, + { + "url": "https://github.com/alexeyshockov", + "type": "github" + }, + { + "url": "https://github.com/gmponos", + "type": "github" + } + ], + "time": "2020-10-10T11:47:56+00:00" }, { "name": "guzzlehttp/promises", - "version": "v1.3.1", + "version": "1.4.0", "source": { "type": "git", "url": "https://github.com/guzzle/promises.git", - "reference": "a59da6cf61d80060647ff4d3eb2c03a2bc694646" + "reference": "60d379c243457e073cff02bc323a2a86cb355631" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/promises/zipball/a59da6cf61d80060647ff4d3eb2c03a2bc694646", - "reference": "a59da6cf61d80060647ff4d3eb2c03a2bc694646", + "url": "https://api.github.com/repos/guzzle/promises/zipball/60d379c243457e073cff02bc323a2a86cb355631", + "reference": "60d379c243457e073cff02bc323a2a86cb355631", "shasum": "" }, "require": { - "php": ">=5.5.0" + "php": ">=5.5" }, "require-dev": { - "phpunit/phpunit": "^4.0" + "symfony/phpunit-bridge": "^4.4 || ^5.1" }, "type": "library", "extra": { @@ -485,37 +754,45 @@ "keywords": [ "promise" ], - "time": "2016-12-20T10:07:11+00:00" + "support": { + "issues": "https://github.com/guzzle/promises/issues", + "source": "https://github.com/guzzle/promises/tree/1.4.0" + }, + "time": "2020-09-30T07:37:28+00:00" }, { "name": "guzzlehttp/psr7", - "version": "1.5.2", + "version": "1.7.0", "source": { "type": "git", "url": "https://github.com/guzzle/psr7.git", - "reference": "9f83dded91781a01c63574e387eaa769be769115" + "reference": "53330f47520498c0ae1f61f7e2c90f55690c06a3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/psr7/zipball/9f83dded91781a01c63574e387eaa769be769115", - "reference": "9f83dded91781a01c63574e387eaa769be769115", + "url": "https://api.github.com/repos/guzzle/psr7/zipball/53330f47520498c0ae1f61f7e2c90f55690c06a3", + "reference": "53330f47520498c0ae1f61f7e2c90f55690c06a3", "shasum": "" }, "require": { "php": ">=5.4.0", "psr/http-message": "~1.0", - "ralouphie/getallheaders": "^2.0.5" + "ralouphie/getallheaders": "^2.0.5 || ^3.0.0" }, "provide": { "psr/http-message-implementation": "1.0" }, "require-dev": { - "phpunit/phpunit": "~4.8.36 || ^5.7.27 || ^6.5.8" + "ext-zlib": "*", + "phpunit/phpunit": "~4.8.36 || ^5.7.27 || ^6.5.14 || ^7.5.20 || ^8.5.8 || ^9.3.10" + }, + "suggest": { + "laminas/laminas-httphandlerrunner": "Emit PSR-7 responses" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.5-dev" + "dev-master": "1.7-dev" } }, "autoload": { @@ -552,35 +829,98 @@ "uri", "url" ], - "time": "2018-12-04T20:46:45+00:00" + "support": { + "issues": "https://github.com/guzzle/psr7/issues", + "source": "https://github.com/guzzle/psr7/tree/1.7.0" + }, + "time": "2020-09-30T07:37:11+00:00" + }, + { + "name": "myclabs/deep-copy", + "version": "1.10.2", + "source": { + "type": "git", + "url": "https://github.com/myclabs/DeepCopy.git", + "reference": "776f831124e9c62e1a2c601ecc52e776d8bb7220" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/776f831124e9c62e1a2c601ecc52e776d8bb7220", + "reference": "776f831124e9c62e1a2c601ecc52e776d8bb7220", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0" + }, + "replace": { + "myclabs/deep-copy": "self.version" + }, + "require-dev": { + "doctrine/collections": "^1.0", + "doctrine/common": "^2.6", + "phpunit/phpunit": "^7.1" + }, + "type": "library", + "autoload": { + "psr-4": { + "DeepCopy\\": "src/DeepCopy/" + }, + "files": [ + "src/DeepCopy/deep_copy.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Create deep copies (clones) of your objects", + "keywords": [ + "clone", + "copy", + "duplicate", + "object", + "object graph" + ], + "support": { + "issues": "https://github.com/myclabs/DeepCopy/issues", + "source": "https://github.com/myclabs/DeepCopy/tree/1.10.2" + }, + "funding": [ + { + "url": "https://tidelift.com/funding/github/packagist/myclabs/deep-copy", + "type": "tidelift" + } + ], + "time": "2020-11-13T09:40:50+00:00" }, { "name": "php-coveralls/php-coveralls", - "version": "v2.1.0", + "version": "v2.4.3", "source": { "type": "git", "url": "https://github.com/php-coveralls/php-coveralls.git", - "reference": "3b00c229726f892bfdadeaf01ea430ffd04a939d" + "reference": "909381bd40a17ae6e9076051f0d73293c1c091af" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-coveralls/php-coveralls/zipball/3b00c229726f892bfdadeaf01ea430ffd04a939d", - "reference": "3b00c229726f892bfdadeaf01ea430ffd04a939d", + "url": "https://api.github.com/repos/php-coveralls/php-coveralls/zipball/909381bd40a17ae6e9076051f0d73293c1c091af", + "reference": "909381bd40a17ae6e9076051f0d73293c1c091af", "shasum": "" }, "require": { "ext-json": "*", "ext-simplexml": "*", - "guzzlehttp/guzzle": "^6.0", - "php": "^5.5 || ^7.0", + "guzzlehttp/guzzle": "^6.0 || ^7.0", + "php": "^5.5 || ^7.0 || ^8.0", "psr/log": "^1.0", - "symfony/config": "^2.1 || ^3.0 || ^4.0", - "symfony/console": "^2.1 || ^3.0 || ^4.0", - "symfony/stopwatch": "^2.0 || ^3.0 || ^4.0", - "symfony/yaml": "^2.0 || ^3.0 || ^4.0" + "symfony/config": "^2.1 || ^3.0 || ^4.0 || ^5.0", + "symfony/console": "^2.1 || ^3.0 || ^4.0 || ^5.0", + "symfony/stopwatch": "^2.0 || ^3.0 || ^4.0 || ^5.0", + "symfony/yaml": "^2.0.5 || ^3.0 || ^4.0 || ^5.0" }, "require-dev": { - "phpunit/phpunit": "^4.8.35 || ^5.4.3 || ^6.0" + "phpunit/phpunit": "^4.8.35 || ^5.4.3 || ^6.0 || ^7.0 || ^8.0 || ^9.0", + "sanmai/phpunit-legacy-adapter": "^6.1 || ^8.0" }, "suggest": { "symfony/http-kernel": "Allows Symfony integration" @@ -589,11 +929,6 @@ "bin/php-coveralls" ], "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.1-dev" - } - }, "autoload": { "psr-4": { "PhpCoveralls\\": "src/" @@ -635,38 +970,46 @@ "github", "test" ], - "time": "2018-05-22T23:11:08+00:00" + "support": { + "issues": "https://github.com/php-coveralls/php-coveralls/issues", + "source": "https://github.com/php-coveralls/php-coveralls/tree/v2.4.3" + }, + "time": "2020-12-24T09:17:03+00:00" }, { - "name": "phpdocumentor/reflection-common", - "version": "1.0.1", + "name": "phpdocumentor/reflection-docblock", + "version": "2.0.5", "source": { "type": "git", - "url": "https://github.com/phpDocumentor/ReflectionCommon.git", - "reference": "21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6" + "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", + "reference": "e6a969a640b00d8daa3c66518b0405fb41ae0c4b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6", - "reference": "21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/e6a969a640b00d8daa3c66518b0405fb41ae0c4b", + "reference": "e6a969a640b00d8daa3c66518b0405fb41ae0c4b", "shasum": "" }, "require": { - "php": ">=5.5" + "php": ">=5.3.3" }, "require-dev": { - "phpunit/phpunit": "^4.6" + "phpunit/phpunit": "~4.0" + }, + "suggest": { + "dflydev/markdown": "~1.0", + "erusev/parsedown": "~1.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0.x-dev" + "dev-master": "2.0.x-dev" } }, "autoload": { - "psr-4": { - "phpDocumentor\\Reflection\\": [ - "src" + "psr-0": { + "phpDocumentor": [ + "src/" ] } }, @@ -676,57 +1019,47 @@ ], "authors": [ { - "name": "Jaap van Otterdijk", - "email": "opensource@ijaap.nl" + "name": "Mike van Riel", + "email": "mike.vanriel@naenius.com" } ], - "description": "Common reflection classes used by phpdocumentor to reflect the code structure", - "homepage": "http://www.phpdoc.org", - "keywords": [ - "FQSEN", - "phpDocumentor", - "phpdoc", - "reflection", - "static analysis" - ], - "time": "2017-09-11T18:02:19+00:00" + "support": { + "issues": "https://github.com/phpDocumentor/ReflectionDocBlock/issues", + "source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/release/2.x" + }, + "time": "2016-01-25T08:17:30+00:00" }, { - "name": "phpdocumentor/reflection-docblock", - "version": "4.3.0", + "name": "phpspec/prophecy", + "version": "v1.5.0", "source": { "type": "git", - "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", - "reference": "94fd0001232e47129dd3504189fa1c7225010d08" + "url": "https://github.com/phpspec/prophecy.git", + "reference": "4745ded9307786b730d7a60df5cb5a6c43cf95f7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/94fd0001232e47129dd3504189fa1c7225010d08", - "reference": "94fd0001232e47129dd3504189fa1c7225010d08", + "url": "https://api.github.com/repos/phpspec/prophecy/zipball/4745ded9307786b730d7a60df5cb5a6c43cf95f7", + "reference": "4745ded9307786b730d7a60df5cb5a6c43cf95f7", "shasum": "" }, "require": { - "php": "^7.0", - "phpdocumentor/reflection-common": "^1.0.0", - "phpdocumentor/type-resolver": "^0.4.0", - "webmozart/assert": "^1.0" + "doctrine/instantiator": "^1.0.2", + "phpdocumentor/reflection-docblock": "~2.0", + "sebastian/comparator": "~1.1" }, "require-dev": { - "doctrine/instantiator": "~1.0.5", - "mockery/mockery": "^1.0", - "phpunit/phpunit": "^6.4" + "phpspec/phpspec": "~2.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "4.x-dev" + "dev-master": "1.4.x-dev" } }, "autoload": { - "psr-4": { - "phpDocumentor\\Reflection\\": [ - "src/" - ] + "psr-0": { + "Prophecy\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", @@ -735,44 +1068,69 @@ ], "authors": [ { - "name": "Mike van Riel", - "email": "me@mikevanriel.com" + "name": "Konstantin Kudryashov", + "email": "ever.zet@gmail.com", + "homepage": "http://everzet.com" + }, + { + "name": "Marcello Duarte", + "email": "marcello.duarte@gmail.com" } ], - "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", - "time": "2017-11-30T07:14:17+00:00" + "description": "Highly opinionated mocking framework for PHP 5.3+", + "homepage": "https://github.com/phpspec/prophecy", + "keywords": [ + "Double", + "Dummy", + "fake", + "mock", + "spy", + "stub" + ], + "support": { + "issues": "https://github.com/phpspec/prophecy/issues", + "source": "https://github.com/phpspec/prophecy/tree/master" + }, + "time": "2015-08-13T10:07:40+00:00" }, { - "name": "phpdocumentor/type-resolver", - "version": "0.4.0", + "name": "phpstan/phpdoc-parser", + "version": "0.4.9", "source": { "type": "git", - "url": "https://github.com/phpDocumentor/TypeResolver.git", - "reference": "9c977708995954784726e25d0cd1dddf4e65b0f7" + "url": "https://github.com/phpstan/phpdoc-parser.git", + "reference": "98a088b17966bdf6ee25c8a4b634df313d8aa531" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/9c977708995954784726e25d0cd1dddf4e65b0f7", - "reference": "9c977708995954784726e25d0cd1dddf4e65b0f7", + "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/98a088b17966bdf6ee25c8a4b634df313d8aa531", + "reference": "98a088b17966bdf6ee25c8a4b634df313d8aa531", "shasum": "" }, "require": { - "php": "^5.5 || ^7.0", - "phpdocumentor/reflection-common": "^1.0" + "php": "^7.1 || ^8.0" }, "require-dev": { - "mockery/mockery": "^0.9.4", - "phpunit/phpunit": "^5.2||^4.8.24" + "consistence/coding-standard": "^3.5", + "ergebnis/composer-normalize": "^2.0.2", + "jakub-onderka/php-parallel-lint": "^0.9.2", + "phing/phing": "^2.16.0", + "phpstan/extension-installer": "^1.0", + "phpstan/phpstan": "^0.12.26", + "phpstan/phpstan-strict-rules": "^0.12", + "phpunit/phpunit": "^6.3", + "slevomat/coding-standard": "^4.7.2", + "symfony/process": "^4.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0.x-dev" + "dev-master": "0.4-dev" } }, "autoload": { "psr-4": { - "phpDocumentor\\Reflection\\": [ + "PHPStan\\PhpDocParser\\": [ "src/" ] } @@ -781,118 +1139,55 @@ "license": [ "MIT" ], - "authors": [ - { - "name": "Mike van Riel", - "email": "me@mikevanriel.com" - } - ], - "time": "2017-07-14T14:27:02+00:00" + "description": "PHPDoc parser with support for nullable, intersection and generic types", + "support": { + "issues": "https://github.com/phpstan/phpdoc-parser/issues", + "source": "https://github.com/phpstan/phpdoc-parser/tree/master" + }, + "time": "2020-08-03T20:32:43+00:00" }, { - "name": "phpspec/prophecy", - "version": "1.8.0", + "name": "phpunit/php-code-coverage", + "version": "3.2.0", "source": { "type": "git", - "url": "https://github.com/phpspec/prophecy.git", - "reference": "4ba436b55987b4bf311cb7c6ba82aa528aac0a06" + "url": "https://github.com/sebastianbergmann/php-code-coverage.git", + "reference": "85f5db2d0a0da79ad6a256eb54148ba383059ad9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpspec/prophecy/zipball/4ba436b55987b4bf311cb7c6ba82aa528aac0a06", - "reference": "4ba436b55987b4bf311cb7c6ba82aa528aac0a06", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/85f5db2d0a0da79ad6a256eb54148ba383059ad9", + "reference": "85f5db2d0a0da79ad6a256eb54148ba383059ad9", "shasum": "" }, "require": { - "doctrine/instantiator": "^1.0.2", - "php": "^5.3|^7.0", - "phpdocumentor/reflection-docblock": "^2.0|^3.0.2|^4.0", - "sebastian/comparator": "^1.1|^2.0|^3.0", - "sebastian/recursion-context": "^1.0|^2.0|^3.0" + "php": ">=5.6", + "phpunit/php-file-iterator": "~1.3", + "phpunit/php-text-template": "~1.2", + "phpunit/php-token-stream": "~1.3", + "sebastian/code-unit-reverse-lookup": "~1.0", + "sebastian/environment": "^1.3.2", + "sebastian/version": "~1.0|~2.0" }, "require-dev": { - "phpspec/phpspec": "^2.5|^3.2", - "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.5 || ^7.1" + "ext-xdebug": ">=2.1.4", + "phpunit/phpunit": "~5" + }, + "suggest": { + "ext-dom": "*", + "ext-xdebug": ">=2.2.1", + "ext-xmlwriter": "*" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.8.x-dev" + "dev-master": "3.2.x-dev" } }, "autoload": { - "psr-0": { - "Prophecy\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Konstantin Kudryashov", - "email": "ever.zet@gmail.com", - "homepage": "http://everzet.com" - }, - { - "name": "Marcello Duarte", - "email": "marcello.duarte@gmail.com" - } - ], - "description": "Highly opinionated mocking framework for PHP 5.3+", - "homepage": "https://github.com/phpspec/prophecy", - "keywords": [ - "Double", - "Dummy", - "fake", - "mock", - "spy", - "stub" - ], - "time": "2018-08-05T17:53:17+00:00" - }, - { - "name": "phpunit/php-code-coverage", - "version": "2.2.4", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "eabf68b476ac7d0f73793aada060f1c1a9bf8979" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/eabf68b476ac7d0f73793aada060f1c1a9bf8979", - "reference": "eabf68b476ac7d0f73793aada060f1c1a9bf8979", - "shasum": "" - }, - "require": { - "php": ">=5.3.3", - "phpunit/php-file-iterator": "~1.3", - "phpunit/php-text-template": "~1.2", - "phpunit/php-token-stream": "~1.3", - "sebastian/environment": "^1.3.2", - "sebastian/version": "~1.0" - }, - "require-dev": { - "ext-xdebug": ">=2.1.4", - "phpunit/phpunit": "~4" - }, - "suggest": { - "ext-dom": "*", - "ext-xdebug": ">=2.2.1", - "ext-xmlwriter": "*" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.2.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] + "classmap": [ + "src/" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -912,7 +1207,12 @@ "testing", "xunit" ], - "time": "2015-10-06T15:47:00+00:00" + "support": { + "irc": "irc://irc.freenode.net/phpunit", + "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/3.2.0" + }, + "time": "2016-02-13T06:47:56+00:00" }, { "name": "phpunit/php-file-iterator", @@ -959,6 +1259,11 @@ "filesystem", "iterator" ], + "support": { + "irc": "irc://irc.freenode.net/phpunit", + "issues": "https://github.com/sebastianbergmann/php-file-iterator/issues", + "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/1.4.5" + }, "time": "2017-11-27T13:52:08+00:00" }, { @@ -1000,32 +1305,36 @@ "keywords": [ "template" ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-text-template/issues", + "source": "https://github.com/sebastianbergmann/php-text-template/tree/1.2.1" + }, "time": "2015-06-21T13:50:34+00:00" }, { "name": "phpunit/php-timer", - "version": "1.0.9", + "version": "5.0.3", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-timer.git", - "reference": "3dcf38ca72b158baf0bc245e9184d3fdffa9c46f" + "reference": "5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/3dcf38ca72b158baf0bc245e9184d3fdffa9c46f", - "reference": "3dcf38ca72b158baf0bc245e9184d3fdffa9c46f", + "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2", + "reference": "5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2", "shasum": "" }, "require": { - "php": "^5.3.3 || ^7.0" + "php": ">=7.3" }, "require-dev": { - "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0" + "phpunit/phpunit": "^9.3" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0-dev" + "dev-master": "5.0-dev" } }, "autoload": { @@ -1040,7 +1349,7 @@ "authors": [ { "name": "Sebastian Bergmann", - "email": "sb@sebastian-bergmann.de", + "email": "sebastian@phpunit.de", "role": "lead" } ], @@ -1049,7 +1358,17 @@ "keywords": [ "timer" ], - "time": "2017-02-26T11:10:40+00:00" + "support": { + "issues": "https://github.com/sebastianbergmann/php-timer/issues", + "source": "https://github.com/sebastianbergmann/php-timer/tree/5.0.3" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T13:16:10+00:00" }, { "name": "phpunit/php-token-stream", @@ -1098,30 +1417,35 @@ "keywords": [ "tokenizer" ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-token-stream/issues", + "source": "https://github.com/sebastianbergmann/php-token-stream/tree/1.4" + }, + "abandoned": true, "time": "2017-12-04T08:55:13+00:00" }, { "name": "phpunit/phpcov", - "version": "2.0.2", + "version": "3.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpcov.git", - "reference": "9ef291483ff65eefd8639584d61bbfb044d747f3" + "reference": "78cb486efff5c297d8b6a6f9091eb9211173785f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpcov/zipball/9ef291483ff65eefd8639584d61bbfb044d747f3", - "reference": "9ef291483ff65eefd8639584d61bbfb044d747f3", + "url": "https://api.github.com/repos/sebastianbergmann/phpcov/zipball/78cb486efff5c297d8b6a6f9091eb9211173785f", + "reference": "78cb486efff5c297d8b6a6f9091eb9211173785f", "shasum": "" }, "require": { - "php": ">=5.3.3", - "phpunit/php-code-coverage": "~2.0", - "phpunit/phpunit": ">=4.1", + "php": ">=5.6", + "phpunit/php-code-coverage": "~3.0", + "phpunit/phpunit": "~5.0", "sebastian/diff": "~1.1", "sebastian/finder-facade": "~1.1", "sebastian/version": "~1.0", - "symfony/console": "~2.2" + "symfony/console": "~2|~3" }, "bin": [ "phpcov" @@ -1129,7 +1453,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "2.0.x-dev" + "dev-master": "3.0.x-dev" } }, "autoload": { @@ -1150,20 +1474,24 @@ ], "description": "CLI frontend for PHP_CodeCoverage", "homepage": "https://github.com/sebastianbergmann/phpcov", - "time": "2015-10-05T09:24:23+00:00" + "support": { + "issues": "https://github.com/sebastianbergmann/phpcov/issues", + "source": "https://github.com/sebastianbergmann/phpcov/tree/3.0.0" + }, + "time": "2016-01-09T05:29:58+00:00" }, { "name": "phpunit/phpunit", - "version": "4.8.36", + "version": "5.2.7", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "46023de9a91eec7dfb06cc56cb4e260017298517" + "reference": "073701643835376cb2f15dc005ea8933f8d4edbd" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/46023de9a91eec7dfb06cc56cb4e260017298517", - "reference": "46023de9a91eec7dfb06cc56cb4e260017298517", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/073701643835376cb2f15dc005ea8933f8d4edbd", + "reference": "073701643835376cb2f15dc005ea8933f8d4edbd", "shasum": "" }, "require": { @@ -1172,19 +1500,21 @@ "ext-pcre": "*", "ext-reflection": "*", "ext-spl": "*", - "php": ">=5.3.3", + "myclabs/deep-copy": "~1.3", + "php": ">=5.6", "phpspec/prophecy": "^1.3.1", - "phpunit/php-code-coverage": "~2.1", + "phpunit/php-code-coverage": "~3.2", "phpunit/php-file-iterator": "~1.4", "phpunit/php-text-template": "~1.2", - "phpunit/php-timer": "^1.0.6", - "phpunit/phpunit-mock-objects": "~2.3", - "sebastian/comparator": "~1.2.2", + "phpunit/php-timer": ">=1.0.6", + "phpunit/phpunit-mock-objects": ">=3.0.5", + "sebastian/comparator": "~1.1", "sebastian/diff": "~1.2", "sebastian/environment": "~1.3", "sebastian/exporter": "~1.2", "sebastian/global-state": "~1.0", - "sebastian/version": "~1.0", + "sebastian/resource-operations": "~1.0", + "sebastian/version": "~1.0|~2.0", "symfony/yaml": "~2.1|~3.0" }, "suggest": { @@ -1196,7 +1526,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "4.8.x-dev" + "dev-master": "5.2.x-dev" } }, "autoload": { @@ -1222,30 +1552,35 @@ "testing", "xunit" ], - "time": "2017-06-21T08:07:12+00:00" + "support": { + "irc": "irc://irc.freenode.net/phpunit", + "issues": "https://github.com/sebastianbergmann/phpunit/issues", + "source": "https://github.com/sebastianbergmann/phpunit/tree/5.2.7" + }, + "time": "2016-02-18T06:39:51+00:00" }, { "name": "phpunit/phpunit-mock-objects", - "version": "2.3.8", + "version": "3.1.3", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git", - "reference": "ac8e7a3db35738d56ee9a76e78a4e03d97628983" + "reference": "151c96874bff6fe61a25039df60e776613a61489" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/ac8e7a3db35738d56ee9a76e78a4e03d97628983", - "reference": "ac8e7a3db35738d56ee9a76e78a4e03d97628983", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/151c96874bff6fe61a25039df60e776613a61489", + "reference": "151c96874bff6fe61a25039df60e776613a61489", "shasum": "" }, "require": { "doctrine/instantiator": "^1.0.2", - "php": ">=5.3.3", + "php": ">=5.6", "phpunit/php-text-template": "~1.2", "sebastian/exporter": "~1.2" }, "require-dev": { - "phpunit/phpunit": "~4.4" + "phpunit/phpunit": "~5" }, "suggest": { "ext-soap": "*" @@ -1253,7 +1588,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "2.3.x-dev" + "dev-master": "3.1.x-dev" } }, "autoload": { @@ -1278,7 +1613,118 @@ "mock", "xunit" ], - "time": "2015-10-02T06:51:40+00:00" + "support": { + "irc": "irc://irc.freenode.net/phpunit", + "issues": "https://github.com/sebastianbergmann/phpunit-mock-objects/issues", + "source": "https://github.com/sebastianbergmann/phpunit-mock-objects/tree/3.1" + }, + "abandoned": true, + "time": "2016-04-20T14:39:26+00:00" + }, + { + "name": "psr/container", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/container.git", + "reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/container/zipball/b7ce3b176482dbbc1245ebf52b181af44c2cf55f", + "reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Container\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common Container Interface (PHP FIG PSR-11)", + "homepage": "https://github.com/php-fig/container", + "keywords": [ + "PSR-11", + "container", + "container-interface", + "container-interop", + "psr" + ], + "support": { + "issues": "https://github.com/php-fig/container/issues", + "source": "https://github.com/php-fig/container/tree/master" + }, + "time": "2017-02-14T16:28:37+00:00" + }, + { + "name": "psr/http-client", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-client.git", + "reference": "2dfb5f6c5eff0e91e20e913f8c5452ed95b86621" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-client/zipball/2dfb5f6c5eff0e91e20e913f8c5452ed95b86621", + "reference": "2dfb5f6c5eff0e91e20e913f8c5452ed95b86621", + "shasum": "" + }, + "require": { + "php": "^7.0 || ^8.0", + "psr/http-message": "^1.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Client\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common interface for HTTP clients", + "homepage": "https://github.com/php-fig/http-client", + "keywords": [ + "http", + "http-client", + "psr", + "psr-18" + ], + "support": { + "source": "https://github.com/php-fig/http-client/tree/master" + }, + "time": "2020-06-29T06:28:15+00:00" }, { "name": "psr/http-message", @@ -1328,20 +1774,23 @@ "request", "response" ], + "support": { + "source": "https://github.com/php-fig/http-message/tree/master" + }, "time": "2016-08-06T14:39:51+00:00" }, { "name": "psr/log", - "version": "1.1.0", + "version": "1.1.3", "source": { "type": "git", "url": "https://github.com/php-fig/log.git", - "reference": "6c001f1daafa3a3ac1d8ff69ee4db8e799a654dd" + "reference": "0f73288fd15629204f9d42b7055f72dacbe811fc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/log/zipball/6c001f1daafa3a3ac1d8ff69ee4db8e799a654dd", - "reference": "6c001f1daafa3a3ac1d8ff69ee4db8e799a654dd", + "url": "https://api.github.com/repos/php-fig/log/zipball/0f73288fd15629204f9d42b7055f72dacbe811fc", + "reference": "0f73288fd15629204f9d42b7055f72dacbe811fc", "shasum": "" }, "require": { @@ -1350,7 +1799,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0.x-dev" + "dev-master": "1.1.x-dev" } }, "autoload": { @@ -1375,28 +1824,31 @@ "psr", "psr-3" ], - "time": "2018-11-20T15:27:04+00:00" + "support": { + "source": "https://github.com/php-fig/log/tree/1.1.3" + }, + "time": "2020-03-23T09:12:05+00:00" }, { "name": "ralouphie/getallheaders", - "version": "2.0.5", + "version": "3.0.3", "source": { "type": "git", "url": "https://github.com/ralouphie/getallheaders.git", - "reference": "5601c8a83fbba7ef674a7369456d12f1e0d0eafa" + "reference": "120b605dfeb996808c31b6477290a714d356e822" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/ralouphie/getallheaders/zipball/5601c8a83fbba7ef674a7369456d12f1e0d0eafa", - "reference": "5601c8a83fbba7ef674a7369456d12f1e0d0eafa", + "url": "https://api.github.com/repos/ralouphie/getallheaders/zipball/120b605dfeb996808c31b6477290a714d356e822", + "reference": "120b605dfeb996808c31b6477290a714d356e822", "shasum": "" }, "require": { - "php": ">=5.3" + "php": ">=5.6" }, "require-dev": { - "phpunit/phpunit": "~3.7.0", - "satooshi/php-coveralls": ">=1.0" + "php-coveralls/php-coveralls": "^2.1", + "phpunit/phpunit": "^5 || ^6.5" }, "type": "library", "autoload": { @@ -1415,7 +1867,66 @@ } ], "description": "A polyfill for getallheaders.", - "time": "2016-02-11T07:05:27+00:00" + "support": { + "issues": "https://github.com/ralouphie/getallheaders/issues", + "source": "https://github.com/ralouphie/getallheaders/tree/develop" + }, + "time": "2019-03-08T08:55:37+00:00" + }, + { + "name": "sebastian/code-unit-reverse-lookup", + "version": "1.0.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", + "reference": "1de8cd5c010cb153fcd68b8d0f64606f523f7619" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/1de8cd5c010cb153fcd68b8d0f64606f523f7619", + "reference": "1de8cd5c010cb153fcd68b8d0f64606f523f7619", + "shasum": "" + }, + "require": { + "php": ">=5.6" + }, + "require-dev": { + "phpunit/phpunit": "^8.5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Looks up which function or method a line of code belongs to", + "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/", + "support": { + "issues": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/issues", + "source": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/tree/1.0.2" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-11-30T08:15:22+00:00" }, { "name": "sebastian/comparator", @@ -1479,27 +1990,31 @@ "compare", "equality" ], + "support": { + "issues": "https://github.com/sebastianbergmann/comparator/issues", + "source": "https://github.com/sebastianbergmann/comparator/tree/1.2" + }, "time": "2017-01-29T09:50:25+00:00" }, { "name": "sebastian/diff", - "version": "1.4.3", + "version": "1.4.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/diff.git", - "reference": "7f066a26a962dbe58ddea9f72a4e82874a3975a4" + "reference": "13edfd8706462032c2f52b4b862974dd46b71c9e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/7f066a26a962dbe58ddea9f72a4e82874a3975a4", - "reference": "7f066a26a962dbe58ddea9f72a4e82874a3975a4", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/13edfd8706462032c2f52b4b862974dd46b71c9e", + "reference": "13edfd8706462032c2f52b4b862974dd46b71c9e", "shasum": "" }, "require": { - "php": "^5.3.3 || ^7.0" + "php": ">=5.3.3" }, "require-dev": { - "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0" + "phpunit/phpunit": "~4.8" }, "type": "library", "extra": { @@ -1531,27 +2046,31 @@ "keywords": [ "diff" ], - "time": "2017-05-22T07:24:03+00:00" + "support": { + "issues": "https://github.com/sebastianbergmann/diff/issues", + "source": "https://github.com/sebastianbergmann/diff/tree/master" + }, + "time": "2015-12-08T07:14:41+00:00" }, { "name": "sebastian/environment", - "version": "1.3.8", + "version": "1.3.7", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/environment.git", - "reference": "be2c607e43ce4c89ecd60e75c6a85c126e754aea" + "reference": "4e8f0da10ac5802913afc151413bc8c53b6c2716" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/be2c607e43ce4c89ecd60e75c6a85c126e754aea", - "reference": "be2c607e43ce4c89ecd60e75c6a85c126e754aea", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/4e8f0da10ac5802913afc151413bc8c53b6c2716", + "reference": "4e8f0da10ac5802913afc151413bc8c53b6c2716", "shasum": "" }, "require": { - "php": "^5.3.3 || ^7.0" + "php": ">=5.3.3" }, "require-dev": { - "phpunit/phpunit": "^4.8 || ^5.0" + "phpunit/phpunit": "~4.4" }, "type": "library", "extra": { @@ -1581,7 +2100,11 @@ "environment", "hhvm" ], - "time": "2016-08-18T05:49:44+00:00" + "support": { + "issues": "https://github.com/sebastianbergmann/environment/issues", + "source": "https://github.com/sebastianbergmann/environment/tree/1.3.7" + }, + "time": "2016-05-17T03:18:57+00:00" }, { "name": "sebastian/exporter", @@ -1648,6 +2171,10 @@ "export", "exporter" ], + "support": { + "issues": "https://github.com/sebastianbergmann/exporter/issues", + "source": "https://github.com/sebastianbergmann/exporter/tree/master" + }, "time": "2016-06-17T09:04:28+00:00" }, { @@ -1687,6 +2214,11 @@ ], "description": "FinderFacade is a convenience wrapper for Symfony's Finder component.", "homepage": "https://github.com/sebastianbergmann/finder-facade", + "support": { + "issues": "https://github.com/sebastianbergmann/finder-facade/issues", + "source": "https://github.com/sebastianbergmann/finder-facade/tree/master" + }, + "abandoned": true, "time": "2017-11-18T17:31:49+00:00" }, { @@ -1738,6 +2270,10 @@ "keywords": [ "global state" ], + "support": { + "issues": "https://github.com/sebastianbergmann/global-state/issues", + "source": "https://github.com/sebastianbergmann/global-state/tree/1.1.1" + }, "time": "2015-10-12T03:26:01+00:00" }, { @@ -1791,8 +2327,58 @@ ], "description": "Provides functionality to recursively process PHP variables", "homepage": "http://www.github.com/sebastianbergmann/recursion-context", + "support": { + "issues": "https://github.com/sebastianbergmann/recursion-context/issues", + "source": "https://github.com/sebastianbergmann/recursion-context/tree/master" + }, "time": "2016-10-03T07:41:43+00:00" }, + { + "name": "sebastian/resource-operations", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/resource-operations.git", + "reference": "ce990bb21759f94aeafd30209e8cfcdfa8bc3f52" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/ce990bb21759f94aeafd30209e8cfcdfa8bc3f52", + "reference": "ce990bb21759f94aeafd30209e8cfcdfa8bc3f52", + "shasum": "" + }, + "require": { + "php": ">=5.6.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Provides a list of PHP built-in functions that operate on resources", + "homepage": "https://www.github.com/sebastianbergmann/resource-operations", + "support": { + "issues": "https://github.com/sebastianbergmann/resource-operations/issues", + "source": "https://github.com/sebastianbergmann/resource-operations/tree/master" + }, + "time": "2015-07-28T20:34:47+00:00" + }, { "name": "sebastian/version", "version": "1.0.6", @@ -1826,35 +2412,100 @@ ], "description": "Library that helps with managing the version number of Git-hosted PHP projects", "homepage": "https://github.com/sebastianbergmann/version", + "support": { + "issues": "https://github.com/sebastianbergmann/version/issues", + "source": "https://github.com/sebastianbergmann/version/tree/1.0.6" + }, "time": "2015-06-21T13:59:46+00:00" }, { - "name": "squizlabs/php_codesniffer", - "version": "3.4.0", + "name": "slevomat/coding-standard", + "version": "6.4.1", "source": { "type": "git", - "url": "https://github.com/squizlabs/PHP_CodeSniffer.git", - "reference": "379deb987e26c7cd103a7b387aea178baec96e48" + "url": "https://github.com/slevomat/coding-standard.git", + "reference": "696dcca217d0c9da2c40d02731526c1e25b65346" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/379deb987e26c7cd103a7b387aea178baec96e48", - "reference": "379deb987e26c7cd103a7b387aea178baec96e48", + "url": "https://api.github.com/repos/slevomat/coding-standard/zipball/696dcca217d0c9da2c40d02731526c1e25b65346", + "reference": "696dcca217d0c9da2c40d02731526c1e25b65346", "shasum": "" }, "require": { - "ext-simplexml": "*", - "ext-tokenizer": "*", - "ext-xmlwriter": "*", - "php": ">=5.4.0" + "dealerdirect/phpcodesniffer-composer-installer": "^0.6.2 || ^0.7", + "php": "^7.1 || ^8.0", + "phpstan/phpdoc-parser": "0.4.5 - 0.4.9", + "squizlabs/php_codesniffer": "^3.5.6" }, "require-dev": { - "phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0" + "phing/phing": "2.16.3", + "php-parallel-lint/php-parallel-lint": "1.2.0", + "phpstan/phpstan": "0.12.48", + "phpstan/phpstan-deprecation-rules": "0.12.5", + "phpstan/phpstan-phpunit": "0.12.16", + "phpstan/phpstan-strict-rules": "0.12.5", + "phpunit/phpunit": "7.5.20|8.5.5|9.4.0" }, - "bin": [ - "bin/phpcs", - "bin/phpcbf" - ], + "type": "phpcodesniffer-standard", + "extra": { + "branch-alias": { + "dev-master": "6.x-dev" + } + }, + "autoload": { + "psr-4": { + "SlevomatCodingStandard\\": "SlevomatCodingStandard" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Slevomat Coding Standard for PHP_CodeSniffer complements Consistence Coding Standard by providing sniffs with additional checks.", + "support": { + "issues": "https://github.com/slevomat/coding-standard/issues", + "source": "https://github.com/slevomat/coding-standard/tree/6.4.1" + }, + "funding": [ + { + "url": "https://github.com/kukulich", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/slevomat/coding-standard", + "type": "tidelift" + } + ], + "time": "2020-10-05T12:39:37+00:00" + }, + { + "name": "squizlabs/php_codesniffer", + "version": "3.5.8", + "source": { + "type": "git", + "url": "https://github.com/squizlabs/PHP_CodeSniffer.git", + "reference": "9d583721a7157ee997f235f327de038e7ea6dac4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/9d583721a7157ee997f235f327de038e7ea6dac4", + "reference": "9d583721a7157ee997f235f327de038e7ea6dac4", + "shasum": "" + }, + "require": { + "ext-simplexml": "*", + "ext-tokenizer": "*", + "ext-xmlwriter": "*", + "php": ">=5.4.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0" + }, + "bin": [ + "bin/phpcs", + "bin/phpcbf" + ], "type": "library", "extra": { "branch-alias": { @@ -1872,50 +2523,53 @@ } ], "description": "PHP_CodeSniffer tokenizes PHP, JavaScript and CSS files and detects violations of a defined set of coding standards.", - "homepage": "http://www.squizlabs.com/php-codesniffer", + "homepage": "https://github.com/squizlabs/PHP_CodeSniffer", "keywords": [ "phpcs", "standards" ], - "time": "2018-12-19T23:57:18+00:00" + "support": { + "issues": "https://github.com/squizlabs/PHP_CodeSniffer/issues", + "source": "https://github.com/squizlabs/PHP_CodeSniffer", + "wiki": "https://github.com/squizlabs/PHP_CodeSniffer/wiki" + }, + "time": "2020-10-23T02:01:07+00:00" }, { "name": "symfony/config", - "version": "v4.2.3", + "version": "v5.2.3", "source": { "type": "git", "url": "https://github.com/symfony/config.git", - "reference": "25a2e7abe0d97e70282537292e3df45cf6da7b98" + "reference": "50e0e1314a3b2609d32b6a5a0d0fb5342494c4ab" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/config/zipball/25a2e7abe0d97e70282537292e3df45cf6da7b98", - "reference": "25a2e7abe0d97e70282537292e3df45cf6da7b98", + "url": "https://api.github.com/repos/symfony/config/zipball/50e0e1314a3b2609d32b6a5a0d0fb5342494c4ab", + "reference": "50e0e1314a3b2609d32b6a5a0d0fb5342494c4ab", "shasum": "" }, "require": { - "php": "^7.1.3", - "symfony/filesystem": "~3.4|~4.0", - "symfony/polyfill-ctype": "~1.8" + "php": ">=7.2.5", + "symfony/deprecation-contracts": "^2.1", + "symfony/filesystem": "^4.4|^5.0", + "symfony/polyfill-ctype": "~1.8", + "symfony/polyfill-php80": "^1.15" }, "conflict": { - "symfony/finder": "<3.4" + "symfony/finder": "<4.4" }, "require-dev": { - "symfony/dependency-injection": "~3.4|~4.0", - "symfony/event-dispatcher": "~3.4|~4.0", - "symfony/finder": "~3.4|~4.0", - "symfony/yaml": "~3.4|~4.0" + "symfony/event-dispatcher": "^4.4|^5.0", + "symfony/finder": "^4.4|^5.0", + "symfony/messenger": "^4.4|^5.0", + "symfony/service-contracts": "^1.1|^2", + "symfony/yaml": "^4.4|^5.0" }, "suggest": { "symfony/yaml": "To use the yaml reference dumper" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.2-dev" - } - }, "autoload": { "psr-4": { "Symfony\\Component\\Config\\": "" @@ -1938,45 +2592,68 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony Config Component", + "description": "Helps you find, load, combine, autofill and validate configuration values of any kind", "homepage": "https://symfony.com", - "time": "2019-01-30T11:44:30+00:00" + "support": { + "source": "https://github.com/symfony/config/tree/v5.2.3" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2021-01-27T10:15:41+00:00" }, { "name": "symfony/console", - "version": "v2.8.49", + "version": "v3.4.47", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "cbcf4b5e233af15cd2bbd50dee1ccc9b7927dc12" + "reference": "a10b1da6fc93080c180bba7219b5ff5b7518fe81" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/cbcf4b5e233af15cd2bbd50dee1ccc9b7927dc12", - "reference": "cbcf4b5e233af15cd2bbd50dee1ccc9b7927dc12", + "url": "https://api.github.com/repos/symfony/console/zipball/a10b1da6fc93080c180bba7219b5ff5b7518fe81", + "reference": "a10b1da6fc93080c180bba7219b5ff5b7518fe81", "shasum": "" }, "require": { - "php": ">=5.3.9", - "symfony/debug": "^2.7.2|~3.0.0", + "php": "^5.5.9|>=7.0.8", + "symfony/debug": "~2.8|~3.0|~4.0", "symfony/polyfill-mbstring": "~1.0" }, + "conflict": { + "symfony/dependency-injection": "<3.4", + "symfony/process": "<3.3" + }, + "provide": { + "psr/log-implementation": "1.0" + }, "require-dev": { "psr/log": "~1.0", - "symfony/event-dispatcher": "~2.1|~3.0.0", - "symfony/process": "~2.1|~3.0.0" + "symfony/config": "~3.3|~4.0", + "symfony/dependency-injection": "~3.4|~4.0", + "symfony/event-dispatcher": "~2.8|~3.0|~4.0", + "symfony/lock": "~3.4|~4.0", + "symfony/process": "~3.3|~4.0" }, "suggest": { - "psr/log-implementation": "For using the console logger", + "psr/log": "For using the console logger", "symfony/event-dispatcher": "", + "symfony/lock": "", "symfony/process": "" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.8-dev" - } - }, "autoload": { "psr-4": { "Symfony\\Component\\Console\\": "" @@ -2001,48 +2678,57 @@ ], "description": "Symfony Console Component", "homepage": "https://symfony.com", - "time": "2018-11-20T15:55:20+00:00" + "support": { + "source": "https://github.com/symfony/console/tree/v3.4.47" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2020-10-24T10:57:07+00:00" }, { - "name": "symfony/contracts", - "version": "v1.0.2", + "name": "symfony/debug", + "version": "v4.4.19", "source": { "type": "git", - "url": "https://github.com/symfony/contracts.git", - "reference": "1aa7ab2429c3d594dd70689604b5cf7421254cdf" + "url": "https://github.com/symfony/debug.git", + "reference": "af4987aa4a5630e9615be9d9c3ed1b0f24ca449c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/contracts/zipball/1aa7ab2429c3d594dd70689604b5cf7421254cdf", - "reference": "1aa7ab2429c3d594dd70689604b5cf7421254cdf", + "url": "https://api.github.com/repos/symfony/debug/zipball/af4987aa4a5630e9615be9d9c3ed1b0f24ca449c", + "reference": "af4987aa4a5630e9615be9d9c3ed1b0f24ca449c", "shasum": "" }, "require": { - "php": "^7.1.3" + "php": ">=7.1.3", + "psr/log": "~1.0", + "symfony/polyfill-php80": "^1.15" }, - "require-dev": { - "psr/cache": "^1.0", - "psr/container": "^1.0" + "conflict": { + "symfony/http-kernel": "<3.4" }, - "suggest": { - "psr/cache": "When using the Cache contracts", - "psr/container": "When using the Service contracts", - "symfony/cache-contracts-implementation": "", - "symfony/service-contracts-implementation": "", - "symfony/translation-contracts-implementation": "" + "require-dev": { + "symfony/http-kernel": "^3.4|^4.0|^5.0" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0-dev" - } - }, "autoload": { "psr-4": { - "Symfony\\Contracts\\": "" + "Symfony\\Component\\Debug\\": "" }, "exclude-from-classmap": [ - "**/Tests/" + "/Tests/" ] }, "notification-url": "https://packagist.org/downloads/", @@ -2051,63 +2737,65 @@ ], "authors": [ { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" + "name": "Fabien Potencier", + "email": "fabien@symfony.com" }, { "name": "Symfony Community", "homepage": "https://symfony.com/contributors" } ], - "description": "A set of abstractions extracted out of the Symfony components", + "description": "Provides tools to ease debugging PHP code", "homepage": "https://symfony.com", - "keywords": [ - "abstractions", - "contracts", - "decoupling", - "interfaces", - "interoperability", - "standards" + "support": { + "source": "https://github.com/symfony/debug/tree/v4.4.19" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } ], - "time": "2018-12-05T08:06:11+00:00" + "time": "2021-01-27T09:09:26+00:00" }, { - "name": "symfony/debug", - "version": "v3.0.9", + "name": "symfony/deprecation-contracts", + "version": "v2.2.0", "source": { "type": "git", - "url": "https://github.com/symfony/debug.git", - "reference": "697c527acd9ea1b2d3efac34d9806bf255278b0a" + "url": "https://github.com/symfony/deprecation-contracts.git", + "reference": "5fa56b4074d1ae755beb55617ddafe6f5d78f665" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/debug/zipball/697c527acd9ea1b2d3efac34d9806bf255278b0a", - "reference": "697c527acd9ea1b2d3efac34d9806bf255278b0a", + "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/5fa56b4074d1ae755beb55617ddafe6f5d78f665", + "reference": "5fa56b4074d1ae755beb55617ddafe6f5d78f665", "shasum": "" }, "require": { - "php": ">=5.5.9", - "psr/log": "~1.0" - }, - "conflict": { - "symfony/http-kernel": ">=2.3,<2.3.24|~2.4.0|>=2.5,<2.5.9|>=2.6,<2.6.2" - }, - "require-dev": { - "symfony/class-loader": "~2.8|~3.0", - "symfony/http-kernel": "~2.8|~3.0" + "php": ">=7.1" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "3.0-dev" + "dev-master": "2.2-dev" + }, + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" } }, "autoload": { - "psr-4": { - "Symfony\\Component\\Debug\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" + "files": [ + "function.php" ] }, "notification-url": "https://packagist.org/downloads/", @@ -2116,42 +2804,54 @@ ], "authors": [ { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" + "name": "Nicolas Grekas", + "email": "p@tchwork.com" }, { "name": "Symfony Community", "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony Debug Component", + "description": "A generic function and convention to trigger deprecation notices", "homepage": "https://symfony.com", - "time": "2016-07-30T07:22:48+00:00" + "support": { + "source": "https://github.com/symfony/deprecation-contracts/tree/master" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2020-09-07T11:33:47+00:00" }, { "name": "symfony/filesystem", - "version": "v4.2.3", + "version": "v5.2.3", "source": { "type": "git", "url": "https://github.com/symfony/filesystem.git", - "reference": "7c16ebc2629827d4ec915a52ac809768d060a4ee" + "reference": "262d033b57c73e8b59cd6e68a45c528318b15038" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/filesystem/zipball/7c16ebc2629827d4ec915a52ac809768d060a4ee", - "reference": "7c16ebc2629827d4ec915a52ac809768d060a4ee", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/262d033b57c73e8b59cd6e68a45c528318b15038", + "reference": "262d033b57c73e8b59cd6e68a45c528318b15038", "shasum": "" }, "require": { - "php": "^7.1.3", + "php": ">=7.2.5", "symfony/polyfill-ctype": "~1.8" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.2-dev" - } - }, "autoload": { "psr-4": { "Symfony\\Component\\Filesystem\\": "" @@ -2174,33 +2874,45 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony Filesystem Component", + "description": "Provides basic utilities for the filesystem", "homepage": "https://symfony.com", - "time": "2019-01-16T20:35:37+00:00" + "support": { + "source": "https://github.com/symfony/filesystem/tree/v5.2.3" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2021-01-27T10:01:46+00:00" }, { "name": "symfony/finder", - "version": "v4.2.3", + "version": "v4.4.19", "source": { "type": "git", "url": "https://github.com/symfony/finder.git", - "reference": "ef71816cbb264988bb57fe6a73f610888b9aa70c" + "reference": "25d79cfccfc12e84e7a63a248c3f0720fdd92db6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/ef71816cbb264988bb57fe6a73f610888b9aa70c", - "reference": "ef71816cbb264988bb57fe6a73f610888b9aa70c", + "url": "https://api.github.com/repos/symfony/finder/zipball/25d79cfccfc12e84e7a63a248c3f0720fdd92db6", + "reference": "25d79cfccfc12e84e7a63a248c3f0720fdd92db6", "shasum": "" }, "require": { - "php": "^7.1.3" + "php": ">=7.1.3" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.2-dev" - } - }, "autoload": { "psr-4": { "Symfony\\Component\\Finder\\": "" @@ -2223,26 +2935,43 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony Finder Component", + "description": "Finds files and directories via an intuitive fluent interface", "homepage": "https://symfony.com", - "time": "2019-01-16T20:35:37+00:00" + "support": { + "source": "https://github.com/symfony/finder/tree/v4.4.19" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2021-01-27T09:09:26+00:00" }, { "name": "symfony/polyfill-ctype", - "version": "v1.10.0", + "version": "v1.22.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-ctype.git", - "reference": "e3d826245268269cd66f8326bd8bc066687b4a19" + "reference": "c6c942b1ac76c82448322025e084cadc56048b4e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/e3d826245268269cd66f8326bd8bc066687b4a19", - "reference": "e3d826245268269cd66f8326bd8bc066687b4a19", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/c6c942b1ac76c82448322025e084cadc56048b4e", + "reference": "c6c942b1ac76c82448322025e084cadc56048b4e", "shasum": "" }, "require": { - "php": ">=5.3.3" + "php": ">=7.1" }, "suggest": { "ext-ctype": "For best performance" @@ -2250,7 +2979,11 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.9-dev" + "dev-main": "1.22-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" } }, "autoload": { @@ -2266,13 +2999,13 @@ "MIT" ], "authors": [ - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - }, { "name": "Gert de Pagter", "email": "BackEndTea@gmail.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" } ], "description": "Symfony polyfill for ctype functions", @@ -2283,24 +3016,41 @@ "polyfill", "portable" ], - "time": "2018-08-06T14:22:27+00:00" + "support": { + "source": "https://github.com/symfony/polyfill-ctype/tree/v1.22.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2021-01-07T16:49:33+00:00" }, { "name": "symfony/polyfill-mbstring", - "version": "v1.10.0", + "version": "v1.22.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "c79c051f5b3a46be09205c73b80b346e4153e494" + "reference": "f377a3dd1fde44d37b9831d68dc8dea3ffd28e13" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/c79c051f5b3a46be09205c73b80b346e4153e494", - "reference": "c79c051f5b3a46be09205c73b80b346e4153e494", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/f377a3dd1fde44d37b9831d68dc8dea3ffd28e13", + "reference": "f377a3dd1fde44d37b9831d68dc8dea3ffd28e13", "shasum": "" }, "require": { - "php": ">=5.3.3" + "php": ">=7.1" }, "suggest": { "ext-mbstring": "For best performance" @@ -2308,7 +3058,11 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.9-dev" + "dev-main": "1.22-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" } }, "autoload": { @@ -2342,32 +3096,206 @@ "portable", "shim" ], - "time": "2018-09-21T13:07:52+00:00" + "support": { + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.22.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2021-01-07T16:49:33+00:00" }, { - "name": "symfony/stopwatch", - "version": "v4.2.3", + "name": "symfony/polyfill-php80", + "version": "v1.22.0", "source": { "type": "git", - "url": "https://github.com/symfony/stopwatch.git", - "reference": "b1a5f646d56a3290230dbc8edf2a0d62cda23f67" + "url": "https://github.com/symfony/polyfill-php80.git", + "reference": "dc3063ba22c2a1fd2f45ed856374d79114998f91" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/stopwatch/zipball/b1a5f646d56a3290230dbc8edf2a0d62cda23f67", - "reference": "b1a5f646d56a3290230dbc8edf2a0d62cda23f67", + "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/dc3063ba22c2a1fd2f45ed856374d79114998f91", + "reference": "dc3063ba22c2a1fd2f45ed856374d79114998f91", "shasum": "" }, "require": { - "php": "^7.1.3", - "symfony/contracts": "^1.0" + "php": ">=7.1" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "4.2-dev" + "dev-main": "1.22-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Php80\\": "" + }, + "files": [ + "bootstrap.php" + ], + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ion Bazan", + "email": "ion.bazan@gmail.com" + }, + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-php80/tree/v1.22.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2021-01-07T16:49:33+00:00" + }, + { + "name": "symfony/service-contracts", + "version": "v2.2.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/service-contracts.git", + "reference": "d15da7ba4957ffb8f1747218be9e1a121fd298a1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/service-contracts/zipball/d15da7ba4957ffb8f1747218be9e1a121fd298a1", + "reference": "d15da7ba4957ffb8f1747218be9e1a121fd298a1", + "shasum": "" + }, + "require": { + "php": ">=7.2.5", + "psr/container": "^1.0" + }, + "suggest": { + "symfony/service-implementation": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.2-dev" + }, + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Contracts\\Service\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" } + ], + "description": "Generic abstractions related to writing services", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], + "support": { + "source": "https://github.com/symfony/service-contracts/tree/master" }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2020-09-07T11:33:47+00:00" + }, + { + "name": "symfony/stopwatch", + "version": "v5.2.3", + "source": { + "type": "git", + "url": "https://github.com/symfony/stopwatch.git", + "reference": "b12274acfab9d9850c52583d136a24398cdf1a0c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/stopwatch/zipball/b12274acfab9d9850c52583d136a24398cdf1a0c", + "reference": "b12274acfab9d9850c52583d136a24398cdf1a0c", + "shasum": "" + }, + "require": { + "php": ">=7.2.5", + "symfony/service-contracts": "^1.0|^2" + }, + "type": "library", "autoload": { "psr-4": { "Symfony\\Component\\Stopwatch\\": "" @@ -2390,39 +3318,55 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony Stopwatch Component", + "description": "Provides a way to profile code", "homepage": "https://symfony.com", - "time": "2019-01-16T20:31:39+00:00" + "support": { + "source": "https://github.com/symfony/stopwatch/tree/v5.2.3" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2021-01-27T10:15:41+00:00" }, { "name": "symfony/yaml", - "version": "v3.3.18", + "version": "v3.4.47", "source": { "type": "git", "url": "https://github.com/symfony/yaml.git", - "reference": "af615970e265543a26ee712c958404eb9b7ac93d" + "reference": "88289caa3c166321883f67fe5130188ebbb47094" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/af615970e265543a26ee712c958404eb9b7ac93d", - "reference": "af615970e265543a26ee712c958404eb9b7ac93d", + "url": "https://api.github.com/repos/symfony/yaml/zipball/88289caa3c166321883f67fe5130188ebbb47094", + "reference": "88289caa3c166321883f67fe5130188ebbb47094", "shasum": "" }, "require": { - "php": "^5.5.9|>=7.0.8" + "php": "^5.5.9|>=7.0.8", + "symfony/polyfill-ctype": "~1.8" + }, + "conflict": { + "symfony/console": "<3.4" }, "require-dev": { - "symfony/console": "~2.8|~3.0" + "symfony/console": "~3.4|~4.0" }, "suggest": { "symfony/console": "For validating YAML files using the lint command" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.3-dev" - } - }, "autoload": { "psr-4": { "Symfony\\Component\\Yaml\\": "" @@ -2447,7 +3391,24 @@ ], "description": "Symfony Yaml Component", "homepage": "https://symfony.com", - "time": "2018-01-20T15:04:53+00:00" + "support": { + "source": "https://github.com/symfony/yaml/tree/v3.4.47" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2020-10-24T10:57:07+00:00" }, { "name": "theseer/fdomdocument", @@ -2487,69 +3448,25 @@ ], "description": "The classes contained within this repository extend the standard DOM to use exceptions at all occasions of errors instead of PHP warnings or notices. They also add various custom methods and shortcuts for convenience and to simplify the usage of DOM.", "homepage": "https://github.com/theseer/fDOMDocument", - "time": "2017-06-30T11:53:12+00:00" - }, - { - "name": "webmozart/assert", - "version": "1.4.0", - "source": { - "type": "git", - "url": "https://github.com/webmozart/assert.git", - "reference": "83e253c8e0be5b0257b881e1827274667c5c17a9" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/webmozart/assert/zipball/83e253c8e0be5b0257b881e1827274667c5c17a9", - "reference": "83e253c8e0be5b0257b881e1827274667c5c17a9", - "shasum": "" - }, - "require": { - "php": "^5.3.3 || ^7.0", - "symfony/polyfill-ctype": "^1.8" - }, - "require-dev": { - "phpunit/phpunit": "^4.6", - "sebastian/version": "^1.0.1" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.3-dev" - } + "support": { + "issues": "https://github.com/theseer/fDOMDocument/issues", + "source": "https://github.com/theseer/fDOMDocument/tree/master" }, - "autoload": { - "psr-4": { - "Webmozart\\Assert\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Bernhard Schussek", - "email": "bschussek@gmail.com" - } - ], - "description": "Assertions to validate method input/output with nice error messages.", - "keywords": [ - "assert", - "check", - "validate" - ], - "time": "2018-12-25T11:19:39+00:00" + "time": "2017-06-30T11:53:12+00:00" } ], "aliases": [], "minimum-stability": "stable", "stability-flags": { - "b23prodtm/markdown-plugin": 20 + "betothreeprod/markdown-plugin": 20, + "betothreeprod/updateshell": 20, + "cakephp/datasources": 20 }, "prefer-stable": false, "prefer-lowest": false, "platform": { - "php": "^5.6 || ^7" + "php": "^5.6 || ^7 || ^8" }, - "platform-dev": [] + "platform-dev": [], + "plugin-api-version": "2.0.0" } diff --git a/configure.sh b/configure.sh index 48a58e49a..c50583a34 100755 --- a/configure.sh +++ b/configure.sh @@ -1,59 +1,97 @@ -#!/bin/bash -set -e -source ./Scripts/lib/shell_prompt.sh -source ./Scripts/lib/parsing.sh -openshift=$(parse_arg_exists "-[oO]*|--openshift" $*) -if [ $openshift 2> /dev/null ]; then - echo "Real environment bootargs..." +#!/usr/bin/env bash +set -eu +TOPDIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) +# shellcheck source=Scripts/lib/test/logging.sh +. "$TOPDIR/Scripts/lib/logging.sh" +# shellcheck source=Scripts/lib/test/parsing.sh +. "$TOPDIR/Scripts/lib/parsing.sh" +# shellcheck source=Scripts/lib/test/shell_prompt.sh +. "$TOPDIR/Scripts/lib/shell_prompt.sh" +openshift=$(parse_arg "-[oO]+|--openshift" "$@") +docker=$(parse_arg "--docker" "$@") +pargs=$(parse_arg_trim "--docker|-[oO]+|--openshift" "$@") +if [ -n "$openshift" ]; then + slogger -st "$0" "Bootargs...: ${pargs}" + # shellcheck source=Scripts/bootargs.sh + . "$TOPDIR/Scripts/bootargs.sh" "$@" else - echo "Provided local/test bootargs..." - source ./Scripts/bootargs.sh $* + slogger -st "$0" "Locally Testing values, bootargs...: ${pargs}" + # shellcheck source=Scripts/fooargs.sh + . "$TOPDIR/Scripts/fooargs.sh" "$@" fi -saved=("$*") +usage=("" \ +"Usage: $0 [-m] [--openshift] [-c] [-h [-p password -s salt [-f filename]]]" \ +" [-m] [--openshift] [-c][[-d|--mig-database] [options]]" \ +" --openshift -d Using real environment variables to migrate database" \ +" -c,--const Reset to $TOPDIR/app/webroot/php-cms/etc/constantes-template.properties" \ +" -h,--hash Reset administrator password hash:" \ +" -p -s [-f ]" \ +" Set administrator with md5 . Optional file to save a shell script export." \ +" -m,--submodule Update sub-modules from Git" \ +" -d, --mig-database [options]" \ +" Migrate Database (see $0 --mig-database --help)" \ +" --development Install composer dependencies" \ +" -a, --apache2 Make apache2 VirtualHost configuration from templates: etc/apache2/site.tpl..." \ +"") +composer_args="require --no-interaction --update-no-dev" +saved=("$@") +show_password_status "${DATABASE_USER}" "${MYSQL_ROOT_PASSWORD}" "is configuring ${openshift} ${docker}..." #; if the full set of the arguments exists, there won't be any prompt in the shell -while [[ "$#" > 0 ]]; do case $1 in - -[cC]*|--const) - shell_prompt "./Scripts/config_etc_const.sh" "${cyan}Step 1. Overwrite constantes.properties\n${nc}" "-Y" - ;; - -[hH]*|--hash) +while [[ "$#" -gt 0 ]]; do case $1 in + -[cC]*|--const) + # shellcheck disable=SC2154 + shell_prompt "$TOPDIR/Scripts/config_etc_const.sh" "${cyan}Step 1. Overwrite constantes.properties\n${nc}" "-Y" + ;; + -[hH]*|--hash) #; get hash password - shell_prompt "./Scripts/config_etc_pass.sh $*" "${cyan}Step 2. Get a hashed password with encryption, PHP encrypts.\n${nc}" "-Y" - ;; - -[dD]*|--mig-database) - #; Know-How : In Openshift 3, configure a CakePhp-Mysql-persistent docker image. Set automatic deployment with _100%_ unavailability - #; If it starts a build, it automatically scales deployments down to zero, and deploys and scales up when it's finished to build. - #; Be sure that lib/Cake/Console/cake test app and Health checks should return gracefullly, or the pods get terminated after a short time. - #; [[-d|--mig-database] [-u]] argument fixes up : Error: Database connection "Mysql" is missing, or could not be created. - args="" - shift - if [ $openshift 2> /dev/null ]; then args="--openshift "; fi - shell_prompt "./migrate-database.sh ${args}$*" "${cyan}Step 3. Migrate database\n${nc}" '-Y' - break;; - -[sS]*|-[pP]*|-[fF]*) - #; void source script known args - shift;; - -[mM]*|--submodule) - git submodule update --init --recursive --force;; - --help ) - echo "Usage: $0 [-m] [-c] [-h [-p password -s salt [-f filename]]] [[-d|--mig-database] [options]] - -c,--const - Reset to app/webroot/php_cms/etc/constantes-template.properties - -h,--hash - Reset administrator password hash - -p -s [-f ] - Set administrator with md5 . Optional file to save a shell script export. - -m,--submodule - Update sub-modules from Git - -d, --mig-database [options] - Migrate Database (see ./migrate-database.sh --help)" - exit 0;; - -[oO]*|--openshift ) - show_password_status $DATABASE_USER $DATABASE_PASSWORD "is configuring openshift...";; - -[vV]*|--verbose ) - echo "Passed params : $0 ${saved}";; - *) echo "Unknown parameter passed: $0 $1"; exit 1;; + shell_prompt "$TOPDIR/Scripts/config_etc_pass.sh ${*:2}" "${cyan}Step 2. Get a hashed password with encryption, PHP encrypts.\n${nc}" "-Y" + ;; + -[dD]*|--mig-database) + #; Know-How : In Openshift 3, configure a CakePhp-Mysql-persistent docker image. Set automatic deployment with _100%_ unavailability + #; If it starts a build, it automatically scales deployments down to zero, and deploys and scales up when it's finished to build. + #; Be sure that lib/Cake/Console/cake test app and Health checks should return gracefullly, or the pods get terminated after a short time. + #; [[-d|--mig-database] [-u]] argument fixes up : Error: Database connection "Mysql" is missing, or could not be created. + shell_prompt "$TOPDIR/migrate-database.sh ${docker} ${openshift} ${*:2}" "${cyan}Step 3. Migrate database\n${nc}" "-Y" + break;; + -[sS]*|-[pP]*|-[fF]*) + #; void --hash password known args + OPTIND=1 + if [[ "$#" -gt 1 ]]; then + arg=$2; [[ "${arg:0:1}" != '-' ]] && OPTIND=2 + fi + shift $((OPTIND -1)) + ;; + -[mM]*|--submodule) + git submodule sync && git submodule update --init --recursive --force;; + --help ) + printf "%s\n" "${usage[@]}" + exit 0;; + -[oO]*|--openshift|--travis ) + # shellcheck disable=SC2154 + echo -e "${green}Fixing some file permissions...${nc}" + # shellcheck source=Scripts/configure_tmp.sh + bash -c "$TOPDIR/Scripts/configure_tmp.sh" + ;; + --docker ) + slogger -st docker "check database container id" + docker ps -q -a -f "name=$(docker_name "$SECONDARY_HUB")" + ;; + --development ) + composer_args="require --no-interaction" + ;; + -[aA]*|--apache ) + # shellcheck disable=SC2154 + echo -e "${green}Adding VirtualHost...${nc}" + # shellcheck source=Scripts/config_a2ensite.sh + bash -c "$TOPDIR/Scripts/config_a2ensite.sh $TOPDIR/app/webroot $TOPDIR/etc/apache2" + ;; + -[vV]*|--verbose ) + set -x + echo "Passed params : ${BASH_SOURCE[*]} ${saved[*]}";; + *) echo "Unknown parameter passed: ${BASH_SOURCE[0]} $1"; exit 1;; esac; shift; done -echo -e "${green}Fixing some file permissions...${nc}" -[ $openshift 2> /dev/null ] && echo "None." || source ./Scripts/configure_tmp.sh +slogger -st sed "Cake 2.x patches" +#; patches +patches "lib/Cake/Console/ShellDispatcher.php" "lib/Cake/Console/ConsoleOutput.php" "app/Config/core.php" #; update plugins and dependencies -source ./Scripts/composer.sh "--dev --no-interaction" +bash -c "$TOPDIR/Scripts/composer.sh ${composer_args}" diff --git a/deploy.sh b/deploy.sh new file mode 100755 index 000000000..cba020e55 --- /dev/null +++ b/deploy.sh @@ -0,0 +1,5 @@ +#!/usr/bin/env bash +rm -f mysqldb/conf.d/custom.cnf +# Fixes: unbound variables on ubuntu +DOCKER_USER="${DOCKER_USER:-betothreeprod}" COLUMNS=0 LINES=0 SYSTEMD_NO_WRAP=0 \ +balena_deploy "${BASH_SOURCE[0]}" "$@" diff --git a/deployment/images/apache-php7/Dockerfile.armhf b/deployment/images/apache-php7/Dockerfile.armhf new file mode 100644 index 000000000..1672f4b74 --- /dev/null +++ b/deployment/images/apache-php7/Dockerfile.armhf @@ -0,0 +1,106 @@ +# +# Source DockerFile: https://github.com/ulsmith/rpi-raspbian-apache-php/blob/master/Dockerfile +# S6 Overlay: https://github.com/smebberson/docker-alpine/blob/master/alpine-apache/Dockerfile +# +FROM balenalib/raspberrypi3-alpine-node:run +RUN [ "cross-build-start" ] +ARG PHP_LIB +ENV PHP_LIB ${PHP_LIB:-7} + +## Install add-apt-repository packages +RUN apk update \ + && apk add \ + bash \ + sudo \ + curl \ + git \ + openssh-client \ + tar \ + gzip \ + ca-certificates \ + zip \ + unzip \ + icu-dev \ + libmcrypt-dev \ + freetype-dev \ + libjpeg-turbo-dev \ + libpng-dev \ + netcat-openbsd + +RUN apk update \ + && apk add \ + php${PHP_LIB} \ + php${PHP_LIB}-curl \ + php${PHP_LIB}-gd \ + php${PHP_LIB}-intl \ + php${PHP_LIB}-json \ + php${PHP_LIB}-mbstring \ + php${PHP_LIB}-opcache \ + php${PHP_LIB}-openssl \ + php${PHP_LIB}-pcntl \ + php${PHP_LIB}-xml \ + php${PHP_LIB}-mysqlnd \ + php${PHP_LIB}-phar \ + php${PHP_LIB}-mysqli \ + php${PHP_LIB}-pdo_mysql \ + php${PHP_LIB}-dom \ + php${PHP_LIB}-tokenizer \ + php${PHP_LIB}-simplexml \ + php${PHP_LIB}-xmlwriter \ + php${PHP_LIB}-fpm \ + php${PHP_LIB}-zlib \ + mariadb-client \ + && apk del build-base \ + && rm -rf /var/cache/apk/* + +## Install base packages +RUN apk update \ + && apk add \ + apache2 \ + apache2-ctl \ + apache2-ssl \ + php${PHP_LIB}-dev \ + php${PHP_LIB}-apache2 \ + curl \ + php${PHP_LIB}-odbc \ + php${PHP_LIB}-pdo_sqlite \ + php${PHP_LIB}-sqlite3 \ + php${PHP_LIB}-session \ + && apk del build-base \ + && rm -rf /var/cache/apk/* + +# Backup default instance +RUN mkdir -p /etc/apache2/conf-available/ \ + && cp /etc/apache2/*.conf /etc/apache2/conf-available/ + +# just containers configuration +COPY etc /etc + +# Expose the ports for apache +EXPOSE 80 443 + +# Stream apache logs to standard outputs +RUN ln -sf /dev/stdout /var/log/apache2/access.log && \ + ln -sf /dev/stderr /var/log/apache2/error.log + +# ADD S6 Overlay +ARG S6_ARCH +ENV S6_ARCH ${S6_ARCH:-armhf} +ARG S6_RELEASE +ENV S6_RELEASE ${S6_RELEASE:-v2.0.0.1} +ENV S6_REPO https://github.com/just-containers/s6-overlay/releases/download +ADD ${S6_REPO}/${S6_RELEASE}/s6-overlay-${S6_ARCH}.tar.gz /tmp/ +ADD ${S6_REPO}/${S6_RELEASE}/s6-overlay-${S6_ARCH}.tar.gz.sig /tmp/ +RUN curl https://keybase.io/justcontainers/key.asc | gpg --import +WORKDIR / +RUN gunzip -c /tmp/s6-overlay-${S6_ARCH}.tar.gz | tar -xf - -C / && \ + gpg --verify /tmp/s6-overlay-${S6_ARCH}.tar.gz.sig /tmp/s6-overlay-${S6_ARCH}.tar.gz + +ENV UDEV on + +ADD "https://raw.githubusercontent.com/b23prodtm/docker-systemctl-replacement/master/files/docker/systemctl3.py" /bin/systemctl +RUN chmod g+xs /bin/systemctl + +ENTRYPOINT /init +RUN node -v && npm -v +RUN [ "cross-build-end" ] diff --git a/deployment/images/apache-php7/Dockerfile.template b/deployment/images/apache-php7/Dockerfile.template new file mode 100644 index 000000000..75c57f583 --- /dev/null +++ b/deployment/images/apache-php7/Dockerfile.template @@ -0,0 +1,106 @@ +# +# Source DockerFile: https://github.com/ulsmith/rpi-raspbian-apache-php/blob/master/Dockerfile +# S6 Overlay: https://github.com/smebberson/docker-alpine/blob/master/alpine-apache/Dockerfile +# +FROM balenalib/%%BALENA_MACHINE_NAME%%-alpine-node:run +# RUN [ "cross-build-start" ] +ARG PHP_LIB +ENV PHP_LIB ${PHP_LIB:-7} + +## Install add-apt-repository packages +RUN apk update \ + && apk add \ + bash \ + sudo \ + curl \ + git \ + openssh-client \ + tar \ + gzip \ + ca-certificates \ + zip \ + unzip \ + icu-dev \ + libmcrypt-dev \ + freetype-dev \ + libjpeg-turbo-dev \ + libpng-dev \ + netcat-openbsd + +RUN apk update \ + && apk add \ + php${PHP_LIB} \ + php${PHP_LIB}-curl \ + php${PHP_LIB}-gd \ + php${PHP_LIB}-intl \ + php${PHP_LIB}-json \ + php${PHP_LIB}-mbstring \ + php${PHP_LIB}-opcache \ + php${PHP_LIB}-openssl \ + php${PHP_LIB}-pcntl \ + php${PHP_LIB}-xml \ + php${PHP_LIB}-mysqlnd \ + php${PHP_LIB}-phar \ + php${PHP_LIB}-mysqli \ + php${PHP_LIB}-pdo_mysql \ + php${PHP_LIB}-dom \ + php${PHP_LIB}-tokenizer \ + php${PHP_LIB}-simplexml \ + php${PHP_LIB}-xmlwriter \ + php${PHP_LIB}-fpm \ + php${PHP_LIB}-zlib \ + mariadb-client \ + && apk del build-base \ + && rm -rf /var/cache/apk/* + +## Install base packages +RUN apk update \ + && apk add \ + apache2 \ + apache2-ctl \ + apache2-ssl \ + php${PHP_LIB}-dev \ + php${PHP_LIB}-apache2 \ + curl \ + php${PHP_LIB}-odbc \ + php${PHP_LIB}-pdo_sqlite \ + php${PHP_LIB}-sqlite3 \ + php${PHP_LIB}-session \ + && apk del build-base \ + && rm -rf /var/cache/apk/* + +# Backup default instance +RUN mkdir -p /etc/apache2/conf-available/ \ + && cp /etc/apache2/*.conf /etc/apache2/conf-available/ + +# just containers configuration +COPY etc /etc + +# Expose the ports for apache +EXPOSE 80 443 + +# Stream apache logs to standard outputs +RUN ln -sf /dev/stdout /var/log/apache2/access.log && \ + ln -sf /dev/stderr /var/log/apache2/error.log + +# ADD S6 Overlay +ARG S6_ARCH +ENV S6_ARCH ${S6_ARCH:-armhf} +ARG S6_RELEASE +ENV S6_RELEASE ${S6_RELEASE:-v2.0.0.1} +ENV S6_REPO https://github.com/just-containers/s6-overlay/releases/download +ADD ${S6_REPO}/${S6_RELEASE}/s6-overlay-${S6_ARCH}.tar.gz /tmp/ +ADD ${S6_REPO}/${S6_RELEASE}/s6-overlay-${S6_ARCH}.tar.gz.sig /tmp/ +RUN curl https://keybase.io/justcontainers/key.asc | gpg --import +WORKDIR / +RUN gunzip -c /tmp/s6-overlay-${S6_ARCH}.tar.gz | tar -xf - -C / && \ + gpg --verify /tmp/s6-overlay-${S6_ARCH}.tar.gz.sig /tmp/s6-overlay-${S6_ARCH}.tar.gz + +ENV UDEV on + +ADD "https://raw.githubusercontent.com/b23prodtm/docker-systemctl-replacement/master/files/docker/systemctl3.py" /bin/systemctl +RUN chmod g+xs /bin/systemctl + +ENTRYPOINT /init +RUN node -v && npm -v +# RUN [ "cross-build-end" ] diff --git a/deployment/images/apache-php7/Dockerfile.x86_64 b/deployment/images/apache-php7/Dockerfile.x86_64 new file mode 100644 index 000000000..42458cb16 --- /dev/null +++ b/deployment/images/apache-php7/Dockerfile.x86_64 @@ -0,0 +1,106 @@ +# +# Source DockerFile: https://github.com/ulsmith/rpi-raspbian-apache-php/blob/master/Dockerfile +# S6 Overlay: https://github.com/smebberson/docker-alpine/blob/master/alpine-apache/Dockerfile +# +FROM balenalib/intel-nuc-alpine-node:run +# RUN [ "cross-build-start" ] +ARG PHP_LIB +ENV PHP_LIB ${PHP_LIB:-7} + +## Install add-apt-repository packages +RUN apk update \ + && apk add \ + bash \ + sudo \ + curl \ + git \ + openssh-client \ + tar \ + gzip \ + ca-certificates \ + zip \ + unzip \ + icu-dev \ + libmcrypt-dev \ + freetype-dev \ + libjpeg-turbo-dev \ + libpng-dev \ + netcat-openbsd + +RUN apk update \ + && apk add \ + php${PHP_LIB} \ + php${PHP_LIB}-curl \ + php${PHP_LIB}-gd \ + php${PHP_LIB}-intl \ + php${PHP_LIB}-json \ + php${PHP_LIB}-mbstring \ + php${PHP_LIB}-opcache \ + php${PHP_LIB}-openssl \ + php${PHP_LIB}-pcntl \ + php${PHP_LIB}-xml \ + php${PHP_LIB}-mysqlnd \ + php${PHP_LIB}-phar \ + php${PHP_LIB}-mysqli \ + php${PHP_LIB}-pdo_mysql \ + php${PHP_LIB}-dom \ + php${PHP_LIB}-tokenizer \ + php${PHP_LIB}-simplexml \ + php${PHP_LIB}-xmlwriter \ + php${PHP_LIB}-fpm \ + php${PHP_LIB}-zlib \ + mariadb-client \ + && apk del build-base \ + && rm -rf /var/cache/apk/* + +## Install base packages +RUN apk update \ + && apk add \ + apache2 \ + apache2-ctl \ + apache2-ssl \ + php${PHP_LIB}-dev \ + php${PHP_LIB}-apache2 \ + curl \ + php${PHP_LIB}-odbc \ + php${PHP_LIB}-pdo_sqlite \ + php${PHP_LIB}-sqlite3 \ + php${PHP_LIB}-session \ + && apk del build-base \ + && rm -rf /var/cache/apk/* + +# Backup default instance +RUN mkdir -p /etc/apache2/conf-available/ \ + && cp /etc/apache2/*.conf /etc/apache2/conf-available/ + +# just containers configuration +COPY etc /etc + +# Expose the ports for apache +EXPOSE 80 443 + +# Stream apache logs to standard outputs +RUN ln -sf /dev/stdout /var/log/apache2/access.log && \ + ln -sf /dev/stderr /var/log/apache2/error.log + +# ADD S6 Overlay +ARG S6_ARCH +ENV S6_ARCH ${S6_ARCH:-armhf} +ARG S6_RELEASE +ENV S6_RELEASE ${S6_RELEASE:-v2.0.0.1} +ENV S6_REPO https://github.com/just-containers/s6-overlay/releases/download +ADD ${S6_REPO}/${S6_RELEASE}/s6-overlay-${S6_ARCH}.tar.gz /tmp/ +ADD ${S6_REPO}/${S6_RELEASE}/s6-overlay-${S6_ARCH}.tar.gz.sig /tmp/ +RUN curl https://keybase.io/justcontainers/key.asc | gpg --import +WORKDIR / +RUN gunzip -c /tmp/s6-overlay-${S6_ARCH}.tar.gz | tar -xf - -C / && \ + gpg --verify /tmp/s6-overlay-${S6_ARCH}.tar.gz.sig /tmp/s6-overlay-${S6_ARCH}.tar.gz + +ENV UDEV on + +ADD "https://raw.githubusercontent.com/b23prodtm/docker-systemctl-replacement/master/files/docker/systemctl3.py" /bin/systemctl +RUN chmod g+xs /bin/systemctl + +ENTRYPOINT /init +RUN node -v && npm -v +# RUN [ "cross-build-end" ] diff --git a/deployment/images/apache-php7/README.md b/deployment/images/apache-php7/README.md new file mode 100644 index 000000000..3f402f616 --- /dev/null +++ b/deployment/images/apache-php7/README.md @@ -0,0 +1,65 @@ + + +- [Apache/PHP7 on Docker](#https://hub.docker.com/repository/docker/betothreeprod/raspberrypi3-php) + + [Source repository layout](#source-repository-layout) + + [Compatibility](#compatibility) + + [License](#license) + + + +Apache/PHP7 on Docker +=============================== + +* **.htaccess** + + To allow Apache server to browse directly to the app/webroot folder on server-side, use mod_rewrite rules, as provided by .htaccess files. + + >/.htaccess + + + RewriteEngine on + # Uncomment if you have a .well-known directory in the root folder, e.g. for the Let's Encrypt challenge + # https://tools.ietf.org/html/rfc5785 + #RewriteRule ^(\.well-known/.*)$ $1 [L] + RewriteRule ^$ app/webroot/ [L] + RewriteRule (.*) app/webroot/$1 [L] + + +* **.env files** + + Set environment variables as the following arguments, for instance on MacOS X: + + ./deploy.sh amd64 --nobuild + + Use a .env file in shell to configure up with RaspberryPI3 hosts : + + ./deploy.sh arm32 --nobuild + + .env -> arm32v7.env + + ./deploy.sh arm32 --balena + +### Compatibility + +* PHP 7 's recommended, excluding any alpha or beta versions. +* Container builder: docker-compose 1.19 and DockerFile version 2 +* Mysql 5.7 and later (or MariaDB 10.1 and later) +* Cloud Platforms: + + Openshift 3 + + Balena Cloud + + Kubernetes (not provided) + +### License + Copyright 2019 www.b23prodtm.info + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + * [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0) + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/deployment/images/apache-php7/common.env b/deployment/images/apache-php7/common.env new file mode 120000 index 000000000..cf1366dd2 --- /dev/null +++ b/deployment/images/apache-php7/common.env @@ -0,0 +1 @@ +/Users/wwwb23prodtminfo/NetBeansProjects/OpenShift/acake2php/common.env \ No newline at end of file diff --git a/deployment/images/apache-php7/etc/apache2/conf.d/site.conf b/deployment/images/apache-php7/etc/apache2/conf.d/site.conf new file mode 100644 index 000000000..bc3cbee3e --- /dev/null +++ b/deployment/images/apache-php7/etc/apache2/conf.d/site.conf @@ -0,0 +1,11 @@ + + ServerAdmin webmaster@localhost + DocumentRoot localhost/htdocs + + Options FollowSymLinks + AllowOverride All + Order allow,deny + Allow from All + Require all granted + + diff --git a/deployment/images/apache-php7/etc/services.d/apache/finish b/deployment/images/apache-php7/etc/services.d/apache/finish new file mode 100755 index 000000000..a6543b896 --- /dev/null +++ b/deployment/images/apache-php7/etc/services.d/apache/finish @@ -0,0 +1,8 @@ +#!/usr/bin/execlineb -S1 + +# only tell s6 to bring down the entire container, if it isn't already doing so +# http://skarnet.org/software/s6/s6-supervise.html +if { s6-test ${1} -ne 0 } +if { s6-test ${1} -ne 256 } + +s6-svscanctl -t /var/run/s6/services diff --git a/deployment/images/apache-php7/etc/services.d/apache/run b/deployment/images/apache-php7/etc/services.d/apache/run new file mode 100755 index 000000000..00904e838 --- /dev/null +++ b/deployment/images/apache-php7/etc/services.d/apache/run @@ -0,0 +1,3 @@ +#!/usr/bin/with-contenv sh + +exec /usr/sbin/apachectl -DFOREGROUND; diff --git a/deployment/images/build.sh b/deployment/images/build.sh new file mode 100755 index 000000000..ddce31d83 --- /dev/null +++ b/deployment/images/build.sh @@ -0,0 +1,2 @@ +#!/usr/bin/env bash +docker_build "${BASH_SOURCE[0]}" "$@" diff --git a/deployment/images/node-php7/Dockerfile.armhf b/deployment/images/node-php7/Dockerfile.armhf new file mode 100644 index 000000000..5e6cd5d87 --- /dev/null +++ b/deployment/images/node-php7/Dockerfile.armhf @@ -0,0 +1,60 @@ +FROM node:lts-alpine +RUN apk update \ + && apk add \ + bash \ + sudo \ + curl \ + git \ + openssh-client \ + tar \ + gzip \ + ca-certificates \ + zip \ + unzip \ + icu-dev \ + libmcrypt-dev \ + freetype-dev \ + libjpeg-turbo-dev \ + libpng-dev \ + netcat-openbsd \ + php7 \ + php7-curl \ + php7-gd \ + php7-intl \ + php7-json \ + php7-mbstring \ + php7-opcache \ + php7-openssl \ + php7-pcntl \ + php7-xml \ + php7-mysqlnd \ + php7-phar \ + php7-mysqli \ + php7-pdo_mysql \ + php7-dom \ + php7-tokenizer \ + php7-simplexml \ + php7-xmlwriter \ + php7-fpm \ + php7-zlib \ + py3-pip \ + python3-dev \ + libffi-dev \ + openssl-dev \ + gcc \ + libc-dev \ + make \ + mariadb-client \ + nodejs \ + \ + python3 \ + git \ + make \ + g++ \ + && apk del build-base \ + && rm -rf /var/cache/apk/* +# Make sure the nginx and php-fpm7 (FASTCGI server) starts when system reboots +# RUN rc-update add php-fpm7 default +# RUN rc-service php-fpm7 start +WORKDIR /var/www/html/ +RUN node -v && npm -v diff --git a/deployment/images/node-php7/Dockerfile.template b/deployment/images/node-php7/Dockerfile.template new file mode 100644 index 000000000..5e6cd5d87 --- /dev/null +++ b/deployment/images/node-php7/Dockerfile.template @@ -0,0 +1,60 @@ +FROM node:lts-alpine +RUN apk update \ + && apk add \ + bash \ + sudo \ + curl \ + git \ + openssh-client \ + tar \ + gzip \ + ca-certificates \ + zip \ + unzip \ + icu-dev \ + libmcrypt-dev \ + freetype-dev \ + libjpeg-turbo-dev \ + libpng-dev \ + netcat-openbsd \ + php7 \ + php7-curl \ + php7-gd \ + php7-intl \ + php7-json \ + php7-mbstring \ + php7-opcache \ + php7-openssl \ + php7-pcntl \ + php7-xml \ + php7-mysqlnd \ + php7-phar \ + php7-mysqli \ + php7-pdo_mysql \ + php7-dom \ + php7-tokenizer \ + php7-simplexml \ + php7-xmlwriter \ + php7-fpm \ + php7-zlib \ + py3-pip \ + python3-dev \ + libffi-dev \ + openssl-dev \ + gcc \ + libc-dev \ + make \ + mariadb-client \ + nodejs \ + \ + python3 \ + git \ + make \ + g++ \ + && apk del build-base \ + && rm -rf /var/cache/apk/* +# Make sure the nginx and php-fpm7 (FASTCGI server) starts when system reboots +# RUN rc-update add php-fpm7 default +# RUN rc-service php-fpm7 start +WORKDIR /var/www/html/ +RUN node -v && npm -v diff --git a/deployment/images/node-php7/Dockerfile.x86_64 b/deployment/images/node-php7/Dockerfile.x86_64 new file mode 100644 index 000000000..5e6cd5d87 --- /dev/null +++ b/deployment/images/node-php7/Dockerfile.x86_64 @@ -0,0 +1,60 @@ +FROM node:lts-alpine +RUN apk update \ + && apk add \ + bash \ + sudo \ + curl \ + git \ + openssh-client \ + tar \ + gzip \ + ca-certificates \ + zip \ + unzip \ + icu-dev \ + libmcrypt-dev \ + freetype-dev \ + libjpeg-turbo-dev \ + libpng-dev \ + netcat-openbsd \ + php7 \ + php7-curl \ + php7-gd \ + php7-intl \ + php7-json \ + php7-mbstring \ + php7-opcache \ + php7-openssl \ + php7-pcntl \ + php7-xml \ + php7-mysqlnd \ + php7-phar \ + php7-mysqli \ + php7-pdo_mysql \ + php7-dom \ + php7-tokenizer \ + php7-simplexml \ + php7-xmlwriter \ + php7-fpm \ + php7-zlib \ + py3-pip \ + python3-dev \ + libffi-dev \ + openssl-dev \ + gcc \ + libc-dev \ + make \ + mariadb-client \ + nodejs \ + \ + python3 \ + git \ + make \ + g++ \ + && apk del build-base \ + && rm -rf /var/cache/apk/* +# Make sure the nginx and php-fpm7 (FASTCGI server) starts when system reboots +# RUN rc-update add php-fpm7 default +# RUN rc-service php-fpm7 start +WORKDIR /var/www/html/ +RUN node -v && npm -v diff --git a/deployment/images/node-php7/common.env b/deployment/images/node-php7/common.env new file mode 120000 index 000000000..cf1366dd2 --- /dev/null +++ b/deployment/images/node-php7/common.env @@ -0,0 +1 @@ +/Users/wwwb23prodtminfo/NetBeansProjects/OpenShift/acake2php/common.env \ No newline at end of file diff --git a/discord.sh b/discord.sh new file mode 100644 index 000000000..092b5449d --- /dev/null +++ b/discord.sh @@ -0,0 +1,98 @@ +#!/bin/bash +# Source: https://raw.githubusercontent.com/k3rn31p4nic/travis-ci-discord-webhook/master/send.sh +case $1 in + "building" ) + EMBED_COLOR=15105570 + STATUS_MESSAGE="Building" + AVATAR="https://travis-ci.org/images/logos/TravisCI-Mascot-red.png" + ;; + + "success" ) + EMBED_COLOR=3066993 + STATUS_MESSAGE="Passed" + AVATAR="https://travis-ci.org/images/logos/TravisCI-Mascot-blue.png" + ;; + + "failure" ) + EMBED_COLOR=15158332 + STATUS_MESSAGE="Failed" + AVATAR="https://travis-ci.org/images/logos/TravisCI-Mascot-red.png" + ;; + + * ) + EMBED_COLOR=0 + STATUS_MESSAGE="Status Unknown" + AVATAR="https://travis-ci.org/images/logos/TravisCI-Mascot-1.png" + ;; +esac + +shift + +if [ $# -lt 1 ]; then + echo -e "WARNING!!\nYou need to pass the WEBHOOK_URL environment variable as the second argument to this script.\nFor details & guide, visit: https://github.com/DiscordHooks/travis-ci-discord-webhook" && exit +fi + +AUTHOR_NAME="$(git log -1 "$TRAVIS_COMMIT" --pretty="%aN")" +COMMITTER_NAME="$(git log -1 "$TRAVIS_COMMIT" --pretty="%cN")" +COMMIT_SUBJECT="$(git log -1 "$TRAVIS_COMMIT" --pretty="%s")" +COMMIT_MESSAGE="$(git log -1 "$TRAVIS_COMMIT" --pretty="%b" | sed -E ':a;N;$!ba;s/\r{0,1}\n/\\n/g')" + +if [ ${#COMMIT_SUBJECT} -gt 256 ]; then + COMMIT_SUBJECT="$(echo "$COMMIT_SUBJECT" | cut -c 1-253)" + COMMIT_SUBJECT+="..." +fi +# shellcheck disable=SC2031 +if [ -n "$COMMIT_MESSAGE" ] && [ ${#COMMIT_MESSAGE} -gt 1900 ]; then + # shellcheck disable=SC2031 + COMMIT_MESSAGE="$(echo "$COMMIT_MESSAGE" | cut -c 1-1900)" + COMMIT_MESSAGE+="..." +fi + +if [ "$AUTHOR_NAME" == "$COMMITTER_NAME" ]; then + CREDITS="$AUTHOR_NAME authored & committed" +else + CREDITS="$AUTHOR_NAME authored & $COMMITTER_NAME committed" +fi + +if [[ $TRAVIS_PULL_REQUEST != false ]]; then + URL="https://github.com/$TRAVIS_REPO_SLUG/pull/$TRAVIS_PULL_REQUEST" +else + URL="" +fi + +TIMESTAMP=$(date -u +%FT%TZ) +WEBHOOK_DATA='{ + "username": "", + "avatar_url": "https://travis-ci.org/images/logos/TravisCI-Mascot-1.png", + "embeds": [ { + "color": '$EMBED_COLOR', + "author": { + "name": "Job #'"$TRAVIS_JOB_NUMBER"' (Build #'"$TRAVIS_BUILD_NUMBER"') '"$STATUS_MESSAGE"' - '"$TRAVIS_REPO_SLUG"'", + "url": "'"$TRAVIS_BUILD_WEB_URL"'", + "icon_url": "'$AVATAR'" + }, + "title": "'"$COMMIT_SUBJECT"'", + "url": "'"$URL"'", + "description": "'"${COMMIT_MESSAGE//$'\n'/ }"\\n\\n"$CREDITS"'", + "fields": [ + { + "name": "Commit", + "value": "'"[\`${TRAVIS_COMMIT:0:7}\`](https://github.com/$TRAVIS_REPO_SLUG/commit/$TRAVIS_COMMIT)"'", + "inline": true + }, + { + "name": "Branch", + "value": "'"[\`$TRAVIS_BRANCH\`](https://github.com/$TRAVIS_REPO_SLUG/tree/$TRAVIS_BRANCH)"'", + "inline": true + } + ], + "timestamp": "'"$TIMESTAMP"'" + } ] +}' + +for ARG in "$@"; do + echo -e "[Webhook]: Sending webhook to Discord...\\n"; + + (curl --fail --progress-bar -A "TravisCI-Webhook" -H Content-Type:application/json -H X-Author:k3rn31p4nic#8383 -d "${WEBHOOK_DATA// / }" "$ARG" \ + && echo -e "\\n[Webhook]: Successfully sent the webhook.") || echo -e "\\n[Webhook]: Unable to send webhook." +done diff --git a/docker-compose-alias.sh b/docker-compose-alias.sh index 01ce3f746..113532fe1 100755 --- a/docker-compose-alias.sh +++ b/docker-compose-alias.sh @@ -5,15 +5,15 @@ docker="" saved=("$*") usage="[-dns=] [-p|--sql-password=] [-t,--test-sql-password=] [other-args]" [ $# -eq 0 ] && echo "Usage: $0 ${usage}" && exit 1 -while [[ "$#" > 0 ]]; do case $1 in +while [[ "$#" -gt 0 ]]; do case $1 in -[pP]*|--sql-password*) parse_sql_password "$1" "DATABASE_PASSWORD" "user ${DATABASE_USER}";; -[tT]*|--test-sql-password*) parse_sql_password "$1" "TEST_DATABASE_PASSWORD" "test user ${TEST_DATABASE_USER}";; -[vV]*|--verbose ) - echo "Passed params : $0 ${saved}";; + echo "Passed params : $0 ${saved[*]}";; -[oO]*|--openshift ) - bootargs=$saved;; + bootargs=("${saved[*]}");; -[S]*|-submodule ) git submodule update --init --recursive;; -dns*|-DNS*) @@ -39,12 +39,12 @@ while [[ "$#" > 0 ]]; do case $1 in *) docker="${docker} $1";; esac; shift; done export DB=Mysql -source Scripts/bootstrap.sh $bootargs -if [ ! $(which docker-compose) 2> /dev/null ]; then Scripts/install-docker-compose.sh; fi -if [ ! -z $SERVER_NAME ]; then - source Scripts/docker_site_conf.sh $SERVER_NAME +source Scripts/bootstrap.sh "${bootargs[*]}" +if [ ! "$(command -v docker-compose 2> /dev/null)" ]; then Scripts/install-docker-compose.sh; fi +if [ -n "$SERVER_NAME" ]; then + source Scripts/docker_site_conf.sh "$SERVER_NAME" else cp -v docker/apache/site-default.conf docker/apache/site.conf fi -docker-compose $docker +docker-compose "$docker" sudo cp index-redirect-8000.php /var/www/html/index.php diff --git a/docker-compose.armhf b/docker-compose.armhf new file mode 100644 index 000000000..95f26bfd2 --- /dev/null +++ b/docker-compose.armhf @@ -0,0 +1,74 @@ +version: "2" +services: + db: + build: + context: mysqldb + dockerfile: Dockerfile.armhf + args: + PUID: 0 + PGID: 0 + TZ: Europe/Paris + MYSQL_ROOT_PASSWORD: mariadb + MYSQL_HOST: localhost + MYSQL_DATABASE: aria_db + MYSQL_USER: maria + MYSQL_PASSWORD: maria-abc + image: betothreeprod/mariadb-raspberrypi3 + volumes: + - db-data:/config + - db-socket:/var/run/mysqld + - db-config:/var/www/htdocs/localhost/app/Config/Schema + ports: + - "3306:3306" + restart: unless-stopped + networks: + - cake + env_file: + - common.env + - .env + labels: + io.balena.features.dbus: "1" + acake2php: + env_file: + - common.env + - .env + build: + context: . + dockerfile: Dockerfile.armhf + args: + CAKEPHP_DEBUG_LEVEL: "2" + MYSQL_HOST: "db" + PUID: 1000 + PGID: 1000 + image: betothreeprod/acake2php-raspberrypi3 + labels: + io.balena.features.dbus: "1" + volumes: + - db-config:/var/www/htdocs/localhost/app/Config/Schema + - db-socket:/var/run/mysqld + ports: + - "80:80" + - "443:443" + depends_on: + - db + networks: + - cake + #docker-compose v3 + #healthcheck: + #test: ["CMD", "curl", "-f", "http://localhost"] + #interval: 1m30s + #timeout: 10s + #retries: 3 + # v3.4 compose file + #start_period: 40s +volumes: + hostapcache: + db-config: + external: false + db-data: + external: false + db-socket: + external: false +networks: + cake: + external: false diff --git a/docker-compose.x86_64 b/docker-compose.x86_64 new file mode 100644 index 000000000..835726d8b --- /dev/null +++ b/docker-compose.x86_64 @@ -0,0 +1,74 @@ +version: "2" +services: + db: + build: + context: mysqldb + dockerfile: Dockerfile.x86_64 + args: + PUID: 0 + PGID: 0 + TZ: Europe/Paris + MYSQL_ROOT_PASSWORD: mariadb + MYSQL_HOST: localhost + MYSQL_DATABASE: aria_db + MYSQL_USER: maria + MYSQL_PASSWORD: maria-abc + image: betothreeprod/mariadb-intel-nuc + volumes: + - db-data:/config + - db-socket:/var/run/mysqld + - db-config:/var/www/htdocs/localhost/app/Config/Schema + ports: + - "3306:3306" + restart: unless-stopped + networks: + - cake + env_file: + - common.env + - .env + labels: + io.balena.features.dbus: "1" + acake2php: + env_file: + - common.env + - .env + build: + context: . + dockerfile: Dockerfile.x86_64 + args: + CAKEPHP_DEBUG_LEVEL: "2" + MYSQL_HOST: "db" + PUID: 1000 + PGID: 1000 + image: betothreeprod/acake2php-intel-nuc + labels: + io.balena.features.dbus: "1" + volumes: + - db-config:/var/www/htdocs/localhost/app/Config/Schema + - db-socket:/var/run/mysqld + ports: + - "80:80" + - "443:443" + depends_on: + - db + networks: + - cake + #docker-compose v3 + #healthcheck: + #test: ["CMD", "curl", "-f", "http://localhost"] + #interval: 1m30s + #timeout: 10s + #retries: 3 + # v3.4 compose file + #start_period: 40s +volumes: + hostapcache: + db-config: + external: false + db-data: + external: false + db-socket: + external: false +networks: + cake: + external: false diff --git a/docker-compose.yml b/docker-compose.yml index b91eef6d6..a614251c1 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,53 +1,74 @@ -version: "3" +version: "2" services: - - app: + db: + build: + context: mysqldb + dockerfile: Dockerfile.aarch64 + args: + PUID: 0 + PGID: 0 + TZ: Europe/Paris + MYSQL_ROOT_PASSWORD: mariadb + MYSQL_HOST: localhost + MYSQL_DATABASE: aria_db + MYSQL_USER: maria + MYSQL_PASSWORD: maria-abc + image: betothreeprod/mariadb-generic-aarch64 + volumes: + - db-data:/config + - db-socket:/var/run/mysqld + - db-config:/var/www/htdocs/localhost/app/Config/Schema + ports: + - "3306:3306" + restart: unless-stopped + networks: + - cake + env_file: + - common.env + - .env + labels: + io.balena.features.dbus: "1" + acake2php: + env_file: + - common.env + - .env build: context: . - dockerfile: Dockerfile + dockerfile: Dockerfile.aarch64 + args: + CAKEPHP_DEBUG_LEVEL: "2" + MYSQL_HOST: "db" + PUID: 1000 + PGID: 1000 + image: betothreeprod/acake2php-generic-aarch64 + labels: + io.balena.features.dbus: "1" volumes: - - .:/var/www/html + - db-config:/var/www/htdocs/localhost/app/Config/Schema + - db-socket:/var/run/mysqld ports: - - 8000:80 + - "80:80" + - "443:443" depends_on: - db - environment: - DOCKER_OS_NAME: linux - DOCKER_PHP_VERSION: ${_PHP} - DB: Mysql - # a host alias or IP address - MYSQL_SERVICE_HOST: db - MYSQL_SERVICE_PORT: 3306 - TEST_MYSQL_SERVICE_HOST: db - TEST_MYSQL_SERVICE_PORT: 3306 - DATABASE_NAME: phpcms - DATABASE_SERVICE_NAME: MYSQL - #(optional) - #WEBHOOK_URL: - # Persistent connection credentials - DATABASE_USER: root - # overrides docker-compose-alias.sh -p= - DATABASE_PASSWORD: ${DATABASE_PASSWORD} - # Just add TEST_DATABASE_USER and TEST_DATABASE_PASSWORD - TEST_DATABASE_USER: ubuntu - # overrides docker-compose-alias.sh -t= - #TEST_DATABASE_PASSWORD: - # CakePHP generated - #CAKEPHP_SECRET_TOKEN: - #CAKEPHP_SECRET_SALT: - #CAKEPHP_SECURITY_CIPHER_SEED: - # Generated by ./configure.sh -h - GET_HASH_PASSWORD: ${GET_HASH_PASSWORD} - db: - image: library/mariadb:10.4-bionic - volumes: - - db-data:/var/lib/mysql - environment: - MYSQL_DATABASE: ${DATABASE_NAME} - MYSQL_ROOT_PASSWORD: ${DATABASE_PASSWORD} - MYSQL_USER: ubuntu - MYSQL_PASSWORD: ${TEST_DATABASE_PASSWORD} - + networks: + - cake + #docker-compose v3 + #healthcheck: + #test: ["CMD", "curl", "-f", "http://localhost"] + #interval: 1m30s + #timeout: 10s + #retries: 3 + # v3.4 compose file + #start_period: 40s volumes: + hostapcache: + db-config: + external: false db-data: external: false + db-socket: + external: false +networks: + cake: + external: false diff --git a/docker-compose/README.md b/docker-compose/README.md new file mode 100644 index 000000000..d3885b635 --- /dev/null +++ b/docker-compose/README.md @@ -0,0 +1 @@ +This chart was created by Kompose diff --git a/docker/configure.sh b/docker/configure.sh index 4bf6c7807..48001f6be 100644 --- a/docker/configure.sh +++ b/docker/configure.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash export DB=Mysql -source Scripts/bootstrap.sh $* +source Scripts/bootstrap.sh "$*" cp -v docker/apache/site-default.conf docker/apache/site.conf echo -e " Set of default Test environment @@ -27,8 +27,8 @@ optional environment VARIABLES in docker-compose.yml ADDITIONAL_PHP_INI='path to a php.ini settings file' ========================== "; -[ ! -z $TEST_DATABASE_USER ] && [ ! -z $TEST_DATABASE_PASSWORD ] && [[ (! -z $TEST_MYSQL_SERVICE_HOST) || (! -z $TEST_PGSQL_SERVICE_HOST) ]] || echo "Missing VARIABLES. Please review your settings !" -if [ ! -z "${ADDITIONAL_PHP_INI}" ]; then /usr/bin/env bash .travis/TravisCI-OSX-PHP/build/custom_php_ini.sh; fi +[ -n "$TEST_DATABASE_USER" ] && [ -n "$TEST_DATABASE_PASSWORD" ] && [[ (-n "$TEST_MYSQL_SERVICE_HOST") || (-n "$TEST_PGSQL_SERVICE_HOST") ]] || echo "Missing VARIABLES. Please review your settings !" +if [ -n "${ADDITIONAL_PHP_INI}" ]; then /usr/bin/env bash .travis/TravisCI-OSX-PHP/build/custom_php_ini.sh; fi mkdir -p build/logs echo -e "Database Unit Tests... DB=${DB}" if [[ "${DOCKER_OS_NAME}" == "linux" ]]; then @@ -38,17 +38,17 @@ if [[ "${DOCKER_OS_NAME}" == "linux" ]]; then sudo locale-gen de_DE sudo locale-gen es_ES fi; -if [[ ${DB} == 'Mysql' ]]; then mysql -v -e 'CREATE DATABASE IF NOT EXISTS cakephp_test;' -u ${DATABASE_USER} --password=${DATABASE_PASSWORD}; fi -if [[ ${DB} == 'Mysql' ]]; then mysql -v -e 'CREATE DATABASE IF NOT EXISTS cakephp_test2;' -u ${DATABASE_USER} --password=${DATABASE_PASSWORD}; fi -if [[ ${DB} == 'Mysql' ]]; then mysql -v -e 'CREATE DATABASE IF NOT EXISTS cakephp_test3;' -u ${DATABASE_USER} --password=${DATABASE_PASSWORD}; fi +if [[ ${DB} == 'Mysql' ]]; then mysql -v -e 'CREATE DATABASE IF NOT EXISTS cakephp_test;' -u "${DATABASE_USER}" --password="${DATABASE_PASSWORD}"; fi +if [[ ${DB} == 'Mysql' ]]; then mysql -v -e 'CREATE DATABASE IF NOT EXISTS cakephp_test2;' -u "${DATABASE_USER}" --password="${DATABASE_PASSWORD}"; fi +if [[ ${DB} == 'Mysql' ]]; then mysql -v -e 'CREATE DATABASE IF NOT EXISTS cakephp_test3;' -u "${DATABASE_USER}" --password="${DATABASE_PASSWORD}"; fi if [[ ${DB} == 'Pgsql' ]]; then psql -c 'CREATE DATABASE cakephp_test;' -U postgres; fi if [[ ${DB} == 'Pgsql' ]]; then psql -c 'CREATE SCHEMA test2;' -U postgres -d cakephp_test; fi if [[ ${DB} == 'Pgsql' ]]; then psql -c 'CREATE SCHEMA test3;' -U postgres -d cakephp_test; fi chmod -R 777 ./app/tmp if [[ "${DOCKER_OS_NAME}" == "linux" ]]; then - echo "extension = memcached.so" >> ~/.phpenv/versions/$(phpenv version-name)/etc/php.ini + echo "extension = memcached.so" >> ~/.phpenv/versions/"$(phpenv version-name)"/etc/php.ini echo "yes" | pecl install apcu-5.1.3 || true - echo -e "extension = apcu.so\napc.enable_cli=1" >> ~/.phpenv/versions/$(phpenv version-name)/etc/php.ini + echo -e "extension = apcu.so\napc.enable_cli=1" >> ~/.phpenv/versions/"$(phpenv version-name)"/etc/php.ini phpenv rehash fi set +H diff --git a/etc/apache2/site.tpl b/etc/apache2/site.tpl new file mode 100644 index 000000000..87d49859c --- /dev/null +++ b/etc/apache2/site.tpl @@ -0,0 +1,20 @@ + + AllowOverride All + Require all denied + + + DocumentRoot ${WWW} + ServerAdmin webmaster@${SERVER_NAME} + ServerName ${SERVER_NAME} + ServerAlias www.${SERVER_NAME} + + DirectoryIndex index.php + Options +FollowSymLinks + AllowOverride All + Require all granted + + ErrorLog logs/error.${SERVER_NAME}.log + TransferLog logs/access.${SERVER_NAME}.log + +ServerName ${SERVER_NAME} +LimitInternalRecursion 20 diff --git a/etc/apache2/ssl_site.tpl b/etc/apache2/ssl_site.tpl new file mode 100644 index 000000000..0923d5d6c --- /dev/null +++ b/etc/apache2/ssl_site.tpl @@ -0,0 +1,20 @@ + + DocumentRoot ${WWW} + ServerAdmin webmaster@${SERVER_NAME} + ServerName ${SERVER_NAME}:${SSL_PORT} + ServerAlias www.${SERVER_NAME}:${SSL_PORT} + + DirectoryIndex index.php + Options +FollowSymLinks + AllowOverride All + Require all granted + + ErrorLog logs/ssl_error.${SERVER_NAME}.log + TransferLog logs/ssl_access.${SERVER_NAME}.log + SSLEngine on + SSLCertificateFile /etc/ssl/apache2/server.pem + SSLCertificateKeyFile /etc/ssl/apache2/server.key + #SSLCertificateChainFile /etc/ssl/apache2/server-ca.pem + #SSLCACertificatePath /etc/ssl/apache2/ssl.crt + #SSLCACertificateFile /etc/ssl/apache2/ssl.crt/ca-bundle.pem + diff --git a/etc/services.d/apache/run b/etc/services.d/apache/run new file mode 100755 index 000000000..d562768da --- /dev/null +++ b/etc/services.d/apache/run @@ -0,0 +1,15 @@ +#!/usr/bin/with-contenv sh + +if [ -e ./setup ]; then + sh -c "./setup" +fi +server_root=$(grep "^ServerRoot" < /etc/apache2/httpd.conf | awk '{ print $2 }' | sed "s/\"//g") +echo "CakePHP LOG: $server_root/localhost/htdocs/app/tmp/logs/error.log" +# start apache +exec /usr/sbin/apachectl -DFOREGROUND; + +# Restarting Apache +# Execute the command s6-svc -h /etc/services.d/apache to send a SIGHUP +# to Apache and have it reload configuration, launching new worker process(es) +# using this new configuration, while gracefully shutting down the old worker +# processes. diff --git a/etc/services.d/apache/setup b/etc/services.d/apache/setup new file mode 100755 index 000000000..eabb86bd9 --- /dev/null +++ b/etc/services.d/apache/setup @@ -0,0 +1,19 @@ +#!/usr/bin/with-contenv sh +if grep www-data < /etc/group; then + id www-data +else + addgroup -g 33 --system www-data +fi +if grep www-data < /etc/passwd; then + id www-data +else + adduser --ingroup www-data --system www-data +fi +server_root=$(grep "^ServerRoot" < /etc/apache2/httpd.conf | awk '{ print $2 }' | sed "s/\"//g") +document_root="${server_root}/localhost/htdocs" +chown -R www-data:www-data "$server_root" \ + && chmod -R g+s "$server_root" +bash -c "${document_root}/Scripts/configure_tmp.sh" +bash -c "${document_root}/Scripts/config_a2ensite.sh" +memcached -d -l 127.0.0.1 -p 11211 -u www-data -m 16 \ + && memcached -d -l 127.0.0.1 -p 11212 -u www-data -m 16 diff --git a/health.php b/health.php index 8db455569..9abc4bd65 100644 --- a/health.php +++ b/health.php @@ -1,8 +1,8 @@ isFile()) { return false; } - if (empty($this->_File) || $this->_File->getBaseName() !== $key) { + if ( + empty($this->_File) || + $this->_File->getBaseName() !== $key || + $this->_File->valid() === false + ) { $exists = file_exists($path->getPathname()); try { $this->_File = $path->openFile('c+'); diff --git a/lib/Cake/Cache/Engine/RedisEngine.php b/lib/Cake/Cache/Engine/RedisEngine.php index 02d677b25..6dd659944 100644 --- a/lib/Cake/Cache/Engine/RedisEngine.php +++ b/lib/Cake/Cache/Engine/RedisEngine.php @@ -228,7 +228,7 @@ public function clearGroup($group) { * Disconnects from the redis server */ public function __destruct() { - if (!$this->settings['persistent']) { + if (empty($this->settings['persistent']) && $this->_Redis !== null) { $this->_Redis->close(); } } diff --git a/lib/Cake/Console/Command/Task/ModelTask.php b/lib/Cake/Console/Command/Task/ModelTask.php index 4619655f9..f70cf656d 100644 --- a/lib/Cake/Console/Command/Task/ModelTask.php +++ b/lib/Cake/Console/Command/Task/ModelTask.php @@ -224,7 +224,7 @@ protected function _interactive() { if (!array_key_exists('id', $fields)) { $primaryKey = $this->findPrimaryKey($fields); } - + $displayField = null; if ($knownToExist) { $displayField = $tempModel->hasField(array('name', 'title')); if (!$displayField) { @@ -388,7 +388,7 @@ public function initValidations() { sort($options); $default = 1; foreach ($options as $option) { - if ($option{0} !== '_') { + if ($option[0] !== '_') { $choices[$default] = $option; $default++; } diff --git a/lib/Cake/Console/Command/TestShell.php b/lib/Cake/Console/Command/TestShell.php index b12f6a078..ebaab5bde 100644 --- a/lib/Cake/Console/Command/TestShell.php +++ b/lib/Cake/Console/Command/TestShell.php @@ -360,23 +360,19 @@ protected function _mapFileToCase($file, $category, $throwOnMissingFile = true) } $testFile = $testCase = null; - + $testCaseFolder = str_replace(APP, '', APP_TEST_CASES); if (preg_match('@Test[\\\/]@', $file)) { - if (substr($file, -8) === 'Test.php') { - $testCase = substr($file, 0, -8); $testCase = str_replace(DS, '/', $testCase); - - if ($testCase = preg_replace('@.*Test\/Case\/@', '', $testCase)) { - + $testCaseFolderEscaped = str_replace('/', '\/', $testCaseFolder); + $testCase = preg_replace('@.*' . $testCaseFolderEscaped . '\/@', '', $testCase); + if (!empty($testCase)) { if ($category === 'core') { $testCase = str_replace('lib/Cake', '', $testCase); } - return $testCase; } - throw new Exception(__d('cake_dev', 'Test case %s cannot be run via this shell', $testFile)); } } @@ -397,11 +393,11 @@ protected function _mapFileToCase($file, $category, $throwOnMissingFile = true) } if ($category === 'app') { - $testFile = str_replace(APP, APP . 'Test/Case/', $file) . 'Test.php'; + $testFile = str_replace(APP, APP_TEST_CASES . '/', $file) . 'Test.php'; } else { $testFile = preg_replace( "@((?:plugins|Plugin)[\\/]{$category}[\\/])(.*)$@", - '\1Test/Case/\2Test.php', + '\1' . $testCaseFolder . '/\2Test.php', $file ); } @@ -412,8 +408,7 @@ protected function _mapFileToCase($file, $category, $throwOnMissingFile = true) $testCase = substr($testFile, 0, -8); $testCase = str_replace(DS, '/', $testCase); - $testCase = preg_replace('@.*Test/Case/@', '', $testCase); - + $testCase = preg_replace('@.*' . $testCaseFolder . '/@', '', $testCase); return $testCase; } diff --git a/lib/Cake/Console/Command/UpgradeShell.php b/lib/Cake/Console/Command/UpgradeShell.php index f9d1223af..c738f0e3d 100644 --- a/lib/Cake/Console/Command/UpgradeShell.php +++ b/lib/Cake/Console/Command/UpgradeShell.php @@ -237,7 +237,7 @@ public function helpers() { foreach ($helpers as $helper) { $helper = preg_replace('/Helper$/', '', $helper); $oldHelper = $helper; - $oldHelper{0} = strtolower($oldHelper{0}); + $oldHelper[0] = strtolower($oldHelper[0]); $patterns[] = array( "\${$oldHelper} to \$this->{$helper}", "/\\\${$oldHelper}->/", diff --git a/lib/Cake/Console/ConsoleOptionParser.php b/lib/Cake/Console/ConsoleOptionParser.php index f90dbc4e1..f313c41c9 100644 --- a/lib/Cake/Console/ConsoleOptionParser.php +++ b/lib/Cake/Console/ConsoleOptionParser.php @@ -620,8 +620,8 @@ protected function _optionExists($name) { if (substr($name, 0, 2) === '--') { return isset($this->_options[substr($name, 2)]); } - if ($name{0} === '-' && $name{1} !== '-') { - return isset($this->_shortOptions[$name{1}]); + if ($name[0] === '-' && $name[1] !== '-') { + return isset($this->_shortOptions[$name[1]]); } return false; } diff --git a/lib/Cake/Console/ConsoleOutput.php b/lib/Cake/Console/ConsoleOutput.php index 4690a850b..233684260 100644 --- a/lib/Cake/Console/ConsoleOutput.php +++ b/lib/Cake/Console/ConsoleOutput.php @@ -265,7 +265,7 @@ protected function _replaceTags($matches) { $styleInfo[] = static::$_options[$option]; } } - return "\033[" . implode($styleInfo, ';') . 'm' . $matches['text'] . "\033[0m"; + return "\033[" . implode( ';',$styleInfo) . 'm' . $matches['text'] . "\033[0m"; } /** diff --git a/lib/Cake/Console/Shell.php b/lib/Cake/Console/Shell.php index 90ee0eb38..c8033e695 100644 --- a/lib/Cake/Console/Shell.php +++ b/lib/Cake/Console/Shell.php @@ -764,8 +764,6 @@ public function clear() { * @link https://book.cakephp.org/2.0/en/console-and-shells.html#Shell::createFile */ public function createFile($path, $contents) { - $path = str_replace(DS . DS, DS, $path); - $this->out(); if (is_file($path) && empty($this->params['force']) && $this->interactive === true) { @@ -808,12 +806,12 @@ public function helper($name) { return $this->_helpers[$name]; } list($plugin, $helperClassName) = pluginSplit($name, true); - $helperClassName = Inflector::camelize($name) . "ShellHelper"; - App::uses($helperClassName, $plugin . "Console/Helper"); - if (!class_exists($helperClassName)) { + $helperClassNameShellHelper = Inflector::camelize($helperClassName) . "ShellHelper"; + App::uses($helperClassNameShellHelper, $plugin . "Console/Helper"); + if (!class_exists($helperClassNameShellHelper)) { throw new RuntimeException("Class " . $helperClassName . " not found"); } - $helper = new $helperClassName($this->stdout); + $helper = new $helperClassNameShellHelper($this->stdout); $this->_helpers[$name] = $helper; return $helper; } diff --git a/lib/Cake/Console/ShellDispatcher.php b/lib/Cake/Console/ShellDispatcher.php index 9f21befb2..f0ac25880 100644 --- a/lib/Cake/Console/ShellDispatcher.php +++ b/lib/Cake/Console/ShellDispatcher.php @@ -63,7 +63,7 @@ public function __construct($args = array(), $bootstrap = true) { */ public static function run($argv) { $dispatcher = new ShellDispatcher($argv); - return $dispatcher->_stop($dispatcher->dispatch() === false ? 1 : 0); + return ($dispatcher->dispatch() === false ? 1 : 0); } /** @@ -140,8 +140,11 @@ protected function _bootstrap() { define('TMP', CAKE_CORE_INCLUDE_PATH . DS . 'Cake' . DS . 'Console' . DS . 'Templates' . DS . 'skel' . DS . 'tmp' . DS); } + if (!defined('CONFIG')) { + define('CONFIG', ROOT . DS . APP_DIR . DS . 'Config' . DS); + } // $boot is used by Cake/bootstrap.php file - $boot = file_exists(ROOT . DS . APP_DIR . DS . 'Config' . DS . 'bootstrap.php'); + $boot = file_exists(CONFIG . 'bootstrap.php'); require CORE_PATH . 'Cake' . DS . 'bootstrap.php'; if (!file_exists(CONFIG . 'core.php')) { @@ -220,7 +223,7 @@ public function dispatch() { } $methods = array_diff(get_class_methods($Shell), get_class_methods('Shell')); $added = in_array($command, $methods); - $private = $command[0] === '_' && method_exists($Shell, $command); + $private = substr($command, 0, 1) === '_' && method_exists($Shell, $command); if (!$private) { if ($added) { diff --git a/lib/Cake/Console/Templates/default/actions/controller_actions.ctp b/lib/Cake/Console/Templates/default/actions/controller_actions.ctp index 8a943b9e7..0cde5c638 100644 --- a/lib/Cake/Console/Templates/default/actions/controller_actions.ctp +++ b/lib/Cake/Console/Templates/default/actions/controller_actions.ctp @@ -131,12 +131,11 @@ * @return void */ public function delete($id = null) { - $this->->id = $id; - if (!$this->->exists()) { + if (!$this->->exists($id)) { throw new NotFoundException(__('Invalid ')); } $this->request->allowMethod('post', 'delete'); - if ($this->->delete()) { + if ($this->->delete($id)) { $this->Flash->success(__('The has been deleted.')); } else { diff --git a/lib/Cake/Controller/Component/CookieComponent.php b/lib/Cake/Controller/Component/CookieComponent.php index 1d01e227d..7d07d8695 100644 --- a/lib/Cake/Controller/Component/CookieComponent.php +++ b/lib/Cake/Controller/Component/CookieComponent.php @@ -248,7 +248,7 @@ public function write($key, $value = null, $encrypt = true, $expires = null) { * $this->Cookie->read(Name.key); * * @param string $key Key of the value to be obtained. If none specified, obtain map key => values - * @return string|null Value for specified key + * @return string|array|null Value for specified key * @link https://book.cakephp.org/2.0/en/core-libraries/components/cookie.html#CookieComponent::read */ public function read($key = null) { diff --git a/lib/Cake/Controller/Component/RequestHandlerComponent.php b/lib/Cake/Controller/Component/RequestHandlerComponent.php index 9471f4849..1915b981a 100644 --- a/lib/Cake/Controller/Component/RequestHandlerComponent.php +++ b/lib/Cake/Controller/Component/RequestHandlerComponent.php @@ -72,6 +72,13 @@ class RequestHandlerComponent extends Component { */ public $ext = null; +/** + * Array of parameters parsed from the URL. + * + * @var array|null + */ + public $params = null; + /** * The template to use when rendering the given content type. * @@ -132,7 +139,7 @@ public function initialize(Controller $controller) { if (empty($this->ext) || $this->ext === 'html') { $this->_setExtension(); } - $this->params = $controller->params; + $this->params = $controller->request->params; if (!empty($this->settings['viewClassMap'])) { $this->viewClassMap($this->settings['viewClassMap']); } @@ -213,7 +220,7 @@ public function startup(Controller $controller) { foreach ($this->_inputTypeMap as $type => $handler) { if ($this->requestedWith($type)) { - $input = call_user_func_array(array($controller->request, 'input'), $handler); + $input = (array)call_user_func_array(array($controller->request, 'input'), $handler); $controller->request->data = $input; } } @@ -264,8 +271,10 @@ public function beforeRedirect(Controller $controller, $url, $status = null, $ex } if (!empty($status)) { $statusCode = $this->response->httpCodes($status); - $code = key($statusCode); - $this->response->statusCode($code); + if (is_array($statusCode)) { + $code = key($statusCode); + $this->response->statusCode($code); + } } $this->response->body($this->requestAction($url, array('return', 'bare' => false))); $this->response->send(); diff --git a/lib/Cake/Controller/Component/SessionComponent.php b/lib/Cake/Controller/Component/SessionComponent.php index b298e420d..f09550957 100644 --- a/lib/Cake/Controller/Component/SessionComponent.php +++ b/lib/Cake/Controller/Component/SessionComponent.php @@ -45,9 +45,9 @@ public function userAgent($userAgent = null) { * * In your controller: $this->Session->write('Controller.sessKey', 'session value'); * - * @param string $name The name of the key your are setting in the session. + * @param string|array $name The name of the key your are setting in the session. * This should be in a Controller.key format for better organizing - * @param string $value The value you want to store in a session. + * @param mixed $value The value you want to store in a session. * @return bool Success * @link https://book.cakephp.org/2.0/en/core-libraries/components/sessions.html#SessionComponent::write */ diff --git a/lib/Cake/Controller/Controller.php b/lib/Cake/Controller/Controller.php index e9d5c6657..19e54692d 100644 --- a/lib/Cake/Controller/Controller.php +++ b/lib/Cake/Controller/Controller.php @@ -48,11 +48,18 @@ * @property AuthComponent $Auth * @property CookieComponent $Cookie * @property EmailComponent $Email + * @property FlashComponent $Flash * @property PaginatorComponent $Paginator * @property RequestHandlerComponent $RequestHandler * @property SecurityComponent $Security * @property SessionComponent $Session - * @property FlashComponent $Flash + * @property string $action The action handling the current request. Deprecated, use CakeRequest::$action instead. + * @property string $base Base URL path. Deprecated, use CakeRequest::$base instead. + * @property array $data POST data. Deprecated, use CakeRequest::$data instead. + * @property string $here The full address to the current request. Deprecated, use CakeRequest::$here instead. + * @property array $paginate Pagination settings. + * @property array $params Array of parameters parsed from the URL. Deprecated, use CakeRequest::$params instead. + * @property string $webroot Webroot path segment for the request. * @link https://book.cakephp.org/2.0/en/controllers.html */ class Controller extends CakeObject implements CakeEventListener { @@ -80,7 +87,7 @@ class Controller extends CakeObject implements CakeEventListener { * * The default value is `true`. * - * @var mixed + * @var bool|array * @link https://book.cakephp.org/2.0/en/controllers.html#components-helpers-and-uses */ public $uses = true; @@ -153,9 +160,9 @@ class Controller extends CakeObject implements CakeEventListener { /** * The name of the layout file to render the view inside of. The name specified * is the filename of the layout in /app/View/Layouts without the .ctp - * extension. + * extension. If `false` then no layout is rendered. * - * @var string + * @var string|bool */ public $layout = 'default'; @@ -287,8 +294,9 @@ class Controller extends CakeObject implements CakeEventListener { /** * Holds any validation errors produced by the last call of the validateErrors() method. + * Contains `false` if no validation errors happened. * - * @var array + * @var array|bool */ public $validationErrors = null; @@ -573,7 +581,7 @@ protected function _mergeControllerVars() { if ($this->uses === true) { $this->uses = array($pluginDot . $this->modelClass); } - if (isset($appVars['uses']) && $appVars['uses'] === $this->uses) { + if (is_array($this->uses) && isset($appVars['uses']) && $appVars['uses'] === $this->uses) { array_unshift($this->uses, $pluginDot . $this->modelClass); } if ($pluginController) { @@ -598,10 +606,7 @@ protected function _mergeControllerVars() { * @return void */ protected function _mergeUses($merge) { - if (!isset($merge['uses'])) { - return; - } - if ($merge['uses'] === true) { + if (!isset($merge['uses']) || $merge['uses'] === true || !is_array($this->uses)) { return; } $this->uses = array_merge( @@ -707,7 +712,7 @@ public function shutdownProcess() { * 800 => 'Unexpected Minotaur' * )); // sets these new values, and returns true * - * @return array Associative array of the HTTP codes as keys, and the message + * @return array|null|true Associative array of the HTTP codes as keys, and the message * strings as values, or null of the given $code does not exist. * @deprecated 3.0.0 Since 2.4. Will be removed in 3.0. Use CakeResponse::httpCodes(). */ @@ -752,7 +757,7 @@ public function loadModel($modelClass = null, $id = null) { * * @param string|array $url A string or array-based URL pointing to another location within the app, * or an absolute URL - * @param int|array|null $status HTTP status code (eg: 301). Defaults to 302 when null is passed. + * @param int|array|null|string $status HTTP status code (eg: 301). Defaults to 302 when null is passed. * @param bool $exit If true, exit() will be called after the redirect * @return CakeResponse|null * @triggers Controller.beforeRedirect $this, array($url, $status, $exit) @@ -838,7 +843,7 @@ public function header($status) { * Saves a variable for use inside a view template. * * @param string|array $one A string or an array of data. - * @param string|array $two Value in case $one is a string (which then works as the key). + * @param mixed $two Value in case $one is a string (which then works as the key). * Unused if $one is an associative array, otherwise serves as the values to $one's keys. * @return void * @link https://book.cakephp.org/2.0/en/controllers.html#interacting-with-views @@ -900,7 +905,7 @@ public function validate() { * * `$errors = $this->validateErrors($this->Article, $this->User);` * - * @return array Validation errors, or false if none + * @return array|false Validation errors, or false if none * @deprecated 3.0.0 This method will be removed in 3.0 */ public function validateErrors() { @@ -925,7 +930,7 @@ public function validateErrors() { /** * Instantiates the correct view class, hands it its data, and uses it to render the view output. * - * @param string $view View to use for rendering + * @param bool|string $view View to use for rendering * @param string $layout Layout to use * @return CakeResponse A response object containing the rendered view. * @triggers Controller.beforeRender $this @@ -1018,7 +1023,7 @@ public function flash($message, $url, $pause = 1, $layout = 'flash') { } /** - * Converts POST'ed form data to a model conditions array. + * Converts POST'ed form data to a model conditions array. * * If combined with SecurityComponent these conditions could be suitable * for use in a Model::find() call. Without SecurityComponent this method diff --git a/lib/Cake/Core/App.php b/lib/Cake/Core/App.php index 8696a485a..5aeac3024 100644 --- a/lib/Cake/Core/App.php +++ b/lib/Cake/Core/App.php @@ -591,7 +591,7 @@ public static function location($className) { * * @param string|array $type The type of Class if passed as a string, or all params can be passed as * a single array to $type. - * @param string $name Name of the Class or a unique name for the file + * @param string|array $name Name of the Class or a unique name for the file * @param bool|array $parent boolean true if Class Parent should be searched, accepts key => value * array('parent' => $parent, 'file' => $file, 'search' => $search, 'ext' => '$ext'); * $ext allows setting the extension of the file name @@ -891,7 +891,7 @@ protected static function _packageFormat() { /** * Increases the PHP "memory_limit" ini setting by the specified amount * in kilobytes - * + * * @param string $additionalKb Number in kilobytes * @return void */ diff --git a/lib/Cake/Core/Configure.php b/lib/Cake/Core/Configure.php index cba018c75..901606cd2 100644 --- a/lib/Cake/Core/Configure.php +++ b/lib/Cake/Core/Configure.php @@ -114,6 +114,9 @@ public static function bootstrap($boot = true) { class_exists('Debugger'); class_exists('CakeText'); } + if (!defined('TESTS')) { + define('TESTS', APP . 'Test' . DS); + } } } diff --git a/lib/Cake/Event/CakeEventManager.php b/lib/Cake/Event/CakeEventManager.php index e2d9276e6..98d73974b 100644 --- a/lib/Cake/Event/CakeEventManager.php +++ b/lib/Cake/Event/CakeEventManager.php @@ -15,6 +15,7 @@ */ App::uses('CakeEventListener', 'Event'); +App::uses('CakeEvent', 'Event'); /** * The event manager is responsible for keeping track of event listeners, passing the correct diff --git a/lib/Cake/Log/CakeLog.php b/lib/Cake/Log/CakeLog.php index 262292ddc..3b2cfb6cd 100644 --- a/lib/Cake/Log/CakeLog.php +++ b/lib/Cake/Log/CakeLog.php @@ -22,7 +22,7 @@ /** * Logs messages to configured Log adapters. - * + * * One or more adapters * can be configured using CakeLogs's methods. * @@ -84,7 +84,7 @@ class CakeLog { /** * Default log levels as detailed in RFC 5424 * http://tools.ietf.org/html/rfc5424 - * + * * Windows has fewer levels, thus notice, info and debug are the same. * https://bugs.php.net/bug.php?id=18090 * @@ -398,7 +398,7 @@ public static function stream($streamName) { * * @param int|string $type Type of message being written. When value is an integer * or a string matching the recognized levels, then it will - * be treated log levels. Otherwise it's treated as scope. + * be treated as a log level. Otherwise it's treated as a scope. * @param string $message Message content to log * @param string|array $scope The scope(s) a log message is being created in. * See CakeLog::config() for more information on logging scopes. diff --git a/lib/Cake/Model/Behavior/ContainableBehavior.php b/lib/Cake/Model/Behavior/ContainableBehavior.php index a494dd7ca..57ae597da 100644 --- a/lib/Cake/Model/Behavior/ContainableBehavior.php +++ b/lib/Cake/Model/Behavior/ContainableBehavior.php @@ -306,7 +306,7 @@ public function containments(Model $Model, $contain, $containments = array(), $t if (!$optionKey && is_string($key) && preg_match('/^[a-z(]/', $key) && (!isset($Model->{$key}) || !is_object($Model->{$key}))) { $option = 'fields'; $val = array($key); - if ($key{0} === '(') { + if ($key[0] === '(') { $val = preg_split('/\s*,\s*/', substr($key, 1, -1)); } elseif (preg_match('/ASC|DESC$/', $key)) { $option = 'order'; diff --git a/lib/Cake/Model/Behavior/TranslateBehavior.php b/lib/Cake/Model/Behavior/TranslateBehavior.php index 1b9b51116..e4bb53734 100644 --- a/lib/Cake/Model/Behavior/TranslateBehavior.php +++ b/lib/Cake/Model/Behavior/TranslateBehavior.php @@ -344,7 +344,7 @@ protected function _addJoin(Model $Model, $query, $field, $aliasField, $locale) public function afterFind(Model $Model, $results, $primary = false) { $Model->virtualFields = $this->runtime[$Model->alias]['virtualFields']; - $this->runtime[$Model->alias]['virtualFields'] = $this->runtime[$Model->alias]['fields'] = array(); + $this->runtime[$Model->alias]['virtualFields'] = array(); if (!empty($this->runtime[$Model->alias]['restoreFields'])) { $this->runtime[$Model->alias]['fields'] = $this->runtime[$Model->alias]['restoreFields']; unset($this->runtime[$Model->alias]['restoreFields']); diff --git a/lib/Cake/Model/Behavior/TreeBehavior.php b/lib/Cake/Model/Behavior/TreeBehavior.php index 9fc12e706..d944007be 100644 --- a/lib/Cake/Model/Behavior/TreeBehavior.php +++ b/lib/Cake/Model/Behavior/TreeBehavior.php @@ -225,7 +225,7 @@ public function beforeSave(Model $Model, $options = array()) { } $parentIsSet = array_key_exists($parent, $Model->data[$Model->alias]); - if (!$Model->id || !$Model->exists()) { + if (!$Model->id || !$Model->exists($Model->getID())) { if ($parentIsSet && $Model->data[$Model->alias][$parent]) { $parentNode = $this->_getNode($Model, $Model->data[$Model->alias][$parent]); if (!$parentNode) { diff --git a/lib/Cake/Model/CakeSchema.php b/lib/Cake/Model/CakeSchema.php index 3d11b3641..f2cb4e73d 100644 --- a/lib/Cake/Model/CakeSchema.php +++ b/lib/Cake/Model/CakeSchema.php @@ -420,6 +420,7 @@ public function generateTable($table, $fields) { $type = $value; $value = array('type' => $type); } + $value['type'] = addslashes($value['type']); $col = "\t\t'{$field}' => array('type' => '" . $value['type'] . "', "; unset($value['type']); $col .= implode(', ', $this->_values($value)); @@ -624,17 +625,19 @@ protected function _columns(&$Obj) { if ($Obj->primaryKey === $name && !$hasPrimaryAlready && !isset($value['key'])) { $value['key'] = 'primary'; } - if (!isset($db->columns[$value['type']])) { - trigger_error(__d('cake_dev', 'Schema generation error: invalid column type %s for %s.%s does not exist in DBO', $value['type'], $Obj->name, $name), E_USER_NOTICE); - continue; - } else { - $defaultCol = $db->columns[$value['type']]; - if (isset($defaultCol['limit']) && $defaultCol['limit'] == $value['length']) { - unset($value['length']); - } elseif (isset($defaultCol['length']) && $defaultCol['length'] == $value['length']) { - unset($value['length']); + if (substr($value['type'], 0, 4) !== 'enum') { + if (!isset($db->columns[$value['type']])) { + trigger_error(__d('cake_dev', 'Schema generation error: invalid column type %s for %s.%s does not exist in DBO', $value['type'], $Obj->name, $name), E_USER_NOTICE); + continue; + } else { + $defaultCol = $db->columns[$value['type']]; + if (isset($defaultCol['limit']) && $defaultCol['limit'] == $value['length']) { + unset($value['length']); + } elseif (isset($defaultCol['length']) && $defaultCol['length'] == $value['length']) { + unset($value['length']); + } + unset($value['limit']); } - unset($value['limit']); } if (isset($value['default']) && ($value['default'] === '' || ($value['default'] === false && $value['type'] !== 'boolean'))) { diff --git a/lib/Cake/Model/Datasource/CakeSession.php b/lib/Cake/Model/Datasource/CakeSession.php index fec94fcf3..e67731429 100644 --- a/lib/Cake/Model/Datasource/CakeSession.php +++ b/lib/Cake/Model/Datasource/CakeSession.php @@ -432,7 +432,7 @@ protected static function _returnSessionVars() { * Writes value to given session variable name. * * @param string|array $name Name of variable - * @param string $value Value to write + * @param mixed $value Value to write * @return bool True if the write was successful, false if the write failed */ public static function write($name, $value = null) { @@ -575,7 +575,7 @@ protected static function _configureSession() { $sessionConfig['cacheLimiter'] = 'must-revalidate'; } - if (empty($_SESSION)) { + if (empty($_SESSION) && !headers_sent() && (!function_exists('session_status') || session_status() !== PHP_SESSION_ACTIVE)) { if (!empty($sessionConfig['ini']) && is_array($sessionConfig['ini'])) { foreach ($sessionConfig['ini'] as $setting => $value) { if (ini_set($setting, $value) === false) { @@ -587,16 +587,18 @@ protected static function _configureSession() { if (!empty($sessionConfig['handler']) && !isset($sessionConfig['handler']['engine'])) { call_user_func_array('session_set_save_handler', $sessionConfig['handler']); } - if (!empty($sessionConfig['handler']['engine'])) { + if (!empty($sessionConfig['handler']['engine']) && !headers_sent()) { $handler = static::_getHandler($sessionConfig['handler']['engine']); - session_set_save_handler( - array($handler, 'open'), - array($handler, 'close'), - array($handler, 'read'), - array($handler, 'write'), - array($handler, 'destroy'), - array($handler, 'gc') - ); + if (!function_exists('session_status') || session_status() !== PHP_SESSION_ACTIVE) { + session_set_save_handler( + array($handler, 'open'), + array($handler, 'close'), + array($handler, 'read'), + array($handler, 'write'), + array($handler, 'destroy'), + array($handler, 'gc') + ); + } } Configure::write('Session', $sessionConfig); static::$sessionTime = static::$time; diff --git a/lib/Cake/Model/Datasource/Database/Mysql.php b/lib/Cake/Model/Datasource/Database/Mysql.php index 7a13c3108..498785f0b 100644 --- a/lib/Cake/Model/Datasource/Database/Mysql.php +++ b/lib/Cake/Model/Datasource/Database/Mysql.php @@ -120,6 +120,7 @@ class Mysql extends DboSource { 'primary_key' => array('name' => 'NOT NULL AUTO_INCREMENT'), 'string' => array('name' => 'varchar', 'limit' => '255'), 'text' => array('name' => 'text'), + 'enum' => array('name' => 'enum'), 'biginteger' => array('name' => 'bigint', 'limit' => '20'), 'integer' => array('name' => 'int', 'limit' => '11', 'formatter' => 'intval'), 'smallinteger' => array('name' => 'smallint', 'limit' => '6', 'formatter' => 'intval'), @@ -131,6 +132,7 @@ class Mysql extends DboSource { 'time' => array('name' => 'time', 'format' => 'H:i:s', 'formatter' => 'date'), 'date' => array('name' => 'date', 'format' => 'Y-m-d', 'formatter' => 'date'), 'binary' => array('name' => 'blob'), + 'mediumbinary' => array('name' => 'mediumblob'), 'boolean' => array('name' => 'tinyint', 'limit' => '1') ); @@ -305,7 +307,7 @@ public function getEncoding() { * Query charset by collation * * @param string $name Collation name - * @return string Character set name + * @return string|false Character set name */ public function getCharsetName($name) { if ((bool)version_compare($this->getVersion(), "5", "<")) { @@ -391,7 +393,7 @@ public function describe($model) { * @param array $fields The fields to update. * @param array $values The values to set. * @param mixed $conditions The conditions to use. - * @return array + * @return bool */ public function update(Model $model, $fields = array(), $values = null, $conditions = null) { if (!$this->_useAlias) { @@ -545,7 +547,7 @@ public function index($model) { * * @param array $compare Result of a CakeSchema::compare() * @param string $table The table name. - * @return array Array of alter statements to make. + * @return string|false String of alter statements to make. */ public function alterSchema($compare, $table = null) { if (!is_array($compare)) { @@ -810,6 +812,9 @@ public function column($real) { if (strpos($col, 'blob') !== false || $col === 'binary') { return 'binary'; } + if (strpos($col, 'mediumblob') !== false || $col === 'mediumbinary') { + return 'mediumbinary'; + } if (strpos($col, 'float') !== false || strpos($col, 'double') !== false) { return 'float'; } diff --git a/lib/Cake/Model/Datasource/Database/Postgres.php b/lib/Cake/Model/Datasource/Database/Postgres.php index 2bf200fee..6568ad4e5 100644 --- a/lib/Cake/Model/Datasource/Database/Postgres.php +++ b/lib/Cake/Model/Datasource/Database/Postgres.php @@ -69,6 +69,7 @@ class Postgres extends DboSource { 'time' => array('name' => 'time', 'format' => 'H:i:s', 'formatter' => 'date'), 'date' => array('name' => 'date', 'format' => 'Y-m-d', 'formatter' => 'date'), 'binary' => array('name' => 'bytea'), + 'mediumbinary' => array('name' => 'bytea'), 'boolean' => array('name' => 'boolean'), 'number' => array('name' => 'numeric'), 'inet' => array('name' => 'inet'), @@ -251,7 +252,7 @@ public function describe($model) { 'default' => preg_replace( "/^'(.*)'$/", "$1", - preg_replace('/::.*/', '', $c->default) + preg_replace('/::[\w\s]+/', '', $c->default) ), 'length' => $length, ); @@ -765,10 +766,10 @@ public function length($real) { /** * resultSet method * - * @param array &$results The results + * @param PDOStatement $results The results * @return void */ - public function resultSet(&$results) { + public function resultSet($results) { $this->map = array(); $numFields = $results->columnCount(); $index = 0; diff --git a/lib/Cake/Model/Datasource/Database/Sqlite.php b/lib/Cake/Model/Datasource/Database/Sqlite.php index 2cf39c356..c8277d8a2 100644 --- a/lib/Cake/Model/Datasource/Database/Sqlite.php +++ b/lib/Cake/Model/Datasource/Database/Sqlite.php @@ -81,6 +81,7 @@ class Sqlite extends DboSource { 'time' => array('name' => 'time', 'format' => 'H:i:s', 'formatter' => 'date'), 'date' => array('name' => 'date', 'format' => 'Y-m-d', 'formatter' => 'date'), 'binary' => array('name' => 'blob'), + 'mediumbinary' => array('name' => 'mediumblob'), 'boolean' => array('name' => 'boolean') ); @@ -179,7 +180,6 @@ public function describe($model) { ); foreach ($result as $column) { - $column = (array)$column; $default = ($column['dflt_value'] === 'NULL') ? null : trim($column['dflt_value'], "'"); $fields[$column['name']] = array( @@ -290,6 +290,9 @@ public function column($real) { if (in_array($col, array('blob', 'clob'))) { return 'binary'; } + if (in_array($col, array('mebiumblob', 'mediumclob'))) { + return 'mediumbinary'; + } if (strpos($col, 'numeric') !== false || strpos($col, 'decimal') !== false) { return 'decimal'; } @@ -299,7 +302,7 @@ public function column($real) { /** * Generate ResultSet * - * @param mixed $results The results to modify. + * @param PDOStatement $results The results to modify. * @return void */ public function resultSet($results) { diff --git a/lib/Cake/Model/Datasource/DboSource.php b/lib/Cake/Model/Datasource/DboSource.php index a8481a38a..ebfab0a97 100644 --- a/lib/Cake/Model/Datasource/DboSource.php +++ b/lib/Cake/Model/Datasource/DboSource.php @@ -109,7 +109,7 @@ class DboSource extends DataSource { /** * Result * - * @var array + * @var array|PDOStatement */ protected $_result = null; @@ -247,6 +247,13 @@ class DboSource extends DataSource { */ protected $_methodCacheChange = false; +/** + * Map of the columns contained in a result. + * + * @var array + */ + public $map = array(); + /** * Constructor * @@ -272,6 +279,16 @@ public function __construct($config = null, $autoConnect = true) { } } +/** + * Connects to the database. + * + * @return bool + */ + public function connect() { + // This method is implemented in subclasses + return $this->connected; + } + /** * Reconnects to database server with optional new settings * @@ -350,6 +367,18 @@ public function value($data, $column = null, $null = true) { $column = $this->introspectType($data); } + $isStringEnum = false; + if (strpos($column, "enum") === 0) { + $firstValue = null; + if (preg_match("/(enum\()(.*)(\))/i", $column, $acceptingValues)) { + $values = explode(",", $acceptingValues[2]); + $firstValue = $values[0]; + } + if (is_string($firstValue)) { + $isStringEnum = true; + } + } + switch ($column) { case 'binary': return $this->_connection->quote($data, PDO::PARAM_LOB); @@ -365,11 +394,12 @@ public function value($data, $column = null, $null = true) { if (is_float($data)) { return str_replace(',', '.', strval($data)); } - if ((is_int($data) || $data === '0') || ( + if (((is_int($data) || $data === '0') || ( is_numeric($data) && strpos($data, ',') === false && $data[0] != '0' && strpos($data, 'e') === false) + ) && !$isStringEnum ) { return $data; } @@ -619,6 +649,16 @@ public function query() { } } +/** + * Builds a map of the columns contained in a result + * + * @param PDOStatement $results The results to format. + * @return void + */ + public function resultSet($results) { + // This method is implemented in subclasses + } + /** * Returns a row from current resultset as an array * @@ -913,7 +953,7 @@ public function name($data) { ) ); } - if (preg_match('/^[\w-_\s]*[\w-_]+/', $data)) { + if (preg_match('/^[\w\-_\s]*[\w\-_]+/', $data)) { return $this->cacheMethod(__FUNCTION__, $cacheKey, $this->startQuote . $data . $this->endQuote); } return $this->cacheMethod(__FUNCTION__, $cacheKey, $data); @@ -1076,7 +1116,7 @@ public function create(Model $Model, $fields = null, $values = null) { for ($i = 0; $i < $count; $i++) { $schema = $Model->schema(); - $valueInsert[] = $this->value($values[$i], $Model->getColumnType($fields[$i]), isset($schema[$fields[$i]]) ? $schema[$fields[$i]]['null'] : true); + $valueInsert[] = $this->value($values[$i], $Model->getColumnType($fields[$i]), isset($schema[$fields[$i]]['null']) ? $schema[$fields[$i]]['null'] : true); $fieldInsert[] = $this->name($fields[$i]); if ($fields[$i] === $Model->primaryKey) { $id = $values[$i]; @@ -2177,7 +2217,7 @@ protected function _prepareUpdateFields(Model $Model, $fields, $quoteValues = tr $update = $quoted . ' = '; if ($quoteValues) { - $update .= $this->value($value, $Model->getColumnType($field), isset($schema[$field]) ? $schema[$field]['null'] : true); + $update .= $this->value($value, $Model->getColumnType($field), isset($schema[$field]['null']) ? $schema[$field]['null'] : true); } elseif ($Model->getColumnType($field) === 'boolean' && (is_int($value) || is_bool($value))) { $update .= $this->boolean($value, true); } elseif (!$alias) { @@ -2520,7 +2560,7 @@ public function defaultConditions(Model $Model, $conditions, $useAlias = true) { if (!empty($conditions)) { return $conditions; } - $exists = $Model->exists(); + $exists = $Model->exists($Model->getID()); if (!$exists && ($conditions !== null || !empty($Model->__safeUpdateMode))) { return false; } elseif (!$exists) { @@ -3046,12 +3086,12 @@ public function order($keys, $direction = 'ASC', Model $Model = null) { if (!is_array($keys)) { $keys = array($keys); } - $keys = array_filter($keys); $result = array(); while (!empty($keys)) { - list($key, $dir) = each($keys); + $key = key($keys); + $dir = current($keys); array_shift($keys); if (is_numeric($key)) { @@ -3242,18 +3282,7 @@ public function length($real) { return (int)$length; } if (in_array($type, array('enum', 'set'))) { - $values = array_map(function ($value) { - return trim(trim($value), '\'"'); - }, explode(',', $length)); - - $maxLength = 0; - foreach ($values as $key => $enumValue) { - $tmpLength = strlen($enumValue); - if ($tmpLength > $maxLength) { - $maxLength = $tmpLength; - } - } - return $maxLength; + return null; } return (int)$length; } @@ -3471,25 +3500,28 @@ public function buildColumn($column) { return null; } - if (!isset($this->columns[$type])) { + if (!isset($this->columns[$type]) && substr($type, 0, 4) !== 'enum') { trigger_error(__d('cake_dev', 'Column type %s does not exist', $type), E_USER_WARNING); return null; } - $real = $this->columns[$type]; - $out = $this->name($name) . ' ' . $real['name']; - - if (isset($column['length'])) { - $length = $column['length']; - } elseif (isset($column['limit'])) { - $length = $column['limit']; - } elseif (isset($real['length'])) { - $length = $real['length']; - } elseif (isset($real['limit'])) { - $length = $real['limit']; - } - if (isset($length)) { - $out .= '(' . $length . ')'; + if (substr($type, 0, 4) === 'enum') { + $out = $this->name($name) . ' ' . $type; + } else { + $real = $this->columns[$type]; + $out = $this->name($name) . ' ' . $real['name']; + if (isset($column['length'])) { + $length = $column['length']; + } elseif (isset($column['limit'])) { + $length = $column['limit']; + } elseif (isset($real['length'])) { + $length = $real['length']; + } elseif (isset($real['limit'])) { + $length = $real['limit']; + } + if (isset($length)) { + $out .= '(' . $length . ')'; + } } if (($column['type'] === 'integer' || $column['type'] === 'float') && isset($column['default']) && $column['default'] === '') { @@ -3512,7 +3544,7 @@ public function buildColumn($column) { } elseif (isset($column['null']) && $column['null'] === false) { $out .= ' NOT NULL'; } - if ($type === 'timestamp' && isset($column['default']) && strtolower($column['default']) === 'current_timestamp') { + if (in_array($type, array('timestamp', 'datetime')) && isset($column['default']) && strtolower($column['default']) === 'current_timestamp') { $out = str_replace(array("'CURRENT_TIMESTAMP'", "'current_timestamp'"), 'CURRENT_TIMESTAMP', $out); } return $this->_buildFieldParameters($out, $column, 'afterDefault'); diff --git a/lib/Cake/Model/Model.php b/lib/Cake/Model/Model.php index cb0b6ef83..860ad5bdf 100644 --- a/lib/Cake/Model/Model.php +++ b/lib/Cake/Model/Model.php @@ -58,7 +58,7 @@ class Model extends CakeObject implements CakeEventListener { /** * Custom database table name, or null/false if no table association is desired. * - * @var string + * @var string|false * @link https://book.cakephp.org/2.0/en/models/model-attributes.html#usetable */ public $useTable = null; @@ -68,7 +68,7 @@ class Model extends CakeObject implements CakeEventListener { * * This field is also used in `find('list')` when called with no extra parameters in the fields list * - * @var string + * @var string|false * @link https://book.cakephp.org/2.0/en/models/model-attributes.html#displayfield */ public $displayField = null; @@ -84,7 +84,7 @@ class Model extends CakeObject implements CakeEventListener { /** * Container for the data that this model gets from persistent storage (usually, a database). * - * @var array + * @var array|false * @link https://book.cakephp.org/2.0/en/models/model-attributes.html#data */ public $data = array(); @@ -632,7 +632,7 @@ class Model extends CakeObject implements CakeEventListener { /** * The ID of the model record that was last inserted. * - * @var int + * @var int|string */ protected $_insertID = null; @@ -699,7 +699,7 @@ class Model extends CakeObject implements CakeEventListener { * * @param bool|int|string|array $id Set this ID for this model on startup, * can also be an array of options, see above. - * @param string $table Name of database table to use. + * @param string|false $table Name of database table to use. * @param string $ds DataSource connection name. */ public function __construct($id = false, $table = null, $ds = null) { @@ -1196,7 +1196,7 @@ public function setSource($tableName) { * a one-item, two-dimensional array using $one for a key and $two as its value.) * * @param string|array|SimpleXmlElement|DomNode $one Array or string of data - * @param string $two Value string for the alternative indata method + * @param string|false $two Value string for the alternative indata method * @return array|null Data with all of $one's keys and values, otherwise null. * @link https://book.cakephp.org/2.0/en/models/saving-your-data.html */ @@ -1358,7 +1358,7 @@ public function deconstruct($field, $data) { } } - if (!isset($data[$val]) || isset($data[$val]) && (empty($data[$val]) || $data[$val][0] === '-')) { + if (!isset($data[$val]) || isset($data[$val]) && (empty($data[$val]) || substr($data[$val], 0, 1) === '-')) { return null; } @@ -1614,7 +1614,7 @@ public function clear() { * * @param string|array $fields String of single field name, or an array of field names. * @param int|string $id The ID of the record to read - * @return array Array of database fields, or false if not found + * @return array|false Array of database fields, or false if not found * @link https://book.cakephp.org/2.0/en/models/retrieving-your-data.html#model-read */ public function read($fields = null, $id = null) { @@ -1648,7 +1648,7 @@ public function read($fields = null, $id = null) { * * @param string $name The name of the field to get. * @param array $conditions SQL conditions (defaults to NULL). - * @param string $order SQL ORDER BY fragment. + * @param string|array $order SQL ORDER BY fragment. * @return string|false Field content, or false if not found. * @link https://book.cakephp.org/2.0/en/models/retrieving-your-data.html#model-field */ @@ -1824,7 +1824,7 @@ protected function _doSave($data = null, $options = array()) { } } - $exists = $this->exists(); + $exists = $this->exists($this->getID()); $dateFields = array('modified', 'updated'); if (!$exists) { @@ -1991,7 +1991,7 @@ protected function _doSave($data = null, $options = array()) { */ protected function _isUUIDField($field) { $field = $this->schema($field); - return $field['length'] == 36 && in_array($field['type'], array('string', 'binary', 'uuid')); + return $field !== null && $field['length'] == 36 && in_array($field['type'], array('string', 'binary', 'uuid')); } /** @@ -2696,7 +2696,7 @@ public function delete($id = null, $cascade = true) { return false; } - if (!$this->exists()) { + if (!$this->exists($this->getID())) { return false; } @@ -2801,7 +2801,7 @@ protected function _deleteLinks($id) { list(, $joinModel) = pluginSplit($data['with']); $Model = $this->{$joinModel}; $records = $Model->find('all', array( - 'conditions' => array($Model->escapeField($data['foreignKey']) => $id), + 'conditions' => $this->_getConditionsForDeletingLinks($Model, $id, $data), 'fields' => $Model->primaryKey, 'recursive' => -1, 'callbacks' => false @@ -2815,6 +2815,19 @@ protected function _deleteLinks($id) { } } +/** + * Returns the conditions to be applied to Model::find() when determining which HABTM records should be deleted via + * Model::_deleteLinks() + * + * @param Model $Model HABTM join model instance + * @param mixed $id The ID of the primary model which is being deleted + * @param array $relationshipConfig The relationship config defined on the primary model + * @return array + */ + protected function _getConditionsForDeletingLinks(Model $Model, $id, array $relationshipConfig) { + return array($Model->escapeField($relationshipConfig['foreignKey']) => $id); + } + /** * Deletes multiple model records based on a set of conditions. * @@ -2997,7 +3010,7 @@ public function hasAny($conditions = null) { * * @param string $type Type of find operation (all / first / count / neighbors / list / threaded) * @param array $query Option fields (conditions / fields / joins / limit / offset / order / page / group / callbacks) - * @return array|null Array of records, or Null on failure. + * @return array|int|null Array of records, int if the type is count, or Null on failure. * @link https://book.cakephp.org/2.0/en/models/retrieving-your-data.html */ public function find($type = 'first', $query = array()) { @@ -3151,7 +3164,7 @@ protected function _findFirst($state, $query, $results = array()) { * @param string $state Either "before" or "after" * @param array $query Query. * @param array $results Results. - * @return int The number of records found, or false + * @return int|false The number of records found, or false * @see Model::find() */ protected function _findCount($state, $query, $results = array()) { @@ -3495,7 +3508,7 @@ public function validates($options = array()) { * Additionally it populates the validationErrors property of the model with the same array. * * @param array|string $options An optional array of custom options to be made available in the beforeValidate callback - * @return array Array of invalid fields and their error messages + * @return array|bool Array of invalid fields and their error messages * @see Model::validates() */ public function invalidFields($options = array()) { diff --git a/lib/Cake/Model/ModelValidator.php b/lib/Cake/Model/ModelValidator.php index c84e58f75..406c0816c 100644 --- a/lib/Cake/Model/ModelValidator.php +++ b/lib/Cake/Model/ModelValidator.php @@ -257,7 +257,7 @@ public function errors($options = array()) { } } - $exists = $model->exists(); + $exists = $model->exists($model->getID()); $methods = $this->getMethods(); $fields = $this->_validationList($fieldList); @@ -280,7 +280,7 @@ public function errors($options = array()) { * why the rule failed * * @param string $field The name of the field to invalidate - * @param string $message Validation message explaining why the rule failed, defaults to true. + * @param string|bool $message Validation message explaining why the rule failed, defaults to true. * @return void */ public function invalidate($field, $message = true) { diff --git a/lib/Cake/Model/Permission.php b/lib/Cake/Model/Permission.php index 617f00465..dc3dcf526 100644 --- a/lib/Cake/Model/Permission.php +++ b/lib/Cake/Model/Permission.php @@ -146,7 +146,7 @@ public function check($aro, $aco, $action = '*') { case -1: return false; case 0: - continue; + break; case 1: return true; } @@ -190,7 +190,7 @@ public function allow($aro, $aco, $actions = '*', $value = 1) { $actions = array('_' . $actions); } foreach ($actions as $action) { - if ($action{0} !== '_') { + if ($action[0] !== '_') { $action = '_' . $action; } if (!in_array($action, $permKeys, true)) { diff --git a/lib/Cake/Network/CakeRequest.php b/lib/Cake/Network/CakeRequest.php index 228e46e2e..ebc2138ac 100644 --- a/lib/Cake/Network/CakeRequest.php +++ b/lib/Cake/Network/CakeRequest.php @@ -25,6 +25,11 @@ * * `$request['controller']` or `$request->controller`. * + * @property string $plugin The plugin handling the request. Will be `null` when there is no plugin. + * @property string $controller The controller handling the current request. + * @property string $action The action handling the current request. + * @property array $named Array of named parameters parsed from the URL. + * @property array $pass Array of passed arguments parsed from the URL. * @package Cake.Network */ class CakeRequest implements ArrayAccess { @@ -241,6 +246,7 @@ protected function _processGet() { * @return string URI The CakePHP request path that is being accessed. */ protected function _url() { + $uri = ''; if (!empty($_SERVER['PATH_INFO'])) { return $_SERVER['PATH_INFO']; } elseif (isset($_SERVER['REQUEST_URI']) && strpos($_SERVER['REQUEST_URI'], '://') === false) { @@ -303,7 +309,7 @@ protected function _base() { return $this->base = $base; } - if (!$baseUrl) { + if (empty($baseUrl)) { $base = dirname(env('PHP_SELF')); // Clean up additional / which cause following code to fail.. $base = preg_replace('#/+#', '/', $base); diff --git a/lib/Cake/Network/CakeResponse.php b/lib/Cake/Network/CakeResponse.php index 21dfd7b2e..cd24b2aad 100644 --- a/lib/Cake/Network/CakeResponse.php +++ b/lib/Cake/Network/CakeResponse.php @@ -331,7 +331,7 @@ class CakeResponse { * Content type to send. This can be an 'extension' that will be transformed using the $_mimetypes array * or a complete mime-type * - * @var int + * @var string */ protected $_contentType = 'text/html'; @@ -374,7 +374,7 @@ class CakeResponse { * Holds all the cache directives that will be converted * into headers when sending the request * - * @var string + * @var array */ protected $_cacheDirectives = array(); @@ -672,8 +672,9 @@ public function statusCode($code = null) { * * For more on HTTP status codes see: http://www.w3.org/Protocols/rfc2616/rfc2616-sec6.html#sec6.1 * - * @return mixed associative array of the HTTP codes as keys, and the message - * strings as values, or null of the given $code does not exist. + * @return array|null|true associative array of the HTTP codes as keys, and the message + * strings as values, or null of the given $code does not exist. `true` if `$code` is + * an array of valid codes. * @throws CakeException If an attempt is made to add an invalid status code */ public function httpCodes($code = null) { @@ -717,8 +718,8 @@ public function httpCodes($code = null) { * * e.g `type(array('jpg' => 'text/plain'));` * - * @param string $contentType Content type key. - * @return mixed current content type or false if supplied an invalid content type + * @param array|string|null $contentType Content type key. + * @return string|false current content type or false if supplied an invalid content type */ public function type($contentType = null) { if ($contentType === null) { @@ -854,7 +855,7 @@ public function sharable($public = null, $time = null) { } $this->maxAge($time); - if (!$time) { + if ((int)$time === 0) { $this->_setCacheControl(); } return (bool)$public; @@ -1160,15 +1161,19 @@ public function length($bytes = null) { * @return bool whether the response was marked as not modified or not. */ public function checkNotModified(CakeRequest $request) { - $etags = preg_split('/\s*,\s*/', $request->header('If-None-Match'), null, PREG_SPLIT_NO_EMPTY); + $ifNoneMatchHeader = $request->header('If-None-Match'); + $etags = array(); + if (is_string($ifNoneMatchHeader)) { + $etags = preg_split('/\s*,\s*/', $ifNoneMatchHeader, null, PREG_SPLIT_NO_EMPTY); + } $modifiedSince = $request->header('If-Modified-Since'); + $checks = array(); if ($responseTag = $this->etag()) { - $etagMatches = in_array('*', $etags) || in_array($responseTag, $etags); + $checks[] = in_array('*', $etags) || in_array($responseTag, $etags); } if ($modifiedSince) { - $timeMatches = strtotime($this->modified()) === strtotime($modifiedSince); + $checks[] = strtotime($this->modified()) === strtotime($modifiedSince); } - $checks = compact('etagMatches', 'timeMatches'); if (empty($checks)) { return false; } @@ -1224,7 +1229,7 @@ public function __toString() { * * `$this->cookie((array) $options)` * - * @param array $options Either null to get all cookies, string for a specific cookie + * @param array|string $options Either null to get all cookies, string for a specific cookie * or array to set cookie. * @return mixed */ @@ -1312,11 +1317,7 @@ protected function _normalizeCorsDomains($domains, $requestIsSSL = false) { $result[] = array('preg' => '@.@', 'original' => '*'); continue; } - - $original = $preg = $domain; - if (strpos($domain, '://') === false) { - $preg = ($requestIsSSL ? 'https://' : 'http://') . $domain; - } + $original = $domain; $preg = '@' . str_replace('*', '.*', $domain) . '@'; $result[] = compact('original', 'preg'); } @@ -1464,7 +1465,7 @@ protected function _sendFile($file, $range) { $file->open('rb'); $end = $start = false; - if ($range) { + if ($range && is_array($range)) { list($start, $end) = $range; } if ($start !== false) { diff --git a/lib/Cake/Network/CakeSocket.php b/lib/Cake/Network/CakeSocket.php index a4c472fea..7b159ab0c 100644 --- a/lib/Cake/Network/CakeSocket.php +++ b/lib/Cake/Network/CakeSocket.php @@ -9,11 +9,11 @@ * For full copyright and license information, please see the LICENSE.txt * Redistributions of files must retain the above copyright notice. * - * @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) - * @link https://cakephp.org CakePHP(tm) Project - * @package Cake.Network - * @since CakePHP(tm) v 1.2.0 - * @license https://opensource.org/licenses/mit-license.php MIT License + * @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) + * @link https://cakephp.org CakePHP(tm) Project + * @package Cake.Network + * @since CakePHP(tm) v 1.2.0 + * @license https://opensource.org/licenses/mit-license.php MIT License */ App::uses('Validation', 'Utility'); @@ -23,7 +23,7 @@ * * Core base class for network communication. * - * @package Cake.Network + * @package Cake.Network */ class CakeSocket { @@ -139,7 +139,9 @@ protected function _addTlsVersions() { 'tlsv1_1_client' => 'STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT', 'tlsv1_2_client' => 'STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT', 'tlsv1_1_server' => 'STREAM_CRYPTO_METHOD_TLSv1_1_SERVER', - 'tlsv1_2_server' => 'STREAM_CRYPTO_METHOD_TLSv1_2_SERVER' + 'tlsv1_2_server' => 'STREAM_CRYPTO_METHOD_TLSv1_2_SERVER', + 'tlsv1_3_server' => 'STREAM_CRYPTO_METHOD_TLSv1_3_SERVER', + 'tlsv1_3_client' => 'STREAM_CRYPTO_METHOD_TLSv1_3_CLIENT' ); foreach ($conditionalCrypto as $key => $const) { if (defined($const)) { @@ -154,6 +156,18 @@ protected function _addTlsVersions() { if (isset($this->_encryptMethods['tlsv1_2_server'])) { $this->_encryptMethods['tls_server'] = STREAM_CRYPTO_METHOD_TLS_SERVER | STREAM_CRYPTO_METHOD_TLSv1_1_SERVER | STREAM_CRYPTO_METHOD_TLSv1_2_SERVER; } + if (isset($this->_encryptMethods['tlsv1_3_client'])) { + $this->_encryptMethods['tls_client'] = STREAM_CRYPTO_METHOD_TLS_CLIENT | + STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT | + STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT | + STREAM_CRYPTO_METHOD_TLSv1_3_CLIENT; + } + if (isset($this->_encryptMethods['tlsv1_3_server'])) { + $this->_encryptMethods['tls_server'] = STREAM_CRYPTO_METHOD_TLS_SERVER | + STREAM_CRYPTO_METHOD_TLSv1_1_SERVER | + STREAM_CRYPTO_METHOD_TLSv1_2_SERVER | + STREAM_CRYPTO_METHOD_TLSv1_3_SERVER; + } // @codingStandardsIgnoreEnd } diff --git a/lib/Cake/Network/Email/CakeEmail.php b/lib/Cake/Network/Email/CakeEmail.php index bb4b47f65..ee4da73d9 100644 --- a/lib/Cake/Network/Email/CakeEmail.php +++ b/lib/Cake/Network/Email/CakeEmail.php @@ -589,7 +589,7 @@ public function emailPattern($regex = false) { */ protected function _setEmail($varName, $email, $name) { if (!is_array($email)) { - $this->_validateEmail($email); + $this->_validateEmail($email, $varName); if ($name === null) { $name = $email; } @@ -601,7 +601,7 @@ protected function _setEmail($varName, $email, $name) { if (is_int($key)) { $key = $value; } - $this->_validateEmail($key); + $this->_validateEmail($key, $varName); $list[$key] = $value; } $this->{$varName} = $list; @@ -611,11 +611,12 @@ protected function _setEmail($varName, $email, $name) { /** * Validate email address * - * @param string $email Email + * @param string $email Email address to validate + * @param string $context Which property was set * @return void * @throws SocketException If email address does not validate */ - protected function _validateEmail($email) { + protected function _validateEmail($email, $context) { if ($this->_emailPattern === null) { if (filter_var($email, FILTER_VALIDATE_EMAIL)) { return; @@ -623,7 +624,10 @@ protected function _validateEmail($email) { } elseif (preg_match($this->_emailPattern, $email)) { return; } - throw new SocketException(__d('cake_dev', 'Invalid email: "%s"', $email)); + if ($email == '') { + throw new SocketException(__d('cake_dev', 'The email set for "%s" is empty.', $context)); + } + throw new SocketException(__d('cake_dev', 'Invalid email set for "%s". You passed "%s".', $context, $email)); } /** @@ -659,7 +663,7 @@ protected function _setEmailSingle($varName, $email, $name, $throwMessage) { */ protected function _addEmail($varName, $email, $name) { if (!is_array($email)) { - $this->_validateEmail($email); + $this->_validateEmail($email, $varName); if ($name === null) { $name = $email; } @@ -671,7 +675,7 @@ protected function _addEmail($varName, $email, $name) { if (is_int($key)) { $key = $value; } - $this->_validateEmail($key); + $this->_validateEmail($key, $varName); $list[$key] = $value; } $this->{$varName} = array_merge($this->{$varName}, $list); @@ -788,7 +792,7 @@ public function getHeaders($include = array()) { } if ($this->_messageId !== false) { if ($this->_messageId === true) { - $headers['Message-ID'] = '<' . str_replace('-', '', CakeText::UUID()) . '@' . $this->_domain . '>'; + $headers['Message-ID'] = '<' . str_replace('-', '', CakeText::uuid()) . '@' . $this->_domain . '>'; } else { $headers['Message-ID'] = $this->_messageId; } diff --git a/lib/Cake/Network/Http/HttpSocket.php b/lib/Cake/Network/Http/HttpSocket.php index 1643bcbfd..624b97a25 100644 --- a/lib/Cake/Network/Http/HttpSocket.php +++ b/lib/Cake/Network/Http/HttpSocket.php @@ -251,7 +251,7 @@ public function setContentResource($resource) { * method and provide a more granular interface. * * @param string|array $request Either an URI string, or an array defining host/uri - * @return mixed false on error, HttpSocketResponse on success + * @return false|HttpSocketResponse false on error, HttpSocketResponse on success * @throws SocketException */ public function request($request = array()) { @@ -449,18 +449,16 @@ public function request($request = array()) { * @param string|array $uri URI to request. Either a string uri, or a uri array, see HttpSocket::_parseUri() * @param array $query Querystring parameters to append to URI * @param array $request An indexed array with indexes such as 'method' or uri - * @return mixed Result of request, either false on failure or the response to the request. + * @return false|HttpSocketResponse Result of request, either false on failure or the response to the request. */ public function get($uri = null, $query = array(), $request = array()) { - if (!empty($query)) { - $uri = $this->_parseUri($uri, $this->config['request']['uri']); - if (isset($uri['query'])) { - $uri['query'] = array_merge($uri['query'], $query); - } else { - $uri['query'] = $query; - } - $uri = $this->_buildUri($uri); + $uri = $this->_parseUri($uri, $this->config['request']['uri']); + if (isset($uri['query'])) { + $uri['query'] = array_merge($uri['query'], $query); + } else { + $uri['query'] = $query; } + $uri = $this->_buildUri($uri); $request = Hash::merge(array('method' => 'GET', 'uri' => $uri), $request); return $this->request($request); @@ -475,18 +473,16 @@ public function get($uri = null, $query = array(), $request = array()) { * @param string|array $uri URI to request. Either a string URI, or a URI array, see HttpSocket::_parseUri() * @param array $query Querystring parameters to append to URI * @param array $request An indexed array with indexes such as 'method' or uri - * @return mixed Result of request, either false on failure or the response to the request. + * @return false|HttpSocketResponse Result of request, either false on failure or the response to the request. */ public function head($uri = null, $query = array(), $request = array()) { - if (!empty($query)) { - $uri = $this->_parseUri($uri, $this->config['request']['uri']); - if (isset($uri['query'])) { - $uri['query'] = array_merge($uri['query'], $query); - } else { - $uri['query'] = $query; - } - $uri = $this->_buildUri($uri); + $uri = $this->_parseUri($uri, $this->config['request']['uri']); + if (isset($uri['query'])) { + $uri['query'] = array_merge($uri['query'], $query); + } else { + $uri['query'] = $query; } + $uri = $this->_buildUri($uri); $request = Hash::merge(array('method' => 'HEAD', 'uri' => $uri), $request); return $this->request($request); @@ -507,7 +503,7 @@ public function head($uri = null, $query = array(), $request = array()) { * @param string|array $uri URI to request. See HttpSocket::_parseUri() * @param array $data Array of request body data keys and values. * @param array $request An indexed array with indexes such as 'method' or uri - * @return mixed Result of request, either false on failure or the response to the request. + * @return false|HttpSocketResponse Result of request, either false on failure or the response to the request. */ public function post($uri = null, $data = array(), $request = array()) { $request = Hash::merge(array('method' => 'POST', 'uri' => $uri, 'body' => $data), $request); @@ -520,7 +516,7 @@ public function post($uri = null, $data = array(), $request = array()) { * @param string|array $uri URI to request, See HttpSocket::_parseUri() * @param array $data Array of request body data keys and values. * @param array $request An indexed array with indexes such as 'method' or uri - * @return mixed Result of request + * @return false|HttpSocketResponse Result of request */ public function put($uri = null, $data = array(), $request = array()) { $request = Hash::merge(array('method' => 'PUT', 'uri' => $uri, 'body' => $data), $request); @@ -533,7 +529,7 @@ public function put($uri = null, $data = array(), $request = array()) { * @param string|array $uri URI to request, See HttpSocket::_parseUri() * @param array $data Array of request body data keys and values. * @param array $request An indexed array with indexes such as 'method' or uri - * @return mixed Result of request + * @return false|HttpSocketResponse Result of request */ public function patch($uri = null, $data = array(), $request = array()) { $request = Hash::merge(array('method' => 'PATCH', 'uri' => $uri, 'body' => $data), $request); @@ -546,7 +542,7 @@ public function patch($uri = null, $data = array(), $request = array()) { * @param string|array $uri URI to request (see {@link _parseUri()}) * @param array $data Array of request body data keys and values. * @param array $request An indexed array with indexes such as 'method' or uri - * @return mixed Result of request + * @return false|HttpSocketResponse Result of request */ public function delete($uri = null, $data = array(), $request = array()) { $request = Hash::merge(array('method' => 'DELETE', 'uri' => $uri, 'body' => $data), $request); @@ -593,7 +589,7 @@ public function url($url = null, $uriTemplate = null) { if (is_array($port)) { $port = $port[0]; } - if ($url{0} === '/') { + if ($url[0] === '/') { $url = $this->config['request']['uri']['host'] . ':' . $port . $url; } if (!preg_match('/^.+:\/\/|\*|^\//', $url)) { diff --git a/lib/Cake/Routing/Router.php b/lib/Cake/Routing/Router.php index 3d252b32e..368a2ceff 100644 --- a/lib/Cake/Routing/Router.php +++ b/lib/Cake/Routing/Router.php @@ -1055,7 +1055,7 @@ protected static function _handleNoRoute($url) { * an array of arguments to convert into a query string. * @param array $extra Extra querystring parameters. * @param bool $escape Whether or not to use escaped & - * @return array + * @return string|null */ public static function queryString($q, $extra = array(), $escape = false) { if (empty($q) && empty($extra)) { diff --git a/lib/Cake/Test/Case/AllControllerTest.php b/lib/Cake/Test/Case/AllControllerTest.php index 8af92e8a5..e6f5644d7 100644 --- a/lib/Cake/Test/Case/AllControllerTest.php +++ b/lib/Cake/Test/Case/AllControllerTest.php @@ -38,6 +38,7 @@ public static function suite() { $suite->addTestFile(CORE_TEST_CASES . DS . 'Controller' . DS . 'PagesControllerTest.php'); $suite->addTestFile(CORE_TEST_CASES . DS . 'Controller' . DS . 'ComponentTest.php'); $suite->addTestFile(CORE_TEST_CASES . DS . 'Controller' . DS . 'ControllerMergeVarsTest.php'); + $suite->addTestFile(CORE_TEST_CASES . DS . 'Controller' . DS . 'ApplicationControllerTest.php'); return $suite; } } diff --git a/lib/Cake/Test/Case/Cache/CacheTest.php b/lib/Cake/Test/Case/Cache/CacheTest.php index 5a36aeef7..0dfd60209 100644 --- a/lib/Cake/Test/Case/Cache/CacheTest.php +++ b/lib/Cake/Test/Case/Cache/CacheTest.php @@ -189,8 +189,12 @@ public function testConfigChange() { $result = Cache::config('tests', array('engine' => 'File', 'path' => TMP . 'tests')); $this->assertEquals(Cache::settings('tests'), $result['settings']); - Cache::config('sessions', $_cacheConfigSessions['settings']); - Cache::config('tests', $_cacheConfigTests['settings']); + if ($_cacheConfigSessions !== false) { + Cache::config('sessions', $_cacheConfigSessions['settings']); + } + if ($_cacheConfigTests !== false) { + Cache::config('tests', $_cacheConfigTests['settings']); + } } /** diff --git a/lib/Cake/Test/Case/Console/Command/Task/ExtractTaskTest.php b/lib/Cake/Test/Case/Console/Command/Task/ExtractTaskTest.php index 56eb15c65..050985ea2 100644 --- a/lib/Cake/Test/Case/Console/Command/Task/ExtractTaskTest.php +++ b/lib/Cake/Test/Case/Console/Command/Task/ExtractTaskTest.php @@ -380,25 +380,12 @@ public function testExtractModelValidation() { $this->Task->execute(); $result = file_get_contents($this->path . DS . 'default.pot'); - - $pattern = preg_quote('#Model/PersisterOne.php:validation for field title#', '\\'); - $this->assertRegExp($pattern, $result); - - $pattern = preg_quote('#Model/PersisterOne.php:validation for field body#', '\\'); - $this->assertRegExp($pattern, $result); - - $pattern = '#msgid "Post title is required"#'; - $this->assertRegExp($pattern, $result); - - $pattern = '#msgid "You may enter up to %s chars \(minimum is %s chars\)"#'; - $this->assertRegExp($pattern, $result); - - $pattern = '#msgid "Post body is required"#'; - $this->assertRegExp($pattern, $result); - - $pattern = '#msgid "Post body is super required"#'; - $this->assertRegExp($pattern, $result); - + $this->assertContains('Model/PersisterOne.php:validation for field title', $result); + $this->assertContains('Model/PersisterOne.php:validation for field body', $result); + $this->assertContains('msgid "Post title is required"', $result); + $this->assertContains('msgid "You may enter up to %s chars (minimum is %s chars)"', $result); + $this->assertContains('msgid "Post body is required"', $result); + $this->assertContains('msgid "Post body is super required"', $result); $this->assertContains('msgid "double \\"quoted\\" validation"', $result, 'Strings with quotes not handled correctly'); $this->assertContains("msgid \"single 'quoted' validation\"", $result, 'Strings with quotes not handled correctly'); } @@ -429,21 +416,11 @@ public function testExtractModelValidationWithDomainInModel() { $this->Task->execute(); $result = file_get_contents($this->path . DS . 'test_plugin.pot'); - - $pattern = preg_quote('#Plugin/TestPlugin/Model/TestPluginPost.php:validation for field title#', '\\'); - $this->assertRegExp($pattern, $result); - - $pattern = preg_quote('#Plugin/TestPlugin/Model/TestPluginPost.php:validation for field body#', '\\'); - $this->assertRegExp($pattern, $result); - - $pattern = '#msgid "Post title is required"#'; - $this->assertRegExp($pattern, $result); - - $pattern = '#msgid "Post body is required"#'; - $this->assertRegExp($pattern, $result); - - $pattern = '#msgid "Post body is super required"#'; - $this->assertRegExp($pattern, $result); + $this->assertContains('Plugin/TestPlugin/Model/TestPluginPost.php:validation for field title', $result); + $this->assertContains('Plugin/TestPlugin/Model/TestPluginPost.php:validation for field body', $result); + $this->assertContains('msgid "Post title is required"', $result); + $this->assertContains('msgid "Post body is required"', $result); + $this->assertContains('msgid "Post body is super required"', $result); } /** @@ -468,24 +445,12 @@ public function testExtractModelValidationInPlugin() { $this->Task->execute(); $result = file_get_contents($this->path . DS . 'test_plugin.pot'); - - $pattern = preg_quote('#Model/TestPluginPost.php:validation for field title#', '\\'); - $this->assertRegExp($pattern, $result); - - $pattern = preg_quote('#Model/TestPluginPost.php:validation for field body#', '\\'); - $this->assertRegExp($pattern, $result); - - $pattern = '#msgid "Post title is required"#'; - $this->assertRegExp($pattern, $result); - - $pattern = '#msgid "Post body is required"#'; - $this->assertRegExp($pattern, $result); - - $pattern = '#msgid "Post body is super required"#'; - $this->assertRegExp($pattern, $result); - - $pattern = '#Plugin/TestPlugin/Model/TestPluginPost.php:validation for field title#'; - $this->assertNotRegExp($pattern, $result); + $this->assertContains('Model/TestPluginPost.php:validation for field title', $result); + $this->assertContains('Model/TestPluginPost.php:validation for field body', $result); + $this->assertContains('msgid "Post title is required"', $result); + $this->assertContains('msgid "Post body is required"', $result); + $this->assertContains('msgid "Post body is super required"', $result); + $this->assertNotContains('Plugin/TestPlugin/Model/TestPluginPost.php:validation for field title', $result); } /** diff --git a/lib/Cake/Test/Case/Controller/ApplicationControllerTest.php b/lib/Cake/Test/Case/Controller/ApplicationControllerTest.php new file mode 100644 index 000000000..2487aa4db --- /dev/null +++ b/lib/Cake/Test/Case/Controller/ApplicationControllerTest.php @@ -0,0 +1,104 @@ +Session->id(); + return $this->redirect(array( + 'controller' => 'trans_session_id', + 'action' => 'next_step', + '?' => array( + $sessionName => $sessionId, + ), + )); + } + +} + +/** + * ApplicationControllerTest class for testing controllers by using ControllerTestCase. + * + * ApplicationControllerTest extends ControllerTestCase in contrast + * with ControllerTest that extends CakeTestCase. + * + * @package Cake.Test.Case.Controller + */ +class ApplicationControllerTest extends ControllerTestCase { + +/** + * setupDown method + * + * @return void + */ + public function setUp() { + CakeSession::destroy(); + parent::setUp(); + } + +/** + * tearDown method + * + * @return void + */ + public function tearDown() { + CakeSession::destroy(); + parent::tearDown(); + } + +/** + * Tests the redirect and session config with use_trans_sid=1. + * + * @return void + */ + public function testRedirect() { + $sessionId = 'o7k64tlhil9pakp89j6d8ovlqk'; + $this->testAction('/trans_session_id/next?CAKEPHP=' . $sessionId); + $this->assertContains('/trans_session_id/next_step?CAKEPHP=' . $sessionId, $this->headers['Location']); + $expectedConfig = array( + 'cookie' => 'CAKEPHP', + 'timeout' => 240, + 'ini' => array( + 'session.use_trans_sid' => 1, + 'session.cookie_path' => '/', + 'session.cookie_lifetime' => 14400, + 'session.name' => 'CAKEPHP', + 'session.gc_maxlifetime' => 14400, + 'session.cookie_httponly' => 1, + 'session.use_cookies' => 0, + 'session.use_only_cookies' => 0, + ), + 'defaults' => 'php', + 'cookieTimeout' => 240, + 'cacheLimiter' => 'must-revalidate', + ); + $actualConfig = Configure::read('Session'); + $this->assertEquals($expectedConfig, $actualConfig); + } + +} diff --git a/lib/Cake/Test/Case/Controller/Component/RequestHandlerComponentTest.php b/lib/Cake/Test/Case/Controller/Component/RequestHandlerComponentTest.php index 17b50cbea..bc0e49cf2 100644 --- a/lib/Cake/Test/Case/Controller/Component/RequestHandlerComponentTest.php +++ b/lib/Cake/Test/Case/Controller/Component/RequestHandlerComponentTest.php @@ -399,6 +399,20 @@ public function testStartupCallback() { $this->assertFalse(is_object($this->Controller->data)); } +/** + * testStartupCallbackJson method + * + * @return void + */ + public function testStartupCallbackJson() { + $_SERVER['REQUEST_METHOD'] = 'PUT'; + $_SERVER['CONTENT_TYPE'] = 'application/json'; + $this->Controller->request = $this->getMock('CakeRequest', array('_readInput')); + $this->RequestHandler->startup($this->Controller); + $this->assertTrue(is_array($this->Controller->data)); + $this->assertFalse(is_object($this->Controller->data)); + } + /** * testStartupCallback with charset. * diff --git a/lib/Cake/Test/Case/I18n/MultibyteTest.php b/lib/Cake/Test/Case/I18n/MultibyteTest.php index 7859aa4f2..48a3fde68 100644 --- a/lib/Cake/Test/Case/I18n/MultibyteTest.php +++ b/lib/Cake/Test/Case/I18n/MultibyteTest.php @@ -7623,25 +7623,58 @@ public function testUsingMbStrtoupper() { $expected = 'ԀԂԄԆԈԊԌԎԐԒ'; $this->assertEquals($expected, $result); - $string = 'աբգդեզէըթժիլխծկհձղճմյնշոչպջռսվտրցւփքօֆև'; + $string = 'ႠႡႢႣႤႥႦႧႨႩႪႫႬႭႮႯႰႱႲႳႴႵႶႷႸႹႺႻႼႽႾႿჀჁჂჃჄჅ'; $result = mb_strtoupper($string); - $expected = 'ԱԲԳԴԵԶԷԸԹԺԻԼԽԾԿՀՁՂՃՄՅՆՇՈՉՊՋՌՍՎՏՐՑՒՓՔՕՖև'; + $expected = 'ႠႡႢႣႤႥႦႧႨႩႪႫႬႭႮႯႰႱႲႳႴႵႶႷႸႹႺႻႼႽႾႿჀჁჂჃჄჅ'; $this->assertEquals($expected, $result); - $string = 'ႠႡႢႣႤႥႦႧႨႩႪႫႬႭႮႯႰႱႲႳႴႵႶႷႸႹႺႻႼႽႾႿჀჁჂჃჄჅ'; + $string = 'ωkå'; $result = mb_strtoupper($string); - $expected = 'ႠႡႢႣႤႥႦႧႨႩႪႫႬႭႮႯႰႱႲႳႴႵႶႷႸႹႺႻႼႽႾႿჀჁჂჃჄჅ'; + $expected = 'ΩKÅ'; $this->assertEquals($expected, $result); + } - $string = 'ḁḃḅḇḉḋḍḏḑḓḕḗḙḛḝḟḡḣḥḧḩḫḭḯḱḳḵḷḹḻḽḿṁṃṅṇṉṋṍṏṑṓṕṗṙṛṝṟṡṣṥṧṩṫṭṯṱṳṵṷṹṻṽṿẁẃẅẇẉẋẍẏẑẓẕẖẗẘẙẚạảấầẩẫậắằẳẵặẹẻẽếềểễệỉịọỏốồổỗộớờởỡợụủứừửữựỳỵỷỹ'; +/** + * testUsingMbStrtoupperArmenian method + * + * @return void + */ + public function testUsingMbStrtoupperArmenian() { + if (extension_loaded('mbstring') && version_compare(PHP_VERSION, '7.3', '>=')) { + $this->markTestSkipped('PHP7.3+ built-in function mb_strtoupper() behaves slightly different from Multibyte::strtoupper()'); + } + + $string = 'աբգդեզէըթժիլխծկհձղճմյնշոչպջռսվտրցւփքօֆև'; $result = mb_strtoupper($string); - $expected = 'ḀḂḄḆḈḊḌḎḐḒḔḖḘḚḜḞḠḢḤḦḨḪḬḮḰḲḴḶḸḺḼḾṀṂṄṆṈṊṌṎṐṒṔṖṘṚṜṞṠṢṤṦṨṪṬṮṰṲṴṶṸṺṼṾẀẂẄẆẈẊẌẎẐẒẔẖẗẘẙẚẠẢẤẦẨẪẬẮẰẲẴẶẸẺẼẾỀỂỄỆỈỊỌỎỐỒỔỖỘỚỜỞỠỢỤỦỨỪỬỮỰỲỴỶỸ'; + $expected = 'ԱԲԳԴԵԶԷԸԹԺԻԼԽԾԿՀՁՂՃՄՅՆՇՈՉՊՋՌՍՎՏՐՑՒՓՔՕՖև'; $this->assertEquals($expected, $result); + } - $string = 'ωkå'; +/** + * testUsingMbStrtoupperDiacritic method + * + * @return void + */ + public function testUsingMbStrtoupperDiacritic() { + if (extension_loaded('mbstring') && version_compare(PHP_VERSION, '7.3', '>=')) { + $this->markTestSkipped('PHP7.3+ built-in function mb_strtoupper() behaves slightly different from Multibyte::strtoupper()'); + } + + $string = 'ḁḃḅḇḉḋḍḏḑḓḕḗḙḛḝḟḡḣḥḧḩḫḭḯḱḳḵḷḹḻḽḿṁṃṅṇṉṋṍṏṑṓṕṗṙṛṝṟṡṣṥṧṩṫṭṯṱṳṵṷṹṻṽṿẁẃẅẇẉẋẍẏẑẓẕẖẗẘẙẚạảấầẩẫậắằẳẵặẹẻẽếềểễệỉịọỏốồổỗộớờởỡợụủứừửữựỳỵỷỹ'; $result = mb_strtoupper($string); - $expected = 'ΩKÅ'; + $expected = 'ḀḂḄḆḈḊḌḎḐḒḔḖḘḚḜḞḠḢḤḦḨḪḬḮḰḲḴḶḸḺḼḾṀṂṄṆṈṊṌṎṐṒṔṖṘṚṜṞṠṢṤṦṨṪṬṮṰṲṴṶṸṺṼṾẀẂẄẆẈẊẌẎẐẒẔẖẗẘẙẚẠẢẤẦẨẪẬẮẰẲẴẶẸẺẼẾỀỂỄỆỈỊỌỎỐỒỔỖỘỚỜỞỠỢỤỦỨỪỬỮỰỲỴỶỸ'; $this->assertEquals($expected, $result); + } + +/** + * testUsingMbStrtoupperLigatures method + * + * @return void + */ + public function testUsingMbStrtoupperLigatures() { + if (extension_loaded('mbstring') && version_compare(PHP_VERSION, '7.3', '>=')) { + $this->markTestSkipped('PHP7.3+ built-in function mb_strtoupper() behaves slightly different from Multibyte::strtoupper()'); + } $string = 'fffiflffifflſtstﬓﬔﬕﬖﬗ'; $result = mb_strtoupper($string); diff --git a/lib/Cake/Test/Case/Model/Behavior/TranslateBehaviorTest.php b/lib/Cake/Test/Case/Model/Behavior/TranslateBehaviorTest.php index 251e8a8bb..8bb584954 100644 --- a/lib/Cake/Test/Case/Model/Behavior/TranslateBehaviorTest.php +++ b/lib/Cake/Test/Case/Model/Behavior/TranslateBehaviorTest.php @@ -1144,6 +1144,16 @@ public function testFieldsRestoreAfterBind() { $TestModel->bindTranslation($translations); $result = $TestModel->find('first'); + $TestModel->find('first', array( + 'fields' => array( + 'TranslatedItem.title', + ), + )); + $TestModel->find('first', array( + 'fields' => array( + 'TranslatedItem.title', + ), + )); $this->assertArrayHasKey('Title', $result); $this->assertArrayHasKey('content', $result['Title'][0]); $this->assertArrayNotHasKey('title', $result); @@ -1445,6 +1455,8 @@ public function testNoExtraRowsForAssociatedTranslations() { public function testBeforeFindAllI18nConditions() { $this->skipIf(!$this->db instanceof Mysql, 'This test is only compatible with Mysql.'); + $dbName = $this->db->config['database']; + $this->loadFixtures('TranslateArticle', 'TranslatedArticle', 'User'); $TestModel = new TranslatedArticle(); $TestModel->cacheQueries = false; @@ -1461,7 +1473,7 @@ public function testBeforeFindAllI18nConditions() { 'table' => (object)array( 'tablePrefix' => '', 'table' => 'article_i18n', - 'schemaName' => 'cakephp_test', + 'schemaName' => $dbName, ), 'conditions' => array( 'TranslatedArticle.id' => (object)array( @@ -1479,7 +1491,7 @@ public function testBeforeFindAllI18nConditions() { 'table' => (object)array( 'tablePrefix' => '', 'table' => 'article_i18n', - 'schemaName' => 'cakephp_test', + 'schemaName' => $dbName, ), 'conditions' => array( 'TranslatedArticle.id' => (object)array( @@ -1527,6 +1539,8 @@ public function testBeforeFindAllI18nConditions() { public function testBeforeFindCountI18nConditions() { $this->skipIf(!$this->db instanceof Mysql, 'This test is only compatible with Mysql.'); + $dbName = $this->db->config['database']; + $this->loadFixtures('TranslateArticle', 'TranslatedArticle', 'User'); $TestModel = new TranslatedArticle(); $TestModel->cacheQueries = false; @@ -1543,7 +1557,7 @@ public function testBeforeFindCountI18nConditions() { 'table' => (object)array( 'tablePrefix' => '', 'table' => 'article_i18n', - 'schemaName' => 'cakephp_test', + 'schemaName' => $dbName, ), 'conditions' => array( '`TranslatedArticle`.`id`' => (object)array( @@ -1560,7 +1574,7 @@ public function testBeforeFindCountI18nConditions() { 'table' => (object)array( 'tablePrefix' => '', 'table' => 'article_i18n', - 'schemaName' => 'cakephp_test', + 'schemaName' => $dbName, ), 'conditions' => array( 'TranslatedArticle.id' => (object)array( diff --git a/lib/Cake/Test/Case/Model/CakeSchemaTest.php b/lib/Cake/Test/Case/Model/CakeSchemaTest.php index c7c8deab1..bdcaf2440 100644 --- a/lib/Cake/Test/Case/Model/CakeSchemaTest.php +++ b/lib/Cake/Test/Case/Model/CakeSchemaTest.php @@ -64,6 +64,13 @@ class MyAppSchema extends CakeSchema { 'published' => array('type' => 'string', 'null' => true, 'default' => 'Y', 'length' => 1), 'created' => array('type' => 'datetime', 'null' => true, 'default' => null), 'updated' => array('type' => 'datetime', 'null' => true, 'default' => null), + 'status' => array( + 'type' => 'enum(\'active\',\'deleted\')', + 'null' => false, + 'default' => 'active', + 'collate' => 'utf8_unicode_ci', + 'charset' => 'utf8', + ), 'indexes' => array('PRIMARY' => array('column' => 'id', 'unique' => true)), ); @@ -809,6 +816,14 @@ public function testSchemaComparison() { 'posts' => array( 'add' => array( 'summary' => array('type' => 'text', 'null' => true, 'after' => 'body'), + 'status' => array( + 'type' => 'enum(\'active\',\'deleted\')', + 'null' => false, + 'default' => 'active', + 'collate' => 'utf8_unicode_ci', + 'charset' => 'utf8', + 'after' => 'updated', + ), ), 'drop' => array( 'tableParameters' => array(), diff --git a/lib/Cake/Test/Case/Model/Datasource/Database/MysqlTest.php b/lib/Cake/Test/Case/Model/Datasource/Database/MysqlTest.php index fe7f3e0db..f569d3627 100644 --- a/lib/Cake/Test/Case/Model/Datasource/Database/MysqlTest.php +++ b/lib/Cake/Test/Case/Model/Datasource/Database/MysqlTest.php @@ -356,41 +356,6 @@ public function testIndexDetection() { $this->assertEquals($expected, $result); } -/** - * testBuildColumn method - * - * @return void - */ - public function testBuildColumn() { - $restore = $this->Dbo->columns; - $this->Dbo->columns = array('varchar(255)' => 1); - $data = array( - 'name' => 'testName', - 'type' => 'varchar(255)', - 'default', - 'null' => true, - 'key', - 'comment' => 'test' - ); - $result = $this->Dbo->buildColumn($data); - $expected = '`testName` DEFAULT NULL COMMENT \'test\''; - $this->assertEquals($expected, $result); - - $data = array( - 'name' => 'testName', - 'type' => 'varchar(255)', - 'default', - 'null' => true, - 'key', - 'charset' => 'utf8', - 'collate' => 'utf8_unicode_ci' - ); - $result = $this->Dbo->buildColumn($data); - $expected = '`testName` CHARACTER SET utf8 COLLATE utf8_unicode_ci DEFAULT NULL'; - $this->assertEquals($expected, $result); - $this->Dbo->columns = $restore; - } - /** * MySQL 4.x returns index data in a different format, * Using a mock ensure that MySQL 4.x output is properly parsed. @@ -3080,14 +3045,6 @@ public function testLength() { $expected = '5,2'; $this->assertSame($expected, $result); - $result = $this->Dbo->length("enum('test','me','now')"); - $expected = 4; - $this->assertSame($expected, $result); - - $result = $this->Dbo->length("set('a','b','cd')"); - $expected = 2; - $this->assertSame($expected, $result); - $result = $this->Dbo->length(false); $this->assertNull($result); @@ -3100,6 +3057,26 @@ public function testLength() { $this->assertSame($expected, $result); } +/** + * Tests the length of enum column. + * + * @return void + */ + public function testLengthEnum() { + $result = $this->Dbo->length("enum('test','me','now')"); + $this->assertNull($result); + } + +/** + * Tests the length of set column. + * + * @return void + */ + public function testLengthSet() { + $result = $this->Dbo->length("set('a','b','cd')"); + $this->assertNull($result); + } + /** * testBuildIndex method * @@ -3154,7 +3131,7 @@ public function testBuildIndex() { * * @return void */ - public function testBuildColumn2() { + public function testBuildColumn() { $data = array( 'name' => 'testName', 'type' => 'string', diff --git a/lib/Cake/Test/Case/Model/Datasource/Database/PostgresTest.php b/lib/Cake/Test/Case/Model/Datasource/Database/PostgresTest.php index 00364eb67..701865c44 100644 --- a/lib/Cake/Test/Case/Model/Datasource/Database/PostgresTest.php +++ b/lib/Cake/Test/Case/Model/Datasource/Database/PostgresTest.php @@ -1218,4 +1218,24 @@ public function testBuildColumnUuid() { $this->assertEquals('"col1" uuid', $result); } + +/** + * Test that postgres describes default columns with functions correctly. + * + * @return void + */ + public function testDescribeFunctionDefault() { + $db = $this->Dbo; + $db->execute('CREATE TABLE test_function_default_describe (id integer PRIMARY KEY, year int default date_part(\'year\'::text, now()))'); + $data = $db->describe('test_function_default_describe'); + + $expected = array( + 'type' => 'integer', + 'null' => true, + 'default' => 'date_part(\'year\', now())', + 'length' => null, + ); + $this->assertSame($expected, $data['year']); + $db->execute('DROP TABLE test_function_default_describe'); + } } diff --git a/lib/Cake/Test/Case/Model/Datasource/DboSourceTest.php b/lib/Cake/Test/Case/Model/Datasource/DboSourceTest.php index 9b9e9f00f..c8df92dc3 100644 --- a/lib/Cake/Test/Case/Model/Datasource/DboSourceTest.php +++ b/lib/Cake/Test/Case/Model/Datasource/DboSourceTest.php @@ -1028,6 +1028,11 @@ public function testNotNullOnEnum() { $this->markTestSkipped('This test can only run on MySQL'); } $name = $this->db->fullTableName('enum_tests'); + + $query = "DROP TABLE IF EXISTS {$name};"; + $result = $this->db->query($query); + $this->assertTrue($result); + $query = "CREATE TABLE {$name} (mood ENUM('','happy','sad','ok') NOT NULL);"; $result = $this->db->query($query); $this->assertTrue($result); @@ -1047,6 +1052,40 @@ public function testNotNullOnEnum() { ), $enumResult); } +/** + * Test for MySQL enum datatype for a list of Integer stored as String + * + * @return void + */ + public function testIntValueAsStringOnEnum() { + if (!$this->db instanceof Mysql) { + $this->markTestSkipped('This test can only run on MySQL'); + } + $name = $this->db->fullTableName('enum_faya_tests'); + + $query = "DROP TABLE IF EXISTS {$name};"; + $result = $this->db->query($query); + $this->assertTrue($result); + + $query = "CREATE TABLE {$name} (faya enum('10','20','30','40') NOT NULL);"; + $result = $this->db->query($query); + $this->assertTrue($result); + + $EnumFayaTest = ClassRegistry::init('EnumFayaTest'); + $enumResult = $EnumFayaTest->save(array('faya' => '10')); + + $query = "DROP TABLE {$name};"; + $result = $this->db->query($query); + $this->assertTrue($result); + + $this->assertEquals(array( + 'EnumFayaTest' => array( + 'faya' => '10', + 'id' => '0' + ) + ), $enumResult); + } + /** * test order to generate query order clause for virtual fields * @@ -2138,12 +2177,19 @@ public function testLength() { $result = $this->db->length('decimal(20,3)'); $this->assertEquals('20,3', $result); + } +/** + * Test length parsing of enum column. + * + * @return void + */ + public function testLengthEnum() { $result = $this->db->length('enum("one", "longer")'); - $this->assertEquals(6, $result); + $this->assertNull($result); $result = $this->db->length("enum('One Value','ANOTHER ... VALUE ...')"); - $this->assertEquals(21, $result); + $this->assertNull($result); } /** diff --git a/lib/Cake/Test/Case/Model/ModelReadTest.php b/lib/Cake/Test/Case/Model/ModelReadTest.php index 851290547..05f27cb8a 100644 --- a/lib/Cake/Test/Case/Model/ModelReadTest.php +++ b/lib/Cake/Test/Case/Model/ModelReadTest.php @@ -6486,6 +6486,8 @@ public function testBuildQuery() { public function testBuildQueryAllI18nConditions() { $this->skipIf(!$this->db instanceof Mysql, 'This test is only compatible with Mysql.'); + $dbName = $this->db->config['database']; + $this->loadFixtures('TranslateArticle', 'TranslatedArticle', 'User'); $TestModel = new TranslatedArticle(); $TestModel->cacheQueries = false; @@ -6502,7 +6504,7 @@ public function testBuildQueryAllI18nConditions() { 'table' => (object)array( 'tablePrefix' => '', 'table' => 'article_i18n', - 'schemaName' => 'cakephp_test', + 'schemaName' => $dbName ), 'conditions' => array( 'TranslatedArticle.id' => (object)array( @@ -6520,7 +6522,7 @@ public function testBuildQueryAllI18nConditions() { 'table' => (object)array( 'tablePrefix' => '', 'table' => 'article_i18n', - 'schemaName' => 'cakephp_test', + 'schemaName' => $dbName ), 'conditions' => array( 'TranslatedArticle.id' => (object)array( @@ -6556,6 +6558,7 @@ public function testBuildQueryAllI18nConditions() { public function testBuildQueryCountI18nConditions() { $this->skipIf(!$this->db instanceof Mysql, 'This test is only compatible with Mysql.'); + $dbName = $this->db->config['database']; $this->loadFixtures('TranslateArticle', 'TranslatedArticle', 'User'); $TestModel = new TranslatedArticle(); $TestModel->cacheQueries = false; @@ -6572,7 +6575,7 @@ public function testBuildQueryCountI18nConditions() { 'table' => (object)array( 'tablePrefix' => '', 'table' => 'article_i18n', - 'schemaName' => 'cakephp_test', + 'schemaName' => $dbName ), 'conditions' => array( '`TranslatedArticle`.`id`' => (object)array( @@ -6589,7 +6592,7 @@ public function testBuildQueryCountI18nConditions() { 'table' => (object)array( 'tablePrefix' => '', 'table' => 'article_i18n', - 'schemaName' => 'cakephp_test', + 'schemaName' => $dbName ), 'conditions' => array( 'TranslatedArticle.id' => (object)array( diff --git a/lib/Cake/Test/Case/Network/Email/CakeEmailTest.php b/lib/Cake/Test/Case/Network/Email/CakeEmailTest.php index a0d15bec8..ca7ae2a38 100644 --- a/lib/Cake/Test/Case/Network/Email/CakeEmailTest.php +++ b/lib/Cake/Test/Case/Network/Email/CakeEmailTest.php @@ -334,23 +334,34 @@ public static function invalidEmails() { /** * testBuildInvalidData * - * @dataProvider invalidEmails * @expectedException SocketException + * @expectedExceptionMessage The email set for "_to" is empty. * @return void */ - public function testInvalidEmail($value) { - $this->CakeEmail->to($value); + public function testInvalidEmail() { + $this->CakeEmail->to(''); } /** * testBuildInvalidData * - * @dataProvider invalidEmails * @expectedException SocketException + * @expectedExceptionMessage Invalid email set for "_from". You passed "cake.@" * @return void */ - public function testInvalidEmailAdd($value) { - $this->CakeEmail->addTo($value); + public function testInvalidFrom() { + $this->CakeEmail->from('cake.@'); + } + +/** + * testBuildInvalidData + * + * @expectedException SocketException + * @expectedExceptionMessage Invalid email set for "_to". You passed "1" + * @return void + */ + public function testInvalidEmailAdd() { + $this->CakeEmail->addTo('1'); } /** @@ -423,7 +434,7 @@ public function testCustomEmailValidation() { * @return void * * @expectedException SocketException - * @expectedExceptionMessage Invalid email: "fail.@example.com" + * @expectedExceptionMessage Invalid email set for "_to". You passed "fail.@example.com" */ public function testUnsetEmailPattern() { $email = new CakeEmail(); diff --git a/lib/Cake/Test/Case/Network/Http/HttpSocketTest.php b/lib/Cake/Test/Case/Network/Http/HttpSocketTest.php index 8332d82ab..3ac6682f9 100644 --- a/lib/Cake/Test/Case/Network/Http/HttpSocketTest.php +++ b/lib/Cake/Test/Case/Network/Http/HttpSocketTest.php @@ -701,7 +701,7 @@ public function testRequestWithConstructor() { ); $http = $this->getMock('TestHttpSocket', array('read', 'write', 'connect', 'request'), array($request)); - $expected = array('method' => 'GET', 'uri' => '/_test'); + $expected = array('method' => 'GET', 'uri' => 'http://localhost:5984/_test'); $http->expects($this->at(0))->method('request')->with($expected); $http->get('/_test'); diff --git a/lib/Cake/Test/Case/TestSuite/CakeTestFixtureTest.php b/lib/Cake/Test/Case/TestSuite/CakeTestFixtureTest.php index 597490d60..379d1a472 100644 --- a/lib/Cake/Test/Case/TestSuite/CakeTestFixtureTest.php +++ b/lib/Cake/Test/Case/TestSuite/CakeTestFixtureTest.php @@ -231,7 +231,6 @@ class CakeTestFixtureTest extends CakeTestCase { public function setUp() { parent::setUp(); $methods = array_diff(get_class_methods('DboSource'), array('enabled')); - $methods[] = 'connect'; $this->criticDb = $this->getMock('DboSource', $methods); $this->criticDb->fullDebug = true; diff --git a/lib/Cake/Test/Case/Utility/CakeTimeTest.php b/lib/Cake/Test/Case/Utility/CakeTimeTest.php index b358b1b48..4bc9f8a62 100644 --- a/lib/Cake/Test/Case/Utility/CakeTimeTest.php +++ b/lib/Cake/Test/Case/Utility/CakeTimeTest.php @@ -421,6 +421,18 @@ public function testNice() { $this->_restoreSystemTimezone(); } + public function testNiceTimezoneConversion() { + date_default_timezone_set('Europe/Copenhagen'); // server timezone + $clientTimeZone = new DateTimeZone('Asia/Bangkok'); + $clientDateTime = new DateTime('2019-01-31 10:00:00', $clientTimeZone); + // Convert to UTC. + $actual = CakeTime::nice($clientDateTime, 'UTC', '%Y-%m-%d %H:%M:%S'); + $clientDateTime->setTimezone(new DateTimeZone('UTC')); + $expected = $clientDateTime->format('Y-m-d H:i:s'); + $this->assertEquals($expected, $actual); + $this->_restoreSystemTimezone(); + } + /** * testNiceShort method * @@ -966,23 +978,44 @@ public function testFromString() { */ public function testFromStringWithDateTime() { date_default_timezone_set('UTC'); - $date = new DateTime('+1 hour', new DateTimeZone('America/New_York')); $result = $this->Time->fromString($date, 'UTC'); $date->setTimezone(new DateTimeZone('UTC')); $expected = $date->format('U') + $date->getOffset(); - $this->assertWithinMargin($expected, $result, 1); + $this->_restoreSystemTimezone(); + } + public function testFromStringWithDateTimeAsia() { date_default_timezone_set('Australia/Melbourne'); - $date = new DateTime('+1 hour', new DateTimeZone('America/New_York')); $result = $this->Time->fromString($date, 'Asia/Kuwait'); - $date->setTimezone(new DateTimeZone('Asia/Kuwait')); $expected = $date->format('U') + $date->getOffset(); $this->assertWithinMargin($expected, $result, 1); + $this->_restoreSystemTimezone(); + } + + public function testFromStringTimezoneConversionToUTC() { + date_default_timezone_set('Europe/Copenhagen'); // server timezone + $clientTimeZone = new DateTimeZone('Asia/Bangkok'); + $clientDateTime = new DateTime('2019-01-31 10:00:00', $clientTimeZone); + // Convert to UTC. + $actual = CakeTime::fromString($clientDateTime, 'UTC'); + $clientDateTime->setTimezone(new DateTimeZone('UTC')); + $expected = $clientDateTime->getTimestamp() + $clientDateTime->getOffset(); // 1548903600 + $this->assertEquals($expected, $actual); + $this->_restoreSystemTimezone(); + } + public function testFromStringUTCtoCopenhagen() { + date_default_timezone_set('UTC'); // server timezone + $clientTimeZone = new DateTimeZone('UTC'); + $clientDateTime = new DateTime('2012-01-01 10:00:00', $clientTimeZone); + $actual = CakeTime::fromString($clientDateTime, 'Europe/Copenhagen'); + $clientDateTime->setTimezone(new DateTimeZone('Europe/Copenhagen')); + $expected = $clientDateTime->getTimestamp() + $clientDateTime->getOffset(); // 1325415600 + $this->assertEquals($expected, $actual); $this->_restoreSystemTimezone(); } @@ -998,6 +1031,24 @@ public function testFromStringWithDateTimeNoConversion() { $this->assertEquals($result, $date->format('U')); } + public function testConvertToBangkok() { + $serverTimeZoneName = 'Europe/Copenhagen'; + date_default_timezone_set($serverTimeZoneName); + + $serverTimeZone = new DateTimeZone($serverTimeZoneName); + $DateTime = new DateTime('2019-01-31 04:00:00', $serverTimeZone); + $serverTimestamp = $DateTime->getTimestamp() + $DateTime->getOffset(); // 1548907200 + + $clientTimeZoneName = 'Asia/Bangkok'; + $clientTimeZone = new DateTimeZone($clientTimeZoneName); + $DateTime->setTimezone($clientTimeZone); + $expected = $DateTime->getTimestamp() + $DateTime->getOffset(); // 1548928800 + + $actual = CakeTime::convert($serverTimestamp, $clientTimeZoneName); + $this->assertEquals($expected, $actual); + $this->_restoreSystemTimezone(); + } + /** * test converting time specifiers using a time definition localfe file * @@ -1149,6 +1200,28 @@ public function testI18nFormat() { $this->assertEquals($expected, $result); } + public function testI18nFormatTimezoneConversionToUTC() { + date_default_timezone_set('Europe/Copenhagen'); // server timezone + $clientTimeZone = new DateTimeZone('Asia/Bangkok'); + $clientDateTime = new DateTime('2019-01-31 10:00:00', $clientTimeZone); + // Convert to UTC. + $actual = CakeTime::i18nFormat($clientDateTime, '%Y-%m-%d %H:%M:%S', false, 'UTC'); + $clientDateTime->setTimezone(new DateTimeZone('UTC')); + $expected = $clientDateTime->format('Y-m-d H:i:s'); + $this->assertEquals($expected, $actual); + $this->_restoreSystemTimezone(); + } + + public function testI18nFormatUTCtoCopenhagen() { + date_default_timezone_set('UTC'); + $clientTimeZone = new DateTimeZone('UTC'); + $clientDateTime = new DateTime('2012-01-01 10:00:00', $clientTimeZone); + $actual = CakeTime::i18nFormat($clientDateTime, '%Y-%m-%d %H:%M', false, 'Europe/Copenhagen'); + $clientDateTime->setTimezone(new DateTimeZone('Europe/Copenhagen')); + $expected = $clientDateTime->format('Y-m-d H:i'); + $this->assertEquals($expected, $actual); + } + /** * test new format() syntax which inverts first and second parameters * @@ -1217,7 +1290,7 @@ public function testListTimezones() { * * @return void */ - public function testCorrectTimezoneConversion() { + public function testCorrectTimezoneConversionAsString() { date_default_timezone_set('UTC'); $date = '2012-01-01 10:00:00'; $converted = CakeTime::format($date, '%Y-%m-%d %H:%M', '', 'Europe/Copenhagen'); @@ -1226,4 +1299,27 @@ public function testCorrectTimezoneConversion() { $this->assertEquals($expected->format('Y-m-d H:i'), $converted); } + public function testCorrectTimezoneConversionAsObject() { + date_default_timezone_set('UTC'); + $clientTimeZone = new DateTimeZone('UTC'); + $date = '2012-01-01 10:00:00'; + $clientDateTime = new DateTime($date, $clientTimeZone); + $converted = CakeTime::format($clientDateTime, '%Y-%m-%d %H:%M', '', 'Europe/Copenhagen'); + $clientDateTime->setTimezone(new DateTimeZone('Europe/Copenhagen')); + $expected = $clientDateTime->format('Y-m-d H:i'); + $this->assertEquals($expected, $converted); + } + + public function testFormatTimezoneConversionToUTC() { + date_default_timezone_set('Europe/Copenhagen'); // server timezone + $clientTimeZone = new DateTimeZone('Asia/Bangkok'); + $clientDateTime = new DateTime('2019-01-31 10:00:00', $clientTimeZone); + // Convert to UTC. + $actual = CakeTime::format($clientDateTime, '%Y-%m-%d %H:%M:%S', false, 'UTC'); + $clientDateTime->setTimezone(new DateTimeZone('UTC')); + $expected = $clientDateTime->format('Y-m-d H:i:s'); + $this->assertEquals($expected, $actual); + $this->_restoreSystemTimezone(); + } + } diff --git a/lib/Cake/Test/Case/View/Helper/FormHelperTest.php b/lib/Cake/Test/Case/View/Helper/FormHelperTest.php index 40a147782..eab4b0bd5 100644 --- a/lib/Cake/Test/Case/View/Helper/FormHelperTest.php +++ b/lib/Cake/Test/Case/View/Helper/FormHelperTest.php @@ -2084,6 +2084,62 @@ public function testPasswordValidation() { $this->assertTags($result, $expected); } +/** + * Test validation errors with error options + * + * @return void + */ + public function testPasswordValidationWithOptions() { + $Contact = ClassRegistry::getObject('Contact'); + $Contact->validationErrors['password'] = array('Please provide a password'); + + $result = $this->Form->input('Contact.password', array( + 'error' => array( + 'attributes' => array('class' => 'special-error-class'), + ) + )); + $expected = array( + 'div' => array('class' => 'input password error'), + 'label' => array('for' => 'ContactPassword'), + 'Password', + '/label', + 'input' => array( + 'type' => 'password', 'name' => 'data[Contact][password]', + 'id' => 'ContactPassword', 'class' => 'form-error' + ), + array('div' => array('class' => 'special-error-class')), + 'Please provide a password', + '/div', + '/div' + ); + $this->assertTags($result, $expected); + + $Contact->validationErrors['password'] = array('Please provide a password
otherwise you will not be able to login'); + $result = $this->Form->input('Contact.password', array( + 'error' => array( + 'attributes' => array( + 'class' => 'special-error-class', + 'escape' => false, + ) + ) + )); + $expected = array( + 'div' => array('class' => 'input password error'), + 'label' => array('for' => 'ContactPassword'), + 'Password', + '/label', + 'input' => array( + 'type' => 'password', 'name' => 'data[Contact][password]', + 'id' => 'ContactPassword', 'class' => 'form-error' + ), + array('div' => array('class' => 'special-error-class')), + 'Please provide a password
otherwise you will not be able to login', + '/div', + '/div' + ); + $this->assertTags($result, $expected); + } + /** * Test validation errors, when validation message is an empty string. * @@ -7919,7 +7975,7 @@ public function testYear() { ); $this->assertTags($result, $expected); - $this->request->data['Contact']['published'] = ''; + $this->Form->request->data['Contact']['published'] = ''; $result = $this->Form->year('Contact.published', 2006, 2007, array('class' => 'year')); $expected = array( array('select' => array('name' => 'data[Contact][published][year]', 'id' => 'ContactPublishedYear', 'class' => 'year')), diff --git a/lib/Cake/Test/Case/View/Helper/RssHelperTest.php b/lib/Cake/Test/Case/View/Helper/RssHelperTest.php index d6606a7e3..0deae0d90 100644 --- a/lib/Cake/Test/Case/View/Helper/RssHelperTest.php +++ b/lib/Cake/Test/Case/View/Helper/RssHelperTest.php @@ -245,7 +245,11 @@ public function testItems() { array('title' => 'title3', 'guid' => 'http://www.example.com/guid3', 'link' => 'http://www.example.com/link3', 'description' => 'description3') ); - $result = $this->Rss->items($items, create_function('$v', '$v[\'title\'] = $v[\'title\'] . \'-transformed\'; return $v;')); + $result = $this->Rss->items($items, function ($v) { + $v['title'] = $v['title'] . '-transformed'; + + return $v; + }); $expected = array( '_checkException( + 'Object of class TestObjectWithoutToString could not be converted to string' + ); + $objectWithToString = new TestObjectWithoutToString(); $this->View->assign('testWithObjectWithoutToString', $objectWithToString); } @@ -1547,13 +1547,13 @@ public function testBlockAppend($value) { /** * Test appending an object without __toString magic method to a block with append. * - * This should produce a "Object of class TestObjectWithoutToString could not be converted to string" error - * which gets thrown as a PHPUnit_Framework_Error Exception by PHPUnit. - * - * @expectedException PHPUnit_Framework_Error * @return void */ public function testBlockAppendObjectWithoutToString() { + $this->_checkException( + 'Object of class TestObjectWithoutToString could not be converted to string' + ); + $object = new TestObjectWithoutToString(); $this->View->assign('testBlock', 'Block '); $this->View->append('testBlock', $object); @@ -1576,13 +1576,13 @@ public function testBlockPrepend($value) { /** * Test prepending an object without __toString magic method to a block with prepend. * - * This should produce a "Object of class TestObjectWithoutToString could not be converted to string" error - * which gets thrown as a PHPUnit_Framework_Error Exception by PHPUnit. - * - * @expectedException PHPUnit_Framework_Error * @return void */ public function testBlockPrependObjectWithoutToString() { + $this->_checkException( + 'Object of class TestObjectWithoutToString could not be converted to string' + ); + $object = new TestObjectWithoutToString(); $this->View->assign('test', 'Block '); $this->View->prepend('test', $object); @@ -1839,4 +1839,12 @@ public function testViewVarDefaultValue() { $result = $this->View->get('title', $default); $this->assertEquals($expected, $result); } + + protected function _checkException($message) { + if (version_compare(PHP_VERSION, '7.4', '>=')) { + $this->setExpectedException('Error', $message); + } else { + $this->setExpectedException('PHPUnit_Framework_Error', $message); + } + } } diff --git a/lib/Cake/Test/bake_compare/Controller/ActionsUsingSessions.ctp b/lib/Cake/Test/bake_compare/Controller/ActionsUsingSessions.ctp index b4072d770..34e3fc23f 100644 --- a/lib/Cake/Test/bake_compare/Controller/ActionsUsingSessions.ctp +++ b/lib/Cake/Test/bake_compare/Controller/ActionsUsingSessions.ctp @@ -77,12 +77,11 @@ * @return void */ public function delete($id = null) { - $this->BakeArticle->id = $id; - if (!$this->BakeArticle->exists()) { + if (!$this->BakeArticle->exists($id)) { throw new NotFoundException(__('Invalid bake article')); } $this->request->allowMethod('post', 'delete'); - if ($this->BakeArticle->delete()) { + if ($this->BakeArticle->delete($id)) { $this->Flash->success(__('The bake article has been deleted.')); } else { $this->Flash->error(__('The bake article could not be deleted. Please, try again.')); diff --git a/lib/Cake/Test/bake_compare/Controller/ActionsWithNoSessions.ctp b/lib/Cake/Test/bake_compare/Controller/ActionsWithNoSessions.ctp index d3f5b19d5..cfdd24f7f 100644 --- a/lib/Cake/Test/bake_compare/Controller/ActionsWithNoSessions.ctp +++ b/lib/Cake/Test/bake_compare/Controller/ActionsWithNoSessions.ctp @@ -71,12 +71,11 @@ * @return void */ public function delete($id = null) { - $this->BakeArticle->id = $id; - if (!$this->BakeArticle->exists()) { + if (!$this->BakeArticle->exists($id)) { throw new NotFoundException(__('Invalid bake article')); } $this->request->allowMethod('post', 'delete'); - if ($this->BakeArticle->delete()) { + if ($this->BakeArticle->delete($id)) { return $this->flash(__('The bake article has been deleted.'), array('action' => 'index')); } else { return $this->flash(__('The bake article could not be deleted. Please, try again.'), array('action' => 'index')); diff --git a/lib/Cake/TestSuite/CakeTestCase.php b/lib/Cake/TestSuite/CakeTestCase.php index 56fefb487..11e022052 100644 --- a/lib/Cake/TestSuite/CakeTestCase.php +++ b/lib/Cake/TestSuite/CakeTestCase.php @@ -84,6 +84,7 @@ public function run(PHPUnit_Framework_TestResult $result = null) { $result = parent::run($result); if (!empty($this->fixtureManager)) { $this->fixtureManager->unload($this); + unset($this->fixtureManager, $this->db); } for ($i = ob_get_level(); $i < $level; ++$i) { @@ -164,6 +165,7 @@ public function tearDown() { if (isset($_GET['debug']) && $_GET['debug']) { ob_flush(); } + unset($this->_configure, $this->_pathRestore); } /** @@ -399,7 +401,7 @@ public function assertTags($string, $expected, $fullDebug = false) { $tags = (string)$tags; } $i++; - if (is_string($tags) && $tags{0} === '<') { + if (is_string($tags) && $tags[0] === '<') { $tags = array(substr($tags, 1) => array()); } elseif (is_string($tags)) { $tagsTrimmed = preg_replace('/\s+/m', '', $tags); diff --git a/lib/Cake/TestSuite/CakeTestRunner.php b/lib/Cake/TestSuite/CakeTestRunner.php index dfd2321de..29c451b8e 100644 --- a/lib/Cake/TestSuite/CakeTestRunner.php +++ b/lib/Cake/TestSuite/CakeTestRunner.php @@ -18,6 +18,14 @@ if (!class_exists('PHPUnit_TextUI_TestRunner')) { require_once 'PHPUnit/TextUI/TestRunner.php'; } +if (class_exists('SebastianBergmann\CodeCoverage\CodeCoverage')) { + class_alias('SebastianBergmann\CodeCoverage\CodeCoverage', 'PHP_CodeCoverage'); + class_alias('SebastianBergmann\CodeCoverage\Report\Text', 'PHP_CodeCoverage_Report_Text'); + class_alias('SebastianBergmann\CodeCoverage\Report\PHP', 'PHP_CodeCoverage_Report_PHP'); + class_alias('SebastianBergmann\CodeCoverage\Report\Clover', 'PHP_CodeCoverage_Report_Clover'); + class_alias('SebastianBergmann\CodeCoverage\Report\Html\Facade', 'PHP_CodeCoverage_Report_HTML'); + class_alias('SebastianBergmann\CodeCoverage\Exception', 'PHP_CodeCoverage_Exception'); +} App::uses('CakeFixtureManager', 'TestSuite/Fixture'); @@ -45,6 +53,7 @@ public function __construct($loader, $params) { * @param PHPUnit_Framework_Test $suite The test suite to run * @param array $arguments The CLI arguments * @param bool $exit Exits by default or returns the results + * This argument is ignored if >PHPUnit5.2.0 * @return void */ public function doRun(PHPUnit_Framework_Test $suite, array $arguments = array(), $exit = true) { @@ -64,7 +73,7 @@ public function doRun(PHPUnit_Framework_Test $suite, array $arguments = array(), } } - $return = parent::doRun($suite, $arguments); + $return = parent::doRun($suite, $arguments, $exit); $fixture->shutdown(); return $return; } diff --git a/lib/Cake/TestSuite/CakeTestSuiteCommand.php b/lib/Cake/TestSuite/CakeTestSuiteCommand.php index c760d5d59..9d83e8ff7 100644 --- a/lib/Cake/TestSuite/CakeTestSuiteCommand.php +++ b/lib/Cake/TestSuite/CakeTestSuiteCommand.php @@ -95,18 +95,21 @@ public function run(array $argv, $exit = true) { unset($this->arguments['testFile']); try { - $result = $runner->doRun($suite, $this->arguments); + $result = $runner->doRun($suite, $this->arguments, false); } catch (PHPUnit_Framework_Exception $e) { print $e->getMessage() . "\n"; } if ($exit) { - if (isset($result) && $result->wasSuccessful()) { - exit(PHPUnit_TextUI_TestRunner::SUCCESS_EXIT); - } elseif (!isset($result) || $result->errorCount() > 0) { + if (!isset($result) || $result->errorCount() > 0) { exit(PHPUnit_TextUI_TestRunner::EXCEPTION_EXIT); } - exit(PHPUnit_TextUI_TestRunner::FAILURE_EXIT); + if ($result->failureCount() > 0) { + exit(PHPUnit_TextUI_TestRunner::FAILURE_EXIT); + } + + // Default to success even if there are warnings to match phpunit's behavior + exit(PHPUnit_TextUI_TestRunner::SUCCESS_EXIT); } } diff --git a/lib/Cake/TestSuite/CakeTestSuiteDispatcher.php b/lib/Cake/TestSuite/CakeTestSuiteDispatcher.php index 66ca94cfd..4f997c078 100644 --- a/lib/Cake/TestSuite/CakeTestSuiteDispatcher.php +++ b/lib/Cake/TestSuite/CakeTestSuiteDispatcher.php @@ -16,8 +16,24 @@ * @license https://opensource.org/licenses/mit-license.php MIT License */ +/** + * Path to the tests directory of the app. + */ +if (!defined('TESTS')) { + define('TESTS', APP . 'Test' . DS); +} + +/** + * Path to the test cases directory of CakePHP. + */ define('CORE_TEST_CASES', CAKE . 'Test' . DS . 'Case'); -define('APP_TEST_CASES', TESTS . 'Case'); + +/** + * Path to the test cases directory of the app. + */ +if (!defined('APP_TEST_CASES')) { + define('APP_TEST_CASES', TESTS . 'Case'); +} App::uses('CakeTestSuiteCommand', 'TestSuite'); @@ -154,7 +170,9 @@ public function loadTestFramework() { } elseif (is_file($vendor . DS . 'phpunit.phar')) { $backup = $GLOBALS['_SERVER']['SCRIPT_NAME']; $GLOBALS['_SERVER']['SCRIPT_NAME'] = '-'; + ob_start(); $included = include_once $vendor . DS . 'phpunit.phar'; + ob_end_clean(); $GLOBALS['_SERVER']['SCRIPT_NAME'] = $backup; return $included; } diff --git a/lib/Cake/TestSuite/ControllerTestCase.php b/lib/Cake/TestSuite/ControllerTestCase.php index ff4adfb58..b13ce7df3 100644 --- a/lib/Cake/TestSuite/ControllerTestCase.php +++ b/lib/Cake/TestSuite/ControllerTestCase.php @@ -265,7 +265,7 @@ protected function _testAction($url, $options = array()) { ->will($this->returnValue($options['data'])); } - $Dispatch = new ControllerTestDispatcher(); + $Dispatch = $this->_createDispatcher(); foreach (Router::$routes as $route) { if ($route instanceof RedirectRoute) { $route->response = $this->getMock('CakeResponse', array('send')); @@ -315,6 +315,15 @@ protected function _testAction($url, $options = array()) { return $this->{$options['return']}; } +/** + * Creates the test dispatcher class + * + * @return Dispatcher + */ + protected function _createDispatcher() { + return new ControllerTestDispatcher(); + } + /** * Generates a mocked controller and mocks any classes passed to `$mocks`. By * default, `_stop()` is stubbed as is sending the response headers, so to not @@ -418,4 +427,20 @@ public function generate($controller, $mocks = array()) { return $this->controller; } +/** + * Unsets some properties to free memory. + * + * @return void + */ + public function tearDown() { + parent::tearDown(); + unset( + $this->contents, + $this->controller, + $this->headers, + $this->result, + $this->view, + $this->vars + ); + } } diff --git a/lib/Cake/Utility/CakeTime.php b/lib/Cake/Utility/CakeTime.php index 2a1de55f3..63911bfde 100644 --- a/lib/Cake/Utility/CakeTime.php +++ b/lib/Cake/Utility/CakeTime.php @@ -239,9 +239,9 @@ protected static function _translateSpecifier($specifier) { /** * Converts given time (in server's time zone) to user's local time, given his/her timezone. * - * @param string $serverTime UNIX timestamp - * @param string|DateTimeZone $timezone User's timezone string or DateTimeZone object - * @return int UNIX timestamp + * @param int $serverTime Server's timestamp. + * @param string|DateTimeZone $timezone User's timezone string or DateTimeZone object. + * @return int User's timezone timestamp. * @link https://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#TimeHelper::convert */ public static function convert($serverTime, $timezone) { @@ -303,11 +303,11 @@ public static function serverOffset() { } /** - * Returns a UNIX timestamp, given either a UNIX timestamp or a valid strtotime() date string. + * Returns a timestamp, given either a UNIX timestamp or a valid strtotime() date string. * * @param int|string|DateTime $dateString UNIX timestamp, strtotime() valid string or DateTime object * @param string|DateTimeZone $timezone Timezone string or DateTimeZone object - * @return string Parsed timestamp + * @return int|false Parsed given timezone timestamp. * @link https://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#TimeHelper::fromString */ public static function fromString($dateString, $timezone = null) { @@ -354,22 +354,22 @@ public static function fromString($dateString, $timezone = null) { * See http://php.net/manual/en/function.strftime.php for information on formatting * using locale strings. * - * @param int|string|DateTime $dateString UNIX timestamp, strtotime() valid string or DateTime object + * @param int|string|DateTime $date UNIX timestamp, strtotime() valid string or DateTime object * @param string|DateTimeZone $timezone Timezone string or DateTimeZone object * @param string $format The format to use. If null, `CakeTime::$niceFormat` is used * @return string Formatted date string * @link https://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#TimeHelper::nice */ - public static function nice($dateString = null, $timezone = null, $format = null) { - if (!$dateString) { - $dateString = time(); + public static function nice($date = null, $timezone = null, $format = null) { + if (!$date) { + $date = time(); } - $date = static::fromString($dateString, $timezone); - + $timestamp = static::fromString($date, $timezone); if (!$format) { $format = static::$niceFormat; } - return static::_strftime(static::convertSpecifiers($format, $date), $date); + $convertedFormat = static::convertSpecifiers($format, $timestamp); + return static::_strftimeWithTimezone($convertedFormat, $timestamp, $date, $timezone); } /** @@ -382,28 +382,31 @@ public static function nice($dateString = null, $timezone = null, $format = null * If $dateString's year is the current year, the returned string does not * include mention of the year. * - * @param int|string|DateTime $dateString UNIX timestamp, strtotime() valid string or DateTime object + * @param int|string|DateTime $date UNIX timestamp, strtotime() valid string or DateTime object * @param string|DateTimeZone $timezone Timezone string or DateTimeZone object * @return string Described, relative date string * @link https://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#TimeHelper::niceShort */ - public static function niceShort($dateString = null, $timezone = null) { - if (!$dateString) { - $dateString = time(); + public static function niceShort($date = null, $timezone = null) { + if (!$date) { + $date = time(); } - $date = static::fromString($dateString, $timezone); + $timestamp = static::fromString($date, $timezone); - if (static::isToday($dateString, $timezone)) { - return __d('cake', 'Today, %s', static::_strftime("%H:%M", $date)); + if (static::isToday($date, $timezone)) { + $formattedDate = static::_strftimeWithTimezone("%H:%M", $timestamp, $date, $timezone); + return __d('cake', 'Today, %s', $formattedDate); } - if (static::wasYesterday($dateString, $timezone)) { - return __d('cake', 'Yesterday, %s', static::_strftime("%H:%M", $date)); + if (static::wasYesterday($date, $timezone)) { + $formattedDate = static::_strftimeWithTimezone("%H:%M", $timestamp, $date, $timezone); + return __d('cake', 'Yesterday, %s', $formattedDate); } - if (static::isTomorrow($dateString, $timezone)) { - return __d('cake', 'Tomorrow, %s', static::_strftime("%H:%M", $date)); + if (static::isTomorrow($date, $timezone)) { + $formattedDate = static::_strftimeWithTimezone("%H:%M", $timestamp, $date, $timezone); + return __d('cake', 'Tomorrow, %s', $formattedDate); } - $d = static::_strftime("%w", $date); + $d = static::_strftimeWithTimezone("%w", $timestamp, $date, $timezone); $day = array( __d('cake', 'Sunday'), __d('cake', 'Monday'), @@ -413,18 +416,21 @@ public static function niceShort($dateString = null, $timezone = null) { __d('cake', 'Friday'), __d('cake', 'Saturday') ); - if (static::wasWithinLast('7 days', $dateString, $timezone)) { - return sprintf('%s %s', $day[$d], static::_strftime(static::$niceShortFormat, $date)); + if (static::wasWithinLast('7 days', $date, $timezone)) { + $formattedDate = static::_strftimeWithTimezone(static::$niceShortFormat, $timestamp, $date, $timezone); + return sprintf('%s %s', $day[$d], $formattedDate); } - if (static::isWithinNext('7 days', $dateString, $timezone)) { - return __d('cake', 'On %s %s', $day[$d], static::_strftime(static::$niceShortFormat, $date)); + if (static::isWithinNext('7 days', $date, $timezone)) { + $formattedDate = static::_strftimeWithTimezone(static::$niceShortFormat, $timestamp, $date, $timezone); + return __d('cake', 'On %s %s', $day[$d], $formattedDate); } $y = ''; - if (!static::isThisYear($date)) { + if (!static::isThisYear($timestamp)) { $y = ' %Y'; } - return static::_strftime(static::convertSpecifiers("%b %eS{$y}, %H:%M", $date), $date); + $format = static::convertSpecifiers("%b %eS{$y}, %H:%M", $timestamp); + return static::_strftimeWithTimezone($format, $timestamp, $date, $timezone); } /** @@ -1055,17 +1061,18 @@ public static function format($date, $format = null, $default = false, $timezone * @link https://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#TimeHelper::i18nFormat */ public static function i18nFormat($date, $format = null, $default = false, $timezone = null) { - $date = static::fromString($date, $timezone); - if ($date === false && $default !== false) { + $timestamp = static::fromString($date, $timezone); + if ($timestamp === false && $default !== false) { return $default; } - if ($date === false) { + if ($timestamp === false) { return ''; } if (empty($format)) { $format = '%x'; } - return static::_strftime(static::convertSpecifiers($format, $date), $date); + $convertedFormat = static::convertSpecifiers($format, $timestamp); + return static::_strftimeWithTimezone($convertedFormat, $timestamp, $date, $timezone); } /** @@ -1156,13 +1163,12 @@ public static function listTimezones($filter = null, $country = null, $options = * Handles utf8_encoding the result of strftime when necessary. * * @param string $format Format string. - * @param int $date Timestamp to format. + * @param int $timestamp Timestamp to format. * @return string formatted string with correct encoding. */ - protected static function _strftime($format, $date) { - $format = strftime($format, $date); + protected static function _strftime($format, $timestamp) { + $format = strftime($format, $timestamp); $encoding = Configure::read('App.encoding'); - if (!empty($encoding) && $encoding === 'UTF-8') { if (function_exists('mb_check_encoding')) { $valid = mb_check_encoding($format, $encoding); @@ -1176,4 +1182,29 @@ protected static function _strftime($format, $date) { return $format; } +/** + * Multibyte wrapper for strftime. + * + * Adjusts the timezone when necessary before formatting the time. + * + * @param string $format Format string. + * @param int $timestamp Timestamp to format. + * @param int|string|DateTime $date Timestamp, strtotime() valid string or DateTime object. + * @param string|DateTimeZone $timezone Timezone string or DateTimeZone object. + * @return string Formatted date string with correct encoding. + */ + protected static function _strftimeWithTimezone($format, $timestamp, $date, $timezone) { + $serverTimeZone = date_default_timezone_get(); + if ( + !empty($timezone) && + $date instanceof DateTime && + $date->getTimezone()->getName() != $serverTimeZone + ) { + date_default_timezone_set($timezone); + } + $result = static::_strftime($format, $timestamp); + date_default_timezone_set($serverTimeZone); + return $result; + } + } diff --git a/lib/Cake/Utility/ClassRegistry.php b/lib/Cake/Utility/ClassRegistry.php index 6234bcf55..d7475a72b 100644 --- a/lib/Cake/Utility/ClassRegistry.php +++ b/lib/Cake/Utility/ClassRegistry.php @@ -91,7 +91,7 @@ public static function getInstance() { * stored in the registry and returned. * @param bool $strict if set to true it will return false if the class was not found instead * of trying to create an AppModel - * @return $class instance of ClassName. + * @return bool|object $class instance of ClassName. * @throws CakeException when you try to construct an interface or abstract class. */ public static function init($class, $strict = false) { @@ -300,7 +300,7 @@ public static function config($type, $param = array()) { * * @param string $alias Alias to check. * @param string $class Class name. - * @return bool + * @return bool|object Object stored in registry or `false` if the object does not exist. */ protected function &_duplicate($alias, $class) { $duplicate = false; diff --git a/lib/Cake/Utility/Debugger.php b/lib/Cake/Utility/Debugger.php index 281453f5f..ef906659e 100644 --- a/lib/Cake/Utility/Debugger.php +++ b/lib/Cake/Utility/Debugger.php @@ -181,7 +181,9 @@ public static function dump($var, $depth = 3) { * as well as export the variable using exportVar. By default the log is written to the debug log. * * @param mixed $var Variable or content to log - * @param int $level type of log to use. Defaults to LOG_DEBUG + * @param int|string $level Type of log to use. Defaults to LOG_DEBUG. When value is an integer + * or a string matching the recognized levels, then it will + * be treated as a log level. Otherwise it's treated as a scope. * @param int $depth The depth to output to. Defaults to 3. * @return void * @link https://book.cakephp.org/2.0/en/development/debugging.html#Debugger::log @@ -250,7 +252,7 @@ public static function showError($code, $description, $file = null, $line = null } $data = compact( - 'level', 'error', 'code', 'description', 'file', 'path', 'line', 'context' + 'level', 'error', 'code', 'description', 'file', 'line', 'context' ); echo $self->outputError($data); diff --git a/lib/Cake/Utility/Folder.php b/lib/Cake/Utility/Folder.php index 62fef677a..cf7e83e9a 100644 --- a/lib/Cake/Utility/Folder.php +++ b/lib/Cake/Utility/Folder.php @@ -122,7 +122,7 @@ class Folder { * * @param string $path Path to folder * @param bool $create Create folder if not found - * @param string|bool $mode Mode (CHMOD) to apply to created folder, false to ignore + * @param int|bool $mode Mode (CHMOD) to apply to created folder, false to ignore * @link https://book.cakephp.org/2.0/en/core-utility-libraries/file-folder.html#Folder */ public function __construct($path = false, $create = false, $mode = false) { @@ -520,7 +520,7 @@ public function tree($path = null, $exceptions = false, $type = null) { foreach ($iterator as $itemPath => $fsIterator) { if ($skipHidden) { $subPathName = $fsIterator->getSubPathname(); - if ($subPathName{0} === '.' || strpos($subPathName, DS . '.') !== false) { + if ($subPathName[0] === '.' || strpos($subPathName, DS . '.') !== false) { continue; } } diff --git a/lib/Cake/Utility/Hash.php b/lib/Cake/Utility/Hash.php index 08dd2700a..84c706aee 100644 --- a/lib/Cake/Utility/Hash.php +++ b/lib/Cake/Utility/Hash.php @@ -384,8 +384,8 @@ public static function remove(array $data, $path) { * following the path specified in `$groupPath`. * * @param array $data Array from where to extract keys and values - * @param string $keyPath A dot-separated string. - * @param string $valuePath A dot-separated string. + * @param array|string $keyPath A dot-separated string or array for formatting rules. + * @param array|string $valuePath A dot-separated string or array for formatting rules. * @param string $groupPath A dot-separated string. * @return array Combined array * @link https://book.cakephp.org/2.0/en/core-utility-libraries/hash.html#Hash::combine diff --git a/lib/Cake/Utility/ObjectCollection.php b/lib/Cake/Utility/ObjectCollection.php index 460ca86d0..1e36e4c4d 100644 --- a/lib/Cake/Utility/ObjectCollection.php +++ b/lib/Cake/Utility/ObjectCollection.php @@ -95,6 +95,7 @@ public function trigger($callback, $params = array(), $options = array()) { if (empty($this->_enabled)) { return true; } + $subject = null; if ($callback instanceof CakeEvent) { $event = $callback; if (is_array($event->data)) { @@ -125,7 +126,7 @@ public function trigger($callback, $params = array(), $options = array()) { } $result = null; foreach ($list as $name) { - $result = call_user_func_array(array($this->_loaded[$name], $callback), compact('subject') + $params); + $result = call_user_func_array(array($this->_loaded[$name], $callback), array_filter(compact('subject')) + $params); if ($options['collectReturn'] === true) { $collected[] = $result; } diff --git a/lib/Cake/Utility/Sanitize.php b/lib/Cake/Utility/Sanitize.php index 0f8b5e073..f05c2bb0f 100644 --- a/lib/Cake/Utility/Sanitize.php +++ b/lib/Cake/Utility/Sanitize.php @@ -72,7 +72,7 @@ public static function escape($string, $connection = 'default') { $db = ConnectionManager::getDataSource($connection); $string = $db->value($string, 'string'); $start = 1; - if ($string{0} === 'N') { + if ($string[0] === 'N') { $start = 2; } diff --git a/lib/Cake/Utility/Set.php b/lib/Cake/Utility/Set.php index 5958b9823..ac811da75 100644 --- a/lib/Cake/Utility/Set.php +++ b/lib/Cake/Utility/Set.php @@ -500,7 +500,7 @@ public static function matches($conditions, $data = array(), $i = null, $length $val = $data[$key]; - if ($op === '=' && $expected && $expected{0} === '/') { + if ($op === '=' && $expected && $expected[0] === '/') { return preg_match($expected, $val); } if ($op === '=' && $val != $expected) { diff --git a/lib/Cake/VERSION.txt b/lib/Cake/VERSION.txt index 0a226824d..844d3c122 100644 --- a/lib/Cake/VERSION.txt +++ b/lib/Cake/VERSION.txt @@ -17,4 +17,4 @@ // @license https://opensource.org/licenses/mit-license.php MIT License // +--------------------------------------------------------------------------------------------+ // //////////////////////////////////////////////////////////////////////////////////////////////////// -2.10.9 +2.10.20 diff --git a/lib/Cake/View/Helper/FormHelper.php b/lib/Cake/View/Helper/FormHelper.php index 8a15e1d7a..eabea8dfb 100644 --- a/lib/Cake/View/Helper/FormHelper.php +++ b/lib/Cake/View/Helper/FormHelper.php @@ -1060,6 +1060,8 @@ public function input($fieldName, $options = array()) { if ($options['type'] === 'radio' && isset($options['options'])) { $radioOptions = (array)$options['options']; unset($options['options']); + } else { + $radioOptions = array(); } $label = $this->_getLabel($fieldName, $options); @@ -1080,6 +1082,9 @@ public function input($fieldName, $options = array()) { $dateFormat = $this->_extractOption('dateFormat', $options, 'MDY'); $timeFormat = $this->_extractOption('timeFormat', $options, 12); unset($options['dateFormat'], $options['timeFormat']); + } else { + $dateFormat = 'MDY'; + $timeFormat = 12; } $type = $options['type']; @@ -2055,7 +2060,7 @@ public function submit($caption = null, $options = array()) { $tag = $this->Html->useTag('submitimage', $caption, $options); } elseif ($isImage) { unset($options['type']); - if ($caption{0} !== '/') { + if ($caption[0] !== '/') { $url = $this->webroot(Configure::read('App.imageBaseUrl') . $caption); } else { $url = $this->webroot(trim($caption, '/')); diff --git a/lib/Cake/View/Helper/HtmlHelper.php b/lib/Cake/View/Helper/HtmlHelper.php index 5fc043534..49651a70e 100644 --- a/lib/Cake/View/Helper/HtmlHelper.php +++ b/lib/Cake/View/Helper/HtmlHelper.php @@ -341,7 +341,7 @@ public function charset($charset = null) { * @param string $title The content to be wrapped by `` tags. * @param string|array $url Cake-relative URL or array of URL parameters, or external URL (starts with http://) * @param array $options Array of options and HTML attributes. - * @param string $confirmMessage JavaScript confirmation message. This + * @param string|bool $confirmMessage JavaScript confirmation message. This * argument is deprecated as of 2.6. Use `confirm` key in $options instead. * @return string An `` element. * @link https://book.cakephp.org/2.0/en/core-libraries/helpers/html.html#HtmlHelper::link diff --git a/lib/Cake/View/Helper/JsBaseEngineHelper.php b/lib/Cake/View/Helper/JsBaseEngineHelper.php index ca2d77621..3aa29b504 100644 --- a/lib/Cake/View/Helper/JsBaseEngineHelper.php +++ b/lib/Cake/View/Helper/JsBaseEngineHelper.php @@ -196,7 +196,7 @@ protected function _utf8ToHex($string) { $length = strlen($string); $return = ''; for ($i = 0; $i < $length; ++$i) { - $ord = ord($string{$i}); + $ord = ord($string[$i]); switch (true) { case $ord == 0x08: $return .= '\b'; @@ -216,10 +216,10 @@ protected function _utf8ToHex($string) { case $ord == 0x22: case $ord == 0x2F: case $ord == 0x5C: - $return .= '\\' . $string{$i}; + $return .= '\\' . $string[$i]; break; case (($ord >= 0x20) && ($ord <= 0x7F)): - $return .= $string{$i}; + $return .= $string[$i]; break; case (($ord & 0xE0) == 0xC0): if ($i + 1 >= $length) { @@ -227,7 +227,7 @@ protected function _utf8ToHex($string) { $return .= '?'; break; } - $charbits = $string{$i} . $string{$i + 1}; + $charbits = $string[$i] . $string[$i + 1]; $char = Multibyte::utf8($charbits); $return .= sprintf('\u%04s', dechex($char[0])); $i += 1; @@ -238,7 +238,7 @@ protected function _utf8ToHex($string) { $return .= '?'; break; } - $charbits = $string{$i} . $string{$i + 1} . $string{$i + 2}; + $charbits = $string[$i] . $string[$i + 1] . $string[$i + 2]; $char = Multibyte::utf8($charbits); $return .= sprintf('\u%04s', dechex($char[0])); $i += 2; @@ -249,7 +249,7 @@ protected function _utf8ToHex($string) { $return .= '?'; break; } - $charbits = $string{$i} . $string{$i + 1} . $string{$i + 2} . $string{$i + 3}; + $charbits = $string[$i] . $string[$i + 1] . $string[$i + 2] . $string[$i + 3]; $char = Multibyte::utf8($charbits); $return .= sprintf('\u%04s', dechex($char[0])); $i += 3; @@ -260,7 +260,7 @@ protected function _utf8ToHex($string) { $return .= '?'; break; } - $charbits = $string{$i} . $string{$i + 1} . $string{$i + 2} . $string{$i + 3} . $string{$i + 4}; + $charbits = $string[$i] . $string[$i + 1] . $string[$i + 2] . $string[$i + 3] . $string[$i + 4]; $char = Multibyte::utf8($charbits); $return .= sprintf('\u%04s', dechex($char[0])); $i += 4; @@ -271,7 +271,7 @@ protected function _utf8ToHex($string) { $return .= '?'; break; } - $charbits = $string{$i} . $string{$i + 1} . $string{$i + 2} . $string{$i + 3} . $string{$i + 4} . $string{$i + 5}; + $charbits = $string[$i] . $string[$i + 1] . $string[$i + 2] . $string[$i + 3] . $string[$i + 4] . $string[$i + 5]; $char = Multibyte::utf8($charbits); $return .= sprintf('\u%04s', dechex($char[0])); $i += 5; diff --git a/lib/Cake/View/View.php b/lib/Cake/View/View.php index 91776ad9a..085928d2e 100644 --- a/lib/Cake/View/View.php +++ b/lib/Cake/View/View.php @@ -120,9 +120,9 @@ class View extends CakeObject { public $view = null; /** - * Name of layout to use with this View. + * Name of layout to use with this View. If `false` then no layout is rendered. * - * @var string + * @var string|bool */ public $layout = 'default'; @@ -455,7 +455,7 @@ public function elementExists($name) { * a plugin view/layout can be used instead of the app ones. If the chosen plugin is not found * the view will be located along the regular view path cascade. * - * @param string $view Name of view file to use + * @param false|string $view Name of view file to use. * @param string $layout Layout to use. * @return string|null Rendered content or null if content already rendered and returned earlier. * @triggers View.beforeRender $this, array($viewFileName) @@ -807,7 +807,7 @@ public function uuid($object, $url) { * a layout or other element. Analogous to Controller::set(). * * @param string|array $one A string or an array of data. - * @param string|array $two Value in case $one is a string (which then works as the key). + * @param mixed $two Value in case $one is a string (which then works as the key). * Unused if $one is an associative array, otherwise serves as the values to $one's keys. * @return void */ diff --git a/lib/Cake/basics.php b/lib/Cake/basics.php index 61ca6f047..10d965c1c 100644 --- a/lib/Cake/basics.php +++ b/lib/Cake/basics.php @@ -135,7 +135,7 @@ function debug($var, $showHtml = null, $showFrom = true) { * - `start` - The stack frame to start generating a trace from. Defaults to 1 * * @param array $options Format for outputting stack trace - * @return mixed Formatted stack trace + * @return void Outputs formatted stack trace. * @see Debugger::trace() */ function stackTrace(array $options = array()) { @@ -167,17 +167,16 @@ function sortByKey(&$array, $sortBy, $order = 'asc', $type = SORT_NUMERIC) { if (!is_array($array)) { return null; } - + $sa = array(); foreach ($array as $key => $val) { $sa[$key] = $val[$sortBy]; } - if ($order === 'asc') { asort($sa, $type); } else { arsort($sa, $type); } - + $out = array(); foreach ($sa as $key => $val) { $out[] = $array[$key]; } @@ -194,9 +193,9 @@ function sortByKey(&$array, $sortBy, $order = 'asc', $type = SORT_NUMERIC) { * @param string|array|object $text Text to wrap through htmlspecialchars. Also works with arrays, and objects. * Arrays will be mapped and have all their elements escaped. Objects will be string cast if they * implement a `__toString` method. Otherwise the class name will be used. - * @param bool $double Encode existing html entities + * @param bool|string $double Boolean - encode existing html entities. String - character set to use when escaping. * @param string $charset Character set to use when escaping. Defaults to config value in 'App.encoding' or 'UTF-8' - * @return string|array|object Wrapped text, Wrapped Array or Wrapped Object + * @return string|array|bool|object Wrapped text, Wrapped Array or Wrapped Object. * @link https://book.cakephp.org/2.0/en/core-libraries/global-constants-and-functions.html#h */ function h($text, $double = true, $charset = null) { @@ -227,6 +226,7 @@ function h($text, $double = true, $charset = null) { } if (is_string($double)) { $charset = $double; + $double = true; } return htmlspecialchars($text, ENT_QUOTES, ($charset) ? $charset : $defaultCharset, $double); } @@ -431,7 +431,7 @@ function cache($path, $data = null, $expires = '+1 day', $target = 'cache') { if (!is_numeric($expires)) { $expires = strtotime($expires, $now); } - + $filename = ''; switch (strtolower($target)) { case 'cache': $filename = CACHE . $path; @@ -484,7 +484,7 @@ function cache($path, $data = null, $expires = '+1 day', $target = 'cache') { * all files in app/tmp/cache/views will be deleted * @param string $type Directory in tmp/cache defaults to view directory * @param string $ext The file extension you are deleting - * @return true if files found and deleted false otherwise + * @return bool `true` if files found and deleted, `false` otherwise. */ function clearCache($params = null, $type = 'views', $ext = '.php') { if (is_string($params) || $params === null) { @@ -551,8 +551,8 @@ function clearCache($params = null, $type = 'views', $ext = '.php') { /** * Recursively strips slashes from all values in an array * - * @param array $values Array of values to strip slashes - * @return mixed What is returned from calling stripslashes + * @param array|string $values Array of values or a string to strip slashes. + * @return array|string What is returned from calling stripslashes. * @link https://book.cakephp.org/2.0/en/core-libraries/global-constants-and-functions.html#stripslashes_deep */ function stripslashes_deep($values) { @@ -1025,14 +1025,13 @@ function LogError($message) { * Searches include path for files. * * @param string $file File to look for - * @return string Full path to file if exists, otherwise false + * @return bool|string Full path to file if exists, otherwise `false`. * @link https://book.cakephp.org/2.0/en/core-libraries/global-constants-and-functions.html#fileExistsInPath */ function fileExistsInPath($file) { $paths = explode(PATH_SEPARATOR, ini_get('include_path')); foreach ($paths as $path) { $fullPath = $path . DS . $file; - if (file_exists($fullPath)) { return $fullPath; } elseif (file_exists($file)) { diff --git a/lib/Cake/bootstrap.php b/lib/Cake/bootstrap.php index 2bb0316ad..399187e5f 100644 --- a/lib/Cake/bootstrap.php +++ b/lib/Cake/bootstrap.php @@ -86,13 +86,6 @@ define('IMAGES', WWW_ROOT . 'img' . DS); } -/** - * Path to the tests directory. - */ -if (!defined('TESTS')) { - define('TESTS', APP . 'Test' . DS); -} - /** * Path to the temporary files directory. */ diff --git a/migrate-database.sh b/migrate-database.sh index 455a57538..58d8bc44b 100755 --- a/migrate-database.sh +++ b/migrate-database.sh @@ -1,135 +1,245 @@ -#!/bin/bash -set -e -source ./Scripts/lib/shell_prompt.sh -source ./Scripts/lib/parsing.sh -openshift=$(parse_arg_exists "-[oO]*|--openshift" $*) -if [ $openshift 2> /dev/null ]; then - echo "Real environment bootargs..." +#!/usr/bin/env bash +set -eu +TOPDIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) +# shellcheck source=Scripts/lib/test/logging.sh +. "$TOPDIR/Scripts/lib/logging.sh" +# shellcheck source=Scripts/lib/test/parsing.sh +. "$TOPDIR/Scripts/lib/parsing.sh" +# shellcheck source=Scripts/lib/test/shell_prompt.sh +. "$TOPDIR/Scripts/lib/shell_prompt.sh" +openshift=$(parse_arg "-[oO]+|--openshift" "$@") +docker=$(parse_arg "--docker" "$@") +travis=$(parse_arg "--travis" "$@") +pargs=$(parse_arg_trim "-[oO]+|--openshift|--docker|--travis" "$@") +if [ -n "$openshift" ]; then + slogger -st "$0" "Bootargs...: ${pargs}" + # shellcheck source=Scripts/bootargs.sh + . "$TOPDIR/Scripts/bootargs.sh" "$@" else - echo "Provided local/test bootargs..." - source ./Scripts/bootargs.sh $* + slogger -st "$0" "Locally Testing values, bootargs...: ${pargs}" + # shellcheck source=Scripts/fooargs.sh + . "$TOPDIR/Scripts/fooargs.sh" "$@" fi -dbfile=database.cms.php -fix_socket="-Y" -config_app_checked="" +LOG=$(new_cake_log "$travis" "$openshift" "$docker") && slogger -st "$0" "$LOG" +usage=("" \ +"Usage: $0 [sockfile.sock] [-u] [-y|n] [-o] [-p ] [-t ] [-i] [--sql-password=] [--test-sql-password=]" \ +" To initialize the databases, enter in the ${MYSQL_HOST} host terminal: $0 -u -i" \ +" -------------" \ +" file.sock Set the socket file to connect SQL database" \ +" -u Update the database in app/Config/Schema/" \ +" -y Overwrite database.php and default socket file" \ +" -n Doesn't overwrite database.php and socket" \ +" -i --sql-password= --test-sql-password=" \ +" Initialize databases with new passwords and reset MYSQL_DATABASE and TEST_DATABASE_NAME privileges" \ +" -o, --openshift, --travis" \ +" Resets database.php, keep socket and update the database" \ +" -p=" \ +" Exports MYSQL_ROOT_PASSWORD" \ +" -t=" \ +" Exports MYSQL_PASSWORD" \ +" --database=" \ +" Exports MYSQL_DATABASE" \ +" --testunitbase=" \ +" Exports TEST_DATABASE_NAME" \ +" --enable-ed25519-plugin" \ +" Enable MariaDB plugin https://mariadb.com/kb/en/authentication-plugin-ed25519/" \ +" -v, --verbose" \ +" Outputs more debug information" \ +" -h, --help Displays this help" \ +"") +sql_connect="mysql" +# shellcheck disable=SC2153 +sql_connect_host="-h ${MYSQL_HOST} -P ${MYSQL_TCP_PORT}" +dbfile=database.php +schemafile=Schema/schema.php +sockfile=/tmp/mysqld.sock +config_app_checked="-Y" +test_checked=0 update_checked=0 -import_identities=0 -identities=app/Config/database.sql -new_pass="" -new_test_pass="" -saved=("$*") -sql_source="" -while [[ "$#" > 0 ]]; do case $1 in +initialize_databases=0 +saved=("$@") +authentication_plugin=0 +mysql_host="%" +ck_args="--connection=default" +# test_args="app AllTests --stderr" +test_args="app Controller/PagesController --stderr >> $LOG" +MARIADB_SHORT_NAME=$(docker_name "$SECONDARY_HUB") +while [ "$#" -gt 0 ]; do case "$1" in + --enable-ed25519-plugin*) + slogger -st "$0" "Enabled auth_ed25519 plugin for passwords..." + log_warning_msg "Plugin Not available from PHP PDO connect (you should avoid using it)" + authentication_plugin="ed25519";; --docker ) - sql_source="docker exec mysql ";; + bash -c "./Scripts/start_daemon.sh ${docker}" + # Running docker ... mysql's allowed to connect without any local mysql installation + docker exec "$MARIADB_SHORT_NAME" hostname 2>> "$LOG" + sql_connect="docker exec $MARIADB_SHORT_NAME mysql" + sockfile="$(pwd)/mysqldb/mysqld/mysqld.sock" + ;; -[uU]* ) - update_checked=1 - ;; - -[yY]* );; + update_checked=1 + ;; + --connection=test ) + ck_args="$1" + test_checked=1 + ;; + --connection* ) + ck_args="$1";; + *.sock ) sockfile=$1;; -[nN]* ) - fix_socket="-N" - dbfile="" - config_app_checked="-N" - ;; + sockfile="" + config_app_checked="-N";; -[iI]* ) - import_identities=1 - new_pass=$2 - new_test_pass=$3 - shift;shift;; + initialize_databases=1 + ;; + --sql-password*) + OPTIND=1 + parse_sql_password "set_DATABASE_PASSWORD" "Altering ${DATABASE_USER} password" "$@" + shift $((OPTIND -1)) + ;; + --test-sql-password*) + test_checked=1 + ck_args="--connection=test" + OPTIND=1 + parse_sql_password "set_MYSQL_PASSWORD" "Altering ${MYSQL_USER} password" "$@" + shift $((OPTIND -1)) + ;; -[vV]*|--verbose ) - [ -f $identities ] && cat $identities # Reset passed args (shift reset) - echo "Passed params : $0 ${saved} - and environment VARIABLES:" - export -p | grep "DATABASE\|MYSQL";; + text=("" \ +"Passed params : $0 ${saved[*]}" \ +"and environment VARIABLES:" \ +"$(export -p | grep "DATABASE\|MYSQL")" \ +"") + printf "%s\n" "${text[@]}" + ck_args="${ck_args} -v" + test_args="${test_args} -v" + ;; -[hH]*|--help ) - echo "Usage: $0 [-u] [-y|n] [-o] [-p|--sql-password=] [-t,--test-sql-password=] [-i] [-p|--new-sql-password=] [-t,--new-test-sql-password=] - -u - Update the database in app/Config/Schema/ - -y - Reset ${dbfile} and default socket file - -n - Doesn't reset ${dbfile} and socket - -i -p= -t= - Import SQL identities - -o, --openshift - Resets ${dbfile}, keep socket and update the database - -p, --sql-password= - Exports DATABASE_PASSWORD - -t,--test-sql-password= - Exports TEST_DATABASE_PASSWORD - -dbase= - Exports DATABASE_NAME - -tbase= - Exports TEST_DATABASE_NAME - -v, --verbose - Outputs more debug information - -h, --help - Displays this help" - exit 0;; - -[oO]*|--openshift ) - fix_socket="-N" - update_checked=1;; - -[pP]*|--sql-password*) - parse_sql_password "$1" "DATABASE_PASSWORD" "current ${DATABASE_USER}";; - -[tT]*|--test-sql-password*) - parse_sql_password "$1" "TEST_DATABASE_PASSWORD" "current ${TEST_DATABASE_USER}";; - -dbase*|-DBASE*) - parse_arg_export "$1" "-dbase*|-DBASE*" "DATABASE_NAME" "${DATABASE_USER} database";; - -tbase*|-TBASE*) - parse_arg_export "$1" "-tbase*|-TBASE*" "TEST_DATABASE_NAME" "${TEST_DATABASE_USER} database";; - *) echo "Unknown parameter passed: $0 $1"; exit 1;; + printf "%s\n" "${usage[@]}" + exit 0;; + -[oO]*|--openshift);; + --travis) + ;; + -[pP]* ) + parse_sql_password "MYSQL_ROOT_PASSWORD" "current ${DATABASE_USER} password" "$@" + shift $((OPTIND -1)) + ;; + -[tT]* ) + test_checked=1 + ck_args="--connection=test" + printf "Testing %s Unit..." $test_checked + parse_sql_password "MYSQL_PASSWORD" "current ${MYSQL_USER} password" "$@" + shift $((OPTIND -1)) + ;; + --database*) + # Transform long options to short ones + arg=$1; shift + # shellcheck disable=SC2046 + set -- $(echo "${arg}" \ + | awk 'BEGIN{ FS="[ =]+" }{ print "-d " $2 }') "$@" + parse_and_export "d" "MYSQL_DATABASE" "${DATABASE_USER} database name" "$@" + shift $((OPTIND -1)) + ;; + --testunitbase*) + # Transform long options to short ones + arg=$1; shift + # shellcheck disable=SC2046 + set -- $(echo "${arg}" \ + | awk 'BEGIN{ FS="[ =]+" }{ print "-u " $2 }') "$@" + test_checked=1 + ck_args="--connection=test" + parse_and_export "u" "TEST_DATABASE_NAME" "${MYSQL_USER} database name" "$@" + shift $((OPTIND -1)) + ;; + *) echo "Invalid parameter: ${BASH_SOURCE[0]} $1" && exit 1;; esac -shift; done -#; import identities -[ ! -z $DATABASE_NAME ] && [ ! -z $DATABASE_USER ] && [ ! -z $DATABASE_PASSWORD ] && [ ! -z $MYSQL_SERVICE_HOST ] && [ ! -z $MYSQL_SERVICE_PORT ] || (echo -e "${red}ERROR : Missing Database VARIABLES.${nc}\n" && export -p | grep " DATABASE\| MYSQL"); -[ ! -z $TEST_DATABASE_NAME ] && [ ! -z $TEST_DATABASE_USER ] && [ ! -z $TEST_DATABASE_PASSWORD ] && [ ! -z $TEST_MYSQL_SERVICE_HOST ] && [ ! -z $TEST_MYSQL_SERVICE_PORT ] || (echo -e "${red}ERROR : Missing Test Database VARIABLES.${nc}\n" && export -p | grep "TEST_DATABASE\|TEST_MYSQL"); -if [[ -f $identities ]]; then source ./Scripts/cp_bkp_old.sh . $identities ${identities}.old; fi +shift; #echo "$@"; +done # configure user application database and eventually alter user database access -[ -z $dbfile ] && [ $fix_socket == "-N" ] && [ -f app/Config/database.php ] || config_app_checked="-Y" -shell_prompt "./Scripts/config_app_database.sh ${dbfile} ${fix_socket}" "${cyan}Setup ${dbfile} connection and socket\n${nc}" $config_app_checked -if [[ $import_identities -eq 1 ]]; then - echo -e "Importing the mysql ${cyan}${DATABASE_USER}${nc} and ${cyan}${TEST_DATABASE_USER}${nc} users SQL identities..." - echo -e "\r${red}WARNING: You will modify SQL ${DATABASE_USER} password !${nc}" && - parse_sql_password "$new_pass" "set_DATABASE_PASSWORD" "new ${DATABASE_USER}" && - echo -e "\r${red}WARNING: You will modify SQL ${TEST_DATABASE_USER} password !${nc}" && - parse_sql_password "$new_test_pass" "set_TEST_DATABASE_PASSWORD" "new ${TEST_DATABASE_USER}" && - #; $identities file contents - echo -e "# WARNING: You will alter SQL users access rights\r - # set_DATABASE_PASSWORD - alter user '${DATABASE_USER}'@'${MYSQL_SERVICE_HOST}' identified by '${set_DATABASE_PASSWORD}';\r - - use mysql;\r - select * from user where user = '${DATABASE_USER}';\r - grant all on ${DATABASE_NAME}.* to '${DATABASE_USER}'@'${MYSQL_SERVICE_HOST}';\r - create database if not exists ${DATABASE_NAME};\r - - create user if not exists '${TEST_DATABASE_USER}'@'${TEST_MYSQL_SERVICE_HOST}';\r - # set_TEST_DATABASE_PASSWORD - alter user '${TEST_DATABASE_USER}'@'${TEST_MYSQL_SERVICE_HOST}' identified by '${set_TEST_DATABASE_PASSWORD}';\r - - use mysql;\r - select * from user where user = '${TEST_DATABASE_USER}';\r - grant all on ${TEST_DATABASE_NAME}.* to '${TEST_DATABASE_USER}'@'${TEST_MYSQL_SERVICE_HOST}';\r - create database if not exists ${TEST_DATABASE_NAME};\r - " > $identities - ${sql_source} sh -c "echo \"source ${identities}\" | mysql -u $DATABASE_USER --password=$DATABASE_PASSWORD --connect-expired-password" - export DATABASE_PASSWORD=$set_DATABASE_PASSWORD - export TEST_DATABASE_PASSWORD=$set_TEST_DATABASE_PASSWORD -fi -if [[ $update_checked -eq 1 ]]; then - show_password_status "$DATABASE_USER" "$DATABASE_PASSWORD" "is updating cake schemas" - #; update plugins and dependencies - source ./Scripts/composer.sh "-o" - #; cakephp shell - if [ ! -f app/Config/Schema/schema.php ]; then - echo "Generating database schema 'cake schema generate'" - ./lib/Cake/Console/cake schema generate -f s +# shellcheck disable=SC2154 +shell_prompt "$TOPDIR/Scripts/config_app_database.sh ${dbfile} ${schemafile} ${sockfile} ${docker}" \ +"${cyan}Setup ${dbfile} connection and socket\n${nc}" "$config_app_checked" +if [[ $initialize_databases -eq 1 ]]; then + #; ---------------------------------- set MYSQL_ROOT_PASSWORD + export set_DATABASE_PASSWORD=${set_DATABASE_PASSWORD:-$MYSQL_ROOT_PASSWORD} + # shellcheck disable=SC2154 + log_warning_msg "${red}WARNING: You will modify SQL ${DATABASE_USER} password !${nc}" + prompt="-Y" + if [ -z "${set_DATABASE_PASSWORD}" ]; then + # shellcheck disable=SC2154 + log_warning_msg "${orange}WARNING: Using blank password for ${DATABASE_USER} !!${nc}" + prompt=${DEBIAN_FRONTEND:-''} + fi + if [ $authentication_plugin = "ed25519" ]; then + identifiedby="IDENTIFIED VIA ed25519 USING '${set_DATABASE_PASSWORD}'" + else + identifiedby="identified by '${set_DATABASE_PASSWORD}'" + fi + # ALTER USER is MariaDB 10.2 and above waiting for ARM binary + # "-e \"alter user '${DATABASE_USER}'@'${mysql_host}' ${identifiedby};\"" \ + args=(\ +"-e \"select version();\"" \ +"-e \"use mysql;\"" \ +"-e \"create user if not exists '${DATABASE_USER}'@'${mysql_host}' ${identifiedby};\"" \ +"-e \"SET PASSWORD FOR '${DATABASE_USER}'@'${mysql_host}' = PASSWORD('${set_DATABASE_PASSWORD}');\"" \ +"-e \"grant all PRIVILEGES on *.* to '${DATABASE_USER}'@'${mysql_host}' WITH GRANT OPTION;\"" \ +"-e \"flush PRIVILEGES;\"" \ +"-e \"create database if not exists ${MYSQL_DATABASE} default character set='utf8' default collate='utf8_bin';\"" \ +"-e \"create database if not exists ${TEST_DATABASE_NAME};\"" \ +"-e \"create database if not exists ${TEST_DATABASE_NAME}_2;\"" \ +"-e \"create database if not exists ${TEST_DATABASE_NAME}_3;\"" \ +"-e \"select plugin from user where user='${DATABASE_USER}';\"" \ +"-e \"show databases;\"" \ +"") + # enable failed-login tracking, such that three consecutive incorrect passwords cause temporary account locking for two days: + # "-e \"FAILED_LOGIN_ATTEMPTS 3 PASSWORD_LOCK_TIME 2;\"" + slogger -st "$0" "Forked script to keep hidden table user secrets..." + password="" + user="${DATABASE_USER}" + if [ -n "${MYSQL_ROOT_PASSWORD:-}" ]; then + password="--password=${MYSQL_ROOT_PASSWORD}" + user="root" fi - if [ ! -f app/Config/Schema/sessions.php ]; then - echo "Generating default Sessions table" - ./lib/Cake/Console/cake schema create Sessions -y + shell_prompt "${sql_connect} ${sql_connect_host} -u ${user} ${password} \ + ${args[*]} >> $LOG 2>&1" "Import default identities" "$prompt"\ + && export MYSQL_ROOT_PASSWORD=${set_DATABASE_PASSWORD} + #; ---------------------------------- set MYSQL_PASSWORD + slogger -st "$0" "\r${red}WARNING: You will modify SQL ${MYSQL_USER} password !${nc}" + export set_MYSQL_PASSWORD=${set_MYSQL_PASSWORD:-$MYSQL_PASSWORD} + if [ -z "${set_MYSQL_PASSWORD}" ]; then + slogger -st "$0" "\r${orange}WARNING: Using blank password for ${MYSQL_USER} !!${nc}" + prompt=${DEBIAN_FRONTEND:-''} fi - echo "Migrating database 'cake schema update' ..." - ./lib/Cake/Console/cake schema update --file myschema.php -y + if [ $authentication_plugin = "ed25519" ]; then + identifiedby="IDENTIFIED VIA ed25519 USING '${set_MYSQL_PASSWORD}'" + else + identifiedby="identified by '${set_MYSQL_PASSWORD}'" + fi + # ALTER USER is MariaDB 10.2 and above waiting for ARM binary + # "-e \"alter user '${MYSQL_USER}'@'${mysql_host}' ${identifiedby};\"" \ + args=(\ +"-e \"use mysql;\"" \ +"-e \"create user if not exists '${MYSQL_USER}'@'${mysql_host}' ${identifiedby};\"" \ +"-e \"SET PASSWORD FOR '${MYSQL_USER}'@'${mysql_host}' = PASSWORD('${set_MYSQL_PASSWORD}');\"" \ +"-e \"grant all PRIVILEGES on ${MYSQL_DATABASE}.* to '${MYSQL_USER}'@'${mysql_host}';\"" \ +"-e \"grant all PRIVILEGES on ${TEST_DATABASE_NAME}.* to '${MYSQL_USER}'@'${mysql_host}';\"" \ +"-e \"grant all PRIVILEGES on ${TEST_DATABASE_NAME}_2.* to '${MYSQL_USER}'@'${mysql_host}';\"" \ +"-e \"grant all PRIVILEGES on ${TEST_DATABASE_NAME}_3.* to '${MYSQL_USER}'@'${mysql_host}';\"" \ +"-e \"flush PRIVILEGES;\"" \ +"-e \"select plugin from user where user='${MYSQL_USER}';\"") + # enable failed-login tracking, such that three consecutive incorrect passwords cause temporary account locking for two days: + # "-e \"FAILED_LOGIN_ATTEMPTS 3 PASSWORD_LOCK_TIME 2;\"" + shell_prompt "${sql_connect} ${sql_connect_host} -u ${user} ${password} \ + ${args[*]} >> $LOG 2>&1" "Import test identities" "$prompt" \ + && export MYSQL_PASSWORD=${set_MYSQL_PASSWORD} + check_log "$LOG" +fi +if [[ $update_checked -eq 1 ]]; then + bash -c "./Scripts/start_daemon.sh ${travis} ${docker} update ${ck_args}" +fi +if [[ $test_checked -eq 1 ]]; then + echo "GOAL $travis $docker $test_args" + bash -c "./Scripts/bootstrap.sh ${travis} ${docker} test ${test_args}" + check_log "$LOG" fi diff --git a/mysqldb/Dockerfile.armhf b/mysqldb/Dockerfile.armhf new file mode 100644 index 000000000..ddf70a29a --- /dev/null +++ b/mysqldb/Dockerfile.armhf @@ -0,0 +1,62 @@ +ARG SECONDARY_HUB +FROM ${SECONDARY_HUB:-betothreeprod/mariadb-raspberrypi3} + +# When using volumes (-v flags) permissions issues can arise +# between the host OS and the container, we avoid this issue +# by allowing you to specify the user PUID and group PGID. +# $ id $USER +ARG PUID +ENV PUID ${PUID:-0} +ARG PGID +ENV PGID ${PGID:-0} +ARG MYSQL_ROOT_PASSWORD +ENV MYSQL_ROOT_PASSWORD ${MYSQL_ROOT_PASSWORD:-'mariadb'} +ARG MYSQL_HOST +ENV MYSQL_HOST ${MYSQL_HOST:-'localhost'} +ENV TZ ${TZ:-'Europe/Paris'} +# Optional +ARG MYSQL_DATABASE +ENV MYSQL_DATABASE ${MYSQL_DATABASE:-'aria_db'} +# Optional +ARG MYSQL_USER +ENV MYSQL_USER ${MYSQL_USER:-'maria'} +# Optional +ARG MYSQL_PASSWORD +ENV MYSQL_PASSWORD ${MYSQL_PASSWORD:-'maria-abc'} +# Optional +ARG MYSQL_BIND_ADDRESS +ENV MYSQL_BIND_ADDRESS ${MYSQL_BIND_ADDRESS:-0.0.0.0} + +# The MariaDB/MySQL tools read configuration files in the following order: +# 1. "/etc/mysql/my.cnf" to set global defaults, +# 2. "/etc/mysql/conf.d/my.cnf" to set server options. +# 3. "~/.my.cnf" User +COPY conf.d/my.cnf /etc/mysql/conf.d/my.cnf +RUN sed -i.bind "/bind-address/s/=.*$/= ${MYSQL_BIND_ADDRESS}/" /etc/mysql/conf.d/my.cnf +RUN sed -i.user "/user/s/=.*$/= ${USER}/" /etc/mysql/conf.d/my.cnf + +RUN apt update && apt install -y \ + expect \ + # auth_ed25519 support package + libmariadbclient18 \ + #\ + && echo "**** cleanup ****" && \ + rm -rf \ + /tmp/* \ + /var/lib/apt/lists/* \ + /var/tmp/* + +COPY mysql_secure_shell . +RUN chmod 1755 mysql_secure_shell +RUN ./mysql_secure_shell + +RUN echo "***** Fix PASSWORD, PRIVILEGES and CREATE ${MYSQL_USER}..." \ + && echo "GRANT ALL PRIVILEGES ON *.* TO 'root'@'% WITH GRANT OPTION;" | tee -a p.sql \ + && echo "CREATE USER '${MYSQL_USER}'@'%' IDENTIFIED BY '${MYSQL_PASSWORD}';" | tee -a p.sql \ + && echo "FLUSH PRIVILEGES;" | tee -a p.sql \ + && mkdir -p /config/initdb.d/ && mv p.sql /config/initdb.d/patch.sql + +COPY mariadb.ans . +RUN cat mariadb.ans + +VOLUME /var/run/mysqld diff --git a/mysqldb/Dockerfile.template b/mysqldb/Dockerfile.template new file mode 100644 index 000000000..93f95931f --- /dev/null +++ b/mysqldb/Dockerfile.template @@ -0,0 +1,62 @@ +ARG SECONDARY_HUB +FROM ${SECONDARY_HUB:-linuxserver/mariadb} + +# When using volumes (-v flags) permissions issues can arise +# between the host OS and the container, we avoid this issue +# by allowing you to specify the user PUID and group PGID. +# $ id $USER +ARG PUID +ENV PUID ${PUID:-0} +ARG PGID +ENV PGID ${PGID:-0} +ARG MYSQL_ROOT_PASSWORD +ENV MYSQL_ROOT_PASSWORD ${MYSQL_ROOT_PASSWORD:-'mariadb'} +ARG MYSQL_HOST +ENV MYSQL_HOST ${MYSQL_HOST:-'localhost'} +ENV TZ ${TZ:-'Europe/Paris'} +# Optional +ARG MYSQL_DATABASE +ENV MYSQL_DATABASE ${MYSQL_DATABASE:-'aria_db'} +# Optional +ARG MYSQL_USER +ENV MYSQL_USER ${MYSQL_USER:-'maria'} +# Optional +ARG MYSQL_PASSWORD +ENV MYSQL_PASSWORD ${MYSQL_PASSWORD:-'maria-abc'} +# Optional +ARG MYSQL_BIND_ADDRESS +ENV MYSQL_BIND_ADDRESS ${MYSQL_BIND_ADDRESS:-0.0.0.0} + +# The MariaDB/MySQL tools read configuration files in the following order: +# 1. "/etc/mysql/my.cnf" to set global defaults, +# 2. "/etc/mysql/conf.d/my.cnf" to set server options. +# 3. "~/.my.cnf" User +COPY conf.d/my.cnf /etc/mysql/conf.d/my.cnf +RUN sed -i.bind "/bind-address/s/=.*$/= ${MYSQL_BIND_ADDRESS}/" /etc/mysql/conf.d/my.cnf +RUN sed -i.user "/user/s/=.*$/= ${USER}/" /etc/mysql/conf.d/my.cnf + +RUN apt update && apt install -y \ + expect \ + # auth_ed25519 support package + libmariadbclient18 \ + #\ + && echo "**** cleanup ****" && \ + rm -rf \ + /tmp/* \ + /var/lib/apt/lists/* \ + /var/tmp/* + +COPY mysql_secure_shell . +RUN chmod 1755 mysql_secure_shell +RUN ./mysql_secure_shell + +RUN echo "***** Fix PASSWORD, PRIVILEGES and CREATE ${MYSQL_USER}..." \ + && echo "GRANT ALL PRIVILEGES ON *.* TO 'root'@'% WITH GRANT OPTION;" | tee -a p.sql \ + && echo "CREATE USER '${MYSQL_USER}'@'%' IDENTIFIED BY '${MYSQL_PASSWORD}';" | tee -a p.sql \ + && echo "FLUSH PRIVILEGES;" | tee -a p.sql \ + && mkdir -p /config/initdb.d/ && mv p.sql /config/initdb.d/patch.sql + +COPY mariadb.ans . +RUN cat mariadb.ans + +VOLUME /var/run/mysqld diff --git a/mysqldb/Dockerfile.x86_64 b/mysqldb/Dockerfile.x86_64 new file mode 100644 index 000000000..5a4534870 --- /dev/null +++ b/mysqldb/Dockerfile.x86_64 @@ -0,0 +1,62 @@ +ARG SECONDARY_HUB +FROM ${SECONDARY_HUB:-betothreeprod/mariadb-intel-nuc} + +# When using volumes (-v flags) permissions issues can arise +# between the host OS and the container, we avoid this issue +# by allowing you to specify the user PUID and group PGID. +# $ id $USER +ARG PUID +ENV PUID ${PUID:-0} +ARG PGID +ENV PGID ${PGID:-0} +ARG MYSQL_ROOT_PASSWORD +ENV MYSQL_ROOT_PASSWORD ${MYSQL_ROOT_PASSWORD:-'mariadb'} +ARG MYSQL_HOST +ENV MYSQL_HOST ${MYSQL_HOST:-'localhost'} +ENV TZ ${TZ:-'Europe/Paris'} +# Optional +ARG MYSQL_DATABASE +ENV MYSQL_DATABASE ${MYSQL_DATABASE:-'aria_db'} +# Optional +ARG MYSQL_USER +ENV MYSQL_USER ${MYSQL_USER:-'maria'} +# Optional +ARG MYSQL_PASSWORD +ENV MYSQL_PASSWORD ${MYSQL_PASSWORD:-'maria-abc'} +# Optional +ARG MYSQL_BIND_ADDRESS +ENV MYSQL_BIND_ADDRESS ${MYSQL_BIND_ADDRESS:-0.0.0.0} + +# The MariaDB/MySQL tools read configuration files in the following order: +# 1. "/etc/mysql/my.cnf" to set global defaults, +# 2. "/etc/mysql/conf.d/my.cnf" to set server options. +# 3. "~/.my.cnf" User +COPY conf.d/my.cnf /etc/mysql/conf.d/my.cnf +RUN sed -i.bind "/bind-address/s/=.*$/= ${MYSQL_BIND_ADDRESS}/" /etc/mysql/conf.d/my.cnf +RUN sed -i.user "/user/s/=.*$/= ${USER}/" /etc/mysql/conf.d/my.cnf + +RUN apt update && apt install -y \ + expect \ + # auth_ed25519 support package + libmariadbclient18 \ + #\ + && echo "**** cleanup ****" && \ + rm -rf \ + /tmp/* \ + /var/lib/apt/lists/* \ + /var/tmp/* + +COPY mysql_secure_shell . +RUN chmod 1755 mysql_secure_shell +RUN ./mysql_secure_shell + +RUN echo "***** Fix PASSWORD, PRIVILEGES and CREATE ${MYSQL_USER}..." \ + && echo "GRANT ALL PRIVILEGES ON *.* TO 'root'@'% WITH GRANT OPTION;" | tee -a p.sql \ + && echo "CREATE USER '${MYSQL_USER}'@'%' IDENTIFIED BY '${MYSQL_PASSWORD}';" | tee -a p.sql \ + && echo "FLUSH PRIVILEGES;" | tee -a p.sql \ + && mkdir -p /config/initdb.d/ && mv p.sql /config/initdb.d/patch.sql + +COPY mariadb.ans . +RUN cat mariadb.ans + +VOLUME /var/run/mysqld diff --git a/mysqldb/README.md b/mysqldb/README.md new file mode 100644 index 000000000..315d06941 --- /dev/null +++ b/mysqldb/README.md @@ -0,0 +1,78 @@ +# [betothreeprod/mariadb](https://github.com/b23prodtm/acake2php/tree/development/mysqldb) + +The architectures supported by this image are: + +| Architecture | repo | +| :----: | --- | +| x86-64 | [betothreeprod/mariadb-intel-nuc](https://hub.docker.com/r/betothreeprod/mariadb-intel-nuc) | +| arm64 | betothreeprod/mariadb-raspberrypi3-64 | +| armhf | [betothreeprod/mariadb-raspberrypi3](https://hub.docker.com/r/betothreeprod/mariadb-raspberrypi3) | + + +## Usage + +Here are some example snippets to help you get started creating a container. + +### docker + +``` +docker create \ + --name=mariadb \ + -e PUID=UID \ + -e PGID=GUID \ + -e MYSQL_ROOT_PASSWORD=ROOT_ACCESS_PASSWORD \ + -e TZ=Europe/London \ + -e MYSQL_DATABASE=USER_DB_NAME \ + -e MYSQL_USER=MYSQL_USER \ + -e MYSQL_PASSWORD=DATABASE_PASSWORD \ + -e MYSQL_HOST=EXTERNAL_IP_ADDRESS `#optional` \ + -e REMOTE_SQL=http://URL1/your.sql,https://URL2/your.sql `#optional` \ + -p 3306:3306 \ + -v path_to_data:/config \ + --restart unless-stopped \ + linuxserver/mariadb +``` + + +### docker-compose + +Compatible with docker-compose v2 schemas. + +``` +--- +version: "2" +services: + mariadb: + image: betothreeprod/mariadb-%%BALENA_MACHINE_NAME%% + container_name: mariadb + environment: + - PUID=UID + - PGID=GUID + - MYSQL_ROOT_PASSWORD=ROOT_ACCESS_PASSWORD + - TZ=Europe/London + - MYSQL_DATABASE=USER_DB_NAME + - MYSQL_USER=MYSQL_USER + - MYSQL_PASSWORD=DATABASE_PASSWORD + - MYSQL_HOST=EXTERNAL_IP_ADDRESS #optional + - REMOTE_SQL=http://URL1/your.sql,https://URL2/your.sql #optional + volumes: + - path_to_data:/config + ports: + - 3306:3306 + restart: unless-stopped +``` + +> %%BALENA_MACHINE_NAME%% it's the template variable for the host system name from [Balena OS reference](https://www.balena.io/docs/reference/base-images/base-images-ref/). +## User / Group Identifiers + +When using volumes (`-v` flags) permissions issues can arise between the host OS and the container, we avoid this issue by allowing you to specify the user `PUID` and group `PGID`. + +Ensure any volume directories on the host are owned by the same user you specify and any permissions issues will vanish like magic. + +In this instance `PUID=UID` and `PGID=GUID`, to find it, you use `id user` as below: + +``` + $ id $USER + uid=1000(thedockeruser) gid=1000(thedockergroup) groups=1000(thedockergroup) +``` +If docker's run by `root(0)`, it's the default behaviour, `PUID=0` and `GUID=0`. diff --git a/mysqldb/common.env b/mysqldb/common.env new file mode 120000 index 000000000..cf1366dd2 --- /dev/null +++ b/mysqldb/common.env @@ -0,0 +1 @@ +/Users/wwwb23prodtminfo/NetBeansProjects/OpenShift/acake2php/common.env \ No newline at end of file diff --git a/mysqldb/conf.d/my.cnf b/mysqldb/conf.d/my.cnf new file mode 100644 index 000000000..aa746e8e7 --- /dev/null +++ b/mysqldb/conf.d/my.cnf @@ -0,0 +1,20 @@ +[mariadb] +### Optional migrate-database.sh --enable-authentication-plugin +### CREATE USER username@hostname IDENTIFIED VIA ed25519 USING PASSWORD('secret'); +plugin_load_add = auth_ed25519 +#unix_socket = OFF + +[mysqld] +default_authentication_plugin=client_ed25519 +max_allowed_packet = 128M +wait_timeout = 28800 +collation-server = utf8_unicode_ci +init-connect="SET NAMES utf8" +character-set-server = utf8 +# TCP Socket settings (making 127.0.0.1 work) +port = 3306 +bind-address = 0.0.0.0 +# Unix socket settings (making localhost work) +#user = root +#pid-file = /var/run/mysqld/mysqld.pid +#socket = /var/run/mysqld/mysqld.sock diff --git a/mysqldb/curl.sh b/mysqldb/curl.sh new file mode 100755 index 000000000..f856e1715 --- /dev/null +++ b/mysqldb/curl.sh @@ -0,0 +1,22 @@ +#!/usr/bin/env bash +# Save the path to THIS script (before we go changing dirs) +TOPDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +# The top of our source tree is the parent of this scripts dir +TOPDIR+="deployment/images/mariadb" +mkdir -p $TOPDIR +cd $TOPDIR || exit 1 +MARIADB_MAJOR=${MARIADB_MAJOR:-10.4} +curl -L "https://raw.githubusercontent.com/docker-library/mariadb/master/$MARIADB_MAJOR/docker-entrypoint.sh" -o docker-entrypoint.sh +curl -L "https://raw.githubusercontent.com/docker-library/mariadb/master/$MARIADB_MAJOR/Dockerfile" -o Dockerfile.template +# patch Dockerfile with balenalib and cross-compilers +# shellcheck disable=SC1004 +sed -i.orig -E -e 's/FROM\ ubuntu:bionic/FROM\ balenalib\/%%BALENA_MACHINE_NAME%%-ubuntu:bionic-build\ +\#\ RUN\ [\ \"cross-build-start\"\ ]\ +ARG\ DEBIAN_FRONTEND=noninteractive/' \ +-e 's/(^CMD.*)/\#\ RUN\ [\ \"cross-build-end\"\ ]\ +\1/' \ +Dockerfile.template +MARIADB_VERSION=$(awk '/ENV MARIADB_VERSION/' < Dockerfile.template | awk 'BEGIN{ FS=" " }{ print $3 }' ) +printf "Mariadb: %s\nImage: %s" "$MARIADB_MAJOR" "$MARIADB_VERSION" | tee VERSION +printf "[Experimental] build of MariaDB for ARM (deployment/images/secondary)" +printf "Find a stable build at lsioarmhf/mariadb." diff --git a/mysqldb/mariadb.ans b/mysqldb/mariadb.ans new file mode 100644 index 000000000..3325e595d --- /dev/null +++ b/mysqldb/mariadb.ans @@ -0,0 +1,28 @@ + *---------------------------* + | MariaDB `mysqld --version`| + *-----------------------\ /-* + V + +[38;5;46;48;5;235m + ********#**** + **@@@@((@@@@(@@@* + **@@@@@/*%@@/*&/@* + *@@@@@@@@@@@@@@** + **@@@@@@@@@@@@** + **@@@@@@@@@@@@@* + **@@@@@@@@@@@@@* + **@@@@@@@@@@@@@@@* + **&@@@@@@@@@@@@@@@@* + **%@@@@@@@@@@@@@@@@@@@(* + *****@@@@@@@@@@@@@@@@@@@@@@@@@@* + ***@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*. + ***@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@** + **@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@** + */@@@@@@@@@@@@@@@@@@@@@@@@@@@@*@@@@@@@@@@@@@&*** + *@@@@@@@@@@@@@@@@@@@@@@@@@@@@@**@@@@@@@@*@@#*@@** + **@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@**@@@@@@@/****@@@@@** + *#@@@@@@@@@@@@@@@@** ******@@@@@@@** ********** + ,,**@@@@@@@@@@** **@@@@@@** + *@@@@@@@/*** *%@@@@*** + ****** + diff --git a/mysqldb/mysql_secure_shell b/mysqldb/mysql_secure_shell new file mode 100644 index 000000000..7738e60d0 --- /dev/null +++ b/mysqldb/mysql_secure_shell @@ -0,0 +1,31 @@ +#!/usr/bin/env bash +#https://gist.github.com/Mins/4602864#gistcomment-3118692 +[ ! -e /usr/bin/expect ] && apt-get update && apt-get -y install expect; +[ -z ${MYSQL_ROOT_PASSWORD:-''} ] \ +&& printf "MYSQL_ALLOW_EMPTY_PASSWORD=%s\n\ + !!! An empty password was detected !!!" ${MYSQL_ALLOW_EMPTY_PASSWORD} +SECURE_MYSQL=$(expect -c " + +set timeout 10 +spawn mysql_secure_installation + +expect \"Enter current password for root (enter for none): \" +send \"\r\" +expect \"Switch to unix_socket authentication \[Y/n\] \" +send \"y\r\" +expect \"Change the root password? \[Y/n\] \" +send \"y\r\" +expect \"New password: \" +send \"${MYSQL_ROOT_PASSWORD:-''}\r\" +expect \"Re-enter new password: \" +send \"${MYSQL_ROOT_PASSWORD:-''}\r\" +expect \"Remove anonymous users? \[Y/n\] \" +send \"y\r\" +expect \"Disallow root login remotely? \[Y/n\] \" +send \"n\r\" +expect \"Remove test database and access to it? \[Y/n\] \" +send \"n\r\" +expect \"Reload privilege tables now? \[Y/n\] \" +send \"y\r\" +expect eof +") diff --git a/openshift/templates/acake2php-data-persistentvolumeclaim.json b/openshift/templates/acake2php-data-persistentvolumeclaim.json new file mode 100644 index 000000000..7afdb6e75 --- /dev/null +++ b/openshift/templates/acake2php-data-persistentvolumeclaim.json @@ -0,0 +1,22 @@ +{ + "kind": "PersistentVolumeClaim", + "apiVersion": "v1", + "metadata": { + "name": "acake2php-data", + "creationTimestamp": null, + "labels": { + "io.kompose.service": "acake2php-data" + } + }, + "spec": { + "accessModes": [ + "ReadWriteOnce" + ], + "resources": { + "requests": { + "storage": "100Mi" + } + } + }, + "status": {} +} \ No newline at end of file diff --git a/openshift/templates/acake2php-db-data-persistentvolumeclaim.json b/openshift/templates/acake2php-db-data-persistentvolumeclaim.json new file mode 100644 index 000000000..d87fc1d4a --- /dev/null +++ b/openshift/templates/acake2php-db-data-persistentvolumeclaim.json @@ -0,0 +1,22 @@ +{ + "kind": "PersistentVolumeClaim", + "apiVersion": "v1", + "metadata": { + "name": "acake2php-db-data", + "creationTimestamp": null, + "labels": { + "io.kompose.service": "acake2php-db-data" + } + }, + "spec": { + "accessModes": [ + "ReadWriteOnce" + ], + "resources": { + "requests": { + "storage": "100Mi" + } + } + }, + "status": {} +} \ No newline at end of file diff --git a/openshift/templates/acake2php-db-socket-persistentvolumeclaim.json b/openshift/templates/acake2php-db-socket-persistentvolumeclaim.json new file mode 100644 index 000000000..bf4ad583b --- /dev/null +++ b/openshift/templates/acake2php-db-socket-persistentvolumeclaim.json @@ -0,0 +1,22 @@ +{ + "kind": "PersistentVolumeClaim", + "apiVersion": "v1", + "metadata": { + "name": "acake2php-db-socket", + "creationTimestamp": null, + "labels": { + "io.kompose.service": "acake2php-db-socket" + } + }, + "spec": { + "accessModes": [ + "ReadWriteOnce" + ], + "resources": { + "requests": { + "storage": "100Mi" + } + } + }, + "status": {} +} \ No newline at end of file diff --git a/openshift/templates/acake2php-deployment.json b/openshift/templates/acake2php-deployment.json new file mode 100644 index 000000000..e7672b0e6 --- /dev/null +++ b/openshift/templates/acake2php-deployment.json @@ -0,0 +1,164 @@ +{ + "apiVersion": "apps/v1", + "kind": "Deployment", + "metadata": { + "annotations": { + "io.balena.features.dbus": "1", + "kompose.cmd": "kompose convert --build build-config --controller deployment -o openshift/templates/ -f docker-compose.x86_64 -j", + "kompose.version": "1.21.0 (992df58d8)" + }, + "creationTimestamp": null, + "labels": { + "io.kompose.service": "acake2php" + }, + "name": "acake2php" + }, + "spec": { + "replicas": 1, + "selector": { + "matchLabels": { + "io.kompose.service": "acake2php" + } + }, + "strategy": { + "type": "Recreate" + }, + "template": { + "metadata": { + "annotations": { + "io.balena.features.dbus": "1", + "kompose.cmd": "kompose convert --build build-config --controller deployment -o openshift/templates/ -f docker-compose.x86_64 -j", + "kompose.version": "1.21.0 (992df58d8)" + }, + "creationTimestamp": null, + "labels": { + "io.kompose.network/acake2php_cake": "true", + "io.kompose.service": "acake2php" + } + }, + "spec": { + "containers": [ + { + "env": [ + { + "name": "BALENA_MACHINE_NAME", + "value": "raspberrypi3" + }, + { + "name": "BALENA_PROJECTS", + "value": "(. ./mysqldb ./deployment/images/node-php7 ./deployment/images/apache-php7) #(submodule deployment/images/primary" + }, + { + "name": "BALENA_PROJECTS_FLAGS", + "value": "(IMG_TAG PRIMARY_HUB SECONDARY_HUB)" + }, + { + "name": "CAKEPHP_DEBUG_LEVEL", + "value": "1" + }, + { + "name": "CAKEPHP_SECURITY_CIPHER_SEED", + "value": "01234" + }, + { + "name": "CAKEPHP_SECURITY_SALT", + "value": "Word" + }, + { + "name": "COLLECT_COVERAGE", + "value": "false" + }, + { + "name": "DATABASE_USER", + "value": "root" + }, + { + "name": "DKR_ARCH", + "value": "armhf" + }, + { + "name": "HTTPD_LISTEN", + "value": "*:80" + }, + { + "name": "IMG_TAG", + "value": "latest" + }, + { + "name": "MYPHPCMS_DIR", + "value": "app/webroot/php-cms" + }, + { + "name": "MYPHPCMS_LOG", + "value": "app/tmp/logs" + }, + { + "name": "PGID", + "value": "1000" + }, + { + "name": "PRIMARY_HUB", + "value": "betothreeprod/apache-php7" + }, + { + "name": "PUID", + "value": "1000" + }, + { + "name": "SECONDARY_HUB", + "value": "betothreeprod/mariadb-raspberrypi3" + }, + { + "name": "SERVER_NAME", + "value": "acake2php.local" + }, + { + "name": "TZ", + "value": "Europe/Paris" + } + ], + "image": "betothreeprod/acake2php-intel-nuc", + "imagePullPolicy": "", + "name": "acake2php", + "ports": [ + { + "containerPort": 80 + }, + { + "containerPort": 443 + } + ], + "resources": {}, + "volumeMounts": [ + { + "mountPath": "/var/www", + "name": "acake2php-data" + }, + { + "mountPath": "/var/run/mysqld", + "name": "acake2php-db-socket" + } + ] + } + ], + "restartPolicy": "Always", + "serviceAccountName": "", + "volumes": [ + { + "name": "acake2php-data", + "persistentVolumeClaim": { + "claimName": "acake2php-data" + } + }, + { + "name": "acake2php-db-socket", + "persistentVolumeClaim": { + "claimName": "acake2php-db-socket" + } + } + ] + } + } + }, + "status": {} +} \ No newline at end of file diff --git a/openshift/templates/acake2php-deploymentconfig.json b/openshift/templates/acake2php-deploymentconfig.json new file mode 100644 index 000000000..f99e5e42c --- /dev/null +++ b/openshift/templates/acake2php-deploymentconfig.json @@ -0,0 +1,175 @@ +{ + "kind": "DeploymentConfig", + "apiVersion": "v1", + "metadata": { + "name": "acake2php", + "creationTimestamp": null, + "labels": { + "io.kompose.service": "acake2php" + }, + "annotations": { + "io.balena.features.dbus": "1", + "kompose.cmd": "kompose convert -f docker-compose.x86_64 --provider openshift --out openshift/templates/ -j", + "kompose.version": "1.21.0 (992df58d8)" + } + }, + "spec": { + "strategy": { + "type": "Recreate", + "resources": {} + }, + "triggers": [ + { + "type": "ConfigChange" + }, + { + "type": "ImageChange", + "imageChangeParams": { + "automatic": true, + "containerNames": [ + "acake2php" + ], + "from": { + "kind": "ImageStreamTag", + "name": "acake2php:latest" + } + } + } + ], + "replicas": 1, + "test": false, + "selector": { + "io.kompose.service": "acake2php" + }, + "template": { + "metadata": { + "creationTimestamp": null, + "labels": { + "io.kompose.network/acake2php_cake": "true", + "io.kompose.service": "acake2php" + } + }, + "spec": { + "volumes": [ + { + "name": "acake2php-data", + "persistentVolumeClaim": { + "claimName": "acake2php-data" + } + }, + { + "name": "acake2php-db-socket", + "persistentVolumeClaim": { + "claimName": "acake2php-db-socket" + } + } + ], + "containers": [ + { + "name": "acake2php", + "image": " ", + "ports": [ + { + "containerPort": 80 + }, + { + "containerPort": 443 + } + ], + "env": [ + { + "name": "BALENA_MACHINE_NAME", + "value": "raspberrypi3" + }, + { + "name": "BALENA_PROJECTS", + "value": "(. ./mysqldb ./deployment/images/node-php7 ./deployment/images/apache-php7) #(submodule deployment/images/primary" + }, + { + "name": "BALENA_PROJECTS_FLAGS", + "value": "(IMG_TAG PRIMARY_HUB SECONDARY_HUB)" + }, + { + "name": "CAKEPHP_DEBUG_LEVEL", + "value": "1" + }, + { + "name": "CAKEPHP_SECURITY_CIPHER_SEED", + "value": "01234" + }, + { + "name": "CAKEPHP_SECURITY_SALT", + "value": "Word" + }, + { + "name": "COLLECT_COVERAGE", + "value": "false" + }, + { + "name": "DATABASE_USER", + "value": "root" + }, + { + "name": "DKR_ARCH", + "value": "armhf" + }, + { + "name": "HTTPD_LISTEN", + "value": "*:80" + }, + { + "name": "IMG_TAG", + "value": "latest" + }, + { + "name": "MYPHPCMS_DIR", + "value": "app/webroot/php-cms" + }, + { + "name": "MYPHPCMS_LOG", + "value": "app/tmp/logs" + }, + { + "name": "PGID", + "value": "1000" + }, + { + "name": "PRIMARY_HUB", + "value": "betothreeprod/apache-php7" + }, + { + "name": "PUID", + "value": "1000" + }, + { + "name": "SECONDARY_HUB", + "value": "betothreeprod/mariadb-raspberrypi3" + }, + { + "name": "SERVER_NAME", + "value": "acake2php.local" + }, + { + "name": "TZ", + "value": "Europe/Paris" + } + ], + "resources": {}, + "volumeMounts": [ + { + "name": "acake2php-data", + "mountPath": "/var/www" + }, + { + "name": "acake2php-db-socket", + "mountPath": "/var/run/mysqld" + } + ] + } + ], + "restartPolicy": "Always" + } + } + }, + "status": {} +} \ No newline at end of file diff --git a/openshift/templates/acake2php-imagestream.json b/openshift/templates/acake2php-imagestream.json new file mode 100644 index 000000000..387d40e9d --- /dev/null +++ b/openshift/templates/acake2php-imagestream.json @@ -0,0 +1,28 @@ +{ + "kind": "ImageStream", + "apiVersion": "v1", + "metadata": { + "name": "acake2php", + "creationTimestamp": null, + "labels": { + "io.kompose.service": "acake2php" + } + }, + "spec": { + "tags": [ + { + "name": "latest", + "annotations": null, + "from": { + "kind": "DockerImage", + "name": "betothreeprod/acake2php-intel-nuc" + }, + "generation": null, + "importPolicy": {} + } + ] + }, + "status": { + "dockerImageRepository": "" + } +} \ No newline at end of file diff --git a/openshift/templates/acake2php-service.json b/openshift/templates/acake2php-service.json new file mode 100644 index 000000000..268c09a62 --- /dev/null +++ b/openshift/templates/acake2php-service.json @@ -0,0 +1,36 @@ +{ + "kind": "Service", + "apiVersion": "v1", + "metadata": { + "name": "acake2php", + "creationTimestamp": null, + "labels": { + "io.kompose.service": "acake2php" + }, + "annotations": { + "io.balena.features.dbus": "1", + "kompose.cmd": "kompose convert --build build-config --controller deployment -o openshift/templates/ -f docker-compose.x86_64 -j", + "kompose.version": "1.21.0 (992df58d8)" + } + }, + "spec": { + "ports": [ + { + "name": "80", + "port": 80, + "targetPort": 80 + }, + { + "name": "443", + "port": 443, + "targetPort": 443 + } + ], + "selector": { + "io.kompose.service": "acake2php" + } + }, + "status": { + "loadBalancer": {} + } +} \ No newline at end of file diff --git a/openshift/templates/acake2php_cake-networkpolicy.json b/openshift/templates/acake2php_cake-networkpolicy.json new file mode 100644 index 000000000..97c832122 --- /dev/null +++ b/openshift/templates/acake2php_cake-networkpolicy.json @@ -0,0 +1,28 @@ +{ + "kind": "NetworkPolicy", + "apiVersion": "extensions/v1beta1", + "metadata": { + "name": "acake2php_cake", + "creationTimestamp": null + }, + "spec": { + "podSelector": { + "matchLabels": { + "io.kompose.network/acake2php_cake": "true" + } + }, + "ingress": [ + { + "from": [ + { + "podSelector": { + "matchLabels": { + "io.kompose.network/acake2php_cake": "true" + } + } + } + ] + } + ] + } +} \ No newline at end of file diff --git a/openshift/templates/cakephp-mysql-persistent.json b/openshift/templates/cakephp-mysql-persistent.json deleted file mode 100644 index fe87336b4..000000000 --- a/openshift/templates/cakephp-mysql-persistent.json +++ /dev/null @@ -1,588 +0,0 @@ -{ - "kind": "Template", - "apiVersion": "v1", - "metadata": { - "name": "cakephp-mysql-persistent", - "annotations": { - "openshift.io/display-name": "CakePHP + MySQL (Persistent)", - "description": "An example CakePHP application with a MySQL database. For more information about using this template, including OpenShift considerations, see https://github.com/openshift/cakephp-ex/blob/master/README.md.", - "tags": "quickstart,php,cakephp", - "iconClass": "icon-php", - "template.openshift.io/long-description": "This template defines resources needed to develop a CakePHP application, including a build configuration, application deployment configuration, and database deployment configuration.", - "template.openshift.io/provider-display-name": "Red Hat, Inc.", - "template.openshift.io/documentation-url": "https://github.com/openshift/cakephp-ex", - "template.openshift.io/support-url": "https://access.redhat.com" - } - }, - "message": "The following service(s) have been created in your project: ${NAME}, ${DATABASE_SERVICE_NAME}.\n\nFor more information about using this template, including OpenShift considerations, see https://github.com/openshift/cake-ex/blob/master/README.md.", - "labels": { - "template": "cakephp-mysql-persistent" - }, - "objects": [ - { - "kind": "Secret", - "apiVersion": "v1", - "metadata": { - "name": "${NAME}" - }, - "stringData" : { - "database-user" : "${DATABASE_USER}", - "database-password" : "${DATABASE_PASSWORD}", - "cakephp-secret-token" : "${CAKEPHP_SECRET_TOKEN}", - "cakephp-security-salt" : "${CAKEPHP_SECURITY_SALT}", - "cakephp-security-cipher-seed" : "${CAKEPHP_SECURITY_CIPHER_SEED}" - } - }, - { - "kind": "Service", - "apiVersion": "v1", - "metadata": { - "name": "${NAME}", - "annotations": { - "description": "Exposes and load balances the application pods", - "service.alpha.openshift.io/dependencies": "[{\"name\": \"${DATABASE_SERVICE_NAME}\", \"kind\": \"Service\"}]" - } - }, - "spec": { - "ports": [ - { - "name": "web", - "port": 8080, - "targetPort": 8080 - } - ], - "selector": { - "name": "${NAME}" - } - } - }, - { - "kind": "Route", - "apiVersion": "v1", - "metadata": { - "name": "${NAME}", - "annotations": { - "template.openshift.io/expose-uri": "http://{.spec.host}{.spec.path}" - } - }, - "spec": { - "host": "${APPLICATION_DOMAIN}", - "to": { - "kind": "Service", - "name": "${NAME}" - } - } - }, - { - "kind": "ImageStream", - "apiVersion": "v1", - "metadata": { - "name": "${NAME}", - "annotations": { - "description": "Keeps track of changes in the application image" - } - } - }, - { - "kind": "BuildConfig", - "apiVersion": "v1", - "metadata": { - "name": "${NAME}", - "annotations": { - "description": "Defines how to build the application", - "template.alpha.openshift.io/wait-for-ready": "true" - } - }, - "spec": { - "source": { - "type": "Git", - "git": { - "uri": "${SOURCE_REPOSITORY_URL}", - "ref": "${SOURCE_REPOSITORY_REF}" - }, - "contextDir": "${CONTEXT_DIR}" - }, - "strategy": { - "type": "Source", - "sourceStrategy": { - "from": { - "kind": "ImageStreamTag", - "namespace": "${NAMESPACE}", - "name": "php:7.0" - }, - "env": [ - { - "name": "COMPOSER_MIRROR", - "value": "${COMPOSER_MIRROR}" - } - ] - } - }, - "output": { - "to": { - "kind": "ImageStreamTag", - "name": "${NAME}:latest" - } - }, - "triggers": [ - { - "type": "ImageChange" - }, - { - "type": "ConfigChange" - }, - { - "type": "GitHub", - "github": { - "secret": "${GITHUB_WEBHOOK_SECRET}" - } - } - ], - "postCommit": { - "script": "./lib/Cake/Console/cake test app AllTests" - } - } - }, - { - "kind": "DeploymentConfig", - "apiVersion": "v1", - "metadata": { - "name": "${NAME}", - "annotations": { - "description": "Defines how to deploy the application server", - "template.alpha.openshift.io/wait-for-ready": "true" - } - }, - "spec": { - "strategy": { - "type": "Recreate", - "recreateParams": { - "pre": { - "failurePolicy": "Retry", - "execNewPod": { - "command": [ - "./migrate-database.sh" - ], - "containerName": "cakephp-mysql-persistent" - } - } - } - }, - "triggers": [ - { - "type": "ImageChange", - "imageChangeParams": { - "automatic": true, - "containerNames": [ - "cakephp-mysql-persistent" - ], - "from": { - "kind": "ImageStreamTag", - "name": "${NAME}:latest" - } - } - }, - { - "type": "ConfigChange" - } - ], - "replicas": 1, - "selector": { - "name": "${NAME}" - }, - "template": { - "metadata": { - "name": "${NAME}", - "labels": { - "name": "${NAME}" - } - }, - "spec": { - "containers": [ - { - "name": "cakephp-mysql-persistent", - "image": " ", - "ports": [ - { - "containerPort": 8080 - } - ], - "readinessProbe": { - "timeoutSeconds": 3, - "initialDelaySeconds": 3, - "httpGet": { - "path": "/health.php", - "port": 8080 - } - }, - "livenessProbe": { - "timeoutSeconds": 3, - "initialDelaySeconds": 30, - "httpGet": { - "path": "/", - "port": 8080 - } - }, - "env": [ - { - "name": "DATABASE_SERVICE_NAME", - "value": "${DATABASE_SERVICE_NAME}" - }, - { - "name": "DATABASE_ENGINE", - "value": "${DATABASE_ENGINE}" - }, - { - "name": "DATABASE_NAME", - "value": "${DATABASE_NAME}" - }, - { - "name": "DATABASE_USER", - "valueFrom": { - "secretKeyRef" : { - "name" : "${NAME}", - "key" : "database-user" - } - } - }, - { - "name": "DATABASE_PASSWORD", - "valueFrom": { - "secretKeyRef" : { - "name" : "${NAME}", - "key" : "database-password" - } - } - }, - { - "name": "CAKEPHP_SECRET_TOKEN", - "valueFrom": { - "secretKeyRef" : { - "name" : "${NAME}", - "key" : "cakephp-secret-token" - } - } - }, - { - "name": "CAKEPHP_SECURITY_SALT", - "valueFrom": { - "secretKeyRef" : { - "name" : "${NAME}", - "key" : "cakephp-security-salt" - } - } - }, - { - "name": "CAKEPHP_SECURITY_CIPHER_SEED", - "valueFrom": { - "secretKeyRef" : { - "name" : "${NAME}", - "key" : "cakephp-security-cipher-seed" - } - } - }, - { - "name": "OPCACHE_REVALIDATE_FREQ", - "value": "${OPCACHE_REVALIDATE_FREQ}" - } - ], - "resources": { - "limits": { - "memory": "${MEMORY_LIMIT}" - } - } - } - ] - } - } - } - }, - { - "kind": "PersistentVolumeClaim", - "apiVersion": "v1", - "metadata": { - "name": "${DATABASE_SERVICE_NAME}" - }, - "spec": { - "accessModes": [ - "ReadWriteOnce" - ], - "resources": { - "requests": { - "storage": "${VOLUME_CAPACITY}" - } - } - } - }, - { - "kind": "Service", - "apiVersion": "v1", - "metadata": { - "name": "${DATABASE_SERVICE_NAME}", - "annotations": { - "description": "Exposes the database server" - } - }, - "spec": { - "ports": [ - { - "name": "mysql", - "port": 3306, - "targetPort": 3306 - } - ], - "selector": { - "name": "${DATABASE_SERVICE_NAME}" - } - } - }, - { - "kind": "DeploymentConfig", - "apiVersion": "v1", - "metadata": { - "name": "${DATABASE_SERVICE_NAME}", - "annotations": { - "description": "Defines how to deploy the database", - "template.alpha.openshift.io/wait-for-ready": "true" - } - }, - "spec": { - "strategy": { - "type": "Recreate" - }, - "triggers": [ - { - "type": "ImageChange", - "imageChangeParams": { - "automatic": true, - "containerNames": [ - "mysql" - ], - "from": { - "kind": "ImageStreamTag", - "namespace": "${NAMESPACE}", - "name": "mysql:5.7" - } - } - }, - { - "type": "ConfigChange" - } - ], - "replicas": 1, - "selector": { - "name": "${DATABASE_SERVICE_NAME}" - }, - "template": { - "metadata": { - "name": "${DATABASE_SERVICE_NAME}", - "labels": { - "name": "${DATABASE_SERVICE_NAME}" - } - }, - "spec": { - "volumes": [ - { - "name": "${DATABASE_SERVICE_NAME}-data", - "persistentVolumeClaim": { - "claimName": "${DATABASE_SERVICE_NAME}" - } - } - ], - "containers": [ - { - "name": "mysql", - "image": " ", - "ports": [ - { - "containerPort": 3306 - } - ], - "volumeMounts": [ - { - "name": "${DATABASE_SERVICE_NAME}-data", - "mountPath": "/var/lib/mysql/data" - } - ], - "readinessProbe": { - "timeoutSeconds": 1, - "initialDelaySeconds": 5, - "exec": { - "command": [ "/bin/sh", "-i", "-c", "MYSQL_PWD='${DATABASE_PASSWORD}' mysql -h 127.0.0.1 -u ${DATABASE_USER} -D ${DATABASE_NAME} -e 'SELECT 1'" ] - } - }, - "livenessProbe": { - "timeoutSeconds": 1, - "initialDelaySeconds": 30, - "tcpSocket": { - "port": 3306 - } - }, - "env": [ - { - "name": "MYSQL_USER", - "valueFrom": { - "secretKeyRef" : { - "name" : "${NAME}", - "key" : "database-user" - } - } - }, - { - "name": "MYSQL_PASSWORD", - "valueFrom": { - "secretKeyRef" : { - "name" : "${NAME}", - "key" : "database-password" - } - } - }, - { - "name": "MYSQL_DATABASE", - "value": "${DATABASE_NAME}" - } - ], - "resources": { - "limits": { - "memory": "${MEMORY_MYSQL_LIMIT}" - } - } - } - ] - } - } - } - } - ], - "parameters": [ - { - "name": "NAME", - "displayName": "Name", - "description": "The name assigned to all of the frontend objects defined in this template.", - "required": true, - "value": "cakephp-mysql-persistent" - }, - { - "name": "NAMESPACE", - "displayName": "Namespace", - "description": "The OpenShift Namespace where the ImageStream resides.", - "required": true, - "value": "openshift" - }, - { - "name": "MEMORY_LIMIT", - "displayName": "Memory Limit", - "description": "Maximum amount of memory the CakePHP container can use.", - "required": true, - "value": "512Mi" - }, - { - "name": "MEMORY_MYSQL_LIMIT", - "displayName": "Memory Limit (MySQL)", - "description": "Maximum amount of memory the MySQL container can use.", - "required": true, - "value": "512Mi" - }, - { - "name": "VOLUME_CAPACITY", - "displayName": "Volume Capacity", - "description": "Volume space available for data, e.g. 512Mi, 2Gi", - "value": "1Gi", - "required": true - }, - { - "name": "SOURCE_REPOSITORY_URL", - "displayName": "Git Repository URL", - "description": "The URL of the repository with your application source code.", - "required": true, - "value": "https://github.com/openshift/cakephp-ex.git" - }, - { - "name": "SOURCE_REPOSITORY_REF", - "displayName": "Git Reference", - "description": "Set this to a branch name, tag or other ref of your repository if you are not using the default branch." - }, - { - "name": "CONTEXT_DIR", - "displayName": "Context Directory", - "description": "Set this to the relative path to your project if it is not in the root of your repository." - }, - { - "name": "APPLICATION_DOMAIN", - "displayName": "Application Hostname", - "description": "The exposed hostname that will route to the CakePHP service, if left blank a value will be defaulted.", - "value": "" - }, - { - "name": "GITHUB_WEBHOOK_SECRET", - "displayName": "GitHub Webhook Secret", - "description": "Github trigger secret. A difficult to guess string encoded as part of the webhook URL. Not encrypted.", - "generate": "expression", - "from": "[a-zA-Z0-9]{40}" - }, - { - "name": "DATABASE_SERVICE_NAME", - "displayName": "Database Service Name", - "required": true, - "value": "mysql" - }, - { - "name": "DATABASE_ENGINE", - "displayName": "Database Engine", - "description": "Database engine: postgresql, mysql or sqlite (default).", - "required": true, - "value": "mysql" - }, - { - "name": "DATABASE_NAME", - "displayName": "Database Name", - "required": true, - "value": "default" - }, - { - "name": "DATABASE_USER", - "displayName": "Database User", - "required": true, - "value": "cakephp" - }, - { - "name": "DATABASE_PASSWORD", - "displayName": "Database Password", - "generate": "expression", - "from": "[a-zA-Z0-9]{16}" - }, - { - "name": "CAKEPHP_SECRET_TOKEN", - "displayName": "CakePHP secret token", - "description": "Set this to a long random string.", - "generate": "expression", - "from": "[\\w]{50}" - }, - { - "name": "CAKEPHP_SECURITY_SALT", - "displayName": "CakePHP Security Salt", - "description": "Security salt for session hash.", - "generate": "expression", - "from": "[a-zA-Z0-9]{40}" - }, - { - "name": "CAKEPHP_SECURITY_CIPHER_SEED", - "displayName": "CakePHP Security Cipher Seed", - "description": "Security cipher seed for session hash.", - "generate": "expression", - "from": "[0-9]{30}" - }, - { - "name": "OPCACHE_REVALIDATE_FREQ", - "displayName": "OPcache Revalidation Frequency", - "description": "How often to check script timestamps for updates, in seconds. 0 will result in OPcache checking for updates on every request.", - "value": "2" - }, - { - "name": "COMPOSER_MIRROR", - "displayName": "Custom Composer Mirror URL", - "description": "The custom Composer mirror URL", - "value": "" - } - ] -} diff --git a/openshift/templates/cakephp-mysql.json b/openshift/templates/cakephp-mysql.json deleted file mode 100644 index 3a4ef0263..000000000 --- a/openshift/templates/cakephp-mysql.json +++ /dev/null @@ -1,562 +0,0 @@ -{ - "kind": "Template", - "apiVersion": "v1", - "metadata": { - "name": "cakephp-mysql-example", - "annotations": { - "openshift.io/display-name": "CakePHP + MySQL (Ephemeral)", - "description": "An example CakePHP application with a MySQL database. For more information about using this template, including OpenShift considerations, see https://github.com/openshift/cakephp-ex/blob/master/README.md.\n\nWARNING: Any data stored will be lost upon pod destruction. Only use this template for testing.", - "tags": "quickstart,php,cakephp", - "iconClass": "icon-php", - "template.openshift.io/long-description": "This template defines resources needed to develop a CakePHP application, including a build configuration, application deployment configuration, and database deployment configuration. The database is stored in non-persistent storage, so this configuration should be used for experimental purposes only.", - "template.openshift.io/provider-display-name": "Red Hat, Inc.", - "template.openshift.io/documentation-url": "https://github.com/openshift/cakephp-ex", - "template.openshift.io/support-url": "https://access.redhat.com" - } - }, - "message": "The following service(s) have been created in your project: ${NAME}, ${DATABASE_SERVICE_NAME}.\n\nFor more information about using this template, including OpenShift considerations, see https://github.com/openshift/cake-ex/blob/master/README.md.", - "labels": { - "template": "cakephp-mysql-example" - }, - "objects": [ - { - "kind": "Secret", - "apiVersion": "v1", - "metadata": { - "name": "${NAME}" - }, - "stringData" : { - "database-user" : "${DATABASE_USER}", - "database-password" : "${DATABASE_PASSWORD}", - "cakephp-secret-token" : "${CAKEPHP_SECRET_TOKEN}", - "cakephp-security-salt" : "${CAKEPHP_SECURITY_SALT}", - "cakephp-security-cipher-seed" : "${CAKEPHP_SECURITY_CIPHER_SEED}" - } - }, - { - "kind": "Service", - "apiVersion": "v1", - "metadata": { - "name": "${NAME}", - "annotations": { - "description": "Exposes and load balances the application pods", - "service.alpha.openshift.io/dependencies": "[{\"name\": \"${DATABASE_SERVICE_NAME}\", \"kind\": \"Service\"}]" - } - }, - "spec": { - "ports": [ - { - "name": "web", - "port": 8080, - "targetPort": 8080 - } - ], - "selector": { - "name": "${NAME}" - } - } - }, - { - "kind": "Route", - "apiVersion": "v1", - "metadata": { - "name": "${NAME}", - "annotations": { - "template.openshift.io/expose-uri": "http://{.spec.host}{.spec.path}" - } - }, - "spec": { - "host": "${APPLICATION_DOMAIN}", - "to": { - "kind": "Service", - "name": "${NAME}" - } - } - }, - { - "kind": "ImageStream", - "apiVersion": "v1", - "metadata": { - "name": "${NAME}", - "annotations": { - "description": "Keeps track of changes in the application image" - } - } - }, - { - "kind": "BuildConfig", - "apiVersion": "v1", - "metadata": { - "name": "${NAME}", - "annotations": { - "description": "Defines how to build the application", - "template.alpha.openshift.io/wait-for-ready": "true" - } - }, - "spec": { - "source": { - "type": "Git", - "git": { - "uri": "${SOURCE_REPOSITORY_URL}", - "ref": "${SOURCE_REPOSITORY_REF}" - }, - "contextDir": "${CONTEXT_DIR}" - }, - "strategy": { - "type": "Source", - "sourceStrategy": { - "from": { - "kind": "ImageStreamTag", - "namespace": "${NAMESPACE}", - "name": "php:7.0" - }, - "env": [ - { - "name": "COMPOSER_MIRROR", - "value": "${COMPOSER_MIRROR}" - } - ] - } - }, - "output": { - "to": { - "kind": "ImageStreamTag", - "name": "${NAME}:latest" - } - }, - "triggers": [ - { - "type": "ImageChange" - }, - { - "type": "ConfigChange" - }, - { - "type": "GitHub", - "github": { - "secret": "${GITHUB_WEBHOOK_SECRET}" - } - } - ], - "postCommit": { - "script": "./lib/Cake/Console/cake test app AllTests" - } - } - }, - { - "kind": "DeploymentConfig", - "apiVersion": "v1", - "metadata": { - "name": "${NAME}", - "annotations": { - "description": "Defines how to deploy the application server", - "template.alpha.openshift.io/wait-for-ready": "true" - } - }, - "spec": { - "strategy": { - "type": "Recreate", - "recreateParams": { - "pre": { - "failurePolicy": "Retry", - "execNewPod": { - "command": [ - "./migrate-database.sh" - ], - "containerName": "cakephp-mysql-example" - } - } - } - }, - "triggers": [ - { - "type": "ImageChange", - "imageChangeParams": { - "automatic": true, - "containerNames": [ - "cakephp-mysql-example" - ], - "from": { - "kind": "ImageStreamTag", - "name": "${NAME}:latest" - } - } - }, - { - "type": "ConfigChange" - } - ], - "replicas": 1, - "selector": { - "name": "${NAME}" - }, - "template": { - "metadata": { - "name": "${NAME}", - "labels": { - "name": "${NAME}" - } - }, - "spec": { - "containers": [ - { - "name": "cakephp-mysql-example", - "image": " ", - "ports": [ - { - "containerPort": 8080 - } - ], - "readinessProbe": { - "timeoutSeconds": 3, - "initialDelaySeconds": 3, - "httpGet": { - "path": "/health.php", - "port": 8080 - } - }, - "livenessProbe": { - "timeoutSeconds": 3, - "initialDelaySeconds": 30, - "httpGet": { - "path": "/", - "port": 8080 - } - }, - "env": [ - { - "name": "DATABASE_SERVICE_NAME", - "value": "${DATABASE_SERVICE_NAME}" - }, - { - "name": "DATABASE_ENGINE", - "value": "${DATABASE_ENGINE}" - }, - { - "name": "DATABASE_NAME", - "value": "${DATABASE_NAME}" - }, - { - "name": "DATABASE_USER", - "valueFrom": { - "secretKeyRef" : { - "name" : "${NAME}", - "key" : "database-user" - } - } - }, - { - "name": "DATABASE_PASSWORD", - "valueFrom": { - "secretKeyRef" : { - "name" : "${NAME}", - "key" : "database-password" - } - } - }, - { - "name": "CAKEPHP_SECRET_TOKEN", - "valueFrom": { - "secretKeyRef" : { - "name" : "${NAME}", - "key" : "cakephp-secret-token" - } - } - }, - { - "name": "CAKEPHP_SECURITY_SALT", - "valueFrom": { - "secretKeyRef" : { - "name" : "${NAME}", - "key" : "cakephp-security-salt" - } - } - }, - { - "name": "CAKEPHP_SECURITY_CIPHER_SEED", - "valueFrom": { - "secretKeyRef" : { - "name" : "${NAME}", - "key" : "cakephp-security-cipher-seed" - } - } - }, - { - "name": "OPCACHE_REVALIDATE_FREQ", - "value": "${OPCACHE_REVALIDATE_FREQ}" - } - ], - "resources": { - "limits": { - "memory": "${MEMORY_LIMIT}" - } - } - } - ] - } - } - } - }, - { - "kind": "Service", - "apiVersion": "v1", - "metadata": { - "name": "${DATABASE_SERVICE_NAME}", - "annotations": { - "description": "Exposes the database server" - } - }, - "spec": { - "ports": [ - { - "name": "mysql", - "port": 3306, - "targetPort": 3306 - } - ], - "selector": { - "name": "${DATABASE_SERVICE_NAME}" - } - } - }, - { - "kind": "DeploymentConfig", - "apiVersion": "v1", - "metadata": { - "name": "${DATABASE_SERVICE_NAME}", - "annotations": { - "description": "Defines how to deploy the database", - "template.alpha.openshift.io/wait-for-ready": "true" - } - }, - "spec": { - "strategy": { - "type": "Recreate" - }, - "triggers": [ - { - "type": "ImageChange", - "imageChangeParams": { - "automatic": true, - "containerNames": [ - "mysql" - ], - "from": { - "kind": "ImageStreamTag", - "namespace": "${NAMESPACE}", - "name": "mysql:5.7" - } - } - }, - { - "type": "ConfigChange" - } - ], - "replicas": 1, - "selector": { - "name": "${DATABASE_SERVICE_NAME}" - }, - "template": { - "metadata": { - "name": "${DATABASE_SERVICE_NAME}", - "labels": { - "name": "${DATABASE_SERVICE_NAME}" - } - }, - "spec": { - "volumes": [ - { - "name": "data", - "emptyDir": {} - } - ], - "containers": [ - { - "name": "mysql", - "image": " ", - "ports": [ - { - "containerPort": 3306 - } - ], - "volumeMounts": [ - { - "name": "data", - "mountPath": "/var/lib/mysql/data" - } - ], - "readinessProbe": { - "timeoutSeconds": 1, - "initialDelaySeconds": 5, - "exec": { - "command": [ "/bin/sh", "-i", "-c", "MYSQL_PWD='${DATABASE_PASSWORD}' mysql -h 127.0.0.1 -u ${DATABASE_USER} -D ${DATABASE_NAME} -e 'SELECT 1'" ] - } - }, - "livenessProbe": { - "timeoutSeconds": 1, - "initialDelaySeconds": 30, - "tcpSocket": { - "port": 3306 - } - }, - "env": [ - { - "name": "MYSQL_USER", - "valueFrom": { - "secretKeyRef" : { - "name" : "${NAME}", - "key" : "database-user" - } - } - }, - { - "name": "MYSQL_PASSWORD", - "valueFrom": { - "secretKeyRef" : { - "name" : "${NAME}", - "key" : "database-password" - } - } - }, - { - "name": "MYSQL_DATABASE", - "value": "${DATABASE_NAME}" - } - ], - "resources": { - "limits": { - "memory": "${MEMORY_MYSQL_LIMIT}" - } - } - } - ] - } - } - } - } - ], - "parameters": [ - { - "name": "NAME", - "displayName": "Name", - "description": "The name assigned to all of the frontend objects defined in this template.", - "required": true, - "value": "cakephp-mysql-example" - }, - { - "name": "NAMESPACE", - "displayName": "Namespace", - "description": "The OpenShift Namespace where the ImageStream resides.", - "required": true, - "value": "openshift" - }, - { - "name": "MEMORY_LIMIT", - "displayName": "Memory Limit", - "description": "Maximum amount of memory the CakePHP container can use.", - "required": true, - "value": "512Mi" - }, - { - "name": "MEMORY_MYSQL_LIMIT", - "displayName": "Memory Limit (MySQL)", - "description": "Maximum amount of memory the MySQL container can use.", - "required": true, - "value": "512Mi" - }, - { - "name": "SOURCE_REPOSITORY_URL", - "displayName": "Git Repository URL", - "description": "The URL of the repository with your application source code.", - "required": true, - "value": "https://github.com/openshift/cakephp-ex.git" - }, - { - "name": "SOURCE_REPOSITORY_REF", - "displayName": "Git Reference", - "description": "Set this to a branch name, tag or other ref of your repository if you are not using the default branch." - }, - { - "name": "CONTEXT_DIR", - "displayName": "Context Directory", - "description": "Set this to the relative path to your project if it is not in the root of your repository." - }, - { - "name": "APPLICATION_DOMAIN", - "displayName": "Application Hostname", - "description": "The exposed hostname that will route to the CakePHP service, if left blank a value will be defaulted.", - "value": "" - }, - { - "name": "GITHUB_WEBHOOK_SECRET", - "displayName": "GitHub Webhook Secret", - "description": "Github trigger secret. A difficult to guess string encoded as part of the webhook URL. Not encrypted.", - "generate": "expression", - "from": "[a-zA-Z0-9]{40}" - }, - { - "name": "DATABASE_SERVICE_NAME", - "displayName": "Database Service Name", - "required": true, - "value": "mysql" - }, - { - "name": "DATABASE_ENGINE", - "displayName": "Database Engine", - "description": "Database engine: postgresql, mysql or sqlite (default).", - "required": true, - "value": "mysql" - }, - { - "name": "DATABASE_NAME", - "displayName": "Database Name", - "required": true, - "value": "default" - }, - { - "name": "DATABASE_USER", - "displayName": "Database User", - "required": true, - "value": "cakephp" - }, - { - "name": "DATABASE_PASSWORD", - "displayName": "Database Password", - "generate": "expression", - "from": "[a-zA-Z0-9]{16}" - }, - { - "name": "CAKEPHP_SECRET_TOKEN", - "displayName": "CakePHP secret token", - "description": "Set this to a long random string.", - "generate": "expression", - "from": "[\\w]{50}" - }, - { - "name": "CAKEPHP_SECURITY_SALT", - "displayName": "CakePHP Security Salt", - "description": "Security salt for session hash.", - "generate": "expression", - "from": "[a-zA-Z0-9]{40}" - }, - { - "name": "CAKEPHP_SECURITY_CIPHER_SEED", - "displayName": "CakePHP Security Cipher Seed", - "description": "Security cipher seed for session hash.", - "generate": "expression", - "from": "[0-9]{30}" - }, - { - "name": "OPCACHE_REVALIDATE_FREQ", - "displayName": "OPcache Revalidation Frequency", - "description": "How often to check script timestamps for updates, in seconds. 0 will result in OPcache checking for updates on every request.", - "value": "2" - }, - { - "name": "COMPOSER_MIRROR", - "displayName": "Custom Composer Mirror URL", - "description": "The custom Composer mirror URL", - "value": "" - } - ] -} diff --git a/openshift/templates/cakephp.json b/openshift/templates/cakephp.json deleted file mode 100644 index cfe8d84ba..000000000 --- a/openshift/templates/cakephp.json +++ /dev/null @@ -1,343 +0,0 @@ -{ - "kind": "Template", - "apiVersion": "v1", - "metadata": { - "name": "cakephp-example", - "annotations": { - "openshift.io/display-name": "CakePHP", - "description": "An example CakePHP application with no database. For more information about using this template, including OpenShift considerations, see https://github.com/openshift/cake-ex/blob/master/README.md.", - "tags": "quickstart,php,cakephp", - "iconClass": "icon-php", - "template.openshift.io/long-description": "This template defines resources needed to develop a CakePHP application, including a build configuration and application deployment configuration. It does not include a database.", - "template.openshift.io/provider-display-name": "Red Hat, Inc.", - "template.openshift.io/documentation-url": "https://github.com/openshift/cakephp-ex", - "template.openshift.io/support-url": "https://access.redhat.com" - } - }, - "message": "The following service(s) have been created in your project: ${NAME}.\n\nFor more information about using this template, including OpenShift considerations, see https://github.com/openshift/cake-ex/blob/master/README.md.", - "labels": { - "template": "cakephp-example" - }, - "objects": [ - { - "kind": "Secret", - "apiVersion": "v1", - "metadata": { - "name": "${NAME}" - }, - "stringData" : { - "cakephp-secret-token" : "${CAKEPHP_SECRET_TOKEN}", - "cakephp-security-salt" : "${CAKEPHP_SECURITY_SALT}", - "cakephp-security-cipher-seed" : "${CAKEPHP_SECURITY_CIPHER_SEED}" - } - }, - { - "kind": "Service", - "apiVersion": "v1", - "metadata": { - "name": "${NAME}", - "annotations": { - "description": "Exposes and load balances the application pods" - } - }, - "spec": { - "ports": [ - { - "name": "web", - "port": 8080, - "targetPort": 8080 - } - ], - "selector": { - "name": "${NAME}" - } - } - }, - { - "kind": "Route", - "apiVersion": "v1", - "metadata": { - "name": "${NAME}", - "annotations": { - "template.openshift.io/expose-uri": "http://{.spec.host}{.spec.path}" - } - }, - "spec": { - "host": "${APPLICATION_DOMAIN}", - "to": { - "kind": "Service", - "name": "${NAME}" - } - } - }, - { - "kind": "ImageStream", - "apiVersion": "v1", - "metadata": { - "name": "${NAME}", - "annotations": { - "description": "Keeps track of changes in the application image" - } - } - }, - { - "kind": "BuildConfig", - "apiVersion": "v1", - "metadata": { - "name": "${NAME}", - "annotations": { - "description": "Defines how to build the application", - "template.alpha.openshift.io/wait-for-ready": "true" - } - }, - "spec": { - "source": { - "type": "Git", - "git": { - "uri": "${SOURCE_REPOSITORY_URL}", - "ref": "${SOURCE_REPOSITORY_REF}" - }, - "contextDir": "${CONTEXT_DIR}" - }, - "strategy": { - "type": "Source", - "sourceStrategy": { - "from": { - "kind": "ImageStreamTag", - "namespace": "${NAMESPACE}", - "name": "php:7.0" - }, - "env": [ - { - "name": "COMPOSER_MIRROR", - "value": "${COMPOSER_MIRROR}" - } - ] - } - }, - "output": { - "to": { - "kind": "ImageStreamTag", - "name": "${NAME}:latest" - } - }, - "triggers": [ - { - "type": "ImageChange" - }, - { - "type": "ConfigChange" - }, - { - "type": "GitHub", - "github": { - "secret": "${GITHUB_WEBHOOK_SECRET}" - } - } - ], - "postCommit": { - "script": "./lib/Cake/Console/cake test app AllTests" - } - } - }, - { - "kind": "DeploymentConfig", - "apiVersion": "v1", - "metadata": { - "name": "${NAME}", - "annotations": { - "description": "Defines how to deploy the application server", - "template.alpha.openshift.io/wait-for-ready": "true" - } - }, - "spec": { - "strategy": { - "type": "Rolling" - }, - "triggers": [ - { - "type": "ImageChange", - "imageChangeParams": { - "automatic": true, - "containerNames": [ - "cakephp-example" - ], - "from": { - "kind": "ImageStreamTag", - "name": "${NAME}:latest" - } - } - }, - { - "type": "ConfigChange" - } - ], - "replicas": 1, - "selector": { - "name": "${NAME}" - }, - "template": { - "metadata": { - "name": "${NAME}", - "labels": { - "name": "${NAME}" - } - }, - "spec": { - "containers": [ - { - "name": "cakephp-example", - "image": " ", - "ports": [ - { - "containerPort": 8080 - } - ], - "readinessProbe": { - "timeoutSeconds": 3, - "initialDelaySeconds": 3, - "httpGet": { - "path": "/", - "port": 8080 - } - }, - "livenessProbe": { - "timeoutSeconds": 3, - "initialDelaySeconds": 30, - "httpGet": { - "path": "/", - "port": 8080 - } - }, - "env": [ - { - "name": "CAKEPHP_SECRET_TOKEN", - "valueFrom": { - "secretKeyRef" : { - "name" : "${NAME}", - "key" : "cakephp-secret-token" - } - } - }, - { - "name": "CAKEPHP_SECURITY_SALT", - "valueFrom": { - "secretKeyRef" : { - "name" : "${NAME}", - "key" : "cakephp-security-salt" - } - } - }, - { - "name": "CAKEPHP_SECURITY_CIPHER_SEED", - "valueFrom": { - "secretKeyRef" : { - "name" : "${NAME}", - "key" : "cakephp-security-cipher-seed" - } - } - }, - { - "name": "OPCACHE_REVALIDATE_FREQ", - "value": "${OPCACHE_REVALIDATE_FREQ}" - } - ], - "resources": { - "limits": { - "memory": "${MEMORY_LIMIT}" - } - } - } - ] - } - } - } - } - ], - "parameters": [ - { - "name": "NAME", - "displayName": "Name", - "description": "The name assigned to all of the frontend objects defined in this template.", - "required": true, - "value": "cakephp-example" - }, - { - "name": "NAMESPACE", - "displayName": "Namespace", - "description": "The OpenShift Namespace where the ImageStream resides.", - "required": true, - "value": "openshift" - }, - { - "name": "MEMORY_LIMIT", - "displayName": "Memory Limit", - "description": "Maximum amount of memory the container can use.", - "required": true, - "value": "512Mi" - }, - { - "name": "SOURCE_REPOSITORY_URL", - "displayName": "Git Repository URL", - "description": "The URL of the repository with your application source code.", - "required": true, - "value": "https://github.com/openshift/cakephp-ex.git" - }, - { - "name": "SOURCE_REPOSITORY_REF", - "displayName": "Git Reference", - "description": "Set this to a branch name, tag or other ref of your repository if you are not using the default branch." - }, - { - "name": "CONTEXT_DIR", - "displayName": "Context Directory", - "description": "Set this to the relative path to your project if it is not in the root of your repository." - }, - { - "name": "APPLICATION_DOMAIN", - "displayName": "Application Hostname", - "description": "The exposed hostname that will route to the CakePHP service, if left blank a value will be defaulted.", - "value": "" - }, - { - "name": "GITHUB_WEBHOOK_SECRET", - "displayName": "GitHub Webhook Secret", - "description": "Github trigger secret. A difficult to guess string encoded as part of the webhook URL. Not encrypted.", - "generate": "expression", - "from": "[a-zA-Z0-9]{40}" - }, - { - "name": "CAKEPHP_SECRET_TOKEN", - "displayName": "CakePHP Secret Token", - "description": "Set this to a long random string.", - "generate": "expression", - "from": "[\\w]{50}" - }, - { - "name": "CAKEPHP_SECURITY_SALT", - "displayName": "CakePHP Security Salt", - "description": "Security salt for session hash.", - "generate": "expression", - "from": "[a-zA-Z0-9]{40}" - }, - { - "name": "CAKEPHP_SECURITY_CIPHER_SEED", - "displayName": "CakePHP Security Cipher Seed", - "description": "Security cipher seed for session hash.", - "generate": "expression", - "from": "[0-9]{30}" - }, - { - "name": "OPCACHE_REVALIDATE_FREQ", - "displayName": "OPcache Revalidation Frequency", - "description": "How often to check script timestamps for updates, in seconds. 0 will result in OPcache checking for updates on every request.", - "value": "2" - }, - { - "name": "COMPOSER_MIRROR", - "displayName": "Custom Composer Mirror URL", - "description": "The custom Composer mirror URL", - "value": "" - } - ] -} diff --git a/openshift/templates/db-deployment.json b/openshift/templates/db-deployment.json new file mode 100644 index 000000000..dced7df64 --- /dev/null +++ b/openshift/templates/db-deployment.json @@ -0,0 +1,171 @@ +{ + "apiVersion": "apps/v1", + "kind": "Deployment", + "metadata": { + "annotations": { + "io.balena.features.dbus": "1", + "kompose.cmd": "kompose convert --build build-config --controller deployment -o openshift/templates/ -f docker-compose.x86_64 -j", + "kompose.version": "1.21.0 (992df58d8)" + }, + "creationTimestamp": null, + "labels": { + "io.kompose.service": "db" + }, + "name": "db" + }, + "spec": { + "replicas": 1, + "selector": { + "matchLabels": { + "io.kompose.service": "db" + } + }, + "strategy": { + "type": "Recreate" + }, + "template": { + "metadata": { + "annotations": { + "io.balena.features.dbus": "1", + "kompose.cmd": "kompose convert --build build-config --controller deployment -o openshift/templates/ -f docker-compose.x86_64 -j", + "kompose.version": "1.21.0 (992df58d8)" + }, + "creationTimestamp": null, + "labels": { + "io.kompose.network/acake2php_cake": "true", + "io.kompose.service": "db" + } + }, + "spec": { + "containers": [ + { + "env": [ + { + "name": "BALENA_MACHINE_NAME", + "value": "raspberrypi3" + }, + { + "name": "BALENA_PROJECTS", + "value": "(. ./mysqldb ./deployment/images/node-php7 ./deployment/images/apache-php7) #(submodule deployment/images/primary" + }, + { + "name": "BALENA_PROJECTS_FLAGS", + "value": "(IMG_TAG PRIMARY_HUB SECONDARY_HUB)" + }, + { + "name": "CAKEPHP_DEBUG_LEVEL", + "value": "1" + }, + { + "name": "CAKEPHP_SECURITY_CIPHER_SEED", + "value": "01234" + }, + { + "name": "CAKEPHP_SECURITY_SALT", + "value": "Word" + }, + { + "name": "COLLECT_COVERAGE", + "value": "false" + }, + { + "name": "DATABASE_USER", + "value": "root" + }, + { + "name": "DKR_ARCH", + "value": "armhf" + }, + { + "name": "HTTPD_LISTEN", + "value": "*:80" + }, + { + "name": "IMG_TAG", + "value": "latest" + }, + { + "name": "MYPHPCMS_DIR", + "value": "app/webroot/php-cms" + }, + { + "name": "MYPHPCMS_LOG", + "value": "app/tmp/logs" + }, + { + "name": "PGID", + "value": "1000" + }, + { + "name": "PRIMARY_HUB", + "value": "betothreeprod/apache-php7" + }, + { + "name": "PUID", + "value": "1000" + }, + { + "name": "SECONDARY_HUB", + "value": "betothreeprod/mariadb-raspberrypi3" + }, + { + "name": "SERVER_NAME", + "value": "acake2php.local" + }, + { + "name": "TZ", + "value": "Europe/Paris" + } + ], + "image": "betothreeprod/mariadb-intel-nuc", + "imagePullPolicy": "", + "name": "db", + "ports": [ + { + "containerPort": 3306 + } + ], + "resources": {}, + "volumeMounts": [ + { + "mountPath": "/config", + "name": "acake2php-db-data" + }, + { + "mountPath": "/var/run/mysqld", + "name": "acake2php-db-socket" + }, + { + "mountPath": "/var/www", + "name": "acake2php-data" + } + ] + } + ], + "restartPolicy": "Always", + "serviceAccountName": "", + "volumes": [ + { + "name": "acake2php-db-data", + "persistentVolumeClaim": { + "claimName": "acake2php-db-data" + } + }, + { + "name": "acake2php-db-socket", + "persistentVolumeClaim": { + "claimName": "acake2php-db-socket" + } + }, + { + "name": "acake2php-data", + "persistentVolumeClaim": { + "claimName": "acake2php-data" + } + } + ] + } + } + }, + "status": {} +} \ No newline at end of file diff --git a/openshift/templates/db-deploymentconfig.json b/openshift/templates/db-deploymentconfig.json new file mode 100644 index 000000000..8cf2f3fcf --- /dev/null +++ b/openshift/templates/db-deploymentconfig.json @@ -0,0 +1,182 @@ +{ + "kind": "DeploymentConfig", + "apiVersion": "v1", + "metadata": { + "name": "db", + "creationTimestamp": null, + "labels": { + "io.kompose.service": "db" + }, + "annotations": { + "io.balena.features.dbus": "1", + "kompose.cmd": "kompose convert -f docker-compose.x86_64 --provider openshift --out openshift/templates/ -j", + "kompose.version": "1.21.0 (992df58d8)" + } + }, + "spec": { + "strategy": { + "type": "Recreate", + "resources": {} + }, + "triggers": [ + { + "type": "ConfigChange" + }, + { + "type": "ImageChange", + "imageChangeParams": { + "automatic": true, + "containerNames": [ + "db" + ], + "from": { + "kind": "ImageStreamTag", + "name": "db:latest" + } + } + } + ], + "replicas": 1, + "test": false, + "selector": { + "io.kompose.service": "db" + }, + "template": { + "metadata": { + "creationTimestamp": null, + "labels": { + "io.kompose.network/acake2php_cake": "true", + "io.kompose.service": "db" + } + }, + "spec": { + "volumes": [ + { + "name": "acake2php-db-data", + "persistentVolumeClaim": { + "claimName": "acake2php-db-data" + } + }, + { + "name": "acake2php-db-socket", + "persistentVolumeClaim": { + "claimName": "acake2php-db-socket" + } + }, + { + "name": "acake2php-data", + "persistentVolumeClaim": { + "claimName": "acake2php-data" + } + } + ], + "containers": [ + { + "name": "db", + "image": " ", + "ports": [ + { + "containerPort": 3306 + } + ], + "env": [ + { + "name": "BALENA_MACHINE_NAME", + "value": "raspberrypi3" + }, + { + "name": "BALENA_PROJECTS", + "value": "(. ./mysqldb ./deployment/images/node-php7 ./deployment/images/apache-php7) #(submodule deployment/images/primary" + }, + { + "name": "BALENA_PROJECTS_FLAGS", + "value": "(IMG_TAG PRIMARY_HUB SECONDARY_HUB)" + }, + { + "name": "CAKEPHP_DEBUG_LEVEL", + "value": "1" + }, + { + "name": "CAKEPHP_SECURITY_CIPHER_SEED", + "value": "01234" + }, + { + "name": "CAKEPHP_SECURITY_SALT", + "value": "Word" + }, + { + "name": "COLLECT_COVERAGE", + "value": "false" + }, + { + "name": "DATABASE_USER", + "value": "root" + }, + { + "name": "DKR_ARCH", + "value": "armhf" + }, + { + "name": "HTTPD_LISTEN", + "value": "*:80" + }, + { + "name": "IMG_TAG", + "value": "latest" + }, + { + "name": "MYPHPCMS_DIR", + "value": "app/webroot/php-cms" + }, + { + "name": "MYPHPCMS_LOG", + "value": "app/tmp/logs" + }, + { + "name": "PGID", + "value": "1000" + }, + { + "name": "PRIMARY_HUB", + "value": "betothreeprod/apache-php7" + }, + { + "name": "PUID", + "value": "1000" + }, + { + "name": "SECONDARY_HUB", + "value": "betothreeprod/mariadb-raspberrypi3" + }, + { + "name": "SERVER_NAME", + "value": "acake2php.local" + }, + { + "name": "TZ", + "value": "Europe/Paris" + } + ], + "resources": {}, + "volumeMounts": [ + { + "name": "acake2php-db-data", + "mountPath": "/config" + }, + { + "name": "acake2php-db-socket", + "mountPath": "/var/run/mysqld" + }, + { + "name": "acake2php-data", + "mountPath": "/var/www" + } + ] + } + ], + "restartPolicy": "Always" + } + } + }, + "status": {} +} \ No newline at end of file diff --git a/openshift/templates/db-imagestream.json b/openshift/templates/db-imagestream.json new file mode 100644 index 000000000..f8a8a16bc --- /dev/null +++ b/openshift/templates/db-imagestream.json @@ -0,0 +1,28 @@ +{ + "kind": "ImageStream", + "apiVersion": "v1", + "metadata": { + "name": "db", + "creationTimestamp": null, + "labels": { + "io.kompose.service": "db" + } + }, + "spec": { + "tags": [ + { + "name": "latest", + "annotations": null, + "from": { + "kind": "DockerImage", + "name": "betothreeprod/mariadb-intel-nuc" + }, + "generation": null, + "importPolicy": {} + } + ] + }, + "status": { + "dockerImageRepository": "" + } +} \ No newline at end of file diff --git a/openshift/templates/db-service.json b/openshift/templates/db-service.json new file mode 100644 index 000000000..4253a9bb9 --- /dev/null +++ b/openshift/templates/db-service.json @@ -0,0 +1,31 @@ +{ + "kind": "Service", + "apiVersion": "v1", + "metadata": { + "name": "db", + "creationTimestamp": null, + "labels": { + "io.kompose.service": "db" + }, + "annotations": { + "io.balena.features.dbus": "1", + "kompose.cmd": "kompose convert --build build-config --controller deployment -o openshift/templates/ -f docker-compose.x86_64 -j", + "kompose.version": "1.21.0 (992df58d8)" + } + }, + "spec": { + "ports": [ + { + "name": "3306", + "port": 3306, + "targetPort": 3306 + } + ], + "selector": { + "io.kompose.service": "db" + } + }, + "status": { + "loadBalancer": {} + } +} \ No newline at end of file diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 000000000..4dd7e3ece --- /dev/null +++ b/package-lock.json @@ -0,0 +1,793 @@ +{ + "name": "myphpcms", + "version": "1.0.0", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "name": "myphpcms", + "version": "1.0.0", + "license": "Apache-2.0", + "dependencies": { + "balena-cloud-apps": "^1.0.34", + "composer": "^4.1.0", + "shellcheck": "^1.1.0" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" + }, + "node_modules/balena-cloud-apps": { + "version": "1.0.34", + "resolved": "https://registry.npmjs.org/balena-cloud-apps/-/balena-cloud-apps-1.0.34.tgz", + "integrity": "sha512-aRFym2kCQkshGUjjhNBmaxtm6c/9IxzH95UsbPsqPyJojgPx4nqb6SsriZe4WA5hfFRTLrHTLYk4rYAHSU4oSQ==", + "dependencies": { + "shelljs": "^0.8.4" + }, + "bin": { + "auto_reboot": "vendor/cni/auto_reboot.sh", + "balena_deploy": "vendor/cni/balena_deploy.sh", + "docker_build": "vendor/cni/docker_build.sh", + "init_functions": "vendor/cni/init_functions.sh", + "post_install": "vendor/cni/post_install.sh" + } + }, + "node_modules/boolean": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/boolean/-/boolean-3.2.0.tgz", + "integrity": "sha512-d0II/GO9uf9lfUHH2BQsjxzRJZBdsjgsBiW4BvhWk/3qoKwQFjIDVN19PfX8F2D/r9PCMTtLWjYVCFrpeYUzsw==" + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/composer": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/composer/-/composer-4.1.0.tgz", + "integrity": "sha512-qIIoNYjwFHrQFUdB8kD3pZs30+JeYK9149EpOYr/NVrii00KMO31IonzZMeRSU4qazyWZpEgVzkBmQ6VFWxedA==", + "dependencies": { + "pretty-time": "^1.1.0", + "use": "^3.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" + }, + "node_modules/define-properties": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.4.tgz", + "integrity": "sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA==", + "dependencies": { + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/detect-node": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz", + "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==" + }, + "node_modules/es6-error": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz", + "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==" + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" + }, + "node_modules/function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + }, + "node_modules/get-intrinsic": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.2.tgz", + "integrity": "sha512-Jfm3OyCxHh9DJyc28qGk+JmfkpO41A4XkneDSujN9MDXrm4oDKdHvndhZ2dN94+ERNfkYJWDclW6k2L/ZGHjXA==", + "dependencies": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/global-agent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/global-agent/-/global-agent-3.0.0.tgz", + "integrity": "sha512-PT6XReJ+D07JvGoxQMkT6qji/jVNfX/h364XHZOWeRzy64sSFr+xJ5OX7LI3b4MPQzdL4H8Y8M0xzPpsVMwA8Q==", + "dependencies": { + "boolean": "^3.0.1", + "es6-error": "^4.1.1", + "matcher": "^3.0.0", + "roarr": "^2.15.3", + "semver": "^7.3.2", + "serialize-error": "^7.0.1" + }, + "engines": { + "node": ">=10.0" + } + }, + "node_modules/globalthis": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.3.tgz", + "integrity": "sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==", + "dependencies": { + "define-properties": "^1.1.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dependencies": { + "function-bind": "^1.1.1" + }, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/has-property-descriptors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz", + "integrity": "sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==", + "dependencies": { + "get-intrinsic": "^1.1.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "node_modules/interpret": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz", + "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/is-core-module": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.9.0.tgz", + "integrity": "sha512-+5FPy5PnwmO3lvfMb0AsoPaBG+5KHUI0wYFXOtYPnVVVspTFUuMZNfNaNVRt3FZadstu2c8x23vykRW/NBoU6A==", + "dependencies": { + "has": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==" + }, + "node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/matcher": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/matcher/-/matcher-3.0.0.tgz", + "integrity": "sha512-OkeDaAZ/bQCxeFAozM55PKcKU0yJMPGifLwV4Qgjitu+5MoAfSQN4lsLJeXZ1b8w0x+/Emda6MZgXS1jvsapng==", + "dependencies": { + "escape-string-regexp": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" + }, + "node_modules/pretty-time": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/pretty-time/-/pretty-time-1.1.0.tgz", + "integrity": "sha512-28iF6xPQrP8Oa6uxE6a1biz+lWeTOAPKggvjB8HAs6nVMKZwf5bG++632Dx614hIWgUPkgivRfG+a8uAXGTIbA==", + "engines": { + "node": ">=4" + } + }, + "node_modules/rechoir": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", + "integrity": "sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==", + "dependencies": { + "resolve": "^1.1.6" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/resolve": { + "version": "1.22.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", + "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==", + "dependencies": { + "is-core-module": "^2.9.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/roarr": { + "version": "2.15.4", + "resolved": "https://registry.npmjs.org/roarr/-/roarr-2.15.4.tgz", + "integrity": "sha512-CHhPh+UNHD2GTXNYhPWLnU8ONHdI+5DI+4EYIAOaiD63rHeYlZvyh8P+in5999TTSFgUYuKUAjzRI4mdh/p+2A==", + "dependencies": { + "boolean": "^3.0.1", + "detect-node": "^2.0.4", + "globalthis": "^1.0.1", + "json-stringify-safe": "^5.0.1", + "semver-compare": "^1.0.0", + "sprintf-js": "^1.1.2" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/semver": { + "version": "7.3.7", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", + "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/semver-compare": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz", + "integrity": "sha512-YM3/ITh2MJ5MtzaM429anh+x2jiLVjqILF4m4oyQB18W7Ggea7BfqdH/wGMK7dDiMghv/6WG7znWMwUDzJiXow==" + }, + "node_modules/serialize-error": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-7.0.1.tgz", + "integrity": "sha512-8I8TjW5KMOKsZQTvoxjuSIa7foAwPWGOts+6o7sgjz41/qMD9VQHEDxi6PBvK2l0MXUmqZyNpUK+T2tQaaElvw==", + "dependencies": { + "type-fest": "^0.13.1" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/shellcheck": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/shellcheck/-/shellcheck-1.1.0.tgz", + "integrity": "sha512-WtLqgjHg7667gGU+0dPV1EtoQgYL/Zxc4fhRt6Z3kfpASG3J08TBJ990HVIUnN/YWUBKMr3FVbBYlEvPVJ24bA==", + "hasInstallScript": true, + "dependencies": { + "global-agent": "^3.0.0" + }, + "bin": { + "shellcheck": "shellcheck-stable/shellcheck" + } + }, + "node_modules/shelljs": { + "version": "0.8.5", + "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.5.tgz", + "integrity": "sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow==", + "dependencies": { + "glob": "^7.0.0", + "interpret": "^1.0.0", + "rechoir": "^0.6.2" + }, + "bin": { + "shjs": "bin/shjs" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/sprintf-js": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.2.tgz", + "integrity": "sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug==" + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/type-fest": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.13.1.tgz", + "integrity": "sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/use": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", + "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" + }, + "node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + } + }, + "dependencies": { + "balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" + }, + "balena-cloud-apps": { + "version": "1.0.34", + "resolved": "https://registry.npmjs.org/balena-cloud-apps/-/balena-cloud-apps-1.0.34.tgz", + "integrity": "sha512-aRFym2kCQkshGUjjhNBmaxtm6c/9IxzH95UsbPsqPyJojgPx4nqb6SsriZe4WA5hfFRTLrHTLYk4rYAHSU4oSQ==", + "requires": { + "shelljs": "^0.8.4" + } + }, + "boolean": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/boolean/-/boolean-3.2.0.tgz", + "integrity": "sha512-d0II/GO9uf9lfUHH2BQsjxzRJZBdsjgsBiW4BvhWk/3qoKwQFjIDVN19PfX8F2D/r9PCMTtLWjYVCFrpeYUzsw==" + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "composer": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/composer/-/composer-4.1.0.tgz", + "integrity": "sha512-qIIoNYjwFHrQFUdB8kD3pZs30+JeYK9149EpOYr/NVrii00KMO31IonzZMeRSU4qazyWZpEgVzkBmQ6VFWxedA==", + "requires": { + "pretty-time": "^1.1.0", + "use": "^3.1.1" + } + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" + }, + "define-properties": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.4.tgz", + "integrity": "sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA==", + "requires": { + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + } + }, + "detect-node": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz", + "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==" + }, + "es6-error": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz", + "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==" + }, + "escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==" + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + }, + "get-intrinsic": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.2.tgz", + "integrity": "sha512-Jfm3OyCxHh9DJyc28qGk+JmfkpO41A4XkneDSujN9MDXrm4oDKdHvndhZ2dN94+ERNfkYJWDclW6k2L/ZGHjXA==", + "requires": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.3" + } + }, + "glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "global-agent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/global-agent/-/global-agent-3.0.0.tgz", + "integrity": "sha512-PT6XReJ+D07JvGoxQMkT6qji/jVNfX/h364XHZOWeRzy64sSFr+xJ5OX7LI3b4MPQzdL4H8Y8M0xzPpsVMwA8Q==", + "requires": { + "boolean": "^3.0.1", + "es6-error": "^4.1.1", + "matcher": "^3.0.0", + "roarr": "^2.15.3", + "semver": "^7.3.2", + "serialize-error": "^7.0.1" + } + }, + "globalthis": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.3.tgz", + "integrity": "sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==", + "requires": { + "define-properties": "^1.1.3" + } + }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "requires": { + "function-bind": "^1.1.1" + } + }, + "has-property-descriptors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz", + "integrity": "sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==", + "requires": { + "get-intrinsic": "^1.1.1" + } + }, + "has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==" + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "interpret": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz", + "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==" + }, + "is-core-module": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.9.0.tgz", + "integrity": "sha512-+5FPy5PnwmO3lvfMb0AsoPaBG+5KHUI0wYFXOtYPnVVVspTFUuMZNfNaNVRt3FZadstu2c8x23vykRW/NBoU6A==", + "requires": { + "has": "^1.0.3" + } + }, + "json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==" + }, + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "requires": { + "yallist": "^4.0.0" + } + }, + "matcher": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/matcher/-/matcher-3.0.0.tgz", + "integrity": "sha512-OkeDaAZ/bQCxeFAozM55PKcKU0yJMPGifLwV4Qgjitu+5MoAfSQN4lsLJeXZ1b8w0x+/Emda6MZgXS1jvsapng==", + "requires": { + "escape-string-regexp": "^4.0.0" + } + }, + "minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==" + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "requires": { + "wrappy": "1" + } + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==" + }, + "path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" + }, + "pretty-time": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/pretty-time/-/pretty-time-1.1.0.tgz", + "integrity": "sha512-28iF6xPQrP8Oa6uxE6a1biz+lWeTOAPKggvjB8HAs6nVMKZwf5bG++632Dx614hIWgUPkgivRfG+a8uAXGTIbA==" + }, + "rechoir": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", + "integrity": "sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==", + "requires": { + "resolve": "^1.1.6" + } + }, + "resolve": { + "version": "1.22.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", + "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==", + "requires": { + "is-core-module": "^2.9.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + } + }, + "roarr": { + "version": "2.15.4", + "resolved": "https://registry.npmjs.org/roarr/-/roarr-2.15.4.tgz", + "integrity": "sha512-CHhPh+UNHD2GTXNYhPWLnU8ONHdI+5DI+4EYIAOaiD63rHeYlZvyh8P+in5999TTSFgUYuKUAjzRI4mdh/p+2A==", + "requires": { + "boolean": "^3.0.1", + "detect-node": "^2.0.4", + "globalthis": "^1.0.1", + "json-stringify-safe": "^5.0.1", + "semver-compare": "^1.0.0", + "sprintf-js": "^1.1.2" + } + }, + "semver": { + "version": "7.3.7", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", + "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "requires": { + "lru-cache": "^6.0.0" + } + }, + "semver-compare": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz", + "integrity": "sha512-YM3/ITh2MJ5MtzaM429anh+x2jiLVjqILF4m4oyQB18W7Ggea7BfqdH/wGMK7dDiMghv/6WG7znWMwUDzJiXow==" + }, + "serialize-error": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-7.0.1.tgz", + "integrity": "sha512-8I8TjW5KMOKsZQTvoxjuSIa7foAwPWGOts+6o7sgjz41/qMD9VQHEDxi6PBvK2l0MXUmqZyNpUK+T2tQaaElvw==", + "requires": { + "type-fest": "^0.13.1" + } + }, + "shellcheck": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/shellcheck/-/shellcheck-1.1.0.tgz", + "integrity": "sha512-WtLqgjHg7667gGU+0dPV1EtoQgYL/Zxc4fhRt6Z3kfpASG3J08TBJ990HVIUnN/YWUBKMr3FVbBYlEvPVJ24bA==", + "requires": { + "global-agent": "^3.0.0" + } + }, + "shelljs": { + "version": "0.8.5", + "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.5.tgz", + "integrity": "sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow==", + "requires": { + "glob": "^7.0.0", + "interpret": "^1.0.0", + "rechoir": "^0.6.2" + } + }, + "sprintf-js": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.2.tgz", + "integrity": "sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug==" + }, + "supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==" + }, + "type-fest": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.13.1.tgz", + "integrity": "sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==" + }, + "use": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", + "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==" + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 000000000..e680c693d --- /dev/null +++ b/package.json @@ -0,0 +1,31 @@ +{ + "name": "myphpcms", + "version": "1.0.0", + "description": "A CakePHP and MariaDB website", + "main": "index.js", + "directories": { + "lib": "lib", + "app": "app" + }, + "scripts": { + "cs-check": "PHP_CS=1 ./test-cake.sh", + "test": "./test-cake.sh", + "start": "./start-cake.sh" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/b23prodtm/acake2php.git" + }, + "keywords": [], + "author": "Tiana Rakoto Arimanana <5566338+b23prodtm@users.noreply.github.com>", + "license": "Apache-2.0", + "bugs": { + "url": "https://github.com/b23prodtm/acake2php/issues" + }, + "homepage": "https://github.com/b23prodtm/acake2php#readme", + "dependencies": { + "balena-cloud-apps": "^1.0.34", + "composer": "^4.1.0", + "shellcheck": "^1.1.0" + } +} diff --git a/start-cake.sh b/start-cake.sh index 67e7edd0d..2824ceb70 100755 --- a/start-cake.sh +++ b/start-cake.sh @@ -1,38 +1,52 @@ -#!/bin/bash -source ./Scripts/lib/parsing.sh -source ./Scripts/lib/shell_prompt.sh -command="server -p 8080" -saved=("$*") -while [[ "$#" > 0 ]]; do case $1 in - --help ) - echo "Usage: $0 [-p|--sql-password=] [--test-sql-password=] [-c ] [options] - Default command is lib/Cake/Console/cake server -p 8080 - -p, --sql-password= - Exports DATABASE_PASSWORD to bootargs. - -t,--test-sql-password= - Exports TEST_DATABASE_PASSWORD - -c [--help] - lib/Cake/Console/cake - E.g. $0 -c server --help - " - exit 0;; - -[pP]*|--sql-password*) - parse_sql_password "$1" "DATABASE_PASSWORD" "current ${DATABASE_USER}";; - -[tT]*|--test-sql-password*) - parse_sql_password "$1" "TEST_DATABASE_PASSWORD" "current ${TEST_DATABASE_USER}";; +#!/usr/bin/env bash +set -e +TOPDIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) +# shellcheck source=Scripts/lib/test/parsing.sh +. "$TOPDIR/Scripts/lib/parsing.sh" +# shellcheck source=Scripts/lib/test/shell_prompt.sh +. "$TOPDIR/Scripts/lib/shell_prompt.sh" +command="--docker -c server -p 8000 -H 0.0.0.0" +saved=("$@") +export COLLECT_COVERAGE="false" +usage=("" \ +"Usage: $0 [-p ] [-t ] [-c ] [options]" \ +" -p Exports MYSQL_ROOT_PASSWORD to bootargs." \ +" -t Exports MYSQL_PASSWORD" \ +" -c [--help]" \ +" Set parameters to lib/Cake/Console/cake" \ +" E.g. $0 -c --docker server --help" \ +" Default command is " \ +" lib/Cake/Console/cake server -p 8000 -H 0.0.0.0" \ +" --disable-docker Don't start Docker Image DATABASE" \ +"") +while [[ "$#" -gt 0 ]]; do case $1 in + -[hH]*|--help ) + printf "%s\n" "${usage[@]}" + exit 0;; + -[vV]*|--verbose ) + set -x + command="${command} $1" + echo "Passed params : $0 ${saved[*]}";; + -[pP]*) + parse_sql_password "MYSQL_ROOT_PASSWORD" "current ${DATABASE_USER} password" "$@" + shift $((OPTIND -1)) + ;; + -[tT]*) + parse_sql_password "MYSQL_PASSWORD" "current ${MYSQL_USER} password" "$@" + shift $((OPTIND -1)) + ;; -[cC]*) - command=$2 - shift; shift; command="${command} $*";; + docker=$(parse_arg "--docker" "$command") + command="$docker ${*:2}" + parse_and_export "-p" "CAKE_TCP_PORT" "specify -p " "$@" + break;; + --disable-docker ) + # shellcheck disable=SC2086 + command=$(parse_arg_trim --docker $command) + ;; + --docker ) + command="$command $1" + ;; *);; esac; shift; done -source ./Scripts/bootstrap.sh $saved -show_password_status "$DATABASE_USER" "$DATABASE_PASSWORD" "is running development server" -url="http://localhost:8080" -echo -e "Welcome homepage ${cyan}${url}${nc}" -echo -e "Administrator login ${cyan}${url}/admin/index${nc}" -echo -e "Debugging echoes ${cyan}${url}${orange}?debug=1&verbose=1${nc}" -echo -e "Another Test configuration ${cyan}${url}/admin/index.php${orange}?test=1${nc}" -echo -e "Unit tests ${cyan}${url}/test.php${nc}" -echo -e "Turnoff flags (fix captcha)${cyan}${url}/admin/logoff.php${nc}" -echo -e "===============================================" -lib/Cake/Console/cake $command +bash -c "./Scripts/bootstrap.sh $command" diff --git a/test-cake.sh b/test-cake.sh index dea52df6e..10fc7ff0d 100755 --- a/test-cake.sh +++ b/test-cake.sh @@ -1,66 +1,93 @@ -#!/bin/bash -source ./Scripts/lib/parsing.sh -bootargs="" -saved=("$*") -config_args="-c -h -p pass -s word --mig-database -y" -config_work_dir="" -notice="\n${cyan}Notice:${nc}The test script is about to modify the root and test users password into resp. ${orange}'proot'${nc} and ${cyan}'ptest'${nc}\n" -while [[ "$#" > 0 ]]; do case $1 in - --travis ) - #; Test values - export DB="Mysql" - export COLLECT_COVERAGE="false" - export TRAVIS_OS_NAME="osx" - export TRAVIS_PHP_VERSION=$(php -v | grep -E "[5-7]\.\\d+\.\\d+" | cut -d " " -f 2 | cut -c 1-3 - ) - config_args="${config_args}" - config_work_dir=".travis";; - --docker ) - #; Test values - export DB="Mysql" - export COLLECT_COVERAGE="false" - config_args="${config_args}" - config_work_dir="docker";; +#!/usr/bin/env bash +set -e +TOPDIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) +# shellcheck source=Scripts/lib/test/parsing.sh +. "$TOPDIR/Scripts/lib/test/parsing.sh" +migrate="--connection=test -v -u -i --enable-authentication-plugin" +# default arg --docker, is enabled +saved=("$@") +set -- "--docker" "$@" +config_args="-c -h -p pass -s word --development" +db_data="db-data:/config/databases/" +usage=("" \ +"${cyan}Notice:${nc}The test script." \ +"Usage: $0 [--travis|--docker|--openshift|--circle [--cov|--phpcs]] [-p ] [-t ] " \ +" --travis, --circle Travis or Circle CI Local Test Workflow" \ +" also disables Docker Image" \ +" -o, --openshift [path to a file with a list of variables], " \ +" also disables Docker Image" \ +" --docker [enabled] Startup with Docker Image DATABASE" \ +" -p Exports MYSQL_ROOT_PASSWORD" \ +" -t Exports MYSQL_PASSWORD" \ +" --cov Coverage All Tests" \ +" --phpcs PHP Code Sniffer" \ +"" \ +"Notice: Use environment variables from open container/pod" \ +" and a file if it exists" \ +"Default arguments: " \ +" --docker" \ +"") +while [[ "$#" -gt 0 ]]; do case $1 in + --circle ) + # shellcheck disable=SC2086 + migrate=$(parse_arg_trim --docker $migrate) + # shellcheck disable=SC2086 + config_args=$(parse_arg_trim --docker $config_args) + ;; + --phpcs ) + export PHPCS=1 + migrate="" + config_args="" + ;; --cov ) export COLLECT_COVERAGE=true;; -[hH]*|--help ) - echo "Usage: $0 [-p|--sql-password=] [-t,--test-sql-password=] [--travis [--cov]] - -p, --sql-password= - Exports DATABASE_PASSWORD - -t, --test-sql-password= - Exports TEST_DATABASE_PASSWORD - --travis - Travis CI Local Test Workflow - --docker - Docker Local Test Workflow - --cov - Coverage All Tests - -o, --openshift - Use environment variables from real pod or current shell - " - exit 0;; - -[pP]*|--sql-password*) - parse_sql_password "$1" "DATABASE_PASSWORD" "user ${DATABASE_USER}";; - -[tT]*|--test-sql-password*) - parse_sql_password "$1" "TEST_DATABASE_PASSWORD" "test user ${TEST_DATABASE_USER}";; + printf "%s\n" "${usage[@]}" + exit 0;; + -[pP]*) + parse_sql_password "MYSQL_ROOT_PASSWORD" "user ${DATABASE_USER} password" "$@" + shift $((OPTIND -1)) + ;; + -[tT]*) + parse_sql_password "MYSQL_PASSWORD" "test user ${MYSQL_USER} password" "$@" + shift $((OPTIND -1)) + ;; -[vV]*|--verbose ) - echo "Passed params : $0 ${saved}";; + set -x + migrate="-v ${migrate}" + echo "Passed params : $0 ${saved[*]}";; -[oO]*|--openshift ) - bootargs="${saved}";; - *) echo "Unknown parameter passed: $0 $1"; exit 1;; + # shellcheck disable=SC2086 + migrate="$(parse_arg_trim --docker $migrate) --openshift" + # shellcheck disable=SC2086 + config_args="$(parse_arg_trim --docker $config_args) --openshift" + ;; + --travis) + export MYSQL_HOST=${MYSQL_HOST:-'127.0.0.1'} + export MYSQL_USER='travis' + export MYSQL_PASSWORD='' + export MYSQL_ROOT_PASSWORD='' + # shellcheck disable=SC2086 + migrate="$(parse_arg_trim --docker $migrate) --travis" + # shellcheck disable=SC2086 + config_args="$(parse_arg_trim --docker $config_args) --travis" + ;; + --docker ) + config_args="--docker ${config_args}" + migrate="--docker ${migrate}" + db_data="$(pwd)/mysqld$(echo ${db_data} | cut -d : -f 2)" + ;; + *) echo "Unknown parameter, passed $0: $1"; exit 1;; esac; shift; done -echo -e $notice -source ./configure.sh "${config_args}" -echo -e $notice -[ ! -z $config_work_dir ] && source "${config_work_dir}/configure.sh" -source ./Scripts/bootstrap.sh $bootargs -show_password_status "$TEST_DATABASE_USER" "$TEST_DATABASE_PASSWORD" "is running tests" -if [[ "$COLLECT_COVERAGE" == "true" ]]; then - ./app/Vendor/bin/phpunit --coverage-clover app/build/logs/clover.xml --stop-on-failure -c app/phpunit.xml.dist app/Test/Case/AllTestsTest.php +if [ "$PHPCS" = 1 ]; then + bash -c "./Scripts/start_daemon.sh test ${saved[*]}" || exit 1 + exit 0 +fi +# shellcheck source=configure.sh +bash -c "${TOPDIR}/configure.sh $config_args" +if bash -c "${TOPDIR}/migrate-database.sh ${migrate}"; then + printf "[SUCCESS] CakePHP Test Suite successfully finished, go on with the job...\n" else - if [ '${PHPCS}' != '1' ]; then - ./lib/Cake/Console/cake test core AllTests --stderr - else - ./app/Vendor/bin/phpcs -p --extensions=php --standard=CakePHP ./lib/Cake - fi + printf "[FAILED] CakePHP Test Suite had errors. Quit the job thread.\n\ +[INFO] Only continuous integration scripts may run tests.\n" fi diff --git a/vagrant-shell.sh b/vagrant-shell.sh new file mode 100755 index 000000000..b75ce8e79 --- /dev/null +++ b/vagrant-shell.sh @@ -0,0 +1,16 @@ +#!/usr/bin/env bash +# Check OS we are running on. NetworkManager only works on Linux. +if [[ "$OSTYPE" != "linux"* ]]; then + echo "ERROR: This application only runs on Linux." + if [[ "$OSTYPE" == "darwin"* ]]; then + echo "WARNING: OSX is only supported for development/simulation." + else + exit 1 + fi +fi +#REV=https://raw.githubusercontent.com/StanAngeloff/vagrant-shell-scripts/master/ubuntu.sh +REV=https://raw.githubusercontent.com/StanAngeloff/vagrant-shell-scripts/master/ubuntu.sh +LNK=/usr/local/share/vagrant-shell-scripts/ubuntu.sh +mkdir -p "$(dirname $LNK)" +curl -sSL $REV -o $LNK +bash "$LNK" "$@" diff --git a/x86_64.env b/x86_64.env new file mode 100644 index 000000000..d3b1645c4 --- /dev/null +++ b/x86_64.env @@ -0,0 +1,5 @@ +DKR_ARCH=x86_64 +BALENA_MACHINE_NAME=intel-nuc +IMG_TAG=latest +PRIMARY_HUB=betothreeprod/apache-php7 +SECONDARY_HUB=betothreeprod/mariadb-intel-nuc