diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9330690 --- /dev/null +++ b/.gitignore @@ -0,0 +1,98 @@ +# ----------------------------------------------------------------- +# .gitignore for WordPress +# Bare Minimum Git +# http://ironco.de/bare-minimum-git/ +# ver 20150227 +# +# This file is tailored for a WordPress project +# using the default directory structure +# +# This file specifies intentionally untracked files to ignore +# http://git-scm.com/docs/gitignore +# +# NOTES: +# The purpose of gitignore files is to ensure that certain files not +# tracked by Git remain untracked. +# +# To ignore uncommitted changes in a file that is already tracked, +# use `git update-index --assume-unchanged`. +# +# To stop tracking a file that is currently tracked, +# use `git rm --cached` +# +# Change Log: +# 20150227 Ignore hello.php plugin. props @damienfa +# 20150227 Change theme ignore to wildcard twenty*. props @Z33 +# 20140606 Add .editorconfig as a tracked file +# 20140404 Ignore database, compiled, and packaged files +# 20140404 Header Information Updated +# 20140402 Initially Published +# +# ----------------------------------------------------------------- + +# ignore all files starting with . +.* + +# track this file .gitignore (i.e. do NOT ignore it) +!.gitignore + +# Eslint +!.eslintrc +!.eslintignore + +# track .editorconfig file (i.e. do NOT ignore it) +!.editorconfig + +# track readme.md in the root (i.e. do NOT ignore it) +!readme.md + +# ignore all files that start with ~ +~* + +# ignore OS generated files +ehthumbs.db +Thumbs.db + +# ignore Editor files +*.sublime-project +*.sublime-workspace +*.komodoproject + +# ignore log files and databases +*.log +*.sql +*.sqlite + +# ignore compiled files +*.com +*.class +*.dll +*.exe +*.o +*.so + +# ignore packaged files +*.7z +*.dmg +*.gz +*.iso +*.jar +*.rar +*.tar +*.zip + +# ignore node/grunt dependency directories +node_modules/ + +# bower +bower_components + +code-coverage + +# no map files +*.map + +vendor +!/src/vendor + +tests/coverage diff --git a/autoloader.php b/autoloader.php new file mode 100644 index 0000000..3031885 --- /dev/null +++ b/autoloader.php @@ -0,0 +1,25 @@ + [db-host] [wp-version] [skip-database-creation]" + exit 1 +fi + +DB_NAME=$1 +DB_USER=$2 +DB_PASS=$3 +DB_HOST=${4-localhost} +WP_VERSION=${5-latest} +SKIP_DB_CREATE=${6-false} + +WP_TESTS_DIR=${WP_TESTS_DIR-/tmp/wordpress-tests-lib} +WP_CORE_DIR=${WP_CORE_DIR-/tmp/wordpress/} + +download() { + if [ `which curl` ]; then + curl -s "$1" > "$2"; + elif [ `which wget` ]; then + wget -nv -O "$2" "$1" + fi +} + +if [[ $WP_VERSION =~ [0-9]+\.[0-9]+(\.[0-9]+)? ]]; then + WP_TESTS_TAG="$WP_VERSION" +elif [[ $WP_VERSION == 'nightly' || $WP_VERSION == 'trunk' ]]; then + WP_TESTS_TAG="trunk" +else + # http serves a single offer, whereas https serves multiple. we only want one + download http://api.wordpress.org/core/version-check/1.7/ /tmp/wp-latest.json + grep '[0-9]+\.[0-9]+(\.[0-9]+)?' /tmp/wp-latest.json + LATEST_VERSION=$(grep -o '"version":"[^"]*' /tmp/wp-latest.json | sed 's/"version":"//') + if [[ -z "$LATEST_VERSION" ]]; then + echo "Latest WordPress version could not be found" + exit 1 + fi + WP_TESTS_TAG="$LATEST_VERSION" +fi + +set -ex + +install_wp() { + + if [ -d $WP_CORE_DIR ]; then + return; + fi + + mkdir -p $WP_CORE_DIR + + if [[ $WP_VERSION == 'nightly' || $WP_VERSION == 'trunk' ]]; then + mkdir -p /tmp/wordpress-nightly + download https://wordpress.org/nightly-builds/wordpress-latest.zip /tmp/wordpress-nightly/wordpress-nightly.zip + unzip -q /tmp/wordpress-nightly/wordpress-nightly.zip -d /tmp/wordpress-nightly/ + mv /tmp/wordpress-nightly/wordpress/* $WP_CORE_DIR + else + if [ $WP_VERSION == 'latest' ]; then + local ARCHIVE_NAME='latest' + else + local ARCHIVE_NAME="wordpress-$WP_VERSION" + fi + download https://wordpress.org/${ARCHIVE_NAME}.tar.gz /tmp/wordpress.tar.gz + tar --strip-components=1 -zxmf /tmp/wordpress.tar.gz -C $WP_CORE_DIR + fi + + download https://raw.github.com/markoheijnen/wp-mysqli/master/db.php $WP_CORE_DIR/wp-content/db.php +} + +install_test_suite() { + # portable in-place argument for both GNU sed and Mac OSX sed + if [[ $(uname -s) == 'Darwin' ]]; then + local ioption='-i .bak' + else + local ioption='-i' + fi + + # set up testing suite if it doesn't yet exist + if [ ! -d $WP_TESTS_DIR ]; then + # set up testing suite + mkdir -p $WP_TESTS_DIR + git clone --depth=50 --branch="${WP_TESTS_TAG}" https://github.com/WordPress/wordpress-develop ${WP_TESTS_DIR}_2 + mv ${WP_TESTS_DIR}_2/tests/phpunit/includes/ ${WP_TESTS_DIR}/includes + mv ${WP_TESTS_DIR}_2/tests/phpunit/data/ ${WP_TESTS_DIR}/data + rm -rf ${WP_TESTS_DIR}_2/ + fi + + if [ ! -f wp-tests-config.php ]; then + download https://develop.svn.wordpress.org/tags/${WP_TESTS_TAG}/wp-tests-config-sample.php "$WP_TESTS_DIR"/wp-tests-config.php + # remove all forward slashes in the end + WP_CORE_DIR=$(echo $WP_CORE_DIR | sed "s:/\+$::") + sed $ioption "s:dirname( __FILE__ ) . '/src/':'$WP_CORE_DIR/':" "$WP_TESTS_DIR"/wp-tests-config.php + sed $ioption "s/youremptytestdbnamehere/$DB_NAME/" "$WP_TESTS_DIR"/wp-tests-config.php + sed $ioption "s/yourusernamehere/$DB_USER/" "$WP_TESTS_DIR"/wp-tests-config.php + sed $ioption "s/yourpasswordhere/$DB_PASS/" "$WP_TESTS_DIR"/wp-tests-config.php + sed $ioption "s|localhost|${DB_HOST}|" "$WP_TESTS_DIR"/wp-tests-config.php + fi + +} + +install_db() { + + if [ ${SKIP_DB_CREATE} = "true" ]; then + return 0 + fi + + # parse DB_HOST for port or socket references + local PARTS=(${DB_HOST//\:/ }) + local DB_HOSTNAME=${PARTS[0]}; + local DB_SOCK_OR_PORT=${PARTS[1]}; + local EXTRA="" + + if ! [ -z $DB_HOSTNAME ] ; then + if [ $(echo $DB_SOCK_OR_PORT | grep -e '^[0-9]\{1,\}$') ]; then + EXTRA=" --host=$DB_HOSTNAME --port=$DB_SOCK_OR_PORT --protocol=tcp" + elif ! [ -z $DB_SOCK_OR_PORT ] ; then + EXTRA=" --socket=$DB_SOCK_OR_PORT" + elif ! [ -z $DB_HOSTNAME ] ; then + EXTRA=" --host=$DB_HOSTNAME --protocol=tcp" + fi + fi + + # create database + if [ ! -d /var/lib/mysql/${DB_NAME} ] ; then + mysqladmin create ${DB_NAME} --user="${DB_USER}" --password="${DB_PASS}"${EXTRA} + fi +} + +install_wp +install_test_suite +install_db diff --git a/bitbucket-pipelines.yml b/bitbucket-pipelines.yml new file mode 100644 index 0000000..bc90933 --- /dev/null +++ b/bitbucket-pipelines.yml @@ -0,0 +1,17 @@ +image: oktupol/bitbucket-pipelines-php71 + +pipelines: + branches: + master: + - step: + name: unit test + caches: + - composer + - vendor-directory + script: + - composer install --no-interaction --no-progress --prefer-dist --ignore-platform-reqs + - ./vendor/bin/phpunit --testsuite "OWC OpenPub Base Plugin Test Suite" + +definitions: + caches: + vendor-directory: vendor \ No newline at end of file diff --git a/composer.json b/composer.json new file mode 100644 index 0000000..cad4218 --- /dev/null +++ b/composer.json @@ -0,0 +1,28 @@ +{ + "name": "plugin/openpub-base", + "description": "OpenPub base plugin", + "authors": [ + { + "name": "Edwin Siebel", + "email": "edwin@yard.nl", + "homepage": "https://www.yarddigital.nl" + } + ], + "type": "wordpress-plugin", + "require": { + "php": ">=7.0" + }, + "require-dev": { + "mockery/mockery": "1.0.*", + "phpunit/phpunit": "~6.0", + "10up/wp_mock": "dev-master", + "phpmd/phpmd": "@stable" + }, + "autoload": { + "psr-4": { + "OWC\\OpenPub\\Base\\": "./src/Base", + "OWC\\OpenPub\\Base\\Tests\\": "./tests" + } + } +} + diff --git a/composer.lock b/composer.lock new file mode 100644 index 0000000..4b88966 --- /dev/null +++ b/composer.lock @@ -0,0 +1,2072 @@ +{ + "_readme": [ + "This file locks the dependencies of your project to a known state", + "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", + "This file is @generated automatically" + ], + "content-hash": "bf54499ee41764b049a5923b903706f0", + "packages": [], + "packages-dev": [ + { + "name": "10up/wp_mock", + "version": "dev-master", + "source": { + "type": "git", + "url": "https://github.com/10up/wp_mock.git", + "reference": "68e90e4d8d8302f0b7f73e41b38624709dc174ea" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/10up/wp_mock/zipball/68e90e4d8d8302f0b7f73e41b38624709dc174ea", + "reference": "68e90e4d8d8302f0b7f73e41b38624709dc174ea", + "shasum": "" + }, + "require": { + "antecedent/patchwork": "^2.1", + "mockery/mockery": "^1.0", + "php": ">=7.0", + "phpunit/phpunit": ">=6.0" + }, + "require-dev": { + "behat/behat": "^3.0", + "satooshi/php-coveralls": "^1.0", + "sebastian/comparator": ">=1.2.3" + }, + "type": "library", + "autoload": { + "psr-4": { + "WP_Mock\\": "./php/WP_Mock" + }, + "classmap": [ + "php/WP_Mock.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "GPL-2.0+" + ], + "description": "A mocking library to take the pain out of unit testing for WordPress", + "time": "2018-04-27T16:32:09+00:00" + }, + { + "name": "antecedent/patchwork", + "version": "2.1.8", + "source": { + "type": "git", + "url": "https://github.com/antecedent/patchwork.git", + "reference": "3bb81ace3914c220aa273d1c0603d5e1b454c0d7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/antecedent/patchwork/zipball/3bb81ace3914c220aa273d1c0603d5e1b454c0d7", + "reference": "3bb81ace3914c220aa273d1c0603d5e1b454c0d7", + "shasum": "" + }, + "require": { + "php": ">=5.4.0" + }, + "type": "library", + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ignas Rudaitis", + "email": "ignas.rudaitis@gmail.com" + } + ], + "description": "Method redefinition (monkey-patching) functionality for PHP.", + "homepage": "http://patchwork2.org/", + "keywords": [ + "aop", + "aspect", + "interception", + "monkeypatching", + "redefinition", + "runkit", + "testing" + ], + "time": "2018-02-19T18:52:50+00:00" + }, + { + "name": "doctrine/instantiator", + "version": "1.1.0", + "source": { + "type": "git", + "url": "https://github.com/doctrine/instantiator.git", + "reference": "185b8868aa9bf7159f5f953ed5afb2d7fcdc3bda" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/instantiator/zipball/185b8868aa9bf7159f5f953ed5afb2d7fcdc3bda", + "reference": "185b8868aa9bf7159f5f953ed5afb2d7fcdc3bda", + "shasum": "" + }, + "require": { + "php": "^7.1" + }, + "require-dev": { + "athletic/athletic": "~0.1.8", + "ext-pdo": "*", + "ext-phar": "*", + "phpunit/phpunit": "^6.2.3", + "squizlabs/php_codesniffer": "^3.0.2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.2.x-dev" + } + }, + "autoload": { + "psr-4": { + "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Marco Pivetta", + "email": "ocramius@gmail.com", + "homepage": "http://ocramius.github.com/" + } + ], + "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", + "homepage": "https://github.com/doctrine/instantiator", + "keywords": [ + "constructor", + "instantiate" + ], + "time": "2017-07-22T11:58:36+00:00" + }, + { + "name": "hamcrest/hamcrest-php", + "version": "v2.0.0", + "source": { + "type": "git", + "url": "https://github.com/hamcrest/hamcrest-php.git", + "reference": "776503d3a8e85d4f9a1148614f95b7a608b046ad" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/hamcrest/hamcrest-php/zipball/776503d3a8e85d4f9a1148614f95b7a608b046ad", + "reference": "776503d3a8e85d4f9a1148614f95b7a608b046ad", + "shasum": "" + }, + "require": { + "php": "^5.3|^7.0" + }, + "replace": { + "cordoval/hamcrest-php": "*", + "davedevelopment/hamcrest-php": "*", + "kodova/hamcrest-php": "*" + }, + "require-dev": { + "phpunit/php-file-iterator": "1.3.3", + "phpunit/phpunit": "~4.0", + "satooshi/php-coveralls": "^1.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0-dev" + } + }, + "autoload": { + "classmap": [ + "hamcrest" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD" + ], + "description": "This is the PHP port of Hamcrest Matchers", + "keywords": [ + "test" + ], + "time": "2016-01-20T08:20:44+00:00" + }, + { + "name": "mockery/mockery", + "version": "1.0", + "source": { + "type": "git", + "url": "https://github.com/mockery/mockery.git", + "reference": "1bac8c362b12f522fdd1f1fa3556284c91affa38" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/mockery/mockery/zipball/1bac8c362b12f522fdd1f1fa3556284c91affa38", + "reference": "1bac8c362b12f522fdd1f1fa3556284c91affa38", + "shasum": "" + }, + "require": { + "hamcrest/hamcrest-php": "~2.0", + "lib-pcre": ">=7.0", + "php": ">=5.6.0" + }, + "require-dev": { + "phpunit/phpunit": "~5.7|~6.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-0": { + "Mockery": "library/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Pádraic Brady", + "email": "padraic.brady@gmail.com", + "homepage": "http://blog.astrumfutura.com" + }, + { + "name": "Dave Marshall", + "email": "dave.marshall@atstsolutions.co.uk", + "homepage": "http://davedevelopment.co.uk" + } + ], + "description": "Mockery is a simple yet flexible PHP mock object framework for use in unit testing with PHPUnit, PHPSpec or any other testing framework. Its core goal is to offer a test double framework with a succinct API capable of clearly defining all possible object operations and interactions using a human readable Domain Specific Language (DSL). Designed as a drop in alternative to PHPUnit's phpunit-mock-objects library, Mockery is easy to integrate with PHPUnit and can operate alongside phpunit-mock-objects without the World ending.", + "homepage": "http://github.com/mockery/mockery", + "keywords": [ + "BDD", + "TDD", + "library", + "mock", + "mock objects", + "mockery", + "stub", + "test", + "test double", + "testing" + ], + "time": "2017-10-06T16:20:43+00:00" + }, + { + "name": "myclabs/deep-copy", + "version": "1.8.1", + "source": { + "type": "git", + "url": "https://github.com/myclabs/DeepCopy.git", + "reference": "3e01bdad3e18354c3dce54466b7fbe33a9f9f7f8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/3e01bdad3e18354c3dce54466b7fbe33a9f9f7f8", + "reference": "3e01bdad3e18354c3dce54466b7fbe33a9f9f7f8", + "shasum": "" + }, + "require": { + "php": "^7.1" + }, + "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" + ], + "time": "2018-06-11T23:09:50+00:00" + }, + { + "name": "pdepend/pdepend", + "version": "2.5.2", + "source": { + "type": "git", + "url": "https://github.com/pdepend/pdepend.git", + "reference": "9daf26d0368d4a12bed1cacae1a9f3a6f0adf239" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/pdepend/pdepend/zipball/9daf26d0368d4a12bed1cacae1a9f3a6f0adf239", + "reference": "9daf26d0368d4a12bed1cacae1a9f3a6f0adf239", + "shasum": "" + }, + "require": { + "php": ">=5.3.7", + "symfony/config": "^2.3.0|^3|^4", + "symfony/dependency-injection": "^2.3.0|^3|^4", + "symfony/filesystem": "^2.3.0|^3|^4" + }, + "require-dev": { + "phpunit/phpunit": "^4.8|^5.7", + "squizlabs/php_codesniffer": "^2.0.0" + }, + "bin": [ + "src/bin/pdepend" + ], + "type": "library", + "autoload": { + "psr-4": { + "PDepend\\": "src/main/php/PDepend" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "description": "Official version of pdepend to be handled with Composer", + "time": "2017-12-13T13:21:38+00:00" + }, + { + "name": "phar-io/manifest", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/phar-io/manifest.git", + "reference": "2df402786ab5368a0169091f61a7c1e0eb6852d0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phar-io/manifest/zipball/2df402786ab5368a0169091f61a7c1e0eb6852d0", + "reference": "2df402786ab5368a0169091f61a7c1e0eb6852d0", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-phar": "*", + "phar-io/version": "^1.0.1", + "php": "^5.6 || ^7.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": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + }, + { + "name": "Sebastian Heuer", + "email": "sebastian@phpeople.de", + "role": "Developer" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "Developer" + } + ], + "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)", + "time": "2017-03-05T18:14:27+00:00" + }, + { + "name": "phar-io/version", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/phar-io/version.git", + "reference": "a70c0ced4be299a63d32fa96d9281d03e94041df" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phar-io/version/zipball/a70c0ced4be299a63d32fa96d9281d03e94041df", + "reference": "a70c0ced4be299a63d32fa96d9281d03e94041df", + "shasum": "" + }, + "require": { + "php": "^5.6 || ^7.0" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + }, + { + "name": "Sebastian Heuer", + "email": "sebastian@phpeople.de", + "role": "Developer" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "Developer" + } + ], + "description": "Library for handling version information and constraints", + "time": "2017-03-05T17:38:23+00:00" + }, + { + "name": "phpdocumentor/reflection-common", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/ReflectionCommon.git", + "reference": "21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6", + "reference": "21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6", + "shasum": "" + }, + "require": { + "php": ">=5.5" + }, + "require-dev": { + "phpunit/phpunit": "^4.6" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": [ + "src" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jaap van Otterdijk", + "email": "opensource@ijaap.nl" + } + ], + "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" + }, + { + "name": "phpdocumentor/reflection-docblock", + "version": "4.3.0", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", + "reference": "94fd0001232e47129dd3504189fa1c7225010d08" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/94fd0001232e47129dd3504189fa1c7225010d08", + "reference": "94fd0001232e47129dd3504189fa1c7225010d08", + "shasum": "" + }, + "require": { + "php": "^7.0", + "phpdocumentor/reflection-common": "^1.0.0", + "phpdocumentor/type-resolver": "^0.4.0", + "webmozart/assert": "^1.0" + }, + "require-dev": { + "doctrine/instantiator": "~1.0.5", + "mockery/mockery": "^1.0", + "phpunit/phpunit": "^6.4" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.x-dev" + } + }, + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": [ + "src/" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mike van Riel", + "email": "me@mikevanriel.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" + }, + { + "name": "phpdocumentor/type-resolver", + "version": "0.4.0", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/TypeResolver.git", + "reference": "9c977708995954784726e25d0cd1dddf4e65b0f7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/9c977708995954784726e25d0cd1dddf4e65b0f7", + "reference": "9c977708995954784726e25d0cd1dddf4e65b0f7", + "shasum": "" + }, + "require": { + "php": "^5.5 || ^7.0", + "phpdocumentor/reflection-common": "^1.0" + }, + "require-dev": { + "mockery/mockery": "^0.9.4", + "phpunit/phpunit": "^5.2||^4.8.24" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": [ + "src/" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mike van Riel", + "email": "me@mikevanriel.com" + } + ], + "time": "2017-07-14T14:27:02+00:00" + }, + { + "name": "phpmd/phpmd", + "version": "2.6.0", + "source": { + "type": "git", + "url": "https://github.com/phpmd/phpmd.git", + "reference": "4e9924b2c157a3eb64395460fcf56b31badc8374" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpmd/phpmd/zipball/4e9924b2c157a3eb64395460fcf56b31badc8374", + "reference": "4e9924b2c157a3eb64395460fcf56b31badc8374", + "shasum": "" + }, + "require": { + "ext-xml": "*", + "pdepend/pdepend": "^2.5", + "php": ">=5.3.9" + }, + "require-dev": { + "phpunit/phpunit": "^4.0", + "squizlabs/php_codesniffer": "^2.0" + }, + "bin": [ + "src/bin/phpmd" + ], + "type": "project", + "autoload": { + "psr-0": { + "PHPMD\\": "src/main/php" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Manuel Pichler", + "email": "github@manuel-pichler.de", + "homepage": "https://github.com/manuelpichler", + "role": "Project Founder" + }, + { + "name": "Other contributors", + "homepage": "https://github.com/phpmd/phpmd/graphs/contributors", + "role": "Contributors" + }, + { + "name": "Marc Würth", + "email": "ravage@bluewin.ch", + "homepage": "https://github.com/ravage84", + "role": "Project Maintainer" + } + ], + "description": "PHPMD is a spin-off project of PHP Depend and aims to be a PHP equivalent of the well known Java tool PMD.", + "homepage": "http://phpmd.org/", + "keywords": [ + "mess detection", + "mess detector", + "pdepend", + "phpmd", + "pmd" + ], + "time": "2017-01-20T14:41:10+00:00" + }, + { + "name": "phpspec/prophecy", + "version": "1.7.6", + "source": { + "type": "git", + "url": "https://github.com/phpspec/prophecy.git", + "reference": "33a7e3c4fda54e912ff6338c48823bd5c0f0b712" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpspec/prophecy/zipball/33a7e3c4fda54e912ff6338c48823bd5c0f0b712", + "reference": "33a7e3c4fda54e912ff6338c48823bd5c0f0b712", + "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" + }, + "require-dev": { + "phpspec/phpspec": "^2.5|^3.2", + "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.7.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-04-18T13:57:24+00:00" + }, + { + "name": "phpunit/php-code-coverage", + "version": "5.3.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-code-coverage.git", + "reference": "c89677919c5dd6d3b3852f230a663118762218ac" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/c89677919c5dd6d3b3852f230a663118762218ac", + "reference": "c89677919c5dd6d3b3852f230a663118762218ac", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-xmlwriter": "*", + "php": "^7.0", + "phpunit/php-file-iterator": "^1.4.2", + "phpunit/php-text-template": "^1.2.1", + "phpunit/php-token-stream": "^2.0.1", + "sebastian/code-unit-reverse-lookup": "^1.0.1", + "sebastian/environment": "^3.0", + "sebastian/version": "^2.0.1", + "theseer/tokenizer": "^1.1" + }, + "require-dev": { + "phpunit/phpunit": "^6.0" + }, + "suggest": { + "ext-xdebug": "^2.5.5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.3.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", + "homepage": "https://github.com/sebastianbergmann/php-code-coverage", + "keywords": [ + "coverage", + "testing", + "xunit" + ], + "time": "2018-04-06T15:36:58+00:00" + }, + { + "name": "phpunit/php-file-iterator", + "version": "1.4.5", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-file-iterator.git", + "reference": "730b01bc3e867237eaac355e06a36b85dd93a8b4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/730b01bc3e867237eaac355e06a36b85dd93a8b4", + "reference": "730b01bc3e867237eaac355e06a36b85dd93a8b4", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.4.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sb@sebastian-bergmann.de", + "role": "lead" + } + ], + "description": "FilterIterator implementation that filters files based on a list of suffixes.", + "homepage": "https://github.com/sebastianbergmann/php-file-iterator/", + "keywords": [ + "filesystem", + "iterator" + ], + "time": "2017-11-27T13:52:08+00:00" + }, + { + "name": "phpunit/php-text-template", + "version": "1.2.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-text-template.git", + "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/31f8b717e51d9a2afca6c9f046f5d69fc27c8686", + "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Simple template engine.", + "homepage": "https://github.com/sebastianbergmann/php-text-template/", + "keywords": [ + "template" + ], + "time": "2015-06-21T13:50:34+00:00" + }, + { + "name": "phpunit/php-timer", + "version": "1.0.9", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-timer.git", + "reference": "3dcf38ca72b158baf0bc245e9184d3fdffa9c46f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/3dcf38ca72b158baf0bc245e9184d3fdffa9c46f", + "reference": "3dcf38ca72b158baf0bc245e9184d3fdffa9c46f", + "shasum": "" + }, + "require": { + "php": "^5.3.3 || ^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sb@sebastian-bergmann.de", + "role": "lead" + } + ], + "description": "Utility class for timing", + "homepage": "https://github.com/sebastianbergmann/php-timer/", + "keywords": [ + "timer" + ], + "time": "2017-02-26T11:10:40+00:00" + }, + { + "name": "phpunit/php-token-stream", + "version": "2.0.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-token-stream.git", + "reference": "791198a2c6254db10131eecfe8c06670700904db" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/791198a2c6254db10131eecfe8c06670700904db", + "reference": "791198a2c6254db10131eecfe8c06670700904db", + "shasum": "" + }, + "require": { + "ext-tokenizer": "*", + "php": "^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^6.2.4" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Wrapper around PHP's tokenizer extension.", + "homepage": "https://github.com/sebastianbergmann/php-token-stream/", + "keywords": [ + "tokenizer" + ], + "time": "2017-11-27T05:48:46+00:00" + }, + { + "name": "phpunit/phpunit", + "version": "6.5.8", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/phpunit.git", + "reference": "4f21a3c6b97c42952fd5c2837bb354ec0199b97b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/4f21a3c6b97c42952fd5c2837bb354ec0199b97b", + "reference": "4f21a3c6b97c42952fd5c2837bb354ec0199b97b", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-json": "*", + "ext-libxml": "*", + "ext-mbstring": "*", + "ext-xml": "*", + "myclabs/deep-copy": "^1.6.1", + "phar-io/manifest": "^1.0.1", + "phar-io/version": "^1.0", + "php": "^7.0", + "phpspec/prophecy": "^1.7", + "phpunit/php-code-coverage": "^5.3", + "phpunit/php-file-iterator": "^1.4.3", + "phpunit/php-text-template": "^1.2.1", + "phpunit/php-timer": "^1.0.9", + "phpunit/phpunit-mock-objects": "^5.0.5", + "sebastian/comparator": "^2.1", + "sebastian/diff": "^2.0", + "sebastian/environment": "^3.1", + "sebastian/exporter": "^3.1", + "sebastian/global-state": "^2.0", + "sebastian/object-enumerator": "^3.0.3", + "sebastian/resource-operations": "^1.0", + "sebastian/version": "^2.0.1" + }, + "conflict": { + "phpdocumentor/reflection-docblock": "3.0.2", + "phpunit/dbunit": "<3.0" + }, + "require-dev": { + "ext-pdo": "*" + }, + "suggest": { + "ext-xdebug": "*", + "phpunit/php-invoker": "^1.1" + }, + "bin": [ + "phpunit" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "6.5.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "The PHP Unit Testing framework.", + "homepage": "https://phpunit.de/", + "keywords": [ + "phpunit", + "testing", + "xunit" + ], + "time": "2018-04-10T11:38:34+00:00" + }, + { + "name": "phpunit/phpunit-mock-objects", + "version": "5.0.7", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git", + "reference": "3eaf040f20154d27d6da59ca2c6e28ac8fd56dce" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/3eaf040f20154d27d6da59ca2c6e28ac8fd56dce", + "reference": "3eaf040f20154d27d6da59ca2c6e28ac8fd56dce", + "shasum": "" + }, + "require": { + "doctrine/instantiator": "^1.0.5", + "php": "^7.0", + "phpunit/php-text-template": "^1.2.1", + "sebastian/exporter": "^3.1" + }, + "conflict": { + "phpunit/phpunit": "<6.0" + }, + "require-dev": { + "phpunit/phpunit": "^6.5" + }, + "suggest": { + "ext-soap": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Mock Object library for PHPUnit", + "homepage": "https://github.com/sebastianbergmann/phpunit-mock-objects/", + "keywords": [ + "mock", + "xunit" + ], + "time": "2018-05-29T13:50:43+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" + ], + "time": "2017-02-14T16:28:37+00:00" + }, + { + "name": "sebastian/code-unit-reverse-lookup", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", + "reference": "4419fcdb5eabb9caa61a27c7a1db532a6b55dd18" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/4419fcdb5eabb9caa61a27c7a1db532a6b55dd18", + "reference": "4419fcdb5eabb9caa61a27c7a1db532a6b55dd18", + "shasum": "" + }, + "require": { + "php": "^5.6 || ^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^5.7 || ^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": "Looks up which function or method a line of code belongs to", + "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/", + "time": "2017-03-04T06:30:41+00:00" + }, + { + "name": "sebastian/comparator", + "version": "2.1.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/comparator.git", + "reference": "34369daee48eafb2651bea869b4b15d75ccc35f9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/34369daee48eafb2651bea869b4b15d75ccc35f9", + "reference": "34369daee48eafb2651bea869b4b15d75ccc35f9", + "shasum": "" + }, + "require": { + "php": "^7.0", + "sebastian/diff": "^2.0 || ^3.0", + "sebastian/exporter": "^3.1" + }, + "require-dev": { + "phpunit/phpunit": "^6.4" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.1.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@2bepublished.at" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Provides the functionality to compare PHP values for equality", + "homepage": "https://github.com/sebastianbergmann/comparator", + "keywords": [ + "comparator", + "compare", + "equality" + ], + "time": "2018-02-01T13:46:46+00:00" + }, + { + "name": "sebastian/diff", + "version": "2.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/diff.git", + "reference": "347c1d8b49c5c3ee30c7040ea6fc446790e6bddd" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/347c1d8b49c5c3ee30c7040ea6fc446790e6bddd", + "reference": "347c1d8b49c5c3ee30c7040ea6fc446790e6bddd", + "shasum": "" + }, + "require": { + "php": "^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^6.2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Kore Nordmann", + "email": "mail@kore-nordmann.de" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Diff implementation", + "homepage": "https://github.com/sebastianbergmann/diff", + "keywords": [ + "diff" + ], + "time": "2017-08-03T08:09:46+00:00" + }, + { + "name": "sebastian/environment", + "version": "3.1.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/environment.git", + "reference": "cd0871b3975fb7fc44d11314fd1ee20925fce4f5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/cd0871b3975fb7fc44d11314fd1ee20925fce4f5", + "reference": "cd0871b3975fb7fc44d11314fd1ee20925fce4f5", + "shasum": "" + }, + "require": { + "php": "^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^6.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.1.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 functionality to handle HHVM/PHP environments", + "homepage": "http://www.github.com/sebastianbergmann/environment", + "keywords": [ + "Xdebug", + "environment", + "hhvm" + ], + "time": "2017-07-01T08:51:00+00:00" + }, + { + "name": "sebastian/exporter", + "version": "3.1.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/exporter.git", + "reference": "234199f4528de6d12aaa58b612e98f7d36adb937" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/234199f4528de6d12aaa58b612e98f7d36adb937", + "reference": "234199f4528de6d12aaa58b612e98f7d36adb937", + "shasum": "" + }, + "require": { + "php": "^7.0", + "sebastian/recursion-context": "^3.0" + }, + "require-dev": { + "ext-mbstring": "*", + "phpunit/phpunit": "^6.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.1.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@2bepublished.at" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" + } + ], + "description": "Provides the functionality to export PHP variables for visualization", + "homepage": "http://www.github.com/sebastianbergmann/exporter", + "keywords": [ + "export", + "exporter" + ], + "time": "2017-04-03T13:19:02+00:00" + }, + { + "name": "sebastian/global-state", + "version": "2.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/global-state.git", + "reference": "e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4", + "reference": "e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4", + "shasum": "" + }, + "require": { + "php": "^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^6.0" + }, + "suggest": { + "ext-uopz": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Snapshotting of global state", + "homepage": "http://www.github.com/sebastianbergmann/global-state", + "keywords": [ + "global state" + ], + "time": "2017-04-27T15:39:26+00:00" + }, + { + "name": "sebastian/object-enumerator", + "version": "3.0.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/object-enumerator.git", + "reference": "7cfd9e65d11ffb5af41198476395774d4c8a84c5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/7cfd9e65d11ffb5af41198476395774d4c8a84c5", + "reference": "7cfd9e65d11ffb5af41198476395774d4c8a84c5", + "shasum": "" + }, + "require": { + "php": "^7.0", + "sebastian/object-reflector": "^1.1.1", + "sebastian/recursion-context": "^3.0" + }, + "require-dev": { + "phpunit/phpunit": "^6.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.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": "Traverses array structures and object graphs to enumerate all referenced objects", + "homepage": "https://github.com/sebastianbergmann/object-enumerator/", + "time": "2017-08-03T12:35:26+00:00" + }, + { + "name": "sebastian/object-reflector", + "version": "1.1.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/object-reflector.git", + "reference": "773f97c67f28de00d397be301821b06708fca0be" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/773f97c67f28de00d397be301821b06708fca0be", + "reference": "773f97c67f28de00d397be301821b06708fca0be", + "shasum": "" + }, + "require": { + "php": "^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^6.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.1-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Allows reflection of object attributes, including inherited and non-public ones", + "homepage": "https://github.com/sebastianbergmann/object-reflector/", + "time": "2017-03-29T09:07:27+00:00" + }, + { + "name": "sebastian/recursion-context", + "version": "3.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/recursion-context.git", + "reference": "5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8", + "reference": "5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8", + "shasum": "" + }, + "require": { + "php": "^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^6.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" + } + ], + "description": "Provides functionality to recursively process PHP variables", + "homepage": "http://www.github.com/sebastianbergmann/recursion-context", + "time": "2017-03-03T06:23:57+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", + "time": "2015-07-28T20:34:47+00:00" + }, + { + "name": "sebastian/version", + "version": "2.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/version.git", + "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/99732be0ddb3361e16ad77b68ba41efc8e979019", + "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019", + "shasum": "" + }, + "require": { + "php": ">=5.6" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library that helps with managing the version number of Git-hosted PHP projects", + "homepage": "https://github.com/sebastianbergmann/version", + "time": "2016-10-03T07:35:21+00:00" + }, + { + "name": "symfony/config", + "version": "v4.1.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/config.git", + "reference": "e57e7b573df9d0eaa8c0152768c708ee7ea2b8e5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/config/zipball/e57e7b573df9d0eaa8c0152768c708ee7ea2b8e5", + "reference": "e57e7b573df9d0eaa8c0152768c708ee7ea2b8e5", + "shasum": "" + }, + "require": { + "php": "^7.1.3", + "symfony/filesystem": "~3.4|~4.0", + "symfony/polyfill-ctype": "~1.8" + }, + "conflict": { + "symfony/finder": "<3.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" + }, + "suggest": { + "symfony/yaml": "To use the yaml reference dumper" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.1-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Config\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Config Component", + "homepage": "https://symfony.com", + "time": "2018-06-20T11:15:17+00:00" + }, + { + "name": "symfony/dependency-injection", + "version": "v4.1.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/dependency-injection.git", + "reference": "e761828a85d7dfc00b927f94ccbe1851ce0b6535" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/e761828a85d7dfc00b927f94ccbe1851ce0b6535", + "reference": "e761828a85d7dfc00b927f94ccbe1851ce0b6535", + "shasum": "" + }, + "require": { + "php": "^7.1.3", + "psr/container": "^1.0" + }, + "conflict": { + "symfony/config": "<4.1.1", + "symfony/finder": "<3.4", + "symfony/proxy-manager-bridge": "<3.4", + "symfony/yaml": "<3.4" + }, + "provide": { + "psr/container-implementation": "1.0" + }, + "require-dev": { + "symfony/config": "~4.1", + "symfony/expression-language": "~3.4|~4.0", + "symfony/yaml": "~3.4|~4.0" + }, + "suggest": { + "symfony/config": "", + "symfony/expression-language": "For using expressions in service container configuration", + "symfony/finder": "For using double-star glob patterns or when GLOB_BRACE portability is required", + "symfony/proxy-manager-bridge": "Generate service proxies to lazy load them", + "symfony/yaml": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.1-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\DependencyInjection\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony DependencyInjection Component", + "homepage": "https://symfony.com", + "time": "2018-06-25T11:12:43+00:00" + }, + { + "name": "symfony/filesystem", + "version": "v4.1.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/filesystem.git", + "reference": "562bf7005b55fd80d26b582d28e3e10f2dd5ae9c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/562bf7005b55fd80d26b582d28e3e10f2dd5ae9c", + "reference": "562bf7005b55fd80d26b582d28e3e10f2dd5ae9c", + "shasum": "" + }, + "require": { + "php": "^7.1.3", + "symfony/polyfill-ctype": "~1.8" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.1-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Filesystem\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Filesystem Component", + "homepage": "https://symfony.com", + "time": "2018-05-30T07:26:09+00:00" + }, + { + "name": "symfony/polyfill-ctype", + "version": "v1.8.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-ctype.git", + "reference": "7cc359f1b7b80fc25ed7796be7d96adc9b354bae" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/7cc359f1b7b80fc25ed7796be7d96adc9b354bae", + "reference": "7cc359f1b7b80fc25ed7796be7d96adc9b354bae", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.8-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Ctype\\": "" + }, + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + }, + { + "name": "Gert de Pagter", + "email": "BackEndTea@gmail.com" + } + ], + "description": "Symfony polyfill for ctype functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "ctype", + "polyfill", + "portable" + ], + "time": "2018-04-30T19:57:29+00:00" + }, + { + "name": "theseer/tokenizer", + "version": "1.1.0", + "source": { + "type": "git", + "url": "https://github.com/theseer/tokenizer.git", + "reference": "cb2f008f3f05af2893a87208fe6a6c4985483f8b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/theseer/tokenizer/zipball/cb2f008f3f05af2893a87208fe6a6c4985483f8b", + "reference": "cb2f008f3f05af2893a87208fe6a6c4985483f8b", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-tokenizer": "*", + "ext-xmlwriter": "*", + "php": "^7.0" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + } + ], + "description": "A small library for converting tokenized PHP source code into XML and potentially other formats", + "time": "2017-04-07T12:08:54+00:00" + }, + { + "name": "webmozart/assert", + "version": "1.3.0", + "source": { + "type": "git", + "url": "https://github.com/webmozart/assert.git", + "reference": "0df1908962e7a3071564e857d86874dad1ef204a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/webmozart/assert/zipball/0df1908962e7a3071564e857d86874dad1ef204a", + "reference": "0df1908962e7a3071564e857d86874dad1ef204a", + "shasum": "" + }, + "require": { + "php": "^5.3.3 || ^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.6", + "sebastian/version": "^1.0.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.3-dev" + } + }, + "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-01-29T19:49:41+00:00" + } + ], + "aliases": [], + "minimum-stability": "stable", + "stability-flags": { + "10up/wp_mock": 20, + "phpmd/phpmd": 0 + }, + "prefer-stable": false, + "prefer-lowest": false, + "platform": { + "php": ">=7.0" + }, + "platform-dev": [] +} diff --git a/config/api.php b/config/api.php new file mode 100644 index 0000000..52edd93 --- /dev/null +++ b/config/api.php @@ -0,0 +1,27 @@ + [ + + 'item' => [ + /** + * Custom field creators. + * + * [ + * 'creator' => CreatesFields::class, + * 'condition' => \Closure + * ] + */ + 'fields' => [ + 'taxonomies' => OWC\OpenPub\Base\RestAPI\ItemFields\TaxonomyField::class, +// 'connected' => OWC\OpenPub\Base\RestAPI\ItemFields\ConnectedField::class, + 'image' => OWC\OpenPub\Base\RestAPI\ItemFields\FeaturedImageField::class, + 'downloads' => OWC\OpenPub\Base\RestAPI\ItemFields\DownloadsField::class, + 'links' => OWC\OpenPub\Base\RestAPI\ItemFields\LinksField::class, + 'synonyms' => OWC\OpenPub\Base\RestAPI\ItemFields\SynonymsField::class, + 'notes' => OWC\OpenPub\Base\RestAPI\ItemFields\NotesField::class, + ] + ], + ] +]; \ No newline at end of file diff --git a/config/core.php b/config/core.php new file mode 100644 index 0000000..bc954a8 --- /dev/null +++ b/config/core.php @@ -0,0 +1,60 @@ + [ + /** + * Global providers. + */ + OWC\OpenPub\Base\Settings\SettingsServiceProvider::class, + OWC\OpenPub\Base\PostType\PostTypeServiceProvider::class, + OWC\OpenPub\Base\Taxonomy\TaxonomyServiceProvider::class, + OWC\OpenPub\Base\PostsToPosts\PostsToPostsServiceProvider::class, + OWC\OpenPub\Base\Metabox\MetaboxServiceProvider::class, + OWC\OpenPub\Base\RestAPI\RestAPIServiceProvider::class, + OWC\OpenPub\Base\Template\TemplateServiceProvider::class, + /** + * Providers specific to the admin. + */ + 'admin' => [ +// OWC\OpenPub\Base\Admin\InterfaceServiceProvider::class + ] + ], + + /** + * Dependencies upon which the plugin relies. + * + * Required: type, label + * Optional: message + * + * Type: plugin + * - Required: file + * - Optional: version + * + * Type: class + * - Required: name + */ + 'dependencies' => [ + [ + 'type' => 'plugin', + 'label' => 'RWMB Metabox', + 'version' => '4.14.0', + 'file' => 'meta-box/meta-box.php' + ], + [ + 'type' => 'plugin', + 'label' => 'Meta Box Group', + 'version' => '1.2.14', + 'file' => 'metabox-group/meta-box-group.php' + ], + [ + 'type' => 'class', + 'label' => 'Extended CPT library', + 'name' => 'Extended_CPT' + ] + ] + +]; \ No newline at end of file diff --git a/config/metaboxes.php b/config/metaboxes.php new file mode 100644 index 0000000..8f98bdd --- /dev/null +++ b/config/metaboxes.php @@ -0,0 +1,95 @@ + [ + 'id' => 'openpub_metadata', + 'title' => __('Data', 'openpub-base'), + 'post_types' => ['openpub-item'], + 'context' => 'normal', + 'priority' => 'high', + 'autosave' => true, + 'fields' => [ + 'general' => [ + 'synonyms' => [ + 'name' => __('Synonyms', 'openpub-base'), + 'desc' => __('Use this option to add an comma separated list of synonyms or related terms', 'openpub-base'), + 'id' => 'openpub_tags', + 'type' => 'textarea', + ], + 'expiration' => [ + 'id' => 'openpub_expirationdate', + 'name' => __('Select end date', 'openpub-base'), + 'type' => 'datetime', + ] + ], + 'links' => [ + 'heading' => [ + 'type' => 'heading', + 'name' => __('Links', 'openpub-base'), + ], + 'links' => [ + 'id' => 'openpub_links_group', + 'type' => 'group', + 'clone' => true, + 'sort_clone' => true, + 'add_button' => __('Add new link', 'openpub-base'), + 'fields' => [ + [ + 'id' => 'openpub_links_title', + 'name' => __('Link title', 'openpub-base'), + 'desc' => __('Use the title to replace the URL', 'openpub-base'), + 'type' => 'text' + ], + [ + 'id' => 'openpub_links_url', + 'name' => __('Link URL', 'openpub-base'), + 'desc' => __('URL including http(s)://', 'openpub-base'), + 'type' => 'text' + ] + ] + ] + ], + 'downloads' => [ + 'heading' => [ + 'type' => 'heading', + 'name' => __('Downloads', 'openpub-base'), + ], + 'downloads' => [ + 'id' => 'openpub_downloads_group', + 'type' => 'group', + 'clone' => true, + 'sort_clone' => true, + 'add_button' => __('Add new download', 'openpub-base'), + 'fields' => [ + [ + 'id' => 'openpub_downloads_title', + 'name' => __('Download title', 'openpub-base'), + 'desc' => __('Use the title to replace the URL', 'openpub-base'), + 'type' => 'text', + ], + [ + 'id' => 'openpub_downloads_url', + 'name' => __('Download URL', 'openpub-base'), + 'desc' => __('URL including http(s)://', 'openpub-base'), + 'type' => 'text', + ] + ] + ] + ], + 'other' => [ + 'heading' => [ + 'type' => 'heading', + 'name' => __('Other', 'openpub-base'), + ], + 'notes' => [ + 'name' => __('Notes', 'openpub-base'), + 'desc' => __('(the law, authority, local regulations, etc.)', 'openpub-base'), + 'id' => 'openpub_notes', + 'type' => 'textarea', + 'cols' => 20, + 'rows' => 5, + ] + ] + ] + ] +]; \ No newline at end of file diff --git a/config/p2p_connections.php b/config/p2p_connections.php new file mode 100644 index 0000000..e9b42eb --- /dev/null +++ b/config/p2p_connections.php @@ -0,0 +1,23 @@ + [ + 'openpub-item' => + [ + 'id' => 'openpub-item', + 'title' => _x('OpenPub item', 'P2P titel', 'openpub-base' ) + ], + 'openpub-owner' => + [ + 'id' => 'openpub-owner', + 'title' => _x('OpenPub owner', 'P2P titel', 'openpub-base') + ] + ], + 'connections' => [ + [ + 'from' => 'openpub-item', + 'to' => 'openpub-item', + 'reciprocal' => false + ], + ] +]; \ No newline at end of file diff --git a/config/posttypes.php b/config/posttypes.php new file mode 100644 index 0000000..1d31613 --- /dev/null +++ b/config/posttypes.php @@ -0,0 +1,69 @@ + [ + 'args' => [ + # Add the post type to the site's main RSS feed: + 'show_in_feed' => false, + # Show all posts on the post type archive: + 'archive' => [ + 'nopaging' => true + ], + 'public' => false, + 'show_ui' => true, + 'supports' => ['title', 'editor', 'thumbnail', 'excerpt', 'revisions'], + 'menu_icon' => 'dashicons-format-aside', + 'show_in_rest' => false, + 'admin_cols' => [], + # Add a dropdown filter to the admin screen: + 'admin_filters' => [ + 'owner' => [ + 'title' => _x('Owner', 'Admin Filter definition', 'openpub-base'), + 'taxonomy' => 'openpub-owner', + ], + 'type' => [ + 'title' => _x('Type', 'Admin Filter definition', 'openpub-base'), + 'taxonomy' => 'openpub-type', + ], + 'audience' => [ + 'title' => _x('Audience', 'Admin Filter definition', 'openpub-base'), + 'taxonomy' => 'openpub-audience', + ], + 'usage' => [ + 'title' => _x('Usage', 'Admin Filter definition', 'openpub-base'), + 'taxonomy' => 'openpub-usage', + ], + 'aspect' => [ + 'title' => _x('Aspect', 'Admin Filter definition', 'openpub-base'), + 'taxonomy' => 'openpub-aspect', + ], + ], + 'labels' => [ + 'singular_name' => _x('OpenPub item', 'post type singular name', 'openpub-base'), + 'menu_name' => _x('OpenPub items', 'admin menu', 'openpub-base'), + 'name_admin_bar' => _x('OpenPub item', 'add new on admin bar', 'openpub-base'), + 'add_new' => _x('Add new OpenPub', '', 'openpub-base'), + 'add_new_item' => __('Add new OpenPub', 'openpub-base'), + 'new_item' => __('New OpenPub', 'openpub-base'), + 'edit_item' => __('Edit OpenPub', 'openpub-base'), + 'view_item' => __('View OpenPub', 'openpub-base'), + 'all_items' => __('All OpenPub items', 'openpub-base'), + 'search_items' => __('Search OpenPub items', 'openpub-base'), + 'parent_item_colon' => __('Parent OpenPub items:', 'openpub-base'), + 'not_found' => __('No OpenPub items found.', 'openpub-base'), + 'not_found_in_trash' => __('No OpenPub items found in trash.', 'openpub-base') + ] + ], + # Override the base names used for labels: + 'names' => [ + 'slug' => 'openpub-item', + 'singular' => _x('OpenPub item', 'Posttype definition', 'openpub-base'), + 'plural' => _x('OpenPub items', 'Posttype definition', 'openpub-base'), + 'name' => _x('OpenPub items', 'post type general name', 'openpub-base') + ] + ] +]; \ No newline at end of file diff --git a/config/rest_api_fields.php b/config/rest_api_fields.php new file mode 100644 index 0000000..b993871 --- /dev/null +++ b/config/rest_api_fields.php @@ -0,0 +1,3 @@ + [ + 'id' => 'general', + 'title' => _x('Portal', 'OpenPub instellingen subpagina', 'openpub-base'), + 'settings_pages' => '_owc_openpub_base_settings', + 'tab' => 'base', + 'fields' => [ + 'portal' => [ + 'portal_url' => [ + 'name' => __('Portal URL','openpub-base'), + 'desc' => __('URL including http(s)://','openpub-base'), + 'id' => 'setting_portal_url', + 'type' => 'text' + ], + 'openpub_item_slug' => [ + 'name' => __('Portal OpenPub item slug','openpub-base'), + 'desc' => __('URL for OpenPub items in the portal, eg "onderwerp"','openpub-base'), + 'id' => 'setting_portal_openpub_item_slug', + 'type' => 'text' + ] + ] + ] + ] +]; \ No newline at end of file diff --git a/config/settings_pages.php b/config/settings_pages.php new file mode 100644 index 0000000..f00d369 --- /dev/null +++ b/config/settings_pages.php @@ -0,0 +1,19 @@ + [ + + 'id' => '_owc_openpub_base_settings', + 'option_name' => '_owc_openpub_base_settings', + 'menu_title' => __('OpenPub settings', 'openpub-base'), + 'icon_url' => 'dashicons-admin-settings', + 'submenu_title' => _x('Base', 'OpenPub settings subpage', 'openpub-base'), + 'position' => 9, + 'columns' => 1, + 'submit_button' => _x('Submit', 'OpenPub settings subpage', 'openpub-base'), + 'tabs' => array( + 'base' => _x('General', 'OpenPub settings tab', 'openpub-base') + ) + ] +]; \ No newline at end of file diff --git a/config/taxonomies.php b/config/taxonomies.php new file mode 100644 index 0000000..d737b39 --- /dev/null +++ b/config/taxonomies.php @@ -0,0 +1,105 @@ + [ + 'object_types' => ['openpub-item'], + 'args' => [ + 'show_in_rest' => false, + 'show_admin_column' => true, + 'capabilities' => [ + // 'manage_terms' => 'manage_openpub_categories', + // 'edit_terms' => 'manage_openpub_categories', + // 'delete_terms' => 'manage_openpub_categories', + // 'assign_terms' => 'edit_openpub_posts' + ] + ], + 'names' => [ + # Override the base names used for labels: + 'singular' => _x('Audience', 'Taxonomy definition', 'openpub-base'), + 'plural' => _x('Audiences', 'Taxonomy definition', 'openpub-base'), + 'slug' => 'openpub-doelgroep' + ] + ], + + 'openpub-type' => [ + 'object_types' => ['openpub-item'], + 'args' => [ + 'show_in_rest' => false, + 'show_admin_column' => true, + 'capabilities' => [ + // 'manage_terms' => 'manage_openpub_categories', + // 'edit_terms' => 'manage_openpub_categories', + // 'delete_terms' => 'manage_openpub_categories', + // 'assign_terms' => 'edit_openpub_posts' + ] + ], + 'names' => [ + # Override the base names used for labels: + 'singular' => _x('Type', 'Taxonomy definition', 'openpub-base'), + 'plural' => _x('Types', 'Taxonomy definition', 'openpub-base'), + 'slug' => 'openpub-type' + ] + ], + + 'openpub-aspect' => [ + 'object_types' => ['openpub-item'], + 'args' => [ + 'show_in_rest' => false, + 'show_admin_column' => true, + 'capabilities' => [ + // 'manage_terms' => 'manage_openpub_categories', + // 'edit_terms' => 'manage_openpub_categories', + // 'delete_terms' => 'manage_openpub_categories', + // 'assign_terms' => 'edit_openpub_posts' + ] + ], + 'names' => [ + # Override the base names used for labels: + 'singular' => _x('Aspect', 'Taxonomy definition', 'openpub-base'), + 'plural' => _x('Aspects', 'Taxonomy definition', 'openpub-base'), + 'slug' => 'openpub-kenmerk' + ] + ], + 'openpub-usage' => [ + 'object_types' => ['openpub-item'], + 'args' => [ + 'show_in_rest' => false, + 'show_admin_column' => true, + 'capabilities' => [ + // 'manage_terms' => 'manage_openpub_categories', + // 'edit_terms' => 'manage_openpub_categories', + // 'delete_terms' => 'manage_openpub_categories', + // 'assign_terms' => 'edit_openpub_posts' + ] + ], + 'names' => [ + # Override the base names used for labels: + 'singular' => _x('Usage', 'Taxonomy definition', 'openpub-base'), + 'plural' => _x('Usages', 'Taxonomy definition', 'openpub-base'), + 'slug' => 'openpub-toepassing' + ] + ], + 'openpub-owner' => [ + 'object_types' => ['openpub-item'], + 'args' => [ + 'show_in_rest' => false, + 'show_admin_column' => true, + 'capabilities' => [ + // 'manage_terms' => 'manage_openpub_categories', + // 'edit_terms' => 'manage_openpub_categories', + // 'delete_terms' => 'manage_openpub_categories', + // 'assign_terms' => 'edit_openpub_posts' + ], + ], + 'names' => [ + # Override the base names used for labels: + 'singular' => _x('Owner', 'Taxonomy definition', 'openpub-base'), + 'plural' => _x('Owners', 'Taxonomy definition', 'openpub-base'), + 'slug' => 'openpub-owner' + ] + ] +]; \ No newline at end of file diff --git a/index.php b/index.php new file mode 100644 index 0000000..e71af0e --- /dev/null +++ b/index.php @@ -0,0 +1 @@ +\n" +"Language-Team: Yard Digital \n" +"Language: nl_NL\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 1.8.7.1\n" +"X-Poedit-Basepath: ..\n" +"X-Poedit-SourceCharset: UTF-8\n" +"X-Poedit-KeywordsList: __;_e;_n:1,2;_x:1,2c;_ex:1,2c;_nx:4c,1,2;esc_attr__;" +"esc_attr_e;esc_attr_x:1,2c;esc_html__;esc_html_e;esc_html_x:1,2c;" +"_n_noop:1,2;_nx_noop:3c,1,2;__ngettext_noop:1,2\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-Poedit-SearchPath-0: .\n" +"X-Poedit-SearchPathExcluded-0: vendor\n" + +#: config/metaboxes.php:6 +msgid "Data" +msgstr "Gegevens" + +#: config/metaboxes.php:14 +msgid "Synonyms" +msgstr "Synoniemen" + +#: config/metaboxes.php:15 +msgid "" +"Use this option to add an comma separated list of synonyms or related terms" +msgstr "" +"Gebruik deze mogelijkheid om een komma gescheiden lijst van synoniemen of " +"gerelateerde termen mee te geven" + +#: config/metaboxes.php:21 +msgid "Select end date" +msgstr "Selecteer een einddatum" + +#: config/metaboxes.php:28 +msgid "Links" +msgstr "Links" + +#: config/metaboxes.php:35 +msgid "Add new link" +msgstr "Voeg nieuwe link toe" + +#: config/metaboxes.php:39 +msgid "Link title" +msgstr "Link titel" + +#: config/metaboxes.php:40 config/metaboxes.php:67 +msgid "Use the title to replace the URL" +msgstr "Wordt gebruikt om de link te tonen ipv de URL" + +#: config/metaboxes.php:45 +msgid "Link URL" +msgstr "Link URL" + +#: config/metaboxes.php:46 config/metaboxes.php:73 config/settings.php:14 +msgid "URL including http(s)://" +msgstr "URL inclusief http(s)://" + +#: config/metaboxes.php:55 +msgid "Downloads" +msgstr "Downloads" + +#: config/metaboxes.php:62 +msgid "Add new download" +msgstr "Voeg nieuwe download toe" + +#: config/metaboxes.php:66 +msgid "Download title" +msgstr "Download titel" + +#: config/metaboxes.php:72 +msgid "Download URL" +msgstr "Download URL" + +#: config/metaboxes.php:82 +msgid "Other" +msgstr "Overig" + +#: config/metaboxes.php:85 +msgid "Notes" +msgstr "Vrij notitieveld" + +#: config/metaboxes.php:86 +msgid "(the law, authority, local regulations, etc.)" +msgstr "(wetgeving, bevoegd gezag, uitvoerder, lokale regelgeving)" + +#: config/p2p_connections.php:8 +msgctxt "P2P titel" +msgid "OpenPub item" +msgstr "OpenPub item" + +#: config/p2p_connections.php:13 +msgctxt "P2P titel" +msgid "OpenPub owner" +msgstr "OpenPub eigenaar" + +#: config/posttypes.php:24 +msgctxt "Admin Filter definition" +msgid "Owner" +msgstr "Eigenaar" + +#: config/posttypes.php:28 +msgctxt "Admin Filter definition" +msgid "Type" +msgstr "Type" + +#: config/posttypes.php:32 +msgctxt "Admin Filter definition" +msgid "Audience" +msgstr "Doelgroep" + +#: config/posttypes.php:36 +msgctxt "Admin Filter definition" +msgid "Usage" +msgstr "Toepassing" + +#: config/posttypes.php:40 +msgctxt "Admin Filter definition" +msgid "Aspect" +msgstr "Kenmerk" + +#: config/posttypes.php:45 +msgctxt "post type singular name" +msgid "OpenPub item" +msgstr "OpenPub item" + +#: config/posttypes.php:46 +msgctxt "admin menu" +msgid "OpenPub items" +msgstr "OpenPub items" + +#: config/posttypes.php:47 +msgctxt "add new on admin bar" +msgid "OpenPub item" +msgstr "OpenPub item" + +#: config/posttypes.php:48 +msgctxt "" +msgid "Add new OpenPub" +msgstr "Add new OpenPub" + +#: config/posttypes.php:49 +msgid "Add new OpenPub" +msgstr "Nieuw OpenPub item" + +#: config/posttypes.php:50 +msgid "New OpenPub" +msgstr "Nieuw OpenPub item" + +#: config/posttypes.php:51 +msgid "Edit OpenPub" +msgstr "Bewerk OpenPub item" + +#: config/posttypes.php:52 +msgid "View OpenPub" +msgstr "Bekijk OpenPub item" + +#: config/posttypes.php:53 +msgid "All OpenPub items" +msgstr "Alle OpenPub items" + +#: config/posttypes.php:54 +msgid "Search OpenPub items" +msgstr "Zoek OpenPub items" + +#: config/posttypes.php:55 +msgid "Parent OpenPub items:" +msgstr "Hoofd OpenPub items:" + +#: config/posttypes.php:56 +msgid "No OpenPub items found." +msgstr "Geen OpenPub items gevonden." + +#: config/posttypes.php:57 +msgid "No OpenPub items found in trash." +msgstr "Geen OpenPub items gevonden in prullenbak." + +#: config/posttypes.php:63 +msgctxt "Posttype definition" +msgid "OpenPub item" +msgstr "OpenPub item" + +#: config/posttypes.php:64 +msgctxt "Posttype definition" +msgid "OpenPub items" +msgstr "OpenPub items" + +#: config/posttypes.php:65 +msgctxt "post type general name" +msgid "OpenPub items" +msgstr "OpenPub items" + +#: config/settings.php:7 +msgctxt "OpenPub instellingen subpagina" +msgid "Portal" +msgstr "Portal" + +#: config/settings.php:13 +msgid "Portal URL" +msgstr "Portal URL" + +#: config/settings.php:19 +msgid "Portal OpenPub item slug" +msgstr "Portal OpenPub item slug" + +#: config/settings.php:20 +msgid "URL for OpenPub items in the portal, eg \"onderwerp\"" +msgstr "URL voor OpenPub items in de portal, bv \"onderwerp\"" + +#: config/settings_pages.php:9 +msgid "OpenPub settings" +msgstr "OpenPub instellingen" + +#: config/settings_pages.php:11 +msgctxt "OpenPub settings subpage" +msgid "Base" +msgstr "Basis" + +#: config/settings_pages.php:14 +msgctxt "OpenPub settings subpage" +msgid "Submit" +msgstr "Opslaan" + +#: config/settings_pages.php:16 +msgctxt "OpenPub settings tab" +msgid "General" +msgstr "Algemeen" + +#: config/taxonomies.php:22 +msgctxt "Taxonomy definition" +msgid "Audience" +msgstr "Doelgroep" + +#: config/taxonomies.php:23 +msgctxt "Taxonomy definition" +msgid "Audiences" +msgstr "Doelgroepen" + +#: config/taxonomies.php:42 +msgctxt "Taxonomy definition" +msgid "Type" +msgstr "Type" + +#: config/taxonomies.php:43 +msgctxt "Taxonomy definition" +msgid "Types" +msgstr "Typen" + +#: config/taxonomies.php:62 +msgctxt "Taxonomy definition" +msgid "Aspect" +msgstr "Kenmerk" + +#: config/taxonomies.php:63 +msgctxt "Taxonomy definition" +msgid "Aspects" +msgstr "Kenmerken" + +#: config/taxonomies.php:81 +msgctxt "Taxonomy definition" +msgid "Usage" +msgstr "Toepassing" + +#: config/taxonomies.php:82 +msgctxt "Taxonomy definition" +msgid "Usages" +msgstr "Toepassingen" + +#: config/taxonomies.php:100 +msgctxt "Taxonomy definition" +msgid "Owner" +msgstr "Eigenaar" + +#: config/taxonomies.php:101 +msgctxt "Taxonomy definition" +msgid "Owners" +msgstr "Eigenaren" + +#: src/Base/Admin/InterfaceServiceProvider.php:34 +msgid "View OpenPub item in portal" +msgstr "Bekijken OpenPub item in portal" + +#: src/Base/Admin/InterfaceServiceProvider.php:53 +msgctxt "preview button text" +msgid "View in Portal" +msgstr "Bekijken in portal" + +#: src/Base/Admin/InterfaceServiceProvider.php:79 +#, php-format +msgid "View “%s”" +msgstr "Bekijk “%s”" + +#: src/Base/Admin/InterfaceServiceProvider.php:80 +msgctxt "Preview text in OpenPub list" +msgid "View in Portal" +msgstr "Bekijken in portal" + +#: src/Base/Foundation/DependencyChecker.php:61 +msgid "The following plugins are required to use the OpenPub:" +msgstr "De volgende plugins zijn vereist om gebruik te maken van de OpenPub:" + +#: src/Base/Foundation/DependencyChecker.php:96 +msgid "Class does not exist" +msgstr "Class bestaat niet" + +#: src/Base/Foundation/DependencyChecker.php:110 +msgid "Inactive" +msgstr "Inactief" + +#: src/Base/Foundation/DependencyChecker.php:118 +msgid "Minimal version:" +msgstr "Minimale versie:" + +#: src/Base/RestAPI/ItemFields/ConnectedField.php:48 +#, php-format +msgid "Connection type \"%s\" does not exist" +msgstr "Verbindingstype \"%s\" bestaat niet" + +#~ msgid "This link does not work, go to our website: %s" +#~ msgstr "Deze link werkt niet, bekijk onze website: %s" diff --git a/languages/openpub-base.pot b/languages/openpub-base.pot new file mode 100644 index 0000000..95123ea --- /dev/null +++ b/languages/openpub-base.pot @@ -0,0 +1,66 @@ +# Loco Gettext template +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: OWC OpenPub\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2018-06-28 10:35+0200\n" +"POT-Revision-Date: Fri Nov 27 2015 13:26:26 GMT+0100 (W. Europe Standard Time)\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: \n" +"Language-Team: Yard Digital \n" +"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Poedit-SourceCharset: UTF-8\n" +"X-Poedit-Basepath: ../src\n" +"X-Poedit-KeywordsList: _:1;gettext:1;dgettext:2;ngettext:1,2;dngettext:2,3;__:1;" +"_e:1;_n:1,2;_n_noop:1,2;_nc:1,2;__ngettext:1,2;__ngettext_noop:1,2;_x:1,2c;" +"_ex:1,2c;_nx:1,2,4c;_nx_noop:1,2,3c;_n_js:1,2;_nx_js:1,2,3c;esc_attr__:1;" +"esc_html__:1;esc_attr_e:1;esc_html_e:1;esc_attr_x:1,2c;esc_html_x:1,2c\n" +"X-Generator: Poedit 1.8.7.1\n" +"X-Poedit-SearchPath-0: .\n" +"X-Poedit-SearchPathExcluded-0: ../assets\n" +"X-Poedit-SearchPathExcluded-1: ../node_modules\n" +"X-Poedit-SearchPathExcluded-2: ../vendor\n" + +#: Base/Admin/InterfaceServiceProvider.php:34 +msgid "View OpenPub item in portal" +msgstr "" + +#: Base/Admin/InterfaceServiceProvider.php:53 +msgctxt "preview button text" +msgid "View in Portal" +msgstr "" + +#: Base/Admin/InterfaceServiceProvider.php:79 +#, php-format +msgid "View “%s”" +msgstr "" + +#: Base/Admin/InterfaceServiceProvider.php:80 +msgctxt "Preview text in OpenPub list" +msgid "View in Portal" +msgstr "" + +#: Base/Foundation/DependencyChecker.php:61 +msgid "The following plugins are required to use the OpenPub:" +msgstr "" + +#: Base/Foundation/DependencyChecker.php:96 +msgid "Class does not exist" +msgstr "" + +#: Base/Foundation/DependencyChecker.php:110 +msgid "Inactive" +msgstr "" + +#: Base/Foundation/DependencyChecker.php:118 +msgid "Minimal version:" +msgstr "" + +#: Base/RestAPI/ItemFields/ConnectedField.php:48 +#, php-format +msgid "Connection type \"%s\" does not exist" +msgstr "" diff --git a/license.txt b/license.txt new file mode 100644 index 0000000..94a0453 --- /dev/null +++ b/license.txt @@ -0,0 +1,621 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS diff --git a/openpub-base.php b/openpub-base.php new file mode 100644 index 0000000..53e810d --- /dev/null +++ b/openpub-base.php @@ -0,0 +1,71 @@ +boot(); +}, 10); diff --git a/phpcs.xml.dist b/phpcs.xml.dist new file mode 100644 index 0000000..2c9e091 --- /dev/null +++ b/phpcs.xml.dist @@ -0,0 +1,17 @@ + + + Generally-applicable sniffs for WordPress plugins + + + + + + + . + + + + + */node_modules/* + */vendor/* + diff --git a/phpunit.xml b/phpunit.xml new file mode 100644 index 0000000..41a92d2 --- /dev/null +++ b/phpunit.xml @@ -0,0 +1,31 @@ + + + + ./tests/Unit + + + + + ./src + + ./src/vendor + + + + + + + \ No newline at end of file diff --git a/src/Base/Admin/InterfaceServiceProvider.php b/src/Base/Admin/InterfaceServiceProvider.php new file mode 100644 index 0000000..b41c5ed --- /dev/null +++ b/src/Base/Admin/InterfaceServiceProvider.php @@ -0,0 +1,87 @@ +plugin->loader->addFilter('admin_bar_menu', $this, 'filterAdminbarMenu', 999); + $this->plugin->loader->addFilter('get_sample_permalink_html', $this, 'filterGetSamplePermalinkHtml', 10, 5); + $this->plugin->loader->addAction('page_row_actions', $this, 'actionModifyPageRowActions', 999, 2); + } + + /** + * Action to edit link to modify current 'OpenPub-item' with deeplink to corresponding Portal onderwerp + * href-node => http://gembur.dev/wp/wp-admin/post.php?post=74&action=edit + * + * @param $wpAdminBar + */ + public function filterAdminbarMenu(WP_Admin_Bar $wpAdminBar) + { + $viewNode = $wpAdminBar->get_node('view'); + if ( ! empty($viewNode) ) { + + global $post; + + if ( get_post_type($post) === 'openpub-item' ) { + $portalUrl = esc_url(trailingslashit($this->plugin->settings['_owc_setting_portal_url']) . trailingslashit($this->plugin->settings['_owc_setting_portal_openpub_item_slug']) . $post->post_name); + $viewNode->href = $portalUrl; + $viewNode->title = __('View OpenPub item in portal', 'openpub-base'); + $wpAdminBar->add_node($viewNode); + } + } + } + + /** + * @param $return + * @param $postId + * @param $newTitle + * @param $newSlug + * @param $post + * + * @return string + */ + public function filterGetSamplePermalinkHtml($return, $postId, $newTitle, $newSlug, $post) + { + if ( 'openpub-item' == $post->post_type ) { + $portalUrl = esc_url(trailingslashit($this->plugin->settings['_owc_setting_portal_url']) . trailingslashit($this->plugin->settings['_owc_setting_portal_openpub_item_slug']) . $post->post_name); + $buttonText = _x('View in Portal', 'preview button text', 'openpub-base'); + $buttonHtml = sprintf('', $portalUrl, $buttonText, $buttonText); + $return .= $buttonHtml; + } + + return $return; + } + + /** + * Action to edit post row actions to modify current 'OpenPub-item' with deeplink to corresponding Portal onderwerp + * + * @param $actions + * @param $post + * + * @return + */ + public function actionModifyPageRowActions($actions, $post) + { + if ( ! empty($actions['view']) && $post->post_type == 'openpub-item' ) { + + $portalUrl = esc_url(trailingslashit($this->plugin->settings['_owc_setting_portal_url']) . trailingslashit($this->plugin->settings['_owc_setting_portal_openpub_item_slug']) . $post->post_name); + + $actions['view'] = sprintf( + '%s', + $portalUrl, + /* translators: %s: post title */ + esc_attr(sprintf(__('View “%s”', 'openpub-base'), $post->post_title)), + _x('View in Portal', 'Preview text in OpenPub list', 'openpub-base') + ); + } + + return $actions; + } + +} \ No newline at end of file diff --git a/src/Base/Exceptions/PropertyNotExistsException.php b/src/Base/Exceptions/PropertyNotExistsException.php new file mode 100644 index 0000000..89053df --- /dev/null +++ b/src/Base/Exceptions/PropertyNotExistsException.php @@ -0,0 +1,10 @@ +items = $items; + $this->path = $path; + } + + /** + * Boot up the configuration repository. + */ + public function boot() + { + $this->scanDirectory($this->getPath()); + } + + /** + * Retrieve a specific config value from the configuration repository. + * + * @param $setting + * + * @return array|mixed + */ + public function get($setting) + { + if ( ! $setting) { + return $this->all(); + } + + $parts = explode('.', $setting); + + $current = $this->items; + + foreach ($parts as $part) { + $current = $current[$part]; + } + + return $current; + } + + /** + * Set a given configuration value. + * + * @param array|string $key + * @param mixed $value + * + * @return void + */ + public function set($key, $value = null) + { + $keys = is_array($key) ? $key : [ $key => $value ]; + + $tempItems = &$this->items; + + foreach ($keys as $key => $value) { + + if (in_array($key, $this->protectedNodes)) { + continue; + } + + $parts = explode('.', $key); + while (count($parts) > 1) { + + $part = array_shift($parts); + // If the key doesn't exist at this depth, we will just create an empty array + // to hold the next value, allowing us to create the arrays to hold final + // values at the correct depth. Then we'll keep digging into the array. + if ( ! isset($tempItems[$part]) || ! is_array($tempItems[$part])) { + $tempItems[$part] = []; + } + $tempItems = &$tempItems[$part]; + } + + $tempItems[array_shift($parts)] = $value; + } + } + + /** + * Return all config values. + * + * @return array + */ + public function all() + { + return $this->items; + } + + /** + * Get the path where the files will be fetched from. + * + * @return string + */ + public function getPath() + { + return $this->path; + } + + /** + * Sets the path where the config files are fetched from. + * + * @param $path + */ + public function setPath($path) + { + $this->path = $path; + } + + /** + * @param array $nodes + */ + public function setProtectedNodes($nodes = []) + { + $this->protectedNodes = $nodes; + } + + /** + * @param $path + */ + private function scanDirectory($path) + { + $files = glob($path.'/*', GLOB_NOSORT); + + foreach ($files as $file) { + + $fileType = filetype($file); + + if ($fileType == "dir") { + $this->scanDirectory($file); + } else { + $name = str_replace('.php', '', basename($file)); + $value = include $file; + + // If its in the first directory just add the file. + if ($path == $this->path) { + $this->items[$name] = $value; + continue; + } + + // Get the path from the starting path. + $path = str_replace($this->path.'/', '', $path); + + // Build an array from the path. + $items = []; + $items[$name] = $value; + foreach (array_reverse(explode('/', $path)) as $key) { + $items = [ $key => $items ]; + } + + // Merge it recursively into items + $this->items = array_merge_recursive($this->items, $items); + } + } + } +} \ No newline at end of file diff --git a/src/Base/Foundation/DependencyChecker.php b/src/Base/Foundation/DependencyChecker.php new file mode 100644 index 0000000..0195112 --- /dev/null +++ b/src/Base/Foundation/DependencyChecker.php @@ -0,0 +1,140 @@ +dependencies = $dependencies; + } + + /** + * Determines if the dependencies are not met. + * + * @return bool + */ + public function failed(): bool + { + foreach ($this->dependencies as $dependency) { + switch ($dependency['type']) { + case 'class': + $this->checkClass($dependency); + break; + case 'plugin': + $this->checkPlugin($dependency); + break; + } + } + + return count($this->failed) > 0; + } + + /** + * Notifies the administrator which plugins need to be enabled, + * or which plugins have the wrong version. + */ + public function notify() + { + add_action('admin_notices', function () { + $list = '

