diff --git a/.ci-env.sh b/.ci-env.sh new file mode 100644 index 000000000..67ef0c34e --- /dev/null +++ b/.ci-env.sh @@ -0,0 +1,5 @@ +export PHPCS_GITHUB_SRC=x-team/PHP_CodeSniffer +export PHPCS_GIT_TREE=subset-selection +export WPCS_GIT_TREE=rule-subset-with-phpcs-pr +export WPCS_STANDARD=WordPress:core-extra +export PHPCS_IGNORE='tests/*,includes/vendor/*' diff --git a/bin/.travis.yml b/bin/.travis.yml index f1797e3de..24bf630a3 100644 --- a/bin/.travis.yml +++ b/bin/.travis.yml @@ -10,24 +10,29 @@ node_js: - 0.10 env: - - WP_VERSION=master WP_MULTISITE=0 - - WP_VERSION=master WP_MULTISITE=1 - WP_VERSION=latest WP_MULTISITE=0 - WP_VERSION=latest WP_MULTISITE=1 + - WP_VERSION=3.8 WP_MULTISITE=0 + - WP_VERSION=3.8 WP_MULTISITE=1 before_script: - export WP_TESTS_DIR=/tmp/wordpress-tests/ - export PLUGIN_DIR=$(pwd) - export PLUGIN_SLUG=$(basename $(pwd) | sed 's/^wp-//') - - if [ -e phpunit.xml ] || [ -e phpunit.xml.dist ]; then bash bin/install-wp-tests.sh wordpress_test root '' localhost $WP_VERSION; cd /tmp/wordpress/wp-content/plugins; ln -s $PLUGIN_DIR $PLUGIN_SLUG; cd $PLUGIN_DIR; fi - - pear config-set auto_discover 1 - - pear install PHP_CodeSniffer - - git clone git://github.com/WordPress-Coding-Standards/WordPress-Coding-Standards.git $(pear config-get php_dir)/PHP/CodeSniffer/Standards/WordPress - - phpenv rehash + - export PHPCS_DIR=/tmp/phpcs + - export PHPCS_GITHUB_SRC=squizlabs/PHP_CodeSniffer + - export PHPCS_GIT_TREE=master + - export WPCS_GITHUB_SRC=WordPress-Coding-Standards/WordPress-Coding-Standards + - export WPCS_GIT_TREE=master + - export WPCS_STANDARD=$(if [ -e phpcs.ruleset.xml ]; then echo phpcs.ruleset.xml; else echo WordPress; fi) + - if [ -e .ci-env.sh ]; then source .ci-env.sh; fi + - if [ -e phpunit.xml ] || [ -e phpunit.xml.dist ]; then wget -O /tmp/install-wp-tests.sh https://raw.githubusercontent.com/wp-cli/wp-cli/master/templates/install-wp-tests.sh; bash /tmp/install-wp-tests.sh wordpress_test root '' localhost $WP_VERSION; cd /tmp/wordpress/wp-content/plugins; ln -s $PLUGIN_DIR $PLUGIN_SLUG; cd $PLUGIN_DIR; fi + - mkdir -p $PHPCS_DIR && curl -L https://github.com/$PHPCS_GITHUB_SRC/archive/$PHPCS_GIT_TREE.tar.gz | tar xvz --strip-components=1 -C $PHPCS_DIR + - mkdir -p $PHPCS_DIR/CodeSniffer/Standards/WordPress && curl -L https://github.com/$WPCS_GITHUB_SRC/archive/$WPCS_GIT_TREE.tar.gz | tar xvz --strip-components=1 -C $PHPCS_DIR/CodeSniffer/Standards/WordPress - npm install -g jshint script: - find . -path ./bin -prune -o \( -name '*.php' -o -name '*.inc' \) -exec php -lf {} \; - if [ -e phpunit.xml ] || [ -e phpunit.xml.dist ]; then phpunit; fi - - phpcs --standard=$(if [ -e phpcs.ruleset.xml ]; then echo phpcs.ruleset.xml; else echo WordPress; fi) $(find . -name '*.php') + - $PHPCS_DIR/scripts/phpcs --standard=$WPCS_STANDARD $(if [ -n "$PHPCS_IGNORE" ]; then echo --ignore=$PHPCS_IGNORE; fi) $(find . -name '*.php') - jshint . diff --git a/bin/class-wordpress-readme-parser.php b/bin/class-wordpress-readme-parser.php index 784b2191d..9dc56f468 100644 --- a/bin/class-wordpress-readme-parser.php +++ b/bin/class-wordpress-readme-parser.php @@ -42,7 +42,7 @@ function __construct( $args = array() ) { throw new Exception( "Parse error in $metadatum" ); } list( $name, $value ) = array_slice( $metadataum_matches, 1, 2 ); - $this->metadata[$name] = $value; + $this->metadata[ $name ] = $value; } $this->metadata['Contributors'] = preg_split( '/\s*,\s*/', $this->metadata['Contributors'] ); $this->metadata['Tags'] = preg_split( '/\s*,\s*/', $this->metadata['Tags'] ); @@ -181,8 +181,8 @@ function ( $tag ) { $body = $section['body']; $body = call_user_func( $general_section_formatter, $body ); - if ( isset( $section_formatters[$section['heading']] ) ) { - $body = trim( call_user_func( $section_formatters[$section['heading']], $body ) ); + if ( isset( $section_formatters[ $section['heading'] ] ) ) { + $body = trim( call_user_func( $section_formatters[ $section['heading'] ], $body ) ); } if ( $body ) { diff --git a/bin/install-wp-tests.sh b/bin/install-wp-tests.sh deleted file mode 100755 index 464772b7b..000000000 --- a/bin/install-wp-tests.sh +++ /dev/null @@ -1,65 +0,0 @@ -#!/usr/bin/env bash - -if [ $# -lt 3 ]; then - echo "usage: $0 [db-host] [wp-version]" - exit 1 -fi - -DB_NAME=$1 -DB_USER=$2 -DB_PASS=$3 -DB_HOST=${4-localhost} -WP_VERSION=${5-master} - -set -ex - -# set up a WP install -WP_CORE_DIR=/tmp/wordpress/ -mkdir -p $WP_CORE_DIR - -if [ $WP_VERSION == 'latest' ]; then - ARCHIVE_URL='http://wordpress.org/latest.tar.gz' -else - ARCHIVE_URL="https://github.com/WordPress/WordPress/tarball/$WP_VERSION" -fi - -wget -nv -O /tmp/wordpress.tar.gz $ARCHIVE_URL -tar --strip-components=1 -zxmf /tmp/wordpress.tar.gz -C $WP_CORE_DIR - -# set up testing suite -svn co --ignore-externals --quiet http://unit-tests.svn.wordpress.org/trunk/ $WP_TESTS_DIR - -# portable in-place argument for both GNU sed and Mac OSX sed -if [[ $(uname -s) == 'Darwin' ]]; then - ioption='-i ""' -else - ioption='-i' -fi - -# generate testing config file -cd $WP_TESTS_DIR -cp wp-tests-config-sample.php wp-tests-config.php -sed $ioption "s:dirname( __FILE__ ) . '/wordpress/':'$WP_CORE_DIR':" wp-tests-config.php -sed $ioption "s/yourdbnamehere/$DB_NAME/" wp-tests-config.php -sed $ioption "s/yourusernamehere/$DB_USER/" wp-tests-config.php -sed $ioption "s/yourpasswordhere/$DB_PASS/" wp-tests-config.php -sed $ioption "s|localhost|${DB_HOST}|" wp-tests-config.php - -# parse DB_HOST for port or socket references -PARTS=(${DB_HOST//\:/ }) -DB_HOSTNAME=${PARTS[0]}; -DB_SOCK_OR_PORT=${PARTS[1]}; -EXTRA="" - -if ! [ -z $DB_HOSTNAME ] ; then - if [[ "$DB_SOCK_OR_PORT" =~ ^[0-9]+$ ]] ; 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 diff --git a/bin/pre-commit b/bin/pre-commit index 8f50f0da5..9495a6d2c 100755 --- a/bin/pre-commit +++ b/bin/pre-commit @@ -3,6 +3,11 @@ set -e +WPCS_STANDARD=$(if [ -e phpcs.ruleset.xml ]; then echo phpcs.ruleset.xml; else echo WordPress; fi) +if [ -e .ci-env.sh ]; then + source .ci-env.sh +fi + message="Checking staged changes..." git_status_egrep='^[MARC].+' @@ -44,9 +49,30 @@ if [ ${#staged_php_files[@]} != 0 ]; then # PHPUnit if [ -e phpunit.xml ] || [ -e phpunit.xml.dist ]; then echo "## phpunit" - if [ "$USER" != 'vagrant' ] && command -v vagrant >/dev/null 2>&1 && command -v vassh >/dev/null 2>&1; then - echo "Running phpunit in vagrant..." - vassh phpunit + if [ "$USER" != 'vagrant' ]; then + + # Check if we're in VVV + plugin_dir=$(pwd) + while [ ! -e Vagrantfile ]; do + if [ $(pwd) == '/' ] || [ "$last_dir" == $(pwd) ]; then + break + fi + last_dir=$(pwd) + cd .. + done + if [ -e Vagrantfile ] && grep -q vvv Vagrantfile; then + vvv_root=$(pwd) + absolute_vvv_plugin_path=/srv${plugin_dir:${#vvv_root}} + fi + cd $plugin_dir + + if [ ! -z "$absolute_vvv_plugin_path" ]; then + echo "Running phpunit in VVV" + vagrant ssh -c "cd $absolute_vvv_plugin_path && phpunit" + elif command -v vassh >/dev/null 2>&1; then + echo "Running phpunit in vagrant via vassh..." + vassh phpunit + fi elif ! command -v phpunit >/dev/null 2>&1;then echo "Skipping phpunit since not installed" elif [ -z "$WP_TESTS_DIR" ]; then @@ -59,8 +85,7 @@ if [ ${#staged_php_files[@]} != 0 ]; then # PHP_CodeSniffer WordPress Coding Standards echo "## phpcs" if command -v phpcs >/dev/null 2>&1; then - phpcs_standard=$(if [ -e phpcs.ruleset.xml ]; then echo phpcs.ruleset.xml; else echo WordPress; fi) - phpcs -p -s -v --standard=$phpcs_standard "${staged_php_files[@]}" + phpcs -p -s -v --standard=$WPCS_STANDARD $(if [ -n "$PHPCS_IGNORE" ]; then echo --ignore=$PHPCS_IGNORE; fi) "${staged_php_files[@]}" else echo "Skipping phpcs since not installed" fi diff --git a/bin/readme.md b/bin/readme.md index 38c581267..ebd8268aa 100644 --- a/bin/readme.md +++ b/bin/readme.md @@ -41,6 +41,17 @@ cd .git/hooks ln -s ../../bin/pre-commit . ``` +You may customize the behavior of the `.travis.yml` and `pre-commit` hook by +specifying a `.ci-env.sh` in the root of the repo, for example: + +```bash +export PHPCS_GITHUB_SRC=x-team/PHP_CodeSniffer +export PHPCS_GIT_TREE=subset-selection +export WPCS_GIT_TREE=rule-subset-with-phpcs-pr +export WPCS_STANDARD=WordPress:core-extra +export PHPCS_IGNORE='tests/*,includes/vendor/*' +``` + The library includes a WordPress README [parser](class-wordpress-readme-parser.php) and [converter](generate-markdown-readme) to Markdown, so you don't have to manually keep your `readme.txt` on WordPress.org in sync with the `readme.md` you have on GitHub. The converter will also automatically recognize the presence of projects with Travis CI and include the status image diff --git a/connectors/menus.php b/connectors/menus.php index 8ba7b3150..ce57d4eca 100644 --- a/connectors/menus.php +++ b/connectors/menus.php @@ -81,7 +81,7 @@ public static function action_links( $links, $record ) { $menu_ids = wp_list_pluck( $menus, 'term_id' ); if ( in_array( $record->object_id, $menu_ids ) ) { - $links[ __( 'Edit Menu', 'stream' ) ] = admin_url( 'nav-menus.php?action=edit&menu=' . $record->object_id ); + $links[ __( 'Edit Menu', 'stream' ) ] = admin_url( 'nav-menus.php?action=edit&menu=' . $record->object_id ); // xss ok (@todo fix WPCS rule) } } @@ -148,7 +148,9 @@ public static function callback_delete_nav_menu( $term, $tt_id, $deleted_term ) */ public static function callback_update_option_theme_mods( $old, $new ) { // Disable if we're switching themes - if ( did_action( 'after_switch_theme' ) ) return; + if ( did_action( 'after_switch_theme' ) ) { + return; + } $key = 'nav_menu_locations'; diff --git a/connectors/widgets.php b/connectors/widgets.php index a54f4d707..ad9c243d9 100644 --- a/connectors/widgets.php +++ b/connectors/widgets.php @@ -77,7 +77,7 @@ public static function action_links( $links, $record ) { global $wp_registered_sidebars; if ( array_key_exists( $sidebar, $wp_registered_sidebars ) ) { - $links[ __( 'Edit Widget Area', 'stream' ) ] = admin_url( 'widgets.php#' . $sidebar ); + $links[ __( 'Edit Widget Area', 'stream' ) ] = admin_url( 'widgets.php#' . $sidebar ); // xss ok (@todo fix WPCS rule) } } diff --git a/includes/extensions.php b/includes/extensions.php index 62ed40bea..c0546173c 100644 --- a/includes/extensions.php +++ b/includes/extensions.php @@ -44,7 +44,7 @@ class WP_Stream_Extensions { /** * @var string|null */ - var $license_key = NULL; + var $license_key = null; /** * @var bool @@ -52,9 +52,9 @@ class WP_Stream_Extensions { public static $instance = false; public static function get_instance() { - if ( ! self::$instance ) + if ( ! self::$instance ) { self::$instance = new self(); - + } return self::$instance; } @@ -202,7 +202,7 @@ function get_plugin_paths() { $plugin_paths = array(); foreach ( get_plugins() as $path => $data ) { if ( isset( $data['TextDomain'] ) && ! empty( $data['TextDomain'] ) ) { - $plugin_paths[$data['TextDomain']] = $path; + $plugin_paths[ $data['TextDomain'] ] = $path; } } return $plugin_paths; @@ -249,12 +249,13 @@ function extensions_display_header( $extensions ) { * @return void */ function extensions_display_body( $extensions ) { + $extensions_url = self::API_TRANSPORT . self::API_DOMAIN . '/#extensions' . $this->get_affiliate(); if ( empty( $extensions ) ) { ?>

