diff --git a/.github/workflows/check-test.yml b/.github/workflows/check-test.yml index 8c55d99..88fb927 100644 --- a/.github/workflows/check-test.yml +++ b/.github/workflows/check-test.yml @@ -3,7 +3,7 @@ name: Check and Test on: push: branches: - - '**' + - 'master' pull_request: branches: - '**' @@ -12,7 +12,6 @@ jobs: check: runs-on: ubuntu-latest timeout-minutes: 10 - continue-on-error: true # We haven't solved all formatting issues yet. strategy: matrix: php: ['7.4'] diff --git a/README.md b/README.md index c47f006..0752885 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,8 @@ # TinyPNG - JPEG, PNG & WebP image compression for WordPress +[![Integration Tests](https://github.com/tinify/wordpress-plugin/actions/workflows/integration-tests.yml/badge.svg)](https://github.com/tinify/wordpress-plugin/actions/workflows/integration-tests.yml) +[![Check and Test](https://github.com/tinify/wordpress-plugin/actions/workflows/check-test.yml/badge.svg)](https://github.com/tinify/wordpress-plugin/actions/workflows/check-test.yml) + Make your website faster by optimizing your JPEG, PNG, and WebP images. This plugin automatically optimizes your images by integrating with the diff --git a/phpcs.xml b/phpcs.xml index c99724e..8582f13 100644 --- a/phpcs.xml +++ b/phpcs.xml @@ -1,12 +1,13 @@ - + - + - - + + + src/views @@ -14,7 +15,6 @@ 0 - tiny-compress-images.php src test src/css @@ -22,4 +22,4 @@ src/js vendor test/ - + \ No newline at end of file diff --git a/src/class-tiny-helpers.php b/src/class-tiny-helpers.php index 48d876f..19aa5d9 100644 --- a/src/class-tiny-helpers.php +++ b/src/class-tiny-helpers.php @@ -24,8 +24,8 @@ class Tiny_Helpers { * truncate_text will truncate a string to a given length. * When text is longer than the given length, the string will be truncated and * the last characters will be replaced with an ellipsis. - * - * We can use mb_strlen & mb_substr as WordPress provides a compat function for + * + * We can use mb_strlen & mb_substr as WordPress provides a compat function for * it if mbstring php module is not installed. * * @param string $text the text diff --git a/src/class-tiny-notices.php b/src/class-tiny-notices.php index 1dd5a0b..3d6d7b8 100644 --- a/src/class-tiny-notices.php +++ b/src/class-tiny-notices.php @@ -147,7 +147,10 @@ public function show( $name, $message, $klass = 'error', $dismissible = true ) { } $css = implode( ' ', $css ); - $plugin_name = esc_html__( 'TinyPNG - JPEG, PNG & WebP image compression', 'tiny-compress-images' ); + $plugin_name = esc_html__( + 'TinyPNG - JPEG, PNG & WebP image compression', + 'tiny-compress-images' + ); add_action( 'admin_notices', function() use ( $css, $name, $plugin_name, $message, $add ) { @@ -268,7 +271,10 @@ public function incompatible_plugins_notice() { private function show_incompatible_plugins( $incompatible_plugins ) { $notice = '
'; $notice .= '

'; - $notice .= esc_html__( 'TinyPNG - JPEG, PNG & WebP image compression', 'tiny-compress-images' ); + $notice .= esc_html__( + 'TinyPNG - JPEG, PNG & WebP image compression', + 'tiny-compress-images' + ); $notice .= '

'; $notice .= '

'; $notice .= esc_html__( @@ -278,7 +284,10 @@ private function show_incompatible_plugins( $incompatible_plugins ) { $notice .= '