'.__('The following plugins are required to use the OpenPub:', + 'openpub-base').'

    '; + + foreach ($this->failed as $dependency) { + $info = isset($dependency['message']) ? ' ('.$dependency['message'].')' : ''; + $list .= sprintf('
  1. %s%s
  2. ', $dependency['label'], $info); + } + + $list .= '
'; + + printf('

%s

', $list); + }); + } + + /** + * Marks a dependency as failed. + * + * @param array $dependency + * @param string $defaultMessage + */ + private function markFailed(array $dependency, string $defaultMessage) + { + $this->failed[] = array_merge([ + 'message' => $dependency['message'] ?? $defaultMessage + ], $dependency); + } + + /** + * + * + * @param array $dependency + */ + private function checkClass(array $dependency) + { + if ( ! class_exists($dependency['name'])) { + $this->markFailed($dependency, __('Class does not exist', 'openpub-base')); + + return; + } + } + + /** + * Check if a plugin is enabled and has the correct version. + * + * @param array $dependency + */ + private function checkPlugin(array $dependency) + { + if ( ! is_plugin_active($dependency['file'])) { + $this->markFailed($dependency, __('Inactive', 'openpub-base')); + + return; + } + + // If there is a version lock set on the dependency... + if (isset($dependency['version'])) { + if ( ! $this->checkVersion($dependency)) { + $this->markFailed($dependency, __('Minimal version:', 'openpub-base').' '.$dependency['version'].''); + } + } + } + + /** + * Checks the installed version of the plugin. + * + * @param array $dependency + * + * @return bool + */ + private function checkVersion(array $dependency): bool + { + $file = file_get_contents(WP_PLUGIN_DIR.'/'.$dependency['file']); + + preg_match('/^(?: ?\* ?Version: ?)(.*)$/m', $file, $matches); + $version = isset($matches[1]) ? str_replace(' ', '', $matches[1]) : '0.0.0'; + + return version_compare($version, $dependency['version'], '>='); + } + +} \ No newline at end of file diff --git a/src/Base/Foundation/Hooks.php b/src/Base/Foundation/Hooks.php new file mode 100644 index 0000000..0c8ecc7 --- /dev/null +++ b/src/Base/Foundation/Hooks.php @@ -0,0 +1,86 @@ +actions = $this->add($this->actions, $hook, $component, $callback, $priority, $acceptedArgs); + } + + /** + * Add a new filter to the collection to be registered with WordPress. + * + * @since 2.0.0 + * + * @param string $hook The name of the WordPress filter that is being registered. + * @param object $component A reference to the instance of the object on which the filter is defined. + * @param string $callback The name of the function definition on the $component. + * @param int $priority Optional. he priority at which the function should be fired. Default is 10. + * @param int $acceptedArgs Optional. The number of arguments that should be passed to the $callback. + * Default is 1 + */ + public function addFilter($hook, $component, $callback, $priority = 10, $acceptedArgs = 1) + { + $this->filters = $this->add($this->filters, $hook, $component, $callback, $priority, $acceptedArgs); + } + + /** + * A utility function that is used to register the actions and hooks into a single + * collection. + * + * @since 2.0.0 + * + * @param array $hooks The collection of hooks that is being registered (that is, actions or filters). + * @param string $hook The name of the WordPress filter that is being registered. + * @param object $component A reference to the instance of the object on which the filter is defined. + * @param string $callback The name of the function definition on the $component. + * @param int $priority The priority at which the function should be fired. + * @param int $acceptedArgs The number of arguments that should be passed to the $callback. + * + * @return array The collection of actions and filters registered with WordPress. + */ + protected function add($hooks, $hook, $component, $callback, $priority, $acceptedArgs) + { + + $hooks[] = [ + 'hook' => $hook, + 'component' => $component, + 'callback' => $callback, + 'priority' => $priority, + 'accepted_args' => $acceptedArgs + ]; + + return $hooks; + + } + + /** + * Register the filters and actions with WordPress. + * + * @since 2.0.0 + */ + public function register() + { + + foreach ($this->filters as $hook) { + add_filter($hook['hook'], [ $hook['component'], $hook['callback'] ], $hook['priority'], + $hook['accepted_args']); + } + + foreach ($this->actions as $hook) { + add_action($hook['hook'], [ $hook['component'], $hook['callback'] ], $hook['priority'], + $hook['accepted_args']); + } + + } + +} \ No newline at end of file diff --git a/src/Base/Foundation/Plugin.php b/src/Base/Foundation/Plugin.php new file mode 100644 index 0000000..8f606f5 --- /dev/null +++ b/src/Base/Foundation/Plugin.php @@ -0,0 +1,198 @@ +rootPath = $rootPath; + load_plugin_textdomain($this->getName(), false, $this->getName().'/languages/'); + + $this->loader = new Loader; + + $this->config = new Config($this->rootPath.'/config'); + $this->config->setProtectedNodes([ 'core' ]); + $this->config->boot(); + + $this->addStartUpHooks(); + $this->addTearDownHooks(); + } + + /** + * Boot the plugin. + * + * @hook plugins_loaded + * + * @return bool + */ + public function boot(): bool + { + $dependencyChecker = new DependencyChecker($this->config->get('core.dependencies')); + + if ($dependencyChecker->failed()) { + $dependencyChecker->notify(); + deactivate_plugins(plugin_basename($this->rootPath.'/'.$this->getName().'.php')); + + return false; + } + + // Set up service providers + $this->callServiceProviders('register'); + + if (is_admin()) { + $this->callServiceProviders('register', 'admin'); + $this->callServiceProviders('boot', 'admin'); + } + + $this->callServiceProviders('boot'); + + // Register the Hook loader. + $this->loader->addAction('init', $this, 'filterPlugin', 4); + $this->loader->register(); + + return true; + } + + public function filterPlugin() + { + do_action('owc/'.self::NAME.'/plugin', $this); + } + + /** + * Call method on service providers. + * + * @param string $method + * @param string $key + * + * @throws \Exception + */ + public function callServiceProviders($method, $key = '') + { + $offset = $key ? "core.providers.{$key}" : 'core.providers'; + $services = $this->config->get($offset); + + foreach ($services as $service) { + if (is_array($service)) { + continue; + } + + $service = new $service($this); + + if ( ! $service instanceof ServiceProvider) { + throw new \Exception('Provider must be an instance of ServiceProvider.'); + } + + if (method_exists($service, $method)) { + $service->$method(); + } + } + } + + /** + * Get the name of the plugin. + * + * @return string + */ + public function getName() + { + return static::NAME; + } + + /** + * Get the version of the plugin. + * + * @return string + */ + public function getVersion() + { + return static::VERSION; + } + + /** + * Return root path of plugin. + * + * @return string + */ + public function getRootPath(): string + { + return $this->rootPath; + } + + /** + * Startup hooks to initialize the plugin. + */ + protected function addStartUpHooks() + { + /** + * This hook registers a plugin function to be run when the plugin is activated. + */ + register_activation_hook(__FILE__, [ Hooks::class, 'pluginActivation' ]); + + /** + * This hook is run immediately after any plugin is activated, and may be used to detect the activation of plugins. + * If a plugin is silently activated (such as during an update), this hook does not fire. + */ + add_action('activated_plugin', [ Hooks::class, 'pluginActivated' ], 10, 2); + } + + /** + * Teardown hooks to cleanup or uninstall the plugin. + */ + protected function addTearDownHooks() + { + /** + * This hook is run immediately after any plugin is deactivated, and may be used to detect the deactivation of other plugins. + */ + add_action('deactivated_plugin', [ Hooks::class, 'pluginDeactivated' ], 10, 2); + + /** + * This hook registers a plugin function to be run when the plugin is deactivated. + */ + register_deactivation_hook(__FILE__, [ Hooks::class, 'pluginDeactivation' ]); + + /** + * Registers the uninstall hook that will be called when the user clicks on the uninstall link that calls for the plugin to uninstall itself. + * The link won’t be active unless the plugin hooks into the action. + */ + register_uninstall_hook(__FILE__, [ Hooks::class, 'uninstallPlugin' ]); + } + +} \ No newline at end of file diff --git a/src/Base/Foundation/ServiceProvider.php b/src/Base/Foundation/ServiceProvider.php new file mode 100644 index 0000000..6ac8cfa --- /dev/null +++ b/src/Base/Foundation/ServiceProvider.php @@ -0,0 +1,25 @@ +plugin = $plugin; + } + + /** + * Register the service provider. + */ + public abstract function register(); + +} \ No newline at end of file diff --git a/src/Base/Metabox/MetaboxBaseServiceProvider.php b/src/Base/Metabox/MetaboxBaseServiceProvider.php new file mode 100644 index 0000000..83a9981 --- /dev/null +++ b/src/Base/Metabox/MetaboxBaseServiceProvider.php @@ -0,0 +1,45 @@ +processFieldGroup($fieldGroup)); + } + $metabox['fields'] = $fields; + + return $metabox; + } + + private function processFieldGroup($fieldGroup) + { + + $fields = []; + foreach ( $fieldGroup as $field ) { + + $fields[] = $this->addPrefix($field); + } + + return $fields; + } + + private function addPrefix($field) + { + + if ( isset($field['id']) ) { + $field['id'] = self::PREFIX . $field['id']; + } + + return $field; + } +} \ No newline at end of file diff --git a/src/Base/Metabox/MetaboxServiceProvider.php b/src/Base/Metabox/MetaboxServiceProvider.php new file mode 100644 index 0000000..3006f30 --- /dev/null +++ b/src/Base/Metabox/MetaboxServiceProvider.php @@ -0,0 +1,31 @@ +plugin->loader->addFilter('rwmb_meta_boxes', $this, 'registerMetaboxes', 10, 1); + } + + /** + * register metaboxes. + * + * @param $rwmbMetaboxes + * + * @return array + */ + public function registerMetaboxes($rwmbMetaboxes) + { + $configMetaboxes = $this->plugin->config->get('metaboxes'); + $metaboxes = []; + + foreach ( $configMetaboxes as $metabox ) { + $metaboxes[] = $this->processMetabox($metabox); + } + + return array_merge($rwmbMetaboxes, apply_filters("owc/openpub-base/before-register-metaboxes", $metaboxes)); + } +} \ No newline at end of file diff --git a/src/Base/Models/Item.php b/src/Base/Models/Item.php new file mode 100644 index 0000000..245adef --- /dev/null +++ b/src/Base/Models/Item.php @@ -0,0 +1,12 @@ +getProperty('globalFields')->class == __CLASS__ ) { + throw new PropertyNotExistsException(sprintf('Property $globalFields must be present on derived class %s.', + static::class)); + } + } + + /** + * Get all the items from the database. + * + * @return array + */ + public function all(): array + { + $args = array_merge($this->queryArgs, [ + 'post_type' => [$this->posttype] + ]); + + $this->query = new WP_Query($args); + + return array_map([$this, 'transform'], $this->getQuery()->posts); + } + + /** + * Find a particular openpub item by ID. + * + * @param int $id + * + * @return array|null + */ + public function find(int $id) + { + + $args = array_merge($this->queryArgs, [ + 'p' => $id, + 'post_type' => [$this->posttype] + ]); + + $this->query = new WP_Query($args); + + if ( empty($this->getQuery()->posts) ) { + return null; + } + + return $this->transform(reset($this->getQuery()->posts)); + } + + /** + * Get the WP_Query object. + * + * @return null|WP_Query + */ + public function getQuery() + { + return $this->query; + } + + /** + * Add additional query arguments. + * + * @param array $args + * + * @return $this + */ + public function query(array $args) + { + $this->queryArgs = array_merge($this->queryArgs, $args); + + return $this; + } + + /** + * Hide a particular key from the request. + * + * @param array $keys + * + * @return $this + */ + public function hide(array $keys) + { + $this->hidden = array_merge($this->hidden, $keys); + + return $this; + } + + /** + * Dynamically add additional fields to the model. + * + * @param string $key + * @param CreatesFields $creator + * + * @return $this + */ + public function addField(string $key, CreatesFields $creator) + { + $this->fields[ $key ] = $creator; + + return $this; + } + + /** + * Adds a new field to the + * + * @param string $key + * @param CreatesFields $creator + * @param Closure|null $conditional + * + * @return void + */ + public static function addGlobalField(string $key, CreatesFields $creator, Closure $conditional = null) + { + static::$globalFields[] = [ + 'key' => $key, + 'creator' => $creator, + 'conditional' => $conditional + ]; + } + + /** + * Get all defined global fields of the Model. + * + * @return array + */ + public static function getGlobalFields(): array + { + uasort(static::$globalFields, function($a, $b) { + return ( $a['key'] < $b['key'] ) ? - 1 : 1; + }); + + return static::$globalFields; + } + + /** + * Transform a single WP_Post item. + * + * @param WP_Post $post + * + * @return array + */ + public function transform(WP_Post $post) + { + $data = [ + 'id' => $post->ID, + 'title' => $post->post_title, + 'content' => apply_filters('the_content', $post->post_content), + 'excerpt' => $post->post_excerpt, + 'date' => $post->post_date + ]; + + $data = $this->assignFields($data, $post); + + return $data; + } + + /** + * Assign fields to the data array. + * + * @param array $data + * @param WP_Post $post + * + * @return array + */ + protected function assignFields(array $data, WP_Post $post) + { + // Assign global fields. + foreach ( static::getGlobalFields() as $field ) { + if ( in_array($field['key'], $this->hidden) ) { + continue; + } + + if ( is_null($field['conditional']) ) { + // If the field has no conditional set we will add it + $data[ $field['key'] ] = $field['creator']->create($post); + } else { + // Check if the conditional matches. + if ( $field['conditional']($post) ) { + $data[ $field['key'] ] = $field['creator']->create($post); + } + } + } + + // Assign dynamic fields. + foreach ( $this->fields as $key => $creator ) { + $data[ $key ] = $creator->create($post); + } + + return $data; + } + +} diff --git a/src/Base/PostType/PostTypeServiceProvider.php b/src/Base/PostType/PostTypeServiceProvider.php new file mode 100644 index 0000000..d74cb8c --- /dev/null +++ b/src/Base/PostType/PostTypeServiceProvider.php @@ -0,0 +1,39 @@ +plugin->loader->addAction('init', $this, 'registerPostTypes'); + } + + /** + * register custom posttypes. + */ + public function registerPostTypes() + { + + if (function_exists('register_extended_post_type')) { + + $this->configPostTypes = $this->plugin->config->get('posttypes'); + foreach ($this->configPostTypes as $postTypeName => $postType) { + + // Examples of registering post types: http://johnbillion.com/extended-cpts/ + register_extended_post_type($postTypeName, $postType['args'], $postType['names']); + } + } + } +} \ No newline at end of file diff --git a/src/Base/PostsToPosts/PostsToPostsServiceProvider.php b/src/Base/PostsToPosts/PostsToPostsServiceProvider.php new file mode 100644 index 0000000..b5e8b10 --- /dev/null +++ b/src/Base/PostsToPosts/PostsToPostsServiceProvider.php @@ -0,0 +1,83 @@ + false, + 'reciprocal' => true, + 'sortable' => 'any', + 'cardinality' => 'many-to-many', + 'duplicate_connections' => false + ]; + + public function register() + { + + $this->plugin->loader->addAction('init', $this, 'registerPostsToPostsConnections'); + $this->plugin->loader->addFilter('p2p_connectable_args', $this, 'filterP2PConnectableArgs', 10); + } + + /** + * register P2P connections + */ + public function registerPostsToPostsConnections() + { + if ( function_exists('p2p_register_connection_type') ) { + + $posttypesInfo = $this->plugin->config->get('p2p_connections.posttypes_info'); + $defaultConnectionArgs = apply_filters('owc/openpub-base/p2p-connection-defaults', $this->connectionDefaults); + $connections = $this->plugin->config->get('p2p_connections.connections'); + + foreach ( $connections as $connectionArgs ) { + + $args = array_merge($defaultConnectionArgs, $connectionArgs); + + $connectionType = [ + 'id' => $posttypesInfo[ $connectionArgs['from'] ]['id'] . '_to_' . $posttypesInfo[ $connectionArgs['to'] ]['id'], + 'from' => $connectionArgs['from'], + 'to' => $connectionArgs['to'], + 'sortable' => $args['sortable'], + 'admin_column' => 'any', + 'from_labels' => [ + 'column_title' => $posttypesInfo[ $connectionArgs['to'] ]['title'] + ], + 'title' => [ + 'from' => 'Koppel met een ' . $posttypesInfo[ $connectionArgs['to'] ]['title'], + 'to' => 'Koppel met een ' . $posttypesInfo[ $connectionArgs['from'] ]['title'] + ], + 'can_create_post' => $args['can_create_post'], + 'reciprocal' => $args['reciprocal'], + ]; + + if ( $connectionArgs['from'] == $connectionArgs['to'] ) { + $connectionType['title']['to'] = ''; + $connectionType['admin_box'] = 'from'; + } + + $connectionType = apply_filters("owc/openpub-base/before-register-p2p-connection/{$posttypesInfo[ $connectionArgs['from'] ]['id']}/{$posttypesInfo[ $connectionArgs['to'] ]['id']}", $connectionType ); + + p2p_register_connection_type($connectionType); + } + } + } + + /* + * method for changing default P2P behaviour. Override by adding additional filter with higher priority (=larger number) + */ + public function filterP2PConnectableArgs($args) + { + $args['orderby'] = 'title'; + $args['order'] = 'asc'; + $args['p2p:per_page'] = 25; + + return $args; + } +} \ No newline at end of file diff --git a/src/Base/RestAPI/Controllers/BaseController.php b/src/Base/RestAPI/Controllers/BaseController.php new file mode 100644 index 0000000..b0b4057 --- /dev/null +++ b/src/Base/RestAPI/Controllers/BaseController.php @@ -0,0 +1,65 @@ +plugin = $plugin; + } + + /** + * Merges a paginator, based on a WP_Query, inside a data arary. + * + * @param array $data + * @param WP_Query $query + * + * @return array + */ + protected function addPaginator(array $data, WP_Query $query): array + { + $page = $query->get('paged'); + $page = $page == 0 ? 1 : $page; + + return array_merge([ + 'data' => $data + ], [ + 'pagination' => [ + 'total_count' => (int) $query->found_posts, + 'total_pages' => $query->max_num_pages, + 'current_page' => $page, + 'limit' => $query->get('posts_per_page') + ] + ]); + } + + /** + * Get the paginator query params for a given query. + * + * @param WP_REST_Request $request + * @param int $limit + * + * @return array + */ + protected function getPaginatorParams(WP_REST_Request $request, int $limit = 10) + { + return [ + 'posts_per_page' => $request->get_param('limit') ?: $limit, + 'paged' => $request->get_param('page') ?: 0 + ]; + } + +} \ No newline at end of file diff --git a/src/Base/RestAPI/Controllers/ItemController.php b/src/Base/RestAPI/Controllers/ItemController.php new file mode 100644 index 0000000..1d9c251 --- /dev/null +++ b/src/Base/RestAPI/Controllers/ItemController.php @@ -0,0 +1,88 @@ +query(apply_filters('owc/openpub/rest-api/items/query', $this->getPaginatorParams($request))) + ->query([ + 'meta_query' => [ + 'relation' => 'OR', + [ + 'key' => '_owc_openpub_expirationdate', + 'value' => date("Y-m-d h:i:s"), + 'compare' => '>=', + 'type' => 'DATETIME' + ], + [ + 'key' => '_owc_openpub_expirationdate', + 'compare' => 'NOT EXISTS' + ] + ] + ]); + + $data = $items->all(); + $query = $items->getQuery(); + + return $this->addPaginator($data, $query); + } + + /** + * Get an individual post item. + * + * @param WP_REST_Request $request $request + * + * @return array|WP_Error + * @throws \OWC\OpenPub\Base\Exceptions\PropertyNotExistsException + * @throws \ReflectionException + */ + public function getItem(WP_REST_Request $request) + { + $id = (int)$request->get_param('id'); + + $item = ( new Item ) + ->query(apply_filters('owc/openpub/rest-api/items/query/single', [])) + ->query([ + 'meta_query' => [ + 'relation' => 'OR', + [ + 'key' => '_owc_openpub_expirationdate', + 'value' => date("Y-m-d h:i:s"), + 'compare' => '>=', + 'type' => 'DATETIME' + ], + [ + 'key' => '_owc_openpub_expirationdate', + 'compare' => 'NOT EXISTS' + ] + ] + ]) + ->find($id); + + if ( ! $item ) { + return new WP_Error('no_item_found', sprintf('Item with ID "%d" not found', $id), [ + 'status' => 404 + ]); + } + + return $item; + } + +} \ No newline at end of file diff --git a/src/Base/RestAPI/ItemFields/ConnectedField.php b/src/Base/RestAPI/ItemFields/ConnectedField.php new file mode 100644 index 0000000..39d825c --- /dev/null +++ b/src/Base/RestAPI/ItemFields/ConnectedField.php @@ -0,0 +1,63 @@ +plugin->config->get('p2p_connections.connections'), function ($connection) { + return in_array('openpub-item', $connection, true); + }); + + $result = []; + + foreach ($connections as $connection) { + $type = $connection['from'].'_to_'.$connection['to']; + $result[$type] = $this->getConnectedItems($post->ID, $type); + } + + return $result; + } + + /** + * Get connected items of a post, for a specific connection type. + * + * @param int $postID + * @param string $type + * + * @return array + */ + protected function getConnectedItems(int $postID, string $type): array + { + $connection = p2p_type($type); + + if ( ! $connection) { + return [ + 'error' => sprintf(__('Connection type "%s" does not exist', 'openpub-base'), $type) + ]; + } + + return array_map(function (WP_Post $post) { + return [ + 'id' => $post->ID, + 'title' => $post->post_title, + 'slug' => $post->post_name, + 'excerpt' => $post->post_excerpt, + 'date' => $post->post_date + ]; + }, $connection->get_connected($postID)->posts); + } + +} \ No newline at end of file diff --git a/src/Base/RestAPI/ItemFields/DownloadsField.php b/src/Base/RestAPI/ItemFields/DownloadsField.php new file mode 100644 index 0000000..d1410c4 --- /dev/null +++ b/src/Base/RestAPI/ItemFields/DownloadsField.php @@ -0,0 +1,42 @@ + esc_attr(strip_tags($download['openpub_downloads_title'])), + 'url' => esc_url($download['openpub_downloads_url']) + ]; + }, $this->getDownloads($post)); + } + + /** + * Get downloads of a post, if URL & title are present. + * + * @param WP_Post $post + * + * @return array + */ + private function getDownloads(WP_Post $post) + { + return array_filter(get_post_meta($post->ID, '_owc_openpub_downloads_group', true) ?: [], function ($download) { + return ! empty($download['openpub_downloads_url']) && ! empty($download['openpub_downloads_title']); + }); + } + +} \ No newline at end of file diff --git a/src/Base/RestAPI/ItemFields/FeaturedImageField.php b/src/Base/RestAPI/ItemFields/FeaturedImageField.php new file mode 100644 index 0000000..4450ffb --- /dev/null +++ b/src/Base/RestAPI/ItemFields/FeaturedImageField.php @@ -0,0 +1,70 @@ +ID)) { + return []; + } + + $id = get_post_thumbnail_id($post->ID); + $attachment = get_post($id); + $imageSize = 'large'; + + $result = []; + + $result['title'] = $attachment->post_title; + $result['description'] = $attachment->post_content; + $result['caption'] = $attachment->post_excerpt; + $result['alt'] = get_post_meta($attachment->ID, '_wp_attachment_image_alt', true); + + $meta = $this->getAttachmentMeta($id); + + $result['rendered'] = wp_get_attachment_image($id, $imageSize); + $result['sizes'] = wp_get_attachment_image_sizes($id, $imageSize, $meta); + $result['srcset'] = wp_get_attachment_image_srcset($id, $imageSize, $meta); + $result['meta'] = $meta; + + return $result; + } + + /** + * Get meta data of an attachment. + * + * @param $id + * + * @return array + */ + private function getAttachmentMeta($id): array + { + $meta = wp_get_attachment_metadata($id, false); + + if (empty($meta['sizes'])) { + return []; + } + + foreach (array_keys($meta['sizes']) as $size) { + $src = wp_get_attachment_image_src($id, $size); + $meta['sizes'][$size]['url'] = $src[0]; + } + + unset($meta['image_meta']); + + return $meta; + } + +} \ No newline at end of file diff --git a/src/Base/RestAPI/ItemFields/LinksField.php b/src/Base/RestAPI/ItemFields/LinksField.php new file mode 100644 index 0000000..c6e6199 --- /dev/null +++ b/src/Base/RestAPI/ItemFields/LinksField.php @@ -0,0 +1,42 @@ + esc_attr(strip_tags($link['openpub_links_title'])), + 'url' => esc_url($link['openpub_links_url']) + ]; + }, $this->getLinks($post)); + } + + /** + * Get links of a post, if URL & title are present. + * + * @param WP_Post $post + * + * @return array + */ + private function getLinks(WP_Post $post) + { + return array_filter(get_post_meta($post->ID, '_owc_openpub_links_group', true) ?: [], function ($link) { + return ! empty($link['openpub_links_url']) && ! empty($link['openpub_links_title']); + }); + } + +} \ No newline at end of file diff --git a/src/Base/RestAPI/ItemFields/NotesField.php b/src/Base/RestAPI/ItemFields/NotesField.php new file mode 100644 index 0000000..ba1f2e8 --- /dev/null +++ b/src/Base/RestAPI/ItemFields/NotesField.php @@ -0,0 +1,33 @@ +getNotes($post)); + } + + /** + * Get notes of a post. + * + * @param WP_Post $post + * + * @return string + */ + private function getNotes(WP_Post $post) + { + return get_post_meta($post->ID, '_owc_openpub_notes', true) ?: ''; + } +} \ No newline at end of file diff --git a/src/Base/RestAPI/ItemFields/SynonymsField.php b/src/Base/RestAPI/ItemFields/SynonymsField.php new file mode 100644 index 0000000..af2784a --- /dev/null +++ b/src/Base/RestAPI/ItemFields/SynonymsField.php @@ -0,0 +1,33 @@ +getSynonyms($post))); + } + + /** + * Get synonyms of a post, if URL & title are present. + * + * @param WP_Post $post + * + * @return string + */ + private function getSynonyms(WP_Post $post) + { + return get_post_meta($post->ID, '_owc_openpub_tags', true) ?: ''; + } +} \ No newline at end of file diff --git a/src/Base/RestAPI/ItemFields/TaxonomyField.php b/src/Base/RestAPI/ItemFields/TaxonomyField.php new file mode 100644 index 0000000..6aecf74 --- /dev/null +++ b/src/Base/RestAPI/ItemFields/TaxonomyField.php @@ -0,0 +1,54 @@ +plugin->config->get('taxonomies')) as $taxonomy) { + $result[$taxonomy] = $this->getTerms($post->ID, $taxonomy); + } + + return $result; + } + + /** + * Get terms of a taxonomy to which the post is connected. + * + * @param int $postID + * @param string $taxonomy + * + * @return array + */ + private function getTerms(int $postID, string $taxonomy): array + { + $terms = wp_get_post_terms($postID, $taxonomy); + + if (is_wp_error($terms)) { + return []; + } + + return array_map(function ($term) { + return [ + 'id' => $term->term_id, + 'name' => $term->name, + 'slug' => $term->slug + ]; + }, $terms); + } + +} \ No newline at end of file diff --git a/src/Base/RestAPI/RestAPIServiceProvider.php b/src/Base/RestAPI/RestAPIServiceProvider.php new file mode 100644 index 0000000..e718b41 --- /dev/null +++ b/src/Base/RestAPI/RestAPIServiceProvider.php @@ -0,0 +1,78 @@ +plugin->loader->addFilter('rest_api_init', $this, 'registerRoutes'); + $this->plugin->loader->addFilter('owc/config-expander/rest-api/whitelist', $this, 'whitelist', 10, 1); + + $this->registerModelFields(); + } + + /** + * Register routes on the rest API. + * + * @return void + */ + public function registerRoutes() + { + register_rest_route($this->namespace, 'items', [ + 'methods' => 'GET', + 'callback' => [new ItemController($this->plugin), 'getItems'], + ]); + + register_rest_route($this->namespace, 'items/(?P\d+)', [ + 'methods' => 'GET', + 'callback' => [new ItemController($this->plugin), 'getItem'], + ]); + } + + /** + * Whitelist endpoints within Config Expander. + * + * @param $whitelist + * + * @return array + */ + public function whitelist($whitelist): array + { + // Remove default root endpoint + unset($whitelist['wp/v2']); + + $whitelist[ $this->namespace ] = [ + 'endpoint_stub' => '/' . $this->namespace, + 'methods' => ['GET'] + ]; + + return $whitelist; + } + + /** + * Register fields for all configured posttypes. + */ + private function registerModelFields() + { + // Add global fields for all Models. + foreach ( $this->plugin->config->get('api.models') as $posttype => $data ) { + foreach ( $data['fields'] as $key => $creator ) { + $class = '\OWC\OpenPub\Base\Models\\' . ucfirst($posttype); + if ( class_exists($class) ) { + $class::addGlobalField($key, new $creator($this->plugin)); + } + } + } + } + +} \ No newline at end of file diff --git a/src/Base/RestAPI/RestOpenPubtemPostsController.php b/src/Base/RestAPI/RestOpenPubtemPostsController.php new file mode 100644 index 0000000..620449d --- /dev/null +++ b/src/Base/RestAPI/RestOpenPubtemPostsController.php @@ -0,0 +1,45 @@ + 404]); + + return $response; + } + + $post = $this->get_post($request['id']); + if ( is_wp_error($post) ) { + return $post; + } + + $data = $this->prepare_item_for_response($post, $request); + $response = rest_ensure_response($data); + + if ( is_post_type_viewable(get_post_type_object($post->post_type)) ) { + $response->link_header('alternate', get_permalink($post->ID), ['type' => 'text/html']); + } + + return $response; + } +} \ No newline at end of file diff --git a/src/Base/Settings/SettingsServiceProvider.php b/src/Base/Settings/SettingsServiceProvider.php new file mode 100644 index 0000000..78584ef --- /dev/null +++ b/src/Base/Settings/SettingsServiceProvider.php @@ -0,0 +1,59 @@ +plugin->loader->addFilter('mb_settings_pages', $this, 'registerSettingsPage', 10, 1); + $this->plugin->loader->addFilter('rwmb_meta_boxes', $this, 'registerSettings', 10, 1); + $this->plugin->loader->addAction('admin_init', $this, 'getSettingsOption'); + } + + /** + * + */ + public function registerSettingsPage($rwmbSettingsPages) + { + + $settingsPages = $this->plugin->config->get('settings_pages'); + + return array_merge($rwmbSettingsPages, $settingsPages); + } + + /** + * register metaboxes for settings page + * + * @param $rwmbMetaboxes + * + * @return array + */ + public function registerSettings($rwmbMetaboxes) + { + $configMetaboxes = $this->plugin->config->get('settings'); + $metaboxes = []; + + foreach ($configMetaboxes as $metabox) { + + $metaboxes[] = $this->processMetabox($metabox); + } + + return array_merge($rwmbMetaboxes, apply_filters("owc/openpub-base/before-register-settings", $metaboxes)); + } + + public function getSettingsOption() + { + //TODO implement better way of retrieving settings (used in InterfaceServiceProvider) + $defaultSettings = [ + '_owc_setting_portal_url' => '', + '_owc_setting_portal_openpub_item_slug' => '' + ]; + + $this->plugin->settings = wp_parse_args(get_option(self::PREFIX.'openpub_base_settings'), $defaultSettings); + } +} \ No newline at end of file diff --git a/src/Base/Support/CreatesFields.php b/src/Base/Support/CreatesFields.php new file mode 100644 index 0000000..46d1140 --- /dev/null +++ b/src/Base/Support/CreatesFields.php @@ -0,0 +1,35 @@ +plugin = $plugin; + } + + /** + * Create an additional field on an array. + * + * @param WP_Post $post + * + * @return mixed + */ + abstract public function create(WP_Post $post); + +} \ No newline at end of file diff --git a/src/Base/Taxonomy/TaxonomyServiceProvider.php b/src/Base/Taxonomy/TaxonomyServiceProvider.php new file mode 100644 index 0000000..cd6484f --- /dev/null +++ b/src/Base/Taxonomy/TaxonomyServiceProvider.php @@ -0,0 +1,37 @@ +plugin->loader->addAction('init', $this, 'registerTaxonomies'); + } + + /** + * Register custom taxonomies via extended_cpts + */ + public function registerTaxonomies() + { + if ( function_exists('register_extended_taxonomy') ) { + + $this->configTaxonomies = $this->plugin->config->get('taxonomies'); + foreach ( $this->configTaxonomies as $taxonomyName => $taxonomy ) { + + // Examples of registering taxonomies: http://johnbillion.com/extended-cpts/ + register_extended_taxonomy($taxonomyName, $taxonomy['object_types'], $taxonomy['args'], $taxonomy['names']); + } + } + } +} \ No newline at end of file diff --git a/src/Base/Template/TemplateServiceProvider.php b/src/Base/Template/TemplateServiceProvider.php new file mode 100644 index 0000000..3d32548 --- /dev/null +++ b/src/Base/Template/TemplateServiceProvider.php @@ -0,0 +1,24 @@ +plugin->loader->addAction('template_redirect', $this, 'redirectAllButAdmin', 10); + } + + public function redirectAllButAdmin() + { + if ( ! ( is_admin() || wp_doing_ajax() || is_feed() ) ) { + + if ( wp_redirect('https://www.openwebconcept.nl/') ) { + exit(); + }; + } + } +} \ No newline at end of file diff --git a/tests/Unit/Base/Admin/InterfaceServiceProviderTest.php b/tests/Unit/Base/Admin/InterfaceServiceProviderTest.php new file mode 100644 index 0000000..80367b9 --- /dev/null +++ b/tests/Unit/Base/Admin/InterfaceServiceProviderTest.php @@ -0,0 +1,96 @@ +config = $config; + $plugin->loader = m::mock(Loader::class); + + $service = new InterfaceServiceProvider($plugin); + + $plugin->loader->shouldReceive('addFilter')->withArgs([ + 'admin_bar_menu', + $service, + 'filterAdminbarMenu', + 999 + ])->once(); + + $plugin->loader->shouldReceive('addFilter')->withArgs([ + 'get_sample_permalink_html', + $service, + 'filterGetSamplePermalinkHtml', + 10, + 5 + ])->once(); + + $plugin->loader->shouldReceive('addAction')->withArgs([ + 'page_row_actions', + $service, + 'actionModifyPageRowActions', + 999, + 2 + ])->once(); + + $service->register(); + + $this->assertTrue(true); + } + + /** @test */ + public function check_filter_get_sample_permalink_html_methods() + { + $config = m::mock(Config::class); + $plugin = m::mock(Plugin::class); + + $plugin->config = $config; + $plugin->loader = m::mock(Loader::class); + $plugin->settings = [ + '_owc_setting_portal_url' => 'http://owc-openpub.test', + '_owc_setting_portal_openpub_item_slug' => 'onderwerp' + ]; + + $service = new InterfaceServiceProvider($plugin); + + \WP_Mock::userFunction('trailingslashit', [ + 'times' => '2', + 'return' => function() { return func_get_arg(0).'/'; } + ] + ); + + $return = ''; + + $post = new \stdClass; + $post->post_type = 'openpub-item'; + $post->post_name = 'test-openpub-item'; + + $button = ''; + + $postId = $newTitle = $newSlug = null; + + $this->assertEquals( $return . $button, $service->filterGetSamplePermalinkHtml($return, $postId, $newTitle, $newSlug, $post)); + } +} diff --git a/tests/Unit/Base/Foundation/DependencyCheckerTest.php b/tests/Unit/Base/Foundation/DependencyCheckerTest.php new file mode 100644 index 0000000..c66bc37 --- /dev/null +++ b/tests/Unit/Base/Foundation/DependencyCheckerTest.php @@ -0,0 +1,126 @@ + 'plugin', + 'label' => 'Dependency #1', + 'file' => 'test-plugin/test-plugin.php' + ] + ]; + + $checker = new DependencyChecker($dependencies); + + \WP_Mock::userFunction('is_plugin_active') + ->withArgs([ 'test-plugin/test-plugin.php' ]) + ->once() + ->andReturn(false); + + $this->assertTrue($checker->failed()); + } + + /** @test */ + public function it_succeeds_when_no_dependencies_are_set() + { + $checker = new DependencyChecker([]); + + \WP_Mock::userFunction('is_plugin_active') + ->never(); + + $this->assertFalse($checker->failed()); + } + + /** + * @dataProvider wrongVersions + * @test + */ + public function it_fails_when_plugin_is_active_but_versions_mismatch($version) + { + $dependencies = [ + [ + 'type' => 'plugin', + 'label' => 'Dependency #1', + 'file' => 'pluginstub.php', // tests/Unit/pluginstub.php + 'version' => $version // Version in pluginstub.php is 1.1.5 + ] + ]; + + $checker = new DependencyChecker($dependencies); + + \WP_Mock::userFunction('is_plugin_active') + ->withArgs([ 'pluginstub.php' ]) + ->once() + ->andReturn(true); + + $this->assertTrue($checker->failed()); + } + + /** + * @dataProvider correctVersions + * @test + */ + public function it_succeeds_when_plugin_is_active_and_versions_match($version) + { + $dependencies = [ + [ + 'type' => 'plugin', + 'label' => 'Dependency #1', + 'file' => 'pluginstub.php', // tests/Unit/pluginstub.php + 'version' => $version // Version in pluginstub.php is 1.1.5 + ] + ]; + + $checker = new DependencyChecker($dependencies); + + \WP_Mock::userFunction('is_plugin_active') + ->withArgs([ 'pluginstub.php' ]) + ->once() + ->andReturn(true); + + $this->assertFalse($checker->failed()); + } + + /** + * Provides old version numbers. + * Version in pluginstub.php is 1.1.5 + * + * @return array + */ + public function wrongVersions() + { + return [ + [ '1.1.8' ], + [ '2.0' ], + [ '3' ] + ]; + } + + public function correctVersions() + { + return [ + [ '1.1.2' ], + [ '1.0' ], + [ '1' ] + ]; + } +} diff --git a/tests/Unit/Base/Metabox/MetaboxServiceProviderTest.php b/tests/Unit/Base/Metabox/MetaboxServiceProviderTest.php new file mode 100644 index 0000000..e6a43d4 --- /dev/null +++ b/tests/Unit/Base/Metabox/MetaboxServiceProviderTest.php @@ -0,0 +1,143 @@ +config = $config; + $plugin->loader = m::mock(Loader::class); + + $service = new MetaboxServiceProvider($plugin); + + $plugin->loader->shouldReceive('addFilter')->withArgs([ + 'rwmb_meta_boxes', + $service, + 'registerMetaboxes', + 10, + 1 + ])->once(); + + $service->register(); + + $configMetaboxes = [ + 'base' => [ + 'id' => 'metadata', + 'fields' => [ + 'general' => [ + 'testfield_noid' => [ + 'type' => 'heading' + ], + 'testfield1' => [ + 'id' => 'metabox_id1' + ], + 'testfield2' => [ + 'id' => 'metabox_id2' + ] + ] + ] + ] + ]; + + $prefix = MetaboxServiceProvider::PREFIX; + + $expectedMetaboxes = [ + 0 => [ + 'id' => 'metadata', + 'fields' => [ + [ + 'type' => 'heading' + ], + [ + 'id' => $prefix . 'metabox_id1' + ], + [ + 'id' => $prefix . 'metabox_id2' + ] + ] + ] + ]; + + $config->shouldReceive('get')->with('metaboxes')->once()->andReturn($configMetaboxes); + + //test for filter being called + \WP_Mock::expectFilter('owc/openpub-base/before-register-metaboxes', $expectedMetaboxes ); + + $this->assertEquals($expectedMetaboxes, $service->registerMetaboxes([])); + + $existingMetaboxes = [ + 0 => [ + 'id' => 'existing_metadata', + 'fields' => [ + [ + 'type' => 'existing_heading' + ], + [ + 'id' => $prefix . 'existing_metabox_id1' + ], + [ + 'id' => $prefix . 'existing_metabox_id2' + ] + ] + ] + ]; + + $expectedMetaboxesAfterMerge = [ + + 0 => [ + 'id' => 'existing_metadata', + 'fields' => [ + [ + 'type' => 'existing_heading' + ], + [ + 'id' => $prefix . 'existing_metabox_id1' + ], + [ + 'id' => $prefix . 'existing_metabox_id2' + ] + ] + ], + 1 => [ + 'id' => 'metadata', + 'fields' => [ + [ + 'type' => 'heading' + ], + [ + 'id' => $prefix . 'metabox_id1' + ], + [ + 'id' => $prefix . 'metabox_id2' + ] + ] + ] + ]; + + $config->shouldReceive('get')->with('metaboxes')->once()->andReturn($configMetaboxes); + + $this->assertEquals($expectedMetaboxesAfterMerge, $service->registerMetaboxes($existingMetaboxes)); + } +} diff --git a/tests/Unit/Base/PostType/PostTypeServiceProviderTest.php b/tests/Unit/Base/PostType/PostTypeServiceProviderTest.php new file mode 100644 index 0000000..7e62e07 --- /dev/null +++ b/tests/Unit/Base/PostType/PostTypeServiceProviderTest.php @@ -0,0 +1,57 @@ +config = $config; + $plugin->loader = m::mock(Loader::class); + + $service = new PostTypeServiceProvider($plugin); + + $plugin->loader->shouldReceive('addAction')->withArgs([ + 'init', + $service, + 'registerPostTypes' + ])->once(); + + /** + * Examples of registering post types: http://johnbillion.com/extended-cpts/ + */ + $configPostTypes = [ + 'posttype' => [ + 'args' => [ + ], + 'names' => [ + ] + ] + ]; + + $service->register(); + + $this->assertTrue(true); + } +} diff --git a/tests/Unit/Base/PostType/PostTypes/OpenPubtemModelTest.php b/tests/Unit/Base/PostType/PostTypes/OpenPubtemModelTest.php new file mode 100644 index 0000000..5e2c40f --- /dev/null +++ b/tests/Unit/Base/PostType/PostTypes/OpenPubtemModelTest.php @@ -0,0 +1,169 @@ +getMethod($methodName); + $method->setAccessible(true); + + return $method->invokeArgs($object, $parameters); + } + + /** @test */ + public function check_model_construct() + { + $config = m::mock(Config::class); + $openpub_item = m::mock(OpenPubItemModel::class); + + $model = new OpenPubItemModel($config); + + $this->assertTrue(true); + } + + // /** @test */ + public function check_get_terms_as_array_methods() + { + $config = m::mock(Config::class); + $openpub_item = m::mock(OpenPubItemModel::class); + + $model = new OpenPubItemModel($config); + + $term1 = new \stdClass(); + $term1->term_id = 1; + $term1->name = 'term_name1'; + $term1->slug = 'term_slug1'; + + $term2 = new \stdClass(); + $term2->term_id = 2; + $term2->name = 'term_name2'; + $term2->slug = 'term_slug2'; + + $terms[] = $term1; + $terms[] = $term2; + + $object = [ 'id' => 1 ]; + $taxonomyId = 1; + + $output = [ + [ + 'ID' => 1, + 'name' => 'term_name1', + 'slug' => 'term_slug1' + ], + [ + 'ID' => 2, + 'name' => 'term_name2', + 'slug' => 'term_slug2' + ] + ]; + + //$this->assertEquals( $output, $this->invokeMethod($model, 'getTermsAsArray', array($object, 1))); + } + + /** @test */ + public function check_get_title_alternative_method() + { + $config = m::mock(Config::class); + $openpub_item = m::mock(OpenPubItemModel::class); + + $model = new OpenPubItemModel($config); + + $output = [ + [ + 'ID' => 1, + 'name' => 'term_name1', + 'slug' => 'term_slug1' + ], + [ + 'ID' => 2, + 'name' => 'term_name2', + 'slug' => 'term_slug2' + ] + ]; + + $object['id'] = 1; + $fieldName = 'field_name'; + $request = null; + + $title_alternative = '