- +

__( 'Activate', 'stream' ), 'active18n' => __( 'Active', 'stream' ), 'actions' => array( - 'activate' => wp_nonce_url( add_query_arg( array( 'action' => 'activate', 'plugin' => $extension->post_meta->plugin_path[0], 'plugin_status' => 'all', 'paged' => '1' ), self_admin_url( 'plugins.php' ) ), 'activate-plugin_' . $extension->post_meta->plugin_path[0] ), - 'install' => wp_nonce_url( add_query_arg( array( 'action' => 'install-plugin', 'plugin' => $extension->slug ), self_admin_url( 'update.php' ) ), 'install-plugin_' . $extension->slug ), + 'activate' => wp_nonce_url( add_query_arg( array( 'action' => 'activate', 'plugin' => $extension->post_meta->plugin_path[0], 'plugin_status' => 'all', 'paged' => '1' ), self_admin_url( 'plugins.php' ) ), 'activate-plugin_' . $extension->post_meta->plugin_path[0] ), // xss ok (todo fix WPCS sniff) + 'install' => wp_nonce_url( add_query_arg( array( 'action' => 'install-plugin', 'plugin' => $extension->slug ), self_admin_url( 'update.php' ) ), 'install-plugin_' . $extension->slug ), // xss ok (todo fix WPCS sniff) 'delete' => null, ), ); diff --git a/includes/feeds.php b/includes/feeds.php index 1e3f90601..5b193a82a 100644 --- a/includes/feeds.php +++ b/includes/feeds.php @@ -185,13 +185,13 @@ public static function feed_template() { $die_title = esc_html__( 'Access Denied', 'stream' ); $die_message = '

' . $die_title .'

' . esc_html__( 'You don\'t have permission to view this feed, please contact your site Administrator.', 'stream' ) . '

