Skip to content

Commit 8b2f953

Browse files
authored
Merge pull request #64 from wcreateweb/tiny-cli
Add WP CLI commands
2 parents 1cc10a2 + 9c820f8 commit 8b2f953

File tree

11 files changed

+564
-129
lines changed

11 files changed

+564
-129
lines changed

bin/run-wpcli

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
#!/usr/bin/env bash
2+
3+
# Usage: bin/run-wpcli [WORDPRESS_VERSION] [PHP_VERSION] [COMMAND]
4+
# Example: bin/run-wpcli 67 82 "tiny optimize --attachments=123,456"
5+
# Example: bin/run-wpcli 67 82 "tiny optimize"
6+
7+
8+
CONFIG_FILE="config/wp-version.conf"
9+
WORDPRESS_VERSION_ENV="${1:-$WORDPRESS_VERSION}"
10+
PHP_VERSION_ENV="${2:-$PHP_VERSION}"
11+
12+
WORDPRESS_PORT="80${WORDPRESS_VERSION_ENV}"
13+
WP_IMAGE_KEY="${WORDPRESS_VERSION_ENV}_${PHP_VERSION_ENV}"
14+
WP_IMAGE=$(grep "^${WP_IMAGE_KEY}=" "$CONFIG_FILE" | cut -d'=' -f2)
15+
16+
COMMAND=${3:-"tiny --help"}
17+
18+
export WP_IMAGE
19+
export COMPOSE_PROJECT_NAME="tinify_${WORDPRESS_VERSION_ENV}_${PHP_VERSION_ENV}"
20+
export WORDPRESS_PORT
21+
22+
docker compose -f config/docker-compose.yml run --rm wpcli wp $COMMAND

src/class-tiny-cli.php

Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
<?php
2+
/*
3+
* Tiny Compress Images - WordPress plugin.
4+
* Copyright (C) 2015-2018 Tinify B.V.
5+
*
6+
* This program is free software; you can redistribute it and/or modify it
7+
* under the terms of the GNU General Public License as published by the Free
8+
* Software Foundation; either version 2 of the License, or (at your option)
9+
* any later version.
10+
*
11+
* This program is distributed in the hope that it will be useful, but WITHOUT
12+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14+
* more details.
15+
*
16+
* You should have received a copy of the GNU General Public License along
17+
* with this program; if not, write to the Free Software Foundation, Inc., 51
18+
* Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19+
*/
20+
21+
class Tiny_Cli {
22+
public static function register_command( $settings ) {
23+
$command_instance = new Tiny_Command( $settings );
24+
WP_CLI::add_command( 'tiny', $command_instance );
25+
}
26+
}
27+
28+
class Tiny_Command {
29+
30+
/**
31+
* Tinify Settings
32+
*
33+
* @var Tiny_Settings
34+
*/
35+
private $tiny_settings;
36+
37+
public function __construct( $settings ) {
38+
$this->tiny_settings = $settings;
39+
}
40+
41+
/**
42+
* Optimize will process images
43+
*
44+
* [--attachments=<strings>]
45+
* : A comma separated list of attachment IDs to process. If omitted
46+
* will optimize all uncompressed attachments
47+
*
48+
*
49+
* ## EXAMPLES
50+
*
51+
* optimize specific attachments
52+
* wp tiny optimize --attachments=532,603,705
53+
*
54+
* optimize all unprocessed images
55+
* wp tiny optimize
56+
*
57+
*
58+
* @param array $args
59+
* @param array $assoc_args
60+
* @return void
61+
*/
62+
public function optimize( $args, $assoc_args ) {
63+
$attachments = isset( $assoc_args['attachments'] ) ?
64+
array_map( 'trim', explode( ',', $assoc_args['attachments'] ) ) :
65+
array();
66+
67+
if ( empty( $attachments ) ) {
68+
$attachments = $this->get_unoptimized_attachments();
69+
}
70+
71+
if ( empty( $attachments ) ) {
72+
WP_CLI::success( 'No images found that need optimization.' );
73+
return;
74+
}
75+
76+
$total = count( $attachments );
77+
WP_CLI::log( 'Optimizing ' . $total . ' images.' );
78+
79+
$progress = WP_CLI\Utils\make_progress_bar( 'Optimizing images', $total );
80+
$optimized = 0;
81+
foreach ( $attachments as $attachment_id ) {
82+
$attachment_id = intval( $attachment_id );
83+
84+
if ( ! $this->is_valid_attachment( $attachment_id ) ) {
85+
WP_CLI::warning( 'skipping - invalid attachment: ' . $attachment_id );
86+
$progress->tick();
87+
continue;
88+
}
89+
90+
try {
91+
$result = $this->optimize_attachment( $attachment_id );
92+
if ( isset( $result['success'] ) && $result['success'] > 0 ) {
93+
$optimized++;
94+
}
95+
} catch ( Exception $e ) {
96+
WP_CLI::warning(
97+
'skipping - error: ' .
98+
$e->getMessage() .
99+
' (ID: ' .
100+
$attachment_id .
101+
')'
102+
);
103+
}
104+
105+
$progress->tick();
106+
}
107+
108+
$progress->finish();
109+
WP_CLI::success( 'Done! Optimized ' . $optimized . ' of ' . $total . ' images.' );
110+
}
111+
112+
private function get_unoptimized_attachments() {
113+
$stats = Tiny_Bulk_Optimization::get_optimization_statistics( $this->tiny_settings );
114+
115+
if ( empty( $stats['available-for-optimization'] ) ) {
116+
return array();
117+
}
118+
119+
$ids = array();
120+
foreach ( $stats['available-for-optimization'] as $item ) {
121+
if ( isset( $item['ID'] ) ) {
122+
$ids[] = $item['ID'];
123+
}
124+
}
125+
return $ids;
126+
}
127+
128+
/**
129+
* Will process an attachment for optimization
130+
*
131+
* @return array{ success: int, failed: int }
132+
*/
133+
private function optimize_attachment( $attachment_id ) {
134+
$tiny_image = new Tiny_Image( $this->tiny_settings, $attachment_id );
135+
return $tiny_image->compress();
136+
}
137+
138+
private function is_valid_attachment( $attachment_id ) {
139+
$mime_type = get_post_mime_type( $attachment_id );
140+
if ( ! $mime_type || strpos( $mime_type, 'image/' ) !== 0 ) {
141+
return false;
142+
}
143+
144+
$supported_types = array( 'image/jpeg', 'image/png', 'image/webp' );
145+
if ( ! in_array( $mime_type, $supported_types, true ) ) {
146+
return false;
147+
}
148+
149+
return true;
150+
}
151+
}