'; $notice .= ''; $notice .= ''; foreach ( $incompatible_plugins as $name => $file ) { $notice .= '
'; - $notice .= esc_html__( 'TinyPNG - JPEG, PNG & WebP image compression', 'tiny-compress-images' ); + $notice .= esc_html__( + 'TinyPNG - JPEG, PNG & WebP image compression', + 'tiny-compress-images' + ); $notice .= '
'; diff --git a/src/class-tiny-plugin.php b/src/class-tiny-plugin.php index 42644a4..51f8c7a 100644 --- a/src/class-tiny-plugin.php +++ b/src/class-tiny-plugin.php @@ -365,9 +365,9 @@ public function process_rpc_request() { } public function compress_on_upload() { - if (!wp_verify_nonce($_POST['_ajax_nonce'], 'new_media-' . $_POST['attachment_id'])) { - exit; - } + if ( ! wp_verify_nonce( $_POST['_ajax_nonce'], 'new_media-' . $_POST['attachment_id'] ) ) { + exit; + } if ( current_user_can( 'upload_files' ) ) { $attachment_id = intval( $_POST['attachment_id'] ); $metadata = $_POST['metadata']; diff --git a/src/class-tiny-settings.php b/src/class-tiny-settings.php index 75b733d..3df63ac 100644 --- a/src/class-tiny-settings.php +++ b/src/class-tiny-settings.php @@ -859,9 +859,9 @@ public function render_pending_status() { } public function create_api_key() { - if (!$this->check_ajax_referer()) { - exit; - } + if ( ! $this->check_ajax_referer() ) { + exit; + } $compressor = $this->get_compressor(); if ( ! current_user_can( 'manage_options' ) ) { $status = (object) array( @@ -929,9 +929,9 @@ public function create_api_key() { public function update_api_key() { $key = $_POST['key']; - if (!$this->check_ajax_referer()) { - exit; - } + if ( ! $this->check_ajax_referer() ) { + exit; + } if ( ! current_user_can( 'manage_options' ) ) { $status = (object) array( 'ok' => false, diff --git a/test/helpers/wordpress.php b/test/helpers/wordpress.php new file mode 100644 index 0000000..9ca852a --- /dev/null +++ b/test/helpers/wordpress.php @@ -0,0 +1,246 @@ +values = array( + 'thumbnail_size_w' => 150, + 'thumbnail_size_h' => 150, + 'medium_size_w' => 300, + 'medium_size_h' => 300, + 'medium_large_size_w' => 768, + 'medium_large_size_h' => 0, + 'large_size_w' => 1024, + 'large_size_h' => 1024, + ); + } + + public function set( $key, $value ) { + if ( preg_match( '#^(.+)\[(.+)\]$#', $key, $match ) ) { + if ( ! isset( $this->values[ $match[1] ] ) ) { + $this->values[ $match[1] ] = array(); + } + $this->values[ $match[1] ][ $match[2] ] = $value; + } else { + $this->values[ $key ] = $value; + } + } + + public function get( $key, $default = null ) { + return isset( $this->values[ $key ] ) ? $this->values[ $key ] : $default; + } +} + +class WordPressStubs { + const UPLOAD_DIR = 'wp-content/uploads'; + + private $vfs; + private $initFunctions; + private $admin_initFunctions; + private $options; + private $metadata; + private $calls; + private $stubs; + + public function __construct( $vfs ) { + $GLOBALS['wp'] = $this; + $this->vfs = $vfs; + $this->addMethod( 'add_action' ); + $this->addMethod( 'do_action' ); + $this->addMethod( 'add_filter' ); + $this->addMethod( 'register_setting' ); + $this->addMethod( 'add_settings_section' ); + $this->addMethod( 'add_settings_field' ); + $this->addMethod( 'get_option' ); + $this->addMethod( 'get_site_option' ); + $this->addMethod( 'update_site_option' ); + $this->addMethod( 'get_post_meta' ); + $this->addMethod( 'update_post_meta' ); + $this->addMethod( 'get_intermediate_image_sizes' ); + $this->addMethod( 'add_image_size' ); + $this->addMethod( 'translate' ); + $this->addMethod( 'load_plugin_textdomain' ); + $this->addMethod( 'get_post_mime_type' ); + $this->addMethod( 'get_plugin_data' ); + $this->addMethod( 'wp_upload_dir' ); + $this->addMethod( 'plugin_basename' ); + $this->addMethod( 'is_multisite' ); + $this->addMethod( 'current_user_can' ); + $this->addMethod( 'wp_get_attachment_metadata' ); + $this->addMethod( 'is_admin' ); + $this->defaults(); + $this->create_filesystem(); + } + + public function create_filesystem() { + vfsStream::newDirectory( self::UPLOAD_DIR ) + ->at( $this->vfs ); + } + + public function defaults() { + $this->initFunctions = array(); + $this->admin_initFunctions = array(); + $this->options = new WordPressOptions(); + $this->metadata = array(); + $GLOBALS['_wp_additional_image_sizes'] = array(); + } + + public function call( $method, $args ) { + $this->calls[ $method ][] = $args; + if ( 'add_action' === $method ) { + if ( 'init' === $args[0] ) { + $this->initFunctions[] = $args[1]; + } elseif ( 'admin_init' === $args[0] ) { + $this->admin_initFunctions[] = $args[1]; + } + } + if ( 'translate' === $method ) { + return $args[0]; + } elseif ( 'get_option' === $method ) { + return call_user_func_array( array( $this->options, 'get' ), $args ); + } elseif ( 'get_post_meta' === $method ) { + return call_user_func_array( array( $this, 'getMetadata' ), $args ); + } elseif ( 'add_image_size' === $method ) { + return call_user_func_array( array( $this, 'addImageSize' ), $args ); + } elseif ( 'update_post_meta' === $method ) { + return call_user_func_array( array( $this, 'updateMetadata' ), $args ); + } elseif ( 'get_intermediate_image_sizes' === $method ) { + return array_merge( array( 'thumbnail', 'medium', 'medium_large', 'large' ), array_keys( $GLOBALS['_wp_additional_image_sizes'] ) ); + } elseif ( 'get_plugin_data' === $method ) { + return array( 'Version' => '1.7.2' ); + } elseif ( 'wp_upload_dir' === $method ) { + return array( 'basedir' => $this->vfs->url() . '/' . self::UPLOAD_DIR, 'baseurl' => '/' . self::UPLOAD_DIR ); + } elseif ( 'is_admin' === $method ) { + return true; + } elseif ( $this->stubs[ $method ] ) { + return call_user_func_array( $this->stubs[ $method ], $args ); + } + } + + public function addMethod( $method ) { + $this->calls[ $method ] = array(); + $this->stubs[ $method ] = array(); + if ( ! function_exists( $method ) ) { + eval( "function $method() { return \$GLOBALS['wp']->call('$method', func_get_args()); }" ); + } + } + + public function addOption( $key, $value ) { + $this->options->set( $key, $value ); + } + + public function addImageSize( $size, $values ) { + $GLOBALS['_wp_additional_image_sizes'][ $size ] = $values; + } + + public function getMetadata( $id, $key, $single = false ) { + $values = isset( $this->metadata[ $id ] ) ? $this->metadata[ $id ] : array(); + $value = isset( $values[ $key ] ) ? $values[ $key ] : ''; + return $single ? $value : array( $value ); + } + + public function updateMetadata( $id, $key, $values ) { + $this->metadata[ $id ][ $key ] = $values; + } + + public function setTinyMetadata( $id, $values ) { + $this->metadata[ $id ] = array( Tiny_Config::META_KEY => $values ); + } + + public function getCalls( $method ) { + return $this->calls[ $method ]; + } + + public function init() { + foreach ( $this->initFunctions as $func ) { + call_user_func( $func ); + } + } + + public function admin_init() { + foreach ( $this->admin_initFunctions as $func ) { + call_user_func( $func ); + } + } + + public function stub( $method, $func ) { + $this->stubs[ $method ] = $func; + } + + public function createImage( $file_size, $path, $name ) { + if ( ! $this->vfs->hasChild( self::UPLOAD_DIR . "/$path" ) ) { + vfsStream::newDirectory( self::UPLOAD_DIR . "/$path" )->at( $this->vfs ); + } + $dir = $this->vfs->getChild( self::UPLOAD_DIR . "/$path" ); + + vfsStream::newFile( $name ) + ->withContent( new LargeFileContent( $file_size ) ) + ->at( $dir ); + } + + public function createImages( $sizes = null, $original_size = 12345, $path = '14/01', $name = 'test' ) { + vfsStream::newDirectory( self::UPLOAD_DIR . "/$path" )->at( $this->vfs ); + $dir = $this->vfs->getChild( self::UPLOAD_DIR . '/' . $path ); + + vfsStream::newFile( "$name.png" ) + ->withContent( new LargeFileContent( $original_size ) ) + ->at( $dir ); + + if ( is_null( $sizes ) ) { + $sizes = array( 'thumbnail' => 100, 'medium' => 1000 , 'large' => 10000, 'post-thumbnail' => 1234 ); + } + + foreach ( $sizes as $key => $size ) { + vfsStream::newFile( "$name-$key.png" ) + ->withContent( new LargeFileContent( $size ) ) + ->at( $dir ); + } + } + + public function createImagesFromJSON( $virtual_images ) { + foreach ( $virtual_images['images'] as $image ) { + self::createImage( $image['size'], $virtual_images['path'], $image['file'] ); + } + } + + public function getTestMetadata( $path = '14/01', $name = 'test' ) { + $metadata = array( + 'file' => "$path/$name.png", + 'width' => 4000, + 'height' => 3000, + 'sizes' => array(), + ); + + $regex = '#^' . preg_quote( $name ) . '-([^.]+)[.](png|jpe?g)$#'; + $dir = $this->vfs->getChild( self::UPLOAD_DIR . "/$path" ); + foreach ( $dir->getChildren() as $child ) { + $file = $child->getName(); + if ( preg_match( $regex, $file, $match ) ) { + $metadata['sizes'][ $match[1] ] = array( 'file' => $file ); + } + } + + return $metadata; + } +} + +class WP_HTTP_Proxy { + public function is_enabled() { + return false; + } +} + +function __( $text, $domain = 'default' ) { + return translate( $text, $domain ); +} + +function esc_html__( $text, $domain = 'default' ) { + return translate( $text, $domain ); +} \ No newline at end of file