'; - if ( ! isset( $_GET[self::FEED_QUERY_VAR] ) || empty( $_GET[self::FEED_QUERY_VAR] ) ) { + if ( ! isset( $_GET[ self::FEED_QUERY_VAR ] ) || empty( $_GET[ self::FEED_QUERY_VAR ] ) ) { wp_die( $die_message, $die_title ); } $args = array( 'meta_key' => self::USER_FEED_KEY, - 'meta_value' => $_GET[self::FEED_QUERY_VAR], + 'meta_value' => $_GET[ self::FEED_QUERY_VAR ], 'number' => 1, ); $user = get_users( $args ); diff --git a/includes/filter-input.php b/includes/filter-input.php index dccea2f35..e0974094c 100644 --- a/includes/filter-input.php +++ b/includes/filter-input.php @@ -101,7 +101,9 @@ public static function filter( $var, $filter = null, $options = array() ) { } public static function is_regex( $var ) { + // @codingStandardsIgnoreStart $test = @preg_match( $var, '' ); + // @codingStandardsIgnoreEnd return $test !== false; } diff --git a/includes/list-table.php b/includes/list-table.php index 7744a918b..9059a250d 100644 --- a/includes/list-table.php +++ b/includes/list-table.php @@ -406,8 +406,8 @@ function column_link( $display, $key, $value = null, $title = null ) { } public function get_term_title( $term, $type ) { - if ( isset( WP_Stream_Connectors::$term_labels["stream_$type"][ $term ] ) ) { - return WP_Stream_Connectors::$term_labels["stream_$type"][ $term ]; + if ( isset( WP_Stream_Connectors::$term_labels[ "stream_$type" ][ $term ] ) ) { + return WP_Stream_Connectors::$term_labels[ "stream_$type" ][ $term ]; } else { return $term; @@ -557,7 +557,6 @@ public function get_filters() { 'items' => $this->assemble_records( 'action' ), ); - /** * Filter allows additional filters in the list table dropdowns * Note the format of the filters above, with they key and array diff --git a/includes/settings.php b/includes/settings.php index 58d88b04d..2f4ea123e 100644 --- a/includes/settings.php +++ b/includes/settings.php @@ -591,7 +591,7 @@ public static function render_field( $field ) { $output .= ''; break; case 'select': - $current_value = (array) self::$options[$section . '_' . $name]; + $current_value = (array) self::$options[ $section . '_' . $name ]; $default_value = isset( $default['value'] ) ? $default['value'] : '-1'; $default_name = isset( $default['name'] ) ? $default['name'] : 'Choose Setting'; @@ -831,8 +831,8 @@ public static function get_default_connectors() { */ public static function get_terms_labels( $column ) { $return_labels = array(); - if ( isset ( WP_Stream_Connectors::$term_labels['stream_' . $column ] ) ) { - $return_labels = WP_Stream_Connectors::$term_labels['stream_' . $column ]; + if ( isset ( WP_Stream_Connectors::$term_labels[ 'stream_' . $column ] ) ) { + $return_labels = WP_Stream_Connectors::$term_labels[ 'stream_' . $column ]; ksort( $return_labels ); } diff --git a/includes/updater.php b/includes/updater.php index de0dc0daf..53341a2fd 100644 --- a/includes/updater.php +++ b/includes/updater.php @@ -40,7 +40,7 @@ public function setup() { } public function register( $plugin_file ) { - $this->plugins[$plugin_file] = preg_match( '#([a-z\-]+).php#', $plugin_file, $match ) ? $match[1] : null; + $this->plugins[ $plugin_file ] = preg_match( '#([a-z\-]+).php#', $plugin_file, $match ) ? $match[1] : null; // Plugin activation link $plugin_basename = plugin_basename( $plugin_file ); @@ -198,7 +198,7 @@ public function license_remove() { public function plugin_action_links( $links ) { if ( ! get_site_option( WP_Stream_Updater::LICENSE_KEY ) ) { - $links[ 'activation' ] = sprintf( + $links['activation'] = sprintf( '%2$s', admin_url( add_query_arg( @@ -210,7 +210,7 @@ public function plugin_action_links( $links ) { __( 'Activate', 'stream' ) ); } else { - $links[ 'activation' ] = __( 'Activated', 'stream' ); + $links['activation'] = __( 'Activated', 'stream' ); } return $links; } @@ -260,7 +260,7 @@ public function install_extension( $slug = null ) { $args = array( 'type' => 'upload', 'title' => sprintf( __( 'Installing %s Stream extension.', 'stream' ), $plugin['name'] ), - 'nonce' => 'install-plugin_' . $plugin['slug'], + 'nonce' => 'install-plugin_' . $plugin['slug'], // xss ok (@todo fix WPCS sniff) 'url' => $url, 'plugin' => $plugin, ); @@ -272,9 +272,9 @@ public function install_extension( $slug = null ) { $plugin_activate = $upgrader->plugin_info(); $activate = activate_plugin( $plugin_activate ); if ( is_wp_error( $activate ) ) { - echo '