Alternative Title

'; + + \WP_Mock::userFunction('get_post_meta', [ + 'args' => [ $object['id'], '_owc_openpub_titel_alternatief', true ], + 'times' => '1', + 'return' => $title_alternative + ] + ); + + $output = 'Alternative Title'; + + \WP_Mock::expectFilter('owc/openpub-base/rest-api/openpubitem/field/get-title-alternative', $output, $object, + $fieldName, $request); + + $this->assertEquals($output, $model->getTitleAlternative($object, $fieldName, $request)); + + $title_alternative = 'Alternative Title'; + + \WP_Mock::userFunction('get_post_meta', [ + 'args' => [ $object['id'], '_owc_openpub_titel_alternatief', true ], + 'times' => '1', + 'return' => $title_alternative + ] + ); + + $this->assertEquals($output, $model->getTitleAlternative($object, $fieldName, $request)); + + $title_alternative = "Alternative\r\nTitle"; + + \WP_Mock::userFunction('get_post_meta', [ + 'args' => [ $object['id'], '_owc_openpub_titel_alternatief', true ], + 'times' => '1', + 'return' => $title_alternative + ] + ); + + $this->assertEquals($output, $model->getTitleAlternative($object, $fieldName, $request)); + + $title_alternative = "Alternative\n\rTitle"; + + \WP_Mock::userFunction('get_post_meta', [ + 'args' => [ $object['id'], '_owc_openpub_titel_alternatief', true ], + 'times' => '1', + 'return' => $title_alternative + ] + ); + + $this->assertEquals($output, $model->getTitleAlternative($object, $fieldName, $request)); + } +} + + + diff --git a/tests/Unit/Base/PostsToPosts/PostsToPostsServiceProviderTest.php b/tests/Unit/Base/PostsToPosts/PostsToPostsServiceProviderTest.php new file mode 100644 index 0000000..10e9af0 --- /dev/null +++ b/tests/Unit/Base/PostsToPosts/PostsToPostsServiceProviderTest.php @@ -0,0 +1,179 @@ +config = $config; + $plugin->loader = m::mock(Loader::class); + + $service = new PostsToPostsServiceProvider($plugin); + + $plugin->loader->shouldReceive('addAction')->withArgs([ + 'init', + $service, + 'registerPostsToPostsConnections' + ])->once(); + + $plugin->loader->shouldReceive('addFilter')->withArgs([ + 'p2p_connectable_args', + $service, + 'filterP2PConnectableArgs', + 10 + ])->once(); + + $service->register(); + + $this->assertTrue(true); + } + + /** @test */ + public function test_filter_p2p_connectable_args_method() + { + $config = m::mock(Config::class); + $plugin = m::mock(Plugin::class); + + $plugin->config = $config; + $plugin->loader = m::mock(Loader::class); + + $service = new PostsToPostsServiceProvider($plugin); + + $inputArgs = []; + $inputArgs['orderby'] = 'date'; + $inputArgs['order'] = 'desc'; + $inputArgs['p2p:per_page'] = 10; + + $outputArgs = []; + $outputArgs['orderby'] = 'title'; + $outputArgs['order'] = 'asc'; + $outputArgs['p2p:per_page'] = 25; + + $this->assertEquals($outputArgs, $service->filterP2PConnectableArgs($inputArgs)); + } + + /** @test */ + public function test_register_posts_to_posts_connections_method() + { + $config = m::mock(Config::class); + $plugin = m::mock(Plugin::class); + + $plugin->config = $config; + $plugin->loader = m::mock(Loader::class); + + $service = new PostsToPostsServiceProvider($plugin); + + \WP_Mock::userFunction('p2p_register_connection_type', [ + 'args' => null, + 'times' => '2', + 'return' => true + ] + ); + + $configPostTypesInfo = [ + 'posttype1' => + [ + 'id' => 'posttype1', + 'title' => 'post1' + ], + 'posttype2' => + [ + 'id' => 'posttype2', + 'title' => 'post2' + ] + ]; + + $config->shouldReceive('get')->with('p2p_connections.posttypes_info')->once()->andReturn($configPostTypesInfo); + + $configConnections = [ + [ + 'from' => 'posttype1', + 'to' => 'posttype2', + 'reciprocal' => true + ], + [ + 'from' => 'posttype1', + 'to' => 'posttype1', + 'reciprocal' => false + ] + ]; + + $config->shouldReceive('get')->with('p2p_connections.connections')->once()->andReturn($configConnections); + + $connectionDefaults = [ + 'can_create_post' => false, + 'reciprocal' => true, + 'sortable' => 'any', + 'cardinality' => 'many-to-many', + 'duplicate_connections' => false + ]; + + //test for filter being called + \WP_Mock::expectFilter('owc/openpub-base/p2p-connection-defaults', $connectionDefaults); + + $connectionType1 = [ + 'id' => 'posttype1_to_posttype2', + 'from' => 'posttype1', + 'to' => 'posttype2', + 'sortable' => 'any', + 'admin_column' => 'any', + 'from_labels' => [ + 'column_title' => 'post2' + ], + 'title' => [ + 'from' => 'Koppel met een post2', + 'to' => 'Koppel met een post1' + ], + 'can_create_post' => false, + 'reciprocal' => true + ]; + + $connectionType2 = [ + 'id' => 'posttype1_to_posttype1', + 'from' => 'posttype1', + 'to' => 'posttype1', + 'sortable' => 'any', + 'admin_column' => 'any', + 'from_labels' => [ + 'column_title' => 'post1' + ], + 'title' => [ + 'from' => 'Koppel met een post1', + 'to' => '' + ], + 'can_create_post' => false, + 'reciprocal' => false, + 'admin_box' => 'from' + ]; + + \WP_Mock::expectFilter('owc/openpub-base/before-register-p2p-connection/posttype1/posttype2', $connectionType1); + \WP_Mock::expectFilter('owc/openpub-base/before-register-p2p-connection/posttype1/posttype1', $connectionType2); + + $service->registerPostsToPostsConnections(); + + $this->assertTrue(true); + } + +} diff --git a/tests/Unit/Base/RestApi/RestApiServiceProviderTest.php b/tests/Unit/Base/RestApi/RestApiServiceProviderTest.php new file mode 100644 index 0000000..bfc11d1 --- /dev/null +++ b/tests/Unit/Base/RestApi/RestApiServiceProviderTest.php @@ -0,0 +1,115 @@ +config = $config; + $plugin->loader = m::mock(Loader::class); + + $service = new RestAPIServiceProvider($plugin); + + $plugin->loader->shouldReceive('addFilter')->withArgs([ + 'owc/config-expander/rest-api/whitelist', + $service, + 'filterEndpointsWhitelist', + 10, + 1 + ])->once(); + + $plugin->loader->shouldReceive('addFilter')->withArgs([ + 'rest_api_init', + $service, + 'registerRestAPIEndpointsFields', + 10 + ])->once(); + + $plugin->loader->shouldReceive('addFilter')->withArgs([ + 'rest_prepare_openpub-item', + $service, + 'filterRestPrepareOpenPubItem', + 10, + 3 + ])->once(); + + $service->register(); + + $this->assertTrue(true); + + $configRestAPIFields = [ + 'posttype1' => [ + 'endpoint_field1' => + [ + 'get_callback' => ['object', 'callback1'], + 'update_callback' => null, + 'schema' => null, + ], + 'endpoint_field2' => + [ + 'get_callback' => ['object', 'callback2'], + 'update_callback' => null, + 'schema' => null, + ] + ], + 'posttype2' => [ + 'endpoint_field1' => + [ + 'get_callback' => ['object', 'callback1'], + 'update_callback' => null, + 'schema' => null, + ], + 'endpoint_field2' => + [ + 'get_callback' => ['object', 'callback2'], + 'update_callback' => null, + 'schema' => null, + ] + ] + ]; + + $config->shouldReceive('get')->with('rest_api_fields')->once()->andReturn($configRestAPIFields); + + \WP_Mock::userFunction('post_type_exists', [ + 'args' => [\WP_Mock\Functions::anyOf('posttype1', 'posttype2')], + 'times' => '0+', + 'return' => true + ] + ); + + \WP_Mock::userFunction('register_rest_field', [ + 'args' => [ + \WP_Mock\Functions::anyOf('posttype1', 'posttype2'), + \WP_Mock\Functions::anyOf('endpoint_field1', 'endpoint_field2'), + '*' + ], + 'times' => '0+' + ]); + + $service->registerRestAPIEndpointsFields(); + + $this->assertTrue(true); + } +} diff --git a/tests/Unit/Base/Settings/SettingsServiceProviderTest.php b/tests/Unit/Base/Settings/SettingsServiceProviderTest.php new file mode 100644 index 0000000..29d94d6 --- /dev/null +++ b/tests/Unit/Base/Settings/SettingsServiceProviderTest.php @@ -0,0 +1,194 @@ +config = $config; + $plugin->loader = m::mock(Loader::class); + + $service = new SettingsServiceProvider($plugin); + + $plugin->loader->shouldReceive('addFilter')->withArgs([ + 'mb_settings_pages', + $service, + 'registerSettingsPage', + 10, + 1 + ])->once(); + + $plugin->loader->shouldReceive('addFilter')->withArgs([ + 'rwmb_meta_boxes', + $service, + 'registerSettings', + 10, + 1 + ])->once(); + + $plugin->loader->shouldReceive('addAction')->withArgs([ + 'admin_init', + $service, + 'getSettingsOption' + ])->once(); + + $service->register(); + + $configSettingsPage = [ + 'base' => [ + 'id' => 'base_settings_page', + 'option_name' => 'base_settings_page' + ] + ]; + + $config->shouldReceive('get')->with('settings_pages')->once()->andReturn($configSettingsPage); + + $this->assertEquals($configSettingsPage, $service->registerSettingsPage([])); + + $existingSettingsPage = [ + 0 => [ + 'id' => 'existing_settings_page', + 'option_name' => 'existing_settings_page' + ] + ]; + + $existingSettingsPageAfterMerge = [ + + 0 => [ + 'id' => 'existing_settings_page', + 'option_name' => 'existing_settings_page' + ], + 'base' => [ + 'id' => 'base_settings_page', + 'option_name' => 'base_settings_page' + ] + ]; + + $config->shouldReceive('get')->with('settings_pages')->once()->andReturn($configSettingsPage); + + $this->assertEquals($existingSettingsPageAfterMerge, $service->registerSettingsPage($existingSettingsPage)); + + $configMetaboxes = [ + 'base' => [ + 'id' => 'metadata', + 'settings_pages' => 'base_settings_page', + 'fields' => [ + 'general' => [ + 'testfield_noid' => [ + 'type' => 'heading' + ], + 'testfield1' => [ + 'id' => 'metabox_id1' + ], + 'testfield2' => [ + 'id' => 'metabox_id2' + ] + ] + ] + ] + ]; + + $prefix = SettingsServiceProvider::PREFIX; + + $expectedMetaboxes = [ + 0 => [ + 'id' => 'metadata', + 'settings_pages' => 'base_settings_page', + 'fields' => [ + [ + 'type' => 'heading' + ], + [ + 'id' => $prefix . 'metabox_id1' + ], + [ + 'id' => $prefix . 'metabox_id2' + ] + ] + ] + ]; + + $config->shouldReceive('get')->with('settings')->once()->andReturn($configMetaboxes); + + //test for filter being called + \WP_Mock::expectFilter('owc/openpub-base/before-register-settings', $expectedMetaboxes); + + $this->assertEquals($expectedMetaboxes, $service->registerSettings([])); + + $existingMetaboxes = [ + 0 => [ + 'id' => 'existing_metadata', + 'fields' => [ + [ + 'type' => 'existing_heading' + ], + [ + 'id' => $prefix . 'existing_metabox_id1' + ], + [ + 'id' => $prefix . 'existing_metabox_id2' + ] + ] + ] + ]; + + $expectedMetaboxesAfterMerge = [ + + 0 => [ + 'id' => 'existing_metadata', + 'fields' => [ + [ + 'type' => 'existing_heading' + ], + [ + 'id' => $prefix . 'existing_metabox_id1' + ], + [ + 'id' => $prefix . 'existing_metabox_id2' + ] + ] + ], + 1 => [ + 'id' => 'metadata', + 'settings_pages' => 'base_settings_page', + 'fields' => [ + [ + 'type' => 'heading' + ], + [ + 'id' => $prefix . 'metabox_id1' + ], + [ + 'id' => $prefix . 'metabox_id2' + ] + ] + ] + ]; + + $config->shouldReceive('get')->with('settings')->once()->andReturn($configMetaboxes); + + $this->assertEquals($expectedMetaboxesAfterMerge, $service->registerSettings($existingMetaboxes)); + } +} diff --git a/tests/Unit/Base/Template/TemplateServiceProviderTest.php b/tests/Unit/Base/Template/TemplateServiceProviderTest.php new file mode 100644 index 0000000..c39e419 --- /dev/null +++ b/tests/Unit/Base/Template/TemplateServiceProviderTest.php @@ -0,0 +1,91 @@ +config = $config; + $plugin->loader = m::mock(Loader::class); + + $service = new TemplateServiceProvider($plugin); + + $plugin->loader->shouldReceive('addAction')->withArgs([ + 'template_redirect', + $service, + 'redirectAllButAdmin', + 10 + ])->once(); + + $service->register(); + + $this->assertTrue(true); + } + + /** @test */ + public function check_redirect_all_but_admin_method() + { + $config = m::mock(Config::class); + $plugin = m::mock(Plugin::class); + + $plugin->config = $config; + $plugin->loader = m::mock(Loader::class); + + $service = new TemplateServiceProvider($plugin); + + \WP_Mock::userFunction('is_admin', [ + 'args' => null, + 'times' => '1', + 'return' => false + ] + ); + + \WP_Mock::userFunction('wp_doing_ajax', [ + 'args' => null, + 'times' => '1', + 'return' => false + ] + ); + + \WP_Mock::userFunction('is_feed', [ + 'args' => null, + 'times' => '1', + 'return' => false + ] + ); + + \WP_Mock::userFunction('wp_redirect', [ + 'args' => 'https://www.openwebconcept.nl/', + 'times' => '1', + 'return' => false + ] + ); + + $service->redirectAllButAdmin(); + + $this->assertTrue(true); + } + +} diff --git a/tests/Unit/Config/RepositoryTest.php b/tests/Unit/Config/RepositoryTest.php new file mode 100644 index 0000000..592cf73 --- /dev/null +++ b/tests/Unit/Config/RepositoryTest.php @@ -0,0 +1,293 @@ +boot(); + + $config = [ + 'test' => [ + 'single_file' => true + ], + 'directory' => [ + 'testfile' => [ + 'in_directory' => 'directory', + ], + 'multi' => [ + 'deep' => [ + 'multi_level' => 'works' + ] + ] + ] + ]; + + $this->assertEquals($config, $repository->all()); + $this->assertEquals($config, $repository->get(false)); + $this->assertEquals(true, $repository->get('test.single_file')); + $this->assertEquals('directory', $repository->get('directory.testfile.in_directory')); + $this->assertEquals('works', $repository->get('directory.multi.deep.multi_level')); + } + + /** @test */ + public function check_setting_of_path() + { + $repository = new Config(__DIR__ . '/config'); + + $path = '/test/path/config/'; + $repository->setPath($path); + + $this->assertEquals($repository->getPath(), $path); + } + + + /** @test */ + public function check_setting_of_protected_nodes() + { + $repository = new Config(__DIR__ . '/config'); + $repository->boot(); + + $expectedConfig = [ + 'test' => [ + 'test' + ], + 'directory' => [ + 'testfile' => [ + 'in_directory' => 'directory' + ], + 'multi' => [ + 'deep' => [ + 'multi_level' => 'works' + ] + ] + ] + ]; + $repository->set('test', ['test']); + $this->assertEquals($expectedConfig, $repository->all()); + + $repository->setProtectedNodes(['test']); + $repository->set('test', ['test2']); + $this->assertEquals($expectedConfig, $repository->all()); + + $expectedConfig = [ + 'test' => [ + 'single_file' => true + ], + 'directory' => 'test' + ]; + + $repository = new Config(__DIR__ . '/config'); + $repository->boot(); + + $repository->set('directory', 'test'); + $this->assertEquals($expectedConfig, $repository->all()); + + $expectedConfig = [ + 'test' => [ + 'single_file' => true + ], + 'directory' => [ + 'test' => 'node' + ] + ]; + $repository->set('directory', ['test' => 'node']); + $this->assertEquals($expectedConfig, $repository->all()); + + $expectedConfig = [ + 'test' => [ + 'single_file' => true + ], + 'directory' => [ + 'test' => [ + 'node' => 'nog deeper' + ] + ] + ]; + $repository->set('directory', ['test' => ['node' => 'nog deeper']]); + $this->assertEquals($expectedConfig, $repository->all()); + + $expectedConfig = [ + 'test' => [ + 'single_file' => true + ], + 'directory' => [ + 'testfile' => 'test', + 'multi' => [ + 'deep' => [ + 'multi_level' => 'works' + ] + ] + ] + ]; + + $repository = new Config(__DIR__ . '/config'); + $repository->boot(); + + $repository->set('directory.testfile', 'test'); + $this->assertEquals($expectedConfig, $repository->all()); + + $expectedConfig = [ + 'test' => [ + 'single_file' => true + ], + 'directory' => [ + 'testfile' => [ + 'test' => 'node' + ], + 'multi' => [ + 'deep' => [ + 'multi_level' => 'works' + ] + ] + ] + ]; + $repository->set('directory.testfile', ['test' => 'node']); + $this->assertEquals($expectedConfig, $repository->all()); + + $expectedConfig = [ + 'test' => [ + 'single_file' => true + ], + 'directory' => [ + 'testfile' => [ + 'test' => [ + 'node' => 'nog deeper' + ] + ], + 'multi' => [ + 'deep' => [ + 'multi_level' => 'works' + ] + ] + ] + ]; + $repository->set('directory.testfile', ['test' => ['node' => 'nog deeper']]); + $this->assertEquals($expectedConfig, $repository->all()); + + $expectedConfig = [ + 'test' => [ + 'single_file' => true + ], + 'directory' => [ + 'testfile' => [ + 'in_directory' => 'directory', + ], + 'multi' => 'test' + ] + ]; + + $repository = new Config(__DIR__ . '/config'); + $repository->boot(); + + $repository->set('directory.multi', 'test'); + $this->assertEquals($expectedConfig, $repository->all()); + + $expectedConfig = [ + 'test' => [ + 'single_file' => true + ], + 'directory' => [ + 'testfile' => [ + 'in_directory' => 'directory', + ], + 'multi' => [ + 'deep' => 'test' + ] + ] + ]; + + $repository = new Config(__DIR__ . '/config'); + $repository->boot(); + + $repository->set('directory.multi.deep', 'test'); + $this->assertEquals($expectedConfig, $repository->all()); + + $expectedConfig = [ + 'test' => [ + 'single_file' => true + ], + 'directory' => [ + 'testfile' => [ + 'in_directory' => 'directory', + ], + 'multi' => [ + 'deep' => [ + 'multi_level' => 'works_also_via_set' + ] + ] + ] + ]; + $repository->set('directory.multi.deep', ['multi_level' => 'works_also_via_set']); + $this->assertEquals($expectedConfig, $repository->all()); + + $expectedConfig = [ + 'test' => [ + 'single_file' => true + ], + 'directory' => [ + 'testfile' => [ + 'in_directory' => 'directory', + ], + 'multi' => [ + 'deep' => [ + 'multi_level' => 'works' + ] + ] + ], + 'doesnotexist' => [ + 'directory' => [ + 'multi' => [ + 'deep' => null + ] + ] + ] + ]; + + $repository = new Config(__DIR__ . '/config'); + $repository->boot(); + + $repository->set('doesnotexist.directory.multi.deep'); + $this->assertEquals($expectedConfig, $repository->all()); + + $expectedConfig = [ + 'test' => [ + 'single_file' => true + ], + 'directory' => [ + 'testfile' => [ + 'in_directory' => 'directory', + ], + 'multi' => [ + 'deep' => [ + 'multi_level' => 'works' + ] + ] + ], + '' => null + ]; + + $repository = new Config(__DIR__ . '/config'); + $repository->boot(); + + $repository->set([null => null]); + $this->assertEquals($expectedConfig, $repository->all()); + } +} \ No newline at end of file diff --git a/tests/Unit/Config/config/directory/multi/deep.php b/tests/Unit/Config/config/directory/multi/deep.php new file mode 100644 index 0000000..ff049a0 --- /dev/null +++ b/tests/Unit/Config/config/directory/multi/deep.php @@ -0,0 +1,5 @@ + 'works' +]; \ No newline at end of file diff --git a/tests/Unit/Config/config/directory/testfile.php b/tests/Unit/Config/config/directory/testfile.php new file mode 100644 index 0000000..072165f --- /dev/null +++ b/tests/Unit/Config/config/directory/testfile.php @@ -0,0 +1,5 @@ + 'directory' +]; \ No newline at end of file diff --git a/tests/Unit/Config/config/test.php b/tests/Unit/Config/config/test.php new file mode 100644 index 0000000..00f070d --- /dev/null +++ b/tests/Unit/Config/config/test.php @@ -0,0 +1,5 @@ + true +]; \ No newline at end of file diff --git a/tests/Unit/TestCase.php b/tests/Unit/TestCase.php new file mode 100644 index 0000000..ae6a2fa --- /dev/null +++ b/tests/Unit/TestCase.php @@ -0,0 +1,10 @@ + array( 'openpub-base/openpub-base.php' ), +); + +class WP_CLI { + public static function add_command() {} +} diff --git a/tests/Unit/pluginstub.php b/tests/Unit/pluginstub.php new file mode 100644 index 0000000..c4160e4 --- /dev/null +++ b/tests/Unit/pluginstub.php @@ -0,0 +1,8 @@ +