Automattic /
jetpack
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
| 1 | <?php |
||
| 2 | |||
| 3 | /** |
||
| 4 | * Handles items that have been selected for automatic updates. |
||
| 5 | * Hooks into WP_Automatic_Updater |
||
| 6 | */ |
||
| 7 | class Jetpack_Autoupdate { |
||
|
1 ignored issue
–
show
Coding Style
introduced
by
Loading history...
|
|||
| 8 | |||
| 9 | public $updates_allowed; |
||
| 10 | public $jetpack; |
||
| 11 | public $autoupdate_results; |
||
| 12 | public $is_updating = false; |
||
| 13 | |||
| 14 | public $autoupdate_expected = array( |
||
| 15 | 'plugin'=> array(), |
||
| 16 | 'theme' => array(), |
||
| 17 | ); |
||
| 18 | |||
| 19 | public $log = array( |
||
| 20 | 'plugin' => array(), |
||
| 21 | 'theme' => array(), |
||
| 22 | ); |
||
| 23 | |||
| 24 | private static $instance = null; |
||
| 25 | |||
| 26 | static function init() { |
||
| 27 | if ( is_null( self::$instance ) ) { |
||
| 28 | self::$instance = new Jetpack_Autoupdate; |
||
| 29 | } |
||
| 30 | return self::$instance; |
||
| 31 | } |
||
| 32 | |||
| 33 | private function __construct() { |
||
| 34 | |||
| 35 | $this->updates_allowed = Jetpack::is_module_active( 'manage' ); |
||
| 36 | // Only run automatic updates if a user as opted in by activating the manage module. |
||
| 37 | if ( $this->updates_allowed ) { |
||
| 38 | add_filter( 'auto_update_plugin', array( $this, 'autoupdate_plugin' ), 10, 2 ); |
||
| 39 | add_filter( 'auto_update_theme', array( $this, 'autoupdate_theme' ), 10, 2 ); |
||
| 40 | add_filter( 'auto_update_core', array( $this, 'autoupdate_core' ), 10, 2 ); |
||
| 41 | add_action( 'automatic_updates_complete', array( $this, 'automatic_updates_complete' ), 10, 1 ); |
||
| 42 | add_action( 'shutdown', array( $this, 'log_results' ) ); |
||
| 43 | } |
||
| 44 | } |
||
| 45 | |||
| 46 | View Code Duplication | function autoupdate_plugin( $update, $item ) { |
|
| 47 | $autoupdate_plugin_list = Jetpack_Options::get_option( 'autoupdate_plugins', array() ); |
||
| 48 | if ( in_array( $item->plugin, $autoupdate_plugin_list ) ) { |
||
| 49 | $this->expect( $item->plugin ); |
||
| 50 | return true; |
||
| 51 | } |
||
| 52 | |||
| 53 | return $update; |
||
| 54 | } |
||
| 55 | |||
| 56 | View Code Duplication | function autoupdate_theme( $update, $item ) { |
|
| 57 | $autoupdate_theme_list = Jetpack_Options::get_option( 'autoupdate_themes', array() ); |
||
| 58 | if ( in_array( $item->theme , $autoupdate_theme_list) ) { |
||
| 59 | $this->expect( $item->theme, $type = 'theme' ); |
||
| 60 | return true; |
||
| 61 | } |
||
| 62 | return $update; |
||
| 63 | } |
||
| 64 | |||
| 65 | function autoupdate_core( $update, $item ) { |
||
|
0 ignored issues
–
show
|
|||
| 66 | $autoupdate_core = Jetpack_Options::get_option( 'autoupdate_core', false ); |
||
| 67 | if ( $autoupdate_core ) { |
||
| 68 | return $autoupdate_core; |
||
| 69 | } |
||
| 70 | return $update; |
||
| 71 | } |
||
| 72 | |||
| 73 | /** |
||
| 74 | * Stores the an item identifier to the autoupdate_expected array. |
||
| 75 | * |
||
| 76 | * @param string $item Example: 'jetpack/jetpack.php' for type 'plugin' or 'twentyfifteen' for type 'theme' |
||
| 77 | * @param string $type 'plugin' or 'theme' |
||
| 78 | */ |
||
| 79 | function expect( $item, $type='plugin' ) { |
||
| 80 | $this->is_updating = true; |
||
| 81 | $this->autoupdate_expected[ $type ][] = $item; |
||
| 82 | } |
||
| 83 | |||
| 84 | /** |
||
| 85 | * On completion of an automatic update, let's store the results. |
||
| 86 | * |
||
| 87 | * @param $results - Sent by WP_Automatic_Updater after it completes an autoupdate action. Results may be empty. |
||
| 88 | */ |
||
| 89 | function automatic_updates_complete( $results ) { |
||
| 90 | $this->autoupdate_results = $results; |
||
| 91 | } |
||
| 92 | |||
| 93 | /** |
||
| 94 | * On shutdown, let's check to see if we've preformed an automatic update. |
||
| 95 | * If so, let's compare the expected results to the actual results, and log our findings. |
||
| 96 | * |
||
| 97 | * Results are logged locally via Jetpack::log(), and globally via Jetpack::do_stats() |
||
| 98 | */ |
||
| 99 | function log_results() { |
||
| 100 | |||
| 101 | if ( $this->is_updating ) { |
||
| 102 | |||
| 103 | $this->jetpack = Jetpack::init(); |
||
| 104 | $items_to_log = array( 'plugin', 'theme' ); |
||
| 105 | |||
| 106 | foreach( $items_to_log as $items ) { |
||
| 107 | $this->log_items( $items ); |
||
| 108 | } |
||
| 109 | |||
| 110 | $this->jetpack->do_stats( 'server_side' ); |
||
| 111 | $this->jetpack->log( 'autoupdates', $this->log ); |
||
| 112 | } |
||
| 113 | } |
||
| 114 | |||
| 115 | /** |
||
| 116 | * Iterates through expected items ( plugins or themes ) and compares them to actual results. |
||
| 117 | * |
||
| 118 | * @param $items 'plugin' or 'theme' |
||
| 119 | */ |
||
| 120 | function log_items( $items ) { |
||
| 121 | $num_items_updated = 0; |
||
| 122 | $num_items_failed = 0; |
||
| 123 | $item_results = $this->get_successful_updates( $items ); |
||
| 124 | $items_failed = array(); |
||
| 125 | |||
| 126 | foreach( $this->autoupdate_expected[ $items ] as $item ) { |
||
| 127 | if ( in_array( $item, $item_results ) ) { |
||
| 128 | $num_items_updated++; |
||
| 129 | $this->log[ $items ][ $item ] = true; |
||
| 130 | } else { |
||
| 131 | $num_items_failed++; |
||
| 132 | $this->log[ $items ][ $item ] = new WP_Error( "$items-fail", $this->get_error_message( $item, $type = $items ) ); |
||
| 133 | $items_failed[] = $item; |
||
| 134 | } |
||
| 135 | } |
||
| 136 | |||
| 137 | if ( $num_items_updated ) { |
||
| 138 | $this->jetpack->stat( "autoupdates/$items-success", $num_items_updated ); |
||
| 139 | } |
||
| 140 | |||
| 141 | if ( $num_items_failed ) { |
||
| 142 | // bump stats |
||
| 143 | $this->jetpack->stat( "autoupdates/$items-fail", $num_items_failed ); |
||
| 144 | Jetpack::load_xml_rpc_client(); |
||
| 145 | $xml = new Jetpack_IXR_Client( array( |
||
| 146 | 'user_id' => get_current_user_id() |
||
| 147 | ) ); |
||
| 148 | $request = array( |
||
| 149 | 'plugins' => $items_failed, |
||
| 150 | 'blog_id' => Jetpack_Options::get_option( 'id' ), |
||
| 151 | ); |
||
| 152 | $xml->query( 'jetpack.debug_autoupdate', $request ); |
||
| 153 | } |
||
| 154 | |||
| 155 | } |
||
| 156 | |||
| 157 | /** |
||
| 158 | * Parses the autoupdate results generated by WP_Automatic_Updater and returns a simple array of successful items |
||
| 159 | * |
||
| 160 | * @param string $type 'plugin' or 'theme' |
||
| 161 | * |
||
| 162 | * @return array |
||
| 163 | */ |
||
| 164 | private function get_successful_updates( $type = 'plugin' ) { |
||
| 165 | $successful_updates = array(); |
||
| 166 | |||
| 167 | if ( ! isset( $this->autoupdate_results[ $type ] ) ) { |
||
| 168 | return $successful_updates; |
||
| 169 | } |
||
| 170 | |||
| 171 | foreach( $this->autoupdate_results[ $type ] as $result ) { |
||
| 172 | if ( $result->result ) { |
||
| 173 | View Code Duplication | switch( $type ) { |
|
| 174 | case 'theme': |
||
| 175 | $successful_updates[] = $result->item->theme; |
||
| 176 | break; |
||
| 177 | default: |
||
| 178 | $successful_updates[] = $result->item->plugin; |
||
| 179 | } |
||
| 180 | } |
||
| 181 | } |
||
| 182 | |||
| 183 | return $successful_updates; |
||
| 184 | } |
||
| 185 | |||
| 186 | /** |
||
| 187 | * Cycles through results generated by WP_Automatic_Updater to find the messages for the given item and item type. |
||
| 188 | * |
||
| 189 | * @param $item Example: 'jetpack/jetpack.php' for type 'plugin' or 'twentyfifteen' for type 'theme' |
||
| 190 | * @param string $type 'plugin' or 'theme' |
||
| 191 | * |
||
| 192 | * @return bool|string |
||
| 193 | */ |
||
| 194 | private function get_error_message( $item, $type = 'plugin' ) { |
||
| 195 | if ( ! isset( $this->autoupdate_results[ $type ] ) ) { |
||
| 196 | return false; |
||
| 197 | } |
||
| 198 | foreach( $this->autoupdate_results[ $type ] as $result ) { |
||
| 199 | View Code Duplication | switch( $type ) { |
|
| 200 | case 'theme': |
||
| 201 | $id = $result->item->theme; |
||
| 202 | break; |
||
| 203 | default: |
||
| 204 | $id = $result->item->plugin; |
||
| 205 | } |
||
| 206 | if ( $id == $item && isset( $result->messages ) ) { |
||
| 207 | return implode( ', ', $result->messages ); |
||
| 208 | } |
||
| 209 | } |
||
| 210 | return false; |
||
| 211 | } |
||
| 212 | |||
| 213 | } |
||
| 214 | Jetpack_Autoupdate::init(); |
||
| 215 |