' . $activate->get_error_message() . '

'; + echo '

' . $activate->get_error_message() . '

'; // xss ok } else { - echo '

' . __( 'Extension was downloaded and activated successfully!', 'stream' ) . '

'; + echo '

' . esc_html__( 'Extension was downloaded and activated successfully!', 'stream' ) . '

'; } } @@ -298,7 +298,7 @@ class WP_Stream_Updater { public static function instance() { $latest = max( array_keys( self::$versions ) ); - return new self::$versions[$latest]; + return new self::$versions[ $latest ]; } public static function register( $class ) { diff --git a/phpcs.ruleset.xml b/phpcs.ruleset.xml deleted file mode 100644 index be48f0a3c..000000000 --- a/phpcs.ruleset.xml +++ /dev/null @@ -1,17 +0,0 @@ - - - Generally-applicable sniffs for WordPress plugins - - - - */vendor/* - - - /tests/* - - - - /includes/settings.php - - - diff --git a/tests/bootstrap.php b/tests/bootstrap.php index 1a16456fc..1b1756c5a 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -9,8 +9,11 @@ // Use in code to trigger custom actions define( 'STREAM_TESTS', true ); -// Create our own test case to prevent repeating ourself -require_once getenv( 'WP_TESTS_DIR' ) . 'includes/functions.php'; +$_tests_dir = getenv('WP_TESTS_DIR'); +if ( ! $_tests_dir ) { + $_tests_dir = '/tmp/wordpress-tests-lib'; +} +require_once $_tests_dir . '/includes/functions.php'; tests_add_filter( 'muplugins_loaded', @@ -34,5 +37,5 @@ function() { 999999 ); -require getenv( 'WP_TESTS_DIR' ) . 'includes/bootstrap.php'; +require $_tests_dir . '/includes/bootstrap.php'; require dirname( __FILE__ ) . '/testcase.php';