diff --git a/.distignore b/.distignore new file mode 100755 index 0000000000000000000000000000000000000000..1649ea423609d218434907825a314314c96c3fa8 --- /dev/null +++ b/.distignore @@ -0,0 +1,30 @@ +# A set of files you probably don't want in your WordPress.org distribution +.distignore +.editorconfig +.git +.gitignore +.gitlab-ci.yml +.travis.yml +.DS_Store +Thumbs.db +behat.yml +bin +circle.yml +composer.json +composer.lock +Gruntfile.js +package.json +phpunit.xml +phpunit.xml.dist +multisite.xml +multisite.xml.dist +phpcs.xml +phpcs.xml.dist +README.md +wp-cli.local.yml +tests +vendor +node_modules +*.sql +*.tar.gz +*.zip diff --git a/.editorconfig b/.editorconfig new file mode 100755 index 0000000000000000000000000000000000000000..79207a40cb9326b8c6b8c958fa864b5345f94e68 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,22 @@ +# This file is for unifying the coding style for different editors and IDEs +# editorconfig.org + +# WordPress Coding Standards +# https://make.wordpress.org/core/handbook/coding-standards/ + +root = true + +[*] +charset = utf-8 +end_of_line = lf +insert_final_newline = true +trim_trailing_whitespace = true +indent_style = tab +indent_size = 4 + +[{.jshintrc,*.json,*.yml}] +indent_style = space +indent_size = 2 + +[{*.txt,wp-config-sample.php}] +end_of_line = crlf diff --git a/.gitignore b/.gitignore new file mode 100755 index 0000000000000000000000000000000000000000..7b4c57a3988f856fdb2e5688204256b53672c91f --- /dev/null +++ b/.gitignore @@ -0,0 +1,7 @@ +.DS_Store +Thumbs.db +wp-cli.local.yml +node_modules/ +*.sql +*.tar.gz +*.zip diff --git a/.travis.yml b/.travis.yml new file mode 100755 index 0000000000000000000000000000000000000000..a6ccc2eeb7d1ff64145d83a2531fa0a4d8774a3b --- /dev/null +++ b/.travis.yml @@ -0,0 +1,61 @@ +sudo: false + +language: php + +notifications: + email: + on_success: never + on_failure: change + +cache: + directories: + - vendor + - $HOME/.composer/cache + +matrix: + include: + # PHPUnit + - php: 7.2 + env: WP_VERSION=latest + - php: 7.2 + env: WP_VERSION=trunk + - php: 7.1 + env: WP_VERSION=latest + - php: 7.1 + env: WP_VERSION=trunk + - php: 7.0 + env: WP_VERSION=latest + - php: 7.0 + env: WP_VERSION=trunk + # PHPCS + - php: 7.1 + env: WP_TRAVISCI=phpcs + +before_script: + - phpenv config-rm xdebug.ini + - export PATH="$HOME/.composer/vendor/bin:$PATH" + - | + if [[ ! -z "$WP_VERSION" ]] ; then + bash bin/install-wp-tests.sh wordpress_test root '' localhost $WP_VERSION + if [[ ${TRAVIS_PHP_VERSION:0:2} == "5." ]]; then + composer global require "phpunit/phpunit=4.8.*" + else + composer global require "phpunit/phpunit=5.7.*" + fi + fi + - | + if [[ "$WP_TRAVISCI" == "phpcs" ]] ; then + composer global require wp-coding-standards/wpcs + phpcs --config-set installed_paths $HOME/.composer/vendor/wp-coding-standards/wpcs + fi + +script: + - | + if [[ ! -z "$WP_VERSION" ]] ; then + phpunit + WP_MULTISITE=1 phpunit + fi + - | + if [[ "$WP_TRAVISCI" == "phpcs" ]] ; then + phpcs + fi diff --git a/Gruntfile.js b/Gruntfile.js new file mode 100755 index 0000000000000000000000000000000000000000..bc0fcf617a006bdf32648830e622c2c201283693 --- /dev/null +++ b/Gruntfile.js @@ -0,0 +1,54 @@ +module.exports = function( grunt ) { + + 'use strict'; + var banner = '/**\n * <%= pkg.homepage %>\n * Copyright (c) <%= grunt.template.today("yyyy") %>\n * This file is generated automatically. Do not edit.\n */\n'; + // Project configuration + grunt.initConfig( { + + pkg: grunt.file.readJSON( 'package.json' ), + + addtextdomain: { + options: { + textdomain: 'bulk-edit-cron-offload', + }, + update_all_domains: { + options: { + updateDomains: true + }, + src: [ '*.php', '**/*.php', '!node_modules/**', '!php-tests/**', '!bin/**' ] + } + }, + + wp_readme_to_markdown: { + your_target: { + files: { + 'README.md': 'readme.txt' + } + }, + }, + + makepot: { + target: { + options: { + domainPath: '/languages', + mainFile: 'bulk-edit-cron-offload.php', + potFilename: 'bulk-edit-cron-offload.pot', + potHeaders: { + poedit: true, + 'x-poedit-keywordslist': true + }, + type: 'wp-plugin', + updateTimestamp: true + } + } + }, + } ); + + grunt.loadNpmTasks( 'grunt-wp-i18n' ); + grunt.loadNpmTasks( 'grunt-wp-readme-to-markdown' ); + grunt.registerTask( 'i18n', ['addtextdomain', 'makepot'] ); + grunt.registerTask( 'readme', ['wp_readme_to_markdown'] ); + + grunt.util.linefeed = '\n'; + +}; diff --git a/README.md b/README.md new file mode 100644 index 0000000000000000000000000000000000000000..a23cc6e940f9a903cca83293060ee1a45e9f5bf9 --- /dev/null +++ b/README.md @@ -0,0 +1,30 @@ +# Bulk Edit Cron Offload # +**Contributors:** ethitter, automattic +**Tags:** cron, bulk edit +**Requires at least:** 4.8.1 +**Tested up to:** 4.9 +**Stable tag:** 1.0 +**License:** GPLv2 or later +**License URI:** http://www.gnu.org/licenses/gpl-2.0.html + +Process Core's Bulk Edit requests using Cron + +## Description ## + +Process Core's Bulk Edit requests using Cron, rather than via a `$_GET` request. + +## Installation ## + +1. Upload the `bulk-edit-cron-offload` directory to the `/wp-content/plugins/` directory +1. Activate the plugin through the 'Plugins' menu in WordPress + +## Frequently Asked Questions ## + +### A question that someone might have ### + +An answer to that question. + +## Changelog ## + +### 1.0 ### +* Initial release diff --git a/bin/install-wp-tests.sh b/bin/install-wp-tests.sh new file mode 100755 index 0000000000000000000000000000000000000000..73bb4c787eb2ccf4b4225729ddaa3578cb606741 --- /dev/null +++ b/bin/install-wp-tests.sh @@ -0,0 +1,127 @@ +#!/usr/bin/env bash + +if [ $# -lt 3 ]; then + echo "usage: $0 <db-name> <db-user> <db-pass> [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="tags/$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="tags/$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 + svn co --quiet https://develop.svn.wordpress.org/${WP_TESTS_TAG}/tests/phpunit/includes/ $WP_TESTS_DIR/includes + svn co --quiet https://develop.svn.wordpress.org/${WP_TESTS_TAG}/tests/phpunit/data/ $WP_TESTS_DIR/data + fi + + if [ ! -f wp-tests-config.php ]; then + download https://develop.svn.wordpress.org/${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 + mysqladmin create $DB_NAME --user="$DB_USER" --password="$DB_PASS"$EXTRA +} + +install_wp +install_test_suite +install_db diff --git a/bulk-edit-cron-offload.php b/bulk-edit-cron-offload.php index 5297a8dd51d0b7f2c0913fd08f89d0230d2c1686..4c3e2552dece2650a094463bba329732e88604b4 100644 --- a/bulk-edit-cron-offload.php +++ b/bulk-edit-cron-offload.php @@ -1,17 +1,21 @@ <?php -/* - Plugin Name: Offload Bulk Edit to Cron - Plugin URI: https://vip.wordpress.com/ - Description: Process Bulk Edit requests using Cron - Author: Erick Hitter, Automattic - Version: 1.0 - Text Domain: automattic-bulk-edit-cron-offload +/** + * Plugin Name: Bulk Edit Cron Offload + * Plugin URI: https://vip.wordpress.com/ + * Description: Process Bulk Edit requests using Cron + * Author: Erick Hitter, Automattic + * Author URI: https://automattic.com/ + * Text Domain: automattic-bulk-edit-cron-offload + * Domain Path: /languages + * Version: 1.0 + * + * @package Bulk_Edit_Cron_Offload */ namespace Automattic\WP\Bulk_Edit_Cron_Offload; -// Plugin dependencies -require __DIR__ . '/includes/abstract-class-singleton.php'; +// Plugin dependencies. +require __DIR__ . '/includes/class-singleton.php'; -// Plugin functionality +// Plugin functionality. require __DIR__ . '/includes/class-main.php'; diff --git a/includes/class-main.php b/includes/class-main.php index c9fdb000ed232581deb1ecee2a569fbd0cfe3319..7d44e484eb00e5f58a10638fd1eb0d912c1b4196 100644 --- a/includes/class-main.php +++ b/includes/class-main.php @@ -1,50 +1,76 @@ <?php +/** + * Plugin's main class, dispatcher for specific bulk-edit requests + * + * @package Bulk_Edit_Cron_Offload + */ namespace Automattic\WP\Bulk_Edit_Cron_Offload; +/** + * Class Main + */ class Main extends Singleton { /** * Requested action + * + * @var string */ private $action = null; /** * Posts to process + * + * @var array */ private $posts = null; /** * Taxonomy terms to add + * + * @var array */ private $tax_input = null; /** * Post author to set + * + * @var int */ private $post_author = null; /** * Comment status to set + * + * @var string */ private $comment_status = null; /** * Ping status to set + * + * @var string */ private $ping_status = null; /** * New post status + * + * @var string */ private $post_status = null; /** - * Posts' stick status + * Posts' sticky status + * + * @var int */ private $post_sticky = null; /** * Posts' format + * + * @var string */ private $post_format = null; @@ -59,33 +85,33 @@ class Main extends Singleton { * Call appropriate handler */ public function intercept() { - // Nothing to do + // Nothing to do. if ( ! isset( $_REQUEST['action'] ) ) { return; } - // Parse request to determine what to do + // Parse request to determine what to do. $this->populate_vars(); // Now what? switch ( $this->action ) { - case 'delete_all' : + case 'delete_all': break; - case 'trash' : + case 'trash': break; - case 'untrash' : + case 'untrash': break; - case 'delete' : + case 'delete': break; - case 'edit' : + case 'edit': break; // How did you get here? - default : + default: return; break; } @@ -129,7 +155,7 @@ class Main extends Singleton { $this->post_format = $_REQUEST['post_format']; } - // Stop Core from processing bulk request + // Stop Core from processing bulk request. unset( $_REQUEST['action'] ); unset( $_REQUEST['action2'] ); } diff --git a/includes/abstract-class-singleton.php b/includes/class-singleton.php similarity index 70% rename from includes/abstract-class-singleton.php rename to includes/class-singleton.php index 5c8042f8b4a3fb97a80c17e81d3a75a2a104482b..53ed87ab65755e26b70fd53644f6e2d3387d6b01 100644 --- a/includes/abstract-class-singleton.php +++ b/includes/class-singleton.php @@ -1,13 +1,28 @@ <?php +/** + * Abstract singleton for plugin's main classes + * + * @package Bulk_Edit_Cron_Offload + */ namespace Automattic\WP\Bulk_Edit_Cron_Offload; +/** + * Class Singleton + */ abstract class Singleton { /** * Class instance + * + * @var array */ private static $__instances = array(); + /** + * Instantiate the class + * + * @return self + */ public static function instance() { $caller = get_called_class(); @@ -20,6 +35,9 @@ abstract class Singleton { return self::$__instances[ $caller ]; } + /** + * Singleton constructor + */ protected function __construct() {} /** diff --git a/languages/bulk-edit-cron-offload.pot b/languages/bulk-edit-cron-offload.pot new file mode 100644 index 0000000000000000000000000000000000000000..c61a699cf66937b19ba5bdfccdd3bc2e02575ea3 --- /dev/null +++ b/languages/bulk-edit-cron-offload.pot @@ -0,0 +1,46 @@ +# Copyright (C) 2017 Erick Hitter, Automattic +# This file is distributed under the same license as the Bulk Edit Cron Offload package. +msgid "" +msgstr "" +"Project-Id-Version: Bulk Edit Cron Offload 1.0\n" +"Report-Msgid-Bugs-To: " +"https://wordpress.org/support/plugin/bulk-edit-cron-offload\n" +"POT-Creation-Date: 2017-09-13 00:10:57+00:00\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"PO-Revision-Date: 2017-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" +"Language-Team: LANGUAGE <LL@li.org>\n" +"X-Generator: grunt-wp-i18n 0.5.4\n" +"X-Poedit-KeywordsList: " +"__;_e;_x:1,2c;_ex:1,2c;_n:1,2;_nx:1,2,4c;_n_noop:1,2;_nx_noop:1,2,3c;esc_" +"attr__;esc_html__;esc_attr_e;esc_html_e;esc_attr_x:1,2c;esc_html_x:1,2c;\n" +"Language: en\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-Poedit-Country: United States\n" +"X-Poedit-SourceCharset: UTF-8\n" +"X-Poedit-Basepath: ../\n" +"X-Poedit-SearchPath-0: .\n" +"X-Poedit-Bookmarks: \n" +"X-Textdomain-Support: yes\n" + +#. Plugin Name of the plugin/theme +msgid "Bulk Edit Cron Offload" +msgstr "" + +#. Plugin URI of the plugin/theme +msgid "https://vip.wordpress.com/" +msgstr "" + +#. Description of the plugin/theme +msgid "Process Bulk Edit requests using Cron" +msgstr "" + +#. Author of the plugin/theme +msgid "Erick Hitter, Automattic" +msgstr "" + +#. Author URI of the plugin/theme +msgid "https://automattic.com/" +msgstr "" \ No newline at end of file diff --git a/package.json b/package.json new file mode 100755 index 0000000000000000000000000000000000000000..6696683db036d618026bdf6278b97ccec4207df8 --- /dev/null +++ b/package.json @@ -0,0 +1,11 @@ +{ + "name": "bulk-edit-cron-offload", + "version": "0.1.0", + "main": "Gruntfile.js", + "author": "YOUR NAME HERE", + "devDependencies": { + "grunt": "~0.4.5", + "grunt-wp-i18n": "~0.5.0", + "grunt-wp-readme-to-markdown": "~1.0.0" + } +} diff --git a/phpcs.xml.dist b/phpcs.xml.dist new file mode 100644 index 0000000000000000000000000000000000000000..2c9e091164834d4505603e2f39ec9a96e193ec8e --- /dev/null +++ b/phpcs.xml.dist @@ -0,0 +1,17 @@ +<?xml version="1.0"?> +<ruleset name="WordPress Coding Standards for Plugins"> + <description>Generally-applicable sniffs for WordPress plugins</description> + + <rule ref="WordPress-Core" /> + <rule ref="WordPress-Docs" /> + + <!-- Check all PHP files in directory tree by default. --> + <arg name="extensions" value="php"/> + <file>.</file> + + <!-- Show sniff codes in all reports --> + <arg value="s"/> + + <exclude-pattern>*/node_modules/*</exclude-pattern> + <exclude-pattern>*/vendor/*</exclude-pattern> +</ruleset> diff --git a/phpunit.xml.dist b/phpunit.xml.dist new file mode 100644 index 0000000000000000000000000000000000000000..2bff769f357d6564eed7ebf3b12b6cdff5647bc9 --- /dev/null +++ b/phpunit.xml.dist @@ -0,0 +1,14 @@ +<phpunit + bootstrap="tests/bootstrap.php" + backupGlobals="false" + colors="true" + convertErrorsToExceptions="true" + convertNoticesToExceptions="true" + convertWarningsToExceptions="true" + > + <testsuites> + <testsuite> + <directory suffix=".php">./tests/tests/</directory> + </testsuite> + </testsuites> +</phpunit> diff --git a/readme.txt b/readme.txt new file mode 100755 index 0000000000000000000000000000000000000000..57472658e428a21d8c58cf0079dabbaf0e047823 --- /dev/null +++ b/readme.txt @@ -0,0 +1,30 @@ +=== Bulk Edit Cron Offload === +Contributors: ethitter, automattic +Tags: cron, bulk edit +Requires at least: 4.8.1 +Tested up to: 4.9 +Stable tag: 1.0 +License: GPLv2 or later +License URI: http://www.gnu.org/licenses/gpl-2.0.html + +Process Core's Bulk Edit requests using Cron + +== Description == + +Process Core's Bulk Edit requests using Cron, rather than via a `$_GET` request. + +== Installation == + +1. Upload the `bulk-edit-cron-offload` directory to the `/wp-content/plugins/` directory +1. Activate the plugin through the 'Plugins' menu in WordPress + +== Frequently Asked Questions == + += A question that someone might have = + +An answer to that question. + +== Changelog == + += 1.0 = +* Initial release diff --git a/tests/bootstrap.php b/tests/bootstrap.php new file mode 100755 index 0000000000000000000000000000000000000000..dde0131d4f82fcad28438b657a4acec782c8545b --- /dev/null +++ b/tests/bootstrap.php @@ -0,0 +1,25 @@ +<?php +/** + * PHPUnit bootstrap file + * + * @package Bulk_Edit_Cron_Offload + */ + +$_tests_dir = getenv( 'WP_TESTS_DIR' ); +if ( ! $_tests_dir ) { + $_tests_dir = '/tmp/wordpress-tests-lib'; +} + +// Give access to tests_add_filter() function. +require_once $_tests_dir . '/includes/functions.php'; + +/** + * Manually load the plugin being tested. + */ +function _manually_load_plugin() { + require dirname( dirname( __FILE__ ) ) . '/bulk-edit-cron-offload.php'; +} +tests_add_filter( 'muplugins_loaded', '_manually_load_plugin' ); + +// Start up the WP testing environment. +require $_tests_dir . '/includes/bootstrap.php'; diff --git a/tests/tests/class-sampletest.php b/tests/tests/class-sampletest.php new file mode 100755 index 0000000000000000000000000000000000000000..814ff7bfb0a76a782a230f37a4c60111ad4bc22f --- /dev/null +++ b/tests/tests/class-sampletest.php @@ -0,0 +1,20 @@ +<?php +/** + * Class SampleTest + * + * @package Bulk_Edit_Cron_Offload + */ + +/** + * Sample test case. + */ +class SampleTest extends WP_UnitTestCase { + + /** + * A single example test. + */ + function test_sample() { + // Replace this with some actual testing code. + $this->assertTrue( true ); + } +}