src/class-tiny-plugin.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,10 @@ public function init() {
7171
}
7272
}
7373

74+
public function cli_init() {
75+
Tiny_CLI::register_command( $this->settings );
76+
}
77+
7478
public function ajax_init() {
7579
add_filter( 'wp_ajax_tiny_async_optimize_upload_new_media',
7680
$this->get_method( 'compress_on_upload' )

src/class-tiny-settings.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,13 @@ public function xmlrpc_init() {
5050
}
5151
}
5252

53+
public function cli_init() {
54+
try {
55+
$this->init_compressor();
56+
} catch ( Tiny_Exception $e ) {
57+
}
58+
}
59+
5360
public function ajax_init() {
5461
try {
5562
$this->init_compressor();

src/class-tiny-wp-base.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,10 @@ protected function doing_ajax_request() {
4949
return defined( 'DOING_AJAX' ) && DOING_AJAX;
5050
}
5151

52+
protected function is_cli() {
53+
return defined( 'WP_CLI' ) && WP_CLI;
54+
}
55+
5256
protected static function get_prefixed_name( $name ) {
5357
return self::PREFIX . $name;
5458
}
@@ -65,6 +69,10 @@ public function __construct() {
6569
add_action( 'admin_init', $this->get_method( 'admin_init' ) );
6670
add_action( 'admin_menu', $this->get_method( 'admin_menu' ) );
6771
}
72+
73+
if ( self::is_cli() ) {
74+
add_action( 'cli_init', $this->get_method( 'cli_init' ) );
75+
}
6876
}
6977

7078
protected function get_method( $name ) {
@@ -100,4 +108,7 @@ public function admin_menu() {
100108

101109
public function rest_init() {
102110
}
111+
112+
public function cli_init() {
113+
}
103114
}

test/helpers/wordpress-cli.php

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<?php
2+
3+
/**
4+
* Mock WP_CLI to be used in php unit tests
5+
*/
6+
class WP_CLI
7+
{
8+
public static function log($message) {}
9+
10+
public static function success($message) {}
11+
12+
public static function warning($message) {}
13+
14+
public static function add_command($name, $command) {}
15+
}
16+
17+
namespace WP_CLI\Utils {
18+
class MockProgressBar
19+
{
20+
public function tick() {}
21+
22+
public function finish() {}
23+
}
24+
25+
function make_progress_bar($label, $count)
26+
{
27+
return new MockProgressBar();
28+
}
29+
}

0 commit comments

Comments
 (0)